只有了解了数学表达式,才能够随心所欲地对他进行处理
1. 符号
python变量名和Symbol地name属性之间没有必然联系, 变量名和符号名可以不一样
var():
快速创建符号以及与之同名的变量(交互式环境)
symbols():
创建多个Symbol对象,显式赋值给py变量
1.1 创建符号
from sympy import *
var("x0,x1,y0,y1")
x0
print(type(x0))
print(x0.name)
print(type(x0.name))
<class 'sympy.core.symbol.Symbol'>
x0
<class 'str'>
x2,y2 = symbols("x2,y2")
print(x2,y2)
x2 y2
# 变量名与symbol名不同
t = x0
a,b = symbols("alpha, beta")
sin(a)+cos(b)+t
1.2 符号的假设条件
通常m,n 表示整数, z表示负数。
使用var(), symbols(), symbol()创建符号Symbol对象时,通过关键字参数 指定创建符号的假设条件,这些假设条件会影响到符号参与的计算
m,n = symbols("m, n", integer=True)
x = Symbol("x", positive=True)
is_属性:
- 下划线后面全部是小写: 判断符号的假设条件
- 下划线后面是大写: 判断变量类型
- assumptions0: 属性,快速查看所有的假设条件(commutative==True表示满足交换律)
[attr for attr in dir(x) if attr.startswith("is_") and attr.lower()==attr]
['is_algebraic',
'is_algebraic_expr',
'is_antihermitian',
'is_commutative',
'is_comparable',
'is_complex',
'is_composite',
'is_constant',
'is_even',
'is_finite',
'is_hermitian',
'is_hypergeometric',
'is_imaginary',
'is_infinite',
'is_integer',
'is_irrational',
'is_negative',
'is_noninteger',
'is_nonnegative',
'is_nonpositive',
'is_nonzero',
'is_number',
'is_odd',
'is_polar',
'is_polynomial',
'is_positive',
'is_prime',
'is_rational',
'is_rational_function',
'is_real',
'is_scalar',
'is_symbol',
'is_transcendental',
'is_zero']
print(x.is_Symbol)
print(x.is_positive)
print(x.is_negative)
True
True
False
x.assumptions0
{'positive': True,
'commutative': True,
'hermitian': True,
'zero': False,
'complex': True,
'nonpositive': False,
'real': True,
'negative': False,
'nonnegative': True,
'imaginary': False,
'nonzero': True}
对象的继承关系:
Sympy中的所有对象 都是从Basic类继承, is_ 属性和assuptions0属性都是在basic中定义的
Symbol.mro()
[sympy.core.symbol.Symbol,
sympy.core.expr.AtomicExpr,
sympy.core.basic.Atom,
sympy.core.expr.Expr,
sympy.logic.boolalg.Boolean,
sympy.core.basic.Basic,
sympy.core.evalf.EvalfMixin,
object]
2. 数值
S对象: 自动将python数值转化为Sympy数值;
Sympy数值参与运算时,结果也为Sympy数值
Float对象: 表示Sympy中的浮点数,使用二进制表示,无法精确表示十进制中的精确小数
N(): 查看浮点数的实际数值
浮点数的精度有限,使用浮点数创建Float对象,即使指定精度参数也不能缩小他与理想值之间的误差,
使用字符串表示数值。
1/2 +1/3
0.8333333333333333
S(1)/2 + 1/S(3)
# 有理数
help(S)
type( (S(1)/S(2) ) )
sympy.core.numbers.Half
help( Float(1.3) )
使用N查看实际数值
type(N)
help( N )
N(.1, 60)
# 查看绝对精度
N(S(.1), 60)
N(1000.1, 60)
使用str创建Float对象
N(Float(.1, 60), 60)
N(Float(".1",60), 60)
N(Float(".1",60), 65)
N(Float(".1",65), 65)
将数值算式按照精度转换为float对象
N(sqrt(2), 50)
N(pi, 10)
3. 运算符和函数
Add()
Mul()
Pow()
sin()
对象 和Symbol()对象相同,都是从Basic类继承
sympy的表达式实际上是一个由Basic类的各种对象多层嵌套结构的树状结构。 dotprint()可以将表达式转换成Graphviz的DOT语言描述的图形,使用本书提供的%dot命令可以将其显示在Notebook中。
var("x,y,z")
Add(x, y, z)
Add(Mul(x,y,z), Pow(x,y), sin(z) )
t = Add(x, y, z)
print(t.func) # func:属性得到对象的类
print(t.args) # args:属性得到其参数
print(t.args[0].func)
print(t.args[0].args)
<class 'sympy.core.add.Add'>
(x, y, z)
<class 'sympy.core.symbol.Symbol'>
()
t = x/y
print(t.func) # func:属性得到对象的类
print(t.args) # args:属性得到其参数
print(t.args[0].func)
print(t.args[0].args)
<class 'sympy.core.mul.Mul'>
(x, 1/y)
<class 'sympy.core.symbol.Symbol'>
()
from sympy.printing.dot import dotprint
graph = dotprint( x*y*sqrt(x**2-y**2)/(x+y) )
graph
%dot -f svg graph
UsageError: Line magic function `%dot` not found.
自定义函数
Function(): 类
f=Function(): f为继承自Function()的子类
t = f(x,y) : 创建f()的实例
f=Function("f")
issubclass(f,Function)
True
t = f(x,y)
print(type(t))
print(t.func)
print(t.args)
f
f
(x, y)
t+t**2
4. 通配符
x,y = var("x,y")
a = Wild("a")
b = Wild("b")
match()
%sympy_latex (3*x*(x+y)**2).match(a*b**2)
UsageError: Line magic function `%sympy_latex` not found.
(3*x*(x+y)**2).match(a*b**2)
{b_: x + y, a_: 3*x}
find()
expr = expand( (x+y)**3 )
expr.find(a*b**2)
{2,
3,
3*x**2*y,
3*x*y**2,
x,
x**2,
x**3,
x**3 + 3*x**2*y + 3*x*y**2 + y**3,
y,
y**2,
y**3}
[ep.match(a*b**2) for ep in expr.find(a*b**2)]
[{b_: x**(3/2), a_: 1},
{b_: sqrt(y), a_: 1},
{b_: sqrt(3), a_: 1},
{b_: y, a_: 1},
{b_: sqrt(x), a_: 1},
{b_: sqrt(2), a_: 1},
{b_: x, a_: 3*y},
{b_: x, a_: 1},
{b_: y, a_: 3*x},
{b_: y**(3/2), a_: 1},
{b_: sqrt(x**3 + 3*x**2*y + 3*x*y**2 + y**3), a_: 1}]
exclude参数:指定不能匹配的参数列表
a = Wild("a", exclude=[1])
b = Wild("b", exclude=[1,Pow])
[ep.match(a*b**2) for ep in expr.find(a*b**2)]
[{b_: x, a_: x}, {b_: y, a_: y}, {b_: x, a_: 3*y}, {b_: y, a_: 3*x}]
replace(): 对表达式中的子表达式进行替换
expr
expr.replace(a*b**2, (a+b)**2)
WildFunction: 定义与任意函数匹配的通配符
expr = sqrt(x) / sin(y**2) + abs(exp(x)*x)
expr
[ep.match(f) for ep in expr.find(f)]
[]
expr.find(f)
set()