SymPy是一个基于Python的符号计算包。可以处理方程和方程组的求解、积分和微分、计算极限、级数展开和级数求和、简化表达式、寻找微分方程和微分方程组的解。
表达式的基本构建块是符号。该符号具有打印表达式时使用的名称。Symbol
需要创建类对象并将其分配给 python 变量,以便它们可以使用。基本上,符号的名称和我们分配这个符号的变量的名称是两个独立的东西,可以写abc=Symbol('xyz')。
但是这样的话,进入程序的时候会用到abc
,打印结果的时候SymPy
会用到xyz
,这样会造成不必要的混乱。因此,符号的名称最好与分配给它的 python 变量的名称相匹配。
首先导包:
from sympy import *
x=Symbol('x')
a = x**2 - 1
print(a)
# x**2 - 1
可以同时定义多个符号。字符串被空格分割成名称。
y,z=symbols('y z')
b = a.subs(x,y+1)
print(b)
# (y + 1)**2 - 1
多项式和有理函数
a=(x+y-z)**6
print(a)
# (x + y - z)**6
a=expand(a)
print(a)
# x**6 + 6*x**5*y - 6*x**5*z + 15*x**4*y**2 - 30*x**4*y*z + 15*x**4*z**2 + 20*x**3*y**3 - 60*x**3*y**2*z + 60*x**3*y*z**2 - 20*x**3*z**3 + 15*x**2*y**4 - 60*x**2*y**3*z + 90*x**2*y**2*z**2 - 60*x**2*y*z**3 + 15*x**2*z**4 + 6*x*y**5 - 30*x*y**4*z + 60*x*y**3*z**2 - 60*x*y**2*z**3 + 30*x*y*z**4 - 6*x*z**5 + y**6 - 6*y**5*z + 15*y**4*z**2 - 20*y**3*z**3 + 15*y**2*z**4 - 6*y*z**5 + z**6
print(degree(a,x))
print(collect(a,x))
print(factor(a))
# 6
# x**6 + x**5*(6*y - 6*z) + x**4*(15*y**2 - 30*y*z + 15*z**2) + x**3*(20*y**3 - 60*y**2*z + 60*y*z**2 - 20*z**3) + x**2*(15*y**4 - 60*y**3*z + 90*y**2*z**2 - 60*y*z**3 + 15*z**4) + x*(6*y**5 - 30*y**4*z + 60*y**3*z**2 - 60*y**2*z**3 + 30*y*z**4 - 6*z**5) + y**6 - #6*y**5*z + 15*y**4*z**2 - 20*y**3*z**3 + 15*y**2*z**4 - 6*y*z**5 + z**6
# (x + y - z)**6
SymPy
不会自动消除多项式的最大公约数的比率。需要使用函数cancel
。
a=(x**3-y**3)/(x**2-y**2)
print(a)
b=cancel(a)
print(b)
# (x**3 - y**3)/(x**2 - y**2)
# (x**2 + x*y + y**2)/(x + y)
SymPy
不会自动将有理表达式的和变成公分母。需要使用函数together
。
a=y/(x-y)+x/(x+y)
# 合并
b = together(a)
print(b)
# 简化
c = simplify(b)
print(c)
# 分解成关于x的基本分数
d = apart(c,x)
print(d)
# 代入具体数值
e = d.subs({x:1,y:2})
print(e)
# 变成小数
f = e.n()
print(f)
# (x*(x - y) + y*(x + y))/((x - y)*(x + y))
# (x**2 + y**2)/(x**2 - y**2)
# -y/(x + y) + y/(x - y) + 1
# -5/3
# -1.66666666666667
解方程
a,b,c,d,e,f=symbols('a b c d e f')
写一个有两个参数的Eq函数方程。求解函数返回一个解决方案的列表。
solve(Eq(a*x,b),x)
# [b/a]
可以将一个简单的表达式传递给求解函数。该方程的含义是表达式为0。
solve(a*x+b,x)
# [-b/a]
有2个解的二次方程。
solve(a*x**2+b*x+c,x)
# [(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)]
线性方程组。
solve([a*x+b*y-e,c*x+d*y-f],[x,y])
# {y: (a*f - c*e)/(a*d - b*c), x: (-b*f + d*e)/(a*d - b*c)}
函数roots返回多项式的根和它们的乘数。
roots(x**3-3*x+2,x)
# {1: 2, -2: 1}
solution_poly_system函数解决一个多项式方程组。
p1=x**2+y**2-1
p2=4*x*y-1
solve_poly_system([p1,p2],x,y)
# [(4*(-1 - sqrt(1/2 - sqrt(3)/4))*sqrt(1/2 - sqrt(3)/4)*(1 - sqrt(1/2 - sqrt(3)/4)), -sqrt(1/2 - sqrt(3)/4)), (-4*(-1 + sqrt(1/2 - sqrt(3)/4))*sqrt(1/2 - sqrt(3)/4)*(sqrt(1/2 - sqrt(3)/4) + 1), sqrt(1/2 - sqrt(3)/4)), (4*(-1 - sqrt(sqrt(3)/4 + 1/2))*(1 - sqrt(sqrt(3)/4 + 1/2))*sqrt(sqrt(3)/4 + 1/2), -sqrt(sqrt(3)/4 + 1/2)), (-4*(-1 + sqrt(sqrt(3)/4 + 1/2))*sqrt(sqrt(3)/4 + 1/2)*(sqrt(sqrt(3)/4 + 1/2) + 1), sqrt(sqrt(3)/4 + 1/2))]
简单求解方程的例子
求解一元一次方程: x - 1 = 0
x = Symbol('x')
f = x - 1
result = solve(f, x)
print(result )
# [1]
求解二元一次方程组: x - y = 0 x + y = 2
x = Symbol('x')
y = Symbol('y')
f1 = x - y
f2 = x + y - 2
result = solve([f1,f2], [x,y])
print(result)
# {x: 1, y: 1}
求解一元二次方程:x ** 2 - 4 = 0
x = Symbol('x')
f = x ** 2 - 4
result = solve(f, x)
print(result)
# [-2, 2]
求解二元二次方程组:x ** 2 - y ** 2 = 0 x - y =4
x = Symbol('x')
y = Symbol('y')
f1 = x ** 2 - y ** 2
f2 = x - y - 4
result = solve([f1,f2], [x,y])
print(result)
# [(2, -2)]
还可以求解三元二次方程n元n次方程组等。