%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%20Decorrelation%20in%20feedback%20delay%20networks%0A%0A%20%20%20%20Analyses%20the%20decorrelation%20properties%20of%20an%20FDN%20with%20a%20velvet-noise%0A%20%20%20%20scattering%20feedback%20matrix.%0A%0A%20%20%20%20The%20MIMO%20transfer%20function%20of%20an%20FDN%20factorises%20as%0A%20%20%20%20%24H(z)%20%3D%20C%20%5C%2C%20%5Cmathrm%7Badj%7D(P(z))%20B%20%5C%2C%2F%5C%2C%20%5Cdet(P(z))%20%2B%20D%24%20with%20the%20characteristic%20matrix%20%24P(z)%20%3D%20%5Cmathrm%7Bdiag%7D(z%5E%7Bm%7D)%20-%20A(z)%24.%20%20The%20adjugate%0A%20%20%20%20matrix%20%24%5Cmathrm%7Badj%7D(P(z))%24%20collects%20the%20FIR%20filters%20that%20differentiate%0A%20%20%20%20the%20input-output%20paths%3A%20the%20more%20decorrelated%20its%20entries%2C%20the%20more%0A%20%20%20%20decorrelated%20the%20FDN%20outputs.%20%20Here%20we%20compute%20the%20adjugate%2C%20then%20the%0A%20%20%20%20pairwise%20maximum%20cross-correlation%20between%20all%20of%20its%20entries.%0A%0A%20%20%20%20Reference%3A%20*Schlecht%2C%20S.%20J.%2C%20Fagerstr%C3%B6m%2C%20J.%20%26%20V%C3%A4lim%C3%A4ki%2C%20V.%20Decorrelation%0A%20%20%20%20in%20Feedback%20Delay%20Networks.%20IEEE%2FACM%20Transactions%20on%20Audio%2C%20Speech%20and%0A%20%20%20%20Language%20Processing%2C%202023.*%0A%0A%20%20%20%20Original%20MATLAB%3A%20%60example_decorrelation.m%60%2C%20Jon%20Fagerstr%C3%B6m%2C%2028%20April%202023.%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.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%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%20Define%20FDN%0A%0A%20%20%20%20A%20small%20FDN%20(%24N%20%3D%204%24)%20with%20random%20delays%20and%20a%20sparse%20velvet-noise%0A%20%20%20%20paraunitary%20feedback%20matrix%20(3%20cascaded%20stages%2C%20sparsity%203).%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(5)%0A%0A%20%20%20%20num_delays%20%3D%204%0A%20%20%20%20delays%20%3D%20np.random.randint(300%2C%201001%2C%20num_delays)%0A%0A%20%20%20%20num_stages%20%3D%203%0A%20%20%20%20sparsity%20%3D%203%0A%20%20%20%20feedback_matrix%2C%20_%20%3D%20pyFDN.construct_velvet_feedback_matrix(%0A%20%20%20%20%20%20%20%20num_delays%2C%20num_stages%2C%20sparsity%0A%20%20%20%20)%0A%0A%20%20%20%20print(f%22Delays%3A%20%7Bdelays%7D%22)%0A%20%20%20%20print(f%22Feedback%20matrix%3A%20%7Bfeedback_matrix.shape%5B2%5D%7D%20taps%22)%0A%20%20%20%20return%20delays%2C%20feedback_matrix%2C%20num_delays%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%20Adjugate%20of%20the%20characteristic%20matrix%0A%0A%20%20%20%20%60loop_tf%60%20constructs%20the%20polynomial%20matrix%20%24P(z)%24%3B%20%60adj_poly%60%20computes%20its%0A%20%20%20%20adjugate%20by%20evaluating%20%24P%24%20on%20a%20DFT%20grid%2C%20taking%20the%20scalar%20adjugate%20at%0A%20%20%20%20every%20bin%2C%20and%20transforming%20back.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(delays%2C%20feedback_matrix%2C%20pyFDN)%3A%0A%20%20%20%20P%20%3D%20pyFDN.loop_tf(delays%2C%20feedback_matrix)%0A%20%20%20%20adj_mat%20%3D%20pyFDN.adj_poly(P%2C%20%22z%5E1%22)%0A%20%20%20%20print(f%22Loop%20transfer%20function%20P%3A%20%7BP.shape%7D%22)%0A%20%20%20%20print(f%22Adjugate%20matrix%3A%20%7Badj_mat.shape%7D%22)%0A%20%20%20%20return%20P%2C%20adj_mat%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%20impulse%20response%20matrix%0A%0A%20%20%20%20Each%20subplot%20is%20one%20FIR%20entry%20of%0A%20%20%20%20-%20%24P(z)%24%20-%20characteristic%20matrix%0A%20%20%20%20-%20%24%5Cmathrm%7Badj%7D(P(z))%24%20%E2%80%94%20the%20path%20filter%20from%20delay-line%20input%20%24j%24%20to%20delay-line%20output%20%24i%24%20(up%20to%20the%20common%20denominator%20%24%5Cdet%20P(z)%24).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(P%2C%20adj_mat%2C%20plt%2C%20pyFDN)%3A%0A%20%20%20%20pyFDN.plot_impulse_response_matrix(%0A%20%20%20%20%20%20%20%20None%2C%0A%20%20%20%20%20%20%20%20P.transpose(2%2C%200%2C%201)%2C%0A%20%20%20%20%20%20%20%20xlabel%3D%22Time%20(samples)%22%2C%0A%20%20%20%20%20%20%20%20ylabel%3D%22Sample%20value%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Characteristic%20matrix%22%2C%0A%20%20%20%20%20%20%20%20linewidth%3D0.6%2C%0A%20%20%20%20)%0A%20%20%20%20plt.show()%0A%0A%20%20%20%20pyFDN.plot_impulse_response_matrix(%0A%20%20%20%20%20%20%20%20None%2C%0A%20%20%20%20%20%20%20%20adj_mat.transpose(2%2C%200%2C%201)%2C%0A%20%20%20%20%20%20%20%20xlabel%3D%22Time%20(samples)%22%2C%0A%20%20%20%20%20%20%20%20ylabel%3D%22Sample%20value%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Adjugate%20of%20the%20characteristic%20matrix%22%2C%0A%20%20%20%20%20%20%20%20linewidth%3D0.6%2C%0A%20%20%20%20)%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%20Correlation%20analysis%0A%0A%20%20%20%20%60max_corr%60%20computes%20the%20maximum%20normalized%20cross-correlation%20over%20all%20lags%0A%20%20%20%20between%20every%20pair%20of%20adjugate%20entries%20(16%20signals%20for%20%24N%20%3D%204%24%2C%20i.e.%20a%0A%20%20%20%20%2416%20%5Ctimes%2016%24%20matrix).%20%20The%20median%20and%20interquartile%20range%20of%20the%0A%20%20%20%20off-diagonal%20correlations%20summarise%20how%20decorrelated%20the%20paths%20are.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(adj_mat%2C%20np%2C%20pyFDN)%3A%0A%20%20%20%20max_correlation%20%3D%20pyFDN.max_corr(adj_mat)%0A%0A%20%20%20%20%23%20statistics%20over%20the%20upper%20triangle%20(each%20pair%20counted%20once)%0A%20%20%20%20_upper%20%3D%20max_correlation%5Bnp.triu_indices(max_correlation.shape%5B0%5D%2C%20k%3D1)%5D%0A%20%20%20%20_upper%20%3D%20np.abs(_upper)%0A%20%20%20%20corr_values%20%3D%20_upper%5B_upper%20%3E%3D%20np.finfo(float).eps%5D%0A%0A%20%20%20%20median_corr%20%3D%20np.median(corr_values)%0A%20%20%20%20iqr_corr%20%3D%20np.percentile(corr_values%2C%2075)%20-%20np.percentile(corr_values%2C%2025)%0A%20%20%20%20print(f%22Median%20correlation%20metric%3A%20%7Bmedian_corr%3A.4f%7D%22)%0A%20%20%20%20print(f%22Interquartile%20range%3A%20%20%20%20%20%20%20%7Biqr_corr%3A.4f%7D%22)%0A%20%20%20%20return%20(max_correlation%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%20Inter-channel%20maximum%20correlation%20matrix%0A%0A%20%20%20%20Heatmap%20of%20%24%7C%5Crho_%7B%5Cmax%7D%7C%24%20between%20all%20pairs%20of%20adjugate%20entries.%20%20Axis%0A%20%20%20%20label%20%24ij%24%20denotes%20the%20adjugate%20entry%20in%20row%20%24i%24%2C%20column%20%24j%24.%20%20The%0A%20%20%20%20diagonal%20is%20the%20autocorrelation%20(1%20by%20construction)%3B%20low%20off-diagonal%0A%20%20%20%20values%20indicate%20good%20decorrelation.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(go%2C%20max_correlation%2C%20np%2C%20num_delays)%3A%0A%20%20%20%20coord_labels%20%3D%20%5B%0A%20%20%20%20%20%20%20%20f%22%7B_k%20%25%20num_delays%20%2B%201%7D%7B_k%20%2F%2F%20num_delays%20%2B%201%7D%22%20for%20_k%20in%20range(num_delays**2)%0A%20%20%20%20%5D%0A%20%20%20%20fig_heat%20%3D%20go.Figure(%0A%20%20%20%20%20%20%20%20go.Heatmap(%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3Dnp.abs(max_correlation)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3Dcoord_labels%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dcoord_labels%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zmin%3D0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zmax%3D1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorscale%3D%22gray%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorbar%3D%7B%22title%22%3A%20%22%7Cmax%20corr%7C%22%7D%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%20%20%20%20fig_heat.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Inter-channel%20maximum%20correlation%22%2C%0A%20%20%20%20%20%20%20%20xaxis%3D%7B%22title%22%3A%20%22ij%22%2C%20%22type%22%3A%20%22category%22%7D%2C%0A%20%20%20%20%20%20%20%20yaxis%3D%7B%22title%22%3A%20%22kl%22%2C%20%22type%22%3A%20%22category%22%2C%20%22autorange%22%3A%20%22reversed%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%3D600%2C%0A%20%20%20%20%20%20%20%20width%3D700%2C%0A%20%20%20%20)%0A%20%20%20%20fig_heat.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%20Single%20input%20distributed%20to%20all%20delays%0A%0A%20%20%20%20With%20a%20single%20source%20distributed%20equally%20to%20all%20delay%20lines%0A%20%20%20%20(%24B%20%3D%20%5Cmathbf%7B1%7D%24)%2C%20the%20numerator%20of%20the%20transfer%20function%20collapses%20to%0A%20%20%20%20the%20vector%20%24%5Cmathrm%7Badj%7D(P(z))%5C%2C%5Cmathbf%7B1%7D%24%20%E2%80%94%20one%20FIR%20filter%20per%20output%0A%20%20%20%20channel.%20%20The%20pairwise%20maximum%20correlation%20among%20these%20%24N%24%20filters%0A%20%20%20%20indicates%20the%20decorrelation%20among%20the%20FDN%20output%20channels%20for%20a%20single%0A%20%20%20%20source.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(adj_mat%2C%20np%2C%20num_delays%2C%20plt%2C%20pyFDN)%3A%0A%20%20%20%20input_gains%20%3D%20np.ones((num_delays%2C%201%2C%201))%0A%20%20%20%20adj_vector%20%3D%20pyFDN.matrix_convolution(adj_mat%2C%20input_gains)%0A%0A%20%20%20%20pyFDN.plot_impulse_response_matrix(%0A%20%20%20%20%20%20%20%20None%2C%0A%20%20%20%20%20%20%20%20adj_vector.transpose(2%2C%200%2C%201)%2C%0A%20%20%20%20%20%20%20%20xlabel%3D%22Time%20(samples)%22%2C%0A%20%20%20%20%20%20%20%20ylabel%3D%22Sample%20value%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Adjugate%20vector%20adj(P(z))%20B%20for%20a%20single%20input%22%2C%0A%20%20%20%20%20%20%20%20linewidth%3D0.6%2C%0A%20%20%20%20)%0A%20%20%20%20plt.show()%0A%20%20%20%20return%20(adj_vector%2C)%0A%0A%0A%40app.cell%0Adef%20_(adj_vector%2C%20go%2C%20np%2C%20num_delays%2C%20pyFDN)%3A%0A%20%20%20%20max_correlation_single%20%3D%20pyFDN.max_corr(adj_vector)%0A%0A%20%20%20%20_upper%20%3D%20max_correlation_single%5B%0A%20%20%20%20%20%20%20%20np.triu_indices(max_correlation_single.shape%5B0%5D%2C%20k%3D1)%0A%20%20%20%20%5D%0A%20%20%20%20_upper%20%3D%20np.abs(_upper)%0A%20%20%20%20_values%20%3D%20_upper%5B_upper%20%3E%3D%20np.finfo(float).eps%5D%0A%20%20%20%20print(f%22Median%20correlation%20metric%3A%20%7Bnp.median(_values)%3A.4f%7D%22)%0A%20%20%20%20print(%0A%20%20%20%20%20%20%20%20%22Interquartile%20range%3A%20%20%20%20%20%20%20%22%0A%20%20%20%20%20%20%20%20f%22%7Bnp.percentile(_values%2C%2075)%20-%20np.percentile(_values%2C%2025)%3A.4f%7D%22%0A%20%20%20%20)%0A%0A%20%20%20%20channel_labels%20%3D%20%5Bstr(_k%20%2B%201)%20for%20_k%20in%20range(num_delays)%5D%0A%20%20%20%20fig_heat_single%20%3D%20go.Figure(%0A%20%20%20%20%20%20%20%20go.Heatmap(%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3Dnp.abs(max_correlation_single)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3Dchannel_labels%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dchannel_labels%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zmin%3D0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zmax%3D1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorscale%3D%22gray%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorbar%3D%7B%22title%22%3A%20%22%7Cmax%20corr%7C%22%7D%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%20%20%20%20fig_heat_single.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Inter-channel%20maximum%20correlation%20%E2%80%94%20single%20input%22%2C%0A%20%20%20%20%20%20%20%20xaxis%3D%7B%22title%22%3A%20%22Output%20channel%22%2C%20%22type%22%3A%20%22category%22%7D%2C%0A%20%20%20%20%20%20%20%20yaxis%3D%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Output%20channel%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22category%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22autorange%22%3A%20%22reversed%22%2C%0A%20%20%20%20%20%20%20%20%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%3D450%2C%0A%20%20%20%20%20%20%20%20width%3D520%2C%0A%20%20%20%20)%0A%20%20%20%20fig_heat_single.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
e985c44d85ad18d7475b117b0616d198