%23%20gallery_category%3A%20Allpass%20FDN%20Examples%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%20Poletti's%20Allpass%20FDN%20(MIMO)%0A%0A%20%20%20%20Example%20for%20Poletti's%20unitary%20reverberator%3A%20a%20multi-input%20multi-output%20(MIMO)%20allpass%20feedback%20delay%20network%20with%20reduced%20colouration.%0A%0A%20%20%20%20**Reference%3A**%20Poletti%2C%20M.%20A.%20(1995).%20*A%20unitary%20reverberator%20for%20reduced%20colouration%20in%20assisted%20reverberation%20systems.*%20INTER-NOISE%20and%20NOISE-CON%2C%205%2C%201223%E2%80%931232.%0A%0A%20%20%20%20See%20also%3A%20*Allpass%20Feedback%20Delay%20Networks*%2C%20Sebastian%20J.%20Schlecht%20(IEEE%20Trans.%20Signal%20Processing).%0A%0A%20%20%20%20%E2%80%94%20Original%20MATLAB%3A%20Sebastian%20J.%20Schlecht%2C%2026%20Dec%202020%0A%20%20%20%20%22%22%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%20Setup%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%0A%20%20%20%20import%20pyFDN%0A%20%20%20%20from%20pyFDN.auxiliary.allpass%20import%20(%0A%20%20%20%20%20%20%20%20is_allpass%2C%0A%20%20%20%20%20%20%20%20is_paraunitary%2C%0A%20%20%20%20%20%20%20%20is_uniallpass%2C%0A%20%20%20%20%20%20%20%20poletti_allpass%2C%0A%20%20%20%20)%0A%0A%20%20%20%20np.random.seed(42)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20is_allpass%2C%0A%20%20%20%20%20%20%20%20is_paraunitary%2C%0A%20%20%20%20%20%20%20%20is_uniallpass%2C%0A%20%20%20%20%20%20%20%20np%2C%0A%20%20%20%20%20%20%20%20plt%2C%0A%20%20%20%20%20%20%20%20poletti_allpass%2C%0A%20%20%20%20%20%20%20%20pyFDN%2C%0A%20%20%20%20)%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%20Poletti%20allpass%20FDN%0A%0A%20%20%20%20Use%20a%20random%20orthogonal%20matrix%20**U**%20and%20gain%20**g**%20to%20form%20the%20delay%20state-space%20**(A%2C%20B%2C%20C%2C%20D)**.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np%2C%20poletti_allpass%2C%20pyFDN)%3A%0A%20%20%20%20N%20%3D%204%0A%20%20%20%20U%20%3D%20pyFDN.random_orthogonal(N)%0A%20%20%20%20Fs%20%3D%2048000%0A%20%20%20%20rt%20%3D%201%0A%20%20%20%20delays%20%3D%20np.random.randint(200%2C%201000%2C%20size%3DN)%0A%20%20%20%20g%20%3D%20pyFDN.rt_to_gain_per_sample(rt%2C%20Fs)%0A%0A%20%20%20%20average_gain%20%3D%20g%20**%20np.mean(delays)%0A%20%20%20%20A%2C%20B%2C%20C%2C%20D%20%3D%20poletti_allpass(average_gain%2C%20U)%0A%20%20%20%20return%20A%2C%20B%2C%20C%2C%20D%2C%20Fs%2C%20N%2C%20delays%2C%20rt%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%20Plot%20the%20system%20matrix%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%20_fig%20%3D%20pyFDN.plot_system_matrix(A%2C%20B%2C%20C%2C%20D)%0A%20%20%20%20_fig.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%23%23%20Test%3A%20uniallpass%0A%0A%20%20%20%20Check%20that%20the%20FDN%20is%20uniallpass%20(lossless%20with%20diagonal%20Lyapunov%20matrix).%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%20is_uniallpass)%3A%0A%20%20%20%20_is_a%2C%20P%20%3D%20is_uniallpass(A%2C%20B%2C%20C%2C%20D)%0A%20%20%20%20assert%20_is_a%2C%20%22Expected%20uniallpass%22%0A%20%20%20%20print(%22Uniallpass%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%20Test%3A%20determinant%20allpass%0A%0A%20%20%20%20Check%20that%20the%20determinant%20transfer%20function%20is%20allpass%20(numerator%20%3D%20reversed%20denominator).%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%20N%2C%20is_allpass%2C%20np)%3A%0A%20%20%20%20test_delays%20%3D%202%20**%20np.arange(N)%0A%20%20%20%20_is_a%2C%20den%2C%20num%20%3D%20is_allpass(A%2C%20B%2C%20C%2C%20D%2C%20test_delays)%0A%20%20%20%20assert%20_is_a%2C%20%22Expected%20allpass%22%0A%20%20%20%20print(%22Allpass%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%20Test%3A%20impulse%20response%20is%20paraunitary%0A%0A%20%20%20%20Compute%20the%20MIMO%20impulse%20response%20and%20verify%20it%20is%20paraunitary%20(lossless).%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%20Fs%2C%20delays%2C%20is_paraunitary%2C%20pyFDN%2C%20rt)%3A%0A%20%20%20%20ir_len%20%3D%20int(rt%20*%20Fs%20*%205)%0A%20%20%20%20impulse_response%20%3D%20pyFDN.dss_to_impz(ir_len%2C%20delays%2C%20A%2C%20B%2C%20C%2C%20D)%0A%20%20%20%20%23%20Shape%3A%20(ir_len%2C%20n_out%2C%20n_in)%0A%0A%20%20%20%20is_p%2C%20test_matrix%2C%20max_off%20%3D%20is_paraunitary(impulse_response)%0A%20%20%20%20assert%20is_p%2C%20%22Expected%20paraunitary%20impulse%20response%22%0A%20%20%20%20print(%22Paraunitary%3A%20OK%22)%0A%20%20%20%20print(%22Max%20off-diagonal%20in%20correlation%20matrix%3A%22%2C%20max_off)%0A%20%20%20%20return%20impulse_response%2C%20ir_len%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%20matrix%0A%0A%20%20%20%20Plot%20each%20input%E2%86%92output%20channel%20impulse%20response%20in%20a%20grid%20(rows%20%3D%20outputs%2C%20cols%20%3D%20inputs).%20One%20consequence%20of%20the%20allpass%20design%20here%20is%20that%20the%20direct%20sound%20dominates%20on%20the%20main%20diagonal.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Fs%2C%20impulse_response%2C%20ir_len%2C%20np%2C%20plt%2C%20pyFDN)%3A%0A%20%20%20%20fig%2C%20_%2C%20_%20%3D%20pyFDN.plot_impulse_response_matrix(%0A%20%20%20%20%20%20%20%20np.arange(ir_len)%2C%0A%20%20%20%20%20%20%20%20pyFDN.mulaw_encode(impulse_response)%2C%0A%20%20%20%20%20%20%20%20xlabel%3D%22Time%20%5Bsamples%5D%22%2C%0A%20%20%20%20%20%20%20%20ylabel%3D%22Amplitude%20%5Bmu-law%5D%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Poletti%20allpass%20FDN%20%E2%80%94%20MIMO%20impulse%20response%22%2C%0A%20%20%20%20%20%20%20%20xlim%3D(-1000%2C%20Fs%20%2F%202)%2C%0A%20%20%20%20)%0A%0A%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%23%23%20Spectrogram%20(one%20channel)%0A%0A%20%20%20%20Spectrogram%20of%20a%20single%20input%E2%86%92output%20channel%20(e.g.%20output%200%2C%20input%200).%20The%20modal%20decay%20is%20not%20homogeneous%20in%20the%20Poletti%20allpass%20which%20leads%20to%20uneven%20decay.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Fs%2C%20impulse_response%2C%20mo%2C%20pyFDN)%3A%0A%20%20%20%20%23%20Pick%20one%20channel%3A%20output%201%2C%20input%200%0A%20%20%20%20channel_ir%20%3D%20impulse_response%5B%3A%2C%201%2C%200%5D%0A%20%20%20%20_fig%20%3D%20pyFDN.plot_spectrogram(channel_ir%2C%20Fs%2C%20xlim%3D(0%2C%202))%0A%0A%20%20%20%20mo.vstack(%5B_fig%2C%20mo.audio(channel_ir%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
f68ee8b1747de4cd6945cf6d4818e8cc