简化#
- sympy.simplify.simplify.simplify(expr, ratio=1.7, measure=<function count_ops>, rational=False, inverse=False, doit=True, **kwargs)[源代码]#
简化给定表达式。
解释
简化不是一个定义良好的术语,这个函数尝试的确切策略可能会在SymPy的未来版本中改变。如果你的算法依赖于“简化”(不管是什么),试着确定你到底需要什么——它是powsimp()吗?,radsimp()?,一起()?,logcombine()?还是别的什么?并且直接使用这个特殊的函数,因为这些函数是定义良好的,因此你的算法将是健壮的。
Nonetheless, especially for interactive use, or when you do not know anything about the structure of the expression, simplify() tries to apply intelligent heuristics to make the input expression "simpler". For example:
>>> from sympy import simplify, cos, sin >>> from sympy.abc import x, y >>> a = (x + x**2)/(x*sin(y)**2 + x*cos(y)**2) >>> a (x**2 + x)/(x*sin(y)**2 + x*cos(y)**2) >>> simplify(a) x + 1
请注意,我们可以通过使用特定的简化函数获得相同的结果:
>>> from sympy import trigsimp, cancel >>> trigsimp(a) (x**2 + x)/x >>> cancel(_) x + 1
在某些情况下,应用
simplify()
可能会导致更复杂的表达式。违约ratio=1.7
防止出现更极端的情况:如果(结果长度)/(输入长度)>比率,则输入未经修改返回。这个measure
参数允许您指定用于确定表达式有多复杂的函数。函数应将单个参数作为表达式,并返回一个数字,以便if表达式a
比表达更复杂b
然后measure(a) > measure(b)
. 默认的度量函数是count_ops()
,返回表达式中的操作总数。For example, if
ratio=1
,simplify
output cannot be longer than input.>>> from sympy import sqrt, simplify, count_ops, oo >>> root = 1/(sqrt(2)+3)
自从
simplify(root)
将导致一个稍长的表达式,而不是返回未更改的根:>>> simplify(root, ratio=1) == root True
如果
ratio=oo
,仍将应用simplify::>>> count_ops(simplify(root, ratio=oo)) > count_ops(root) True
注意,最短的表达式不一定是最简单的,所以设置
ratio
1可能不是个好主意。试探地说,默认值ratio=1.7
似乎是个合理的选择。You can easily define your own measure function based on what you feel should represent the "size" or "complexity" of the input expression. Note that some choices, such as
lambda expr: len(str(expr))
may appear to be good metrics, but have other problems (in this case, the measure function may slow down simplify too much for very large expressions). If you do not know what a good metric would be, the default,count_ops
, is a good one.例如:
>>> from sympy import symbols, log >>> a, b = symbols('a b', positive=True) >>> g = log(a) + log(b) + log(a)*log(1/b) >>> h = simplify(g) >>> h log(a*b**(1 - log(a))) >>> count_ops(g) 8 >>> count_ops(h) 5
所以你可以看到
h
比g
使用count_ops度量。但是,我们可能不喜欢怎样simplify
(在这种情况下,使用logcombine
)已经创建了b**(log(1/a) + 1)
期限。一个简单的方法可以减少这种情况,那就是在count_ops
. 我们可以使用visual=True
选项:>>> print(count_ops(g, visual=True)) 2*ADD + DIV + 4*LOG + MUL >>> print(count_ops(h, visual=True)) 2*LOG + MUL + POW + SUB
>>> from sympy import Symbol, S >>> def my_measure(expr): ... POW = Symbol('POW') ... # Discourage powers by giving POW a weight of 10 ... count = count_ops(expr, visual=True).subs(POW, 10) ... # Every other operation gets a weight of 1 (the default) ... count = count.replace(Symbol, type(S.One)) ... return count >>> my_measure(g) 8 >>> my_measure(h) 14 >>> 15./8 > 1.7 # 1.7 is the default ratio True >>> simplify(g, measure=my_measure) -log(a)*log(b) + log(a) + log(b)
请注意,因为
simplify()
内部尝试了许多不同的简化策略,然后使用度量函数对它们进行了比较,得到了与输入表达式完全不同的结果。If
rational=True
, Floats will be recast as Rationals before simplification. Ifrational=None
, Floats will be recast as Rationals but the result will be recast as Floats. If rational=False(default) then nothing will be done to the Floats.If
inverse=True
, it will be assumed that a composition of inverse functions, such as sin and asin, can be cancelled in any order. For example,asin(sin(x))
will yieldx
without checking whether x belongs to the set where this relation is true. The default is False.注意
simplify()
自动呼叫doit()
在最后的表达上。你可以通过路过来避免这种行为doit=False
作为一个论点。Also, it should be noted that simplifying a boolean expression is not well defined. If the expression prefers automatic evaluation (such as
Eq()
orOr()
), simplification will returnTrue
orFalse
if truth value can be determined. If the expression is not evaluated by default (such asPredicate()
), simplification will not reduce it and you should userefine()
orask()
function. This inconsistency will be resolved in future version.参见
sympy.assumptions.refine.refine
Simplification using assumptions.
sympy.assumptions.ask.ask
Query for boolean expressions using assumptions.
- sympy.simplify.simplify.separatevars(expr, symbols=[], dict=False, force=False)[源代码]#
如果可能,分隔表达式中的变量。默认情况下,它与表达式中的所有符号分离,并收集独立于符号的常数系数。
解释
If
dict=True
then the separated terms will be returned in a dictionary keyed to their corresponding symbols. By default, all symbols in the expression will appear as keys; if symbols are provided, then all those symbols will be used as keys, and any terms in the expression containing other symbols or non-symbols will be returned keyed to the string 'coeff'. (Passing None for symbols will return the expression in a dictionary keyed to 'coeff'.)If
force=True
, then bases of powers will be separated regardless of assumptions on the symbols involved.笔记
因子的顺序由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),则不返回任何表达式。
>>> 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)[源代码]#
Compute a real nth-root of a sum of surds.
- 参数:
expr :附加值之和
n :整数
max_len :作为常量传递给
nsimplify
算法
弗斯特
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.besselsimp(expr)[源代码]#
简化贝塞尔函数。
解释
This routine tries to simplify bessel-type functions. Currently it only works on the Bessel J and I functions, however. It works by looking at all such functions in turn, and eliminating factors of "I" and "-1" (actually their polar equivalents) in front of the argument. Then, functions of half-integer order are rewritten using trigonometric functions and functions of integer order (> 1) are rewritten using functions of low order. Finally, if the expression was changed, compute factorization of the result with factor().
>>> from sympy import besselj, besseli, besselsimp, polar_lift, I, S >>> from sympy.abc import z, nu >>> besselsimp(besselj(nu, z*polar_lift(-1))) exp(I*pi*nu)*besselj(nu, z) >>> besselsimp(besseli(nu, z*polar_lift(-I))) exp(-I*pi*nu/2)*besselj(nu, z) >>> besselsimp(besseli(S(-1)/2, z)) sqrt(2)*cosh(z)/(sqrt(pi)*sqrt(z)) >>> besselsimp(z*besseli(0, z) + z*(besseli(2, z))/2 + besseli(1, z)) 3*z*besseli(0, z)/2
- sympy.simplify.simplify.hypersimp(f, k)[源代码]#
给定组合项f(k)简化其连续项比率,即f(k+1)/f(k)。输入项可以由函数和整数序列组成,这些整数序列用gamma特殊函数表示。
解释
该算法执行三个基本步骤:
如果可能,用gamma重写所有函数。
用gamma的乘积重写gamma的所有出现,并用整数绝对常数指数递增阶乘。
对嵌套的分数、幂进行简化,如果得到的表达式是多项式的商,则降低它们的总阶数。
如果f(k)是超几何的,那么我们得到了极小次多项式的商。否则将不返回任何内容。
有关已实现算法的更多信息,请参阅:
W、 Koepf,m倍超几何求和算法,符号计算杂志(1995)20,399-417
- sympy.simplify.simplify.hypersimilar(f, g, k)[源代码]#
Returns True if
f
andg
are hyper-similar.解释
Similarity in hypergeometric sense means that a quotient of f(k) and g(k) is a rational function in
k
. This procedure is useful in solving recurrence relations.有关详细信息,请参见hypersimp()。
- sympy.simplify.simplify.nsimplify(expr, constants=(), tolerance=None, full=False, rational=None, rational_conversion='base10')[源代码]#
Find a simple representation for a number or, if there are free symbols or if
rational=True
, then replace Floats with their Rational equivalents. If no change is made and rational is not False then Floats will at least be converted to Rationals.解释
对于数值表达式,寻求一个简单的公式,在数值上与给定的数值表达式相匹配(并且输入应该能够计算到至少30位数字的精度)。
可选地,可以给出公式中包含的(合理独立的)常数列表。
可以设置较低的公差来查找不太精确的匹配。如果未给出公差,则最小精度值将设置公差(例如,浮点值默认为15位精度,公差=10**-15)。
With
full=True
, a more extensive search is performed (this is useful to find simpler numbers when the tolerance is set low).当转换为有理数时,如果rational_conversion='base10'(默认值),那么使用它们的base10(字符串)表示将浮点转换为有理数。当rational_conversion='exact'时,它使用精确的base-2表示。
实例
>>> 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.posify(eq)[源代码]#
Return
eq
(with generic symbols made positive) and a dictionary containing the mapping between the old and new symbols.解释
任何具有正数=无的符号都将替换为具有相同名称的正伪符号。这个替换将允许对表达式进行更多的符号处理,特别是那些涉及幂和对数的表达式。
A dictionary that can be sent to subs to restore
eq
to its original symbols is also returned.>>> from sympy import posify, Symbol, log, solve >>> from sympy.abc import x >>> posify(x + Symbol('p', positive=True) + Symbol('n', negative=True)) (_x + n + p, {_x: x})
>>> eq = 1/x >>> log(eq).expand() log(1/x) >>> log(posify(eq)[0]).expand() -log(_x) >>> p, rep = posify(eq) >>> log(p).expand().subs(rep) -log(x)
可以对表达式的iterable应用相同的转换:
>>> eq = x**2 - 4 >>> solve(eq, x) [-2, 2] >>> eq_x, reps = posify([eq, x]); eq_x [_x**2 - 4, _x] >>> solve(*eq_x) [2]
- sympy.simplify.simplify.logcombine(expr, force=False)[源代码]#
取对数并使用以下规则组合:
对数(x)+对数(y)=对数(x*y),如果两者都是正的
一 log(x) == log(x *a) 如果x是正的,a是真的
If
force
isTrue
then the assumptions above will be assumed to hold if there is no assumption already in place on a quantity. For example, ifa
is imaginary or the argument negative, force will not perform a combination but ifa
is a symbol with no assumptions the change will take place.实例
>>> 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)
参见
posify
将所有符号替换为具有肯定假设的符号
sympy.core.function.expand_log
展开乘积和幂的对数;与logcombine相反
- sympy.simplify.radsimp.radsimp(expr, symbolic=True, max_terms=4)[源代码]#
通过去掉平方根使分母合理化。
解释
The expression returned from radsimp must be used with caution since if the denominator contains symbols, it will be possible to make substitutions that violate the assumptions of the simplification process: that for a denominator matching a + b*sqrt(c), a != +/-b*sqrt(c). (If there are no symbols, this assumptions is made valid by collecting terms of sqrt(c) so the match variable
a
does not containsqrt(c)
.) If you do not want the simplification to occur for symbolic denominators, setsymbolic
to False.如果有超过
max_terms
则表达式返回不变。实例
>>> 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)
除了去除gcd外,没有任何简化。然而,人们可能需要通过收集平方根项来对结果稍加润色:
>>> 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
If
symbolic=False
, symbolic denominators will not be transformed (but numeric denominators will still be processed):>>> radsimp(eq, symbolic=False) 1/(a + b*sqrt(c))
- sympy.simplify.radsimp.rad_rationalize(num, den)[源代码]#
Rationalize
num/den
by removing square roots in the denominator; num and den are sum of terms whose squares are positive rationals.实例
>>> 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)[源代码]#
收集表达式的附加项。
解释
这个函数收集一个表达式的加法项,它与一个表达式列表有关,直到有理指数的幂次。这里所说的符号是指任意表达式,可以包含幂、乘积、和等。换句话说,符号是一种模式,将在表达式的术语中搜索。
The input expression is not expanded by
collect()
, so user is expected to provide an expression in an appropriate form. This makescollect()
more predictable as there is no magic happening behind the scenes. However, it is important to note, that powers of products are converted to products of powers using theexpand_power_base()
function.有两种可能的输出类型。首先,如果
evaluate
如果设置了标志,则此函数将返回一个包含集合项的表达式,否则它将返回一个字典,其中表达式的有理幂作为键,收集的系数作为值。实例
>>> 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)
If you are interested only in collecting specific powers of some symbols then set
exact
flag to 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)
If you want to collect on any object containing symbols, set
exact
to 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)[源代码]#
返回expr,将具有公共平方根的项集合在一起。如果
evaluate
为False表示将返回包含字词的sqrt个数的计数,如果不为零,则返回Add的字词,否则表达式本身将作为单个字词返回。如果evaluate
如果为真,将返回包含任何收集的术语的表达式。注意:因为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
不会收集浮动或有理数。- 参数:
expr : SymPy expression
此参数定义表达式,从中收集具有相似系数的项的表达式。非Add表达式按原样返回。
vars :可变长度的数字集合,可选
指定集合的目标常量。可以是多个数字。
数字 布尔
指定以的所有实例为目标
sympy.core.numbers.Number
班级。如果Numbers=False
,则不会收集Float或Rational。- 返回:
expr :表达式
返回收集了相似系数项的表达式。
实例
>>> 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))
If we know nothing about sign of some exponent and
exact
flag is unset, then the exponent's structure will be analyzed and pretty fraction will be returned:>>> 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)
The
exact
flag will also keep any unevaluated Muls from being evaluated:>>> 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理想的基础。实例
>>> 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)
If
polynomial
isFalse
, the algorithm computes a rational simplification which minimizes the sum of the total degrees of the numerator and the denominator.If
polynomial
isTrue
, this function just brings numerator and denominator into a canonical form. This is much faster, but has potentially worse results.工具书类
[R855]M. Monagan, R. Pearce, Rational Simplification Modulo a Polynomial Ideal, https://dl.acm.org/doi/pdf/10.1145/1145768.1145809 (specifically, the second algorithm)
- sympy.simplify.trigsimp.trigsimp(expr, inverse=False, **opts)[源代码]#
Returns a reduced expression by using known trig identities.
- 参数:
inverse : bool, optional
If
inverse=True
, it will be assumed that a composition of inverse functions, such as sin and asin, can be cancelled in any order. For example,asin(sin(x))
will yieldx
without checking whether x belongs to the set where this relation is true. The default is False. Default : True方法 :字符串,可选
Specifies the method to use. Valid choices are:
'matching'
, default'groebner'
'combined'
'fu'
'old'
If
'matching'
, simplify the expression recursively by targeting common patterns. If'groebner'
, apply an experimental groebner basis algorithm. In this case further options are forwarded totrigsimp_groebner
, please refer to its docstring. If'combined'
, it first runs the groebner basis algorithm with small default parameters, then runs the'matching'
algorithm. If'fu'
, run the collection of trigonometric transformations described by Fu, et al. (see thefu()
docstring). If'old'
, the original SymPy trig simplification function is run.opts :
Optional keyword arguments passed to the method. See each method's function docstring for details.
实例
>>> 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)
Using
method='groebner'
(ormethod='combined'
) might lead to greater simplification.The old trigsimp routine can be accessed as with method
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>)[源代码]#
Reduce expression by combining powers with similar bases and exponents.
解释
If
deep
isTrue
then powsimp() will also simplify arguments of functions. By defaultdeep
is set toFalse
.If
force
isTrue
then bases will be combined without checking for assumptions, e.g. sqrt(x)*sqrt(y) -> sqrt(x*y) which is not true if x and y are both negative.通过更改combine='base'或combine='exp',可以使powsimp()只组合基数或只组合指数。默认情况下,combine='all',这两者兼而有之。combine='base'将只组合:
a a a 2x x x * y => (x*y) as well as things like 2 => 4
而combine='exp'将只组合:
a b (a + b) x * x => x
combine='exp'将严格按照以前自动的方式组合指数。如果需要旧的行为,也可以使用deep=True。
当combine='all'时,首先计算'exp'。考虑下面的第一个例子,以了解何时可能存在与此相关的歧义。这样做是为了像第二个例子这样的事情可以完全结合起来。如果要先组合'base',请执行类似powsimp(powsimp(expr,combine='base'),combine='exp')之类的操作。
实例
>>> 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)[源代码]#
在假设允许的情况下收集幂指数。
解释
- 鉴于
(bb**be)**e
可以简化如下: 如果
bb
是肯定的,或者e
是整数,或|be| < 1
then this simplifies tobb**(be*e)
把一个能量的乘积提升为一个幂,
(bb1**be1 * bb2**be2...)**e
,简化方法如下:如果gce与所有的gce都是正的,则可以将其与所有的gce结合;
所有非负的bb都可以从负的bb中分离出来,它们的gcd可以与e结合;autosimplication已经处理了这种分离。
指数分母中含有整数的幂的整数因子可以从任何项中移除,并且这些整数的gcd可以与e结合
Setting
force
toTrue
will make symbols that are not explicitly negative behave as though they are positive, resulting in more denesting.Setting
polar
toTrue
will do simplifications on the Riemann surface of the logarithm, also resulting in more denestings.当exp()中有日志的总和时,可以得到幂的乘积,例如。
exp(3*(log(a) + 2*log(b)))
- >a**3*b**6
.实例
>>> 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()将通过将所有非log项移到函数之外而被denested;这可能导致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)[源代码]#
简化组合表达式。
解释
此函数将包含阶乘、二元数、波希哈默符号和其他“组合”函数的表达式作为输入,并尝试最小化这些函数的数量并减小其参数的大小。
该算法的工作原理是将所有组合函数重写为gamma函数,并应用gammasimp(),但简化步骤可能使整型参数变为非整数。有关详细信息,请参见gammasimp的docstring。
然后它通过将gamma重写为阶乘并转换(a+b),以阶乘和二项式重写表达式!/a!b!变成二项式。
如果表达式有gamma函数或带有非整数参数的组合函数,它将自动传递给gammasimp。
实例
>>> 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)[源代码]#
如果可能,Denests表达式中包含其他平方根的sqrt,否则返回表达式不变。这是基于 [1] .
实例
>>> from sympy.simplify.sqrtdenest import sqrtdenest >>> from sympy import sqrt >>> sqrtdenest(sqrt(5 + 2 * sqrt(6))) sqrt(2) + sqrt(3)
工具书类
[R856][R857]D. J. Jeffrey and A. D. Rich, 'Symplifying Square Roots of Square Roots by Denesting' (available at https://www.cybertester.com/data/denest.pdf)
- sympy.simplify.cse_main.cse(exprs, symbols=None, optimizations=None, postprocess=None, order='canonical', ignore=(), list=True)[源代码]#
对表达式执行公共子表达式消除。
- 参数:
exprs : list of SymPy expressions, or a single SymPy expression
要减少的表达式。
符号 :产生唯一符号的无限迭代器
用于标记提取的公共子表达式的符号。这个
numbered_symbols
发电机很有用。默认值是“x0”、“x1”等形式的符号流。这必须是一个无限迭代器。优化 :列表(可调用,可调用)对
(预处理器,后处理器)对外部优化函数。可选地,可以为一组预定义的基本优化传递“basic”。这种“基本”优化默认用于旧实现,但是在较大的表达式上它们可能会非常缓慢。现在,默认情况下不会进行预优化或后优化。
后处理 :一个接受cse和两个返回值的函数
从cse返回所需的输出形式,例如,如果要反转替换,则函数可以是以下lambda:lambda r,e:return reversed(r),e
秩序 :string,'none'或'canonical'
Mul和Add参数的处理顺序。如果设置为“canonical”,则参数将按规范排序。如果设置为'none',排序将更快,但依赖于表达式哈希,因此依赖于机器和变量。对于需要考虑速度的大型表达式,请使用设置顺序=“无”。
忽视 :i符号表
包含来自的任何符号的替换
ignore
将被忽略。list : bool, (default True)
Returns expression in list or else with same type as input (when False).
- 返回:
替换 :列表(符号,表达式)对
所有被替换的公共子表达式。此列表前面的子表达式可能会显示在此列表后面的子表达式中。
reduced_exprs : list of SymPy expressions
包含以上所有替换项的简化表达式。
实例
>>> 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])
The default return value for the reduced expression(s) is a list, even if there is only one expression. The \(list\) flag preserves the type of the input in the output:
>>> cse(x) ([], [x]) >>> cse(x, list=False) ([], x)
- sympy.simplify.cse_main.opt_cse(exprs, order='canonical')[源代码]#
Find optimization opportunities in Adds, Muls, Pows and negative coefficient Muls.
- 参数:
exprs : list of SymPy expressions
要优化的表达式。
秩序 :string,'none'或'canonical'
Mul和Add参数的处理顺序。对于需要考虑速度的大型表达式,请使用设置顺序=“无”。
- 返回:
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_sub考虑在内。
- 参数:
exprs : list of SymPy expressions
要减少的表达式。
符号 :产生唯一符号的无限迭代器
用于标记提取的公共子表达式的符号。
opt_subs :表达式替换字典
在执行任何CSE操作之前要替换的表达式。
秩序 :string,'none'或'canonical'
Mul和Add参数的处理顺序。对于需要考虑速度的大型表达式,请使用设置顺序=“无”。
忽视 :i符号表
包含来自的任何符号的替换
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)[源代码]#
使用路径操作表达式。
EBNF符号中的EPath语法:
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()函数的docstring。
- 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)[源代码]#
操作由路径选择的表达式部分。
- 参数:
path :str |埃帕斯
作为字符串或编译EPath的路径。
expr :基本
表达式表达式或表达式的容器。
func :可调用(可选)
将应用于匹配部件的可调用项。
args :tuple(可选)
的其他位置参数
func
.关键字参数 :dict(可选)
的其他关键字参数
func
.
解释
此函数允许在一行代码中操作大型嵌套表达式,利用XML处理标准中应用的技术(例如XPath)。
如果
func
是None
,epath()
检索由选定的元素path
. 否则适用func
到每个匹配元素。请注意,创建EPath对象并使用该对象的select和apply方法更有效,因为这样只编译一次路径字符串。此功能只能作为方便的快捷方式使用,以便交互使用。
以下是支持的语法:
- 全选:
/*
相当于
for arg in args:
.
- 全选:
- 选择切片:
/[0]
或/[1:5]
或/[1:5:2]
支持标准的Python切片语法。
- 选择切片:
- 按类型选择:
/list
或/list|tuple
模仿
isinstance()
.
- 按类型选择:
- 按属性选择:
/__iter__?
模仿
hasattr()
.
- 按属性选择:
实例
>>> 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)