Formatting small decimal numbers in MATLAB - matlab

How can I format the number 0.00935349 in a string using fprintf() so that I can display ?

The %e format specifier gets you close:
>> fprintf('%.1e\n', 0.00935349)
9.4e-03
If you want the e to appear as x10, you can use sprintf to generate the number string, replace the e using strrep on the result, then pass that to fprintf:
>> fprintf(strrep(sprintf('%.1e\n', 0.00935349), 'e', 'x10'))
9.4x10-03

Related

How to connect words/phrases in matlab

How can I connect these two parts?
In Excel if you say 'state'&2 you will get a combined phrase state2.
I want to join 'state' and 'i' where i is a number between e.g. 1,2,3...
Then I can end up with state1 or state5 for example depending on what i is equal to.
How can I do this?
You can
Use num2str to convert 2 to '2', and then concatenation to build your char array
Use sprintf to create a char array with a specified placeholder format
Use strings.
Importantly here I've made a distinction between strings ("double quotes") and character arrays ('single quotes') - read here for more details about their differences.
Corresponding code would look like
% 1. Use num2str and concatenation
str = ['state', num2str(2)]; % -> 'state2' (char)
% 2. Use sprintf
str = sprintf( 'state%d', 2 ); % -> 'state2' (char)
% 3. Use strings
str = "state" + 2 % -> "state2" (string)
I would opt for number 2, since I think it's cleaner than 1 and more flexible, and I have used MATLAB since before strings existed so I'm predisposed to dislike them!

Matlab: Parsing strings

How can I turn strings like 1-14 into 01_014? (and for 2-2 into 02_002)?
I can do something like this:
testpoint_number = '5-16';
temp = textscan(testpoint_number, '%s', 'delimiter', '-');
temp = temp{1};
first_part = temp{1};
second_part = temp{2};
output_prefix = strcat('0',first_part);
parsed_testpoint_number = strcat(output_prefix, '_',second_part);
parsed_testpoint_number
But I feel this is very tedious, and I don't know how to handle the second part (16 to 016)
As you are handling integer numbers, I would suggest to change the textscan to %d (integer numbers). With that, you can use the formatting power of the *printf commands (e.g. sprintf).
*printf allows you to specify the width of the integer. With %02d, a 2 chars wide integer, which will be filled up with zeros, is printed.
The textscan returns a {1x1} cell, which contains a 2x1 array of integers. *printf can handle this itsself, so you just have to supply the argument temp{1}:
temp = textscan(testpoint_number, '%d', 'delimiter', '-');
parsed_testpoint_number = sprintf('%02d_%03d',temp{1});
Your textscanning is probably the most intuitive way to do this, but from then on what I would recommend doing is instead converting the scanned first_part and second_part into numerical format, giving you integers.
You can then sprintf these into your target string using the correct 'c'-style formatters to indicate your zero-padding prefix width, e.g.:
temp = textscan(testpoint_number, '%d', 'delimiter', '-');
parsed_testpoint_number = sprintf('%02d_%03d', temp{1});
Take a look at the C sprintf() documentation for an explanation of the string formatting options.

Function to split string in matlab and return second number

I have a string and I need two characters to be returned.
I tried with strsplit but the delimiter must be a string and I don't have any delimiters in my string. Instead, I always want to get the second number in my string. The number is always 2 digits.
Example: 001a02.jpg I use the fileparts function to delete the extension of the image (jpg), so I get this string: 001a02
The expected return value is 02
Another example: 001A43a . Return values: 43
Another one: 002A12. Return values: 12
All the filenames are in a matrix 1002x1. Maybe I can use textscan but in the second example, it gives "43a" as a result.
(Just so this question doesn't remain unanswered, here's a possible approach: )
One way to go about this uses splitting with regular expressions (MATLAB's strsplit which you mentioned):
str = '001a02.jpg';
C = strsplit(str,'[a-zA-Z.]','DelimiterType','RegularExpression');
Results in:
C =
'001' '02' ''
In older versions of MATLAB, before strsplit was introduced, similar functionality was achieved using regexp(...,'split').
If you want to learn more about regular expressions (abbreviated as "regex" or "regexp"), there are many online resources (JGI..)
In your case, if you only need to take the 5th and 6th characters from the string you could use:
D = str(5:6);
... and if you want to convert those into numbers you could use:
E = str2double(str(5:6));
If your number is always at a certain position in the string, you can simply index this position.
In the examples you gave, the number is always the 5th and 6th characters in the string.
filename = '002A12';
num = str2num(filename(5:6));
Otherwise, if the formating is more complex, you may want to use a regular expression. There is a similar question matlab - extracting numbers from (odd) string. Modifying the code found there you can do the following
all_num = regexp(filename, '\d+', 'match'); %Find all numbers in the filename
num = str2num(all_num{2}) %Convert second number from str

How should I write a matrix onto a text in Hex format?

I have a matrix, say:
M = [1000 1350;2000 2040;3000 1400];
I wish to write this matrix onto a text file in the hex format, like this:
0x000003e8 0x00000bb8
0x000007d0 0x000007f8
0x00000bb8 0x00000578
I considered using the function dec2hex but it's very slow and inefficient. It also gives me the output as a string, which I don't know how to restructure for my above required format.
MATlab directly converts hex numbers to decimal when reading from a text file, ex. when using the function fscanf(fid,'%x').
Can we do the exact same thing while writing a matrix?
You can use the %x format string. For the sake of demonstration, see an example with sprintf below. If you want to write to a file, you will have to use fprintf.
M = [1000 1350;2000 2040;3000 1400];
str = sprintf('0x%08x\t0x%08x\n', M')
this results in
str =
0x000003e8 0x00000546
0x000007d0 0x000007f8
0x00000bb8 0x00000578
You may use num2str with a format string:
str = num2str(M, '0x%08x ');
which returns
str =
0x000003e8 0x00000546
0x000007d0 0x000007f8
0x00000bb8 0x00000578
Using this instead of sprintf you do not need to repeat the format string for each column.

matlab saving a cellarray

I have a script which does not fully work:
inputfield=input('Which field would you like to see: ','s')
if isfield(package, inputfield)
fprintf('The value of the %s field is: %c\n',inputfield,...
eval(['package.' inputfield]))
else
fprintf('Error: %s is not valid field\n', inputfield)
end
First I define a structure in matlab and then i use the script on the structure:
package=struct('item_no',123,'cost',19.99,'price',39.95,'code','g')
package =
item_no: 123
cost: 19.9900
price: 39.9500
code: 'g'
structurevalue
Which field would you like to see: cost
inputfield =
cost
The value of the cost field is: 1.999000e+001
structurevalue
Which field would you like to see: item_no
inputfield =
item_no
The value of the item_no field is: {
why cant it read value for item_no?
Try:
fprintf('The value of the %s field is: %s\n',inputfield,...
num2str(package.(inputfield)))
There were two issues with your version.
You were passing both numbers and strings into the %c field in your fprintf string. When a decimal goes in, it is interpreted as a number and displayed in full precision, which is why 19.99 got displayed as 1.999000e+001. But when an integer goes in, it gets interpreted as a character, which is why 123 got displayed as '{' (ASCII character 123). Use num2str to convert numbers to strings for display. Also, use %s for a string of any length, rather than %c for a character.
In general, it's not a good idea to use eval unless you have to. In this case, it's more convenient to use inputfield as a dynamic field name of package.