【SymPy】(一)SymPy简介
【SymPy】(二)使用SymPy需要避开的坑
【SymPy】(三)基本操作(四)打印

简化

文章目录

  • 简化
    • 1 simplify
    • 2 多项式/有理函数简化
      • 2.1 expand
      • 2.2 factor
      • 2.2.3 collect
      • 2.2.4 cancel
      • 2.2.5 apart
    • 3 三角化简Trigonometric Simplification
      • 3.1 trigsimp
      • 3.2 expand_trig
    • 4 幂( Power)简化函数
      • 4.1 powsimp
      • 4.2 expand_power_exp / expand_power_base
      • 4.3 powdenest
    • 5 指数和对数( Exponentials and logarithms)
      • 5.1 expand_log
      • 5.2 logcombine
    • 6 特殊的函数
      • 6.1 rewrite
      • 6.2 expand_func
      • 6.3 hyperexpand
      • 6.4 combsimp
In [1]: from sympy import *In [2]: x, y, z = symbols('x y z')In [3]: init_printing(use_unicode=True)

1 simplify

符号操作系统最有用的特性之一是简化数学表达式。SymPy有几十个函数来执行各种简化。还有一个名为simplify()的通用函数,它通过智能的方式应用所有简化函数然后得出最简单的表达形式。
例如:

In [7]: simplify(sin(x)**2 + cos(x)**2)
Out[7]: 1In [8]: simplify((x**3 + x**2 - x - 1)/(x**2 + 2*x + 1))
Out[8]: x - 1In [9]: simplify(gamma(x)/gamma(x - 2))
Out[9]: (x - 2)⋅(x - 1)

这里,gamma(x)是gamma函数Γ(x)
实数域上:
Γ(x)=∫0+∞tx−1e−tdt(x>0)\Gamma(x)=\int_{0}^{+\infty} t^{x-1} e^{-t} \mathrm{~d} t(x>0)Γ(x)=∫0+∞​tx−1e−t dt(x>0)

simplify()应用SymPy中所有主要的简化操作,并使用启发式算法来确定最简单的结果,但所谓的“最简单”并不是明确的。
例如,我们想“简化”x2+2x+1x^{2}+2 x+1x2+2x+1为(x+1)2(x+1)^{2}(x+1)2:

In [10]: simplify(x**2 + 2*x + 1)
Out[10]: 2
x  + 2⋅x + 1

可以看到结果不是我们想要的。

simplify()的另一个缺陷是它寻找最简表达式会非常慢,因为它在选择最佳的简化方法之前会尝试多种简化方法。如果你已经确切地知道您要进行哪种简化,那么最好选择特定的简化函数。

应用特定的简化函数还有一个优点,即特定函数对其输出的形式有一定的保证。这些将在后面讨论。
例如,当对有理系数多项式调用factor()时,可以保证将多项式分解为不可约因子。但simplify()没有保证,因为它完全是启发式的。

如果你只想将表达式缩减为更简单的形式,simplify()会是个不错的选择。在看到simplify()返回的结果后,可以选择应用特定的函数,以获得更精确的结果。当你不知道表达式将采用什么形式,并且需要简化它时,simplify()也很有用。

2 多项式/有理函数简化

2.1 expand

expand()是SymPy中最常见的简化函数之一。可用于展开多项式表达式。

例如:

In [11]: expand((x + 1)**2)
Out[11]: 2
x  + 2⋅x + 1In [12]: expand((x + 2)*(x - 3))
Out[12]: 2
x  - x - 6

给定一个多项式,expand()将把它转换成一个单项式和的标准形式。

expand()听起来可能不像一个简化函数。毕竟,就其名称而言,它使表达式变长,而不是变短,但通常一个表达式在调用expand()时会因为相消而变小。

In [13]: expand((x + 1)*(x - 2) - (x - 1)*x)
Out[13]: -2

2.2 factor

factor()将多项式分解为不可约的有理数因子。
例如:

In [14]: factor(x**3 - x**2 + x - 1)
Out[14]: ⎛ 2    ⎞
(x - 1)⋅⎝x  + 1⎠In [15]: factor(x**2*z + 4*x*y*z + 4*y**2*z)
Out[15]: 2
z⋅(x + 2⋅y)

