极限是微积分和数学分析的核心概念,它描述了函数在某个点的邻域或无穷远处的行为特征。本文将结合Python的SymPy库实现,深入浅出地讲解极限计算的方法与技巧。
对于函数f(x)=1/x,当x趋近于0时表现出明显的方向性差异:
x = sy.Symbol('x')
expression = 1 / x
# 右侧趋近返回正无穷
sy.limit(expression, x, 0, '+') # ∞
# 左侧趋近返回负无穷
sy.limit(expression, x, 0, '-') # -∞
# 双向趋近返回复数无穷
sy.limit(expression, x, 0, '+-') # zoo
这揭示了极限的重要性质——方向敏感性。实际应用中必须明确趋近方向,否则可能得到错误结论。
这个函数在物理波动和工程振动分析中广泛应用:
expression = sy.sin(x)/x
# 无论x趋近正负无穷,结果都是0
sy.limit(expression, x, sy.oo) # 0
其收敛性源于正弦函数的有界性(|sin(x)| ≤ 1),当分母x趋向无穷时,整体趋近于0。
expression = x * sy.sin(1/x)
# 所有方向的极限均为0
sy.limit(expression, x, 0) # 0
虽然sin(1/x)在0点附近无限震荡,但乘数x的线性衰减压制了震荡幅度,形成稳定的收敛结果。
expression = sy.sin(1/x)
# 双向趋近时极限不存在
sy.limit(expression, x, 0) # AccumBounds(-1, 1)
此时函数在-1,1之间无限震荡,不收敛于任何确定值。SymPy返回震荡边界,表示极限不存在。
对分式函数(x²-3x+2)/(x-2):
expression = (x**2-3x+2)/(x-2)
# 分解后简化为(x-1)(x-2)/(x-2) → x-1
sy.limit(expression, x, 2) # 1
通过因式分解消除分母的零因子,使直接代入成为可能。
处理含根号的分式:
expression = (sy.sqrt(x**2-9)-4)/(x-5)
# 分子分母同乘共轭表达式后化简
sy.limit(expression, x, 5) # 5/4
通过有理化处理消除根号,将问题转化为多项式极限计算。
对于有理函数:
expression = (x-8x⁴)/(7x⁴+5x³+2000x²-6)
# 首项系数之比决定极限
sy.limit(expression, x, sy.oo) # -8/7
在x→±∞时,最高次项主导函数行为,其他项可忽略。
expression = (sy.sqrt(16x⁴+8)+3x³)/(2x²+6x+1)
# 分子首项为3x³,分母为2x² → 整体趋近∞
sy.limit(expression, x, sy.oo) # ∞
当分子次数高于分母时,函数将发散至无穷。
符号函数在零点处的行为:
expression = sy.Abs(x)/x
sy.limit(expression, x, 0, '+') # 1
sy.limit(expression, x, 0, '-') # -1
左右极限不一致导致整体极限不存在,这在信号处理中对应阶跃函数的变化。
技巧类型 | 适用场景 | 实现方法 |
---|---|---|
因式分解 | 可约分的有理函数 | factor()函数进行多项式分解 |
共轭表达式 | 含根号的无理式 | 分子分母同乘共轭项 |
泰勒展开 | 复杂函数在特定点展开 | series()函数进行级数展开 |
首项提取 | 无穷远处的极限分析 | 提取分子分母最高次项 |
夹逼定理 | 无法直接计算的情形 | 构造上下界函数进行逼近 |
import random
import unittest
import sympy as sy
from sympy import sqrt
class LimitationTestCase(unittest.TestCase):
def test_1_x(self):
"""
求 1/x 的极限
"""
x = sy.Symbol('x')
expression = 1 / x
# 计算 1/x 中在 x->+0 时的极限(右侧方向逼近)
self.assertEqual(sy.limit(expression , x , 0 , '+') , sy.oo)
# 计算 1/x 中在 x->-0 时的极限(左侧方向逼近)
self.assertEqual(sy.limit(expression , x , 0 , '-') , -sy.oo)
# 计算 1/x 中在 x->0 时的极限(不区分方向)
self.assertEqual(sy.limit(expression , x , 0 , '+-') , sy.zoo)
def test_sin_x_x(self):
"""
求 sin(x)/x 的极限
"""
x = sy.Symbol('x')
expression = sy.sin(x) / x
# 计算 sy.sin(x) / x 中在 x->+无穷 时的极限(右侧方向逼近)
self.assertEqual(sy.limit(expression , x , sy.oo , '+') , 0)
# 计算 sy.sin(x) / x 中在 x->-无穷 时的极限(左侧方向逼近)
self.assertEqual(sy.limit(expression , x , -sy.oo , '-') , 0)
# 计算 sy.sin(x) / x 中在 x->无穷 时的极限(不区分方向)
self.assertEqual(sy.limit(expression , x , sy.oo , '+-') , 0)
def test_x_sin_1_x(self):
"""
求 x*sin(1/x) 的极限
"""
x = sy.Symbol('x')
expression = x * sy.sin(1 / x)
# 计算 x * sy.sin(1 / x) 中在 x->+0 时的极限(右侧方向逼近)
self.assertEqual(sy.limit(expression , x , 0 , '+') , 0)
# 计算 x * sy.sin(1 / x) 中在 x->-0 时的极限(左侧方向逼近)
self.assertEqual(sy.limit(expression , x , -0 , '-') , 0)
# 计算 x * sy.sin(1 / x) 中在 x->0 时的极限(不区分方向)
self.assertEqual(sy.limit(expression , x , 0 , '+-') , 0)
def test_sin_1_x(self):
"""
求 sin(1/x) 的极限
"""
x = sy.Symbol('x')
expression = sy.sin(1 / x)
# 无限趋近于 0 时会有震荡
ret = sy.limit(sy.sin(1 / x) , x , 0 , '+-')
print(ret , type(ret))
# 计算 sy.sin(1 / x) 中在 x->+无穷 时的极限(右侧方向逼近)
self.assertEqual(sy.limit(expression , x , sy.oo , '+') , 0)
# 计算 sy.sin(1 / x) 中在 x->-无穷 时的极限(左侧方向逼近)
self.assertEqual(sy.limit(expression , x , sy.oo , '-') , 0)
# 计算 sy.sin(1 / x) 中在 x->无穷 时的极限(不区分方向)
self.assertEqual(sy.limit(expression , x , sy.oo , '+-') , 0)
def test_limit_of_a_polynomial_in_x(self):
x = sy.Symbol('x')
# 在 x=-1 处的极限,可以直接代入x=-1进行运算,得到结果为-2
expression_1 = (x ** 2 - 3 * x + 2) / (x - 2)
self.assertEqual(sy.limit(expression_1 , x , -1 , '+-') , -2)
# 在 x=2 处的极限,不能直接代入 x=2进行运算,但是可以做因式分解:
# (x ** 2 - 3 * x + 2) = ( x - 2 ) * ( x - 1 )
self.assertEqual(sy.limit(expression_1 , x , 2 , '+-') , 1)
# 先做因式分解:
# 由 a^3 - b^3 = (a-b)(a^2 + b^2 + ab)
# 得到:
# (x ** 3 - 27) / (x ** 4 - 5 * (x ** 3) + 6 * (x ** 2))
# 可分解为:
# (x - 3) * ( x ** 2 + 3 * x + 9)/( x ** 2 ) * ( x - 3 ) * ( x - 2 )
# 得到:
# ( x ** 2 + 3 * x + 9) / ( x ** 2 ) * ( x - 2 )
# 然后再代入 x=3 进行计算:
# 27/9 = 3
expression_2 = (x ** 3 - 27) / (x ** 4 - 5 * (x ** 3) + 6 * (x ** 2))
self.assertEqual(sy.limit(expression_2 , x , 3 , '+-') , 3)
# 不存在双侧极限,仅存在单侧极限
# 当x>1时极限为正,而当x<1时极限为负
# 双侧极限不一致,且围绕x=1剧烈变化
expression_3 = (2 * (x ** 2) - x - 6) / (x * ((x - 1) ** 3))
self.assertEqual(sy.limit(expression_3 , x , 1 , '+') , -sy.oo)
self.assertEqual(sy.limit(expression_3 , x , 1 , '-') , sy.oo)
self.assertEqual(sy.limit(expression_3 , x , 1 , '+-') , sy.zoo)
# 存在双侧极限
# 将(x-1)^3改变为(x-1)^2
# 则左极限和右极限也都是−∞
expression_4 = (2 * (x ** 2) - x - 6) / (x * ((x - 1) ** 2))
self.assertEqual(sy.limit(expression_4 , x , 1 , '+') , -sy.oo)
self.assertEqual(sy.limit(expression_4 , x , 1 , '-') , -sy.oo)
self.assertEqual(sy.limit(expression_4 , x , 1 , '+-') , -sy.oo)
# 把分子分母同时乘以sqrt(x ** 2 - 9) + 4
# 即使用共轭表达式将x^2−25分解为(x−5)(x+5)并消去分子分母中的公因子
# 此时再代入x=5即可得到10/8
expression_5 = (sqrt(x ** 2 - 9) - 4) / (x - 5)
self.assertAlmostEqual(sy.limit(expression_5 , x , 5 , '+-') , 5 / 4 , delta = 1e-10)
# 对于任意的n>0,只要C是常数,则一定有x趋于无穷时, C/x^n 的极限为 0
n = random.randint(1 , 10000000)
C = random.randint(1 , 10000000)
expression_6 = C / x ** n
self.assertEqual(sy.limit(expression_6 , x , sy.oo , '+-') , 0)
# 当看到某个关于p的多项式p(x)是多于一项时,把它代以
# (p(x)/p(x)的首项) * p(x)的首项
expression_7 = (x - 8 * (x ** 4)) / (7 * (x ** 4) + 5 * (x ** 3) + 2000 * (x ** 2) - 6)
self.assertAlmostEqual(sy.limit(expression_7 , x , sy.oo , '+-') , -8 / 7 , delta = 1e-10)
# 更复杂的进行首项提取的例子,分子分母分别提取
# 并且分子也要分为两部分进行提取,分母也要分为两部分提取
# 对于p(x)/q(x),在 x 趋于无穷时:
# 如果p的次数等于q的次数,则极限是有限的且非零
# 如果p的次数大于q的次数,则极限是∞或−∞
# 如果p的次数小于q的次数,则极限是0.
expression_8 = (((x ** 4) + 3 * x - 99) * (2 - x ** 5)) / (18 * (x ** 7) + 9 * (x ** 6) - 3 * (x ** 2) - 1) * (
x + 1)
self.assertEqual(sy.limit(expression_8 , x , sy.oo , '+-') , -sy.oo)
# 对于首项不清晰的场景
# 对于分母提取首项 2*(x**2)
# 对于分子虽然带有根号,但是很明显16 * (x ** 4)可以变为4 * (x ** 2)的平方
# 因此分子可以提取首项4 * (x ** 2)并将其代入到根号中
expression_9 = (sy.sqrt(16 * (x ** 4) + 8) + 3 * x) / (2 * (x ** 2) + 6 * x + 1)
self.assertEqual(sy.limit(expression_9 , x , sy.oo , '+-') , 2)
# 对分子做细微调整,将 3*x 变为 3 * (x ** 3),此时需要对分子提取首项3 * (x ** 3)
expression_10 = (sy.sqrt(16 * (x ** 4) + 8) + 3 * (x ** 3)) / (2 * (x ** 2) + 6 * x + 1)
self.assertEqual(sy.limit(expression_10 , x , sy.oo , '+-') , sy.oo)
# 含有绝对值的极限
expression_11 = sy.Abs(x) / x
self.assertEqual(sy.limit(expression_11 , x , 0 , '-') , -1)
self.assertEqual(sy.limit(expression_11 , x , 0 , '+') , 1)
# 不存在极限
with self.assertRaises(Exception):
sy.limit(expression_11 , x , 0 , '+-')
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。