Address Complex numbers and create new matrix in MATLAB - matlab

I have a complex matrix of size 3x2x372 complex double. I would like to work with only one specific of these three dimensions. Therefore, I used the following code to make the table easier to read:
new_output = abs(output);
In fact, the new matrix is of size 3x2x372 double. I guess it makes the further computation simpler. So I obtain the following output:
I would now like to create a matrix that only refers to the highlighted values. So it should ideally be of size 2x372 double.

Make a for-loop and assign the last row to a new matrix.
mat = zeroes(372, 2)
for k = 1:372
a = val(:, :, k)
mat(k, :) = a(1, :)
end
Edit: above gives you a 372x2 matrix. Use below to get a 2x372 matrix
mat = zeroes(2, 372)
And
mat(:, k) = a(1,:).'
in the loop

Actually, you need the last row from each "slice", so you can get it by:
new_output=data(size(data,1),:,:);
But that will give you the same dimensions as the original matrix, with 3D. To directly get it as 2D matrix, use squeeze:
new_output=squeeze(data(size(data,1),:,:));

Related

How do I reshape a non-quadratic matrix?

I have a column vector A with dimensions (35064x1) that I want to reshape into a matrix with 720 lines and as many columns as it needs.
In MATLAB, it'd be something like this:
B = reshape(A,720,[])
in which B is my new matrix.
However, if I divide 35604 by 720, there'll be a remainder.
Ideally, MATLAB would go about filling every column with 720 values until the last column, which wouldn't have 720 values; rather, 504 values (48x720+504 = 35064).
Is there any function, as reshape, that would perform this task?
Since I am not good at coding, I'd resort to built-in functions first before going into programming.
reshape preserves the number of elements but you achieve the same in two steps
b=zeros(720*ceil(35604/720),1); b(1:35604)=a;
reshape(b,720,[])
A = rand(35064,1);
NoCols = 720;
tmp = mod(numel(A),NoCols ); % get the remainder
tmp2 = NoCols -tmp;
B = reshape([A; nan(tmp2,1)],720,[]); % reshape the extended column
This first gets the remainder after division, and then subtract that from the number of columns to find the amount of missing values. Then create an array with nan (or zeros, whichever suits your purpose best) to pad the original and then reshape. One liner:
A = rand(35064,1);
NoCols = 720;
B = reshape([A; nan(NoCols-mod(numel(A),NoCols);,1)],720,[]);
karakfa got the right idea, but some error in his code.
Fixing the errors and slightly simplifying it, you end up with:
B=nan(720,ceil(numel(a)/720));
B(1:numel(A))=A;
Create a matrix where A fits in and assingn the elemnent of A to the first numel(A) elements of the matrix.
An alternative implementation which is probably a bit faster but manipulates your variable b
%pads zeros at the end
A(720*ceil(numel(A)/720))=0;
%reshape
B=reshape(A,720,[]);

matlab Create growing matrix with for loop that grows by 3 per loop

So I have written this:
HSRXdistpR = squeeze(comDatape_m1(2,7,1,:,isubj));
HSRXdistpL = squeeze(comDatape_m1(2,4,1,:,isubj));
TocomXdistp = squeeze(comDatape_m1(2,10,1,:,isubj));
for i = 1:2;
HSRXp = NaN(8,3*i);
HSRXp(:,i*3) = [HSRXdistpR(:,i) HSRXdistpL(:,i) TocomXdistp(:,i)];
end
In the first part I am just selecting data from a 5-D matrix, nothing special. All that's important here is that it creates an 8x2 matrix per line (isubj=2). Now I want to add the first column of each matrix into an 8x3 matrix, and then the second column of each matrix into the same matrix (creating an 8x6 matrix). Since the number of my subjects will vary, I want to do this in a for loop. This way, if the isubj increases to 3, it should go on to create an 8x9 matrix.
So I tried to create a matrix that will grow by 3 for each iteration of i, which selects the ith column of each of the 3 matrices and then puts them in there.
However I get the following error:
Subscripted assignment dimension mismatch.
Is it possible to let a matrix grow by more than one in a for loop? Or how should it be done otherwise?
Here is your problem:
HSRXp(:,i*3) = [HSRXdistpR(:,i) HSRXdistpL(:,i) TocomXdistp(:,i)];
You're trying to assign an n x 3 matrix (RHS) into an n x 1 vector (LHS). It would be easier to simply use horizontal concatenation:
HSRXp = [HSRXp, [HSRXdistpR(:,i) HSRXdistpL(:,i) TocomXdistp(:,i)]];
But that would mean reallocation at each step, which might slow your code down if the matrix becomes large.

