Загрузка данных


import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize

# 1. Сначала определяем функции
def f(x):
    return x[0]**4 + 2*x[1]**2 - 1.1*x[0]*x[1]

def grad_f(x):
    df_dx1 = 4 * x[0]**3 - 1.1 * x[1]
    df_dx2 = 4 * x[1] - 1.1 * x[0]
    return np.array([df_dx1, df_dx2])

# Начальная точка
x_start = np.array([3.0, 3.0])

# 2. Алгоритм градиентного спуска
def gradient_descent(f, grad, x_start, lr=0.01, eps=1e-7, max_it=10000):
    x = x_start.copy()
    for i in range(max_it):
        g = grad(x)
        if np.linalg.norm(g) < eps:
            break
        x = x - lr * g
    return x, f(x), i  # Должно быть на одном уровне с 'for'

# 3. Тестирование и сравнение
# Вызов своего метода
res_grad_custom, f_grad_custom, it_grad = gradient_descent(f, grad_f, x_start)

# Вызов стандартного решателя BFGS
res_bfgs_scipy = minimize(f, x_start, method='BFGS', jac=grad_f)

print("--- Градиентный метод ---")
print(f"Своя реализация: точка {res_grad_custom}, f = {f_grad_custom}, итераций: {it_grad}")
print(f"Scipy (BFGS):    точка {res_bfgs_scipy.x}, f = {res_bfgs_scipy.fun}")

# 4. Визуализация (чтобы выполнить пункт 3 задания)
x_vals = np.linspace(-1, 4, 100)
y_vals = np.linspace(-1, 4, 100)
X, Y = np.meshgrid(x_vals, y_vals)
Z = f([X, Y])

plt.figure(figsize=(8, 6))
plt.contour(X, Y, Z, levels=50)
plt.plot(res_grad_custom[0], res_grad_custom[1], 'ro', label='Minimum')
plt.title('Линии уровня и найденный минимум')
plt.legend()
plt.show()