MCPcopy Create free account
hub / github.com/cortex-js/compute-engine / trigammaCore

Function trigammaCore

src/compute-engine/numerics/special-functions.ts:891–941  ·  view source on GitHub ↗
(ce: ComputeEngine, z: BigNum)

Source from the content-addressed store, hash-verified

889 const tol = new BigDecimal(10).pow(-(p + guard));
890 const nTerms = Math.min(maxTerms, bernoulli.length);
891 for (let k = 0; k < nTerms; k++) {
892 const [bNum, bDen] = bernoulli[k];
893 const twoK = BigInt(2 * (k + 1));
894 const term = new BigDecimal(bNum.toString()).div(
895 new BigDecimal((bDen * twoK).toString()).mul(w2k)
896 );
897 if (k > 0 && term.abs().lt(tol)) break;
898 result = result.sub(term);
899 w2k = w2k._mulToPrecision(w2, p);
900 }
901
902 return result;
903}
904
905/**
906 * Bignum Trigamma function ψ₁(z) = d/dz ψ(z) = d²/dz² ln(Γ(z))
907 * Same recurrence/asymptotic structure as digamma but for the second derivative.
908 */
909export function bigTrigamma(ce: ComputeEngine, z: BigNum): BigNum {
910 if (!z.isFinite()) return BigDecimal.NAN;
911 return withGuardDigits(SPECIAL_FN_GUARD, () => trigammaCore(ce, z));
912}
913
914function trigammaCore(ce: ComputeEngine, z: BigNum): BigNum {
915 // Reflection formula: ψ₁(1-z) + ψ₁(z) = π²/sin²(πz)
916 if (z.isNegative()) {
917 if (z.isInteger()) return BigDecimal.NAN;
918 const pi = BigDecimal.PI;
919 const s = pi.mul(z).sin();
920 return pi
921 .mul(pi)
922 .div(s.mul(s))
923 .sub(trigammaCore(ce, BigDecimal.ONE.sub(z)));
924 }
925
926 if (z.isZero()) return BigDecimal.NAN; // pole
927
928 const p = BigDecimal.precision;
929 const guard = 10;
930 // Shift to w ≈ p so the asymptotic series converges in ≈0.4·p terms rather
931 // than running its full ≈π·w (see `gammalnCore`).
932 const shift = Math.max(7, Math.ceil(p));
933
934 // Recurrence: ψ₁(z+1) = ψ₁(z) - 1/z²
935 let result = new BigDecimal(0);
936 let w = z;
937 while (w.lt(shift)) {
938 result = result.add(BigDecimal.ONE.div(w.mul(w)));
939 w = w.add(BigDecimal.ONE);
940 }
941
942 const maxTerms = Math.max(20, Math.ceil(0.6 * p) + 20);
943 const bernoulli = getBernoulliRationals(ce, maxTerms);
944

Callers 1

bigTrigammaFunction · 0.85

Calls 15

addMethod · 0.95
getBernoulliRationalsFunction · 0.85
sinMethod · 0.80
mulToPrecisionMethod · 0.80
mulMethod · 0.65
subMethod · 0.65
divMethod · 0.65
isZeroMethod · 0.65
addMethod · 0.65
powMethod · 0.65
toStringMethod · 0.65
absMethod · 0.65

Tested by

no test coverage detected