SpecialFunctionsFunctors.h
Go to the documentation of this file.
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 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 
20 
26 template<typename Scalar> struct scalar_igamma_op : binary_op_base<Scalar,Scalar>
27 {
28  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& x) const {
29  using numext::igamma; return igamma(a, x);
30  }
31  template<typename Packet>
32  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& x) const {
33  return internal::pigamma(a, x);
34  }
35 };
36 template<typename Scalar>
37 struct functor_traits<scalar_igamma_op<Scalar> > {
38  enum {
39  // Guesstimate
41  PacketAccess = packet_traits<Scalar>::HasIGamma
42  };
43 };
44 
51 template <typename Scalar>
52 struct scalar_igamma_der_a_op {
53  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(const Scalar& a, const Scalar& x) const {
55  return igamma_der_a(a, x);
56  }
57  template <typename Packet>
58  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& x) const {
59  return internal::pigamma_der_a(a, x);
60  }
61 };
62 template <typename Scalar>
63 struct functor_traits<scalar_igamma_der_a_op<Scalar> > {
64  enum {
65  // 2x the cost of igamma
67  PacketAccess = packet_traits<Scalar>::HasIGammaDerA
68  };
69 };
70 
78 template <typename Scalar>
79 struct scalar_gamma_sample_der_alpha_op {
80  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(const Scalar& alpha, const Scalar& sample) const {
82  return gamma_sample_der_alpha(alpha, sample);
83  }
84  template <typename Packet>
85  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& alpha, const Packet& sample) const {
86  return internal::pgamma_sample_der_alpha(alpha, sample);
87  }
88 };
89 template <typename Scalar>
90 struct functor_traits<scalar_gamma_sample_der_alpha_op<Scalar> > {
91  enum {
92  // 2x the cost of igamma, minus the lgamma cost (the lgamma cancels out)
94  PacketAccess = packet_traits<Scalar>::HasGammaSampleDerAlpha
95  };
96 };
97 
103 template<typename Scalar> struct scalar_igammac_op : binary_op_base<Scalar,Scalar>
104 {
105  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& x) const {
106  using numext::igammac; return igammac(a, x);
107  }
108  template<typename Packet>
109  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& x) const
110  {
111  return internal::pigammac(a, x);
112  }
113 };
114 template<typename Scalar>
115 struct functor_traits<scalar_igammac_op<Scalar> > {
116  enum {
117  // Guesstimate
119  PacketAccess = packet_traits<Scalar>::HasIGammac
120  };
121 };
122 
123 
128 template<typename Scalar> struct scalar_betainc_op {
129  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& x, const Scalar& a, const Scalar& b) const {
130  using numext::betainc; return betainc(x, a, b);
131  }
132  template<typename Packet>
133  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& x, const Packet& a, const Packet& b) const
134  {
135  return internal::pbetainc(x, a, b);
136  }
137 };
138 template<typename Scalar>
139 struct functor_traits<scalar_betainc_op<Scalar> > {
140  enum {
141  // Guesstimate
143  PacketAccess = packet_traits<Scalar>::HasBetaInc
144  };
145 };
146 
147 
153 template<typename Scalar> struct scalar_lgamma_op {
154  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const {
155  using numext::lgamma; return lgamma(a);
156  }
157  typedef typename packet_traits<Scalar>::type Packet;
158  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a) const { return internal::plgamma(a); }
159 };
160 template<typename Scalar>
161 struct functor_traits<scalar_lgamma_op<Scalar> >
162 {
163  enum {
164  // Guesstimate
166  PacketAccess = packet_traits<Scalar>::HasLGamma
167  };
168 };
169 
174 template<typename Scalar> struct scalar_digamma_op {
175  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const {
176  using numext::digamma; return digamma(a);
177  }
178  typedef typename packet_traits<Scalar>::type Packet;
179  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a) const { return internal::pdigamma(a); }
180 };
181 template<typename Scalar>
182 struct functor_traits<scalar_digamma_op<Scalar> >
183 {
184  enum {
185  // Guesstimate
187  PacketAccess = packet_traits<Scalar>::HasDiGamma
188  };
189 };
190 
195 template<typename Scalar> struct scalar_zeta_op {
196  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& x, const Scalar& q) const {
197  using numext::zeta; return zeta(x, q);
198  }
199  typedef typename packet_traits<Scalar>::type Packet;
200  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& x, const Packet& q) const { return internal::pzeta(x, q); }
201 };
202 template<typename Scalar>
203 struct functor_traits<scalar_zeta_op<Scalar> >
204 {
205  enum {
206  // Guesstimate
208  PacketAccess = packet_traits<Scalar>::HasZeta
209  };
210 };
211 
216 template<typename Scalar> struct scalar_polygamma_op {
217  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& n, const Scalar& x) const {
218  using numext::polygamma; return polygamma(n, x);
219  }
220  typedef typename packet_traits<Scalar>::type Packet;
221  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& n, const Packet& x) const { return internal::ppolygamma(n, x); }
222 };
223 template<typename Scalar>
224 struct functor_traits<scalar_polygamma_op<Scalar> >
225 {
226  enum {
227  // Guesstimate
229  PacketAccess = packet_traits<Scalar>::HasPolygamma
230  };
231 };
232 
237 template<typename Scalar> struct scalar_erf_op {
238  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar
239  operator()(const Scalar& a) const {
240  return numext::erf(a);
241  }
242  template <typename Packet>
243  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& x) const {
244  return perf(x);
245  }
246 };
247 template <typename Scalar>
248 struct functor_traits<scalar_erf_op<Scalar> > {
249  enum {
250  PacketAccess = packet_traits<Scalar>::HasErf,
251  Cost =
252  (PacketAccess
253 #ifdef EIGEN_VECTORIZE_FMA
254  // TODO(rmlarsen): Move the FMA cost model to a central location.
255  // Haswell can issue 2 add/mul/madd per cycle.
256  // 10 pmadd, 2 pmul, 1 div, 2 other
259  scalar_div_cost<Scalar, packet_traits<Scalar>::HasDiv>::value)
260 #else
263  scalar_div_cost<Scalar, packet_traits<Scalar>::HasDiv>::value)
264 #endif
265  // Assume for simplicity that this is as expensive as an exp().
266  : (functor_traits<scalar_exp_op<Scalar> >::Cost))
267  };
268 };
269 
275 template<typename Scalar> struct scalar_erfc_op {
276  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const {
277  using numext::erfc; return erfc(a);
278  }
279  typedef typename packet_traits<Scalar>::type Packet;
280  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a) const { return internal::perfc(a); }
281 };
282 template<typename Scalar>
283 struct functor_traits<scalar_erfc_op<Scalar> >
284 {
285  enum {
286  // Guesstimate
288  PacketAccess = packet_traits<Scalar>::HasErfc
289  };
290 };
291 
297 template<typename Scalar> struct scalar_ndtri_op {
298  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const {
299  using numext::ndtri; return ndtri(a);
300  }
301  typedef typename packet_traits<Scalar>::type Packet;
302  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a) const { return internal::pndtri(a); }
303 };
304 template<typename Scalar>
305 struct functor_traits<scalar_ndtri_op<Scalar> >
306 {
307  enum {
308  // On average, We are evaluating rational functions with degree N=9 in the
309  // numerator and denominator. This results in 2*N additions and 2*N
310  // multiplications.
312  PacketAccess = packet_traits<Scalar>::HasNdtri
313  };
314 };
315 
316 } // end namespace internal
317 
318 } // end namespace Eigen
319 
320 #endif // EIGEN_SPECIALFUNCTIONS_FUNCTORS_H
IndexedView_or_VectorBlock operator()(const Indices &indices)
#define EIGEN_DEVICE_FUNC
Packet pigamma_der_a(const Packet &a, const Packet &x)
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pdigamma(const Packet &a)
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pndtri(const Packet &a)
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet perf(const Packet &a)
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet ppolygamma(const Packet &n, const Packet &x)
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet perfc(const Packet &a)
Packet pigamma(const Packet &a, const Packet &x)
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plgamma(const Packet &a)
Packet pigammac(const Packet &a, const Packet &x)
Packet pgamma_sample_der_alpha(const Packet &alpha, const Packet &sample)
Packet pbetainc(const Packet &a, const Packet &b, const Packet &x)
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pzeta(const Packet &x, const Packet &q)
: TensorContractionSycl.h, provides various tensor contraction kernel for SYCL backend
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_erfc_op< typename Derived::Scalar >, const Derived > erfc(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseBinaryOp< Eigen::internal::scalar_igammac_op< typename Derived::Scalar >, const Derived, const ExponentDerived > igammac(const Eigen::ArrayBase< Derived > &a, const Eigen::ArrayBase< ExponentDerived > &x)
const TensorCwiseTernaryOp< internal::scalar_betainc_op< typename XDerived::Scalar >, const ADerived, const BDerived, const XDerived > betainc(const ADerived &a, const BDerived &b, const XDerived &x)
const Eigen::CwiseBinaryOp< Eigen::internal::scalar_igamma_op< typename Derived::Scalar >, const Derived, const ExponentDerived > igamma(const Eigen::ArrayBase< Derived > &a, const Eigen::ArrayBase< ExponentDerived > &x)
const Eigen::CwiseBinaryOp< Eigen::internal::scalar_polygamma_op< typename DerivedX::Scalar >, const DerivedN, const DerivedX > polygamma(const Eigen::ArrayBase< DerivedN > &n, const Eigen::ArrayBase< DerivedX > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_ndtri_op< typename Derived::Scalar >, const Derived > ndtri(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_lgamma_op< typename Derived::Scalar >, const Derived > lgamma(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseBinaryOp< Eigen::internal::scalar_igamma_der_a_op< typename Derived::Scalar >, const Derived, const ExponentDerived > igamma_der_a(const Eigen::ArrayBase< Derived > &a, const Eigen::ArrayBase< ExponentDerived > &x)
const Eigen::CwiseBinaryOp< Eigen::internal::scalar_zeta_op< typename DerivedX::Scalar >, const DerivedX, const DerivedQ > zeta(const Eigen::ArrayBase< DerivedX > &x, const Eigen::ArrayBase< DerivedQ > &q)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_digamma_op< typename Derived::Scalar >, const Derived > digamma(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseBinaryOp< Eigen::internal::scalar_gamma_sample_der_alpha_op< typename AlphaDerived::Scalar >, const AlphaDerived, const SampleDerived > gamma_sample_der_alpha(const Eigen::ArrayBase< AlphaDerived > &alpha, const Eigen::ArrayBase< SampleDerived > &sample)