2
votes

I want to replace value of n-th column of a matrix, based on a vector values, in a vectorized way.
Input:

[0 0 0 0]  
[0 0 0 0]  
[0 0 0 0]  
[0 0 0 0]  

Vector:

[2]  
[4]  
[1]  
[3]  

Expected output:

[0 1 0 0]  
[0 0 0 1]  
[1 0 0 0]  
[0 0 1 0]  

Matlab code with for-loop:

A = zeros(4,4);  
b = [2; 4; 1; 3];  
for row=1:4  
   A(row, b(row)) = 1;  
endfor  

Matlab code with sub2ind:

A = zeros(4,4);  
b = [2; 4; 1; 3];  
c = [[1:length(b)]' b];  
A(sub2ind(size(A), c(:,1), c(:,2))) = 1;  

Is there more vectorized way in Matlab? Thank you.

1

1 Answers

1
votes

You can use the raw version of sub2ind to solve it in a vectorized manner -

A( (b(:)-1)*size(A,1) + [1:numel(b)]' ) = 1;

How it works: Since elements of b are the column indices and MATLAB follows column-major indexing, so we need to multiply each such column index with the number of rows in A to get us the number of elements before starting that column, which would be (b(:)-1)*size(A,1). Then, add the corresponding row indices i.e. [1:numel(b)]' to give us the final linear indices, same as the ones produced by sub2ind. Finally, index into A with those linear indices and set them to all 1's as per the question's requirement.