Registered Member
|
Hello, i am not a very experienced user but i have to solve larger
Systems of linear equations with sparse, symmetric semi-positive definite matrices. For this i wanted to use CHOLMOD. But i cant find a good tutorial on how to use the Cholmod-Support from within Eigen. Even when i only include <unsupported/Eigen/SparseExtra/CholmodSupport.h> i get tons of errors like
I cant figure out what exactly i have to include and to write. If someone could give me a minimum example how to solve Ax = b using Cholmod via Eigen, id be really thankful. Going back to sleep, eversleeping |
Moderator
|
First of all I recommend you to use Eigen 3.1.0-alpha2 which is much more mature regarding sparse stuff. Then have a look at the updated tutorial:
http://eigen.tuxfamily.org/dox-devel/Tu ... parse.html For your first tries, you should simply use the built-in SimplicialLDLT solver which is quite fast for very sparse matrices. Then you can move to CholmodDecomposition. |
Registered Member
|
I have to publish the resulting program. I am currently using cmake and some
FindEigen.cmake i have found in the web. If my programm will use the new version, how can i check for it in cmake? EDIT: i have found a FindEIgen in the downloads. I think this will be best option and it has a VERSION too. Unfortunately this file is not installed when you install eigen via packagemanager. So i have to copy this FindEigen3.cmake and add it to my cmake-folder ? |
Moderator
|
|
Registered Member
|
I am havin a little problem right now.
I am operating on matrices whcih should be (if calculated correctly) positive-semi-definite. The step i want to caluculate is
H stands for Hessian Matrices and Grads are gradients. I am trying to solve the problem like this:
But i get :
Do i use Eigen-Commands in some wrong way? Or do i have to consider i calculate the matrices wrong or even the whole algorithm fails? Thx |
Moderator
|
I see that you are using dense matrices. How large is 'matrix' ? Perhaps it would be better to simply use a dense solver:
LLDT<MatrixXd> ldlt(matrix); X = ldlt.solve(-b); Now, to check if 'matrix' is really positive definite, you could check its eigenvalues: SelfAdjointEigenSolver<MatrixXd> eig(matrix,EigenvaluesOnly); std::cout << eig.eigenvalue().minCoeff() << " " << eig.eigenvalue().maxCoeff() << std::endl; |
Registered Member
|
I am getting confused more and more:
According to the paper I am reading, the usage of the sparse equation solver CHOLMOD is recommended. Now i am calculating a simple matrix A (12*12):
The real problem has matrices about 1000*1000. But nevertheless: Vector b:
The Cholmodsupport-Module never gave any good solution. Now i have like adviced calculated the eigenvalues.
Now i have tried some of the offered solvers:
I wonder what the best solution may be. Given the matrix to maple i get the solution:
yet another solution. But it may be that some digits behind the comma are not print so that Maple has less precision and therefor another solution. So how should i continue from here on? |
Moderator
|
Your problem is underdetermined, or in other words not full rank, so there no a single solution but there exist a space of solutions.You need to add some additional constraints. For instance you can use a SVD to get the minimal norm solution. For a 1000x1000 matrix, it is still ok to use dense algorithms:
x = JacobiSVD<MatrixXd>(matrix, ComputeThinU|ComputeThinV).solve(b); Moreover, it seems your matrix has a band structure. If that's really the case, the best for you would be use an Eigen::BandMatrix to assemble the matrix, and then call the lapack DSBEV routine. (we currently don't have optimized algorithm for band matrices). |
Registered Member
|
The Matrix A
Has as far as i can see full rank. Even if some eigenvalues are suspiciously small. But nevertheless the system of equations should have an unique solution. If i am wrong (it is my first time that i do such stuff), plz tell me where i err. Thx The banded structure like in this example is always occuring in some form but not a single band but more, something like:
|
Moderator
|
well, with double 1e-15 compared to 35 means 0. I tested with the printed values and I got:
singular vals: 35.565 32.9951 22.1422 7.81155 7.023 1.60069 1.286 0.450117 0.225467 3.57001e-05 4.49997e-06 7.00281e-07 eigen vals: -1.60069 -1.286 -0.450117 -4.49997e-06 -7.00281e-07 3.57001e-05 0.225467 7.023 7.81155 22.1422 32.9951 35.565 FullPivLU -0.537247 -0.0110334 0.495247 0.407148 0.248263 -0.460445 -0.407148 -0.248263 -0.460445 0.537247 0.0110334 0.495247 PartialPivLU -0.537247 -0.0110334 0.495247 0.407148 0.248263 -0.460445 -0.407148 -0.248263 -0.460445 0.537247 0.0110334 0.495247 JacobiSVD -0.537247 -0.0110334 0.495247 0.407148 0.248263 -0.460445 -0.407148 -0.248263 -0.460445 0.537247 0.0110334 0.495247 LDLT -0.537247 -0.0110334 0.495247 0.407148 0.248263 -0.460445 -0.407148 -0.248263 -0.460445 0.537247 0.0110334 0.495247 resp errs: 1.96104e-15 4.14665e-15 1.31497e-09 2.25897e-15 The clamped version is indeed positive definite and easy to solve with any solver. Perhaps you could try to regularize your problem by adding epsilon to the diagonal.... Our built-in sparse LDLT solver can do that for you: SimplicialLDLT<SparseMatrix<double> > ldlt; ldlt.setShift(epsilon); ldlt.compute(A); if(ldlt.info()!=Success) increase epsilon and try again ! x = ldtd.solve(b); |
Registered users: Bing [Bot], claydoh, Google [Bot], rblackwell, Yahoo [Bot]