How can I vectorize the following piece of code in Matlab?

Viewed 62

y is 5000 x 1 vector containing numbers 1 to 10. I can convert y to Y (5000 x 10 matrix) such that

Y = zeros(5000,10);
for i = 1:5000
    Y(i,y(i))=1;
end

Can I achieve the same result without using for loop?

3 Answers

A solution using implicit expansion:

Y = y == 1:10;

It creates a logical matrix. If you need a double matrix you can write:

Y = double(y == 1:10);

You can use sparse for that:

y = [8 5 7 4 2 6 4]; % example y. Arbitrary size
M = 10; % maximum possible value in y
Y = full(sparse(1:numel(y), y, 1, numel(y), M));

Equivalently, it can be done with accumarray:

Y = accumarray([(1:numel(y)).' y(:)], 1, [numel(y) M]);

In addition to @LuisMendo answer, you can also use sub2ind:

Y = zeros(5,10);                      % Y preallocation, zeros(numel(y),max_column)
y = [8 5 7 4 2];                      % Example y
Y(sub2ind(size(Y),1:numel(y),y)) = 1  % Linear indexation

Noticed that this method is slightly different than accumarray and sparse if there are duplicate pairs of [row,column] index:

% The linear index assigns the last value:
Y = zeros(2,2);
Y(sub2ind(size(Y),[1 1],[1,1])) = [3,4] % 4 overwrite 3

Result:

Y =

   4   0
   0   0

VS

% Sparse sum the values:
Y = full(sparse([1 1],[1,1], [3,4], 2, 2)) % 3+4

Result:

Y =

   7   0
   0   0
Related