Eigen::internal::igammac_cf_impl< Scalar, mode > Struct Template Reference

#include <SpecialFunctionsImpl.h>

Static Public Member Functions

static EIGEN_DEVICE_FUNC Scalar run (Scalar a, Scalar x)
 

Member Function Documentation

◆ run()

template<typename Scalar , IgammaComputationMode mode>
static EIGEN_DEVICE_FUNC Scalar Eigen::internal::igammac_cf_impl< Scalar, mode >::run ( Scalar  a,
Scalar  x 
)
inlinestatic
848  {
849  const Scalar zero = 0;
850  const Scalar one = 1;
851  const Scalar two = 2;
852  const Scalar machep = cephes_helper<Scalar>::machep();
853  const Scalar big = cephes_helper<Scalar>::big();
854  const Scalar biginv = cephes_helper<Scalar>::biginv();
855 
856  if ((numext::isinf)(x)) {
857  return zero;
858  }
859 
860  Scalar ax = main_igamma_term<Scalar>(a, x);
861  // This is independent of mode. If this value is zero,
862  // then the function value is zero. If the function value is zero,
863  // then we are in a neighborhood where the function value evaluates to zero,
864  // so the derivative is zero.
865  if (ax == zero) {
866  return zero;
867  }
868 
869  // continued fraction
870  Scalar y = one - a;
871  Scalar z = x + y + one;
872  Scalar c = zero;
873  Scalar pkm2 = one;
874  Scalar qkm2 = x;
875  Scalar pkm1 = x + one;
876  Scalar qkm1 = z * x;
877  Scalar ans = pkm1 / qkm1;
878 
879  Scalar dpkm2_da = zero;
880  Scalar dqkm2_da = zero;
881  Scalar dpkm1_da = zero;
882  Scalar dqkm1_da = -x;
883  Scalar dans_da = (dpkm1_da - ans * dqkm1_da) / qkm1;
884 
885  for (int i = 0; i < igamma_num_iterations<Scalar, mode>(); i++) {
886  c += one;
887  y += one;
888  z += two;
889 
890  Scalar yc = y * c;
891  Scalar pk = pkm1 * z - pkm2 * yc;
892  Scalar qk = qkm1 * z - qkm2 * yc;
893 
894  Scalar dpk_da = dpkm1_da * z - pkm1 - dpkm2_da * yc + pkm2 * c;
895  Scalar dqk_da = dqkm1_da * z - qkm1 - dqkm2_da * yc + qkm2 * c;
896 
897  if (qk != zero) {
898  Scalar ans_prev = ans;
899  ans = pk / qk;
900 
901  Scalar dans_da_prev = dans_da;
902  dans_da = (dpk_da - ans * dqk_da) / qk;
903 
904  if (mode == VALUE) {
905  if (numext::abs(ans_prev - ans) <= machep * numext::abs(ans)) {
906  break;
907  }
908  } else {
909  if (numext::abs(dans_da - dans_da_prev) <= machep) {
910  break;
911  }
912  }
913  }
914 
915  pkm2 = pkm1;
916  pkm1 = pk;
917  qkm2 = qkm1;
918  qkm1 = qk;
919 
920  dpkm2_da = dpkm1_da;
921  dpkm1_da = dpk_da;
922  dqkm2_da = dqkm1_da;
923  dqkm1_da = dqk_da;
924 
925  if (numext::abs(pk) > big) {
926  pkm2 *= biginv;
927  pkm1 *= biginv;
928  qkm2 *= biginv;
929  qkm1 *= biginv;
930 
931  dpkm2_da *= biginv;
932  dpkm1_da *= biginv;
933  dqkm2_da *= biginv;
934  dqkm1_da *= biginv;
935  }
936  }
937 
938  /* Compute x**a * exp(-x) / gamma(a) */
940  Scalar dax_da = ax * dlogax_da;
941 
942  switch (mode) {
943  case VALUE:
944  return ans * ax;
945  case DERIVATIVE:
946  return ans * dax_da + dans_da * ax;
947  case SAMPLE_DERIVATIVE:
948  default: // this is needed to suppress clang warning
949  return -(dans_da + ans * dlogax_da) * x;
950  }
951  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
SCALAR Scalar
Definition: bench_gemm.cpp:45
const Scalar * a
Definition: level2_cplx_impl.h:32
const Scalar & y
Definition: RandomImpl.h:36
@ SAMPLE_DERIVATIVE
Definition: SpecialFunctionsImpl.h:806
@ VALUE
Definition: SpecialFunctionsImpl.h:806
@ DERIVATIVE
Definition: SpecialFunctionsImpl.h:806
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T log(const T &x)
Definition: MathFunctions.h:1332
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool() isinf(const Eigen::bfloat16 &h)
Definition: BFloat16.h:747
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 & x
Definition: SpecialFunctionsImpl.h:2024
int c
Definition: calibrate.py:100
ax
Definition: plotDoE.py:39
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar big()
Definition: SpecialFunctionsImpl.h:769
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar biginv()
Definition: SpecialFunctionsImpl.h:773
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar machep()
Definition: SpecialFunctionsImpl.h:765
static EIGEN_DEVICE_FUNC Scalar run(Scalar x)
Definition: SpecialFunctionsImpl.h:164
EIGEN_DONT_INLINE Scalar zero()
Definition: svd_common.h:232

References a, Eigen::numext::abs(), plotDoE::ax, Eigen::internal::cephes_helper< Scalar >::big(), Eigen::internal::cephes_helper< Scalar >::biginv(), calibrate::c, Eigen::internal::DERIVATIVE, i, Eigen::numext::isinf(), Eigen::numext::log(), Eigen::internal::cephes_helper< Scalar >::machep(), Eigen::internal::digamma_impl< Scalar >::run(), Eigen::internal::SAMPLE_DERIVATIVE, Eigen::internal::VALUE, Eigen::numext::x, Eigen::internal::y, and zero().


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