How to select selective indices base column from matrix? - matlab

I have a matrix named eta (54×1800). For selecting specific rows and columns typically we use:
result = eta(:, 86:90:1800);
But here I need to select consecutive 5 columns 86,87,88,89,90 each having difference 90. e.g after 86, 87, 88, 89, 90, I want to get 176, 177, 178, 179, 180.
I tried this:
result=eta(:,[86:90:1800,87:90:1800,88:90:1800,89:90:1800,90:90:1800]);
But it does not give the result of consecutive columns.

If your first index is a(=86), the end of region to extract is b(=1800) and the difference is d(=90), then you would do:
s = a:d:b; % create all start indices
k = cumsum([s; ones(4,numel(s))],1) % compute all consecutive indices
result = eta(:,k(:)); % exctract all indeces using linear index for the column subscript

try this
mat=rand(54,1800); %your eta matrix
mywish=[86:1:90]; %your wish to select consective columns
for i=1:length(mywish)
results=mat(:,mywish(i):90:1800) %getting the column interval 90
end

Related

How to use several loops to make calculations in a matrix?

I have a 9 x 682 matrix (A). Every 36 columns correspond to a new variable (17 variable in total). For each variable (36 columns), I want to calculate the mean of every 6th column (i.e. mean of columns 1, 7, 13, 19, 31 and so on for each block of 36 columns.
I am stuck with the use of several For loops.
A_averaged = zeros(9,102);
for i = 1:36:length(A)
for j = i:i+35
for k = j:6:j+1
A_averaged(:,k) = mean(A(:,k), 2);
end
end
end
Any help is much appreciated.
To vectorize this, I would reshape your data in a smart way, select the columns you want, and then compute the mean.
% Reshape data to 3D with dimensions: 9 x 36 x (nGroups)
B = reshape(A, size(A, 1), 36, []);
% Now grab the columns of each chunk you want
C = B(:, 1:6:end, :);
% Now compute the mean along the first dimension and squeeze the result
result = squeeze(mean(C, 1));
You can do this in one line with the following:
result = squeeze(mean(reshape(A(:, 1:6:end), size(A, 1), 6, []), 1))
If you instead want the mean of all rows and columns, you can reshape your data into 45 x nGroups and compute the mean along the first dimension
result = mean(reshape(C, [], size(C, 3)), 1);
As a side note, your initial dimensions of 9 x 682 are not actually divisible by 36 columns. Did you mean 9 x 612?

Matlab: Looping over segments of an array

I have 2 m x n matrices and would like to calculate canonical correlations for segments within a given window length. For example, if my window length is 100, I'd like to have the correlation coefficients for
canoncorr(X(1:100,:),Y(1:100,:))
canoncorr(X(101:200,:),Y(101:200,:))
canoncorr(X(201:300,:),Y(201:300,:))
...
and so on all accumulated into one matrix. I am only interested in the correlation coefficient r.
I am trying the following:
win=100;
r=[];
for i=1:win:size(X,1)-win-2
[A,B,r(i,:)] = canoncorr(X(i:i+win,:),Y(i:i+win,:));
end
However, my resulting matrix does not only save the values from row 1, 101, 201 etc. but also fills the rows between 1 and 101 and so on with zeroes.
If I try
[A,B,r(i:i+win,:)] = canoncorr(X(i:i+win,:),Y(i:i+win,:));
then subscripted assignment dimensions mismatch.
What am I doing wrong?
i goes from 1, 101, 201, ...
so, please check for 101th row and see if they are zero.
you can also spy(r) to see matrix elements.

How do I efficiently replace elements in the first column of a 3D matrix

I have a 3D matrix: size(data) = [100, 3, 500]
I want to replace all the -1s in the first column with 1s.
Then, I want to replace all the -1s in the second and third columns with 0s.
Linear indexing doesn't seem to work because I have to replace the second and third column as well.
Can't you just do:
col1 = data(:,1,:);
col1(col1 == -1) = 1;
data(:,1,:) = col1;
etc...?

Converting Matrix into an array

I have a matrix that is size(A) = 20x301088 and another vector linear_index which is 301088x1.
I need to convert A into an array that is 97x97x32x20. But it has to be in a certain order, the vector linear_index contains the linear indices of a 97x97x32 in a specific order.
For example, the element at A(20,4) should be put into linear_index(4) of B(:,:,:,20). Hopefully that makes sense. Each row of A will make its own 97x97x32 matrix, and the elements will be placed at the indices specified by the value in linear_index.
I have done it once but it requires the shiftdim command:
B(1:length(lx) , linear_index) = A(1:length(lx) , :);
B = shiftdim(A,1);
This works, but the shiftdim command takes a bit of time, especially as the size of my matrices can go up to 97x97x32x194.
How about
>> B = A(:,linear_index)'; %' re-order and permute
>> B = reshape( B, 97, 97, 32, 194, 20 );

Column selection in Matlab

Is it possible to select only particular columns of a matrix? E.g. I have a 10x100 shaped matrix and I only would like to get these 4 columns: 231, 82, 12, 493.
Yes, it is possible. If your matrix is named A then A(:, [3,7,12,89]) will retrieve the columns numbered 3, 7, 12, and 89.