loop a matrix through disorder columns indices - matlab

I have a matrix A which has 100 rows and 5 columns, I would like to iterate the matrix with disorder indices of columns and save them in each iteration, column indices [2;5;3;4;1].
1st iteration: get all the rows of A with column 2 then do some processes.
2nd iteration : get all the rows of A with columns 2 and 5.
.....
last iteration: get all the rows and columns of A.
Anyone helps me to implement it on Matlab environment please.

Define the column indices as cols = [2 5 3 4 1]; and iterate through each submatrix of A like subA = A(:,cols(1:i)).
A = rand(100,5);
cols = [2 5 3 4 1];
for i = 1:length(cols)
subA = A(:,cols(1:i));
% do calculations on subA ..
end

Related

Count rows of a matrix and give back an array

I would like to know how to count rows in an matrix in such a way that gives an output for each colum. for example:
X=[1 1 1;
5 5 5]
I would like to find a command that when I input the matrix X the answers is [2 2 2], so that it counts the number of rows per column.
I have already found nunel(X) but the answer is a scalar numel(X)=6, whereas I need per column.
size(X,1) will give you the number of rows in the matrix (a scalar). a matrix has only one number of rows, i.e. each column has the same number of rows.
however if you still want the number of rows per each column you can use:
X = [1 1 1;
5 5 5];
nrows = size(X,1);
ncols = size(X,2);
nrowsPerCol = repmat(nrows, [1 ncols]) % [2 2 2]
Each matrix object in MATLAB has height and width property.
In other words: each column has the same number of rows.
To get this value, use MATLAB's size function:
[numOfRows, numOfCols] = size(X);

Delete a row and a column at the same time in a matrix

Is it possible to delete a row and a column of a matrix at the same time ?
Example:
M = magic(3)
M =
8 1 6
3 5 7
4 9 2
And with a one-liner remove the column 2 and the row 2 to obtain:
M =
8 6
4 2
You can supply an array of indices for the row and column indices and MATLAB will automatically return all permutations (usually an annoying feature, but a benefit here).
So you could do something like:
M([1 3], [1 3])
Or more flexible, you could use logical indexing
M([true false true], [true false true])
Or more generally (with potentially more rows and columns)
row = 2; % Could be an array of rows to exclude
column = 2; % Could be an array of columns to exclude
out = M(~ismember(1:size(M, 1), row), ~ismember(1:size(M, 2), column))

Get even/odd indices of a matrix - MATLAB

