displaying a vector in MATLAB using sprintf - matlab

I have a vector that looks like:
x =
4.250000000000000
2.719000000000051
5.953000000000088
2.656999999999925
I want to create a string that looks like:
'4.25, 2.72, 5.95, 2.67'
Maybe, I can do something like
disp(sprintf('% 4.2f, % 4.2f, % 4.2f, % 4.2f,', x));
Is there a good way to write those four % 4.2f without actually writing four times so that it can match the length of x?

As suggested by dpwe sprintf support vectorization by default thus
s = sprintf( '%.2f, ', x );
will result with
s =
4.25, 2.72, 5.95, 2.66,
you can remove the trailing comma simply by
s=s(1:end-2)
s =
4.25, 2.72, 5.95, 2.66

Related

Printing multiple disp functions with one for loop

So, I have a series of display functions, ranging from x1 to x7. These all contain both strings and variables like:
x1 = ['The result of the scalar multiplication of V and U: ',num2str(scalar_uv)];
x2 = similar to above but with for example a value on the cross multiplication of the two scalars.
Instead of printing out each one through:
disp(x1);
disp(x2);
disp(x3);
I thought it would be possible to print them all out through a for loop or perhaps a nested for loop but I just can't figure out how to do it. I preferably don't want straight up solutions (I won't say no to them) but rather some hints or tips of possible.
A simple example solution would be to make a cell array and loop through it, or use celldisp() to display it. But if you want to print nicely, i.e. formatted specifically, to the command window you can use the fprintf function and format in line breaks. For example:
for displayValue = {x1, x2, x3, x4}
fprintf('%s\n', displayValue{1});
end
If you want more formatting options, such as precision, or fieldwidth, the formatspec code (%s in the example) has many configurations. You can see them on the fprintf helpdoc. The \n just tells the fprintf function to create a newline when it prints.
Instead of creating seven different variables (x1...x7), just create a cell array to hold all your strings:
x{1} = ['The result of the scalar multiplication of V and U: ',num2str(scalar_uv)];
x{2} = ['Some other statement with a value at the end: ',num2str(somevar)];
Now you can write a loop:
for iX = 1:length(x)
disp(x{iX})
end
Or use cellfun to display them without a for loop:
cellfun(#disp,x)
If you really want to keep them named x1...x7, then you can use an eval statement to get your variable names:
for iX = 1:7
disp(eval(['x' num2str(iX)]));
end

Matlab: for loop and sprintf combination

I have the following data:
no_gridpoints = 640 % amount of columns in considered
surfaceelevation % a 1x640 array with surface elevation
Terskol1752, Terskol1753, ... Terskol2017 % 365x1 arrays with daily mean temperatures for 1 year of which the fifth colomn contains the temperature data
I want to create temp_glacier files with the corresponding year in the file name. This with a loop over all the years (1752-2017) by using the sprintf command in the loop:
for k = 1752:2017
for m = 1:no_gridpoints
sprintf('temp_glacier%d(m)',k) = sprintf('Terskol%d(:,5)',k) + surfaceelevation
end
end
However, I always get the error 'Subscripted assignment dimension mismatch.'. Can anyone tell me what I am doing wrong?
Thanks
As stated in my comment: it looks like you're mistaking sprintf for eval. The expression within sprintf is not evaluated, so your assignment is stating "make this string = this other string added to an array" - it makes no sense.
To correct your code as-is, you could do the following
for k = 1752:2017
for m = 1:no_gridpoints
eval(sprintf('temp_glacier%d(m) = Terskol%d(:,5) + surfaceelevation', k, k))
end
end
This is a bad idea
It would be far better practise for you to store your yearly data in a single cell array (or because it's numerical and the same size, just a standard matrix) rather than 266 individually named variables. I say better practise because if you to mean to use eval, you should know it should be avoided!
This method would look like the following:
Terskol = [ ... ] % your data here, in a 266*365 matrix where each row is a year
for k = (1752:2017) - 1751 % We actually want to loop through rows 1 to 266
for m = 1:no_gridpoints
% Your arrays were 1D, so you were originally getting a scalar temp val
% We can do that here like so...
temp_glacier(m) = Terskol(k, 5) + surfaceelevation;
% Now do something with temp_glacier, or there was no point in this loop!
% ...
end
end
Vectorising the inner loop:
for k = (1752:2017) - 1751 % We actually want to loop through rows 1 to 266
temp_glacier = repmat( Terskol(k, 5) + surfaceelevation, 1, no_gridpoints );
% Do something with temp_glacier...
end

Matlab num2str (A, format) function component-wise?

I have
a=[0.221354766 315.806415];
I want sth like (same fieldwidth)
0.2214 315.8064
I tried
b=num2str(a)
% b =
% 0.2213548 315.8064
c=num2str(a,'%8.4f')
% c =
% 0.2214315.8064
d=num2str(a,'%8.7g')
%d =
%0.2213548 315.8064
Any suggestion? Tks
If I understand you correctly, you want the same number of decimal places? If this is the case, just leave off the first number in your format string:
num2str([0.221354766 315.806415],'%.4f ')
ans =
'0.2214 315.8064'
If you want to store these values as strings, then by all means use num2str(a, '%.4f'). It seems odd to take a numerical martrix and store all of the values as strings though, to just round the result use round
m = round([0.221354766 315.806415], 4)
>> m = [0.2214, 315.8064]

How can I view all elements of a structure of arrays without writing a FOR-loop?

I am interested in seeing all the elements in the :
result(:,:).randMin(1:4,2:end)
in which the result(a=1:24, d=1:5).
In general is it possible to access them without a loop and cat ?
You cannot use the [] trick with multi-level indexing, but if all of randMin are 128 x 11 arrays:
out = [result(1:24,1:5).randMin];
out = reshape(out,[128 11, 24, 5]);
out = out(1:4,2:end,:,:);
Final result has size of 4 x 10 x 24 x 5 where the first two are your randMin(1:4,2:end), and last two dimensions are your a and d respectively.
It looks like you are looking for getfield:
getfield( result, {1:24, 1:5}, 'randMin', {1:4, 2:end} );
I'm a bit rusty with this command and you might need to play with it a bit to make it work.
Read its manual and good luck!
I don't think it is possible because randMin could be something else for every field in result. result(1,1).randMin could be a matrix, result(1,2).randMin could be a vector, result(2,1).randMin could be 4-dimensional...you see where I'm going with this.
So there is no way of knowing the dimensions or the size of each result's randMin without looping through all fields in result. If there is a function that does what you want, it will have to use a loop internally, so you might as well use a loop yourself.
Edit:
If it is constant you can try something like this:
%Generating matrix struct results(a,b).randMin(c,d)
dim1=24;
dim2=5;
dim3=128;
dim4=11;
% value=0;
% for i=1:dim1
% for j=1:dim2
% for k=1:dim3
% for l=1:dim4
% results(i,j).randMin(k,l)=value;
% value=value+1;
% end
% end
% end
% end
%Getting the values
range1=1:24;
range2=1:5;
range3=1:4;
range4=2:dim4;
myMat=[results(range1, range2).randMin];
myContainer=reshape(myMat, dim3, dim4, length(range1), length(range2));
desiredValues=myContainer(range3, range4,:,:);
In the end, desiredValues will have the values you want, but the indices switched sides, instead of results(a,b).randMin(c,d) it is now desiredValues(c,d,a,b).
As I didn't know exactly how your struct looks like, I defined dim1 to dim4 as maximum values for the indices a to d. You can use range1 to range4 to select your desired values.

generate a name vector MATLAB

How would I generate a vector like
x1,x2,x3,x4,...,xn
the problem is concatenate ','and a 'x' char
n=100
A = (1:n);
This is a slight improvement on #Jonas's answer. SPRINTF will do the repeating for you avoiding the need for a mask:
>> n = 5;
>> out = sprintf('x%u,', 1:n);
>> out(end) = []
out =
x1,x2,x3,x4,x5
To generate the string 'x1,x2' etc, you can create a mask for SPRINTF using REPMAT like so:
n = 5;
mask = repmat('x%i,',1,n);
out = sprintf(mask,1:n);
out = out(1:end-1)
out =
x1,x2,x3,x4,x5
Note that in case you actually want to create a vector containing the strings 'x1','x2' etc, you'd use ARRAYFUN to generate a cell array:
out = arrayfun(#(x)sprintf('x%i',x),1:n,'uniformOutput',false)
out =
'x1' 'x2' 'x3' 'x4' 'x5'
The better answer is, don't do it. While you CAN do so, this will likely cause more heartache for you in the future than you want. Having hundreds of such variables floating around is silly, when you can use an array to index the same data. Thus perhaps x{1}, x{2}, ....