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
package/src/pipeline/pipeline.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
1
2
|
import { solveIvp } from '../worker-tools';
|
|
2
3
|
import { BasicModelPipelineCreator } from './basic-pipeline-creator';
|
|
3
4
|
import { UpdatesModelPipelineCreator } from './updates-pipeline-creator';
|
|
@@ -9,7 +10,103 @@ function concat(arr1, arr2) {
|
|
|
9
10
|
result.set(arr2, arr1.length);
|
|
10
11
|
return result;
|
|
11
12
|
}
|
|
12
|
-
/** Apply pipeline to initial value problem with the source inputs, and return a solution
|
|
13
|
+
/** Apply pipeline to initial value problem with the source inputs, and return a solution
|
|
14
|
+
* @param pipeline - computational pipeleine
|
|
15
|
+
* @param ivp - initial value problem
|
|
16
|
+
* @param sourceInputs - source inputs of the model
|
|
17
|
+
* @returns the solution of the initial value problem
|
|
18
|
+
* @example
|
|
19
|
+
* // Here, we consider modeling queues: https://en.wikipedia.org/wiki/M/M/c_queue
|
|
20
|
+
* import * as DGL from 'diff-grok';
|
|
21
|
+
*
|
|
22
|
+
* // 1. Model specification: the M|M|2|2 model
|
|
23
|
+
* const model = `#name: M|M|2|2
|
|
24
|
+
* #description: Modelling the system with two servers & two waiting places (EXPLAINED)
|
|
25
|
+
*
|
|
26
|
+
* #equations:
|
|
27
|
+
* dp0/dt = -la * p0 + mu * p1
|
|
28
|
+
* dp1/dt = la * p0 - (la + mu) * p1 + 2 * mu * p2
|
|
29
|
+
* dp2/dt = la * p1 - (la + 2 * mu) * p2 + 2 * mu * p3
|
|
30
|
+
* dp3/dt = la * p2 - (la + 2 * mu) * p3 + 2 * mu * p4
|
|
31
|
+
*
|
|
32
|
+
* #expressions:
|
|
33
|
+
* la = 1 / arrival
|
|
34
|
+
* mu = 1 / service
|
|
35
|
+
* p4 = 1 - p0 - p1 - p2 - p3
|
|
36
|
+
* busy = 1 - p0 - p1
|
|
37
|
+
* queue = p3 + 2 * p4
|
|
38
|
+
*
|
|
39
|
+
* #argument: t
|
|
40
|
+
* _t0 = 0 {min: 0; max: 10; caption: start; category: Time; units: min} [Initial time of simulation]
|
|
41
|
+
* _t1 = 60 {min: 20; max: 100; caption: finish; category: Time; units: min} [Final time of simulation]
|
|
42
|
+
* _h = 1 {min: 0.01; max: 0.1; caption: step; category: Time; units: min} [Time step of simulation]
|
|
43
|
+
*
|
|
44
|
+
* #inits:
|
|
45
|
+
* p0 = 1 {min: 0; max: 1; category: Initial state; caption: empty} [Probability that initially there are NO customers]
|
|
46
|
+
* p1 = 0 {min: 0; max: 1; category: Initial state; caption: single} [Probability that initially there is ONE customer]
|
|
47
|
+
* p2 = 0 {min: 0; max: 1; category: Initial state; caption: two} [Probability that initially there are TWO customers]
|
|
48
|
+
* p3 = 0 {min: 0; max: 1; category: Initial state; caption: three} [Probability that initially there are THREE customers]
|
|
49
|
+
*
|
|
50
|
+
* #output:
|
|
51
|
+
* t {caption: Time, min}
|
|
52
|
+
* p0 {caption: P(Empty)}
|
|
53
|
+
* busy {caption: P(Full load)}
|
|
54
|
+
* queue {caption: E(Queue)}
|
|
55
|
+
*
|
|
56
|
+
* #parameters:
|
|
57
|
+
* arrival = 10 {min: 1; max: 100; category: Means; caption: arrival; units: min} [Mean arrival time]
|
|
58
|
+
* service = 100 {min: 1; max: 100; category: Means; caption: service; units: min} [Mean service time]`;
|
|
59
|
+
*
|
|
60
|
+
* // 2. Generate IVP-objects: for the main thread & for computations in webworkers
|
|
61
|
+
* const ivp = DGL.getIVP(model);
|
|
62
|
+
* const ivpWW = DGL.getIvp2WebWorker(ivp);
|
|
63
|
+
*
|
|
64
|
+
* // 3. Perform computations
|
|
65
|
+
* try {
|
|
66
|
+
* // 3.1) Extract names of outputs
|
|
67
|
+
* const outputNames = DGL.getOutputNames(ivp);
|
|
68
|
+
* const outSize = outputNames.length;
|
|
69
|
+
*
|
|
70
|
+
* // 3.2) Set model inputs
|
|
71
|
+
* const inputs = {
|
|
72
|
+
* _t0: 0, // Initial time of simulation
|
|
73
|
+
* _t1: 60, // Final time of simulation
|
|
74
|
+
* _h: 1, // Time step of simulation
|
|
75
|
+
* p0: 1, // Probability that initially there are NO customers
|
|
76
|
+
* p1: 0, // Probability that initially there is ONE customer
|
|
77
|
+
* p2: 0, // Probability that initially there are TWO customers
|
|
78
|
+
* p3: 0, // Probability that initially there are THREE customers
|
|
79
|
+
* arrival: 10, // Mean arrival time
|
|
80
|
+
* service: 100, // Mean service time
|
|
81
|
+
* };
|
|
82
|
+
* const inputVector = DGL.getInputVector(inputs, ivp);
|
|
83
|
+
*
|
|
84
|
+
* // 3.3) Create a pipeline
|
|
85
|
+
* const creator = DGL.getPipelineCreator(ivp);
|
|
86
|
+
* const pipeline = creator.getPipeline(inputVector);
|
|
87
|
+
*
|
|
88
|
+
* // 3.4) Apply pipeline to perform computations
|
|
89
|
+
* const solution = DGL.applyPipeline(pipeline, ivpWW, inputVector);
|
|
90
|
+
* // 3.5) Print results
|
|
91
|
+
*
|
|
92
|
+
* // 3.5.1) Table header
|
|
93
|
+
* let line = '';
|
|
94
|
+
* outputNames.forEach((name) => line += name + ' ');
|
|
95
|
+
* console.log(line);
|
|
96
|
+
*
|
|
97
|
+
* // 3.5.2) Table with solution
|
|
98
|
+
* const length = solution[0].length;
|
|
99
|
+
* for (let i = 0; i < length; ++i) {
|
|
100
|
+
* line = '';
|
|
101
|
+
*
|
|
102
|
+
* for (let j = 0; j < outSize; ++j)
|
|
103
|
+
* line += solution[j][i].toFixed(8) + ' ';
|
|
104
|
+
* console.log(line);
|
|
105
|
+
* }
|
|
106
|
+
* } catch (err) {
|
|
107
|
+
* console.log('Simulation failed: ', err instanceof Error ? err.message : 'Unknown problem!');
|
|
108
|
+
* }
|
|
109
|
+
*/
|
|
13
110
|
export function applyPipeline(pipeline, ivp, sourceInputs) {
|
|
14
111
|
let solution = [];
|
|
15
112
|
let currentSolution;
|
|
@@ -60,7 +157,101 @@ export function applyPipeline(pipeline, ivp, sourceInputs) {
|
|
|
60
157
|
}
|
|
61
158
|
return solution;
|
|
62
159
|
} // performPipeline
|
|
63
|
-
/** Return pipeline creator specified by the initial value problem
|
|
160
|
+
/** Return pipeline creator specified by the initial value problem
|
|
161
|
+
* @param ivp - initial value problem
|
|
162
|
+
* @returns a creator of computational pipeline corresponding to the given model
|
|
163
|
+
* @example
|
|
164
|
+
* // Here, we consider modeling queues: https://en.wikipedia.org/wiki/M/M/c_queue
|
|
165
|
+
* import * as DGL from 'diff-grok';
|
|
166
|
+
*
|
|
167
|
+
* // 1. Model specification: the M|M|2|2 model
|
|
168
|
+
* const model = `#name: M|M|2|2
|
|
169
|
+
* #description: Modelling the system with two servers & two waiting places (EXPLAINED)
|
|
170
|
+
*
|
|
171
|
+
* #equations:
|
|
172
|
+
* dp0/dt = -la * p0 + mu * p1
|
|
173
|
+
* dp1/dt = la * p0 - (la + mu) * p1 + 2 * mu * p2
|
|
174
|
+
* dp2/dt = la * p1 - (la + 2 * mu) * p2 + 2 * mu * p3
|
|
175
|
+
* dp3/dt = la * p2 - (la + 2 * mu) * p3 + 2 * mu * p4
|
|
176
|
+
*
|
|
177
|
+
* #expressions:
|
|
178
|
+
* la = 1 / arrival
|
|
179
|
+
* mu = 1 / service
|
|
180
|
+
* p4 = 1 - p0 - p1 - p2 - p3
|
|
181
|
+
* busy = 1 - p0 - p1
|
|
182
|
+
* queue = p3 + 2 * p4
|
|
183
|
+
*
|
|
184
|
+
* #argument: t
|
|
185
|
+
* _t0 = 0 {min: 0; max: 10; caption: start; category: Time; units: min} [Initial time of simulation]
|
|
186
|
+
* _t1 = 60 {min: 20; max: 100; caption: finish; category: Time; units: min} [Final time of simulation]
|
|
187
|
+
* _h = 1 {min: 0.01; max: 0.1; caption: step; category: Time; units: min} [Time step of simulation]
|
|
188
|
+
*
|
|
189
|
+
* #inits:
|
|
190
|
+
* p0 = 1 {min: 0; max: 1; category: Initial state; caption: empty} [Probability that initially there are NO customers]
|
|
191
|
+
* p1 = 0 {min: 0; max: 1; category: Initial state; caption: single} [Probability that initially there is ONE customer]
|
|
192
|
+
* p2 = 0 {min: 0; max: 1; category: Initial state; caption: two} [Probability that initially there are TWO customers]
|
|
193
|
+
* p3 = 0 {min: 0; max: 1; category: Initial state; caption: three} [Probability that initially there are THREE customers]
|
|
194
|
+
*
|
|
195
|
+
* #output:
|
|
196
|
+
* t {caption: Time, min}
|
|
197
|
+
* p0 {caption: P(Empty)}
|
|
198
|
+
* busy {caption: P(Full load)}
|
|
199
|
+
* queue {caption: E(Queue)}
|
|
200
|
+
*
|
|
201
|
+
* #parameters:
|
|
202
|
+
* arrival = 10 {min: 1; max: 100; category: Means; caption: arrival; units: min} [Mean arrival time]
|
|
203
|
+
* service = 100 {min: 1; max: 100; category: Means; caption: service; units: min} [Mean service time]`;
|
|
204
|
+
*
|
|
205
|
+
* // 2. Generate IVP-objects: for the main thread & for computations in webworkers
|
|
206
|
+
* const ivp = DGL.getIVP(model);
|
|
207
|
+
* const ivpWW = DGL.getIvp2WebWorker(ivp);
|
|
208
|
+
*
|
|
209
|
+
* // 3. Perform computations
|
|
210
|
+
* try {
|
|
211
|
+
* // 3.1) Extract names of outputs
|
|
212
|
+
* const outputNames = DGL.getOutputNames(ivp);
|
|
213
|
+
* const outSize = outputNames.length;
|
|
214
|
+
*
|
|
215
|
+
* // 3.2) Set model inputs
|
|
216
|
+
* const inputs = {
|
|
217
|
+
* _t0: 0, // Initial time of simulation
|
|
218
|
+
* _t1: 60, // Final time of simulation
|
|
219
|
+
* _h: 1, // Time step of simulation
|
|
220
|
+
* p0: 1, // Probability that initially there are NO customers
|
|
221
|
+
* p1: 0, // Probability that initially there is ONE customer
|
|
222
|
+
* p2: 0, // Probability that initially there are TWO customers
|
|
223
|
+
* p3: 0, // Probability that initially there are THREE customers
|
|
224
|
+
* arrival: 10, // Mean arrival time
|
|
225
|
+
* service: 100, // Mean service time
|
|
226
|
+
* };
|
|
227
|
+
* const inputVector = DGL.getInputVector(inputs, ivp);
|
|
228
|
+
*
|
|
229
|
+
* // 3.3) Create a pipeline
|
|
230
|
+
* const creator = DGL.getPipelineCreator(ivp);
|
|
231
|
+
* const pipeline = creator.getPipeline(inputVector);
|
|
232
|
+
*
|
|
233
|
+
* // 3.4) Apply pipeline to perform computations
|
|
234
|
+
* const solution = DGL.applyPipeline(pipeline, ivpWW, inputVector);
|
|
235
|
+
* // 3.5) Print results
|
|
236
|
+
*
|
|
237
|
+
* // 3.5.1) Table header
|
|
238
|
+
* let line = '';
|
|
239
|
+
* outputNames.forEach((name) => line += name + ' ');
|
|
240
|
+
* console.log(line);
|
|
241
|
+
*
|
|
242
|
+
* // 3.5.2) Table with solution
|
|
243
|
+
* const length = solution[0].length;
|
|
244
|
+
* for (let i = 0; i < length; ++i) {
|
|
245
|
+
* line = '';
|
|
246
|
+
*
|
|
247
|
+
* for (let j = 0; j < outSize; ++j)
|
|
248
|
+
* line += solution[j][i].toFixed(8) + ' ';
|
|
249
|
+
* console.log(line);
|
|
250
|
+
* }
|
|
251
|
+
* } catch (err) {
|
|
252
|
+
* console.log('Simulation failed: ', err instanceof Error ? err.message : 'Unknown problem!');
|
|
253
|
+
* }
|
|
254
|
+
*/
|
|
64
255
|
export function getPipelineCreator(ivp) {
|
|
65
256
|
if (ivp.updates !== null)
|
|
66
257
|
return new UpdatesModelPipelineCreator(ivp);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,QAAQ,EAAC,MAAM,iBAAiB,CAAC;AAExD,OAAO,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAC,2BAA2B,EAAC,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAC,0BAA0B,EAAC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["pipeline.ts"],"names":[],"mappings":"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"}
|
package/src/pipeline/pipeline.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
1
2
|
import {IVP2WebWorker, solveIvp} from '../worker-tools';
|
|
2
3
|
import {PipelineCreator} from './pipeline-creator';
|
|
3
4
|
import {BasicModelPipelineCreator} from './basic-pipeline-creator';
|
|
@@ -6,14 +7,25 @@ import {UpdatesModelPipelineCreator} from './updates-pipeline-creator';
|
|
|
6
7
|
import {CyclicModelPipelineCreator} from './loops-pipeline-creator';
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Represents a wrapper for a single modeling step in a multi-stage simulation.
|
|
12
|
+
*
|
|
13
|
+
* @property preproc - A preprocessing script for the step's inputs.
|
|
14
|
+
* @property postproc - A postprocessing script applied after the step is executed.
|
|
15
|
+
* @property out - A script that generates the output of the step.
|
|
16
|
+
*/
|
|
10
17
|
export type Wrapper = {
|
|
11
18
|
preproc: string | null,
|
|
12
19
|
out: string | null,
|
|
13
20
|
postproc: string | null,
|
|
14
21
|
};
|
|
15
22
|
|
|
16
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Represents a computational pipeline for multi-stage simulations.
|
|
25
|
+
*
|
|
26
|
+
* @property wrappers - An array of modeling steps (wrappers) that compose the pipeline.
|
|
27
|
+
* @property out - A script or specification that generates the final output of the pipeline.
|
|
28
|
+
*/
|
|
17
29
|
export type Pipeline = {
|
|
18
30
|
wrappers: Wrapper[],
|
|
19
31
|
out: string | null,
|
|
@@ -27,7 +39,103 @@ function concat(arr1: Float64Array, arr2: Float64Array): Float64Array {
|
|
|
27
39
|
return result;
|
|
28
40
|
}
|
|
29
41
|
|
|
30
|
-
/** Apply pipeline to initial value problem with the source inputs, and return a solution
|
|
42
|
+
/** Apply pipeline to initial value problem with the source inputs, and return a solution
|
|
43
|
+
* @param pipeline - computational pipeleine
|
|
44
|
+
* @param ivp - initial value problem
|
|
45
|
+
* @param sourceInputs - source inputs of the model
|
|
46
|
+
* @returns the solution of the initial value problem
|
|
47
|
+
* @example
|
|
48
|
+
* // Here, we consider modeling queues: https://en.wikipedia.org/wiki/M/M/c_queue
|
|
49
|
+
* import * as DGL from 'diff-grok';
|
|
50
|
+
*
|
|
51
|
+
* // 1. Model specification: the M|M|2|2 model
|
|
52
|
+
* const model = `#name: M|M|2|2
|
|
53
|
+
* #description: Modelling the system with two servers & two waiting places (EXPLAINED)
|
|
54
|
+
*
|
|
55
|
+
* #equations:
|
|
56
|
+
* dp0/dt = -la * p0 + mu * p1
|
|
57
|
+
* dp1/dt = la * p0 - (la + mu) * p1 + 2 * mu * p2
|
|
58
|
+
* dp2/dt = la * p1 - (la + 2 * mu) * p2 + 2 * mu * p3
|
|
59
|
+
* dp3/dt = la * p2 - (la + 2 * mu) * p3 + 2 * mu * p4
|
|
60
|
+
*
|
|
61
|
+
* #expressions:
|
|
62
|
+
* la = 1 / arrival
|
|
63
|
+
* mu = 1 / service
|
|
64
|
+
* p4 = 1 - p0 - p1 - p2 - p3
|
|
65
|
+
* busy = 1 - p0 - p1
|
|
66
|
+
* queue = p3 + 2 * p4
|
|
67
|
+
*
|
|
68
|
+
* #argument: t
|
|
69
|
+
* _t0 = 0 {min: 0; max: 10; caption: start; category: Time; units: min} [Initial time of simulation]
|
|
70
|
+
* _t1 = 60 {min: 20; max: 100; caption: finish; category: Time; units: min} [Final time of simulation]
|
|
71
|
+
* _h = 1 {min: 0.01; max: 0.1; caption: step; category: Time; units: min} [Time step of simulation]
|
|
72
|
+
*
|
|
73
|
+
* #inits:
|
|
74
|
+
* p0 = 1 {min: 0; max: 1; category: Initial state; caption: empty} [Probability that initially there are NO customers]
|
|
75
|
+
* p1 = 0 {min: 0; max: 1; category: Initial state; caption: single} [Probability that initially there is ONE customer]
|
|
76
|
+
* p2 = 0 {min: 0; max: 1; category: Initial state; caption: two} [Probability that initially there are TWO customers]
|
|
77
|
+
* p3 = 0 {min: 0; max: 1; category: Initial state; caption: three} [Probability that initially there are THREE customers]
|
|
78
|
+
*
|
|
79
|
+
* #output:
|
|
80
|
+
* t {caption: Time, min}
|
|
81
|
+
* p0 {caption: P(Empty)}
|
|
82
|
+
* busy {caption: P(Full load)}
|
|
83
|
+
* queue {caption: E(Queue)}
|
|
84
|
+
*
|
|
85
|
+
* #parameters:
|
|
86
|
+
* arrival = 10 {min: 1; max: 100; category: Means; caption: arrival; units: min} [Mean arrival time]
|
|
87
|
+
* service = 100 {min: 1; max: 100; category: Means; caption: service; units: min} [Mean service time]`;
|
|
88
|
+
*
|
|
89
|
+
* // 2. Generate IVP-objects: for the main thread & for computations in webworkers
|
|
90
|
+
* const ivp = DGL.getIVP(model);
|
|
91
|
+
* const ivpWW = DGL.getIvp2WebWorker(ivp);
|
|
92
|
+
*
|
|
93
|
+
* // 3. Perform computations
|
|
94
|
+
* try {
|
|
95
|
+
* // 3.1) Extract names of outputs
|
|
96
|
+
* const outputNames = DGL.getOutputNames(ivp);
|
|
97
|
+
* const outSize = outputNames.length;
|
|
98
|
+
*
|
|
99
|
+
* // 3.2) Set model inputs
|
|
100
|
+
* const inputs = {
|
|
101
|
+
* _t0: 0, // Initial time of simulation
|
|
102
|
+
* _t1: 60, // Final time of simulation
|
|
103
|
+
* _h: 1, // Time step of simulation
|
|
104
|
+
* p0: 1, // Probability that initially there are NO customers
|
|
105
|
+
* p1: 0, // Probability that initially there is ONE customer
|
|
106
|
+
* p2: 0, // Probability that initially there are TWO customers
|
|
107
|
+
* p3: 0, // Probability that initially there are THREE customers
|
|
108
|
+
* arrival: 10, // Mean arrival time
|
|
109
|
+
* service: 100, // Mean service time
|
|
110
|
+
* };
|
|
111
|
+
* const inputVector = DGL.getInputVector(inputs, ivp);
|
|
112
|
+
*
|
|
113
|
+
* // 3.3) Create a pipeline
|
|
114
|
+
* const creator = DGL.getPipelineCreator(ivp);
|
|
115
|
+
* const pipeline = creator.getPipeline(inputVector);
|
|
116
|
+
*
|
|
117
|
+
* // 3.4) Apply pipeline to perform computations
|
|
118
|
+
* const solution = DGL.applyPipeline(pipeline, ivpWW, inputVector);
|
|
119
|
+
* // 3.5) Print results
|
|
120
|
+
*
|
|
121
|
+
* // 3.5.1) Table header
|
|
122
|
+
* let line = '';
|
|
123
|
+
* outputNames.forEach((name) => line += name + ' ');
|
|
124
|
+
* console.log(line);
|
|
125
|
+
*
|
|
126
|
+
* // 3.5.2) Table with solution
|
|
127
|
+
* const length = solution[0].length;
|
|
128
|
+
* for (let i = 0; i < length; ++i) {
|
|
129
|
+
* line = '';
|
|
130
|
+
*
|
|
131
|
+
* for (let j = 0; j < outSize; ++j)
|
|
132
|
+
* line += solution[j][i].toFixed(8) + ' ';
|
|
133
|
+
* console.log(line);
|
|
134
|
+
* }
|
|
135
|
+
* } catch (err) {
|
|
136
|
+
* console.log('Simulation failed: ', err instanceof Error ? err.message : 'Unknown problem!');
|
|
137
|
+
* }
|
|
138
|
+
*/
|
|
31
139
|
export function applyPipeline(pipeline: Pipeline, ivp: IVP2WebWorker, sourceInputs: Float64Array): Float64Array[] {
|
|
32
140
|
let solution: Float64Array[] = [];
|
|
33
141
|
let currentSolution: Float64Array[];
|
|
@@ -92,7 +200,101 @@ export function applyPipeline(pipeline: Pipeline, ivp: IVP2WebWorker, sourceInpu
|
|
|
92
200
|
return solution;
|
|
93
201
|
} // performPipeline
|
|
94
202
|
|
|
95
|
-
/** Return pipeline creator specified by the initial value problem
|
|
203
|
+
/** Return pipeline creator specified by the initial value problem
|
|
204
|
+
* @param ivp - initial value problem
|
|
205
|
+
* @returns a creator of computational pipeline corresponding to the given model
|
|
206
|
+
* @example
|
|
207
|
+
* // Here, we consider modeling queues: https://en.wikipedia.org/wiki/M/M/c_queue
|
|
208
|
+
* import * as DGL from 'diff-grok';
|
|
209
|
+
*
|
|
210
|
+
* // 1. Model specification: the M|M|2|2 model
|
|
211
|
+
* const model = `#name: M|M|2|2
|
|
212
|
+
* #description: Modelling the system with two servers & two waiting places (EXPLAINED)
|
|
213
|
+
*
|
|
214
|
+
* #equations:
|
|
215
|
+
* dp0/dt = -la * p0 + mu * p1
|
|
216
|
+
* dp1/dt = la * p0 - (la + mu) * p1 + 2 * mu * p2
|
|
217
|
+
* dp2/dt = la * p1 - (la + 2 * mu) * p2 + 2 * mu * p3
|
|
218
|
+
* dp3/dt = la * p2 - (la + 2 * mu) * p3 + 2 * mu * p4
|
|
219
|
+
*
|
|
220
|
+
* #expressions:
|
|
221
|
+
* la = 1 / arrival
|
|
222
|
+
* mu = 1 / service
|
|
223
|
+
* p4 = 1 - p0 - p1 - p2 - p3
|
|
224
|
+
* busy = 1 - p0 - p1
|
|
225
|
+
* queue = p3 + 2 * p4
|
|
226
|
+
*
|
|
227
|
+
* #argument: t
|
|
228
|
+
* _t0 = 0 {min: 0; max: 10; caption: start; category: Time; units: min} [Initial time of simulation]
|
|
229
|
+
* _t1 = 60 {min: 20; max: 100; caption: finish; category: Time; units: min} [Final time of simulation]
|
|
230
|
+
* _h = 1 {min: 0.01; max: 0.1; caption: step; category: Time; units: min} [Time step of simulation]
|
|
231
|
+
*
|
|
232
|
+
* #inits:
|
|
233
|
+
* p0 = 1 {min: 0; max: 1; category: Initial state; caption: empty} [Probability that initially there are NO customers]
|
|
234
|
+
* p1 = 0 {min: 0; max: 1; category: Initial state; caption: single} [Probability that initially there is ONE customer]
|
|
235
|
+
* p2 = 0 {min: 0; max: 1; category: Initial state; caption: two} [Probability that initially there are TWO customers]
|
|
236
|
+
* p3 = 0 {min: 0; max: 1; category: Initial state; caption: three} [Probability that initially there are THREE customers]
|
|
237
|
+
*
|
|
238
|
+
* #output:
|
|
239
|
+
* t {caption: Time, min}
|
|
240
|
+
* p0 {caption: P(Empty)}
|
|
241
|
+
* busy {caption: P(Full load)}
|
|
242
|
+
* queue {caption: E(Queue)}
|
|
243
|
+
*
|
|
244
|
+
* #parameters:
|
|
245
|
+
* arrival = 10 {min: 1; max: 100; category: Means; caption: arrival; units: min} [Mean arrival time]
|
|
246
|
+
* service = 100 {min: 1; max: 100; category: Means; caption: service; units: min} [Mean service time]`;
|
|
247
|
+
*
|
|
248
|
+
* // 2. Generate IVP-objects: for the main thread & for computations in webworkers
|
|
249
|
+
* const ivp = DGL.getIVP(model);
|
|
250
|
+
* const ivpWW = DGL.getIvp2WebWorker(ivp);
|
|
251
|
+
*
|
|
252
|
+
* // 3. Perform computations
|
|
253
|
+
* try {
|
|
254
|
+
* // 3.1) Extract names of outputs
|
|
255
|
+
* const outputNames = DGL.getOutputNames(ivp);
|
|
256
|
+
* const outSize = outputNames.length;
|
|
257
|
+
*
|
|
258
|
+
* // 3.2) Set model inputs
|
|
259
|
+
* const inputs = {
|
|
260
|
+
* _t0: 0, // Initial time of simulation
|
|
261
|
+
* _t1: 60, // Final time of simulation
|
|
262
|
+
* _h: 1, // Time step of simulation
|
|
263
|
+
* p0: 1, // Probability that initially there are NO customers
|
|
264
|
+
* p1: 0, // Probability that initially there is ONE customer
|
|
265
|
+
* p2: 0, // Probability that initially there are TWO customers
|
|
266
|
+
* p3: 0, // Probability that initially there are THREE customers
|
|
267
|
+
* arrival: 10, // Mean arrival time
|
|
268
|
+
* service: 100, // Mean service time
|
|
269
|
+
* };
|
|
270
|
+
* const inputVector = DGL.getInputVector(inputs, ivp);
|
|
271
|
+
*
|
|
272
|
+
* // 3.3) Create a pipeline
|
|
273
|
+
* const creator = DGL.getPipelineCreator(ivp);
|
|
274
|
+
* const pipeline = creator.getPipeline(inputVector);
|
|
275
|
+
*
|
|
276
|
+
* // 3.4) Apply pipeline to perform computations
|
|
277
|
+
* const solution = DGL.applyPipeline(pipeline, ivpWW, inputVector);
|
|
278
|
+
* // 3.5) Print results
|
|
279
|
+
*
|
|
280
|
+
* // 3.5.1) Table header
|
|
281
|
+
* let line = '';
|
|
282
|
+
* outputNames.forEach((name) => line += name + ' ');
|
|
283
|
+
* console.log(line);
|
|
284
|
+
*
|
|
285
|
+
* // 3.5.2) Table with solution
|
|
286
|
+
* const length = solution[0].length;
|
|
287
|
+
* for (let i = 0; i < length; ++i) {
|
|
288
|
+
* line = '';
|
|
289
|
+
*
|
|
290
|
+
* for (let j = 0; j < outSize; ++j)
|
|
291
|
+
* line += solution[j][i].toFixed(8) + ' ';
|
|
292
|
+
* console.log(line);
|
|
293
|
+
* }
|
|
294
|
+
* } catch (err) {
|
|
295
|
+
* console.log('Simulation failed: ', err instanceof Error ? err.message : 'Unknown problem!');
|
|
296
|
+
* }
|
|
297
|
+
*/
|
|
96
298
|
export function getPipelineCreator(ivp: IVP): PipelineCreator {
|
|
97
299
|
if (ivp.updates !== null)
|
|
98
300
|
return new UpdatesModelPipelineCreator(ivp);
|
|
@@ -1,15 +1,143 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
1
2
|
import { MATH_CONSTS, MATH_FUNCS, POW_IDX } from '../scripting-tools/scripting-tools';
|
|
2
3
|
import { getOutputCode } from './output';
|
|
3
4
|
import { PipelineCreator } from './pipeline-creator';
|
|
4
5
|
import { argName2IdxMap, ARG, ARG_COL_IDX, CORRECTION_FACTOR, DEFAULT_CORRECTION } from './constants';
|
|
5
|
-
/** Pipeline creator for model with updates
|
|
6
|
+
/** Pipeline creator for model with updates
|
|
7
|
+
* @example
|
|
8
|
+
* // This example shows how to apply pipelines and models with updates.
|
|
9
|
+
* // This approach can be used for in-webworkers analysis of models.
|
|
10
|
+
* // Here, we consider gluconic acid (GA) production by Aspergillus niger modeling.
|
|
11
|
+
*
|
|
12
|
+
* import * as DGL from 'diff-grok';
|
|
13
|
+
*
|
|
14
|
+
* // 1. Model specification
|
|
15
|
+
* const model = `#name: GA-production
|
|
16
|
+
* #tags: model
|
|
17
|
+
* #description: Gluconic acid (GA) production by Aspergillus niger modeling
|
|
18
|
+
*
|
|
19
|
+
* #equations:
|
|
20
|
+
* dX/dt = rX
|
|
21
|
+
* dS/dt = -gamma * rX - lambda * X
|
|
22
|
+
* dO/dt = Kla * (Cod - O) - delta * rX - phi * X
|
|
23
|
+
* dP/dt = alpha * rX + beta * X
|
|
24
|
+
*
|
|
25
|
+
* #expressions:
|
|
26
|
+
* mu = muM * S / (Ks + S) * O / (Ko + O)
|
|
27
|
+
* rX = mu * X
|
|
28
|
+
*
|
|
29
|
+
* #argument: t, 1-st stage
|
|
30
|
+
* _t0 = 0 {units: h; caption: initial; category: Misc} [Start of the process]
|
|
31
|
+
* _t1 = 60 {units: h; caption: 1-st stage; category: Durations; min: 20; max: 80} [Duration of the 1-st stage]
|
|
32
|
+
* step = 0.1 {units: h; caption: step; category: Misc; min: 0.01; max: 1} [Time step of simulation]
|
|
33
|
+
*
|
|
34
|
+
* #update: 2-nd stage
|
|
35
|
+
* duration = overall - _t1
|
|
36
|
+
* S += 70
|
|
37
|
+
*
|
|
38
|
+
* #inits:
|
|
39
|
+
* X = 5 {units: kg/m³; caption: biomass; category: Initial concentrations; min: 1; max: 10} [Aspergillus niger biomass]
|
|
40
|
+
* S = 150 {units: kg/m³; caption: glucose; category: Initial concentrations; min: 50; max: 200} [Glucose]
|
|
41
|
+
* O = 7 {units: kg/m³; caption: oxygen; category: Initial concentrations; min: 1; max: 10} [Dissolved oxygen]
|
|
42
|
+
* P = 0 {units: kg/m³; caption: acid; category: Initial concentrations; min: 0; max: 0.1} [Gluconic acid]
|
|
43
|
+
*
|
|
44
|
+
* #output:
|
|
45
|
+
* t {caption: time}
|
|
46
|
+
* X {caption: biomass}
|
|
47
|
+
* S {caption: glucose}
|
|
48
|
+
* O {caption: oxygen}
|
|
49
|
+
* P {caption: acid}
|
|
50
|
+
*
|
|
51
|
+
* #parameters:
|
|
52
|
+
* overall = 100 {units: h; category: Durations; min: 100; max: 140} [Overall duration]
|
|
53
|
+
* muM = 0.668 {units: 1/h; category: Parameters} [Monod type model parameter]
|
|
54
|
+
* alpha = 2.92 {category: Parameters} [Monod type model parameter]
|
|
55
|
+
* beta = 0.131 {units: 1/h; category: Parameters} [Monod type model parameter]
|
|
56
|
+
* gamma = 2.12 {category: Parameters} [Monod type model parameter]
|
|
57
|
+
* lambda = 0.232 {units: 1/h; category: Parameters} [Monod type model parameter]
|
|
58
|
+
* delta = 0.278 {category: Parameters} [Monod type model parameter]
|
|
59
|
+
* phi = 4.87e-3 {units: 1/h; category: Parameters} [Monod type model parameter]
|
|
60
|
+
* Ks = 1.309e2 {units: g/L; category: Parameters} [Monod type model parameter]
|
|
61
|
+
* Ko = 3.63e-4 {units: g/L; category: Parameters} [Monod type model parameter]
|
|
62
|
+
* Kla = 1.7e-2 {units: 1/s; category: Parameters} [Volumetric mass transfer coefficient]
|
|
63
|
+
* Cod = 15 {units: kg/m³; category: Parameters} [Liquid phase dissolved oxygen saturation concentration]
|
|
64
|
+
*
|
|
65
|
+
* #tolerance: 1e-9`;
|
|
66
|
+
*
|
|
67
|
+
* // 2. Generate IVP-objects: for the main thread & for computations in webworkers
|
|
68
|
+
* const ivp = DGL.getIVP(model);
|
|
69
|
+
* const ivpWW = DGL.getIvp2WebWorker(ivp);
|
|
70
|
+
*
|
|
71
|
+
* // 3. Perform computations
|
|
72
|
+
* try {
|
|
73
|
+
* // 3.1) Extract names of outputs
|
|
74
|
+
* const outputNames = DGL.getOutputNames(ivp);
|
|
75
|
+
* const outSize = outputNames.length;
|
|
76
|
+
*
|
|
77
|
+
* // 3.2) Set model inputs
|
|
78
|
+
* const inputs = {
|
|
79
|
+
* _t0: 0,
|
|
80
|
+
* _t1: 60,
|
|
81
|
+
* _h: 1,
|
|
82
|
+
* X: 5,
|
|
83
|
+
* S: 150,
|
|
84
|
+
* O: 7,
|
|
85
|
+
* P: 0,
|
|
86
|
+
* overall: 100,
|
|
87
|
+
* muM: 0.668,
|
|
88
|
+
* alpha: 2.92,
|
|
89
|
+
* beta: 0.131,
|
|
90
|
+
* gamma: 2.12,
|
|
91
|
+
* lambda: 0.232,
|
|
92
|
+
* delta: 0.278,
|
|
93
|
+
* phi: 4.87e-3,
|
|
94
|
+
* Ks: 1.309e2,
|
|
95
|
+
* Ko: 3.63e-4,
|
|
96
|
+
* Kla: 1.7e-2,
|
|
97
|
+
* Cod: 15,
|
|
98
|
+
* };
|
|
99
|
+
*
|
|
100
|
+
* const inputVector = DGL.getInputVector(inputs, ivp);
|
|
101
|
+
*
|
|
102
|
+
* // 3.3) Create a pipeline
|
|
103
|
+
* const creator = DGL.getPipelineCreator(ivp);
|
|
104
|
+
* const pipeline = creator.getPipeline(inputVector);
|
|
105
|
+
*
|
|
106
|
+
* // 3.4) Apply pipeline to perform computations
|
|
107
|
+
* const solution = DGL.applyPipeline(pipeline, ivpWW, inputVector);
|
|
108
|
+
*
|
|
109
|
+
* // 3.5) Print results
|
|
110
|
+
*
|
|
111
|
+
* // 3.5.1) Table header
|
|
112
|
+
* let line = ' ';
|
|
113
|
+
* outputNames.forEach((name) => line += name + ' ');
|
|
114
|
+
* console.log(line);
|
|
115
|
+
*
|
|
116
|
+
* // 3.5.2) Table with solution const length = solution[0].length;
|
|
117
|
+
* for (let i = 0; i < length; ++i) {
|
|
118
|
+
* line = '';
|
|
119
|
+
*
|
|
120
|
+
* for (let j = 0; j < outSize; ++j)
|
|
121
|
+
* line += solution[j][i].toFixed(8) + ' ';
|
|
122
|
+
*
|
|
123
|
+
* console.log(line);
|
|
124
|
+
* }
|
|
125
|
+
* } catch (err) {
|
|
126
|
+
* console.log('Simulation failed: ', err instanceof Error ? err.message : 'Unknown problem!');
|
|
127
|
+
* }
|
|
128
|
+
*/
|
|
6
129
|
export class UpdatesModelPipelineCreator extends PipelineCreator {
|
|
130
|
+
/**
|
|
131
|
+
* @param ivp - initial value problem to be solved
|
|
132
|
+
*/
|
|
7
133
|
constructor(ivp) {
|
|
8
134
|
super(ivp);
|
|
9
135
|
if (ivp.updates === null)
|
|
10
136
|
throw new Error('Incorrect use of UpdatesModelPipelineCreator: model has no updates');
|
|
11
137
|
}
|
|
12
|
-
/** Return computations pipeline
|
|
138
|
+
/** Return computations pipeline corresponding to the given input vector
|
|
139
|
+
* @param inputs - input vector of the model
|
|
140
|
+
*/
|
|
13
141
|
getPipeline(inputs) {
|
|
14
142
|
if (this.ivp.updates === null)
|
|
15
143
|
throw new Error('Incorrect use of UpdatesModelPipelineCreator: model has no updates');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updates-pipeline-creator.js","sourceRoot":"","sources":["updates-pipeline-creator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"updates-pipeline-creator.js","sourceRoot":"","sources":["updates-pipeline-creator.ts"],"names":[],"mappings":"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"}
|