elbow_helper.null_test module

Phase 8 — the no-knee null test.

Asks: how often does the entire search procedure find a knee at least as strong as the observed one when the data really have no knee? The null model is a monotonic straight line carrying the observed residual structure. The test statistic is the search-adjusted lexicographic tuple from search, and the p-value is the usual (1 + #{null >= observed}) / (B + 1).

Author

Warith Harchaoui, <warithmetics@deraison.ai>

elbow_helper.null_test.no_knee_null_test(prepared, observed_statistic, knee_x_norm, config)[source]

Monte-Carlo test of the observed knee against a straight-line null.

The null model is a straight line (the shape under “no knee”) carrying noise of the magnitude the data actually show — not the straight-line fit’s own residuals, which on a genuinely kinked curve are the knee signal itself and would inflate the null distribution. The noise scale comes from signal_and_noise(), i.e. the residuals of a light smoother rescaled to the successive-difference noise estimate. It used to come from the accepted broken line’s residuals, which carry that model’s misfit on any smoothly bending curve and so made the null replicates far noisier than the data, miscalibrating the test in the permissive direction.

Parameters:
  • prepared (PreparedCurve) – The observed normalized curve.

  • observed_statistic (tuple) – The search statistic of the accepted knee (from run_search()).

  • knee_x_norm (float) – The accepted knee. Unused since the noise scale stopped coming from the broken-line fit; kept so the stage signatures stay uniform.

  • config (RobustKneeConfig) – null_replicates, max_null_p_value and random_seed.

Returns:

The Monte-Carlo p-value and a pass flag (with reason on failure).

Return type:

NullEvidence