1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2014-2019 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_INVERSE_H 11 #define EIGEN_INVERSE_H 12 13 namespace Eigen { 14 15 template<typename XprType,typename StorageKind> class InverseImpl; 16 17 namespace internal { 18 19 template<typename XprType> 20 struct traits<Inverse<XprType> > 21 : traits<typename XprType::PlainObject> 22 { 23 typedef typename XprType::PlainObject PlainObject; 24 typedef traits<PlainObject> BaseTraits; 25 enum { 26 Flags = BaseTraits::Flags & RowMajorBit 27 }; 28 }; 29 30 } // end namespace internal 31 32 /** \class Inverse 33 * 34 * \brief Expression of the inverse of another expression 35 * 36 * \tparam XprType the type of the expression we are taking the inverse 37 * 38 * This class represents an abstract expression of A.inverse() 39 * and most of the time this is the only way it is used. 40 * 41 */ 42 template<typename XprType> 43 class Inverse : public InverseImpl<XprType,typename internal::traits<XprType>::StorageKind> 44 { 45 public: 46 typedef typename XprType::StorageIndex StorageIndex; 47 typedef typename XprType::Scalar Scalar; 48 typedef typename internal::ref_selector<XprType>::type XprTypeNested; 49 typedef typename internal::remove_all<XprTypeNested>::type XprTypeNestedCleaned; 50 typedef typename internal::ref_selector<Inverse>::type Nested; 51 typedef typename internal::remove_all<XprType>::type NestedExpression; 52 53 explicit EIGEN_DEVICE_FUNC Inverse(const XprType &xpr) 54 : m_xpr(xpr) 55 {} 56 57 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_xpr.cols(); } 58 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_xpr.rows(); } 59 60 EIGEN_DEVICE_FUNC const XprTypeNestedCleaned& nestedExpression() const { return m_xpr; } 61 62 protected: 63 XprTypeNested m_xpr; 64 }; 65 66 // Generic API dispatcher 67 template<typename XprType, typename StorageKind> 68 class InverseImpl 69 : public internal::generic_xpr_base<Inverse<XprType> >::type 70 { 71 public: 72 typedef typename internal::generic_xpr_base<Inverse<XprType> >::type Base; 73 typedef typename XprType::Scalar Scalar; 74 private: 75 76 Scalar coeff(Index row, Index col) const; 77 Scalar coeff(Index i) const; 78 }; 79 80 namespace internal { 81 82 /** \internal 83 * \brief Default evaluator for Inverse expression. 84 * 85 * This default evaluator for Inverse expression simply evaluate the inverse into a temporary 86 * by a call to internal::call_assignment_no_alias. 87 * Therefore, inverse implementers only have to specialize Assignment<Dst,Inverse<...>, ...> for 88 * there own nested expression. 89 * 90 * \sa class Inverse 91 */ 92 template<typename ArgType> 93 struct unary_evaluator<Inverse<ArgType> > 94 : public evaluator<typename Inverse<ArgType>::PlainObject> 95 { 96 typedef Inverse<ArgType> InverseType; 97 typedef typename InverseType::PlainObject PlainObject; 98 typedef evaluator<PlainObject> Base; 99 100 enum { Flags = Base::Flags | EvalBeforeNestingBit }; 101 102 unary_evaluator(const InverseType& inv_xpr) 103 : m_result(inv_xpr.rows(), inv_xpr.cols()) 104 { 105 ::new (static_cast<Base*>(this)) Base(m_result); 106 internal::call_assignment_no_alias(m_result, inv_xpr); 107 } 108 109 protected: 110 PlainObject m_result; 111 }; 112 113 } // end namespace internal 114 115 } // end namespace Eigen 116 117 #endif // EIGEN_INVERSE_H 118