对于多项式来说,factor()expand()相反。factor()在有理数上使用一个完整的多元因式分解算法,这意味着factor()返回的每个因子保证是不能再化简的。

如果你对因子本身感兴趣,factor_list会返回一个更结构化的输出。

In [16]: factor_list(x**2*z + 4*x*y*z + 4*y**2*z)
Out[16]: (1, [(z, 1), (x + 2⋅y, 2)])

注意,factorexpand的输入不必是严格意义上的多项式:

In [17]: expand((cos(x) + sin(x))**2)
Out[17]: 2                           2
sin (x) + 2⋅sin(x)⋅cos(x) + cos (x)In [18]: factor(cos(x)**2 + 2*cos(x)*sin(x) + sin(x)**2)
Out[18]: 2
(sin(x) + cos(x))

2.2.3 collect

collect()收集表达式中某个项的公共幂。例如

In [19]: expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3In [20]: expr
Out[20]: 3    2        2
x  - x ⋅z + 2⋅x  + x⋅y + x - 3In [21]: collected_expr = collect(expr, x)In [22]: collected_expr
Out[22]: 3    2
x  + x ⋅(-z + 2) + x⋅(y + 1) - 3

collect().coeff()方法结合使用特别有用。表达式系数(x,n)给出了x**n在表达式中的系数:

In [23]: collected_expr.coeff(x, 2)
Out[23]: -z + 2

2.2.4 cancel

cancel()将任意有理函数转换为标准规范形式pq\frac{p}{q}qp​,其中ppp和qqq是无公因式的展开多项式,ppp和qqq的前导系数没有分母(即为整数)。

In [24]: cancel((x**2 + 2*x + 1)/(x**2 + x))
Out[24]:
x + 1
─────x
In [25]: expr = 1/x + (3*x/2 - 2)/(x - 4)In [26]:  expr
Out[26]:
3⋅x
─── - 22        1
─────── + ─x - 4    xIn [27]: cancel(expr)
Out[27]: 2
3⋅x  - 2⋅x - 8
──────────────22⋅x  - 8⋅x
In [28]: expr = (x*y**2 - 2*x*y*z + x*z**2 + y**2 - 2*y*z + z**2)/(x**2 - 1)In [29]: expr
Out[29]: 2                2    2            2
x⋅y  - 2⋅x⋅y⋅z + x⋅z  + y  - 2⋅y⋅z + z
───────────────────────────────────────2x  - 1In [30]: cancel(expr)
Out[30]: 2            2
y  - 2⋅y⋅z + z
───────────────x - 1

请注意,由于factor()将完全分解表达式的分子和分母,因此它也可以用于执行相同的操作:

In [31]:  factor(expr)
Out[31]: 2
(y - z)
────────x - 1

但是,如果您只想确保表达式是分子分母相消形式,那么cancel()factor()更有效。

2.2.5 apart

apart()对有理函数执行部分分式分解。

In [35]: expr = (4*x**3 + 21*x**2 + 10*x + 12)/(x**4 + 5*x**3 + 5*x**2 + 4*x)In [36]: expr
Out[36]: 3       2
4⋅x  + 21⋅x  + 10⋅x + 12
────────────────────────4      3      2x  + 5⋅x  + 5⋅x  + 4⋅xIn [37]: apart(expr)
Out[37]: 2⋅x - 1       1     3
────────── - ───── + ─2           x + 4   x
x  + x + 1

3 三角化简Trigonometric Simplification

sympy遵循Python对反三角函数的命名约定,在函数名的前面加上一个a
例如,反余弦或弧余弦称为acos()

In [38]: acos(x)
Out[38]: acos(x)In [39]: cos(acos(x))
Out[39]: xIn [40]: asin(1)
Out[40]:
π
─
2

3.1 trigsimp

要用三角恒等式简化表达式,则使用trigsimp()

In [42]: trigsimp(sin(x)**2 + cos(x)**2)
Out[42]: 1In [43]: trigsimp(sin(x)**4 - 2*cos(x)**2*sin(x)**2 + cos(x)**4)
Out[43]:
cos(4⋅x)   1
──────── + ─2       2In [44]: trigsimp(sin(x)*tan(x)/sec(x))
Out[44]: 2
sin (x)

trigsimp()也适用于双曲三角函数。

In [45]: trigsimp(cosh(x)**2 + sinh(x)**2)
Out[45]: cosh(2⋅x)In [46]: trigsimp(sinh(x)/tanh(x))
Out[46]: cosh(x)

simplify()非常相似,trigsimp()将各种三角恒等式应用于输入表达式,然后启发式地返回“最佳”恒等式。

3.2 expand_trig

要展开三角函数,即应用三角函数和角公式,则使用expand_trig()

In [47]: expand_trig(sin(x + y))
Out[47]: sin(x)⋅cos(y) + sin(y)⋅cos(x)In [48]: expand_trig(tan(2*x))
Out[48]: 2⋅tan(x)
─────────────2
- tan (x) + 1

因为expand_trig()倾向于使三角表达式变大,而trigsimp()倾向于使它们变小,所以可以使用trigsimp()反向应用这些恒等式

In [49]: trigsimp(sin(x)*cos(y) + sin(y)*cos(x))
Out[49]: sin(x + y)

4 幂( Power)简化函数

在我们引入幂简化函数之前,先从数学上讨论幂所具有的三种等式:
1、xaxb=xa+b1、x^{a} x^{b}=x^{a+b}1、xaxb=xa+b
2、xaya=(xy)a2、x^{a} y^{a}=(x y)^{a}2、xaya=(xy)a
3、(xa)b=xab3、\left(x^{a}\right)^{b}=x^{a b}3、(xa)b=xab

等式1总是正确的
等式2不一定是正确的。例如,如果x=y=−1x=y=-1x=y=−1,a=12a=\frac{1}{2}a=21​,xaya=−1−1=i⋅i=−1x^{a} y^{a}=\sqrt{-1} \sqrt{-1}=i\cdot i=-1xaya=−1​−1​=i⋅i=−1,而(xy)a=−1⋅−1=1=1(x y)^{a}=\sqrt{-1 \cdot-1}=\sqrt{1}=1(xy)a=−1⋅−1​=1​=1。只有当xxx和yyy是非负的,aaa是实数时,恒等式2才是正确的。不满足条件的话可能导致:xy≠xy\sqrt{x} \sqrt{y} \neq \sqrt{x y}x​y​​=xy​

等式3也不一定是正确的。例如:如果x=−1,a=2,b=12x=-1,a=2,b=\frac{1}{2}x=−1,a=2,b=21​,那么(xa)b=((−1)2)1/2=1=1\left(x^{a}\right)^{b}=\left((-1)^{2}\right)^{1 / 2}=\sqrt{1}=1(xa)b=((−1)2)1/2=1​=1,而xab=(−1)2⋅1/2=(−1)1=−1x^{a b}=(-1)^{2 \cdot 1 / 2}=(-1)^{1}=-1xab=(−1)2⋅1/2=(−1)1=−1,只有当bbb为整数等式3才成立。
不满足条件的话可能导致:x2≠x\sqrt{x^{2}} \neq xx2​​=x,1x≠1x\sqrt{\frac{1}{x}} \neq \frac{1}{\sqrt{x}}x1​​​=x​1​

记住以上内容很重要,因为默认情况下,SymPy不会执行不正确的简化

使用SymPy进行简化,涉及到只有在某些假设下才成立的特性时,我们需要对符号进行假设。我们稍后将对假设系统进行全面讨论,但目前,我们只需要知道以下内容。

  • 默认情况下,SymPy符号被认为是复数。也就是说,除非对复数适用,否则简化不会应用于给定符号的表达式
  • 通过将假设传递给Symbols(),可以为符号提供不同的假设。在本节的其余部分,我们将假设xy是正数,ab是实数的。我们将把ztc作为任意的复数符号。
In [53]:  x, y = symbols('x y', positive=True)In [54]: a, b = symbols('a b', real=True)In [55]: z, t, c = symbols('z t c')

注:在SymPy中,sqrt(x)x**Rational(1,2)是同一对象

In [51]: sqrt(x) == x**Rational(1, 2)
Out[51]: True

4.1 powsimp

powsimp()从左到右应用等式1和等式2。

In [56]: powsimp(x**a*x**b)
Out[56]: a + b
xIn [57]:  powsimp(x**a*y**a)
Out[57]: a
(x⋅y)

