1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > latex 符号_sympy: 符号运算-1

latex 符号_sympy: 符号运算-1

时间:2023-05-06 08:08:12

相关推荐

latex 符号_sympy: 符号运算-1

本文主要参考资料来自sympy的官网:

Introduction - SymPy 1.4 documentation​

一般,我们使用计算机软件进行数学计算,主要是数值计算,就算有变量,也是代入具体数值来算的,我们在初中到大学学到的符号计算,很多时候无法用计算机来进行,比如下面的多项式化简:

上面的式中没有任何一个具体数值,完全是符号进行计算,这时我们只能手算了。当然,我们可以用商业软件mathematics, 但是非常昂贵,幸好我们还有python,有了开源的sympy模块,我们可以做到如下功能:

core symbolic mathematics: 基础运算,包括:化简Simplification,各种函数运算等;Polynomials:多项式运算及求解Calculus:极限、微分、积分Solving equations:各种方程求解Combinatorics:组合学Discrete math:离散数学Matrices:矩阵运算Geometry:几何学Physics:物理学Statistics:统计学Cryptography:密码学

下面我们分几个专题来介绍其功能,这篇介绍基础的运算。

Symbols : 符号

在进行符号运算前,必须先定义符号,下面的例子我们定义了两个符号x,y:

import sympy as syx,y = sy.symbols('x y') #符号间用空格隔开print(type(x))print(type(y))

输出:

sympy.core.symbol.Symbolsympy.core.symbol.Symbol

2. Symbols expression: 符号表达式

当一个表达式中有任何一个变量是sympy symbol,就变成一个symbols expression,它不会直接进行运算,除非你使用subs()方法代入具体的数值,看下面的例子:

import sympy as syx,y=sy.symbols("x y")f=x**2+3*x-5print(f"f(x)={f}") #直接打印f是显示表达式xx=3print(f"f({xx})={f.subs({x:xx})}") #代入具体数值来计算最终的结果yy=4f1=(x**2+y**2)**0.5print(f"f1(x,y)={f1}") #直接打印f1是显示表达式print(f"f1({xx},{yy})={f1.subs({x:xx, y:yy})}") #代入具体数值来计算最终的结果

结果:

f(x)=x**2 + 3*x - 5f(3)=13f1(x,y)=(x**2 + y**2)**0.5f1(3,4)=5.00000000000000

3. Substitution : 代换

上面的例子,显示了如何在表达式中代入具体的数值,但是替换还可以有更多的可能,看下面的例子:

, --->

import sympy as sya,x,t=sy.symbols("a x t")f=sy.cos(x)print(f"f(t)={f.subs({x: a**t})}")

输出:

f(t)=cos(a**t)

4.evalf:计算出具体的值

不单单用sympy symbols组成的表达式,用sympy functionssympy Rational组成的表达式,都是不会直接计算出实际的数值,这时候可以用evalf函数来实际计算出具体的数值,看下例:

import sympy as syy = sy.sqrt(2)+sy.Rational(3,8)print(f"{y}={y.evalf()}")

输出:

3/8 + sqrt(2)=1.78921356237310

5. 更漂亮和专业的输出

ipython中,运行:sympy.init_printing()后,可以以比较漂亮的格式来打印(用sympy.pprint()函数)输出公式,比如:

import sympy as sysy.init_printing()sy.pprint(x**2+sy.Rational(1,3))

输出:

2 1x + ─3

如果在jupyter notebook中,可以用下面的方法用latex来输出漂亮的公式:

from IPython.display import display, Lateximport sympy as sysy.init_printing()x,y=sy.symbols("x y")f=x**2+3*x-5display(Latex(f"$$f(x)={sy.latex(f)}$$"))xx=3sy.pprint(f"f({xx})={f.subs({x:xx})}")yy=4f1=sy.sqrt(x**2+y**2)display(Latex(f"$$f_1(x,y)={sy.latex(f1)}$$"))sy.pprint(f"f1({xx},{yy})={f1.subs({x:xx, y:yy})}")

输出:

关于latex的介绍,参见我的另一个专栏。

6. Simplification : 化简

对于sympy来说,最强大的一点就是对公式进行化简,下面显示几个例子:

from IPython.display import display, Lateximport sympy as sysy.init_printing()x = sy.symbols("x")y = (x**3 + x**2 - x - 1)/(x**2 + 2*x + 1)display(Latex(f"$${sy.latex(y)}={sy.latex(sy.simplify(y))}$$"))

输出:

这里是用simplify()函数,绝大部分情况下它很好用,就是有几个问题:

它不能控制我们最终想要的形式,比如想要多项式(和式a+b+c)的最简式,还是多项乘积(a*b*c)的最简式,这可以用后面介绍的两个函数来取代;它速度比较慢,同样,可以用其他更快的函数取代,但是通用性没有它好。

