Check loss of precision in complex arc* functions
(self, dtype)
| 4545 | np.complex64, np.complex128, np.clongdouble |
| 4546 | ]) |
| 4547 | def test_loss_of_precision(self, dtype): |
| 4548 | """Check loss of precision in complex arc* functions""" |
| 4549 | if dtype is np.clongdouble and platform.machine() != 'x86_64': |
| 4550 | # Failures on musllinux, aarch64, s390x, ppc64le (see gh-17554) |
| 4551 | pytest.skip('Only works reliably for x86-64 and recent glibc') |
| 4552 | |
| 4553 | # Check against known-good functions |
| 4554 | |
| 4555 | info = np.finfo(dtype) |
| 4556 | real_dtype = dtype(0.).real.dtype |
| 4557 | eps = info.eps |
| 4558 | |
| 4559 | def check(x, rtol): |
| 4560 | x = x.astype(real_dtype) |
| 4561 | |
| 4562 | z = x.astype(dtype) |
| 4563 | d = np.absolute(np.arcsinh(x) / np.arcsinh(z).real - 1) |
| 4564 | assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), |
| 4565 | 'arcsinh')) |
| 4566 | |
| 4567 | z = (1j * x).astype(dtype) |
| 4568 | d = np.absolute(np.arcsinh(x) / np.arcsin(z).imag - 1) |
| 4569 | assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), |
| 4570 | 'arcsin')) |
| 4571 | |
| 4572 | z = x.astype(dtype) |
| 4573 | d = np.absolute(np.arctanh(x) / np.arctanh(z).real - 1) |
| 4574 | assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), |
| 4575 | 'arctanh')) |
| 4576 | |
| 4577 | z = (1j * x).astype(dtype) |
| 4578 | d = np.absolute(np.arctanh(x) / np.arctan(z).imag - 1) |
| 4579 | assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), |
| 4580 | 'arctan')) |
| 4581 | |
| 4582 | # The switchover was chosen as 1e-3; hence there can be up to |
| 4583 | # ~eps/1e-3 of relative cancellation error before it |
| 4584 | |
| 4585 | x_series = np.logspace(-20, -3.001, 200) |
| 4586 | x_basic = np.logspace(-2.999, 0, 10, endpoint=False) |
| 4587 | |
| 4588 | if dtype is np.clongdouble: |
| 4589 | if bad_arcsinh(): |
| 4590 | pytest.skip("Trig functions of np.clongdouble values known " |
| 4591 | "to be inaccurate on aarch64 and PPC for some " |
| 4592 | "compilation configurations.") |
| 4593 | # It's not guaranteed that the system-provided arc functions |
| 4594 | # are accurate down to a few epsilons. (Eg. on Linux 64-bit) |
| 4595 | # So, give more leeway for long complex tests here: |
| 4596 | check(x_series, 50.0 * eps) |
| 4597 | else: |
| 4598 | check(x_series, 2.1 * eps) |
| 4599 | check(x_basic, 2.0 * eps / 1e-3) |
| 4600 | |
| 4601 | # Check a few points |
| 4602 | |
| 4603 | z = np.array([1e-5 * (1 + 1j)], dtype=dtype) |
| 4604 | p = 9.999999999333333333e-6 + 1.000000000066666666e-5j |
nothing calls this directly
no test coverage detected