前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于 sympy 进行极限计算

基于 sympy 进行极限计算

原创
作者头像
密码学人CipherHUB
修改2025-05-23 17:26:50
修改2025-05-23 17:26:50
18600
代码可运行
举报
文章被收录于专栏:数理视界数理视界
运行总次数:0
代码可运行

极限是微积分和数学分析的核心概念,它描述了函数在某个点的邻域或无穷远处的行为特征。本文将结合Python的SymPy库实现,深入浅出地讲解极限计算的方法与技巧。

一、基础函数的极限特征

1.1 简单分式函数(1/x)

对于函数f(x)=1/x,当x趋近于0时表现出明显的方向性差异:

代码语言:python
代码运行次数:0
运行
复制
x = sy.Symbol('x')
expression = 1 / x

# 右侧趋近返回正无穷
sy.limit(expression, x, 0, '+')  # ∞

# 左侧趋近返回负无穷 
sy.limit(expression, x, 0, '-')  # -∞

# 双向趋近返回复数无穷
sy.limit(expression, x, 0, '+-')  # zoo

这揭示了极限的重要性质——方向敏感性。实际应用中必须明确趋近方向,否则可能得到错误结论。

1.2 经典正弦函数(sin(x)/x)

这个函数在物理波动和工程振动分析中广泛应用:

代码语言:python
代码运行次数:0
运行
复制
expression = sy.sin(x)/x

# 无论x趋近正负无穷,结果都是0
sy.limit(expression, x, sy.oo)  # 0

其收敛性源于正弦函数的有界性(|sin(x)| ≤ 1),当分母x趋向无穷时,整体趋近于0。

二、震荡函数的极限处理

2.1 高频震荡函数(x*sin(1/x))

代码语言:python
代码运行次数:0
运行
复制
expression = x * sy.sin(1/x)

# 所有方向的极限均为0
sy.limit(expression, x, 0)  # 0

虽然sin(1/x)在0点附近无限震荡,但乘数x的线性衰减压制了震荡幅度,形成稳定的收敛结果。

2.2 纯震荡函数(sin(1/x))

代码语言:python
代码运行次数:0
运行
复制
expression = sy.sin(1/x)

# 双向趋近时极限不存在
sy.limit(expression, x, 0)  # AccumBounds(-1, 1)

此时函数在-1,1之间无限震荡,不收敛于任何确定值。SymPy返回震荡边界,表示极限不存在。

三、多项式函数的破解之道

3.1 因式分解法

对分式函数(x²-3x+2)/(x-2):

代码语言:python
代码运行次数:0
运行
复制
expression = (x**2-3x+2)/(x-2)

# 分解后简化为(x-1)(x-2)/(x-2) → x-1
sy.limit(expression, x, 2)  # 1

通过因式分解消除分母的零因子,使直接代入成为可能。

3.2 共轭表达式法

处理含根号的分式:

代码语言:python
代码运行次数:0
运行
复制
expression = (sy.sqrt(x**2-9)-4)/(x-5)

# 分子分母同乘共轭表达式后化简
sy.limit(expression, x, 5)  # 5/4

通过有理化处理消除根号,将问题转化为多项式极限计算。

四、无穷远处的行为分析

4.1 首项主导法则

对于有理函数:

代码语言:python
代码运行次数:0
运行
复制
expression = (x-8x⁴)/(7x⁴+5x³+2000x²-6)

# 首项系数之比决定极限
sy.limit(expression, x, sy.oo)  # -8/7

在x→±∞时,最高次项主导函数行为,其他项可忽略。

4.2 混合函数分析

代码语言:python
代码运行次数:0
运行
复制
expression = (sy.sqrt(16x⁴+8)+3x³)/(2x²+6x+1)

# 分子首项为3x³,分母为2x² → 整体趋近∞
sy.limit(expression, x, sy.oo)  # ∞

当分子次数高于分母时,函数将发散至无穷。

五、特殊函数的极限特征

5.1 绝对值函数

符号函数在零点处的行为:

代码语言:python
代码运行次数:0
运行
复制
expression = sy.Abs(x)/x

sy.limit(expression, x, 0, '+')  # 1
sy.limit(expression, x, 0, '-')  # -1

左右极限不一致导致整体极限不存在,这在信号处理中对应阶跃函数的变化。

六、实战技巧总结

技巧类型

适用场景

实现方法

因式分解

可约分的有理函数

factor()函数进行多项式分解

共轭表达式

含根号的无理式

分子分母同乘共轭项

泰勒展开

复杂函数在特定点展开

series()函数进行级数展开

首项提取

无穷远处的极限分析

提取分子分母最高次项

夹逼定理

无法直接计算的情形

构造上下界函数进行逼近

完整测试代码

代码语言:python
代码运行次数:0
运行
复制
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 , '+-')

典型计算场景

因式分解

简单因式分解
简单因式分解
立方差公式
立方差公式
立方差因式分解
立方差因式分解

x=a处的极限场景

x=a处的各种极限
x=a处的各种极限
x=a时两边极限不一致
x=a时两边极限不一致

x=a时的平方根极限

共轭表达式
共轭表达式
再次进行因式分解
再次进行因式分解

x=♾️时的极限

n>0时的高级项作为分母
n>0时的高级项作为分母
高阶多项式提取首项
高阶多项式提取首项
更复杂的首项提取
更复杂的首项提取
各因子分别提取首项
各因子分别提取首项
带有根号的高阶多项式首项提取
带有根号的高阶多项式首项提取
更高次数的项3x^3在根号外面
更高次数的项3x^3在根号外面

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、基础函数的极限特征
    • 1.1 简单分式函数(1/x)
    • 1.2 经典正弦函数(sin(x)/x)
  • 二、震荡函数的极限处理
    • 2.1 高频震荡函数(x*sin(1/x))
    • 2.2 纯震荡函数(sin(1/x))
  • 三、多项式函数的破解之道
    • 3.1 因式分解法
    • 3.2 共轭表达式法
  • 四、无穷远处的行为分析
    • 4.1 首项主导法则
    • 4.2 混合函数分析
  • 五、特殊函数的极限特征
    • 5.1 绝对值函数
  • 六、实战技巧总结
  • 完整测试代码
  • 典型计算场景
    • 因式分解
    • x=a处的极限场景
    • x=a时的平方根极限
    • x=♾️时的极限
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档