How should I progressively add results to a matrix? - matlab

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.

Related

Removing rows based on a condition (Matlab)

I am trying to remove rows from a matrix based on a condition. I have a 371000x5 double matrix, and a 371000x1 vector of dummies (1 and 0). I want to remove each row from the original matrix, where the value of the vector of dummies is 1.
I have tried the following, but it is taking very long:
for i = 1:size(matrix_num,1)
if missing_matrix(i,1) >=0
matrix_num(i,:) = [];
end
end
My Matlab has been busy for over 30 minutes now, so I am not even sure if the code is right. Is there a more efficient way to do this?
Additionally, I have to do the same action on a cell matrix (categorical data). Should I expect any huge difference from the numerical matrix?
The programmatic way of doing this is:
new_matrix = old_matrix(missing_vector==1,:)
for keeping lines with missing_vector 1
new_matrix = old_matrix(missing_vector==0,:)
for removing lines with missing_vector 1
For educational values, if you want the loop to work, don't do that row by row. Your solution causes the matrix to be copied and re-allocated on every row removed.
So, you would be better off if you calculate the resulting matrix size in advance:
new_matrix = zeros(sum(missing_vector), 5)
and then your iteration would work:
index_new=1
for index_old = 1:size(old_matrix,1)
if missing_vector(index_old) ==0
new_matrix(index_new,:) = old_matrix(index_old,:);
end
end
Try compact MATLAB code
matrix_num(missing_matrix>=0,:)=[]
Note : You must make a vector for missing_matrix variable. If this variable is matrix, you need other form of code .
As I know, you can use it in cell array too.

Address Complex numbers and create new matrix in 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),:,:));

MATLAB: Insert leading rows in every slice of 3D matrix

I need to insert some leading zeros in every slice of a 3D matrix. I am wondering whether there is a more elegant way rather than using a for-loop, such as this one:
orig3D = rand(5,1,2);
for n = 1 : 2
new3D(:,:,n) = [zeros(3,1); orig3D(:,:,n)];
end
The code can be vectorised, avoiding the loop:
new3D = [zeros(3,1,2); orig3D];

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.