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.
Files changed (200) hide show
  1. package/.claude/settings.local.json +11 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. package/.github/PULL_REQUEST_TEMPLATE.md +22 -0
  5. package/.github/workflows/deploy-docs.yml +15 -0
  6. package/CLAUDE.md +98 -0
  7. package/CONTRIBUTING.md +74 -0
  8. package/README.MD +272 -18
  9. package/images/E5.png +0 -0
  10. package/images/HIRES.png +0 -0
  11. package/images/OREGO.png +0 -0
  12. package/images/POLL-full.png +0 -0
  13. package/images/POLL.png +0 -0
  14. package/images/ROBER.png +0 -0
  15. package/images/VDP0L.png +0 -0
  16. package/images/VDPOL.png +0 -0
  17. package/index.js +2 -2
  18. package/index.js.map +1 -1
  19. package/index.ts +7 -5
  20. package/jest.config.js +1 -0
  21. package/package.json +2 -1
  22. package/src/examples/bioreactor.js +125 -0
  23. package/src/examples/bioreactor.js.map +1 -0
  24. package/src/examples/bioreactor.ts +132 -0
  25. package/src/examples/check-methods.js +23 -9
  26. package/src/examples/check-methods.js.map +1 -1
  27. package/src/examples/check-methods.ts +28 -9
  28. package/src/examples/corr-probs.js +3 -1
  29. package/src/examples/corr-probs.js.map +1 -1
  30. package/src/examples/corr-probs.ts +7 -3
  31. package/src/examples/cyclic-model.js +3 -1
  32. package/src/examples/cyclic-model.js.map +1 -1
  33. package/src/examples/cyclic-model.ts +3 -1
  34. package/src/examples/e5.js +6 -0
  35. package/src/examples/e5.js.map +1 -1
  36. package/src/examples/e5.ts +7 -0
  37. package/src/examples/hires.js +10 -0
  38. package/src/examples/hires.js.map +1 -1
  39. package/src/examples/hires.ts +11 -0
  40. package/src/examples/index.js +21 -7
  41. package/src/examples/index.js.map +1 -1
  42. package/src/examples/index.ts +23 -7
  43. package/src/examples/orego.js +5 -0
  44. package/src/examples/orego.js.map +1 -1
  45. package/src/examples/orego.ts +6 -0
  46. package/src/examples/pollution.js +22 -0
  47. package/src/examples/pollution.js.map +1 -1
  48. package/src/examples/pollution.ts +23 -0
  49. package/src/examples/print-benchmark.js +581 -0
  50. package/src/examples/print-benchmark.js.map +1 -0
  51. package/src/examples/print-benchmark.ts +594 -0
  52. package/src/examples/robertson.js +6 -1
  53. package/src/examples/robertson.js.map +1 -1
  54. package/src/examples/robertson.ts +7 -1
  55. package/src/examples/scripting.js +1 -1
  56. package/src/examples/scripting.js.map +1 -1
  57. package/src/examples/scripting.ts +1 -1
  58. package/src/examples/vdpol.js +4 -0
  59. package/src/examples/vdpol.js.map +1 -1
  60. package/src/examples/vdpol.ts +5 -0
  61. package/src/pipeline/basic-pipeline-creator.js +96 -1
  62. package/src/pipeline/basic-pipeline-creator.js.map +1 -1
  63. package/src/pipeline/basic-pipeline-creator.ts +97 -1
  64. package/src/pipeline/loops-pipeline-creator.js +115 -2
  65. package/src/pipeline/loops-pipeline-creator.js.map +1 -1
  66. package/src/pipeline/loops-pipeline-creator.ts +116 -2
  67. package/src/pipeline/output.js +7 -2
  68. package/src/pipeline/output.js.map +1 -1
  69. package/src/pipeline/output.ts +7 -2
  70. package/src/pipeline/pipeline-creator.js.map +1 -1
  71. package/src/pipeline/pipeline-creator.ts +4 -0
  72. package/src/pipeline/pipeline.js +193 -2
  73. package/src/pipeline/pipeline.js.map +1 -1
  74. package/src/pipeline/pipeline.ts +206 -4
  75. package/src/pipeline/updates-pipeline-creator.js +130 -2
  76. package/src/pipeline/updates-pipeline-creator.js.map +1 -1
  77. package/src/pipeline/updates-pipeline-creator.ts +131 -2
  78. package/src/scripting-tools/constants.js +18 -4
  79. package/src/scripting-tools/constants.js.map +1 -1
  80. package/src/scripting-tools/constants.ts +22 -4
  81. package/src/scripting-tools/index.js.map +1 -1
  82. package/src/scripting-tools/index.ts +3 -2
  83. package/src/scripting-tools/model-error.js +3 -1
  84. package/src/scripting-tools/model-error.js.map +1 -1
  85. package/src/scripting-tools/model-error.ts +3 -1
  86. package/src/scripting-tools/scripting-tools.js +139 -9
  87. package/src/scripting-tools/scripting-tools.js.map +1 -1
  88. package/src/scripting-tools/scripting-tools.ts +228 -21
  89. package/src/solver-tools/ab4-method.js +332 -0
  90. package/src/solver-tools/ab4-method.js.map +1 -0
  91. package/src/solver-tools/ab4-method.ts +395 -0
  92. package/src/solver-tools/ab5-method.js +334 -0
  93. package/src/solver-tools/ab5-method.js.map +1 -0
  94. package/src/solver-tools/ab5-method.ts +397 -0
  95. package/src/solver-tools/callbacks/callback-base.js +2 -0
  96. package/src/solver-tools/callbacks/callback-base.js.map +1 -1
  97. package/src/solver-tools/callbacks/callback-base.ts +4 -0
  98. package/src/solver-tools/callbacks/callback-tools.js +3 -1
  99. package/src/solver-tools/callbacks/callback-tools.js.map +1 -1
  100. package/src/solver-tools/callbacks/callback-tools.ts +3 -1
  101. package/src/solver-tools/callbacks/iter-checker-callback.js +4 -0
  102. package/src/solver-tools/callbacks/iter-checker-callback.js.map +1 -1
  103. package/src/solver-tools/callbacks/iter-checker-callback.ts +4 -0
  104. package/src/solver-tools/callbacks/time-checker-callback.js +4 -0
  105. package/src/solver-tools/callbacks/time-checker-callback.js.map +1 -1
  106. package/src/solver-tools/callbacks/time-checker-callback.ts +4 -0
  107. package/src/solver-tools/index.js +9 -0
  108. package/src/solver-tools/index.js.map +1 -1
  109. package/src/solver-tools/index.ts +9 -0
  110. package/src/solver-tools/lsoda/blas.js +246 -0
  111. package/src/solver-tools/lsoda/blas.js.map +1 -0
  112. package/src/solver-tools/lsoda/blas.ts +267 -0
  113. package/src/solver-tools/lsoda/cfode.js +73 -0
  114. package/src/solver-tools/lsoda/cfode.js.map +1 -0
  115. package/src/solver-tools/lsoda/cfode.ts +83 -0
  116. package/src/solver-tools/lsoda/common.js +94 -0
  117. package/src/solver-tools/lsoda/common.js.map +1 -0
  118. package/src/solver-tools/lsoda/common.ts +135 -0
  119. package/src/solver-tools/lsoda/corfailure.js +25 -0
  120. package/src/solver-tools/lsoda/corfailure.js.map +1 -0
  121. package/src/solver-tools/lsoda/corfailure.ts +30 -0
  122. package/src/solver-tools/lsoda/correction.js +101 -0
  123. package/src/solver-tools/lsoda/correction.js.map +1 -0
  124. package/src/solver-tools/lsoda/correction.ts +119 -0
  125. package/src/solver-tools/lsoda/dense.js +110 -0
  126. package/src/solver-tools/lsoda/dense.js.map +1 -0
  127. package/src/solver-tools/lsoda/dense.ts +129 -0
  128. package/src/solver-tools/lsoda/index.js +4 -0
  129. package/src/solver-tools/lsoda/index.js.map +1 -0
  130. package/src/solver-tools/lsoda/index.ts +5 -0
  131. package/src/solver-tools/lsoda/intdy.js +43 -0
  132. package/src/solver-tools/lsoda/intdy.js.map +1 -0
  133. package/src/solver-tools/lsoda/intdy.ts +50 -0
  134. package/src/solver-tools/lsoda/lsoda.js +567 -0
  135. package/src/solver-tools/lsoda/lsoda.js.map +1 -0
  136. package/src/solver-tools/lsoda/lsoda.ts +632 -0
  137. package/src/solver-tools/lsoda/methodswitch.js +97 -0
  138. package/src/solver-tools/lsoda/methodswitch.js.map +1 -0
  139. package/src/solver-tools/lsoda/methodswitch.ts +107 -0
  140. package/src/solver-tools/lsoda/orderswitch.js +86 -0
  141. package/src/solver-tools/lsoda/orderswitch.js.map +1 -0
  142. package/src/solver-tools/lsoda/orderswitch.ts +95 -0
  143. package/src/solver-tools/lsoda/prja.js +43 -0
  144. package/src/solver-tools/lsoda/prja.js.map +1 -0
  145. package/src/solver-tools/lsoda/prja.ts +49 -0
  146. package/src/solver-tools/lsoda/scaleh.js +30 -0
  147. package/src/solver-tools/lsoda/scaleh.js.map +1 -0
  148. package/src/solver-tools/lsoda/scaleh.ts +33 -0
  149. package/src/solver-tools/lsoda/solsy.js +14 -0
  150. package/src/solver-tools/lsoda/solsy.js.map +1 -0
  151. package/src/solver-tools/lsoda/solsy.ts +18 -0
  152. package/src/solver-tools/lsoda/stoda.js +259 -0
  153. package/src/solver-tools/lsoda/stoda.js.map +1 -0
  154. package/src/solver-tools/lsoda/stoda.ts +286 -0
  155. package/src/solver-tools/lsoda-method.js +120 -0
  156. package/src/solver-tools/lsoda-method.js.map +1 -0
  157. package/src/solver-tools/lsoda-method.ts +136 -0
  158. package/src/solver-tools/mrt-method.js +121 -19
  159. package/src/solver-tools/mrt-method.js.map +1 -1
  160. package/src/solver-tools/mrt-method.ts +151 -22
  161. package/src/solver-tools/rk3-method.js +210 -0
  162. package/src/solver-tools/rk3-method.js.map +1 -0
  163. package/src/solver-tools/rk3-method.ts +257 -0
  164. package/src/solver-tools/rk4-method.js +236 -0
  165. package/src/solver-tools/rk4-method.js.map +1 -0
  166. package/src/solver-tools/rk4-method.ts +286 -0
  167. package/src/solver-tools/rkdp-method.js +247 -0
  168. package/src/solver-tools/rkdp-method.js.map +1 -0
  169. package/src/solver-tools/rkdp-method.ts +300 -0
  170. package/src/solver-tools/ros34prw-method.js +40 -2
  171. package/src/solver-tools/ros34prw-method.js.map +1 -1
  172. package/src/solver-tools/ros34prw-method.ts +40 -2
  173. package/src/solver-tools/ros3prw-method.js +40 -2
  174. package/src/solver-tools/ros3prw-method.js.map +1 -1
  175. package/src/solver-tools/ros3prw-method.ts +40 -2
  176. package/src/solver-tools/solver-defs.js +15 -3
  177. package/src/solver-tools/solver-defs.js.map +1 -1
  178. package/src/solver-tools/solver-defs.ts +91 -7
  179. package/src/tests/correctness.test.js +6 -4
  180. package/src/tests/correctness.test.js.map +1 -1
  181. package/src/tests/correctness.test.ts +6 -4
  182. package/src/tests/lsoda-lib-correctness.test.js +223 -0
  183. package/src/tests/lsoda-lib-correctness.test.js.map +1 -0
  184. package/src/tests/lsoda-lib-correctness.test.ts +283 -0
  185. package/src/tests/lsoda-lib-performance.test.js +95 -0
  186. package/src/tests/lsoda-lib-performance.test.js.map +1 -0
  187. package/src/tests/lsoda-lib-performance.test.ts +126 -0
  188. package/src/tests/performance.test.js +10 -8
  189. package/src/tests/performance.test.js.map +1 -1
  190. package/src/tests/performance.test.ts +10 -8
  191. package/src/tests/test-defs.js +14 -1
  192. package/src/tests/test-defs.js.map +1 -1
  193. package/src/tests/test-defs.ts +15 -1
  194. package/src/worker-tools/scripting.js +95 -1
  195. package/src/worker-tools/scripting.js.map +1 -1
  196. package/src/worker-tools/scripting.ts +104 -2
  197. package/src/worker-tools/solving.js +18 -2
  198. package/src/worker-tools/solving.js.map +1 -1
  199. package/src/worker-tools/solving.ts +25 -2
  200. package/typedoc.json +8 -0
