I have this problem which requires solving for X
in AX=B
. A
is of the order 15000 x 15000 and is sparse and symmetric. B
is 15000 X 7500 and is NOT sparse. What is the fastest way to solve for X?
I can think of 2 ways.
X = A\B
Using for loop,
invA = A\speye(size(A))
for i = 1:size(B,2)
X(:,i) = invA*B(:,i);
end
Is there a better way than the above two? If not, which one is best between the two I mentioned?
(a) For every b, the equation Ax = b has a solution.
First things first - never, ever compute inverse of A. That is never sparse except when A is a diagonal matrix. Try it for a simple tridiagonal matrix. That line on its own kills your code - memory-wise and performance-wise. And computing the inverse is numerically less accurate than other methods.
Generally, \
should work for you fine. MATLAB does recognize that your matrix is sparse and executes sparse factorization. If you give a matrix B
as the right-hand side, the performance is much better than if you only solve one system of equations with a b
vector. So you do that correctly. The only other technical thing you could try here is to explicitly call lu
, chol
, or ldl
, depending on the matrix you have, and perform backward/forward substitution yourself. Maybe you save some time there.
The fact is that the methods to solve linear systems of equations, especially sparse systems, strongly depend on the problem. But in almost any (sparse) case I imagine, factorization of a 15k system should only take a fraction of a second. That is not a large system nowadays. If your code is slow, this probably means that your factor is not that sparse sparse anymore. You need to make sure that your matrix is properly reordered to minimize the fill (added non-zero entries) during sparse factorization. That is the crucial step. Have a look at this page for some tests and explanations on how to reorder your system. And have a brief look at example reorderings at this SO thread.
Since you can answer yourself which of the two is faster, I'll try yo suggest the next options. Solve it using a GPU. Plenty of details can be found online, including this SO post, a matlab benchmarking of A/b, etc. Additionally, there's the MATLAB add-on of LAMG (Lean Algebraic Multigrid). LAMG is a fast graph Laplacian solver. It can solve Ax=b in O(m) time and storage.
If your matrix A
is symmetric positive definite, then here's what you can do to solve the system efficiently and stably:
A=L*L'
. Since you have a sparse matrix, and you want to exploit it to accelerate the inversion, you should not apply chol
directly, which would destroy the sparsity pattern. Instead, use one of the reordering method described here. X = L'\(L\B)
Finally, if are not dealing with potential complex values, then you can replace all the L'
by L.'
, which gives a bit further acceleration because it's just trying to transpose instead of computing the complex conjugate.
Another alternative would be the preconditioned conjugate gradient method, pcg
in Matlab. This one is very popular in practice, because you can trade off speed for accuracy, i.e. give it less number of iterations, and it will give you a (usually pretty good) approximate solution. You also never need to store the matrix A
explicitly, but just be able to compute matrix-vector product with A
, if your matrix doesn't fit into memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With