I have a matrix:
A = [1 1 1
2 2 2
3 3 3]
Is there a vectorized way of obtaining:
B = [1 0 0
0 1 0
0 0 1
2 0 0
0 2 0
0 0 2
3 0 0
0 3 0
0 0 3]
I have a matrix:
A = [1 1 1
2 2 2
3 3 3]
Is there a vectorized way of obtaining:
B = [1 0 0
0 1 0
0 0 1
2 0 0
0 2 0
0 0 2
3 0 0
0 3 0
0 0 3]
An alternative, which (for me) is faster than any of the methods benchmarked above (for large and small matrices) is
Here's another way using
sparse
andrepmat
:The original matrix is in
A
, and I transpose it so I can unroll the rows of each matrix properly for the next step. I usesparse
to declare what is non-zero in a matrix. Specifically, we see that there is only one entry per row and so the row indices should range from 1 up to as many entries as there are inA
. The columns fluctuate from 1 up to the last column and repeat.mod
is certainly the way to go via thewaywewalk's solution, but I wanted to userepmat
so that this is an independent solution from his approach. As such, we create a vector for accessing the columns that goes from 1 up to as many columns as we have, and we repeat this for as many rows as we have. These row and column index vectors are is going to dictate where the non-zero locations will appear. Finally, what will go into each non-zero location are the elements ofA
unrolled in row major order, following the order dictated by the row and column index vectors.Take note that in the
repmat
call, the rows and columns when callingsize
are reversed due to the transpose operation.The result thus follows and we get:
Given the sparsity of the above problem, it may be faster to leave the matrix in
sparse
form and only convert usingfull
if necessary. There will be time spent to convert between the two formats so take that into consideration if you decide to benchmark.Edit: I guess thewaywewalk's benchmark leaves me only with a readability argument ;)
Edit using Beaker's suggestion:
This code converts A to a cell array of row vectors, applies the
diag
function to each, and then stacks them:Results:
This is one solution using
mod
andsub2ind
:Or if you prefer saving lines of code, instead of readability:
Two other fast solutions, but not faster than the others:
For the sake of competition - Benchmark