%23%20gallery_category%3A%20Allpass%20FDNs%0A%23%20gallery_title%3A%20Homogeneous%20allpass%20FDN%20(MIMO)%0A%23%20gallery_description%3A%20Construct%20and%20verify%20a%20multi-input%2C%20multi-output%20homogeneous%20allpass%20FDN%20from%20delay-line%20gains%20and%20an%20orthogonal%20mixing%20matrix.%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.24.0%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%2C%20pyFDN)%3A%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%20Homogeneous%20allpass%20FDN%20(MIMO)%0A%0A%20%20%20%20Example%20for%20an%20allpass%20FDN%20with%20**homogeneous%20decay**%20so%20that%20all%20poles%20have%20the%20same%20decay%20rate.%20Compared%20to%20the%20SISO%20case%2C%20the%20MIMO%20has%20considerably%20more%20degrees%20of%20freedom.%0A%0A%20%20%20%20See%20%7BpyFDN.paper_link(%22Allpass_Feedback_Delay_Networks%22)%7D.%0A%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%20numpy%20as%20np%0A%0A%20%20%20%20import%20pyFDN%0A%0A%20%20%20%20np.random.seed(1)%0A%20%20%20%20return%20np%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%20Build%20homogeneous%20allpass%20FDN%0A%0A%20%20%20%20Random%20delays%2C%20gain%20matrix%20**G**%2C%20random%20mixing%20matrix%20**U**%2C%20combined%20to%20the%20feedback%20matrix%20**A**.%20The%20remaining%20coefficients%20are%20reconstructed%20by%20completing%20the%20allpass%20FDN.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np%2C%20pyFDN)%3A%0A%20%20%20%20fs%20%3D%2048000%0A%20%20%20%20N%20%3D%208%0A%20%20%20%20numio%20%3D%20N%0A%0A%20%20%20%20delays%20%3D%20np.random.randint(800%2C%201800%2C%20size%3DN)%0A%20%20%20%20g%20%3D%20pyFDN.rt_to_gain_per_sample(0.6%2C%20fs)%0A%20%20%20%20G%20%3D%20np.diag(g**delays)%0A%20%20%20%20U%20%3D%20pyFDN.random_orthogonal(N)%0A%20%20%20%20A%20%3D%20G%20%40%20U%0A%0A%20%20%20%20B%2C%20C%2C%20D%2C%20X%20%3D%20pyFDN.complete_fdn(A%2C%20N%2C%20str(numio))%0A%20%20%20%20return%20A%2C%20B%2C%20C%2C%20D%2C%20delays%2C%20fs%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%20Test%3A%20uniallpass%0A%0A%20%20%20%20Check%20that%20the%20system%20is%20uniallpass%2C%20i.e.%2C%20allpass%20for%20any%20delays.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A%2C%20B%2C%20C%2C%20D%2C%20pyFDN)%3A%0A%20%20%20%20is_a%2C%20_%20%3D%20pyFDN.is_uniallpass(A%2C%20B%2C%20C%2C%20D%2C%20tol%3D1e-7)%0A%20%20%20%20assert%20is_a%2C%20%22Expected%20allpass%20for%20homogeneous%20FDN%20with%20these%20delays%22%0A%20%20%20%20print(%22is_allpass%3A%20OK%22)%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%23%23%20The%20system%20matrix%0A%0A%20%20%20%20%60%5BA%2C%20B%3B%20C%2C%20D%5D%60%20as%20one%20block%20heatmap.%20Losslessness%20is%20a%20property%20of%20the%20whole%20matrix%2C%20not%20of%20%60A%60%20alone%2C%20which%20is%20why%20it%20is%20worth%20seeing%20the%20four%20blocks%20together.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A%2C%20B%2C%20C%2C%20D%2C%20pyFDN)%3A%0A%20%20%20%20pyFDN.plot_system_matrix(A%2C%20B%2C%20C%2C%20D)%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%23%23%20Impulse%20response%0A%0A%20%20%20%20One%20second%20of%20the%20response%2C%20taken%20from%20output%203%20driven%20by%20input%202.%20Every%20input%2Foutput%20pair%20of%20a%20MIMO%20allpass%20FDN%20is%20a%20different%20filter%3B%20the%20allpass%20property%20belongs%20to%20the%20matrix%20as%20a%20whole%2C%20so%20no%20single%20pair%20has%20to%20look%20special.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A%2C%20B%2C%20C%2C%20D%2C%20delays%2C%20fs%2C%20mo%2C%20pyFDN)%3A%0A%20%20%20%20impulse_response%20%3D%20pyFDN.dss_to_impz(fs%2C%20delays%2C%20A%2C%20B%2C%20C%2C%20D)%0A%20%20%20%20ir_channel%20%3D%20impulse_response%5B%3A%2C%202%2C%201%5D%0A%0A%20%20%20%20_fig%20%3D%20pyFDN.plot_impulse_response(%0A%20%20%20%20%20%20%20%20ir_channel%2C%0A%20%20%20%20%20%20%20%20fs%3Dfs%2C%0A%20%20%20%20%20%20%20%20title%3D%22Homogeneous%20allpass%20FDN%20%E2%80%94%20impulse%20response%22%2C%0A%20%20%20%20)%0A%0A%20%20%20%20mo.vstack(%5B_fig%2C%20mo.audio(ir_channel%2C%20fs)%5D)%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
57a0037bd09c75988f42b2ae32dd9c47