@datagrok-libraries/statistics 1.2.13 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/.eslintrc.json +1 -0
  2. package/CHANGELOG.md +6 -0
  3. package/README.md +0 -1
  4. package/package.json +1 -1
  5. package/src/correlation-coefficient.d.ts.map +1 -1
  6. package/src/correlation-coefficient.js +1 -1
  7. package/src/fit/fit-curve.d.ts +32 -67
  8. package/src/fit/fit-curve.d.ts.map +1 -1
  9. package/src/fit/fit-curve.js +160 -190
  10. package/src/fit/fit-data.d.ts +0 -4
  11. package/src/fit/fit-data.d.ts.map +1 -1
  12. package/src/fit/fit-data.js +22 -22
  13. package/src/fit/fitting-algorithm/optimizer-misc.d.ts +19 -0
  14. package/src/fit/fitting-algorithm/optimizer-misc.d.ts.map +1 -0
  15. package/src/fit/fitting-algorithm/optimizer-misc.js +7 -0
  16. package/src/fit/fitting-algorithm/optimizer-nelder-mead.d.ts +25 -0
  17. package/src/fit/fitting-algorithm/optimizer-nelder-mead.d.ts.map +1 -0
  18. package/src/fit/fitting-algorithm/optimizer-nelder-mead.js +156 -0
  19. package/src/fit/fitting-algorithm/optimizer-sampler.d.ts +2 -0
  20. package/src/fit/fitting-algorithm/optimizer-sampler.d.ts.map +1 -0
  21. package/src/fit/fitting-algorithm/optimizer-sampler.js +28 -0
  22. package/src/fit/fitting-algorithm/optimizer.d.ts +4 -0
  23. package/src/fit/fitting-algorithm/optimizer.d.ts.map +1 -0
  24. package/src/fit/fitting-algorithm/optimizer.js +48 -0
  25. package/lbfgs/lbfgs.d.ts +0 -1
  26. package/lbfgs/lbfgs.js +0 -316
  27. package/src/optimization/opt-nelder-mead.d.ts +0 -5
  28. package/src/optimization/opt-nelder-mead.d.ts.map +0 -1
  29. package/src/optimization/opt-nelder-mead.js +0 -116
  30. package/src/optimization/optimizer.d.ts +0 -28
  31. package/src/optimization/optimizer.d.ts.map +0 -1
  32. package/src/optimization/optimizer.js +0 -63
@@ -1,28 +0,0 @@
1
- export declare const FitErrorModel: {
2
- CONSTANT: string;
3
- PROPORTIONAL: string;
4
- };
5
- export declare type Likelihood = {
6
- likelihood: number;
7
- likelihoodYs: number[];
8
- residualSquaresSums: number[];
9
- };
10
- export declare abstract class FitFunction {
11
- abstract solve(params: Float32Array, xs: Float32Array[]): NumericalSolution;
12
- }
13
- export declare abstract class Optimizer {
14
- abstract optimize(params: Float32Array, objectiveFunc: (params: Float32Array) => Likelihood): Likelihood;
15
- }
16
- export declare type NumericalSolution = {
17
- ys: Float32Array[];
18
- devereges: boolean;
19
- };
20
- export declare function getLikelihood(func: FitFunction, params: Float32Array, sigmaTypes: string[], sigmaValues: number[], data: {
21
- ys: Float32Array[];
22
- xs: Float32Array[];
23
- }): Likelihood;
24
- export declare function fit(func: FitFunction, params: Float32Array, sigmaTypes: string[], data: {
25
- ys: Float32Array[];
26
- xs: Float32Array[];
27
- }, optimizer: Optimizer): void;
28
- //# sourceMappingURL=optimizer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"optimizer.d.ts","sourceRoot":"","sources":["optimizer.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa;;;CAGzB,CAAC;AAEF,oBAAY,UAAU,GAAG;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB,EAAE,MAAM,EAAE,CAAA;CAC9B,CAAC;AAEF,8BAAsB,WAAW;IAG/B,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,iBAAiB;CAE5E;AAED,8BAAsB,SAAS;IAC7B,QAAQ,CAAC,QAAQ,CACf,MAAM,EAAE,YAAY,EACpB,aAAa,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,UAAU,GAClD,UAAU;CACd;AAED,oBAAY,iBAAiB,GAAG;IAC9B,EAAE,EAAE,YAAY,EAAG,CAAC;IACpB,SAAS,EAAE,OAAO,CAAA;CACnB,CAAA;AAiBD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EACpF,IAAI,EAAE;IAAC,EAAE,EAAE,YAAY,EAAE,CAAC;IAAC,EAAE,EAAE,YAAY,EAAE,CAAA;CAAC,GAAG,UAAU,CAyB5D;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,EAC/E,IAAI,EAAE;IAAC,EAAE,EAAE,YAAY,EAAE,CAAC;IAAC,EAAE,EAAE,YAAY,EAAE,CAAA;CAAC,EAAE,SAAS,EAAE,SAAS,QAmBrE"}
@@ -1,63 +0,0 @@
1
- const INFINITY = Number.MAX_VALUE;
2
- const PI = Math.PI;
3
- export const FitErrorModel = {
4
- CONSTANT: 'constant',
5
- PROPORTIONAL: 'proportional',
6
- };
7
- export class FitFunction {
8
- }
9
- export class Optimizer {
10
- }
11
- function getResiduals(observed, predicted) {
12
- const dimYtypes = predicted.length;
13
- const residuals = new Array(dimYtypes);
14
- for (let i = 0; i < dimYtypes; i++) {
15
- const dimY = predicted[i].length;
16
- residuals[i] = new Float32Array(dimY);
17
- for (let j = 0; j < dimY; j++)
18
- residuals[i][j] = observed[i][j] - predicted[i][j];
19
- }
20
- return residuals;
21
- }
22
- //sigma types number equal to data.ys.length, data.xs.length
23
- export function getLikelihood(func, params, sigmaTypes, sigmaValues, data) {
24
- const solution = func.solve(params, data.xs);
25
- if (solution.devereges)
26
- return { likelihood: INFINITY, likelihoodYs: [], residualSquaresSums: [] };
27
- const residuals = getResiduals(data.ys, solution.ys);
28
- const dimYtypes = data.ys.length;
29
- const residualSquaresSums = new Array(dimYtypes);
30
- const likelihoodYs = new Array(dimYtypes);
31
- let likelihood = 0;
32
- for (let i = 0; i < dimYtypes; i++) {
33
- const dimY = solution.ys[i].length;
34
- const sigmaSqare = sigmaValues[i] * sigmaValues[i];
35
- for (let j = 0; j < dimY; j++) {
36
- const square = residuals[i][j] * residuals[i][j];
37
- likelihoodYs[i] += square / sigmaSqare + Math.log(2 * PI * sigmaSqare);
38
- if (sigmaTypes[i] == FitErrorModel.PROPORTIONAL)
39
- residualSquaresSums[i] += square / (solution.ys[i][j] * solution.ys[i][j]);
40
- else
41
- residualSquaresSums[i] += square;
42
- }
43
- likelihood += likelihoodYs[i];
44
- }
45
- return { likelihood, likelihoodYs, residualSquaresSums };
46
- }
47
- export function fit(func, params, sigmaTypes, data, optimizer) {
48
- let convergenceIndicator = INFINITY / 2;
49
- let convergenceIndicatorOld = INFINITY;
50
- const dimYtypes = data.ys.length;
51
- const sigmaValues = new Array(dimYtypes).fill(1);
52
- const objectiveFunc = (params) => {
53
- return getLikelihood(func, params, sigmaTypes, sigmaValues, data);
54
- };
55
- while (Math.abs(convergenceIndicator - convergenceIndicatorOld) > 0.001) {
56
- const optimizedLikelihood = optimizer.optimize(params, objectiveFunc);
57
- for (let i = 0; i < dimYtypes; i++)
58
- sigmaValues[i] = Math.sqrt(optimizedLikelihood.residualSquaresSums[i] / data.ys[i].length);
59
- convergenceIndicatorOld = convergenceIndicator;
60
- convergenceIndicator = optimizedLikelihood.likelihood;
61
- }
62
- }
63
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW1pemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsib3B0aW1pemVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7QUFDbEMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztBQUVuQixNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUc7SUFDM0IsUUFBUSxFQUFFLFVBQVU7SUFDcEIsWUFBWSxFQUFFLGNBQWM7Q0FDN0IsQ0FBQztBQVFGLE1BQU0sT0FBZ0IsV0FBVztDQUtoQztBQUVELE1BQU0sT0FBZ0IsU0FBUztDQUs5QjtBQU9ELFNBQVMsWUFBWSxDQUFDLFFBQXdCLEVBQUUsU0FBeUI7SUFDdkUsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztJQUNuQyxNQUFNLFNBQVMsR0FBRyxJQUFJLEtBQUssQ0FBZSxTQUFTLENBQUMsQ0FBQztJQUVyRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ2xDLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDakMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFO1lBQzNCLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQ3REO0lBRUQsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVELDREQUE0RDtBQUM1RCxNQUFNLFVBQVUsYUFBYSxD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QW9CLEdBQUcsdUJBQXVCLENBQUMsR0FBRyxLQUFLLEVBQUU7UUFDdkUsTUFBTSxtQkFBbUIsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsQ0FBQztRQUV0RSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxFQUFFLENBQUMsRUFBRTtZQUNoQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTNGLHVCQUF1QixHQUFHLG9CQUFvQixDQUFDO1FBQy9DLG9CQUFvQixHQUFHLG1CQUFtQixDQUFDLFVBQVUsQ0FBQztLQUN2RDtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJcbmNvbnN0IElORklOSVRZID0gTnVtYmVyLk1BWF9WQUxVRTtcbmNvbnN0IFBJID0gTWF0aC5QSTtcblxuZXhwb3J0IGNvbnN0IEZpdEVycm9yTW9kZWwgPSB7XG4gIENPTlNUQU5UOiAnY29uc3RhbnQnLFxuICBQUk9QT1JUSU9OQUw6ICdwcm9wb3J0aW9uYWwnLFxufTtcblxuZXhwb3J0IHR5cGUgTGlrZWxpaG9vZCA9IHtcbiAgbGlrZWxpaG9vZDogbnVtYmVyLFxuICBsaWtlbGlob29kWXM6IG51bWJlcltdLFxuICByZXNpZHVhbFNxdWFyZXNTdW1zOiBudW1iZXJbXVxufTtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEZpdEZ1bmN0aW9uIHtcbiAgLy8gYWJzdHJhY3QgZ2V0IG5hbWUoKTogc3RyaW5nO1xuICAvLyBhYnN0cmFjdCBnZXQgcGFyYW1ldGVyTmFtZXMoKTogc3RyaW5nW107XG4gIGFic3RyYWN0IHNvbHZlKHBhcmFtczogRmxvYXQzMkFycmF5LCB4czogRmxvYXQzMkFycmF5W10pOiBOdW1lcmljYWxTb2x1dGlvbjtcbiAgLy9hYnN0cmFjdCBnZXRJbml0aWFsUGFyYW1ldGVycyh4OiBudW1iZXJbXSwgeTogbnVtYmVyW10pOiBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIE9wdGltaXplciB7XG4gIGFic3RyYWN0IG9wdGltaXplKFxuICAgIHBhcmFtczogRmxvYXQzMkFycmF5LFxuICAgIG9iamVjdGl2ZUZ1bmM6IChwYXJhbXM6IEZsb2F0MzJBcnJheSkgPT4gTGlrZWxpaG9vZFxuICApOiBMaWtlbGlob29kXG59XG5cbmV4cG9ydCB0eXBlIE51bWVyaWNhbFNvbHV0aW9uID0ge1xuICB5czogRmxvYXQzMkFycmF5IFtdLFxuICBkZXZlcmVnZXM6IGJvb2xlYW5cbn1cblxuZnVuY3Rpb24gZ2V0UmVzaWR1YWxzKG9ic2VydmVkOiBGbG9hdDMyQXJyYXlbXSwgcHJlZGljdGVkOiBGbG9hdDMyQXJyYXlbXSk6IEZsb2F0MzJBcnJheVtdIHtcbiAgY29uc3QgZGltWXR5cGVzID0gcHJlZGljdGVkLmxlbmd0aDtcbiAgY29uc3QgcmVzaWR1YWxzID0gbmV3IEFycmF5PEZsb2F0MzJBcnJheT4oZGltWXR5cGVzKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbVl0eXBlczsgaSsrKSB7XG4gICAgY29uc3QgZGltWSA9IHByZWRpY3RlZFtpXS5sZW5ndGg7XG4gICAgcmVzaWR1YWxzW2ldID0gbmV3IEZsb2F0MzJBcnJheShkaW1ZKTtcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGRpbVk7IGorKylcbiAgICAgIHJlc2lkdWFsc1tpXVtqXSA9IG9ic2VydmVkW2ldW2pdIC0gcHJlZGljdGVkW2ldW2pdO1xuICB9XG5cbiAgcmV0dXJuIHJlc2lkdWFscztcbn1cblxuLy9zaWdtYSB0eXBlcyBudW1iZXIgZXF1YWwgdG8gZGF0YS55cy5sZW5ndGgsIGRhdGEueHMubGVuZ3RoXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGlrZWxpaG9vZChcbiAgZnVuYzogRml0RnVuY3Rpb24sIHBhcmFtczogRmxvYXQzMkFycmF5LCBzaWdtYVR5cGVzOiBzdHJpbmdbXSwgc2lnbWFWYWx1ZXM6IG51bWJlcltdLFxuICBkYXRhOiB7eXM6IEZsb2F0MzJBcnJheVtdLCB4czogRmxvYXQzMkFycmF5W119KTogTGlrZWxpaG9vZCB7XG4gIGNvbnN0IHNvbHV0aW9uID0gZnVuYy5zb2x2ZShwYXJhbXMsIGRhdGEueHMpO1xuICBpZiAoc29sdXRpb24uZGV2ZXJlZ2VzKVxuICAgIHJldHVybiB7bGlrZWxpaG9vZDogSU5GSU5JVFksIGxpa2VsaWhvb2RZczogW10sIHJlc2lkdWFsU3F1YXJlc1N1bXM6IFtdfTtcblxuICBjb25zdCByZXNpZHVhbHMgPSBnZXRSZXNpZHVhbHMoZGF0YS55cywgc29sdXRpb24ueXMpO1xuICBjb25zdCBkaW1ZdHlwZXMgPSBkYXRhLnlzLmxlbmd0aDtcbiAgY29uc3QgcmVzaWR1YWxTcXVhcmVzU3VtcyA9IG5ldyBBcnJheTxudW1iZXI+KGRpbVl0eXBlcyk7XG4gIGNvbnN0IGxpa2VsaWhvb2RZcyA9IG5ldyBBcnJheTxudW1iZXI+KGRpbVl0eXBlcyk7XG4gIGxldCBsaWtlbGlob29kID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaW1ZdHlwZXM7IGkrKykge1xuICAgIGNvbnN0IGRpbVkgPSBzb2x1dGlvbi55c1tpXS5sZW5ndGg7XG4gICAgY29uc3Qgc2lnbWFTcWFyZSA9IHNpZ21hVmFsdWVzW2ldKnNpZ21hVmFsdWVzW2ldO1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgZGltWTsgaisrKSB7XG4gICAgICBjb25zdCBzcXVhcmUgPSByZXNpZHVhbHNbaV1bal0qcmVzaWR1YWxzW2ldW2pdO1xuICAgICAgbGlrZWxpaG9vZFlzW2ldICs9IHNxdWFyZS9zaWdtYVNxYXJlICsgTWF0aC5sb2coMipQSSpzaWdtYVNxYXJlKTtcbiAgICAgIGlmIChzaWdtYVR5cGVzW2ldID09IEZpdEVycm9yTW9kZWwuUFJPUE9SVElPTkFMKVxuICAgICAgICByZXNpZHVhbFNxdWFyZXNTdW1zW2ldICs9IHNxdWFyZS8oc29sdXRpb24ueXNbaV1bal0qc29sdXRpb24ueXNbaV1bal0pO1xuICAgICAgZWxzZVxuICAgICAgICByZXNpZHVhbFNxdWFyZXNTdW1zW2ldICs9IHNxdWFyZTtcbiAgICB9XG4gICAgbGlrZWxpaG9vZCArPSBsaWtlbGlob29kWXNbaV07XG4gIH1cblxuICByZXR1cm4ge2xpa2VsaWhvb2QsIGxpa2VsaWhvb2RZcywgcmVzaWR1YWxTcXVhcmVzU3Vtc307XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaXQoZnVuYzogRml0RnVuY3Rpb24sIHBhcmFtczogRmxvYXQzMkFycmF5LCBzaWdtYVR5cGVzOiBzdHJpbmdbXSxcbiAgZGF0YToge3lzOiBGbG9hdDMyQXJyYXlbXSwgeHM6IEZsb2F0MzJBcnJheVtdfSwgb3B0aW1pemVyOiBPcHRpbWl6ZXIpIHtcbiAgbGV0IGNvbnZlcmdlbmNlSW5kaWNhdG9yID0gSU5GSU5JVFkgLyAyO1xuICBsZXQgY29udmVyZ2VuY2VJbmRpY2F0b3JPbGQgPSBJTkZJTklUWTtcbiAgY29uc3QgZGltWXR5cGVzID0gZGF0YS55cy5sZW5ndGg7XG4gIGNvbnN0IHNpZ21hVmFsdWVzID0gbmV3IEFycmF5PG51bWJlcj4oZGltWXR5cGVzKS5maWxsKDEpO1xuXG4gIGNvbnN0IG9iamVjdGl2ZUZ1bmMgPSAocGFyYW1zOiBGbG9hdDMyQXJyYXkpID0+IHtcbiAgICByZXR1cm4gZ2V0TGlrZWxpaG9vZChmdW5jLCBwYXJhbXMsIHNpZ21hVHlwZXMsIHNpZ21hVmFsdWVzLCBkYXRhKTtcbiAgfTtcblxuICB3aGlsZSAoTWF0aC5hYnMoY29udmVyZ2VuY2VJbmRpY2F0b3IgLSBjb252ZXJnZW5jZUluZGljYXRvck9sZCkgPiAwLjAwMSkge1xuICAgIGNvbnN0IG9wdGltaXplZExpa2VsaWhvb2QgPSBvcHRpbWl6ZXIub3B0aW1pemUocGFyYW1zLCBvYmplY3RpdmVGdW5jKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGltWXR5cGVzOyBpKyspXG4gICAgICBzaWdtYVZhbHVlc1tpXSA9IE1hdGguc3FydChvcHRpbWl6ZWRMaWtlbGlob29kLnJlc2lkdWFsU3F1YXJlc1N1bXNbaV0vZGF0YS55c1tpXS5sZW5ndGgpO1xuXG4gICAgY29udmVyZ2VuY2VJbmRpY2F0b3JPbGQgPSBjb252ZXJnZW5jZUluZGljYXRvcjtcbiAgICBjb252ZXJnZW5jZUluZGljYXRvciA9IG9wdGltaXplZExpa2VsaWhvb2QubGlrZWxpaG9vZDtcbiAgfVxufVxuIl19