请注意,如果powsimp()无效,它将拒绝进行简化。

In [58]: powsimp(t**c*z**c)
Out[58]: c  c
t ⋅z

可以传递force=True标志进行强制简化,而不考虑假设。

In [59]: powsimp(t**c*z**c, force=True)
Out[59]: c
(t⋅z)

请注意,在某些情况下,特别是当指数是整数或有理数且等式2成立时,它将自动按等式从右到左拆分:

In [60]:  (z*t)**2
Out[60]: 2  2
t ⋅zIn [61]:  sqrt(x*y)
Out[61]: √x⋅√y

这意味着不可能用powsimp()撤消此特性,因为它们会再次自动拆分。

In [62]: powsimp(z**2*t**2)
Out[62]: 2  2
t ⋅zIn [63]: powsimp(sqrt(x)*sqrt(y))
Out[63]: √x⋅√y

4.2 expand_power_exp / expand_power_base

expand_power_exp()expand_power_base() 分别从右到左应用等式1和等式2的公式。

In [64]: expand_power_exp(x**(a + b))
Out[64]: a  b
x ⋅xIn [65]: expand_power_base((x*y)**a)
Out[65]: a  a
x ⋅y

powsimp()一样,如果等式2无效,则不应用它。

In [66]: expand_power_base((z*t)**c)
Out[66]: c
(t⋅z)

也可以强制转换

In [67]: expand_power_base((z*t)**c, force=True)
Out[67]: c  c
t ⋅z

如果幂是数字,则等式1将自动应用,并且不能使用 expand_power_exp()撤消。

In [68]: x**2*x**3
Out[68]: 5
xIn [69]: expand_power_exp(x**5)
Out[69]: 5
x

4.3 powdenest

powdenest()从左到右应用等式3。

In [70]: powdenest((x**a)**b)
Out[70]: a⋅b
x

如前所述,如果在给定的假设下不成立,则不应用该恒等式。

In [71]: powdenest((z**a)**b)
Out[71]: b
⎛ a⎞
⎝z ⎠

同样可以强制转换:

In [72]: powdenest((z**a)**b, force=True)
Out[72]: a⋅b
z

5 指数和对数( Exponentials and logarithms)

注意:在SymPy中,与Python和大多数编程语言一样,log是自然对数,也称为ln。SymPy会自动提供一个别名log,log=ln

In [73]: ln(x)
Out[73]: log(x)

对数和幂有相似,主要有两种特性
1. log⁡(xy)=log⁡(x)+log⁡(y)\text { 1. } \log (x y)=\log (x)+\log (y) 1. log(xy)=log(x)+log(y)
2. log⁡(xn)=nlog⁡(x)\text { 2. } \log \left(x^{n}\right)=n \log (x) 2. log(xn)=nlog(x)

等式成立的充分条件是xy为正数,n为实数。

In [74]: x, y = symbols('x y', positive=True)In [75]: n = symbols('n', real=True)

跟前面一样,zt将是没有额外假设的Symbols。

5.1 expand_log

要从左到右应用特性1和特性2,请使用expand_log()。而且,除非这些标识是有效的,否则不会应用它们

In [76]: expand_log(log(x*y))
Out[76]: log(x) + log(y)In [77]: expand_log(log(x/y))
Out[77]: log(x) - log(y)In [78]: expand_log(log(x**2))
Out[78]: 2⋅log(x)In [79]: expand_log(log(x**n))
Out[79]: n⋅log(x)In [80]: expand_log(log(z*t))
Out[80]: log(t⋅z)

同样可以强制展开:

In [82]: expand_log(log(z**2))
Out[82]: ⎛ 2⎞
log⎝z ⎠In [83]: expand_log(log(z**2), force=True)
Out[83]: 2⋅log(z)

5.2 logcombine

使用logcombine(),从右向左应用特性1和特性2:

In [84]: logcombine(log(x) + log(y))
Out[84]: log(x⋅y)In [85]: logcombine(n*log(x))
Out[85]: ⎛ n⎞
log⎝x ⎠In [86]: logcombine(n*log(z))
Out[86]: n⋅log(z)

可强制执行:

