Skip to content

Add shared endpoint-aware momentum input and precision diagnostics - #127

Merged
ianmccul merged 2 commits into
mainfrom
feature/endpoint-momentum-input
Nov 7, 2026
Merged

ianmccul merged 2 commits into
mainfrom
feature/endpoint-momentum-input

Conversation

@ianmccul

@ianmccul ianmccul commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

A momentum close to pi can lose its entire endpoint distance when parsed directly into the calculation's scalar type. Add a model-independent MomentumInput/MomentumCoordinate<Real> interface that preserves b = log(tan(q_folded/2)), exact endpoints and reflection, and exposes explicit checked scalar conversion. This is reusable by six- and eight-spinon geometry and other frontends.

The XXX thermodynamic spectrum and moment apps share three mutually exclusive inputs: --momentum, --momentum-from-pi, and --momentum-beta. MPFR-enabled builds convert the original decimal text at independently guarded precision before rounding beta to the working type; native-only builds use the widest enabled native format. Diagnostics estimate both input-to-beta and scalar-angle conversion errors, including cancellation near pi, with a configurable absolute-beta warning threshold. Exports retain the input and conversion metadata.

Scalar backends preserve ordinary decimal angles independently of the rounded working beta; beta/distance inputs are converted at reference precision before narrowing. An explicit warning tolerance requires a momentum input.

Current kernels still consume scalar q: an interior coordinate that would collapse to an endpoint fails before exports are opened. This PR provides the shared coordinate/input layer; migrating integration geometry is separate. Error estimates are roundoff diagnostics, not rigorous interval bounds or kernel error estimates.

Validation with GCC 13 and pinned Uni20 ca350254:

  • Native-only build: 20 focused unit/frontend and existing CLI checks pass.
  • MPFR/binary128 build: 22 corresponding checks pass.
  • Binary128 without MPFR: 21 checks pass, including both frontends. The focused ci-momentum-native128 preset covers this configuration separately from the current GitHub CI matrix.
  • Existing selected-sector spectrum, moment and thermodynamic precision regressions pass (3 additional checks).
  • Tests cover beta ±1000, tiny decimal momenta, high-precision pi-minus-offset conversion, subnormal reconstruction, ordinary-angle preservation, nonzero input underflow, reflection, symbolic endpoints, precision diagnostics, conflicts, metadata and preservation of existing export files on conversion failure.

Documentation: docs/momentum-input.md, linked from command-line and XXX model guides.

Copilot AI lite review requested due to automatic review settings November 6, 2026 15:22
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-06T16:02:24.741116Z e0eb329 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 33a28d1003

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread include/bethe/momentum_input.hpp Resolved
Comment thread include/bethe/momentum_input.hpp Resolved

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The review records no active issues requiring resolution for this change.

No open issues 🎉

What changed in this PR

Adds a reusable, endpoint-aware momentum input layer for the XXX thermodynamic spectrum and moments frontends. It preserves logarithmic coordinates and symbolic endpoints, supports precision-aware scalar conversion, and records conversion diagnostics and metadata.

Changes:

  • Introduces MomentumInput, MomentumCoordinate, endpoint handling, reflection, checked scalar conversion, and precision diagnostics.
  • Adds mutually exclusive --momentum, --momentum-from-pi, and --momentum-beta options to both thermodynamic applications.
  • Adds unit, CLI, frontend, export-preservation, precision, and documentation coverage.

Review note: include/bethe/momentum_input.hpp:255 contains a moderate issue: the recovery message for a decimal rounding to the 2*pi endpoint incorrectly suggests specifying pi, which changes the requested endpoint.

