@danielsimonjr/mathts-core 0.14.1 → 0.14.3

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.
@@ -2,6 +2,16 @@
2
2
  function isComplex(value) {
3
3
  return value instanceof Complex;
4
4
  }
5
+ function hypotFast(re, im) {
6
+ if (im === 0) return Math.abs(re);
7
+ if (re === 0) return Math.abs(im);
8
+ const a = re < 0 ? -re : re;
9
+ const b = im < 0 ? -im : im;
10
+ if (a < 1e150 && b < 1e150 && (a > 1e-150 || b > 1e-150)) {
11
+ return Math.sqrt(re * re + im * im);
12
+ }
13
+ return Math.hypot(re, im);
14
+ }
5
15
  var Complex = class _Complex {
6
16
  type = "Complex";
7
17
  re;
@@ -150,7 +160,7 @@ var Complex = class _Complex {
150
160
  * Magnitude (absolute value) |z| = √(re² + im²)
151
161
  */
152
162
  abs() {
153
- return Math.hypot(this.re, this.im);
163
+ return hypotFast(this.re, this.im);
154
164
  }
155
165
  /**
156
166
  * Phase angle (argument) in radians, range (-π, π]
@@ -266,13 +276,28 @@ var Complex = class _Complex {
266
276
  // Transcendental Functions
267
277
  // ============================================================
268
278
  /**
269
- * Square root using principal branch
270
- * √z = √r · e^(iθ/2) where r = |z|, θ = arg(z)
279
+ * Square root using the principal branch (Re ≥ 0; Im has the sign of `this.im`).
280
+ *
281
+ * Algebraic form, not polar: one hypot + one sqrt instead of hypot + atan2 +
282
+ * cos + sin. Same branch cut as C99 / the previous polar implementation,
283
+ * including `sqrt(-x - 0i) = −√x · i`.
271
284
  */
272
285
  sqrt() {
273
- const r = this.abs();
274
- const theta = this.arg();
275
- return _Complex.fromPolar(Math.sqrt(r), theta / 2);
286
+ const x = this.re;
287
+ const y = this.im;
288
+ if (y === 0) {
289
+ if (x >= 0) return new _Complex(Math.sqrt(x), y);
290
+ const im2 = Math.sqrt(-x);
291
+ return new _Complex(0, Object.is(y, -0) ? -im2 : im2);
292
+ }
293
+ const r = hypotFast(x, y);
294
+ if (x >= 0) {
295
+ const t2 = Math.sqrt(0.5 * (r + x));
296
+ return new _Complex(t2, y / (2 * t2));
297
+ }
298
+ const t = Math.sqrt(0.5 * (r - x));
299
+ const im = y < 0 ? -t : t;
300
+ return new _Complex(y / (2 * im), im);
276
301
  }
277
302
  /**
278
303
  * n-th root (returns principal root)
@@ -312,13 +337,15 @@ var Complex = class _Complex {
312
337
  * Logarithm base 10
313
338
  */
314
339
  log10() {
315
- return this.log().divide(new _Complex(Math.LN10, 0));
340
+ const ln10 = Math.LN10;
341
+ return new _Complex(Math.log(hypotFast(this.re, this.im)) / ln10, this.arg() / ln10);
316
342
  }
317
343
  /**
318
344
  * Logarithm base 2
319
345
  */
320
346
  log2() {
321
- return this.log().divide(new _Complex(Math.LN2, 0));
347
+ const ln2 = Math.LN2;
348
+ return new _Complex(Math.log(hypotFast(this.re, this.im)) / ln2, this.arg() / ln2);
322
349
  }
323
350
  /**
324
351
  * Power: z^w = e^(w·ln(z))
@@ -359,16 +386,24 @@ var Complex = class _Complex {
359
386
  );
360
387
  }
361
388
  /**
362
- * Tangent: tan(z) = sin(z) / cos(z)
389
+ * Tangent: tan(x+iy) = (sin 2x + i sinh 2y) / (cos 2x + cosh 2y)
390
+ *
391
+ * Closed form — no intermediate `sin`/`cos` Complex allocations.
363
392
  */
364
393
  tan() {
365
- return this.sin().divide(this.cos());
394
+ const x2 = this.re * 2;
395
+ const y2 = this.im * 2;
396
+ const d = Math.cos(x2) + Math.cosh(y2);
397
+ return new _Complex(Math.sin(x2) / d, Math.sinh(y2) / d);
366
398
  }
367
399
  /**
368
- * Cotangent: cot(z) = cos(z) / sin(z)
400
+ * Cotangent: cot(x+iy) = (sin 2x − i sinh 2y) / (cosh 2y − cos 2x)
369
401
  */
370
402
  cot() {
371
- return this.cos().divide(this.sin());
403
+ const x2 = this.re * 2;
404
+ const y2 = this.im * 2;
405
+ const d = Math.cosh(y2) - Math.cos(x2);
406
+ return new _Complex(Math.sin(x2) / d, -Math.sinh(y2) / d);
372
407
  }
373
408
  /**
374
409
  * Secant: sec(z) = 1 / cos(z)
@@ -404,16 +439,22 @@ var Complex = class _Complex {
404
439
  );
405
440
  }
406
441
  /**
407
- * Hyperbolic tangent: tanh(z) = sinh(z) / cosh(z)
442
+ * Hyperbolic tangent: tanh(x+iy) = (sinh 2x + i sin 2y) / (cosh 2x + cos 2y)
408
443
  */
409
444
  tanh() {
410
- return this.sinh().divide(this.cosh());
445
+ const x2 = this.re * 2;
446
+ const y2 = this.im * 2;
447
+ const d = Math.cosh(x2) + Math.cos(y2);
448
+ return new _Complex(Math.sinh(x2) / d, Math.sin(y2) / d);
411
449
  }
412
450
  /**
413
- * Hyperbolic cotangent: coth(z) = cosh(z) / sinh(z)
451
+ * Hyperbolic cotangent: coth(x+iy) = (sinh 2x − i sin 2y) / (cosh 2x − cos 2y)
414
452
  */
415
453
  coth() {
416
- return this.cosh().divide(this.sinh());
454
+ const x2 = this.re * 2;
455
+ const y2 = this.im * 2;
456
+ const d = Math.cosh(x2) - Math.cos(y2);
457
+ return new _Complex(Math.sinh(x2) / d, -Math.sin(y2) / d);
417
458
  }
418
459
  /**
419
460
  * Hyperbolic secant: sech(z) = 1 / cosh(z)
@@ -1491,11 +1532,49 @@ function gcd(a, b) {
1491
1532
  }
1492
1533
  return a;
1493
1534
  }
1535
+ function reducePair(num, den) {
1536
+ if (den === 0n) {
1537
+ throw new Error("Fraction denominator cannot be zero");
1538
+ }
1539
+ if (den < 0n) {
1540
+ num = -num;
1541
+ den = -den;
1542
+ }
1543
+ if (num === 0n) return [0n, 1n];
1544
+ const g = gcd(num, den);
1545
+ return [num / g, den / g];
1546
+ }
1494
1547
  var Fraction = class _Fraction {
1495
1548
  type = "Fraction";
1496
1549
  numerator;
1497
1550
  denominator;
1498
1551
  constructor(numerator, denominator = 1n) {
1552
+ if (typeof numerator === "bigint" && typeof denominator === "bigint") {
1553
+ const [num2, den2] = reducePair(numerator, denominator);
1554
+ this.numerator = num2;
1555
+ this.denominator = den2;
1556
+ return;
1557
+ }
1558
+ if (typeof numerator === "number" && Number.isInteger(numerator)) {
1559
+ if (typeof denominator === "bigint") {
1560
+ const [num2, den2] = reducePair(BigInt(numerator), denominator);
1561
+ this.numerator = num2;
1562
+ this.denominator = den2;
1563
+ return;
1564
+ }
1565
+ if (typeof denominator === "number" && Number.isInteger(denominator)) {
1566
+ const [num2, den2] = reducePair(BigInt(numerator), BigInt(denominator));
1567
+ this.numerator = num2;
1568
+ this.denominator = den2;
1569
+ return;
1570
+ }
1571
+ }
1572
+ if (typeof numerator === "bigint" && typeof denominator === "number" && Number.isInteger(denominator)) {
1573
+ const [num2, den2] = reducePair(numerator, BigInt(denominator));
1574
+ this.numerator = num2;
1575
+ this.denominator = den2;
1576
+ return;
1577
+ }
1499
1578
  const toRatio = (x) => {
1500
1579
  if (isFraction2(x)) {
1501
1580
  return [x.numerator, x.denominator];
@@ -1692,6 +1771,9 @@ var Fraction = class _Fraction {
1692
1771
  */
1693
1772
  add(other) {
1694
1773
  if (other instanceof _Fraction) {
1774
+ if (this.denominator === other.denominator) {
1775
+ return new _Fraction(this.numerator + other.numerator, this.denominator);
1776
+ }
1695
1777
  const num = this.numerator * other.denominator + other.numerator * this.denominator;
1696
1778
  const den = this.denominator * other.denominator;
1697
1779
  return new _Fraction(num, den);
@@ -1703,6 +1785,9 @@ var Fraction = class _Fraction {
1703
1785
  */
1704
1786
  subtract(other) {
1705
1787
  if (other instanceof _Fraction) {
1788
+ if (this.denominator === other.denominator) {
1789
+ return new _Fraction(this.numerator - other.numerator, this.denominator);
1790
+ }
1706
1791
  const num = this.numerator * other.denominator - other.numerator * this.denominator;
1707
1792
  const den = this.denominator * other.denominator;
1708
1793
  return new _Fraction(num, den);
@@ -2041,6 +2126,9 @@ var BigNumber = class _BigNumber {
2041
2126
  if (n === 0) {
2042
2127
  return new _BigNumber(0, 0n, 0);
2043
2128
  }
2129
+ if (Number.isSafeInteger(n)) {
2130
+ return _BigNumber.fromBigInt(BigInt(n));
2131
+ }
2044
2132
  return _BigNumber.parse(n.toString());
2045
2133
  }
2046
2134
  /**
@@ -2105,19 +2193,13 @@ var BigNumber = class _BigNumber {
2105
2193
  return new _BigNumber(0, 0n, 0);
2106
2194
  }
2107
2195
  const sign2 = n < 0n ? -1 : 1;
2108
- let str = (n < 0n ? -n : n).toString();
2109
- let trailingZeros = 0;
2110
- for (let i = str.length - 1; i >= 0; i--) {
2111
- if (str[i] === "0") {
2112
- trailingZeros++;
2113
- } else {
2114
- break;
2115
- }
2116
- }
2117
- if (trailingZeros > 0) {
2118
- str = str.slice(0, -trailingZeros);
2196
+ let coef = n < 0n ? -n : n;
2197
+ let exp = 0;
2198
+ while (coef % 10n === 0n) {
2199
+ coef /= 10n;
2200
+ exp++;
2119
2201
  }
2120
- return new _BigNumber(sign2, BigInt(str), trailingZeros);
2202
+ return new _BigNumber(sign2, coef, exp);
2121
2203
  }
2122
2204
  /**
2123
2205
  * Create a BigNumber from a JSON object
@@ -6199,7 +6281,7 @@ var createUnitClass = /* @__PURE__ */ factory(
6199
6281
  } else {
6200
6282
  prefixes = PREFIXES.NONE;
6201
6283
  }
6202
- let newUnit = {};
6284
+ let newUnit;
6203
6285
  if (!defUnit) {
6204
6286
  baseName = baseName || name2 + "_STUFF";
6205
6287
  if (BASE_DIMENSIONS.indexOf(baseName) >= 0) {
package/dist/index.d.ts CHANGED
@@ -258,8 +258,11 @@ declare class Complex implements IComplex {
258
258
  */
259
259
  inverse(): Complex;
260
260
  /**
261
- * Square root using principal branch
262
- * √z = √r · e^(iθ/2) where r = |z|, θ = arg(z)
261
+ * Square root using the principal branch (Re ≥ 0; Im has the sign of `this.im`).
262
+ *
263
+ * Algebraic form, not polar: one hypot + one sqrt instead of hypot + atan2 +
264
+ * cos + sin. Same branch cut as C99 / the previous polar implementation,
265
+ * including `sqrt(-x - 0i) = −√x · i`.
263
266
  */
264
267
  sqrt(): Complex;
265
268
  /**
@@ -299,11 +302,13 @@ declare class Complex implements IComplex {
299
302
  */
300
303
  cos(): Complex;
301
304
  /**
302
- * Tangent: tan(z) = sin(z) / cos(z)
305
+ * Tangent: tan(x+iy) = (sin 2x + i sinh 2y) / (cos 2x + cosh 2y)
306
+ *
307
+ * Closed form — no intermediate `sin`/`cos` Complex allocations.
303
308
  */
304
309
  tan(): Complex;
305
310
  /**
306
- * Cotangent: cot(z) = cos(z) / sin(z)
311
+ * Cotangent: cot(x+iy) = (sin 2x − i sinh 2y) / (cosh 2y − cos 2x)
307
312
  */
308
313
  cot(): Complex;
309
314
  /**
@@ -323,11 +328,11 @@ declare class Complex implements IComplex {
323
328
  */
324
329
  cosh(): Complex;
325
330
  /**
326
- * Hyperbolic tangent: tanh(z) = sinh(z) / cosh(z)
331
+ * Hyperbolic tangent: tanh(x+iy) = (sinh 2x + i sin 2y) / (cosh 2x + cos 2y)
327
332
  */
328
333
  tanh(): Complex;
329
334
  /**
330
- * Hyperbolic cotangent: coth(z) = cosh(z) / sinh(z)
335
+ * Hyperbolic cotangent: coth(x+iy) = (sinh 2x − i sin 2y) / (cosh 2x − cos 2y)
331
336
  */
332
337
  coth(): Complex;
333
338
  /**
@@ -2558,6 +2563,9 @@ declare function scaledDistance(a: ArrayLike<number>, b: ArrayLike<number>): num
2558
2563
  * Measured on 1e9-pedestal data: the plain naive two-pass (what shipped) lands ~1e-7 relative error;
2559
2564
  * this lands ~1e-16 — better than `np.var`, which uses the uncorrected two-pass (~1e-13).
2560
2565
  *
2566
+ * The deviation vector is never materialised: both pairwise sums walk `xs` in
2567
+ * registers, so variance/std no longer pay an extra n-long allocation.
2568
+ *
2561
2569
  * Divide the result by `n` (uncorrected), `n − 1` (unbiased/sample), or `n + 1` (biased) for the
2562
2570
  * corresponding variance. Returns 0 for fewer than two elements.
2563
2571
  */
package/dist/index.js CHANGED
@@ -44,7 +44,7 @@ import {
44
44
  round,
45
45
  sign,
46
46
  subtractScalar
47
- } from "./chunk-VPK5YTKG.js";
47
+ } from "./chunk-L5MWGOLB.js";
48
48
 
49
49
  // src/types/matrix/Range.ts
50
50
  var name = "Range";
@@ -1301,13 +1301,60 @@ function sumSquaredDeviations(xs) {
1301
1301
  const n = xs.length;
1302
1302
  if (n < 2) return 0;
1303
1303
  const mean = pairwiseSum(xs) / n;
1304
- const d = new Float64Array(n);
1305
- for (let i = 0; i < n; i++) d[i] = xs[i] - mean;
1306
- const sumD = pairwiseSum(d);
1307
- const sumDD = pairwiseDot(d, d);
1304
+ const { sumD, sumDD } = pairwiseDeviationSums(xs, mean, 0, n);
1308
1305
  const corrected = sumDD - sumD * sumD / n;
1309
1306
  return corrected < 0 ? 0 : corrected;
1310
1307
  }
1308
+ function pairwiseDeviationSums(xs, mean, start, end) {
1309
+ const n = end - start;
1310
+ if (n <= PAIRWISE_BLOCK) {
1311
+ let d0 = 0, d1 = 0, d2 = 0, d3 = 0, d4 = 0, d5 = 0, d6 = 0, d7 = 0;
1312
+ let q0 = 0, q1 = 0, q2 = 0, q3 = 0, q4 = 0, q5 = 0, q6 = 0, q7 = 0;
1313
+ let i = start;
1314
+ const limit = start + (n - n % 8);
1315
+ for (; i < limit; i += 8) {
1316
+ const a0 = xs[i] - mean;
1317
+ const a1 = xs[i + 1] - mean;
1318
+ const a2 = xs[i + 2] - mean;
1319
+ const a3 = xs[i + 3] - mean;
1320
+ const a4 = xs[i + 4] - mean;
1321
+ const a5 = xs[i + 5] - mean;
1322
+ const a6 = xs[i + 6] - mean;
1323
+ const a7 = xs[i + 7] - mean;
1324
+ d0 += a0;
1325
+ q0 += a0 * a0;
1326
+ d1 += a1;
1327
+ q1 += a1 * a1;
1328
+ d2 += a2;
1329
+ q2 += a2 * a2;
1330
+ d3 += a3;
1331
+ q3 += a3 * a3;
1332
+ d4 += a4;
1333
+ q4 += a4 * a4;
1334
+ d5 += a5;
1335
+ q5 += a5 * a5;
1336
+ d6 += a6;
1337
+ q6 += a6 * a6;
1338
+ d7 += a7;
1339
+ q7 += a7 * a7;
1340
+ }
1341
+ let tailD = 0;
1342
+ let tailDD = 0;
1343
+ for (; i < end; i++) {
1344
+ const a = xs[i] - mean;
1345
+ tailD += a;
1346
+ tailDD += a * a;
1347
+ }
1348
+ return {
1349
+ sumD: d0 + d1 + (d2 + d3) + (d4 + d5 + (d6 + d7)) + tailD,
1350
+ sumDD: q0 + q1 + (q2 + q3) + (q4 + q5 + (q6 + q7)) + tailDD
1351
+ };
1352
+ }
1353
+ const half = (n >> 1) - (n >> 1) % 8;
1354
+ const left = pairwiseDeviationSums(xs, mean, start, start + half);
1355
+ const right = pairwiseDeviationSums(xs, mean, start + half, end);
1356
+ return { sumD: left.sumD + right.sumD, sumDD: left.sumDD + right.sumDD };
1357
+ }
1311
1358
  function neumaierCumsum(xs, out) {
1312
1359
  let sum = 0;
1313
1360
  let c = 0;
@@ -1321,7 +1368,7 @@ function neumaierCumsum(xs, out) {
1321
1368
  }
1322
1369
 
1323
1370
  // src/index.ts
1324
- var VERSION = "0.14.1";
1371
+ var VERSION = "0.14.3";
1325
1372
  export {
1326
1373
  ALL_UNITS,
1327
1374
  BASE_UNITS,
package/dist/internal.js CHANGED
@@ -78,7 +78,7 @@ import {
78
78
  typeOf,
79
79
  unitDependencies,
80
80
  warnOnce
81
- } from "./chunk-VPK5YTKG.js";
81
+ } from "./chunk-L5MWGOLB.js";
82
82
 
83
83
  // src/error/DimensionError.ts
84
84
  var DimensionError = class _DimensionError extends RangeError {
@@ -232,7 +232,7 @@ function format2(value, options) {
232
232
  let str;
233
233
  const rounded = v.toSignificantDigits(precision);
234
234
  const exp = rounded.e;
235
- let condition = false;
235
+ let condition;
236
236
  if (isBigNumber(lowerExp) && isBigNumber(upperExp)) {
237
237
  const lowerExpBn = lowerExp;
238
238
  const upperExpBn = upperExp;
@@ -559,7 +559,9 @@ function reshape(array, sizes) {
559
559
  return _reshape(flatArray, processedSizes);
560
560
  } catch (e) {
561
561
  if (e instanceof DimensionError) {
562
- throw new DimensionError(newLength, currentLength, "!=");
562
+ const dimErr = new DimensionError(newLength, currentLength, "!=");
563
+ dimErr.cause = e;
564
+ throw dimErr;
563
565
  }
564
566
  throw e;
565
567
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielsimonjr/mathts-core",
3
- "version": "0.14.1",
3
+ "version": "0.14.3",
4
4
  "description": "Core types, utilities, and configuration for MathTS",
5
5
  "author": "Daniel Simon Jr.",
6
6
  "license": "MIT",
@@ -38,7 +38,7 @@
38
38
  "typed-function": "github:danielsimonjr/typed-function"
39
39
  },
40
40
  "devDependencies": {
41
- "@types/node": "^25.5.2",
41
+ "@types/node": "^26.4.0",
42
42
  "tsup": "^8.0.0",
43
43
  "typescript": "^5.3.0",
44
44
  "vitest": "^4.1.10"