4
votes

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.

2
The difficulty is here the dimensionality, especially if you do not know it at programming time. What I did in the past is putting a slicing string together and then using eval for it. Not nice, but if anyone has a better idea for an arbitrary number of dimensions. – Trilarion
@Trilarion In that case you can use a comma-separated list generated from a cell array; see my updated answer – Luis Mendo

2 Answers

5
votes

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{:});
2
votes

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);