本文整理汇总了Python中sympy.utilities.numbered_symbols函数的典型用法代码示例。如果您正苦于以下问题:Python numbered_symbols函数的具体用法?Python numbered_symbols怎么用?Python numbered_symbols使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了numbered_symbols函数的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: genEval
def genEval(self):
text = " bool evaluate(\n"
args=[]
for name,v in self.variables:
if v.is_Matrix:
args.append(" const Eigen::MatrixXd & %s" % name)
else:
args.append(" double %s" % name)
args.append(" bool evalF=true,bool evalJ=true")
text += ",\n".join(args) + ") {\n"
text += " if (evalF) {\n"
(interm, expr) = cse(self.function,numbered_symbols("__x"));
for dummy,exp in interm:
text += " double %s = %s;\n" % (str(dummy),ccode(exp))
for i in range(self.function.rows):
text += " F(%d) = %s;\n" % (i,ccode(expr[0][i]))
text += " }\n"
text += " if (evalJ) {\n"
(interm, expr) = cse(self.J,numbered_symbols("__x"));
for dummy,exp in interm:
text += " double %s = %s;\n" % (str(dummy),ccode(exp))
for i in range(self.J.rows):
for j in range(self.J.cols):
text += " J(%d,%d) = %s;\n" % (i,j,ccode(expr[0][i,j]))
text += " }\n"
text += " return true;\n"
text += " }\n"
return text
示例2: viete
def viete(f, roots=None, *gens, **args):
"""
Generate Viete's formulas for ``f``.
Examples
========
>>> from sympy.polys.polyfuncs import viete
>>> from sympy import symbols
>>> x, a, b, c, r1, r2 = symbols('x,a:c,r1:3')
>>> viete(a*x**2 + b*x + c, [r1, r2], x)
[(r1 + r2, -b/a), (r1*r2, c/a)]
"""
allowed_flags(args, [])
if isinstance(roots, Basic):
gens, roots = (roots,) + gens, None
try:
f, opt = poly_from_expr(f, *gens, **args)
except PolificationFailed as exc:
raise ComputationFailed('viete', 1, exc)
if f.is_multivariate:
raise MultivariatePolynomialError(
"multivariate polynomials are not allowed")
n = f.degree()
if n < 1:
raise ValueError(
"can't derive Viete's formulas for a constant polynomial")
if roots is None:
roots = numbered_symbols('r', start=1)
roots = take(roots, n)
if n != len(roots):
raise ValueError("required %s roots, got %s" % (n, len(roots)))
lc, coeffs = f.LC(), f.all_coeffs()
result, sign = [], -1
for i, coeff in enumerate(coeffs[1:]):
poly = symmetric_poly(i + 1, roots)
coeff = sign*(coeff/lc)
result.append((poly, coeff))
sign = -sign
return result
示例3: genEval
def genEval(self):
text = " bool evaluate(\n"
args=[]
for name,v,lD in self.variables:
if isinstance(v, Matrix):
args.append(" const Eigen::Matrix<double, %d, 1> & %s" % (v.rows, name))
else:
args.append(" double %s" % name)
args.append(" Eigen::Matrix<double, %d, 1> * F" % self.function.rows)
for name,v,localDim in self.variables:
if isinstance(v, Matrix):
args.append(" Eigen::Matrix<double, %d, %d> * J%s" % (self.J.rows, localDim, name))
else:
args.append(" Eigen::Matrix<double, %d, 1> * J%s" % (self.J.rows, name))
text += ",\n".join(args) + ") {\n"
text += " if (F) {\n"
(interm, expr) = cse(self.function,numbered_symbols("__x"));
for dummy,exp in interm:
text += " double %s = %s;\n" % (str(dummy),ccode(exp))
for i in range(self.function.rows):
text += " (*F)(%d) = %s;\n" % (i,ccode(expr[0][i]))
text += " }\n"
text += " if (%s) {\n" % " && ".join([ "J" + name for name,v,lD in self.variables ])
(interm, expr) = cse(self.J,numbered_symbols("__x"));
for dummy,exp in interm:
text += " double %s = %s;\n" % (str(dummy),ccode(exp))
colBase = 0;
for name,v,localDim in self.variables:
for i in range(self.J.rows):
for j in range(0, localDim):
text += " (*J%s)(%d,%d) = %s;\n" % (name, i,j,ccode(expr[0][i,colBase + j]))
colBase+=localDim
text += " }\n"
text += " return true;\n"
text += " }\n"
return text
示例4: apart_undetermined_coeffs
def apart_undetermined_coeffs(P, Q):
"""Partial fractions via method of undetermined coefficients. """
X = numbered_symbols(cls=Dummy)
partial, symbols = [], []
_, factors = Q.factor_list()
for f, k in factors:
n, q = f.degree(), Q
for i in xrange(1, k + 1):
coeffs, q = take(X, n), q.quo(f)
partial.append((coeffs, q, f, i))
symbols.extend(coeffs)
dom = Q.get_domain().inject(*symbols)
F = Poly(0, Q.gen, domain=dom)
for i, (coeffs, q, f, k) in enumerate(partial):
h = Poly(coeffs, Q.gen, domain=dom)
partial[i] = (h, f, k)
q = q.set_domain(dom)
F += h * q
system, result = [], S(0)
for (k,), coeff in F.terms():
system.append(coeff - P.nth(k))
from sympy.solvers import solve
solution = solve(system, symbols)
for h, f, k in partial:
h = h.as_expr().subs(solution)
result += h / f.as_expr() ** k
return result
示例5: default
def default(cls):
return numbered_symbols('s', start=1)
示例6: test_convert_to_symbolic_indices
#.........这里部分代码省略.........
expected = (X(i0), Y(i0), Z(i0), H(i0), X(i1), Y(i1), Z(i1), H(i1))
exp_map = {i0: Integer(0), i1: Integer(1)}
actual, act_map, sndx, gen = convert_to_symbolic_indices((x, y, z, h,
x1, y1, z1, h1))
assert actual == expected
assert act_map == exp_map
exp_map = {i0: Integer(1), i1: Integer(0)}
actual, act_map, sndx, gen = convert_to_symbolic_indices(Mul(x1, y1,
z1, h1, x, y, z, h))
assert actual == expected
assert act_map == exp_map
expected = (X(i0), X(i1), Y(i0), Y(i1), Z(i0), Z(i1), H(i0), H(i1))
exp_map = {i0: Integer(0), i1: Integer(1)}
actual, act_map, sndx, gen = convert_to_symbolic_indices(Mul(x, x1,
y, y1, z, z1, h, h1))
assert actual == expected
assert act_map == exp_map
exp_map = {i0: Integer(1), i1: Integer(0)}
actual, act_map, sndx, gen = convert_to_symbolic_indices((x1, x, y1, y,
z1, z, h1, h))
assert actual == expected
assert act_map == exp_map
cnot_10 = CNOT(1, 0)
cnot_01 = CNOT(0, 1)
cgate_z_10 = CGate(1, Z(0))
cgate_z_01 = CGate(0, Z(1))
expected = (X(i0), X(i1), Y(i0), Y(i1), Z(i0), Z(i1),
H(i0), H(i1), CNOT(i1, i0), CNOT(i0, i1),
CGate(i1, Z(i0)), CGate(i0, Z(i1)))
exp_map = {i0: Integer(0), i1: Integer(1)}
args = (x, x1, y, y1, z, z1, h, h1, cnot_10, cnot_01,
cgate_z_10, cgate_z_01)
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
assert actual == expected
assert act_map == exp_map
args = (x1, x, y1, y, z1, z, h1, h, cnot_10, cnot_01,
cgate_z_10, cgate_z_01)
expected = (X(i0), X(i1), Y(i0), Y(i1), Z(i0), Z(i1),
H(i0), H(i1), CNOT(i0, i1), CNOT(i1, i0),
CGate(i0, Z(i1)), CGate(i1, Z(i0)))
exp_map = {i0: Integer(1), i1: Integer(0)}
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
assert actual == expected
assert act_map == exp_map
args = (cnot_10, h, cgate_z_01, h)
expected = (CNOT(i0, i1), H(i1), CGate(i1, Z(i0)), H(i1))
exp_map = {i0: Integer(1), i1: Integer(0)}
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
assert actual == expected
assert act_map == exp_map
args = (cnot_01, h1, cgate_z_10, h1)
exp_map = {i0: Integer(0), i1: Integer(1)}
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
assert actual == expected
assert act_map == exp_map
args = (cnot_10, h1, cgate_z_01, h1)
expected = (CNOT(i0, i1), H(i0), CGate(i1, Z(i0)), H(i0))
exp_map = {i0: Integer(1), i1: Integer(0)}
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
assert actual == expected
assert act_map == exp_map
i2 = Symbol('i2')
ccgate_z = CGate(0, CGate(1, Z(2)))
ccgate_x = CGate(1, CGate(2, X(0)))
args = (ccgate_z, ccgate_x)
expected = (CGate(i0, CGate(i1, Z(i2))), CGate(i1, CGate(i2, X(i0))))
exp_map = {i0: Integer(0), i1: Integer(1), i2: Integer(2)}
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
assert actual == expected
assert act_map == exp_map
ndx_map = {i0: Integer(0)}
index_gen = numbered_symbols(prefix='i', start=1)
actual, act_map, sndx, gen = convert_to_symbolic_indices(args,
qubit_map=ndx_map,
start=i0,
gen=index_gen)
assert actual == expected
assert act_map == exp_map
i3 = Symbol('i3')
cgate_x0_c321 = CGate((3, 2, 1), X(0))
exp_map = {i0: Integer(3), i1: Integer(2),
i2: Integer(1), i3: Integer(0)}
expected = (CGate((i0, i1, i2), X(i3)),)
args = (cgate_x0_c321,)
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
assert actual == expected
assert act_map == exp_map
示例7: convert_to_symbolic_indices
def convert_to_symbolic_indices(seq, start=None, gen=None, qubit_map=None):
"""Returns the circuit with symbolic indices and the
dictionary mapping symbolic indices to real indices.
The mapping is 1 to 1 and onto (bijective).
Parameters
==========
seq : tuple, Gate/Integer/tuple or Mul
A tuple of Gate, Integer, or tuple objects, or a Mul
start : Symbol
An optional starting symbolic index
gen : object
An optional numbered symbol generator
qubit_map : dict
An existing mapping of symbolic indices to real indices
All symbolic indices have the format 'i#', where # is
some number >= 0.
"""
if isinstance(seq, Mul):
seq = seq.args
# A numbered symbol generator
index_gen = numbered_symbols(prefix='i', start=-1)
cur_ndx = index_gen.next()
# keys are symbolic indices; values are real indices
ndx_map = {}
def create_inverse_map(symb_to_real_map):
rev_items = lambda item: tuple([item[1], item[0]])
return dict(map(rev_items, symb_to_real_map.items()))
if start is not None:
if not isinstance(start, Symbol):
msg = 'Expected Symbol for starting index, got %r.' % start
raise TypeError(msg)
cur_ndx = start
if gen is not None:
if not isinstance(gen, numbered_symbols().__class__):
msg = 'Expected a generator, got %r.' % gen
raise TypeError(msg)
index_gen = gen
if qubit_map is not None:
if not isinstance(qubit_map, dict):
msg = ('Expected dict for existing map, got ' +
'%r.' % qubit_map)
raise TypeError(msg)
ndx_map = qubit_map
ndx_map = _sympify_qubit_map(ndx_map)
# keys are real indices; keys are symbolic indices
inv_map = create_inverse_map(ndx_map)
sym_seq = ()
for item in seq:
# Nested items, so recurse
if isinstance(item, Gate):
result = convert_to_symbolic_indices(item.args,
qubit_map=ndx_map,
start=cur_ndx,
gen=index_gen)
sym_item, new_map, cur_ndx, index_gen = result
ndx_map.update(new_map)
inv_map = create_inverse_map(ndx_map)
elif isinstance(item, tuple) or isinstance(item, Tuple):
result = convert_to_symbolic_indices(item,
qubit_map=ndx_map,
start=cur_ndx,
gen=index_gen)
sym_item, new_map, cur_ndx, index_gen = result
ndx_map.update(new_map)
inv_map = create_inverse_map(ndx_map)
elif item in inv_map:
sym_item = inv_map[item]
else:
cur_ndx = gen.next()
ndx_map[cur_ndx] = item
inv_map[item] = cur_ndx
sym_item = cur_ndx
if isinstance(item, Gate):
sym_item = item.__class__(*sym_item)
sym_seq = sym_seq + (sym_item,)
return sym_seq, ndx_map, cur_ndx, index_gen
示例8: primitive_element
def primitive_element(extension, x=None, **args):
"""Construct a common number field for all extensions. """
if not extension:
raise ValueError("can't compute primitive element for empty extension")
if x is not None:
x, cls = sympify(x), Poly
else:
x, cls = Dummy('x'), PurePoly
if not args.get('ex', False):
extension = [ AlgebraicNumber(ext, gen=x) for ext in extension ]
g, coeffs = extension[0].minpoly.replace(x), [1]
for ext in extension[1:]:
s, _, g = sqf_norm(g, x, extension=ext)
coeffs = [ s*c for c in coeffs ] + [1]
if not args.get('polys', False):
return g.as_expr(), coeffs
else:
return cls(g), coeffs
generator = numbered_symbols('y', cls=Dummy)
F, Y = [], []
for ext in extension:
y = next(generator)
if ext.is_Poly:
if ext.is_univariate:
f = ext.as_expr(y)
else:
raise ValueError("expected minimal polynomial, got %s" % ext)
else:
f = minpoly(ext, y)
F.append(f)
Y.append(y)
coeffs_generator = args.get('coeffs', _coeffs_generator)
for coeffs in coeffs_generator(len(Y)):
f = x - sum([ c*y for c, y in zip(coeffs, Y)])
G = groebner(F + [f], Y + [x], order='lex', field=True)
H, g = G[:-1], cls(G[-1], x, domain='QQ')
for i, (h, y) in enumerate(zip(H, Y)):
try:
H[i] = Poly(y - h, x,
domain='QQ').all_coeffs() # XXX: composite=False
except CoercionFailed: # pragma: no cover
break # G is not a triangular set
else:
break
else: # pragma: no cover
raise RuntimeError("run out of coefficient configurations")
_, g = g.clear_denoms()
if not args.get('polys', False):
return g.as_expr(), coeffs, H
else:
return g, coeffs, H
示例9: _minpoly_groebner
def _minpoly_groebner(ex, x, cls):
"""
Computes the minimal polynomial of an algebraic number
using Groebner bases
Examples
========
>>> from sympy import minimal_polynomial, sqrt, Rational
>>> from sympy.abc import x
>>> minimal_polynomial(sqrt(2) + 3*Rational(1, 3), x, compose=False)
x**2 - 2*x - 1
"""
from sympy.polys.polytools import degree
from sympy.core.function import expand_multinomial
generator = numbered_symbols('a', cls=Dummy)
mapping, symbols, replace = {}, {}, []
def update_mapping(ex, exp, base=None):
a = next(generator)
symbols[ex] = a
if base is not None:
mapping[ex] = a**exp + base
else:
mapping[ex] = exp.as_expr(a)
return a
def bottom_up_scan(ex):
if ex.is_Atom:
if ex is S.ImaginaryUnit:
if ex not in mapping:
return update_mapping(ex, 2, 1)
else:
return symbols[ex]
elif ex.is_Rational:
return ex
elif ex.is_Add:
return Add(*[ bottom_up_scan(g) for g in ex.args ])
elif ex.is_Mul:
return Mul(*[ bottom_up_scan(g) for g in ex.args ])
elif ex.is_Pow:
if ex.exp.is_Rational:
if ex.exp < 0 and ex.base.is_Add:
coeff, terms = ex.base.as_coeff_add()
elt, _ = primitive_element(terms, polys=True)
alg = ex.base - coeff
# XXX: turn this into eval()
inverse = invert(elt.gen + coeff, elt).as_expr()
base = inverse.subs(elt.gen, alg).expand()
if ex.exp == -1:
return bottom_up_scan(base)
else:
ex = base**(-ex.exp)
if not ex.exp.is_Integer:
base, exp = (
ex.base**ex.exp.p).expand(), Rational(1, ex.exp.q)
else:
base, exp = ex.base, ex.exp
base = bottom_up_scan(base)
expr = base**exp
if expr not in mapping:
return update_mapping(expr, 1/exp, -base)
else:
return symbols[expr]
elif ex.is_AlgebraicNumber:
if ex.root not in mapping:
return update_mapping(ex.root, ex.minpoly)
else:
return symbols[ex.root]
raise NotAlgebraic("%s doesn't seem to be an algebraic number" % ex)
def simpler_inverse(ex):
"""
Returns True if it is more likely that the minimal polynomial
algorithm works better with the inverse
"""
if ex.is_Pow:
if (1/ex.exp).is_integer and ex.exp < 0:
if ex.base.is_Add:
return True
if ex.is_Mul:
hit = True
a = []
for p in ex.args:
if p.is_Add:
return False
if p.is_Pow:
if p.base.is_Add and p.exp > 0:
return False
if hit:
#.........这里部分代码省略.........
示例10: minimal_polynomial
def minimal_polynomial(ex, x=None, **args):
"""
Computes the minimal polynomial of an algebraic number.
**Example**
>>> from sympy import minimal_polynomial, sqrt
>>> from sympy.abc import x
>>> minimal_polynomial(sqrt(2), x)
x**2 - 2
>>> minimal_polynomial(sqrt(2) + sqrt(3), x)
x**4 - 10*x**2 + 1
"""
generator = numbered_symbols('a', cls=Dummy)
mapping, symbols, replace = {}, {}, []
ex = sympify(ex)
if x is not None:
x, cls = sympify(x), Poly
else:
x, cls = Dummy('x'), PurePoly
def update_mapping(ex, exp, base=None):
a = generator.next()
symbols[ex] = a
if base is not None:
mapping[ex] = a**exp + base
else:
mapping[ex] = exp.as_expr(a)
return a
def bottom_up_scan(ex):
if ex.is_Atom:
if ex is S.ImaginaryUnit:
if ex not in mapping:
return update_mapping(ex, 2, 1)
else:
return symbols[ex]
elif ex.is_Rational and ex.q != 0:
return ex
elif ex.is_Add:
return Add(*[ bottom_up_scan(g) for g in ex.args ])
elif ex.is_Mul:
return Mul(*[ bottom_up_scan(g) for g in ex.args ])
elif ex.is_Pow:
if ex.exp.is_Rational:
if ex.exp < 0 and ex.base.is_Add:
coeff, terms = ex.base.as_coeff_add()
elt, _ = primitive_element(terms, polys=True)
alg = ex.base - coeff
# XXX: turn this into eval()
inverse = invert(elt.gen + coeff, elt).as_expr()
base = inverse.subs(elt.gen, alg).expand()
if ex.exp == -1:
return bottom_up_scan(base)
else:
ex = base**(-ex.exp)
if not ex.exp.is_Integer:
base, exp = (ex.base**ex.exp.p).expand(), Rational(1, ex.exp.q)
else:
base, exp = ex.base, ex.exp
base = bottom_up_scan(base)
expr = base**exp
if expr not in mapping:
return update_mapping(expr, 1/exp, -base)
else:
return symbols[expr]
elif ex.is_AlgebraicNumber:
if ex.root not in mapping:
return update_mapping(ex.root, ex.minpoly)
else:
return symbols[ex.root]
raise NotAlgebraic("%s doesn't seem to be an algebraic number" % ex)
polys = args.get('polys', False)
if ex.is_AlgebraicNumber:
if not polys:
return ex.minpoly.as_expr(x)
else:
return ex.minpoly.replace(x)
elif ex.is_Rational and ex.q != 0:
result = ex.q*x - ex.p
else:
F = [x - bottom_up_scan(ex)] + mapping.values()
G = groebner(F, symbols.values() + [x], order='lex')
_, factors = factor_list(G[-1])
#.........这里部分代码省略.........
示例11: poly_from_expr
try:
f, opt = poly_from_expr(f, *gens, **args)
except PolificationFailed, exc:
raise ComputationFailed('viete', 1, exc)
if f.is_multivariate:
raise MultivariatePolynomialError("multivariate polynomials are not allowed")
n = f.degree()
if n < 1:
raise ValueError("can't derive Viete's formulas for a constant polynomial")
if roots is None:
roots = numbered_symbols('r', start=1)
roots = take(roots, n)
if n != len(roots):
raise ValueError("required %s roots, got %s" % (n, len(roots)))
lc, coeffs = f.LC(), f.all_coeffs()
result, sign = [], -1
for i, coeff in enumerate(coeffs[1:]):
poly = symmetric_poly(i+1, roots)
coeff = sign*(coeff/lc)
result.append((poly, coeff))
sign = -sign
示例12: minimal_polynomial
def minimal_polynomial(ex, x=None, **args):
"""
Computes the minimal polynomial of an algebraic number.
Parameters
==========
ex : algebraic number expression
x : indipendent variable of the minimal polynomial
Options
=======
compose : if ``True`` _minpoly1`` is used, else the ``groebner`` algorithm
polys : if ``True`` returns a ``Poly`` object
Notes
=====
By default ``compose=True``, the minimal polynomial of the subexpressions of ``ex``
are computed, then the arithmetic operations on them are performed using the resultant
and factorization.
If ``compose=False``, a bottom-up algorithm is used with ``groebner``.
The default algorithm stalls less frequently.
Examples
========
>>> from sympy import minimal_polynomial, sqrt, solve
>>> from sympy.abc import x
>>> minimal_polynomial(sqrt(2), x)
x**2 - 2
>>> minimal_polynomial(sqrt(2) + sqrt(3), x)
x**4 - 10*x**2 + 1
>>> minimal_polynomial(solve(x**3 + x + 3)[0], x)
x**3 + x + 3
"""
from sympy.polys.polytools import degree
from sympy.core.function import expand_multinomial
from sympy.core.basic import preorder_traversal
compose = args.get('compose', True)
polys = args.get('polys', False)
ex = sympify(ex)
for expr in preorder_traversal(ex):
if expr.is_AlgebraicNumber:
compose = False
break
if ex.is_AlgebraicNumber:
compose = False
if x is not None:
x, cls = sympify(x), Poly
else:
x, cls = Dummy('x'), PurePoly
if compose:
result = _minpoly1(ex, x)
result = result.primitive()[1]
c = result.coeff(x**degree(result, x))
if c < 0:
result = expand_mul(-result)
c = -c
return cls(result, x, field=True) if polys else result
generator = numbered_symbols('a', cls=Dummy)
mapping, symbols, replace = {}, {}, []
def update_mapping(ex, exp, base=None):
a = generator.next()
symbols[ex] = a
if base is not None:
mapping[ex] = a**exp + base
else:
mapping[ex] = exp.as_expr(a)
return a
def bottom_up_scan(ex):
if ex.is_Atom:
if ex is S.ImaginaryUnit:
if ex not in mapping:
return update_mapping(ex, 2, 1)
else:
return symbols[ex]
elif ex.is_Rational:
return ex
elif ex.is_Add:
return Add(*[ bottom_up_scan(g) for g in ex.args ])
elif ex.is_Mul:
return Mul(*[ bottom_up_scan(g) for g in ex.args ])
elif ex.is_Pow:
if ex.exp.is_Rational:
if ex.exp < 0 and ex.base.is_Add:
#.........这里部分代码省略.........
示例13: minimal_polynomial
def minimal_polynomial(ex, x=None, **args):
"""
Computes the minimal polynomial of an algebraic number.
Examples
========
>>> from sympy import minimal_polynomial, sqrt
>>> from sympy.abc import x
>>> minimal_polynomial(sqrt(2), x)
x**2 - 2
>>> minimal_polynomial(sqrt(2) + sqrt(3), x)
x**4 - 10*x**2 + 1
"""
from sympy.polys.polytools import degree
from sympy.core.function import expand_mul, expand_multinomial
from sympy.simplify.simplify import _is_sum_surds
generator = numbered_symbols("a", cls=Dummy)
mapping, symbols, replace = {}, {}, []
ex = sympify(ex)
if x is not None:
x, cls = sympify(x), Poly
else:
x, cls = Dummy("x"), PurePoly
def update_mapping(ex, exp, base=None):
a = generator.next()
symbols[ex] = a
if base is not None:
mapping[ex] = a ** exp + base
else:
mapping[ex] = exp.as_expr(a)
return a
def bottom_up_scan(ex):
if ex.is_Atom:
if ex is S.ImaginaryUnit:
if ex not in mapping:
return update_mapping(ex, 2, 1)
else:
return symbols[ex]
elif ex.is_Rational:
return ex
elif ex.is_Add:
return Add(*[bottom_up_scan(g) for g in ex.args])
elif ex.is_Mul:
return Mul(*[bottom_up_scan(g) for g in ex.args])
elif ex.is_Pow:
if ex.exp.is_Rational:
if ex.exp < 0 and ex.base.is_Add:
coeff, terms = ex.base.as_coeff_add()
elt, _ = primitive_element(terms, polys=True)
alg = ex.base - coeff
# XXX: turn this into eval()
inverse = invert(elt.gen + coeff, elt).as_expr()
base = inverse.subs(elt.gen, alg).expand()
if ex.exp == -1:
return bottom_up_scan(base)
else:
ex = base ** (-ex.exp)
if not ex.exp.is_Integer:
base, exp = (ex.base ** ex.exp.p).expand(), Rational(1, ex.exp.q)
else:
base, exp = ex.base, ex.exp
base = bottom_up_scan(base)
expr = base ** exp
if expr not in mapping:
return update_mapping(expr, 1 / exp, -base)
else:
return symbols[expr]
elif ex.is_AlgebraicNumber:
if ex.root not in mapping:
return update_mapping(ex.root, ex.minpoly)
else:
return symbols[ex.root]
raise NotAlgebraic("%s doesn't seem to be an algebraic number" % ex)
def simpler_inverse(ex):
"""
Returns True if it is more likely that the minimal polynomial
algorithm works better with the inverse
"""
if ex.is_Pow:
if (1 / ex.exp).is_integer and ex.exp < 0:
if ex.base.is_Add:
return True
if ex.is_Mul:
hit = True
#.........这里部分代码省略.........