pyFDN 0.4.2__tar.gz → 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. {pyfdn-0.4.2 → pyfdn-0.6.0}/CONTRIBUTING.rst +12 -6
  2. pyfdn-0.6.0/HISTORY.rst +521 -0
  3. {pyfdn-0.4.2 → pyfdn-0.6.0}/PKG-INFO +17 -13
  4. {pyfdn-0.4.2 → pyfdn-0.6.0}/README.rst +14 -7
  5. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/api_reference.rst +95 -74
  6. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/index.rst +25 -1
  7. pyfdn-0.6.0/docs/lindsey_fox_examples.rst +172 -0
  8. pyfdn-0.6.0/docs/usage.rst +91 -0
  9. {pyfdn-0.4.2 → pyfdn-0.6.0}/pyproject.toml +9 -33
  10. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/__init__.py +221 -234
  11. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/auxiliary/__init__.py +3 -17
  12. pyfdn-0.6.0/src/pyFDN/auxiliary/_fft_polynomial.py +133 -0
  13. pyfdn-0.6.0/src/pyFDN/auxiliary/_modal_bound.py +169 -0
  14. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/auxiliary/acoustics.py +79 -50
  15. pyfdn-0.6.0/src/pyFDN/auxiliary/allpass.py +176 -0
  16. pyfdn-0.6.0/src/pyFDN/auxiliary/delay.py +56 -0
  17. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/auxiliary/flamo.py +176 -154
  18. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/auxiliary/flamo_graph.py +14 -158
  19. pyfdn-0.6.0/src/pyFDN/auxiliary/lindsey_fox.py +209 -0
  20. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/auxiliary/marimo_utils.py +20 -12
  21. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/auxiliary/math.py +88 -91
  22. pyfdn-0.6.0/src/pyFDN/auxiliary/modal.py +197 -0
  23. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/auxiliary/plot.py +443 -638
  24. pyfdn-0.6.0/src/pyFDN/auxiliary/poles.py +319 -0
  25. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/auxiliary/utils.py +55 -148
  26. pyfdn-0.6.0/src/pyFDN/dss.py +33 -0
  27. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/eq/__init__.py +14 -20
  28. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/eq/biquads.py +6 -5
  29. pyfdn-0.6.0/src/pyFDN/eq/design.py +283 -0
  30. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/eq/graphic_eq.py +21 -25
  31. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/eq/probe_sos.py +23 -15
  32. {pyfdn-0.4.2/src/pyFDN/generate/allpass_FDN → pyfdn-0.6.0/src/pyFDN/generate/allpass_fdn}/__init__.py +2 -2
  33. {pyfdn-0.4.2/src/pyFDN/generate/allpass_FDN → pyfdn-0.6.0/src/pyFDN/generate/allpass_fdn}/allpass_completion.py +67 -62
  34. {pyfdn-0.4.2/src/pyFDN/generate/allpass_FDN → pyfdn-0.6.0/src/pyFDN/generate/allpass_fdn}/homogeneous_allpass_fdn.py +6 -19
  35. pyfdn-0.4.2/src/pyFDN/generate/allpass_FDN/rand_admissible_homogeneous_allpass.py → pyfdn-0.6.0/src/pyFDN/generate/allpass_fdn/random_admissible_homogeneous_allpass.py +9 -3
  36. pyfdn-0.4.2/src/pyFDN/generate/fdn_build_gallery.py → pyfdn-0.6.0/src/pyFDN/generate/fdn_dss_gallery.py +33 -141
  37. pyfdn-0.6.0/src/pyFDN/generate/fdn_matrix_gallery.py +296 -0
  38. pyfdn-0.6.0/src/pyFDN/generate/kronecker_matrix.py +284 -0
  39. pyfdn-0.6.0/src/pyFDN/generate/orthogonal.py +329 -0
  40. pyfdn-0.6.0/src/pyFDN/generate/paraunitary.py +244 -0
  41. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/generate/sample_delay_lengths.py +31 -27
  42. pyfdn-0.6.0/src/pyFDN/generate/sdn.py +313 -0
  43. pyfdn-0.6.0/src/pyFDN/generate/structures.py +300 -0
  44. pyfdn-0.6.0/src/pyFDN/process.py +42 -0
  45. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_N16_d1.json +47 -0
  46. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_N16_d2.json +47 -0
  47. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_N4_d1.json +23 -0
  48. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_N4_d2.json +23 -0
  49. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_N6_d1.json +27 -0
  50. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_N6_d2.json +27 -0
  51. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_N8_d1.json +31 -0
  52. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_N8_d2.json +31 -0
  53. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N16_d1.json +47 -0
  54. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N16_d2.json +47 -0
  55. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N4_d1.json +23 -0
  56. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N4_d2.json +23 -0
  57. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N6_d1.json +27 -0
  58. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N6_d2.json +27 -0
  59. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N8_d1.json +31 -0
  60. pyfdn-0.6.0/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N8_d2.json +31 -0
  61. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/references.bib +31 -0
  62. pyfdn-0.6.0/src/pyFDN/save.py +144 -0
  63. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/td/__init__.py +9 -5
  64. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/td/connectors.py +63 -52
  65. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/td/operators.py +430 -193
  66. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/train/__init__.py +27 -12
  67. pyfdn-0.6.0/src/pyFDN/train/build.py +355 -0
  68. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/train/engine.py +9 -6
  69. pyfdn-0.6.0/src/pyFDN/train/features/__init__.py +5 -0
  70. pyfdn-0.6.0/src/pyFDN/train/features/spatial.py +65 -0
  71. pyfdn-0.6.0/src/pyFDN/train/filters.py +271 -0
  72. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/train/losses/__init__.py +27 -0
  73. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/train/losses/_targets.py +1 -1
  74. pyfdn-0.6.0/src/pyFDN/train/losses/distances.py +172 -0
  75. pyfdn-0.6.0/src/pyFDN/train/losses/features.py +519 -0
  76. pyfdn-0.6.0/src/pyFDN/train/losses/match.py +80 -0
  77. pyfdn-0.6.0/src/pyFDN/train/losses/reductions.py +72 -0
  78. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/train/losses/spectral.py +234 -102
  79. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/train/losses/temporal.py +174 -155
  80. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/train/response.py +12 -8
  81. pyfdn-0.6.0/src/pyFDN/translate/_lindsey_fox_flamo.py +108 -0
  82. pyfdn-0.6.0/src/pyFDN/translate/dss_to_flamo.py +171 -0
  83. pyfdn-0.6.0/src/pyFDN/translate/dss_to_impz.py +41 -0
  84. pyfdn-0.6.0/src/pyFDN/translate/dss_to_pr.py +282 -0
  85. pyfdn-0.6.0/src/pyFDN/translate/dss_to_ss.py +101 -0
  86. pyfdn-0.6.0/src/pyFDN/translate/dss_to_td.py +185 -0
  87. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/translate/dss_to_tf.py +7 -4
  88. pyfdn-0.6.0/src/pyFDN/translate/flamo_to_dss.py +136 -0
  89. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/translate/flamo_to_pr.py +177 -104
  90. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/translate/impz_to_res.py +9 -7
  91. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/translate/pr_to_impz.py +26 -10
  92. pyfdn-0.4.2/src/pyFDN/translate/mtf_to_impz.py → pyfdn-0.6.0/src/pyFDN/translate/tf_to_impz.py +2 -2
  93. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN.egg-info/PKG-INFO +17 -13
  94. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN.egg-info/SOURCES.txt +42 -34
  95. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN.egg-info/requires.txt +2 -5
  96. pyfdn-0.6.0/tests/benchmark_general_char_poly.py +54 -0
  97. pyfdn-0.6.0/tests/benchmark_lindsey_fox.py +94 -0
  98. pyfdn-0.6.0/tests/modal_examples.py +149 -0
  99. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_api_reference.py +3 -19
  100. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_auxiliary_allpass.py +7 -9
  101. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_auxiliary_delay.py +5 -6
  102. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_auxiliary_flamo.py +26 -26
  103. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_auxiliary_math.py +90 -8
  104. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_auxiliary_plot.py +67 -114
  105. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_auxiliary_utils.py +21 -20
  106. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_dss_to_pr.py +26 -28
  107. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_eq_designs.py +170 -112
  108. pyfdn-0.6.0/tests/test_features.py +109 -0
  109. pyfdn-0.6.0/tests/test_fft_polynomial.py +132 -0
  110. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_flamo_graph.py +6 -6
  111. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_flamo_one_pole_absorption.py +3 -3
  112. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_flamo_to_pr.py +14 -32
  113. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_generate.py +157 -161
  114. pyfdn-0.6.0/tests/test_import.py +23 -0
  115. pyfdn-0.6.0/tests/test_kronecker_matrix.py +387 -0
  116. pyfdn-0.6.0/tests/test_lindsey_fox.py +163 -0
  117. pyfdn-0.6.0/tests/test_losses_features.py +389 -0
  118. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_marimo_examples_run.py +3 -8
  119. pyfdn-0.6.0/tests/test_modal_bound.py +133 -0
  120. pyfdn-0.6.0/tests/test_modal_contract.py +99 -0
  121. pyfdn-0.6.0/tests/test_modal_examples.py +91 -0
  122. pyfdn-0.6.0/tests/test_modal_scaling.py +157 -0
  123. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_packaged_resources.py +17 -17
  124. pyfdn-0.6.0/tests/test_process_extensions.py +482 -0
  125. pyfdn-0.6.0/tests/test_save.py +103 -0
  126. pyfdn-0.6.0/tests/test_sdn.py +89 -0
  127. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_td_connectors.py +21 -21
  128. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_td_graph_processing.py +80 -86
  129. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_td_operators.py +101 -68
  130. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_time_varying_matrix.py +12 -16
  131. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_train.py +596 -233
  132. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_translate.py +51 -12
  133. pyfdn-0.6.0/tests/test_validated_lindsey_fox.py +214 -0
  134. pyfdn-0.4.2/HISTORY.rst +0 -140
  135. pyfdn-0.4.2/docs/references.py +0 -8
  136. pyfdn-0.4.2/docs/usage.rst +0 -102
  137. pyfdn-0.4.2/setup.py +0 -7
  138. pyfdn-0.4.2/src/pyFDN/auxiliary/allpass.py +0 -337
  139. pyfdn-0.4.2/src/pyFDN/auxiliary/coupled_rooms.py +0 -193
  140. pyfdn-0.4.2/src/pyFDN/auxiliary/delay.py +0 -132
  141. pyfdn-0.4.2/src/pyFDN/auxiliary/poles.py +0 -104
  142. pyfdn-0.4.2/src/pyFDN/auxiliary/tiny_rotation_matrix.py +0 -109
  143. pyfdn-0.4.2/src/pyFDN/build.py +0 -201
  144. pyfdn-0.4.2/src/pyFDN/eq/_backend.py +0 -34
  145. pyfdn-0.4.2/src/pyFDN/eq/_design_record.py +0 -25
  146. pyfdn-0.4.2/src/pyFDN/eq/design.py +0 -235
  147. pyfdn-0.4.2/src/pyFDN/generate/SDN.py +0 -718
  148. pyfdn-0.4.2/src/pyFDN/generate/allpass_in_fdn.py +0 -78
  149. pyfdn-0.4.2/src/pyFDN/generate/anderson_matrix.py +0 -46
  150. pyfdn-0.4.2/src/pyFDN/generate/complete_orthogonal.py +0 -56
  151. pyfdn-0.4.2/src/pyFDN/generate/construct_cascaded_paraunitary_matrix.py +0 -58
  152. pyfdn-0.4.2/src/pyFDN/generate/construct_paraunitary_from_elementals.py +0 -52
  153. pyfdn-0.4.2/src/pyFDN/generate/construct_velvet_feedback_matrix.py +0 -17
  154. pyfdn-0.4.2/src/pyFDN/generate/degree_one_lossless.py +0 -31
  155. pyfdn-0.4.2/src/pyFDN/generate/fdn_matrix_gallery.py +0 -341
  156. pyfdn-0.4.2/src/pyFDN/generate/householder_matrix.py +0 -24
  157. pyfdn-0.4.2/src/pyFDN/generate/is_almost_zero.py +0 -18
  158. pyfdn-0.4.2/src/pyFDN/generate/nearest_orthogonal.py +0 -24
  159. pyfdn-0.4.2/src/pyFDN/generate/nearest_sign_agnostic_orthogonal.py +0 -82
  160. pyfdn-0.4.2/src/pyFDN/generate/random_matrix_shift.py +0 -42
  161. pyfdn-0.4.2/src/pyFDN/generate/random_orthogonal.py +0 -10
  162. pyfdn-0.4.2/src/pyFDN/generate/schroeder_reverberator.py +0 -85
  163. pyfdn-0.4.2/src/pyFDN/generate/shift_matrix.py +0 -45
  164. pyfdn-0.4.2/src/pyFDN/generate/shift_matrix_distribute.py +0 -24
  165. pyfdn-0.4.2/src/pyFDN/preset.py +0 -195
  166. pyfdn-0.4.2/src/pyFDN/process.py +0 -115
  167. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_N16_d1.json +0 -412
  168. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_N16_d2.json +0 -412
  169. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_N4_d1.json +0 -88
  170. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_N4_d2.json +0 -88
  171. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_N6_d1.json +0 -122
  172. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_N6_d2.json +0 -122
  173. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_N8_d1.json +0 -164
  174. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_N8_d2.json +0 -164
  175. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N16_d1.json +0 -412
  176. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N16_d2.json +0 -412
  177. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N4_d1.json +0 -88
  178. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N4_d2.json +0 -88
  179. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N6_d1.json +0 -122
  180. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N6_d2.json +0 -122
  181. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N8_d1.json +0 -164
  182. pyfdn-0.4.2/src/pyFDN/resources/presets/colorless_FDN/colorless_init_N8_d2.json +0 -164
  183. pyfdn-0.4.2/src/pyFDN/train/build.py +0 -586
  184. pyfdn-0.4.2/src/pyFDN/train/filters.py +0 -304
  185. pyfdn-0.4.2/src/pyFDN/translate/dss_to_flamo.py +0 -229
  186. pyfdn-0.4.2/src/pyFDN/translate/dss_to_impz.py +0 -119
  187. pyfdn-0.4.2/src/pyFDN/translate/dss_to_pr.py +0 -222
  188. pyfdn-0.4.2/src/pyFDN/translate/dss_to_ss.py +0 -101
  189. pyfdn-0.4.2/tests/test_build.py +0 -60
  190. pyfdn-0.4.2/tests/test_coupled_rooms.py +0 -229
  191. pyfdn-0.4.2/tests/test_preset.py +0 -298
  192. pyfdn-0.4.2/tests/test_process_extensions.py +0 -307
  193. pyfdn-0.4.2/tests/test_sdn.py +0 -52
  194. {pyfdn-0.4.2 → pyfdn-0.6.0}/AUTHORS.rst +0 -0
  195. {pyfdn-0.4.2 → pyfdn-0.6.0}/LICENSE +0 -0
  196. {pyfdn-0.4.2 → pyfdn-0.6.0}/MANIFEST.in +0 -0
  197. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/Makefile +0 -0
  198. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/__init__.py +0 -0
  199. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/audio_gallery.py +0 -0
  200. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/authors.rst +0 -0
  201. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/conf.py +0 -0
  202. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/contributing.rst +0 -0
  203. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/example_gallery.py +0 -0
  204. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/history.rst +0 -0
  205. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/installation.rst +0 -0
  206. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/logo/logo_pyFDN_3.png +0 -0
  207. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/logo/logo_pyFDN_4.png +0 -0
  208. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/logo/pyfdn_logo_basic.png +0 -0
  209. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/logo/pyfdn_logo_wave.png +0 -0
  210. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/make.bat +0 -0
  211. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/patch_rst.py +0 -0
  212. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/readme.rst +0 -0
  213. {pyfdn-0.4.2 → pyfdn-0.6.0}/docs/training_losses.rst +0 -0
  214. {pyfdn-0.4.2 → pyfdn-0.6.0}/setup.cfg +0 -0
  215. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/auxiliary/audio.py +0 -0
  216. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/references.py +0 -0
  217. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/ATTRIBUTION.md +0 -0
  218. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/__init__.py +0 -0
  219. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/audio/drums/drums.wav +0 -0
  220. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/audio/general/synth_dry.wav +0 -0
  221. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/audio/metadata.json +0 -0
  222. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/audio/rir/meetingroom_to_hallway_290cm.wav +0 -0
  223. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/audio/rir/s3_r4_o.wav +0 -0
  224. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/audio/speech/P1_Set1_8.wav +0 -0
  225. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/audio/speech/P20_Set1_8.wav +0 -0
  226. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/audio/strings/Kleiderschrank_Taylor_DI.wav +0 -0
  227. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/audio/strings/Sommerhit2016_Taylor_DI.wav +0 -0
  228. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/licenses/coupled-rooms-CC-BY-4.0.txt +0 -0
  229. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/resources/licenses/diff-fdn-colorless-MIT.txt +0 -0
  230. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/train/losses/base.py +0 -0
  231. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/train/losses/parameter.py +0 -0
  232. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN/train/params.py +0 -0
  233. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN.egg-info/dependency_links.txt +0 -0
  234. {pyfdn-0.4.2 → pyfdn-0.6.0}/src/pyFDN.egg-info/top_level.txt +0 -0
  235. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/__init__.py +0 -0
  236. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/conftest.py +0 -0
  237. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/matloader.py +0 -0
  238. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/reference/README.md +0 -0
  239. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/reference/example_onePoleAbsorption.mat +0 -0
  240. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/reference/onePoleAbsorption_reference.mat +0 -0
  241. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_audio_gallery.py +0 -0
  242. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_auxiliary_acoustics.py +0 -0
  243. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_example_gallery.py +0 -0
  244. {pyfdn-0.4.2 → pyfdn-0.6.0}/tests/test_pyFDN.py +0 -0
@@ -141,15 +141,21 @@ The repository separates the installable package, executable examples,
141
141
  documentation sources, and tests:
142
142
 
143
143
  * ``src/pyFDN/`` contains the library. The top-level ``__init__.py`` defines
144
- the public API, while ``process.py``, ``build_io.py``, and ``presets.py``
145
- provide the main processing and persistence entry points.
144
+ the public API, while ``process.py``, ``build.py``, and ``preset.py``
145
+ provide the main build-processing and persistence entry points.
146
146
  * ``src/pyFDN/generate/`` contains feedback-matrix and FDN construction
147
- algorithms, including the allpass and scattering-delay-network builders.
147
+ algorithms: ``orthogonal.py``, ``paraunitary.py`` and ``kronecker_matrix.py``
148
+ for feedback matrices, ``structures.py`` for classic reverberator structures,
149
+ the galleries, and the allpass and scattering-delay-network builders.
148
150
  * ``src/pyFDN/td/`` contains stateful block-processing operators and the
149
151
  connectors (``Series``, ``Parallel``, ``Recursion``) that wire them into a
150
- time-domain graph. ``process_fdn`` uses ``MatrixFIR`` for polynomial feedback
151
- matrices; ``SOSBank`` implements per-delay-line filter cascades used for
152
- frequency-dependent absorption.
152
+ time-domain graph. ``dss_to_td`` assembles an FDN from these
153
+ operators (``SOSBank`` for per-delay-line filter cascades; a ``MatrixFIR``
154
+ feedback matrix goes in the ``post_matrix`` hook); ``process_dss`` and
155
+ ``dss_to_impz`` render the matrix-only system through that graph.
156
+ * ``import pyFDN`` must not import torch or flamo (``tests/test_import.py``):
157
+ import them inside the functions that need them, or add the module to the
158
+ lazily loaded names at the end of ``src/pyFDN/__init__.py``.
153
159
  * ``src/pyFDN/eq/`` contains every EQ and absorption-filter design, while
