Source code for pyranha.test

# -*- coding: iso-8859-1 -*-
# Copyright 2009-2017 Francesco Biscani (bluescarni@gmail.com)
#
# This file is part of the Piranha library.
#
# The Piranha library is free software; you can redistribute it and/or modify
# it under the terms of either:
#
#  * the GNU Lesser General Public License as published by the Free
#    Software Foundation; either version 3 of the License, or (at your
#    option) any later version.
#
# or
#
#  * the GNU General Public License as published by the Free Software
#    Foundation; either version 3 of the License, or (at your option) any
#    later version.
#
# or both in parallel, as here.
#
# The Piranha library is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received copies of the GNU General Public License and the
# GNU Lesser General Public License along with the Piranha library.  If not,
# see https://www.gnu.org/licenses/.

from __future__ import absolute_import as _ai

import unittest as _ut


# s11n tests for save/load file.
def _s11n_load_save_test(self, p):
    import tempfile
    import os
    import shutil
    from . import load_file, save_file, data_format as df, compression as comp
    for form in [df.boost_portable, df.boost_binary, df.msgpack_portable, df.msgpack_binary]:
        for c in [comp.none, comp.bzip2, comp.gzip, comp.zlib]:
            f = tempfile.NamedTemporaryFile(delete=False)
            f.close()
            try:
                save_file(p, f.name, form, c)
                ret = type(p)()
                load_file(ret, f.name, form, c)
                self.assertEqual(ret, p)
            except NotImplementedError:
                pass
            finally:
                os.remove(f.name)
    # Deduce from filename.
    temp_dir = tempfile.mkdtemp()
    try:
        for suff in ['.boostb', '.boostp', '.mpackb', '.mpackp']:
            for comp in ['', '.bz2', '.zip', '.gz']:
                filename = os.path.join(temp_dir, 'foo' + suff + comp)
                save_file(p, filename)
                ret = type(p)()
                load_file(ret, filename)
                self.assertEqual(ret, p)
    except NotImplementedError:
        pass
    finally:
        shutil.rmtree(temp_dir)
    self.assertRaises(ValueError, lambda: save_file(p, "foo"))
    self.assertRaises(ValueError, lambda: load_file(p, "foo"))
    # Input args checking.
    self.assertRaisesRegexp(
        TypeError, "the file name must be a string", lambda: save_file(p, 123))
    self.assertRaisesRegexp(
        ValueError, "the data format was provided but the compression format was not", lambda: save_file(p, "foo", df=1))
    self.assertRaisesRegexp(
        ValueError, "the compression format was provided but the data format was not", lambda: save_file(p, "foo", cf=1, df=None))

# Helper to check that pickle roundtrips.


def _pickle_test(self, x):
    import pickle
    str_rep = pickle.dumps(x)
    self.assertEqual(x, pickle.loads(str_rep))


