MOAB  4.9.3pre
BinaryFunctors.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2010 Gael Guennebaud <[email protected]>
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_BINARY_FUNCTORS_H
00011 #define EIGEN_BINARY_FUNCTORS_H
00012 
00013 namespace Eigen {
00014 
00015 namespace internal {
00016 
00017 //---------- associative binary functors ----------
00018 
00024 template<typename Scalar> struct scalar_sum_op {
00025 //   typedef Scalar result_type;
00026   EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op)
00027   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
00028   template<typename Packet>
00029   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00030   { return internal::padd(a,b); }
00031   template<typename Packet>
00032   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00033   { return internal::predux(a); }
00034 };
00035 template<typename Scalar>
00036 struct functor_traits<scalar_sum_op<Scalar> > {
00037   enum {
00038     Cost = NumTraits<Scalar>::AddCost,
00039     PacketAccess = packet_traits<Scalar>::HasAdd
00040   };
00041 };
00042 
00048 template<> struct scalar_sum_op<bool> : scalar_sum_op<int> {
00049   EIGEN_DEPRECATED
00050   scalar_sum_op() {}
00051 };
00052 
00053 
00059 template<typename LhsScalar,typename RhsScalar> struct scalar_product_op {
00060   enum {
00061     // TODO vectorize mixed product
00062     Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
00063   };
00064   typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
00065   EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
00066   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
00067   template<typename Packet>
00068   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00069   { return internal::pmul(a,b); }
00070   template<typename Packet>
00071   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
00072   { return internal::predux_mul(a); }
00073 };
00074 template<typename LhsScalar,typename RhsScalar>
00075 struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
00076   enum {
00077     Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2, // rough estimate!
00078     PacketAccess = scalar_product_op<LhsScalar,RhsScalar>::Vectorizable
00079   };
00080 };
00081 
00087 template<typename LhsScalar,typename RhsScalar> struct scalar_conj_product_op {
00088 
00089   enum {
00090     Conj = NumTraits<LhsScalar>::IsComplex
00091   };
00092   
00093   typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
00094   
00095   EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op)
00096   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
00097   { return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
00098   
00099   template<typename Packet>
00100   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00101   { return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
00102 };
00103 template<typename LhsScalar,typename RhsScalar>
00104 struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
00105   enum {
00106     Cost = NumTraits<LhsScalar>::MulCost,
00107     PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
00108   };
00109 };
00110 
00116 template<typename Scalar> struct scalar_min_op {
00117   EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
00118   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return numext::mini(a, b); }
00119   template<typename Packet>
00120   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00121   { return internal::pmin(a,b); }
00122   template<typename Packet>
00123   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00124   { return internal::predux_min(a); }
00125 };
00126 template<typename Scalar>
00127 struct functor_traits<scalar_min_op<Scalar> > {
00128   enum {
00129     Cost = NumTraits<Scalar>::AddCost,
00130     PacketAccess = packet_traits<Scalar>::HasMin
00131   };
00132 };
00133 
00139 template<typename Scalar> struct scalar_max_op {
00140   EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
00141   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return numext::maxi(a, b); }
00142   template<typename Packet>
00143   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00144   { return internal::pmax(a,b); }
00145   template<typename Packet>
00146   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00147   { return internal::predux_max(a); }
00148 };
00149 template<typename Scalar>
00150 struct functor_traits<scalar_max_op<Scalar> > {
00151   enum {
00152     Cost = NumTraits<Scalar>::AddCost,
00153     PacketAccess = packet_traits<Scalar>::HasMax
00154   };
00155 };
00156 
00161 template<typename Scalar, ComparisonName cmp> struct scalar_cmp_op;
00162 
00163 template<typename Scalar, ComparisonName cmp>
00164 struct functor_traits<scalar_cmp_op<Scalar, cmp> > {
00165   enum {
00166     Cost = NumTraits<Scalar>::AddCost,
00167     PacketAccess = false
00168   };
00169 };
00170 
00171 template<ComparisonName Cmp, typename Scalar>
00172 struct result_of<scalar_cmp_op<Scalar, Cmp>(Scalar,Scalar)> {
00173   typedef bool type;
00174 };
00175 
00176 
00177 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_EQ> {
00178   typedef bool result_type;
00179   EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
00180   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a==b;}
00181 };
00182 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LT> {
00183   typedef bool result_type;
00184   EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
00185   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<b;}
00186 };
00187 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LE> {
00188   typedef bool result_type;
00189   EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
00190   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<=b;}
00191 };
00192 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_GT> {
00193   typedef bool result_type;
00194   EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
00195   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a>b;}
00196 };
00197 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_GE> {
00198   typedef bool result_type;
00199   EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
00200   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a>=b;}
00201 };
00202 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_UNORD> {
00203   typedef bool result_type;
00204   EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
00205   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return !(a<=b || b<=a);}
00206 };
00207 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_NEQ> {
00208   typedef bool result_type;
00209   EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
00210   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a!=b;}
00211 };
00212 
00213 
00219 template<typename Scalar> struct scalar_hypot_op {
00220   EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
00221 //   typedef typename NumTraits<Scalar>::Real result_type;
00222   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
00223   {
00224     using std::sqrt;
00225     Scalar p, qp;
00226     if(_x>_y)
00227     {
00228       p = _x;
00229       qp = _y / p;
00230     }
00231     else
00232     {
00233       p = _y;
00234       qp = _x / p;
00235     }
00236     return p * sqrt(Scalar(1) + qp*qp);
00237   }
00238 };
00239 template<typename Scalar>
00240 struct functor_traits<scalar_hypot_op<Scalar> > {
00241   enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess=0 };
00242 };
00243 
00247 template<typename Scalar, typename OtherScalar> struct scalar_binary_pow_op {
00248   EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op)
00249   EIGEN_DEVICE_FUNC
00250   inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return numext::pow(a, b); }
00251 };
00252 template<typename Scalar, typename OtherScalar>
00253 struct functor_traits<scalar_binary_pow_op<Scalar,OtherScalar> > {
00254   enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
00255 };
00256 
00257 
00258 
00259 //---------- non associative binary functors ----------
00260 
00266 template<typename Scalar> struct scalar_difference_op {
00267   EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op)
00268   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
00269   template<typename Packet>
00270   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00271   { return internal::psub(a,b); }
00272 };
00273 template<typename Scalar>
00274 struct functor_traits<scalar_difference_op<Scalar> > {
00275   enum {
00276     Cost = NumTraits<Scalar>::AddCost,
00277     PacketAccess = packet_traits<Scalar>::HasSub
00278   };
00279 };
00280 
00286 template<typename LhsScalar,typename RhsScalar> struct scalar_quotient_op {
00287   enum {
00288     // TODO vectorize mixed product
00289     Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv
00290   };
00291   typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
00292   EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
00293   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
00294   template<typename Packet>
00295   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00296   { return internal::pdiv(a,b); }
00297 };
00298 template<typename LhsScalar,typename RhsScalar>
00299 struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
00300   enum {
00301     Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost), // rough estimate!
00302     PacketAccess = scalar_quotient_op<LhsScalar,RhsScalar>::Vectorizable
00303   };
00304 };
00305 
00306 
00307 
00313 struct scalar_boolean_and_op {
00314   EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op)
00315   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; }
00316 };
00317 template<> struct functor_traits<scalar_boolean_and_op> {
00318   enum {
00319     Cost = NumTraits<bool>::AddCost,
00320     PacketAccess = false
00321   };
00322 };
00323 
00329 struct scalar_boolean_or_op {
00330   EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op)
00331   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; }
00332 };
00333 template<> struct functor_traits<scalar_boolean_or_op> {
00334   enum {
00335     Cost = NumTraits<bool>::AddCost,
00336     PacketAccess = false
00337   };
00338 };
00339 
00340 
00341 
00342 //---------- binary functors bound to a constant, thus appearing as a unary functor ----------
00343 
00349 /* NOTE why doing the pset1() in packetOp *is* an optimization ?
00350  * indeed it seems better to declare m_other as a Packet and do the pset1() once
00351  * in the constructor. However, in practice:
00352  *  - GCC does not like m_other as a Packet and generate a load every time it needs it
00353  *  - on the other hand GCC is able to moves the pset1() outside the loop :)
00354  *  - simpler code ;)
00355  * (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y)
00356  */
00357 template<typename Scalar>
00358 struct scalar_multiple_op {
00359   // FIXME default copy constructors seems bugged with std::complex<>
00360   EIGEN_DEVICE_FUNC
00361   EIGEN_STRONG_INLINE scalar_multiple_op(const scalar_multiple_op& other) : m_other(other.m_other) { }
00362   EIGEN_DEVICE_FUNC
00363   EIGEN_STRONG_INLINE scalar_multiple_op(const Scalar& other) : m_other(other) { }
00364   EIGEN_DEVICE_FUNC
00365   EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
00366   template <typename Packet>
00367   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00368   { return internal::pmul(a, pset1<Packet>(m_other)); }
00369   typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
00370 };
00371 template<typename Scalar>
00372 struct functor_traits<scalar_multiple_op<Scalar> >
00373 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00374 
00375 template<typename Scalar1, typename Scalar2>
00376 struct scalar_multiple2_op {
00377   typedef typename scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type;
00378   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_multiple2_op(const scalar_multiple2_op& other) : m_other(other.m_other) { }
00379   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_multiple2_op(const Scalar2& other) : m_other(other) { }
00380   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; }
00381   typename add_const_on_value_type<typename NumTraits<Scalar2>::Nested>::type m_other;
00382 };
00383 template<typename Scalar1,typename Scalar2>
00384 struct functor_traits<scalar_multiple2_op<Scalar1,Scalar2> >
00385 { enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess = false }; };
00386 
00395 template<typename Scalar>
00396 struct scalar_quotient1_op {
00397   // FIXME default copy constructors seems bugged with std::complex<>
00398   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_quotient1_op(const scalar_quotient1_op& other) : m_other(other.m_other) { }
00399   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other) : m_other(other) {}
00400   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
00401   template <typename Packet>
00402   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00403   { return internal::pdiv(a, pset1<Packet>(m_other)); }
00404   typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
00405 };
00406 template<typename Scalar>
00407 struct functor_traits<scalar_quotient1_op<Scalar> >
00408 { enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; };
00409 
00410 template<typename Scalar1, typename Scalar2>
00411 struct scalar_quotient2_op {
00412   typedef typename scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type;
00413   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_quotient2_op(const scalar_quotient2_op& other) : m_other(other.m_other) { }
00414   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_quotient2_op(const Scalar2& other) : m_other(other) { }
00415   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a / m_other; }
00416   typename add_const_on_value_type<typename NumTraits<Scalar2>::Nested>::type m_other;
00417 };
00418 template<typename Scalar1,typename Scalar2>
00419 struct functor_traits<scalar_quotient2_op<Scalar1,Scalar2> >
00420 { enum { Cost = 2 * NumTraits<Scalar1>::MulCost, PacketAccess = false }; };
00421 
00422 // In Eigen, any binary op (Product, CwiseBinaryOp) require the Lhs and Rhs to have the same scalar type, except for multiplication
00423 // where the mixing of different types is handled by scalar_product_traits
00424 // In particular, real * complex<real> is allowed.
00425 // FIXME move this to functor_traits adding a functor_default
00426 template<typename Functor> struct functor_is_product_like { enum { ret = 0 }; };
00427 template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
00428 template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
00429 template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_quotient_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
00430 
00431 
00436 /* If you wonder why doing the pset1() in packetOp() is an optimization check scalar_multiple_op */
00437 template<typename Scalar>
00438 struct scalar_add_op {
00439   // FIXME default copy constructors seems bugged with std::complex<>
00440   EIGEN_DEVICE_FUNC inline scalar_add_op(const scalar_add_op& other) : m_other(other.m_other) { }
00441   EIGEN_DEVICE_FUNC inline scalar_add_op(const Scalar& other) : m_other(other) { }
00442   EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return a + m_other; }
00443   template <typename Packet>
00444   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00445   { return internal::padd(a, pset1<Packet>(m_other)); }
00446   const Scalar m_other;
00447 };
00448 template<typename Scalar>
00449 struct functor_traits<scalar_add_op<Scalar> >
00450 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
00451 
00456 template<typename Scalar>
00457 struct scalar_sub_op {
00458   EIGEN_DEVICE_FUNC inline scalar_sub_op(const scalar_sub_op& other) : m_other(other.m_other) { }
00459   EIGEN_DEVICE_FUNC inline scalar_sub_op(const Scalar& other) : m_other(other) { }
00460   EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return a - m_other; }
00461   template <typename Packet>
00462   EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
00463   { return internal::psub(a, pset1<Packet>(m_other)); }
00464   const Scalar m_other;
00465 };
00466 template<typename Scalar>
00467 struct functor_traits<scalar_sub_op<Scalar> >
00468 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
00469 
00474 template<typename Scalar>
00475 struct scalar_rsub_op {
00476   EIGEN_DEVICE_FUNC inline scalar_rsub_op(const scalar_rsub_op& other) : m_other(other.m_other) { }
00477   EIGEN_DEVICE_FUNC inline scalar_rsub_op(const Scalar& other) : m_other(other) { }
00478   EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return m_other - a; }
00479   template <typename Packet>
00480   EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
00481   { return internal::psub(pset1<Packet>(m_other), a); }
00482   const Scalar m_other;
00483 };
00484 template<typename Scalar>
00485 struct functor_traits<scalar_rsub_op<Scalar> >
00486 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
00487 
00492 template<typename Scalar>
00493 struct scalar_pow_op {
00494   // FIXME default copy constructors seems bugged with std::complex<>
00495   EIGEN_DEVICE_FUNC inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { }
00496   EIGEN_DEVICE_FUNC inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
00497   EIGEN_DEVICE_FUNC
00498   inline Scalar operator() (const Scalar& a) const { return numext::pow(a, m_exponent); }
00499   const Scalar m_exponent;
00500 };
00501 template<typename Scalar>
00502 struct functor_traits<scalar_pow_op<Scalar> >
00503 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
00504 
00509 template<typename Scalar>
00510 struct scalar_inverse_mult_op {
00511   EIGEN_DEVICE_FUNC scalar_inverse_mult_op(const Scalar& other) : m_other(other) {}
00512   EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return m_other / a; }
00513   template<typename Packet>
00514   EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
00515   { return internal::pdiv(pset1<Packet>(m_other),a); }
00516   Scalar m_other;
00517 };
00518 
00519 } // end namespace internal
00520 
00521 } // end namespace Eigen
00522 
00523 #endif // EIGEN_BINARY_FUNCTORS_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines