@danielsimonjr/mathts-functions

中文文档
0.83.0发布于 2026/11/11MITTypeScriptES Module近 30 天下载 7009

Mathematical functions for MathTS - arithmetic, algebra, trigonometry, statistics, and more

原始使用文档
文档目录3 节
  1. Install
  2. What it provides
  3. License

@danielsimonjr/mathts-functions

Math functions for MathTS.

The mathematical function library for MathTS — arithmetic, trigonometry, algebra, statistics, signal processing, and more — dispatched polymorphically via typed-function across number / Complex / Fraction / BigNumber / Matrix.

Install

npm install @danielsimonjr/mathts-functions

What it provides

  • Hundreds of typed functions (add, sin, svd-aware ops, parallelFFT, …).
  • A wired parse / evaluate against the full activated math scope.
  • scalar / evaluateScalar — evaluate a typed scalar tree (+ - * / ^, ln → natural log, log → log10, and the other scalar calls). A formula string is rejected. compileScalar evaluates the same tree over Float64Array columns and marks a row invalid where evaluateScalar would throw. compileScalarGradient reuses that tape to return exact ∂f/∂parameter for each row. fitScalarParameters fits those constants to data via levenbergMarquardt, bfgs, or nelderMead (multi-restart search with optional bounds).
  • levenbergMarquardt accepts an optional analytic jacobian in LMOptions; the default remains forward-difference numericJacobian. Stiff solveODE, solveDAE, and solveBVP use the same helper (forward differences; ODE/DAE use step: { rel: 1e-7, floor: 1e-8 }, BVP shooting uses h: 1e-7).
  • minimize (Nelder–Mead) delegates to nelderMead with an absolute simplex step; nelderMead keeps relative defaults for fitScalarParameters.
  • scalarToNode / nodeToScalar / simplifyScalar / scalarToTex — convert between scalar trees and wired expression nodes (no formula string); simplifyScalar uses the same simplify as the expression language.
  • paretoFront / scoreFront / selectFrontModel — hall of fame per complexity, log-loss scores on the log scale, and accuracy / score / best selection.
  • frontToLatexTable / frontToJson — export a scored front (M15). frontToLatexTable(scored, { precision }) writes one tabular with columns complexity, loss, score, equation and a header row; loss and score are toPrecision(precision) text (default 6, an integer from 1 to 100), a null score (the linear loss scale) is an empty cell, and each equation cell is scalarToTex inside $…$ because a tabular cell is text mode and \cdot, \frac and \sin need math mode (an infinite score is $\infty$). frontToJson(scored) returns { schemaVersion: 1, rows: [{ complexity, loss, score, key, tex }] } with key = scalarCanonicalKey(item) and tex = scalarToTex(item); a non-finite loss or score is the string 'Infinity', '-Infinity' or 'NaN', so the report survives JSON.stringify and JSON.parse (an exact fit scores Infinity, and JSON would turn that into the linear scale's null). A non-finite complexity throws RangeError.
  • inferScalarDimension / solveParameterDimensions — SI dimension of a scalar tree with exact Fraction exponents on SiDimensionVector ([L,M,T,I,Θ,N,J]), or one of four named violations with the path of the failing node (add-mismatch, transcendental-arg-not-dimensionless, non-literal-exponent-on-dimensional-base, unknown-symbol). solveParameterDimensions solves the dimension of each unknown fitted parameter from the equations the tree implies (+ operands agree, transcendental arguments are dimensionless, the root equals target), exactly via rationalNullspace; it returns solved, underdetermined, or inconsistent.
  • weightedMutation / mutateConstant / mutateOperator / mutateFeature / swapOperands / addNode / insertNode / deleteNode / rotateTree / randomizeTree / simplifyConstants / identityMutation / crossoverSubtrees — variation operators over a scalar tree. Each takes (node, rng, ctx) with a SeededRng and ctx = { grammar, perturbationFactor, temperature }, never changes its input, and returns null when the mutation does not apply or the result fails scalarGrammarAccepts. weightedMutation(weights?) picks one operator by DEFAULT_MUTATION_WEIGHTS (summing to 8.512392). The identity operator is named identityMutation because identity is the matrix identity export of this package; its weight key is still identity.
  • searchScalars — evolutionary search over scalar trees, an async generator of SearchProgress that returns a ScalarSearchResult. One population evolves by tournament selection and weightedMutation; it starts from seeds plus the smallest trees of enumerateScalars (both filtered by scalarGrammarAccepts and, when set, grammar.admit; a rejected seed is skipped, a rejected mutation is a failed attempt), refits parameters of a tree with probability optimizeProbability (fitScalarParameters), and keeps a hall of fame whose Pareto front is reported through paretoFront / scoreFront (modelSelection adds selectFrontModel; bestLossFactor forwards to its bestLossFactor when modelSelection is set, default 1.5). crossoverProbability defaults to 0 (no coin, mutation-only). Above 0 each offspring may take crossoverSubtrees of two tournament parents and otherwise falls through to mutation; the inherited parameters stay the first parent's. admit must be a pure function of the node; the search does not copy it. Loss is the sum of squared errors by default (loss: 'l2'); set loss to 'l1' or 'huber' and the hall and every refit use that same named loss from fitScalarParameters. Optional rowWeights (one finite >= 0 weight per row) apply to both. An optional fit object is forwarded to fitScalarParameters: restarts (default 2), maxIterations (default 8), bounds, algorithm, and initial (default the inherited vector); a bad bound or length throws RangeError before the first yield. A tree that is invalid on any positive-weight row has loss Infinity and never reaches the front; set invalidRows: 'penalize' to score such a tree as the fitter's invalid-row penalty (1e8) times its invalid rows, plus the chosen loss on the valid rows, instead. fittedParameters gives the values behind each front row's loss. options.rng is never advanced, so one seed gives one result. runScalarSearch(problem, options) is the one-call form: it consumes the generator and returns the final result; its options take seed (exactly one of seed and rng) and its problem may give columns as a record keyed by variable name instead of an aligned array. maxEvaluations caps evaluations, initial population included. With populations > 1 independent islands (rng.fork('island:' + index)) evolve side by side; after every generation each island's worst trees are replaced by copies of other islands' best (fractionReplaced, default 0.00036), the constant-perturbation temperature cools from initialTemperature (3.17) by 0.995 per generation (annealing), and tournaments rank by loss * exp(adaptiveParsimonyScaling * share) where share is how common the tree's size is (adaptiveParsimony, scaling 1040). Annealing and adaptive parsimony default to on only for several islands, so populations: 1 is the single-population search to the last bit. parallel: { timeoutMs?, pool? } scores each generation's trees on worker threads once observed has 100 or more rows (scalar-batch.worker.js, a second tsdown entry loaded by URL); parameter refits and every random draw stay on the caller thread, so a parallel run equals the serial run for the same seed, bit for bit. complexityWeights (a ScalarComplexityWeights from @danielsimonjr/mathts-expression) weighs the nodes of the complexity the hall, the truncation tie-break, and adaptive parsimony rank by; omitted, it is today's node count, and a non-finite weight throws RangeError before the first yield. simplify ('off' | 'constants' | 'algebraic', default 'off') simplifies each seed and each bred offspring once, before the grammar check and the score: 'constants' folds numeric-only subtrees (simplifyConstants), 'algebraic' runs simplifyScalar; a ScalarBuildError, RangeError, grammar rejection (including admit), or row-wise evaluation mismatch keeps the unsimplified tree (simplifyFallbacks on the result), and enumerated trees are not simplified. timeoutMs (default 30000, must be positive) bounds every worker call, queueing included. A pool you pass is yours to terminate; otherwise the search starts one when it first needs it and terminates it when the generator ends or is closed. The 100-row floor comes from the M3 benchmark (the tape against the per-row interpreter, on the caller thread); no worker round trip was timed, so parallel is opt-in and carries no speed-up claim.
  • numericallyEquivalent — sample two scalar trees with createSeededRng, evaluate via compileScalar, compare with core nearlyEqual. Numerical agreement alone never proves symbolic equivalence; a consistent verdict is evidence, not proof.
import { createSeededRng } from '@danielsimonjr/mathts-core';
import {
  compileScalar,
  compileScalarGradient,
  fitScalarParameters,
  numericallyEquivalent,
  frontToJson,
  frontToLatexTable,
  paretoFront,
  scoreFront,
  selectFrontModel,
  scalar,
  simplifyScalar,
  scalarToTex,
  runScalarSearch,
} from '@danielsimonjr/mathts-functions';

const node = scalar.op('*', [scalar.symbol('x'), scalar.symbol('x')]);
const linear = scalar.op('+', [
  scalar.op('*', [scalar.symbol('a'), scalar.symbol('x')]),
  scalar.symbol('b'),
]);
const gradCompiled = compileScalarGradient(linear, { variables: ['x'], parameters: ['a', 'b'] });
const { values, grad } = gradCompiled.evaluate([new Float64Array([3])], [2, -1]);
values[0]; // 5
[...grad]; // 3, 1 — ∂/∂a = x, ∂/∂b = 1
const quotient = scalar.op('/', [
  scalar.symbol('a'),
  scalar.op('/', [scalar.symbol('b'), scalar.symbol('c')]),
]);
scalarToTex(simplifyScalar(quotient)); // \frac{ a\cdot c}{ b}

const compiled = compileScalar(node, { variables: ['x'] });
compiled.evaluate([new Float64Array([2, 3])]).values; // Float64Array [4, 9]

const slope = scalar.op('*', [scalar.symbol('a'), scalar.symbol('x')]);
const xCol = new Float64Array([1, 2, 3]);
const yCol = new Float64Array([2, 4, 6]);
fitScalarParameters(slope, [xCol], yCol, ['x'], { parameters: ['a'], restarts: 0 }).parameters[0]; // 2

const front = paretoFront([
  { loss: 0.5, complexity: 1, item: 'x' },
  { loss: 0.1, complexity: 3, item: 'x^3' },
]);
selectFrontModel(scoreFront(front), 'best').item; // 'x^3'
frontToJson(scoreFront([{ loss: 0.5, complexity: 1, item: scalar.symbol('x') }])).rows[0]!.key; // '{"k":"s","v":"x"}'

const rng = createSeededRng(1);
const id = scalar.op('+', [
  scalar.op('^', [scalar.call('sin', scalar.symbol('x')), scalar.number(2)]),
  scalar.op('^', [scalar.call('cos', scalar.symbol('x')), scalar.number(2)]),
]);
numericallyEquivalent(id, scalar.number(1), { domain: { x: [0, 1] }, rng }).verdict; // 'consistent' — evidence, not proof

const quadGrammar = {
  variables: ['x'],
  binary: ['+', '*', '^'],
  unary: [],
  literals: [1],
  maxSize: 7,
} as const;
const quad = scalar.op('+', [
  scalar.op('*', [scalar.symbol('x'), scalar.symbol('x')]),
  scalar.symbol('x'),
]);
const xs = new Float64Array(20);
for (let i = 0; i < 20; i += 1) xs[i] = -1 + (2 * i) / 19;
const quadResult = await runScalarSearch(
  {
    variables: ['x'],
    columns: { x: xs },
    observed: compileScalar(quad, { variables: ['x'] }).evaluate([xs]).values,
  },
  { grammar: quadGrammar, seed: 7, populationSize: 8, tournamentSize: 4, maxEvaluations: 120 }
);
quadResult.front.at(-1)?.item; // x^2 + x — the planted law, at loss 0
quadResult.stopReason; // 'max-evaluations' — runScalarSearch consumes the generator for you
  • Per-domain focused entry points are also published: @danielsimonjr/mathts-{arithmetic,trigonometry,statistics,signal}.

License

MIT (c) Daniel Simon Jr.

版本与发布记录

@danielsimonjr/mathts-functions 共发布 132 个版本,首次发布于 2026/04/05;过去 12 个月发布了 132 个版本。

版本发布日期距今
0.83.0latest2026/11/11今天
0.82.02026/11/11今天
0.81.02026/11/11今天
0.80.12026/11/10今天
0.80.02026/11/10今天
0.79.02026/11/101 天前

关于 @danielsimonjr/mathts-functions 的常见问题

@danielsimonjr/mathts-functions 是什么?

Mathematical functions for MathTS - arithmetic, algebra, trigonometry, statistics, and more

如何安装 @danielsimonjr/mathts-functions?

在项目目录运行 npm install @danielsimonjr/mathts-functions,或使用 pnpm add / yarn add / bun add。

@danielsimonjr/mathts-functions 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@danielsimonjr/mathts-functions 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@danielsimonjr/mathts-functions 可以商用吗?

@danielsimonjr/mathts-functions 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@danielsimonjr/mathts-functions 的下载量有多少?

根据 npm 官方下载统计,@danielsimonjr/mathts-functions 在 2026/10/12 – 2026/11/10 这 30 天内被下载 7,009 次,日均约 234 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@danielsimonjr/mathts-functions 还在维护吗?

最新版本 0.83.0 发布于 2026/11/11(今天);至今共发布 132 个版本,其中过去 12 个月发布了 132 个;首次发布于 2026/04/05。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。