当我们需要化简为和式的表达式时,可以用expand()函数,参见下例:

from IPython.display import display, Lateximport sympy as sysy.init_printing()x = sy.symbols("x")y = (x + 1)**2display(Latex(f"$${sy.latex(y)}={sy.latex(sy.expand(y))}$$"))

输出:

当我们需要化简为乘积表达式时,可以用factor()函数,参见下例:

from IPython.display import display, Lateximport sympy as sysy.init_printing()x = sy.symbols("x")y = x**3 - x**2 + x - 1display(Latex(f"$${sy.latex(y)}={sy.latex(sy.factor(y))}$$"))

输出:

当我们的表达式各项有相同的变量,我们可以用collect()函数来合并同阶的项,看下例:

from IPython.display import display, Lateximport sympy as sysy.init_printing()x,y,z = sy.symbols("x y z")f = x*y + x - 3 + 2*x**2 - z*x**2 + x**3display(Latex(f"$${sy.latex(f)}={sy.latex(sy.collect(f,x))}$$"))

输出:

当我们需要把表达式转换为

这样的最简式的时候,可以用cancel()函数,它会上下消除相同的项,见下例,另,cancel()函数最后分子分母都化简为多项式的和式,如果要化简为乘积式,可以用factor()函数。

from IPython.display import display, Lateximport sympy as sysy.init_printing()x,y,z = sy.symbols("x y z")f = (x*y**2 - 2*x*y*z + x*z**2 + y**2 - 2*y*z + z**2)/(x**2 - 1)display(Latex(f"$${sy.latex(f)}={sy.latex(sy.cancel(f))}={sy.latex(sy.factor(f))}$$"))

输出:

下面看看apart()函数,可以用来把分数表示的多项式因式分解,看例子:

from IPython.display import display, Lateximport sympy as sysy.init_printing()x,y,z = sy.symbols("x y z")f = (4*x**3 + 21*x**2 + 10*x + 12)/(x**4 + 5*x**3 + 5*x**2 + 4*x)display(Latex(f"$${sy.latex(f)}={sy.latex(sy.apart(f))}$$"))print(sy.latex(f), sy.latex(sy.apart(f)))

输出:

对于三角函数,可以用:trigsimp()函数来化简,比如下例:

from IPython.display import display, Lateximport sympy as sysy.init_printing()x,y,z = sy.symbols("x y z")f = sin(x)**4 - 2*cos(x)**2*sin(x)**2 + cos(x)**4display(Latex(f"$${sy.latex(f)}={sy.latex(sy.trigsimp(f))}$$"))

反过来,可以用expand_trig()函数来展开三角函数,看下例:

from IPython.display import display, Lateximport sympy as sysy.init_printing()x,y,z = sy.symbols("x y z")f = sin(x+y)display(Latex(f"$${sy.latex(f)}={sy.latex(sy.expand_trig(f))}$$"))

输出:

对于指数函数的化简,比较麻烦,因为一般指数函数的形式:

,对于底: 和指数: ,当它们取不同类型的值或范围的时候,其结果是不一样的,比如: :当 都是正数,且 是实数,可以化简为: ,但是 其他情况就不行,比如设 , ,则 ,而 ,两边不相等; :当 是整数时,可以化简为: ,但是其他情况下,就不行,比如:设: , 而 ,两者不相同; :对于任何情况都合适。

缺省情况下,sympy假设symbols都是属于复数类型,这样上面的一些指数表达式就无法进行简化,而我们可以在定义symbols的时候,指定其属于什么类型,这样一些简化就可以进行,看下面的例子:

from IPython.display import display, Lateximport sympy as sysy.init_printing()x, y = symbols('x y', positive=True) #定义为正实数a, b = symbols('a b', real=True)#定义为实数z, t, c = symbols('z t c')f1 = t**c*z**cf2 = x**a*x**bf3 = x**a*y**adisplay(Latex(f"$${sy.latex(f1)}={sy.latex(sy.powsimp(f1))}$$"))display(Latex(f"$${sy.latex(f2)}={sy.latex(sy.powsimp(f2))}$$"))display(Latex(f"$${sy.latex(f3)}={sy.latex(sy.powsimp(f3))}$$"))

输出:

注意上面第一个式子,由于

是复数,所以简化没法进行;

而第二、第三个式子中由于设定符号

都符合要求,所以可以进行简化。

除了这些以外,还有:expand_power_exp(), expand_power_base(), powdenest(), expand_log(), logcombine()等函数可以进行化简,参看下面的资料:

Simplification - SymPy 1.4 documentation​

Simplification - SymPy 1.4 documentation

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。