10 #ifndef EIGEN_SPECIAL_FUNCTIONS_H 11 #define EIGEN_SPECIAL_FUNCTIONS_H 80 template <
typename Scalar,
int N>
83 static EIGEN_STRONG_INLINE Scalar run(
const Scalar x,
const Scalar coef[]) {
84 EIGEN_STATIC_ASSERT((N > 0), YOU_MADE_A_PROGRAMMING_MISTAKE);
90 template <
typename Scalar>
93 static EIGEN_STRONG_INLINE Scalar run(
const Scalar,
const Scalar coef[]) {
104 template <
typename Scalar>
107 static EIGEN_STRONG_INLINE Scalar run(
const Scalar) {
109 THIS_TYPE_IS_NOT_SUPPORTED);
114 template <
typename Scalar>
119 #if EIGEN_HAS_C99_MATH 123 static EIGEN_STRONG_INLINE
float run(
float x) {
124 #if !defined(__CUDA_ARCH__) && (defined(_BSD_SOURCE) || defined(_SVID_SOURCE)) && !defined(__APPLE__) 126 return ::lgammaf_r(x, &signgam);
136 static EIGEN_STRONG_INLINE
double run(
double x) {
137 #if !defined(__CUDA_ARCH__) && (defined(_BSD_SOURCE) || defined(_SVID_SOURCE)) && !defined(__APPLE__) 139 return ::lgamma_r(x, &signgam);
151 template <
typename Scalar>
169 template <
typename Scalar>
172 static EIGEN_STRONG_INLINE Scalar run(
const Scalar) {
174 THIS_TYPE_IS_NOT_SUPPORTED);
183 static EIGEN_STRONG_INLINE
float run(
const float s) {
185 -4.16666666666666666667E-3f,
186 3.96825396825396825397E-3f,
187 -8.33333333333333333333E-3f,
188 8.33333333333333333333E-2f
202 static EIGEN_STRONG_INLINE
double run(
const double s) {
204 8.33333333333333333333E-2,
205 -2.10927960927960927961E-2,
206 7.57575757575757575758E-3,
207 -4.16666666666666666667E-3,
208 3.96825396825396825397E-3,
209 -8.33333333333333333333E-3,
210 8.33333333333333333333E-2
222 template <
typename Scalar>
225 static Scalar run(Scalar x) {
283 Scalar p, q, nz, s, w, y;
284 bool negative =
false;
287 const Scalar m_pi = Scalar(EIGEN_PI);
289 const Scalar zero = Scalar(0);
290 const Scalar one = Scalar(1);
291 const Scalar
half = Scalar(0.5);
297 p = numext::floor(q);
310 nz = m_pi / numext::tan(m_pi * nz);
321 while (s < Scalar(10)) {
328 y = numext::log(s) - (half / s) - y - w;
330 return (negative) ? y - nz : y;
338 template <
typename Scalar>
341 static EIGEN_STRONG_INLINE Scalar run(
const Scalar) {
343 THIS_TYPE_IS_NOT_SUPPORTED);
348 template <
typename Scalar>
353 #if EIGEN_HAS_C99_MATH 357 static EIGEN_STRONG_INLINE
float run(
float x) { return ::erff(x); }
363 static EIGEN_STRONG_INLINE
double run(
double x) { return ::erf(x); }
365 #endif // EIGEN_HAS_C99_MATH 371 template <
typename Scalar>
374 static EIGEN_STRONG_INLINE Scalar run(
const Scalar) {
376 THIS_TYPE_IS_NOT_SUPPORTED);
381 template <
typename Scalar>
386 #if EIGEN_HAS_C99_MATH 390 static EIGEN_STRONG_INLINE
float run(
const float x) { return ::erfcf(x); }
396 static EIGEN_STRONG_INLINE
double run(
const double x) { return ::erfc(x); }
398 #endif // EIGEN_HAS_C99_MATH 404 template <
typename Scalar>
410 template <
typename Scalar>
413 static EIGEN_STRONG_INLINE Scalar machep() { assert(
false &&
"machep not supported for this type");
return 0.0; }
415 static EIGEN_STRONG_INLINE Scalar big() { assert(
false &&
"big not supported for this type");
return 0.0; }
417 static EIGEN_STRONG_INLINE Scalar biginv() { assert(
false &&
"biginv not supported for this type");
return 0.0; }
423 static EIGEN_STRONG_INLINE
float machep() {
427 static EIGEN_STRONG_INLINE
float big() {
432 static EIGEN_STRONG_INLINE
float biginv() {
441 static EIGEN_STRONG_INLINE
double machep() {
445 static EIGEN_STRONG_INLINE
double big() {
449 static EIGEN_STRONG_INLINE
double biginv() {
455 #if !EIGEN_HAS_C99_MATH 457 template <
typename Scalar>
460 static Scalar run(Scalar a, Scalar x) {
462 THIS_TYPE_IS_NOT_SUPPORTED);
471 template <
typename Scalar>
474 static Scalar run(Scalar a, Scalar x) {
529 const Scalar zero = 0;
530 const Scalar one = 1;
533 if ((x < zero) || (a <= zero)) {
538 if ((x < one) || (x < a)) {
563 EIGEN_DEVICE_FUNC
static Scalar Impl(Scalar a, Scalar x) {
564 const Scalar zero = 0;
565 const Scalar one = 1;
566 const Scalar two = 2;
573 Scalar ans, ax, c, yc, r, t, y, z;
574 Scalar pk, pkm1, pkm2, qk, qkm1, qkm2;
576 if (x == inf)
return zero;
583 ax = numext::exp(ax);
600 pk = pkm1 * z - pkm2 * yc;
601 qk = qkm1 * z - qkm2 * yc;
604 t = numext::abs((ans - r) / r);
613 if (numext::abs(pk) > big) {
628 #endif // EIGEN_HAS_C99_MATH 634 template <
typename Scalar>
639 #if !EIGEN_HAS_C99_MATH 641 template <
typename Scalar>
644 static EIGEN_STRONG_INLINE Scalar run(Scalar a, Scalar x) {
646 THIS_TYPE_IS_NOT_SUPPORTED);
653 template <
typename Scalar>
656 static Scalar run(Scalar a, Scalar x) {
717 const Scalar zero = 0;
718 const Scalar one = 1;
721 if (x == zero)
return zero;
723 if ((x < zero) || (a <= zero)) {
727 if ((x > one) && (x > a)) {
752 EIGEN_DEVICE_FUNC
static Scalar Impl(Scalar a, Scalar x) {
753 const Scalar zero = 0;
754 const Scalar one = 1;
758 Scalar ans, ax, c, r;
766 ax = numext::exp(ax);
777 if (c/ans <= machep) {
782 return (ans * ax / a);
786 #endif // EIGEN_HAS_C99_MATH 792 template <
typename Scalar>
797 template <
typename Scalar>
800 static EIGEN_STRONG_INLINE Scalar run(
const Scalar) {
802 THIS_TYPE_IS_NOT_SUPPORTED);
810 static EIGEN_STRONG_INLINE
bool run(
float& a,
float& b,
float& s,
const float x,
const float machep) {
816 b = numext::pow( a, -x );
818 if( numext::abs(b/s) < machep )
830 static EIGEN_STRONG_INLINE
bool run(
double& a,
double& b,
double& s,
const double x,
const double machep) {
832 while( (i < 9) || (a <= 9.0) )
836 b = numext::pow( a, -x );
838 if( numext::abs(b/s) < machep )
847 template <
typename Scalar>
850 static Scalar run(Scalar x, Scalar q) {
913 Scalar p, r, a, b, k, s, t, w;
921 Scalar(-1.8924375803183791606e9),
922 Scalar(7.47242496e10),
923 Scalar(-2.950130727918164224e12),
924 Scalar(1.1646782814350067249e14),
925 Scalar(-4.5979787224074726105e15),
926 Scalar(1.8152105401943546773e17),
927 Scalar(-7.1661652561756670113e18)
931 const Scalar zero = 0.0,
half = 0.5, one = 1.0;
945 if(q == numext::floor(q))
950 r = numext::floor(p);
960 s = numext::pow( q, -x );
973 for( i=0; i<12; i++ )
979 t = numext::abs(t/s);
996 template <
typename Scalar>
1001 #if !EIGEN_HAS_C99_MATH 1003 template <
typename Scalar>
1006 static EIGEN_STRONG_INLINE Scalar run(Scalar n, Scalar x) {
1008 THIS_TYPE_IS_NOT_SUPPORTED);
1015 template <
typename Scalar>
1018 static Scalar run(Scalar n, Scalar x) {
1019 Scalar zero = 0.0, one = 1.0;
1020 Scalar nplus = n + one;
1024 if (numext::floor(n) != n) {
1028 else if (n == zero) {
1039 #endif // EIGEN_HAS_C99_MATH 1045 template <
typename Scalar>
1047 typedef Scalar type;
1050 #if !EIGEN_HAS_C99_MATH 1052 template <
typename Scalar>
1055 static EIGEN_STRONG_INLINE Scalar run(Scalar a, Scalar b, Scalar x) {
1057 THIS_TYPE_IS_NOT_SUPPORTED);
1064 template <
typename Scalar>
1067 static EIGEN_STRONG_INLINE Scalar run(Scalar, Scalar, Scalar) {
1138 THIS_TYPE_IS_NOT_SUPPORTED);
1146 template <
typename Scalar>
1147 struct incbeta_cfe {
1149 static EIGEN_STRONG_INLINE Scalar run(Scalar a, Scalar b, Scalar x,
bool small_branch) {
1152 THIS_TYPE_IS_NOT_SUPPORTED);
1157 const Scalar zero = 0;
1158 const Scalar one = 1;
1159 const Scalar two = 2;
1161 Scalar xk, pk, pkm1, pkm2, qk, qkm1, qkm2;
1162 Scalar k1, k2, k3, k4, k5, k6, k7, k8, k26update;
1167 const Scalar thresh =
1202 xk = -(x * k1 * k2) / (k3 * k4);
1203 pk = pkm1 + pkm2 * xk;
1204 qk = qkm1 + qkm2 * xk;
1210 xk = (x * k5 * k6) / (k7 * k8);
1211 pk = pkm1 + pkm2 * xk;
1212 qk = qkm1 + qkm2 * xk;
1220 if (numext::abs(ans - r) < numext::abs(r) * thresh) {
1235 if ((numext::abs(qk) + numext::abs(pk)) > big) {
1241 if ((numext::abs(qk) < biginv) || (numext::abs(pk) < biginv)) {
1247 }
while (++n < num_iters);
1254 template <
typename Scalar>
1255 struct betainc_helper {};
1258 struct betainc_helper<float> {
1260 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE
float incbsa(
float aa,
float bb,
1262 float ans, a, b, t, x, onemx;
1263 bool reversed_a_b =
false;
1268 if (xx > (aa / (aa + bb))) {
1269 reversed_a_b =
true;
1283 if (numext::abs(b * x / a) < 0.3f) {
1284 t = betainc_helper<float>::incbps(a, b, x);
1285 if (reversed_a_b) t = 1.0f - t;
1290 ans = x * (a + b - 2.0f) / (a - 1.0f);
1292 ans = incbeta_cfe<float>::run(a, b, x,
true );
1293 t = b * numext::log(t);
1295 ans = incbeta_cfe<float>::run(a, b, x,
false );
1296 t = (b - 1.0f) * numext::log(t);
1301 t += numext::log(ans / a);
1304 if (reversed_a_b) t = 1.0f - t;
1309 static EIGEN_STRONG_INLINE
float incbps(
float a,
float b,
float x) {
1313 y = a * numext::log(x) + (b - 1.0f) * numext::log1p(-x) - numext::log(a);
1328 }
while (numext::abs(u) > machep);
1330 return numext::exp(y) * (1.0f + s);
1337 static float run(
float a,
float b,
float x) {
1341 if (a <= 0.0f)
return nan;
1342 if (b <= 0.0f)
return nan;
1343 if ((x <= 0.0f) || (x >= 1.0f)) {
1344 if (x == 0.0f)
return 0.0f;
1345 if (x == 1.0f)
return 1.0f;
1352 ans = betainc_helper<float>::incbsa(a + 1.0f, b, x);
1353 t = a * numext::log(x) + b * numext::log1p(-x) +
1356 return (ans + numext::exp(t));
1358 return betainc_helper<float>::incbsa(a, b, x);
1364 struct betainc_helper<double> {
1366 static EIGEN_STRONG_INLINE
double incbps(
double a,
double b,
double x) {
1369 double s, t, u, v, n, t1, z, ai;
1379 while (numext::abs(v) > z) {
1380 u = (n - b) * x / n;
1389 u = a * numext::log(x);
1399 return s = numext::exp(t);
1406 static double run(
double aa,
double bb,
double xx) {
1411 double a, b, t, x, xc, w, y;
1412 bool reversed_a_b =
false;
1414 if (aa <= 0.0 || bb <= 0.0) {
1418 if ((xx <= 0.0) || (xx >= 1.0)) {
1419 if (xx == 0.0)
return (0.0);
1420 if (xx == 1.0)
return (1.0);
1425 if ((bb * xx) <= 1.0 && xx <= 0.95) {
1426 return betainc_helper<double>::incbps(aa, bb, xx);
1432 if (xx > (aa / (aa + bb))) {
1433 reversed_a_b =
true;
1445 if (reversed_a_b && (b * x) <= 1.0 && x <= 0.95) {
1446 t = betainc_helper<double>::incbps(a, b, x);
1456 y = x * (a + b - 2.0) - (a - 1.0);
1458 w = incbeta_cfe<double>::run(a, b, x,
true );
1460 w = incbeta_cfe<double>::run(a, b, x,
false ) / xc;
1467 y = a * numext::log(x);
1468 t = b * numext::log(xc);
1483 y += numext::log(w / a);
1500 #endif // EIGEN_HAS_C99_MATH 1506 template <
typename Scalar>
1507 EIGEN_DEVICE_FUNC
inline EIGEN_MATHFUNC_RETVAL(lgamma, Scalar)
1508 lgamma(
const Scalar& x) {
1509 return EIGEN_MATHFUNC_IMPL(lgamma, Scalar)::run(x);
1512 template <
typename Scalar>
1513 EIGEN_DEVICE_FUNC
inline EIGEN_MATHFUNC_RETVAL(digamma, Scalar)
1514 digamma(
const Scalar& x) {
1515 return EIGEN_MATHFUNC_IMPL(digamma, Scalar)::run(x);
1518 template <
typename Scalar>
1519 EIGEN_DEVICE_FUNC
inline EIGEN_MATHFUNC_RETVAL(
zeta, Scalar)
1520 zeta(
const Scalar& x,
const Scalar& q) {
1521 return EIGEN_MATHFUNC_IMPL(
zeta, Scalar)::run(x, q);
1524 template <
typename Scalar>
1525 EIGEN_DEVICE_FUNC
inline EIGEN_MATHFUNC_RETVAL(
polygamma, Scalar)
1526 polygamma(
const Scalar& n,
const Scalar& x) {
1527 return EIGEN_MATHFUNC_IMPL(
polygamma, Scalar)::run(n, x);
1530 template <
typename Scalar>
1531 EIGEN_DEVICE_FUNC
inline EIGEN_MATHFUNC_RETVAL(erf, Scalar)
1532 erf(
const Scalar& x) {
1533 return EIGEN_MATHFUNC_IMPL(erf, Scalar)::run(x);
1536 template <
typename Scalar>
1537 EIGEN_DEVICE_FUNC
inline EIGEN_MATHFUNC_RETVAL(erfc, Scalar)
1538 erfc(
const Scalar& x) {
1539 return EIGEN_MATHFUNC_IMPL(erfc, Scalar)::run(x);
1542 template <
typename Scalar>
1543 EIGEN_DEVICE_FUNC
inline EIGEN_MATHFUNC_RETVAL(
igamma, Scalar)
1544 igamma(
const Scalar& a,
const Scalar& x) {
1545 return EIGEN_MATHFUNC_IMPL(
igamma, Scalar)::run(a, x);
1548 template <
typename Scalar>
1549 EIGEN_DEVICE_FUNC
inline EIGEN_MATHFUNC_RETVAL(
igammac, Scalar)
1550 igammac(
const Scalar& a,
const Scalar& x) {
1551 return EIGEN_MATHFUNC_IMPL(
igammac, Scalar)::run(a, x);
1554 template <
typename Scalar>
1555 EIGEN_DEVICE_FUNC
inline EIGEN_MATHFUNC_RETVAL(
betainc, Scalar)
1556 betainc(
const Scalar& a,
const Scalar& b,
const Scalar& x) {
1557 return EIGEN_MATHFUNC_IMPL(
betainc, Scalar)::run(a, b, x);
1565 #endif // EIGEN_SPECIAL_FUNCTIONS_H Definition: SpecialFunctionsImpl.h:115
Definition: SpecialFunctionsImpl.h:997
Definition: SpecialFunctionsImpl.h:1046
Definition: SpecialFunctionsImpl.h:642
Definition: SpecialFunctionsImpl.h:382
Definition: SpecialFunctionsImpl.h:105
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:85
Holds information about the various numeric (i.e.
Definition: NumTraits.h:150
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)
Definition: SpecialFunctionsArrayAPI.h:48
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)
Definition: SpecialFunctionsArrayAPI.h:28
Definition: SpecialFunctionsImpl.h:1004
Definition: SpecialFunctionsImpl.h:372
Definition: SpecialFunctionsImpl.h:635
Definition: SpecialFunctionsImpl.h:349
Definition: SpecialFunctionsImpl.h:411
Definition: SpecialFunctionsImpl.h:1053
Definition: SpecialFunctionsImpl.h:223
Definition: SpecialFunctionsImpl.h:405
Definition: SpecialFunctionsImpl.h:152
Definition: BandTriangularSolver.h:13
Definition: SpecialFunctionsImpl.h:170
Definition: SpecialFunctionsImpl.h:339
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)
Definition: SpecialFunctionsArrayAPI.h:114
Definition: SpecialFunctionsImpl.h:458
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)
Definition: SpecialFunctionsArrayAPI.h:70
Definition: SpecialFunctionsImpl.h:81
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:178
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 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)
Definition: TensorGlobalFunctions.h:24
Definition: SpecialFunctionsImpl.h:848
Definition: SpecialFunctionsImpl.h:798
Definition: SpecialFunctionsImpl.h:793