def deltaproduct(f, limit): """ Handle products containing a KroneckerDelta. See Also ======== deltasummation sympy.functions.special.tensor_functions.KroneckerDelta sympy.concrete.products.product """ from sympy.concrete.products import product if ((limit[2] - limit[1]) < 0) == True: return S.One if not f.has(KroneckerDelta): return product(f, limit) if f.is_Add: # Identify the term in the Add that has a simple KroneckerDelta delta = None terms = [] for arg in sorted(f.args, key=default_sort_key): if delta is None and _has_simple_delta(arg, limit[0]): delta = arg else: terms.append(arg) newexpr = f.func(*terms) k = Dummy("kprime", integer=True) if isinstance(limit[1], int) and isinstance(limit[2], int): result = deltaproduct(newexpr, limit) + sum([ deltaproduct(newexpr, (limit[0], limit[1], ik - 1)) * delta.subs(limit[0], ik) * deltaproduct(newexpr, (limit[0], ik + 1, limit[2])) for ik in range(int(limit[1]), int(limit[2] + 1)) ]) else: result = deltaproduct(newexpr, limit) + deltasummation( deltaproduct(newexpr, (limit[0], limit[1], k - 1)) * delta.subs(limit[0], k) * deltaproduct(newexpr, (limit[0], k + 1, limit[2])), (k, limit[1], limit[2]), no_piecewise=_has_simple_delta(newexpr, limit[0])) return _remove_multiple_delta(result) delta, _ = _extract_delta(f, limit[0]) if not delta: g = _expand_delta(f, limit[0]) if f != g: from sympy import factor try: return factor(deltaproduct(g, limit)) except AssertionError: return deltaproduct(g, limit) return product(f, limit) return _remove_multiple_delta(f.subs(limit[0], limit[1])*KroneckerDelta(limit[2], limit[1])) + \ S.One*_simplify_delta(KroneckerDelta(limit[2], limit[1] - 1))
def test_funcmatrix_creation(): i, j, k = symbols('i j k') assert FunctionMatrix(2, 2, Lambda((i, j), 0)) assert FunctionMatrix(0, 0, Lambda((i, j), 0)) raises(ValueError, lambda: FunctionMatrix(-1, 0, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(2.0, 0, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(2j, 0, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(0, -1, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(0, 2.0, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(0, 2j, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(2, 2, Lambda(i, 0))) raises(ValueError, lambda: FunctionMatrix(2, 2, lambda i, j: 0)) raises(ValueError, lambda: FunctionMatrix(2, 2, Lambda((i,), 0))) raises(ValueError, lambda: FunctionMatrix(2, 2, Lambda((i, j, k), 0))) raises(ValueError, lambda: FunctionMatrix(2, 2, i+j)) assert FunctionMatrix(2, 2, "lambda i, j: 0") == \ FunctionMatrix(2, 2, Lambda((i, j), 0)) m = FunctionMatrix(2, 2, KroneckerDelta) assert m.as_explicit() == Identity(2).as_explicit() assert m.args[2] == Lambda((i, j), KroneckerDelta(i, j)) n = symbols('n') assert FunctionMatrix(n, n, Lambda((i, j), 0)) n = symbols('n', integer=False) raises(ValueError, lambda: FunctionMatrix(n, n, Lambda((i, j), 0))) n = symbols('n', negative=True) raises(ValueError, lambda: FunctionMatrix(n, n, Lambda((i, j), 0)))
def _remove_multiple_delta(expr): """ Evaluate products of KroneckerDelta's. """ from sympy.solvers import solve if expr.is_Add: return expr.func(*list(map(_remove_multiple_delta, expr.args))) if not expr.is_Mul: return expr eqs = [] newargs = [] for arg in expr.args: if isinstance(arg, KroneckerDelta): eqs.append(arg.args[0] - arg.args[1]) else: newargs.append(arg) if not eqs: return expr solns = solve(eqs, dict=True) if len(solns) == 0: return S.Zero elif len(solns) == 1: for key in solns[0].keys(): newargs.append(KroneckerDelta(key, solns[0][key])) expr2 = expr.func(*newargs) if expr != expr2: return _remove_multiple_delta(expr2) return expr
def test_PythonCodePrinter(): prntr = PythonCodePrinter() assert not prntr.module_imports assert prntr.doprint(x**y) == 'x**y' assert prntr.doprint(Mod(x, 2)) == 'x % 2' assert prntr.doprint(And(x, y)) == 'x and y' assert prntr.doprint(Or(x, y)) == 'x or y' assert not prntr.module_imports assert prntr.doprint(pi) == 'math.pi' assert prntr.module_imports == {'math': {'pi'}} assert prntr.doprint(x**Rational(1, 2)) == 'math.sqrt(x)' assert prntr.doprint(sqrt(x)) == 'math.sqrt(x)' assert prntr.module_imports == {'math': {'pi', 'sqrt'}} assert prntr.doprint(acos(x)) == 'math.acos(x)' assert prntr.doprint(Assignment(x, 2)) == 'x = 2' assert prntr.doprint(Piecewise( (1, Eq(x, 0)), (2, x > 6))) == '((1) if (x == 0) else (2) if (x > 6) else None)' assert prntr.doprint(Piecewise((2, Le(x, 0)), (3, Gt(x, 0)), evaluate=False)) == '((2) if (x <= 0) else'\ ' (3) if (x > 0) else None)' assert prntr.doprint(sign(x)) == '(0.0 if x == 0 else math.copysign(1, x))' assert prntr.doprint(p[0, 1]) == 'p[0, 1]' assert prntr.doprint(KroneckerDelta(x, y)) == '(1 if x == y else 0)'
def test_funcmatrix_creation(): i, j, k = symbols('i j k') assert FunctionMatrix(2, 2, Lambda((i, j), 0)) assert FunctionMatrix(0, 0, Lambda((i, j), 0)) raises(ValueError, lambda: FunctionMatrix(-1, 0, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(2.0, 0, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(2j, 0, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(0, -1, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(0, 2.0, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(0, 2j, Lambda((i, j), 0))) raises(ValueError, lambda: FunctionMatrix(2, 2, Lambda(i, 0))) with warns(SymPyDeprecationWarning, test_stacklevel=False): # This raises a deprecation warning from sympify() raises(ValueError, lambda: FunctionMatrix(2, 2, lambda i, j: 0)) raises(ValueError, lambda: FunctionMatrix(2, 2, Lambda((i,), 0))) raises(ValueError, lambda: FunctionMatrix(2, 2, Lambda((i, j, k), 0))) raises(ValueError, lambda: FunctionMatrix(2, 2, i+j)) assert FunctionMatrix(2, 2, "lambda i, j: 0") == \ FunctionMatrix(2, 2, Lambda((i, j), 0)) m = FunctionMatrix(2, 2, KroneckerDelta) assert m.as_explicit() == Identity(2).as_explicit() assert m.args[2].dummy_eq(Lambda((i, j), KroneckerDelta(i, j))) n = symbols('n') assert FunctionMatrix(n, n, Lambda((i, j), 0)) n = symbols('n', integer=False) raises(ValueError, lambda: FunctionMatrix(n, n, Lambda((i, j), 0))) n = symbols('n', negative=True) raises(ValueError, lambda: FunctionMatrix(n, n, Lambda((i, j), 0)))
def _simplify_delta(expr): """ Rewrite a KroneckerDelta's indices in its simplest form. """ from sympy.solvers import solve if isinstance(expr, KroneckerDelta): try: slns = solve(expr.args[0] - expr.args[1], dict=True) if slns and len(slns) == 1: return Mul(*[KroneckerDelta(*(key, value)) for key, value in slns[0].items()]) except NotImplementedError: pass return expr
def test_KroneckerDelta(): from sympy.functions import KroneckerDelta assert mcode(KroneckerDelta(x, y)) == "double(x == y)" assert mcode(KroneckerDelta(x, y + 1)) == "double(x == (y + 1))" assert mcode(KroneckerDelta(2**x, y)) == "double((2.^x) == y)"
def test_latex_KroneckerDelta(): assert latex(KroneckerDelta(x, y)) == r"\delta_{x y}" assert latex(KroneckerDelta(x, y)**2) == r"\left(\delta_{x y}\right)^{2}" assert latex(KroneckerDelta(x, y + 1)) == r"\delta_{x, y + 1}" # issue 3479 assert latex(KroneckerDelta(x + 1, y)) == r"\delta_{y, x + 1}"
def _entry(self, i, j, **kwargs): perm = self.args[0] return KroneckerDelta(perm.apply(i), j)
def test_latex_KroneckerDelta(): assert latex(KroneckerDelta(x, y)) == r"\delta_{x y}" assert latex(KroneckerDelta(x, y + 1)) == r"\delta_{x, y + 1}" # issue 3479 assert latex(KroneckerDelta(x + 1, y)) == r"\delta_{y, x + 1}"