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%20warnings%0A%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%0A%20%20%20%20from%20chebpy.bndfun%20import%20Bndfun%0A%20%20%20%20from%20chebpy.maps%20import%20MapParams%0A%20%20%20%20from%20chebpy.singfun%20import%20Singfun%0A%20%20%20%20from%20chebpy.utilities%20import%20Interval%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%20Endpoint%20Singularities%0A%0A%20%20%20%20This%20notebook%20tours%20ChebPy's%20%60Singfun%60%20machinery%20for%20functions%20with%0A%20%20%20%20branch-type%20singularities%20at%20one%20or%20both%20endpoints%20of%20a%20bounded%20interval.%0A%20%20%20%20The%20underlying%20technology%20is%20the%20Adcock-Richardson%20slit-strip%0A%20%20%20%20variable%20transform%20(Adcock%20%26%20Richardson%2C%20*SIAM%20J.%20Numer.%20Anal.*%0A%20%20%20%2052(4)%2C%201887%E2%80%931912%2C%202014%3B%20arXiv%3A1305.2643)%2C%20which%20clusters%0A%20%20%20%20Chebyshev%20nodes%20super-exponentially%20near%20the%20singular%20endpoint(s)%0A%20%20%20%20so%20that%20the%20transformed%20function%20is%20analytic%20and%20resolves%20to%0A%20%20%20%20spectral%20accuracy.%0A%0A%20%20%20%20Square-root%20and%20other%20algebraic%20singularities%20%E2%80%94%20%24%5Csqrt%7Bx%7D%24%2C%0A%20%20%20%20%24(1-x)%5E%7B1%2F2%7D%24%2C%20%24%5Csqrt%7Bx(1-x)%7D%24%20%E2%80%94%20are%20the%20canonical%20use%20cases.%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%20The%20map%20families%0A%0A%20%20%20%20Both%20clustering%20maps%20act%20through%20a%20smooth%20bijection%0A%20%20%20%20%24m%20%3A%20%5B-1%2C%201%5D%20%5Cto%20%5Ba%2C%20b%5D%24%20whose%20derivative%20vanishes%0A%20%20%20%20super-exponentially%20at%20the%20clustered%20endpoint(s).%20The%20%60Onefun%60%0A%20%20%20%20payload%20then%20sees%20the%20analytic%20function%20%24f%20%5Ccirc%20m%24%20and%20resolves%0A%20%20%20%20it%20to%20spectral%20accuracy.%20Both%20maps%20are%20parameterised%20by%0A%20%20%20%20%60MapParams(L%2C%20alpha)%60%3A%20%24%5Calpha%20%3E%200%24%20is%20the%20strip%20half-width%20and%0A%20%20%20%20%24L%20%3E%200%24%20truncates%20the%20(otherwise%20semi-%2Fbi-infinite)%20underlying%0A%20%20%20%20paper%20map.%0A%0A%20%20%20%20%23%23%23%20One-sided%20(%60sing%3D%22left%22%60%2C%20%60sing%3D%22right%22%60)%0A%0A%20%20%20%20With%20%24s%20%3D%20L(t%20-%201)%2F2%24%20and%20the%20shift%0A%20%20%20%20%24%5Cgamma%20%3D%20(%5Calpha%2F%5Cpi)%5Clog(e%5E%7B%5Cpi%2F%5Calpha%7D%20-%201)%24%20chosen%20so%20that%20the%0A%20%20%20%20smooth%20endpoint%20is%20hit%20exactly%2C%0A%0A%20%20%20%20%24%24%0A%20%20%20%20u_%5Calpha(s)%20%3D%20%5Cfrac%7B%5Calpha%7D%7B%5Cpi%7D%20%5Clog(1%20%2B%20e%5E%7B%5Cpi(s%20%2B%20%5Cgamma)%2F%5Calpha%7D)%2C%20%5Cqquad%0A%20%20%20%20m(t)%20%3D%20a%20%2B%20(b%20-%20a)%5C%2C%20u_%5Calpha(L(t%20-%201)%2F2).%0A%20%20%20%20%24%24%0A%0A%20%20%20%20For%20%60sing%3D%22right%22%60%20the%20analogous%20reflection%0A%20%20%20%20%24m(t)%20%3D%20b%20-%20(b%20-%20a)%5C%2C%20u_%5Calpha(L(-t%20-%201)%2F2)%24%20is%20used.%0A%0A%20%20%20%20%23%23%23%20Two-sided%20(%60sing%3D%22both%22%60)%0A%0A%20%20%20%20With%20%24s%20%3D%20L%5C%2Ct%24%2C%0A%0A%20%20%20%20%24%24%0A%20%20%20%20v_%5Calpha(s)%20%3D%20%5Cfrac%7B%5Calpha%7D%7B%5Cpi%7D%20%5Cleft%5B%20%5Clog(1%20%2B%20e%5E%7B%5Cpi(s%20%2B%201%2F2)%2F%5Calpha%7D)%20-%20%5Clog(1%20%2B%20e%5E%7B%5Cpi(s%20-%201%2F2)%2F%5Calpha%7D)%20%5Cright%5D%2C%20%5Cqquad%0A%20%20%20%20m(t)%20%3D%20a%20%2B%20(b%20-%20a)%5C%2C%20v_%5Calpha(L%5C%2Ct)%2C%0A%20%20%20%20%24%24%0A%0A%20%20%20%20so%20%24v_%5Calpha(0)%20%3D%201%2F2%24%20and%20%24v_%5Calpha(%5Cpm%5Cinfty)%20%3D%20(1%5Cpm%201)%2F2%24%2C%0A%20%20%20%20clustering%20at%20both%20endpoints%20simultaneously.%0A%0A%20%20%20%20With%20finite%20%24L%24%20the%20image%20of%20%24m%24%20falls%20short%20of%20the%20clustered%0A%20%20%20%20endpoint(s)%20by%20a%20small%20%60gap%60%3B%20with%20the%20default%20%24L%20%3D%208%24%20this%20is%0A%20%20%20%20below%20%2410%5E%7B-10%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%20A%20one-sided%20logarithmic%20singularity%0A%0A%20%20%20%20The%20simplest%20example%3A%20%24f(x)%20%3D%20x%5Clog%20x%24%20on%20%24%5B0%2C%201%5D%24%2C%20with%20the%0A%20%20%20%20derivative%20singularity%20at%20the%20left%20endpoint.%20%20Pass%20%60sing%3D%22left%22%60%20to%0A%20%20%20%20%60chebfun%60%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%20xlogx_left%20%3D%20chebfun(lambda%20x%3A%20x%20*%20np.log(x)%2C%20%5B0.0%2C%201.0%5D%2C%20sing%3D%22left%22)%0A%20%20%20%20print(xlogx_left)%0A%20%20%20%20print()%0A%20%20%20%20print(f%22piece%20type%20%20%20%20%3A%20%7Btype(xlogx_left.funs%5B0%5D).__name__%7D%22)%0A%20%20%20%20print(f%22size%20%20%20%20%20%20%20%20%20%20%3A%20%7Bxlogx_left.funs%5B0%5D.size%7D%20coefficients%22)%0A%20%20%20%20print(f%22sum%20(%3D%20-1%2F4)%20%20%3A%20%7Bfloat(xlogx_left.sum())%3A.16f%7D%22)%0A%20%20%20%20print(f%22%20%20%20%20%20%20%20%20%20%20%20%20ref%20%7B-1.0%20%2F%204.0%3A.16f%7D%22)%0A%20%20%20%20return%20(xlogx_left%2C)%0A%0A%0A%40app.cell%0Adef%20_(xlogx_left)%3A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20xlogx_left.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%20x%5Clog%20x%24%20on%20%24%5B0%2C%201%5D%24%20(sing%3D'left')%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%20A%20two-sided%20singularity%0A%0A%20%20%20%20With%20%60sing%3D%22both%22%60%2C%20the%20symmetric%20%22double-slit%22%20map%20clusters%20nodes%0A%20%20%20%20at%20*both*%20endpoints.%20%20The%20integrand%20%24%5Csqrt%7Bx(1-x)%7D%24%20is%20the%20textbook%0A%20%20%20%20example%20with%20closed-form%20integral%20%24%5Cpi%2F8%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%20sqrt_two_sided%20%3D%20chebfun(lambda%20x%3A%20np.sqrt(x%20*%20(1.0%20-%20x))%2C%20%5B0.0%2C%201.0%5D%2C%20sing%3D%22both%22)%0A%20%20%20%20print(f%22size%20%3A%20%7Bsqrt_two_sided.funs%5B0%5D.size%7D%20coefficients%22)%0A%20%20%20%20print(f%22sum%20%20%3A%20%7Bfloat(sqrt_two_sided.sum())%3A.16f%7D%22)%0A%20%20%20%20print(f%22%20%20ref%3A%20%7Bnp.pi%20%2F%208.0%3A.16f%7D%22)%0A%20%20%20%20return%20(sqrt_two_sided%2C)%0A%0A%0A%40app.cell%0Adef%20_(sqrt_two_sided)%3A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20sqrt_two_sided.plot(ax%3D_ax)%0A%20%20%20%20_ax.set_xlabel(%22x%22)%0A%20%20%20%20_ax.set_title(r%22%24%5Csqrt%7Bx(1-x)%7D%24%20on%20%24%5B0%2C%201%5D%24%20(sing%3D'both')%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%20Resolution%20power%20vs.%20plain%20Chebyshev%0A%0A%20%20%20%20A%20standard%20%60Bndfun%60%20(no%20map)%20cannot%20resolve%20a%20square%20root%20with%0A%20%20%20%20machine%20precision%3A%20the%20adaptive%20constructor%20refuses%20to%20converge%20and%0A%20%20%20%20emits%20a%20%60did%20not%20converge%60%20warning.%20%20The%20%60Singfun%60%20construction%0A%20%20%20%20reaches%20full%20machine%20precision%20with%20a%20small%20coefficient%20count.%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%20with%20warnings.catch_warnings()%3A%0A%20%20%20%20%20%20%20%20warnings.simplefilter(%22ignore%22)%0A%20%20%20%20%20%20%20%20bndfun_sqrt%20%3D%20Bndfun.initfun_adaptive(np.sqrt%2C%20Interval(0.0%2C%201.0))%0A%20%20%20%20singfun_sqrt%20%3D%20Singfun.initfun_adaptive(np.sqrt%2C%20%5B0.0%2C%201.0%5D%2C%20sing%3D%22left%22%2C%20params%3DMapParams(alpha%3D1.0))%0A%0A%20%20%20%20_grid%20%3D%20np.linspace(0.001%2C%200.999%2C%20401)%0A%20%20%20%20_err_bnd%20%3D%20float(np.max(np.abs(bndfun_sqrt(_grid)%20-%20np.sqrt(_grid))))%0A%20%20%20%20_err_sng%20%3D%20float(np.max(np.abs(singfun_sqrt(_grid)%20-%20np.sqrt(_grid))))%0A%20%20%20%20print(f%22Bndfun%20%20%20%3A%20size%3D%7Bbndfun_sqrt.size%3A5d%7D%2C%20max-err%3D%7B_err_bnd%3A.2e%7D%22)%0A%20%20%20%20print(f%22Singfun%20%20%3A%20size%3D%7Bsingfun_sqrt.size%3A5d%7D%2C%20max-err%3D%7B_err_sng%3A.2e%7D%22)%0A%20%20%20%20return%20bndfun_sqrt%2C%20singfun_sqrt%0A%0A%0A%40app.cell%0Adef%20_(bndfun_sqrt%2C%20singfun_sqrt)%3A%0A%20%20%20%20_fig%2C%20(_ax1%2C%20_ax2)%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(12%2C%205)%2C%20sharey%3DTrue)%0A%20%20%20%20_ax1.semilogy(np.arange(bndfun_sqrt.size)%2C%20np.abs(bndfun_sqrt.coeffs)%20%2B%201e-20%2C%20color%3D%22C0%22)%0A%20%20%20%20_ax1.set_xlabel(%22coefficient%20index%22)%0A%20%20%20%20_ax1.set_ylabel(%22%7Ccoefficient%7C%22)%0A%20%20%20%20_ax1.set_title(f%22Bndfun%20(no%20map)%3A%20%7Bbndfun_sqrt.size%7D%20coeffs%22)%0A%20%20%20%20_ax2.semilogy(np.arange(singfun_sqrt.size)%2C%20np.abs(singfun_sqrt.coeffs)%20%2B%201e-20%2C%20color%3D%22C1%22)%0A%20%20%20%20_ax2.set_xlabel(%22coefficient%20index%22)%0A%20%20%20%20_ax2.set_title(f%22Singfun%20(sing%3D'left')%3A%20%7Bsingfun_sqrt.size%7D%20coeffs%22)%0A%20%20%20%20_fig.suptitle(r%22Chebyshev%20coefficient%20decay%20for%20%24%5Csqrt%7Bx%7D%24%20on%20%24%5B0%2C1%5D%24%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%20Tuning%20the%20map%3A%20%60MapParams(L%2C%20alpha)%60%0A%0A%20%20%20%20The%20two%20parameters%20trade%20off%20three%20things%20%E2%80%94%20coefficient%20count%2C%0A%20%20%20%20pointwise%20accuracy%20near%20the%20clustered%20endpoint%2C%20and%20the%20size%20of%0A%20%20%20%20the%20unresolved%20%60gap%60.%20Defaults%20%60L%20%3D%208.0%60%2C%20%60alpha%20%3D%201.0%60%20are%20a%0A%20%20%20%20safe%20choice%20for%20the%20canonical%20algebraic%20singularities%20%24x%5Ep%24%20with%0A%20%20%20%20%24p%20%5Cin%20%5B1%2F4%2C%201%5D%24%20on%20a%20bounded%20interval%3B%20the%20cells%20below%20show%0A%20%20%20%20when%20and%20how%20to%20depart%20from%20them.%0A%0A%20%20%20%20**%60alpha%60%20(strip%20half-width).**%20Smaller%20%24%5Calpha%24%20clusters%20nodes%0A%20%20%20%20more%20aggressively%20near%20the%20singular%20endpoint%2C%20which%20helps%20for%0A%20%20%20%20*stronger*%20singularities%20(e.g.%20%24(1-x)%5E%7B0.1%7D%24)%20at%20the%20cost%20of%20more%0A%20%20%20%20Chebyshev%20coefficients.%20Larger%20%24%5Calpha%24%20relaxes%20the%20clustering%20%E2%80%94%0A%20%20%20%20fewer%20coefficients%2C%20but%20weak%2Flog%20singularities%20may%20stop%0A%20%20%20%20converging.%0A%0A%20%20%20%20-%20%24%5Calpha%20%5Capprox%200.5%24%20%E2%80%94%20strong%20singularities%2C%0A%20%20%20%20%20%20%24f%20%5Csim%20(x-a)%5Ep%24%20with%20%24p%20%5Clesssim%200.25%24%2C%20or%20weak%20logarithms.%0A%20%20%20%20-%20%24%5Calpha%20%3D%201.0%24%20(default)%20%E2%80%94%20square%20roots%20and%20most%20algebraic%0A%20%20%20%20%20%20cases%3B%20matches%20the%20paper's%20empirical%20optimum.%0A%20%20%20%20-%20%24%5Calpha%20%5Capprox%202.0%24%20%E2%80%94%20gentle%20singularities%2C%20e.g.%0A%20%20%20%20%20%20%24(x-a)%5E%7B0.8%7D%24%2C%20or%20smooth%20functions%20where%20you%20only%20want%20a%20hint%0A%20%20%20%20%20%20of%20clustering.%0A%0A%20%20%20%20**%60L%60%20(truncation%20length).**%20%24L%24%20controls%20how%20far%20into%20the%0A%20%20%20%20paper's%20semi-%2Fbi-infinite%20strip%20we%20sample%2C%20and%20equivalently%20the%0A%20%20%20%20%60gap%60%20left%20at%20the%20clustered%20endpoint.%20With%20the%20default%20%24L%20%3D%208%24%0A%20%20%20%20the%20gap%20is%20below%20%2410%5E%7B-10%7D%24%20%E2%80%94%20invisible%20at%20working%20precision.%0A%20%20%20%20Smaller%20%24L%24%20widens%20the%20gap%20visibly%3B%20larger%20%24L%24%20shrinks%20it%0A%20%20%20%20super-exponentially%20but%20also%20moves%20samples%20closer%20to%20the%0A%20%20%20%20endpoint%20where%20float64%20ulp's%20bound%20pointwise%20accuracy.%0A%0A%20%20%20%20-%20%24L%20%3D%201%24%E2%80%93%242%24%20%E2%80%94%20the%20paper's%20empirical%20optimum%20for%20fastest%0A%20%20%20%20%20%20coefficient%20decay%3B%20gap%20is%20%24%5Csim%2010%5E%7B-2%7D%24%E2%80%93%2410%5E%7B-1%7D%24%2C%20fine%0A%20%20%20%20%20%20when%20only%20the%20integral%20or%20interior%20values%20matter.%0A%20%20%20%20-%20%24L%20%3D%208%24%20(default)%20%E2%80%94%20gap%20below%20%2410%5E%7B-10%7D%24%2C%20indistinguishable%0A%20%20%20%20%20%20from%20a%20closed%20map%20at%20working%20precision.%0A%20%20%20%20-%20%24L%20%3D%2016%24%E2%80%93%2420%24%20%E2%80%94%20vanishing%20gap%3B%20useful%20when%20evaluating%20*at*%0A%20%20%20%20%20%20the%20clustered%20endpoint%20matters%20(e.g.%20boundary%20conditions)%2C%0A%20%20%20%20%20%20assuming%20the%20float64%20ulp%20ceiling%20at%20the%20clustered%20%24x%24%20is%20not%0A%20%20%20%20%20%20your%20real%20limit.%0A%0A%20%20%20%20**Rules%20of%20thumb.**%0A%0A%20%20%20%20-%20If%20the%20adaptive%20constructor%20fails%20to%20converge%2C%20*decrease*%0A%20%20%20%20%20%20%24%5Calpha%24%20first%2C%20then%20increase%20%24L%24.%0A%20%20%20%20-%20If%20you%20want%20fewer%20coefficients%20and%20only%20need%20integrals%2C%0A%20%20%20%20%20%20*decrease*%20%24L%24%20(toward%20%241%24%E2%80%93%242%24)%3B%20coefficient%20decay%20improves%0A%20%20%20%20%20%20noticeably.%0A%20%20%20%20-%20If%20pointwise%20accuracy%20at%20the%20clustered%20endpoint%20matters%2C%0A%20%20%20%20%20%20*increase*%20%24L%24%20but%20check%20that%20ulp%24(x_a)%24%20is%20not%20the%20dominant%0A%20%20%20%20%20%20error.%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%20The%20cell%20below%20sweeps%20%60alpha%60%20and%20%60L%60%20independently%20for%0A%20%20%20%20%24f(x)%20%3D%20%5Csqrt%7Bx%7D%24%20on%20%24%5B0%2C%201%5D%24%2C%20reporting%20the%20adaptive%0A%20%20%20%20coefficient%20count%2C%20the%20resulting%20%60gap%60%2C%20and%20the%20max%20pointwise%0A%20%20%20%20error%20on%20a%20uniform%20interior%20grid.%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%20print(f%22%7B'alpha'%3A%3E6%7D%20%20%7B'L'%3A%3E5%7D%20%20%7B'size'%3A%3E6%7D%20%20%7B'gap'%3A%3E10%7D%20%20%7B'max-err'%3A%3E10%7D%22)%0A%20%20%20%20print(%22-%22%20*%2046)%0A%20%20%20%20_grid%20%3D%20np.linspace(0.001%2C%200.999%2C%20401)%0A%20%20%20%20for%20_alpha%20in%20(0.5%2C%201.0%2C%202.0)%3A%0A%20%20%20%20%20%20%20%20for%20_L%20in%20(1.0%2C%204.0%2C%208.0%2C%2016.0)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_s%20%3D%20Singfun.initfun_adaptive(np.sqrt%2C%20%5B0.0%2C%201.0%5D%2C%20sing%3D%22left%22%2C%20params%3DMapParams(L%3D_L%2C%20alpha%3D_alpha))%0A%20%20%20%20%20%20%20%20%20%20%20%20_err%20%3D%20float(np.max(np.abs(_s(_grid)%20-%20np.sqrt(_grid))))%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%7B_alpha%3A%3E6.2f%7D%20%20%7B_L%3A%3E5.1f%7D%20%20%7B_s.size%3A%3E6d%7D%20%20%7B_s.map.gap%3A%3E10.2e%7D%20%20%7B_err%3A%3E10.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%20Reading%20the%20table%3A%20holding%20%24%5Calpha%24%20fixed%2C%20decreasing%20%24L%24%0A%20%20%20%20typically%20*reduces*%20coefficient%20count%20(faster%20decay%2C%20the%20paper's%0A%20%20%20%20main%20result)%20at%20the%20price%20of%20a%20visible%20%60gap%60.%20Holding%20%24L%24%20fixed%2C%0A%20%20%20%20decreasing%20%24%5Calpha%24%20pulls%20samples%20closer%20to%20the%20singularity%20%E2%80%94%0A%20%20%20%20sometimes%20the%20only%20way%20to%20get%20a%20stubborn%20weak-power%20case%20to%0A%20%20%20%20converge.%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%20Accuracy%20ceiling%20near%20non-zero%20clustered%20endpoints%0A%0A%20%20%20%20Pointwise%20accuracy%20is%20bounded%20below%20by%20the%20float64%20spacing%20of%20%24x%24%20at%0A%20%20%20%20the%20clustered%20samples%2C%20scaled%20by%20the%20local%20Lipschitz%20constant%20of%20%24f%24%3A%0A%0A%20%20%20%20%24%24%20%7Cf(x_%7B%5Ctext%7Bexact%7D%7D)%20-%20f(x_%7B%5Ctext%7Bfloat%7D%7D)%7C%20%5C%3B%5Capprox%5C%3B%20%7Cf'(x)%7C%20%5Ccdot%20%5Cmathrm%7Bulp%7D(x).%20%24%24%0A%0A%20%20%20%20For%20%24%5Csqrt%7Bx%7D%24%20clustered%20at%20%24x%20%3D%200%24%20the%20subnormals%20give%20effectively%0A%20%20%20%20unbounded%20relative%20resolution.%20%20For%20%24%5Csqrt%7B1-x%7D%24%20clustered%20at%20%24x%3D1%24%0A%20%20%20%20the%20floor%20is%20around%20%2410%5E%7B-10%7D%24.%20%20Weak%20singularities%20%24(1-x)%5Ep%24%20with%0A%20%20%20%20small%20%24p%24%20can%20fail%20to%20converge%20entirely.%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%20accuracy_cases%20%3D%20%5B%0A%20%20%20%20%20%20%20%20(%22sqrt(x)%22%2C%20np.sqrt%2C%20%22left%22%2C%201.0)%2C%0A%20%20%20%20%20%20%20%20(%22sqrt(1-x)%22%2C%20lambda%20x%3A%20np.sqrt(1.0%20-%20x)%2C%20%22right%22%2C%201.0)%2C%0A%20%20%20%20%20%20%20%20(%22sqrt(x(1-x))%22%2C%20lambda%20x%3A%20np.sqrt(x%20*%20(1.0%20-%20x))%2C%20%22both%22%2C%201.0)%2C%0A%20%20%20%20%5D%0A%20%20%20%20for%20_label%2C%20_fn%2C%20_side%2C%20_alpha%20in%20accuracy_cases%3A%0A%20%20%20%20%20%20%20%20_s%20%3D%20Singfun.initfun_adaptive(_fn%2C%20%5B0.0%2C%201.0%5D%2C%20sing%3D_side%2C%20params%3DMapParams(alpha%3D_alpha))%0A%20%20%20%20%20%20%20%20_xx%20%3D%20np.linspace(0.001%2C%200.999%2C%20401)%0A%20%20%20%20%20%20%20%20_err%20%3D%20float(np.max(np.abs(_s(_xx)%20-%20_fn(_xx))))%0A%20%20%20%20%20%20%20%20print(f%22%7B_label%3A14s%7D%20sing%3D%7B_side%3A5s%7D%20size%3D%7B_s.size%3A4d%7D%20%20max-err%3D%7B_err%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%20The%20integrals%20are%20unaffected.%20%20The%20bad%20samples%20sit%20at%20%24t%20%5Cto%20%5Cpm%201%24%0A%20%20%20%20where%20the%20Jacobian%20%24m'(t)%20%5Cto%200%24%20super-exponentially%2C%20suppressing%0A%20%20%20%20noise%20below%20machine%20epsilon%20%E2%80%94%20so%20%60sum()%60%20reaches%20full%20precision%0A%20%20%20%20even%20where%20pointwise%20evaluation%20does%20not.%0A%0A%20%20%20%20%23%23%20Convolution%20refuses%20Singfun%20pieces%0A%0A%20%20%20%20The%20Hale-Townsend%20Legendre%20convolution%20algorithm%20assumes%20an%20affine%0A%20%20%20%20map%20between%20logical%20and%20reference%20variables.%20%20The%20slit-strip%0A%20%20%20%20clustering%20map%20breaks%20this%20assumption%2C%20so%20%60Chebfun.conv%60%20refuses%0A%20%20%20%20%60Singfun%60%20operands%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%20conv_lhs%20%3D%20chebfun(np.sqrt%2C%20%5B0.0%2C%201.0%5D%2C%20sing%3D%22left%22)%0A%20%20%20%20conv_rhs%20%3D%20chebfun(lambda%20x%3A%201.0%20%2B%200%20*%20x%2C%20%5B0.0%2C%201.0%5D)%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20conv_lhs.conv(conv_rhs)%0A%20%20%20%20except%20NotImplementedError%20as%20err%3A%0A%20%20%20%20%20%20%20%20print(str(err))%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%20Mixed-piece%20arithmetic%0A%0A%20%20%20%20Operations%20between%20a%20%60Singfun%60%20and%20a%20%60Bndfun%60%20on%20the%20same%20interval%0A%20%20%20%20reconstruct%20the%20result%20on%20the%20singular%20representation.%20%20This%20means%20a%0A%20%20%20%20user%20assembling%20expressions%20like%20%24%5Csqrt%7Bx%7D%20%2B%20x%5E2%24%20does%20not%20have%20to%0A%20%20%20%20think%20about%20which%20operand%20is%20singular%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%20mixed_singular%20%3D%20Singfun.initfun_adaptive(np.sqrt%2C%20%5B0.0%2C%201.0%5D%2C%20sing%3D%22left%22)%0A%20%20%20%20mixed_smooth%20%3D%20Bndfun.initfun_adaptive(lambda%20x%3A%20x%20*%20x%2C%20Interval(0.0%2C%201.0))%0A%20%20%20%20mixed_sum%20%3D%20mixed_singular%20%2B%20mixed_smooth%0A%20%20%20%20print(f%22Singfun%20%2B%20Bndfun%20is%20a%20%7Btype(mixed_sum).__name__%7D%22)%0A%20%20%20%20_grid%20%3D%20np.linspace(0.0001%2C%200.9999%2C%2021)%0A%20%20%20%20_err%20%3D%20float(np.max(np.abs(mixed_sum(_grid)%20-%20(np.sqrt(_grid)%20%2B%20_grid%20*%20_grid))))%0A%20%20%20%20print(f%22max-err%20vs%20reference%3A%20%7B_err%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%20Restriction%0A%0A%20%20%20%20%60Singfun.restrict%60%20chooses%20its%20result%20type%20by%20inspecting%20the%0A%20%20%20%20subinterval%3A%0A%0A%20%20%20%20-%20sharing%20the%20clustered%20endpoint%20-%3E%20%60Singfun%60%0A%20%20%20%20-%20purely%20interior%20-%3E%20%60Bndfun%60%20(the%20function%20is%20analytic%20there).%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%20restrict_source%20%3D%20Singfun.initfun_adaptive(np.sqrt%2C%20%5B0.0%2C%201.0%5D%2C%20sing%3D%22left%22%2C%20params%3DMapParams(alpha%3D1.0))%0A%20%20%20%20restrict_left%20%3D%20restrict_source.restrict(%5B0.0%2C%200.5%5D)%0A%20%20%20%20with%20warnings.catch_warnings()%3A%0A%20%20%20%20%20%20%20%20warnings.simplefilter(%22ignore%22)%0A%20%20%20%20%20%20%20%20restrict_interior%20%3D%20restrict_source.restrict(%5B0.2%2C%200.8%5D)%0A%20%20%20%20print(f%22restrict(%5B0.0%2C%200.5%5D)%20-%3E%20%7Btype(restrict_left).__name__%7D%22)%0A%20%20%20%20print(f%22restrict(%5B0.2%2C%200.8%5D)%20-%3E%20%7Btype(restrict_interior).__name__%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%20References%0A%0A%20%20%20%20-%20B.%20Adcock%20and%20M.%20Richardson%2C%0A%20%20%20%20%20%20*New%20exponential%20variable%20transform%20methods%20for%20functions%20with%0A%20%20%20%20%20%20endpoint%20singularities*%2C%0A%20%20%20%20%20%20%5BSIAM%20J.%20Numer.%20Anal.%2052(4)%2C%201887%E2%80%931912%20(2014)%5D(https%3A%2F%2Fdoi.org%2F10.1137%2F130920460)%3B%0A%20%20%20%20%20%20%5BarXiv%3A1305.2643%5D(https%3A%2F%2Farxiv.org%2Fabs%2F1305.2643).%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%2C%20ch.%209.%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
bb89a1f283243e30e9d89964f7afceba