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%20chebfun%2C%20trigfun%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%20Periodic%20Representations%0A%0A%20%20%20%20For%20smooth%20periodic%20functions%20on%20a%20bounded%20interval%2C%20ChebPy%20offers%20a%0A%20%20%20%20Fourier-based%20representation%20via%20%60Trigtech%60%20%E2%80%94%20the%20trigonometric%20analogue%0A%20%20%20%20of%20the%20default%20%60Chebtech%60.%20%20The%20user-facing%20entry%20point%20is%0A%20%20%20%20%5B%60trigfun%60%5D(..%2Fapi.md)%2C%20which%20mirrors%20%60chebfun%60%20exactly%20but%20always%20uses%0A%20%20%20%20%60Trigtech%60%20as%20the%20underlying%20technology.%0A%0A%20%20%20%20Two%20design%20points%20are%20worth%20noting%20up-front%3A%0A%0A%20%20%20%20-%20**Periodicity%20is%20opted%20into%20explicitly**%20%E2%80%94%20there%20is%20no%20automatic%0A%20%20%20%20%20%20detection.%20%20This%20mirrors%20MATLAB%20Chebfun's%20%60chebfun(f%2C%20'trig')%60%20while%0A%20%20%20%20%20%20keeping%20the%20Python%20API%20unambiguous.%0A%20%20%20%20-%20**%60Trigtech%60%20shares%20the%20%60Onefun%20%E2%86%92%20Smoothfun%60%20interface**%20with%0A%20%20%20%20%20%20%60Chebtech%60%2C%20so%20a%20%60trigfun%60-backed%20Chebfun%20supports%20all%20the%20usual%0A%20%20%20%20%20%20operations%20(%60diff%60%2C%20%60cumsum%60%2C%20%60sum%60%2C%20%60roots%60%2C%20arithmetic%2C%20plotting).%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%3A%20%24%5Ccos(%5Cpi%20x)%24%20on%20%24%5B-1%2C%201%5D%24%0A%0A%20%20%20%20A%20simple%20period-2%20cosine%20is%20captured%20exactly%20by%20a%20single%20Fourier%20mode%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%20f%20%3D%20trigfun(lambda%20x%3A%20np.cos(np.pi%20*%20x)%2C%20%5B-1%2C%201%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%22f(0.0)%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%7Bf(0.0)%3A%2B.15f%7D%20%20%20(expected%20%201)%22)%0A%20%20%20%20print(f%22f(0.5)%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%7Bf(0.5)%3A%2B.15f%7D%20%20%20(expected%20%200)%22)%0A%20%20%20%20print(f%22f(1.0)%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%7Bf(1.0)%3A%2B.15f%7D%20%20%20(expected%20-1)%22)%0A%20%20%20%20return%20(f%2C)%0A%0A%0A%40app.cell%0Adef%20_(f)%3A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20f.plot(ax%3D_ax)%0A%20%20%20%20_ax.set_xlabel(%22x%22)%0A%20%20%20%20_ax.set_title(r%22%24f(x)%20%3D%20%5Ccos(%5Cpi%20x)%24%20via%20%24%5Cmathrm%7Btrigfun%7D%24%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%20Compactness%20vs.%20Chebyshev%0A%0A%20%20%20%20For%20a%20smooth%20periodic%20target%2C%20a%20Fourier%20series%20typically%20requires%20far%0A%20%20%20%20fewer%20coefficients%20than%20a%20Chebyshev%20series%20of%20comparable%20accuracy.%0A%20%20%20%20Compare%20the%20lengths%20of%20two%20representations%20of%20the%20same%20function%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%20def%20target(x)%3A%0A%20%20%20%20%20%20%20%20return%20np.cos(8%20*%20np.pi%20*%20x)%20%2B%20np.sin(3%20*%20np.pi%20*%20x)%0A%0A%20%20%20%20fc%20%3D%20chebfun(target%2C%20%5B-1%2C%201%5D)%0A%20%20%20%20ft%20%3D%20trigfun(target%2C%20%5B-1%2C%201%5D)%0A%20%20%20%20print(f%22chebfun%20length%20%20%20%3D%20%7Blen(fc)%3A4d%7D%20%20%20(Chebyshev%20coefficients)%22)%0A%20%20%20%20print(f%22trigfun%20length%20%20%20%3D%20%7Blen(ft)%3A4d%7D%20%20%20(Fourier%20coefficients)%22)%0A%20%20%20%20_xx%20%3D%20np.linspace(-1.0%2C%201.0%2C%204001)%0A%20%20%20%20_err_c%20%3D%20float(np.max(np.abs(fc(_xx)%20-%20target(_xx))))%0A%20%20%20%20_err_t%20%3D%20float(np.max(np.abs(ft(_xx)%20-%20target(_xx))))%0A%20%20%20%20print(f%22max%20%7Cerror%7C%20%20%20%20%20%20chebfun%20%3D%20%7B_err_c%3A.2e%7D%22)%0A%20%20%20%20print(f%22max%20%7Cerror%7C%20%20%20%20%20%20trigfun%20%3D%20%7B_err_t%3A.2e%7D%22)%0A%20%20%20%20return%20fc%2C%20ft%0A%0A%0A%40app.cell%0Adef%20_(fc%2C%20ft)%3A%0A%20%20%20%20_fig%2C%20_axes%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(12%2C%204))%0A%20%20%20%20fc.plotcoeffs(ax%3D_axes%5B0%5D)%0A%20%20%20%20_axes%5B0%5D.set_title(f%22Chebyshev%20coefficients%20(n%20%3D%20%7Blen(fc)%7D)%22)%0A%20%20%20%20ft.plotcoeffs(ax%3D_axes%5B1%5D)%0A%20%20%20%20_axes%5B1%5D.set_title(f%22Fourier%20coefficients%20(n%20%3D%20%7Blen(ft)%7D)%22)%0A%20%20%20%20_fig.tight_layout()%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%20Calculus%20in%20Fourier%20space%0A%0A%20%20%20%20Differentiation%20and%20integration%20are%20spectral%20operations%20on%20the%20Fourier%0A%20%20%20%20coefficients.%20%20The%20result%20of%20%60diff%60%20or%20%60cumsum%60%20is%20itself%20a%20%60trigfun%60-%0A%20%20%20%20backed%20Chebfun%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%20g%20%3D%20trigfun(lambda%20x%3A%20np.sin(np.pi%20*%20x)%2C%20%5B-1%2C%201%5D)%0A%20%20%20%20dg%20%3D%20g.diff()%0A%20%20%20%20print(f%22sum(g)%20%20%20%20%20%20%20%20%20%3D%20%7Bg.sum()%3A%2B.15f%7D%20%20%20(expected%200)%22)%0A%20%20%20%20print(f%22dg(0.0)%20%20%20%20%20%20%20%20%3D%20%7Bdg(0.0)%3A%2B.15f%7D%20%20%20(expected%20%CF%80%20%3D%20%7Bnp.pi%3A.15f%7D)%22)%0A%20%20%20%20print(f%22piece%20tech%20%20%20%20%20%3D%20%7Btype(dg.funs%5B0%5D.onefun).__name__%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_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20g.plot(ax%3D_ax%2C%20label%3Dr%22%24g(x)%20%3D%20%5Csin(%5Cpi%20x)%24%22)%0A%20%20%20%20dg.plot(ax%3D_ax%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%20Roots%20of%20a%20periodic%20function%0A%0A%20%20%20%20%60roots%60%20works%20as%20usual%3B%20for%20%24%5Csin(2%5Cpi%20x)%24%20on%20%24%5B-1%2C%201%5D%24%20we%20expect%20roots%0A%20%20%20%20at%20%24%5C%7B-1%2C%20-0.5%2C%200%2C%200.5%2C%201%5C%7D%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%20h%20%3D%20trigfun(lambda%20x%3A%20np.sin(2%20*%20np.pi%20*%20x)%2C%20%5B-1%2C%201%5D)%0A%20%20%20%20print(%22roots%3A%22%2C%20np.array2string(h.roots()%2C%20precision%3D12%2C%20suppress_small%3DTrue))%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%20non-trivial%20periodic%20target%0A%0A%20%20%20%20The%20function%20%24f(x)%20%3D%20e%5E%7B%5Csin(%5Cpi%20x)%7D%24%20is%20smooth%20and%20exactly%202-periodic%20on%0A%20%20%20%20%24%5B-1%2C%201%5D%24.%20%20Its%20Fourier%20coefficients%20decay%20geometrically%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%20fp%20%3D%20trigfun(lambda%20x%3A%20np.exp(np.sin(np.pi%20*%20x))%2C%20%5B-1%2C%201%5D)%0A%20%20%20%20print(fp)%0A%20%20%20%20print(f%22len(fp)%20%20%20%20%20%20%20%20%3D%20%7Blen(fp)%7D%22)%0A%20%20%20%20print(f%22sum(fp)%20%20%20%20%20%20%20%20%3D%20%7Bfp.sum()%3A.15f%7D%20%20%20(%E2%89%88%202%20*%20I_0(1)%20%3D%20%7B2.0%20*%201.2660658777520084%3A.15f%7D)%22)%0A%20%20%20%20return%20(fp%2C)%0A%0A%0A%40app.cell%0Adef%20_(fp)%3A%0A%20%20%20%20_fig%2C%20_axes%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(12%2C%204))%0A%20%20%20%20fp.plot(ax%3D_axes%5B0%5D)%0A%20%20%20%20_axes%5B0%5D.set_xlabel(%22x%22)%0A%20%20%20%20_axes%5B0%5D.set_title(r%22%24f(x)%20%3D%20e%5E%7B%5Csin(%5Cpi%20x)%7D%24%22)%0A%20%20%20%20fp.plotcoeffs(ax%3D_axes%5B1%5D)%0A%20%20%20%20_axes%5B1%5D.set_title(%22Fourier%20coefficient%20magnitudes%22)%0A%20%20%20%20_fig.tight_layout()%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%20When%20*not*%20to%20use%20%60trigfun%60%0A%0A%20%20%20%20%60trigfun%60%20assumes%20the%20target%20is%20smooth%20**and**%20periodic%20on%20the%20requested%0A%20%20%20%20domain%20%E2%80%94%20i.e.%20%24f(a)%20%3D%20f(b)%24%20along%20with%20all%20relevant%20derivatives.%20%20If%0A%20%20%20%20the%20target%20violates%20periodicity%2C%20the%20Fourier%20series%20suffers%20from%20the%0A%20%20%20%20Gibbs%20phenomenon%20and%20convergence%20stalls.%20%20The%20example%20below%20%E2%80%94%20a%0A%20%20%20%20non-periodic%20linear%20function%20fit%20on%20%24%5B-1%2C%201%5D%24%20as%20if%20it%20were%20periodic%20%E2%80%94%0A%20%20%20%20illustrates%20the%20failure%20mode%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%20bad%20%3D%20trigfun(lambda%20x%3A%20x%2C%20%5B-1%2C%201%5D)%0A%20%20%20%20_xx%20%3D%20np.linspace(-1.0%2C%201.0%2C%204001)%0A%20%20%20%20_err%20%3D%20float(np.max(np.abs(bad(_xx)%20-%20_xx)))%0A%20%20%20%20print(f%22len(bad)%20%20%20%20%20%20%20%20%3D%20%7Blen(bad)%7D%22)%0A%20%20%20%20print(f%22max%20%7Cbad%20-%20x%7C%20%20%20%3D%20%7B_err%3A.2e%7D%20%20%20%20(large%20%E2%80%94%20Gibbs)%22)%0A%20%20%20%20return%20(bad%2C)%0A%0A%0A%40app.cell%0Adef%20_(bad)%3A%0A%20%20%20%20_xx%20%3D%20np.linspace(-1.0%2C%201.0%2C%202001)%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20_ax.plot(_xx%2C%20_xx%2C%20color%3D%22C0%22%2C%20linewidth%3D2%2C%20label%3D%22%24x%24%20(truth)%22)%0A%20%20%20%20_ax.plot(_xx%2C%20bad(_xx)%2C%20color%3D%22C1%22%2C%20linewidth%3D1.2%2C%20label%3D%22trigfun%20fit%22)%0A%20%20%20%20_ax.set_xlabel(%22x%22)%0A%20%20%20%20_ax.set_title(%22Non-periodic%20target%3A%20Gibbs%20oscillations%20near%20the%20endpoints%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%20See%20also%0A%0A%20%20%20%20-%20The%20%5BPeriodic%20Functions%5D(..%2Fuser%2Ffeatures%2Fperiodic.md)%20feature%20page%20for%0A%20%20%20%20%20%20a%20written%20summary%20of%20the%20%60trigfun%60%20API.%0A%20%20%20%20-%20The%20%5BGaussian%20Process%20Regression%20notebook%5D(6_gaussian_process.html)%0A%20%20%20%20%20%20for%20%60gpr(...%2C%20trig%3DTrue)%60%2C%20which%20produces%20a%20periodic%20posterior%20backed%0A%20%20%20%20%20%20by%20%60Trigtech%60.%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
ba82cdeb5c7b1f98b8c14d106409a37b