In [87]: logcombine(n*log(z), force=True)
Out[87]: ⎛ n⎞
log⎝z ⎠

6 特殊的函数

SymPy实现了几十个特殊函数,从组合数学中的函数到数学物理。

让我们介绍一下SymPy中的一些特殊函数。

In [88]: x, y, z = symbols('x y z')In [89]: k, m, n = symbols('k m n')

factorial是阶乘函数。 factorial(n)表示n!=1⋅2⋯(n−1)⋅nn !=1 \cdot 2 \cdots(n-1) \cdot nn!=1⋅2⋯(n−1)⋅n。n!n!n!表示nnn个不同项的排列。

In [90]: factorial(n)
Out[90]: n!

二项式系数函数是binomial。binomial(n, k)表示(nk)\left(\begin{array}{l}n \\k\end{array}\right)(nk​),从一组n个不同项的项目中选择k个项的方法数,即组合数。也写成CnkC_n^kCnk​

In [91]:  binomial(n, k)
Out[91]: ⎛n⎞
⎜ ⎟
⎝k⎠

gamma函数
Γ(z)=∫0∞tz−1e−tdt\Gamma(z)=\int_{0}^{\infty} t^{z-1} e^{-t} d tΓ(z)=∫0∞​tz−1e−tdt

In [92]: gamma(z)
Out[92]: Γ(z)

广义超几何函数( generalized hypergeometric function)是hyper:hyper([a_1, …, a_p], [b_1, …,b_q], z) ,表示
rFq(a1,⋯,apb1,⋯,bq∣z){ }_{r} F_{q}\left(\begin{array}{l}a_{1}, \cdots, a_{p} \\b_{1}, \cdots, b_{q}\end{array} \mid z\right)r​Fq​(a1​,⋯,ap​b1​,⋯,bq​​∣z)
最常见的情况是2F1_2F^12​F1,它通常被称为普通的超几何函数。

In [93]: hyper([1, 2], [3], z)
Out[93]: ┌─  ⎛1, 2 │  ⎞├─  ⎜     │ z⎟
2╵ 1 ⎝ 3   │  ⎠

6.1 rewrite

处理特殊函数的一种常见方法是根据其他函数重写它们。这适用于SymPy中的任何函数,而不仅仅是特殊函数。使用:expr.rewrite(function)

In [94]: tan(x).rewrite(sin)
Out[94]: 2
2⋅sin (x)
─────────sin(2⋅x)In [95]: factorial(x).rewrite(gamma)
Out[95]: Γ(x + 1)

6.2 expand_func

在某些方面扩展特殊函数,使用expand_func().

In [96]: expand_func(gamma(x + 3))
Out[96]: x⋅(x + 1)⋅(x + 2)⋅Γ(x)

6.3 hyperexpand

用更标准的函数重写hyper,使用hyperexpand().

In [97]: hyperexpand(hyper([1, 1], [2], z))
Out[97]:
-log(-z + 1)
─────────────z

hyperexpand()也适用于更一般的Meijer G函数

In [98]: expr = meijerg([[1],[1]], [[1],[]], -z)In [99]: expr
Out[99]:
╭─╮1, 1 ⎛1  1 │   ⎞
│╶┐     ⎜     │ -z⎟
╰─╯2, 1 ⎝1    │   ⎠
In [100]: hyperexpand(expr)
Out[100]: 1─z
ℯ

6.4 combsimp

简化组合表达式,使用combsimp().

In [102]: n, k = symbols('n k', integer=True)In [103]: combsimp(factorial(n)/factorial(n - 3))
Out[103]: n⋅(n - 2)⋅(n - 1)

未完待续:

【SymPy】(六)微积分

【SymPy】(七)方程求解

【SymPy】(八)矩阵

【SymPy】(九)高级表达式操作

