Replace specific columns in a matrix with a constant column vector

matlab, matrix

Solution

From the context of your question, you wish to find a matrix where each column is an identity vector. For an identity vector, each column in this matrix is a non-zero vector where 1 is set in the position of the vector denoted by each position of `y` and 0 otherwise. Therefore, let's say we had the following example:

y = [1 5 4 3]

You would have `y_out` as the final matrix, which is:

y_out =

     1     0     0     0
     0     0     0     0
     0     0     0     1
     0     0     1     0
     0     1     0     0

There are several ways to do this. The easiest one would be to declare the identity matrix with `eye`, then let `y` pick out those columns that you want from this matrix and place them as columns into your final matrix. If `y` had all unique values, then we would simply be rearranging the columns of this identity matrix based on `y`. As such:

y_out = eye(max(y));
y_out = y_out(:,y)

y_out =

     1     0     0     0
     0     0     0     0
     0     0     0     1
     0     0     1     0
     0     1     0     0

Another way would be to declare a `sparse` matrix, where each row index is simply those elements from `y` and each column index is increasing from 1 up to as many elements as we have `y`:

y_out = sparse(y, 1:numel(y), 1, max(y), numel(y));
y_out = full(y_out)

y_out =

     1     0     0     0
     0     0     0     0
     0     0     0     1
     0     0     1     0
     0     1     0     0

One more way would be to use `sub2ind` to find linear indices into your matrix, then access those elements and set them to 1. Therefore:

ind = sub2ind([max(y) numel(y)], y, 1:numel(y));
y_out = zeros(max(y), numel(y));
y_out(ind) = 1

y_out =

     1     0     0     0
     0     0     0     0
     0     0     0     1
     0     0     1     0
     0     1     0     0

Problem

For neural networking, I would like to represent a column vector `y = [1;2;3]` in a matrix like so: ``` y = [1 0 0; 0 1 0; 0 0 1] ``` My vector `y` is very large, and so hardcoding is not an option. Also, I would like to avoid using `for`-loops. What I did so far: ``` y1 =[y; zeros(1,length(y)) ;zeros(1,length(y))] % add two rows with zeros in orde to give y the right format idx = find(y1(1,:) == 2); % find all the columns containing a 2 y1(:,idx(1):idx(end)) = y1(:,[0;1;0]); % this does not work because now I am comparing a matrix with a vector ``` I also tried this: ``` y1( y1 == [2;0;0] )=[0;1;0]; % This of course does not work ``` Is there a way to specify I want to compare columns in `y1 == [2;0;0]`, or is there another way to solve this?

Original source