Inverse.h 3.4 KB

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