I'm looking for a completely general way to convert any value to a string in MATLAB.
Basically, I want to be able to write something like
x = disp(y);
The above fails with the error Too many output arguments. (I was not able to find the source code for disp.)
Is there a single MATLAB function for converting any value into a string?
(Note that this function should behave like the identity when passed a string.)
Basically I'm looking for MATLAB's equivalent of Python's str. I thought it might be char, but (for example) char(Inf) fails to produce anything like the string 'Inf'. (Note: that was just an example. It does not begin to cover all the possibilities.)
pm89's answer has the right idea, but doesn't work because evalc requires a string as input. I suggest making your own function like so:
function str = anything2string(thing)
str = evalc('disp(thing)');
It works for anything that Matlab can display:
>> anything2string(3)
ans =
3
>> anything2string(Inf)
ans =
Inf
>> anything2string('hi')
ans =
hi
>> anything2string(1:4)
ans =
1 2 3 4
It's not quite the same as Python's str, but num2str works with Inf and handles strings as input.
num2str(Inf)
ans = Inf
num2str('some string')
ans = some string
You could get the exact same string as you see in your command window using evalc (evaluate and capture the result):
x = evalc('disp(y)'); % y could be anything displayable by Matlab!
Related
I would like to convert a scientific number to a string in Matlab but using a rather specific format. I started with the following:
>> num2str(1E4, '%e')
ans =
'1.000000e+04'
Then played around with the formatstring to get rid of the digits after the decimal point in the first part
>> num2str(1E4, '%.0e')
ans =
'1e+04'
The thing is I want it exactly how I am expressing it in numbers, namely I want a string like this '1E4'. I could use strrep to get rid of that plus sign but I refuse to use it to get rid of the leading 0 on the +04 part since I have other instances of the variable which have things like +10. It it feasible to reproduce the number as a string without resorting to some big complicated algorithm? Preferably using the formatstring?
Solution
According to num2str documentation, you need to use a format parameter of and precision parameter as follows:
num2str(1E4,'%.E')
Result
ans = 1E+04
Read about sprintf . LEt A be your number, to achieve what you want, you can use:
sprintf('%1.0e',A)
Here is a way to convert integers to scientific notation:
function out= scientific(num)
E = 0;
if mod(num,10) == 0
[f n]=factor(num);
E=min(n(ismember(f,[2 5])));
end
out = sprintf('%dE%d',num/10^E,E);
end
>> scientific(134)
ans = 134E0
>> scientific(134000)
ans = 134E3
Another solution that accepts input as vector:
function out= scientific2(num)
E = sum(cumsum(num2str(num(:))-48,2,'reverse')==0,2);
out = num2str([num(:)./10.^E,E],'%dE%d\n');
end
You could use a combination of sprintf and regexprep.
my_format = #(x)regexprep(sprintf('%.E',x),'E\+0*','E');
Examples:
>> my_format(1E4)
ans =
1E4
>> my_format(2E12)
ans =
2E12
This is not ideal for all cases:
>> my_format(5) % Expect 5E0
ans =
5E
>> my_format(1E-4) % Expect 1E-4
ans =
1E-04
We can fix the first case with a token:
f2 = #(x)regexprep(sprintf('%.E',x),'E\+0*(\d)','E$1');
>> {f2(1E4), f2(1E20), f2(5)}
ans =
'1E4' '1E20' '5E0'
And we can fix the second case with tokens and a ? quantifier:
>> f3 = #(x)regexprep(sprintf('%.E',x),'E\+?(-?)0*(\d)','E$1$2');
>> {f3(1E4), f3(1E20), f3(5),f3(1E-1),f3(2E-12)}
ans =
'1E4' '1E20' '5E0' '1E-1' '2E-12'
To explain, sprintf('%.E',x) formats x in scientific notation with E, e.g. 1E+04, then it finds
'E\+?(-?)0*(\d)'
E The literal E
\+?(-?) Either a + or a -; if - then save to group $1
0* As many 0s as it can match, subject to...
(\d) At least one digit, saves digit to group $2
Finally, the matched text is replaced with E$1$2, that is the literal E, then group $1 (a minus sign if found E-, nothing if found E+) and the group $2 (a single digit).
im trying to make a script to be able to calculate a vector of numbers and math symbols to convert back to a single string
im using eval() function and example would be
str = '4*2'
eval(str)
and the result would be
ans =
8
but when i create into a vector and convert back using horzcat the result won't work.
Number = [52 42 50]
Number1 = (mat2str(char(Number)))
str = horzcat(Number1)
eval(str)
and i would get
ans =
4*2
can anyone help me find the problem with the script?
Your problem is with the mat2str command. This is unecesarry. The char command already returns a string. You end up with a string in a string, so when you eval in your code, you just display the inner string.
First - You should not use eval!
Second, there is no need in horzcat and mat2str in your code. Just write:
str = char(Number)
Below is the output from the Matlab's console. Both of the strings are the same: '#TBMA3'. Yet Matlab's strcmp function returns 0 when comparing them. Why?
K>> str='#TBMA3'
str =
#TBMA3
K>> method.fhandle
ans =
#TBMA3
K>> strcmp(method.fhandle, str)
ans =
0
The most likely reason is that method.fhandle is not a string, but a function handle. Check if class(method.fhandle) gives
ans =
function_handle
In that case, the comparison gives 0 because a string (str) cannot be equal to a function handle (method.fhandle).
In order to check for equality, you would need to convert method.fhandle to a string, or str to a function handle. The first option is not adequate, because char(function_handle) would give 'TBMS3', without '#'. So use the second option, and compare using isequal:
isequal(method.fhandle, str2func(str))
should give 1.†
† This isequal comparison works because both method.fhandle and str2func(str) point to the same already-defined function TBMA3. Compare with f = #(x)x; g = #(x)x, isequal(f,g), which gives 0. This behaviour is explained in the documentation. Thanks to #knedlsepp for helping clarify this.
I got a strange piece of code to debug which to my opinion should throw an exception but instead it produced totally odd results. Reduced it to these two lines:
EDU>> A={0,0}
A =
[0] [0]
EDU>> A{1:2}==A{2:1}
ans =
1
Why is the comparison of two non equal comma separated lists true?
The line of code A{1:2}==A{2:1} is not checking the equality of two comma-separated lists because 2:1 is an empty array. I think the intended indexing was 2:-1:1; this will create a comma-separated list but also throw an error since == cannot handle the list.
However, it is odd that A{1:2}==A{2:1} produces a valid output of any kind in my mind. The code is literally saying A{1:2} == A{[]}, and the question is "what is A{[]}?" According to my MATLAB R2014b, nothing, which makes some sense, but even a simple double array with an empty index returns an empty double. I guess the actual content, which is what is retreived by { and }, is nothing so, yeah.
But then how is MATLAB producing the answer of true?
Consider the following code from the command window:
>> A = {0,0}; A{1:2} == A{[]}
ans =
1
>> A = {0,1}; A{1:2} == A{[]}
ans =
0
From that, I surmise that MATLAB places the comma-separated list as the first two arguments to eq and appends A{[]} nothing to it and interpret it simply as
eq(0,0,A{[]})
eq(0,1,A{[]})
which is, apparently, valid syntax (eq(a,b,) is not). It is very interesting for a binary operation on elements of a cell array. This also works:
>> A = {[2,3],[3,2]};
>> A{1:2} .* A{[]}
ans =
6 6
>> A{1:2} ./ A{[]}
ans =
0.6667 1.5000
And just for fun, because I'm finding this quite interesting:
>> A = {rand(2),rand(2,1)};
>> A{1:2} \ A{[]}
ans =
0.8984
-0.7841
But I guess it makes sense. The parser finds a token, followed by an infix operator, followed by another token. It resolves the infix operator to its function, and then places the left and right tokens into the argument list in turn.
I guess I just find it a odd about the existence of "nothing"; although that would explain how [1,2,3,] is valid syntax.
That said, I'm sure this is a quirk of the language and not a bug nor a feature.
Of course, the only way to know what is actually going on is to have an intimate knowledge of how MATLAB is interpreting the cell array expansion and application of the operator. Of course, I do not have this experience nor the source required (I'd imagine).
Since both are 0. Try A = {1, 2} then you will get ans = 0
It looks like this has been asked many times, but none of the past posts seem to solve my question. All those had to do with matrix/vector while my code does not have any of these, just simple variables. It takes three variables as arguments. It works perfectly fine within the Matlab environment. I only got the error when I compiled it with mcc -m Normal.m and tried to run with the executable like this "./Normal 1 5 0.5". The complete error message is:
Error using /
Matrix dimensions must agree.
Error in Normal (line 4)
MATLAB:dimagree
It is complaining about line 4: N=2/dt, what is wrong with this?
Here is the code:
function val=Normal(l1,l2,dt)
const=(l2/l1-1);
N=2/dt;
S=1.0/sqrt(l2/l1);
Z(1)=S;
for i=2:N
t= -1+(i-1)*dt;
Z(i)=1.0/sqrt(const*t*t+1);
S=S+2*Z(i);
end
Z(21)=1.0/(l2/l1);
S=S+1.0/sqrt(l2/l1);
val=dt*S/2;
end
But dt is not a scalar when passed into the standalone through the command ./Normal 1 5 0.5. It is a character array with 3 elements ('0', '.','5')!
When passing numerical arguments to a standalone, they are passed as strings. Thus, inside the function, you need to convert '0.5' into a double, and similarly for l1 and l2:
dt = str2num(dt);
l1 = str2num(l1);
l2 = str2num(l2);
Note that you can use isdeployed to determine at runtime if the function is a standalone:
if isdeployed, dt = str2num(dt); end
And you might need to display the result:
if isdeployed, disp(val); end
Result:
>> system('Normal 1 5 0.5');
1.4307
>> Normal(1,5,0.5) % .m function for comparison
ans =
1.4307