Access matrix value using a vector of coordinates?

2019-02-24 12:06发布

问题:

Let's say we have a vector:

b = [3, 2, 1];

Let's say we also have matrix like this:

A = ones([10 10 10]);

I want to use vector b as a source of coordinates to assign values to matrix A. In this example it will be equivalent to:

A(3, 2, 1) = 5;

Is there an easy way in MALTAB to use a vector as a source of coordinates for indexing a matrix?

回答1:

You can do this by converting your vector b into a cell array:

B = num2cell(b);
A(B{:}) = 5;

The second line will expand B into a comma-separated list, passing each element of B as a separate array index.

Generalization

If b contains coordinates for more than one point (each row represents one point), you could generalize the solution as follows:

B = mat2cell(b, size(b, 1), ones(1, size(b, 2)));
A(sub2ind(size(a), B{:}))

Here b is converted into cell array, each cell containing all the coordinates for the same dimension. Note that A(B{:}) won't produce the result we want (instead, this will select all elements between the top left and bottom right coordinates), so we'll have to do an intermediate step of converting the coordinates to linear indices with sub2ind.



回答2:

The straightforward way to do it would be:

A(b(1), b(2), b(3)) = 5;

Another way would be to convert the coordinates to a linear index, similar to function sub2ind:

idx = [1, cumprod(size(A))] * [b(:) - 1; 0] + 1;
A(idx) = 5;

This solution can be further extended for multiple points, the coordinates of which are stored in the rows of b, and the assigned values in vector vals, that equals in length to the number of rows of b:

idx = [1, cumprod(siz(2:end))] * (reshape(b, [], ndims(A)) - 1)' + 1;
A(idx) = vals;