![]() |
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-2016 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_UNARY_FUNCTORS_H 00011 #define EIGEN_UNARY_FUNCTORS_H 00012 00013 namespace Eigen { 00014 00015 namespace internal { 00016 00022 template<typename Scalar> struct scalar_opposite_op { 00023 EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op) 00024 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; } 00025 template<typename Packet> 00026 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const 00027 { return internal::pnegate(a); } 00028 }; 00029 template<typename Scalar> 00030 struct functor_traits<scalar_opposite_op<Scalar> > 00031 { enum { 00032 Cost = NumTraits<Scalar>::AddCost, 00033 PacketAccess = packet_traits<Scalar>::HasNegate }; 00034 }; 00035 00041 template<typename Scalar> struct scalar_abs_op { 00042 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op) 00043 typedef typename NumTraits<Scalar>::Real result_type; 00044 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs(a); } 00045 template<typename Packet> 00046 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const 00047 { return internal::pabs(a); } 00048 }; 00049 template<typename Scalar> 00050 struct functor_traits<scalar_abs_op<Scalar> > 00051 { 00052 enum { 00053 Cost = NumTraits<Scalar>::AddCost, 00054 PacketAccess = packet_traits<Scalar>::HasAbs 00055 }; 00056 }; 00057 00063 template<typename Scalar> struct scalar_score_coeff_op : scalar_abs_op<Scalar> 00064 { 00065 typedef void Score_is_abs; 00066 }; 00067 template<typename Scalar> 00068 struct functor_traits<scalar_score_coeff_op<Scalar> > : functor_traits<scalar_abs_op<Scalar> > {}; 00069 00070 /* Avoid recomputing abs when we know the score and they are the same. Not a true Eigen functor. */ 00071 template<typename Scalar, typename=void> struct abs_knowing_score 00072 { 00073 EIGEN_EMPTY_STRUCT_CTOR(abs_knowing_score) 00074 typedef typename NumTraits<Scalar>::Real result_type; 00075 template<typename Score> 00076 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a, const Score&) const { return numext::abs(a); } 00077 }; 00078 template<typename Scalar> struct abs_knowing_score<Scalar, typename scalar_score_coeff_op<Scalar>::Score_is_abs> 00079 { 00080 EIGEN_EMPTY_STRUCT_CTOR(abs_knowing_score) 00081 typedef typename NumTraits<Scalar>::Real result_type; 00082 template<typename Scal> 00083 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scal&, const result_type& a) const { return a; } 00084 }; 00085 00091 template<typename Scalar> struct scalar_abs2_op { 00092 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op) 00093 typedef typename NumTraits<Scalar>::Real result_type; 00094 EIGEN_DEVICE_FUNC 00095 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); } 00096 template<typename Packet> 00097 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const 00098 { return internal::pmul(a,a); } 00099 }; 00100 template<typename Scalar> 00101 struct functor_traits<scalar_abs2_op<Scalar> > 00102 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasAbs2 }; }; 00103 00109 template<typename Scalar> struct scalar_conjugate_op { 00110 EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op) 00111 EIGEN_DEVICE_FUNC 00112 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::conj; return conj(a); } 00113 template<typename Packet> 00114 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); } 00115 }; 00116 template<typename Scalar> 00117 struct functor_traits<scalar_conjugate_op<Scalar> > 00118 { 00119 enum { 00120 Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0, 00121 PacketAccess = packet_traits<Scalar>::HasConj 00122 }; 00123 }; 00124 00130 template<typename Scalar> struct scalar_arg_op { 00131 EIGEN_EMPTY_STRUCT_CTOR(scalar_arg_op) 00132 typedef typename NumTraits<Scalar>::Real result_type; 00133 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using numext::arg; return arg(a); } 00134 template<typename Packet> 00135 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const 00136 { return internal::parg(a); } 00137 }; 00138 template<typename Scalar> 00139 struct functor_traits<scalar_arg_op<Scalar> > 00140 { 00141 enum { 00142 Cost = NumTraits<Scalar>::IsComplex ? 5 * NumTraits<Scalar>::MulCost : NumTraits<Scalar>::AddCost, 00143 PacketAccess = packet_traits<Scalar>::HasArg 00144 }; 00145 }; 00151 template<typename Scalar, typename NewType> 00152 struct scalar_cast_op { 00153 EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op) 00154 typedef NewType result_type; 00155 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); } 00156 }; 00157 template<typename Scalar, typename NewType> 00158 struct functor_traits<scalar_cast_op<Scalar,NewType> > 00159 { enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; }; 00160 00166 template<typename Scalar> 00167 struct scalar_real_op { 00168 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op) 00169 typedef typename NumTraits<Scalar>::Real result_type; 00170 EIGEN_DEVICE_FUNC 00171 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); } 00172 }; 00173 template<typename Scalar> 00174 struct functor_traits<scalar_real_op<Scalar> > 00175 { enum { Cost = 0, PacketAccess = false }; }; 00176 00182 template<typename Scalar> 00183 struct scalar_imag_op { 00184 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op) 00185 typedef typename NumTraits<Scalar>::Real result_type; 00186 EIGEN_DEVICE_FUNC 00187 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); } 00188 }; 00189 template<typename Scalar> 00190 struct functor_traits<scalar_imag_op<Scalar> > 00191 { enum { Cost = 0, PacketAccess = false }; }; 00192 00198 template<typename Scalar> 00199 struct scalar_real_ref_op { 00200 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op) 00201 typedef typename NumTraits<Scalar>::Real result_type; 00202 EIGEN_DEVICE_FUNC 00203 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast<Scalar*>(&a)); } 00204 }; 00205 template<typename Scalar> 00206 struct functor_traits<scalar_real_ref_op<Scalar> > 00207 { enum { Cost = 0, PacketAccess = false }; }; 00208 00214 template<typename Scalar> 00215 struct scalar_imag_ref_op { 00216 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op) 00217 typedef typename NumTraits<Scalar>::Real result_type; 00218 EIGEN_DEVICE_FUNC 00219 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast<Scalar*>(&a)); } 00220 }; 00221 template<typename Scalar> 00222 struct functor_traits<scalar_imag_ref_op<Scalar> > 00223 { enum { Cost = 0, PacketAccess = false }; }; 00224 00231 template<typename Scalar> struct scalar_exp_op { 00232 EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op) 00233 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::exp(a); } 00234 template <typename Packet> 00235 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pexp(a); } 00236 }; 00237 template <typename Scalar> 00238 struct functor_traits<scalar_exp_op<Scalar> > { 00239 enum { 00240 PacketAccess = packet_traits<Scalar>::HasExp, 00241 // The following numbers are based on the AVX implementation. 00242 #ifdef EIGEN_VECTORIZE_FMA 00243 // Haswell can issue 2 add/mul/madd per cycle. 00244 Cost = 00245 (sizeof(Scalar) == 4 00246 // float: 8 pmadd, 4 pmul, 2 padd/psub, 6 other 00247 ? (8 * NumTraits<Scalar>::AddCost + 6 * NumTraits<Scalar>::MulCost) 00248 // double: 7 pmadd, 5 pmul, 3 padd/psub, 1 div, 13 other 00249 : (14 * NumTraits<Scalar>::AddCost + 00250 6 * NumTraits<Scalar>::MulCost + 00251 scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value)) 00252 #else 00253 Cost = 00254 (sizeof(Scalar) == 4 00255 // float: 7 pmadd, 6 pmul, 4 padd/psub, 10 other 00256 ? (21 * NumTraits<Scalar>::AddCost + 13 * NumTraits<Scalar>::MulCost) 00257 // double: 7 pmadd, 5 pmul, 3 padd/psub, 1 div, 13 other 00258 : (23 * NumTraits<Scalar>::AddCost + 00259 12 * NumTraits<Scalar>::MulCost + 00260 scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value)) 00261 #endif 00262 }; 00263 }; 00264 00271 template<typename Scalar> struct scalar_log_op { 00272 EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op) 00273 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::log(a); } 00274 template <typename Packet> 00275 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plog(a); } 00276 }; 00277 template <typename Scalar> 00278 struct functor_traits<scalar_log_op<Scalar> > { 00279 enum { 00280 PacketAccess = packet_traits<Scalar>::HasLog, 00281 Cost = 00282 (PacketAccess 00283 // The following numbers are based on the AVX implementation. 00284 #ifdef EIGEN_VECTORIZE_FMA 00285 // 8 pmadd, 6 pmul, 8 padd/psub, 16 other, can issue 2 add/mul/madd per cycle. 00286 ? (20 * NumTraits<Scalar>::AddCost + 7 * NumTraits<Scalar>::MulCost) 00287 #else 00288 // 8 pmadd, 6 pmul, 8 padd/psub, 20 other 00289 ? (36 * NumTraits<Scalar>::AddCost + 14 * NumTraits<Scalar>::MulCost) 00290 #endif 00291 // Measured cost of std::log. 00292 : sizeof(Scalar)==4 ? 40 : 85) 00293 }; 00294 }; 00295 00302 template<typename Scalar> struct scalar_log1p_op { 00303 EIGEN_EMPTY_STRUCT_CTOR(scalar_log1p_op) 00304 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::log1p(a); } 00305 template <typename Packet> 00306 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plog1p(a); } 00307 }; 00308 template <typename Scalar> 00309 struct functor_traits<scalar_log1p_op<Scalar> > { 00310 enum { 00311 PacketAccess = packet_traits<Scalar>::HasLog1p, 00312 Cost = functor_traits<scalar_log_op<Scalar> >::Cost // TODO measure cost of log1p 00313 }; 00314 }; 00315 00322 template<typename Scalar> struct scalar_log10_op { 00323 EIGEN_EMPTY_STRUCT_CTOR(scalar_log10_op) 00324 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { EIGEN_USING_STD_MATH(log10) return log10(a); } 00325 template <typename Packet> 00326 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plog10(a); } 00327 }; 00328 template<typename Scalar> 00329 struct functor_traits<scalar_log10_op<Scalar> > 00330 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog10 }; }; 00331 00336 template<typename Scalar> struct scalar_sqrt_op { 00337 EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op) 00338 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::sqrt(a); } 00339 template <typename Packet> 00340 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); } 00341 }; 00342 template <typename Scalar> 00343 struct functor_traits<scalar_sqrt_op<Scalar> > { 00344 enum { 00345 #if EIGEN_FAST_MATH 00346 // The following numbers are based on the AVX implementation. 00347 Cost = (sizeof(Scalar) == 8 ? 28 00348 // 4 pmul, 1 pmadd, 3 other 00349 : (3 * NumTraits<Scalar>::AddCost + 00350 5 * NumTraits<Scalar>::MulCost)), 00351 #else 00352 // The following numbers are based on min VSQRT throughput on Haswell. 00353 Cost = (sizeof(Scalar) == 8 ? 28 : 14), 00354 #endif 00355 PacketAccess = packet_traits<Scalar>::HasSqrt 00356 }; 00357 }; 00358 00363 template<typename Scalar> struct scalar_rsqrt_op { 00364 EIGEN_EMPTY_STRUCT_CTOR(scalar_rsqrt_op) 00365 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return Scalar(1)/numext::sqrt(a); } 00366 template <typename Packet> 00367 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::prsqrt(a); } 00368 }; 00369 00370 template<typename Scalar> 00371 struct functor_traits<scalar_rsqrt_op<Scalar> > 00372 { enum { 00373 Cost = 5 * NumTraits<Scalar>::MulCost, 00374 PacketAccess = packet_traits<Scalar>::HasRsqrt 00375 }; 00376 }; 00377 00382 template<typename Scalar> struct scalar_cos_op { 00383 EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op) 00384 EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return numext::cos(a); } 00385 template <typename Packet> 00386 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pcos(a); } 00387 }; 00388 template<typename Scalar> 00389 struct functor_traits<scalar_cos_op<Scalar> > 00390 { 00391 enum { 00392 Cost = 5 * NumTraits<Scalar>::MulCost, 00393 PacketAccess = packet_traits<Scalar>::HasCos 00394 }; 00395 }; 00396 00401 template<typename Scalar> struct scalar_sin_op { 00402 EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op) 00403 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::sin(a); } 00404 template <typename Packet> 00405 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psin(a); } 00406 }; 00407 template<typename Scalar> 00408 struct functor_traits<scalar_sin_op<Scalar> > 00409 { 00410 enum { 00411 Cost = 5 * NumTraits<Scalar>::MulCost, 00412 PacketAccess = packet_traits<Scalar>::HasSin 00413 }; 00414 }; 00415 00416 00421 template<typename Scalar> struct scalar_tan_op { 00422 EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op) 00423 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::tan(a); } 00424 template <typename Packet> 00425 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::ptan(a); } 00426 }; 00427 template<typename Scalar> 00428 struct functor_traits<scalar_tan_op<Scalar> > 00429 { 00430 enum { 00431 Cost = 5 * NumTraits<Scalar>::MulCost, 00432 PacketAccess = packet_traits<Scalar>::HasTan 00433 }; 00434 }; 00435 00440 template<typename Scalar> struct scalar_acos_op { 00441 EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op) 00442 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::acos(a); } 00443 template <typename Packet> 00444 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pacos(a); } 00445 }; 00446 template<typename Scalar> 00447 struct functor_traits<scalar_acos_op<Scalar> > 00448 { 00449 enum { 00450 Cost = 5 * NumTraits<Scalar>::MulCost, 00451 PacketAccess = packet_traits<Scalar>::HasACos 00452 }; 00453 }; 00454 00459 template<typename Scalar> struct scalar_asin_op { 00460 EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op) 00461 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::asin(a); } 00462 template <typename Packet> 00463 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pasin(a); } 00464 }; 00465 template<typename Scalar> 00466 struct functor_traits<scalar_asin_op<Scalar> > 00467 { 00468 enum { 00469 Cost = 5 * NumTraits<Scalar>::MulCost, 00470 PacketAccess = packet_traits<Scalar>::HasASin 00471 }; 00472 }; 00473 00474 00479 template<typename Scalar> struct scalar_atan_op { 00480 EIGEN_EMPTY_STRUCT_CTOR(scalar_atan_op) 00481 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::atan(a); } 00482 template <typename Packet> 00483 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::patan(a); } 00484 }; 00485 template<typename Scalar> 00486 struct functor_traits<scalar_atan_op<Scalar> > 00487 { 00488 enum { 00489 Cost = 5 * NumTraits<Scalar>::MulCost, 00490 PacketAccess = packet_traits<Scalar>::HasATan 00491 }; 00492 }; 00493 00498 template <typename Scalar> 00499 struct scalar_tanh_op { 00500 EIGEN_EMPTY_STRUCT_CTOR(scalar_tanh_op) 00501 EIGEN_DEVICE_FUNC inline const Scalar operator()(const Scalar& a) const { return numext::tanh(a); } 00502 template <typename Packet> 00503 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& x) const { return ptanh(x); } 00504 }; 00505 00506 template <typename Scalar> 00507 struct functor_traits<scalar_tanh_op<Scalar> > { 00508 enum { 00509 PacketAccess = packet_traits<Scalar>::HasTanh, 00510 Cost = ( (EIGEN_FAST_MATH && is_same<Scalar,float>::value) 00511 // The following numbers are based on the AVX implementation, 00512 #ifdef EIGEN_VECTORIZE_FMA 00513 // Haswell can issue 2 add/mul/madd per cycle. 00514 // 9 pmadd, 2 pmul, 1 div, 2 other 00515 ? (2 * NumTraits<Scalar>::AddCost + 00516 6 * NumTraits<Scalar>::MulCost + 00517 scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value) 00518 #else 00519 ? (11 * NumTraits<Scalar>::AddCost + 00520 11 * NumTraits<Scalar>::MulCost + 00521 scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value) 00522 #endif 00523 // This number assumes a naive implementation of tanh 00524 : (6 * NumTraits<Scalar>::AddCost + 00525 3 * NumTraits<Scalar>::MulCost + 00526 2 * scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value + 00527 functor_traits<scalar_exp_op<Scalar> >::Cost)) 00528 }; 00529 }; 00530 00535 template<typename Scalar> struct scalar_sinh_op { 00536 EIGEN_EMPTY_STRUCT_CTOR(scalar_sinh_op) 00537 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::sinh(a); } 00538 template <typename Packet> 00539 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psinh(a); } 00540 }; 00541 template<typename Scalar> 00542 struct functor_traits<scalar_sinh_op<Scalar> > 00543 { 00544 enum { 00545 Cost = 5 * NumTraits<Scalar>::MulCost, 00546 PacketAccess = packet_traits<Scalar>::HasSinh 00547 }; 00548 }; 00549 00554 template<typename Scalar> struct scalar_cosh_op { 00555 EIGEN_EMPTY_STRUCT_CTOR(scalar_cosh_op) 00556 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::cosh(a); } 00557 template <typename Packet> 00558 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pcosh(a); } 00559 }; 00560 template<typename Scalar> 00561 struct functor_traits<scalar_cosh_op<Scalar> > 00562 { 00563 enum { 00564 Cost = 5 * NumTraits<Scalar>::MulCost, 00565 PacketAccess = packet_traits<Scalar>::HasCosh 00566 }; 00567 }; 00568 00573 template<typename Scalar> 00574 struct scalar_inverse_op { 00575 EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op) 00576 EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; } 00577 template<typename Packet> 00578 EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const 00579 { return internal::pdiv(pset1<Packet>(Scalar(1)),a); } 00580 }; 00581 template<typename Scalar> 00582 struct functor_traits<scalar_inverse_op<Scalar> > 00583 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; }; 00584 00589 template<typename Scalar> 00590 struct scalar_square_op { 00591 EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op) 00592 EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return a*a; } 00593 template<typename Packet> 00594 EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const 00595 { return internal::pmul(a,a); } 00596 }; 00597 template<typename Scalar> 00598 struct functor_traits<scalar_square_op<Scalar> > 00599 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; }; 00600 00605 template<typename Scalar> 00606 struct scalar_cube_op { 00607 EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op) 00608 EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return a*a*a; } 00609 template<typename Packet> 00610 EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const 00611 { return internal::pmul(a,pmul(a,a)); } 00612 }; 00613 template<typename Scalar> 00614 struct functor_traits<scalar_cube_op<Scalar> > 00615 { enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; }; 00616 00621 template<typename Scalar> struct scalar_round_op { 00622 EIGEN_EMPTY_STRUCT_CTOR(scalar_round_op) 00623 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::round(a); } 00624 template <typename Packet> 00625 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pround(a); } 00626 }; 00627 template<typename Scalar> 00628 struct functor_traits<scalar_round_op<Scalar> > 00629 { 00630 enum { 00631 Cost = NumTraits<Scalar>::MulCost, 00632 PacketAccess = packet_traits<Scalar>::HasRound 00633 }; 00634 }; 00635 00640 template<typename Scalar> struct scalar_floor_op { 00641 EIGEN_EMPTY_STRUCT_CTOR(scalar_floor_op) 00642 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::floor(a); } 00643 template <typename Packet> 00644 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pfloor(a); } 00645 }; 00646 template<typename Scalar> 00647 struct functor_traits<scalar_floor_op<Scalar> > 00648 { 00649 enum { 00650 Cost = NumTraits<Scalar>::MulCost, 00651 PacketAccess = packet_traits<Scalar>::HasFloor 00652 }; 00653 }; 00654 00659 template<typename Scalar> struct scalar_ceil_op { 00660 EIGEN_EMPTY_STRUCT_CTOR(scalar_ceil_op) 00661 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::ceil(a); } 00662 template <typename Packet> 00663 EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pceil(a); } 00664 }; 00665 template<typename Scalar> 00666 struct functor_traits<scalar_ceil_op<Scalar> > 00667 { 00668 enum { 00669 Cost = NumTraits<Scalar>::MulCost, 00670 PacketAccess = packet_traits<Scalar>::HasCeil 00671 }; 00672 }; 00673 00678 template<typename Scalar> struct scalar_isnan_op { 00679 EIGEN_EMPTY_STRUCT_CTOR(scalar_isnan_op) 00680 typedef bool result_type; 00681 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return (numext::isnan)(a); } 00682 }; 00683 template<typename Scalar> 00684 struct functor_traits<scalar_isnan_op<Scalar> > 00685 { 00686 enum { 00687 Cost = NumTraits<Scalar>::MulCost, 00688 PacketAccess = false 00689 }; 00690 }; 00691 00696 template<typename Scalar> struct scalar_isinf_op { 00697 EIGEN_EMPTY_STRUCT_CTOR(scalar_isinf_op) 00698 typedef bool result_type; 00699 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return (numext::isinf)(a); } 00700 }; 00701 template<typename Scalar> 00702 struct functor_traits<scalar_isinf_op<Scalar> > 00703 { 00704 enum { 00705 Cost = NumTraits<Scalar>::MulCost, 00706 PacketAccess = false 00707 }; 00708 }; 00709 00714 template<typename Scalar> struct scalar_isfinite_op { 00715 EIGEN_EMPTY_STRUCT_CTOR(scalar_isfinite_op) 00716 typedef bool result_type; 00717 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return (numext::isfinite)(a); } 00718 }; 00719 template<typename Scalar> 00720 struct functor_traits<scalar_isfinite_op<Scalar> > 00721 { 00722 enum { 00723 Cost = NumTraits<Scalar>::MulCost, 00724 PacketAccess = false 00725 }; 00726 }; 00727 00733 template<typename Scalar> struct scalar_boolean_not_op { 00734 EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_not_op) 00735 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a) const { return !a; } 00736 }; 00737 template<typename Scalar> 00738 struct functor_traits<scalar_boolean_not_op<Scalar> > { 00739 enum { 00740 Cost = NumTraits<bool>::AddCost, 00741 PacketAccess = false 00742 }; 00743 }; 00744 00749 template<typename Scalar,bool iscpx=(NumTraits<Scalar>::IsComplex!=0) > struct scalar_sign_op; 00750 template<typename Scalar> 00751 struct scalar_sign_op<Scalar,false> { 00752 EIGEN_EMPTY_STRUCT_CTOR(scalar_sign_op) 00753 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const 00754 { 00755 return Scalar( (a>Scalar(0)) - (a<Scalar(0)) ); 00756 } 00757 //TODO 00758 //template <typename Packet> 00759 //EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psign(a); } 00760 }; 00761 template<typename Scalar> 00762 struct scalar_sign_op<Scalar,true> { 00763 EIGEN_EMPTY_STRUCT_CTOR(scalar_sign_op) 00764 EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const 00765 { 00766 typedef typename NumTraits<Scalar>::Real real_type; 00767 real_type aa = numext::abs(a); 00768 if (aa==real_type(0)) 00769 return Scalar(0); 00770 aa = real_type(1)/aa; 00771 return Scalar(real(a)*aa, imag(a)*aa ); 00772 } 00773 //TODO 00774 //template <typename Packet> 00775 //EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psign(a); } 00776 }; 00777 template<typename Scalar> 00778 struct functor_traits<scalar_sign_op<Scalar> > 00779 { enum { 00780 Cost = 00781 NumTraits<Scalar>::IsComplex 00782 ? ( 8*NumTraits<Scalar>::MulCost ) // roughly 00783 : ( 3*NumTraits<Scalar>::AddCost), 00784 PacketAccess = packet_traits<Scalar>::HasSign 00785 }; 00786 }; 00787 00788 } // end namespace internal 00789 00790 } // end namespace Eigen 00791 00792 #endif // EIGEN_FUNCTORS_H