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 = numext::madd<Scalar>(-lastVal, other.coeff(lastIndex, col), tmp);
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 = numext::madd<Scalar>(-it.value(), other.coeff(it.index(), col), tmp);
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;
111 other.coeffRef(it.index(), col) = numext::madd<Scalar>(-tmp, it.value(), other.coeffRef(it.index(), col));
120template <
typename Lhs,
typename Rhs,
int Mode>
121struct sparse_solve_triangular_selector<Lhs, Rhs, Mode, Upper, ColMajor> {
122 typedef typename Rhs::Scalar Scalar;
123 typedef evaluator<Lhs> LhsEval;
124 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
125 static void run(
const Lhs& lhs, Rhs& other) {
126 LhsEval lhsEval(lhs);
127 for (
Index col = 0; col < other.cols(); ++col) {
128 for (
Index i = lhs.cols() - 1; i >= 0; --i) {
129 Scalar& tmp = other.coeffRef(i, col);
130 if (!numext::is_exactly_zero(tmp))
134 LhsIterator it(lhsEval, i);
135 while (it && it.index() != i) ++it;
136 eigen_assert(it && it.index() == i);
137 other.coeffRef(i, col) /= it.value();
139 LhsIterator it(lhsEval, i);
140 for (; it && it.index() < i; ++it) {
141 other.coeffRef(it.index(), col) = numext::madd<Scalar>(-tmp, it.value(), other.coeffRef(it.index(), col));
151#ifndef EIGEN_PARSED_BY_DOXYGEN
153template <
typename ExpressionType,
unsigned int Mode>
154template <
typename OtherDerived>
156 eigen_assert(derived().cols() == derived().rows() && derived().cols() == other.rows());
159 enum { copy = internal::traits<OtherDerived>::Flags &
RowMajorBit };
161 typedef std::conditional_t<copy, typename internal::plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>
163 OtherCopy otherCopy(other.derived());
165 internal::sparse_solve_triangular_selector<ExpressionType, std::remove_reference_t<OtherCopy>, Mode>::run(
166 derived().nestedExpression(), otherCopy);
168 if (copy) other = otherCopy;
176template <
typename Lhs,
typename Rhs,
int Mode,
180 int StorageOrder = int(Lhs::Flags) & (
RowMajorBit)>
181struct sparse_solve_triangular_sparse_selector;
184template <
typename Lhs,
typename Rhs,
int Mode,
int UpLo>
185struct sparse_solve_triangular_sparse_selector<Lhs, Rhs, Mode, UpLo, ColMajor> {
186 typedef typename Rhs::Scalar Scalar;
187 typedef typename promote_index_type<typename traits<Lhs>::StorageIndex,
typename traits<Rhs>::StorageIndex>::type
189 static void run(
const Lhs& lhs, Rhs& other) {
190 const bool IsLower = (UpLo ==
Lower);
191 AmbiVector<Scalar, StorageIndex> tempVector(other.rows() * 2);
192 tempVector.setBounds(0, other.rows());
194 Rhs res(other.rows(), other.cols());
195 res.reserve(other.nonZeros());
197 for (
Index col = 0; col < other.cols(); ++col) {
199 tempVector.init(.99 );
200 tempVector.setZero();
201 tempVector.restart();
202 for (
typename Rhs::InnerIterator rhsIt(other, col); rhsIt; ++rhsIt) {
203 tempVector.coeffRef(rhsIt.index()) = rhsIt.value();
206 for (
Index i = IsLower ? 0 : lhs.cols() - 1; IsLower ? i < lhs.cols() : i >= 0; i += IsLower ? 1 : -1) {
207 tempVector.restart();
208 Scalar& ci = tempVector.coeffRef(i);
209 if (!numext::is_exactly_zero(ci)) {
211 typename Lhs::InnerIterator it(lhs, i);
214 eigen_assert(it.index() == i);
217 ci /= lhs.coeff(i, i);
219 tempVector.restart();
221 if (it.index() == i) ++it;
223 tempVector.coeffRef(it.index()) = numext::madd<Scalar>(-ci, it.value(), tempVector.coeffRef(it.index()));
226 for (; it && it.index() < i; ++it) {
227 tempVector.coeffRef(it.index()) = numext::madd<Scalar>(-ci, it.value(), tempVector.coeffRef(it.index()));
240 res.insert(it.index(), col) = it.value();
245 other = res.markAsRValue();
251#ifndef EIGEN_PARSED_BY_DOXYGEN
252template <
typename ExpressionType,
unsigned int Mode>
253template <
typename OtherDerived>
255 eigen_assert(derived().cols() == derived().rows() && derived().cols() == other.rows());
264 internal::sparse_solve_triangular_sparse_selector<ExpressionType, OtherDerived, Mode>::run(
265 derived().nestedExpression(), other.derived());
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:52
Base class of any sparse matrices or sparse expressions.
Definition SparseMatrixBase.h:30
Definition AmbiVector.h:251
@ UnitDiag
Definition Constants.h:215
@ ZeroDiag
Definition Constants.h:217
@ Lower
Definition Constants.h:211
@ Upper
Definition Constants.h:213
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82