def refine_MatMul(expr, assumptions): """ >>> from sympy import MatrixSymbol, Q, assuming, refine >>> X = MatrixSymbol('X', 2, 2) >>> expr = X * X.T >>> print(expr) X*X.T >>> with assuming(Q.orthogonal(X)): ... print(refine(expr)) I """ newargs = [] exprargs = [] for args in expr.args: if args.is_Matrix: exprargs.append(args) else: newargs.append(args) last = exprargs[0] for arg in exprargs[1:]: if arg == last.T and ask(Q.orthogonal(arg), assumptions): last = Identity(arg.shape[0]) elif arg == last.conjugate() and ask(Q.unitary(arg), assumptions): last = Identity(arg.shape[0]) else: newargs.append(last) last = arg newargs.append(last) return MatMul(*newargs)
def test_is_literal(): assert is_literal(True) is True assert is_literal(False) is True assert is_literal(A) is True assert is_literal(~A) is True assert is_literal(Or(A, B)) is False assert is_literal(Q.zero(A)) is True assert is_literal(Not(Q.zero(A))) is True assert is_literal(Or(A, B)) is False assert is_literal(And(Q.zero(A), Q.zero(B))) is False
def test_global(): """Test for global assumptions""" global_assumptions.add(Q.is_true(x > 0)) assert Q.is_true(x > 0) in global_assumptions global_assumptions.remove(Q.is_true(x > 0)) assert not Q.is_true(x > 0) in global_assumptions # same with multiple of assumptions global_assumptions.add(Q.is_true(x > 0), Q.is_true(y > 0)) assert Q.is_true(x > 0) in global_assumptions assert Q.is_true(y > 0) in global_assumptions global_assumptions.clear() assert not Q.is_true(x > 0) in global_assumptions assert not Q.is_true(y > 0) in global_assumptions
def test_binary_symbols(): assert ITE(x < 1, y, z).binary_symbols == set((y, z)) for f in (Eq, Ne): assert f(x, 1).binary_symbols == set() assert f(x, True).binary_symbols == set([x]) assert f(x, False).binary_symbols == set([x]) assert S.true.binary_symbols == set() assert S.false.binary_symbols == set() assert x.binary_symbols == set([x]) assert And(x, Eq(y, False), Eq(z, 1)).binary_symbols == set([x, y]) assert Q.prime(x).binary_symbols == set() assert Q.is_true(x < 1).binary_symbols == set() assert Q.is_true(x).binary_symbols == set([x]) assert Q.is_true(Eq(x, True)).binary_symbols == set([x]) assert Q.prime(x).binary_symbols == set()
def test_binary_symbols(): assert ITE(x < 1, y, z).binary_symbols == {y, z} for f in (Eq, Ne): assert f(x, 1).binary_symbols == set() assert f(x, True).binary_symbols == {x} assert f(x, False).binary_symbols == {x} assert S.true.binary_symbols == set() assert S.false.binary_symbols == set() assert x.binary_symbols == {x} assert And(x, Eq(y, False), Eq(z, 1)).binary_symbols == {x, y} assert Q.prime(x).binary_symbols == set() assert Q.lt(x, 1).binary_symbols == set() assert Q.is_true(x).binary_symbols == {x} assert Q.eq(x, True).binary_symbols == {x} assert Q.prime(x).binary_symbols == set()
def test_dft(): n, i, j = symbols('n i j') assert DFT(4).shape == (4, 4) assert ask(Q.unitary(DFT(4))) assert Abs(simplify(det(Matrix(DFT(4))))) == 1 assert DFT(n) * IDFT(n) == Identity(n) assert DFT(n)[i, j] == exp(-2 * S.Pi * I / n)**(i * j) / sqrt(n)
def test_is_infinite(): x = Symbol('x', infinite=True) y = Symbol('y', infinite=False) z = Symbol('z') assert is_infinite(x) assert not is_infinite(y) assert is_infinite(z) is None assert is_infinite(z, Q.infinite(z))
def test_is_extended_real(): x = Symbol('x', extended_real=True) y = Symbol('y', extended_real=False) z = Symbol('z') assert is_extended_real(x) assert not is_extended_real(y) assert is_extended_real(z) is None assert is_extended_real(z, Q.extended_real(z))
def test_refine(): # relational assert not refine(x < 0, ~(x < 0)) assert refine(x < 0, (x < 0)) assert refine(x < 0, (0 > x)) is S.true assert refine(x < 0, (y < 0)) == (x < 0) assert not refine(x <= 0, ~(x <= 0)) assert refine(x <= 0, (x <= 0)) assert refine(x <= 0, (0 >= x)) is S.true assert refine(x <= 0, (y <= 0)) == (x <= 0) assert not refine(x > 0, ~(x > 0)) assert refine(x > 0, (x > 0)) assert refine(x > 0, (0 < x)) is S.true assert refine(x > 0, (y > 0)) == (x > 0) assert not refine(x >= 0, ~(x >= 0)) assert refine(x >= 0, (x >= 0)) assert refine(x >= 0, (0 <= x)) is S.true assert refine(x >= 0, (y >= 0)) == (x >= 0) assert not refine(Eq(x, 0), ~(Eq(x, 0))) assert refine(Eq(x, 0), (Eq(x, 0))) assert refine(Eq(x, 0), (Eq(0, x))) is S.true assert refine(Eq(x, 0), (Eq(y, 0))) == Eq(x, 0) assert not refine(Ne(x, 0), ~(Ne(x, 0))) assert refine(Ne(x, 0), (Ne(0, x))) is S.true assert refine(Ne(x, 0), (Ne(x, 0))) assert refine(Ne(x, 0), (Ne(y, 0))) == (Ne(x, 0)) # boolean functions assert refine(And(x > 0, y > 0), (x > 0)) == (y > 0) assert refine(And(x > 0, y > 0), (x > 0) & (y > 0)) is S.true # predicates assert refine(Q.positive(x), Q.positive(x)) is S.true assert refine(Q.positive(x), Q.negative(x)) is S.false assert refine(Q.positive(x), Q.real(x)) == Q.positive(x)
def refine_Inverse(expr, assumptions): """ >>> from sympy import MatrixSymbol, Q, assuming, refine >>> X = MatrixSymbol('X', 2, 2) >>> X.I X^-1 >>> with assuming(Q.orthogonal(X)): ... print(refine(X.I)) X.T """ if ask(Q.orthogonal(expr), assumptions): return expr.arg.T elif ask(Q.unitary(expr), assumptions): return expr.arg.conjugate() elif ask(Q.singular(expr), assumptions): raise ValueError("Inverse of singular matrix %s" % expr.arg) return expr
def refine_Determinant(expr, assumptions): """ >>> from sympy import MatrixSymbol, Q, assuming, refine, det >>> X = MatrixSymbol('X', 2, 2) >>> det(X) Determinant(X) >>> with assuming(Q.orthogonal(X)): ... print(refine(det(X))) 1 """ if ask(Q.orthogonal(expr.arg), assumptions): return S.One elif ask(Q.singular(expr.arg), assumptions): return S.Zero elif ask(Q.unit_triangular(expr.arg), assumptions): return S.One return expr
def refine_Inverse(expr, assumptions): """ >>> from sympy import MatrixSymbol, Q, assuming, refine >>> X = MatrixSymbol('X', 2, 2) >>> X.I X**(-1) >>> with assuming(Q.orthogonal(X)): ... print(refine(X.I)) X.T """ if ask(Q.orthogonal(expr), assumptions): return expr.arg.T elif ask(Q.unitary(expr), assumptions): return expr.arg.conjugate() elif ask(Q.singular(expr), assumptions): raise ValueError("Inverse of singular matrix %s" % expr.arg) return expr
def _eval_power(self, exp): # exp = -1, 0, 1 are already handled at this stage if self._is_1x1() == True: return Identity(1) if (exp < 0) == True: raise NonInvertibleMatrixError("Matrix det == 0; not invertible") if ask(Q.integer(exp)): return self.shape[0]**(exp - 1) * OneMatrix(*self.shape) return super(OneMatrix, self)._eval_power(exp)
def test_BlockMatrix_Determinant(): A, B, C, D = [MatrixSymbol(s, 3, 3) for s in 'ABCD'] X = BlockMatrix([[A, B], [C, D]]) from sympy.assumptions.ask import Q from sympy.assumptions.assume import assuming with assuming(Q.invertible(A)): assert det(X) == det(A) * det(X.schur('A')) assert isinstance(det(X), Expr) assert det(BlockMatrix([A])) == det(A) assert det(BlockMatrix([ZeroMatrix(n, n)])) == 0
def test_call(): x, y = symbols('x y') # See the long history of this in issues 5026 and 5105. raises(TypeError, lambda: sin(x)({x: 1, sin(x): 2})) raises(TypeError, lambda: sin(x)(1)) # No effect as there are no callables assert sin(x).rcall(1) == sin(x) assert (1 + sin(x)).rcall(1) == 1 + sin(x) # Effect in the pressence of callables l = Lambda(x, 2 * x) assert (l + x).rcall(y) == 2 * y + x assert (x**l).rcall(2) == x**4 # TODO UndefinedFunction does not subclass Expr #f = Function('f') #assert (2*f)(x) == 2*f(x) assert (Q.real & Q.positive).rcall(x) == Q.real(x) & Q.positive(x)
def test_invertible_BlockMatrix(): assert ask(Q.invertible(BlockMatrix([Identity(3)]))) == True assert ask(Q.invertible(BlockMatrix([ZeroMatrix(3, 3)]))) == False X = Matrix([[1, 2, 3], [3, 5, 4]]) Y = Matrix([[4, 2, 7], [2, 3, 5]]) # non-invertible A block assert ask( Q.invertible( BlockMatrix([ [Matrix.ones(3, 3), Y.T], [X, Matrix.eye(2)], ]))) == True # non-invertible B block assert ask( Q.invertible( BlockMatrix([ [Y.T, Matrix.ones(3, 3)], [Matrix.eye(2), X], ]))) == True # non-invertible C block assert ask( Q.invertible( BlockMatrix([ [X, Matrix.eye(2)], [Matrix.ones(3, 3), Y.T], ]))) == True # non-invertible D block assert ask( Q.invertible( BlockMatrix([ [Matrix.eye(2), X], [Y.T, Matrix.ones(3, 3)], ]))) == True
def test_is_ge_le(): # test assumptions assert is_ge(x, S(0), Q.nonnegative(x)) is True assert is_ge(x, S(0), Q.negative(x)) is False # test registration class PowTest(Expr): def __new__(cls, base, exp): return Basic.__new__(cls, _sympify(base), _sympify(exp)) @dispatch(PowTest, PowTest) def _eval_is_ge(lhs, rhs): if type(lhs) == PowTest and type(rhs) == PowTest: return fuzzy_and([ is_ge(lhs.args[0], rhs.args[0]), is_ge(lhs.args[1], rhs.args[1]) ]) assert is_ge(PowTest(3, 9), PowTest(3, 2)) assert is_gt(PowTest(3, 9), PowTest(3, 2)) assert is_le(PowTest(3, 2), PowTest(3, 9)) assert is_lt(PowTest(3, 2), PowTest(3, 9))
def refine_Transpose(expr, assumptions): """ >>> from sympy import MatrixSymbol, Q, assuming, refine >>> X = MatrixSymbol('X', 2, 2) >>> X.T X.T >>> with assuming(Q.symmetric(X)): ... print(refine(X.T)) X """ if ask(Q.symmetric(expr), assumptions): return expr.arg return expr
def refine_MatMul(expr, assumptions): """ >>> from sympy import MatrixSymbol, Q, assuming, refine >>> X = MatrixSymbol('X', 2, 2) >>> expr = X * X.T >>> print(expr) X*X' >>> with assuming(Q.orthogonal(X)): ... print(refine(expr)) I """ newargs = [] last = expr.args[0] for arg in expr.args[1:]: if arg == last.T and ask(Q.orthogonal(arg), assumptions): last = Identity(arg.shape[0]) elif arg == last.conjugate() and ask(Q.unitary(arg), assumptions): last = Identity(arg.shape[0]) else: newargs.append(last) last = arg newargs.append(last) return MatMul(*newargs)
def _contains(self, other): from sympy.assumptions.ask import ask, Q if ask(Q.real(other)) is False: return False if self.left_open: expr = other > self.start else: expr = other >= self.start if self.right_open: expr = And(expr, other < self.end) else: expr = And(expr, other <= self.end) return expr
def test_sign(): x = Symbol('x', real = True) assert refine(sign(x), Q.positive(x)) == 1 assert refine(sign(x), Q.negative(x)) == -1 assert refine(sign(x), Q.zero(x)) == 0 assert refine(sign(x), True) == sign(x) assert refine(sign(Abs(x)), Q.nonzero(x)) == 1 x = Symbol('x', imaginary=True) assert refine(sign(x), Q.positive(im(x))) == S.ImaginaryUnit assert refine(sign(x), Q.negative(im(x))) == -S.ImaginaryUnit assert refine(sign(x), True) == sign(x) x = Symbol('x', complex=True) assert refine(sign(x), Q.zero(x)) == 0
def test_pretty(): assert pretty(Q.positive(x)) == "Q.positive(x)"
def test_equal(): """Test for equality""" x = symbols('x') assert Q.positive(x) == Q.positive(x) assert Q.positive(x) != ~Q.positive(x) assert ~Q.positive(x) == ~Q.positive(x)
def test_pretty(): x = symbols('x') assert pretty(Q.positive(x)) == "Q.positive(x)"
def _contains(self, other): from sympy.assumptions.ask import ask, Q return (other >= self.inf and other <= self.sup and ask(Q.integer((self.start - other)/self.step)))
def _contains(self, other): from sympy.assumptions.ask import ask, Q if ask(Q.negative(other)) == False and ask(Q.integer(other)): return True return False
def test_equal(): """Test for equality""" assert Q.positive(x) == Q.positive(x) assert Q.positive(x) != ~Q.positive(x) assert ~Q.positive(x) == ~Q.positive(x)
def register_fact(klass, fact, registry=fact_registry): registry[klass] |= set([fact]) for klass, fact in [ (Mul, Equivalent(Q.zero, AnyArgs(Q.zero))), (MatMul, Implies(AllArgs(Q.square), Equivalent(Q.invertible, AllArgs(Q.invertible)))), (Add, Implies(AllArgs(Q.positive), Q.positive)), (Add, Implies(AllArgs(Q.negative), Q.negative)), (Mul, Implies(AllArgs(Q.positive), Q.positive)), (Mul, Implies(AllArgs(Q.commutative), Q.commutative)), (Mul, Implies(AllArgs(Q.real), Q.commutative)), # This one can still be made easier to read. I think we need basic pattern # matching, so that we can just write Equivalent(Q.zero(x**y), Q.zero(x) & Q.positive(y)) (Pow, CustomLambda(lambda power: Equivalent(Q.zero(power), Q.zero(power.base) & Q.positive(power.exp)))), (Integer, CheckIsPrime(Q.prime)), # Implicitly assumes Mul has more than one arg # Would be AllArgs(Q.prime | Q.composite) except 1 is composite (Mul, Implies(AllArgs(Q.prime), ~Q.prime)), # More advanced prime assumptions will require inequalities, as 1 provides # a corner case. (Mul, Implies(AllArgs(Q.imaginary | Q.real), Implies(ExactlyOneArg(Q.imaginary), Q.imaginary))), (Mul, Implies(AllArgs(Q.real), Q.real)), (Add, Implies(AllArgs(Q.real), Q.real)), #General Case: Odd number of imaginary args implies mul is imaginary(To be implemented) (Mul, Implies(AllArgs(Q.real), Implies(ExactlyOneArg(Q.irrational), Q.irrational))), (Add, Implies(AllArgs(Q.real), Implies(ExactlyOneArg(Q.irrational), Q.irrational))), (Mul, Implies(AllArgs(Q.rational), Q.rational)),
def test_AppliedPredicate(): sT(Q.even(Symbol('z')), "AppliedPredicate(Q.even, Symbol('z'))")
def test_pretty(): assert pretty(Q.positive(x)) == "Q.positive(x)" assert pretty(set([Q.positive, Q.integer])) == "set([Q.integer, Q.positive])"
def test_arg(): x = Symbol('x', complex = True) assert refine(arg(x), Q.positive(x)) == 0 assert refine(arg(x), Q.negative(x)) == pi
def test_pow1(): assert refine((-1)**x, Q.even(x)) == 1 assert refine((-1)**x, Q.odd(x)) == -1 assert refine((-2)**x, Q.even(x)) == 2**x # nested powers assert refine(sqrt(x**2)) != Abs(x) assert refine(sqrt(x**2), Q.complex(x)) != Abs(x) assert refine(sqrt(x**2), Q.real(x)) == Abs(x) assert refine(sqrt(x**2), Q.positive(x)) == x assert refine((x**3)**Rational(1, 3)) != x assert refine((x**3)**Rational(1, 3), Q.real(x)) != x assert refine((x**3)**Rational(1, 3), Q.positive(x)) == x assert refine(sqrt(1/x), Q.real(x)) != 1/sqrt(x) assert refine(sqrt(1/x), Q.positive(x)) == 1/sqrt(x) # powers of (-1) assert refine((-1)**(x + y), Q.even(x)) == (-1)**y assert refine((-1)**(x + y + z), Q.odd(x) & Q.odd(z)) == (-1)**y assert refine((-1)**(x + y + 1), Q.odd(x)) == (-1)**y assert refine((-1)**(x + y + 2), Q.odd(x)) == (-1)**(y + 1) assert refine((-1)**(x + 3)) == (-1)**(x + 1) # continuation assert refine((-1)**((-1)**x/2 - S.Half), Q.integer(x)) == (-1)**x assert refine((-1)**((-1)**x/2 + S.Half), Q.integer(x)) == (-1)**(x + 1) assert refine((-1)**((-1)**x/2 + 5*S.Half), Q.integer(x)) == (-1)**(x + 1)
def _contains(self, other): if ask(Q.negative(other)) == False and ask(Q.integer(other)): return True return False
def test_composite_predicates(): pred = Q.integer | ~Q.positive assert type(pred(x)) is Or assert pred(x) == Q.integer(x) | ~Q.positive(x)
def _contains(self, other): return (other >= self.inf and other <= self.sup and ask(Q.integer((self.start - other)/self.step)))
def register_fact(klass, fact, registry=fact_registry): registry[klass] |= {fact} for klass, fact in [ (Mul, Equivalent(Q.zero, AnyArgs(Q.zero))), (MatMul, Implies(AllArgs(Q.square), Equivalent(Q.invertible, AllArgs(Q.invertible)))), (Add, Implies(AllArgs(Q.positive), Q.positive)), (Add, Implies(AllArgs(Q.negative), Q.negative)), (Mul, Implies(AllArgs(Q.positive), Q.positive)), (Mul, Implies(AllArgs(Q.commutative), Q.commutative)), (Mul, Implies(AllArgs(Q.real), Q.commutative)), (Pow, CustomLambda(lambda power: Implies(Q.real(power.base) & Q.even(power.exp) & Q.nonnegative(power.exp), Q.nonnegative(power)))), (Pow, CustomLambda(lambda power: Implies(Q.nonnegative(power.base) & Q.odd(power.exp) & Q.nonnegative(power.exp), Q.nonnegative(power)))), (Pow, CustomLambda(lambda power: Implies(Q.nonpositive(power.base) & Q.odd(power.exp) & Q.nonnegative(power.exp), Q.nonpositive(power)))), # This one can still be made easier to read. I think we need basic pattern # matching, so that we can just write Equivalent(Q.zero(x**y), Q.zero(x) & Q.positive(y)) (Pow, CustomLambda(lambda power: Equivalent(Q.zero(power), Q.zero(power.base) & Q.positive(power.exp)))), (Integer, CheckIsPrime(Q.prime)), # Implicitly assumes Mul has more than one arg # Would be AllArgs(Q.prime | Q.composite) except 1 is composite (Mul, Implies(AllArgs(Q.prime), ~Q.prime)), # More advanced prime assumptions will require inequalities, as 1 provides # a corner case. (Mul, Implies(AllArgs(Q.imaginary | Q.real), Implies(ExactlyOneArg(Q.imaginary), Q.imaginary))), (Mul, Implies(AllArgs(Q.real), Q.real)),
def test_refine(): assert refine(C.T, Q.symmetric(C)) == C
def test_refine(): assert refine(C * C.T * D, Q.orthogonal(C)).doit() == D kC = k * C assert refine(kC * C.T, Q.orthogonal(C)).doit() == k * Identity(n) assert refine(kC * kC.T, Q.orthogonal(C)).doit() == (k**2) * Identity(n)
def test_re(): assert refine(re(x), Q.real(x)) == x assert refine(re(x), Q.imaginary(x)) is S.Zero assert refine(re(x+y), Q.real(x) & Q.real(y)) == x + y assert refine(re(x+y), Q.real(x) & Q.imaginary(y)) == x assert refine(re(x*y), Q.real(x) & Q.real(y)) == x * y assert refine(re(x*y), Q.real(x) & Q.imaginary(y)) == 0 assert refine(re(x*y*z), Q.real(x) & Q.real(y) & Q.real(z)) == x * y * z
def test_im(): assert refine(im(x), Q.imaginary(x)) == -I*x assert refine(im(x), Q.real(x)) is S.Zero assert refine(im(x+y), Q.imaginary(x) & Q.imaginary(y)) == -I*x - I*y assert refine(im(x+y), Q.real(x) & Q.imaginary(y)) == -I*y assert refine(im(x*y), Q.imaginary(x) & Q.real(y)) == -I*x*y assert refine(im(x*y), Q.imaginary(x) & Q.imaginary(y)) == 0 assert refine(im(1/x), Q.imaginary(x)) == -I/x assert refine(im(x*y*z), Q.imaginary(x) & Q.imaginary(y) & Q.imaginary(z)) == -I*x*y*z
def test_is_eq(): # test assumptions assert is_eq(x, y, Q.infinite(x) & Q.finite(y)) is False assert is_eq( x, y, Q.infinite(x) & Q.infinite(y) & Q.extended_real(x) & ~Q.extended_real(y)) is False assert is_eq( x, y, Q.infinite(x) & Q.infinite(y) & Q.extended_positive(x) & Q.extended_negative(y)) is False assert is_eq(x + I, y + I, Q.infinite(x) & Q.finite(y)) is False assert is_eq(1 + x * I, 1 + y * I, Q.infinite(x) & Q.finite(y)) is False assert is_eq(x, S(0), assumptions=Q.zero(x)) assert is_eq(x, S(0), assumptions=~Q.zero(x)) is False assert is_eq(x, S(0), assumptions=Q.nonzero(x)) is False assert is_neq(x, S(0), assumptions=Q.zero(x)) is False assert is_neq(x, S(0), assumptions=~Q.zero(x)) assert is_neq(x, S(0), assumptions=Q.nonzero(x)) # test registration class PowTest(Expr): def __new__(cls, base, exp): return Basic.__new__(cls, _sympify(base), _sympify(exp)) @dispatch(PowTest, PowTest) def _eval_is_eq(lhs, rhs): if type(lhs) == PowTest and type(rhs) == PowTest: return fuzzy_and([ is_eq(lhs.args[0], rhs.args[0]), is_eq(lhs.args[1], rhs.args[1]) ]) assert is_eq(PowTest(3, 4), PowTest(3, 4)) assert is_eq(PowTest(3, 4), _sympify(4)) is None assert is_neq(PowTest(3, 4), PowTest(3, 7))
def test_complex(): assert refine(re(1/(x + I*y)), Q.real(x) & Q.real(y)) == \ x/(x**2 + y**2) assert refine(im(1/(x + I*y)), Q.real(x) & Q.real(y)) == \ -y/(x**2 + y**2) assert refine(re((w + I*x) * (y + I*z)), Q.real(w) & Q.real(x) & Q.real(y) & Q.real(z)) == w*y - x*z assert refine(im((w + I*x) * (y + I*z)), Q.real(w) & Q.real(x) & Q.real(y) & Q.real(z)) == w*z + x*y
def test_atan2(): assert refine(atan2(y, x), Q.real(y) & Q.positive(x)) == atan(y/x) assert refine(atan2(y, x), Q.negative(y) & Q.positive(x)) == atan(y/x) assert refine(atan2(y, x), Q.negative(y) & Q.negative(x)) == atan(y/x) - pi assert refine(atan2(y, x), Q.positive(y) & Q.negative(x)) == atan(y/x) + pi assert refine(atan2(y, x), Q.zero(y) & Q.negative(x)) == pi assert refine(atan2(y, x), Q.positive(y) & Q.zero(x)) == pi/2 assert refine(atan2(y, x), Q.negative(y) & Q.zero(x)) == -pi/2 assert refine(atan2(y, x), Q.zero(y) & Q.zero(x)) is nan
def _contains(self, other): if ask(Q.positive(other)) and ask(Q.integer(other)): return True return False