diff --git a/.github/workflows/numpy.yml b/.github/workflows/numpy.yml index 82420452..e3819ca4 100644 --- a/.github/workflows/numpy.yml +++ b/.github/workflows/numpy.yml @@ -11,7 +11,10 @@ jobs: python-version: [3.8, 3.9] steps: - - uses: actions/checkout@v1 + - name: Checkout array-api-tests + uses: actions/checkout@v1 + with: + submodules: 'true' - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 with: @@ -40,6 +43,30 @@ jobs: # waiting on NumPy to allow/revert distinct NaNs for np.unique # https://github.com/numpy/numpy/issues/20326#issuecomment-1012380448 array_api_tests/test_set_functions.py + # https://github.com/numpy/numpy/issues/21211 + array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -0 and x2_i is -0) -> -0] + # https://github.com/numpy/numpy/issues/21213 + array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] + array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] + # noted diversions from spec + array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] + array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] + array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] + array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] + array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] + array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] + array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] + array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] + array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] + array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] + array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] + array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] + array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] + array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] + array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] + array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] + array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] + array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] EOF diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..c225c24e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "array_api_tests/array-api"] + path = array-api + url = https://github.com/data-apis/array-api/ diff --git a/README.md b/README.md index 1d4ad770..9eebc397 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,15 @@ welcome! ### Setup +Currently we pin the Array API specification repo [`array-api`](https://github.com/data-apis/array-api/) +as a git submodule. This might change in the future to better support vendoring +use cases (see [#107](https://github.com/data-apis/array-api-tests/issues/107)), +but for now be sure submodules are pulled too, e.g. + +```bash +$ git submodule update --init +``` + To run the tests, install the testing dependencies. ```bash diff --git a/array-api b/array-api new file mode 160000 index 00000000..2b9c402e --- /dev/null +++ b/array-api @@ -0,0 +1 @@ +Subproject commit 2b9c402ebdb9825c2e8787caaabb5c5e3d9cf394 diff --git a/array_api_tests/meta/test_special_cases.py b/array_api_tests/meta/test_special_cases.py new file mode 100644 index 00000000..826e5969 --- /dev/null +++ b/array_api_tests/meta/test_special_cases.py @@ -0,0 +1,10 @@ +import math + +from ..test_special_cases import parse_result + + +def test_parse_result(): + check_result, _ = parse_result( + "an implementation-dependent approximation to ``+3π/4``" + ) + assert check_result(3 * math.pi / 4) diff --git a/array_api_tests/special_cases/__init__.py b/array_api_tests/special_cases/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/array_api_tests/special_cases/test_abs.py b/array_api_tests/special_cases/test_abs.py deleted file mode 100644 index 4ed04d02..00000000 --- a/array_api_tests/special_cases/test_abs.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -Special cases tests for abs. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import abs - -from hypothesis import given - - -@given(numeric_arrays) -def test_abs_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `abs(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = abs(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_abs_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `abs(x, /)`: - - - If `x_i` is `-0`, the result is `+0`. - - """ - res = abs(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_abs_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `abs(x, /)`: - - - If `x_i` is `-infinity`, the result is `+infinity`. - - """ - res = abs(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_acos.py b/array_api_tests/special_cases/test_acos.py deleted file mode 100644 index b1c3cb56..00000000 --- a/array_api_tests/special_cases/test_acos.py +++ /dev/null @@ -1,66 +0,0 @@ -""" -Special cases tests for acos. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, greater, less, one, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import acos - -from hypothesis import given - - -@given(numeric_arrays) -def test_acos_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `acos(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = acos(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_acos_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `acos(x, /)`: - - - If `x_i` is `1`, the result is `+0`. - - """ - res = acos(arg1) - mask = exactly_equal(arg1, one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_acos_special_cases_one_arg_greater(arg1): - """ - Special case test for `acos(x, /)`: - - - If `x_i` is greater than `1`, the result is `NaN`. - - """ - res = acos(arg1) - mask = greater(arg1, one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_acos_special_cases_one_arg_less(arg1): - """ - Special case test for `acos(x, /)`: - - - If `x_i` is less than `-1`, the result is `NaN`. - - """ - res = acos(arg1) - mask = less(arg1, -one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_acosh.py b/array_api_tests/special_cases/test_acosh.py deleted file mode 100644 index 8749eaf2..00000000 --- a/array_api_tests/special_cases/test_acosh.py +++ /dev/null @@ -1,66 +0,0 @@ -""" -Special cases tests for acosh. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, less, one, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import acosh - -from hypothesis import given - - -@given(numeric_arrays) -def test_acosh_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `acosh(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = acosh(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_acosh_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `acosh(x, /)`: - - - If `x_i` is `1`, the result is `+0`. - - """ - res = acosh(arg1) - mask = exactly_equal(arg1, one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_acosh_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `acosh(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = acosh(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_acosh_special_cases_one_arg_less(arg1): - """ - Special case test for `acosh(x, /)`: - - - If `x_i` is less than `1`, the result is `NaN`. - - """ - res = acosh(arg1) - mask = less(arg1, one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_add.py b/array_api_tests/special_cases/test_add.py deleted file mode 100644 index eaccb803..00000000 --- a/array_api_tests/special_cases/test_add.py +++ /dev/null @@ -1,226 +0,0 @@ -""" -Special cases tests for add. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, infinity, isfinite, - logical_and, logical_or, non_zero, zero) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import add - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = add(arg1, arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_1(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is `-infinity`, the result is `NaN`. - - """ - res = add(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_2(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is `+infinity`, the result is `NaN`. - - """ - res = add(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_3(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is `+infinity`, the result is `+infinity`. - - """ - res = add(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_4(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is `-infinity`, the result is `-infinity`. - - """ - res = add(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_5(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is a finite number, the result is `+infinity`. - - """ - res = add(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_6(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is a finite number, the result is `-infinity`. - - """ - res = add(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_7(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is a finite number and `x2_i` is `+infinity`, the result is `+infinity`. - - """ - res = add(arg1, arg2) - mask = logical_and(isfinite(arg1), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_8(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is a finite number and `x2_i` is `-infinity`, the result is `-infinity`. - - """ - res = add(arg1, arg2) - mask = logical_and(isfinite(arg1), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_9(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is `-0` and `x2_i` is `-0`, the result is `-0`. - - """ - res = add(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_10(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is `-0` and `x2_i` is `+0`, the result is `+0`. - - """ - res = add(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_11(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is `+0` and `x2_i` is `-0`, the result is `+0`. - - """ - res = add(arg1, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_12(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is `+0` and `x2_i` is `+0`, the result is `+0`. - - """ - res = add(arg1, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_13(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is a nonzero finite number and `x2_i` is `-x1_i`, the result is `+0`. - - """ - res = add(arg1, arg2) - mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), exactly_equal(arg2, -arg1)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_either__equal(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is either `+0` or `-0` and `x2_i` is a nonzero finite number, the result is `x2_i`. - - """ - res = add(arg1, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) - assert_exactly_equal(res[mask], (arg2)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__either(arg1, arg2): - """ - Special case test for `add(x1, x2, /)`: - - - If `x1_i` is a nonzero finite number and `x2_i` is either `+0` or `-0`, the result is `x1_i`. - - """ - res = add(arg1, arg2) - mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (arg1)[mask]) - -# TODO: Implement REMAINING test for: -# - In the remaining cases, when neither `infinity`, `+0`, `-0`, nor a `NaN` is involved, and the operands have the same mathematical sign or have different magnitudes, the sum must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported round mode. If the magnitude is too large to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test_asin.py b/array_api_tests/special_cases/test_asin.py deleted file mode 100644 index 0a41b716..00000000 --- a/array_api_tests/special_cases/test_asin.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Special cases tests for asin. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, greater, less, one, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import asin - -from hypothesis import given - - -@given(numeric_arrays) -def test_asin_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `asin(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = asin(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_asin_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `asin(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = asin(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_asin_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `asin(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = asin(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_asin_special_cases_one_arg_greater(arg1): - """ - Special case test for `asin(x, /)`: - - - If `x_i` is greater than `1`, the result is `NaN`. - - """ - res = asin(arg1) - mask = greater(arg1, one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_asin_special_cases_one_arg_less(arg1): - """ - Special case test for `asin(x, /)`: - - - If `x_i` is less than `-1`, the result is `NaN`. - - """ - res = asin(arg1) - mask = less(arg1, -one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_asinh.py b/array_api_tests/special_cases/test_asinh.py deleted file mode 100644 index a54d3346..00000000 --- a/array_api_tests/special_cases/test_asinh.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Special cases tests for asinh. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import asinh - -from hypothesis import given - - -@given(numeric_arrays) -def test_asinh_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `asinh(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = asinh(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_asinh_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `asinh(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = asinh(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_asinh_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `asinh(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = asinh(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_asinh_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `asinh(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = asinh(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_asinh_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `asinh(x, /)`: - - - If `x_i` is `-infinity`, the result is `-infinity`. - - """ - res = asinh(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_atan.py b/array_api_tests/special_cases/test_atan.py deleted file mode 100644 index 4b6936ed..00000000 --- a/array_api_tests/special_cases/test_atan.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Special cases tests for atan. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, zero, π -from ..hypothesis_helpers import numeric_arrays -from .._array_module import atan - -from hypothesis import given - - -@given(numeric_arrays) -def test_atan_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `atan(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = atan(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_atan_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `atan(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = atan(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_atan_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `atan(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = atan(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_atan_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `atan(x, /)`: - - - If `x_i` is `+infinity`, the result is an implementation-dependent approximation to `+π/2`. - - """ - res = atan(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (+π(arg1.shape, arg1.dtype)/2)[mask]) - - -@given(numeric_arrays) -def test_atan_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `atan(x, /)`: - - - If `x_i` is `-infinity`, the result is an implementation-dependent approximation to `-π/2`. - - """ - res = atan(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-π(arg1.shape, arg1.dtype)/2)[mask]) diff --git a/array_api_tests/special_cases/test_atan2.py b/array_api_tests/special_cases/test_atan2.py deleted file mode 100644 index 9d7452e7..00000000 --- a/array_api_tests/special_cases/test_atan2.py +++ /dev/null @@ -1,314 +0,0 @@ -""" -Special cases tests for atan2. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, greater, infinity, isfinite, - less, logical_and, logical_or, zero, π) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import atan2 - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = atan2(arg1, arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_greater__equal_1(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is greater than `0` and `x2_i` is `+0`, the result is an implementation-dependent approximation to `+π/2`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (+π(arg1.shape, arg1.dtype)/2)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_greater__equal_2(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is greater than `0` and `x2_i` is `-0`, the result is an implementation-dependent approximation to `+π/2`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (+π(arg1.shape, arg1.dtype)/2)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__greater_1(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__greater_2(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `-0` and `x2_i` is greater than `0`, the result is `-0`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__equal_1(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `+0` and `x2_i` is `+0`, the result is `+0`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__equal_2(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `+0` and `x2_i` is `-0`, the result is an implementation-dependent approximation to `+π`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (+π(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__equal_3(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `-0` and `x2_i` is `+0`, the result is `-0`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__equal_4(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `-0` and `x2_i` is `-0`, the result is an implementation-dependent approximation to `-π`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-π(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__equal_5(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is finite, the result is an implementation-dependent approximation to `+π/2`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) - assert_exactly_equal(res[mask], (+π(arg1.shape, arg1.dtype)/2)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__equal_6(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is finite, the result is an implementation-dependent approximation to `-π/2`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) - assert_exactly_equal(res[mask], (-π(arg1.shape, arg1.dtype)/2)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__equal_7(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is `+infinity`, the result is an implementation-dependent approximation to `+π/4`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (+π(arg1.shape, arg1.dtype)/4)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__equal_8(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is `-infinity`, the result is an implementation-dependent approximation to `+3π/4`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (+3*π(arg1.shape, arg1.dtype)/4)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__equal_9(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is `+infinity`, the result is an implementation-dependent approximation to `-π/4`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-π(arg1.shape, arg1.dtype)/4)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__equal_10(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is `-infinity`, the result is an implementation-dependent approximation to `-3π/4`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-3*π(arg1.shape, arg1.dtype)/4)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__less_1(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is an implementation-dependent approximation to `+π`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (+π(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_equal__less_2(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is `-0` and `x2_i` is less than `0`, the result is an implementation-dependent approximation to `-π`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-π(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_less__equal_1(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is less than `0` and `x2_i` is `+0`, the result is an implementation-dependent approximation to `-π/2`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-π(arg1.shape, arg1.dtype)/2)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_less__equal_2(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is less than `0` and `x2_i` is `-0`, the result is an implementation-dependent approximation to `-π/2`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-π(arg1.shape, arg1.dtype)/2)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_greater_equal__equal_1(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is greater than `0`, `x1_i` is a finite number, and `x2_i` is `+infinity`, the result is `+0`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), isfinite(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_greater_equal__equal_2(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is greater than `0`, `x1_i` is a finite number, and `x2_i` is `-infinity`, the result is an implementation-dependent approximation to `+π`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), isfinite(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (+π(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_less_equal__equal_1(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is less than `0`, `x1_i` is a finite number, and `x2_i` is `+infinity`, the result is `-0`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), isfinite(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_atan2_special_cases_two_args_less_equal__equal_2(arg1, arg2): - """ - Special case test for `atan2(x1, x2, /)`: - - - If `x1_i` is less than `0`, `x1_i` is a finite number, and `x2_i` is `-infinity`, the result is an implementation-dependent approximation to `-π`. - - """ - res = atan2(arg1, arg2) - mask = logical_and(logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), isfinite(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-π(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_atanh.py b/array_api_tests/special_cases/test_atanh.py deleted file mode 100644 index 6e26cc99..00000000 --- a/array_api_tests/special_cases/test_atanh.py +++ /dev/null @@ -1,106 +0,0 @@ -""" -Special cases tests for atanh. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, greater, infinity, less, one, - zero) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import atanh - -from hypothesis import given - - -@given(numeric_arrays) -def test_atanh_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `atanh(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = atanh(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_atanh_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `atanh(x, /)`: - - - If `x_i` is `-1`, the result is `-infinity`. - - """ - res = atanh(arg1) - mask = exactly_equal(arg1, -one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_atanh_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `atanh(x, /)`: - - - If `x_i` is `+1`, the result is `+infinity`. - - """ - res = atanh(arg1) - mask = exactly_equal(arg1, one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_atanh_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `atanh(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = atanh(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_atanh_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `atanh(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = atanh(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_atanh_special_cases_one_arg_less(arg1): - """ - Special case test for `atanh(x, /)`: - - - If `x_i` is less than `-1`, the result is `NaN`. - - """ - res = atanh(arg1) - mask = less(arg1, -one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_atanh_special_cases_one_arg_greater(arg1): - """ - Special case test for `atanh(x, /)`: - - - If `x_i` is greater than `1`, the result is `NaN`. - - """ - res = atanh(arg1) - mask = greater(arg1, one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_ceil.py b/array_api_tests/special_cases/test_ceil.py deleted file mode 100644 index 5c9eee86..00000000 --- a/array_api_tests/special_cases/test_ceil.py +++ /dev/null @@ -1,92 +0,0 @@ -""" -Special cases tests for ceil. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, isintegral, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import ceil - -from hypothesis import given - - -@given(numeric_arrays) -def test_ceil_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `ceil(x, /)`: - - - If `x_i` is already integer-valued, the result is `x_i`. - - """ - res = ceil(arg1) - mask = isintegral(arg1) - assert_exactly_equal(res[mask], (arg1)[mask]) - - -@given(numeric_arrays) -def test_ceil_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `ceil(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = ceil(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_ceil_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `ceil(x, /)`: - - - If `x_i` is `-infinity`, the result is `-infinity`. - - """ - res = ceil(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_ceil_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `ceil(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = ceil(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_ceil_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `ceil(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = ceil(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_ceil_special_cases_one_arg_equal_6(arg1): - """ - Special case test for `ceil(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = ceil(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_cos.py b/array_api_tests/special_cases/test_cos.py deleted file mode 100644 index e80a7130..00000000 --- a/array_api_tests/special_cases/test_cos.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Special cases tests for cos. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, one, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import cos - -from hypothesis import given - - -@given(numeric_arrays) -def test_cos_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `cos(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = cos(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_cos_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `cos(x, /)`: - - - If `x_i` is `+0`, the result is `1`. - - """ - res = cos(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_cos_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `cos(x, /)`: - - - If `x_i` is `-0`, the result is `1`. - - """ - res = cos(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_cos_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `cos(x, /)`: - - - If `x_i` is `+infinity`, the result is `NaN`. - - """ - res = cos(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_cos_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `cos(x, /)`: - - - If `x_i` is `-infinity`, the result is `NaN`. - - """ - res = cos(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_cosh.py b/array_api_tests/special_cases/test_cosh.py deleted file mode 100644 index bdca4a82..00000000 --- a/array_api_tests/special_cases/test_cosh.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Special cases tests for cosh. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, one, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import cosh - -from hypothesis import given - - -@given(numeric_arrays) -def test_cosh_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `cosh(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = cosh(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_cosh_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `cosh(x, /)`: - - - If `x_i` is `+0`, the result is `1`. - - """ - res = cosh(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_cosh_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `cosh(x, /)`: - - - If `x_i` is `-0`, the result is `1`. - - """ - res = cosh(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_cosh_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `cosh(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = cosh(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_cosh_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `cosh(x, /)`: - - - If `x_i` is `-infinity`, the result is `+infinity`. - - """ - res = cosh(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_divide.py b/array_api_tests/special_cases/test_divide.py deleted file mode 100644 index fe1596c9..00000000 --- a/array_api_tests/special_cases/test_divide.py +++ /dev/null @@ -1,293 +0,0 @@ -""" -Special cases tests for divide. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, assert_negative_mathematical_sign, - assert_positive_mathematical_sign, exactly_equal, greater, infinity, - isfinite, isnegative, ispositive, less, logical_and, logical_not, - logical_or, non_zero, same_sign, zero) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import divide - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = divide(arg1, arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_either__either_1(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. - - """ - res = divide(arg1, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_either__either_2(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+0` or `-0`, the result is `NaN`. - - """ - res = divide(arg1, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__greater_1(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. - - """ - res = divide(arg1, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__greater_2(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is `-0` and `x2_i` is greater than `0`, the result is `-0`. - - """ - res = divide(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__less_1(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `-0`. - - """ - res = divide(arg1, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__less_2(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is `-0` and `x2_i` is less than `0`, the result is `+0`. - - """ - res = divide(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_greater__equal_1(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is greater than `0` and `x2_i` is `+0`, the result is `+infinity`. - - """ - res = divide(arg1, arg2) - mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_greater__equal_2(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is greater than `0` and `x2_i` is `-0`, the result is `-infinity`. - - """ - res = divide(arg1, arg2) - mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_less__equal_1(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is less than `0` and `x2_i` is `+0`, the result is `-infinity`. - - """ - res = divide(arg1, arg2) - mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_less__equal_2(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is less than `0` and `x2_i` is `-0`, the result is `+infinity`. - - """ - res = divide(arg1, arg2) - mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__equal_1(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `+infinity`. - - """ - res = divide(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__equal_2(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `-infinity`. - - """ - res = divide(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__equal_3(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `-infinity`. - - """ - res = divide(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__equal_4(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `+infinity`. - - """ - res = divide(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__equal_5(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `+infinity`, the result is `+0`. - - """ - res = divide(arg1, arg2) - mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__equal_6(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `-infinity`, the result is `-0`. - - """ - res = divide(arg1, arg2) - mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__equal_7(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `+infinity`, the result is `-0`. - - """ - res = divide(arg1, arg2) - mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_equal__equal_8(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `-infinity`, the result is `+0`. - - """ - res = divide(arg1, arg2) - mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_same_sign_both(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` and `x2_i` have the same mathematical sign and are both nonzero finite numbers, the result has a positive mathematical sign. - - """ - res = divide(arg1, arg2) - mask = logical_and(same_sign(arg1, arg2), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) - assert_positive_mathematical_sign(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_divide_special_cases_two_args_different_signs_both(arg1, arg2): - """ - Special case test for `divide(x1, x2, /)`: - - - If `x1_i` and `x2_i` have different mathematical signs and are both nonzero finite numbers, the result has a negative mathematical sign. - - """ - res = divide(arg1, arg2) - mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) - assert_negative_mathematical_sign(res[mask]) - -# TODO: Implement REMAINING test for: -# - In the remaining cases, where neither `-infinity`, `+0`, `-0`, nor `NaN` is involved, the quotient must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too larger to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test_dunder_abs.py b/array_api_tests/special_cases/test_dunder_abs.py deleted file mode 100644 index 5028f1b7..00000000 --- a/array_api_tests/special_cases/test_dunder_abs.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -Special cases tests for __abs__. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, zero -from ..hypothesis_helpers import numeric_arrays - -from hypothesis import given - - -@given(numeric_arrays) -def test_abs_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `__abs__(self, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = (arg1).__abs__() - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_abs_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `__abs__(self, /)`: - - - If `x_i` is `-0`, the result is `+0`. - - """ - res = (arg1).__abs__() - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_abs_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `__abs__(self, /)`: - - - If `x_i` is `-infinity`, the result is `+infinity`. - - """ - res = (arg1).__abs__() - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_dunder_add.py b/array_api_tests/special_cases/test_dunder_add.py deleted file mode 100644 index d3b5e169..00000000 --- a/array_api_tests/special_cases/test_dunder_add.py +++ /dev/null @@ -1,225 +0,0 @@ -""" -Special cases tests for __add__. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, infinity, isfinite, - logical_and, logical_or, non_zero, zero) -from ..hypothesis_helpers import numeric_arrays - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = arg1.__add__(arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_1(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is `-infinity`, the result is `NaN`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_2(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is `+infinity`, the result is `NaN`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_3(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is `+infinity`, the result is `+infinity`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_4(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is `-infinity`, the result is `-infinity`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_5(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is a finite number, the result is `+infinity`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_6(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is a finite number, the result is `-infinity`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_7(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is a finite number and `x2_i` is `+infinity`, the result is `+infinity`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(isfinite(arg1), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_8(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is a finite number and `x2_i` is `-infinity`, the result is `-infinity`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(isfinite(arg1), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_9(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is `-0` and `x2_i` is `-0`, the result is `-0`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_10(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is `-0` and `x2_i` is `+0`, the result is `+0`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_11(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is `-0`, the result is `+0`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_12(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is `+0`, the result is `+0`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__equal_13(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is a nonzero finite number and `x2_i` is `-x1_i`, the result is `+0`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), exactly_equal(arg2, -arg1)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_either__equal(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is either `+0` or `-0` and `x2_i` is a nonzero finite number, the result is `x2_i`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) - assert_exactly_equal(res[mask], (arg2)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_add_special_cases_two_args_equal__either(arg1, arg2): - """ - Special case test for `__add__(self, other, /)`: - - - If `x1_i` is a nonzero finite number and `x2_i` is either `+0` or `-0`, the result is `x1_i`. - - """ - res = arg1.__add__(arg2) - mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (arg1)[mask]) - -# TODO: Implement REMAINING test for: -# - In the remaining cases, when neither `infinity`, `+0`, `-0`, nor a `NaN` is involved, and the operands have the same mathematical sign or have different magnitudes, the sum must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported round mode. If the magnitude is too large to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test_dunder_iadd.py b/array_api_tests/special_cases/test_dunder_iadd.py deleted file mode 100644 index 692877bf..00000000 --- a/array_api_tests/special_cases/test_dunder_iadd.py +++ /dev/null @@ -1,243 +0,0 @@ -""" -Special cases tests for __iadd__. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from operator import iadd - -from ..array_helpers import (NaN, asarray, assert_exactly_equal, exactly_equal, infinity, isfinite, - logical_and, logical_or, non_zero, zero) -from ..hypothesis_helpers import numeric_arrays - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_1(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is `-infinity`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_2(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is `+infinity`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_3(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is `+infinity`, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_4(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is `-infinity`, the result is `-infinity`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_5(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is a finite number, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_6(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is a finite number, the result is `-infinity`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_7(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is a finite number and `x2_i` is `+infinity`, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(isfinite(arg1), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_8(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is a finite number and `x2_i` is `-infinity`, the result is `-infinity`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(isfinite(arg1), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_9(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is `-0` and `x2_i` is `-0`, the result is `-0`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_10(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is `-0` and `x2_i` is `+0`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_11(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is `-0`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_12(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is `+0`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__equal_13(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is a nonzero finite number and `x2_i` is `-x1_i`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), exactly_equal(arg2, -arg1)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_either__equal(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is either `+0` or `-0` and `x2_i` is a nonzero finite number, the result is `x2_i`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) - assert_exactly_equal(res[mask], (arg2)[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_iadd_special_cases_two_args_equal__either(arg1, arg2): - """ - Special case test for `__iadd__(self, other, /)`: - - - If `x1_i` is a nonzero finite number and `x2_i` is either `+0` or `-0`, the result is `x1_i`. - - """ - res = asarray(arg1, copy=True) - iadd(res, arg2) - mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (arg1)[mask]) - -# TODO: Implement REMAINING test for: -# - In the remaining cases, when neither `infinity`, `+0`, `-0`, nor a `NaN` is involved, and the operands have the same mathematical sign or have different magnitudes, the sum must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported round mode. If the magnitude is too large to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test_dunder_imul.py b/array_api_tests/special_cases/test_dunder_imul.py deleted file mode 100644 index a077fb9a..00000000 --- a/array_api_tests/special_cases/test_dunder_imul.py +++ /dev/null @@ -1,133 +0,0 @@ -""" -Special cases tests for __imul__. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from operator import imul - -from ..array_helpers import (NaN, asarray, assert_exactly_equal, assert_isinf, - assert_negative_mathematical_sign, assert_positive_mathematical_sign, - exactly_equal, infinity, isfinite, logical_and, logical_not, - logical_or, non_zero, same_sign, zero) -from ..hypothesis_helpers import numeric_arrays - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_imul_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `__imul__(self, other, /)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - imul(res, arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_imul_special_cases_two_args_either__either_1(arg1, arg2): - """ - Special case test for `__imul__(self, other, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+0` or `-0`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - imul(res, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_imul_special_cases_two_args_either__either_2(arg1, arg2): - """ - Special case test for `__imul__(self, other, /)`: - - - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - imul(res, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_imul_special_cases_two_args_either__either_3(arg1, arg2): - """ - Special case test for `__imul__(self, other, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. - - """ - res = asarray(arg1, copy=True) - imul(res, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_isinf(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_imul_special_cases_two_args_same_sign_except(arg1, arg2): - """ - Special case test for `__imul__(self, other, /)`: - - - If `x1_i` and `x2_i` have the same mathematical sign, the result has a positive mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. - - """ - res = asarray(arg1, copy=True) - imul(res, arg2) - mask = logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) - assert_positive_mathematical_sign(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_imul_special_cases_two_args_different_signs_except(arg1, arg2): - """ - Special case test for `__imul__(self, other, /)`: - - - If `x1_i` and `x2_i` have different mathematical signs, the result has a negative mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. - - """ - res = asarray(arg1, copy=True) - imul(res, arg2) - mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) - assert_negative_mathematical_sign(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_imul_special_cases_two_args_either__equal(arg1, arg2): - """ - Special case test for `__imul__(self, other, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is a nonzero finite number, the result is a signed infinity with the mathematical sign determined by the rule already stated above. - - """ - res = asarray(arg1, copy=True) - imul(res, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) - assert_isinf(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_imul_special_cases_two_args_equal__either(arg1, arg2): - """ - Special case test for `__imul__(self, other, /)`: - - - If `x1_i` is a nonzero finite number and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. - - """ - res = asarray(arg1, copy=True) - imul(res, arg2) - mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_isinf(res[mask]) - -# TODO: Implement REMAINING test for: -# - In the remaining cases, where neither `infinity` nor `NaN` is involved, the product must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too large to represent, the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the result is a zero of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test_dunder_ipow.py b/array_api_tests/special_cases/test_dunder_ipow.py deleted file mode 100644 index 0ca5e705..00000000 --- a/array_api_tests/special_cases/test_dunder_ipow.py +++ /dev/null @@ -1,353 +0,0 @@ -""" -Special cases tests for __ipow__. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from operator import ipow - -from ..array_helpers import (NaN, asarray, assert_exactly_equal, exactly_equal, greater, infinity, - isfinite, isintegral, isodd, less, logical_and, logical_not, notequal, - one, zero) -from ..hypothesis_helpers import numeric_arrays - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_notequal__equal(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is not equal to `1` and `x2_i` is `NaN`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(logical_not(exactly_equal(arg1, one(arg1.shape, arg1.dtype))), exactly_equal(arg2, NaN(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_even_if_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x2_i` is `+0`, the result is `1`, even if `x1_i` is `NaN`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = exactly_equal(arg2, zero(arg2.shape, arg2.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_even_if_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x2_i` is `-0`, the result is `1`, even if `x1_i` is `NaN`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__notequal_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `NaN` and `x2_i` is not equal to `0`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), notequal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__notequal_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `1` and `x2_i` is not `NaN`, the result is `1`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, one(arg1.shape, arg1.dtype)), logical_not(exactly_equal(arg2, NaN(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_absgreater__equal_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `abs(x1_i)` is greater than `1` and `x2_i` is `+infinity`, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_absgreater__equal_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `abs(x1_i)` is greater than `1` and `x2_i` is `-infinity`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_absequal__equal_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `abs(x1_i)` is `1` and `x2_i` is `+infinity`, the result is `1`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_absequal__equal_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `abs(x1_i)` is `1` and `x2_i` is `-infinity`, the result is `1`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_absless__equal_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `abs(x1_i)` is less than `1` and `x2_i` is `+infinity`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_absless__equal_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `abs(x1_i)` is less than `1` and `x2_i` is `-infinity`, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__greater_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is greater than `0`, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__greater_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__less_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is less than `0`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__less_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__greater_equal_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__greater_equal_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-0`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__greater_notequal_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__greater_notequal_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__less_equal_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-0`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__less_equal_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__less_notequal_1(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_equal__less_notequal_2(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_ipow_special_cases_two_args_less_equal__equal_notequal(arg1, arg2): - """ - Special case test for `__ipow__(self, other, /)`: - - - If `x1_i` is less than `0`, `x1_i` is a finite number, `x2_i` is a finite number, and `x2_i` is not an integer value, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - ipow(res, arg2) - mask = logical_and(logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), isfinite(arg1)), logical_and(isfinite(arg2), logical_not(isintegral(arg2)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_dunder_itruediv.py b/array_api_tests/special_cases/test_dunder_itruediv.py deleted file mode 100644 index e6747d40..00000000 --- a/array_api_tests/special_cases/test_dunder_itruediv.py +++ /dev/null @@ -1,315 +0,0 @@ -""" -Special cases tests for __itruediv__. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from operator import itruediv - -from ..array_helpers import (NaN, asarray, assert_exactly_equal, assert_negative_mathematical_sign, - assert_positive_mathematical_sign, exactly_equal, greater, infinity, - isfinite, isnegative, ispositive, less, logical_and, logical_not, - logical_or, non_zero, same_sign, zero) -from ..hypothesis_helpers import numeric_arrays - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_either__either_1(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_either__either_2(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+0` or `-0`, the result is `NaN`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__greater_1(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__greater_2(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is `-0` and `x2_i` is greater than `0`, the result is `-0`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__less_1(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `-0`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__less_2(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is `-0` and `x2_i` is less than `0`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_greater__equal_1(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is greater than `0` and `x2_i` is `+0`, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_greater__equal_2(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is greater than `0` and `x2_i` is `-0`, the result is `-infinity`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_less__equal_1(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is less than `0` and `x2_i` is `+0`, the result is `-infinity`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_less__equal_2(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is less than `0` and `x2_i` is `-0`, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__equal_1(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__equal_2(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `-infinity`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__equal_3(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `-infinity`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__equal_4(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `+infinity`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__equal_5(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `+infinity`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__equal_6(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `-infinity`, the result is `-0`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__equal_7(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `+infinity`, the result is `-0`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_equal__equal_8(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `-infinity`, the result is `+0`. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_same_sign_both(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` and `x2_i` have the same mathematical sign and are both nonzero finite numbers, the result has a positive mathematical sign. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(same_sign(arg1, arg2), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) - assert_positive_mathematical_sign(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_itruediv_special_cases_two_args_different_signs_both(arg1, arg2): - """ - Special case test for `__itruediv__(self, other, /)`: - - - If `x1_i` and `x2_i` have different mathematical signs and are both nonzero finite numbers, the result has a negative mathematical sign. - - """ - res = asarray(arg1, copy=True) - itruediv(res, arg2) - mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) - assert_negative_mathematical_sign(res[mask]) - -# TODO: Implement REMAINING test for: -# - In the remaining cases, where neither `-infinity`, `+0`, `-0`, nor `NaN` is involved, the quotient must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too larger to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test_dunder_mul.py b/array_api_tests/special_cases/test_dunder_mul.py deleted file mode 100644 index 983f3654..00000000 --- a/array_api_tests/special_cases/test_dunder_mul.py +++ /dev/null @@ -1,123 +0,0 @@ -""" -Special cases tests for __mul__. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, assert_isinf, - assert_negative_mathematical_sign, assert_positive_mathematical_sign, - exactly_equal, infinity, isfinite, logical_and, logical_not, - logical_or, non_zero, same_sign, zero) -from ..hypothesis_helpers import numeric_arrays - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_mul_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `__mul__(self, other, /)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = arg1.__mul__(arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_mul_special_cases_two_args_either__either_1(arg1, arg2): - """ - Special case test for `__mul__(self, other, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+0` or `-0`, the result is `NaN`. - - """ - res = arg1.__mul__(arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_mul_special_cases_two_args_either__either_2(arg1, arg2): - """ - Special case test for `__mul__(self, other, /)`: - - - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. - - """ - res = arg1.__mul__(arg2) - mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_mul_special_cases_two_args_either__either_3(arg1, arg2): - """ - Special case test for `__mul__(self, other, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. - - """ - res = arg1.__mul__(arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_isinf(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_mul_special_cases_two_args_same_sign_except(arg1, arg2): - """ - Special case test for `__mul__(self, other, /)`: - - - If `x1_i` and `x2_i` have the same mathematical sign, the result has a positive mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. - - """ - res = arg1.__mul__(arg2) - mask = logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) - assert_positive_mathematical_sign(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_mul_special_cases_two_args_different_signs_except(arg1, arg2): - """ - Special case test for `__mul__(self, other, /)`: - - - If `x1_i` and `x2_i` have different mathematical signs, the result has a negative mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. - - """ - res = arg1.__mul__(arg2) - mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) - assert_negative_mathematical_sign(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_mul_special_cases_two_args_either__equal(arg1, arg2): - """ - Special case test for `__mul__(self, other, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is a nonzero finite number, the result is a signed infinity with the mathematical sign determined by the rule already stated above. - - """ - res = arg1.__mul__(arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) - assert_isinf(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_mul_special_cases_two_args_equal__either(arg1, arg2): - """ - Special case test for `__mul__(self, other, /)`: - - - If `x1_i` is a nonzero finite number and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. - - """ - res = arg1.__mul__(arg2) - mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_isinf(res[mask]) - -# TODO: Implement REMAINING test for: -# - In the remaining cases, where neither `infinity` nor `NaN` is involved, the product must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too large to represent, the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the result is a zero of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test_dunder_pow.py b/array_api_tests/special_cases/test_dunder_pow.py deleted file mode 100644 index b90abd4c..00000000 --- a/array_api_tests/special_cases/test_dunder_pow.py +++ /dev/null @@ -1,326 +0,0 @@ -""" -Special cases tests for __pow__. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, greater, infinity, isfinite, - isintegral, isodd, less, logical_and, logical_not, notequal, one, zero) -from ..hypothesis_helpers import numeric_arrays - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_notequal__equal(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is not equal to `1` and `x2_i` is `NaN`, the result is `NaN`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(logical_not(exactly_equal(arg1, one(arg1.shape, arg1.dtype))), exactly_equal(arg2, NaN(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_even_if_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x2_i` is `+0`, the result is `1`, even if `x1_i` is `NaN`. - - """ - res = arg1.__pow__(arg2) - mask = exactly_equal(arg2, zero(arg2.shape, arg2.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_even_if_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x2_i` is `-0`, the result is `1`, even if `x1_i` is `NaN`. - - """ - res = arg1.__pow__(arg2) - mask = exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__notequal_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `NaN` and `x2_i` is not equal to `0`, the result is `NaN`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), notequal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__notequal_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `1` and `x2_i` is not `NaN`, the result is `1`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, one(arg1.shape, arg1.dtype)), logical_not(exactly_equal(arg2, NaN(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absgreater__equal_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `abs(x1_i)` is greater than `1` and `x2_i` is `+infinity`, the result is `+infinity`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absgreater__equal_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `abs(x1_i)` is greater than `1` and `x2_i` is `-infinity`, the result is `+0`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absequal__equal_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `abs(x1_i)` is `1` and `x2_i` is `+infinity`, the result is `1`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absequal__equal_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `abs(x1_i)` is `1` and `x2_i` is `-infinity`, the result is `1`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absless__equal_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `abs(x1_i)` is less than `1` and `x2_i` is `+infinity`, the result is `+0`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absless__equal_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `abs(x1_i)` is less than `1` and `x2_i` is `-infinity`, the result is `+infinity`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is greater than `0`, the result is `+infinity`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is less than `0`, the result is `+0`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `+infinity`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_equal_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_equal_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-0`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_notequal_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_notequal_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+0`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_equal_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-0`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_equal_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_notequal_1(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+0`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_notequal_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_less_equal__equal_notequal(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is less than `0`, `x1_i` is a finite number, `x2_i` is a finite number, and `x2_i` is not an integer value, the result is `NaN`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), isfinite(arg1)), logical_and(isfinite(arg2), logical_not(isintegral(arg2)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_dunder_truediv.py b/array_api_tests/special_cases/test_dunder_truediv.py deleted file mode 100644 index d08302f2..00000000 --- a/array_api_tests/special_cases/test_dunder_truediv.py +++ /dev/null @@ -1,292 +0,0 @@ -""" -Special cases tests for __truediv__. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, assert_negative_mathematical_sign, - assert_positive_mathematical_sign, exactly_equal, greater, infinity, - isfinite, isnegative, ispositive, less, logical_and, logical_not, - logical_or, non_zero, same_sign, zero) -from ..hypothesis_helpers import numeric_arrays - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_either__either_1(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_either__either_2(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+0` or `-0`, the result is `NaN`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__greater_1(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__greater_2(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is `-0` and `x2_i` is greater than `0`, the result is `-0`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__less_1(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `-0`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__less_2(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is `-0` and `x2_i` is less than `0`, the result is `+0`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_greater__equal_1(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is greater than `0` and `x2_i` is `+0`, the result is `+infinity`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_greater__equal_2(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is greater than `0` and `x2_i` is `-0`, the result is `-infinity`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_less__equal_1(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is less than `0` and `x2_i` is `+0`, the result is `-infinity`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_less__equal_2(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is less than `0` and `x2_i` is `-0`, the result is `+infinity`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__equal_1(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `+infinity`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__equal_2(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `-infinity`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__equal_3(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `-infinity`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__equal_4(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `+infinity`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__equal_5(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `+infinity`, the result is `+0`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__equal_6(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `-infinity`, the result is `-0`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__equal_7(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `+infinity`, the result is `-0`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_equal__equal_8(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `-infinity`, the result is `+0`. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_same_sign_both(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` and `x2_i` have the same mathematical sign and are both nonzero finite numbers, the result has a positive mathematical sign. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(same_sign(arg1, arg2), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) - assert_positive_mathematical_sign(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_truediv_special_cases_two_args_different_signs_both(arg1, arg2): - """ - Special case test for `__truediv__(self, other, /)`: - - - If `x1_i` and `x2_i` have different mathematical signs and are both nonzero finite numbers, the result has a negative mathematical sign. - - """ - res = arg1.__truediv__(arg2) - mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) - assert_negative_mathematical_sign(res[mask]) - -# TODO: Implement REMAINING test for: -# - In the remaining cases, where neither `-infinity`, `+0`, `-0`, nor `NaN` is involved, the quotient must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too larger to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test_exp.py b/array_api_tests/special_cases/test_exp.py deleted file mode 100644 index 47399648..00000000 --- a/array_api_tests/special_cases/test_exp.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Special cases tests for exp. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, one, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import exp - -from hypothesis import given - - -@given(numeric_arrays) -def test_exp_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `exp(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = exp(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_exp_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `exp(x, /)`: - - - If `x_i` is `+0`, the result is `1`. - - """ - res = exp(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_exp_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `exp(x, /)`: - - - If `x_i` is `-0`, the result is `1`. - - """ - res = exp(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_exp_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `exp(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = exp(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_exp_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `exp(x, /)`: - - - If `x_i` is `-infinity`, the result is `+0`. - - """ - res = exp(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_expm1.py b/array_api_tests/special_cases/test_expm1.py deleted file mode 100644 index d96b742e..00000000 --- a/array_api_tests/special_cases/test_expm1.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Special cases tests for expm1. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, one, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import expm1 - -from hypothesis import given - - -@given(numeric_arrays) -def test_expm1_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `expm1(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = expm1(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_expm1_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `expm1(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = expm1(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_expm1_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `expm1(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = expm1(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_expm1_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `expm1(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = expm1(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_expm1_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `expm1(x, /)`: - - - If `x_i` is `-infinity`, the result is `-1`. - - """ - res = expm1(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-one(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_floor.py b/array_api_tests/special_cases/test_floor.py deleted file mode 100644 index bf7a1572..00000000 --- a/array_api_tests/special_cases/test_floor.py +++ /dev/null @@ -1,92 +0,0 @@ -""" -Special cases tests for floor. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, isintegral, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import floor - -from hypothesis import given - - -@given(numeric_arrays) -def test_floor_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `floor(x, /)`: - - - If `x_i` is already integer-valued, the result is `x_i`. - - """ - res = floor(arg1) - mask = isintegral(arg1) - assert_exactly_equal(res[mask], (arg1)[mask]) - - -@given(numeric_arrays) -def test_floor_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `floor(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = floor(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_floor_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `floor(x, /)`: - - - If `x_i` is `-infinity`, the result is `-infinity`. - - """ - res = floor(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_floor_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `floor(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = floor(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_floor_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `floor(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = floor(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_floor_special_cases_one_arg_equal_6(arg1): - """ - Special case test for `floor(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = floor(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_log.py b/array_api_tests/special_cases/test_log.py deleted file mode 100644 index 0ea6cd25..00000000 --- a/array_api_tests/special_cases/test_log.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -Special cases tests for log. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, infinity, less, logical_or, - one, zero) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import log - -from hypothesis import given - - -@given(numeric_arrays) -def test_log_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `log(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = log(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `log(x, /)`: - - - If `x_i` is `1`, the result is `+0`. - - """ - res = log(arg1) - mask = exactly_equal(arg1, one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `log(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = log(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log_special_cases_one_arg_less(arg1): - """ - Special case test for `log(x, /)`: - - - If `x_i` is less than `0`, the result is `NaN`. - - """ - res = log(arg1) - mask = less(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log_special_cases_one_arg_either(arg1): - """ - Special case test for `log(x, /)`: - - - If `x_i` is either `+0` or `-0`, the result is `-infinity`. - - """ - res = log(arg1) - mask = logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_log10.py b/array_api_tests/special_cases/test_log10.py deleted file mode 100644 index 8dc5a5de..00000000 --- a/array_api_tests/special_cases/test_log10.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -Special cases tests for log10. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, infinity, less, logical_or, - one, zero) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import log10 - -from hypothesis import given - - -@given(numeric_arrays) -def test_log10_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `log10(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = log10(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log10_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `log10(x, /)`: - - - If `x_i` is `1`, the result is `+0`. - - """ - res = log10(arg1) - mask = exactly_equal(arg1, one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log10_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `log10(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = log10(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log10_special_cases_one_arg_less(arg1): - """ - Special case test for `log10(x, /)`: - - - If `x_i` is less than `0`, the result is `NaN`. - - """ - res = log10(arg1) - mask = less(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log10_special_cases_one_arg_either(arg1): - """ - Special case test for `log10(x, /)`: - - - If `x_i` is either `+0` or `-0`, the result is `-infinity`. - - """ - res = log10(arg1) - mask = logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_log1p.py b/array_api_tests/special_cases/test_log1p.py deleted file mode 100644 index 432a761b..00000000 --- a/array_api_tests/special_cases/test_log1p.py +++ /dev/null @@ -1,92 +0,0 @@ -""" -Special cases tests for log1p. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, less, one, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import log1p - -from hypothesis import given - - -@given(numeric_arrays) -def test_log1p_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `log1p(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = log1p(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log1p_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `log1p(x, /)`: - - - If `x_i` is `-1`, the result is `-infinity`. - - """ - res = log1p(arg1) - mask = exactly_equal(arg1, -one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log1p_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `log1p(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = log1p(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log1p_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `log1p(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = log1p(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log1p_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `log1p(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = log1p(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log1p_special_cases_one_arg_less(arg1): - """ - Special case test for `log1p(x, /)`: - - - If `x_i` is less than `-1`, the result is `NaN`. - - """ - res = log1p(arg1) - mask = less(arg1, -one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_log2.py b/array_api_tests/special_cases/test_log2.py deleted file mode 100644 index 41797dd7..00000000 --- a/array_api_tests/special_cases/test_log2.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -Special cases tests for log2. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, infinity, less, logical_or, - one, zero) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import log2 - -from hypothesis import given - - -@given(numeric_arrays) -def test_log2_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `log2(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = log2(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log2_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `log2(x, /)`: - - - If `x_i` is `1`, the result is `+0`. - - """ - res = log2(arg1) - mask = exactly_equal(arg1, one(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log2_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `log2(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = log2(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log2_special_cases_one_arg_less(arg1): - """ - Special case test for `log2(x, /)`: - - - If `x_i` is less than `0`, the result is `NaN`. - - """ - res = log2(arg1) - mask = less(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_log2_special_cases_one_arg_either(arg1): - """ - Special case test for `log2(x, /)`: - - - If `x_i` is either `+0` or `-0`, the result is `-infinity`. - - """ - res = log2(arg1) - mask = logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_logaddexp.py b/array_api_tests/special_cases/test_logaddexp.py deleted file mode 100644 index de8081e7..00000000 --- a/array_api_tests/special_cases/test_logaddexp.py +++ /dev/null @@ -1,54 +0,0 @@ -""" -Special cases tests for logaddexp. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, infinity, logical_and, - logical_not, logical_or) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import logaddexp - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_logaddexp_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `logaddexp(x1, x2)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = logaddexp(arg1, arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_logaddexp_special_cases_two_args_equal__notequal(arg1, arg2): - """ - Special case test for `logaddexp(x1, x2)`: - - - If `x1_i` is `+infinity` and `x2_i` is not `NaN`, the result is `+infinity`. - - """ - res = logaddexp(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_not(exactly_equal(arg2, NaN(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_logaddexp_special_cases_two_args_notequal__equal(arg1, arg2): - """ - Special case test for `logaddexp(x1, x2)`: - - - If `x1_i` is not `NaN` and `x2_i` is `+infinity`, the result is `+infinity`. - - """ - res = logaddexp(arg1, arg2) - mask = logical_and(logical_not(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype))), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_multiply.py b/array_api_tests/special_cases/test_multiply.py deleted file mode 100644 index 0ab2eec0..00000000 --- a/array_api_tests/special_cases/test_multiply.py +++ /dev/null @@ -1,124 +0,0 @@ -""" -Special cases tests for multiply. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, assert_isinf, - assert_negative_mathematical_sign, assert_positive_mathematical_sign, - exactly_equal, infinity, isfinite, logical_and, logical_not, - logical_or, non_zero, same_sign, zero) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import multiply - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_multiply_special_cases_two_args_either(arg1, arg2): - """ - Special case test for `multiply(x1, x2, /)`: - - - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. - - """ - res = multiply(arg1, arg2) - mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_multiply_special_cases_two_args_either__either_1(arg1, arg2): - """ - Special case test for `multiply(x1, x2, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+0` or `-0`, the result is `NaN`. - - """ - res = multiply(arg1, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_multiply_special_cases_two_args_either__either_2(arg1, arg2): - """ - Special case test for `multiply(x1, x2, /)`: - - - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. - - """ - res = multiply(arg1, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_multiply_special_cases_two_args_either__either_3(arg1, arg2): - """ - Special case test for `multiply(x1, x2, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. - - """ - res = multiply(arg1, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_isinf(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_multiply_special_cases_two_args_same_sign_except(arg1, arg2): - """ - Special case test for `multiply(x1, x2, /)`: - - - If `x1_i` and `x2_i` have the same mathematical sign, the result has a positive mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. - - """ - res = multiply(arg1, arg2) - mask = logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) - assert_positive_mathematical_sign(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_multiply_special_cases_two_args_different_signs_except(arg1, arg2): - """ - Special case test for `multiply(x1, x2, /)`: - - - If `x1_i` and `x2_i` have different mathematical signs, the result has a negative mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. - - """ - res = multiply(arg1, arg2) - mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) - assert_negative_mathematical_sign(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_multiply_special_cases_two_args_either__equal(arg1, arg2): - """ - Special case test for `multiply(x1, x2, /)`: - - - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is a nonzero finite number, the result is a signed infinity with the mathematical sign determined by the rule already stated above. - - """ - res = multiply(arg1, arg2) - mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) - assert_isinf(res[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_multiply_special_cases_two_args_equal__either(arg1, arg2): - """ - Special case test for `multiply(x1, x2, /)`: - - - If `x1_i` is a nonzero finite number and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. - - """ - res = multiply(arg1, arg2) - mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) - assert_isinf(res[mask]) - -# TODO: Implement REMAINING test for: -# - In the remaining cases, where neither `infinity` nor `NaN` is involved, the product must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too large to represent, the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the result is a zero of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test_pow.py b/array_api_tests/special_cases/test_pow.py deleted file mode 100644 index a422ffd3..00000000 --- a/array_api_tests/special_cases/test_pow.py +++ /dev/null @@ -1,327 +0,0 @@ -""" -Special cases tests for pow. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, greater, infinity, isfinite, - isintegral, isodd, less, logical_and, logical_not, notequal, one, zero) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import pow - -from hypothesis import given - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_notequal__equal(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is not equal to `1` and `x2_i` is `NaN`, the result is `NaN`. - - """ - res = pow(arg1, arg2) - mask = logical_and(logical_not(exactly_equal(arg1, one(arg1.shape, arg1.dtype))), exactly_equal(arg2, NaN(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_even_if_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x2_i` is `+0`, the result is `1`, even if `x1_i` is `NaN`. - - """ - res = pow(arg1, arg2) - mask = exactly_equal(arg2, zero(arg2.shape, arg2.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_even_if_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x2_i` is `-0`, the result is `1`, even if `x1_i` is `NaN`. - - """ - res = pow(arg1, arg2) - mask = exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__notequal_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `NaN` and `x2_i` is not equal to `0`, the result is `NaN`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), notequal(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__notequal_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `1` and `x2_i` is not `NaN`, the result is `1`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, one(arg1.shape, arg1.dtype)), logical_not(exactly_equal(arg2, NaN(arg2.shape, arg2.dtype)))) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absgreater__equal_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `abs(x1_i)` is greater than `1` and `x2_i` is `+infinity`, the result is `+infinity`. - - """ - res = pow(arg1, arg2) - mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absgreater__equal_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `abs(x1_i)` is greater than `1` and `x2_i` is `-infinity`, the result is `+0`. - - """ - res = pow(arg1, arg2) - mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absequal__equal_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `abs(x1_i)` is `1` and `x2_i` is `+infinity`, the result is `1`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absequal__equal_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `abs(x1_i)` is `1` and `x2_i` is `-infinity`, the result is `1`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absless__equal_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `abs(x1_i)` is less than `1` and `x2_i` is `+infinity`, the result is `+0`. - - """ - res = pow(arg1, arg2) - mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_absless__equal_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `abs(x1_i)` is less than `1` and `x2_i` is `-infinity`, the result is `+infinity`. - - """ - res = pow(arg1, arg2) - mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is greater than `0`, the result is `+infinity`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `+infinity` and `x2_i` is less than `0`, the result is `+0`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `+infinity`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_equal_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_equal_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-0`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_notequal_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__greater_notequal_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+0`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_equal_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-0`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_equal_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_notequal_1(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+0`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_equal__less_notequal_2(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. - - """ - res = pow(arg1, arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test_pow_special_cases_two_args_less_equal__equal_notequal(arg1, arg2): - """ - Special case test for `pow(x1, x2, /)`: - - - If `x1_i` is less than `0`, `x1_i` is a finite number, `x2_i` is a finite number, and `x2_i` is not an integer value, the result is `NaN`. - - """ - res = pow(arg1, arg2) - mask = logical_and(logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), isfinite(arg1)), logical_and(isfinite(arg2), logical_not(isintegral(arg2)))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_round.py b/array_api_tests/special_cases/test_round.py deleted file mode 100644 index 13dc2d99..00000000 --- a/array_api_tests/special_cases/test_round.py +++ /dev/null @@ -1,108 +0,0 @@ -""" -Special cases tests for round. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (NaN, assert_exactly_equal, assert_iseven, assert_positive, ceil, equal, - exactly_equal, floor, infinity, isintegral, logical_and, not_equal, - one, subtract, zero) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import round - -from hypothesis import given - - -@given(numeric_arrays) -def test_round_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `round(x, /)`: - - - If `x_i` is already integer-valued, the result is `x_i`. - - """ - res = round(arg1) - mask = isintegral(arg1) - assert_exactly_equal(res[mask], (arg1)[mask]) - - -@given(numeric_arrays) -def test_round_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `round(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = round(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_round_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `round(x, /)`: - - - If `x_i` is `-infinity`, the result is `-infinity`. - - """ - res = round(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_round_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `round(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = round(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_round_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `round(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = round(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_round_special_cases_one_arg_equal_6(arg1): - """ - Special case test for `round(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = round(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_round_special_cases_one_arg_two_integers_equally_close(arg1): - """ - Special case test for `round(x, /)`: - - - If two integers are equally close to `x_i`, the result is the even integer closest to `x_i`. - - """ - res = round(arg1) - mask = logical_and(not_equal(floor(arg1), ceil(arg1)), equal(subtract(arg1, floor(arg1)), subtract(ceil(arg1), arg1))) - assert_iseven(res[mask]) - assert_positive(subtract(one(arg1[mask].shape, arg1[mask].dtype), abs(subtract(arg1[mask], res[mask])))) diff --git a/array_api_tests/special_cases/test_sign.py b/array_api_tests/special_cases/test_sign.py deleted file mode 100644 index e2ac6630..00000000 --- a/array_api_tests/special_cases/test_sign.py +++ /dev/null @@ -1,54 +0,0 @@ -""" -Special cases tests for sign. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import (assert_exactly_equal, exactly_equal, greater, less, logical_or, one, - zero) -from ..hypothesis_helpers import numeric_arrays -from .._array_module import sign - -from hypothesis import given - - -@given(numeric_arrays) -def test_sign_special_cases_one_arg_less(arg1): - """ - Special case test for `sign(x, /)`: - - - If `x_i` is less than `0`, the result is `-1`. - - """ - res = sign(arg1) - mask = less(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sign_special_cases_one_arg_either(arg1): - """ - Special case test for `sign(x, /)`: - - - If `x_i` is either `-0` or `+0`, the result is `0`. - - """ - res = sign(arg1) - mask = logical_or(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, zero(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sign_special_cases_one_arg_greater(arg1): - """ - Special case test for `sign(x, /)`: - - - If `x_i` is greater than `0`, the result is `+1`. - - """ - res = sign(arg1) - mask = greater(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_sin.py b/array_api_tests/special_cases/test_sin.py deleted file mode 100644 index 4af01736..00000000 --- a/array_api_tests/special_cases/test_sin.py +++ /dev/null @@ -1,66 +0,0 @@ -""" -Special cases tests for sin. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, logical_or, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import sin - -from hypothesis import given - - -@given(numeric_arrays) -def test_sin_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `sin(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = sin(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sin_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `sin(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = sin(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sin_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `sin(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = sin(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sin_special_cases_one_arg_either(arg1): - """ - Special case test for `sin(x, /)`: - - - If `x_i` is either `+infinity` or `-infinity`, the result is `NaN`. - - """ - res = sin(arg1) - mask = logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_sinh.py b/array_api_tests/special_cases/test_sinh.py deleted file mode 100644 index 4d2ff217..00000000 --- a/array_api_tests/special_cases/test_sinh.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Special cases tests for sinh. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import sinh - -from hypothesis import given - - -@given(numeric_arrays) -def test_sinh_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `sinh(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = sinh(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sinh_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `sinh(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = sinh(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sinh_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `sinh(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = sinh(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sinh_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `sinh(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = sinh(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sinh_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `sinh(x, /)`: - - - If `x_i` is `-infinity`, the result is `-infinity`. - - """ - res = sinh(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_sqrt.py b/array_api_tests/special_cases/test_sqrt.py deleted file mode 100644 index 18244755..00000000 --- a/array_api_tests/special_cases/test_sqrt.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Special cases tests for sqrt. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, less, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import sqrt - -from hypothesis import given - - -@given(numeric_arrays) -def test_sqrt_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `sqrt(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = sqrt(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sqrt_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `sqrt(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = sqrt(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sqrt_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `sqrt(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = sqrt(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sqrt_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `sqrt(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = sqrt(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_sqrt_special_cases_one_arg_less(arg1): - """ - Special case test for `sqrt(x, /)`: - - - If `x_i` is less than `0`, the result is `NaN`. - - """ - res = sqrt(arg1) - mask = less(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_tan.py b/array_api_tests/special_cases/test_tan.py deleted file mode 100644 index ec09878d..00000000 --- a/array_api_tests/special_cases/test_tan.py +++ /dev/null @@ -1,66 +0,0 @@ -""" -Special cases tests for tan. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, logical_or, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import tan - -from hypothesis import given - - -@given(numeric_arrays) -def test_tan_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `tan(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = tan(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_tan_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `tan(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = tan(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_tan_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `tan(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = tan(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_tan_special_cases_one_arg_either(arg1): - """ - Special case test for `tan(x, /)`: - - - If `x_i` is either `+infinity` or `-infinity`, the result is `NaN`. - - """ - res = tan(arg1) - mask = logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_tanh.py b/array_api_tests/special_cases/test_tanh.py deleted file mode 100644 index 91304c2f..00000000 --- a/array_api_tests/special_cases/test_tanh.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Special cases tests for tanh. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, one, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import tanh - -from hypothesis import given - - -@given(numeric_arrays) -def test_tanh_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `tanh(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = tanh(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_tanh_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `tanh(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = tanh(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_tanh_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `tanh(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = tanh(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_tanh_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `tanh(x, /)`: - - - If `x_i` is `+infinity`, the result is `+1`. - - """ - res = tanh(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_tanh_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `tanh(x, /)`: - - - If `x_i` is `-infinity`, the result is `-1`. - - """ - res = tanh(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-one(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_trunc.py b/array_api_tests/special_cases/test_trunc.py deleted file mode 100644 index 6ee7d402..00000000 --- a/array_api_tests/special_cases/test_trunc.py +++ /dev/null @@ -1,92 +0,0 @@ -""" -Special cases tests for trunc. - -These tests are generated from the special cases listed in the spec. - -NOTE: This file is generated automatically by the generate_stubs.py script. Do -not modify it directly. -""" - -from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, isintegral, zero -from ..hypothesis_helpers import numeric_arrays -from .._array_module import trunc - -from hypothesis import given - - -@given(numeric_arrays) -def test_trunc_special_cases_one_arg_equal_1(arg1): - """ - Special case test for `trunc(x, /)`: - - - If `x_i` is already integer-valued, the result is `x_i`. - - """ - res = trunc(arg1) - mask = isintegral(arg1) - assert_exactly_equal(res[mask], (arg1)[mask]) - - -@given(numeric_arrays) -def test_trunc_special_cases_one_arg_equal_2(arg1): - """ - Special case test for `trunc(x, /)`: - - - If `x_i` is `+infinity`, the result is `+infinity`. - - """ - res = trunc(arg1) - mask = exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_trunc_special_cases_one_arg_equal_3(arg1): - """ - Special case test for `trunc(x, /)`: - - - If `x_i` is `-infinity`, the result is `-infinity`. - - """ - res = trunc(arg1) - mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_trunc_special_cases_one_arg_equal_4(arg1): - """ - Special case test for `trunc(x, /)`: - - - If `x_i` is `+0`, the result is `+0`. - - """ - res = trunc(arg1) - mask = exactly_equal(arg1, zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_trunc_special_cases_one_arg_equal_5(arg1): - """ - Special case test for `trunc(x, /)`: - - - If `x_i` is `-0`, the result is `-0`. - - """ - res = trunc(arg1) - mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays) -def test_trunc_special_cases_one_arg_equal_6(arg1): - """ - Special case test for `trunc(x, /)`: - - - If `x_i` is `NaN`, the result is `NaN`. - - """ - res = trunc(arg1) - mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) - assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/stubs.py b/array_api_tests/stubs.py new file mode 100644 index 00000000..15fb7646 --- /dev/null +++ b/array_api_tests/stubs.py @@ -0,0 +1,44 @@ +import sys +from importlib import import_module +from importlib.util import find_spec +from pathlib import Path +from types import FunctionType, ModuleType +from typing import Dict, List + +__all__ = ["category_to_funcs", "array", "extension_to_funcs"] + + +spec_dir = Path(__file__).parent.parent / "array-api" / "spec" / "API_specification" +assert spec_dir.exists(), f"{spec_dir} not found - try `git submodule update --init`" +sigs_dir = spec_dir / "signatures" +assert sigs_dir.exists() + +spec_abs_path: str = str(spec_dir.resolve()) +sys.path.append(spec_abs_path) +assert find_spec("signatures") is not None + +name_to_mod: Dict[str, ModuleType] = {} +for path in sigs_dir.glob("*.py"): + name = path.name.replace(".py", "") + name_to_mod[name] = import_module(f"signatures.{name}") + + +category_to_funcs: Dict[str, List[FunctionType]] = {} +for name, mod in name_to_mod.items(): + if name.endswith("_functions"): + category = name.replace("_functions", "") + objects = [getattr(mod, name) for name in mod.__all__] + assert all(isinstance(o, FunctionType) for o in objects) + category_to_funcs[category] = objects + + +array = name_to_mod["array_object"].array + + +EXTENSIONS = ["linalg"] +extension_to_funcs: Dict[str, List[FunctionType]] = {} +for ext in EXTENSIONS: + mod = name_to_mod[ext] + objects = [getattr(mod, name) for name in mod.__all__] + assert all(isinstance(o, FunctionType) for o in objects) + extension_to_funcs[ext] = objects diff --git a/array_api_tests/test_special_cases.py b/array_api_tests/test_special_cases.py new file mode 100644 index 00000000..b8979298 --- /dev/null +++ b/array_api_tests/test_special_cases.py @@ -0,0 +1,1345 @@ +# We use __future__ for forward reference type hints - this will work for even py3.8.0 +# See https://stackoverflow.com/a/33533514/5193926 +from __future__ import annotations + +import inspect +import math +import operator +import re +from dataclasses import dataclass, field +from decimal import ROUND_HALF_EVEN, Decimal +from enum import Enum, auto +from typing import Any, Callable, Dict, List, Optional, Protocol, Tuple +from warnings import warn + +import pytest +from hypothesis import assume, given, note +from hypothesis import strategies as st + +from array_api_tests.typing import Array, DataType + +from . import dtype_helpers as dh +from . import hypothesis_helpers as hh +from . import pytest_helpers as ph +from . import shape_helpers as sh +from . import xps +from ._array_module import mod as xp +from .stubs import category_to_funcs +from .test_operators_and_elementwise_functions import ( + oneway_broadcastable_shapes, + oneway_promotable_dtypes, +) + +pytestmark = pytest.mark.ci + +# The special case test casess are built on runtime via the parametrized +# test_unary and test_binary functions. Most of this file consists of utility +# classes and functions, all bought together to create the test cases (pytest +# params), to finally be run through the general test logic of either test_unary +# or test_binary. + + +UnaryCheck = Callable[[float], bool] +BinaryCheck = Callable[[float, float], bool] + + +def make_strict_eq(v: float) -> UnaryCheck: + if math.isnan(v): + return math.isnan + if v == 0: + if ph.is_pos_zero(v): + return ph.is_pos_zero + else: + return ph.is_neg_zero + + def strict_eq(i: float) -> bool: + return i == v + + return strict_eq + + +def make_strict_neq(v: float) -> UnaryCheck: + strict_eq = make_strict_eq(v) + + def strict_neq(i: float) -> bool: + return not strict_eq(i) + + return strict_neq + + +def make_rough_eq(v: float) -> UnaryCheck: + assert math.isfinite(v) # sanity check + + def rough_eq(i: float) -> bool: + return math.isclose(i, v, abs_tol=0.01) + + return rough_eq + + +def make_gt(v: float) -> UnaryCheck: + assert not math.isnan(v) # sanity check + + def gt(i: float) -> bool: + return i > v + + return gt + + +def make_lt(v: float) -> UnaryCheck: + assert not math.isnan(v) # sanity check + + def lt(i: float) -> bool: + return i < v + + return lt + + +def make_or(cond1: UnaryCheck, cond2: UnaryCheck) -> UnaryCheck: + def or_(i: float) -> bool: + return cond1(i) or cond2(i) + + return or_ + + +def make_and(cond1: UnaryCheck, cond2: UnaryCheck) -> UnaryCheck: + def and_(i: float) -> bool: + return cond1(i) or cond2(i) + + return and_ + + +def make_not_cond(cond: UnaryCheck) -> UnaryCheck: + def not_cond(i: float) -> bool: + return not cond(i) + + return not_cond + + +def absify_cond(cond: UnaryCheck) -> UnaryCheck: + def abs_cond(i: float) -> bool: + return cond(abs(i)) + + return abs_cond + + +repr_to_value = { + "NaN": float("nan"), + "infinity": float("inf"), + "0": 0.0, + "1": 1.0, +} +r_value = re.compile(r"([+-]?)(.+)") +r_pi = re.compile(r"(\d?)π(?:/(\d))?") + + +@dataclass +class ParseError(ValueError): + value: str + + +def parse_value(value_str: str) -> float: + """ + Parses a value string to return a float, e.g. + + >>> parse_value('1') + 1. + >>> parse_value('-infinity') + -float('inf') + >>> parse_value('3π/4') + 2.356194490192345 + + """ + m = r_value.match(value_str) + if m is None: + raise ParseError(value_str) + if pi_m := r_pi.match(m.group(2)): + value = math.pi + if numerator := pi_m.group(1): + value *= int(numerator) + if denominator := pi_m.group(2): + value /= int(denominator) + else: + value = repr_to_value[m.group(2)] + if sign := m.group(1): + if sign == "-": + value *= -1 + return value + + +r_code = re.compile(r"``([^\s]+)``") +r_approx_value = re.compile( + rf"an implementation-dependent approximation to {r_code.pattern}" +) + + +def parse_inline_code(inline_code: str) -> float: + """ + Parses a Sphinx code string to return a float, e.g. + + >>> parse_value('``0``') + 0. + >>> parse_value('``NaN``') + float('nan') + + """ + if m := r_code.match(inline_code): + return parse_value(m.group(1)) + else: + raise ParseError(inline_code) + + +r_not = re.compile("not (.+)") +r_equal_to = re.compile(f"equal to {r_code.pattern}") +r_array_element = re.compile(r"``([+-]?)x([12])_i``") +r_either_code = re.compile(f"either {r_code.pattern} or {r_code.pattern}") +r_gt = re.compile(f"greater than {r_code.pattern}") +r_lt = re.compile(f"less than {r_code.pattern}") + + +class FromDtypeFunc(Protocol): + """ + Type hint for functions that return an elements strategy for arrays of the + given dtype, e.g. xps.from_dtype(). + """ + + def __call__(self, dtype: DataType, **kw) -> st.SearchStrategy[float]: + ... + + +@dataclass +class BoundFromDtype(FromDtypeFunc): + """ + A xps.from_dtype()-like callable with bounded kwargs, filters and base function. + + We can bound: + + 1. Keyword arguments that xps.from_dtype() can use, e.g. + + >>> from_dtype = BoundFromDtype(kwargs={'min_value': 0, 'allow_infinity': False}) + >>> strategy = from_dtype(xp.float64) + + is equivalent to + + >>> strategy = xps.from_dtype(xp.float64, min_value=0, allow_infinity=False) + + i.e. a strategy that generates finite floats above 0 + + 2. Functions that filter the elements strategy that xps.from_dtype() returns, e.g. + + >>> from_dtype = BoundFromDtype(filter=lambda i: i != 0) + >>> strategy = from_dtype(xp.float64) + + is equivalent to + + >>> strategy = xps.from_dtype(xp.float64).filter(lambda i: i != 0) + + i.e. a strategy that generates any float except +0 and -0 + + 3. The underlying function that returns an elements strategy from a dtype, e.g. + + >>> from_dtype = BoundFromDtype( + ... from_dtype=lambda d: st.integers( + ... math.ceil(xp.finfo(d).min), math.floor(xp.finfo(d).max) + ... ) + ... ) + >>> strategy = from_dtype(xp.float64) + + is equivalent to + + >>> strategy = st.integers( + ... math.ceil(xp.finfo(xp.float64).min), math.floor(xp.finfo(xp.float64).max) + ... ) + + i.e. a strategy that generates integers (within the dtype's range) + + This is useful to avoid translating special case conditions into either a + dict, filter or "base func", and instead allows us to generalise these three + components into a callable equivalent of xps.from_dtype(). + + Additionally, BoundFromDtype instances can be added together. This allows us + to keep parsing each condition individually - so we don't need to duplicate + complicated parsing code - as ultimately we can represent (and subsequently + test for) special cases which have more than one condition per array, e.g. + + "If x1_i is greater than 0 and x1_i is not 42, ..." + + could be translated as + + >>> gt_0_from_dtype = BoundFromDtype(kwargs={'min_value': 0}) + >>> not_42_from_dtype = BoundFromDtype(filter=lambda i: i != 42) + >>> gt_0_from_dtype + not_42_from_dtype + BoundFromDtype(kwargs={'min_value': 0}, filter=(i)) + + """ + + kwargs: Dict[str, Any] = field(default_factory=dict) + filter_: Optional[Callable[[Array], bool]] = None + base_func: Optional[FromDtypeFunc] = None + + def __call__(self, dtype: DataType, **kw) -> st.SearchStrategy[float]: + assert len(kw) == 0 # sanity check + from_dtype = self.base_func or xps.from_dtype + strat = from_dtype(dtype, **self.kwargs) + if self.filter_ is not None: + strat = strat.filter(self.filter_) + return strat + + def __add__(self, other: BoundFromDtype) -> BoundFromDtype: + for k in self.kwargs.keys(): + if k in other.kwargs.keys(): + assert self.kwargs[k] == other.kwargs[k] # sanity check + kwargs = {**self.kwargs, **other.kwargs} + + if self.filter_ is not None and other.filter_ is not None: + filter_ = lambda i: self.filter_(i) and other.filter_(i) + else: + if self.filter_ is not None: + filter_ = self.filter_ + elif other.filter_ is not None: + filter_ = other.filter_ + else: + filter_ = None + + # sanity check + assert not (self.base_func is not None and other.base_func is not None) + if self.base_func is not None: + base_func = self.base_func + elif other.base_func is not None: + base_func = other.base_func + else: + base_func = None + + return BoundFromDtype(kwargs, filter_, base_func) + + +def wrap_strat_as_from_dtype(strat: st.SearchStrategy[float]) -> FromDtypeFunc: + """ + Wraps an elements strategy as a xps.from_dtype()-like function + """ + + def from_dtype(dtype: DataType, **kw) -> st.SearchStrategy[float]: + assert len(kw) == 0 # sanity check + return strat + + return from_dtype + + +def parse_cond(cond_str: str) -> Tuple[UnaryCheck, str, BoundFromDtype]: + """ + Parses a Sphinx-formatted condition string to return: + + 1. A function which takes an input and returns True if it meets the + condition, otherwise False. + 2. A string template for expressing the condition. + 3. A xps.from_dtype()-like function which returns a strategy that generates + elements that meet the condition. + + e.g. + + >>> cond, expr_template, from_dtype = parse_cond('greater than ``0``') + >>> cond(42) + True + >>> cond(-123) + False + >>> expr_template.replace('{}', 'x_i') + 'x_i > 0' + >>> strategy = from_dtype(xp.float64) + >>> for _ in range(5): + ... print(strategy.example()) + 1. + 0.1 + 1.7976931348623155e+179 + inf + 124.978 + + """ + # We first identify whether the condition starts with "not". If so, we note + # this but parse the condition as if it was not negated. + if m := r_not.match(cond_str): + cond_str = m.group(1) + not_cond = True + else: + not_cond = False + + # We parse the condition to identify the condition function, expression + # template, and xps.from_dtype()-like condition strategy. + kwargs = {} + filter_ = None + from_dtype = None # type: ignore + if m := r_code.match(cond_str): + value = parse_value(m.group(1)) + cond = make_strict_eq(value) + expr_template = "{} is " + m.group(1) + from_dtype = wrap_strat_as_from_dtype(st.just(value)) + elif m := r_either_code.match(cond_str): + v1 = parse_value(m.group(1)) + v2 = parse_value(m.group(2)) + cond = make_or(make_strict_eq(v1), make_strict_eq(v2)) + expr_template = "({} is " + m.group(1) + " or {} == " + m.group(2) + ")" + from_dtype = wrap_strat_as_from_dtype(st.sampled_from([v1, v2])) + elif m := r_equal_to.match(cond_str): + value = parse_value(m.group(1)) + if math.isnan(value): + raise ParseError(cond_str) + cond = lambda i: i == value + expr_template = "{} == " + m.group(1) + elif m := r_gt.match(cond_str): + value = parse_value(m.group(1)) + cond = make_gt(value) + expr_template = "{} > " + m.group(1) + kwargs = {"min_value": value, "exclude_min": True} + elif m := r_lt.match(cond_str): + value = parse_value(m.group(1)) + cond = make_lt(value) + expr_template = "{} < " + m.group(1) + kwargs = {"max_value": value, "exclude_max": True} + elif cond_str in ["finite", "a finite number"]: + cond = math.isfinite + expr_template = "isfinite({})" + kwargs = {"allow_nan": False, "allow_infinity": False} + elif cond_str in "a positive (i.e., greater than ``0``) finite number": + cond = lambda i: math.isfinite(i) and i > 0 + expr_template = "isfinite({}) and {} > 0" + kwargs = { + "allow_nan": False, + "allow_infinity": False, + "min_value": 0, + "exclude_min": True, + } + elif cond_str == "a negative (i.e., less than ``0``) finite number": + cond = lambda i: math.isfinite(i) and i < 0 + expr_template = "isfinite({}) and {} < 0" + kwargs = { + "allow_nan": False, + "allow_infinity": False, + "max_value": 0, + "exclude_max": True, + } + elif cond_str == "positive": + cond = lambda i: math.copysign(1, i) == 1 + expr_template = "copysign(1, {}) == 1" + # We assume (positive) zero is special cased seperately + kwargs = {"min_value": 0, "exclude_min": True} + elif cond_str == "negative": + cond = lambda i: math.copysign(1, i) == -1 + expr_template = "copysign(1, {}) == -1" + # We assume (negative) zero is special cased seperately + kwargs = {"max_value": 0, "exclude_max": True} + elif "nonzero finite" in cond_str: + cond = lambda i: math.isfinite(i) and i != 0 + expr_template = "isfinite({}) and {} != 0" + kwargs = {"allow_nan": False, "allow_infinity": False} + filter_ = lambda n: n != 0 + elif cond_str == "an integer value": + cond = lambda i: i.is_integer() + expr_template = "{}.is_integer()" + from_dtype = integers_from_dtype # type: ignore + elif cond_str == "an odd integer value": + cond = lambda i: i.is_integer() and i % 2 == 1 + expr_template = "{}.is_integer() and {} % 2 == 1" + if not_cond: + expr_template = f"({expr_template})" + + def from_dtype(dtype: DataType, **kw) -> st.SearchStrategy[float]: + return integers_from_dtype(dtype, **kw).filter(lambda n: n % 2 == 1) + + else: + raise ParseError(cond_str) + + if not_cond: + # We handle negated conitions by simply negating the condition function + # and using it as a filter for xps.from_dtype() (or an equivalent). + cond = make_not_cond(cond) + expr_template = f"not {expr_template}" + filter_ = cond + return cond, expr_template, BoundFromDtype(filter_=filter_) + else: + return cond, expr_template, BoundFromDtype(kwargs, filter_, from_dtype) + + +def parse_result(result_str: str) -> Tuple[UnaryCheck, str]: + """ + Parses a Sphinx-formatted result string to return: + + 1. A function which takes an input and returns True if it is the expected + result (or meets the condition of the expected result), otherwise False. + 2. A string that expresses the result. + + e.g. + + >>> check_result, expr = parse_result('``42``') + >>> check_result(7) + False + >>> check_result(42) + True + >>> expr + '42' + + """ + if m := r_code.match(result_str): + value = parse_value(m.group(1)) + check_result = make_strict_eq(value) # type: ignore + expr = m.group(1) + elif m := r_approx_value.match(result_str): + value = parse_value(m.group(1)) + check_result = make_rough_eq(value) # type: ignore + repr_ = m.group(1).replace("π", "pi") # for pytest param names + expr = f"roughly {repr_}" + elif "positive" in result_str: + + def check_result(result: float) -> bool: + if math.isnan(result): + # The sign of NaN is out-of-scope + return True + return math.copysign(1, result) == 1 + + expr = "positive sign" + elif "negative" in result_str: + + def check_result(result: float) -> bool: + if math.isnan(result): + # The sign of NaN is out-of-scope + return True + return math.copysign(1, result) == -1 + + expr = "negative sign" + else: + raise ParseError(result_str) + + return check_result, expr + + +class Case(Protocol): + cond_expr: str + result_expr: str + + def cond(self, *args) -> bool: + ... + + def check_result(self, *args) -> bool: + ... + + def __str__(self) -> str: + return f"{self.cond_expr} -> {self.result_expr}" + + def __repr__(self) -> str: + return f"{self.__class__.__name__}(<{self}>)" + + +class UnaryCond(Protocol): + def __call__(self, i: float) -> bool: + ... + + +class UnaryResultCheck(Protocol): + def __call__(self, i: float, result: float) -> bool: + ... + + +@dataclass(repr=False) +class UnaryCase(Case): + cond_expr: str + result_expr: str + cond_from_dtype: FromDtypeFunc + cond: UnaryCheck + check_result: UnaryResultCheck + + +r_unary_case = re.compile("If ``x_i`` is (.+), the result is (.+)") +r_even_round_halves_case = re.compile( + "If two integers are equally close to ``x_i``, " + "the result is the even integer closest to ``x_i``" +) + + +def trailing_halves_from_dtype(dtype: DataType) -> st.SearchStrategy[float]: + """ + Returns a strategy that generates floats that end with .5 and are within the + bounds of dtype. + """ + # We bound our base integers strategy to a range of values which should be + # able to represent a decimal 5 when .5 is added or subtracted. + if dtype == xp.float32: + abs_max = 10**4 + else: + abs_max = 10**16 + return st.sampled_from([0.5, -0.5]).flatmap( + lambda half: st.integers(-abs_max, abs_max).map(lambda n: n + half) + ) + + +even_round_halves_case = UnaryCase( + cond_expr="modf(i)[0] == 0.5", + cond=lambda i: math.modf(i)[0] == 0.5, + cond_from_dtype=trailing_halves_from_dtype, + result_expr="Decimal(i).to_integral_exact(ROUND_HALF_EVEN)", + check_result=lambda i, result: ( + result == float(Decimal(i).to_integral_exact(ROUND_HALF_EVEN)) + ), +) + + +def make_unary_check_result(check_just_result: UnaryCheck) -> UnaryResultCheck: + def check_result(i: float, result: float) -> bool: + return check_just_result(result) + + return check_result + + +def parse_unary_docstring(docstring: str) -> List[UnaryCase]: + """ + Parses a Sphinx-formatted docstring of a unary function to return a list of + codified unary cases, e.g. + + >>> def sqrt(x): + ... ''' + ... Calculates the square root + ... + ... **Special Cases** + ... + ... For floating-point operands, + ... + ... - If ``x_i`` is less than ``0``, the result is ``NaN``. + ... - If ``x_i`` is ``NaN``, the result is ``NaN``. + ... - If ``x_i`` is ``+0``, the result is ``+0``. + ... - If ``x_i`` is ``-0``, the result is ``-0``. + ... - If ``x_i`` is ``+infinity``, the result is ``+infinity``. + ... + ... Parameters + ... ---------- + ... x: array + ... input array + ... + ... Returns + ... ------- + ... out: array + ... an array containing the square root of each element in ``x`` + ... ''' + ... + >>> unary_cases = parse_unary_docstring(sqrt.__doc__) + >>> for case in unary_cases: + ... print(repr(case)) + UnaryCase( NaN>) + UnaryCase( NaN>) + UnaryCase( +0>) + UnaryCase( -0>) + UnaryCase( +infinity>) + >>> lt_0_case = unary_cases[0] + >>> lt_0_case.cond(-123) + True + >>> lt_0_case.check_result(-123, float('nan')) + True + + """ + + match = r_special_cases.search(docstring) + if match is None: + return [] + lines = match.group(1).split("\n")[:-1] + cases = [] + for line in lines: + if m := r_case.match(line): + case = m.group(1) + else: + warn(f"line not machine-readable: '{line}'") + continue + if m := r_unary_case.search(case): + try: + cond, cond_expr_template, cond_from_dtype = parse_cond(m.group(1)) + _check_result, result_expr = parse_result(m.group(2)) + except ParseError as e: + warn(f"not machine-readable: '{e.value}'") + continue + cond_expr = cond_expr_template.replace("{}", "x_i") + # Do not define check_result in this function's body - see + # parse_binary_case comment. + check_result = make_unary_check_result(_check_result) + case = UnaryCase( + cond_expr=cond_expr, + cond=cond, + cond_from_dtype=cond_from_dtype, + result_expr=result_expr, + check_result=check_result, + ) + cases.append(case) + elif m := r_even_round_halves_case.search(case): + cases.append(even_round_halves_case) + else: + if not r_remaining_case.search(case): + warn(f"case not machine-readable: '{case}'") + return cases + + +class BinaryCond(Protocol): + def __call__(self, i1: float, i2: float) -> bool: + ... + + +class BinaryResultCheck(Protocol): + def __call__(self, i1: float, i2: float, result: float) -> bool: + ... + + +@dataclass(repr=False) +class BinaryCase(Case): + cond_expr: str + result_expr: str + x1_cond_from_dtype: FromDtypeFunc + x2_cond_from_dtype: FromDtypeFunc + cond: BinaryCond + check_result: BinaryResultCheck + + +r_special_cases = re.compile( + r"\*\*Special [Cc]ases\*\*(?:\n.*)+" + r"For floating-point operands,\n+" + r"((?:\s*-\s*.*\n)+)" +) +r_case = re.compile(r"\s+-\s*(.*)\.\n?") +r_binary_case = re.compile("If (.+), the result (.+)") +r_remaining_case = re.compile("In the remaining cases.+") +r_cond_sep = re.compile(r"(? float: + return n + + +def make_binary_cond( + cond_arg: BinaryCondArg, + unary_cond: UnaryCheck, + *, + input_wrapper: Optional[Callable[[float], float]] = None, +) -> BinaryCond: + """ + Wraps a unary condition as a binary condition, e.g. + + >>> unary_cond = lambda i: i == 42 + >>> binary_cond_first = make_binary_cond(BinaryCondArg.FIRST, unary_cond) + >>> binary_cond_first(42, 0) + True + >>> binary_cond_second = make_binary_cond(BinaryCondArg.SECOND, unary_cond) + >>> binary_cond_second(42, 0) + False + >>> binary_cond_second(0, 42) + True + >>> binary_cond_both = make_binary_cond(BinaryCondArg.BOTH, unary_cond) + >>> binary_cond_both(42, 0) + False + >>> binary_cond_both(42, 42) + True + >>> binary_cond_either = make_binary_cond(BinaryCondArg.EITHER, unary_cond) + >>> binary_cond_either(0, 0) + False + >>> binary_cond_either(42, 0) + True + >>> binary_cond_either(0, 42) + True + >>> binary_cond_either(42, 42) + True + + """ + if input_wrapper is None: + input_wrapper = noop + + if cond_arg == BinaryCondArg.FIRST: + + def partial_cond(i1: float, i2: float) -> bool: + return unary_cond(input_wrapper(i1)) + + elif cond_arg == BinaryCondArg.SECOND: + + def partial_cond(i1: float, i2: float) -> bool: + return unary_cond(input_wrapper(i2)) + + elif cond_arg == BinaryCondArg.BOTH: + + def partial_cond(i1: float, i2: float) -> bool: + return unary_cond(input_wrapper(i1)) and unary_cond(input_wrapper(i2)) + + else: + + def partial_cond(i1: float, i2: float) -> bool: + return unary_cond(input_wrapper(i1)) or unary_cond(input_wrapper(i2)) + + return partial_cond + + +def make_eq_input_check_result( + eq_to: BinaryCondArg, *, eq_neg: bool = False +) -> BinaryResultCheck: + """ + Returns a result checker for cases where the result equals an array element + + >>> check_result_first = make_eq_input_check_result(BinaryCondArg.FIRST) + >>> check_result(42, 0, 42) + True + >>> check_result_second = make_eq_input_check_result(BinaryCondArg.SECOND) + >>> check_result(42, 0, 42) + False + >>> check_result(0, 42, 42) + True + >>> check_result_neg_first = make_eq_input_check_result(BinaryCondArg.FIRST, eq_neg=True) + >>> check_result_neg_first(42, 0, 42) + False + >>> check_result_neg_first(42, 0, -42) + True + + """ + if eq_neg: + input_wrapper = lambda i: -i + else: + input_wrapper = noop + + if eq_to == BinaryCondArg.FIRST: + + def check_result(i1: float, i2: float, result: float) -> bool: + eq = make_strict_eq(input_wrapper(i1)) + return eq(result) + + elif eq_to == BinaryCondArg.SECOND: + + def check_result(i1: float, i2: float, result: float) -> bool: + eq = make_strict_eq(input_wrapper(i2)) + return eq(result) + + else: + raise ValueError(f"{eq_to=} must be FIRST or SECOND") + + return check_result + + +def make_binary_check_result(check_just_result: UnaryCheck) -> BinaryResultCheck: + def check_result(i1: float, i2: float, result: float) -> bool: + return check_just_result(result) + + return check_result + + +def integers_from_dtype(dtype: DataType, **kw) -> st.SearchStrategy[float]: + """ + Returns a strategy that generates float-casted integers within the bounds of dtype. + """ + for k in kw.keys(): + # sanity check + assert k in ["min_value", "max_value", "exclude_min", "exclude_max"] + m, M = dh.dtype_ranges[dtype] + if "min_value" in kw.keys(): + m = kw["min_value"] + if "exclude_min" in kw.keys(): + m += 1 + if "max_value" in kw.keys(): + M = kw["max_value"] + if "exclude_max" in kw.keys(): + M -= 1 + return st.integers(math.ceil(m), math.floor(M)).map(float) + + +def parse_binary_case(case_str: str) -> BinaryCase: + """ + Parses a Sphinx-formatted binary case string to return codified binary cases, e.g. + + >>> case_str = ( + ... "If ``x1_i`` is greater than ``0``, ``x1_i`` is a finite number, " + ... "and ``x2_i`` is ``+infinity``, the result is ``NaN``." + ... ) + >>> case = parse_binary_case(case_str) + >>> case + BinaryCase( 0 and isfinite(x1_i) and x2_i == +infinity -> NaN>) + >>> case.cond(42, float('inf')) + True + >>> case.check_result(42, float('inf'), float('nan')) + True + + """ + case_m = r_binary_case.match(case_str) + if case_m is None: + raise ParseError(case_str) + cond_strs = r_cond_sep.split(case_m.group(1)) + + partial_conds = [] + partial_exprs = [] + x1_cond_from_dtypes = [] + x2_cond_from_dtypes = [] + for cond_str in cond_strs: + if m := r_input_is_array_element.match(cond_str): + in_sign, in_no, other_sign, other_no = m.groups() + if in_sign != "" or other_no == in_no: + raise ParseError(cond_str) + partial_expr = f"{in_sign}x{in_no}_i == {other_sign}x{other_no}_i" + + # For these scenarios, we want to make sure both array elements + # generate respective to one another by using a shared strategy. + shared_from_dtype = lambda d, **kw: st.shared( + xps.from_dtype(d, **kw), key=cond_str + ) + input_wrapper = lambda i: -i if other_sign == "-" else noop + if other_no == "1": + + def partial_cond(i1: float, i2: float) -> bool: + eq = make_strict_eq(input_wrapper(i1)) + return eq(i2) + + _x2_cond_from_dtype = shared_from_dtype # type: ignore + + def _x1_cond_from_dtype(dtype, **kw) -> st.SearchStrategy[float]: + return shared_from_dtype(dtype, **kw).map(input_wrapper) + + elif other_no == "2": + + def partial_cond(i1: float, i2: float) -> bool: + eq = make_strict_eq(input_wrapper(i2)) + return eq(i1) + + _x1_cond_from_dtype = shared_from_dtype # type: ignore + + def _x2_cond_from_dtype(dtype, **kw) -> st.SearchStrategy[float]: + return shared_from_dtype(dtype, **kw).map(input_wrapper) + + else: + raise ParseError(cond_str) + + x1_cond_from_dtypes.append(BoundFromDtype(base_func=_x1_cond_from_dtype)) + x2_cond_from_dtypes.append(BoundFromDtype(base_func=_x2_cond_from_dtype)) + + elif m := r_both_inputs_are_value.match(cond_str): + unary_cond, expr_template, cond_from_dtype = parse_cond(m.group(1)) + left_expr = expr_template.replace("{}", "x1_i") + right_expr = expr_template.replace("{}", "x2_i") + partial_expr = f"{left_expr} and {right_expr}" + partial_cond = make_binary_cond( # type: ignore + BinaryCondArg.BOTH, unary_cond + ) + x1_cond_from_dtypes.append(cond_from_dtype) + x2_cond_from_dtypes.append(cond_from_dtype) + else: + cond_m = r_cond.match(cond_str) + if cond_m is None: + raise ParseError(cond_str) + input_str, value_str = cond_m.groups() + + if value_str == "the same mathematical sign": + partial_expr = "copysign(1, x1_i) == copysign(1, x2_i)" + + def partial_cond(i1: float, i2: float) -> bool: + return math.copysign(1, i1) == math.copysign(1, i2) + + elif value_str == "different mathematical signs": + partial_expr = "copysign(1, x1_i) != copysign(1, x2_i)" + + def partial_cond(i1: float, i2: float) -> bool: + return math.copysign(1, i1) != math.copysign(1, i2) + + else: + unary_cond, expr_template, cond_from_dtype = parse_cond(value_str) + # Do not define partial_cond via the def keyword or lambda + # expressions, as one partial_cond definition can mess up + # previous definitions in the partial_conds list. This is a + # hard-limitation of using local functions with the same name + # and that use the same outer variables (i.e. unary_cond). Use + # def in a called function avoids this problem. + input_wrapper = None + if m := r_input.match(input_str): + x_no = m.group(1) + partial_expr = expr_template.replace("{}", f"x{x_no}_i") + cond_arg = BinaryCondArg.from_x_no(x_no) + elif m := r_abs_input.match(input_str): + x_no = m.group(1) + partial_expr = expr_template.replace("{}", f"abs(x{x_no}_i)") + cond_arg = BinaryCondArg.from_x_no(x_no) + input_wrapper = abs + elif r_and_input.match(input_str): + left_expr = expr_template.replace("{}", "x1_i") + right_expr = expr_template.replace("{}", "x2_i") + partial_expr = f"{left_expr} and {right_expr}" + cond_arg = BinaryCondArg.BOTH + elif r_or_input.match(input_str): + left_expr = expr_template.replace("{}", "x1_i") + right_expr = expr_template.replace("{}", "x2_i") + partial_expr = f"{left_expr} or {right_expr}" + if len(cond_strs) != 1: + partial_expr = f"({partial_expr})" + cond_arg = BinaryCondArg.EITHER + else: + raise ParseError(input_str) + partial_cond = make_binary_cond( # type: ignore + cond_arg, unary_cond, input_wrapper=input_wrapper + ) + if cond_arg == BinaryCondArg.FIRST: + x1_cond_from_dtypes.append(cond_from_dtype) + elif cond_arg == BinaryCondArg.SECOND: + x2_cond_from_dtypes.append(cond_from_dtype) + elif cond_arg == BinaryCondArg.BOTH: + x1_cond_from_dtypes.append(cond_from_dtype) + x2_cond_from_dtypes.append(cond_from_dtype) + else: + # For "either x1_i or x2_i is " cases, we want to + # test three scenarios: + # + # 1. x1_i is + # 2. x2_i is + # 3. x1_i AND x2_i is + # + # This is achieved by a shared base strategy that picks one + # of these scenarios to determine whether each array will + # use either cond_from_dtype() (i.e. meet the condition), or + # simply xps.from_dtype() (i.e. be any value). + + use_x1_or_x2_strat = st.shared( + st.sampled_from([(True, False), (False, True), (True, True)]) + ) + + def _x1_cond_from_dtype(dtype, **kw) -> st.SearchStrategy[float]: + assert len(kw) == 0 # sanity check + return use_x1_or_x2_strat.flatmap( + lambda t: cond_from_dtype(dtype) + if t[0] + else xps.from_dtype(dtype) + ) + + def _x2_cond_from_dtype(dtype, **kw) -> st.SearchStrategy[float]: + assert len(kw) == 0 # sanity check + return use_x1_or_x2_strat.flatmap( + lambda t: cond_from_dtype(dtype) + if t[1] + else xps.from_dtype(dtype) + ) + + x1_cond_from_dtypes.append( + BoundFromDtype(base_func=_x1_cond_from_dtype) + ) + x2_cond_from_dtypes.append( + BoundFromDtype(base_func=_x2_cond_from_dtype) + ) + + partial_conds.append(partial_cond) + partial_exprs.append(partial_expr) + + result_m = r_result.match(case_m.group(2)) + if result_m is None: + raise ParseError(case_m.group(2)) + result_str = result_m.group(1) + # Like with partial_cond, do not define check_result in this function's body. + if m := r_array_element.match(result_str): + sign, x_no = m.groups() + result_expr = f"{sign}x{x_no}_i" + check_result = make_eq_input_check_result( # type: ignore + BinaryCondArg.from_x_no(x_no), eq_neg=sign == "-" + ) + else: + _check_result, result_expr = parse_result(result_m.group(1)) + check_result = make_binary_check_result(_check_result) + + cond_expr = " and ".join(partial_exprs) + + def cond(i1: float, i2: float) -> bool: + return all(pc(i1, i2) for pc in partial_conds) + + x1_cond_from_dtype = sum(x1_cond_from_dtypes, start=BoundFromDtype()) + x2_cond_from_dtype = sum(x2_cond_from_dtypes, start=BoundFromDtype()) + + return BinaryCase( + cond_expr=cond_expr, + cond=cond, + x1_cond_from_dtype=x1_cond_from_dtype, + x2_cond_from_dtype=x2_cond_from_dtype, + result_expr=result_expr, + check_result=check_result, + ) + + +r_redundant_case = re.compile("result.+determined by the rule already stated above") + + +def parse_binary_docstring(docstring: str) -> List[BinaryCase]: + """ + Parses a Sphinx-formatted docstring of a binary function to return a list of + codified binary cases, e.g. + + >>> def logaddexp(x1, x2): + ... ''' + ... Calculates the logarithm of the sum of exponentiations + ... + ... **Special Cases** + ... + ... For floating-point operands, + ... + ... - If either ``x1_i`` or ``x2_i`` is ``NaN``, the result is ``NaN``. + ... - If ``x1_i`` is ``+infinity`` and ``x2_i`` is not ``NaN``, the result is ``+infinity``. + ... - If ``x1_i`` is not ``NaN`` and ``x2_i`` is ``+infinity``, the result is ``+infinity``. + ... + ... Parameters + ... ---------- + ... x1: array + ... first input array + ... x2: array + ... second input array + ... + ... Returns + ... ------- + ... out: array + ... an array containing the results + ... ''' + ... + >>> binary_cases = parse_binary_docstring(logaddexp.__doc__) + >>> for case in binary_cases: + ... print(repr(case)) + BinaryCase( NaN>) + BinaryCase( +infinity>) + BinaryCase( +infinity>) + + """ + + match = r_special_cases.search(docstring) + if match is None: + return [] + lines = match.group(1).split("\n")[:-1] + cases = [] + for line in lines: + if m := r_case.match(line): + case_str = m.group(1) + else: + warn(f"line not machine-readable: '{line}'") + continue + if r_redundant_case.search(case_str): + continue + if m := r_binary_case.match(case_str): + try: + case = parse_binary_case(case_str) + cases.append(case) + except ParseError as e: + warn(f"not machine-readable: '{e.value}'") + else: + if not r_remaining_case.match(case_str): + warn(f"case not machine-readable: '{case_str}'") + return cases + + +unary_params = [] +binary_params = [] +iop_params = [] +func_to_op: Dict[str, str] = {v: k for k, v in dh.op_to_func.items()} +for stub in category_to_funcs["elementwise"]: + if stub.__doc__ is None: + warn(f"{stub.__name__}() stub has no docstring") + continue + marks = [] + try: + func = getattr(xp, stub.__name__) + except AttributeError: + marks.append( + pytest.mark.skip(reason=f"{stub.__name__} not found in array module") + ) + func = None + sig = inspect.signature(stub) + param_names = list(sig.parameters.keys()) + if len(sig.parameters) == 0: + warn(f"{func=} has no parameters") + continue + if param_names[0] == "x": + if cases := parse_unary_docstring(stub.__doc__): + func_name_to_func = {stub.__name__: func} + if stub.__name__ in func_to_op.keys(): + op_name = func_to_op[stub.__name__] + op = getattr(operator, op_name) + func_name_to_func[op_name] = op + for func_name, func in func_name_to_func.items(): + for case in cases: + id_ = f"{func_name}({case.cond_expr}) -> {case.result_expr}" + p = pytest.param(func_name, func, case, id=id_) + unary_params.append(p) + continue + if len(sig.parameters) == 1: + warn(f"{func=} has one parameter '{param_names[0]}' which is not named 'x'") + continue + if param_names[0] == "x1" and param_names[1] == "x2": + if cases := parse_binary_docstring(stub.__doc__): + func_name_to_func = {stub.__name__: func} + if stub.__name__ in func_to_op.keys(): + op_name = func_to_op[stub.__name__] + op = getattr(operator, op_name) + func_name_to_func[op_name] = op + # We collect inplaceoperator test cases seperately + iop_name = "__i" + op_name[2:] + iop = getattr(operator, iop_name) + for case in cases: + id_ = f"{iop_name}({case.cond_expr}) -> {case.result_expr}" + p = pytest.param(iop_name, iop, case, id=id_) + iop_params.append(p) + for func_name, func in func_name_to_func.items(): + for case in cases: + id_ = f"{func_name}({case.cond_expr}) -> {case.result_expr}" + p = pytest.param(func_name, func, case, id=id_) + binary_params.append(p) + continue + else: + warn( + f"{func=} starts with two parameters '{param_names[0]}' and " + f"'{param_names[1]}', which are not named 'x1' and 'x2'" + ) + + +# test_unary and test_binary naively generate arrays, i.e. arrays that might not +# meet the condition that is being test. We then forcibly make the array meet +# the condition by picking a random index to insert an acceptable element. +# +# good_example is a flag that tells us whether Hypothesis generated an array +# with at least on element that is special-cased. We reject the example when +# its False - Hypothesis will complain if we reject too many examples, thus +# indicating we've done something wrong. + + +@pytest.mark.parametrize("func_name, func, case", unary_params) +@given( + x=xps.arrays(dtype=xps.floating_dtypes(), shape=hh.shapes(min_side=1)), + data=st.data(), +) +def test_unary(func_name, func, case, x, data): + set_idx = data.draw( + xps.indices(x.shape, max_dims=0, allow_ellipsis=False), label="set idx" + ) + set_value = data.draw(case.cond_from_dtype(x.dtype), label="set value") + x[set_idx] = set_value + note(f"{x=}") + + res = func(x) + + good_example = False + for idx in sh.ndindex(res.shape): + in_ = float(x[idx]) + if case.cond(in_): + good_example = True + out = float(res[idx]) + f_in = f"{sh.fmt_idx('x', idx)}={in_}" + f_out = f"{sh.fmt_idx('out', idx)}={out}" + assert case.check_result(in_, out), ( + f"{f_out}, but should be {case.result_expr} [{func_name}()]\n" + f"condition: {case.cond_expr}\n" + f"{f_in}" + ) + break + assume(good_example) + + +x1_strat, x2_strat = hh.two_mutual_arrays( + dtypes=dh.float_dtypes, + two_shapes=hh.mutually_broadcastable_shapes(2, min_side=1), +) + + +@pytest.mark.parametrize("func_name, func, case", binary_params) +@given(x1=x1_strat, x2=x2_strat, data=st.data()) +def test_binary(func_name, func, case, x1, x2, data): + result_shape = sh.broadcast_shapes(x1.shape, x2.shape) + all_indices = list(sh.iter_indices(x1.shape, x2.shape, result_shape)) + + indices_strat = st.shared(st.sampled_from(all_indices)) + set_x1_idx = data.draw(indices_strat.map(lambda t: t[0]), label="set x1 idx") + set_x1_value = data.draw(case.x1_cond_from_dtype(x1.dtype), label="set x1 value") + x1[set_x1_idx] = set_x1_value + note(f"{x1=}") + set_x2_idx = data.draw(indices_strat.map(lambda t: t[1]), label="set x2 idx") + set_x2_value = data.draw(case.x2_cond_from_dtype(x2.dtype), label="set x2 value") + x2[set_x2_idx] = set_x2_value + note(f"{x2=}") + + res = func(x1, x2) + # sanity check + ph.assert_result_shape(func_name, [x1.shape, x2.shape], res.shape, result_shape) + + good_example = False + for l_idx, r_idx, o_idx in all_indices: + l = float(x1[l_idx]) + r = float(x2[r_idx]) + if case.cond(l, r): + good_example = True + o = float(res[o_idx]) + f_left = f"{sh.fmt_idx('x1', l_idx)}={l}" + f_right = f"{sh.fmt_idx('x2', r_idx)}={r}" + f_out = f"{sh.fmt_idx('out', o_idx)}={o}" + assert case.check_result(l, r, o), ( + f"{f_out}, but should be {case.result_expr} [{func_name}()]\n" + f"condition: {case}\n" + f"{f_left}, {f_right}" + ) + break + assume(good_example) + + +@pytest.mark.parametrize("iop_name, iop, case", iop_params) +@given( + oneway_dtypes=oneway_promotable_dtypes(dh.float_dtypes), + oneway_shapes=oneway_broadcastable_shapes(), + data=st.data(), +) +def test_iop(iop_name, iop, case, oneway_dtypes, oneway_shapes, data): + x1 = data.draw( + xps.arrays(dtype=oneway_dtypes.result_dtype, shape=oneway_shapes.result_shape), + label="x1", + ) + x2 = data.draw( + xps.arrays(dtype=oneway_dtypes.input_dtype, shape=oneway_shapes.input_shape), + label="x2", + ) + + all_indices = list(sh.iter_indices(x1.shape, x2.shape, x1.shape)) + + indices_strat = st.shared(st.sampled_from(all_indices)) + set_x1_idx = data.draw(indices_strat.map(lambda t: t[0]), label="set x1 idx") + set_x1_value = data.draw(case.x1_cond_from_dtype(x1.dtype), label="set x1 value") + x1[set_x1_idx] = set_x1_value + note(f"{x1=}") + set_x2_idx = data.draw(indices_strat.map(lambda t: t[1]), label="set x2 idx") + set_x2_value = data.draw(case.x2_cond_from_dtype(x2.dtype), label="set x2 value") + x2[set_x2_idx] = set_x2_value + note(f"{x2=}") + + res = xp.asarray(x1, copy=True) + iop(res, x2) + # sanity check + ph.assert_result_shape(iop_name, [x1.shape, x2.shape], res.shape) + + good_example = False + for l_idx, r_idx, o_idx in all_indices: + l = float(x1[l_idx]) + r = float(x2[r_idx]) + if case.cond(l, r): + good_example = True + o = float(res[o_idx]) + f_left = f"{sh.fmt_idx('x1', l_idx)}={l}" + f_right = f"{sh.fmt_idx('x2', r_idx)}={r}" + f_out = f"{sh.fmt_idx('out', o_idx)}={o}" + assert case.check_result(l, r, o), ( + f"{f_out}, but should be {case.result_expr} [{iop_name}()]\n" + f"condition: {case}\n" + f"{f_left}, {f_right}" + ) + break + assume(good_example)