![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_SOLVE_H 00011 #define EIGEN_SOLVE_H 00012 00013 namespace Eigen { 00014 00015 template<typename Decomposition, typename RhsType, typename StorageKind> class SolveImpl; 00016 00029 namespace internal { 00030 00031 // this solve_traits class permits to determine the evaluation type with respect to storage kind (Dense vs Sparse) 00032 template<typename Decomposition, typename RhsType,typename StorageKind> struct solve_traits; 00033 00034 template<typename Decomposition, typename RhsType> 00035 struct solve_traits<Decomposition,RhsType,Dense> 00036 { 00037 typedef Matrix<typename RhsType::Scalar, 00038 Decomposition::ColsAtCompileTime, 00039 RhsType::ColsAtCompileTime, 00040 RhsType::PlainObject::Options, 00041 Decomposition::MaxColsAtCompileTime, 00042 RhsType::MaxColsAtCompileTime> PlainObject; 00043 }; 00044 00045 template<typename Decomposition, typename RhsType> 00046 struct traits<Solve<Decomposition, RhsType> > 00047 : traits<typename solve_traits<Decomposition,RhsType,typename internal::traits<RhsType>::StorageKind>::PlainObject> 00048 { 00049 typedef typename solve_traits<Decomposition,RhsType,typename internal::traits<RhsType>::StorageKind>::PlainObject PlainObject; 00050 typedef typename promote_index_type<typename Decomposition::StorageIndex, typename RhsType::StorageIndex>::type StorageIndex; 00051 typedef traits<PlainObject> BaseTraits; 00052 enum { 00053 Flags = BaseTraits::Flags & RowMajorBit, 00054 CoeffReadCost = HugeCost 00055 }; 00056 }; 00057 00058 } 00059 00060 00061 template<typename Decomposition, typename RhsType> 00062 class Solve : public SolveImpl<Decomposition,RhsType,typename internal::traits<RhsType>::StorageKind> 00063 { 00064 public: 00065 typedef typename internal::traits<Solve>::PlainObject PlainObject; 00066 typedef typename internal::traits<Solve>::StorageIndex StorageIndex; 00067 00068 Solve(const Decomposition &dec, const RhsType &rhs) 00069 : m_dec(dec), m_rhs(rhs) 00070 {} 00071 00072 EIGEN_DEVICE_FUNC Index rows() const { return m_dec.cols(); } 00073 EIGEN_DEVICE_FUNC Index cols() const { return m_rhs.cols(); } 00074 00075 EIGEN_DEVICE_FUNC const Decomposition& dec() const { return m_dec; } 00076 EIGEN_DEVICE_FUNC const RhsType& rhs() const { return m_rhs; } 00077 00078 protected: 00079 const Decomposition &m_dec; 00080 const RhsType &m_rhs; 00081 }; 00082 00083 00084 // Specialization of the Solve expression for dense results 00085 template<typename Decomposition, typename RhsType> 00086 class SolveImpl<Decomposition,RhsType,Dense> 00087 : public MatrixBase<Solve<Decomposition,RhsType> > 00088 { 00089 typedef Solve<Decomposition,RhsType> Derived; 00090 00091 public: 00092 00093 typedef MatrixBase<Solve<Decomposition,RhsType> > Base; 00094 EIGEN_DENSE_PUBLIC_INTERFACE(Derived) 00095 00096 private: 00097 00098 Scalar coeff(Index row, Index col) const; 00099 Scalar coeff(Index i) const; 00100 }; 00101 00102 // Generic API dispatcher 00103 template<typename Decomposition, typename RhsType, typename StorageKind> 00104 class SolveImpl : public internal::generic_xpr_base<Solve<Decomposition,RhsType>, MatrixXpr, StorageKind>::type 00105 { 00106 public: 00107 typedef typename internal::generic_xpr_base<Solve<Decomposition,RhsType>, MatrixXpr, StorageKind>::type Base; 00108 }; 00109 00110 namespace internal { 00111 00112 // Evaluator of Solve -> eval into a temporary 00113 template<typename Decomposition, typename RhsType> 00114 struct evaluator<Solve<Decomposition,RhsType> > 00115 : public evaluator<typename Solve<Decomposition,RhsType>::PlainObject> 00116 { 00117 typedef Solve<Decomposition,RhsType> SolveType; 00118 typedef typename SolveType::PlainObject PlainObject; 00119 typedef evaluator<PlainObject> Base; 00120 00121 enum { Flags = Base::Flags | EvalBeforeNestingBit }; 00122 00123 EIGEN_DEVICE_FUNC explicit evaluator(const SolveType& solve) 00124 : m_result(solve.rows(), solve.cols()) 00125 { 00126 ::new (static_cast<Base*>(this)) Base(m_result); 00127 solve.dec()._solve_impl(solve.rhs(), m_result); 00128 } 00129 00130 protected: 00131 PlainObject m_result; 00132 }; 00133 00134 // Specialization for "dst = dec.solve(rhs)" 00135 // NOTE we need to specialize it for Dense2Dense to avoid ambiguous specialization error and a Sparse2Sparse specialization must exist somewhere 00136 template<typename DstXprType, typename DecType, typename RhsType, typename Scalar> 00137 struct Assignment<DstXprType, Solve<DecType,RhsType>, internal::assign_op<Scalar,Scalar>, Dense2Dense> 00138 { 00139 typedef Solve<DecType,RhsType> SrcXprType; 00140 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &) 00141 { 00142 Index dstRows = src.rows(); 00143 Index dstCols = src.cols(); 00144 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols)) 00145 dst.resize(dstRows, dstCols); 00146 00147 src.dec()._solve_impl(src.rhs(), dst); 00148 } 00149 }; 00150 00151 // Specialization for "dst = dec.transpose().solve(rhs)" 00152 template<typename DstXprType, typename DecType, typename RhsType, typename Scalar> 00153 struct Assignment<DstXprType, Solve<Transpose<const DecType>,RhsType>, internal::assign_op<Scalar,Scalar>, Dense2Dense> 00154 { 00155 typedef Solve<Transpose<const DecType>,RhsType> SrcXprType; 00156 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &) 00157 { 00158 Index dstRows = src.rows(); 00159 Index dstCols = src.cols(); 00160 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols)) 00161 dst.resize(dstRows, dstCols); 00162 00163 src.dec().nestedExpression().template _solve_impl_transposed<false>(src.rhs(), dst); 00164 } 00165 }; 00166 00167 // Specialization for "dst = dec.adjoint().solve(rhs)" 00168 template<typename DstXprType, typename DecType, typename RhsType, typename Scalar> 00169 struct Assignment<DstXprType, Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,RhsType>, 00170 internal::assign_op<Scalar,Scalar>, Dense2Dense> 00171 { 00172 typedef Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,RhsType> SrcXprType; 00173 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &) 00174 { 00175 Index dstRows = src.rows(); 00176 Index dstCols = src.cols(); 00177 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols)) 00178 dst.resize(dstRows, dstCols); 00179 00180 src.dec().nestedExpression().nestedExpression().template _solve_impl_transposed<true>(src.rhs(), dst); 00181 } 00182 }; 00183 00184 } // end namepsace internal 00185 00186 } // end namespace Eigen 00187 00188 #endif // EIGEN_SOLVE_H