(
f: (x: number) => number,
x0: number,
options: ExtrapolateOptions = {}
)
| 91 | |
| 92 | */ |
| 93 | export function extrapolate( |
| 94 | f: (x: number) => number, |
| 95 | x0: number, |
| 96 | options: ExtrapolateOptions = {} |
| 97 | ): [val: number, err: number] { |
| 98 | const { |
| 99 | contract = 0.125, |
| 100 | step = 1, |
| 101 | // An ordinary Taylor/asymptotic series in h (see the doc comment above — |
| 102 | // `power=2` is an opt-in acceleration for even functions). The default |
| 103 | // was transcribed as 2, contradicting the docstring and Richardson.jl: |
| 104 | // on series with odd powers (e.g. Hₙ − ln n − γ ~ 1/(2n)) the h¹ term was |
| 105 | // never eliminated, the error estimate stalled above `limit()`'s 1e-6 |
| 106 | // acceptance threshold, and convergent limits were reported as NaN. |
| 107 | power = 1, |
| 108 | atol = 1e-16, |
| 109 | rtol = atol > 0 ? 0 : Math.sqrt(Number.EPSILON), |
| 110 | maxeval = 1e6, // Number.MAX_SAFE_INTEGER |
| 111 | breaktol = 2, |
| 112 | // A call reached through compiled code (`_SYS.limit`) has no deadline |
| 113 | // of its own: inherit the ambient one (see interruptible.ts) |
| 114 | deadline = getAmbientDeadline(), |
| 115 | } = options; |
| 116 | |
| 117 | if (!isFinite(x0)) { |
| 118 | // use a change of variables x = 1/u |
| 119 | return extrapolate((u) => f(1 / u), 1 / x0, { |
| 120 | rtol, |
| 121 | atol, |
| 122 | maxeval, |
| 123 | contract: Math.abs(contract) > 1 ? 1 / contract : contract, |
| 124 | step: 1 / step, |
| 125 | power, |
| 126 | deadline, |
| 127 | }); |
| 128 | } |
| 129 | |
| 130 | return withAmbientDeadline(deadline, () => { |
| 131 | let h = step; |
| 132 | const invcontract = Math.pow(1 / contract, power); |
| 133 | let f0 = f(x0 + h); |
| 134 | const neville: number[] = [f0]; // The current diagonal of the Neville tableau |
| 135 | let err = Infinity; |
| 136 | let numeval = 1; |
| 137 | |
| 138 | while (numeval < maxeval) { |
| 139 | // Each iteration costs a function evaluation, which may itself be |
| 140 | // expensive: check the evaluation deadline between evaluations. |
| 141 | checkDeadline(deadline); |
| 142 | numeval += 1; |
| 143 | h *= contract; |
| 144 | neville.push(f(x0 + h)); |
| 145 | let c = invcontract; |
| 146 | let minerr = Infinity; |
| 147 | |
| 148 | for (let i = neville.length - 2; i >= 0; i--) { |
| 149 | const old = neville[i]; |
| 150 | neville[i] = neville[i + 1] + (neville[i + 1] - neville[i]) / (c - 1); |
no test coverage detected