Skip to content

Commit

Permalink
Merge pull request #42 from skirpichev/make-complex-finite
Browse files Browse the repository at this point in the history
Make complex numbers - finite in old assumptions
  • Loading branch information
skirpichev committed Jan 7, 2016
2 parents 654f3f0 + f377d5a commit 3299539
Show file tree
Hide file tree
Showing 24 changed files with 99 additions and 82 deletions.
5 changes: 3 additions & 2 deletions sympy/core/assumptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,10 @@
'real == extended_real & finite',
'rational -> algebraic',
'algebraic -> complex',
'extended_real -> complex & hermitian',
'real -> complex & hermitian',
'imaginary -> complex & antihermitian',
'complex -> commutative',
'complex -> finite & commutative',
'extended_real -> commutative',

'odd == integer & ~even',
'even == integer & ~odd',
Expand Down
7 changes: 3 additions & 4 deletions sympy/core/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,9 @@ def assumptions0(self):
{'commutative': True}
>>> x = Symbol("x", positive=True)
>>> x.assumptions0 == \
... {'commutative': True, 'complex': True, 'extended_real': True,
... 'hermitian': True, 'imaginary': False, 'negative': False,
... 'nonnegative': True, 'nonpositive': False, 'nonzero': True,
... 'positive': True, 'zero': False}
... {'commutative': True, 'extended_real': True, 'imaginary': False,
... 'negative': False, 'nonnegative': True, 'nonpositive': False,
... 'nonzero': True, 'positive': True, 'zero': False}
True
"""
return {}
Expand Down
10 changes: 5 additions & 5 deletions sympy/core/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def __ge__(self, other):
except SympifyError:
raise TypeError("Invalid comparison %s >= %s" % (self, other))
for me in (self, other):
if me.is_complex and me.is_extended_real is False:
if me.is_commutative and me.is_extended_real is False:
raise TypeError("Invalid comparison of complex %s" % me)
if me is S.NaN:
raise TypeError("Invalid NaN comparison")
Expand All @@ -254,7 +254,7 @@ def __le__(self, other):
except SympifyError:
raise TypeError("Invalid comparison %s <= %s" % (self, other))
for me in (self, other):
if me.is_complex and me.is_extended_real is False:
if me.is_commutative and me.is_extended_real is False:
raise TypeError("Invalid comparison of complex %s" % me)
if me is S.NaN:
raise TypeError("Invalid NaN comparison")
Expand All @@ -272,7 +272,7 @@ def __gt__(self, other):
except SympifyError:
raise TypeError("Invalid comparison %s > %s" % (self, other))
for me in (self, other):
if me.is_complex and me.is_extended_real is False:
if me.is_commutative and me.is_extended_real is False:
raise TypeError("Invalid comparison of complex %s" % me)
if me is S.NaN:
raise TypeError("Invalid NaN comparison")
Expand All @@ -290,7 +290,7 @@ def __lt__(self, other):
except SympifyError:
raise TypeError("Invalid comparison %s < %s" % (self, other))
for me in (self, other):
if me.is_complex and me.is_extended_real is False:
if me.is_commutative and me.is_extended_real is False:
raise TypeError("Invalid comparison of complex %s" % me)
if me is S.NaN:
raise TypeError("Invalid NaN comparison")
Expand Down Expand Up @@ -812,7 +812,7 @@ def conjugate(self):

def _eval_transpose(self):
from sympy.functions.elementary.complexes import conjugate
if self.is_complex:
if self.is_complex or self.is_extended_real:
return self
elif self.is_hermitian:
return conjugate(self)
Expand Down
3 changes: 0 additions & 3 deletions sympy/core/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,9 +495,6 @@ def _eval_derivative(self, s):
def _eval_is_commutative(self):
return fuzzy_and(a.is_commutative for a in self.args)

def _eval_is_complex(self):
return fuzzy_and(a.is_complex for a in self.args)

def as_base_exp(self):
"""
Returns the method as the 2-tuple (base, exponent).
Expand Down
2 changes: 1 addition & 1 deletion sympy/core/mul.py
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ def _eval_is_extended_real(self):
zero = one_neither = False

for t in self.args:
if not t.is_complex:
if t.is_finite and not t.is_complex:
return t.is_complex
elif t.is_imaginary:
real = not real
Expand Down
1 change: 0 additions & 1 deletion sympy/core/numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2804,7 +2804,6 @@ class ComplexInfinity(AtomicExpr, metaclass=Singleton):
is_infinite = True
is_number = True
is_prime = False
is_complex = True
is_extended_real = False

__slots__ = []
Expand Down
7 changes: 3 additions & 4 deletions sympy/core/power.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,10 +433,9 @@ def _eval_is_extended_real(self):
return i.is_integer

def _eval_is_complex(self):
if all(a.is_complex for a in self.args):
return True
elif self.base is S.Exp1:
return self.exp.is_complex
from sympy import log
if self.base.is_complex:
return (log(self.base)*self.exp).is_complex

def _eval_is_imaginary(self):
from sympy import arg, log
Expand Down
3 changes: 2 additions & 1 deletion sympy/core/relational.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,8 @@ def __new__(cls, lhs, rhs=0, **options):

# If appropriate, check if the difference evaluates. Detect
# incompatibility such as lhs real and rhs not real.
if lhs.is_complex and rhs.is_complex:
if ((lhs.is_complex and rhs.is_complex) or
(lhs.is_extended_real and rhs.is_extended_real)):
r = (lhs - rhs).is_zero
if r is not None:
return _sympify(r)
Expand Down
40 changes: 20 additions & 20 deletions sympy/core/tests/test_arit.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def test_Symbol():
assert x.is_imaginary is None # could be I or 1 + I
x = Symbol('x', complex=True, imaginary=False)
assert x.is_extended_real is None # could be 1 or 1 + I
x = Symbol('x', extended_real=True)
x = Symbol('x', real=True)
assert x.is_complex
x = Symbol('x', imaginary=True)
assert x.is_complex
Expand Down Expand Up @@ -368,16 +368,18 @@ def test_Add_Mul_is_integer():

def test_Add_Mul_is_finite():
x = Symbol('x', extended_real=True, finite=False)

assert sin(x).is_finite is True
assert (x*sin(x)).is_finite is False
assert (1024*sin(x)).is_finite is True
assert (sin(x)*exp(x)).is_finite is not True
assert (sin(x)*cos(x)).is_finite is True
assert (x*sin(x)*exp(x)).is_finite is not True

assert (sin(x) - 67).is_finite is True
assert (sin(x) + exp(x)).is_finite is not True
y = Symbol('y', real=True)
z = Symbol('z', real=True)

assert y.is_finite is True
assert (x*y).is_finite is False
assert (1024*y).is_finite is True
assert (y*exp(x)).is_finite is not True
assert (y*z).is_finite is True
assert (x*y*exp(x)).is_finite is not True

assert (y - 67).is_finite is True
assert (y + exp(x)).is_finite is not True
assert (1 + x).is_finite is False
assert (1 + x**2 + (1 + x)*(1 - x)).is_finite is None
assert (sqrt(2)*(1 + x)).is_finite is False
Expand Down Expand Up @@ -490,12 +492,9 @@ def test_Mul_is_rational():
r = Symbol('r', rational=True)
assert (pi*r).is_rational is None

# issue 8008
z = Symbol('z', zero=True)
i = Symbol('i', imaginary=True)
assert (z*i).is_rational is None
bi = Symbol('i', imaginary=True, finite=True)
assert (z*bi).is_zero is True
assert (z*i).is_rational


def test_Add_is_rational():
Expand Down Expand Up @@ -1032,16 +1031,17 @@ def test_Pow_is_finite():
x = Symbol('x', extended_real=True)
p = Symbol('p', positive=True)
n = Symbol('n', negative=True)
y = Symbol('y', real=True)

assert (x**2).is_finite is None # x could be oo
assert (x**x).is_finite is None # ditto
assert (p**x).is_finite is None # ditto
assert (n**x).is_finite is None # ditto
assert (1/S.Pi).is_finite
assert (sin(x)**2).is_finite is True
assert (sin(x)**x).is_finite is None
assert (sin(x)**exp(x)).is_finite is None
assert (1/sin(x)).is_finite is None # if zero, no, otherwise yes
assert (y**2).is_finite is True
assert (y**x).is_finite is None
assert (y**exp(x)).is_finite is None
assert (1/y).is_finite is None # if zero, no, otherwise yes
assert (1/exp(x)).is_finite is None # x could be -oo


Expand Down Expand Up @@ -1208,7 +1208,7 @@ def test_Pow_is_nonpositive_nonnegative():

def test_Mul_is_imaginary_real():
r = Symbol('r', extended_real=True)
p = Symbol('p', positive=True)
p = Symbol('p', positive=True, real=True)
i = Symbol('i', imaginary=True)
ii = Symbol('ii', imaginary=True)
x = Symbol('x')
Expand Down
15 changes: 8 additions & 7 deletions sympy/core/tests/test_assumptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ def test_infinity():
assert oo.is_commutative is True
assert oo.is_integer is False
assert oo.is_rational is False
assert oo.is_algebraic is None
assert oo.is_transcendental is None
assert oo.is_algebraic is False
assert oo.is_transcendental is False
assert oo.is_extended_real is True
assert oo.is_complex is True
assert oo.is_complex is False
assert oo.is_noninteger is False
assert oo.is_irrational is False
assert oo.is_imaginary is False
Expand All @@ -126,10 +126,10 @@ def test_neg_infinity():
assert mm.is_commutative is True
assert mm.is_integer is False
assert mm.is_rational is False
assert mm.is_algebraic is None
assert mm.is_transcendental is None
assert mm.is_algebraic is False
assert mm.is_transcendental is False
assert mm.is_extended_real is True
assert mm.is_complex is True
assert mm.is_complex is False
assert mm.is_noninteger is False
assert mm.is_irrational is False
assert mm.is_imaginary is False
Expand All @@ -149,9 +149,10 @@ def test_neg_infinity():

def test_zoo():
zoo = S.ComplexInfinity
assert zoo.is_complex
assert zoo.is_complex is False
assert zoo.is_real is False
assert zoo.is_prime is False
assert zoo.is_infinite


def test_nan():
Expand Down
7 changes: 5 additions & 2 deletions sympy/core/tests/test_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,10 +361,13 @@ def test_function_complex():
assert sin(x).is_commutative is True
assert exp(x).is_commutative is True
assert log(x).is_commutative is True
assert f(x).is_complex is True
assert sin(x).is_complex is True
assert exp(x).is_complex is True
assert log(x).is_complex is True
assert log(x).is_complex is None # could be zero
n = Symbol('n', complex=True, nonzero=True)
z = Symbol('z', zero=True)
assert log(n).is_complex is True
assert log(z).is_complex is False


def test_function__eval_nseries():
Expand Down
4 changes: 4 additions & 0 deletions sympy/functions/elementary/complexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,10 @@ def _eval_evalf(self, prec):
ub = periodic_argument(z, oo)._eval_evalf(prec)
return (ub - ceiling(ub/period - S(1)/2)*period)._eval_evalf(prec)

def _eval_is_real(self):
if self.args[1].is_positive:
return True


def unbranched_argument(arg):
from sympy import oo
Expand Down
7 changes: 7 additions & 0 deletions sympy/functions/elementary/exponential.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,13 @@ def _eval_is_finite(self):
return False
return arg.is_finite

def _eval_is_complex(self):
arg = self.args[0]
if arg.is_zero:
return False
elif arg.is_nonzero:
return arg.is_complex

def _eval_is_positive(self):
return (self.args[0] - 1).is_positive

Expand Down
2 changes: 2 additions & 0 deletions sympy/functions/elementary/tests/test_complexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,8 @@ def test_periodic_argument():

assert Abs(polar_lift(1 + I)) == Abs(1 + I)

assert periodic_argument(x, pi).is_real is True


@pytest.mark.xfail
def test_principal_branch_fail():
Expand Down
2 changes: 1 addition & 1 deletion sympy/functions/elementary/tests/test_piecewise.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def test_piecewise_integrate():

def test_piecewise_integrate_inequality_conditions():
x, y = symbols("x y", real=True)
c1, c2 = symbols("c1 c2", positive=True)
c1, c2 = symbols("c1 c2", positive=True, real=True)
g = Piecewise((0, c1*x > 1), (1, c1*x > 0), (0, True))
assert integrate(g, (x, -oo, 0)) == 0
assert integrate(g, (x, -5, 0)) == 0
Expand Down
13 changes: 8 additions & 5 deletions sympy/functions/elementary/tests/test_trigonometric.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
FiniteSet, asec, acsc, sech, csch)

x, y, z = symbols('x y z')
r = Symbol('r', extended_real=True)
r = Symbol('r', real=True)
c = Symbol('c', complex=True)
k = Symbol('k', integer=True)
p = Symbol('p', positive=True)
n = Symbol('n', negative=True)
Expand Down Expand Up @@ -102,7 +103,8 @@ def test_sin():

assert sin(k*pi*I) == sinh(k*pi)*I

assert sin(r).is_extended_real is True
assert sin(r).is_real
assert sin(c).is_complex

assert sin(0, evaluate=False).is_algebraic
assert sin(a).is_algebraic is None
Expand Down Expand Up @@ -289,7 +291,8 @@ def test_cos():
assert cos(x*I) == cosh(x)
assert cos(k*pi*I) == cosh(k*pi)

assert cos(r).is_extended_real is True
assert cos(r).is_real
assert cos(c).is_complex

assert cos(0, evaluate=False).is_algebraic
assert cos(a).is_algebraic is None
Expand Down Expand Up @@ -1184,7 +1187,7 @@ def test_sec():
assert sec(x).expand(trig=True) == 1/cos(x)
assert sec(2*x).expand(trig=True) == 1/(2*cos(x)**2 - 1)

assert sec(x).is_extended_real
assert sec(r).is_extended_real
assert sec(z).is_extended_real is None

assert sec(a).is_algebraic is None
Expand Down Expand Up @@ -1259,7 +1262,7 @@ def test_csc():
assert csc(x).expand(trig=True) == 1/sin(x)
assert csc(2*x).expand(trig=True) == 1/(2*sin(x)*cos(x))

assert csc(x).is_extended_real
assert csc(r).is_extended_real
assert csc(z).is_extended_real is None

assert csc(a).is_algebraic is None
Expand Down
Loading

0 comments on commit 3299539

Please sign in to comment.