Repository navigation
Toolbox audit: lazy import, merged duplicates, consistent DSS API - #255
Merged
Merged
Conversation
- construct_cascaded_paraunitary_matrix (and the Velvet/RandomDense gallery types) could not be reproduced with np.random.seed, because shift_matrix_distribute and random_matrix_shift drew from an unseeded np.random.default_rng(). They now use NumPy's global state like the rest of pyFDN.generate; the test fixture no longer needs to monkeypatch default_rng, and a regression test covers it. - random_orthogonal takes an optional rng; fdn_build_gallery and build_fdn use it instead of their own copies of the Haar QR draw (outputs are bit-identical for the same seed). - td.connectors reuses operators._as_2d instead of a verbatim copy. - rt_to_gain_per_sample docstring: 10^-3 after rt seconds is -60 dB, not -30 dB. - Drop the flareverb runtime dependency (never imported; torchaudio still arrives through flamo) and two mypy overrides for modules that no longer exist (pyFDN.recursive, translate.dss_to_pr_flamo). - Remove docs/references.py, an unused compatibility shim. - Makefile: lint with ruff (flake8 is not a dependency and pointed at a non-src path); build/install via python -m build / pip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5CGmfvpxMnpAt4QYPKs6c
- import pyFDN no longer loads torch or flamo (~2.9 s -> ~0.9 s). The training API and the FLAMO pole finder resolve on first access through a module __getattr__; every name in __all__ stays exported. FLAMO wrappers import flamo inside the functions that need it. - flamo and scipy are required dependencies, so the "is it installed?" guards, the placeholder AttenuationFilter/OutputEQ classes and the scipy-less sqrtm fallback are gone. - generate/: fifteen one-function modules become orthogonal.py, paraunitary.py and structures.py. The allpass structure builders (series/nested/poletti) move there from auxiliary/allpass.py, which re-exports them; is_almost_zero moves to auxiliary/utils.py. - tiny_rotation_matrix and rotation_matrix_from_angles are NumPy (every caller converted the torch result anyway) and draw from NumPy's global random state; the dtype argument is gone. - Remove auxiliary/coupled_rooms.py: a hand-wired FLAMO FDN used only by its own test; example_coupled_rooms builds the network with dss_to_flamo. It also carried a private copy of matrix_sqrt. - Shared default_device() and to_numpy() helpers replace five copies of the CUDA-else-CPU default and four tensor-to-NumPy conversions; flamo_to_pr reads delays with flamo_graph's reader instead of its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5CGmfvpxMnpAt4QYPKs6c
- process_dss is now dss_to_td(...).process_signal: one time-domain FDN engine. dss_to_td runs the recursion on the delay bank itself, so post_delay sees the delay output in real time (bit-identical to the old process_dss for LTI, nonlinear and time-varying hooks) and hooks may be SOS banks, td operators or any process_block object. dss_to_impz and build_to_impz share one impulse loop. - dss_to_flamo and trainable_from_build build their FLAMO core through one fdn_core(); training only swaps in the parametrized matrix and the trainable flags. - edc and energy_decay_curve share one backend-agnostic schroeder_integral (NumPy or torch); the loss octave edges derive from octave_bands(); array_namespace moves to auxiliary.utils. - Residue extraction (null-vector formula and multipole handling) is one helper used by both dss_to_pr and flamo_to_pr. - One as_generator() for seeds; the losses' channels check exists once. - Breaking: DSS arguments are (delays, A, B, C, D) everywhere: dss_to_flamo(delays, A, B, C, D, fs, ...), is_allpass(delays, A, B, C, D), dss_to_impz(delays, A, B, C, D, ir_len). All callers updated. - Gallery type names are snake_case in all three galleries (fdn_system_gallery: "nested_allpass", "allpass_in_fdn", ...; filter_matrix_gallery: "velvet", "random_dense", "from_elementals"); the old fdnToolbox spellings are still accepted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5CGmfvpxMnpAt4QYPKs6c
- Breaking: pole_boundaries takes the absorption as an (sections, 6, N) SOS bank, the FDNBuild.post_delay format, instead of an object with b and a fields; it also accepts a 2-D feedback matrix. Output is unchanged (checked against the old implementation). - plot_fdn_build replaces plot_FDN_build, which stays as an alias. The plot module documents why plot_spectrogram and plot_impulse_response_matrix stay Matplotlib (notebook size, subplot grids) while the rest is Plotly. - flamo_to_pr no longer prints by default, like dss_to_pr. - matrix_sqrt keeps the input dtype (was float32 / complex64 always). - fdn_build_gallery: drop the two @overload copies of its signature. - AttenuationFilter reuses the eq RT-to-dB formula; its target validation is one function instead of two near-copies. - Trim duplicated rationale in the training docstrings. - CI: new lint job runs ruff check/format and mypy (now clean). Format the four test files that were not. Drop the setup.py shim and ruff's copy of its own default excludes. - CONTRIBUTING and HISTORY describe the changes in this branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5CGmfvpxMnpAt4QYPKs6c
Every plot helper now returns a pyplot-free Matplotlib figure, animate() returns a FuncAnimation (shown with .to_jshtml()), and SDN.visualize draws a Matplotlib 3-D axes. The Plotly-only helpers downsampled_scatter and downsample_plotly_trace are removed, plotly is dropped from every extra, and all example notebooks use Matplotlib. This also fixes the two CI failures on this branch: example_train_fdn_to_rir used plotly.express, which needs pandas, and mypy could not resolve the optional marimo import in the lint job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CNoCYhy16up9ifdTYpfUFX
SebastianJiroSchlecht
deleted the
claude/affectionate-mccarthy-k91r9v
branch
September 27, 2026 10:08
6 tasks
SebastianJiroSchlecht
pushed a commit
that referenced
this pull request
Sep 27, 2026
Resolve conflicts with #255: keep both HISTORY entries, require flamo>=0.2.20 and drop flareverb, take the (delays, A, B, C, D) argument order in dss_to_flamo and the new tests, pass device through main's wrap_fdn_shell call, accept the removal of auxiliary/coupled_rooms.py, and use main's default_device in wrap_fdn_shell. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q6VyZo1pfcFKwK1Nz6cWcC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the toolbox audit. It removes duplicated implementations, dead fallback code and one-function modules, fixes an RNG reproducibility bug, makes
import pyFDNlight, makes the delay state-space API consistent, and replaces Plotly with Matplotlib throughout.As agreed, these two things are unchanged:
plot_fdn_build). The two Plotly-only helpersdownsampled_scatteranddownsample_plotly_traceare removed.tdoperators stay in the library.Changes
Bug fixes
construct_cascaded_paraunitary_matrix(and thevelvet/random_densegallery types),shift_matrix_distributeandrandom_matrix_shiftignorednp.random.seed, because they drew from an unseededdefault_rng(); the tests had been patching around this. They now use NumPy's global state like the rest ofgenerate/. A regression test is added.rt_to_gain_per_sampledocstring: the level after RT seconds is −60 dB, not −30 dB.matrix_sqrtalways returned float32. It now keeps the input's dtype.Import time and dead code
import pyFDNno longer loads torch or flamo: about 2.9 s → 0.9 s. The training API andflamo_to_prload on first attribute access.tests/test_import.pyguards this.AttenuationFilter/OutputEQclassessqrtmfallbackauxiliary/coupled_rooms.py, a hand-wired FLAMO FDN used only by its own test;example_coupled_roomscovers the model.flareverbdependency, the deaddocs/references.py, thesetup.pyshim and stale mypy overrides.Merged duplicates (outputs checked against the old code)
process_dssnow renders throughdss_to_td.dss_to_tdrunspost_delaydirectly on the delay output, so results are bit-identical to the oldprocess_dssfor LTI, time-varying and nonlinear hooks (checked for SOS,PitchShift,RingModulatorand time-varying Kronecker hooks).dss_to_impzandbuild_to_impzshare one impulse loop.dss_to_flamoandtrainable_from_buildshare onefdn_core().edcandenergy_decay_curveshare one Schroeder integral that works on NumPy arrays and torch tensors. The loss octave edges are derived fromoctave_bands()(same values).dss_to_prandflamo_to_pr.Consistency
Breaking: delay state-space arguments are
(delays, A, B, C, D)everywhere:dss_to_flamo(delays, A, B, C, D, fs, ...)is_allpass(delays, A, B, C, D)dss_to_impz(delays, A, B, C, D, ir_len)All call sites in
src/,tests/andexamples/were rewritten mechanically with an AST script.Breaking:
pole_boundariestakes the absorption as an(sections, 6, N)SOS bank (theFDNBuild.post_delayformat) instead of a.b/.aobject. Output is identical to the old version.Breaking:
tiny_rotation_matrixandrotation_matrix_from_anglesnow return NumPy arrays; every caller already converted the torch result.Gallery names: all three galleries use snake_case type names (
"nested_allpass","velvet", …). The old fdnToolbox spellings are still accepted.Renames and defaults:
plot_fdn_buildis the new name (plot_FDN_buildstays as an alias), andflamo_to_prno longer prints progress by default.Plotting: Matplotlib only
A, and curves coloured by delay length.animatereturns a MatplotlibFuncAnimation; in a notebook, show it withmo.Html(anim.to_jshtml()). The Plotly-onlytransition_msargument is removed.SDN.visualizedraws a Matplotlib 3-D axes.downsampled_scatteranddownsample_plotly_traceare removed.plotlyis removed from every extra, and all example notebooks use Matplotlib. Ruff allows a barefigas a cell's last expression inexamples/, because that is how marimo displays a figure.Less verbosity and structure
generate/, fifteen one-function modules becomeorthogonal.py,paraunitary.pyandstructures.py. The allpass structure builders move there and are still re-exported frompyFDN.allpass.fdn_build_galleryloses its two@overloadcopies of its signature.CI: a new
lintjob runsruff check,ruff format --checkandmypy, and mypy is clean. The four unformatted test files are now formatted. Optional imports (marimo,mpl_toolkits) are in mypy's ignore-missing-imports list, because the lint job doesn't install the examples extra.Testing
pytestpasses locally: 523 passed, including all example notebooks (test_marimo_examples_run.py)marimo export htmlof several notebooks (animation, SDN, gallery, echo density) runs with no cell errorsplot_FDN_buildalias; plot and SDN tests now check the Matplotlib figuresChecklist
ruff check,ruff format --checkandpython -m mypyall cleanHISTORY.rst(Unreleased) andCONTRIBUTING.rstupdatedcheck-wheel.pyandtwine checkpass🤖 Generated with Claude Code
https://claude.ai/code/session_01CNoCYhy16up9ifdTYpfUFX