File Description
tests/​test_momentum_input.cpp Tests coordinate behavior, endpoints, reflection, precision, validation, and diagnostics.
tests/​test_cli_momentum_input.cpp Tests CLI exclusivity, input preservation, scalar collapse, and warnings.
tests/​CMakeLists.txt Registers the new unit, CLI, and frontend tests.
tests/​check_momentum_input_cli.py Exercises both production frontends and export behavior.
include/​bethe/​momentum_input.hpp Implements shared endpoint-aware momentum parsing and conversion diagnostics.
docs/​xxx-structure-factor-thermo.md Links the structure-factor guide to momentum-input documentation.
docs/​xxx-six-spinon-structure-factor.md Links the six-spinon guide to momentum-input documentation.
docs/​xxx-six-spinon-moments.md Links the six-spinon moments guide to momentum-input documentation.
docs/​momentum-input.md Documents supported input forms, diagnostics, and scalar-geometry limits.
docs/​command-line.md Links thermodynamic CLI users to the momentum-input documentation.
apps/​spinon-thermo.hpp Applies shared momentum conversion to selected-sector spectrum calculations.
apps/​momentum-input.hpp Registers shared CLI options, warnings, and metadata reporting.
apps/​bethe-xxx-structure-factor-thermo.cpp Integrates shared momentum inputs into the structure-factor frontend.
apps/​bethe-xxx-moments-thermo.cpp Integrates shared momentum inputs into thermodynamic moment calculations.

Review effort: Lite

@ian-review-bot

Copy link
Copy Markdown
Collaborator

Claude review of exact head 33a28d1003a290c6f43e810a2799cd4ef578688c

Found 3 issues: two are posted inline, and a minor one is below.

What the PR does. It adds a header-only coordinate layer, include/bethe/momentum_input.hpp. This layer stores the folded external momentum as b = log(tan(q_f/2)) with explicit endpoints and a reflection flag. It parses decimal input at a guarded precision: MPFR when that is available, otherwise binary128 or long double. Conversion error estimates are attached, and a checked scalar q is offered for the existing kernels. apps/momentum-input.hpp connects this to bethe-xxx-structure-factor-thermo and bethe-xxx-moments-thermo (including the selected-sector run_spectrum in apps/spinon-thermo.hpp). It adds --momentum-from-pi, --momentum-beta and --momentum-beta-tolerance, plus export metadata. The author says the changes are covered by new unit, CLI and frontend tests, and that conversion fails before any output file is opened.

What I reviewed.

  • include/bethe/momentum_input.hpp in full: the decimal syntax check, momentum_from_radians, radians(), log_distance(), and the error and condition estimates in convert().
  • apps/momentum-input.hpp and the three call sites.
  • The new tests and docs/momentum-input.md.
  • Callers the diff does not touch that drive these tools with --momentum (scripts/check_xxx_*, tests/check_xxx_*, the XXX docs and tutorials).
  • Head against base 4b0c876 on the same inputs.

Verified (x86_64 Xeon, GCC 13.3, Release, Uni20 ca350254, 80-bit long double):

  • Build from the hints' command (MPFR + binary128 + binary80). bethe_momentum_input_tests 10/10 and bethe_cli_momentum_input_tests 3/3 pass. ctest -R "XXXSpinon|XXXThermodynamicDSF|Arguments.bethe-xxx-…|Citations.bethe-xxx-…|MomentumInput" passes 24/24, including MomentumInput.frontends, XXXSpinonDensityPrecision.cli, XXXSpinonPrecisionStages.cli and XXXThermodynamicDSF.precision.
  • ci-native-like build (FLOAT80/FLOAT128/MPREAL=OFF, so the long double input path): the same selection passes 20/20.
  • The new frontend test passes. It checks that --momentum-from-pi 1e-100 --precision fp64 fails with the scalar-q error and leaves --force export files untouched, that the same input succeeds at bits-512 with no warning, and that --momentum-beta 0 gives q = pi/2 with moments matching --momentum 1.5707963267948966. I did not run these cases separately; the assertions in the test are what verified them.
  • Behaviour I ran myself is listed under the issues below.

Issues.

  1. Inline: builds with binary128 on and MPFR off do not compile (momentum_input.hpp:267). No CI preset covers that combination.
  2. Inline: the scalar q is rebuilt from the beta value after it has been rounded to working precision, so ordinary inputs shift by 1–2 ulp compared with main (--momentum 2 --precision fp64 gives q = 1.9999999999999998). For --momentum 3.141592653589793 the shift skips the endpoint rejection.
  3. Minor: --momentum-beta-tolerance (apps/momentum-input.hpp:39) is parsed and validated only inside MomentumInput::resolve. With a grid or --global it is accepted and ignored, even when invalid: bethe-xxx-structure-factor-thermo --sectors 2 --momentum-points 3 --points 2 --momentum-beta-tolerance -5 exits 0. With a momentum input, the same value is an error. Making the option require one of the three momentum inputs, or validating it at parse time, would make this consistent.

Not checked.

  • The MPFR-off/binary128-on configuration could not be tested past the compile failure.
  • The Clang 19 ASan/UBSan preset and the ci-wide MPLAPACK build were not run. I built with UNI20_BACKEND_MPLAPACK=OFF.
  • aarch64 (113-bit long double) and MSVC were not tried.
  • The four- and six-spinon values at the shifted-q points were not compared with base.
  • Scripts and validators that regenerate the tutorial records (scripts/check_xxx_* --check, test_tutorial_*.py) were not run. The diff does not change those records.
  • The tutorial commands that pass 33- or 80-digit pi/2 with bits-N were not re-run against base.
  • No CI results were available in this run.

Review tier: full (code or new pull request) · model: claude-opus-5-5 · effort: high

Comment thread include/bethe/momentum_input.hpp Resolved
Comment thread include/bethe/momentum_input.hpp Resolved

ianmccul commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the reviews from Four, Codex, Claude and Copilot in e0eb329:

  • The small-distance path includes log(2) before exponentiation. Both direct coordinate reconstruction and resolved input retain the smallest representable binary64 angles; genuinely unrepresentable results remain rejected.
  • Scalar diagnostics include the roundtrip reference's own pi-subtraction uncertainty, separately from input conditioning. Both reported binary64/x86-long-double examples now warn. The native allowance is conservative, so warning text says estimated error rather than measured loss.
  • Native binary128 narrowing uses an explicit cast. Both frontends and both test binaries build with binary128 enabled and MPFR disabled; a focused ci-momentum-native128 configure/build/test preset makes this configuration repeatable. It is not yet an additional GitHub CI matrix job.
  • Scalar backends preserve ordinary decimal input independently of the rounded working beta. Distance/beta inputs are converted at reference precision first. Exact-equality regressions cover native and MPFR scalars; --momentum 3.141592653589793 --precision fp64 now fails the endpoint guard before exports open.
  • An explicitly supplied --momentum-beta-tolerance requires a momentum input, in either option order. Grid/global requests cannot silently ignore it.
  • The rounded 2*pi recovery message now names 2*pi.

The added regressions reproduce the original half-angle, diagnostic, scalar-shift, endpoint-guard and ignored-option failures before their fixes. Final GCC 13 validation: 20 native checks, 22 MPFR/binary128 checks, 21 binary128-without-MPFR checks, plus the three existing selected-sector spectrum, moment and thermodynamic precision regressions, all pass. No full local suite or sanitizer rerun is claimed. Fresh CI and exact-head peer review remain required.

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: e0eb329467

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ianmccul ianmccul left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent Four-session follow-up review of e0eb329, including the changes since 33a28d1: no blocking findings; source review sign-off for this exact head.

I reproduced the earlier half-angle underflow and scalar-reference-conditioning failures before this correction. Fresh standalone probes compiled against the corrected source now preserve the representable 3e-324/5e-324 binary64 angles and flag both the binary64 and native-long-double cancellation examples. The comparison reconstructs the returned hexadecimal scalar angles exactly and evaluates their beta errors using 150-digit arithmetic. Ordinary decimal inputs also match their direct scalar conversion in the probes.

Validation performed in all three configurations, using the existing pinned dependency builds:

  • Native: 12 library tests, 4 CLI tests, and the frontend integration script pass.
  • MPFR/binary128: 14 library tests, 4 CLI tests, and the frontend integration script pass.
  • Binary128 without MPFR: 13 library tests, 4 CLI tests, and the frontend integration script pass.

The reviewed follow-up also covers direct ordinary-angle preservation, explicit working-endpoint rejection, the native128 cast/preset, tolerance-option validation, and the corrected 2*pi diagnostic. The existing tests cover output preservation on errors and both CLI option orders. This is a focused review and validation, not a fresh full-suite or sanitizer run.

Six retains source/CI ownership. Required CI and completed current-revision reviewer checks remain separate merge gates.

@ian-review-bot

Copy link
Copy Markdown
Collaborator

Claude recheck of exact head e0eb329467450c5e0df68bd212b8a2faf6afab86

All three issues from my review of 33a28d1 are fixed on this head. I found no new defect.

