universal-physics-tensor 10.0.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/bin/upt.mjs +13 -1
- package/data/atlas/atlas.json +25 -25
- package/data/atlas/atlas.jsonld +1 -1
- package/data/atlas/diffusion.json +6 -6
- package/data/atlas/oscillators.json +7 -7
- package/data/atlas/waves.json +14 -14
- package/data/atlas/witness-results.json +11 -11
- package/data/bridge-catalog.json +371 -228
- package/data/bridge-catalog.schema.json +45 -7
- package/dist/atlas/applicability.d.ts.map +1 -1
- package/dist/atlas/applicability.js +21 -15
- package/dist/atlas/applicability.js.map +1 -1
- package/dist/atlas/benchmark/hybrid-retrieval.d.ts +9 -1
- package/dist/atlas/benchmark/hybrid-retrieval.d.ts.map +1 -1
- package/dist/atlas/benchmark/hybrid-retrieval.js +15 -13
- package/dist/atlas/benchmark/hybrid-retrieval.js.map +1 -1
- package/dist/atlas/benchmark/loader.js +2 -2
- package/dist/atlas/benchmark/loader.js.map +1 -1
- package/dist/atlas/benchmark/stats.d.ts +2 -2
- package/dist/atlas/benchmark/stats.d.ts.map +1 -1
- package/dist/atlas/benchmark/stats.js +15 -7
- package/dist/atlas/benchmark/stats.js.map +1 -1
- package/dist/atlas/catalog-formal-ref.d.ts +26 -3
- package/dist/atlas/catalog-formal-ref.d.ts.map +1 -1
- package/dist/atlas/catalog-formal-ref.js +52 -5
- package/dist/atlas/catalog-formal-ref.js.map +1 -1
- package/dist/atlas/chain-pipeline.d.ts.map +1 -1
- package/dist/atlas/chain-pipeline.js +7 -8
- package/dist/atlas/chain-pipeline.js.map +1 -1
- package/dist/atlas/diffusion/bridges-closure.d.ts +0 -4
- package/dist/atlas/diffusion/bridges-closure.d.ts.map +1 -1
- package/dist/atlas/diffusion/bridges-closure.js +8 -12
- package/dist/atlas/diffusion/bridges-closure.js.map +1 -1
- package/dist/atlas/diffusion/bridges.d.ts.map +1 -1
- package/dist/atlas/diffusion/bridges.js +27 -39
- package/dist/atlas/diffusion/bridges.js.map +1 -1
- package/dist/atlas/diffusion/dimensions.d.ts +6 -14
- package/dist/atlas/diffusion/dimensions.d.ts.map +1 -1
- package/dist/atlas/diffusion/dimensions.js +8 -16
- package/dist/atlas/diffusion/dimensions.js.map +1 -1
- package/dist/atlas/diffusion/models.d.ts +3 -3
- package/dist/atlas/diffusion/models.d.ts.map +1 -1
- package/dist/atlas/diffusion/models.js +5 -10
- package/dist/atlas/diffusion/models.js.map +1 -1
- package/dist/atlas/diffusion/numerics.d.ts +16 -4
- package/dist/atlas/diffusion/numerics.d.ts.map +1 -1
- package/dist/atlas/diffusion/numerics.js +38 -24
- package/dist/atlas/diffusion/numerics.js.map +1 -1
- package/dist/atlas/link-prediction.d.ts +106 -3
- package/dist/atlas/link-prediction.d.ts.map +1 -1
- package/dist/atlas/link-prediction.js +212 -66
- package/dist/atlas/link-prediction.js.map +1 -1
- package/dist/atlas/oscillators/bridges-coarse.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-coarse.js +7 -11
- package/dist/atlas/oscillators/bridges-coarse.js.map +1 -1
- package/dist/atlas/oscillators/bridges-exact.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-exact.js +6 -7
- package/dist/atlas/oscillators/bridges-exact.js.map +1 -1
- package/dist/atlas/oscillators/bridges-limits.d.ts +3 -16
- package/dist/atlas/oscillators/bridges-limits.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-limits.js +23 -34
- package/dist/atlas/oscillators/bridges-limits.js.map +1 -1
- package/dist/atlas/oscillators/dimensions.d.ts +9 -21
- package/dist/atlas/oscillators/dimensions.d.ts.map +1 -1
- package/dist/atlas/oscillators/dimensions.js +9 -21
- package/dist/atlas/oscillators/dimensions.js.map +1 -1
- package/dist/atlas/oscillators/limit-witnesses.d.ts +2 -2
- package/dist/atlas/oscillators/limit-witnesses.d.ts.map +1 -1
- package/dist/atlas/oscillators/limit-witnesses.js +17 -15
- package/dist/atlas/oscillators/limit-witnesses.js.map +1 -1
- package/dist/atlas/oscillators/models.d.ts.map +1 -1
- package/dist/atlas/oscillators/models.js +2 -6
- package/dist/atlas/oscillators/models.js.map +1 -1
- package/dist/atlas/oscillators/pendulum-motion.d.ts +29 -6
- package/dist/atlas/oscillators/pendulum-motion.d.ts.map +1 -1
- package/dist/atlas/oscillators/pendulum-motion.js +60 -40
- package/dist/atlas/oscillators/pendulum-motion.js.map +1 -1
- package/dist/atlas/oscillators/phase-translation.d.ts +0 -11
- package/dist/atlas/oscillators/phase-translation.d.ts.map +1 -1
- package/dist/atlas/oscillators/phase-translation.js +3 -4
- package/dist/atlas/oscillators/phase-translation.js.map +1 -1
- package/dist/atlas/oscillators/position-translation.d.ts +68 -7
- package/dist/atlas/oscillators/position-translation.d.ts.map +1 -1
- package/dist/atlas/oscillators/position-translation.js +123 -12
- package/dist/atlas/oscillators/position-translation.js.map +1 -1
- package/dist/atlas/oscillators/rejections.d.ts +0 -2
- package/dist/atlas/oscillators/rejections.d.ts.map +1 -1
- package/dist/atlas/oscillators/rejections.js +0 -7
- package/dist/atlas/oscillators/rejections.js.map +1 -1
- package/dist/atlas/physjs-entries.generated.d.ts +25 -24
- package/dist/atlas/physjs-entries.generated.d.ts.map +1 -1
- package/dist/atlas/physjs-entries.generated.js +25 -24
- package/dist/atlas/physjs-entries.generated.js.map +1 -1
- package/dist/atlas/physjs-ref.d.ts +34 -31
- package/dist/atlas/physjs-ref.d.ts.map +1 -1
- package/dist/atlas/physjs-ref.js +55 -53
- package/dist/atlas/physjs-ref.js.map +1 -1
- package/dist/atlas/physjs-reviewed.d.ts +1 -1
- package/dist/atlas/physjs-reviewed.js +15 -15
- package/dist/atlas/physjs-reviewed.js.map +1 -1
- package/dist/atlas/poster/statements.d.ts +0 -19
- package/dist/atlas/poster/statements.d.ts.map +1 -1
- package/dist/atlas/poster/statements.js +1 -1
- package/dist/atlas/poster/statements.js.map +1 -1
- package/dist/atlas/proof-target.d.ts +1 -1
- package/dist/atlas/proof-target.js +1 -1
- package/dist/atlas/proof-target.js.map +1 -1
- package/dist/atlas/regime.d.ts +1 -1
- package/dist/atlas/regime.d.ts.map +1 -1
- package/dist/atlas/regime.js +1 -1
- package/dist/atlas/regime.js.map +1 -1
- package/dist/atlas/text-overlap.d.ts +23 -0
- package/dist/atlas/text-overlap.d.ts.map +1 -0
- package/dist/atlas/text-overlap.js +41 -0
- package/dist/atlas/text-overlap.js.map +1 -0
- package/dist/atlas/waves/bridges-closure.d.ts.map +1 -1
- package/dist/atlas/waves/bridges-closure.js +2 -6
- package/dist/atlas/waves/bridges-closure.js.map +1 -1
- package/dist/atlas/waves/bridges.d.ts.map +1 -1
- package/dist/atlas/waves/bridges.js +32 -48
- package/dist/atlas/waves/bridges.js.map +1 -1
- package/dist/atlas/waves/models.d.ts +5 -6
- package/dist/atlas/waves/models.d.ts.map +1 -1
- package/dist/atlas/waves/models.js +7 -13
- package/dist/atlas/waves/models.js.map +1 -1
- package/dist/atlas/waves/numerics.d.ts.map +1 -1
- package/dist/atlas/waves/numerics.js +10 -3
- package/dist/atlas/waves/numerics.js.map +1 -1
- package/dist/atlas/witness-numeric.d.ts +30 -0
- package/dist/atlas/witness-numeric.d.ts.map +1 -1
- package/dist/atlas/witness-numeric.js +53 -0
- package/dist/atlas/witness-numeric.js.map +1 -1
- package/dist/atlas/witness-specs.d.ts.map +1 -1
- package/dist/atlas/witness-specs.js +19 -0
- package/dist/atlas/witness-specs.js.map +1 -1
- package/dist/atlas/witness-symbolic.d.ts +75 -3
- package/dist/atlas/witness-symbolic.d.ts.map +1 -1
- package/dist/atlas/witness-symbolic.js +116 -10
- package/dist/atlas/witness-symbolic.js.map +1 -1
- package/dist/bridges/catalog-load.d.ts.map +1 -1
- package/dist/bridges/catalog-load.js +13 -8
- package/dist/bridges/catalog-load.js.map +1 -1
- package/dist/bridges/catalog-types.d.ts +26 -2
- package/dist/bridges/catalog-types.d.ts.map +1 -1
- package/dist/bridges/catalog-types.js +11 -1
- package/dist/bridges/catalog-types.js.map +1 -1
- package/dist/bridges/evaluation-errors.d.ts +31 -1
- package/dist/bridges/evaluation-errors.d.ts.map +1 -1
- package/dist/bridges/evaluation-errors.js +20 -2
- package/dist/bridges/evaluation-errors.js.map +1 -1
- package/dist/bridges/evaluator-inputs.d.ts.map +1 -1
- package/dist/bridges/evaluator-inputs.js +7 -5
- package/dist/bridges/evaluator-inputs.js.map +1 -1
- package/dist/bridges/evaluators.d.ts.map +1 -1
- package/dist/bridges/evaluators.js +27 -12
- package/dist/bridges/evaluators.js.map +1 -1
- package/dist/bridges/expr-parse.d.ts +11 -0
- package/dist/bridges/expr-parse.d.ts.map +1 -1
- package/dist/bridges/expr-parse.js +14 -5
- package/dist/bridges/expr-parse.js.map +1 -1
- package/dist/bridges/holds.d.ts +35 -3
- package/dist/bridges/holds.d.ts.map +1 -1
- package/dist/bridges/holds.js +117 -23
- package/dist/bridges/holds.js.map +1 -1
- package/dist/bridges/notices.d.ts.map +1 -1
- package/dist/bridges/notices.js +5 -5
- package/dist/bridges/notices.js.map +1 -1
- package/dist/bridges/relation-eval.d.ts +4 -4
- package/dist/bridges/relation-eval.d.ts.map +1 -1
- package/dist/bridges/relation-eval.js +15 -16
- package/dist/bridges/relation-eval.js.map +1 -1
- package/dist/bridges/sensitivity.d.ts.map +1 -1
- package/dist/bridges/sensitivity.js +3 -3
- package/dist/bridges/sensitivity.js.map +1 -1
- package/dist/bridges/validity.d.ts +33 -0
- package/dist/bridges/validity.d.ts.map +1 -0
- package/dist/bridges/validity.js +67 -0
- package/dist/bridges/validity.js.map +1 -0
- package/dist/canonical/entries/atomic.js +1 -3
- package/dist/canonical/entries/atomic.js.map +1 -1
- package/dist/canonical/entries/condensed-matter.d.ts.map +1 -1
- package/dist/canonical/entries/condensed-matter.js +4 -5
- package/dist/canonical/entries/condensed-matter.js.map +1 -1
- package/dist/canonical/entries/dimensional-classics.d.ts.map +1 -1
- package/dist/canonical/entries/dimensional-classics.js +3 -4
- package/dist/canonical/entries/dimensional-classics.js.map +1 -1
- package/dist/canonical/entries/electromagnetism.d.ts.map +1 -1
- package/dist/canonical/entries/electromagnetism.js +4 -10
- package/dist/canonical/entries/electromagnetism.js.map +1 -1
- package/dist/canonical/entries/fluids-waves.d.ts.map +1 -1
- package/dist/canonical/entries/fluids-waves.js +3 -7
- package/dist/canonical/entries/fluids-waves.js.map +1 -1
- package/dist/canonical/entries/mechanics.d.ts.map +1 -1
- package/dist/canonical/entries/mechanics.js +4 -6
- package/dist/canonical/entries/mechanics.js.map +1 -1
- package/dist/canonical/entries/nonmonomial.d.ts.map +1 -1
- package/dist/canonical/entries/nonmonomial.js +9 -17
- package/dist/canonical/entries/nonmonomial.js.map +1 -1
- package/dist/canonical/entries/relativity.d.ts.map +1 -1
- package/dist/canonical/entries/relativity.js +6 -6
- package/dist/canonical/entries/relativity.js.map +1 -1
- package/dist/canonical/entries/thermo-nuclear-cosmo.d.ts.map +1 -1
- package/dist/canonical/entries/thermo-nuclear-cosmo.js +6 -10
- package/dist/canonical/entries/thermo-nuclear-cosmo.js.map +1 -1
- package/dist/canonical/fixed-points.d.ts +94 -0
- package/dist/canonical/fixed-points.d.ts.map +1 -0
- package/dist/canonical/fixed-points.js +81 -0
- package/dist/canonical/fixed-points.js.map +1 -0
- package/dist/canonical/linkage.d.ts.map +1 -1
- package/dist/canonical/linkage.js +25 -44
- package/dist/canonical/linkage.js.map +1 -1
- package/dist/canonical/normal-form.d.ts.map +1 -1
- package/dist/canonical/normal-form.js +5 -11
- package/dist/canonical/normal-form.js.map +1 -1
- package/dist/canonical/structural.d.ts +21 -21
- package/dist/canonical/structural.d.ts.map +1 -1
- package/dist/canonical/structural.js +40 -19
- package/dist/canonical/structural.js.map +1 -1
- package/dist/cases/brownian-sphere.d.ts +3 -3
- package/dist/cases/brownian-sphere.d.ts.map +1 -1
- package/dist/cases/brownian-sphere.js +6 -5
- package/dist/cases/brownian-sphere.js.map +1 -1
- package/dist/cases/damped-resonator.d.ts.map +1 -1
- package/dist/cases/damped-resonator.js +6 -9
- package/dist/cases/damped-resonator.js.map +1 -1
- package/dist/cases/kepler-rv.d.ts +1 -1
- package/dist/cases/kepler-rv.d.ts.map +1 -1
- package/dist/cases/kepler-rv.js +3 -2
- package/dist/cases/kepler-rv.js.map +1 -1
- package/dist/cases/lumped-cooling.d.ts +8 -3
- package/dist/cases/lumped-cooling.d.ts.map +1 -1
- package/dist/cases/lumped-cooling.js +21 -23
- package/dist/cases/lumped-cooling.js.map +1 -1
- package/dist/cases/quadrature.d.ts +7 -9
- package/dist/cases/quadrature.d.ts.map +1 -1
- package/dist/cases/quadrature.js +28 -32
- package/dist/cases/quadrature.js.map +1 -1
- package/dist/cases/resistor-noise.js +4 -4
- package/dist/cases/resistor-noise.js.map +1 -1
- package/dist/cases/skin-depth.d.ts +0 -4
- package/dist/cases/skin-depth.d.ts.map +1 -1
- package/dist/cases/skin-depth.js +3 -7
- package/dist/cases/skin-depth.js.map +1 -1
- package/dist/cli/args.d.ts +23 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +30 -8
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/bindings.d.ts.map +1 -1
- package/dist/cli/bindings.js +5 -4
- package/dist/cli/bindings.js.map +1 -1
- package/dist/cli/command.d.ts +8 -1
- package/dist/cli/command.d.ts.map +1 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/commands/_atlas-map.d.ts +0 -9
- package/dist/cli/commands/_atlas-map.d.ts.map +1 -1
- package/dist/cli/commands/_atlas-map.js +8 -18
- package/dist/cli/commands/_atlas-map.js.map +1 -1
- package/dist/cli/commands/_atlas-route.d.ts.map +1 -1
- package/dist/cli/commands/_atlas-route.js +6 -2
- package/dist/cli/commands/_atlas-route.js.map +1 -1
- package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
- package/dist/cli/commands/_discovery-opts.js +8 -9
- package/dist/cli/commands/_discovery-opts.js.map +1 -1
- package/dist/cli/commands/atlas.d.ts.map +1 -1
- package/dist/cli/commands/atlas.js +8 -5
- package/dist/cli/commands/atlas.js.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +8 -1
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/axes.d.ts.map +1 -1
- package/dist/cli/commands/axes.js +20 -1
- package/dist/cli/commands/axes.js.map +1 -1
- package/dist/cli/commands/confront.d.ts.map +1 -1
- package/dist/cli/commands/confront.js +8 -14
- package/dist/cli/commands/confront.js.map +1 -1
- package/dist/cli/commands/derive.d.ts.map +1 -1
- package/dist/cli/commands/derive.js +22 -22
- package/dist/cli/commands/derive.js.map +1 -1
- package/dist/cli/commands/discover.d.ts.map +1 -1
- package/dist/cli/commands/discover.js +6 -2
- package/dist/cli/commands/discover.js.map +1 -1
- package/dist/cli/commands/eval.d.ts.map +1 -1
- package/dist/cli/commands/eval.js +1 -0
- package/dist/cli/commands/eval.js.map +1 -1
- package/dist/cli/commands/evaluate.d.ts.map +1 -1
- package/dist/cli/commands/evaluate.js +65 -37
- package/dist/cli/commands/evaluate.js.map +1 -1
- package/dist/cli/commands/explain.d.ts.map +1 -1
- package/dist/cli/commands/explain.js +2 -1
- package/dist/cli/commands/explain.js.map +1 -1
- package/dist/cli/commands/ground.d.ts.map +1 -1
- package/dist/cli/commands/ground.js +1 -0
- package/dist/cli/commands/ground.js.map +1 -1
- package/dist/cli/commands/map.d.ts.map +1 -1
- package/dist/cli/commands/map.js +75 -5
- package/dist/cli/commands/map.js.map +1 -1
- package/dist/cli/commands/metric.d.ts.map +1 -1
- package/dist/cli/commands/metric.js +12 -9
- package/dist/cli/commands/metric.js.map +1 -1
- package/dist/cli/commands/path.d.ts +10 -0
- package/dist/cli/commands/path.d.ts.map +1 -1
- package/dist/cli/commands/path.js +25 -3
- package/dist/cli/commands/path.js.map +1 -1
- package/dist/cli/commands/probe.d.ts.map +1 -1
- package/dist/cli/commands/probe.js +59 -16
- package/dist/cli/commands/probe.js.map +1 -1
- package/dist/cli/commands/regime.d.ts.map +1 -1
- package/dist/cli/commands/regime.js +1 -0
- package/dist/cli/commands/regime.js.map +1 -1
- package/dist/cli/commands/retrieve.d.ts.map +1 -1
- package/dist/cli/commands/retrieve.js +1 -0
- package/dist/cli/commands/retrieve.js.map +1 -1
- package/dist/cli/commands/search.d.ts.map +1 -1
- package/dist/cli/commands/search.js +1 -0
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/symbolic.d.ts.map +1 -1
- package/dist/cli/commands/symbolic.js +19 -28
- package/dist/cli/commands/symbolic.js.map +1 -1
- package/dist/cli/commands/testplan.d.ts.map +1 -1
- package/dist/cli/commands/testplan.js +4 -2
- package/dist/cli/commands/testplan.js.map +1 -1
- package/dist/cli/expr-print.d.ts +0 -2
- package/dist/cli/expr-print.d.ts.map +1 -1
- package/dist/cli/expr-print.js +7 -31
- package/dist/cli/expr-print.js.map +1 -1
- package/dist/cli/main.d.ts +7 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +18 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/numeric-flag.d.ts +12 -0
- package/dist/cli/numeric-flag.d.ts.map +1 -0
- package/dist/cli/numeric-flag.js +44 -0
- package/dist/cli/numeric-flag.js.map +1 -0
- package/dist/cli/output.d.ts +20 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +15 -0
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/record-reach.js +2 -2
- package/dist/cli/record-reach.js.map +1 -1
- package/dist/cli/record-tables.d.ts.map +1 -1
- package/dist/cli/record-tables.js +6 -5
- package/dist/cli/record-tables.js.map +1 -1
- package/dist/cli/record.d.ts +1 -5
- package/dist/cli/record.d.ts.map +1 -1
- package/dist/cli/record.js +9 -8
- package/dist/cli/record.js.map +1 -1
- package/dist/cli/search-index.d.ts.map +1 -1
- package/dist/cli/search-index.js +7 -6
- package/dist/cli/search-index.js.map +1 -1
- package/dist/cli/statuses.d.ts +0 -2
- package/dist/cli/statuses.d.ts.map +1 -1
- package/dist/cli/statuses.js +0 -7
- package/dist/cli/statuses.js.map +1 -1
- package/dist/cli/stored-results.d.ts +7 -0
- package/dist/cli/stored-results.d.ts.map +1 -0
- package/dist/cli/stored-results.js +23 -0
- package/dist/cli/stored-results.js.map +1 -0
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +7 -5
- package/dist/cli/version.js.map +1 -1
- package/dist/cli-api.d.ts +34 -5
- package/dist/cli-api.d.ts.map +1 -1
- package/dist/cli-api.js +28 -4
- package/dist/cli-api.js.map +1 -1
- package/dist/composition/algebraic-equivalence.d.ts +43 -0
- package/dist/composition/algebraic-equivalence.d.ts.map +1 -0
- package/dist/composition/algebraic-equivalence.js +115 -0
- package/dist/composition/algebraic-equivalence.js.map +1 -0
- package/dist/composition/axes.d.ts +0 -6
- package/dist/composition/axes.d.ts.map +1 -1
- package/dist/composition/axes.js +6 -6
- package/dist/composition/axes.js.map +1 -1
- package/dist/composition/axis-audit.d.ts +47 -20
- package/dist/composition/axis-audit.d.ts.map +1 -1
- package/dist/composition/axis-audit.js +82 -9
- package/dist/composition/axis-audit.js.map +1 -1
- package/dist/composition/bridge-analysis.d.ts +17 -0
- package/dist/composition/bridge-analysis.d.ts.map +1 -1
- package/dist/composition/bridge-analysis.js +102 -55
- package/dist/composition/bridge-analysis.js.map +1 -1
- package/dist/composition/canonical-compare.d.ts +40 -0
- package/dist/composition/canonical-compare.d.ts.map +1 -1
- package/dist/composition/canonical-compare.js +122 -24
- package/dist/composition/canonical-compare.js.map +1 -1
- package/dist/composition/canonical-graph.d.ts +1 -1
- package/dist/composition/canonical-graph.d.ts.map +1 -1
- package/dist/composition/canonical-graph.js +9 -36
- package/dist/composition/canonical-graph.js.map +1 -1
- package/dist/composition/canonical-json.js +2 -2
- package/dist/composition/canonical-json.js.map +1 -1
- package/dist/composition/catalog-graph.d.ts.map +1 -1
- package/dist/composition/catalog-graph.js +2 -5
- package/dist/composition/catalog-graph.js.map +1 -1
- package/dist/composition/chain-candidate.d.ts +8 -0
- package/dist/composition/chain-candidate.d.ts.map +1 -1
- package/dist/composition/chain-candidate.js +9 -2
- package/dist/composition/chain-candidate.js.map +1 -1
- package/dist/composition/chain-match.d.ts +6 -3
- package/dist/composition/chain-match.d.ts.map +1 -1
- package/dist/composition/chain-match.js +4 -1
- package/dist/composition/chain-match.js.map +1 -1
- package/dist/composition/chain-result.d.ts.map +1 -1
- package/dist/composition/chain-result.js +2 -14
- package/dist/composition/chain-result.js.map +1 -1
- package/dist/composition/compose-symbolic.d.ts.map +1 -1
- package/dist/composition/compose-symbolic.js +3 -2
- package/dist/composition/compose-symbolic.js.map +1 -1
- package/dist/composition/compose.d.ts.map +1 -1
- package/dist/composition/compose.js +13 -5
- package/dist/composition/compose.js.map +1 -1
- package/dist/composition/composition-recovery.d.ts.map +1 -1
- package/dist/composition/composition-recovery.js +4 -7
- package/dist/composition/composition-recovery.js.map +1 -1
- package/dist/composition/discovery.d.ts +56 -0
- package/dist/composition/discovery.d.ts.map +1 -1
- package/dist/composition/discovery.js +114 -60
- package/dist/composition/discovery.js.map +1 -1
- package/dist/composition/edge.d.ts +21 -2
- package/dist/composition/edge.d.ts.map +1 -1
- package/dist/composition/edge.js +23 -1
- package/dist/composition/edge.js.map +1 -1
- package/dist/composition/enumerate.d.ts.map +1 -1
- package/dist/composition/enumerate.js +18 -3
- package/dist/composition/enumerate.js.map +1 -1
- package/dist/composition/evaluate-relation.d.ts +35 -11
- package/dist/composition/evaluate-relation.d.ts.map +1 -1
- package/dist/composition/evaluate-relation.js +60 -39
- package/dist/composition/evaluate-relation.js.map +1 -1
- package/dist/composition/explain.d.ts +3 -12
- package/dist/composition/explain.d.ts.map +1 -1
- package/dist/composition/explain.js +7 -20
- package/dist/composition/explain.js.map +1 -1
- package/dist/composition/expr-eval.d.ts.map +1 -1
- package/dist/composition/expr-eval.js +2 -11
- package/dist/composition/expr-eval.js.map +1 -1
- package/dist/composition/expr-simplify.d.ts +16 -0
- package/dist/composition/expr-simplify.d.ts.map +1 -1
- package/dist/composition/expr-simplify.js +15 -20
- package/dist/composition/expr-simplify.js.map +1 -1
- package/dist/composition/formula-shape.d.ts +23 -4
- package/dist/composition/formula-shape.d.ts.map +1 -1
- package/dist/composition/formula-shape.js +57 -17
- package/dist/composition/formula-shape.js.map +1 -1
- package/dist/composition/graph-structure.d.ts +98 -0
- package/dist/composition/graph-structure.d.ts.map +1 -0
- package/dist/composition/graph-structure.js +167 -0
- package/dist/composition/graph-structure.js.map +1 -0
- package/dist/composition/graph-viz-svg.d.ts.map +1 -1
- package/dist/composition/graph-viz-svg.js +1 -1
- package/dist/composition/graph-viz-svg.js.map +1 -1
- package/dist/composition/graph-viz.d.ts.map +1 -1
- package/dist/composition/graph-viz.js +8 -37
- package/dist/composition/graph-viz.js.map +1 -1
- package/dist/composition/identifiability.d.ts +91 -4
- package/dist/composition/identifiability.d.ts.map +1 -1
- package/dist/composition/identifiability.js +363 -6
- package/dist/composition/identifiability.js.map +1 -1
- package/dist/composition/index.d.ts +8 -4
- package/dist/composition/index.d.ts.map +1 -1
- package/dist/composition/index.js +3 -2
- package/dist/composition/index.js.map +1 -1
- package/dist/composition/mathts-quiet.d.ts +4 -3
- package/dist/composition/mathts-quiet.d.ts.map +1 -1
- package/dist/composition/mathts-quiet.js +4 -3
- package/dist/composition/mathts-quiet.js.map +1 -1
- package/dist/composition/mathts-scalar-symbols.d.ts.map +1 -1
- package/dist/composition/mathts-scalar-symbols.js +2 -1
- package/dist/composition/mathts-scalar-symbols.js.map +1 -1
- package/dist/composition/probe/corpus.d.ts +4 -2
- package/dist/composition/probe/corpus.d.ts.map +1 -1
- package/dist/composition/probe/corpus.js +20 -9
- package/dist/composition/probe/corpus.js.map +1 -1
- package/dist/composition/probe/dataset.d.ts +17 -0
- package/dist/composition/probe/dataset.d.ts.map +1 -1
- package/dist/composition/probe/dataset.js +95 -50
- package/dist/composition/probe/dataset.js.map +1 -1
- package/dist/composition/probe/experiment-design.d.ts +5 -1
- package/dist/composition/probe/experiment-design.d.ts.map +1 -1
- package/dist/composition/probe/experiment-design.js +44 -24
- package/dist/composition/probe/experiment-design.js.map +1 -1
- package/dist/composition/probe/falsify.d.ts.map +1 -1
- package/dist/composition/probe/falsify.js +2 -0
- package/dist/composition/probe/falsify.js.map +1 -1
- package/dist/composition/probe/fit.d.ts +6 -0
- package/dist/composition/probe/fit.d.ts.map +1 -1
- package/dist/composition/probe/fit.js +46 -22
- package/dist/composition/probe/fit.js.map +1 -1
- package/dist/composition/probe/frontier.d.ts.map +1 -1
- package/dist/composition/probe/frontier.js +33 -15
- package/dist/composition/probe/frontier.js.map +1 -1
- package/dist/composition/probe/generator.d.ts +27 -1
- package/dist/composition/probe/generator.d.ts.map +1 -1
- package/dist/composition/probe/generator.js +53 -30
- package/dist/composition/probe/generator.js.map +1 -1
- package/dist/composition/probe/index.d.ts +14 -0
- package/dist/composition/probe/index.d.ts.map +1 -1
- package/dist/composition/probe/index.js +6 -0
- package/dist/composition/probe/index.js.map +1 -1
- package/dist/composition/probe/limits.d.ts +24 -1
- package/dist/composition/probe/limits.d.ts.map +1 -1
- package/dist/composition/probe/limits.js +53 -11
- package/dist/composition/probe/limits.js.map +1 -1
- package/dist/composition/probe/pipeline.d.ts.map +1 -1
- package/dist/composition/probe/pipeline.js +10 -4
- package/dist/composition/probe/pipeline.js.map +1 -1
- package/dist/composition/probe/power-law.d.ts +121 -0
- package/dist/composition/probe/power-law.d.ts.map +1 -0
- package/dist/composition/probe/power-law.js +255 -0
- package/dist/composition/probe/power-law.js.map +1 -0
- package/dist/composition/probe/problem.d.ts +7 -4
- package/dist/composition/probe/problem.d.ts.map +1 -1
- package/dist/composition/probe/problem.js +177 -49
- package/dist/composition/probe/problem.js.map +1 -1
- package/dist/composition/probe/report.js +1 -1
- package/dist/composition/probe/report.js.map +1 -1
- package/dist/composition/probe/residual.d.ts +6 -1
- package/dist/composition/probe/residual.d.ts.map +1 -1
- package/dist/composition/probe/residual.js +9 -7
- package/dist/composition/probe/residual.js.map +1 -1
- package/dist/composition/probe/structure.d.ts +82 -17
- package/dist/composition/probe/structure.d.ts.map +1 -1
- package/dist/composition/probe/structure.js +129 -55
- package/dist/composition/probe/structure.js.map +1 -1
- package/dist/composition/probe/study.d.ts +31 -9
- package/dist/composition/probe/study.d.ts.map +1 -1
- package/dist/composition/probe/study.js +236 -181
- package/dist/composition/probe/study.js.map +1 -1
- package/dist/composition/probe/t-tail.d.ts +17 -0
- package/dist/composition/probe/t-tail.d.ts.map +1 -0
- package/dist/composition/probe/t-tail.js +32 -0
- package/dist/composition/probe/t-tail.js.map +1 -0
- package/dist/composition/probe/types.d.ts +3 -0
- package/dist/composition/probe/types.d.ts.map +1 -1
- package/dist/composition/probe/types.js.map +1 -1
- package/dist/composition/proposed-bridges.d.ts +41 -10
- package/dist/composition/proposed-bridges.d.ts.map +1 -1
- package/dist/composition/proposed-bridges.js +100 -55
- package/dist/composition/proposed-bridges.js.map +1 -1
- package/dist/composition/quantity-clusters.d.ts +48 -0
- package/dist/composition/quantity-clusters.d.ts.map +1 -0
- package/dist/composition/quantity-clusters.js +98 -0
- package/dist/composition/quantity-clusters.js.map +1 -0
- package/dist/composition/rational-exponent.d.ts +40 -0
- package/dist/composition/rational-exponent.d.ts.map +1 -0
- package/dist/composition/rational-exponent.js +65 -0
- package/dist/composition/rational-exponent.js.map +1 -0
- package/dist/composition/representative-values.d.ts +22 -0
- package/dist/composition/representative-values.d.ts.map +1 -1
- package/dist/composition/representative-values.js +23 -0
- package/dist/composition/representative-values.js.map +1 -1
- package/dist/composition/retrodiction.d.ts.map +1 -1
- package/dist/composition/retrodiction.js +2 -1
- package/dist/composition/retrodiction.js.map +1 -1
- package/dist/composition/user-equation.d.ts.map +1 -1
- package/dist/composition/user-equation.js +2 -2
- package/dist/composition/user-equation.js.map +1 -1
- package/dist/core/assignment.d.ts +19 -0
- package/dist/core/assignment.d.ts.map +1 -0
- package/dist/core/assignment.js +19 -0
- package/dist/core/assignment.js.map +1 -0
- package/dist/core/compare.d.ts +32 -0
- package/dist/core/compare.d.ts.map +1 -0
- package/dist/core/compare.js +46 -0
- package/dist/core/compare.js.map +1 -0
- package/dist/core/constants.d.ts +30 -30
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +47 -30
- package/dist/core/constants.js.map +1 -1
- package/dist/core/data-file.d.ts +7 -0
- package/dist/core/data-file.d.ts.map +1 -1
- package/dist/core/data-file.js +17 -0
- package/dist/core/data-file.js.map +1 -1
- package/dist/core/format.d.ts +36 -0
- package/dist/core/format.d.ts.map +1 -0
- package/dist/core/format.js +39 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/hash.d.ts +14 -0
- package/dist/core/hash.d.ts.map +1 -0
- package/dist/core/hash.js +17 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/json-schema.d.ts +2 -0
- package/dist/core/json-schema.d.ts.map +1 -1
- package/dist/core/json-schema.js +14 -13
- package/dist/core/json-schema.js.map +1 -1
- package/dist/core/labeled-tensor.d.ts.map +1 -1
- package/dist/core/labeled-tensor.js +0 -8
- package/dist/core/labeled-tensor.js.map +1 -1
- package/dist/core/mathts-read.d.ts +25 -0
- package/dist/core/mathts-read.d.ts.map +1 -0
- package/dist/core/mathts-read.js +51 -0
- package/dist/core/mathts-read.js.map +1 -0
- package/dist/core/tensor.d.ts.map +1 -1
- package/dist/core/tensor.js +24 -0
- package/dist/core/tensor.js.map +1 -1
- package/dist/core/types.d.ts +5 -5
- package/dist/diff/bridge-gradient.d.ts +19 -6
- package/dist/diff/bridge-gradient.d.ts.map +1 -1
- package/dist/diff/bridge-gradient.js +19 -11
- package/dist/diff/bridge-gradient.js.map +1 -1
- package/dist/diff/bridge-specs.d.ts.map +1 -1
- package/dist/diff/bridge-specs.js +3 -0
- package/dist/diff/bridge-specs.js.map +1 -1
- package/dist/dimensional/algebra.d.ts +18 -0
- package/dist/dimensional/algebra.d.ts.map +1 -1
- package/dist/dimensional/algebra.js +41 -1
- package/dist/dimensional/algebra.js.map +1 -1
- package/dist/dimensional/ast-builders.d.ts +7 -0
- package/dist/dimensional/ast-builders.d.ts.map +1 -1
- package/dist/dimensional/ast-builders.js +11 -0
- package/dist/dimensional/ast-builders.js.map +1 -1
- package/dist/dimensional/ast-leaves.d.ts +81 -0
- package/dist/dimensional/ast-leaves.d.ts.map +1 -0
- package/dist/dimensional/ast-leaves.js +146 -0
- package/dist/dimensional/ast-leaves.js.map +1 -0
- package/dist/dimensional/buckingham.d.ts.map +1 -1
- package/dist/dimensional/buckingham.js +15 -27
- package/dist/dimensional/buckingham.js.map +1 -1
- package/dist/dimensional/constant-rows.js +9 -9
- package/dist/dimensional/constant-rows.js.map +1 -1
- package/dist/dimensional/dimension-inference.d.ts.map +1 -1
- package/dist/dimensional/dimension-inference.js +1 -2
- package/dist/dimensional/dimension-inference.js.map +1 -1
- package/dist/dimensional/errors.d.ts +1 -1
- package/dist/dimensional/errors.d.ts.map +1 -1
- package/dist/dimensional/errors.js +1 -15
- package/dist/dimensional/errors.js.map +1 -1
- package/dist/dimensional/exact-scale.d.ts +0 -17
- package/dist/dimensional/exact-scale.d.ts.map +1 -1
- package/dist/dimensional/exact-scale.js +8 -8
- package/dist/dimensional/exact-scale.js.map +1 -1
- package/dist/dimensional/gauge-field.d.ts.map +1 -1
- package/dist/dimensional/gauge-field.js +2 -2
- package/dist/dimensional/gauge-field.js.map +1 -1
- package/dist/dimensional/hyphen-names.d.ts +12 -2
- package/dist/dimensional/hyphen-names.d.ts.map +1 -1
- package/dist/dimensional/hyphen-names.js +44 -19
- package/dist/dimensional/hyphen-names.js.map +1 -1
- package/dist/dimensional/metric.d.ts.map +1 -1
- package/dist/dimensional/metric.js +0 -1
- package/dist/dimensional/metric.js.map +1 -1
- package/dist/dimensional/symbolic-constants.d.ts +9 -0
- package/dist/dimensional/symbolic-constants.d.ts.map +1 -1
- package/dist/dimensional/symbolic-constants.js +13 -1
- package/dist/dimensional/symbolic-constants.js.map +1 -1
- package/dist/dimensional/types.d.ts +36 -0
- package/dist/dimensional/types.d.ts.map +1 -1
- package/dist/dimensional/types.js +45 -7
- package/dist/dimensional/types.js.map +1 -1
- package/dist/dimensional/unit-data.js +2 -2
- package/dist/dimensional/unit-data.js.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/numerical/christoffel-flat.d.ts.map +1 -1
- package/dist/numerical/christoffel-flat.js +3 -2
- package/dist/numerical/christoffel-flat.js.map +1 -1
- package/dist/numerical/covariant-eikonal.d.ts.map +1 -1
- package/dist/numerical/covariant-eikonal.js +34 -11
- package/dist/numerical/covariant-eikonal.js.map +1 -1
- package/dist/numerical/curvature-lowering-helpers.js +3 -2
- package/dist/numerical/curvature-lowering-helpers.js.map +1 -1
- package/dist/numerical/errors.d.ts.map +1 -1
- package/dist/numerical/errors.js +0 -3
- package/dist/numerical/errors.js.map +1 -1
- package/dist/numerical/finite-difference.d.ts +22 -0
- package/dist/numerical/finite-difference.d.ts.map +1 -0
- package/dist/numerical/finite-difference.js +27 -0
- package/dist/numerical/finite-difference.js.map +1 -0
- package/dist/numerical/geodesic-integrator.d.ts.map +1 -1
- package/dist/numerical/geodesic-integrator.js +22 -14
- package/dist/numerical/geodesic-integrator.js.map +1 -1
- package/dist/numerical/geometrized.d.ts.map +1 -1
- package/dist/numerical/geometrized.js +0 -1
- package/dist/numerical/geometrized.js.map +1 -1
- package/dist/numerical/mathts-engine.d.ts.map +1 -1
- package/dist/numerical/mathts-engine.js +10 -24
- package/dist/numerical/mathts-engine.js.map +1 -1
- package/dist/numerical/metric-inverse.d.ts.map +1 -1
- package/dist/numerical/metric-inverse.js +83 -46
- package/dist/numerical/metric-inverse.js.map +1 -1
- package/dist/numerical/null-ray-integrator.d.ts +2 -1
- package/dist/numerical/null-ray-integrator.d.ts.map +1 -1
- package/dist/numerical/null-ray-integrator.js +12 -12
- package/dist/numerical/null-ray-integrator.js.map +1 -1
- package/dist/numerical/painleve-gullstrand-metric.js +2 -2
- package/dist/numerical/painleve-gullstrand-metric.js.map +1 -1
- package/dist/numerical/perihelion-finder.d.ts +0 -36
- package/dist/numerical/perihelion-finder.d.ts.map +1 -1
- package/dist/numerical/perihelion-finder.js +41 -87
- package/dist/numerical/perihelion-finder.js.map +1 -1
- package/dist/numerical/quadrature.d.ts.map +1 -1
- package/dist/numerical/quadrature.js +8 -10
- package/dist/numerical/quadrature.js.map +1 -1
- package/dist/numerical/rk4-trajectory.d.ts +10 -0
- package/dist/numerical/rk4-trajectory.d.ts.map +1 -0
- package/dist/numerical/rk4-trajectory.js +37 -0
- package/dist/numerical/rk4-trajectory.js.map +1 -0
- package/dist/numerical/schwarzschild.d.ts +14 -0
- package/dist/numerical/schwarzschild.d.ts.map +1 -0
- package/dist/numerical/schwarzschild.js +17 -0
- package/dist/numerical/schwarzschild.js.map +1 -0
- package/dist/numerical/spacetime-metrics.d.ts +12 -0
- package/dist/numerical/spacetime-metrics.d.ts.map +1 -1
- package/dist/numerical/spacetime-metrics.js +72 -56
- package/dist/numerical/spacetime-metrics.js.map +1 -1
- package/dist/numerical/statistics.d.ts +24 -0
- package/dist/numerical/statistics.d.ts.map +1 -0
- package/dist/numerical/statistics.js +52 -0
- package/dist/numerical/statistics.js.map +1 -0
- package/dist/numerical/tensor-engine.d.ts +21 -0
- package/dist/numerical/tensor-engine.d.ts.map +1 -1
- package/dist/numerical/tensor-engine.js +12 -0
- package/dist/numerical/tensor-engine.js.map +1 -1
- package/dist/relations/regime.d.ts +10 -0
- package/dist/relations/regime.d.ts.map +1 -1
- package/dist/relations/regime.js +18 -1
- package/dist/relations/regime.js.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset.js","sourceRoot":"","sources":["../../../src/composition/probe/dataset.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Observation adapters for Product B.\n *\n * In-memory / JSON / CSV. Does not live in `src/bridges/observations/` —\n * that tree is Product A's confrontation ledger and must stay cycle-free\n * from probe.\n *\n * @internal\n */\n\nimport { readFileSync } from 'node:fs';\nimport type { DatasetRole, ObservationRow, ProbeDataset } from './types.js';\nimport { SCHEMA_VERSION } from './types.js';\n\n/** Build an in-memory dataset. @internal */\nexport function datasetFromRows(\n rows: readonly ObservationRow[],\n observable: string,\n role: DatasetRole,\n id = 'inline',\n sigma?: number,\n): ProbeDataset {\n return { id, role, rows, observable, ...(sigma !== undefined ? { sigma } : {}), schemaVersion: SCHEMA_VERSION };\n}\n\n/** Coerce unknown JSON into a ProbeDataset. @internal */\nexport function asDatasetSafe(raw: unknown, fallbackId: string, fallbackRole?: DatasetRole): ProbeDataset {\n if (!raw || typeof raw !== 'object') {\n throw new Error(`dataset JSON is not an object (${fallbackId})`);\n }\n const obj = raw as {\n id?: unknown;\n role?: unknown;\n rows?: unknown;\n observable?: unknown;\n sigma?: unknown;\n schemaVersion?: unknown;\n };\n if (!Array.isArray(obj.rows)) {\n throw new Error(`dataset at ${fallbackId} is missing rows[]`);\n }\n if (typeof obj.observable !== 'string' || obj.observable.length === 0) {\n throw new Error(`dataset at ${fallbackId} is missing observable`);\n }\n const role = (typeof obj.role === 'string' ? obj.role : fallbackRole) as DatasetRole | undefined;\n if (\n role !== 'exploratory-fit' &&\n role !== 'validation-holdout' &&\n role !== 'external-replication' &&\n role !== 'falsification-only'\n ) {\n throw new Error(`dataset at ${fallbackId} has invalid role '${String(obj.role)}'`);\n }\n const rows: ObservationRow[] = obj.rows.map((row, i) => {\n if (!row || typeof row !== 'object' || Array.isArray(row)) {\n throw new Error(`dataset ${fallbackId} row ${i} is not an object`);\n }\n const out: Record<string, number> = {};\n for (const [k, v] of Object.entries(row as Record<string, unknown>)) {\n const n = typeof v === 'number' ? v : Number(v);\n if (!Number.isFinite(n)) {\n throw new Error(`dataset ${fallbackId} row ${i} column ${k}: not a finite number`);\n }\n out[k] = n;\n }\n return out;\n });\n return {\n id: typeof obj.id === 'string' ? obj.id : fallbackId,\n role,\n rows,\n observable: obj.observable,\n ...(typeof obj.sigma === 'number' && Number.isFinite(obj.sigma) ? { sigma: obj.sigma } : {}),\n schemaVersion: typeof obj.schemaVersion === 'string' ? obj.schemaVersion : SCHEMA_VERSION,\n };\n}\n\n/** Load a single ProbeDataset JSON object. @internal */\nexport function loadDatasetFromJson(path: string, fallbackRole?: DatasetRole): ProbeDataset {\n const raw = JSON.parse(readFileSync(path, 'utf8')) as unknown;\n return asDatasetSafe(raw, path, fallbackRole);\n}\n\nexport interface SplitFileDatasets {\n readonly exploratory?: ProbeDataset;\n readonly holdout?: ProbeDataset;\n}\n\n/** Load `{ exploratory, holdout }` JSON. @internal */\nexport function loadSplitDatasetsFromJson(path: string): SplitFileDatasets {\n const raw = JSON.parse(readFileSync(path, 'utf8')) as {\n exploratory?: unknown;\n holdout?: unknown;\n observations?: unknown;\n };\n if (raw.exploratory || raw.holdout) {\n return {\n exploratory: raw.exploratory\n ? asDatasetSafe(raw.exploratory, `${path}#exploratory`, 'exploratory-fit')\n : undefined,\n holdout: raw.holdout\n ? asDatasetSafe(raw.holdout, `${path}#holdout`, 'validation-holdout')\n : undefined,\n };\n }\n if (raw.observations) {\n return {\n exploratory: asDatasetSafe(\n { ...(raw.observations as object), role: 'exploratory-fit' },\n `${path}#observations`,\n 'exploratory-fit',\n ),\n };\n }\n throw new Error(`JSON at ${path} needs exploratory/holdout or observations`);\n}\n\n/**\n * Minimal CSV: first row headers, remaining rows numeric values.\n * Optional `split` column (`exploratory`/`holdout`/`blind`).\n * `blind` rows are withheld with holdout data, never fit.\n *\n * @internal\n */\nexport function loadDatasetFromCsv(\n path: string,\n observable: string,\n role: DatasetRole,\n id = path,\n): ProbeDataset {\n const text = readFileSync(path, 'utf8').trim();\n const lines = text.split(/\\r?\\n/).filter((l) => l.length > 0);\n if (lines.length < 2) {\n throw new Error(`CSV dataset at ${path} needs a header and at least one row`);\n }\n const headers = lines[0]!.split(',').map((h) => h.trim());\n const rows: ObservationRow[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cells = lines[i]!.split(',').map((c) => c.trim());\n const row: Record<string, number> = {};\n for (let c = 0; c < headers.length; c++) {\n const h = headers[c]!;\n if (h === 'split') continue;\n const n = Number(cells[c] ?? '');\n if (!Number.isFinite(n)) {\n throw new Error(`CSV ${path} row ${i + 1} column ${h}: not a finite number`);\n }\n row[h] = n;\n }\n rows.push(row);\n }\n if (!(observable in (rows[0] ?? {}))) {\n throw new Error(`CSV ${path} is missing observable column '${observable}'`);\n }\n return datasetFromRows(rows, observable, role, id);\n}\n\n/** Partition a mixed-split CSV (uses a `split` column). @internal */\nexport function loadSplitCsv(\n path: string,\n observable: string,\n): { exploratory: ProbeDataset; holdout: ProbeDataset } {\n const text = readFileSync(path, 'utf8').trim();\n const lines = text.split(/\\r?\\n/).filter((l) => l.length > 0);\n if (lines.length < 2) {\n throw new Error(`CSV dataset at ${path} needs a header and at least one row`);\n }\n const headers = lines[0]!.split(',').map((h) => h.trim());\n const splitIdx = headers.indexOf('split');\n if (splitIdx < 0) {\n throw new Error(`CSV ${path} has no split column`);\n }\n const exploratoryRows: ObservationRow[] = [];\n const holdoutRows: ObservationRow[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cells = lines[i]!.split(',').map((c) => c.trim());\n const row: Record<string, number> = {};\n for (let c = 0; c < headers.length; c++) {\n if (c === splitIdx) continue;\n const n = Number(cells[c] ?? '');\n if (!Number.isFinite(n)) {\n throw new Error(`CSV ${path} row ${i + 1} column ${headers[c]}: not a finite number`);\n }\n row[headers[c]!] = n;\n }\n const split = cells[splitIdx];\n if (split === 'holdout' || split === 'blind') holdoutRows.push(row);\n else if (split === 'exploratory') exploratoryRows.push(row);\n else throw new Error(`CSV ${path} row ${i + 1} has invalid split '${split}'`);\n }\n return {\n exploratory: datasetFromRows(exploratoryRows, observable, 'exploratory-fit', `${path}#exploratory`),\n holdout: datasetFromRows(holdoutRows, observable, 'validation-holdout', `${path}#holdout`),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dataset.js","sourceRoot":"","sources":["../../../src/composition/probe/dataset.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Observation adapters for Product B.\n *\n * In-memory / JSON / CSV. Does not live in `src/bridges/observations/` —\n * that tree is Product A's confrontation ledger and must stay cycle-free\n * from probe.\n *\n * A cell is a finite number or a non-empty string in the strict decimal\n * grammar (`1`, `-0.5`, `.5`, `2.`, `1e-3`). Nothing is coerced: an empty\n * cell, `null`, `true`, `false`, a list and `\"0x10\"` are refused by column\n * and row, with {@link DatasetError}. `Number(v)` once read all of those as\n * 0, 1 or 16, which also defeated the missing-observation guard of the\n * declared-limit check (a missing observation scored as 0).\n *\n * @internal\n */\n\nimport { readFileSync } from 'node:fs';\nimport { readJsonFile } from '../../core/data-file.js';\nimport type { DatasetRole, ObservationRow, ProbeDataset } from './types.js';\nimport { SCHEMA_VERSION } from './types.js';\n\n/** A dataset file or object that is not a dataset: the message names the row and the column. @internal */\nexport class DatasetError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DatasetError';\n }\n}\n\n/** The strict decimal grammar a string cell must match: sign, digits with an optional fraction, an optional exponent. */\nconst DECIMAL = /^[+-]?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/;\n\n/** What a JSON value is, in the words a file author would use. */\nfunction kindOf(v: unknown): string {\n if (v === null) return 'null';\n if (Array.isArray(v)) return 'a list';\n if (typeof v === 'boolean') return String(v);\n if (typeof v === 'string') return `'${v}'`;\n return typeof v === 'object' ? 'an object' : typeof v;\n}\n\n/**\n * A cell as a number: a finite number, or a non-empty string in the strict\n * decimal grammar. Anything else is refused at `where` (the dataset, row and\n * column). @internal\n */\nexport function readDatasetNumber(v: unknown, where: string): number {\n if (typeof v === 'number') {\n if (!Number.isFinite(v)) throw new DatasetError(`${where}: ${v} is not a finite number`);\n return v;\n }\n if (typeof v === 'string') {\n if (v.trim() === '') throw new DatasetError(`${where}: an empty cell is not a number`);\n const n = DECIMAL.test(v.trim()) ? Number(v.trim()) : NaN;\n if (!Number.isFinite(n)) throw new DatasetError(`${where}: ${kindOf(v)} is not a finite decimal number`);\n return n;\n }\n throw new DatasetError(`${where}: ${kindOf(v)} is not a number`);\n}\n\n/** Build an in-memory dataset. @internal */\nexport function datasetFromRows(\n rows: readonly ObservationRow[],\n observable: string,\n role: DatasetRole,\n id = 'inline',\n sigma?: number,\n): ProbeDataset {\n return { id, role, rows, observable, ...(sigma !== undefined ? { sigma } : {}), schemaVersion: SCHEMA_VERSION };\n}\n\n/** Coerce unknown JSON into a ProbeDataset. @internal */\nexport function asDatasetSafe(raw: unknown, fallbackId: string, fallbackRole?: DatasetRole): ProbeDataset {\n if (!raw || typeof raw !== 'object') {\n throw new DatasetError(`dataset JSON is not an object (${fallbackId})`);\n }\n const obj = raw as {\n id?: unknown;\n role?: unknown;\n rows?: unknown;\n observable?: unknown;\n sigma?: unknown;\n schemaVersion?: unknown;\n };\n if (!Array.isArray(obj.rows)) {\n throw new DatasetError(`dataset at ${fallbackId} is missing rows[]`);\n }\n if (typeof obj.observable !== 'string' || obj.observable.length === 0) {\n throw new DatasetError(`dataset at ${fallbackId} is missing observable`);\n }\n const role = (typeof obj.role === 'string' ? obj.role : fallbackRole) as DatasetRole | undefined;\n if (\n role !== 'exploratory-fit' &&\n role !== 'validation-holdout' &&\n role !== 'external-replication' &&\n role !== 'falsification-only'\n ) {\n throw new DatasetError(`dataset at ${fallbackId} has invalid role '${String(obj.role)}'`);\n }\n const rows: ObservationRow[] = obj.rows.map((row, i) => {\n if (!row || typeof row !== 'object' || Array.isArray(row)) {\n throw new DatasetError(`dataset ${fallbackId} row ${i} is not an object`);\n }\n const out: Record<string, number> = {};\n for (const [k, v] of Object.entries(row as Record<string, unknown>)) {\n out[k] = readDatasetNumber(v, `dataset ${fallbackId} row ${i} column ${k}`);\n }\n return out;\n });\n return {\n id: typeof obj.id === 'string' ? obj.id : fallbackId,\n role,\n rows,\n observable: obj.observable,\n ...(typeof obj.sigma === 'number' && Number.isFinite(obj.sigma) ? { sigma: obj.sigma } : {}),\n schemaVersion: typeof obj.schemaVersion === 'string' ? obj.schemaVersion : SCHEMA_VERSION,\n };\n}\n\n/** Load a single ProbeDataset JSON object. @internal */\nexport function loadDatasetFromJson(path: string, fallbackRole?: DatasetRole): ProbeDataset {\n const raw = readJsonFile(path);\n return asDatasetSafe(raw, path, fallbackRole);\n}\n\nexport interface SplitFileDatasets {\n readonly exploratory?: ProbeDataset;\n readonly holdout?: ProbeDataset;\n}\n\n/** Load `{ exploratory, holdout }` JSON. @internal */\nexport function loadSplitDatasetsFromJson(path: string): SplitFileDatasets {\n const raw = readJsonFile(path) as {\n exploratory?: unknown;\n holdout?: unknown;\n observations?: unknown;\n };\n if (raw.exploratory || raw.holdout) {\n return {\n exploratory: raw.exploratory\n ? asDatasetSafe(raw.exploratory, `${path}#exploratory`, 'exploratory-fit')\n : undefined,\n holdout: raw.holdout\n ? asDatasetSafe(raw.holdout, `${path}#holdout`, 'validation-holdout')\n : undefined,\n };\n }\n if (raw.observations) {\n return {\n exploratory: asDatasetSafe(\n { ...(raw.observations as object), role: 'exploratory-fit' },\n `${path}#observations`,\n 'exploratory-fit',\n ),\n };\n }\n throw new DatasetError(`JSON at ${path} needs exploratory/holdout or observations`);\n}\n\n/** The header and the data lines of a CSV file; the file needs both. */\nfunction csvLines(path: string): { headers: string[]; lines: string[] } {\n const text = readFileSync(path, 'utf8').trim();\n const lines = text.split(/\\r?\\n/).filter((l) => l.length > 0);\n if (lines.length < 2) {\n throw new DatasetError(`CSV dataset at ${path} needs a header and at least one row`);\n }\n const headers = lines[0]!.split(',').map((h) => h.trim());\n return { headers, lines };\n}\n\n/**\n * One CSV data line as a row of numbers. A line with fewer cells than the\n * header is refused by the first column it lacks; `skip` names the header\n * column (if any) that is not a number column. `line` is the 1-based line\n * number of the file, so a message points at the file.\n */\nfunction csvRow(cells: readonly string[], headers: readonly string[], line: number, path: string, skip: number): Record<string, number> {\n if (cells.length < headers.length) {\n throw new DatasetError(\n `CSV ${path} row ${line} has ${cells.length} cell(s); the header has ${headers.length} (column ${headers[cells.length]} is missing)`,\n );\n }\n const row: Record<string, number> = {};\n for (let c = 0; c < headers.length; c++) {\n if (c === skip) continue;\n row[headers[c]!] = readDatasetNumber(cells[c], `CSV ${path} row ${line} column ${headers[c]}`);\n }\n return row;\n}\n\n/**\n * Minimal CSV: first row headers, remaining rows numeric values.\n * Optional `split` column (`exploratory`/`holdout`/`blind`).\n * `blind` rows are withheld with holdout data, never fit.\n *\n * @internal\n */\nexport function loadDatasetFromCsv(\n path: string,\n observable: string,\n role: DatasetRole,\n id = path,\n): ProbeDataset {\n const { headers, lines } = csvLines(path);\n const splitIdx = headers.indexOf('split');\n const rows: ObservationRow[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cells = lines[i]!.split(',').map((c) => c.trim());\n rows.push(csvRow(cells, headers, i + 1, path, splitIdx));\n }\n if (!(observable in (rows[0] ?? {}))) {\n throw new DatasetError(`CSV ${path} is missing observable column '${observable}'`);\n }\n return datasetFromRows(rows, observable, role, id);\n}\n\n/** Partition a mixed-split CSV (uses a `split` column). @internal */\nexport function loadSplitCsv(\n path: string,\n observable: string,\n): { exploratory: ProbeDataset; holdout: ProbeDataset } {\n const { headers, lines } = csvLines(path);\n const splitIdx = headers.indexOf('split');\n if (splitIdx < 0) {\n throw new DatasetError(`CSV ${path} has no split column`);\n }\n const exploratoryRows: ObservationRow[] = [];\n const holdoutRows: ObservationRow[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cells = lines[i]!.split(',').map((c) => c.trim());\n const row = csvRow(cells, headers, i + 1, path, splitIdx);\n const split = cells[splitIdx];\n if (split === 'holdout' || split === 'blind') holdoutRows.push(row);\n else if (split === 'exploratory') exploratoryRows.push(row);\n else throw new DatasetError(`CSV ${path} row ${i + 1} has invalid split '${split}'`);\n }\n return {\n exploratory: datasetFromRows(exploratoryRows, observable, 'exploratory-fit', `${path}#exploratory`),\n holdout: datasetFromRows(holdoutRows, observable, 'validation-holdout', `${path}#holdout`),\n };\n}\n"]}
|
|
@@ -19,7 +19,11 @@ export interface DesignBounds {
|
|
|
19
19
|
}>>[];
|
|
20
20
|
readonly sigma?: number;
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Coerce unknown JSON into {@link DesignBounds}. Every bound is a finite
|
|
24
|
+
* number and `steps` a positive integer; a value of another kind is refused,
|
|
25
|
+
* naming the field and what was found. @internal
|
|
26
|
+
*/
|
|
23
27
|
export declare function parseDesignBounds(raw: unknown, source: string): DesignBounds;
|
|
24
28
|
export interface DesignSuggestion {
|
|
25
29
|
readonly point: Readonly<Record<string, number>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"experiment-design.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/experiment-design.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAG/D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC3F,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,EAAE,CAAC;IACvF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"experiment-design.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/experiment-design.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAG/D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC3F,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,EAAE,CAAC;IACvF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAyBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CA4D5E;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAeD,6FAA6F;AAC7F,wBAAgB,0BAA0B,CACxC,EAAE,EAAE,QAAQ,EACZ,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,YAAY,GACnB,gBAAgB,CAkElB"}
|
|
@@ -7,7 +7,36 @@
|
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
9
9
|
import { evalExpr } from '../expr-eval.js';
|
|
10
|
-
/**
|
|
10
|
+
/** What a JSON value is, in the words a file author would use. */
|
|
11
|
+
function kindOf(v) {
|
|
12
|
+
if (v === null)
|
|
13
|
+
return 'null';
|
|
14
|
+
if (Array.isArray(v))
|
|
15
|
+
return 'a list';
|
|
16
|
+
if (typeof v === 'string')
|
|
17
|
+
return 'text';
|
|
18
|
+
if (typeof v === 'number')
|
|
19
|
+
return Number.isFinite(v) ? 'a number' : String(v);
|
|
20
|
+
if (typeof v === 'boolean')
|
|
21
|
+
return 'true or false';
|
|
22
|
+
return typeof v === 'object' ? 'an object' : typeof v;
|
|
23
|
+
}
|
|
24
|
+
/** A finite number, or null: nothing is coerced (`null`, `""` and `"0"` once read as 0). */
|
|
25
|
+
const finite = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : null);
|
|
26
|
+
/** `{min, max}` as two finite numbers, located by `where` in any refusal. */
|
|
27
|
+
function readRange(spec, where) {
|
|
28
|
+
const min = finite(spec.min);
|
|
29
|
+
const max = finite(spec.max);
|
|
30
|
+
if (min === null || max === null) {
|
|
31
|
+
throw new Error(`${where} needs finite min/max numbers (found ${kindOf(spec.min)} and ${kindOf(spec.max)})`);
|
|
32
|
+
}
|
|
33
|
+
return { min, max };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Coerce unknown JSON into {@link DesignBounds}. Every bound is a finite
|
|
37
|
+
* number and `steps` a positive integer; a value of another kind is refused,
|
|
38
|
+
* naming the field and what was found. @internal
|
|
39
|
+
*/
|
|
11
40
|
export function parseDesignBounds(raw, source) {
|
|
12
41
|
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
13
42
|
throw new Error(`design bounds at ${source} is not an object`);
|
|
@@ -21,22 +50,18 @@ export function parseDesignBounds(raw, source) {
|
|
|
21
50
|
if (!spec || typeof spec !== 'object' || Array.isArray(spec)) {
|
|
22
51
|
throw new Error(`design bounds at ${source}: variables.${name} is not an object`);
|
|
23
52
|
}
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
throw new Error(`design bounds at ${source}: variables.${name} needs finite min/max`);
|
|
29
|
-
}
|
|
30
|
-
if (minN > maxN) {
|
|
31
|
-
throw new Error(`design bounds at ${source}: variables.${name} has min > max`);
|
|
53
|
+
const where = `design bounds at ${source}: variables.${name}`;
|
|
54
|
+
const { min, max } = readRange(spec, where);
|
|
55
|
+
if (min > max) {
|
|
56
|
+
throw new Error(`${where} has min > max`);
|
|
32
57
|
}
|
|
33
|
-
const entry = { min
|
|
58
|
+
const entry = { min, max };
|
|
59
|
+
const { steps } = spec;
|
|
34
60
|
if (steps !== undefined) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
throw new Error(`design bounds at ${source}: variables.${name}.steps must be positive`);
|
|
61
|
+
if (typeof steps !== 'number' || !Number.isInteger(steps) || steps < 1) {
|
|
62
|
+
throw new Error(`${where}.steps must be a positive integer (found ${typeof steps === 'number' ? steps : kindOf(steps)})`);
|
|
38
63
|
}
|
|
39
|
-
entry.steps =
|
|
64
|
+
entry.steps = steps;
|
|
40
65
|
}
|
|
41
66
|
variables[name] = entry;
|
|
42
67
|
}
|
|
@@ -54,23 +79,18 @@ export function parseDesignBounds(raw, source) {
|
|
|
54
79
|
if (!r || typeof r !== 'object' || Array.isArray(r)) {
|
|
55
80
|
throw new Error(`design bounds at ${source}: forbidden[${i}].${k} is not an object`);
|
|
56
81
|
}
|
|
57
|
-
|
|
58
|
-
const minN = typeof min === 'number' ? min : Number(min);
|
|
59
|
-
const maxN = typeof max === 'number' ? max : Number(max);
|
|
60
|
-
if (!Number.isFinite(minN) || !Number.isFinite(maxN)) {
|
|
61
|
-
throw new Error(`design bounds at ${source}: forbidden[${i}].${k} needs finite min/max`);
|
|
62
|
-
}
|
|
63
|
-
out[k] = { min: minN, max: maxN };
|
|
82
|
+
out[k] = readRange(r, `design bounds at ${source}: forbidden[${i}].${k}`);
|
|
64
83
|
}
|
|
65
84
|
return out;
|
|
66
85
|
});
|
|
67
86
|
}
|
|
68
87
|
let sigma;
|
|
69
88
|
if (obj.sigma !== undefined) {
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
throw new Error(`design bounds at ${source}: sigma must be a positive number`);
|
|
89
|
+
const s = finite(obj.sigma);
|
|
90
|
+
if (s === null || s <= 0) {
|
|
91
|
+
throw new Error(`design bounds at ${source}: sigma must be a positive number (found ${s === null ? kindOf(obj.sigma) : s})`);
|
|
73
92
|
}
|
|
93
|
+
sigma = s;
|
|
74
94
|
}
|
|
75
95
|
return { variables, ...(forbidden ? { forbidden } : {}), ...(sigma !== undefined ? { sigma } : {}) };
|
|
76
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"experiment-design.js","sourceRoot":"","sources":["../../../src/composition/probe/experiment-design.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Cheap experiment-design suggestions for two competing hypotheses.\n *\n * Grid-search max |H1−H2|/σ under declared bounds. Never recommend a\n * forbidden region.\n *\n * @internal\n */\n\nimport type { ExprNode } from '../../dimensional/ast-types.js';\nimport { evalExpr } from '../expr-eval.js';\n\nexport interface DesignBounds {\n readonly variables: Readonly<Record<string, { min: number; max: number; steps?: number }>>;\n readonly forbidden?: readonly Readonly<Record<string, { min: number; max: number }>>[];\n readonly sigma?: number;\n}\n\n/** Coerce unknown JSON into {@link DesignBounds}. @internal */\nexport function parseDesignBounds(raw: unknown, source: string): DesignBounds {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new Error(`design bounds at ${source} is not an object`);\n }\n const obj = raw as {\n variables?: unknown;\n forbidden?: unknown;\n sigma?: unknown;\n };\n if (!obj.variables || typeof obj.variables !== 'object' || Array.isArray(obj.variables)) {\n throw new Error(`design bounds at ${source} is missing variables`);\n }\n const variables: Record<string, { min: number; max: number; steps?: number }> = {};\n for (const [name, spec] of Object.entries(obj.variables as Record<string, unknown>)) {\n if (!spec || typeof spec !== 'object' || Array.isArray(spec)) {\n throw new Error(`design bounds at ${source}: variables.${name} is not an object`);\n }\n const { min, max, steps } = spec as { min?: unknown; max?: unknown; steps?: unknown };\n const minN = typeof min === 'number' ? min : Number(min);\n const maxN = typeof max === 'number' ? max : Number(max);\n if (!Number.isFinite(minN) || !Number.isFinite(maxN)) {\n throw new Error(`design bounds at ${source}: variables.${name} needs finite min/max`);\n }\n if (minN > maxN) {\n throw new Error(`design bounds at ${source}: variables.${name} has min > max`);\n }\n const entry: { min: number; max: number; steps?: number } = { min: minN, max: maxN };\n if (steps !== undefined) {\n const stepsN = typeof steps === 'number' ? steps : Number(steps);\n if (!Number.isFinite(stepsN) || stepsN <= 0) {\n throw new Error(`design bounds at ${source}: variables.${name}.steps must be positive`);\n }\n entry.steps = stepsN;\n }\n variables[name] = entry;\n }\n let forbidden: DesignBounds['forbidden'];\n if (obj.forbidden !== undefined) {\n if (!Array.isArray(obj.forbidden)) {\n throw new Error(`design bounds at ${source}: forbidden must be an array`);\n }\n forbidden = obj.forbidden.map((region, i) => {\n if (!region || typeof region !== 'object' || Array.isArray(region)) {\n throw new Error(`design bounds at ${source}: forbidden[${i}] is not an object`);\n }\n const out: Record<string, { min: number; max: number }> = {};\n for (const [k, r] of Object.entries(region as Record<string, unknown>)) {\n if (!r || typeof r !== 'object' || Array.isArray(r)) {\n throw new Error(`design bounds at ${source}: forbidden[${i}].${k} is not an object`);\n }\n const { min, max } = r as { min?: unknown; max?: unknown };\n const minN = typeof min === 'number' ? min : Number(min);\n const maxN = typeof max === 'number' ? max : Number(max);\n if (!Number.isFinite(minN) || !Number.isFinite(maxN)) {\n throw new Error(`design bounds at ${source}: forbidden[${i}].${k} needs finite min/max`);\n }\n out[k] = { min: minN, max: maxN };\n }\n return out;\n });\n }\n let sigma: number | undefined;\n if (obj.sigma !== undefined) {\n sigma = typeof obj.sigma === 'number' ? obj.sigma : Number(obj.sigma);\n if (!Number.isFinite(sigma) || sigma <= 0) {\n throw new Error(`design bounds at ${source}: sigma must be a positive number`);\n }\n }\n return { variables, ...(forbidden ? { forbidden } : {}), ...(sigma !== undefined ? { sigma } : {}) };\n}\n\nexport interface DesignSuggestion {\n readonly point: Readonly<Record<string, number>>;\n readonly discrimination: number;\n readonly h1: number;\n readonly h2: number;\n readonly abstained?: boolean;\n readonly reason?: string;\n}\n\nfunction inForbidden(\n point: Record<string, number>,\n forbidden: readonly Readonly<Record<string, { min: number; max: number }>>[] | undefined,\n): boolean {\n if (!forbidden) return false;\n return forbidden.some((region) =>\n Object.entries(region).every(([k, r]) => {\n const v = point[k];\n return v !== undefined && v >= r.min && v <= r.max;\n }),\n );\n}\n\n/** Suggest the grid point that maximises |H1−H2|/σ, skipping forbidden regions. @internal */\nexport function suggestDiscriminatingPoint(\n h1: ExprNode,\n h2: ExprNode,\n bounds: DesignBounds,\n): DesignSuggestion {\n const names = Object.keys(bounds.variables);\n if (names.length === 0) {\n return {\n point: {},\n discrimination: 0,\n h1: NaN,\n h2: NaN,\n abstained: true,\n reason: 'no free variables in bounds',\n };\n }\n\n const sigma = bounds.sigma ?? 1;\n let best: DesignSuggestion | null = null;\n\n const grids = names.map((n) => {\n const b = bounds.variables[n]!;\n const steps = Math.max(2, b.steps ?? 8);\n const out: number[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n out.push(b.min + t * (b.max - b.min));\n }\n return out;\n });\n\n const idx = new Array(names.length).fill(0);\n const rec = (d: number): void => {\n if (d === names.length) {\n const point: Record<string, number> = {};\n for (let i = 0; i < names.length; i++) point[names[i]!] = grids[i]![idx[i]!]!;\n if (inForbidden(point, bounds.forbidden)) return;\n let y1: number;\n let y2: number;\n try {\n y1 = evalExpr(h1, point);\n y2 = evalExpr(h2, point);\n } catch {\n return;\n }\n if (!Number.isFinite(y1) || !Number.isFinite(y2)) return;\n const disc = Math.abs(y1 - y2) / sigma;\n if (!best || disc > best.discrimination) {\n best = { point, discrimination: disc, h1: y1, h2: y2 };\n }\n return;\n }\n for (let i = 0; i < grids[d]!.length; i++) {\n idx[d] = i;\n rec(d + 1);\n }\n };\n rec(0);\n\n if (!best) {\n return {\n point: {},\n discrimination: 0,\n h1: NaN,\n h2: NaN,\n abstained: true,\n reason: 'every grid point was forbidden or non-finite',\n };\n }\n return best;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"experiment-design.js","sourceRoot":"","sources":["../../../src/composition/probe/experiment-design.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Cheap experiment-design suggestions for two competing hypotheses.\n *\n * Grid-search max |H1−H2|/σ under declared bounds. Never recommend a\n * forbidden region.\n *\n * @internal\n */\n\nimport type { ExprNode } from '../../dimensional/ast-types.js';\nimport { evalExpr } from '../expr-eval.js';\n\nexport interface DesignBounds {\n readonly variables: Readonly<Record<string, { min: number; max: number; steps?: number }>>;\n readonly forbidden?: readonly Readonly<Record<string, { min: number; max: number }>>[];\n readonly sigma?: number;\n}\n\n/** What a JSON value is, in the words a file author would use. */\nfunction kindOf(v: unknown): string {\n if (v === null) return 'null';\n if (Array.isArray(v)) return 'a list';\n if (typeof v === 'string') return 'text';\n if (typeof v === 'number') return Number.isFinite(v) ? 'a number' : String(v);\n if (typeof v === 'boolean') return 'true or false';\n return typeof v === 'object' ? 'an object' : typeof v;\n}\n\n/** A finite number, or null: nothing is coerced (`null`, `\"\"` and `\"0\"` once read as 0). */\nconst finite = (v: unknown): number | null => (typeof v === 'number' && Number.isFinite(v) ? v : null);\n\n/** `{min, max}` as two finite numbers, located by `where` in any refusal. */\nfunction readRange(spec: Record<string, unknown>, where: string): { min: number; max: number } {\n const min = finite(spec.min);\n const max = finite(spec.max);\n if (min === null || max === null) {\n throw new Error(`${where} needs finite min/max numbers (found ${kindOf(spec.min)} and ${kindOf(spec.max)})`);\n }\n return { min, max };\n}\n\n/**\n * Coerce unknown JSON into {@link DesignBounds}. Every bound is a finite\n * number and `steps` a positive integer; a value of another kind is refused,\n * naming the field and what was found. @internal\n */\nexport function parseDesignBounds(raw: unknown, source: string): DesignBounds {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new Error(`design bounds at ${source} is not an object`);\n }\n const obj = raw as {\n variables?: unknown;\n forbidden?: unknown;\n sigma?: unknown;\n };\n if (!obj.variables || typeof obj.variables !== 'object' || Array.isArray(obj.variables)) {\n throw new Error(`design bounds at ${source} is missing variables`);\n }\n const variables: Record<string, { min: number; max: number; steps?: number }> = {};\n for (const [name, spec] of Object.entries(obj.variables as Record<string, unknown>)) {\n if (!spec || typeof spec !== 'object' || Array.isArray(spec)) {\n throw new Error(`design bounds at ${source}: variables.${name} is not an object`);\n }\n const where = `design bounds at ${source}: variables.${name}`;\n const { min, max } = readRange(spec as Record<string, unknown>, where);\n if (min > max) {\n throw new Error(`${where} has min > max`);\n }\n const entry: { min: number; max: number; steps?: number } = { min, max };\n const { steps } = spec as { steps?: unknown };\n if (steps !== undefined) {\n if (typeof steps !== 'number' || !Number.isInteger(steps) || steps < 1) {\n throw new Error(`${where}.steps must be a positive integer (found ${typeof steps === 'number' ? steps : kindOf(steps)})`);\n }\n entry.steps = steps;\n }\n variables[name] = entry;\n }\n let forbidden: DesignBounds['forbidden'];\n if (obj.forbidden !== undefined) {\n if (!Array.isArray(obj.forbidden)) {\n throw new Error(`design bounds at ${source}: forbidden must be an array`);\n }\n forbidden = obj.forbidden.map((region, i) => {\n if (!region || typeof region !== 'object' || Array.isArray(region)) {\n throw new Error(`design bounds at ${source}: forbidden[${i}] is not an object`);\n }\n const out: Record<string, { min: number; max: number }> = {};\n for (const [k, r] of Object.entries(region as Record<string, unknown>)) {\n if (!r || typeof r !== 'object' || Array.isArray(r)) {\n throw new Error(`design bounds at ${source}: forbidden[${i}].${k} is not an object`);\n }\n out[k] = readRange(r as Record<string, unknown>, `design bounds at ${source}: forbidden[${i}].${k}`);\n }\n return out;\n });\n }\n let sigma: number | undefined;\n if (obj.sigma !== undefined) {\n const s = finite(obj.sigma);\n if (s === null || s <= 0) {\n throw new Error(`design bounds at ${source}: sigma must be a positive number (found ${s === null ? kindOf(obj.sigma) : s})`);\n }\n sigma = s;\n }\n return { variables, ...(forbidden ? { forbidden } : {}), ...(sigma !== undefined ? { sigma } : {}) };\n}\n\nexport interface DesignSuggestion {\n readonly point: Readonly<Record<string, number>>;\n readonly discrimination: number;\n readonly h1: number;\n readonly h2: number;\n readonly abstained?: boolean;\n readonly reason?: string;\n}\n\nfunction inForbidden(\n point: Record<string, number>,\n forbidden: readonly Readonly<Record<string, { min: number; max: number }>>[] | undefined,\n): boolean {\n if (!forbidden) return false;\n return forbidden.some((region) =>\n Object.entries(region).every(([k, r]) => {\n const v = point[k];\n return v !== undefined && v >= r.min && v <= r.max;\n }),\n );\n}\n\n/** Suggest the grid point that maximises |H1−H2|/σ, skipping forbidden regions. @internal */\nexport function suggestDiscriminatingPoint(\n h1: ExprNode,\n h2: ExprNode,\n bounds: DesignBounds,\n): DesignSuggestion {\n const names = Object.keys(bounds.variables);\n if (names.length === 0) {\n return {\n point: {},\n discrimination: 0,\n h1: NaN,\n h2: NaN,\n abstained: true,\n reason: 'no free variables in bounds',\n };\n }\n\n const sigma = bounds.sigma ?? 1;\n let best: DesignSuggestion | null = null;\n\n const grids = names.map((n) => {\n const b = bounds.variables[n]!;\n const steps = Math.max(2, b.steps ?? 8);\n const out: number[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n out.push(b.min + t * (b.max - b.min));\n }\n return out;\n });\n\n const idx = new Array(names.length).fill(0);\n const rec = (d: number): void => {\n if (d === names.length) {\n const point: Record<string, number> = {};\n for (let i = 0; i < names.length; i++) point[names[i]!] = grids[i]![idx[i]!]!;\n if (inForbidden(point, bounds.forbidden)) return;\n let y1: number;\n let y2: number;\n try {\n y1 = evalExpr(h1, point);\n y2 = evalExpr(h2, point);\n } catch {\n return;\n }\n if (!Number.isFinite(y1) || !Number.isFinite(y2)) return;\n const disc = Math.abs(y1 - y2) / sigma;\n if (!best || disc > best.discrimination) {\n best = { point, discrimination: disc, h1: y1, h2: y2 };\n }\n return;\n }\n for (let i = 0; i < grids[d]!.length; i++) {\n idx[d] = i;\n rec(d + 1);\n }\n };\n rec(0);\n\n if (!best) {\n return {\n point: {},\n discrimination: 0,\n h1: NaN,\n h2: NaN,\n abstained: true,\n reason: 'every grid point was forbidden or non-finite',\n };\n }\n return best;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"falsify.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/falsify.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAI/D,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;CACvE;
|
|
1
|
+
{"version":3,"file":"falsify.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/falsify.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAI/D,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;CACvE;AA6FD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAwBnE;AAED,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,EAAE,SAAS,oBAAoB,EAI5D,CAAC"}
|
|
@@ -77,6 +77,8 @@ function limitsBattery(checks) {
|
|
|
77
77
|
detail: fatal.map((c) => c.detail).join('; '),
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
|
+
// A non-fatal failure (domain not claimed) and an undecided limit (too few evaluable rows)
|
|
81
|
+
// both leave the battery inconclusive; neither is a pass.
|
|
80
82
|
const failedNonFatal = checks.filter((c) => !c.passed && !c.fatal);
|
|
81
83
|
if (failedNonFatal.length > 0) {
|
|
82
84
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"falsify.js","sourceRoot":"","sources":["../../../src/composition/probe/falsify.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Falsification batteries for probe candidates.\n *\n * Persist counterexamples. Failed limits are fatal only when the candidate\n * claims that domain (see limits.ts). Catalog retrodiction is Product A and\n * is not a battery here.\n *\n * @internal\n */\n\nimport type { ExprNode } from '../../dimensional/ast-types.js';\nimport { validate } from '../../dimensional/validator.js';\nimport { evalExpr } from '../expr-eval.js';\nimport { checkDeclaredLimits, type LimitCheckResult } from './limits.js';\nimport type {\n DeclaredLimit,\n FalsificationBattery,\n FalsificationRecord,\n ProbeDataset,\n} from './types.js';\n\nexport interface FalsifyInput {\n readonly expr: ExprNode;\n readonly dataset?: ProbeDataset;\n readonly prefactor?: number;\n readonly claimedRegimes?: Readonly<Record<string, string>>;\n readonly limits?: readonly DeclaredLimit[];\n readonly skipDimensional?: boolean;\n}\n\nexport interface FalsifyResult {\n readonly records: readonly FalsificationRecord[];\n readonly survived: boolean;\n readonly counterexamples: readonly Readonly<Record<string, number>>[];\n}\n\nfunction dimBattery(expr: ExprNode): FalsificationRecord {\n const v = validate(expr);\n if (!v.ok || v.inferredDimension === null) {\n return {\n battery: 'dimensional',\n outcome: 'fail',\n detail: 'expression is dimensionally inconsistent',\n };\n }\n return {\n battery: 'dimensional',\n outcome: 'pass',\n detail: 'expression is dimensionally consistent',\n };\n}\n\nfunction finitenessBattery(\n expr: ExprNode,\n dataset: ProbeDataset | undefined,\n prefactor: number,\n): { record: FalsificationRecord; counterexamples: Record<string, number>[] } {\n if (!dataset || dataset.rows.length === 0) {\n return {\n record: {\n battery: 'finiteness',\n outcome: 'pass',\n detail: 'no rows to evaluate',\n },\n counterexamples: [],\n };\n }\n const counterexamples: Record<string, number>[] = [];\n for (const row of dataset.rows) {\n let y: number;\n try {\n y = prefactor * evalExpr(expr, row);\n } catch {\n counterexamples.push({ ...row });\n continue;\n }\n if (!Number.isFinite(y)) counterexamples.push({ ...row });\n }\n if (counterexamples.length > 0) {\n return {\n record: {\n battery: 'finiteness',\n outcome: 'fail',\n detail: `${counterexamples.length} observation(s) produced non-finite predictions`,\n },\n counterexamples,\n };\n }\n return {\n record: {\n battery: 'finiteness',\n outcome: 'pass',\n detail: 'all predictions finite',\n },\n counterexamples: [],\n };\n}\n\nfunction limitsBattery(checks: readonly LimitCheckResult[]): FalsificationRecord {\n const fatal = checks.filter((c) => c.fatal);\n if (fatal.length > 0) {\n return {\n battery: 'limits',\n outcome: 'fail',\n detail: fatal.map((c) => c.detail).join('; '),\n };\n }\n const failedNonFatal = checks.filter((c) => !c.passed && !c.fatal);\n if (failedNonFatal.length > 0) {\n return {\n battery: 'limits',\n outcome: 'inconclusive',\n detail: failedNonFatal.map((c) => c.detail).join('; '),\n };\n }\n return {\n battery: 'limits',\n outcome: 'pass',\n detail:\n checks.length === 0\n ? 'no declared limits'\n : 'declared limits held or were out of claimed domain',\n };\n}\n\n/**\n * Run the Product B falsification batteries: dimensional, finiteness, limits.\n *\n * Every listed battery can fail. Two batteries once listed here, `retrodiction`\n * and `observational-bounds`, returned `inconclusive` by construction (catalog\n * retrodiction is Product A, and no bound was ever evaluated), so \"survived\n * five batteries\" overstated what was checked; they are not listed until they\n * are real (9.0.0 audit §4 Low). A problem's `observationalBoundIds` stay\n * recorded on the problem and are not a battery.\n *\n * @internal\n */\nexport function runFalsification(input: FalsifyInput): FalsifyResult {\n const prefactor = input.prefactor ?? 1;\n const records: FalsificationRecord[] = [];\n const counterexamples: Record<string, number>[] = [];\n\n if (!input.skipDimensional) {\n records.push(dimBattery(input.expr));\n }\n\n const fin = finitenessBattery(input.expr, input.dataset, prefactor);\n records.push(fin.record);\n counterexamples.push(...fin.counterexamples);\n\n const limitChecks = checkDeclaredLimits(\n input.expr,\n input.dataset,\n prefactor,\n input.limits ?? [],\n input.claimedRegimes ?? {},\n );\n records.push(limitsBattery(limitChecks));\n\n const survived = records.every((r) => r.outcome !== 'fail');\n return { records, survived, counterexamples };\n}\n\n/** The batteries `runFalsification` runs, in order; each one can fail. @internal */\nexport const DEFAULT_BATTERIES: readonly FalsificationBattery[] = [\n 'dimensional',\n 'finiteness',\n 'limits',\n];\n"]}
|
|
1
|
+
{"version":3,"file":"falsify.js","sourceRoot":"","sources":["../../../src/composition/probe/falsify.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Falsification batteries for probe candidates.\n *\n * Persist counterexamples. Failed limits are fatal only when the candidate\n * claims that domain (see limits.ts). Catalog retrodiction is Product A and\n * is not a battery here.\n *\n * @internal\n */\n\nimport type { ExprNode } from '../../dimensional/ast-types.js';\nimport { validate } from '../../dimensional/validator.js';\nimport { evalExpr } from '../expr-eval.js';\nimport { checkDeclaredLimits, type LimitCheckResult } from './limits.js';\nimport type {\n DeclaredLimit,\n FalsificationBattery,\n FalsificationRecord,\n ProbeDataset,\n} from './types.js';\n\nexport interface FalsifyInput {\n readonly expr: ExprNode;\n readonly dataset?: ProbeDataset;\n readonly prefactor?: number;\n readonly claimedRegimes?: Readonly<Record<string, string>>;\n readonly limits?: readonly DeclaredLimit[];\n readonly skipDimensional?: boolean;\n}\n\nexport interface FalsifyResult {\n readonly records: readonly FalsificationRecord[];\n readonly survived: boolean;\n readonly counterexamples: readonly Readonly<Record<string, number>>[];\n}\n\nfunction dimBattery(expr: ExprNode): FalsificationRecord {\n const v = validate(expr);\n if (!v.ok || v.inferredDimension === null) {\n return {\n battery: 'dimensional',\n outcome: 'fail',\n detail: 'expression is dimensionally inconsistent',\n };\n }\n return {\n battery: 'dimensional',\n outcome: 'pass',\n detail: 'expression is dimensionally consistent',\n };\n}\n\nfunction finitenessBattery(\n expr: ExprNode,\n dataset: ProbeDataset | undefined,\n prefactor: number,\n): { record: FalsificationRecord; counterexamples: Record<string, number>[] } {\n if (!dataset || dataset.rows.length === 0) {\n return {\n record: {\n battery: 'finiteness',\n outcome: 'pass',\n detail: 'no rows to evaluate',\n },\n counterexamples: [],\n };\n }\n const counterexamples: Record<string, number>[] = [];\n for (const row of dataset.rows) {\n let y: number;\n try {\n y = prefactor * evalExpr(expr, row);\n } catch {\n counterexamples.push({ ...row });\n continue;\n }\n if (!Number.isFinite(y)) counterexamples.push({ ...row });\n }\n if (counterexamples.length > 0) {\n return {\n record: {\n battery: 'finiteness',\n outcome: 'fail',\n detail: `${counterexamples.length} observation(s) produced non-finite predictions`,\n },\n counterexamples,\n };\n }\n return {\n record: {\n battery: 'finiteness',\n outcome: 'pass',\n detail: 'all predictions finite',\n },\n counterexamples: [],\n };\n}\n\nfunction limitsBattery(checks: readonly LimitCheckResult[]): FalsificationRecord {\n const fatal = checks.filter((c) => c.fatal);\n if (fatal.length > 0) {\n return {\n battery: 'limits',\n outcome: 'fail',\n detail: fatal.map((c) => c.detail).join('; '),\n };\n }\n // A non-fatal failure (domain not claimed) and an undecided limit (too few evaluable rows)\n // both leave the battery inconclusive; neither is a pass.\n const failedNonFatal = checks.filter((c) => !c.passed && !c.fatal);\n if (failedNonFatal.length > 0) {\n return {\n battery: 'limits',\n outcome: 'inconclusive',\n detail: failedNonFatal.map((c) => c.detail).join('; '),\n };\n }\n return {\n battery: 'limits',\n outcome: 'pass',\n detail:\n checks.length === 0\n ? 'no declared limits'\n : 'declared limits held or were out of claimed domain',\n };\n}\n\n/**\n * Run the Product B falsification batteries: dimensional, finiteness, limits.\n *\n * Every listed battery can fail. Two batteries once listed here, `retrodiction`\n * and `observational-bounds`, returned `inconclusive` by construction (catalog\n * retrodiction is Product A, and no bound was ever evaluated), so \"survived\n * five batteries\" overstated what was checked; they are not listed until they\n * are real (9.0.0 audit §4 Low). A problem's `observationalBoundIds` stay\n * recorded on the problem and are not a battery.\n *\n * @internal\n */\nexport function runFalsification(input: FalsifyInput): FalsifyResult {\n const prefactor = input.prefactor ?? 1;\n const records: FalsificationRecord[] = [];\n const counterexamples: Record<string, number>[] = [];\n\n if (!input.skipDimensional) {\n records.push(dimBattery(input.expr));\n }\n\n const fin = finitenessBattery(input.expr, input.dataset, prefactor);\n records.push(fin.record);\n counterexamples.push(...fin.counterexamples);\n\n const limitChecks = checkDeclaredLimits(\n input.expr,\n input.dataset,\n prefactor,\n input.limits ?? [],\n input.claimedRegimes ?? {},\n );\n records.push(limitsBattery(limitChecks));\n\n const survived = records.every((r) => r.outcome !== 'fail');\n return { records, survived, counterexamples };\n}\n\n/** The batteries `runFalsification` runs, in order; each one can fail. @internal */\nexport const DEFAULT_BATTERIES: readonly FalsificationBattery[] = [\n 'dimensional',\n 'finiteness',\n 'limits',\n];\n"]}
|
|
@@ -7,6 +7,12 @@ import type { ExprNode } from '../../dimensional/ast-types.js';
|
|
|
7
7
|
import { type ProbeDataset } from './types.js';
|
|
8
8
|
export interface FitResult {
|
|
9
9
|
readonly prefactor: number;
|
|
10
|
+
/**
|
|
11
|
+
* Standard error of the prefactor from the residual scatter of the exploratory rows
|
|
12
|
+
* (MathTS `ols`, one column, no intercept); null below two finite rows or when the
|
|
13
|
+
* form is zero on every row.
|
|
14
|
+
*/
|
|
15
|
+
readonly prefactorStderr: number | null;
|
|
10
16
|
readonly exploratoryRmse: number;
|
|
11
17
|
readonly nExploratory: number;
|
|
12
18
|
readonly holdoutRmse: number | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fit.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/fit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"fit.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/fit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAIpE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC;AAuDD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,YAAY,EACzB,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,UAAU,SAAsB,GAC/B,SAAS,CAuDX"}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module composition/probe/fit
|
|
5
5
|
*/
|
|
6
|
+
import { norm2, pairwiseDot } from '@danielsimonjr/mathts-core';
|
|
7
|
+
import { ols } from '@danielsimonjr/mathts-functions';
|
|
6
8
|
import { evalExpr } from '../expr-eval.js';
|
|
7
9
|
import { DEFAULT_HOLDOUT_TOL } from './types.js';
|
|
8
10
|
import { scalarDiscrepancy } from './residual.js';
|
|
@@ -22,6 +24,35 @@ function observed(rows) {
|
|
|
22
24
|
return y;
|
|
23
25
|
});
|
|
24
26
|
}
|
|
27
|
+
/** Root-mean-square additive discrepancy: core `norm2` of the residuals (the scaled, overflow-safe 2-norm) over √n. */
|
|
28
|
+
function rmse(observedValues, predicted) {
|
|
29
|
+
const residuals = observedValues.map((obs, i) => scalarDiscrepancy(obs, predicted[i], 'additive'));
|
|
30
|
+
return norm2(residuals) / Math.sqrt(residuals.length);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The standard error of the least-squares prefactor: MathTS `ols` on the single
|
|
34
|
+
* column f with no intercept, the column scaled to order one first because
|
|
35
|
+
* `ols` tests singularity with an absolute 1e-15 (a column of 1e-9 is refused
|
|
36
|
+
* unscaled), then unscaled. The estimator is the one `pairwiseDot` ratio above
|
|
37
|
+
* gives, so the coefficient itself is not read back from here. Null below two
|
|
38
|
+
* finite rows (no residual degree of freedom) or when f is zero everywhere.
|
|
39
|
+
*/
|
|
40
|
+
function prefactorStderr(fs, ys) {
|
|
41
|
+
if (fs.length < 2)
|
|
42
|
+
return null;
|
|
43
|
+
const scale = fs.reduce((m, v) => Math.max(m, Math.abs(v)), 0);
|
|
44
|
+
if (!(scale > 0))
|
|
45
|
+
return null;
|
|
46
|
+
let fit;
|
|
47
|
+
try {
|
|
48
|
+
fit = ols(fs.map((v) => [v / scale]), [...ys], { intercept: false });
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const se = fit.stderr[0];
|
|
54
|
+
return typeof se === 'number' && Number.isFinite(se) ? se / scale : null;
|
|
55
|
+
}
|
|
25
56
|
function predictorKey(row, observable) {
|
|
26
57
|
const predictors = {};
|
|
27
58
|
for (const [key, value] of Object.entries(row)) {
|
|
@@ -53,25 +84,20 @@ export function fitPrefactor(expr, exploratory, holdout, holdoutTol = DEFAULT_HO
|
|
|
53
84
|
}
|
|
54
85
|
const y = observed(exploratory);
|
|
55
86
|
const f = predictions(expr, exploratory, 1);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const prefactor = den > 0 ? num / den : 1;
|
|
87
|
+
// The least-squares prefactor over the rows where the form is finite: c = f·y / f·f
|
|
88
|
+
// (core `pairwiseDot`, a pairwise sum).
|
|
89
|
+
const finite = f.map((v, i) => [v, y[i]]).filter(([v]) => Number.isFinite(v));
|
|
90
|
+
const fs = finite.map(([v]) => v);
|
|
91
|
+
const ys = finite.map(([, obs]) => obs);
|
|
92
|
+
const den = pairwiseDot(fs, fs);
|
|
93
|
+
const prefactor = den > 0 ? pairwiseDot(fs, ys) / den : 1;
|
|
94
|
+
const stderr = den > 0 ? prefactorStderr(fs, ys) : null;
|
|
65
95
|
const pred = predictions(expr, exploratory, prefactor);
|
|
66
|
-
|
|
67
|
-
for (let i = 0; i < y.length; i++) {
|
|
68
|
-
const r = scalarDiscrepancy(y[i], pred[i], 'additive');
|
|
69
|
-
acc += r * r;
|
|
70
|
-
}
|
|
71
|
-
const exploratoryRmse = Math.sqrt(acc / y.length);
|
|
96
|
+
const exploratoryRmse = rmse(y, pred);
|
|
72
97
|
if (!holdout || holdout.rows.length === 0) {
|
|
73
98
|
return {
|
|
74
99
|
prefactor,
|
|
100
|
+
prefactorStderr: stderr,
|
|
75
101
|
exploratoryRmse,
|
|
76
102
|
nExploratory: y.length,
|
|
77
103
|
holdoutRmse: null,
|
|
@@ -81,16 +107,14 @@ export function fitPrefactor(expr, exploratory, holdout, holdoutTol = DEFAULT_HO
|
|
|
81
107
|
}
|
|
82
108
|
const yh = observed(holdout);
|
|
83
109
|
const ph = predictions(expr, holdout, prefactor);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
const holdoutRmse = Math.sqrt(hacc / yh.length);
|
|
90
|
-
const scale = Math.max(...yh.map(Math.abs), ...ph.map(Math.abs), 1e-12);
|
|
110
|
+
const holdoutRmse = rmse(yh, ph);
|
|
111
|
+
// A reduce, not `Math.max(...rows)`: a spread of a large holdout overflows the call stack.
|
|
112
|
+
const maxAbs = (m, v) => (Number.isFinite(v) ? Math.max(m, Math.abs(v)) : m);
|
|
113
|
+
const scale = ph.reduce(maxAbs, yh.reduce(maxAbs, 1e-12));
|
|
91
114
|
const holdoutSupported = holdoutRmse <= holdoutTol * scale;
|
|
92
115
|
return {
|
|
93
116
|
prefactor,
|
|
117
|
+
prefactorStderr: stderr,
|
|
94
118
|
exploratoryRmse,
|
|
95
119
|
nExploratory: y.length,
|
|
96
120
|
holdoutRmse,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fit.js","sourceRoot":"","sources":["../../../src/composition/probe/fit.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Prefactor fit + holdout evaluation. Generation never sees holdout rows.\n *\n * @module composition/probe/fit\n */\n\nimport type { ExprNode } from '../../dimensional/ast-types.js';\nimport { evalExpr } from '../expr-eval.js';\nimport { DEFAULT_HOLDOUT_TOL, type ProbeDataset } from './types.js';\nimport { scalarDiscrepancy } from './residual.js';\nimport { canonicalJson } from './serialize.js';\n\nexport interface FitResult {\n readonly prefactor: number;\n readonly exploratoryRmse: number;\n readonly nExploratory: number;\n readonly holdoutRmse: number | null;\n readonly nHoldout: number;\n readonly holdoutSupported: boolean;\n}\n\nfunction predictions(expr: ExprNode, rows: ProbeDataset, prefactor: number): number[] {\n return rows.rows.map((row) => {\n const y = evalExpr(expr, row);\n return prefactor * y;\n });\n}\n\nfunction observed(rows: ProbeDataset): number[] {\n return rows.rows.map((row) => {\n const y = row[rows.observable];\n if (!Number.isFinite(y)) {\n throw new RangeError(`fit: row missing finite observable '${rows.observable}'`);\n }\n return y;\n });\n}\n\nfunction predictorKey(row: Readonly<Record<string, number>>, observable: string): string {\n const predictors: Record<string, number> = {};\n for (const [key, value] of Object.entries(row)) {\n if (key !== observable) predictors[key] = value;\n }\n return canonicalJson(predictors);\n}\n\n/**\n * Least-squares prefactor c in y ≈ c · f(x) on exploratory data, then score\n * locked holdout. Holdout must not have been in the generation context.\n *\n * @internal\n */\nexport function fitPrefactor(\n expr: ExprNode,\n exploratory: ProbeDataset,\n holdout: ProbeDataset | undefined,\n holdoutTol = DEFAULT_HOLDOUT_TOL,\n): FitResult {\n if (exploratory.role !== 'exploratory-fit') {\n throw new RangeError(`fit: exploratory role must be exploratory-fit (got '${exploratory.role}')`);\n }\n if (holdout) {\n if (holdout.role !== 'validation-holdout' && holdout.role !== 'external-replication') {\n throw new RangeError(`fit: holdout role must be validation-holdout or external-replication`);\n }\n const holdKeys = new Set(holdout.rows.map((r) => predictorKey(r, holdout.observable)));\n for (const row of exploratory.rows) {\n if (holdKeys.has(predictorKey(row, exploratory.observable))) {\n throw new RangeError('fit: holdout row leaked into exploratory set');\n }\n }\n }\n const y = observed(exploratory);\n const f = predictions(expr, exploratory, 1);\n let num = 0;\n let den = 0;\n for (let i = 0; i < y.length; i++) {\n if (!Number.isFinite(f[i])) continue;\n num += f[i] * y[i];\n den += f[i] * f[i];\n }\n const prefactor = den > 0 ? num / den : 1;\n const pred = predictions(expr, exploratory, prefactor);\n let acc = 0;\n for (let i = 0; i < y.length; i++) {\n const r = scalarDiscrepancy(y[i], pred[i], 'additive');\n acc += r * r;\n }\n const exploratoryRmse = Math.sqrt(acc / y.length);\n\n if (!holdout || holdout.rows.length === 0) {\n return {\n prefactor,\n exploratoryRmse,\n nExploratory: y.length,\n holdoutRmse: null,\n nHoldout: 0,\n holdoutSupported: false,\n };\n }\n const yh = observed(holdout);\n const ph = predictions(expr, holdout, prefactor);\n let hacc = 0;\n for (let i = 0; i < yh.length; i++) {\n const r = scalarDiscrepancy(yh[i], ph[i], 'additive');\n hacc += r * r;\n }\n const holdoutRmse = Math.sqrt(hacc / yh.length);\n const scale =\n Math.max(...yh.map(Math.abs), ...ph.map(Math.abs), 1e-12);\n const holdoutSupported = holdoutRmse <= holdoutTol * scale;\n return {\n prefactor,\n exploratoryRmse,\n nExploratory: y.length,\n holdoutRmse,\n nHoldout: yh.length,\n holdoutSupported,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fit.js","sourceRoot":"","sources":["../../../src/composition/probe/fit.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Prefactor fit + holdout evaluation. Generation never sees holdout rows.\n *\n * @module composition/probe/fit\n */\n\nimport { norm2, pairwiseDot } from '@danielsimonjr/mathts-core';\nimport { ols } from '@danielsimonjr/mathts-functions';\nimport type { ExprNode } from '../../dimensional/ast-types.js';\nimport { evalExpr } from '../expr-eval.js';\nimport { DEFAULT_HOLDOUT_TOL, type ProbeDataset } from './types.js';\nimport { scalarDiscrepancy } from './residual.js';\nimport { canonicalJson } from './serialize.js';\n\nexport interface FitResult {\n readonly prefactor: number;\n /**\n * Standard error of the prefactor from the residual scatter of the exploratory rows\n * (MathTS `ols`, one column, no intercept); null below two finite rows or when the\n * form is zero on every row.\n */\n readonly prefactorStderr: number | null;\n readonly exploratoryRmse: number;\n readonly nExploratory: number;\n readonly holdoutRmse: number | null;\n readonly nHoldout: number;\n readonly holdoutSupported: boolean;\n}\n\nfunction predictions(expr: ExprNode, rows: ProbeDataset, prefactor: number): number[] {\n return rows.rows.map((row) => {\n const y = evalExpr(expr, row);\n return prefactor * y;\n });\n}\n\nfunction observed(rows: ProbeDataset): number[] {\n return rows.rows.map((row) => {\n const y = row[rows.observable];\n if (!Number.isFinite(y)) {\n throw new RangeError(`fit: row missing finite observable '${rows.observable}'`);\n }\n return y;\n });\n}\n\n/** Root-mean-square additive discrepancy: core `norm2` of the residuals (the scaled, overflow-safe 2-norm) over √n. */\nfunction rmse(observedValues: readonly number[], predicted: readonly number[]): number {\n const residuals = observedValues.map((obs, i) => scalarDiscrepancy(obs, predicted[i]!, 'additive'));\n return norm2(residuals) / Math.sqrt(residuals.length);\n}\n\n/**\n * The standard error of the least-squares prefactor: MathTS `ols` on the single\n * column f with no intercept, the column scaled to order one first because\n * `ols` tests singularity with an absolute 1e-15 (a column of 1e-9 is refused\n * unscaled), then unscaled. The estimator is the one `pairwiseDot` ratio above\n * gives, so the coefficient itself is not read back from here. Null below two\n * finite rows (no residual degree of freedom) or when f is zero everywhere.\n */\nfunction prefactorStderr(fs: readonly number[], ys: readonly number[]): number | null {\n if (fs.length < 2) return null;\n const scale = fs.reduce((m, v) => Math.max(m, Math.abs(v)), 0);\n if (!(scale > 0)) return null;\n let fit;\n try {\n fit = ols(fs.map((v) => [v / scale]), [...ys], { intercept: false });\n } catch {\n return null;\n }\n const se: unknown = fit.stderr[0];\n return typeof se === 'number' && Number.isFinite(se) ? se / scale : null;\n}\n\nfunction predictorKey(row: Readonly<Record<string, number>>, observable: string): string {\n const predictors: Record<string, number> = {};\n for (const [key, value] of Object.entries(row)) {\n if (key !== observable) predictors[key] = value;\n }\n return canonicalJson(predictors);\n}\n\n/**\n * Least-squares prefactor c in y ≈ c · f(x) on exploratory data, then score\n * locked holdout. Holdout must not have been in the generation context.\n *\n * @internal\n */\nexport function fitPrefactor(\n expr: ExprNode,\n exploratory: ProbeDataset,\n holdout: ProbeDataset | undefined,\n holdoutTol = DEFAULT_HOLDOUT_TOL,\n): FitResult {\n if (exploratory.role !== 'exploratory-fit') {\n throw new RangeError(`fit: exploratory role must be exploratory-fit (got '${exploratory.role}')`);\n }\n if (holdout) {\n if (holdout.role !== 'validation-holdout' && holdout.role !== 'external-replication') {\n throw new RangeError(`fit: holdout role must be validation-holdout or external-replication`);\n }\n const holdKeys = new Set(holdout.rows.map((r) => predictorKey(r, holdout.observable)));\n for (const row of exploratory.rows) {\n if (holdKeys.has(predictorKey(row, exploratory.observable))) {\n throw new RangeError('fit: holdout row leaked into exploratory set');\n }\n }\n }\n const y = observed(exploratory);\n const f = predictions(expr, exploratory, 1);\n // The least-squares prefactor over the rows where the form is finite: c = f·y / f·f\n // (core `pairwiseDot`, a pairwise sum).\n const finite = f.map((v, i) => [v, y[i]!] as const).filter(([v]) => Number.isFinite(v));\n const fs = finite.map(([v]) => v);\n const ys = finite.map(([, obs]) => obs);\n const den = pairwiseDot(fs, fs);\n const prefactor = den > 0 ? pairwiseDot(fs, ys) / den : 1;\n const stderr = den > 0 ? prefactorStderr(fs, ys) : null;\n const pred = predictions(expr, exploratory, prefactor);\n const exploratoryRmse = rmse(y, pred);\n\n if (!holdout || holdout.rows.length === 0) {\n return {\n prefactor,\n prefactorStderr: stderr,\n exploratoryRmse,\n nExploratory: y.length,\n holdoutRmse: null,\n nHoldout: 0,\n holdoutSupported: false,\n };\n }\n const yh = observed(holdout);\n const ph = predictions(expr, holdout, prefactor);\n const holdoutRmse = rmse(yh, ph);\n // A reduce, not `Math.max(...rows)`: a spread of a large holdout overflows the call stack.\n const maxAbs = (m: number, v: number) => (Number.isFinite(v) ? Math.max(m, Math.abs(v)) : m);\n const scale = ph.reduce(maxAbs, yh.reduce(maxAbs, 1e-12));\n const holdoutSupported = holdoutRmse <= holdoutTol * scale;\n return {\n prefactor,\n prefactorStderr: stderr,\n exploratoryRmse,\n nExploratory: y.length,\n holdoutRmse,\n nHoldout: yh.length,\n holdoutSupported,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontier.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/frontier.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"frontier.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/frontier.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAuB3E;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,CAmChF;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,CA2B7E;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,CAwB1E;AAMD,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,CAExE;AAED,6CAA6C;AAC7C,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,EAAE,EAAE,MAAM,GACT,WAAW,GAAG,SAAS,CAEzB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAC/B,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,EACrC,WAAW,CAAC,EAAE,YAAY,EAC1B,OAAO,CAAC,EAAE,YAAY,GACrB,aAAa,CA8Df"}
|
|
@@ -7,6 +7,7 @@ import { proposeLinkCandidates, proposeOrphanConnectors } from '../bridge-analys
|
|
|
7
7
|
import { predictMissingBridges } from '../bridge-prediction.js';
|
|
8
8
|
import { QUANTITY_IDENTIFICATIONS } from '../compose.js';
|
|
9
9
|
import { candidateId, candidateIdIfSlug } from '../adjudication.js';
|
|
10
|
+
import { logDesign, logDesignRank, piStructure } from './power-law.js';
|
|
10
11
|
const ALIAS_PAIRS = new Set(QUANTITY_IDENTIFICATIONS.map((id) => candidateId(id.from, id.to)));
|
|
11
12
|
/**
|
|
12
13
|
* Stable pair token. Slug pairs keep the ledger id. Other symbols are
|
|
@@ -143,32 +144,49 @@ export function problemFromResidualGap(gap, target, governing, exploratory, hold
|
|
|
143
144
|
if (gap.kind === 'relation-link' || gap.kind === 'regime-transition') {
|
|
144
145
|
throw new RangeError(`problemFromResidualGap: ${gap.kind} is not a Product B search target; use upt discover`);
|
|
145
146
|
}
|
|
147
|
+
// Identifiability is the rank of the log-design [1, log π₁, …, log πₖ] over the exploratory
|
|
148
|
+
// rows (MathTS `matrixRank`), against the k + 1 parameters of a rational power law: a
|
|
149
|
+
// prefactor and one exponent per π-group of the governing set. The row count is kept under
|
|
150
|
+
// its own name; it is not a count of independent observations (six rows with c/d = (a/b)²
|
|
151
|
+
// on every one of them carry two).
|
|
146
152
|
const nObs = exploratory?.rows.length ?? 0;
|
|
147
|
-
const
|
|
148
|
-
const
|
|
153
|
+
const { groups } = piStructure(target, governing);
|
|
154
|
+
const k = groups.length;
|
|
155
|
+
const nPar = 1 + k;
|
|
156
|
+
const design = nObs > 0 ? logDesign(groups, exploratory.rows) : { rows: [], used: 0, skipped: 0 };
|
|
157
|
+
const rank = logDesignRank(design);
|
|
158
|
+
const status = nObs === 0 ? 'unknown' : rank >= nPar ? 'identifiable' : 'partially-identifiable';
|
|
159
|
+
const parameters = k === 0 ? 'a prefactor' : `a prefactor and ${k} exponent(s)`;
|
|
160
|
+
const reasons = status === 'unknown'
|
|
161
|
+
? ['no observations: identifiability not assessed']
|
|
162
|
+
: status === 'identifiable'
|
|
163
|
+
? [`rank ${rank} of the log-design over ${design.used} usable row(s) of ${nObs}: ${parameters} identifiable`]
|
|
164
|
+
: [
|
|
165
|
+
`rank ${rank} of the log-design over ${design.used} usable row(s) of ${nObs} (${design.skipped} with a non-positive π-group), ` +
|
|
166
|
+
`against ${nPar} parameters (${parameters}): the exponents are not all identifiable; the monomial prefactor is fit on the linear scale`,
|
|
167
|
+
];
|
|
149
168
|
const enriched = {
|
|
150
169
|
...gap,
|
|
151
170
|
identifiability: {
|
|
152
171
|
kind: 'parametric',
|
|
153
172
|
parametric: {
|
|
154
|
-
status
|
|
155
|
-
rank
|
|
173
|
+
status,
|
|
174
|
+
rank,
|
|
156
175
|
nParameters: nPar,
|
|
157
|
-
nIndependentObservations:
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
: ['insufficient observations for a unique prefactor'],
|
|
176
|
+
nIndependentObservations: rank,
|
|
177
|
+
nObservations: nObs,
|
|
178
|
+
reasons,
|
|
161
179
|
},
|
|
162
180
|
},
|
|
163
181
|
searchability: {
|
|
164
|
-
searchable:
|
|
165
|
-
reasons:
|
|
166
|
-
? ['
|
|
167
|
-
:
|
|
168
|
-
? ['
|
|
169
|
-
: ['
|
|
182
|
+
searchable: true,
|
|
183
|
+
reasons: status === 'unknown'
|
|
184
|
+
? ['no data — structural generation only; status will be insufficient-evidence']
|
|
185
|
+
: status === 'identifiable'
|
|
186
|
+
? ['parametric rank sufficient for a monomial prefactor and the π-group exponents']
|
|
187
|
+
: ['the monomial prefactor is identifiable; the power-law fit abstains by itself on a rank-deficient design'],
|
|
170
188
|
},
|
|
171
|
-
status:
|
|
189
|
+
status: 'searchable',
|
|
172
190
|
};
|
|
173
191
|
return {
|
|
174
192
|
gap: enriched,
|