Most efficient way to add multiple sparse matrices in a loop in MATLAB
Afficher commentaires plus anciens
I have a code that repeatedly calculates a sparse matrix in a loop (it performs this calculation 13472 times to be precise). Each of these sparse matrices is unique.
After each execution, it adds the newly calculated sparse matrix to what was originally a sparse zero matrix.
When all 13742 matrices have been added, the code exits the loop and the program terminates.
The code bottleneck occurs in adding the sparse matrices. I have made a dummy version of the code that exhibits the same behavior as my real code. It consists of a MATLAB function and a script given below.
(1) Function that generates the sparse matrix:
function out = test_evaluate_stiffness(n)
ind = randi([1 n*n],300,1);
val = rand(300,1);
[I,J] = ind2sub([n,n],ind);
out = sparse(I,J,val,n,n);
end
(2) Main script (program)
% Calculate the stiffness matrix
n=1000;
K=sparse([],[],[],n,n,n^2);
tic
for i=1:13472
temp=rand(1)*test_evaluate_stiffness(n);
K=K+temp;
end
fprintf('Stiffness Calculation Complete\nTime taken = %f s\n',toc)
I'm not very familiar with sparse matrix operations so I may be missing a critical point here that may allow my code to be sped up considerably.
Am I handling the updating of my stiffness matrix in a reasonable way in my code? Is there another way that I should be using sparse that will result in a faster assembly?
Note that I have coupling in my system so the the values by which I augment my global stiffness matrix in each loop execution aren't necessarily on the diagonal.
A profiler report is also provided below:

%
Réponse acceptée
Plus de réponses (1)
James Tursa
le 15 Avr 2015
Modifié(e) : James Tursa
le 15 Avr 2015
1 vote
Unless you know in advance the pattern of the non-zero spots and can exploit that, then I think you are stuck. At every iteration of K = K + temp, the entire data area of K in general will need to be copied to a new memory location and the temp data will need to be added/merged in as well.
If you do know the pattern in advance, then possibly something could be done to minimize the data copying.
How big is n in your real problem? Can you do some calculations in full and then convert to sparse later for your downstream needs?
4 commentaires
James Tursa
le 15 Avr 2015
Modifié(e) : James Tursa
le 15 Avr 2015
Two strategies to consider:
(1) Have K full and keep temp sparse. If MATLAB is smart enough, should be able to add temp to K without turning temp full first. If MATLAB is not smart enough a mex routine could be written to do this in-place. Drawback is that K memory is still accessed in fragmented fashion when adding temp, and K is very large, so there may not be any benefit to this approach.
(2) Create K as a banded sparse matrix in the pattern that you know the result to be, putting realmin values in the banded spots. The spdiags function can help with this. Then, if MATLAB is smart enough (no guarantee of this), the K = K + temp will not require any data copying. If MATLAB is not smart enough for this, a mex routine could easily be written to do the K = K + temp calculation in-place to avoid the data copy. Any leftover realmin values could be cleaned out at the end.
UPDATE: I just did a test and MATLAB is not smart enough to avoid the data copy in (2) above. So your only option for this method would be a mex routine.
Kobye
le 15 Avr 2015
John D'Errico
le 15 Avr 2015
See my answer. There are good ways to do this without resorting to mex.
Catégories
En savoir plus sur Matrix Indexing dans Centre d'aide et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
