MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2014 Gael Guennebaud <[email protected]> 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>, Dense2Dense, Scalar> 00138 { 00139 typedef Solve<DecType,RhsType> SrcXprType; 00140 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &) 00141 { 00142 // FIXME shall we resize dst here? 00143 src.dec()._solve_impl(src.rhs(), dst); 00144 } 00145 }; 00146 00147 // Specialization for "dst = dec.transpose().solve(rhs)" 00148 template<typename DstXprType, typename DecType, typename RhsType, typename Scalar> 00149 struct Assignment<DstXprType, Solve<Transpose<const DecType>,RhsType>, internal::assign_op<Scalar>, Dense2Dense, Scalar> 00150 { 00151 typedef Solve<Transpose<const DecType>,RhsType> SrcXprType; 00152 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &) 00153 { 00154 src.dec().nestedExpression().template _solve_impl_transposed<false>(src.rhs(), dst); 00155 } 00156 }; 00157 00158 // Specialization for "dst = dec.adjoint().solve(rhs)" 00159 template<typename DstXprType, typename DecType, typename RhsType, typename Scalar> 00160 struct Assignment<DstXprType, Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,RhsType>, internal::assign_op<Scalar>, Dense2Dense, Scalar> 00161 { 00162 typedef Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,RhsType> SrcXprType; 00163 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &) 00164 { 00165 src.dec().nestedExpression().nestedExpression().template _solve_impl_transposed<true>(src.rhs(), dst); 00166 } 00167 }; 00168 00169 } // end namepsace internal 00170 00171 } // end namespace Eigen 00172 00173 #endif // EIGEN_SOLVE_H