1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2016 Eugene Brevdo <ebrevdo@gmail.com> 5 // Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@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 { EIGEN_EMPTY_STRUCT_CTORscalar_igamma_op26 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> packetOpscalar_igamma_op31 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