40class DiagonalPreconditioner {
41 using Scalar = Scalar_;
45 using StorageIndex =
typename Vector::StorageIndex;
46 enum { ColsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic };
48 DiagonalPreconditioner() =
default;
50 template <
typename MatType>
51 explicit DiagonalPreconditioner(
const MatType& mat) : m_invdiag(mat.cols()) {
55 constexpr Index rows()
const noexcept {
return m_invdiag.size(); }
56 constexpr Index cols()
const noexcept {
return m_invdiag.size(); }
58 template <
typename MatType>
59 DiagonalPreconditioner& analyzePattern(
const MatType&) {
63 template <
typename MatType>
64 DiagonalPreconditioner& factorize(
const MatType& mat) {
65 m_invdiag.resize(mat.cols());
66 for (Index j = 0; j < mat.outerSize(); ++j) {
67 typename MatType::InnerIterator it(mat, j);
68 while (it && it.index() != j) ++it;
69 if (it && it.index() == j && it.value() != Scalar(0))
70 m_invdiag(j) = Scalar(1) / it.value();
72 m_invdiag(j) = Scalar(1);
74 m_isInitialized =
true;
78 template <
typename MatType>
79 DiagonalPreconditioner& compute(
const MatType& mat) {
80 return factorize(mat);
84 template <
typename Rhs,
typename Dest>
85 void _solve_impl(
const Rhs& b, Dest& x)
const {
86 x = m_invdiag.array() * b.array();
89 template <
typename Rhs>
91 eigen_assert(m_isInitialized &&
"DiagonalPreconditioner is not initialized.");
92 eigen_assert(m_invdiag.size() == b.rows() &&
93 "DiagonalPreconditioner::solve(): invalid number of rows of the right hand side matrix b");
101 bool m_isInitialized =
false;
122class LeastSquareDiagonalPreconditioner :
public DiagonalPreconditioner<Scalar_> {
123 using Scalar = Scalar_;
124 using RealScalar =
typename NumTraits<Scalar>::Real;
125 using Base = DiagonalPreconditioner<Scalar_>;
126 using Base::m_invdiag;
129 LeastSquareDiagonalPreconditioner() =
default;
131 template <
typename MatType>
132 explicit LeastSquareDiagonalPreconditioner(
const MatType& mat) : Base() {
136 template <
typename MatType>
137 LeastSquareDiagonalPreconditioner& analyzePattern(
const MatType&) {
141 template <
typename MatType>
142 LeastSquareDiagonalPreconditioner& factorize(
const MatType& mat) {
144 m_invdiag.resize(mat.cols());
145 EIGEN_IF_CONSTEXPR (MatType::IsRowMajor) {
147 for (Index j = 0; j < mat.outerSize(); ++j) {
148 for (
typename MatType::InnerIterator it(mat, j); it; ++it) m_invdiag(it.index()) += numext::abs2(it.value());
150 for (Index j = 0; j < mat.cols(); ++j) {
151 RealScalar sum = numext::real(m_invdiag(j));
152 m_invdiag(j) = sum > RealScalar(0) ? RealScalar(1) / sum : RealScalar(1);
155 for (Index j = 0; j < mat.outerSize(); ++j) {
156 RealScalar sum = mat.col(j).squaredNorm();
157 m_invdiag(j) = sum > RealScalar(0) ? RealScalar(1) / sum : RealScalar(1);
160 Base::m_isInitialized =
true;
164 template <
typename MatType>
165 LeastSquareDiagonalPreconditioner& compute(
const MatType& mat) {
166 return factorize(mat);