154
160
  ``src/pyFDN/translate/`` converts between delay state-space, transfer
155
161
  function, pole-residue, impulse-response, and FLAMO representations.
@@ -0,0 +1,521 @@
1
+ =======
2
+ History
3
+ =======
4
+
5
+ 0.6.0 (2026-11-08)
6
+ ------------------
7
+
8
+ * ``RecursionState.set_lines`` and ``fill_noise(variance)`` overwrite the delay-line
9
+ content, e.g. noise for a diffuse-field start. In a ``dss_to_td`` graph the
10
+ state is at ``graph.ops[0].ops[1].state``.
11
+ * New ``gain_to_two_stage`` / ``decay_to_two_stage`` design the two-stage
12
+ attenuation filter of Välimäki, Prawda and Schlecht (IEEE SPL, 2024): a
13
+ first-order shelf sets the gain towards DC and Nyquist, and the ten-band
14
+ graphic EQ fits the remainder per band. It follows steep high-frequency
15
+ decays more closely than the graphic EQ alone.
16
+ * ``EQDesign`` gains ``"two_stage"``, so ``AttenuationFilter`` and
17
+ ``OutputEQ`` can train it.
18
+ * **Breaking: ``FDNBuild`` is replaced by ``DSS``**, a named tuple of exactly
19
+ ``(delays, A, B, C, D)`` in the argument order of the ``dss_to_*`` functions,
20
+ so ``pyFDN.dss_to_td(*dss, **filters)`` works. Filters (``post_delay``,
21
+ ``post_matrix``, ``post_output``) and the sample rate are passed alongside.
22
+ ``build_to_td`` / ``build_to_impz`` / ``build_to_flamo`` / ``process_fdn``,
23
+ ``build_set_decay`` and ``plot_fdn_build`` (and ``plot_FDN_build``) are
24
+ removed. ``dss_to_impz`` and ``process_dss`` take the matrices only; a
25
+ system with filters renders through its ``td`` graph, and the new
26
+ ``TimeOperator.impulse_response(ir_len)`` gives
27
+ ``dss_to_td(*dss, **filters).impulse_response(ir_len)``.
28
+ * **Breaking: a filter (FIR) feedback matrix is a graph operator, not a DSS
29
+ matrix.** ``dss_to_td`` and ``dss_to_flamo`` take a 2-D ``A`` only; put the
30
+ FIR matrix on the feedback path with ``A`` the identity:
31
+ ``post_matrix=td.MatrixFIR(fir)`` or
32
+ ``post_matrix=pyFDN.fir_matrix_module(fir, nfft)``.
33
+ ``plot_fdn_parameter``'s ``post_*_sos`` keywords are now ``post_*``.
34
+ Renamed: ``extract_build`` -> ``flamo_to_dss`` (returns ``(dss, filters)``,
35
+ now in ``pyFDN.translate`` next to ``dss_to_flamo``),
36
+ ``trainable_from_build`` -> ``trainable_from_dss(*dss, fs, ...)``,
37
+ ``fdn_build_gallery`` -> ``fdn_dss_gallery`` (returns ``(dss, filters)``).
38
+ * **Breaking: one save for everything.** ``save_fdn`` / ``load_fdn`` /
39
+ ``resave_fdn`` write a ``DSS`` as readable JSON (``"format": "pyfdn-dss"``,
40
+ one matrix row per line) and pickle anything else -- a ``td`` graph, a FLAMO
41
+ model -- with ``cloudpickle``, plus the pyFDN and Python versions that wrote
42
+ it; ``pyFDN.save.RENAMED`` maps classes that moved since. The JSON build
43
+ format (``save_fdn_build`` / ``load_fdn_build`` / ``fdn_build_*_dict``),
44
+ ``FDNPreset`` with its design records, ``trainable_from_preset`` and the EQ
45
+ designers' ``return_design`` option are removed. ``get_fdn_preset`` is now
46
+ ``load_fdn_preset``, pairing with ``load_audio`` and ``load_fdn``, and returns
47
+ a ``DSS``; the packaged presets are DSS JSON files. New dependency:
48
+ ``cloudpickle>=3``.
49
+ * **Breaking: one convention per concept.**
50
+
51
+ * ``flamo_time_response(model)`` returns ``(nfft, out, in)``, one response
52
+ per input like ``dss_to_impz``; its ``fs`` and ``identity`` arguments are
53
+ gone. ``pr_to_impz``'s ``impulse_response_length`` is ``ir_len``.
54
+ * ``is_paraunitary`` takes an FIR matrix in pyFDN's ``(out, in, taps)``
55
+ layout; pass an impulse response as ``ir.transpose(1, 2, 0)``.
56
+ * ``fir_matrix_module`` takes ``alias_decay_db`` like the other module
57
+ builders, so an FIR feedback matrix works in a model with alias decay.
58
+ * ``dss_to_flamo``'s ``nfft`` and ``device`` are keyword-only; every FLAMO
59
+ builder defaults to ``nfft=2**16``.
60
+ * Gains are ``B, C, D`` everywhere: ``plot_system_matrix``,
61
+ ``plot_fdn_parameter``, ``allpass_in_fdn``, ``schroeder_reverberator``.
62
+ * ``pole_boundaries(delays, A, fs, *, post_delay, nfft)``.
63
+ * Galleries return a matrix and nothing else; ``FEEDBACK_MATRIX_TYPES``,
64
+ ``FILTER_MATRIX_TYPES`` and ``SYSTEM_TYPES`` list their names. The old
65
+ fdnToolbox spellings (``"Hadamard"``, ``"nestedAllpass"``, ...) are no
66
+ longer accepted. ``FDNSystem`` is removed; ``fdn_system_gallery`` returns
67
+ ``(A, B, C, D)`` like the structure builders.
68
+ * ``pyFDN`` no longer exports the allpass-completion internals,
69
+ ``is_almost_zero``, ``ensure_3d``, ``polydiag``, ``negpolyder``, or the
70
+ ``pyFDN.allpass`` / ``pyFDN.allpass_completion`` aliases; they stay in
71
+ their modules. Removed as unused: ``flamo_freq_response``,
72
+ ``flamo_extract_pr_decomposition``, ``matrix_polyder``, ``matrix_sqrt``,
73
+ ``mulaw_decode``, ``db_to_lin``, ``db_to_sq``.
74
+ * The system comes before the signal: ``process_dss(*dss, x)``, as in
75
+ ``dss_to_impz`` and ``flamo_process(model, x)``.
76
+ * ``TimeVaryingMatrix(N, fs, *, rate, depth, spread=0.0, seed=None)`` names
77
+ its knobs as ``TimeVaryingKroneckerMatrix`` does (``rate``, ``depth``,
78
+ ``phase`` attributes) and draws from its own ``seed`` instead of NumPy's
79
+ global generator.
80
+ * ``build_fdn`` is ``trainable_fdn``, pairing with ``trainable_from_dss``.
81
+ * One function per quantity: ``general_char_poly`` uses the FFT route of
82
+ the former ``general_char_poly_fft`` for a static ``A`` (principal minors
83
+ remain for a polynomial ``A``), and ``energy_decay_curve`` is removed in
84
+ favour of ``edc``, which already takes tensors.
85
+ * Descriptive names for the MATLAB-style ones: ``mgrpdelay`` ->
86
+ ``matrix_group_delay``, ``ms_to_smp`` -> ``ms_to_samples``, ``adj_poly``
87
+ -> ``adjugate_polynomial``, ``loop_tf`` -> ``loop_transfer_function``,
88
+ ``rand_admissible_homogeneous_allpass`` ->
89
+ ``random_admissible_homogeneous_allpass``.
90
+ * Option names are matched exactly: ``construct_cascaded_paraunitary_matrix``
91
+ takes ``"hadamard"`` / ``"random"`` and ``dss_to_pr`` / ``flamo_to_pr``
92
+ their ``mode`` in lower case only.
93
+ * ``SDN`` defaults to ``fs=48_000.0`` like the rest of pyFDN, and
94
+ ``flamo_process`` types ``fs`` as a float.
95
+ * ``dss_to_ss(delays, A, B, C, D)`` takes the gains like every other
96
+ ``dss_*`` function (they were optional, lower case and defaulted to ones)
97
+ and handles several inputs and outputs.
98
+ * The EQ designers take the sample rate before the shelf frequency, which is
99
+ the keyword ``crossover``: ``decay_to_first_order_shelf(rt, rt_nyquist,
100
+ delays, fs, *, crossover=None)``, ``gain_to_first_order_shelf(gain_db,
101
+ gain_db_nyquist, fs, *, crossover=None)``, and ``crossover=`` for the
102
+ two-stage designers and ``AttenuationFilter`` (was ``rt_crossover``).
103
+ * ``AttenuationFilter`` and ``OutputEQ`` default to ``nfft=2**16`` like the
104
+ model builders they plug into.
105
+ * Matrix generators take the size as ``N``. ``construct_cascaded_paraunitary_matrix``
106
+ is ``cascaded_paraunitary_matrix(N, stages, ...)`` and
107
+ ``construct_paraunitary_from_elementals`` is ``paraunitary_from_elementals``;
108
+ ``construct_velvet_feedback_matrix`` is removed, since it was
109
+ ``cascaded_paraunitary_matrix`` with its default Hadamard stages.
110
+ ``mtf_to_impz`` is ``tf_to_impz``, pairing with ``dss_to_tf``.
111
+ * ``nfft`` names every FFT size: ``mimo_rir_eigenvalues_per_frequency`` (was
112
+ ``n_fft``) and ``MatchMelEnergyDecayRelief`` (was ``fft_sizes``). The EAI
113
+ ``deflation_type`` values are ``"full"``, ``"neighbor"`` and ``"none"``.
114
+ * ``plot_matrix`` and ``plot_system_matrix`` take ``title``, ``zmin`` and
115
+ ``zmax`` as keywords.
116
+ * ``pyFDN`` no longer exports single-caller helpers: ``last_nonzero_indices``,
117
+ ``downsample_minmax``, ``flamo_model_to_nodes``, ``flamo_nodes_flat``,
118
+ ``hook_module``, ``skew``, ``poly_degree``, ``polyder_rational``,
119
+ ``matrix_polyval``, ``shift_matrix``, ``shift_matrix_distribute``,
120
+ ``random_matrix_shift`` and ``degree_one_lossless`` stay in their modules.
121
+ * ``dss_to_flamo`` takes ``alias_decay_db``, so a lossless FDN renders through
122
+ it without time aliasing, as through ``trainable_from_dss``.
123
+ * ``DCBlocker`` drops its ``env_tau_s`` / ``gain_tau_s`` arguments and
124
+ ``PitchShift`` its ``min_delay_samps`` argument; nothing set them, and they
125
+ are now fixed at 50 ms, 20 ms and 3 samples.
126
+
127
+ * **Breaking: one convention for randomness.** Every random function takes
128
+ ``rng=``, a NumPy ``Generator`` or an integer seed, and none draws from
129
+ NumPy's global generator any more: the matrix and system galleries,
130
+ ``random_orthogonal`` (now keyword-only), ``tiny_rotation_matrix``,
131
+ ``anderson_matrix``, ``nearest_sign_agnostic_orthogonal``,
132
+ ``cascaded_paraunitary_matrix``, ``paraunitary_from_elementals``,
133
+ ``shift_matrix_distribute``, ``random_matrix_shift``,
134
+ ``random_admissible_homogeneous_allpass``, ``complete_fdn`` and
135
+ ``RecursionState.fill_noise``. ``TimeVaryingMatrix`` and
136
+ ``GranularPitchShift`` take ``rng=`` instead of ``seed=``.
137
+ ``np.random.seed`` no longer makes them reproducible; pass ``rng=``.
138
+ * **Breaking: the ``is_*`` checks return a plain ``bool``.** ``is_allpass``,
139
+ ``is_uniallpass``, ``is_paraunitary`` and ``is_bounding_curve`` returned
140
+ tuples, so ``if pyFDN.is_paraunitary(m):`` was always true. The
141
+ characteristic polynomial ``is_allpass`` compared is
142
+ ``general_char_poly(delays, A)``. ``is_uniallpass`` no longer warns when the
143
+ answer is simply no.
144
+ * **Breaking: ``SDN`` is cleaned up.** It computes everything when it is
145
+ built (``compute()`` and its 20-key dictionary are gone) and exposes
146
+ ``delays`` in samples, ``A``, ``B``, ``C``, ``D``, a ``wall_filters`` SOS
147
+ bank, and the ``input_delays``, ``output_delays`` and ``direct_delay`` of
148
+ the source, receiver and direct paths. ``wall_filters`` takes an SOS bank
149
+ with one filter per wall or per delay line. It renders with
150
+ ``pyFDN.sdn_to_flamo(sdn)`` (default ``nfft=2**16``, the model only) and
151
+ draws with ``pyFDN.plot_sdn(sdn)``, which replace the ``sdn_to_flamo`` and
152
+ ``visualize`` methods. The modules ``pyFDN.generate.SDN`` and
153
+ ``pyFDN.generate.allpass_FDN`` are now ``pyFDN.generate.sdn`` and
154
+ ``pyFDN.generate.allpass_fdn``.
155
+ * **Breaking: no flags that change the return type.** ``dss_to_flamo``
156
+ always returns the ``Shell``; ``.get_core()`` gives the FDN without its FFT
157
+ layers, e.g. for another FDN's hook. ``complete_fdn`` always returns
158
+ ``(B, C, D, x)``, and its options after ``k`` are keyword-only.
159
+ * **Breaking: no silent sample rates.** ``echo_density(ir, fs, *, window,
160
+ pre_delay, mixing_threshold, hop)`` and ``probe_sos(sos, fs, *,
161
+ control_frequencies, nfft)`` take ``fs`` as a required argument, and
162
+ ``delay_module`` takes delays in samples, like every other pyFDN function.
163
+
164
+ * **Breaking: pole-residue results are a named tuple.** ``dss_to_pr`` and
165
+ ``flamo_to_pr`` return ``(pr, info)``: ``pr`` is a ``PoleResidue``
166
+ ``(residues, poles, direct, is_conjugate_pole_pair)`` that unpacks into
167
+ ``pr_to_impz(*pr, ir_len)``, and ``info`` is the solver report.
168
+ ``dss_to_pr`` keeps its static solvers (``"eig"``, ``"roots"``,
169
+ ``"lindsey_fox"``) and their two options; the Ehrlich-Aberth iteration is
170
+ ``flamo_to_pr(dss_to_flamo(*dss, fs))``, so ``dss_to_pr`` no longer copies
171
+ its nine solver and four model options. ``impz_to_res`` returns the residues
172
+ only.
173
+ * **Breaking: the plots use Matplotlib's vocabulary.** ``vmin``/``vmax``
174
+ replace ``zmin``/``zmax``, ``plot_spectrogram`` takes ``cmap`` and
175
+ ``figsize`` instead of ``colorscale`` and a pixel ``height``, and
176
+ ``plot_matrix_grid`` takes ``figsize``. ``plot_impulse_response_matrix(ir,
177
+ *, fs=None, ...)`` takes the response first, like
178
+ ``plot_impulse_response``, and returns the figure alone.
179
+ * **Breaking: the** ``td`` **operators share their parameter names.** Every
180
+ operator takes its channel count as ``channels`` (``TimeVaryingMatrix``
181
+ took ``N``); ``fs`` is the second argument wherever a rate in Hz needs it;
182
+ options are keyword-only, and ``active_channels`` defaults to all channels.
183
+ ``RingModulator(channels, fs, *, rate, depth)`` names its modulation like
184
+ the time-varying matrices; ``PitchShift`` and ``GranularPitchShift`` take
185
+ ``max_delay``, ``window`` and ``grain_length`` in samples (``PitchShift``
186
+ no longer takes an unused ``fs``); ``DCBlocker`` takes ``pole`` and no
187
+ ``fs``. ``SDFD`` is ``SignalDependentFractionalDelay`` (``fraction`` for
188
+ ``d``) and ``ControllableFullWaveRect`` is
189
+ ``ControllableFullWaveRectifier``.
190
+ * **Breaking: the training losses frame in samples.** ``MatchEchoDensity``
191
+ takes ``window`` in samples (was ``win_duration`` in seconds),
192
+ ``MatchMelEnergyDecayRelief`` takes ``window`` and ``hop`` (were
193
+ ``win_lengths``/``hop_lengths``), and ``MatchSpectrogram`` /
194
+ ``MatchMelSpectrogram`` take ``overlap`` like the other spectrogram losses
195
+ instead of ``device``; they follow the response's device.
196
+ * **Breaking:** ``echo_density`` reports the mixing time in seconds, like
197
+ every other time in pyFDN.
198
+ * **Breaking: the allpass helpers follow the conventions.** ``complete_fdn``
199
+ and ``complete_general_mimo_svd`` call the number of inputs/outputs
200
+ ``num_io`` like ``complete_orthogonal`` (was ``k``);
201
+ ``homogeneous_allpass_fdn`` drops its printing ``verbose`` flag; the
202
+ completion results are documented as ``B, C, D``.
203
+ * **Breaking:** ``octave_bands``, ``estimate_rt_bands`` and
204
+ ``estimate_initial_level_bands`` take ``lowest_octave`` and ``num_bands``
205
+ (were ``start`` and ``n``), keyword-only.
206
+ * ``flamo_delay_feedback_matrix`` and ``swap_flamo_recursion_paths`` moved to
207
+ ``pyFDN.auxiliary.flamo`` and always return a modified copy (no
208
+ ``inplace``); ``pole_boundaries`` and ``is_bounding_curve`` moved to
209
+ ``pyFDN.auxiliary.poles``; ``pyFDN.auxiliary.allpass`` no longer re-exports
210
+ the allpass structures. The top-level names are unchanged.
211
+ * **Breaking:** ``flamo_time_response`` is ``flamo_to_impz``, pairing with
212
+ ``dss_to_impz``, ``tf_to_impz`` and ``pr_to_impz``.
213
+
214
+ * **Breaking:** ``trainable_fdn`` takes its starting matrices as ``A``,
215
+ ``B``, ``C``, ``D`` (were ``feedback``, ``input_gain``, ``output_gain``,
216
+ ``direct``), like ``trainable_from_dss``.
217
+ * **Breaking: the EQ designers are named after their designs.**
218
+ ``decay_to_geq``, ``gain_to_geq``, ``gain_to_bounded_geq`` and
219
+ ``geq_design_matrix`` are ``decay_to_graphic_eq``, ``gain_to_graphic_eq``,
220
+ ``gain_to_bounded_graphic_eq`` and ``graphic_eq_design_matrix``. The
221
+ Nyquist targets are keyword-only, as in ``AttenuationFilter`` and
222
+ ``OutputEQ``: ``decay_to_first_order_shelf(rt, delays, fs, *, rt_nyquist,
223
+ crossover=None)``, ``decay_to_one_pole(rt, delays, fs, *, rt_nyquist)``,
224
+ ``gain_to_first_order_shelf(gain_db, fs, *, gain_db_nyquist,
225
+ crossover=None)``, ``gain_to_one_pole(gain_db, *, gain_db_nyquist)``.
226
+ ``OutputEQ`` takes ``channels`` (was ``n_channels``).
227
+ * The biquad builders (``lowshelf_biquad``, ``highshelf_biquad``,
228
+ ``peaking_biquad``, ``first_order_shelf_biquad``, ``one_pole_biquad``) are
229
+ no longer exported; they stay in ``pyFDN.eq.biquads`` behind the designers.
230
+ * Every public docstring uses the NumPy style.
231
+ * ``impulse_excitation`` takes ``num_inputs``; the FLAMO module builders,
232
+ ``flamo_to_impz``, ``flamo_process`` and ``complete_fdn`` are fully typed.
233
+ * **Breaking:** ``plot_flamo_graph`` returns a Figure like every other plot
234
+ and no longer takes ``ax``.
235
+ * **Breaking:** ``fdn_dss_gallery`` accepts ``io_type="normalized"`` only
236
+ (the default; ``"normalised"`` is gone).
237
+ * **Breaking:** ``mimo_rir_eigenvalues_per_frequency`` takes ``axis`` like
238
+ ``edc`` (was ``dim``), ``nearest_sign_agnostic_orthogonal`` takes ``tol``
239
+ (was ``tolerance``), and ``plot_spectrogram`` takes ``fs`` as a keyword like
240
+ the other plots.
241
+
242
+ 0.5.0 (2026-09-28)
243
+ ------------------
244
+
245
+ * Fix GPU training (#231): ``model_response`` excites the model on its own
246
+ device, ``wrap_fdn_shell`` / ``dss_to_flamo`` / ``trainable_from_build``
247
+ build the FFT layers on the requested device, and ``train_fdn`` now defaults
248
+ to the model's device instead of the CPU. Requires ``flamo>=0.2.20``, whose
249
+ canonical module devices let ``device="cpu"`` / ``"cuda"`` mix with
250
+ ``.to(...)`` (previously ``Shell`` rejected them as different devices).
251
+ * ``import pyFDN`` no longer loads torch or flamo, which makes it about three
252
+ times faster; the training API and ``flamo_to_pr`` load on first use. Every
253
+ public name is still exported from ``pyFDN``.
254
+ * ``construct_cascaded_paraunitary_matrix`` (and the ``velvet`` /
255
+ ``random_dense`` gallery types), ``shift_matrix_distribute`` and
256
+ ``random_matrix_shift`` are now reproducible with ``np.random.seed``; they
257
+ used an unseeded generator before. ``random_orthogonal`` takes an optional
258
+ ``rng``.
259
+ * ``process_dss`` renders through the same graph as ``dss_to_td`` (one
260
+ time-domain engine), with identical output. ``dss_to_td`` / ``build_to_td``
261
+ now accept a ``td`` operator or any ``process_block`` object as a hook, and
262
+ run ``post_delay`` on the delay output in real time.
263
+ * **Breaking:** delay state-space arguments are ``(delays, A, B, C, D)``
264
+ everywhere: ``dss_to_flamo(delays, A, B, C, D, fs, ...)``,
265
+ ``is_allpass(delays, A, B, C, D)`` and
266
+ ``dss_to_impz(delays, A, B, C, D, ir_len)``.
267
+ * **Breaking:** ``pole_boundaries`` takes the absorption as an
268
+ ``(sections, 6, N)`` SOS bank (the ``FDNBuild.post_delay`` format) instead of
269
+ an object with ``b`` and ``a`` fields, and accepts a 2-D feedback matrix.
270
+ * **Breaking:** ``tiny_rotation_matrix`` and ``rotation_matrix_from_angles``
271
+ return NumPy arrays (the ``dtype`` argument is gone) and draw from NumPy's
272
+ random state.
273
+ * ``fdn_system_gallery`` and ``filter_matrix_gallery`` use snake_case type
274
+ names like ``fdn_matrix_gallery`` (``"nested_allpass"``,
275
+ ``"allpass_in_fdn"``, ``"velvet"``, ...); the old spellings are still
276
+ accepted.
277
+ * ``plot_FDN_build`` is now ``plot_fdn_build``; the old name remains an alias.
278
+ * **Breaking:** Plotly is gone; every plot function returns a Matplotlib
279
+ figure, built without pyplot. ``animate`` returns a Matplotlib
280
+ ``FuncAnimation`` (show it with ``.to_jshtml()``; the Plotly-only
281
+ ``transition_ms`` argument is removed), ``SDN.visualize`` draws a
282
+ Matplotlib 3-D axes, and the Plotly helpers ``downsampled_scatter`` and
283
+ ``downsample_plotly_trace`` are removed. The example notebooks use
284
+ Matplotlib throughout, and ``plotly`` is no longer in any extra.
285
+ * ``flamo_to_pr`` no longer prints progress by default (``verbose=False``, like
286
+ ``dss_to_pr``). ``matrix_sqrt`` keeps float64 precision.
287
+ * ``edc`` accepts torch tensors and shares its Schroeder integral with
288
+ ``energy_decay_curve`` and the decay losses.
289
+ * Remove the ``pyFDN.auxiliary.coupled_rooms`` module (a hand-wired FLAMO FDN
290
+ used only by its test; ``example_coupled_rooms`` covers the model) and the
291
+ unused ``flareverb`` dependency.
292
+ * Internal: ``generate/`` is consolidated into ``orthogonal.py``,
293
+ ``paraunitary.py`` and ``structures.py``; ``dss_to_flamo`` and
294
+ ``trainable_from_build`` share one FLAMO core builder; the residue
295
+ extraction, device default, tensor conversion and seed handling exist once.
296
+ CI now runs ruff and mypy.
297
+ * Add ``Match``, a composable response loss that extracts a feature from the
298
+ model response and the reference (waveform, magnitude, phase, mel
299
+ magnitude, multi-resolution spectrogram, octave-band EDC, cumulative energy),
300
+ compares them with a distance (squared, absolute, circular, ...) and reduces
301
+ the result to a scalar. The reference feature is cached across steps.
302
+ ``FlatMagnitude``, ``FlatSpectrogram``, ``MatchMagnitude``,
303
+ ``MatchImpulseResponse``, ``MatchEnergyDecay`` and ``MatchCumulativeEnergy``
304
+ are now built on it, with unchanged values.
305
+ * Add the losses ``SpectralFlatness`` (geometric over arithmetic mean of
306
+ ``|H|``, gain-invariant), ``MatchPhase`` and ``MatchPhaseSpectrogram``
307
+ (circular phase distance, whole-response and multi-resolution STFT) and
308
+ ``MatchMelMagnitude`` (mel-filterbank magnitude).
309
+ * Add the differentiable features ``energy_decay_curve`` (Schroeder EDC) and
310
+ ``mimo_rir_eigenvalues_per_frequency`` (eigenvalues of a square MIMO
311
+ transfer matrix per frequency bin).
312
+ * Add the Kronecker feedback matrix of Coppola (DAFx26): ``kronecker_matrix``
313
+ builds a lossless ``2**M x 2**M`` matrix from ``M`` two-by-two rotation or
314
+ reflection kernels, one angle each, and ``kronecker_transform`` applies it in
315
+ ``O(N log2 N)`` with the paper's in-place butterfly instead of a dense
316
+ product. Every kernel angle addresses one bit of the delay-line index, so a
317
+ single angle cuts or re-couples the network along one partition -- the
318
+ outermost across the two stereo halves, the innermost between the even- and
319
+ odd-indexed lines -- and the matrix stays orthogonal at every setting. All
320
+ reflection kernels at ``pi/4`` recover the normalised Hadamard matrix, so the
321
+ usual FDN mixing matrix is one point in the family. Reachable from the
322
+ gallery as ``fdn_matrix_gallery(N, "kronecker")``, with ``kronecker_angles``
323
+ for naming the angles to move.
324
+ * Add the ``td.KroneckerMatrix`` and ``td.TimeVaryingKroneckerMatrix``
325
+ operators. The latter modulates chosen kernel angles by a sine or triangle,
326
+ which breaks up fixed modal resonances by moving the poles without the
327
+ chorusing that modulating the delay lengths brings; since only one two-by-two
328
+ kernel changes per moving angle, per-sample modulation costs no more than the
329
+ static matrix. Both go straight into the ``post_matrix`` hook of
330
+ ``process_dss``.
331
+ * Add the ``example_kronecker_matrix`` notebook, which reproduces the
332
+ configurations from the paper's companion site: the construction and its
333
+ Hadamard special case, the fast transform, the stereo cross-coupling sweep on
334
+ the outermost angle with its interchannel-balance and IACC analysis, and
335
+ matrix modulation on the next angle in, with the pole-frequency histogram
336
+ that shows why it reduces coloration.
337
+ * **Breaking:** the ten-band graphic EQ's command grid is now the octave
338
+ centres 31.25 Hz through 16 kHz, with nearest-neighbour hold below 31.25 Hz
339
+ and above 16 kHz, instead of dummy DC and Nyquist anchors at 1 Hz and
340
+ ``fs``. The 10-vector of ``gain_to_geq`` / ``decay_to_geq`` /
341
+ ``AttenuationFilter`` / ``OutputEQ`` targets is ordered on
342
+ ``pyFDN.eq.COMMAND_FREQUENCIES``. The 11-section cascade itself is
343
+ unchanged.
344
+ * Fix the first-order shelf bilinear prewarp: ``first_order_shelf_biquad``
345
+ used ``tan(ω)`` rather than ``tan(ω/2)``, so a requested crossover sat at
346
+ twice the named frequency. High crossovers are now clamped at ``fs/2.1``
347
+ (Nyquist-safe for the corrected prewarp) instead of ``fs/5``. The default
348
+ midpoint is ``fs/4``. ``example_reverberation_enhancement`` uses a
349
+ challenge gain of 1.6.
350
+ * ``example_train_fdn_to_rir`` now fits on a shorter FFT grid than it measures
351
+ on. The loss only needs enough of the decay to steer on, while the octave-band
352
+ estimators need a longer measurement window, so the notebook trains at
353
+ ``nfft=2**16`` (1.37 s) and switches to ``2**17`` (2.73 s) with FLAMO's new
354
+ ``Shell.set_nfft`` before rendering. The step cost is linear in ``nfft``, so
355
+ shorter grid reduces training time. Each training-cell run resets the grid
356
+ before fitting. Requires ``flamo>=0.2.18``, where ``set_nfft`` was added.
357
+ The walkthrough now focuses on the implemented workflow and ends with
358
+ octave-band validation.
359
+ Keep a CPU/CUDA float32 selector and use first-order shelves for absorption
360
+ and output EQ. Cite the filter-learning paper with a TODO for publication.
361
+
362
+ * Type every DSS matrix parameter (``A``/``B``/``C``/``D`` and the ``b``/``c``/``d``
363
+ gains in ``dss_to_ss``) as ``ArrayLike`` instead of ``ndarray`` across
364
+ ``dss_to_flamo``, ``dss_to_impz``, ``dss_to_td``, ``dss_to_tf``, ``dss_to_ss``,
365
+ ``general_char_poly``, and ``loop_tf`` -- matching what these functions
366
+ already do internally (``np.asarray(...)``) and how ``delays`` was already
367
+ typed. Also fixes ``dss_to_ss`` silently returning a non-array ``dd`` when
368
+ ``d`` was passed as a list rather than an ``ndarray``.
369
+ * Add ``dss_to_td``, the raw delay state-space (DSS) counterpart of
370
+ ``build_to_td`` -- matching the ``dss_to_*``/``build_to_*`` pattern already
371
+ used by ``dss_to_flamo``/``build_to_flamo`` and ``dss_to_impz``/
372
+ ``build_to_impz``.
373
+ * **Breaking:** rename the ``m`` parameter to ``delays`` in ``dss_to_ss`` and
374
+ ``dss_to_flamo``, matching every other DSS-related function.
375
+ * Clarify docs and docstrings on the relationship between a delay state-space
376
+ (DSS) system and an ``FDNBuild``: a build is a DSS system plus ``fs`` and
377
+ baked filter hooks.
378
+ * Fix ``dss_to_ss`` raising a dimension-mismatch error for delays at the
379
+ documented minimum of 3 samples.
380
+ * **Breaking:** ``process_fdn`` now takes an ``FDNBuild`` and assembles a
381
+ stateful ``td`` graph (new ``build_to_td``) instead of taking raw DSS
382
+ arguments; the old signature is renamed to ``process_dss``. ``td`` operators
383
+ rename ``filter(block)``/``process(signal)`` to
384
+ ``process_block(block)``/``process_signal(signal)``.
385
+
386
+ 0.4.2 (2026-08-27)
387
+ ------------------
388
+
389
+ * Add the ``example_multislope_rir_to_fdn`` notebook: a measured room-transition
390
+ response is fitted with two decay slopes per octave band using DecayFitNet
391
+ from the ``multislope`` package, and each slope is resynthesised by its own
392
+ FDN. The response it uses ships with the package as the
393
+ ``meetingroom_to_hallway_290cm`` audio resource, taken from the coupled-rooms
394
+ transition dataset.
395
+ * Add nonlinear and pitch-shifting time-domain operators for shimmer
396
+ reverberation -- ``DCBlocker``, ``ControllableFullWaveRect``, ``SDFD``,
397
+ ``RingModulator``, ``PitchShift`` and ``GranularPitchShift`` -- all usable as
398
+ ``process_dss`` hooks, plus the ``example_shimmer_fdn`` notebook that walks
399
+ through each one inside the feedback loop of the same 8-line FDN.
400
+ * ``is_uniallpass`` no longer solves a singular Lyapunov equation when ``A`` is
401
+ itself lossless (as in the allpass-in-FDN structure). The spectral radius is
402
+ checked first and such a system is reported as not uniallpass, instead of the
403
+ result depending on whether LAPACK chose to warn or raise on the ill-
404
+ conditioned solve.
405
+ * Fix a device mismatch when a loss built for one run is used in another: every
406
+ loss that holds a reference impulse response (``MatchCumulativeEnergy``,
407
+ ``MatchEnergyDecay``, ``MatchMagnitude``, ``MatchImpulseResponse``,
408
+ ``MatchSpectrogram``, ``MatchMelSpectrogram``) aligned its reference once, on
409
+ the first response it saw, and then handed that CPU tensor to a later CUDA
410
+ step -- the way a notebook cell that builds the loss but does not re-run on a
411
+ runtime switch would hit it. The aligned reference is now keyed on the
412
+ response's shape, device, dtype and sample rate, and rebuilt when any of them
413
+ changes. ``MatchSpectrogram`` and ``MatchMelSpectrogram`` also default their
414
+ ``device`` to the response's rather than to the CPU, so FLAMO builds its
415
+ filterbanks where the model is.
416
+
417
+ 0.4.1 (2026-08-24)
418
+ ------------------
419
+
420
+ * Let ``fdn_build_gallery`` and the target-to-EQ functions optionally return
421
+ the design choices used to produce their coefficients, ready to store in an
422
+ ``FDNPreset``. Build generation now also exposes the delay distribution and
423
+ coprimality options and lives separately from the matrix galleries.
424
+ * **Breaking:** rename the ``Fs`` parameter to ``fs`` everywhere it is still
425
+ spelled with a capital -- ``dss_to_flamo``, ``dss_to_pr``, ``delay_module``
426
+ and ``SDN``. Every other sampling-rate argument in the package was already
427
+ ``fs``, and the odd one out forced callers to remember which spelling each
428
+ function wanted. ``SDN`` also renames its ``fs`` attribute and the ``"fs"``
429
+ key of the dictionary ``SDN.compute()`` returns.
430
+
431
+ 0.4.0 (2026-08-23)
432
+ ------------------
433
+
434
+ * Add ``FDNPreset`` JSON documents: a baked ``FDNBuild`` plus catalog
435
+ metadata and a controlled vocabulary for delays, matrices, and the three
436
+ filter hooks. ``trainable_from_preset`` restores filter targets as meaningful
437
+ FLAMO parameters only when they reproduce the baked coefficients.
438
+ * **Breaking:** replace ``train_fdn``'s ``mode`` string, and the ``target``,
439
+ ``criteria``, ``sparsity_alpha`` and ``mss_nfft`` arguments that went with
440
+ it, with a composed loss object. An objective is now written out --
441
+ ``FlatMagnitude() + 0.2 * Sparsity(param(model, "feedback"))`` -- and every
442
+ loss is a function of the impulse response, carried as a ``Response``, so
443
+ losses own their reference data and one objective can fit two different
444
+ references. ``pyFDN.train.objectives`` and ``build_objective`` are gone.
445
+ * **Breaking:** collect every EQ design in ``pyFDN.eq`` (formerly
446
+ ``pyFDN.graphicEQ``) behind one ``EQDesign`` interface, with ``GraphicEQ``,
447
+ ``FirstOrderShelf`` and ``OnePole`` sharing a single implementation across
448
+ the numpy and torch backends.
449
+ * **Breaking:** remove ``absorption_filters`` and ``absorption_to_rt``; the FIR
450
+ absorption path they served has no callers left.
451
+ * **Breaking:** name the three filter hooks ``post_delay``, ``post_matrix`` and
452
+ ``post_output`` everywhere -- on ``FDNBuild``, in the FLAMO graph, in the
453
+ plots and in the JSON schema -- and add the slot for the third. The build
454
+ schema is version 2; version 1 files no longer load.
455
+ * Fix colorless training on a lossless FDN, whose poles sit on the unit circle
456
+ and leave ``|H|`` unbounded. ``build_fdn`` now defaults ``alias_decay_db``
457
+ from ``rt`` (``LOSSLESS_ALIAS_DECAY_DB`` when ``rt`` is None) and
458
+ ``trainable_from_build`` threads it into every module, so a magnitude
459
+ objective sees a bounded response.
460
+ * Train the decay: ``AttenuationFilter`` parametrizes the in-loop absorption filter
461
+ by reverberation time per band, so the loop stays contractive for every value
462
+ the parameter can take, and takes either one RT curve for the network or one
463
+ per delay line. ``OutputEQ`` trains the output filter outside the recursion,
464
+ the only part of an FDN that shapes the spectral envelope without touching
465
+ the decay. Both are passed as the ``post_delay`` and ``post_output`` hooks of
466
+ ``trainable_from_build``.
467
+ * Add the losses that go with it: ``AsymmetricFlatMagnitude``,
468
+ ``FlatSpectrogram``, ``MatchEnergyDecay``, ``MatchCumulativeEnergy``,
469
+ ``MatchMagnitude``, ``MatchSpectrogram``, ``MatchMelSpectrogram``,
470
+ ``MatchImpulseResponse``, ``Energy``, ``Sparsity``, ``L1`` and ``L2``.
471
+ * Resolve trainable parameters by name: ``param(model, "feedback")`` fails
472
+ where you write it with the list of available names, and ``params(model)``
473
+ enumerates them.
474
+ * Export the FLAMO graph builders (``assemble_fdn_core``, ``wrap_fdn_shell``,
475
+ ``gain_module``, ``delay_module``, ``matrix_module``, ``fir_matrix_module``,
476
+ ``sos_filter_module``, ``hook_module``, ``AttenuationFilter``, ``OutputEQ``) from
477
+ the top-level namespace.
478
+ * Make ``build_to_impz`` apply all three hooks, so it no longer rejects builds
479
+ that carry an output EQ, and make ``extract_build`` refuse a hook it cannot
480
+ bake rather than silently dropping it.
481
+ * Add an example notebook that fits every parameter of an FDN, decay included,
482
+ to a measured concert-hall RIR, and document the loss rationale and
483
+ measurements in ``docs/training_losses.rst``.
484
+ * Fix stereo orientation in ``labeled_audio``, which decoded a stereo render as
485
+ thousands of channels.
486
+ * Check packaging metadata in CI and fail the documentation build on notebook
487
+ cell errors.
488
+
489
+ 0.3.0 (2026-08-17)
490
+ ------------------
491
+
492
+ * **Breaking:** replace the ``pyFDN.dsp`` subpackage with ``pyFDN.td``. The
493
+ top-level ``FeedbackDelay``, ``FIRMatrixFilter`` and ``SOSFilterBank``
494
+ exports are gone; use ``pyFDN.td`` operators instead.
495
+ * **Breaking:** ship the packaged colorless-FDN presets as JSON rather than
496
+ MATLAB ``.mat`` files.
497
+ * Add ``pyFDN.td``, a time-domain block-based processing graph built on NumPy
498
+ alone (no torch, no FFT), with the ``Series``, ``Parallel`` and
499
+ ``Recursion`` connectors and stateful ``Gain``, ``Delay``, ``SOSBank``,
500
+ ``MatrixFIR``, ``MatrixConvolver`` and ``TimeVaryingMatrix`` operators.
501
+ * Add ``load_fdn_build``, ``save_fdn_build``, ``fdn_build_from_dict`` and
502
+ ``fdn_build_to_dict`` for reading and writing FDN builds as JSON.
503
+ * Add an FDN-to-FAUST example that compiles a pyFDN design with adac, and a
504
+ reverberation-enhancement example.
505
+ * Improve the example gallery and stop tracking generated documentation in the
506
+ repository.
507
+ * Test on Python 3.14 in CI and the documentation build.
508
+
509
+ 0.2.0 (2026-08-10)
510
+ ------------------
511
+
512
+ * Package compact audio examples and predefined colorless-FDN coefficients so
513
+ browser-hosted tutorials work without repository-relative files.
514
+ * Add public APIs for packaged audio, FDN presets, and paper references.
515
+ * Add generated documentation galleries and wheel-content checks.
516
+ * Keep decay-estimation dependencies optional for a smaller core installation.
517
+
518
+ 0.1.0 (2025-07-02)
519
+ ------------------
520
+
521
+ * First release on PyPI.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyFDN
3
- Version: 0.4.2
3
+ Version: 0.6.0
4
4
  Summary: Python library for Feedback Delay Networks
5
5
  Author: Sebastian J. Schlecht, Facundo Franchino, Jeremy Bai
6
6
  Maintainer: Facundo Franchino, Sebastian J. Schlecht
@@ -22,20 +22,18 @@ License-File: src/pyFDN/resources/licenses/diff-fdn-colorless-MIT.txt
22
22
  Requires-Dist: numpy
23
23
  Requires-Dist: soundfile
24
24
  Requires-Dist: scipy
25
- Requires-Dist: flamo>=0.2.14
26
- Requires-Dist: flareverb
25
+ Requires-Dist: flamo>=0.2.20
26
+ Requires-Dist: cloudpickle>=3
27
27
  Provides-Extra: examples
28
28
  Requires-Dist: marimo; extra == "examples"
29
29
  Requires-Dist: adac; extra == "examples"
30
30
  Requires-Dist: matplotlib>=3.5.0; extra == "examples"
31
- Requires-Dist: plotly>=5.0.0; extra == "examples"
32
31
  Requires-Dist: multislope>=0.1.1; extra == "examples"
33
32
  Requires-Dist: pyroomacoustics; extra == "examples"
34
33
  Provides-Extra: test
35
34
  Requires-Dist: marimo; extra == "test"
36
35
  Requires-Dist: adac; extra == "test"
37
36
  Requires-Dist: matplotlib>=3.5.0; extra == "test"
38
- Requires-Dist: plotly>=5.0.0; extra == "test"
39
37
  Requires-Dist: multislope>=0.1.1; extra == "test"
40
38
  Requires-Dist: pyroomacoustics; extra == "test"
41
39
  Requires-Dist: pytest>=7.0.0; extra == "test"
@@ -62,7 +60,6 @@ Requires-Dist: sphinx-marimo; extra == "docs"
62
60
  Requires-Dist: nbsphinx>=0.9.0; extra == "docs"
63
61
  Requires-Dist: ipykernel>=6.0.0; extra == "docs"
64
62
  Requires-Dist: pandoc>=2.0; extra == "docs"
65
- Requires-Dist: plotly>=5.0.0; extra == "docs"
66
63
  Requires-Dist: matplotlib>=3.5.0; extra == "docs"
67
64
  Requires-Dist: multislope>=0.1.1; extra == "docs"
68
65
  Requires-Dist: pyroomacoustics; extra == "docs"
@@ -78,8 +75,8 @@ pyFDN
78
75
  :align: center
79
76
  :width: 300px
80
77
 
81
- .. image:: https://img.shields.io/badge/python-3.10%20%7C%203.11-blue
82
- :target: https://www.python.org/downloads/
78
+ .. image:: https://img.shields.io/pypi/pyversions/pyfdn.svg
79
+ :target: https://pypi.org/project/pyfdn/
83
80
  :alt: Python versions
84
81
 
85
82
  .. image:: https://img.shields.io/badge/license-MIT-blue.svg
@@ -114,7 +111,7 @@ Highlights
114
111
 
115
112
  * Matrix polynomial helpers for evaluating, differentiating, and convolving FIR/IIR blocks.
116
113
  * Loop analysis utilities including pole boundary estimation and curve bounding checks.
117
- * Acoustic absorption design tools that translate RT targets into one-pole loop filters.
114
+ * Acoustic absorption design tools that translate RT targets into one-pole and first-order shelf loop filters.
118
115
  * Echo density (Abel & Huang 2006) for analysing reverberation and mixing time.
119
116
  * Random orthogonal matrix generation to prototype energy-preserving feedback networks.
120
117
 
@@ -149,17 +146,24 @@ All main functions are accessible directly from the top-level ``pyFDN`` namespac
149
146
  feedback = pyFDN.random_orthogonal(len(delays))
150
147
 
151
148
  # one-pole absorption filters targeting RT of 1.2 s at DC and 0.9 s at Nyquist
152
- absorption = pyFDN.decay_to_one_pole(1.2, 0.9, delays, fs)
149
+ absorption = pyFDN.decay_to_one_pole(1.2, delays, fs, rt_nyquist=0.9)
153
150
 
154
- # convert delay state-space to standard state-space (A_ss, b, c, d)
155
- A_ss, b, c, d = pyFDN.dss_to_ss(delays, feedback)
151
+ # convert delay state-space to standard state-space
152
+ B, C, D = np.ones((4, 1)) / 2, np.ones((1, 4)) / 2, np.zeros((1, 1))
153
+ A_ss, B_ss, C_ss, D_ss = pyFDN.dss_to_ss(delays, feedback, B, C, D)
156
154
 
157
155
  Alternatively, import specific functions directly::
158
156
 
159
157
  from pyFDN import decay_to_one_pole, lin_to_db, random_orthogonal
160
158
 
161
159
  feedback = random_orthogonal(4)
162
- absorption = decay_to_one_pole(1.2, 0.9, [100, 150, 200, 250], 48_000)
160
+ absorption = decay_to_one_pole(1.2, [100, 150, 200, 250], 48_000, rt_nyquist=0.9)
161
+
162
+
163
+ Citing pyFDN
164
+ ------------
165
+
166
+ If you use pyFDN in research, please cite Sebastian J. Schlecht, Facundo Franchino, and Jeremy B. Bai (2026), *pyFDN: A Python Toolbox for Feedback Delay Network Design, Analysis, and Optimization*, `arXiv:2610.27217 <https://arxiv.org/abs/2610.27217>`_ (technical report; not peer reviewed). BibTeX is available in the `documentation <https://artificial-audio.github.io/pyFDN/#citing-pyfdn>`_.
163
167
 
164
168
 
165
169
  Development