![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-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_ASSIGNMENT_FUNCTORS_H 00011 #define EIGEN_ASSIGNMENT_FUNCTORS_H 00012 00013 namespace Eigen { 00014 00015 namespace internal { 00016 00021 template<typename DstScalar,typename SrcScalar> struct assign_op { 00022 00023 EIGEN_EMPTY_STRUCT_CTOR(assign_op) 00024 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a = b; } 00025 00026 template<int Alignment, typename Packet> 00027 EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const 00028 { internal::pstoret<DstScalar,Packet,Alignment>(a,b); } 00029 }; 00030 00031 // Empty overload for void type (used by PermutationMatrix) 00032 template<typename DstScalar> struct assign_op<DstScalar,void> {}; 00033 00034 template<typename DstScalar,typename SrcScalar> 00035 struct functor_traits<assign_op<DstScalar,SrcScalar> > { 00036 enum { 00037 Cost = NumTraits<DstScalar>::ReadCost, 00038 PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::Vectorizable && packet_traits<SrcScalar>::Vectorizable 00039 }; 00040 }; 00041 00046 template<typename DstScalar,typename SrcScalar> struct add_assign_op { 00047 00048 EIGEN_EMPTY_STRUCT_CTOR(add_assign_op) 00049 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a += b; } 00050 00051 template<int Alignment, typename Packet> 00052 EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const 00053 { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::padd(internal::ploadt<Packet,Alignment>(a),b)); } 00054 }; 00055 template<typename DstScalar,typename SrcScalar> 00056 struct functor_traits<add_assign_op<DstScalar,SrcScalar> > { 00057 enum { 00058 Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::AddCost, 00059 PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasAdd 00060 }; 00061 }; 00062 00067 template<typename DstScalar,typename SrcScalar> struct sub_assign_op { 00068 00069 EIGEN_EMPTY_STRUCT_CTOR(sub_assign_op) 00070 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a -= b; } 00071 00072 template<int Alignment, typename Packet> 00073 EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const 00074 { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::psub(internal::ploadt<Packet,Alignment>(a),b)); } 00075 }; 00076 template<typename DstScalar,typename SrcScalar> 00077 struct functor_traits<sub_assign_op<DstScalar,SrcScalar> > { 00078 enum { 00079 Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::AddCost, 00080 PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasSub 00081 }; 00082 }; 00083 00088 template<typename DstScalar, typename SrcScalar=DstScalar> 00089 struct mul_assign_op { 00090 00091 EIGEN_EMPTY_STRUCT_CTOR(mul_assign_op) 00092 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a *= b; } 00093 00094 template<int Alignment, typename Packet> 00095 EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const 00096 { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::pmul(internal::ploadt<Packet,Alignment>(a),b)); } 00097 }; 00098 template<typename DstScalar, typename SrcScalar> 00099 struct functor_traits<mul_assign_op<DstScalar,SrcScalar> > { 00100 enum { 00101 Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::MulCost, 00102 PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasMul 00103 }; 00104 }; 00105 00110 template<typename DstScalar, typename SrcScalar=DstScalar> struct div_assign_op { 00111 00112 EIGEN_EMPTY_STRUCT_CTOR(div_assign_op) 00113 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a /= b; } 00114 00115 template<int Alignment, typename Packet> 00116 EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const 00117 { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::pdiv(internal::ploadt<Packet,Alignment>(a),b)); } 00118 }; 00119 template<typename DstScalar, typename SrcScalar> 00120 struct functor_traits<div_assign_op<DstScalar,SrcScalar> > { 00121 enum { 00122 Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::MulCost, 00123 PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasDiv 00124 }; 00125 }; 00126 00142 template<typename Scalar> struct swap_assign_op { 00143 00144 EIGEN_EMPTY_STRUCT_CTOR(swap_assign_op) 00145 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const 00146 { 00147 #ifdef __CUDACC__ 00148 // FIXME is there some kind of cuda::swap? 00149 Scalar t=b; const_cast<Scalar&>(b)=a; a=t; 00150 #else 00151 using std::swap; 00152 swap(a,const_cast<Scalar&>(b)); 00153 #endif 00154 } 00155 }; 00156 template<typename Scalar> 00157 struct functor_traits<swap_assign_op<Scalar> > { 00158 enum { 00159 Cost = 3 * NumTraits<Scalar>::ReadCost, 00160 PacketAccess = packet_traits<Scalar>::Vectorizable 00161 }; 00162 }; 00163 00164 } // namespace internal 00165 00166 } // namespace Eigen 00167 00168 #endif // EIGEN_ASSIGNMENT_FUNCTORS_H