Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
benchmark
coverage
lib
CHANGELOG.md
31 changes: 11 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
# levenberg-marquardt
# ml-levenberg-marquardt

[![NPM version][npm-image]][npm-url]
[![build status][ci-image]][ci-url]
[![Test coverage][codecov-image]][codecov-url]
[![npm download][download-image]][download-url]
[![NPM version](https://img.shields.io/npm/v/ml-levenberg-marquardt.svg)](https://www.npmjs.com/package/ml-levenberg-marquardt)
[![npm download](https://img.shields.io/npm/dm/ml-levenberg-marquardt.svg)](https://www.npmjs.com/package/ml-levenberg-marquardt)
[![test coverage](https://img.shields.io/codecov/c/github/mljs/levenberg-marquardt.svg)](https://codecov.io/gh/mljs/levenberg-marquardt)
[![license](https://img.shields.io/npm/l/ml-levenberg-marquardt.svg)](https://github.com/mljs/levenberg-marquardt/blob/main/LICENSE)

Curve fitting method in javascript.

## [API Documentation](https://mljs.github.io/levenberg-marquardt/)

This algorithm is based on the article [Brown, Kenneth M., and J. E. Dennis. "Derivative free analogues of the Levenberg-Marquardt and Gauss algorithms for nonlinear least squares approximation." Numerische Mathematik 18.4 (1971): 289-297.](https://doi.org/10.1007/BF01404679) and [http://people.duke.edu/~hpgavin/ce281/lm.pdf](http://people.duke.edu/~hpgavin/ce281/lm.pdf)

In order to get a general idea of the problem you could also check the [Wikipedia article](https://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm).
To get a general idea of the problem, you could also check the [Wikipedia article](https://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm).

## Installation

`$ npm i ml-levenberg-marquardt`
```console
npm i ml-levenberg-marquardt
```

## Options

Next there is some options could change the behavior of the code.
Next, there are some options could change the behaviour of the code.

### centralDifference

The jacobian matrix is approximated by finite difference; forward differences or central differences (one additional function evaluation). The option centralDifference select one of them, by default the jacobian is calculated by forward difference.

### gradientDifference

The jacobian matrix is approximated as mention above, the gradientDifference option is the step size (dp) to calculate de difference between the function with the current parameter state and the perturbation added. It could be a number (same step size for all parameters) or an array with different values for each parameter, if the gradientDifference is zero the derive will be zero, and the parameter will hold fixed
The jacobian matrix is approximated as mentioned above, the gradientDifference option is the step size (dp) to calculate the difference between the function with the current parameter state and the perturbation added. It could be a number (same step size for all parameters) or an array with different values for each parameter, if the gradientDifference is zero, the derive will be zero, and the parameter will hold fixed

## Examples

Expand Down Expand Up @@ -107,17 +109,6 @@ const options = {
let fittedParams = LM(data, sinFunction, options);
```

Or test it in [Runkit](https://runkit.com/npm/ml-levenberg-marquardt)

## License

[MIT](./LICENSE)

[npm-image]: https://img.shields.io/npm/v/ml-levenberg-marquardt.svg
[npm-url]: https://npmjs.org/package/ml-levenberg-marquardt
[codecov-image]: https://img.shields.io/codecov/c/github/mljs/levenberg-marquardt.svg
[codecov-url]: https://codecov.io/gh/mljs/levenberg-marquardt
[ci-image]: https://github.com/mljs/levenberg-marquardt/workflows/Node.js%20CI/badge.svg?branch=main
[ci-url]: https://github.com/mljs/levenberg-marquardt/actions?query=workflow%3A%22Node.js+CI%22
[download-image]: https://img.shields.io/npm/dm/ml-levenberg-marquardt.svg
[download-url]: https://npmjs.org/package/ml-levenberg-marquardt
112 changes: 0 additions & 112 deletions benchmark/index.js

This file was deleted.

5 changes: 1 addition & 4 deletions eslint.config.mjs → eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { defineConfig, globalIgnores } from 'eslint/config';
import ts from 'eslint-config-cheminfo-typescript/base';

export default defineConfig(
globalIgnores(['coverage', 'lib', 'benchmark']),
ts,
);
export default defineConfig(globalIgnores(['coverage', 'lib']), ts);
19 changes: 7 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,19 @@
},
"homepage": "https://github.com/mljs/levenberg-marquardt#readme",
"devDependencies": {
"@types/node": "^24.0.1",
"@vitest/coverage-v8": "^3.2.3",
"benchmark": "^2.1.4",
"cz-conventional-changelog": "^3.3.0",
"@zakodium/tsconfig": "^1.0.1",
"eslint": "^9.28.0",
"eslint-config-cheminfo-typescript": "^18.0.1",
"jest-matcher-deep-close-to": "^3.0.2",
"prettier": "^2.8.7",
"rimraf": "^5.0.0",
"typescript": "^5.0.4",
"prettier": "^3.5.3",
"rimraf": "^6.0.1",
"typescript": "^5.8.3",
"vitest": "^3.2.3"
},
"dependencies": {
"is-any-array": "^2.0.0",
"ml-matrix": "^6.10.4"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
"is-any-array": "^2.0.1",
"ml-matrix": "^6.12.1"
}
}
8 changes: 4 additions & 4 deletions src/__tests__/curve.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import * as os from 'node:os';

import { describe, expect, it, test } from 'vitest';

import { levenbergMarquardt } from '../index.js';
import { levenbergMarquardt } from '../index.ts';

function sinFunction([a, b]: number[]) {
return (t) => a * Math.sin(b * t);
return (t: number) => a * Math.sin(b * t);
}

test('linear regression', () => {
Expand Down Expand Up @@ -105,8 +105,8 @@ describe('curve', () => {
},
{
name: 'Sum of lorentzians, central differences',
getFunctionFromParameters: function sumOfLorentzians(p) {
return (t) => {
getFunctionFromParameters: function sumOfLorentzians(p: number[]) {
return (t: number) => {
const nL = p.length;
let factor: number, p2: number;
let result = 0;
Expand Down
6 changes: 3 additions & 3 deletions src/__tests__/error_calculation.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { describe, expect, it } from 'vitest';

import errorCalculation from '../error_calculation.js';
import errorCalculation from '../error_calculation.ts';

describe('parameterError', () => {
describe('Linear functions', () => {
function linearFunction([slope, intercept]: number[]) {
return (x) => slope * x + intercept;
return (x: number) => slope * x + intercept;
}

/** @type [number, number] */
Expand Down Expand Up @@ -38,7 +38,7 @@ describe('parameterError', () => {

describe('Linear functions with typed array', () => {
function linearFunction([slope, intercept]: number[]) {
return (x) => slope * x + intercept;
return (x: number) => slope * x + intercept;
}

/** @type [number, number] */
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/exceptions.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';

import { levenbergMarquardt } from '../index.js';
import { levenbergMarquardt } from '../index.ts';

function sinFunction([a, b]: number[]) {
return (t: number) => a * Math.sin(b * t);
Expand Down Expand Up @@ -98,7 +98,7 @@ describe('Handling of invalid arguments', () => {

describe('Handling of ill-behaved functions', () => {
function fourParamEq([a, b, c, d]: number[]) {
return (t) => a + (b - a) / (1 + c ** d * t ** -d);
return (t: number) => a + (b - a) / (1 + c ** d * t ** -d);
}

const data = {
Expand Down
2 changes: 1 addition & 1 deletion src/check_options.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isAnyArray } from 'is-any-array';

import type { Data2D, LevenbergMarquardtOptions } from './types.js';
import type { Data2D, LevenbergMarquardtOptions } from './types.ts';

export interface CheckedOptions {
checkTimeout: () => boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/error_calculation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Data2D, ParameterizedFunction } from './types.js';
import type { Data2D, ParameterizedFunction } from './types.ts';

/**
* the sum of the weighted squares of the errors (or weighted residuals) between the data.y
Expand Down
2 changes: 1 addition & 1 deletion src/gradient_function.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Matrix } from 'ml-matrix';

import type { Data2D, ParameterizedFunction } from './types.js';
import type { Data2D, ParameterizedFunction } from './types.ts';

/**
* Difference of the matrix function over the parameters
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { levenbergMarquardt } from './levenberg_marquardt.js';
export type * from './types.js';
export { levenbergMarquardt } from './levenberg_marquardt.ts';
export type * from './types.ts';
8 changes: 4 additions & 4 deletions src/levenberg_marquardt.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import checkOptions from './check_options.js';
import errorCalculation from './error_calculation.js';
import step from './step.js';
import checkOptions from './check_options.ts';
import errorCalculation from './error_calculation.ts';
import step from './step.ts';
import type {
Data2D,
LevenbergMarquardtOptions,
LevenbergMarquardtReturn,
ParameterizedFunction,
} from './types.js';
} from './types.ts';

/**
* Curve fitting algorithm
Expand Down
4 changes: 2 additions & 2 deletions src/step.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { inverse, Matrix } from 'ml-matrix';

import gradientFunction from './gradient_function.js';
import type { Data2D, ParameterizedFunction } from './types.js';
import gradientFunction from './gradient_function.ts';
import type { Data2D, ParameterizedFunction } from './types.ts';

/**
* Matrix function over the samples
Expand Down
18 changes: 3 additions & 15 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
{
"extends": "@zakodium/tsconfig",
"compilerOptions": {
"lib": ["ES2022", "WebWorker"],
"target": "ES2022",
"types": ["node"],
"outDir": "lib",
"module": "NodeNext",
"strict": true,
"skipLibCheck": false,
"resolveJsonModule": false,
"forceConsistentCasingInFileNames": true,
"allowJs": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"sourceMap": true,
"declaration": true,
"declarationMap": true,
"checkJs": true,
"noImplicitAny": false
"noUncheckedIndexedAccess": false
},
"include": ["src", "vite*.ts"]
}