3

I have a 3d matrix H(i,j,k) with dimensions (i=1:m,j=1:n,k=1:o). I will use a simple case with m=n=o = 2:

H(:,:,1) =[1 2; 3 4];
H(:,:,2) =[5 6; 7 8];

I want to filter this matrix and project it to an (m,n) matrix by selecting for each j in 1:n a different k in 1:0.

For instance, I would like to retrieve (j,k) = {(1,2), (2,1)}, resulting in matrix G:

G = [5 2; 7 4];

This can be achieved with a for loop:

filter = [2 1]; % meaning filter (j,k) = {(1,2), (2,1)}

for i = 1:length(filter)
    G(:,i) = squeeze(H(:,i,filter(i)));
end

But I'm wondering if it is possible to avoid the for loop via some smart indexing.

Divakar
  • 218,885
  • 19
  • 262
  • 358
jruizaranguren
  • 12,679
  • 7
  • 55
  • 73

1 Answers1

3

You can create all the linear indices to get such an output with the expansion needed for the first dimension with bsxfun. The implementation would look like this -

szH = size(H)
offset = (filter-1)*szH(1)*szH(2) + (0:numel(filter)-1)*szH(1)
out = H(bsxfun(@plus,[1:szH(1)].',offset))

How does it work

  • (filter-1)*szH(1)*szH(2) and (0:numel(filter)-1)*szH(1) gets the linear indices considering only the third and second dimension elements respectively. Adding these two gives us the offset linear indices.

  • Add the first dimenion linear indices 1:szH(1) to offset array in elementwise fashion with bsxfun to give us the actual linear indices, which when indexed into H would be the output.

Sample run -

H(:,:,1) =
     1     2
     3     4
H(:,:,2) =
     5     6
     7     8
filter =
     2     1
out =
     5     2
     7     4
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • Divakar, just a question. Why do you need to use .' symbol and the squared brakets around 1:szH(1)? Is it not equivalent to simple ' and parenthesis?. Thanks. – jruizaranguren Oct 23 '15 at 07:18
  • 1
    @jruizaranguren On `.'` thing, [`this`](http://stackoverflow.com/a/25150319/3293881) might provide some good reasons. On using `[]`, yes, you can also use parenthesis, both would work. – Divakar Oct 23 '15 at 07:58