UNPKG

ml-levenberg-marquardt

Version:
45 lines 2.2 kB
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