Buckets:
| import sympy as sym | |
| import numpy as np | |
| from numpy import linspace, tanh, pi, sin | |
| import matplotlib.pyplot as plt | |
| import scipy.integrate | |
| def least_square(f, psi, Omega): | |
| N = len(psi) - 1 | |
| A = sym.zeros(N + 1, N + 1) | |
| b = sym.zeros(N + 1, 1) | |
| x = sym.Symbol('x') | |
| for i in range(N + 1): | |
| for j in range(i, N + 1): | |
| A[i, j] = sym.integrate(psi[i] * psi[j], (x, Omega[0], Omega[1])) | |
| A[j, i] = A[i, j] # Symmetric matrix | |
| b[i, 0] = sym.integrate(f * psi[i], (x, Omega[0], Omega[1])) | |
| c = A.LUsolve(b) | |
| u = 0 | |
| for i in range(N + 1): | |
| u += c[i, 0] * psi[i] | |
| return u, c | |
| def regression(f, psi, points): | |
| N = len(psi) - 1 | |
| m = len(points) | |
| # Convert to numpy arrays for vectorized operations | |
| points = np.array(points) | |
| # Create lambda functions | |
| x = sym.Symbol('x') | |
| f_f = sym.lambdify([x], f, modules='numpy') | |
| psi_f = [sym.lambdify([x], psi[i], modules='numpy') for i in range(N + 1)] | |
| # Build psi_matrix properly - ensure all outputs are 1D arrays of the same length | |
| psi_matrix = np.zeros((m, N + 1)) | |
| for i in range(N + 1): | |
| psi_val = psi_f[i](points) | |
| # Ensure we have a 1D array of the correct length | |
| if np.isscalar(psi_val): | |
| psi_matrix[:, i] = psi_val # Broadcast scalar to all points | |
| else: | |
| psi_matrix[:, i] = psi_val.flatten()[:m] # Take first m elements | |
| # Evaluate f at all points | |
| f_values = f_f(points) | |
| # Build normal equations: B = psi_matrix^T @ psi_matrix, d = psi_matrix^T @ f_values | |
| B = psi_matrix.T @ psi_matrix | |
| d = psi_matrix.T @ f_values.reshape(-1, 1) | |
| # Solve for coefficients | |
| c = np.linalg.solve(B, d) | |
| # Build approximation function | |
| u = sum(c[i, 0] * psi[i] for i in range(N + 1)) | |
| return u, c | |
| def comparison_plot(f, u, Omega, filename='tmp.pdf'): | |
| x = sym.Symbol('x') | |
| f_f = sym.lambdify([x], f, modules='numpy') | |
| u_f = sym.lambdify([x], u, modules='numpy') | |
| resolution = 401 | |
| xcoor = linspace(Omega[0], Omega[1], resolution) | |
| exact = f_f(xcoor) | |
| approx = u_f(xcoor) | |
| plt.plot(xcoor, approx) | |
| plt.plot(xcoor, exact) | |
| plt.legend(['approximation', 'exact']) | |
| plt.savefig(filename) | |
| plt.close() | |
| def traperzoidal(values, dx): | |
| return dx * (np.sum(values) - 0.5 * (values[0] + values[-1])) | |
| def least_squares_numerical(f, psi, N, x, integration_method='scipy', orthogonal_basis=False): | |
| A = np.zeros((N + 1, N + 1)) | |
| b = np.zeros(N + 1) | |
| Omega = [x[0], x[-1]] | |
| dx = x[1] - x[0] | |
| for i in range(N + 1): | |
| j_limit = i + 1 if orthogonal_basis else N + 1 | |
| for j in range(i, j_limit): | |
| print('(%d,%d)' % (i, j)) | |
| if integration_method == 'scipy': | |
| def integrand_ij(x_val): | |
| return psi(x_val, i) * psi(x_val, j) | |
| A_ij = scipy.integrate.quad(integrand_ij, Omega[0], Omega[1], | |
| epsabs=1e-9, epsrel=1e-9)[0] | |
| elif integration_method == 'sympy': | |
| def integrand_ij(x_val): | |
| return psi(x_val, i) * psi(x_val, j) | |
| A_ij = scipy.integrate.quad(integrand_ij, Omega[0], Omega[1])[0] | |
| else: | |
| values = psi(x, i) * psi(x, j) | |
| A_ij = traperzoidal(values, dx) | |
| A[i, j] = A_ij | |
| if i != j: | |
| A[j, i] = A_ij | |
| # Compute b[i] | |
| if integration_method in ['scipy', 'sympy']: | |
| def integrand_b(x_val): | |
| return f(x_val) * psi(x_val, i) | |
| b_i = scipy.integrate.quad(integrand_b, Omega[0], Omega[1], | |
| epsabs=1e-9, epsrel=1e-9)[0] | |
| else: | |
| values = f(x) * psi(x, i) | |
| b_i = traperzoidal(values, dx) | |
| b[i] = b_i | |
| # Solve for coefficients | |
| if orthogonal_basis: | |
| c = b / np.diag(A) | |
| else: | |
| c = np.linalg.solve(A, b) | |
| def Lagrange_polynomials(x,i,points): | |
| p=1 | |
| for k in range(len(points)): | |
| if k!=i: | |
| p*=(x-points[k])/(points[i]-points[k]) | |
| return p | |
| def Lagrange_polynomials_01(x,N): | |
| if isinstance(x,sym.Symbol): | |
| h= sym.Rational(1,N-1) | |
| else: | |
| h=1.0/(N-1) | |
| points=[i*h for i in range(N)] | |
| psi=[Lagrange_polynomials(x,i, points) for i in range(N)] | |
| return psi, points | |
| # Build the approximation function | |
| def u_func(x_vals): | |
| result = np.zeros_like(x_vals) | |
| for i in range(N + 1): | |
| result += c[i] * psi(x_vals, i) | |
| return result | |
| u = u_func(x) | |
| return u, c | |
| def save_plot_to_file(x, exact_func, approx_values, filename='least_squares_approximation.pdf'): | |
| """Save the comparison plot to a file""" | |
| plt.figure(figsize=(10, 6)) | |
| plt.plot(x, exact_func(x), 'b-', linewidth=2, label='Exact: tanh(x-pi)') | |
| plt.plot(x, approx_values, 'r--', linewidth=2, label='Approximation') | |
| plt.xlabel('x') | |
| plt.ylabel('f(x)') | |
| plt.legend() | |
| plt.title('Least Squares Approximation') | |
| plt.grid(True) | |
| # Save to file | |
| plt.savefig(filename, dpi=300, bbox_inches='tight') | |
| plt.close() | |
| print(f"Plot saved as {filename}") | |
| def interpolation(f, psi, points): | |
| N = len(psi) - 1 | |
| A = sym.zeros(N+1, N+1) | |
| b = sym.zeros(N+1, 1) | |
| psi_sym = psi # save symbolic expression | |
| # Turn psi and f into Python functions | |
| x = sym.Symbol('x') | |
| psi = [] | |
| for i in range(N+1): | |
| psi.append(sym.lambdify([x], psi_sym[i])) | |
| f_f = sym.lambdify([x], f) | |
| for i in range(N+1): | |
| for j in range(N+1): | |
| A[i,j] = psi[j](points[i]) | |
| b[i,0] = f_f(points[i]) | |
| c = A.LUsolve(b) | |
| # c is a sympy Matrix object, turn to list | |
| c = [sym.simplify(c[i,0]) for i in range(c.shape[0])] | |
| u = sym.simplify(sum(c[i]*psi_sym[i] for i in range(N+1))) | |
| return u, c | |
| # Test the function | |
| def psi(x, i): | |
| return np.sin((i + 1) * x) | |
| # Create sample data | |
| # x = linspace(0, 2 * pi, 501) | |
| # N = 10 # Reduced for better stability | |
| # f_func = lambda x: tanh(x - pi) | |
| # # Call the function - using trapezoidal method for array-based computation | |
| # u, c = least_squares_numerical(f_func, psi, N, x, | |
| # integration_method='trapezoidal', | |
| # orthogonal_basis=False) | |
| # # Save the plot to a file | |
| # save_plot_to_file(x, f_func, u, 'least_squares_approximation.pdf') | |
| # # You can also save in different formats | |
| # save_plot_to_file(x, f_func, u, 'least_squares_approximation.png') # PNG format | |
| # save_plot_to_file(x, f_func, u, 'least_squares_approximation.jpg') # JPG format | |
| # print("Coefficients:", c) | |
| # print("Plot has been saved to 'least_squares_approximation.pdf'") | |
| x=sym.Symbol('x') | |
| # f=10*(x-1)**2-1 | |
| # psi=[1,x] | |
| # Omega=[1,2] | |
| # m_values=[2-1,8-1,64-1] | |
| # # Create m+3 points and use the inner m+1 points | |
| # for m in m_values: | |
| # points=np.linspace(Omega[0],Omega[1],m+3)[1:-1] | |
| # u,c=regression(f,psi,points) | |
| # filename='regression_m=%d.pdf'%m | |
| # comparison_plot(f,u,Omega,filename) | |
| # x=0.5 | |
| # psi, points= Lagrange_polynomials_01(x,N=3) | |
| # print(psi) | |
| # print(points) | |
| # for N in [2, 4, 5, 6, 8, 10, 12]: | |
| # f = x**2 | |
| # psi, points = Lagrange_polynomials_01(x, N) | |
| # u=interpolation(f, psi, points) | |
| # comparison_plot(f, u, [0, 1], filename='interpolation_f=x^2_N=%d.pdf'%N) | |
| # f = sym.sin(2*sym.pi*x) | |
| # N=4 | |
| # f = sym.sin(2*sym.pi*x) | |
| # psi, points = Lagrange_polynomials_01(x, N) | |
| # Omega=[0, 1] | |
| # u, c = least_square(f, psi, Omega) | |
| # comparison_plot(f, u, Omega) | |
| # u, c = interpolation(f, psi, points) | |
| # comparison_plot(f, u, Omega) |
Xet Storage Details
- Size:
- 7.7 kB
- Xet hash:
- 42e985899e72620d3f0933f88144a674c6eb62d67316e66aa50e6393b2deeacd
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.