#!/usr/bin/env python3
"""笔记正确性自检 —— 用代码验证笔记里的数值断言和公式。

运行：双击「数学工具/启动 Python 命令行.command」，然后执行
      exec(open('教材/自检脚本.py').read())
或命令行：~/miniconda3/bin/python 教材/自检脚本.py
"""
import numpy as np

np.random.seed(0)
ok = lambda b: "✅" if b else "❌"

print("【线代】SVD / 最小二乘")
A = np.random.randn(5, 3)
U, S, Vt = np.linalg.svd(A)
print(f"  SVD 重构           {ok(np.allclose(A, U[:,:3]@np.diag(S)@Vt))}")
ev = np.sort(np.linalg.eigvalsh(A.T @ A))[::-1]
print(f"  A^TA非零特征值=σ²  {ok(np.allclose(ev[:3], S**2))}")
Ad, b = np.random.randn(20,3), np.random.randn(20)
xh = np.linalg.lstsq(Ad, b, rcond=None)[0]
print(f"  正规方程 A^TAx=A^Tb {ok(np.allclose(Ad.T@Ad@xh, Ad.T@b))}")

print("\n【概率】贝叶斯 / 期望")
sens, spec, prev = .99, .99, .001
p = sens*prev / (sens*prev + (1-spec)*(1-prev))
print(f"  基础率谬误 ≈9%      {ok(abs(p-0.09) < 0.01)}  (实算 {p:.4f})")

print("\n【统计】MLE / 多重比较")
print(f"  有偏σ̂²  期望<1      {ok(np.mean([np.random.randn(10).var() for _ in range(50000)]) < 1)}")
print(f"  无偏s²  期望≈1      {ok(abs(np.mean([np.random.randn(10).var(ddof=1) for _ in range(50000)])-1) < 0.02)}")
print(f"  1-0.95^20 ≈ 64%     {ok(abs(1-0.95**20 - 0.64) < 0.01)}")

print("\n【优化】梯度")
f = lambda x: (x**2).sum(); g = lambda x: 2*x
x = np.array([3.,-4.])
for _ in range(100): x = x - 0.1*g(x)
print(f"  梯度下降收敛        {ok(np.allclose(x, 0, atol=1e-6))}")
print(f"  凸函数海森半正定    {ok(np.all(np.linalg.eigvalsh(np.array([[2,0],[0,2]])) >= 0))}")

print("\n【动力系统】稳定性 / 混沌")
from scipy.integrate import odeint
t = np.linspace(0,5,100)
print(f"  a<0收敛 a>0发散     {ok(abs(odeint(lambda x,t:-x,1.,t)[-1,0])<0.01 and abs(odeint(lambda x,t:x,1.,t)[-1,0])>10)}")
def lm(r):
    x = 0.4
    for _ in range(800): x = r*x*(1-x)
    return len(set(np.round([x := r*x*(1-x) for _ in range(50)], 4)))
print(f"  Logistic r=2.8稳定  {ok(lm(2.8) <= 4)}")
print(f"  Logistic r=3.9混沌  {ok(lm(3.9) > 10)}")

print("\n全部核验完毕。任何 ❌ 说明笔记可能有误，请对照原教材复核。")
