00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_FUNCTORS_H
00026 #define EIGEN_FUNCTORS_H
00027
00028
00029
00035 template<typename Scalar> struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT {
00036 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
00037 template<typename PacketScalar>
00038 EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
00039 { return ei_padd(a,b); }
00040 };
00041 template<typename Scalar>
00042 struct ei_functor_traits<ei_scalar_sum_op<Scalar> > {
00043 enum {
00044 Cost = NumTraits<Scalar>::AddCost,
00045 PacketAccess = ei_packet_traits<Scalar>::size>1
00046 };
00047 };
00048
00054 template<typename Scalar> struct ei_scalar_product_op EIGEN_EMPTY_STRUCT {
00055 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
00056 template<typename PacketScalar>
00057 EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
00058 { return ei_pmul(a,b); }
00059 };
00060 template<typename Scalar>
00061 struct ei_functor_traits<ei_scalar_product_op<Scalar> > {
00062 enum {
00063 Cost = NumTraits<Scalar>::MulCost,
00064 PacketAccess = ei_packet_traits<Scalar>::size>1
00065 };
00066 };
00067
00073 template<typename Scalar> struct ei_scalar_min_op EIGEN_EMPTY_STRUCT {
00074 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
00075 template<typename PacketScalar>
00076 EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
00077 { return ei_pmin(a,b); }
00078 };
00079 template<typename Scalar>
00080 struct ei_functor_traits<ei_scalar_min_op<Scalar> > {
00081 enum {
00082 Cost = NumTraits<Scalar>::AddCost,
00083 PacketAccess = ei_packet_traits<Scalar>::size>1
00084 };
00085 };
00086
00092 template<typename Scalar> struct ei_scalar_max_op EIGEN_EMPTY_STRUCT {
00093 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
00094 template<typename PacketScalar>
00095 EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
00096 { return ei_pmax(a,b); }
00097 };
00098 template<typename Scalar>
00099 struct ei_functor_traits<ei_scalar_max_op<Scalar> > {
00100 enum {
00101 Cost = NumTraits<Scalar>::AddCost,
00102 PacketAccess = ei_packet_traits<Scalar>::size>1
00103 };
00104 };
00105
00106
00107
00108
00114 template<typename Scalar> struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT {
00115 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
00116 template<typename PacketScalar>
00117 EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
00118 { return ei_psub(a,b); }
00119 };
00120 template<typename Scalar>
00121 struct ei_functor_traits<ei_scalar_difference_op<Scalar> > {
00122 enum {
00123 Cost = NumTraits<Scalar>::AddCost,
00124 PacketAccess = ei_packet_traits<Scalar>::size>1
00125 };
00126 };
00127
00133 template<typename Scalar> struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT {
00134 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
00135 template<typename PacketScalar>
00136 EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
00137 { return ei_pdiv(a,b); }
00138 };
00139 template<typename Scalar>
00140 struct ei_functor_traits<ei_scalar_quotient_op<Scalar> > {
00141 enum {
00142 Cost = 2 * NumTraits<Scalar>::MulCost,
00143 PacketAccess = ei_packet_traits<Scalar>::size>1
00144 #if (defined EIGEN_VECTORIZE_SSE)
00145 && NumTraits<Scalar>::HasFloatingPoint
00146 #endif
00147 };
00148 };
00149
00150
00151
00157 template<typename Scalar> struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT {
00158 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
00159 };
00160 template<typename Scalar>
00161 struct ei_functor_traits<ei_scalar_opposite_op<Scalar> >
00162 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false }; };
00163
00169 template<typename Scalar> struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT {
00170 typedef typename NumTraits<Scalar>::Real result_type;
00171 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs(a); }
00172 };
00173 template<typename Scalar>
00174 struct ei_functor_traits<ei_scalar_abs_op<Scalar> >
00175 {
00176 enum {
00177 Cost = NumTraits<Scalar>::AddCost,
00178 PacketAccess = false
00179 };
00180 };
00181
00187 template<typename Scalar> struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT {
00188 typedef typename NumTraits<Scalar>::Real result_type;
00189 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs2(a); }
00190 template<typename PacketScalar>
00191 EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
00192 { return ei_pmul(a,a); }
00193 };
00194 template<typename Scalar>
00195 struct ei_functor_traits<ei_scalar_abs2_op<Scalar> >
00196 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = int(ei_packet_traits<Scalar>::size)>1 }; };
00197
00203 template<typename Scalar> struct ei_scalar_conjugate_op EIGEN_EMPTY_STRUCT {
00204 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return ei_conj(a); }
00205 template<typename PacketScalar>
00206 EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return a; }
00207 };
00208 template<typename Scalar>
00209 struct ei_functor_traits<ei_scalar_conjugate_op<Scalar> >
00210 {
00211 enum {
00212 Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0,
00213 PacketAccess = int(ei_packet_traits<Scalar>::size)>1
00214 };
00215 };
00216
00222 template<typename Scalar, typename NewType>
00223 struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT {
00224 typedef NewType result_type;
00225 EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return static_cast<NewType>(a); }
00226 };
00227 template<typename Scalar, typename NewType>
00228 struct ei_functor_traits<ei_scalar_cast_op<Scalar,NewType> >
00229 { enum { Cost = ei_is_same_type<Scalar, NewType>::ret ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; };
00230
00236 template<typename Scalar>
00237 struct ei_scalar_real_op EIGEN_EMPTY_STRUCT {
00238 typedef typename NumTraits<Scalar>::Real result_type;
00239 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_real(a); }
00240 };
00241 template<typename Scalar>
00242 struct ei_functor_traits<ei_scalar_real_op<Scalar> >
00243 { enum { Cost = 0, PacketAccess = false }; };
00244
00250 template<typename Scalar>
00251 struct ei_scalar_imag_op EIGEN_EMPTY_STRUCT {
00252 typedef typename NumTraits<Scalar>::Real result_type;
00253 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_imag(a); }
00254 };
00255 template<typename Scalar>
00256 struct ei_functor_traits<ei_scalar_imag_op<Scalar> >
00257 { enum { Cost = 0, PacketAccess = false }; };
00258
00264
00265
00266
00267
00268
00269
00270
00271
00272 template<typename Scalar>
00273 struct ei_scalar_multiple_op {
00274 typedef typename ei_packet_traits<Scalar>::type PacketScalar;
00275
00276 EIGEN_STRONG_INLINE ei_scalar_multiple_op(const ei_scalar_multiple_op& other) : m_other(other.m_other) { }
00277 EIGEN_STRONG_INLINE ei_scalar_multiple_op(const Scalar& other) : m_other(other) { }
00278 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
00279 EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
00280 { return ei_pmul(a, ei_pset1(m_other)); }
00281 const Scalar m_other;
00282 private:
00283 ei_scalar_multiple_op& operator=(const ei_scalar_multiple_op&);
00284 };
00285 template<typename Scalar>
00286 struct ei_functor_traits<ei_scalar_multiple_op<Scalar> >
00287 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = ei_packet_traits<Scalar>::size>1 }; };
00288
00289 template<typename Scalar, bool HasFloatingPoint>
00290 struct ei_scalar_quotient1_impl {
00291 typedef typename ei_packet_traits<Scalar>::type PacketScalar;
00292
00293 EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const ei_scalar_quotient1_impl& other) : m_other(other.m_other) { }
00294 EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
00295 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
00296 EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
00297 { return ei_pmul(a, ei_pset1(m_other)); }
00298 const Scalar m_other;
00299 private:
00300 ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&);
00301 };
00302 template<typename Scalar>
00303 struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> >
00304 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = ei_packet_traits<Scalar>::size>1 }; };
00305
00306 template<typename Scalar>
00307 struct ei_scalar_quotient1_impl<Scalar,false> {
00308
00309 EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const ei_scalar_quotient1_impl& other) : m_other(other.m_other) { }
00310 EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
00311 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
00312 const Scalar m_other;
00313 private:
00314 ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&);
00315 };
00316 template<typename Scalar>
00317 struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,false> >
00318 { enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
00319
00328 template<typename Scalar>
00329 struct ei_scalar_quotient1_op : ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint > {
00330 EIGEN_STRONG_INLINE ei_scalar_quotient1_op(const Scalar& other)
00331 : ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint >(other) {}
00332 private:
00333 ei_scalar_quotient1_op& operator=(const ei_scalar_quotient1_op&);
00334 };
00335
00336
00337
00338 template<typename Scalar>
00339 struct ei_scalar_constant_op {
00340 typedef typename ei_packet_traits<Scalar>::type PacketScalar;
00341 EIGEN_STRONG_INLINE ei_scalar_constant_op(const ei_scalar_constant_op& other) : m_other(other.m_other) { }
00342 EIGEN_STRONG_INLINE ei_scalar_constant_op(const Scalar& other) : m_other(other) { }
00343 EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; }
00344 EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); }
00345 const Scalar m_other;
00346 private:
00347 ei_scalar_constant_op& operator=(const ei_scalar_constant_op&);
00348 };
00349 template<typename Scalar>
00350 struct ei_functor_traits<ei_scalar_constant_op<Scalar> >
00351 { enum { Cost = 1, PacketAccess = ei_packet_traits<Scalar>::size>1, IsRepeatable = true }; };
00352
00353 template<typename Scalar> struct ei_scalar_identity_op EIGEN_EMPTY_STRUCT {
00354 EIGEN_STRONG_INLINE ei_scalar_identity_op(void) {}
00355 EIGEN_STRONG_INLINE const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); }
00356 };
00357 template<typename Scalar>
00358 struct ei_functor_traits<ei_scalar_identity_op<Scalar> >
00359 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
00360
00361
00362
00363 #ifdef EIGEN_FUNCTORS_PLUGIN
00364 #include EIGEN_FUNCTORS_PLUGIN
00365 #endif
00366
00367
00368
00369
00370 template<typename Functor> struct ei_functor_has_linear_access { enum { ret = 1 }; };
00371 template<typename Scalar> struct ei_functor_has_linear_access<ei_scalar_identity_op<Scalar> > { enum { ret = 0 }; };
00372
00373
00374
00375 template<typename Functor> struct ei_functor_allows_mixing_real_and_complex { enum { ret = 0 }; };
00376 template<typename Scalar> struct ei_functor_allows_mixing_real_and_complex<ei_scalar_product_op<Scalar> > { enum { ret = 1 }; };
00377
00378 #endif // EIGEN_FUNCTORS_H