Ben
Ben

Reputation: 11

Matlab: How can I shift columns independently in a matrix?

I have a matrix of 10X3 and I want to make a new matrix using only a subset of each column but I want the subset to be different for each column based on an index array and a defined range from that point.

For example if the matrix is (the numbers will not actually go up in such a linear fashion when I'm doing this):

A = ...
   [1   11  21
    2   12  22
    3   13  23
    4   14  24
    5   15  25
    6   16  26
    7   17  27
    8   18  28
    9   19  29
    10  20  30]

and the index array is pos = [5,16,24] with a spread of +/-3 (so 3 cells either side of each indexed cell) then I want the new matrix to be:

2   13  21
3   14  22
4   15  23
5   16  24
6   17  25
7   18  26
8   19  27

So in the new matrix all of the values referenced by the index array should line up.

I'm actually doing this with much larger matrices (up to 400X100) so I'm not sure if loops would be a good idea….

Thanks for any ideas!

Upvotes: 0

Views: 1268

Answers (3)

Mohsen Nosratinia
Mohsen Nosratinia

Reputation: 9864

You may use

r = 3;
B = A(bsxfun(@plus, pos, (-r:r)'));

Upvotes: 1

Oleg
Oleg

Reputation: 10686

shift          = 3;

% Prevent out of bounds
bread          = NaN(shift,size(A,2));
A              = [bread;A;bread] 
pos            = pos+shift;

% Create mask
B              = zeros(size(A));
B(pos-shift)   = 1;
B(pos+shift+1) = -1;
B              = logical(cumsum(B));

% Select and reshape
reshape(A(B),shift*2+1,numel(pos))

Upvotes: 3

p8me
p8me

Reputation: 1860

Here is a way with arrayfun:

r = 3; % Spread range
B = arrayfun(@(x) A(x-r:x+r)', pos, 'UniformOutput', false);

B would be a cell however, you can get a matrix with: [B{:}].

Upvotes: 0

Related Questions