import%20marimo%0A%0A__generated_with%20%3D%20%220.25.2%22%0Aapp%20%3D%20marimo.App(%0A%20%20%20%20width%3D%22medium%22%2C%0A%20%20%20%20app_title%3D%22Week%204%20%E2%80%94%20ODEs%3A%20direction%20fields%20and%20the%20discrete%20origin%22%2C%0A)%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%20Week%204%3A%20Ordinary%20differential%20equations%20%E2%80%94%20geometry%20and%20the%20discrete%20origin%0A%20%20%20%20%23%23%20Computation%20lecture%0A%0A%20%20%20%20**MATH4120%20%E2%80%94%20Mathematical%20Modelling%20and%20Programming**%20Lancaster%20University%2C%202026%E2%80%9327%0A%0A%20%20%20%20---%0A%0A%20%20%20%20Lectures%20this%20week%20focused%20on%20solving%20ODEs%20by%20hand%20%E2%80%94%20separation%20of%20variables%2C%20integrating%20factors%2C%20and%20the%20auxiliary%20equation.%20%20Here%20we%20step%20back%20and%20ask%20a%20more%20fundamental%20question%3A%20*what%20is%20an%20ODE%2C%20geometrically%3F*%0A%0A%20%20%20%20Two%20ideas.%20%20First%3A%20a%20direction%20field%2C%20which%20turns%20any%20ODE%20into%20a%20picture.%20%20Second%3A%20where%20the%20ODE%20comes%20from.%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%20matplotlib.pyplot%20as%20plt%0A%0A%20%20%20%20return%20np%2C%20plt%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%201.%20Direction%20fields%0A%0A%20%20%20%20A%20first-order%20ODE%20%24y'%20%3D%20f(t%2C%20y)%24%20looks%20like%20an%20equation%20to%20*solve*.%20Read%20it%20another%20way%3A%20it%20is%20a%20**rule%20that%20gives%20a%20slope**.%20Pick%20any%20point%20%24(t%2C%20y)%24%20in%20the%20plane%2C%20plug%20it%20into%20%24f%24%2C%20and%20out%20comes%20a%20number%3A%20the%20slope%20that%20a%20solution%20curve%20passing%20through%20that%20point%20must%20have%20there.%0A%0A%20%20%20%20We%20will%20use%20an%20example%20from%20this%20week's%20lectures%20(integrating%20factor)%3A%20%5C%5By'%20%3D%20t%20-%20y%2C%20%5Cqquad%5Ctext%7Bso%7D%5Cqquad%20f(t%2C%20y)%20%3D%20t%20-%20y.%5C%5D%0A%0A%20%20%20%20%23%23%23%201.1%20One%20point%2C%20one%20arrow%0A%0A%20%20%20%20At%20the%20point%20%24(t%2C%20y)%20%3D%20(2%2C%200.5)%24%20the%20slope%20is%20%24f(2%2C%200.5)%20%3D%202%20-%200.5%20%3D%201.5%24.%20In%20Python%2C%20%24f%24%20is%20just%20a%20function%20of%20two%20inputs%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.function%0Adef%20f_relax(t%2C%20y)%3A%0A%20%20%20%20return%20t%20-%20y%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20t_point%20%3D%202.0%0A%20%20%20%20y_point%20%3D%200.5%0A%20%20%20%20slope_point%20%3D%20f_relax(t_point%2C%20y_point)%0A%20%20%20%20print(%22slope%20at%20(2%2C%200.5)%20is%22%2C%20slope_point)%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%20A%20slope%20of%20%241.5%24%20means%3A%20**go%201%20to%20the%20right%2C%20go%201.5%20up**.%20That%20is%20the%20arrow%20we%20draw%20at%20the%20point%2C%20the%20vector%20%24(1%2C%5C%20f(t%2C%20y))%24.%20Move%20the%20point%20around%20and%20watch%20the%20arrow%20change.%20Before%20you%20move%20it%3A%20where%20do%20you%20expect%20the%20arrow%20to%20point%20*downhill*%3F%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20t_point_slider%20%3D%20mo.ui.slider(0.0%2C%203.0%2C%20step%3D0.5%2C%20value%3D2.0%2C%20label%3Dr%22%24t%24%22)%0A%20%20%20%20y_point_slider%20%3D%20mo.ui.slider(0.0%2C%203.0%2C%20step%3D0.5%2C%20value%3D0.5%2C%20label%3Dr%22%24y%24%22)%0A%20%20%20%20return%20t_point_slider%2C%20y_point_slider%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20plt%2C%20t_point_slider%2C%20y_point_slider)%3A%0A%20%20%20%20_t0%20%3D%20t_point_slider.value%0A%20%20%20%20_y0%20%3D%20y_point_slider.value%0A%20%20%20%20_f0%20%3D%20f_relax(_t0%2C%20_y0)%0A%0A%20%20%20%20_fig1%2C%20_ax1%20%3D%20plt.subplots(figsize%3D(8%2C%205))%0A%0A%20%20%20%20%23%20run%3A%201%20to%20the%20right%0A%20%20%20%20_ax1.plot(%5B_t0%2C%20_t0%20%2B%201%5D%2C%20%5B_y0%2C%20_y0%5D%2C%20%22--%22%2C%20color%3D%22%231a5276%22%2C%20linewidth%3D1.5)%0A%20%20%20%20_ax1.text(_t0%20%2B%200.5%2C%20_y0%20-%200.12%2C%20%22run%20%3D%201%22%2C%20ha%3D%22center%22%2C%20va%3D%22top%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20fontsize%3D12%2C%20color%3D%22%231a5276%22)%0A%20%20%20%20%23%20rise%3A%20f(t%2C%20y)%20up%20(or%20down)%0A%20%20%20%20_ax1.plot(%5B_t0%20%2B%201%2C%20_t0%20%2B%201%5D%2C%20%5B_y0%2C%20_y0%20%2B%20_f0%5D%2C%20%22--%22%2C%20color%3D%22%231e8449%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20linewidth%3D1.5)%0A%20%20%20%20_ax1.text(_t0%20%2B%201.08%2C%20_y0%20%2B%20_f0%20%2F%202%2C%20rf%22rise%20%3D%20%24f%24%20%3D%20%7B_f0%3Ag%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20ha%3D%22left%22%2C%20va%3D%22center%22%2C%20fontsize%3D12%2C%20color%3D%22%231e8449%22)%0A%20%20%20%20%23%20the%20arrow%20itself%0A%20%20%20%20_ax1.annotate(%22%22%2C%20xy%3D(_t0%20%2B%201%2C%20_y0%20%2B%20_f0)%2C%20xytext%3D(_t0%2C%20_y0)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20arrowprops%3Ddict(arrowstyle%3D%22-%7C%3E%22%2C%20color%3D%22%23922b21%22%2C%20lw%3D2.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mutation_scale%3D20))%0A%20%20%20%20_ax1.plot(_t0%2C%20_y0%2C%20%22o%22%2C%20color%3D%22%23922b21%22%2C%20markersize%3D9%2C%20zorder%3D5)%0A%0A%20%20%20%20_ax1.set_xlim(-0.3%2C%204.6)%0A%20%20%20%20_ax1.set_ylim(-0.5%2C%203.5)%0A%20%20%20%20_ax1.set_aspect(%22equal%22)%0A%20%20%20%20_ax1.set_xlabel(r%22%24t%24%22%2C%20fontsize%3D13)%0A%20%20%20%20_ax1.set_ylabel(r%22%24y%24%22%2C%20fontsize%3D13)%0A%20%20%20%20_ax1.set_title(%0A%20%20%20%20%20%20%20%20rf%22At%20%24(t%2C%20y)%20%3D%20(%7B_t0%3Ag%7D%2C%20%7B_y0%3Ag%7D)%24%3A%20%20%20%22%0A%20%20%20%20%20%20%20%20rf%22%24f%20%3D%20t%20-%20y%20%3D%20%7B_t0%3Ag%7D%20-%20%7B_y0%3Ag%7D%20%3D%20%7B_f0%3Ag%7D%24%22%2C%0A%20%20%20%20%20%20%20%20fontsize%3D13%2C%0A%20%20%20%20)%0A%20%20%20%20_ax1.grid(True%2C%20alpha%3D0.3)%0A%20%20%20%20_fig1.tight_layout()%0A%20%20%20%20mo.vstack(%5Bt_point_slider%2C%20y_point_slider%2C%20_fig1%5D)%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%23%201.2%20Many%20points%2C%20many%20arrows%0A%0A%20%20%20%20Now%20do%20the%20same%20at%20lots%20of%20points.%20Here%20are%20the%20slopes%20at%20the%2016%20whole-number%20points%20with%20%24t%24%20and%20%24y%24%20between%200%20and%203%2C%20laid%20out%20like%20the%20plane%20(large%20%24y%24%20at%20the%20top)%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%20print(%22%20%20%20%20%20%20%20%20%20t%20%3D%200%20%20%20t%20%3D%201%20%20%20t%20%3D%202%20%20%20t%20%3D%203%22)%0A%20%20%20%20for%20y_row%20in%20%5B3%2C%202%2C%201%2C%200%5D%3A%0A%20%20%20%20%20%20%20%20table_line%20%3D%20%22y%20%3D%20%22%20%2B%20str(y_row)%20%2B%20%22%20%20%20%22%0A%20%20%20%20%20%20%20%20for%20t_col%20in%20%5B0%2C%201%2C%202%2C%203%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20table_line%20%3D%20table_line%20%2B%20f%22%7Bf_relax(t_col%2C%20y_row)%3A6%7D%20%20%22%0A%20%20%20%20%20%20%20%20print(table_line)%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**Question.**%20Find%20the%20zeros%20in%20the%20table.%20What%20line%20do%20they%20lie%20on%3F%20What%20does%20a%20zero%20slope%20look%20like%20as%20an%20arrow%3F%0A%0A%20%20%20%20Below%2C%20every%20one%20of%20those%20numbers%20becomes%20an%20arrow.%20Start%20with%204%20points%20per%20side%20(the%20table%20above)%2C%20then%20drag%20the%20slider%20up.%20One%20thing%20changes%3A%20a%20slope%20of%20%243%24%20gives%20an%20arrow%20three%20times%20taller%20than%20a%20slope%20of%20%241%24%2C%20and%20a%20slope%20of%20%2450%24%20would%20fill%20the%20whole%20picture.%20So%20when%20we%20draw%20a%20field%20we%20**give%20every%20arrow%20the%20same%20length%20and%20keep%20only%20its%20direction**.%20The%20slope%20is%20still%20exactly%20%24f(t%2C%20y)%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(np)%3A%0A%20%20%20%20def%20draw_arrows(ax%2C%20f%2C%20t_min%2C%20t_max%2C%20y_min%2C%20y_max%2C%20n_t%2C%20n_y%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pivot%3D%22mid%22%2C%20inset%3DTrue%2C%20color%3D%22grey%22%2C%20alpha%3D0.6%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width%3D0.003)%3A%0A%20%20%20%20%20%20%20%20%22%22%22Draw%20the%20arrow%20(1%2C%20f(t%2C%20y))%20at%20every%20grid%20point%2C%20all%20the%20same%20length%20on%20screen.%22%22%22%0A%20%20%20%20%20%20%20%20fig%20%3D%20ax.figure%0A%20%20%20%20%20%20%20%20ax.apply_aspect()%0A%20%20%20%20%20%20%20%20box%20%3D%20ax.get_position()%0A%20%20%20%20%20%20%20%20t_per_inch%20%3D%20(t_max%20-%20t_min)%20%2F%20(fig.get_figwidth()%20*%20box.width)%0A%20%20%20%20%20%20%20%20y_per_inch%20%3D%20(y_max%20-%20y_min)%20%2F%20(fig.get_figheight()%20*%20box.height)%0A%20%20%20%20%20%20%20%20if%20inset%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20t_vals%20%3D%20np.linspace(t_min%2C%20t_max%2C%20n_t%20%2B%202)%5B1%3A-1%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20y_vals%20%3D%20np.linspace(y_min%2C%20y_max%2C%20n_y%20%2B%202)%5B1%3A-1%5D%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20t_vals%20%3D%20np.linspace(t_min%2C%20t_max%2C%20n_t)%0A%20%20%20%20%20%20%20%20%20%20%20%20y_vals%20%3D%20np.linspace(y_min%2C%20y_max%2C%20n_y)%0A%20%20%20%20%20%20%20%20T%2C%20Y%20%3D%20np.meshgrid(t_vals%2C%20y_vals)%0A%20%20%20%20%20%20%20%20%23%20arrows%20fill%2070%25%20of%20the%20gap%20between%20neighbouring%20grid%20points%0A%20%20%20%20%20%20%20%20gap_t_in%20%3D%20(t_vals%5B1%5D%20-%20t_vals%5B0%5D)%20%2F%20t_per_inch%0A%20%20%20%20%20%20%20%20gap_y_in%20%3D%20(y_vals%5B1%5D%20-%20y_vals%5B0%5D)%20%2F%20y_per_inch%0A%20%20%20%20%20%20%20%20arrow_inches%20%3D%200.7%20*%20min(gap_t_in%2C%20gap_y_in)%0A%20%20%20%20%20%20%20%20run%20%3D%20np.ones_like(T)%0A%20%20%20%20%20%20%20%20rise%20%3D%20f(T%2C%20Y)%20*%20np.ones_like(T)%0A%20%20%20%20%20%20%20%20%23%20measure%20each%20arrow%20in%20inches%20on%20screen%2C%20then%20scale%20to%20a%20fixed%20length%0A%20%20%20%20%20%20%20%20run_in%20%3D%20run%20%2F%20t_per_inch%0A%20%20%20%20%20%20%20%20rise_in%20%3D%20rise%20%2F%20y_per_inch%0A%20%20%20%20%20%20%20%20length_in%20%3D%20np.hypot(run_in%2C%20rise_in)%0A%20%20%20%20%20%20%20%20U%20%3D%20run_in%20%2F%20length_in%20*%20arrow_inches%20*%20t_per_inch%0A%20%20%20%20%20%20%20%20V%20%3D%20rise_in%20%2F%20length_in%20*%20arrow_inches%20*%20y_per_inch%0A%20%20%20%20%20%20%20%20ax.quiver(T%2C%20Y%2C%20U%2C%20V%2C%20angles%3D%22xy%22%2C%20scale_units%3D%22xy%22%2C%20scale%3D1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pivot%3Dpivot%2C%20color%3Dcolor%2C%20alpha%3Dalpha%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width%3Dwidth%2C%20headwidth%3D3.5%2C%20headlength%3D4.5)%0A%20%20%20%20%20%20%20%20return%20T%2C%20Y%2C%20rise%0A%0A%20%20%20%20return%20(draw_arrows%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20n_grid_slider%20%3D%20mo.ui.slider(2%2C%2020%2C%20step%3D1%2C%20value%3D4%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3D%22Points%20per%20side%22)%0A%20%20%20%20return%20(n_grid_slider%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(draw_arrows%2C%20mo%2C%20n_grid_slider%2C%20plt)%3A%0A%20%20%20%20_n%20%3D%20n_grid_slider.value%0A%0A%20%20%20%20_fig2%2C%20_ax2%20%3D%20plt.subplots(figsize%3D(8%2C%205.5))%0A%20%20%20%20_ax2.set_xlim(-0.4%2C%203.8)%0A%20%20%20%20_ax2.set_ylim(-0.4%2C%203.4)%0A%20%20%20%20_ax2.set_aspect(%22equal%22)%0A%20%20%20%20_ax2.set_xlabel(r%22%24t%24%22%2C%20fontsize%3D13)%0A%20%20%20%20_ax2.set_ylabel(r%22%24y%24%22%2C%20fontsize%3D13)%0A%20%20%20%20_ax2.set_title(%0A%20%20%20%20%20%20%20%20rf%22Direction%20field%20for%20%24y'%20%3D%20t%20-%20y%24%3A%20%20%20%7B_n%7D%20%C3%97%20%7B_n%7D%20%3D%20%7B_n%20*%20_n%7D%20arrows%22%2C%0A%20%20%20%20%20%20%20%20fontsize%3D13%2C%0A%20%20%20%20)%0A%20%20%20%20_ax2.grid(True%2C%20alpha%3D0.3)%0A%20%20%20%20_fig2.tight_layout()%0A%0A%20%20%20%20_T2%2C%20_Y2%2C%20_F2%20%3D%20draw_arrows(%0A%20%20%20%20%20%20%20%20_ax2%2C%20f_relax%2C%200%2C%203%2C%200%2C%203%2C%20_n%2C%20_n%2C%0A%20%20%20%20%20%20%20%20pivot%3D%22tail%22%2C%20inset%3DFalse%2C%20color%3D%22%23922b21%22%2C%20alpha%3D0.85%2C%0A%20%20%20%20%20%20%20%20width%3D0.006%20if%20_n%20%3C%3D%206%20else%200.004%2C%0A%20%20%20%20)%0A%20%20%20%20if%20_n%20%3C%3D%206%3A%0A%20%20%20%20%20%20%20%20_ax2.plot(_T2%2C%20_Y2%2C%20%22o%22%2C%20color%3D%22%23922b21%22%2C%20markersize%3D6)%0A%20%20%20%20if%20_n%20%3C%3D%205%3A%0A%20%20%20%20%20%20%20%20for%20_tp%2C%20_yp%2C%20_fp%20in%20zip(_T2.ravel()%2C%20_Y2.ravel()%2C%20_F2.ravel())%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_ax2.text(_tp%20-%200.06%2C%20_yp%20%2B%200.06%2C%20f%22%7B_fp%3Ag%7D%22%2C%20ha%3D%22right%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20va%3D%22bottom%22%2C%20fontsize%3D11%2C%20color%3D%22%231a5276%22)%0A%20%20%20%20mo.vstack(%5Bn_grid_slider%2C%20_fig2%5D)%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%20With%20enough%20arrows%20a%20pattern%20jumps%20out%3A%20the%20arrows%20are%20flat%20along%20the%20line%20%24y%20%3D%20t%24%20(where%20%24f%20%3D%200%24)%2C%20point%20down%20above%20it%20and%20up%20below%20it.%20You%20can%20almost%20*see*%20the%20solution%20curves%20already.%20A%20solution%20curve%20is%20simply%20a%20curve%20that%20is%20**tangent%20to%20the%20arrows%20everywhere**.%0A%0A%20%20%20%20How%20do%20we%20draw%20one%3F%20Start%20at%20a%20point%2C%20take%20a%20tiny%20step%20along%20the%20arrow%20there%2C%20look%20up%20the%20new%20arrow%2C%20take%20another%20tiny%20step%2C%20and%20repeat.%20Here%20is%20that%20recipe%20in%20code%3B%20we%20will%20use%20it%20to%20draw%20every%20curve%20below.%20(Keep%20it%20in%20mind%20for%20Section%202.)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np)%3A%0A%20%20%20%20def%20follow_arrows(f%2C%20t_start%2C%20y_start%2C%20t_stop%2C%20n_steps%3D2000)%3A%0A%20%20%20%20%20%20%20%20%22%22%22Trace%20a%20solution%20curve%3A%20take%20a%20tiny%20step%20along%20the%20arrow%2C%20then%20look%20again.%22%22%22%0A%20%20%20%20%20%20%20%20h%20%3D%20(t_stop%20-%20t_start)%20%2F%20n_steps%0A%20%20%20%20%20%20%20%20t_values%20%3D%20%5Bt_start%5D%0A%20%20%20%20%20%20%20%20y_values%20%3D%20%5By_start%5D%0A%20%20%20%20%20%20%20%20for%20step%20in%20range(n_steps)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20t_now%20%3D%20t_values%5B-1%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20y_now%20%3D%20y_values%5B-1%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20abs(y_now)%20%3E%20100%3A%20%20%20%20%20%20%23%20the%20curve%20has%20shot%20off%20the%20picture%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20t_values.append(t_now%20%2B%20h)%0A%20%20%20%20%20%20%20%20%20%20%20%20y_values.append(y_now%20%2B%20h%20*%20f(t_now%2C%20y_now))%0A%20%20%20%20%20%20%20%20return%20np.array(t_values)%2C%20np.array(y_values)%0A%0A%20%20%20%20return%20(follow_arrows%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%23%201.3%20A%20gallery%20of%20direction%20fields%0A%0A%20%20%20%20Here%20are%20six%20more%20ODEs%2C%20several%20straight%20from%20this%20week's%20lectures.%20The%20arrows%20are%20drawn%20exactly%20as%20above%2C%20and%20the%20curves%20come%20from%20%60follow_arrows%60%2C%20never%20from%20a%20formula.%0A%0A%20%20%20%20**Predict%20first**%2C%20before%20you%20switch%20to%20each%20one%3A%0A%0A%20%20%20%201.%20%24y'%20%3D%20t%24%3A%20will%20the%20arrows%20change%20as%20you%20move%20*up%20and%20down*%3F%20As%20you%20move%20*left%20and%20right*%3F%0A%20%20%20%202.%20%24y'%20%3D%20t%20-%20y%24%3A%20you%20already%20know%20where%20the%20arrows%20are%20flat.%20What%20do%20you%20expect%20the%20curves%20to%20do%20in%20the%20long%20run%3F%0A%20%20%20%203.%20%24y'%20%3D%20y(1%20-%20y)%24%3A%20which%20starting%20values%20%24y_0%24%20give%20a%20solution%20that%20never%20changes%20at%20all%3F%0A%20%20%20%204.%20%24y'%20%3D%204t%5E3y%5E2%24%3A%20the%20lectures%20found%20%24y%20%3D%20-1%2F(t%5E4%20-%201)%24%20for%20%24y(0)%20%3D%201%24.%20What%20happens%20at%20%24t%20%3D%201%24%3F%20Will%20the%20arrows%20%22know%22%3F%0A%20%20%20%205.%20%24y'%20%3D%20y%5E2%20-%20t%24%3A%20there%20is%20*no*%20formula%20for%20this%20one%20from%20any%20of%20the%20methods%20this%20week.%20Can%20you%20still%20say%20what%20happens%20if%20%24y_0%24%20is%20large%3F%20If%20%24y_0%24%20is%20very%20negative%3F%0A%0A%20%20%20%20Tick%20**Show%20where%20the%20slope%20is%20zero**%20to%20mark%20the%20points%20where%20%24f(t%2C%20y)%20%3D%200%24.%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%20def%20f_growth(t%2C%20y)%3A%0A%20%20%20%20%20%20%20%20return%200.5%20*%20y%0A%0A%20%20%20%20def%20f_decay(t%2C%20y)%3A%0A%20%20%20%20%20%20%20%20return%20-0.5%20*%20y%0A%0A%20%20%20%20def%20f_ramp(t%2C%20y)%3A%0A%20%20%20%20%20%20%20%20return%20t%0A%0A%20%20%20%20def%20f_logistic(t%2C%20y)%3A%0A%20%20%20%20%20%20%20%20return%20y%20*%20(1%20-%20y)%0A%0A%20%20%20%20def%20f_blowup(t%2C%20y)%3A%0A%20%20%20%20%20%20%20%20return%204%20*%20t**3%20*%20y**2%0A%0A%20%20%20%20def%20f_riccati(t%2C%20y)%3A%0A%20%20%20%20%20%20%20%20return%20y**2%20-%20t%0A%0A%20%20%20%20return%20f_blowup%2C%20f_decay%2C%20f_growth%2C%20f_logistic%2C%20f_ramp%2C%20f_riccati%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(f_blowup%2C%20f_decay%2C%20f_growth%2C%20f_logistic%2C%20f_ramp%2C%20f_riccati%2C%20np)%3A%0A%20%20%20%20_s%20%3D%20np.linspace(-10%2C%2010%2C%20400)%0A%20%20%20%20_sqrt_t%20%3D%20np.sqrt(np.linspace(0%2C%206%2C%20400))%0A%20%20%20%20gallery%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22growth%22%3A%20dict(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%3Df_growth%2C%20latex%3Dr%22y'%20%3D%200.5%5C%2Cy%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t_range%3D(0%2C%206)%2C%20y_range%3D(-1%2C%205)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y0_range%3D(-1.0%2C%203.0%2C%200.1)%2C%20y0%3D0.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20family%3D%5B-0.5%2C%200.2%2C%201.0%2C%202.0%2C%203.0%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zero_curves%3D%5B(_s%2C%200%20*%20_s)%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20notice%3Dr%22The%20arrows%20depend%20only%20on%20%24y%24%3A%20every%20**row**%20of%20arrows%20is%20identical%2C%20and%20they%20get%20steeper%20the%20higher%20you%20go%2C%20so%20growth%20speeds%20up.%20Along%20%24y%20%3D%200%24%20the%20arrows%20are%20flat%3A%20a%20solution%20that%20starts%20at%20%240%24%20stays%20there%20forever.%20Switch%20to%20*decay*%20and%20every%20arrow%20flips%3A%20growth%20becomes%20decay.%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%22decay%22%3A%20dict(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%3Df_decay%2C%20latex%3Dr%22y'%20%3D%20-0.5%5C%2Cy%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t_range%3D(0%2C%206)%2C%20y_range%3D(-1%2C%205)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y0_range%3D(-1.0%2C%205.0%2C%200.1)%2C%20y0%3D4.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20family%3D%5B-0.8%2C%201.0%2C%202.0%2C%203.0%2C%204.8%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zero_curves%3D%5B(_s%2C%200%20*%20_s)%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20notice%3Dr%22The%20same%20picture%20as%20growth%20with%20every%20arrow%20flipped.%20Now%20all%20the%20arrows%20point%20*towards*%20%24y%20%3D%200%24%2C%20so%20every%20solution%20decays%20to%20%240%24%2C%20from%20above%20or%20from%20below.%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%22ramp%22%3A%20dict(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%3Df_ramp%2C%20latex%3Dr%22y'%20%3D%20t%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t_range%3D(-3%2C%203)%2C%20y_range%3D(-5%2C%205)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y0_range%3D(-1.0%2C%205.0%2C%200.1)%2C%20y0%3D2.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20family%3D%5B-1.0%2C%200.0%2C%201.0%2C%203.0%2C%204.0%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zero_curves%3D%5B(0%20*%20_s%2C%20_s)%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20notice%3Dr%22Now%20the%20arrows%20depend%20only%20on%20%24t%24%3A%20every%20**column**%20is%20identical.%20So%20if%20you%20slide%20a%20solution%20curve%20straight%20up%20or%20down%20it%20still%20fits%20the%20arrows%2C%20and%20every%20curve%20is%20a%20shifted%20copy%20of%20one%20parabola%3A%20%24y%20%3D%20%5Ctfrac12%20t%5E2%20%2B%20C%24.%20The%20arrows%20are%20flat%20along%20%24t%20%3D%200%24%2C%20which%20is%20where%20every%20curve%20has%20its%20minimum.%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%22relax%22%3A%20dict(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%3Df_relax%2C%20latex%3Dr%22y'%20%3D%20t%20-%20y%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t_range%3D(0%2C%206)%2C%20y_range%3D(-2%2C%206)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y0_range%3D(-2.0%2C%206.0%2C%200.1)%2C%20y0%3D5.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20family%3D%5B-2.0%2C%200.0%2C%201.0%2C%203.0%2C%206.0%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zero_curves%3D%5B(_s%2C%20_s)%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20notice%3Dr%22Curves%20above%20%24y%20%3D%20t%24%20head%20down%2C%20curves%20below%20head%20up%2C%20and%20they%20cross%20the%20line%20%24y%20%3D%20t%24%20exactly%20where%20they%20are%20flat%3A%20that's%20where%20they%20turn%20around.%20In%20the%20long%20run%20they%20all%20**funnel%20onto%20the%20line%20%24y%20%3D%20t%20-%201%24**.%20That%20line%20is%20itself%20a%20solution%3A%20along%20it%20the%20slope%20is%20%24t%20-%20(t%20-%201)%20%3D%201%24%2C%20the%20slope%20of%20the%20line.%20The%20integrating%20factor%20gives%20the%20same%20story%20as%20a%20formula%3A%20%24y%20%3D%20t%20-%201%20%2B%20Ce%5E%7B-t%7D%24%2C%20and%20%24Ce%5E%7B-t%7D%20%5Cto%200%24.%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%22logistic%22%3A%20dict(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%3Df_logistic%2C%20latex%3Dr%22y'%20%3D%20y%5C%2C(1%20-%20y)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t_range%3D(0%2C%208)%2C%20y_range%3D(-0.5%2C%201.5)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y0_range%3D(-0.2%2C%201.5%2C%200.02)%2C%20y0%3D0.04%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20family%3D%5B-0.02%2C%200.02%2C%200.2%2C%200.5%2C%201.3%2C%201.5%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zero_curves%3D%5B(_s%2C%200%20*%20_s)%2C%20(_s%2C%200%20*%20_s%20%2B%201)%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20notice%3Dr%22Again%20only%20%24y%24%20matters%2C%20so%20every%20row%20is%20identical.%20The%20arrows%20are%20flat%20at%20%24y%20%3D%200%24%20and%20%24y%20%3D%201%24%3A%20start%20exactly%20there%20and%20nothing%20ever%20changes.%20These%20are%20**equilibria**.%20Start%20between%20them%20and%20you%20climb%20to%20%241%24%3B%20start%20above%20%241%24%20and%20you%20fall%20back%20to%20%241%24%3B%20start%20below%20%240%24%20and%20you%20fall%20away.%20Chapter%205%20is%20all%20about%20pictures%20like%20this%20one.%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%22blowup%22%3A%20dict(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%3Df_blowup%2C%20latex%3Dr%22y'%20%3D%204t%5E3y%5E2%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t_range%3D(0%2C%201.5)%2C%20y_range%3D(-2%2C%205)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y0_range%3D(-2.0%2C%202.0%2C%200.1)%2C%20y0%3D1.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20family%3D%5B-1.5%2C%20-0.5%2C%200.3%2C%200.5%2C%201.5%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zero_curves%3D%5B(_s%2C%200%20*%20_s)%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20notice%3Dr%22Near%20%24t%20%3D%200%24%20the%20arrows%20are%20almost%20flat%2C%20then%20they%20steepen%20ferociously.%20With%20%24y(0)%20%3D%201%24%20the%20formula%20%24y%20%3D%20-1%2F(t%5E4%20-%201)%24%20shoots%20to%20infinity%20at%20%24t%20%3D%201%24%2C%20and%20the%20traced%20curve%20does%20the%20same%3A%20the%20solution%20**blows%20up%20in%20finite%20time**.%20Try%20%24y_0%20%3D%200.5%24%3A%20it%20blows%20up%20later%2C%20at%20%24t%20%3D%202%5E%7B1%2F4%7D%20%5Capprox%201.19%24.%20Negative%20%24y_0%24%20never%20blows%20up.%20The%20formula%20and%20the%20picture%20agree%3B%20the%20picture%20just%20shows%20all%20starting%20values%20at%20once.%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%22riccati%22%3A%20dict(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%3Df_riccati%2C%20latex%3Dr%22y'%20%3D%20y%5E2%20-%20t%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t_range%3D(0%2C%206)%2C%20y_range%3D(-3%2C%203)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y0_range%3D(-3.0%2C%203.0%2C%200.05)%2C%20y0%3D0.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20family%3D%5B-2.5%2C%20-1.0%2C%200.0%2C%200.7%2C%201.0%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zero_curves%3D%5B(np.linspace(0%2C%206%2C%20400)%2C%20_sqrt_t)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(np.linspace(0%2C%206%2C%20400)%2C%20-_sqrt_t)%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20notice%3Dr%22None%20of%20this%20week's%20methods%20give%20a%20formula%20for%20this%20ODE%2C%20yet%20the%20picture%20tells%20the%20whole%20story.%20The%20arrows%20are%20flat%20on%20the%20parabola%20%24y%5E2%20%3D%20t%24.%20Curves%20that%20start%20low%20get%20trapped%20in%20a%20**funnel**%20and%20follow%20%24y%20%5Capprox%20-%5Csqrt%7Bt%7D%24%20for%20ever.%20Curves%20that%20start%20high%20escape%20and%20blow%20up.%20A%20knife-edge%20near%20%24y_0%20%5Capprox%200.73%24%20separates%20the%20two%20fates%3A%20try%20%24y_0%20%3D%200.70%24%20and%20then%20%240.75%24.%20Drawing%20this%20picture%20needed%20nothing%20but%20%24f%24%20and%20%60follow_arrows%60%2C%20which%20is%20the%20idea%20behind%20every%20numerical%20solver%20(Chapter%206).%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%7D%0A%20%20%20%20return%20(gallery%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20ode_dropdown%20%3D%20mo.ui.dropdown(%0A%20%20%20%20%20%20%20%20options%3D%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22y'%20%3D%200.5%20y%20%20%20(exponential%20growth)%22%3A%20%22growth%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22y'%20%3D%20%E2%88%920.5%20y%20%20%20(exponential%20decay)%22%3A%20%22decay%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22y'%20%3D%20t%20%20%20(direct%20integration)%22%3A%20%22ramp%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22y'%20%3D%20t%20%E2%88%92%20y%20%20%20(integrating%20factor)%22%3A%20%22relax%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22y'%20%3D%20y(1%20%E2%88%92%20y)%20%20%20(logistic%2C%20preview%20of%20Ch%205)%22%3A%20%22logistic%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22y'%20%3D%204t%C2%B3y%C2%B2%20%20%20(separable%2C%20blows%20up)%22%3A%20%22blowup%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22y'%20%3D%20y%C2%B2%20%E2%88%92%20t%20%20%20(no%20formula!)%22%3A%20%22riccati%22%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20value%3D%22y'%20%3D%20t%20%E2%88%92%20y%20%20%20(integrating%20factor)%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22ODE%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%20(ode_dropdown%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20zero_checkbox%20%3D%20mo.ui.checkbox(label%3D%22Show%20where%20the%20slope%20is%20zero%22)%0A%20%20%20%20return%20(zero_checkbox%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(gallery%2C%20ode_dropdown)%3A%0A%20%20%20%20%23%20the%20chosen%20example%2C%20plus%20slider%20settings%20for%20it%0A%20%20%20%20ode_now%20%3D%20dict(gallery%5Bode_dropdown.value%5D)%0A%20%20%20%20ode_now%5B%22t_step%22%5D%20%3D%20(ode_now%5B%22t_range%22%5D%5B1%5D%20-%20ode_now%5B%22t_range%22%5D%5B0%5D)%20%2F%2060%0A%20%20%20%20ode_now%5B%22t_trace0%22%5D%20%3D%20ode_now%5B%22t_range%22%5D%5B0%5D%20%2B%2040%20*%20ode_now%5B%22t_step%22%5D%0A%20%20%20%20return%20(ode_now%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20ode_now)%3A%0A%20%20%20%20y0_gallery_slider%20%3D%20mo.ui.slider(%0A%20%20%20%20%20%20%20%20ode_now%5B%22y0_range%22%5D%5B0%5D%2C%20ode_now%5B%22y0_range%22%5D%5B1%5D%2C%0A%20%20%20%20%20%20%20%20step%3Dode_now%5B%22y0_range%22%5D%5B2%5D%2C%20value%3Dode_now%5B%22y0%22%5D%2C%0A%20%20%20%20%20%20%20%20label%3Drf%22Start%20at%20%24y(%7Bode_now%5B't_range'%5D%5B0%5D%3Ag%7D)%24%20%3D%22%2C%0A%20%20%20%20)%0A%20%20%20%20t_trace_slider%20%3D%20mo.ui.slider(%0A%20%20%20%20%20%20%20%20ode_now%5B%22t_range%22%5D%5B0%5D%2C%20ode_now%5B%22t_range%22%5D%5B1%5D%2C%0A%20%20%20%20%20%20%20%20step%3Dode_now%5B%22t_step%22%5D%2C%20value%3Dode_now%5B%22t_trace0%22%5D%2C%0A%20%20%20%20%20%20%20%20label%3Dr%22Trace%20to%20%24t%24%20%3D%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%20t_trace_slider%2C%20y0_gallery_slider%0A%0A%0A%40app.cell%0Adef%20_(follow_arrows%2C%20ode_now)%3A%0A%20%20%20%20%23%20faded%20family%20of%20solution%20curves%20(depends%20only%20on%20which%20ODE%20is%20chosen)%0A%20%20%20%20family_curves%20%3D%20%5B%5D%0A%20%20%20%20for%20y0_member%20in%20ode_now%5B%22family%22%5D%3A%0A%20%20%20%20%20%20%20%20family_curves.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20follow_arrows(ode_now%5B%22f%22%5D%2C%20ode_now%5B%22t_range%22%5D%5B0%5D%2C%20y0_member%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ode_now%5B%22t_range%22%5D%5B1%5D)%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20return%20(family_curves%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(%0A%20%20%20%20draw_arrows%2C%0A%20%20%20%20family_curves%2C%0A%20%20%20%20follow_arrows%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20ode_dropdown%2C%0A%20%20%20%20ode_now%2C%0A%20%20%20%20plt%2C%0A%20%20%20%20t_trace_slider%2C%0A%20%20%20%20y0_gallery_slider%2C%0A%20%20%20%20zero_checkbox%2C%0A)%3A%0A%20%20%20%20_ex_g%20%3D%20ode_now%0A%20%20%20%20_f_g%20%3D%20_ex_g%5B%22f%22%5D%0A%20%20%20%20_t_lo_g%2C%20_t_hi_g%20%3D%20_ex_g%5B%22t_range%22%5D%0A%20%20%20%20_y_lo_g%2C%20_y_hi_g%20%3D%20_ex_g%5B%22y_range%22%5D%0A%20%20%20%20_y0_g%20%3D%20y0_gallery_slider.value%0A%20%20%20%20_t_end_g%20%3D%20t_trace_slider.value%0A%0A%20%20%20%20_fig3%2C%20_ax3%20%3D%20plt.subplots(figsize%3D(9%2C%205))%0A%20%20%20%20_ax3.set_xlim(_t_lo_g%2C%20_t_hi_g)%0A%20%20%20%20_ax3.set_ylim(_y_lo_g%2C%20_y_hi_g)%0A%20%20%20%20_ax3.set_xlabel(r%22%24t%24%22%2C%20fontsize%3D13)%0A%20%20%20%20_ax3.set_ylabel(r%22%24y%24%22%2C%20fontsize%3D13)%0A%20%20%20%20_ax3.set_title(rf%22Direction%20field%20for%20%24%7B_ex_g%5B'latex'%5D%7D%24%22%2C%20fontsize%3D13)%0A%20%20%20%20_ax3.grid(True%2C%20alpha%3D0.2)%0A%20%20%20%20_fig3.tight_layout()%0A%0A%20%20%20%20draw_arrows(_ax3%2C%20_f_g%2C%20_t_lo_g%2C%20_t_hi_g%2C%20_y_lo_g%2C%20_y_hi_g%2C%2025%2C%2015)%0A%0A%20%20%20%20_col_fam_g%20%3D%20%5B%22%231a5276%22%2C%20%22%231e8449%22%2C%20%22%23922b21%22%2C%20%22%237d3c98%22%2C%20%22%23b7950b%22%2C%20%22%23117a65%22%5D%0A%20%20%20%20for%20_i_fam%2C%20(_t_fam%2C%20_y_fam)%20in%20enumerate(family_curves)%3A%0A%20%20%20%20%20%20%20%20_ax3.plot(_t_fam%2C%20_y_fam%2C%20color%3D_col_fam_g%5B_i_fam%20%25%206%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20linewidth%3D1.3%2C%20alpha%3D0.5)%0A%0A%20%20%20%20if%20zero_checkbox.value%3A%0A%20%20%20%20%20%20%20%20for%20_i_z%2C%20(_t_z%2C%20_y_z)%20in%20enumerate(_ex_g%5B%22zero_curves%22%5D)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_ax3.plot(_t_z%2C%20_y_z%2C%20%22--%22%2C%20color%3D%22%23e67e22%22%2C%20linewidth%3D2.2%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3D%22slope%20%3D%200%22%20if%20_i_z%20%3D%3D%200%20else%20None)%0A%0A%20%20%20%20%23%20the%20highlighted%20solution%2C%20traced%20up%20to%20t_end%0A%20%20%20%20_t_tr%2C%20_y_tr%20%3D%20follow_arrows(_f_g%2C%20_t_lo_g%2C%20_y0_g%2C%20_t_hi_g)%0A%20%20%20%20_keep%20%3D%20_t_tr%20%3C%3D%20_t_end_g%20%2B%201e-9%0A%20%20%20%20_ax3.plot(_t_tr%5B_keep%5D%2C%20_y_tr%5B_keep%5D%2C%20color%3D%22%231a5276%22%2C%20linewidth%3D2.8%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3Drf%22%24y(%7B_t_lo_g%3Ag%7D)%20%3D%20%7B_y0_g%3Ag%7D%24%22)%0A%20%20%20%20_t_now%2C%20_y_now%20%3D%20_t_tr%5B_keep%5D%5B-1%5D%2C%20_y_tr%5B_keep%5D%5B-1%5D%0A%20%20%20%20if%20_y_lo_g%20%3C%3D%20_y_now%20%3C%3D%20_y_hi_g%3A%0A%20%20%20%20%20%20%20%20_ax3.plot(_t_now%2C%20_y_now%2C%20%22o%22%2C%20color%3D%22%23922b21%22%2C%20markersize%3D9%2C%20zorder%3D5)%0A%20%20%20%20_ax3.legend(fontsize%3D11%2C%20loc%3D%22best%22%2C%20framealpha%3D0.9)%0A%0A%20%20%20%20mo.vstack(%5B%0A%20%20%20%20%20%20%20%20ode_dropdown%2C%20y0_gallery_slider%2C%20t_trace_slider%2C%20zero_checkbox%2C%20_fig3%2C%0A%20%20%20%20%20%20%20%20mo.md(%22%2F%2F%2F%20details%20%7C%20What%20to%20notice%5Cn%5Cn%22%20%2B%20_ex_g%5B%22notice%22%5D%20%2B%20%22%5Cn%5Cn%2F%2F%2F%22)%2C%0A%20%20%20%20%5D)%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%20Notice%20in%20every%20picture%3A%20**two%20solution%20curves%20never%20cross**.%20The%20field%20gives%20exactly%20one%20slope%20at%20each%20point%2C%20so%20if%20two%20curves%20met%20they%20would%20have%20to%20leave%20that%20point%20in%20the%20same%20direction%2C%20and%20from%20then%20on%20they%20would%20be%20the%20same%20curve.%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%202.%20The%20discrete%20origin%20of%20the%20ODE%0A%0A%20%20%20%20In%20Week%201%20we%20wrote%20the%20discrete%20model%20%24N_%7Bn%2B1%7D%20%3D%20r%5C%2CN_n%24%20for%20geometric%20growth.%20Let%20%24h%24%20be%20the%20time%20step%20between%20generations%20and%20%24r%20%3D%201%20%2B%20kh%24.%20%20Then%20%5C%5BN_%7Bn%2B1%7D%20%3D%20N_n%20%2B%20h%5C%2Ck%5C%2CN_n%20%5Cqquad%5CLongrightarrow%5Cqquad%20%5Cfrac%7BN_%7Bn%2B1%7D%20-%20N_n%7D%7Bh%7D%20%3D%20k%5C%2CN_n.%5C%5D%20As%20%24h%20%5Cto%200%24%20the%20left%20side%20is%20the%20definition%20of%20%24%5Cmathrm%7Bd%7DN%2F%5Cmathrm%7Bd%7Dt%24%2C%20and%20we%20recover%20%24N'%20%3D%20kN%24.%20%20**The%20ODE%20is%20the%20continuous%20limit%20of%20the%20difference%20equation.**%0A%0A%20%20%20%20The%20update%20rule%20%24y_%7Bn%2B1%7D%20%3D%20y_n%20%2B%20h%5C%2Cf(t_n%2C%20y_n)%24%20is%20**Euler's%20method**%20%E2%80%94%20the%20simplest%20numerical%20solver.%20%20Look%20back%20at%20%60follow_arrows%60%20in%20Section%201%3A%20%60y_now%20%2B%20h%20*%20f(t_now%2C%20y_now)%60%20is%20exactly%20this%20rule%2C%20with%20a%20tiny%20%24h%24.%20%20Every%20curve%20in%20the%20gallery%20was%20drawn%20by%20Euler's%20method.%20%20Here%20we%20make%20%24h%24%20big%20and%20watch%20what%20happens%20as%20it%20shrinks.%20%20Chapter%206%20asks%20how%20to%20make%20it%20accurate%20and%20efficient.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20h_euler_slider%20%3D%20mo.ui.slider(0.05%2C%202.0%2C%20step%3D0.05%2C%20value%3D1.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3Dr%22Step%20size%20%24h%24%22)%0A%20%20%20%20return%20(h_euler_slider%2C)%0A%0A%0A%40app.cell%0Adef%20_(h_euler_slider%2C%20np)%3A%0A%20%20%20%20h_eu%20%3D%20h_euler_slider.value%0A%20%20%20%20k_eu%20%3D%200.5%0A%20%20%20%20y0_eu%20%3D%201.0%0A%20%20%20%20T_eu%20%3D%206.0%0A%0A%20%20%20%20%23%20Euler's%20method%3A%20y_%7Bn%2B1%7D%20%3D%20y_n%20%2B%20h%20*%20f(t_n%2C%20y_n)%0A%20%20%20%20t_eu%20%3D%20np.arange(0%2C%20T_eu%20%2B%20h_eu%20%2F%202%2C%20h_eu)%0A%20%20%20%20y_eu%20%3D%20np.zeros(len(t_eu))%0A%20%20%20%20y_eu%5B0%5D%20%3D%20y0_eu%0A%20%20%20%20for%20i_eu%20in%20range(1%2C%20len(t_eu))%3A%0A%20%20%20%20%20%20%20%20y_eu%5Bi_eu%5D%20%3D%20y_eu%5Bi_eu%20-%201%5D%20%2B%20h_eu%20*%20k_eu%20*%20y_eu%5Bi_eu%20-%201%5D%0A%0A%20%20%20%20err_eu%20%3D%20abs(y_eu%5B-1%5D%20-%20y0_eu%20*%20np.exp(k_eu%20*%20t_eu%5B-1%5D))%0A%20%20%20%20return%20T_eu%2C%20err_eu%2C%20k_eu%2C%20t_eu%2C%20y0_eu%2C%20y_eu%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(T_eu%2C%20err_eu%2C%20h_euler_slider%2C%20k_eu%2C%20mo%2C%20np%2C%20plt%2C%20t_eu%2C%20y0_eu%2C%20y_eu)%3A%0A%20%20%20%20_h%20%3D%20h_euler_slider.value%0A%20%20%20%20_t_ex%20%3D%20np.linspace(0%2C%20T_eu%2C%20500)%0A%20%20%20%20_y_ex%20%3D%20y0_eu%20*%20np.exp(k_eu%20*%20_t_ex)%0A%0A%20%20%20%20_fig_e%2C%20_ax_e%20%3D%20plt.subplots(figsize%3D(9%2C%204))%0A%20%20%20%20_ax_e.step(t_eu%2C%20y_eu%2C%20where%3D%22post%22%2C%20color%3D%22%231a5276%22%2C%20linewidth%3D2.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3Drf%22Euler%20staircase%20(%24h%20%3D%20%7B_h%3A.2f%7D%24)%22)%0A%20%20%20%20_ax_e.plot(_t_ex%2C%20_y_ex%2C%20%22k--%22%2C%20linewidth%3D1.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3Dr%22analytic%20%24y_0%5C%2Ce%5E%7Bkt%7D%24%22)%0A%20%20%20%20_ax_e.set_xlabel(r%22%24t%24%22%2C%20fontsize%3D13)%0A%20%20%20%20_ax_e.set_ylabel(r%22%24y(t)%24%22%2C%20fontsize%3D13)%0A%20%20%20%20_ax_e.set_title(%0A%20%20%20%20%20%20%20%20rf%22Euler%20staircase%20vs%20exact%20%20%20(error%20at%20%24t%20%3D%20%7BT_eu%3A.0f%7D%24%3A%20%7Berr_eu%3A.3f%7D)%22%2C%0A%20%20%20%20%20%20%20%20fontsize%3D13%2C%0A%20%20%20%20)%0A%20%20%20%20_ax_e.legend(fontsize%3D11)%0A%20%20%20%20_ax_e.grid(True%2C%20alpha%3D0.3)%0A%20%20%20%20_fig_e.tight_layout()%0A%20%20%20%20mo.vstack(%5Bh_euler_slider%2C%20_fig_e%5D)%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%20Drag%20%24h%24%20down%20to%20zero%3A%20the%20staircase%20converges%20to%20the%20smooth%20curve.%20This%20is%20not%20approximation%20magic%20%E2%80%94%20it%20is%20literally%20the%20definition%20of%20the%20derivative%2C%20reversed.%0A%0A%20%20%20%20Notice%20that%20halving%20%24h%24%20roughly%20halves%20the%20error.%20%20Euler's%20method%20has%20**first-order%20convergence**.%20%20Chapter%206%20introduces%20methods%20where%20halving%20%24h%24%20reduces%20the%20error%20by%20a%20factor%20of%20four%20(second-order)%20or%20sixteen%20(fourth-order).%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%20Summary%0A%0A%20%20%20%20-%20A%20first-order%20ODE%20%24y'%20%3D%20f(t%2C%20y)%24%20is%20a%20**direction%20field**%3A%20at%20each%20point%20%24(t%2C%20y)%24%20draw%20the%20arrow%20%24(1%2C%5C%20f(t%2C%20y))%24%2C%20i.e.%20run%201%2C%20rise%20%24f%24.%20%20Solution%20curves%20are%20tangent%20to%20the%20arrows%20everywhere%3B%20they%20cannot%20cross%20each%20other.%0A%20%20%20%20-%20The%20field%20shows%20the%20behaviour%20(equilibria%2C%20funnels%2C%20blow-up)%20for%20all%20starting%20values%20at%20once%2C%20even%20when%20there%20is%20no%20formula.%0A%20%20%20%20-%20The%20ODE%20is%20the%20continuous%20limit%20of%20the%20difference%20equation%20%24y_%7Bn%2B1%7D%20%3D%20y_n%20%2B%20h%5C%2Cf(t_n%2C%20y_n)%24%20as%20%24h%20%5Cto%200%24.%0A%20%20%20%20-%20That%20difference%20equation%20is%20Euler's%20method.%20%20Chapter%206%20is%20the%20story%20of%20how%20to%20do%20this%20better.%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%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
4e6cef65b31f9e9bbd3b6a75823fa49c