Registered Member
|
Hello,
I want to compute and decompose a Schur complement J.M^{-1}.J^T where J and M are large sparse matrices, and M is symmetric positive definite. I have not found an efficient way to compute this matrix product. The inverse of M being not available, I thougt I could use a SparseLDLT decomposition and apply in to J^T:
Unfortunately, solveInPlace works only for dense matrices... Converting J to a dense matrix is very inefficient. Computing M^{-1} by solving a series of (dense) unit vectors is also very inefficient. Does anyone know a good solution ? Thanks, |
Moderator
|
well, first of all it seems you are using pretty old, deprecated stuff. I suggest you the 3.1.0-alpha2. It provides a simplified assembly mechanism based on a list of triplet:
http://eigen.tuxfamily.org/dox-devel/Tu ... rseFilling and many new and more reliable solvers. In your case this becomes: CholmodDecomposition<SparseMatrix<double>, Lower> solver(M); A = solver.solve(J.transpose()); A = J * A; this solution makes use of 'cholmod_spsolve' though, as far as I remember, this function simply uses intermediate dense vectors. The reason is that, in general, it is very unlikely that inv(M) * J is sparse even if M and J are sparse. |
Registered Member
|
Hi,
thanks for the quick answer. I installed the 3.1.0-alpha2. Unfortunately, I have not been able to successfully implement your suggestion. For the following code,
, I get the following error message:
How can I convert the return type to a sparse matrix ? config: g++-4.4 (Ubuntu/Linaro 4.4.6-11ubuntu2) 4.4.6 |
Moderator
|
hm... works for me:
#include <Eigen/Sparse> #include <Eigen/CholmodSupport> int main() { int n = 100; typedef Eigen::SparseMatrix<double> Matrix; Matrix M(n,n),J(n,n),A(n,n); Eigen::CholmodDecomposition<Matrix> solver(M); A = solver.solve(J); } compiled with 3.0.1-alpha2 and gcc 4.4.6: g++-mp-4.4 cholmod.cpp -I /opt/local/include/ufsparse/ /opt/local/lib/libcholmod.a /opt/local/lib/libcamd.a /opt/local/lib/libamd.a /opt/local/lib/libcolamd.a /opt/local/lib/libmetis.a /opt/local/lib/libccolamd.a ../build-44/blas/libeigen_blas.dylib ../build-44/lapack/libeigen_lapack.dylib -I ../../eigen3.1/ |
Registered Member
|
Thanks, I will have another look.
Allow me to raise another point:
Actually, in a very large class of practical problems including Finite Elements, matrix M is (block-)diagonal and inv(M) * J is sparse. And matrix J^T.inv(M).J is less sparse than J, but it is still very sparse. Typically, each row of J represent a value associated with a cell, M is associated with the nodes, and each row of J^T.inv(M).J has non-null entries only for the nodes of the associated cell or their one-ring neighbors. So a 100% sparse method would probably be worthwile. Is such a sparse method used with SparseLDLT ? |
Moderator
|
yes I'm aware that in some cases the result is expected to be sparse, and the Schur complement is one typical use case for that. None of the sparse solver libraries we support offers a true solve method with a sparse right hand side, and we also don't offer that yet in Eigen, though this is something we plane to have.
|
Registered Member
|
Hi,
I'm also getting the same error. If I try to compile this simple code...
... I get: WARNING!
main.cpp:7: error: conversion from ‘const Eigen::internal::sparse_solve_retval<Eigen::SimplicialCholeskyBase<Eigen::SimplicialLLT<Eigen::SparseMatrix<double, 0, int>, 1> >, Eigen::SparseMatrix<double, 0, int> >’ to non-scalar type ‘Eigen::SparseMatrix<double, 0, int>’ requested Am I doing something wrong? I'm on Eigen 3.1.1 and I tried both with gcc 4.2 and gcc 4.7. Thanks! |
Registered Member
|
I would like to add some findings which I can't undertand:
1- The following compiles
2- The following also compiles
3- This instead fails
4- ... but this is compiles ok
So, if B is sparse, what am I supposed to define C as? Thanks. |
Moderator
|
The following should do the job:
|
Moderator
|
The problem should be fixed now in 3.1 and devel branches (missing ctor overload)
|
Registered users: Baidu [Spider], Bing [Bot], Google [Bot]