"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createZeta = void 0; var _factory = require("../../utils/factory.js"); const name = 'zeta'; const dependencies = ['typed', 'config', 'multiply', 'pow', 'divide', 'factorial', 'equal', 'smallerEq', 'isNegative', 'gamma', 'sin', 'subtract', 'add', '?Complex', '?BigNumber', 'pi']; const createZeta = exports.createZeta = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => { let { typed, config, multiply, pow, divide, factorial, equal, smallerEq, isNegative, gamma, sin, subtract, add, Complex, BigNumber, pi } = _ref; /** * Compute the Riemann Zeta function of a value using an infinite series for * all of the complex plane using Riemann's Functional equation. * * Based off the paper by Xavier Gourdon and Pascal Sebah * ( http://numbers.computation.free.fr/Constants/Miscellaneous/zetaevaluations.pdf ) * * Implementation and slight modification by Anik Patel * * Note: the implementation is accurate up to about 6 digits. * * Syntax: * * math.zeta(n) * * Examples: * * math.zeta(5) // returns 1.0369277551433895 * math.zeta(-0.5) // returns -0.2078862249773449 * math.zeta(math.i) // returns 0.0033002236853253153 - 0.4181554491413212i * * See also: * erf * * @param {number | Complex | BigNumber} s A Real, Complex or BigNumber parameter to the Riemann Zeta Function * @return {number | Complex | BigNumber} The Riemann Zeta of `s` */ return typed(name, { number: s => zetaNumeric(s, value => value, () => 20), BigNumber: s => zetaNumeric(s, value => new BigNumber(value), () => { // relTol is for example 1e-12. Extract the positive exponent 12 from that return Math.abs(Math.log10(config.relTol)); }), Complex: zetaComplex }); /** * @param {number | BigNumber} s * @param {(value: number) => number | BigNumber} createValue * @param {(value: number | BigNumber | Complex) => number} determineDigits * @returns {number | BigNumber} */ function zetaNumeric(s, createValue, determineDigits) { if (equal(s, 0)) { return createValue(-0.5); } if (equal(s, 1)) { return createValue(NaN); } if (!isFinite(s)) { return isNegative(s) ? createValue(NaN) : createValue(1); } return zeta(s, createValue, determineDigits, s => s); } /** * @param {Complex} s * @returns {Complex} */ function zetaComplex(s) { if (s.re === 0 && s.im === 0) { return new Complex(-0.5); } if (s.re === 1) { return new Complex(NaN, NaN); } if (s.re === Infinity && s.im === 0) { return new Complex(1); } if (s.im === Infinity || s.re === -Infinity) { return new Complex(NaN, NaN); } return zeta(s, value => value, s => Math.round(1.3 * 15 + 0.9 * Math.abs(s.im)), s => s.re); } /** * @param {number | BigNumber | Complex} s * @param {(value: number) => number | BigNumber | Complex} createValue * @param {(value: number | BigNumber | Complex) => number} determineDigits * @param {(value: number | BigNumber | Complex) => number} getRe * @returns {*|number} */ function zeta(s, createValue, determineDigits, getRe) { const n = determineDigits(s); if (getRe(s) > -(n - 1) / 2) { return f(s, createValue(n), createValue); } else { // Function Equation for reflection to x < 1 let c = multiply(pow(2, s), pow(createValue(pi), subtract(s, 1))); c = multiply(c, sin(multiply(divide(createValue(pi), 2), s))); c = multiply(c, gamma(subtract(1, s))); return multiply(c, zeta(subtract(1, s), createValue, determineDigits, getRe)); } } /** * Calculate a portion of the sum * @param {number | BigNumber} k a positive integer * @param {number | BigNumber} n a positive integer * @return {number} the portion of the sum **/ function d(k, n) { let S = k; for (let j = k; smallerEq(j, n); j = add(j, 1)) { const factor = divide(multiply(factorial(add(n, subtract(j, 1))), pow(4, j)), multiply(factorial(subtract(n, j)), factorial(multiply(2, j)))); S = add(S, factor); } return multiply(n, S); } /** * Calculate the positive Riemann Zeta function * @param {number} s a real or complex number with s.re > 1 * @param {number} n a positive integer * @param {(number) => number | BigNumber | Complex} createValue * @return {number} Riemann Zeta of s **/ function f(s, n, createValue) { const c = divide(1, multiply(d(createValue(0), n), subtract(1, pow(2, subtract(1, s))))); let S = createValue(0); for (let k = createValue(1); smallerEq(k, n); k = add(k, 1)) { S = add(S, divide(multiply((-1) ** (k - 1), d(k, n)), pow(k, s))); } return multiply(c, S); } });