Skip to content

ForceFreeStates - BUGFIX - Preserve the symplectic structure across ideal singular-surface crossings #481

Description

@jhalpern30

Summary

Once the forward Euler-Lagrange integration has a per-column absolute tolerance (#480), W⁻¹ = U₁U₂⁻¹ stays Hermitian to roundoff between singular surfaces. The non-Hermiticity that remains is added at each ideal singular-surface crossing. This is the residual left over from #93 after that fix.

Figure: https://claude.ai/artifact/8VJSoYZRUPDZvKqryqY5aP

Evidence

DIIID-like_ideal_example, n = 1, fixed axis start (frobenius_psi_max = 0), ucrit = 1e3, on the #480 branch. Values are the stability check's ‖anti-Hermitian‖/‖Hermitian‖ of W⁻¹ at every saved step:

Region Non-Hermiticity
Axis to the first rational surface (q = 2) median 1.2e-14, at most 3.2e-12
After the q = 2 crossing about 9e-5, never returning to roundoff
Steps above the 1e-3 warning threshold 6, all peaks between surfaces (q ≈ 2.54, 3.80, 4.67, 5.85)

The jump happens exactly at the first crossing, and each later crossing leaves a similar level. The flagged steps are not at the surfaces: they are where the ~1e-4 defect is amplified between them.

Likely source

cross_ideal_singular_surf! zeroes one column, takes a two-point trapezoidal step across 2·dpsi, and substitutes the asymptotic small solution. That is the one operation in the integration that does not preserve U₁†U₂ − U₂†U₁ = 0.

Candidate fixes, from the discussion on #93:

  1. Re-project U onto the symplectic constraint right after each crossing.
  2. Replace the trapezoidal jump with a few sub-steps of the ODE integrator.
  3. Evaluate the asymptotic extraction (sing_get_ca / sing_get_ua) in extended precision.

Related

Activity

  1. jhalpern30 commented on Oct 6, 2026

    @jhalpern30
    CollaboratorAuthor

    Findings, proposed fix and draft diff: https://claude.ai/artifact/MaMkwYpbRxALD99cT6GAWB

    The non-Hermiticity in W after ideal crossings is truncation error from the crossing's jump. It is first order in the jump half-width, so DIIID n=1 et₁ is 0.34% off at today's singfac_min = 1e-4.

    Lowering singfac_min alone doesn't work, for two reasons:

    • Forward: after a high-α surface every column grows alike, so the ucrit ratio test never fires and the basis collapses (cond up to 1e15).
    • Riccati: singfac_min is also the Δ′ matching distance, and Δ′ loses precision as it shrinks.

    Proposed fix, in three parts:

    1. ForceFreeStates - BUGFIX - ⚠️ Remove the resonant solution at ideal crossings regardless of reduction timing #489's resonant-row crossing.
    2. A Gaussian reduction also triggered when the solution columns become nearly parallel. The ucrit test only fires when growth rates differ; here every column grows at the same rate because each is dominated by the same solution. The prototype detects this with a condition number (cond > 1e6), but that is one option among several, including cheaper ones (see the page).
    3. A separate jump half-width (default 1e-6), reached by ODE legs inside the crossings. singfac_min keeps its other roles.

    With all three, energies converge with the jump and forward and Riccati agree, while the Δ′ matrix is unchanged. Today they disagree by up to 2.7× (DIIID n=3).

    Input wanted on:

    • the parameter design;
    • crossing in asymptotic-coefficient space as an alternative;
    • which test to use for detecting the collapse.
  2. self-assigned this
    on Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions