How to display sequence numbers in Matlab in a better way? - matlab

For example, I have an array:
a=[1:5 8:10];
If I display it using:
disp(['a = ' num2str(a)]);
The result would be something like
a = 1 2 3 4 5 8 9 10
It's quite too long than I need. How can I let Matlab to display as same as the way I defined it or as close as is?
Be more specific, if I defined the variable in an "informal" way like:
a=[1:3 4:6 8:10]
(should be normally 1:6 instead of 1:3 4:6)
I just want Matlab to display in either way:
1:3 4:6 8:10 or 1:6 8:10
I also not care about whether it displays the variable name or square brackets.
Searched but didn't find anything useful. Considered to manually parse it but doesn't sounds like a clever way.
Any suggestion would be great helpful, thanks a lot.

The only way to do this would be to create your own function to display the arrays in the format you want. For example, if you want to display monotonically-increasing portions of your array in a condensed fashion, you could use a function like this:
function display_array(array)
str = cellfun(#(n) {num2str(n)}, num2cell(array));
index = (diff(array) == 1) & ([1 diff(array, 2)] == 0);
str(index) = {':'};
str = regexprep(sprintf(' %s', str{:}), '( :)+\s*', ':');
disp([inputname(1) ' = [' str(2:end) ']']);
end
And you would use it like so:
>> a = [1:5 7 9:11] %# Define a sample array
a =
1 2 3 4 5 7 9 10 11 %# Default display
>> display_array(a)
a = [1:5 7 9:11] %# Condensed display
>> b = [1 2 3 4 4 4 3 2 1]; %# Another sample array
>> display_array(b)
b = [1:4 4 4 3 2 1] %# Note only the monotonically increasing part is replaced

For this, I use vec2str from the Matlab file exchange. For example:
str = vec2str([1 3 5 5 9 8 7 6 5])
ans =
[1:2:5,5,9:-1:5]
>> eval(str)
ans =
1 3 5 5 9 8 7 6 5

Impossible. Matlab throws away your definition very quickly. The "object" a has no knowledge of that definition at all.

Related

how to reverse the element of matrix?

I am trying to reverse the elements of the matrix such that for given matrix order of the elements get reversed.
my code is as shown for the 3x3 matrix is working.
X = [ 1 2 3 ; 4 5 6 ; 7 8 9 ];
B = [fliplr(X(3,:));fliplr(X(2,:));fliplr(X(1,:))];
input X =
1 2 3
4 5 6
7 8 9
output:
B =
9 8 7
6 5 4
3 2 1
the above code I am trying to generalize for any matrix with the following code
[a,b]=size(X);
for i=0:a-1
A = [fliplr(X(a-i,:))];
end
but get only last row as output.
output A =
3 2 1
please help me to concatenate all the rows of the matrix one above to each other after it got reversed.
rot90 is the function made for this purpose.
B = rot90(A,2);
Your code doesn't work because you overwrite A in every loop iteration. Instead, you should index into A to save each of your rows.
However, fliplr can flip a whole matrix. You want to flip left/right and up/down:
B = flipud(fliplr(X));
This is the same as rotating the matrix (as Sardar posted while I was writing this):
B = rot90(X,2);
A totally different approach would work for arrays of any dimensionality:
X(:) = flipud(X(:));

how to use inputdlg with for loop in matlab

have tried searching but can't find anything to help, maybe my problem is too simple! Anyway, I'm running a nested FOR loop, but the array I save my results to only keeps the last "run" of results. Can someone please help me to store/concatenate the results ?
clc
clear
n = 2;
for aa = 1:n
aa = inputdlg({'Depth from','Depth to','Outer Diameter','Nominal Weight'},'1',[1 7;1 7;1 30;1 30]);
x = [str2num(aa{1}),str2num(aa{2}),str2num(aa{3}),str2num(aa{4})]
end
and the results
x =
1 2 3 4
x =
5 6 7 8
I cannot use the first one,
want to save all the results and save every iteration in a single variable
That is not the way to save the result into an array in a for loop; separate the looping variable and the array you are storing values in:
clc
clear
n = 2;
x = zeros(n, 4);
for k = 1:n
aa = inputdlg({'Depth from','Depth to','Outer Diameter','Nominal Weight'},'1',[1 7;1 7;1 30;1 30]);
x(k, :) = [str2double(aa{1}),str2double(aa{2}),str2double(aa{3}),str2double(aa{4})];
end
Then if you display x you get something like:
x =
1 2 3 4
5 6 7 8
Assuming you entered 1 to 4 and then 5 to 8 in the dialog.

visualizing 2D-graphs of n-dim. array via surf() in matlab

I want to show 2dim. Surface plots for different combinations of 2 parameters of a 3- or higher-dimensional array in matlab. The data for the non-shown dimensions are integrated (i.e. summed in the remaining dimensions). I am using surf(), and for parameter combinations other than (1,2) (eg. (1,3), (2,3) ...) I have to rearrange the data matrices in order to make it work.
I am looking for an alternative command (or shorter code) which does this work.
Here's the code:
a=zeros(3,3,2);
a(:,:,1) = [1 2 3 ;4 5 6; 7 8 9; 10 11 12]; % // data matrix
a(:,:,2) = -[1 2 3 ;4 5 6; 7 8 9; 10 11 12]*2; % // data matrix
ai=[[1 2 3 4]' [5 6 7 0]' [8 9 0 0]']; % // parameter vector
mat12 = sum(a,3);
surf(ai(1:3,2),ai(1:4,1),mat12)
aux13 = sum(a,2);
for i = 1:2; mat13(:,i) = aux13(:,:,i);
surf(ai(1:2,3),ai(1:4,1),mat13)
aux23 = sum(a,1);
for i = 1:2; mat23(i,:) = aux23(:,:,i);
surf(ai(1:3,2),ai(1:2,3),mat23)
In other words, I am looking for a way to use surf for matrices mat13 and mat23 without the aux13, aux23 variables and the for loop.
First your example doesn't run because you declare a=zeros(3,3,2); as a matrix [3x3x2] but you immediately try to populate it as a [4x3x2] matrix, so I had to adjust your first line to: a=zeros(4,3,2);
If I run your code with that adjustment, your auxiliary variable and for loops are to reform/reshape a matrix stripped of it's singleton dimension. Matlab provide a handy function for that : squeeze.
For example, your variable aux13 is of dimension [4x1x2], then mat13=squeeze(aux13); achieve the same thing than your for loop. Your matrix mat13 is now of dimension [4x2].
Since no for loop is needed, you can completely bypass your auxiliary variable by calling squeeze directly on the result of your summation: mat13=squeeze( sum(a,2) );
Full example, the code below does exactly the same than your code sample:
mat12 = sum(a,3);
surf(ai(1:3,2),ai(1:4,1),mat12)
mat13 = squeeze( sum(a,2) ) ;
surf(ai(1:2,3),ai(1:4,1),mat13)
mat23 = squeeze( sum(a,1) ) ;
mat23 = mat23.' ; %'// <= note the "transpose" operation here
surf(ai(1:3,2),ai(1:2,3),mat23)
Note that I had to transpose mat23 to make it match the one in your example.
sum(a,1) is [1x3x2] => squeeze that and you obtain a [3x2] matrix but your code arrange the same values in a [2x3] matrix, so the use of the transpose. The transpose operator has a shorthand notation .'.
I used it in the example in a separate line just to highlight it. Once understood you can simply write the full operation in one line:
mat23 = squeeze(sum(a,1)).' ;
The way you write your loops isn't exactly MATLAB syntax. Below is the correct loop syntax shown.
On line 2 and 3, you are trying to load (4x3)-matrices into (3x3)-matrices. That is why you get a subscript error. You could resolve it by making the zeros-matrix bigger. Here's some Syntax fixed:
a=zeros(4,3,2);
a(:,:,1) = [1 2 3 ;4 5 6; 7 8 9; 10 11 12]; % // data matrix
a(:,:,2) = -[1 2 3 ;4 5 6; 7 8 9; 10 11 12]*2; % // data matrix
ai=[[1 2 3 4]' [5 6 7 0]' [8 9 0 0]']; % // parameter vector
mat12 = sum(a,3);
surf(ai(1:3,2),ai(1:4,1),mat12)
aux13 = sum(a,2);
for i = 1:2 mat13(:,i) = aux13(:,:,i);
surf(ai(1:2,3),ai(1:4,1),mat13)
end
aux23 = sum(a,1);
for i = 1:2 mat23(i,:) = aux23(:,:,i);
surf(ai(1:3,2),ai(1:2,3),mat23)
end
Now, what are you exactly trying to do inside those loops?

Adding time slice in a matlab output using fprintf

I have matlab output of a complex number, where 'modTrace' contains the complex numbers. to write my output in a file called '3pt.txt' I write the following:
modTrace
fileID = fopen('3pt.txt','w');
fprintf ( fileID,'%e+%ei\n',real ( traces ), imag ( traces ) );
fclose(fileID);
The output looks like this:
2.355387e-13+3.263411e-12i
3.037095e-12+1.848502e-12i
2.264321e-12+1.408536e-12i
3.808791e-13-1.647224e-14i
-3.249665e-14+7.954636e-15i
7.026766e-14+1.056313e-13i
and so on. Now if I want the output with time slice numbers to the left, something like:
0 2.355387e-13+3.263411e-12i
1 3.037095e-12+1.848502e-12i
2 2.264321e-12+1.408536e-12i
3 3.808791e-13-1.647224e-14i
4 -3.249665e-14+7.954636e-15i
5 7.026766e-14+1.056313e-13i
and so on, how to I edit the code?
Thank you in advance for help.
Your fprintf statement is not working the way you are intending. It prints out all the values in real(traces) before getting to imag(traces). For example,
>> v = [1 2; 3 4; 5 6]
v =
1 2
3 4
5 6
>> fprintf('%d %d\n',v(:,1),v(:,2))
1 3
5 2
4 6
To pair values the way intended, you need to transpose the matrix:
>> fprintf('%d %d\n',v.')
1 2
3 4
5 6
Following this example, you can prepend slice numbers as follows:
v = [(1:numel(traces)).' real(traces(:)) imag(traces(:))].';
fprintf(fileID,'%d %e+%ei\n',v)

Is there a non-iterative equivalent of this expression in MATLAB?

The expression is:
for i=1:n
X(:,i) = [P{i}(:)];
end
where X is a DxN matrix and P is a cell-array.
reshape(cat(3,P{:}),[numel(P{1}) n])
Of course, the above solution is just for fun. I would recommend profiling both solutions and only using this one if it has a significant performance advantage.
Maintenance and readability are also very important factors to consider when writing code.
If you obtained the cell array via mat2cell, you may be wanting to arrange blocks of an image into the columns of an array X. This can be achieved in a single step using the command IM2COL
%# rearrange the large array so that each column of X
%# corresponds to the 4 pixels of each 2-by-2 block
X = im2col(largeArray,[2 2],'distinct');
You might be able to get away with:
P{1} = [ 1 2; 3 4];
P{2} = [ 7 8; 9 10];
P{3} = [ 11 12; 13 14];
X = [P{:}]
X =
1 2 7 8 11 12
3 4 9 10 13 14
Then some sort of reshape() to get to where you want to be.