MOAB  4.9.3pre
Solve.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines