universal-physics-tensor 10.0.0 → 12.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 +39 -36
- package/bin/upt.mjs +13 -1
- package/data/applied-cases.json +1892 -0
- package/data/applied-cases.schema.json +194 -0
- 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 +389 -230
- package/data/bridge-catalog.schema.json +45 -7
- package/data/units.json +6 -25
- 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 +9 -15
- 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 +35 -25
- package/dist/atlas/physjs-entries.generated.d.ts.map +1 -1
- package/dist/atlas/physjs-entries.generated.js +37 -25
- 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/catalog-checks.d.ts +10 -0
- package/dist/cases/catalog-checks.d.ts.map +1 -0
- package/dist/cases/catalog-checks.js +241 -0
- package/dist/cases/catalog-checks.js.map +1 -0
- package/dist/cases/catalog.d.ts +83 -0
- package/dist/cases/catalog.d.ts.map +1 -0
- package/dist/cases/catalog.js +118 -0
- package/dist/cases/catalog.js.map +1 -0
- package/dist/cases/engine.d.ts +13 -0
- package/dist/cases/engine.d.ts.map +1 -0
- package/dist/cases/engine.js +179 -0
- package/dist/cases/engine.js.map +1 -0
- package/dist/cases/index.d.ts.map +1 -1
- package/dist/cases/index.js +5 -7
- package/dist/cases/index.js.map +1 -1
- package/dist/cases/methods.d.ts +215 -0
- package/dist/cases/methods.d.ts.map +1 -0
- package/dist/cases/methods.js +743 -0
- package/dist/cases/methods.js.map +1 -0
- 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/types.d.ts +12 -0
- package/dist/cases/types.d.ts.map +1 -1
- package/dist/cases/types.js.map +1 -1
- package/dist/cli/args.d.ts +25 -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 +11 -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 +1 -0
- package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
- package/dist/cli/commands/_discovery-opts.js +9 -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 +122 -73
- 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 +67 -39
- 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 +24 -3
- 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 +7 -1
- 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 +84 -11
- 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/determination.d.ts +1 -0
- package/dist/cli/determination.d.ts.map +1 -1
- package/dist/cli/determination.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/flag-help.d.ts +1 -0
- package/dist/cli/flag-help.d.ts.map +1 -1
- package/dist/cli/flag-help.js +1 -0
- package/dist/cli/flag-help.js.map +1 -1
- package/dist/cli/graphs.d.ts +2 -0
- package/dist/cli/graphs.d.ts.map +1 -1
- package/dist/cli/graphs.js +1 -0
- package/dist/cli/graphs.js.map +1 -1
- package/dist/cli/main.d.ts +8 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +19 -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 +28 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +23 -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 +12 -9
- 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 +1 -0
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +8 -5
- package/dist/cli/version.js.map +1 -1
- package/dist/cli-api.d.ts +36 -5
- package/dist/cli-api.d.ts.map +1 -1
- package/dist/cli-api.js +30 -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 +3 -3
- package/dist/composition/canonical-graph.d.ts.map +1 -1
- package/dist/composition/canonical-graph.js +11 -38
- 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/consequence.d.ts +15 -5
- package/dist/composition/consequence.d.ts.map +1 -1
- package/dist/composition/consequence.js +6 -4
- package/dist/composition/consequence.js.map +1 -1
- package/dist/composition/discovery.d.ts +129 -9
- package/dist/composition/discovery.d.ts.map +1 -1
- package/dist/composition/discovery.js +171 -67
- 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 +1 -1
- package/dist/composition/expr-eval.d.ts.map +1 -1
- package/dist/composition/expr-eval.js +6 -15
- package/dist/composition/expr-eval.js.map +1 -1
- package/dist/composition/expr-simplify.d.ts +26 -14
- package/dist/composition/expr-simplify.d.ts.map +1 -1
- package/dist/composition/expr-simplify.js +64 -72
- 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/grounding.d.ts.map +1 -1
- package/dist/composition/grounding.js +19 -7
- package/dist/composition/grounding.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 +7 -8
- package/dist/composition/mathts-quiet.d.ts.map +1 -1
- package/dist/composition/mathts-quiet.js +7 -16
- 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/own-equation-magnitude.d.ts +95 -0
- package/dist/composition/own-equation-magnitude.d.ts.map +1 -0
- package/dist/composition/own-equation-magnitude.js +270 -0
- package/dist/composition/own-equation-magnitude.js.map +1 -0
- package/dist/composition/probe/backend-protocol.d.ts +3 -0
- package/dist/composition/probe/backend-protocol.d.ts.map +1 -1
- package/dist/composition/probe/backend-protocol.js.map +1 -1
- package/dist/composition/probe/candidate-store.d.ts +1 -0
- package/dist/composition/probe/candidate-store.d.ts.map +1 -1
- package/dist/composition/probe/candidate-store.js +1 -0
- package/dist/composition/probe/candidate-store.js.map +1 -1
- package/dist/composition/probe/corpus.d.ts +8 -4
- package/dist/composition/probe/corpus.d.ts.map +1 -1
- package/dist/composition/probe/corpus.js +23 -12
- package/dist/composition/probe/corpus.js.map +1 -1
- package/dist/composition/probe/dataset.d.ts +18 -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 +7 -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 +2 -0
- 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 +7 -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 +30 -1
- package/dist/composition/probe/generator.d.ts.map +1 -1
- package/dist/composition/probe/generator.js +58 -36
- 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 +25 -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 +5 -0
- package/dist/composition/probe/pipeline.d.ts.map +1 -1
- package/dist/composition/probe/pipeline.js +73 -24
- 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 +251 -0
- package/dist/composition/probe/power-law.js.map +1 -0
- package/dist/composition/probe/problem.d.ts +8 -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 +7 -1
- package/dist/composition/probe/residual.d.ts.map +1 -1
- package/dist/composition/probe/residual.js +10 -7
- package/dist/composition/probe/residual.js.map +1 -1
- package/dist/composition/probe/run-manifest.d.ts +1 -0
- package/dist/composition/probe/run-manifest.d.ts.map +1 -1
- package/dist/composition/probe/run-manifest.js.map +1 -1
- package/dist/composition/probe/scalar-search.d.ts +50 -0
- package/dist/composition/probe/scalar-search.d.ts.map +1 -0
- package/dist/composition/probe/scalar-search.js +169 -0
- package/dist/composition/probe/scalar-search.js.map +1 -0
- package/dist/composition/probe/scoring.d.ts +1 -0
- package/dist/composition/probe/scoring.d.ts.map +1 -1
- package/dist/composition/probe/scoring.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 +235 -184
- package/dist/composition/probe/study.js.map +1 -1
- package/dist/composition/probe/t-tail.d.ts +16 -0
- package/dist/composition/probe/t-tail.d.ts.map +1 -0
- package/dist/composition/probe/t-tail.js +29 -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 +52 -12
- package/dist/composition/proposed-bridges.d.ts.map +1 -1
- package/dist/composition/proposed-bridges.js +107 -60
- 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 +29 -0
- package/dist/composition/representative-values.js.map +1 -1
- package/dist/composition/retrodiction.d.ts +15 -0
- package/dist/composition/retrodiction.d.ts.map +1 -1
- package/dist/composition/retrodiction.js +12 -4
- package/dist/composition/retrodiction.js.map +1 -1
- package/dist/composition/user-equation.d.ts +1 -0
- package/dist/composition/user-equation.d.ts.map +1 -1
- package/dist/composition/user-equation.js +3 -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 +42 -41
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +71 -51
- 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-ast-gradient.d.ts +27 -23
- package/dist/diff/bridge-ast-gradient.d.ts.map +1 -1
- package/dist/diff/bridge-ast-gradient.js +75 -173
- package/dist/diff/bridge-ast-gradient.js.map +1 -1
- 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/ast-types.d.ts +15 -0
- package/dist/dimensional/ast-types.d.ts.map +1 -1
- package/dist/dimensional/ast-types.js.map +1 -1
- 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/curvature-composite.d.ts +1 -1
- package/dist/dimensional/curvature-composite.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 +24 -11
- package/dist/dimensional/exact-scale.d.ts.map +1 -1
- package/dist/dimensional/exact-scale.js +122 -130
- 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/mathts-unit-delegation.d.ts +29 -0
- package/dist/dimensional/mathts-unit-delegation.d.ts.map +1 -0
- package/dist/dimensional/mathts-unit-delegation.js +187 -0
- package/dist/dimensional/mathts-unit-delegation.js.map +1 -0
- package/dist/dimensional/mathts-unit-wrapper.d.ts +33 -0
- package/dist/dimensional/mathts-unit-wrapper.d.ts.map +1 -0
- package/dist/dimensional/mathts-unit-wrapper.js +190 -0
- package/dist/dimensional/mathts-unit-wrapper.js.map +1 -0
- 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/scalar-lowering.d.ts +21 -0
- package/dist/dimensional/scalar-lowering.d.ts.map +1 -0
- package/dist/dimensional/scalar-lowering.js +45 -0
- package/dist/dimensional/scalar-lowering.js.map +1 -0
- 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.d.ts +5 -1
- package/dist/dimensional/unit-data.d.ts.map +1 -1
- package/dist/dimensional/unit-data.js +30 -6
- package/dist/dimensional/unit-data.js.map +1 -1
- package/dist/dimensional/units.d.ts +2 -0
- package/dist/dimensional/units.d.ts.map +1 -1
- package/dist/dimensional/units.js +59 -3
- package/dist/dimensional/units.js.map +1 -1
- package/dist/dimensional/validator.d.ts +2 -0
- package/dist/dimensional/validator.d.ts.map +1 -1
- package/dist/dimensional/validator.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/connection-lowering-helpers.d.ts +3 -1
- package/dist/numerical/connection-lowering-helpers.d.ts.map +1 -1
- package/dist/numerical/connection-lowering-helpers.js +11 -15
- package/dist/numerical/connection-lowering-helpers.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/pderiv.d.ts.map +1 -1
- package/dist/numerical/pderiv.js +2 -6
- package/dist/numerical/pderiv.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 +11 -13
- 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/strides.d.ts +3 -2
- package/dist/numerical/strides.d.ts.map +1 -1
- package/dist/numerical/strides.js +3 -10
- package/dist/numerical/strides.js.map +1 -1
- 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 +9 -12
- package/dist/cases/brownian-sphere.d.ts +0 -68
- package/dist/cases/brownian-sphere.d.ts.map +0 -1
- package/dist/cases/brownian-sphere.js +0 -354
- package/dist/cases/brownian-sphere.js.map +0 -1
- package/dist/cases/damped-resonator.d.ts +0 -23
- package/dist/cases/damped-resonator.d.ts.map +0 -1
- package/dist/cases/damped-resonator.js +0 -224
- package/dist/cases/damped-resonator.js.map +0 -1
- package/dist/cases/kepler-rv.d.ts +0 -13
- package/dist/cases/kepler-rv.d.ts.map +0 -1
- package/dist/cases/kepler-rv.js +0 -172
- package/dist/cases/kepler-rv.js.map +0 -1
- package/dist/cases/lumped-cooling.d.ts +0 -46
- package/dist/cases/lumped-cooling.d.ts.map +0 -1
- package/dist/cases/lumped-cooling.js +0 -261
- package/dist/cases/lumped-cooling.js.map +0 -1
- package/dist/cases/resistor-noise.d.ts +0 -14
- package/dist/cases/resistor-noise.d.ts.map +0 -1
- package/dist/cases/resistor-noise.js +0 -215
- package/dist/cases/resistor-noise.js.map +0 -1
- package/dist/cases/skin-depth.d.ts +0 -21
- package/dist/cases/skin-depth.d.ts.map +0 -1
- package/dist/cases/skin-depth.js +0 -174
- package/dist/cases/skin-depth.js.map +0 -1
|
@@ -1,69 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Exact bridge-gradients
|
|
2
|
+
* Exact bridge-gradients over the symbolic RHS AST.
|
|
3
3
|
*
|
|
4
4
|
* The catalog's plain-JS evaluators cannot be differentiated by AD (they run
|
|
5
5
|
* raw `Math.*` arithmetic and return a number, which carries no tape; see
|
|
6
6
|
* `bridge-gradient.ts`). But each bridge also carries a faithful symbolic
|
|
7
7
|
* encoding of its RHS (`*_RHS: ExprNode`). This module lowers that scalar AST
|
|
8
|
-
*
|
|
9
|
-
* chosen variable
|
|
10
|
-
*
|
|
11
|
-
* the plain-JS evaluators
|
|
8
|
+
* with the MathTS scalar builder and differentiates it with MathTS
|
|
9
|
+
* `compileScalarGradient`: the chosen variable is the one parameter, and every
|
|
10
|
+
* other symbol is a constant. The result is the EXACT derivative (machine
|
|
11
|
+
* precision); the plain-JS evaluators stay untouched (P8 Decision #1).
|
|
12
12
|
*
|
|
13
|
-
* Scope: the
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* an exponent).
|
|
13
|
+
* Scope: the scalar grammar is `symbol` + `op(+ − * / ^)` + `transcendental` +
|
|
14
|
+
* `abs`. A bridge encoded with a typed stub differentiates with respect to the
|
|
15
|
+
* stub, not the physics inside it; fully-expanded encodings (e.g. BE-42
|
|
16
|
+
* `ℏc³/(8πGM·k_B)`) differentiate exactly. A `^` exponent must be constant: a
|
|
17
|
+
* UPT pre-check refuses the differentiation variable in an exponent before
|
|
18
|
+
* MathTS sees the tree.
|
|
20
19
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* A point where the value overflows gives `NaN` for the value and the
|
|
21
|
+
* gradient (MathTS marks the row invalid), not `±Infinity`.
|
|
23
22
|
*
|
|
24
23
|
* @module diff/bridge-ast-gradient
|
|
25
24
|
*/
|
|
25
|
+
import { ScalarBuildError } from '@danielsimonjr/mathts-expression';
|
|
26
|
+
import { compileScalarGradient } from '@danielsimonjr/mathts-functions';
|
|
27
|
+
import { forEachScalarLeaf, isDecimalLiteral } from '../dimensional/ast-leaves.js';
|
|
26
28
|
import { constantScope } from '../dimensional/symbolic-constants.js';
|
|
27
|
-
import {
|
|
29
|
+
import { toScalarNode } from '../dimensional/scalar-lowering.js';
|
|
28
30
|
import { BRIDGE_RHS_BY_ID, parseBridgeId } from '../bridges/rhs-registry.js';
|
|
29
|
-
import { GAUSS_LEGENDRE_16 } from '../numerical/quadrature.js';
|
|
30
|
-
/** Map a transcendental fn name to the TapedTensor method that traces it. */
|
|
31
|
-
function applyTranscendental(fn, t) {
|
|
32
|
-
switch (fn) {
|
|
33
|
-
case 'exp':
|
|
34
|
-
return t.exp();
|
|
35
|
-
case 'ln':
|
|
36
|
-
return t.log();
|
|
37
|
-
case 'log2':
|
|
38
|
-
return t.log2();
|
|
39
|
-
case 'log10':
|
|
40
|
-
return t.log10();
|
|
41
|
-
case 'sin':
|
|
42
|
-
return t.sin();
|
|
43
|
-
case 'cos':
|
|
44
|
-
return t.cos();
|
|
45
|
-
case 'tan':
|
|
46
|
-
return t.tan();
|
|
47
|
-
case 'sinh':
|
|
48
|
-
return t.sinh();
|
|
49
|
-
case 'cosh':
|
|
50
|
-
return t.cosh();
|
|
51
|
-
case 'tanh':
|
|
52
|
-
return t.tanh();
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
31
|
/**
|
|
56
32
|
* Named physical constants the bridge encodings reference as bare symbols:
|
|
57
33
|
* every registered spelling, from the constant registry, plus π and its
|
|
58
|
-
* registered multiples, so
|
|
34
|
+
* registered multiples, so the AST evaluates to the SAME number as the
|
|
59
35
|
* numeric evaluator. Callers can override or extend via the `bindings` argument.
|
|
60
36
|
*/
|
|
61
37
|
const NAMED_CONSTANTS = constantScope();
|
|
62
38
|
/** Resolve a symbol's numeric value: caller bindings → named constants → numeric literal. */
|
|
63
39
|
function resolveConstant(name, bindings) {
|
|
64
|
-
if (Object.
|
|
40
|
+
if (Object.hasOwn(bindings, name))
|
|
65
41
|
return bindings[name];
|
|
66
|
-
if (Object.
|
|
42
|
+
if (Object.hasOwn(NAMED_CONSTANTS, name))
|
|
67
43
|
return NAMED_CONSTANTS[name];
|
|
68
44
|
const asNumber = Number(name);
|
|
69
45
|
if (name.trim() !== '' && Number.isFinite(asNumber))
|
|
@@ -75,9 +51,8 @@ function resolveConstant(name, bindings) {
|
|
|
75
51
|
*
|
|
76
52
|
* The exponent may contain scalar arithmetic over constants/bindings (for
|
|
77
53
|
* example `-1/z`) as long as it is independent of the differentiation
|
|
78
|
-
* variable.
|
|
79
|
-
*
|
|
80
|
-
* explicitly rather than being silently detached from AD.
|
|
54
|
+
* variable. UPT keeps the constant-power contract, so the differentiation
|
|
55
|
+
* variable in an exponent is refused before MathTS reads the tree.
|
|
81
56
|
*/
|
|
82
57
|
function resolveExponent(node, varName, bindings) {
|
|
83
58
|
if (node.kind === 'symbol') {
|
|
@@ -103,125 +78,60 @@ function resolveExponent(node, varName, bindings) {
|
|
|
103
78
|
throw new TypeError(`bridgeGradientAST: '^' exponent must be a constant scalar expression, got node kind '${node.kind}'.`);
|
|
104
79
|
}
|
|
105
80
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
|
|
81
|
+
* Refuse the differentiation variable in any `^` exponent, and check that every
|
|
82
|
+
* exponent is a constant scalar expression. MathTS would differentiate a
|
|
83
|
+
* variable exponent; UPT keeps the constant-power contract.
|
|
84
|
+
*/
|
|
85
|
+
function checkExponents(node, varName, bindings) {
|
|
86
|
+
if (node.kind === 'op') {
|
|
87
|
+
if (node.op === '^' && node.args.length === 2)
|
|
88
|
+
resolveExponent(node.args[1], varName, bindings);
|
|
89
|
+
for (const arg of node.args)
|
|
90
|
+
checkExponents(arg, varName, bindings);
|
|
91
|
+
}
|
|
92
|
+
else if (node.kind === 'transcendental' || node.kind === 'abs') {
|
|
93
|
+
checkExponents(node.arg, varName, bindings);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Differentiate a scalar bridge RHS AST with respect to one symbol through
|
|
98
|
+
* MathTS `compileScalarGradient`. Every symbol other than `varName` is resolved
|
|
99
|
+
* to a constant (caller `bindings`, then {@link NAMED_CONSTANTS}, then numeric
|
|
100
|
+
* literal); the `bindings` must contain `varName` (its value sets the point of
|
|
101
|
+
* evaluation).
|
|
110
102
|
*
|
|
103
|
+
* @throws TypeError when `varName` is not bound, a symbol cannot be resolved,
|
|
104
|
+
* `varName` appears in an exponent, or a node kind is outside the scalar grammar.
|
|
111
105
|
* @public
|
|
112
106
|
*/
|
|
113
|
-
export
|
|
114
|
-
if (!Object.
|
|
107
|
+
export function bridgeGradientAST(rhs, varName, bindings) {
|
|
108
|
+
if (!Object.hasOwn(bindings, varName)) {
|
|
115
109
|
throw new TypeError(`bridgeGradientAST: bindings must contain the differentiation variable '${varName}'.`);
|
|
116
110
|
}
|
|
117
|
-
|
|
118
|
-
let
|
|
111
|
+
checkExponents(rhs, varName, bindings);
|
|
112
|
+
let lowered;
|
|
119
113
|
try {
|
|
120
|
-
|
|
121
|
-
// this lowering calls: reverseGrad, TapedTensor, Tensor.fromNested …).
|
|
122
|
-
// The casts state that those members exist on the imported modules, which
|
|
123
|
-
// their own type declarations guarantee; the full MathTS types are not
|
|
124
|
-
// imported so this file compiles without the autograd types at hand.
|
|
125
|
-
autograd =
|
|
126
|
-
(await import('@danielsimonjr/mathts-autograd'));
|
|
127
|
-
tensorMod =
|
|
128
|
-
(await import('@danielsimonjr/mathts-tensor'));
|
|
114
|
+
lowered = toScalarNode(rhs);
|
|
129
115
|
}
|
|
130
|
-
catch {
|
|
131
|
-
|
|
116
|
+
catch (err) {
|
|
117
|
+
if (!(err instanceof ScalarBuildError))
|
|
118
|
+
throw err;
|
|
119
|
+
throw new TypeError(`bridgeGradientAST: unsupported node kind — ${err.message}. The differentiable grammar is ` +
|
|
120
|
+
`symbol + op(+ − * / ^) + transcendental + abs. Other encodings (tensor/curvature, integrals, ` +
|
|
121
|
+
`or physics hidden in a typed-stub symbol) are not exactly differentiable.`);
|
|
132
122
|
}
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const bound = boundVars.get(node.name);
|
|
146
|
-
if (bound !== undefined)
|
|
147
|
-
return bound;
|
|
148
|
-
return node.name === varName
|
|
149
|
-
? x
|
|
150
|
-
: constLeaf(resolveConstant(node.name, bindings));
|
|
151
|
-
}
|
|
152
|
-
if (node.kind === 'op') {
|
|
153
|
-
switch (node.op) {
|
|
154
|
-
case '+':
|
|
155
|
-
return node.args.map((a) => walk(a, boundVars)).reduce((a, b) => a.add(b));
|
|
156
|
-
case '-': {
|
|
157
|
-
const terms = node.args.map((a) => walk(a, boundVars));
|
|
158
|
-
// Unary minus (0 − t); n-ary subtract folds left.
|
|
159
|
-
return terms.length === 1
|
|
160
|
-
? constLeaf(0).sub(terms[0])
|
|
161
|
-
: terms.reduce((a, b) => a.sub(b));
|
|
162
|
-
}
|
|
163
|
-
case '*':
|
|
164
|
-
return node.args.map((a) => walk(a, boundVars)).reduce((a, b) => a.mul(b));
|
|
165
|
-
case '/':
|
|
166
|
-
return node.args.map((a) => walk(a, boundVars)).reduce((a, b) => a.divide(b));
|
|
167
|
-
case '^':
|
|
168
|
-
return walk(node.args[0], boundVars).pow(resolveExponent(node.args[1], varName, bindings));
|
|
169
|
-
default:
|
|
170
|
-
throw new TypeError(`bridgeGradientAST: unsupported operator '${node.op}'.`);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
if (node.kind === 'transcendental') {
|
|
174
|
-
return applyTranscendental(node.fn, walk(node.arg, boundVars));
|
|
175
|
-
}
|
|
176
|
-
if (node.kind === 'abs') {
|
|
177
|
-
return walk(node.arg, boundVars).abs();
|
|
178
|
-
}
|
|
179
|
-
if (node.kind === 'integral') {
|
|
180
|
-
// Definite integral via 16-point Gauss–Legendre quadrature, built from
|
|
181
|
-
// traced ops so reverse-mode AD yields the gradient w.r.t. integrand
|
|
182
|
-
// parameters (Leibniz: ∫ ∂f/∂θ) and w.r.t. bounds (∂Q/∂b ≈ f(b)).
|
|
183
|
-
// NOTE: the gradient is EXACT for the quadrature, which APPROXIMATES the
|
|
184
|
-
// true integral for non-polynomial integrands (exact for constant /
|
|
185
|
-
// polynomial-degree ≤ 31 integrands).
|
|
186
|
-
if (!node.lower || !node.upper) {
|
|
187
|
-
throw new TypeError(`bridgeGradientAST: an abstract (bound-less) integral is not differentiable; ` +
|
|
188
|
-
`supply lower/upper bounds for a definite integral.`);
|
|
189
|
-
}
|
|
190
|
-
if (node.over.kind !== 'symbol') {
|
|
191
|
-
throw new TypeError(`bridgeGradientAST: integral 'over' must be a symbol.`);
|
|
192
|
-
}
|
|
193
|
-
const overName = node.over.name;
|
|
194
|
-
if (overName === varName) {
|
|
195
|
-
throw new TypeError(`bridgeGradientAST: cannot differentiate w.r.t. the integration variable '${overName}'.`);
|
|
196
|
-
}
|
|
197
|
-
const lo = walk(node.lower, boundVars);
|
|
198
|
-
const hi = walk(node.upper, boundVars);
|
|
199
|
-
const half = hi.sub(lo).scale(0.5); // (b − a)/2
|
|
200
|
-
const mid = lo.add(hi).scale(0.5); // (a + b)/2
|
|
201
|
-
let sum = null;
|
|
202
|
-
for (const gl of GAUSS_LEGENDRE_16) {
|
|
203
|
-
const xPoint = mid.add(half.scale(gl.node)); // (b−a)/2·ξ + (a+b)/2
|
|
204
|
-
const env = new Map(boundVars);
|
|
205
|
-
env.set(overName, xPoint);
|
|
206
|
-
const term = walk(node.integrand, env).scale(gl.weight);
|
|
207
|
-
sum = sum === null ? term : sum.add(term);
|
|
208
|
-
}
|
|
209
|
-
// GAUSS_LEGENDRE_16 is non-empty, so `sum` is set.
|
|
210
|
-
return half.mul(sum);
|
|
211
|
-
}
|
|
212
|
-
throw new TypeError(`bridgeGradientAST: unsupported node kind '${node.kind}' — the differentiable ` +
|
|
213
|
-
`grammar is symbol + op(+ − * / ^) + transcendental + abs + definite integral. ` +
|
|
214
|
-
`Other encodings (tensor/curvature, bound-less integrals, or physics hidden in ` +
|
|
215
|
-
`a typed-stub symbol) are not exactly differentiable.`);
|
|
216
|
-
};
|
|
217
|
-
return walk(rhs, new Map());
|
|
218
|
-
};
|
|
219
|
-
const xLeaf = Tensor.fromNested(bindings[varName], []);
|
|
220
|
-
const { value, gradient } = reverseGrad(fn, xLeaf);
|
|
221
|
-
return {
|
|
222
|
-
value: value.toNested(),
|
|
223
|
-
gradient: gradient.toNested(),
|
|
224
|
-
};
|
|
123
|
+
const constants = {};
|
|
124
|
+
forEachScalarLeaf(rhs, (leaf) => {
|
|
125
|
+
if (leaf.name === varName)
|
|
126
|
+
return;
|
|
127
|
+
// A literal spelling stays MathTS's literal unless the caller bound that name.
|
|
128
|
+
if (isDecimalLiteral(leaf.name) && !Object.hasOwn(bindings, leaf.name))
|
|
129
|
+
return;
|
|
130
|
+
constants[leaf.name] = resolveConstant(leaf.name, bindings);
|
|
131
|
+
}, { transcendental: true, abs: true });
|
|
132
|
+
const compiled = compileScalarGradient(lowered, { variables: [], parameters: [varName], constants });
|
|
133
|
+
const { values, grad } = compiled.evaluate([], [bindings[varName]]);
|
|
134
|
+
return { value: values[0], gradient: grad[0] };
|
|
225
135
|
}
|
|
226
136
|
/**
|
|
227
137
|
* Convenience wrapper around {@link bridgeGradientAST} that looks the RHS AST up
|
|
@@ -229,7 +139,7 @@ export async function bridgeGradientAST(rhs, varName, bindings) {
|
|
|
229
139
|
*
|
|
230
140
|
* Throws if the id has no encoded RHS in {@link BRIDGE_RHS_BY_ID} (e.g. BE-51/52,
|
|
231
141
|
* which are closed-form evaluators without an AST). If the bridge's RHS is not in
|
|
232
|
-
* the differentiable scalar grammar (a tensor
|
|
142
|
+
* the differentiable scalar grammar (a tensor, integral or curvature encoding), the
|
|
233
143
|
* delegated `bridgeGradientAST` throws the "unsupported node kind" error — use
|
|
234
144
|
* {@link astDifferentiableBridgeIds} to discover which ids are AD-eligible.
|
|
235
145
|
*
|
|
@@ -244,7 +154,7 @@ export function bridgeGradientASTById(bridgeId, varName, bindings) {
|
|
|
244
154
|
}
|
|
245
155
|
return bridgeGradientAST(rhs, varName, bindings);
|
|
246
156
|
}
|
|
247
|
-
/** Whether an AST consists solely of the differentiable scalar grammar (symbol + op(+ − * / ^)). */
|
|
157
|
+
/** Whether an AST consists solely of the differentiable scalar grammar (symbol + op(+ − * / ^) + transcendental + abs). */
|
|
248
158
|
function isDifferentiableScalarAST(node) {
|
|
249
159
|
if (node.kind === 'symbol')
|
|
250
160
|
return true;
|
|
@@ -253,24 +163,16 @@ function isDifferentiableScalarAST(node) {
|
|
|
253
163
|
return false;
|
|
254
164
|
return node.args.every(isDifferentiableScalarAST);
|
|
255
165
|
}
|
|
256
|
-
if (node.kind === 'transcendental')
|
|
166
|
+
if (node.kind === 'transcendental' || node.kind === 'abs')
|
|
257
167
|
return isDifferentiableScalarAST(node.arg);
|
|
258
|
-
if (node.kind === 'abs')
|
|
259
|
-
return isDifferentiableScalarAST(node.arg);
|
|
260
|
-
if (node.kind === 'integral') {
|
|
261
|
-
return (!!node.lower &&
|
|
262
|
-
!!node.upper &&
|
|
263
|
-
node.over.kind === 'symbol' &&
|
|
264
|
-
isDifferentiableScalarAST(node.integrand) &&
|
|
265
|
-
isDifferentiableScalarAST(node.lower) &&
|
|
266
|
-
isDifferentiableScalarAST(node.upper));
|
|
267
|
-
}
|
|
268
168
|
return false;
|
|
269
169
|
}
|
|
270
170
|
/**
|
|
271
171
|
* The catalog bridge ids whose encoded RHS lies entirely in the differentiable
|
|
272
|
-
* scalar grammar
|
|
273
|
-
*
|
|
172
|
+
* scalar grammar. `bridgeGradientASTById` differentiates each of them exactly
|
|
173
|
+
* with respect to any variable that is not in an exponent; a variable in an
|
|
174
|
+
* exponent is refused (`checkExponents`).
|
|
175
|
+
* Bridges encoded with tensor, integral or curvature nodes (or whose physics is
|
|
274
176
|
* hidden behind a typed-stub symbol) are excluded from EXACT differentiation
|
|
275
177
|
* (a stub still differentiates w.r.t. the stub symbol, but not the physics
|
|
276
178
|
* inside it). Returned sorted ascending.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-ast-gradient.js","sourceRoot":"","sources":["../../src/diff/bridge-ast-gradient.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Exact bridge-gradients via reverse-mode AD over the symbolic RHS AST.\n *\n * The catalog's plain-JS evaluators cannot be differentiated by AD (they run\n * raw `Math.*` arithmetic and return a number, which carries no tape; see\n * `bridge-gradient.ts`). But each bridge also carries a faithful symbolic\n * encoding of its RHS (`*_RHS: ExprNode`). This module lowers that scalar AST\n * through `@danielsimonjr/mathts-autograd`'s `TapedTensor` ops — binding the\n * chosen variable to a traced input and every other symbol to a constant tape\n * leaf — so `reverseGrad` returns the EXACT derivative (machine precision), with\n * the plain-JS evaluators left untouched (P8 Decision #1).\n *\n * Scope: the dimensional scalar grammar is `symbol` + `op(+ − * / ^)` (the\n * transcendentals of a bridge are absorbed into typed-stub *symbols*, so they\n * appear as opaque constants here). A bridge encoded with a typed stub therefore\n * differentiates with respect to the stub, not the physics inside it — faithful,\n * fully-expanded encodings (e.g. BE-42 `ℏc³/(8πGM·k_B)`) differentiate exactly.\n * `^` exponents must be constant (the differentiation variable may not appear in\n * an exponent).\n *\n * Loads `@danielsimonjr/mathts-autograd` at the call and throws\n * `EngineCapabilityError` when that import fails.\n *\n * @module diff/bridge-ast-gradient\n */\n\nimport type { ExprNode, TranscendentalFn } from '../dimensional/validator.js';\nimport { constantScope } from '../dimensional/symbolic-constants.js';\nimport { EngineCapabilityError } from '../numerical/errors.js';\nimport { BRIDGE_RHS_BY_ID, parseBridgeId } from '../bridges/rhs-registry.js';\nimport { GAUSS_LEGENDRE_16 } from '../numerical/quadrature.js';\n\n/**\n * Result of {@link bridgeGradientAST}: the bridge's scalar `value` at the\n * supplied point and the exact `gradient` d(value)/d(varName).\n *\n * @public\n */\nexport interface ASTGradientResult {\n readonly value: number;\n readonly gradient: number;\n}\n\n// --- Structural views of the autograd/tensor packages (required dependencies; the\n// dynamic import keeps the AD path off the module's load, and its result is narrowed\n// to the call-site shape). ---\n\ntype TapeHandle = unknown;\n\ninterface TapedScalar {\n readonly tape: TapeHandle;\n add(o: TapedScalar): TapedScalar;\n sub(o: TapedScalar): TapedScalar;\n mul(o: TapedScalar): TapedScalar;\n divide(o: TapedScalar): TapedScalar;\n scale(k: number): TapedScalar;\n pow(k: number): TapedScalar;\n exp(): TapedScalar;\n log(): TapedScalar;\n log2(): TapedScalar;\n log10(): TapedScalar;\n sin(): TapedScalar;\n cos(): TapedScalar;\n tan(): TapedScalar;\n sinh(): TapedScalar;\n cosh(): TapedScalar;\n tanh(): TapedScalar;\n abs(): TapedScalar;\n}\n\n/** Map a transcendental fn name to the TapedTensor method that traces it. */\nfunction applyTranscendental(fn: TranscendentalFn, t: TapedScalar): TapedScalar {\n switch (fn) {\n case 'exp':\n return t.exp();\n case 'ln':\n return t.log();\n case 'log2':\n return t.log2();\n case 'log10':\n return t.log10();\n case 'sin':\n return t.sin();\n case 'cos':\n return t.cos();\n case 'tan':\n return t.tan();\n case 'sinh':\n return t.sinh();\n case 'cosh':\n return t.cosh();\n case 'tanh':\n return t.tanh();\n }\n}\n\ninterface MathTSTensorLike {\n toNested(): unknown;\n}\n\ninterface AutogradModuleLike {\n reverseGrad(\n fn: (x: TapedScalar) => TapedScalar,\n x: MathTSTensorLike,\n cotangent?: MathTSTensorLike,\n ): { value: MathTSTensorLike; gradient: MathTSTensorLike };\n TapedTensor: {\n fromTensorAsInput(t: MathTSTensorLike, tape: TapeHandle): TapedScalar;\n };\n}\n\ninterface TensorModuleLike {\n Tensor: { fromNested(data: number, shape: number[]): MathTSTensorLike };\n}\n\n/**\n * Named physical constants the bridge encodings reference as bare symbols:\n * every registered spelling, from the constant registry, plus π and its\n * registered multiples, so a traced AST evaluates to the SAME number as the\n * numeric evaluator. Callers can override or extend via the `bindings` argument.\n */\nconst NAMED_CONSTANTS: Readonly<Record<string, number>> = constantScope();\n\n/** Resolve a symbol's numeric value: caller bindings → named constants → numeric literal. */\nfunction resolveConstant(\n name: string,\n bindings: Record<string, number>,\n): number {\n if (Object.prototype.hasOwnProperty.call(bindings, name))\n return bindings[name];\n if (Object.prototype.hasOwnProperty.call(NAMED_CONSTANTS, name))\n return NAMED_CONSTANTS[name];\n const asNumber = Number(name);\n if (name.trim() !== '' && Number.isFinite(asNumber)) return asNumber;\n throw new TypeError(\n `bridgeGradientAST: unknown symbol '${name}' — not a binding, a named constant ` +\n `(${Object.keys(NAMED_CONSTANTS).join(', ')}), or a numeric literal. Supply it in bindings.`,\n );\n}\n\n/** Resolve a `^` exponent to a numeric constant expression.\n *\n * The exponent may contain scalar arithmetic over constants/bindings (for\n * example `-1/z`) as long as it is independent of the differentiation\n * variable. Variable exponents require a traced `pow(base, exponent)` op,\n * which the current MathTS tape surface does not expose, so they are rejected\n * explicitly rather than being silently detached from AD.\n */\nfunction resolveExponent(\n node: ExprNode,\n varName: string,\n bindings: Record<string, number>,\n): number {\n if (node.kind === 'symbol') {\n if (node.name === varName) {\n throw new TypeError(\n `bridgeGradientAST: differentiation variable '${varName}' appears as an exponent — ` +\n `variable exponents are not supported (only constant powers).`,\n );\n }\n return resolveConstant(node.name, bindings);\n }\n if (node.kind === 'op') {\n const values = node.args.map((arg) => resolveExponent(arg, varName, bindings));\n if (values.length === 0) {\n throw new TypeError(`bridgeGradientAST: '${node.op}' exponent expression has no operands.`);\n }\n switch (node.op) {\n case '+': return values.reduce((a, b) => a + b);\n case '-': return values.length === 1 ? -values[0] : values.slice(1).reduce((a, b) => a - b, values[0]);\n case '*': return values.reduce((a, b) => a * b);\n case '/': return values.slice(1).reduce((a, b) => a / b, values[0]);\n case '^': return values.slice(1).reduce((a, b) => a ** b, values[0]);\n }\n }\n throw new TypeError(\n `bridgeGradientAST: '^' exponent must be a constant scalar expression, got node kind '${node.kind}'.`,\n );\n}\n\n/**\n * Differentiate a scalar bridge RHS AST with respect to one symbol via\n * reverse-mode AD. Every symbol other than `varName` is resolved to a constant\n * (caller `bindings`, then {@link NAMED_CONSTANTS}, then numeric literal); the\n * `bindings` must contain `varName` (its value sets the point of evaluation).\n *\n * @public\n */\nexport async function bridgeGradientAST(\n rhs: ExprNode,\n varName: string,\n bindings: Record<string, number>,\n): Promise<ASTGradientResult> {\n if (!Object.prototype.hasOwnProperty.call(bindings, varName)) {\n throw new TypeError(\n `bridgeGradientAST: bindings must contain the differentiation variable '${varName}'.`,\n );\n }\n\n let autograd: AutogradModuleLike;\n let tensorMod: TensorModuleLike;\n try {\n // The two modules are typed by the structural views above (the members\n // this lowering calls: reverseGrad, TapedTensor, Tensor.fromNested …).\n // The casts state that those members exist on the imported modules, which\n // their own type declarations guarantee; the full MathTS types are not\n // imported so this file compiles without the autograd types at hand.\n autograd =\n (await import('@danielsimonjr/mathts-autograd')) as unknown as AutogradModuleLike;\n tensorMod =\n (await import('@danielsimonjr/mathts-tensor')) as unknown as TensorModuleLike;\n } catch {\n throw new EngineCapabilityError('mathts-autograd', 'reverseGrad');\n }\n const { reverseGrad, TapedTensor } = autograd;\n const { Tensor } = tensorMod;\n\n // Build the (traced var) → scalar function reverseGrad expects. `x` arrives as\n // a TapedTensor; constants become extra tape leaves (their gradients are\n // computed and ignored — only `x`'s gradient is returned).\n const fn = (x: TapedScalar): TapedScalar => {\n const constLeaf = (v: number): TapedScalar =>\n TapedTensor.fromTensorAsInput(Tensor.fromNested(v, []), x.tape);\n\n // `boundVars` maps an integration variable name to its current (traced)\n // quadrature point; it is checked BEFORE the diff-var / constants so an\n // integration variable correctly shadows an outer symbol of the same name.\n const walk = (node: ExprNode, boundVars: ReadonlyMap<string, TapedScalar>): TapedScalar => {\n if (node.kind === 'symbol') {\n const bound = boundVars.get(node.name);\n if (bound !== undefined) return bound;\n return node.name === varName\n ? x\n : constLeaf(resolveConstant(node.name, bindings));\n }\n if (node.kind === 'op') {\n switch (node.op) {\n case '+':\n return node.args.map((a) => walk(a, boundVars)).reduce((a, b) => a.add(b));\n case '-': {\n const terms = node.args.map((a) => walk(a, boundVars));\n // Unary minus (0 − t); n-ary subtract folds left.\n return terms.length === 1\n ? constLeaf(0).sub(terms[0])\n : terms.reduce((a, b) => a.sub(b));\n }\n case '*':\n return node.args.map((a) => walk(a, boundVars)).reduce((a, b) => a.mul(b));\n case '/':\n return node.args.map((a) => walk(a, boundVars)).reduce((a, b) => a.divide(b));\n case '^':\n return walk(node.args[0], boundVars).pow(\n resolveExponent(node.args[1], varName, bindings),\n );\n default:\n throw new TypeError(\n `bridgeGradientAST: unsupported operator '${node.op}'.`,\n );\n }\n }\n if (node.kind === 'transcendental') {\n return applyTranscendental(node.fn, walk(node.arg, boundVars));\n }\n if (node.kind === 'abs') {\n return walk(node.arg, boundVars).abs();\n }\n if (node.kind === 'integral') {\n // Definite integral via 16-point Gauss–Legendre quadrature, built from\n // traced ops so reverse-mode AD yields the gradient w.r.t. integrand\n // parameters (Leibniz: ∫ ∂f/∂θ) and w.r.t. bounds (∂Q/∂b ≈ f(b)).\n // NOTE: the gradient is EXACT for the quadrature, which APPROXIMATES the\n // true integral for non-polynomial integrands (exact for constant /\n // polynomial-degree ≤ 31 integrands).\n if (!node.lower || !node.upper) {\n throw new TypeError(\n `bridgeGradientAST: an abstract (bound-less) integral is not differentiable; ` +\n `supply lower/upper bounds for a definite integral.`,\n );\n }\n if (node.over.kind !== 'symbol') {\n throw new TypeError(`bridgeGradientAST: integral 'over' must be a symbol.`);\n }\n const overName = node.over.name;\n if (overName === varName) {\n throw new TypeError(\n `bridgeGradientAST: cannot differentiate w.r.t. the integration variable '${overName}'.`,\n );\n }\n const lo = walk(node.lower, boundVars);\n const hi = walk(node.upper, boundVars);\n const half = hi.sub(lo).scale(0.5); // (b − a)/2\n const mid = lo.add(hi).scale(0.5); // (a + b)/2\n let sum: TapedScalar | null = null;\n for (const gl of GAUSS_LEGENDRE_16) {\n const xPoint = mid.add(half.scale(gl.node)); // (b−a)/2·ξ + (a+b)/2\n const env = new Map(boundVars);\n env.set(overName, xPoint);\n const term = walk(node.integrand, env).scale(gl.weight);\n sum = sum === null ? term : sum.add(term);\n }\n // GAUSS_LEGENDRE_16 is non-empty, so `sum` is set.\n return half.mul(sum as TapedScalar);\n }\n throw new TypeError(\n `bridgeGradientAST: unsupported node kind '${node.kind}' — the differentiable ` +\n `grammar is symbol + op(+ − * / ^) + transcendental + abs + definite integral. ` +\n `Other encodings (tensor/curvature, bound-less integrals, or physics hidden in ` +\n `a typed-stub symbol) are not exactly differentiable.`,\n );\n };\n\n return walk(rhs, new Map());\n };\n\n const xLeaf = Tensor.fromNested(bindings[varName], []);\n const { value, gradient } = reverseGrad(fn, xLeaf);\n return {\n value: value.toNested() as number,\n gradient: gradient.toNested() as number,\n };\n}\n\n/**\n * Convenience wrapper around {@link bridgeGradientAST} that looks the RHS AST up\n * by catalog bridge id. `bridgeId` accepts a number, `'42'`, or `'BE-42'`.\n *\n * Throws if the id has no encoded RHS in {@link BRIDGE_RHS_BY_ID} (e.g. BE-51/52,\n * which are closed-form evaluators without an AST). If the bridge's RHS is not in\n * the differentiable scalar grammar (a tensor/integral/curvature encoding), the\n * delegated `bridgeGradientAST` throws the \"unsupported node kind\" error — use\n * {@link astDifferentiableBridgeIds} to discover which ids are AD-eligible.\n *\n * @public\n */\nexport function bridgeGradientASTById(\n bridgeId: number | string,\n varName: string,\n bindings: Record<string, number>\n): Promise<ASTGradientResult> {\n const id = parseBridgeId(bridgeId);\n const rhs = BRIDGE_RHS_BY_ID.get(id);\n if (rhs === undefined) {\n throw new TypeError(\n `bridgeGradientASTById: BE-${id} has no encoded RHS AST in the registry ` +\n `(BE-51/52 are closed-form; ${BRIDGE_RHS_BY_ID.size} bridges have an encoded AST).`\n );\n }\n return bridgeGradientAST(rhs, varName, bindings);\n}\n\n/** Whether an AST consists solely of the differentiable scalar grammar (symbol + op(+ − * / ^)). */\nfunction isDifferentiableScalarAST(node: ExprNode): boolean {\n if (node.kind === 'symbol') return true;\n if (node.kind === 'op') {\n if (!['+', '-', '*', '/', '^'].includes(node.op)) return false;\n return node.args.every(isDifferentiableScalarAST);\n }\n if (node.kind === 'transcendental') return isDifferentiableScalarAST(node.arg);\n if (node.kind === 'abs') return isDifferentiableScalarAST(node.arg);\n if (node.kind === 'integral') {\n return (\n !!node.lower &&\n !!node.upper &&\n node.over.kind === 'symbol' &&\n isDifferentiableScalarAST(node.integrand) &&\n isDifferentiableScalarAST(node.lower) &&\n isDifferentiableScalarAST(node.upper)\n );\n }\n return false;\n}\n\n/**\n * The catalog bridge ids whose encoded RHS lies entirely in the differentiable\n * scalar grammar — i.e. those `bridgeGradientASTById` can differentiate exactly.\n * Bridges encoded with tensor/integral/curvature nodes (or whose physics is\n * hidden behind a typed-stub symbol) are excluded from EXACT differentiation\n * (a stub still differentiates w.r.t. the stub symbol, but not the physics\n * inside it). Returned sorted ascending.\n *\n * @public\n */\nexport function astDifferentiableBridgeIds(): number[] {\n const ids: number[] = [];\n for (const [id, rhs] of BRIDGE_RHS_BY_ID) {\n if (isDifferentiableScalarAST(rhs)) ids.push(id);\n }\n return ids.sort((a, b) => a - b);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bridge-ast-gradient.js","sourceRoot":"","sources":["../../src/diff/bridge-ast-gradient.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Exact bridge-gradients over the symbolic RHS AST.\n *\n * The catalog's plain-JS evaluators cannot be differentiated by AD (they run\n * raw `Math.*` arithmetic and return a number, which carries no tape; see\n * `bridge-gradient.ts`). But each bridge also carries a faithful symbolic\n * encoding of its RHS (`*_RHS: ExprNode`). This module lowers that scalar AST\n * with the MathTS scalar builder and differentiates it with MathTS\n * `compileScalarGradient`: the chosen variable is the one parameter, and every\n * other symbol is a constant. The result is the EXACT derivative (machine\n * precision); the plain-JS evaluators stay untouched (P8 Decision #1).\n *\n * Scope: the scalar grammar is `symbol` + `op(+ − * / ^)` + `transcendental` +\n * `abs`. A bridge encoded with a typed stub differentiates with respect to the\n * stub, not the physics inside it; fully-expanded encodings (e.g. BE-42\n * `ℏc³/(8πGM·k_B)`) differentiate exactly. A `^` exponent must be constant: a\n * UPT pre-check refuses the differentiation variable in an exponent before\n * MathTS sees the tree.\n *\n * A point where the value overflows gives `NaN` for the value and the\n * gradient (MathTS marks the row invalid), not `±Infinity`.\n *\n * @module diff/bridge-ast-gradient\n */\n\nimport { ScalarBuildError } from '@danielsimonjr/mathts-expression';\nimport { compileScalarGradient } from '@danielsimonjr/mathts-functions';\nimport type { ExprNode } from '../dimensional/validator.js';\nimport { forEachScalarLeaf, isDecimalLiteral } from '../dimensional/ast-leaves.js';\nimport { constantScope } from '../dimensional/symbolic-constants.js';\nimport { toScalarNode } from '../dimensional/scalar-lowering.js';\nimport { BRIDGE_RHS_BY_ID, parseBridgeId } from '../bridges/rhs-registry.js';\n\n/**\n * Result of {@link bridgeGradientAST}: the bridge's scalar `value` at the\n * supplied point and the exact `gradient` d(value)/d(varName).\n *\n * @public\n */\nexport interface ASTGradientResult {\n readonly value: number;\n readonly gradient: number;\n}\n\n/**\n * Named physical constants the bridge encodings reference as bare symbols:\n * every registered spelling, from the constant registry, plus π and its\n * registered multiples, so the AST evaluates to the SAME number as the\n * numeric evaluator. Callers can override or extend via the `bindings` argument.\n */\nconst NAMED_CONSTANTS: Readonly<Record<string, number>> = constantScope();\n\n/** Resolve a symbol's numeric value: caller bindings → named constants → numeric literal. */\nfunction resolveConstant(\n name: string,\n bindings: Record<string, number>,\n): number {\n if (Object.hasOwn(bindings, name))\n return bindings[name];\n if (Object.hasOwn(NAMED_CONSTANTS, name))\n return NAMED_CONSTANTS[name];\n const asNumber = Number(name);\n if (name.trim() !== '' && Number.isFinite(asNumber)) return asNumber;\n throw new TypeError(\n `bridgeGradientAST: unknown symbol '${name}' — not a binding, a named constant ` +\n `(${Object.keys(NAMED_CONSTANTS).join(', ')}), or a numeric literal. Supply it in bindings.`,\n );\n}\n\n/** Resolve a `^` exponent to a numeric constant expression.\n *\n * The exponent may contain scalar arithmetic over constants/bindings (for\n * example `-1/z`) as long as it is independent of the differentiation\n * variable. UPT keeps the constant-power contract, so the differentiation\n * variable in an exponent is refused before MathTS reads the tree.\n */\nfunction resolveExponent(\n node: ExprNode,\n varName: string,\n bindings: Record<string, number>,\n): number {\n if (node.kind === 'symbol') {\n if (node.name === varName) {\n throw new TypeError(\n `bridgeGradientAST: differentiation variable '${varName}' appears as an exponent — ` +\n `variable exponents are not supported (only constant powers).`,\n );\n }\n return resolveConstant(node.name, bindings);\n }\n if (node.kind === 'op') {\n const values = node.args.map((arg) => resolveExponent(arg, varName, bindings));\n if (values.length === 0) {\n throw new TypeError(`bridgeGradientAST: '${node.op}' exponent expression has no operands.`);\n }\n switch (node.op) {\n case '+': return values.reduce((a, b) => a + b);\n case '-': return values.length === 1 ? -values[0] : values.slice(1).reduce((a, b) => a - b, values[0]);\n case '*': return values.reduce((a, b) => a * b);\n case '/': return values.slice(1).reduce((a, b) => a / b, values[0]);\n case '^': return values.slice(1).reduce((a, b) => a ** b, values[0]);\n }\n }\n throw new TypeError(\n `bridgeGradientAST: '^' exponent must be a constant scalar expression, got node kind '${node.kind}'.`,\n );\n}\n\n/**\n * Refuse the differentiation variable in any `^` exponent, and check that every\n * exponent is a constant scalar expression. MathTS would differentiate a\n * variable exponent; UPT keeps the constant-power contract.\n */\nfunction checkExponents(node: ExprNode, varName: string, bindings: Record<string, number>): void {\n if (node.kind === 'op') {\n if (node.op === '^' && node.args.length === 2) resolveExponent(node.args[1], varName, bindings);\n for (const arg of node.args) checkExponents(arg, varName, bindings);\n } else if (node.kind === 'transcendental' || node.kind === 'abs') {\n checkExponents(node.arg, varName, bindings);\n }\n}\n\n/**\n * Differentiate a scalar bridge RHS AST with respect to one symbol through\n * MathTS `compileScalarGradient`. Every symbol other than `varName` is resolved\n * to a constant (caller `bindings`, then {@link NAMED_CONSTANTS}, then numeric\n * literal); the `bindings` must contain `varName` (its value sets the point of\n * evaluation).\n *\n * @throws TypeError when `varName` is not bound, a symbol cannot be resolved,\n * `varName` appears in an exponent, or a node kind is outside the scalar grammar.\n * @public\n */\nexport function bridgeGradientAST(\n rhs: ExprNode,\n varName: string,\n bindings: Record<string, number>,\n): ASTGradientResult {\n if (!Object.hasOwn(bindings, varName)) {\n throw new TypeError(\n `bridgeGradientAST: bindings must contain the differentiation variable '${varName}'.`,\n );\n }\n checkExponents(rhs, varName, bindings);\n\n let lowered: ReturnType<typeof toScalarNode>;\n try {\n lowered = toScalarNode(rhs);\n } catch (err) {\n if (!(err instanceof ScalarBuildError)) throw err;\n throw new TypeError(\n `bridgeGradientAST: unsupported node kind — ${err.message}. The differentiable grammar is ` +\n `symbol + op(+ − * / ^) + transcendental + abs. Other encodings (tensor/curvature, integrals, ` +\n `or physics hidden in a typed-stub symbol) are not exactly differentiable.`,\n ); }\n\n const constants: Record<string, number> = {};\n forEachScalarLeaf(\n rhs,\n (leaf) => {\n if (leaf.name === varName) return;\n // A literal spelling stays MathTS's literal unless the caller bound that name.\n if (isDecimalLiteral(leaf.name) && !Object.hasOwn(bindings, leaf.name)) return;\n constants[leaf.name] = resolveConstant(leaf.name, bindings);\n },\n { transcendental: true, abs: true },\n );\n\n const compiled = compileScalarGradient(lowered, { variables: [], parameters: [varName], constants });\n const { values, grad } = compiled.evaluate([], [bindings[varName]]);\n return { value: values[0]!, gradient: grad[0]! };\n}\n\n/**\n * Convenience wrapper around {@link bridgeGradientAST} that looks the RHS AST up\n * by catalog bridge id. `bridgeId` accepts a number, `'42'`, or `'BE-42'`.\n *\n * Throws if the id has no encoded RHS in {@link BRIDGE_RHS_BY_ID} (e.g. BE-51/52,\n * which are closed-form evaluators without an AST). If the bridge's RHS is not in\n * the differentiable scalar grammar (a tensor, integral or curvature encoding), the\n * delegated `bridgeGradientAST` throws the \"unsupported node kind\" error — use\n * {@link astDifferentiableBridgeIds} to discover which ids are AD-eligible.\n *\n * @public\n */\nexport function bridgeGradientASTById(\n bridgeId: number | string,\n varName: string,\n bindings: Record<string, number>\n): ASTGradientResult {\n const id = parseBridgeId(bridgeId);\n const rhs = BRIDGE_RHS_BY_ID.get(id);\n if (rhs === undefined) {\n throw new TypeError(\n `bridgeGradientASTById: BE-${id} has no encoded RHS AST in the registry ` +\n `(BE-51/52 are closed-form; ${BRIDGE_RHS_BY_ID.size} bridges have an encoded AST).`\n );\n }\n return bridgeGradientAST(rhs, varName, bindings);\n}\n\n/** Whether an AST consists solely of the differentiable scalar grammar (symbol + op(+ − * / ^) + transcendental + abs). */\nfunction isDifferentiableScalarAST(node: ExprNode): boolean {\n if (node.kind === 'symbol') return true;\n if (node.kind === 'op') {\n if (!['+', '-', '*', '/', '^'].includes(node.op)) return false;\n return node.args.every(isDifferentiableScalarAST);\n }\n if (node.kind === 'transcendental' || node.kind === 'abs') return isDifferentiableScalarAST(node.arg);\n return false;\n}\n\n/**\n * The catalog bridge ids whose encoded RHS lies entirely in the differentiable\n * scalar grammar. `bridgeGradientASTById` differentiates each of them exactly\n * with respect to any variable that is not in an exponent; a variable in an\n * exponent is refused (`checkExponents`).\n * Bridges encoded with tensor, integral or curvature nodes (or whose physics is\n * hidden behind a typed-stub symbol) are excluded from EXACT differentiation\n * (a stub still differentiates w.r.t. the stub symbol, but not the physics\n * inside it). Returned sorted ascending.\n *\n * @public\n */\nexport function astDifferentiableBridgeIds(): number[] {\n const ids: number[] = [];\n for (const [id, rhs] of BRIDGE_RHS_BY_ID) {\n if (isDifferentiableScalarAST(rhs)) ids.push(id);\n }\n return ids.sort((a, b) => a - b);\n}\n"]}
|
|
@@ -46,6 +46,14 @@ export interface BridgeDiffSpec<Input> {
|
|
|
46
46
|
readonly defaults: Partial<Input>;
|
|
47
47
|
/** The bridge's scalar evaluator. */
|
|
48
48
|
readonly evaluate: (input: Input) => number;
|
|
49
|
+
/**
|
|
50
|
+
* The smallest magnitude the relative step is taken against, per parameter:
|
|
51
|
+
* for `|x| < floor` the step is `floor·relStep`. A parameter that is zero at
|
|
52
|
+
* a point of interest (an eccentricity on a circular orbit) needs its scale
|
|
53
|
+
* stated here, because a relative step at zero is no step. A parameter not
|
|
54
|
+
* named here has no floor: the step is `|x|·relStep`, and `x = 0` is refused.
|
|
55
|
+
*/
|
|
56
|
+
readonly stepFloors?: Readonly<Partial<Record<keyof Input & string, number>>>;
|
|
49
57
|
}
|
|
50
58
|
/**
|
|
51
59
|
* Result of {@link bridgeGradientNumerical}: the bridge's scalar `value`
|
|
@@ -63,12 +71,17 @@ export interface BridgeNumericalGradientResult {
|
|
|
63
71
|
* way to differentiate the catalog's plain-JS closed forms without
|
|
64
72
|
* rewriting them. Needs no engine and is synchronous.
|
|
65
73
|
*
|
|
66
|
-
* For each differentiable param with value `x` it uses
|
|
67
|
-
* `h = max(|x|,
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* `
|
|
71
|
-
*
|
|
74
|
+
* For each differentiable param with value `x` it uses the relative step
|
|
75
|
+
* `h = max(|x|, floor)·cbrt(eps)`, where `floor` is the spec's
|
|
76
|
+
* {@link BridgeDiffSpec.stepFloors} entry for that param (0 when the spec
|
|
77
|
+
* states none), and the ACTUAL representable denominator
|
|
78
|
+
* `dx = (x + h) − (x − h)` (`numerical/finite-difference`) — so the
|
|
79
|
+
* perturbation survives floating-point rounding at astrophysical scales
|
|
80
|
+
* (`M ≈ 2e30 kg`) and stays relative at atomic ones (a charge of 1.6e-19
|
|
81
|
+
* takes a step of 1e-24, not the 6e-6 an absolute floor of 1 gave). A param
|
|
82
|
+
* at exactly 0 with no stated floor is refused with a `RangeError`: there is
|
|
83
|
+
* no scale to step by. The supplied `params` must contain every key in
|
|
84
|
+
* `spec.paramNames`; non-differentiable fields come from `spec.defaults`.
|
|
72
85
|
*
|
|
73
86
|
* @public
|
|
74
87
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-gradient.d.ts","sourceRoot":"","sources":["../../src/diff/bridge-gradient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"bridge-gradient.d.ts","sourceRoot":"","sources":["../../src/diff/bridge-gradient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc,CAAC,KAAK;IACnC,2GAA2G;IAC3G,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC;IACzD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAClC,qCAAqC;IACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC;IAC5C;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;CAC/E;AAED;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AAUD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAC3C,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,EAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACnC,6BAA6B,CAiD/B"}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*
|
|
19
19
|
* @module diff/bridge-gradient
|
|
20
20
|
*/
|
|
21
|
+
import { centralPartial } from '../numerical/finite-difference.js';
|
|
21
22
|
/**
|
|
22
23
|
* Relative step for central differences: `cbrt(eps)` balances the `O(h²)`
|
|
23
24
|
* truncation error against the `O(eps/h)` round-off error (the central-diff
|
|
@@ -30,12 +31,17 @@ const CENTRAL_DIFF_REL_STEP = Math.cbrt(Number.EPSILON); // ≈ 6.06e-6
|
|
|
30
31
|
* way to differentiate the catalog's plain-JS closed forms without
|
|
31
32
|
* rewriting them. Needs no engine and is synchronous.
|
|
32
33
|
*
|
|
33
|
-
* For each differentiable param with value `x` it uses
|
|
34
|
-
* `h = max(|x|,
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* `
|
|
38
|
-
*
|
|
34
|
+
* For each differentiable param with value `x` it uses the relative step
|
|
35
|
+
* `h = max(|x|, floor)·cbrt(eps)`, where `floor` is the spec's
|
|
36
|
+
* {@link BridgeDiffSpec.stepFloors} entry for that param (0 when the spec
|
|
37
|
+
* states none), and the ACTUAL representable denominator
|
|
38
|
+
* `dx = (x + h) − (x − h)` (`numerical/finite-difference`) — so the
|
|
39
|
+
* perturbation survives floating-point rounding at astrophysical scales
|
|
40
|
+
* (`M ≈ 2e30 kg`) and stays relative at atomic ones (a charge of 1.6e-19
|
|
41
|
+
* takes a step of 1e-24, not the 6e-6 an absolute floor of 1 gave). A param
|
|
42
|
+
* at exactly 0 with no stated floor is refused with a `RangeError`: there is
|
|
43
|
+
* no scale to step by. The supplied `params` must contain every key in
|
|
44
|
+
* `spec.paramNames`; non-differentiable fields come from `spec.defaults`.
|
|
39
45
|
*
|
|
40
46
|
* @public
|
|
41
47
|
*/
|
|
@@ -70,11 +76,13 @@ export function bridgeGradientNumerical(spec, params, opts) {
|
|
|
70
76
|
const gradient = {};
|
|
71
77
|
for (const k of spec.paramNames) {
|
|
72
78
|
const x = params[k];
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
const floor = spec.stepFloors?.[k] ?? 0;
|
|
80
|
+
const h = Math.max(Math.abs(x), floor) * relStep;
|
|
81
|
+
if (!(h > 0)) {
|
|
82
|
+
throw new RangeError(`bridgeGradientNumerical: ${spec.bridgeId}: param '${k}' is ${x} and the spec states no stepFloors['${k}'], ` +
|
|
83
|
+
`so a relative central-difference step has no scale; state the parameter's scale in the spec's stepFloors.`);
|
|
84
|
+
}
|
|
85
|
+
gradient[k] = centralPartial((p) => spec.evaluate(buildInput({ key: k, val: p[k] })), { [k]: x }, k, h);
|
|
78
86
|
}
|
|
79
87
|
return { value, gradient };
|
|
80
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-gradient.js","sourceRoot":"","sources":["../../src/diff/bridge-gradient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"bridge-gradient.js","sourceRoot":"","sources":["../../src/diff/bridge-gradient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAoDnE;;;;;GAKG;AACH,MAAM,qBAAqB,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY;AAErE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAA2B,EAC3B,MAA8B,EAC9B,IAAoC;IAEpC,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,qBAAqB,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,UAAU,CAClB,4BAA4B,IAAI,CAAC,QAAQ,mDAAmD,OAAO,GAAG;YACtG,6FAA6F,CAC9F,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,SAAS,CACjB,4BAA4B,IAAI,CAAC,QAAQ,kCAAkC,CAAC,IAAI;gBAChF,QAAQ,MAAM,CAAC,CAAC,CAAC,gEAAgE,CAClF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,oEAAoE;IACpE,0EAA0E;IAC1E,uEAAuE;IACvE,yEAAyE;IACzE,MAAM,UAAU,GAAG,CAAC,QAAuC,EAAS,EAAE;QACpE,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,EAA6B,CAAC;QAC9D,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU;YAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACtD,IAAI,QAAQ;YAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC;QACjD,OAAO,KAAyB,CAAC;IACnC,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAE1C,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC;QACjD,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACb,MAAM,IAAI,UAAU,CAClB,4BAA4B,IAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,CAAC,uCAAuC,CAAC,MAAM;gBAC7G,2GAA2G,CAC5G,CAAC;QACJ,CAAC;QACD,QAAQ,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3G,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["/**\n * Bridge-parameter differentiation by central finite differences.\n *\n * A {@link BridgeDiffSpec} wraps one catalog closed form (a plain-JS scalar\n * function over a named-field struct) and names which fields vary.\n * {@link bridgeGradientNumerical} perturbs those fields and returns the\n * gradient keyed by field name.\n *\n * There is no engine-AD path over a spec. `evaluate` returns a `number`, and\n * a number carries no autograd tape, so reverse- or forward-mode AD of a spec\n * is unreachable by construction; the function that once offered it\n * (`bridgeGradient`) threw for every shipped spec and was removed. The exact\n * AD path is {@link bridgeGradientAST} in `bridge-ast-gradient.ts`, which\n * lowers the bridge's symbolic RHS through `@danielsimonjr/mathts-autograd`.\n *\n * This module lives in `src/diff/` (P8 Decision #1), not in `src/bridges/`,\n * so the catalog closed forms stay untouched.\n *\n * @module diff/bridge-gradient\n */\n\nimport { centralPartial } from '../numerical/finite-difference.js';\n\n/**\n * Specification of a differentiable bridge: which parameters can vary, in\n * what order the gradient reports them, the fixed inputs, and the bridge's\n * scalar evaluator.\n *\n * `paramNames` is the report order. For a Shapiro-delay spec with\n * `paramNames: ['M_kg', 'R_far_m', 'R_near_m']`, the gradient returned by\n * `bridgeGradientNumerical` has keys in that insertion order.\n *\n * @public\n */\nexport interface BridgeDiffSpec<Input> {\n /** Catalog id used in error messages (for example the relation that uses the covariant-eikonal method). */\n readonly bridgeId: string;\n /** Display name (e.g., 'Shapiro time delay'). */\n readonly name: string;\n /**\n * Which Input keys vary, in report order. All names must be present in the\n * frozen `Input` struct as `number`-valued keys.\n */\n readonly paramNames: ReadonlyArray<keyof Input & string>;\n /**\n * The non-differentiable input fields (those NOT in `paramNames`). The\n * evaluator receives `defaults` merged with the varying params.\n */\n readonly defaults: Partial<Input>;\n /** The bridge's scalar evaluator. */\n readonly evaluate: (input: Input) => number;\n /**\n * The smallest magnitude the relative step is taken against, per parameter:\n * for `|x| < floor` the step is `floor·relStep`. A parameter that is zero at\n * a point of interest (an eccentricity on a circular orbit) needs its scale\n * stated here, because a relative step at zero is no step. A parameter not\n * named here has no floor: the step is `|x|·relStep`, and `x = 0` is refused.\n */\n readonly stepFloors?: Readonly<Partial<Record<keyof Input & string, number>>>;\n}\n\n/**\n * Result of {@link bridgeGradientNumerical}: the bridge's scalar `value`\n * at the supplied point, plus the `gradient` of partial derivatives keyed\n * by `paramName` (insertion follows `spec.paramNames` order).\n *\n * @public\n */\nexport interface BridgeNumericalGradientResult {\n readonly value: number;\n readonly gradient: Readonly<Record<string, number>>;\n}\n\n/**\n * Relative step for central differences: `cbrt(eps)` balances the `O(h²)`\n * truncation error against the `O(eps/h)` round-off error (the central-diff\n * optimum). `sqrt(eps)` — the FORWARD-diff optimum — would leave precision on\n * the table for central differences.\n */\nconst CENTRAL_DIFF_REL_STEP = Math.cbrt(Number.EPSILON); // ≈ 6.06e-6\n\n/**\n * Gradient of a bridge evaluator by **central finite differences** — the\n * way to differentiate the catalog's plain-JS closed forms without\n * rewriting them. Needs no engine and is synchronous.\n *\n * For each differentiable param with value `x` it uses the relative step\n * `h = max(|x|, floor)·cbrt(eps)`, where `floor` is the spec's\n * {@link BridgeDiffSpec.stepFloors} entry for that param (0 when the spec\n * states none), and the ACTUAL representable denominator\n * `dx = (x + h) − (x − h)` (`numerical/finite-difference`) — so the\n * perturbation survives floating-point rounding at astrophysical scales\n * (`M ≈ 2e30 kg`) and stays relative at atomic ones (a charge of 1.6e-19\n * takes a step of 1e-24, not the 6e-6 an absolute floor of 1 gave). A param\n * at exactly 0 with no stated floor is refused with a `RangeError`: there is\n * no scale to step by. The supplied `params` must contain every key in\n * `spec.paramNames`; non-differentiable fields come from `spec.defaults`.\n *\n * @public\n */\nexport function bridgeGradientNumerical<Input>(\n spec: BridgeDiffSpec<Input>,\n params: Record<string, number>,\n opts?: { readonly relStep?: number },\n): BridgeNumericalGradientResult {\n const relStep = opts?.relStep ?? CENTRAL_DIFF_REL_STEP;\n if (!Number.isFinite(relStep) || relStep <= 0) {\n throw new RangeError(\n `bridgeGradientNumerical: ${spec.bridgeId}: relStep must be a positive finite number, got ${relStep} ` +\n `(a zero/non-finite step collapses the central-difference denominator to 0 → NaN gradients).`,\n );\n }\n\n // Every paramName must be a FINITE number. (`typeof NaN === 'number'`, so a\n // bare typeof check let NaN/∞ flow into a silently non-finite gradient.)\n for (const k of spec.paramNames) {\n if (!Number.isFinite(params[k])) {\n throw new TypeError(\n `bridgeGradientNumerical: ${spec.bridgeId}: missing or non-finite param '${k}' ` +\n `(got ${params[k]}). All paramNames must be finite numbers in the params object.`,\n );\n }\n }\n\n // Build the full Input struct (defaults + differentiable params), with an\n // optional single-param override for the perturbed evaluations. The\n // `Input` generic has no runtime schema: `spec.paramNames` is declared as\n // keys of `Input`, and `defaults` is a `Partial<Input>`, so the merged\n // record is an `Input` by the spec's own contract; the cast states that.\n const buildInput = (override?: { key: string; val: number }): Input => {\n const input = { ...spec.defaults } as Record<string, unknown>;\n for (const k of spec.paramNames) input[k] = params[k];\n if (override) input[override.key] = override.val;\n return input as unknown as Input;\n };\n\n const value = spec.evaluate(buildInput());\n\n const gradient: Record<string, number> = {};\n for (const k of spec.paramNames) {\n const x = params[k];\n const floor = spec.stepFloors?.[k] ?? 0;\n const h = Math.max(Math.abs(x), floor) * relStep;\n if (!(h > 0)) {\n throw new RangeError(\n `bridgeGradientNumerical: ${spec.bridgeId}: param '${k}' is ${x} and the spec states no stepFloors['${k}'], ` +\n `so a relative central-difference step has no scale; state the parameter's scale in the spec's stepFloors.`,\n );\n }\n gradient[k] = centralPartial((p) => spec.evaluate(buildInput({ key: k, val: p[k]! })), { [k]: x }, k, h);\n }\n\n return { value, gradient };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-specs.d.ts","sourceRoot":"","sources":["../../src/diff/bridge-specs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAGnE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAKlE;AAsBD,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,+GAA+G;AAC/G,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,mGAAmG;IACnG,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,uFAAuF;AACvF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAUD,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,YAAY,CAM3D,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,uBAAuB,EAAE,cAAc,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"bridge-specs.d.ts","sourceRoot":"","sources":["../../src/diff/bridge-specs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAGnE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAKlE;AAsBD,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,+GAA+G;AAC/G,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,mGAAmG;IACnG,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,uFAAuF;AACvF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAUD,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,YAAY,CAM3D,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,uBAAuB,EAAE,cAAc,CAAC,eAAe,CASnE,CAAC;AAEF,2DAA2D;AAC3D,eAAO,MAAM,wBAAwB,EAAE,cAAc,CAAC,YAAY,CAMjE,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC,gBAAgB,CAMlE,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,wBAAwB,0IAK3B,CAAC"}
|
|
@@ -60,6 +60,9 @@ export const PERIHELION_ADVANCE_DIFF = {
|
|
|
60
60
|
paramNames: ['M_kg', 'a_m', 'eccentricity'],
|
|
61
61
|
defaults: {},
|
|
62
62
|
evaluate: (input) => evaluateAliased(perihelion, input),
|
|
63
|
+
// The eccentricity is a dimensionless number in [0, 1): its scale is 1, so a circular orbit
|
|
64
|
+
// (eccentricity 0) still takes the step 1·∛ε, the step every orbit took before the floor was stated.
|
|
65
|
+
stepFloors: { eccentricity: 1 },
|
|
63
66
|
};
|
|
64
67
|
/** Hawking temperature. Differentiable in mass. @public */
|
|
65
68
|
export const HAWKING_TEMPERATURE_DIFF = {
|