Skip to content

A fit on an identically-zero curve returns its own seed as a confident beta_D #123

Description

@marcohost33-maker

Where this comes from

PR #115 review, thread "Account for time before the first caller sample". Fixing the resolution guard (72b7da3) surfaced a second, independent weakness that the guard now merely discloses. Recording it separately, because it is a different defect with a different fix.

The observation

Grid np.linspace(100, 101, 101) against a rate-1 amplitude-damping mode, measured:

amplitude at t[0] = e^-100          = 3.7e-44
rel_entropy[0]  = 0.0
rel_entropy[-1] = 0.0               <- the entire curve is zero to machine precision
beta_D                              = 1.0   <- returned anyway

The relative-entropy curve is identically zero. There is no signal, not a weak one. The fit nevertheless returns beta_D = 1.0, which is its own initial seed handed back with the confident shape of a measurement.

After 72b7da3 this case now warns (samples_per_fast_efolding = 0.01), so a caller who reads warnings is told. A caller who reads only beta_D still gets a number that looks measured and is not.

Why it is not the same defect

The resolution guard answers "was the mode sampled?". This asks "did the fit have anything to fit?" — a question about the curve, not about the grid. A curve can be flat for reasons the grid cannot see (a steady initial state, a fully decayed one, an observable with no support on the dynamics). The seed-passthrough happens in all of them.

Proposed contract

A fit on a curve with no resolvable variation should fail closed rather than return its seed:

  1. Detect the degenerate case at the curve, not at the grid: the curve's variation is at or below what the numerics can distinguish from zero (relative to its own scale — an absolute threshold would reintroduce the rate-unit dependence of Absolute zero-mode tolerance EPS_GAP breaks D1/D3/D4/D16/D19/D20 under rate rescaling — false A11/F4 candidate and negative gap #108/Least-squares convergence is not rate-unit invariant at extreme time-grid spans #111).
  2. In that case return a non-value (nan) with an explicit reason on the result, in line with how the sibling diagnostics answer their degenerate cases, rather than a fitted parameter.
  3. success must be False, so aggregate/consumer layers cannot read the outcome as a measurement.

Discrimination requirement

The regression must prove that the old behaviour returned the seed. A test that merely asserts nan on a zero curve passes against an implementation that returns nan for everything. Pair it with a positive control on a curve with genuine signal, and pin that the returned value is not the seed by choosing a seed that differs from the true rate.

Note

This is the second time an unmeasured quantity was reported with the shape of a measured one in this layer (the first was the unsampled fast mode, PR #115). Both were caught by external review, not by the suite. Worth considering whether a single structural check — "no output without a measurement behind it" — belongs at the boundary of this module.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions