系列文章:
- 第一篇:算法工程师必知必会的数学基础之线性代数
- 第二篇:算法工程师必知必会的数学基础之微积分上篇
- 第三篇:算法工程师必知必会的数学基础之微积分下篇(本文)
文章目录
2. 微积分
微积分部分字数过多,故分为两部分。本文为下篇,书接 微积分上篇。
2.7 泰勒级数(Taylor Series)
泰勒级数是微积分中的一个重要概念,它提供了一种将函数表示为其在某一点附近导数值的无穷级数的方法。下面是关于泰勒级数的定义、麦克劳林级数以及泰勒级数的收敛性的详细介绍。
2.7.1 泰勒级数的定义
- 定义:假设函数
f
(
x
)
f(x)
f(x) 在点
a
a
a 的邻域内可以无限次求导,那么
f
(
x
)
f(x)
f(x) 在点
a
a
a 处的泰勒级数定义为:
T ( x ) = f ( a ) + f ′ ( a ) ( x − a ) + f ′ ′ ( a ) 2 ! ( x − a ) 2 + f ′ ′ ′ ( a ) 3 ! ( x − a ) 3 + ⋯ T(x) = f(a) + f'(a)(x-a) + \frac{f''(a)}{2!}(x-a)^2 + \frac{f'''(a)}{3!}(x-a)^3 + \cdots T(x)=f(a)+f′(a)(x−a)+2!f′′(a)(x−a)2+3!f′′′(a)(x−a)3+⋯
=
∑
n
=
0
∞
f
(
n
)
(
a
)
n
!
(
x
−
a
)
n
= \sum_{n=0}^{\infty} \frac{f^{(n)}(a)}{n!}(x-a)^n
=n=0∑∞n!f(n)(a)(x−a)n
其中
f
(
n
)
(
a
)
f^{(n)}(a)
f(n)(a) 表示
f
(
x
)
f(x)
f(x) 在点
a
a
a 处的
n
n
n 阶导数。
-
构造方法:泰勒级数是通过将函数在某一点的各阶导数值与多项式系数联系起来构建的。通过计算函数在该点的各阶导数,我们可以构造出泰勒级数的每一项。
-
应用:泰勒级数在函数逼近、数值计算、误差估计等领域有广泛的应用。
2.7.2 麦克劳林级数(Maclaurin Series)
- 定义:当
a
=
0
a = 0
a=0 时,泰勒级数称为麦克劳林级数。麦克劳林级数是泰勒级数在原点处的特例。
T ( x ) = f ( 0 ) + f ′ ( 0 ) x + f ′ ′ ( 0 ) 2 ! x 2 + f ′ ′ ′ ( 0 ) 3 ! x 3 + ⋯ T(x) = f(0) + f'(0)x + \frac{f''(0)}{2!}x^2 + \frac{f'''(0)}{3!}x^3 + \cdots T(x)=f(0)+f′(0)x+2!f′′(0)x2+3!f′′′(0)x3+⋯
= ∑ n = 0 ∞ f ( n ) ( 0 ) n ! x n = \sum_{n=0}^{\infty} \frac{f^{(n)}(0)}{n!}x^n =n=0∑∞n!f(n)(0)xn
- 常见函数的麦克劳林展开式:
- e x = 1 + x + x 2 2 ! + x 3 3 ! + ⋯ = ∑ n = 0 ∞ x n n ! e^x = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \cdots = \sum_{n=0}^{\infty} \frac{x^n}{n!} ex=1+x+2!x2+3!x3+⋯=∑n=0∞n!xn
- sin ( x ) = x − x 3 3 ! + x 5 5 ! − ⋯ = ∑ n = 0 ∞ ( − 1 ) n x 2 n + 1 ( 2 n + 1 ) ! \sin(x) = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \cdots = \sum_{n=0}^{\infty} (-1)^n \frac{x^{2n+1}}{(2n+1)!} sin(x)=x−3!x3+5!x5−⋯=∑n=0∞(−1)n(2n+1)!x2n+1
- cos ( x ) = 1 − x 2 2 ! + x 4 4 ! − ⋯ = ∑ n = 0 ∞ ( − 1 ) n x 2 n ( 2 n ) ! \cos(x) = 1 - \frac{x^2}{2!} + \frac{x^4}{4!} - \cdots = \sum_{n=0}^{\infty} (-1)^n \frac{x^{2n}}{(2n)!} cos(x)=1−2!x2+4!x4−⋯=∑n=0∞(−1)n(2n)!x2n
- ln ( 1 + x ) = x − x 2 2 + x 3 3 − ⋯ = ∑ n = 1 ∞ ( − 1 ) n + 1 x n n \ln(1+x) = x - \frac{x^2}{2} + \frac{x^3}{3} - \cdots = \sum_{n=1}^{\infty} (-1)^{n+1} \frac{x^n}{n} ln(1+x)=x−2x2+3x3−⋯=∑n=1∞(−1)n+1nxn (对于 ∣ x ∣ < 1 |x| < 1 ∣x∣<1)
2.7.3 泰勒级数的收敛性
-
收敛域:泰勒级数的收敛性取决于函数 f ( x ) f(x) f(x) 的性质。对于大多数常见的函数,泰勒级数在其收敛半径内收敛。收敛半径 R R R 是指从展开点 a a a 到最近奇点的距离。
-
判断泰勒级数的收敛性:
- 使用比值测试(Ratio Test)或根值测试(Root Test)来确定泰勒级数的收敛半径。
- 对于一些特殊情况,如多项式函数,泰勒级数在整个实数范围内收敛。
- 对于某些函数,如 1 1 − x \frac{1}{1-x} 1−x1( x ≠ 1 x \neq 1 x=1),泰勒级数只在 ∣ x ∣ < 1 |x| < 1 ∣x∣<1 的区域内收敛。
2.7.4 应用实例
- 函数逼近:考虑函数
f
(
x
)
=
e
x
f(x) = e^x
f(x)=ex,我们可以使用麦克劳林级数来逼近
e
x
e^x
ex:
e x ≈ 1 + x + x 2 2 ! + x 3 3 ! e^x \approx 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} ex≈1+x+2!x2+3!x3 - 误差估计:我们可以使用泰勒级数的余项公式来估计逼近的误差。例如,对于 e x e^x ex 的近似,我们可以计算出剩余项的大小来估计误差范围。
2.8 微积分的应用
微积分是数学的一个重要分支,它主要研究变化率(导数)和累积量(积分)。在许多领域都有广泛的应用,包括物理学、工程学、经济学、生物学以及计算机科学等。以下是微积分在不同领域的应用实例:
领域 | 具体应用领域 | 微积分概念及应用详情 |
---|---|---|
物理学 | 运动学 | 位置函数 s ( t ) s(t) s(t) 的一阶导数 s ′ ( t ) s'(t) s′(t) 表示速度;二阶导数 s ′ ′ ( t ) s''(t) s′′(t) 表示加速度 |
动力学 | 牛顿第二定律 F = m a F = ma F=ma 中的质量 m m m 和加速度 a a a 通过微分方程描述 | |
工程学 | 优化问题 | 寻找函数极值(最大值或最小值),通过求解导数为零的点来实现 |
控制系统 | 通过微分方程描述动态系统的行为,并设计控制器来稳定系统,如PID控制器 | |
经济学 | 边际分析 | 使用边际成本、边际收益等概念来优化生产和消费决策,如利润最大化问题 |
效用理论 | 通过求解效用函数的导数来确定消费者选择商品的最佳组合,以最大化效用 | |
医学与生物学 | 药代动力学 | 用微分方程来建模药物在体内的吸收、分布、代谢和排泄过程,如单室模型 |
种群增长模型 | 如Logistic方程 P ( t ) = K 1 + e − r ( t − t 0 ) P(t) = \frac{K}{1 + e^{-r(t-t_0)}} P(t)=1+e−r(t−t0)K,用来描述有限资源下的种群增长 | |
计算机科学 | 算法分析 | 评估算法效率时使用的极限和级数概念,如大O记号 O ( n ) O(n) O(n) 表示时间复杂度 |
机器学习 | 在训练神经网络时,使用链式法则来计算梯度,以更新权重,如反向传播算法 | |
其他 | 几何学 | 利用积分来计算曲线长度、曲面面积和体积等,如圆的周长 C = 2 π r C = 2\pi r C=2πr |
概率论 | 连续随机变量的概率密度函数 f ( x ) f(x) f(x) 和累积分布函数 F ( x ) F(x) F(x) | |
金融学 | 在金融衍生品定价中,Black-Scholes方程是一个著名的偏微分方程,用于计算期权价格 |
2.8.1 应用举例:优化问题
寻找函数极值(最大值或最小值),通过求解导数为零的点来实现。在2.2.3节中已经介绍。
2.8.2 应用举例:算法分析
在计算机科学中,算法分析是评估算法效率的一个重要方面,它涉及到使用数学工具来分析算法的时间复杂度和空间复杂度。时间复杂度通常用大O记号(Big O notation)来表示,它描述了算法运行时间随着输入规模的增长而增长的速度。极限和级数的概念在分析算法效率时也非常重要,尤其是在处理递归算法时。
大O记号 O ( f ( n ) ) O(f(n)) O(f(n)) 表示一个函数 T ( n ) T(n) T(n) 的增长率不超过 f ( n ) f(n) f(n) 的增长率。具体来说,如果存在正常数 c c c 和 n 0 n_0 n0 使得对于所有的 n ≥ n 0 n \geq n_0 n≥n0,都有 T ( n ) ≤ c ⋅ f ( n ) T(n) \leq c \cdot f(n) T(n)≤c⋅f(n),则称 T ( n ) T(n) T(n) 的时间复杂度为 O ( f ( n ) ) O(f(n)) O(f(n))。
在算法分析中,极限的概念用来描述算法运行时间随着输入规模 n n n 的增长而趋于无穷大时的趋势。例如,当我们说一个算法的时间复杂度是 O ( n 2 ) O(n^2) O(n2),我们实际上是指随着 n n n 的增长,算法的运行时间 T ( n ) T(n) T(n) 的增长率不会超过 n 2 n^2 n2 的增长率。
在某些情况下,特别是当算法涉及到递归时,级数的概念被用来计算算法的总运行时间。例如,当分析递归算法的时间复杂度时,可能会遇到级数的求和问题。
例子1:多项式函数
考虑一个简单的例子,假设我们有一个算法,它的运行时间
T
(
n
)
T(n)
T(n) 由以下函数给出:
T
(
n
)
=
n
2
+
3
n
+
4
T(n) = n^2 + 3n + 4
T(n)=n2+3n+4
要分析这个算法的时间复杂度,我们首先要找出 T ( n ) T(n) T(n) 的增长率。在这个例子中,随着 n n n 的增长, n 2 n^2 n2 的增长速度比 3 n 3n 3n 和 4 4 4 快得多。因此,我们可以忽略低阶项和常数项,只保留最高次项 n 2 n^2 n2。
因此,我们可以得出结论:
T
(
n
)
=
O
(
n
2
)
T(n) = O(n^2)
T(n)=O(n2)
这意味着随着输入规模 n n n 的增加,算法的运行时间增长不会超过 n 2 n^2 n2 的增长速度。
下面是一个使用 Python 来分析算法时间复杂度的示例代码:
import math
# 定义一个函数来模拟算法的运行时间
def T(n):
return n**2 + 3*n + 4
# 计算时间复杂度
def time_complexity(n):
# 忽略低阶项和常数项
highest_order_term = n**2
# 使用大O记号表示时间复杂度
return "O(n^2)" if highest_order_term >= T(n) else "Not O(n^2)"
# 测试不同的 n 值
for n in [10, 100, 1000]:
print(f"For n = {n}, Time Complexity: {time_complexity(n)}")
运行上面的代码时,输出将是:
For n = 10, Time Complexity: O(n^2)
For n = 100, Time Complexity: O(n^2)
For n = 1000, Time Complexity: O(n^2)
这表明对于给定的函数 T ( n ) = n 2 + 3 n + 4 T(n) = n^2 + 3n + 4 T(n)=n2+3n+4,算法的时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
例子2:斐波那契数列
让我们来看一个稍微复杂一点的例子,涉及递归算法的时间复杂度分析。我们将分析一个递归函数,该函数用于计算斐波那契数列的第 n n n 项,并使用极限和级数的概念来分析其时间复杂度。
斐波那契数列是一个经典的数列,其中每一项是前两项的和,即:
F
(
n
)
=
F
(
n
−
1
)
+
F
(
n
−
2
)
F(n) = F(n-1) + F(n-2)
F(n)=F(n−1)+F(n−2)
其中
F
(
0
)
=
0
F(0) = 0
F(0)=0 和
F
(
1
)
=
1
F(1) = 1
F(1)=1。
我们可以使用递归的方式来计算斐波那契数列的第 n n n 项。递归函数如下所示:
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
递归算法的时间复杂度分析通常比较复杂,因为每次递归调用都会产生新的子调用。在这种情况下,我们可以使用极限和级数的概念来估计递归树的深度,并最终确定时间复杂度。
斐波那契递归函数的递归树如下所示:
fibonacci(n)
/ \
fibonacci(n-1) fibonacci(n-2)
/ \ / \
... ... ... ...
每一层的节点数大约是前一层的两倍。由于每一层代表一次递归调用,我们可以估计递归树的深度大约为 n n n。递归树的叶子节点数量大约是 2 n − 1 2^{n-1} 2n−1。
由于每一层都需要执行常数时间的操作(例如递归调用、加法等),我们可以估计总的递归调用次数约为 2 n − 1 2^{n-1} 2n−1。因此,递归算法的时间复杂度大致为 O ( 2 n ) O(2^n) O(2n)。
下面是一个使用 Python 来分析斐波那契递归函数时间复杂度的示例代码:
import time
# 定义斐波那契递归函数
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
# 定义函数来测量递归函数的运行时间
def measure_time(n):
start_time = time.time()
result = fibonacci(n)
end_time = time.time()
elapsed_time = end_time - start_time
return elapsed_time, result
# 测试不同的 n 值
for n in [10, 20, 30, 40]:
elapsed_time, fib_result = measure_time(n)
print(f"For n = {n}, Fibonacci({n}) = {fib_result}, Time taken: {elapsed_time:.6f} seconds")
运行上面的代码时,输出将是:
For n = 10, Fibonacci(10) = 55, Time taken: 0.000020 seconds
For n = 20, Fibonacci(20) = 6765, Time taken: 0.001977 seconds
For n = 30, Fibonacci(30) = 832040, Time taken: 0.269839 seconds
For n = 40, Fibonacci(40) = 102334155, Time taken: 28.665041 seconds
通过观察输出结果,我们可以看到随着 n n n 的增加,递归函数的运行时间呈指数级增长。这与我们之前的时间复杂度分析 O ( 2 n ) O(2^n) O(2n) 相符。因此,虽然递归方法简洁易懂,但对于较大的 n n n 值来说,它并不是一个高效的解决方案。在实际应用中,通常会使用动态规划或者记忆化技术来优化递归算法,从而降低时间复杂度。
2.8.3 应用举例:机器学习
在机器学习中,特别是在训练神经网络时,使用链式法则来计算梯度是一个非常关键的概念。链式法则是微积分中的一个规则,用于计算复合函数的导数。在神经网络中,链式法则被用于计算损失函数相对于每个权重的梯度,这是反向传播算法的核心部分。
反向传播算法
反向传播算法是一种监督学习中的优化算法,用于调整神经网络中的权重,以最小化损失函数(也称为误差函数或代价函数)。神经网络通常包含多层,每层包含多个节点(或称为神经元)。每个节点接收输入,通过激活函数处理这些输入,并将其传递给下一层。在训练过程中,我们根据预测输出与实际标签之间的差异来调整权重。
链式法则
链式法则用于计算损失函数相对于每个权重的梯度。假设我们有一个神经网络,其中包含多个层,每一层的输出作为下一层的输入。对于每个权重 w w w,我们想要计算损失函数 L L L 相对于该权重的梯度 ∂ L ∂ w \frac{\partial L}{\partial w} ∂w∂L。
链式法则的应用
- 损失函数: 定义一个损失函数 L L L 来衡量预测值与真实值之间的差距。
- 权重更新: 使用梯度下降算法来更新权重,以最小化损失函数。
反向传播过程
- 前向传播: 输入数据通过网络向前传播,计算每一层的输出。
- 计算损失: 使用损失函数计算最终输出与真实标签之间的差距。
- 反向传播梯度: 从输出层开始,逆向计算每个权重的梯度。
- 权重更新: 使用梯度下降或其他优化算法来更新权重。
Python代码示例
假设我们有一个简单的神经网络,包含一个输入层、一个隐藏层和一个输出层。隐藏层包含一个节点,输出层同样包含一个节点。我们使用 sigmoid 激活函数和均方误差作为损失函数。
下面是一个使用 Python 和 NumPy 来实现简单神经网络反向传播算法的示例代码:
import numpy as np
# Sigmoid 激活函数及其导数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return sigmoid(x) * (1 - sigmoid(x))
def he_init(shape):
return np.random.randn(*shape) * np.sqrt(2 / shape[0])
# 输入数据和标签
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])
# 初始化权重
np.random.seed(1)
weights_input_hidden = he_init((2, 4)) # 输入层到隐含层,4个节点
weights_hidden_output = he_init((4, 1)) # 隐含层到输出层
# 设置学习率
learning_rate = 0.1
# 训练循环
N = 40000 # 迭代次数
for epoch in range(N):
# 前向传播
# 输入层到隐含层
hidden_layer_input = np.dot(X, weights_input_hidden)
hidden_layer_output = sigmoid(hidden_layer_input)
# 隐含层到输出层
output_layer_input = np.dot(hidden_layer_output, weights_hidden_output)
output_layer_output = sigmoid(output_layer_input)
# 计算损失
loss = np.mean((output_layer_output - y) ** 2)
# 反向传播
# 计算输出层误差
output_error = output_layer_output - y
output_delta = output_error * sigmoid_derivative(output_layer_output)
# 计算隐含层误差
hidden_error = np.dot(output_delta, weights_hidden_output.T) * sigmoid_derivative(hidden_layer_output)
# 更新权重
weights_hidden_output -= learning_rate * np.dot(hidden_layer_output.T, output_delta)
weights_input_hidden -= learning_rate * np.dot(X.T, hidden_error)
# 打印训练好的网络权重
print("Weights Input to Hidden:")
print(weights_input_hidden)
print("\nWeights Hidden to Output:")
print(weights_hidden_output)
# 使用训练好的权重进行预测
# 输入数据
X_test = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
# 前向传播
# 输入层到隐含层
hidden_layer_input = np.dot(X_test, weights_input_hidden)
hidden_layer_output = sigmoid(hidden_layer_input)
# 隐含层到输出层
output_layer_input = np.dot(hidden_layer_output, weights_hidden_output)
output_layer_output = sigmoid(output_layer_input)
# 输出原始预测结果
print("Raw Output:")
print(output_layer_output)
# 阈值处理
threshold = 0.5 # 调整阈值
output_layer_output[output_layer_output >= threshold] = 1
output_layer_output[output_layer_output < threshold] = 0
# 输出预测结果
print("Predicted Output:")
print(output_layer_output)
这段代码实现了一个简单的前馈神经网络,用于解决逻辑异或(XOR)问题。运行上面的代码时,最终权重将被打印出来。这些权重经过训练后,使得神经网络能够更好地预测输入数据对应的输出。在模型训练完成后,我们用测试输入X_test = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
查看网络的实际输出效果,结果一并显示在下方。
Weights Input to Hidden:
[[ 1.71710526 -0.89975038 -14.05470169 16.29013708]
[ 1.89598582 -2.30978834 15.58147621 -14.77986351]]
Weights Hidden to Output:
[[ 21.67682113]
[ 0.3479069 ]
[-15.3439219 ]
[-14.93573351]]
Raw Output:
[[0.01586787]
[0.97164305]
[0.97184531]
[0.02369869]]
Predicted Output:
[[0.]
[1.]
[1.]
[0.]]
可以看到,这个简单的前馈网络模型学习到了XOR的逻辑。训练成功。
2.8.4 应用举例:几何学
积分可以用来计算曲线长度、曲面面积和体积等几何量,这些计算是微积分的一个重要应用领域。下面我将分别介绍如何使用积分来计算曲线长度、曲面面积和体积。
曲线长度
假设我们有一个平面曲线 y = f ( x ) y = f(x) y=f(x),该曲线在区间 [ a , b ] [a, b] [a,b] 上连续可导。我们可以使用积分来计算这条曲线在这段区间上的弧长 L L L。公式如下:
L = ∫ a b 1 + ( d y d x ) 2 d x L = \int_{a}^{b} \sqrt{1 + \left(\frac{dy}{dx}\right)^2} \, dx L=∫ab1+(dxdy)2dx
曲面面积
假设我们有一个旋转曲面,由函数 y = f ( x ) y = f(x) y=f(x) 绕 x 轴旋转生成,其中 f ( x ) f(x) f(x) 在 [ a , b ] [a, b] [a,b] 区间上连续可导。我们可以使用积分来计算这个旋转曲面的面积 A A A。公式如下:
A = 2 π ∫ a b ∣ f ( x ) ∣ 1 + ( d y d x ) 2 d x A = 2\pi \int_{a}^{b} |f(x)| \sqrt{1 + \left(\frac{dy}{dx}\right)^2} \, dx A=2π∫ab∣f(x)∣1+(dxdy)2dx
体积
假设我们有一个旋转体,由函数 y = f ( x ) y = f(x) y=f(x) 绕 x 轴旋转生成,其中 f ( x ) f(x) f(x) 在 [ a , b ] [a, b] [a,b] 区间上连续可导。我们可以使用积分来计算这个旋转体的体积 V V V。公式如下:
V = π ∫ a b [ f ( x ) ] 2 d x V = \pi \int_{a}^{b} [f(x)]^2 \, dx V=π∫ab[f(x)]2dx
示例:计算圆的周长
对于圆的周长,实际上并不需要使用积分来计算。圆的周长 C C C 可以直接使用公式 C = 2 π r C = 2\pi r C=2πr 来计算,其中 r r r 是圆的半径。
但是,如果我们想使用积分来验证这个结果,我们可以考虑圆的一段弧。假设我们有一个单位圆,即半径为 1 的圆,其方程为 x 2 + y 2 = 1 x^2 + y^2 = 1 x2+y2=1。我们可以使用积分来计算四分之一圆的弧长,然后乘以 4 来得到整个圆的周长。
四分之一圆的弧长可以表示为:
L quarter = ∫ 0 1 1 + ( d y d x ) 2 d x L_{\text{quarter}} = \int_{0}^{1} \sqrt{1 + \left(\frac{dy}{dx}\right)^2} \, dx Lquarter=∫011+(dxdy)2dx
由于 x 2 + y 2 = 1 x^2 + y^2 = 1 x2+y2=1,我们可以解出 y y y 关于 x x x 的表达式:
y = 1 − x 2 = y = ( 1 − x 2 ) 1 / 2 y = \sqrt{1 - x^2} = y = (1-x^2)^{1/2} y=1−x2=y=(1−x2)1/2
接着求导:
d
y
d
x
=
1
2
(
1
−
x
2
)
−
1
/
2
⋅
d
d
x
(
1
−
x
2
)
=
1
2
(
1
−
x
2
)
−
1
/
2
⋅
(
−
2
x
)
=
−
x
(
1
−
x
2
)
−
1
/
2
=
−
x
1
−
x
2
\begin{aligned} \frac{dy}{dx} &= \frac{1}{2}(1-x^2)^{-1/2} \cdot \frac{d}{dx}(1-x^2) \\ &= \frac{1}{2}(1-x^2)^{-1/2} \cdot (-2x) \\ &= -x(1-x^2)^{-1/2} \\ &= -\frac{x}{\sqrt{1 - x^2}} \end{aligned}
dxdy=21(1−x2)−1/2⋅dxd(1−x2)=21(1−x2)−1/2⋅(−2x)=−x(1−x2)−1/2=−1−x2x
所以:
L quarter = ∫ 0 1 1 + ( − x 1 − x 2 ) 2 d x L_{\text{quarter}} = \int_{0}^{1} \sqrt{1 + \left(-\frac{x}{\sqrt{1 - x^2}}\right)^2} \, dx Lquarter=∫011+(−1−x2x)2dx
简化得到:
L quarter = ∫ 0 1 1 + x 2 1 − x 2 d x = ∫ 0 1 1 1 − x 2 d x L_{\text{quarter}} = \int_{0}^{1} \sqrt{1 + \frac{x^2}{1 - x^2}} \, dx = \int_{0}^{1} \sqrt{\frac{1}{1 - x^2}} \, dx Lquarter=∫011+1−x2x2dx=∫011−x21dx
使用积分公式计算这个积分:
L quarter = [ arcsin ( x ) ] 0 1 = arcsin ( 1 ) − arcsin ( 0 ) = π 2 L_{\text{quarter}} = \left[ \arcsin(x) \right]_{0}^{1} = \arcsin(1) - \arcsin(0) = \frac{\pi}{2} Lquarter=[arcsin(x)]01=arcsin(1)−arcsin(0)=2π
因此,整个圆的周长为:
L = 4 × L quarter = 4 × π 2 = 2 π L = 4 \times L_{\text{quarter}} = 4 \times \frac{\pi}{2} = 2\pi L=4×Lquarter=4×2π=2π
这与我们直接使用公式 C = 2 π r C = 2\pi r C=2πr 得到的结果相同。
示例:计算旋转体体积
函数
f
(
x
)
=
x
2
f(x) = x^2
f(x)=x2 沿着
x
x
x 轴旋转会形成一个旋转体。这个旋转体的横截面在任何给定的
x
x
x 值处都是一个圆,圆的半径等于该点的
y
y
y 值,即
x
2
x^2
x2。
图像描述
- 底面:当 x = 0 x = 0 x=0 时, y = 0 y = 0 y=0,所以旋转体的底部是一个点。
- 顶部:随着 x x x 的增加, y = x 2 y = x^2 y=x2 也在增加,直到 x = 1 x = 1 x=1 时 y = 1 y = 1 y=1。因此,当 x = 1 x = 1 x=1 时,旋转体的顶部是一个半径为 1 的圆。
- 形状:旋转体的形状类似于一个倒置的碗或圆锥体,但它的侧面是平滑的曲线,而不是直线。随着 x x x 的增加,旋转体的直径(即圆的直径)也随之增加,直到 x = 1 x = 1 x=1 时直径达到最大值 2。
数学描述
假设我们考虑函数 f ( x ) = x 2 f(x) = x^2 f(x)=x2 在区间 [ 0 , b ] [0, b] [0,b] 上旋转形成的旋转体,其中 b > 0 b > 0 b>0。
对于任意给定的 x x x 值,旋转体在该 x x x 值处的横截面是一个圆,其面积为 A ( x ) = π r 2 = π ( x 2 ) 2 = π x 4 A(x) = \pi r^2 = \pi (x^2)^2 = \pi x^4 A(x)=πr2=π(x2)2=πx4。因此,旋转体的体积可以通过定积分 $V = \pi \int_{0}^{b} x^4 , dx $ 来计算。
计算这个积分:
V
=
π
[
x
5
5
]
0
b
V = \pi \left[ \frac{x^5}{5} \right]_{0}^{b}
V=π[5x5]0b
V
=
π
(
b
5
5
−
0
5
5
)
V = \pi \left( \frac{b^5}{5} - \frac{0^5}{5} \right)
V=π(5b5−505)
V
=
π
b
5
5
V = \pi \frac{b^5}{5}
V=π5b5
因此,函数
f
(
x
)
=
x
2
f(x) = x^2
f(x)=x2 在区间
[
0
,
b
]
[0, b]
[0,b] 上绕
x
x
x 轴旋转形成的旋转体的体积为:
V
=
π
b
5
5
V = \frac{\pi b^5}{5}
V=5πb5
import sympy as sp
# 定义符号变量
x = sp.symbols('x')
# 定义函数
f = x**2
# 计算旋转体的体积
b=1
volume = sp.integrate(sp.pi * f**2, (x, 0, b))
# 输出结果
print("Volume of the solid of revolution:", volume)
运行这段代码,你将得到如下输出:
Volume of the solid of revolution: pi/5
这表明函数 f ( x ) = x 2 f(x) = x^2 f(x)=x2 在区间 [ 0 , 1 ] [0, 1] [0,1] 上绕 x x x 轴旋转所形成的旋转体的体积为 π 5 \frac{\pi}{5} 5π。
2.8.5 应用举例:金融学
Black-Scholes方程是金融工程和衍生品定价领域中最著名的偏微分方程之一。它是由 Fischer Black 和 Myron Scholes 在 1973 年提出的,并且 Robert Merton 同时独立地发展了类似的理论。这个方程用于计算欧式期权的价格,并且它基于无套利定价原理。
Black-Scholes 方程
Black-Scholes 方程描述了一个期权价值 V V V 随时间 t t t 和标的资产价格 S S S 的变化。它是以下形式的偏微分方程:
∂ V ∂ t + 1 2 σ 2 S 2 ∂ 2 V ∂ S 2 + r S ∂ V ∂ S − r V = 0 \frac{\partial V}{\partial t} + \frac{1}{2} \sigma^2 S^2 \frac{\partial^2 V}{\partial S^2} + r S \frac{\partial V}{\partial S} - rV = 0 ∂t∂V+21σ2S2∂S2∂2V+rS∂S∂V−rV=0
其中:
- V V V 是期权的价值;
- S S S 是标的资产的价格;
- t t t 是时间;
- σ \sigma σ 是标的资产价格的波动率;
- r r r 是无风险利率。
边界条件
为了求解这个偏微分方程,还需要加上适当的边界条件。对于欧式看涨期权,边界条件通常是:
- 当 t = T t = T t=T 时,即期权到期时, V = max ( S − K , 0 ) V = \max(S - K, 0) V=max(S−K,0),其中 K K K 是行权价格;
- 当 S → 0 S \rightarrow 0 S→0 时, V → 0 V \rightarrow 0 V→0;
- 当 S → ∞ S \rightarrow \infty S→∞ 时, V → S − K e − r ( T − t ) V \rightarrow S - Ke^{-r(T-t)} V→S−Ke−r(T−t)。
解析解
对于欧式看涨期权和欧式看跌期权,Black-Scholes 方程有一个封闭形式的解析解。这个解称为 Black-Scholes 公式,它可以用来直接计算期权的价格。对于欧式看涨期权 C C C,公式为:
C = S N ( d 1 ) − K e − r T N ( d 2 ) C = S N(d_1) - Ke^{-rT} N(d_2) C=SN(d1)−Ke−rTN(d2)
其中:
- N ( x ) N(x) N(x) 是标准正态分布的累积分布函数;
- d 1 = ln ( S / K ) + ( r + σ 2 2 ) T σ T d_1 = \frac{\ln(S/K) + (r + \frac{\sigma^2}{2})T}{\sigma \sqrt{T}} d1=σTln(S/K)+(r+2σ2)T;
- d 2 = d 1 − σ T d_2 = d_1 - \sigma \sqrt{T} d2=d1−σT。
对于欧式看跌期权 P P P,公式为:
P = K e − r T N ( − d 2 ) − S N ( − d 1 ) P = Ke^{-rT} N(-d_2) - S N(-d_1) P=Ke−rTN(−d2)−SN(−d1)
实际应用
在实际应用中,Black-Scholes 方程和公式被广泛用于金融市场的期权定价。然而,需要注意的是,Black-Scholes 模型有一些基本假设,包括:
- 标的资产价格遵循几何布朗运动;
- 无风险利率是常数;
- 市场不存在交易成本和税收;
- 期权只能在到期日行使(欧式期权);
- 不存在套利机会。
这些假设在现实世界中往往是不成立的,因此在实际应用中需要对模型进行一定的调整。尽管如此,Black-Scholes 模型仍然是理解和计算期权价格的基础,并且它启发了许多后续的衍生品定价模型。