jiangchengfeiyi-xiaochengxu/node_modules/mathjs/lib/cjs/function/special/zeta.js
2025-01-02 11:13:50 +08:00

154 lines
4.8 KiB
JavaScript

"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);
}
});