Automatic sparsification algorithm and zero-threshold

조회 수: 9 (최근 30일)
Petros Bogiatzis
Petros Bogiatzis 2014년 6월 20일
편집: Matt J 2014년 6월 24일
Matlab uses an automatic sparsification algorithm to convert an array from double to sparse and also to propagate sparsity during arithmetic operations. There is a sparsity threshold value to decide if an element should be regarded as 0. Unfortunately this threshold seems that can't be changed from the user. Also it is really small: ~1e-324 (even smaller than realmin=~1e-308).
e.g,
A=bucky; % non-zeros are 1
subplot(131), spy(A), title('A')
subplot(132), spy(A*1e-323),title('A*1e-323')
subplot(133), spy(A*1e-324),title('A*1e-324')
This has an effect on the propagation of sparsity after arithmetic operations on the initial sparse array. Although some resulted arrays are practically sparse with many values smaller that EPS, these values are stored as non-zeros and the memory requirements explode.
So I guess my question is the following: Is there any way to change that tinny threshold?
Thank you for your time, Petros
  댓글 수: 9
James Tursa
James Tursa 2014년 6월 20일
@Petros: realmin = 2.2251e-308 is the smallest full precision double number in IEEE, but it is not the smallest number in IEEE double. Below realmin there is a range of denormalized numbers available with less precision (all the way down to only 1 bit of precision). The smallest denormalized number is 4.9407e-324. All of the normalized and denormalized numbers are non-zero, so they propagate in the sparse matrix calculations. I don't know how to change the behavior from strict non-zero to a tolerance. There is an FEX submission that can clean sparse matrices of small values here:
Petros Bogiatzis
Petros Bogiatzis 2014년 6월 24일
@James: Thank you for your comments and your suggestion. Unfortunately any cleaning after creating he matrix is not applicable in my case. I'm working with large matrices, so once they become full (or pseudo-full) the memory explodes and can't be stored.

댓글을 달려면 로그인하십시오.

답변 (1개)

Matt J
Matt J 2014년 6월 24일
편집: Matt J 2014년 6월 24일
About the only generic thing I can think of is to do the mldivide operation A\B column-by-column and apply the tolerance to each result. Then, at the very end, recompose the matrix:
[ma,na]=size(A);
[mb,nb]=size(B);
I=cell(1,nb); J=I, S=I;
for j=1:nb
tmp=A\B(:,j);
idx=find(abs(tmp)>tol).';
I{i}=idx;
J{i}(1:length(idx))=j;
S{i}=tmp(idx);
end
result=sparse([I{:}], [J{:}], [S{:}], na,nb);
There are potentially more efficient ways to do the intermediate mldivides A\B(:,j) by pre-decomposing A. Depending on A's structure, for example, an LU decomposition is used, as described here, and that can be done once prior to the loop.
Again, though, if you have enough foreknowledge about the solution to make such truncation both useful and safe, you should probably describe to us what it is about the problem structure that makes that foreknowledge possible. It's the kind of foreknowledge that often leads to good customized solutions.

카테고리

Help CenterFile Exchange에서 Sparse Matrices에 대해 자세히 알아보기

제품

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by