Eigen::internal::zeta_impl< Scalar > Struct Template Reference

#include <SpecialFunctionsImpl.h>

Static Public Member Functions

static EIGEN_DEVICE_FUNC Scalar run (Scalar x, Scalar q)
 

Member Function Documentation

◆ run()

template<typename Scalar >
static EIGEN_DEVICE_FUNC Scalar Eigen::internal::zeta_impl< Scalar >::run ( Scalar  x,
Scalar  q 
)
inlinestatic
1365  {
1366  /* zeta.c
1367  *
1368  * Riemann zeta function of two arguments
1369  *
1370  *
1371  *
1372  * SYNOPSIS:
1373  *
1374  * double x, q, y, zeta();
1375  *
1376  * y = zeta( x, q );
1377  *
1378  *
1379  *
1380  * DESCRIPTION:
1381  *
1382  *
1383  *
1384  * inf.
1385  * - -x
1386  * zeta(x,q) = > (k+q)
1387  * -
1388  * k=0
1389  *
1390  * where x > 1 and q is not a negative integer or zero.
1391  * The Euler-Maclaurin summation formula is used to obtain
1392  * the expansion
1393  *
1394  * n
1395  * - -x
1396  * zeta(x,q) = > (k+q)
1397  * -
1398  * k=1
1399  *
1400  * 1-x inf. B x(x+1)...(x+2j)
1401  * (n+q) 1 - 2j
1402  * + --------- - ------- + > --------------------
1403  * x-1 x - x+2j+1
1404  * 2(n+q) j=1 (2j)! (n+q)
1405  *
1406  * where the B2j are Bernoulli numbers. Note that (see zetac.c)
1407  * zeta(x,1) = zetac(x) + 1.
1408  *
1409  *
1410  *
1411  * ACCURACY:
1412  *
1413  * Relative error for single precision:
1414  * arithmetic domain # trials peak rms
1415  * IEEE 0,25 10000 6.9e-7 1.0e-7
1416  *
1417  * Large arguments may produce underflow in powf(), in which
1418  * case the results are inaccurate.
1419  *
1420  * REFERENCE:
1421  *
1422  * Gradshteyn, I. S., and I. M. Ryzhik, Tables of Integrals,
1423  * Series, and Products, p. 1073; Academic Press, 1980.
1424  *
1425  */
1426 
1427  int i;
1428  Scalar p, r, a, b, k, s, t, w;
1429 
1430  const Scalar A[] = {
1431  Scalar(12.0),
1432  Scalar(-720.0),
1433  Scalar(30240.0),
1434  Scalar(-1209600.0),
1435  Scalar(47900160.0),
1436  Scalar(-1.8924375803183791606e9), /*1.307674368e12/691*/
1437  Scalar(7.47242496e10),
1438  Scalar(-2.950130727918164224e12), /*1.067062284288e16/3617*/
1439  Scalar(1.1646782814350067249e14), /*5.109094217170944e18/43867*/
1440  Scalar(-4.5979787224074726105e15), /*8.028576626982912e20/174611*/
1441  Scalar(1.8152105401943546773e17), /*1.5511210043330985984e23/854513*/
1442  Scalar(-7.1661652561756670113e18) /*1.6938241367317436694528e27/236364091*/
1443  };
1444 
1445  const Scalar maxnum = NumTraits<Scalar>::infinity();
1446  const Scalar zero = Scalar(0.0), half = Scalar(0.5), one = Scalar(1.0);
1447  const Scalar machep = cephes_helper<Scalar>::machep();
1448  const Scalar nan = NumTraits<Scalar>::quiet_NaN();
1449 
1450  if (x == one) return maxnum;
1451 
1452  if (x < one) {
1453  return nan;
1454  }
1455 
1456  if (q <= zero) {
1457  if (q == numext::floor(q)) {
1458  if (x == numext::floor(x) && long(x) % 2 == 0) {
1459  return maxnum;
1460  } else {
1461  return nan;
1462  }
1463  }
1464  p = x;
1465  r = numext::floor(p);
1466  if (p != r) return nan;
1467  }
1468 
1469  /* Permit negative q but continue sum until n+q > +9 .
1470  * This case should be handled by a reflection formula.
1471  * If q<0 and x is an integer, there is a relation to
1472  * the polygamma function.
1473  */
1474  s = numext::pow(q, -x);
1475  a = q;
1476  b = zero;
1477  // Run the summation in a helper function that is specific to the floating precision
1478  if (zeta_impl_series<Scalar>::run(a, b, s, x, machep)) {
1479  return s;
1480  }
1481 
1482  // If b is zero, then the tail sum will also end up being zero.
1483  // Exiting early here can prevent NaNs for some large inputs, where
1484  // the tail sum computed below has term `a` which can overflow to `inf`.
1485  if (numext::equal_strict(b, zero)) {
1486  return s;
1487  }
1488 
1489  w = a;
1490  s += b * w / (x - one);
1491  s -= half * b;
1492  a = one;
1493  k = zero;
1494 
1495  for (i = 0; i < 12; i++) {
1496  a *= x + k;
1497  b /= w;
1498  t = a * b / A[i];
1499  s = s + t;
1500  t = numext::abs(t / s);
1501  if (t < machep) {
1502  break;
1503  }
1504  k += one;
1505  a *= x + k;
1506  b /= w;
1507  k += one;
1508  }
1509  return s;
1510  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
RowVector3d w
Definition: Matrix_resize_int.cpp:3
float * p
Definition: Tutorial_Map_using.cpp:9
SCALAR Scalar
Definition: bench_gemm.cpp:45
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:47
RealScalar s
Definition: level1_cplx_impl.h:130
const Scalar * a
Definition: level2_cplx_impl.h:32
char char char int int * k
Definition: level2_impl.h:374
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const X &x, const Y &y)
Definition: Meta.h:571
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::enable_if_t< NumTraits< T >::IsSigned||NumTraits< T >::IsComplex, typename NumTraits< T >::Real > abs(const T &x)
Definition: MathFunctions.h:1355
EIGEN_DEVICE_FUNC const Scalar & q
Definition: SpecialFunctionsImpl.h:2019
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar() floor(const Scalar &x)
Definition: MathFunctions.h:1200
EIGEN_DEVICE_FUNC internal::pow_impl< ScalarX, ScalarY >::result_type pow(const ScalarX &x, const ScalarY &y)
Definition: MathFunctions.h:1161
EIGEN_DEVICE_FUNC const Scalar & x
Definition: SpecialFunctionsImpl.h:2024
EIGEN_DEVICE_FUNC const Scalar & b
Definition: SpecialFunctionsImpl.h:2066
r
Definition: UniformPSDSelfTest.py:20
t
Definition: plotPSD.py:36
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar machep()
Definition: SpecialFunctionsImpl.h:765
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run(const Scalar)
Definition: SpecialFunctionsImpl.h:1324
EIGEN_DONT_INLINE Scalar zero()
Definition: svd_common.h:232

References a, Eigen::numext::abs(), Eigen::numext::b, Eigen::numext::equal_strict(), Eigen::numext::floor(), i, k, Eigen::internal::cephes_helper< Scalar >::machep(), p, Eigen::numext::pow(), Eigen::numext::q, UniformPSDSelfTest::r, s, plotPSD::t, w, Eigen::numext::x, and zero().


The documentation for this struct was generated from the following file: