diff-grok 1.0.9 → 1.1.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.
- package/.claude/settings.local.json +11 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/.github/workflows/deploy-docs.yml +15 -0
- package/CLAUDE.md +98 -0
- package/CONTRIBUTING.md +74 -0
- package/README.MD +272 -18
- package/images/E5.png +0 -0
- package/images/HIRES.png +0 -0
- package/images/OREGO.png +0 -0
- package/images/POLL-full.png +0 -0
- package/images/POLL.png +0 -0
- package/images/ROBER.png +0 -0
- package/images/VDP0L.png +0 -0
- package/images/VDPOL.png +0 -0
- package/index.js +2 -2
- package/index.js.map +1 -1
- package/index.ts +7 -5
- package/jest.config.js +1 -0
- package/package.json +2 -1
- package/src/examples/bioreactor.js +125 -0
- package/src/examples/bioreactor.js.map +1 -0
- package/src/examples/bioreactor.ts +132 -0
- package/src/examples/check-methods.js +23 -9
- package/src/examples/check-methods.js.map +1 -1
- package/src/examples/check-methods.ts +28 -9
- package/src/examples/corr-probs.js +3 -1
- package/src/examples/corr-probs.js.map +1 -1
- package/src/examples/corr-probs.ts +7 -3
- package/src/examples/cyclic-model.js +3 -1
- package/src/examples/cyclic-model.js.map +1 -1
- package/src/examples/cyclic-model.ts +3 -1
- package/src/examples/e5.js +6 -0
- package/src/examples/e5.js.map +1 -1
- package/src/examples/e5.ts +7 -0
- package/src/examples/hires.js +10 -0
- package/src/examples/hires.js.map +1 -1
- package/src/examples/hires.ts +11 -0
- package/src/examples/index.js +21 -7
- package/src/examples/index.js.map +1 -1
- package/src/examples/index.ts +23 -7
- package/src/examples/orego.js +5 -0
- package/src/examples/orego.js.map +1 -1
- package/src/examples/orego.ts +6 -0
- package/src/examples/pollution.js +22 -0
- package/src/examples/pollution.js.map +1 -1
- package/src/examples/pollution.ts +23 -0
- package/src/examples/print-benchmark.js +581 -0
- package/src/examples/print-benchmark.js.map +1 -0
- package/src/examples/print-benchmark.ts +594 -0
- package/src/examples/robertson.js +6 -1
- package/src/examples/robertson.js.map +1 -1
- package/src/examples/robertson.ts +7 -1
- package/src/examples/scripting.js +1 -1
- package/src/examples/scripting.js.map +1 -1
- package/src/examples/scripting.ts +1 -1
- package/src/examples/vdpol.js +4 -0
- package/src/examples/vdpol.js.map +1 -1
- package/src/examples/vdpol.ts +5 -0
- package/src/pipeline/basic-pipeline-creator.js +96 -1
- package/src/pipeline/basic-pipeline-creator.js.map +1 -1
- package/src/pipeline/basic-pipeline-creator.ts +97 -1
- package/src/pipeline/loops-pipeline-creator.js +115 -2
- package/src/pipeline/loops-pipeline-creator.js.map +1 -1
- package/src/pipeline/loops-pipeline-creator.ts +116 -2
- package/src/pipeline/output.js +7 -2
- package/src/pipeline/output.js.map +1 -1
- package/src/pipeline/output.ts +7 -2
- package/src/pipeline/pipeline-creator.js.map +1 -1
- package/src/pipeline/pipeline-creator.ts +4 -0
- package/src/pipeline/pipeline.js +193 -2
- package/src/pipeline/pipeline.js.map +1 -1
- package/src/pipeline/pipeline.ts +206 -4
- package/src/pipeline/updates-pipeline-creator.js +130 -2
- package/src/pipeline/updates-pipeline-creator.js.map +1 -1
- package/src/pipeline/updates-pipeline-creator.ts +131 -2
- package/src/scripting-tools/constants.js +18 -4
- package/src/scripting-tools/constants.js.map +1 -1
- package/src/scripting-tools/constants.ts +22 -4
- package/src/scripting-tools/index.js.map +1 -1
- package/src/scripting-tools/index.ts +3 -2
- package/src/scripting-tools/model-error.js +3 -1
- package/src/scripting-tools/model-error.js.map +1 -1
- package/src/scripting-tools/model-error.ts +3 -1
- package/src/scripting-tools/scripting-tools.js +139 -9
- package/src/scripting-tools/scripting-tools.js.map +1 -1
- package/src/scripting-tools/scripting-tools.ts +228 -21
- package/src/solver-tools/ab4-method.js +332 -0
- package/src/solver-tools/ab4-method.js.map +1 -0
- package/src/solver-tools/ab4-method.ts +395 -0
- package/src/solver-tools/ab5-method.js +334 -0
- package/src/solver-tools/ab5-method.js.map +1 -0
- package/src/solver-tools/ab5-method.ts +397 -0
- package/src/solver-tools/callbacks/callback-base.js +2 -0
- package/src/solver-tools/callbacks/callback-base.js.map +1 -1
- package/src/solver-tools/callbacks/callback-base.ts +4 -0
- package/src/solver-tools/callbacks/callback-tools.js +3 -1
- package/src/solver-tools/callbacks/callback-tools.js.map +1 -1
- package/src/solver-tools/callbacks/callback-tools.ts +3 -1
- package/src/solver-tools/callbacks/iter-checker-callback.js +4 -0
- package/src/solver-tools/callbacks/iter-checker-callback.js.map +1 -1
- package/src/solver-tools/callbacks/iter-checker-callback.ts +4 -0
- package/src/solver-tools/callbacks/time-checker-callback.js +4 -0
- package/src/solver-tools/callbacks/time-checker-callback.js.map +1 -1
- package/src/solver-tools/callbacks/time-checker-callback.ts +4 -0
- package/src/solver-tools/index.js +9 -0
- package/src/solver-tools/index.js.map +1 -1
- package/src/solver-tools/index.ts +9 -0
- package/src/solver-tools/lsoda/blas.js +246 -0
- package/src/solver-tools/lsoda/blas.js.map +1 -0
- package/src/solver-tools/lsoda/blas.ts +267 -0
- package/src/solver-tools/lsoda/cfode.js +73 -0
- package/src/solver-tools/lsoda/cfode.js.map +1 -0
- package/src/solver-tools/lsoda/cfode.ts +83 -0
- package/src/solver-tools/lsoda/common.js +94 -0
- package/src/solver-tools/lsoda/common.js.map +1 -0
- package/src/solver-tools/lsoda/common.ts +135 -0
- package/src/solver-tools/lsoda/corfailure.js +25 -0
- package/src/solver-tools/lsoda/corfailure.js.map +1 -0
- package/src/solver-tools/lsoda/corfailure.ts +30 -0
- package/src/solver-tools/lsoda/correction.js +101 -0
- package/src/solver-tools/lsoda/correction.js.map +1 -0
- package/src/solver-tools/lsoda/correction.ts +119 -0
- package/src/solver-tools/lsoda/dense.js +110 -0
- package/src/solver-tools/lsoda/dense.js.map +1 -0
- package/src/solver-tools/lsoda/dense.ts +129 -0
- package/src/solver-tools/lsoda/index.js +4 -0
- package/src/solver-tools/lsoda/index.js.map +1 -0
- package/src/solver-tools/lsoda/index.ts +5 -0
- package/src/solver-tools/lsoda/intdy.js +43 -0
- package/src/solver-tools/lsoda/intdy.js.map +1 -0
- package/src/solver-tools/lsoda/intdy.ts +50 -0
- package/src/solver-tools/lsoda/lsoda.js +567 -0
- package/src/solver-tools/lsoda/lsoda.js.map +1 -0
- package/src/solver-tools/lsoda/lsoda.ts +632 -0
- package/src/solver-tools/lsoda/methodswitch.js +97 -0
- package/src/solver-tools/lsoda/methodswitch.js.map +1 -0
- package/src/solver-tools/lsoda/methodswitch.ts +107 -0
- package/src/solver-tools/lsoda/orderswitch.js +86 -0
- package/src/solver-tools/lsoda/orderswitch.js.map +1 -0
- package/src/solver-tools/lsoda/orderswitch.ts +95 -0
- package/src/solver-tools/lsoda/prja.js +43 -0
- package/src/solver-tools/lsoda/prja.js.map +1 -0
- package/src/solver-tools/lsoda/prja.ts +49 -0
- package/src/solver-tools/lsoda/scaleh.js +30 -0
- package/src/solver-tools/lsoda/scaleh.js.map +1 -0
- package/src/solver-tools/lsoda/scaleh.ts +33 -0
- package/src/solver-tools/lsoda/solsy.js +14 -0
- package/src/solver-tools/lsoda/solsy.js.map +1 -0
- package/src/solver-tools/lsoda/solsy.ts +18 -0
- package/src/solver-tools/lsoda/stoda.js +259 -0
- package/src/solver-tools/lsoda/stoda.js.map +1 -0
- package/src/solver-tools/lsoda/stoda.ts +286 -0
- package/src/solver-tools/lsoda-method.js +120 -0
- package/src/solver-tools/lsoda-method.js.map +1 -0
- package/src/solver-tools/lsoda-method.ts +136 -0
- package/src/solver-tools/mrt-method.js +121 -19
- package/src/solver-tools/mrt-method.js.map +1 -1
- package/src/solver-tools/mrt-method.ts +151 -22
- package/src/solver-tools/rk3-method.js +210 -0
- package/src/solver-tools/rk3-method.js.map +1 -0
- package/src/solver-tools/rk3-method.ts +257 -0
- package/src/solver-tools/rk4-method.js +236 -0
- package/src/solver-tools/rk4-method.js.map +1 -0
- package/src/solver-tools/rk4-method.ts +286 -0
- package/src/solver-tools/rkdp-method.js +247 -0
- package/src/solver-tools/rkdp-method.js.map +1 -0
- package/src/solver-tools/rkdp-method.ts +300 -0
- package/src/solver-tools/ros34prw-method.js +40 -2
- package/src/solver-tools/ros34prw-method.js.map +1 -1
- package/src/solver-tools/ros34prw-method.ts +40 -2
- package/src/solver-tools/ros3prw-method.js +40 -2
- package/src/solver-tools/ros3prw-method.js.map +1 -1
- package/src/solver-tools/ros3prw-method.ts +40 -2
- package/src/solver-tools/solver-defs.js +15 -3
- package/src/solver-tools/solver-defs.js.map +1 -1
- package/src/solver-tools/solver-defs.ts +91 -7
- package/src/tests/correctness.test.js +6 -4
- package/src/tests/correctness.test.js.map +1 -1
- package/src/tests/correctness.test.ts +6 -4
- package/src/tests/lsoda-lib-correctness.test.js +223 -0
- package/src/tests/lsoda-lib-correctness.test.js.map +1 -0
- package/src/tests/lsoda-lib-correctness.test.ts +283 -0
- package/src/tests/lsoda-lib-performance.test.js +95 -0
- package/src/tests/lsoda-lib-performance.test.js.map +1 -0
- package/src/tests/lsoda-lib-performance.test.ts +126 -0
- package/src/tests/performance.test.js +10 -8
- package/src/tests/performance.test.js.map +1 -1
- package/src/tests/performance.test.ts +10 -8
- package/src/tests/test-defs.js +14 -1
- package/src/tests/test-defs.js.map +1 -1
- package/src/tests/test-defs.ts +15 -1
- package/src/worker-tools/scripting.js +95 -1
- package/src/worker-tools/scripting.js.map +1 -1
- package/src/worker-tools/scripting.ts +104 -2
- package/src/worker-tools/solving.js +18 -2
- package/src/worker-tools/solving.js.map +1 -1
- package/src/worker-tools/solving.ts +25 -2
- package/typedoc.json +8 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import {Lsoda} from '../solver-tools/lsoda';
|
|
2
|
+
import {ODEs} from '../../index';
|
|
3
|
+
import {robertson, robertsonReferencePoint} from '../examples/robertson';
|
|
4
|
+
import {hires, hiresReferencePoint} from '../examples/hires';
|
|
5
|
+
import {vdpol, vdpolReferencePoint} from '../examples/vdpol';
|
|
6
|
+
import {orego, oregoReferencePoint} from '../examples/orego';
|
|
7
|
+
import {e5, e5ReferencePoint} from '../examples/e5';
|
|
8
|
+
import {pollution, pollutionReferencePoint} from '../examples/pollution';
|
|
9
|
+
|
|
10
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
/** Wraps an ODEs func into an OdeFunction compatible with Lsoda (returns 0). */
|
|
13
|
+
function wrapFunc(ode: ODEs): (t: number, y: Float64Array, ydot: Float64Array) => number {
|
|
14
|
+
return (t, y, ydot) => {
|
|
15
|
+
ode.func(t, y, ydot);
|
|
16
|
+
return 0;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface SolverOpts {
|
|
21
|
+
mxstep?: number;
|
|
22
|
+
hmax?: number;
|
|
23
|
+
rtol?: Float64Array;
|
|
24
|
+
atol?: Float64Array;
|
|
25
|
+
/** Small initial tout to bootstrap very stiff problems before the main loop. */
|
|
26
|
+
warmupTout?: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Solves a benchmark problem, checks accuracy against the reference point, and verifies solver health. */
|
|
30
|
+
function solveBenchmarkAndCheck(
|
|
31
|
+
ode: ODEs, referencePoint: Float64Array, relTol: number, absTol: number, opts?: SolverOpts,
|
|
32
|
+
): void {
|
|
33
|
+
const neq = ode.initial.length;
|
|
34
|
+
const tol = ode.tolerance;
|
|
35
|
+
const rtol = opts?.rtol ?? new Float64Array(neq).fill(tol);
|
|
36
|
+
const atol = opts?.atol ?? new Float64Array(neq).fill(tol);
|
|
37
|
+
|
|
38
|
+
const solver = new Lsoda(wrapFunc(ode), neq, {
|
|
39
|
+
rtol, atol, itask: 1,
|
|
40
|
+
...(opts?.mxstep ? {mxstep: opts.mxstep} : {}),
|
|
41
|
+
...(opts?.hmax ? {hmax: opts.hmax} : {}),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
let y: ArrayLike<number> = [...ode.initial];
|
|
45
|
+
let t = ode.arg.start;
|
|
46
|
+
const step = ode.arg.step;
|
|
47
|
+
const finish = ode.arg.finish;
|
|
48
|
+
|
|
49
|
+
// Warmup phase: bootstrap very stiff problems with a small initial tout
|
|
50
|
+
if (opts?.warmupTout !== undefined) {
|
|
51
|
+
const result = solver.solve(y, t, opts.warmupTout);
|
|
52
|
+
y = result.y;
|
|
53
|
+
t = result.t;
|
|
54
|
+
expect(solver.state).toBeGreaterThan(0);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let tout = t + step;
|
|
58
|
+
while (tout <= finish + step / 2) {
|
|
59
|
+
const result = solver.solve(y, t, tout);
|
|
60
|
+
y = result.y;
|
|
61
|
+
t = result.t;
|
|
62
|
+
|
|
63
|
+
if (solver.state <= 0)
|
|
64
|
+
throw new Error(`${ode.name}: solver failed at t=${t} with state=${solver.state}, error: ${solver.error}`);
|
|
65
|
+
|
|
66
|
+
tout += step;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Check final solution against reference point
|
|
70
|
+
for (let j = 0; j < neq; j++) {
|
|
71
|
+
const absErr = Math.abs(y[j] - referencePoint[j]);
|
|
72
|
+
const allowed = relTol * Math.abs(referencePoint[j]) + absTol;
|
|
73
|
+
expect(absErr).toBeLessThan(allowed);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ─── Performance tests ──────────────────────────────────────────────────────
|
|
78
|
+
|
|
79
|
+
// Robertson: components span many orders of magnitude; use component-wise atol
|
|
80
|
+
describe('Robertson', () => {
|
|
81
|
+
it('should solve correctly', () => {
|
|
82
|
+
solveBenchmarkAndCheck(robertson, robertsonReferencePoint, 1e-2, 1e-7, {
|
|
83
|
+
mxstep: 50000,
|
|
84
|
+
atol: new Float64Array([1e-8, 1e-14, 1e-8]),
|
|
85
|
+
rtol: new Float64Array([1e-7, 1e-7, 1e-7]),
|
|
86
|
+
});
|
|
87
|
+
}, 60000);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('HIRES', () => {
|
|
91
|
+
it('should solve correctly', () => {
|
|
92
|
+
solveBenchmarkAndCheck(hires, hiresReferencePoint, 1e-3, 1e-12);
|
|
93
|
+
}, 60000);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Van der Pol (mu=1000): very stiff, needs many internal steps
|
|
97
|
+
describe('van der Pol', () => {
|
|
98
|
+
it('should solve correctly', () => {
|
|
99
|
+
solveBenchmarkAndCheck(vdpol, vdpolReferencePoint, 1e-3, 1e-6, {
|
|
100
|
+
mxstep: 50000,
|
|
101
|
+
});
|
|
102
|
+
}, 60000);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe('OREGO', () => {
|
|
106
|
+
it('should solve correctly', () => {
|
|
107
|
+
solveBenchmarkAndCheck(orego, oregoReferencePoint, 1e-2, 1e-6);
|
|
108
|
+
}, 60000);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// E5: extremely stiff (rate constants span 20 orders), needs warmup and many steps.
|
|
112
|
+
// Reference values are near-zero (y1~1e-290, y2~1e-22), so absTol must be generous.
|
|
113
|
+
describe('E5', () => {
|
|
114
|
+
it('should solve correctly', () => {
|
|
115
|
+
solveBenchmarkAndCheck(e5, e5ReferencePoint, 1, 1e-6, {
|
|
116
|
+
mxstep: 50000,
|
|
117
|
+
warmupTout: 1e-5,
|
|
118
|
+
});
|
|
119
|
+
}, 60000);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe('Pollution', () => {
|
|
123
|
+
it('should solve correctly', () => {
|
|
124
|
+
solveBenchmarkAndCheck(pollution, pollutionReferencePoint, 1e-2, 1e-10);
|
|
125
|
+
}, 60000);
|
|
126
|
+
});
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
// Performance tests
|
|
2
2
|
import { perfProbs } from '../../index';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
import { implicitMethods, TIMEOUT_MS } from './test-defs';
|
|
4
|
+
implicitMethods.forEach((method, name) => {
|
|
5
|
+
describe(`${name}`, () => {
|
|
6
|
+
perfProbs.forEach((odes) => {
|
|
7
|
+
test(`${odes.name}`, () => {
|
|
8
|
+
const start = performance.now();
|
|
9
|
+
method(odes);
|
|
10
|
+
const elapsed = performance.now() - start;
|
|
11
|
+
expect(elapsed).toBeLessThan(TIMEOUT_MS);
|
|
12
|
+
});
|
|
11
13
|
});
|
|
12
14
|
});
|
|
13
15
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performance.test.js","sourceRoot":"","sources":["performance.test.ts"],"names":[],"mappings":"AAAA,oBAAoB;AAEpB,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"performance.test.js","sourceRoot":"","sources":["performance.test.ts"],"names":[],"mappings":"AAAA,oBAAoB;AAEpB,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,eAAe,EAAE,UAAU,EAAC,MAAM,aAAa,CAAC;AAExD,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;IACvC,QAAQ,CAAC,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE;QACvB,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE;gBACxB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACb,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;gBAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
// Performance tests
|
|
2
2
|
|
|
3
3
|
import {perfProbs} from '../../index';
|
|
4
|
-
import {
|
|
4
|
+
import {implicitMethods, TIMEOUT_MS} from './test-defs';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
implicitMethods.forEach((method, name) => {
|
|
7
|
+
describe(`${name}`, () => {
|
|
8
|
+
perfProbs.forEach((odes) => {
|
|
9
|
+
test(`${odes.name}`, () => {
|
|
10
|
+
const start = performance.now();
|
|
11
|
+
method(odes);
|
|
12
|
+
const elapsed = performance.now() - start;
|
|
13
|
+
expect(elapsed).toBeLessThan(TIMEOUT_MS);
|
|
14
|
+
});
|
|
13
15
|
});
|
|
14
16
|
});
|
|
15
17
|
});
|
package/src/tests/test-defs.js
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
/* eslint-disable max-len */
|
|
2
|
-
import { mrt, ros3prw, ros34prw } from '../../index';
|
|
2
|
+
import { mrt, ros3prw, ros34prw, rk4, ab5, ab4, rkdp, rk3, lsoda } from '../../index';
|
|
3
3
|
export const methods = new Map([
|
|
4
4
|
['MRT', mrt],
|
|
5
5
|
['ROS3PRw', ros3prw],
|
|
6
6
|
['ROS34PRw', ros34prw],
|
|
7
|
+
['RK4', rk4],
|
|
8
|
+
['AB5', ab5],
|
|
9
|
+
['AB4', ab4],
|
|
10
|
+
['RKDP', rkdp],
|
|
11
|
+
['RK3', rk3],
|
|
12
|
+
['LSODA', lsoda],
|
|
13
|
+
]);
|
|
14
|
+
/** Implicit methods suitable for stiff performance benchmarks */
|
|
15
|
+
export const implicitMethods = new Map([
|
|
16
|
+
['MRT', mrt],
|
|
17
|
+
['ROS3PRw', ros3prw],
|
|
18
|
+
['ROS34PRw', ros34prw],
|
|
19
|
+
['LSODA', lsoda],
|
|
7
20
|
]);
|
|
8
21
|
export const MAX_MAD = 0.1;
|
|
9
22
|
export const TIMEOUT_MS = 10000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-defs.js","sourceRoot":"","sources":["test-defs.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,OAAO,EAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"test-defs.js","sourceRoot":"","sources":["test-defs.ts"],"names":[],"mappings":"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"}
|
package/src/tests/test-defs.ts
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
/* eslint-disable max-len */
|
|
2
|
-
import {mrt, ros3prw, ros34prw} from '../../index';
|
|
2
|
+
import {mrt, ros3prw, ros34prw, rk4, ab5, ab4, rkdp, rk3, lsoda} from '../../index';
|
|
3
3
|
|
|
4
4
|
export const methods = new Map([
|
|
5
5
|
['MRT', mrt],
|
|
6
6
|
['ROS3PRw', ros3prw],
|
|
7
7
|
['ROS34PRw', ros34prw],
|
|
8
|
+
['RK4', rk4],
|
|
9
|
+
['AB5', ab5],
|
|
10
|
+
['AB4', ab4],
|
|
11
|
+
['RKDP', rkdp],
|
|
12
|
+
['RK3', rk3],
|
|
13
|
+
['LSODA', lsoda],
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
/** Implicit methods suitable for stiff performance benchmarks */
|
|
17
|
+
export const implicitMethods = new Map([
|
|
18
|
+
['MRT', mrt],
|
|
19
|
+
['ROS3PRw', ros3prw],
|
|
20
|
+
['ROS34PRw', ros34prw],
|
|
21
|
+
['LSODA', lsoda],
|
|
8
22
|
]);
|
|
9
23
|
|
|
10
24
|
export const MAX_MAD = 0.1;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
1
2
|
// Scripting tools for solving IVPs in web-workers
|
|
2
3
|
import { MATH_CONSTS, POW_IDX, MATH_FUNCS } from '../scripting-tools/scripting-tools';
|
|
3
4
|
const DEFAULT_METHOD = 'ros34prw';
|
|
@@ -45,7 +46,100 @@ function getFuncMainBody(ivp) {
|
|
|
45
46
|
ivp.deqs.solutionNames.forEach((name, idx) => lines.push(`arguments[2][${idx}] = ${ivp.deqs.equations.get(name)};`));
|
|
46
47
|
return lines.join('\n');
|
|
47
48
|
}
|
|
48
|
-
/** Return IVP-structure to be passed to web-worker
|
|
49
|
+
/** Return IVP-structure to be passed to web-worker
|
|
50
|
+
* @param ivp - initial value problem to be solved
|
|
51
|
+
* @example
|
|
52
|
+
* // Here, we consider modeling queues: https://en.wikipedia.org/wiki/M/M/c_queue
|
|
53
|
+
* import * as DGL from 'diff-grok';
|
|
54
|
+
*
|
|
55
|
+
* // 1. Model specification: the M|M|2|2 model
|
|
56
|
+
* const model = `#name: M|M|2|2
|
|
57
|
+
* #description: Modelling the system with two servers & two waiting places (EXPLAINED)
|
|
58
|
+
*
|
|
59
|
+
* #equations:
|
|
60
|
+
* dp0/dt = -la * p0 + mu * p1
|
|
61
|
+
* dp1/dt = la * p0 - (la + mu) * p1 + 2 * mu * p2
|
|
62
|
+
* dp2/dt = la * p1 - (la + 2 * mu) * p2 + 2 * mu * p3
|
|
63
|
+
* dp3/dt = la * p2 - (la + 2 * mu) * p3 + 2 * mu * p4
|
|
64
|
+
*
|
|
65
|
+
* #expressions:
|
|
66
|
+
* la = 1 / arrival
|
|
67
|
+
* mu = 1 / service
|
|
68
|
+
* p4 = 1 - p0 - p1 - p2 - p3
|
|
69
|
+
* busy = 1 - p0 - p1
|
|
70
|
+
* queue = p3 + 2 * p4
|
|
71
|
+
*
|
|
72
|
+
* #argument: t
|
|
73
|
+
* _t0 = 0 {min: 0; max: 10; caption: start; category: Time; units: min} [Initial time of simulation]
|
|
74
|
+
* _t1 = 60 {min: 20; max: 100; caption: finish; category: Time; units: min} [Final time of simulation]
|
|
75
|
+
* _h = 1 {min: 0.01; max: 0.1; caption: step; category: Time; units: min} [Time step of simulation]
|
|
76
|
+
*
|
|
77
|
+
* #inits:
|
|
78
|
+
* p0 = 1 {min: 0; max: 1; category: Initial state; caption: empty} [Probability that initially there are NO customers]
|
|
79
|
+
* p1 = 0 {min: 0; max: 1; category: Initial state; caption: single} [Probability that initially there is ONE customer]
|
|
80
|
+
* p2 = 0 {min: 0; max: 1; category: Initial state; caption: two} [Probability that initially there are TWO customers]
|
|
81
|
+
* p3 = 0 {min: 0; max: 1; category: Initial state; caption: three} [Probability that initially there are THREE customers]
|
|
82
|
+
*
|
|
83
|
+
* #output:
|
|
84
|
+
* t {caption: Time, min}
|
|
85
|
+
* p0 {caption: P(Empty)}
|
|
86
|
+
* busy {caption: P(Full load)}
|
|
87
|
+
* queue {caption: E(Queue)}
|
|
88
|
+
*
|
|
89
|
+
* #parameters:
|
|
90
|
+
* arrival = 10 {min: 1; max: 100; category: Means; caption: arrival; units: min} [Mean arrival time]
|
|
91
|
+
* service = 100 {min: 1; max: 100; category: Means; caption: service; units: min} [Mean service time]`;
|
|
92
|
+
*
|
|
93
|
+
* // 2. Generate IVP-objects: for the main thread & for computations in webworkers
|
|
94
|
+
* const ivp = DGL.getIVP(model);
|
|
95
|
+
* const ivpWW = DGL.getIvp2WebWorker(ivp);
|
|
96
|
+
*
|
|
97
|
+
* // 3. Perform computations
|
|
98
|
+
* try {
|
|
99
|
+
* // 3.1) Extract names of outputs
|
|
100
|
+
* const outputNames = DGL.getOutputNames(ivp);
|
|
101
|
+
* const outSize = outputNames.length;
|
|
102
|
+
*
|
|
103
|
+
* // 3.2) Set model inputs
|
|
104
|
+
* const inputs = {
|
|
105
|
+
* _t0: 0, // Initial time of simulation
|
|
106
|
+
* _t1: 60, // Final time of simulation
|
|
107
|
+
* _h: 1, // Time step of simulation
|
|
108
|
+
* p0: 1, // Probability that initially there are NO customers
|
|
109
|
+
* p1: 0, // Probability that initially there is ONE customer
|
|
110
|
+
* p2: 0, // Probability that initially there are TWO customers
|
|
111
|
+
* p3: 0, // Probability that initially there are THREE customers
|
|
112
|
+
* arrival: 10, // Mean arrival time
|
|
113
|
+
* service: 100, // Mean service time
|
|
114
|
+
* };
|
|
115
|
+
* const inputVector = DGL.getInputVector(inputs, ivp);
|
|
116
|
+
*
|
|
117
|
+
* // 3.3) Create a pipeline
|
|
118
|
+
* const creator = DGL.getPipelineCreator(ivp);
|
|
119
|
+
* const pipeline = creator.getPipeline(inputVector);
|
|
120
|
+
*
|
|
121
|
+
* // 3.4) Apply pipeline to perform computations
|
|
122
|
+
* const solution = DGL.applyPipeline(pipeline, ivpWW, inputVector);
|
|
123
|
+
* // 3.5) Print results
|
|
124
|
+
*
|
|
125
|
+
* // 3.5.1) Table header
|
|
126
|
+
* let line = '';
|
|
127
|
+
* outputNames.forEach((name) => line += name + ' ');
|
|
128
|
+
* console.log(line);
|
|
129
|
+
*
|
|
130
|
+
* // 3.5.2) Table with solution
|
|
131
|
+
* const length = solution[0].length;
|
|
132
|
+
* for (let i = 0; i < length; ++i) {
|
|
133
|
+
* line = '';
|
|
134
|
+
*
|
|
135
|
+
* for (let j = 0; j < outSize; ++j)
|
|
136
|
+
* line += solution[j][i].toFixed(8) + ' ';
|
|
137
|
+
* console.log(line);
|
|
138
|
+
* }
|
|
139
|
+
* } catch (err) {
|
|
140
|
+
* console.log('Simulation failed: ', err instanceof Error ? err.message : 'Unknown problem!');
|
|
141
|
+
* }
|
|
142
|
+
*/
|
|
49
143
|
export function getIvp2WebWorker(ivp) {
|
|
50
144
|
const paramNames = [];
|
|
51
145
|
if (ivp.params !== null)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scripting.js","sourceRoot":"","sources":["scripting.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAElD,OAAO,EAAM,WAAW,EAAE,OAAO,EAAE,UAAU,EAAC,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"scripting.js","sourceRoot":"","sources":["scripting.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,kDAAkD;AAElD,OAAO,EAAM,WAAW,EAAE,OAAO,EAAE,UAAU,EAAC,MAAM,oCAAoC,CAAC;AAoBzF,MAAM,cAAc,GAAG,UAAU,CAAC;AAClC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAElC,4BAA4B;AAC5B,SAAS,aAAa,CAAC,IAAY;IACjC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI;aACzB,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;aACpB,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC;aAC7B,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC;aACnC,OAAO,CAAC,eAAe,EAAE,iBAAiB,CAAC;aAC3C,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CACnB,CAAC;QAEF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO;YACL,MAAM,EAAE,cAAc;YACtB,SAAS,EAAE,mBAAmB;SAC/B,CAAC;IACJ,CAAC;AACH,CAAC;AAED,4DAA4D;AAC5D,SAAS,eAAe,CAAC,GAAQ;IAC/B,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,kBAAkB;IAClB,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAChC,IAAI,GAAG,KAAK,OAAO;YACjB,KAAK,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,GAAG,CAAC,kBAAkB,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;;YAE5E,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,mBAAmB;IACnB,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,WAAW,CAAC,GAAG,CAAC,WAAW,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAEzG,kBAAkB;IAClB,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI;QACrB,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,MAAM,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAErF,gCAAgC;IAChC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,CAAC;IACpD,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,mBAAmB,GAAG,IAAI,CAAC,CAAC,CAAC;IAEnG,uBAAuB;IACvB,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI;QACpB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;IAE9E,iBAAiB;IACjB,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAErH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAQ;IACvC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI;QACrB,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEzD,MAAM,KAAK,GAAkB;QAC3B,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;QAChC,UAAU,EAAE,aAAa,CAAC,GAAG,CAAC,cAAc,CAAC;QAC7C,YAAY,EAAE,eAAe,CAAC,GAAG,CAAC;QAClC,UAAU,EAAE,UAAU;QACtB,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM;KACzC,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,OAAO,CAAC,GAAkB,EAAE,SAAuB;IACjE,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,MAAM,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAExF,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
1
2
|
// Scripting tools for solving IVPs in web-workers
|
|
2
3
|
|
|
3
4
|
import {IVP, MATH_CONSTS, POW_IDX, MATH_FUNCS} from '../scripting-tools/scripting-tools';
|
|
4
5
|
import {SolverOptions} from '../solver-tools/solver-defs';
|
|
5
6
|
|
|
6
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Represents a fully parsed simulation prepared for execution in Web Workers.
|
|
9
|
+
*
|
|
10
|
+
* @property deqsCount - The number of differential equations in the system.
|
|
11
|
+
* @property funcMainBody - The main body of the function implementing the ODE system.
|
|
12
|
+
* @property paramNames - Names of the model parameters.
|
|
13
|
+
* @property solverOpts - Configuration options for the numerical solver (partial).
|
|
14
|
+
* @property tolerance - Tolerance for the numerical solver.
|
|
15
|
+
*/
|
|
7
16
|
export type IVP2WebWorker = {
|
|
8
17
|
tolerance: number,
|
|
9
18
|
solverOpts: Partial<SolverOptions>,
|
|
@@ -68,7 +77,100 @@ function getFuncMainBody(ivp: IVP): string {
|
|
|
68
77
|
return lines.join('\n');
|
|
69
78
|
}
|
|
70
79
|
|
|
71
|
-
/** Return IVP-structure to be passed to web-worker
|
|
80
|
+
/** Return IVP-structure to be passed to web-worker
|
|
81
|
+
* @param ivp - initial value problem to be solved
|
|
82
|
+
* @example
|
|
83
|
+
* // Here, we consider modeling queues: https://en.wikipedia.org/wiki/M/M/c_queue
|
|
84
|
+
* import * as DGL from 'diff-grok';
|
|
85
|
+
*
|
|
86
|
+
* // 1. Model specification: the M|M|2|2 model
|
|
87
|
+
* const model = `#name: M|M|2|2
|
|
88
|
+
* #description: Modelling the system with two servers & two waiting places (EXPLAINED)
|
|
89
|
+
*
|
|
90
|
+
* #equations:
|
|
91
|
+
* dp0/dt = -la * p0 + mu * p1
|
|
92
|
+
* dp1/dt = la * p0 - (la + mu) * p1 + 2 * mu * p2
|
|
93
|
+
* dp2/dt = la * p1 - (la + 2 * mu) * p2 + 2 * mu * p3
|
|
94
|
+
* dp3/dt = la * p2 - (la + 2 * mu) * p3 + 2 * mu * p4
|
|
95
|
+
*
|
|
96
|
+
* #expressions:
|
|
97
|
+
* la = 1 / arrival
|
|
98
|
+
* mu = 1 / service
|
|
99
|
+
* p4 = 1 - p0 - p1 - p2 - p3
|
|
100
|
+
* busy = 1 - p0 - p1
|
|
101
|
+
* queue = p3 + 2 * p4
|
|
102
|
+
*
|
|
103
|
+
* #argument: t
|
|
104
|
+
* _t0 = 0 {min: 0; max: 10; caption: start; category: Time; units: min} [Initial time of simulation]
|
|
105
|
+
* _t1 = 60 {min: 20; max: 100; caption: finish; category: Time; units: min} [Final time of simulation]
|
|
106
|
+
* _h = 1 {min: 0.01; max: 0.1; caption: step; category: Time; units: min} [Time step of simulation]
|
|
107
|
+
*
|
|
108
|
+
* #inits:
|
|
109
|
+
* p0 = 1 {min: 0; max: 1; category: Initial state; caption: empty} [Probability that initially there are NO customers]
|
|
110
|
+
* p1 = 0 {min: 0; max: 1; category: Initial state; caption: single} [Probability that initially there is ONE customer]
|
|
111
|
+
* p2 = 0 {min: 0; max: 1; category: Initial state; caption: two} [Probability that initially there are TWO customers]
|
|
112
|
+
* p3 = 0 {min: 0; max: 1; category: Initial state; caption: three} [Probability that initially there are THREE customers]
|
|
113
|
+
*
|
|
114
|
+
* #output:
|
|
115
|
+
* t {caption: Time, min}
|
|
116
|
+
* p0 {caption: P(Empty)}
|
|
117
|
+
* busy {caption: P(Full load)}
|
|
118
|
+
* queue {caption: E(Queue)}
|
|
119
|
+
*
|
|
120
|
+
* #parameters:
|
|
121
|
+
* arrival = 10 {min: 1; max: 100; category: Means; caption: arrival; units: min} [Mean arrival time]
|
|
122
|
+
* service = 100 {min: 1; max: 100; category: Means; caption: service; units: min} [Mean service time]`;
|
|
123
|
+
*
|
|
124
|
+
* // 2. Generate IVP-objects: for the main thread & for computations in webworkers
|
|
125
|
+
* const ivp = DGL.getIVP(model);
|
|
126
|
+
* const ivpWW = DGL.getIvp2WebWorker(ivp);
|
|
127
|
+
*
|
|
128
|
+
* // 3. Perform computations
|
|
129
|
+
* try {
|
|
130
|
+
* // 3.1) Extract names of outputs
|
|
131
|
+
* const outputNames = DGL.getOutputNames(ivp);
|
|
132
|
+
* const outSize = outputNames.length;
|
|
133
|
+
*
|
|
134
|
+
* // 3.2) Set model inputs
|
|
135
|
+
* const inputs = {
|
|
136
|
+
* _t0: 0, // Initial time of simulation
|
|
137
|
+
* _t1: 60, // Final time of simulation
|
|
138
|
+
* _h: 1, // Time step of simulation
|
|
139
|
+
* p0: 1, // Probability that initially there are NO customers
|
|
140
|
+
* p1: 0, // Probability that initially there is ONE customer
|
|
141
|
+
* p2: 0, // Probability that initially there are TWO customers
|
|
142
|
+
* p3: 0, // Probability that initially there are THREE customers
|
|
143
|
+
* arrival: 10, // Mean arrival time
|
|
144
|
+
* service: 100, // Mean service time
|
|
145
|
+
* };
|
|
146
|
+
* const inputVector = DGL.getInputVector(inputs, ivp);
|
|
147
|
+
*
|
|
148
|
+
* // 3.3) Create a pipeline
|
|
149
|
+
* const creator = DGL.getPipelineCreator(ivp);
|
|
150
|
+
* const pipeline = creator.getPipeline(inputVector);
|
|
151
|
+
*
|
|
152
|
+
* // 3.4) Apply pipeline to perform computations
|
|
153
|
+
* const solution = DGL.applyPipeline(pipeline, ivpWW, inputVector);
|
|
154
|
+
* // 3.5) Print results
|
|
155
|
+
*
|
|
156
|
+
* // 3.5.1) Table header
|
|
157
|
+
* let line = '';
|
|
158
|
+
* outputNames.forEach((name) => line += name + ' ');
|
|
159
|
+
* console.log(line);
|
|
160
|
+
*
|
|
161
|
+
* // 3.5.2) Table with solution
|
|
162
|
+
* const length = solution[0].length;
|
|
163
|
+
* for (let i = 0; i < length; ++i) {
|
|
164
|
+
* line = '';
|
|
165
|
+
*
|
|
166
|
+
* for (let j = 0; j < outSize; ++j)
|
|
167
|
+
* line += solution[j][i].toFixed(8) + ' ';
|
|
168
|
+
* console.log(line);
|
|
169
|
+
* }
|
|
170
|
+
* } catch (err) {
|
|
171
|
+
* console.log('Simulation failed: ', err instanceof Error ? err.message : 'Unknown problem!');
|
|
172
|
+
* }
|
|
173
|
+
*/
|
|
72
174
|
export function getIvp2WebWorker(ivp: IVP): IVP2WebWorker {
|
|
73
175
|
const paramNames: string[] = [];
|
|
74
176
|
if (ivp.params !== null)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Tools for solving IVPs in web-workers
|
|
2
|
-
import { mrt, ros3prw, ros34prw, getCallback } from '../solver-tools';
|
|
2
|
+
import { mrt, ros3prw, ros34prw, getCallback, rk4, ab5, ab4, rkdp, rk3, lsoda } from '../solver-tools';
|
|
3
3
|
import { getFunc } from './scripting';
|
|
4
4
|
const ARG_INIT = 0;
|
|
5
5
|
const ARG_FINAL = 1;
|
|
@@ -12,6 +12,18 @@ function getMethod(name) {
|
|
|
12
12
|
return mrt;
|
|
13
13
|
case 'ros3prw':
|
|
14
14
|
return ros3prw;
|
|
15
|
+
case 'rk4':
|
|
16
|
+
return rk4;
|
|
17
|
+
case 'ab5':
|
|
18
|
+
return ab5;
|
|
19
|
+
case 'ab4':
|
|
20
|
+
return ab4;
|
|
21
|
+
case 'rkdp':
|
|
22
|
+
return rkdp;
|
|
23
|
+
case 'rk3':
|
|
24
|
+
return rk3;
|
|
25
|
+
case 'lsoda':
|
|
26
|
+
return lsoda;
|
|
15
27
|
default:
|
|
16
28
|
return ros34prw;
|
|
17
29
|
}
|
|
@@ -22,7 +34,11 @@ function checkInputs(ivp, inputs) {
|
|
|
22
34
|
if (expected > inputs.length)
|
|
23
35
|
throw new Error(`Incorrect inputs count, expected: ${expected}, current: ${inputs.length}`);
|
|
24
36
|
}
|
|
25
|
-
/** Return solution of IVP with a specified inputs
|
|
37
|
+
/** Return solution of IVP with a specified inputs
|
|
38
|
+
* @param ivp - initial value problem to be solved
|
|
39
|
+
* @param inputs - vector of input values
|
|
40
|
+
* @returns solution of the given initial value problem
|
|
41
|
+
*/
|
|
26
42
|
export function solveIvp(ivp, inputs) {
|
|
27
43
|
checkInputs(ivp, inputs);
|
|
28
44
|
const nonParamInputsCount = inputs.length - ivp.paramNames.length;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solving.js","sourceRoot":"","sources":["solving.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,OAAO,EAAe,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAQ,WAAW,EAAC,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"solving.js","sourceRoot":"","sources":["solving.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,OAAO,EAAe,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAQ,WAAW,EAC7D,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAC,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAgB,OAAO,EAAC,MAAM,aAAa,CAAC;AAEnD,MAAM,QAAQ,GAAG,CAAC,CAAC;AACnB,MAAM,SAAS,GAAG,CAAC,CAAC;AACpB,MAAM,QAAQ,GAAG,CAAC,CAAC;AACnB,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,oCAAoC;AACpC,SAAS,SAAS,CAAC,IAAwB;IACzC,QAAQ,IAAI,EAAE,CAAC;QACf,KAAK,KAAK;YACR,OAAO,GAAG,CAAC;QAEb,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC;QAEjB,KAAK,KAAK;YACR,OAAO,GAAG,CAAC;QAEb,KAAK,KAAK;YACR,OAAO,GAAG,CAAC;QAEb,KAAK,KAAK;YACR,OAAO,GAAG,CAAC;QAEb,KAAK,MAAM;YACT,OAAO,IAAI,CAAC;QAEd,KAAK,KAAK;YACR,OAAO,GAAG,CAAC;QAEb,KAAK,OAAO;YACV,OAAO,KAAK,CAAC;QAEf;YACE,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,gDAAgD;AAChD,SAAS,WAAW,CAAC,GAAkB,EAAE,MAAoB;IAC3D,MAAM,QAAQ,GAAG,aAAa,GAAG,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;IAEvE,IAAI,QAAQ,GAAG,MAAM,CAAC,MAAM;QAC1B,MAAM,IAAI,KAAK,CAAC,qCAAqC,QAAQ,cAAc,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAChG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAkB,EAAE,MAAoB;IAC/D,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACzB,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;IAElE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,QAAQ,CAAS,CAAC;IAE5C,MAAM,IAAI,GAAS;QACjB,IAAI,EAAE,EAAE;QACR,GAAG,EAAE;YACH,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC;YACzB,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC;SACvB;QACD,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,mBAAmB,CAAC;QACxD,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,gBAAgB,EAAE,EAAE;KACrB,CAAC;IAEF,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAE7C,OAAO,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Tools for solving IVPs in web-workers
|
|
2
2
|
|
|
3
|
-
import {SolverMethod, mrt, ros3prw, ros34prw, ODEs, getCallback
|
|
3
|
+
import {SolverMethod, mrt, ros3prw, ros34prw, ODEs, getCallback,
|
|
4
|
+
rk4, ab5, ab4, rkdp, rk3, lsoda} from '../solver-tools';
|
|
4
5
|
import {Func} from '../solver-tools/solver-defs';
|
|
5
6
|
import {IVP2WebWorker, getFunc} from './scripting';
|
|
6
7
|
|
|
@@ -18,6 +19,24 @@ function getMethod(name: string | undefined): SolverMethod {
|
|
|
18
19
|
case 'ros3prw':
|
|
19
20
|
return ros3prw;
|
|
20
21
|
|
|
22
|
+
case 'rk4':
|
|
23
|
+
return rk4;
|
|
24
|
+
|
|
25
|
+
case 'ab5':
|
|
26
|
+
return ab5;
|
|
27
|
+
|
|
28
|
+
case 'ab4':
|
|
29
|
+
return ab4;
|
|
30
|
+
|
|
31
|
+
case 'rkdp':
|
|
32
|
+
return rkdp;
|
|
33
|
+
|
|
34
|
+
case 'rk3':
|
|
35
|
+
return rk3;
|
|
36
|
+
|
|
37
|
+
case 'lsoda':
|
|
38
|
+
return lsoda;
|
|
39
|
+
|
|
21
40
|
default:
|
|
22
41
|
return ros34prw;
|
|
23
42
|
}
|
|
@@ -31,7 +50,11 @@ function checkInputs(ivp: IVP2WebWorker, inputs: Float64Array): void {
|
|
|
31
50
|
throw new Error(`Incorrect inputs count, expected: ${expected}, current: ${inputs.length}`);
|
|
32
51
|
}
|
|
33
52
|
|
|
34
|
-
/** Return solution of IVP with a specified inputs
|
|
53
|
+
/** Return solution of IVP with a specified inputs
|
|
54
|
+
* @param ivp - initial value problem to be solved
|
|
55
|
+
* @param inputs - vector of input values
|
|
56
|
+
* @returns solution of the given initial value problem
|
|
57
|
+
*/
|
|
35
58
|
export function solveIvp(ivp: IVP2WebWorker, inputs: Float64Array): Float64Array[] {
|
|
36
59
|
checkInputs(ivp, inputs);
|
|
37
60
|
const nonParamInputsCount = inputs.length - ivp.paramNames.length;
|