Eigen  5.0.1-dev+60122df6
 
Loading...
Searching...
No Matches
Solve.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#ifndef EIGEN_SOLVE_H
11#define EIGEN_SOLVE_H
12
13// IWYU pragma: private
14#include "./InternalHeaderCheck.h"
15
16namespace Eigen {
17
18template <typename Decomposition, typename RhsType, typename StorageKind>
19class SolveImpl;
20
33namespace internal {
34
35// this solve_traits class permits to determine the evaluation type with respect to storage kind (Dense vs Sparse)
36template <typename Decomposition, typename RhsType, typename StorageKind>
37struct solve_traits;
38
39template <typename Decomposition, typename RhsType>
40struct solve_traits<Decomposition, RhsType, Dense> {
41 typedef typename make_proper_matrix_type<typename RhsType::Scalar, Decomposition::ColsAtCompileTime,
42 RhsType::ColsAtCompileTime, RhsType::PlainObject::Options,
43 Decomposition::MaxColsAtCompileTime, RhsType::MaxColsAtCompileTime>::type
44 PlainObject;
45};
46
47template <typename Decomposition, typename RhsType>
48struct traits<Solve<Decomposition, RhsType> >
49 : traits<
50 typename solve_traits<Decomposition, RhsType, typename internal::traits<RhsType>::StorageKind>::PlainObject> {
51 typedef typename solve_traits<Decomposition, RhsType, typename internal::traits<RhsType>::StorageKind>::PlainObject
52 PlainObject;
53 typedef typename promote_index_type<typename Decomposition::StorageIndex, typename RhsType::StorageIndex>::type
54 StorageIndex;
55 typedef traits<PlainObject> BaseTraits;
56 enum { Flags = BaseTraits::Flags & RowMajorBit, CoeffReadCost = HugeCost };
57};
58
59} // namespace internal
60
61template <typename Decomposition, typename RhsType>
62class Solve : public SolveImpl<Decomposition, RhsType, typename internal::traits<RhsType>::StorageKind> {
63 public:
64 typedef typename internal::traits<Solve>::PlainObject PlainObject;
65 typedef typename internal::traits<Solve>::StorageIndex StorageIndex;
66
67 Solve(const Decomposition &dec, const RhsType &rhs) : m_dec(dec), m_rhs(rhs) {}
68
69 EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_dec.cols(); }
70 EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_rhs.cols(); }
71
72 EIGEN_DEVICE_FUNC const Decomposition &dec() const { return m_dec; }
73 EIGEN_DEVICE_FUNC const RhsType &rhs() const { return m_rhs; }
74
75 protected:
76 const Decomposition &m_dec;
77 const typename internal::ref_selector<RhsType>::type m_rhs;
78};
79
80// Specialization of the Solve expression for dense results
81template <typename Decomposition, typename RhsType>
82class SolveImpl<Decomposition, RhsType, Dense> : public MatrixBase<Solve<Decomposition, RhsType> > {
83 typedef Solve<Decomposition, RhsType> Derived;
84
85 public:
87 EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
88
89 private:
90 Scalar coeff(Index row, Index col) const;
91 Scalar coeff(Index i) const;
92};
93
94// Generic API dispatcher
95template <typename Decomposition, typename RhsType, typename StorageKind>
96class SolveImpl : public internal::generic_xpr_base<Solve<Decomposition, RhsType>, MatrixXpr, StorageKind>::type {
97 public:
98 typedef typename internal::generic_xpr_base<Solve<Decomposition, RhsType>, MatrixXpr, StorageKind>::type Base;
99};
100
101namespace internal {
102
103// Evaluator of Solve -> eval into a temporary
104template <typename Decomposition, typename RhsType>
105struct evaluator<Solve<Decomposition, RhsType> >
106 : public evaluator<typename Solve<Decomposition, RhsType>::PlainObject> {
107 typedef Solve<Decomposition, RhsType> SolveType;
108 typedef typename SolveType::PlainObject PlainObject;
109 typedef evaluator<PlainObject> Base;
110
111 enum { Flags = Base::Flags | EvalBeforeNestingBit };
112
113 EIGEN_DEVICE_FUNC explicit evaluator(const SolveType &solve) : m_result(solve.rows(), solve.cols()) {
114 internal::construct_at<Base>(this, m_result);
115 solve.dec()._solve_impl(solve.rhs(), m_result);
116 }
117
118 protected:
119 PlainObject m_result;
120};
121
122// Specialization for "dst = dec.solve(rhs)"
123// NOTE we need to specialize it for Dense2Dense to avoid ambiguous specialization error and a Sparse2Sparse
124// specialization must exist somewhere
125template <typename DstXprType, typename DecType, typename RhsType, typename Scalar>
126struct Assignment<DstXprType, Solve<DecType, RhsType>, internal::assign_op<Scalar, Scalar>, Dense2Dense> {
127 typedef Solve<DecType, RhsType> SrcXprType;
128 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar, Scalar> &) {
129 Index dstRows = src.rows();
130 Index dstCols = src.cols();
131 if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);
132
133 src.dec()._solve_impl(src.rhs(), dst);
134 }
135};
136
137// Specialization for "dst = dec.transpose().solve(rhs)"
138template <typename DstXprType, typename DecType, typename RhsType, typename Scalar>
139struct Assignment<DstXprType, Solve<Transpose<const DecType>, RhsType>, internal::assign_op<Scalar, Scalar>,
140 Dense2Dense> {
141 typedef Solve<Transpose<const DecType>, RhsType> SrcXprType;
142 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar, Scalar> &) {
143 Index dstRows = src.rows();
144 Index dstCols = src.cols();
145 if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);
146
147 src.dec().nestedExpression().template _solve_impl_transposed<false>(src.rhs(), dst);
148 }
149};
150
151// Specialization for "dst = dec.adjoint().solve(rhs)"
152template <typename DstXprType, typename DecType, typename RhsType, typename Scalar>
153struct Assignment<
154 DstXprType,
155 Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,
156 RhsType>,
157 internal::assign_op<Scalar, Scalar>, Dense2Dense> {
158 typedef Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,
159 RhsType>
160 SrcXprType;
161 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar, Scalar> &) {
162 Index dstRows = src.rows();
163 Index dstCols = src.cols();
164 if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);
165
166 src.dec().nestedExpression().nestedExpression().template _solve_impl_transposed<true>(src.rhs(), dst);
167 }
168};
169
170} // end namespace internal
171
172} // end namespace Eigen
173
174#endif // EIGEN_SOLVE_H
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:52
Pseudo expression representing a solving operation.
Definition Solve.h:62
const unsigned int EvalBeforeNestingBit
Definition Constants.h:74
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
const int HugeCost
Definition Constants.h:48
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82
Definition Constants.h:519