Eigen  3.3.3
Solve.h
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
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends