-
Notifications
You must be signed in to change notification settings - Fork 7
Open
Description
I wanted to use this in my project, but I needed to convert it to TypeScript / ES6. Here's what I did:
// Copied from https://github.com/scijs/newton-raphson-method
// Converted to TypeScript and ES6
interface INewtonRaphsonOptions {
tolerance?: number;
epsilon?: number;
maxIterations?: number;
h?: number;
verbose?: boolean;
}
export function newtonRaphson(
f: (n: number) => number,
fp: (n: number) => number,
x0: number,
options?: INewtonRaphsonOptions
): number | boolean;
export function newtonRaphson(
f: (n: number) => number,
x0: number,
options?: INewtonRaphsonOptions
): number | boolean;
export function newtonRaphson(
f: (n: number) => number,
fp: number | ((n: number) => number),
x0?: number | INewtonRaphsonOptions,
options?: INewtonRaphsonOptions
): number | boolean {
// Iterpret variadic forms:
const fnp = typeof fp === 'function' ? fp : null;
const {
tolerance: tol = 1e-7,
epsilon: eps = 2.220446049250313e-16,
maxIterations: maxIter = 20,
h = 1e-4,
verbose = false,
} = (fnp ? (options as INewtonRaphsonOptions) : (x0 as INewtonRaphsonOptions)) ?? {};
let x1, y, yp, yph, ymh, yp2h, ym2h;
let hr = 1 / h;
let x = (fnp ? x0 : fp) as number;
let iter = 0;
while (iter++ < maxIter) {
// Compute the value of the function:
y = f(x);
if (fnp) {
yp = fnp(x);
} else {
// Needs numerical derivatives:
yph = f(x + h);
ymh = f(x - h);
yp2h = f(x + 2 * h);
ym2h = f(x - 2 * h);
yp = ((ym2h - yp2h + 8 * (yph - ymh)) * hr) / 12;
}
// Check for badly conditioned update (extremely small first deriv relative to function):
if (Math.abs(yp) <= eps * Math.abs(y)) {
if (verbose) {
console.log('Newton-Raphson: failed to converged due to nearly zero first derivative');
}
return false;
}
// Update the guess:
x1 = x - y / yp;
// Check for convergence:
if (Math.abs(x1 - x) <= tol * Math.abs(x1)) {
if (verbose) {
console.log('Newton-Raphson: converged to x = ' + x1 + ' after ' + iter + ' iterations');
}
return x1;
}
// Transfer update to the new guess:
x = x1;
}
if (verbose) {
console.log('Newton-Raphson: Maximum iterations reached (' + maxIter + ')');
}
return false;
}
I also converted the unit tests to Vitest (since that's what I am using). I can supply the code if you are interested.
jimmywarting
Metadata
Metadata
Assignees
Labels
No labels