diff-grok 1.0.8 → 1.0.9

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.
@@ -0,0 +1,19 @@
1
+ name: Run tests
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ runs-on: ubuntu-latest
8
+
9
+ steps:
10
+ - uses: actions/checkout@v4
11
+ - uses: actions/setup-node@v4
12
+ with:
13
+ node-version: 20
14
+
15
+ - name: Install dependencies
16
+ run: npm install
17
+
18
+ - name: Run tests
19
+ run: npm test
package/jest.config.js ADDED
@@ -0,0 +1,12 @@
1
+ /** @type {import('ts-jest').JestConfigWithTsJest} */
2
+ module.exports = {
3
+ preset: 'ts-jest',
4
+ testEnvironment: 'node',
5
+ roots: ['<rootDir>/src'],
6
+ testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
7
+ collectCoverageFrom: [
8
+ 'src/**/*.ts',
9
+ '!src/**/*.d.ts',
10
+ '!src/**/*.test.ts',
11
+ ],
12
+ };
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "access": "public"
9
9
  },
10
10
  "license": "MIT",
11
- "version": "1.0.8",
11
+ "version": "1.0.9",
12
12
  "description": "Tools for solving initial value problem for ordinary differential equations",
13
13
  "keywords": [
14
14
  "initial value problem",
@@ -16,8 +16,8 @@
16
16
  "Rosenbrock-Wanner method"
17
17
  ],
18
18
  "devDependencies": {
19
+ "@types/jest": "^29.0.0",
19
20
  "@types/wu": "^2.1.44",
20
- "eslint-plugin-vue": "^9.29.0",
21
21
  "@typescript-eslint/eslint-plugin": "^5.62.0",
22
22
  "@typescript-eslint/parser": "^5.62.0",
23
23
  "css-loader": "^6.7.3",
@@ -25,7 +25,10 @@
25
25
  "eslint-config-eslint": "^9.0.0",
26
26
  "eslint-config-google": "^0.14.0",
27
27
  "eslint-plugin-react": "^7.33.2",
28
+ "eslint-plugin-vue": "^9.29.0",
29
+ "jest": "^29.0.0",
28
30
  "style-loader": "^3.3.2",
31
+ "ts-jest": "^29.0.0",
29
32
  "ts-loader": "^9.2.6",
30
33
  "typescript": "^5.6.3",
31
34
  "typescript-eslint": "^8.10.0"
@@ -35,7 +38,8 @@
35
38
  "build-diff-studio": "git clean -f -X -d ./src && tsc",
36
39
  "build": "tsc",
37
40
  "lint": "eslint \"./src/**/*.ts\"",
38
- "lint-fix": "eslint \"./src/**/*.ts\" --fix"
41
+ "lint-fix": "eslint \"./src/**/*.ts\" --fix",
42
+ "test": "jest"
39
43
  },
