feat: measurement uncertainty for quantities and measured constants - #819
Merged
Conversation
A failure said which workflows grew and by how much, leaving the useful question - what got more expensive - to be answered by hand afterwards. The suite's baselines record the sha they were measured from, so the job can now check out that exact tree and attribute the offending workflows against it, naming the templates whose instantiation counts moved. The gate step becomes non-fatal so the explanation runs before the job ends, and a final step fails it as before. Capped at three workflows, and it says so when there is no recorded sha to compare against rather than guessing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds `uncertain<T>`, a representation type carrying a value and its standard
uncertainty, and teaches the library which physical constants are measured
rather than exact by definition.
Uncertainty is modelled as a relational property: in its own unit a measured
constant is exactly `1`, and it is the conversion factor between units that
carries the uncertainty. The conversion engine therefore derives a factor's
relative standard uncertainty from the measured constants in both units'
definitions, so a constant appearing on both sides cancels symbolically (a
solar mass expressed in Earth masses stays exact) and only the surviving
contributions combine in quadrature. Representations opt in through the new
`fold_conversion_uncertainty` customization point; every other representation
converts exactly and the machinery compiles away.
Constants declare their published uncertainty in their definition:
named_constant<"G", ..., relative_standard_uncertainty{...}>
which makes exact-vs-measured visible to the type system through the
`MeasuredConstant` concept and gates `measurement_of` and
`get_relative_standard_uncertainty`. Asking for the measurement of a constant
that is exact by definition does not compile.
Values are transcribed from the published CODATA tables rather than recomputed
from the rounded value/uncertainty pairs, which disagree in the last digit.
Annotated: `iau::newtonian_constant_of_gravitation` and every measured constant
in the three `hep` CODATA namespaces. `k_B` is annotated for CODATA 2014 only,
being exact since the 2019 SI redefinition. `hep` vacuum magnetic permeability
moves out of the exact section into the per-release namespaces for the opposite
reason: exactly 4π×10⁻⁷ before 2019, measured since.
The `measurement` example is replaced by `weighing_the_earth`, which determines
the mass of the Earth from a pendulum, a radius, and `G`, and prints an
uncertainty budget showing that `G` is negligible next to the stopwatch.
Resolves #464
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The static tests asserted exact floating-point equality between a published `u_r` literal and the value materialized from the constant's exact magnitude. Those need not agree bit for bit across platforms, so Apple Clang, Clang-18 on arm64, MSVC, and GCC-12 Debug failed while local Release builds passed. Uses the existing `approx_equal` test helper on dimensionless quantities instead, which also replaces two ad-hoc tolerance helpers. The derivation checks pass an explicit tolerance, being computed through the consteval root rather than read straight from a magnitude. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #464.
Adds
uncertain<T>, a representation type carrying a value and its standard uncertainty, and teaches the library which physical constants are measured rather than exact by definition.The model
Uncertainty is relational: in its own unit a measured constant is exactly
1, and it is the conversion factor between units that carries the uncertainty. So the conversion engine derives a factor's relative standard uncertainty from the measured constants in both units' definitions. A constant appearing on both sides cancels symbolically, which no value-level scheme can get right:Representations opt in through the new
fold_conversion_uncertaintycustomization point. Every other representation converts exactly and the whole mechanism, including the derivation, compiles away.Constants
A measured constant declares its published uncertainty in its definition, as an exact magnitude, so no representation type is imposed:
This makes exact-vs-measured visible to the type system via
MeasuredConstant, which gatesmeasurement_ofandget_relative_standard_uncertainty. Asking for the measurement of a constant that is exact by definition does not compile: "exact by definition" and "measured infinitely precisely" are different statements.Values are transcribed from the published CODATA tables, not recomputed from the rounded value/uncertainty pairs, which disagree in the last digit (2022 α is 1.6, not 1.5 × 10⁻¹⁰). Annotated:
iau::newtonian_constant_of_gravitationand every measured constant across the threehepCODATA namespaces.Two metrological corrections fall out:
k_Bis annotated for CODATA 2014 only, being exact since the 2019 SI redefinition.hepvacuum magnetic permeability moves out of the "exact across all releases" section into the per-release namespaces, for the opposite reason: exactly 4π×10⁻⁷ before 2019, measured since. The old definition was 3.6σ from the CODATA 2018 value.Example
measurementis replaced byweighing_the_earth, a scenario rather than a feature tour: determine the mass of the Earth from a pendulum, a radius, andG, then print an uncertainty budget showing thatGis some sixty times below the stopwatch noise, and that the modelling bias of a uniform sphere is larger than the random uncertainty.Testing
Compile-time assertions pin the derivation rules (symbolic cancellation, quadrature, fractional powers, annotated constants not recursed). Runtime tests cover propagation, all three conversion spellings (
.in(U),.in<Rep>(U),value_cast<U, Rep>), and the per-release CODATA values.Verified locally on gcc-12, gcc-15, clang-16, and clang-21, plus header-set verification and the full suite (130,142 assertions). Opened as a PR so CI can confirm the rest of the matrix.
🤖 Generated with Claude Code