From 3324da4da824c60c2a3435cc9a6458d56bec0554 Mon Sep 17 00:00:00 2001 From: vtavana <120411540+vtavana@users.noreply.github.com> Date: Sun, 18 Feb 2024 10:09:08 -0600 Subject: [PATCH] return a view for `dpnp.ndarray.real` and `dpnp.ndarray.imag` (#1719) * return a view for dpnp.ndarray.real/imag * return self for real numbers * update real/imag/conj test * fix dtype in test_conj_out --- dpnp/dpnp_array.py | 11 ++- tests/test_dparray.py | 17 ++++ tests/test_mathematical.py | 181 ++++++++++++++++++++++++++----------- 3 files changed, 152 insertions(+), 57 deletions(-) diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index b5e75dde07c..6b4ccb4e33a 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -831,7 +831,9 @@ def imag(self): array([0. , 0.70710677]) """ - return dpnp.imag(self) + return dpnp_array._create_from_usm_ndarray( + dpnp.get_usm_ndarray(self).imag + ) @imag.setter def imag(self, value): @@ -1042,7 +1044,12 @@ def real(self): array([1. , 0.70710677]) """ - return dpnp.real(self) + if dpnp.issubsctype(self.dtype, dpnp.complexfloating): + return dpnp_array._create_from_usm_ndarray( + dpnp.get_usm_ndarray(self).real + ) + else: + return self @real.setter def real(self, value): diff --git a/tests/test_dparray.py b/tests/test_dparray.py index 26446c855ac..874493f4e95 100644 --- a/tests/test_dparray.py +++ b/tests/test_dparray.py @@ -86,6 +86,23 @@ def test_flags_strides(dtype, order, strides): assert numpy_array.flags.f_contiguous == dpnp_array.flags.f_contiguous +def test_flags_writable(): + a = dpnp.arange(10, dtype="f4") + a.flags["W"] = False + + a.shape = (5, 2) + assert not a.flags.writable + assert not a.T.flags.writable + assert not a.real.flags.writable + assert not a[0:3].flags.writable + + a = dpnp.arange(10, dtype="c8") + a.flags["W"] = False + + assert not a.real.flags.writable + assert not a.imag.flags.writable + + def test_print_dpnp_int(): result = repr(dpnp.array([1, 0, 2, -3, -1, 2, 21, -9], dtype="i4")) expected = "array([ 1, 0, 2, -3, -1, 2, 21, -9], dtype=int32)" diff --git a/tests/test_mathematical.py b/tests/test_mathematical.py index 7c0e87fe3d2..cbbab19333c 100644 --- a/tests/test_mathematical.py +++ b/tests/test_mathematical.py @@ -906,70 +906,141 @@ def test_signbit(data, dtype): assert_dtype_allclose(result, expected) -@pytest.mark.parametrize( - "func", - ["real", "imag", "conj"], - ids=["real", "imag", "conj"], -) -@pytest.mark.parametrize( - "data", - [complex(-1, -4), complex(-1, 2), complex(3, -7), complex(4, 12)], - ids=[ - "complex(-1, -4)", - "complex(-1, 2)", - "complex(3, -7)", - "complex(4, 12)", - ], -) -@pytest.mark.parametrize("dtype", get_complex_dtypes()) -def test_complex_funcs(func, data, dtype): - np_a = numpy.array(data, dtype=dtype) - dpnp_a = dpnp.array(data, dtype=dtype) +class TestConj: + @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + def test_conj(self, dtype): + a = numpy.array(numpy.random.uniform(-5, 5, 20), dtype=dtype) + ia = dpnp.array(a) - result = getattr(dpnp, func)(dpnp_a) - expected = getattr(numpy, func)(np_a) - assert_dtype_allclose(result, expected) + result = dpnp.conj(ia) + expected = numpy.conj(a) + assert_dtype_allclose(result, expected) - # out keyword - if func == "conj": - dp_out = dpnp.empty(expected.shape, dtype=expected.dtype) - result = getattr(dpnp, func)(dpnp_a, out=dp_out) + @pytest.mark.parametrize("dtype", get_complex_dtypes()) + def test_conj_complex(self, dtype): + x1 = numpy.random.uniform(-5, 5, 20) + x2 = numpy.random.uniform(-5, 5, 20) + a = numpy.array(x1 + 1j * x2, dtype=dtype) + ia = dpnp.array(a) + + result = dpnp.conj(ia) + expected = numpy.conj(a) + assert_dtype_allclose(result, expected) + + @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + def test_conj_ndarray(self, dtype): + a = numpy.array(numpy.random.uniform(-5, 5, 20), dtype=dtype) + ia = dpnp.array(a) + + result = ia.conj() + assert result is ia + assert_dtype_allclose(result, a.conj()) + + @pytest.mark.parametrize("dtype", get_complex_dtypes()) + def test_conj_complex_ndarray(self, dtype): + x1 = numpy.random.uniform(-5, 5, 20) + x2 = numpy.random.uniform(-5, 5, 20) + a = numpy.array(x1 + 1j * x2, dtype=dtype) + ia = dpnp.array(a) + + assert_dtype_allclose(ia.conj(), a.conj()) + + @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) + def test_conj_out(self, dtype): + a = numpy.array(numpy.random.uniform(-5, 5, 20), dtype=dtype) + ia = dpnp.array(a) + + expected = numpy.conj(a) + dp_out = dpnp.empty(ia.shape, dtype=dtype) + result = dpnp.conj(ia, out=dp_out) assert dp_out is result assert_dtype_allclose(result, expected) -@pytest.mark.parametrize("dtype", get_complex_dtypes()) -def test_projection_infinity(dtype): - X = [ - complex(1, 2), - complex(dpnp.inf, -1), - complex(0, -dpnp.inf), - complex(-dpnp.inf, dpnp.nan), - ] - Y = [ - complex(1, 2), - complex(dpnp.inf, -0.0), - complex(dpnp.inf, -0.0), - complex(dpnp.inf, 0.0), - ] - - a = dpnp.array(X, dtype=dtype) - result = dpnp.proj(a) - expected = dpnp.array(Y, dtype=dtype) - assert_dtype_allclose(result, expected) +class TestRealImag: + @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + def test_real_imag(self, dtype): + a = numpy.array(numpy.random.uniform(-5, 5, 20), dtype=dtype) + ia = dpnp.array(a) - # out keyword - dp_out = dpnp.empty(expected.shape, dtype=expected.dtype) - result = dpnp.proj(a, out=dp_out) - assert dp_out is result - assert_dtype_allclose(result, expected) + result = dpnp.real(ia) + assert result is ia + expected = numpy.real(a) + assert expected is a + assert_dtype_allclose(result, expected) + result = dpnp.imag(ia) + expected = numpy.imag(a) + assert_dtype_allclose(result, expected) -@pytest.mark.parametrize("dtype", get_all_dtypes()) -def test_projection(dtype): - result = dpnp.proj(dpnp.array(1, dtype=dtype)) - expected = dpnp.array(complex(1, 0)) - assert_allclose(result, expected) + @pytest.mark.parametrize("dtype", get_complex_dtypes()) + def test_real_imag_complex(self, dtype): + x1 = numpy.random.uniform(-5, 5, 20) + x2 = numpy.random.uniform(-5, 5, 20) + a = numpy.array(x1 + 1j * x2, dtype=dtype) + ia = dpnp.array(a) + + result = dpnp.real(ia) + expected = numpy.real(a) + assert_dtype_allclose(result, expected) + + result = dpnp.imag(ia) + expected = numpy.imag(a) + assert_dtype_allclose(result, expected) + + @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + def test_real_imag_ndarray(self, dtype): + a = numpy.array(numpy.random.uniform(-5, 5, 20), dtype=dtype) + ia = dpnp.array(a) + + result = ia.real + assert result is ia + assert_dtype_allclose(result, a.real) + assert_dtype_allclose(ia.imag, a.imag) + + @pytest.mark.parametrize("dtype", get_complex_dtypes()) + def test_real_imag_complex_ndarray(self, dtype): + x1 = numpy.random.uniform(-5, 5, 20) + x2 = numpy.random.uniform(-5, 5, 20) + a = numpy.array(x1 + 1j * x2, dtype=dtype) + ia = dpnp.array(a) + + assert_dtype_allclose(ia.real, a.real) + assert_dtype_allclose(ia.imag, a.imag) + + +class TestProjection: + @pytest.mark.parametrize("dtype", get_complex_dtypes()) + def test_projection_infinity(self, dtype): + X = [ + complex(1, 2), + complex(dpnp.inf, -1), + complex(0, -dpnp.inf), + complex(-dpnp.inf, dpnp.nan), + ] + Y = [ + complex(1, 2), + complex(dpnp.inf, -0.0), + complex(dpnp.inf, -0.0), + complex(dpnp.inf, 0.0), + ] + + a = dpnp.array(X, dtype=dtype) + result = dpnp.proj(a) + expected = dpnp.array(Y, dtype=dtype) + assert_dtype_allclose(result, expected) + + # out keyword + dp_out = dpnp.empty(expected.shape, dtype=expected.dtype) + result = dpnp.proj(a, out=dp_out) + assert dp_out is result + assert_dtype_allclose(result, expected) + + @pytest.mark.parametrize("dtype", get_all_dtypes()) + def test_projection(self, dtype): + result = dpnp.proj(dpnp.array(1, dtype=dtype)) + expected = dpnp.array(complex(1, 0)) + assert_allclose(result, expected) @pytest.mark.parametrize("val_type", get_all_dtypes(no_none=True))