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%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---%0A%0A%20%20%20%20**Reference.**%20%20The%20ideas%20and%20examples%20in%20this%20notebook%20are%20drawn%20from%0A%20%20%20%20Chapter%206%20(%22Quasimatrices%20and%20Least-Squares%22)%20of%20the%0A%20%20%20%20%5BChebfun%20Guide%5D(https%3A%2F%2Fwww.chebfun.org%2Fdocs%2Fguide%2Fguide06.html)%0A%20%20%20%20by%20L.%20N.%20Trefethen%20(2009%2C%20revised%202019).%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%20import%20Quasimatrix%2C%20chebfun%2C%20polyfit%0A%20%20%20%20return%20Quasimatrix%2C%20chebfun%2C%20polyfit%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%20Quasimatrices%20and%20Continuous%20Linear%20Algebra%0A%0A%20%20%20%20Numerical%20linear%20algebra%20operates%20on%20matrices%20%E2%80%94%20rectangular%20arrays%20of%0A%20%20%20%20numbers.%20%20But%20many%20of%20the%20same%20ideas%20(QR%2C%20SVD%2C%20least-squares%2C%20norms)%0A%20%20%20%20make%20perfect%20sense%20when%20the%20%22rows%22%20are%20continuous%3A%20each%20column%20is%20a%0A%20%20%20%20*function*%20rather%20than%20a%20finite%20vector%20of%20samples.%0A%0A%20%20%20%20A%20**quasimatrix**%20is%20exactly%20this%20object%3A%20an%20%24%5Cinfty%20%5Ctimes%20n%24%20matrix%0A%20%20%20%20whose%20%24n%24%20columns%20are%20chebfuns%20on%20a%20common%20interval.%20%20ChebPy's%0A%20%20%20%20%60Quasimatrix%60%20class%20lets%20you%20manipulate%20them%20with%20familiar%20linear%0A%20%20%20%20algebra%20syntax.%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%20Building%20a%20quasimatrix%0A%0A%20%20%20%20The%20simplest%20example%3A%20stack%20the%20first%20six%20monomials%0A%20%20%20%20%241%2C%20x%2C%20x%5E2%2C%20%5Cldots%2C%20x%5E5%24%20on%20%24%5B-1%2C1%5D%24%20into%20a%20single%20object.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Quasimatrix%2C%20chebfun)%3A%0A%20%20%20%20x%20%3D%20chebfun(%22x%22)%0A%20%20%20%20A%20%3D%20Quasimatrix(%5B1%2C%20x%2C%20x**2%2C%20x**3%2C%20x**4%2C%20x**5%5D)%0A%20%20%20%20print(%22shape%3A%22%2C%20A.shape)%0A%20%20%20%20print(%22A(0.5%2C%202)%20%3D%22%2C%20A%5B0.5%2C%202%5D)%20%20%23%20x%C2%B2%20evaluated%20at%200.5%0A%20%20%20%20return%20A%2C%20x%0A%0A%0A%40app.cell%0Adef%20_(A)%3A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20A.plot(ax%3D_ax)%0A%20%20%20%20_ax.set_ylim(-1.1%2C%201.1)%0A%20%20%20%20_ax.grid(True)%0A%20%20%20%20_ax.set_title(%22Columns%20of%20A%20%3D%20%5B1%2C%20x%2C%20x%C2%B2%2C%20x%C2%B3%2C%20x%E2%81%B4%2C%20x%E2%81%B5%5D%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%20Because%20integration%20is%20the%20continuous%20analogue%20of%20summation%2C%20the%20column%0A%20%20%20%20sums%20of%20%24A%24%20are%20the%20integrals%20%24%5Cint_%7B-1%7D%5E%7B1%7D%20x%5Ek%20%5C%2C%20dx%24%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A)%3A%0A%20%20%20%20print(A.sum())%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%20Inner%20products%20and%20the%20Gram%20matrix%0A%0A%20%20%20%20The%20inner%20product%20of%20two%20column%20chebfuns%20is%0A%20%20%20%20%24%5Clangle%20f%2C%20g%20%5Crangle%20%3D%20%5Cint_%7B-1%7D%5E%7B1%7D%20f(x)%5C%2Cg(x)%5C%2Cdx%24.%0A%20%20%20%20For%20example%2C%20%24%5Clangle%20x%5E2%2C%20x%5E4%20%5Crangle%20%3D%202%2F7%24%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A)%3A%0A%20%20%20%20ip%20%3D%20A%5B%3A%2C%202%5D.dot(A%5B%3A%2C%204%5D)%0A%20%20%20%20print(f%22%E2%9F%A8x%C2%B2%2C%20x%E2%81%B4%E2%9F%A9%20%3D%20%7Bip%3A.15f%7D%20%20(exact%20%3D%20%7B2%20%2F%207%3A.15f%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%20Gram%20matrix%20%24G%20%3D%20A%5E%5Ctop%5C!A%24%20collects%20all%20pairwise%20inner%20products%0A%20%20%20%20into%20a%20single%20%24n%20%5Ctimes%20n%24%20matrix.%20%20Because%20the%20monomials%20are%20far%20from%0A%20%20%20%20orthogonal%2C%20%24G%24%20is%20far%20from%20the%20identity%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A)%3A%0A%20%20%20%20G%20%3D%20A.T%20%40%20A%0A%20%20%20%20print(np.round(G%2C%204))%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%20Least-squares%20fitting%0A%0A%20%20%20%20Given%20a%20quasimatrix%20%24A%24%20and%20a%20target%20function%20%24f%24%2C%20we%20can%20solve%20the%0A%20%20%20%20continuous%20least-squares%20problem%0A%0A%20%20%20%20%24%24%5Cmin_%7B%5Cmathbf%7Bc%7D%7D%20%5C%7C%20A%5Cmathbf%7Bc%7D%20-%20f%20%5C%7C_2%24%24%0A%0A%20%20%20%20with%20%60A.solve(f)%60.%20%20This%20is%20the%20continuous%20analogue%20of%20the%20matrix%0A%20%20%20%20backslash%20operator.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A%2C%20x)%3A%0A%20%20%20%20f%20%3D%20np.exp(x)%20*%20np.sin(6%20*%20x)%0A%20%20%20%20c%20%3D%20A.solve(f)%0A%20%20%20%20print(%22Least-squares%20coefficients%20c%3A%22)%0A%20%20%20%20print(c)%0A%20%20%20%20return%20c%2C%20f%0A%0A%0A%40app.cell%0Adef%20_(A%2C%20c%2C%20f)%3A%0A%20%20%20%20ffit%20%3D%20A%20%40%20c%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20f.plot(ax%3D_ax%2C%20label%3D%22f%22%2C%20linewidth%3D2)%0A%20%20%20%20ffit.plot(ax%3D_ax%2C%20label%3D%22%24%5C%5Ctilde%7Bf%7D%24%22%2C%20linestyle%3D%22--%22%2C%20color%3D%22r%22)%0A%20%20%20%20_ax.legend()%0A%20%20%20%20_ax.grid(True)%0A%20%20%20%20_ax.set_title(f%22Degree-5%20least-squares%20fit%20%20(error%20%3D%20%7B(f%20-%20ffit).norm(2)%3A.4f%7D)%22)%0A%20%20%20%20_fig%0A%20%20%20%20return%20(ffit%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%20convenience%20wrapper%20%60polyfit(f%2C%20n)%60%20does%20the%20same%20thing%20in%20one%20call%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(f%2C%20ffit%2C%20polyfit)%3A%0A%20%20%20%20ffit2%20%3D%20polyfit(f%2C%205)%0A%20%20%20%20print(f%22%E2%80%96ffit%20%E2%88%92%20polyfit(f%2C%205)%E2%80%96%20%3D%20%7B(ffit%20-%20ffit2).norm(2)%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%23%20Beyond%20polynomials%3A%20a%20hat-function%20basis%0A%0A%20%20%20%20Quasimatrix%20columns%20need%20not%20be%20polynomials.%20%20Here%20we%20construct%2011%0A%20%20%20%20piecewise-linear%20hat%20functions%20centred%20at%20equally%20spaced%20points%20on%0A%20%20%20%20%24%5B-1%2C%201%5D%24%20and%20use%20them%20as%20a%20finite-element-style%20basis%20for%0A%20%20%20%20least-squares%20fitting.%20%20All%20columns%20share%20the%20same%20breakpoints%20so%0A%20%20%20%20their%20domains%20match%20in%20arithmetic.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Quasimatrix%2C%20chebfun%2C%20f)%3A%0A%20%20%20%20_bkpts%20%3D%20%5Bround(-1%20%2B%20_k%20*%200.2%2C%2010)%20for%20_k%20in%20range(11)%5D%0A%20%20%20%20hat_cols%20%3D%20%5B%5D%0A%20%20%20%20for%20_j%20in%20range(11)%3A%0A%20%20%20%20%20%20%20%20_xj%20%3D%20round(-1%20%2B%20_j%20*%200.2%2C%2010)%0A%20%20%20%20%20%20%20%20hat_cols.append(chebfun(lambda%20t%2C%20__xj%3D_xj%3A%20np.maximum(0%2C%201%20-%205%20*%20np.abs(t%20-%20__xj))%2C%20_bkpts))%0A%20%20%20%20A2%20%3D%20Quasimatrix(hat_cols)%0A%0A%20%20%20%20_fig%2C%20_axes%20%3D%20plt.subplots(2%2C%201%2C%20figsize%3D(8%2C%206)%2C%20height_ratios%3D(1%2C%202))%0A%20%20%20%20A2.plot(ax%3D_axes%5B0%5D)%0A%20%20%20%20_axes%5B0%5D.set_title(%22Hat-function%20basis%22)%0A%20%20%20%20_axes%5B0%5D.grid(True)%0A%20%20%20%20_axes%5B0%5D.tick_params(labelbottom%3DFalse)%0A%0A%20%20%20%20c2%20%3D%20A2.solve(f)%0A%20%20%20%20ffit_hat%20%3D%20A2%20%40%20c2%0A%20%20%20%20f.plot(ax%3D_axes%5B1%5D%2C%20label%3D%22f%22%2C%20linewidth%3D2)%0A%20%20%20%20ffit_hat.plot(ax%3D_axes%5B1%5D%2C%20label%3D%22%24%5C%5Ctilde%7Bf%7D%24%22%2C%20linestyle%3D%22--%22%2C%20color%3D%22r%22)%0A%20%20%20%20_axes%5B1%5D.legend()%0A%20%20%20%20_axes%5B1%5D.grid(True)%0A%20%20%20%20_axes%5B1%5D.set_title(f%22Hat-function%20fit%20%20(error%20%3D%20%7B(f%20-%20ffit_hat).norm(2)%3A.4f%7D)%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%20QR%20factorisation%0A%0A%20%20%20%20The%20reduced%20QR%20factorisation%20%24A%20%3D%20QR%24%20produces%20an%20%24%5Cinfty%20%5Ctimes%20n%24%0A%20%20%20%20quasimatrix%20%24Q%24%20whose%20columns%20are%20orthonormal%20in%20%24L%5E2%24%20and%20an%0A%20%20%20%20%24n%20%5Ctimes%20n%24%20upper-triangular%20factor%20%24R%24.%0A%0A%20%20%20%20When%20the%20input%20columns%20are%20the%20monomials%20%241%2C%20x%2C%20%5Cldots%2C%20x%5En%24%2C%0A%20%20%20%20Gram%E2%80%93Schmidt%20orthogonalisation%20recovers%20the%20**Legendre%20polynomials**%0A%20%20%20%20(up%20to%20%24L%5E2%24%20normalisation).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A)%3A%0A%20%20%20%20Q%2C%20R%20%3D%20A.qr()%0A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20Q.plot(ax%3D_ax)%0A%20%20%20%20_ax.grid(True)%0A%20%20%20%20_ax.set_title(%22Columns%20of%20Q%20%20(L%C2%B2-normalised%20Legendre%20polynomials)%22)%0A%20%20%20%20_fig%0A%20%20%20%20return%20Q%2C%20R%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%20orthonormality%20relation%20%24Q%5E%5Ctop%20Q%20%3D%20I%24%20holds%20to%20machine%20precision%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Q)%3A%0A%20%20%20%20QTQ%20%3D%20Q.T%20%40%20Q%0A%20%20%20%20print(%22Q%5ET%20Q%3A%22)%0A%20%20%20%20print(np.round(QTQ%2C%2010))%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%20If%20we%20rescale%20each%20column%20so%20that%20%24P_k(1)%20%3D%201%24%2C%20we%20recover%20the%0A%20%20%20%20standard%20Legendre%20polynomials.%20%20The%20inverse%20of%20the%20rescaled%20%24R%24%0A%20%20%20%20then%20holds%20the%20monomial%20expansion%20coefficients%20%E2%80%94%20for%20instance%0A%20%20%20%20%24P_3(x)%20%3D%20%5Ctfrac%7B5%7D%7B2%7Dx%5E3%20-%20%5Ctfrac%7B3%7D%7B2%7Dx%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Q%2C%20R)%3A%0A%20%20%20%20R_leg%20%3D%20R.copy()%0A%20%20%20%20Q_leg_cols%20%3D%20%5Bcol.copy()%20for%20col%20in%20Q.columns%5D%0A%20%20%20%20for%20_j%20in%20range(len(Q_leg_cols))%3A%0A%20%20%20%20%20%20%20%20_v%20%3D%20float(Q_leg_cols%5B_j%5D(1.0))%0A%20%20%20%20%20%20%20%20R_leg%5B_j%2C%20%3A%5D%20*%3D%20_v%0A%20%20%20%20%20%20%20%20Q_leg_cols%5B_j%5D%20%3D%20(1.0%20%2F%20_v)%20*%20Q_leg_cols%5B_j%5D%0A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20from%20chebpy.quasimatrix%20import%20Quasimatrix%20as%20_QM%0A%0A%20%20%20%20_QM(Q_leg_cols).plot(ax%3D_ax)%0A%20%20%20%20_ax.grid(True)%0A%20%20%20%20_ax.set_title(%22Legendre%20polynomials%20P%E2%82%80%2C%20P%E2%82%81%2C%20%E2%80%A6%2C%20P%E2%82%85%20%20(normalised%20so%20P(1)%20%3D%201)%22)%0A%0A%20%20%20%20print(%22inv(R)%20%E2%80%94%20monomial%20coefficients%20of%20Legendre%20polynomials%3A%22)%0A%20%20%20%20print(np.round(np.linalg.inv(R_leg)%2C%204))%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%20SVD%2C%20norms%2C%20and%20condition%20numbers%0A%0A%20%20%20%20The%20singular%20value%20decomposition%20%24A%20%3D%20U%20%5CSigma%20V%5E%5Ctop%24%20generalises%0A%20%20%20%20naturally%20to%20quasimatrices.%20%20The%20singular%20values%20tell%20us%20about%20the%0A%20%20%20%20%22geometry%22%20of%20the%20column%20space%3A%20how%20much%20the%20quasimatrix%20stretches%0A%20%20%20%20or%20compresses%20different%20directions.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A)%3A%0A%20%20%20%20_U%2C%20S%2C%20V%20%3D%20A.svd()%0A%20%20%20%20print(%22Singular%20values%3A%22)%0A%20%20%20%20print(S)%0A%20%20%20%20print(f%22%5Cn%E2%80%96A%E2%80%96%E2%82%82%20%20%20%20%3D%20%7BA.norm(2)%3A.15f%7D%22)%0A%20%20%20%20print(f%22cond(A)%20%3D%20%7BA.cond()%3A.15f%7D%22)%0A%20%20%20%20return%20(V%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%20first%20and%20last%20right%20singular%20vectors%20%24v_1%24%20and%20%24v_n%24%20tell%20us%0A%20%20%20%20which%20coefficient%20vectors%20produce%20the%20largest%20and%20smallest%20functions%0A%20%20%20%20in%20%24L%5E2%24.%20%20Multiplying%20%24A%24%20by%20these%20vectors%20gives%20the%0A%20%20%20%20**extreme%20singular%20functions**%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A%2C%20V)%3A%0A%20%20%20%20_v1%20%3D%20V%5B%3A%2C%200%5D%0A%20%20%20%20_vn%20%3D%20V%5B%3A%2C%20-1%5D%0A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20(A%20%40%20_v1).plot(ax%3D_ax%2C%20label%3D%22Av%E2%82%81%20%20(largest)%22)%0A%20%20%20%20(A%20%40%20_vn).plot(ax%3D_ax%2C%20label%3D%22Av%E2%82%99%20%20(smallest)%22)%0A%20%20%20%20_ax.legend()%0A%20%20%20%20_ax.grid(True)%0A%20%20%20%20_ax.set_title(%22Extreme%20singular%20functions%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%20Several%20matrix%20norms%20extend%20directly%20to%20the%20quasimatrix%20setting%3A%0A%0A%20%20%20%20%7C%20Norm%20%7C%20Definition%20%7C%20Value%20%7C%0A%20%20%20%20%7C---%7C---%7C---%7C%0A%20%20%20%20%7C%201-norm%20%7C%20%24%5Cmax_j%20%5ClVert%20A_j%20%5CrVert_1%24%20%7C%20maximum%20column%20%24L%5E1%24%20norm%20%7C%0A%20%20%20%20%7C%20%24%5Cinfty%24-norm%20%7C%20%24%5Cmax_x%20%5Csum_j%20%5Clvert%20A_j(x)%5Crvert%24%20%7C%20maximum%20absolute%20row%20sum%20%7C%0A%20%20%20%20%7C%20Frobenius%20%7C%20%24%5Cbigl(%5Csum_k%20%5Csigma_k%5E2%5Cbigr)%5E%7B1%2F2%7D%24%20%7C%20Hilbert%E2%80%93Schmidt%20norm%20%7C%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A)%3A%0A%20%20%20%20print(f%22%E2%80%96A%E2%80%96%E2%82%81%20%20%20%3D%20%7BA.norm(1)%7D%22)%0A%20%20%20%20print(f%22%E2%80%96A%E2%80%96_%E2%88%9E%20%20%3D%20%7BA.norm(np.inf)%7D%22)%0A%20%20%20%20print(f%22%E2%80%96A%E2%80%96_F%20%20%3D%20%7BA.norm('fro')%3A.15f%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%20Rank%2C%20null%20space%2C%20and%20pseudoinverse%0A%0A%20%20%20%20Three%20functions%20that%20live%20on%20the%20same%20interval%20can%20still%20be%20linearly%0A%20%20%20%20*dependent*.%20%20The%20Pythagorean%20identity%20%24%5Csin%5E2%20x%20%2B%20%5Ccos%5E2%20x%20%3D%201%24%0A%20%20%20%20means%20the%20quasimatrix%20%24B%20%3D%20%5B1%2C%5C%3B%20%5Csin%5E2%20x%2C%5C%3B%20%5Ccos%5E2%20x%5D%24%20has%20rank%202%0A%20%20%20%20and%20a%20one-dimensional%20null%20space.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Quasimatrix%2C%20x)%3A%0A%20%20%20%20B%20%3D%20Quasimatrix(%5B1%2C%20np.sin(x)%20**%202%2C%20np.cos(x)%20**%202%5D)%0A%20%20%20%20print(f%22rank(B)%20%3D%20%7BB.rank()%7D%22)%0A%20%20%20%20print(f%22%5Cnnull(B)%20%3D%5Cn%7BB.null()%7D%22)%0A%20%20%20%20return%20(B%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%20null%20vector%20%24%5B-1%2F%5Csqrt%7B3%7D%2C%5C%3B%201%2F%5Csqrt%7B3%7D%2C%5C%3B%201%2F%5Csqrt%7B3%7D%5D%24%0A%20%20%20%20encodes%20exactly%20the%20identity%20%24%5Csin%5E2%20x%20%2B%20%5Ccos%5E2%20x%20-%201%20%3D%200%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(B)%3A%0A%20%20%20%20O%20%3D%20B.orth()%0A%20%20%20%20print(f%22orth(B)%20shape%3A%20%7BO.shape%7D%22)%0A%20%20%20%20print(f%22Orthonormality%20check%20(O%5ET%20O)%3A%5Cn%7Bnp.round(O.T%20%40%20O%2C%2010)%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%20pseudoinverse%20maps%20a%20function%20%24f%24%20to%20the%20least-squares%0A%20%20%20%20coefficients%2C%20so%20%60pinv(A)%20%40%20f%60%20and%20%60A.solve(f)%60%20agree%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A%2C%20f)%3A%0A%20%20%20%20P%20%3D%20A.pinv()%0A%20%20%20%20c_solve%20%3D%20A.solve(f)%0A%20%20%20%20c_pinv%20%3D%20P%20%40%20f%0A%20%20%20%20print(f%22%E2%80%96A.solve(f)%20%E2%88%92%20pinv(A)%20%40%20f%E2%80%96%20%3D%20%7Bnp.linalg.norm(c_solve%20-%20c_pinv)%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%20Why%20orthogonal%20bases%20matter%0A%0A%20%20%20%20The%20monomial%20basis%20%24%5C%7B1%2C%20x%2C%20%5Cldots%2C%20x%5En%5C%7D%24%20becomes%20spectacularly%0A%20%20%20%20ill-conditioned%20as%20%24n%24%20grows%20%E2%80%94%20the%20condition%20number%20grows%0A%20%20%20%20exponentially.%20%20This%20is%20precisely%20why%20orthogonal%20polynomial%20bases%0A%20%20%20%20(Legendre%2C%20Chebyshev)%20are%20preferred%20in%20practice.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Quasimatrix%2C%20x)%3A%0A%20%20%20%20_conds%20%3D%20%5B%5D%0A%20%20%20%20_ns%20%3D%20range(1%2C%2016)%0A%20%20%20%20for%20_n%20in%20_ns%3A%0A%20%20%20%20%20%20%20%20_cols%20%3D%20%5Bx**_k%20for%20_k%20in%20range(_n%20%2B%201)%5D%0A%20%20%20%20%20%20%20%20from%20chebpy%20import%20chebfun%20as%20_cf%0A%0A%20%20%20%20%20%20%20%20_cols%5B0%5D%20%3D%20_cf(1.0)%0A%20%20%20%20%20%20%20%20_An%20%3D%20Quasimatrix(_cols)%0A%20%20%20%20%20%20%20%20_conds.append(_An.cond())%0A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots()%0A%20%20%20%20_ax.semilogy(list(_ns)%2C%20_conds%2C%20%22o-%22)%0A%20%20%20%20_ax.set_xlabel(%22n%22)%0A%20%20%20%20_ax.set_ylabel(%22cond(A)%22)%0A%20%20%20%20_ax.set_title(%22Condition%20number%20of%20the%20monomial%20quasimatrix%22)%0A%20%20%20%20_ax.grid(True)%0A%20%20%20%20_fig%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
c3d82372e8d1f0460623674797f8c99d