import%20marimo%0A%0A__generated_with%20%3D%20%220.18.4%22%0Aapp%20%3D%20marimo.App()%0A%0Awith%20app.setup(hide_code%3DTrue)%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20matplotlib%20as%20mpl%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20seaborn%20as%20sns%0A%0A%20%20%20%20sns.set(font_scale%3D1.5)%0A%20%20%20%20sns.set_style(%22whitegrid%22)%0A%20%20%20%20sns.set_palette(%22deep%22)%0A%20%20%20%20mpl.rc(%22figure%22%2C%20figsize%3D(9%2C%205)%2C%20dpi%3D100)%0A%0A%0A%40app.function(hide_code%3DTrue)%0Adef%20mark_breakpoints(chebfun%2C%20ax%3DNone%2C%20**kwargs)%3A%0A%20%20%20%20%22%22%22Mark%20breakpoints%20of%20a%20Chebfun%20on%20the%20given%20axes.%22%22%22%0A%20%20%20%20ax%20%3D%20ax%20or%20plt.gca()%0A%20%20%20%20opts%20%3D%20%7B%22color%22%3A%20%22k%22%2C%20%22marker%22%3A%20%22o%22%2C%20%22markersize%22%3A%206%2C%20%22zorder%22%3A%205%2C%20%22linestyle%22%3A%20%22none%22%7D%0A%20%20%20%20opts.update(kwargs)%0A%20%20%20%20bps%20%3D%20chebfun.breakpoints%0A%20%20%20%20vals%20%3D%20chebfun(bps)%0A%20%20%20%20ax.plot(bps%2C%20vals%2C%20**opts)%0A%20%20%20%20return%20ax%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%20Convolution%20of%20Chebfuns%0A%0A%20%20%20%20ChebPy%20supports%20the%20**convolution**%20of%20two%20Chebfuns%20via%20the%20%60.conv%60%20method.%0A%0A%20%20%20%20Given%20two%20functions%20%24f%24%20on%20%24%5Ba%2C%20b%5D%24%20and%20%24g%24%20on%20%24%5Bc%2C%20d%5D%24%2C%20their%20convolution%20is%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20(f%20%5Cstar%20g)(x)%20%3D%20%5Cint%20f(t)%5C%2C%20g(x%20-%20t)%5C%2C%20dt%0A%20%20%20%20%24%24%0A%0A%20%20%20%20The%20result%20is%20a%20piecewise%20Chebfun%20on%20%24%5Ba%2Bc%2C%5C%3B%20b%2Bd%5D%24%20whose%20breakpoints%20are%20the%0A%20%20%20%20pairwise%20sums%20of%20the%20breakpoints%20of%20%24f%24%20and%20%24g%24.%20%20Both%20inputs%20may%20be%0A%20%20%20%20**piecewise**%20(an%20arbitrary%20number%20of%20smooth%20pieces).%0A%0A%20%20%20%20For%20single-piece%20inputs%20of%20equal%20width%2C%20the%20fast%20Hale%E2%80%93Townsend%20algorithm%20is%20used.%0A%20%20%20%20For%20general%20piecewise%20inputs%2C%20each%20output%20sub-interval%20is%20constructed%20via%0A%20%20%20%20Gauss%E2%80%93Legendre%20quadrature.%0A%0A%20%20%20%20%3E%20N.%20Hale%20and%20A.%20Townsend%2C%20%22An%20algorithm%20for%20the%20convolution%20of%20Legendre%20series%22%2C%0A%20%20%20%20%3E%20*SIAM%20J.%20Sci.%20Comput.*%2C%2036(3)%2C%20A1207%E2%80%93A1220%2C%202014.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20from%20chebpy.chebfun%20import%20Chebfun%0A%20%20%20%20return%20(Chebfun%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%20Example%201%3A%20The%20triangle%20function%0A%0A%20%20%20%20The%20simplest%20example%20is%20%24f%20%3D%20g%20%3D%201%24%20on%20%24%5B-1%2C%201%5D%24.%20%20The%20convolution%20is%20the%0A%20%20%20%20well-known%20**triangle%20function**%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20(1%20%5Cstar%201)(x)%20%3D%20%5Cmax(0%2C%5C%3B%202%20-%20%7Cx%7C)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20which%20is%20supported%20on%20%24%5B-2%2C%202%5D%24%20and%20peaks%20at%20%24x%20%3D%200%24%20with%20value%20%242%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Chebfun)%3A%0A%20%20%20%20ones%20%3D%20Chebfun.initconst(1.0%2C%20%5B-1%2C%201%5D)%0A%20%20%20%20triangle%20%3D%20ones.conv(ones)%0A%20%20%20%20triangle%0A%20%20%20%20return%20(triangle%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(triangle)%3A%0A%20%20%20%20triangle.plot(linewidth%3D3)%0A%20%20%20%20mark_breakpoints(triangle)%0A%20%20%20%20plt.title(%22Triangle%20function%3A%201%20%E2%98%85%201%22)%0A%20%20%20%20plt.xlabel(%22x%22)%0A%20%20%20%20plt.ylabel(%22(1%20%E2%98%85%201)(x)%22)%0A%20%20%20%20plt.show()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(triangle)%3A%0A%20%20%20%20mo.md(rf%22%22%22%0A%20%20%20%20We%20can%20verify%20the%20expected%20values%20at%20a%20few%20key%20points%3A%0A%0A%20%20%20%20-%20%24(1%20%5Cstar%201)(0)%20%3D%20%7Bfloat(triangle(0.0))%3A.6f%7D%24%20(expected%20%242%24)%0A%20%20%20%20-%20%24(1%20%5Cstar%201)(-1)%20%3D%20%7Bfloat(triangle(-1.0))%3A.6f%7D%24%20(expected%20%241%24)%0A%20%20%20%20-%20%24(1%20%5Cstar%201)(1)%20%3D%20%7Bfloat(triangle(1.0))%3A.6f%7D%24%20(expected%20%241%24)%0A%20%20%20%20-%20%24(1%20%5Cstar%201)(%5Cpm%202)%20%3D%200%24%20(ends%20of%20support)%0A%20%20%20%20%22%22%22)%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%20%23%23%20Example%202%3A%20Smooth%20convolution%20%E2%80%94%20%24%5Csin%20%5Cstar%20%5Ccos%24%0A%0A%20%20%20%20Convolution%20of%20smooth%20functions%20produces%20a%20smooth%20result.%20%20Let's%20compute%0A%20%20%20%20%24(%5Csin%20%5Cstar%20%5Ccos)(x)%24%20on%20%24%5B-1%2C%201%5D%24%20and%20plot%20the%20inputs%20alongside%20the%20output.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Chebfun)%3A%0A%20%20%20%20f_sin%20%3D%20Chebfun.initfun_adaptive(np.sin)%0A%20%20%20%20f_cos%20%3D%20Chebfun.initfun_adaptive(np.cos)%0A%20%20%20%20h_sincos%20%3D%20f_sin.conv(f_cos)%0A%20%20%20%20h_sincos%0A%20%20%20%20return%20f_cos%2C%20f_sin%2C%20h_sincos%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(f_cos%2C%20f_sin%2C%20h_sincos)%3A%0A%20%20%20%20_fig%2C%20(_ax1%2C%20_ax2)%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(16%2C%205))%0A%0A%20%20%20%20_ax1.set_title(%22Input%20functions%22)%0A%20%20%20%20f_sin.plot(ax%3D_ax1%2C%20linewidth%3D3)%0A%20%20%20%20f_cos.plot(ax%3D_ax1%2C%20linewidth%3D3)%0A%20%20%20%20mark_breakpoints(f_sin%2C%20_ax1%2C%20color%3D%22C0%22)%0A%20%20%20%20mark_breakpoints(f_cos%2C%20_ax1%2C%20color%3D%22C1%22)%0A%20%20%20%20_ax1.legend(%5B%22sin%22%2C%20%22cos%22%5D)%0A%20%20%20%20_ax1.set_xlabel(%22x%22)%0A%0A%20%20%20%20_ax2.set_title(%22sin%20%E2%98%85%20cos%22)%0A%20%20%20%20h_sincos.plot(ax%3D_ax2%2C%20linewidth%3D3%2C%20color%3D%22C2%22)%0A%20%20%20%20mark_breakpoints(h_sincos%2C%20_ax2)%0A%20%20%20%20_ax2.set_xlabel(%22x%22)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20plt.show()%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%20%23%23%20Example%203%3A%20Commutativity%0A%0A%20%20%20%20Convolution%20is%20commutative%3A%20%24f%20%5Cstar%20g%20%3D%20g%20%5Cstar%20f%24.%20%20Let's%20verify%20this%0A%20%20%20%20numerically%20by%20comparing%20%24%5Csin%20%5Cstar%20%5Ccos%24%20with%20%24%5Ccos%20%5Cstar%20%5Csin%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(f_cos%2C%20f_sin%2C%20h_sincos)%3A%0A%20%20%20%20h_cossin%20%3D%20f_cos.conv(f_sin)%0A%20%20%20%20xs%20%3D%20np.linspace(-1.8%2C%201.8%2C%20200)%0A%20%20%20%20err_commut%20%3D%20np.max(np.abs(h_sincos(xs)%20-%20h_cossin(xs)))%0A%20%20%20%20print(f%22%E2%80%96sin%E2%98%85cos%20%E2%88%92%20cos%E2%98%85sin%E2%80%96%E2%88%9E%20%3D%20%7Berr_commut%3A.2e%7D%22)%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%20%23%23%20Example%204%3A%20Self-convolution%20of%20%24e%5Ex%24%0A%0A%20%20%20%20We%20can%20also%20convolve%20a%20function%20with%20itself.%20%20Here%20is%20%24e%5Ex%20%5Cstar%20e%5Ex%24%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Chebfun)%3A%0A%20%20%20%20f_exp%20%3D%20Chebfun.initfun_adaptive(np.exp)%0A%20%20%20%20h_exp%20%3D%20f_exp.conv(f_exp)%0A%20%20%20%20h_exp%0A%20%20%20%20return%20f_exp%2C%20h_exp%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(f_exp%2C%20h_exp)%3A%0A%20%20%20%20_fig%2C%20(_ax1%2C%20_ax2)%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(16%2C%205))%0A%0A%20%20%20%20_ax1.set_title(%22exp(x)%20on%20%5B-1%2C%201%5D%22)%0A%20%20%20%20f_exp.plot(ax%3D_ax1%2C%20linewidth%3D3)%0A%20%20%20%20mark_breakpoints(f_exp%2C%20_ax1)%0A%20%20%20%20_ax1.set_xlabel(%22x%22)%0A%0A%20%20%20%20_ax2.set_title(%22exp%20%E2%98%85%20exp%22)%0A%20%20%20%20h_exp.plot(ax%3D_ax2%2C%20linewidth%3D3%2C%20color%3D%22C3%22)%0A%20%20%20%20mark_breakpoints(h_exp%2C%20_ax2)%0A%20%20%20%20_ax2.set_xlabel(%22x%22)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20plt.show()%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%20%23%23%20Example%205%3A%20Linearity%0A%0A%20%20%20%20Convolution%20is%20**linear**%3A%20%24(af%20%2B%20bg)%20%5Cstar%20h%20%3D%20a(f%20%5Cstar%20h)%20%2B%20b(g%20%5Cstar%20h)%24.%0A%0A%20%20%20%20Let's%20verify%20with%20%24a%20%3D%202%24%2C%20%24b%20%3D%20-3%24%2C%20%24f%20%3D%20%5Csin%24%2C%20%24g%20%3D%20%5Ccos%24%2C%20%24h%20%3D%20e%5Ex%24%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(Chebfun%2C%20f_cos%2C%20f_sin)%3A%0A%20%20%20%20a_coeff%2C%20b_coeff%20%3D%202.0%2C%20-3.0%0A%20%20%20%20h_rhs%20%3D%20Chebfun.initfun_adaptive(np.exp)%0A%0A%20%20%20%20lhs_fun%20%3D%20(a_coeff%20*%20f_sin%20%2B%20b_coeff%20*%20f_cos).conv(h_rhs)%0A%20%20%20%20rhs_fun%20%3D%20a_coeff%20*%20f_sin.conv(h_rhs)%20%2B%20b_coeff%20*%20f_cos.conv(h_rhs)%0A%0A%20%20%20%20xs_lin%20%3D%20np.linspace(-1.8%2C%201.8%2C%20200)%0A%20%20%20%20err_linearity%20%3D%20np.max(np.abs(lhs_fun(xs_lin)%20-%20rhs_fun(xs_lin)))%0A%20%20%20%20print(f%22%E2%80%96(2sin%20%E2%88%92%203cos)%20%E2%98%85%20exp%20%E2%88%92%20(2(sin%E2%98%85exp)%20%E2%88%92%203(cos%E2%98%85exp))%E2%80%96%E2%88%9E%20%3D%20%7Berr_linearity%3A.2e%7D%22)%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%20%23%23%20Example%206%3A%20B-spline%20construction%20by%20repeated%20convolution%0A%0A%20%20%20%20The%20%60conv%60%20method%20handles%20**piecewise%20Chebfuns**%20with%20an%20arbitrary%20number%0A%20%20%20%20of%20smooth%20pieces.%20%20A%20beautiful%20illustration%20is%20the%20construction%20of%0A%20%20%20%20**cardinal%20B-splines**%20via%20repeated%20convolution%20of%20the%20box%20function%0A%20%20%20%20%24B_0%20%3D%20%5Cmathbf%7B1%7D_%7B%5B-1%2F2%2C%5C%2C1%2F2%5D%7D%24%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20B_0%20%3D%20%5Cmathbf%7B1%7D_%7B%5B-%5Ctfrac12%2C%5Ctfrac12%5D%7D%2C%20%5Cqquad%0A%20%20%20%20B_n%20%3D%20B_0%20%5Cstar%20B_%7Bn-1%7D%2C%20%5Cquad%20n%20%3D%201%2C%202%2C%203%2C%20%5Cldots%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Each%20convolution%20increases%20smoothness%20by%20one%20order%20%E2%80%94%20%24B_0%24%20is%20%24C%5E%7B-1%7D%24%0A%20%20%20%20(discontinuous)%2C%20%24B_1%24%20is%20%24C%5E0%24%20(the%20hat%2Ftent%20function)%2C%20%24B_2%24%20is%20%24C%5E1%24%0A%20%20%20%20(quadratic%20B-spline)%2C%20and%20%24B_3%24%20is%20%24C%5E2%24%20(cubic%20B-spline).%20%20The%20support%0A%20%20%20%20grows%20by%201%20at%20each%20step.%0A%0A%20%20%20%20*Cf.*%20the%20MATLAB%20Chebfun%20example%0A%20%20%20%20%5BBSplineConv%5D(https%3A%2F%2Fwww.chebfun.org%2Fexamples%2Fapprox%2FBSplineConv.html).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(Chebfun)%3A%0A%20%20%20%20B0%20%3D%20Chebfun.initconst(1.0%2C%20%5B-0.5%2C%200.5%5D)%0A%20%20%20%20B1%20%3D%20B0.conv(B0)%0A%20%20%20%20B2%20%3D%20B0.conv(B1)%0A%20%20%20%20B3%20%3D%20B0.conv(B2)%0A%0A%20%20%20%20_splines%20%3D%20%5BB0%2C%20B1%2C%20B2%2C%20B3%5D%0A%20%20%20%20_titles%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%22%24B_0%24%3A%20box%20%20(1%20piece)%22%2C%0A%20%20%20%20%20%20%20%20%22%24B_1%24%3A%20hat%20%2F%20linear%20%20(2%20pieces)%22%2C%0A%20%20%20%20%20%20%20%20%22%24B_2%24%3A%20quadratic%20%20(3%20pieces)%22%2C%0A%20%20%20%20%20%20%20%20%22%24B_3%24%3A%20cubic%20%20(4%20pieces)%22%2C%0A%20%20%20%20%5D%0A%20%20%20%20_colors%20%3D%20%5B%22C0%22%2C%20%22C1%22%2C%20%22C2%22%2C%20%22C3%22%5D%0A%0A%20%20%20%20_fig%2C%20_axes%20%3D%20plt.subplots(2%2C%202%2C%20figsize%3D(14%2C%2010))%0A%20%20%20%20for%20_ax%2C%20_b%2C%20_t%2C%20_c%20in%20zip(_axes.flat%2C%20_splines%2C%20_titles%2C%20_colors%2C%20strict%3DFalse)%3A%0A%20%20%20%20%20%20%20%20_b.plot(ax%3D_ax%2C%20linewidth%3D3%2C%20color%3D_c)%0A%20%20%20%20%20%20%20%20mark_breakpoints(_b%2C%20_ax%2C%20color%3D_c)%0A%20%20%20%20%20%20%20%20_ax.set_title(_t)%0A%20%20%20%20%20%20%20%20_ax.set_xlabel(%22x%22)%0A%20%20%20%20%20%20%20%20_ax.set_xlim(-2.5%2C%202.5)%0A%20%20%20%20%20%20%20%20_ax.set_ylim(-0.05%2C%201.1)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20plt.show()%0A%20%20%20%20return%20B0%2C%20B1%2C%20B2%2C%20B3%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(B0%2C%20B1%2C%20B2%2C%20B3)%3A%0A%20%20%20%20mo.md(rf%22%22%22%0A%20%20%20%20%7C%20Spline%20%7C%20Pieces%20%7C%20Support%20%7C%20Continuity%20%7C%20Peak%20at%200%20%7C%0A%20%20%20%20%7C--------%7C--------%7C---------%7C------------%7C-----------%7C%0A%20%20%20%20%7C%20%24B_0%24%20%20%7C%20%7BB0.funs.size%7D%20%7C%20%24%5B-1%2F2%2C%5C%3B%201%2F2%5D%24%20%7C%20%24C%5E%7B%7B-1%7D%7D%24%20%7C%20%7Bfloat(B0(0.0))%3A.4f%7D%20%7C%0A%20%20%20%20%7C%20%24B_1%24%20%20%7C%20%7BB1.funs.size%7D%20%7C%20%24%5B-1%2C%5C%3B%201%5D%24%20%7C%20%24C%5E0%24%20%7C%20%7Bfloat(B1(0.0))%3A.4f%7D%20%7C%0A%20%20%20%20%7C%20%24B_2%24%20%20%7C%20%7BB2.funs.size%7D%20%7C%20%24%5B-3%2F2%2C%5C%3B%203%2F2%5D%24%20%7C%20%24C%5E1%24%20%7C%20%7Bfloat(B2(0.0))%3A.4f%7D%20%7C%0A%20%20%20%20%7C%20%24B_3%24%20%20%7C%20%7BB3.funs.size%7D%20%7C%20%24%5B-2%2C%202%5D%24%20%7C%20%24C%5E2%24%20%7C%20%7Bfloat(B3(0.0))%3A.4f%7D%20%7C%0A%0A%20%20%20%20Each%20B-spline%20integrates%20to%20%241%24%20and%20the%20peak%20value%20decreases%20as%20the%0A%20%20%20%20support%20widens.%20%20The%20breakpoints%20(marked%20with%20dots)%20are%20at%20the%20integers%20and%0A%20%20%20%20half-integers%20%E2%80%94%20exactly%20the%20pairwise%20sums%20of%20the%20input%20breakpoints%2C%20as%0A%20%20%20%20expected%20from%20the%20convolution%20theorem.%0A%20%20%20%20%22%22%22)%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%20%23%23%20Example%207%3A%20Boundary%20behaviour%0A%0A%20%20%20%20The%20convolution%20of%20two%20functions%20on%20%24%5B-1%2C%201%5D%24%20always%20vanishes%20at%20the%0A%20%20%20%20endpoints%20%24x%20%3D%20%5Cpm%202%24%20of%20the%20result%20domain%2C%20because%20the%20overlap%20region%0A%20%20%20%20between%20%24f%24%20and%20the%20shifted%20copy%20of%20%24g%24%20becomes%20empty.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(h_exp)%3A%0A%20%20%20%20_a%2C%20_b%20%3D%20float(h_exp.domain%5B0%5D)%2C%20float(h_exp.domain%5B-1%5D)%0A%20%20%20%20print(f%22(exp%E2%98%85exp)(%7B_a%7D)%20%3D%20%7Bfloat(h_exp(_a))%3A.2e%7D%22)%0A%20%20%20%20print(f%22(exp%E2%98%85exp)(%7B_b%7D)%20%3D%20%7Bfloat(h_exp(_b))%3A.2e%7D%22)%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%20%23%23%20Example%208%3A%20Probability%20%E2%80%94%20PDF%20of%20a%20sum%20of%20independent%20random%20variables%0A%0A%20%20%20%20A%20classic%20application%20of%20convolution%20is%20in%20**probability%20theory**.%20%20If%20%24X%24%0A%20%20%20%20and%20%24Y%24%20are%20independent%20continuous%20random%20variables%20with%20PDFs%20%24f_X%24%20and%0A%20%20%20%20%24f_Y%24%2C%20then%20the%20PDF%20of%20%24Z%20%3D%20X%20%2B%20Y%24%20is%20the%20convolution%20%24f_Z%20%3D%20f_X%20%5Cstar%20f_Y%24.%0A%0A%20%20%20%20%23%23%23%20Uniform%20%2B%20Uniform%20%E2%86%92%20Triangular%0A%0A%20%20%20%20Let%20%24X%2C%20Y%20%5Csim%20%5Cmathrm%7BUniform%7D(0%2C%201)%24%2C%20so%20%24f_X%20%3D%20f_Y%20%3D%201%24%20on%20%24%5B0%2C%201%5D%24.%0A%20%20%20%20The%20sum%20%24Z%20%3D%20X%20%2B%20Y%24%20has%20the%20**triangular%20distribution**%20on%20%24%5B0%2C%202%5D%24%2C%20peaking%0A%20%20%20%20at%20%24z%20%3D%201%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(Chebfun)%3A%0A%20%20%20%20pdf_uniform%20%3D%20Chebfun.initconst(1.0%2C%20%5B0%2C%201%5D)%0A%20%20%20%20pdf_sum_uniform%20%3D%20pdf_uniform.conv(pdf_uniform)%0A%0A%20%20%20%20pdf_sum_uniform.plot(linewidth%3D3)%0A%20%20%20%20mark_breakpoints(pdf_sum_uniform)%0A%20%20%20%20plt.title(%22PDF%20of%20%24Z%20%3D%20X%20%2B%20Y%24%2C%20%20%24X%2C%20Y%20%5C%5Csim%20%5C%5Cmathrm%7BUniform%7D(0%2C1)%24%22)%0A%20%20%20%20plt.xlabel(%22z%22)%0A%20%20%20%20plt.ylabel(%22%24f_Z(z)%24%22)%0A%20%20%20%20plt.show()%0A%20%20%20%20return%20(pdf_sum_uniform%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(pdf_sum_uniform)%3A%0A%20%20%20%20_total_area%20%3D%20pdf_sum_uniform.sum()%0A%20%20%20%20_peak%20%3D%20float(pdf_sum_uniform(1.0))%0A%20%20%20%20mo.md(rf%22%22%22%0A%20%20%20%20As%20expected%2C%20the%20result%20integrates%20to%201%20(total%20probability%20%3D%0A%20%20%20%20%24%7B_total_area%3A.15f%7D%24)%20and%20peaks%20at%20%24z%20%3D%201%24%20with%20%24f_Z(1)%20%3D%20%7B_peak%3A.6f%7D%24.%0A%20%20%20%20%22%22%22)%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%20%23%23%23%20Quadratic%20PDF%20%2B%20Quadratic%20PDF%0A%0A%20%20%20%20For%20a%20less%20trivial%20example%2C%20consider%20two%20independent%20random%20variables%20each%0A%20%20%20%20with%20PDF%20%24f(x)%20%3D%206x(1%20-%20x)%24%20on%20%24%5B0%2C%201%5D%24%20(the%20%24%5Cmathrm%7BBeta%7D(2%2C%202)%24%0A%20%20%20%20distribution%2C%20a%20symmetric%20bell%20on%20%24%5B0%2C%201%5D%24).%0A%0A%20%20%20%20The%20PDF%20of%20their%20sum%20%E2%80%94%20the%20**Irwin%E2%80%93Hall-like**%20distribution%20%E2%80%94%20is%20obtained%0A%20%20%20%20by%20convolution%20and%20lives%20on%20%24%5B0%2C%202%5D%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(Chebfun)%3A%0A%20%20%20%20pdf_beta22%20%3D%20Chebfun.initfun_adaptive(lambda%20x%3A%206.0%20*%20x%20*%20(1.0%20-%20x)%2C%20%5B0%2C%201%5D)%0A%20%20%20%20pdf_sum_beta%20%3D%20pdf_beta22.conv(pdf_beta22)%0A%0A%20%20%20%20_fig%2C%20(_ax1%2C%20_ax2)%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(16%2C%205))%0A%0A%20%20%20%20_ax1.set_title(%22%24f_X(x)%20%3D%206x(1-x)%24%20%20(Beta(2%2C2)%20PDF)%22)%0A%20%20%20%20pdf_beta22.plot(ax%3D_ax1%2C%20linewidth%3D3)%0A%20%20%20%20mark_breakpoints(pdf_beta22%2C%20_ax1)%0A%20%20%20%20_ax1.set_xlabel(%22x%22)%0A%20%20%20%20_ax1.set_ylabel(%22%24f_X(x)%24%22)%0A%0A%20%20%20%20_ax2.set_title(%22PDF%20of%20%24Z%20%3D%20X%20%2B%20Y%24%22)%0A%20%20%20%20pdf_sum_beta.plot(ax%3D_ax2%2C%20linewidth%3D3%2C%20color%3D%22C1%22)%0A%20%20%20%20mark_breakpoints(pdf_sum_beta%2C%20_ax2)%0A%20%20%20%20_ax2.set_xlabel(%22z%22)%0A%20%20%20%20_ax2.set_ylabel(%22%24f_Z(z)%24%22)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20plt.show()%0A%20%20%20%20return%20(pdf_sum_beta%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(pdf_sum_beta)%3A%0A%20%20%20%20_area%20%3D%20pdf_sum_beta.sum()%0A%20%20%20%20mo.md(rf%22%22%22%0A%20%20%20%20Again%20the%20total%20area%20is%20%24%7B_area%3A.15f%7D%20%5Capprox%201%24%2C%20confirming%20a%20valid%20PDF.%0A%20%20%20%20Note%20how%20convolving%20two%20bell-shaped%20distributions%20produces%20a%20smoother%2C%20more%0A%20%20%20%20concentrated%20bell%20%E2%80%94%20an%20illustration%20of%20the%20**Central%20Limit%20Theorem**%20in%20action.%0A%20%20%20%20%22%22%22)%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%20%23%23%20Example%209%3A%20The%20convolution%20theorem%20and%20the%20sinc%20function%0A%0A%20%20%20%20The%20**convolution%20theorem**%20states%20that%20convolution%20in%20the%20time%20domain%0A%20%20%20%20corresponds%20to%20multiplication%20in%20the%20frequency%20domain%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cwidehat%7Bf%20%5Cstar%20g%7D(%5Comega)%20%3D%20%5Chat%7Bf%7D(%5Comega)%5C%2C%5Chat%7Bg%7D(%5Comega)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20where%20%24%5Chat%7Bf%7D(%5Comega)%20%3D%20%5Cint%20f(t)%5C%2C%20e%5E%7B-2%5Cpi%20i%20%5Comega%20t%7D%5C%2Cdt%24%20is%20the%0A%20%20%20%20Fourier%20transform.%0A%0A%20%20%20%20A%20classic%20illustration%20uses%20the%20**box%20function**%0A%20%20%20%20%24B_0%20%3D%20%5Cmathbf%7B1%7D_%7B%5B-1%2F2%2C%5C%2C1%2F2%5D%7D%24%2C%20whose%20Fourier%20transform%20is%20the%0A%20%20%20%20**sinc%20function**%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cwidehat%7BB_0%7D(%5Comega)%20%3D%20%5Coperatorname%7Bsinc%7D(%5Comega)%0A%20%20%20%20%20%20%20%20%3D%20%5Cfrac%7B%5Csin(%5Cpi%5Comega)%7D%7B%5Cpi%5Comega%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Since%20%24B_0%20%5Cstar%20B_0%20%3D%20B_1%24%20(the%20triangle%20%2F%20hat%20function)%2C%20the%0A%20%20%20%20convolution%20theorem%20tells%20us%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cwidehat%7BB_1%7D(%5Comega)%20%3D%20%5Coperatorname%7Bsinc%7D%5E2(%5Comega)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Let's%20verify%20this%20numerically%20with%20ChebPy.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(Chebfun)%3A%0A%20%20%20%20%23%20Time%20domain%3A%20box%20and%20triangle%20(from%20B-spline%20construction)%0A%20%20%20%20box%20%3D%20Chebfun.initconst(1.0%2C%20%5B-0.5%2C%200.5%5D)%0A%20%20%20%20tri_conv%20%3D%20box.conv(box)%0A%0A%20%20%20%20%23%20Frequency%20domain%3A%20sinc%20and%20sinc%C2%B2%20as%20Chebfuns%20of%20%CF%89%0A%20%20%20%20_wmax%20%3D%206.0%0A%20%20%20%20ft_box%20%3D%20Chebfun.initfun_adaptive(lambda%20w%3A%20np.sinc(w)%2C%20%5B-_wmax%2C%20_wmax%5D)%0A%20%20%20%20ft_tri%20%3D%20Chebfun.initfun_adaptive(lambda%20w%3A%20np.sinc(w)%20**%202%2C%20%5B-_wmax%2C%20_wmax%5D)%0A%0A%20%20%20%20_fig%2C%20_axes%20%3D%20plt.subplots(2%2C%202%2C%20figsize%3D(16%2C%2010))%0A%0A%20%20%20%20%23%20Top-left%3A%20time%20domain%20%E2%80%94%20box%0A%20%20%20%20_axes%5B0%2C%200%5D.set_title(%22%24B_0(t)%24%20%E2%80%94%20box%20function%22)%0A%20%20%20%20box.plot(ax%3D_axes%5B0%2C%200%5D%2C%20linewidth%3D3%2C%20color%3D%22C0%22)%0A%20%20%20%20mark_breakpoints(box%2C%20_axes%5B0%2C%200%5D%2C%20color%3D%22C0%22)%0A%20%20%20%20_axes%5B0%2C%200%5D.set_xlabel(%22%24t%24%22)%0A%20%20%20%20_axes%5B0%2C%200%5D.set_xlim(-1.5%2C%201.5)%0A%20%20%20%20_axes%5B0%2C%200%5D.set_ylim(-0.1%2C%201.2)%0A%0A%20%20%20%20%23%20Top-right%3A%20frequency%20domain%20%E2%80%94%20sinc%0A%20%20%20%20_axes%5B0%2C%201%5D.set_title(r%22%24%5Cwidehat%7BB_0%7D(%5Comega)%20%3D%20%5Cmathrm%7Bsinc%7D(%5Comega)%24%22)%0A%20%20%20%20ft_box.plot(ax%3D_axes%5B0%2C%201%5D%2C%20linewidth%3D3%2C%20color%3D%22C0%22)%0A%20%20%20%20mark_breakpoints(ft_box%2C%20_axes%5B0%2C%201%5D%2C%20color%3D%22C0%22)%0A%20%20%20%20_axes%5B0%2C%201%5D.set_xlabel(r%22%24%5Comega%24%22)%0A%0A%20%20%20%20%23%20Bottom-left%3A%20time%20domain%20%E2%80%94%20triangle%20(B0%20%E2%98%85%20B0)%0A%20%20%20%20_axes%5B1%2C%200%5D.set_title(%22%24B_1(t)%20%3D%20B_0%20%5C%5Cstar%20B_0%24%20%E2%80%94%20triangle%22)%0A%20%20%20%20tri_conv.plot(ax%3D_axes%5B1%2C%200%5D%2C%20linewidth%3D3%2C%20color%3D%22C1%22)%0A%20%20%20%20mark_breakpoints(tri_conv%2C%20_axes%5B1%2C%200%5D%2C%20color%3D%22C1%22)%0A%20%20%20%20_axes%5B1%2C%200%5D.set_xlabel(%22%24t%24%22)%0A%20%20%20%20_axes%5B1%2C%200%5D.set_xlim(-1.5%2C%201.5)%0A%20%20%20%20_axes%5B1%2C%200%5D.set_ylim(-0.1%2C%201.2)%0A%0A%20%20%20%20%23%20Bottom-right%3A%20frequency%20domain%20%E2%80%94%20sinc%C2%B2%0A%20%20%20%20_axes%5B1%2C%201%5D.set_title(r%22%24%5Cwidehat%7BB_1%7D(%5Comega)%20%3D%20%5Cmathrm%7Bsinc%7D%5E2(%5Comega)%24%22)%0A%20%20%20%20ft_tri.plot(ax%3D_axes%5B1%2C%201%5D%2C%20linewidth%3D3%2C%20color%3D%22C1%22)%0A%20%20%20%20mark_breakpoints(ft_tri%2C%20_axes%5B1%2C%201%5D%2C%20color%3D%22C1%22)%0A%20%20%20%20_axes%5B1%2C%201%5D.set_xlabel(r%22%24%5Comega%24%22)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20plt.show()%0A%20%20%20%20return%20box%2C%20ft_box%2C%20tri_conv%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(Chebfun%2C%20box%2C%20ft_box%2C%20tri_conv)%3A%0A%20%20%20%20%23%20Numerically%20verify%20the%20convolution%20theorem%3A%0A%20%20%20%20%23%20Compute%20FT%20of%20box%20and%20triangle%20via%20chebpy%20integration%2C%20compare%20with%20sinc%20%2F%20sinc%C2%B2%0A%20%20%20%20_ws%20%3D%20np.linspace(0.5%2C%205.5%2C%2050)%0A%20%20%20%20_ft_box_num%20%3D%20np.array(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20float((box%20*%20Chebfun.initfun_adaptive(lambda%20t%2C%20w%3Dw%3A%20np.cos(2%20*%20np.pi%20*%20w%20*%20t)%2C%20%5B-0.5%2C%200.5%5D)).sum())%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20w%20in%20_ws%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20_ft_tri_num%20%3D%20np.array(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20float((tri_conv%20*%20Chebfun.initfun_adaptive(lambda%20t%2C%20w%3Dw%3A%20np.cos(2%20*%20np.pi%20*%20w%20*%20t)%2C%20%5B-1.0%2C%201.0%5D)).sum())%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20w%20in%20_ws%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%0A%20%20%20%20_err_box%20%3D%20np.max(np.abs(_ft_box_num%20-%20ft_box(_ws)))%0A%20%20%20%20_err_tri%20%3D%20np.max(np.abs(_ft_tri_num%20-%20np.sinc(_ws)%20**%202))%0A%20%20%20%20_err_thm%20%3D%20np.max(np.abs(_ft_tri_num%20-%20_ft_box_num**2))%0A%0A%20%20%20%20mo.md(rf%22%22%22%0A%20%20%20%20**Numerical%20verification**%20(computed%20via%20ChebPy%20integration)%3A%0A%0A%20%20%20%20%7C%20Check%20%7C%20%24%5C%7C%5C%7C%5Ccdot%5C%7C%5C%7C_%5Cinfty%24%20error%20%7C%0A%20%20%20%20%7C-------%7C------------------------------%7C%0A%20%20%20%20%7C%20%24%5Cwidehat%7B%7BB_0%7D%7D(%5Comega)%24%20vs%20%24%5Cmathrm%7B%7Bsinc%7D%7D(%5Comega)%24%20%7C%20%7B_err_box%3A.2e%7D%20%7C%0A%20%20%20%20%7C%20%24%5Cwidehat%7B%7BB_1%7D%7D(%5Comega)%24%20vs%20%24%5Cmathrm%7B%7Bsinc%7D%7D%5E2(%5Comega)%24%20%7C%20%7B_err_tri%3A.2e%7D%20%7C%0A%20%20%20%20%7C%20%24%5Cwidehat%7B%7BB_0%20%5Cstar%20B_0%7D%7D%24%20vs%20%24%5Cwidehat%7B%7BB_0%7D%7D%5E2%24%20(convolution%20theorem)%20%7C%20%7B_err_thm%3A.2e%7D%20%7C%0A%0A%20%20%20%20All%20errors%20are%20at%20machine%20precision%2C%20confirming%20the%20convolution%20theorem.%0A%20%20%20%20%22%22%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
8691bbb1da4cf1c2bf187de3242feb0d