40
44
  "repository": {
41
45
  "type": "git",
@@ -1,6 +1,5 @@
1
1
  import { getIVP, getJScode } from '../../index';
2
2
  /** Example. Solve the following initial value problem
3
-
4
3
  dx / dt = x + y - cos(t)
5
4
  dy / dt = x - y + sin(t)
6
5
  x(0) = 1
@@ -1 +1 @@
1
- {"version":3,"file":"scripting.js","sourceRoot":"","sources":["scripting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAE,SAAS,EAAC,MAAM,aAAa,CAAC;AAE9C;;;;;;;;GAQG;AAEH,oDAAoD;AACpD,MAAM,KAAK,GAAG;;;;;;;;;;;;cAYA,CAAC;AAEf,sBAAsB;AACtB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAE1B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEjB,8CAA8C;AAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;AAE7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"scripting.js","sourceRoot":"","sources":["scripting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAE,SAAS,EAAC,MAAM,aAAa,CAAC;AAE9C;;;;;;;GAOG;AAEH,oDAAoD;AACpD,MAAM,KAAK,GAAG;;;;;;;;;;;;cAYA,CAAC;AAEf,sBAAsB;AACtB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAE1B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEjB,8CAA8C;AAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;AAE7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC"}
@@ -1,7 +1,6 @@
1
1
  import {getIVP, getJScode} from '../../index';
2
2
 
3
3
  /** Example. Solve the following initial value problem
4
-
5
4
  dx / dt = x + y - cos(t)
6
5
  dy / dt = x - y + sin(t)
7
6
  x(0) = 1
@@ -33,4 +32,4 @@ console.log(ivp);
33
32
  // Get lines of JS-code specifying ODEs object
34
33
  const lines = getJScode(ivp);
35
34
 
36
- console.log(lines);
35
+ console.log(lines);
@@ -0,0 +1,13 @@
1
+ // Correctness tests
2
+ import { corrProbs } from '../../index';
3
+ import { getError } from './test-utils';
4
+ import { methods, MAX_MAD } from './test-defs';
5
+ methods.forEach((method, name) => {
6
+ corrProbs.forEach((problem) => {
7
+ test(`Correctness: method - ${name}, problem - ${problem.odes.name}`, () => {
8
+ const error = getError(method, problem);
9
+ expect(error).toBeLessThan(MAX_MAD);
10
+ });
11
+ });
12
+ });
13
+ //# sourceMappingURL=correctness.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"correctness.test.js","sourceRoot":"","sources":["correctness.test.ts"],"names":[],"mappings":"AAAA,oBAAoB;AAEpB,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAC;AACtC,OAAO,EAAC,OAAO,EAAE,OAAO,EAAC,MAAM,aAAa,CAAC;AAE7C,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;IAC/B,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC5B,IAAI,CAAC,yBAAyB,IAAI,eAAe,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE;YACzE,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACxC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ // Correctness tests
2
+
3
+ import {corrProbs} from '../../index';
4
+ import {getError} from './test-utils';
5
+ import {methods, MAX_MAD} from './test-defs';
6
+
7
+ methods.forEach((method, name) => {
8
+ corrProbs.forEach((problem) => {
9
+ test(`Correctness: method - ${name}, problem - ${problem.odes.name}`, () => {
10
+ const error = getError(method, problem);
11
+ expect(error).toBeLessThan(MAX_MAD);
12
+ });
13
+ });
14
+ });
@@ -0,0 +1,14 @@
1
+ // Performance tests
2
+ import { perfProbs } from '../../index';
3
+ import { methods, TIMEOUT_MS } from './test-defs';
4
+ methods.forEach((method, name) => {
5
+ perfProbs.forEach((odes) => {
6
+ test(`Performance: method - ${name}, problem - ${odes.name}`, () => {
7
+ const start = performance.now();
8
+ method(odes);
9
+ const elapsed = performance.now() - start;
10
+ expect(elapsed).toBeLessThan(TIMEOUT_MS);
11
+ });
12
+ });
13
+ });
14
+ //# sourceMappingURL=performance.test.js.map
@@ -0,0 +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,OAAO,EAAE,UAAU,EAAC,MAAM,aAAa,CAAC;AAEhD,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;IAC/B,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,IAAI,CAAC,yBAAyB,IAAI,eAAe,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE;YACjE,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,CAAC;YACb,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ // Performance tests
2
+
3
+ import {perfProbs} from '../../index';
4
+ import {methods, TIMEOUT_MS} from './test-defs';
5
+
6
+ methods.forEach((method, name) => {
7
+ perfProbs.forEach((odes) => {
8
+ test(`Performance: method - ${name}, problem - ${odes.name}`, () => {
9
+ const start = performance.now();
10
+ method(odes);
11
+ const elapsed = performance.now() - start;
12
+ expect(elapsed).toBeLessThan(TIMEOUT_MS);
13
+ });
14
+ });
15
+ });
@@ -0,0 +1,10 @@
1
+ // Pipeline tests
2
+ import { problems } from './test-defs';
3
+ import { evalModel } from './test-utils';
4
+ problems.forEach((task, name) => {
5
+ test(`Pipeline: model - ${name}`, () => {
6
+ const solution = evalModel(task.model, task.inputs);
7
+ expect(solution.length).toBe(task.outputsCount);
8
+ });
9
+ });
10
+ //# sourceMappingURL=pipeline.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.test.js","sourceRoot":"","sources":["pipeline.test.ts"],"names":[],"mappings":"AAAA,iBAAiB;AAEjB,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAEvC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;IAC9B,IAAI,CAAC,qBAAqB,IAAI,EAAE,EAAE,GAAG,EAAE;QACrC,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ // Pipeline tests
2
+
3
+ import {problems} from './test-defs';
4
+ import {evalModel} from './test-utils';
5
+
6
+ problems.forEach((task, name) => {
7
+ test(`Pipeline: model - ${name}`, () => {
8
+ const solution = evalModel(task.model, task.inputs);
9
+ expect(solution.length).toBe(task.outputsCount);
10
+ });
11
+ });
@@ -0,0 +1,194 @@
1
+ /* eslint-disable max-len */
2
+ import { mrt, ros3prw, ros34prw } from '../../index';
3
+ export const methods = new Map([
4
+ ['MRT', mrt],
5
+ ['ROS3PRw', ros3prw],
6
+ ['ROS34PRw', ros34prw],
7
+ ]);
8
+ export const MAX_MAD = 0.1;
9
+ export const TIMEOUT_MS = 10000;
10
+ const BASIC_MODEL = `#name: M|M|2|2
11
+ #description: Modelling the system with two servers & two waiting places (EXPLAINED)
12
+ #equations:
13
+ dp0/dt = -la * p0 + mu * p1
14
+ dp1/dt = la * p0 - (la + mu) * p1 + 2 * mu * p2
15
+ dp2/dt = la * p1 - (la + 2 * mu) * p2 + 2 * mu * p3
16
+ dp3/dt = la * p2 - (la + 2 * mu) * p3 + 2 * mu * p4
17
+
18
+ #expressions:
19
+ la = 1 / arrival
20
+ mu = 1 / service
21
+ p4 = 1 - p0 - p1 - p2 - p3
22
+ busy = 1 - p0 - p1
23
+ queue = p3 + 2 * p4
24
+
25
+ #argument: t
26
+ _t0 = 0 {min: 0; max: 10; caption: start; category: Time; units: min} [Initial time of simulation]
27
+ _t1 = 60 {min: 20; max: 100; caption: finish; category: Time; units: min} [Final time of simulation]
28
+ _h = 1 {min: 0.01; max: 0.1; caption: step; category: Time; units: min} [Time step of simulation]
29
+
30
+ #inits:
31
+ p0 = 1 {min: 0; max: 1; category: Initial state; caption: empty} [Probability that initially there are NO customers]
32
+ p1 = 0 {min: 0; max: 1; category: Initial state; caption: single} [Probability that initially there is ONE customer]
33
+ p2 = 0 {min: 0; max: 1; category: Initial state; caption: two} [Probability that initially there are TWO customers]
34
+ p3 = 0 {min: 0; max: 1; category: Initial state; caption: three} [Probability that initially there are THREE customers]
35
+
36
+ #output:
37
+ t {caption: Time, min}
38
+ p0 {caption: P(Empty)}
39
+ busy {caption: P(Full load)}
40
+ queue {caption: E(Queue)}
41
+
42
+ #parameters:
43
+ arrival = 10 {min: 1; max: 100; category: Means; caption: arrival; units: min} [Mean arrival time]
44
+ service = 100 {min: 1; max: 100; category: Means; caption: service; units: min} [Mean service time]`;
45
+ const BASIC_MODEL_INPUTS = {
46
+ _t0: 0,
47
+ _t1: 60,
48
+ _h: 1,
49
+ p0: 1,
50
+ p1: 0,
51
+ p2: 0,
52
+ p3: 0,
53
+ arrival: 10,
54
+ service: 100,
55
+ };
56
+ const BASIC_MODEL_OUTPUTS = 4;
57
+ const CYCLIC_MODEL = `#name: PK-PD
58
+ #tags: model
59
+ #description: Pharmacokinetic-pharmacodynamic (PK-PD) simulation: two-compartment model
60
+ #equations:
61
+ d(depot)/dt = -KA * depot
62
+ d(centr)/dt = KA * depot - CL * C2 - Q * C2 + Q * C3
63
+ d(peri)/dt = Q * C2 - Q * C3
64
+ d(eff)/dt = Kin - Kout * (1 - C2/(EC50 + C2)) * eff
65
+
66
+ #expressions:
67
+ C2 = centr / V2
68
+ C3 = peri / V3
69
+
70
+ #loop:
71
+ _count = 10 {caption: count; category: Dosing; min: 1; max: 20} [Number of doses]
72
+ depot += dose
73
+
74
+ #argument: t
75
+ _t0 = 0 {units: h; caption: begin; category: Dosing; min: 0; max: 1} [Begin of dosing interval]
76
+ _t1 = 12 {units: h; caption: end; category: Dosing; min: 5; max: 15} [End of dosing interval]
77
+ _h = 1 {units: h; caption: step; category: Dosing; min: 0.01; max: 0.1} [Time step of simulation]
78
+
79
+ #inits:
80
+ depot = 0 {category: Initial values}
81
+ centr = 0 {category: Initial values} [Central]
82
+ peri = 0 {category: Initial values} [Peripheral]
83
+ eff = 0.2 {category: Initial values} [Effective compartment rate]
84
+
85
+ #parameters:
86
+ dose = 1e4 {category: Dosing; min: 1e3; max: 2e4; step: 1e3} [Dosage]
87
+ KA = 0.3 {caption: rate constant; category: Parameters; min: 0.1; max: 1}
88
+ CL = 2 {caption: clearance; category: Parameters; min: 1; max: 5}
89
+ V2 = 4 {caption: central volume; category: Parameters; min: 1; max: 10} [Central compartment volume]
90
+ Q = 1 {caption: inter rate; category: Parameters; min: 0.1; max: 1} [Intercompartmental rate]
91
+ V3 = 30 {caption: peri volume; category: Parameters; min: 20; max: 40} [Peripheral compartment volume]
92
+ EC50 = 8 {caption: effect; category: Parameters; min: 1; max: 10}
93
+ Kin = 0.2 {caption: Kin; category: Parameters; min: 0.1; max: 0.5} [The first-order production constant]
94
+ Kout = 0.2 {caption: Kout; category: Parameters; min: 0.1; max: 0.5} [The first-order dissipation rate constant]
95
+
96
+ #tolerance: 1e-9`;
97
+ const CYCLIC_MODEL_INPUTS = {
98
+ _count: 10,
99
+ _t0: 0,
100
+ _t1: 16,
101
+ _h: 1,
102
+ depot: 0,
103
+ centr: 0,
104
+ peri: 0,
105
+ eff: 0.2,
106
+ dose: 10000,
107
+ KA: 0.63,
108
+ CL: 3.2,
109
+ V2: 6.58,
110
+ Q: 0.622,
111
+ V3: 35.6,
112
+ EC50: 5.41,
113
+ Kin: 0.272,
114
+ Kout: 0.276,
115
+ };
116
+ const CYCLIC_MODEL_OUTPUTS = 5;
117
+ const MULTISTAGE_MODEL = `#name: GA-production
118
+ #tags: model
119
+ #description: Gluconic acid (GA) production by Aspergillus niger modeling
120
+ #equations:
121
+ dX/dt = rX
122
+ dS/dt = -gamma * rX - lambda * X
123
+ dO/dt = Kla * (Cod - O) - delta * rX - phi * X
124
+ dP/dt = alpha * rX + beta * X
125
+
126
+ #expressions:
127
+ mu = muM * S / (Ks + S) * O / (Ko + O)
128
+ rX = mu * X
129
+
130
+ #argument: t, 1-st stage
131
+ _t0 = 0 {units: h; caption: initial; category: Misc} [Start of the process]
132
+ _t1 = 60 {units: h; caption: 1-st stage; category: Durations; min: 20; max: 80} [Duration of the 1-st stage]
133
+ step = 0.1 {units: h; caption: step; category: Misc; min: 0.01; max: 1} [Time step of simulation]
134
+
135
+ #update: 2-nd stage
136
+ duration = overall - _t1
137
+ S += 70
138
+
139
+ #inits:
140
+ X = 5 {units: kg/m³; caption: biomass; category: Initial concentrations; min: 1; max: 10} [Aspergillus niger biomass]
141
+ S = 150 {units: kg/m³; caption: glucose; category: Initial concentrations; min: 50; max: 200} [Glucose]
142
+ O = 7 {units: kg/m³; caption: oxygen; category: Initial concentrations; min: 1; max: 10} [Dissolved oxygen]
143
+ P = 0 {units: kg/m³; caption: acid; category: Initial concentrations; min: 0; max: 0.1} [Gluconic acid]
144
+
145
+ #output:
146
+ t {caption: time}
147
+ X {caption: biomass}
148
+ S {caption: glucose}
149
+ O {caption: oxygen}
150
+ P {caption: acid}
151
+
152
+ #parameters:
153
+ overall = 100 {units: h; category: Durations; min: 100; max: 140} [Overall duration]
154
+ muM = 0.668 {units: 1/h; category: Parameters} [Monod type model parameter]
155
+ alpha = 2.92 {category: Parameters} [Monod type model parameter]
156
+ beta = 0.131 {units: 1/h; category: Parameters} [Monod type model parameter]
157
+ gamma = 2.12 {category: Parameters} [Monod type model parameter]
158
+ lambda = 0.232 {units: 1/h; category: Parameters} [Monod type model parameter]
159
+ delta = 0.278 {category: Parameters} [Monod type model parameter]
160
+ phi = 4.87e-3 {units: 1/h; category: Parameters} [Monod type model parameter]
161
+ Ks = 1.309e2 {units: g/L; category: Parameters} [Monod type model parameter]
162
+ Ko = 3.63e-4 {units: g/L; category: Parameters} [Monod type model parameter]
163
+ Kla = 1.7e-2 {units: 1/s; category: Parameters} [Volumetric mass transfer coefficient]
164
+ Cod = 15 {units: kg/m³; category: Parameters} [Liquid phase dissolved oxygen saturation concentration]
165
+
166
+ #tolerance: 1e-9`;
167
+ const MULTISTAGE_MODEL_INPUTS = {
168
+ _t0: 0,
169
+ _t1: 60,
170
+ _h: 1,
171
+ X: 5,
172
+ S: 150,
173
+ O: 7,
174
+ P: 0,
175
+ overall: 100,
176
+ muM: 0.668,
177
+ alpha: 2.92,
178
+ beta: 0.131,
179
+ gamma: 2.12,
180
+ lambda: 0.232,
181
+ delta: 0.278,
182
+ phi: 4.87e-3,
183
+ Ks: 1.309e2,
184
+ Ko: 3.63e-4,
185
+ Kla: 1.7e-2,
186
+ Cod: 15,
187
+ };
188
+ const MULTISTAGE_MODEL_OUTPUTS = 5;
189
+ export const problems = new Map([
190
+ ['basic', { model: BASIC_MODEL, inputs: BASIC_MODEL_INPUTS, outputsCount: BASIC_MODEL_OUTPUTS }],
191
+ ['cyclic', { model: CYCLIC_MODEL, inputs: CYCLIC_MODEL_INPUTS, outputsCount: CYCLIC_MODEL_OUTPUTS }],
192
+ ['multistage', { model: MULTISTAGE_MODEL, inputs: MULTISTAGE_MODEL_INPUTS, outputsCount: MULTISTAGE_MODEL_OUTPUTS }],
193
+ ]);
194
+ //# sourceMappingURL=test-defs.js.map
@@ -0,0 +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;AAEnD,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC;IAC7B,CAAC,KAAK,EAAE,GAAG,CAAC;IACZ,CAAC,SAAS,EAAE,OAAO,CAAC;IACpB,CAAC,UAAU,EAAE,QAAQ,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,CAAC;AAC3B,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC;AAEhC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uGAkCmF,CAAC;AAExG,MAAM,kBAAkB,GAAG;IACzB,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,EAAE;IACP,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,GAAG;CACb,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCJ,CAAC;AAElB,MAAM,mBAAmB,GAAG;IAC1B,MAAM,EAAE,EAAE;IACV,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,EAAE;IACP,EAAE,EAAE,CAAC;IACL,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,GAAG;IACR,IAAI,EAAE,KAAK;IACX,EAAE,EAAE,IAAI;IACR,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,IAAI;IACR,CAAC,EAAE,KAAK;IACR,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,IAAI;IACV,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,KAAK;CACZ,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAE/B,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiDR,CAAC;AAElB,MAAM,uBAAuB,GAAG;IAC9B,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,EAAE;IACP,EAAE,EAAE,CAAC;IACL,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;IACJ,OAAO,EAAE,GAAG;IACZ,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,KAAK;IACX,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,KAAK;IACZ,GAAG,EAAE,OAAO;IACZ,EAAE,EAAE,OAAO;IACX,EAAE,EAAE,OAAO;IACX,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,EAAE;CACR,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAQnC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAsB;IACnD,CAAC,OAAO,EAAE,EAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,YAAY,EAAE,mBAAmB,EAAC,CAAC;IAC9F,CAAC,QAAQ,EAAE,EAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,mBAAmB,EAAE,YAAY,EAAE,oBAAoB,EAAC,CAAC;IAClG,CAAC,YAAY,EAAE,EAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,uBAAuB,EAAE,YAAY,EAAE,wBAAwB,EAAC,CAAC;CACnH,CAAC,CAAC"}
@@ -0,0 +1,211 @@
1
+ /* eslint-disable max-len */
2
+ import {mrt, ros3prw, ros34prw} from '../../index';
3
+
4
+ export const methods = new Map([
5
+ ['MRT', mrt],
6
+ ['ROS3PRw', ros3prw],
7
+ ['ROS34PRw', ros34prw],
8
+ ]);
9
+
10
+ export const MAX_MAD = 0.1;
11
+ export const TIMEOUT_MS = 10000;
12
+
13
+ const BASIC_MODEL = `#name: M|M|2|2
14
+ #description: Modelling the system with two servers & two waiting places (EXPLAINED)
15
+ #equations:
16
+ dp0/dt = -la * p0 + mu * p1
17
+ dp1/dt = la * p0 - (la + mu) * p1 + 2 * mu * p2
18
+ dp2/dt = la * p1 - (la + 2 * mu) * p2 + 2 * mu * p3
19
+ dp3/dt = la * p2 - (la + 2 * mu) * p3 + 2 * mu * p4
20
+
21
+ #expressions:
22
+ la = 1 / arrival
23
+ mu = 1 / service
24
+ p4 = 1 - p0 - p1 - p2 - p3
25
+ busy = 1 - p0 - p1
26
+ queue = p3 + 2 * p4
27
+
28
+ #argument: t
29
+ _t0 = 0 {min: 0; max: 10; caption: start; category: Time; units: min} [Initial time of simulation]
30
+ _t1 = 60 {min: 20; max: 100; caption: finish; category: Time; units: min} [Final time of simulation]
31
+ _h = 1 {min: 0.01; max: 0.1; caption: step; category: Time; units: min} [Time step of simulation]
32
+
33
+ #inits:
34
+ p0 = 1 {min: 0; max: 1; category: Initial state; caption: empty} [Probability that initially there are NO customers]
35
+ p1 = 0 {min: 0; max: 1; category: Initial state; caption: single} [Probability that initially there is ONE customer]
36
+ p2 = 0 {min: 0; max: 1; category: Initial state; caption: two} [Probability that initially there are TWO customers]
37
+ p3 = 0 {min: 0; max: 1; category: Initial state; caption: three} [Probability that initially there are THREE customers]
38
+
39
+ #output:
40
+ t {caption: Time, min}
41
+ p0 {caption: P(Empty)}
42
+ busy {caption: P(Full load)}
43
+ queue {caption: E(Queue)}
44
+
45
+ #parameters:
46
+ arrival = 10 {min: 1; max: 100; category: Means; caption: arrival; units: min} [Mean arrival time]
47
+ service = 100 {min: 1; max: 100; category: Means; caption: service; units: min} [Mean service time]`;
48
+
49
+ const BASIC_MODEL_INPUTS = {
50
+ _t0: 0,
51
+ _t1: 60,
52
+ _h: 1,
53
+ p0: 1,
54
+ p1: 0,
55
+ p2: 0,
56
+ p3: 0,
57
+ arrival: 10,
58
+ service: 100,
59
+ };
60
+
61
+ const BASIC_MODEL_OUTPUTS = 4;
62
+
63
+ const CYCLIC_MODEL = `#name: PK-PD
64
+ #tags: model
65
+ #description: Pharmacokinetic-pharmacodynamic (PK-PD) simulation: two-compartment model
66
+ #equations:
67
+ d(depot)/dt = -KA * depot
68
+ d(centr)/dt = KA * depot - CL * C2 - Q * C2 + Q * C3
69
+ d(peri)/dt = Q * C2 - Q * C3
70
+ d(eff)/dt = Kin - Kout * (1 - C2/(EC50 + C2)) * eff
71
+
72
+ #expressions:
73
+ C2 = centr / V2
74
+ C3 = peri / V3
75
+
76
+ #loop:
77
+ _count = 10 {caption: count; category: Dosing; min: 1; max: 20} [Number of doses]
78
+ depot += dose
79
+
80
+ #argument: t
81
+ _t0 = 0 {units: h; caption: begin; category: Dosing; min: 0; max: 1} [Begin of dosing interval]
82
+ _t1 = 12 {units: h; caption: end; category: Dosing; min: 5; max: 15} [End of dosing interval]
83
+ _h = 1 {units: h; caption: step; category: Dosing; min: 0.01; max: 0.1} [Time step of simulation]
84
+
85
+ #inits:
86
+ depot = 0 {category: Initial values}
87
+ centr = 0 {category: Initial values} [Central]
88
+ peri = 0 {category: Initial values} [Peripheral]
89
+ eff = 0.2 {category: Initial values} [Effective compartment rate]
90
+
91
+ #parameters:
92
+ dose = 1e4 {category: Dosing; min: 1e3; max: 2e4; step: 1e3} [Dosage]
93
+ KA = 0.3 {caption: rate constant; category: Parameters; min: 0.1; max: 1}
94
+ CL = 2 {caption: clearance; category: Parameters; min: 1; max: 5}
95
+ V2 = 4 {caption: central volume; category: Parameters; min: 1; max: 10} [Central compartment volume]
96
+ Q = 1 {caption: inter rate; category: Parameters; min: 0.1; max: 1} [Intercompartmental rate]
97
+ V3 = 30 {caption: peri volume; category: Parameters; min: 20; max: 40} [Peripheral compartment volume]
98
+ EC50 = 8 {caption: effect; category: Parameters; min: 1; max: 10}
99
+ Kin = 0.2 {caption: Kin; category: Parameters; min: 0.1; max: 0.5} [The first-order production constant]
100
+ Kout = 0.2 {caption: Kout; category: Parameters; min: 0.1; max: 0.5} [The first-order dissipation rate constant]
101
+
102
+ #tolerance: 1e-9`;
103
+
104
+ const CYCLIC_MODEL_INPUTS = {
105
+ _count: 10,
106
+ _t0: 0,
107
+ _t1: 16,
108
+ _h: 1,
109
+ depot: 0,
110
+ centr: 0,
111
+ peri: 0,
112
+ eff: 0.2,
113
+ dose: 10000,
114
+ KA: 0.63,
115
+ CL: 3.2,
116
+ V2: 6.58,
117
+ Q: 0.622,
118
+ V3: 35.6,
119
+ EC50: 5.41,
120
+ Kin: 0.272,
121
+ Kout: 0.276,
122
+ };
123
+
124
+ const CYCLIC_MODEL_OUTPUTS = 5;
125
+
126
+ const MULTISTAGE_MODEL = `#name: GA-production
127
+ #tags: model
128
+ #description: Gluconic acid (GA) production by Aspergillus niger modeling
129
+ #equations:
130
+ dX/dt = rX
131
+ dS/dt = -gamma * rX - lambda * X
132
+ dO/dt = Kla * (Cod - O) - delta * rX - phi * X
133
+ dP/dt = alpha * rX + beta * X
134
+
135
+ #expressions:
136
+ mu = muM * S / (Ks + S) * O / (Ko + O)
137
+ rX = mu * X
138
+
139
+ #argument: t, 1-st stage
140
+ _t0 = 0 {units: h; caption: initial; category: Misc} [Start of the process]
141
+ _t1 = 60 {units: h; caption: 1-st stage; category: Durations; min: 20; max: 80} [Duration of the 1-st stage]
142
+ step = 0.1 {units: h; caption: step; category: Misc; min: 0.01; max: 1} [Time step of simulation]
143
+
144
+ #update: 2-nd stage
145
+ duration = overall - _t1
146
+ S += 70
147
+
148
+ #inits:
149
+ X = 5 {units: kg/m³; caption: biomass; category: Initial concentrations; min: 1; max: 10} [Aspergillus niger biomass]
150
+ S = 150 {units: kg/m³; caption: glucose; category: Initial concentrations; min: 50; max: 200} [Glucose]
151
+ O = 7 {units: kg/m³; caption: oxygen; category: Initial concentrations; min: 1; max: 10} [Dissolved oxygen]
152
+ P = 0 {units: kg/m³; caption: acid; category: Initial concentrations; min: 0; max: 0.1} [Gluconic acid]
153
+
154
+ #output:
155
+ t {caption: time}
156
+ X {caption: biomass}
157
+ S {caption: glucose}
158
+ O {caption: oxygen}
159
+ P {caption: acid}
160
+
161
+ #parameters:
162
+ overall = 100 {units: h; category: Durations; min: 100; max: 140} [Overall duration]
163
+ muM = 0.668 {units: 1/h; category: Parameters} [Monod type model parameter]
164
+ alpha = 2.92 {category: Parameters} [Monod type model parameter]
165
+ beta = 0.131 {units: 1/h; category: Parameters} [Monod type model parameter]
166
+ gamma = 2.12 {category: Parameters} [Monod type model parameter]
167
+ lambda = 0.232 {units: 1/h; category: Parameters} [Monod type model parameter]
168
+ delta = 0.278 {category: Parameters} [Monod type model parameter]
169
+ phi = 4.87e-3 {units: 1/h; category: Parameters} [Monod type model parameter]
170
+ Ks = 1.309e2 {units: g/L; category: Parameters} [Monod type model parameter]
171
+ Ko = 3.63e-4 {units: g/L; category: Parameters} [Monod type model parameter]
172
+ Kla = 1.7e-2 {units: 1/s; category: Parameters} [Volumetric mass transfer coefficient]
173
+ Cod = 15 {units: kg/m³; category: Parameters} [Liquid phase dissolved oxygen saturation concentration]
174
+
175
+ #tolerance: 1e-9`;
176
+
177
+ const MULTISTAGE_MODEL_INPUTS = {
178
+ _t0: 0,
179
+ _t1: 60,
180
+ _h: 1,
181
+ X: 5,
182
+ S: 150,
183
+ O: 7,
184
+ P: 0,
185
+ overall: 100,
186
+ muM: 0.668,
187
+ alpha: 2.92,
188
+ beta: 0.131,
189
+ gamma: 2.12,
190
+ lambda: 0.232,
191
+ delta: 0.278,
192
+ phi: 4.87e-3,
193
+ Ks: 1.309e2,
194
+ Ko: 3.63e-4,
195
+ Kla: 1.7e-2,
196
+ Cod: 15,
197
+ };
198
+
199
+ const MULTISTAGE_MODEL_OUTPUTS = 5;
200
+
201
+ type TestProblem = {
202
+ model: string,
203
+ inputs: Record<string, number>,
204
+ outputsCount: number,
205
+ };
206
+
207
+ export const problems = new Map<string, TestProblem>([
208
+ ['basic', {model: BASIC_MODEL, inputs: BASIC_MODEL_INPUTS, outputsCount: BASIC_MODEL_OUTPUTS}],
209
+ ['cyclic', {model: CYCLIC_MODEL, inputs: CYCLIC_MODEL_INPUTS, outputsCount: CYCLIC_MODEL_OUTPUTS}],
210
+ ['multistage', {model: MULTISTAGE_MODEL, inputs: MULTISTAGE_MODEL_INPUTS, outputsCount: MULTISTAGE_MODEL_OUTPUTS}],
211
+ ]);
@@ -0,0 +1,28 @@
1
+ import { getIVP, getIvp2WebWorker, getInputVector, getPipelineCreator, applyPipeline } from '../../index';
2
+ /** Return numerical solution error: maximum absolute deviation between approximate & exact solutions */
3
+ export function getError(method, corProb) {
4
+ let error = 0;
5
+ // Get numerical solution
6
+ const approxSolution = method(corProb.odes);
7
+ const exact = corProb.exact;
8
+ const arg = approxSolution[0];
9
+ const pointsCount = arg.length;
10
+ const funcsCount = approxSolution.length - 1;
11
+ // Compute error
12
+ for (let i = 0; i < pointsCount; ++i) {
13
+ const exactSolution = exact(arg[i]);
14
+ for (let j = 0; j < funcsCount; ++j)
15
+ error = Math.max(error, Math.abs(exactSolution[j] - approxSolution[j + 1][i]));
16
+ }
17
+ return error;
18
+ } // getError
19
+ /** Evaluate model */
20
+ export function evalModel(model, inputs) {
21
+ const ivp = getIVP(model);
22
+ const ivpWW = getIvp2WebWorker(ivp);
23
+ const inputVector = getInputVector(inputs, ivp);
24
+ const creator = getPipelineCreator(ivp);
25
+ const pipeline = creator.getPipeline(inputVector);
26
+ return applyPipeline(pipeline, ivpWW, inputVector);
27
+ } // evalModel
28
+ //# sourceMappingURL=test-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-utils.js","sourceRoot":"","sources":["test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAE,gBAAgB,EAAE,cAAc,EAAE,kBAAkB,EACrF,aAAa,EAAC,MAAM,aAAa,CAAC;AAEpC,wGAAwG;AACxG,MAAM,UAAU,QAAQ,CAAC,MAAsC,EAAE,OAAoB;IACnF,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,yBAAyB;IACzB,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAE5B,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;IAE9B,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC;IAC/B,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;IAE7C,gBAAgB;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC;QACrC,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,EAAE,CAAC;YACjC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC,WAAW;AAEb,sBAAsB;AACtB,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,MAA8B;IACrE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IAClD,OAAO,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;AACrD,CAAC,CAAC,YAAY"}
@@ -0,0 +1,37 @@
1
+ import {ODEs, CorrProblem, getIVP, getIvp2WebWorker, getInputVector, getPipelineCreator,
2
+ applyPipeline} from '../../index';
3
+
4
+ /** Return numerical solution error: maximum absolute deviation between approximate & exact solutions */
5
+ export function getError(method: (odes: ODEs) => Float64Array[], corProb: CorrProblem): number {
6
+ let error = 0;
7
+
8
+ // Get numerical solution
9
+ const approxSolution = method(corProb.odes);
10
+
11
+ const exact = corProb.exact;
12
+
13
+ const arg = approxSolution[0];
14
+
15
+ const pointsCount = arg.length;
16
+ const funcsCount = approxSolution.length - 1;
17
+
18
+ // Compute error
19
+ for (let i = 0; i < pointsCount; ++i) {
20
+ const exactSolution = exact(arg[i]);
21
+
22
+ for (let j = 0; j < funcsCount; ++j)
23
+ error = Math.max(error, Math.abs(exactSolution[j] - approxSolution[j + 1][i]));
24
+ }
25
+
26
+ return error;
27
+ } // getError
28
+
29
+ /** Evaluate model */
30
+ export function evalModel(model: string, inputs: Record<string, number>): Float64Array[] {
31
+ const ivp = getIVP(model);
32
+ const ivpWW = getIvp2WebWorker(ivp);
33
+ const inputVector = getInputVector(inputs, ivp);
34
+ const creator = getPipelineCreator(ivp);
35
+ const pipeline = creator.getPipeline(inputVector);
36
+ return applyPipeline(pipeline, ivpWW, inputVector);
37
+ } // evalModel
package/tsconfig.json CHANGED
@@ -48,7 +48,7 @@
48
48
  // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
49
49
  // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
50
50
  // "typeRoots": [], /* List of folders to include type definitions from. */
51
- // "types": [], /* Type declaration files to be included in compilation. */
51
+ "types": ["jest", "node"], /* Type declaration files to be included in compilation. */
52
52
  // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
53
53
  "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
54
54
  // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */