%23%20%2F%2F%2F%20script%0A%23%20requires-python%20%3D%20%22%3E%3D3.14%22%0A%23%20dependencies%20%3D%20%5B%0A%23%20%20%20%20%20%22marimo%3E%3D0.21.1%22%2C%0A%23%20%5D%0A%23%20%2F%2F%2F%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.23.16%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0Aasync%20with%20app.setup(hide_code%3DTrue)%3A%0A%20%20%20%20%23%20Setup%20cell%20for%20marimo%20notebook%2C%20can%20be%20ignored%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20sys%0A%0A%20%20%20%20%23%20Import%20packages%20if%20running%20on%20marimo%20playground%0A%20%20%20%20if%20sys.executable%20%3D%3D%20%22%2Fhome%2Fpyodide%2Fthis.program%22%3A%0A%20%20%20%20%20%20%20%20import%20micropip%0A%0A%20%20%20%20%20%20%20%20await%20micropip.install(%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B%22pint_pandas%3C%3D0.7%22%2C%20%22typing_extensions%3E%3D4.15.0%22%2C%20%22poincare%3E%3D1.1.2%22%2C%20%22matplotlib%22%5D%2C%20verbose%20%3D%20False%0A%20%20%20%20%20%20%20%20)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Model%20composition%20in%20Poincare%0A%20%20%20%20One%20of%20Poincare's%20key%20features%20is%20being%20able%20to%20make%20larger%20models%20by%20composing%20smaller%20ones.%20Take%20as%20an%20example%20an%20oscillator%3A%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%20from%20poincare%20import%20(%0A%20%20%20%20%20%20%20%20Derivative%2C%0A%20%20%20%20%20%20%20%20Parameter%2C%0A%20%20%20%20%20%20%20%20Simulator%2C%0A%20%20%20%20%20%20%20%20System%2C%0A%20%20%20%20%20%20%20%20Variable%2C%0A%20%20%20%20%20%20%20%20assign%2C%0A%20%20%20%20%20%20%20%20initial%2C%0A%20%20%20%20)%0A%0A%20%20%20%20class%20Oscillator(System)%3A%0A%20%20%20%20%20%20%20%20x%3A%20Variable%20%3D%20initial(default%3D0)%0A%20%20%20%20%20%20%20%20vx%3A%20Derivative%20%3D%20x.derive(initial%3D0)%0A%0A%20%20%20%20%20%20%20%20spring_constant%3A%20Parameter%20%3D%20assign(default%3D0)%0A%0A%20%20%20%20%20%20%20%20spring%20%3D%20vx.derive()%20%3C%3C%20-spring_constant%20*%20x%0A%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20Derivative%2C%0A%20%20%20%20%20%20%20%20Oscillator%2C%0A%20%20%20%20%20%20%20%20Parameter%2C%0A%20%20%20%20%20%20%20%20Simulator%2C%0A%20%20%20%20%20%20%20%20System%2C%0A%20%20%20%20%20%20%20%20Variable%2C%0A%20%20%20%20%20%20%20%20assign%2C%0A%20%20%20%20%20%20%20%20initial%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Which%20represents%20the%20equations%3A%0A%20%20%20%20%24%24%20%5Cfrac%7Bd%5E2x%7D%7Bdt%5E2%7D%20%3D%20-kx%20%24%24%0A%20%20%20%20If%20we%20wanted%20to%20add%20damping%2C%20instead%20of%20adding%20it%20directly%20in%20the%20model's%20code%20we%20could%20create%20a%20second%20class%20for%20the%20damping%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Derivative%2C%20Parameter%2C%20System%2C%20Variable%2C%20assign%2C%20initial)%3A%0A%20%20%20%20class%20Damping(System)%3A%0A%20%20%20%20%20%20%20%20x%3A%20Variable%20%3D%20initial(default%3D0)%0A%20%20%20%20%20%20%20%20vx%3A%20Derivative%20%3D%20x.derive(initial%3D0)%0A%0A%20%20%20%20%20%20%20%20damp_rate%3A%20Parameter%20%3D%20assign(default%3D0)%0A%0A%20%20%20%20%20%20%20%20dampening%20%3D%20vx.derive()%20%3C%3C%20-damp_rate%20*%20vx%0A%0A%20%20%20%20return%20(Damping%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Which%20represents%20the%20equations%3A%0A%20%20%20%20%24%24%20%5Cfrac%7Bd%5E2x%7D%7Bdt%5E2%7D%20%3D%20-%5Cgamma%5Cfrac%7Bdx%7D%7Bdt%7D%20%24%24%0A%20%20%20%20And%20add%20both%20to%20a%20third%20model%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20Damping%2C%0A%20%20%20%20Derivative%2C%0A%20%20%20%20Oscillator%2C%0A%20%20%20%20Parameter%2C%0A%20%20%20%20System%2C%0A%20%20%20%20Variable%2C%0A%20%20%20%20assign%2C%0A%20%20%20%20initial%2C%0A)%3A%0A%20%20%20%20class%20DampedOscillator(System)%3A%0A%20%20%20%20%20%20%20%20%23%20Define%20new%20external%20variables%20for%20the%20sysyem%0A%20%20%20%20%20%20%20%20x_ext%3A%20Variable%20%3D%20initial(default%3D1)%0A%20%20%20%20%20%20%20%20vx_ext%3A%20Derivative%20%3D%20x_ext.derive(initial%3D0)%0A%0A%20%20%20%20%20%20%20%20spring_constant%3A%20Parameter%20%3D%20assign(default%3D1)%0A%20%20%20%20%20%20%20%20damp_rate%3A%20Parameter%20%3D%20assign(default%3D0.1)%0A%0A%20%20%20%20%20%20%20%20%23%20Apply%20the%20models%20to%20the%20external%20systems%20variables%0A%20%20%20%20%20%20%20%20oscillator%20%3D%20Oscillator(x%3Dx_ext%2C%20spring_constant%3Dspring_constant)%0A%20%20%20%20%20%20%20%20dampening%20%3D%20Damping(x%3Dx_ext%2C%20damp_rate%3Ddamp_rate)%0A%0A%20%20%20%20return%20(DampedOscillator%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Here%20we%20are%20applying%20the%20systems%20to%20the%20external%20variable%20%60x_ext%60%2C%20adding%20both%20equations%20for%20it's%20second%20derivative%3A%0A%20%20%20%20%24%24%20%5Cfrac%7Bd%5E2x%7D%7Bdt%5E2%7D%20%3D%20-%20kx%20-%20%5Cgamma%20%5Cfrac%7Bdx%7D%7Bdt%7D.%20%24%24%0A%20%20%20%20We%20can%20run%20it%20using%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(DampedOscillator%2C%20Simulator)%3A%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%0A%20%20%20%20sim_2%20%3D%20Simulator(DampedOscillator)%0A%20%20%20%20result_2%20%3D%20sim_2.solve(save_at%3Dnp.linspace(0%2C%2050%2C%201000))%0A%20%20%20%20result_2.to_dataframe().plot()%0A%20%20%20%20plt.show()%0A%20%20%20%20return%20(np%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Multiple%20variables%0A%20%20%20%20If%20we%20wanted%20to%20create%20a%20pair%20of%20coupled%20oscillators%20we%20can%20create%20a%20Coupling%0A%20%20%20%20class%20to%20represent%20the%20interaction%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Derivative%2C%20Parameter%2C%20System%2C%20Variable%2C%20assign%2C%20initial)%3A%0A%20%20%20%20class%20Coupling(System)%3A%0A%20%20%20%20%20%20%20%20%23%20Create%20the%20variables%20for%20both%20oscillators%0A%20%20%20%20%20%20%20%20x_1%3A%20Variable%20%3D%20initial(default%3D0)%0A%20%20%20%20%20%20%20%20v_1%3A%20Derivative%20%3D%20x_1.derive(initial%3D0)%0A%20%20%20%20%20%20%20%20x_2%3A%20Variable%20%3D%20initial(default%3D0)%0A%20%20%20%20%20%20%20%20v_2%3A%20Derivative%20%3D%20x_2.derive(initial%3D0)%0A%0A%20%20%20%20%20%20%20%20spring_constant%3A%20Parameter%20%3D%20assign(default%3D0.1)%0A%0A%20%20%20%20%20%20%20%20%23%20Apply%20the%20force%20from%20the%20interaction%20to%20both%20springs%0A%20%20%20%20%20%20%20%20force_1%20%3D%20v_1.derive()%20%3C%3C%20spring_constant%20*%20(x_2%20-%20x_1)%0A%20%20%20%20%20%20%20%20force_2%20%3D%20v_2.derive()%20%3C%3C%20spring_constant%20*%20(x_1%20-%20x_2)%0A%0A%20%20%20%20return%20(Coupling%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20And%20compose%20it%20with%20the%20damped%20oscillator%20class%20we%20defined%20before%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20Coupling%2C%0A%20%20%20%20DampedOscillator%2C%0A%20%20%20%20Derivative%2C%0A%20%20%20%20Parameter%2C%0A%20%20%20%20System%2C%0A%20%20%20%20Variable%2C%0A%20%20%20%20assign%2C%0A%20%20%20%20initial%2C%0A)%3A%0A%20%20%20%20class%20CoupledOscillators(System)%3A%0A%20%20%20%20%20%20%20%20%23%20Create%20the%20variables%20for%20both%20oscillators%0A%20%20%20%20%20%20%20%20x_1%3A%20Variable%20%3D%20initial(default%3D1)%0A%20%20%20%20%20%20%20%20v_1%3A%20Derivative%20%3D%20x_1.derive(initial%3D0)%0A%20%20%20%20%20%20%20%20x_2%3A%20Variable%20%3D%20initial(default%3D0)%0A%20%20%20%20%20%20%20%20v_2%3A%20Derivative%20%3D%20x_2.derive(initial%3D0)%0A%0A%20%20%20%20%20%20%20%20%23%20Define%20separate%20constants%20for%20the%20restoring%20force%20on%20each%20spring%20and%20the%20interaction%0A%20%20%20%20%20%20%20%20own_constant%3A%20Parameter%20%3D%20assign(default%3D1)%0A%20%20%20%20%20%20%20%20interaction_constant%3A%20Parameter%20%3D%20assign(default%3D0.05)%0A%20%20%20%20%20%20%20%20damp_rate%3A%20Parameter%20%3D%20assign(default%3D0.01)%0A%0A%20%20%20%20%20%20%20%20%23%20Apply%20Damped%20Oscillator%20model%20to%20each%20of%20the%20variables%0A%20%20%20%20%20%20%20%20Damped_1%20%3D%20DampedOscillator(%0A%20%20%20%20%20%20%20%20%20%20%20%20x_ext%3Dx_1%2C%20spring_constant%3Down_constant%2C%20damp_rate%3Ddamp_rate%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20Damped_2%20%3D%20DampedOscillator(%0A%20%20%20%20%20%20%20%20%20%20%20%20x_ext%3Dx_2%2C%20spring_constant%3Down_constant%2C%20damp_rate%3Ddamp_rate%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Since%20the%20Coupling%20model%20includes%20efffect%20of%20the%20interaction%20for%20both%20we%20only%20need%20to%20apply%20it%20once%0A%20%20%20%20%20%20%20%20Coupling%20%3D%20Coupling(x_1%3Dx_1%2C%20x_2%3Dx_2%2C%20spring_constant%3Dinteraction_constant)%0A%0A%20%20%20%20return%20(CoupledOscillators%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20And%20we%20can%20run%20it%20to%20get%20the%20expected%20beats%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(CoupledOscillators%2C%20Simulator%2C%20np)%3A%0A%20%20%20%20sim_3%20%3D%20Simulator(CoupledOscillators)%0A%20%20%20%20result_3%20%3D%20sim_3.solve(save_at%3Dnp.linspace(0%2C%20500%2C%201000))%0A%20%20%20%20result_3%5B%5B%22x_1%22%2C%20%22x_2%22%5D%5D.to_dataframe().plot()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20We%20can%20easily%20create%20larger%20systems%20this%20way%3B%20for%20a%20chain%20of%204%20coupled%20oscillators%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20Coupling%2C%0A%20%20%20%20DampedOscillator%2C%0A%20%20%20%20Derivative%2C%0A%20%20%20%20Parameter%2C%0A%20%20%20%20System%2C%0A%20%20%20%20Variable%2C%0A%20%20%20%20assign%2C%0A%20%20%20%20initial%2C%0A)%3A%0A%20%20%20%20class%20CoupledOscillatorsFour(System)%3A%0A%20%20%20%20%20%20%20%20%23%20Create%20the%20variables%20for%20all%20oscillators%0A%20%20%20%20%20%20%20%20x_1%3A%20Variable%20%3D%20initial(default%3D1)%0A%20%20%20%20%20%20%20%20v_1%3A%20Derivative%20%3D%20x_1.derive(initial%3D0)%0A%20%20%20%20%20%20%20%20x_2%3A%20Variable%20%3D%20initial(default%3D0)%0A%20%20%20%20%20%20%20%20v_2%3A%20Derivative%20%3D%20x_2.derive(initial%3D0)%0A%20%20%20%20%20%20%20%20x_3%3A%20Variable%20%3D%20initial(default%3D0)%0A%20%20%20%20%20%20%20%20v_3%3A%20Derivative%20%3D%20x_3.derive(initial%3D0)%0A%20%20%20%20%20%20%20%20x_4%3A%20Variable%20%3D%20initial(default%3D0)%0A%20%20%20%20%20%20%20%20v_4%3A%20Derivative%20%3D%20x_4.derive(initial%3D0)%0A%20%20%20%20%20%20%20%20%23%20Define%20separate%20constants%20for%20the%20restoring%20force%20on%20each%20spring%20and%20the%20interaction%0A%20%20%20%20%20%20%20%20own_constant%3A%20Parameter%20%3D%20assign(default%3D1)%0A%20%20%20%20%20%20%20%20interaction_constant%3A%20Parameter%20%3D%20assign(default%3D0.05)%0A%20%20%20%20%20%20%20%20damp_rate%3A%20Parameter%20%3D%20assign(default%3D0.01)%0A%0A%20%20%20%20%20%20%20%20%23%20Apply%20Damped%20Oscillator%20model%20to%20each%20of%20the%20variables%0A%20%20%20%20%20%20%20%20Damped_1%20%3D%20DampedOscillator(%0A%20%20%20%20%20%20%20%20%20%20%20%20x_ext%3Dx_1%2C%20spring_constant%3Down_constant%2C%20damp_rate%3Ddamp_rate%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20Damped_2%20%3D%20DampedOscillator(%0A%20%20%20%20%20%20%20%20%20%20%20%20x_ext%3Dx_2%2C%20spring_constant%3Down_constant%2C%20damp_rate%3Ddamp_rate%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20Damped_3%20%3D%20DampedOscillator(%0A%20%20%20%20%20%20%20%20%20%20%20%20x_ext%3Dx_3%2C%20spring_constant%3Down_constant%2C%20damp_rate%3Ddamp_rate%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20Damped_4%20%3D%20DampedOscillator(%0A%20%20%20%20%20%20%20%20%20%20%20%20x_ext%3Dx_4%2C%20spring_constant%3Down_constant%2C%20damp_rate%3Ddamp_rate%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Since%20the%20Coupling%20model%20includes%20efffect%20of%20the%20interaction%20for%20all%20interacting%20paris%201-2%2C%202-3%2C%203-4%0A%20%20%20%20%20%20%20%20Coupling_12%20%3D%20Coupling(x_1%3Dx_1%2C%20x_2%3Dx_2%2C%20spring_constant%3Dinteraction_constant)%0A%20%20%20%20%20%20%20%20Coupling_23%20%3D%20Coupling(x_1%3Dx_2%2C%20x_2%3Dx_3%2C%20spring_constant%3Dinteraction_constant)%0A%20%20%20%20%20%20%20%20Coupling_34%20%3D%20Coupling(x_1%3Dx_3%2C%20x_2%3Dx_4%2C%20spring_constant%3Dinteraction_constant)%0A%0A%20%20%20%20return%20(CoupledOscillatorsFour%2C)%0A%0A%0A%40app.cell%0Adef%20_(CoupledOscillatorsFour%2C%20Simulator%2C%20np)%3A%0A%20%20%20%20sim_4%20%3D%20Simulator(CoupledOscillatorsFour)%0A%20%20%20%20result_4%20%3D%20sim_4.solve(save_at%3Dnp.linspace(0%2C%20500%2C%201000))%0A%20%20%20%20result_4%5B%5B%22x_1%22%2C%20%22x_2%22%2C%20%22x_3%22%2C%20%22x_4%22%5D%5D.to_dataframe().plot()%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
63e4f022b793d6980e4561f25e92e30b