Eigen  3.3.3
UnaryFunctors.h
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
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends