In matlab, evaluating a variable without a semicolon causes it to be printed on the console output. disp is similar but does not include the variable name. Is there a way to get either console output as a string?
e.g.
>> x = [-1; 2];
>> x
x =
-1
2
Is there a way to get this output assigned to a variable in a string, i.e. in this example the string "x = \n\n -1\n 2\n"
x=[1;2]
s=evalc('x')
Then s='\nx =\n\n 0\n 1'
Related
I have defined a class like
classdef Test
properties
a
b
end
methods
function this = Test(a, b)
this.a = a;
this.b = b;
end
function disp(this)
fprintf('a=%d b=%d\n', this.a, this.b);
end
end
end
But when I want to display a vector of Test, it seems not print each elements of array using the disp function just defined.
>> out = [Test(1,2),Test(3,4)]
out =
a=1 b=3
a=2 b=4
The questions is how to display an array of objects appropriately? Is there a way to overload the disp function and print as the following:
out=
a=1 b=2
a=3 b=4
(In my considering , the output will be same as calling disp function to element of array one by one.. But the output seems like firstly print all the a's value 1 3 and then b's value 2 4.)
You are getting this result because in your statement out = [Test(1,2),Test(3,4)], the variable out becomes an array of the same class Test, but of size [1x2].
If you try out.a in your console, you'll get:
>> out.a
ans =
1
ans =
3
This is a coma separated list of all the values of a in the out array. This is also the first parameter that your custom disp function sees. It then sees another column vector of all the values of b. To understand what the function fprintf is presented with you can also try in your console:
>> [out.a,out.b]
ans =
1 3 2 4
>> [out.a;out.b]
ans =
1 3
2 4
Since fprintf works in column major order, it will consume all the values column wise first. In that case we can see that the last option we tried seems better.
Indeed, if you change your disp function to:
function disp(this)
fprintf('a=%d b=%d\n', [this.a ; this.b]);
end
You get the desired output:
>> out = [Test(1,2),Test(3,4),Test(5,6)]
out =
a=1 b=2
a=3 b=4
a=5 b=6
Whichever size of object array you define. Just keep in mind that if you input an array of Test object they will be considered column wise:
>> out = [ Test(1,2),Test(3,4) ; Test(5,6),Test(7,8) ]
out =
a=1 b=2
a=5 b=6
a=3 b=4
a=7 b=8
Last option, if you want even more granularity over the display of your object array, you can customise it the way you like inside the disp function:
function disp(this)
nElem = numel(this) ;
if nElem==1
fprintf('a=%d b=%d\n', this.a , this.b );
else
for k=1:nElem
fprintf('a=%d b=%d\n', this(k).a , this(k).b);
end
end
end
This produces the same display than before, but since the elements are treated one by one, you could customise even further without having to consider the way arrays are treated by fprintf.
With the syntax you use, you should overload the display function instead of the disp function.
See the (not that simple to read) corresponding page in the documentation.
I am trying to define the following function in MATLAB:
file = #(var1,var2,var3,var4) ['var1=' num2str(var1) 'var2=' num2str(var2) 'var3=' num2str(var3) 'var4=' num2str(var4)'];
However, I want the function to expand as I add more parameters; if I wanted to add the variable vark, I want the function to be:
file = #(var1,var2,var3,var4,vark) ['var1=' num2str(var1) 'var2=' num2str(var2) 'var3=' num2str(var3) 'var4=' num2str(var4) 'vark=' num2str(vark)'];
Is there a systematic way to do this?
Use fprintf with varargin for this:
f = #(varargin) fprintf('var%i= %i\n', [(1:numel(varargin));[varargin{:}]])
f(5,6,7,88)
var1= 5
var2= 6
var3= 7
var4= 88
The format I've used is: 'var%i= %i\n'. This means it will first write var then %i says it should input an integer. Thereafter it should write = followed by a new number: %i and a newline \n.
It will choose the integer in odd positions for var%i and integers in the even positions for the actual number. Since the linear index in MATLAB goes column for column we place the vector [1 2 3 4 5 ...] on top, and the content of the variable in the second row.
By the way: If you actually want it on the format you specified in the question, skip the \n:
f = #(varargin) fprintf('var%i= %i', [(1:numel(varargin));[varargin{:}]])
f(6,12,3,15,5553)
var1= 6var2= 12var3= 3var4= 15var5= 5553
Also, you can change the second %i to floats (%f), doubles (%d) etc.
If you want to use actual variable names var1, var2, var3, ... in your input then I can only say one thing: Don't! It's a horrible idea. Use cells, structs, or anything else than numbered variable names.
Just to be crytsal clear: Don't use the output from this in MATLAB in combination with eval! eval is evil. The Mathworks actually warns you about this in the official documentation!
How about calling the function as many times as the number of parameters? I wrote this considering the specific form of the character string returned by your function where k is assumed to be the index of the 'kth' variable to be entered. Array var can be the list of your numeric parameters.
file=#(var,i)[strcat('var',num2str(i),'=') num2str(var) ];
var=[2,3,4,5];
str='';
for i=1:length(var);
str=strcat(str,file(var(i),i));
end
If you want a function to accept a flexible number of input arguments, you need varargin.
In case you want the final string to be composed of the names of your variables as in your workspace, I found no way, since you need varargin and then it looks impossible. But if you are fine with having var1, var2 in your string, you can define this function and then use it:
function str = strgen(varargin)
str = '';
for ii = 1:numel(varargin);
str = sprintf('%s var%d = %s', str, ii, num2str(varargin{ii}));
end
str = str(2:end); % to remove the initial blank space
It is also compatible with strings. Testing it:
% A = pi;
% B = 'Hello!';
strgen(A, B)
ans =
var1 = 3.1416 var2 = Hello!
How can I use the variable name from an input with the sprintf function and write it as part of the filename.
allData = input('Introduce a variable name:','s');
matfilename = sprintf('xcross_%d_.mat',names(k));
i.e: During the input process I enter the variable name Hands_X
So I want to added into the filename as this:
xcross_0914_Hands_X.mat
Thank you so much advance!!!!
Since you mentioned in the comment that you don't know how to add the variable containing the string as another argument, I'm going to explain the principle of using sprintf.
Let's have a look at the documentation accessible by doc sprintf in the command window or in the online documentation here:
str = sprintf(formatSpec,A1,...,An)
We see that sprintf takes a variable amount of arguments. In fact the number of arguments reflect - simply speaking - the number of %-constructs in the string formatSpec. So when you only have one variable that should be formatted and inserted into the output str, the command looks very simple (similar to your question):
>> A1 = 42;
>> sprintf('demo_%d',A1)
ans =
demo_42
Now we can add another variable by adding a new %-construct in the format-string and by writing the new variable containing the actual value as another argument A2.
>> A1 = 42;
>> A2 = 'test';
>> sprintf('demo_%d_%s',A1,A2)
ans =
demo_42_test
Note that I used the term %-construct as simplification for the term formatting operator. In the documentation you'll find a lot of information on how to use them.
Of course we can add some more variables and format them a bit:
>> A1 = 42;
>> A2 = 'test';
>> A3 = 0.012345;
>> A4 = 12;
>> sprintf('demo_%d_%s %.2e %X',A1,A2,A3,A4)
ans =
demo_42_test 1.23e-02 C
You can do this my simply adding an additional string input to sprintf
allData = input('Introduce a variable name:','s');
matfilename = sprintf('xcross_%d_%s.mat', names(k), allData);
In Matlab, I need to format a latex string containing a numeric variable.
The string is like: foo1 , where 1 is contained in variable X and must be subscript.
This line works if I write directly the value of variable
str = texlabel('foo_{1}')
I'm wondering how to insert the X instead of the value.
In fact this line
str = texlabel('foo_{X}')'
produce, of course, fooX
Thanks
The quickest method would be to include a call to sprintf:
X = 1;
str = texlabel(sprintf('foo_{%u}', X));
Which returns:
str =
{foo}_{{2}}
Which we can plot real quick with text(0.1, 0.1, str):
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!