aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/numpy/polynomial/tests
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/numpy/polynomial/tests
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are hereHEADmaster
Diffstat (limited to '.venv/lib/python3.12/site-packages/numpy/polynomial/tests')
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/__init__.py0
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_chebyshev.py619
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_classes.py600
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_hermite.py555
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_hermite_e.py556
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_laguerre.py537
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_legendre.py568
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_polynomial.py611
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_polyutils.py121
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_printing.py530
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_symbol.py216
11 files changed, 4913 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/__init__.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/__init__.py
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_chebyshev.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_chebyshev.py
new file mode 100644
index 00000000..2f54bebf
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_chebyshev.py
@@ -0,0 +1,619 @@
+"""Tests for chebyshev module.
+
+"""
+from functools import reduce
+
+import numpy as np
+import numpy.polynomial.chebyshev as cheb
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+ assert_almost_equal, assert_raises, assert_equal, assert_,
+ )
+
+
+def trim(x):
+ return cheb.chebtrim(x, tol=1e-6)
+
+T0 = [1]
+T1 = [0, 1]
+T2 = [-1, 0, 2]
+T3 = [0, -3, 0, 4]
+T4 = [1, 0, -8, 0, 8]
+T5 = [0, 5, 0, -20, 0, 16]
+T6 = [-1, 0, 18, 0, -48, 0, 32]
+T7 = [0, -7, 0, 56, 0, -112, 0, 64]
+T8 = [1, 0, -32, 0, 160, 0, -256, 0, 128]
+T9 = [0, 9, 0, -120, 0, 432, 0, -576, 0, 256]
+
+Tlist = [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]
+
+
+class TestPrivate:
+
+ def test__cseries_to_zseries(self):
+ for i in range(5):
+ inp = np.array([2] + [1]*i, np.double)
+ tgt = np.array([.5]*i + [2] + [.5]*i, np.double)
+ res = cheb._cseries_to_zseries(inp)
+ assert_equal(res, tgt)
+
+ def test__zseries_to_cseries(self):
+ for i in range(5):
+ inp = np.array([.5]*i + [2] + [.5]*i, np.double)
+ tgt = np.array([2] + [1]*i, np.double)
+ res = cheb._zseries_to_cseries(inp)
+ assert_equal(res, tgt)
+
+
+class TestConstants:
+
+ def test_chebdomain(self):
+ assert_equal(cheb.chebdomain, [-1, 1])
+
+ def test_chebzero(self):
+ assert_equal(cheb.chebzero, [0])
+
+ def test_chebone(self):
+ assert_equal(cheb.chebone, [1])
+
+ def test_chebx(self):
+ assert_equal(cheb.chebx, [0, 1])
+
+
+class TestArithmetic:
+
+ def test_chebadd(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] += 1
+ res = cheb.chebadd([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_chebsub(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] -= 1
+ res = cheb.chebsub([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_chebmulx(self):
+ assert_equal(cheb.chebmulx([0]), [0])
+ assert_equal(cheb.chebmulx([1]), [0, 1])
+ for i in range(1, 5):
+ ser = [0]*i + [1]
+ tgt = [0]*(i - 1) + [.5, 0, .5]
+ assert_equal(cheb.chebmulx(ser), tgt)
+
+ def test_chebmul(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(i + j + 1)
+ tgt[i + j] += .5
+ tgt[abs(i - j)] += .5
+ res = cheb.chebmul([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_chebdiv(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ ci = [0]*i + [1]
+ cj = [0]*j + [1]
+ tgt = cheb.chebadd(ci, cj)
+ quo, rem = cheb.chebdiv(tgt, ci)
+ res = cheb.chebadd(cheb.chebmul(quo, ci), rem)
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_chebpow(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ c = np.arange(i + 1)
+ tgt = reduce(cheb.chebmul, [c]*j, np.array([1]))
+ res = cheb.chebpow(c, j)
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation:
+ # coefficients of 1 + 2*x + 3*x**2
+ c1d = np.array([2.5, 2., 1.5])
+ c2d = np.einsum('i,j->ij', c1d, c1d)
+ c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+ y = polyval(x, [1., 2., 3.])
+
+ def test_chebval(self):
+ #check empty input
+ assert_equal(cheb.chebval([], [1]).size, 0)
+
+ #check normal input)
+ x = np.linspace(-1, 1)
+ y = [polyval(x, c) for c in Tlist]
+ for i in range(10):
+ msg = f"At i={i}"
+ tgt = y[i]
+ res = cheb.chebval(x, [0]*i + [1])
+ assert_almost_equal(res, tgt, err_msg=msg)
+
+ #check that shape is preserved
+ for i in range(3):
+ dims = [2]*i
+ x = np.zeros(dims)
+ assert_equal(cheb.chebval(x, [1]).shape, dims)
+ assert_equal(cheb.chebval(x, [1, 0]).shape, dims)
+ assert_equal(cheb.chebval(x, [1, 0, 0]).shape, dims)
+
+ def test_chebval2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises(ValueError, cheb.chebval2d, x1, x2[:2], self.c2d)
+
+ #test values
+ tgt = y1*y2
+ res = cheb.chebval2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = cheb.chebval2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3))
+
+ def test_chebval3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises(ValueError, cheb.chebval3d, x1, x2, x3[:2], self.c3d)
+
+ #test values
+ tgt = y1*y2*y3
+ res = cheb.chebval3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = cheb.chebval3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3))
+
+ def test_chebgrid2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j->ij', y1, y2)
+ res = cheb.chebgrid2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = cheb.chebgrid2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3)*2)
+
+ def test_chebgrid3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+ res = cheb.chebgrid3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = cheb.chebgrid3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral:
+
+ def test_chebint(self):
+ # check exceptions
+ assert_raises(TypeError, cheb.chebint, [0], .5)
+ assert_raises(ValueError, cheb.chebint, [0], -1)
+ assert_raises(ValueError, cheb.chebint, [0], 1, [0, 0])
+ assert_raises(ValueError, cheb.chebint, [0], lbnd=[0])
+ assert_raises(ValueError, cheb.chebint, [0], scl=[0])
+ assert_raises(TypeError, cheb.chebint, [0], axis=.5)
+
+ # test integration of zero polynomial
+ for i in range(2, 5):
+ k = [0]*(i - 2) + [1]
+ res = cheb.chebint([0], m=i, k=k)
+ assert_almost_equal(res, [0, 1])
+
+ # check single integration with integration constant
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [1/scl]
+ chebpol = cheb.poly2cheb(pol)
+ chebint = cheb.chebint(chebpol, m=1, k=[i])
+ res = cheb.cheb2poly(chebint)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check single integration with integration constant and lbnd
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ chebpol = cheb.poly2cheb(pol)
+ chebint = cheb.chebint(chebpol, m=1, k=[i], lbnd=-1)
+ assert_almost_equal(cheb.chebval(-1, chebint), i)
+
+ # check single integration with integration constant and scaling
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [2/scl]
+ chebpol = cheb.poly2cheb(pol)
+ chebint = cheb.chebint(chebpol, m=1, k=[i], scl=2)
+ res = cheb.cheb2poly(chebint)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with default k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = cheb.chebint(tgt, m=1)
+ res = cheb.chebint(pol, m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with defined k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = cheb.chebint(tgt, m=1, k=[k])
+ res = cheb.chebint(pol, m=j, k=list(range(j)))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with lbnd
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = cheb.chebint(tgt, m=1, k=[k], lbnd=-1)
+ res = cheb.chebint(pol, m=j, k=list(range(j)), lbnd=-1)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = cheb.chebint(tgt, m=1, k=[k], scl=2)
+ res = cheb.chebint(pol, m=j, k=list(range(j)), scl=2)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_chebint_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([cheb.chebint(c) for c in c2d.T]).T
+ res = cheb.chebint(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([cheb.chebint(c) for c in c2d])
+ res = cheb.chebint(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([cheb.chebint(c, k=3) for c in c2d])
+ res = cheb.chebint(c2d, k=3, axis=1)
+ assert_almost_equal(res, tgt)
+
+
+class TestDerivative:
+
+ def test_chebder(self):
+ # check exceptions
+ assert_raises(TypeError, cheb.chebder, [0], .5)
+ assert_raises(ValueError, cheb.chebder, [0], -1)
+
+ # check that zeroth derivative does nothing
+ for i in range(5):
+ tgt = [0]*i + [1]
+ res = cheb.chebder(tgt, m=0)
+ assert_equal(trim(res), trim(tgt))
+
+ # check that derivation is the inverse of integration
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = cheb.chebder(cheb.chebint(tgt, m=j), m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check derivation with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = cheb.chebder(cheb.chebint(tgt, m=j, scl=2), m=j, scl=.5)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_chebder_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([cheb.chebder(c) for c in c2d.T]).T
+ res = cheb.chebder(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([cheb.chebder(c) for c in c2d])
+ res = cheb.chebder(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+
+class TestVander:
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+
+ def test_chebvander(self):
+ # check for 1d x
+ x = np.arange(3)
+ v = cheb.chebvander(x, 3)
+ assert_(v.shape == (3, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], cheb.chebval(x, coef))
+
+ # check for 2d x
+ x = np.array([[1, 2], [3, 4], [5, 6]])
+ v = cheb.chebvander(x, 3)
+ assert_(v.shape == (3, 2, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], cheb.chebval(x, coef))
+
+ def test_chebvander2d(self):
+ # also tests chebval2d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3))
+ van = cheb.chebvander2d(x1, x2, [1, 2])
+ tgt = cheb.chebval2d(x1, x2, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = cheb.chebvander2d([x1], [x2], [1, 2])
+ assert_(van.shape == (1, 5, 6))
+
+ def test_chebvander3d(self):
+ # also tests chebval3d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3, 4))
+ van = cheb.chebvander3d(x1, x2, x3, [1, 2, 3])
+ tgt = cheb.chebval3d(x1, x2, x3, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = cheb.chebvander3d([x1], [x2], [x3], [1, 2, 3])
+ assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting:
+
+ def test_chebfit(self):
+ def f(x):
+ return x*(x - 1)*(x - 2)
+
+ def f2(x):
+ return x**4 + x**2 + 1
+
+ # Test exceptions
+ assert_raises(ValueError, cheb.chebfit, [1], [1], -1)
+ assert_raises(TypeError, cheb.chebfit, [[1]], [1], 0)
+ assert_raises(TypeError, cheb.chebfit, [], [1], 0)
+ assert_raises(TypeError, cheb.chebfit, [1], [[[1]]], 0)
+ assert_raises(TypeError, cheb.chebfit, [1, 2], [1], 0)
+ assert_raises(TypeError, cheb.chebfit, [1], [1, 2], 0)
+ assert_raises(TypeError, cheb.chebfit, [1], [1], 0, w=[[1]])
+ assert_raises(TypeError, cheb.chebfit, [1], [1], 0, w=[1, 1])
+ assert_raises(ValueError, cheb.chebfit, [1], [1], [-1,])
+ assert_raises(ValueError, cheb.chebfit, [1], [1], [2, -1, 6])
+ assert_raises(TypeError, cheb.chebfit, [1], [1], [])
+
+ # Test fit
+ x = np.linspace(0, 2)
+ y = f(x)
+ #
+ coef3 = cheb.chebfit(x, y, 3)
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(cheb.chebval(x, coef3), y)
+ coef3 = cheb.chebfit(x, y, [0, 1, 2, 3])
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(cheb.chebval(x, coef3), y)
+ #
+ coef4 = cheb.chebfit(x, y, 4)
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(cheb.chebval(x, coef4), y)
+ coef4 = cheb.chebfit(x, y, [0, 1, 2, 3, 4])
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(cheb.chebval(x, coef4), y)
+ # check things still work if deg is not in strict increasing
+ coef4 = cheb.chebfit(x, y, [2, 3, 4, 1, 0])
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(cheb.chebval(x, coef4), y)
+ #
+ coef2d = cheb.chebfit(x, np.array([y, y]).T, 3)
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ coef2d = cheb.chebfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ # test weighting
+ w = np.zeros_like(x)
+ yw = y.copy()
+ w[1::2] = 1
+ y[0::2] = 0
+ wcoef3 = cheb.chebfit(x, yw, 3, w=w)
+ assert_almost_equal(wcoef3, coef3)
+ wcoef3 = cheb.chebfit(x, yw, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef3, coef3)
+ #
+ wcoef2d = cheb.chebfit(x, np.array([yw, yw]).T, 3, w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ wcoef2d = cheb.chebfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ # test scaling with complex values x points whose square
+ # is zero when summed.
+ x = [1, 1j, -1, -1j]
+ assert_almost_equal(cheb.chebfit(x, x, 1), [0, 1])
+ assert_almost_equal(cheb.chebfit(x, x, [0, 1]), [0, 1])
+ # test fitting only even polynomials
+ x = np.linspace(-1, 1)
+ y = f2(x)
+ coef1 = cheb.chebfit(x, y, 4)
+ assert_almost_equal(cheb.chebval(x, coef1), y)
+ coef2 = cheb.chebfit(x, y, [0, 2, 4])
+ assert_almost_equal(cheb.chebval(x, coef2), y)
+ assert_almost_equal(coef1, coef2)
+
+
+class TestInterpolate:
+
+ def f(self, x):
+ return x * (x - 1) * (x - 2)
+
+ def test_raises(self):
+ assert_raises(ValueError, cheb.chebinterpolate, self.f, -1)
+ assert_raises(TypeError, cheb.chebinterpolate, self.f, 10.)
+
+ def test_dimensions(self):
+ for deg in range(1, 5):
+ assert_(cheb.chebinterpolate(self.f, deg).shape == (deg + 1,))
+
+ def test_approximation(self):
+
+ def powx(x, p):
+ return x**p
+
+ x = np.linspace(-1, 1, 10)
+ for deg in range(0, 10):
+ for p in range(0, deg + 1):
+ c = cheb.chebinterpolate(powx, deg, (p,))
+ assert_almost_equal(cheb.chebval(x, c), powx(x, p), decimal=12)
+
+
+class TestCompanion:
+
+ def test_raises(self):
+ assert_raises(ValueError, cheb.chebcompanion, [])
+ assert_raises(ValueError, cheb.chebcompanion, [1])
+
+ def test_dimensions(self):
+ for i in range(1, 5):
+ coef = [0]*i + [1]
+ assert_(cheb.chebcompanion(coef).shape == (i, i))
+
+ def test_linear_root(self):
+ assert_(cheb.chebcompanion([1, 2])[0, 0] == -.5)
+
+
+class TestGauss:
+
+ def test_100(self):
+ x, w = cheb.chebgauss(100)
+
+ # test orthogonality. Note that the results need to be normalized,
+ # otherwise the huge values that can arise from fast growing
+ # functions like Laguerre can be very confusing.
+ v = cheb.chebvander(x, 99)
+ vv = np.dot(v.T * w, v)
+ vd = 1/np.sqrt(vv.diagonal())
+ vv = vd[:, None] * vv * vd
+ assert_almost_equal(vv, np.eye(100))
+
+ # check that the integral of 1 is correct
+ tgt = np.pi
+ assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc:
+
+ def test_chebfromroots(self):
+ res = cheb.chebfromroots([])
+ assert_almost_equal(trim(res), [1])
+ for i in range(1, 5):
+ roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+ tgt = [0]*i + [1]
+ res = cheb.chebfromroots(roots)*2**(i-1)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_chebroots(self):
+ assert_almost_equal(cheb.chebroots([1]), [])
+ assert_almost_equal(cheb.chebroots([1, 2]), [-.5])
+ for i in range(2, 5):
+ tgt = np.linspace(-1, 1, i)
+ res = cheb.chebroots(cheb.chebfromroots(tgt))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_chebtrim(self):
+ coef = [2, -1, 1, 0]
+
+ # Test exceptions
+ assert_raises(ValueError, cheb.chebtrim, coef, -1)
+
+ # Test results
+ assert_equal(cheb.chebtrim(coef), coef[:-1])
+ assert_equal(cheb.chebtrim(coef, 1), coef[:-3])
+ assert_equal(cheb.chebtrim(coef, 2), [0])
+
+ def test_chebline(self):
+ assert_equal(cheb.chebline(3, 4), [3, 4])
+
+ def test_cheb2poly(self):
+ for i in range(10):
+ assert_almost_equal(cheb.cheb2poly([0]*i + [1]), Tlist[i])
+
+ def test_poly2cheb(self):
+ for i in range(10):
+ assert_almost_equal(cheb.poly2cheb(Tlist[i]), [0]*i + [1])
+
+ def test_weight(self):
+ x = np.linspace(-1, 1, 11)[1:-1]
+ tgt = 1./(np.sqrt(1 + x) * np.sqrt(1 - x))
+ res = cheb.chebweight(x)
+ assert_almost_equal(res, tgt)
+
+ def test_chebpts1(self):
+ #test exceptions
+ assert_raises(ValueError, cheb.chebpts1, 1.5)
+ assert_raises(ValueError, cheb.chebpts1, 0)
+
+ #test points
+ tgt = [0]
+ assert_almost_equal(cheb.chebpts1(1), tgt)
+ tgt = [-0.70710678118654746, 0.70710678118654746]
+ assert_almost_equal(cheb.chebpts1(2), tgt)
+ tgt = [-0.86602540378443871, 0, 0.86602540378443871]
+ assert_almost_equal(cheb.chebpts1(3), tgt)
+ tgt = [-0.9238795325, -0.3826834323, 0.3826834323, 0.9238795325]
+ assert_almost_equal(cheb.chebpts1(4), tgt)
+
+ def test_chebpts2(self):
+ #test exceptions
+ assert_raises(ValueError, cheb.chebpts2, 1.5)
+ assert_raises(ValueError, cheb.chebpts2, 1)
+
+ #test points
+ tgt = [-1, 1]
+ assert_almost_equal(cheb.chebpts2(2), tgt)
+ tgt = [-1, 0, 1]
+ assert_almost_equal(cheb.chebpts2(3), tgt)
+ tgt = [-1, -0.5, .5, 1]
+ assert_almost_equal(cheb.chebpts2(4), tgt)
+ tgt = [-1.0, -0.707106781187, 0, 0.707106781187, 1.0]
+ assert_almost_equal(cheb.chebpts2(5), tgt)
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_classes.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_classes.py
new file mode 100644
index 00000000..6322062f
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_classes.py
@@ -0,0 +1,600 @@
+"""Test inter-conversion of different polynomial classes.
+
+This tests the convert and cast methods of all the polynomial classes.
+
+"""
+import operator as op
+from numbers import Number
+
+import pytest
+import numpy as np
+from numpy.polynomial import (
+ Polynomial, Legendre, Chebyshev, Laguerre, Hermite, HermiteE)
+from numpy.testing import (
+ assert_almost_equal, assert_raises, assert_equal, assert_,
+ )
+from numpy.polynomial.polyutils import RankWarning
+
+#
+# fixtures
+#
+
+classes = (
+ Polynomial, Legendre, Chebyshev, Laguerre,
+ Hermite, HermiteE
+ )
+classids = tuple(cls.__name__ for cls in classes)
+
+@pytest.fixture(params=classes, ids=classids)
+def Poly(request):
+ return request.param
+
+#
+# helper functions
+#
+random = np.random.random
+
+
+def assert_poly_almost_equal(p1, p2, msg=""):
+ try:
+ assert_(np.all(p1.domain == p2.domain))
+ assert_(np.all(p1.window == p2.window))
+ assert_almost_equal(p1.coef, p2.coef)
+ except AssertionError:
+ msg = f"Result: {p1}\nTarget: {p2}"
+ raise AssertionError(msg)
+
+
+#
+# Test conversion methods that depend on combinations of two classes.
+#
+
+Poly1 = Poly
+Poly2 = Poly
+
+
+def test_conversion(Poly1, Poly2):
+ x = np.linspace(0, 1, 10)
+ coef = random((3,))
+
+ d1 = Poly1.domain + random((2,))*.25
+ w1 = Poly1.window + random((2,))*.25
+ p1 = Poly1(coef, domain=d1, window=w1)
+
+ d2 = Poly2.domain + random((2,))*.25
+ w2 = Poly2.window + random((2,))*.25
+ p2 = p1.convert(kind=Poly2, domain=d2, window=w2)
+
+ assert_almost_equal(p2.domain, d2)
+ assert_almost_equal(p2.window, w2)
+ assert_almost_equal(p2(x), p1(x))
+
+
+def test_cast(Poly1, Poly2):
+ x = np.linspace(0, 1, 10)
+ coef = random((3,))
+
+ d1 = Poly1.domain + random((2,))*.25
+ w1 = Poly1.window + random((2,))*.25
+ p1 = Poly1(coef, domain=d1, window=w1)
+
+ d2 = Poly2.domain + random((2,))*.25
+ w2 = Poly2.window + random((2,))*.25
+ p2 = Poly2.cast(p1, domain=d2, window=w2)
+
+ assert_almost_equal(p2.domain, d2)
+ assert_almost_equal(p2.window, w2)
+ assert_almost_equal(p2(x), p1(x))
+
+
+#
+# test methods that depend on one class
+#
+
+
+def test_identity(Poly):
+ d = Poly.domain + random((2,))*.25
+ w = Poly.window + random((2,))*.25
+ x = np.linspace(d[0], d[1], 11)
+ p = Poly.identity(domain=d, window=w)
+ assert_equal(p.domain, d)
+ assert_equal(p.window, w)
+ assert_almost_equal(p(x), x)
+
+
+def test_basis(Poly):
+ d = Poly.domain + random((2,))*.25
+ w = Poly.window + random((2,))*.25
+ p = Poly.basis(5, domain=d, window=w)
+ assert_equal(p.domain, d)
+ assert_equal(p.window, w)
+ assert_equal(p.coef, [0]*5 + [1])
+
+
+def test_fromroots(Poly):
+ # check that requested roots are zeros of a polynomial
+ # of correct degree, domain, and window.
+ d = Poly.domain + random((2,))*.25
+ w = Poly.window + random((2,))*.25
+ r = random((5,))
+ p1 = Poly.fromroots(r, domain=d, window=w)
+ assert_equal(p1.degree(), len(r))
+ assert_equal(p1.domain, d)
+ assert_equal(p1.window, w)
+ assert_almost_equal(p1(r), 0)
+
+ # check that polynomial is monic
+ pdom = Polynomial.domain
+ pwin = Polynomial.window
+ p2 = Polynomial.cast(p1, domain=pdom, window=pwin)
+ assert_almost_equal(p2.coef[-1], 1)
+
+
+def test_bad_conditioned_fit(Poly):
+
+ x = [0., 0., 1.]
+ y = [1., 2., 3.]
+
+ # check RankWarning is raised
+ with pytest.warns(RankWarning) as record:
+ Poly.fit(x, y, 2)
+ assert record[0].message.args[0] == "The fit may be poorly conditioned"
+
+
+def test_fit(Poly):
+
+ def f(x):
+ return x*(x - 1)*(x - 2)
+ x = np.linspace(0, 3)
+ y = f(x)
+
+ # check default value of domain and window
+ p = Poly.fit(x, y, 3)
+ assert_almost_equal(p.domain, [0, 3])
+ assert_almost_equal(p(x), y)
+ assert_equal(p.degree(), 3)
+
+ # check with given domains and window
+ d = Poly.domain + random((2,))*.25
+ w = Poly.window + random((2,))*.25
+ p = Poly.fit(x, y, 3, domain=d, window=w)
+ assert_almost_equal(p(x), y)
+ assert_almost_equal(p.domain, d)
+ assert_almost_equal(p.window, w)
+ p = Poly.fit(x, y, [0, 1, 2, 3], domain=d, window=w)
+ assert_almost_equal(p(x), y)
+ assert_almost_equal(p.domain, d)
+ assert_almost_equal(p.window, w)
+
+ # check with class domain default
+ p = Poly.fit(x, y, 3, [])
+ assert_equal(p.domain, Poly.domain)
+ assert_equal(p.window, Poly.window)
+ p = Poly.fit(x, y, [0, 1, 2, 3], [])
+ assert_equal(p.domain, Poly.domain)
+ assert_equal(p.window, Poly.window)
+
+ # check that fit accepts weights.
+ w = np.zeros_like(x)
+ z = y + random(y.shape)*.25
+ w[::2] = 1
+ p1 = Poly.fit(x[::2], z[::2], 3)
+ p2 = Poly.fit(x, z, 3, w=w)
+ p3 = Poly.fit(x, z, [0, 1, 2, 3], w=w)
+ assert_almost_equal(p1(x), p2(x))
+ assert_almost_equal(p2(x), p3(x))
+
+
+def test_equal(Poly):
+ p1 = Poly([1, 2, 3], domain=[0, 1], window=[2, 3])
+ p2 = Poly([1, 1, 1], domain=[0, 1], window=[2, 3])
+ p3 = Poly([1, 2, 3], domain=[1, 2], window=[2, 3])
+ p4 = Poly([1, 2, 3], domain=[0, 1], window=[1, 2])
+ assert_(p1 == p1)
+ assert_(not p1 == p2)
+ assert_(not p1 == p3)
+ assert_(not p1 == p4)
+
+
+def test_not_equal(Poly):
+ p1 = Poly([1, 2, 3], domain=[0, 1], window=[2, 3])
+ p2 = Poly([1, 1, 1], domain=[0, 1], window=[2, 3])
+ p3 = Poly([1, 2, 3], domain=[1, 2], window=[2, 3])
+ p4 = Poly([1, 2, 3], domain=[0, 1], window=[1, 2])
+ assert_(not p1 != p1)
+ assert_(p1 != p2)
+ assert_(p1 != p3)
+ assert_(p1 != p4)
+
+
+def test_add(Poly):
+ # This checks commutation, not numerical correctness
+ c1 = list(random((4,)) + .5)
+ c2 = list(random((3,)) + .5)
+ p1 = Poly(c1)
+ p2 = Poly(c2)
+ p3 = p1 + p2
+ assert_poly_almost_equal(p2 + p1, p3)
+ assert_poly_almost_equal(p1 + c2, p3)
+ assert_poly_almost_equal(c2 + p1, p3)
+ assert_poly_almost_equal(p1 + tuple(c2), p3)
+ assert_poly_almost_equal(tuple(c2) + p1, p3)
+ assert_poly_almost_equal(p1 + np.array(c2), p3)
+ assert_poly_almost_equal(np.array(c2) + p1, p3)
+ assert_raises(TypeError, op.add, p1, Poly([0], domain=Poly.domain + 1))
+ assert_raises(TypeError, op.add, p1, Poly([0], window=Poly.window + 1))
+ if Poly is Polynomial:
+ assert_raises(TypeError, op.add, p1, Chebyshev([0]))
+ else:
+ assert_raises(TypeError, op.add, p1, Polynomial([0]))
+
+
+def test_sub(Poly):
+ # This checks commutation, not numerical correctness
+ c1 = list(random((4,)) + .5)
+ c2 = list(random((3,)) + .5)
+ p1 = Poly(c1)
+ p2 = Poly(c2)
+ p3 = p1 - p2
+ assert_poly_almost_equal(p2 - p1, -p3)
+ assert_poly_almost_equal(p1 - c2, p3)
+ assert_poly_almost_equal(c2 - p1, -p3)
+ assert_poly_almost_equal(p1 - tuple(c2), p3)
+ assert_poly_almost_equal(tuple(c2) - p1, -p3)
+ assert_poly_almost_equal(p1 - np.array(c2), p3)
+ assert_poly_almost_equal(np.array(c2) - p1, -p3)
+ assert_raises(TypeError, op.sub, p1, Poly([0], domain=Poly.domain + 1))
+ assert_raises(TypeError, op.sub, p1, Poly([0], window=Poly.window + 1))
+ if Poly is Polynomial:
+ assert_raises(TypeError, op.sub, p1, Chebyshev([0]))
+ else:
+ assert_raises(TypeError, op.sub, p1, Polynomial([0]))
+
+
+def test_mul(Poly):
+ c1 = list(random((4,)) + .5)
+ c2 = list(random((3,)) + .5)
+ p1 = Poly(c1)
+ p2 = Poly(c2)
+ p3 = p1 * p2
+ assert_poly_almost_equal(p2 * p1, p3)
+ assert_poly_almost_equal(p1 * c2, p3)
+ assert_poly_almost_equal(c2 * p1, p3)
+ assert_poly_almost_equal(p1 * tuple(c2), p3)
+ assert_poly_almost_equal(tuple(c2) * p1, p3)
+ assert_poly_almost_equal(p1 * np.array(c2), p3)
+ assert_poly_almost_equal(np.array(c2) * p1, p3)
+ assert_poly_almost_equal(p1 * 2, p1 * Poly([2]))
+ assert_poly_almost_equal(2 * p1, p1 * Poly([2]))
+ assert_raises(TypeError, op.mul, p1, Poly([0], domain=Poly.domain + 1))
+ assert_raises(TypeError, op.mul, p1, Poly([0], window=Poly.window + 1))
+ if Poly is Polynomial:
+ assert_raises(TypeError, op.mul, p1, Chebyshev([0]))
+ else:
+ assert_raises(TypeError, op.mul, p1, Polynomial([0]))
+
+
+def test_floordiv(Poly):
+ c1 = list(random((4,)) + .5)
+ c2 = list(random((3,)) + .5)
+ c3 = list(random((2,)) + .5)
+ p1 = Poly(c1)
+ p2 = Poly(c2)
+ p3 = Poly(c3)
+ p4 = p1 * p2 + p3
+ c4 = list(p4.coef)
+ assert_poly_almost_equal(p4 // p2, p1)
+ assert_poly_almost_equal(p4 // c2, p1)
+ assert_poly_almost_equal(c4 // p2, p1)
+ assert_poly_almost_equal(p4 // tuple(c2), p1)
+ assert_poly_almost_equal(tuple(c4) // p2, p1)
+ assert_poly_almost_equal(p4 // np.array(c2), p1)
+ assert_poly_almost_equal(np.array(c4) // p2, p1)
+ assert_poly_almost_equal(2 // p2, Poly([0]))
+ assert_poly_almost_equal(p2 // 2, 0.5*p2)
+ assert_raises(
+ TypeError, op.floordiv, p1, Poly([0], domain=Poly.domain + 1))
+ assert_raises(
+ TypeError, op.floordiv, p1, Poly([0], window=Poly.window + 1))
+ if Poly is Polynomial:
+ assert_raises(TypeError, op.floordiv, p1, Chebyshev([0]))
+ else:
+ assert_raises(TypeError, op.floordiv, p1, Polynomial([0]))
+
+
+def test_truediv(Poly):
+ # true division is valid only if the denominator is a Number and
+ # not a python bool.
+ p1 = Poly([1,2,3])
+ p2 = p1 * 5
+
+ for stype in np.ScalarType:
+ if not issubclass(stype, Number) or issubclass(stype, bool):
+ continue
+ s = stype(5)
+ assert_poly_almost_equal(op.truediv(p2, s), p1)
+ assert_raises(TypeError, op.truediv, s, p2)
+ for stype in (int, float):
+ s = stype(5)
+ assert_poly_almost_equal(op.truediv(p2, s), p1)
+ assert_raises(TypeError, op.truediv, s, p2)
+ for stype in [complex]:
+ s = stype(5, 0)
+ assert_poly_almost_equal(op.truediv(p2, s), p1)
+ assert_raises(TypeError, op.truediv, s, p2)
+ for s in [tuple(), list(), dict(), bool(), np.array([1])]:
+ assert_raises(TypeError, op.truediv, p2, s)
+ assert_raises(TypeError, op.truediv, s, p2)
+ for ptype in classes:
+ assert_raises(TypeError, op.truediv, p2, ptype(1))
+
+
+def test_mod(Poly):
+ # This checks commutation, not numerical correctness
+ c1 = list(random((4,)) + .5)
+ c2 = list(random((3,)) + .5)
+ c3 = list(random((2,)) + .5)
+ p1 = Poly(c1)
+ p2 = Poly(c2)
+ p3 = Poly(c3)
+ p4 = p1 * p2 + p3
+ c4 = list(p4.coef)
+ assert_poly_almost_equal(p4 % p2, p3)
+ assert_poly_almost_equal(p4 % c2, p3)
+ assert_poly_almost_equal(c4 % p2, p3)
+ assert_poly_almost_equal(p4 % tuple(c2), p3)
+ assert_poly_almost_equal(tuple(c4) % p2, p3)
+ assert_poly_almost_equal(p4 % np.array(c2), p3)
+ assert_poly_almost_equal(np.array(c4) % p2, p3)
+ assert_poly_almost_equal(2 % p2, Poly([2]))
+ assert_poly_almost_equal(p2 % 2, Poly([0]))
+ assert_raises(TypeError, op.mod, p1, Poly([0], domain=Poly.domain + 1))
+ assert_raises(TypeError, op.mod, p1, Poly([0], window=Poly.window + 1))
+ if Poly is Polynomial:
+ assert_raises(TypeError, op.mod, p1, Chebyshev([0]))
+ else:
+ assert_raises(TypeError, op.mod, p1, Polynomial([0]))
+
+
+def test_divmod(Poly):
+ # This checks commutation, not numerical correctness
+ c1 = list(random((4,)) + .5)
+ c2 = list(random((3,)) + .5)
+ c3 = list(random((2,)) + .5)
+ p1 = Poly(c1)
+ p2 = Poly(c2)
+ p3 = Poly(c3)
+ p4 = p1 * p2 + p3
+ c4 = list(p4.coef)
+ quo, rem = divmod(p4, p2)
+ assert_poly_almost_equal(quo, p1)
+ assert_poly_almost_equal(rem, p3)
+ quo, rem = divmod(p4, c2)
+ assert_poly_almost_equal(quo, p1)
+ assert_poly_almost_equal(rem, p3)
+ quo, rem = divmod(c4, p2)
+ assert_poly_almost_equal(quo, p1)
+ assert_poly_almost_equal(rem, p3)
+ quo, rem = divmod(p4, tuple(c2))
+ assert_poly_almost_equal(quo, p1)
+ assert_poly_almost_equal(rem, p3)
+ quo, rem = divmod(tuple(c4), p2)
+ assert_poly_almost_equal(quo, p1)
+ assert_poly_almost_equal(rem, p3)
+ quo, rem = divmod(p4, np.array(c2))
+ assert_poly_almost_equal(quo, p1)
+ assert_poly_almost_equal(rem, p3)
+ quo, rem = divmod(np.array(c4), p2)
+ assert_poly_almost_equal(quo, p1)
+ assert_poly_almost_equal(rem, p3)
+ quo, rem = divmod(p2, 2)
+ assert_poly_almost_equal(quo, 0.5*p2)
+ assert_poly_almost_equal(rem, Poly([0]))
+ quo, rem = divmod(2, p2)
+ assert_poly_almost_equal(quo, Poly([0]))
+ assert_poly_almost_equal(rem, Poly([2]))
+ assert_raises(TypeError, divmod, p1, Poly([0], domain=Poly.domain + 1))
+ assert_raises(TypeError, divmod, p1, Poly([0], window=Poly.window + 1))
+ if Poly is Polynomial:
+ assert_raises(TypeError, divmod, p1, Chebyshev([0]))
+ else:
+ assert_raises(TypeError, divmod, p1, Polynomial([0]))
+
+
+def test_roots(Poly):
+ d = Poly.domain * 1.25 + .25
+ w = Poly.window
+ tgt = np.linspace(d[0], d[1], 5)
+ res = np.sort(Poly.fromroots(tgt, domain=d, window=w).roots())
+ assert_almost_equal(res, tgt)
+ # default domain and window
+ res = np.sort(Poly.fromroots(tgt).roots())
+ assert_almost_equal(res, tgt)
+
+
+def test_degree(Poly):
+ p = Poly.basis(5)
+ assert_equal(p.degree(), 5)
+
+
+def test_copy(Poly):
+ p1 = Poly.basis(5)
+ p2 = p1.copy()
+ assert_(p1 == p2)
+ assert_(p1 is not p2)
+ assert_(p1.coef is not p2.coef)
+ assert_(p1.domain is not p2.domain)
+ assert_(p1.window is not p2.window)
+
+
+def test_integ(Poly):
+ P = Polynomial
+ # Check defaults
+ p0 = Poly.cast(P([1*2, 2*3, 3*4]))
+ p1 = P.cast(p0.integ())
+ p2 = P.cast(p0.integ(2))
+ assert_poly_almost_equal(p1, P([0, 2, 3, 4]))
+ assert_poly_almost_equal(p2, P([0, 0, 1, 1, 1]))
+ # Check with k
+ p0 = Poly.cast(P([1*2, 2*3, 3*4]))
+ p1 = P.cast(p0.integ(k=1))
+ p2 = P.cast(p0.integ(2, k=[1, 1]))
+ assert_poly_almost_equal(p1, P([1, 2, 3, 4]))
+ assert_poly_almost_equal(p2, P([1, 1, 1, 1, 1]))
+ # Check with lbnd
+ p0 = Poly.cast(P([1*2, 2*3, 3*4]))
+ p1 = P.cast(p0.integ(lbnd=1))
+ p2 = P.cast(p0.integ(2, lbnd=1))
+ assert_poly_almost_equal(p1, P([-9, 2, 3, 4]))
+ assert_poly_almost_equal(p2, P([6, -9, 1, 1, 1]))
+ # Check scaling
+ d = 2*Poly.domain
+ p0 = Poly.cast(P([1*2, 2*3, 3*4]), domain=d)
+ p1 = P.cast(p0.integ())
+ p2 = P.cast(p0.integ(2))
+ assert_poly_almost_equal(p1, P([0, 2, 3, 4]))
+ assert_poly_almost_equal(p2, P([0, 0, 1, 1, 1]))
+
+
+def test_deriv(Poly):
+ # Check that the derivative is the inverse of integration. It is
+ # assumes that the integration has been checked elsewhere.
+ d = Poly.domain + random((2,))*.25
+ w = Poly.window + random((2,))*.25
+ p1 = Poly([1, 2, 3], domain=d, window=w)
+ p2 = p1.integ(2, k=[1, 2])
+ p3 = p1.integ(1, k=[1])
+ assert_almost_equal(p2.deriv(1).coef, p3.coef)
+ assert_almost_equal(p2.deriv(2).coef, p1.coef)
+ # default domain and window
+ p1 = Poly([1, 2, 3])
+ p2 = p1.integ(2, k=[1, 2])
+ p3 = p1.integ(1, k=[1])
+ assert_almost_equal(p2.deriv(1).coef, p3.coef)
+ assert_almost_equal(p2.deriv(2).coef, p1.coef)
+
+
+def test_linspace(Poly):
+ d = Poly.domain + random((2,))*.25
+ w = Poly.window + random((2,))*.25
+ p = Poly([1, 2, 3], domain=d, window=w)
+ # check default domain
+ xtgt = np.linspace(d[0], d[1], 20)
+ ytgt = p(xtgt)
+ xres, yres = p.linspace(20)
+ assert_almost_equal(xres, xtgt)
+ assert_almost_equal(yres, ytgt)
+ # check specified domain
+ xtgt = np.linspace(0, 2, 20)
+ ytgt = p(xtgt)
+ xres, yres = p.linspace(20, domain=[0, 2])
+ assert_almost_equal(xres, xtgt)
+ assert_almost_equal(yres, ytgt)
+
+
+def test_pow(Poly):
+ d = Poly.domain + random((2,))*.25
+ w = Poly.window + random((2,))*.25
+ tgt = Poly([1], domain=d, window=w)
+ tst = Poly([1, 2, 3], domain=d, window=w)
+ for i in range(5):
+ assert_poly_almost_equal(tst**i, tgt)
+ tgt = tgt * tst
+ # default domain and window
+ tgt = Poly([1])
+ tst = Poly([1, 2, 3])
+ for i in range(5):
+ assert_poly_almost_equal(tst**i, tgt)
+ tgt = tgt * tst
+ # check error for invalid powers
+ assert_raises(ValueError, op.pow, tgt, 1.5)
+ assert_raises(ValueError, op.pow, tgt, -1)
+
+
+def test_call(Poly):
+ P = Polynomial
+ d = Poly.domain
+ x = np.linspace(d[0], d[1], 11)
+
+ # Check defaults
+ p = Poly.cast(P([1, 2, 3]))
+ tgt = 1 + x*(2 + 3*x)
+ res = p(x)
+ assert_almost_equal(res, tgt)
+
+
+def test_cutdeg(Poly):
+ p = Poly([1, 2, 3])
+ assert_raises(ValueError, p.cutdeg, .5)
+ assert_raises(ValueError, p.cutdeg, -1)
+ assert_equal(len(p.cutdeg(3)), 3)
+ assert_equal(len(p.cutdeg(2)), 3)
+ assert_equal(len(p.cutdeg(1)), 2)
+ assert_equal(len(p.cutdeg(0)), 1)
+
+
+def test_truncate(Poly):
+ p = Poly([1, 2, 3])
+ assert_raises(ValueError, p.truncate, .5)
+ assert_raises(ValueError, p.truncate, 0)
+ assert_equal(len(p.truncate(4)), 3)
+ assert_equal(len(p.truncate(3)), 3)
+ assert_equal(len(p.truncate(2)), 2)
+ assert_equal(len(p.truncate(1)), 1)
+
+
+def test_trim(Poly):
+ c = [1, 1e-6, 1e-12, 0]
+ p = Poly(c)
+ assert_equal(p.trim().coef, c[:3])
+ assert_equal(p.trim(1e-10).coef, c[:2])
+ assert_equal(p.trim(1e-5).coef, c[:1])
+
+
+def test_mapparms(Poly):
+ # check with defaults. Should be identity.
+ d = Poly.domain
+ w = Poly.window
+ p = Poly([1], domain=d, window=w)
+ assert_almost_equal([0, 1], p.mapparms())
+ #
+ w = 2*d + 1
+ p = Poly([1], domain=d, window=w)
+ assert_almost_equal([1, 2], p.mapparms())
+
+
+def test_ufunc_override(Poly):
+ p = Poly([1, 2, 3])
+ x = np.ones(3)
+ assert_raises(TypeError, np.add, p, x)
+ assert_raises(TypeError, np.add, x, p)
+
+
+#
+# Test class method that only exists for some classes
+#
+
+
+class TestInterpolate:
+
+ def f(self, x):
+ return x * (x - 1) * (x - 2)
+
+ def test_raises(self):
+ assert_raises(ValueError, Chebyshev.interpolate, self.f, -1)
+ assert_raises(TypeError, Chebyshev.interpolate, self.f, 10.)
+
+ def test_dimensions(self):
+ for deg in range(1, 5):
+ assert_(Chebyshev.interpolate(self.f, deg).degree() == deg)
+
+ def test_approximation(self):
+
+ def powx(x, p):
+ return x**p
+
+ x = np.linspace(0, 2, 10)
+ for deg in range(0, 10):
+ for t in range(0, deg + 1):
+ p = Chebyshev.interpolate(powx, deg, domain=[0, 2], args=(t,))
+ assert_almost_equal(p(x), powx(x, t), decimal=11)
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_hermite.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_hermite.py
new file mode 100644
index 00000000..53ee0844
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_hermite.py
@@ -0,0 +1,555 @@
+"""Tests for hermite module.
+
+"""
+from functools import reduce
+
+import numpy as np
+import numpy.polynomial.hermite as herm
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+ assert_almost_equal, assert_raises, assert_equal, assert_,
+ )
+
+H0 = np.array([1])
+H1 = np.array([0, 2])
+H2 = np.array([-2, 0, 4])
+H3 = np.array([0, -12, 0, 8])
+H4 = np.array([12, 0, -48, 0, 16])
+H5 = np.array([0, 120, 0, -160, 0, 32])
+H6 = np.array([-120, 0, 720, 0, -480, 0, 64])
+H7 = np.array([0, -1680, 0, 3360, 0, -1344, 0, 128])
+H8 = np.array([1680, 0, -13440, 0, 13440, 0, -3584, 0, 256])
+H9 = np.array([0, 30240, 0, -80640, 0, 48384, 0, -9216, 0, 512])
+
+Hlist = [H0, H1, H2, H3, H4, H5, H6, H7, H8, H9]
+
+
+def trim(x):
+ return herm.hermtrim(x, tol=1e-6)
+
+
+class TestConstants:
+
+ def test_hermdomain(self):
+ assert_equal(herm.hermdomain, [-1, 1])
+
+ def test_hermzero(self):
+ assert_equal(herm.hermzero, [0])
+
+ def test_hermone(self):
+ assert_equal(herm.hermone, [1])
+
+ def test_hermx(self):
+ assert_equal(herm.hermx, [0, .5])
+
+
+class TestArithmetic:
+ x = np.linspace(-3, 3, 100)
+
+ def test_hermadd(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] += 1
+ res = herm.hermadd([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_hermsub(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] -= 1
+ res = herm.hermsub([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_hermmulx(self):
+ assert_equal(herm.hermmulx([0]), [0])
+ assert_equal(herm.hermmulx([1]), [0, .5])
+ for i in range(1, 5):
+ ser = [0]*i + [1]
+ tgt = [0]*(i - 1) + [i, 0, .5]
+ assert_equal(herm.hermmulx(ser), tgt)
+
+ def test_hermmul(self):
+ # check values of result
+ for i in range(5):
+ pol1 = [0]*i + [1]
+ val1 = herm.hermval(self.x, pol1)
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ pol2 = [0]*j + [1]
+ val2 = herm.hermval(self.x, pol2)
+ pol3 = herm.hermmul(pol1, pol2)
+ val3 = herm.hermval(self.x, pol3)
+ assert_(len(pol3) == i + j + 1, msg)
+ assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+ def test_hermdiv(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ ci = [0]*i + [1]
+ cj = [0]*j + [1]
+ tgt = herm.hermadd(ci, cj)
+ quo, rem = herm.hermdiv(tgt, ci)
+ res = herm.hermadd(herm.hermmul(quo, ci), rem)
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_hermpow(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ c = np.arange(i + 1)
+ tgt = reduce(herm.hermmul, [c]*j, np.array([1]))
+ res = herm.hermpow(c, j)
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation:
+ # coefficients of 1 + 2*x + 3*x**2
+ c1d = np.array([2.5, 1., .75])
+ c2d = np.einsum('i,j->ij', c1d, c1d)
+ c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+ y = polyval(x, [1., 2., 3.])
+
+ def test_hermval(self):
+ #check empty input
+ assert_equal(herm.hermval([], [1]).size, 0)
+
+ #check normal input)
+ x = np.linspace(-1, 1)
+ y = [polyval(x, c) for c in Hlist]
+ for i in range(10):
+ msg = f"At i={i}"
+ tgt = y[i]
+ res = herm.hermval(x, [0]*i + [1])
+ assert_almost_equal(res, tgt, err_msg=msg)
+
+ #check that shape is preserved
+ for i in range(3):
+ dims = [2]*i
+ x = np.zeros(dims)
+ assert_equal(herm.hermval(x, [1]).shape, dims)
+ assert_equal(herm.hermval(x, [1, 0]).shape, dims)
+ assert_equal(herm.hermval(x, [1, 0, 0]).shape, dims)
+
+ def test_hermval2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises(ValueError, herm.hermval2d, x1, x2[:2], self.c2d)
+
+ #test values
+ tgt = y1*y2
+ res = herm.hermval2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = herm.hermval2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3))
+
+ def test_hermval3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises(ValueError, herm.hermval3d, x1, x2, x3[:2], self.c3d)
+
+ #test values
+ tgt = y1*y2*y3
+ res = herm.hermval3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = herm.hermval3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3))
+
+ def test_hermgrid2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j->ij', y1, y2)
+ res = herm.hermgrid2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = herm.hermgrid2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3)*2)
+
+ def test_hermgrid3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+ res = herm.hermgrid3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = herm.hermgrid3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral:
+
+ def test_hermint(self):
+ # check exceptions
+ assert_raises(TypeError, herm.hermint, [0], .5)
+ assert_raises(ValueError, herm.hermint, [0], -1)
+ assert_raises(ValueError, herm.hermint, [0], 1, [0, 0])
+ assert_raises(ValueError, herm.hermint, [0], lbnd=[0])
+ assert_raises(ValueError, herm.hermint, [0], scl=[0])
+ assert_raises(TypeError, herm.hermint, [0], axis=.5)
+
+ # test integration of zero polynomial
+ for i in range(2, 5):
+ k = [0]*(i - 2) + [1]
+ res = herm.hermint([0], m=i, k=k)
+ assert_almost_equal(res, [0, .5])
+
+ # check single integration with integration constant
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [1/scl]
+ hermpol = herm.poly2herm(pol)
+ hermint = herm.hermint(hermpol, m=1, k=[i])
+ res = herm.herm2poly(hermint)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check single integration with integration constant and lbnd
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ hermpol = herm.poly2herm(pol)
+ hermint = herm.hermint(hermpol, m=1, k=[i], lbnd=-1)
+ assert_almost_equal(herm.hermval(-1, hermint), i)
+
+ # check single integration with integration constant and scaling
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [2/scl]
+ hermpol = herm.poly2herm(pol)
+ hermint = herm.hermint(hermpol, m=1, k=[i], scl=2)
+ res = herm.herm2poly(hermint)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with default k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = herm.hermint(tgt, m=1)
+ res = herm.hermint(pol, m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with defined k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = herm.hermint(tgt, m=1, k=[k])
+ res = herm.hermint(pol, m=j, k=list(range(j)))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with lbnd
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = herm.hermint(tgt, m=1, k=[k], lbnd=-1)
+ res = herm.hermint(pol, m=j, k=list(range(j)), lbnd=-1)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = herm.hermint(tgt, m=1, k=[k], scl=2)
+ res = herm.hermint(pol, m=j, k=list(range(j)), scl=2)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_hermint_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([herm.hermint(c) for c in c2d.T]).T
+ res = herm.hermint(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([herm.hermint(c) for c in c2d])
+ res = herm.hermint(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([herm.hermint(c, k=3) for c in c2d])
+ res = herm.hermint(c2d, k=3, axis=1)
+ assert_almost_equal(res, tgt)
+
+
+class TestDerivative:
+
+ def test_hermder(self):
+ # check exceptions
+ assert_raises(TypeError, herm.hermder, [0], .5)
+ assert_raises(ValueError, herm.hermder, [0], -1)
+
+ # check that zeroth derivative does nothing
+ for i in range(5):
+ tgt = [0]*i + [1]
+ res = herm.hermder(tgt, m=0)
+ assert_equal(trim(res), trim(tgt))
+
+ # check that derivation is the inverse of integration
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = herm.hermder(herm.hermint(tgt, m=j), m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check derivation with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = herm.hermder(herm.hermint(tgt, m=j, scl=2), m=j, scl=.5)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_hermder_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([herm.hermder(c) for c in c2d.T]).T
+ res = herm.hermder(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([herm.hermder(c) for c in c2d])
+ res = herm.hermder(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+
+class TestVander:
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+
+ def test_hermvander(self):
+ # check for 1d x
+ x = np.arange(3)
+ v = herm.hermvander(x, 3)
+ assert_(v.shape == (3, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], herm.hermval(x, coef))
+
+ # check for 2d x
+ x = np.array([[1, 2], [3, 4], [5, 6]])
+ v = herm.hermvander(x, 3)
+ assert_(v.shape == (3, 2, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], herm.hermval(x, coef))
+
+ def test_hermvander2d(self):
+ # also tests hermval2d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3))
+ van = herm.hermvander2d(x1, x2, [1, 2])
+ tgt = herm.hermval2d(x1, x2, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = herm.hermvander2d([x1], [x2], [1, 2])
+ assert_(van.shape == (1, 5, 6))
+
+ def test_hermvander3d(self):
+ # also tests hermval3d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3, 4))
+ van = herm.hermvander3d(x1, x2, x3, [1, 2, 3])
+ tgt = herm.hermval3d(x1, x2, x3, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = herm.hermvander3d([x1], [x2], [x3], [1, 2, 3])
+ assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting:
+
+ def test_hermfit(self):
+ def f(x):
+ return x*(x - 1)*(x - 2)
+
+ def f2(x):
+ return x**4 + x**2 + 1
+
+ # Test exceptions
+ assert_raises(ValueError, herm.hermfit, [1], [1], -1)
+ assert_raises(TypeError, herm.hermfit, [[1]], [1], 0)
+ assert_raises(TypeError, herm.hermfit, [], [1], 0)
+ assert_raises(TypeError, herm.hermfit, [1], [[[1]]], 0)
+ assert_raises(TypeError, herm.hermfit, [1, 2], [1], 0)
+ assert_raises(TypeError, herm.hermfit, [1], [1, 2], 0)
+ assert_raises(TypeError, herm.hermfit, [1], [1], 0, w=[[1]])
+ assert_raises(TypeError, herm.hermfit, [1], [1], 0, w=[1, 1])
+ assert_raises(ValueError, herm.hermfit, [1], [1], [-1,])
+ assert_raises(ValueError, herm.hermfit, [1], [1], [2, -1, 6])
+ assert_raises(TypeError, herm.hermfit, [1], [1], [])
+
+ # Test fit
+ x = np.linspace(0, 2)
+ y = f(x)
+ #
+ coef3 = herm.hermfit(x, y, 3)
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(herm.hermval(x, coef3), y)
+ coef3 = herm.hermfit(x, y, [0, 1, 2, 3])
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(herm.hermval(x, coef3), y)
+ #
+ coef4 = herm.hermfit(x, y, 4)
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(herm.hermval(x, coef4), y)
+ coef4 = herm.hermfit(x, y, [0, 1, 2, 3, 4])
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(herm.hermval(x, coef4), y)
+ # check things still work if deg is not in strict increasing
+ coef4 = herm.hermfit(x, y, [2, 3, 4, 1, 0])
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(herm.hermval(x, coef4), y)
+ #
+ coef2d = herm.hermfit(x, np.array([y, y]).T, 3)
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ coef2d = herm.hermfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ # test weighting
+ w = np.zeros_like(x)
+ yw = y.copy()
+ w[1::2] = 1
+ y[0::2] = 0
+ wcoef3 = herm.hermfit(x, yw, 3, w=w)
+ assert_almost_equal(wcoef3, coef3)
+ wcoef3 = herm.hermfit(x, yw, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef3, coef3)
+ #
+ wcoef2d = herm.hermfit(x, np.array([yw, yw]).T, 3, w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ wcoef2d = herm.hermfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ # test scaling with complex values x points whose square
+ # is zero when summed.
+ x = [1, 1j, -1, -1j]
+ assert_almost_equal(herm.hermfit(x, x, 1), [0, .5])
+ assert_almost_equal(herm.hermfit(x, x, [0, 1]), [0, .5])
+ # test fitting only even Legendre polynomials
+ x = np.linspace(-1, 1)
+ y = f2(x)
+ coef1 = herm.hermfit(x, y, 4)
+ assert_almost_equal(herm.hermval(x, coef1), y)
+ coef2 = herm.hermfit(x, y, [0, 2, 4])
+ assert_almost_equal(herm.hermval(x, coef2), y)
+ assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion:
+
+ def test_raises(self):
+ assert_raises(ValueError, herm.hermcompanion, [])
+ assert_raises(ValueError, herm.hermcompanion, [1])
+
+ def test_dimensions(self):
+ for i in range(1, 5):
+ coef = [0]*i + [1]
+ assert_(herm.hermcompanion(coef).shape == (i, i))
+
+ def test_linear_root(self):
+ assert_(herm.hermcompanion([1, 2])[0, 0] == -.25)
+
+
+class TestGauss:
+
+ def test_100(self):
+ x, w = herm.hermgauss(100)
+
+ # test orthogonality. Note that the results need to be normalized,
+ # otherwise the huge values that can arise from fast growing
+ # functions like Laguerre can be very confusing.
+ v = herm.hermvander(x, 99)
+ vv = np.dot(v.T * w, v)
+ vd = 1/np.sqrt(vv.diagonal())
+ vv = vd[:, None] * vv * vd
+ assert_almost_equal(vv, np.eye(100))
+
+ # check that the integral of 1 is correct
+ tgt = np.sqrt(np.pi)
+ assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc:
+
+ def test_hermfromroots(self):
+ res = herm.hermfromroots([])
+ assert_almost_equal(trim(res), [1])
+ for i in range(1, 5):
+ roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+ pol = herm.hermfromroots(roots)
+ res = herm.hermval(roots, pol)
+ tgt = 0
+ assert_(len(pol) == i + 1)
+ assert_almost_equal(herm.herm2poly(pol)[-1], 1)
+ assert_almost_equal(res, tgt)
+
+ def test_hermroots(self):
+ assert_almost_equal(herm.hermroots([1]), [])
+ assert_almost_equal(herm.hermroots([1, 1]), [-.5])
+ for i in range(2, 5):
+ tgt = np.linspace(-1, 1, i)
+ res = herm.hermroots(herm.hermfromroots(tgt))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_hermtrim(self):
+ coef = [2, -1, 1, 0]
+
+ # Test exceptions
+ assert_raises(ValueError, herm.hermtrim, coef, -1)
+
+ # Test results
+ assert_equal(herm.hermtrim(coef), coef[:-1])
+ assert_equal(herm.hermtrim(coef, 1), coef[:-3])
+ assert_equal(herm.hermtrim(coef, 2), [0])
+
+ def test_hermline(self):
+ assert_equal(herm.hermline(3, 4), [3, 2])
+
+ def test_herm2poly(self):
+ for i in range(10):
+ assert_almost_equal(herm.herm2poly([0]*i + [1]), Hlist[i])
+
+ def test_poly2herm(self):
+ for i in range(10):
+ assert_almost_equal(herm.poly2herm(Hlist[i]), [0]*i + [1])
+
+ def test_weight(self):
+ x = np.linspace(-5, 5, 11)
+ tgt = np.exp(-x**2)
+ res = herm.hermweight(x)
+ assert_almost_equal(res, tgt)
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_hermite_e.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_hermite_e.py
new file mode 100644
index 00000000..2d262a33
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_hermite_e.py
@@ -0,0 +1,556 @@
+"""Tests for hermite_e module.
+
+"""
+from functools import reduce
+
+import numpy as np
+import numpy.polynomial.hermite_e as herme
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+ assert_almost_equal, assert_raises, assert_equal, assert_,
+ )
+
+He0 = np.array([1])
+He1 = np.array([0, 1])
+He2 = np.array([-1, 0, 1])
+He3 = np.array([0, -3, 0, 1])
+He4 = np.array([3, 0, -6, 0, 1])
+He5 = np.array([0, 15, 0, -10, 0, 1])
+He6 = np.array([-15, 0, 45, 0, -15, 0, 1])
+He7 = np.array([0, -105, 0, 105, 0, -21, 0, 1])
+He8 = np.array([105, 0, -420, 0, 210, 0, -28, 0, 1])
+He9 = np.array([0, 945, 0, -1260, 0, 378, 0, -36, 0, 1])
+
+Helist = [He0, He1, He2, He3, He4, He5, He6, He7, He8, He9]
+
+
+def trim(x):
+ return herme.hermetrim(x, tol=1e-6)
+
+
+class TestConstants:
+
+ def test_hermedomain(self):
+ assert_equal(herme.hermedomain, [-1, 1])
+
+ def test_hermezero(self):
+ assert_equal(herme.hermezero, [0])
+
+ def test_hermeone(self):
+ assert_equal(herme.hermeone, [1])
+
+ def test_hermex(self):
+ assert_equal(herme.hermex, [0, 1])
+
+
+class TestArithmetic:
+ x = np.linspace(-3, 3, 100)
+
+ def test_hermeadd(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] += 1
+ res = herme.hermeadd([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_hermesub(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] -= 1
+ res = herme.hermesub([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_hermemulx(self):
+ assert_equal(herme.hermemulx([0]), [0])
+ assert_equal(herme.hermemulx([1]), [0, 1])
+ for i in range(1, 5):
+ ser = [0]*i + [1]
+ tgt = [0]*(i - 1) + [i, 0, 1]
+ assert_equal(herme.hermemulx(ser), tgt)
+
+ def test_hermemul(self):
+ # check values of result
+ for i in range(5):
+ pol1 = [0]*i + [1]
+ val1 = herme.hermeval(self.x, pol1)
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ pol2 = [0]*j + [1]
+ val2 = herme.hermeval(self.x, pol2)
+ pol3 = herme.hermemul(pol1, pol2)
+ val3 = herme.hermeval(self.x, pol3)
+ assert_(len(pol3) == i + j + 1, msg)
+ assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+ def test_hermediv(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ ci = [0]*i + [1]
+ cj = [0]*j + [1]
+ tgt = herme.hermeadd(ci, cj)
+ quo, rem = herme.hermediv(tgt, ci)
+ res = herme.hermeadd(herme.hermemul(quo, ci), rem)
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_hermepow(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ c = np.arange(i + 1)
+ tgt = reduce(herme.hermemul, [c]*j, np.array([1]))
+ res = herme.hermepow(c, j)
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation:
+ # coefficients of 1 + 2*x + 3*x**2
+ c1d = np.array([4., 2., 3.])
+ c2d = np.einsum('i,j->ij', c1d, c1d)
+ c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+ y = polyval(x, [1., 2., 3.])
+
+ def test_hermeval(self):
+ #check empty input
+ assert_equal(herme.hermeval([], [1]).size, 0)
+
+ #check normal input)
+ x = np.linspace(-1, 1)
+ y = [polyval(x, c) for c in Helist]
+ for i in range(10):
+ msg = f"At i={i}"
+ tgt = y[i]
+ res = herme.hermeval(x, [0]*i + [1])
+ assert_almost_equal(res, tgt, err_msg=msg)
+
+ #check that shape is preserved
+ for i in range(3):
+ dims = [2]*i
+ x = np.zeros(dims)
+ assert_equal(herme.hermeval(x, [1]).shape, dims)
+ assert_equal(herme.hermeval(x, [1, 0]).shape, dims)
+ assert_equal(herme.hermeval(x, [1, 0, 0]).shape, dims)
+
+ def test_hermeval2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises(ValueError, herme.hermeval2d, x1, x2[:2], self.c2d)
+
+ #test values
+ tgt = y1*y2
+ res = herme.hermeval2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = herme.hermeval2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3))
+
+ def test_hermeval3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises(ValueError, herme.hermeval3d, x1, x2, x3[:2], self.c3d)
+
+ #test values
+ tgt = y1*y2*y3
+ res = herme.hermeval3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = herme.hermeval3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3))
+
+ def test_hermegrid2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j->ij', y1, y2)
+ res = herme.hermegrid2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = herme.hermegrid2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3)*2)
+
+ def test_hermegrid3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+ res = herme.hermegrid3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = herme.hermegrid3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral:
+
+ def test_hermeint(self):
+ # check exceptions
+ assert_raises(TypeError, herme.hermeint, [0], .5)
+ assert_raises(ValueError, herme.hermeint, [0], -1)
+ assert_raises(ValueError, herme.hermeint, [0], 1, [0, 0])
+ assert_raises(ValueError, herme.hermeint, [0], lbnd=[0])
+ assert_raises(ValueError, herme.hermeint, [0], scl=[0])
+ assert_raises(TypeError, herme.hermeint, [0], axis=.5)
+
+ # test integration of zero polynomial
+ for i in range(2, 5):
+ k = [0]*(i - 2) + [1]
+ res = herme.hermeint([0], m=i, k=k)
+ assert_almost_equal(res, [0, 1])
+
+ # check single integration with integration constant
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [1/scl]
+ hermepol = herme.poly2herme(pol)
+ hermeint = herme.hermeint(hermepol, m=1, k=[i])
+ res = herme.herme2poly(hermeint)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check single integration with integration constant and lbnd
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ hermepol = herme.poly2herme(pol)
+ hermeint = herme.hermeint(hermepol, m=1, k=[i], lbnd=-1)
+ assert_almost_equal(herme.hermeval(-1, hermeint), i)
+
+ # check single integration with integration constant and scaling
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [2/scl]
+ hermepol = herme.poly2herme(pol)
+ hermeint = herme.hermeint(hermepol, m=1, k=[i], scl=2)
+ res = herme.herme2poly(hermeint)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with default k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = herme.hermeint(tgt, m=1)
+ res = herme.hermeint(pol, m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with defined k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = herme.hermeint(tgt, m=1, k=[k])
+ res = herme.hermeint(pol, m=j, k=list(range(j)))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with lbnd
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = herme.hermeint(tgt, m=1, k=[k], lbnd=-1)
+ res = herme.hermeint(pol, m=j, k=list(range(j)), lbnd=-1)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = herme.hermeint(tgt, m=1, k=[k], scl=2)
+ res = herme.hermeint(pol, m=j, k=list(range(j)), scl=2)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_hermeint_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([herme.hermeint(c) for c in c2d.T]).T
+ res = herme.hermeint(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([herme.hermeint(c) for c in c2d])
+ res = herme.hermeint(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([herme.hermeint(c, k=3) for c in c2d])
+ res = herme.hermeint(c2d, k=3, axis=1)
+ assert_almost_equal(res, tgt)
+
+
+class TestDerivative:
+
+ def test_hermeder(self):
+ # check exceptions
+ assert_raises(TypeError, herme.hermeder, [0], .5)
+ assert_raises(ValueError, herme.hermeder, [0], -1)
+
+ # check that zeroth derivative does nothing
+ for i in range(5):
+ tgt = [0]*i + [1]
+ res = herme.hermeder(tgt, m=0)
+ assert_equal(trim(res), trim(tgt))
+
+ # check that derivation is the inverse of integration
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = herme.hermeder(herme.hermeint(tgt, m=j), m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check derivation with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = herme.hermeder(
+ herme.hermeint(tgt, m=j, scl=2), m=j, scl=.5)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_hermeder_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([herme.hermeder(c) for c in c2d.T]).T
+ res = herme.hermeder(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([herme.hermeder(c) for c in c2d])
+ res = herme.hermeder(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+
+class TestVander:
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+
+ def test_hermevander(self):
+ # check for 1d x
+ x = np.arange(3)
+ v = herme.hermevander(x, 3)
+ assert_(v.shape == (3, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], herme.hermeval(x, coef))
+
+ # check for 2d x
+ x = np.array([[1, 2], [3, 4], [5, 6]])
+ v = herme.hermevander(x, 3)
+ assert_(v.shape == (3, 2, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], herme.hermeval(x, coef))
+
+ def test_hermevander2d(self):
+ # also tests hermeval2d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3))
+ van = herme.hermevander2d(x1, x2, [1, 2])
+ tgt = herme.hermeval2d(x1, x2, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = herme.hermevander2d([x1], [x2], [1, 2])
+ assert_(van.shape == (1, 5, 6))
+
+ def test_hermevander3d(self):
+ # also tests hermeval3d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3, 4))
+ van = herme.hermevander3d(x1, x2, x3, [1, 2, 3])
+ tgt = herme.hermeval3d(x1, x2, x3, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = herme.hermevander3d([x1], [x2], [x3], [1, 2, 3])
+ assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting:
+
+ def test_hermefit(self):
+ def f(x):
+ return x*(x - 1)*(x - 2)
+
+ def f2(x):
+ return x**4 + x**2 + 1
+
+ # Test exceptions
+ assert_raises(ValueError, herme.hermefit, [1], [1], -1)
+ assert_raises(TypeError, herme.hermefit, [[1]], [1], 0)
+ assert_raises(TypeError, herme.hermefit, [], [1], 0)
+ assert_raises(TypeError, herme.hermefit, [1], [[[1]]], 0)
+ assert_raises(TypeError, herme.hermefit, [1, 2], [1], 0)
+ assert_raises(TypeError, herme.hermefit, [1], [1, 2], 0)
+ assert_raises(TypeError, herme.hermefit, [1], [1], 0, w=[[1]])
+ assert_raises(TypeError, herme.hermefit, [1], [1], 0, w=[1, 1])
+ assert_raises(ValueError, herme.hermefit, [1], [1], [-1,])
+ assert_raises(ValueError, herme.hermefit, [1], [1], [2, -1, 6])
+ assert_raises(TypeError, herme.hermefit, [1], [1], [])
+
+ # Test fit
+ x = np.linspace(0, 2)
+ y = f(x)
+ #
+ coef3 = herme.hermefit(x, y, 3)
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(herme.hermeval(x, coef3), y)
+ coef3 = herme.hermefit(x, y, [0, 1, 2, 3])
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(herme.hermeval(x, coef3), y)
+ #
+ coef4 = herme.hermefit(x, y, 4)
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(herme.hermeval(x, coef4), y)
+ coef4 = herme.hermefit(x, y, [0, 1, 2, 3, 4])
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(herme.hermeval(x, coef4), y)
+ # check things still work if deg is not in strict increasing
+ coef4 = herme.hermefit(x, y, [2, 3, 4, 1, 0])
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(herme.hermeval(x, coef4), y)
+ #
+ coef2d = herme.hermefit(x, np.array([y, y]).T, 3)
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ coef2d = herme.hermefit(x, np.array([y, y]).T, [0, 1, 2, 3])
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ # test weighting
+ w = np.zeros_like(x)
+ yw = y.copy()
+ w[1::2] = 1
+ y[0::2] = 0
+ wcoef3 = herme.hermefit(x, yw, 3, w=w)
+ assert_almost_equal(wcoef3, coef3)
+ wcoef3 = herme.hermefit(x, yw, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef3, coef3)
+ #
+ wcoef2d = herme.hermefit(x, np.array([yw, yw]).T, 3, w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ wcoef2d = herme.hermefit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ # test scaling with complex values x points whose square
+ # is zero when summed.
+ x = [1, 1j, -1, -1j]
+ assert_almost_equal(herme.hermefit(x, x, 1), [0, 1])
+ assert_almost_equal(herme.hermefit(x, x, [0, 1]), [0, 1])
+ # test fitting only even Legendre polynomials
+ x = np.linspace(-1, 1)
+ y = f2(x)
+ coef1 = herme.hermefit(x, y, 4)
+ assert_almost_equal(herme.hermeval(x, coef1), y)
+ coef2 = herme.hermefit(x, y, [0, 2, 4])
+ assert_almost_equal(herme.hermeval(x, coef2), y)
+ assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion:
+
+ def test_raises(self):
+ assert_raises(ValueError, herme.hermecompanion, [])
+ assert_raises(ValueError, herme.hermecompanion, [1])
+
+ def test_dimensions(self):
+ for i in range(1, 5):
+ coef = [0]*i + [1]
+ assert_(herme.hermecompanion(coef).shape == (i, i))
+
+ def test_linear_root(self):
+ assert_(herme.hermecompanion([1, 2])[0, 0] == -.5)
+
+
+class TestGauss:
+
+ def test_100(self):
+ x, w = herme.hermegauss(100)
+
+ # test orthogonality. Note that the results need to be normalized,
+ # otherwise the huge values that can arise from fast growing
+ # functions like Laguerre can be very confusing.
+ v = herme.hermevander(x, 99)
+ vv = np.dot(v.T * w, v)
+ vd = 1/np.sqrt(vv.diagonal())
+ vv = vd[:, None] * vv * vd
+ assert_almost_equal(vv, np.eye(100))
+
+ # check that the integral of 1 is correct
+ tgt = np.sqrt(2*np.pi)
+ assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc:
+
+ def test_hermefromroots(self):
+ res = herme.hermefromroots([])
+ assert_almost_equal(trim(res), [1])
+ for i in range(1, 5):
+ roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+ pol = herme.hermefromroots(roots)
+ res = herme.hermeval(roots, pol)
+ tgt = 0
+ assert_(len(pol) == i + 1)
+ assert_almost_equal(herme.herme2poly(pol)[-1], 1)
+ assert_almost_equal(res, tgt)
+
+ def test_hermeroots(self):
+ assert_almost_equal(herme.hermeroots([1]), [])
+ assert_almost_equal(herme.hermeroots([1, 1]), [-1])
+ for i in range(2, 5):
+ tgt = np.linspace(-1, 1, i)
+ res = herme.hermeroots(herme.hermefromroots(tgt))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_hermetrim(self):
+ coef = [2, -1, 1, 0]
+
+ # Test exceptions
+ assert_raises(ValueError, herme.hermetrim, coef, -1)
+
+ # Test results
+ assert_equal(herme.hermetrim(coef), coef[:-1])
+ assert_equal(herme.hermetrim(coef, 1), coef[:-3])
+ assert_equal(herme.hermetrim(coef, 2), [0])
+
+ def test_hermeline(self):
+ assert_equal(herme.hermeline(3, 4), [3, 4])
+
+ def test_herme2poly(self):
+ for i in range(10):
+ assert_almost_equal(herme.herme2poly([0]*i + [1]), Helist[i])
+
+ def test_poly2herme(self):
+ for i in range(10):
+ assert_almost_equal(herme.poly2herme(Helist[i]), [0]*i + [1])
+
+ def test_weight(self):
+ x = np.linspace(-5, 5, 11)
+ tgt = np.exp(-.5*x**2)
+ res = herme.hermeweight(x)
+ assert_almost_equal(res, tgt)
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_laguerre.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_laguerre.py
new file mode 100644
index 00000000..227ef3c5
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_laguerre.py
@@ -0,0 +1,537 @@
+"""Tests for laguerre module.
+
+"""
+from functools import reduce
+
+import numpy as np
+import numpy.polynomial.laguerre as lag
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+ assert_almost_equal, assert_raises, assert_equal, assert_,
+ )
+
+L0 = np.array([1])/1
+L1 = np.array([1, -1])/1
+L2 = np.array([2, -4, 1])/2
+L3 = np.array([6, -18, 9, -1])/6
+L4 = np.array([24, -96, 72, -16, 1])/24
+L5 = np.array([120, -600, 600, -200, 25, -1])/120
+L6 = np.array([720, -4320, 5400, -2400, 450, -36, 1])/720
+
+Llist = [L0, L1, L2, L3, L4, L5, L6]
+
+
+def trim(x):
+ return lag.lagtrim(x, tol=1e-6)
+
+
+class TestConstants:
+
+ def test_lagdomain(self):
+ assert_equal(lag.lagdomain, [0, 1])
+
+ def test_lagzero(self):
+ assert_equal(lag.lagzero, [0])
+
+ def test_lagone(self):
+ assert_equal(lag.lagone, [1])
+
+ def test_lagx(self):
+ assert_equal(lag.lagx, [1, -1])
+
+
+class TestArithmetic:
+ x = np.linspace(-3, 3, 100)
+
+ def test_lagadd(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] += 1
+ res = lag.lagadd([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_lagsub(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] -= 1
+ res = lag.lagsub([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_lagmulx(self):
+ assert_equal(lag.lagmulx([0]), [0])
+ assert_equal(lag.lagmulx([1]), [1, -1])
+ for i in range(1, 5):
+ ser = [0]*i + [1]
+ tgt = [0]*(i - 1) + [-i, 2*i + 1, -(i + 1)]
+ assert_almost_equal(lag.lagmulx(ser), tgt)
+
+ def test_lagmul(self):
+ # check values of result
+ for i in range(5):
+ pol1 = [0]*i + [1]
+ val1 = lag.lagval(self.x, pol1)
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ pol2 = [0]*j + [1]
+ val2 = lag.lagval(self.x, pol2)
+ pol3 = lag.lagmul(pol1, pol2)
+ val3 = lag.lagval(self.x, pol3)
+ assert_(len(pol3) == i + j + 1, msg)
+ assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+ def test_lagdiv(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ ci = [0]*i + [1]
+ cj = [0]*j + [1]
+ tgt = lag.lagadd(ci, cj)
+ quo, rem = lag.lagdiv(tgt, ci)
+ res = lag.lagadd(lag.lagmul(quo, ci), rem)
+ assert_almost_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_lagpow(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ c = np.arange(i + 1)
+ tgt = reduce(lag.lagmul, [c]*j, np.array([1]))
+ res = lag.lagpow(c, j)
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation:
+ # coefficients of 1 + 2*x + 3*x**2
+ c1d = np.array([9., -14., 6.])
+ c2d = np.einsum('i,j->ij', c1d, c1d)
+ c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+ y = polyval(x, [1., 2., 3.])
+
+ def test_lagval(self):
+ #check empty input
+ assert_equal(lag.lagval([], [1]).size, 0)
+
+ #check normal input)
+ x = np.linspace(-1, 1)
+ y = [polyval(x, c) for c in Llist]
+ for i in range(7):
+ msg = f"At i={i}"
+ tgt = y[i]
+ res = lag.lagval(x, [0]*i + [1])
+ assert_almost_equal(res, tgt, err_msg=msg)
+
+ #check that shape is preserved
+ for i in range(3):
+ dims = [2]*i
+ x = np.zeros(dims)
+ assert_equal(lag.lagval(x, [1]).shape, dims)
+ assert_equal(lag.lagval(x, [1, 0]).shape, dims)
+ assert_equal(lag.lagval(x, [1, 0, 0]).shape, dims)
+
+ def test_lagval2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises(ValueError, lag.lagval2d, x1, x2[:2], self.c2d)
+
+ #test values
+ tgt = y1*y2
+ res = lag.lagval2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = lag.lagval2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3))
+
+ def test_lagval3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises(ValueError, lag.lagval3d, x1, x2, x3[:2], self.c3d)
+
+ #test values
+ tgt = y1*y2*y3
+ res = lag.lagval3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = lag.lagval3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3))
+
+ def test_laggrid2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j->ij', y1, y2)
+ res = lag.laggrid2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = lag.laggrid2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3)*2)
+
+ def test_laggrid3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+ res = lag.laggrid3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = lag.laggrid3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral:
+
+ def test_lagint(self):
+ # check exceptions
+ assert_raises(TypeError, lag.lagint, [0], .5)
+ assert_raises(ValueError, lag.lagint, [0], -1)
+ assert_raises(ValueError, lag.lagint, [0], 1, [0, 0])
+ assert_raises(ValueError, lag.lagint, [0], lbnd=[0])
+ assert_raises(ValueError, lag.lagint, [0], scl=[0])
+ assert_raises(TypeError, lag.lagint, [0], axis=.5)
+
+ # test integration of zero polynomial
+ for i in range(2, 5):
+ k = [0]*(i - 2) + [1]
+ res = lag.lagint([0], m=i, k=k)
+ assert_almost_equal(res, [1, -1])
+
+ # check single integration with integration constant
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [1/scl]
+ lagpol = lag.poly2lag(pol)
+ lagint = lag.lagint(lagpol, m=1, k=[i])
+ res = lag.lag2poly(lagint)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check single integration with integration constant and lbnd
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ lagpol = lag.poly2lag(pol)
+ lagint = lag.lagint(lagpol, m=1, k=[i], lbnd=-1)
+ assert_almost_equal(lag.lagval(-1, lagint), i)
+
+ # check single integration with integration constant and scaling
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [2/scl]
+ lagpol = lag.poly2lag(pol)
+ lagint = lag.lagint(lagpol, m=1, k=[i], scl=2)
+ res = lag.lag2poly(lagint)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with default k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = lag.lagint(tgt, m=1)
+ res = lag.lagint(pol, m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with defined k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = lag.lagint(tgt, m=1, k=[k])
+ res = lag.lagint(pol, m=j, k=list(range(j)))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with lbnd
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = lag.lagint(tgt, m=1, k=[k], lbnd=-1)
+ res = lag.lagint(pol, m=j, k=list(range(j)), lbnd=-1)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = lag.lagint(tgt, m=1, k=[k], scl=2)
+ res = lag.lagint(pol, m=j, k=list(range(j)), scl=2)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_lagint_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([lag.lagint(c) for c in c2d.T]).T
+ res = lag.lagint(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([lag.lagint(c) for c in c2d])
+ res = lag.lagint(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([lag.lagint(c, k=3) for c in c2d])
+ res = lag.lagint(c2d, k=3, axis=1)
+ assert_almost_equal(res, tgt)
+
+
+class TestDerivative:
+
+ def test_lagder(self):
+ # check exceptions
+ assert_raises(TypeError, lag.lagder, [0], .5)
+ assert_raises(ValueError, lag.lagder, [0], -1)
+
+ # check that zeroth derivative does nothing
+ for i in range(5):
+ tgt = [0]*i + [1]
+ res = lag.lagder(tgt, m=0)
+ assert_equal(trim(res), trim(tgt))
+
+ # check that derivation is the inverse of integration
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = lag.lagder(lag.lagint(tgt, m=j), m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check derivation with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = lag.lagder(lag.lagint(tgt, m=j, scl=2), m=j, scl=.5)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_lagder_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([lag.lagder(c) for c in c2d.T]).T
+ res = lag.lagder(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([lag.lagder(c) for c in c2d])
+ res = lag.lagder(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+
+class TestVander:
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+
+ def test_lagvander(self):
+ # check for 1d x
+ x = np.arange(3)
+ v = lag.lagvander(x, 3)
+ assert_(v.shape == (3, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], lag.lagval(x, coef))
+
+ # check for 2d x
+ x = np.array([[1, 2], [3, 4], [5, 6]])
+ v = lag.lagvander(x, 3)
+ assert_(v.shape == (3, 2, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], lag.lagval(x, coef))
+
+ def test_lagvander2d(self):
+ # also tests lagval2d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3))
+ van = lag.lagvander2d(x1, x2, [1, 2])
+ tgt = lag.lagval2d(x1, x2, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = lag.lagvander2d([x1], [x2], [1, 2])
+ assert_(van.shape == (1, 5, 6))
+
+ def test_lagvander3d(self):
+ # also tests lagval3d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3, 4))
+ van = lag.lagvander3d(x1, x2, x3, [1, 2, 3])
+ tgt = lag.lagval3d(x1, x2, x3, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = lag.lagvander3d([x1], [x2], [x3], [1, 2, 3])
+ assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting:
+
+ def test_lagfit(self):
+ def f(x):
+ return x*(x - 1)*(x - 2)
+
+ # Test exceptions
+ assert_raises(ValueError, lag.lagfit, [1], [1], -1)
+ assert_raises(TypeError, lag.lagfit, [[1]], [1], 0)
+ assert_raises(TypeError, lag.lagfit, [], [1], 0)
+ assert_raises(TypeError, lag.lagfit, [1], [[[1]]], 0)
+ assert_raises(TypeError, lag.lagfit, [1, 2], [1], 0)
+ assert_raises(TypeError, lag.lagfit, [1], [1, 2], 0)
+ assert_raises(TypeError, lag.lagfit, [1], [1], 0, w=[[1]])
+ assert_raises(TypeError, lag.lagfit, [1], [1], 0, w=[1, 1])
+ assert_raises(ValueError, lag.lagfit, [1], [1], [-1,])
+ assert_raises(ValueError, lag.lagfit, [1], [1], [2, -1, 6])
+ assert_raises(TypeError, lag.lagfit, [1], [1], [])
+
+ # Test fit
+ x = np.linspace(0, 2)
+ y = f(x)
+ #
+ coef3 = lag.lagfit(x, y, 3)
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(lag.lagval(x, coef3), y)
+ coef3 = lag.lagfit(x, y, [0, 1, 2, 3])
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(lag.lagval(x, coef3), y)
+ #
+ coef4 = lag.lagfit(x, y, 4)
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(lag.lagval(x, coef4), y)
+ coef4 = lag.lagfit(x, y, [0, 1, 2, 3, 4])
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(lag.lagval(x, coef4), y)
+ #
+ coef2d = lag.lagfit(x, np.array([y, y]).T, 3)
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ coef2d = lag.lagfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ # test weighting
+ w = np.zeros_like(x)
+ yw = y.copy()
+ w[1::2] = 1
+ y[0::2] = 0
+ wcoef3 = lag.lagfit(x, yw, 3, w=w)
+ assert_almost_equal(wcoef3, coef3)
+ wcoef3 = lag.lagfit(x, yw, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef3, coef3)
+ #
+ wcoef2d = lag.lagfit(x, np.array([yw, yw]).T, 3, w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ wcoef2d = lag.lagfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ # test scaling with complex values x points whose square
+ # is zero when summed.
+ x = [1, 1j, -1, -1j]
+ assert_almost_equal(lag.lagfit(x, x, 1), [1, -1])
+ assert_almost_equal(lag.lagfit(x, x, [0, 1]), [1, -1])
+
+
+class TestCompanion:
+
+ def test_raises(self):
+ assert_raises(ValueError, lag.lagcompanion, [])
+ assert_raises(ValueError, lag.lagcompanion, [1])
+
+ def test_dimensions(self):
+ for i in range(1, 5):
+ coef = [0]*i + [1]
+ assert_(lag.lagcompanion(coef).shape == (i, i))
+
+ def test_linear_root(self):
+ assert_(lag.lagcompanion([1, 2])[0, 0] == 1.5)
+
+
+class TestGauss:
+
+ def test_100(self):
+ x, w = lag.laggauss(100)
+
+ # test orthogonality. Note that the results need to be normalized,
+ # otherwise the huge values that can arise from fast growing
+ # functions like Laguerre can be very confusing.
+ v = lag.lagvander(x, 99)
+ vv = np.dot(v.T * w, v)
+ vd = 1/np.sqrt(vv.diagonal())
+ vv = vd[:, None] * vv * vd
+ assert_almost_equal(vv, np.eye(100))
+
+ # check that the integral of 1 is correct
+ tgt = 1.0
+ assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc:
+
+ def test_lagfromroots(self):
+ res = lag.lagfromroots([])
+ assert_almost_equal(trim(res), [1])
+ for i in range(1, 5):
+ roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+ pol = lag.lagfromroots(roots)
+ res = lag.lagval(roots, pol)
+ tgt = 0
+ assert_(len(pol) == i + 1)
+ assert_almost_equal(lag.lag2poly(pol)[-1], 1)
+ assert_almost_equal(res, tgt)
+
+ def test_lagroots(self):
+ assert_almost_equal(lag.lagroots([1]), [])
+ assert_almost_equal(lag.lagroots([0, 1]), [1])
+ for i in range(2, 5):
+ tgt = np.linspace(0, 3, i)
+ res = lag.lagroots(lag.lagfromroots(tgt))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_lagtrim(self):
+ coef = [2, -1, 1, 0]
+
+ # Test exceptions
+ assert_raises(ValueError, lag.lagtrim, coef, -1)
+
+ # Test results
+ assert_equal(lag.lagtrim(coef), coef[:-1])
+ assert_equal(lag.lagtrim(coef, 1), coef[:-3])
+ assert_equal(lag.lagtrim(coef, 2), [0])
+
+ def test_lagline(self):
+ assert_equal(lag.lagline(3, 4), [7, -4])
+
+ def test_lag2poly(self):
+ for i in range(7):
+ assert_almost_equal(lag.lag2poly([0]*i + [1]), Llist[i])
+
+ def test_poly2lag(self):
+ for i in range(7):
+ assert_almost_equal(lag.poly2lag(Llist[i]), [0]*i + [1])
+
+ def test_weight(self):
+ x = np.linspace(0, 10, 11)
+ tgt = np.exp(-x)
+ res = lag.lagweight(x)
+ assert_almost_equal(res, tgt)
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_legendre.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_legendre.py
new file mode 100644
index 00000000..92399c16
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_legendre.py
@@ -0,0 +1,568 @@
+"""Tests for legendre module.
+
+"""
+from functools import reduce
+
+import numpy as np
+import numpy.polynomial.legendre as leg
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+ assert_almost_equal, assert_raises, assert_equal, assert_,
+ )
+
+L0 = np.array([1])
+L1 = np.array([0, 1])
+L2 = np.array([-1, 0, 3])/2
+L3 = np.array([0, -3, 0, 5])/2
+L4 = np.array([3, 0, -30, 0, 35])/8
+L5 = np.array([0, 15, 0, -70, 0, 63])/8
+L6 = np.array([-5, 0, 105, 0, -315, 0, 231])/16
+L7 = np.array([0, -35, 0, 315, 0, -693, 0, 429])/16
+L8 = np.array([35, 0, -1260, 0, 6930, 0, -12012, 0, 6435])/128
+L9 = np.array([0, 315, 0, -4620, 0, 18018, 0, -25740, 0, 12155])/128
+
+Llist = [L0, L1, L2, L3, L4, L5, L6, L7, L8, L9]
+
+
+def trim(x):
+ return leg.legtrim(x, tol=1e-6)
+
+
+class TestConstants:
+
+ def test_legdomain(self):
+ assert_equal(leg.legdomain, [-1, 1])
+
+ def test_legzero(self):
+ assert_equal(leg.legzero, [0])
+
+ def test_legone(self):
+ assert_equal(leg.legone, [1])
+
+ def test_legx(self):
+ assert_equal(leg.legx, [0, 1])
+
+
+class TestArithmetic:
+ x = np.linspace(-1, 1, 100)
+
+ def test_legadd(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] += 1
+ res = leg.legadd([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_legsub(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] -= 1
+ res = leg.legsub([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_legmulx(self):
+ assert_equal(leg.legmulx([0]), [0])
+ assert_equal(leg.legmulx([1]), [0, 1])
+ for i in range(1, 5):
+ tmp = 2*i + 1
+ ser = [0]*i + [1]
+ tgt = [0]*(i - 1) + [i/tmp, 0, (i + 1)/tmp]
+ assert_equal(leg.legmulx(ser), tgt)
+
+ def test_legmul(self):
+ # check values of result
+ for i in range(5):
+ pol1 = [0]*i + [1]
+ val1 = leg.legval(self.x, pol1)
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ pol2 = [0]*j + [1]
+ val2 = leg.legval(self.x, pol2)
+ pol3 = leg.legmul(pol1, pol2)
+ val3 = leg.legval(self.x, pol3)
+ assert_(len(pol3) == i + j + 1, msg)
+ assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+ def test_legdiv(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ ci = [0]*i + [1]
+ cj = [0]*j + [1]
+ tgt = leg.legadd(ci, cj)
+ quo, rem = leg.legdiv(tgt, ci)
+ res = leg.legadd(leg.legmul(quo, ci), rem)
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_legpow(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ c = np.arange(i + 1)
+ tgt = reduce(leg.legmul, [c]*j, np.array([1]))
+ res = leg.legpow(c, j)
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation:
+ # coefficients of 1 + 2*x + 3*x**2
+ c1d = np.array([2., 2., 2.])
+ c2d = np.einsum('i,j->ij', c1d, c1d)
+ c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+ y = polyval(x, [1., 2., 3.])
+
+ def test_legval(self):
+ #check empty input
+ assert_equal(leg.legval([], [1]).size, 0)
+
+ #check normal input)
+ x = np.linspace(-1, 1)
+ y = [polyval(x, c) for c in Llist]
+ for i in range(10):
+ msg = f"At i={i}"
+ tgt = y[i]
+ res = leg.legval(x, [0]*i + [1])
+ assert_almost_equal(res, tgt, err_msg=msg)
+
+ #check that shape is preserved
+ for i in range(3):
+ dims = [2]*i
+ x = np.zeros(dims)
+ assert_equal(leg.legval(x, [1]).shape, dims)
+ assert_equal(leg.legval(x, [1, 0]).shape, dims)
+ assert_equal(leg.legval(x, [1, 0, 0]).shape, dims)
+
+ def test_legval2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises(ValueError, leg.legval2d, x1, x2[:2], self.c2d)
+
+ #test values
+ tgt = y1*y2
+ res = leg.legval2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = leg.legval2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3))
+
+ def test_legval3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises(ValueError, leg.legval3d, x1, x2, x3[:2], self.c3d)
+
+ #test values
+ tgt = y1*y2*y3
+ res = leg.legval3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = leg.legval3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3))
+
+ def test_leggrid2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j->ij', y1, y2)
+ res = leg.leggrid2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = leg.leggrid2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3)*2)
+
+ def test_leggrid3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+ res = leg.leggrid3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = leg.leggrid3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral:
+
+ def test_legint(self):
+ # check exceptions
+ assert_raises(TypeError, leg.legint, [0], .5)
+ assert_raises(ValueError, leg.legint, [0], -1)
+ assert_raises(ValueError, leg.legint, [0], 1, [0, 0])
+ assert_raises(ValueError, leg.legint, [0], lbnd=[0])
+ assert_raises(ValueError, leg.legint, [0], scl=[0])
+ assert_raises(TypeError, leg.legint, [0], axis=.5)
+
+ # test integration of zero polynomial
+ for i in range(2, 5):
+ k = [0]*(i - 2) + [1]
+ res = leg.legint([0], m=i, k=k)
+ assert_almost_equal(res, [0, 1])
+
+ # check single integration with integration constant
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [1/scl]
+ legpol = leg.poly2leg(pol)
+ legint = leg.legint(legpol, m=1, k=[i])
+ res = leg.leg2poly(legint)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check single integration with integration constant and lbnd
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ legpol = leg.poly2leg(pol)
+ legint = leg.legint(legpol, m=1, k=[i], lbnd=-1)
+ assert_almost_equal(leg.legval(-1, legint), i)
+
+ # check single integration with integration constant and scaling
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [2/scl]
+ legpol = leg.poly2leg(pol)
+ legint = leg.legint(legpol, m=1, k=[i], scl=2)
+ res = leg.leg2poly(legint)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with default k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = leg.legint(tgt, m=1)
+ res = leg.legint(pol, m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with defined k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = leg.legint(tgt, m=1, k=[k])
+ res = leg.legint(pol, m=j, k=list(range(j)))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with lbnd
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = leg.legint(tgt, m=1, k=[k], lbnd=-1)
+ res = leg.legint(pol, m=j, k=list(range(j)), lbnd=-1)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = leg.legint(tgt, m=1, k=[k], scl=2)
+ res = leg.legint(pol, m=j, k=list(range(j)), scl=2)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_legint_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([leg.legint(c) for c in c2d.T]).T
+ res = leg.legint(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([leg.legint(c) for c in c2d])
+ res = leg.legint(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([leg.legint(c, k=3) for c in c2d])
+ res = leg.legint(c2d, k=3, axis=1)
+ assert_almost_equal(res, tgt)
+
+ def test_legint_zerointord(self):
+ assert_equal(leg.legint((1, 2, 3), 0), (1, 2, 3))
+
+
+class TestDerivative:
+
+ def test_legder(self):
+ # check exceptions
+ assert_raises(TypeError, leg.legder, [0], .5)
+ assert_raises(ValueError, leg.legder, [0], -1)
+
+ # check that zeroth derivative does nothing
+ for i in range(5):
+ tgt = [0]*i + [1]
+ res = leg.legder(tgt, m=0)
+ assert_equal(trim(res), trim(tgt))
+
+ # check that derivation is the inverse of integration
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = leg.legder(leg.legint(tgt, m=j), m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check derivation with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = leg.legder(leg.legint(tgt, m=j, scl=2), m=j, scl=.5)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_legder_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([leg.legder(c) for c in c2d.T]).T
+ res = leg.legder(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([leg.legder(c) for c in c2d])
+ res = leg.legder(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+ def test_legder_orderhigherthancoeff(self):
+ c = (1, 2, 3, 4)
+ assert_equal(leg.legder(c, 4), [0])
+
+class TestVander:
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+
+ def test_legvander(self):
+ # check for 1d x
+ x = np.arange(3)
+ v = leg.legvander(x, 3)
+ assert_(v.shape == (3, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], leg.legval(x, coef))
+
+ # check for 2d x
+ x = np.array([[1, 2], [3, 4], [5, 6]])
+ v = leg.legvander(x, 3)
+ assert_(v.shape == (3, 2, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], leg.legval(x, coef))
+
+ def test_legvander2d(self):
+ # also tests polyval2d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3))
+ van = leg.legvander2d(x1, x2, [1, 2])
+ tgt = leg.legval2d(x1, x2, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = leg.legvander2d([x1], [x2], [1, 2])
+ assert_(van.shape == (1, 5, 6))
+
+ def test_legvander3d(self):
+ # also tests polyval3d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3, 4))
+ van = leg.legvander3d(x1, x2, x3, [1, 2, 3])
+ tgt = leg.legval3d(x1, x2, x3, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = leg.legvander3d([x1], [x2], [x3], [1, 2, 3])
+ assert_(van.shape == (1, 5, 24))
+
+ def test_legvander_negdeg(self):
+ assert_raises(ValueError, leg.legvander, (1, 2, 3), -1)
+
+
+class TestFitting:
+
+ def test_legfit(self):
+ def f(x):
+ return x*(x - 1)*(x - 2)
+
+ def f2(x):
+ return x**4 + x**2 + 1
+
+ # Test exceptions
+ assert_raises(ValueError, leg.legfit, [1], [1], -1)
+ assert_raises(TypeError, leg.legfit, [[1]], [1], 0)
+ assert_raises(TypeError, leg.legfit, [], [1], 0)
+ assert_raises(TypeError, leg.legfit, [1], [[[1]]], 0)
+ assert_raises(TypeError, leg.legfit, [1, 2], [1], 0)
+ assert_raises(TypeError, leg.legfit, [1], [1, 2], 0)
+ assert_raises(TypeError, leg.legfit, [1], [1], 0, w=[[1]])
+ assert_raises(TypeError, leg.legfit, [1], [1], 0, w=[1, 1])
+ assert_raises(ValueError, leg.legfit, [1], [1], [-1,])
+ assert_raises(ValueError, leg.legfit, [1], [1], [2, -1, 6])
+ assert_raises(TypeError, leg.legfit, [1], [1], [])
+
+ # Test fit
+ x = np.linspace(0, 2)
+ y = f(x)
+ #
+ coef3 = leg.legfit(x, y, 3)
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(leg.legval(x, coef3), y)
+ coef3 = leg.legfit(x, y, [0, 1, 2, 3])
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(leg.legval(x, coef3), y)
+ #
+ coef4 = leg.legfit(x, y, 4)
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(leg.legval(x, coef4), y)
+ coef4 = leg.legfit(x, y, [0, 1, 2, 3, 4])
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(leg.legval(x, coef4), y)
+ # check things still work if deg is not in strict increasing
+ coef4 = leg.legfit(x, y, [2, 3, 4, 1, 0])
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(leg.legval(x, coef4), y)
+ #
+ coef2d = leg.legfit(x, np.array([y, y]).T, 3)
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ coef2d = leg.legfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ # test weighting
+ w = np.zeros_like(x)
+ yw = y.copy()
+ w[1::2] = 1
+ y[0::2] = 0
+ wcoef3 = leg.legfit(x, yw, 3, w=w)
+ assert_almost_equal(wcoef3, coef3)
+ wcoef3 = leg.legfit(x, yw, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef3, coef3)
+ #
+ wcoef2d = leg.legfit(x, np.array([yw, yw]).T, 3, w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ wcoef2d = leg.legfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ # test scaling with complex values x points whose square
+ # is zero when summed.
+ x = [1, 1j, -1, -1j]
+ assert_almost_equal(leg.legfit(x, x, 1), [0, 1])
+ assert_almost_equal(leg.legfit(x, x, [0, 1]), [0, 1])
+ # test fitting only even Legendre polynomials
+ x = np.linspace(-1, 1)
+ y = f2(x)
+ coef1 = leg.legfit(x, y, 4)
+ assert_almost_equal(leg.legval(x, coef1), y)
+ coef2 = leg.legfit(x, y, [0, 2, 4])
+ assert_almost_equal(leg.legval(x, coef2), y)
+ assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion:
+
+ def test_raises(self):
+ assert_raises(ValueError, leg.legcompanion, [])
+ assert_raises(ValueError, leg.legcompanion, [1])
+
+ def test_dimensions(self):
+ for i in range(1, 5):
+ coef = [0]*i + [1]
+ assert_(leg.legcompanion(coef).shape == (i, i))
+
+ def test_linear_root(self):
+ assert_(leg.legcompanion([1, 2])[0, 0] == -.5)
+
+
+class TestGauss:
+
+ def test_100(self):
+ x, w = leg.leggauss(100)
+
+ # test orthogonality. Note that the results need to be normalized,
+ # otherwise the huge values that can arise from fast growing
+ # functions like Laguerre can be very confusing.
+ v = leg.legvander(x, 99)
+ vv = np.dot(v.T * w, v)
+ vd = 1/np.sqrt(vv.diagonal())
+ vv = vd[:, None] * vv * vd
+ assert_almost_equal(vv, np.eye(100))
+
+ # check that the integral of 1 is correct
+ tgt = 2.0
+ assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc:
+
+ def test_legfromroots(self):
+ res = leg.legfromroots([])
+ assert_almost_equal(trim(res), [1])
+ for i in range(1, 5):
+ roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+ pol = leg.legfromroots(roots)
+ res = leg.legval(roots, pol)
+ tgt = 0
+ assert_(len(pol) == i + 1)
+ assert_almost_equal(leg.leg2poly(pol)[-1], 1)
+ assert_almost_equal(res, tgt)
+
+ def test_legroots(self):
+ assert_almost_equal(leg.legroots([1]), [])
+ assert_almost_equal(leg.legroots([1, 2]), [-.5])
+ for i in range(2, 5):
+ tgt = np.linspace(-1, 1, i)
+ res = leg.legroots(leg.legfromroots(tgt))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_legtrim(self):
+ coef = [2, -1, 1, 0]
+
+ # Test exceptions
+ assert_raises(ValueError, leg.legtrim, coef, -1)
+
+ # Test results
+ assert_equal(leg.legtrim(coef), coef[:-1])
+ assert_equal(leg.legtrim(coef, 1), coef[:-3])
+ assert_equal(leg.legtrim(coef, 2), [0])
+
+ def test_legline(self):
+ assert_equal(leg.legline(3, 4), [3, 4])
+
+ def test_legline_zeroscl(self):
+ assert_equal(leg.legline(3, 0), [3])
+
+ def test_leg2poly(self):
+ for i in range(10):
+ assert_almost_equal(leg.leg2poly([0]*i + [1]), Llist[i])
+
+ def test_poly2leg(self):
+ for i in range(10):
+ assert_almost_equal(leg.poly2leg(Llist[i]), [0]*i + [1])
+
+ def test_weight(self):
+ x = np.linspace(-1, 1, 11)
+ tgt = 1.
+ res = leg.legweight(x)
+ assert_almost_equal(res, tgt)
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_polynomial.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_polynomial.py
new file mode 100644
index 00000000..6b3ef238
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_polynomial.py
@@ -0,0 +1,611 @@
+"""Tests for polynomial module.
+
+"""
+from functools import reduce
+
+import numpy as np
+import numpy.polynomial.polynomial as poly
+import pickle
+from copy import deepcopy
+from numpy.testing import (
+ assert_almost_equal, assert_raises, assert_equal, assert_,
+ assert_warns, assert_array_equal, assert_raises_regex)
+
+
+def trim(x):
+ return poly.polytrim(x, tol=1e-6)
+
+T0 = [1]
+T1 = [0, 1]
+T2 = [-1, 0, 2]
+T3 = [0, -3, 0, 4]
+T4 = [1, 0, -8, 0, 8]
+T5 = [0, 5, 0, -20, 0, 16]
+T6 = [-1, 0, 18, 0, -48, 0, 32]
+T7 = [0, -7, 0, 56, 0, -112, 0, 64]
+T8 = [1, 0, -32, 0, 160, 0, -256, 0, 128]
+T9 = [0, 9, 0, -120, 0, 432, 0, -576, 0, 256]
+
+Tlist = [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]
+
+
+class TestConstants:
+
+ def test_polydomain(self):
+ assert_equal(poly.polydomain, [-1, 1])
+
+ def test_polyzero(self):
+ assert_equal(poly.polyzero, [0])
+
+ def test_polyone(self):
+ assert_equal(poly.polyone, [1])
+
+ def test_polyx(self):
+ assert_equal(poly.polyx, [0, 1])
+
+ def test_copy(self):
+ x = poly.Polynomial([1, 2, 3])
+ y = deepcopy(x)
+ assert_equal(x, y)
+
+ def test_pickle(self):
+ x = poly.Polynomial([1, 2, 3])
+ y = pickle.loads(pickle.dumps(x))
+ assert_equal(x, y)
+
+class TestArithmetic:
+
+ def test_polyadd(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] += 1
+ res = poly.polyadd([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_polysub(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(max(i, j) + 1)
+ tgt[i] += 1
+ tgt[j] -= 1
+ res = poly.polysub([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_polymulx(self):
+ assert_equal(poly.polymulx([0]), [0])
+ assert_equal(poly.polymulx([1]), [0, 1])
+ for i in range(1, 5):
+ ser = [0]*i + [1]
+ tgt = [0]*(i + 1) + [1]
+ assert_equal(poly.polymulx(ser), tgt)
+
+ def test_polymul(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ tgt = np.zeros(i + j + 1)
+ tgt[i + j] += 1
+ res = poly.polymul([0]*i + [1], [0]*j + [1])
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+ def test_polydiv(self):
+ # check zero division
+ assert_raises(ZeroDivisionError, poly.polydiv, [1], [0])
+
+ # check scalar division
+ quo, rem = poly.polydiv([2], [2])
+ assert_equal((quo, rem), (1, 0))
+ quo, rem = poly.polydiv([2, 2], [2])
+ assert_equal((quo, rem), ((1, 1), 0))
+
+ # check rest.
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ ci = [0]*i + [1, 2]
+ cj = [0]*j + [1, 2]
+ tgt = poly.polyadd(ci, cj)
+ quo, rem = poly.polydiv(tgt, ci)
+ res = poly.polyadd(poly.polymul(quo, ci), rem)
+ assert_equal(res, tgt, err_msg=msg)
+
+ def test_polypow(self):
+ for i in range(5):
+ for j in range(5):
+ msg = f"At i={i}, j={j}"
+ c = np.arange(i + 1)
+ tgt = reduce(poly.polymul, [c]*j, np.array([1]))
+ res = poly.polypow(c, j)
+ assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation:
+ # coefficients of 1 + 2*x + 3*x**2
+ c1d = np.array([1., 2., 3.])
+ c2d = np.einsum('i,j->ij', c1d, c1d)
+ c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+ y = poly.polyval(x, [1., 2., 3.])
+
+ def test_polyval(self):
+ #check empty input
+ assert_equal(poly.polyval([], [1]).size, 0)
+
+ #check normal input)
+ x = np.linspace(-1, 1)
+ y = [x**i for i in range(5)]
+ for i in range(5):
+ tgt = y[i]
+ res = poly.polyval(x, [0]*i + [1])
+ assert_almost_equal(res, tgt)
+ tgt = x*(x**2 - 1)
+ res = poly.polyval(x, [0, -1, 0, 1])
+ assert_almost_equal(res, tgt)
+
+ #check that shape is preserved
+ for i in range(3):
+ dims = [2]*i
+ x = np.zeros(dims)
+ assert_equal(poly.polyval(x, [1]).shape, dims)
+ assert_equal(poly.polyval(x, [1, 0]).shape, dims)
+ assert_equal(poly.polyval(x, [1, 0, 0]).shape, dims)
+
+ #check masked arrays are processed correctly
+ mask = [False, True, False]
+ mx = np.ma.array([1, 2, 3], mask=mask)
+ res = np.polyval([7, 5, 3], mx)
+ assert_array_equal(res.mask, mask)
+
+ #check subtypes of ndarray are preserved
+ class C(np.ndarray):
+ pass
+
+ cx = np.array([1, 2, 3]).view(C)
+ assert_equal(type(np.polyval([2, 3, 4], cx)), C)
+
+ def test_polyvalfromroots(self):
+ # check exception for broadcasting x values over root array with
+ # too few dimensions
+ assert_raises(ValueError, poly.polyvalfromroots,
+ [1], [1], tensor=False)
+
+ # check empty input
+ assert_equal(poly.polyvalfromroots([], [1]).size, 0)
+ assert_(poly.polyvalfromroots([], [1]).shape == (0,))
+
+ # check empty input + multidimensional roots
+ assert_equal(poly.polyvalfromroots([], [[1] * 5]).size, 0)
+ assert_(poly.polyvalfromroots([], [[1] * 5]).shape == (5, 0))
+
+ # check scalar input
+ assert_equal(poly.polyvalfromroots(1, 1), 0)
+ assert_(poly.polyvalfromroots(1, np.ones((3, 3))).shape == (3,))
+
+ # check normal input)
+ x = np.linspace(-1, 1)
+ y = [x**i for i in range(5)]
+ for i in range(1, 5):
+ tgt = y[i]
+ res = poly.polyvalfromroots(x, [0]*i)
+ assert_almost_equal(res, tgt)
+ tgt = x*(x - 1)*(x + 1)
+ res = poly.polyvalfromroots(x, [-1, 0, 1])
+ assert_almost_equal(res, tgt)
+
+ # check that shape is preserved
+ for i in range(3):
+ dims = [2]*i
+ x = np.zeros(dims)
+ assert_equal(poly.polyvalfromroots(x, [1]).shape, dims)
+ assert_equal(poly.polyvalfromroots(x, [1, 0]).shape, dims)
+ assert_equal(poly.polyvalfromroots(x, [1, 0, 0]).shape, dims)
+
+ # check compatibility with factorization
+ ptest = [15, 2, -16, -2, 1]
+ r = poly.polyroots(ptest)
+ x = np.linspace(-1, 1)
+ assert_almost_equal(poly.polyval(x, ptest),
+ poly.polyvalfromroots(x, r))
+
+ # check multidimensional arrays of roots and values
+ # check tensor=False
+ rshape = (3, 5)
+ x = np.arange(-3, 2)
+ r = np.random.randint(-5, 5, size=rshape)
+ res = poly.polyvalfromroots(x, r, tensor=False)
+ tgt = np.empty(r.shape[1:])
+ for ii in range(tgt.size):
+ tgt[ii] = poly.polyvalfromroots(x[ii], r[:, ii])
+ assert_equal(res, tgt)
+
+ # check tensor=True
+ x = np.vstack([x, 2*x])
+ res = poly.polyvalfromroots(x, r, tensor=True)
+ tgt = np.empty(r.shape[1:] + x.shape)
+ for ii in range(r.shape[1]):
+ for jj in range(x.shape[0]):
+ tgt[ii, jj, :] = poly.polyvalfromroots(x[jj], r[:, ii])
+ assert_equal(res, tgt)
+
+ def test_polyval2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises_regex(ValueError, 'incompatible',
+ poly.polyval2d, x1, x2[:2], self.c2d)
+
+ #test values
+ tgt = y1*y2
+ res = poly.polyval2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = poly.polyval2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3))
+
+ def test_polyval3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test exceptions
+ assert_raises_regex(ValueError, 'incompatible',
+ poly.polyval3d, x1, x2, x3[:2], self.c3d)
+
+ #test values
+ tgt = y1*y2*y3
+ res = poly.polyval3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = poly.polyval3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3))
+
+ def test_polygrid2d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j->ij', y1, y2)
+ res = poly.polygrid2d(x1, x2, self.c2d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = poly.polygrid2d(z, z, self.c2d)
+ assert_(res.shape == (2, 3)*2)
+
+ def test_polygrid3d(self):
+ x1, x2, x3 = self.x
+ y1, y2, y3 = self.y
+
+ #test values
+ tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+ res = poly.polygrid3d(x1, x2, x3, self.c3d)
+ assert_almost_equal(res, tgt)
+
+ #test shape
+ z = np.ones((2, 3))
+ res = poly.polygrid3d(z, z, z, self.c3d)
+ assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral:
+
+ def test_polyint(self):
+ # check exceptions
+ assert_raises(TypeError, poly.polyint, [0], .5)
+ assert_raises(ValueError, poly.polyint, [0], -1)
+ assert_raises(ValueError, poly.polyint, [0], 1, [0, 0])
+ assert_raises(ValueError, poly.polyint, [0], lbnd=[0])
+ assert_raises(ValueError, poly.polyint, [0], scl=[0])
+ assert_raises(TypeError, poly.polyint, [0], axis=.5)
+ with assert_warns(DeprecationWarning):
+ poly.polyint([1, 1], 1.)
+
+ # test integration of zero polynomial
+ for i in range(2, 5):
+ k = [0]*(i - 2) + [1]
+ res = poly.polyint([0], m=i, k=k)
+ assert_almost_equal(res, [0, 1])
+
+ # check single integration with integration constant
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [1/scl]
+ res = poly.polyint(pol, m=1, k=[i])
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check single integration with integration constant and lbnd
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ res = poly.polyint(pol, m=1, k=[i], lbnd=-1)
+ assert_almost_equal(poly.polyval(-1, res), i)
+
+ # check single integration with integration constant and scaling
+ for i in range(5):
+ scl = i + 1
+ pol = [0]*i + [1]
+ tgt = [i] + [0]*i + [2/scl]
+ res = poly.polyint(pol, m=1, k=[i], scl=2)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with default k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = poly.polyint(tgt, m=1)
+ res = poly.polyint(pol, m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with defined k
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = poly.polyint(tgt, m=1, k=[k])
+ res = poly.polyint(pol, m=j, k=list(range(j)))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with lbnd
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = poly.polyint(tgt, m=1, k=[k], lbnd=-1)
+ res = poly.polyint(pol, m=j, k=list(range(j)), lbnd=-1)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check multiple integrations with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ pol = [0]*i + [1]
+ tgt = pol[:]
+ for k in range(j):
+ tgt = poly.polyint(tgt, m=1, k=[k], scl=2)
+ res = poly.polyint(pol, m=j, k=list(range(j)), scl=2)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_polyint_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([poly.polyint(c) for c in c2d.T]).T
+ res = poly.polyint(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([poly.polyint(c) for c in c2d])
+ res = poly.polyint(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([poly.polyint(c, k=3) for c in c2d])
+ res = poly.polyint(c2d, k=3, axis=1)
+ assert_almost_equal(res, tgt)
+
+
+class TestDerivative:
+
+ def test_polyder(self):
+ # check exceptions
+ assert_raises(TypeError, poly.polyder, [0], .5)
+ assert_raises(ValueError, poly.polyder, [0], -1)
+
+ # check that zeroth derivative does nothing
+ for i in range(5):
+ tgt = [0]*i + [1]
+ res = poly.polyder(tgt, m=0)
+ assert_equal(trim(res), trim(tgt))
+
+ # check that derivation is the inverse of integration
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = poly.polyder(poly.polyint(tgt, m=j), m=j)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ # check derivation with scaling
+ for i in range(5):
+ for j in range(2, 5):
+ tgt = [0]*i + [1]
+ res = poly.polyder(poly.polyint(tgt, m=j, scl=2), m=j, scl=.5)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_polyder_axis(self):
+ # check that axis keyword works
+ c2d = np.random.random((3, 4))
+
+ tgt = np.vstack([poly.polyder(c) for c in c2d.T]).T
+ res = poly.polyder(c2d, axis=0)
+ assert_almost_equal(res, tgt)
+
+ tgt = np.vstack([poly.polyder(c) for c in c2d])
+ res = poly.polyder(c2d, axis=1)
+ assert_almost_equal(res, tgt)
+
+
+class TestVander:
+ # some random values in [-1, 1)
+ x = np.random.random((3, 5))*2 - 1
+
+ def test_polyvander(self):
+ # check for 1d x
+ x = np.arange(3)
+ v = poly.polyvander(x, 3)
+ assert_(v.shape == (3, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], poly.polyval(x, coef))
+
+ # check for 2d x
+ x = np.array([[1, 2], [3, 4], [5, 6]])
+ v = poly.polyvander(x, 3)
+ assert_(v.shape == (3, 2, 4))
+ for i in range(4):
+ coef = [0]*i + [1]
+ assert_almost_equal(v[..., i], poly.polyval(x, coef))
+
+ def test_polyvander2d(self):
+ # also tests polyval2d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3))
+ van = poly.polyvander2d(x1, x2, [1, 2])
+ tgt = poly.polyval2d(x1, x2, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = poly.polyvander2d([x1], [x2], [1, 2])
+ assert_(van.shape == (1, 5, 6))
+
+ def test_polyvander3d(self):
+ # also tests polyval3d for non-square coefficient array
+ x1, x2, x3 = self.x
+ c = np.random.random((2, 3, 4))
+ van = poly.polyvander3d(x1, x2, x3, [1, 2, 3])
+ tgt = poly.polyval3d(x1, x2, x3, c)
+ res = np.dot(van, c.flat)
+ assert_almost_equal(res, tgt)
+
+ # check shape
+ van = poly.polyvander3d([x1], [x2], [x3], [1, 2, 3])
+ assert_(van.shape == (1, 5, 24))
+
+ def test_polyvandernegdeg(self):
+ x = np.arange(3)
+ assert_raises(ValueError, poly.polyvander, x, -1)
+
+
+class TestCompanion:
+
+ def test_raises(self):
+ assert_raises(ValueError, poly.polycompanion, [])
+ assert_raises(ValueError, poly.polycompanion, [1])
+
+ def test_dimensions(self):
+ for i in range(1, 5):
+ coef = [0]*i + [1]
+ assert_(poly.polycompanion(coef).shape == (i, i))
+
+ def test_linear_root(self):
+ assert_(poly.polycompanion([1, 2])[0, 0] == -.5)
+
+
+class TestMisc:
+
+ def test_polyfromroots(self):
+ res = poly.polyfromroots([])
+ assert_almost_equal(trim(res), [1])
+ for i in range(1, 5):
+ roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+ tgt = Tlist[i]
+ res = poly.polyfromroots(roots)*2**(i-1)
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_polyroots(self):
+ assert_almost_equal(poly.polyroots([1]), [])
+ assert_almost_equal(poly.polyroots([1, 2]), [-.5])
+ for i in range(2, 5):
+ tgt = np.linspace(-1, 1, i)
+ res = poly.polyroots(poly.polyfromroots(tgt))
+ assert_almost_equal(trim(res), trim(tgt))
+
+ def test_polyfit(self):
+ def f(x):
+ return x*(x - 1)*(x - 2)
+
+ def f2(x):
+ return x**4 + x**2 + 1
+
+ # Test exceptions
+ assert_raises(ValueError, poly.polyfit, [1], [1], -1)
+ assert_raises(TypeError, poly.polyfit, [[1]], [1], 0)
+ assert_raises(TypeError, poly.polyfit, [], [1], 0)
+ assert_raises(TypeError, poly.polyfit, [1], [[[1]]], 0)
+ assert_raises(TypeError, poly.polyfit, [1, 2], [1], 0)
+ assert_raises(TypeError, poly.polyfit, [1], [1, 2], 0)
+ assert_raises(TypeError, poly.polyfit, [1], [1], 0, w=[[1]])
+ assert_raises(TypeError, poly.polyfit, [1], [1], 0, w=[1, 1])
+ assert_raises(ValueError, poly.polyfit, [1], [1], [-1,])
+ assert_raises(ValueError, poly.polyfit, [1], [1], [2, -1, 6])
+ assert_raises(TypeError, poly.polyfit, [1], [1], [])
+
+ # Test fit
+ x = np.linspace(0, 2)
+ y = f(x)
+ #
+ coef3 = poly.polyfit(x, y, 3)
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(poly.polyval(x, coef3), y)
+ coef3 = poly.polyfit(x, y, [0, 1, 2, 3])
+ assert_equal(len(coef3), 4)
+ assert_almost_equal(poly.polyval(x, coef3), y)
+ #
+ coef4 = poly.polyfit(x, y, 4)
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(poly.polyval(x, coef4), y)
+ coef4 = poly.polyfit(x, y, [0, 1, 2, 3, 4])
+ assert_equal(len(coef4), 5)
+ assert_almost_equal(poly.polyval(x, coef4), y)
+ #
+ coef2d = poly.polyfit(x, np.array([y, y]).T, 3)
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ coef2d = poly.polyfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+ assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+ # test weighting
+ w = np.zeros_like(x)
+ yw = y.copy()
+ w[1::2] = 1
+ yw[0::2] = 0
+ wcoef3 = poly.polyfit(x, yw, 3, w=w)
+ assert_almost_equal(wcoef3, coef3)
+ wcoef3 = poly.polyfit(x, yw, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef3, coef3)
+ #
+ wcoef2d = poly.polyfit(x, np.array([yw, yw]).T, 3, w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ wcoef2d = poly.polyfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+ assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+ # test scaling with complex values x points whose square
+ # is zero when summed.
+ x = [1, 1j, -1, -1j]
+ assert_almost_equal(poly.polyfit(x, x, 1), [0, 1])
+ assert_almost_equal(poly.polyfit(x, x, [0, 1]), [0, 1])
+ # test fitting only even Polyendre polynomials
+ x = np.linspace(-1, 1)
+ y = f2(x)
+ coef1 = poly.polyfit(x, y, 4)
+ assert_almost_equal(poly.polyval(x, coef1), y)
+ coef2 = poly.polyfit(x, y, [0, 2, 4])
+ assert_almost_equal(poly.polyval(x, coef2), y)
+ assert_almost_equal(coef1, coef2)
+
+ def test_polytrim(self):
+ coef = [2, -1, 1, 0]
+
+ # Test exceptions
+ assert_raises(ValueError, poly.polytrim, coef, -1)
+
+ # Test results
+ assert_equal(poly.polytrim(coef), coef[:-1])
+ assert_equal(poly.polytrim(coef, 1), coef[:-3])
+ assert_equal(poly.polytrim(coef, 2), [0])
+
+ def test_polyline(self):
+ assert_equal(poly.polyline(3, 4), [3, 4])
+
+ def test_polyline_zero(self):
+ assert_equal(poly.polyline(3, 0), [3])
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_polyutils.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_polyutils.py
new file mode 100644
index 00000000..cc630790
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_polyutils.py
@@ -0,0 +1,121 @@
+"""Tests for polyutils module.
+
+"""
+import numpy as np
+import numpy.polynomial.polyutils as pu
+from numpy.testing import (
+ assert_almost_equal, assert_raises, assert_equal, assert_,
+ )
+
+
+class TestMisc:
+
+ def test_trimseq(self):
+ for i in range(5):
+ tgt = [1]
+ res = pu.trimseq([1] + [0]*5)
+ assert_equal(res, tgt)
+
+ def test_as_series(self):
+ # check exceptions
+ assert_raises(ValueError, pu.as_series, [[]])
+ assert_raises(ValueError, pu.as_series, [[[1, 2]]])
+ assert_raises(ValueError, pu.as_series, [[1], ['a']])
+ # check common types
+ types = ['i', 'd', 'O']
+ for i in range(len(types)):
+ for j in range(i):
+ ci = np.ones(1, types[i])
+ cj = np.ones(1, types[j])
+ [resi, resj] = pu.as_series([ci, cj])
+ assert_(resi.dtype.char == resj.dtype.char)
+ assert_(resj.dtype.char == types[i])
+
+ def test_trimcoef(self):
+ coef = [2, -1, 1, 0]
+ # Test exceptions
+ assert_raises(ValueError, pu.trimcoef, coef, -1)
+ # Test results
+ assert_equal(pu.trimcoef(coef), coef[:-1])
+ assert_equal(pu.trimcoef(coef, 1), coef[:-3])
+ assert_equal(pu.trimcoef(coef, 2), [0])
+
+ def test_vander_nd_exception(self):
+ # n_dims != len(points)
+ assert_raises(ValueError, pu._vander_nd, (), (1, 2, 3), [90])
+ # n_dims != len(degrees)
+ assert_raises(ValueError, pu._vander_nd, (), (), [90.65])
+ # n_dims == 0
+ assert_raises(ValueError, pu._vander_nd, (), (), [])
+
+ def test_div_zerodiv(self):
+ # c2[-1] == 0
+ assert_raises(ZeroDivisionError, pu._div, pu._div, (1, 2, 3), [0])
+
+ def test_pow_too_large(self):
+ # power > maxpower
+ assert_raises(ValueError, pu._pow, (), [1, 2, 3], 5, 4)
+
+class TestDomain:
+
+ def test_getdomain(self):
+ # test for real values
+ x = [1, 10, 3, -1]
+ tgt = [-1, 10]
+ res = pu.getdomain(x)
+ assert_almost_equal(res, tgt)
+
+ # test for complex values
+ x = [1 + 1j, 1 - 1j, 0, 2]
+ tgt = [-1j, 2 + 1j]
+ res = pu.getdomain(x)
+ assert_almost_equal(res, tgt)
+
+ def test_mapdomain(self):
+ # test for real values
+ dom1 = [0, 4]
+ dom2 = [1, 3]
+ tgt = dom2
+ res = pu.mapdomain(dom1, dom1, dom2)
+ assert_almost_equal(res, tgt)
+
+ # test for complex values
+ dom1 = [0 - 1j, 2 + 1j]
+ dom2 = [-2, 2]
+ tgt = dom2
+ x = dom1
+ res = pu.mapdomain(x, dom1, dom2)
+ assert_almost_equal(res, tgt)
+
+ # test for multidimensional arrays
+ dom1 = [0, 4]
+ dom2 = [1, 3]
+ tgt = np.array([dom2, dom2])
+ x = np.array([dom1, dom1])
+ res = pu.mapdomain(x, dom1, dom2)
+ assert_almost_equal(res, tgt)
+
+ # test that subtypes are preserved.
+ class MyNDArray(np.ndarray):
+ pass
+
+ dom1 = [0, 4]
+ dom2 = [1, 3]
+ x = np.array([dom1, dom1]).view(MyNDArray)
+ res = pu.mapdomain(x, dom1, dom2)
+ assert_(isinstance(res, MyNDArray))
+
+ def test_mapparms(self):
+ # test for real values
+ dom1 = [0, 4]
+ dom2 = [1, 3]
+ tgt = [1, .5]
+ res = pu. mapparms(dom1, dom2)
+ assert_almost_equal(res, tgt)
+
+ # test for complex values
+ dom1 = [0 - 1j, 2 + 1j]
+ dom2 = [-2, 2]
+ tgt = [-1 + 1j, 1 - 1j]
+ res = pu.mapparms(dom1, dom2)
+ assert_almost_equal(res, tgt)
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_printing.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_printing.py
new file mode 100644
index 00000000..6f2a5092
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_printing.py
@@ -0,0 +1,530 @@
+from math import nan, inf
+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:
+
+ @pytest.fixture(scope='class', autouse=True)
+ def use_unicode(self):
+ poly.set_default_printstyle('unicode')
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0·x + 3.0·x²"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0·x + 3.0·x² - 1.0·x³"),
+ (arange(12), ("0.0 + 1.0·x + 2.0·x² + 3.0·x³ + 4.0·x⁴ + 5.0·x⁵ + "
+ "6.0·x⁶ + 7.0·x⁷ +\n8.0·x⁸ + 9.0·x⁹ + 10.0·x¹⁰ + "
+ "11.0·x¹¹")),
+ ))
+ def test_polynomial_str(self, inp, tgt):
+ res = str(poly.Polynomial(inp))
+ assert_equal(res, tgt)
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0·T₁(x) + 3.0·T₂(x)"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0·T₁(x) + 3.0·T₂(x) - 1.0·T₃(x)"),
+ (arange(12), ("0.0 + 1.0·T₁(x) + 2.0·T₂(x) + 3.0·T₃(x) + 4.0·T₄(x) + "
+ "5.0·T₅(x) +\n6.0·T₆(x) + 7.0·T₇(x) + 8.0·T₈(x) + "
+ "9.0·T₉(x) + 10.0·T₁₀(x) + 11.0·T₁₁(x)")),
+ ))
+ def test_chebyshev_str(self, inp, tgt):
+ res = str(poly.Chebyshev(inp))
+ assert_equal(res, tgt)
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0·P₁(x) + 3.0·P₂(x)"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0·P₁(x) + 3.0·P₂(x) - 1.0·P₃(x)"),
+ (arange(12), ("0.0 + 1.0·P₁(x) + 2.0·P₂(x) + 3.0·P₃(x) + 4.0·P₄(x) + "
+ "5.0·P₅(x) +\n6.0·P₆(x) + 7.0·P₇(x) + 8.0·P₈(x) + "
+ "9.0·P₉(x) + 10.0·P₁₀(x) + 11.0·P₁₁(x)")),
+ ))
+ def test_legendre_str(self, inp, tgt):
+ res = str(poly.Legendre(inp))
+ assert_equal(res, tgt)
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0·H₁(x) + 3.0·H₂(x)"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0·H₁(x) + 3.0·H₂(x) - 1.0·H₃(x)"),
+ (arange(12), ("0.0 + 1.0·H₁(x) + 2.0·H₂(x) + 3.0·H₃(x) + 4.0·H₄(x) + "
+ "5.0·H₅(x) +\n6.0·H₆(x) + 7.0·H₇(x) + 8.0·H₈(x) + "
+ "9.0·H₉(x) + 10.0·H₁₀(x) + 11.0·H₁₁(x)")),
+ ))
+ def test_hermite_str(self, inp, tgt):
+ res = str(poly.Hermite(inp))
+ assert_equal(res, tgt)
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0·He₁(x) + 3.0·He₂(x)"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0·He₁(x) + 3.0·He₂(x) - 1.0·He₃(x)"),
+ (arange(12), ("0.0 + 1.0·He₁(x) + 2.0·He₂(x) + 3.0·He₃(x) + "
+ "4.0·He₄(x) + 5.0·He₅(x) +\n6.0·He₆(x) + 7.0·He₇(x) + "
+ "8.0·He₈(x) + 9.0·He₉(x) + 10.0·He₁₀(x) +\n"
+ "11.0·He₁₁(x)")),
+ ))
+ def test_hermiteE_str(self, inp, tgt):
+ res = str(poly.HermiteE(inp))
+ assert_equal(res, tgt)
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0·L₁(x) + 3.0·L₂(x)"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0·L₁(x) + 3.0·L₂(x) - 1.0·L₃(x)"),
+ (arange(12), ("0.0 + 1.0·L₁(x) + 2.0·L₂(x) + 3.0·L₃(x) + 4.0·L₄(x) + "
+ "5.0·L₅(x) +\n6.0·L₆(x) + 7.0·L₇(x) + 8.0·L₈(x) + "
+ "9.0·L₉(x) + 10.0·L₁₀(x) + 11.0·L₁₁(x)")),
+ ))
+ def test_laguerre_str(self, inp, tgt):
+ res = str(poly.Laguerre(inp))
+ assert_equal(res, tgt)
+
+
+class TestStrAscii:
+
+ @pytest.fixture(scope='class', autouse=True)
+ def use_ascii(self):
+ poly.set_default_printstyle('ascii')
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0 x + 3.0 x**2"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0 x + 3.0 x**2 - 1.0 x**3"),
+ (arange(12), ("0.0 + 1.0 x + 2.0 x**2 + 3.0 x**3 + 4.0 x**4 + "
+ "5.0 x**5 + 6.0 x**6 +\n7.0 x**7 + 8.0 x**8 + "
+ "9.0 x**9 + 10.0 x**10 + 11.0 x**11")),
+ ))
+ def test_polynomial_str(self, inp, tgt):
+ res = str(poly.Polynomial(inp))
+ assert_equal(res, tgt)
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0 T_1(x) + 3.0 T_2(x)"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0 T_1(x) + 3.0 T_2(x) - 1.0 T_3(x)"),
+ (arange(12), ("0.0 + 1.0 T_1(x) + 2.0 T_2(x) + 3.0 T_3(x) + "
+ "4.0 T_4(x) + 5.0 T_5(x) +\n6.0 T_6(x) + 7.0 T_7(x) + "
+ "8.0 T_8(x) + 9.0 T_9(x) + 10.0 T_10(x) +\n"
+ "11.0 T_11(x)")),
+ ))
+ def test_chebyshev_str(self, inp, tgt):
+ res = str(poly.Chebyshev(inp))
+ assert_equal(res, tgt)
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0 P_1(x) + 3.0 P_2(x)"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0 P_1(x) + 3.0 P_2(x) - 1.0 P_3(x)"),
+ (arange(12), ("0.0 + 1.0 P_1(x) + 2.0 P_2(x) + 3.0 P_3(x) + "
+ "4.0 P_4(x) + 5.0 P_5(x) +\n6.0 P_6(x) + 7.0 P_7(x) + "
+ "8.0 P_8(x) + 9.0 P_9(x) + 10.0 P_10(x) +\n"
+ "11.0 P_11(x)")),
+ ))
+ def test_legendre_str(self, inp, tgt):
+ res = str(poly.Legendre(inp))
+ assert_equal(res, tgt)
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0 H_1(x) + 3.0 H_2(x)"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0 H_1(x) + 3.0 H_2(x) - 1.0 H_3(x)"),
+ (arange(12), ("0.0 + 1.0 H_1(x) + 2.0 H_2(x) + 3.0 H_3(x) + "
+ "4.0 H_4(x) + 5.0 H_5(x) +\n6.0 H_6(x) + 7.0 H_7(x) + "
+ "8.0 H_8(x) + 9.0 H_9(x) + 10.0 H_10(x) +\n"
+ "11.0 H_11(x)")),
+ ))
+ def test_hermite_str(self, inp, tgt):
+ res = str(poly.Hermite(inp))
+ assert_equal(res, tgt)
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0 He_1(x) + 3.0 He_2(x)"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0 He_1(x) + 3.0 He_2(x) - 1.0 He_3(x)"),
+ (arange(12), ("0.0 + 1.0 He_1(x) + 2.0 He_2(x) + 3.0 He_3(x) + "
+ "4.0 He_4(x) +\n5.0 He_5(x) + 6.0 He_6(x) + "
+ "7.0 He_7(x) + 8.0 He_8(x) + 9.0 He_9(x) +\n"
+ "10.0 He_10(x) + 11.0 He_11(x)")),
+ ))
+ def test_hermiteE_str(self, inp, tgt):
+ res = str(poly.HermiteE(inp))
+ assert_equal(res, tgt)
+
+ @pytest.mark.parametrize(('inp', 'tgt'), (
+ ([1, 2, 3], "1.0 + 2.0 L_1(x) + 3.0 L_2(x)"),
+ ([-1, 0, 3, -1], "-1.0 + 0.0 L_1(x) + 3.0 L_2(x) - 1.0 L_3(x)"),
+ (arange(12), ("0.0 + 1.0 L_1(x) + 2.0 L_2(x) + 3.0 L_3(x) + "
+ "4.0 L_4(x) + 5.0 L_5(x) +\n6.0 L_6(x) + 7.0 L_7(x) + "
+ "8.0 L_8(x) + 9.0 L_9(x) + 10.0 L_10(x) +\n"
+ "11.0 L_11(x)")),
+ ))
+ def test_laguerre_str(self, inp, tgt):
+ res = str(poly.Laguerre(inp))
+ assert_equal(res, tgt)
+
+
+class TestLinebreaking:
+
+ @pytest.fixture(scope='class', autouse=True)
+ 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([12345678, 12345678, 12345678, 12345678, 123])
+ assert_equal(len(str(p)), 74)
+ assert_equal(str(p), (
+ '12345678.0 + 12345678.0 x + 12345678.0 x**2 + '
+ '12345678.0 x**3 + 123.0 x**4'
+ ))
+
+ def test_num_chars_is_linewidth(self):
+ # len(str(p)) == default linewidth == 75
+ p = poly.Polynomial([12345678, 12345678, 12345678, 12345678, 1234])
+ assert_equal(len(str(p)), 75)
+ assert_equal(str(p), (
+ '12345678.0 + 12345678.0 x + 12345678.0 x**2 + '
+ '12345678.0 x**3 +\n1234.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(
+ [12345678, 12345678, 12345678, 12345678, 1, 12345678]
+ )
+ assert_equal(len(str(p).split('\n')[0]), 74)
+ assert_equal(str(p), (
+ '12345678.0 + 12345678.0 x + 12345678.0 x**2 + '
+ '12345678.0 x**3 + 1.0 x**4 +\n12345678.0 x**5'
+ ))
+
+ def test_first_linebreak_multiline_on_linewidth(self):
+ # First line is one character longer than previous test
+ p = poly.Polynomial(
+ [12345678, 12345678, 12345678, 12345678.12, 1, 12345678]
+ )
+ assert_equal(str(p), (
+ '12345678.0 + 12345678.0 x + 12345678.0 x**2 + '
+ '12345678.12 x**3 +\n1.0 x**4 + 12345678.0 x**5'
+ ))
+
+ @pytest.mark.parametrize(('lw', 'tgt'), (
+ (75, ('0.0 + 10.0 x + 200.0 x**2 + 3000.0 x**3 + 40000.0 x**4 + '
+ '500000.0 x**5 +\n600000.0 x**6 + 70000.0 x**7 + 8000.0 x**8 + '
+ '900.0 x**9')),
+ (45, ('0.0 + 10.0 x + 200.0 x**2 + 3000.0 x**3 +\n40000.0 x**4 + '
+ '500000.0 x**5 +\n600000.0 x**6 + 70000.0 x**7 + 8000.0 x**8 +\n'
+ '900.0 x**9')),
+ (132, ('0.0 + 10.0 x + 200.0 x**2 + 3000.0 x**3 + 40000.0 x**4 + '
+ '500000.0 x**5 + 600000.0 x**6 + 70000.0 x**7 + 8000.0 x**8 + '
+ '900.0 x**9')),
+ ))
+ 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 + 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 - (2-2j) x**2 + (3+0j) x**3")
+ assert_equal(str(p2), "1j + (1+1j) x + (-2+2j) x**2 + (3+0j) x**3")
+
+
+@pytest.mark.parametrize(('coefs', 'tgt'), (
+ (array([Fraction(1, 2), Fraction(3, 4)], dtype=object), (
+ "1/2 + 3/4·x"
+ )),
+ (array([1, 2, Fraction(5, 7)], dtype=object), (
+ "1 + 2·x + 5/7·x²"
+ )),
+ (array([Decimal('1.00'), Decimal('2.2'), 3], dtype=object), (
+ "1.00 + 2.2·x + 3·x²"
+ )),
+))
+def test_numeric_object_coefficients(coefs, tgt):
+ p = poly.Polynomial(coefs)
+ poly.set_default_printstyle('unicode')
+ assert_equal(str(p), tgt)
+
+
+@pytest.mark.parametrize(('coefs', 'tgt'), (
+ (array([1, 2, 'f'], dtype=object), '1 + 2·x + f·x²'),
+ (array([1, 2, [3, 4]], dtype=object), '1 + 2·x + [3, 4]·x²'),
+))
+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 + 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 + 3.0 x**2")
+ assert_equal(f"{p}", "1.0 + 2.0 x + 3.0 x**2")
+
+ def test_bad_formatstr(self):
+ p = poly.Polynomial([1, 2, 0, -1])
+ with pytest.raises(ValueError):
+ format(p, '.2f')
+
+
+@pytest.mark.parametrize(('poly', 'tgt'), (
+ (poly.Polynomial, '1.0 + 2.0·z + 3.0·z²'),
+ (poly.Chebyshev, '1.0 + 2.0·T₁(z) + 3.0·T₂(z)'),
+ (poly.Hermite, '1.0 + 2.0·H₁(z) + 3.0·H₂(z)'),
+ (poly.HermiteE, '1.0 + 2.0·He₁(z) + 3.0·He₂(z)'),
+ (poly.Laguerre, '1.0 + 2.0·L₁(z) + 3.0·L₂(z)'),
+ (poly.Legendre, '1.0 + 2.0·P₁(z) + 3.0·P₂(z)'),
+))
+def test_symbol(poly, tgt):
+ p = poly([1, 2, 3], symbol='z')
+ assert_equal(f"{p:unicode}", tgt)
+
+
+class TestRepr:
+ def test_polynomial_str(self):
+ res = repr(poly.Polynomial([0, 1]))
+ tgt = (
+ "Polynomial([0., 1.], domain=[-1, 1], window=[-1, 1], "
+ "symbol='x')"
+ )
+ 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], "
+ "symbol='x')"
+ )
+ 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], "
+ "symbol='x')"
+ )
+ 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], "
+ "symbol='x')"
+ )
+ 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], "
+ "symbol='x')"
+ )
+ 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], "
+ "symbol='x')"
+ )
+ 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, parens=False: 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)$')
+
+ def test_symbol_basic(self):
+ # default input
+ p = poly.Polynomial([1, 2, 3], symbol='z')
+ assert_equal(self.as_latex(p),
+ r'$z \mapsto 1.0 + 2.0\,z + 3.0\,z^{2}$')
+
+ # translated input
+ p = poly.Polynomial([1, 2, 3], domain=[-2, 0], symbol='z')
+ assert_equal(
+ self.as_latex(p),
+ (
+ r'$z \mapsto 1.0 + 2.0\,\left(1.0 + z\right) + 3.0\,'
+ r'\left(1.0 + z\right)^{2}$'
+ ),
+ )
+
+ # scaled input
+ p = poly.Polynomial([1, 2, 3], domain=[-0.5, 0.5], symbol='z')
+ assert_equal(
+ self.as_latex(p),
+ (
+ r'$z \mapsto 1.0 + 2.0\,\left(2.0z\right) + 3.0\,'
+ r'\left(2.0z\right)^{2}$'
+ ),
+ )
+
+ # affine input
+ p = poly.Polynomial([1, 2, 3], domain=[-1, 0], symbol='z')
+ assert_equal(
+ self.as_latex(p),
+ (
+ r'$z \mapsto 1.0 + 2.0\,\left(1.0 + 2.0z\right) + 3.0\,'
+ r'\left(1.0 + 2.0z\right)^{2}$'
+ ),
+ )
+
+
+SWITCH_TO_EXP = (
+ '1.0 + (1.0e-01) x + (1.0e-02) x**2',
+ '1.2 + (1.2e-01) x + (1.2e-02) x**2',
+ '1.23 + 0.12 x + (1.23e-02) x**2 + (1.23e-03) x**3',
+ '1.235 + 0.123 x + (1.235e-02) x**2 + (1.235e-03) x**3',
+ '1.2346 + 0.1235 x + 0.0123 x**2 + (1.2346e-03) x**3 + (1.2346e-04) x**4',
+ '1.23457 + 0.12346 x + 0.01235 x**2 + (1.23457e-03) x**3 + '
+ '(1.23457e-04) x**4',
+ '1.234568 + 0.123457 x + 0.012346 x**2 + 0.001235 x**3 + '
+ '(1.234568e-04) x**4 + (1.234568e-05) x**5',
+ '1.2345679 + 0.1234568 x + 0.0123457 x**2 + 0.0012346 x**3 + '
+ '(1.2345679e-04) x**4 + (1.2345679e-05) x**5')
+
+class TestPrintOptions:
+ """
+ Test the output is properly configured via printoptions.
+ The exponential notation is enabled automatically when the values
+ are too small or too large.
+ """
+
+ @pytest.fixture(scope='class', autouse=True)
+ def use_ascii(self):
+ poly.set_default_printstyle('ascii')
+
+ def test_str(self):
+ p = poly.Polynomial([1/2, 1/7, 1/7*10**8, 1/7*10**9])
+ assert_equal(str(p), '0.5 + 0.14285714 x + 14285714.28571429 x**2 '
+ '+ (1.42857143e+08) x**3')
+
+ with printoptions(precision=3):
+ assert_equal(str(p), '0.5 + 0.143 x + 14285714.286 x**2 '
+ '+ (1.429e+08) x**3')
+
+ def test_latex(self):
+ p = poly.Polynomial([1/2, 1/7, 1/7*10**8, 1/7*10**9])
+ assert_equal(p._repr_latex_(),
+ r'$x \mapsto \text{0.5} + \text{0.14285714}\,x + '
+ r'\text{14285714.28571429}\,x^{2} + '
+ r'\text{(1.42857143e+08)}\,x^{3}$')
+
+ with printoptions(precision=3):
+ assert_equal(p._repr_latex_(),
+ r'$x \mapsto \text{0.5} + \text{0.143}\,x + '
+ r'\text{14285714.286}\,x^{2} + \text{(1.429e+08)}\,x^{3}$')
+
+ def test_fixed(self):
+ p = poly.Polynomial([1/2])
+ assert_equal(str(p), '0.5')
+
+ with printoptions(floatmode='fixed'):
+ assert_equal(str(p), '0.50000000')
+
+ with printoptions(floatmode='fixed', precision=4):
+ assert_equal(str(p), '0.5000')
+
+ def test_switch_to_exp(self):
+ for i, s in enumerate(SWITCH_TO_EXP):
+ with printoptions(precision=i):
+ p = poly.Polynomial([1.23456789*10**-i
+ for i in range(i//2+3)])
+ assert str(p).replace('\n', ' ') == s
+
+ def test_non_finite(self):
+ p = poly.Polynomial([nan, inf])
+ assert str(p) == 'nan + inf x'
+ assert p._repr_latex_() == r'$x \mapsto \text{nan} + \text{inf}\,x$'
+ with printoptions(nanstr='NAN', infstr='INF'):
+ assert str(p) == 'NAN + INF x'
+ assert p._repr_latex_() == \
+ r'$x \mapsto \text{NAN} + \text{INF}\,x$'
diff --git a/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_symbol.py b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_symbol.py
new file mode 100644
index 00000000..4ea6035e
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/polynomial/tests/test_symbol.py
@@ -0,0 +1,216 @@
+"""
+Tests related to the ``symbol`` attribute of the ABCPolyBase class.
+"""
+
+import pytest
+import numpy.polynomial as poly
+from numpy.core import array
+from numpy.testing import assert_equal, assert_raises, assert_
+
+
+class TestInit:
+ """
+ Test polynomial creation with symbol kwarg.
+ """
+ c = [1, 2, 3]
+
+ def test_default_symbol(self):
+ p = poly.Polynomial(self.c)
+ assert_equal(p.symbol, 'x')
+
+ @pytest.mark.parametrize(('bad_input', 'exception'), (
+ ('', ValueError),
+ ('3', ValueError),
+ (None, TypeError),
+ (1, TypeError),
+ ))
+ def test_symbol_bad_input(self, bad_input, exception):
+ with pytest.raises(exception):
+ p = poly.Polynomial(self.c, symbol=bad_input)
+
+ @pytest.mark.parametrize('symbol', (
+ 'x',
+ 'x_1',
+ 'A',
+ 'xyz',
+ 'β',
+ ))
+ def test_valid_symbols(self, symbol):
+ """
+ Values for symbol that should pass input validation.
+ """
+ p = poly.Polynomial(self.c, symbol=symbol)
+ assert_equal(p.symbol, symbol)
+
+ def test_property(self):
+ """
+ 'symbol' attribute is read only.
+ """
+ p = poly.Polynomial(self.c, symbol='x')
+ with pytest.raises(AttributeError):
+ p.symbol = 'z'
+
+ def test_change_symbol(self):
+ p = poly.Polynomial(self.c, symbol='y')
+ # Create new polynomial from p with different symbol
+ pt = poly.Polynomial(p.coef, symbol='t')
+ assert_equal(pt.symbol, 't')
+
+
+class TestUnaryOperators:
+ p = poly.Polynomial([1, 2, 3], symbol='z')
+
+ def test_neg(self):
+ n = -self.p
+ assert_equal(n.symbol, 'z')
+
+ def test_scalarmul(self):
+ out = self.p * 10
+ assert_equal(out.symbol, 'z')
+
+ def test_rscalarmul(self):
+ out = 10 * self.p
+ assert_equal(out.symbol, 'z')
+
+ def test_pow(self):
+ out = self.p ** 3
+ assert_equal(out.symbol, 'z')
+
+
+@pytest.mark.parametrize(
+ 'rhs',
+ (
+ poly.Polynomial([4, 5, 6], symbol='z'),
+ array([4, 5, 6]),
+ ),
+)
+class TestBinaryOperatorsSameSymbol:
+ """
+ Ensure symbol is preserved for numeric operations on polynomials with
+ the same symbol
+ """
+ p = poly.Polynomial([1, 2, 3], symbol='z')
+
+ def test_add(self, rhs):
+ out = self.p + rhs
+ assert_equal(out.symbol, 'z')
+
+ def test_sub(self, rhs):
+ out = self.p - rhs
+ assert_equal(out.symbol, 'z')
+
+ def test_polymul(self, rhs):
+ out = self.p * rhs
+ assert_equal(out.symbol, 'z')
+
+ def test_divmod(self, rhs):
+ for out in divmod(self.p, rhs):
+ assert_equal(out.symbol, 'z')
+
+ def test_radd(self, rhs):
+ out = rhs + self.p
+ assert_equal(out.symbol, 'z')
+
+ def test_rsub(self, rhs):
+ out = rhs - self.p
+ assert_equal(out.symbol, 'z')
+
+ def test_rmul(self, rhs):
+ out = rhs * self.p
+ assert_equal(out.symbol, 'z')
+
+ def test_rdivmod(self, rhs):
+ for out in divmod(rhs, self.p):
+ assert_equal(out.symbol, 'z')
+
+
+class TestBinaryOperatorsDifferentSymbol:
+ p = poly.Polynomial([1, 2, 3], symbol='x')
+ other = poly.Polynomial([4, 5, 6], symbol='y')
+ ops = (p.__add__, p.__sub__, p.__mul__, p.__floordiv__, p.__mod__)
+
+ @pytest.mark.parametrize('f', ops)
+ def test_binops_fails(self, f):
+ assert_raises(ValueError, f, self.other)
+
+
+class TestEquality:
+ p = poly.Polynomial([1, 2, 3], symbol='x')
+
+ def test_eq(self):
+ other = poly.Polynomial([1, 2, 3], symbol='x')
+ assert_(self.p == other)
+
+ def test_neq(self):
+ other = poly.Polynomial([1, 2, 3], symbol='y')
+ assert_(not self.p == other)
+
+
+class TestExtraMethods:
+ """
+ Test other methods for manipulating/creating polynomial objects.
+ """
+ p = poly.Polynomial([1, 2, 3, 0], symbol='z')
+
+ def test_copy(self):
+ other = self.p.copy()
+ assert_equal(other.symbol, 'z')
+
+ def test_trim(self):
+ other = self.p.trim()
+ assert_equal(other.symbol, 'z')
+
+ def test_truncate(self):
+ other = self.p.truncate(2)
+ assert_equal(other.symbol, 'z')
+
+ @pytest.mark.parametrize('kwarg', (
+ {'domain': [-10, 10]},
+ {'window': [-10, 10]},
+ {'kind': poly.Chebyshev},
+ ))
+ def test_convert(self, kwarg):
+ other = self.p.convert(**kwarg)
+ assert_equal(other.symbol, 'z')
+
+ def test_integ(self):
+ other = self.p.integ()
+ assert_equal(other.symbol, 'z')
+
+ def test_deriv(self):
+ other = self.p.deriv()
+ assert_equal(other.symbol, 'z')
+
+
+def test_composition():
+ p = poly.Polynomial([3, 2, 1], symbol="t")
+ q = poly.Polynomial([5, 1, 0, -1], symbol="λ_1")
+ r = p(q)
+ assert r.symbol == "λ_1"
+
+
+#
+# Class methods that result in new polynomial class instances
+#
+
+
+def test_fit():
+ x, y = (range(10),)*2
+ p = poly.Polynomial.fit(x, y, deg=1, symbol='z')
+ assert_equal(p.symbol, 'z')
+
+
+def test_froomroots():
+ roots = [-2, 2]
+ p = poly.Polynomial.fromroots(roots, symbol='z')
+ assert_equal(p.symbol, 'z')
+
+
+def test_identity():
+ p = poly.Polynomial.identity(domain=[-1, 1], window=[5, 20], symbol='z')
+ assert_equal(p.symbol, 'z')
+
+
+def test_basis():
+ p = poly.Polynomial.basis(3, symbol='z')
+ assert_equal(p.symbol, 'z')