%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%20Random%20FDN%20statistics%0A%0A%20%20%20%20Statistics%20of%20the%20modal%20decomposition%20of%20a%20random%20FDN.%20The%20pole%20angles%20are%0A%20%20%20%20almost%20equidistributed%20on%20the%20unit%20circle%2C%20while%20the%20residue%20magnitudes%20are%0A%20%20%20%20spread%20across%20a%20large%20range.%0A%0A%20%20%20%20The%20residue%20of%20each%20mode%20factors%20into%0A%0A%20%20%20%20%24%24%5Crho_i%20%3D%20%5Cunderbrace%7B%5Cfrac%7B1%7D%7Bl_i%5EH%20P'(%5Clambda_i)%5C%2C%20r_i%7D%7D_%7B%5Ctext%7Bundriven%7D%7D%0A%20%20%20%20%20%20%5Ccdot%20%5Cunderbrace%7B(c%5C%2C%20r_i)(l_i%5EH%20b)%7D_%7B%5Ctext%7Binput%2Foutput%20drive%7D%7D%2C%24%24%0A%0A%20%20%20%20so%20we%20compare%20the%20distribution%20of%20total%20residues%2C%20undriven%20residues%2C%20and%0A%20%20%20%20the%20input%E2%80%93output%20drive.%0A%0A%20%20%20%20Reference%3A%20*Schlecht%2C%20S.%2C%20Habets%2C%20E.%20(2019).%20Modal%20Decomposition%20of%20Feedback%0A%20%20%20%20Delay%20Networks.%20IEEE%20Transactions%20on%20Signal%20Processing%2067(20)%2C%205340-5351.*%0A%20%20%20%20%5Bdoi%3A10.1109%2Ftsp.2019.2937286%5D(https%3A%2F%2Fdx.doi.org%2F10.1109%2Ftsp.2019.2937286)%0A%0A%20%20%20%20Original%20MATLAB%3A%20%60example_randomFDNstatistics.m%60%2C%20Sebastian%20J.%20Schlecht%2C%2023%20April%202018.%0A%20%20%20%20Delays%20are%20scaled%20down%20relative%20to%20MATLAB%20to%20keep%20the%20eigendecomposition%20fast.%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%20modal%20decomposition%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(3)%0A%20%20%20%20fs%20%3D%2048000%0A%20%20%20%20ir_len%20%3D%20fs%20%2F%2F%202%0A%0A%20%20%20%20build%20%3D%20pyFDN.fdn_build_gallery(%0A%20%20%20%20%20%20%20%208%2C%0A%20%20%20%20%20%20%20%20fs%3Dfs%2C%0A%20%20%20%20%20%20%20%20delay_range%3D(100%2C%20401)%2C%0A%20%20%20%20%20%20%20%20io_type%3D%22identity%22%2C%0A%20%20%20%20%20%20%20%20direct_gain%3DNone%2C%0A%20%20%20%20%20%20%20%20rt%3DNone%2C%0A%20%20%20%20%20%20%20%20rng%3D3%2C%0A%20%20%20%20)%0A%20%20%20%20delays%20%3D%20build.delays%0A%20%20%20%20feedback_matrix%20%3D%20build.A%0A%20%20%20%20input_gain%2C%20output_gain%2C%20direct%20%3D%20build.B%2C%20build.C%2C%20build.D%0A%0A%20%20%20%20print(f%22Delays%3A%20%7Bdelays%7D%20(sum%20%3D%20%7Bdelays.sum()%7D)%22)%0A%20%20%20%20return%20delays%2C%20direct%2C%20feedback_matrix%2C%20input_gain%2C%20ir_len%2C%20output_gain%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20delays%2C%0A%20%20%20%20direct%2C%0A%20%20%20%20feedback_matrix%2C%0A%20%20%20%20input_gain%2C%0A%20%20%20%20ir_len%2C%0A%20%20%20%20np%2C%0A%20%20%20%20output_gain%2C%0A%20%20%20%20pyFDN%2C%0A)%3A%0A%20%20%20%20ir_time%20%3D%20pyFDN.dss_to_impz(%0A%20%20%20%20%20%20%20%20ir_len%2C%20delays%2C%20feedback_matrix%2C%20input_gain%2C%20output_gain%2C%20direct%0A%20%20%20%20)%5B%3A%2C%200%2C%200%5D%0A%0A%20%20%20%20residues%2C%20poles%2C%20direct_term%2C%20is_pair%2C%20meta%20%3D%20pyFDN.dss_to_pr(%0A%20%20%20%20%20%20%20%20delays%2C%20feedback_matrix%2C%20input_gain%2C%20output_gain%2C%20direct%0A%20%20%20%20)%0A%20%20%20%20undriven_residues%20%3D%20meta%5B%22undrivenResidues%22%5D%0A%0A%20%20%20%20ir_modal%20%3D%20pyFDN.pr_to_impz(%0A%20%20%20%20%20%20%20%20residues%2C%20poles%2C%20direct_term%2C%20is_pair%2C%20ir_len%2C%20mode%3D%22lowMemory%22%0A%20%20%20%20)%5B%3A%2C%200%2C%200%5D%0A%0A%20%20%20%20difference%20%3D%20ir_time%20-%20ir_modal%0A%20%20%20%20print(f%22Number%20of%20poles%3A%20%7Bpoles.size%7D%22)%0A%20%20%20%20print(f%22Max%20%7CIR_time%20-%20IR_modal%7C%20%3D%20%7Bnp.max(np.abs(difference))%3A.3e%7D%22)%0A%20%20%20%20return%20difference%2C%20ir_modal%2C%20ir_time%2C%20poles%2C%20residues%2C%20undriven_residues%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%20Time-domain%20vs%20modal%20reconstruction%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(difference%2C%20go%2C%20ir_modal%2C%20ir_time%2C%20np)%3A%0A%20%20%20%20fig_ir%20%3D%20go.Figure()%0A%20%20%20%20t_axis%20%3D%20np.arange(len(ir_time))%0A%20%20%20%20for%20_sig%2C%20_name%2C%20_offset%20in%20%5B%0A%20%20%20%20%20%20%20%20(difference%2C%20%22Difference%22%2C%200.0)%2C%0A%20%20%20%20%20%20%20%20(ir_time%2C%20%22Time%20domain%22%2C%20-2.0)%2C%0A%20%20%20%20%20%20%20%20(ir_modal%2C%20%22Poles%2Fresidues%22%2C%20-4.0)%2C%0A%20%20%20%20%5D%3A%0A%20%20%20%20%20%20%20%20fig_ir.add_trace(%0A%20%20%20%20%20%20%20%20%20%20%20%20go.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%3D_sig%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%22width%22%3A%200.8%7D%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_ir.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Impulse%20response%3A%20time-domain%20recursion%20vs%20modal%20synthesis%22%2C%0A%20%20%20%20%20%20%20%20xaxis%3D%7B%22title%22%3A%20%22Time%20(samples)%22%7D%2C%0A%20%20%20%20%20%20%20%20yaxis%3D%7B%22title%22%3A%20%22Amplitude%20(offset%20for%20display)%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%3D420%2C%0A%20%20%20%20)%0A%20%20%20%20fig_ir.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%20Pole%20angle%20distribution%0A%0A%20%20%20%20The%20pole%20angles%20of%20a%20random%20lossless%20FDN%20are%20nearly%20uniformly%20distributed.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(go%2C%20np%2C%20poles)%3A%0A%20%20%20%20angle_counts%2C%20angle_edges%20%3D%20np.histogram(%0A%20%20%20%20%20%20%20%20np.angle(poles)%2C%20bins%3Dnp.linspace(0%2C%20np.pi%2C%20300)%2C%20density%3DTrue%0A%20%20%20%20)%0A%20%20%20%20fig_angles%20%3D%20go.Figure(%0A%20%20%20%20%20%20%20%20go.Bar(x%3Dangle_edges%5B1%3A%5D%2C%20y%3Dangle_counts%2C%20marker%3D%7B%22line%22%3A%20%7B%22width%22%3A%200%7D%7D)%0A%20%20%20%20)%0A%20%20%20%20fig_angles.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Distribution%20of%20pole%20angles%22%2C%0A%20%20%20%20%20%20%20%20xaxis%3D%7B%22title%22%3A%20%22Pole%20angle%20(rad)%22%2C%20%22range%22%3A%20%5B0%2C%20np.pi%5D%7D%2C%0A%20%20%20%20%20%20%20%20yaxis%3D%7B%22title%22%3A%20%22Likelihood%20of%20occurrence%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%3D380%2C%0A%20%20%20%20%20%20%20%20bargap%3D0%2C%0A%20%20%20%20)%0A%20%20%20%20fig_angles.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%20Residue%20magnitude%20distribution%0A%0A%20%20%20%20Total%20residues%20split%20into%20the%20undriven%20part%20(system-intrinsic)%20and%20the%0A%20%20%20%20input%2Foutput%20drive.%20The%20total%20residue%20magnitudes%20span%20a%20wide%20dB%20range.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(go%2C%20np%2C%20pyFDN%2C%20residues%2C%20undriven_residues)%3A%0A%20%20%20%20db_edges%20%3D%20np.arange(-120.0%2C%2041.0%2C%201.0)%0A%0A%20%20%20%20def%20_pdf(values_db)%3A%0A%20%20%20%20%20%20%20%20counts%2C%20edges%20%3D%20np.histogram(values_db%2C%20bins%3Ddb_edges%2C%20density%3DTrue)%0A%20%20%20%20%20%20%20%20return%20edges%5B1%3A%5D%2C%20counts%0A%0A%20%20%20%20fig_res%20%3D%20go.Figure()%0A%20%20%20%20_x%2C%20_y%20%3D%20_pdf(pyFDN.lin_to_db(np.abs(residues%5B%3A%2C%200%2C%200%5D%20%2F%20undriven_residues)))%0A%20%20%20%20fig_res.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_x%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_y%2C%0A%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%20name%3D%22Input-output%20drives%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3D%7B%22dash%22%3A%20%22dot%22%2C%20%22color%22%3A%20%22black%22%7D%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%20%20%20%20_x%2C%20_y%20%3D%20_pdf(pyFDN.lin_to_db(np.abs(residues).ravel()))%0A%20%20%20%20fig_res.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(x%3D_x%2C%20y%3D_y%2C%20mode%3D%22lines%22%2C%20name%3D%22Total%20residues%22%2C%20line%3D%7B%22width%22%3A%202%7D)%0A%20%20%20%20)%0A%20%20%20%20_x%2C%20_y%20%3D%20_pdf(pyFDN.lin_to_db(np.abs(undriven_residues)))%0A%20%20%20%20fig_res.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_x%2C%20y%3D_y%2C%20mode%3D%22lines%22%2C%20name%3D%22Undriven%20residues%22%2C%20line%3D%7B%22width%22%3A%202%7D%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%20%20%20%20fig_res.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Distribution%20of%20residue%20magnitudes%22%2C%0A%20%20%20%20%20%20%20%20xaxis%3D%7B%22title%22%3A%20%22Residue%20magnitude%20(dB)%22%7D%2C%0A%20%20%20%20%20%20%20%20yaxis%3D%7B%22title%22%3A%20%22Likelihood%20of%20occurrence%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%3D420%2C%0A%20%20%20%20)%0A%20%20%20%20fig_res.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
31a407fd7f8fe99291ef6260a4a76aa6