Home | History | Annotate | Download | only in SpecialFunctions
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2016 Eugene Brevdo <ebrevdo (at) gmail.com>
      5 // Copyright (C) 2016 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      6 //
      7 // This Source Code Form is subject to the terms of the Mozilla
      8 // Public License v. 2.0. If a copy of the MPL was not distributed
      9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     10 
     11 #ifndef EIGEN_SPECIALFUNCTIONS_FUNCTORS_H
     12 #define EIGEN_SPECIALFUNCTIONS_FUNCTORS_H
     13 
     14 namespace Eigen {
     15 
     16 namespace internal {
     17 
     18 
     19 /** \internal
     20   * \brief Template functor to compute the incomplete gamma function igamma(a, x)
     21   *
     22   * \sa class CwiseBinaryOp, Cwise::igamma
     23   */
     24 template<typename Scalar> struct scalar_igamma_op : binary_op_base<Scalar,Scalar>
     25 {
     26   EIGEN_EMPTY_STRUCT_CTOR(scalar_igamma_op)
     27   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& x) const {
     28     using numext::igamma; return igamma(a, x);
     29   }
     30   template<typename Packet>
     31   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& x) const {
     32     return internal::pigamma(a, x);
     33   }
     34 };
     35 template<typename Scalar>
     36 struct functor_traits<scalar_igamma_op<Scalar> > {
     37   enum {
     38     // Guesstimate
     39     Cost = 20 * NumTraits<Scalar>::MulCost + 10 * NumTraits<Scalar>::AddCost,
     40     PacketAccess = packet_traits<Scalar>::HasIGamma
     41   };
     42 };
     43 
     44 
     45 /** \internal
     46   * \brief Template functor to compute the complementary incomplete gamma function igammac(a, x)
     47   *
     48   * \sa class CwiseBinaryOp, Cwise::igammac
     49   */
     50 template<typename Scalar> struct scalar_igammac_op : binary_op_base<Scalar,Scalar>
     51 {
     52   EIGEN_EMPTY_STRUCT_CTOR(scalar_igammac_op)
     53   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& x) const {
     54     using numext::igammac; return igammac(a, x);
     55   }
     56   template<typename Packet>
     57   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& x) const
     58   {
     59     return internal::pigammac(a, x);
     60   }
     61 };
     62 template<typename Scalar>
     63 struct functor_traits<scalar_igammac_op<Scalar> > {
     64   enum {
     65     // Guesstimate
     66     Cost = 20 * NumTraits<Scalar>::MulCost + 10 * NumTraits<Scalar>::AddCost,
     67     PacketAccess = packet_traits<Scalar>::HasIGammac
     68   };
     69 };
     70 
     71 
     72 /** \internal
     73   * \brief Template functor to compute the incomplete beta integral betainc(a, b, x)
     74   *
     75   */
     76 template<typename Scalar> struct scalar_betainc_op {
     77   EIGEN_EMPTY_STRUCT_CTOR(scalar_betainc_op)
     78   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& x, const Scalar& a, const Scalar& b) const {
     79     using numext::betainc; return betainc(x, a, b);
     80   }
     81   template<typename Packet>
     82   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& x, const Packet& a, const Packet& b) const
     83   {
     84     return internal::pbetainc(x, a, b);
     85   }
     86 };
     87 template<typename Scalar>
     88 struct functor_traits<scalar_betainc_op<Scalar> > {
     89   enum {
     90     // Guesstimate
     91     Cost = 400 * NumTraits<Scalar>::MulCost + 400 * NumTraits<Scalar>::AddCost,
     92     PacketAccess = packet_traits<Scalar>::HasBetaInc
     93   };
     94 };
     95 
     96 
     97 /** \internal
     98  * \brief Template functor to compute the natural log of the absolute
     99  * value of Gamma of a scalar
    100  * \sa class CwiseUnaryOp, Cwise::lgamma()
    101  */
    102 template<typename Scalar> struct scalar_lgamma_op {
    103   EIGEN_EMPTY_STRUCT_CTOR(scalar_lgamma_op)
    104   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const {
    105     using numext::lgamma; return lgamma(a);
    106   }
    107   typedef typename packet_traits<Scalar>::type Packet;
    108   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plgamma(a); }
    109 };
    110 template<typename Scalar>
    111 struct functor_traits<scalar_lgamma_op<Scalar> >
    112 {
    113   enum {
    114     // Guesstimate
    115     Cost = 10 * NumTraits<Scalar>::MulCost + 5 * NumTraits<Scalar>::AddCost,
    116     PacketAccess = packet_traits<Scalar>::HasLGamma
    117   };
    118 };
    119 
    120 /** \internal
    121  * \brief Template functor to compute psi, the derivative of lgamma of a scalar.
    122  * \sa class CwiseUnaryOp, Cwise::digamma()
    123  */
    124 template<typename Scalar> struct scalar_digamma_op {
    125   EIGEN_EMPTY_STRUCT_CTOR(scalar_digamma_op)
    126   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const {
    127     using numext::digamma; return digamma(a);
    128   }
    129   typedef typename packet_traits<Scalar>::type Packet;
    130   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pdigamma(a); }
    131 };
    132 template<typename Scalar>
    133 struct functor_traits<scalar_digamma_op<Scalar> >
    134 {
    135   enum {
    136     // Guesstimate
    137     Cost = 10 * NumTraits<Scalar>::MulCost + 5 * NumTraits<Scalar>::AddCost,
    138     PacketAccess = packet_traits<Scalar>::HasDiGamma
    139   };
    140 };
    141 
    142 /** \internal
    143  * \brief Template functor to compute the Riemann Zeta function of two arguments.
    144  * \sa class CwiseUnaryOp, Cwise::zeta()
    145  */
    146 template<typename Scalar> struct scalar_zeta_op {
    147     EIGEN_EMPTY_STRUCT_CTOR(scalar_zeta_op)
    148     EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& x, const Scalar& q) const {
    149         using numext::zeta; return zeta(x, q);
    150     }
    151     typedef typename packet_traits<Scalar>::type Packet;
    152     EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& x, const Packet& q) const { return internal::pzeta(x, q); }
    153 };
    154 template<typename Scalar>
    155 struct functor_traits<scalar_zeta_op<Scalar> >
    156 {
    157     enum {
    158         // Guesstimate
    159         Cost = 10 * NumTraits<Scalar>::MulCost + 5 * NumTraits<Scalar>::AddCost,
    160         PacketAccess = packet_traits<Scalar>::HasZeta
    161     };
    162 };
    163 
    164 /** \internal
    165  * \brief Template functor to compute the polygamma function.
    166  * \sa class CwiseUnaryOp, Cwise::polygamma()
    167  */
    168 template<typename Scalar> struct scalar_polygamma_op {
    169     EIGEN_EMPTY_STRUCT_CTOR(scalar_polygamma_op)
    170     EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& n, const Scalar& x) const {
    171         using numext::polygamma; return polygamma(n, x);
    172     }
    173     typedef typename packet_traits<Scalar>::type Packet;
    174     EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& n, const Packet& x) const { return internal::ppolygamma(n, x); }
    175 };
    176 template<typename Scalar>
    177 struct functor_traits<scalar_polygamma_op<Scalar> >
    178 {
    179     enum {
    180         // Guesstimate
    181         Cost = 10 * NumTraits<Scalar>::MulCost + 5 * NumTraits<Scalar>::AddCost,
    182         PacketAccess = packet_traits<Scalar>::HasPolygamma
    183     };
    184 };
    185 
    186 /** \internal
    187  * \brief Template functor to compute the Gauss error function of a
    188  * scalar
    189  * \sa class CwiseUnaryOp, Cwise::erf()
    190  */
    191 template<typename Scalar> struct scalar_erf_op {
    192   EIGEN_EMPTY_STRUCT_CTOR(scalar_erf_op)
    193   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const {
    194     using numext::erf; return erf(a);
    195   }
    196   typedef typename packet_traits<Scalar>::type Packet;
    197   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::perf(a); }
    198 };
    199 template<typename Scalar>
    200 struct functor_traits<scalar_erf_op<Scalar> >
    201 {
    202   enum {
    203     // Guesstimate
    204     Cost = 10 * NumTraits<Scalar>::MulCost + 5 * NumTraits<Scalar>::AddCost,
    205     PacketAccess = packet_traits<Scalar>::HasErf
    206   };
    207 };
    208 
    209 /** \internal
    210  * \brief Template functor to compute the Complementary Error Function
    211  * of a scalar
    212  * \sa class CwiseUnaryOp, Cwise::erfc()
    213  */
    214 template<typename Scalar> struct scalar_erfc_op {
    215   EIGEN_EMPTY_STRUCT_CTOR(scalar_erfc_op)
    216   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const {
    217     using numext::erfc; return erfc(a);
    218   }
    219   typedef typename packet_traits<Scalar>::type Packet;
    220   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::perfc(a); }
    221 };
    222 template<typename Scalar>
    223 struct functor_traits<scalar_erfc_op<Scalar> >
    224 {
    225   enum {
    226     // Guesstimate
    227     Cost = 10 * NumTraits<Scalar>::MulCost + 5 * NumTraits<Scalar>::AddCost,
    228     PacketAccess = packet_traits<Scalar>::HasErfc
    229   };
    230 };
    231 
    232 } // end namespace internal
    233 
    234 } // end namespace Eigen
    235 
    236 #endif // EIGEN_SPECIALFUNCTIONS_FUNCTORS_H
    237