ml-levenberg-marquardt
Version:
Curve fitting method in javascript
45 lines • 2.2 kB
JavaScript
import { inverse, Matrix } from 'ml-matrix';
import gradientFunction from "./gradient_function.js";
/**
* Matrix function over the samples
*
* @param data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]
* @param evaluatedData - Array of previous evaluated function values
*/
function matrixFunction(data, evaluatedData) {
const m = data.x.length;
const ans = new Matrix(m, 1);
for (let point = 0; point < m; point++) {
ans.set(point, 0, data.y[point] - evaluatedData[point]);
}
return ans;
}
/**
* Iteration for Levenberg-Marquardt
*
* @param data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]
* @param params - Array of previous parameter values
* @param damping - Levenberg-Marquardt parameter
* @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 parameterizedFunction - The parameters and returns a function with the independent variable as a parameter
* @param weights - scale the gradient and residual error by weights
*/
export default function step(data, params, damping, gradientDifference, parameterizedFunction, centralDifference, weights) {
const identity = Matrix.eye(params.length, params.length, damping);
const func = parameterizedFunction(params);
const evaluatedData = new Float64Array(data.x.length);
for (let i = 0; i < data.x.length; i++) {
evaluatedData[i] = func(data.x[i]);
}
const gradientFunc = gradientFunction(data, evaluatedData, params, gradientDifference, parameterizedFunction, centralDifference);
const residualError = matrixFunction(data, evaluatedData);
const inverseMatrix = inverse(identity.add(gradientFunc.mmul(gradientFunc.transpose().scale('row', { scale: weights }))));
const jacobianWeightResidualError = gradientFunc.mmul(residualError.scale('row', { scale: weights }));
const perturbations = inverseMatrix.mmul(jacobianWeightResidualError);
return {
perturbations,
jacobianWeightResidualError,
};
}
//# sourceMappingURL=step.js.map