@danielsimonjr/mathts-functions 0.25.1 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -36301,6 +36301,127 @@ var createSolveODE = /* @__PURE__ */ factory(
36301
36301
  }
36302
36302
  return true;
36303
36303
  }
36304
+ function _rmsNorm(v) {
36305
+ let s = 0;
36306
+ for (let i = 0; i < v.length; i++) s += v[i] * v[i];
36307
+ return Math.sqrt(s / v.length);
36308
+ }
36309
+ function _luSolve(A, b) {
36310
+ const n = b.length;
36311
+ const M = A.map((r) => r.slice());
36312
+ const x = b.slice();
36313
+ for (let k = 0; k < n; k++) {
36314
+ let piv = k;
36315
+ for (let i = k + 1; i < n; i++) if (Math.abs(M[i][k]) > Math.abs(M[piv][k])) piv = i;
36316
+ [M[k], M[piv]] = [M[piv], M[k]];
36317
+ [x[k], x[piv]] = [x[piv], x[k]];
36318
+ const akk = M[k][k];
36319
+ for (let i = k + 1; i < n; i++) {
36320
+ const factor2 = M[i][k] / akk;
36321
+ for (let j = k; j < n; j++) M[i][j] -= factor2 * M[k][j];
36322
+ x[i] -= factor2 * x[k];
36323
+ }
36324
+ }
36325
+ for (let i = n - 1; i >= 0; i--) {
36326
+ let s = x[i];
36327
+ for (let j = i + 1; j < n; j++) s -= M[i][j] * x[j];
36328
+ x[i] = s / M[i][i];
36329
+ }
36330
+ return x;
36331
+ }
36332
+ function _fArr(f, t, y) {
36333
+ const r = f(t, y);
36334
+ return Array.isArray(r) ? r : [r];
36335
+ }
36336
+ function _fdJacobian(f, t, y, f0) {
36337
+ const n = y.length;
36338
+ const J = Array.from({ length: n }, () => new Array(n));
36339
+ for (let j = 0; j < n; j++) {
36340
+ const eps = Math.max(1e-8, 1e-7 * Math.abs(y[j]));
36341
+ const yj = y.slice();
36342
+ yj[j] += eps;
36343
+ const fj = _fArr(f, t, yj);
36344
+ for (let i = 0; i < n; i++) J[i][j] = (fj[i] - f0[i]) / eps;
36345
+ }
36346
+ return J;
36347
+ }
36348
+ function _rosenbrock(f, tspan, y0raw, options) {
36349
+ const t0 = tspan[0];
36350
+ const tf = tspan[1];
36351
+ if (!(typeof t0 === "number" && typeof tf === "number")) {
36352
+ throw new Error('The "Rosenbrock" stiff method requires numeric tspan');
36353
+ }
36354
+ if (!y0raw.every((v) => typeof v === "number")) {
36355
+ throw new Error('The "Rosenbrock" stiff method requires plain-number state (y0)');
36356
+ }
36357
+ const y0 = y0raw;
36358
+ const n = y0.length;
36359
+ const dir = tf >= t0 ? 1 : -1;
36360
+ const gamma2 = 1 / (2 + Math.SQRT2);
36361
+ const c32 = 6 + Math.SQRT2;
36362
+ const rtol = options.tol ? options.tol : 1e-4;
36363
+ const atol = rtol * 1e-3;
36364
+ const maxIter = options.maxIter ? options.maxIter : 1e5;
36365
+ const span = Math.abs(tf - t0);
36366
+ let t = t0;
36367
+ let y = y0.slice();
36368
+ let h;
36369
+ if (options.firstStep) {
36370
+ h = dir * Math.abs(options.firstStep);
36371
+ } else {
36372
+ const f0 = f(t, y);
36373
+ const d0 = _rmsNorm(y);
36374
+ const d1 = _rmsNorm(Array.isArray(f0) ? f0 : [f0]);
36375
+ h = dir * Math.min(d0 < 1e-5 || d1 < 1e-5 ? 1e-6 : 0.01 * (d0 / d1), span);
36376
+ }
36377
+ const tOut = [t];
36378
+ const yOut = [y.slice()];
36379
+ let iter = 0;
36380
+ const identityMinus = (J, hg) => J.map((row2, i) => row2.map((v, j) => (i === j ? 1 : 0) - hg * v));
36381
+ while ((dir > 0 ? t < tf : t > tf) && iter < maxIter) {
36382
+ if (Math.abs(h) > Math.abs(tf - t)) h = tf - t;
36383
+ const F0 = _fArr(f, t, y);
36384
+ const J = _fdJacobian(f, t, y, F0);
36385
+ const W = identityMinus(J, h * gamma2);
36386
+ const k1 = _luSolve(W, F0);
36387
+ const y1 = y.map((yi, i) => yi + 0.5 * h * k1[i]);
36388
+ const F1 = _fArr(f, t + 0.5 * h, y1);
36389
+ const dk = _luSolve(
36390
+ W,
36391
+ F1.map((v, i) => v - k1[i])
36392
+ );
36393
+ const k2 = k1.map((v, i) => v + dk[i]);
36394
+ const yNew = y.map((yi, i) => yi + h * k2[i]);
36395
+ const F2 = _fArr(f, t + h, yNew);
36396
+ const k3 = _luSolve(
36397
+ W,
36398
+ F2.map((v, i) => v - c32 * (k2[i] - F1[i]) - 2 * (k1[i] - F0[i]))
36399
+ );
36400
+ let errNorm = 0;
36401
+ for (let i = 0; i < n; i++) {
36402
+ const err = h / 6 * (k1[i] - 2 * k2[i] + k3[i]);
36403
+ const sc = atol + rtol * Math.max(Math.abs(y[i]), Math.abs(yNew[i]));
36404
+ errNorm += (err / sc) ** 2;
36405
+ }
36406
+ errNorm = Math.sqrt(errNorm / n);
36407
+ if (errNorm <= 1 || Math.abs(h) <= 1e-14 * Math.abs(t)) {
36408
+ t += h;
36409
+ y = yNew;
36410
+ tOut.push(t);
36411
+ yOut.push(y.slice());
36412
+ }
36413
+ h *= Math.min(4, Math.max(0.25, 0.9 * Math.pow(errNorm || 1e-10, -1 / 3)));
36414
+ const maxStepR = options.maxStep;
36415
+ const minStepR = options.minStep;
36416
+ if (maxStepR && Math.abs(h) > maxStepR) h = dir * maxStepR;
36417
+ else if (minStepR && Math.abs(h) < minStepR) h = dir * minStepR;
36418
+ iter++;
36419
+ }
36420
+ if (iter >= maxIter) {
36421
+ throw new Error("Maximum number of iterations reached, try changing options");
36422
+ }
36423
+ return { t: tOut, y: yOut };
36424
+ }
36304
36425
  function _rkWasmLoop(f, tspan, y0, options, butcherTableau) {
36305
36426
  const wasm = wasmLoader.getModule();
36306
36427
  if (!wasm) return null;
@@ -36313,12 +36434,21 @@ var createSolveODE = /* @__PURE__ */ factory(
36313
36434
  const t0 = tspan[0];
36314
36435
  const tf = tspan[1];
36315
36436
  const isForwards = tf > t0;
36316
- const steps = 1;
36317
36437
  const tol = options.tol ? options.tol : 1e-4;
36318
36438
  const minDelta = options.minDelta ? options.minDelta : 0.2;
36319
36439
  const maxDelta = options.maxDelta ? options.maxDelta : 5;
36320
36440
  const maxIter = options.maxIter ? options.maxIter : 1e4;
36321
- let h = options.firstStep ? isForwards ? options.firstStep : -options.firstStep : (tf - t0) / steps;
36441
+ let h;
36442
+ if (options.firstStep) {
36443
+ h = isForwards ? options.firstStep : -options.firstStep;
36444
+ } else {
36445
+ const f0 = f(t0, y0);
36446
+ const d0 = _rmsNorm(y0);
36447
+ const d1 = _rmsNorm(Array.isArray(f0) ? f0 : [f0]);
36448
+ const h0 = d0 < 1e-5 || d1 < 1e-5 ? 1e-6 : 0.01 * (d0 / d1);
36449
+ const hMag = Math.min(h0, Math.abs(tf - t0));
36450
+ h = isForwards ? hMag : -hMag;
36451
+ }
36322
36452
  const maxStepVal = options.maxStep;
36323
36453
  const minStepVal = options.minStep;
36324
36454
  const deltaB = new Float64Array(numStages);
@@ -36468,10 +36598,31 @@ var createSolveODE = /* @__PURE__ */ factory(
36468
36598
  bignumber2(butcherTableau.b),
36469
36599
  bignumber2(butcherTableau.bp)
36470
36600
  ] : [butcherTableau.a, butcherTableau.c, butcherTableau.b, butcherTableau.bp];
36471
- let h = firstStep ? isForwards ? firstStep : unaryMinus2(firstStep) : divide2(subtract2(tf, t0), steps);
36601
+ let h;
36602
+ if (firstStep) {
36603
+ h = isForwards ? firstStep : unaryMinus2(firstStep);
36604
+ } else if (!hasBigNumbers && !tspan.some(isUnit) && y0.every((v) => typeof v === "number")) {
36605
+ const f0 = f(t0, y0);
36606
+ const f0arr = Array.isArray(f0) ? f0 : [f0];
36607
+ const d0 = _rmsNorm(y0);
36608
+ const d1 = _rmsNorm(f0arr);
36609
+ const h0 = d0 < 1e-5 || d1 < 1e-5 ? 1e-6 : 0.01 * (d0 / d1);
36610
+ const hMag = Math.min(h0, Math.abs(tf - t0));
36611
+ h = isForwards ? hMag : -hMag;
36612
+ } else {
36613
+ h = divide2(subtract2(tf, t0), steps);
36614
+ }
36472
36615
  const t = [t0];
36473
36616
  const y = [y0];
36474
36617
  const deltaB = subtract2(b, bp);
36618
+ function stageCombo(coeffs, stages) {
36619
+ const m = Math.min(coeffs.length, stages.length);
36620
+ let acc = multiply2(coeffs[0], stages[0]);
36621
+ for (let j = 1; j < m; j++) {
36622
+ acc = add2(acc, multiply2(coeffs[j], stages[j]));
36623
+ }
36624
+ return acc;
36625
+ }
36475
36626
  let n = 0;
36476
36627
  let iter = 0;
36477
36628
  const ongoing = _createOngoing(isForwards);
@@ -36481,14 +36632,14 @@ var createSolveODE = /* @__PURE__ */ factory(
36481
36632
  h = trimStep(t[n], tf, h);
36482
36633
  k.push(f(t[n], y[n]));
36483
36634
  for (let i = 1; i < c.length; ++i) {
36484
- k.push(f(add2(t[n], multiply2(c[i], h)), add2(y[n], multiply2(h, a[i], k))));
36635
+ k.push(f(add2(t[n], multiply2(c[i], h)), add2(y[n], multiply2(h, stageCombo(a[i], k)))));
36485
36636
  }
36486
- const TE = max2(
36487
- abs2(map2(multiply2(deltaB, k), (X) => isUnit(X) ? X.value : X))
36488
- );
36637
+ const errComb = stageCombo(deltaB, k);
36638
+ const errArr = Array.isArray(errComb) ? errComb : [errComb];
36639
+ const TE = max2(abs2(map2(errArr, (X) => isUnit(X) ? X.value : X)));
36489
36640
  if (TE < tol && tol / TE > 1 / 4) {
36490
36641
  t.push(add2(t[n], h));
36491
- y.push(add2(y[n], multiply2(h, b, k)));
36642
+ y.push(add2(y[n], multiply2(h, stageCombo(b, k))));
36492
36643
  n++;
36493
36644
  }
36494
36645
  let delta = 0.84 * (tol / TE) ** (1 / 5);
@@ -36548,7 +36699,8 @@ var createSolveODE = /* @__PURE__ */ factory(
36548
36699
  const method = opt.method ? opt.method : "RK45";
36549
36700
  const methods = {
36550
36701
  RK23: _rk23,
36551
- RK45: _rk45
36702
+ RK45: _rk45,
36703
+ ROSENBROCK: _rosenbrock
36552
36704
  };
36553
36705
  if (method.toUpperCase() in methods) {
36554
36706
  const methodOptions = { ...opt };
@@ -1 +1 @@
1
- {"version":3,"file":"solveODE.d.ts","sourceRoot":"","sources":["../../src/numeric/solveODE.ts"],"names":[],"mappings":"AAmEA,eAAO,MAAM,cAAc,yDA8kB1B,CAAC"}
1
+ {"version":3,"file":"solveODE.d.ts","sourceRoot":"","sources":["../../src/numeric/solveODE.ts"],"names":[],"mappings":"AAmEA,eAAO,MAAM,cAAc,yDAkyB1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielsimonjr/mathts-functions",
3
- "version": "0.25.1",
3
+ "version": "0.27.0",
4
4
  "description": "Mathematical functions for MathTS - arithmetic, algebra, trigonometry, statistics, and more",
5
5
  "author": "Daniel Simon Jr.",
6
6
  "license": "MIT",