#include <iostream>
#include <Eigen/IterativeLinearSolvers>
class MatrixReplacement;
namespace Eigen {
namespace internal {
template <>
struct traits<MatrixReplacement> : public Eigen::internal::traits<Eigen::SparseMatrix<double> > {};
}
}
public:
using Scalar = double;
using RealScalar = double;
using StorageIndex = int;
static constexpr int ColsAtCompileTime = Eigen::Dynamic;
static constexpr int MaxColsAtCompileTime = Eigen::Dynamic;
static constexpr bool IsRowMajor = false;
Index
rows()
const {
return mp_mat->rows(); }
Index
cols()
const {
return mp_mat->cols(); }
template <typename Rhs>
Eigen::Product<MatrixReplacement, Rhs, Eigen::AliasFreeProduct> operator*(const Eigen::MatrixBase<Rhs>& x) const {
return Eigen::Product<MatrixReplacement, Rhs, Eigen::AliasFreeProduct>(*this, x.derived());
}
MatrixReplacement() = default;
void attachMyMatrix(const SparseMatrix<double>& mat) { mp_mat = &mat; }
const SparseMatrix<double>& my_matrix() const { return *mp_mat; }
private:
const SparseMatrix<double>* mp_mat = nullptr;
};
namespace Eigen {
namespace internal {
template <typename Rhs>
struct generic_product_impl<MatrixReplacement, Rhs, SparseShape, DenseShape,
GemvProduct>
: generic_product_impl_base<MatrixReplacement, Rhs, generic_product_impl<MatrixReplacement, Rhs> > {
using Scalar = typename Product<MatrixReplacement, Rhs>::Scalar;
template <typename Dest>
static void scaleAndAddTo(Dest& dst, const MatrixReplacement& lhs, const Rhs& rhs, const Scalar& alpha) {
eigen_assert(alpha == Scalar(1) && "scaling is not implemented");
EIGEN_ONLY_USED_FOR_DEBUG(alpha);
for (Index i = 0; i < lhs.cols(); ++i) dst += rhs(i) * lhs.my_matrix().col(i);
}
};
}
}
template <typename Solver>
void solve(
const char* name, Solver& solver,
const MatrixReplacement& A,
const Eigen::VectorXd& b) {
solver.setTolerance(1e-10);
solver.compute(A);
std::cout << name << (solver.info() ==
Eigen::Success ?
" converged" :
" did not converge") <<
" after "
<< solver.iterations() << " iterations, estimated error: " << solver.error() << std::endl;
}
int main() {
Eigen::Index n = 10;
S = S.transpose() * S;
MatrixReplacement A;
A.attachMyMatrix(S);
solve("CG: ", cg, A, b);
solve("BiCGSTAB:", bicgstab, A, b);
solve("GMRES: ", gmres, A, b);
solve("DGMRES: ", dgmres, A, b);
solve("MINRES: ", minres, A, b);
}
A bi conjugate gradient stabilized solver for sparse square problems.
Definition BiCGSTAB.h:170
A conjugate gradient solver for sparse (or dense) self-adjoint problems.
Definition ConjugateGradient.h:161
A Restarted GMRES with deflation. This class implements a modification of the GMRES solver for sparse...
Definition DGMRES.h:98
A GMRES solver for sparse square problems.
Definition GMRES.h:264
A minimal residual solver for sparse symmetric problems.
Definition MINRES.h:197
Derived & setRandom(Index size)
Definition Random.h:148
A versatile sparse matrix representation.
Definition SparseMatrix.h:122
@ Success
Definition Constants.h:457
Matrix< double, Dynamic, 1 > VectorXd
DynamicĂ—1 vector of type double.
Definition Matrix.h:489
Definition EigenBase.h:34
constexpr Index cols() const noexcept
Definition EigenBase.h:62
constexpr Index rows() const noexcept
Definition EigenBase.h:60