MOAB
4.9.3pre
|
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