# @johnhenry/math

> Advanced college-level mathematics library — a modern TypeScript port of the Mallory ActionScript 3 library.

Latest version **0.0.1** (published 2026-08-28) · MIT license · 0 weekly downloads

## Install

```sh
npm install @johnhenry/math
pnpm add @johnhenry/math
yarn add @johnhenry/math
bun add @johnhenry/math
```

## Health

**Score 60/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.0.1 |
| Published | 2026-08-28 |
| First published | 2026-08-22 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM |
| Node | >=22.6.0 |
| Dependencies | 0 |
| Unpacked size | 1.7 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | John Henry |
| Maintainers | johnhenry |
| Keywords | math, mathematics, complex-numbers, linear-algebra, matrix, permutation, group-theory, finite-field, polynomial, expression-parser |

## Links

- npm: https://www.npmjs.com/package/@johnhenry/math
- Repository: https://github.com/johnhenry/math
- Homepage: https://github.com/johnhenry/math#readme
- Issues: https://github.com/johnhenry/math/issues
- npm.io page: https://npm.io/package/@johnhenry/math

## Alternatives

- [random-seedable](https://npm.io/package/random-seedable.md) — 27.9K weekly downloads
- [n2words](https://npm.io/package/n2words.md) — 22.2K weekly downloads
- [@stdlib/math-base-special-factorialln](https://npm.io/package/@stdlib/math-base-special-factorialln.md) — 5.7K weekly downloads
- [@stdlib/math-base-special-abs2](https://npm.io/package/@stdlib/math-base-special-abs2.md) — 1.7K weekly downloads
- [commons-math-interpolation](https://npm.io/package/commons-math-interpolation.md) — 1.4K weekly downloads

## Recent versions

- 0.0.1 (latest) — 2026-08-28
- 0.0.0 — 2026-08-22

## README

# @johnhenry/math

**Advanced college-level mathematics for TypeScript** — a modern, fully-typed,
test-covered port of the Mallory ActionScript 3 library (a project worked on,
on and off, since 2004), published to npm as `@johnhenry/math`.

Complex numbers, linear algebra over arbitrary algebraic structures,
combinatorics and number theory, an expression evaluator, and renderer-agnostic
graphing geometry — all rewritten in modern TypeScript with `node:test`
(example-based and, for algebraic laws, property-based via `fast-check`).

```ts
import { ComplexNumber, Structure, Vector, StringEvaluator } from "@johnhenry/math";

ComplexNumber.E.power(new ComplexNumber(0, Math.PI)); // ≈ -1  (Euler)
Structure.realField().determinant(/* 3×3 matrix, as Vector<Vector<number>> */);
StringEvaluator.evaluate("sin(pi/2) + 2^3", StringEvaluator.mathEnvironment()); // 9
```

## Install & use

Requires Node.js ≥ 22.6 (the test suite runs `.ts` directly via Node's built-in
type stripping).

```bash
npm install @johnhenry/math
```

To work on the library itself from within this monorepo:

```bash
npm install
npm test           # run the node:test suite (against src/)
npm run typecheck  # tsc --noEmit
npm run check      # Biome lint + format check
npm run check:fix  # apply Biome fixes
npm run build      # emit ./dist (ESM + .d.ts)
npm run test:build # build, then smoke-test the emitted package
npm run docs       # generate the API reference into docs/api (TypeDoc)
```

Continuous integration (`.github/workflows/ci.yml`) runs typecheck → lint →
tests → build → dist smoke test → docs build on Node 22 and 24.

**Documentation:**

- **[Cookbook](docs/COOKBOOK.md)** — task-oriented recipes across every
  domain (linear algebra, symbolic calculus, number theory, group theory,
  FFT, geometry, graphs, and more), each one verified against the test suite.
- **API reference** — generated with [TypeDoc](https://typedoc.org) from
  the source JSDoc; run `npm run docs` and open `docs/api/index.html`.

## Modules

| Area | Modules |
|------|---------|
| Foundations | `Vector`, `ComplexNumber` (arithmetic, trig, logs as fluent instance methods), `Type` |
| Real & complex analysis | `RealMath` (plain scalar functions, not a class), `ComplexMath` (complex vectors + probability helpers), `Statistics` (descriptive stats on `number[]`) |
| Linear algebra | `VectorUtils`, generic linear algebra in `Structure`, numerical decompositions in `MatrixMath` |
| Algebraic structures | `Structure` — groups/rings/fields; do linear algebra over e.g. GF(7) |
| Number theory & combinatorics | `Permutation`, `Cycle` |
| Geometry | `Polygon`, `GraphUtils`, `Graph3DUtils` (emit paths/meshes as plain data) |
| Expressions | `Environment`, `Expression`, `StringEvaluator` |
| Misc | `Utilities`, `Logic`, `IntUtils`, `SpecialOperator` |

## About the port

This is a faithful port that **fixes bugs rather than carrying them over**, and
takes advantage of modern JavaScript/TypeScript: ES classes, generics, iterators,
`Array` subclassing, tagged unions, and `.ts`-native execution. Every module was
translated **test-first**.

A sampling of the ~40 bugs found and fixed while translating:

- **`RealMath.subtract` returned `a * b`.** (Yes, really.)
- **Order statistics were broken:** `sort` used the default *lexicographic* sort,
  so `minimum`/`maximum`/`median` were wrong for numbers.
- **`ComplexMath.divide`** compared `alpha.ivalue` (lowercase `v`, always
  `undefined`), so all eight directed-infinity results were dead code.
- **`ComplexMath.normalDistribution`** reciprocated the whole expression, putting
  the exponential in the denominator (wrong sign) — the normal PDF was inverted.
- **`solveN`** wasn't Newton's method — it assumed a derivative of 1 and diverged;
  now a real numeric Newton–Raphson.
- **`integrateN`** sampled at `2·x + interval`; **`differentiateN`** was a forward
  difference despite claiming to be symmetric.
- **`invertMatrix`** had no pivoting (divide-by-zero on a zero pivot); now uses
  partial pivoting (and a zero-pivot row swap in `Structure`, for finite fields).
- **`crossProduct`** read index 3 for the z-component and used truthiness tests
  that dropped zero components; **`powerMatrix`** never actually multiplied.
- **`Vector.setElement`** infinitely recursed on a falsy slot.
- **`ComplexNumber` string parsing** crashed on non-matches and couldn't
  round-trip negative imaginary parts; it also swallowed every `*`, so `"4*2"`
  parsed as `42`.
- **`StringEvaluator`** was uniformly right-associative (`10-2-3 → 11`); now
  left-associative for `+ - * / %` and right-associative for `^`.
- **`Polynomial.multiply`** referenced a non-existent `dimension.value`;
  **`Polynomial.antiderivative`** dropped its highest-degree term.
- **`IntegerMath.modulus`** recursed one step at a time (stack overflow);
  `primeFactors` infinite-looped on `0` and negatives.
- **`Structure`**'s matrix section was non-functional (static/instance confusion,
  undefined references) and is reconstructed as working generic linear algebra.
- `IntUtils` spelled "forty" and "ninety" as "fourty" and "ninty".

Where the original genuinely had *no* verifiable intended behavior — the Flash
3D ribbon geometry in `Graph3DUtils` — the math is ported verbatim with an
explicit note rather than "fixed" by guesswork. The Flash rendering utilities
(`GraphUtils`/`Graph3DUtils`) now return renderer-agnostic geometry (2D paths,
3D meshes) instead of Flash display objects.

## Beyond the original

A completeness pass added the missing counterparts and a few natural supplements
the AS3 library never had:

- **`ComplexNumber`**: `fromPolar`, `fromVector`, `fromXML` (inverses of
  `magnitude`/`angle`, `toVector`, `toXML`).
- **`Vector`**: `fromXML`, `fromString` (best-effort inverses of `toXML`/`toString`).
- **`PolynomialRing`**: `evaluate` (Horner), `add`/`subtract`, `divide`/`mod`/`divmod`
  (long division), `derivative`/`antiderivative` (generalized to any `Structure`,
  not just reals), and the real-number-only `parsePolynomial`/`polynomialToString`
  helpers (inverses of each other).
- **`Polygon`**: `centroid`, `contains` (point-in-polygon), `isConvex`, `isSimple`.
- **`Statistics`**: `populationVariance` / `populationStandardDeviation`
  alongside the sample versions.
- **`Structure` presets**: `Structure.realField()`, `complexField()`,
  `integersModulo(n)` (a field when `n` is prime), and `booleanRing()` — so you
  can do linear algebra over these without wiring up operations by hand:

  ```ts
  const gf7 = Structure.integersModulo(7);
  gf7.invertMatrix(/* a matrix over GF(7) */); // Gauss-Jordan over the finite field
  ```

## Expanded mathematics

Well beyond the original ActionScript scope, the library now spans:

| Area | Module(s) | Highlights |
|------|-----------|------------|
| Numerical linear algebra | `MatrixMath` | LU, QR, Cholesky, symmetric eigen (Jacobi), SVD; `solve`, RREF, rank, null space, least squares, pseudo-inverse, norms, condition number |
| Symbolic calculus | `Symbolic` | expression parser (41 unary elementary functions incl. inverse-trig, reciprocal-trig, hyperbolic/inverse-hyperbolic, `abs`/`log10`/`log2`/`cbrt`/`floor`/`ceil`/`round`/`sign`/`trunc`, and `expm1`/`log1p`/`sigmoid`/`erf`/`relu`, with `arcsin`/`logistic`-style aliases and `\|x\|` bar syntax, plus N-ary `atan2`/`hypot`/`min`/`max`/`gcd`/`lcm`, `log(base, x)`/`clamp(x, lo, hi)`, and `piecewise(cond, expr, ..., otherwise)` with `<`/`<=`/`>`/`>=`/`==`/`!=` comparisons), symbolic differentiation (incl. the multivariate chain rule for the N-ary functions and branch-wise piecewise differentiation) with a u-substitution fallback for `integrate`, algebraic simplification with like-term collection and constant-folding, elementary integration (incl. by-parts, arctan/arcsin forms, and u-substitution), `integrateDefinite` (closed-form first, adaptive-quadrature fallback), `sumSeries` (finite/infinite, closed-form geometric recognition + numeric fallback), Taylor series, `expand`/`substitute`, polynomial `solve`/`factor`, linear `solveSystem`, L'Hopital `limit` (incl. limits at infinity), LaTeX round-trip (`toLatex`/`fromLatex`, incl. `\operatorname{...}`, bracket notation for `abs`/`floor`/`ceil`/`cbrt`, and `\begin{cases}` for piecewise), `evaluateExact` (exact `Rational` evaluation), `evaluateOverStructure` (folds an `Expr` through an arbitrary `Structure`'s own algebra, e.g. for plotting over Z/7Z), and `freeVariables`/`assertVariables` (auto-detect an expression's variables, or opt into strict mode and throw `UndeclaredVariableError` instead of silently resolving an undeclared one to `NaN`) |
| Number types | `Rational`, `Quaternion`, `DualNumber`, `Interval` | exact bigint rationals, 3D-rotation quaternions, forward-mode autodiff, rigorous interval arithmetic — each also a `Structure` preset |
| 4D geometric algebra | `Vec4`, `Bivector4`, `Rotor4`, `GeometricAlgebra4` | a genuine fourth *spatial* dimension (not time): 4D vectors, 6-component bivectors (the 2-planes of 4D), and rotors that generalize `Quaternion` to 4D — including 4D-only **double rotations** (simultaneous, independent rotation in two orthogonal planes at once); built on an internal Cl(4,0) blade engine for correctness (verified against `Quaternion` on their shared 3D subspace). `GeometricAlgebra4` also has the `commutatorProduct` and `leftContraction` operations n-dimensional rigid-body dynamics needs (generalized Euler's equation, point velocity). `Rotor4.factor()`/`renormalize()` implement Perwass-style rotor factorization — the proper fix for numerical drift on a double rotation, where naive magnitude normalization silently produces an invalid rotor (verified against 200+ random plane orientations/angles, including the isoclinic and right-isoclinic degenerate cases) |
| Number theory | `NumberTheory` | `bigint` modPow, extended GCD, CRT, Miller–Rabin, Pollard-rho factorization, Legendre/Jacobi |
| Group theory | `GroupTheory` | Cayley tables, axiom checks, element order, generated subgroups, cosets, Lagrange, orbits, Sₙ/Zₙ |
| Numerical methods | `Numerical` | bisection/secant/Newton/Brent; Simpson, adaptive Simpson, Gauss–Legendre; Euler & RK4 ODE solvers |
| Probability & special functions | `SpecialFunctions`, `Distributions` | gamma/beta/erf, incomplete gamma/beta; normal/exponential/uniform/gamma/χ²/t/binomial/Poisson; t-tests, χ² GoF, CIs |
| Signal processing | `FFT` | radix-2 FFT/IFFT, DFT, FFT convolution |
| Computational geometry | `Geometry`, `Transform2D` | convex hull, predicates, point-in-polygon, 2D affine transforms |
| Graph theory | `Graph` | BFS/DFS, Dijkstra, Kruskal MST, topological sort, components, Floyd–Warshall |
| Counting mathematics | `Combinatorics` | `bigint` factorials, nCk/nPk, multinomial coefficients, Catalan/Stirling/Bell numbers, integer partitions, derangements |
| Arbitrary precision | `Decimal` | `bigint`-backed decimal arithmetic — exact add/subtract/multiply, configurable-precision division; also a `Structure` preset |
| Abstract algebra | `PolynomialRing` | polynomials over any `Structure` (finite fields, rationals, ...) — long division, monic GCD, Horner evaluation, derivative/antiderivative |
| Multivariable calculus | `VectorCalculus` | gradient, directional derivative, Jacobian, divergence, curl, Hessian (via `DualNumber` autodiff), plus an exact symbolic gradient |

Many of these interlock: `GroupTheory` runs over any `Structure` (including
`integersModulo`); `Graph.floydWarshall` emits matrices for `MatrixMath`;
`DualNumber` gives exact derivatives, which both `Structure.dualNumbers()` and
`VectorCalculus` build on; `PolynomialRing` composes with any `Structure`
preset (including the new `Decimal`-backed `decimalField()`); and
`SpecialFunctions` gives the `Distributions` CDFs exact closed forms.

## License

MIT

---
_Source: https://npm.io/package/@johnhenry/math · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