[docs]class basic_test_case(_ut.TestCase): """Basic test case. To be used within the :mod:`unittest` framework. Will test features common to all series types. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(basic_test_case) """ def runTest(self): from fractions import Fraction from copy import copy, deepcopy # Test version number. import pyranha self.assertTrue(pyranha.__version__) # Use polynomial for testing. from .types import polynomial, integer, rational, int16, double, monomial # Arithmetic with int and Fraction, len, str and comparisons. for s, t in [(integer, int), (rational, Fraction)]: tp = polynomial[s, monomial[int16]]() self.assertEqual(tp('x') - tp('x'), t(1) - t(1)) self.assertEqual(tp(tp('x')) - tp('x'), t(1) - t(1)) self.assertEqual(tp(), t(0)) self.assertEqual(tp(t(2)), t(2)) self.assertEqual(tp('x'), +tp('x')) foo = tp(t(1)) foo += t(2) self.assertEqual(foo, t(1) + t(2)) self.assertEqual(tp(1) + tp(2), t(1) + t(2)) self.assertEqual(tp() + t(2), t(0) + t(2)) self.assertEqual(t(2) + tp(), t(0) + t(2)) self.assertEqual(tp('x') * t(-1), -tp('x')) foo -= t(4) self.assertEqual(foo, t(3) - t(4)) self.assertEqual(tp(1) - tp(2), t(1) - t(2)) self.assertEqual(tp() - t(2), t(0) - t(2)) self.assertEqual(t(2) - tp(), t(2) - t(0)) self.assertEqual(tp('x'), -(-tp('x'))) foo *= t(-5) self.assertEqual(foo, t(-1) * t(-5)) self.assertEqual(tp(1) * tp(2), t(1) * t(2)) self.assertEqual(tp(1) * t(2), t(1) * t(2)) self.assertEqual(t(2) * tp(1), t(2) * t(1)) self.assertNotEqual(repr(tp('x')), '') self.assertNotEqual(str(tp('x')), '') self.assertEqual(len(tp('x') + 1), 2) self.assertTrue(tp('x') != tp('y')) self.assertTrue(tp('x') != t(1)) self.assertTrue(t(1) != tp('x')) self.assertTrue(tp('x') == tp('x')) self.assertTrue(tp(t(1)) == t(1)) self.assertTrue(t(1) == tp(t(1))) self.assertTrue(tp('x') ** 3 == tp('x') * tp('x') * tp('x')) # A couple of trimming tests. x, y, z = [tp(_) for _ in "xyz"] self.assertEqual((x + y + z).symbol_set, ['x', 'y', 'z']) self.assertEqual((x + y + z - y - z).symbol_set, ['x', 'y', 'z']) self.assertEqual((x + y + z - y - z).trim().symbol_set, ['x']) tp_int = polynomial[integer, monomial[int16]]() self.assertRaises(ValueError, tp_int, float('inf')) self.assertRaises(ZeroDivisionError, lambda: tp_int() ** -1) tp_q = polynomial[rational, monomial[int16]]() self.assertRaises(ZeroDivisionError, lambda: tp_q(Fraction(0, 1)) ** -1) self.assertEqual(tp_q(Fraction(1, 3)) ** -2, 9) self.assertRaises(ZeroDivisionError, lambda: tp_int(Fraction(1, 3)) ** -2) tp_f = polynomial[double, monomial[int16]]() # NOTE: here we are going to assume that Python's float implementation uses C++ doubles and # the corresponding pow() function. self.assertEqual(tp_f(0.1) ** (0.5), 0.1**0.5) q1 = tp_q(Fraction(1, 6)) self.assertEqual(q1 ** 20, Fraction(2, 12) ** 20) self.assertEqual(Fraction(1, 3) ** 100000, tp_q(Fraction(1, 3)) ** 100000) # Copy and deepcopy. s1 = tp_int(2) self.assertNotEqual(id(copy(s1)), s1) self.assertEqual(copy(s1), s1) self.assertNotEqual(id(deepcopy(s1)), s1) self.assertEqual(deepcopy(s1), s1) # Latex renderer, if available. x = tp_int('x') tmp = x._repr_png_() self.assertTrue(tmp is None or len(tmp) != 0) # Evaluation. from .math import evaluate x = tp_q('x') self.assertEqual(evaluate(x, {'x': 3}), 3) self.assertEqual(evaluate(2 * x, {'x': Fraction(3, 2)}), Fraction(3)) # Test exception translation. # NOTE: the msgpack exception translation is tested elsewhere. from ._core import _test_safe_cast_failure, _test_zero_division_error, _test_not_implemented_error, _test_overflow_error, \ _test_bn_poverflow_error, _test_bn_noverflow_error, _test_bn_bnc self.assertRaisesRegexp( ValueError, "hello world", _test_safe_cast_failure) self.assertRaisesRegexp( ZeroDivisionError, "hello world", _test_zero_division_error) self.assertRaisesRegexp( NotImplementedError, "hello world", _test_not_implemented_error) self.assertRaisesRegexp( OverflowError, "hello world", _test_overflow_error) self.assertRaisesRegexp( OverflowError, "positive overflow", _test_bn_poverflow_error) self.assertRaisesRegexp( OverflowError, "negative overflow", _test_bn_noverflow_error) self.assertRaisesRegexp( OverflowError, "overflow", _test_bn_bnc)
[docs]class series_division_test_case(_ut.TestCase): """Series division test case. To be used within the :mod:`unittest` framework. Will test series division. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(series_division_test_case) """ def runTest(self): from fractions import Fraction as F from .types import poisson_series, polynomial, monomial, int16, rational, double pt = poisson_series[polynomial[rational, monomial[int16]]]() pt2 = poisson_series[polynomial[double, monomial[int16]]]() x, y, z = [pt(_) for _ in 'xyz'] self.assertEqual(pt(4) / pt(3), F(4, 3)) self.assertEqual(type(pt(4) / pt(3)), pt) self.assertEqual(pt(4) / 2, 2) self.assertEqual(type(pt(4) / 2), pt) self.assertEqual(1 / pt(2), F(1, 2)) self.assertEqual(type(1 / pt(2)), pt) self.assertEqual(1. / pt(2), 1. / 2.) # We don't support mixed operations among series types. self.assertRaises(TypeError, lambda: type(pt(2) / pt2(1))) self.assertEqual(type(1. / pt(2)), pt2) self.assertEqual(type(pt(2) / 1.), pt2) self.assertRaises(ZeroDivisionError, lambda: x / 0) self.assertRaises(ValueError, lambda: x / y) tmp = pt(4) tmp /= 4 self.assertEqual(tmp, 1)
[docs]class custom_derivatives_test_case(_ut.TestCase): """Test case for custom derivatives in series. To be used within the :mod:`unittest` framework. Will check that the custom derivatives machinery works properly. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(custom_derivatives_test_case) """ def runTest(self): from .types import polynomial, monomial, int16, rational from .math import partial pt = polynomial[rational, monomial[int16]]() x = pt('x') # A custom derivative functor with a state, # used to check we actually deepcopy it. class cd(object): def __init__(self): self.value = 1 def __call__(self, p): return pt(self.value) def set_value(self, value): self.value = value c = cd() pt.register_custom_derivative('x', c) pt.register_custom_derivative('y', c) self.assertEqual(partial(x, 'x'), 1) c.set_value(42) self.assertEqual(partial(x, 'x'), 1) pt.unregister_custom_derivative('x') pt.unregister_all_custom_derivatives()
[docs]class series_in_place_ops_test_case(_ut.TestCase): """Series in-place operations test case. To be used within the :mod:`unittest` framework. Will test in-place series arithmetics. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(series_in_place_ops_test_case) """ def runTest(self): # The idea of the test is to make sure that in-place operations # really mutate the object (and do not end up creating a new object # instead). from .types import polynomial, monomial, int16, rational pt = polynomial[rational, monomial[int16]]() x = pt('x') x0 = pt('x') # Test with scalar. x_id = id(x) x += 1 self.assertEqual(x, x0 + 1) self.assertEqual(id(x), x_id) x -= 2 self.assertEqual(x, x0 - 1) self.assertEqual(id(x), x_id) x *= 2 self.assertEqual(x, 2 * x0 - 2) self.assertEqual(id(x), x_id) x /= 2 self.assertEqual(x, x0 - 1) self.assertEqual(id(x), x_id) # Test with series. x, y = pt('x'), pt('y') x_id = id(x) x += y self.assertEqual(x, x0 + y) self.assertEqual(id(x), x_id) x -= y self.assertEqual(x, x0) self.assertEqual(id(x), x_id) x *= y self.assertEqual(x, x0 * y) self.assertEqual(id(x), x_id) x /= pt(2) self.assertEqual(x, x0 * y / 2) self.assertEqual(id(x), x_id)
[docs]class mpmath_test_case(_ut.TestCase): """:mod:`mpmath` test case. To be used within the :mod:`unittest` framework. Will test interoperability between the :mod:`mpmath` library and the C++ *real* class. If the :mod:`mpmath` library is not available, the test will return immediately. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(mpmath_test_case) """ def runTest(self): try: from mpmath import workdps, mpf, pi except ImportError: return from .types import polynomial, integer, int16, monomial from .math import evaluate pt = polynomial[integer, monomial[int16]]() x = pt('x') self.assertEqual(evaluate(x, {'x': mpf('4.5667')}), mpf('4.5667')) self.assert_(type(evaluate(x, {'x': mpf('4.5667')})) == mpf) for n in [11, 21, 51, 101, 501]: with workdps(n): self.assertEqual( evaluate(x, {'x': mpf('4.5667')}), mpf('4.5667')) self.assert_(type(evaluate(x, {'x': mpf('4.5667')})) == mpf)
[docs]class math_test_case(_ut.TestCase): """:mod:`math` module test case. To be used within the :mod:`unittest` framework. Will test the functions implemented in the :mod:`math` module. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(math_test_case) """ def runTest(self): import math from .math import cos as pcos, sin as psin from .types import polynomial, k_monomial, double, real # NOTE: according to # https://docs.python.org/3/library/math.html # the CPython math functions are wrappers around the corresponding # C functions. The results should thus be roughly the same. self.assertAlmostEqual(math.cos(3.), pcos(3.)) self.assertAlmostEqual(math.cos(3.1234), pcos(3.1234)) self.assertAlmostEqual(math.sin(3.), psin(3.)) self.assertAlmostEqual(math.sin(3.1234), psin(3.1234)) pt = polynomial[double, k_monomial]() self.assertAlmostEqual(math.cos(3), pcos(pt(3)).list[0][0]) self.assertAlmostEqual(math.cos(2.456), pcos(pt(2.456)).list[0][0]) self.assertAlmostEqual(math.sin(3), psin(pt(3)).list[0][0]) self.assertAlmostEqual(math.sin(-2.456), psin(pt(-2.456)).list[0][0]) self.assertRaises(TypeError, lambda: pcos("")) self.assertRaises(TypeError, lambda: psin("")) self.binomialTest() self.sincosTest() self.evaluateTest() self.subsTest() self.invertTest() self.lambdifyTest() def binomialTest(self): from fractions import Fraction as F from .math import binomial # Check the return types of binomial. self.assertEqual(type(binomial(5, 4)), int) self.assertEqual(type(binomial(5, 4.)), float) self.assertEqual(type(binomial(5, F(4))), float) self.assertEqual(type(binomial(5., 4)), float) self.assertEqual(type(binomial(5., 4.)), float) self.assertEqual(type(binomial(5., F(4))), float) self.assertEqual(type(binomial(F(5), 4)), F) self.assertEqual(type(binomial(F(5), 4.)), float) self.assertEqual(type(binomial(F(5), F(4))), float) try: from mpmath import mpf except ImportError: return self.assertEqual(type(binomial(mpf(5), mpf(4))), mpf) self.assertEqual(type(binomial(5, mpf(4))), mpf) self.assertEqual(type(binomial(5., mpf(4))), mpf) self.assertEqual(type(binomial(F(5), mpf(4))), mpf) self.assertEqual(type(binomial(mpf(5), 4)), mpf) self.assertEqual(type(binomial(mpf(5), 4.)), mpf) self.assertEqual(type(binomial(mpf(5), F(4))), mpf) def sincosTest(self): from fractions import Fraction as F from .math import sin, cos # Check the return types. self.assertEqual(type(cos(0)), int) self.assertEqual(type(sin(0)), int) self.assertEqual(type(cos(F(0))), F) self.assertEqual(type(sin(F(0))), F) self.assertEqual(type(cos(1.)), float) self.assertEqual(type(sin(1.)), float) try: from mpmath import mpf except ImportError: return self.assertEqual(type(cos(mpf(1))), mpf) self.assertEqual(type(sin(mpf(1))), mpf) def evaluateTest(self): from fractions import Fraction as F from .math import evaluate from .types import polynomial, k_monomial, double, integer, real, rational pt = polynomial[double, k_monomial]() x, y, z = pt('x'), pt('y'), pt('z') self.assertEqual(evaluate(3 * x * y, {'x': 4, 'y': 5}), 3. * (4. * 5.)) self.assertEqual(type(evaluate(3 * x * y, {'x': 4, 'y': 5})), float) self.assertEqual( evaluate(x**2 * y**3 / 5, {'x': 4, 'y': 5}), (4.**2 * 5.**3) / 5) pt = polynomial[rational, k_monomial]() x, y, z = pt('x'), pt('y'), pt('z') self.assertEqual( evaluate(3 * x * y, {'x': F(4), 'y': F(5)}), 3 * (F(4) * F(5))) self.assertEqual(type(evaluate(3 * x * y, {'x': F(4), 'y': F(5)})), F) self.assertEqual( evaluate(x**2 * y**3 / 5, {'x': F(4), 'y': F(5)}), (F(4)**2 * F(5)**3) / 5) pt = polynomial[integer, k_monomial]() x, y, z = pt('x'), pt('y'), pt('z') self.assertEqual(evaluate(3 * x * y, {'x': 4, 'y': 5}), 3 * (4 * 5)) self.assertEqual(type(evaluate(3 * x * y, {'x': 4, 'y': 5})), int) # Integer division truncates. self.assertEqual(evaluate(x**2 * y**3 / 5, {'x': 2, 'y': 1}), 0) # Check errors. self.assertRaises(ValueError, lambda: evaluate(pt(0), {})) self.assertRaises(TypeError, lambda: evaluate( x**2 * y**3 / 5, {'x': 2., 'y': 1})) self.assertRaises(TypeError, lambda: evaluate( x**2 * y**3 / 5, {2: 2, 'y': 1})) self.assertRaises(TypeError, lambda: evaluate(x**2 * y**3 / 5, [1, 2])) # A missing symbol, thrown from C++. self.assertRaises(ValueError, lambda: evaluate( 3 * x * y, {'x': 4, 'z': 5})) try: from mpmath import mpf except ImportError: return pt = polynomial[double, k_monomial]() x, y, z = pt('x'), pt('y'), pt('z') self.assertEqual( evaluate(3 * x * y, {'x': mpf(4), 'y': mpf(5)}), mpf(3.) * (4. * 5.)) self.assertEqual( type(evaluate(3 * x * y, {'x': mpf(4), 'y': mpf(5)})), mpf) self.assertEqual( evaluate(x**2 * y**3 / 5, {'x': mpf(4), 'y': mpf(5)}), (mpf(4)**2 * 5.**3) / 5) def subsTest(self): from fractions import Fraction as F from .math import subs, ipow_subs, t_subs, cos, sin from .types import poisson_series, polynomial, k_monomial, rational, double, real pt = poisson_series[polynomial[rational, k_monomial]]() x, y, z = pt('x'), pt('y'), pt('z') # Normal subs(). self.assertEqual(subs(z * cos(x + y), {'x': 0}), z * cos(y)) # Make sure that substitution with int does not trigger any conversion # to floating point. self.assertEqual(type(subs(z * cos(x + y), {'x': 0})), pt) # Trigger a floating-point conversion. self.assertEqual(type(subs(z * cos(x + y), {'x': 0.})), poisson_series[polynomial[double, k_monomial]]()) # Trig subs. self.assertEqual(t_subs(z * sin(x + y), 'y', 0, 1), z * cos(x)) self.assertEqual(type(t_subs(z * sin(x + y), 'y', 0, 1)), pt) n, m = 2, 3 c, s = F(n**2 - m**2, n**2 + m**2), F(n * m, n**2 + m**2) self.assertEqual(t_subs(z * sin(x + y), 'y', c, s), z * sin(x) * c + z * cos(x) * s) self.assertEqual(type(t_subs(z * sin(x + y), 'y', c, s)), pt) self.assertEqual(type(t_subs(z * sin(x + y), 'y', 0., 1.)), poisson_series[polynomial[double, k_monomial]]()) # Ipow subs. self.assertEqual(ipow_subs(x**5 * y**2 * z / 5, 'x', 2, 3), 9 * x * y**2 * z / 5) self.assertEqual(type(ipow_subs(x**5 * y**2 * z / 5, 'x', 2, 3)), pt) self.assertEqual(ipow_subs(x**6 * y**2 * z / 5, 'x', 2, 3), 27 * y**2 * z / 5) self.assertEqual(type(ipow_subs(x**5 * y**2 * z / 5, 'x', 2, 3.)), poisson_series[polynomial[double, k_monomial]]()) def invertTest(self): from fractions import Fraction as F from .math import invert self.assertEqual(invert(F(3, 4)), F(4, 3)) self.assertEqual(invert(F(3, -4)), -F(4, 3)) self.assertAlmostEqual(invert(1.234), 1.234**-1.) self.assertAlmostEqual(invert(-3.456), -3.456**-1.) try: from mpmath import mpf self.assertEqual(type(invert(mpf(1.23))), mpf) except ImportError: pass from .types import polynomial, monomial, rational, int16, divisor_series, divisor, poisson_series t = polynomial[rational, monomial[rational]]() self.assertEqual(invert(t(F(3, 4))), F(4, 3)) self.assertEqual(type(invert(t(F(3, 4)))), t) self.assertEqual(invert(t('x')), t('x')**-1) t = divisor_series[polynomial[ rational, monomial[rational]], divisor[int16]]() self.assertEqual(invert(t(F(3, 4))), F(4, 3)) self.assertEqual(type(invert(t(F(3, 4)))), t) self.assertEqual(str(invert(t('x'))), '1/[(x)]') self.assertEqual(str(t('x')**-1), 'x**-1') t = poisson_series[divisor_series[polynomial[ rational, monomial[rational]], divisor[int16]]]() self.assertEqual(invert(t(F(3, 4))), F(4, 3)) self.assertEqual(type(invert(t(F(3, 4)))), t) self.assertEqual(str(invert(t('x'))), '1/[(x)]') self.assertEqual(str(t('x')**-1), 'x**-1') def lambdifyTest(self): from .math import lambdify from fractions import Fraction as F from .types import polynomial, k_monomial, rational pt = polynomial[rational, k_monomial]() x, y, z = [pt(_) for _ in 'xyz'] l = lambdify(F, 3 * x**4 / 2 - y / 3 + z**2, ['y', 'z', 'x']) self.assertEqual(l([F(1, 2), F(3, 4), F(5, 6)]), 3 * F(5, 6)**4 / 2 - F(1, 2) / 3 + F(3, 4)**2) self.assertEqual(type(l([F(1, 2), F(3, 4), F(5, 6)])), F) l = lambdify(float, 3 * x**4 / 2 - y / 3 + z**2, ['y', 'z', 'x']) self.assertAlmostEqual( l([1.2, 3.4, 5.6]), 3 * 5.6**4 / 2 - 1.2 / 3 + 3.4**2) self.assertEqual(type(l([1.2, 3.4, 5.6])), float) self.assertRaises(TypeError, lambda: lambdify( 3, 3 * x**4 / 2 - y / 3 + z**2, ['y', 'z', 'x'])) self.assertRaises(ValueError, lambda: lambdify( int, 3 * x**4 / 2 - y / 3 + z**2, ['y', 'z', 'x', 'y'])) self.assertRaises(TypeError, lambda: lambdify( int, 3 * x**4 / 2 - y / 3 + z**2, [1, 2, 3])) self.assertRaises(ValueError, lambda: l([1.2, 3.4])) self.assertRaises(ValueError, lambda: l([1.2, 3.4, 5.6, 6.7])) # Try with extra maps. l = lambdify(float, 3 * x**4 / 2 - y / 3 + z ** 2, ['y', 'z'], {'x': lambda _: 5.}) self.assertAlmostEqual(l([1.2, 3.4]), 3 * 5.**4 / 2 - 1.2 / 3 + 3.4**2) # Check that a deep copy of the functor is made. class functor(object): def __init__(self): self.n = 42. def __call__(self, a): return self.n f = functor() l = lambdify(float, 3 * x**4 / 2 - y / 3 + z**2, ['y', 'z'], {'x': f}) f.n = 0. self.assertEqual(f(1), 0.) self.assertAlmostEqual(l([1.2, 3.4]), 3 * 42. ** 4 / 2 - 1.2 / 3 + 3.4**2) # Try various errors. self.assertRaises(TypeError, lambda: lambdify( float, 3 * x**4 / 2 - y / 3 + z**2, ['y', 'z'], {'x': 1})) self.assertRaises(TypeError, lambda: lambdify( float, 3 * x**4 / 2 - y / 3 + z**2, ['y', 'z'], {3: lambda _: 3})) l = lambdify(float, 3 * x**4 / 2 - y / 3 + z ** 2, ['y', 'z'], {'x': lambda _: ""}) self.assertRaises(TypeError, lambda: l([1.2, 3.4])) self.assertRaises(ValueError, lambda: lambdify( float, 3 * x**4 / 2 - y / 3 + z**2, ['y', 'z'], {'y': lambda _: ""})) # Check the str repr. eobj = 3 * x**4 / 2 - y / 3 + z**2 l = lambdify(float, eobj, ['y', 'z']) self.assertEqual(str(l), "Lambdified object: " + str(eobj) + "\nEvaluation variables: [\"y\",\"z\"]\nSymbols in the extra map: []") l = lambdify(float, eobj, ['y', 'z'], {'x': f}) self.assertEqual(str(l), "Lambdified object: " + str(eobj) + "\nEvaluation variables: [\"y\",\"z\"]\nSymbols in the extra map: [\"x\"]") # Try with optional modules: try: from mpmath import mpf l = lambdify(mpf, x - y, ['x', 'y']) self.assertEqual(l([mpf(1), mpf(2)]), mpf(1) - mpf(2)) self.assertEqual(type(l([mpf(1), mpf(2)])), mpf) except ImportError: pass try: from numpy import array l = lambdify(float, 3 * x**4 / 2 - y / 3 + z**2, ['y', 'z', 'x']) self.assertAlmostEqual( l(array([1.2, 3.4, 5.6])), 3 * 5.6**4 / 2 - 1.2 / 3 + 3.4**2) self.assertEqual(type(l(array([1.2, 3.4, 5.6]))), float) except ImportError: pass
[docs]class polynomial_test_case(_ut.TestCase): """:mod:`polynomial` module test case. To be used within the :mod:`unittest` framework. Will test the functions implemented in the :mod:`polynomial` module. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(polynomial_test_case) """ def runTest(self): from .types import polynomial, rational, int16, integer, double, real, monomial from fractions import Fraction from .math import integrate self.assertEqual( type(polynomial[rational, monomial[int16]]()(1).list[0][0]), Fraction) self.assertEqual( type(polynomial[integer, monomial[int16]]()(1).list[0][0]), int) self.assertEqual( type(polynomial[double, monomial[int16]]()(1).list[0][0]), float) # A couple of tests for integration. pt = polynomial[rational, monomial[int16]]() x, y, z = [pt(_) for _ in ['x', 'y', 'z']] self.assertEqual(integrate(x, 'x'), x * x / 2) self.assertEqual(integrate(x, 'y'), x * y) self.assertEqual(integrate(x, 'z'), x * z) self.assertEqual(integrate(x + y * z, 'x'), x * x / 2 + x * y * z) # Some tests for find_cf(). self.assertEqual(x.find_cf([0]), 0) self.assertEqual(x.find_cf([1]), 1) self.assertEqual((3 * x).find_cf([1]), 3) self.assertEqual( (3 * x + (4 * y**2) / 3).find_cf([0, 2]), Fraction(4, 3)) self.assertRaises(ValueError, lambda: x.find_cf([1, 2])) self.assertRaises(TypeError, lambda: x.find_cf([1.])) self.assertRaises(TypeError, lambda: x.find_cf([1, 'a'])) self.assertRaises(TypeError, lambda: x.find_cf(1)) # s11n. pt = polynomial[integer, monomial[int16]]() x, y, z = pt('x'), pt('y'), pt('z') p = (x + 3 * y - 4 * z)**4 _s11n_load_save_test(self, p) _pickle_test(self, p)
[docs]class divisor_series_test_case(_ut.TestCase): """:mod:`divisor_series` module test case. To be used within the :mod:`unittest` framework. Will test the functions implemented in the :mod:`divisor_series` module. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(divisor_series_test_case) """ def runTest(self): from .types import divisor_series, rational, int16, double, real, divisor, monomial, polynomial from fractions import Fraction from .math import partial, integrate, invert self.assertEqual(type(divisor_series[polynomial[rational, monomial[int16]], divisor[ int16]]()(1).list[0][0]), polynomial[rational, monomial[int16]]()) self.assertEqual(type(divisor_series[polynomial[double, monomial[int16]], divisor[ int16]]()(1).list[0][0]), polynomial[double, monomial[int16]]()) # A couple of tests for the invert() functionality. dt = divisor_series[polynomial[ rational, monomial[int16]], divisor[int16]]() self.assertEqual( str(invert(2 * dt('x') + 4 * dt('y'))), "1/2*1/[(x+2*y)]") self.assertEqual(str(invert(dt('x') + 2 * dt('y'))), "1/[(x+2*y)]") self.assertRaises(ValueError, lambda: invert( dt('x') + 2 * dt('y') / 3)) self.assertRaises(ValueError, lambda: invert(dt('x') + 1)) # Check about partial(). x, y, z = [dt(_) for _ in ['x', 'y', 'z']] self.assertEqual(partial(z, 'x'), 0) self.assertEqual(partial(z * x, 'x'), z) self.assertEqual(partial(x**2, 'x'), 2 * x) # Variables both in the coefficient and in the divisors. self.assertEqual(partial(y * x**-1, 'x'), -y * x**-2) self.assertEqual(partial(x * invert(x - y), 'x'), invert(x - y) - x * invert(x - y)**2) # Some integrate() testing. self.assertEqual(integrate(x, 'x'), x * x / 2) self.assertEqual(integrate(x * invert(y), 'x'), x * x / 2 * invert(y)) self.assertEqual(integrate(x * invert(y) + z, 'x'), z * x + x * x / 2 * invert(y)) self.assertRaises(ValueError, lambda: integrate(invert(x), 'x')) # s11n. p = (x + 3 * y - 4 * invert(z))**4 _s11n_load_save_test(self, p) _pickle_test(self, p)
[docs]class poisson_series_test_case(_ut.TestCase): """:mod:`poisson_series` module test case. To be used within the :mod:`unittest` framework. Will test the functions implemented in the :mod:`poisson_series` module. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(poisson_series_test_case) """ def runTest(self): from .types import poisson_series, rational, monomial, int16, divisor_series, divisor, polynomial, \ k_monomial from .math import partial, integrate, sin, cos, invert # A couple of tests with eps. eps = poisson_series[divisor_series[polynomial[ rational, monomial[int16]], divisor[int16]]]() x, y, z = [eps(_) for _ in ['x', 'y', 'z']] self.assertEqual(str(cos(x)), 'cos(x)') self.assertEqual(str(sin(x)), 'sin(x)') self.assertRaises(ValueError, lambda: sin(x**2)) self.assertEqual(str(invert(x - y)), '1/[(x-y)]') self.assertEqual(str(invert(-2 * x + 4 * y)**2), '1/4*1/[(x-2*y)**2]') self.assertEqual(str(invert(-2 * x + 4 * y)**3), '-1/8*1/[(x-2*y)**3]') # Partial. self.assertEqual(partial(invert(x - y) * cos(z), 'z'), -invert(x - y) * sin(z)) self.assertEqual(partial(x * invert(x - y) * cos(x), 'x'), invert(x - y) * cos(x) + x * (-invert(x - y)**2 * cos(x) - sin(x) * invert(x - y))) # Integrate. self.assertEqual(integrate(invert(x - y) * cos(z), 'z'), invert(x - y) * sin(z)) self.assertEqual(integrate(invert(x - y) * cos(2 * z), 'z'), invert(x - y) * sin(2 * z) / 2) self.assertEqual(integrate(y * invert(x) * cos(2 * z), 'y'), y * y / 2 * invert(x) * cos(2 * z)) self.assertRaises(ValueError, lambda: integrate( y * invert(x) * cos(2 * z), 'x')) self.assertRaises(ValueError, lambda: integrate( z * invert(x) * cos(2 * z), 'z')) # s11n. p = (x + 3 * invert(y) - 4 * cos(z))**4 _s11n_load_save_test(self, p) _pickle_test(self, p)
[docs]class converters_test_case(_ut.TestCase): """Test case for the automatic conversion to/from Python from/to C++. To be used within the :mod:`unittest` framework. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(converters_test_case) """ def runTest(self): import sys from .types import polynomial, int16, integer, rational, real, monomial from fractions import Fraction as F from .math import evaluate # Context for the temporary monkey-patching of type t to return bogus # string bad_str for representation via str. class patch_str(object): def __init__(self, t, bad_str): self.t = t self.bad_str = bad_str def __enter__(self): self.old_str = self.t.__str__ self.t.__str__ = lambda s: self.bad_str def __exit__(self, type, value, traceback): self.t.__str__ = self.old_str # Same for repr. class patch_repr(object): def __init__(self, t, bad_repr): self.t = t self.bad_repr = bad_repr def __enter__(self): self.old_repr = self.t.__repr__ self.t.__repr__ = lambda s: self.bad_repr def __exit__(self, type, value, traceback): self.t.__repr__ = self.old_repr # Start with plain integers. pt = polynomial[integer, monomial[int16]]() # Use small integers to make it work both on Python 2 and Python 3. self.assertEqual(int, type(pt(4).list[0][0])) self.assertEqual(pt(4).list[0][0], 4) self.assertEqual(int, type(evaluate(pt("x"), {"x": 5}))) self.assertEqual(evaluate(pt("x"), {"x": 5}), 5) # Specific for Python 2. if sys.version_info[0] == 2: self.assertEqual(int, type(pt(sys.maxint).list[0][0])) self.assertEqual(pt(sys.maxint).list[0][0], sys.maxint) self.assertEqual(long, type((pt(sys.maxint) + 1).list[0][0])) self.assertEqual((pt(sys.maxint) + 1).list[0][0], sys.maxint + 1) self.assertEqual(int, type(evaluate(pt("x"), {"x": sys.maxint}))) self.assertEqual(evaluate(pt("x"), {"x": sys.maxint}), sys.maxint) self.assertEqual(long, type( evaluate(pt("x"), {"x": sys.maxint + 1}))) self.assertEqual( evaluate(pt("x"), {"x": sys.maxint + 1}), sys.maxint + 1) # Now rationals. pt = polynomial[rational, monomial[int16]]() self.assertEqual(F, type((pt(4) / 3).list[0][0])) self.assertEqual((pt(4) / 3).list[0][0], F(4, 3)) self.assertEqual(F, type(evaluate(pt("x"), {"x": F(5, 6)}))) self.assertEqual(evaluate(pt("x"), {"x": F(5, 6)}), F(5, 6)) # NOTE: if we don't go any more through str for the conversion, these types # of tests can go away. with patch_str(F, "boo"): self.assertRaises(ValueError, lambda: pt(F(5, 6))) with patch_str(F, "5/0"): self.assertRaises(ZeroDivisionError, lambda: pt(F(5, 6))) # Reals, if possible. try: from mpmath import mpf, mp, workdps, binomial as bin, fabs except ImportError: return pt = polynomial[integer, monomial[int16]]() self.assertEqual(mpf, type(evaluate(pt("x"), {"x": mpf(5)}))) self.assertEqual(evaluate(pt("x"), {"x": mpf(5)}), mpf(5)) # Check the handling of the precision. from .math import binomial # Original number of decimal digits. orig_dps = mp.dps tmp = binomial(mpf(5.1), mpf(3.2)) self.assertEqual(tmp.context.dps, orig_dps) with workdps(100): # Check that the precision is maintained on output # and that the values computed with our implementation and # mpmath are close. tmp = binomial(mpf(5.1), mpf(3.2)) self.assertEqual(tmp.context.dps, 100) self.assertTrue(fabs(tmp - bin(mpf(5.1), mpf(3.2))) < mpf('5e-100'))
[docs]class serialization_test_case(_ut.TestCase): """Test case for the serialization of series. To be used within the :mod:`unittest` framework. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(serialization_test_case) """ def runTest(self): # NOTE: this used to contain more, but now it contains # only this exception translation check. # Check msgpack exception translation. import os import shutil import tempfile from . import load_file, save_file from .types import polynomial, integer, rational, int16, monomial pt1 = polynomial[integer, monomial[int16]]() pt2 = polynomial[rational, monomial[int16]]() temp_dir = tempfile.mkdtemp() try: x = pt1('x') save_file(x, os.path.join(temp_dir, 'foo.mpackp')) ret = pt2() self.assertRaises(TypeError, lambda: load_file( ret, os.path.join(temp_dir, 'foo.mpackp'))) except NotImplementedError: pass finally: shutil.rmtree(temp_dir)
[docs]class truncate_degree_test_case(_ut.TestCase): """Test case for the degree-based truncation of series. To be used within the :mod:`unittest` framework. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(truncate_degree_test_case) """ def runTest(self): from fractions import Fraction as F from .math import truncate_degree, cos, sin, degree from .types import polynomial, int16, rational, poisson_series, monomial pt = polynomial[rational, monomial[int16]]() x, y, z = pt('x'), pt('y'), pt('z') s = x**5 * y + F(1, 2) * z**-5 * x * y + x * y * z / 4 self.assertEqual(s.truncate_degree(3), z**- 5 / 2 * x * y + x * y * z / 4) self.assertEqual(truncate_degree(s, 3), z**- 5 / 2 * x * y + x * y * z / 4) self.assertEqual(s.truncate_degree( 2, ["x"]), z**-5 / 2 * x * y + x * y * z / 4) self.assertEqual(truncate_degree( s, 2, ["x"]), z**-5 / 2 * x * y + x * y * z / 4) self.assertRaises(TypeError, lambda: truncate_degree(s, 2, ["x", 1])) self.assertRaises(TypeError, lambda: truncate_degree(s, 2, "x")) pt = poisson_series[polynomial[rational, monomial[int16]]]() x, y, z, a, b = pt("x"), pt("y"), pt("z"), pt("a"), pt("b") s = (x + y**2 / 4 + 3 * x * y * z / 7) * cos(a) + \ (x * y + y * z / 3 + 3 * z**2 * x / 8) * sin(a + b) self.assertEqual(s.truncate_degree(2), (x + y * y / 4) * cos(a) + (x * y + z * y / 3) * sin(a + b)) self.assertEqual(truncate_degree(s, 2), (x + y * y / 4) * cos(a) + (x * y + z * y / 3) * sin(a + b)) self.assertEqual(s.truncate_degree( 1, ["y", "x"]), x * cos(a) + (z * y / 3 + 3 * z * z * x / 8) * sin(a + b)) self.assertEqual(truncate_degree( s, 1, ["y", "x"]), x * cos(a) + (z * y / 3 + 3 * z * z * x / 8) * sin(a + b)) self.assertRaises(TypeError, lambda: truncate_degree(s, 2, ["x", 1])) self.assertRaises(TypeError, lambda: truncate_degree(s, 2, "x")) # Automatic truncation. # Just make sure we do not re-use any previous result. pt = polynomial[rational, monomial[int16]]() x, y = pt('x'), pt('y') pt.clear_pow_cache() self.assertEqual(pt.get_auto_truncate_degree(), (0, 0, [])) pt.set_auto_truncate_degree(4) self.assertEqual(pt.get_auto_truncate_degree(), (1, 4, [])) self.assertEqual(degree(x * x * x), 3) self.assertEqual(x * x * x * x * x, 0) pt.set_auto_truncate_degree(3, ['x', 'y']) self.assertEqual(pt.get_auto_truncate_degree(), (2, 3, ['x', 'y'])) self.assertEqual(1 + 12 * x * y + 4 * x + 12 * x**2 * y + 6 * x**2 + 4 * x**3 + 4 * y**3 + 6 * y**2 + 4 * y + 12 * x * y**2, (x + y + 1)**4) # Check throwing conversion. self.assertRaises( ValueError, lambda: pt.set_auto_truncate_degree(F(4, 3), ['x', 'y'])) self.assertEqual(pt.get_auto_truncate_degree(), (2, 3, ['x', 'y'])) # Check multiplication. self.assertEqual(degree(x * x * y), 3) self.assertEqual((x * x * y * y), 0) # Check we cannot use float for auto truncation. self.assertRaises(TypeError, lambda: pt.set_auto_truncate_degree(1.23)) # Reset before finishing. pt.unset_auto_truncate_degree() pt.clear_pow_cache() self.assertEqual(pt.get_auto_truncate_degree(), (0, 0, [])) # Explicit truncated/untruncated multiplication methods. pt = polynomial[rational, monomial[int16]]() x, y = pt('x'), pt('y') pt.clear_pow_cache() res = x**2 - y**2 res2 = -y * y res3 = x * x pt.set_auto_truncate_degree(1) self.assertEqual(pt.untruncated_multiplication(x + y, x - y), res) pt.set_auto_truncate_degree(5) self.assertEqual(pt.truncated_multiplication(x + y, x - y, 1), 0) self.assertEqual(pt.truncated_multiplication(x + y, x - y, F(1)), 0) self.assertRaises( ValueError, lambda: pt.truncated_multiplication(x + y, x - y, F(1, 2))) self.assertEqual(pt.truncated_multiplication( x + y, x - y, 1, ["x"]), res2) self.assertEqual(pt.truncated_multiplication( x + 1, x, 1, ["x", "y"]), x) self.assertRaises(ValueError, lambda: pt.truncated_multiplication( x + y, x - y, F(3, 2), ["x"])) self.assertRaises(TypeError, lambda: pt.truncated_multiplication( x + y, x - y, 3, ["x", 3])) # Reset before finishing. pt.unset_auto_truncate_degree() pt.clear_pow_cache() # Test the new behaviour of pow cache clearing. pt = polynomial[rational, monomial[int16]]() x, y = pt('x'), pt('y') self.assertEqual((x + y + 1)**2, 2 * x + 1 + 2 * y + x * x + y * y + 2 * x * y) pt.set_auto_truncate_degree(1) self.assertEqual((x + y + 1)**2, 2 * x + 1 + 2 * y) pt.set_auto_truncate_degree(1, ['x']) self.assertEqual((x + y + 1)**2, 2 * x + 1 + 2 * y + y * y + 2 * x * y) pt.set_auto_truncate_degree(1, ['y']) self.assertEqual((x + y + 1)**2, 2 * x + 1 + 2 * y + x * x + 2 * x * y) # Reset before finishing. pt.unset_auto_truncate_degree() pt.clear_pow_cache()
[docs]class integrate_test_case(_ut.TestCase): """Test case for the integration functionality. To be used within the :mod:`unittest` framework. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(integrate_test_case) """ def runTest(self): from fractions import Fraction as F from .math import sin, cos from .types import polynomial, int16, rational, poisson_series, monomial, integer pt = poisson_series[polynomial[rational, monomial[int16]]]() x, y, z = pt('x'), pt('y'), pt('z') s = F(1, 3) * z * sin(4 * x - 2 * y) self.assertEqual(s.integrate('y'), F(1, 6) * z * cos(4 * x - 2 * y)) self.assertEqual(s.integrate('z'), z**2 / 6 * sin(4 * x - 2 * y)) pt = polynomial[integer, monomial[rational]]() z = pt('z') s = z**F(3, 4) self.assertEqual(type(s), pt) self.assertEqual(s.integrate('z'), F(4, 7) * z**F(7, 4)) self.assertEqual(type(s.integrate('z')), polynomial[ rational, monomial[rational]]())
[docs]class t_integrate_test_case(_ut.TestCase): """Test case for the time integration functionality. To be used within the :mod:`unittest` framework. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(t_integrate_test_case) """ def runTest(self): from fractions import Fraction as F from .math import sin, cos from .types import polynomial, int16, rational, poisson_series, monomial, divisor, divisor_series, \ k_monomial pt = poisson_series[divisor_series[polynomial[ rational, monomial[int16]], divisor[int16]]]() x, y, z = pt('x'), pt('y'), pt('z') s = F(1, 3) * z * sin(4 * x - 2 * y) st = s.t_integrate() self.assertEqual(type(st.list[0][0]), divisor_series[ polynomial[rational, monomial[int16]], divisor[int16]]()) self.assertEqual( str(st), '-1/6*z*1/[(2*\\nu_{x}-\\nu_{y})]*cos(4*x-2*y)') st = s.t_integrate(['a', 'b']) self.assertEqual(type(st.list[0][0]), divisor_series[ polynomial[rational, monomial[int16]], divisor[int16]]()) self.assertEqual(str(st), '-1/6*z*1/[(2*a-b)]*cos(4*x-2*y)') self.assertRaises(ValueError, lambda: s.t_integrate([])) self.assertRaises(ValueError, lambda: s.t_integrate(['a', 'b', 'c'])) self.assertRaises(ValueError, lambda: s.t_integrate(['b', 'a'])) st = s.t_integrate(['a', 'b', 'b']) self.assertEqual(str(st), '-1/6*z*1/[(2*a-b)]*cos(4*x-2*y)') st = s.t_integrate(['a', 'a', 'b', 'b']) self.assertEqual(str(st), '-1/6*z*1/[(2*a-b)]*cos(4*x-2*y)') st = s.t_integrate(['a', 'a', 'b']) self.assertEqual(str(st), '-1/6*z*1/[(2*a-b)]*cos(4*x-2*y)')
[docs]class doctests_test_case(_ut.TestCase): """Test case that will run all the doctests. To be used within the :mod:`unittest` framework. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(doctests_test_case) """ def runTest(self): import doctest import pyranha from . import celmec, math, test try: doctest.testmod(pyranha, raise_on_error=True) doctest.testmod(celmec, raise_on_error=True) doctest.testmod(math, raise_on_error=True) doctest.testmod(test, raise_on_error=True) except Exception as e: self.fail(str(e))
[docs]class tutorial_test_case(_ut.TestCase): """Test case that will check the tutorial files. To be used within the :mod:`unittest` framework. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(tutorial_test_case) """ def runTest(self): from . import _tutorial
[docs]class degree_test_case(_ut.TestCase): """Test case for the degree/ldegree functionality. To be used within the :mod:`unittest` framework. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(degree_test_case) """ def runTest(self): from .types import polynomial, int16, rational, poisson_series, monomial from .math import degree, ldegree from fractions import Fraction as F pt = polynomial[rational, monomial[int16]]() x, y, z = [pt(_) for _ in 'xyz'] self.assertEqual(degree(x), 1) self.assertEqual(degree(x**2 * y**-3 * z**-4), -5) self.assertEqual(degree(x**2 * y**-3 * z**-4 + 1), 0) self.assertEqual(degree(x**2 * y**-3 * z**-4, ['x']), 2) self.assertEqual(degree(x**2 * y**-3 * z**-4, ['x', 'y']), -1) self.assertEqual(degree(x**2 * y**-3 * z**-4 + 1, ['x', 'y']), 0) self.assertRaises(TypeError, lambda: degree( x**2 * y**-3 * z**-4 + 1, [11])) self.assertEqual(ldegree(x**2 * y**-3 * z**-4 + 1), -5) self.assertEqual(ldegree(x**2 * y**-3 * z**-4 + 1, ['y']), -3) self.assertEqual(ldegree(x**2 * y**-3 * z**-4 + 1, ['y', 'z']), -7) self.assertRaises(TypeError, lambda: ldegree( x**2 * y**-3 * z**-4 + 1, [11])) pt = poisson_series[polynomial[rational, monomial[rational]]]() x, y, z = [pt(_) for _ in 'xyz'] self.assertEqual(degree(x**F(4, 5) * y**-3 * z**-4), F(4, 5) - 3 - 4) self.assertEqual(degree(x**F(4, 5) * y**-3 * z**-4 + 1), 0) self.assertEqual(degree(x**F(4, 5) * y**-3 * z**-4, ['x']), F(4, 5)) self.assertEqual(degree(x**F(4, 5) * y**-3 * z**-4, ['x', 'z']), F(4, 5) - 4) self.assertRaises(TypeError, lambda: degree( x**2 * y**-3 * z**-4 + 1, [11])) self.assertEqual(ldegree(x**F(4, 5) * y**-3 * z**-4 + 1), F(4, 5) - 3 - 4) self.assertEqual(ldegree(x**F(4, 5) * y**-3 * z**-4 + 1, ['y']), -3) self.assertEqual( ldegree(x**F(4, 5) * y**-3 * z**-4 + 1, ['y', 'z']), -7) self.assertRaises(TypeError, lambda: ldegree( x**2 * y**-3 * z**-4 + 1, [11]))
[docs]class t_degree_order_test_case(_ut.TestCase): """Test case for the t_degree/t_ldegree/t_order/t_lorder functionality. To be used within the :mod:`unittest` framework. >>> import unittest as ut >>> suite = ut.TestLoader().loadTestsFromTestCase(t_degree_order_test_case) """ def runTest(self): from .types import polynomial, int16, rational, poisson_series, monomial from .math import t_degree, t_ldegree, t_order, t_lorder, cos, sin pt = poisson_series[polynomial[rational, monomial[int16]]]() x, y, z = [pt(_) for _ in 'xyz'] self.assertEqual(t_degree(cos(x)), 1) self.assertEqual(t_degree(cos(3 * x - y)), 2) self.assertEqual(t_degree(cos(3 * x - y), ['x']), 3) self.assertRaises(TypeError, lambda: t_degree(cos(3 * x - y), [11])) self.assertEqual(t_ldegree(cos(x)), 1) self.assertEqual(t_ldegree(cos(3 * x - y) + cos(x)), 1) self.assertEqual(t_ldegree(cos(3 * x - y) + sin(y), ['x']), 0) self.assertRaises(TypeError, lambda: t_ldegree(cos(3 * x - y), [11])) self.assertEqual(t_order(cos(x)), 1) self.assertEqual(t_order(cos(3 * x - y)), 4) self.assertEqual(t_order(cos(3 * x - y), ['x']), 3) self.assertRaises(TypeError, lambda: t_order(cos(3 * x - y), [11])) self.assertEqual(t_lorder(cos(x)), 1) self.assertEqual(t_lorder(cos(3 * x - y) + cos(x - y)), 2) self.assertEqual(t_lorder(cos(3 * x - y) + sin(y), ['x']), 0) self.assertRaises(TypeError, lambda: t_lorder(cos(3 * x - y), [11]))
[docs]def run_test_suite(): """Run the full test suite. This function will raise an exception if at least one test fails. """ retval = 0 suite = _ut.TestLoader().loadTestsFromTestCase(basic_test_case) suite.addTest(series_in_place_ops_test_case()) suite.addTest(custom_derivatives_test_case()) suite.addTest(series_division_test_case()) suite.addTest(mpmath_test_case()) suite.addTest(math_test_case()) suite.addTest(polynomial_test_case()) suite.addTest(divisor_series_test_case()) suite.addTest(poisson_series_test_case()) suite.addTest(converters_test_case()) suite.addTest(serialization_test_case()) suite.addTest(integrate_test_case()) suite.addTest(t_integrate_test_case()) suite.addTest(truncate_degree_test_case()) suite.addTest(degree_test_case()) suite.addTest(t_degree_order_test_case()) suite.addTest(doctests_test_case()) test_result = _ut.TextTestRunner(verbosity=2).run(suite) if len(test_result.failures) > 0 or len(test_result.errors) > 0: retval = 1 suite = _ut.TestLoader().loadTestsFromTestCase(tutorial_test_case) # Context for the suppression of output while running the tutorials. Inspired by: # http://stackoverflow.com/questions/8522689/how-to-temporary-hide-stdout-or-stderr-while-running-a-unittest-in-python # This will temporarily replace sys.stdout with the null device. class suppress_stdout(object): def __init__(self): pass def __enter__(self): import sys import os self._stdout = sys.stdout # NOTE: originally here it was 'wb', but apparently this will create problems # in Python 3 due to the string changes. With 'wt' it seems to work ok in both Python 2 # and 3. null = open(os.devnull, 'wt') sys.stdout = null def __exit__(self, type, value, traceback): import sys sys.stdout = self._stdout with suppress_stdout(): test_result = _ut.TextTestRunner(verbosity=2).run(suite) if len(test_result.failures) > 0: retval = 1 if retval != 0: raise RuntimeError('One or more tests failed.')