%23%20gallery_category%3A%20Representations%0A%23%20gallery_description%3A%20Convert%20delay%20state-space%20FDN%20parameters%20into%20a%20conventional%20state-space%20model%20and%20verify%20matching%20impulse%20responses.%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)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Delay%20state-space%20to%20state-space%0A%0A%20%20%20%20Delay%20state-space%20form%20describes%20an%20FDN%20with%20%24N%24%20delay%20lines%20as%20%24N%24%20delay%20lengths%20plus%20an%20%24N%20%5Ctimes%20N%24%20feedback%20matrix%20%E2%80%94%20a%20compact%20description%20that%20says%20nothing%20about%20how%20many%20states%20the%20system%20actually%20has.%20%60pyFDN.dss_to_ss%60%20expands%20it%20into%20an%20ordinary%20state-space%20system%20by%20giving%20every%20sample%20inside%20every%20delay%20line%20its%20own%20state%2C%20so%20the%20%24N%20%5Ctimes%20N%24%20feedback%20matrix%20becomes%20a%20%24%5Csum_i%20m_i%24%20square%20matrix%20of%20mostly%20shift%20structure.%0A%0A%20%20%20%20That%20expansion%20is%20what%20lets%20any%20standard%20state-space%20tool%20work%20on%20an%20FDN%20%E2%80%94%20here%20%60scipy.signal.dimpulse%60%2C%20but%20equally%20a%20controllability%20or%20balancing%20routine.%20The%20price%20is%20size%3A%20three%20delays%20of%2013%2C%2019%20and%2023%20samples%20already%20need%2055%20states%2C%20and%20a%20realistic%20FDN%20needs%20tens%20of%20thousands.%20The%20delays%20are%20kept%20deliberately%20tiny%20for%20that%20reason.%0A%20%20%20%20%22%22%22)%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%20A%20three-delay%20FDN%0A%0A%20%20%20%20Three%20short%20delays%20with%20a%20random%20orthogonal%20feedback%20matrix%20and%20random%20input%2Foutput%20vectors.%20The%20per-line%20attenuation%20that%20%60fdn_build_gallery%60%20returns%20as%20a%20separate%20%60post_delay%60%20gain%20is%20folded%20into%20the%20feedback%20matrix%2C%20so%20the%20whole%20loop%20is%20the%20single%20matrix%20%60A%60%20that%20%60dss_to_ss%60%20expects.%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%20dataclasses%0A%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20from%20scipy.signal%20import%20dimpulse%2C%20dlti%0A%0A%20%20%20%20import%20pyFDN%0A%0A%20%20%20%20np.random.seed(1)%0A%20%20%20%20impulse_response_length%20%3D%201000%0A%0A%20%20%20%20m%20%3D%20np.array(%5B13%2C%2019%2C%2023%5D)%0A%20%20%20%20build%20%3D%20pyFDN.fdn_build_gallery(%0A%20%20%20%20%20%20%20%20delays%3Dm%2C%0A%20%20%20%20%20%20%20%20io_type%3D%22random%22%2C%0A%20%20%20%20%20%20%20%20direct_gain%3DNone%2C%0A%20%20%20%20%20%20%20%20rt%3D0.02%2C%0A%20%20%20%20%20%20%20%20rng%3D1%2C%0A%20%20%20%20)%0A%20%20%20%20build%20%3D%20dataclasses.replace(build%2C%20A%3Dnp.diag(build.post_delay%5B0%2C%200%2C%20%3A%5D)%20%40%20build.A)%0A%20%20%20%20A%2C%20b%2C%20c%2C%20d%20%3D%20build.A%2C%20build.B%2C%20build.C%2C%20build.D%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20A%2C%0A%20%20%20%20%20%20%20%20b%2C%0A%20%20%20%20%20%20%20%20build%2C%0A%20%20%20%20%20%20%20%20c%2C%0A%20%20%20%20%20%20%20%20d%2C%0A%20%20%20%20%20%20%20%20dimpulse%2C%0A%20%20%20%20%20%20%20%20dlti%2C%0A%20%20%20%20%20%20%20%20impulse_response_length%2C%0A%20%20%20%20%20%20%20%20m%2C%0A%20%20%20%20%20%20%20%20np%2C%0A%20%20%20%20%20%20%20%20pyFDN%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%20Expand%20and%20compare%0A%0A%20%20%20%20%60dss_to_ss%60%20returns%20the%20expanded%20matrices%3B%20%60scipy.signal.dimpulse%60%20then%20treats%20the%20FDN%20as%20any%20other%20discrete-time%20system.%20Running%20the%20delay%20recursion%20with%20%60dss_to_impz%60%20gives%20the%20reference.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A%2C%20b%2C%20c%2C%20d%2C%20dimpulse%2C%20dlti%2C%20impulse_response_length%2C%20m%2C%20np%2C%20pyFDN)%3A%0A%20%20%20%20aa%2C%20bb%2C%20cc%2C%20dd%20%3D%20pyFDN.dss_to_ss(m%2C%20A%2C%20b%2C%20c%2C%20d)%0A%0A%20%20%20%20system%20%3D%20dlti(aa%2C%20bb%2C%20cc%2C%20dd%2C%20dt%3D1.0)%0A%20%20%20%20_%2C%20ir_state_space%20%3D%20dimpulse(system%2C%20n%3Dimpulse_response_length)%0A%20%20%20%20ir_state_space%20%3D%20np.squeeze(ir_state_space)%0A%0A%20%20%20%20ir_delay_state_space%20%3D%20pyFDN.dss_to_impz(impulse_response_length%2C%20m%2C%20A%2C%20b%2C%20c%2C%20d)%0A%20%20%20%20ir_delay_state_space%20%3D%20np.asarray(ir_delay_state_space).squeeze()%0A%0A%20%20%20%20assert%20pyFDN.is_almost_zero(ir_state_space%20-%20ir_delay_state_space%2C%20tol%3D0.001)%0A%0A%20%20%20%20pyFDN.plot_impulse_response(%0A%20%20%20%20%20%20%20%20ir_state_space%2C%0A%20%20%20%20%20%20%20%20ir_delay_state_space%2C%0A%20%20%20%20%20%20%20%20labels%3D%5B%22State%20space%22%2C%20%22Delay%20state%20space%22%5D%2C%0A%20%20%20%20)%0A%20%20%20%20return%20aa%2C%20bb%2C%20cc%2C%20dd%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%20The%20FDN%20it%20started%20from%0A%0A%20%20%20%20Feedback%20matrix%2C%20delays%2C%20input%2Foutput%20vectors%20and%20magnitude%20response%20of%20the%20delay%20state-space%20description.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(build%2C%20pyFDN)%3A%0A%20%20%20%20pyFDN.plot_FDN_build(build%2C%20title%3D%22FDN%20parameters%22)%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%20The%20expanded%20system%0A%0A%20%20%20%20The%20same%20FDN%20as%20one%2055-state%20system.%20The%20feedback%20matrix%20is%20almost%20entirely%20the%20sub-diagonal%20that%20shifts%20each%20delay%20line%20along%20by%20one%20sample%3B%20the%20original%20%243%20%5Ctimes%203%24%20mixing%20survives%20only%20in%20the%20few%20entries%20where%20a%20delay%20line%20ends%20and%20feeds%20the%20others.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(aa%2C%20bb%2C%20cc%2C%20dd%2C%20pyFDN)%3A%0A%20%20%20%20pyFDN.plot_system_matrix(aa%2C%20bb%2C%20cc%2C%20dd%2C%20title%3D%22State-space%20system%22)%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
302930f190a7a56b12e0d8344247a3b4