import%20marimo%0A%0A__generated_with%20%3D%20%220.18.4%22%0Aapp%20%3D%20marimo.App()%0A%0Awith%20app.setup%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20matplotlib%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%20matplotlib.rc(%22figure%22%2C%20figsize%3D(9%2C%205)%2C%20dpi%3D100)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20from%20chebpy%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%20The%20function%20%60%60chebfun%60%60%20behaves%20in%20essentially%20the%20same%20way%20as%20its%20MATLAB%20counterpart.%0A%20%20%20%20A%20good%20way%20to%20begin%20is%20to%20type%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%20x%20%3D%20chebfun(%22x%22%2C%20%5B0%2C%2010%5D)%0A%20%20%20%20x%0A%20%20%20%20return%20(x%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%20What's%20happened%20here%20is%20we've%20instantiated%20a%20numerical%20representation%20of%20the%20identity%20function%0A%20%20%20%20on%20the%20interval%20%60%5B0%2C10%5D%60%20and%20assigned%20this%20to%20a%20computer%20variable%20%60x%60.%20This%20particular%20representation%0A%20%20%20%20has%20length%202%2C%20meaning%20that%20it%20is%20a%20degree%20one%20polynomial%20defined%20via%20two%20degrees%20of%20freedom%0A%20%20%20%20(as%20you%20would%20expect%20of%20a%20linear%20function).%0A%0A%20%20%20%20An%20intuitive%20set%20of%20composition-like%20operations%20can%20now%20be%20performed.%20For%20instance%20here%20is%0A%20%20%20%20the%20specification%20of%20a%20function%20%60f%60%20that%20oscillates%20with%20two%20modes%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(x)%3A%0A%20%20%20%20f%20%3D%20np.sin(x)%20%2B%20np.sin(5%20*%20x)%0A%20%20%20%20f%0A%20%20%20%20return%20(f%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%20The%20zeros%20of%20f%20can%20be%20computed%20via%20%60roots%60%2C%20which%20behind%20the%20scenes%20is%20implemented%0A%20%20%20%20via%20a%20recursive%20subdivision%20algorithm%20in%20which%20a%20number%20of%20Colleague%20Matrix%20eigenvalue%0A%20%20%20%20sub-problems%20are%20solved%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(f)%3A%0A%20%20%20%20r%20%3D%20f.roots()%0A%20%20%20%20r%0A%20%20%20%20return%20(r%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%20By%20default%20ChebPy%20computations%20are%20accurate%20to%20machine%20precision%2C%20or%20approximately%20fifteen%20digits%0A%20%20%20%20in%20double-precision%20arithmetic%20(see%20also%20the%20%60UserPrefs%60%20interface%20%5Bhere%5D(.%2Fimplementation.ipynb)).%0A%0A%20%20%20%20We%20can%20verify%20this%20for%20the%20computed%20roots%20of%20%60f%60%20by%20typing%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(f%2C%20r)%3A%0A%20%20%20%20f(r)%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%20The%20function%20and%20its%20roots%20can%20be%20plotted%20together%20as%20follows%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(f%2C%20r)%3A%0A%20%20%20%20_ax%20%3D%20f.plot(linewidth%3D3)%0A%20%20%20%20_ax.plot(r%2C%20f(r)%2C%20%22.r%22%2C%20markersize%3D10)%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%20Calculus%20operations%20are%20natively%20possible%20with%20Chebfun%20objects.%0A%20%20%20%20For%20example%20here%20is%20the%20derivative%20and%20indefinite%20integral%20of%20%60f%60%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(f)%3A%0A%20%20%20%20df%20%3D%20f.diff()%0A%20%20%20%20if_%20%3D%20f.cumsum()%0A%20%20%20%20f.plot(linewidth%3D3)%0A%20%20%20%20df.plot(linewidth%3D3)%0A%20%20%20%20if_.plot(linewidth%3D3)%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%20One%20can%20verify%20analytically%20that%20the%20exact%20value%20of%20the%20definite%20integral%20here%20is%20%601.2%20-%20cos(10)%20-%200.2cos(50)%60.%0A%0A%20%20%20%20This%20matches%20our%20numerical%20integral%20(via%20Clenshaw-Curtis%20quadrature)%2C%20which%20is%20computable%20in%20ChebPy%0A%20%20%20%20via%20the%20%60sum%60%20command.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(f)%3A%0A%20%20%20%20i_ana%20%3D%201.2%20-%20np.cos(10)%20-%200.2%20*%20np.cos(50)%0A%20%20%20%20i_num%20%3D%20f.sum()%0A%20%20%20%20print(f%22analytical%20%3A%20I%3D%7Bi_ana%7D%22)%0A%20%20%20%20print(f%22%20%20%20%20ChebPy%20%3A%20I%3D%7Bi_num%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%20Discontinuities%0A%0A%20%20%20%20Chebfun%20is%20capable%20of%20handling%20certain%20classes%20of%20mathematical%20nonsmoothness.%20For%20example%2C%20here%20we%20compute%0A%20%20%20%20the%20pointwise%20maximum%20of%20two%20functions%2C%20which%20results%20in%20a%20'piecewise-smooth'%20concatenation%20of%20twelve%0A%20%20%20%20individual%20pieces%20(in%20Chebfun%20%26%20ChebPy%20terminology%20this%20is%20a%20collection%20of%20'Funs').%20The%20breakpoints%0A%20%20%20%20between%20the%20pieces%20(Funs)%20have%20been%20determined%20by%20ChebPy%20in%20the%20background%20by%20solving%20the%20corresponding%0A%20%20%20%20root-finding%20problem.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(f%2C%20x)%3A%0A%20%20%20%20g%20%3D%20x%20%2F%205%20-%201%0A%20%20%20%20h%20%3D%20f.maximum(g)%0A%20%20%20%20h%0A%20%20%20%20return%20g%2C%20h%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's%20a%20plot%20of%20both%20%60f%60%20and%20%60g%60%2C%20and%20their%20maximum%2C%20%60h%60%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(f%2C%20g%2C%20h)%3A%0A%20%20%20%20fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20f.plot(ax%3D_ax%2C%20linewidth%3D3%2C%20linestyle%3D%22--%22%2C%20label%3D%22f%22)%0A%20%20%20%20g.plot(ax%3D_ax%2C%20linewidth%3D3%2C%20linestyle%3D%22--%22%2C%20label%3D%22g%22)%0A%20%20%20%20h.plot(ax%3D_ax%2C%20linewidth%3D3%2C%20label%3D%22max(f%2C%20g)%22)%0A%20%20%20%20_ax.set_ylim(%5B-2.5%2C%202.5%5D)%0A%20%20%20%20_ax.legend()%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%20The%20function%20%60h%60%20is%20a%20further%20Chebfun%20representation%20(Chebfun%20operations%20such%20as%20this%20are%20closures)%0A%20%20%20%20and%20thus%20the%20same%20set%20of%20operations%20can%20be%20applied%20as%20normal.%20Here%20for%20instance%20is%20the%20exponential%0A%20%20%20%20of%20%60h%60%20and%20its%20integral%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(h)%3A%0A%20%20%20%20np.exp(h).plot(linewidth%3D3)%0A%20%20%20%20plt.show()%0A%20%20%20%20print(f%22integral%3A%20%7Bnp.exp(h).sum()%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%20Probability%20distributions%0A%0A%20%20%20%20Here's%20a%20further%20example%2C%20this%20time%20related%20to%20statistics.%20We%20consider%20the%20following%20Chebfun%20representation%0A%20%20%20%20of%20the%20standardised%20Gaussian%20distribution%2C%20using%20a%20sufficiently%20wide%20interval%20as%20to%20facilitate%20a%20machine-precision%0A%20%20%20%20representation.%20On%20this%20occasion%20we%20utlilise%20a%20slightly%20different%20(but%20still%20perfectly%20valid)%20approach%20to%0A%20%20%20%20construction%20whereby%20we%20supply%20the%20function%20handle%20(in%20this%20case%2C%20a%20Python%20lambda%2C%20but%20more%20generally%20any%0A%20%20%20%20object%20in%20possession%20of%20a%20%60__call__%60%20attribute)%20together%20with%20the%20interval%20of%20definition.%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%20def%20gaussian(x)%3A%0A%20%20%20%20%20%20%20%20%22%22%22Calculate%20the%20standard%20Gaussian%20probability%20density%20function.%0A%0A%20%20%20%20%20%20%20%20Args%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3A%20Input%20value%20or%20array%0A%0A%20%20%20%20%20%20%20%20Returns%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20The%20value%20of%20the%20standard%20Gaussian%20PDF%20at%20x%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20return%201%20%2F%20np.sqrt(2%20*%20np.pi)%20*%20np.exp(-0.5%20*%20x**2)%0A%0A%20%20%20%20pdf%20%3D%20chebfun(gaussian%2C%20%5B-15%2C%2015%5D)%0A%20%20%20%20_ax%20%3D%20pdf.plot(linewidth%3D3)%0A%20%20%20%20_ax.set_ylim(%5B-0.05%2C%200.45%5D)%0A%20%20%20%20_ax.set_title(%22Standard%20Gaussian%20distribution%20(mean%20%200%2C%20variance%201)%22)%0A%20%20%20%20plt.show()%0A%20%20%20%20return%20(pdf%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%20The%20integral%20of%20any%20probability%20density%20function%20should%20be%20unity%2C%0A%20%20%20%20and%20this%20is%20the%20case%20for%20our%20numerical%20approximation%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pdf)%3A%0A%20%20%20%20print(f%22integral%20%3A%20%7Bpdf.sum()%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%20Suppose%20we%20wish%20to%20generate%20quantiles%20of%20the%20distribution.%20This%20can%20be%20achieved%20as%20follows.%0A%20%20%20%20First%20we%20form%20the%20cumulative%20distribution%20function%2C%20computed%20as%20the%20indefinite%20integral%0A%20%20%20%20(%60cumsum%60)%20of%20the%20density%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pdf)%3A%0A%20%20%20%20cdf%20%3D%20pdf.cumsum()%0A%20%20%20%20_ax%20%3D%20cdf.plot(linewidth%3D3)%0A%20%20%20%20_ax.set_ylim(%5B-0.1%2C%201.1%5D)%0A%20%20%20%20plt.show()%0A%20%20%20%20return%20(cdf%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%20Then%20it%20is%20simply%20a%20case%20of%20utilising%20the%20%60roots%60%20command%20to%20determine%20the%20standardised%20score%0A%20%20%20%20(sometimes%20known%20as%20'z-score')%20corresponding%20to%20the%20quantile%20of%20interest.%20For%20example%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(cdf)%3A%0A%20%20%20%20print(%22quantile%20%20%20%20z-score%20%22)%0A%20%20%20%20print(%22--------------------%22)%0A%20%20%20%20for%20quantile%20in%20np.arange(0.1%2C%200.0%2C%20-0.01)%3A%0A%20%20%20%20%20%20%20%20roots%20%3D%20(cdf%20-%20quantile).roots()%0A%20%20%20%20%20%20%20%20print(f%22%20%20%7Bquantile%20*%20100%3A2.0f%7D%25%20%20%20%20%20%20%20%7Broots%5B0%5D%3A%2B5.3f%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%20Other%20distributional%20properties%20are%20also%20computable.%20Here's%20how%20we%20can%20compute%20the%20first%20four%0A%20%20%20%20normalised%20and%20centralised%20moments%20(Mean%2C%20Variance%2C%20Skew%2C%20Kurtosis)%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pdf)%3A%0A%20%20%20%20x_1%20%3D%20pdf.x%0A%20%20%20%20m1%20%3D%20(pdf%20*%20x_1).sum()%0A%20%20%20%20m2%20%3D%20(pdf%20*%20(x_1%20-%20m1)%20**%202).sum()%0A%20%20%20%20m3%20%3D%20(pdf%20*%20(x_1%20-%20m1)%20**%203).sum()%20%2F%20m2**1.5%0A%20%20%20%20m4%20%3D%20(pdf%20*%20(x_1%20-%20m1)%20**%204).sum()%20%2F%20m2**2%0A%20%20%20%20print(f%22%20%20%20%20mean%20%3D%20%7Bm1%3A%2B.15f%7D%22)%0A%20%20%20%20print(f%22variance%20%3D%20%7Bm2%3A%2B.15f%7D%22)%0A%20%20%20%20print(f%22%20%20%20%20skew%20%3D%20%7Bm3%3A%2B.15f%7D%22)%0A%20%20%20%20print(f%22kurtosis%20%3D%20%7Bm4%3A%2B.15f%7D%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
b6b0b7fa92a2398777c6de3849387ad1