Setup. x86_64, GCC 13.3, Release, Uni20 ca350254, 80-bit long double, MPLAPACK off. I built head three ways:

  • (a) the hints' command: MPFR + binary128 + binary80;
  • (b) cmake --preset ci-momentum-native128: MPFR off, binary128 on;
  • (c) cmake --preset ci-native: long double reference.

Base 4b0c876 was built the same way as (a).

1. binary128 without MPFR. With (b), the generated config.hpp has UNI20_HAS_MPREAL 0 and UNI20_HAS_FLOAT128 1. All four preset targets build. ctest -R "^(MomentumInput|CliMomentumInput)" passes 18/18, including MomentumInput.frontends and RoundedEndpointDiagnosticNamesTheRequestedEndpoint. That is 13 + 4 + 1 tests; I did not try to reproduce the "21" count.

2. Scalar q. I ran bethe-xxx-structure-factor-thermo --sectors 2 --momentum Q --omega 1.8 --precision P --format json. The exported q now matches base:

P exported q (head = base)
fp64 1.8, 2, 3.2000000000000002
long-double 1.79999999999999999996
fp128 1.80000000000000000000000000000000004
bits-128 2

I also swept neighbouring points: Q ∈ {0.3, 1, 1.5, 1.8, 2, 2.5, 3, 3.1, 3.14, 3.1415, 3.2, 3.5, 4, 5, 6, 6.2}, compared row by row against base:

  • Sector-2 spectrum, P ∈ {fp64, long-double, fp128, bits-128}: 64/64 identical.
  • --sectors 2,4, fp64 and long-double: 32/32 identical. The fp64 four-spinon row is numerical_failure in both builds. The long-double rows carry values; for example, q=3.2 gives 0.114736810227382806759 in both.
  • bethe-xxx-moments-thermo --sectors 2 --momentum Q, fp64 and long-double: 32/32 identical. --momentum 2 again reports Momentum: 2 and 0.17573189722059879.
  • The only new stderr is the scalar-geometry warning at 3.1415/fp64 (estimate 1.96e-12). This is consistent with the real rounding: 3.1415 in binary64 is off by 1.8e-16, and the endpoint distance is 9.3e-5.
  • --momentum 3.141592653589793 --precision fp64 now exits 1 with the scalar-q error.

The beta and distance paths in the native build (c) give the same fp64 q as the MPFR build (a) for 60 random --momentum-beta values in [-30, 30] and 60 random --momentum-from-pi values in [1e-15, 2.5].

3. --momentum-beta-tolerance. These all exit 1 with "requires --momentum, --momentum-from-pi or --momentum-beta":

  • with --sectors 2 --momentum-points 3 --points 2, values -5 or 1e-8;
  • with --global in the moments tool;
  • with no momentum input.

With --momentum 2, the value -5 is rejected by the positivity check. In the CLI runs, the option is accepted when it comes before --momentum-from-pi or --momentum-beta. For --momentum, CliMomentumInput.ExplicitToleranceRequiresMomentumInEitherOrder covers both orders.

Other checks.

  • On (a), the momentum unit tests pass 14/14 and the CLI tests 4/4. This ctest selection passes 29/29: XXXSpinon*, XXXThermodynamicDSF.*, Arguments/Citations for both tools, and MomentumInput*.
  • On (c), the momentum tests pass 17/17.
  • I compiled the head tests/test_momentum_input.cpp against the 33a28d1 header in build (a). Four tests then fail: ScalarDistanceDoesNotUnderflowThroughTheHalfAngle, OrdinaryAndReflectedAnglesRemainSupported, OrdinaryDecimalThatRoundsOntoPiIsRejected and MomentumInputMpfr.DecimalMomentumIsConvertedBeforeWorkingPrecisionRounding. So the new regressions catch the old behaviour. The reference-conditioning tests can only discriminate in builds (b) and (c), and I did not run the old header there.

Not checked.

  • The Clang 19 ASan/UBSan preset and ci-wide with MPLAPACK.
  • aarch64 (113-bit long double) and MSVC.
  • Six-spinon values.
  • Sector-4 rows at fp128 and bits-128 against base. That sweep was too slow to finish in this run.
  • Regeneration of tutorial and validation records.
  • The 33-/80-digit pi/2 tutorial commands.
  • No CI results were available to me.

Review tier: full (code or new pull request) · model: claude-opus-5-5 · effort: high

@ianmccul
ianmccul merged commit 17656b0 into main Nov 7, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants