本文整理汇总了Python中sympy.polys.factor函数的典型用法代码示例。如果您正苦于以下问题:Python factor函数的具体用法?Python factor怎么用?Python factor使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了factor函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: _separatevars
def _separatevars(expr, force):
if len(expr.free_symbols) == 1:
return expr
# don't destroy a Mul since much of the work may already be done
if expr.is_Mul:
args = list(expr.args)
changed = False
for i, a in enumerate(args):
args[i] = separatevars(a, force)
changed = changed or args[i] != a
if changed:
expr = expr.func(*args)
return expr
# get a Pow ready for expansion
if expr.is_Pow:
expr = Pow(separatevars(expr.base, force=force), expr.exp)
# First try other expansion methods
expr = expr.expand(mul=False, multinomial=False, force=force)
_expr, reps = posify(expr) if force else (expr, {})
expr = factor(_expr).subs(reps)
if not expr.is_Add:
return expr
# Find any common coefficients to pull out
args = list(expr.args)
commonc = args[0].args_cnc(cset=True, warn=False)[0]
for i in args[1:]:
commonc &= i.args_cnc(cset=True, warn=False)[0]
commonc = Mul(*commonc)
commonc = commonc.as_coeff_Mul()[1] # ignore constants
commonc_set = commonc.args_cnc(cset=True, warn=False)[0]
# remove them
for i, a in enumerate(args):
c, nc = a.args_cnc(cset=True, warn=False)
c = c - commonc_set
args[i] = Mul(*c)*Mul(*nc)
nonsepar = Add(*args)
if len(nonsepar.free_symbols) > 1:
_expr = nonsepar
_expr, reps = posify(_expr) if force else (_expr, {})
_expr = (factor(_expr)).subs(reps)
if not _expr.is_Add:
nonsepar = _expr
return commonc*nonsepar
示例2: heuristics
def heuristics(e, z, z0, dir):
"""Computes the limit of an expression term-wise.
Parameters are the same as for the ``limit`` function.
Works with the arguments of expression ``e`` one by one, computing
the limit of each and then combining the results. This approach
works only for simple limits, but it is fast.
"""
from sympy.calculus.util import AccumBounds
rv = None
if abs(z0) is S.Infinity:
rv = limit(e.subs(z, 1/z), z, S.Zero, "+" if z0 is S.Infinity else "-")
if isinstance(rv, Limit):
return
elif e.is_Mul or e.is_Add or e.is_Pow or e.is_Function:
r = []
for a in e.args:
l = limit(a, z, z0, dir)
if l.has(S.Infinity) and l.is_finite is None:
if isinstance(e, Add):
m = factor_terms(e)
if not isinstance(m, Mul): # try together
m = together(m)
if not isinstance(m, Mul): # try factor if the previous methods failed
m = factor(e)
if isinstance(m, Mul):
return heuristics(m, z, z0, dir)
return
return
elif isinstance(l, Limit):
return
elif l is S.NaN:
return
else:
r.append(l)
if r:
rv = e.func(*r)
if rv is S.NaN and e.is_Mul and any(isinstance(rr, AccumBounds) for rr in r):
r2 = []
e2 = []
for ii in range(len(r)):
if isinstance(r[ii], AccumBounds):
r2.append(r[ii])
else:
e2.append(e.args[ii])
if len(e2) > 0:
e3 = Mul(*e2).simplify()
l = limit(e3, z, z0, dir)
rv = l * Mul(*r2)
if rv is S.NaN:
try:
rat_e = ratsimp(e)
except PolynomialError:
return
if rat_e is S.NaN or rat_e == e:
return
return limit(rat_e, z, z0, dir)
return rv
示例3: _futrig
def _futrig(e, **kwargs):
"""Helper for futrig."""
from sympy.simplify.fu import (
TR1, TR2, TR3, TR2i, TR10, L, TR10i,
TR8, TR6, TR15, TR16, TR111, TR5, TRmorrie, TR11, TR14, TR22,
TR12)
from sympy.core.compatibility import _nodes
if not e.has(TrigonometricFunction):
return e
if e.is_Mul:
coeff, e = e.as_independent(TrigonometricFunction)
else:
coeff = S.One
Lops = lambda x: (L(x), x.count_ops(), _nodes(x), len(x.args), x.is_Add)
trigs = lambda x: x.has(TrigonometricFunction)
tree = [identity,
(
TR3, # canonical angles
TR1, # sec-csc -> cos-sin
TR12, # expand tan of sum
lambda x: _eapply(factor, x, trigs),
TR2, # tan-cot -> sin-cos
[identity, lambda x: _eapply(_mexpand, x, trigs)],
TR2i, # sin-cos ratio -> tan
lambda x: _eapply(lambda i: factor(i.normal()), x, trigs),
TR14, # factored identities
TR5, # sin-pow -> cos_pow
TR10, # sin-cos of sums -> sin-cos prod
TR11, TR6, # reduce double angles and rewrite cos pows
lambda x: _eapply(factor, x, trigs),
TR14, # factored powers of identities
[identity, lambda x: _eapply(_mexpand, x, trigs)],
TRmorrie,
TR10i, # sin-cos products > sin-cos of sums
[identity, TR8], # sin-cos products -> sin-cos of sums
[identity, lambda x: TR2i(TR2(x))], # tan -> sin-cos -> tan
[
lambda x: _eapply(expand_mul, TR5(x), trigs),
lambda x: _eapply(
expand_mul, TR15(x), trigs)], # pos/neg powers of sin
[
lambda x: _eapply(expand_mul, TR6(x), trigs),
lambda x: _eapply(
expand_mul, TR16(x), trigs)], # pos/neg powers of cos
TR111, # tan, sin, cos to neg power -> cot, csc, sec
[identity, TR2i], # sin-cos ratio to tan
[identity, lambda x: _eapply(
expand_mul, TR22(x), trigs)], # tan-cot to sec-csc
TR1, TR2, TR2i,
[identity, lambda x: _eapply(
factor_terms, TR12(x), trigs)], # expand tan of sum
)]
e = greedy(tree, objective=Lops)(e)
return coeff*e
示例4: apart
def apart(f, x=None, full=False, **options):
"""
Compute partial fraction decomposition of a rational function.
Given a rational function ``f`` compute partial fraction decomposition
of ``f``. Two algorithms are available: one is based on undetermined
coefficients method and the other is Bronstein's full partial fraction
decomposition algorithm.
Examples
========
>>> from sympy.polys.partfrac import apart
>>> from sympy.abc import x, y
>>> apart(y/(x + 2)/(x + 1), x)
-y/(x + 2) + y/(x + 1)
"""
allowed_flags(options, [])
f = sympify(f)
if f.is_Atom:
return f
else:
P, Q = f.as_numer_denom()
options = set_defaults(options, extension=True)
(P, Q), opt = parallel_poly_from_expr((P, Q), x, **options)
if P.is_multivariate:
raise NotImplementedError(
"multivariate partial fraction decomposition")
common, P, Q = P.cancel(Q)
poly, P = P.div(Q, auto=True)
P, Q = P.rat_clear_denoms(Q)
if Q.degree() <= 1:
partial = P/Q
else:
if not full:
partial = apart_undetermined_coeffs(P, Q)
else:
partial = apart_full_decomposition(P, Q)
terms = S.Zero
for term in Add.make_args(partial):
if term.has(RootSum):
terms += term
else:
terms += factor(term)
return common*(poly.as_expr() + terms)
示例5: gosper_sum
def gosper_sum(f, k):
r"""
Gosper's hypergeometric summation algorithm.
Given a hypergeometric term ``f`` such that:
.. math ::
s_n = \sum_{k=0}^{n-1} f_k
and `f(n)` doesn't depend on `n`, returns `g_{n} - g(0)` where
`g_{n+1} - g_n = f_n`, or ``None`` if `s_n` can not be expressed
in closed form as a sum of hypergeometric terms.
Examples
========
>>> from sympy.concrete.gosper import gosper_sum
>>> from sympy.functions import factorial
>>> from sympy.abc import i, n, k
>>> f = (4*k + 1)*factorial(k)/factorial(2*k + 1)
>>> gosper_sum(f, (k, 0, n))
(-n! + 2*(2*n + 1)!)/(2*n + 1)!
>>> _.subs(n, 2) == sum(f.subs(k, i) for i in [0, 1, 2])
True
>>> gosper_sum(f, (k, 3, n))
(-60*n! + (2*n + 1)!)/(60*(2*n + 1)!)
>>> _.subs(n, 5) == sum(f.subs(k, i) for i in [3, 4, 5])
True
References
==========
.. [1] Marko Petkovsek, Herbert S. Wilf, Doron Zeilberger, A = B,
AK Peters, Ltd., Wellesley, MA, USA, 1997, pp. 73--100
"""
indefinite = False
if is_sequence(k):
k, a, b = k
else:
indefinite = True
g = gosper_term(f, k)
if g is None:
return None
if indefinite:
result = f*g
else:
result = (f*(g+1)).subs(k, b) - (f*g).subs(k, a)
return factor(result)
示例6: heuristics
def heuristics(e, z, z0, dir):
from sympy.calculus.util import AccumBounds
rv = None
if abs(z0) is S.Infinity:
rv = limit(e.subs(z, 1/z), z, S.Zero, "+" if z0 is S.Infinity else "-")
if isinstance(rv, Limit):
return
elif e.is_Mul or e.is_Add or e.is_Pow or e.is_Function:
r = []
for a in e.args:
l = limit(a, z, z0, dir)
if l.has(S.Infinity) and l.is_finite is None:
if isinstance(e, Add):
m = factor_terms(e)
if not isinstance(m, Mul): # try together
m = together(m)
if not isinstance(m, Mul): # try factor if the previous methods failed
m = factor(e)
if isinstance(m, Mul):
return heuristics(m, z, z0, dir)
return
return
elif isinstance(l, Limit):
return
elif l is S.NaN:
return
else:
r.append(l)
if r:
rv = e.func(*r)
if rv is S.NaN and e.is_Mul and any(isinstance(rr, AccumBounds) for rr in r):
r2 = []
e2 = []
for ii in range(len(r)):
if isinstance(r[ii], AccumBounds):
r2.append(r[ii])
else:
e2.append(e.args[ii])
if len(e2) > 0:
e3 = Mul(*e2).simplify()
l = limit(e3, z, z0, dir)
rv = l * Mul(*r2)
if rv is S.NaN:
try:
rat_e = ratsimp(e)
except PolynomialError:
return
if rat_e is S.NaN or rat_e == e:
return
return limit(rat_e, z, z0, dir)
return rv
示例7: gosper_sum
def gosper_sum(f, k):
"""
Gosper's hypergeometric summation algorithm.
Given a hypergeometric term ``f`` such that::
.. math::
s_n = \sum_{k=0}^{n-1} f_k
and $f(n)$ doesn't depend on $n$, returns $g_{n} - g(0)$ where
$g_{n+1} - g_n = f_n$, or ``None`` if $s_n$ can not be expressed
in closed form as a sum of hypergeometric terms.
**Examples**
>>> from sympy.concrete.gosper import gosper_sum
>>> from sympy.functions import factorial
>>> from sympy.abc import n, k
>>> gosper_sum((4*k + 1)*factorial(k)/factorial(2*k + 1), (k, 0, n))
(-n! + 2*(2*n + 1)!)/(2*n + 1)!
**References**
.. [1] Marko Petkovsek, Herbert S. Wilf, Doron Zeilberger, A = B,
AK Peters, Ltd., Wellesley, MA, USA, 1997, pp. 73--100
"""
indefinite = False
if is_sequence(k):
k, a, b = k
else:
indefinite = True
g = gosper_term(f, k)
if g is None:
return None
if indefinite:
result = f*g
else:
result = (f*(g+1)).subs(k, b) - (f*g).subs(k, a)
return factor(result)
示例8: _separatevars
def _separatevars(expr):
# First try other expansion methods
expr = expr.expand(mul=False, multinomial=False)
try:
expr = factor(expr)
except PolynomialError:
pass
_coeff = Symbol('_coeff', dummy=True)
if expr.is_Add:
nonsepar = sympify(0)
# Find any common coeficients to pull out
commoncsetlist = []
for i in expr.args:
if i.is_Mul:
commoncsetlist.append(set(i.args))
else:
commoncsetlist.append(set((i,)))
commoncset = set(flatten(commoncsetlist))
commonc = sympify(1)
for i in commoncsetlist:
commoncset = commoncset.intersection(i)
commonc = Mul(*commoncset)
for i in expr.args:
coe = i.extract_multiplicatively(commonc)
if coe == None:
nonsepar += sympify(1)
else:
nonsepar += coe
if nonsepar == 0:
return commonc
else:
return commonc*nonsepar
else:
return expr
示例9: heuristics
def heuristics(e, z, z0, dir):
rv = None
if abs(z0) is S.Infinity:
rv = limit(e.subs(z, 1/z), z, S.Zero, "+" if z0 is S.Infinity else "-")
if isinstance(rv, Limit):
return
elif e.is_Mul or e.is_Add or e.is_Pow or e.is_Function:
r = []
for a in e.args:
l = limit(a, z, z0, dir)
if l.has(S.Infinity) and l.is_finite is None:
if isinstance(e, Add):
m = factor_terms(e)
if not isinstance(m, Mul): # try together
m = together(m)
if not isinstance(m, Mul): # try factor if the previous methods failed
m = factor(e)
if isinstance(m, Mul):
return heuristics(m, z, z0, dir)
return
return
elif isinstance(l, Limit):
return
elif l is S.NaN:
return
else:
r.append(l)
if r:
rv = e.func(*r)
if rv is S.NaN:
try:
rat_e = ratsimp(e)
except PolynomialError:
return
if rat_e is S.NaN or rat_e == e:
return
return limit(rat_e, z, z0, dir)
return rv
示例10: apart
def apart(f, x=None, full=False, **options):
"""
Compute partial fraction decomposition of a rational function.
Given a rational function ``f``, computes the partial fraction
decomposition of ``f``. Two algorithms are available: One is based on the
undertermined coefficients method, the other is Bronstein's full partial
fraction decomposition algorithm.
The undetermined coefficients method (selected by ``full=False``) uses
polynomial factorization (and therefore accepts the same options as
factor) for the denominator. Per default it works over the rational
numbers, therefore decomposition of denominators with non-rational roots
(e.g. irrational, complex roots) is not supported by default (see options
of factor).
Bronstein's algorithm can be selected by using ``full=True`` and allows a
decomposition of denominators with non-rational roots. A human-readable
result can be obtained via ``doit()`` (see examples below).
Examples
========
>>> from sympy.polys.partfrac import apart
>>> from sympy.abc import x, y
By default, using the undetermined coefficients method:
>>> apart(y/(x + 2)/(x + 1), x)
-y/(x + 2) + y/(x + 1)
The undetermined coefficients method does not provide a result when the
denominators roots are not rational:
>>> apart(y/(x**2 + x + 1), x)
y/(x**2 + x + 1)
You can choose Bronstein's algorithm by setting ``full=True``:
>>> apart(y/(x**2 + x + 1), x, full=True)
RootSum(_w**2 + _w + 1, Lambda(_a, (-2*_a*y/3 - y/3)/(-_a + x)))
Calling ``doit()`` yields a human-readable result:
>>> apart(y/(x**2 + x + 1), x, full=True).doit()
(-y/3 - 2*y*(-1/2 - sqrt(3)*I/2)/3)/(x + 1/2 + sqrt(3)*I/2) + (-y/3 -
2*y*(-1/2 + sqrt(3)*I/2)/3)/(x + 1/2 - sqrt(3)*I/2)
See Also
========
apart_list, assemble_partfrac_list
"""
allowed_flags(options, [])
f = sympify(f)
if f.is_Atom:
return f
else:
P, Q = f.as_numer_denom()
_options = options.copy()
options = set_defaults(options, extension=True)
try:
(P, Q), opt = parallel_poly_from_expr((P, Q), x, **options)
except PolynomialError as msg:
if f.is_commutative:
raise PolynomialError(msg)
# non-commutative
if f.is_Mul:
c, nc = f.args_cnc(split_1=False)
nc = f.func(*nc)
if c:
c = apart(f.func._from_args(c), x=x, full=full, **_options)
return c*nc
else:
return nc
elif f.is_Add:
c = []
nc = []
for i in f.args:
if i.is_commutative:
c.append(i)
else:
try:
nc.append(apart(i, x=x, full=full, **_options))
except NotImplementedError:
nc.append(i)
return apart(f.func(*c), x=x, full=full, **_options) + f.func(*nc)
else:
reps = []
pot = preorder_traversal(f)
next(pot)
for e in pot:
try:
reps.append((e, apart(e, x=x, full=full, **_options)))
pot.skip() # this was handled successfully
except NotImplementedError:
#.........这里部分代码省略.........
示例11: factor_nc
def factor_nc(expr):
"""Return the factored form of ``expr`` while handling non-commutative
expressions.
**examples**
>>> from sympy.core.exprtools import factor_nc
>>> from sympy import Symbol
>>> from sympy.abc import x
>>> A = Symbol('A', commutative=False)
>>> B = Symbol('B', commutative=False)
>>> factor_nc((x**2 + 2*A*x + A**2).expand())
(x + A)**2
>>> factor_nc(((x + A)*(x + B)).expand())
(x + A)*(x + B)
"""
from sympy.simplify.simplify import _mexpand
from sympy.polys import gcd, factor
expr = sympify(expr)
if not isinstance(expr, Expr) or not expr.args:
return expr
if not expr.is_Add:
return expr.func(*[factor_nc(a) for a in expr.args])
expr, rep, nc_symbols = _mask_nc(expr)
if rep:
return factor(expr).subs(rep)
else:
args = [a.args_cnc() for a in Add.make_args(expr)]
c = g = l = r = S.One
hit = False
# find any commutative gcd term
for i, a in enumerate(args):
if i == 0:
c = Mul._from_args(a[0])
elif a[0]:
c = gcd(c, Mul._from_args(a[0]))
else:
c = S.One
if c is not S.One:
hit = True
c, g = c.as_coeff_Mul()
if g is not S.One:
for i, (cc, _) in enumerate(args):
cc = list(Mul.make_args(Mul._from_args(list(cc))/g))
args[i][0] = cc
else:
for i, (cc, _) in enumerate(args):
cc[0] = cc[0]/c
args[i][0] = cc
# find any noncommutative common prefix
for i, a in enumerate(args):
if i == 0:
n = a[1][:]
else:
n = common_prefix(n, a[1])
if not n:
# is there a power that can be extracted?
if not args[0][1]:
break
b, e = args[0][1][0].as_base_exp()
ok = False
if e.is_Integer:
for t in args:
if not t[1]:
break
bt, et = t[1][0].as_base_exp()
if et.is_Integer and bt == b:
e = min(e, et)
else:
break
else:
ok = hit = True
l = b**e
il = b**-e
for i, a in enumerate(args):
args[i][1][0] = il*args[i][1][0]
break
if not ok:
break
else:
hit = True
lenn = len(n)
l = Mul(*n)
for i, a in enumerate(args):
args[i][1] = args[i][1][lenn:]
# find any noncommutative common suffix
for i, a in enumerate(args):
if i == 0:
n = a[1][:]
else:
n = common_suffix(n, a[1])
if not n:
# is there a power that can be extracted?
if not args[0][1]:
break
b, e = args[0][1][-1].as_base_exp()
ok = False
if e.is_Integer:
for t in args:
#.........这里部分代码省略.........
示例12: factor
def factor(self, *gens, **args):
"""See the factor function in sympy.simplify"""
from sympy.polys import factor
return factor(self, *gens, **args)
示例13: expand_polyeq
def expand_polyeq(eq):
if not isinstance(eq, Rel):
return eq
rel = eq.func
expr = factor(eq.args[0]-eq.args[1])
if expr.is_number:
return rel(expr, 0, evaluate=True)
elif isinstance(expr, Mul):
terms = expr.args
else:
terms = (expr,)
# eliminate positive/negative terms
terms = tuple(t for t in terms if not _is_positive(t))
sign = len(terms)
terms = tuple(t for t in terms if not _is_negative(t))
sign -= len(terms)
# reduce power terms
terms1 = (t for t in terms if not isinstance(t, Pow))
termspow = tuple(t for t in terms if isinstance(t, Pow))
terms2 = (t.args[0] for t in termspow if t.args[1]%2==0)
terms3 = (t.args[0] for t in termspow if t.args[1]%2==1)
# find positive-or-zero terms
termsp_ = list(terms2)
termsn = []
for term in chain(terms1, terms3):
if _is_positive_or_zero(term):
termsp_.append(term)
elif _is_negative_or_zero(term):
termsp_.append(-term)
sign += 1
else:
termsn.append(term)
# reduce polynomial positive-or-zero terms
termsp = []
for term in termsp_:
if is_polynomial(term):
termsp.extend(term.free_symbols)
else:
termsp.append(term)
# normalize leading coeff
for i in range(len(termsn)):
lc = LC(termsn[i], sorted(termsn[i].free_symbols, key=lambda x: x.name))
if lc < 0:
sign += 1
termsn[i] = termsn[i]/lc
for i in range(len(termsp)):
lc = LC(termsp[i], sorted(termsp[i].free_symbols, key=lambda x: x.name))
termsp[i] = termsp[i]/lc
# swap relation
if sign % 2 == 1:
swap = {Eq: Eq, Ne: Ne,
Lt: Gt, Le: Ge,
Gt: Lt, Ge: Le}
rel = swap[rel]
# construct expression
eqs = []
if rel == Ne:
eqs.append(And(*[Ne(term,0) for term in termsn+termsp]))
elif rel == Gt:
eq0 = And(*[Ne(term,0) for term in termsp])
for i in range(0, len(termsn)+1, 2):
for neg in combinations(termsn, i):
pos = tuple(set(termsn)-set(neg))
eqp = And(*[Gt(p,0) for p in pos])
eqn = And(*[Lt(n,0) for n in neg])
eqs.append(And(eq0, eqp, eqn))
elif rel == Ge:
for i in range(0, len(termsn)+1, 2):
for neg in combinations(termsn, i):
pos = tuple(set(termsn)-set(neg))
eqp = And(*[Gt(p,0) for p in pos])
eqn = And(*[Lt(n,0) for n in neg])
eqs.append(And(eqp, eqn))
elif rel == Lt:
eq0 = And(*[Ne(term,0) for term in termsp])
for i in range(1, len(termsn)+1, 2):
for neg in combinations(termsn, i):
pos = tuple(set(termsn)-set(neg))
eqp = And(*[Gt(p,0) for p in pos])
eqn = And(*[Lt(n,0) for n in neg])
eqs.append(And(eq0, eqp, eqn))
elif rel == Le:
for i in range(1, len(termsn)+1, 2):
for neg in combinations(termsn, i):
pos = tuple(set(termsn)-set(neg))
eqp = And(*[Gt(p,0) for p in pos])
eqn = And(*[Lt(n,0) for n in neg])
eqs.append(And(eqp, eqn))
if rel in (Eq, Ge, Le):
for term in termsn+termsp:
eqs.append(Eq(term,0))
return Or(*eqs)
示例14: apart
#.........这里部分代码省略.........
>>> from sympy.polys.partfrac import apart
>>> from sympy.abc import x, y
By default, using the undetermined coefficients method:
>>> apart(y/(x + 2)/(x + 1), x)
-y/(x + 2) + y/(x + 1)
You can choose Bronstein's algorithm by setting ``full=True``:
>>> apart(y/(x**2 + x + 1), x)
y/(x**2 + x + 1)
>>> apart(y/(x**2 + x + 1), x, full=True)
RootSum(_w**2 + _w + 1, Lambda(_a, (-2*_a*y/3 - y/3)/(-_a + x)))
See Also
========
apart_list, assemble_partfrac_list
"""
allowed_flags(options, [])
f = sympify(f)
if f.is_Atom:
return f
else:
P, Q = f.as_numer_denom()
_options = options.copy()
options = set_defaults(options, extension=True)
try:
(P, Q), opt = parallel_poly_from_expr((P, Q), x, **options)
except PolynomialError as msg:
if f.is_commutative:
raise PolynomialError(msg)
# non-commutative
if f.is_Mul:
c, nc = f.args_cnc(split_1=False)
nc = Mul(*[apart(i, x=x, full=full, **_options) for i in nc])
if c:
c = apart(Mul._from_args(c), x=x, full=full, **_options)
return c*nc
else:
return nc
elif f.is_Add:
c = []
nc = []
for i in f.args:
if i.is_commutative:
c.append(i)
else:
try:
nc.append(apart(i, x=x, full=full, **_options))
except NotImplementedError:
nc.append(i)
return apart(Add(*c), x=x, full=full, **_options) + Add(*nc)
else:
reps = []
pot = preorder_traversal(f)
pot.next()
for e in pot:
try:
reps.append((e, apart(e, x=x, full=full, **_options)))
pot.skip() # this was handled successfully
except NotImplementedError:
pass
return f.xreplace(dict(reps))
if P.is_multivariate:
fc = f.cancel()
if fc != f:
return apart(fc, x=x, full=full, **_options)
raise NotImplementedError(
"multivariate partial fraction decomposition")
common, P, Q = P.cancel(Q)
poly, P = P.div(Q, auto=True)
P, Q = P.rat_clear_denoms(Q)
if Q.degree() <= 1:
partial = P/Q
else:
if not full:
partial = apart_undetermined_coeffs(P, Q)
else:
partial = apart_full_decomposition(P, Q)
terms = S.Zero
for term in Add.make_args(partial):
if term.has(RootSum):
terms += term
else:
terms += factor(term)
return common*(poly.as_expr() + terms)
示例15: _gammasimp
def _gammasimp(expr, as_comb):
"""
Helper function for gammasimp and combsimp.
Simplifies expressions written in terms of gamma function. If
as_comb is True, it tries to preserve integer arguments. See
docstring of gammasimp for more information. This was part of
combsimp() in combsimp.py.
"""
expr = expr.replace(gamma,
lambda n: _rf(1, (n - 1).expand()))
if as_comb:
expr = expr.replace(_rf,
lambda a, b: gamma(b + 1))
else:
expr = expr.replace(_rf,
lambda a, b: gamma(a + b)/gamma(a))
def rule(n, k):
coeff, rewrite = S.One, False
cn, _n = n.as_coeff_Add()
if _n and cn.is_Integer and cn:
coeff *= _rf(_n + 1, cn)/_rf(_n - k + 1, cn)
rewrite = True
n = _n
# this sort of binomial has already been removed by
# rising factorials but is left here in case the order
# of rule application is changed
if k.is_Add:
ck, _k = k.as_coeff_Add()
if _k and ck.is_Integer and ck:
coeff *= _rf(n - ck - _k + 1, ck)/_rf(_k + 1, ck)
rewrite = True
k = _k
if count_ops(k) > count_ops(n - k):
rewrite = True
k = n - k
if rewrite:
return coeff*binomial(n, k)
expr = expr.replace(binomial, rule)
def rule_gamma(expr, level=0):
""" Simplify products of gamma functions further. """
if expr.is_Atom:
return expr
def gamma_rat(x):
# helper to simplify ratios of gammas
was = x.count(gamma)
xx = x.replace(gamma, lambda n: _rf(1, (n - 1).expand()
).replace(_rf, lambda a, b: gamma(a + b)/gamma(a)))
if xx.count(gamma) < was:
x = xx
return x
def gamma_factor(x):
# return True if there is a gamma factor in shallow args
if isinstance(x, gamma):
return True
if x.is_Add or x.is_Mul:
return any(gamma_factor(xi) for xi in x.args)
if x.is_Pow and (x.exp.is_integer or x.base.is_positive):
return gamma_factor(x.base)
return False
# recursion step
if level == 0:
expr = expr.func(*[rule_gamma(x, level + 1) for x in expr.args])
level += 1
if not expr.is_Mul:
return expr
# non-commutative step
if level == 1:
args, nc = expr.args_cnc()
if not args:
return expr
if nc:
return rule_gamma(Mul._from_args(args), level + 1)*Mul._from_args(nc)
level += 1
# pure gamma handling, not factor absorption
if level == 2:
T, F = sift(expr.args, gamma_factor, binary=True)
gamma_ind = Mul(*F)
d = Mul(*T)
nd, dd = d.as_numer_denom()
for ipass in range(2):
args = list(ordered(Mul.make_args(nd)))
#.........这里部分代码省略.........