Eigne Matrix Class Library

Dependents:   MPC_current_control HydraulicControlBoard_SW AHRS Test_ekf ... more

Committer:
jsoh91
Date:
Tue Sep 24 00:18:23 2019 +0000
Revision:
1:3b8049da21b8
Parent:
0:13a5d365ba16
ignore and revise some of error parts

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ykuroda 0:13a5d365ba16 1 // This file is part of Eigen, a lightweight C++ template library
ykuroda 0:13a5d365ba16 2 // for linear algebra.
ykuroda 0:13a5d365ba16 3 //
ykuroda 0:13a5d365ba16 4 // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
ykuroda 0:13a5d365ba16 5 //
ykuroda 0:13a5d365ba16 6 // This Source Code Form is subject to the terms of the Mozilla
ykuroda 0:13a5d365ba16 7 // Public License v. 2.0. If a copy of the MPL was not distributed
ykuroda 0:13a5d365ba16 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
ykuroda 0:13a5d365ba16 9
ykuroda 0:13a5d365ba16 10 #ifndef EIGEN_SELFCWISEBINARYOP_H
ykuroda 0:13a5d365ba16 11 #define EIGEN_SELFCWISEBINARYOP_H
ykuroda 0:13a5d365ba16 12
ykuroda 0:13a5d365ba16 13 namespace Eigen {
ykuroda 0:13a5d365ba16 14
ykuroda 0:13a5d365ba16 15 /** \class SelfCwiseBinaryOp
ykuroda 0:13a5d365ba16 16 * \ingroup Core_Module
ykuroda 0:13a5d365ba16 17 *
ykuroda 0:13a5d365ba16 18 * \internal
ykuroda 0:13a5d365ba16 19 *
ykuroda 0:13a5d365ba16 20 * \brief Internal helper class for optimizing operators like +=, -=
ykuroda 0:13a5d365ba16 21 *
ykuroda 0:13a5d365ba16 22 * This is a pseudo expression class re-implementing the copyCoeff/copyPacket
ykuroda 0:13a5d365ba16 23 * method to directly performs a +=/-= operations in an optimal way. In particular,
ykuroda 0:13a5d365ba16 24 * this allows to make sure that the input/output data are loaded only once using
ykuroda 0:13a5d365ba16 25 * aligned packet loads.
ykuroda 0:13a5d365ba16 26 *
ykuroda 0:13a5d365ba16 27 * \sa class SwapWrapper for a similar trick.
ykuroda 0:13a5d365ba16 28 */
ykuroda 0:13a5d365ba16 29
ykuroda 0:13a5d365ba16 30 namespace internal {
ykuroda 0:13a5d365ba16 31 template<typename BinaryOp, typename Lhs, typename Rhs>
ykuroda 0:13a5d365ba16 32 struct traits<SelfCwiseBinaryOp<BinaryOp,Lhs,Rhs> >
ykuroda 0:13a5d365ba16 33 : traits<CwiseBinaryOp<BinaryOp,Lhs,Rhs> >
ykuroda 0:13a5d365ba16 34 {
ykuroda 0:13a5d365ba16 35 enum {
ykuroda 0:13a5d365ba16 36 // Note that it is still a good idea to preserve the DirectAccessBit
ykuroda 0:13a5d365ba16 37 // so that assign can correctly align the data.
ykuroda 0:13a5d365ba16 38 Flags = traits<CwiseBinaryOp<BinaryOp,Lhs,Rhs> >::Flags | (Lhs::Flags&DirectAccessBit) | (Lhs::Flags&LvalueBit),
ykuroda 0:13a5d365ba16 39 OuterStrideAtCompileTime = Lhs::OuterStrideAtCompileTime,
ykuroda 0:13a5d365ba16 40 InnerStrideAtCompileTime = Lhs::InnerStrideAtCompileTime
ykuroda 0:13a5d365ba16 41 };
ykuroda 0:13a5d365ba16 42 };
ykuroda 0:13a5d365ba16 43 }
ykuroda 0:13a5d365ba16 44
ykuroda 0:13a5d365ba16 45 template<typename BinaryOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp
ykuroda 0:13a5d365ba16 46 : public internal::dense_xpr_base< SelfCwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
ykuroda 0:13a5d365ba16 47 {
ykuroda 0:13a5d365ba16 48 public:
ykuroda 0:13a5d365ba16 49
ykuroda 0:13a5d365ba16 50 typedef typename internal::dense_xpr_base<SelfCwiseBinaryOp>::type Base;
ykuroda 0:13a5d365ba16 51 EIGEN_DENSE_PUBLIC_INTERFACE(SelfCwiseBinaryOp)
ykuroda 0:13a5d365ba16 52
ykuroda 0:13a5d365ba16 53 typedef typename internal::packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 54
ykuroda 0:13a5d365ba16 55 inline SelfCwiseBinaryOp(Lhs& xpr, const BinaryOp& func = BinaryOp()) : m_matrix(xpr), m_functor(func) {}
ykuroda 0:13a5d365ba16 56
ykuroda 0:13a5d365ba16 57 inline Index rows() const { return m_matrix.rows(); }
ykuroda 0:13a5d365ba16 58 inline Index cols() const { return m_matrix.cols(); }
ykuroda 0:13a5d365ba16 59 inline Index outerStride() const { return m_matrix.outerStride(); }
ykuroda 0:13a5d365ba16 60 inline Index innerStride() const { return m_matrix.innerStride(); }
ykuroda 0:13a5d365ba16 61 inline const Scalar* data() const { return m_matrix.data(); }
ykuroda 0:13a5d365ba16 62
ykuroda 0:13a5d365ba16 63 // note that this function is needed by assign to correctly align loads/stores
ykuroda 0:13a5d365ba16 64 // TODO make Assign use .data()
ykuroda 0:13a5d365ba16 65 inline Scalar& coeffRef(Index row, Index col)
ykuroda 0:13a5d365ba16 66 {
ykuroda 0:13a5d365ba16 67 EIGEN_STATIC_ASSERT_LVALUE(Lhs)
ykuroda 0:13a5d365ba16 68 return m_matrix.const_cast_derived().coeffRef(row, col);
ykuroda 0:13a5d365ba16 69 }
ykuroda 0:13a5d365ba16 70 inline const Scalar& coeffRef(Index row, Index col) const
ykuroda 0:13a5d365ba16 71 {
ykuroda 0:13a5d365ba16 72 return m_matrix.coeffRef(row, col);
ykuroda 0:13a5d365ba16 73 }
ykuroda 0:13a5d365ba16 74
ykuroda 0:13a5d365ba16 75 // note that this function is needed by assign to correctly align loads/stores
ykuroda 0:13a5d365ba16 76 // TODO make Assign use .data()
ykuroda 0:13a5d365ba16 77 inline Scalar& coeffRef(Index index)
ykuroda 0:13a5d365ba16 78 {
ykuroda 0:13a5d365ba16 79 EIGEN_STATIC_ASSERT_LVALUE(Lhs)
ykuroda 0:13a5d365ba16 80 return m_matrix.const_cast_derived().coeffRef(index);
ykuroda 0:13a5d365ba16 81 }
ykuroda 0:13a5d365ba16 82 inline const Scalar& coeffRef(Index index) const
ykuroda 0:13a5d365ba16 83 {
ykuroda 0:13a5d365ba16 84 return m_matrix.const_cast_derived().coeffRef(index);
ykuroda 0:13a5d365ba16 85 }
ykuroda 0:13a5d365ba16 86
ykuroda 0:13a5d365ba16 87 template<typename OtherDerived>
ykuroda 0:13a5d365ba16 88 void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
ykuroda 0:13a5d365ba16 89 {
ykuroda 0:13a5d365ba16 90 OtherDerived& _other = other.const_cast_derived();
ykuroda 0:13a5d365ba16 91 eigen_internal_assert(row >= 0 && row < rows()
ykuroda 0:13a5d365ba16 92 && col >= 0 && col < cols());
ykuroda 0:13a5d365ba16 93 Scalar& tmp = m_matrix.coeffRef(row,col);
ykuroda 0:13a5d365ba16 94 tmp = m_functor(tmp, _other.coeff(row,col));
ykuroda 0:13a5d365ba16 95 }
ykuroda 0:13a5d365ba16 96
ykuroda 0:13a5d365ba16 97 template<typename OtherDerived>
ykuroda 0:13a5d365ba16 98 void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
ykuroda 0:13a5d365ba16 99 {
ykuroda 0:13a5d365ba16 100 OtherDerived& _other = other.const_cast_derived();
ykuroda 0:13a5d365ba16 101 eigen_internal_assert(index >= 0 && index < m_matrix.size());
ykuroda 0:13a5d365ba16 102 Scalar& tmp = m_matrix.coeffRef(index);
ykuroda 0:13a5d365ba16 103 tmp = m_functor(tmp, _other.coeff(index));
ykuroda 0:13a5d365ba16 104 }
ykuroda 0:13a5d365ba16 105
ykuroda 0:13a5d365ba16 106 template<typename OtherDerived, int StoreMode, int LoadMode>
ykuroda 0:13a5d365ba16 107 void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
ykuroda 0:13a5d365ba16 108 {
ykuroda 0:13a5d365ba16 109 OtherDerived& _other = other.const_cast_derived();
ykuroda 0:13a5d365ba16 110 eigen_internal_assert(row >= 0 && row < rows()
ykuroda 0:13a5d365ba16 111 && col >= 0 && col < cols());
ykuroda 0:13a5d365ba16 112 m_matrix.template writePacket<StoreMode>(row, col,
ykuroda 0:13a5d365ba16 113 m_functor.packetOp(m_matrix.template packet<StoreMode>(row, col),_other.template packet<LoadMode>(row, col)) );
ykuroda 0:13a5d365ba16 114 }
ykuroda 0:13a5d365ba16 115
ykuroda 0:13a5d365ba16 116 template<typename OtherDerived, int StoreMode, int LoadMode>
ykuroda 0:13a5d365ba16 117 void copyPacket(Index index, const DenseBase<OtherDerived>& other)
ykuroda 0:13a5d365ba16 118 {
ykuroda 0:13a5d365ba16 119 OtherDerived& _other = other.const_cast_derived();
ykuroda 0:13a5d365ba16 120 eigen_internal_assert(index >= 0 && index < m_matrix.size());
ykuroda 0:13a5d365ba16 121 m_matrix.template writePacket<StoreMode>(index,
ykuroda 0:13a5d365ba16 122 m_functor.packetOp(m_matrix.template packet<StoreMode>(index),_other.template packet<LoadMode>(index)) );
ykuroda 0:13a5d365ba16 123 }
ykuroda 0:13a5d365ba16 124
ykuroda 0:13a5d365ba16 125 // reimplement lazyAssign to handle complex *= real
ykuroda 0:13a5d365ba16 126 // see CwiseBinaryOp ctor for details
ykuroda 0:13a5d365ba16 127 template<typename RhsDerived>
ykuroda 0:13a5d365ba16 128 EIGEN_STRONG_INLINE SelfCwiseBinaryOp& lazyAssign(const DenseBase<RhsDerived>& rhs)
ykuroda 0:13a5d365ba16 129 {
ykuroda 0:13a5d365ba16 130 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs,RhsDerived)
ykuroda 0:13a5d365ba16 131 EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename RhsDerived::Scalar);
ykuroda 0:13a5d365ba16 132
ykuroda 0:13a5d365ba16 133 #ifdef EIGEN_DEBUG_ASSIGN
ykuroda 0:13a5d365ba16 134 internal::assign_traits<SelfCwiseBinaryOp, RhsDerived>::debug();
ykuroda 0:13a5d365ba16 135 #endif
ykuroda 0:13a5d365ba16 136 eigen_assert(rows() == rhs.rows() && cols() == rhs.cols());
ykuroda 0:13a5d365ba16 137 internal::assign_impl<SelfCwiseBinaryOp, RhsDerived>::run(*this,rhs.derived());
ykuroda 0:13a5d365ba16 138 #ifndef EIGEN_NO_DEBUG
ykuroda 0:13a5d365ba16 139 this->checkTransposeAliasing(rhs.derived());
ykuroda 0:13a5d365ba16 140 #endif
ykuroda 0:13a5d365ba16 141 return *this;
ykuroda 0:13a5d365ba16 142 }
ykuroda 0:13a5d365ba16 143
ykuroda 0:13a5d365ba16 144 // overloaded to honor evaluation of special matrices
ykuroda 0:13a5d365ba16 145 // maybe another solution would be to not use SelfCwiseBinaryOp
ykuroda 0:13a5d365ba16 146 // at first...
ykuroda 0:13a5d365ba16 147 SelfCwiseBinaryOp& operator=(const Rhs& _rhs)
ykuroda 0:13a5d365ba16 148 {
ykuroda 0:13a5d365ba16 149 typename internal::nested<Rhs>::type rhs(_rhs);
ykuroda 0:13a5d365ba16 150 return Base::operator=(rhs);
ykuroda 0:13a5d365ba16 151 }
ykuroda 0:13a5d365ba16 152
ykuroda 0:13a5d365ba16 153 Lhs& expression() const
ykuroda 0:13a5d365ba16 154 {
ykuroda 0:13a5d365ba16 155 return m_matrix;
ykuroda 0:13a5d365ba16 156 }
ykuroda 0:13a5d365ba16 157
ykuroda 0:13a5d365ba16 158 const BinaryOp& functor() const
ykuroda 0:13a5d365ba16 159 {
ykuroda 0:13a5d365ba16 160 return m_functor;
ykuroda 0:13a5d365ba16 161 }
ykuroda 0:13a5d365ba16 162
ykuroda 0:13a5d365ba16 163 protected:
ykuroda 0:13a5d365ba16 164 Lhs& m_matrix;
ykuroda 0:13a5d365ba16 165 const BinaryOp& m_functor;
ykuroda 0:13a5d365ba16 166
ykuroda 0:13a5d365ba16 167 private:
ykuroda 0:13a5d365ba16 168 SelfCwiseBinaryOp& operator=(const SelfCwiseBinaryOp&);
ykuroda 0:13a5d365ba16 169 };
ykuroda 0:13a5d365ba16 170
ykuroda 0:13a5d365ba16 171 template<typename Derived>
ykuroda 0:13a5d365ba16 172 inline Derived& DenseBase<Derived>::operator*=(const Scalar& other)
ykuroda 0:13a5d365ba16 173 {
ykuroda 0:13a5d365ba16 174 typedef typename Derived::PlainObject PlainObject;
ykuroda 0:13a5d365ba16 175 SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
ykuroda 0:13a5d365ba16 176 tmp = PlainObject::Constant(rows(),cols(),other);
ykuroda 0:13a5d365ba16 177 return derived();
ykuroda 0:13a5d365ba16 178 }
ykuroda 0:13a5d365ba16 179
ykuroda 0:13a5d365ba16 180 template<typename Derived>
ykuroda 0:13a5d365ba16 181 inline Derived& DenseBase<Derived>::operator/=(const Scalar& other)
ykuroda 0:13a5d365ba16 182 {
ykuroda 0:13a5d365ba16 183 typedef typename Derived::PlainObject PlainObject;
ykuroda 0:13a5d365ba16 184 SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
ykuroda 0:13a5d365ba16 185 tmp = PlainObject::Constant(rows(),cols(), other);
ykuroda 0:13a5d365ba16 186 return derived();
ykuroda 0:13a5d365ba16 187 }
ykuroda 0:13a5d365ba16 188
ykuroda 0:13a5d365ba16 189 } // end namespace Eigen
ykuroda 0:13a5d365ba16 190
ykuroda 0:13a5d365ba16 191 #endif // EIGEN_SELFCWISEBINARYOP_H