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%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%20from%20chebpy%20import%20equifun%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.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Equispaced%20Sample%20Data%0A%0A%20%20%20%20Most%20of%20ChebPy's%20constructors%20expect%20a%20*callable*%20%E2%80%94%20a%20function%20that%20can%20be%0A%20%20%20%20evaluated%20at%20Chebyshev%20points.%20%20Sometimes%2C%20though%2C%20all%20you%20have%20is%20a%20vector%0A%20%20%20%20of%20values%20sampled%20on%20an%20**equispaced**%20grid%20that%20includes%20both%20endpoints%20of%0A%20%20%20%20the%20interval%20(measured%20data%2C%20the%20output%20of%20another%20simulation%2C%20a%20lookup%0A%20%20%20%20table).%20%20Interpolating%20equispaced%20data%20with%20a%20single%20high-degree%20polynomial%0A%20%20%20%20is%20famously%20unstable%3A%20it%20triggers%20the%20**Runge%20phenomenon**%2C%20and%20no%20fast%2C%0A%20%20%20%20stable%20scheme%20can%20do%20better%20in%20general%20(Platte%2C%20Trefethen%20%26%20Kuijlaars%2C%0A%20%20%20%202011).%0A%0A%20%20%20%20ChebPy's%20%5B%60equifun%60%5D(..%2Fapi.md)%20sidesteps%20this%20by%20first%20fitting%20a%0A%20%20%20%20**Floater%E2%80%93Hormann%20barycentric%20rational%20interpolant**%20through%20the%20samples%20and%0A%20%20%20%20then%20adaptively%20representing%20that%20smooth%20interpolant%20as%20an%20ordinary%20Chebfun.%0A%20%20%20%20The%20result%20behaves%20like%20any%20other%20Chebfun%20%E2%80%94%20you%20can%20differentiate%2C%0A%20%20%20%20integrate%2C%20find%20roots%2C%20and%20plot%20it.%0A%0A%20%20%20%20This%20mirrors%20MATLAB%20Chebfun's%20%60chebfun(values%2C%20'equi')%60%20constructor%2C%20whose%0A%20%20%20%20%60funqui%60%20routine%20implements%20the%20same%20Floater%E2%80%93Hormann%20fit%20and%20adaptive%0A%20%20%20%20degree%20selection.%20%20ChebPy%20keeps%20it%20as%20a%20standalone%20%60equifun%60%20factory%20(in%20the%0A%20%20%20%20spirit%20of%20%60trigfun%60)%20rather%20than%20overloading%20%60chebfun%60.%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%20A%20first%20example%0A%0A%20%20%20%20Given%20values%20of%20a%20smooth%20function%20on%20an%20equispaced%20grid%2C%20%60equifun%60%0A%20%20%20%20reconstructs%20a%20Chebfun%20that%20interpolates%20the%20samples.%20%20The%20domain%20defaults%0A%20%20%20%20to%20the%20preference%20domain%20%24%5B-1%2C%201%5D%24%3B%20pass%20a%20two-element%20%60%5Ba%2C%20b%5D%60%20to%20place%20the%0A%20%20%20%20grid%20on%20any%20bounded%20interval.%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%20nodes%20%3D%20np.linspace(0.0%2C%202.0%20*%20np.pi%2C%2017)%0A%20%20%20%20values%20%3D%20np.sin(nodes)%20%2B%200.25%20*%20np.cos(3.0%20*%20nodes)%0A%20%20%20%20f%20%3D%20equifun(values%2C%20%5B0.0%2C%202.0%20*%20np.pi%5D)%0A%20%20%20%20print(f)%0A%20%20%20%20print(f%22len(f)%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%7Blen(f)%7D%22)%0A%20%20%20%20print(f%22max%20%7Cf(node)%20-%20y%7C%20%3D%20%7Bfloat(np.max(np.abs(f(nodes)%20-%20values)))%3A.2e%7D%22)%0A%20%20%20%20return%20f%2C%20nodes%2C%20values%0A%0A%0A%40app.cell%0Adef%20_(f%2C%20nodes%2C%20values)%3A%0A%20%20%20%20_xx%20%3D%20np.linspace(0.0%2C%202.0%20*%20np.pi%2C%20500)%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20_ax.plot(_xx%2C%20f(_xx)%2C%20color%3D%22C0%22%2C%20linewidth%3D2%2C%20label%3D%22equifun%22)%0A%20%20%20%20_ax.plot(nodes%2C%20values%2C%20%22o%22%2C%20color%3D%22C1%22%2C%20label%3D%22samples%22)%0A%20%20%20%20_ax.set_xlabel(%22x%22)%0A%20%20%20%20_ax.set_title(%22Chebfun%20through%20equispaced%20samples%22)%0A%20%20%20%20_ax.legend()%0A%20%20%20%20_fig%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%20The%20Runge%20phenomenon%0A%0A%20%20%20%20The%20classic%20cautionary%20tale%20is%20Runge's%20function%0A%20%20%20%20%24r(x)%20%3D%201%2F(1%20%2B%2025x%5E2)%24%20on%20%24%5B-1%2C%201%5D%24.%20%20Interpolating%20it%20by%20a%20single%0A%20%20%20%20polynomial%20through%20equispaced%20nodes%20diverges%20wildly%20near%20the%20endpoints%20as%0A%20%20%20%20the%20node%20count%20grows.%20%20The%20Floater%E2%80%93Hormann%20fit%20used%20by%20%60equifun%60%20stays%0A%20%20%20%20bounded%20and%20converges.%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%20runge(x)%3A%0A%20%20%20%20%20%20%20%20return%201.0%20%2F%20(1.0%20%2B%2025.0%20*%20x**2)%0A%0A%20%20%20%20_nodes%20%3D%20np.linspace(-1.0%2C%201.0%2C%2025)%0A%20%20%20%20fh%20%3D%20equifun(runge(_nodes))%0A%0A%20%20%20%20_coeffs%20%3D%20np.polyfit(_nodes%2C%20runge(_nodes)%2C%20_nodes.size%20-%201)%0A%20%20%20%20_xx%20%3D%20np.linspace(-1.0%2C%201.0%2C%202001)%0A%20%20%20%20_err_fh%20%3D%20float(np.max(np.abs(fh(_xx)%20-%20runge(_xx))))%0A%20%20%20%20_err_poly%20%3D%20float(np.max(np.abs(np.polyval(_coeffs%2C%20_xx)%20-%20runge(_xx))))%0A%20%20%20%20print(f%22equifun%20(Floater-Hormann)%20%20max%20%7Cerror%7C%20%3D%20%7B_err_fh%3A.2e%7D%22)%0A%20%20%20%20print(f%22degree-24%20polynomial%20%20%20%20%20%20%20max%20%7Cerror%7C%20%3D%20%7B_err_poly%3A.2e%7D%22)%0A%20%20%20%20return%20fh%2C%20runge%0A%0A%0A%40app.cell%0Adef%20_(fh%2C%20runge)%3A%0A%20%20%20%20_nodes%20%3D%20np.linspace(-1.0%2C%201.0%2C%2025)%0A%20%20%20%20_coeffs%20%3D%20np.polyfit(_nodes%2C%20runge(_nodes)%2C%20_nodes.size%20-%201)%0A%20%20%20%20_xx%20%3D%20np.linspace(-1.0%2C%201.0%2C%202001)%0A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20_ax.plot(_xx%2C%20runge(_xx)%2C%20color%3D%22black%22%2C%20linewidth%3D3.0%2C%20label%3D%22%24r(x)%20%3D%201%2F(1%2B25x%5E2)%24%22)%0A%20%20%20%20_ax.plot(_xx%2C%20fh(_xx)%2C%20color%3D%22%23D55E00%22%2C%20linestyle%3D%22--%22%2C%20linewidth%3D1.5%2C%20label%3D%22equifun%22)%0A%20%20%20%20_ax.plot(_xx%2C%20np.polyval(_coeffs%2C%20_xx)%2C%20color%3D%22%230072B2%22%2C%20linewidth%3D1.0%2C%20alpha%3D0.9%2C%20label%3D%22degree-24%20polynomial%22)%0A%20%20%20%20_ax.plot(%0A%20%20%20%20%20%20%20%20_nodes%2C%0A%20%20%20%20%20%20%20%20runge(_nodes)%2C%0A%20%20%20%20%20%20%20%20linestyle%3D%22none%22%2C%0A%20%20%20%20%20%20%20%20marker%3D%22o%22%2C%0A%20%20%20%20%20%20%20%20markersize%3D4%2C%0A%20%20%20%20%20%20%20%20markerfacecolor%3D%22white%22%2C%0A%20%20%20%20%20%20%20%20markeredgecolor%3D%22black%22%2C%0A%20%20%20%20%20%20%20%20markeredgewidth%3D0.8%2C%0A%20%20%20%20%20%20%20%20label%3D%22samples%22%2C%0A%20%20%20%20)%0A%20%20%20%20_ax.set_ylim(-1.0%2C%202.0)%0A%20%20%20%20_ax.set_xlabel(%22x%22)%0A%20%20%20%20_ax.set_title(%22Equispaced%20interpolation%20of%20Runge's%20function%22)%0A%20%20%20%20_ax.legend(loc%3D%22upper%20right%22%2C%20fontsize%3D%22small%22)%0A%20%20%20%20_fig%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%20Convergence%20under%20grid%20refinement%0A%0A%20%20%20%20As%20the%20equispaced%20grid%20is%20refined%2C%20the%20reconstruction%20error%20decreases%0A%20%20%20%20steadily%20%E2%80%94%20the%20opposite%20of%20the%20polynomial's%20divergence.%20%20Note%20that%20the%0A%20%20%20%20length%20of%20the%20resulting%20Chebfun%20stays%20modest%3A%20the%20Floater%E2%80%93Hormann%0A%20%20%20%20interpolant%20is%20smooth%2C%20so%20its%20adaptive%20Chebyshev%20representation%20is%20compact.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(runge)%3A%0A%20%20%20%20_xx%20%3D%20np.linspace(-1.0%2C%201.0%2C%204001)%0A%20%20%20%20print(f%22%7B'samples'%3A%3E8%7D%20%20%7B'len(f)'%3A%3E7%7D%20%20%7B'max%20%7Cerror%7C'%3A%3E12%7D%22)%0A%20%20%20%20print(%22-%22%20*%2032)%0A%20%20%20%20for%20_n%20in%20(17%2C%2033%2C%2065%2C%20129%2C%20257)%3A%0A%20%20%20%20%20%20%20%20_nodes%20%3D%20np.linspace(-1.0%2C%201.0%2C%20_n)%0A%20%20%20%20%20%20%20%20_f%20%3D%20equifun(runge(_nodes))%0A%20%20%20%20%20%20%20%20_err%20%3D%20float(np.max(np.abs(_f(_xx)%20-%20runge(_xx))))%0A%20%20%20%20%20%20%20%20print(f%22%7B_n%3A%3E8d%7D%20%20%7Blen(_f)%3A%3E7d%7D%20%20%7B_err%3A%3E12.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%20Calculus%20on%20reconstructed%20data%0A%0A%20%20%20%20Because%20%60equifun%60%20returns%20an%20ordinary%20Chebfun%2C%20the%20full%20toolbox%20applies.%0A%20%20%20%20Here%20we%20recover%20a%20derivative%20and%20a%20definite%20integral%20directly%20from%20sampled%0A%20%20%20%20values%20of%20%24g(x)%20%3D%20%5Csin(%5Cpi%20x)%24%20on%20%24%5B-1%2C%201%5D%24%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%20_nodes%20%3D%20np.linspace(-1.0%2C%201.0%2C%2033)%0A%20%20%20%20g%20%3D%20equifun(np.sin(np.pi%20*%20_nodes))%0A%20%20%20%20dg%20%3D%20g.diff()%0A%20%20%20%20print(f%22sum(g)%20%20%20%3D%20%7Bfloat(g.sum())%3A%2B.12f%7D%20%20%20(expected%200)%22)%0A%20%20%20%20print(f%22dg(0.0)%20%20%3D%20%7Bfloat(dg(0.0))%3A%2B.12f%7D%20%20%20(expected%20pi%20%3D%20%7Bnp.pi%3A.12f%7D)%22)%0A%20%20%20%20return%20dg%2C%20g%0A%0A%0A%40app.cell%0Adef%20_(dg%2C%20g)%3A%0A%20%20%20%20_xx%20%3D%20np.linspace(-1.0%2C%201.0%2C%20500)%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20_ax.plot(_xx%2C%20g(_xx)%2C%20color%3D%22C0%22%2C%20linewidth%3D2%2C%20label%3Dr%22%24g(x)%20%3D%20%5Csin(%5Cpi%20x)%24%22)%0A%20%20%20%20_ax.plot(_xx%2C%20dg(_xx)%2C%20color%3D%22C1%22%2C%20linewidth%3D2%2C%20label%3Dr%22%24g'(x)%20%3D%20%5Cpi%20%5Ccos(%5Cpi%20x)%24%22)%0A%20%20%20%20_ax.set_xlabel(%22x%22)%0A%20%20%20%20_ax.legend()%0A%20%20%20%20_fig%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%20Small-sample%20edge%20cases%0A%0A%20%20%20%20%60equifun%60%20degrades%20gracefully%20when%20there%20is%20very%20little%20data%3A%0A%0A%20%20%20%20-%20a%20**single**%20value%20produces%20the%20corresponding%20constant%20Chebfun%2C%20and%0A%20%20%20%20-%20**two**%20values%20produce%20the%20straight%20line%20joining%20them.%0A%0A%20%20%20%20Both%20real%20and%20complex%20sample%20vectors%20are%20supported.%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%20const%20%3D%20equifun(%5B2.5%5D%2C%20%5B2.0%2C%205.0%5D)%0A%20%20%20%20line%20%3D%20equifun(%5B-3.0%2C%203.0%5D)%0A%20%20%20%20cplx%20%3D%20equifun(%5B1.0%20%2B%201.0j%2C%200.0%2C%20-1.0%20%2B%201.0j%5D)%0A%20%20%20%20print(f%22single%20sample%20%3A%20f(3.0)%20%3D%20%7Bfloat(const(3.0))%3A.3f%7D%20%20%20(constant)%22)%0A%20%20%20%20print(f%22two%20samples%20%20%20%3A%20f(0.0)%20%3D%20%7Bfloat(line(0.0))%3A.3f%7D%20%20%20(linear%20midpoint)%22)%0A%20%20%20%20print(f%22complex%20data%20%20%3A%20f(0.0)%20%3D%20%7Bcomplex(cplx(0.0))%3A.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%20%23%23%20See%20also%0A%0A%20%20%20%20-%20The%20%5BFunction%20Approximation%5D(..%2Fuser%2Ffeatures%2Fapproximation.md)%20feature%0A%20%20%20%20%20%20page%20for%20a%20written%20summary%20of%20%60equifun%60.%0A%20%20%20%20-%20MATLAB%20Chebfun's%20%60chebfun(values%2C%20'equi')%60%20constructor%20and%20its%20%60funqui%60%0A%20%20%20%20%20%20routine%2C%20which%20ChebPy's%20implementation%20follows.%0A%0A%20%20%20%20%23%23%20References%0A%0A%20%20%20%20-%20M.%20S.%20Floater%20and%20K.%20Hormann%2C%0A%20%20%20%20%20%20*Barycentric%20rational%20interpolation%20with%20no%20poles%20and%20high%20rates%20of%0A%20%20%20%20%20%20approximation*%2C%0A%20%20%20%20%20%20%5BNumer.%20Math.%20107%2C%20315%E2%80%93331%20(2007)%5D(https%3A%2F%2Fdoi.org%2F10.1007%2Fs00211-007-0093-y).%0A%20%20%20%20-%20R.%20B.%20Platte%2C%20L.%20N.%20Trefethen%2C%20and%20A.%20B.%20J.%20Kuijlaars%2C%0A%20%20%20%20%20%20*Impossibility%20of%20fast%20stable%20approximation%20of%20analytic%20functions%20from%0A%20%20%20%20%20%20equispaced%20samples*%2C%0A%20%20%20%20%20%20%5BSIAM%20Rev.%2053(2)%2C%20308%E2%80%93318%20(2011)%5D(https%3A%2F%2Fdoi.org%2F10.1137%2F090774707).%0A%20%20%20%20-%20T.%20A.%20Driscoll%2C%20N.%20Hale%2C%20and%20L.%20N.%20Trefethen%20(eds.)%2C%0A%20%20%20%20%20%20%5B*Chebfun%20Guide*%5D(https%3A%2F%2Fwww.chebfun.org%2Fdocs%2Fguide%2F)%2C%0A%20%20%20%20%20%20Pafnuty%20Publications%2C%202014.%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
2fbcef070f7abdeb187471a82bb8fed2