diff-grok 1.2.0 → 1.3.1

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 (624) hide show
  1. package/README.MD +56 -8
  2. package/dist/index.d.ts +6 -0
  3. package/{index.js → dist/index.js} +1 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/src/examples/basic-use.d.ts +10 -0
  6. package/dist/src/examples/basic-use.js.map +1 -0
  7. package/dist/src/examples/check-methods.d.ts +1 -0
  8. package/dist/src/examples/check-methods.js.map +1 -0
  9. package/dist/src/examples/corr-probs.d.ts +15 -0
  10. package/{src → dist/src}/examples/corr-probs.js +2 -2
  11. package/dist/src/examples/corr-probs.js.map +1 -0
  12. package/dist/src/examples/cyclic-model.d.ts +6 -0
  13. package/dist/src/examples/cyclic-model.js.map +1 -0
  14. package/dist/src/examples/e5.d.ts +15 -0
  15. package/dist/src/examples/e5.js.map +1 -0
  16. package/dist/src/examples/hires.d.ts +15 -0
  17. package/dist/src/examples/hires.js.map +1 -0
  18. package/dist/src/examples/index.d.ts +22 -0
  19. package/dist/src/examples/index.js.map +1 -0
  20. package/dist/src/examples/model-updates.d.ts +6 -0
  21. package/dist/src/examples/model-updates.js.map +1 -0
  22. package/dist/src/examples/orego.d.ts +15 -0
  23. package/dist/src/examples/orego.js.map +1 -0
  24. package/dist/src/examples/pipeline-use.d.ts +6 -0
  25. package/dist/src/examples/pipeline-use.js.map +1 -0
  26. package/dist/src/examples/pollution.d.ts +15 -0
  27. package/dist/src/examples/pollution.js.map +1 -0
  28. package/{src/examples/print-benchmark.ts → dist/src/examples/print-benchmark.d.ts} +8 -58
  29. package/dist/src/examples/print-benchmark.js.map +1 -0
  30. package/dist/src/examples/robertson.d.ts +15 -0
  31. package/{docs/media → dist/src/examples}/robertson.js +2 -2
  32. package/dist/src/examples/robertson.js.map +1 -0
  33. package/dist/src/examples/scripting.d.ts +1 -0
  34. package/dist/src/examples/scripting.js.map +1 -0
  35. package/dist/src/examples/vdpol.d.ts +15 -0
  36. package/dist/src/examples/vdpol.js.map +1 -0
  37. package/dist/src/latex-export/examples/advanced-to-latex.d.ts +2 -0
  38. package/dist/src/latex-export/examples/advanced-to-latex.js +41 -0
  39. package/dist/src/latex-export/examples/advanced-to-latex.js.map +1 -0
  40. package/dist/src/latex-export/examples/basic-to-latex.d.ts +2 -0
  41. package/dist/src/latex-export/examples/basic-to-latex.js +17 -0
  42. package/dist/src/latex-export/examples/basic-to-latex.js.map +1 -0
  43. package/dist/src/latex-export/examples/bioreactor-to-latex-selective.d.ts +2 -0
  44. package/dist/src/latex-export/examples/bioreactor-to-latex-selective.js +145 -0
  45. package/dist/src/latex-export/examples/bioreactor-to-latex-selective.js.map +1 -0
  46. package/dist/src/latex-export/examples/chem-react-to-latex-no-cdot.d.ts +2 -0
  47. package/dist/src/latex-export/examples/chem-react-to-latex-no-cdot.js +41 -0
  48. package/dist/src/latex-export/examples/chem-react-to-latex-no-cdot.js.map +1 -0
  49. package/dist/src/latex-export/examples/energy-n-control-to-markdown.d.ts +2 -0
  50. package/dist/src/latex-export/examples/energy-n-control-to-markdown.js +58 -0
  51. package/dist/src/latex-export/examples/energy-n-control-to-markdown.js.map +1 -0
  52. package/dist/src/latex-export/examples/extended-to-markdown.d.ts +2 -0
  53. package/dist/src/latex-export/examples/extended-to-markdown.js +37 -0
  54. package/dist/src/latex-export/examples/extended-to-markdown.js.map +1 -0
  55. package/dist/src/latex-export/examples/fermentation-to-latex.d.ts +2 -0
  56. package/dist/src/latex-export/examples/fermentation-to-latex.js +32 -0
  57. package/dist/src/latex-export/examples/fermentation-to-latex.js.map +1 -0
  58. package/dist/src/latex-export/examples/ga-production-to-markdown.d.ts +2 -0
  59. package/dist/src/latex-export/examples/ga-production-to-markdown.js +58 -0
  60. package/dist/src/latex-export/examples/ga-production-to-markdown.js.map +1 -0
  61. package/dist/src/latex-export/examples/nimotuzumab-to-latex.d.ts +2 -0
  62. package/dist/src/latex-export/examples/nimotuzumab-to-latex.js +53 -0
  63. package/dist/src/latex-export/examples/nimotuzumab-to-latex.js.map +1 -0
  64. package/dist/src/latex-export/examples/pk-pd-to-markdown-minimal.d.ts +2 -0
  65. package/dist/src/latex-export/examples/pk-pd-to-markdown-minimal.js +50 -0
  66. package/dist/src/latex-export/examples/pk-pd-to-markdown-minimal.js.map +1 -0
  67. package/dist/src/latex-export/examples/pk-to-markdown.d.ts +2 -0
  68. package/dist/src/latex-export/examples/pk-to-markdown.js +35 -0
  69. package/dist/src/latex-export/examples/pk-to-markdown.js.map +1 -0
  70. package/dist/src/latex-export/examples/pollution-to-latex.d.ts +2 -0
  71. package/dist/src/latex-export/examples/pollution-to-latex.js +141 -0
  72. package/dist/src/latex-export/examples/pollution-to-latex.js.map +1 -0
  73. package/dist/src/latex-export/examples/robertson-to-latex-no-meta.d.ts +2 -0
  74. package/dist/src/latex-export/examples/robertson-to-latex-no-meta.js +25 -0
  75. package/dist/src/latex-export/examples/robertson-to-latex-no-meta.js.map +1 -0
  76. package/dist/src/latex-export/generator/bracket-manager.d.ts +19 -0
  77. package/dist/src/latex-export/generator/bracket-manager.js +58 -0
  78. package/dist/src/latex-export/generator/bracket-manager.js.map +1 -0
  79. package/dist/src/latex-export/generator/document-builder.d.ts +13 -0
  80. package/dist/src/latex-export/generator/document-builder.js +433 -0
  81. package/dist/src/latex-export/generator/document-builder.js.map +1 -0
  82. package/dist/src/latex-export/generator/latex-generator.d.ts +26 -0
  83. package/dist/src/latex-export/generator/latex-generator.js +180 -0
  84. package/dist/src/latex-export/generator/latex-generator.js.map +1 -0
  85. package/dist/src/latex-export/index.d.ts +8 -0
  86. package/dist/src/latex-export/index.js +25 -0
  87. package/dist/src/latex-export/index.js.map +1 -0
  88. package/dist/src/latex-export/output/md-formatter.d.ts +16 -0
  89. package/dist/src/latex-export/output/md-formatter.js +27 -0
  90. package/dist/src/latex-export/output/md-formatter.js.map +1 -0
  91. package/dist/src/latex-export/output/tex-formatter.d.ts +5 -0
  92. package/dist/src/latex-export/output/tex-formatter.js +20 -0
  93. package/dist/src/latex-export/output/tex-formatter.js.map +1 -0
  94. package/dist/src/latex-export/parser/ast-parser.d.ts +7 -0
  95. package/dist/src/latex-export/parser/ast-parser.js +153 -0
  96. package/dist/src/latex-export/parser/ast-parser.js.map +1 -0
  97. package/dist/src/latex-export/parser/ivp-parser.d.ts +6 -0
  98. package/dist/src/latex-export/parser/ivp-parser.js +219 -0
  99. package/dist/src/latex-export/parser/ivp-parser.js.map +1 -0
  100. package/dist/src/latex-export/parser/line-joiner.d.ts +25 -0
  101. package/dist/src/latex-export/parser/line-joiner.js +80 -0
  102. package/dist/src/latex-export/parser/line-joiner.js.map +1 -0
  103. package/dist/src/latex-export/parser/tokenizer.d.ts +7 -0
  104. package/dist/src/latex-export/parser/tokenizer.js +143 -0
  105. package/dist/src/latex-export/parser/tokenizer.js.map +1 -0
  106. package/dist/src/latex-export/transformer/functions.d.ts +12 -0
  107. package/dist/src/latex-export/transformer/functions.js +47 -0
  108. package/dist/src/latex-export/transformer/functions.js.map +1 -0
  109. package/dist/src/latex-export/transformer/identifier.d.ts +23 -0
  110. package/dist/src/latex-export/transformer/identifier.js +194 -0
  111. package/dist/src/latex-export/transformer/identifier.js.map +1 -0
  112. package/dist/src/latex-export/transformer/operators.d.ts +9 -0
  113. package/dist/src/latex-export/transformer/operators.js +41 -0
  114. package/dist/src/latex-export/transformer/operators.js.map +1 -0
  115. package/dist/src/latex-export/types.d.ts +122 -0
  116. package/dist/src/latex-export/types.js +10 -0
  117. package/dist/src/latex-export/types.js.map +1 -0
  118. package/{src/pipeline/basic-pipeline-creator.ts → dist/src/pipeline/basic-pipeline-creator.d.ts} +11 -28
  119. package/dist/src/pipeline/basic-pipeline-creator.js.map +1 -0
  120. package/dist/src/pipeline/constants.d.ts +14 -0
  121. package/dist/src/pipeline/constants.js.map +1 -0
  122. package/dist/src/pipeline/index.d.ts +7 -0
  123. package/dist/src/pipeline/index.js.map +1 -0
  124. package/dist/src/pipeline/input.d.ts +3 -0
  125. package/dist/src/pipeline/input.js.map +1 -0
  126. package/dist/src/pipeline/loops-pipeline-creator.d.ts +124 -0
  127. package/dist/src/pipeline/loops-pipeline-creator.js.map +1 -0
  128. package/dist/src/pipeline/output.d.ts +10 -0
  129. package/{src → dist/src}/pipeline/output.js +1 -1
  130. package/dist/src/pipeline/output.js.map +1 -0
  131. package/dist/src/pipeline/pipeline-creator.d.ts +12 -0
  132. package/{src → dist/src}/pipeline/pipeline-creator.js +2 -0
  133. package/dist/src/pipeline/pipeline-creator.js.map +1 -0
  134. package/{src/pipeline/pipeline.ts → dist/src/pipeline/pipeline.d.ts} +10 -97
  135. package/dist/src/pipeline/pipeline.js.map +1 -0
  136. package/{src/pipeline/updates-pipeline-creator.ts → dist/src/pipeline/updates-pipeline-creator.d.ts} +15 -131
  137. package/dist/src/pipeline/updates-pipeline-creator.js.map +1 -0
  138. package/dist/src/scripting-tools/constants.d.ts +59 -0
  139. package/dist/src/scripting-tools/constants.js.map +1 -0
  140. package/dist/src/scripting-tools/index.d.ts +3 -0
  141. package/dist/src/scripting-tools/index.js.map +1 -0
  142. package/dist/src/scripting-tools/model-error.d.ts +10 -0
  143. package/{src → dist/src}/scripting-tools/model-error.js +2 -1
  144. package/dist/src/scripting-tools/model-error.js.map +1 -0
  145. package/dist/src/scripting-tools/scripting-tools.d.ts +277 -0
  146. package/{src → dist/src}/scripting-tools/scripting-tools.js +2 -4
  147. package/dist/src/scripting-tools/scripting-tools.js.map +1 -0
  148. package/dist/src/solver-tools/ab4-method.d.ts +46 -0
  149. package/{src → dist/src}/solver-tools/ab4-method.js +3 -3
  150. package/dist/src/solver-tools/ab4-method.js.map +1 -0
  151. package/dist/src/solver-tools/ab5-method.d.ts +46 -0
  152. package/{src → dist/src}/solver-tools/ab5-method.js +3 -3
  153. package/dist/src/solver-tools/ab5-method.js.map +1 -0
  154. package/dist/src/solver-tools/callbacks/callback-base.d.ts +8 -0
  155. package/dist/src/solver-tools/callbacks/callback-base.js.map +1 -0
  156. package/dist/src/solver-tools/callbacks/callback-tools.d.ts +6 -0
  157. package/dist/src/solver-tools/callbacks/callback-tools.js.map +1 -0
  158. package/dist/src/solver-tools/callbacks/iter-checker-callback.d.ts +12 -0
  159. package/{src → dist/src}/solver-tools/callbacks/iter-checker-callback.js +2 -0
  160. package/dist/src/solver-tools/callbacks/iter-checker-callback.js.map +1 -0
  161. package/dist/src/solver-tools/callbacks/time-checker-callback.d.ts +12 -0
  162. package/{src → dist/src}/solver-tools/callbacks/time-checker-callback.js +2 -2
  163. package/dist/src/solver-tools/callbacks/time-checker-callback.js.map +1 -0
  164. package/dist/src/solver-tools/cvode/common.d.ts +395 -0
  165. package/dist/src/solver-tools/cvode/common.js +483 -0
  166. package/dist/src/solver-tools/cvode/common.js.map +1 -0
  167. package/dist/src/solver-tools/cvode/cvode.d.ts +23 -0
  168. package/dist/src/solver-tools/cvode/cvode.js.map +1 -0
  169. package/dist/src/solver-tools/cvode/cvode_adams.d.ts +22 -0
  170. package/dist/src/solver-tools/cvode/cvode_adams.js.map +1 -0
  171. package/dist/src/solver-tools/cvode/cvode_bdf.d.ts +37 -0
  172. package/dist/src/solver-tools/cvode/cvode_bdf.js.map +1 -0
  173. package/dist/src/solver-tools/cvode/cvode_class.d.ts +116 -0
  174. package/{src → dist/src}/solver-tools/cvode/cvode_class.js +9 -4
  175. package/dist/src/solver-tools/cvode/cvode_class.js.map +1 -0
  176. package/dist/src/solver-tools/cvode/cvode_hin.d.ts +24 -0
  177. package/dist/src/solver-tools/cvode/cvode_hin.js.map +1 -0
  178. package/dist/src/solver-tools/cvode/cvode_io.d.ts +98 -0
  179. package/{src → dist/src}/solver-tools/cvode/cvode_io.js +1 -2
  180. package/dist/src/solver-tools/cvode/cvode_io.js.map +1 -0
  181. package/dist/src/solver-tools/cvode/cvode_ls.d.ts +23 -0
  182. package/dist/src/solver-tools/cvode/cvode_ls.js.map +1 -0
  183. package/dist/src/solver-tools/cvode/cvode_nls.d.ts +25 -0
  184. package/dist/src/solver-tools/cvode/cvode_nls.js.map +1 -0
  185. package/dist/src/solver-tools/cvode/cvode_root.d.ts +64 -0
  186. package/dist/src/solver-tools/cvode/cvode_root.js.map +1 -0
  187. package/dist/src/solver-tools/cvode/dense_linalg.d.ts +50 -0
  188. package/dist/src/solver-tools/cvode/dense_linalg.js.map +1 -0
  189. package/dist/src/solver-tools/cvode/index.d.ts +24 -0
  190. package/dist/src/solver-tools/cvode/index.js.map +1 -0
  191. package/dist/src/solver-tools/cvode-method.d.ts +47 -0
  192. package/dist/src/solver-tools/cvode-method.js.map +1 -0
  193. package/dist/src/solver-tools/index.d.ts +16 -0
  194. package/dist/src/solver-tools/index.js.map +1 -0
  195. package/dist/src/solver-tools/lin-alg-tools.d.ts +6 -0
  196. package/dist/src/solver-tools/lin-alg-tools.js.map +1 -0
  197. package/dist/src/solver-tools/lsoda/blas.d.ts +59 -0
  198. package/dist/src/solver-tools/lsoda/blas.js.map +1 -0
  199. package/{src/solver-tools/lsoda/index.ts → dist/src/solver-tools/lsoda/cfode.d.ts} +7 -6
  200. package/dist/src/solver-tools/lsoda/cfode.js.map +1 -0
  201. package/dist/src/solver-tools/lsoda/common.d.ts +85 -0
  202. package/dist/src/solver-tools/lsoda/common.js +96 -0
  203. package/dist/src/solver-tools/lsoda/common.js.map +1 -0
  204. package/{src/solver-tools/lsoda/corfailure.ts → dist/src/solver-tools/lsoda/corfailure.d.ts} +2 -26
  205. package/dist/src/solver-tools/lsoda/corfailure.js.map +1 -0
  206. package/dist/src/solver-tools/lsoda/correction.d.ts +23 -0
  207. package/dist/src/solver-tools/lsoda/correction.js.map +1 -0
  208. package/dist/src/solver-tools/lsoda/dense.d.ts +47 -0
  209. package/{src → dist/src}/solver-tools/lsoda/dense.js +2 -0
  210. package/dist/src/solver-tools/lsoda/dense.js.map +1 -0
  211. package/dist/src/solver-tools/lsoda/index.d.ts +16 -0
  212. package/dist/src/solver-tools/lsoda/index.js.map +1 -0
  213. package/dist/src/solver-tools/lsoda/intdy.d.ts +19 -0
  214. package/dist/src/solver-tools/lsoda/intdy.js.map +1 -0
  215. package/dist/src/solver-tools/lsoda/lsoda.d.ts +66 -0
  216. package/{src → dist/src}/solver-tools/lsoda/lsoda.js +13 -5
  217. package/dist/src/solver-tools/lsoda/lsoda.js.map +1 -0
  218. package/dist/src/solver-tools/lsoda/methodswitch.d.ts +21 -0
  219. package/dist/src/solver-tools/lsoda/methodswitch.js.map +1 -0
  220. package/dist/src/solver-tools/lsoda/orderswitch.d.ts +21 -0
  221. package/dist/src/solver-tools/lsoda/orderswitch.js.map +1 -0
  222. package/dist/src/solver-tools/lsoda/prja.d.ts +18 -0
  223. package/dist/src/solver-tools/lsoda/prja.js.map +1 -0
  224. package/dist/src/solver-tools/lsoda/scaleh.d.ts +16 -0
  225. package/dist/src/solver-tools/lsoda/scaleh.js.map +1 -0
  226. package/{src/solver-tools/lsoda/solsy.ts → dist/src/solver-tools/lsoda/solsy.d.ts} +2 -15
  227. package/dist/src/solver-tools/lsoda/solsy.js.map +1 -0
  228. package/dist/src/solver-tools/lsoda/stoda.d.ts +19 -0
  229. package/dist/src/solver-tools/lsoda/stoda.js.map +1 -0
  230. package/dist/src/solver-tools/lsoda-method.d.ts +46 -0
  231. package/dist/src/solver-tools/lsoda-method.js.map +1 -0
  232. package/dist/src/solver-tools/mrt-method.d.ts +47 -0
  233. package/{src → dist/src}/solver-tools/mrt-method.js +2 -2
  234. package/dist/src/solver-tools/mrt-method.js.map +1 -0
  235. package/dist/src/solver-tools/rk3-method.d.ts +46 -0
  236. package/{src → dist/src}/solver-tools/rk3-method.js +2 -2
  237. package/dist/src/solver-tools/rk3-method.js.map +1 -0
  238. package/dist/src/solver-tools/rk4-method.d.ts +46 -0
  239. package/{src → dist/src}/solver-tools/rk4-method.js +2 -2
  240. package/dist/src/solver-tools/rk4-method.js.map +1 -0
  241. package/dist/src/solver-tools/rkdp-method.d.ts +46 -0
  242. package/{src → dist/src}/solver-tools/rkdp-method.js +2 -2
  243. package/dist/src/solver-tools/rkdp-method.js.map +1 -0
  244. package/dist/src/solver-tools/ros34prw-method.d.ts +46 -0
  245. package/{src → dist/src}/solver-tools/ros34prw-method.js +2 -2
  246. package/dist/src/solver-tools/ros34prw-method.js.map +1 -0
  247. package/dist/src/solver-tools/ros3prw-method.d.ts +46 -0
  248. package/{src → dist/src}/solver-tools/ros3prw-method.js +2 -2
  249. package/dist/src/solver-tools/ros3prw-method.js.map +1 -0
  250. package/{src/solver-tools/solver-defs.ts → dist/src/solver-tools/solver-defs.d.ts} +45 -85
  251. package/dist/src/solver-tools/solver-defs.js.map +1 -0
  252. package/dist/src/worker-tools/index.d.ts +2 -0
  253. package/dist/src/worker-tools/index.js.map +1 -0
  254. package/{src/worker-tools/scripting.ts → dist/src/worker-tools/scripting.d.ts} +9 -91
  255. package/dist/src/worker-tools/scripting.js.map +1 -0
  256. package/dist/src/worker-tools/solving.d.ts +7 -0
  257. package/dist/src/worker-tools/solving.js.map +1 -0
  258. package/package.json +10 -11
  259. package/.claude/settings.local.json +0 -11
  260. package/.claude/skills/license-updater/SKILL.md +0 -149
  261. package/.claude/skills/license-updater/references/compatibility.md +0 -68
  262. package/.claude/skills/license-updater/references/templates.md +0 -151
  263. package/.claude/skills/license-updater/scripts/generate_license_files.py +0 -467
  264. package/.eslintrc.json +0 -45
  265. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -29
  266. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  267. package/.github/PULL_REQUEST_TEMPLATE.md +0 -22
  268. package/.github/scripts/bump-js-api-version.sh +0 -106
  269. package/.github/scripts/check-output.sh +0 -20
  270. package/.github/scripts/iac-cfn-deploy.sh +0 -90
  271. package/.github/scripts/slack_api_request.sh +0 -65
  272. package/.github/scripts/test_package.sh +0 -270
  273. package/.github/workflows/deploy-docs.yml +0 -15
  274. package/.github/workflows/libraries.yaml +0 -305
  275. package/.github/workflows/test.yaml +0 -19
  276. package/CLAUDE.md +0 -104
  277. package/CONTRIBUTING.md +0 -74
  278. package/THIRD_PARTY_LICENSES +0 -135
  279. package/docs/.nojekyll +0 -1
  280. package/docs/assets/hierarchy.js +0 -1
  281. package/docs/assets/highlight.css +0 -99
  282. package/docs/assets/icons.js +0 -18
  283. package/docs/assets/icons.svg +0 -1
  284. package/docs/assets/main.js +0 -60
  285. package/docs/assets/navigation.js +0 -1
  286. package/docs/assets/search.js +0 -1
  287. package/docs/assets/style.css +0 -1633
  288. package/docs/classes/BasicModelPipelineCreator.html +0 -10
  289. package/docs/classes/Callback.html +0 -7
  290. package/docs/classes/CyclicModelPipelineCreator.html +0 -10
  291. package/docs/classes/IterCheckerCallback.html +0 -8
  292. package/docs/classes/PipelineCreator.html +0 -6
  293. package/docs/classes/TimeCheckerCallback.html +0 -8
  294. package/docs/classes/UpdatesModelPipelineCreator.html +0 -10
  295. package/docs/functions/ab4.html +0 -8
  296. package/docs/functions/ab5.html +0 -8
  297. package/docs/functions/applyPipeline.html +0 -9
  298. package/docs/functions/getCallback.html +0 -3
  299. package/docs/functions/getIVP.html +0 -6
  300. package/docs/functions/getInputVector.html +0 -2
  301. package/docs/functions/getIvp2WebWorker.html +0 -6
  302. package/docs/functions/getJScode.html +0 -6
  303. package/docs/functions/getOutputNames.html +0 -4
  304. package/docs/functions/getPipelineCreator.html +0 -7
  305. package/docs/functions/lsoda.html +0 -8
  306. package/docs/functions/mrt.html +0 -11
  307. package/docs/functions/printE5.html +0 -76
  308. package/docs/functions/printHires.html +0 -76
  309. package/docs/functions/printOrego.html +0 -66
  310. package/docs/functions/printPollution.html +0 -163
  311. package/docs/functions/printRobertson.html +0 -60
  312. package/docs/functions/printVdpol.html +0 -66
  313. package/docs/functions/rk3.html +0 -8
  314. package/docs/functions/rk4.html +0 -8
  315. package/docs/functions/rkdp.html +0 -8
  316. package/docs/functions/ros34prw.html +0 -8
  317. package/docs/functions/ros3prw.html +0 -8
  318. package/docs/functions/solveIvp.html +0 -5
  319. package/docs/hierarchy.html +0 -1
  320. package/docs/index.html +0 -768
  321. package/docs/media/CONTRIBUTING.md +0 -74
  322. package/docs/media/E5.png +0 -0
  323. package/docs/media/HIRES.png +0 -0
  324. package/docs/media/OREGO.png +0 -0
  325. package/docs/media/POLL-full.png +0 -0
  326. package/docs/media/POLL.png +0 -0
  327. package/docs/media/ROBER.png +0 -0
  328. package/docs/media/VDP0L.png +0 -0
  329. package/docs/media/VDPOL.png +0 -0
  330. package/docs/media/acid-prod.gif +0 -0
  331. package/docs/media/basic-use.js.map +0 -1
  332. package/docs/media/basic-use.ts +0 -44
  333. package/docs/media/check-methods.js +0 -59
  334. package/docs/media/check-methods.js.map +0 -1
  335. package/docs/media/check-methods.ts +0 -81
  336. package/docs/media/corr-probs.js +0 -132
  337. package/docs/media/corr-probs.js.map +0 -1
  338. package/docs/media/corr-probs.ts +0 -155
  339. package/docs/media/cyclic-model.js.map +0 -1
  340. package/docs/media/cyclic-model.ts +0 -112
  341. package/docs/media/e5.js.map +0 -1
  342. package/docs/media/e5.ts +0 -36
  343. package/docs/media/hires.js.map +0 -1
  344. package/docs/media/hires.ts +0 -40
  345. package/docs/media/model-updates.js.map +0 -1
  346. package/docs/media/model-updates.ts +0 -122
  347. package/docs/media/orego.js.map +0 -1
  348. package/docs/media/orego.ts +0 -25
  349. package/docs/media/pipeline-use.js.map +0 -1
  350. package/docs/media/pipeline-use.ts +0 -98
  351. package/docs/media/pollution.js.map +0 -1
  352. package/docs/media/pollution.ts +0 -133
  353. package/docs/media/print-benchmark.js.map +0 -1
  354. package/docs/media/print-benchmark.ts +0 -594
  355. package/docs/media/robertson.js.map +0 -1
  356. package/docs/media/robertson.ts +0 -19
  357. package/docs/media/scripting.js.map +0 -1
  358. package/docs/media/scripting.ts +0 -35
  359. package/docs/media/vdpol.js.map +0 -1
  360. package/docs/media/vdpol.ts +0 -17
  361. package/docs/modules.html +0 -1
  362. package/docs/types/Arg.html +0 -12
  363. package/docs/types/DifEqs.html +0 -8
  364. package/docs/types/Func.html +0 -7
  365. package/docs/types/IVP.html +0 -40
  366. package/docs/types/IVP2WebWorker.html +0 -12
  367. package/docs/types/Input.html +0 -8
  368. package/docs/types/Loop.html +0 -7
  369. package/docs/types/ODEs.html +0 -31
  370. package/docs/types/Output.html +0 -6
  371. package/docs/types/Pipeline.html +0 -6
  372. package/docs/types/SolverOptions.html +0 -8
  373. package/docs/types/Update.html +0 -9
  374. package/docs/types/Wrapper.html +0 -8
  375. package/eslintrc.json +0 -45
  376. package/images/E5.png +0 -0
  377. package/images/HIRES.png +0 -0
  378. package/images/OREGO.png +0 -0
  379. package/images/POLL-full.png +0 -0
  380. package/images/POLL.png +0 -0
  381. package/images/ROBER.png +0 -0
  382. package/images/VDP0L.png +0 -0
  383. package/images/VDPOL.png +0 -0
  384. package/images/acid-prod.gif +0 -0
  385. package/index.js.map +0 -1
  386. package/index.ts +0 -17
  387. package/jest.config.js +0 -13
  388. package/src/examples/basic-use.js +0 -40
  389. package/src/examples/basic-use.js.map +0 -1
  390. package/src/examples/basic-use.ts +0 -44
  391. package/src/examples/check-methods.js.map +0 -1
  392. package/src/examples/check-methods.ts +0 -96
  393. package/src/examples/corr-probs.js.map +0 -1
  394. package/src/examples/corr-probs.ts +0 -155
  395. package/src/examples/cyclic-model.js +0 -102
  396. package/src/examples/cyclic-model.js.map +0 -1
  397. package/src/examples/cyclic-model.ts +0 -112
  398. package/src/examples/e5.js +0 -36
  399. package/src/examples/e5.js.map +0 -1
  400. package/src/examples/e5.ts +0 -36
  401. package/src/examples/hires.js +0 -39
  402. package/src/examples/hires.js.map +0 -1
  403. package/src/examples/hires.ts +0 -40
  404. package/src/examples/index.js.map +0 -1
  405. package/src/examples/index.ts +0 -34
  406. package/src/examples/model-updates.js +0 -112
  407. package/src/examples/model-updates.js.map +0 -1
  408. package/src/examples/model-updates.ts +0 -122
  409. package/src/examples/orego.js +0 -24
  410. package/src/examples/orego.js.map +0 -1
  411. package/src/examples/orego.ts +0 -25
  412. package/src/examples/pipeline-use.js +0 -87
  413. package/src/examples/pipeline-use.js.map +0 -1
  414. package/src/examples/pipeline-use.ts +0 -98
  415. package/src/examples/pollution.js +0 -132
  416. package/src/examples/pollution.js.map +0 -1
  417. package/src/examples/pollution.ts +0 -133
  418. package/src/examples/print-benchmark.js +0 -581
  419. package/src/examples/print-benchmark.js.map +0 -1
  420. package/src/examples/robertson.js +0 -19
  421. package/src/examples/robertson.js.map +0 -1
  422. package/src/examples/robertson.ts +0 -19
  423. package/src/examples/scripting.js +0 -30
  424. package/src/examples/scripting.js.map +0 -1
  425. package/src/examples/scripting.ts +0 -35
  426. package/src/examples/vdpol.js +0 -17
  427. package/src/examples/vdpol.js.map +0 -1
  428. package/src/examples/vdpol.ts +0 -17
  429. package/src/pipeline/basic-pipeline-creator.js.map +0 -1
  430. package/src/pipeline/constants.js.map +0 -1
  431. package/src/pipeline/constants.ts +0 -21
  432. package/src/pipeline/index.js.map +0 -1
  433. package/src/pipeline/index.ts +0 -7
  434. package/src/pipeline/input.js.map +0 -1
  435. package/src/pipeline/input.ts +0 -55
  436. package/src/pipeline/loops-pipeline-creator.js.map +0 -1
  437. package/src/pipeline/loops-pipeline-creator.ts +0 -252
  438. package/src/pipeline/output.js.map +0 -1
  439. package/src/pipeline/output.ts +0 -201
  440. package/src/pipeline/pipeline-creator.js.map +0 -1
  441. package/src/pipeline/pipeline-creator.ts +0 -20
  442. package/src/pipeline/pipeline.js.map +0 -1
  443. package/src/pipeline/updates-pipeline-creator.js.map +0 -1
  444. package/src/scripting-tools/constants.js.map +0 -1
  445. package/src/scripting-tools/constants.ts +0 -69
  446. package/src/scripting-tools/index.js.map +0 -1
  447. package/src/scripting-tools/index.ts +0 -8
  448. package/src/scripting-tools/model-error.js.map +0 -1
  449. package/src/scripting-tools/model-error.ts +0 -21
  450. package/src/scripting-tools/scripting-tools.js.map +0 -1
  451. package/src/scripting-tools/scripting-tools.ts +0 -1582
  452. package/src/solver-tools/ab4-method.js.map +0 -1
  453. package/src/solver-tools/ab4-method.ts +0 -395
  454. package/src/solver-tools/ab5-method.js.map +0 -1
  455. package/src/solver-tools/ab5-method.ts +0 -397
  456. package/src/solver-tools/callbacks/callback-base.js.map +0 -1
  457. package/src/solver-tools/callbacks/callback-base.ts +0 -12
  458. package/src/solver-tools/callbacks/callback-tools.js.map +0 -1
  459. package/src/solver-tools/callbacks/callback-tools.ts +0 -22
  460. package/src/solver-tools/callbacks/iter-checker-callback.js.map +0 -1
  461. package/src/solver-tools/callbacks/iter-checker-callback.ts +0 -25
  462. package/src/solver-tools/callbacks/time-checker-callback.js.map +0 -1
  463. package/src/solver-tools/callbacks/time-checker-callback.ts +0 -23
  464. package/src/solver-tools/cvode/common.js +0 -487
  465. package/src/solver-tools/cvode/common.js.map +0 -1
  466. package/src/solver-tools/cvode/common.ts +0 -549
  467. package/src/solver-tools/cvode/cvode.js.map +0 -1
  468. package/src/solver-tools/cvode/cvode.ts +0 -1226
  469. package/src/solver-tools/cvode/cvode_adams.js.map +0 -1
  470. package/src/solver-tools/cvode/cvode_adams.ts +0 -142
  471. package/src/solver-tools/cvode/cvode_bdf.js.map +0 -1
  472. package/src/solver-tools/cvode/cvode_bdf.ts +0 -164
  473. package/src/solver-tools/cvode/cvode_class.js.map +0 -1
  474. package/src/solver-tools/cvode/cvode_class.ts +0 -271
  475. package/src/solver-tools/cvode/cvode_hin.js.map +0 -1
  476. package/src/solver-tools/cvode/cvode_hin.ts +0 -150
  477. package/src/solver-tools/cvode/cvode_io.js.map +0 -1
  478. package/src/solver-tools/cvode/cvode_io.ts +0 -258
  479. package/src/solver-tools/cvode/cvode_ls.js.map +0 -1
  480. package/src/solver-tools/cvode/cvode_ls.ts +0 -249
  481. package/src/solver-tools/cvode/cvode_nls.js.map +0 -1
  482. package/src/solver-tools/cvode/cvode_nls.ts +0 -259
  483. package/src/solver-tools/cvode/cvode_root.js.map +0 -1
  484. package/src/solver-tools/cvode/cvode_root.ts +0 -503
  485. package/src/solver-tools/cvode/dense_linalg.js.map +0 -1
  486. package/src/solver-tools/cvode/dense_linalg.ts +0 -144
  487. package/src/solver-tools/cvode/index.js.map +0 -1
  488. package/src/solver-tools/cvode/index.ts +0 -64
  489. package/src/solver-tools/cvode-method.js.map +0 -1
  490. package/src/solver-tools/cvode-method.ts +0 -129
  491. package/src/solver-tools/index.js.map +0 -1
  492. package/src/solver-tools/index.ts +0 -16
  493. package/src/solver-tools/lin-alg-tools.js.map +0 -1
  494. package/src/solver-tools/lin-alg-tools.ts +0 -75
  495. package/src/solver-tools/lsoda/blas.js.map +0 -1
  496. package/src/solver-tools/lsoda/blas.ts +0 -279
  497. package/src/solver-tools/lsoda/cfode.js.map +0 -1
  498. package/src/solver-tools/lsoda/cfode.ts +0 -95
  499. package/src/solver-tools/lsoda/common.js +0 -94
  500. package/src/solver-tools/lsoda/common.js.map +0 -1
  501. package/src/solver-tools/lsoda/common.ts +0 -135
  502. package/src/solver-tools/lsoda/corfailure.js.map +0 -1
  503. package/src/solver-tools/lsoda/correction.js.map +0 -1
  504. package/src/solver-tools/lsoda/correction.ts +0 -131
  505. package/src/solver-tools/lsoda/dense.js.map +0 -1
  506. package/src/solver-tools/lsoda/dense.ts +0 -141
  507. package/src/solver-tools/lsoda/index.js.map +0 -1
  508. package/src/solver-tools/lsoda/intdy.js.map +0 -1
  509. package/src/solver-tools/lsoda/intdy.ts +0 -62
  510. package/src/solver-tools/lsoda/lsoda.js.map +0 -1
  511. package/src/solver-tools/lsoda/lsoda.ts +0 -644
  512. package/src/solver-tools/lsoda/methodswitch.js.map +0 -1
  513. package/src/solver-tools/lsoda/methodswitch.ts +0 -119
  514. package/src/solver-tools/lsoda/orderswitch.js.map +0 -1
  515. package/src/solver-tools/lsoda/orderswitch.ts +0 -107
  516. package/src/solver-tools/lsoda/prja.js.map +0 -1
  517. package/src/solver-tools/lsoda/prja.ts +0 -61
  518. package/src/solver-tools/lsoda/scaleh.js.map +0 -1
  519. package/src/solver-tools/lsoda/scaleh.ts +0 -45
  520. package/src/solver-tools/lsoda/solsy.js.map +0 -1
  521. package/src/solver-tools/lsoda/stoda.js.map +0 -1
  522. package/src/solver-tools/lsoda/stoda.ts +0 -298
  523. package/src/solver-tools/lsoda-method.js.map +0 -1
  524. package/src/solver-tools/lsoda-method.ts +0 -154
  525. package/src/solver-tools/mrt-method.js.map +0 -1
  526. package/src/solver-tools/mrt-method.ts +0 -398
  527. package/src/solver-tools/rk3-method.js.map +0 -1
  528. package/src/solver-tools/rk3-method.ts +0 -257
  529. package/src/solver-tools/rk4-method.js.map +0 -1
  530. package/src/solver-tools/rk4-method.ts +0 -286
  531. package/src/solver-tools/rkdp-method.js.map +0 -1
  532. package/src/solver-tools/rkdp-method.ts +0 -300
  533. package/src/solver-tools/ros34prw-method.js.map +0 -1
  534. package/src/solver-tools/ros34prw-method.ts +0 -373
  535. package/src/solver-tools/ros3prw-method.js.map +0 -1
  536. package/src/solver-tools/ros3prw-method.ts +0 -342
  537. package/src/solver-tools/solver-defs.js.map +0 -1
  538. package/src/tests/correctness.test.js +0 -15
  539. package/src/tests/correctness.test.js.map +0 -1
  540. package/src/tests/correctness.test.ts +0 -16
  541. package/src/tests/cvode-lib-correctness.test.js +0 -404
  542. package/src/tests/cvode-lib-correctness.test.js.map +0 -1
  543. package/src/tests/cvode-lib-correctness.test.ts +0 -505
  544. package/src/tests/cvode-lib-performance.test.js +0 -103
  545. package/src/tests/cvode-lib-performance.test.js.map +0 -1
  546. package/src/tests/cvode-lib-performance.test.ts +0 -128
  547. package/src/tests/lsoda-lib-correctness.test.js +0 -223
  548. package/src/tests/lsoda-lib-correctness.test.js.map +0 -1
  549. package/src/tests/lsoda-lib-correctness.test.ts +0 -283
  550. package/src/tests/lsoda-lib-performance.test.js +0 -95
  551. package/src/tests/lsoda-lib-performance.test.js.map +0 -1
  552. package/src/tests/lsoda-lib-performance.test.ts +0 -126
  553. package/src/tests/performance.test.js +0 -18
  554. package/src/tests/performance.test.js.map +0 -1
  555. package/src/tests/performance.test.ts +0 -19
  556. package/src/tests/pipeline.test.js +0 -10
  557. package/src/tests/pipeline.test.js.map +0 -1
  558. package/src/tests/pipeline.test.ts +0 -11
  559. package/src/tests/test-defs.js +0 -213
  560. package/src/tests/test-defs.js.map +0 -1
  561. package/src/tests/test-defs.ts +0 -232
  562. package/src/tests/test-utils.js +0 -28
  563. package/src/tests/test-utils.js.map +0 -1
  564. package/src/tests/test-utils.ts +0 -37
  565. package/src/worker-tools/index.js.map +0 -1
  566. package/src/worker-tools/index.ts +0 -2
  567. package/src/worker-tools/scripting.js.map +0 -1
  568. package/src/worker-tools/solving.js.map +0 -1
  569. package/src/worker-tools/solving.ts +0 -86
  570. package/tsconfig.json +0 -71
  571. package/typedoc.json +0 -8
  572. /package/{docs/media → dist/src/examples}/basic-use.js +0 -0
  573. /package/{src → dist/src}/examples/check-methods.js +0 -0
  574. /package/{docs/media → dist/src/examples}/cyclic-model.js +0 -0
  575. /package/{docs/media → dist/src/examples}/e5.js +0 -0
  576. /package/{docs/media → dist/src/examples}/hires.js +0 -0
  577. /package/{src → dist/src}/examples/index.js +0 -0
  578. /package/{docs/media → dist/src/examples}/model-updates.js +0 -0
  579. /package/{docs/media → dist/src/examples}/orego.js +0 -0
  580. /package/{docs/media → dist/src/examples}/pipeline-use.js +0 -0
  581. /package/{docs/media → dist/src/examples}/pollution.js +0 -0
  582. /package/{docs/media → dist/src/examples}/print-benchmark.js +0 -0
  583. /package/{docs/media → dist/src/examples}/scripting.js +0 -0
  584. /package/{docs/media → dist/src/examples}/vdpol.js +0 -0
  585. /package/{src → dist/src}/pipeline/basic-pipeline-creator.js +0 -0
  586. /package/{src → dist/src}/pipeline/constants.js +0 -0
  587. /package/{src → dist/src}/pipeline/index.js +0 -0
  588. /package/{src → dist/src}/pipeline/input.js +0 -0
  589. /package/{src → dist/src}/pipeline/loops-pipeline-creator.js +0 -0
  590. /package/{src → dist/src}/pipeline/pipeline.js +0 -0
  591. /package/{src → dist/src}/pipeline/updates-pipeline-creator.js +0 -0
  592. /package/{src → dist/src}/scripting-tools/constants.js +0 -0
  593. /package/{src → dist/src}/scripting-tools/index.js +0 -0
  594. /package/{src → dist/src}/solver-tools/callbacks/callback-base.js +0 -0
  595. /package/{src → dist/src}/solver-tools/callbacks/callback-tools.js +0 -0
  596. /package/{src → dist/src}/solver-tools/cvode/cvode.js +0 -0
  597. /package/{src → dist/src}/solver-tools/cvode/cvode_adams.js +0 -0
  598. /package/{src → dist/src}/solver-tools/cvode/cvode_bdf.js +0 -0
  599. /package/{src → dist/src}/solver-tools/cvode/cvode_hin.js +0 -0
  600. /package/{src → dist/src}/solver-tools/cvode/cvode_ls.js +0 -0
  601. /package/{src → dist/src}/solver-tools/cvode/cvode_nls.js +0 -0
  602. /package/{src → dist/src}/solver-tools/cvode/cvode_root.js +0 -0
  603. /package/{src → dist/src}/solver-tools/cvode/dense_linalg.js +0 -0
  604. /package/{src → dist/src}/solver-tools/cvode/index.js +0 -0
  605. /package/{src → dist/src}/solver-tools/cvode-method.js +0 -0
  606. /package/{src → dist/src}/solver-tools/index.js +0 -0
  607. /package/{src → dist/src}/solver-tools/lin-alg-tools.js +0 -0
  608. /package/{src → dist/src}/solver-tools/lsoda/blas.js +0 -0
  609. /package/{src → dist/src}/solver-tools/lsoda/cfode.js +0 -0
  610. /package/{src → dist/src}/solver-tools/lsoda/corfailure.js +0 -0
  611. /package/{src → dist/src}/solver-tools/lsoda/correction.js +0 -0
  612. /package/{src → dist/src}/solver-tools/lsoda/index.js +0 -0
  613. /package/{src → dist/src}/solver-tools/lsoda/intdy.js +0 -0
  614. /package/{src → dist/src}/solver-tools/lsoda/methodswitch.js +0 -0
  615. /package/{src → dist/src}/solver-tools/lsoda/orderswitch.js +0 -0
  616. /package/{src → dist/src}/solver-tools/lsoda/prja.js +0 -0
  617. /package/{src → dist/src}/solver-tools/lsoda/scaleh.js +0 -0
  618. /package/{src → dist/src}/solver-tools/lsoda/solsy.js +0 -0
  619. /package/{src → dist/src}/solver-tools/lsoda/stoda.js +0 -0
  620. /package/{src → dist/src}/solver-tools/lsoda-method.js +0 -0
  621. /package/{src → dist/src}/solver-tools/solver-defs.js +0 -0
  622. /package/{src → dist/src}/worker-tools/index.js +0 -0
  623. /package/{src → dist/src}/worker-tools/scripting.js +0 -0
  624. /package/{src → dist/src}/worker-tools/solving.js +0 -0
