%23%20gallery_category%3A%20Analysis%20%26%20Verification%0A%23%20gallery_description%3A%20Analyze%20the%20pole-angle%20and%20residue%20distributions%20of%20random%20FDNs%20and%20separate%20modal%20drive%20from%20undriven%20residue.%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.25.1%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%20almost%20equidistributed%20on%20the%20unit%20circle%2C%20while%20the%20residue%20magnitudes%20are%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%20the%20input%E2%80%93output%20drive.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%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%20Reference%3A%20*%7BpyFDN.paper_link(%22Schlecht2019ModalDecompositionFeedback%22)%7D*%0A%0A%20%20%20%20Delays%20are%20scaled%20down%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%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%0A%20%20%20%20import%20pyFDN%0A%0A%20%20%20%20return%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%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%20delays%2C%20feedback_matrix%2C%20input_gain%2C%20output_gain%2C%20direct%2C%20ir_len%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%20ir_modal%2C%20ir_time%2C%20np%2C%20plt)%3A%0A%20%20%20%20fig_ir%2C%20_ax%20%3D%20plt.subplots(figsize%3D(8%2C%204.2))%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%20_ax.plot(t_axis%2C%20_sig%20%2B%20_offset%2C%20linewidth%3D0.8%2C%20label%3D_name)%0A%20%20%20%20_ax.set_title(%22Impulse%20response%3A%20time-domain%20recursion%20vs%20modal%20synthesis%22)%0A%20%20%20%20_ax.set_xlabel(%22Time%20(samples)%22)%0A%20%20%20%20_ax.set_ylabel(%22Amplitude%20(offset%20for%20display)%22)%0A%20%20%20%20_ax.legend()%0A%20%20%20%20fig_ir.tight_layout()%0A%20%20%20%20fig_ir%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_(np%2C%20plt%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%2C%20_ax%20%3D%20plt.subplots(figsize%3D(8%2C%203.8))%0A%20%20%20%20_ax.stairs(angle_counts%2C%20angle_edges%2C%20fill%3DTrue)%0A%20%20%20%20_ax.set_xlim(0%2C%20np.pi)%0A%20%20%20%20_ax.set_title(%22Distribution%20of%20pole%20angles%22)%0A%20%20%20%20_ax.set_xlabel(%22Pole%20angle%20(rad)%22)%0A%20%20%20%20_ax.set_ylabel(%22Likelihood%20of%20occurrence%22)%0A%20%20%20%20fig_angles.tight_layout()%0A%20%20%20%20fig_angles%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%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_(np%2C%20plt%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%2C%20_ax%20%3D%20plt.subplots(figsize%3D(8%2C%204.2))%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%20_ax.plot(_x%2C%20_y%2C%20linestyle%3D%22%3A%22%2C%20color%3D%22black%22%2C%20label%3D%22Input-output%20drives%22)%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%20_ax.plot(_x%2C%20_y%2C%20linewidth%3D2%2C%20label%3D%22Total%20residues%22)%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%20_ax.plot(_x%2C%20_y%2C%20linewidth%3D2%2C%20label%3D%22Undriven%20residues%22)%0A%20%20%20%20_ax.set_title(%22Distribution%20of%20residue%20magnitudes%22)%0A%20%20%20%20_ax.set_xlabel(%22Residue%20magnitude%20(dB)%22)%0A%20%20%20%20_ax.set_ylabel(%22Likelihood%20of%20occurrence%22)%0A%20%20%20%20_ax.legend()%0A%20%20%20%20fig_res.tight_layout()%0A%20%20%20%20fig_res%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
6e711dd8dd2e0bf999335a6f77065d75