Spaces:
Sleeping
Sleeping
import pytest | |
from numpy.core import array, arange, printoptions | |
import numpy.polynomial as poly | |
from numpy.testing import assert_equal, assert_ | |
# For testing polynomial printing with object arrays | |
from fractions import Fraction | |
from decimal import Decimal | |
class TestStrUnicodeSuperSubscripts: | |
def use_unicode(self): | |
poly.set_default_printstyle('unicode') | |
def test_polynomial_str(self, inp, tgt): | |
res = str(poly.Polynomial(inp)) | |
assert_equal(res, tgt) | |
def test_chebyshev_str(self, inp, tgt): | |
res = str(poly.Chebyshev(inp)) | |
assert_equal(res, tgt) | |
def test_legendre_str(self, inp, tgt): | |
res = str(poly.Legendre(inp)) | |
assert_equal(res, tgt) | |
def test_hermite_str(self, inp, tgt): | |
res = str(poly.Hermite(inp)) | |
assert_equal(res, tgt) | |
def test_hermiteE_str(self, inp, tgt): | |
res = str(poly.HermiteE(inp)) | |
assert_equal(res, tgt) | |
def test_laguerre_str(self, inp, tgt): | |
res = str(poly.Laguerre(inp)) | |
assert_equal(res, tgt) | |
class TestStrAscii: | |
def use_ascii(self): | |
poly.set_default_printstyle('ascii') | |
def test_polynomial_str(self, inp, tgt): | |
res = str(poly.Polynomial(inp)) | |
assert_equal(res, tgt) | |
def test_chebyshev_str(self, inp, tgt): | |
res = str(poly.Chebyshev(inp)) | |
assert_equal(res, tgt) | |
def test_legendre_str(self, inp, tgt): | |
res = str(poly.Legendre(inp)) | |
assert_equal(res, tgt) | |
def test_hermite_str(self, inp, tgt): | |
res = str(poly.Hermite(inp)) | |
assert_equal(res, tgt) | |
def test_hermiteE_str(self, inp, tgt): | |
res = str(poly.HermiteE(inp)) | |
assert_equal(res, tgt) | |
def test_laguerre_str(self, inp, tgt): | |
res = str(poly.Laguerre(inp)) | |
assert_equal(res, tgt) | |
class TestLinebreaking: | |
def use_ascii(self): | |
poly.set_default_printstyle('ascii') | |
def test_single_line_one_less(self): | |
# With 'ascii' style, len(str(p)) is default linewidth - 1 (i.e. 74) | |
p = poly.Polynomial([123456789, 123456789, 123456789, 1234, 1]) | |
assert_equal(len(str(p)), 74) | |
assert_equal(str(p), ( | |
'123456789.0 + 123456789.0 x**1 + 123456789.0 x**2 + ' | |
'1234.0 x**3 + 1.0 x**4' | |
)) | |
def test_num_chars_is_linewidth(self): | |
# len(str(p)) == default linewidth == 75 | |
p = poly.Polynomial([123456789, 123456789, 123456789, 1234, 10]) | |
assert_equal(len(str(p)), 75) | |
assert_equal(str(p), ( | |
'123456789.0 + 123456789.0 x**1 + 123456789.0 x**2 + ' | |
'1234.0 x**3 +\n10.0 x**4' | |
)) | |
def test_first_linebreak_multiline_one_less_than_linewidth(self): | |
# Multiline str where len(first_line) + len(next_term) == lw - 1 == 74 | |
p = poly.Polynomial( | |
[123456789, 123456789, 123456789, 12, 1, 123456789] | |
) | |
assert_equal(len(str(p).split('\n')[0]), 74) | |
assert_equal(str(p), ( | |
'123456789.0 + 123456789.0 x**1 + 123456789.0 x**2 + ' | |
'12.0 x**3 + 1.0 x**4 +\n123456789.0 x**5' | |
)) | |
def test_first_linebreak_multiline_on_linewidth(self): | |
# First line is one character longer than previous test | |
p = poly.Polynomial( | |
[123456789, 123456789, 123456789, 123, 1, 123456789] | |
) | |
assert_equal(str(p), ( | |
'123456789.0 + 123456789.0 x**1 + 123456789.0 x**2 + ' | |
'123.0 x**3 +\n1.0 x**4 + 123456789.0 x**5' | |
)) | |
def test_linewidth_printoption(self, lw, tgt): | |
p = poly.Polynomial( | |
[0, 10, 200, 3000, 40000, 500000, 600000, 70000, 8000, 900] | |
) | |
with printoptions(linewidth=lw): | |
assert_equal(str(p), tgt) | |
for line in str(p).split('\n'): | |
assert_(len(line) < lw) | |
def test_set_default_printoptions(): | |
p = poly.Polynomial([1, 2, 3]) | |
c = poly.Chebyshev([1, 2, 3]) | |
poly.set_default_printstyle('ascii') | |
assert_equal(str(p), "1.0 + 2.0 x**1 + 3.0 x**2") | |
assert_equal(str(c), "1.0 + 2.0 T_1(x) + 3.0 T_2(x)") | |
poly.set_default_printstyle('unicode') | |
assert_equal(str(p), "1.0 + 2.0·x¹ + 3.0·x²") | |
assert_equal(str(c), "1.0 + 2.0·T₁(x) + 3.0·T₂(x)") | |
with pytest.raises(ValueError): | |
poly.set_default_printstyle('invalid_input') | |
def test_complex_coefficients(): | |
"""Test both numpy and built-in complex.""" | |
coefs = [0+1j, 1+1j, -2+2j, 3+0j] | |
# numpy complex | |
p1 = poly.Polynomial(coefs) | |
# Python complex | |
p2 = poly.Polynomial(array(coefs, dtype=object)) | |
poly.set_default_printstyle('unicode') | |
assert_equal(str(p1), "1j + (1+1j)·x¹ - (2-2j)·x² + (3+0j)·x³") | |
assert_equal(str(p2), "1j + (1+1j)·x¹ + (-2+2j)·x² + (3+0j)·x³") | |
poly.set_default_printstyle('ascii') | |
assert_equal(str(p1), "1j + (1+1j) x**1 - (2-2j) x**2 + (3+0j) x**3") | |
assert_equal(str(p2), "1j + (1+1j) x**1 + (-2+2j) x**2 + (3+0j) x**3") | |
def test_numeric_object_coefficients(coefs, tgt): | |
p = poly.Polynomial(coefs) | |
poly.set_default_printstyle('unicode') | |
assert_equal(str(p), tgt) | |
def test_nonnumeric_object_coefficients(coefs, tgt): | |
""" | |
Test coef fallback for object arrays of non-numeric coefficients. | |
""" | |
p = poly.Polynomial(coefs) | |
poly.set_default_printstyle('unicode') | |
assert_equal(str(p), tgt) | |
class TestFormat: | |
def test_format_unicode(self): | |
poly.set_default_printstyle('ascii') | |
p = poly.Polynomial([1, 2, 0, -1]) | |
assert_equal(format(p, 'unicode'), "1.0 + 2.0·x¹ + 0.0·x² - 1.0·x³") | |
def test_format_ascii(self): | |
poly.set_default_printstyle('unicode') | |
p = poly.Polynomial([1, 2, 0, -1]) | |
assert_equal( | |
format(p, 'ascii'), "1.0 + 2.0 x**1 + 0.0 x**2 - 1.0 x**3" | |
) | |
def test_empty_formatstr(self): | |
poly.set_default_printstyle('ascii') | |
p = poly.Polynomial([1, 2, 3]) | |
assert_equal(format(p), "1.0 + 2.0 x**1 + 3.0 x**2") | |
assert_equal(f"{p}", "1.0 + 2.0 x**1 + 3.0 x**2") | |
def test_bad_formatstr(self): | |
p = poly.Polynomial([1, 2, 0, -1]) | |
with pytest.raises(ValueError): | |
format(p, '.2f') | |
class TestRepr: | |
def test_polynomial_str(self): | |
res = repr(poly.Polynomial([0, 1])) | |
tgt = 'Polynomial([0., 1.], domain=[-1, 1], window=[-1, 1])' | |
assert_equal(res, tgt) | |
def test_chebyshev_str(self): | |
res = repr(poly.Chebyshev([0, 1])) | |
tgt = 'Chebyshev([0., 1.], domain=[-1, 1], window=[-1, 1])' | |
assert_equal(res, tgt) | |
def test_legendre_repr(self): | |
res = repr(poly.Legendre([0, 1])) | |
tgt = 'Legendre([0., 1.], domain=[-1, 1], window=[-1, 1])' | |
assert_equal(res, tgt) | |
def test_hermite_repr(self): | |
res = repr(poly.Hermite([0, 1])) | |
tgt = 'Hermite([0., 1.], domain=[-1, 1], window=[-1, 1])' | |
assert_equal(res, tgt) | |
def test_hermiteE_repr(self): | |
res = repr(poly.HermiteE([0, 1])) | |
tgt = 'HermiteE([0., 1.], domain=[-1, 1], window=[-1, 1])' | |
assert_equal(res, tgt) | |
def test_laguerre_repr(self): | |
res = repr(poly.Laguerre([0, 1])) | |
tgt = 'Laguerre([0., 1.], domain=[0, 1], window=[0, 1])' | |
assert_equal(res, tgt) | |
class TestLatexRepr: | |
"""Test the latex repr used by Jupyter""" | |
def as_latex(self, obj): | |
# right now we ignore the formatting of scalars in our tests, since | |
# it makes them too verbose. Ideally, the formatting of scalars will | |
# be fixed such that tests below continue to pass | |
obj._repr_latex_scalar = lambda x: str(x) | |
try: | |
return obj._repr_latex_() | |
finally: | |
del obj._repr_latex_scalar | |
def test_simple_polynomial(self): | |
# default input | |
p = poly.Polynomial([1, 2, 3]) | |
assert_equal(self.as_latex(p), | |
r'$x \mapsto 1.0 + 2.0\,x + 3.0\,x^{2}$') | |
# translated input | |
p = poly.Polynomial([1, 2, 3], domain=[-2, 0]) | |
assert_equal(self.as_latex(p), | |
r'$x \mapsto 1.0 + 2.0\,\left(1.0 + x\right) + 3.0\,\left(1.0 + x\right)^{2}$') | |
# scaled input | |
p = poly.Polynomial([1, 2, 3], domain=[-0.5, 0.5]) | |
assert_equal(self.as_latex(p), | |
r'$x \mapsto 1.0 + 2.0\,\left(2.0x\right) + 3.0\,\left(2.0x\right)^{2}$') | |
# affine input | |
p = poly.Polynomial([1, 2, 3], domain=[-1, 0]) | |
assert_equal(self.as_latex(p), | |
r'$x \mapsto 1.0 + 2.0\,\left(1.0 + 2.0x\right) + 3.0\,\left(1.0 + 2.0x\right)^{2}$') | |
def test_basis_func(self): | |
p = poly.Chebyshev([1, 2, 3]) | |
assert_equal(self.as_latex(p), | |
r'$x \mapsto 1.0\,{T}_{0}(x) + 2.0\,{T}_{1}(x) + 3.0\,{T}_{2}(x)$') | |
# affine input - check no surplus parens are added | |
p = poly.Chebyshev([1, 2, 3], domain=[-1, 0]) | |
assert_equal(self.as_latex(p), | |
r'$x \mapsto 1.0\,{T}_{0}(1.0 + 2.0x) + 2.0\,{T}_{1}(1.0 + 2.0x) + 3.0\,{T}_{2}(1.0 + 2.0x)$') | |
def test_multichar_basis_func(self): | |
p = poly.HermiteE([1, 2, 3]) | |
assert_equal(self.as_latex(p), | |
r'$x \mapsto 1.0\,{He}_{0}(x) + 2.0\,{He}_{1}(x) + 3.0\,{He}_{2}(x)$') | |