How should I progressively add results to a matrix?

I want to initialise a matrix in MATLAB and add things to it with a loop. I am unsure of how big it should be to start off with, but I want to be able to add as many sub-matrices to it as is required.
You can define it empty:
matrix = [];
and then append rows, columns, or submatrices:
matrix = [matrix; newSubMatrix];
matrix = [matrix, newSubMatrix];
However, enlarging the matrix this way causes Matlab to reallocate memory. If this happens at each loop iteration your code will be slow.
A better approach is to initialize to an approximate size:
matrix = zeros(M,N);
and then fill elements in:
matrix(m,n) = exampleEntry;
matrix(m,:) = exampleRow;
matrix(:,n) = exampleCol;
This way, only if m or n get larger than M and N does Matlab need to enlarge the matrix.
I would suggest to initialise a larger matrix:
x=nan(n,m)
After adding your data, cut it:
[a,b]=ind2sub(size(x),find(~isnan(x),1,'last'))
x=x(1:a,1:b)
This assumes you do not use nan in your data.

replace all numbers in a matrix

There are two matrices; the first one is my input matrix
and the second one ("renaming matrix") is used to replace the values of the first one
That is, looking at the renaming matrix; 701 must be replaced by 1,...,717 must be replaced by 10,etc.. such that the input matrix becomes as such
The ? values are defined but i didn't put them. The second column of the input matrix is already sorted(ascending order from top down) but the values are not consecutive(no "710": see first pic).
The question is how to get the output matrix(last pic) from the first two.
Looks to me like it's screaming for a sparse matrix solution. In matlab you can create a sparse matrix with the following command:
SM = sparse( ri, ci, val );
where ri is the row index of the non-zero elements, ci is the corresponding column index, and val is the values.
Let's call your input matrix IM and your lookup matrix LUM, then we construct the sparse matrix:
nr = size(LUM, 1);
SM = sparse( ones(nr, 1), LUM(:, 1), LUM(:, 2) );
Now we can get your result in a single line:
newMatrix = reshape(SM(1, IM), size(IM));
almost magic.
I didn't have a chance to check this tonight - but if it doesn't work exactly as described, it should be really really close...
If the values in the first column all appear in the second column, and if all you want is replace the values in the second column by 1..n and change the values in the first column accordingly, you can do all of this with a simple call to ismember:
%# define "inputMatrix" here as the first array in your post
[~,newFirstColumn] = ismember(inputMatrix(:,1),inputMatrix(:,2));
To create your output, you'd then write
outputMatrix = [newFirstColumn,(1:length(newFirstColumn))'];
If M is the original matrix and R is the renaming matrix, here's how you do it
N = M;
for n = 1:size(M,1)
N(find(M==R(n,1))) = R(n,2);
end
Note that in this case you're creating a new matrix N with the renamed values. You don't have to do that if you like.

How do I create a matrix whose elements are the sum of the row and column numbers?

I need to create a 95x95 matrix in MATLAB in which each element is a sum of its row and column number.
I'm new at this so I can't really think of a way to tell MATLAB to just create a matrix without putting the elements in.
From what I understand I'll have to initiate a loop for the sum part.
No math needed if you use HANKEL:
A = hankel(2:96, 96:190);
I propose another strategy, as simple as EitanT's one:
v = 1:95;
A = bsxfun(#plus,v,v');
There is no need "reinventing the wheel" with loops. Try this:
[X, Y] = meshgrid(1:95, 1:95);
A = X + Y
The desired output is stored in matrix A.