import numpy import pytest import cupy from cupy.cuda import driver from cupy.cuda import runtime import cupyx from cupy import testing @testing.parameterize( {'variable': None}, {'variable': 'y'}, ) class TestPoly1dInit: @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_poly1d_numpy_array(self, xp, dtype): a = numpy.arange(5, dtype=dtype) with cupyx.allow_synchronize(False): out = xp.poly1d(a, variable=self.variable) assert out.variable == (self.variable or 'x') return out @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_poly1d_cupy_array(self, xp, dtype): a = testing.shaped_arange((5,), xp, dtype) with cupyx.allow_synchronize(False): out = xp.poly1d(a, variable=self.variable) assert out.variable == (self.variable or 'x') return out @testing.numpy_cupy_array_equal() def test_poly1d_list(self, xp): with cupyx.allow_synchronize(False): out = xp.poly1d([1, 2, 3, 4], variable=self.variable) assert out.variable == (self.variable or 'x') return out @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_poly1d_numpy_poly1d(self, xp, dtype): array = testing.shaped_arange((5,), numpy, dtype) a = numpy.poly1d(array) with cupyx.allow_synchronize(False): out = xp.poly1d(a, variable=self.variable) assert out.variable == (self.variable or 'x') return out @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_poly1d_numpy_poly1d_variable(self, xp, dtype): array = testing.shaped_arange((5,), numpy, dtype) a = numpy.poly1d(array, variable='z') with cupyx.allow_synchronize(False): out = xp.poly1d(a, variable=self.variable) assert out.variable == (self.variable or 'z') return out @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_poly1d_cupy_poly1d(self, xp, dtype): array = testing.shaped_arange((5,), xp, dtype) a = xp.poly1d(array) out = xp.poly1d(a, variable=self.variable) assert out.variable == (self.variable or 'x') return out @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_poly1d_cupy_poly1d_variable(self, xp, dtype): array = testing.shaped_arange((5,), xp, dtype) a = xp.poly1d(array, variable='z') out = xp.poly1d(a, variable=self.variable) assert out.variable == (self.variable or 'z') return out @testing.with_requires('numpy>=1.20') @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_poly1d_zero_dim(self, xp, dtype): a = testing.shaped_arange((), xp, dtype) with cupyx.allow_synchronize(False): out = xp.poly1d(a, variable=self.variable) assert out.variable == (self.variable or 'x') return out @testing.with_requires('numpy>=1.20') @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_poly1d_zero_size(self, xp, dtype): a = testing.shaped_arange((0,), xp, dtype) with cupyx.allow_synchronize(False): out = xp.poly1d(a, variable=self.variable) assert out.variable == (self.variable or 'x') return out @testing.for_all_dtypes() @testing.numpy_cupy_allclose(rtol=1e-5, atol=1e-5) def test_poly1d_roots(self, xp, dtype): a = testing.shaped_arange((4,), xp, dtype) out = xp.poly1d(a, True, variable=self.variable) assert out.variable == (self.variable or 'x') return out.coeffs class TestPoly1d: @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_poly1d_leading_zeros(self, xp, dtype): a = xp.array([0, 0, 1, 2, 3], dtype) return xp.poly1d(a) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_poly1d_neg(self, xp, dtype): a = testing.shaped_arange((5,), xp, dtype) return -xp.poly1d(a) @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_order(self, xp, dtype): a = testing.shaped_arange((10,), xp, dtype) return xp.poly1d(a).order @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_order_leading_zeros(self, xp, dtype): a = xp.array([0, 0, 1, 2, 3, 0], dtype) return xp.poly1d(a).order @pytest.mark.skipif(runtime.is_hip and driver.get_build_version() < 402, reason='syevj not available') @testing.for_signed_dtypes() @testing.numpy_cupy_allclose(rtol=1e-6) def test_poly1d_roots(self, xp, dtype): a = xp.array([-3, -2.5, 3], dtype) out = xp.poly1d(a).roots # The current `cupy.roots` doesn't guarantee the order of results. return xp.sort(out) @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_getitem1(self, xp, dtype): a = testing.shaped_arange((10,), xp, dtype) with cupyx.allow_synchronize(False): return xp.poly1d(a)[-1] @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_getitem2(self, xp, dtype): a = testing.shaped_arange((10,), xp, dtype) with cupyx.allow_synchronize(False): return xp.poly1d(a)[5] @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_getitem3(self, xp, dtype): a = testing.shaped_arange((10,), xp, dtype) with cupyx.allow_synchronize(False): return xp.poly1d(a)[100] @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_getitem4(self, xp, dtype): a = xp.array([0, 0, 1, 2, 3, 0], dtype) with cupyx.allow_synchronize(False): return xp.poly1d(a)[2] @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_poly1d_setitem(self, xp, dtype): a = testing.shaped_arange((10,), xp, dtype) b = xp.poly1d(a) with cupyx.allow_synchronize(False): b[100] = 20 return b @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_poly1d_setitem_leading_zeros(self, xp, dtype): a = xp.array([0, 0, 0, 2, 3, 0], dtype) b = xp.poly1d(a) with cupyx.allow_synchronize(False): b[1] = 10 return b @testing.for_all_dtypes() def test_poly1d_setitem_neg(self, dtype): for xp in (numpy, cupy): a = testing.shaped_arange((10,), xp, dtype) b = xp.poly1d(a) with pytest.raises(ValueError): b[-1] = 20 @testing.for_all_dtypes() def test_poly1d_get1(self, dtype): a1 = testing.shaped_arange((10,), cupy, dtype) a2 = testing.shaped_arange((10,), numpy, dtype) b1 = cupy.poly1d(a1, variable='z').get() b2 = numpy.poly1d(a2, variable='z') assert b1 == b2 @testing.for_all_dtypes() def test_poly1d_get2(self, dtype): a1 = testing.shaped_arange((), cupy, dtype) a2 = testing.shaped_arange((), numpy, dtype) b1 = cupy.poly1d(a1).get() b2 = numpy.poly1d(a2) assert b1 == b2 @testing.for_all_dtypes(no_bool=True) def test_poly1d_set(self, dtype): arr1 = testing.shaped_arange((10,), cupy, dtype) arr2 = numpy.ones(10, dtype=dtype) a = cupy.poly1d(arr1) b = numpy.poly1d(arr2, variable='z') a.set(b) assert a.variable == b.variable testing.assert_array_equal(a.coeffs, b.coeffs) @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_repr(self, xp, dtype): a = testing.shaped_arange((5,), xp, dtype) return repr(xp.poly1d(a)) @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_str(self, xp, dtype): a = testing.shaped_arange((5,), xp, dtype) return str(xp.poly1d(a)) @testing.for_all_dtypes() @testing.numpy_cupy_allclose(rtol={numpy.float16: 1e-2, 'default': 1e-6}) def test_poly1d_call(self, xp, dtype): a = testing.shaped_arange((5,), xp, dtype) b = xp.poly1d(a) return b(a) class TestPoly: @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_allclose(rtol=1e-4) def test_poly_1d(self, xp, dtype): a = testing.shaped_arange((5,), xp, dtype) return xp.poly(a) @testing.for_all_dtypes(no_bool=True, no_float16=True, no_complex=True) @testing.numpy_cupy_allclose(rtol=1e-4) def test_poly_2d_symmetric_real(self, xp, dtype): a = xp.array([[6, 3, 1], [3, 0, 5], [1, 5, 6]], dtype) return xp.poly(a) @testing.for_complex_dtypes() @testing.numpy_cupy_allclose(rtol=1e-6) def test_poly_2d_hermitian_complex(self, xp, dtype): a = xp.array([[2, -1j], [1j, 1]], dtype) return xp.poly(a) @testing.for_all_dtypes(no_bool=True) def test_poly_2d_square(self, dtype): a = testing.shaped_arange((3, 3), cupy, dtype) with pytest.raises(NotImplementedError): cupy.poly(a) @testing.for_all_dtypes() def test_poly_2d_general(self, dtype): for xp in (numpy, cupy): a = testing.shaped_arange((2, 4), xp, dtype) with pytest.raises(ValueError): xp.poly(a) @testing.for_all_dtypes() def test_poly_ndim(self, dtype): for xp in (numpy, cupy): a = testing.shaped_arange((5, 4, 3), xp, dtype) with pytest.raises(ValueError): xp.poly(a) @testing.for_all_dtypes(no_bool=True) def test_poly_zero_dim(self, dtype): for xp in (numpy, cupy): a = testing.shaped_arange((), xp, dtype) with pytest.raises(TypeError): numpy.poly(a) @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly_empty(self, xp, dtype): a = xp.zeros((0), dtype) return xp.poly(a) @testing.parameterize(*testing.product({ 'shape': [(), (0,), (5,)], 'exp': [0, 4, 5, numpy.int32(5), numpy.int64(5)], })) class TestPoly1dPow: @testing.with_requires('numpy>=1.20') @testing.for_all_dtypes() @testing.numpy_cupy_allclose(rtol=1e-1) def test_poly1d_pow_scalar(self, xp, dtype): a = testing.shaped_arange(self.shape, xp, dtype) return xp.poly1d(a) ** self.exp @testing.parameterize(*testing.product({ 'shape': [(5,), (5, 2)], 'exp': [-10, 3.5, [1, 2, 3]], })) class TestPoly1dPowInvalidValue: @testing.for_all_dtypes() def test_poly1d_pow(self, dtype): for xp in (numpy, cupy): a = testing.shaped_arange(self.shape, xp, dtype) with pytest.raises(ValueError): xp.poly1d(a) ** self.exp @testing.parameterize(*testing.product({ 'exp': [3.0, numpy.float64(5)], })) class TestPoly1dPowInvalidType: @testing.for_all_dtypes() def test_poly1d_pow(self, dtype): for xp in (numpy, cupy): a = testing.shaped_arange((5,), xp, dtype) with pytest.raises(TypeError): xp.poly1d(a) ** self.exp class Poly1dTestBase: def _get_input(self, xp, in_type, dtype, *, size=10): if in_type in ('ndarray', 'poly1d'): array = testing.shaped_arange((size,), xp, dtype) if array.dtype == numpy.bool_: # Avoid leading zero-coefficients. array = xp.logical_not(array) if in_type == 'poly1d': array = xp.poly1d(array) return array if in_type == 'python_scalar': return dtype(5).item() if in_type == 'numpy_scalar': return dtype(5) assert False @testing.parameterize(*testing.product({ 'func': [ lambda x, y: x + y, lambda x, y: x - y, lambda x, y: x * y, ], 'type_l': ['poly1d', 'ndarray', 'python_scalar', 'numpy_scalar'], 'type_r': ['poly1d', 'ndarray', 'python_scalar', 'numpy_scalar'], })) class TestPoly1dPolynomialArithmetic(Poly1dTestBase): @testing.with_requires('numpy>=1.20') @testing.for_all_dtypes() @testing.numpy_cupy_allclose(rtol=1e-4, accept_error=TypeError) def test_poly1d_arithmetic(self, xp, dtype): if self.type_l == 'numpy_scalar' and self.type_r == 'poly1d': pytest.skip('Avoid numpy bug.') a1 = self._get_input(xp, self.type_l, dtype) a2 = self._get_input(xp, self.type_r, dtype) return self.func(a1, a2) @testing.parameterize(*testing.product({ 'fname': ['add', 'subtract', 'multiply', 'divide', 'power'], 'type_l': ['poly1d', 'ndarray', 'python_scalar', 'numpy_scalar'], 'type_r': ['poly1d', 'ndarray', 'python_scalar', 'numpy_scalar'], })) class TestPoly1dMathArithmetic(Poly1dTestBase): @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_allclose(rtol=1e-5) def test_poly1d_arithmetic(self, xp, dtype): func = getattr(xp, self.fname) a1 = self._get_input(xp, self.type_l, dtype) a2 = self._get_input(xp, self.type_r, dtype) return func(a1, a2) @testing.parameterize(*testing.product({ 'fname': ['polyadd', 'polysub', 'polymul'], 'type_l': ['poly1d', 'ndarray', 'python_scalar', 'numpy_scalar'], 'type_r': ['poly1d', 'ndarray', 'python_scalar', 'numpy_scalar'], })) class TestPoly1dRoutines(Poly1dTestBase): @testing.with_requires('numpy>=1.20') @testing.for_all_dtypes() @testing.numpy_cupy_allclose(rtol=1e-4, accept_error=TypeError) def test_poly1d_routine(self, xp, dtype): func = getattr(xp, self.fname) a1 = self._get_input(xp, self.type_l, dtype) a2 = self._get_input(xp, self.type_r, dtype) return func(a1, a2) class TestPoly1dEquality: def make_poly1d1(self, xp, dtype): a1 = testing.shaped_arange((4,), xp, dtype) a2 = xp.zeros((4,), dtype) b1 = xp.poly1d(a1) b2 = xp.poly1d(a2) return b1, b2 def make_poly1d2(self, xp, dtype): a1 = testing.shaped_arange((4,), xp, dtype) a2 = testing.shaped_arange((4,), xp, dtype) b1 = xp.poly1d(a1) b2 = xp.poly1d(a2) return b1, b2 @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_eq1(self, xp, dtype): a, b = self.make_poly1d1(xp, dtype) return a == b @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_eq2(self, xp, dtype): a, b = self.make_poly1d2(xp, dtype) return a == b @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_ne1(self, xp, dtype): a, b = self.make_poly1d1(xp, dtype) return a != b @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_poly1d_ne2(self, xp, dtype): a, b = self.make_poly1d2(xp, dtype) return a != b @testing.parameterize(*testing.product({ 'fname': ['polyadd', 'polysub', 'polymul'], 'shape1': [(), (0,), (3,), (5,)], 'shape2': [(), (0,), (3,), (5,)], })) class TestPolyArithmeticShapeCombination: @testing.with_requires('numpy>=1.20') @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_allclose(rtol=1e-5) def test_polyroutine(self, xp, dtype): func = getattr(xp, self.fname) a = testing.shaped_arange(self.shape1, xp, dtype) b = testing.shaped_arange(self.shape2, xp, dtype) return func(a, b) @testing.parameterize(*testing.product({ 'fname': ['polyadd', 'polysub', 'polymul'], })) class TestPolyArithmeticDiffTypes: @testing.for_all_dtypes_combination(names=['dtype1', 'dtype2']) def test_polyroutine_diff_types_array(self, dtype1, dtype2): def f(xp): func = getattr(xp, self.fname) a = testing.shaped_arange((10,), xp, dtype1) b = testing.shaped_arange((5,), xp, dtype2) return func(a, b) rtol = 1e-5 if runtime.is_hip and self.fname == 'polymul': rtol = 1e-4 try: testing.assert_allclose(f(cupy), f(numpy), rtol=rtol) except TypeError: pass @testing.for_all_dtypes_combination(names=['dtype1', 'dtype2']) def test_polyroutine_diff_types_poly1d(self, dtype1, dtype2): def f(xp): func = getattr(xp, self.fname) a = testing.shaped_arange((10,), xp, dtype1) b = testing.shaped_arange((5,), xp, dtype2) a = xp.poly1d(a, variable='z') b = xp.poly1d(b, variable='y') out = func(a, b) assert out.variable == 'x' return out rtol = 1e-5 if runtime.is_hip and self.fname == 'polymul': rtol = 1e-4 try: testing.assert_allclose(f(cupy), f(numpy), rtol=rtol) except TypeError: pass @testing.parameterize(*testing.product({ 'shape1': [(3,)], 'shape2': [(3,), (3, 2)], 'deg': [0, 3, 3.0, 3.5, 10], 'rcond': [None, 0.5, 1e-15], 'weighted': [True, False] })) class TestPolyfitParametersCombinations: def _full_fit(self, xp, dtype): x = testing.shaped_arange(self.shape1, xp, dtype) y = testing.shaped_arange(self.shape2, xp, dtype) w = x if self.weighted else None return xp.polyfit(x, y, self.deg, self.rcond, True, w) @testing.for_all_dtypes() @testing.numpy_cupy_allclose( atol=1e-9, accept_error=TypeError, contiguous_check=False) def test_polyfit_default(self, xp, dtype): if runtime.is_hip and self.deg == 0: pytest.xfail('ROCm/HIP may have a bug') x = testing.shaped_arange(self.shape1, xp, dtype) y = testing.shaped_arange(self.shape2, xp, dtype) w = x if self.weighted else None return xp.polyfit(x, y, self.deg, self.rcond, w=w) @testing.for_all_dtypes(no_float16=True) def test_polyfit_full(self, dtype): if runtime.is_hip and self.deg == 0: pytest.xfail('ROCm/HIP may have a bug') cp_c, cp_resids, cp_rank, cp_s, cp_rcond = self._full_fit(cupy, dtype) np_c, np_resids, np_rank, np_s, np_rcond = self._full_fit(numpy, dtype) testing.assert_allclose(cp_c, np_c, atol=1e-9) testing.assert_allclose(cp_resids, np_resids, atol=1e-9) testing.assert_allclose(cp_s, np_s, atol=1e-9) assert cp_rank == np_rank if self.rcond is not None: assert cp_rcond == np_rcond @testing.parameterize(*testing.product({ 'shape': [(3,), (3, 2)], 'deg': [0, 1], 'rcond': [None, 1e-15], 'weighted': [True, False], 'cov': ['unscaled', True] })) class TestPolyfitCovMode: def _cov_fit(self, xp, dtype): x = xp.array([0.008, 0.01, 0.015], dtype) y = testing.shaped_arange(self.shape, xp, dtype) w = x if self.weighted else None return xp.polyfit(x, y, self.deg, self.rcond, w=w, cov=self.cov) @testing.for_float_dtypes(no_float16=True) def test_polyfit_cov(self, dtype): if runtime.is_hip and self.deg == 0: pytest.xfail('ROCm/HIP may have a bug') cp_c, cp_cov = self._cov_fit(cupy, dtype) np_c, np_cov = self._cov_fit(numpy, dtype) testing.assert_allclose(cp_c, np_c, rtol=1e-5) testing.assert_allclose(cp_cov, np_cov, rtol=1e-3) class TestPolyfit: @testing.for_all_dtypes(no_float16=True) def test_polyfit_poor_fit(self, dtype): for xp in (numpy, cupy): x = testing.shaped_arange((5,), xp, dtype) y = testing.shaped_arange((5,), xp, dtype) with pytest.warns(numpy.RankWarning): xp.polyfit(x, y, 6) @testing.parameterize(*testing.product({ 'shape': [(), (0,), (5, 3, 3)], })) class TestPolyfitInvalidShapes: @testing.for_all_dtypes(no_float16=True) def test_polyfit_x_invalid_shape(self, dtype): for xp in (numpy, cupy): x = testing.shaped_arange(self.shape, xp, dtype) y = testing.shaped_arange((5,), xp, dtype) with pytest.raises(TypeError): xp.polyfit(x, y, 5) @testing.for_all_dtypes(no_float16=True) def test_polyfit_y_invalid_shape(self, dtype): for xp in (numpy, cupy): x = testing.shaped_arange((5,), xp, dtype) y = testing.shaped_arange(self.shape, xp, dtype) with pytest.raises(TypeError): xp.polyfit(x, y, 5) @testing.for_all_dtypes(no_float16=True) def test_polyfit_w_invalid_shape(self, dtype): for xp in (numpy, cupy): x = testing.shaped_arange((5,), xp, dtype) w = testing.shaped_arange(self.shape, xp, dtype) with pytest.raises(TypeError): xp.polyfit(x, x, 5, w=w) class TestPolyfitInvalid: @testing.for_all_dtypes(no_float16=True) def test_polyfit_neg_degree(self, dtype): for xp in (numpy, cupy): x = testing.shaped_arange((5,), xp, dtype) y = testing.shaped_arange((5,), xp, dtype) with pytest.raises(ValueError): xp.polyfit(x, y, -4) @testing.for_all_dtypes(no_float16=True) def test_polyfit_complex_degree(self, dtype): for xp in (numpy, cupy): x = testing.shaped_arange((5,), xp, dtype) y = testing.shaped_arange((5,), xp, dtype) with pytest.raises(TypeError): xp.polyfit(x, y, 5j) @testing.for_all_dtypes(no_float16=True) def test_polyfit_xy_mismatched_length(self, dtype): for xp in (numpy, cupy): x = testing.shaped_arange((10,), xp, dtype) y = testing.shaped_arange((5,), xp, dtype) with pytest.raises(TypeError): xp.polyfit(x, y, 5) @testing.for_all_dtypes(no_float16=True) def test_polyfit_yw_mismatched_length(self, dtype): for xp in (numpy, cupy): y = testing.shaped_arange((10,), xp, dtype) w = testing.shaped_arange((5,), xp, dtype) with pytest.raises(TypeError): xp.polyfit(y, y, 5, w=w) @testing.for_all_dtypes(no_float16=True, no_bool=True) def test_polyfit_cov_invalid(self, dtype): for xp in (numpy, cupy): x = testing.shaped_arange((5,), xp, dtype) y = testing.shaped_arange((5,), xp, dtype) with pytest.raises(ValueError): xp.polyfit(x, y, 5, cov=True) def test_polyfit_float16(self): for xp in (numpy, cupy): x = testing.shaped_arange((5,), xp, numpy.float16) with pytest.raises(TypeError): xp.polyfit(x, x, 4) class TestPolyfitDiffTypes: @testing.for_all_dtypes_combination( names=['dtype1', 'dtype2'], no_bool=True, full=True) @testing.numpy_cupy_allclose(rtol=1e-1, atol=1e-1, accept_error=TypeError) def test_polyfit_unweighted_diff_types(self, xp, dtype1, dtype2): x = testing.shaped_arange((5,), xp, dtype1) y = testing.shaped_arange((5,), xp, dtype2) return xp.polyfit(x, y, 5) @testing.for_all_dtypes_combination( names=['dtype1', 'dtype2', 'dtype3'], no_bool=True, full=True) @testing.numpy_cupy_allclose(atol=1e-0, accept_error=TypeError) def test_polyfit_weighted_diff_types(self, xp, dtype1, dtype2, dtype3): x = testing.shaped_arange((5,), xp, dtype1) y = testing.shaped_arange((5,), xp, dtype2) w = testing.shaped_arange((5,), xp, dtype3) return xp.polyfit(x, y, 5, w=w) @testing.parameterize(*testing.product({ 'type_l': ['poly1d', 'ndarray'], 'type_r': ['poly1d', 'ndarray', 'numpy_scalar', 'python_scalar'], })) class TestPolyval(Poly1dTestBase): @testing.for_all_dtypes() @testing.numpy_cupy_allclose(rtol={numpy.float16: 1e-2, 'default': 1e-3}) def test_polyval(self, xp, dtype): a1 = self._get_input(xp, self.type_l, dtype, size=5) a2 = self._get_input(xp, self.type_r, dtype, size=5) return xp.polyval(a1, a2) @testing.parameterize(*testing.product({ 'type_l': ['numpy_scalar', 'python_scalar'], 'type_r': ['poly1d', 'ndarray', 'python_scalar', 'numpy_scalar'], })) class TestPolyvalInvalidTypes(Poly1dTestBase): @testing.for_all_dtypes() def test_polyval(self, dtype): for xp in (numpy, cupy): a1 = self._get_input(xp, self.type_l, dtype) a2 = self._get_input(xp, self.type_r, dtype) with pytest.raises(TypeError): xp.polyval(a1, a2) @testing.parameterize(*testing.product({ 'shape1': [(0,), (3,), (5,)], 'shape2': [(), (0,), (3,), (5,)] })) class TestPolyvalShapeCombination: @testing.for_all_dtypes() @testing.numpy_cupy_allclose(rtol={numpy.float16: 1e-2, 'default': 1e-6}) def test_polyval(self, xp, dtype): a = testing.shaped_arange(self.shape1, xp, dtype) b = testing.shaped_arange(self.shape2, xp, dtype) return xp.polyval(a, b) @testing.parameterize(*testing.product({ 'shape': [(), (0,), (3,), (5,)] })) class TestPolyvalInvalidShapeCombination: @testing.for_all_dtypes() def test_polyval(self, dtype): for xp in (numpy, cupy): a = testing.shaped_arange((), xp, dtype) b = testing.shaped_arange(self.shape, xp, dtype) with pytest.raises(TypeError): xp.polyval(a, b) class TestPolyvalDtypesCombination: @testing.for_all_dtypes_combination(names=['dtype1', 'dtype2'], full=True) @testing.numpy_cupy_allclose(rtol={numpy.float16: 1e-2, 'default': 1e-6}) def test_polyval_diff_types_array_array(self, xp, dtype1, dtype2): a = testing.shaped_arange((10,), xp, dtype1) b = testing.shaped_arange((3,), xp, dtype2) return xp.polyval(a, b) @testing.for_all_dtypes_combination(names=['dtype1', 'dtype2'], full=True) @testing.numpy_cupy_allclose(rtol=1e-6) def test_polyval_diff_types_array_scalar(self, xp, dtype1, dtype2): a = testing.shaped_arange((10,), xp, dtype1) b = dtype2(3) return xp.polyval(a, b) class TestPolyvalMultiDimensional: @testing.for_all_dtypes() def test_polyval_ndim_values(self, dtype): a = testing.shaped_arange((10,), cupy, dtype) b = testing.shaped_arange((2, 4), cupy, dtype) return cupy.polyval(a, b) @testing.for_all_dtypes() def test_polyval_poly1d_values(self, dtype): a = testing.shaped_arange((5,), cupy, dtype) b = testing.shaped_arange((3,), cupy, dtype) b = cupy.poly1d(b) return cupy.polyval(a, b) @testing.parameterize(*testing.product({ 'fname': ['polyadd', 'polysub', 'polymul', 'polyval'], })) class TestPolyRoutinesNdim: @testing.for_all_dtypes() def test_polyroutine_ndim(self, dtype): for xp in (numpy, cupy): func = getattr(xp, self.fname) a = testing.shaped_arange((2, 3, 4), xp, dtype) b = testing.shaped_arange((10, 5), xp, dtype) with pytest.raises(ValueError): func(a, b) @testing.parameterize(*testing.product({ 'input': [[2, -1, -2], [-4, 10, 4]], })) @pytest.mark.skipif(runtime.is_hip and driver.get_build_version() < 402, reason='syevj not available') class TestRootsReal: @testing.for_signed_dtypes() @testing.numpy_cupy_allclose(rtol=1e-6) def test_roots_array(self, xp, dtype): a = xp.array(self.input, dtype) out = xp.roots(a) return xp.sort(out) @testing.for_signed_dtypes() @testing.numpy_cupy_allclose(rtol=1e-6) def test_roots_poly1d(self, xp, dtype): a = xp.array(self.input, dtype) out = xp.roots(xp.poly1d(a)) return xp.sort(out) @testing.parameterize(*testing.product({ 'input': [[3j, 1.5j, -3j], [3 + 2j, 5], [3j, 0], [0, 3j]], })) class TestRootsComplex: @testing.for_complex_dtypes() @testing.numpy_cupy_allclose(rtol=1e-6) def test_roots_array(self, xp, dtype): if runtime.is_hip and self.input == [3j, 1.5j, -3j]: pytest.xfail('rocBLAS not implemented') a = xp.array(self.input, dtype) out = xp.roots(a) return xp.sort(out) @testing.for_complex_dtypes() @testing.numpy_cupy_allclose(rtol=1e-6) def test_roots_poly1d(self, xp, dtype): if runtime.is_hip and self.input == [3j, 1.5j, -3j]: pytest.xfail('rocBLAS not implemented') a = xp.array(self.input, dtype) out = xp.roots(xp.poly1d(a)) return xp.sort(out) @testing.parameterize(*testing.product({ 'input': [[5, 10], [5, 0], [0, 5], [0, 0], [5]], })) class TestRootsSpecialCases: @testing.for_all_dtypes(no_float16=True, no_bool=True) @testing.numpy_cupy_array_equal() def test_roots_array(self, xp, dtype): a = xp.array(self.input, dtype) return xp.roots(a) @testing.for_all_dtypes(no_float16=True, no_bool=True) @testing.numpy_cupy_array_equal() def test_roots_poly1d(self, xp, dtype): a = xp.array(self.input, dtype) return xp.roots(xp.poly1d(a)) class TestRoots: @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_roots_zero_sized(self, xp, dtype): a = xp.zeros((0,), dtype) return xp.roots(a) @testing.with_requires('numpy>1.17') @testing.for_all_dtypes(no_bool=True) def test_roots_zero_dim(self, dtype): for xp in (numpy, cupy): a = testing.shaped_random((), xp, dtype) with pytest.raises(TypeError): xp.roots(a) @testing.for_all_dtypes(no_bool=True) def test_roots_ndim(self, dtype): for xp in (numpy, cupy): a = testing.shaped_arange((3, 1), xp, dtype) with pytest.raises(ValueError): xp.roots(a) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_roots_zeros(self, xp, dtype): a = xp.zeros((3,), dtype) return xp.roots(a) @testing.for_all_dtypes(no_bool=True) def test_roots_zeros_ndim(self, dtype): for xp in (numpy, cupy): a = xp.zeros((2, 1), dtype) with pytest.raises(ValueError): xp.roots(a) def test_roots_bool_symmetric(self): a = cupy.array([5, -1, -5], bool) with pytest.raises(NotImplementedError): cupy.roots(a)