I need to create matrix in MATLAB with the following requirement. Given a vector v
, for example, [1,2,2,1,3,5,1]
, I need to form a matrix:
[1 0 0 1 0 0 1;
0 1 1 0 0 0 0;
0 0 0 0 1 0 0;
0 0 0 0 0 0 0;
0 0 0 0 0 1 0]
i.e. the matrix's i
th column contains only one non-zero element (a single 1
) at row v[i]
. How can I avoid a loop and do this in an efficient way?
Others are pointing out that loops are fine here. I'll point out that sparse is FAR better. Your matrix is sparse, very much so, so use the capability of sparse to solve the problem, and save a vast amount of storage in case that matrix is large.
So if the matrix is at all large, there is a huge difference in time.
How about space?
The matrices are identical otherwise.
The sparse matrix takes very little space, and you can use it just like any other matrix.
Use the capabilities of MATLAB.
First, I have to give my standard disclaimer, that despite the commonly held notion that loops should generally be avoided in MATLAB, loops have actually become much more efficient in modern releases of MATLAB, in large part, due to the JIT accelerator. So, certainly, benchmark your code to determine if loops actually are a bottleneck.
That said, my first thought on how to approach this problem without a loop was to index into an identity matrix (as shown below).
I think that this is a nice, clean looking solution; however, I don't necessarily know that it is significantly more efficient than using a loop. As a point of comparison, I implemented the following solution using a loop:
Based on my test runs, it looks like the top (no loop) solution is generally faster for those cases where
v
is not very long. However, whenv
contains many elements (>100 for example), I was actually seeing average times where the loop solution was beating the alternative.This is very similar to the step required in creating a target vector in Neural Network Assignment (Week 5- Handwritten Digit Recognition from Andrew NG ML course). We had to create a vector of 10 X 1 size for a single training output say ith output of y. If the ith training output in y is 2, the vectorized ith output was [0 1 0 0 0 0 0 0 0 0]'. So, For 5000 training examples, we required 5000 vectors.
Without much ado, The code is :
v_vec' is the desired output. A useful link : https://www.ee.columbia.edu/~marios/matlab/Matlab%20Tricks.pdf