import%20marimo%0A%0A__generated_with%20%3D%20%220.18.1%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%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%20Vectorised%20Finite%20Differences%20and%20Neighbour%20Operations%3A%201D%20and%202D%0A%20%20%20%20Covers%20padding%2C%20central%20differences%2C%20edge%20handling%2C%20and%20compact%20generator-style%20loops.%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%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20return%20mo%2C%20np%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%20random%20matrix%20with%20integers%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%20%23%20create%20a%20matrix%20and%20fill%20it%20with%20random%20integers%20from%201%20to%209%0A%20%20%20%20rows%2C%20cols%20%3D%207%2C%208%0A%20%20%20%20arr%20%3D%20np.random.randint(1%2C%2010%2C%20size%3D(rows%2C%20cols))%0A%20%20%20%20print(arr)%0A%20%20%20%20return%20arr%2C%20cols%2C%20rows%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%20padding%20a%20matrix%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(arr%2C%20np)%3A%0A%20%20%20%20%23%20add%20a%20padding%20layer%20of%200's%20around%20the%20matrix%0A%20%20%20%20padd_arr%20%3D%20np.pad(arr%2C%201%2C%20mode%3D%22constant%22%2C%20constant_values%3D0)%0A%20%20%20%20%23padd2_arr%20%3D%20np.pad(arr%2C%202%2C%20mode%3D%22constant%22%2C%20constant_values%3D0)%20%23%20for%202%20layers%20of%20padding%0A%20%20%20%20print(padd_arr)%0A%20%20%20%20return%20(padd_arr%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%20adding%20neighbouring%20values%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%20%23%20How%20to%20add%20the%208%20neighbouring%20digits%3A%0A%20%20%20%20%23%20define%20a%20kernel%20of%20neighbours%0A%20%20%20%20kernel%20%3D%20np.array(%5B%20%23%20a%200%20in%20one%20of%20them%20would%20mean%20excluding%20that%20neighbour%0A%20%20%20%20%20%20%20%20%5B1%2C%201%2C%201%5D%2C%0A%20%20%20%20%20%20%20%20%5B1%2C%201%2C%201%5D%2C%0A%20%20%20%20%20%20%20%20%5B1%2C%201%2C%201%5D%0A%20%20%20%20%5D)%0A%20%20%20%20return%20(kernel%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%20summing%20with%20compact%20generator-style%20loops%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(cols%2C%20kernel%2C%20padd_arr%2C%20rows)%3A%0A%20%20%20%20%23%20perform%20the%20sum%0A%20%20%20%20total%20%3D%20sum(%0A%20%20%20%20%20%20%20%20%23%20pad_arr%5Bi%3Ai%20%2B%20rows%2C%20j%3Aj%20%2B%20cols%5D%20selects%20a%20subarray%20of%20the%20padded%20array%0A%20%20%20%20%20%20%20%20%23%20*%20kernel%5Bi%2Cj%5D%20multiplie%20the%20subarray%20by%20the%20weight%20from%20the%20kernel%0A%20%20%20%20%20%20%20%20padd_arr%5Bi%3Ai%20%2B%20rows%2C%20j%3Aj%20%2B%20cols%5D%20*%20kernel%5Bi%2C%20j%5D%0A%20%20%20%20%20%20%20%20for%20i%20in%20range(3)%20%23%20loop%20over%20rows%0A%20%20%20%20%20%20%20%20for%20j%20in%20range(3)%20%23%20loop%20over%20cols%0A%20%20%20%20)%0A%20%20%20%20print(total)%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%20first%20derivatives%0A%20%20%20%20%23%23%23%201D%2C%20Neumann%20boundary%20conditions%20(zero%20derivative%20at%20edges)%0A%0A%20%20%20%20-%20boundary%20value%20is%20copied%20from%20the%20nearest%20interior%20point%0A%20%20%20%20-%20this%20effectively%20enforces%20that%20the%20derivative%20at%20the%20boundary%20is%20zero%2C%20because%20for%20a%20central%20difference%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%20%23%20first%20derivaties%20in%201D%0A%20%20%20%20N%20%3D%2012%0A%20%20%20%20vec%20%3D%20np.random.randint(1%2C%2010%2C%20size%3DN)%0A%20%20%20%20print(%22vec%20%3D%20%22%2C%20vec)%20%23%20length%20N%0A%20%20%20%20dx%20%3D%201%0A%20%20%20%20pad_vec%20%3D%20np.pad(vec%2C%201%2C%20mode%3D'edge')%20%20%23%20length%20N%2B2%0A%20%20%20%20%23%20mode%3D'edge'%20means%20the%20padding%20copies%20the%20values%20at%20the%20edge%20of%20the%20original%20array.%0A%20%20%20%20print(%22pad_vec%20%3D%20%22%2C%20pad_vec)%0A%20%20%20%20%23%20first%20derivative%3A%20dfdx_vec%20has%20length%20N%2C%20not%20N%2B2%0A%20%20%20%20%23%20both%20pad_vec%5B2%3A%5D%20and%20pad_vec%5B%3A-2%5D%20have%20length%20N%0A%20%20%20%20dfdx_vec%20%3D%20(pad_vec%5B2%3A%5D%20-%20pad_vec%5B%3A-2%5D)%20%2F%20(2*dx)%20%23%20length%20N%0A%20%20%20%20print(%22pad_vec%5B2%3A%5D%20%3D%20%22%2C%20pad_vec%5B2%3A%5D)%0A%20%20%20%20print(%22pad_vec%5B%3A-2%5D%20%3D%20%22%2C%20pad_vec%5B%3A-2%5D)%0A%20%20%20%20print(%22dfdx_vec%20%3D%20%22%2C%20dfdx_vec)%0A%20%20%20%20return%20dfdx_vec%2C%20dx%2C%20vec%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%20Dirichlet%20(fixed%20value%20at%20edges)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dfdx_vec%2C%20dx%2C%20np%2C%20vec)%3A%0A%20%20%20%20a%2C%20b%20%3D%201.0%2C%203.0%20%20%23%20example%20fixed%20values%0A%20%20%20%20pad_vec_dir%20%3D%20np.pad(vec%2C%201%2C%20mode%3D'constant'%2C%20constant_values%3D(a%2C%20b))%0A%20%20%20%20dfdx_vec_dir%20%3D%20(pad_vec_dir%5B2%3A%5D%20-%20pad_vec_dir%5B%3A-2%5D)%20%2F%20(2*dx)%20%23%20central%20difference%20for%20interior%0A%20%20%20%20dfdx_vec%5B0%5D%20%3D%20(vec%5B1%5D%20-%20a)%20%2F%20dx%20%20%20%20%20%20%23%20forward%20difference%20at%20left%0A%20%20%20%20dfdx_vec%5B-1%5D%20%3D%20(b%20-%20vec%5B-2%5D)%20%2F%20dx%20%20%20%20%23%20backward%20difference%20at%20right%0A%20%20%20%20print(%22vec%20%3D%20%22%2C%20vec)%0A%20%20%20%20print(%22pad_vec_dir%20%3D%20%22%2C%20pad_vec_dir)%0A%20%20%20%20print(%22dfdx_vec_dir%20%3D%20%22%2C%20dfdx_vec_dir)%0A%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%20Periodic%20boundary%20conditions%20(wrap-around)%0A%20%20%20%20-%20for%20periodic%20boundary%20conditions%20(PBC)%2C%20the%20padded%20array%20is%20just%20a%20copy%20of%20the%20wrap-around%20values%20at%20the%20time%20you%20pad%20it.%0A%20%20%20%20-%20it%20does%20not%20automatically%20update%20if%20the%20original%20array%20changes.%0A%20%20%20%20-%20centred%20differences%20work%2C%20unline%20in%20Dirichlet%0A%0A%20%20%20%20For%20loops%3A%0A%20%20%20%20-%20Update%20vec%20(or%20field)%20based%20on%20your%20finite-difference%20formula%0A%20%20%20%20-%20Recompute%20pad_vec%20for%20the%20current%20vec%20before%20computing%20derivatives.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dx%2C%20np%2C%20vec)%3A%0A%20%20%20%20pad_vec_pbc%20%3D%20np.pad(vec%2C%201%2C%20mode%3D'wrap')%20%20%23%20length%20N%2B2%0A%20%20%20%20dfdx_vec_pbc%20%3D%20(pad_vec_pbc%5B2%3A%5D%20-%20pad_vec_pbc%5B%3A-2%5D)%20%2F%20(2*dx)%0A%20%20%20%20print(%22vec%20%3D%20%22%2C%20vec)%0A%20%20%20%20print(%22pad_vec_pbc%20%3D%20%22%2C%20pad_vec_pbc)%0A%20%20%20%20print(%22dfdx_vec_pbc%20%3D%20%22%2C%20dfdx_vec_pbc)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%202D%20(Neumann)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(arr%2C%20dx%2C%20np)%3A%0A%20%20%20%20%23%20first%20x%20derivatives%20in%202D%20--%3E%20trivial%20after%20the%201D%20case%0A%20%20%20%20%23%20pad%20to%20safely%20access%20neighbours%0A%20%20%20%20pad_arr%20%3D%20np.pad(arr%2C%201%2C%20mode%3D'edge')%0A%20%20%20%20print(%22pad_arr%20%3D%20%5Cn%22%2C%20pad_arr)%0A%20%20%20%20%23%20centred%20finite%20difference%0A%20%20%20%20%23%20pad_arr%5B2%3A%2C%201%3A-1%5D%20%E2%86%92%20take%20rows%202..end%2C%20cols%201..-1%20(-1%20not%20included)%0A%20%20%20%20%23%20pad_arr%5B%3A-2%2C%201%3A-1%5D%20%E2%86%92%20take%20rows%200..-3%2C%20cols%201..-1%20(-1%20not%20included)%0A%20%20%20%20dfdx%20%3D%20(pad_arr%5B2%3A%2C1%3A-1%5D%20-%20pad_arr%5B%3A-2%2C1%3A-1%5D)%20%2F%20(2*dx)%0A%20%20%20%20print(%22x-derivative%20%3D%20%5Cn%22%2C%20dfdx)%0A%20%20%20%20return%20(pad_arr%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%202D%2C%20PBC%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(arr%2C%20dx%2C%20np)%3A%0A%20%20%20%20pad_arr_pbc%20%3D%20np.pad(arr%2C%201%2C%20mode%3D'wrap')%0A%20%20%20%20dfdx_pbc%20%3D%20(pad_arr_pbc%5B2%3A%2C%201%3A-1%5D%20-%20pad_arr_pbc%5B%3A-2%2C%201%3A-1%5D)%20%2F%20(2*dx)%0A%20%20%20%20dfdy_pbc%20%3D%20(pad_arr_pbc%5B1%3A-1%2C%202%3A%5D%20-%20pad_arr_pbc%5B1%3A-1%2C%20%3A-2%5D)%20%2F%20(2*dx)%0A%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Laplacian%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dx%2C%20pad_arr)%3A%0A%20%20%20%20laplacian%20%3D%20(%0A%20%20%20%20%20%20%20%20pad_arr%5B2%3A%2C1%3A-1%5D%20%2B%20pad_arr%5B%3A-2%2C1%3A-1%5D%20%2B%20%20%20%23%20top%20%2B%20bottom%0A%20%20%20%20%20%20%20%20pad_arr%5B1%3A-1%2C2%3A%5D%20%2B%20pad_arr%5B1%3A-1%2C%3A-2%5D%20-%20%20%20%23%20right%20%2B%20left%0A%20%20%20%20%20%20%20%204%20*%20pad_arr%5B1%3A-1%2C1%3A-1%5D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20center%0A%20%20%20%20)%20%2F%20dx**2%0A%20%20%20%20print(laplacian)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%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
2e8548006d2f99ed8740e938433410f2