I have following problem:
I have a given matrix of let's say 4x4.
How can I get the indices of the following combinations:
row odd and column odd
row odd and column even
row even and column odd
row even and column even
For example if I have the matrix:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
'row odd and column odd' would be the indices of 1, 3, 9, 11...
'row odd and column even' would be the indices of 2, 4, 10, 12...
'row even and column odd' would be the indices of 5, 7, 13, 15...
and 'row even and column even' would be indices of 6, 8, 14, 16...
Also, is it possible to combine those operations so e.g. I get the indices for 'row odd and column odd' and 'row even and column even'?
Thank you!
It's pretty easy to do with indexing:
Odd rows and odd columns
B = A(1:2:end, 1:2:end);
Odd rows and even columns
B = A(1:2:end, 2:2:end);
Even rows and odd columns
B = A(2:2:end, 1:2:end);
Even rows and even columns
B = A(2:2:end, 2:2:end);
The above assumes that you want the actual matrix values themselves. It's a bit confusing as your matrix elements are the same as linear indexing values themselves. If you want to determine the actual column major indices to access the matrix, you can generate a vector from 1 to N where N is the total number of elements in your matrix, then reshape this matrix into the desired size that you want. After, use the same logic above to get the actual linear indices:
N = numel(A);
B = reshape(1:N, size(A,1), size(A,2));
ind = B(1:2:end, 1:2:end); %// For odd rows, odd columns
%// Repeat for the other ones...
Now, given your comment, you want to create a new matrix that will store only these extracted matrix values while making all of the other elements zero. If you want to do this, simply pre-allocate a matrix of zeroes, then copy over those values to extract using the computed indices into the new matrix. In other words:
N = numel(A);
B = reshape(1:N, size(A,1), size(A,2));
ind = B(1:2:end, 1:2:end); %// For odd rows, odd columns - Change to suit your tastes
out = zeros(size(A));
out(ind(:)) = A(ind(:));
If you want to combine the indices like having odd row - odd column, and even row - even column, just compute two sets of indices, concatenate them into a single vector and do the same syntax like before. Therefore:
N = numel(A);
B = reshape(1:N, size(A,1), size(A,2));
ind = B(1:2:end, 1:2:end); %// For odd rows, odd columns
ind2 = B(2:2:end, 2:2:end); %// For even rows, even columns
ind = [ind(:); ind2(:)];
out = zeros(size(A));
out(ind) = A(ind);
Code
N = size(A,1); %// Get size of input matrix A
case1_ind = bsxfun(#plus,[1:2:N]',(0:N/2-1)*2*N)
case2_ind = case1_ind + N
case3_ind = case1_ind + 1
case4_ind = case3_ind + N
Note: These outputs are indices. So, to get the actual outputs, use these as indices.
To combine indices for case 1 and case 4, just concatenate -
case14comb_ind = [case1_ind ; case4_ind]
Edit :
%// To copy onto some other matrix of the same size as A, do this for case 1
new_matrix = zeros(size(A))
new_matrix(case1_ind(:)) = A(case1_ind(:))
Repeat this for the other cases too.

Find rows that match between two unequal matrices (one is subset of anotherusing two columns of data)

I have tried the code below to find matches, but I have gotten the error that matrix dimensions must agree.
mat = [ 8 5; 4 3; 3 5]
mat2 = [2 3; 2 3; 4 3; 4 3]
for i=1:size(mat,1)
idx= find(mat2(:,1) == mat(i,1)& mat2(:,2) == mat(i,2));
end
idx= find(mat2(:,1) == mat(:,1))
I need to find rows that match between two unequal matrices using two columns of data (x&y coordinates for example) in order to append a column of data to the correct rows in the larger matrix. I basically need to find the rows in the larger matrix where values match those values in the smaller matrix so that the column of data from the smaller matrix can be appended to the correct row.
I think you want:
>> [c,imat,imat2] = intersect( mat, mat2, 'rows')
c =
4 3
imat =
2
imat2 =
4
c are the rows that match.
imat are the indices of the matching rows in mat
imat2 are the indices of the matching rows in mat2

Subtotal Calculation in Matlab

I would like to take subtotal of table in matlab. If the values of two columns are equal, take the value and add if there is an entry.
If we give an example, source matrix is as follows:
A = [1 2 3;
1 2 2;
1 4 1;
2 2 1;
2 2 3];
The output would look like this:
B = [1 2 5;
1 4 1;
2 2 4];
If the first two columns are equal, sum the third column. Is there a simple way of doing, without having to loop several times?
You can do this with a combination of unique and accumarray:
%# find unique rows and their corresponding indices in A
[uniqueRows,~,rowIdx]=unique(A(:,1:2),'rows');
%# for each group of unique rows, sum the values of the third column of A
subtotal = accumarray(rowIdx,A(:,3),[],#sum);
B = [uniqueRows,subtotal];
You can use unique to get all of the groups, then splitapply to sum them
[u, ~, iu] = unique( A(:,1:2), 'rows' ); % Get unique rows & their indices
sums = splitapply( #sum, A(:,3), iu ); % Sum all values according to unique indices
output = [u, sums]
% >> output =
% output =
% 26 7 124
% 26 8 785
% 27 7 800
This is a late answer because a duplicate question has just been asked so I posted here instead. Note that splitapply was introduced in R2015b, so wasn't around when the accumarray solution was posted.