Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
SelfCwiseBinaryOp.h
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2009-2010 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_SELFCWISEBINARYOP_H 00011 #define EIGEN_SELFCWISEBINARYOP_H 00012 00013 namespace Eigen { 00014 00015 /** \class SelfCwiseBinaryOp 00016 * \ingroup Core_Module 00017 * 00018 * \internal 00019 * 00020 * \brief Internal helper class for optimizing operators like +=, -= 00021 * 00022 * This is a pseudo expression class re-implementing the copyCoeff/copyPacket 00023 * method to directly performs a +=/-= operations in an optimal way. In particular, 00024 * this allows to make sure that the input/output data are loaded only once using 00025 * aligned packet loads. 00026 * 00027 * \sa class SwapWrapper for a similar trick. 00028 */ 00029 00030 namespace internal { 00031 template<typename BinaryOp, typename Lhs, typename Rhs> 00032 struct traits<SelfCwiseBinaryOp<BinaryOp,Lhs,Rhs> > 00033 : traits<CwiseBinaryOp<BinaryOp,Lhs,Rhs> > 00034 { 00035 enum { 00036 // Note that it is still a good idea to preserve the DirectAccessBit 00037 // so that assign can correctly align the data. 00038 Flags = traits<CwiseBinaryOp<BinaryOp,Lhs,Rhs> >::Flags | (Lhs::Flags&DirectAccessBit) | (Lhs::Flags&LvalueBit), 00039 OuterStrideAtCompileTime = Lhs::OuterStrideAtCompileTime, 00040 InnerStrideAtCompileTime = Lhs::InnerStrideAtCompileTime 00041 }; 00042 }; 00043 } 00044 00045 template<typename BinaryOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp 00046 : public internal::dense_xpr_base< SelfCwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type 00047 { 00048 public: 00049 00050 typedef typename internal::dense_xpr_base<SelfCwiseBinaryOp>::type Base; 00051 EIGEN_DENSE_PUBLIC_INTERFACE(SelfCwiseBinaryOp) 00052 00053 typedef typename internal::packet_traits<Scalar>::type Packet; 00054 00055 inline SelfCwiseBinaryOp(Lhs& xpr, const BinaryOp& func = BinaryOp()) : m_matrix(xpr), m_functor(func) {} 00056 00057 inline Index rows() const { return m_matrix.rows(); } 00058 inline Index cols() const { return m_matrix.cols(); } 00059 inline Index outerStride() const { return m_matrix.outerStride(); } 00060 inline Index innerStride() const { return m_matrix.innerStride(); } 00061 inline const Scalar* data() const { return m_matrix.data(); } 00062 00063 // note that this function is needed by assign to correctly align loads/stores 00064 // TODO make Assign use .data() 00065 inline Scalar& coeffRef(Index row, Index col) 00066 { 00067 EIGEN_STATIC_ASSERT_LVALUE(Lhs) 00068 return m_matrix.const_cast_derived().coeffRef(row, col); 00069 } 00070 inline const Scalar& coeffRef(Index row, Index col) const 00071 { 00072 return m_matrix.coeffRef(row, col); 00073 } 00074 00075 // note that this function is needed by assign to correctly align loads/stores 00076 // TODO make Assign use .data() 00077 inline Scalar& coeffRef(Index index) 00078 { 00079 EIGEN_STATIC_ASSERT_LVALUE(Lhs) 00080 return m_matrix.const_cast_derived().coeffRef(index); 00081 } 00082 inline const Scalar& coeffRef(Index index) const 00083 { 00084 return m_matrix.const_cast_derived().coeffRef(index); 00085 } 00086 00087 template<typename OtherDerived> 00088 void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other) 00089 { 00090 OtherDerived& _other = other.const_cast_derived(); 00091 eigen_internal_assert(row >= 0 && row < rows() 00092 && col >= 0 && col < cols()); 00093 Scalar& tmp = m_matrix.coeffRef(row,col); 00094 tmp = m_functor(tmp, _other.coeff(row,col)); 00095 } 00096 00097 template<typename OtherDerived> 00098 void copyCoeff(Index index, const DenseBase<OtherDerived>& other) 00099 { 00100 OtherDerived& _other = other.const_cast_derived(); 00101 eigen_internal_assert(index >= 0 && index < m_matrix.size()); 00102 Scalar& tmp = m_matrix.coeffRef(index); 00103 tmp = m_functor(tmp, _other.coeff(index)); 00104 } 00105 00106 template<typename OtherDerived, int StoreMode, int LoadMode> 00107 void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other) 00108 { 00109 OtherDerived& _other = other.const_cast_derived(); 00110 eigen_internal_assert(row >= 0 && row < rows() 00111 && col >= 0 && col < cols()); 00112 m_matrix.template writePacket<StoreMode>(row, col, 00113 m_functor.packetOp(m_matrix.template packet<StoreMode>(row, col),_other.template packet<LoadMode>(row, col)) ); 00114 } 00115 00116 template<typename OtherDerived, int StoreMode, int LoadMode> 00117 void copyPacket(Index index, const DenseBase<OtherDerived>& other) 00118 { 00119 OtherDerived& _other = other.const_cast_derived(); 00120 eigen_internal_assert(index >= 0 && index < m_matrix.size()); 00121 m_matrix.template writePacket<StoreMode>(index, 00122 m_functor.packetOp(m_matrix.template packet<StoreMode>(index),_other.template packet<LoadMode>(index)) ); 00123 } 00124 00125 // reimplement lazyAssign to handle complex *= real 00126 // see CwiseBinaryOp ctor for details 00127 template<typename RhsDerived> 00128 EIGEN_STRONG_INLINE SelfCwiseBinaryOp& lazyAssign(const DenseBase<RhsDerived>& rhs) 00129 { 00130 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs,RhsDerived) 00131 EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename RhsDerived::Scalar); 00132 00133 #ifdef EIGEN_DEBUG_ASSIGN 00134 internal::assign_traits<SelfCwiseBinaryOp, RhsDerived>::debug(); 00135 #endif 00136 eigen_assert(rows() == rhs.rows() && cols() == rhs.cols()); 00137 internal::assign_impl<SelfCwiseBinaryOp, RhsDerived>::run(*this,rhs.derived()); 00138 #ifndef EIGEN_NO_DEBUG 00139 this->checkTransposeAliasing(rhs.derived()); 00140 #endif 00141 return *this; 00142 } 00143 00144 // overloaded to honor evaluation of special matrices 00145 // maybe another solution would be to not use SelfCwiseBinaryOp 00146 // at first... 00147 SelfCwiseBinaryOp& operator=(const Rhs& _rhs) 00148 { 00149 typename internal::nested<Rhs>::type rhs(_rhs); 00150 return Base::operator=(rhs); 00151 } 00152 00153 Lhs& expression() const 00154 { 00155 return m_matrix; 00156 } 00157 00158 const BinaryOp& functor() const 00159 { 00160 return m_functor; 00161 } 00162 00163 protected: 00164 Lhs& m_matrix; 00165 const BinaryOp& m_functor; 00166 00167 private: 00168 SelfCwiseBinaryOp& operator=(const SelfCwiseBinaryOp&); 00169 }; 00170 00171 template<typename Derived> 00172 inline Derived& DenseBase<Derived>::operator*=(const Scalar& other) 00173 { 00174 typedef typename Derived::PlainObject PlainObject; 00175 SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived()); 00176 tmp = PlainObject::Constant(rows(),cols(),other); 00177 return derived(); 00178 } 00179 00180 template<typename Derived> 00181 inline Derived& DenseBase<Derived>::operator/=(const Scalar& other) 00182 { 00183 typedef typename Derived::PlainObject PlainObject; 00184 SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived()); 00185 tmp = PlainObject::Constant(rows(),cols(), other); 00186 return derived(); 00187 } 00188 00189 } // end namespace Eigen 00190 00191 #endif // EIGEN_SELFCWISEBINARYOP_H
Generated on Thu Nov 17 2022 22:01:30 by
1.7.2