Advertisement
575

lab4_2

575
Oct 10th, 2022
1,242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.94 KB | None | 0 0
  1. # Вторая производная, выраженная через x, f, f'
  2. def ddf(x, f, df):
  3.     return np.tan(x)*df-2*f
  4.  
  5. # Точное решение
  6. def f(x):
  7.     return np.sin(x)+2-np.sin(x)*np.log((1+np.sin(x))/(1-np.sin(x)))
  8.  
  9. # Функция перед y'
  10. def p(x):
  11.     return -np.tan(x)
  12.  
  13. # Функция перед y
  14. def q(x):
  15.     return 2
  16.  
  17. # Функция в правой части уравнения
  18. def right_f(x):
  19.     return 0
  20.  
  21. def diff_right(BCondition, h, y):
  22.     return (BCondition['c']+(BCondition['b']/h)*y[-2]) / (BCondition['a']+(BCondition['b']/h))
  23.  
  24. def ShotingMethod(ddy, borders, eta1, eta2, BCondition1, BCondition2, h):
  25.     y0 = BCondition1['c']/BCondition1['a']
  26.     eps = 0.1*h
  27.     resolve1 = RungeKutta(ddy, borders, y0, eta1, h)[0]
  28.     resolve2 = RungeKutta(ddy, borders, y0, eta2, h)[0]
  29.     Phi1 = resolve1[-1] - diff_right(BCondition2, h, resolve1)
  30.     Phi2 = resolve2[-1] - diff_right(BCondition2, h, resolve2)
  31.     x = np.arange(borders[0], borders[1] + h, h)
  32.     plt.figure(figsize=(12, 7))
  33.     plt.plot(x, resolve1, '--', label='1 приближение', linewidth=1)
  34.     plt.plot(x, resolve2, '--', label='2 приближение', linewidth=1)
  35.     iter=2;
  36.     while abs(Phi2 - Phi1) > eps:
  37.         iter = iter + 1
  38.         temp = eta2
  39.         eta2 = eta2 - (eta2 - eta1) / (Phi2 - Phi1) * Phi2
  40.         eta1 = temp
  41.         resolve1 = RungeKutta(ddy, borders, y0, eta1, h)[0]
  42.         resolve2 = RungeKutta(ddy, borders, y0, eta2, h)[0]
  43.         Phi1 = resolve1[-1] - diff_right(BCondition2, h, resolve1)
  44.         Phi2 = resolve2[-1] - diff_right(BCondition2, h, resolve2)
  45.         plt.plot(x, resolve2, '--', label=f'{iter} приближение', linewidth=1)
  46.  
  47.     plt.grid()
  48.     plt.legend()
  49.     plt.show()
  50.     return RungeKutta(ddy, borders, y0, eta2, h)[0]
  51.  
  52. def FiniteDifferenceMethod(BCondition1, BCondition2, equation, borders, h):
  53.     x = np.arange(borders[0], borders[1] + h, h)
  54.     N = np.shape(x)[0]
  55.  
  56.     # Составляем СЛАУ
  57.     A = np.zeros((N, N))
  58.     b = np.zeros(N)
  59.     A[0][0] = BCondition1['a'] - BCondition1['b']/h
  60.     A[0][1] = BCondition1['b']/h
  61.     b[0] = BCondition1['c']
  62.     for i in range(1, N-1):
  63.         A[i][i-1] = 1/h**2 - equation['p'](x[i])/(2*h)
  64.         A[i][i] = -2/h**2 + equation['q'](x[i])
  65.         A[i][i+1] = 1/h**2 + equation['p'](x[i])/(2*h)
  66.         b[i] = equation['f'](x[i])
  67.     A[N-1][N-2] = -BCondition2['b']/h
  68.     A[N-1][N-1] = BCondition2['a'] + BCondition2['b']/h
  69.     b[N-1] = BCondition2['c']
  70.  
  71.     return Solve(A, b)
  72.  
  73. # Метод Рунге-Кутты решения задачи Коши
  74. def RungeKutta(ddy, borders, y0, z0, h):
  75.     x = np.arange(borders[0], borders[1] + h, h)
  76.     N = np.shape(x)[0]
  77.     y = np.zeros(N)
  78.     z = np.zeros(N)
  79.     y[0] = y0; z[0] = z0
  80.  
  81.     for i in range(N-1):
  82.         K1 = h * z[i]
  83.         L1 = h * ddy(x[i], y[i], z[i])
  84.         K2 = h * (z[i] + 0.5 * L1)
  85.         L2 = h * ddy(x[i] + 0.5 * h, y[i] + 0.5 * K1, z[i] + 0.5 * L1)
  86.         K3 = h * (z[i] + 0.5 * L2)
  87.         L3 = h * ddy(x[i] + 0.5 * h, y[i] + 0.5 * K2, z[i] + 0.5 * L2)
  88.         K4 = h * (z[i] + L3)
  89.         L4 = h * ddy(x[i] + h, y[i] + K3, z[i] + L3)
  90.         delta_y = (K1 + 2 * K2 + 2 * K3 + K4) / 6
  91.         delta_z = (L1 + 2 * L2 + 2 * L3 + L4) / 6
  92.         y[i+1] = y[i] + delta_y
  93.         z[i+1] = z[i] + delta_z
  94.  
  95.     return y, z
  96.  
  97. # Метод прогонки
  98. def Solve(A, b):
  99.     p = np.zeros(len(b))
  100.     q = np.zeros(len(b))
  101.  
  102.     # Прямой ход: поиск прогоночных коэффициентов P и Q
  103.     p[0] = -A[0][1]/A[0][0]
  104.     q[0] = b[0]/A[0][0]
  105.     for i in range(1, len(p)-1):
  106.         p[i] = -A[i][i+1]/(A[i][i] + A[i][i-1]*p[i-1])
  107.         q[i] = (b[i] - A[i][i-1]*q[i-1])/(A[i][i] + A[i][i-1]*p[i-1])
  108.  
  109.     p[-1] = 0
  110.     q[-1] = (b[-1] - A[-1][-2]*q[-2])/(A[-1][-1] + A[-1][-2]*p[-2])
  111.  
  112.     # Обратный ход: поиск x
  113.     x = np.zeros(len(b))
  114.     x[-1] = q[-1]
  115.     for i in reversed(range(len(b)-1)):
  116.         x[i] = p[i]*x[i+1] + q[i]
  117.     return x
  118.  
  119. def sqr_error(y, y_correct):
  120.     return np.sqrt(np.sum((y-y_correct)**2))
  121.  
  122. def RungeRombert(y1, y2, h1, h2, p):
  123.     if h1 > h2:
  124.         k = int(h1 / h2)
  125.         y = np.zeros(np.shape(y1)[0])
  126.         for i in range(np.shape(y1)[0]):
  127.             y[i] = y2[i*k]+(y2[i*k]-y1[i])/(k**p-1)
  128.         return y
  129.     else:
  130.         k = int(h2 / h1)
  131.         y = np.zeros(np.shape(y2)[0])
  132.         for i in range(np.shape(y2)[0]):
  133.             y[i] = y1[i * k] + (y1[i * k] - y2[i]) / (k ** p - 1)
  134.         return y
  135.  
  136. equation = {'p': p, 'q': q, 'f': right_f}
  137. BCondition1 = {'a': 1, 'b': 0, 'c': 2}
  138. BCondition2 = {'a': 1, 'b': 0, 'c': 2.5 - 0.5*np.log(3)}
  139. borders = (0, np.pi/6)
  140. h = np.pi/120
  141. x = np.arange(borders[0], borders[1]+h, h)
  142. y = f(x)
  143. eta1 = abs(y[-1]-y[1])/abs(x[-1]-x[1])
  144. eta2 = eta1/2
  145. y1 = ShotingMethod(ddf, borders, eta1, eta2, BCondition1, BCondition2, h)
  146. y2 = FiniteDifferenceMethod(BCondition1, BCondition2, equation, borders, h)
  147. h2 = h / 2
  148. y1_2 = ShotingMethod(ddf, borders, eta1, eta2, BCondition1, BCondition2, h2)
  149. y2_2 = FiniteDifferenceMethod(BCondition1, BCondition2, equation, borders, h2)
  150. print("Оценка погрешности методом Рунге-Ромберта:")
  151. print("Для метода стрельбы:", sqr_error(y1, RungeRombert(y1, y1_2, h, h2, 1)))
  152. print("Для метода конечных разностей:", sqr_error(y2, RungeRombert(y2, y2_2, h, h2, 1)))
  153.  
  154. print("\nСравнение с точным решением:")
  155. print("Для метода стрельбы:", sqr_error(y1, y))
  156. print("Для метода конечных разностей:", sqr_error(y2, y))
  157. plt.figure(figsize=(12, 7))
  158. plt.plot(x, y, label='Точное решение', linewidth=1, color="blue")
  159. plt.plot(x, y1, label='Метод стрельбы', linewidth=1, color="red")
  160. plt.plot(x, y2, label='Метод конечных разностей', linewidth=1, color="green")
  161. plt.grid()
  162. plt.legend()
  163. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement