sympy库 2019/2/13
===========================================================
1.前言
1.1.参考文档
https://docs.sympy.org/latest/modules/solvers/inequalities.html
1.2.特点
可作为高级计算器进行交互式使用,完全用Python编写,速度似乎与Maxima相当
Mathematica和Maple速度更快;C ++版本SymEngine是SymPy的一个子集(开发中)
1.2.安装
pip install sympy# 安装sympy库
===========================================================
2.准备知识
2.1.数据类型
# SymPy用类表示整数Integer,有理数Rational和浮点数Float,而不是默认的Python int和float 类型
x = Symbol("x", integer=True);x.is_integer #True 对应Python int
x = Symbol("x", real=True);x.is_real #True 对应Python float
x = Symbol("x", complex=True);x.is_complex #True 对应Python complex
x = Integer(2);x.is_Integer #True 对应SymPy int
x=Float(10);x.is_Float #True对应SymPy float
x=Rational(1,2);x.is_Rational #True对应SymPy 有理数
2.2创建符号:
x, y, z = symbols('x y z') # 等效symbols('x,y,z')或symbols('x:z')
x0,x1,x2=symbols('x0:3',Integer=True) # 创建x0,x1,x2三个整数 [complex=True,real=True]
x = sympy.Symbol('x', real=True) # 仅指定单个符号,数据类型为实数
x0,x1,x2=symbols('x0:2') # 等效symbols('x:3')创建x0, x1, x2
x, y, z = symbols('x y z', cls=Dummy) # 推广符号到类Dummy(任何带str参数的类)
f, g, h = symbols('f,g,h', cls=Function) # 定义函数的符号f、g、h
# 临时符号
Symbol("x") == Symbol("x") # True
Dummy("x") == Dummy("x") # False
# 常用的sympy内置符号
sympy.I ** 2 # -1 #虚数单位i
ln(E) # 1 #E 自然对数的底e
1 + sympy.oo # oo #无穷大oo
sympy.sin(sympy.pi/2) # 1 #圆周率pi
===========================================================
2.3.符号表达式
6.2 # 只含数字表达式默认Python表达式6.2000000000000002
S(6.2) # SymPy表达式 6.20000000000000
x**(1/2) # x**0.5
x**(S(1)/2) # sqrt(x)
x**Rational(1, 2) # sqrt(x)
===========================================================
2.3.1符号表达式数据类型
1)有理数
x = Symbol('x') #7*x=22
a = solve(7*x - 22, x) # [22/7] 返回list
a[0],type(a[0]) # 22/7 sympy.core.numbers.Rational
S("22/7") # 22/7
# 执行数字/表达式或表达式/数字,则该数字将自动转换为SymPy数字
2/x # 分数表达式
2)用Floats和Rationals评估表达式
(1)创建
# 字符串和整数被解释为精确
Float(10) #10.000000000000#SymPy默认精度为15位数
Float(10.0) #10.000000000000#SymPy默认精度为15位数
Float('10.0') #10.000000000000#SymPy默认精度为15位数
Float(Rational(10,1)) #10.000000000000
(2)指定精度
Float(12.34, 4) # 12.34
Float(1234, '') ,Float('12.34', '') # 1234 12.34#空str可用于精度仅用于整数和字符串
1/7,Float(Rational(1,7)),Float(Rational(1,7),3)#0.14285714285714285 0.142857142857143 0.143
Float(Rational(1,7)).n(20) # 0.14285714285714284921
Float('0.1', 10) + Float('0.1', 3) #0.2000061035 只有4位精度
Float('0.1', 10) + Float('0.1', 10)#0.2000000000
(3)提高运行精度
v = 12345678901234567890
expr = v*cos(x)**2 + v*sin(x)**2 - v*1 #sin(x)^2+cos(x)^2=1
abs(expr.subs(x, .1).n(2)) > 1000 #True 结果本应为0但由于精度问题造成误差
# 默认cos 和 sin 为15位精度并乘以大数 ,当减去20位大数时,结果不为零。
获得更精确的表达式数值:
a)通过要评估的调用传递所需的替换
expr.n(2, {x: 0.1}) #-0.e-91
b)用Rational # Rational可计算任意精度,Float 默认15位数
expr.subs(x, S('1/10')).n(2) #0.e-91
c)尝试简化表达式
expr.simplify() #0 SymPy将识别trig标识并将其简化为零
===========================================================
2.3.2表达式的不变性
# SymPy中的表达式是不可变的,并且不能通过就地操作进行修改。
# 这意味着函数将始终返回一个对象,并且不会修改原始表达式
def main():
var('x y a b')
expr = 3*x + 4*y
print('original =', expr) #original = 3*x + 4*y
expr_modified = expr.subs({x: a, y: b})#subs()不修改原始表达式expr而是返回表达式修改副本
print('modified =', expr_modified) #modified = 3*a + 4*b
if __name__ == "__main__":
main()
===========================================================
2.4数学运算符
SymPy使用与Python相同的默认运算符。
其中大多数 */+-都是标准的 log()幂用**exp();^异或计算 Ture ^False#True
===========================================================
2.5返回值类型
solve(x**2 + 2*x - 1, x) # 返回列表 [-1 + sqrt(2), -sqrt(2) - 1]
roots((x - 5)**2*(x + 3), x) # 返回dicts {-3: 1, 5: 2}
integrate(x**2, (x, 0, 1)) # 1/3 #integ会将序列(列表或元祖)作为第二个参数
===========================================================
2.6关键字参数
x = Symbol('x');sqrt(x**2) #不会自动简化为x,默认x是复杂 sqrt(x**2)
x = Symbol('x', positive=True);sqrt(x**2) #x
x,y,m,n=symbols('x y m n')
powsimp(x**n*x**m*y**n*y**m, combine='all') #默认combine='all'格式:结合或指数
powsimp(x**n*x**m*y**n*y**m, combine='exp') #格式:指数
powsimp(x**n*x**m*y**n*y**m, combine='base') #格式:结合
'''
m + n m + n m + n m n
(x*y) x * y (x*y) * (x*y)
'''
===========================================================
2.7获取表达式符号
from sympy.abc import x, y, z
e = x + y*sin(z**2)
e.atoms() # set([2, x, y, z])
e.atoms(Symbol) # set([x, y, z])
===========================================================
2.8不改变输入内容
x+2/4 #x + 0.5 0.5作为Python表达式
x+Rational(2,4) #x+1/2 全部作为Symbol表达式
from sympy import Mul, Pow, Rational#设置evaluate=False
Mul(2, Rational(1, 4), evaluate=False) # 2 / 4
Pow(x * y, 2, evaluate=False) # (x * y) ** 2
===========================================================
备注1:创建符号:
# 推荐方法7.编写更多永久代码时应避免1-6使用
# 1.x = Symbol('x')。
# 2.x, y, z = map(Symbol, 'xyz')# 不能放入空间,不能多字符
# 3.var('x y z') # 用 inspect.currentframe注入符号不能保证始终有效。
# 在某些嵌套作用域中或在CPython中表现不如预期
# 4.from sympy.abc import x, y, z
# 5.x = S('x') # or sympify('x')
# 6.isympy -a # 仅用交互式
建议您不要使用I,E,S,N,C,O,Q为变量或符号名称:
# 用助记符OSINEQ来记住SymPy中默认定义的符号或用小写字母
# I虚数单位,E自然对数的基数(e),S, N() 相当于evalf(),C,O大O阶符号(如)O(nlogn)),
===========================================================
备注2:帮助help()
help(powsimp) ;powsimp?
source()打印函数的源代码也可以function??:
===========================================================