1

is there any possibility to assign multiple values for a matrix from an another vector without a loop?

For example:

I have a matrix filled with zeros:

matrix=zeros(2);
matrix =

 0     0      
 0     0      

Now i have an another vector where the first two columns are the positions and the third column are the values wich belongs to the corresponding positions.

 values=[2 1 4;1 2 2]
 values =

        Posx PosY   Value
        2     1     4
        1     2     2

The result should look like:

matrix = 
             0     2  <-- matrix(values(2,1),values(2,2))=values(2,3) ;     
             4     0  <-- matrix(values(1,1),values(1,2))=values(1,3);
Cœur
  • 37,241
  • 25
  • 195
  • 267
Hakan Kiyar
  • 1,199
  • 6
  • 16
  • 26
  • 2
    Duplicate of [Changing the value of multiple points in a matrix](http://stackoverflow.com/questions/6850368/changing-the-value-of-mulitple-points-in-a-matrix) and [Matlab: assign to matrix with column\row index pairs](http://stackoverflow.com/q/7119581/52738). – gnovice Mar 26 '12 at 13:45

2 Answers2

1

This isn't pretty, but it is a one liner:

matrix(size(matrix,1) * (values(:,2) - 1) + values(:,1)) = values(:,3)

I can make it a bit clearer by splitting it into two lines. The idea is that you transform the first two columns of values into a one dimensional indexing vector which has as many elements as there are values to be assigned, and then assign values:

index = size(matrix,1) * (values(:,2) - 1) + values(:,1)

matrix(index) = values(:,3)

When you index into a matrix with a vector it counts down the columns first, and then across the rows. To make it even more clear, split the first statement up some more:

numRows  = size(matrix,1)
rowIndex = values(:,1)
colIndex = values(:,2)
vals     = values(:,3)
index    = numRows * (colIndex - 1) + rowIndex

matrix(index) = vals

In fact, you don't need to go through all the trouble of building the index vector, as the function sub2ind exists to do that for you:

index = sub2ind(size(matrix), rowIndex, colIndex)

matrix(index) = vals

although I think it's good to see how to get the results with a call to sub2index, for your own education.

Chris Taylor
  • 46,912
  • 15
  • 110
  • 154
0

I made a function to do that, you can use it, if you want:

function B = ndassign( A , varargin )
%%% copy A to B, and assign values to A at specified nd indexes
%%% B=ndind(A,X,Y,Z,V)
%%%   ---> B(X(i),Y(i),Z(i))=V(i)
%%% Example:
%%% ndassign(eye(3),[1 2 3],[3 2 1],[4 5 6])
%%% ans =
%%%      1     0     4
%%%      0     5     0
%%%      6     0     1

B=A;
inds=sub2ind(size(A),varargin{1:end-1});
B(inds)=varargin{end};

end
Oli
  • 15,935
  • 7
  • 50
  • 66