|
15 | 15 |
|
16 | 16 | from .helper import (
|
17 | 17 | assert_dtype_allclose,
|
| 18 | + generate_random_numpy_array, |
18 | 19 | get_all_dtypes,
|
19 | 20 | get_complex_dtypes,
|
20 | 21 | get_float_complex_dtypes,
|
21 | 22 | get_float_dtypes,
|
22 | 23 | has_support_aspect64,
|
| 24 | + numpy_version, |
23 | 25 | )
|
24 | 26 | from .third_party.cupy import testing
|
25 | 27 |
|
@@ -604,7 +606,14 @@ def test_nanprod_Error(self):
|
604 | 606 | dpnp.nanprod(dpnp.asnumpy(ia))
|
605 | 607 |
|
606 | 608 |
|
607 |
| -class TestNanStd: |
| 609 | +@testing.parameterize( |
| 610 | + *testing.product( |
| 611 | + { |
| 612 | + "func": ("nanstd", "nanvar"), |
| 613 | + } |
| 614 | + ) |
| 615 | +) |
| 616 | +class TestNanStdVar: |
608 | 617 | @pytest.mark.parametrize(
|
609 | 618 | "array",
|
610 | 619 | [
|
@@ -646,89 +655,121 @@ class TestNanStd:
|
646 | 655 | @pytest.mark.parametrize(
|
647 | 656 | "dtype", get_all_dtypes(no_none=True, no_bool=True)
|
648 | 657 | )
|
649 |
| - def test_nanstd(self, array, dtype): |
| 658 | + def test_basic(self, array, dtype): |
650 | 659 | try:
|
651 | 660 | a = numpy.array(array, dtype=dtype)
|
652 | 661 | except:
|
653 | 662 | pytest.skip("floating datat type is needed to store NaN")
|
654 | 663 | ia = dpnp.array(a)
|
| 664 | + |
655 | 665 | 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) |
658 | 668 | assert_dtype_allclose(result, expected)
|
659 | 669 |
|
660 | 670 | @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) |
665 | 673 | a[::3] = numpy.nan
|
666 | 674 | ia = dpnp.array(a)
|
667 | 675 |
|
668 |
| - expected = numpy.nanstd(a) |
669 |
| - result = dpnp.nanstd(ia) |
| 676 | + expected = getattr(numpy, self.func)(a) |
| 677 | + result = getattr(dpnp, self.func)(ia) |
670 | 678 | assert_dtype_allclose(result, expected)
|
671 | 679 |
|
672 | 680 | @pytest.mark.usefixtures("suppress_dof_numpy_warnings")
|
673 | 681 | @pytest.mark.parametrize("dtype", get_float_complex_dtypes())
|
674 | 682 | @pytest.mark.parametrize("axis", [None, 0, 1, 2, (0, 1), (1, 2)])
|
675 | 683 | @pytest.mark.parametrize("keepdims", [True, False])
|
676 | 684 | @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): |
678 | 686 | a = numpy.arange(4 * 3 * 5, dtype=dtype)
|
679 | 687 | a[::2] = numpy.nan
|
680 | 688 | a = a.reshape(4, 3, 5)
|
681 | 689 | ia = dpnp.array(a)
|
682 | 690 |
|
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 | + ) |
684 | 694 | if has_support_aspect64():
|
685 | 695 | res_dtype = expected.dtype
|
686 | 696 | else:
|
687 | 697 | res_dtype = dpnp.default_float_type(ia.device)
|
688 | 698 | out = dpnp.empty(expected.shape, dtype=res_dtype)
|
689 |
| - result = dpnp.nanstd( |
| 699 | + result = getattr(dpnp, self.func)( |
690 | 700 | ia, out=out, axis=axis, ddof=ddof, keepdims=keepdims
|
691 | 701 | )
|
692 | 702 | assert result is out
|
693 | 703 | assert_dtype_allclose(result, expected)
|
694 | 704 |
|
695 | 705 | @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) |
700 | 710 |
|
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]) |
703 | 713 | assert_dtype_allclose(result, expected)
|
704 | 714 |
|
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]) |
707 | 717 | assert_dtype_allclose(result, expected)
|
708 | 718 |
|
709 | 719 | @pytest.mark.usefixtures("suppress_complex_warning")
|
710 | 720 | @pytest.mark.parametrize("dt_in", get_float_complex_dtypes())
|
711 | 721 | @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): |
713 | 723 | a = numpy.arange(4 * 3 * 5, dtype=dt_in)
|
714 | 724 | a[::2] = numpy.nan
|
715 | 725 | a = a.reshape(4, 3, 5)
|
716 | 726 | ia = dpnp.array(a)
|
717 | 727 |
|
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) |
720 | 730 | assert_dtype_allclose(result, expected)
|
721 | 731 |
|
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): |
723 | 754 | ia = dpnp.arange(5, dtype=dpnp.float32)
|
724 | 755 | ia[0] = dpnp.nan
|
| 756 | + |
725 | 757 | # where keyword is not implemented
|
726 | 758 | 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) |
728 | 769 |
|
729 | 770 | # ddof should be an integer or float
|
730 | 771 | with pytest.raises(TypeError):
|
731 |
| - dpnp.nanstd(ia, ddof="1") |
| 772 | + getattr(dpnp, self.func)(ia, ddof="1") |
732 | 773 |
|
733 | 774 |
|
734 | 775 | class TestNanSum:
|
@@ -789,139 +830,3 @@ def test_nansum_strided(self, dtype):
|
789 | 830 | result = dpnp.nansum(dp_array[::2])
|
790 | 831 | expected = numpy.nansum(np_array[::2])
|
791 | 832 | 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