Skip to content

Add residual input mode for error envelope spectrum#90

Merged
Arcadia-1 merged 1 commit into
Arcadia-1:mainfrom
chenzc24:codex/error-envelope-input-kind
Jul 8, 2026
Merged

Add residual input mode for error envelope spectrum#90
Arcadia-1 merged 1 commit into
Arcadia-1:mainfrom
chenzc24:codex/error-envelope-input-kind

Conversation

@chenzc24

@chenzc24 chenzc24 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR fixes the errevspec parity fixture by making the input contract explicit for error-envelope spectrum analysis.

The core Python high-level API was not the underlying problem: analyze_error_envelope_spectrum(signal) is a valid convenience path that accepts a raw signal, fits/subtracts a sine, then analyzes the residual envelope.

The compare fixture was the mismatch. MATLAB run_errevspec.m does:

err_data = read_data - sinfit(read_data);
errevspec(err_data, 'Fs', 1);

So MATLAB errevspec receives a precomputed residual. The previous Python integration also computed err_data, but then passed that residual into plot_envelope_spectrum(err_data), whose default path treated the residual as a raw signal and fit/subtracted another sine. That made the Python comparison analyze a residual-of-residual envelope rather than the residual envelope MATLAB analyzes.

Changes

  • Add input_kind to analyze_error_envelope_spectrum:
    • input_kind="signal" keeps the existing default behavior.
    • input_kind="error" treats the input as a precomputed residual and skips sine fitting.
  • Update plot_envelope_spectrum integration for MATLAB parity to call input_kind="error".
  • Unskip test_compare_err_envelope_spectrum with a local 1e-4 threshold for the remaining residual-generation difference between Python fit_sine_4param and MATLAB sinfit.
  • Refresh run_errevspec reference CSVs from the current MATLAB implementation. The old NF reference was stale relative to current plotspec noise-floor semantics.
  • Add unit tests proving that residual-input mode does not call fit_sine_4param, signal-input mode still does, and invalid input_kind is rejected.
  • Update docs and bundled user-guide references.

Experiment

Dataset: reference_dataset/sinewave_noise_200uV.csv
MATLAB current reference path: read_data -> sinfit -> err_data -> errevspec(err_data, 'Fs', 1)

Fixture Max abs metric diff vs current MATLAB
Old fixture: residual passed through signal-input path 0.450591600162
New fixture: residual passed with input_kind="error" 4.64013392865e-05

Selected per-metric diffs after the fix:

Metric Python MATLAB Delta
ENoB -4.23774012541 -4.23774768754 7.5621e-06
SNDR -23.7511955550 -23.7512410790 4.5524e-05
SFDR 0.323067410582 0.323042005698 2.5405e-05
SNR -23.0219513983 -23.0219977997 4.6401e-05
THD -1.69939776031 -1.69938018073 -1.7580e-05
pwr -32.2253391830 -32.2253540516 1.4869e-05
NF -9.20338778469 -9.20335625197 -3.1533e-05

The remaining small deltas are from the independently generated residuals (fit_sine_4param vs MATLAB sinfit), not from the envelope-spectrum input contract.

Reference refresh note: current MATLAB regenerated NF=-9.20335625197; the previous committed reference had NF=+9.33090873637, which does not match current plotspec noise-floor semantics.

Tests

  • uv run --with pytest pytest tests/unit/aout/test_analyze_error_envelope_spectrum.py -q
  • uv run --with pytest pytest tests/integration/test_err_envelope_spectrum.py -q --artifact-root E:/.tmp_artifacts/error-envelope-input-kind
  • uv run --with pytest pytest tests/compare/test_compare_err_envelope_spectrum.py -q --comparison-output-root E:/.tmp_artifacts/error-envelope-input-kind/test_output
  • uv run --with pytest pytest tests/unit/test_skill_cli.py -q
  • uv run --with pytest pytest tests/integration/test_user_guide_skill_examples.py -q

Also ran MATLAB to regenerate the run_errevspec reference from current code:

matlab -batch "cd('E:/ADCToolbox/matlab'); addpath(genpath(fullfile(pwd,'src'))); sig=readmatrix('../reference_dataset/sinewave_noise_200uV.csv'); err=sig-sinfit(sig); [ENoB,SNDR,SFDR,SNR,THD,pwr,NF,~]=errevspec(err,'Fs',1); fprintf('ENoB %.15g\nSNDR %.15g\nSFDR %.15g\nSNR %.15g\nTHD %.15g\npwr %.15g\nNF %.15g\n', ENoB,SNDR,SFDR,SNR,THD,pwr,NF);"

@Arcadia-1
Arcadia-1 merged commit 24ac9e4 into Arcadia-1:main Jul 8, 2026
1 check passed
@chenzc24
chenzc24 deleted the codex/error-envelope-input-kind branch July 9, 2026 06:07
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.

2 participants