%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%20Scattering%20feedback%20matrices%0A%0A%20%20%20%20Demonstration%20of%20different%20types%20of%20scattering%20(FIR%20paraunitary)%20feedback%0A%20%20%20%20matrices%20from%20%60filter_matrix_gallery%60%3A%0A%0A%20%20%20%20-%20**RandomDense**%20%E2%80%94%20dense%20cascaded%20paraunitary%20matrix%3B%0A%20%20%20%20-%20**Velvet**%20%E2%80%94%20sparse%20velvet-noise%20feedback%20matrix%3B%0A%20%20%20%20-%20**FromElementals**%20%E2%80%94%20cascade%20of%20degree-one%20lossless%20factors%3B%0A%20%20%20%20-%20**NoScatter**%20%E2%80%94%20plain%20static%20orthogonal%20matrix%20(for%20comparison).%0A%0A%20%20%20%20Validation%20is%20performed%20with%20the%20normalized%20echo%20density%20measure%0A%20%20%20%20(Abel%20%26%20Huang%202006)%3A%20scattering%20matrices%20build%20up%20echo%20density%20much%20faster%0A%20%20%20%20than%20the%20static%20matrix.%0A%0A%20%20%20%20Reference%3A%20*Schlecht%2C%20S.%2C%20Habets%2C%20E.%20(2020).%20Scattering%20in%20Feedback%20Delay%0A%20%20%20%20Networks.%20IEEE%2FACM%20Transactions%20on%20Audio%2C%20Speech%2C%20and%20Language%20Processing.*%0A%20%20%20%20%5Bdoi%3A10.1109%2Ftaslp.2020.3001395%5D(https%3A%2F%2Fdx.doi.org%2F10.1109%2Ftaslp.2020.3001395)%0A%0A%20%20%20%20Original%20MATLAB%3A%20%60example_scatteringFDN.m%60%2C%20Sebastian%20J.%20Schlecht%2C%0A%20%20%20%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%20numpy%20as%20np%0A%20%20%20%20import%20plotly.graph_objects%20as%20go%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%20go%2C%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%20Define%20FDN%20and%20feedback%20matrices%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%20np.random.seed(1)%0A%20%20%20%20fs%20%3D%2048000%0A%20%20%20%20ir_len%20%3D%20fs%0A%0A%20%20%20%20num_delays%20%3D%204%0A%20%20%20%20delays%20%3D%20np.random.randint(750%2C%202001%2C%20num_delays)%0A%20%20%20%20input_gain%20%3D%20np.ones((num_delays%2C%201))%0A%20%20%20%20output_gain%20%3D%20np.ones((1%2C%20num_delays))%0A%20%20%20%20direct%20%3D%20np.zeros((1%2C%201))%0A%0A%20%20%20%20num_stages%20%3D%203%0A%20%20%20%20sparsity%20%3D%203%0A%20%20%20%20feedback_matrices%20%3D%20%7B%0A%20%20%20%20%20%20%20%20_name%3A%20pyFDN.filter_matrix_gallery(%0A%20%20%20%20%20%20%20%20%20%20%20%20num_delays%2C%20_name%2C%20num_stages%3Dnum_stages%2C%20sparsity%3Dsparsity%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20for%20_name%20in%20pyFDN.filter_matrix_gallery()%0A%20%20%20%20%7D%0A%20%20%20%20feedback_matrices%5B%22NoScatter%22%5D%20%3D%20pyFDN.random_orthogonal(num_delays)%0A%0A%20%20%20%20print(f%22Delays%3A%20%7Bdelays%7D%22)%0A%20%20%20%20for%20_name%2C%20_mat%20in%20feedback_matrices.items()%3A%0A%20%20%20%20%20%20%20%20_taps%20%3D%20_mat.shape%5B2%5D%20if%20_mat.ndim%20%3D%3D%203%20else%201%0A%20%20%20%20%20%20%20%20print(f%22%7B_name%7D%3A%20%7B_taps%7D%20taps%22)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20delays%2C%0A%20%20%20%20%20%20%20%20direct%2C%0A%20%20%20%20%20%20%20%20feedback_matrices%2C%0A%20%20%20%20%20%20%20%20fs%2C%0A%20%20%20%20%20%20%20%20input_gain%2C%0A%20%20%20%20%20%20%20%20ir_len%2C%0A%20%20%20%20%20%20%20%20output_gain%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%20Impulse%20responses%20and%20echo%20density%0A%0A%20%20%20%20%60process_fdn%60%20handles%20the%20FIR%20feedback%20matrices%20directly%20in%20the%20time-domain%0A%20%20%20%20recursion%20(each%20matrix%20entry%20is%20an%20FIR%20filter%20with%20persistent%20state).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20delays%2C%0A%20%20%20%20direct%2C%0A%20%20%20%20feedback_matrices%2C%0A%20%20%20%20fs%2C%0A%20%20%20%20input_gain%2C%0A%20%20%20%20ir_len%2C%0A%20%20%20%20output_gain%2C%0A%20%20%20%20pyFDN%2C%0A)%3A%0A%20%20%20%20irs%20%3D%20%7B%7D%0A%20%20%20%20echo_densities%20%3D%20%7B%7D%0A%20%20%20%20for%20_name%2C%20_mat%20in%20feedback_matrices.items()%3A%0A%20%20%20%20%20%20%20%20irs%5B_name%5D%20%3D%20pyFDN.dss_to_impz(%0A%20%20%20%20%20%20%20%20%20%20%20%20ir_len%2C%20delays%2C%20_mat%2C%20input_gain%2C%20output_gain%2C%20direct%0A%20%20%20%20%20%20%20%20)%5B%3A%2C%200%2C%200%5D%0A%20%20%20%20%20%20%20%20_t_mix%2C%20echo_densities%5B_name%5D%20%3D%20pyFDN.echo_density(irs%5B_name%5D%2C%201024%2C%20fs%2C%200)%0A%20%20%20%20%20%20%20%20print(f%22%7B_name%7D%3A%20mixing%20time%20%3D%20%7B_t_mix%3A.0f%7D%20ms%22)%0A%20%20%20%20return%20echo_densities%2C%20irs%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%0A%0A%20%20%20%20Solid%3A%20impulse%20responses%20(offset%20per%20type).%20Dashed%3A%20normalized%20echo%0A%20%20%20%20density%20profiles.%20The%20scattering%20matrices%20reach%20echo%20density%201%20(Gaussian)%0A%20%20%20%20long%20before%20the%20static%20matrix.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(echo_densities%2C%20fs%2C%20go%2C%20irs%2C%20np%2C%20pyFDN)%3A%0A%20%20%20%20fig%20%3D%20go.Figure()%0A%20%20%20%20colors%20%3D%20%5B%22%23636efa%22%2C%20%22%23ef553b%22%2C%20%22%2300cc96%22%2C%20%22%23ab63fa%22%5D%0A%20%20%20%20t_axis%20%3D%20np.arange(len(next(iter(irs.values()))))%20%2F%20fs%0A%20%20%20%20for%20_i%2C%20_name%20in%20enumerate(irs)%3A%0A%20%20%20%20%20%20%20%20_offset%20%3D%202.0%20*%20(_i%20%2B%201)%0A%20%20%20%20%20%20%20%20fig.add_trace(%0A%20%20%20%20%20%20%20%20%20%20%20%20pyFDN.downsampled_scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3Dt_axis%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%3Dirs%5B_name%5D%20%2B%20_offset%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3D_name%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20line%3D%7B%22color%22%3A%20colors%5B_i%5D%2C%20%22width%22%3A%200.6%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20legendgroup%3D_name%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20fig.add_trace(%0A%20%20%20%20%20%20%20%20%20%20%20%20pyFDN.downsampled_scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3Dt_axis%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%3Decho_densities%5B_name%5D%20%2B%20_offset%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20line%3D%7B%22color%22%3A%20colors%5B_i%5D%2C%20%22width%22%3A%201.8%2C%20%22dash%22%3A%20%22dash%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20legendgroup%3D_name%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showlegend%3DFalse%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20fig.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Impulse%20response%20(solid)%20and%20echo%20density%20(dashed)%22%2C%0A%20%20%20%20%20%20%20%20xaxis%3D%7B%22title%22%3A%20%22Time%20(s)%22%7D%2C%0A%20%20%20%20%20%20%20%20yaxis%3D%7B%22title%22%3A%20%22Amplitude%20and%20echo%20density%20(offset%20per%20type)%22%7D%2C%0A%20%20%20%20%20%20%20%20template%3D%22plotly_white%22%2C%0A%20%20%20%20%20%20%20%20height%3D560%2C%0A%20%20%20%20)%0A%20%20%20%20fig.show()%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
8f31f8937a8e673ec68fa0908221a135