* Probe the geometric sample ladder that `extrapolate()` uses for a numeric * limit and report how many leading samples are *trustworthy*. * * Returns `Infinity` when the ladder is well-behaved (the common case — no cap * needed), or a finite count when the function crosses a floating-point * "
( f: (x: number) => number, x0: number, step: number )
| 296 | if (n < 0) return NaN; |
| 297 | if (n <= 1) return 1; |
| 298 | |
| 299 | let result = n; |
| 300 | while (n > 2) { |
| 301 | n -= 2; |
| 302 | result *= n; |
| 303 | } |
| 304 | |
| 305 | return result; |
| 306 | } |
| 307 | |
| 308 | export function chop(n: number, tolerance = DEFAULT_TOLERANCE): 0 | number { |
| 309 | if (typeof n === 'number' && Math.abs(n) <= tolerance) return 0; |
| 310 | return n; |
| 311 | } |
| 312 | |
| 313 | /** |
| 314 | * An 8th-order centered difference approximation can be used to get a highly |
| 315 | * accurate approximation of the first derivative of a function. |
| 316 | * The formula for the 8th-order centered difference approximation for the |
| 317 | * first derivative is given by: |
| 318 | * |
| 319 | * $$ f'(x) \approx \frac{1}{280h} \left[ -f(x-4h) + \frac{4}{3}f(x-3h) - \frac{1}{5}f(x-2h) + \frac{8}{5}f(x-h) - \frac{8}{5}f(x+h) + \frac{1}{5}f(x+2h) - \frac{4}{3}f(x+3h) + f(x+4h) \right]$$ |
| 320 | * |
| 321 | * Note: Mathematica uses an 8th order approximation for the first derivative |
| 322 | * |
| 323 | * f: the function |
| 324 | * x: the point at which to approximate the derivative |
| 325 | * h: the step size |
| 326 | * |
| 327 | * See https://en.wikipedia.org/wiki/Finite_difference_coefficient |
| 328 | */ |
| 329 | export function centeredDiff8thOrder( |
| 330 | f: (x: number) => number, |
| 331 | x: number, |
| 332 | h = 0.1 |
| 333 | ) { |
| 334 | return ( |
| 335 | (f(x - 4 * h) / 280 - |
| 336 | (4 * f(x - 3 * h)) / 105 + |
| 337 | f(x - 2 * h) / 5 - |
| 338 | (4 * f(x - h)) / 5 + |
| 339 | (4 * f(x + h)) / 5 - |
| 340 | f(x + 2 * h) / 5 + |
| 341 | (4 * f(x + 3 * h)) / 105 - |
| 342 | f(x + 4 * h) / 280) / |
| 343 | h |
| 344 | ); |
| 345 | } |
| 346 | |
| 347 | /** |
| 348 | * |
| 349 | * @param f |
| 350 | * @param x |
| 351 | * @param dir Direction of approach: > 0 for right, < 0 for left, 0 for both |
| 352 | * @returns |
| 353 | */ |
| 354 | /** |
| 355 | * Probe the geometric sample ladder that `extrapolate()` uses for a numeric |