Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access matrix value using a vector of coordinates?

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?

like image 921
drsealks Avatar asked Mar 23 '23 21:03

drsealks


2 Answers

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.

like image 141
wakjah Avatar answered Apr 01 '23 15:04

wakjah


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;
like image 27
Eitan T Avatar answered Apr 01 '23 15:04

Eitan T