Closed dariomangoni closed 6 years ago
Hi @dariomangoni , thanks for the comments!
This is indeed a good point. Map<SparseMatrix<double>>
and Ref<SparseMatrix<double>>
are new features introduced in the recent Eigen 3.3, and they didn't exist before. I need to think of a way to make it compatible with older versions of Eigen, but at least for your own use, it's perfectly a good idea to make that change.
This has been solved in https://github.com/yixuan/spectra/commit/dec0d1fc1ad40f860c3d38e4835fa94135e7f65a. Thank you for the suggestion!
I'm a first-time user of Eigen and Spectra, so what I'm experiencing may not be critical, even not correct, anyway...
I need to solve a Generalized Eigenvalue Problem on CSR-format matrices. I already have CSR arrays so I would like to wrap them in a
Eigen::SparseMatrix
in order to feed theSpectra::SymGEigsSolver
by mean ofSpectra::SparseSymMatProd
andSpectra::SparseCholesky
.To wrap CSR C-style arrays I would use
Map<SparseMatrix<double>>(...CSRmatrixdata...)
, but then I came to an empasse. How can I call theSparseSymMatProd
constructor? There are few ways...Map<>
itselfRef<>
to theMap<>
Eigen::SparseMatrix&
referring toMap<>
Eigen::SparseMatrix&
referring toRef<>
that refers to theMap<>
What happens? Fact 1) inside the
SparseSymMatProd
constructor, aconst Eigen::SparseMatrix&
is initialized with the argument of the constructor. i.e.const Eigen::SparseMatrix& m_mat = _argument_
Fact 2a) these passages do not call copy*
Map<>(CSRarrays)
Ref<> = Map<>
and obviouslyEigen::SparseMatrix& = Eigen::SparseMatrix&
Fact 2b) these passages do call copy*
Eigen::SparseMatrix& = Ref<>
Eigen::SparseMatrix& = Map<>
*in order to prove that, I compared the
valuePtr()
address with the original CSR value addressNow: in [1] and [2]: the reference-initialization inside the constructor forces a copy, but suddenly the destructors of
SparseMatrix
first andCompressedStorage
after are called and they destroy the arrays ofm_mat
that have just been created! The matrix is invalidated an no product can be actually performed.in [3] and [4]: everything works fine, the reference-initialization called inside the constructor is of the last case of Fact 2a, so there is no copy and avoid this strange behaviour above, but there do is a copy in the reference initialization that is made before calling the constructor.
So: I would recommend to change the first lines of
Spectra::SparseSymMatProd
fromto
This is retro-compatible: it works with
Eigen::SparseMatrix
and it should works also withRef
s and it doesn't force a copy.I'm not aware of all the implications and if this is actually correct. If you, instead, have a better way to pass some arrays to the eigen solver without this mess and that doesn't force copies, please tell me!