Skip to content

Commit

Permalink
Merge pull request #302 from skirpichev/add-coverage10
Browse files Browse the repository at this point in the history
Add test coverage
  • Loading branch information
skirpichev committed Aug 2, 2016
2 parents a625bff + 071ac36 commit 4737c17
Show file tree
Hide file tree
Showing 14 changed files with 119 additions and 134 deletions.
14 changes: 3 additions & 11 deletions diofant/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,9 @@

__version__ = "0.8.0a1"


def __diofant_debug():
# helper function so we don't import os globally
import os
debug_str = os.getenv('DIOFANT_DEBUG', 'False')
if debug_str in ('True', 'False'):
return eval(debug_str)
else:
raise RuntimeError("unrecognized value for DIOFANT_DEBUG: %s" %
debug_str)
DIOFANT_DEBUG = __diofant_debug()
import os
DIOFANT_DEBUG = os.getenv('DIOFANT_DEBUG', 'False') != 'False'
del os

from .core import * # noqa: F403
from .logic import * # noqa: F403
Expand Down
1 change: 1 addition & 0 deletions diofant/core/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def flatten(cls, seq):
if coeff is S.NaN:
# we know for sure the result will be nan
return [S.NaN], [], None
o # XXX "peephole" optimization, http://bugs.python.org/issue2506
continue

elif o is S.ComplexInfinity:
Expand Down
42 changes: 18 additions & 24 deletions diofant/core/evalf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from .sympify import sympify
from .singleton import S

from diofant.utilities.misc import debug

LG10 = math.log(10, 2)
rnd = round_nearest

Expand Down Expand Up @@ -394,17 +396,15 @@ def evalf_add(v, prec, options):
[a[1::2] for a in terms if a[1]], prec, target_prec)
acc = complex_accuracy((re, im, re_acc, im_acc))
if acc >= target_prec:
if options.get('verbose'):
print("ADD: wanted", target_prec, "accurate bits, got", re_acc, im_acc)
debug("ADD: wanted", target_prec, "accurate bits, got", re_acc, im_acc)
break
else:
if (prec - target_prec) > options['maxprec']:
break

prec = prec + max(10 + 2**i, target_prec - acc)
i += 1
if options.get('verbose'):
print("ADD: restarting with prec", prec)
debug("ADD: restarting with prec", prec)

options['maxprec'] = oldmaxprec
if iszero(re, scaled=True):
Expand Down Expand Up @@ -520,8 +520,7 @@ def evalf_mul(v, prec, options):
D = mpf_mul(im, wre, use_prec)
re = mpf_add(A, B, use_prec)
im = mpf_add(C, D, use_prec)
if options.get('verbose'):
print("MUL: wanted", prec, "accurate bits, got", acc)
debug("MUL: wanted", prec, "accurate bits, got", acc)
# multiply by I
if direction & 1:
re, im = mpf_neg(im), re
Expand Down Expand Up @@ -645,7 +644,7 @@ def evalf_trig(v, prec, options):
func = mpf_cos
elif v.func is sin:
func = mpf_sin
else:
else: # pagma: no cover
raise NotImplementedError
arg = v.args[0]
# 20 extra bits is possibly overkill. It does make the need
Expand All @@ -661,7 +660,7 @@ def evalf_trig(v, prec, options):
return fone, None, prec, None
elif v.func is sin:
return None, None, None, None
else:
else: # pragme: no cover
raise NotImplementedError
# For trigonometric functions, we are interested in the
# fixed-point (absolute) accuracy of the argument.
Expand All @@ -683,9 +682,8 @@ def evalf_trig(v, prec, options):
gap = -ysize
accuracy = (xprec - xsize) - gap
if accuracy < prec:
if options.get('verbose'):
print("SIN/COS", accuracy, "wanted", prec, "gap", gap)
print(to_str(y, 10))
debug("SIN/COS", accuracy, "wanted", prec, "gap", gap)
debug(to_str(y, 10))
if xprec > options.get('maxprec', DEFAULT_MAXPREC):
return y, None, accuracy, None
xprec += gap
Expand Down Expand Up @@ -1054,7 +1052,7 @@ def evalf_sum(expr, prec, options):
expr = expr.subs(options['subs'])
func = expr.function
limits = expr.limits
if len(limits) != 1 or len(limits[0]) != 3:
if len(limits) != 1 or len(limits[0]) != 3: # pragma: no cover
raise NotImplementedError
if func is S.Zero:
return mpf(0), None, None, None
Expand Down Expand Up @@ -1195,11 +1193,10 @@ def evalf(x, prec, options):
r = re, im, reprec, imprec
except AttributeError:
raise NotImplementedError
if options.get("verbose"):
print("### input", x)
print("### output", to_str(r[0] or fzero, 50))
print("### raw", r) # r[0], r[2]
print()
debug("### input", x)
debug("### output", to_str(r[0] or fzero, 50))
debug("### raw", r) # r[0], r[2]
debug()
chop = options.get('chop', False)
if chop:
if chop is True:
Expand All @@ -1220,7 +1217,7 @@ def evalf(x, prec, options):
class EvalfMixin(object):
"""Mixin class adding evalf capabililty."""

