"""有限差分梯度检查：验证解析梯度是否写对。"""
import numpy as np


def loss(w: np.ndarray, x: np.ndarray, y: float) -> float:
    pred = float(x @ w)
    return 0.5 * (pred - y) ** 2


def analytic_grad(w: np.ndarray, x: np.ndarray, y: float) -> np.ndarray:
    pred = float(x @ w)
    return (pred - y) * x


def numeric_grad(w: np.ndarray, x: np.ndarray, y: float, eps: float = 1e-5) -> np.ndarray:
    grad = np.zeros_like(w, dtype=np.float64)
    for i in range(w.size):
        plus, minus = w.copy(), w.copy()
        plus[i] += eps
        minus[i] -= eps
        grad[i] = (loss(plus, x, y) - loss(minus, x, y)) / (2 * eps)
    return grad


if __name__ == "__main__":
    w = np.array([0.2, -0.3], dtype=np.float64)
    x = np.array([1.5, 2.0], dtype=np.float64)
    a = analytic_grad(w, x, 0.7)
    n = numeric_grad(w, x, 0.7)
    print("analytic:", a, "numeric:", n)
    assert np.allclose(a, n, rtol=1e-5, atol=1e-7)
