Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MATLAB: How to subset a multidimensional matrix using 1-D vector indices without for loops?

I am currently looking for an efficient way to slice multidimensional matrices in MATLAB. Ax an example, say I have a multidimensional matrix such as

A = rand(10,10,10)

I would like obtain a subset of this matrix (let's call it B) at certain indices along each dimension. To do this, I have access to the index vectors along each dimension:

ind_1 = [1,4,5]
ind_2 = [1,2]
ind_3 = [1,2]

Right now, I am doing this rather inefficiently as follows:

N1 = length(ind_1)
N2 = length(ind_2)
N3 = length(ind_3)

B = NaN(N1,N2,N3)

for i = 1:N1
   for j = 1:N2
     for k = 1:N3

      B(i,j,k) = A(ind_1(i),ind_2(j),ind_3(k))

     end
   end
end

I suspect there is a smarter way to do this. Ideally, I'm looking for a solution that does not use for loops and could be used for an arbitrary N dimensional matrix.

like image 477
Berk U. Avatar asked Mar 16 '23 03:03

Berk U.


2 Answers

Actually it's very simple:

B = A(ind_1, ind_2, ind_3);

As you see, Matlab indices can be vectors, and then the result is the Cartesian product of those vector indices. More information about Matlab indexing can be found here.

If the number of dimensions is unknown at programming time, you can define the indices in a cell aray and then expand into a comma-separated list:

ind = {[1 4 5], [1 2], [1 2]};
B = A(ind{:});
like image 143
Luis Mendo Avatar answered Apr 26 '23 15:04

Luis Mendo


You can reference data in matrices by simply specifying the indices, like in the following example:

B = A(start:stop, :, 2);

In the example:

  1. start:stop gets a range of data between two points
  2. : gets all entries
  3. 2 gets only one entry

In your case, since all your indices are 1D, you could just simply use:

C = A(x_index, y_index, z_index);
like image 32
James Taylor Avatar answered Apr 26 '23 17:04

James Taylor