0

I need to create spare matrices with variable elements. Unfortunately, sparse matrix index operations are very slow.

Is there any way to speed up the process? Maybe there are some tricks that I don't know of?

Here is a minimal working example:

N = 400; A = eye(7)+ [ zeros(3,3) eye(3) zeros(3,1) ; zeros(3,3) zeros(3,3) zeros(3,1) ; zeros(1,3) zeros(1,3) zeros(1,1) ] ; B = [ zeros(3,3) zeros(3,1) ; eye(3) zeros(3,1) ; zeros(1,3) -2 ] ; Su = sparse(7*N, 4*N); for i=1:N for j=0:i-1 Su(((i)*7 + 1) : ((i+1) * 7), (j*4 + 1) : ... ((j+1) * 4)) = A^(i-j-1) * B; end end Sx = sparse(N*7, N*7); for i=0:N Sx((1 + i*7 : (i+1)*7), (1 + i*7 : (i+1)*7)) = A^i; end 

Su and Sx are matrices that are partitioned by (products of) A and B.

1 Answer 1

1

MATLABs code analyzer already mentions that this method of assigning sparse matrices is very slow as the nonzero pattern is changed which incurs significant overhead. Forgoing the sparse matrices and just using Su = zeros(.. instead makes the function execute in a reasonable time, even if you convert the matrices to sparse matrices afterwards.

If the memory used is of any concern, you could consider defining the zeros matrix as a different type, e.g. int16, as all values appear to be signed integers smaller than 400.

Otherwise, if you can predict the nonzero pattern in you're sparse matrix you can define it correctly upfront and won't suffer performance problems. You don't need to know the exact values, just whether a value is nonzero or not. Taking the following from MATLAB's Code Analyzer:

Explanation

Code Analyzer detects an indexing pattern for a sparse array that is likely to be slow. An assignment that changes the nonzero pattern of a sparse array can cause this error because such assignments result in considerable overhead.

Suggested Action

If possible, build sparse arrays using sparse as follows, and do not use indexed assignments (such as C(4) = B) to build them:

  1. Create separate index and value arrays.
  2. Call sparse to assemble the index and value arrays.

If you must use indexed assignments to build sparse arrays, you can optimize performance by first preallocating the sparse array with spalloc.

If the code changes only array elements that are already nonzero, then the overhead is reasonable. Suppress this message as described in Adjust Code Analyzer Message Indicators and Messages. For more information, see “Constructing Sparse Matrices”.

So, if you can create an array of indices that will contain nonzero values, you can call sparse(i,j,s[,m,n,nzmax]) to predefine the nonzero pattern. If you only know the number of nonzero values, but not their pattern, using spalloc should also improve your performance.

Sign up to request clarification or add additional context in comments.

4 Comments

Memory is indeed the issue here. If I take N >> 400 on a 32 bit system and I do zeros() I'll have tough luck. Using a different type might be a good idea, though, I'll try single.
Otherwise, if you can predict the nonzero pattern in you're sparse matrix you can define it correctly upfront and won't suffer performance problems. You don't need to know the exact values, just whether a value is nonzero or not.
Can you expand on that? I do know the structure of the matrix, so this might be something that could work.
I've modified my answer to expand on it ;-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.