Kienan

Метод Ньютона <3

Nov 13th, 2025
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.70 KB | None | 0 0
  1. import numpy as np
  2.  
  3. # Те же F(x) из предыдущего кода
  4. def F(X):
  5.     x, y, z = X
  6.     return np.array([
  7.         x**2 + x - y*z - 0.1,
  8.         -3*y + y**2 - x*z + 0.2,
  9.         2*z + z**2 + x*y - 0.3
  10.     ], dtype=float)
  11.  
  12. # Якобиан J(x)
  13. def J(X):
  14.     x, y, z = X
  15.     return np.array([
  16.         [2*x + 1,   -z,       -y],
  17.         [  -z,    2*y - 3,    -x],
  18.         [   y,       x,    2 + 2*z]
  19.     ], dtype=float)
  20.  
  21. # Твой Гаусс
  22. def gauss_solve(A, bb):
  23.     n = A.shape[0]
  24.     M = np.hstack((A.copy(), bb.reshape(-1, 1)))
  25.  
  26.     # Прямой ход с выбором главного элемента по столбцу
  27.     for i in range(n):
  28.         max_row = i
  29.         for k in range(i + 1, n):
  30.             if abs(M[k, i]) > abs(M[max_row, i]):
  31.                 max_row = k
  32.         M[[i, max_row]] = M[[max_row, i]]  # перестановка строк
  33.  
  34.         for k in range(i + 1, n):
  35.             if M[i, i] == 0:
  36.                 raise ValueError("Нулевой ведущий элемент в Гауссе")
  37.             c = M[k, i] / M[i, i]
  38.             M[k, i:] -= c * M[i, i:]
  39.  
  40.     # Обратный ход
  41.     x = np.zeros(n)
  42.     for i in range(n - 1, -1, -1):
  43.         x[i] = M[i, n]
  44.         for j in range(i + 1, n):
  45.             x[i] -= M[i, j] * x[j]
  46.         x[i] /= M[i, i]
  47.  
  48.     return x
  49.  
  50. def gauss_inverse(A):
  51.     n = A.shape[0]
  52.     A_inv = np.zeros((n, n))
  53.     I = np.eye(n)
  54.  
  55.     for i in range(n):
  56.         e = I[:, i]
  57.         A_inv[:, i] = gauss_solve(A, e)
  58.  
  59.     return A_inv
  60.  
  61. def newton(x0, eps=1e-6, max_iter=10):
  62.     X = np.array(x0, dtype=float)
  63.  
  64.     print("\nМетод Ньютона (ε = %.0e)" % eps)
  65.     print("k\t     x_k\t\t     y_k\t\t     z_k\t\tmax|F_i(x_k)|")
  66.  
  67.     for k in range(1, max_iter + 1):
  68.         Fx = F(X)
  69.         Jx = J(X)
  70.         Jinv = gauss_inverse(Jx)      # обратная к Якоби
  71.         delta = -Jinv.dot(Fx)
  72.         X_new = X + delta
  73.         r_new = F(X_new)
  74.         r_max = np.max(np.abs(r_new))
  75.  
  76.         print(f"{k:2d}\t{X_new[0]: .8f}\t{X_new[1]: .8f}\t"
  77.               f"{X_new[2]: .8f}\t{r_max: .2e}")
  78.         print("J(x_k) =\n", Jx)
  79.         print("J(x_k)^(-1) =\n", Jinv, "\n")
  80.  
  81.         # критерий остановки по шагу
  82.         if np.max(np.abs(delta)) < eps:
  83.             print("Достигнута точность по шагу ε =", eps)
  84.             break
  85.  
  86.         X = X_new
  87.  
  88.     return X_new
  89.  
  90. # Тот же старт
  91. x0 = [0.10, 0.07, 0.15]
  92. root_newton = newton(x0)
  93.  
  94. print("\nИтог (метод Ньютона):")
  95. print("x =", root_newton[0])
  96. print("y =", root_newton[1])
  97. print("z =", root_newton[2])
  98. print("Невязки F(x):", F(root_newton))
  99.  
Advertisement
Add Comment
Please, Sign In to add comment