【SymPy】(五)简化相关推荐

  1. Python——利用sympy模块进行数学计算

    参考链接: SymPy简易教程 SymPy库常用函数 Python sympy 模块常用功能(一) Python科学计算库SymPy初探 简介 SymPy是一个符号计算的Python库.它的目标是成为 ...

  2. Sympy代数符号运算库

    Python之Sympy代数符号运算库 计算器与数学 计算机代数系统 CAS Sympy符号运算的基本使用指南 Sympy 与 Math 函数的区别 定义变量 Symbol('x'), symbols ...

  3. 使用 CodeIgniter 框架快速开发 PHP 应用(五)

    原文:使用 CodeIgniter 框架快速开发 PHP 应用(五) 简化 HTML 页面和表格设计 这一章介绍了又一个节约你的时间而且使你的代码更具安全性和逻辑性的领域. 第一,我们将会介绍创建视图 ...

  4. python一元一次方程虚数解_python – SymPy虚数

    我正在乱写一些SymPy代码来处理带有虚数的符号表达式. 首先,我想让它将x和y作为实数,并找到x = iy的解决方案.所以我可以这样做. x, y = sympy.symbols("x y ...

  5. 信息安全数学基础(一):同余

    一.同余的概念 给定一个正整数m,如果a-b被m整除(即m|(a-b)),则称两个整数a,b模m同余,否则叫做a,b模m不同余. 同余的判断 设m是一个正整数,a,b是两个整数,则 a=b(mod m ...

  6. 教学|zbrush图片转浮雕的方法,diy你想要的logo

    什么是浮雕灰度图?首先,灰度图用我们通常的俗话来说就是黑白图片,当然黑白图片不止有黑色和白色,还有灰色.它是和彩色图片相对的.浮雕灰度图是指用颜 色来表示物体局部远近关系的图片,专门作为做浮雕.颜色越 ...

  7. 5.3Python数据处理篇之Sympy系列(三)---简化操作

    目录 5.3简化操作 目录 前言 (一)有理数与多项式的简化 1.最简化-simplify() 2.展开-expand() 3.提公因式-factor() 4.合并同类项-ceiling() 5.简化 ...

  8. python解复杂方程_Python数据处理篇之Sympy系列(五)---解方程

    前言 sympy不仅在符号运算方面强大,在解方程方面也是很强大. 本章节学习对应官网的:Solvers 官方教程 (一)求解多元一次方程-solve() 1.说明: 解多元一次方程可以使用solve( ...

  9. python 解方程 sympy_Python数据处理篇之Sympy系列(五)---解方程

    前言 sympy不仅在符号运算方面强大,在解方程方面也是很强大. 本章节学习对应官网的:Solvers 官方教程 (一)求解多元一次方程-solve() 1.说明: 解多元一次方程可以使用solve( ...

最新文章

  1. CRM lifecycle status
  2. Spring中实现自定义事件
  3. 【原创】Js:日期处理(日期格式必须【yyyy-mm-dd】才能转成long的毫秒!其他的不是【年-月-日】的格式,结果会是【NaN】)...
  4. 【bzoj5072】[Lydsy十月月赛]小A的树 树形背包dp
  5. 正则表达式替换字符串
  6. python10进制2进制转换
  7. DSkin的TabControl在设计视图报错
  8. 全国计算机自动化办公专业人才证书,急问懂计算机证书的人
  9. DevExpress 主从表折叠显示
  10. cad打印去掉边框_CAD中图片的边框怎么去除? - CAD自学网
  11. 线性渐变与径向渐变与重复渐变
  12. #AD18#PCB绘制时合并铜皮
  13. 证券公司交易系统架构演进探析
  14. 关于macbookpro外接显示器(非扩展屏幕,只有一个外接显示器当屏幕)手贱把分辨率设置成1080i(显示器所不支持的分辨率)所造成显示器黑屏并弹出“不支持此视频格式”的解决方法
  15. Consul + fabio 实现自动服务发现、负载均衡 1
  16. open函数里的newline
  17. 删除姓名、年龄重复的记录——数据库
  18. LeetCode每日一题 1238.循环码排列
  19. 硅谷送货机器人:脚下的路不好走
  20. 应用于语义分割问题的深度学习技术综述

热门文章

  1. 拯救007 迪杰斯特拉最短路解决
  2. Android 扇形图
  3. Kubernetes使用Prometheus全方位监控(李作强)
  4. Vue中动态显示表格内容
  5. 密钥管理系统-为你的天翼云资产上把“锁
  6. QNX BSP包目录结构
  7. A. Boboniu Chats with Du
  8. 内存分析(一)AVPacket
  9. 图像边缘锐化,其实很简单-提取边界+处理边界
  10. icp备案和公安备案