Reputation: 23
I struggle to create a sparse matrix efficiently in matlab.
The problem looks like this:
Let's take a square matrix
a = 4; b = 2;
t = rand(a,a);
What I want is equivalent to P = sparse(kron(eye(a),ones(1,b)).*repmat(t,1,b))
Only that will be a = 12*2^10 and b = 2^10 (i.e. first creating the element wise multiplication between the kroneker product and the repmat of t is too memory intensive).
I've been browsing around and couldn't find a related question. My idea is to implement this matrix directly using the sparse(B,d,m,n) or spidag() syntax.
Would be amazing if someone had an idea.
Cheers
I expect a matrix like this:
P = sparse(kron(eye(a),ones(1,b)).*repmat(t,1,b))
Upvotes: 2
Views: 34
Reputation: 30175
Tested with your example and b=3
.
r = repelem(1:a,1,b)
c = mod( repmat(0:(b-1),1,a) + (r-1)*b, a ) + 1;
P = sparse( r, 1:a*b, t(sub2ind([a,a],r,c)) );
Logic:
r
is the row index, which is the same for the sparse output and row input from t
; each row repeated b
times.c
is the column index within t
to take the value from. This appears to start as 1:b
, and then take the next b
elements starting from the following column, wrapping round to column 1.Then you can directly form the sparse matrix extracting elements from t
using a linear index from r
and c
.
Output:
>> P = sparse(kron(eye(a),ones(1,b)).*repmat(t,1,b))
P =
(1,1) 0.8147
(1,2) 0.6324
(2,3) 0.9649
(2,4) 0.4854
(3,5) 0.1270
(3,6) 0.2785
(4,7) 0.9706
(4,8) 0.1419
>> s = sparse( r, 1:a*b, t(sub2ind([a,a],r,c)) )
s =
(1,1) 0.8147
(1,2) 0.6324
(2,3) 0.9649
(2,4) 0.4854
(3,5) 0.1270
(3,6) 0.2785
(4,7) 0.9706
(4,8) 0.1419
Upvotes: 1