简化¶
- sympy.simplify.simplify.simplify(
- expr,
- ratio=1.7,
- measure=<function count_ops>,
- rational=False,
- inverse=False,
- doit=True,
- **kwargs,
简化给定的表达式。
参见
sympy.assumptions.refine.refine
使用假设进行简化。
sympy.assumptions.ask.ask
使用假设查询布尔表达式。
- sympy.simplify.simplify.separatevars(
- expr,
- symbols=[],
- dict=False,
- force=False,
如果可能,在表达式中分隔变量。默认情况下,它根据表达式中的所有符号进行分隔,并收集独立于符号的常数系数。
注释
因子的顺序由 Mul 决定,因此分离的表达式不一定必须被组合在一起。
虽然因式分解在某些表达式中是分离变量所必需的,但并非所有情况下都需要,因此不应依赖返回的因子是否被分解。
示例
>>> from sympy.abc import x, y, z, alpha >>> from sympy import separatevars, sin >>> separatevars((x*y)**y) (x*y)**y >>> separatevars((x*y)**y, force=True) x**y*y**y
>>> e = 2*x**2*z*sin(y)+2*z*x**2 >>> separatevars(e) 2*x**2*z*(sin(y) + 1) >>> separatevars(e, symbols=(x, y), dict=True) {'coeff': 2*z, x: x**2, y: sin(y) + 1} >>> separatevars(e, [x, y, alpha], dict=True) {'coeff': 2*z, alpha: 1, x: x**2, y: sin(y) + 1}
如果表达式不可完全分离,或只能部分分离,separatevars 将尽其所能通过因式分解来分离它。
>>> separatevars(x + x*y - 3*x**2) -x*(3*x - y - 1)
如果表达式不可分离,则返回 expr 不变,或者(如果 dict=True)则返回 None。
>>> eq = 2*x + y*sin(x) >>> separatevars(eq) == eq True >>> separatevars(2*x + y*sin(x), symbols=(x, y), dict=True) is None True
- sympy.simplify.simplify.nthroot(expr, n, max_len=4, prec=15)[源代码][源代码]¶
计算一个和的实数 n 次根。
- 参数:
- 表达式根式的和
- n整数
- max_len : 传递给
nsimplify
的常数中最大根号数传递为常量的最大根号数
示例
>>> from sympy.simplify.simplify import nthroot >>> from sympy import sqrt >>> nthroot(90 + 34*sqrt(7), 3) sqrt(7) + 3
- sympy.simplify.simplify.kroneckersimp(expr)[源代码][源代码]¶
使用 KroneckerDelta 简化表达式。
目前唯一尝试的简化是识别乘法消去:
示例
>>> from sympy import KroneckerDelta, kroneckersimp >>> from sympy.abc import i >>> kroneckersimp(1 + KroneckerDelta(0, i) * KroneckerDelta(1, i)) 1
- sympy.simplify.simplify.hypersimp(f, k)[源代码][源代码]¶
给定组合项 f(k),简化其连续项比率,即 f(k+1)/f(k)。输入项可以由函数和整数序列组成,这些序列可以用伽马特殊函数的形式等价表示。
- sympy.simplify.simplify.nsimplify(
- expr,
- constants=(),
- tolerance=None,
- full=False,
- rational=None,
- rational_conversion='base10',
找到一个数字的简单表示,或者如果有自由符号或
rational=True
,则用它们的 Rational 等价物替换 Floats。如果没有进行更改且 rational 不是 False,那么 Floats 至少会被转换为 Rationals。示例
>>> from sympy import nsimplify, sqrt, GoldenRatio, exp, I, pi >>> nsimplify(4/(1+sqrt(5)), [GoldenRatio]) -2 + 2*GoldenRatio >>> nsimplify((1/(exp(3*pi*I/5)+1))) 1/2 - I*sqrt(sqrt(5)/10 + 1/4) >>> nsimplify(I**I, [pi]) exp(-pi/2) >>> nsimplify(pi, tolerance=0.01) 22/7
>>> nsimplify(0.333333333333333, rational=True, rational_conversion='exact') 6004799503160655/18014398509481984 >>> nsimplify(0.333333333333333, rational=True) 1/3
- sympy.simplify.simplify.logcombine(expr, force=False)[源代码][源代码]¶
使用以下规则取对数并组合它们:
log(x) + log(y) == log(x*y) 如果两者均为正
a*log(x) == log(x**a) 如果 x 是正数且 a 是实数
如果
force
是True
,那么在数量上没有现有假设的情况下,将假定上述假设成立。例如,如果a
是虚数或参数为负,force 将不会执行组合,但如果a
是一个没有假设的符号,则更改将会发生。参见
posify
用具有积极假设的符号替换所有符号
sympy.core.function.expand_log
展开对数乘积和幂的对数;与 logcombine 相反
示例
>>> from sympy import Symbol, symbols, log, logcombine, I >>> from sympy.abc import a, x, y, z >>> logcombine(a*log(x) + log(y) - log(z)) a*log(x) + log(y) - log(z) >>> logcombine(a*log(x) + log(y) - log(z), force=True) log(x**a*y/z) >>> x,y,z = symbols('x,y,z', positive=True) >>> a = Symbol('a', real=True) >>> logcombine(a*log(x) + log(y) - log(z)) log(x**a*y/z)
转换仅限于包含对数因子或项,因此结果取决于展开的初始状态:
>>> eq = (2 + 3*I)*log(x) >>> logcombine(eq, force=True) == eq True >>> logcombine(eq.expand(), force=True) log(x**2) + I*log(x**3)
- sympy.simplify.radsimp.radsimp(expr, symbolic=True, max_terms=4)[源代码][源代码]¶
通过去除平方根来合理化分母。
示例
>>> from sympy import radsimp, sqrt, Symbol, pprint >>> from sympy import factor_terms, fraction, signsimp >>> from sympy.simplify.radsimp import collect_sqrt >>> from sympy.abc import a, b, c
>>> radsimp(1/(2 + sqrt(2))) (2 - sqrt(2))/2 >>> x,y = map(Symbol, 'xy') >>> e = ((2 + 2*sqrt(2))*x + (2 + sqrt(8))*y)/(2 + sqrt(2)) >>> radsimp(e) sqrt(2)*(x + y)
除了去除最大公约数之外,没有进行简化。然而,通过收集平方根项,人们可能希望稍微润色一下结果:
>>> r2 = sqrt(2) >>> r5 = sqrt(5) >>> ans = radsimp(1/(y*r2 + x*r2 + a*r5 + b*r5)); pprint(ans) ___ ___ ___ ___ \/ 5 *a + \/ 5 *b - \/ 2 *x - \/ 2 *y ------------------------------------------ 2 2 2 2 5*a + 10*a*b + 5*b - 2*x - 4*x*y - 2*y
>>> n, d = fraction(ans) >>> pprint(factor_terms(signsimp(collect_sqrt(n))/d, radical=True)) ___ ___ \/ 5 *(a + b) - \/ 2 *(x + y) ------------------------------------------ 2 2 2 2 5*a + 10*a*b + 5*b - 2*x - 4*x*y - 2*y
如果分母中的根式无法被移除或没有分母,将返回原始表达式。
>>> radsimp(sqrt(2)*x + sqrt(2)) sqrt(2)*x + sqrt(2)
带有符号的结果并不总是对所有替换都有效:
>>> eq = 1/(a + b*sqrt(c)) >>> eq.subs(a, b*sqrt(c)) 1/(2*b*sqrt(c)) >>> radsimp(eq).subs(a, b*sqrt(c)) nan
如果
symbolic=False
,符号分母将不会被转换(但数字分母仍将被处理):>>> radsimp(eq, symbolic=False) 1/(a + b*sqrt(c))
- sympy.simplify.radsimp.rad_rationalize(num, den)[源代码][源代码]¶
通过去除分母中的平方根来合理化
num/den
;num 和 den 是平方为正有理数的项的和。示例
>>> from sympy import sqrt >>> from sympy.simplify.radsimp import rad_rationalize >>> rad_rationalize(sqrt(3), 1 + sqrt(2)/3) (-sqrt(3) + sqrt(6)/3, -7/9)
- sympy.simplify.radsimp.collect(
- expr,
- syms,
- func=None,
- evaluate=None,
- exact=False,
- distribute_order_term=True,
收集表达式的加法项。
示例
>>> from sympy import S, collect, expand, factor, Wild >>> from sympy.abc import a, b, c, x, y
此函数可以收集多项式或有理表达式中的符号系数。它将设法找到收集变量的所有整数或有理数次幂:
>>> collect(a*x**2 + b*x**2 + a*x - b*x + c, x) c + x**2*(a + b) + x*(a - b)
同样的结果可以通过字典形式实现:
>>> d = collect(a*x**2 + b*x**2 + a*x - b*x + c, x, evaluate=False) >>> d[x**2] a + b >>> d[x] a - b >>> d[S.One] c
你也可以处理多元多项式。然而,请记住这个函数是贪婪的,因此它每次只会关注一个符号,按照指定的顺序:
>>> collect(x**2 + y*x**2 + x*y + y + a*y, [x, y]) x**2*(y + 1) + x*y + y*(a + 1)
也可以使用更复杂的表达式作为模式:
>>> from sympy import sin, log >>> collect(a*sin(2*x) + b*sin(2*x), sin(2*x)) (a + b)*sin(2*x) >>> collect(a*x*log(x) + b*(x*log(x)), x*log(x)) x*(a + b)*log(x)
你可以在模式中使用通配符:
>>> w = Wild('w1') >>> collect(a*x**y - b*x**y, w**y) x**y*(a - b)
也可以使用符号幂,尽管它的行为更为复杂,因为在这种情况下,幂的底数和指数的符号部分被视为一个单一的符号:
>>> collect(a*x**c + b*x**c, x) a*x**c + b*x**c >>> collect(a*x**c + b*x**c, x**c) x**c*(a + b)
然而,如果你将理据纳入指数中,那么你将会得到众所周知的行为:
>>> collect(a*x**(2*c) + b*x**(2*c), x**c) x**(2*c)*(a + b)
还要注意,所有关于
collect()
函数的先前陈述的事实也适用于指数函数,因此你可以得到:>>> from sympy import exp >>> collect(a*exp(2*x) + b*exp(2*x), exp(x)) (a + b)*exp(2*x)
如果你只对收集某些符号的特定幂感兴趣,那么将
exact
标志设置为 True:>>> collect(a*x**7 + b*x**7, x, exact=True) a*x**7 + b*x**7 >>> collect(a*x**7 + b*x**7, x**7, exact=True) x**7*(a + b)
如果你想收集任何包含符号的对象,请将
exact
设置为 None:>>> collect(x*exp(x) + sin(x)*y + sin(x)*2 + 3*x, x, exact=None) x*exp(x) + 3*x + (y + 2)*sin(x) >>> collect(a*x*y + x*y + b*x + x, [x, y], exact=None) x*y*(a + 1) + x*(b + 1)
你也可以将此函数应用于微分方程,其中可以收集任意阶的导数。请注意,如果你根据一个函数或函数的导数进行收集,该函数的所有导数也将被收集。使用
exact=True
可以防止这种情况发生:>>> from sympy import Derivative as D, collect, Function >>> f = Function('f') (x) >>> collect(a*D(f,x) + b*D(f,x), D(f,x)) (a + b)*Derivative(f(x), x) >>> collect(a*D(D(f,x),x) + b*D(D(f,x),x), f) (a + b)*Derivative(f(x), (x, 2)) >>> collect(a*D(D(f,x),x) + b*D(D(f,x),x), D(f,x), exact=True) a*Derivative(f(x), (x, 2)) + b*Derivative(f(x), (x, 2)) >>> collect(a*D(f,x) + b*D(f,x) + a*f + b*f, f) (a + b)*f(x) + (a + b)*Derivative(f(x), x)
或者你甚至可以同时匹配导数的阶数和指数:
>>> collect(a*D(D(f,x),x)**2 + b*D(D(f,x),x)**2, D(f,x)) (a + b)*Derivative(f(x), (x, 2))**2
最后,您可以对每个收集到的系数应用一个函数。例如,您可以对多项式的符号系数进行因式分解:
>>> f = expand((x + a + 1)**3) >>> collect(f, x, factor) x**3 + 3*x**2*(a + 1) + 3*x*(a + 1)**2 + (a + 1)**3
备注
参数应以扩展形式提供,因此在调用此函数之前,您可能需要调用
expand()
。
- sympy.simplify.radsimp.rcollect(expr, *vars)[源代码][源代码]¶
递归地在表达式中收集总和。
示例
>>> from sympy.simplify import rcollect >>> from sympy.abc import x, y
>>> expr = (x**2*y + x*y + x + y)/(x + y)
>>> rcollect(expr, y) (x + y*(x**2 + x + 1))/(x + y)
- sympy.simplify.radsimp.collect_sqrt(expr, evaluate=None)[源代码][源代码]¶
返回表达式,其中包含公共平方根的项被收集在一起。如果
evaluate
为 False,将返回一个计数,指示包含平方根的项的数量,如果非零,则返回 Add 的项,否则将返回表达式本身作为一个单项。如果evaluate
为 True,将返回包含任何收集项的表达式。注意:由于 I = sqrt(-1),它也被收集。
参见
示例
>>> from sympy import sqrt >>> from sympy.simplify.radsimp import collect_sqrt >>> from sympy.abc import a, b
>>> r2, r3, r5 = [sqrt(i) for i in [2, 3, 5]] >>> collect_sqrt(a*r2 + b*r2) sqrt(2)*(a + b) >>> collect_sqrt(a*r2 + b*r2 + a*r3 + b*r3) sqrt(2)*(a + b) + sqrt(3)*(a + b) >>> collect_sqrt(a*r2 + b*r2 + a*r3 + b*r5) sqrt(3)*a + sqrt(5)*b + sqrt(2)*(a + b)
如果 evaluate 为 False,那么参数将被排序并作为列表返回,同时返回包含 sqrt 项的数量:
>>> collect_sqrt(a*r2 + b*r2 + a*r3 + b*r5, evaluate=False) ((sqrt(3)*a, sqrt(5)*b, sqrt(2)*(a + b)), 3) >>> collect_sqrt(a*sqrt(2) + b, evaluate=False) ((b, sqrt(2)*a), 1) >>> collect_sqrt(a + b, evaluate=False) ((a + b,), 0)
- sympy.simplify.radsimp.collect_const(expr, *vars, Numbers=True)[源代码][源代码]¶
在一个加法表达式中,具有相似系数项的非贪婪集合。如果给出了
vars
,则只会针对这些常数。尽管任何数字也可以被针对,但如果不需要这样做,请设置Numbers=False
,这样就不会收集浮点数或有理数。- 参数:
- 表达式SymPy 表达式
此参数定义了从中收集具有相似系数的项的表达式。非加法表达式将按原样返回。
- 变量可变长度的数字集合,可选
指定要收集的目标常量。可以有多个。
- 数字布尔
指定目标为所有
sympy.core.numbers.Number
类的实例。如果Numbers=False
,则不会收集任何浮点数或有理数。
- 返回:
- 表达式表达式
返回一个表达式,其中相似的系数项被合并。
参见
示例
>>> from sympy import sqrt >>> from sympy.abc import s, x, y, z >>> from sympy.simplify.radsimp import collect_const >>> collect_const(sqrt(3) + sqrt(3)*(1 + sqrt(2))) sqrt(3)*(sqrt(2) + 2) >>> collect_const(sqrt(3)*s + sqrt(7)*s + sqrt(3) + sqrt(7)) (sqrt(3) + sqrt(7))*(s + 1) >>> s = sqrt(2) + 2 >>> collect_const(sqrt(3)*s + sqrt(3) + sqrt(7)*s + sqrt(7)) (sqrt(2) + 3)*(sqrt(3) + sqrt(7)) >>> collect_const(sqrt(3)*s + sqrt(3) + sqrt(7)*s + sqrt(7), sqrt(3)) sqrt(7) + sqrt(3)*(sqrt(2) + 3) + sqrt(7)*(sqrt(2) + 2)
该集合对符号敏感,赋予无符号值更高的优先级:
>>> collect_const(x - y - z) x - (y + z) >>> collect_const(-y - z) -(y + z) >>> collect_const(2*x - 2*y - 2*z, 2) 2*(x - y - z) >>> collect_const(2*x - 2*y - 2*z, -2) 2*x - 2*(y + z)
- sympy.simplify.radsimp.fraction(expr, exact=False)[源代码][源代码]¶
返回一个包含表达式的分子和分母的元组。如果给定的表达式不是分数,则此函数将返回元组 (expr, 1)。
此函数不会尝试简化嵌套分数,也不会进行任何项的重写。
如果只需要分子/分母对中的一个,则分别使用 numer(expr) 或 denom(expr) 函数。
>>> from sympy import fraction, Rational, Symbol >>> from sympy.abc import x, y
>>> fraction(x/y) (x, y) >>> fraction(x) (x, 1)
>>> fraction(1/y**2) (1, y**2)
>>> fraction(x*y/2) (x*y, 2) >>> fraction(Rational(1, 2)) (1, 2)
这个函数在假设条件下也能正常工作:
>>> k = Symbol('k', negative=True) >>> fraction(x * y**k) (x, y**(-k))
如果我们对某个指数的符号一无所知且
exact
标志未设置,那么将分析指数的结构并返回一个漂亮的分数:>>> from sympy import exp, Mul >>> fraction(2*x**(-y)) (2, x**y)
>>> fraction(exp(-x)) (1, exp(x))
>>> fraction(exp(-x), exact=True) (exp(-x), 1)
exact
标志还将阻止任何未评估的 Muls 被评估:>>> u = Mul(2, x + 1, evaluate=False) >>> fraction(u) (2*x + 2, 1) >>> fraction(u, exact=True) (2*(x + 1), 1)
- sympy.simplify.ratsimp.ratsimp(expr)[源代码][源代码]¶
将表达式放在一个公分母上,消去并简化。
示例
>>> from sympy import ratsimp >>> from sympy.abc import x, y >>> ratsimp(1/x + 1/y) (x + y)/(x*y)
- sympy.simplify.ratsimp.ratsimpmodprime(
- expr,
- G,
- *gens,
- quick=True,
- polynomial=False,
- **args,
简化有理表达式
expr
模由G
生成的素理想。G
应该是理想的 Groebner 基。参考文献
[1]M. Monagan, R. Pearce, Rational Simplification Modulo a Polynomial Ideal, https://dl.acm.org/doi/pdf/10.1145/1145768.1145809 (specifically, the second algorithm)
示例
>>> from sympy.simplify.ratsimp import ratsimpmodprime >>> from sympy.abc import x, y >>> eq = (x + y**5 + y)/(x - y) >>> ratsimpmodprime(eq, [x*y**5 - x - y], x, y, order='lex') (-x**2 - x*y - x - y)/(-x**2 + x*y)
如果
polynomial
为False
,该算法计算一个有理化简,该化简最小化了分子和分母的总次数之和。如果
polynomial
为True
,此函数仅将分子和分母转换为标准形式。这会快得多,但可能结果较差。
- sympy.simplify.trigsimp.trigsimp(expr, inverse=False, **opts)[源代码][源代码]¶
通过使用已知的三角恒等式返回一个简化的表达式。
- 参数:
- 反向bool, 可选
如果
inverse=True
,将假设一个逆函数的组合,如 sin 和 asin,可以在任何顺序中被取消。例如,asin(sin(x))
将产生x
,而不检查 x 是否属于此关系为真的集合。默认值为 False。默认值:True- 方法字符串,可选
指定要使用的方法。有效选项包括:
'matching'
,默认'groebner'
'combined'
'fu'
'old'
如果
'matching'
,通过递归地针对常见模式来简化表达式。如果'groebner'
,应用一个实验性的 Groebner 基算法。在这种情况下,进一步的选项会被传递给trigsimp_groebner
,请参考其文档字符串。如果'combined'
,它首先使用小的默认参数运行 Groebner 基算法,然后运行'matching'
算法。如果'fu'
,运行 Fu 等人描述的三角变换集合(参见fu()
文档字符串)。如果'old'
,运行原始的 SymPy 三角简化函数。- 选项
传递给方法的可选关键字参数。详情请参阅每个方法的函数文档字符串。
示例
>>> from sympy import trigsimp, sin, cos, log >>> from sympy.abc import x >>> e = 2*sin(x)**2 + 2*cos(x)**2 >>> trigsimp(e) 2
简化发生在任何三角函数所在的地方。
>>> trigsimp(log(e)) log(2)
使用
method='groebner'
(或method='combined'
) 可能会导致更大的简化。旧的 trigsimp 例程可以通过方法
method='old'
访问。>>> from sympy import coth, tanh >>> t = 3*tanh(x)**7 - 2/coth(x)**7 >>> trigsimp(t, method='old') == t True >>> trigsimp(t) tanh(x)**7
- sympy.simplify.powsimp.powsimp(
- expr,
- deep=False,
- combine='all',
- force=False,
- measure=<function count_ops>,
通过合并具有相同底数和指数的幂来简化表达式。
示例
>>> from sympy import powsimp, exp, log, symbols >>> from sympy.abc import x, y, z, n >>> powsimp(x**y*x**z*y**z, combine='all') x**(y + z)*y**z >>> powsimp(x**y*x**z*y**z, combine='exp') x**(y + z)*y**z >>> powsimp(x**y*x**z*y**z, combine='base', force=True) x**y*(x*y)**z
>>> powsimp(x**z*x**y*n**z*n**y, combine='all', force=True) (n*x)**(y + z) >>> powsimp(x**z*x**y*n**z*n**y, combine='exp') n**(y + z)*x**(y + z) >>> powsimp(x**z*x**y*n**z*n**y, combine='base', force=True) (n*x)**y*(n*x)**z
>>> x, y = symbols('x y', positive=True) >>> powsimp(log(exp(x)*exp(y))) log(exp(x)*exp(y)) >>> powsimp(log(exp(x)*exp(y)), deep=True) x + y
如果 combine=’exp’,具有多个基的部首将被合并
>>> from sympy import sqrt >>> x, y = symbols('x y')
两个根式通过 Mul 自动连接:
>>> a=sqrt(x*sqrt(y)) >>> a*a**3 == a**4 True
但如果该根式的整数次幂已被自动展开,那么 Mul 不会合并结果因子:
>>> a**4 # auto expands to a Mul, no longer a Pow x**2*y >>> _*a # so Mul doesn't combine them x**2*y*sqrt(x*sqrt(y)) >>> powsimp(_) # but powsimp will (x*sqrt(y))**(5/2) >>> powsimp(x*y*a) # but won't when doing so would violate assumptions x*y*sqrt(x*sqrt(y))
- sympy.simplify.powsimp.powdenest(eq, force=False, polar=False)[源代码][源代码]¶
在假设允许的情况下收集幂上的指数。
示例
>>> from sympy.abc import a, b, x, y, z >>> from sympy import Symbol, exp, log, sqrt, symbols, powdenest
>>> powdenest((x**(2*a/3))**(3*x)) (x**(2*a/3))**(3*x) >>> powdenest(exp(3*x*log(2))) 2**(3*x)
假设可能会阻碍扩展:
>>> powdenest(sqrt(x**2)) sqrt(x**2)
>>> p = symbols('p', positive=True) >>> powdenest(sqrt(p**2)) p
没有进行其他扩展。
>>> i, j = symbols('i,j', integer=True) >>> powdenest((x**x)**(i + j)) # -X-> (x**x)**i*(x**x)**j x**(x*(i + j))
但是 exp() 将会通过将所有非对数项移出函数来去嵌套;这可能会导致 exp 折叠为具有不同基数的幂:
>>> powdenest(exp(3*y*log(x))) x**(3*y) >>> powdenest(exp(y*(log(a) + log(b)))) (a*b)**y >>> powdenest(exp(3*(log(a) + log(b)))) a**3*b**3
如果假设允许,符号也可以移到最外层的指数上:
>>> i = Symbol('i', integer=True) >>> powdenest(((x**(2*i))**(3*y))**x) ((x**(2*i))**(3*y))**x >>> powdenest(((x**(2*i))**(3*y))**x, force=True) x**(6*i*x*y)
>>> powdenest(((x**(2*a/3))**(3*y/i))**x) ((x**(2*a/3))**(3*y/i))**x >>> powdenest((x**(2*i)*y**(4*i))**z, force=True) (x*y**2)**(2*i*z)
>>> n = Symbol('n', negative=True)
>>> powdenest((x**i)**y, force=True) x**(i*y) >>> powdenest((n**i)**x, force=True) (n**i)**x
- sympy.simplify.combsimp.combsimp(expr)[源代码][源代码]¶
简化组合表达式。
示例
>>> from sympy.simplify import combsimp >>> from sympy import factorial, binomial, symbols >>> n, k = symbols('n k', integer = True)
>>> combsimp(factorial(n)/factorial(n - 3)) n*(n - 2)*(n - 1) >>> combsimp(binomial(n+1, k+1)/binomial(n, k)) (n + 1)/(k + 1)
- sympy.simplify.sqrtdenest.sqrtdenest(expr, max_iter=3)[源代码][源代码]¶
如果可能,展开表达式中包含其他平方根的平方根,否则返回未更改的表达式。这是基于[1]中的算法。
参考文献
[2]D. J. Jeffrey and A. D. Rich, ‘Symplifying Square Roots of Square Roots by Denesting’ (available at https://www.cybertester.com/data/denest.pdf)
示例
>>> from sympy.simplify.sqrtdenest import sqrtdenest >>> from sympy import sqrt >>> sqrtdenest(sqrt(5 + 2 * sqrt(6))) sqrt(2) + sqrt(3)
- sympy.simplify.cse_main.cse(
- exprs,
- symbols=None,
- optimizations=None,
- postprocess=None,
- order='canonical',
- ignore=(),
- list=True,
对表达式执行公共子表达式消除。
- 参数:
- 表达式SymPy 表达式的列表,或单个 SymPy 表达式
要简化的表达式。
- 符号无限迭代器生成唯一的符号
用于标记被提取出的公共子表达式的符号。
numbered_symbols
生成器很有用。默认是形式为“x0”、“x1”等的符号流。这必须是一个无限迭代器。- 优化(可调用对象,可调用对象)对的列表
外部优化函数的 (预处理器, 后处理器) 对。可选地,可以传递 ‘basic’ 以获取一组预定义的基本优化。这种 ‘basic’ 优化在旧实现中默认使用,但在较大的表达式上可能会非常慢。现在,默认情况下不会进行任何预处理或后处理优化。
- 后处理一个接受 cse 两个返回值的函数
从cse返回所需的输出形式,例如,如果你想要替换反转,函数可能是以下lambda:lambda r, e: return reversed(r), e
- 顺序字符串, ‘none’ 或 ‘canonical’
Mul 和 Add 参数的处理顺序。如果设置为 ‘canonical’,参数将按规范顺序排列。如果设置为 ‘none’,排序将更快,但依赖于表达式的哈希值,因此是机器依赖且可变的。对于速度是关注点的大型表达式,请使用 order=’none’ 设置。
- 忽略Symbols 的可迭代对象
包含
ignore
中任何符号的替换将被忽略。- 列表bool, (默认 True)
返回与输入类型相同的表达式列表或单个元素(当为 False 时)。
- 返回:
- 替换(符号, 表达式)对的列表
所有被替换的常见子表达式。本列表中较早的子表达式可能会出现在本列表中较晚的子表达式中。
- reduced_exprsSymPy 表达式列表
经过上述所有替换后的简化表达式。
示例
>>> from sympy import cse, SparseMatrix >>> from sympy.abc import x, y, z, w >>> cse(((w + x + y + z)*(w + y + z))/(w + x)**3) ([(x0, y + z), (x1, w + x)], [(w + x0)*(x0 + x1)/x1**3])
递归替换的表达式列表:
>>> m = SparseMatrix([x + y, x + y + z]) >>> cse([(x+y)**2, x + y + z, y + z, x + z + y, m]) ([(x0, x + y), (x1, x0 + z)], [x0**2, x1, y + z, x1, Matrix([ [x0], [x1]])])
注意:输入矩阵的类型和可变性保持不变。
>>> isinstance(_[1][-1], SparseMatrix) True
用户可以禁止包含某些符号的替换:
>>> cse([y**2*(x + 1), 3*y**2*(x + 1)], ignore=(y,)) ([(x0, x + 1)], [x0*y**2, 3*x0*y**2])
简化表达式的默认返回值是一个列表,即使只有一个表达式也是如此。\(list\) 标志保留了输出中输入的类型:
>>> cse(x) ([], [x]) >>> cse(x, list=False) ([], x)
- sympy.simplify.cse_main.opt_cse(exprs, order='canonical')[源代码][源代码]¶
在加法、乘法、幂运算和负系数乘法中寻找优化机会。
- 参数:
- 表达式SymPy 表达式列表
要优化的表达式。
- 顺序字符串, ‘none’ 或 ‘canonical’
Mul 和 Add 参数的处理顺序。对于速度是关键的大表达式,使用设置 order=’none’。
- 返回:
- opt_subs表达式替换字典
可以用于优化CSE的有用表达式替换。
示例
>>> from sympy.simplify.cse_main import opt_cse >>> from sympy.abc import x >>> opt_subs = opt_cse([x**-2]) >>> k, v = list(opt_subs.keys())[0], list(opt_subs.values())[0] >>> print((k, v.as_unevaluated_basic())) (x**(-2), 1/(x**2))
- sympy.simplify.cse_main.tree_cse(
- exprs,
- symbols,
- opt_subs=None,
- order='canonical',
- ignore=(),
在表达式树上执行原始CSE,同时考虑opt_subs。
- 参数:
- 表达式SymPy 表达式列表
要简化的表达式。
- 符号无限迭代器生成唯一的符号
用于标记被提取出来的公共子表达式的符号。
- opt_subs表达式替换字典
在执行任何CSE操作之前要替换的表达式。
- 顺序字符串, ‘none’ 或 ‘canonical’
Mul 和 Add 参数的处理顺序。对于速度是关键的大表达式,使用设置 order=’none’。
- 忽略Symbols 的可迭代对象
包含
ignore
中任何符号的替换将被忽略。
- sympy.simplify.hyperexpand.hyperexpand(
- f,
- allow_hyper=False,
- rewrite='default',
- place=None,
扩展超几何函数。如果 allow_hyper 为 True,允许部分简化(即结果不同于输入,但仍包含超几何函数)。
如果一个 G-函数在零点和无穷远处都有展开,
place
可以设置为0
或zoo
以指示首选选择。示例
>>> from sympy.simplify.hyperexpand import hyperexpand >>> from sympy.functions import hyper >>> from sympy.abc import z >>> hyperexpand(hyper([], [], z)) exp(z)
表达式中的非超几何部分和未被识别的超几何表达式保持不变:
>>> hyperexpand(1 + hyper([1, 1, 1], [], z)) hyper((1, 1, 1), (), z) + 1
- class sympy.simplify.epathtools.EPath(path)[源代码][源代码]¶
使用路径操作表达式。
EPath 语法的 EBNF 表示法:
literal ::= /[A-Za-z_][A-Za-z_0-9]*/ number ::= /-?\d+/ type ::= literal attribute ::= literal "?" all ::= "*" slice ::= "[" number? (":" number? (":" number?)?)? "]" range ::= all | slice query ::= (type | attribute) ("|" (type | attribute))* selector ::= range | query range? path ::= "/" selector ("/" selector)*
查看 epath() 函数的文档字符串。
方法
- apply(expr, func, args=None, kwargs=None)[源代码][源代码]¶
修改由路径选择的表达式的一部分。
示例
>>> from sympy.simplify.epathtools import EPath >>> from sympy import sin, cos, E >>> from sympy.abc import x, y, z, t
>>> path = EPath("/*/[0]/Symbol") >>> expr = [((x, 1), 2), ((3, y), z)]
>>> path.apply(expr, lambda expr: expr**2) [((x**2, 1), 2), ((3, y**2), z)]
>>> path = EPath("/*/*/Symbol") >>> expr = t + sin(x + 1) + cos(x + y + E)
>>> path.apply(expr, lambda expr: 2*expr) t + sin(2*x + 1) + cos(2*x + 2*y + E)
- select(expr)[源代码][源代码]¶
根据路径检索表达式的部分内容。
示例
>>> from sympy.simplify.epathtools import EPath >>> from sympy import sin, cos, E >>> from sympy.abc import x, y, z, t
>>> path = EPath("/*/[0]/Symbol") >>> expr = [((x, 1), 2), ((3, y), z)]
>>> path.select(expr) [x, y]
>>> path = EPath("/*/*/Symbol") >>> expr = t + sin(x + 1) + cos(x + y + E)
>>> path.select(expr) [x, x, y]
- sympy.simplify.epathtools.epath(
- path,
- expr=None,
- func=None,
- args=None,
- kwargs=None,
通过路径选择表达式的一部分进行操作。
- 参数:
- 路径str | EPath
一个字符串路径或一个编译的 EPath。
- 表达式基本 | 可迭代
一个表达式或表达式的容器。
- 函数可调用对象(可选)
一个将被应用于匹配部分的调用函数。
- 参数tuple (可选)
func
的额外位置参数。- kwargsdict (可选)
func
的额外关键字参数。
示例
>>> from sympy.simplify.epathtools import epath >>> from sympy import sin, cos, E >>> from sympy.abc import x, y, z, t
>>> path = "/*/[0]/Symbol" >>> expr = [((x, 1), 2), ((3, y), z)]
>>> epath(path, expr) [x, y] >>> epath(path, expr, lambda expr: expr**2) [((x**2, 1), 2), ((3, y**2), z)]
>>> path = "/*/*/Symbol" >>> expr = t + sin(x + 1) + cos(x + y + E)
>>> epath(path, expr) [x, x, y] >>> epath(path, expr, lambda expr: 2*expr) t + sin(2*x + 1) + cos(2*x + 2*y + E)