Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
test_polynomial.py326 linesDownload Raw Back to tests
1import pytest
2
3import numpy as np
4import numpy.polynomial.polynomial as poly
5from numpy.testing import (
6    assert_,
7    assert_allclose,
8    assert_almost_equal,
9    assert_array_almost_equal,
10    assert_array_equal,
11    assert_equal,
12    assert_raises,
13)
14
15# `poly1d` has some support for `np.bool` and `np.timedelta64`,
16# but it is limited and they are therefore excluded here
17TYPE_CODES = np.typecodes["AllInteger"] + np.typecodes["AllFloat"] + "O"
18
19
20class TestPolynomial:
21    def test_poly1d_str_and_repr(self):
22        p = np.poly1d([1., 2, 3])
23        assert_equal(repr(p), 'poly1d([1., 2., 3.])')
24        assert_equal(str(p),
25                     '   2\n'
26                     '1 x + 2 x + 3')
27
28        q = np.poly1d([3., 2, 1])
29        assert_equal(repr(q), 'poly1d([3., 2., 1.])')
30        assert_equal(str(q),
31                     '   2\n'
32                     '3 x + 2 x + 1')
33
34        r = np.poly1d([1.89999 + 2j, -3j, -5.12345678, 2 + 1j])
35        assert_equal(str(r),
36                     '            3      2\n'
37                     '(1.9 + 2j) x - 3j x - 5.123 x + (2 + 1j)')
38
39        assert_equal(str(np.poly1d([-3, -2, -1])),
40                     '    2\n'
41                     '-3 x - 2 x - 1')
42
43    def test_poly1d_resolution(self):
44        p = np.poly1d([1., 2, 3])
45        q = np.poly1d([3., 2, 1])
46        assert_equal(p(0), 3.0)
47        assert_equal(p(5), 38.0)
48        assert_equal(q(0), 1.0)
49        assert_equal(q(5), 86.0)
50
51    def test_poly1d_math(self):
52        # here we use some simple coeffs to make calculations easier
53        p = np.poly1d([1., 2, 4])
54        q = np.poly1d([4., 2, 1])
55        assert_equal(p / q, (np.poly1d([0.25]), np.poly1d([1.5, 3.75])))
56        assert_equal(p.integ(), np.poly1d([1 / 3, 1., 4., 0.]))
57        assert_equal(p.integ(1), np.poly1d([1 / 3, 1., 4., 0.]))
58
59        p = np.poly1d([1., 2, 3])
60        q = np.poly1d([3., 2, 1])
61        assert_equal(p * q, np.poly1d([3., 8., 14., 8., 3.]))
62        assert_equal(p + q, np.poly1d([4., 4., 4.]))
63        assert_equal(p - q, np.poly1d([-2., 0., 2.]))
64        assert_equal(p ** 4, np.poly1d([1., 8., 36., 104., 214.,
65                                        312., 324., 216., 81.]))
66        assert_equal(p(q), np.poly1d([9., 12., 16., 8., 6.]))
67        assert_equal(q(p), np.poly1d([3., 12., 32., 40., 34.]))
68        assert_equal(p.deriv(), np.poly1d([2., 2.]))
69        assert_equal(p.deriv(2), np.poly1d([2.]))
70        assert_equal(np.polydiv(np.poly1d([1, 0, -1]), np.poly1d([1, 1])),
71                     (np.poly1d([1., -1.]), np.poly1d([0.])))
72
73    @pytest.mark.parametrize("type_code", TYPE_CODES)
74    def test_poly1d_misc(self, type_code: str) -> None:
75        dtype = np.dtype(type_code)
76        ar = np.array([1, 2, 3], dtype=dtype)
77        p = np.poly1d(ar)
78
79        # `__eq__`
80        assert_equal(np.asarray(p), ar)
81        assert_equal(np.asarray(p).dtype, dtype)
82        assert_equal(len(p), 2)
83
84        # `__getitem__`
85        comparison_dct = {-1: 0, 0: 3, 1: 2, 2: 1, 3: 0}
86        for index, ref in comparison_dct.items():
87            scalar = p[index]
88            assert_equal(scalar, ref)
89            if dtype == np.object_:
90                assert isinstance(scalar, int)
91            else:
92                assert_equal(scalar.dtype, dtype)
93
94    def test_poly1d_variable_arg(self):
95        q = np.poly1d([1., 2, 3], variable='y')
96        assert_equal(str(q),
97                     '   2\n'
98                     '1 y + 2 y + 3')
99        q = np.poly1d([1., 2, 3], variable='lambda')
100        assert_equal(str(q),
101                     '        2\n'
102                     '1 lambda + 2 lambda + 3')
103
104    def test_poly(self):
105        assert_array_almost_equal(np.poly([3, -np.sqrt(2), np.sqrt(2)]),
106                                  [1, -3, -2, 6])
107
108        # From matlab docs
109        A = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]
110        assert_array_almost_equal(np.poly(A), [1, -6, -72, -27])
111
112        # Should produce real output for perfect conjugates
113        assert_(np.isrealobj(np.poly([+1.082j, +2.613j, -2.613j, -1.082j])))
114        assert_(np.isrealobj(np.poly([0 + 1j, -0 + -1j, 1 + 2j,
115                                      1 - 2j, 1. + 3.5j, 1 - 3.5j])))
116        assert_(np.isrealobj(np.poly([1j, -1j, 1 + 2j, 1 - 2j, 1 + 3j, 1 - 3.j])))
117        assert_(np.isrealobj(np.poly([1j, -1j, 1 + 2j, 1 - 2j])))
118        assert_(np.isrealobj(np.poly([1j, -1j, 2j, -2j])))
119        assert_(np.isrealobj(np.poly([1j, -1j])))
120        assert_(np.isrealobj(np.poly([1, -1])))
121
122        assert_(np.iscomplexobj(np.poly([1j, -1.0000001j])))
123
124        np.random.seed(42)
125        a = np.random.randn(100) + 1j * np.random.randn(100)
126        assert_(np.isrealobj(np.poly(np.concatenate((a, np.conjugate(a))))))
127
128    def test_roots(self):
129        assert_array_equal(np.roots([1, 0, 0]), [0, 0])
130
131        # Testing for larger root values
132        for i in np.logspace(10, 25, num=1000, base=10):
133            tgt = np.array([-1, 1, i])
134            res = np.sort(np.roots(poly.polyfromroots(tgt)[::-1]))
135            # Adapting the expected precision according to the root value,
136            # to take into account numerical calculation error
137            assert_almost_equal(res, tgt, 14 - int(np.log10(i)))
138
139        for i in np.logspace(10, 25, num=1000, base=10):
140            tgt = np.array([-1, 1.01, i])
141            res = np.sort(np.roots(poly.polyfromroots(tgt)[::-1]))
142            # Adapting the expected precision according to the root value,
143            # to take into account numerical calculation error
144            assert_almost_equal(res, tgt, 14 - int(np.log10(i)))
145
146    def test_str_leading_zeros(self):
147        p = np.poly1d([4, 3, 2, 1])
148        p[3] = 0
149        assert_equal(str(p),
150                     "   2\n"
151                     "3 x + 2 x + 1")
152
153        p = np.poly1d([1, 2])
154        p[0] = 0
155        p[1] = 0
156        assert_equal(str(p), " \n0")
157
158    def test_polyfit(self):
159        c = np.array([3., 2., 1.])
160        x = np.linspace(0, 2, 7)
161        y = np.polyval(c, x)
162        err = [1, -1, 1, -1, 1, -1, 1]
163        weights = np.arange(8, 1, -1)**2 / 7.0
164
165        # Check exception when too few points for variance estimate. Note that
166        # the estimate requires the number of data points to exceed
167        # degree + 1
168        assert_raises(ValueError, np.polyfit,
169                      [1], [1], deg=0, cov=True)
170
171        # check 1D case
172        m, cov = np.polyfit(x, y + err, 2, cov=True)
173        est = [3.8571, 0.2857, 1.619]
174        assert_almost_equal(est, m, decimal=4)
175        val0 = [[ 1.4694, -2.9388,  0.8163],
176                [-2.9388,  6.3673, -2.1224],
177                [ 0.8163, -2.1224,  1.161 ]]  # noqa: E202
178        assert_almost_equal(val0, cov, decimal=4)
179
180        m2, cov2 = np.polyfit(x, y + err, 2, w=weights, cov=True)
181        assert_almost_equal([4.8927, -1.0177, 1.7768], m2, decimal=4)
182        val = [[ 4.3964, -5.0052,  0.4878],
183               [-5.0052,  6.8067, -0.9089],
184               [ 0.4878, -0.9089,  0.3337]]
185        assert_almost_equal(val, cov2, decimal=4)
186
187        m3, cov3 = np.polyfit(x, y + err, 2, w=weights, cov="unscaled")
188        assert_almost_equal([4.8927, -1.0177, 1.7768], m3, decimal=4)
189        val = [[ 0.1473, -0.1677,  0.0163],
190               [-0.1677,  0.228 , -0.0304],  # noqa: E203
191               [ 0.0163, -0.0304,  0.0112]]
192        assert_almost_equal(val, cov3, decimal=4)
193
194        # check 2D (n,1) case
195        y = y[:, np.newaxis]
196        c = c[:, np.newaxis]
197        assert_almost_equal(c, np.polyfit(x, y, 2))
198        # check 2D (n,2) case
199        yy = np.concatenate((y, y), axis=1)
200        cc = np.concatenate((c, c), axis=1)
201        assert_almost_equal(cc, np.polyfit(x, yy, 2))
202
203        m, cov = np.polyfit(x, yy + np.array(err)[:, np.newaxis], 2, cov=True)
204        assert_almost_equal(est, m[:, 0], decimal=4)
205        assert_almost_equal(est, m[:, 1], decimal=4)
206        assert_almost_equal(val0, cov[:, :, 0], decimal=4)
207        assert_almost_equal(val0, cov[:, :, 1], decimal=4)
208
209        # check order 1 (deg=0) case, were the analytic results are simple
210        np.random.seed(123)
211        y = np.random.normal(size=(4, 10000))
212        mean, cov = np.polyfit(np.zeros(y.shape[0]), y, deg=0, cov=True)
213        # Should get sigma_mean = sigma/sqrt(N) = 1./sqrt(4) = 0.5.
214        assert_allclose(mean.std(), 0.5, atol=0.01)
215        assert_allclose(np.sqrt(cov.mean()), 0.5, atol=0.01)
216        # Without scaling, since reduced chi2 is 1, the result should be the same.
217        mean, cov = np.polyfit(np.zeros(y.shape[0]), y, w=np.ones(y.shape[0]),
218                               deg=0, cov="unscaled")
219        assert_allclose(mean.std(), 0.5, atol=0.01)
220        assert_almost_equal(np.sqrt(cov.mean()), 0.5)
221        # If we estimate our errors wrong, no change with scaling:
222        w = np.full(y.shape[0], 1. / 0.5)
223        mean, cov = np.polyfit(np.zeros(y.shape[0]), y, w=w, deg=0, cov=True)
224        assert_allclose(mean.std(), 0.5, atol=0.01)
225        assert_allclose(np.sqrt(cov.mean()), 0.5, atol=0.01)
226        # But if we do not scale, our estimate for the error in the mean will
227        # differ.
228        mean, cov = np.polyfit(np.zeros(y.shape[0]), y, w=w, deg=0, cov="unscaled")
229        assert_allclose(mean.std(), 0.5, atol=0.01)
230        assert_almost_equal(np.sqrt(cov.mean()), 0.25)
231
232    def test_objects(self):
233        from decimal import Decimal
234        p = np.poly1d([Decimal('4.0'), Decimal('3.0'), Decimal('2.0')])
235        p2 = p * Decimal('1.333333333333333')
236        assert_(p2[1] == Decimal("3.9999999999999990"))
237        p2 = p.deriv()
238        assert_(p2[1] == Decimal('8.0'))
239        p2 = p.integ()
240        assert_(p2[3] == Decimal("1.333333333333333333333333333"))
241        assert_(p2[2] == Decimal('1.5'))
242        assert_(np.issubdtype(p2.coeffs.dtype, np.object_))
243        p = np.poly([Decimal(1), Decimal(2)])
244        assert_equal(np.poly([Decimal(1), Decimal(2)]),
245                     [1, Decimal(-3), Decimal(2)])
246
247    def test_complex(self):
248        p = np.poly1d([3j, 2j, 1j])
249        p2 = p.integ()
250        assert_((p2.coeffs == [1j, 1j, 1j, 0]).all())
251        p2 = p.deriv()
252        assert_((p2.coeffs == [6j, 2j]).all())
253
254    def test_integ_coeffs(self):
255        p = np.poly1d([3, 2, 1])
256        p2 = p.integ(3, k=[9, 7, 6])
257        expected = [1 / 4 / 5, 1 / 3 / 4, 1 / 2 / 3, 9 / 1 / 2, 7, 6]
258        assert_((p2.coeffs == expected).all())
259
260    def test_zero_dims(self):
261        try:
262            np.poly(np.zeros((0, 0)))
263        except ValueError:
264            pass
265
266    def test_poly_int_overflow(self):
267        """
268        Regression test for gh-5096.
269        """
270        v = np.arange(1, 21)
271        assert_almost_equal(np.poly(v), np.poly(np.diag(v)))
272
273    def test_zero_poly_dtype(self):
274        """
275        Regression test for gh-16354.
276        """
277        z = np.array([0, 0, 0])
278        p = np.poly1d(z.astype(np.int64))
279        assert_equal(p.coeffs.dtype, np.int64)
280
281        p = np.poly1d(z.astype(np.float32))
282        assert_equal(p.coeffs.dtype, np.float32)
283
284        p = np.poly1d(z.astype(np.complex64))
285        assert_equal(p.coeffs.dtype, np.complex64)
286
287    def test_poly_eq(self):
288        p = np.poly1d([1, 2, 3])
289        p2 = np.poly1d([1, 2, 4])
290        assert_equal(p == None, False)  # noqa: E711
291        assert_equal(p != None, True)  # noqa: E711
292        assert_equal(p == p, True)
293        assert_equal(p == p2, False)
294        assert_equal(p != p2, True)
295
296    def test_polydiv(self):
297        b = np.poly1d([2, 6, 6, 1])
298        a = np.poly1d([-1j, (1 + 2j), -(2 + 1j), 1])
299        q, r = np.polydiv(b, a)
300        assert_equal(q.coeffs.dtype, np.complex128)
301        assert_equal(r.coeffs.dtype, np.complex128)
302        assert_equal(q * a + r, b)
303
304        c = [1, 2, 3]
305        d = np.poly1d([1, 2, 3])
306        s, t = np.polydiv(c, d)
307        assert isinstance(s, np.poly1d)
308        assert isinstance(t, np.poly1d)
309        u, v = np.polydiv(d, c)
310        assert isinstance(u, np.poly1d)
311        assert isinstance(v, np.poly1d)
312
313    def test_poly_coeffs_mutable(self):
314        """ Coefficients should be modifiable """
315        p = np.poly1d([1, 2, 3])
316
317        p.coeffs += 1
318        assert_equal(p.coeffs, [2, 3, 4])
319
320        p.coeffs[2] += 10
321        assert_equal(p.coeffs, [2, 3, 14])
322
323        # this never used to be allowed - let's not add features to deprecated
324        # APIs
325        assert_raises(AttributeError, setattr, p, 'coeffs', np.array(1))
326 
codekingpro/portable-devtools · Team Ai