HOUSEHOLDER

import math import scipy.linalg as sla import numpy as np import matplotlib.pyplot as plt from math import copysign, hypot #hypot = euclidian norm from numpy import linalg %matplotlib inline N = 7 M = 4 def func(x): return x*math.sin(x) x = np.zeros(shape=(M), dtype=np.float128(0.)) y = np.zeros(shape=(M), dtype=np.float128(0.)) for i in range(0, M): x[i] = -1. + 2. / (M - 1) * i y[i] = func(x[i]) #Матрица степеней полиномов Лежандра G = np.zeros((max(2, N), max(2, N)), dtype=np.float128(0.)) G[0][0] = 1 # g_0 = 1*x^0 G[1][1] = 1 # g_1 = 1*x^1 for i in range(2, N): # np.roll - Roll array elements along a given axis. G[i] = (np.roll(G[i - 1], 1) * (2 * i - 1.) - (i - 1) * G[i - 2]) / i px = np.zeros((max(2, N), M), dtype=np.float128(0.)) for i in range(0, M): px[0][i] = 1. for i in range(1, N): for j in range(0, M): px[i][j] = px[i - 1][j] * x[j] #print(px) G_px = np.dot(G,px) #print(G_px) def householder_reflection(A, b): (num_rows, num_cols) = np.shape(A) R = np.copy(A) for cnt in range(num_rows - 1): x = R[cnt:, cnt] e = np.zeros_like(x) e[0] = copysign(np.linalg.norm(x), -A[cnt, cnt]) u = x + e v = u / np.linalg.norm(u) Q_cnt = np.identity(num_rows) Q_cnt[cnt:, cnt:] -= 2.0 * np.outer(v, v) R = np.dot(Q_cnt, R) b = np.dot(Q_cnt, b) return (R, b) A = G_px.dot(G_px.T) # A = ggT - Gram's matrix b = G_px.dot(y.T) # b = gyT - also mult the b vector (AA, bb) = householder_reflection(A, b) # QR decomp of original system ans = sla.solve_triangular(AA, bb) #вычисление функци Psi for i in range(0, N): G[i] *= ans[i] #вычисление Psi(x) для данного x def G_at_x(x): w = np.zeros(shape=(N), dtype=np.float128(0.)) w[0] = 1. for i in range(1, N): w[i] = w[i - 1] * x #строка степеней x return np.sum(np.dot(G,w)) #значение Psi в точке х eps = 1e-4 drawx = np.arange(x[0], x[M - 1], eps) #построение графика def get_graph(xx, f): drawy = np.array(xx) for i in range(0, drawy.shape[0]): drawy[i] = f(drawx[i]) return drawy plt.figure(num=None, figsize=(12,10), dpi=200, facecolor='w', edgecolor='k') #отрисовка Psi drawy = get_graph(drawx, G_at_x) curve1, = plt.plot(drawx, drawy, 'm-', linewidth=1.) #отрисовка исходной функции drawy = get_graph(drawx, func) curve2, = plt.plot(drawx, drawy, 'g-', linewidth=1.) #узлы curve3, = plt.plot(x, y, 'ko') plt.legend(("Psi", "Function"),loc='upper right') plt.setp(curve1, linewidth=3) plt.setp(curve2, linewidth=3) plt.title('Approximation Results') plt.show()

Be the first to comment

You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.