ml-levenberg-marquardt
Version:
Curve fitting method in javascript
59 lines (54 loc) • 1.94 kB
text/typescript
import { Matrix } from 'ml-matrix';
import type { Data2D, ParameterizedFunction } from './types.ts';
/**
* Difference of the matrix function over the parameters
* @param data Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]
* @param evaluatedData - Array of previous evaluated function values
* @param params - Array of previous parameter values
* @param gradientDifference - The step size to approximate the jacobian matrix
* @param centralDifference - If true the jacobian matrix is approximated by central differences otherwise by forward differences
* @param paramFunction - The parameters and returns a function with the independent variable as a parameter
*/
export default function gradientFunction(
data: Data2D,
evaluatedData: Float64Array,
params: number[],
gradientDifference: number[],
paramFunction: ParameterizedFunction,
centralDifference: boolean,
): Matrix {
const nbParams = params.length;
const nbPoints = data.x.length;
const ans = Matrix.zeros(nbParams, nbPoints);
let rowIndex = 0;
for (let param = 0; param < nbParams; param++) {
if (gradientDifference[param] === 0) continue;
let delta = gradientDifference[param];
let auxParams = params.slice();
auxParams[param] += delta;
const funcParam = paramFunction(auxParams);
if (!centralDifference) {
for (let point = 0; point < nbPoints; point++) {
ans.set(
rowIndex,
point,
(evaluatedData[point] - funcParam(data.x[point])) / delta,
);
}
} else {
auxParams = params.slice();
auxParams[param] -= delta;
delta *= 2;
const funcParam2 = paramFunction(auxParams);
for (let point = 0; point < nbPoints; point++) {
ans.set(
rowIndex,
point,
(funcParam2(data.x[point]) - funcParam(data.x[point])) / delta,
);
}
}
rowIndex++;
}
return ans;
}