Skip to content

Commit 1cf5aa3

Browse files
committed
Update tests for nan-like functions
1 parent 36f7e2b commit 1cf5aa3

File tree

1 file changed

+68
-163
lines changed

1 file changed

+68
-163
lines changed

dpnp/tests/test_nanfunctions.py

Lines changed: 68 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515

1616
from .helper import (
1717
assert_dtype_allclose,
18+
generate_random_numpy_array,
1819
get_all_dtypes,
1920
get_complex_dtypes,
2021
get_float_complex_dtypes,
2122
get_float_dtypes,
2223
has_support_aspect64,
24+
numpy_version,
2325
)
2426
from .third_party.cupy import testing
2527

@@ -604,7 +606,14 @@ def test_nanprod_Error(self):
604606
dpnp.nanprod(dpnp.asnumpy(ia))
605607

606608

607-
class TestNanStd:
609+
@testing.parameterize(
610+
*testing.product(
611+
{
612+
"func": ("nanstd", "nanvar"),
613+
}
614+
)
615+
)
616+
class TestNanStdVar:
608617
@pytest.mark.parametrize(
609618
"array",
610619
[
@@ -646,89 +655,121 @@ class TestNanStd:
646655
@pytest.mark.parametrize(
647656
"dtype", get_all_dtypes(no_none=True, no_bool=True)
648657
)
649-
def test_nanstd(self, array, dtype):
658+
def test_basic(self, array, dtype):
650659
try:
651660
a = numpy.array(array, dtype=dtype)
652661
except:
653662
pytest.skip("floating datat type is needed to store NaN")
654663
ia = dpnp.array(a)
664+
655665
for ddof in range(a.ndim):
656-
expected = numpy.nanstd(a, ddof=ddof)
657-
result = dpnp.nanstd(ia, ddof=ddof)
666+
expected = getattr(numpy, self.func)(a, ddof=ddof)
667+
result = getattr(dpnp, self.func)(ia, ddof=ddof)
658668
assert_dtype_allclose(result, expected)
659669

660670
@pytest.mark.parametrize("dtype", get_complex_dtypes())
661-
def test_nanstd_complex(self, dtype):
662-
x1 = numpy.random.rand(10)
663-
x2 = numpy.random.rand(10)
664-
a = numpy.array(x1 + 1j * x2, dtype=dtype)
671+
def test_complex_dtype(self, dtype):
672+
a = generate_random_numpy_array(10, dtype=dtype)
665673
a[::3] = numpy.nan
666674
ia = dpnp.array(a)
667675

668-
expected = numpy.nanstd(a)
669-
result = dpnp.nanstd(ia)
676+
expected = getattr(numpy, self.func)(a)
677+
result = getattr(dpnp, self.func)(ia)
670678
assert_dtype_allclose(result, expected)
671679

672680
@pytest.mark.usefixtures("suppress_dof_numpy_warnings")
673681
@pytest.mark.parametrize("dtype", get_float_complex_dtypes())
674682
@pytest.mark.parametrize("axis", [None, 0, 1, 2, (0, 1), (1, 2)])
675683
@pytest.mark.parametrize("keepdims", [True, False])
676684
@pytest.mark.parametrize("ddof", [0, 0.5, 1, 1.5, 2, 3])
677-
def test_nanstd_out(self, dtype, axis, keepdims, ddof):
685+
def test_out_keyword(self, dtype, axis, keepdims, ddof):
678686
a = numpy.arange(4 * 3 * 5, dtype=dtype)
679687
a[::2] = numpy.nan
680688
a = a.reshape(4, 3, 5)
681689
ia = dpnp.array(a)
682690

683-
expected = numpy.nanstd(a, axis=axis, ddof=ddof, keepdims=keepdims)
691+
expected = getattr(numpy, self.func)(
692+
a, axis=axis, ddof=ddof, keepdims=keepdims
693+
)
684694
if has_support_aspect64():
685695
res_dtype = expected.dtype
686696
else:
687697
res_dtype = dpnp.default_float_type(ia.device)
688698
out = dpnp.empty(expected.shape, dtype=res_dtype)
689-
result = dpnp.nanstd(
699+
result = getattr(dpnp, self.func)(
690700
ia, out=out, axis=axis, ddof=ddof, keepdims=keepdims
691701
)
692702
assert result is out
693703
assert_dtype_allclose(result, expected)
694704

695705
@pytest.mark.parametrize("dtype", get_float_complex_dtypes())
696-
def test_nanstd_strided(self, dtype):
697-
dp_array = dpnp.arange(20, dtype=dtype)
698-
dp_array[::3] = dpnp.nan
699-
np_array = dpnp.asnumpy(dp_array)
706+
def test_strided_array(self, dtype):
707+
a = numpy.arange(20, dtype=dtype)
708+
a[::3] = numpy.nan
709+
ia = dpnp.array(a)
700710

701-
result = dpnp.nanstd(dp_array[::-1])
702-
expected = numpy.nanstd(np_array[::-1])
711+
result = getattr(dpnp, self.func)(ia[::-1])
712+
expected = getattr(numpy, self.func)(a[::-1])
703713
assert_dtype_allclose(result, expected)
704714

705-
result = dpnp.nanstd(dp_array[::2])
706-
expected = numpy.nanstd(np_array[::2])
715+
result = getattr(dpnp, self.func)(ia[::2])
716+
expected = getattr(numpy, self.func)(a[::2])
707717
assert_dtype_allclose(result, expected)
708718

709719
@pytest.mark.usefixtures("suppress_complex_warning")
710720
@pytest.mark.parametrize("dt_in", get_float_complex_dtypes())
711721
@pytest.mark.parametrize("dt_out", get_float_complex_dtypes())
712-
def test_nanstd_dtype(self, dt_in, dt_out):
722+
def test_dtype_keyword(self, dt_in, dt_out):
713723
a = numpy.arange(4 * 3 * 5, dtype=dt_in)
714724
a[::2] = numpy.nan
715725
a = a.reshape(4, 3, 5)
716726
ia = dpnp.array(a)
717727

718-
expected = numpy.nanstd(a, dtype=dt_out)
719-
result = dpnp.nanstd(ia, dtype=dt_out)
728+
expected = getattr(numpy, self.func)(a, dtype=dt_out)
729+
result = getattr(dpnp, self.func)(ia, dtype=dt_out)
720730
assert_dtype_allclose(result, expected)
721731

722-
def test_nanstd_error(self):
732+
@pytest.mark.parametrize("dtype", get_float_complex_dtypes())
733+
@pytest.mark.parametrize("axis", [1, (0, 2), None])
734+
@pytest.mark.parametrize("keepdims", [True, False])
735+
def test_mean_keyword(self, dtype, axis, keepdims):
736+
a = generate_random_numpy_array((10, 20, 5), dtype)
737+
mask = numpy.random.choice([True, False], size=a.size, p=[0.3, 0.7])
738+
numpy.place(a, mask, numpy.nan)
739+
ia = dpnp.array(a)
740+
741+
mean = numpy.nanmean(a, axis=axis, keepdims=True)
742+
imean = dpnp.nanmean(ia, axis=axis, keepdims=True)
743+
744+
mean_kw = {"mean": mean} if numpy_version() >= "2.0.0" else {}
745+
expected = getattr(numpy, self.func)(
746+
a, axis=axis, keepdims=keepdims, **mean_kw
747+
)
748+
result = getattr(dpnp, self.func)(
749+
ia, axis=axis, keepdims=keepdims, mean=imean
750+
)
751+
assert_dtype_allclose(result, expected)
752+
753+
def test_error(self):
723754
ia = dpnp.arange(5, dtype=dpnp.float32)
724755
ia[0] = dpnp.nan
756+
725757
# where keyword is not implemented
726758
with pytest.raises(NotImplementedError):
727-
dpnp.nanstd(ia, where=False)
759+
getattr(dpnp, self.func)(ia, where=False)
760+
761+
# dtype should be floating
762+
with pytest.raises(TypeError):
763+
getattr(dpnp, self.func)(ia, dtype=dpnp.int32)
764+
765+
# out dtype should be inexact
766+
res = dpnp.empty((1,), dtype=dpnp.int32)
767+
with pytest.raises(TypeError):
768+
getattr(dpnp, self.func)(ia, out=res)
728769

729770
# ddof should be an integer or float
730771
with pytest.raises(TypeError):
731-
dpnp.nanstd(ia, ddof="1")
772+
getattr(dpnp, self.func)(ia, ddof="1")
732773

733774

734775
class TestNanSum:
@@ -789,139 +830,3 @@ def test_nansum_strided(self, dtype):
789830
result = dpnp.nansum(dp_array[::2])
790831
expected = numpy.nansum(np_array[::2])
791832
assert_allclose(result, expected)
792-
793-
794-
class TestNanVar:
795-
@pytest.mark.parametrize(
796-
"array",
797-
[
798-
[2, 0, 6, 2],
799-
[2, 0, 6, 2, 5, 6, 7, 8],
800-
[],
801-
[2, 1, numpy.nan, 5, 3],
802-
[-1, numpy.nan, 1, numpy.inf],
803-
[3, 6, 0, 1],
804-
[3, 6, 0, 1, 8],
805-
[3, 2, 9, 6, numpy.nan],
806-
[numpy.nan, numpy.nan, numpy.inf, numpy.nan],
807-
[[2, 0], [6, 2]],
808-
[[2, 0, 6, 2], [5, 6, 7, 8]],
809-
[[[2, 0], [6, 2]], [[5, 6], [7, 8]]],
810-
[[-1, numpy.nan], [1, numpy.inf]],
811-
[[numpy.nan, numpy.nan], [numpy.inf, numpy.nan]],
812-
],
813-
ids=[
814-
"[2, 0, 6, 2]",
815-
"[2, 0, 6, 2, 5, 6, 7, 8]",
816-
"[]",
817-
"[2, 1, np.nan, 5, 3]",
818-
"[-1, np.nan, 1, np.inf]",
819-
"[3, 6, 0, 1]",
820-
"[3, 6, 0, 1, 8]",
821-
"[3, 2, 9, 6, np.nan]",
822-
"[np.nan, np.nan, np.inf, np.nan]",
823-
"[[2, 0], [6, 2]]",
824-
"[[2, 0, 6, 2], [5, 6, 7, 8]]",
825-
"[[[2, 0], [6, 2]], [[5, 6], [7, 8]]]",
826-
"[[-1, np.nan], [1, np.inf]]",
827-
"[[np.nan, np.nan], [np.inf, np.nan]]",
828-
],
829-
)
830-
@pytest.mark.usefixtures(
831-
"suppress_invalid_numpy_warnings", "suppress_dof_numpy_warnings"
832-
)
833-
@pytest.mark.parametrize(
834-
"dtype", get_all_dtypes(no_none=True, no_bool=True)
835-
)
836-
def test_nanvar(self, array, dtype):
837-
try:
838-
a = numpy.array(array, dtype=dtype)
839-
except:
840-
pytest.skip("floating datat type is needed to store NaN")
841-
ia = dpnp.array(a)
842-
for ddof in range(a.ndim):
843-
expected = numpy.nanvar(a, ddof=ddof)
844-
result = dpnp.nanvar(ia, ddof=ddof)
845-
assert_dtype_allclose(result, expected)
846-
847-
@pytest.mark.parametrize("dtype", get_complex_dtypes())
848-
def test_nanvar_complex(self, dtype):
849-
x1 = numpy.random.rand(10)
850-
x2 = numpy.random.rand(10)
851-
a = numpy.array(x1 + 1j * x2, dtype=dtype)
852-
a[::3] = numpy.nan
853-
ia = dpnp.array(a)
854-
855-
expected = numpy.nanvar(a)
856-
result = dpnp.nanvar(ia)
857-
assert_dtype_allclose(result, expected)
858-
859-
@pytest.mark.usefixtures("suppress_dof_numpy_warnings")
860-
@pytest.mark.parametrize("dtype", get_float_complex_dtypes())
861-
@pytest.mark.parametrize("axis", [None, 0, 1, 2, (0, 1), (1, 2)])
862-
@pytest.mark.parametrize("keepdims", [True, False])
863-
@pytest.mark.parametrize("ddof", [0, 0.5, 1, 1.5, 2, 3])
864-
def test_nanvar_out(self, dtype, axis, keepdims, ddof):
865-
a = numpy.arange(4 * 3 * 5, dtype=dtype)
866-
a[::2] = numpy.nan
867-
a = a.reshape(4, 3, 5)
868-
ia = dpnp.array(a)
869-
870-
expected = numpy.nanvar(a, axis=axis, ddof=ddof, keepdims=keepdims)
871-
if has_support_aspect64():
872-
res_dtype = expected.dtype
873-
else:
874-
res_dtype = dpnp.default_float_type(ia.device)
875-
out = dpnp.empty(expected.shape, dtype=res_dtype)
876-
result = dpnp.nanvar(
877-
ia, out=out, axis=axis, ddof=ddof, keepdims=keepdims
878-
)
879-
assert result is out
880-
assert_dtype_allclose(result, expected)
881-
882-
@pytest.mark.parametrize("dtype", get_float_complex_dtypes())
883-
def test_nanvar_strided(self, dtype):
884-
dp_array = dpnp.arange(20, dtype=dtype)
885-
dp_array[::3] = dpnp.nan
886-
np_array = dpnp.asnumpy(dp_array)
887-
888-
result = dpnp.nanvar(dp_array[::-1])
889-
expected = numpy.nanvar(np_array[::-1])
890-
assert_dtype_allclose(result, expected)
891-
892-
result = dpnp.nanvar(dp_array[::2])
893-
expected = numpy.nanvar(np_array[::2])
894-
assert_dtype_allclose(result, expected)
895-
896-
@pytest.mark.usefixtures("suppress_complex_warning")
897-
@pytest.mark.parametrize("dt_in", get_float_complex_dtypes())
898-
@pytest.mark.parametrize("dt_out", get_float_complex_dtypes())
899-
def test_nanvar_dtype(self, dt_in, dt_out):
900-
a = numpy.arange(4 * 3 * 5, dtype=dt_in)
901-
a[::2] = numpy.nan
902-
a = a.reshape(4, 3, 5)
903-
ia = dpnp.array(a)
904-
905-
expected = numpy.nanvar(a, dtype=dt_out)
906-
result = dpnp.nanvar(ia, dtype=dt_out)
907-
assert_dtype_allclose(result, expected)
908-
909-
def test_nanvar_error(self):
910-
ia = dpnp.arange(5, dtype=dpnp.float32)
911-
ia[0] = dpnp.nan
912-
# where keyword is not implemented
913-
with pytest.raises(NotImplementedError):
914-
dpnp.nanvar(ia, where=False)
915-
916-
# dtype should be floating
917-
with pytest.raises(TypeError):
918-
dpnp.nanvar(ia, dtype=dpnp.int32)
919-
920-
# out dtype should be inexact
921-
res = dpnp.empty((1,), dtype=dpnp.int32)
922-
with pytest.raises(TypeError):
923-
dpnp.nanvar(ia, out=res)
924-
925-
# ddof should be an integer or float
926-
with pytest.raises(TypeError):
927-
dpnp.nanvar(ia, ddof="1")

0 commit comments

Comments
 (0)