What is a fast simple solver for a large Laplacian

2019-06-27 14:16发布

问题:

I need to solve some large (N~1e6) Laplacian matrices that arise in the study of resistor networks. The rest of the network analysis is being handled with boost graph and I would like to stay in C++ if possible. I know there are lots and lots of C++ matrix libraries but no one seems to be a clear leader in speed or usability. Also, the many questions on the subject, here and elsewhere seem to rapidly devolve into laundry lists which are of limited utility. In an attempt to help myself and others, I will try to keep the question concise and answerable:

What is the best library that can effectively handle the following requirements?

  • Matrix type: Symmetric Diagonal Dominant/Laplacian
  • Size: Very large (N~1e6), no dynamic resizing needed
  • Sparsity: Extreme (maximum 5 nonzero terms per row/column)
  • Operations needed: Solve for x in A*x=b and mat/vec multiply
  • Language: C++ (C ok)
  • Priority: Speed and simplicity to code. I would really rather avoid having to learn a whole new framework for this one problem or have to manually write too much helper code.

Extra love to answers with a minimal working example...

回答1:

If you want to write your own solver, in terms of simplicity, it's hard to beat Gauss-Seidel iteration. The update step is one line, and it can be parallelized easily. Successive over-relaxation (SOR) is only slightly more complicated and converges much faster.

Conjugate gradient is also straightforward to code, and should converge much faster than the other iterative methods. The important thing to note is that you don't need to form the full matrix A, just compute matrix-vector products A*b. Once that's working, you can improve the convergance rate again by adding a preconditioner like SSOR (Symmetric SOR).

Probably the fastest solution method that's reasonable to write yourself is a Fourier-based solver. It essentially involves taking an FFT of the right-hand side, multiplying each value by a function of its coordinate, and taking the inverse FFT. You can use an FFT library like FFTW, or roll your own.

A good reference for all of these is A First Course in the Numerical Analysis of Differential Equations by Arieh Iserles.



回答2:

Eigen is quite nice to use and one of the fastest libraries I know:

http://eigen.tuxfamily.org/dox/group__TutorialSparse.html



回答3:

There is a lot of related post, you could have look. I would recommend C++ and Boost::ublas as used in UMFPACK and BOOST's uBLAS Sparse Matrix