Forming a 'partial' identity-matrix according to a partially filled vector

• A+
Category：Languages

I'm currently forming a matrix from a vector in MATLAB following the scheme described below:

Given is a vector x containing ones and zeros in an arbitrary order, e.g.

x = [0 1 1 0 1];

From this, I would like to form a matrix Y that is described as follows:

• Y has m rows, where m is the number of ones in x (here: 3).
• Each row of Y is filled with a one at the k-th entry, where k is the position of a one in vector x (here: k = 2,3,5)
• For the example x from above, this would result in:

Y = [0 1 0 0 0;      0 0 1 0 0;       0 0 0 0 1]

This is identical to an identity matrix, that has its (x=0)th rows eliminated.

I'm currently achieving this via the following code:

x = [0,1,1,0,1]; %example from above m = sum(x==1); Y = zeros(m,numel(x)); p = 1; for n = 1:numel(x)     if x(n) == 1         Y(p,n) = 1;        p = p+1;     end   end

It works but I'm kind of unhappy with it as it seems rather inefficient and inelegant. Any ideas for a smoother implementation, maybe using some matrix multiplications or so are welcome.

Here are a few one-line alternatives:

• Using sparse:

Y = full(sparse(1:nnz(x), find(x), 1));
• Similar but with accumarray:

Y = accumarray([(1:nnz(x)).' find(x(:))], 1);
• Using eye and indexing. This assumes Y is previously undefined:

Y(:,logical(x)) = eye(nnz(x));