@@ -0,0 +1,210 @@
1
+ /* The Bogacki-Shampine 3(2) method (RK3).
2
+
3
+ An explicit adaptive Runge-Kutta method of order 3 with an embedded
4
+ 2nd-order error estimate for step size control. Uses the FSAL (First
5
+ Same As Last) property for efficiency.
6
+
7
+ Reference:
8
+ [1] P. Bogacki and L.F. Shampine, "A 3(2) pair of Runge-Kutta formulas",
9
+ Applied Mathematics Letters, 2(4):321-325, 1989.
10
+ */
11
+ import { max, abs, SAFETY, REDUCE_COEF, GROW_COEF, ERR_CONTR, TINY, ERROR_MSG } from './solver-defs';
12
+ // Step size control exponents for a 3rd-order method
13
+ const PSHRNK = -1.0 / 3.0; // -1/p = -1/3
14
+ const PSGROW = -0.25; // -1/(p+1) = -1/4
15
+ // Bogacki-Shampine 3(2) Butcher tableau coefficients
16
+ // Nodes (c_i)
17
+ const C2 = 1.0 / 2.0;
18
+ const C3 = 3.0 / 4.0;
19
+ // C4 = 1 (FSAL)
20
+ // Matrix coefficients (a_ij)
21
+ const A21 = 1.0 / 2.0;
22
+ const A32 = 3.0 / 4.0;
23
+ // A4i = Bi (FSAL property: 4th-stage coefficients equal the 3rd-order weights)
24
+ // 3rd-order weights (b_i) — used to advance the solution
25
+ const B1 = 2.0 / 9.0;
26
+ const B2 = 1.0 / 3.0;
27
+ const B3 = 4.0 / 9.0;
28
+ // B4 = 0
29
+ // Error coefficients: (b_i - bHat_i), where bHat are the 2nd-order weights
30
+ const E1 = -5.0 / 72.0;
31
+ const E2 = 1.0 / 12.0;
32
+ const E3 = 1.0 / 9.0;
33
+ const E4 = -1.0 / 8.0;
34
+ /** Solve initial value problem using the Bogacki-Shampine 3(2) method
35
+ * @param odes initial value problem for ordinary differential equations
36
+ * @param callback computations control callback
37
+ * @returns solution of the problem
38
+ * @example
39
+ * // Example. Solve the following initial value problem using the RK3 method:
40
+ * // dx/dt = x + y - t
41
+ * // dy/dt = x * y + t
42
+ * // x(0) = 1
43
+ * // y(0) = -1
44
+ * // on [0, 2] with the step 0.01.
45
+ * import { ODEs, rk3 } from 'diff-grok';
46
+ *
47
+ * const task: ODEs = {
48
+ * name: 'Example', // name of your model
49
+ * arg: {
50
+ * name: 't', // name of the argument
51
+ * start: 0, // initial value of the argument
52
+ * finish: 2, // final value of the argument
53
+ * step: 0.01, // solution grid step
54
+ * },
55
+ * initial: [1, -1], // initial values
56
+ * func: (t: number, y: Float64Array, output: Float64Array) => { // right-hand side of the system
57
+ * output[0] = y[0] + y[1] - t; // 1-st equation
58
+ * output[1] = y[0] * y[1] + t; // 2-nd equation
59
+ * },
60
+ * tolerance: 1e-7, // tolerance
61
+ * solutionColNames: ['x', 'y'], // names of solution functions
62
+ * };
63
+ *
64
+ * try {
65
+ * // Solve the problem using the RK3 method
66
+ * const solution = rk3(task);
67
+ *
68
+ * // Print a table with the results
69
+ * console.log(task.arg.name, task.solutionColNames[0], task.solutionColNames[1]);
70
+ * const length = solution[0].length;
71
+ * for (let i = 0; i < length; ++i)
72
+ * console.log(solution[0][i], solution[1][i], solution[2][i]);
73
+ * } catch (err) {
74
+ * console.log('Solver failed: ', err instanceof Error ? err.message : 'Unknown problem!');
75
+ * }
76
+ */
77
+ export function rk3(odes, callback) {
78
+ const f = odes.func;
79
+ // operating variables
80
+ const t0 = odes.arg.start;
81
+ const t1 = odes.arg.finish;
82
+ let h = odes.arg.step;
83
+ const hDataframe = h;
84
+ const hMax = hDataframe * 10;
85
+ const tolerance = odes.tolerance;
86
+ const rowCount = Math.trunc((t1 - t0) / h) + 1;
87
+ const dim = odes.initial.length;
88
+ // result arrays
89
+ const tArr = new Float64Array(rowCount);
90
+ const yArrs = Array(dim);
91
+ for (let i = 0; i < dim; ++i)
92
+ yArrs[i] = new Float64Array(rowCount);
93
+ // method routine
94
+ let timeDataframe = t0 + hDataframe;
95
+ let t = t0;
96
+ let tPrev = t0;
97
+ let hNext = 0.0;
98
+ let flag = true;
99
+ let index = 1;
100
+ let errmax = 0;
101
+ let hTemp = 0;
102
+ let tNew = 0;
103
+ // buffers
104
+ const y = new Float64Array(odes.initial);
105
+ const yPrev = new Float64Array(odes.initial);
106
+ const dydt = new Float64Array(dim);
107
+ const yScale = new Float64Array(dim);
108
+ const yTemp = new Float64Array(dim);
109
+ const yErr = new Float64Array(dim);
110
+ const k1 = new Float64Array(dim);
111
+ const k2 = new Float64Array(dim);
112
+ const k3 = new Float64Array(dim);
113
+ const k4 = new Float64Array(dim);
114
+ // 1. SOLUTION AT THE POINT t0
115
+ tArr[0] = t0;
116
+ for (let i = 0; i < dim; ++i)
117
+ yArrs[i][0] = y[i];
118
+ // 2. COMPUTE NUMERICAL SOLUTION FOR THE POINTS FROM THE INTERVAL (t0, t1)
119
+ while (flag) {
120
+ // compute derivative
121
+ f(t, y, dydt);
122
+ // check whether to go on computations
123
+ if (callback)
124
+ callback.onIterationStart();
125
+ // compute scale vector
126
+ for (let i = 0; i < dim; ++i)
127
+ yScale[i] = abs(y[i]) + h * abs(dydt[i]) + TINY;
128
+ // check end point
129
+ if (t + h > t1) {
130
+ h = t1 - t;
131
+ flag = false;
132
+ }
133
+ // adaptive step loop
134
+ while (true) {
135
+ // Stage 1: k1 = f(t, y)
136
+ f(t, y, k1);
137
+ // Stage 2: k2 = f(t + C2*h, y + h*A21*k1)
138
+ for (let i = 0; i < dim; ++i)
139
+ yTemp[i] = y[i] + h * A21 * k1[i];
140
+ f(t + C2 * h, yTemp, k2);
141
+ // Stage 3: k3 = f(t + C3*h, y + h*A32*k2)
142
+ for (let i = 0; i < dim; ++i)
143
+ yTemp[i] = y[i] + h * A32 * k2[i];
144
+ f(t + C3 * h, yTemp, k3);
145
+ // 3rd-order solution
146
+ for (let i = 0; i < dim; ++i)
147
+ yTemp[i] = y[i] + h * (B1 * k1[i] + B2 * k2[i] + B3 * k3[i]);
148
+ // Stage 4: k4 = f(t + h, yTemp) — needed for error estimate (FSAL)
149
+ f(t + h, yTemp, k4);
150
+ // Error estimate: difference between 3rd and 2nd order solutions
151
+ for (let i = 0; i < dim; ++i)
152
+ yErr[i] = h * (E1 * k1[i] + E2 * k2[i] + E3 * k3[i] + E4 * k4[i]);
153
+ // estimating error
154
+ errmax = 0;
155
+ for (let i = 0; i < dim; ++i)
156
+ errmax = max(errmax, abs(yErr[i] / yScale[i]));
157
+ errmax /= tolerance;
158
+ // processing the error obtained
159
+ if (errmax > 1) {
160
+ hTemp = SAFETY * h * Math.pow(errmax, PSHRNK);
161
+ h = max(hTemp, REDUCE_COEF * h);
162
+ tNew = t + h;
163
+ if (tNew == t)
164
+ throw new Error(ERROR_MSG.RK3_FAILS);
165
+ }
166
+ else {
167
+ if (errmax > ERR_CONTR)
168
+ hNext = SAFETY * h * Math.pow(errmax, PSGROW);
169
+ else
170
+ hNext = GROW_COEF * h;
171
+ if (hNext > hMax)
172
+ hNext = hMax;
173
+ t = t + h;
174
+ for (let i = 0; i < dim; ++i)
175
+ y[i] = yTemp[i];
176
+ break;
177
+ }
178
+ } // while (true)
179
+ // compute linearly interpolated results and store them in dataframe
180
+ while (timeDataframe < t) {
181
+ const cLeft = (t - timeDataframe) / (t - tPrev);
182
+ const cRight = 1.0 - cLeft;
183
+ tArr[index] = timeDataframe;
184
+ for (let j = 0; j < dim; ++j)
185
+ yArrs[j][index] = cRight * y[j] + cLeft * yPrev[j];
186
+ timeDataframe += hDataframe;
187
+ ++index;
188
+ }
189
+ h = hNext;
190
+ tPrev = t;
191
+ for (let i = 0; i < dim; ++i)
192
+ yPrev[i] = y[i];
193
+ } // while (flag)
194
+ // perform final callback actions
195
+ if (callback)
196
+ callback.onComputationsCompleted();
197
+ // 3. solution at the point t1
198
+ tArr[rowCount - 1] = t1;
199
+ for (let i = 0; i < dim; ++i)
200
+ yArrs[i][rowCount - 1] = y[i];
201
+ // 4. prepare output
202
+ const solution = Array(dim + 1);
203
+ // independent variable
204
+ solution[0] = tArr;
205
+ // functions
206
+ for (let i = 0; i < dim; ++i)
207
+ solution[i + 1] = yArrs[i];
208
+ return solution;
209
+ } // rk3
210
+ //# sourceMappingURL=rk3-method.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rk3-method.js","sourceRoot":"","sources":["rk3-method.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,257 @@
1
+ /* The Bogacki-Shampine 3(2) method (RK3).
2
+
3
+ An explicit adaptive Runge-Kutta method of order 3 with an embedded
4
+ 2nd-order error estimate for step size control. Uses the FSAL (First
5
+ Same As Last) property for efficiency.
6
+
7
+ Reference:
8
+ [1] P. Bogacki and L.F. Shampine, "A 3(2) pair of Runge-Kutta formulas",
9
+ Applied Mathematics Letters, 2(4):321-325, 1989.
10
+ */
11
+
12
+ import {ODEs, max, abs, SAFETY, REDUCE_COEF, GROW_COEF,
13
+ ERR_CONTR, TINY, ERROR_MSG} from './solver-defs';
14
+ import {Callback} from './callbacks/callback-base';
15
+
16
+ // Step size control exponents for a 3rd-order method
17
+ const PSHRNK = -1.0 / 3.0; // -1/p = -1/3
18
+ const PSGROW = -0.25; // -1/(p+1) = -1/4
19
+
20
+ // Bogacki-Shampine 3(2) Butcher tableau coefficients
21
+
22
+ // Nodes (c_i)
23
+ const C2 = 1.0 / 2.0;
24
+ const C3 = 3.0 / 4.0;
25
+ // C4 = 1 (FSAL)
26
+
27
+ // Matrix coefficients (a_ij)
28
+ const A21 = 1.0 / 2.0;
29
+
30
+ const A32 = 3.0 / 4.0;
31
+
32
+ // A4i = Bi (FSAL property: 4th-stage coefficients equal the 3rd-order weights)
33
+
34
+ // 3rd-order weights (b_i) — used to advance the solution
35
+ const B1 = 2.0 / 9.0;
36
+ const B2 = 1.0 / 3.0;
37
+ const B3 = 4.0 / 9.0;
38
+ // B4 = 0
39
+
40
+ // Error coefficients: (b_i - bHat_i), where bHat are the 2nd-order weights
41
+ const E1 = -5.0 / 72.0;
42
+ const E2 = 1.0 / 12.0;
43
+ const E3 = 1.0 / 9.0;
44
+ const E4 = -1.0 / 8.0;
45
+
46
+ /** Solve initial value problem using the Bogacki-Shampine 3(2) method
47
+ * @param odes initial value problem for ordinary differential equations
48
+ * @param callback computations control callback
49
+ * @returns solution of the problem
50
+ * @example
51
+ * // Example. Solve the following initial value problem using the RK3 method:
52
+ * // dx/dt = x + y - t
53
+ * // dy/dt = x * y + t
54
+ * // x(0) = 1
55
+ * // y(0) = -1
56
+ * // on [0, 2] with the step 0.01.
57
+ * import { ODEs, rk3 } from 'diff-grok';
58
+ *
59
+ * const task: ODEs = {
60
+ * name: 'Example', // name of your model
61
+ * arg: {
62
+ * name: 't', // name of the argument
63
+ * start: 0, // initial value of the argument
64
+ * finish: 2, // final value of the argument
65
+ * step: 0.01, // solution grid step
66
+ * },
67
+ * initial: [1, -1], // initial values
68
+ * func: (t: number, y: Float64Array, output: Float64Array) => { // right-hand side of the system
69
+ * output[0] = y[0] + y[1] - t; // 1-st equation
70
+ * output[1] = y[0] * y[1] + t; // 2-nd equation
71
+ * },
72
+ * tolerance: 1e-7, // tolerance
73
+ * solutionColNames: ['x', 'y'], // names of solution functions
74
+ * };
75
+ *
76
+ * try {
77
+ * // Solve the problem using the RK3 method
78
+ * const solution = rk3(task);
79
+ *
80
+ * // Print a table with the results
81
+ * console.log(task.arg.name, task.solutionColNames[0], task.solutionColNames[1]);
82
+ * const length = solution[0].length;
83
+ * for (let i = 0; i < length; ++i)
84
+ * console.log(solution[0][i], solution[1][i], solution[2][i]);
85
+ * } catch (err) {
86
+ * console.log('Solver failed: ', err instanceof Error ? err.message : 'Unknown problem!');
87
+ * }
88
+ */
89
+ export function rk3(odes: ODEs, callback?: Callback): Float64Array[] {
90
+ const f = odes.func;
91
+
92
+ // operating variables
93
+ const t0 = odes.arg.start;
94
+ const t1 = odes.arg.finish;
95
+ let h = odes.arg.step;
96
+ const hDataframe = h;
97
+ const hMax = hDataframe * 10;
98
+ const tolerance = odes.tolerance;
99
+
100
+ const rowCount = Math.trunc((t1 - t0) / h) + 1;
101
+ const dim = odes.initial.length;
102
+
103
+ // result arrays
104
+ const tArr = new Float64Array(rowCount);
105
+ const yArrs = Array<Float64Array>(dim);
106
+
107
+ for (let i = 0; i < dim; ++i)
108
+ yArrs[i] = new Float64Array(rowCount);
109
+
110
+ // method routine
111
+ let timeDataframe = t0 + hDataframe;
112
+ let t = t0;
113
+ let tPrev = t0;
114
+ let hNext = 0.0;
115
+ let flag = true;
116
+ let index = 1;
117
+ let errmax = 0;
118
+ let hTemp = 0;
119
+ let tNew = 0;
120
+
121
+ // buffers
122
+ const y = new Float64Array(odes.initial);
123
+ const yPrev = new Float64Array(odes.initial);
124
+ const dydt = new Float64Array(dim);
125
+ const yScale = new Float64Array(dim);
126
+ const yTemp = new Float64Array(dim);
127
+ const yErr = new Float64Array(dim);
128
+
129
+ const k1 = new Float64Array(dim);
130
+ const k2 = new Float64Array(dim);
131
+ const k3 = new Float64Array(dim);
132
+ const k4 = new Float64Array(dim);
133
+
134
+ // 1. SOLUTION AT THE POINT t0
135
+ tArr[0] = t0;
136
+ for (let i = 0; i < dim; ++i)
137
+ yArrs[i][0] = y[i];
138
+
139
+ // 2. COMPUTE NUMERICAL SOLUTION FOR THE POINTS FROM THE INTERVAL (t0, t1)
140
+ while (flag) {
141
+ // compute derivative
142
+ f(t, y, dydt);
143
+
144
+ // check whether to go on computations
145
+ if (callback)
146
+ callback.onIterationStart();
147
+
148
+ // compute scale vector
149
+ for (let i = 0; i < dim; ++i)
150
+ yScale[i] = abs(y[i]) + h * abs(dydt[i]) + TINY;
151
+
152
+ // check end point
153
+ if (t + h > t1) {
154
+ h = t1 - t;
155
+ flag = false;
156
+ }
157
+
158
+ // adaptive step loop
159
+ while (true) {
160
+ // Stage 1: k1 = f(t, y)
161
+ f(t, y, k1);
162
+
163
+ // Stage 2: k2 = f(t + C2*h, y + h*A21*k1)
164
+ for (let i = 0; i < dim; ++i)
165
+ yTemp[i] = y[i] + h * A21 * k1[i];
166
+ f(t + C2 * h, yTemp, k2);
167
+
168
+ // Stage 3: k3 = f(t + C3*h, y + h*A32*k2)
169
+ for (let i = 0; i < dim; ++i)
170
+ yTemp[i] = y[i] + h * A32 * k2[i];
171
+ f(t + C3 * h, yTemp, k3);
172
+
173
+ // 3rd-order solution
174
+ for (let i = 0; i < dim; ++i)
175
+ yTemp[i] = y[i] + h * (B1 * k1[i] + B2 * k2[i] + B3 * k3[i]);
176
+
177
+ // Stage 4: k4 = f(t + h, yTemp) — needed for error estimate (FSAL)
178
+ f(t + h, yTemp, k4);
179
+
180
+ // Error estimate: difference between 3rd and 2nd order solutions
181
+ for (let i = 0; i < dim; ++i)
182
+ yErr[i] = h * (E1 * k1[i] + E2 * k2[i] + E3 * k3[i] + E4 * k4[i]);
183
+
184
+ // estimating error
185
+ errmax = 0;
186
+ for (let i = 0; i < dim; ++i)
187
+ errmax = max(errmax, abs(yErr[i] / yScale[i]));
188
+ errmax /= tolerance;
189
+
190
+ // processing the error obtained
191
+ if (errmax > 1) {
192
+ hTemp = SAFETY * h * errmax**PSHRNK;
193
+ h = max(hTemp, REDUCE_COEF * h);
194
+ tNew = t + h;
195
+ if (tNew == t)
196
+ throw new Error(ERROR_MSG.RK3_FAILS);
197
+ } else {
198
+ if (errmax > ERR_CONTR)
199
+ hNext = SAFETY * h * errmax**PSGROW;
200
+ else
201
+ hNext = GROW_COEF * h;
202
+
203
+ if (hNext > hMax)
204
+ hNext = hMax;
205
+
206
+ t = t + h;
207
+
208
+ for (let i = 0; i < dim; ++i)
209
+ y[i] = yTemp[i];
210
+
211
+ break;
212
+ }
213
+ } // while (true)
214
+
215
+ // compute linearly interpolated results and store them in dataframe
216
+ while (timeDataframe < t) {
217
+ const cLeft = (t - timeDataframe) / (t - tPrev);
218
+ const cRight = 1.0 - cLeft;
219
+
220
+ tArr[index] = timeDataframe;
221
+
222
+ for (let j = 0; j < dim; ++j)
223
+ yArrs[j][index] = cRight * y[j] + cLeft * yPrev[j];
224
+
225
+ timeDataframe += hDataframe;
226
+ ++index;
227
+ }
228
+
229
+ h = hNext;
230
+ tPrev = t;
231
+
232
+ for (let i = 0; i < dim; ++i)
233
+ yPrev[i] = y[i];
234
+ } // while (flag)
235
+
236
+ // perform final callback actions
237
+ if (callback)
238
+ callback.onComputationsCompleted();
239
+
240
+ // 3. solution at the point t1
241
+ tArr[rowCount - 1] = t1;
242
+
243
+ for (let i = 0; i < dim; ++i)
244
+ yArrs[i][rowCount - 1] = y[i];
245
+
246
+ // 4. prepare output
247
+ const solution = Array<Float64Array>(dim + 1);
248
+
249
+ // independent variable
250
+ solution[0] = tArr;
251
+
252
+ // functions
253
+ for (let i = 0; i < dim; ++i)
254
+ solution[i + 1] = yArrs[i];
255
+
256
+ return solution;
257
+ } // rk3