%23%20gallery_category%3A%20Feedback%20Matrices%0A%23%20gallery_title%3A%20Scattering%20feedback%20matrices%0A%23%20gallery_description%3A%20Compare%20dense%2C%20velvet-noise%2C%20elemental%2C%20and%20static%20feedback%20matrices%20by%20their%20echo-density%20buildup.%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%20Scattering%20feedback%20matrices%0A%0A%20%20%20%20Demonstration%20of%20different%20types%20of%20scattering%20(FIR%20paraunitary)%20feedback%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%20(Abel%20%26%20Huang%202006)%3A%20scattering%20matrices%20build%20up%20echo%20density%20much%20faster%20than%20the%20static%20matrix.%0A%0A%20%20%20%20Reference%3A%20*%7BpyFDN.paper_link(%22Scattering_in_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%20%20%20%20import%20plotly.graph_objects%20as%20go%0A%0A%20%20%20%20import%20pyFDN%0A%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%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%20density%20profiles.%20The%20scattering%20matrices%20reach%20echo%20density%201%20(Gaussian)%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
d1b54d7f1150acc7216dd74f3bc42cba