JonasW
JonasW

Reputation: 23

Create blockwise shifted sparse matrix in matlab directly

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

Answers (1)

Wolfie
Wolfie

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

Related Questions