Buckets:
| """ | |
| Approximation of functions by linear combination of basis functions in | |
| function spaces and the least squares method (or the Galerkin method). | |
| 2D version. | |
| """ | |
| import sympy as sym | |
| import numpy as np | |
| def least_squares(f, psi, Omega, symbolic=True, print_latex=False): | |
| """ | |
| Given a function f(x,y) on a rectangular domain | |
| Omega=[[xmin,xmax],[ymin,ymax]], | |
| return the best approximation to f(x,y) in the space V | |
| spanned by the functions in the list psi. | |
| """ | |
| N = len(psi) - 1 | |
| A = sym.zeros((N+1, N+1)) | |
| b = sym.zeros((N+1, 1)) | |
| x, y = sym.symbols('x y') | |
| print ('...evaluating matrix...') | |
| for i in range(N+1): | |
| for j in range(i, N+1): | |
| print ('(%d,%d)' % (i, j)) | |
| integrand = psi[i]*psi[j] | |
| if symbolic: | |
| I = sym.integrate(integrand, | |
| (x, Omega[0][0], Omega[0][1]), | |
| (y, Omega[1][0], Omega[1][1])) | |
| if not symbolic or isinstance(I, sym.Integral): | |
| # Could not integrate symbolically, use numerical int. | |
| print ('numerical integration of', integrand) | |
| integrand = sym.lambdify([x,y], integrand) | |
| I = sym.mpmath.quad(integrand, | |
| [Omega[0][0], Omega[0][1]], | |
| [Omega[1][0], Omega[1][1]]) | |
| A[i,j] = A[j,i] = I | |
| integrand = psi[i]*f | |
| if symbolic: | |
| I = sym.integrate(integrand, | |
| (x, Omega[0][0], Omega[0][1]), | |
| (y, Omega[1][0], Omega[1][1])) | |
| if not symbolic or isinstance(I, sym.Integral): | |
| # Could not integrate symbolically, use numerical int. | |
| print ('numerical integration of', integrand) | |
| integrand = sym.lambdify([x,y], integrand) | |
| I = sym.mpmath.quad(integrand, | |
| [Omega[0][0], Omega[0][1]], | |
| [Omega[1][0], Omega[1][1]]) | |
| b[i,0] = I | |
| print ('A:\n', A, '\nb:\n', b) | |
| if symbolic: | |
| c = A.LUsolve(b) # symbolic solve | |
| # c is a sympy Matrix object, numbers are in c[i,0] | |
| c = [c[i,0] for i in range(c.shape[0])] | |
| else: | |
| c = sym.mpmath.lu_solve(A, b) # numerical solve | |
| print ('coeff:', c) | |
| u = sum(c[i]*psi[i] for i in range(len(psi))) | |
| print ('approximation:', u) | |
| print ('f:', sym.expand(f)) | |
| if print_latex: | |
| print (sym.latex(A, mode='plain')) | |
| print (sym.latex(b, mode='plain')) | |
| print (sym.latex(c, mode='plain')) | |
| return u, c | |
| def comparison_plot(f, u, Omega, plotfile='tmp', title=''): | |
| """Compare f(x,y) and u(x,y) for x,y in Omega in a plot.""" | |
| x, y = sym.symbols('x y') | |
| f = sym.lambdify([x,y], f, modules="numpy") | |
| u = sym.lambdify([x,y], u, modules="numpy") | |
| # When doing symbolics, Omega can easily contain symbolic expressions, | |
| # assume .evalf() will work in that case to obtain numerical | |
| # expressions, which then must be converted to float before calling | |
| # linspace below | |
| for r in range(2): | |
| for s in range(2): | |
| if not isinstance(Omega[r][s], (int,float)): | |
| Omega[r][s] = float(Omega[r][s].evalf()) | |
| resolution = 41 # no of points in plot | |
| xcoor = np.linspace(Omega[0][0], Omega[0][1], resolution) | |
| ycoor = np.linspace(Omega[1][0], Omega[1][1], resolution) | |
| xv, yv = np.meshgrid(xcoor, ycoor) | |
| # Vectorized functions expressions does not work with | |
| # lambdify'ed functions without the modules="numpy" | |
| exact = f(xv, yv) | |
| approx = u(xv, yv) | |
| error = exact - approx | |
| import matplotlib.pyplot as plt | |
| plt.figure() | |
| contours = plt.contour(xv, yv, error, 8) # 8 contour lines | |
| plt.clabel(contours, inline=1, fontsize=10) # labels | |
| if title: plt.title(title) | |
| if plotfile: | |
| plt.savefig('%s_error_c.pdf' % plotfile) | |
| plt.savefig('%s_error_c.png' % plotfile) | |
| fig = plt.figure() | |
| from mpl_toolkits.mplot3d import Axes3D | |
| from matplotlib import cm | |
| #ax = fig.add_subplot(111) #, projection='3d') | |
| ax = fig.gca(projection='3d') | |
| surf = ax.plot_surface(xv, yv, error, rstride=1, cstride=1, | |
| cmap=cm.coolwarm, linewidth=0, | |
| antialiased=False) | |
| fig.colorbar(surf, shrink=0.5, aspect=5) | |
| if title: plt.title(title) | |
| if plotfile: | |
| plt.savefig('%s_error_s.pdf' % plotfile) | |
| plt.savefig('%s_error_s.png' % plotfile) | |
| plt.show() | |
| if __name__ == '__main__': | |
| print ('Module file not meant for execution.') | |
Xet Storage Details
- Size:
- 4.62 kB
- Xet hash:
- 7012d550264b00f90255509281caa0fcf1c7380fe1987a25442dbbd56849b206
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.