def eval(cls, arg):
from sympy import exp_polar, pi, I, arg as argument
if arg.is_number:
ar = argument(arg)
#if not ar.has(argument) and not ar.has(atan):
if ar in (0, pi/2, -pi/2, pi):
return exp_polar(I*ar)*abs(arg)
if arg.is_Mul:
args = arg.args
else:
args = [arg]
included = []
excluded = []
positive = []
for arg in args:
if arg.is_polar:
included += [arg]
elif arg.is_positive:
positive += [arg]
else:
excluded += [arg]
if len(excluded) < len(args):
if excluded:
return Mul(*(included + positive))*polar_lift(Mul(*excluded))
elif included:
return Mul(*(included + positive))
else:
return Mul(*positive)*exp_polar(0)
python类Mul()的实例源码
def test_inflate():
subs = {a: randcplx()/10, b: randcplx()/10 + I, c: randcplx(),
d: randcplx(), y: randcplx()/10}
def t(a, b, arg, n):
from sympy import Mul
m1 = meijerg(a, b, arg)
m2 = Mul(*_inflate_g(m1, n))
# NOTE: (the random number)**9 must still be on the principal sheet.
# Thus make b&d small to create random numbers of small imaginary part.
return test_numerically(m1.subs(subs), m2.subs(subs), x, b=0.1, d=-0.1)
assert t([[a], [b]], [[c], [d]], x, 3)
assert t([[a, y], [b]], [[c], [d]], x, 3)
assert t([[a], [b]], [[c, y], [d]], 2*x**3, 3)
def manual_diff(f, symbol):
"""Derivative of f in form expected by find_substitutions
SymPy's derivatives for some trig functions (like cot) aren't in a form
that works well with finding substitutions; this replaces the
derivatives for those particular forms with something that works better.
"""
if f.args:
arg = f.args[0]
if isinstance(f, sympy.tan):
return arg.diff(symbol) * sympy.sec(arg)**2
elif isinstance(f, sympy.cot):
return -arg.diff(symbol) * sympy.csc(arg)**2
elif isinstance(f, sympy.sec):
return arg.diff(symbol) * sympy.sec(arg) * sympy.tan(arg)
elif isinstance(f, sympy.csc):
return -arg.diff(symbol) * sympy.csc(arg) * sympy.cot(arg)
elif isinstance(f, sympy.Add):
return sum([manual_diff(arg, symbol) for arg in f.args])
elif isinstance(f, sympy.Mul):
if len(f.args) == 2 and isinstance(f.args[0], sympy.Number):
return f.args[0] * manual_diff(f.args[1], symbol)
return f.diff(symbol)
# Method based on that on SIN, described in "Symbolic Integration: The
# Stormy Decade"
def test_distribute_add_mul():
from sympy import Add, Mul, symbols
x, y = symbols('x, y')
expr = Mul(2, Add(x, y), evaluate=False)
expected = Add(Mul(2, x), Mul(2, y))
distribute_mul = distribute(Mul, Add)
assert distribute_mul(expr) == expected
def main():
x = Pow(2, 50, evaluate=False)
y = Pow(10, -50, evaluate=False)
# A large, unevaluated expression
m = Mul(x, y, evaluate=False)
# Evaluating the expression
e = S(2)**50/S(10)**50
print("%s == %s" % (m, e))
def expr(self):
"""
Process the term, by returning a sympy expression
"""
if DEBUG:
print("> Term ")
ret = self.op[0].expr
for operation, operand in zip(self.op[1::2], self.op[2::2]):
if operation == '*':
ret = Mul(ret, operand.expr)
else:
a = Pow(operand.expr, -1)
ret = Mul(ret, a)
return ret
def p_additiveExpr_impl(self, p):
'''additiveExpr : additiveExpr '+' multiplicitiveExpr
| additiveExpr '-' multiplicitiveExpr
'''
lhs = p[1]
rhs = p[3]
if p[2] == '-':
rhs = AST(sympy.Mul(sympy.Integer(-1),rhs.sympy), rhs.astUnit)
p[0] = AST(sympy.Add(lhs.sympy,rhs.sympy), self.checkExactUnits(lhs.astUnit,rhs.astUnit))
def p_multiplicitiveExpr_impl(self, p):
'''multiplicitiveExpr : multiplicitiveExpr '*' unaryExpr
| multiplicitiveExpr '/' unaryExpr
'''
lhs = p[1]
rhs = p[3]
if p[2] == '/':
rhs = AST(sympy.Pow(rhs.sympy,sympy.Integer(-1)), rhs.astUnit ** -1)
ret = AST(sympy.Mul(lhs.sympy,rhs.sympy), lhs.astUnit*rhs.astUnit)
p[0] = ret
def p_unaryExpr_uminus(self, p):
'''unaryExpr : '-' unaryExpr'''
p[0] = AST(sympy.Mul(sympy.Integer(-1),p[2].sympy), p[2].astUnit)
def cv_equations(control_volume_dimensions, info_dict):
key_list = control_volume_dimensions[0].keys()
equation_dict = {}
variable_list = []
compatibility = 0
for key in key_list:
balance_eq = 0
if key != 'Direction':
for path in control_volume_dimensions:
if key == 'Total':
balance_eq = sp.Add(balance_eq, sp.Mul(path['Direction'], path[key]))
else:
if path[key] != 0:
balance_eq = sp.Add(balance_eq, sp.Mul(path['Direction'], sp.Mul(path['Total'], path[key])))
equation_dict[key] = balance_eq
for key_eq, eq in equation_dict.items():
variable_count = eq.atoms(sp.Symbol)
for var in variable_count:
if var not in variable_list:
variable_list.append(var)
for info_number, info_equation in info_dict.items():
info_equation_variables = info_equation.atoms(sp.Symbol)
for variable in info_equation_variables:
if variable in variable_list:
compatibility += 1
if compatibility == len(info_equation_variables):
equation_dict[info_number] = info_equation
compatibility = 0
return equation_dict
def doit(self, **hints):
arg = self.args[0]
condition = self._condition
if not arg.has(RandomSymbol):
return S.Zero
if isinstance(arg, RandomSymbol):
return self
elif isinstance(arg, Add):
rv = []
for a in arg.args:
if a.has(RandomSymbol):
rv.append(a)
variances = Add(*map(lambda xv: Variance(xv, condition).doit(), rv))
map_to_covar = lambda x: 2*Covariance(*x, condition=condition).doit()
covariances = Add(*map(map_to_covar, itertools.combinations(rv, 2)))
return variances + covariances
elif isinstance(arg, Mul):
nonrv = []
rv = []
for a in arg.args:
if a.has(RandomSymbol):
rv.append(a)
else:
nonrv.append(a**2)
if len(rv) == 0:
return S.Zero
return Mul(*nonrv)*Variance(Mul(*rv), condition)
# this expression contains a RandomSymbol somehow:
return self
def _get_mul_nonrv_rv_tuple(cls, m):
rv = []
nonrv = []
for a in m.args:
if a.has(RandomSymbol):
rv.append(a)
else:
nonrv.append(a)
return (Mul(*nonrv), Mul(*rv))
def _eval_expand_power_exp(self, **hints):
"""a**(n+m) -> a**n*a**m"""
b = self.base
e = self.exp
if e.is_Add and e.is_commutative:
expr = []
for x in e.args:
expr.append(self.func(self.base, x))
return Mul(*expr)
return self.func(b, e)
def _rearrange_args(l):
""" this just moves the last arg to first position
to enable expansion of args
A,B,A ==> A**2,B
"""
if len(l) == 1:
return l
x = list(l[-1:])
x.extend(l[0:-1])
return Mul(*x).args
def permute(self, pos):
""" Permute the arguments cyclically.
Parameters
==========
pos : integer, if positive, shift-right, else shift-left
Examples
========
>>> from sympy.core.trace import Tr
>>> from sympy import symbols
>>> A, B, C, D = symbols('A B C D', commutative=False)
>>> t = Tr(A*B*C*D)
>>> t.permute(2)
Tr(C*D*A*B)
>>> t.permute(-2)
Tr(C*D*A*B)
"""
if pos > 0:
pos = pos % len(self.args[0].args)
else:
pos = -(abs(pos) % len(self.args[0].args))
args = list(self.args[0].args[-pos:] + self.args[0].args[0:-pos])
return Tr(Mul(*(args)))
def _hashable_content(self):
if isinstance(self.args[0], Mul):
args = _cycle_permute(_rearrange_args(self.args[0].args))
else:
args = [self.args[0]]
return tuple(args) + (self.args[1], )
def test_dim_simplify_rec():
assert dim_simplify(Mul(Add(L, L), T)) == L*T
assert dim_simplify((L + L) * T) == L*T
def get_dimensional_expr(expr):
if isinstance(expr, Mul):
return Mul(*[Quantity.get_dimensional_expr(i) for i in expr.args])
elif isinstance(expr, Pow):
return Quantity.get_dimensional_expr(expr.base) ** expr.exp
elif isinstance(expr, Add):
# return get_dimensional_expr()
raise NotImplementedError
elif isinstance(expr, Quantity):
return expr.dimension.name
return 1
def dim_simplify(expr):
"""
NOTE: this function could be deprecated in the future.
Simplify expression by recursively evaluating the dimension arguments.
This function proceeds to a very rough dimensional analysis. It tries to
simplify expression with dimensions, and it deletes all what multiplies a
dimension without being a dimension. This is necessary to avoid strange
behavior when Add(L, L) be transformed into Mul(2, L).
"""
if isinstance(expr, Dimension):
return expr
if isinstance(expr, Pow):
return dim_simplify(expr.base)**dim_simplify(expr.exp)
elif isinstance(expr, Function):
return dim_simplify(expr.args[0])
elif isinstance(expr, Add):
if (all(isinstance(arg, Dimension) for arg in expr.args) or
all(arg.is_dimensionless for arg in expr.args if isinstance(arg, Dimension))):
return reduce(lambda x, y: x.add(y), expr.args)
else:
raise ValueError("Dimensions cannot be added: %s" % expr)
elif isinstance(expr, Mul):
return Dimension(Mul(*[dim_simplify(i).name for i in expr.args if isinstance(i, Dimension)]))
raise ValueError("Cannot be simplifed: %s", expr)
def qubit_to_matrix(qubit, format='sympy'):
"""Converts an Add/Mul of Qubit objects into it's matrix representation
This function is the inverse of ``matrix_to_qubit`` and is a shorthand
for ``represent(qubit)``.
"""
return represent(qubit, format=format)
#-----------------------------------------------------------------------------
# Measurement
#-----------------------------------------------------------------------------