Skip to content

第 6 章 常见函数的导数 ​

学习目标 ​

  • 理解自然常数 与指数函数 的导数
  • 推导对数函数 的导数
  • 推导三角函数 、、 的导数
  • 掌握一般底数 、 的求导
  • 理解高阶导数及其物理意义
  • 会用数值方法与 PyTorch 验证

6.1 指数函数与自然常数 ​

先看一种特殊的增长。把 1 元存进银行,年利率 100%(即 1)。如果一年结算一次,年底变成 元。如果半年结算一次,利率按 算,复利变成 元。如果每个月结算一次, 元。结算次数越多,钱越多,但增长会越来越慢——它逼近一个极限,这个极限就是 :

这是第 3 章第二个重要极限。函数 叫自然指数函数,它有一个惊艳的性质:它的导数等于它自己:

推导:用导数定义:

(依据:指数运算法则 ,提取公因式 。)现在只需知道 的极限。由 的定义可以推出(证明思路:令 , 当 很小时)

于是 。

python
import numpy as np

for h in [0.1, 0.01, 0.001, 0.0001]:
    print(f"h = {h:<8} (e^h - 1)/h = {(np.exp(h) - 1) / h:.8f}")
text
h = 0.1      (e^h - 1)/h = 1.05170918
h = 0.01     (e^h - 1)/h = 1.00501671
h = 0.001    (e^h - 1)/h = 1.00050017
h = 0.0001   (e^h - 1)/h = 1.00005000

推广到一般底数:利用 (两边取自然对数可得),由链式法则:

例如 。当 时,,回到 。

6.2 对数函数 ​

是 的反函数:意思是

求它的导数,用隐函数求导:设 ,则 。两边对 求导:

左边用链式法则( 是 的函数),右边导数是 1:

所以:

验证:

python
import numpy as np

x = 2.0
h = 1e-6
numerical = (np.log(x + h) - np.log(x - h)) / (2 * h)
print("数值导数 ≈", numerical)
print("1/x        =", 1 / x)
text
数值导数 ≈ 0.5000000000143778
1/x        = 0.5

一般底数:由换底公式 ,常数倍法则给出

6.3 三角函数 ​

正弦函数的导数:

推导:用和角公式 :

现在看两个极限。第一个是重要极限:。第二个:

(这里用到了平方恒等式 。)所以 。

同理可得 。由商法则:

数值验证 在 处的导数:

python
import numpy as np

x = 0.8
h = 1e-6
numerical = (np.sin(x + h) - np.sin(x - h)) / (2 * h)
print("数值导数 ≈", numerical)
print("cos(x)     =", np.cos(x))
text
数值导数 ≈ 0.6967067093799351
cos(x)     = 0.6967067093471654

正弦与导数

python
import matplotlib.pyplot as plt
from matplotlib import font_manager
for f in font_manager.findSystemFonts():
    if any(k in f for k in ("NotoSansCJK", "NotoSansSC", "wqy", "SimHei", "msyh", "PingFang")):
        font_manager.fontManager.addfont(f)
plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "WenQuanYi Zen Hei", "SimHei", "Microsoft YaHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False

import numpy as np

x = np.linspace(-3.5, 3.5, 500)
fig, axes = plt.subplots(1, 2, figsize=(12, 4.4))

# 左:sin x 与几处切线
axes[0].plot(x, np.sin(x), color="tab:blue", label="sin x")
for a in [-2.0, 0.0, 1.5]:
    slope = np.cos(a)
    xt = np.array([a - 0.7, a + 0.7])
    axes[0].plot(xt, np.sin(a) + slope * (xt - a), color="tab:red", linewidth=1.4)
axes[0].set_title("sin x 的切线(斜率 cos x)")
axes[0].set_ylim(-1.6, 1.6)

# 右:sin x 与 cos x
axes[1].plot(x, np.sin(x), color="tab:blue", label="sin x")
axes[1].plot(x, np.cos(x), color="tab:green", label="cos x = (sin x)'")
axes[1].set_title("sin x 与其导数 cos x")
axes[1].set_ylim(-1.6, 1.6)

for ax in axes:
    ax.axhline(0, color="black", linewidth=0.8)
    ax.axvline(0, color="black", linewidth=0.8)
    ax.grid(True, linestyle=":", alpha=0.5)
    ax.legend(fontsize=9)

fig.savefig("book/public/figs/fig06-sin_cos.png", dpi=120, bbox_inches="tight")
plt.close(fig)

6.4 指数与对数图像 ​

指数与对数

python
import matplotlib.pyplot as plt
from matplotlib import font_manager
for f in font_manager.findSystemFonts():
    if any(k in f for k in ("NotoSansCJK", "NotoSansSC", "wqy", "SimHei", "msyh", "PingFang")):
        font_manager.fontManager.addfont(f)
plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "WenQuanYi Zen Hei", "SimHei", "Microsoft YaHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False

import numpy as np

x = np.linspace(-2, 2.4, 400)
fig, axes = plt.subplots(1, 2, figsize=(12, 4.4))

axes[0].plot(x, np.exp(x), color="tab:blue", label="e^x")
axes[0].plot(x, x + 1, color="tab:red", linestyle="--", label="切线 y = x + 1")
axes[0].set_title("e^x 在 x=0 处切线斜率 = e^0 = 1")
axes[0].set_ylim(-0.5, 7)

xp = np.linspace(0.05, 5, 400)
axes[1].plot(xp, np.log(xp), color="tab:green", label="ln x")
axes[1].plot(xp, (xp - 1), color="tab:red", linestyle="--", label="切线 y = x - 1")
axes[1].set_title("ln x 在 x=1 处切线斜率 = 1/1 = 1")
axes[1].set_ylim(-2.5, 2.5)

for ax in axes:
    ax.axhline(0, color="black", linewidth=0.8)
    ax.axvline(0, color="black", linewidth=0.8)
    ax.grid(True, linestyle=":", alpha=0.5)
    ax.legend(fontsize=9)

fig.savefig("book/public/figs/fig06-exp_log.png", dpi=120, bbox_inches="tight")
plt.close(fig)

6.5 高阶导数 ​

导数本身还是函数,可以再求导。 的导数叫二阶导数,记作 或 ;以此类推有三阶、四阶……

二阶导数的物理意义:加速度。路程 的一阶导数是速度 ,速度的导数(即路程的二阶导数)是加速度:

自由落体 :

加速度恒为 10 m/s²(即重力加速度 取整后的近似),这符合物理事实。

python
def s(t):
    return 5 * t ** 2

h = 1e-5
t = 3.0
second = (s(t + h) - 2 * s(t) + s(t - h)) / h ** 2
print("数值二阶导 ≈", second)
print("理论值(加速度) =", 10)
text
数值二阶导 ≈ 9.999894245993344
理论值(加速度) = 10

用 PyTorch 求高阶导数:

python
import torch

x = torch.tensor(1.0, requires_grad=True)
y = torch.exp(x)
first = torch.autograd.grad(y, x, create_graph=True)[0]
second = torch.autograd.grad(first, x)[0]

print("y    =", y.item())
print("y'   =", first.item())
print("y''  =", second.item())
text
y    = 2.7182817459106445
y'   = 2.7182817459106445
y''  = 2.7182817459106445

三阶及以上的所有导数都等于 本身——这正是 的体现。

6.6 常见错误 ​

错误写法/理解原因
认为 幂函数公式只适用于 在底数位置;指数函数 的导数是它自己
认为 同样混淆底与指数; 的导数是
认为 对 成立 的定义域是
忘记 的负号余弦在 0 附近下降,导数应为负
用 np.sin 计算时忘记弧度制NumPy 三角函数默认弧度,角度要先转换

6.7 动手实践:增长率问题 ​

某细菌数量按 增长( 为小时)。求 时的增长速率:

python
import numpy as np

def N(t):
    return 100 * np.exp(0.3 * t)

def Np(t):
    return 30 * np.exp(0.3 * t)

t = 2.0
h = 1e-6
numerical = (N(t + h) - N(t - h)) / (2 * h)
print("数值增长速率 ≈", numerical)
print("公式 N'(2)    =", Np(t))
text
数值增长速率 ≈ 54.66356401484518
公式 N'(2)    = 54.663564011715266

章末练习 ​

基础

  1. 求导:、、、。
  2. 求导:、。
  3. 在 时的速度与加速度各是多少?

提高

  1. 用链式法则求 、、 的导数。
  2. 求 的导数,写出乘法法则的每一步。

挑战

  1. 证明 (提示:,仿照 6.3 的推导)。
  2. 用 PyTorch 求 在 处的导数,并与手算结果 比较。

章末自测 ​

每题选择一个最佳答案。本书不附答案:完成后交由老师或 AI 老师批改讲解。

  1. 等于?
    • A.
    • B.
    • C.
    • D.
  2. 等于?
    • A.
    • B.
    • C.
    • D.
  3. 等于?
    • A.
    • B.
    • C.
    • D.
  4. 等于?
    • A.
    • B.
    • C.
    • D.
  5. 等于?
    • A.
    • B.
    • C.
    • D.
  6. 等于?
    • A.
    • B.
    • C.
    • D.
  7. 路程 的二阶导数 表示?
    • A. 速度
    • B. 加速度
    • C. 位移
    • D. 功
  8. 的加速度是?
    • A.
    • B.
    • C.
    • D.
  9. 的导数是?
    • A.
    • B.
    • C.
    • D.
  10. 等于?
    • A.
    • B.
    • C.
    • D.