@@ -1,1582 +0,0 @@
1
- /* eslint-disable max-len */
2
- /* Scripting tools for the Initial Value Problem (IVP) solver:
3
- - parser of formulas defining IVP;
4
- - JS-script generator.
5
-
6
- The parser processes IVP formulas given in the declarative form (see README.md).
7
-
8
- JS-script generator creates DATAGROK JavaScript script: annotation & code.
9
- */
10
-
11
- import {CONTROL_TAG, CONTROL_TAG_LEN, CONTROL_EXPR, LOOP, UPDATE, MAX_LINE_CHART,
12
- SOLVER_OPTIONS_RANGES, TINY, STEP_RATIO} from './constants';
13
-
14
- import {ModelError} from './model-error';
15
-
16
- // Scripting specific constants
17
-
18
- /** @internal */
19
- export const CONTROL_SEP = ':';
20
-
21
- const COMMA = ',';
22
- const EQUAL_SIGN = '=';
23
- const DIV_SIGN = '/';
24
- const SERVICE = '_';
25
-
26
- /** @internal */
27
- export const BRACE_OPEN = '{';
28
-
29
- /** @internal */
30
- export const BRACE_CLOSE = '}';
31
-
32
- /** @internal */
33
- export const BRACKET_OPEN = '[';
34
-
35
- /** @internal */
36
- export const BRACKET_CLOSE = ']';
37
-
38
- /** @internal */
39
- export const ANNOT_SEPAR = ';';
40
-
41
- const DEFAULT_TOL = '0.00005';
42
-
43
- /** @internal */
44
- export const DEFAULT_SOLVER_SETTINGS: string = '{}';
45
-
46
- const COMMENT_SEQ = '//';
47
-
48
- /** @internal */
49
- export const STAGE_COL_NAME = `_Stage`;
50
- const INCEPTION = 'Inception';
51
-
52
- /** Elementary math tools
53
- * @internal
54
- */
55
- export const MATH_FUNCS = ['pow', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'sqrt', 'exp', 'log', 'sinh', 'cosh', 'tanh'];
56
-
57
- /** @internal */
58
- export const POW_IDX = MATH_FUNCS.indexOf('pow');
59
-
60
- /** @internal */
61
- export const MATH_CONSTS = ['PI', 'E'];
62
-
63
- /** Default meta */
64
- const defaultMetas = `//meta.runOnOpen: true
65
- //meta.runOnInput: true
66
- //meta.features: {"sens-analysis": true, "fitting": true}`;
67
-
68
- /**
69
- * Represents a numeric user input.
70
- *
71
- * @property value - The numeric value provided by the user.
72
- * @property annot - An optional annotation associated with the input.
73
- * See more details in the UI options documentation:
74
- * https://datagrok.ai/help/compute/diff-studio#user-interface-options
75
- */
76
- export type Input = {
77
- value: number,
78
- annot: string | null,
79
- };
80
-
81
- /**
82
- * Specifies an independent variable for a simulation model.
83
- *
84
- * @property name - The name of the variable.
85
- * @property initial - The initial value of the variable.
86
- * @property final - The final value of the variable.
87
- * @property step - The step size for the variable's grid.
88
- * @property updateName - The name of the stage in a multi-stage model, if applicable.
89
- */
90
- export type Arg = {
91
- name: string,
92
- initial: Input,
93
- final: Input,
94
- step: Input,
95
- updateName: string | undefined,
96
- };
97
-
98
- /** Input keys of Arg
99
- * @internal
100
- */
101
- export const ARG_INPUT_KEYS = ['initial', 'final', 'step'];
102
-
103
- /** Scripting specific constants
104
- * @internal
105
- */
106
- export enum SCRIPTING {
107
- ARG_NAME = 'name',
108
- COUNT = 'count',
109
- DURATION = 'duration',
110
- };
111
-
112
- /**
113
- * Represents a system of differential equations.
114
- *
115
- * @property equations - A mapping where each key is the name of a function
116
- * and each value is the right-hand side of its differential equation.
117
- *
118
- * @property solutionNames - Names of the functions that form the solution
119
- * of the system.
120
- */
121
- export type DifEqs = {
122
- equations: Map<string, string>,
123
- solutionNames: string[]
124
- };
125
-
126
- /**
127
- * Specifies a looped stage in a simulation model.
128
- *
129
- * @property count - The number of repetitions for the loop.
130
- * @property updates - An array of formulas or specifications that modify
131
- * the model's parameters during each iteration.
132
- */
133
- export type Loop = {
134
- count: Input,
135
- updates: string[],
136
- };
137
-
138
- /**
139
- * Represents an update of model parameters for a multi-stage simulation.
140
- *
141
- * @property name - The name of the simulation step.
142
- * @property durationFormula - A formula defining the duration of the step.
143
- * @property updates - An array of formulas that modify the model's parameters
144
- * during this update step.
145
- */
146
- export type Update = {
147
- name: string,
148
- durationFormula: string,
149
- updates: string[],
150
- };
151
-
152
- /**
153
- * Specifies an output of a simulation.
154
- *
155
- * @property caption - The title or label of the output.
156
- * @property formula - An optional formula used to compute the output.
157
- */
158
- export type Output = {
159
- caption: string,
160
- formula: string | null,
161
- };
162
-
163
- /**
164
- * Represents a fully parsed model defined declaratively.
165
- *
166
- * @property arg - Specification of the independent variable.
167
- * @property name - The name of the model.
168
- * @property tags - Tags associated with the model. See:
169
- * https://datagrok.ai/help/datagrok/concepts/functions/func-params-annotation
170
- * @property descr - Optional description of the model.
171
- * @property deqs - The specification of the ODE system.
172
- * @property exprs - Optional specification of auxiliary calculations.
173
- * @property inits - Specification of initial conditions.
174
- * @property consts - Specification of model constants.
175
- * @property params - Specification of model parameters.
176
- * @property tolerance - Tolerance for the numerical solver.
177
- * @property usedMathFuncs - Indices of used mathematical functions.
178
- * @property usedMathConsts - Indices of used mathematical constants.
179
- * @property loop - Optional specification of loops in the model.
180
- * @property updates - Optional specification of multi-stage simulation updates.
181
- * @property metas - Specification of meta-options for the model.
182
- * @property outputs - Optional specification of model outputs.
183
- * @property solverSettings - String representation of the numerical solver settings.
184
- * @property inputsLookup - Optional specification of lookup tables. See:
185
- * https://datagrok.ai/help/datagrok/concepts/functions/func-params-annotation#lookup-tables
186
- */
187
- export type IVP = {
188
- name: string,
189
- tags: string | null,
190
- descr: string | null,
191
- deqs: DifEqs,
192
- exprs: Map<string, string> | null,
193
- arg: Arg,
194
- inits: Map<string, Input>,
195
- consts: Map<string, Input> | null,
196
- params: Map<string, Input> | null,
197
- tolerance: string,
198
- usedMathFuncs: number[],
199
- usedMathConsts: number[],
200
- loop: Loop | null,
201
- updates: Update[] | null,
202
- metas: string[],
203
- outputs: Map<string, Output> | null,
204
- solverSettings: string,
205
- inputsLookup: string | null,
206
- };
207
-
208
- /** Help links for model errors */
209
- enum ERROR_LINK {
210
- MAIN_DOCS = '/help/compute/diff-studio',
211
- CORE_BLOCKS = `/help/compute/diff-studio#core-blocks`,
212
- COMPS_SYNTAX = `/help/compute/diff-studio#model-components-and-syntax`,
213
- LOOP = `/help/compute/diff-studio#cyclic-processes`,
214
- UPDATE = `/help/compute/diff-studio#multistage-processes`,
215
- UI_OPTS = `/help/compute/diff-studio#user-interface-options`,
216
- LOOP_VS_UPDATE = `/help/compute/diff-studio#advanced-features`,
217
- SOLVER_CONFIG = `/help/compute/diff-studio#solver-configuration`,
218
- MODEL_PARAMS = `/help/compute/diff-studio#model-parameters`,
219
- };
220
-
221
- /** Specific error messages */
222
- enum ERROR_MSG {
223
- CTRL_EXPR = `Unsupported control expression with the tag **"#"**`,
224
- ARG = `'The **#argument** block must consist of 3 lines specifying initial and final time, and solution grid step.`,
225
- LOOP = `The **#loop** block must contain at least one line.`,
226
- COUNT = 'Incorrect loop count',
227
- LOOP_VS_UPDATE = `The **#loop** and **'#update'** blocks cannot be used simultaneously.`,
228
- UPDATE_LINES_COUNT = `The **'#update'** block must contain at least one line.`,
229
- DURATION = 'Incorrect update duration',
230
- BRACES = ' Missing one of the braces (**{**, **}**).',
231
- COLON = `Incorrect position of **":"**.`,
232
- CASE_INSENS = 'Non-unique name (case-insensitive): use different caption for ',
233
- MISSING_INIT = `Correct the **#inits** block.`,
234
- UNDEF_NAME = `Model name missing. Specify the model name in the **#name** block.`,
235
- UNDEF_DEQS = `Differential equation(s) are required for this model. Add equation(s) under the **#equations** block.`,
236
- UNDEF_INITS = `Initial conditions are required for this model. Add initial conditions under the **#inits** block.`,
237
- UNDEF_ARG = `Argument specification is required for this model. Specify an argument, its range, and a grid step in the **#argument** block.`,
238
- CORRECT_ARG_LIM = `Correct limits in the **#argument** block.`,
239
- INTERVAL = `Incorrect range for`,
240
- NEGATIVE_STEP = `Solution grid step must be positive. Correct the **#argument** block.`,
241
- INCOR_STEP = `Grid step must less than the length of solution interval. Correct the **#argument** block.`,
242
- MISS_COLON = `Missing **":"**`,
243
- NAN = `is not a valid number. Correct the line`,
244
- SERVICE_START = `Variable names must not begin with **"_"**.`,
245
- REUSE_NAME = 'Variable reuse (case-insensitive): rename ',
246
- SOLVER = `Incorrect solver options. Correct the **#meta.solver** line.`,
247
- } // ERROR_MSG
248
-
249
- /** Datagrok annotations */
250
- enum ANNOT {
251
- NAME = '//name:',
252
- DESCR = '//description:',
253
- TAGS = '//tags:',
254
- LANG = '//language: javascript',
255
- DOUBLE_INPUT = '//input: double',
256
- INT_INPUT = '//input: int',
257
- OUTPUT = `//output: dataframe df`,
258
- EDITOR = '//editor: Compute:RichFunctionViewEditor',
259
- SIDEBAR = '//sidebar: @compute',
260
- CAPTION = 'caption:',
261
- ARG_INIT = '{caption: Initial; category: Argument}',
262
- ARG_FIN = '{caption: Final; category: Argument}',
263
- ARG_STEP = '{caption: Step; category: Argument}',
264
- INITS = 'category: Initial values',
265
- PARAMS = 'category: Parameters',
266
- }
267
-
268
- /** JS-scripting components */
269
- enum SCRIPT {
270
- CONSTS = '// constants',
271
- ODE_COM = '// the problem definition',
272
- ODE = 'let odes = {',
273
- SOLVER_COM = '// solve the problem',
274
- SOLVER = `const solver = await grok.functions.eval('DiffStudio:solveEquations');`,
275
- PREPARE = 'let call = solver.prepare({problem: odes, options: opts});',
276
- CALL = 'await call.call();',
277
- OUTPUT = `let df = call.getParamValue('df');`,
278
- SPACE2 = ' ',
279
- SPACE4 = ' ',
280
- SPACE6 = ' ',
281
- SPACE8 = ' ',
282
- FUNC_VALS = '// extract function values',
283
- EVAL_EXPR = '// evaluate expressions',
284
- COMP_OUT = '// compute output',
285
- MATH_FUNC_COM = '// used Math-functions',
286
- MATH_CONST_COM = '// used Math-constants',
287
- ONE_STAGE_COM = '\n// one stage solution',
288
- ONE_STAGE_BEGIN = 'let _oneStage = async (',
289
- ONE_STAGE_END = ') => {',
290
- ASYNC_OUTPUT = `let df = await _oneStage(`,
291
- RETURN_OUTPUT = `return call.getParamValue('df');`,
292
- EMPTY_OUTPUT = `let df = DG.DataFrame.create();`,
293
- APPEND = `df.append(`,
294
- SOLUTION_DF_COM = '// solution dataframe',
295
- LOOP_INTERVAL_COM = '// loop interval',
296
- LOOP_INTERVAL = `_interval`,
297
- LAST_IDX = `_lastIdx`,
298
- UPDATE_COM = '// update ',
299
- CUSTOM_OUTPUT_COM = '// create custom output',
300
- CUSTOM_COLUMNS = `let _columns = [`,
301
- ONE_STAGE = 'await _oneStage(',
302
- SEGMENT_COM = '// add segment category',
303
- }
304
-
305
- /** Limits of the problem specification */
306
- type Block = {
307
- begin: number,
308
- end: number
309
- }
310
-
311
- /** Get start of the problem skipping note-lines */
312
- function getStartOfProblemDef(lines: string[]): number {
313
- const linesCount = lines.length;
314
- let idx = 0;
315
-
316
- while (!lines[idx].startsWith(CONTROL_TAG)) {
317
- ++idx;
318
-
319
- if (idx === linesCount)
320
- throw new ModelError(ERROR_MSG.UNDEF_NAME, ERROR_LINK.CORE_BLOCKS);
321
- }
322
-
323
- return idx;
324
- }
325
-
326
- /** Get limits of blocks specifying IVP */
327
- function getBlocks(lines: string[], start: number): Block[] {
328
- const linesCount = lines.length;
329
- let beg = start;
330
- let idx = start + 1;
331
- const blocks = [] as Block[];
332
-
333
- while (true) {
334
- if (idx === linesCount) {
335
- blocks.push({begin: beg, end: idx});
336
- break;
337
- }
338
-
339
- if (lines[idx].startsWith(CONTROL_TAG)) {
340
- blocks.push({begin: beg, end: idx});
341
- beg = idx;
342
- }
343
-
344
- ++idx;
345
- }
346
-
347
- return blocks;
348
- }
349
-
350
- /** Concatenate multi-line formulas & expressions */
351
- function concatMultilineFormulas(source: string[]): string[] {
352
- const res: string[] = [source[0]];
353
-
354
- let idxRes = 0;
355
- let idxSource = 1;
356
- const size = source.length;
357
-
358
- while (idxSource < size) {
359
- const str = source[idxSource];
360
-
361
- if (!str.includes(EQUAL_SIGN))
362
- res[idxRes] += str;
363
- else {
364
- res.push(str);
365
- ++idxRes;
366
- }
367
-
368
- ++idxSource;
369
- }
370
-
371
- return res;
372
- }
373
-
374
- /** Get indeces of math functions used in the current text */
375
- function getUsedMathIds(text: string, mathIds: string[]) {
376
- const res = [] as number[];
377
- const size = mathIds.length;
378
-
379
- for (let i = 0; i < size; ++i) {
380
- if (text.includes(`${mathIds[i]}`))
381
- res.push(i);
382
- }
383
-
384
- return res;
385
- }
386
-
387
- /** Get differential equations */
388
- function getDifEquations(lines: string[]): DifEqs {
389
- const deqs = new Map<string, string>();
390
- const names = [] as string[];
391
-
392
- let divIdx = 0;
393
- let eqIdx = 0;
394
-
395
- for (const line of lines) {
396
- if (line === undefined)
397
- throw new ModelError(ERROR_MSG.UNDEF_DEQS, ERROR_LINK.CORE_BLOCKS, CONTROL_EXPR.DIF_EQ);
398
-
399
- divIdx = line.indexOf(DIV_SIGN);
400
- eqIdx = line.indexOf(EQUAL_SIGN);
401
- const name = line.slice(line.indexOf('d') + 1, divIdx).replace(/[() ]/g, '');
402
- names.push(name);
403
- deqs.set(name, line.slice(eqIdx + 1).trim());
404
- }
405
-
406
- return {
407
- equations: deqs,
408
- solutionNames: names,
409
- };
410
- }
411
-
412
- /** Get expressions of IVP */
413
- function getExpressions(lines: string[]): Map<string, string> {
414
- const exprs = new Map<string, string>();
415
- let eqIdx = 0;
416
-
417
- for (const line of lines) {
418
- if (line === undefined)
419
- break;
420
-
421
- eqIdx = line.indexOf(EQUAL_SIGN);
422
- exprs.set(line.slice(0, eqIdx).replaceAll(' ', ''), line.slice(eqIdx + 1).trim());
423
- }
424
-
425
- return exprs;
426
- }
427
-
428
- /** Get input specification */
429
- function getInput(line: string) : Input {
430
- const str = line.slice(line.indexOf(EQUAL_SIGN) + 1).trim();
431
- const braceIdx = str.indexOf(BRACE_OPEN);
432
- let val: number;
433
-
434
- if (braceIdx === -1) { // no annotation
435
- val = Number(str);
436
-
437
- // Check right-hand side
438
- if (isNaN(val))
439
- throw new ModelError(`**${str}** ${ERROR_MSG.NAN}\n **${line}**.`, ERROR_LINK.COMPS_SYNTAX, line);
440
-
441
- return {
442
- value: val,
443
- annot: null,
444
- };
445
- }
446
-
447
- // There is an annotation
448
- val = Number(str.slice(0, braceIdx));
449
-
450
- // Check right-hand side
451
- if (isNaN(val))
452
- throw new ModelError(`**${str.slice(0, braceIdx)}** ${ERROR_MSG.NAN}: **${line}**`, ERROR_LINK.COMPS_SYNTAX, line);
453
-
454
- return {
455
- value: val,
456
- annot: str.slice(braceIdx),
457
- };
458
- }
459
-
460
- /** Get argument (independent variable) of IVP */
461
- function getArg(lines: string[]): Arg {
462
- if (lines.length !== 4)
463
- throw new ModelError(ERROR_MSG.ARG, ERROR_LINK.CORE_BLOCKS, CONTROL_EXPR.ARG);
464
-
465
- const sepIdx = lines[0].indexOf(CONTROL_SEP);
466
- if (sepIdx === -1)
467
- throw new ModelError(`${ERROR_MSG.MISS_COLON}. Correct the line **${lines[0]}**`, ERROR_LINK.CORE_BLOCKS, lines[0]);
468
-
469
- const commaIdx = lines[0].indexOf(COMMA);
470
-
471
- return {
472
- name: ((commaIdx > -1) ? lines[0].slice(sepIdx + 1, commaIdx) : lines[0].slice(sepIdx + 1)).trim(),
473
- initial: getInput(lines[1]),
474
- final: getInput(lines[2]),
475
- step: getInput(lines[3]),
476
- updateName: (commaIdx > -1) ? lines[0].slice(commaIdx + 1).trim() : undefined,
477
- };
478
- }
479
-
480
- /** Get equalities specification */
481
- function getEqualities(lines: string[], begin: number, end: number): Map<string, Input> {
482
- const source = concatMultilineFormulas(lines.slice(begin, end));
483
- const eqs = new Map<string, Input>();
484
- let eqIdx = 0;
485
-
486
- for (const line of source) {
487
- if (line === undefined)
488
- break;
489
-
490
- eqIdx = line.indexOf(EQUAL_SIGN);
491
- eqs.set(line.slice(0, eqIdx).replaceAll(' ', ''), getInput(line));
492
- }
493
-
494
- return eqs;
495
- }
496
-
497
- /** Get loop specification */
498
- function getLoop(lines: string[], begin: number, end: number): Loop {
499
- if (begin >= end)
500
- throw new ModelError(ERROR_MSG.LOOP, ERROR_LINK.LOOP, CONTROL_EXPR.LOOP);
501
-
502
- const source = concatMultilineFormulas(lines.slice(begin, end));
503
- const size = source.length;
504
-
505
- if (size < LOOP.MIN_LINES_COUNT)
506
- throw new ModelError(ERROR_MSG.LOOP, ERROR_LINK.LOOP, CONTROL_EXPR.LOOP);
507
-
508
- const count = getInput(source[LOOP.COUNT_IDX]);
509
- if (count.value < LOOP.MIN_COUNT)
510
- throw new ModelError(`${ERROR_MSG.COUNT}: **${count.value}**.`, ERROR_LINK.LOOP, source[LOOP.COUNT_IDX]);
511
-
512
- return {count: count, updates: source.slice(LOOP.COUNT_IDX + 1)};
513
- }
514
-
515
- /** Get update specification */
516
- function getUpdate(lines: string[], begin: number, end: number): Update {
517
- const colonIdx = lines[begin].indexOf(CONTROL_SEP);
518
- if (colonIdx === -1) {
519
- throw new ModelError(
520
- `${ERROR_MSG.MISS_COLON}. Correct the line: **${lines[begin]}**`,
521
- ERROR_LINK.UPDATE,
522
- lines[begin],
523
- );
524
- }
525
-
526
- const source = concatMultilineFormulas(lines.slice(begin + 1, end));
527
- const size = source.length;
528
-
529
- if (size < UPDATE.MIN_LINES_COUNT)
530
- throw new ModelError(ERROR_MSG.UPDATE_LINES_COUNT, ERROR_LINK.UPDATE, CONTROL_EXPR.UPDATE);
531
-
532
- if (source[UPDATE.DURATION_IDX] == undefined)
533
- throw new ModelError(ERROR_MSG.UPDATE_LINES_COUNT, ERROR_LINK.UPDATE, CONTROL_EXPR.UPDATE);
534
-
535
- const eqIdx = source[UPDATE.DURATION_IDX].indexOf(EQUAL_SIGN);
536
-
537
- if (eqIdx === -1) {
538
- throw new ModelError(
539
- `Missing **${EQUAL_SIGN}**. Correct the line: **${source[UPDATE.DURATION_IDX]}**`,
540
- ERROR_LINK.UPDATE,
541
- source[UPDATE.DURATION_IDX],
542
- );
543
- }
544
-
545
- return {
546
- name: lines[begin].slice(colonIdx + 1),
547
- durationFormula: source[UPDATE.DURATION_IDX].slice(eqIdx + 1).trim(),
548
- updates: source.slice(UPDATE.DURATION_IDX + 1),
549
- };
550
- } // getUpdate
551
-
552
- /** Get output specification */
553
- function getOutput(lines: string[], begin: number, end: number): Map<string, Output> {
554
- const res = new Map<string, Output>();
555
-
556
- let line: string;
557
- let token: string;
558
- let eqIdx: number;
559
- let openIdx: number;
560
- let closeIdx: number;
561
- let colonIdx: number;
562
-
563
- for (let i = begin; i < end; ++i) {
564
- line = lines[i].trim();
565
-
566
- if (line.length < 1)
567
- continue;
568
-
569
- eqIdx = line.indexOf(EQUAL_SIGN);
570
- openIdx = line.indexOf(BRACE_OPEN);
571
- closeIdx = line.indexOf(BRACE_CLOSE);
572
- colonIdx = line.indexOf(CONTROL_SEP);
573
-
574
- // check braces
575
- if (openIdx * closeIdx <= 0) {
576
- throw new ModelError(
577
- `${ERROR_MSG.BRACES} Correct the line **${line}** in the **${CONTROL_EXPR.OUTPUT}** block.`,
578
- ERROR_LINK.UI_OPTS,
579
- line,
580
- );
581
- }
582
-
583
- // check ":"
584
- if (openIdx * colonIdx <= 0) {
585
- throw new ModelError(
586
- `${ERROR_MSG.COLON} Correct the line **${line}** in the **#output** block.`,
587
- ERROR_LINK.UI_OPTS,
588
- line,
589
- );
590
- }
591
-
592
- if (eqIdx === -1) {// no formula
593
- if (openIdx === -1) { // no annotation
594
- token = line.trim();
595
- res.set(token, {
596
- caption: token,
597
- formula: null,
598
- });
599
- } else { // there is an annotation
600
- token = line.slice(0, openIdx).trim();
601
- res.set(token, {
602
- caption: line.slice(colonIdx + 1, closeIdx).trim(),
603
- formula: null,
604
- });
605
- }
606
- } else // there is a formula
607
- if (openIdx === -1) { // no annotation
608
- token = line.slice(0, eqIdx).trim();
609
- res.set(token, {
610
- caption: token,
611
- formula: line.slice(eqIdx + 1),
612
- });
613
- } else { // there is an annotation
614
- token = line.slice(0, eqIdx).trim();
615
- res.set(token, {
616
- caption: line.slice(colonIdx + 1, closeIdx),
617
- formula: line.slice(eqIdx + 1, openIdx),
618
- });
619
- }
620
- } // for i
621
-
622
- return res;
623
- } // getOutput
624
-
625
- /** Return initial value problem specification given in the text
626
- * @param text - declarative specification of initial value problem
627
- * @example
628
- * // Here, we consider modeling queues: https://en.wikipedia.org/wiki/M/M/c_queue
629
- * import * as DGL from 'diff-grok';
630
- *
631
- * // 1. Model specification: the M|M|2|2 model
632
- * const model = `#name: M|M|2|2
633
- * #description: Modelling the system with two servers & two waiting places (EXPLAINED)
634
- *
635
- * #equations:
636
- * dp0/dt = -la * p0 + mu * p1
637
- * dp1/dt = la * p0 - (la + mu) * p1 + 2 * mu * p2
638
- * dp2/dt = la * p1 - (la + 2 * mu) * p2 + 2 * mu * p3
639
- * dp3/dt = la * p2 - (la + 2 * mu) * p3 + 2 * mu * p4
640
- *
641
- * #expressions:
642
- * la = 1 / arrival
643
- * mu = 1 / service
644
- * p4 = 1 - p0 - p1 - p2 - p3
645
- * busy = 1 - p0 - p1
646
- * queue = p3 + 2 * p4
647
- *
648
- * #argument: t
649
- * _t0 = 0 {min: 0; max: 10; caption: start; category: Time; units: min} [Initial time of simulation]
650
- * _t1 = 60 {min: 20; max: 100; caption: finish; category: Time; units: min} [Final time of simulation]
651
- * _h = 1 {min: 0.01; max: 0.1; caption: step; category: Time; units: min} [Time step of simulation]
652
- *
653
- * #inits:
654
- * p0 = 1 {min: 0; max: 1; category: Initial state; caption: empty} [Probability that initially there are NO customers]
655
- * p1 = 0 {min: 0; max: 1; category: Initial state; caption: single} [Probability that initially there is ONE customer]
656
- * p2 = 0 {min: 0; max: 1; category: Initial state; caption: two} [Probability that initially there are TWO customers]
657
- * p3 = 0 {min: 0; max: 1; category: Initial state; caption: three} [Probability that initially there are THREE customers]
658
- *
659
- * #output:
660
- * t {caption: Time, min}
661
- * p0 {caption: P(Empty)}
662
- * busy {caption: P(Full load)}
663
- * queue {caption: E(Queue)}
664
- *
665
- * #parameters:
666
- * arrival = 10 {min: 1; max: 100; category: Means; caption: arrival; units: min} [Mean arrival time]
667
- * service = 100 {min: 1; max: 100; category: Means; caption: service; units: min} [Mean service time]`;
668
- *
669
- * // 2. Generate IVP-objects: for the main thread & for computations in webworkers
670
- * const ivp = DGL.getIVP(model);
671
- * const ivpWW = DGL.getIvp2WebWorker(ivp);
672
- *
673
- * // 3. Perform computations
674
- * try {
675
- * // 3.1) Extract names of outputs
676
- * const outputNames = DGL.getOutputNames(ivp);
677
- * const outSize = outputNames.length;
678
- *
679
- * // 3.2) Set model inputs
680
- * const inputs = {
681
- * _t0: 0, // Initial time of simulation
682
- * _t1: 60, // Final time of simulation
683
- * _h: 1, // Time step of simulation
684
- * p0: 1, // Probability that initially there are NO customers
685
- * p1: 0, // Probability that initially there is ONE customer
686
- * p2: 0, // Probability that initially there are TWO customers
687
- * p3: 0, // Probability that initially there are THREE customers
688
- * arrival: 10, // Mean arrival time
689
- * service: 100, // Mean service time
690
- * };
691
- * const inputVector = DGL.getInputVector(inputs, ivp);
692
- *
693
- * // 3.3) Create a pipeline
694
- * const creator = DGL.getPipelineCreator(ivp);
695
- * const pipeline = creator.getPipeline(inputVector);
696
- *
697
- * // 3.4) Apply pipeline to perform computations
698
- * const solution = DGL.applyPipeline(pipeline, ivpWW, inputVector);
699
- * // 3.5) Print results
700
- *
701
- * // 3.5.1) Table header
702
- * let line = '';
703
- * outputNames.forEach((name) => line += name + ' ');
704
- * console.log(line);
705
- *
706
- * // 3.5.2) Table with solution
707
- * const length = solution[0].length;
708
- * for (let i = 0; i < length; ++i) {
709
- * line = '';
710
- *
711
- * for (let j = 0; j < outSize; ++j)
712
- * line += solution[j][i].toFixed(8) + ' ';
713
- * console.log(line);
714
- * }
715
- * } catch (err) {
716
- * console.log('Simulation failed: ', err instanceof Error ? err.message : 'Unknown problem!');
717
- * }
718
- */
719
- export function getIVP(text: string): IVP {
720
- // The current Initial Value Problem (IVP) specification
721
- let name: string;
722
- let tags: string | null = null;
723
- let descr: string | null = null;
724
- let deqs: DifEqs;
725
- let exprs: Map<string, string> | null = null;
726
- let arg: Arg;
727
- let inits: Map<string, Input>;
728
- let consts: Map<string, Input> | null = null;
729
- let params: Map<string, Input> | null = null;
730
- let tolerance = DEFAULT_TOL;
731
- let loop: Loop | null = null;
732
- const updates = [] as Update[];
733
- const metas = [] as string[];
734
- let outputs: Map<string, Output> | null = null;
735
- let solverSettings = DEFAULT_SOLVER_SETTINGS;
736
- let inputsLookup: string | null = null;
737
-
738
- // 0. Split text into lines & remove comments
739
- const lines = text.replaceAll('\t', ' ').split('\n')
740
- .map((s) => {
741
- const idx = s.indexOf(COMMENT_SEQ);
742
- return s.slice(0, (idx >= 0) ? idx : undefined).trimStart();
743
- })
744
- .filter((s) => s !== '');
745
-
746
- // 1. Skip first lines without the control tag
747
- const start = getStartOfProblemDef(lines);
748
-
749
- // 2. Get blocks limits
750
- const blocks = getBlocks(lines, start);
751
-
752
- // 3. Process blocks
753
- for (const block of blocks) {
754
- const firstLine = lines[block.begin];
755
-
756
- if (firstLine.startsWith(CONTROL_EXPR.NAME)) { // the 'name' block
757
- name = firstLine.slice(firstLine.indexOf(CONTROL_SEP) + 1).trim();
758
- } else if (firstLine.startsWith(CONTROL_EXPR.TAGS)) { // the 'tags' block
759
- tags = firstLine.slice(firstLine.indexOf(CONTROL_SEP) + 1).trim();
760
- } else if (firstLine.startsWith(CONTROL_EXPR.DESCR)) { // the 'description' block
761
- descr = firstLine.slice(firstLine.indexOf(CONTROL_SEP) + 1).trim();
762
- } else if (firstLine.startsWith(CONTROL_EXPR.DIF_EQ)) { // the 'differential equations' block
763
- deqs = getDifEquations(concatMultilineFormulas(lines.slice(block.begin + 1, block.end)));
764
- } else if (firstLine.startsWith(CONTROL_EXPR.EXPR)) { // the 'expressions' block
765
- exprs = getExpressions(concatMultilineFormulas(lines.slice(block.begin + 1, block.end)));
766
- } else if (firstLine.startsWith(CONTROL_EXPR.ARG)) { // the 'argument' block
767
- arg = getArg(concatMultilineFormulas(lines.slice(block.begin, block.end)));
768
- } else if (firstLine.startsWith(CONTROL_EXPR.INITS)) { // the 'initial values' block
769
- inits = getEqualities(lines, block.begin + 1, block.end);
770
- } else if (firstLine.startsWith(CONTROL_EXPR.CONSTS)) { // the 'constants' block
771
- consts = getEqualities(lines, block.begin + 1, block.end);
772
- } else if (firstLine.startsWith(CONTROL_EXPR.PARAMS)) { // the 'parameters' block
773
- params = getEqualities(lines, block.begin + 1, block.end);
774
- } else if (firstLine.startsWith(CONTROL_EXPR.TOL)) { // the 'tolerance' block
775
- tolerance = firstLine.slice( firstLine.indexOf(CONTROL_SEP) + 1).trim();
776
- } else if (firstLine.startsWith(CONTROL_EXPR.SOLVER)) { // the 'solver settings' block
777
- solverSettings = firstLine.slice(firstLine.indexOf(CONTROL_SEP) + 1).trim();
778
- } else if (firstLine.startsWith(CONTROL_EXPR.LOOP)) { // the 'loop' block
779
- loop = getLoop(lines, block.begin + 1, block.end);
780
- } else if (firstLine.startsWith(CONTROL_EXPR.UPDATE)) { // the 'update' block
781
- updates.push(getUpdate(lines, block.begin, block.end));
782
- } else if (firstLine.startsWith(CONTROL_EXPR.OUTPUT)) { // the 'output' block
783
- outputs = getOutput(lines, block.begin + 1, block.end);
784
- } else if (firstLine.startsWith(CONTROL_EXPR.INPUTS)) { // the 'inputs' block
785
- inputsLookup = firstLine.slice(firstLine.indexOf(CONTROL_SEP) + 1).trim();
786
- } else if (firstLine.startsWith(CONTROL_EXPR.COMMENT)) { // the 'comment' block
787
- // just skip it
788
- } else
789
- metas.push(firstLine.slice(CONTROL_TAG_LEN));
790
- } // for
791
-
792
- // check loop- & update-features: just one is supported
793
- if ( (loop !== null) && (updates.length > 0))
794
- throw new ModelError(ERROR_MSG.LOOP_VS_UPDATE, ERROR_LINK.LOOP_VS_UPDATE, CONTROL_EXPR.LOOP);
795
-
796
- // obtained model
797
- const ivp = {
798
- name: name!,
799
- tags: tags,
800
- descr: descr,
801
- deqs: deqs!,
802
- exprs: exprs,
803
- arg: arg!,
804
- inits: inits!,
805
- consts: consts,
806
- params: params,
807
- tolerance: tolerance,
808
- usedMathFuncs: getUsedMathIds(text, MATH_FUNCS),
809
- usedMathConsts: getUsedMathIds(text, MATH_CONSTS),
810
- loop: loop,
811
- updates: (updates.length === 0) ? null : updates,
812
- metas: metas,
813
- outputs: outputs,
814
- solverSettings: solverSettings,
815
- inputsLookup: inputsLookup,
816
- };
817
-
818
- checkCorrectness(ivp);
819
-
820
- return ivp;
821
- } // getIVP
822
-
823
- /** Return input specification, required for annotation generating */
824
- function getInputSpec(inp: Input): string {
825
- if (inp.annot)
826
- return `${inp.value} ${inp.annot}`;
827
-
828
- return `${inp.value}`;
829
- }
830
-
831
- /** Return annotation line specifying viewers */
832
- function getViewersLine(ivp: IVP): string {
833
- const outputColsCount = (ivp.outputs) ? ivp.outputs.size : ivp.inits.size;
834
- const multiAxis = (outputColsCount > MAX_LINE_CHART - 1) ? 'true' : 'false';
835
-
836
- const segments = (ivp.updates) ? ` segmentColumnName: "${STAGE_COL_NAME}",` : '';
837
-
838
- // eslint-disable-next-line max-len
839
- return `viewer: Line chart(block: 100, multiAxis: "${multiAxis}",${segments} multiAxisLegendPosition: "RightCenter", autoLayout: "false", showAggrSelectors: "false") | Grid(block: 100)`;
840
- }
841
-
842
- /** Generate annotation lines */
843
- function getAnnot(ivp: IVP, toAddViewers = true, toAddEditor = false): string[] {
844
- const res = [] as string[];
845
-
846
- // the 'name' line
847
- res.push(`${ANNOT.NAME} ${ivp.name}`);
848
-
849
- // the 'tags' line
850
- if (ivp.tags)
851
- res.push(`${ANNOT.TAGS} ${ivp.tags}`);
852
-
853
- // the 'description' line
854
- if (ivp.descr)
855
- res.push(`${ANNOT.DESCR} ${ivp.descr}`);
856
-
857
- // the 'language' line
858
- res.push(ANNOT.LANG);
859
-
860
- // the 'loop' lines
861
- if (ivp.loop)
862
- res.push(`${ANNOT.INT_INPUT} ${LOOP.COUNT_NAME} = ${getInputSpec(ivp.loop.count)}`);
863
-
864
- // argument lines
865
- const arg = ivp.arg;
866
- const t0 = `_${arg.name}0`;
867
- const t1 = `_${arg.name}1`;
868
- const h = `_h`;
869
- res.push(`${ANNOT.DOUBLE_INPUT} ${t0} = ${getInputSpec(arg.initial)}`);
870
- res.push(`${ANNOT.DOUBLE_INPUT} ${t1} = ${getInputSpec(arg.final)}`);
871
- res.push(`${ANNOT.DOUBLE_INPUT} ${h} = ${getInputSpec(arg.step)}`);
872
-
873
- // initial values lines
874
- ivp.inits.forEach((val, key) => res.push(`${ANNOT.DOUBLE_INPUT} ${key} = ${getInputSpec(val)}`));
875
-
876
- // parameters lines
877
- if (ivp.params !== null)
878
- ivp.params.forEach((val, key) => res.push(`${ANNOT.DOUBLE_INPUT} ${key} = ${getInputSpec(val)}`));
879
-
880
- // the 'output' line
881
- if (toAddViewers)
882
- res.push(`${ANNOT.OUTPUT} {${ANNOT.CAPTION} ${ivp.name}; ${getViewersLine(ivp)}}`);
883
- else
884
- res.push(`${ANNOT.OUTPUT} {${ANNOT.CAPTION} ${ivp.name}`);
885
-
886
- // the 'editor' line
887
- if (toAddEditor) {
888
- res.push(ANNOT.EDITOR);
889
- res.push(ANNOT.SIDEBAR);
890
- }
891
-
892
- if (ivp.metas.length >0)
893
- ivp.metas.forEach((line) => res.push(`//${line}`));
894
- else
895
- res.push(defaultMetas);
896
-
897
- return res;
898
- } // getAnnot
899
-
900
- /** Returns math functions arguments string
901
- * @internal
902
- */
903
- function getMathArg(funcIdx: number): string {
904
- return (funcIdx > POW_IDX) ? '(x)' : '(x, y)';
905
- }
906
-
907
- /** Return custom output lines: no expressions */
908
- function getCustomOutputLinesNoExpressions(name: string,
909
- outputs: Map<string, Output>, toAddUpdateCol: boolean): string[] {
910
- const res = [''];
911
-
912
- res.push(SCRIPT.CUSTOM_OUTPUT_COM);
913
- res.push(SCRIPT.CUSTOM_COLUMNS);
914
-
915
- outputs.forEach((val, key) => {
916
- if (!val.formula)
917
- res.push(`${SCRIPT.SPACE2}df.col('${key}'),`);
918
- });
919
-
920
- if (toAddUpdateCol)
921
- res.push(`${SCRIPT.SPACE2}df.col('${STAGE_COL_NAME}'),`);
922
-
923
- res.push('];');
924
-
925
- outputs.forEach((val, key) => {
926
- if (!val.formula)
927
- res.push(`df.col('${key}').name = '${val.caption}';`);
928
- });
929
-
930
- res.push(`df = DG.DataFrame.fromColumns(_columns);`);
931
- res.push(`df.name = '${name}';`);
932
- return res;
933
- } // getCustomOutputLinesNoExpressions
934
-
935
- /** Return custom output lines: with expressions */
936
- function getCustomOutputLinesWithExpressions(ivp: IVP): string[] {
937
- const res = [''];
938
-
939
- res.push(SCRIPT.CUSTOM_OUTPUT_COM);
940
-
941
- // 1. Solution raw data
942
- res.push(`const ${ivp.arg.name}RawData = df.col('${ivp.arg.name}').getRawData();`);
943
- res.push(`let ${ivp.arg.name};`);
944
- res.push(`const len = df.rowCount;\n`);
945
-
946
- ivp.inits.forEach((val, key) => {
947
- res.push(`const ${key}RawData = df.col('${key}').getRawData();`);
948
- });
949
-
950
- res.push('');
951
-
952
- // 2. Expressions raw data & variables
953
- ivp.exprs!.forEach((val, key) => {
954
- if (ivp.outputs!.has(key))
955
- res.push(`const ${key}RawData = new Float64Array(len);`);
956
-
957
- res.push(`let ${key};`);
958
- });
959
-
960
- res.push('');
961
-
962
- // 3. Computations
963
- res.push('for (let i = 0; i < len; ++i) {');
964
- res.push(`${SCRIPT.SPACE2}${ivp.arg.name} = ${ivp.arg.name}RawData[i];`);
965
-
966
- ivp.inits.forEach((val, key) => {
967
- res.push(`${SCRIPT.SPACE2}${key} = ${key}RawData[i];`);
968
- });
969
-
970
- ivp.exprs!.forEach((val, key) => {
971
- res.push(`${SCRIPT.SPACE2}${key} = ${val};`);
972
-
973
- if (ivp.outputs!.has(key))
974
- res.push(`${SCRIPT.SPACE2}${key}RawData[i] = ${key};`);
975
- });
976
-
977
- res.push('}\n');
978
-
979
- // 4. Form output
980
- res.push(`df = DG.DataFrame.fromColumns([`);
981
- ivp.outputs!.forEach((val, key) => {
982
- if (!val.formula)
983
- res.push(`${SCRIPT.SPACE2}DG.Column.fromFloat64Array('${val.caption}', ${key}RawData.slice(0, len)),`);
984
- });
985
-
986
- if (ivp.updates !== null)
987
- res.push(`${SCRIPT.SPACE2}df.col('${STAGE_COL_NAME}'),`);
988
-
989
- res.push(']);');
990
- res.push(`df.name = '${ivp.name}';`);
991
-
992
- return res;
993
- } // getCustomOutputLinesWithExpressions
994
-
995
- /** Return custom output lines */
996
- function getCustomOutputLines(ivp: IVP): string[] {
997
- if (ivp.exprs !== null) {
998
- for (const key of ivp.exprs.keys()) {
999
- if (ivp.outputs?.has(key))
1000
- return getCustomOutputLinesWithExpressions(ivp);
1001
- }
1002
- }
1003
-
1004
- return getCustomOutputLinesNoExpressions(ivp.name, ivp.outputs!, (ivp.updates !== null));
1005
- } // getCustomOutputLinesWithExpressions
1006
-
1007
- /** Return main body of JS-script: basic variant */
1008
- function getScriptMainBodyBasic(ivp: IVP): string[] {
1009
- const res = [] as string[];
1010
-
1011
- // 1. Constants lines
1012
- if (ivp.consts !== null) {
1013
- res.push('');
1014
- res.push(SCRIPT.CONSTS);
1015
- ivp.consts.forEach((val, key) => res.push(`const ${key} = ${val.value};`));
1016
- }
1017
-
1018
- // 2. The problem definition lines
1019
- res.push('');
1020
- res.push(SCRIPT.ODE_COM);
1021
- res.push(SCRIPT.ODE);
1022
- res.push(`${SCRIPT.SPACE4}name: '${ivp.name}',`);
1023
-
1024
- // 2.1) argument
1025
- const t = ivp.arg.name;
1026
- const t0 = `_${t}0`;
1027
- const t1 = `_${t}1`;
1028
- const h = `_h`;
1029
- res.push(`${SCRIPT.SPACE4}arg: {name: '${t}', start: ${t0}, finish: ${t1}, step: ${h}},`);
1030
-
1031
- const names = ivp.deqs.solutionNames;
1032
-
1033
- // 2.2) initial values
1034
- res.push(`${SCRIPT.SPACE4}initial: [${names.join(', ')}],`);
1035
-
1036
- // 2.3) the right-hand side of the problem
1037
- res.push(`${SCRIPT.SPACE4}func: (${t}, _y, _output) => {`);
1038
-
1039
- res.push(`${SCRIPT.SPACE6}${SCRIPT.FUNC_VALS}`);
1040
- names.forEach((name, idx) => res.push(`${SCRIPT.SPACE6}const ${name} = _y[${idx}];`));
1041
-
1042
- if (ivp.exprs !== null) {
1043
- res.push(`\n${SCRIPT.SPACE6}${SCRIPT.EVAL_EXPR}`);
1044
- ivp.exprs.forEach((val, key) => res.push(`${SCRIPT.SPACE6}const ${key} = ${val};`));
1045
- }
1046
-
1047
- res.push(`\n${SCRIPT.SPACE6}${SCRIPT.COMP_OUT}`);
1048
- names.forEach((name, idx) => res.push(`${SCRIPT.SPACE6}_output[${idx}] = ${ivp.deqs.equations.get(name)};`));
1049
-
1050
- res.push(`${SCRIPT.SPACE4}},`);
1051
-
1052
- // 2.4) final lines of the problem specification
1053
- res.push(`${SCRIPT.SPACE4}tolerance: ${ivp.tolerance},`);
1054
- //res.push(`${SCRIPT.SPACE6}solverOptions: ${ivp.solverSettings.replaceAll(ANNOT_SEPAR, COMMA)},`);
1055
- res.push(`${SCRIPT.SPACE4}solutionColNames: [${names.map((key) => `'${key}'`).join(', ')}]`);
1056
- res.push('};');
1057
-
1058
- // 2.5) solver options
1059
- res.push('');
1060
- res.push(`let opts = ${ivp.solverSettings.replaceAll(';', ',')};`);
1061
-
1062
- // 3. Math functions
1063
- if (ivp.usedMathFuncs.length > 0) {
1064
- res.push('');
1065
- res.push(SCRIPT.MATH_FUNC_COM);
1066
- ivp.usedMathFuncs.forEach((i) =>
1067
- res.push(`const ${MATH_FUNCS[i]} = ${getMathArg(i)} => Math.${MATH_FUNCS[i]}${getMathArg(i)};`,
1068
- ));
1069
- }
1070
-
1071
- // 4. Math constants
1072
- if (ivp.usedMathConsts.length > 0) {
1073
- res.push('');
1074
- res.push(SCRIPT.MATH_CONST_COM);
1075
- ivp.usedMathConsts.forEach((i) => res.push(`const ${MATH_CONSTS[i]} = Math.${MATH_CONSTS[i]};`));
1076
- }
1077
-
1078
- // 5. The 'call solver' lines
1079
- res.push('');
1080
- res.push(SCRIPT.SOLVER_COM);
1081
- res.push(SCRIPT.SOLVER);
1082
- res.push(SCRIPT.PREPARE);
1083
- res.push(SCRIPT.CALL);
1084
- res.push(SCRIPT.OUTPUT);
1085
-
1086
- return res;
1087
- } // getScriptMainBodyBasic
1088
-
1089
- /** Return function for JS-script */
1090
- function getScriptFunc(ivp: IVP, funcParamsNames: string): string[] {
1091
- const res = [] as string[];
1092
-
1093
- // 0. Function declaration
1094
- res.push(SCRIPT.ONE_STAGE_COM);
1095
- res.push(`${SCRIPT.ONE_STAGE_BEGIN}${funcParamsNames}${SCRIPT.ONE_STAGE_END}`);
1096
-
1097
- // 1. Constants lines
1098
- if (ivp.consts !== null) {
1099
- res.push('');
1100
- res.push(SCRIPT.SPACE2 + SCRIPT.CONSTS);
1101
- ivp.consts.forEach((val, key) => res.push(`${SCRIPT.SPACE2}const ${key} = ${val.value};`));
1102
- }
1103
-
1104
- // 2. The problem definition lines
1105
- res.push(SCRIPT.SPACE2 + SCRIPT.ODE_COM);
1106
- res.push(SCRIPT.SPACE2 + SCRIPT.ODE);
1107
- res.push(`${SCRIPT.SPACE6}name: '${ivp.name}',`);
1108
-
1109
- // 2.1) argument
1110
- const t = ivp.arg.name;
1111
- const t0 = `_${t}0`;
1112
- const t1 = `_${t}1`;
1113
- const h = `_h`;
1114
- res.push(`${SCRIPT.SPACE6}arg: {name: '${t}', start: ${t0}, finish: ${t1}, step: ${h}},`);
1115
-
1116
- const names = ivp.deqs.solutionNames;
1117
-
1118
- // 2.2) initial values
1119
- res.push(`${SCRIPT.SPACE6}initial: [${names.join(', ')}],`);
1120
-
1121
- // 2.3) the right-hand side of the problem
1122
- res.push(`${SCRIPT.SPACE6}func: (${t}, _y, _output) => {`);
1123
-
1124
- res.push(`${SCRIPT.SPACE8}${SCRIPT.FUNC_VALS}`);
1125
- names.forEach((name, idx) => res.push(`${SCRIPT.SPACE8}const ${name} = _y[${idx}];`));
1126
-
1127
- if (ivp.exprs !== null) {
1128
- res.push(`\n${SCRIPT.SPACE8}${SCRIPT.EVAL_EXPR}`);
1129
- ivp.exprs.forEach((val, key) => res.push(`${SCRIPT.SPACE8}const ${key} = ${val};`));
1130
- }
1131
-
1132
- res.push(`\n${SCRIPT.SPACE8}${SCRIPT.COMP_OUT}`);
1133
- names.forEach((name, idx) => res.push(`${SCRIPT.SPACE8}_output[${idx}] = ${ivp.deqs.equations.get(name)};`));
1134
-
1135
- res.push(`${SCRIPT.SPACE6}},`);
1136
-
1137
- // 2.4) final lines of the problem specification
1138
- res.push(`${SCRIPT.SPACE6}tolerance: ${ivp.tolerance},`);
1139
- //res.push(`${SCRIPT.SPACE6}solverOptions: ${ivp.solverSettings.replaceAll(ANNOT_SEPAR, COMMA)},`);
1140
- res.push(`${SCRIPT.SPACE6}solutionColNames: [${names.map((key) => `'${key}'`).join(', ')}]`);
1141
- res.push(`${SCRIPT.SPACE2}};`);
1142
-
1143
- // 2.5) solver options
1144
- res.push('');
1145
- res.push(`${SCRIPT.SPACE2}let opts = ${ivp.solverSettings.replaceAll(';', ',')};`);
1146
-
1147
- // 3. Math functions
1148
- if (ivp.usedMathFuncs.length > 0) {
1149
- res.push('');
1150
- res.push(SCRIPT.SPACE2 + SCRIPT.MATH_FUNC_COM);
1151
- // eslint-disable-next-line max-len
1152
- ivp.usedMathFuncs.forEach((i) => res.push(`${SCRIPT.SPACE2}const ${MATH_FUNCS[i]} = ${getMathArg(i)} => Math.${MATH_FUNCS[i]}${getMathArg(i)};`));
1153
- }
1154
-
1155
- // 4. Math constants
1156
- if (ivp.usedMathConsts.length > 0) {
1157
- res.push('');
1158
- res.push(SCRIPT.SPACE2 + SCRIPT.MATH_CONST_COM);
1159
- ivp.usedMathConsts.forEach((i) => res.push(`${SCRIPT.SPACE2}const ${MATH_CONSTS[i]} = Math.${MATH_CONSTS[i]};`));
1160
- }
1161
-
1162
- // 5. The 'call solver' lines
1163
- res.push('');
1164
- res.push(SCRIPT.SPACE2 + SCRIPT.SOLVER_COM);
1165
- res.push(SCRIPT.SPACE2 + SCRIPT.SOLVER);
1166
- res.push(SCRIPT.SPACE2 + SCRIPT.PREPARE);
1167
- res.push(SCRIPT.SPACE2 + SCRIPT.CALL);
1168
- res.push(SCRIPT.SPACE2 + SCRIPT.RETURN_OUTPUT);
1169
-
1170
- // 6. Close the function
1171
- res.push('};');
1172
-
1173
- return res;
1174
- } // getScriptFunc
1175
-
1176
- /** Return main body of JS-script: loop case */
1177
- function getScriptMainBodyLoopCase(ivp: IVP): string[] {
1178
- const funcParamsNames = getFuncParamsNames(ivp);
1179
- const res = getScriptFunc(ivp, funcParamsNames);
1180
- res.push('');
1181
- //res.push(`${SCRIPT.ASYNC_OUTPUT}${funcParamsNames});`);
1182
-
1183
- res.push(SCRIPT.SOLUTION_DF_COM);
1184
- const dfNames = getSolutionDfColsNames(ivp);
1185
-
1186
- res.push(`let df = DG.DataFrame.fromColumns([`);
1187
- dfNames.forEach((name) => res.push(`${SCRIPT.SPACE2}DG.Column.fromFloat64Array('${name}', []),`));
1188
- res.push(`]);`);
1189
- res.push(`df.name = '${ivp.name}';`);
1190
- res.push('');
1191
-
1192
- res.push(SCRIPT.LOOP_INTERVAL_COM);
1193
- res.push(`const ${SCRIPT.LOOP_INTERVAL} = _${ivp.arg.name}1 - _${ivp.arg.name}0;`);
1194
- res.push('');
1195
- res.push(`let ${SCRIPT.LAST_IDX} = 0;\n`);
1196
-
1197
- res.push(SCRIPT.SOLVER_COM);
1198
- res.push(`for (let _idx = 0; _idx < ${LOOP.COUNT_NAME}; ++_idx) {`);
1199
- ivp.loop!.updates.forEach((upd) => res.push(`${SCRIPT.SPACE2}${upd};`));
1200
- res.push(`${SCRIPT.SPACE2}${SCRIPT.APPEND}${SCRIPT.ONE_STAGE}${funcParamsNames}), true);`);
1201
- res.push(`${SCRIPT.SPACE2}_${ivp.arg.name}0 = _${ivp.arg.name}1;`);
1202
- res.push(`${SCRIPT.SPACE2}_${ivp.arg.name}1 += ${SCRIPT.LOOP_INTERVAL};`);
1203
- res.push(`${SCRIPT.SPACE2}${SCRIPT.LAST_IDX} = df.rowCount - 1;`);
1204
-
1205
- dfNames.forEach((name, idx) => {
1206
- if (idx !== 0)
1207
- res.push(`${SCRIPT.SPACE2}${name} = df.get('${name}', ${SCRIPT.LAST_IDX});`);
1208
- });
1209
-
1210
- // eslint-disable-next-line max-len
1211
- res.push(`${SCRIPT.SPACE2}df.set('${ivp.arg.name}', ${SCRIPT.LAST_IDX}, _${ivp.arg.name}0 - Math.min(_h * ${STEP_RATIO}, ${TINY}));`);
1212
-
1213
- res.push('};');
1214
-
1215
- return res;
1216
- } // getScriptMainBodyLoopCase
1217
-
1218
- /** Return main body of JS-script: update case */
1219
- function getScriptMainBodyUpdateCase(ivp: IVP): string[] {
1220
- const funcParamsNames = getFuncParamsNames(ivp);
1221
- const res = getScriptFunc(ivp, funcParamsNames);
1222
-
1223
- res.push('');
1224
-
1225
- res.push(SCRIPT.SOLUTION_DF_COM);
1226
- const dfNames = getSolutionDfColsNames(ivp);
1227
-
1228
- res.push(`${SCRIPT.ASYNC_OUTPUT}${funcParamsNames});`);
1229
-
1230
- res.push('');
1231
-
1232
- res.push(SCRIPT.SEGMENT_COM);
1233
- // eslint-disable-next-line max-len
1234
- res.push(`df.columns.add(DG.Column.fromList('string', '${STAGE_COL_NAME}', new Array(df.rowCount).fill('${ivp.arg.updateName ?? INCEPTION}')));`);
1235
-
1236
- res.push('');
1237
- res.push(`let ${SCRIPT.LAST_IDX} = 0;`);
1238
-
1239
- ivp.updates!.forEach((upd, idx) => {
1240
- res.push('');
1241
- res.push(`${SCRIPT.UPDATE_COM} ${idx + 1}`);
1242
- res.push(`const ${UPDATE.DURATION}${idx + 1} = ${upd.durationFormula};`);
1243
- res.push(`${SCRIPT.LAST_IDX} = df.rowCount - 1;`);
1244
-
1245
- // eslint-disable-next-line max-len
1246
- res.push(`df.set('${ivp.arg.name}', ${SCRIPT.LAST_IDX}, _${ivp.arg.name}1 - Math.min(_h * ${STEP_RATIO}, ${TINY}));`);
1247
-
1248
- dfNames.forEach((name, idx) => {
1249
- if (idx !== 0)
1250
- res.push(`${name} = df.get('${name}', ${SCRIPT.LAST_IDX});`);
1251
- });
1252
-
1253
- upd.updates.forEach((upd) => res.push(`${upd};`));
1254
-
1255
- res.push(`_${ivp.arg.name}0 = _${ivp.arg.name}1;`);
1256
- res.push(`_${ivp.arg.name}1 += ${UPDATE.DURATION}${idx + 1};`);
1257
-
1258
- res.push(`const _DF${idx + 1} = ${SCRIPT.ONE_STAGE}${funcParamsNames});`);
1259
- // eslint-disable-next-line max-len
1260
- res.push(`_DF${idx + 1}.columns.add(DG.Column.fromList('string', '${STAGE_COL_NAME}', new Array(_DF${idx + 1}.rowCount).fill('${upd.name}')));`);
1261
- res.push(`${SCRIPT.APPEND}_DF${idx + 1}, true);`);
1262
- });
1263
-
1264
- return res;
1265
- } // getScriptMainBodyUpdateCase
1266
-
1267
- /** Return main body of JS-script */
1268
- function getScriptMainBody(ivp: IVP): string[] {
1269
- if (ivp.loop)
1270
- return getScriptMainBodyLoopCase(ivp);
1271
-
1272
- if (ivp.updates)
1273
- return getScriptMainBodyUpdateCase(ivp);
1274
-
1275
- return getScriptMainBodyBasic(ivp);
1276
- }
1277
-
1278
- /** Return JS-script lines
1279
- * @internal
1280
- */
1281
- export function getScriptLines(ivp: IVP, toAddViewers = true, toAddEditor = false): string[] {
1282
- const res = getAnnot(ivp, toAddViewers, toAddEditor).concat(getScriptMainBody(ivp));
1283
-
1284
- if (ivp.outputs)
1285
- return res.concat(getCustomOutputLines(ivp));
1286
-
1287
- return res;
1288
- }
1289
-
1290
- /** Return parameters of JS-script
1291
- * @internal
1292
- */
1293
- export function getScriptParams(ivp: IVP): Record<string, number> {
1294
- const res = {} as Record<string, number>;
1295
-
1296
- if (ivp.loop)
1297
- res[LOOP.COUNT_NAME] = ivp.loop.count.value;
1298
-
1299
- const arg = ivp.arg;
1300
-
1301
- res[`_${arg.name}0`] = arg.initial.value;
1302
- res[`_${arg.name}1`] = arg.final.value;
1303
- res[`_h`] = arg.step.value;
1304
-
1305
- ivp.inits.forEach((val, key) => res[key] = val.value);
1306
-
1307
- if (ivp.params)
1308
- ivp.params.forEach((val, key) => res[key] = val.value);
1309
-
1310
- return res;
1311
- }
1312
-
1313
- /** Return func parameters names string */
1314
- function getFuncParamsNames(ivp: IVP): string {
1315
- const names = [] as string [];
1316
-
1317
- const arg = ivp.arg.name;
1318
-
1319
- names.push(`_${arg}0`);
1320
- names.push(`_${arg}1`);
1321
- names.push(`_h`);
1322
-
1323
- ivp.inits.forEach((val, key) => names.push(key));
1324
-
1325
- if (ivp.params)
1326
- ivp.params.forEach((val, key) => names.push(key));
1327
-
1328
- return names.join(', ');
1329
- }
1330
-
1331
- /** Return solution dataframe columns names*/
1332
- function getSolutionDfColsNames(ivp: IVP): string[] {
1333
- const res = [] as string[];
1334
-
1335
- res.push(ivp.arg.name);
1336
-
1337
- ivp.inits.forEach((val, key) => res.push(key));
1338
-
1339
- return res;
1340
- }
1341
-
1342
- /** Check solver settings */
1343
- function checkSolverSettings(line: string): void {
1344
- const settings = new Map<string, string>();
1345
-
1346
- const openBraceIdx = line.indexOf(BRACE_OPEN);
1347
- const closeBraceIdx = line.indexOf(BRACE_CLOSE);
1348
- let sepIdx: number;
1349
-
1350
- if ((openBraceIdx < 0 )|| (closeBraceIdx < 0))
1351
- throw new ModelError(`${ERROR_MSG.BRACES}. Correct the line **${line}**.`, ERROR_LINK.SOLVER_CONFIG, line);
1352
-
1353
- for (const item of line.slice(openBraceIdx + 1, closeBraceIdx).split(ANNOT_SEPAR)) {
1354
- sepIdx = item.indexOf(CONTROL_SEP);
1355
-
1356
- if (sepIdx > 1)
1357
- settings.set(item.slice(0, sepIdx).trim(), item.slice(sepIdx + 1).trim());
1358
- }
1359
-
1360
- SOLVER_OPTIONS_RANGES.forEach((range, opt) => {
1361
- if (settings.has(opt)) {
1362
- const val = Number(settings.get(opt));
1363
-
1364
- if ((val < range.min) || (val > range.max)) {
1365
- throw new ModelError(
1366
- `${ERROR_MSG.SOLVER}: **${opt}** must be in the range **${range.min}..${range.max}**.`,
1367
- ERROR_LINK.SOLVER_CONFIG,
1368
- line,
1369
- );
1370
- }
1371
- }
1372
- });
1373
- } // checkSolverSettings
1374
-
1375
- /** Check IVP correctness */
1376
- function checkCorrectness(ivp: IVP): void {
1377
- // 0. Check basic elements
1378
- if (ivp.name === undefined)
1379
- throw new ModelError(ERROR_MSG.UNDEF_NAME, ERROR_LINK.CORE_BLOCKS);
1380
-
1381
- if ((ivp.deqs === undefined) || (ivp.deqs.equations.size === 0))
1382
- throw new ModelError(ERROR_MSG.UNDEF_DEQS, ERROR_LINK.CORE_BLOCKS);
1383
-
1384
- if ((ivp.inits === undefined) || (ivp.inits.size === 0))
1385
- throw new ModelError(ERROR_MSG.UNDEF_INITS, ERROR_LINK.CORE_BLOCKS);
1386
-
1387
- if (ivp.arg === undefined)
1388
- throw new ModelError(ERROR_MSG.UNDEF_ARG, ERROR_LINK.CORE_BLOCKS);
1389
-
1390
- // 1. Check initial values
1391
- ivp.deqs.equations.forEach((ignore, name) => {
1392
- if (!ivp.inits.has(name)) {
1393
- throw new ModelError(
1394
- `Initial value for **${name}** is missing. ${ERROR_MSG.MISSING_INIT}`,
1395
- ERROR_LINK.CORE_BLOCKS,
1396
- CONTROL_EXPR.INITS,
1397
- );
1398
- }
1399
- });
1400
-
1401
- // 2. Check names of output columns
1402
- const usedNames = [] as string[];
1403
- let lowCase: string;
1404
-
1405
- if (ivp.outputs !== null) {
1406
- ivp.outputs.forEach((val) => {
1407
- lowCase = val.caption.toLowerCase();
1408
-
1409
- if (usedNames.includes(lowCase))
1410
- throw new ModelError(`${ERROR_MSG.CASE_INSENS}**${val.caption}**.`, ERROR_LINK.UI_OPTS, CONTROL_EXPR.OUTPUT);
1411
- else
1412
- usedNames.push(lowCase);
1413
- });
1414
- } else {
1415
- const usedNames = [ivp.arg.name];
1416
-
1417
- ivp.deqs.solutionNames.forEach((name) => {
1418
- lowCase = name.toLowerCase();
1419
-
1420
- if (usedNames.includes(lowCase))
1421
- throw new ModelError(`${ERROR_MSG.CASE_INSENS}**${name}**.`, ERROR_LINK.UI_OPTS);
1422
- else
1423
- usedNames.push(lowCase);
1424
- });
1425
- }
1426
-
1427
- // 3. Check argument
1428
- if (ivp.arg.initial.value >= ivp.arg.final.value) {
1429
- throw new ModelError(
1430
- `${ERROR_MSG.INTERVAL} **${ivp.arg.name}**. ${ERROR_MSG.CORRECT_ARG_LIM}`,
1431
- ERROR_LINK.CORE_BLOCKS,
1432
- CONTROL_EXPR.ARG,
1433
- );
1434
- }
1435
-
1436
- if (ivp.arg.step.value <= 0) {
1437
- throw new ModelError(
1438
- `${ERROR_MSG.NEGATIVE_STEP}`,
1439
- ERROR_LINK.CORE_BLOCKS);
1440
- }
1441
-
1442
- if (ivp.arg.step.value > ivp.arg.final.value - ivp.arg.initial.value)
1443
- throw new ModelError(ERROR_MSG.INCOR_STEP, ERROR_LINK.CORE_BLOCKS);
1444
-
1445
- // 4. Check script inputs, due to https://reddata.atlassian.net/browse/GROK-15152
1446
- const scriptInputs = [] as string[];
1447
- let current: string;
1448
-
1449
- // 4.1) initial values
1450
- ivp.inits.forEach((_, key) => {
1451
- if (key[0] === SERVICE) {
1452
- throw new ModelError(
1453
- `${ERROR_MSG.SERVICE_START} Correct **"${key}"** in the **#inits** block.`,
1454
- ERROR_LINK.CORE_BLOCKS,
1455
- );
1456
- }
1457
-
1458
- current = key.toLocaleLowerCase();
1459
-
1460
- if (scriptInputs.includes(current)) {
1461
- throw new ModelError(
1462
- `${ERROR_MSG.REUSE_NAME} **"${key}"** in the **#inits** block.`,
1463
- ERROR_LINK.CORE_BLOCKS,
1464
- );
1465
- }
1466
-
1467
- scriptInputs.push(current);
1468
- });
1469
-
1470
- // 4.2) parameters
1471
- if (ivp.params !== null) {
1472
- ivp.params.forEach((_, key) => {
1473
- if (key[0] === SERVICE) {
1474
- throw new ModelError(
1475
- `${ERROR_MSG.SERVICE_START}: correct **"${key}"** in the **${CONTROL_EXPR.PARAMS}** block.`,
1476
- ERROR_LINK.MODEL_PARAMS,
1477
- );
1478
- }
1479
-
1480
- current = key.toLocaleLowerCase();
1481
-
1482
- if (scriptInputs.includes(current)) {
1483
- throw new ModelError(
1484
- `${ERROR_MSG.REUSE_NAME} **"${key}"** in the **${CONTROL_EXPR.PARAMS}** block.`,
1485
- ERROR_LINK.MODEL_PARAMS,
1486
- );
1487
- }
1488
-
1489
- scriptInputs.push(current);
1490
- });
1491
- }
1492
-
1493
- // 5. Check solver settings
1494
- checkSolverSettings(ivp.solverSettings);
1495
- } // checkCorrectness
1496
-
1497
- /** Return JavaScript code that solves the given initial value problem
1498
- * @param ivp - initial value problem to be solved
1499
- * @example
1500
- * import {getIVP, getJScode} from 'diff-grok';
1501
- *
1502
- * const model = `
1503
- * #name: Example
1504
- * #equations:
1505
- * dx/dt = x + y - cos(t)
1506
- * dy/dt = x - y + sin(t)
1507
- * ...
1508
- * `;
1509
- *
1510
- * const ivp = getIVP(model);
1511
- * const lines = getJScode(ivp);
1512
- */
1513
- export function getJScode(ivp: IVP): string[] {
1514
- const res = [] as string[];
1515
-
1516
- // 1. Math functions
1517
- if (ivp.usedMathFuncs.length > 0) {
1518
- res.push(SCRIPT.MATH_FUNC_COM);
1519
- ivp.usedMathFuncs.forEach((i) =>
1520
- res.push(`const ${MATH_FUNCS[i]} = ${getMathArg(i)} => Math.${MATH_FUNCS[i]}${getMathArg(i)};`,
1521
- ));
1522
- }
1523
-
1524
- // 2. Math constants
1525
- if (ivp.usedMathConsts.length > 0) {
1526
- res.push('');
1527
- res.push(SCRIPT.MATH_CONST_COM);
1528
- ivp.usedMathConsts.forEach((i) => res.push(`const ${MATH_CONSTS[i]} = Math.${MATH_CONSTS[i]};`));
1529
- }
1530
-
1531
- // 1. Constants lines
1532
- if (ivp.consts !== null) {
1533
- res.push('');
1534
- res.push(SCRIPT.CONSTS);
1535
- ivp.consts.forEach((val, key) => res.push(`const ${key} = ${val.value};`));
1536
- }
1537
-
1538
- // 2. The problem definition lines
1539
- res.push('');
1540
- res.push(SCRIPT.ODE_COM);
1541
- res.push(`const odes = {`);
1542
- res.push(`${SCRIPT.SPACE4}name: '${ivp.name}',`);
1543
-
1544
- // 2.1) argument
1545
- const t = ivp.arg.name;
1546
- const t0 = `_${t}0`;
1547
- const t1 = `_${t}1`;
1548
- const h = `_h`;
1549
- res.push(`${SCRIPT.SPACE4}arg: {name: '${t}', start: ${t0}, finish: ${t1}, step: ${h}},`);
1550
-
1551
- const names = ivp.deqs.solutionNames;
1552
-
1553
- // 2.2) initial values
1554
- res.push(`${SCRIPT.SPACE4}initial: [${names.join(', ')}],`);
1555
-
1556
- // 2.3) the right-hand side of the problem
1557
- res.push(`${SCRIPT.SPACE4}func: (${t}, _y, _output) => {`);
1558
-
1559
- res.push(`${SCRIPT.SPACE6}${SCRIPT.FUNC_VALS}`);
1560
- names.forEach((name, idx) => res.push(`${SCRIPT.SPACE6}const ${name} = _y[${idx}];`));
1561
-
1562
- if (ivp.exprs !== null) {
1563
- res.push(`\n${SCRIPT.SPACE6}${SCRIPT.EVAL_EXPR}`);
1564
- ivp.exprs.forEach((val, key) => res.push(`${SCRIPT.SPACE6}const ${key} = ${val};`));
1565
- }
1566
-
1567
- res.push(`\n${SCRIPT.SPACE6}${SCRIPT.COMP_OUT}`);
1568
- names.forEach((name, idx) => res.push(`${SCRIPT.SPACE6}_output[${idx}] = ${ivp.deqs.equations.get(name)};`));
1569
-
1570
- res.push(`${SCRIPT.SPACE4}},`);
1571
-
1572
- // 2.4) final lines of the problem specification
1573
- res.push(`${SCRIPT.SPACE4}tolerance: ${ivp.tolerance},`);
1574
- //res.push(`${SCRIPT.SPACE6}solverOptions: ${ivp.solverSettings.replaceAll(ANNOT_SEPAR, COMMA)},`);
1575
- res.push(`${SCRIPT.SPACE4}solutionColNames: [${names.map((key) => `'${key}'`).join(', ')}]`);
1576
- res.push('};');
1577
-
1578
- return res;
1579
- } // getJScode
1580
-
1581
- /** @internal */
1582
- export function getFunc4worker(ivp: IVP) {}