Suppose I have a matrix such that each row is a standard basis vector, i.e. each row contains exactly one 1, the other columns being 0.
Is there a convenient way to create such a matrix (i.e. given a vector of positions of where the ones are in each row)?
Also, is there a way I should represent such a matrix so that multiplications with it can be done more efficiently in octave?
Suppose you want a 3x3 matrix with the ones in columns 3, 1, and 2 respectively:
> pos = [3,1,2];
> x = eye(3)(pos,:);
will give you a matrix with 9 elements, most zero, with the ones in the desired places. You can save memory by using a sparse representation: sparse_x = sparse(x);
. But the following test on my machine implies that the natural form multiplies faster:
> N = 10000;
> s = rand(N,N);
> x = eye(N)(randperm(N),:);
> sx = sparse(x);
> t = cputime(); ss = s*x; cputime()-t
ans = 0.41124
> t = cputime(); ss2 = s*sx; cputime()-t
ans = 1.0313
This was Octave 3.4 on a Core i7, YMMV.
Looking at whos
it appears that Octave is doing something clever with x
:
> whos
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
N 1x1 8 double
s 10000x10000 800000000 double
ss 10000x10000 800000000 double
ss2 10000x10000 800000000 double
sx 10000x10000 160004 double
x 10000x10000 40000 double <---SMALLER THAN s!
If it knows x
is special, maybe it's already taking advantage of speedups in the multiplication.