Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SymGEigsSolver settings for large sparse problem #36

Closed
armingeiser opened this issue Dec 13, 2017 · 14 comments
Closed

SymGEigsSolver settings for large sparse problem #36

armingeiser opened this issue Dec 13, 2017 · 14 comments

Comments

@armingeiser
Copy link

armingeiser commented Dec 13, 2017

Hello,

I am trying to use the library to solve for a structural eigenfrequency probem. This gives me a sparse (60kx60k) generalized eigenvalue problem.

I am using the Spectra::SparseCholesky and Spectra::SparseSymMatProd
I am looking for the 5 lowest eigenvalues, however the solution with the Spectra lib fails.

I transfered the matrices A and B to python and solved the eigenvalue problem using the scipy "eigs" function, that, as far as i know uses the ARPACK library.

from scipy.sparse.linalg import eigs
evals_small, evecs_small = eigs(A, 5, B, sigma=0, which='LM')

There i was able to obtain the correct eigenvalues.

Is there a way to use the SymGEigsSolver with shift mode?

Thanks!

@yixuan
Copy link
Owner

yixuan commented Dec 14, 2017

I haven't verified it yet, but here is what you can try: SymGEigsSolver has two operators to define, one for A and one for B.
The built-in class SparseCholesky takes care of the B operator, so what's left is a class that computes inv(A) * x. You can borrow some code from the SparseSymShiftSolve class, but in your case the sigma parameter is fixed to zero.

@armingeiser
Copy link
Author

Thank you for the hint, I will try it!

@dilevin
Copy link

dilevin commented Mar 3, 2018

Hi,

I'm also interested in finding the smallest Eigenvalues of a large sparse matrix. If this worked for the previous poster, would you mind posting the code ?

Thanks!

@yixuan
Copy link
Owner

yixuan commented Mar 4, 2018

@dilevin Are you talking about the eigenvalue of a single matrix, or the generalized eigenvalue involving two matrices?

@dilevin
Copy link

dilevin commented Mar 4, 2018

Thanks for the quick response! I’d like to solve the generalized eigenvalue problem, but find the smallest eigenvalue efficiently.

@WindingWinter
Copy link

@yixuan , I second @dilevin . It would be supremely useful if you can do a class for generalized eigenvalue problem with shift inverted mode.

@armingeiser
Copy link
Author

I did not find the time yet to try the suggestions by @yixuan, sorry for the late response.

@WindingWinter
Copy link

@armingeiser , how do you solve this problem of finding eigenvalues/modes to generalized eigenvalue problem with shift inverted mode?

@armingeiser
Copy link
Author

@nsoonhui as i wrote above, unfortunately i did not solve/try it yet.

@dilevin
Copy link

dilevin commented Mar 12, 2018

@armingeiser @nsoonhui

For my particular problem, modal analysis for finite element systems, I found a pretty good solution which is to solve a mass shifted generalized eigenvalue problem:

   Eigen::SparseMatrix<DataType> K = -A + shift*B;
    Eigen::SparseMatrix<DataType> M = B;
   
    Spectra::SparseSymMatProd<DataType> Aop(M);
    Spectra::SparseCholesky<DataType> Bop(K);
    
    // Construct eigen solver object, requesting the smallest three eigenvalues
    Spectra::SymGEigsSolver<DataType, Spectra::LARGEST_MAGN,      Spectra::SparseSymMatProd<DataType>, Spectra::SparseCholesky<DataType>, Spectra::GEIGS_CHOLESKY > eigs(&Aop, &Bop, numVecs, 5*numVecs);

Then correct the eigenvalues using:
-1.0/(eigs.eigenvalues()[ii]) + shift);

Here A is my input stiffness matrix (symmetric -ve semidefinite), B is my mass matrix and shift is a small number used to stabilize the stiffness matrix.

You have to renormalize your eigenvectors (wrt to the mass matrix) after retrieving them from spectra, but this seems to work and is much faster than using SMALLEST_MAGN.

@yixuan
Copy link
Owner

yixuan commented Jun 20, 2020

For people who are still looking for the shift-and-invert mode of SymGEigsSolver, I have just implemented a new SymGEigsShiftSolver class in the 1.y.z branch. Example code is available in the testing program.

Note that this new branch contains several API-breaking changes that will be included in the next major release, so some (minor) code migration is needed.

@giacomo-b
Copy link

giacomo-b commented Feb 25, 2021

For anyone having similar problems: I followed the approach suggested by @dilevin, unfortunately without success.

I am also dealing with modal analysis, my matrices are about 20,000 x 20,000.

The following worked for me:

int n_eigs = 3, convergence_ratio = 5;

double shift = 0;

// K is the stiffness matrix, M the mass matrix
Eigen::SparseMatrix<double> K_new = K + shift * M;
Eigen::SparseMatrix<double> M_new = M;

Spectra::SparseSymMatProd<double> Aop(M_new);
Spectra::SparseCholesky<double> Bop(K_new);

Spectra::SymGEigsSolver<double, Spectra::LARGEST_MAGN, Spectra::SparseSymMatProd<double>, Spectra::SparseCholesky<double>, Spectra::GEIGS_CHOLESKY> eigs(&Aop, &Bop, n_eigs, convergence_ratio * n_eigs);

eigs.init();
int n_conv = eigs.compute();

Eigen::VectorXd evalues;
if (eigs.info() == SUCCESSFUL)
    evalues = 1.0 / eigs.eigenvalues().array() + shift;

std::cout << "Generalized eigenvalues found:\n" << evalues << std::endl;

Note that I left shift = 0 in case someone needed to shift the eigenvalues, but I could just write:

Spectra::SparseSymMatProd<double> Aop(M);
Spectra::SparseCholesky<double> Bop(K);

@armingeiser
Copy link
Author

armingeiser commented Mar 6, 2021

Thanks @yixuan!

I have been successful using the SymGEigsShiftSolver exactly following the mentioned test program.
FFR: i used it to solve a modal analysis of a solid structure with ~100k dofs.

From my point of view this issue can be closed.

@yixuan
Copy link
Owner

yixuan commented Jul 2, 2021

Spectra v1.0.0 has been released, and SymGEigsShiftSolver is fully supported now. Let me close this issue.

@yixuan yixuan closed this as completed Jul 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants