WARNING
🧪 Beta公测版本提示:教程主体已完成,正在优化细节,欢迎大家提Issue反馈问题或建议。
导数与微分 — Python / C++ 代码详解
Download demo.pyDownload dual.hppDownload demo.cpp
运行方式
bash
cd docs/math/derivative/code
python demo.py
g++ -std=c++17 demo.cpp -o deriv_demo两张图:deriv_secant.png(割线 → 切线)、deriv_fd_error.png(中心差分误差随
代码逐段详解(Python)
第1步:Dual — 为什么乘法不能只乘 .v
对偶数
python
def __mul__(self, other):
other = other if isinstance(other, Dual) else Dual(other, 0.0)
return Dual(self.v * other.v, self.v * other.d + self.d * other.v)- 常数变成
Dual(other, 0):2.0 * t走__rmul__,否则double不知道怎么乘Dual。 Dual.var(x):种子,表示「对这个 求导」。对常数求导应得到 0,不要误写成 var。t * t * t - 2.0 * t:和在纸上写同一棵表达式树。 .d就是。
C++ operator* 是同一行公式。不要写成 a.v*b.v 配 a.d*b.d——那是错的逐元乘。
第2步:割线图 — 斜率怎么画成线
python
slope = (y2 - y1) / h
line_y = y1 + slope * (line_x - a)过点 sharey=True,才能看出割线在转动,而不是坐标系在偷偷缩放。
第3步:多项式系数与差分误差
python
c = np.array([0.0, -2.0, 0.0, 1.0]) # c0 + c1 x + c2 x^2 + c3 x^3
poly_diff(c) # [1*(-2), 2*0, 3*1] → [-2, 0, 3] 即 -2 + 3x^2下标
中心差分扫 hs = logspace(-1, -8, 8):误差先降后升。对数横轴才能看见
C++:dual.hpp
Dual::var / Dual::cnst 比布尔参数更不容易用反。sin/exp 的 x.d(链式法则)。central_diff 吃函数指针 double (*)(double),所以 cube_minus_2x 必须是普通函数,不能是带捕获的 lambda(除非写成不捕获并转成指针,教学里不绕这个弯)。
x * x * x - 2.0 * x 依赖 operator*(double, Dual),否则 2.0 * x 编不过。
源码位置
docs/math/derivative/code/demo.pydocs/math/derivative/code/dual.hppdocs/math/derivative/code/demo.cpp