def evalf(self, n=15, subs=None, maxn=100, chop=False, strict=False, quad=None, verbose=False):
def evalf(self, n=15, subs=None, maxn=100, chop=False, strict=False, quad=None):
"""
Evaluate the given formula to an accuracy of n digits.
Optional keyword arguments:
Expand All @@ -1247,10 +1244,6 @@ def evalf(self, n=15, subs=None, maxn=100, chop=False, strict=False, quad=None,
Choose algorithm for numerical quadrature. By default,
tanh-sinh quadrature is used. For oscillatory
integrals on an infinite interval, try quad='osc'.
verbose=<bool>
Print debug information (default=False)
"""
from diofant import Float, Number
n = n if n is not None else 15
Expand All @@ -1261,7 +1254,7 @@ def evalf(self, n=15, subs=None, maxn=100, chop=False, strict=False, quad=None,
# for sake of sage that doesn't like evalf(1)
if n == 1 and isinstance(self, Number):
from diofant.core.expr import _mag
rv = self.evalf(2, subs, maxn, chop, strict, quad, verbose)
rv = self.evalf(2, subs, maxn, chop, strict, quad)
m = _mag(rv)
rv = rv.round(1 - m)
return rv
Expand All @@ -1270,7 +1263,7 @@ def evalf(self, n=15, subs=None, maxn=100, chop=False, strict=False, quad=None,
_create_evalf_table()
prec = dps_to_prec(n)
options = {'maxprec': max(prec, int(maxn*LG10)), 'chop': chop,
'strict': strict, 'verbose': verbose}
'strict': strict}
if subs is not None:
options['subs'] = subs
if quad is not None:
Expand Down Expand Up @@ -1358,6 +1351,7 @@ def N(x, n=15, **options):
Calls x.evalf(n, \*\*options).
Both .n() and N() are equivalent to .evalf(); use the one that you like better.
Examples
========
Expand Down
18 changes: 2 additions & 16 deletions diofant/core/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,8 +589,6 @@ def equals(self, other, failing_expression=False):
"""
from diofant.simplify.simplify import nsimplify, simplify
from diofant.solvers.solvers import solve
from diofant.polys.polyerrors import NotAlgebraic
from diofant.polys.numberfields import minimal_polynomial

other = sympify(other)
if self == other:
Expand Down Expand Up @@ -656,18 +654,7 @@ def equals(self, other, failing_expression=False):
and simplify(si) == s
for si in sol):
return True
except NotImplementedError:
pass

# try to prove with minimal_polynomial but know when
# *not* to use this or else it can take a long time. e.g. issue 8354
if True: # change True to condition that assures non-hang
try:
mp = minimal_polynomial(diff)
if mp.is_Symbol:
return True
return False
except (NotAlgebraic, NotImplementedError):
except NotImplementedError: # pragma: no cover
pass

# diff has not simplified to zero; constant is either None, True
Expand Down Expand Up @@ -937,10 +924,9 @@ def as_terms(self):
if factor.is_number:
try:
coeff *= complex(factor)
continue
except TypeError:
pass
else:
continue

if factor.is_commutative:
base, exp = decompose_power(factor)
Expand Down
9 changes: 3 additions & 6 deletions diofant/core/exprtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def __init__(self, factors=None): # Factors
if n.p != 1:
factors[Integer(n.p)] = S.One
factors[Integer(n.q)] = S.NegativeOne
else:
else: # pragma: no cover
raise ValueError('Expected Float|Rational|Integer, not %s' % n)
elif isinstance(factors, Basic) and not factors.args:
factors = {factors: S.One}
Expand Down Expand Up @@ -179,14 +179,11 @@ def __init__(self, factors=None): # Factors
raise ValueError('unexpected factor in i1: %s' % a)

self.factors = factors
try:
self.gens = frozenset(factors.keys())
except AttributeError:
raise TypeError('expecting Expr or dictionary')
self.gens = frozenset(factors.keys())

def __hash__(self): # Factors
keys = tuple(ordered(self.factors.keys()))
values = [self.factors[k] for k in keys]
values = tuple(self.factors[k] for k in keys)
return hash((keys, values))

def __repr__(self): # Factors
Expand Down
3 changes: 2 additions & 1 deletion diofant/core/mul.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,12 @@ def flatten(cls, seq):
if o is S.NaN or coeff is S.ComplexInfinity and o is S.Zero:
# we know for sure the result will be nan
return [S.NaN], [], None
elif coeff.is_Number: # it could be zoo
if coeff.is_Number: # it could be zoo
coeff *= o
if coeff is S.NaN:
# we know for sure the result will be nan
return [S.NaN], [], None
o # XXX "peephole" optimization, http://bugs.python.org/issue2506
continue

elif o is S.ComplexInfinity:
Expand Down
8 changes: 6 additions & 2 deletions diofant/core/tests/test_arit.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from diofant import (Basic, Symbol, sin, cos, exp, sqrt, Rational, Float, re, pi,
sympify, Add, Mul, Pow, Mod, I, log, S, Max, symbols, oo,
Integer, sign, im, nan, Dummy, factorial, comp, O)
Integer, sign, im, nan, Dummy, factorial, comp, O, zoo)
from diofant.utilities.randtest import verify_numerically


Expand Down Expand Up @@ -1687,7 +1687,7 @@ def test_issue_6077():
assert 2**(1.5*x)*2**(2.5*x) == 2**(4.0*x)


def test_mul_flatten_oo():
def test_mul_flatten_oo_zoo():
p = symbols('p', positive=True)
n, m = symbols('n,m', negative=True)
x_im = symbols('x_im', imaginary=True)
Expand All @@ -1696,6 +1696,8 @@ def test_mul_flatten_oo():
assert p*oo == oo
assert x_im*oo != I*oo # i could be +/- 3*I -> +/-oo

assert zoo*2*zoo is zoo


def test_add_flatten():
# see https://github.com/sympy/sympy/issues/2633#issuecomment-29545524
Expand All @@ -1708,6 +1710,8 @@ def test_add_flatten():
a = Pow(2, 3, evaluate=False)
assert a + a == 16

assert zoo + 1 + zoo is nan


def test_diofantissue_31():
assert sin(x + O(x**2)) - sin(x + O(x**2)) == \
Expand Down
1 change: 1 addition & 0 deletions diofant/core/tests/test_evalf.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ def test_issue_5486():
def test_issue_5486_bug():
from diofant import I, Expr
assert abs(Expr._from_mpmath(I._to_mpmath(15), 15) - I) < 1.0e-15
pytest.raises(TypeError, lambda: Expr._from_mpmath(I, 15))


def test_bugs():
Expand Down
5 changes: 5 additions & 0 deletions diofant/core/tests/test_exprtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@ def test_decompose_power():

def test_Factors():
assert Factors() == Factors({}) == Factors(Integer(1))
assert Factors(Integer(1)) == Factors(Factors(Integer(1)))
assert Factors().as_expr() == S.One
assert Factors({x: 2, y: 3, sin(x): 4}).as_expr() == x**2*y**3*sin(x)**4
assert Factors(S.Infinity) == Factors({oo: 1})
assert Factors(S.NegativeInfinity) == Factors({oo: 1, -1: 1})

f1 = Factors({oo: 1})
f2 = Factors({oo: 1})
assert hash(f1) == hash(f2)

a = Factors({x: 5, y: 3, z: 7})
b = Factors({ y: 4, z: 3, t: 10})

Expand Down
18 changes: 18 additions & 0 deletions diofant/core/tests/test_priority.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,32 @@ class Lower(Higher):
result = 'low'


class Lower2(Higher):
_op_priority = 5.0
result = 'low'

@call_highest_priority('typo')
def __mul__(self, other):
return self.result


class Higher2:
result = "high"


def test_mul():
x = Symbol('x')
h = Higher()
l = Lower()
l2 = Lower2()
h2 = Higher2()
assert l*h == h*l == 'high'
assert x*h == h*x == 'high'
assert l*x == x*l != 'low'

assert l2*h == 'low'
assert l2*h2 == 'low'


def test_add():
x = Symbol('x')
Expand Down
5 changes: 5 additions & 0 deletions diofant/core/tests/test_sympify.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,11 @@ def add_raises(a, b):

pytest.raises(SympifyError, lambda: add_raises(x, '1'))

with pytest.raises(LookupError):
@_sympifyit('x', NotImplemented)
def spam():
return


def test_int_float():
class F1_1(object):
Expand Down

0 comments on commit 4737c17

Please sign in to comment.