tef2128
tef2128

Reputation: 780

assign new matrix values based on row and column index vectors

New to MatLab here (R2015a, Mac OS 10.10.5), and hoping to find a solution to this indexing problem.

I want to change the values of a large 2D matrix, based on one vector of row indices and one of column indices. For a very simple example, if I have a 3 x 2 matrix of zeros:

A = zeros(3, 2)

0 0
0 0
0 0

I want to change A(1, 1) = 1, and A(2, 2) = 1, and A(3, 1) = 1, such that A is now

1 0
0 1
1 0

And I want to do this using vectors to indicate the row and column indices:

rows = [1 2 3];
cols = [1 2 1];

Is there a way to do this without looping? Remember, this is a toy example that needs to work on a very large 2D matrix. For extra credit, can I also include a vector that indicates which value to insert, instead of fixing it at 1?

My looping approach is easy, but slow:

for i = 1:length(rows)

    A(rows(i), cols(i)) = 1;

end

Upvotes: 1

Views: 2592

Answers (3)

tef2128
tef2128

Reputation: 780

I found this answer online when checking on the speed of sub2ind.

idx = rows + (cols - 1) * size(A, 1);

therefore

A(idx) = 1 % or b

5 tests on a big matrix (~ 5 second operations) shows it's 20% faster than sub2ind.

There is code for an n-dimensional problem here too.

Upvotes: 1

Daniel
Daniel

Reputation: 36720

What you have is basically a sparse definition of a matrix. Thus, an alternative to sub2ind is sparse. It will create a sparse matrix, use full to convert it to a full matrix.

A=full(sparse(rows,cols,1,3,2))

Upvotes: 0

RTL
RTL

Reputation: 3587

sub2ind can help here,

A = zeros(3,2)
rows = [1 2 3];
cols = [1 2 1];

A(sub2ind(size(A),rows,cols))=1
A =

     1     0
     0     1
     1     0

with a vector to 'insert'

b = [1,2,3];
A(sub2ind(size(A),rows,cols))=b

A =

     1     0
     0     2
     3     0

Upvotes: 4

Related Questions