@@ -868,6 +868,92 @@ def test_ufunc_inplace_non_standard_dtype(self):
868868 a4 += u .Quantity (10 , u .mm , dtype = np .int64 )
869869
870870
871+ @pytest .mark .skipif (not hasattr (np .core .umath , 'clip' ),
872+ reason = 'no clip ufunc available' )
873+ class TestClip :
874+ """Test the clip ufunc.
875+
876+ In numpy, this is hidden behind a function that does not backwards
877+ compatibility checks. We explicitly test the ufunc here.
878+ """
879+ def setup (self ):
880+ self .clip = np .core .umath .clip
881+
882+ def test_clip_simple (self ):
883+ q = np .arange (- 1. , 10. ) * u .m
884+ q_min = 125 * u .cm
885+ q_max = 0.0055 * u .km
886+ result = self .clip (q , q_min , q_max )
887+ assert result .unit == q .unit
888+ expected = self .clip (q .value , q_min .to_value (q .unit ),
889+ q_max .to_value (q .unit )) * q .unit
890+ assert np .all (result == expected )
891+
892+ def test_clip_unitless_parts (self ):
893+ q = np .arange (- 1. , 10. ) * u .m
894+ qlim = 0.0055 * u .km
895+ # one-sided
896+ result1 = self .clip (q , - np .inf , qlim )
897+ expected1 = self .clip (q .value , - np .inf , qlim .to_value (q .unit )) * q .unit
898+ assert np .all (result1 == expected1 )
899+ result2 = self .clip (q , qlim , np .inf )
900+ expected2 = self .clip (q .value , qlim .to_value (q .unit ), np .inf ) * q .unit
901+ assert np .all (result2 == expected2 )
902+ # Zero
903+ result3 = self .clip (q , np .zeros (q .shape ), qlim )
904+ expected3 = self .clip (q .value , 0 , qlim .to_value (q .unit )) * q .unit
905+ assert np .all (result3 == expected3 )
906+ # Two unitless parts, array-shaped.
907+ result4 = self .clip (q , np .zeros (q .shape ), np .full (q .shape , np .inf ))
908+ expected4 = self .clip (q .value , 0 , np .inf ) * q .unit
909+ assert np .all (result4 == expected4 )
910+
911+ def test_clip_dimensionless (self ):
912+ q = np .arange (- 1. , 10. ) * u .dimensionless_unscaled
913+ result = self .clip (q , 200 * u .percent , 5. )
914+ expected = self .clip (q , 2. , 5. )
915+ assert result .unit == u .dimensionless_unscaled
916+ assert np .all (result == expected )
917+
918+ def test_clip_ndarray (self ):
919+ a = np .arange (- 1. , 10. )
920+ result = self .clip (a , 200 * u .percent , 5. * u .dimensionless_unscaled )
921+ assert isinstance (result , u .Quantity )
922+ expected = self .clip (a , 2. , 5. ) * u .dimensionless_unscaled
923+ assert np .all (result == expected )
924+
925+ def test_clip_quantity_inplace (self ):
926+ q = np .arange (- 1. , 10. ) * u .m
927+ q_min = 125 * u .cm
928+ q_max = 0.0055 * u .km
929+ expected = self .clip (q .value , q_min .to_value (q .unit ),
930+ q_max .to_value (q .unit )) * q .unit
931+ result = self .clip (q , q_min , q_max , out = q )
932+ assert result is q
933+ assert np .all (result == expected )
934+
935+ def test_clip_ndarray_dimensionless_output (self ):
936+ a = np .arange (- 1. , 10. )
937+ q = np .zeros_like (a ) * u .m
938+ expected = self .clip (a , 2. , 5. ) * u .dimensionless_unscaled
939+ result = self .clip (a , 200 * u .percent , 5. * u .dimensionless_unscaled ,
940+ out = q )
941+ assert result is q
942+ assert result .unit == u .dimensionless_unscaled
943+ assert np .all (result == expected )
944+
945+ def test_clip_errors (self ):
946+ q = np .arange (- 1. , 10. ) * u .m
947+ with pytest .raises (u .UnitsError ):
948+ self .clip (q , 0 , 1 * u .s )
949+ with pytest .raises (u .UnitsError ):
950+ self .clip (q .value , 0 , 1 * u .s )
951+ with pytest .raises (u .UnitsError ):
952+ self .clip (q , - 1 , 0. )
953+ with pytest .raises (u .UnitsError ):
954+ self .clip (q , 0. , 1. )
955+
956+
871957class TestUfuncAt :
872958 """Test that 'at' method for ufuncs (calculates in-place at given indices)
873959
0 commit comments