10#ifndef EIGEN_SPARSETRIANGULARSOLVER_H
11#define EIGEN_SPARSETRIANGULARSOLVER_H
14#include "./InternalHeaderCheck.h"
20template <
typename Lhs,
typename Rhs,
int Mode,
24 int StorageOrder = int(traits<Lhs>::Flags) &
RowMajorBit>
25struct sparse_solve_triangular_selector;
28template <
typename Lhs,
typename Rhs,
int Mode>
29struct sparse_solve_triangular_selector<Lhs, Rhs, Mode, Lower, RowMajor> {
30 typedef typename Rhs::Scalar Scalar;
31 typedef evaluator<Lhs> LhsEval;
32 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
33 static void run(
const Lhs& lhs, Rhs& other) {
35 for (Index col = 0; col < other.cols(); ++col) {
36 for (Index i = 0; i < lhs.rows(); ++i) {
37 Scalar tmp = other.coeff(i, col);
40 for (LhsIterator it(lhsEval, i); it; ++it) {
42 lastIndex = it.index();
43 if (lastIndex == i)
break;
44 tmp -= lastVal * other.coeff(lastIndex, col);
47 other.coeffRef(i, col) = tmp;
49 eigen_assert(lastIndex == i);
50 other.coeffRef(i, col) = tmp / lastVal;
58template <
typename Lhs,
typename Rhs,
int Mode>
59struct sparse_solve_triangular_selector<Lhs, Rhs, Mode, Upper, RowMajor> {
60 typedef typename Rhs::Scalar Scalar;
61 typedef evaluator<Lhs> LhsEval;
62 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
63 static void run(
const Lhs& lhs, Rhs& other) {
65 for (Index col = 0; col < other.cols(); ++col) {
66 for (Index i = lhs.rows() - 1; i >= 0; --i) {
67 Scalar tmp = other.coeff(i, col);
69 LhsIterator it(lhsEval, i);
70 while (it && it.index() < i) ++it;
72 eigen_assert(it && it.index() == i);
75 }
else if (it && it.index() == i)
78 tmp -= it.value() * other.coeff(it.index(), col);
82 other.coeffRef(i, col) = tmp;
84 other.coeffRef(i, col) = tmp / l_ii;
91template <
typename Lhs,
typename Rhs,
int Mode>
92struct sparse_solve_triangular_selector<Lhs, Rhs, Mode,
Lower,
ColMajor> {
93 typedef typename Rhs::Scalar Scalar;
94 typedef evaluator<Lhs> LhsEval;
95 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
96 static void run(
const Lhs& lhs, Rhs& other) {
98 for (Index col = 0; col < other.cols(); ++col) {
99 for (Index i = 0; i < lhs.cols(); ++i) {
100 Scalar& tmp = other.coeffRef(i, col);
101 if (!numext::is_exactly_zero(tmp))
103 LhsIterator it(lhsEval, i);
104 while (it && it.index() < i) ++it;
106 eigen_assert(it && it.index() == i);
109 if (it && it.index() == i) ++it;
110 for (; it; ++it) other.coeffRef(it.index(), col) -= tmp * it.value();
118template <
typename Lhs,
typename Rhs,
int Mode>
119struct sparse_solve_triangular_selector<Lhs, Rhs, Mode,
Upper,
ColMajor> {
120 typedef typename Rhs::Scalar Scalar;
121 typedef evaluator<Lhs> LhsEval;
122 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
123 static void run(
const Lhs& lhs, Rhs& other) {
124 LhsEval lhsEval(lhs);
125 for (Index col = 0; col < other.cols(); ++col) {
126 for (Index i = lhs.cols() - 1; i >= 0; --i) {
127 Scalar& tmp = other.coeffRef(i, col);
128 if (!numext::is_exactly_zero(tmp))
132 LhsIterator it(lhsEval, i);
133 while (it && it.index() != i) ++it;
134 eigen_assert(it && it.index() == i);
135 other.coeffRef(i, col) /= it.value();
137 LhsIterator it(lhsEval, i);
138 for (; it && it.index() < i; ++it) other.coeffRef(it.index(), col) -= tmp * it.value();
147#ifndef EIGEN_PARSED_BY_DOXYGEN
149template <
typename ExpressionType,
unsigned int Mode>
150template <
typename OtherDerived>
151void TriangularViewImpl<ExpressionType, Mode, Sparse>::solveInPlace(MatrixBase<OtherDerived>& other)
const {
152 eigen_assert(derived().cols() == derived().rows() && derived().cols() == other.rows());
153 eigen_assert((!(Mode & ZeroDiag)) &&
bool(Mode & (Upper | Lower)));
155 enum { copy = internal::traits<OtherDerived>::Flags &
RowMajorBit };
157 typedef std::conditional_t<copy, typename internal::plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>
159 OtherCopy otherCopy(other.derived());
161 internal::sparse_solve_triangular_selector<ExpressionType, std::remove_reference_t<OtherCopy>, Mode>::run(
162 derived().nestedExpression(), otherCopy);
164 if (copy) other = otherCopy;
172template <
typename Lhs,
typename Rhs,
int Mode,
176 int StorageOrder = int(Lhs::Flags) & (
RowMajorBit)>
177struct sparse_solve_triangular_sparse_selector;
180template <
typename Lhs,
typename Rhs,
int Mode,
int UpLo>
181struct sparse_solve_triangular_sparse_selector<Lhs, Rhs, Mode, UpLo, ColMajor> {
182 typedef typename Rhs::Scalar Scalar;
183 typedef typename promote_index_type<typename traits<Lhs>::StorageIndex,
typename traits<Rhs>::StorageIndex>::type
185 static void run(
const Lhs& lhs, Rhs& other) {
186 const bool IsLower = (UpLo ==
Lower);
187 AmbiVector<Scalar, StorageIndex> tempVector(other.rows() * 2);
188 tempVector.setBounds(0, other.rows());
190 Rhs res(other.rows(), other.cols());
191 res.reserve(other.nonZeros());
193 for (Index col = 0; col < other.cols(); ++col) {
195 tempVector.init(.99 );
196 tempVector.setZero();
197 tempVector.restart();
198 for (
typename Rhs::InnerIterator rhsIt(other, col); rhsIt; ++rhsIt) {
199 tempVector.coeffRef(rhsIt.index()) = rhsIt.value();
202 for (Index i = IsLower ? 0 : lhs.cols() - 1; IsLower ? i < lhs.cols() : i >= 0; i += IsLower ? 1 : -1) {
203 tempVector.restart();
204 Scalar& ci = tempVector.coeffRef(i);
205 if (!numext::is_exactly_zero(ci)) {
207 typename Lhs::InnerIterator it(lhs, i);
210 eigen_assert(it.index() == i);
213 ci /= lhs.coeff(i, i);
215 tempVector.restart();
217 if (it.index() == i) ++it;
218 for (; it; ++it) tempVector.coeffRef(it.index()) -= ci * it.value();
220 for (; it && it.index() < i; ++it) tempVector.coeffRef(it.index()) -= ci * it.value();
227 for (
typename AmbiVector<Scalar, StorageIndex>::Iterator it(tempVector ); it; ++it) {
232 res.insert(it.index(), col) = it.value();
237 other = res.markAsRValue();
243#ifndef EIGEN_PARSED_BY_DOXYGEN
244template <
typename ExpressionType,
unsigned int Mode>
245template <
typename OtherDerived>
246void TriangularViewImpl<ExpressionType, Mode, Sparse>::solveInPlace(SparseMatrixBase<OtherDerived>& other)
const {
247 eigen_assert(derived().cols() == derived().rows() && derived().cols() == other.rows());
248 eigen_assert((!(Mode & ZeroDiag)) &&
bool(Mode & (Upper | Lower)));
256 internal::sparse_solve_triangular_sparse_selector<ExpressionType, OtherDerived, Mode>::run(
257 derived().nestedExpression(), other.derived());
@ UnitDiag
Definition Constants.h:215
@ Lower
Definition Constants.h:211
@ Upper
Definition Constants.h:213
@ ColMajor
Definition Constants.h:318
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition Core:137