0

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!

Mohsen Nosratinia
  • 9,844
  • 1
  • 27
  • 52
Ben
  • 11
  • 3

3 Answers3

3
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))
Oleg
  • 10,406
  • 3
  • 29
  • 57
  • 1
    Shouldn't it be `pos+shift+1`, and `shift*2+1`? I tried what you posted and the bottom row of the result was missing. – Dan455 Jun 27 '13 at 21:01
  • Well wait now that creates an issue if you try to get any element from the bottom row... – Dan455 Jun 27 '13 at 21:15
  • 1
    You can pad `A` with `bread = NaN(shift,size(A,2));`, `A = [bread;A;bread]` and increment `pos = pos+shift;`. – Oleg Jun 27 '13 at 21:28
1

You may use

r = 3;
B = A(bsxfun(@plus, pos, (-r:r)'));
Mohsen Nosratinia
  • 9,844
  • 1
  • 27
  • 52
0

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{:}].

p8me
  • 1,840
  • 1
  • 15
  • 23