universal-physics-tensor 10.0.0 → 11.0.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/README.md +4 -3
- package/bin/upt.mjs +13 -1
- package/data/atlas/atlas.json +25 -25
- package/data/atlas/atlas.jsonld +1 -1
- package/data/atlas/diffusion.json +6 -6
- package/data/atlas/oscillators.json +7 -7
- package/data/atlas/waves.json +14 -14
- package/data/atlas/witness-results.json +11 -11
- package/data/bridge-catalog.json +371 -228
- package/data/bridge-catalog.schema.json +45 -7
- package/dist/atlas/applicability.d.ts.map +1 -1
- package/dist/atlas/applicability.js +21 -15
- package/dist/atlas/applicability.js.map +1 -1
- package/dist/atlas/benchmark/hybrid-retrieval.d.ts +9 -1
- package/dist/atlas/benchmark/hybrid-retrieval.d.ts.map +1 -1
- package/dist/atlas/benchmark/hybrid-retrieval.js +15 -13
- package/dist/atlas/benchmark/hybrid-retrieval.js.map +1 -1
- package/dist/atlas/benchmark/loader.js +2 -2
- package/dist/atlas/benchmark/loader.js.map +1 -1
- package/dist/atlas/benchmark/stats.d.ts +2 -2
- package/dist/atlas/benchmark/stats.d.ts.map +1 -1
- package/dist/atlas/benchmark/stats.js +15 -7
- package/dist/atlas/benchmark/stats.js.map +1 -1
- package/dist/atlas/catalog-formal-ref.d.ts +26 -3
- package/dist/atlas/catalog-formal-ref.d.ts.map +1 -1
- package/dist/atlas/catalog-formal-ref.js +52 -5
- package/dist/atlas/catalog-formal-ref.js.map +1 -1
- package/dist/atlas/chain-pipeline.d.ts.map +1 -1
- package/dist/atlas/chain-pipeline.js +7 -8
- package/dist/atlas/chain-pipeline.js.map +1 -1
- package/dist/atlas/diffusion/bridges-closure.d.ts +0 -4
- package/dist/atlas/diffusion/bridges-closure.d.ts.map +1 -1
- package/dist/atlas/diffusion/bridges-closure.js +8 -12
- package/dist/atlas/diffusion/bridges-closure.js.map +1 -1
- package/dist/atlas/diffusion/bridges.d.ts.map +1 -1
- package/dist/atlas/diffusion/bridges.js +27 -39
- package/dist/atlas/diffusion/bridges.js.map +1 -1
- package/dist/atlas/diffusion/dimensions.d.ts +6 -14
- package/dist/atlas/diffusion/dimensions.d.ts.map +1 -1
- package/dist/atlas/diffusion/dimensions.js +8 -16
- package/dist/atlas/diffusion/dimensions.js.map +1 -1
- package/dist/atlas/diffusion/models.d.ts +3 -3
- package/dist/atlas/diffusion/models.d.ts.map +1 -1
- package/dist/atlas/diffusion/models.js +5 -10
- package/dist/atlas/diffusion/models.js.map +1 -1
- package/dist/atlas/diffusion/numerics.d.ts +16 -4
- package/dist/atlas/diffusion/numerics.d.ts.map +1 -1
- package/dist/atlas/diffusion/numerics.js +38 -24
- package/dist/atlas/diffusion/numerics.js.map +1 -1
- package/dist/atlas/link-prediction.d.ts +106 -3
- package/dist/atlas/link-prediction.d.ts.map +1 -1
- package/dist/atlas/link-prediction.js +212 -66
- package/dist/atlas/link-prediction.js.map +1 -1
- package/dist/atlas/oscillators/bridges-coarse.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-coarse.js +7 -11
- package/dist/atlas/oscillators/bridges-coarse.js.map +1 -1
- package/dist/atlas/oscillators/bridges-exact.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-exact.js +6 -7
- package/dist/atlas/oscillators/bridges-exact.js.map +1 -1
- package/dist/atlas/oscillators/bridges-limits.d.ts +3 -16
- package/dist/atlas/oscillators/bridges-limits.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-limits.js +23 -34
- package/dist/atlas/oscillators/bridges-limits.js.map +1 -1
- package/dist/atlas/oscillators/dimensions.d.ts +9 -21
- package/dist/atlas/oscillators/dimensions.d.ts.map +1 -1
- package/dist/atlas/oscillators/dimensions.js +9 -21
- package/dist/atlas/oscillators/dimensions.js.map +1 -1
- package/dist/atlas/oscillators/limit-witnesses.d.ts +2 -2
- package/dist/atlas/oscillators/limit-witnesses.d.ts.map +1 -1
- package/dist/atlas/oscillators/limit-witnesses.js +17 -15
- package/dist/atlas/oscillators/limit-witnesses.js.map +1 -1
- package/dist/atlas/oscillators/models.d.ts.map +1 -1
- package/dist/atlas/oscillators/models.js +2 -6
- package/dist/atlas/oscillators/models.js.map +1 -1
- package/dist/atlas/oscillators/pendulum-motion.d.ts +29 -6
- package/dist/atlas/oscillators/pendulum-motion.d.ts.map +1 -1
- package/dist/atlas/oscillators/pendulum-motion.js +60 -40
- package/dist/atlas/oscillators/pendulum-motion.js.map +1 -1
- package/dist/atlas/oscillators/phase-translation.d.ts +0 -11
- package/dist/atlas/oscillators/phase-translation.d.ts.map +1 -1
- package/dist/atlas/oscillators/phase-translation.js +3 -4
- package/dist/atlas/oscillators/phase-translation.js.map +1 -1
- package/dist/atlas/oscillators/position-translation.d.ts +68 -7
- package/dist/atlas/oscillators/position-translation.d.ts.map +1 -1
- package/dist/atlas/oscillators/position-translation.js +123 -12
- package/dist/atlas/oscillators/position-translation.js.map +1 -1
- package/dist/atlas/oscillators/rejections.d.ts +0 -2
- package/dist/atlas/oscillators/rejections.d.ts.map +1 -1
- package/dist/atlas/oscillators/rejections.js +0 -7
- package/dist/atlas/oscillators/rejections.js.map +1 -1
- package/dist/atlas/physjs-entries.generated.d.ts +25 -24
- package/dist/atlas/physjs-entries.generated.d.ts.map +1 -1
- package/dist/atlas/physjs-entries.generated.js +25 -24
- package/dist/atlas/physjs-entries.generated.js.map +1 -1
- package/dist/atlas/physjs-ref.d.ts +34 -31
- package/dist/atlas/physjs-ref.d.ts.map +1 -1
- package/dist/atlas/physjs-ref.js +55 -53
- package/dist/atlas/physjs-ref.js.map +1 -1
- package/dist/atlas/physjs-reviewed.d.ts +1 -1
- package/dist/atlas/physjs-reviewed.js +15 -15
- package/dist/atlas/physjs-reviewed.js.map +1 -1
- package/dist/atlas/poster/statements.d.ts +0 -19
- package/dist/atlas/poster/statements.d.ts.map +1 -1
- package/dist/atlas/poster/statements.js +1 -1
- package/dist/atlas/poster/statements.js.map +1 -1
- package/dist/atlas/proof-target.d.ts +1 -1
- package/dist/atlas/proof-target.js +1 -1
- package/dist/atlas/proof-target.js.map +1 -1
- package/dist/atlas/regime.d.ts +1 -1
- package/dist/atlas/regime.d.ts.map +1 -1
- package/dist/atlas/regime.js +1 -1
- package/dist/atlas/regime.js.map +1 -1
- package/dist/atlas/text-overlap.d.ts +23 -0
- package/dist/atlas/text-overlap.d.ts.map +1 -0
- package/dist/atlas/text-overlap.js +41 -0
- package/dist/atlas/text-overlap.js.map +1 -0
- package/dist/atlas/waves/bridges-closure.d.ts.map +1 -1
- package/dist/atlas/waves/bridges-closure.js +2 -6
- package/dist/atlas/waves/bridges-closure.js.map +1 -1
- package/dist/atlas/waves/bridges.d.ts.map +1 -1
- package/dist/atlas/waves/bridges.js +32 -48
- package/dist/atlas/waves/bridges.js.map +1 -1
- package/dist/atlas/waves/models.d.ts +5 -6
- package/dist/atlas/waves/models.d.ts.map +1 -1
- package/dist/atlas/waves/models.js +7 -13
- package/dist/atlas/waves/models.js.map +1 -1
- package/dist/atlas/waves/numerics.d.ts.map +1 -1
- package/dist/atlas/waves/numerics.js +10 -3
- package/dist/atlas/waves/numerics.js.map +1 -1
- package/dist/atlas/witness-numeric.d.ts +30 -0
- package/dist/atlas/witness-numeric.d.ts.map +1 -1
- package/dist/atlas/witness-numeric.js +53 -0
- package/dist/atlas/witness-numeric.js.map +1 -1
- package/dist/atlas/witness-specs.d.ts.map +1 -1
- package/dist/atlas/witness-specs.js +19 -0
- package/dist/atlas/witness-specs.js.map +1 -1
- package/dist/atlas/witness-symbolic.d.ts +75 -3
- package/dist/atlas/witness-symbolic.d.ts.map +1 -1
- package/dist/atlas/witness-symbolic.js +116 -10
- package/dist/atlas/witness-symbolic.js.map +1 -1
- package/dist/bridges/catalog-load.d.ts.map +1 -1
- package/dist/bridges/catalog-load.js +13 -8
- package/dist/bridges/catalog-load.js.map +1 -1
- package/dist/bridges/catalog-types.d.ts +26 -2
- package/dist/bridges/catalog-types.d.ts.map +1 -1
- package/dist/bridges/catalog-types.js +11 -1
- package/dist/bridges/catalog-types.js.map +1 -1
- package/dist/bridges/evaluation-errors.d.ts +31 -1
- package/dist/bridges/evaluation-errors.d.ts.map +1 -1
- package/dist/bridges/evaluation-errors.js +20 -2
- package/dist/bridges/evaluation-errors.js.map +1 -1
- package/dist/bridges/evaluator-inputs.d.ts.map +1 -1
- package/dist/bridges/evaluator-inputs.js +7 -5
- package/dist/bridges/evaluator-inputs.js.map +1 -1
- package/dist/bridges/evaluators.d.ts.map +1 -1
- package/dist/bridges/evaluators.js +27 -12
- package/dist/bridges/evaluators.js.map +1 -1
- package/dist/bridges/expr-parse.d.ts +11 -0
- package/dist/bridges/expr-parse.d.ts.map +1 -1
- package/dist/bridges/expr-parse.js +14 -5
- package/dist/bridges/expr-parse.js.map +1 -1
- package/dist/bridges/holds.d.ts +35 -3
- package/dist/bridges/holds.d.ts.map +1 -1
- package/dist/bridges/holds.js +117 -23
- package/dist/bridges/holds.js.map +1 -1
- package/dist/bridges/notices.d.ts.map +1 -1
- package/dist/bridges/notices.js +5 -5
- package/dist/bridges/notices.js.map +1 -1
- package/dist/bridges/relation-eval.d.ts +4 -4
- package/dist/bridges/relation-eval.d.ts.map +1 -1
- package/dist/bridges/relation-eval.js +15 -16
- package/dist/bridges/relation-eval.js.map +1 -1
- package/dist/bridges/sensitivity.d.ts.map +1 -1
- package/dist/bridges/sensitivity.js +3 -3
- package/dist/bridges/sensitivity.js.map +1 -1
- package/dist/bridges/validity.d.ts +33 -0
- package/dist/bridges/validity.d.ts.map +1 -0
- package/dist/bridges/validity.js +67 -0
- package/dist/bridges/validity.js.map +1 -0
- package/dist/canonical/entries/atomic.js +1 -3
- package/dist/canonical/entries/atomic.js.map +1 -1
- package/dist/canonical/entries/condensed-matter.d.ts.map +1 -1
- package/dist/canonical/entries/condensed-matter.js +4 -5
- package/dist/canonical/entries/condensed-matter.js.map +1 -1
- package/dist/canonical/entries/dimensional-classics.d.ts.map +1 -1
- package/dist/canonical/entries/dimensional-classics.js +3 -4
- package/dist/canonical/entries/dimensional-classics.js.map +1 -1
- package/dist/canonical/entries/electromagnetism.d.ts.map +1 -1
- package/dist/canonical/entries/electromagnetism.js +4 -10
- package/dist/canonical/entries/electromagnetism.js.map +1 -1
- package/dist/canonical/entries/fluids-waves.d.ts.map +1 -1
- package/dist/canonical/entries/fluids-waves.js +3 -7
- package/dist/canonical/entries/fluids-waves.js.map +1 -1
- package/dist/canonical/entries/mechanics.d.ts.map +1 -1
- package/dist/canonical/entries/mechanics.js +4 -6
- package/dist/canonical/entries/mechanics.js.map +1 -1
- package/dist/canonical/entries/nonmonomial.d.ts.map +1 -1
- package/dist/canonical/entries/nonmonomial.js +9 -17
- package/dist/canonical/entries/nonmonomial.js.map +1 -1
- package/dist/canonical/entries/relativity.d.ts.map +1 -1
- package/dist/canonical/entries/relativity.js +6 -6
- package/dist/canonical/entries/relativity.js.map +1 -1
- package/dist/canonical/entries/thermo-nuclear-cosmo.d.ts.map +1 -1
- package/dist/canonical/entries/thermo-nuclear-cosmo.js +6 -10
- package/dist/canonical/entries/thermo-nuclear-cosmo.js.map +1 -1
- package/dist/canonical/fixed-points.d.ts +94 -0
- package/dist/canonical/fixed-points.d.ts.map +1 -0
- package/dist/canonical/fixed-points.js +81 -0
- package/dist/canonical/fixed-points.js.map +1 -0
- package/dist/canonical/linkage.d.ts.map +1 -1
- package/dist/canonical/linkage.js +25 -44
- package/dist/canonical/linkage.js.map +1 -1
- package/dist/canonical/normal-form.d.ts.map +1 -1
- package/dist/canonical/normal-form.js +5 -11
- package/dist/canonical/normal-form.js.map +1 -1
- package/dist/canonical/structural.d.ts +21 -21
- package/dist/canonical/structural.d.ts.map +1 -1
- package/dist/canonical/structural.js +40 -19
- package/dist/canonical/structural.js.map +1 -1
- package/dist/cases/brownian-sphere.d.ts +3 -3
- package/dist/cases/brownian-sphere.d.ts.map +1 -1
- package/dist/cases/brownian-sphere.js +6 -5
- package/dist/cases/brownian-sphere.js.map +1 -1
- package/dist/cases/damped-resonator.d.ts.map +1 -1
- package/dist/cases/damped-resonator.js +6 -9
- package/dist/cases/damped-resonator.js.map +1 -1
- package/dist/cases/kepler-rv.d.ts +1 -1
- package/dist/cases/kepler-rv.d.ts.map +1 -1
- package/dist/cases/kepler-rv.js +3 -2
- package/dist/cases/kepler-rv.js.map +1 -1
- package/dist/cases/lumped-cooling.d.ts +8 -3
- package/dist/cases/lumped-cooling.d.ts.map +1 -1
- package/dist/cases/lumped-cooling.js +21 -23
- package/dist/cases/lumped-cooling.js.map +1 -1
- package/dist/cases/quadrature.d.ts +7 -9
- package/dist/cases/quadrature.d.ts.map +1 -1
- package/dist/cases/quadrature.js +28 -32
- package/dist/cases/quadrature.js.map +1 -1
- package/dist/cases/resistor-noise.js +4 -4
- package/dist/cases/resistor-noise.js.map +1 -1
- package/dist/cases/skin-depth.d.ts +0 -4
- package/dist/cases/skin-depth.d.ts.map +1 -1
- package/dist/cases/skin-depth.js +3 -7
- package/dist/cases/skin-depth.js.map +1 -1
- package/dist/cli/args.d.ts +23 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +30 -8
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/bindings.d.ts.map +1 -1
- package/dist/cli/bindings.js +5 -4
- package/dist/cli/bindings.js.map +1 -1
- package/dist/cli/command.d.ts +8 -1
- package/dist/cli/command.d.ts.map +1 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/commands/_atlas-map.d.ts +0 -9
- package/dist/cli/commands/_atlas-map.d.ts.map +1 -1
- package/dist/cli/commands/_atlas-map.js +8 -18
- package/dist/cli/commands/_atlas-map.js.map +1 -1
- package/dist/cli/commands/_atlas-route.d.ts.map +1 -1
- package/dist/cli/commands/_atlas-route.js +6 -2
- package/dist/cli/commands/_atlas-route.js.map +1 -1
- package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
- package/dist/cli/commands/_discovery-opts.js +8 -9
- package/dist/cli/commands/_discovery-opts.js.map +1 -1
- package/dist/cli/commands/atlas.d.ts.map +1 -1
- package/dist/cli/commands/atlas.js +8 -5
- package/dist/cli/commands/atlas.js.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +8 -1
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/axes.d.ts.map +1 -1
- package/dist/cli/commands/axes.js +20 -1
- package/dist/cli/commands/axes.js.map +1 -1
- package/dist/cli/commands/confront.d.ts.map +1 -1
- package/dist/cli/commands/confront.js +8 -14
- package/dist/cli/commands/confront.js.map +1 -1
- package/dist/cli/commands/derive.d.ts.map +1 -1
- package/dist/cli/commands/derive.js +22 -22
- package/dist/cli/commands/derive.js.map +1 -1
- package/dist/cli/commands/discover.d.ts.map +1 -1
- package/dist/cli/commands/discover.js +6 -2
- package/dist/cli/commands/discover.js.map +1 -1
- package/dist/cli/commands/eval.d.ts.map +1 -1
- package/dist/cli/commands/eval.js +1 -0
- package/dist/cli/commands/eval.js.map +1 -1
- package/dist/cli/commands/evaluate.d.ts.map +1 -1
- package/dist/cli/commands/evaluate.js +65 -37
- package/dist/cli/commands/evaluate.js.map +1 -1
- package/dist/cli/commands/explain.d.ts.map +1 -1
- package/dist/cli/commands/explain.js +2 -1
- package/dist/cli/commands/explain.js.map +1 -1
- package/dist/cli/commands/ground.d.ts.map +1 -1
- package/dist/cli/commands/ground.js +1 -0
- package/dist/cli/commands/ground.js.map +1 -1
- package/dist/cli/commands/map.d.ts.map +1 -1
- package/dist/cli/commands/map.js +75 -5
- package/dist/cli/commands/map.js.map +1 -1
- package/dist/cli/commands/metric.d.ts.map +1 -1
- package/dist/cli/commands/metric.js +12 -9
- package/dist/cli/commands/metric.js.map +1 -1
- package/dist/cli/commands/path.d.ts +10 -0
- package/dist/cli/commands/path.d.ts.map +1 -1
- package/dist/cli/commands/path.js +25 -3
- package/dist/cli/commands/path.js.map +1 -1
- package/dist/cli/commands/probe.d.ts.map +1 -1
- package/dist/cli/commands/probe.js +59 -16
- package/dist/cli/commands/probe.js.map +1 -1
- package/dist/cli/commands/regime.d.ts.map +1 -1
- package/dist/cli/commands/regime.js +1 -0
- package/dist/cli/commands/regime.js.map +1 -1
- package/dist/cli/commands/retrieve.d.ts.map +1 -1
- package/dist/cli/commands/retrieve.js +1 -0
- package/dist/cli/commands/retrieve.js.map +1 -1
- package/dist/cli/commands/search.d.ts.map +1 -1
- package/dist/cli/commands/search.js +1 -0
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/symbolic.d.ts.map +1 -1
- package/dist/cli/commands/symbolic.js +19 -28
- package/dist/cli/commands/symbolic.js.map +1 -1
- package/dist/cli/commands/testplan.d.ts.map +1 -1
- package/dist/cli/commands/testplan.js +4 -2
- package/dist/cli/commands/testplan.js.map +1 -1
- package/dist/cli/expr-print.d.ts +0 -2
- package/dist/cli/expr-print.d.ts.map +1 -1
- package/dist/cli/expr-print.js +7 -31
- package/dist/cli/expr-print.js.map +1 -1
- package/dist/cli/main.d.ts +7 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +18 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/numeric-flag.d.ts +12 -0
- package/dist/cli/numeric-flag.d.ts.map +1 -0
- package/dist/cli/numeric-flag.js +44 -0
- package/dist/cli/numeric-flag.js.map +1 -0
- package/dist/cli/output.d.ts +20 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +15 -0
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/record-reach.js +2 -2
- package/dist/cli/record-reach.js.map +1 -1
- package/dist/cli/record-tables.d.ts.map +1 -1
- package/dist/cli/record-tables.js +6 -5
- package/dist/cli/record-tables.js.map +1 -1
- package/dist/cli/record.d.ts +1 -5
- package/dist/cli/record.d.ts.map +1 -1
- package/dist/cli/record.js +9 -8
- package/dist/cli/record.js.map +1 -1
- package/dist/cli/search-index.d.ts.map +1 -1
- package/dist/cli/search-index.js +7 -6
- package/dist/cli/search-index.js.map +1 -1
- package/dist/cli/statuses.d.ts +0 -2
- package/dist/cli/statuses.d.ts.map +1 -1
- package/dist/cli/statuses.js +0 -7
- package/dist/cli/statuses.js.map +1 -1
- package/dist/cli/stored-results.d.ts +7 -0
- package/dist/cli/stored-results.d.ts.map +1 -0
- package/dist/cli/stored-results.js +23 -0
- package/dist/cli/stored-results.js.map +1 -0
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +7 -5
- package/dist/cli/version.js.map +1 -1
- package/dist/cli-api.d.ts +34 -5
- package/dist/cli-api.d.ts.map +1 -1
- package/dist/cli-api.js +28 -4
- package/dist/cli-api.js.map +1 -1
- package/dist/composition/algebraic-equivalence.d.ts +43 -0
- package/dist/composition/algebraic-equivalence.d.ts.map +1 -0
- package/dist/composition/algebraic-equivalence.js +115 -0
- package/dist/composition/algebraic-equivalence.js.map +1 -0
- package/dist/composition/axes.d.ts +0 -6
- package/dist/composition/axes.d.ts.map +1 -1
- package/dist/composition/axes.js +6 -6
- package/dist/composition/axes.js.map +1 -1
- package/dist/composition/axis-audit.d.ts +47 -20
- package/dist/composition/axis-audit.d.ts.map +1 -1
- package/dist/composition/axis-audit.js +82 -9
- package/dist/composition/axis-audit.js.map +1 -1
- package/dist/composition/bridge-analysis.d.ts +17 -0
- package/dist/composition/bridge-analysis.d.ts.map +1 -1
- package/dist/composition/bridge-analysis.js +102 -55
- package/dist/composition/bridge-analysis.js.map +1 -1
- package/dist/composition/canonical-compare.d.ts +40 -0
- package/dist/composition/canonical-compare.d.ts.map +1 -1
- package/dist/composition/canonical-compare.js +122 -24
- package/dist/composition/canonical-compare.js.map +1 -1
- package/dist/composition/canonical-graph.d.ts +1 -1
- package/dist/composition/canonical-graph.d.ts.map +1 -1
- package/dist/composition/canonical-graph.js +9 -36
- package/dist/composition/canonical-graph.js.map +1 -1
- package/dist/composition/canonical-json.js +2 -2
- package/dist/composition/canonical-json.js.map +1 -1
- package/dist/composition/catalog-graph.d.ts.map +1 -1
- package/dist/composition/catalog-graph.js +2 -5
- package/dist/composition/catalog-graph.js.map +1 -1
- package/dist/composition/chain-candidate.d.ts +8 -0
- package/dist/composition/chain-candidate.d.ts.map +1 -1
- package/dist/composition/chain-candidate.js +9 -2
- package/dist/composition/chain-candidate.js.map +1 -1
- package/dist/composition/chain-match.d.ts +6 -3
- package/dist/composition/chain-match.d.ts.map +1 -1
- package/dist/composition/chain-match.js +4 -1
- package/dist/composition/chain-match.js.map +1 -1
- package/dist/composition/chain-result.d.ts.map +1 -1
- package/dist/composition/chain-result.js +2 -14
- package/dist/composition/chain-result.js.map +1 -1
- package/dist/composition/compose-symbolic.d.ts.map +1 -1
- package/dist/composition/compose-symbolic.js +3 -2
- package/dist/composition/compose-symbolic.js.map +1 -1
- package/dist/composition/compose.d.ts.map +1 -1
- package/dist/composition/compose.js +13 -5
- package/dist/composition/compose.js.map +1 -1
- package/dist/composition/composition-recovery.d.ts.map +1 -1
- package/dist/composition/composition-recovery.js +4 -7
- package/dist/composition/composition-recovery.js.map +1 -1
- package/dist/composition/discovery.d.ts +56 -0
- package/dist/composition/discovery.d.ts.map +1 -1
- package/dist/composition/discovery.js +114 -60
- package/dist/composition/discovery.js.map +1 -1
- package/dist/composition/edge.d.ts +21 -2
- package/dist/composition/edge.d.ts.map +1 -1
- package/dist/composition/edge.js +23 -1
- package/dist/composition/edge.js.map +1 -1
- package/dist/composition/enumerate.d.ts.map +1 -1
- package/dist/composition/enumerate.js +18 -3
- package/dist/composition/enumerate.js.map +1 -1
- package/dist/composition/evaluate-relation.d.ts +35 -11
- package/dist/composition/evaluate-relation.d.ts.map +1 -1
- package/dist/composition/evaluate-relation.js +60 -39
- package/dist/composition/evaluate-relation.js.map +1 -1
- package/dist/composition/explain.d.ts +3 -12
- package/dist/composition/explain.d.ts.map +1 -1
- package/dist/composition/explain.js +7 -20
- package/dist/composition/explain.js.map +1 -1
- package/dist/composition/expr-eval.d.ts.map +1 -1
- package/dist/composition/expr-eval.js +2 -11
- package/dist/composition/expr-eval.js.map +1 -1
- package/dist/composition/expr-simplify.d.ts +16 -0
- package/dist/composition/expr-simplify.d.ts.map +1 -1
- package/dist/composition/expr-simplify.js +15 -20
- package/dist/composition/expr-simplify.js.map +1 -1
- package/dist/composition/formula-shape.d.ts +23 -4
- package/dist/composition/formula-shape.d.ts.map +1 -1
- package/dist/composition/formula-shape.js +57 -17
- package/dist/composition/formula-shape.js.map +1 -1
- package/dist/composition/graph-structure.d.ts +98 -0
- package/dist/composition/graph-structure.d.ts.map +1 -0
- package/dist/composition/graph-structure.js +167 -0
- package/dist/composition/graph-structure.js.map +1 -0
- package/dist/composition/graph-viz-svg.d.ts.map +1 -1
- package/dist/composition/graph-viz-svg.js +1 -1
- package/dist/composition/graph-viz-svg.js.map +1 -1
- package/dist/composition/graph-viz.d.ts.map +1 -1
- package/dist/composition/graph-viz.js +8 -37
- package/dist/composition/graph-viz.js.map +1 -1
- package/dist/composition/identifiability.d.ts +91 -4
- package/dist/composition/identifiability.d.ts.map +1 -1
- package/dist/composition/identifiability.js +363 -6
- package/dist/composition/identifiability.js.map +1 -1
- package/dist/composition/index.d.ts +8 -4
- package/dist/composition/index.d.ts.map +1 -1
- package/dist/composition/index.js +3 -2
- package/dist/composition/index.js.map +1 -1
- package/dist/composition/mathts-quiet.d.ts +4 -3
- package/dist/composition/mathts-quiet.d.ts.map +1 -1
- package/dist/composition/mathts-quiet.js +4 -3
- package/dist/composition/mathts-quiet.js.map +1 -1
- package/dist/composition/mathts-scalar-symbols.d.ts.map +1 -1
- package/dist/composition/mathts-scalar-symbols.js +2 -1
- package/dist/composition/mathts-scalar-symbols.js.map +1 -1
- package/dist/composition/probe/corpus.d.ts +4 -2
- package/dist/composition/probe/corpus.d.ts.map +1 -1
- package/dist/composition/probe/corpus.js +20 -9
- package/dist/composition/probe/corpus.js.map +1 -1
- package/dist/composition/probe/dataset.d.ts +17 -0
- package/dist/composition/probe/dataset.d.ts.map +1 -1
- package/dist/composition/probe/dataset.js +95 -50
- package/dist/composition/probe/dataset.js.map +1 -1
- package/dist/composition/probe/experiment-design.d.ts +5 -1
- package/dist/composition/probe/experiment-design.d.ts.map +1 -1
- package/dist/composition/probe/experiment-design.js +44 -24
- package/dist/composition/probe/experiment-design.js.map +1 -1
- package/dist/composition/probe/falsify.d.ts.map +1 -1
- package/dist/composition/probe/falsify.js +2 -0
- package/dist/composition/probe/falsify.js.map +1 -1
- package/dist/composition/probe/fit.d.ts +6 -0
- package/dist/composition/probe/fit.d.ts.map +1 -1
- package/dist/composition/probe/fit.js +46 -22
- package/dist/composition/probe/fit.js.map +1 -1
- package/dist/composition/probe/frontier.d.ts.map +1 -1
- package/dist/composition/probe/frontier.js +33 -15
- package/dist/composition/probe/frontier.js.map +1 -1
- package/dist/composition/probe/generator.d.ts +27 -1
- package/dist/composition/probe/generator.d.ts.map +1 -1
- package/dist/composition/probe/generator.js +53 -30
- package/dist/composition/probe/generator.js.map +1 -1
- package/dist/composition/probe/index.d.ts +14 -0
- package/dist/composition/probe/index.d.ts.map +1 -1
- package/dist/composition/probe/index.js +6 -0
- package/dist/composition/probe/index.js.map +1 -1
- package/dist/composition/probe/limits.d.ts +24 -1
- package/dist/composition/probe/limits.d.ts.map +1 -1
- package/dist/composition/probe/limits.js +53 -11
- package/dist/composition/probe/limits.js.map +1 -1
- package/dist/composition/probe/pipeline.d.ts.map +1 -1
- package/dist/composition/probe/pipeline.js +10 -4
- package/dist/composition/probe/pipeline.js.map +1 -1
- package/dist/composition/probe/power-law.d.ts +121 -0
- package/dist/composition/probe/power-law.d.ts.map +1 -0
- package/dist/composition/probe/power-law.js +255 -0
- package/dist/composition/probe/power-law.js.map +1 -0
- package/dist/composition/probe/problem.d.ts +7 -4
- package/dist/composition/probe/problem.d.ts.map +1 -1
- package/dist/composition/probe/problem.js +177 -49
- package/dist/composition/probe/problem.js.map +1 -1
- package/dist/composition/probe/report.js +1 -1
- package/dist/composition/probe/report.js.map +1 -1
- package/dist/composition/probe/residual.d.ts +6 -1
- package/dist/composition/probe/residual.d.ts.map +1 -1
- package/dist/composition/probe/residual.js +9 -7
- package/dist/composition/probe/residual.js.map +1 -1
- package/dist/composition/probe/structure.d.ts +82 -17
- package/dist/composition/probe/structure.d.ts.map +1 -1
- package/dist/composition/probe/structure.js +129 -55
- package/dist/composition/probe/structure.js.map +1 -1
- package/dist/composition/probe/study.d.ts +31 -9
- package/dist/composition/probe/study.d.ts.map +1 -1
- package/dist/composition/probe/study.js +236 -181
- package/dist/composition/probe/study.js.map +1 -1
- package/dist/composition/probe/t-tail.d.ts +17 -0
- package/dist/composition/probe/t-tail.d.ts.map +1 -0
- package/dist/composition/probe/t-tail.js +32 -0
- package/dist/composition/probe/t-tail.js.map +1 -0
- package/dist/composition/probe/types.d.ts +3 -0
- package/dist/composition/probe/types.d.ts.map +1 -1
- package/dist/composition/probe/types.js.map +1 -1
- package/dist/composition/proposed-bridges.d.ts +41 -10
- package/dist/composition/proposed-bridges.d.ts.map +1 -1
- package/dist/composition/proposed-bridges.js +100 -55
- package/dist/composition/proposed-bridges.js.map +1 -1
- package/dist/composition/quantity-clusters.d.ts +48 -0
- package/dist/composition/quantity-clusters.d.ts.map +1 -0
- package/dist/composition/quantity-clusters.js +98 -0
- package/dist/composition/quantity-clusters.js.map +1 -0
- package/dist/composition/rational-exponent.d.ts +40 -0
- package/dist/composition/rational-exponent.d.ts.map +1 -0
- package/dist/composition/rational-exponent.js +65 -0
- package/dist/composition/rational-exponent.js.map +1 -0
- package/dist/composition/representative-values.d.ts +22 -0
- package/dist/composition/representative-values.d.ts.map +1 -1
- package/dist/composition/representative-values.js +23 -0
- package/dist/composition/representative-values.js.map +1 -1
- package/dist/composition/retrodiction.d.ts.map +1 -1
- package/dist/composition/retrodiction.js +2 -1
- package/dist/composition/retrodiction.js.map +1 -1
- package/dist/composition/user-equation.d.ts.map +1 -1
- package/dist/composition/user-equation.js +2 -2
- package/dist/composition/user-equation.js.map +1 -1
- package/dist/core/assignment.d.ts +19 -0
- package/dist/core/assignment.d.ts.map +1 -0
- package/dist/core/assignment.js +19 -0
- package/dist/core/assignment.js.map +1 -0
- package/dist/core/compare.d.ts +32 -0
- package/dist/core/compare.d.ts.map +1 -0
- package/dist/core/compare.js +46 -0
- package/dist/core/compare.js.map +1 -0
- package/dist/core/constants.d.ts +30 -30
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +47 -30
- package/dist/core/constants.js.map +1 -1
- package/dist/core/data-file.d.ts +7 -0
- package/dist/core/data-file.d.ts.map +1 -1
- package/dist/core/data-file.js +17 -0
- package/dist/core/data-file.js.map +1 -1
- package/dist/core/format.d.ts +36 -0
- package/dist/core/format.d.ts.map +1 -0
- package/dist/core/format.js +39 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/hash.d.ts +14 -0
- package/dist/core/hash.d.ts.map +1 -0
- package/dist/core/hash.js +17 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/json-schema.d.ts +2 -0
- package/dist/core/json-schema.d.ts.map +1 -1
- package/dist/core/json-schema.js +14 -13
- package/dist/core/json-schema.js.map +1 -1
- package/dist/core/labeled-tensor.d.ts.map +1 -1
- package/dist/core/labeled-tensor.js +0 -8
- package/dist/core/labeled-tensor.js.map +1 -1
- package/dist/core/mathts-read.d.ts +25 -0
- package/dist/core/mathts-read.d.ts.map +1 -0
- package/dist/core/mathts-read.js +51 -0
- package/dist/core/mathts-read.js.map +1 -0
- package/dist/core/tensor.d.ts.map +1 -1
- package/dist/core/tensor.js +24 -0
- package/dist/core/tensor.js.map +1 -1
- package/dist/core/types.d.ts +5 -5
- package/dist/diff/bridge-gradient.d.ts +19 -6
- package/dist/diff/bridge-gradient.d.ts.map +1 -1
- package/dist/diff/bridge-gradient.js +19 -11
- package/dist/diff/bridge-gradient.js.map +1 -1
- package/dist/diff/bridge-specs.d.ts.map +1 -1
- package/dist/diff/bridge-specs.js +3 -0
- package/dist/diff/bridge-specs.js.map +1 -1
- package/dist/dimensional/algebra.d.ts +18 -0
- package/dist/dimensional/algebra.d.ts.map +1 -1
- package/dist/dimensional/algebra.js +41 -1
- package/dist/dimensional/algebra.js.map +1 -1
- package/dist/dimensional/ast-builders.d.ts +7 -0
- package/dist/dimensional/ast-builders.d.ts.map +1 -1
- package/dist/dimensional/ast-builders.js +11 -0
- package/dist/dimensional/ast-builders.js.map +1 -1
- package/dist/dimensional/ast-leaves.d.ts +81 -0
- package/dist/dimensional/ast-leaves.d.ts.map +1 -0
- package/dist/dimensional/ast-leaves.js +146 -0
- package/dist/dimensional/ast-leaves.js.map +1 -0
- package/dist/dimensional/buckingham.d.ts.map +1 -1
- package/dist/dimensional/buckingham.js +15 -27
- package/dist/dimensional/buckingham.js.map +1 -1
- package/dist/dimensional/constant-rows.js +9 -9
- package/dist/dimensional/constant-rows.js.map +1 -1
- package/dist/dimensional/dimension-inference.d.ts.map +1 -1
- package/dist/dimensional/dimension-inference.js +1 -2
- package/dist/dimensional/dimension-inference.js.map +1 -1
- package/dist/dimensional/errors.d.ts +1 -1
- package/dist/dimensional/errors.d.ts.map +1 -1
- package/dist/dimensional/errors.js +1 -15
- package/dist/dimensional/errors.js.map +1 -1
- package/dist/dimensional/exact-scale.d.ts +0 -17
- package/dist/dimensional/exact-scale.d.ts.map +1 -1
- package/dist/dimensional/exact-scale.js +8 -8
- package/dist/dimensional/exact-scale.js.map +1 -1
- package/dist/dimensional/gauge-field.d.ts.map +1 -1
- package/dist/dimensional/gauge-field.js +2 -2
- package/dist/dimensional/gauge-field.js.map +1 -1
- package/dist/dimensional/hyphen-names.d.ts +12 -2
- package/dist/dimensional/hyphen-names.d.ts.map +1 -1
- package/dist/dimensional/hyphen-names.js +44 -19
- package/dist/dimensional/hyphen-names.js.map +1 -1
- package/dist/dimensional/metric.d.ts.map +1 -1
- package/dist/dimensional/metric.js +0 -1
- package/dist/dimensional/metric.js.map +1 -1
- package/dist/dimensional/symbolic-constants.d.ts +9 -0
- package/dist/dimensional/symbolic-constants.d.ts.map +1 -1
- package/dist/dimensional/symbolic-constants.js +13 -1
- package/dist/dimensional/symbolic-constants.js.map +1 -1
- package/dist/dimensional/types.d.ts +36 -0
- package/dist/dimensional/types.d.ts.map +1 -1
- package/dist/dimensional/types.js +45 -7
- package/dist/dimensional/types.js.map +1 -1
- package/dist/dimensional/unit-data.js +2 -2
- package/dist/dimensional/unit-data.js.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/numerical/christoffel-flat.d.ts.map +1 -1
- package/dist/numerical/christoffel-flat.js +3 -2
- package/dist/numerical/christoffel-flat.js.map +1 -1
- package/dist/numerical/covariant-eikonal.d.ts.map +1 -1
- package/dist/numerical/covariant-eikonal.js +34 -11
- package/dist/numerical/covariant-eikonal.js.map +1 -1
- package/dist/numerical/curvature-lowering-helpers.js +3 -2
- package/dist/numerical/curvature-lowering-helpers.js.map +1 -1
- package/dist/numerical/errors.d.ts.map +1 -1
- package/dist/numerical/errors.js +0 -3
- package/dist/numerical/errors.js.map +1 -1
- package/dist/numerical/finite-difference.d.ts +22 -0
- package/dist/numerical/finite-difference.d.ts.map +1 -0
- package/dist/numerical/finite-difference.js +27 -0
- package/dist/numerical/finite-difference.js.map +1 -0
- package/dist/numerical/geodesic-integrator.d.ts.map +1 -1
- package/dist/numerical/geodesic-integrator.js +22 -14
- package/dist/numerical/geodesic-integrator.js.map +1 -1
- package/dist/numerical/geometrized.d.ts.map +1 -1
- package/dist/numerical/geometrized.js +0 -1
- package/dist/numerical/geometrized.js.map +1 -1
- package/dist/numerical/mathts-engine.d.ts.map +1 -1
- package/dist/numerical/mathts-engine.js +10 -24
- package/dist/numerical/mathts-engine.js.map +1 -1
- package/dist/numerical/metric-inverse.d.ts.map +1 -1
- package/dist/numerical/metric-inverse.js +83 -46
- package/dist/numerical/metric-inverse.js.map +1 -1
- package/dist/numerical/null-ray-integrator.d.ts +2 -1
- package/dist/numerical/null-ray-integrator.d.ts.map +1 -1
- package/dist/numerical/null-ray-integrator.js +12 -12
- package/dist/numerical/null-ray-integrator.js.map +1 -1
- package/dist/numerical/painleve-gullstrand-metric.js +2 -2
- package/dist/numerical/painleve-gullstrand-metric.js.map +1 -1
- package/dist/numerical/perihelion-finder.d.ts +0 -36
- package/dist/numerical/perihelion-finder.d.ts.map +1 -1
- package/dist/numerical/perihelion-finder.js +41 -87
- package/dist/numerical/perihelion-finder.js.map +1 -1
- package/dist/numerical/quadrature.d.ts.map +1 -1
- package/dist/numerical/quadrature.js +8 -10
- package/dist/numerical/quadrature.js.map +1 -1
- package/dist/numerical/rk4-trajectory.d.ts +10 -0
- package/dist/numerical/rk4-trajectory.d.ts.map +1 -0
- package/dist/numerical/rk4-trajectory.js +37 -0
- package/dist/numerical/rk4-trajectory.js.map +1 -0
- package/dist/numerical/schwarzschild.d.ts +14 -0
- package/dist/numerical/schwarzschild.d.ts.map +1 -0
- package/dist/numerical/schwarzschild.js +17 -0
- package/dist/numerical/schwarzschild.js.map +1 -0
- package/dist/numerical/spacetime-metrics.d.ts +12 -0
- package/dist/numerical/spacetime-metrics.d.ts.map +1 -1
- package/dist/numerical/spacetime-metrics.js +72 -56
- package/dist/numerical/spacetime-metrics.js.map +1 -1
- package/dist/numerical/statistics.d.ts +24 -0
- package/dist/numerical/statistics.d.ts.map +1 -0
- package/dist/numerical/statistics.js +52 -0
- package/dist/numerical/statistics.js.map +1 -0
- package/dist/numerical/tensor-engine.d.ts +21 -0
- package/dist/numerical/tensor-engine.d.ts.map +1 -1
- package/dist/numerical/tensor-engine.js +12 -0
- package/dist/numerical/tensor-engine.js.map +1 -1
- package/dist/relations/regime.d.ts +10 -0
- package/dist/relations/regime.d.ts.map +1 -1
- package/dist/relations/regime.js +18 -1
- package/dist/relations/regime.js.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"algebra.js","sourceRoot":"","sources":["../../src/dimensional/algebra.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Dimensional algebra: per-base-exponent arithmetic.\n *\n * Operations follow standard dimensional analysis (Bridgman, \"Dimensional Analysis\", 1922):\n * - multiply: add exponents per base\n * - divide: subtract exponents per base\n * - power: scale exponents by the scalar `n`\n * - add/sub: permitted only when both operands have the same dimension\n *\n * @module dimensional/algebra\n */\n\nimport { Dimension, NAMED_DIMENSIONS } from './types.js';\nimport { DimensionMismatchError } from './errors.js';\n\n/**\n * Re-exported for callers that import the error from the algebra module.\n * The definition lives in `errors.ts`.\n *\n * @public\n */\nexport { DimensionMismatchError } from './errors.js';\n\nconst BASES = ['L', 'M', 'T', 'I', 'Theta', 'N', 'J'] as const;\ntype Base = typeof BASES[number];\n\n/** Product of two dimensions: exponents add per base. */\nexport function multiply(a: Dimension, b: Dimension): Dimension {\n const out = {} as Dimension;\n for (const base of BASES) {\n out[base as Base] = a[base as Base] + b[base as Base];\n }\n return out;\n}\n\n/** Quotient of two dimensions: exponents subtract per base. */\nexport function divide(a: Dimension, b: Dimension): Dimension {\n const out = {} as Dimension;\n for (const base of BASES) {\n out[base as Base] = a[base as Base] - b[base as Base];\n }\n return out;\n}\n\n/** Raise a dimension to a (possibly fractional) power: exponents scale by `n`. */\nexport function power(a: Dimension, n: number): Dimension {\n const out = {} as Dimension;\n for (const base of BASES) {\n out[base as Base] = a[base as Base] * n;\n }\n return out;\n}\n\n/**\n * Largest exponent difference still treated as equal. Physical dimension\n * exponents are integers or simple rationals (halves, thirds), so any genuine\n * distinction is ≥ ~1/3 — far above this tolerance, which only absorbs\n * floating-point round-off in fractional powers (v0.20 dimensionful `M^0.5`\n * reached by different op chains, e.g. 0.30000000000000004 vs 0.3).\n */\nexport const EXPONENT_TOL = 1e-9;\n\n/**\n * True iff two dimensions have equal exponents on every base, within\n * `EXPONENT_TOL` so floating-point round-off in fractional exponents does not\n * read as unequal.\n *\n * Unrolled over the 7 bases (no iterator / dynamic-key access) and\n * short-circuiting — `equals` is on the hot path (every `add`/`subtract`, and\n * `format`'s named-dimension scan calls it per entry). Stays distinct from\n * `linkage.ts`'s exact `dimEqual`: this one is tolerant by design (the v0.20\n * fractional-power round-off fix), so they are NOT the same predicate.\n */\nexport function equals(a: Dimension, b: Dimension): boolean {\n return (\n Math.abs(a.L - b.L) <= EXPONENT_TOL &&\n Math.abs(a.M - b.M) <= EXPONENT_TOL &&\n Math.abs(a.T - b.T) <= EXPONENT_TOL &&\n Math.abs(a.I - b.I) <= EXPONENT_TOL &&\n Math.abs(a.Theta - b.Theta) <= EXPONENT_TOL &&\n Math.abs(a.N - b.N) <= EXPONENT_TOL &&\n Math.abs(a.J - b.J) <= EXPONENT_TOL\n );\n}\n\n/** Dimensional sum: requires equal dimensions, else throws `DimensionMismatchError`. */\nexport function add(a: Dimension, b: Dimension): Dimension {\n if (!equals(a, b)) {\n throw new DimensionMismatchError(\n `Cannot add unlike dimensions: ${format(a)} + ${format(b)}`,\n a,\n b,\n );\n }\n return { ...a };\n}\n\n/** Dimensional difference: requires equal dimensions, else throws `DimensionMismatchError`. */\nexport function subtract(a: Dimension, b: Dimension): Dimension {\n if (!equals(a, b)) {\n throw new DimensionMismatchError(\n `Cannot subtract unlike dimensions: ${format(a)} - ${format(b)}`,\n a,\n b,\n );\n }\n return { ...a };\n}\n\n/**\n * Format a `Dimension` for human display.\n *\n * Strategy:\n * 1. If `d` matches a named SI dimension exactly, return e.g. \"[energy]\".\n * \"dimensionless\" is rendered as \"[1]\" for compactness.\n * 2. Otherwise emit the bracketed product form, e.g. \"[M L^2 T^-2]\".\n * Bases with exponent 0 are omitted; exponent 1 is written without \"^1\".\n */\nexport function format(d: Dimension): string {\n for (const [name, ref] of NAMED_DIMENSIONS) {\n if (equals(d, ref)) {\n if (name === 'dimensionless') return '[1]';\n return `[${name}]`;\n }\n }\n const parts: string[] = [];\n for (const base of BASES) {\n const exp = d[base as Base];\n if (exp === 0) continue;\n if (exp === 1) parts.push(base);\n else parts.push(`${base}^${exp}`);\n }\n if (parts.length === 0) return '[1]';\n return `[${parts.join(' ')}]`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"algebra.js","sourceRoot":"","sources":["../../src/dimensional/algebra.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Dimensional algebra: per-base-exponent arithmetic.\n *\n * Operations follow standard dimensional analysis (Bridgman, \"Dimensional Analysis\", 1922):\n * - multiply: add exponents per base\n * - divide: subtract exponents per base\n * - power: scale exponents by the scalar `n`\n * - add/sub: permitted only when both operands have the same dimension\n *\n * @module dimensional/algebra\n */\n\nimport { Dimension, NAMED_DIMENSIONS } from './types.js';\nimport { DimensionMismatchError } from './errors.js';\n\n/**\n * Re-exported for callers that import the error from the algebra module.\n * The definition lives in `errors.ts`.\n *\n * @public\n */\nexport { DimensionMismatchError } from './errors.js';\n\n/** The seven SI bases, in the order every exponent list is written. @internal */\nexport const BASES = ['L', 'M', 'T', 'I', 'Theta', 'N', 'J'] as const;\ntype Base = typeof BASES[number];\n\n/** Exact zero on every base; a base missing from a partial object reads as 0. @internal */\nexport function isDimensionless(d: Dimension): boolean {\n return BASES.every((base) => (d[base] ?? 0) === 0);\n}\n\n/**\n * Exact equality on every base, no tolerance: the predicate for exponents that\n * were never computed. {@link equals} is the tolerant one for exponents that\n * were (a fractional power reached by different op chains).\n * @internal\n */\nexport function exactlyEquals(a: Dimension, b: Dimension): boolean {\n return BASES.every((base) => (a[base] ?? 0) === (b[base] ?? 0));\n}\n\n/** Product of two dimensions: exponents add per base. */\nexport function multiply(a: Dimension, b: Dimension): Dimension {\n const out = {} as Dimension;\n for (const base of BASES) {\n out[base as Base] = a[base as Base] + b[base as Base];\n }\n return out;\n}\n\n/** Quotient of two dimensions: exponents subtract per base. */\nexport function divide(a: Dimension, b: Dimension): Dimension {\n const out = {} as Dimension;\n for (const base of BASES) {\n out[base as Base] = a[base as Base] - b[base as Base];\n }\n return out;\n}\n\n/** Raise a dimension to a (possibly fractional) power: exponents scale by `n`. */\nexport function power(a: Dimension, n: number): Dimension {\n const out = {} as Dimension;\n for (const base of BASES) {\n out[base as Base] = a[base as Base] * n;\n }\n return out;\n}\n\n/**\n * Largest exponent difference still treated as equal. Physical dimension\n * exponents are integers or simple rationals (halves, thirds), so any genuine\n * distinction is ≥ ~1/3 — far above this tolerance, which only absorbs\n * floating-point round-off in fractional powers (v0.20 dimensionful `M^0.5`\n * reached by different op chains, e.g. 0.30000000000000004 vs 0.3).\n */\nexport const EXPONENT_TOL = 1e-9;\n\n/**\n * True iff two dimensions have equal exponents on every base, within\n * `EXPONENT_TOL` so floating-point round-off in fractional exponents does not\n * read as unequal.\n *\n * Unrolled over the 7 bases (no iterator / dynamic-key access) and\n * short-circuiting — `equals` is on the hot path (every `add`/`subtract`, and\n * `format`'s named-dimension scan calls it per entry). Stays distinct from\n * `linkage.ts`'s exact `dimEqual`: this one is tolerant by design (the v0.20\n * fractional-power round-off fix), so they are NOT the same predicate.\n */\nexport function equals(a: Dimension, b: Dimension): boolean {\n return (\n Math.abs(a.L - b.L) <= EXPONENT_TOL &&\n Math.abs(a.M - b.M) <= EXPONENT_TOL &&\n Math.abs(a.T - b.T) <= EXPONENT_TOL &&\n Math.abs(a.I - b.I) <= EXPONENT_TOL &&\n Math.abs(a.Theta - b.Theta) <= EXPONENT_TOL &&\n Math.abs(a.N - b.N) <= EXPONENT_TOL &&\n Math.abs(a.J - b.J) <= EXPONENT_TOL\n );\n}\n\n/** Dimensional sum: requires equal dimensions, else throws `DimensionMismatchError`. */\nexport function add(a: Dimension, b: Dimension): Dimension {\n if (!equals(a, b)) {\n throw new DimensionMismatchError(\n `Cannot add unlike dimensions: ${format(a)} + ${format(b)}`,\n a,\n b,\n );\n }\n return { ...a };\n}\n\n/** Dimensional difference: requires equal dimensions, else throws `DimensionMismatchError`. */\nexport function subtract(a: Dimension, b: Dimension): Dimension {\n if (!equals(a, b)) {\n throw new DimensionMismatchError(\n `Cannot subtract unlike dimensions: ${format(a)} - ${format(b)}`,\n a,\n b,\n );\n }\n return { ...a };\n}\n\n/**\n * Format a `Dimension` for human display.\n *\n * Strategy:\n * 1. If `d` matches a named SI dimension exactly, return e.g. \"[energy]\".\n * \"dimensionless\" is rendered as \"[1]\" for compactness.\n * 2. Otherwise emit the bracketed product form, e.g. \"[M L^2 T^-2]\".\n * Bases with exponent 0 are omitted; exponent 1 is written without \"^1\".\n */\nexport function format(d: Dimension): string {\n for (const [name, ref] of NAMED_DIMENSIONS) {\n if (equals(d, ref)) {\n if (name === 'dimensionless') return '[1]';\n return `[${name}]`;\n }\n }\n const parts: string[] = [];\n for (const base of BASES) {\n const exp = d[base as Base];\n if (exp === 0) continue;\n if (exp === 1) parts.push(base);\n else parts.push(`${base}^${exp}`);\n }\n if (parts.length === 0) return '[1]';\n return `[${parts.join(' ')}]`;\n}\n\n/** Each base with its coherent SI unit, kilogram first (the order `siUnitOf` prints). @internal */\nexport const SI_BASE: readonly (readonly [keyof Dimension, string])[] = [\n ['M', 'kg'],\n ['L', 'm'],\n ['T', 's'],\n ['I', 'A'],\n ['Theta', 'K'],\n ['N', 'mol'],\n ['J', 'cd'],\n];\n\n/**\n * A dimension as SI base units, numerator before one `/` (`m^3/(kg*s^2)`), a bare denominator as\n * negative powers (`s^-1`), and `1` when dimensionless: the forms `parseUnit` reads back.\n */\nexport function siUnitOf(dim: Dimension): string {\n const factor = (u: string, e: number): string => (e === 1 ? u : `${u}^${e}`);\n const num = SI_BASE.filter(([k]) => dim[k] > 0).map(([k, u]) => factor(u, dim[k]));\n const den = SI_BASE.filter(([k]) => dim[k] < 0).map(([k, u]) => factor(u, -dim[k]));\n if (num.length === 0 && den.length === 0) return '1';\n if (num.length === 0) return SI_BASE.filter(([k]) => dim[k] < 0).map(([k, u]) => factor(u, dim[k])).join('*');\n if (den.length === 0) return num.join('*');\n return `${num.join('*')}/${den.length === 1 ? den[0] : `(${den.join('*')})`}`;\n}\n"]}
|
|
@@ -23,4 +23,11 @@ export declare function sym(name: string, dim: Dimension): ExprNode;
|
|
|
23
23
|
* are reachable from the one builder.
|
|
24
24
|
*/
|
|
25
25
|
export declare function dim(L?: number, M?: number, T?: number, I?: number, Theta?: number, N?: number, J?: number): Dimension;
|
|
26
|
+
/**
|
|
27
|
+
* `base ^ exponent`, with the exponent a dimensionless literal written `String(exponent)`;
|
|
28
|
+
* exponent 1 returns `base` itself. The factor both monomial builders share
|
|
29
|
+
* (`monomialToExpr` in composition/probe/generator.ts, `fromMonomial` in
|
|
30
|
+
* composition/proposed-bridges.ts), which arrange their factors differently.
|
|
31
|
+
*/
|
|
32
|
+
export declare function symbolPower(base: ExprNode, exponent: number): ExprNode;
|
|
26
33
|
//# sourceMappingURL=ast-builders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-builders.d.ts","sourceRoot":"","sources":["../../src/dimensional/ast-builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,mEAAmE;AACnE,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,GAAG,QAAQ,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAI,EAAE,CAAC,SAAI,EAAE,CAAC,SAAI,EAAE,CAAC,SAAI,EAAE,KAAK,SAAI,EAAE,CAAC,SAAI,EAAE,CAAC,SAAI,GAAG,SAAS,CAElF"}
|
|
1
|
+
{"version":3,"file":"ast-builders.d.ts","sourceRoot":"","sources":["../../src/dimensional/ast-builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,mEAAmE;AACnE,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,GAAG,QAAQ,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAI,EAAE,CAAC,SAAI,EAAE,CAAC,SAAI,EAAE,CAAC,SAAI,EAAE,KAAK,SAAI,EAAE,CAAC,SAAI,EAAE,CAAC,SAAI,GAAG,SAAS,CAElF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAGtE"}
|
|
@@ -25,4 +25,15 @@ export function sym(name, dim) {
|
|
|
25
25
|
export function dim(L = 0, M = 0, T = 0, I = 0, Theta = 0, N = 0, J = 0) {
|
|
26
26
|
return { L, M, T, I, Theta, N, J };
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* `base ^ exponent`, with the exponent a dimensionless literal written `String(exponent)`;
|
|
30
|
+
* exponent 1 returns `base` itself. The factor both monomial builders share
|
|
31
|
+
* (`monomialToExpr` in composition/probe/generator.ts, `fromMonomial` in
|
|
32
|
+
* composition/proposed-bridges.ts), which arrange their factors differently.
|
|
33
|
+
*/
|
|
34
|
+
export function symbolPower(base, exponent) {
|
|
35
|
+
if (exponent === 1)
|
|
36
|
+
return base;
|
|
37
|
+
return { kind: 'op', op: '^', args: [base, sym(String(exponent), dim())] };
|
|
38
|
+
}
|
|
28
39
|
//# sourceMappingURL=ast-builders.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-builders.js","sourceRoot":"","sources":["../../src/dimensional/ast-builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,mEAAmE;AACnE,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,GAAc;IAC9C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC;IACrE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACrC,CAAC","sourcesContent":["/**\n * Tiny pure builders for dimensional ASTs — `sym` (a symbol leaf) and `dim`\n * (a `Dimension` from its first five base exponents). These were copy-pasted\n * across the bridge-equation helpers, the canonical L1 builder, the\n * composition layer, and the formula transpiler; this module is their single\n * source of truth.\n *\n * Deliberately depends only on TYPES (`ExprNode`, `Dimension`), so it has no\n * runtime imports and can be imported from any layer without risking a cycle.\n * `_be-helpers` and `_l1-build` re-export `sym`/`dim` for their existing\n * importers, so most call sites are unchanged.\n *\n * @module dimensional/ast-builders\n */\n\nimport type { ExprNode } from './validator.js';\nimport type { Dimension } from './types.js';\n\n/** A symbol-leaf `ExprNode` carrying its name and SI dimension. */\nexport function sym(name: string, dim: Dimension): ExprNode {\n return { kind: 'symbol', name, dim };\n}\n\n/**\n * Build a `Dimension` from its base exponents. Arg order is\n * (L, M, T, **I**, **Θ**, N, J) — note I precedes Θ; every omitted exponent\n * is 0, so the amount-of-substance (N) and luminous-intensity (J) exponents\n * are reachable from the one builder.\n */\nexport function dim(L = 0, M = 0, T = 0, I = 0, Theta = 0, N = 0, J = 0): Dimension {\n return { L, M, T, I, Theta, N, J };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ast-builders.js","sourceRoot":"","sources":["../../src/dimensional/ast-builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,mEAAmE;AACnE,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,GAAc;IAC9C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC;IACrE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAc,EAAE,QAAgB;IAC1D,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;AAC7E,CAAC","sourcesContent":["/**\n * Tiny pure builders for dimensional ASTs — `sym` (a symbol leaf) and `dim`\n * (a `Dimension` from its first five base exponents). These were copy-pasted\n * across the bridge-equation helpers, the canonical L1 builder, the\n * composition layer, and the formula transpiler; this module is their single\n * source of truth.\n *\n * Deliberately depends only on TYPES (`ExprNode`, `Dimension`), so it has no\n * runtime imports and can be imported from any layer without risking a cycle.\n * `_be-helpers` and `_l1-build` re-export `sym`/`dim` for their existing\n * importers, so most call sites are unchanged.\n *\n * @module dimensional/ast-builders\n */\n\nimport type { ExprNode } from './validator.js';\nimport type { Dimension } from './types.js';\n\n/** A symbol-leaf `ExprNode` carrying its name and SI dimension. */\nexport function sym(name: string, dim: Dimension): ExprNode {\n return { kind: 'symbol', name, dim };\n}\n\n/**\n * Build a `Dimension` from its base exponents. Arg order is\n * (L, M, T, **I**, **Θ**, N, J) — note I precedes Θ; every omitted exponent\n * is 0, so the amount-of-substance (N) and luminous-intensity (J) exponents\n * are reachable from the one builder.\n */\nexport function dim(L = 0, M = 0, T = 0, I = 0, Theta = 0, N = 0, J = 0): Dimension {\n return { L, M, T, I, Theta, N, J };\n}\n\n/**\n * `base ^ exponent`, with the exponent a dimensionless literal written `String(exponent)`;\n * exponent 1 returns `base` itself. The factor both monomial builders share\n * (`monomialToExpr` in composition/probe/generator.ts, `fromMonomial` in\n * composition/proposed-bridges.ts), which arrange their factors differently.\n */\nexport function symbolPower(base: ExprNode, exponent: number): ExprNode {\n if (exponent === 1) return base;\n return { kind: 'op', op: '^', args: [base, sym(String(exponent), dim())] };\n}\n"]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One owner for the scalar-leaf walk of an `ExprNode` and the literal rule.
|
|
3
|
+
*
|
|
4
|
+
* Thirteen walks over the leaves and six spellings of "is this name a number"
|
|
5
|
+
* once lived in the funnel, the probe and the canonical layer, and they
|
|
6
|
+
* disagreed on the edges: one accepted `0x2`, one rejected `1e3`, and several
|
|
7
|
+
* accepted the empty string (`Number('')` is `0`). The rule here is the
|
|
8
|
+
* validator's decimal-literal grammar, so a formula is read the same way
|
|
9
|
+
* everywhere it is read.
|
|
10
|
+
*
|
|
11
|
+
* The walker descends into `op` arguments always. Every other arm is opted
|
|
12
|
+
* into by the caller through {@link LeafWalkArms}, because the callers it
|
|
13
|
+
* replaced did not agree on which arms they walked (the evaluator reads
|
|
14
|
+
* `transcendental` and `abs`; the simplifier reads an integral's measure and
|
|
15
|
+
* integrand but not its bounds), and the behaviour of each is kept by passing
|
|
16
|
+
* its own set.
|
|
17
|
+
*
|
|
18
|
+
* @module dimensional/ast-leaves
|
|
19
|
+
*/
|
|
20
|
+
import type { ExprNode } from './ast-types.js';
|
|
21
|
+
/** A scalar leaf: a symbol with its dimension. @internal */
|
|
22
|
+
export type ScalarLeaf = Extract<ExprNode, {
|
|
23
|
+
kind: 'symbol';
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* The decimal-literal grammar: an optional sign, digits with an optional
|
|
27
|
+
* fraction (or a bare fraction), and an optional exponent. `1e3` and `2.` are
|
|
28
|
+
* literals; `0x2`, `Infinity` and the empty string are not. This is the
|
|
29
|
+
* validator's rule for a literal exponent.
|
|
30
|
+
*
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export declare const DECIMAL_LITERAL: RegExp;
|
|
34
|
+
/** True when `name` is a decimal literal under {@link DECIMAL_LITERAL}. @internal */
|
|
35
|
+
export declare function isDecimalLiteral(name: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The number a decimal-literal symbol names, or `undefined` for any other
|
|
38
|
+
* node. The dimension stored on the symbol is not read: a caller that needs
|
|
39
|
+
* the literal to be dimensionless checks that itself.
|
|
40
|
+
*
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export declare function literalValue(node: ExprNode): number | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Which non-`op` arms a walk descends into. `op` arguments are always walked.
|
|
46
|
+
* An arm left out is not entered, and its leaves are not visited.
|
|
47
|
+
*
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
export interface LeafWalkArms {
|
|
51
|
+
/** `exp`, `ln`, the trigonometric functions: their argument. */
|
|
52
|
+
readonly transcendental?: boolean;
|
|
53
|
+
/** `abs`: its argument. */
|
|
54
|
+
readonly abs?: boolean;
|
|
55
|
+
/** `dirac-delta`: its argument. */
|
|
56
|
+
readonly diracDelta?: boolean;
|
|
57
|
+
/** `integral`: the measure and the integrand, or those and both bounds. */
|
|
58
|
+
readonly integral?: 'over+integrand' | 'all';
|
|
59
|
+
/** `derivative`: `of` and `wrt`. */
|
|
60
|
+
readonly derivative?: boolean;
|
|
61
|
+
/** `variational-derivative`: the functional, the field and the measure. */
|
|
62
|
+
readonly variationalDerivative?: boolean;
|
|
63
|
+
/** `tensor-product`: its arguments. */
|
|
64
|
+
readonly tensorProduct?: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Visit every scalar leaf of `node` reachable through `op` arguments and the
|
|
68
|
+
* arms in `arms`, in source order. A leaf is visited once per occurrence.
|
|
69
|
+
*
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
export declare function forEachScalarLeaf(node: ExprNode, visit: (leaf: ScalarLeaf) => void, arms: LeafWalkArms): void;
|
|
73
|
+
/**
|
|
74
|
+
* Replace each scalar leaf reachable under `arms` by `f(leaf)`. A subtree in
|
|
75
|
+
* which no leaf changed is returned by reference, so an arm the walk did not
|
|
76
|
+
* enter, and an unchanged tree, are the same objects the caller passed.
|
|
77
|
+
*
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
export declare function mapScalarLeaves(node: ExprNode, f: (leaf: ScalarLeaf) => ExprNode, arms: LeafWalkArms): ExprNode;
|
|
81
|
+
//# sourceMappingURL=ast-leaves.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-leaves.d.ts","sourceRoot":"","sources":["../../src/dimensional/ast-leaves.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,4DAA4D;AAC5D,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAE/D;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,QAAgD,CAAC;AAE7E,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAG/D;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,2BAA2B;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,mCAAmC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC;IAC7C,oCAAoC;IACpC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,2EAA2E;IAC3E,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,uCAAuC;IACvC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAiCD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,EACjC,IAAI,EAAE,YAAY,GACjB,IAAI,CAMN;AAmCD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,QAAQ,EACjC,IAAI,EAAE,YAAY,GACjB,QAAQ,CAWV"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One owner for the scalar-leaf walk of an `ExprNode` and the literal rule.
|
|
3
|
+
*
|
|
4
|
+
* Thirteen walks over the leaves and six spellings of "is this name a number"
|
|
5
|
+
* once lived in the funnel, the probe and the canonical layer, and they
|
|
6
|
+
* disagreed on the edges: one accepted `0x2`, one rejected `1e3`, and several
|
|
7
|
+
* accepted the empty string (`Number('')` is `0`). The rule here is the
|
|
8
|
+
* validator's decimal-literal grammar, so a formula is read the same way
|
|
9
|
+
* everywhere it is read.
|
|
10
|
+
*
|
|
11
|
+
* The walker descends into `op` arguments always. Every other arm is opted
|
|
12
|
+
* into by the caller through {@link LeafWalkArms}, because the callers it
|
|
13
|
+
* replaced did not agree on which arms they walked (the evaluator reads
|
|
14
|
+
* `transcendental` and `abs`; the simplifier reads an integral's measure and
|
|
15
|
+
* integrand but not its bounds), and the behaviour of each is kept by passing
|
|
16
|
+
* its own set.
|
|
17
|
+
*
|
|
18
|
+
* @module dimensional/ast-leaves
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* The decimal-literal grammar: an optional sign, digits with an optional
|
|
22
|
+
* fraction (or a bare fraction), and an optional exponent. `1e3` and `2.` are
|
|
23
|
+
* literals; `0x2`, `Infinity` and the empty string are not. This is the
|
|
24
|
+
* validator's rule for a literal exponent.
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export const DECIMAL_LITERAL = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
29
|
+
/** True when `name` is a decimal literal under {@link DECIMAL_LITERAL}. @internal */
|
|
30
|
+
export function isDecimalLiteral(name) {
|
|
31
|
+
return DECIMAL_LITERAL.test(name);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The number a decimal-literal symbol names, or `undefined` for any other
|
|
35
|
+
* node. The dimension stored on the symbol is not read: a caller that needs
|
|
36
|
+
* the literal to be dimensionless checks that itself.
|
|
37
|
+
*
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export function literalValue(node) {
|
|
41
|
+
if (node.kind !== 'symbol' || !isDecimalLiteral(node.name))
|
|
42
|
+
return undefined;
|
|
43
|
+
return Number(node.name);
|
|
44
|
+
}
|
|
45
|
+
/** The children a walk enters under `arms`, in source order. */
|
|
46
|
+
function walkedChildren(node, arms) {
|
|
47
|
+
switch (node.kind) {
|
|
48
|
+
case 'op':
|
|
49
|
+
return node.args;
|
|
50
|
+
case 'transcendental':
|
|
51
|
+
return arms.transcendental ? [node.arg] : [];
|
|
52
|
+
case 'abs':
|
|
53
|
+
return arms.abs ? [node.arg] : [];
|
|
54
|
+
case 'dirac-delta':
|
|
55
|
+
return arms.diracDelta ? [node.arg] : [];
|
|
56
|
+
case 'integral':
|
|
57
|
+
if (arms.integral === undefined)
|
|
58
|
+
return [];
|
|
59
|
+
if (arms.integral === 'over+integrand')
|
|
60
|
+
return [node.over, node.integrand];
|
|
61
|
+
return [
|
|
62
|
+
node.over,
|
|
63
|
+
node.integrand,
|
|
64
|
+
...(node.lower === undefined ? [] : [node.lower]),
|
|
65
|
+
...(node.upper === undefined ? [] : [node.upper]),
|
|
66
|
+
];
|
|
67
|
+
case 'derivative':
|
|
68
|
+
return arms.derivative ? [node.of, node.wrt] : [];
|
|
69
|
+
case 'variational-derivative':
|
|
70
|
+
return arms.variationalDerivative ? [node.functional, node.field, node.over] : [];
|
|
71
|
+
case 'tensor-product':
|
|
72
|
+
return arms.tensorProduct ? node.args : [];
|
|
73
|
+
default:
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Visit every scalar leaf of `node` reachable through `op` arguments and the
|
|
79
|
+
* arms in `arms`, in source order. A leaf is visited once per occurrence.
|
|
80
|
+
*
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
export function forEachScalarLeaf(node, visit, arms) {
|
|
84
|
+
if (node.kind === 'symbol') {
|
|
85
|
+
visit(node);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
for (const child of walkedChildren(node, arms))
|
|
89
|
+
forEachScalarLeaf(child, visit, arms);
|
|
90
|
+
}
|
|
91
|
+
/** Rebuild `node` with the walked children replaced, keeping the node when none changed. */
|
|
92
|
+
function rebuild(node, arms, children) {
|
|
93
|
+
switch (node.kind) {
|
|
94
|
+
case 'op':
|
|
95
|
+
return { ...node, args: [...children] };
|
|
96
|
+
case 'transcendental':
|
|
97
|
+
case 'abs':
|
|
98
|
+
case 'dirac-delta':
|
|
99
|
+
return { ...node, arg: children[0] };
|
|
100
|
+
case 'integral': {
|
|
101
|
+
if (arms.integral === 'over+integrand')
|
|
102
|
+
return { ...node, over: children[0], integrand: children[1] };
|
|
103
|
+
let i = 2;
|
|
104
|
+
const lower = node.lower === undefined ? undefined : children[i++];
|
|
105
|
+
const upper = node.upper === undefined ? undefined : children[i++];
|
|
106
|
+
return {
|
|
107
|
+
...node,
|
|
108
|
+
over: children[0],
|
|
109
|
+
integrand: children[1],
|
|
110
|
+
...(lower === undefined ? {} : { lower }),
|
|
111
|
+
...(upper === undefined ? {} : { upper }),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
case 'derivative':
|
|
115
|
+
return { ...node, of: children[0], wrt: children[1] };
|
|
116
|
+
case 'variational-derivative':
|
|
117
|
+
return { ...node, functional: children[0], field: children[1], over: children[2] };
|
|
118
|
+
case 'tensor-product':
|
|
119
|
+
return { ...node, args: [...children] };
|
|
120
|
+
default:
|
|
121
|
+
return node;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Replace each scalar leaf reachable under `arms` by `f(leaf)`. A subtree in
|
|
126
|
+
* which no leaf changed is returned by reference, so an arm the walk did not
|
|
127
|
+
* enter, and an unchanged tree, are the same objects the caller passed.
|
|
128
|
+
*
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
export function mapScalarLeaves(node, f, arms) {
|
|
132
|
+
if (node.kind === 'symbol')
|
|
133
|
+
return f(node);
|
|
134
|
+
const children = walkedChildren(node, arms);
|
|
135
|
+
if (children.length === 0)
|
|
136
|
+
return node;
|
|
137
|
+
let changed = false;
|
|
138
|
+
const mapped = children.map((child) => {
|
|
139
|
+
const next = mapScalarLeaves(child, f, arms);
|
|
140
|
+
if (next !== child)
|
|
141
|
+
changed = true;
|
|
142
|
+
return next;
|
|
143
|
+
});
|
|
144
|
+
return changed ? rebuild(node, arms, mapped) : node;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=ast-leaves.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-leaves.js","sourceRoot":"","sources":["../../src/dimensional/ast-leaves.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One owner for the scalar-leaf walk of an `ExprNode` and the literal rule.\n *\n * Thirteen walks over the leaves and six spellings of \"is this name a number\"\n * once lived in the funnel, the probe and the canonical layer, and they\n * disagreed on the edges: one accepted `0x2`, one rejected `1e3`, and several\n * accepted the empty string (`Number('')` is `0`). The rule here is the\n * validator's decimal-literal grammar, so a formula is read the same way\n * everywhere it is read.\n *\n * The walker descends into `op` arguments always. Every other arm is opted\n * into by the caller through {@link LeafWalkArms}, because the callers it\n * replaced did not agree on which arms they walked (the evaluator reads\n * `transcendental` and `abs`; the simplifier reads an integral's measure and\n * integrand but not its bounds), and the behaviour of each is kept by passing\n * its own set.\n *\n * @module dimensional/ast-leaves\n */\n\nimport type { ExprNode } from './ast-types.js';\n\n/** A scalar leaf: a symbol with its dimension. @internal */\nexport type ScalarLeaf = Extract<ExprNode, { kind: 'symbol' }>;\n\n/**\n * The decimal-literal grammar: an optional sign, digits with an optional\n * fraction (or a bare fraction), and an optional exponent. `1e3` and `2.` are\n * literals; `0x2`, `Infinity` and the empty string are not. This is the\n * validator's rule for a literal exponent.\n *\n * @internal\n */\nexport const DECIMAL_LITERAL = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?$/;\n\n/** True when `name` is a decimal literal under {@link DECIMAL_LITERAL}. @internal */\nexport function isDecimalLiteral(name: string): boolean {\n return DECIMAL_LITERAL.test(name);\n}\n\n/**\n * The number a decimal-literal symbol names, or `undefined` for any other\n * node. The dimension stored on the symbol is not read: a caller that needs\n * the literal to be dimensionless checks that itself.\n *\n * @internal\n */\nexport function literalValue(node: ExprNode): number | undefined {\n if (node.kind !== 'symbol' || !isDecimalLiteral(node.name)) return undefined;\n return Number(node.name);\n}\n\n/**\n * Which non-`op` arms a walk descends into. `op` arguments are always walked.\n * An arm left out is not entered, and its leaves are not visited.\n *\n * @internal\n */\nexport interface LeafWalkArms {\n /** `exp`, `ln`, the trigonometric functions: their argument. */\n readonly transcendental?: boolean;\n /** `abs`: its argument. */\n readonly abs?: boolean;\n /** `dirac-delta`: its argument. */\n readonly diracDelta?: boolean;\n /** `integral`: the measure and the integrand, or those and both bounds. */\n readonly integral?: 'over+integrand' | 'all';\n /** `derivative`: `of` and `wrt`. */\n readonly derivative?: boolean;\n /** `variational-derivative`: the functional, the field and the measure. */\n readonly variationalDerivative?: boolean;\n /** `tensor-product`: its arguments. */\n readonly tensorProduct?: boolean;\n}\n\n/** The children a walk enters under `arms`, in source order. */\nfunction walkedChildren(node: ExprNode, arms: LeafWalkArms): readonly ExprNode[] {\n switch (node.kind) {\n case 'op':\n return node.args;\n case 'transcendental':\n return arms.transcendental ? [node.arg] : [];\n case 'abs':\n return arms.abs ? [node.arg] : [];\n case 'dirac-delta':\n return arms.diracDelta ? [node.arg] : [];\n case 'integral':\n if (arms.integral === undefined) return [];\n if (arms.integral === 'over+integrand') return [node.over, node.integrand];\n return [\n node.over,\n node.integrand,\n ...(node.lower === undefined ? [] : [node.lower]),\n ...(node.upper === undefined ? [] : [node.upper]),\n ];\n case 'derivative':\n return arms.derivative ? [node.of, node.wrt] : [];\n case 'variational-derivative':\n return arms.variationalDerivative ? [node.functional, node.field, node.over] : [];\n case 'tensor-product':\n return arms.tensorProduct ? node.args : [];\n default:\n return [];\n }\n}\n\n/**\n * Visit every scalar leaf of `node` reachable through `op` arguments and the\n * arms in `arms`, in source order. A leaf is visited once per occurrence.\n *\n * @internal\n */\nexport function forEachScalarLeaf(\n node: ExprNode,\n visit: (leaf: ScalarLeaf) => void,\n arms: LeafWalkArms,\n): void {\n if (node.kind === 'symbol') {\n visit(node);\n return;\n }\n for (const child of walkedChildren(node, arms)) forEachScalarLeaf(child, visit, arms);\n}\n\n/** Rebuild `node` with the walked children replaced, keeping the node when none changed. */\nfunction rebuild(node: ExprNode, arms: LeafWalkArms, children: readonly ExprNode[]): ExprNode {\n switch (node.kind) {\n case 'op':\n return { ...node, args: [...children] };\n case 'transcendental':\n case 'abs':\n case 'dirac-delta':\n return { ...node, arg: children[0]! };\n case 'integral': {\n if (arms.integral === 'over+integrand') return { ...node, over: children[0]!, integrand: children[1]! };\n let i = 2;\n const lower = node.lower === undefined ? undefined : children[i++];\n const upper = node.upper === undefined ? undefined : children[i++];\n return {\n ...node,\n over: children[0]!,\n integrand: children[1]!,\n ...(lower === undefined ? {} : { lower }),\n ...(upper === undefined ? {} : { upper }),\n };\n }\n case 'derivative':\n return { ...node, of: children[0]!, wrt: children[1]! };\n case 'variational-derivative':\n return { ...node, functional: children[0]!, field: children[1]!, over: children[2]! };\n case 'tensor-product':\n return { ...node, args: [...children] };\n default:\n return node;\n }\n}\n\n/**\n * Replace each scalar leaf reachable under `arms` by `f(leaf)`. A subtree in\n * which no leaf changed is returned by reference, so an arm the walk did not\n * enter, and an unchanged tree, are the same objects the caller passed.\n *\n * @internal\n */\nexport function mapScalarLeaves(\n node: ExprNode,\n f: (leaf: ScalarLeaf) => ExprNode,\n arms: LeafWalkArms,\n): ExprNode {\n if (node.kind === 'symbol') return f(node);\n const children = walkedChildren(node, arms);\n if (children.length === 0) return node;\n let changed = false;\n const mapped = children.map((child) => {\n const next = mapScalarLeaves(child, f, arms);\n if (next !== child) changed = true;\n return next;\n });\n return changed ? rebuild(node, arms, mapped) : node;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buckingham.d.ts","sourceRoot":"","sources":["../../src/dimensional/buckingham.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"buckingham.d.ts","sourceRoot":"","sources":["../../src/dimensional/buckingham.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C;kEACkE;AAClE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;CACzB;AAED;;6BAE6B;AAC7B,MAAM,WAAW,OAAO;IACtB,uEAAuE;IACvE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,yDAAyD;AACzD,MAAM,MAAM,iBAAiB,GACzB,2BAA2B,GAC3B,kBAAkB,GAClB,qBAAqB,CAAC;AAE1B,8CAA8C;AAC9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,yDAAyD;IACzD,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,mCAAmC;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;CACrC;AAED,yDAAyD;AACzD,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC;oDACgD;IAChD,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,oEAAoE;IACpE,QAAQ,CAAC,yBAAyB,CAAC,EAAE,IAAI,CAAC;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;cACc;AACd,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AA+ED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,SAAS,mBAAmB,EAAE,GACxC,gBAAgB,CAsClB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,SAAS,mBAAmB,EAAE,GACxC,8BAA8B,CAmEhC"}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
*/
|
|
27
27
|
import { Fraction } from '@danielsimonjr/mathts-core';
|
|
28
28
|
import { rationalNullspace } from '@danielsimonjr/mathts-functions';
|
|
29
|
-
|
|
29
|
+
import { BASES } from './algebra.js';
|
|
30
30
|
/** Rationalization failed: a dimension exponent is not a small rational.
|
|
31
31
|
* @public */
|
|
32
32
|
export class RationalizationError extends Error {
|
|
@@ -35,39 +35,28 @@ export class RationalizationError extends Error {
|
|
|
35
35
|
this.name = 'RationalizationError';
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
[a, b] = [b, a % b];
|
|
43
|
-
}
|
|
44
|
-
return a || 1;
|
|
45
|
-
}
|
|
46
|
-
function frac(n, d) {
|
|
47
|
-
if (d === 0)
|
|
48
|
-
throw new RationalizationError('zero denominator');
|
|
49
|
-
if (d < 0) {
|
|
50
|
-
n = -n;
|
|
51
|
-
d = -d;
|
|
52
|
-
}
|
|
53
|
-
const g = gcd(n, d);
|
|
54
|
-
return { n: n / g, d: d / g };
|
|
55
|
-
}
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Exact rational arithmetic: MathTS core `Fraction` (bigint-backed, reduced by
|
|
40
|
+
// its constructor). Dimension exponents are small rationals.
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
56
42
|
const MAX_DEN = 720;
|
|
57
|
-
/**
|
|
58
|
-
*
|
|
43
|
+
/**
|
|
44
|
+
* Convert a (possibly rational) exponent to an exact {@link Fraction} by
|
|
45
|
+
* scanning small denominators; throws if none matches within tolerance. The
|
|
46
|
+
* scan, not `Fraction.fromNumber`'s continued fraction, is what refuses an
|
|
47
|
+
* irrational exponent instead of approximating it.
|
|
48
|
+
*/
|
|
59
49
|
function toFrac(x) {
|
|
60
50
|
if (Number.isInteger(x))
|
|
61
|
-
return
|
|
51
|
+
return new Fraction(x, 1);
|
|
62
52
|
for (let d = 2; d <= MAX_DEN; d++) {
|
|
63
53
|
const n = x * d;
|
|
64
54
|
if (Math.abs(n - Math.round(n)) < 1e-9 * Math.max(1, Math.abs(n))) {
|
|
65
|
-
return
|
|
55
|
+
return new Fraction(Math.round(n), d);
|
|
66
56
|
}
|
|
67
57
|
}
|
|
68
58
|
throw new RationalizationError(`dimension exponent ${x} is not a rational with denominator ≤ ${MAX_DEN}`);
|
|
69
59
|
}
|
|
70
|
-
const fZero = (a) => a.n === 0;
|
|
71
60
|
/**
|
|
72
61
|
* Exact null space of the dimension matrix. Exponents pass through as
|
|
73
62
|
* {@link Fraction} values after {@link toFrac}, so an irrational is still
|
|
@@ -76,8 +65,7 @@ const fZero = (a) => a.n === 0;
|
|
|
76
65
|
* MathTS integerizes each vector (content 1, first nonzero entry positive).
|
|
77
66
|
*/
|
|
78
67
|
function nullSpace(matrix, cols) {
|
|
79
|
-
const
|
|
80
|
-
const solved = rationalNullspace(entries, { columns: cols });
|
|
68
|
+
const solved = rationalNullspace(matrix, { columns: cols });
|
|
81
69
|
const basis = solved.basis.map((vec) => vec.map((entry) => {
|
|
82
70
|
if (entry.denominator !== 1n) {
|
|
83
71
|
throw new RationalizationError(`null-space entry ${entry.toString()} is not an integer`);
|
|
@@ -91,7 +79,7 @@ function buildMatrix(variables) {
|
|
|
91
79
|
const matrix = [];
|
|
92
80
|
for (const base of BASES) {
|
|
93
81
|
const row = variables.map((v) => toFrac(v.dim[base]));
|
|
94
|
-
if (row.some((f) => !
|
|
82
|
+
if (row.some((f) => !f.isZero())) {
|
|
95
83
|
spannedBases.push(base);
|
|
96
84
|
matrix.push(row);
|
|
97
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buckingham.js","sourceRoot":"","sources":["../../src/dimensional/buckingham.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Buckingham-π enumerator (build target 1 of\n * docs/planning/Bridge-Inference-Epistemics-Note.md — the principled\n * primitive for the classifier's EXACTLY-DETERMINED case).\n *\n * Given a set of dimensional variables presumed to obey one\n * dimensionally-homogeneous relation, the Buckingham-π theorem says that\n * relation re-expresses as F(π₁,…,π_{n−r}) = 0, where each πᵢ is a\n * dimensionless power-product of the variables and there are exactly\n * n − r of them (n = variables, r = rank of the dimension matrix). The\n * π-groups are a basis of the NULL SPACE of the dimension matrix.\n *\n * THE HONEST BOUNDARY (enforced by the result types — there is no value\n * or constant field anywhere): this returns the FORM only. It yields the\n * π-groups and, for a target, the monomial that determines it UP TO A\n * DIMENSIONLESS CONSTANT (the 2π, the ½, α). It does NOT and cannot\n * supply that constant, nor the function F. That boundary is exactly what\n * separates dimensional analysis from numerology — see the epistemics\n * note.\n *\n * Computation is EXACT (rational arithmetic), not floating Gaussian\n * elimination: physics dimension exponents are small rationals, and the\n * null-space basis must be exact to be trustworthy.\n *\n * @module dimensional/buckingham\n */\n\nimport { Fraction } from '@danielsimonjr/mathts-core';\nimport { rationalNullspace } from '@danielsimonjr/mathts-functions';\nimport type { Dimension } from './types.js';\n\nconst BASES = ['L', 'M', 'T', 'I', 'Theta', 'N', 'J'] as const;\n\n/** A named physical quantity with a dimension — the enumerator's input.\n * Structurally satisfied by a composition `Quantity`. @public */\nexport interface DimensionalVariable {\n readonly name: string;\n readonly dim: Dimension;\n}\n\n/** A dimensionless power-product of the input variables (integer\n * exponents; the conventional form). No value — π-groups carry FORM,\n * not magnitude. @public */\nexport interface PiGroup {\n /** Integer exponent of each variable in this dimensionless product. */\n readonly exponents: Readonly<Record<string, number>>;\n /** Display form, e.g. `period^2 · gravity · length^-1`. */\n readonly formula: string;\n}\n\n/** The dimensional closure of a variable set. @public */\nexport type BuckinghamVerdict =\n | 'dimensionally-independent' // 0 π-groups: no dimensionless product exists\n | 'single-invariant' // 1 π-group: one dimensionless invariant\n | 'multiple-invariants'; // ≥2 π-groups: a family F(π₁,…)\n\n/** Result of {@link buckinghamPi}. @public */\nexport interface BuckinghamResult {\n readonly variables: readonly string[];\n /** Base SI dimensions actually spanned by the inputs. */\n readonly baseDimensions: readonly string[];\n /** n — the number of variables. */\n readonly variableCount: number;\n /** r — the rank of the dimension matrix. */\n readonly rank: number;\n /** n − r — the number of independent dimensionless groups. */\n readonly piGroupCount: number;\n readonly piGroups: readonly PiGroup[];\n readonly verdict: BuckinghamVerdict;\n}\n\n/** Result of {@link dimensionallyDetermines}. @public */\nexport interface DimensionalDeterminationResult {\n readonly target: string;\n readonly governing: readonly string[];\n /** True iff the target is fixed by the governing variables UP TO A\n * DIMENSIONLESS CONSTANT (unique monomial). */\n readonly determined: boolean;\n /**\n * When determined: target = const · Π(governingⱼ ^ monomial[j]). The\n * exponents may be rational (e.g. 0.5 for a √ law). Always read with\n * `upToDimensionlessConstant` — the leading constant is NOT supplied.\n */\n readonly monomial?: Readonly<Record<string, number>>;\n /** Always true when `monomial` is present — a standing reminder. */\n readonly upToDimensionlessConstant?: true;\n /**\n * True only when the target's dimension is not in the span of the governing\n * variables, so a monomial needs dimensionful constants the inputs do not\n * name. False when the governing variables are dimensionally dependent or\n * leave more than one π-group: that failure is not a missing constant.\n */\n readonly outsideGoverningSpan: boolean;\n /** Plain-language reason for the verdict. */\n readonly reason: string;\n}\n\n/** Rationalization failed: a dimension exponent is not a small rational.\n * @public */\nexport class RationalizationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'RationalizationError';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Exact rational arithmetic (number-backed; dimension exponents are small\n// rationals, so reduced fractions never overflow in practice).\n// ---------------------------------------------------------------------------\n\ninterface Frac {\n readonly n: number;\n readonly d: number;\n}\n\nfunction gcd(a: number, b: number): number {\n a = Math.abs(a);\n b = Math.abs(b);\n while (b) {\n [a, b] = [b, a % b];\n }\n return a || 1;\n}\n\nfunction frac(n: number, d: number): Frac {\n if (d === 0) throw new RationalizationError('zero denominator');\n if (d < 0) {\n n = -n;\n d = -d;\n }\n const g = gcd(n, d);\n return { n: n / g, d: d / g };\n}\n\nconst MAX_DEN = 720;\n\n/** Convert a (possibly rational) exponent to an exact fraction by scanning\n * small denominators; throws if none matches within tolerance. */\nfunction toFrac(x: number): Frac {\n if (Number.isInteger(x)) return { n: x, d: 1 };\n for (let d = 2; d <= MAX_DEN; d++) {\n const n = x * d;\n if (Math.abs(n - Math.round(n)) < 1e-9 * Math.max(1, Math.abs(n))) {\n return frac(Math.round(n), d);\n }\n }\n throw new RationalizationError(\n `dimension exponent ${x} is not a rational with denominator ≤ ${MAX_DEN}`,\n );\n}\n\nconst fZero = (a: Frac): boolean => a.n === 0;\n\n/**\n * Exact null space of the dimension matrix. Exponents pass through as\n * {@link Fraction} values after {@link toFrac}, so an irrational is still\n * {@link RationalizationError} and is not accepted by a continued fraction.\n * A matrix with no rows is `0×n`: `{ columns: n }` is the standard basis.\n * MathTS integerizes each vector (content 1, first nonzero entry positive).\n */\nfunction nullSpace(matrix: Frac[][], cols: number): { basis: number[][]; rank: number } {\n const entries = matrix.map((row) => row.map((f) => new Fraction(f.n, f.d)));\n const solved = rationalNullspace(entries, { columns: cols });\n const basis = solved.basis.map((vec) =>\n vec.map((entry) => {\n if (entry.denominator !== 1n) {\n throw new RationalizationError(\n `null-space entry ${entry.toString()} is not an integer`,\n );\n }\n return Number(entry.numerator);\n }),\n );\n return { basis, rank: solved.rank };\n}\n\nfunction buildMatrix(variables: readonly DimensionalVariable[]): {\n matrix: Frac[][];\n spannedBases: string[];\n} {\n const spannedBases: string[] = [];\n const matrix: Frac[][] = [];\n for (const base of BASES) {\n const row = variables.map((v) => toFrac(v.dim[base]));\n if (row.some((f) => !fZero(f))) {\n spannedBases.push(base);\n matrix.push(row);\n }\n }\n return { matrix, spannedBases };\n}\n\nfunction formatPiGroup(\n exponents: Record<string, number>,\n order: readonly string[],\n): string {\n const parts: string[] = [];\n for (const name of order) {\n const e = exponents[name];\n if (e === 0) continue;\n parts.push(e === 1 ? name : `${name}^${e}`);\n }\n return parts.join(' · ') || '1';\n}\n\n/**\n * Enumerate the Buckingham-π groups of a dimensional variable set. Returns\n * the rank, the count n − r, and a null-space basis of dimensionless\n * groups. FORM only — no constants (see module docs).\n *\n * @public\n */\nexport function buckinghamPi(\n variables: readonly DimensionalVariable[],\n): BuckinghamResult {\n if (variables.length === 0) {\n throw new RationalizationError('buckinghamPi requires at least one variable');\n }\n const names = variables.map((v) => v.name);\n if (new Set(names).size !== names.length) {\n throw new RationalizationError(\n `buckinghamPi requires unique variable names; got [${names.join(', ')}]`,\n );\n }\n\n const n = variables.length;\n const { matrix, spannedBases } = buildMatrix(variables);\n\n const { basis, rank } = nullSpace(matrix, n);\n const piGroups: PiGroup[] = basis.map((vec) => {\n const exponents: Record<string, number> = {};\n for (let j = 0; j < n; j++) exponents[names[j]] = vec[j];\n return { exponents, formula: formatPiGroup(exponents, names) };\n });\n\n const piGroupCount = n - rank;\n const verdict: BuckinghamVerdict =\n piGroupCount === 0\n ? 'dimensionally-independent'\n : piGroupCount === 1\n ? 'single-invariant'\n : 'multiple-invariants';\n\n return {\n variables: names,\n baseDimensions: spannedBases,\n variableCount: n,\n rank,\n piGroupCount,\n piGroups,\n verdict,\n };\n}\n\n/**\n * Does the governing set fix the target UP TO A DIMENSIONLESS CONSTANT?\n *\n * True iff the governing variables are dimensionally independent and the\n * target's dimension lies in their span — equivalently, the full set has\n * exactly one π-group and the governing set has none. When determined,\n * returns the (possibly rational) monomial exponents such that\n * target = const · Π(governingⱼ ^ monomial[j]). The constant is NOT\n * supplied — dimensional analysis cannot.\n *\n * @public\n */\nexport function dimensionallyDetermines(\n target: DimensionalVariable,\n governing: readonly DimensionalVariable[],\n): DimensionalDeterminationResult {\n const governingNames = governing.map((v) => v.name);\n\n const governingPi = buckinghamPi(\n governing.length > 0 ? governing : [target],\n );\n // A redundancy among the governing variables means the monomial is not\n // unique (any dimensionless governing combo can be folded into the\n // constant) → not determined.\n if (governing.length > 0 && governingPi.piGroupCount > 0) {\n return {\n target: target.name,\n governing: governingNames,\n determined: false,\n outsideGoverningSpan: false,\n reason:\n 'governing variables are dimensionally dependent ' +\n `(${governingPi.piGroupCount} dimensionless combination(s) among them); ` +\n 'the determining monomial is not unique',\n };\n }\n\n const full = buckinghamPi([target, ...governing]);\n if (full.piGroupCount !== 1) {\n return {\n target: target.name,\n governing: governingNames,\n determined: false,\n outsideGoverningSpan: full.piGroupCount === 0,\n reason:\n full.piGroupCount === 0\n ? \"the target's dimension is not in the span of the governing \" +\n 'variables — no dimensionless group exists, so no monomial determines it'\n : `${full.piGroupCount} independent π-groups — the target is fixed ` +\n 'only as a function of several dimensionless ratios (under-constrained)',\n };\n }\n\n // The single π-group involves the target; solve it for the target.\n const group = full.piGroups[0].exponents;\n const targetExp = group[target.name];\n if (!targetExp) {\n return {\n target: target.name,\n governing: governingNames,\n determined: false,\n outsideGoverningSpan: false,\n reason:\n 'the sole dimensionless group does not involve the target ' +\n '(the target is dimensionally redundant with the governing set)',\n };\n }\n const monomial: Record<string, number> = {};\n for (const name of governingNames) {\n monomial[name] = -(group[name] ?? 0) / targetExp;\n }\n\n return {\n target: target.name,\n governing: governingNames,\n determined: true,\n monomial,\n upToDimensionlessConstant: true,\n outsideGoverningSpan: false,\n reason:\n 'unique dimensionless group fixes the target up to a dimensionless constant',\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"buckingham.js","sourceRoot":"","sources":["../../src/dimensional/buckingham.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Buckingham-π enumerator (build target 1 of\n * docs/planning/Bridge-Inference-Epistemics-Note.md — the principled\n * primitive for the classifier's EXACTLY-DETERMINED case).\n *\n * Given a set of dimensional variables presumed to obey one\n * dimensionally-homogeneous relation, the Buckingham-π theorem says that\n * relation re-expresses as F(π₁,…,π_{n−r}) = 0, where each πᵢ is a\n * dimensionless power-product of the variables and there are exactly\n * n − r of them (n = variables, r = rank of the dimension matrix). The\n * π-groups are a basis of the NULL SPACE of the dimension matrix.\n *\n * THE HONEST BOUNDARY (enforced by the result types — there is no value\n * or constant field anywhere): this returns the FORM only. It yields the\n * π-groups and, for a target, the monomial that determines it UP TO A\n * DIMENSIONLESS CONSTANT (the 2π, the ½, α). It does NOT and cannot\n * supply that constant, nor the function F. That boundary is exactly what\n * separates dimensional analysis from numerology — see the epistemics\n * note.\n *\n * Computation is EXACT (rational arithmetic), not floating Gaussian\n * elimination: physics dimension exponents are small rationals, and the\n * null-space basis must be exact to be trustworthy.\n *\n * @module dimensional/buckingham\n */\n\nimport { Fraction } from '@danielsimonjr/mathts-core';\nimport { rationalNullspace } from '@danielsimonjr/mathts-functions';\nimport type { Dimension } from './types.js';\nimport { BASES } from './algebra.js';\n\n/** A named physical quantity with a dimension — the enumerator's input.\n * Structurally satisfied by a composition `Quantity`. @public */\nexport interface DimensionalVariable {\n readonly name: string;\n readonly dim: Dimension;\n}\n\n/** A dimensionless power-product of the input variables (integer\n * exponents; the conventional form). No value — π-groups carry FORM,\n * not magnitude. @public */\nexport interface PiGroup {\n /** Integer exponent of each variable in this dimensionless product. */\n readonly exponents: Readonly<Record<string, number>>;\n /** Display form, e.g. `period^2 · gravity · length^-1`. */\n readonly formula: string;\n}\n\n/** The dimensional closure of a variable set. @public */\nexport type BuckinghamVerdict =\n | 'dimensionally-independent' // 0 π-groups: no dimensionless product exists\n | 'single-invariant' // 1 π-group: one dimensionless invariant\n | 'multiple-invariants'; // ≥2 π-groups: a family F(π₁,…)\n\n/** Result of {@link buckinghamPi}. @public */\nexport interface BuckinghamResult {\n readonly variables: readonly string[];\n /** Base SI dimensions actually spanned by the inputs. */\n readonly baseDimensions: readonly string[];\n /** n — the number of variables. */\n readonly variableCount: number;\n /** r — the rank of the dimension matrix. */\n readonly rank: number;\n /** n − r — the number of independent dimensionless groups. */\n readonly piGroupCount: number;\n readonly piGroups: readonly PiGroup[];\n readonly verdict: BuckinghamVerdict;\n}\n\n/** Result of {@link dimensionallyDetermines}. @public */\nexport interface DimensionalDeterminationResult {\n readonly target: string;\n readonly governing: readonly string[];\n /** True iff the target is fixed by the governing variables UP TO A\n * DIMENSIONLESS CONSTANT (unique monomial). */\n readonly determined: boolean;\n /**\n * When determined: target = const · Π(governingⱼ ^ monomial[j]). The\n * exponents may be rational (e.g. 0.5 for a √ law). Always read with\n * `upToDimensionlessConstant` — the leading constant is NOT supplied.\n */\n readonly monomial?: Readonly<Record<string, number>>;\n /** Always true when `monomial` is present — a standing reminder. */\n readonly upToDimensionlessConstant?: true;\n /**\n * True only when the target's dimension is not in the span of the governing\n * variables, so a monomial needs dimensionful constants the inputs do not\n * name. False when the governing variables are dimensionally dependent or\n * leave more than one π-group: that failure is not a missing constant.\n */\n readonly outsideGoverningSpan: boolean;\n /** Plain-language reason for the verdict. */\n readonly reason: string;\n}\n\n/** Rationalization failed: a dimension exponent is not a small rational.\n * @public */\nexport class RationalizationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'RationalizationError';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Exact rational arithmetic: MathTS core `Fraction` (bigint-backed, reduced by\n// its constructor). Dimension exponents are small rationals.\n// ---------------------------------------------------------------------------\n\nconst MAX_DEN = 720;\n\n/**\n * Convert a (possibly rational) exponent to an exact {@link Fraction} by\n * scanning small denominators; throws if none matches within tolerance. The\n * scan, not `Fraction.fromNumber`'s continued fraction, is what refuses an\n * irrational exponent instead of approximating it.\n */\nfunction toFrac(x: number): Fraction {\n if (Number.isInteger(x)) return new Fraction(x, 1);\n for (let d = 2; d <= MAX_DEN; d++) {\n const n = x * d;\n if (Math.abs(n - Math.round(n)) < 1e-9 * Math.max(1, Math.abs(n))) {\n return new Fraction(Math.round(n), d);\n }\n }\n throw new RationalizationError(\n `dimension exponent ${x} is not a rational with denominator ≤ ${MAX_DEN}`,\n );\n}\n\n/**\n * Exact null space of the dimension matrix. Exponents pass through as\n * {@link Fraction} values after {@link toFrac}, so an irrational is still\n * {@link RationalizationError} and is not accepted by a continued fraction.\n * A matrix with no rows is `0×n`: `{ columns: n }` is the standard basis.\n * MathTS integerizes each vector (content 1, first nonzero entry positive).\n */\nfunction nullSpace(matrix: Fraction[][], cols: number): { basis: number[][]; rank: number } {\n const solved = rationalNullspace(matrix, { columns: cols });\n const basis = solved.basis.map((vec) =>\n vec.map((entry) => {\n if (entry.denominator !== 1n) {\n throw new RationalizationError(\n `null-space entry ${entry.toString()} is not an integer`,\n );\n }\n return Number(entry.numerator);\n }),\n );\n return { basis, rank: solved.rank };\n}\n\nfunction buildMatrix(variables: readonly DimensionalVariable[]): {\n matrix: Fraction[][];\n spannedBases: string[];\n} {\n const spannedBases: string[] = [];\n const matrix: Fraction[][] = [];\n for (const base of BASES) {\n const row = variables.map((v) => toFrac(v.dim[base]));\n if (row.some((f) => !f.isZero())) {\n spannedBases.push(base);\n matrix.push(row);\n }\n }\n return { matrix, spannedBases };\n}\n\nfunction formatPiGroup(\n exponents: Record<string, number>,\n order: readonly string[],\n): string {\n const parts: string[] = [];\n for (const name of order) {\n const e = exponents[name];\n if (e === 0) continue;\n parts.push(e === 1 ? name : `${name}^${e}`);\n }\n return parts.join(' · ') || '1';\n}\n\n/**\n * Enumerate the Buckingham-π groups of a dimensional variable set. Returns\n * the rank, the count n − r, and a null-space basis of dimensionless\n * groups. FORM only — no constants (see module docs).\n *\n * @public\n */\nexport function buckinghamPi(\n variables: readonly DimensionalVariable[],\n): BuckinghamResult {\n if (variables.length === 0) {\n throw new RationalizationError('buckinghamPi requires at least one variable');\n }\n const names = variables.map((v) => v.name);\n if (new Set(names).size !== names.length) {\n throw new RationalizationError(\n `buckinghamPi requires unique variable names; got [${names.join(', ')}]`,\n );\n }\n\n const n = variables.length;\n const { matrix, spannedBases } = buildMatrix(variables);\n\n const { basis, rank } = nullSpace(matrix, n);\n const piGroups: PiGroup[] = basis.map((vec) => {\n const exponents: Record<string, number> = {};\n for (let j = 0; j < n; j++) exponents[names[j]] = vec[j];\n return { exponents, formula: formatPiGroup(exponents, names) };\n });\n\n const piGroupCount = n - rank;\n const verdict: BuckinghamVerdict =\n piGroupCount === 0\n ? 'dimensionally-independent'\n : piGroupCount === 1\n ? 'single-invariant'\n : 'multiple-invariants';\n\n return {\n variables: names,\n baseDimensions: spannedBases,\n variableCount: n,\n rank,\n piGroupCount,\n piGroups,\n verdict,\n };\n}\n\n/**\n * Does the governing set fix the target UP TO A DIMENSIONLESS CONSTANT?\n *\n * True iff the governing variables are dimensionally independent and the\n * target's dimension lies in their span — equivalently, the full set has\n * exactly one π-group and the governing set has none. When determined,\n * returns the (possibly rational) monomial exponents such that\n * target = const · Π(governingⱼ ^ monomial[j]). The constant is NOT\n * supplied — dimensional analysis cannot.\n *\n * @public\n */\nexport function dimensionallyDetermines(\n target: DimensionalVariable,\n governing: readonly DimensionalVariable[],\n): DimensionalDeterminationResult {\n const governingNames = governing.map((v) => v.name);\n\n const governingPi = buckinghamPi(\n governing.length > 0 ? governing : [target],\n );\n // A redundancy among the governing variables means the monomial is not\n // unique (any dimensionless governing combo can be folded into the\n // constant) → not determined.\n if (governing.length > 0 && governingPi.piGroupCount > 0) {\n return {\n target: target.name,\n governing: governingNames,\n determined: false,\n outsideGoverningSpan: false,\n reason:\n 'governing variables are dimensionally dependent ' +\n `(${governingPi.piGroupCount} dimensionless combination(s) among them); ` +\n 'the determining monomial is not unique',\n };\n }\n\n const full = buckinghamPi([target, ...governing]);\n if (full.piGroupCount !== 1) {\n return {\n target: target.name,\n governing: governingNames,\n determined: false,\n outsideGoverningSpan: full.piGroupCount === 0,\n reason:\n full.piGroupCount === 0\n ? \"the target's dimension is not in the span of the governing \" +\n 'variables — no dimensionless group exists, so no monomial determines it'\n : `${full.piGroupCount} independent π-groups — the target is fixed ` +\n 'only as a function of several dimensionless ratios (under-constrained)',\n };\n }\n\n // The single π-group involves the target; solve it for the target.\n const group = full.piGroups[0].exponents;\n const targetExp = group[target.name];\n if (!targetExp) {\n return {\n target: target.name,\n governing: governingNames,\n determined: false,\n outsideGoverningSpan: false,\n reason:\n 'the sole dimensionless group does not involve the target ' +\n '(the target is dimensionally redundant with the governing set)',\n };\n }\n const monomial: Record<string, number> = {};\n for (const name of governingNames) {\n monomial[name] = -(group[name] ?? 0) / targetExp;\n }\n\n return {\n target: target.name,\n governing: governingNames,\n determined: true,\n monomial,\n upToDimensionlessConstant: true,\n outsideGoverningSpan: false,\n reason:\n 'unique dimensionless group fixes the target up to a dimensionless constant',\n };\n}\n"]}
|
|
@@ -34,9 +34,9 @@ export const CONSTANT_ROWS = [
|
|
|
34
34
|
row({ name: 'c', spellings: ['speed-of-light', 'speed_of_light'], value: C_SI, unit: 'm/s', canonical: true, mathts: 'speedOfLight', exact: true,
|
|
35
35
|
meaning: 'speed of light in vacuum', source: `exact SI (${OWNER} C_SI)` }),
|
|
36
36
|
row({ name: 'R_inf', spellings: ['Rinf', 'R_infinity', 'rydberg'], quantity: 'rydberg-constant', value: R_INF_SI, unit: '1/m', canonical: true, mathts: 'rydberg',
|
|
37
|
-
meaning: 'Rydberg constant R∞, infinite nuclear mass (the reduced-mass correction R_M = R∞/(1 + m_e/M) is not applied)', source: `CODATA
|
|
37
|
+
meaning: 'Rydberg constant R∞, infinite nuclear mass (the reduced-mass correction R_M = R∞/(1 + m_e/M) is not applied)', source: `CODATA 2022, MathTS (${OWNER} R_INF_SI)` }),
|
|
38
38
|
row({ name: 'G', value: G_SI, unit: 'm^3/(kg*s^2)', canonical: true, mathts: 'gravitationConstant',
|
|
39
|
-
meaning: 'Newtonian gravitational constant', source: `CODATA
|
|
39
|
+
meaning: 'Newtonian gravitational constant', source: `CODATA 2022, MathTS (${OWNER} G_SI)` }),
|
|
40
40
|
row({ name: 'k_B', spellings: ['kB', 'boltzmann'], quantity: 'boltzmann-constant', value: K_B_SI, unit: 'J/K', canonical: true, mathts: 'boltzmann', exact: true,
|
|
41
41
|
meaning: 'Boltzmann constant', source: `exact SI, 2019 redefinition (${OWNER} K_B_SI)` }),
|
|
42
42
|
row({ name: 'ln2', value: Math.LN2, unit: '1', canonical: true, irrational: true,
|
|
@@ -53,25 +53,25 @@ export const CONSTANT_ROWS = [
|
|
|
53
53
|
row({ name: 'e', spellings: ['e_charge'], value: E_SI, unit: 'C', canonical: true, mathts: 'elementaryCharge', exact: true,
|
|
54
54
|
meaning: 'elementary charge', source: `exact SI, 2019 redefinition (${OWNER} E_SI)` }),
|
|
55
55
|
row({ name: 'epsilon_0', spellings: ['epsilon0', 'eps0', 'vacuum-permittivity'], value: EPS0_SI, unit: 'F/m', canonical: true,
|
|
56
|
-
meaning: 'vacuum permittivity', source: `CODATA
|
|
56
|
+
meaning: 'vacuum permittivity', source: `CODATA 2022, MathTS (${OWNER} EPS0_SI)` }),
|
|
57
57
|
row({ name: 'sigma_sb', spellings: ['stefan-boltzmann-constant'], value: SIGMA_SB_SI, unit: 'W/(m^2*K^4)', canonical: true, mathts: 'stefanBoltzmann',
|
|
58
|
-
meaning: 'Stefan–Boltzmann constant', source: `CODATA
|
|
58
|
+
meaning: 'Stefan–Boltzmann constant', source: `CODATA 2022, MathTS (${OWNER} SIGMA_SB_SI)` }),
|
|
59
59
|
row({ name: 'b', spellings: ['wien-constant'], value: B_WIEN_SI, unit: 'm*K', canonical: true, mathts: 'wienDisplacement',
|
|
60
|
-
meaning: 'Wien displacement constant', source: `CODATA
|
|
60
|
+
meaning: 'Wien displacement constant', source: `CODATA 2022, MathTS (${OWNER} B_WIEN_SI)` }),
|
|
61
61
|
// IAU 2015 nominal solar parameter. M_sun in eval stays the rounded kilogram M_SUN_SI.
|
|
62
62
|
row({ name: 'GM_sun', value: GM_SUN_SI, unit: 'm^3/s^2', canonical: true,
|
|
63
63
|
meaning: 'IAU nominal solar gravitational parameter (GM)☉', source: `IAU 2015 Resolution B3 (${OWNER} GM_SUN_SI)` }),
|
|
64
64
|
row({ name: 'Msun_iau', value: M_SUN_IAU_SI, unit: 'kg', canonical: true,
|
|
65
65
|
meaning: 'IAU solar mass (GM)☉/G, the mass that reproduces GM_sun with G_SI', source: `GM_SUN_SI/G_SI (${OWNER} M_SUN_IAU_SI)` }),
|
|
66
66
|
row({ name: 'm_u', value: M_U_SI, unit: 'kg', canonical: true, mathts: 'atomicMass',
|
|
67
|
-
meaning: 'unified atomic mass unit (atomic mass constant)', source: `CODATA
|
|
67
|
+
meaning: 'unified atomic mass unit (atomic mass constant)', source: `CODATA 2022, MathTS (${OWNER} M_U_SI)` }),
|
|
68
68
|
row({ name: 'm_e', spellings: ['electron_mass', 'electron-mass'], value: M_E_SI, unit: 'kg', canonical: true, mathts: 'electronMass',
|
|
69
|
-
meaning: 'electron mass', source: `CODATA
|
|
69
|
+
meaning: 'electron mass', source: `CODATA 2022, MathTS (${OWNER} M_E_SI)` }),
|
|
70
70
|
// ── overlay names for `upt eval` and the dimensional assignment only ────
|
|
71
71
|
row({ name: 'mu_0', spellings: ['mu0'], value: MU0_SI, unit: 'H/m', mathts: 'magneticConstant',
|
|
72
72
|
meaning: 'vacuum permeability 1/(ε₀ c²)', source: `1/(EPS0_SI·C_SI²) (${OWNER} MU0_SI)` }),
|
|
73
73
|
row({ name: 'm_p', spellings: ['m_proton'], value: M_PROTON_SI, unit: 'kg', mathts: 'protonMass',
|
|
74
|
-
meaning: 'proton mass', source: `CODATA
|
|
74
|
+
meaning: 'proton mass', source: `CODATA 2022, MathTS (${OWNER} M_PROTON_SI)` }),
|
|
75
75
|
row({ name: 'N_A', value: N_A_SI, unit: 'mol^-1', mathts: 'avogadro', exact: true,
|
|
76
76
|
meaning: 'Avogadro constant', source: `exact SI, 2019 redefinition (${OWNER} N_A_SI)` }),
|
|
77
77
|
row({ name: 'F', value: FARADAY_SI, unit: 'C/mol', mathts: 'faraday', exact: true,
|
|
@@ -88,7 +88,7 @@ export const CONSTANT_ROWS = [
|
|
|
88
88
|
row({ name: 'scale_factor', value: 1, unit: 'm',
|
|
89
89
|
meaning: 'Friedmann scale factor, unit by default', source: 'this registry (default 1)' }),
|
|
90
90
|
row({ name: 'sigma_T', value: THOMSON_CROSS_SECTION_SI, unit: 'm^2', mathts: 'thomsonCrossSection',
|
|
91
|
-
meaning: 'Thomson cross section', source: `CODATA
|
|
91
|
+
meaning: 'Thomson cross section', source: `CODATA 2022, MathTS (${OWNER} THOMSON_CROSS_SECTION_SI)` }),
|
|
92
92
|
row({ name: 'lane_emden_omega_3', quantity: 'lane-emden-omega-3', value: LANE_EMDEN_OMEGA3, unit: '1',
|
|
93
93
|
meaning: 'Lane–Emden n = 3 dimensionless radius', source: `${OWNER} LANE_EMDEN_OMEGA3` }),
|
|
94
94
|
row({ name: 'euler_gamma', value: EULER_GAMMA, unit: '1',
|