%23%20gallery_category%3A%20FDN%20Design%20%26%20Analysis%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.23.13%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20FDN%20Gallery%0A%0A%20%20%20%20Overview%20of%20feedback%20matrices%20and%20full%20FDN%20systems%20available%20in%20pyFDN.%0A%0A%20%20%20%20%60fdn_matrix_gallery%60%20provides%20pure%20feedback%20matrices%20%E2%80%94%20each%20is%20an%20N%C3%97N%20matrix%0A%20%20%20%20used%20as%20the%20recirculation%20matrix%20in%20a%20delay%20network.%20Losslessness%20properties%20are%0A%20%20%20%20characterised%20by%20orthogonality%20(%60A%20%40%20A.T%20%E2%89%88%20I%60)%20and%20unilosslessness%20(diagonal%0A%20%20%20%20similarity%20to%20an%20orthogonal%20matrix).%0A%0A%20%20%20%20%60fdn_system_gallery%60%20provides%20complete%20state-space%20systems%20%60(A%2C%20B%2C%20C%2C%20D)%60%20%E2%80%94%0A%20%20%20%20structures%20where%20the%20input%2Foutput%20coupling%20is%20part%20of%20the%20design%2C%20such%20as%0A%20%20%20%20series%20allpass%2C%20nested%20allpass%2C%20and%20the%20Schroeder%20reverberator.%20These%20are%0A%20%20%20%20checked%20for%20the%20stronger%20uniallpass%20condition.%0A%0A%20%20%20%20Reference%3A%20*Schlecht%2C%20%22FDNTB%3A%20The%20Feedback%20Delay%20Network%20Toolbox%2C%22%20DAFx-20%2C%202020.*%0A%0A%20%20%20%20Original%20MATLAB%3A%20Sebastian%20J.%20Schlecht%2C%2028%20December%202019.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20plotly.io%20as%20pio%0A%0A%20%20%20%20import%20pyFDN%0A%0A%20%20%20%20pio.renderers.default%20%3D%20%22sphinx_gallery%22%0A%20%20%20%20return%20np%2C%20plt%2C%20pyFDN%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Retrieve%20all%20matrix%20types%0A%0A%20%20%20%20Query%20%60fdn_matrix_gallery()%60%20with%20no%20arguments%20to%20get%20the%20list%20of%20available%20types.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pyFDN)%3A%0A%20%20%20%20N%20%3D%208%0A%20%20%20%20matrix_types%20%3D%20pyFDN.fdn_matrix_gallery()%0A%20%20%20%20print(f%22Available%20types%20(%7Blen(matrix_types)%7D)%3A%22)%0A%20%20%20%20for%20t%20in%20matrix_types%3A%0A%20%20%20%20%20%20%20%20print(f%22%20%20%7Bt%7D%22)%0A%20%20%20%20return%20N%2C%20matrix_types%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Build%20matrices%20and%20check%20losslessness%0A%0A%20%20%20%20A%20matrix%20is%20orthogonal%20if%20%60A%20%40%20A.T%20%E2%89%88%20I%60.%20%20A%20matrix%20is%20spectrally%20lossless%20if%0A%20%20%20%20all%20eigenvalues%20lie%20on%20the%20unit%20circle.%20%20The%20table%20below%20shows%20both%20checks.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(N%2C%20matrix_types%2C%20mo%2C%20pyFDN)%3A%0A%20%20%20%20results%20%3D%20%7B%7D%0A%20%20%20%20for%20mtype%20in%20matrix_types%3A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20A%20%3D%20pyFDN.fdn_matrix_gallery(N%2C%20mtype)%0A%20%20%20%20%20%20%20%20%20%20%20%20results%5Bmtype%5D%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22matrix%22%3A%20A%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22orthogonal%22%3A%20pyFDN.is_orthogonal(A)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22unilossless%22%3A%20pyFDN.is_unilossless(A)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20except%20NotImplementedError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20results%5Bmtype%5D%20%3D%20%7B%22matrix%22%3A%20None%2C%20%22orthogonal%22%3A%20None%2C%20%22unilossless%22%3A%20None%7D%0A%0A%20%20%20%20mo.ui.table(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Type%22%3A%20mtype%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Orthogonal%22%3A%20r%5B%22orthogonal%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Unilossless%22%3A%20r%5B%22unilossless%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20mtype%2C%20r%20in%20results.items()%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%20(results%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Matrix%20heatmaps%0A%0A%20%20%20%20Visualise%20each%20matrix%20as%20a%20colour-coded%20grid.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20pyFDN%2C%20results)%3A%0A%20%20%20%20implemented%20%3D%20%5B(t%2C%20r)%20for%20t%2C%20r%20in%20results.items()%20if%20r%5B%22matrix%22%5D%20is%20not%20None%5D%0A%20%20%20%20figs%20%3D%20%5B%0A%20%20%20%20%20%20%20%20pyFDN.plot_matrix(%0A%20%20%20%20%20%20%20%20%20%20%20%20r%5B%22matrix%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3Df%22%7Bt%7D%3Cbr%3E%3Csup%3Eorth%3D%7Br%5B'orthogonal'%5D%7D%2C%20uni%3D%7Br%5B'unilossless'%5D%7D%3C%2Fsup%3E%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20for%20t%2C%20r%20in%20implemented%0A%20%20%20%20%5D%0A%20%20%20%20mo.hstack(figs%2C%20wrap%3DTrue)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20---%0A%0A%20%20%20%20%23%20Filter%20Matrix%20Gallery%0A%0A%20%20%20%20%60filter_matrix_gallery%60%20provides%20FIR%20*filter*%20feedback%20matrices%20%E2%80%94%20each%0A%20%20%20%20entry%20of%20the%20N%C3%97N%20matrix%20is%20an%20FIR%20filter%2C%20so%20the%20matrix%20scatters%20energy%0A%20%20%20%20over%20time%20as%20well%20as%20across%20delay%20lines%20(Schlecht%20%26%20Habets%202020%2C%0A%20%20%20%20*Scattering%20in%20Feedback%20Delay%20Networks*).%20All%20types%20are%20paraunitary%0A%20%20%20%20(lossless)%3A%20%24A%5ET(z%5E%7B-1%7D)%5C%2CA(z)%20%3D%20I%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pyFDN)%3A%0A%20%20%20%20filter_types%20%3D%20pyFDN.filter_matrix_gallery()%0A%20%20%20%20print(f%22Available%20filter%20matrix%20types%20(%7Blen(filter_types)%7D)%3A%22)%0A%20%20%20%20for%20_t%20in%20filter_types%3A%0A%20%20%20%20%20%20%20%20print(f%22%20%20%7B_t%7D%22)%0A%20%20%20%20return%20(filter_types%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Matrix%20impulse%20responses%0A%0A%20%20%20%20Each%20subplot%20grid%20shows%20the%20FIR%20of%20every%20matrix%20entry%3B%20the%20paraunitarity%0A%20%20%20%20check%20is%20printed%20in%20the%20title.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(filter_types%2C%20np%2C%20plt%2C%20pyFDN)%3A%0A%20%20%20%20N_filter%20%3D%204%0A%20%20%20%20for%20_t%20in%20filter_types%3A%0A%20%20%20%20%20%20%20%20_mat%20%3D%20pyFDN.filter_matrix_gallery(N_filter%2C%20_t%2C%20num_stages%3D2)%0A%20%20%20%20%20%20%20%20_is_pu%2C%20_%2C%20_%20%3D%20pyFDN.is_paraunitary(_mat.transpose(2%2C%200%2C%201))%0A%20%20%20%20%20%20%20%20pyFDN.plot_impulse_response_matrix(%0A%20%20%20%20%20%20%20%20%20%20%20%20np.arange(_mat.shape%5B2%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20_mat.transpose(2%2C%200%2C%201)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20xlabel%3D%22Time%20(samples)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ylabel%3D%22Amplitude%20(lin)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3Df%22%7B_t%7D%20%E2%80%94%20%7B_mat.shape%5B2%5D%7D%20taps%2C%20paraunitary%3D%7Bbool(_is_pu)%7D%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20plt.show()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20---%0A%0A%20%20%20%20%23%20Complete%20FDN%20Build%20Gallery%0A%0A%20%20%20%20%60fdn_build_gallery%60%20provides%20ready-to-render%20FDN%20parameters%3A%20feedback%2C%0A%20%20%20%20input%2Foutput%2Fdirect%20matrices%2C%20delays%2C%20sample%20rate%2C%20and%20optional%20loop%20filters.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pyFDN)%3A%0A%20%20%20%20builds%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22lossless%22%3A%20pyFDN.fdn_build_gallery(8%2C%20rt%3DNone%2C%20rng%3D0)%2C%0A%20%20%20%20%20%20%20%20%22first-order%20absorption%22%3A%20pyFDN.fdn_build_gallery(%0A%20%20%20%20%20%20%20%20%20%20%20%208%2C%20rt%3D2.0%2C%20rt_nyquist%3D0.5%2C%20rng%3D0%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%22with%20post%20EQ%22%3A%20pyFDN.fdn_build_gallery(%0A%20%20%20%20%20%20%20%20%20%20%20%208%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20rt%3D2.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20rt_nyquist%3D0.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20post_eq_db_dc%3D0.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20post_eq_db_nyquist%3D-6.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20rng%3D0%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%22multichannel%20post%20EQ%22%3A%20pyFDN.fdn_build_gallery(%0A%20%20%20%20%20%20%20%20%20%20%20%208%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20num_outputs%3D3%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20rt%3D2.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20rt_nyquist%3D0.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20post_eq_db_dc%3D%5B0.0%2C%20-3.0%2C%20-6.0%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20post_eq_db_nyquist%3D-6.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20rng%3D0%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%7D%0A%20%20%20%20return%20(builds%2C)%0A%0A%0A%40app.cell%0Adef%20_(builds%2C%20mo)%3A%0A%20%20%20%20mo.ui.table(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Build%22%3A%20_name%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Delay%20lines%22%3A%20_b.delays.size%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Delay%20range%22%3A%20f%22%7B_b.delays.min()%7D%E2%80%93%7B_b.delays.max()%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Filters%22%3A%20%22yes%22%20if%20_b.filters%20is%20not%20None%20else%20%22no%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Post%20EQ%20outputs%22%3A%200%20if%20_b.post_eq%20is%20None%20else%20_b.post_eq.shape%5B2%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20_name%2C%20_b%20in%20builds.items()%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(builds%2C%20pyFDN)%3A%0A%20%20%20%20pyFDN.plot_FDN_build(%0A%20%20%20%20%20%20%20%20builds%5B%22multichannel%20post%20EQ%22%5D%2C%20title%3D%22FDN%20build%20with%20per-output%20post%20EQ%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20---%0A%0A%20%20%20%20%23%20FDN%20System%20Gallery%0A%0A%20%20%20%20Overview%20of%20full%20FDN%20system%20types%20available%20in%20%60pyFDN.fdn_system_gallery%60.%0A%20%20%20%20Each%20type%20returns%20a%20complete%20state-space%20system%20%60(A%2C%20B%2C%20C%2C%20D)%60%20visualised%0A%20%20%20%20as%20the%20block%20matrix%20%60%5BA%20%20b%3B%20c%20%20d%5D%60.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pyFDN)%3A%0A%20%20%20%20system_types%20%3D%20pyFDN.fdn_system_gallery()%0A%20%20%20%20print(f%22Available%20system%20types%20(%7Blen(system_types)%7D)%3A%22)%0A%20%20%20%20for%20_t%20in%20system_types%3A%0A%20%20%20%20%20%20%20%20print(f%22%20%20%7B_t%7D%22)%0A%20%20%20%20return%20(system_types%2C)%0A%0A%0A%40app.cell%0Adef%20_(N%2C%20mo%2C%20pyFDN%2C%20system_types)%3A%0A%20%20%20%20sys_results%20%3D%20%7B%7D%0A%20%20%20%20for%20stype%20in%20system_types%3A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20s%20%3D%20pyFDN.fdn_system_gallery(N%2C%20stype)%0A%20%20%20%20%20%20%20%20%20%20%20%20is_ua%2C%20_%20%3D%20pyFDN.is_uniallpass(s.A%2C%20s.B%2C%20s.C%2C%20s.D)%0A%20%20%20%20%20%20%20%20%20%20%20%20sys_results%5Bstype%5D%20%3D%20%7B%22system%22%3A%20s%2C%20%22uniallpass%22%3A%20is_ua%7D%0A%20%20%20%20%20%20%20%20except%20NotImplementedError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20sys_results%5Bstype%5D%20%3D%20None%0A%0A%20%20%20%20sys_figs%20%3D%20%5B%0A%20%20%20%20%20%20%20%20pyFDN.plot_system_matrix(%0A%20%20%20%20%20%20%20%20%20%20%20%20*sys_results%5Bstype%5D%5B%22system%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3Df%22%7Bstype%7D%3Cbr%3E%3Csup%3Euniallpass%3D%7Bsys_results%5Bstype%5D%5B'uniallpass'%5D%7D%3C%2Fsup%3E%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20for%20stype%20in%20system_types%0A%20%20%20%20%20%20%20%20if%20sys_results%5Bstype%5D%20is%20not%20None%0A%20%20%20%20%5D%0A%20%20%20%20mo.hstack(sys_figs%2C%20wrap%3DTrue)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
dbd98269006677c3c391b2446b5733b2