From 1db9312b20b403c245f5f73232dca0a93dbf01a8 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Tue, 19 May 2026 16:48:45 +0100 Subject: [PATCH 01/43] Add `jupyter` as `dev` dep --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 6d004a73..52ee4e5c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ dev = [ "coverage[toml]", "hatch-vcs", "hatchling", + "jupyter", "nox", "nox-uv", {include-group = "build"}, From eeb69fdbf3099db9e2801f36790874d09ed87a03 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Tue, 19 May 2026 16:49:35 +0100 Subject: [PATCH 02/43] Use `xp_assert` methods from `xpx` --- tests/benchmarks/test_fields.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/tests/benchmarks/test_fields.py b/tests/benchmarks/test_fields.py index db00bf49..6e6c935f 100644 --- a/tests/benchmarks/test_fields.py +++ b/tests/benchmarks/test_fields.py @@ -5,6 +5,8 @@ import pytest +from array_api_extra._lib._testing import xp_assert_close + import glass import glass.fields import glass.healpix as hp @@ -16,7 +18,7 @@ from pytest_benchmark.fixture import BenchmarkFixture from glass._types import AngularPowerSpectra, UnifiedGenerator - from tests.fixtures.helper_classes import Compare, GeneratorConsumer + from tests.fixtures.helper_classes import GeneratorConsumer @pytest.mark.stable @@ -102,7 +104,6 @@ def function_to_benchmark() -> list[Any]: @pytest.mark.stable def test_iternorm_k_0( benchmark: BenchmarkFixture, - compare: Compare, generator_consumer: GeneratorConsumer, xpb: ModuleType, ) -> None: @@ -119,13 +120,12 @@ def function_to_benchmark() -> list[Any]: j, a, s = results[0] assert j is None assert a.shape == (0,) - compare.assert_allclose(xpb.asarray(s), 1.0) + xp_assert_close(s, xpb.ones_like(s)) @pytest.mark.stable def test_cls2cov( benchmark: BenchmarkFixture, - compare: Compare, generator_consumer: GeneratorConsumer, xpb: ModuleType, ) -> None: @@ -148,9 +148,9 @@ def function_to_benchmark() -> list[Any]: assert cov.shape == (nl, nc + 1) assert cov.dtype == xpb.float64 - compare.assert_allclose(cov[:, 0], xpb.asarray([1.0, 1.5, 2.0])) - compare.assert_allclose(cov[:, 1], xpb.asarray([1.5, 2.0, 2.5])) - compare.assert_allclose(cov[:, 2], 0) + xp_assert_close(cov[:, 0], xpb.asarray([1.0, 1.5, 2.0])) + xp_assert_close(cov[:, 1], xpb.asarray([1.5, 2.0, 2.5])) + xp_assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) @pytest.mark.stable @@ -185,7 +185,6 @@ def function_to_benchmark() -> list[Any]: @pytest.mark.parametrize("ncorr", [None, 1]) def test_generate( benchmark: BenchmarkFixture, - compare: Compare, generator_consumer: GeneratorConsumer, xpb: ModuleType, ncorr: int | None, @@ -214,13 +213,12 @@ def function_to_benchmark() -> list[Any]: for field in result: assert field.shape == (hp.nside2npix(nside),) - compare.assert_allclose(result[1], result[0] ** 2, atol=1e-05) + xp_assert_close(result[1], result[0] ** 2, atol=1e-05) @pytest.mark.unstable def test_getcl_lmax_0( benchmark: BenchmarkFixture, - compare: type[Compare], xpb: ModuleType, ) -> None: """Benchmarks for glass.getcl with lmax of 0.""" @@ -245,13 +243,12 @@ def test_getcl_lmax_0( ) expected = xpb.asarray([max(random_i, random_j)], dtype=xpb.float64) assert result.shape[0] == 1 - compare.assert_allclose(result, expected) + xp_assert_close(result, expected) @pytest.mark.unstable def test_getcl_lmax_larger_than_cls( benchmark: BenchmarkFixture, - compare: type[Compare], xpb: ModuleType, ) -> None: """Benchmarks for glass.getcl with lmax larger than the length of cl.""" @@ -277,4 +274,4 @@ def test_getcl_lmax_larger_than_cls( ) expected = xpb.zeros((lmax - 1,), dtype=xpb.float64) assert result.shape[0] == lmax + 1 - compare.assert_allclose(result[2:], expected) + xp_assert_close(result[2:], expected) From a8c81aba10937bbedd15b7bbb05c1e39039ba424 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Tue, 19 May 2026 17:11:19 +0100 Subject: [PATCH 03/43] Missing comma --- glass/fields.py | 3 ++- glass/galaxies.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/glass/fields.py b/glass/fields.py index 81a5303e..6a3cc626 100644 --- a/glass/fields.py +++ b/glass/fields.py @@ -662,7 +662,8 @@ def effective_cls( itertools.combinations_with_replacement(uxpx.ndindex(shape1[1:], xp=xp), 2) if weights2 is weights1 else itertools.product( - uxpx.ndindex(shape1[1:], xp=xp), uxpx.ndindex(shape2[1:], xp=xp) + uxpx.ndindex(shape1[1:], xp=xp), + uxpx.ndindex(shape2[1:], xp=xp), ) ) diff --git a/glass/galaxies.py b/glass/galaxies.py index 0c66b2f2..a36f1ee4 100644 --- a/glass/galaxies.py +++ b/glass/galaxies.py @@ -148,7 +148,7 @@ def redshifts_from_nz( rng.uniform(0, 1, size=int(count_out[k])), cdf, z_out_slice, - ) + ), ) total += count_out[k] From fdd7cc0983c0a31eb2b52967670ea2a3e5b1ac25 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Tue, 19 May 2026 17:12:21 +0100 Subject: [PATCH 04/43] Remove redundant assert statements from `Compare` --- tests/fixtures/helper_classes.py | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/tests/fixtures/helper_classes.py b/tests/fixtures/helper_classes.py index f7fd0094..2e73f77e 100644 --- a/tests/fixtures/helper_classes.py +++ b/tests/fixtures/helper_classes.py @@ -31,17 +31,6 @@ class Compare: """ - @staticmethod - def assert_allclose( - actual: AnyArray, - desired: AnyArray, - *, - rtol: float = 1e-7, - atol: float = 0, - ) -> None: - """Check if two objects are not equal up to desired tolerance.""" - np.testing.assert_allclose(actual, desired, rtol=rtol, atol=atol) - @staticmethod def assert_array_almost_equal_nulp( actual: AnyArray, @@ -52,16 +41,6 @@ def assert_array_almost_equal_nulp( """Compare two arrays relatively to their spacing.""" np.testing.assert_array_almost_equal_nulp(actual, desired, nulp=nulp) - @staticmethod - def assert_array_equal(actual: AnyArray, desired: AnyArray) -> None: - """Check if two array objects are not equal.""" - np.testing.assert_array_equal(actual, desired) - - @staticmethod - def assert_array_less(actual: AnyArray, desired: AnyArray) -> None: - """Check if two array objects are not ordered by less than.""" - np.testing.assert_array_less(actual, desired) - @pytest.fixture(scope="session") def compare() -> type[Compare]: @@ -160,7 +139,7 @@ class HealpixInputs: def alm(*, rng: UnifiedGenerator) -> ComplexArray: """Generate random alm coefficients.""" return rng.standard_normal( # ty: ignore[unsupported-operator] - HealpixInputs.alm_size + HealpixInputs.alm_size, ) + 1j * rng.standard_normal( HealpixInputs.alm_size, ) From 3b8c8c254ab46e773622c94546b85aa8e760a1b5 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Tue, 19 May 2026 17:23:45 +0100 Subject: [PATCH 05/43] Remove `compare` calls --- tests/benchmarks/test_arraytools.py | 12 +-- tests/benchmarks/test_harmonics.py | 7 +- tests/benchmarks/test_lensing.py | 13 ++- tests/benchmarks/test_shells.py | 7 +- tests/core/grf/test_core.py | 5 +- tests/core/grf/test_solver.py | 28 +++--- tests/core/grf/test_transformations.py | 31 +++---- tests/core/test_algorithm.py | 15 ++- tests/core/test_arraytools.py | 34 +++---- tests/core/test_fields.py | 121 +++++++++++++------------ tests/core/test_galaxies.py | 24 +++-- tests/core/test_harmonics.py | 16 ++-- tests/core/test_healpix.py | 48 ++++------ tests/core/test_lensing.py | 56 +++++------- tests/core/test_observations.py | 40 ++++---- tests/core/test_points.py | 111 ++++++++++------------- tests/core/test_shapes.py | 47 +++++----- tests/core/test_shells.py | 59 ++++++------ tests/core/test_user.py | 14 ++- 19 files changed, 329 insertions(+), 359 deletions(-) diff --git a/tests/benchmarks/test_arraytools.py b/tests/benchmarks/test_arraytools.py index da07fbe8..7f3e764b 100644 --- a/tests/benchmarks/test_arraytools.py +++ b/tests/benchmarks/test_arraytools.py @@ -4,6 +4,8 @@ import pytest +from array_api_extra._lib._testing import xp_assert_close + import glass.arraytools if TYPE_CHECKING: @@ -11,8 +13,6 @@ from pytest_benchmark.fixture import BenchmarkFixture - from tests.fixtures.helper_classes import Compare - @pytest.mark.unstable def test_broadcast_leading_axes( @@ -44,7 +44,6 @@ def test_broadcast_leading_axes( @pytest.mark.unstable def test_cumulative_trapezoid_1d( benchmark: BenchmarkFixture, - compare: type[Compare], xpb: ModuleType, ) -> None: """Benchmark test for glass.arraytools.cumulative_trapezoid.""" @@ -56,7 +55,7 @@ def test_cumulative_trapezoid_1d( ct = benchmark(glass.arraytools.cumulative_trapezoid, f, x) # Compare to int64 as old versions of glass round to int64 if `dtype` is not passed. - compare.assert_allclose( + xp_assert_close( xpb.asarray(ct[:4], dtype=xpb.int64), xpb.asarray([0, 1, 4, 7]), ) @@ -66,7 +65,6 @@ def test_cumulative_trapezoid_1d( @pytest.mark.unstable def test_cumulative_trapezoid_2d( benchmark: BenchmarkFixture, - compare: type[Compare], xpb: ModuleType, ) -> None: """Benchmark test for glass.arraytools.cumulative_trapezoid.""" @@ -85,11 +83,11 @@ def test_cumulative_trapezoid_2d( ct = benchmark(glass.arraytools.cumulative_trapezoid, f, x) # Compare to int64 as old versions of glass round to int64 if `dtype` is not passed. - compare.assert_allclose( + xp_assert_close( xpb.asarray(ct[0, :4], dtype=xpb.int64), expected_first_4_out, ) - compare.assert_allclose( + xp_assert_close( xpb.asarray(ct[1, :4], dtype=xpb.int64), expected_first_4_out, ) diff --git a/tests/benchmarks/test_harmonics.py b/tests/benchmarks/test_harmonics.py index c004c36c..48ffd492 100644 --- a/tests/benchmarks/test_harmonics.py +++ b/tests/benchmarks/test_harmonics.py @@ -4,6 +4,8 @@ import pytest +from array_api_extra._lib._testing import xp_assert_close + glass_harmonics = pytest.importorskip( "glass.harmonics", reason="tests require glass.harmonics", @@ -15,13 +17,10 @@ from pytest_benchmark.fixture import BenchmarkFixture - from tests.fixtures.helper_classes import Compare - @pytest.mark.unstable def test_multalm( benchmark: BenchmarkFixture, - compare: type[Compare], xpb: ModuleType, ) -> None: """Benchmarks for glass.harmonics.multalm.""" @@ -32,7 +31,7 @@ def test_multalm( result = benchmark(glass_harmonics.multalm, alm, bl) - compare.assert_allclose( + xp_assert_close( result[:5], xpb.asarray([scale_factor * x for x in [0.0, 3.0, 6.0, 9.0, 12.0]]), ) diff --git a/tests/benchmarks/test_lensing.py b/tests/benchmarks/test_lensing.py index d220dd71..49af57bd 100644 --- a/tests/benchmarks/test_lensing.py +++ b/tests/benchmarks/test_lensing.py @@ -4,6 +4,8 @@ import pytest +from array_api_extra._lib._testing import xp_assert_equal + import glass if TYPE_CHECKING: @@ -14,13 +16,11 @@ from glass._types import FloatArray, UnifiedGenerator from glass.cosmology import Cosmology - from tests.fixtures.helper_classes import Compare @pytest.mark.stable def test_multi_plane_matrix( benchmark: BenchmarkFixture, - compare: type[Compare], cosmo: Cosmology, urngb: UnifiedGenerator, xpb: ModuleType, @@ -38,8 +38,8 @@ def test_multi_plane_matrix( mat = glass.multi_plane_matrix(shells, cosmo) deltas = urngb.random((len(shells), 10)) - compare.assert_array_equal(mat, xpb.tril(mat)) - compare.assert_array_equal(xpb.triu(mat, k=1), 0) + xp_assert_equal(mat, xpb.tril(mat)) + xp_assert_equal(xpb.triu(mat, k=1), 0) def setup_shells_and_deltas() -> tuple[ tuple[ @@ -79,7 +79,6 @@ def multi_plane_matrix_add_window( @pytest.mark.stable def test_multi_plane_weights( benchmark: BenchmarkFixture, - compare: type[Compare], cosmo: Cosmology, urngb: UnifiedGenerator, xpb: ModuleType, @@ -100,8 +99,8 @@ def test_multi_plane_weights( w_out = glass.multi_plane_weights(w_in, shells, cosmo) - compare.assert_array_equal(w_out, xpb.triu(w_out, 1)) - compare.assert_array_equal(xpb.tril(w_out), 0) + xp_assert_equal(w_out, xpb.triu(w_out, 1)) + xp_assert_equal(xpb.tril(w_out), 0) def setup_shells_deltas_and_weights() -> tuple[ tuple[ diff --git a/tests/benchmarks/test_shells.py b/tests/benchmarks/test_shells.py index 552d2efd..45c8df3c 100644 --- a/tests/benchmarks/test_shells.py +++ b/tests/benchmarks/test_shells.py @@ -4,6 +4,8 @@ import pytest +from array_api_extra._lib._testing import xp_assert_close + import glass if TYPE_CHECKING: @@ -11,14 +13,11 @@ from pytest_benchmark.fixture import BenchmarkFixture - from tests.fixtures.helper_classes import Compare - @pytest.mark.unstable def test_radialwindow( benchmark: BenchmarkFixture, xpb: ModuleType, - compare: Compare, ) -> None: """Benchmark for shells.RadialWindow.""" # check zeff is computed when not provided @@ -30,4 +29,4 @@ def test_radialwindow( w = benchmark(glass.RadialWindow, za, wa) - compare.assert_allclose(w.zeff, expected_zeff) + xp_assert_close(w.zeff, expected_zeff) diff --git a/tests/core/grf/test_core.py b/tests/core/grf/test_core.py index 3db40af7..88d5c214 100644 --- a/tests/core/grf/test_core.py +++ b/tests/core/grf/test_core.py @@ -37,7 +37,10 @@ def dcorr(self, _other, _x): glass.grf.dcorr(t1, t2, x) -def test_compute(mocker: MockerFixture, xp: ModuleType) -> None: +def test_compute( + mocker: MockerFixture, + xp: ModuleType, +) -> None: cltocorr = mocker.patch("transformcl.cltocorr") icorr = mocker.patch("glass.grf._core.icorr") corrtocl = mocker.patch("transformcl.corrtocl") diff --git a/tests/core/grf/test_solver.py b/tests/core/grf/test_solver.py index 1faa6d4e..6788923f 100644 --- a/tests/core/grf/test_solver.py +++ b/tests/core/grf/test_solver.py @@ -5,11 +5,12 @@ import numpy as np import pytest +from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal + import glass.grf if TYPE_CHECKING: from glass._types import FloatArray - from tests.fixtures.helper_classes import Compare @pytest.fixture(scope="session") @@ -21,7 +22,6 @@ def cl() -> FloatArray: def test_one_transformation( cl: FloatArray, - compare: type[Compare], rng: np.random.Generator, ) -> None: lam = rng.random() @@ -30,10 +30,13 @@ def test_one_transformation( gl1, _, _ = glass.grf.solve(cl, t) gl2, _, _ = glass.grf.solve(cl, t, t) - compare.assert_array_equal(gl1, gl2) + xp_assert_equal(gl1, gl2) -def test_pad(cl: FloatArray, rng: np.random.Generator) -> None: +def test_pad( + cl: FloatArray, + rng: np.random.Generator, +) -> None: lam = rng.random() t = glass.grf.Lognormal(lam) @@ -48,7 +51,6 @@ def test_pad(cl: FloatArray, rng: np.random.Generator) -> None: def test_initial( cl: FloatArray, - compare: type[Compare], rng: np.random.Generator, ) -> None: lam = rng.random() @@ -59,21 +61,20 @@ def test_initial( gl1, _, _ = glass.grf.solve(cl, t) gl2, _, _ = glass.grf.solve(cl, t, initial=gl) - compare.assert_array_equal(gl1, gl2) + xp_assert_equal(gl1, gl2) -def test_no_iterations(cl: FloatArray, compare: type[Compare]) -> None: +def test_no_iterations(cl: FloatArray) -> None: t = glass.grf.Lognormal() gl1 = glass.grf.compute(cl, t) gl2, _, _ = glass.grf.solve(cl, t, maxiter=0) - compare.assert_array_equal(gl1, gl2) + xp_assert_equal(gl1, gl2) def test_lognormal( cl: FloatArray, - compare: type[Compare], rng: np.random.Generator, ) -> None: t1 = glass.grf.Lognormal() @@ -87,17 +88,16 @@ def test_lognormal( assert info > 0 - compare.assert_allclose(cl_[1 : cl.shape[0]], cl[1:], atol=0.0, rtol=cltol) + xp_assert_close(cl_[1 : cl.shape[0]], cl[1:], atol=0.0, rtol=cltol) gl_ = glass.grf.compute(cl_, t1, t2) assert gl[0] == gl0 - compare.assert_allclose(gl_[1 : gl.shape[0]], gl[1:]) + xp_assert_close(gl_[1 : gl.shape[0]], gl[1:]) def test_monopole( cl: FloatArray, - compare: type[Compare], rng: np.random.Generator, ) -> None: t = glass.grf.Lognormal() @@ -108,10 +108,10 @@ def test_monopole( gl, cl_out, _ = glass.grf.solve(cl, t, monopole=None, gltol=1e-8) assert gl[0] != 0.0 - compare.assert_allclose(cl_out[0], cl[0]) + xp_assert_close(cl_out[0], cl[0]) gl, cl_out, _ = glass.grf.solve(cl, t, monopole=gl0, gltol=1e-8) assert gl[0] == gl0 with pytest.raises(AssertionError, match="Not equal to tolerance"): - compare.assert_allclose(cl_out[0], cl[0]) + xp_assert_close(cl_out[0], cl[0]) diff --git a/tests/core/grf/test_transformations.py b/tests/core/grf/test_transformations.py index 1e8b88e9..073781a2 100644 --- a/tests/core/grf/test_transformations.py +++ b/tests/core/grf/test_transformations.py @@ -2,6 +2,8 @@ from typing import TYPE_CHECKING +from array_api_extra._lib._testing import xp_assert_equal + import glass.grf if TYPE_CHECKING: @@ -11,14 +13,13 @@ from tests.fixtures.helper_classes import Compare -def test_normal(compare: type[Compare], urng: UnifiedGenerator) -> None: +def test_normal(urng: UnifiedGenerator) -> None: t = glass.grf.Normal() x = urng.standard_normal(10) - compare.assert_array_equal(t(x, 1.0), x) + xp_assert_equal(t(x, 1.0), x) def test_lognormal( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -27,11 +28,10 @@ def test_lognormal( t = glass.grf.Lognormal(lam) x = urng.standard_normal(10) y = lam * xp.expm1(x - var / 2) - compare.assert_array_equal(t(x, var), y) + xp_assert_equal(t(x, var), y) def test_sqnormal( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -41,20 +41,19 @@ def test_sqnormal( t = glass.grf.SquaredNormal(a, lam) x = urng.standard_normal(10) y = lam * ((x - a) ** 2 - 1) - compare.assert_array_equal(t(x, var), y) + xp_assert_equal(t(x, var), y) def test_normal_normal( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: t1 = glass.grf.Normal() t2 = glass.grf.Normal() x = urng.random(10) - compare.assert_array_equal(glass.grf.corr(t1, t2, x), x) - compare.assert_array_equal(glass.grf.icorr(t1, t2, x), x) - compare.assert_array_equal(glass.grf.dcorr(t1, t2, x), xp.ones_like(x)) + xp_assert_equal(glass.grf.corr(t1, t2, x), x) + xp_assert_equal(glass.grf.icorr(t1, t2, x), x) + xp_assert_equal(glass.grf.dcorr(t1, t2, x), xp.ones_like(x)) def test_lognormal_lognormal( @@ -72,9 +71,9 @@ def test_lognormal_lognormal( y = lam1 * lam2 * xp.expm1(x) dy = lam1 * lam2 * xp.exp(x) - compare.assert_array_equal(glass.grf.corr(t1, t2, x), y) + xp_assert_equal(glass.grf.corr(t1, t2, x), y) compare.assert_array_almost_equal_nulp(glass.grf.icorr(t1, t2, y), x) - compare.assert_array_equal(glass.grf.dcorr(t1, t2, x), dy) + xp_assert_equal(glass.grf.dcorr(t1, t2, x), dy) def test_lognormal_normal( @@ -91,9 +90,9 @@ def test_lognormal_normal( y = lam1 * x dy = lam1 * xp.ones_like(x) - compare.assert_array_equal(glass.grf.corr(t1, t2, x), y) + xp_assert_equal(glass.grf.corr(t1, t2, x), y) compare.assert_array_almost_equal_nulp(glass.grf.icorr(t1, t2, y), x) - compare.assert_array_equal(glass.grf.dcorr(t1, t2, x), dy) + xp_assert_equal(glass.grf.dcorr(t1, t2, x), dy) def test_sqnormal_sqnormal( @@ -114,6 +113,6 @@ def test_sqnormal_sqnormal( y = 2 * lam1 * lam2 * x * (x + 2 * a1 * a2) dy = 4 * lam1 * lam2 * (x + a1 * a2) - compare.assert_array_equal(glass.grf.corr(t1, t2, x), y) + xp_assert_equal(glass.grf.corr(t1, t2, x), y) compare.assert_array_almost_equal_nulp(glass.grf.icorr(t1, t2, y), x, nulp=8) - compare.assert_array_equal(glass.grf.dcorr(t1, t2, x), dy) + xp_assert_equal(glass.grf.dcorr(t1, t2, x), dy) diff --git a/tests/core/test_algorithm.py b/tests/core/test_algorithm.py index bbf30750..8968f692 100644 --- a/tests/core/test_algorithm.py +++ b/tests/core/test_algorithm.py @@ -5,6 +5,7 @@ import pytest import array_api_extra as xpx +from array_api_extra._lib._testing import xp_assert_close import glass.algorithm @@ -18,7 +19,6 @@ def test_nnls( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -40,7 +40,7 @@ def test_nnls( x, tol=500 * xp.linalg.matrix_norm(a, ord=1) * xp.finfo(xp.float64).eps, ) - compare.assert_allclose(res, b, rtol=0.0, atol=1e-10) + xp_assert_close(res, b, rtol=0.0, atol=1e-10) # check matrix and vector's shape @@ -56,7 +56,6 @@ def test_nnls( def test_cov_clip( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -77,10 +76,10 @@ def test_cov_clip( # make sure all eigenvalues are positive h = xp.max(xp.linalg.eigvalsh(a)) - compare.assert_allclose(xp.linalg.eigvalsh(cov), h) + xp_assert_close(xp.linalg.eigvalsh(cov), h) -def test_nearcorr(compare: type[Compare], xp: ModuleType) -> None: +def test_nearcorr(xp: ModuleType) -> None: # from Higham (2002) a = xp.asarray( [ @@ -98,11 +97,11 @@ def test_nearcorr(compare: type[Compare], xp: ModuleType) -> None: ) x = glass.algorithm.nearcorr(a) - compare.assert_allclose(x, b, atol=1e-4) + xp_assert_close(x, b, atol=1e-4) # explicit tolerance x = glass.algorithm.nearcorr(a, tol=1e-10) - compare.assert_allclose(x, b, atol=1e-4) + xp_assert_close(x, b, atol=1e-4) # no iterations with pytest.warns( @@ -110,7 +109,7 @@ def test_nearcorr(compare: type[Compare], xp: ModuleType) -> None: match="Nearest correlation matrix not found in 0 iterations", ): x = glass.algorithm.nearcorr(a, niter=0) - compare.assert_allclose(x, a) + xp_assert_close(x, a) # non-square matrix should raise with pytest.raises(ValueError, match="non-square matrix"): diff --git a/tests/core/test_arraytools.py b/tests/core/test_arraytools.py index 7c330de3..ca156bd9 100644 --- a/tests/core/test_arraytools.py +++ b/tests/core/test_arraytools.py @@ -4,13 +4,13 @@ import pytest +from array_api_extra._lib._testing import xp_assert_close + import glass.arraytools if TYPE_CHECKING: from types import ModuleType - from tests.fixtures.helper_classes import Compare - def test_broadcast_first(xp: ModuleType) -> None: a = xp.ones((2, 3, 4)) @@ -59,7 +59,7 @@ def test_broadcast_leading_axes(xp: ModuleType) -> None: assert c_out.shape == (3, 4, 5, 6) -def test_ndinterp(compare: type[Compare], xp: ModuleType) -> None: +def test_ndinterp(xp: ModuleType) -> None: # test 1d interpolation xq = xp.asarray([0, 1, 2, 3, 4]) @@ -68,17 +68,17 @@ def test_ndinterp(compare: type[Compare], xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == () - compare.assert_allclose(y, 1.15, atol=1e-15) + xp_assert_close(y, 1.15, atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (3,) - compare.assert_allclose(y, [1.15, 1.25, 1.35], atol=1e-15) + xp_assert_close(y, [1.15, 1.25, 1.35], atol=1e-15) x = xp.asarray([[0.5, 1.5], [2.5, 3.5]]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 2) - compare.assert_allclose(y, [[1.15, 1.25], [1.35, 1.45]], atol=1e-15) + xp_assert_close(y, [[1.15, 1.25], [1.35, 1.45]], atol=1e-15) # test n-dimensional interpolation in final axis @@ -87,17 +87,17 @@ def test_ndinterp(compare: type[Compare], xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2,) - compare.assert_allclose(y, [1.15, 2.15], atol=1e-15) + xp_assert_close(y, [1.15, 2.15], atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 3) - compare.assert_allclose(y, [[1.15, 1.25, 1.35], [2.15, 2.25, 2.35]], atol=1e-15) + xp_assert_close(y, [[1.15, 1.25, 1.35], [2.15, 2.25, 2.35]], atol=1e-15) x = xp.asarray([[0.5, 1.5], [2.5, 3.5]]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 2, 2) - compare.assert_allclose( + xp_assert_close( y, [[[1.15, 1.25], [1.35, 1.45]], [[2.15, 2.25], [2.35, 2.45]]], atol=1e-15, @@ -112,12 +112,12 @@ def test_ndinterp(compare: type[Compare], xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 1) - compare.assert_allclose(y, [[1.15], [2.15]], atol=1e-15) + xp_assert_close(y, [[1.15], [2.15]], atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 3, 1) - compare.assert_allclose( + xp_assert_close( y, [[[1.15], [1.25], [1.35]], [[2.15], [2.25], [2.35]]], atol=1e-15, @@ -126,7 +126,7 @@ def test_ndinterp(compare: type[Compare], xp: ModuleType) -> None: x = xp.asarray([[0.5, 1.5, 2.5, 3.5], [3.5, 2.5, 1.5, 0.5], [0.5, 3.5, 1.5, 2.5]]) y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 3, 4, 1) - compare.assert_allclose( + xp_assert_close( y, [ [ @@ -144,7 +144,7 @@ def test_ndinterp(compare: type[Compare], xp: ModuleType) -> None: ) -def test_trapezoid_product(compare: type[Compare], xp: ModuleType) -> None: +def test_trapezoid_product(xp: ModuleType) -> None: x1 = xp.linspace(0, 2, 100) f1 = xp.full_like(x1, 2.0) @@ -153,24 +153,24 @@ def test_trapezoid_product(compare: type[Compare], xp: ModuleType) -> None: s = glass.arraytools.trapezoid_product((x1, f1), (x2, f2)) - compare.assert_allclose(s, 1.0) + xp_assert_close(s, 1.0) -def test_cumulative_trapezoid(compare: type[Compare], xp: ModuleType) -> None: +def test_cumulative_trapezoid(xp: ModuleType) -> None: # 1D f and x f = xp.asarray([1, 2, 3, 4]) x = xp.asarray([0, 1, 2, 3]) ct = glass.arraytools.cumulative_trapezoid(f, x) - compare.assert_allclose(ct, xp.asarray([0.0, 1.5, 4.0, 7.5])) + xp_assert_close(ct, xp.asarray([0.0, 1.5, 4.0, 7.5])) # 2D f and 1D x f = xp.asarray([[1, 4, 9, 16], [2, 3, 5, 7]]) x = xp.asarray([0, 1, 2.5, 4]) ct = glass.arraytools.cumulative_trapezoid(f, x) - compare.assert_allclose( + xp_assert_close( ct, xp.asarray([[0.0, 2.5, 12.25, 31.0], [0.0, 2.5, 8.5, 17.5]]), ) diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index d5a499f2..8ae98465 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -5,6 +5,8 @@ import pytest +from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal + import glass import glass.fields import glass.healpix as hp @@ -16,7 +18,6 @@ from pytest_mock import MockerFixture from glass._types import AngularPowerSpectra, UnifiedGenerator - from tests.fixtures.helper_classes import Compare HAVE_JAX = importlib.util.find_spec("jax") is not None @@ -140,7 +141,7 @@ def test_iternorm(xp: ModuleType) -> None: @pytest.mark.skipif(not HAVE_JAX, reason="test requires jax") -def test_cls2cov_jax(compare: type[Compare], jnp: ModuleType) -> None: +def test_cls2cov_jax(jnp: ModuleType) -> None: nl, nf, nc = 3, 3, 2 generator = glass.cls2cov( @@ -173,17 +174,17 @@ def test_cls2cov_jax(compare: type[Compare], jnp: ModuleType) -> None: assert cov3.dtype == jnp.float64 # cov1 has the expected value for the first iteration (different to cov1_copy) - compare.assert_allclose(cov1[:, 0], jnp.asarray([0.5, 0.25, 0.15])) + xp_assert_close(cov1[:, 0], jnp.asarray([0.5, 0.25, 0.15])) # The copies should not be equal with pytest.raises(AssertionError, match="Not equal to tolerance"): - compare.assert_allclose(cov1, cov2) + xp_assert_close(cov1, cov2) with pytest.raises(AssertionError, match="Not equal to tolerance"): - compare.assert_allclose(cov2, cov3) + xp_assert_close(cov2, cov3) -def test_cls2cov_no_jax(compare: type[Compare], xpb: ModuleType) -> None: +def test_cls2cov_no_jax(xpb: ModuleType) -> None: # check output values and shape nl, nf, nc = 3, 2, 2 @@ -199,9 +200,9 @@ def test_cls2cov_no_jax(compare: type[Compare], xpb: ModuleType) -> None: assert cov.shape == (nl, nc + 1) assert cov.dtype == xpb.float64 - compare.assert_allclose(cov[:, 0], xpb.asarray([0.5, 0.25, 0.15])) - compare.assert_allclose(cov[:, 1], 0) - compare.assert_allclose(cov[:, 2], 0) + xp_assert_close(cov[:, 0], xpb.asarray([0.5, 0.25, 0.15])) + xp_assert_close(cov[:, 1], 0) + xp_assert_close(cov[:, 2], 0) # test negative value error @@ -257,19 +258,19 @@ def test_cls2cov_no_jax(compare: type[Compare], xpb: ModuleType) -> None: assert cov3.dtype == xpb.float64 # cov1|2|3 reuse the same data, so should all equal the third result - compare.assert_allclose(cov1[:, 0], xpb.asarray([0.45, 0.25, 0.15])) - compare.assert_allclose(cov1, cov2) - compare.assert_allclose(cov2, cov3) + xp_assert_close(cov1[:, 0], xpb.asarray([0.45, 0.25, 0.15])) + xp_assert_close(cov1, cov2) + xp_assert_close(cov2, cov3) # cov1 has the expected value for the first iteration (different to cov1_copy) - compare.assert_allclose(cov1_copy[:, 0], xpb.asarray([0.5, 0.25, 0.15])) + xp_assert_close(cov1_copy[:, 0], xpb.asarray([0.5, 0.25, 0.15])) # The copies should not be equal with pytest.raises(AssertionError, match="Not equal to tolerance"): - compare.assert_allclose(cov1_copy, cov2_copy) + xp_assert_close(cov1_copy, cov2_copy) with pytest.raises(AssertionError, match="Not equal to tolerance"): - compare.assert_allclose(cov2_copy, cov3) + xp_assert_close(cov2_copy, cov3) def test_lognormal_gls(xp: ModuleType) -> None: @@ -294,7 +295,7 @@ def test_lognormal_gls(xp: ModuleType) -> None: assert out[2].shape[0] == 3 -def test_discretized_cls(compare: type[Compare], xp: ModuleType) -> None: +def test_discretized_cls(xp: ModuleType) -> None: # empty cls result = glass.discretized_cls([]) @@ -339,10 +340,10 @@ def test_discretized_cls(compare: type[Compare], xp: ModuleType) -> None: for cl in result: n = min(cl.shape[0], pw.shape[0]) # ty: ignore[unresolved-attribute] expected = xp.ones(n) * pw[:n] ** 2 - compare.assert_allclose(cl[:n], expected) + xp_assert_close(cl[:n], expected) -def test_effective_cls(compare: type[Compare], xp: ModuleType) -> None: +def test_effective_cls(xp: ModuleType) -> None: # empty cls result = glass.effective_cls([], xp.asarray([])) @@ -371,7 +372,7 @@ def test_effective_cls(compare: type[Compare], xp: ModuleType) -> None: result = glass.effective_cls(cls, weights1, lmax=5) assert result.shape == (1, 1, 6) - compare.assert_allclose(result[..., 6:], 0) + xp_assert_close(result[..., 6:], 0) # check with weights1 and weights2 and weights1 is weights2 @@ -379,7 +380,7 @@ def test_effective_cls(compare: type[Compare], xp: ModuleType) -> None: assert result.shape == (1, 1, 15) -def test_generate_grf(compare: type[Compare], xp: ModuleType) -> None: +def test_generate_grf(xp: ModuleType) -> None: gls: AngularPowerSpectra = [xp.asarray([1.0, 0.5, 0.1])] nside = 4 ncorr = 1 @@ -402,7 +403,7 @@ def test_generate_grf(compare: type[Compare], xp: ModuleType) -> None: assert new_gaussian_fields[0].shape == (hp.nside2npix(nside),) - compare.assert_allclose(new_gaussian_fields[0], gaussian_fields[0]) + xp_assert_close(new_gaussian_fields[0], gaussian_fields[0]) with pytest.raises(ValueError, match="all gls are empty"): list(glass.fields._generate_grf([xp.asarray([])], nside)) @@ -420,7 +421,7 @@ def test_generate_lognormal(xp: ModuleType) -> None: next(result) -def test_generate(compare: type[Compare], xp: ModuleType) -> None: +def test_generate(xp: ModuleType) -> None: # shape mismatch error fields = [lambda x, var: x, lambda x, var: x] # noqa: ARG005 @@ -455,10 +456,10 @@ def test_generate(compare: type[Compare], xp: ModuleType) -> None: result = list(glass.generate(fields, gls, nside=nside)) - compare.assert_allclose(result[1], result[0] ** 2, atol=1e-05) + xp_assert_close(result[1], result[0] ** 2, atol=1e-05) -def test_getcl(compare: type[Compare], xp: ModuleType) -> None: +def test_getcl(xp: ModuleType) -> None: # make a mock Cls array with the index pairs as entries cls: AngularPowerSpectra = [ xp.asarray([i, j], dtype=xp.float64) @@ -470,19 +471,19 @@ def test_getcl(compare: type[Compare], xp: ModuleType) -> None: for j in range(10): result = glass.getcl(cls, i, j) expected = xp.asarray([min(i, j), max(i, j)], dtype=xp.float64) - compare.assert_allclose(xp.sort(result), expected) + xp_assert_close(xp.sort(result), expected) # check slicing result = glass.getcl(cls, i, j, lmax=0) expected = xp.asarray([max(i, j)], dtype=xp.float64) assert result.shape[0] == 1 - compare.assert_allclose(result, expected) + xp_assert_close(result, expected) # check padding result = glass.getcl(cls, i, j, lmax=50) expected = xp.zeros((49,), dtype=xp.float64) assert result.shape[0] == 51 - compare.assert_allclose(result[2:], expected) + xp_assert_close(result[2:], expected) def test_is_inv_triangle_number(not_triangle_numbers: list[int]) -> None: @@ -503,7 +504,7 @@ def test_nfields_from_nspectra(not_triangle_numbers: list[int]) -> None: glass.nfields_from_nspectra(t) -def test_enumerate_spectra(compare: type[Compare], xp: ModuleType) -> None: +def test_enumerate_spectra(xp: ModuleType) -> None: n = 100 tn = n * (n + 1) // 2 @@ -518,21 +519,19 @@ def test_enumerate_spectra(compare: type[Compare], xp: ModuleType) -> None: # go through expected indices and values and compare for k, (i, j) in enumerate(indices): - compare.assert_allclose(next(it), (i, j, k)) + xp_assert_close(next(it), (i, j, k)) # make sure iterator is exhausted with pytest.raises(StopIteration): next(it) -def test_spectra_indices(compare: type[Compare], xp: ModuleType) -> None: - compare.assert_array_equal(glass.spectra_indices(0), xp.zeros((0, 2))) - compare.assert_array_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2))) - compare.assert_array_equal(glass.spectra_indices(1, xp=xp), [[0, 0]]) - compare.assert_array_equal( - glass.spectra_indices(2, xp=xp), [[0, 0], [1, 1], [1, 0]] - ) - compare.assert_array_equal( +def test_spectra_indices(xp: ModuleType) -> None: + xp_assert_equal(glass.spectra_indices(0), xp.zeros((0, 2))) + xp_assert_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2))) + xp_assert_equal(glass.spectra_indices(1, xp=xp), [[0, 0]]) + xp_assert_equal(glass.spectra_indices(2, xp=xp), [[0, 0], [1, 1], [1, 0]]) + xp_assert_equal( glass.spectra_indices(3, xp=xp), [[0, 0], [1, 1], [1, 0], [2, 2], [2, 1], [2, 0]], ) @@ -564,7 +563,10 @@ def test_lognormal_fields(xp: ModuleType) -> None: assert [f.lamda for f in fields] == [1, 4, 9] -def test_compute_gaussian_spectra(mocker: MockerFixture, xp: ModuleType) -> None: +def test_compute_gaussian_spectra( + mocker: MockerFixture, + xp: ModuleType, +) -> None: mock = mocker.patch("glass.grf.compute") fields = [glass.grf.Normal(), glass.grf.Normal()] @@ -583,7 +585,10 @@ def test_compute_gaussian_spectra(mocker: MockerFixture, xp: ModuleType) -> None glass.compute_gaussian_spectra(fields, spectra[:2]) -def test_compute_gaussian_spectra_gh639(mocker: MockerFixture, xp: ModuleType) -> None: +def test_compute_gaussian_spectra_gh639( + mocker: MockerFixture, + xp: ModuleType, +) -> None: """Test compute_gaussian_spectra() with an empty input.""" mock = mocker.patch("glass.grf.compute") @@ -599,7 +604,10 @@ def test_compute_gaussian_spectra_gh639(mocker: MockerFixture, xp: ModuleType) - assert gls[2].shape[0] == 0 -def test_solve_gaussian_spectra(mocker: MockerFixture, xp: ModuleType) -> None: +def test_solve_gaussian_spectra( + mocker: MockerFixture, + xp: ModuleType, +) -> None: mock = mocker.patch("glass.grf.solve") result = mock.return_value @@ -640,41 +648,38 @@ def test_solve_gaussian_spectra(mocker: MockerFixture, xp: ModuleType) -> None: glass.solve_gaussian_spectra(fields, spectra[:2]) -def test_glass_to_healpix_spectra(compare: type[Compare]) -> None: +def test_glass_to_healpix_spectra() -> None: inp = [11, 22, 21, 33, 32, 31, 44, 43, 42, 41] out = glass.glass_to_healpix_spectra(inp) - compare.assert_array_equal(out, [11, 22, 33, 44, 21, 32, 43, 31, 42, 41]) + xp_assert_equal(out, [11, 22, 33, 44, 21, 32, 43, 31, 42, 41]) -def test_healpix_to_glass_spectra(compare: type[Compare]) -> None: +def test_healpix_to_glass_spectra() -> None: inp = [11, 22, 33, 44, 21, 32, 43, 31, 42, 41] out = glass.healpix_to_glass_spectra(inp) - compare.assert_array_equal(out, [11, 22, 21, 33, 32, 31, 44, 43, 42, 41]) + xp_assert_equal(out, [11, 22, 21, 33, 32, 31, 44, 43, 42, 41]) -def test_glass_to_healpix_alm(compare: type[Compare], xp: ModuleType) -> None: +def test_glass_to_healpix_alm(xp: ModuleType) -> None: inp = xp.asarray([00, 10, 11, 20, 21, 22, 30, 31, 32, 33], dtype=xp.complex128) out = glass.fields._glass_to_healpix_alm(inp) - compare.assert_array_equal( + xp_assert_equal( out, xp.asarray([00, 10, 20, 30, 11, 21, 31, 22, 32, 33], dtype=xp.complex128), ) -def test_lognormal_shift_hilbert2011(compare: type[Compare]) -> None: +def test_lognormal_shift_hilbert2011() -> None: zs = [0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0] shifts = [glass.lognormal_shift_hilbert2011(z) for z in zs] # computed by hand check = [0.0103031, 0.02975, 0.0538781, 0.0792, 0.103203, 0.12435, 0.142078, 0.1568] - compare.assert_allclose(shifts, check, atol=1e-4, rtol=1e-4) + xp_assert_close(shifts, check, atol=1e-4, rtol=1e-4) -def test_cov_from_spectra( - compare: type[Compare], - xp: ModuleType, -) -> None: +def test_cov_from_spectra(xp: ModuleType) -> None: spectra: AngularPowerSpectra = [ xp.asarray(x) for x in [ @@ -687,7 +692,7 @@ def test_cov_from_spectra( ] ] - compare.assert_array_equal( + xp_assert_equal( glass.cov_from_spectra(spectra), [ [ @@ -713,7 +718,7 @@ def test_cov_from_spectra( ], ) - compare.assert_array_equal( + xp_assert_equal( glass.cov_from_spectra(spectra, lmax=1), [ [ @@ -729,7 +734,7 @@ def test_cov_from_spectra( ], ) - compare.assert_array_equal( + xp_assert_equal( glass.cov_from_spectra(spectra, lmax=4), [ [ @@ -771,7 +776,7 @@ def test_check_posdef_spectra(xp: ModuleType) -> None: [1.0, 1.0, 1.0], [0.9, 0.9, 0.9], ] - ] + ], ) # semidef spectra assert glass.check_posdef_spectra( @@ -782,7 +787,7 @@ def test_check_posdef_spectra(xp: ModuleType) -> None: [1.0, 1.0, 0.0], [0.9, 1.0, 0.0], ] - ] + ], ) # indef spectra assert not glass.check_posdef_spectra( @@ -793,7 +798,7 @@ def test_check_posdef_spectra(xp: ModuleType) -> None: [1.0, 1.0, 1.0], [1.1, 1.1, 1.1], ] - ] + ], ) diff --git a/tests/core/test_galaxies.py b/tests/core/test_galaxies.py index 2bb228f6..3bf38638 100644 --- a/tests/core/test_galaxies.py +++ b/tests/core/test_galaxies.py @@ -4,6 +4,8 @@ import pytest +from array_api_extra._lib._testing import xp_assert_equal + import glass if TYPE_CHECKING: @@ -12,10 +14,12 @@ from pytest_mock import MockerFixture from glass._types import FloatArray, UnifiedGenerator - from tests.fixtures.helper_classes import Compare -def test_redshifts(mocker: MockerFixture, xp: ModuleType) -> None: +def test_redshifts( + mocker: MockerFixture, + xp: ModuleType, +) -> None: # create a mock radial window function w = mocker.Mock() w.za = xp.linspace(0.0, 1.0, 20) @@ -32,7 +36,10 @@ def test_redshifts(mocker: MockerFixture, xp: ModuleType) -> None: assert z.shape == (10,) -def test_redshifts_from_nz(urng: UnifiedGenerator, xp: ModuleType) -> None: +def test_redshifts_from_nz( + urng: UnifiedGenerator, + xp: ModuleType, +) -> None: # test sampling redshifts = glass.redshifts_from_nz( @@ -199,7 +206,6 @@ def test_galaxy_shear( def test_gaussian_phz( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -212,13 +218,13 @@ def test_gaussian_phz( phz = glass.gaussian_phz(z, sigma_0) - compare.assert_array_equal(z, phz) + xp_assert_equal(z, phz) # test with rng phz = glass.gaussian_phz(z, sigma_0, rng=urng) - compare.assert_array_equal(z, phz) + xp_assert_equal(z, phz) # case: truncated normal @@ -264,7 +270,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - compare.assert_array_equal(z, phz) + xp_assert_equal(z, phz) # case: scalar redshift, array sigma_0 @@ -275,7 +281,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - compare.assert_array_equal(z, phz) + xp_assert_equal(z, phz) # case: array redshift, array sigma_0 @@ -286,7 +292,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (11, 10) - compare.assert_array_equal(xp.broadcast_to(z, (11, 10)), phz) + xp_assert_equal(xp.broadcast_to(z, (11, 10)), phz) # shape mismatch diff --git a/tests/core/test_harmonics.py b/tests/core/test_harmonics.py index 91d60101..b812177b 100644 --- a/tests/core/test_harmonics.py +++ b/tests/core/test_harmonics.py @@ -4,15 +4,15 @@ import pytest +from array_api_extra._lib._testing import xp_assert_close + import glass.harmonics if TYPE_CHECKING: from types import ModuleType - from tests.fixtures.helper_classes import Compare - -def test_multalm(compare: type[Compare], xp: ModuleType) -> None: +def test_multalm(xp: ModuleType) -> None: # check output values and shapes alm = xp.asarray([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) @@ -22,9 +22,9 @@ def test_multalm(compare: type[Compare], xp: ModuleType) -> None: result = glass.harmonics.multalm(alm, bl) expected_result = xp.asarray([2.0, 1.0, 1.5, 4.0, 5.0, 6.0]) - compare.assert_allclose(result, expected_result) + xp_assert_close(result, expected_result) with pytest.raises(AssertionError, match="Not equal to tolerance"): - compare.assert_allclose(alm_copy, result) + xp_assert_close(alm_copy, result) # multiple with 1s @@ -32,7 +32,7 @@ def test_multalm(compare: type[Compare], xp: ModuleType) -> None: bl = xp.ones(3) result = glass.harmonics.multalm(alm, bl) - compare.assert_allclose(result, alm) + xp_assert_close(result, alm) # multiple with 0s @@ -41,7 +41,7 @@ def test_multalm(compare: type[Compare], xp: ModuleType) -> None: result = glass.harmonics.multalm(alm, bl) expected_result = xp.asarray([0.0, 2.0, 3.0, 0.0, 0.0, 0.0]) - compare.assert_allclose(result, expected_result) + xp_assert_close(result, expected_result) # empty arrays @@ -49,4 +49,4 @@ def test_multalm(compare: type[Compare], xp: ModuleType) -> None: bl = xp.asarray([]) result = glass.harmonics.multalm(alm, bl) - compare.assert_allclose(result, alm) + xp_assert_close(result, alm) diff --git a/tests/core/test_healpix.py b/tests/core/test_healpix.py index 230a8a0c..b4ddfde5 100644 --- a/tests/core/test_healpix.py +++ b/tests/core/test_healpix.py @@ -9,6 +9,8 @@ import numpy as np import pytest +from array_api_extra._lib._testing import xp_assert_equal + import glass.healpix as hp from glass import _rng @@ -16,7 +18,7 @@ from types import ModuleType from glass._types import UnifiedGenerator - from tests.fixtures.helper_classes import Compare, HealpixInputs + from tests.fixtures.helper_classes import HealpixInputs HAVE_ARRAY_API_STRICT = importlib.util.find_spec("array_api_strict") is not None @@ -31,7 +33,6 @@ ], ) def test_alm2map_individual( - compare: type[Compare], healpix_inputs: type[HealpixInputs], pixwin: bool, # noqa: FBT001 pol: bool, # noqa: FBT001 @@ -39,7 +40,7 @@ def test_alm2map_individual( ) -> None: """Compare ``glass.healpix.alm2map`` against ``healpy.alm2map``.""" alm = healpix_inputs.alm(rng=urng) - compare.assert_array_equal( + xp_assert_equal( healpy.alm2map( np.asarray(alm), healpix_inputs.nside, @@ -67,7 +68,6 @@ def test_alm2map_individual( ], ) def test_alm2map_sequence( - compare: type[Compare], healpix_inputs: type[HealpixInputs], pixwin: bool, # noqa: FBT001 pol: bool, # noqa: FBT001 @@ -91,12 +91,11 @@ def test_alm2map_sequence( pixwin=pixwin, pol=pol, ) - compare.assert_array_equal(old, new) + xp_assert_equal(old, new) @pytest.mark.parametrize("spin", [1, 2]) def test_alm2map_spin( - compare: type[Compare], healpix_inputs: type[HealpixInputs], spin: int, urng: UnifiedGenerator, @@ -114,18 +113,17 @@ def test_alm2map_spin( assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - compare.assert_array_equal(old[i], new[i]) + xp_assert_equal(old[i], new[i]) def test_almxfl( - compare: type[Compare], healpix_inputs: type[HealpixInputs], urng: UnifiedGenerator, ) -> None: """Compare ``glass.healpix.almxfl`` against ``healpy.almxfl``.""" alm = healpix_inputs.alm(rng=urng) fl = healpix_inputs.fl(rng=urng) - compare.assert_array_equal( + xp_assert_equal( healpy.almxfl(alm, fl), hp.almxfl(alm, fl), ) @@ -139,7 +137,6 @@ def test_almxfl( ], ) def test_ang2pix( # noqa: PLR0913 - compare: type[Compare], healpix_inputs: type[HealpixInputs], lonlat: bool, # noqa: FBT001 max_phi: float, @@ -152,7 +149,7 @@ def test_ang2pix( # noqa: PLR0913 phis = healpix_inputs.latitudes(max_phi, rng=urng) old = healpix.ang2pix(healpix_inputs.nside, thetas, phis, lonlat=lonlat) new = hp.ang2pix(healpix_inputs.nside, thetas, phis, lonlat=lonlat, xp=xp) - compare.assert_array_equal(old, new) + xp_assert_equal(old, new) @pytest.mark.parametrize( @@ -163,7 +160,6 @@ def test_ang2pix( # noqa: PLR0913 ], ) def test_ang2vec( # noqa: PLR0913 - compare: type[Compare], healpix_inputs: type[HealpixInputs], lonlat: bool, # noqa: FBT001 max_phi: float, @@ -179,7 +175,7 @@ def test_ang2vec( # noqa: PLR0913 assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - compare.assert_array_equal(old[i], new[i]) + xp_assert_equal(old[i], new[i]) def test_get_nside( @@ -201,7 +197,6 @@ def test_get_nside( ], ) def test_map2alm_individual( - compare: type[Compare], healpix_inputs: type[HealpixInputs], pol: bool, # noqa: FBT001 urng: UnifiedGenerator, @@ -209,7 +204,7 @@ def test_map2alm_individual( ) -> None: """Compare ``glass.healpix.map2alm`` against ``healpy.map2alm``.""" kappa = healpix_inputs.kappa(rng=urng) - compare.assert_array_equal( + xp_assert_equal( healpy.map2alm( np.asarray(kappa), lmax=healpix_inputs.lmax, @@ -235,7 +230,6 @@ def test_map2alm_individual( ], ) def test_map2alm_sequence( - compare: type[Compare], healpix_inputs: type[HealpixInputs], pol: bool, # noqa: FBT001 urng: UnifiedGenerator, @@ -245,7 +239,7 @@ def test_map2alm_sequence( kappa1 = healpix_inputs.kappa(rng=urng) kappa2 = healpix_inputs.kappa(rng=urng) kappa3 = healpix_inputs.kappa(rng=urng) - compare.assert_array_equal( + xp_assert_equal( healpy.map2alm( [np.asarray(kappa1), np.asarray(kappa2), np.asarray(kappa3)], lmax=healpix_inputs.lmax, @@ -261,16 +255,12 @@ def test_map2alm_sequence( ) -def test_npix2nside( - healpix_inputs: type[HealpixInputs], -) -> None: +def test_npix2nside(healpix_inputs: type[HealpixInputs]) -> None: """Compare ``glass.healpix.npix2nside`` against ``healpix.npix2nside``.""" assert healpix.npix2nside(healpix_inputs.npix) == hp.npix2nside(healpix_inputs.npix) -def test_nside2npix( - healpix_inputs: type[HealpixInputs], -) -> None: +def test_nside2npix(healpix_inputs: type[HealpixInputs]) -> None: """Compare ``glass.healpix.nside2npix`` against ``healpix.nside2npix``.""" assert healpix.nside2npix(healpix_inputs.nside) == hp.nside2npix( healpix_inputs.nside, @@ -279,7 +269,6 @@ def test_nside2npix( @pytest.mark.parametrize("pol", [False, True]) def test_pixwin( - compare: type[Compare], healpix_inputs: type[HealpixInputs], pol: bool, # noqa: FBT001 xp: ModuleType, @@ -294,12 +283,11 @@ def test_pixwin( assert len(old) == len(new) for i in range(len(old)): - compare.assert_array_equal(old[i], new[i]) + xp_assert_equal(old[i], new[i]) @pytest.mark.parametrize("thetas", [((20, 80)), ((30, 90))]) def test_query_strip_float64( - compare: type[Compare], healpix_inputs: type[HealpixInputs], thetas: tuple[int, int], xp: ModuleType, @@ -316,7 +304,7 @@ def test_query_strip_float64( old[healpy.query_strip(healpix_inputs.nside, *thetas)] = 0 new = xp.ones(healpix_inputs.npix) new *= 1 - hp.query_strip(healpix_inputs.nside, thetas, dtype=xp.float64, xp=xp) - compare.assert_array_equal(old, new) + xp_assert_equal(old, new) @pytest.mark.skipif(not HAVE_ARRAY_API_STRICT, reason="test requires array_api_strict") @@ -340,7 +328,6 @@ def test_query_strip_none( @pytest.mark.parametrize("lonlat", [False, True]) def test_randang( - compare: type[Compare], healpix_inputs: type[HealpixInputs], lonlat: bool, # noqa: FBT001 xp: ModuleType, @@ -368,12 +355,11 @@ def test_randang( assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - compare.assert_array_equal(old[i], new[i]) + xp_assert_equal(old[i], new[i]) @pytest.mark.parametrize("coord", ["CE", "GC"]) def test_rotate_map_pixel( - compare: type[Compare], coord: str, healpix_inputs: type[HealpixInputs], urng: UnifiedGenerator, @@ -384,7 +370,7 @@ def test_rotate_map_pixel( """ # noqa: D205 kappa = healpix_inputs.kappa(rng=urng) - compare.assert_array_equal( + xp_assert_equal( healpy.Rotator(coord=coord).rotate_map_pixel(np.asarray(kappa)), hp.Rotator(coord=coord).rotate_map_pixel(kappa), ) diff --git a/tests/core/test_lensing.py b/tests/core/test_lensing.py index 155093c2..8da68af5 100644 --- a/tests/core/test_lensing.py +++ b/tests/core/test_lensing.py @@ -5,6 +5,8 @@ import pytest +from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal + import glass import glass.healpix as hp from glass._array_api_utils import xp_additions as uxpx @@ -14,13 +16,9 @@ from glass._types import FloatArray, UnifiedGenerator from glass.cosmology import Cosmology - from tests.fixtures.helper_classes import Compare -def test_from_convergence( - compare: type[Compare], - urng: UnifiedGenerator, -) -> None: +def test_from_convergence(urng: UnifiedGenerator) -> None: """Add unit tests for :func:`glass.from_convergence`.""" # l_max = 100 # noqa: ERA001 n_side = 32 @@ -32,30 +30,30 @@ def test_from_convergence( # check with all False results = glass.from_convergence(kappa) # ty: ignore[no-matching-overload] - compare.assert_array_equal(results, ()) + xp_assert_equal(results, ()) # check all combinations of potential, deflection, shear being True results = glass.from_convergence(kappa, potential=True) - compare.assert_array_equal(len(results), 1) + xp_assert_equal(len(results), 1) results = glass.from_convergence(kappa, deflection=True) - compare.assert_array_equal(len(results), 1) + xp_assert_equal(len(results), 1) results = glass.from_convergence(kappa, shear=True) - compare.assert_array_equal(len(results), 1) + xp_assert_equal(len(results), 1) results = glass.from_convergence(kappa, potential=True, deflection=True) - compare.assert_array_equal(len(results), 2) + xp_assert_equal(len(results), 2) results = glass.from_convergence(kappa, potential=True, shear=True) - compare.assert_array_equal(len(results), 2) + xp_assert_equal(len(results), 2) results = glass.from_convergence(kappa, deflection=True, shear=True) - compare.assert_array_equal(len(results), 2) + xp_assert_equal(len(results), 2) results = glass.from_convergence(kappa, potential=True, deflection=True, shear=True) - compare.assert_array_equal(len(results), 3) + xp_assert_equal(len(results), 3) def test_shear_from_convergence() -> None: @@ -64,7 +62,6 @@ def test_shear_from_convergence() -> None: def test_multi_plane_matrix( - compare: type[Compare], cosmo: Cosmology, shells: list[glass.RadialWindow], urng: UnifiedGenerator, @@ -72,8 +69,8 @@ def test_multi_plane_matrix( ) -> None: mat = glass.multi_plane_matrix(shells, cosmo) - compare.assert_array_equal(mat, xp.tril(mat)) - compare.assert_array_equal(xp.triu(mat, k=1), 0) + xp_assert_equal(mat, xp.tril(mat)) + xp_assert_equal(xp.triu(mat, k=1), 0) convergence = glass.MultiPlaneConvergence(cosmo) @@ -86,11 +83,10 @@ def test_multi_plane_matrix( if convergence.kappa is not None: kappas.append(xp.asarray(convergence.kappa, copy=True)) - compare.assert_allclose(mat @ deltas, kappas) + xp_assert_close(mat @ deltas, kappas) def test_multi_plane_weights( - compare: type[Compare], cosmo: Cosmology, urng: UnifiedGenerator, shells: list[glass.RadialWindow], @@ -99,8 +95,8 @@ def test_multi_plane_weights( w_in = xp.eye(len(shells)) w_out = glass.multi_plane_weights(w_in, shells, cosmo) - compare.assert_array_equal(w_out, xp.triu(w_out, k=1)) - compare.assert_array_equal(xp.tril(w_out), 0) + xp_assert_equal(w_out, xp.triu(w_out, k=1)) + xp_assert_equal(xp.tril(w_out), 0) convergence = glass.MultiPlaneConvergence(cosmo) @@ -118,12 +114,11 @@ def test_multi_plane_weights( wmat = glass.multi_plane_weights(weights, shells, cosmo) - compare.assert_allclose(uxpx.einsum("ij,ik", wmat, deltas), kappa) + xp_assert_close(uxpx.einsum("ij,ik", wmat, deltas), kappa) @pytest.mark.parametrize("usecomplex", [True, False]) def test_deflect_nsew( - compare: type[Compare], usecomplex: bool, # noqa: FBT001 xp: ModuleType, ) -> None: @@ -140,19 +135,19 @@ def alpha( # north lon, lat = glass.deflect(0.0, 0.0, alpha(r, 0, usecomplex=usecomplex), xp=xp) - compare.assert_allclose([lon, lat], [0.0, d], atol=1e-15) + xp_assert_close([lon, lat], [0.0, d], atol=1e-15) # south lon, lat = glass.deflect(0.0, 0.0, alpha(-r, 0, usecomplex=usecomplex), xp=xp) - compare.assert_allclose([lon, lat], [0.0, -d], atol=1e-15) + xp_assert_close([lon, lat], [0.0, -d], atol=1e-15) # east lon, lat = glass.deflect(0.0, 0.0, alpha(0, r, usecomplex=usecomplex), xp=xp) - compare.assert_allclose([lon, lat], [-d, 0.0], atol=1e-15) + xp_assert_close([lon, lat], [-d, 0.0], atol=1e-15) # west lon, lat = glass.deflect(0.0, 0.0, alpha(0, -r, usecomplex=usecomplex), xp=xp) - compare.assert_allclose([lon, lat], [d, 0.0], atol=1e-15) + xp_assert_close([lon, lat], [d, 0.0], atol=1e-15) # At least one input is an array lon, lat = glass.deflect( @@ -160,15 +155,15 @@ def alpha( xp.asarray(0.0), alpha(0, -r, usecomplex=usecomplex), ) - compare.assert_allclose([lon, lat], [d, 0.0], atol=1e-15) + xp_assert_close([lon, lat], [d, 0.0], atol=1e-15) lon, lat = glass.deflect( xp.asarray([0.0, 0.0]), xp.asarray([0.0, 0.0]), alpha(0, -r, usecomplex=usecomplex), ) - compare.assert_allclose(lon, xp.asarray([d, d]), atol=1e-15) - compare.assert_allclose(lat, 0.0, atol=1e-15) + xp_assert_close(lon, xp.asarray([d, d]), atol=1e-15) + xp_assert_close(lat, 0.0, atol=1e-15) # No inputs are arrays and xp not provided with pytest.raises( @@ -179,7 +174,6 @@ def alpha( def test_deflect_many( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -197,4 +191,4 @@ def test_deflect_many( dotp = x * x_ + y * y_ + z * z_ - compare.assert_allclose(dotp, xp.cos(abs_alpha)) + xp_assert_close(dotp, xp.cos(abs_alpha)) diff --git a/tests/core/test_observations.py b/tests/core/test_observations.py index ca3be81a..7e0ec380 100644 --- a/tests/core/test_observations.py +++ b/tests/core/test_observations.py @@ -6,6 +6,8 @@ import numpy as np import pytest +from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal + import glass import glass.healpix as hp @@ -13,28 +15,27 @@ from types import ModuleType from glass._types import UnifiedGenerator - from tests.fixtures.helper_classes import Compare -def test_vmap_galactic_ecliptic(compare: type[Compare], xp: ModuleType) -> None: +def test_vmap_galactic_ecliptic(xp: ModuleType) -> None: """Add unit tests for :func:`glass.vmap_galactic_ecliptic`.""" n_side = 4 # check shape vmap = glass.vmap_galactic_ecliptic(n_side, xp=xp) - compare.assert_array_equal(vmap.shape[0], hp.nside2npix(n_side)) + xp_assert_equal(vmap.shape[0], hp.nside2npix(n_side)) # Test without xp vmap = glass.vmap_galactic_ecliptic(n_side) assert vmap.__array_namespace__().__name__ == "numpy" - compare.assert_array_equal(vmap.shape[0], hp.nside2npix(n_side)) + xp_assert_equal(vmap.shape[0], hp.nside2npix(n_side)) # no rotation vmap = glass.vmap_galactic_ecliptic(n_side, galactic=(0, 0), ecliptic=(0, 0), xp=xp) - compare.assert_array_equal(vmap, xp.zeros_like(vmap)) + xp_assert_equal(vmap, xp.zeros_like(vmap)) # check errors raised @@ -52,7 +53,6 @@ def test_vmap_galactic_ecliptic(compare: type[Compare], xp: ModuleType) -> None: def test_gaussian_nz( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -64,13 +64,13 @@ def test_gaussian_nz( # check passing in the norm nz = glass.gaussian_nz(z, mean, sigma, norm=0) - compare.assert_array_equal(nz, xp.zeros_like(nz)) + xp_assert_equal(nz, xp.zeros_like(nz)) # check the value of each entry is close to the norm norm = 1 nz = glass.gaussian_nz(z, mean, sigma, norm=norm) - compare.assert_allclose(xp.sum(nz) / nz.shape[0], norm, rtol=1e-2) + xp_assert_close(xp.sum(nz) / nz.shape[0], norm, rtol=1e-2) # check multidimensionality size @@ -83,7 +83,7 @@ def test_gaussian_nz( assert nz.shape == (z.shape[0], z.shape[0]) -def test_smail_nz(compare: type[Compare], xp: ModuleType) -> None: +def test_smail_nz(xp: ModuleType) -> None: """Add unit tests for :func:`glass.smail_nz`.""" alpha = 1 beta = 1 @@ -93,10 +93,10 @@ def test_smail_nz(compare: type[Compare], xp: ModuleType) -> None: # check passing in the norm pz = glass.smail_nz(z, mode, alpha, beta, norm=0) - compare.assert_array_equal(pz, xp.zeros_like(pz)) + xp_assert_equal(pz, xp.zeros_like(pz)) -def test_fixed_zbins_default_xp(compare: type[Compare]) -> None: +def test_fixed_zbins_default_xp() -> None: """Add unit tests for :func:`glass.fixed_zbins` with default xp.""" zmin = 0.0 zmax = 1.0 @@ -112,14 +112,14 @@ def test_fixed_zbins_default_xp(compare: type[Compare]) -> None: ) zbins = glass.fixed_zbins(zmin, zmax, nbins=nbins) assert len(zbins) == nbins - compare.assert_allclose(zbins, expected_zbins, rtol=1e-15) + xp_assert_close(zbins, expected_zbins, rtol=1e-15) # check dz input dz = 0.2 zbins = glass.fixed_zbins(zmin, zmax, dz=dz) assert len(zbins) == math.ceil((zmax - zmin) / dz) - compare.assert_allclose(zbins, expected_zbins, rtol=1e-15) + xp_assert_close(zbins, expected_zbins, rtol=1e-15) # check dz for spacing which results in a max value above zmax @@ -134,7 +134,7 @@ def test_fixed_zbins_default_xp(compare: type[Compare]) -> None: glass.fixed_zbins(zmin, zmax, nbins=nbins, dz=dz) -def test_fixed_zbins_xp_provided(compare: type[Compare], xp: ModuleType) -> None: +def test_fixed_zbins_xp_provided(xp: ModuleType) -> None: """Add unit tests for :func:`glass.fixed_zbins`.""" zmin = 0.0 zmax = 1.0 @@ -150,14 +150,14 @@ def test_fixed_zbins_xp_provided(compare: type[Compare], xp: ModuleType) -> None ) zbins = glass.fixed_zbins(zmin, zmax, nbins=nbins, xp=xp) assert len(zbins) == nbins - compare.assert_allclose(zbins, expected_zbins, rtol=1e-15) + xp_assert_close(zbins, expected_zbins, rtol=1e-15) # check dz input dz = 0.2 zbins = glass.fixed_zbins(zmin, zmax, dz=dz, xp=xp) assert len(zbins) == math.ceil((zmax - zmin) / dz) - compare.assert_allclose(zbins, expected_zbins, rtol=1e-15) + xp_assert_close(zbins, expected_zbins, rtol=1e-15) # check dz for spacing which results in a max value above zmax @@ -170,7 +170,7 @@ def test_fixed_zbins_xp_provided(compare: type[Compare], xp: ModuleType) -> None glass.fixed_zbins(zmin, zmax, nbins=nbins, dz=dz, xp=xp) -def test_equal_dens_zbins(compare: type[Compare], xp: ModuleType) -> None: +def test_equal_dens_zbins(xp: ModuleType) -> None: """Add unit tests for :func:`glass.equal_dens_zbins`.""" z = xp.linspace(0, 1, 11) nbins = 5 @@ -184,14 +184,14 @@ def test_equal_dens_zbins(compare: type[Compare], xp: ModuleType) -> None: ], ) zbins = glass.equal_dens_zbins(z, xp.ones_like(z), nbins) - compare.assert_allclose(zbins, expected_zbins, rtol=1e-15) + xp_assert_close(zbins, expected_zbins, rtol=1e-15) # check output shape assert len(zbins) == nbins -def test_tomo_nz_gausserr(compare: type[Compare], xp: ModuleType) -> None: +def test_tomo_nz_gausserr(xp: ModuleType) -> None: """Add unit tests for :func:`glass.tomo_nz_gausserr`.""" sigma_0 = 0.1 z = xp.linspace(0, 1, 11) @@ -200,7 +200,7 @@ def test_tomo_nz_gausserr(compare: type[Compare], xp: ModuleType) -> None: # check zeros returned binned_nz = glass.tomo_nz_gausserr(z, xp.zeros_like(z), sigma_0, zbins) - compare.assert_array_equal(binned_nz, xp.zeros_like(binned_nz)) + xp_assert_equal(binned_nz, xp.zeros_like(binned_nz)) # check the shape of the output diff --git a/tests/core/test_points.py b/tests/core/test_points.py index e870c51c..ac0006cf 100644 --- a/tests/core/test_points.py +++ b/tests/core/test_points.py @@ -6,9 +6,11 @@ import pytest import array_api_extra as xpx +from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal import glass import glass.healpix as hp +import glass.points from glass._array_api_utils import xp_additions as uxpx if TYPE_CHECKING: @@ -19,11 +21,10 @@ from pytest_mock import MockerFixture from glass._types import UnifiedGenerator - from tests.fixtures.helper_classes import Compare, DataTransformer + from tests.fixtures.helper_classes import DataTransformer def test_effective_bias( - compare: type[Compare], mocker: MockerFixture, xp: ModuleType, ) -> None: @@ -34,21 +35,20 @@ def test_effective_bias( z = xp.linspace(0, 1, 10) bz = xp.zeros((10,)) - compare.assert_allclose(glass.effective_bias(z, bz, w), 0.0) + xp_assert_close(glass.effective_bias(z, bz, w), 0.0) z = xp.zeros((10,)) bz = xp.full_like(z, 0.5) - compare.assert_allclose(glass.effective_bias(z, bz, w), 0.0) + xp_assert_close(glass.effective_bias(z, bz, w), 0.0) z = xp.linspace(0, 1, 10) bz = xp.full_like(z, 0.5) - compare.assert_allclose(glass.effective_bias(z, bz, w), 0.25) + xp_assert_close(glass.effective_bias(z, bz, w), 0.25) def test_linear_bias( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -57,25 +57,24 @@ def test_linear_bias( delta = xp.zeros((2, 2)) b = 2.0 - compare.assert_allclose(glass.linear_bias(delta, b), xp.zeros((2, 2))) + xp_assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) # test with 0 b delta = urng.normal(5, 1, size=(2, 2)) b = 0.0 - compare.assert_allclose(glass.linear_bias(delta, b), xp.zeros((2, 2))) + xp_assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) # compare with original implementation delta = urng.normal(5, 1, size=(2, 2)) b = 2.0 - compare.assert_allclose(glass.linear_bias(delta, b), b * delta) + xp_assert_close(glass.linear_bias(delta, b), b * delta) def test_loglinear_bias( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -84,30 +83,27 @@ def test_loglinear_bias( delta = xp.zeros((2, 2)) b = 2.0 - compare.assert_allclose(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) + xp_assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) # test with 0 b delta = urng.normal(5, 1, size=(2, 2)) b = 0.0 - compare.assert_allclose(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) + xp_assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) # compare with numpy implementation delta = urng.normal(5, 1, size=(2, 2)) b = 2.0 - compare.assert_allclose( + xp_assert_close( glass.loglinear_bias(delta, b), xp.expm1(b * xp.log1p(delta)), ) -def test_broadcast_inputs( - compare: type[Compare], - xp: ModuleType, -) -> None: +def test_broadcast_inputs(xp: ModuleType) -> None: bias_in = 0.8 delta_in = xp.zeros((3, 1, 12)) ngal_in = xp.asarray([1e-3, 2e-3]) @@ -123,11 +119,11 @@ def test_broadcast_inputs( assert dims == (3, 2) assert bias.shape == dims # ty: ignore[unresolved-attribute] assert xp.all(bias == bias_in) - compare.assert_array_equal(delta, xp.zeros_like(delta)) + xp_assert_equal(delta, xp.zeros_like(delta)) assert ngal.shape == dims # ty: ignore[unresolved-attribute] - compare.assert_array_equal(ngal[0, :], ngal_in) # ty: ignore[not-subscriptable] + xp_assert_equal(ngal[0, :], ngal_in) # ty: ignore[not-subscriptable] assert vis.shape == delta.shape # ty: ignore[unresolved-attribute] - compare.assert_array_equal(vis[0, 0, :], vis_in) # ty: ignore[not-subscriptable] + xp_assert_equal(vis[0, 0, :], vis_in) # ty: ignore[not-subscriptable] @pytest.mark.parametrize( @@ -139,7 +135,6 @@ def test_broadcast_inputs( ) def test_compute_density_contrast( bias_model: Callable[..., Any], - compare: type[Compare], xp: ModuleType, ) -> None: bias = 0.8 * xp.ones((3, 2)) @@ -155,7 +150,7 @@ def test_compute_density_contrast( ) assert n.shape[0] == delta.shape[-1] - compare.assert_array_equal(n, xp.zeros_like(n)) + xp_assert_equal(n, xp.zeros_like(n)) @pytest.mark.parametrize("remove_monopole", [False, True]) @@ -179,10 +174,7 @@ def test_compute_expected_count( assert xp.all(n == n[0]) -def test_apply_visibility( - compare: type[Compare], - xp: ModuleType, -) -> None: +def test_apply_visibility(xp: ModuleType) -> None: k = (1, 1) n_in = 24751.77674965 * xp.ones(12) vis = xp.tile(xp.repeat(xp.asarray([0.0, 1.0]), 6), (3, 2, 1)) @@ -193,24 +185,20 @@ def test_apply_visibility( vis, ) - compare.assert_array_equal(n[:6], xp.zeros_like(n[:6])) - compare.assert_array_equal(n[6:], n_in[6:]) + xp_assert_equal(n[:6], xp.zeros_like(n[:6])) + xp_assert_equal(n[6:], n_in[6:]) -def test_sample_number_galaxies( - compare: type[Compare], - xp: ModuleType, -) -> None: +def test_sample_number_galaxies(xp: ModuleType) -> None: n_in = xp.repeat(xp.asarray([0.0, 24751.77674965]), 6) n = glass.points._sample_number_galaxies(n_in) - compare.assert_array_equal(n[:6], xp.zeros_like(n[:6])) - compare.assert_allclose(n[6:], n_in[6:], atol=250) + xp_assert_equal(n[:6], xp.zeros_like(n[:6])) + xp_assert_close(n[6:], n_in[6:], atol=250) def test_sample_number_galaxies_rng( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -218,8 +206,8 @@ def test_sample_number_galaxies_rng( n = glass.points._sample_number_galaxies(n_in, rng=urng) - compare.assert_array_equal(n[:6], xp.zeros_like(n[:6])) - compare.assert_allclose(n[6:], n_in[6:], atol=250) + xp_assert_equal(n[:6], xp.zeros_like(n[:6])) + xp_assert_close(n[6:], n_in[6:], atol=250) def test_sample_galaxies_per_pixel( @@ -247,7 +235,6 @@ def test_sample_galaxies_per_pixel( def test_positions_from_delta( # noqa: PLR0915 - compare: type[Compare], data_transformer: DataTransformer, urng: UnifiedGenerator, xp: ModuleType, @@ -319,8 +306,8 @@ def test_positions_from_delta( # noqa: PLR0915 ) assert int(count) == count - compare.assert_allclose(lon, []) - compare.assert_allclose(lat, []) + xp_assert_close(lon, []) + xp_assert_close(lat, []) # case: large delta @@ -453,7 +440,6 @@ def test_uniform_positions( def test_position_weights( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -479,10 +465,10 @@ def test_position_weights( ) expected = bias * expected - compare.assert_allclose(weights, expected) + xp_assert_close(weights, expected) -def test_displace_arg_complex(compare: type[Compare], xp: ModuleType) -> None: +def test_displace_arg_complex(xp: ModuleType) -> None: """Test displace function with complex-valued displacement.""" d = 5.0 # deg r = d / 180 * math.pi @@ -493,22 +479,22 @@ def test_displace_arg_complex(compare: type[Compare], xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray(r + 0j)) - compare.assert_allclose([lon, lat], [0.0, d]) + xp_assert_close([lon, lat], [0.0, d]) # south lon, lat = glass.displace(lon0, lat0, xp.asarray(-r + 0j)) - compare.assert_allclose([lon, lat], [0.0, -d], atol=1e-15) + xp_assert_close([lon, lat], [0.0, -d], atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray(1j * r)) - compare.assert_allclose([lon, lat], [d, 0.0], atol=1e-15) + xp_assert_close([lon, lat], [d, 0.0], atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray(-1j * r)) - compare.assert_allclose([lon, lat], [-d, 0.0], atol=1e-15) + xp_assert_close([lon, lat], [-d, 0.0], atol=1e-15) -def test_displace_arg_real(compare: type[Compare], xp: ModuleType) -> None: +def test_displace_arg_real(xp: ModuleType) -> None: """Test displace function with real-valued argument.""" d = 5.0 # deg r = d / 180 * math.pi @@ -519,23 +505,22 @@ def test_displace_arg_real(compare: type[Compare], xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray([r, 0])) - compare.assert_allclose([lon, lat], [0.0, d]) + xp_assert_close([lon, lat], [0.0, d]) # south lon, lat = glass.displace(lon0, lat0, xp.asarray([-r, 0])) - compare.assert_allclose([lon, lat], [0.0, -d], atol=1e-15) + xp_assert_close([lon, lat], [0.0, -d], atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray([0, r])) - compare.assert_allclose([lon, lat], [d, 0.0], atol=1e-15) + xp_assert_close([lon, lat], [d, 0.0], atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray([0, -r])) - compare.assert_allclose([lon, lat], [-d, 0.0], atol=1e-15) + xp_assert_close([lon, lat], [-d, 0.0], atol=1e-15) def test_displace_abs( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -555,11 +540,10 @@ def test_displace_abs( cos_a = xp.cos(th) * xp.cos(th_) + xp.cos(delta) * xp.sin(th) * xp.sin(th_) - compare.assert_allclose(cos_a, xp.cos(abs_alpha)) + xp_assert_close(cos_a, xp.cos(abs_alpha)) def test_displacement( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -592,7 +576,7 @@ def test_displacement( # test each displacement individually for from_lon, from_lat, to_lon, to_lat, alpha in data: alpha_ = glass.displacement(from_lon, from_lat, to_lon, to_lat) - compare.assert_allclose(alpha_, alpha) + xp_assert_close(alpha_, alpha) # test on an array alpha = glass.displacement( @@ -605,7 +589,6 @@ def test_displacement( def test_displacement_zerodist( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -613,14 +596,13 @@ def test_displacement_zerodist( lon = urng.uniform(-180.0, 180.0, size=100) lat = urng.uniform(-90.0, 90.0, size=100) - compare.assert_allclose( + xp_assert_close( glass.displacement(lon, lat, lon, lat), xp.zeros(100), ) def test_displacement_consistent( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -644,11 +626,10 @@ def test_displacement_consistent( # measure displacement alpha_out = glass.displacement(from_lon, from_lat, to_lon, to_lat) - compare.assert_allclose(alpha_out, alpha_in, atol=0.0, rtol=1e-10) + xp_assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) def test_displacement_random( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -693,11 +674,11 @@ def test_displacement_random( ], axis=1, ) - compare.assert_allclose(rot @ xp.asarray([0.0, 0.0, 1.0]), u) + xp_assert_close(rot @ xp.asarray([0.0, 0.0, 1.0]), u) # meta-check that recovering theta and phi from vector works - compare.assert_allclose(xp.atan2(xp.hypot(u[:, 0], u[:, 1]), u[:, 2]), theta) - compare.assert_allclose(xp.atan2(u[:, 1], u[:, 0]), phi) + xp_assert_close(xp.atan2(xp.hypot(u[:, 0], u[:, 1]), u[:, 2]), theta) + xp_assert_close(xp.atan2(u[:, 1], u[:, 0]), phi) # build the displaced points near (0, 0, 1) and rotate near theta and phi v = xp.stack( @@ -724,4 +705,4 @@ def test_displacement_random( # compute displacement and compare to input alpha_in = r * xp.exp(1j * x) alpha_out = glass.displacement(from_lon, from_lat, to_lon, to_lat) - compare.assert_allclose(alpha_out, alpha_in, atol=0.0, rtol=1e-10) + xp_assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) diff --git a/tests/core/test_shapes.py b/tests/core/test_shapes.py index 3c5ac273..493a25ab 100644 --- a/tests/core/test_shapes.py +++ b/tests/core/test_shapes.py @@ -4,16 +4,20 @@ import pytest +from array_api_extra._lib._testing import xp_assert_close, xp_assert_less + import glass if TYPE_CHECKING: from types import ModuleType from glass._types import UnifiedGenerator - from tests.fixtures.helper_classes import Compare -def test_triaxial_axis_ratio(urng: UnifiedGenerator, xp: ModuleType) -> None: +def test_triaxial_axis_ratio( + urng: UnifiedGenerator, + xp: ModuleType, +) -> None: # Pass floats without xp with pytest.raises( @@ -63,7 +67,10 @@ def test_triaxial_axis_ratio(urng: UnifiedGenerator, xp: ModuleType) -> None: assert xp.all((qmax >= q) & (q >= qmin)) -def test_ellipticity_ryden04(urng: UnifiedGenerator, xp: ModuleType) -> None: +def test_ellipticity_ryden04( + urng: UnifiedGenerator, + xp: ModuleType, +) -> None: # Pass floats without xp with pytest.raises( @@ -121,7 +128,6 @@ def test_ellipticity_ryden04(urng: UnifiedGenerator, xp: ModuleType) -> None: @pytest.mark.flaky(rerun=5, only_rerun=["AssertionError"]) def test_ellipticity_gaussian( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -145,25 +151,24 @@ def test_ellipticity_gaussian( assert eps.shape == (n,) - compare.assert_array_less(xp.abs(eps), 1) + xp_assert_less(xp.abs(eps), 1) - compare.assert_allclose(xp.std(xp.real(eps)), 0.256, atol=1e-3, rtol=0) - compare.assert_allclose(xp.std(xp.imag(eps)), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)), 0.256, atol=1e-3, rtol=0) eps = glass.ellipticity_gaussian(xp.asarray([n, n]), xp.asarray([0.128, 0.256])) assert eps.shape == (2 * n,) - compare.assert_array_less(xp.abs(eps), 1) + xp_assert_less(xp.abs(eps), 1) - compare.assert_allclose(xp.std(xp.real(eps)[:n]), 0.128, atol=1e-3, rtol=0) - compare.assert_allclose(xp.std(xp.imag(eps)[:n]), 0.128, atol=1e-3, rtol=0) - compare.assert_allclose(xp.std(xp.real(eps)[n:]), 0.256, atol=1e-3, rtol=0) - compare.assert_allclose(xp.std(xp.imag(eps)[n:]), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)[:n]), 0.128, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)[:n]), 0.128, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)[n:]), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)[n:]), 0.256, atol=1e-3, rtol=0) def test_ellipticity_intnorm( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -187,21 +192,21 @@ def test_ellipticity_intnorm( assert eps.shape == (n,) - compare.assert_array_less(xp.abs(eps), 1) + xp_assert_less(xp.abs(eps), 1) - compare.assert_allclose(xp.std(xp.real(eps)), 0.256, atol=1e-3, rtol=0) - compare.assert_allclose(xp.std(xp.imag(eps)), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)), 0.256, atol=1e-3, rtol=0) eps = glass.ellipticity_intnorm(xp.asarray([n, n]), xp.asarray([0.128, 0.256])) assert eps.shape == (2 * n,) - compare.assert_array_less(xp.abs(eps), 1) + xp_assert_less(xp.abs(eps), 1) - compare.assert_allclose(xp.std(xp.real(eps)[:n]), 0.128, atol=1e-3, rtol=0) - compare.assert_allclose(xp.std(xp.imag(eps)[:n]), 0.128, atol=1e-3, rtol=0) - compare.assert_allclose(xp.std(xp.real(eps)[n:]), 0.256, atol=1e-3, rtol=0) - compare.assert_allclose(xp.std(xp.imag(eps)[n:]), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)[:n]), 0.128, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)[:n]), 0.128, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)[n:]), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)[n:]), 0.256, atol=1e-3, rtol=0) with pytest.raises(ValueError, match="sigma must be between"): glass.ellipticity_intnorm(1, 0.71, xp=xp) diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index 82487ca8..0d41966e 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -7,6 +7,12 @@ import numpy as np import pytest +from array_api_extra._lib._testing import ( + xp_assert_close, + xp_assert_equal, + xp_assert_less, +) + import glass from glass._array_api_utils import xp_additions as uxpx @@ -14,11 +20,9 @@ from types import ModuleType from glass.cosmology import Cosmology - from tests.fixtures.helper_classes import Compare def test_distance_weight( - compare: type[Compare], cosmo: Cosmology, xp: ModuleType, ) -> None: @@ -28,7 +32,7 @@ def test_distance_weight( # check shape w = glass.DistanceWeight(cosmo)(z) - compare.assert_array_equal(w.shape, z.shape) + xp_assert_equal(w.shape, z.shape) # check first value is 1 @@ -36,11 +40,10 @@ def test_distance_weight( # check values are decreasing - compare.assert_array_less(w[1:], w[:-1]) + xp_assert_less(w[1:], w[:-1]) def test_volume_weight( - compare: type[Compare], cosmo: Cosmology, xp: ModuleType, ) -> None: @@ -50,7 +53,7 @@ def test_volume_weight( # check shape w = glass.VolumeWeight(cosmo)(z) - compare.assert_array_equal(w.shape, z.shape) + xp_assert_equal(w.shape, z.shape) # check first value is 0 @@ -58,17 +61,17 @@ def test_volume_weight( # check values are increasing - compare.assert_array_less(w[:-1], w[1:]) + xp_assert_less(w[:-1], w[1:]) -def test_density_weight(compare: type[Compare], cosmo: Cosmology) -> None: +def test_density_weight(cosmo: Cosmology) -> None: """Add unit tests for :class:`glass.DensityWeight`.""" z = np.linspace(0, 1, 6) # check shape w = glass.DensityWeight(cosmo)(z) - compare.assert_array_equal(w.shape, z.shape) + xp_assert_equal(w.shape, z.shape) # check first value is 0 @@ -76,7 +79,7 @@ def test_density_weight(compare: type[Compare], cosmo: Cosmology) -> None: # check values are increasing - compare.assert_array_less(w[:-1], w[1:]) + xp_assert_less(w[:-1], w[1:]) def test_tophat_windows(xp: ModuleType) -> None: @@ -101,7 +104,7 @@ def test_tophat_windows(xp: ModuleType) -> None: assert all(xp.all(w.wa == 1) for w in ws) -def test_linear_windows(compare: type[Compare], xp: ModuleType) -> None: +def test_linear_windows(xp: ModuleType) -> None: """Add unit tests for :func:`glass.linear_windows`.""" dz = 1e-2 zgrid = xp.asarray( @@ -117,7 +120,7 @@ def test_linear_windows(compare: type[Compare], xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.linear_windows(zgrid) - compare.assert_allclose(dz, xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xp_assert_close(dz, xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -125,7 +128,7 @@ def test_linear_windows(compare: type[Compare], xp: ModuleType) -> None: # check values of zeff - compare.assert_allclose([w.zeff for w in ws], zgrid[1:-1]) + xp_assert_close([w.zeff for w in ws], zgrid[1:-1]) # check weight function input @@ -134,7 +137,7 @@ def test_linear_windows(compare: type[Compare], xp: ModuleType) -> None: weight=lambda _: 0, ) for w in ws: - compare.assert_allclose(w.wa, xp.zeros_like(w.wa)) + xp_assert_close(w.wa, xp.zeros_like(w.wa)) # check error raised @@ -150,7 +153,7 @@ def test_linear_windows(compare: type[Compare], xp: ModuleType) -> None: glass.linear_windows(xp.asarray([0.1, 0.2, 0.3])) -def test_cubic_windows(compare: type[Compare], xp: ModuleType) -> None: +def test_cubic_windows(xp: ModuleType) -> None: """Add unit tests for :func:`glass.cubic_windows`.""" dz = 1e-2 zgrid = xp.asarray( @@ -166,7 +169,7 @@ def test_cubic_windows(compare: type[Compare], xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.cubic_windows(zgrid) - compare.assert_allclose(dz, xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xp_assert_close(dz, xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -174,7 +177,7 @@ def test_cubic_windows(compare: type[Compare], xp: ModuleType) -> None: # check values of zeff - compare.assert_allclose([w.zeff for w in ws], zgrid[1:-1]) + xp_assert_close([w.zeff for w in ws], zgrid[1:-1]) # check weight function input @@ -183,7 +186,7 @@ def test_cubic_windows(compare: type[Compare], xp: ModuleType) -> None: weight=lambda _: 0, ) for w in ws: - compare.assert_allclose(w.wa, xp.zeros_like(w.wa)) + xp_assert_close(w.wa, xp.zeros_like(w.wa)) # check error raised @@ -234,7 +237,6 @@ def test_restrict(xp: ModuleType) -> None: @pytest.mark.parametrize("method", ["lstsq", "nnls", "restrict"]) def test_partition( - compare: type[Compare], method: str, xp: ModuleType, ) -> None: @@ -277,7 +279,7 @@ def test_partition( assert part.shape == (len(shells), 3, 2) - compare.assert_allclose(xp.sum(part, axis=0), uxpx.trapezoid(fz, z)) + xp_assert_close(xp.sum(part, axis=0), uxpx.trapezoid(fz, z)) def test_redshift_grid_default_xp() -> None: @@ -340,7 +342,7 @@ def test_redshift_grid(xp: ModuleType) -> None: glass.redshift_grid(zmin, zmax, dz=dz, num=num, xp=xp) -def test_distance_grid(compare: type[Compare], cosmo: Cosmology) -> None: +def test_distance_grid(cosmo: Cosmology) -> None: """Add unit tests for :func:`glass.distance_grid`.""" zmin = 0.0 zmax = 1.0 @@ -360,7 +362,7 @@ def test_distance_grid(compare: type[Compare], cosmo: Cosmology) -> None: # check decrease in distance x = glass.distance_grid(cosmo, zmin, zmax, dx=0.3) - compare.assert_array_less(x[1:], x[:-1]) + xp_assert_less(x[1:], x[:-1]) # check error raised @@ -377,10 +379,7 @@ def test_distance_grid(compare: type[Compare], cosmo: Cosmology) -> None: glass.distance_grid(cosmo, zmin, zmax, dx=dx, num=num) -def test_combine( - compare: type[Compare], - xp: ModuleType, -) -> None: +def test_combine(xp: ModuleType) -> None: """Add unit tests for :func:`glass.combine`.""" z = xp.linspace(0.0, 5.0, 1_000) weights = xp.asarray( @@ -416,10 +415,10 @@ def test_combine( assert result.shape == z.shape # Check sum of result - compare.assert_allclose(sum(result), 929.267284) + xp_assert_close(sum(result), 929.267284) # Check integral w.r.t z has not changed - compare.assert_allclose(uxpx.trapezoid(result, z), 4.643139, rtol=1e-6) + xp_assert_close(uxpx.trapezoid(result, z), 4.643139, rtol=1e-6) def test_radial_window_immutable(xp: ModuleType) -> None: @@ -449,7 +448,7 @@ def test_radial_window_immutable(xp: ModuleType) -> None: w.zeff = zeff # ty: ignore[invalid-assignment] -def test_radial_window_zeff_none(compare: type[Compare], xp: ModuleType) -> None: +def test_radial_window_zeff_none(xp: ModuleType) -> None: """Checks ``zeff`` is computed when not provided to :class:`RadialWindow`.""" # check zeff is computed when not provided @@ -458,7 +457,7 @@ def test_radial_window_zeff_none(compare: type[Compare], xp: ModuleType) -> None w = glass.RadialWindow(za, wa) - compare.assert_allclose(w.zeff, 1.0) + xp_assert_close(w.zeff, 1.0) # check zeff is NaN when redshift array is empty diff --git a/tests/core/test_user.py b/tests/core/test_user.py index 278c240d..f7f4ac08 100644 --- a/tests/core/test_user.py +++ b/tests/core/test_user.py @@ -7,11 +7,12 @@ import numpy as np import pytest +from array_api_extra._lib._testing import xp_assert_equal + import glass if TYPE_CHECKING: from glass._types import AngularPowerSpectra, FloatArray - from tests.fixtures.helper_classes import Compare # check if available for testing HAVE_FITSIO = importlib.util.find_spec("fitsio") is not None @@ -24,7 +25,6 @@ def test_read_write_cls( - compare: type[Compare], rng: np.random.Generator, tmp_path: pathlib.Path, ) -> None: @@ -37,14 +37,12 @@ def test_read_write_cls( values = npz["values"] split = npz["split"] - compare.assert_array_equal(values, np.concat(cls)) - compare.assert_array_equal( - split, np.cumulative_sum([cl.shape[0] for cl in cls[:-1]]) - ) - compare.assert_array_equal(cls, np.split(values, split)) + xp_assert_equal(values, np.concat(cls)) + xp_assert_equal(split, np.cumulative_sum([cl.shape[0] for cl in cls[:-1]])) + xp_assert_equal(cls, np.split(values, split)) npz = glass.load_cls(tmp_path / cls_file) - compare.assert_array_equal(npz, cls) + xp_assert_equal(npz, cls) @pytest.mark.skipif(not HAVE_FITSIO, reason="test requires fitsio") From d53c07ec59b73f00e810e0c0e21d38cc2ab9c9a7 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Wed, 20 May 2026 10:24:22 +0100 Subject: [PATCH 06/43] Fix some tests --- tests/benchmarks/test_lensing.py | 4 ++-- tests/core/test_lensing.py | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/benchmarks/test_lensing.py b/tests/benchmarks/test_lensing.py index 49af57bd..eb39cd30 100644 --- a/tests/benchmarks/test_lensing.py +++ b/tests/benchmarks/test_lensing.py @@ -39,7 +39,7 @@ def test_multi_plane_matrix( deltas = urngb.random((len(shells), 10)) xp_assert_equal(mat, xpb.tril(mat)) - xp_assert_equal(xpb.triu(mat, k=1), 0) + xp_assert_equal(xpb.triu(mat, k=1), xpb.zeros_like(mat)) def setup_shells_and_deltas() -> tuple[ tuple[ @@ -100,7 +100,7 @@ def test_multi_plane_weights( w_out = glass.multi_plane_weights(w_in, shells, cosmo) xp_assert_equal(w_out, xpb.triu(w_out, 1)) - xp_assert_equal(xpb.tril(w_out), 0) + xp_assert_equal(xpb.tril(w_out), xpb.zeros_like(w_out)) def setup_shells_deltas_and_weights() -> tuple[ tuple[ diff --git a/tests/core/test_lensing.py b/tests/core/test_lensing.py index 8da68af5..4beb3ad7 100644 --- a/tests/core/test_lensing.py +++ b/tests/core/test_lensing.py @@ -30,30 +30,30 @@ def test_from_convergence(urng: UnifiedGenerator) -> None: # check with all False results = glass.from_convergence(kappa) # ty: ignore[no-matching-overload] - xp_assert_equal(results, ()) + assert results == () # check all combinations of potential, deflection, shear being True results = glass.from_convergence(kappa, potential=True) - xp_assert_equal(len(results), 1) + assert len(results) == 1 results = glass.from_convergence(kappa, deflection=True) - xp_assert_equal(len(results), 1) + assert len(results) == 1 results = glass.from_convergence(kappa, shear=True) - xp_assert_equal(len(results), 1) + assert len(results) == 1 results = glass.from_convergence(kappa, potential=True, deflection=True) - xp_assert_equal(len(results), 2) + assert len(results) == 2 results = glass.from_convergence(kappa, potential=True, shear=True) - xp_assert_equal(len(results), 2) + assert len(results) == 2 results = glass.from_convergence(kappa, deflection=True, shear=True) - xp_assert_equal(len(results), 2) + assert len(results) == 2 results = glass.from_convergence(kappa, potential=True, deflection=True, shear=True) - xp_assert_equal(len(results), 3) + assert len(results) == 3 def test_shear_from_convergence() -> None: @@ -70,7 +70,7 @@ def test_multi_plane_matrix( mat = glass.multi_plane_matrix(shells, cosmo) xp_assert_equal(mat, xp.tril(mat)) - xp_assert_equal(xp.triu(mat, k=1), 0) + xp_assert_equal(xp.triu(mat, k=1), xp.zeros_like(mat)) convergence = glass.MultiPlaneConvergence(cosmo) @@ -96,7 +96,7 @@ def test_multi_plane_weights( w_out = glass.multi_plane_weights(w_in, shells, cosmo) xp_assert_equal(w_out, xp.triu(w_out, k=1)) - xp_assert_equal(xp.tril(w_out), 0) + xp_assert_equal(xp.tril(w_out), xp.zeros_like(w_out)) convergence = glass.MultiPlaneConvergence(cosmo) From 0bb932a0deea582a54e0b8ab9f54538e7f404d27 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Wed, 20 May 2026 12:45:34 +0100 Subject: [PATCH 07/43] Port more test --- tests/core/test_fields.py | 14 ++++++++------ tests/core/test_lensing.py | 14 +++++++------- tests/core/test_points.py | 20 ++++++++++---------- tests/core/test_shapes.py | 8 ++++---- tests/core/test_shells.py | 6 +++--- 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index 8400e2a8..aafe5399 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -201,8 +201,8 @@ def test_cls2cov_no_jax(xpb: ModuleType) -> None: assert cov.dtype == xpb.float64 xp_assert_close(cov[:, 0], xpb.asarray([0.5, 0.25, 0.15])) - xp_assert_close(cov[:, 1], 0) - xp_assert_close(cov[:, 2], 0) + xp_assert_close(cov[:, 1], xpb.zeros_like(cov[:, 1])) + xp_assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) # test negative value error @@ -372,7 +372,7 @@ def test_effective_cls(xp: ModuleType) -> None: result = glass.effective_cls(cls, weights1, lmax=5) assert result.shape == (1, 1, 6) - xp_assert_close(result[..., 6:], 0) + xp_assert_close(result[..., 6:], xp.zeros_like(result[..., 6:])) # check with weights1 and weights2 and weights1 is weights2 @@ -529,11 +529,13 @@ def test_enumerate_spectra(xp: ModuleType) -> None: def test_spectra_indices(xp: ModuleType) -> None: xp_assert_equal(glass.spectra_indices(0), xp.zeros((0, 2))) xp_assert_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2))) - xp_assert_equal(glass.spectra_indices(1, xp=xp), [[0, 0]]) - xp_assert_equal(glass.spectra_indices(2, xp=xp), [[0, 0], [1, 1], [1, 0]]) + xp_assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) + xp_assert_equal( + glass.spectra_indices(2, xp=xp), xp.asarray([[0, 0], [1, 1], [1, 0]]) + ) xp_assert_equal( glass.spectra_indices(3, xp=xp), - [[0, 0], [1, 1], [1, 0], [2, 2], [2, 1], [2, 0]], + xp.asarray([[0, 0], [1, 1], [1, 0], [2, 2], [2, 1], [2, 0]]), ) diff --git a/tests/core/test_lensing.py b/tests/core/test_lensing.py index 4beb3ad7..8b852009 100644 --- a/tests/core/test_lensing.py +++ b/tests/core/test_lensing.py @@ -83,7 +83,7 @@ def test_multi_plane_matrix( if convergence.kappa is not None: kappas.append(xp.asarray(convergence.kappa, copy=True)) - xp_assert_close(mat @ deltas, kappas) + xp_assert_close(mat @ deltas, xp.asarray(kappas)) def test_multi_plane_weights( @@ -135,19 +135,19 @@ def alpha( # north lon, lat = glass.deflect(0.0, 0.0, alpha(r, 0, usecomplex=usecomplex), xp=xp) - xp_assert_close([lon, lat], [0.0, d], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, d]), atol=1e-15) # south lon, lat = glass.deflect(0.0, 0.0, alpha(-r, 0, usecomplex=usecomplex), xp=xp) - xp_assert_close([lon, lat], [0.0, -d], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.deflect(0.0, 0.0, alpha(0, r, usecomplex=usecomplex), xp=xp) - xp_assert_close([lon, lat], [-d, 0.0], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.deflect(0.0, 0.0, alpha(0, -r, usecomplex=usecomplex), xp=xp) - xp_assert_close([lon, lat], [d, 0.0], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) # At least one input is an array lon, lat = glass.deflect( @@ -155,7 +155,7 @@ def alpha( xp.asarray(0.0), alpha(0, -r, usecomplex=usecomplex), ) - xp_assert_close([lon, lat], [d, 0.0], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) lon, lat = glass.deflect( xp.asarray([0.0, 0.0]), @@ -163,7 +163,7 @@ def alpha( alpha(0, -r, usecomplex=usecomplex), ) xp_assert_close(lon, xp.asarray([d, d]), atol=1e-15) - xp_assert_close(lat, 0.0, atol=1e-15) + xp_assert_close(lat, xp.asarray([0.0, 0.0]), atol=1e-15) # No inputs are arrays and xp not provided with pytest.raises( diff --git a/tests/core/test_points.py b/tests/core/test_points.py index ac0006cf..b135c6f0 100644 --- a/tests/core/test_points.py +++ b/tests/core/test_points.py @@ -306,8 +306,8 @@ def test_positions_from_delta( # noqa: PLR0915 ) assert int(count) == count - xp_assert_close(lon, []) - xp_assert_close(lat, []) + xp_assert_close(lon, xp.asarray([])) + xp_assert_close(lat, xp.asarray([])) # case: large delta @@ -479,19 +479,19 @@ def test_displace_arg_complex(xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray(r + 0j)) - xp_assert_close([lon, lat], [0.0, d]) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, d])) # south lon, lat = glass.displace(lon0, lat0, xp.asarray(-r + 0j)) - xp_assert_close([lon, lat], [0.0, -d], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray(1j * r)) - xp_assert_close([lon, lat], [d, 0.0], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray(-1j * r)) - xp_assert_close([lon, lat], [-d, 0.0], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) def test_displace_arg_real(xp: ModuleType) -> None: @@ -505,19 +505,19 @@ def test_displace_arg_real(xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray([r, 0])) - xp_assert_close([lon, lat], [0.0, d]) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, d])) # south lon, lat = glass.displace(lon0, lat0, xp.asarray([-r, 0])) - xp_assert_close([lon, lat], [0.0, -d], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray([0, r])) - xp_assert_close([lon, lat], [d, 0.0], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray([0, -r])) - xp_assert_close([lon, lat], [-d, 0.0], atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) def test_displace_abs( diff --git a/tests/core/test_shapes.py b/tests/core/test_shapes.py index 493a25ab..99552fa6 100644 --- a/tests/core/test_shapes.py +++ b/tests/core/test_shapes.py @@ -151,7 +151,7 @@ def test_ellipticity_gaussian( assert eps.shape == (n,) - xp_assert_less(xp.abs(eps), 1) + xp_assert_less(xp.abs(eps), xp.ones_like(eps)) xp_assert_close(xp.std(xp.real(eps)), 0.256, atol=1e-3, rtol=0) xp_assert_close(xp.std(xp.imag(eps)), 0.256, atol=1e-3, rtol=0) @@ -160,7 +160,7 @@ def test_ellipticity_gaussian( assert eps.shape == (2 * n,) - xp_assert_less(xp.abs(eps), 1) + xp_assert_less(xp.abs(eps), xp.ones_like(eps)) xp_assert_close(xp.std(xp.real(eps)[:n]), 0.128, atol=1e-3, rtol=0) xp_assert_close(xp.std(xp.imag(eps)[:n]), 0.128, atol=1e-3, rtol=0) @@ -192,7 +192,7 @@ def test_ellipticity_intnorm( assert eps.shape == (n,) - xp_assert_less(xp.abs(eps), 1) + xp_assert_less(xp.abs(eps), xp.ones_like(eps)) xp_assert_close(xp.std(xp.real(eps)), 0.256, atol=1e-3, rtol=0) xp_assert_close(xp.std(xp.imag(eps)), 0.256, atol=1e-3, rtol=0) @@ -201,7 +201,7 @@ def test_ellipticity_intnorm( assert eps.shape == (2 * n,) - xp_assert_less(xp.abs(eps), 1) + xp_assert_less(xp.abs(eps), xp.ones_like(eps)) xp_assert_close(xp.std(xp.real(eps)[:n]), 0.128, atol=1e-3, rtol=0) xp_assert_close(xp.std(xp.imag(eps)[:n]), 0.128, atol=1e-3, rtol=0) diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index 0d41966e..c948b74d 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -53,7 +53,7 @@ def test_volume_weight( # check shape w = glass.VolumeWeight(cosmo)(z) - xp_assert_equal(w.shape, z.shape) + assert w.shape == z.shape # check first value is 0 @@ -71,7 +71,7 @@ def test_density_weight(cosmo: Cosmology) -> None: # check shape w = glass.DensityWeight(cosmo)(z) - xp_assert_equal(w.shape, z.shape) + assert w.shape == z.shape # check first value is 0 @@ -457,7 +457,7 @@ def test_radial_window_zeff_none(xp: ModuleType) -> None: w = glass.RadialWindow(za, wa) - xp_assert_close(w.zeff, 1.0) + xp_assert_close(w.zeff, xp.ones_like(w.zeff)) # check zeff is NaN when redshift array is empty From 732618fcbd66c2a35b3ef6756a1fb51d6867eac5 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Wed, 20 May 2026 14:16:53 +0100 Subject: [PATCH 08/43] More fixing --- tests/benchmarks/test_arraytools.py | 2 +- tests/benchmarks/test_shells.py | 2 +- tests/core/test_arraytools.py | 40 +++++++++++++++-------------- tests/core/test_shells.py | 2 +- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/tests/benchmarks/test_arraytools.py b/tests/benchmarks/test_arraytools.py index 7f3e764b..1f175990 100644 --- a/tests/benchmarks/test_arraytools.py +++ b/tests/benchmarks/test_arraytools.py @@ -78,7 +78,7 @@ def test_cumulative_trapezoid_2d( ) x = xpb.arange(scaled_length) # [0, 1, 2, 3,...] - expected_first_4_out = [0, 1, 4, 7] + expected_first_4_out = xpb.asarray([0, 1, 4, 7]) ct = benchmark(glass.arraytools.cumulative_trapezoid, f, x) diff --git a/tests/benchmarks/test_shells.py b/tests/benchmarks/test_shells.py index 45c8df3c..e58fc8fd 100644 --- a/tests/benchmarks/test_shells.py +++ b/tests/benchmarks/test_shells.py @@ -29,4 +29,4 @@ def test_radialwindow( w = benchmark(glass.RadialWindow, za, wa) - xp_assert_close(w.zeff, expected_zeff) + xp_assert_close(w.zeff, xpb.asarray(expected_zeff)) diff --git a/tests/core/test_arraytools.py b/tests/core/test_arraytools.py index ca156bd9..bbb4efca 100644 --- a/tests/core/test_arraytools.py +++ b/tests/core/test_arraytools.py @@ -73,12 +73,12 @@ def test_ndinterp(xp: ModuleType) -> None: x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (3,) - xp_assert_close(y, [1.15, 1.25, 1.35], atol=1e-15) + xp_assert_close(y, xp.asarray([1.15, 1.25, 1.35]), atol=1e-15) x = xp.asarray([[0.5, 1.5], [2.5, 3.5]]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 2) - xp_assert_close(y, [[1.15, 1.25], [1.35, 1.45]], atol=1e-15) + xp_assert_close(y, xp.asarray([[1.15, 1.25], [1.35, 1.45]]), atol=1e-15) # test n-dimensional interpolation in final axis @@ -87,19 +87,19 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2,) - xp_assert_close(y, [1.15, 2.15], atol=1e-15) + xp_assert_close(y, xp.asarray([1.15, 2.15]), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 3) - xp_assert_close(y, [[1.15, 1.25, 1.35], [2.15, 2.25, 2.35]], atol=1e-15) + xp_assert_close(y, xp.asarray([[1.15, 1.25, 1.35], [2.15, 2.25, 2.35]]), atol=1e-15) x = xp.asarray([[0.5, 1.5], [2.5, 3.5]]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 2, 2) xp_assert_close( y, - [[[1.15, 1.25], [1.35, 1.45]], [[2.15, 2.25], [2.35, 2.45]]], + xp.asarray([[[1.15, 1.25], [1.35, 1.45]], [[2.15, 2.25], [2.35, 2.45]]]), atol=1e-15, ) @@ -112,14 +112,14 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 1) - xp_assert_close(y, [[1.15], [2.15]], atol=1e-15) + xp_assert_close(y, xp.asarray([[1.15], [2.15]]), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 3, 1) xp_assert_close( y, - [[[1.15], [1.25], [1.35]], [[2.15], [2.25], [2.35]]], + xp.asarray([[[1.15], [1.25], [1.35]], [[2.15], [2.25], [2.35]]]), atol=1e-15, ) @@ -128,18 +128,20 @@ def test_ndinterp(xp: ModuleType) -> None: assert y.shape == (2, 3, 4, 1) xp_assert_close( y, - [ + xp.asarray( [ - [[1.15], [1.25], [1.35], [1.45]], - [[1.45], [1.35], [1.25], [1.15]], - [[1.15], [1.45], [1.25], [1.35]], - ], - [ - [[2.15], [2.25], [2.35], [2.45]], - [[2.45], [2.35], [2.25], [2.15]], - [[2.15], [2.45], [2.25], [2.35]], - ], - ], + [ + [[1.15], [1.25], [1.35], [1.45]], + [[1.45], [1.35], [1.25], [1.15]], + [[1.15], [1.45], [1.25], [1.35]], + ], + [ + [[2.15], [2.25], [2.35], [2.45]], + [[2.45], [2.35], [2.25], [2.15]], + [[2.15], [2.45], [2.25], [2.35]], + ], + ] + ), atol=1e-15, ) @@ -153,7 +155,7 @@ def test_trapezoid_product(xp: ModuleType) -> None: s = glass.arraytools.trapezoid_product((x1, f1), (x2, f2)) - xp_assert_close(s, 1.0) + xp_assert_close(s, xp.ones_like(s)) def test_cumulative_trapezoid(xp: ModuleType) -> None: diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index c948b74d..753245dc 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -32,7 +32,7 @@ def test_distance_weight( # check shape w = glass.DistanceWeight(cosmo)(z) - xp_assert_equal(w.shape, z.shape) + assert w.shape == z.shape # check first value is 1 From c4e1ff8fda929ae6df74a4891d43bfbd9abfd602 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Wed, 20 May 2026 16:24:48 +0100 Subject: [PATCH 09/43] Fix points --- tests/core/test_points.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/core/test_points.py b/tests/core/test_points.py index b135c6f0..7d647658 100644 --- a/tests/core/test_points.py +++ b/tests/core/test_points.py @@ -35,17 +35,17 @@ def test_effective_bias( z = xp.linspace(0, 1, 10) bz = xp.zeros((10,)) - xp_assert_close(glass.effective_bias(z, bz, w), 0.0) + xp_assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) z = xp.zeros((10,)) bz = xp.full_like(z, 0.5) - xp_assert_close(glass.effective_bias(z, bz, w), 0.0) + xp_assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) z = xp.linspace(0, 1, 10) bz = xp.full_like(z, 0.5) - xp_assert_close(glass.effective_bias(z, bz, w), 0.25) + xp_assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.25)) def test_linear_bias( @@ -194,8 +194,8 @@ def test_sample_number_galaxies(xp: ModuleType) -> None: n = glass.points._sample_number_galaxies(n_in) - xp_assert_equal(n[:6], xp.zeros_like(n[:6])) - xp_assert_close(n[6:], n_in[6:], atol=250) + xp_assert_equal(n[:6], xp.zeros_like(n[:6], dtype=xp.int64)) + xp_assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) def test_sample_number_galaxies_rng( @@ -207,7 +207,7 @@ def test_sample_number_galaxies_rng( n = glass.points._sample_number_galaxies(n_in, rng=urng) xp_assert_equal(n[:6], xp.zeros_like(n[:6])) - xp_assert_close(n[6:], n_in[6:], atol=250) + xp_assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) def test_sample_galaxies_per_pixel( @@ -598,7 +598,7 @@ def test_displacement_zerodist( xp_assert_close( glass.displacement(lon, lat, lon, lat), - xp.zeros(100), + xp.zeros(100, dtype=xp.complex128), ) From c0c8cf6e92ea8d17f1008ce62fa43c41985aef7e Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Wed, 20 May 2026 16:35:13 +0100 Subject: [PATCH 10/43] Fix fields --- tests/core/test_fields.py | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index aafe5399..71644e64 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -519,7 +519,7 @@ def test_enumerate_spectra(xp: ModuleType) -> None: # go through expected indices and values and compare for k, (i, j) in enumerate(indices): - xp_assert_close(next(it), (i, j, k)) + assert next(it) == (i, j, k) # make sure iterator is exhausted with pytest.raises(StopIteration): @@ -527,8 +527,8 @@ def test_enumerate_spectra(xp: ModuleType) -> None: def test_spectra_indices(xp: ModuleType) -> None: - xp_assert_equal(glass.spectra_indices(0), xp.zeros((0, 2))) - xp_assert_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2))) + xp_assert_equal(glass.spectra_indices(0), xp.zeros((0, 2), dtype=xp.int64)) + xp_assert_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2), dtype=xp.int64)) xp_assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) xp_assert_equal( glass.spectra_indices(2, xp=xp), xp.asarray([[0, 0], [1, 1], [1, 0]]) @@ -653,13 +653,13 @@ def test_solve_gaussian_spectra( def test_glass_to_healpix_spectra() -> None: inp = [11, 22, 21, 33, 32, 31, 44, 43, 42, 41] out = glass.glass_to_healpix_spectra(inp) - xp_assert_equal(out, [11, 22, 33, 44, 21, 32, 43, 31, 42, 41]) + assert out == [11, 22, 33, 44, 21, 32, 43, 31, 42, 41] def test_healpix_to_glass_spectra() -> None: inp = [11, 22, 33, 44, 21, 32, 43, 31, 42, 41] out = glass.healpix_to_glass_spectra(inp) - xp_assert_equal(out, [11, 22, 21, 33, 32, 31, 44, 43, 42, 41]) + assert out == [11, 22, 21, 33, 32, 31, 44, 43, 42, 41] def test_glass_to_healpix_alm(xp: ModuleType) -> None: @@ -671,12 +671,21 @@ def test_glass_to_healpix_alm(xp: ModuleType) -> None: ) -def test_lognormal_shift_hilbert2011() -> None: +def test_lognormal_shift_hilbert2011(xp: ModuleType) -> None: zs = [0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0] - shifts = [glass.lognormal_shift_hilbert2011(z) for z in zs] + shifts = xp.asarray([glass.lognormal_shift_hilbert2011(z) for z in zs]) # computed by hand - check = [0.0103031, 0.02975, 0.0538781, 0.0792, 0.103203, 0.12435, 0.142078, 0.1568] + check = xp.asarray([ + 0.0103031, + 0.02975, + 0.0538781, + 0.0792, + 0.103203, + 0.12435, + 0.142078, + 0.1568, + ]) xp_assert_close(shifts, check, atol=1e-4, rtol=1e-4) @@ -696,7 +705,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: xp_assert_equal( glass.cov_from_spectra(spectra), - [ + xp.asarray([ [ [110, 210, 310], [210, 220, 320], @@ -717,12 +726,12 @@ def test_cov_from_spectra(xp: ModuleType) -> None: [213, 223, 323], [313, 323, 333], ], - ], + ]), ) xp_assert_equal( glass.cov_from_spectra(spectra, lmax=1), - [ + xp.asarray([ [ [110, 210, 310], [210, 220, 320], @@ -733,12 +742,12 @@ def test_cov_from_spectra(xp: ModuleType) -> None: [211, 221, 321], [311, 321, 331], ], - ], + ]), ) xp_assert_equal( glass.cov_from_spectra(spectra, lmax=4), - [ + xp.asarray([ [ [110, 210, 310], [210, 220, 320], @@ -764,7 +773,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: [0, 0, 0], [0, 0, 0], ], - ], + ]), ) From dd6112878e8d4e4e72dbe729fd2de8d84cb1f680 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Wed, 20 May 2026 17:19:40 +0100 Subject: [PATCH 11/43] Fix more tests --- tests/core/test_algorithm.py | 2 +- tests/core/test_observations.py | 10 +++++++--- tests/core/test_shapes.py | 32 ++++++++++++++++---------------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/tests/core/test_algorithm.py b/tests/core/test_algorithm.py index 8968f692..f1e9d460 100644 --- a/tests/core/test_algorithm.py +++ b/tests/core/test_algorithm.py @@ -76,7 +76,7 @@ def test_cov_clip( # make sure all eigenvalues are positive h = xp.max(xp.linalg.eigvalsh(a)) - xp_assert_close(xp.linalg.eigvalsh(cov), h) + xp_assert_close(xp.linalg.eigvalsh(cov), h * xp.ones(cov.shape[0])) def test_nearcorr(xp: ModuleType) -> None: diff --git a/tests/core/test_observations.py b/tests/core/test_observations.py index 7e0ec380..b7b776dd 100644 --- a/tests/core/test_observations.py +++ b/tests/core/test_observations.py @@ -24,13 +24,13 @@ def test_vmap_galactic_ecliptic(xp: ModuleType) -> None: # check shape vmap = glass.vmap_galactic_ecliptic(n_side, xp=xp) - xp_assert_equal(vmap.shape[0], hp.nside2npix(n_side)) + assert vmap.shape[0] == hp.nside2npix(n_side) # Test without xp vmap = glass.vmap_galactic_ecliptic(n_side) assert vmap.__array_namespace__().__name__ == "numpy" - xp_assert_equal(vmap.shape[0], hp.nside2npix(n_side)) + assert vmap.shape[0] == hp.nside2npix(n_side) # no rotation @@ -70,7 +70,11 @@ def test_gaussian_nz( norm = 1 nz = glass.gaussian_nz(z, mean, sigma, norm=norm) - xp_assert_close(xp.sum(nz) / nz.shape[0], norm, rtol=1e-2) + xp_assert_close( + xp.sum(nz) / nz.shape[0], + xp.asarray(norm, dtype=xp.float64), + rtol=1e-2, + ) # check multidimensionality size diff --git a/tests/core/test_shapes.py b/tests/core/test_shapes.py index 99552fa6..b572ddca 100644 --- a/tests/core/test_shapes.py +++ b/tests/core/test_shapes.py @@ -151,21 +151,21 @@ def test_ellipticity_gaussian( assert eps.shape == (n,) - xp_assert_less(xp.abs(eps), xp.ones_like(eps)) + xp_assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xp_assert_close(xp.std(xp.real(eps)), 0.256, atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) eps = glass.ellipticity_gaussian(xp.asarray([n, n]), xp.asarray([0.128, 0.256])) assert eps.shape == (2 * n,) - xp_assert_less(xp.abs(eps), xp.ones_like(eps)) + xp_assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xp_assert_close(xp.std(xp.real(eps)[:n]), 0.128, atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)[:n]), 0.128, atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.real(eps)[n:]), 0.256, atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)[n:]), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0) def test_ellipticity_intnorm( @@ -192,21 +192,21 @@ def test_ellipticity_intnorm( assert eps.shape == (n,) - xp_assert_less(xp.abs(eps), xp.ones_like(eps)) + xp_assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xp_assert_close(xp.std(xp.real(eps)), 0.256, atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) eps = glass.ellipticity_intnorm(xp.asarray([n, n]), xp.asarray([0.128, 0.256])) assert eps.shape == (2 * n,) - xp_assert_less(xp.abs(eps), xp.ones_like(eps)) + xp_assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xp_assert_close(xp.std(xp.real(eps)[:n]), 0.128, atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)[:n]), 0.128, atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.real(eps)[n:]), 0.256, atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)[n:]), 0.256, atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.real(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0) + xp_assert_close(xp.std(xp.imag(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0) with pytest.raises(ValueError, match="sigma must be between"): glass.ellipticity_intnorm(1, 0.71, xp=xp) From 7bb239f9c41228c03fba0bdbad20b548bda82364 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 10:02:22 +0100 Subject: [PATCH 12/43] Fix some more tests --- tests/core/test_arraytools.py | 26 ++++++++++++-------------- tests/core/test_galaxies.py | 2 +- tests/core/test_healpix.py | 2 +- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/tests/core/test_arraytools.py b/tests/core/test_arraytools.py index bbb4efca..96d634fb 100644 --- a/tests/core/test_arraytools.py +++ b/tests/core/test_arraytools.py @@ -68,7 +68,7 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == () - xp_assert_close(y, 1.15, atol=1e-15) + xp_assert_close(y, xp.asarray(1.15), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) @@ -128,20 +128,18 @@ def test_ndinterp(xp: ModuleType) -> None: assert y.shape == (2, 3, 4, 1) xp_assert_close( y, - xp.asarray( + xp.asarray([ [ - [ - [[1.15], [1.25], [1.35], [1.45]], - [[1.45], [1.35], [1.25], [1.15]], - [[1.15], [1.45], [1.25], [1.35]], - ], - [ - [[2.15], [2.25], [2.35], [2.45]], - [[2.45], [2.35], [2.25], [2.15]], - [[2.15], [2.45], [2.25], [2.35]], - ], - ] - ), + [[1.15], [1.25], [1.35], [1.45]], + [[1.45], [1.35], [1.25], [1.15]], + [[1.15], [1.45], [1.25], [1.35]], + ], + [ + [[2.15], [2.25], [2.35], [2.45]], + [[2.45], [2.35], [2.25], [2.15]], + [[2.15], [2.45], [2.25], [2.35]], + ], + ]), atol=1e-15, ) diff --git a/tests/core/test_galaxies.py b/tests/core/test_galaxies.py index 3bf38638..7276c675 100644 --- a/tests/core/test_galaxies.py +++ b/tests/core/test_galaxies.py @@ -281,7 +281,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - xp_assert_equal(z, phz) + xp_assert_equal(z * xp.ones_like(phz), phz) # case: array redshift, array sigma_0 diff --git a/tests/core/test_healpix.py b/tests/core/test_healpix.py index b4ddfde5..3600a3d2 100644 --- a/tests/core/test_healpix.py +++ b/tests/core/test_healpix.py @@ -283,7 +283,7 @@ def test_pixwin( assert len(old) == len(new) for i in range(len(old)): - xp_assert_equal(old[i], new[i]) + xp_assert_equal(xp.asarray(old[i], dtype=xp.float64), new[i]) @pytest.mark.parametrize("thetas", [((20, 80)), ((30, 90))]) From 107ffbc5a55a4d4c5e7296060486a05a181adf36 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 10:48:59 +0100 Subject: [PATCH 13/43] Fix NumPy tests --- tests/core/test_lensing.py | 4 ++-- tests/core/test_observations.py | 10 +++++----- tests/core/test_shells.py | 13 ++++++------- tests/core/test_user.py | 11 +++++++---- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/tests/core/test_lensing.py b/tests/core/test_lensing.py index 8b852009..a3719495 100644 --- a/tests/core/test_lensing.py +++ b/tests/core/test_lensing.py @@ -143,11 +143,11 @@ def alpha( # east lon, lat = glass.deflect(0.0, 0.0, alpha(0, r, usecomplex=usecomplex), xp=xp) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) # west lon, lat = glass.deflect(0.0, 0.0, alpha(0, -r, usecomplex=usecomplex), xp=xp) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xp_assert_close(xp.asarray([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # At least one input is an array lon, lat = glass.deflect( diff --git a/tests/core/test_observations.py b/tests/core/test_observations.py index b7b776dd..950043c2 100644 --- a/tests/core/test_observations.py +++ b/tests/core/test_observations.py @@ -116,14 +116,14 @@ def test_fixed_zbins_default_xp() -> None: ) zbins = glass.fixed_zbins(zmin, zmax, nbins=nbins) assert len(zbins) == nbins - xp_assert_close(zbins, expected_zbins, rtol=1e-15) + xp_assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) # check dz input dz = 0.2 zbins = glass.fixed_zbins(zmin, zmax, dz=dz) assert len(zbins) == math.ceil((zmax - zmin) / dz) - xp_assert_close(zbins, expected_zbins, rtol=1e-15) + xp_assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) # check dz for spacing which results in a max value above zmax @@ -154,14 +154,14 @@ def test_fixed_zbins_xp_provided(xp: ModuleType) -> None: ) zbins = glass.fixed_zbins(zmin, zmax, nbins=nbins, xp=xp) assert len(zbins) == nbins - xp_assert_close(zbins, expected_zbins, rtol=1e-15) + xp_assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check dz input dz = 0.2 zbins = glass.fixed_zbins(zmin, zmax, dz=dz, xp=xp) assert len(zbins) == math.ceil((zmax - zmin) / dz) - xp_assert_close(zbins, expected_zbins, rtol=1e-15) + xp_assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check dz for spacing which results in a max value above zmax @@ -188,7 +188,7 @@ def test_equal_dens_zbins(xp: ModuleType) -> None: ], ) zbins = glass.equal_dens_zbins(z, xp.ones_like(z), nbins) - xp_assert_close(zbins, expected_zbins, rtol=1e-15) + xp_assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check output shape diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index 753245dc..c12448c6 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -9,7 +9,6 @@ from array_api_extra._lib._testing import ( xp_assert_close, - xp_assert_equal, xp_assert_less, ) @@ -120,7 +119,7 @@ def test_linear_windows(xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.linear_windows(zgrid) - xp_assert_close(dz, xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xp_assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -128,7 +127,7 @@ def test_linear_windows(xp: ModuleType) -> None: # check values of zeff - xp_assert_close([w.zeff for w in ws], zgrid[1:-1]) + xp_assert_close(xp.asarray([w.zeff for w in ws]), zgrid[1:-1]) # check weight function input @@ -169,7 +168,7 @@ def test_cubic_windows(xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.cubic_windows(zgrid) - xp_assert_close(dz, xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xp_assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -177,7 +176,7 @@ def test_cubic_windows(xp: ModuleType) -> None: # check values of zeff - xp_assert_close([w.zeff for w in ws], zgrid[1:-1]) + xp_assert_close(xp.asarray([w.zeff for w in ws]), zgrid[1:-1]) # check weight function input @@ -415,10 +414,10 @@ def test_combine(xp: ModuleType) -> None: assert result.shape == z.shape # Check sum of result - xp_assert_close(sum(result), 929.267284) + assert sum(result) == 929.2672844944944 # Check integral w.r.t z has not changed - xp_assert_close(uxpx.trapezoid(result, z), 4.643139, rtol=1e-6) + xp_assert_close(uxpx.trapezoid(result, z), xp.asarray(4.643139), rtol=1e-6) def test_radial_window_immutable(xp: ModuleType) -> None: diff --git a/tests/core/test_user.py b/tests/core/test_user.py index f7f4ac08..0c7a5b0a 100644 --- a/tests/core/test_user.py +++ b/tests/core/test_user.py @@ -12,6 +12,8 @@ import glass if TYPE_CHECKING: + from types import ModuleType + from glass._types import AngularPowerSpectra, FloatArray # check if available for testing @@ -27,6 +29,7 @@ def test_read_write_cls( rng: np.random.Generator, tmp_path: pathlib.Path, + xp: ModuleType, ) -> None: cls: AngularPowerSpectra = [rng.normal(size=(10,)) for _ in range(10)] glass.save_cls(tmp_path / cls_file, cls) @@ -37,12 +40,12 @@ def test_read_write_cls( values = npz["values"] split = npz["split"] - xp_assert_equal(values, np.concat(cls)) - xp_assert_equal(split, np.cumulative_sum([cl.shape[0] for cl in cls[:-1]])) - xp_assert_equal(cls, np.split(values, split)) + xp_assert_equal(values, xp.concat(cls)) + xp_assert_equal(split, xp.cumulative_sum([cl.shape[0] for cl in cls[:-1]])) + xp_assert_equal(xp.asarray(cls), xp.asarray(xp.split(values, split))) npz = glass.load_cls(tmp_path / cls_file) - xp_assert_equal(npz, cls) + xp_assert_equal(xp.asarray(npz), xp.asarray(cls)) @pytest.mark.skipif(not HAVE_FITSIO, reason="test requires fitsio") From cf1b4390248e95cd38969f10b8bb31a3bd2a7e57 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 14:42:45 +0100 Subject: [PATCH 14/43] Revert back to NumPy --- tests/core/test_user.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/core/test_user.py b/tests/core/test_user.py index 0c7a5b0a..e9d89e71 100644 --- a/tests/core/test_user.py +++ b/tests/core/test_user.py @@ -7,13 +7,9 @@ import numpy as np import pytest -from array_api_extra._lib._testing import xp_assert_equal - import glass if TYPE_CHECKING: - from types import ModuleType - from glass._types import AngularPowerSpectra, FloatArray # check if available for testing @@ -29,7 +25,6 @@ def test_read_write_cls( rng: np.random.Generator, tmp_path: pathlib.Path, - xp: ModuleType, ) -> None: cls: AngularPowerSpectra = [rng.normal(size=(10,)) for _ in range(10)] glass.save_cls(tmp_path / cls_file, cls) @@ -40,12 +35,14 @@ def test_read_write_cls( values = npz["values"] split = npz["split"] - xp_assert_equal(values, xp.concat(cls)) - xp_assert_equal(split, xp.cumulative_sum([cl.shape[0] for cl in cls[:-1]])) - xp_assert_equal(xp.asarray(cls), xp.asarray(xp.split(values, split))) + np.testing.assert_array_equal(values, np.concat(cls)) + np.testing.assert_array_equal( + split, np.cumulative_sum([cl.shape[0] for cl in cls[:-1]]) + ) + np.testing.assert_array_equal(cls, np.split(values, split)) npz = glass.load_cls(tmp_path / cls_file) - xp_assert_equal(xp.asarray(npz), xp.asarray(cls)) + np.testing.assert_array_equal(npz, cls) @pytest.mark.skipif(not HAVE_FITSIO, reason="test requires fitsio") From cb7e87f36ca16de4b4a56f6ccea7384be5026504 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 14:54:20 +0100 Subject: [PATCH 15/43] Change `asarray` to `stack` --- tests/core/test_lensing.py | 12 ++++++------ tests/core/test_points.py | 16 ++++++++-------- tests/core/test_shells.py | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/core/test_lensing.py b/tests/core/test_lensing.py index a3719495..3c65a5fa 100644 --- a/tests/core/test_lensing.py +++ b/tests/core/test_lensing.py @@ -83,7 +83,7 @@ def test_multi_plane_matrix( if convergence.kappa is not None: kappas.append(xp.asarray(convergence.kappa, copy=True)) - xp_assert_close(mat @ deltas, xp.asarray(kappas)) + xp_assert_close(mat @ deltas, xp.stack(kappas)) def test_multi_plane_weights( @@ -135,19 +135,19 @@ def alpha( # north lon, lat = glass.deflect(0.0, 0.0, alpha(r, 0, usecomplex=usecomplex), xp=xp) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, d]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d]), atol=1e-15) # south lon, lat = glass.deflect(0.0, 0.0, alpha(-r, 0, usecomplex=usecomplex), xp=xp) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.deflect(0.0, 0.0, alpha(0, r, usecomplex=usecomplex), xp=xp) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) # west lon, lat = glass.deflect(0.0, 0.0, alpha(0, -r, usecomplex=usecomplex), xp=xp) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # At least one input is an array lon, lat = glass.deflect( @@ -155,7 +155,7 @@ def alpha( xp.asarray(0.0), alpha(0, -r, usecomplex=usecomplex), ) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) lon, lat = glass.deflect( xp.asarray([0.0, 0.0]), diff --git a/tests/core/test_points.py b/tests/core/test_points.py index 7d647658..f7276d7c 100644 --- a/tests/core/test_points.py +++ b/tests/core/test_points.py @@ -479,19 +479,19 @@ def test_displace_arg_complex(xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray(r + 0j)) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, d])) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) # south lon, lat = glass.displace(lon0, lat0, xp.asarray(-r + 0j)) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray(1j * r)) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray(-1j * r)) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) def test_displace_arg_real(xp: ModuleType) -> None: @@ -505,19 +505,19 @@ def test_displace_arg_real(xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray([r, 0])) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, d])) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) # south lon, lat = glass.displace(lon0, lat0, xp.asarray([-r, 0])) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray([0, r])) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray([0, -r])) - xp_assert_close(xp.asarray([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xp_assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) def test_displace_abs( diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index c12448c6..e3bd00e4 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -127,7 +127,7 @@ def test_linear_windows(xp: ModuleType) -> None: # check values of zeff - xp_assert_close(xp.asarray([w.zeff for w in ws]), zgrid[1:-1]) + xp_assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) # check weight function input @@ -176,7 +176,7 @@ def test_cubic_windows(xp: ModuleType) -> None: # check values of zeff - xp_assert_close(xp.asarray([w.zeff for w in ws]), zgrid[1:-1]) + xp_assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) # check weight function input From e6529918e7e3ea36b00d814320d92f088ff6156c Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 15:09:35 +0100 Subject: [PATCH 16/43] Fix `healpix` tests --- tests/core/test_healpix.py | 112 +++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/tests/core/test_healpix.py b/tests/core/test_healpix.py index 3600a3d2..de36f7d3 100644 --- a/tests/core/test_healpix.py +++ b/tests/core/test_healpix.py @@ -37,25 +37,25 @@ def test_alm2map_individual( pixwin: bool, # noqa: FBT001 pol: bool, # noqa: FBT001 urng: UnifiedGenerator, + xp: ModuleType, ) -> None: """Compare ``glass.healpix.alm2map`` against ``healpy.alm2map``.""" alm = healpix_inputs.alm(rng=urng) - xp_assert_equal( - healpy.alm2map( - np.asarray(alm), - healpix_inputs.nside, - lmax=healpix_inputs.lmax, - pixwin=pixwin, - pol=pol, - ), - hp.alm2map( - alm, - healpix_inputs.nside, - lmax=healpix_inputs.lmax, - pixwin=pixwin, - pol=pol, - ), + old = healpy.alm2map( + np.asarray(alm), + healpix_inputs.nside, + lmax=healpix_inputs.lmax, + pixwin=pixwin, + pol=pol, + ) + new = hp.alm2map( + alm, + healpix_inputs.nside, + lmax=healpix_inputs.lmax, + pixwin=pixwin, + pol=pol, ) + xp_assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -72,6 +72,7 @@ def test_alm2map_sequence( pixwin: bool, # noqa: FBT001 pol: bool, # noqa: FBT001 urng: UnifiedGenerator, + xp: ModuleType, ) -> None: """Compare ``glass.healpix.alm2map`` against ``healpy.alm2map``.""" alm = healpix_inputs.alm(rng=urng) @@ -91,7 +92,7 @@ def test_alm2map_sequence( pixwin=pixwin, pol=pol, ) - xp_assert_equal(old, new) + xp_assert_equal(xp.asarray(old), new) @pytest.mark.parametrize("spin", [1, 2]) @@ -99,6 +100,7 @@ def test_alm2map_spin( healpix_inputs: type[HealpixInputs], spin: int, urng: UnifiedGenerator, + xp: ModuleType, ) -> None: """Compare ``glass.healpix.alm2map_spin`` against ``healpy.alm2map_spin``.""" alm = healpix_inputs.alm(rng=urng) @@ -113,20 +115,20 @@ def test_alm2map_spin( assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xp_assert_equal(old[i], new[i]) + xp_assert_equal(xp.asarray(old[i]), new[i]) def test_almxfl( healpix_inputs: type[HealpixInputs], urng: UnifiedGenerator, + xp: ModuleType, ) -> None: """Compare ``glass.healpix.almxfl`` against ``healpy.almxfl``.""" alm = healpix_inputs.alm(rng=urng) fl = healpix_inputs.fl(rng=urng) - xp_assert_equal( - healpy.almxfl(alm, fl), - hp.almxfl(alm, fl), - ) + old = healpy.almxfl(alm, fl) + new = hp.almxfl(alm, fl) + xp_assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -149,7 +151,7 @@ def test_ang2pix( # noqa: PLR0913 phis = healpix_inputs.latitudes(max_phi, rng=urng) old = healpix.ang2pix(healpix_inputs.nside, thetas, phis, lonlat=lonlat) new = hp.ang2pix(healpix_inputs.nside, thetas, phis, lonlat=lonlat, xp=xp) - xp_assert_equal(old, new) + xp_assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -175,7 +177,7 @@ def test_ang2vec( # noqa: PLR0913 assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xp_assert_equal(old[i], new[i]) + xp_assert_equal(xp.asarray(old[i]), new[i]) def test_get_nside( @@ -201,23 +203,23 @@ def test_map2alm_individual( pol: bool, # noqa: FBT001 urng: UnifiedGenerator, use_pixel_weights: bool, # noqa: FBT001 + xp: ModuleType, ) -> None: """Compare ``glass.healpix.map2alm`` against ``healpy.map2alm``.""" kappa = healpix_inputs.kappa(rng=urng) - xp_assert_equal( - healpy.map2alm( - np.asarray(kappa), - lmax=healpix_inputs.lmax, - pol=pol, - use_pixel_weights=use_pixel_weights, - ), - hp.map2alm( - kappa, - lmax=healpix_inputs.lmax, - pol=pol, - use_pixel_weights=use_pixel_weights, - ), + old = healpy.map2alm( + np.asarray(kappa), + lmax=healpix_inputs.lmax, + pol=pol, + use_pixel_weights=use_pixel_weights, ) + new = hp.map2alm( + kappa, + lmax=healpix_inputs.lmax, + pol=pol, + use_pixel_weights=use_pixel_weights, + ) + xp_assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -234,25 +236,25 @@ def test_map2alm_sequence( pol: bool, # noqa: FBT001 urng: UnifiedGenerator, use_pixel_weights: bool, # noqa: FBT001 + xp: ModuleType, ) -> None: """Compare ``glass.healpix.map2alm`` against ``healpy.map2alm``.""" kappa1 = healpix_inputs.kappa(rng=urng) kappa2 = healpix_inputs.kappa(rng=urng) kappa3 = healpix_inputs.kappa(rng=urng) - xp_assert_equal( - healpy.map2alm( - [np.asarray(kappa1), np.asarray(kappa2), np.asarray(kappa3)], - lmax=healpix_inputs.lmax, - pol=pol, - use_pixel_weights=use_pixel_weights, - ), - hp.map2alm( - [kappa1, kappa2, kappa3], - lmax=healpix_inputs.lmax, - pol=pol, - use_pixel_weights=use_pixel_weights, - ), + old = healpy.map2alm( + [np.asarray(kappa1), np.asarray(kappa2), np.asarray(kappa3)], + lmax=healpix_inputs.lmax, + pol=pol, + use_pixel_weights=use_pixel_weights, ) + new = hp.map2alm( + [kappa1, kappa2, kappa3], + lmax=healpix_inputs.lmax, + pol=pol, + use_pixel_weights=use_pixel_weights, + ) + xp_assert_equal(xp.asarray(old), new) def test_npix2nside(healpix_inputs: type[HealpixInputs]) -> None: @@ -304,7 +306,7 @@ def test_query_strip_float64( old[healpy.query_strip(healpix_inputs.nside, *thetas)] = 0 new = xp.ones(healpix_inputs.npix) new *= 1 - hp.query_strip(healpix_inputs.nside, thetas, dtype=xp.float64, xp=xp) - xp_assert_equal(old, new) + xp_assert_equal(xp.asarray(old), new) @pytest.mark.skipif(not HAVE_ARRAY_API_STRICT, reason="test requires array_api_strict") @@ -355,7 +357,7 @@ def test_randang( assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xp_assert_equal(old[i], new[i]) + xp_assert_equal(xp.asarray(old[i]), new[i]) @pytest.mark.parametrize("coord", ["CE", "GC"]) @@ -363,6 +365,7 @@ def test_rotate_map_pixel( coord: str, healpix_inputs: type[HealpixInputs], urng: UnifiedGenerator, + xp: ModuleType, ) -> None: """ Compare ``glass.healpix.Rotator.rotate_map_pixel`` against @@ -370,7 +373,6 @@ def test_rotate_map_pixel( """ # noqa: D205 kappa = healpix_inputs.kappa(rng=urng) - xp_assert_equal( - healpy.Rotator(coord=coord).rotate_map_pixel(np.asarray(kappa)), - hp.Rotator(coord=coord).rotate_map_pixel(kappa), - ) + old = healpy.Rotator(coord=coord).rotate_map_pixel(np.asarray(kappa)) + new = hp.Rotator(coord=coord).rotate_map_pixel(kappa) + xp_assert_equal(xp.asarray(old), new) From 4ceb12be7cde8fbce283b05e2b6636fc2346c22b Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 15:17:22 +0100 Subject: [PATCH 17/43] Fix all core tests --- tests/core/test_fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index 71644e64..bb7829fb 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -527,7 +527,7 @@ def test_enumerate_spectra(xp: ModuleType) -> None: def test_spectra_indices(xp: ModuleType) -> None: - xp_assert_equal(glass.spectra_indices(0), xp.zeros((0, 2), dtype=xp.int64)) + xp_assert_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2), dtype=xp.int64)) xp_assert_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2), dtype=xp.int64)) xp_assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) xp_assert_equal( From 2ab6cf3e97767d1af19435826df1eb721e084b52 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 15:24:42 +0100 Subject: [PATCH 18/43] Comma --- tests/core/test_fields.py | 3 ++- tests/core/test_user.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index bb7829fb..80b624e6 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -531,7 +531,8 @@ def test_spectra_indices(xp: ModuleType) -> None: xp_assert_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2), dtype=xp.int64)) xp_assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) xp_assert_equal( - glass.spectra_indices(2, xp=xp), xp.asarray([[0, 0], [1, 1], [1, 0]]) + glass.spectra_indices(2, xp=xp), + xp.asarray([[0, 0], [1, 1], [1, 0]]), ) xp_assert_equal( glass.spectra_indices(3, xp=xp), diff --git a/tests/core/test_user.py b/tests/core/test_user.py index e9d89e71..ecf6956a 100644 --- a/tests/core/test_user.py +++ b/tests/core/test_user.py @@ -37,7 +37,8 @@ def test_read_write_cls( np.testing.assert_array_equal(values, np.concat(cls)) np.testing.assert_array_equal( - split, np.cumulative_sum([cl.shape[0] for cl in cls[:-1]]) + split, + np.cumulative_sum([cl.shape[0] for cl in cls[:-1]]), ) np.testing.assert_array_equal(cls, np.split(values, split)) From 097af7e6193dcc301dc190ca5c97f2cd4158d9d3 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 15:26:06 +0100 Subject: [PATCH 19/43] Swap order --- tests/benchmarks/test_arraytools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/benchmarks/test_arraytools.py b/tests/benchmarks/test_arraytools.py index 1f175990..ac5d77c5 100644 --- a/tests/benchmarks/test_arraytools.py +++ b/tests/benchmarks/test_arraytools.py @@ -78,10 +78,10 @@ def test_cumulative_trapezoid_2d( ) x = xpb.arange(scaled_length) # [0, 1, 2, 3,...] - expected_first_4_out = xpb.asarray([0, 1, 4, 7]) - ct = benchmark(glass.arraytools.cumulative_trapezoid, f, x) + expected_first_4_out = xpb.asarray([0, 1, 4, 7]) + # Compare to int64 as old versions of glass round to int64 if `dtype` is not passed. xp_assert_close( xpb.asarray(ct[0, :4], dtype=xpb.int64), From 8d7eafc082d76f7eb2624c2e48178a4e61e4e068 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 15:39:01 +0100 Subject: [PATCH 20/43] Fix NumPy test --- tests/core/test_fields.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index 80b624e6..7570587e 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -3,6 +3,7 @@ import importlib.util from typing import TYPE_CHECKING +import numpy as np import pytest from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal @@ -527,7 +528,7 @@ def test_enumerate_spectra(xp: ModuleType) -> None: def test_spectra_indices(xp: ModuleType) -> None: - xp_assert_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2), dtype=xp.int64)) + xp_assert_equal(glass.spectra_indices(0), np.zeros((0, 2), dtype=np.int64)) xp_assert_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2), dtype=xp.int64)) xp_assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) xp_assert_equal( From 5493d4f76db30b722ed36f0007c59958512ba5c2 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 15:44:38 +0100 Subject: [PATCH 21/43] Remove new line --- tests/core/test_shells.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index e3bd00e4..17e8a1ee 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -7,10 +7,7 @@ import numpy as np import pytest -from array_api_extra._lib._testing import ( - xp_assert_close, - xp_assert_less, -) +from array_api_extra._lib._testing import xp_assert_close, xp_assert_less import glass from glass._array_api_utils import xp_additions as uxpx From b6e1cc242d6d814a1e47e1b0946e2f28d54daa5d Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 21 May 2026 15:50:07 +0100 Subject: [PATCH 22/43] Change to `xp_` test --- tests/core/test_shells.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index 17e8a1ee..6df67457 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -411,7 +411,7 @@ def test_combine(xp: ModuleType) -> None: assert result.shape == z.shape # Check sum of result - assert sum(result) == 929.2672844944944 + xp_assert_close(xp.sum(result), xp.asarray(929.267284)) # Check integral w.r.t z has not changed xp_assert_close(uxpx.trapezoid(result, z), xp.asarray(4.643139), rtol=1e-6) From 1c6a64cc03308b4faaf8eb551d03ae255cfe36cf Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Tue, 26 May 2026 16:51:50 +0100 Subject: [PATCH 23/43] Change to new assert names --- tests/benchmarks/test_arraytools.py | 8 +-- tests/benchmarks/test_fields.py | 16 +++--- tests/benchmarks/test_harmonics.py | 4 +- tests/benchmarks/test_lensing.py | 10 ++-- tests/benchmarks/test_shells.py | 4 +- tests/core/grf/test_solver.py | 16 +++--- tests/core/grf/test_transformations.py | 26 ++++----- tests/core/test_algorithm.py | 11 ++-- tests/core/test_arraytools.py | 30 +++++----- tests/core/test_fields.py | 63 +++++++++++---------- tests/core/test_galaxies.py | 12 ++-- tests/core/test_harmonics.py | 12 ++-- tests/core/test_healpix.py | 26 ++++----- tests/core/test_lensing.py | 30 +++++----- tests/core/test_observations.py | 22 ++++---- tests/core/test_points.py | 77 +++++++++++++------------- tests/core/test_shapes.py | 74 +++++++++++++++++++------ tests/core/test_shells.py | 30 +++++----- 18 files changed, 258 insertions(+), 213 deletions(-) diff --git a/tests/benchmarks/test_arraytools.py b/tests/benchmarks/test_arraytools.py index ac5d77c5..63409f37 100644 --- a/tests/benchmarks/test_arraytools.py +++ b/tests/benchmarks/test_arraytools.py @@ -4,7 +4,7 @@ import pytest -from array_api_extra._lib._testing import xp_assert_close +import array_api_extra as xpx import glass.arraytools @@ -55,7 +55,7 @@ def test_cumulative_trapezoid_1d( ct = benchmark(glass.arraytools.cumulative_trapezoid, f, x) # Compare to int64 as old versions of glass round to int64 if `dtype` is not passed. - xp_assert_close( + xpx.testing.assert_close( xpb.asarray(ct[:4], dtype=xpb.int64), xpb.asarray([0, 1, 4, 7]), ) @@ -83,11 +83,11 @@ def test_cumulative_trapezoid_2d( expected_first_4_out = xpb.asarray([0, 1, 4, 7]) # Compare to int64 as old versions of glass round to int64 if `dtype` is not passed. - xp_assert_close( + xpx.testing.assert_close( xpb.asarray(ct[0, :4], dtype=xpb.int64), expected_first_4_out, ) - xp_assert_close( + xpx.testing.assert_close( xpb.asarray(ct[1, :4], dtype=xpb.int64), expected_first_4_out, ) diff --git a/tests/benchmarks/test_fields.py b/tests/benchmarks/test_fields.py index 6e6c935f..ac6dfdd3 100644 --- a/tests/benchmarks/test_fields.py +++ b/tests/benchmarks/test_fields.py @@ -5,7 +5,7 @@ import pytest -from array_api_extra._lib._testing import xp_assert_close +import array_api_extra as xpx import glass import glass.fields @@ -120,7 +120,7 @@ def function_to_benchmark() -> list[Any]: j, a, s = results[0] assert j is None assert a.shape == (0,) - xp_assert_close(s, xpb.ones_like(s)) + xpx.testing.assert_close(s, xpb.ones_like(s)) @pytest.mark.stable @@ -148,9 +148,9 @@ def function_to_benchmark() -> list[Any]: assert cov.shape == (nl, nc + 1) assert cov.dtype == xpb.float64 - xp_assert_close(cov[:, 0], xpb.asarray([1.0, 1.5, 2.0])) - xp_assert_close(cov[:, 1], xpb.asarray([1.5, 2.0, 2.5])) - xp_assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) + xpx.testing.assert_close(cov[:, 0], xpb.asarray([1.0, 1.5, 2.0])) + xpx.testing.assert_close(cov[:, 1], xpb.asarray([1.5, 2.0, 2.5])) + xpx.testing.assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) @pytest.mark.stable @@ -213,7 +213,7 @@ def function_to_benchmark() -> list[Any]: for field in result: assert field.shape == (hp.nside2npix(nside),) - xp_assert_close(result[1], result[0] ** 2, atol=1e-05) + xpx.testing.assert_close(result[1], result[0] ** 2, atol=1e-05) @pytest.mark.unstable @@ -243,7 +243,7 @@ def test_getcl_lmax_0( ) expected = xpb.asarray([max(random_i, random_j)], dtype=xpb.float64) assert result.shape[0] == 1 - xp_assert_close(result, expected) + xpx.testing.assert_close(result, expected) @pytest.mark.unstable @@ -274,4 +274,4 @@ def test_getcl_lmax_larger_than_cls( ) expected = xpb.zeros((lmax - 1,), dtype=xpb.float64) assert result.shape[0] == lmax + 1 - xp_assert_close(result[2:], expected) + xpx.testing.assert_close(result[2:], expected) diff --git a/tests/benchmarks/test_harmonics.py b/tests/benchmarks/test_harmonics.py index 48ffd492..d0953bd6 100644 --- a/tests/benchmarks/test_harmonics.py +++ b/tests/benchmarks/test_harmonics.py @@ -4,7 +4,7 @@ import pytest -from array_api_extra._lib._testing import xp_assert_close +import array_api_extra as xpx glass_harmonics = pytest.importorskip( "glass.harmonics", @@ -31,7 +31,7 @@ def test_multalm( result = benchmark(glass_harmonics.multalm, alm, bl) - xp_assert_close( + xpx.testing.assert_close( result[:5], xpb.asarray([scale_factor * x for x in [0.0, 3.0, 6.0, 9.0, 12.0]]), ) diff --git a/tests/benchmarks/test_lensing.py b/tests/benchmarks/test_lensing.py index eb39cd30..9aa37867 100644 --- a/tests/benchmarks/test_lensing.py +++ b/tests/benchmarks/test_lensing.py @@ -4,7 +4,7 @@ import pytest -from array_api_extra._lib._testing import xp_assert_equal +import array_api_extra as xpx import glass @@ -38,8 +38,8 @@ def test_multi_plane_matrix( mat = glass.multi_plane_matrix(shells, cosmo) deltas = urngb.random((len(shells), 10)) - xp_assert_equal(mat, xpb.tril(mat)) - xp_assert_equal(xpb.triu(mat, k=1), xpb.zeros_like(mat)) + xpx.testing.assert_equal(mat, xpb.tril(mat)) + xpx.testing.assert_equal(xpb.triu(mat, k=1), xpb.zeros_like(mat)) def setup_shells_and_deltas() -> tuple[ tuple[ @@ -99,8 +99,8 @@ def test_multi_plane_weights( w_out = glass.multi_plane_weights(w_in, shells, cosmo) - xp_assert_equal(w_out, xpb.triu(w_out, 1)) - xp_assert_equal(xpb.tril(w_out), xpb.zeros_like(w_out)) + xpx.testing.assert_equal(w_out, xpb.triu(w_out, 1)) + xpx.testing.assert_equal(xpb.tril(w_out), xpb.zeros_like(w_out)) def setup_shells_deltas_and_weights() -> tuple[ tuple[ diff --git a/tests/benchmarks/test_shells.py b/tests/benchmarks/test_shells.py index e58fc8fd..5d187832 100644 --- a/tests/benchmarks/test_shells.py +++ b/tests/benchmarks/test_shells.py @@ -4,7 +4,7 @@ import pytest -from array_api_extra._lib._testing import xp_assert_close +import array_api_extra as xpx import glass @@ -29,4 +29,4 @@ def test_radialwindow( w = benchmark(glass.RadialWindow, za, wa) - xp_assert_close(w.zeff, xpb.asarray(expected_zeff)) + xpx.testing.assert_close(w.zeff, xpb.asarray(expected_zeff)) diff --git a/tests/core/grf/test_solver.py b/tests/core/grf/test_solver.py index 6788923f..d3f3e8ce 100644 --- a/tests/core/grf/test_solver.py +++ b/tests/core/grf/test_solver.py @@ -5,7 +5,7 @@ import numpy as np import pytest -from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal +import array_api_extra as xpx import glass.grf @@ -30,7 +30,7 @@ def test_one_transformation( gl1, _, _ = glass.grf.solve(cl, t) gl2, _, _ = glass.grf.solve(cl, t, t) - xp_assert_equal(gl1, gl2) + xpx.testing.assert_equal(gl1, gl2) def test_pad( @@ -61,7 +61,7 @@ def test_initial( gl1, _, _ = glass.grf.solve(cl, t) gl2, _, _ = glass.grf.solve(cl, t, initial=gl) - xp_assert_equal(gl1, gl2) + xpx.testing.assert_equal(gl1, gl2) def test_no_iterations(cl: FloatArray) -> None: @@ -70,7 +70,7 @@ def test_no_iterations(cl: FloatArray) -> None: gl1 = glass.grf.compute(cl, t) gl2, _, _ = glass.grf.solve(cl, t, maxiter=0) - xp_assert_equal(gl1, gl2) + xpx.testing.assert_equal(gl1, gl2) def test_lognormal( @@ -88,12 +88,12 @@ def test_lognormal( assert info > 0 - xp_assert_close(cl_[1 : cl.shape[0]], cl[1:], atol=0.0, rtol=cltol) + xpx.testing.assert_close(cl_[1 : cl.shape[0]], cl[1:], atol=0.0, rtol=cltol) gl_ = glass.grf.compute(cl_, t1, t2) assert gl[0] == gl0 - xp_assert_close(gl_[1 : gl.shape[0]], gl[1:]) + xpx.testing.assert_close(gl_[1 : gl.shape[0]], gl[1:]) def test_monopole( @@ -108,10 +108,10 @@ def test_monopole( gl, cl_out, _ = glass.grf.solve(cl, t, monopole=None, gltol=1e-8) assert gl[0] != 0.0 - xp_assert_close(cl_out[0], cl[0]) + xpx.testing.assert_close(cl_out[0], cl[0]) gl, cl_out, _ = glass.grf.solve(cl, t, monopole=gl0, gltol=1e-8) assert gl[0] == gl0 with pytest.raises(AssertionError, match="Not equal to tolerance"): - xp_assert_close(cl_out[0], cl[0]) + xpx.testing.assert_close(cl_out[0], cl[0]) diff --git a/tests/core/grf/test_transformations.py b/tests/core/grf/test_transformations.py index 073781a2..1b4fc755 100644 --- a/tests/core/grf/test_transformations.py +++ b/tests/core/grf/test_transformations.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING -from array_api_extra._lib._testing import xp_assert_equal +import array_api_extra as xpx import glass.grf @@ -16,7 +16,7 @@ def test_normal(urng: UnifiedGenerator) -> None: t = glass.grf.Normal() x = urng.standard_normal(10) - xp_assert_equal(t(x, 1.0), x) + xpx.testing.assert_equal(t(x, 1.0), x) def test_lognormal( @@ -28,7 +28,7 @@ def test_lognormal( t = glass.grf.Lognormal(lam) x = urng.standard_normal(10) y = lam * xp.expm1(x - var / 2) - xp_assert_equal(t(x, var), y) + xpx.testing.assert_equal(t(x, var), y) def test_sqnormal( @@ -41,7 +41,7 @@ def test_sqnormal( t = glass.grf.SquaredNormal(a, lam) x = urng.standard_normal(10) y = lam * ((x - a) ** 2 - 1) - xp_assert_equal(t(x, var), y) + xpx.testing.assert_equal(t(x, var), y) def test_normal_normal( @@ -51,9 +51,9 @@ def test_normal_normal( t1 = glass.grf.Normal() t2 = glass.grf.Normal() x = urng.random(10) - xp_assert_equal(glass.grf.corr(t1, t2, x), x) - xp_assert_equal(glass.grf.icorr(t1, t2, x), x) - xp_assert_equal(glass.grf.dcorr(t1, t2, x), xp.ones_like(x)) + xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), x) + xpx.testing.assert_equal(glass.grf.icorr(t1, t2, x), x) + xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), xp.ones_like(x)) def test_lognormal_lognormal( @@ -71,9 +71,9 @@ def test_lognormal_lognormal( y = lam1 * lam2 * xp.expm1(x) dy = lam1 * lam2 * xp.exp(x) - xp_assert_equal(glass.grf.corr(t1, t2, x), y) + xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) compare.assert_array_almost_equal_nulp(glass.grf.icorr(t1, t2, y), x) - xp_assert_equal(glass.grf.dcorr(t1, t2, x), dy) + xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) def test_lognormal_normal( @@ -90,9 +90,9 @@ def test_lognormal_normal( y = lam1 * x dy = lam1 * xp.ones_like(x) - xp_assert_equal(glass.grf.corr(t1, t2, x), y) + xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) compare.assert_array_almost_equal_nulp(glass.grf.icorr(t1, t2, y), x) - xp_assert_equal(glass.grf.dcorr(t1, t2, x), dy) + xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) def test_sqnormal_sqnormal( @@ -113,6 +113,6 @@ def test_sqnormal_sqnormal( y = 2 * lam1 * lam2 * x * (x + 2 * a1 * a2) dy = 4 * lam1 * lam2 * (x + a1 * a2) - xp_assert_equal(glass.grf.corr(t1, t2, x), y) + xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) compare.assert_array_almost_equal_nulp(glass.grf.icorr(t1, t2, y), x, nulp=8) - xp_assert_equal(glass.grf.dcorr(t1, t2, x), dy) + xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) diff --git a/tests/core/test_algorithm.py b/tests/core/test_algorithm.py index f1e9d460..b5794365 100644 --- a/tests/core/test_algorithm.py +++ b/tests/core/test_algorithm.py @@ -5,7 +5,6 @@ import pytest import array_api_extra as xpx -from array_api_extra._lib._testing import xp_assert_close import glass.algorithm @@ -40,7 +39,7 @@ def test_nnls( x, tol=500 * xp.linalg.matrix_norm(a, ord=1) * xp.finfo(xp.float64).eps, ) - xp_assert_close(res, b, rtol=0.0, atol=1e-10) + xpx.testing.assert_close(res, b, rtol=0.0, atol=1e-10) # check matrix and vector's shape @@ -76,7 +75,7 @@ def test_cov_clip( # make sure all eigenvalues are positive h = xp.max(xp.linalg.eigvalsh(a)) - xp_assert_close(xp.linalg.eigvalsh(cov), h * xp.ones(cov.shape[0])) + xpx.testing.assert_close(xp.linalg.eigvalsh(cov), h * xp.ones(cov.shape[0])) def test_nearcorr(xp: ModuleType) -> None: @@ -97,11 +96,11 @@ def test_nearcorr(xp: ModuleType) -> None: ) x = glass.algorithm.nearcorr(a) - xp_assert_close(x, b, atol=1e-4) + xpx.testing.assert_close(x, b, atol=1e-4) # explicit tolerance x = glass.algorithm.nearcorr(a, tol=1e-10) - xp_assert_close(x, b, atol=1e-4) + xpx.testing.assert_close(x, b, atol=1e-4) # no iterations with pytest.warns( @@ -109,7 +108,7 @@ def test_nearcorr(xp: ModuleType) -> None: match="Nearest correlation matrix not found in 0 iterations", ): x = glass.algorithm.nearcorr(a, niter=0) - xp_assert_close(x, a) + xpx.testing.assert_close(x, a) # non-square matrix should raise with pytest.raises(ValueError, match="non-square matrix"): diff --git a/tests/core/test_arraytools.py b/tests/core/test_arraytools.py index 96d634fb..ca750bba 100644 --- a/tests/core/test_arraytools.py +++ b/tests/core/test_arraytools.py @@ -4,7 +4,7 @@ import pytest -from array_api_extra._lib._testing import xp_assert_close +import array_api_extra as xpx import glass.arraytools @@ -68,17 +68,17 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == () - xp_assert_close(y, xp.asarray(1.15), atol=1e-15) + xpx.testing.assert_close(y, xp.asarray(1.15), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (3,) - xp_assert_close(y, xp.asarray([1.15, 1.25, 1.35]), atol=1e-15) + xpx.testing.assert_close(y, xp.asarray([1.15, 1.25, 1.35]), atol=1e-15) x = xp.asarray([[0.5, 1.5], [2.5, 3.5]]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 2) - xp_assert_close(y, xp.asarray([[1.15, 1.25], [1.35, 1.45]]), atol=1e-15) + xpx.testing.assert_close(y, xp.asarray([[1.15, 1.25], [1.35, 1.45]]), atol=1e-15) # test n-dimensional interpolation in final axis @@ -87,17 +87,21 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2,) - xp_assert_close(y, xp.asarray([1.15, 2.15]), atol=1e-15) + xpx.testing.assert_close(y, xp.asarray([1.15, 2.15]), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 3) - xp_assert_close(y, xp.asarray([[1.15, 1.25, 1.35], [2.15, 2.25, 2.35]]), atol=1e-15) + xpx.testing.assert_close( + y, + xp.asarray([[1.15, 1.25, 1.35], [2.15, 2.25, 2.35]]), + atol=1e-15, + ) x = xp.asarray([[0.5, 1.5], [2.5, 3.5]]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 2, 2) - xp_assert_close( + xpx.testing.assert_close( y, xp.asarray([[[1.15, 1.25], [1.35, 1.45]], [[2.15, 2.25], [2.35, 2.45]]]), atol=1e-15, @@ -112,12 +116,12 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 1) - xp_assert_close(y, xp.asarray([[1.15], [2.15]]), atol=1e-15) + xpx.testing.assert_close(y, xp.asarray([[1.15], [2.15]]), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 3, 1) - xp_assert_close( + xpx.testing.assert_close( y, xp.asarray([[[1.15], [1.25], [1.35]], [[2.15], [2.25], [2.35]]]), atol=1e-15, @@ -126,7 +130,7 @@ def test_ndinterp(xp: ModuleType) -> None: x = xp.asarray([[0.5, 1.5, 2.5, 3.5], [3.5, 2.5, 1.5, 0.5], [0.5, 3.5, 1.5, 2.5]]) y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 3, 4, 1) - xp_assert_close( + xpx.testing.assert_close( y, xp.asarray([ [ @@ -153,7 +157,7 @@ def test_trapezoid_product(xp: ModuleType) -> None: s = glass.arraytools.trapezoid_product((x1, f1), (x2, f2)) - xp_assert_close(s, xp.ones_like(s)) + xpx.testing.assert_close(s, xp.ones_like(s)) def test_cumulative_trapezoid(xp: ModuleType) -> None: @@ -163,14 +167,14 @@ def test_cumulative_trapezoid(xp: ModuleType) -> None: x = xp.asarray([0, 1, 2, 3]) ct = glass.arraytools.cumulative_trapezoid(f, x) - xp_assert_close(ct, xp.asarray([0.0, 1.5, 4.0, 7.5])) + xpx.testing.assert_close(ct, xp.asarray([0.0, 1.5, 4.0, 7.5])) # 2D f and 1D x f = xp.asarray([[1, 4, 9, 16], [2, 3, 5, 7]]) x = xp.asarray([0, 1, 2.5, 4]) ct = glass.arraytools.cumulative_trapezoid(f, x) - xp_assert_close( + xpx.testing.assert_close( ct, xp.asarray([[0.0, 2.5, 12.25, 31.0], [0.0, 2.5, 8.5, 17.5]]), ) diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index 7570587e..3f8591e4 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -6,7 +6,7 @@ import numpy as np import pytest -from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal +import array_api_extra as xpx import glass import glass.fields @@ -175,14 +175,14 @@ def test_cls2cov_jax(jnp: ModuleType) -> None: assert cov3.dtype == jnp.float64 # cov1 has the expected value for the first iteration (different to cov1_copy) - xp_assert_close(cov1[:, 0], jnp.asarray([0.5, 0.25, 0.15])) + xpx.testing.assert_close(cov1[:, 0], jnp.asarray([0.5, 0.25, 0.15])) # The copies should not be equal with pytest.raises(AssertionError, match="Not equal to tolerance"): - xp_assert_close(cov1, cov2) + xpx.testing.assert_close(cov1, cov2) with pytest.raises(AssertionError, match="Not equal to tolerance"): - xp_assert_close(cov2, cov3) + xpx.testing.assert_close(cov2, cov3) def test_cls2cov_no_jax(xpb: ModuleType) -> None: @@ -201,9 +201,9 @@ def test_cls2cov_no_jax(xpb: ModuleType) -> None: assert cov.shape == (nl, nc + 1) assert cov.dtype == xpb.float64 - xp_assert_close(cov[:, 0], xpb.asarray([0.5, 0.25, 0.15])) - xp_assert_close(cov[:, 1], xpb.zeros_like(cov[:, 1])) - xp_assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) + xpx.testing.assert_close(cov[:, 0], xpb.asarray([0.5, 0.25, 0.15])) + xpx.testing.assert_close(cov[:, 1], xpb.zeros_like(cov[:, 1])) + xpx.testing.assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) # test negative value error @@ -259,19 +259,19 @@ def test_cls2cov_no_jax(xpb: ModuleType) -> None: assert cov3.dtype == xpb.float64 # cov1|2|3 reuse the same data, so should all equal the third result - xp_assert_close(cov1[:, 0], xpb.asarray([0.45, 0.25, 0.15])) - xp_assert_close(cov1, cov2) - xp_assert_close(cov2, cov3) + xpx.testing.assert_close(cov1[:, 0], xpb.asarray([0.45, 0.25, 0.15])) + xpx.testing.assert_close(cov1, cov2) + xpx.testing.assert_close(cov2, cov3) # cov1 has the expected value for the first iteration (different to cov1_copy) - xp_assert_close(cov1_copy[:, 0], xpb.asarray([0.5, 0.25, 0.15])) + xpx.testing.assert_close(cov1_copy[:, 0], xpb.asarray([0.5, 0.25, 0.15])) # The copies should not be equal with pytest.raises(AssertionError, match="Not equal to tolerance"): - xp_assert_close(cov1_copy, cov2_copy) + xpx.testing.assert_close(cov1_copy, cov2_copy) with pytest.raises(AssertionError, match="Not equal to tolerance"): - xp_assert_close(cov2_copy, cov3) + xpx.testing.assert_close(cov2_copy, cov3) def test_lognormal_gls(xp: ModuleType) -> None: @@ -341,7 +341,7 @@ def test_discretized_cls(xp: ModuleType) -> None: for cl in result: n = min(cl.shape[0], pw.shape[0]) # ty: ignore[unresolved-attribute] expected = xp.ones(n) * pw[:n] ** 2 - xp_assert_close(cl[:n], expected) + xpx.testing.assert_close(cl[:n], expected) def test_effective_cls(xp: ModuleType) -> None: @@ -373,7 +373,7 @@ def test_effective_cls(xp: ModuleType) -> None: result = glass.effective_cls(cls, weights1, lmax=5) assert result.shape == (1, 1, 6) - xp_assert_close(result[..., 6:], xp.zeros_like(result[..., 6:])) + xpx.testing.assert_close(result[..., 6:], xp.zeros_like(result[..., 6:])) # check with weights1 and weights2 and weights1 is weights2 @@ -404,7 +404,7 @@ def test_generate_grf(xp: ModuleType) -> None: assert new_gaussian_fields[0].shape == (hp.nside2npix(nside),) - xp_assert_close(new_gaussian_fields[0], gaussian_fields[0]) + xpx.testing.assert_close(new_gaussian_fields[0], gaussian_fields[0]) with pytest.raises(ValueError, match="all gls are empty"): list(glass.fields._generate_grf([xp.asarray([])], nside)) @@ -457,7 +457,7 @@ def test_generate(xp: ModuleType) -> None: result = list(glass.generate(fields, gls, nside=nside)) - xp_assert_close(result[1], result[0] ** 2, atol=1e-05) + xpx.testing.assert_close(result[1], result[0] ** 2, atol=1e-05) def test_getcl(xp: ModuleType) -> None: @@ -472,19 +472,19 @@ def test_getcl(xp: ModuleType) -> None: for j in range(10): result = glass.getcl(cls, i, j) expected = xp.asarray([min(i, j), max(i, j)], dtype=xp.float64) - xp_assert_close(xp.sort(result), expected) + xpx.testing.assert_close(xp.sort(result), expected) # check slicing result = glass.getcl(cls, i, j, lmax=0) expected = xp.asarray([max(i, j)], dtype=xp.float64) assert result.shape[0] == 1 - xp_assert_close(result, expected) + xpx.testing.assert_close(result, expected) # check padding result = glass.getcl(cls, i, j, lmax=50) expected = xp.zeros((49,), dtype=xp.float64) assert result.shape[0] == 51 - xp_assert_close(result[2:], expected) + xpx.testing.assert_close(result[2:], expected) def test_is_inv_triangle_number(not_triangle_numbers: list[int]) -> None: @@ -528,14 +528,17 @@ def test_enumerate_spectra(xp: ModuleType) -> None: def test_spectra_indices(xp: ModuleType) -> None: - xp_assert_equal(glass.spectra_indices(0), np.zeros((0, 2), dtype=np.int64)) - xp_assert_equal(glass.spectra_indices(0, xp=xp), xp.zeros((0, 2), dtype=xp.int64)) - xp_assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) - xp_assert_equal( + xpx.testing.assert_equal(glass.spectra_indices(0), np.zeros((0, 2), dtype=np.int64)) + xpx.testing.assert_equal( + glass.spectra_indices(0, xp=xp), + xp.zeros((0, 2), dtype=xp.int64), + ) + xpx.testing.assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) + xpx.testing.assert_equal( glass.spectra_indices(2, xp=xp), xp.asarray([[0, 0], [1, 1], [1, 0]]), ) - xp_assert_equal( + xpx.testing.assert_equal( glass.spectra_indices(3, xp=xp), xp.asarray([[0, 0], [1, 1], [1, 0], [2, 2], [2, 1], [2, 0]]), ) @@ -667,7 +670,7 @@ def test_healpix_to_glass_spectra() -> None: def test_glass_to_healpix_alm(xp: ModuleType) -> None: inp = xp.asarray([00, 10, 11, 20, 21, 22, 30, 31, 32, 33], dtype=xp.complex128) out = glass.fields._glass_to_healpix_alm(inp) - xp_assert_equal( + xpx.testing.assert_equal( out, xp.asarray([00, 10, 20, 30, 11, 21, 31, 22, 32, 33], dtype=xp.complex128), ) @@ -689,7 +692,7 @@ def test_lognormal_shift_hilbert2011(xp: ModuleType) -> None: 0.1568, ]) - xp_assert_close(shifts, check, atol=1e-4, rtol=1e-4) + xpx.testing.assert_close(shifts, check, atol=1e-4, rtol=1e-4) def test_cov_from_spectra(xp: ModuleType) -> None: @@ -705,7 +708,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: ] ] - xp_assert_equal( + xpx.testing.assert_equal( glass.cov_from_spectra(spectra), xp.asarray([ [ @@ -731,7 +734,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: ]), ) - xp_assert_equal( + xpx.testing.assert_equal( glass.cov_from_spectra(spectra, lmax=1), xp.asarray([ [ @@ -747,7 +750,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: ]), ) - xp_assert_equal( + xpx.testing.assert_equal( glass.cov_from_spectra(spectra, lmax=4), xp.asarray([ [ diff --git a/tests/core/test_galaxies.py b/tests/core/test_galaxies.py index 7276c675..e086784b 100644 --- a/tests/core/test_galaxies.py +++ b/tests/core/test_galaxies.py @@ -4,7 +4,7 @@ import pytest -from array_api_extra._lib._testing import xp_assert_equal +import array_api_extra as xpx import glass @@ -218,13 +218,13 @@ def test_gaussian_phz( phz = glass.gaussian_phz(z, sigma_0) - xp_assert_equal(z, phz) + xpx.testing.assert_equal(z, phz) # test with rng phz = glass.gaussian_phz(z, sigma_0, rng=urng) - xp_assert_equal(z, phz) + xpx.testing.assert_equal(z, phz) # case: truncated normal @@ -270,7 +270,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - xp_assert_equal(z, phz) + xpx.testing.assert_equal(z, phz) # case: scalar redshift, array sigma_0 @@ -281,7 +281,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - xp_assert_equal(z * xp.ones_like(phz), phz) + xpx.testing.assert_equal(z * xp.ones_like(phz), phz) # case: array redshift, array sigma_0 @@ -292,7 +292,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (11, 10) - xp_assert_equal(xp.broadcast_to(z, (11, 10)), phz) + xpx.testing.assert_equal(xp.broadcast_to(z, (11, 10)), phz) # shape mismatch diff --git a/tests/core/test_harmonics.py b/tests/core/test_harmonics.py index b812177b..e00d2b91 100644 --- a/tests/core/test_harmonics.py +++ b/tests/core/test_harmonics.py @@ -4,7 +4,7 @@ import pytest -from array_api_extra._lib._testing import xp_assert_close +import array_api_extra as xpx import glass.harmonics @@ -22,9 +22,9 @@ def test_multalm(xp: ModuleType) -> None: result = glass.harmonics.multalm(alm, bl) expected_result = xp.asarray([2.0, 1.0, 1.5, 4.0, 5.0, 6.0]) - xp_assert_close(result, expected_result) + xpx.testing.assert_close(result, expected_result) with pytest.raises(AssertionError, match="Not equal to tolerance"): - xp_assert_close(alm_copy, result) + xpx.testing.assert_close(alm_copy, result) # multiple with 1s @@ -32,7 +32,7 @@ def test_multalm(xp: ModuleType) -> None: bl = xp.ones(3) result = glass.harmonics.multalm(alm, bl) - xp_assert_close(result, alm) + xpx.testing.assert_close(result, alm) # multiple with 0s @@ -41,7 +41,7 @@ def test_multalm(xp: ModuleType) -> None: result = glass.harmonics.multalm(alm, bl) expected_result = xp.asarray([0.0, 2.0, 3.0, 0.0, 0.0, 0.0]) - xp_assert_close(result, expected_result) + xpx.testing.assert_close(result, expected_result) # empty arrays @@ -49,4 +49,4 @@ def test_multalm(xp: ModuleType) -> None: bl = xp.asarray([]) result = glass.harmonics.multalm(alm, bl) - xp_assert_close(result, alm) + xpx.testing.assert_close(result, alm) diff --git a/tests/core/test_healpix.py b/tests/core/test_healpix.py index de36f7d3..116e7f4f 100644 --- a/tests/core/test_healpix.py +++ b/tests/core/test_healpix.py @@ -9,7 +9,7 @@ import numpy as np import pytest -from array_api_extra._lib._testing import xp_assert_equal +import array_api_extra as xpx import glass.healpix as hp from glass import _rng @@ -55,7 +55,7 @@ def test_alm2map_individual( pixwin=pixwin, pol=pol, ) - xp_assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -92,7 +92,7 @@ def test_alm2map_sequence( pixwin=pixwin, pol=pol, ) - xp_assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize("spin", [1, 2]) @@ -115,7 +115,7 @@ def test_alm2map_spin( assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xp_assert_equal(xp.asarray(old[i]), new[i]) + xpx.testing.assert_equal(xp.asarray(old[i]), new[i]) def test_almxfl( @@ -128,7 +128,7 @@ def test_almxfl( fl = healpix_inputs.fl(rng=urng) old = healpy.almxfl(alm, fl) new = hp.almxfl(alm, fl) - xp_assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -151,7 +151,7 @@ def test_ang2pix( # noqa: PLR0913 phis = healpix_inputs.latitudes(max_phi, rng=urng) old = healpix.ang2pix(healpix_inputs.nside, thetas, phis, lonlat=lonlat) new = hp.ang2pix(healpix_inputs.nside, thetas, phis, lonlat=lonlat, xp=xp) - xp_assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -177,7 +177,7 @@ def test_ang2vec( # noqa: PLR0913 assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xp_assert_equal(xp.asarray(old[i]), new[i]) + xpx.testing.assert_equal(xp.asarray(old[i]), new[i]) def test_get_nside( @@ -219,7 +219,7 @@ def test_map2alm_individual( pol=pol, use_pixel_weights=use_pixel_weights, ) - xp_assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -254,7 +254,7 @@ def test_map2alm_sequence( pol=pol, use_pixel_weights=use_pixel_weights, ) - xp_assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) def test_npix2nside(healpix_inputs: type[HealpixInputs]) -> None: @@ -285,7 +285,7 @@ def test_pixwin( assert len(old) == len(new) for i in range(len(old)): - xp_assert_equal(xp.asarray(old[i], dtype=xp.float64), new[i]) + xpx.testing.assert_equal(xp.asarray(old[i], dtype=xp.float64), new[i]) @pytest.mark.parametrize("thetas", [((20, 80)), ((30, 90))]) @@ -306,7 +306,7 @@ def test_query_strip_float64( old[healpy.query_strip(healpix_inputs.nside, *thetas)] = 0 new = xp.ones(healpix_inputs.npix) new *= 1 - hp.query_strip(healpix_inputs.nside, thetas, dtype=xp.float64, xp=xp) - xp_assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.skipif(not HAVE_ARRAY_API_STRICT, reason="test requires array_api_strict") @@ -357,7 +357,7 @@ def test_randang( assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xp_assert_equal(xp.asarray(old[i]), new[i]) + xpx.testing.assert_equal(xp.asarray(old[i]), new[i]) @pytest.mark.parametrize("coord", ["CE", "GC"]) @@ -375,4 +375,4 @@ def test_rotate_map_pixel( kappa = healpix_inputs.kappa(rng=urng) old = healpy.Rotator(coord=coord).rotate_map_pixel(np.asarray(kappa)) new = hp.Rotator(coord=coord).rotate_map_pixel(kappa) - xp_assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) diff --git a/tests/core/test_lensing.py b/tests/core/test_lensing.py index 3c65a5fa..155d5a3a 100644 --- a/tests/core/test_lensing.py +++ b/tests/core/test_lensing.py @@ -5,7 +5,7 @@ import pytest -from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal +import array_api_extra as xpx import glass import glass.healpix as hp @@ -69,8 +69,8 @@ def test_multi_plane_matrix( ) -> None: mat = glass.multi_plane_matrix(shells, cosmo) - xp_assert_equal(mat, xp.tril(mat)) - xp_assert_equal(xp.triu(mat, k=1), xp.zeros_like(mat)) + xpx.testing.assert_equal(mat, xp.tril(mat)) + xpx.testing.assert_equal(xp.triu(mat, k=1), xp.zeros_like(mat)) convergence = glass.MultiPlaneConvergence(cosmo) @@ -83,7 +83,7 @@ def test_multi_plane_matrix( if convergence.kappa is not None: kappas.append(xp.asarray(convergence.kappa, copy=True)) - xp_assert_close(mat @ deltas, xp.stack(kappas)) + xpx.testing.assert_close(mat @ deltas, xp.stack(kappas)) def test_multi_plane_weights( @@ -95,8 +95,8 @@ def test_multi_plane_weights( w_in = xp.eye(len(shells)) w_out = glass.multi_plane_weights(w_in, shells, cosmo) - xp_assert_equal(w_out, xp.triu(w_out, k=1)) - xp_assert_equal(xp.tril(w_out), xp.zeros_like(w_out)) + xpx.testing.assert_equal(w_out, xp.triu(w_out, k=1)) + xpx.testing.assert_equal(xp.tril(w_out), xp.zeros_like(w_out)) convergence = glass.MultiPlaneConvergence(cosmo) @@ -114,7 +114,7 @@ def test_multi_plane_weights( wmat = glass.multi_plane_weights(weights, shells, cosmo) - xp_assert_close(uxpx.einsum("ij,ik", wmat, deltas), kappa) + xpx.testing.assert_close(uxpx.einsum("ij,ik", wmat, deltas), kappa) @pytest.mark.parametrize("usecomplex", [True, False]) @@ -135,19 +135,19 @@ def alpha( # north lon, lat = glass.deflect(0.0, 0.0, alpha(r, 0, usecomplex=usecomplex), xp=xp) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d]), atol=1e-15) # south lon, lat = glass.deflect(0.0, 0.0, alpha(-r, 0, usecomplex=usecomplex), xp=xp) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.deflect(0.0, 0.0, alpha(0, r, usecomplex=usecomplex), xp=xp) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) # west lon, lat = glass.deflect(0.0, 0.0, alpha(0, -r, usecomplex=usecomplex), xp=xp) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # At least one input is an array lon, lat = glass.deflect( @@ -155,15 +155,15 @@ def alpha( xp.asarray(0.0), alpha(0, -r, usecomplex=usecomplex), ) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) lon, lat = glass.deflect( xp.asarray([0.0, 0.0]), xp.asarray([0.0, 0.0]), alpha(0, -r, usecomplex=usecomplex), ) - xp_assert_close(lon, xp.asarray([d, d]), atol=1e-15) - xp_assert_close(lat, xp.asarray([0.0, 0.0]), atol=1e-15) + xpx.testing.assert_close(lon, xp.asarray([d, d]), atol=1e-15) + xpx.testing.assert_close(lat, xp.asarray([0.0, 0.0]), atol=1e-15) # No inputs are arrays and xp not provided with pytest.raises( @@ -191,4 +191,4 @@ def test_deflect_many( dotp = x * x_ + y * y_ + z * z_ - xp_assert_close(dotp, xp.cos(abs_alpha)) + xpx.testing.assert_close(dotp, xp.cos(abs_alpha)) diff --git a/tests/core/test_observations.py b/tests/core/test_observations.py index 950043c2..cac05ccf 100644 --- a/tests/core/test_observations.py +++ b/tests/core/test_observations.py @@ -6,7 +6,7 @@ import numpy as np import pytest -from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal +import array_api_extra as xpx import glass import glass.healpix as hp @@ -35,7 +35,7 @@ def test_vmap_galactic_ecliptic(xp: ModuleType) -> None: # no rotation vmap = glass.vmap_galactic_ecliptic(n_side, galactic=(0, 0), ecliptic=(0, 0), xp=xp) - xp_assert_equal(vmap, xp.zeros_like(vmap)) + xpx.testing.assert_equal(vmap, xp.zeros_like(vmap)) # check errors raised @@ -64,13 +64,13 @@ def test_gaussian_nz( # check passing in the norm nz = glass.gaussian_nz(z, mean, sigma, norm=0) - xp_assert_equal(nz, xp.zeros_like(nz)) + xpx.testing.assert_equal(nz, xp.zeros_like(nz)) # check the value of each entry is close to the norm norm = 1 nz = glass.gaussian_nz(z, mean, sigma, norm=norm) - xp_assert_close( + xpx.testing.assert_close( xp.sum(nz) / nz.shape[0], xp.asarray(norm, dtype=xp.float64), rtol=1e-2, @@ -97,7 +97,7 @@ def test_smail_nz(xp: ModuleType) -> None: # check passing in the norm pz = glass.smail_nz(z, mode, alpha, beta, norm=0) - xp_assert_equal(pz, xp.zeros_like(pz)) + xpx.testing.assert_equal(pz, xp.zeros_like(pz)) def test_fixed_zbins_default_xp() -> None: @@ -116,14 +116,14 @@ def test_fixed_zbins_default_xp() -> None: ) zbins = glass.fixed_zbins(zmin, zmax, nbins=nbins) assert len(zbins) == nbins - xp_assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) + xpx.testing.assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) # check dz input dz = 0.2 zbins = glass.fixed_zbins(zmin, zmax, dz=dz) assert len(zbins) == math.ceil((zmax - zmin) / dz) - xp_assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) + xpx.testing.assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) # check dz for spacing which results in a max value above zmax @@ -154,14 +154,14 @@ def test_fixed_zbins_xp_provided(xp: ModuleType) -> None: ) zbins = glass.fixed_zbins(zmin, zmax, nbins=nbins, xp=xp) assert len(zbins) == nbins - xp_assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) + xpx.testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check dz input dz = 0.2 zbins = glass.fixed_zbins(zmin, zmax, dz=dz, xp=xp) assert len(zbins) == math.ceil((zmax - zmin) / dz) - xp_assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) + xpx.testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check dz for spacing which results in a max value above zmax @@ -188,7 +188,7 @@ def test_equal_dens_zbins(xp: ModuleType) -> None: ], ) zbins = glass.equal_dens_zbins(z, xp.ones_like(z), nbins) - xp_assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) + xpx.testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check output shape @@ -204,7 +204,7 @@ def test_tomo_nz_gausserr(xp: ModuleType) -> None: # check zeros returned binned_nz = glass.tomo_nz_gausserr(z, xp.zeros_like(z), sigma_0, zbins) - xp_assert_equal(binned_nz, xp.zeros_like(binned_nz)) + xpx.testing.assert_equal(binned_nz, xp.zeros_like(binned_nz)) # check the shape of the output diff --git a/tests/core/test_points.py b/tests/core/test_points.py index f7276d7c..3402fc3c 100644 --- a/tests/core/test_points.py +++ b/tests/core/test_points.py @@ -6,7 +6,6 @@ import pytest import array_api_extra as xpx -from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal import glass import glass.healpix as hp @@ -35,17 +34,17 @@ def test_effective_bias( z = xp.linspace(0, 1, 10) bz = xp.zeros((10,)) - xp_assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) + xpx.testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) z = xp.zeros((10,)) bz = xp.full_like(z, 0.5) - xp_assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) + xpx.testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) z = xp.linspace(0, 1, 10) bz = xp.full_like(z, 0.5) - xp_assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.25)) + xpx.testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.25)) def test_linear_bias( @@ -57,21 +56,21 @@ def test_linear_bias( delta = xp.zeros((2, 2)) b = 2.0 - xp_assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) + xpx.testing.assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) # test with 0 b delta = urng.normal(5, 1, size=(2, 2)) b = 0.0 - xp_assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) + xpx.testing.assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) # compare with original implementation delta = urng.normal(5, 1, size=(2, 2)) b = 2.0 - xp_assert_close(glass.linear_bias(delta, b), b * delta) + xpx.testing.assert_close(glass.linear_bias(delta, b), b * delta) def test_loglinear_bias( @@ -83,21 +82,21 @@ def test_loglinear_bias( delta = xp.zeros((2, 2)) b = 2.0 - xp_assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) + xpx.testing.assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) # test with 0 b delta = urng.normal(5, 1, size=(2, 2)) b = 0.0 - xp_assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) + xpx.testing.assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) # compare with numpy implementation delta = urng.normal(5, 1, size=(2, 2)) b = 2.0 - xp_assert_close( + xpx.testing.assert_close( glass.loglinear_bias(delta, b), xp.expm1(b * xp.log1p(delta)), ) @@ -119,11 +118,11 @@ def test_broadcast_inputs(xp: ModuleType) -> None: assert dims == (3, 2) assert bias.shape == dims # ty: ignore[unresolved-attribute] assert xp.all(bias == bias_in) - xp_assert_equal(delta, xp.zeros_like(delta)) + xpx.testing.assert_equal(delta, xp.zeros_like(delta)) assert ngal.shape == dims # ty: ignore[unresolved-attribute] - xp_assert_equal(ngal[0, :], ngal_in) # ty: ignore[not-subscriptable] + xpx.testing.assert_equal(ngal[0, :], ngal_in) # ty: ignore[not-subscriptable] assert vis.shape == delta.shape # ty: ignore[unresolved-attribute] - xp_assert_equal(vis[0, 0, :], vis_in) # ty: ignore[not-subscriptable] + xpx.testing.assert_equal(vis[0, 0, :], vis_in) # ty: ignore[not-subscriptable] @pytest.mark.parametrize( @@ -150,7 +149,7 @@ def test_compute_density_contrast( ) assert n.shape[0] == delta.shape[-1] - xp_assert_equal(n, xp.zeros_like(n)) + xpx.testing.assert_equal(n, xp.zeros_like(n)) @pytest.mark.parametrize("remove_monopole", [False, True]) @@ -185,8 +184,8 @@ def test_apply_visibility(xp: ModuleType) -> None: vis, ) - xp_assert_equal(n[:6], xp.zeros_like(n[:6])) - xp_assert_equal(n[6:], n_in[6:]) + xpx.testing.assert_equal(n[:6], xp.zeros_like(n[:6])) + xpx.testing.assert_equal(n[6:], n_in[6:]) def test_sample_number_galaxies(xp: ModuleType) -> None: @@ -194,8 +193,8 @@ def test_sample_number_galaxies(xp: ModuleType) -> None: n = glass.points._sample_number_galaxies(n_in) - xp_assert_equal(n[:6], xp.zeros_like(n[:6], dtype=xp.int64)) - xp_assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) + xpx.testing.assert_equal(n[:6], xp.zeros_like(n[:6], dtype=xp.int64)) + xpx.testing.assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) def test_sample_number_galaxies_rng( @@ -206,8 +205,8 @@ def test_sample_number_galaxies_rng( n = glass.points._sample_number_galaxies(n_in, rng=urng) - xp_assert_equal(n[:6], xp.zeros_like(n[:6])) - xp_assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) + xpx.testing.assert_equal(n[:6], xp.zeros_like(n[:6])) + xpx.testing.assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) def test_sample_galaxies_per_pixel( @@ -306,8 +305,8 @@ def test_positions_from_delta( # noqa: PLR0915 ) assert int(count) == count - xp_assert_close(lon, xp.asarray([])) - xp_assert_close(lat, xp.asarray([])) + xpx.testing.assert_close(lon, xp.asarray([])) + xpx.testing.assert_close(lat, xp.asarray([])) # case: large delta @@ -465,7 +464,7 @@ def test_position_weights( ) expected = bias * expected - xp_assert_close(weights, expected) + xpx.testing.assert_close(weights, expected) def test_displace_arg_complex(xp: ModuleType) -> None: @@ -479,19 +478,19 @@ def test_displace_arg_complex(xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray(r + 0j)) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) # south lon, lat = glass.displace(lon0, lat0, xp.asarray(-r + 0j)) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray(1j * r)) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray(-1j * r)) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) def test_displace_arg_real(xp: ModuleType) -> None: @@ -505,19 +504,19 @@ def test_displace_arg_real(xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray([r, 0])) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) # south lon, lat = glass.displace(lon0, lat0, xp.asarray([-r, 0])) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray([0, r])) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray([0, -r])) - xp_assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) def test_displace_abs( @@ -540,7 +539,7 @@ def test_displace_abs( cos_a = xp.cos(th) * xp.cos(th_) + xp.cos(delta) * xp.sin(th) * xp.sin(th_) - xp_assert_close(cos_a, xp.cos(abs_alpha)) + xpx.testing.assert_close(cos_a, xp.cos(abs_alpha)) def test_displacement( @@ -576,7 +575,7 @@ def test_displacement( # test each displacement individually for from_lon, from_lat, to_lon, to_lat, alpha in data: alpha_ = glass.displacement(from_lon, from_lat, to_lon, to_lat) - xp_assert_close(alpha_, alpha) + xpx.testing.assert_close(alpha_, alpha) # test on an array alpha = glass.displacement( @@ -596,7 +595,7 @@ def test_displacement_zerodist( lon = urng.uniform(-180.0, 180.0, size=100) lat = urng.uniform(-90.0, 90.0, size=100) - xp_assert_close( + xpx.testing.assert_close( glass.displacement(lon, lat, lon, lat), xp.zeros(100, dtype=xp.complex128), ) @@ -626,7 +625,7 @@ def test_displacement_consistent( # measure displacement alpha_out = glass.displacement(from_lon, from_lat, to_lon, to_lat) - xp_assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) + xpx.testing.assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) def test_displacement_random( @@ -674,11 +673,11 @@ def test_displacement_random( ], axis=1, ) - xp_assert_close(rot @ xp.asarray([0.0, 0.0, 1.0]), u) + xpx.testing.assert_close(rot @ xp.asarray([0.0, 0.0, 1.0]), u) # meta-check that recovering theta and phi from vector works - xp_assert_close(xp.atan2(xp.hypot(u[:, 0], u[:, 1]), u[:, 2]), theta) - xp_assert_close(xp.atan2(u[:, 1], u[:, 0]), phi) + xpx.testing.assert_close(xp.atan2(xp.hypot(u[:, 0], u[:, 1]), u[:, 2]), theta) + xpx.testing.assert_close(xp.atan2(u[:, 1], u[:, 0]), phi) # build the displaced points near (0, 0, 1) and rotate near theta and phi v = xp.stack( @@ -705,4 +704,4 @@ def test_displacement_random( # compute displacement and compare to input alpha_in = r * xp.exp(1j * x) alpha_out = glass.displacement(from_lon, from_lat, to_lon, to_lat) - xp_assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) + xpx.testing.assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) diff --git a/tests/core/test_shapes.py b/tests/core/test_shapes.py index b572ddca..f7c712f0 100644 --- a/tests/core/test_shapes.py +++ b/tests/core/test_shapes.py @@ -4,7 +4,7 @@ import pytest -from array_api_extra._lib._testing import xp_assert_close, xp_assert_less +import array_api_extra as xpx import glass @@ -151,21 +151,41 @@ def test_ellipticity_gaussian( assert eps.shape == (n,) - xp_assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xp_assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx.testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx.testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) eps = glass.ellipticity_gaussian(xp.asarray([n, n]), xp.asarray([0.128, 0.256])) assert eps.shape == (2 * n,) - xp_assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xp_assert_close(xp.std(xp.real(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.real(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx.testing.assert_close( + xp.std(xp.real(eps)[:n]), + xp.asarray(0.128), + atol=1e-3, + rtol=0, + ) + xpx.testing.assert_close( + xp.std(xp.imag(eps)[:n]), + xp.asarray(0.128), + atol=1e-3, + rtol=0, + ) + xpx.testing.assert_close( + xp.std(xp.real(eps)[n:]), + xp.asarray(0.256), + atol=1e-3, + rtol=0, + ) + xpx.testing.assert_close( + xp.std(xp.imag(eps)[n:]), + xp.asarray(0.256), + atol=1e-3, + rtol=0, + ) def test_ellipticity_intnorm( @@ -192,21 +212,41 @@ def test_ellipticity_intnorm( assert eps.shape == (n,) - xp_assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xp_assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx.testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx.testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) eps = glass.ellipticity_intnorm(xp.asarray([n, n]), xp.asarray([0.128, 0.256])) assert eps.shape == (2 * n,) - xp_assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xp_assert_close(xp.std(xp.real(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.real(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0) - xp_assert_close(xp.std(xp.imag(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx.testing.assert_close( + xp.std(xp.real(eps)[:n]), + xp.asarray(0.128), + atol=1e-3, + rtol=0, + ) + xpx.testing.assert_close( + xp.std(xp.imag(eps)[:n]), + xp.asarray(0.128), + atol=1e-3, + rtol=0, + ) + xpx.testing.assert_close( + xp.std(xp.real(eps)[n:]), + xp.asarray(0.256), + atol=1e-3, + rtol=0, + ) + xpx.testing.assert_close( + xp.std(xp.imag(eps)[n:]), + xp.asarray(0.256), + atol=1e-3, + rtol=0, + ) with pytest.raises(ValueError, match="sigma must be between"): glass.ellipticity_intnorm(1, 0.71, xp=xp) diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index 6df67457..9f738f31 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -7,7 +7,7 @@ import numpy as np import pytest -from array_api_extra._lib._testing import xp_assert_close, xp_assert_less +import array_api_extra as xpx import glass from glass._array_api_utils import xp_additions as uxpx @@ -36,7 +36,7 @@ def test_distance_weight( # check values are decreasing - xp_assert_less(w[1:], w[:-1]) + xpx.testing.assert_less(w[1:], w[:-1]) def test_volume_weight( @@ -57,7 +57,7 @@ def test_volume_weight( # check values are increasing - xp_assert_less(w[:-1], w[1:]) + xpx.testing.assert_less(w[:-1], w[1:]) def test_density_weight(cosmo: Cosmology) -> None: @@ -75,7 +75,7 @@ def test_density_weight(cosmo: Cosmology) -> None: # check values are increasing - xp_assert_less(w[:-1], w[1:]) + xpx.testing.assert_less(w[:-1], w[1:]) def test_tophat_windows(xp: ModuleType) -> None: @@ -116,7 +116,7 @@ def test_linear_windows(xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.linear_windows(zgrid) - xp_assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xpx.testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -124,7 +124,7 @@ def test_linear_windows(xp: ModuleType) -> None: # check values of zeff - xp_assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) + xpx.testing.assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) # check weight function input @@ -133,7 +133,7 @@ def test_linear_windows(xp: ModuleType) -> None: weight=lambda _: 0, ) for w in ws: - xp_assert_close(w.wa, xp.zeros_like(w.wa)) + xpx.testing.assert_close(w.wa, xp.zeros_like(w.wa)) # check error raised @@ -165,7 +165,7 @@ def test_cubic_windows(xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.cubic_windows(zgrid) - xp_assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xpx.testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -173,7 +173,7 @@ def test_cubic_windows(xp: ModuleType) -> None: # check values of zeff - xp_assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) + xpx.testing.assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) # check weight function input @@ -182,7 +182,7 @@ def test_cubic_windows(xp: ModuleType) -> None: weight=lambda _: 0, ) for w in ws: - xp_assert_close(w.wa, xp.zeros_like(w.wa)) + xpx.testing.assert_close(w.wa, xp.zeros_like(w.wa)) # check error raised @@ -275,7 +275,7 @@ def test_partition( assert part.shape == (len(shells), 3, 2) - xp_assert_close(xp.sum(part, axis=0), uxpx.trapezoid(fz, z)) + xpx.testing.assert_close(xp.sum(part, axis=0), uxpx.trapezoid(fz, z)) def test_redshift_grid_default_xp() -> None: @@ -358,7 +358,7 @@ def test_distance_grid(cosmo: Cosmology) -> None: # check decrease in distance x = glass.distance_grid(cosmo, zmin, zmax, dx=0.3) - xp_assert_less(x[1:], x[:-1]) + xpx.testing.assert_less(x[1:], x[:-1]) # check error raised @@ -411,10 +411,10 @@ def test_combine(xp: ModuleType) -> None: assert result.shape == z.shape # Check sum of result - xp_assert_close(xp.sum(result), xp.asarray(929.267284)) + xpx.testing.assert_close(xp.sum(result), xp.asarray(929.267284)) # Check integral w.r.t z has not changed - xp_assert_close(uxpx.trapezoid(result, z), xp.asarray(4.643139), rtol=1e-6) + xpx.testing.assert_close(uxpx.trapezoid(result, z), xp.asarray(4.643139), rtol=1e-6) def test_radial_window_immutable(xp: ModuleType) -> None: @@ -453,7 +453,7 @@ def test_radial_window_zeff_none(xp: ModuleType) -> None: w = glass.RadialWindow(za, wa) - xp_assert_close(w.zeff, xp.ones_like(w.zeff)) + xpx.testing.assert_close(w.zeff, xp.ones_like(w.zeff)) # check zeff is NaN when redshift array is empty From fa3900d9c197e303ab70b4939899651a28fdc404 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 28 May 2026 12:51:02 +0100 Subject: [PATCH 24/43] Use `assert_close_nulp` --- tests/core/grf/test_transformations.py | 10 +++------ tests/core/test_algorithm.py | 4 +--- tests/fixtures/helper_classes.py | 29 -------------------------- 3 files changed, 4 insertions(+), 39 deletions(-) diff --git a/tests/core/grf/test_transformations.py b/tests/core/grf/test_transformations.py index 1b4fc755..a24ad492 100644 --- a/tests/core/grf/test_transformations.py +++ b/tests/core/grf/test_transformations.py @@ -10,7 +10,6 @@ from types import ModuleType from glass._types import UnifiedGenerator - from tests.fixtures.helper_classes import Compare def test_normal(urng: UnifiedGenerator) -> None: @@ -57,7 +56,6 @@ def test_normal_normal( def test_lognormal_lognormal( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -72,12 +70,11 @@ def test_lognormal_lognormal( dy = lam1 * lam2 * xp.exp(x) xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) - compare.assert_array_almost_equal_nulp(glass.grf.icorr(t1, t2, y), x) + xpx.testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x) xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) def test_lognormal_normal( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -91,12 +88,11 @@ def test_lognormal_normal( dy = lam1 * xp.ones_like(x) xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) - compare.assert_array_almost_equal_nulp(glass.grf.icorr(t1, t2, y), x) + xpx.testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x) xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) def test_sqnormal_sqnormal( - compare: type[Compare], urng: UnifiedGenerator, xp: ModuleType, ) -> None: @@ -114,5 +110,5 @@ def test_sqnormal_sqnormal( dy = 4 * lam1 * lam2 * (x + a1 * a2) xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) - compare.assert_array_almost_equal_nulp(glass.grf.icorr(t1, t2, y), x, nulp=8) + xpx.testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x, nulp=8) xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) diff --git a/tests/core/test_algorithm.py b/tests/core/test_algorithm.py index b5794365..29546a97 100644 --- a/tests/core/test_algorithm.py +++ b/tests/core/test_algorithm.py @@ -14,7 +14,6 @@ from pytest_mock import MockerFixture from glass._types import UnifiedGenerator - from tests.fixtures.helper_classes import Compare def test_nnls( @@ -123,7 +122,6 @@ def test_nearcorr(xp: ModuleType) -> None: def test_cov_nearest( - compare: type[Compare], mocker: MockerFixture, urng: UnifiedGenerator, xp: ModuleType, @@ -149,7 +147,7 @@ def test_cov_nearest( # make sure nearcorr was called with correct input nearcorr.assert_called_once() - compare.assert_array_almost_equal_nulp( + xpx.testing.assert_close_nulp( nearcorr.call_args_list[0].args[0], xp.divide(a, norm), ) diff --git a/tests/fixtures/helper_classes.py b/tests/fixtures/helper_classes.py index 2e73f77e..bf83bbb3 100644 --- a/tests/fixtures/helper_classes.py +++ b/tests/fixtures/helper_classes.py @@ -4,7 +4,6 @@ from typing import TYPE_CHECKING -import numpy as np import pytest if TYPE_CHECKING: @@ -13,7 +12,6 @@ from typing import Any from glass._types import ( - AnyArray, ComplexArray, FloatArray, IntArray, @@ -21,33 +19,6 @@ ) -class Compare: - """ - Helper class for array comparisons in tests. - - This class wraps numpy testing functions to provide a consistent interface - for comparing arrays in tests. Ultimately, it would be great if we can - make the array testing backend-agnostic. - - """ - - @staticmethod - def assert_array_almost_equal_nulp( - actual: AnyArray, - desired: AnyArray, - *, - nulp: int = 1, - ) -> None: - """Compare two arrays relatively to their spacing.""" - np.testing.assert_array_almost_equal_nulp(actual, desired, nulp=nulp) - - -@pytest.fixture(scope="session") -def compare() -> type[Compare]: - """Fixture for array comparison utility.""" - return Compare - - class DataTransformer: """Helper class for transforming various data structures into others.""" From 6e7a97508e5d5d59345ba8fa47fad08d3391ba85 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Thu, 28 May 2026 23:32:52 +0100 Subject: [PATCH 25/43] Import `array_api_extra.testing` --- tests/benchmarks/test_arraytools.py | 8 +-- tests/benchmarks/test_fields.py | 16 +++--- tests/benchmarks/test_harmonics.py | 4 +- tests/benchmarks/test_lensing.py | 10 ++-- tests/benchmarks/test_shells.py | 4 +- tests/core/grf/test_solver.py | 16 +++--- tests/core/grf/test_transformations.py | 32 +++++------ tests/core/test_algorithm.py | 13 +++-- tests/core/test_arraytools.py | 26 ++++----- tests/core/test_fields.py | 60 ++++++++++---------- tests/core/test_galaxies.py | 12 ++-- tests/core/test_harmonics.py | 12 ++-- tests/core/test_healpix.py | 26 ++++----- tests/core/test_lensing.py | 30 +++++----- tests/core/test_observations.py | 22 ++++---- tests/core/test_points.py | 77 +++++++++++++------------- tests/core/test_shapes.py | 34 ++++++------ tests/core/test_shells.py | 30 +++++----- 18 files changed, 217 insertions(+), 215 deletions(-) diff --git a/tests/benchmarks/test_arraytools.py b/tests/benchmarks/test_arraytools.py index 63409f37..8acec52d 100644 --- a/tests/benchmarks/test_arraytools.py +++ b/tests/benchmarks/test_arraytools.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass.arraytools @@ -55,7 +55,7 @@ def test_cumulative_trapezoid_1d( ct = benchmark(glass.arraytools.cumulative_trapezoid, f, x) # Compare to int64 as old versions of glass round to int64 if `dtype` is not passed. - xpx.testing.assert_close( + xpx_testing.assert_close( xpb.asarray(ct[:4], dtype=xpb.int64), xpb.asarray([0, 1, 4, 7]), ) @@ -83,11 +83,11 @@ def test_cumulative_trapezoid_2d( expected_first_4_out = xpb.asarray([0, 1, 4, 7]) # Compare to int64 as old versions of glass round to int64 if `dtype` is not passed. - xpx.testing.assert_close( + xpx_testing.assert_close( xpb.asarray(ct[0, :4], dtype=xpb.int64), expected_first_4_out, ) - xpx.testing.assert_close( + xpx_testing.assert_close( xpb.asarray(ct[1, :4], dtype=xpb.int64), expected_first_4_out, ) diff --git a/tests/benchmarks/test_fields.py b/tests/benchmarks/test_fields.py index ac6dfdd3..75c7a145 100644 --- a/tests/benchmarks/test_fields.py +++ b/tests/benchmarks/test_fields.py @@ -5,7 +5,7 @@ import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass import glass.fields @@ -120,7 +120,7 @@ def function_to_benchmark() -> list[Any]: j, a, s = results[0] assert j is None assert a.shape == (0,) - xpx.testing.assert_close(s, xpb.ones_like(s)) + xpx_testing.assert_close(s, xpb.ones_like(s)) @pytest.mark.stable @@ -148,9 +148,9 @@ def function_to_benchmark() -> list[Any]: assert cov.shape == (nl, nc + 1) assert cov.dtype == xpb.float64 - xpx.testing.assert_close(cov[:, 0], xpb.asarray([1.0, 1.5, 2.0])) - xpx.testing.assert_close(cov[:, 1], xpb.asarray([1.5, 2.0, 2.5])) - xpx.testing.assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) + xpx_testing.assert_close(cov[:, 0], xpb.asarray([1.0, 1.5, 2.0])) + xpx_testing.assert_close(cov[:, 1], xpb.asarray([1.5, 2.0, 2.5])) + xpx_testing.assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) @pytest.mark.stable @@ -213,7 +213,7 @@ def function_to_benchmark() -> list[Any]: for field in result: assert field.shape == (hp.nside2npix(nside),) - xpx.testing.assert_close(result[1], result[0] ** 2, atol=1e-05) + xpx_testing.assert_close(result[1], result[0] ** 2, atol=1e-05) @pytest.mark.unstable @@ -243,7 +243,7 @@ def test_getcl_lmax_0( ) expected = xpb.asarray([max(random_i, random_j)], dtype=xpb.float64) assert result.shape[0] == 1 - xpx.testing.assert_close(result, expected) + xpx_testing.assert_close(result, expected) @pytest.mark.unstable @@ -274,4 +274,4 @@ def test_getcl_lmax_larger_than_cls( ) expected = xpb.zeros((lmax - 1,), dtype=xpb.float64) assert result.shape[0] == lmax + 1 - xpx.testing.assert_close(result[2:], expected) + xpx_testing.assert_close(result[2:], expected) diff --git a/tests/benchmarks/test_harmonics.py b/tests/benchmarks/test_harmonics.py index d0953bd6..d9985cf2 100644 --- a/tests/benchmarks/test_harmonics.py +++ b/tests/benchmarks/test_harmonics.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing glass_harmonics = pytest.importorskip( "glass.harmonics", @@ -31,7 +31,7 @@ def test_multalm( result = benchmark(glass_harmonics.multalm, alm, bl) - xpx.testing.assert_close( + xpx_testing.assert_close( result[:5], xpb.asarray([scale_factor * x for x in [0.0, 3.0, 6.0, 9.0, 12.0]]), ) diff --git a/tests/benchmarks/test_lensing.py b/tests/benchmarks/test_lensing.py index 9aa37867..1157c8cb 100644 --- a/tests/benchmarks/test_lensing.py +++ b/tests/benchmarks/test_lensing.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass @@ -38,8 +38,8 @@ def test_multi_plane_matrix( mat = glass.multi_plane_matrix(shells, cosmo) deltas = urngb.random((len(shells), 10)) - xpx.testing.assert_equal(mat, xpb.tril(mat)) - xpx.testing.assert_equal(xpb.triu(mat, k=1), xpb.zeros_like(mat)) + xpx_testing.assert_equal(mat, xpb.tril(mat)) + xpx_testing.assert_equal(xpb.triu(mat, k=1), xpb.zeros_like(mat)) def setup_shells_and_deltas() -> tuple[ tuple[ @@ -99,8 +99,8 @@ def test_multi_plane_weights( w_out = glass.multi_plane_weights(w_in, shells, cosmo) - xpx.testing.assert_equal(w_out, xpb.triu(w_out, 1)) - xpx.testing.assert_equal(xpb.tril(w_out), xpb.zeros_like(w_out)) + xpx_testing.assert_equal(w_out, xpb.triu(w_out, 1)) + xpx_testing.assert_equal(xpb.tril(w_out), xpb.zeros_like(w_out)) def setup_shells_deltas_and_weights() -> tuple[ tuple[ diff --git a/tests/benchmarks/test_shells.py b/tests/benchmarks/test_shells.py index 5d187832..b24c1fba 100644 --- a/tests/benchmarks/test_shells.py +++ b/tests/benchmarks/test_shells.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass @@ -29,4 +29,4 @@ def test_radialwindow( w = benchmark(glass.RadialWindow, za, wa) - xpx.testing.assert_close(w.zeff, xpb.asarray(expected_zeff)) + xpx_testing.assert_close(w.zeff, xpb.asarray(expected_zeff)) diff --git a/tests/core/grf/test_solver.py b/tests/core/grf/test_solver.py index d3f3e8ce..7de7e996 100644 --- a/tests/core/grf/test_solver.py +++ b/tests/core/grf/test_solver.py @@ -5,7 +5,7 @@ import numpy as np import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass.grf @@ -30,7 +30,7 @@ def test_one_transformation( gl1, _, _ = glass.grf.solve(cl, t) gl2, _, _ = glass.grf.solve(cl, t, t) - xpx.testing.assert_equal(gl1, gl2) + xpx_testing.assert_equal(gl1, gl2) def test_pad( @@ -61,7 +61,7 @@ def test_initial( gl1, _, _ = glass.grf.solve(cl, t) gl2, _, _ = glass.grf.solve(cl, t, initial=gl) - xpx.testing.assert_equal(gl1, gl2) + xpx_testing.assert_equal(gl1, gl2) def test_no_iterations(cl: FloatArray) -> None: @@ -70,7 +70,7 @@ def test_no_iterations(cl: FloatArray) -> None: gl1 = glass.grf.compute(cl, t) gl2, _, _ = glass.grf.solve(cl, t, maxiter=0) - xpx.testing.assert_equal(gl1, gl2) + xpx_testing.assert_equal(gl1, gl2) def test_lognormal( @@ -88,12 +88,12 @@ def test_lognormal( assert info > 0 - xpx.testing.assert_close(cl_[1 : cl.shape[0]], cl[1:], atol=0.0, rtol=cltol) + xpx_testing.assert_close(cl_[1 : cl.shape[0]], cl[1:], atol=0.0, rtol=cltol) gl_ = glass.grf.compute(cl_, t1, t2) assert gl[0] == gl0 - xpx.testing.assert_close(gl_[1 : gl.shape[0]], gl[1:]) + xpx_testing.assert_close(gl_[1 : gl.shape[0]], gl[1:]) def test_monopole( @@ -108,10 +108,10 @@ def test_monopole( gl, cl_out, _ = glass.grf.solve(cl, t, monopole=None, gltol=1e-8) assert gl[0] != 0.0 - xpx.testing.assert_close(cl_out[0], cl[0]) + xpx_testing.assert_close(cl_out[0], cl[0]) gl, cl_out, _ = glass.grf.solve(cl, t, monopole=gl0, gltol=1e-8) assert gl[0] == gl0 with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx.testing.assert_close(cl_out[0], cl[0]) + xpx_testing.assert_close(cl_out[0], cl[0]) diff --git a/tests/core/grf/test_transformations.py b/tests/core/grf/test_transformations.py index a24ad492..987bd524 100644 --- a/tests/core/grf/test_transformations.py +++ b/tests/core/grf/test_transformations.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass.grf @@ -15,7 +15,7 @@ def test_normal(urng: UnifiedGenerator) -> None: t = glass.grf.Normal() x = urng.standard_normal(10) - xpx.testing.assert_equal(t(x, 1.0), x) + xpx_testing.assert_equal(t(x, 1.0), x) def test_lognormal( @@ -27,7 +27,7 @@ def test_lognormal( t = glass.grf.Lognormal(lam) x = urng.standard_normal(10) y = lam * xp.expm1(x - var / 2) - xpx.testing.assert_equal(t(x, var), y) + xpx_testing.assert_equal(t(x, var), y) def test_sqnormal( @@ -40,7 +40,7 @@ def test_sqnormal( t = glass.grf.SquaredNormal(a, lam) x = urng.standard_normal(10) y = lam * ((x - a) ** 2 - 1) - xpx.testing.assert_equal(t(x, var), y) + xpx_testing.assert_equal(t(x, var), y) def test_normal_normal( @@ -50,9 +50,9 @@ def test_normal_normal( t1 = glass.grf.Normal() t2 = glass.grf.Normal() x = urng.random(10) - xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), x) - xpx.testing.assert_equal(glass.grf.icorr(t1, t2, x), x) - xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), xp.ones_like(x)) + xpx_testing.assert_equal(glass.grf.corr(t1, t2, x), x) + xpx_testing.assert_equal(glass.grf.icorr(t1, t2, x), x) + xpx_testing.assert_equal(glass.grf.dcorr(t1, t2, x), xp.ones_like(x)) def test_lognormal_lognormal( @@ -69,9 +69,9 @@ def test_lognormal_lognormal( y = lam1 * lam2 * xp.expm1(x) dy = lam1 * lam2 * xp.exp(x) - xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) - xpx.testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x) - xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) + xpx_testing.assert_equal(glass.grf.corr(t1, t2, x), y) + xpx_testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x) + xpx_testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) def test_lognormal_normal( @@ -87,9 +87,9 @@ def test_lognormal_normal( y = lam1 * x dy = lam1 * xp.ones_like(x) - xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) - xpx.testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x) - xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) + xpx_testing.assert_equal(glass.grf.corr(t1, t2, x), y) + xpx_testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x) + xpx_testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) def test_sqnormal_sqnormal( @@ -109,6 +109,6 @@ def test_sqnormal_sqnormal( y = 2 * lam1 * lam2 * x * (x + 2 * a1 * a2) dy = 4 * lam1 * lam2 * (x + a1 * a2) - xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) - xpx.testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x, nulp=8) - xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) + xpx_testing.assert_equal(glass.grf.corr(t1, t2, x), y) + xpx_testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x, nulp=8) + xpx_testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) diff --git a/tests/core/test_algorithm.py b/tests/core/test_algorithm.py index 29546a97..756c99a2 100644 --- a/tests/core/test_algorithm.py +++ b/tests/core/test_algorithm.py @@ -5,6 +5,7 @@ import pytest import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass.algorithm @@ -38,7 +39,7 @@ def test_nnls( x, tol=500 * xp.linalg.matrix_norm(a, ord=1) * xp.finfo(xp.float64).eps, ) - xpx.testing.assert_close(res, b, rtol=0.0, atol=1e-10) + xpx_testing.assert_close(res, b, rtol=0.0, atol=1e-10) # check matrix and vector's shape @@ -74,7 +75,7 @@ def test_cov_clip( # make sure all eigenvalues are positive h = xp.max(xp.linalg.eigvalsh(a)) - xpx.testing.assert_close(xp.linalg.eigvalsh(cov), h * xp.ones(cov.shape[0])) + xpx_testing.assert_close(xp.linalg.eigvalsh(cov), h * xp.ones(cov.shape[0])) def test_nearcorr(xp: ModuleType) -> None: @@ -95,11 +96,11 @@ def test_nearcorr(xp: ModuleType) -> None: ) x = glass.algorithm.nearcorr(a) - xpx.testing.assert_close(x, b, atol=1e-4) + xpx_testing.assert_close(x, b, atol=1e-4) # explicit tolerance x = glass.algorithm.nearcorr(a, tol=1e-10) - xpx.testing.assert_close(x, b, atol=1e-4) + xpx_testing.assert_close(x, b, atol=1e-4) # no iterations with pytest.warns( @@ -107,7 +108,7 @@ def test_nearcorr(xp: ModuleType) -> None: match="Nearest correlation matrix not found in 0 iterations", ): x = glass.algorithm.nearcorr(a, niter=0) - xpx.testing.assert_close(x, a) + xpx_testing.assert_close(x, a) # non-square matrix should raise with pytest.raises(ValueError, match="non-square matrix"): @@ -147,7 +148,7 @@ def test_cov_nearest( # make sure nearcorr was called with correct input nearcorr.assert_called_once() - xpx.testing.assert_close_nulp( + xpx_testing.assert_close_nulp( nearcorr.call_args_list[0].args[0], xp.divide(a, norm), ) diff --git a/tests/core/test_arraytools.py b/tests/core/test_arraytools.py index ca750bba..32636d45 100644 --- a/tests/core/test_arraytools.py +++ b/tests/core/test_arraytools.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass.arraytools @@ -68,17 +68,17 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == () - xpx.testing.assert_close(y, xp.asarray(1.15), atol=1e-15) + xpx_testing.assert_close(y, xp.asarray(1.15), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (3,) - xpx.testing.assert_close(y, xp.asarray([1.15, 1.25, 1.35]), atol=1e-15) + xpx_testing.assert_close(y, xp.asarray([1.15, 1.25, 1.35]), atol=1e-15) x = xp.asarray([[0.5, 1.5], [2.5, 3.5]]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 2) - xpx.testing.assert_close(y, xp.asarray([[1.15, 1.25], [1.35, 1.45]]), atol=1e-15) + xpx_testing.assert_close(y, xp.asarray([[1.15, 1.25], [1.35, 1.45]]), atol=1e-15) # test n-dimensional interpolation in final axis @@ -87,12 +87,12 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2,) - xpx.testing.assert_close(y, xp.asarray([1.15, 2.15]), atol=1e-15) + xpx_testing.assert_close(y, xp.asarray([1.15, 2.15]), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 3) - xpx.testing.assert_close( + xpx_testing.assert_close( y, xp.asarray([[1.15, 1.25, 1.35], [2.15, 2.25, 2.35]]), atol=1e-15, @@ -101,7 +101,7 @@ def test_ndinterp(xp: ModuleType) -> None: x = xp.asarray([[0.5, 1.5], [2.5, 3.5]]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 2, 2) - xpx.testing.assert_close( + xpx_testing.assert_close( y, xp.asarray([[[1.15, 1.25], [1.35, 1.45]], [[2.15, 2.25], [2.35, 2.45]]]), atol=1e-15, @@ -116,12 +116,12 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 1) - xpx.testing.assert_close(y, xp.asarray([[1.15], [2.15]]), atol=1e-15) + xpx_testing.assert_close(y, xp.asarray([[1.15], [2.15]]), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 3, 1) - xpx.testing.assert_close( + xpx_testing.assert_close( y, xp.asarray([[[1.15], [1.25], [1.35]], [[2.15], [2.25], [2.35]]]), atol=1e-15, @@ -130,7 +130,7 @@ def test_ndinterp(xp: ModuleType) -> None: x = xp.asarray([[0.5, 1.5, 2.5, 3.5], [3.5, 2.5, 1.5, 0.5], [0.5, 3.5, 1.5, 2.5]]) y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 3, 4, 1) - xpx.testing.assert_close( + xpx_testing.assert_close( y, xp.asarray([ [ @@ -157,7 +157,7 @@ def test_trapezoid_product(xp: ModuleType) -> None: s = glass.arraytools.trapezoid_product((x1, f1), (x2, f2)) - xpx.testing.assert_close(s, xp.ones_like(s)) + xpx_testing.assert_close(s, xp.ones_like(s)) def test_cumulative_trapezoid(xp: ModuleType) -> None: @@ -167,14 +167,14 @@ def test_cumulative_trapezoid(xp: ModuleType) -> None: x = xp.asarray([0, 1, 2, 3]) ct = glass.arraytools.cumulative_trapezoid(f, x) - xpx.testing.assert_close(ct, xp.asarray([0.0, 1.5, 4.0, 7.5])) + xpx_testing.assert_close(ct, xp.asarray([0.0, 1.5, 4.0, 7.5])) # 2D f and 1D x f = xp.asarray([[1, 4, 9, 16], [2, 3, 5, 7]]) x = xp.asarray([0, 1, 2.5, 4]) ct = glass.arraytools.cumulative_trapezoid(f, x) - xpx.testing.assert_close( + xpx_testing.assert_close( ct, xp.asarray([[0.0, 2.5, 12.25, 31.0], [0.0, 2.5, 8.5, 17.5]]), ) diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index 3f8591e4..ce97040e 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -6,7 +6,7 @@ import numpy as np import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass import glass.fields @@ -175,14 +175,14 @@ def test_cls2cov_jax(jnp: ModuleType) -> None: assert cov3.dtype == jnp.float64 # cov1 has the expected value for the first iteration (different to cov1_copy) - xpx.testing.assert_close(cov1[:, 0], jnp.asarray([0.5, 0.25, 0.15])) + xpx_testing.assert_close(cov1[:, 0], jnp.asarray([0.5, 0.25, 0.15])) # The copies should not be equal with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx.testing.assert_close(cov1, cov2) + xpx_testing.assert_close(cov1, cov2) with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx.testing.assert_close(cov2, cov3) + xpx_testing.assert_close(cov2, cov3) def test_cls2cov_no_jax(xpb: ModuleType) -> None: @@ -201,9 +201,9 @@ def test_cls2cov_no_jax(xpb: ModuleType) -> None: assert cov.shape == (nl, nc + 1) assert cov.dtype == xpb.float64 - xpx.testing.assert_close(cov[:, 0], xpb.asarray([0.5, 0.25, 0.15])) - xpx.testing.assert_close(cov[:, 1], xpb.zeros_like(cov[:, 1])) - xpx.testing.assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) + xpx_testing.assert_close(cov[:, 0], xpb.asarray([0.5, 0.25, 0.15])) + xpx_testing.assert_close(cov[:, 1], xpb.zeros_like(cov[:, 1])) + xpx_testing.assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) # test negative value error @@ -259,19 +259,19 @@ def test_cls2cov_no_jax(xpb: ModuleType) -> None: assert cov3.dtype == xpb.float64 # cov1|2|3 reuse the same data, so should all equal the third result - xpx.testing.assert_close(cov1[:, 0], xpb.asarray([0.45, 0.25, 0.15])) - xpx.testing.assert_close(cov1, cov2) - xpx.testing.assert_close(cov2, cov3) + xpx_testing.assert_close(cov1[:, 0], xpb.asarray([0.45, 0.25, 0.15])) + xpx_testing.assert_close(cov1, cov2) + xpx_testing.assert_close(cov2, cov3) # cov1 has the expected value for the first iteration (different to cov1_copy) - xpx.testing.assert_close(cov1_copy[:, 0], xpb.asarray([0.5, 0.25, 0.15])) + xpx_testing.assert_close(cov1_copy[:, 0], xpb.asarray([0.5, 0.25, 0.15])) # The copies should not be equal with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx.testing.assert_close(cov1_copy, cov2_copy) + xpx_testing.assert_close(cov1_copy, cov2_copy) with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx.testing.assert_close(cov2_copy, cov3) + xpx_testing.assert_close(cov2_copy, cov3) def test_lognormal_gls(xp: ModuleType) -> None: @@ -341,7 +341,7 @@ def test_discretized_cls(xp: ModuleType) -> None: for cl in result: n = min(cl.shape[0], pw.shape[0]) # ty: ignore[unresolved-attribute] expected = xp.ones(n) * pw[:n] ** 2 - xpx.testing.assert_close(cl[:n], expected) + xpx_testing.assert_close(cl[:n], expected) def test_effective_cls(xp: ModuleType) -> None: @@ -373,7 +373,7 @@ def test_effective_cls(xp: ModuleType) -> None: result = glass.effective_cls(cls, weights1, lmax=5) assert result.shape == (1, 1, 6) - xpx.testing.assert_close(result[..., 6:], xp.zeros_like(result[..., 6:])) + xpx_testing.assert_close(result[..., 6:], xp.zeros_like(result[..., 6:])) # check with weights1 and weights2 and weights1 is weights2 @@ -404,7 +404,7 @@ def test_generate_grf(xp: ModuleType) -> None: assert new_gaussian_fields[0].shape == (hp.nside2npix(nside),) - xpx.testing.assert_close(new_gaussian_fields[0], gaussian_fields[0]) + xpx_testing.assert_close(new_gaussian_fields[0], gaussian_fields[0]) with pytest.raises(ValueError, match="all gls are empty"): list(glass.fields._generate_grf([xp.asarray([])], nside)) @@ -457,7 +457,7 @@ def test_generate(xp: ModuleType) -> None: result = list(glass.generate(fields, gls, nside=nside)) - xpx.testing.assert_close(result[1], result[0] ** 2, atol=1e-05) + xpx_testing.assert_close(result[1], result[0] ** 2, atol=1e-05) def test_getcl(xp: ModuleType) -> None: @@ -472,19 +472,19 @@ def test_getcl(xp: ModuleType) -> None: for j in range(10): result = glass.getcl(cls, i, j) expected = xp.asarray([min(i, j), max(i, j)], dtype=xp.float64) - xpx.testing.assert_close(xp.sort(result), expected) + xpx_testing.assert_close(xp.sort(result), expected) # check slicing result = glass.getcl(cls, i, j, lmax=0) expected = xp.asarray([max(i, j)], dtype=xp.float64) assert result.shape[0] == 1 - xpx.testing.assert_close(result, expected) + xpx_testing.assert_close(result, expected) # check padding result = glass.getcl(cls, i, j, lmax=50) expected = xp.zeros((49,), dtype=xp.float64) assert result.shape[0] == 51 - xpx.testing.assert_close(result[2:], expected) + xpx_testing.assert_close(result[2:], expected) def test_is_inv_triangle_number(not_triangle_numbers: list[int]) -> None: @@ -528,17 +528,17 @@ def test_enumerate_spectra(xp: ModuleType) -> None: def test_spectra_indices(xp: ModuleType) -> None: - xpx.testing.assert_equal(glass.spectra_indices(0), np.zeros((0, 2), dtype=np.int64)) - xpx.testing.assert_equal( + xpx_testing.assert_equal(glass.spectra_indices(0), np.zeros((0, 2), dtype=np.int64)) + xpx_testing.assert_equal( glass.spectra_indices(0, xp=xp), xp.zeros((0, 2), dtype=xp.int64), ) - xpx.testing.assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) - xpx.testing.assert_equal( + xpx_testing.assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) + xpx_testing.assert_equal( glass.spectra_indices(2, xp=xp), xp.asarray([[0, 0], [1, 1], [1, 0]]), ) - xpx.testing.assert_equal( + xpx_testing.assert_equal( glass.spectra_indices(3, xp=xp), xp.asarray([[0, 0], [1, 1], [1, 0], [2, 2], [2, 1], [2, 0]]), ) @@ -670,7 +670,7 @@ def test_healpix_to_glass_spectra() -> None: def test_glass_to_healpix_alm(xp: ModuleType) -> None: inp = xp.asarray([00, 10, 11, 20, 21, 22, 30, 31, 32, 33], dtype=xp.complex128) out = glass.fields._glass_to_healpix_alm(inp) - xpx.testing.assert_equal( + xpx_testing.assert_equal( out, xp.asarray([00, 10, 20, 30, 11, 21, 31, 22, 32, 33], dtype=xp.complex128), ) @@ -692,7 +692,7 @@ def test_lognormal_shift_hilbert2011(xp: ModuleType) -> None: 0.1568, ]) - xpx.testing.assert_close(shifts, check, atol=1e-4, rtol=1e-4) + xpx_testing.assert_close(shifts, check, atol=1e-4, rtol=1e-4) def test_cov_from_spectra(xp: ModuleType) -> None: @@ -708,7 +708,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: ] ] - xpx.testing.assert_equal( + xpx_testing.assert_equal( glass.cov_from_spectra(spectra), xp.asarray([ [ @@ -734,7 +734,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: ]), ) - xpx.testing.assert_equal( + xpx_testing.assert_equal( glass.cov_from_spectra(spectra, lmax=1), xp.asarray([ [ @@ -750,7 +750,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: ]), ) - xpx.testing.assert_equal( + xpx_testing.assert_equal( glass.cov_from_spectra(spectra, lmax=4), xp.asarray([ [ diff --git a/tests/core/test_galaxies.py b/tests/core/test_galaxies.py index e086784b..a5705bd4 100644 --- a/tests/core/test_galaxies.py +++ b/tests/core/test_galaxies.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass @@ -218,13 +218,13 @@ def test_gaussian_phz( phz = glass.gaussian_phz(z, sigma_0) - xpx.testing.assert_equal(z, phz) + xpx_testing.assert_equal(z, phz) # test with rng phz = glass.gaussian_phz(z, sigma_0, rng=urng) - xpx.testing.assert_equal(z, phz) + xpx_testing.assert_equal(z, phz) # case: truncated normal @@ -270,7 +270,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - xpx.testing.assert_equal(z, phz) + xpx_testing.assert_equal(z, phz) # case: scalar redshift, array sigma_0 @@ -281,7 +281,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - xpx.testing.assert_equal(z * xp.ones_like(phz), phz) + xpx_testing.assert_equal(z * xp.ones_like(phz), phz) # case: array redshift, array sigma_0 @@ -292,7 +292,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (11, 10) - xpx.testing.assert_equal(xp.broadcast_to(z, (11, 10)), phz) + xpx_testing.assert_equal(xp.broadcast_to(z, (11, 10)), phz) # shape mismatch diff --git a/tests/core/test_harmonics.py b/tests/core/test_harmonics.py index e00d2b91..913abca2 100644 --- a/tests/core/test_harmonics.py +++ b/tests/core/test_harmonics.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass.harmonics @@ -22,9 +22,9 @@ def test_multalm(xp: ModuleType) -> None: result = glass.harmonics.multalm(alm, bl) expected_result = xp.asarray([2.0, 1.0, 1.5, 4.0, 5.0, 6.0]) - xpx.testing.assert_close(result, expected_result) + xpx_testing.assert_close(result, expected_result) with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx.testing.assert_close(alm_copy, result) + xpx_testing.assert_close(alm_copy, result) # multiple with 1s @@ -32,7 +32,7 @@ def test_multalm(xp: ModuleType) -> None: bl = xp.ones(3) result = glass.harmonics.multalm(alm, bl) - xpx.testing.assert_close(result, alm) + xpx_testing.assert_close(result, alm) # multiple with 0s @@ -41,7 +41,7 @@ def test_multalm(xp: ModuleType) -> None: result = glass.harmonics.multalm(alm, bl) expected_result = xp.asarray([0.0, 2.0, 3.0, 0.0, 0.0, 0.0]) - xpx.testing.assert_close(result, expected_result) + xpx_testing.assert_close(result, expected_result) # empty arrays @@ -49,4 +49,4 @@ def test_multalm(xp: ModuleType) -> None: bl = xp.asarray([]) result = glass.harmonics.multalm(alm, bl) - xpx.testing.assert_close(result, alm) + xpx_testing.assert_close(result, alm) diff --git a/tests/core/test_healpix.py b/tests/core/test_healpix.py index 116e7f4f..f115217c 100644 --- a/tests/core/test_healpix.py +++ b/tests/core/test_healpix.py @@ -9,7 +9,7 @@ import numpy as np import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass.healpix as hp from glass import _rng @@ -55,7 +55,7 @@ def test_alm2map_individual( pixwin=pixwin, pol=pol, ) - xpx.testing.assert_equal(xp.asarray(old), new) + xpx_testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -92,7 +92,7 @@ def test_alm2map_sequence( pixwin=pixwin, pol=pol, ) - xpx.testing.assert_equal(xp.asarray(old), new) + xpx_testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize("spin", [1, 2]) @@ -115,7 +115,7 @@ def test_alm2map_spin( assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xpx.testing.assert_equal(xp.asarray(old[i]), new[i]) + xpx_testing.assert_equal(xp.asarray(old[i]), new[i]) def test_almxfl( @@ -128,7 +128,7 @@ def test_almxfl( fl = healpix_inputs.fl(rng=urng) old = healpy.almxfl(alm, fl) new = hp.almxfl(alm, fl) - xpx.testing.assert_equal(xp.asarray(old), new) + xpx_testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -151,7 +151,7 @@ def test_ang2pix( # noqa: PLR0913 phis = healpix_inputs.latitudes(max_phi, rng=urng) old = healpix.ang2pix(healpix_inputs.nside, thetas, phis, lonlat=lonlat) new = hp.ang2pix(healpix_inputs.nside, thetas, phis, lonlat=lonlat, xp=xp) - xpx.testing.assert_equal(xp.asarray(old), new) + xpx_testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -177,7 +177,7 @@ def test_ang2vec( # noqa: PLR0913 assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xpx.testing.assert_equal(xp.asarray(old[i]), new[i]) + xpx_testing.assert_equal(xp.asarray(old[i]), new[i]) def test_get_nside( @@ -219,7 +219,7 @@ def test_map2alm_individual( pol=pol, use_pixel_weights=use_pixel_weights, ) - xpx.testing.assert_equal(xp.asarray(old), new) + xpx_testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -254,7 +254,7 @@ def test_map2alm_sequence( pol=pol, use_pixel_weights=use_pixel_weights, ) - xpx.testing.assert_equal(xp.asarray(old), new) + xpx_testing.assert_equal(xp.asarray(old), new) def test_npix2nside(healpix_inputs: type[HealpixInputs]) -> None: @@ -285,7 +285,7 @@ def test_pixwin( assert len(old) == len(new) for i in range(len(old)): - xpx.testing.assert_equal(xp.asarray(old[i], dtype=xp.float64), new[i]) + xpx_testing.assert_equal(xp.asarray(old[i], dtype=xp.float64), new[i]) @pytest.mark.parametrize("thetas", [((20, 80)), ((30, 90))]) @@ -306,7 +306,7 @@ def test_query_strip_float64( old[healpy.query_strip(healpix_inputs.nside, *thetas)] = 0 new = xp.ones(healpix_inputs.npix) new *= 1 - hp.query_strip(healpix_inputs.nside, thetas, dtype=xp.float64, xp=xp) - xpx.testing.assert_equal(xp.asarray(old), new) + xpx_testing.assert_equal(xp.asarray(old), new) @pytest.mark.skipif(not HAVE_ARRAY_API_STRICT, reason="test requires array_api_strict") @@ -357,7 +357,7 @@ def test_randang( assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xpx.testing.assert_equal(xp.asarray(old[i]), new[i]) + xpx_testing.assert_equal(xp.asarray(old[i]), new[i]) @pytest.mark.parametrize("coord", ["CE", "GC"]) @@ -375,4 +375,4 @@ def test_rotate_map_pixel( kappa = healpix_inputs.kappa(rng=urng) old = healpy.Rotator(coord=coord).rotate_map_pixel(np.asarray(kappa)) new = hp.Rotator(coord=coord).rotate_map_pixel(kappa) - xpx.testing.assert_equal(xp.asarray(old), new) + xpx_testing.assert_equal(xp.asarray(old), new) diff --git a/tests/core/test_lensing.py b/tests/core/test_lensing.py index 155d5a3a..1fe761d7 100644 --- a/tests/core/test_lensing.py +++ b/tests/core/test_lensing.py @@ -5,7 +5,7 @@ import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass import glass.healpix as hp @@ -69,8 +69,8 @@ def test_multi_plane_matrix( ) -> None: mat = glass.multi_plane_matrix(shells, cosmo) - xpx.testing.assert_equal(mat, xp.tril(mat)) - xpx.testing.assert_equal(xp.triu(mat, k=1), xp.zeros_like(mat)) + xpx_testing.assert_equal(mat, xp.tril(mat)) + xpx_testing.assert_equal(xp.triu(mat, k=1), xp.zeros_like(mat)) convergence = glass.MultiPlaneConvergence(cosmo) @@ -83,7 +83,7 @@ def test_multi_plane_matrix( if convergence.kappa is not None: kappas.append(xp.asarray(convergence.kappa, copy=True)) - xpx.testing.assert_close(mat @ deltas, xp.stack(kappas)) + xpx_testing.assert_close(mat @ deltas, xp.stack(kappas)) def test_multi_plane_weights( @@ -95,8 +95,8 @@ def test_multi_plane_weights( w_in = xp.eye(len(shells)) w_out = glass.multi_plane_weights(w_in, shells, cosmo) - xpx.testing.assert_equal(w_out, xp.triu(w_out, k=1)) - xpx.testing.assert_equal(xp.tril(w_out), xp.zeros_like(w_out)) + xpx_testing.assert_equal(w_out, xp.triu(w_out, k=1)) + xpx_testing.assert_equal(xp.tril(w_out), xp.zeros_like(w_out)) convergence = glass.MultiPlaneConvergence(cosmo) @@ -114,7 +114,7 @@ def test_multi_plane_weights( wmat = glass.multi_plane_weights(weights, shells, cosmo) - xpx.testing.assert_close(uxpx.einsum("ij,ik", wmat, deltas), kappa) + xpx_testing.assert_close(uxpx.einsum("ij,ik", wmat, deltas), kappa) @pytest.mark.parametrize("usecomplex", [True, False]) @@ -135,19 +135,19 @@ def alpha( # north lon, lat = glass.deflect(0.0, 0.0, alpha(r, 0, usecomplex=usecomplex), xp=xp) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d]), atol=1e-15) # south lon, lat = glass.deflect(0.0, 0.0, alpha(-r, 0, usecomplex=usecomplex), xp=xp) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.deflect(0.0, 0.0, alpha(0, r, usecomplex=usecomplex), xp=xp) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) # west lon, lat = glass.deflect(0.0, 0.0, alpha(0, -r, usecomplex=usecomplex), xp=xp) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # At least one input is an array lon, lat = glass.deflect( @@ -155,15 +155,15 @@ def alpha( xp.asarray(0.0), alpha(0, -r, usecomplex=usecomplex), ) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) lon, lat = glass.deflect( xp.asarray([0.0, 0.0]), xp.asarray([0.0, 0.0]), alpha(0, -r, usecomplex=usecomplex), ) - xpx.testing.assert_close(lon, xp.asarray([d, d]), atol=1e-15) - xpx.testing.assert_close(lat, xp.asarray([0.0, 0.0]), atol=1e-15) + xpx_testing.assert_close(lon, xp.asarray([d, d]), atol=1e-15) + xpx_testing.assert_close(lat, xp.asarray([0.0, 0.0]), atol=1e-15) # No inputs are arrays and xp not provided with pytest.raises( @@ -191,4 +191,4 @@ def test_deflect_many( dotp = x * x_ + y * y_ + z * z_ - xpx.testing.assert_close(dotp, xp.cos(abs_alpha)) + xpx_testing.assert_close(dotp, xp.cos(abs_alpha)) diff --git a/tests/core/test_observations.py b/tests/core/test_observations.py index cac05ccf..2227d1e6 100644 --- a/tests/core/test_observations.py +++ b/tests/core/test_observations.py @@ -6,7 +6,7 @@ import numpy as np import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass import glass.healpix as hp @@ -35,7 +35,7 @@ def test_vmap_galactic_ecliptic(xp: ModuleType) -> None: # no rotation vmap = glass.vmap_galactic_ecliptic(n_side, galactic=(0, 0), ecliptic=(0, 0), xp=xp) - xpx.testing.assert_equal(vmap, xp.zeros_like(vmap)) + xpx_testing.assert_equal(vmap, xp.zeros_like(vmap)) # check errors raised @@ -64,13 +64,13 @@ def test_gaussian_nz( # check passing in the norm nz = glass.gaussian_nz(z, mean, sigma, norm=0) - xpx.testing.assert_equal(nz, xp.zeros_like(nz)) + xpx_testing.assert_equal(nz, xp.zeros_like(nz)) # check the value of each entry is close to the norm norm = 1 nz = glass.gaussian_nz(z, mean, sigma, norm=norm) - xpx.testing.assert_close( + xpx_testing.assert_close( xp.sum(nz) / nz.shape[0], xp.asarray(norm, dtype=xp.float64), rtol=1e-2, @@ -97,7 +97,7 @@ def test_smail_nz(xp: ModuleType) -> None: # check passing in the norm pz = glass.smail_nz(z, mode, alpha, beta, norm=0) - xpx.testing.assert_equal(pz, xp.zeros_like(pz)) + xpx_testing.assert_equal(pz, xp.zeros_like(pz)) def test_fixed_zbins_default_xp() -> None: @@ -116,14 +116,14 @@ def test_fixed_zbins_default_xp() -> None: ) zbins = glass.fixed_zbins(zmin, zmax, nbins=nbins) assert len(zbins) == nbins - xpx.testing.assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) + xpx_testing.assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) # check dz input dz = 0.2 zbins = glass.fixed_zbins(zmin, zmax, dz=dz) assert len(zbins) == math.ceil((zmax - zmin) / dz) - xpx.testing.assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) + xpx_testing.assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) # check dz for spacing which results in a max value above zmax @@ -154,14 +154,14 @@ def test_fixed_zbins_xp_provided(xp: ModuleType) -> None: ) zbins = glass.fixed_zbins(zmin, zmax, nbins=nbins, xp=xp) assert len(zbins) == nbins - xpx.testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) + xpx_testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check dz input dz = 0.2 zbins = glass.fixed_zbins(zmin, zmax, dz=dz, xp=xp) assert len(zbins) == math.ceil((zmax - zmin) / dz) - xpx.testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) + xpx_testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check dz for spacing which results in a max value above zmax @@ -188,7 +188,7 @@ def test_equal_dens_zbins(xp: ModuleType) -> None: ], ) zbins = glass.equal_dens_zbins(z, xp.ones_like(z), nbins) - xpx.testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) + xpx_testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check output shape @@ -204,7 +204,7 @@ def test_tomo_nz_gausserr(xp: ModuleType) -> None: # check zeros returned binned_nz = glass.tomo_nz_gausserr(z, xp.zeros_like(z), sigma_0, zbins) - xpx.testing.assert_equal(binned_nz, xp.zeros_like(binned_nz)) + xpx_testing.assert_equal(binned_nz, xp.zeros_like(binned_nz)) # check the shape of the output diff --git a/tests/core/test_points.py b/tests/core/test_points.py index 3402fc3c..a934d082 100644 --- a/tests/core/test_points.py +++ b/tests/core/test_points.py @@ -6,6 +6,7 @@ import pytest import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass import glass.healpix as hp @@ -34,17 +35,17 @@ def test_effective_bias( z = xp.linspace(0, 1, 10) bz = xp.zeros((10,)) - xpx.testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) + xpx_testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) z = xp.zeros((10,)) bz = xp.full_like(z, 0.5) - xpx.testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) + xpx_testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) z = xp.linspace(0, 1, 10) bz = xp.full_like(z, 0.5) - xpx.testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.25)) + xpx_testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.25)) def test_linear_bias( @@ -56,21 +57,21 @@ def test_linear_bias( delta = xp.zeros((2, 2)) b = 2.0 - xpx.testing.assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) + xpx_testing.assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) # test with 0 b delta = urng.normal(5, 1, size=(2, 2)) b = 0.0 - xpx.testing.assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) + xpx_testing.assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) # compare with original implementation delta = urng.normal(5, 1, size=(2, 2)) b = 2.0 - xpx.testing.assert_close(glass.linear_bias(delta, b), b * delta) + xpx_testing.assert_close(glass.linear_bias(delta, b), b * delta) def test_loglinear_bias( @@ -82,21 +83,21 @@ def test_loglinear_bias( delta = xp.zeros((2, 2)) b = 2.0 - xpx.testing.assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) + xpx_testing.assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) # test with 0 b delta = urng.normal(5, 1, size=(2, 2)) b = 0.0 - xpx.testing.assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) + xpx_testing.assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) # compare with numpy implementation delta = urng.normal(5, 1, size=(2, 2)) b = 2.0 - xpx.testing.assert_close( + xpx_testing.assert_close( glass.loglinear_bias(delta, b), xp.expm1(b * xp.log1p(delta)), ) @@ -118,11 +119,11 @@ def test_broadcast_inputs(xp: ModuleType) -> None: assert dims == (3, 2) assert bias.shape == dims # ty: ignore[unresolved-attribute] assert xp.all(bias == bias_in) - xpx.testing.assert_equal(delta, xp.zeros_like(delta)) + xpx_testing.assert_equal(delta, xp.zeros_like(delta)) assert ngal.shape == dims # ty: ignore[unresolved-attribute] - xpx.testing.assert_equal(ngal[0, :], ngal_in) # ty: ignore[not-subscriptable] + xpx_testing.assert_equal(ngal[0, :], ngal_in) # ty: ignore[not-subscriptable] assert vis.shape == delta.shape # ty: ignore[unresolved-attribute] - xpx.testing.assert_equal(vis[0, 0, :], vis_in) # ty: ignore[not-subscriptable] + xpx_testing.assert_equal(vis[0, 0, :], vis_in) # ty: ignore[not-subscriptable] @pytest.mark.parametrize( @@ -149,7 +150,7 @@ def test_compute_density_contrast( ) assert n.shape[0] == delta.shape[-1] - xpx.testing.assert_equal(n, xp.zeros_like(n)) + xpx_testing.assert_equal(n, xp.zeros_like(n)) @pytest.mark.parametrize("remove_monopole", [False, True]) @@ -184,8 +185,8 @@ def test_apply_visibility(xp: ModuleType) -> None: vis, ) - xpx.testing.assert_equal(n[:6], xp.zeros_like(n[:6])) - xpx.testing.assert_equal(n[6:], n_in[6:]) + xpx_testing.assert_equal(n[:6], xp.zeros_like(n[:6])) + xpx_testing.assert_equal(n[6:], n_in[6:]) def test_sample_number_galaxies(xp: ModuleType) -> None: @@ -193,8 +194,8 @@ def test_sample_number_galaxies(xp: ModuleType) -> None: n = glass.points._sample_number_galaxies(n_in) - xpx.testing.assert_equal(n[:6], xp.zeros_like(n[:6], dtype=xp.int64)) - xpx.testing.assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) + xpx_testing.assert_equal(n[:6], xp.zeros_like(n[:6], dtype=xp.int64)) + xpx_testing.assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) def test_sample_number_galaxies_rng( @@ -205,8 +206,8 @@ def test_sample_number_galaxies_rng( n = glass.points._sample_number_galaxies(n_in, rng=urng) - xpx.testing.assert_equal(n[:6], xp.zeros_like(n[:6])) - xpx.testing.assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) + xpx_testing.assert_equal(n[:6], xp.zeros_like(n[:6])) + xpx_testing.assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) def test_sample_galaxies_per_pixel( @@ -305,8 +306,8 @@ def test_positions_from_delta( # noqa: PLR0915 ) assert int(count) == count - xpx.testing.assert_close(lon, xp.asarray([])) - xpx.testing.assert_close(lat, xp.asarray([])) + xpx_testing.assert_close(lon, xp.asarray([])) + xpx_testing.assert_close(lat, xp.asarray([])) # case: large delta @@ -464,7 +465,7 @@ def test_position_weights( ) expected = bias * expected - xpx.testing.assert_close(weights, expected) + xpx_testing.assert_close(weights, expected) def test_displace_arg_complex(xp: ModuleType) -> None: @@ -478,19 +479,19 @@ def test_displace_arg_complex(xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray(r + 0j)) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) # south lon, lat = glass.displace(lon0, lat0, xp.asarray(-r + 0j)) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray(1j * r)) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray(-1j * r)) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) def test_displace_arg_real(xp: ModuleType) -> None: @@ -504,19 +505,19 @@ def test_displace_arg_real(xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray([r, 0])) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) # south lon, lat = glass.displace(lon0, lat0, xp.asarray([-r, 0])) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray([0, r])) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray([0, -r])) - xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) def test_displace_abs( @@ -539,7 +540,7 @@ def test_displace_abs( cos_a = xp.cos(th) * xp.cos(th_) + xp.cos(delta) * xp.sin(th) * xp.sin(th_) - xpx.testing.assert_close(cos_a, xp.cos(abs_alpha)) + xpx_testing.assert_close(cos_a, xp.cos(abs_alpha)) def test_displacement( @@ -575,7 +576,7 @@ def test_displacement( # test each displacement individually for from_lon, from_lat, to_lon, to_lat, alpha in data: alpha_ = glass.displacement(from_lon, from_lat, to_lon, to_lat) - xpx.testing.assert_close(alpha_, alpha) + xpx_testing.assert_close(alpha_, alpha) # test on an array alpha = glass.displacement( @@ -595,7 +596,7 @@ def test_displacement_zerodist( lon = urng.uniform(-180.0, 180.0, size=100) lat = urng.uniform(-90.0, 90.0, size=100) - xpx.testing.assert_close( + xpx_testing.assert_close( glass.displacement(lon, lat, lon, lat), xp.zeros(100, dtype=xp.complex128), ) @@ -625,7 +626,7 @@ def test_displacement_consistent( # measure displacement alpha_out = glass.displacement(from_lon, from_lat, to_lon, to_lat) - xpx.testing.assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) + xpx_testing.assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) def test_displacement_random( @@ -673,11 +674,11 @@ def test_displacement_random( ], axis=1, ) - xpx.testing.assert_close(rot @ xp.asarray([0.0, 0.0, 1.0]), u) + xpx_testing.assert_close(rot @ xp.asarray([0.0, 0.0, 1.0]), u) # meta-check that recovering theta and phi from vector works - xpx.testing.assert_close(xp.atan2(xp.hypot(u[:, 0], u[:, 1]), u[:, 2]), theta) - xpx.testing.assert_close(xp.atan2(u[:, 1], u[:, 0]), phi) + xpx_testing.assert_close(xp.atan2(xp.hypot(u[:, 0], u[:, 1]), u[:, 2]), theta) + xpx_testing.assert_close(xp.atan2(u[:, 1], u[:, 0]), phi) # build the displaced points near (0, 0, 1) and rotate near theta and phi v = xp.stack( @@ -704,4 +705,4 @@ def test_displacement_random( # compute displacement and compare to input alpha_in = r * xp.exp(1j * x) alpha_out = glass.displacement(from_lon, from_lat, to_lon, to_lat) - xpx.testing.assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) + xpx_testing.assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) diff --git a/tests/core/test_shapes.py b/tests/core/test_shapes.py index f7c712f0..4a97c0ff 100644 --- a/tests/core/test_shapes.py +++ b/tests/core/test_shapes.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass @@ -151,36 +151,36 @@ def test_ellipticity_gaussian( assert eps.shape == (n,) - xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx_testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xpx.testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) - xpx.testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx_testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx_testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) eps = glass.ellipticity_gaussian(xp.asarray([n, n]), xp.asarray([0.128, 0.256])) assert eps.shape == (2 * n,) - xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx_testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xpx.testing.assert_close( + xpx_testing.assert_close( xp.std(xp.real(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0, ) - xpx.testing.assert_close( + xpx_testing.assert_close( xp.std(xp.imag(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0, ) - xpx.testing.assert_close( + xpx_testing.assert_close( xp.std(xp.real(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0, ) - xpx.testing.assert_close( + xpx_testing.assert_close( xp.std(xp.imag(eps)[n:]), xp.asarray(0.256), atol=1e-3, @@ -212,36 +212,36 @@ def test_ellipticity_intnorm( assert eps.shape == (n,) - xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx_testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xpx.testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) - xpx.testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx_testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx_testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) eps = glass.ellipticity_intnorm(xp.asarray([n, n]), xp.asarray([0.128, 0.256])) assert eps.shape == (2 * n,) - xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx_testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xpx.testing.assert_close( + xpx_testing.assert_close( xp.std(xp.real(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0, ) - xpx.testing.assert_close( + xpx_testing.assert_close( xp.std(xp.imag(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0, ) - xpx.testing.assert_close( + xpx_testing.assert_close( xp.std(xp.real(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0, ) - xpx.testing.assert_close( + xpx_testing.assert_close( xp.std(xp.imag(eps)[n:]), xp.asarray(0.256), atol=1e-3, diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index 9f738f31..47e9dc35 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -7,7 +7,7 @@ import numpy as np import pytest -import array_api_extra as xpx +import array_api_extra.testing as xpx_testing import glass from glass._array_api_utils import xp_additions as uxpx @@ -36,7 +36,7 @@ def test_distance_weight( # check values are decreasing - xpx.testing.assert_less(w[1:], w[:-1]) + xpx_testing.assert_less(w[1:], w[:-1]) def test_volume_weight( @@ -57,7 +57,7 @@ def test_volume_weight( # check values are increasing - xpx.testing.assert_less(w[:-1], w[1:]) + xpx_testing.assert_less(w[:-1], w[1:]) def test_density_weight(cosmo: Cosmology) -> None: @@ -75,7 +75,7 @@ def test_density_weight(cosmo: Cosmology) -> None: # check values are increasing - xpx.testing.assert_less(w[:-1], w[1:]) + xpx_testing.assert_less(w[:-1], w[1:]) def test_tophat_windows(xp: ModuleType) -> None: @@ -116,7 +116,7 @@ def test_linear_windows(xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.linear_windows(zgrid) - xpx.testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xpx_testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -124,7 +124,7 @@ def test_linear_windows(xp: ModuleType) -> None: # check values of zeff - xpx.testing.assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) + xpx_testing.assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) # check weight function input @@ -133,7 +133,7 @@ def test_linear_windows(xp: ModuleType) -> None: weight=lambda _: 0, ) for w in ws: - xpx.testing.assert_close(w.wa, xp.zeros_like(w.wa)) + xpx_testing.assert_close(w.wa, xp.zeros_like(w.wa)) # check error raised @@ -165,7 +165,7 @@ def test_cubic_windows(xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.cubic_windows(zgrid) - xpx.testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xpx_testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -173,7 +173,7 @@ def test_cubic_windows(xp: ModuleType) -> None: # check values of zeff - xpx.testing.assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) + xpx_testing.assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) # check weight function input @@ -182,7 +182,7 @@ def test_cubic_windows(xp: ModuleType) -> None: weight=lambda _: 0, ) for w in ws: - xpx.testing.assert_close(w.wa, xp.zeros_like(w.wa)) + xpx_testing.assert_close(w.wa, xp.zeros_like(w.wa)) # check error raised @@ -275,7 +275,7 @@ def test_partition( assert part.shape == (len(shells), 3, 2) - xpx.testing.assert_close(xp.sum(part, axis=0), uxpx.trapezoid(fz, z)) + xpx_testing.assert_close(xp.sum(part, axis=0), uxpx.trapezoid(fz, z)) def test_redshift_grid_default_xp() -> None: @@ -358,7 +358,7 @@ def test_distance_grid(cosmo: Cosmology) -> None: # check decrease in distance x = glass.distance_grid(cosmo, zmin, zmax, dx=0.3) - xpx.testing.assert_less(x[1:], x[:-1]) + xpx_testing.assert_less(x[1:], x[:-1]) # check error raised @@ -411,10 +411,10 @@ def test_combine(xp: ModuleType) -> None: assert result.shape == z.shape # Check sum of result - xpx.testing.assert_close(xp.sum(result), xp.asarray(929.267284)) + xpx_testing.assert_close(xp.sum(result), xp.asarray(929.267284)) # Check integral w.r.t z has not changed - xpx.testing.assert_close(uxpx.trapezoid(result, z), xp.asarray(4.643139), rtol=1e-6) + xpx_testing.assert_close(uxpx.trapezoid(result, z), xp.asarray(4.643139), rtol=1e-6) def test_radial_window_immutable(xp: ModuleType) -> None: @@ -453,7 +453,7 @@ def test_radial_window_zeff_none(xp: ModuleType) -> None: w = glass.RadialWindow(za, wa) - xpx.testing.assert_close(w.zeff, xp.ones_like(w.zeff)) + xpx_testing.assert_close(w.zeff, xp.ones_like(w.zeff)) # check zeff is NaN when redshift array is empty From ac38c9a78559a0b5d9cd885d043a4817c24a410a Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 10:07:06 +0100 Subject: [PATCH 26/43] Drop Python 3.10 support --- .github/workflows/test.yaml | 7 +++---- glass/arraytools.py | 4 +--- glass/jax.py | 3 ++- noxfile.py | 1 - pyproject.toml | 3 +-- tests/benchmarks/test_lensing.py | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b91d3858..57b4ede9 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -87,7 +87,6 @@ jobs: strategy: matrix: python-version: - - "3.10" - "3.11" - "3.12" - "3.13" @@ -159,9 +158,9 @@ jobs: uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2 with: carryforward: - ${{ env.BENCH_COV_NAME }},${{ env.CORE_COV_NAME }}-3.10,${{ - env.CORE_COV_NAME }}-3.11,${{ env.CORE_COV_NAME }}-3.12,${{ - env.CORE_COV_NAME }}-3.13,${{ env.CORE_COV_NAME }}-3.14 + ${{ env.BENCH_COV_NAME }},${{ env.CORE_COV_NAME }}-3.11,${{ + env.CORE_COV_NAME }}-3.12,${{ env.CORE_COV_NAME }}-3.13,${{ + env.CORE_COV_NAME }}-3.14 parallel-finished: true build: diff --git a/glass/arraytools.py b/glass/arraytools.py index 903d8e44..49a27221 100644 --- a/glass/arraytools.py +++ b/glass/arraytools.py @@ -12,8 +12,6 @@ if TYPE_CHECKING: from types import ModuleType - from typing_extensions import Unpack - from glass._types import AnyArray, FloatArray, IntArray @@ -48,7 +46,7 @@ def broadcast_leading_axes( xp: ModuleType | None = None, ) -> tuple[ tuple[int, ...], - Unpack[tuple[FloatArray, ...]], + *tuple[FloatArray, ...], ]: """ Broadcast all but the last N axes. diff --git a/glass/jax.py b/glass/jax.py index 487721df..eab52e58 100644 --- a/glass/jax.py +++ b/glass/jax.py @@ -13,8 +13,9 @@ import jax.typing if TYPE_CHECKING: + from typing import Self + from jaxtyping import PRNGKeyArray - from typing_extensions import Self from glass._types import AnyArray, DTypeLike, FloatArray, IntArray diff --git a/noxfile.py b/noxfile.py index 2d43fe79..a749ebbf 100644 --- a/noxfile.py +++ b/noxfile.py @@ -16,7 +16,6 @@ ] ALL_PYTHON = [ - "3.10", "3.11", "3.12", "3.13", diff --git a/pyproject.toml b/pyproject.toml index 9c647880..fc3a77ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,7 +60,6 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", @@ -97,7 +96,7 @@ optional-dependencies = {examples = [ "jupyter", "matplotlib", ]} -requires-python = ">=3.10" +requires-python = ">=3.11" [project.urls] Changelog = "https://glass.readthedocs.io/stable/manual/releases.html" diff --git a/tests/benchmarks/test_lensing.py b/tests/benchmarks/test_lensing.py index 1157c8cb..08201e39 100644 --- a/tests/benchmarks/test_lensing.py +++ b/tests/benchmarks/test_lensing.py @@ -10,9 +10,9 @@ if TYPE_CHECKING: from types import ModuleType + from typing import Never from pytest_benchmark.fixture import BenchmarkFixture - from typing_extensions import Never from glass._types import FloatArray, UnifiedGenerator from glass.cosmology import Cosmology From f320389603d1c54b4f1add409cd0f2fbde83db42 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 10:07:42 +0100 Subject: [PATCH 27/43] Point to main hash --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fc3a77ce..48f34cb7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,7 +70,7 @@ classifiers = [ ] dependencies = [ "array-api-compat>=1.12.0", - "array-api-extra>=0.9.0", + "array-api-extra @ git+https://github.com/data-apis/array-api-extra.git", "healpix>=2022.11.1", "healpy>=1.15.0", "transformcl>=2026.1", From 414575879eaadc1e99148d071b7bb91b08f0f849 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 10:08:24 +0100 Subject: [PATCH 28/43] Move hash to dependency groups --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 48f34cb7..3c8bc3d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,7 @@ lint = [ "ty==0.0.35", ] test = [ + "array-api-extra @ git+https://github.com/data-apis/array-api-extra.git", "cosmology-api", "fitsio", "pytest", @@ -70,7 +71,7 @@ classifiers = [ ] dependencies = [ "array-api-compat>=1.12.0", - "array-api-extra @ git+https://github.com/data-apis/array-api-extra.git", + "array-api-extra>=0.9.0", "healpix>=2022.11.1", "healpy>=1.15.0", "transformcl>=2026.1", From 0b21711a3395055ea13dae2ef66b2f4376518280 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 10:39:43 +0100 Subject: [PATCH 29/43] `check_shape=False` --- tests/core/test_algorithm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_algorithm.py b/tests/core/test_algorithm.py index 756c99a2..1fc4fac8 100644 --- a/tests/core/test_algorithm.py +++ b/tests/core/test_algorithm.py @@ -75,7 +75,7 @@ def test_cov_clip( # make sure all eigenvalues are positive h = xp.max(xp.linalg.eigvalsh(a)) - xpx_testing.assert_close(xp.linalg.eigvalsh(cov), h * xp.ones(cov.shape[0])) + xpx_testing.assert_close(xp.linalg.eigvalsh(cov), h, check_shape=False) def test_nearcorr(xp: ModuleType) -> None: From 9f0a09e3268df60314998bf7c092a085554a8d65 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 10:53:43 +0100 Subject: [PATCH 30/43] Testing improvements --- tests/benchmarks/test_shells.py | 4 ++-- tests/core/test_arraytools.py | 2 +- tests/core/test_fields.py | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/benchmarks/test_shells.py b/tests/benchmarks/test_shells.py index b24c1fba..c495fb1a 100644 --- a/tests/benchmarks/test_shells.py +++ b/tests/benchmarks/test_shells.py @@ -22,11 +22,11 @@ def test_radialwindow( """Benchmark for shells.RadialWindow.""" # check zeff is computed when not provided arr_length = 100_000 - expected_zeff = 66_666.0 + expected_zeff = xpb.asarray(66_666.0) wa = xpb.arange(arr_length) za = xpb.arange(arr_length) w = benchmark(glass.RadialWindow, za, wa) - xpx_testing.assert_close(w.zeff, xpb.asarray(expected_zeff)) + xpx_testing.assert_close(w.zeff, expected_zeff) diff --git a/tests/core/test_arraytools.py b/tests/core/test_arraytools.py index 32636d45..1fdc9ff9 100644 --- a/tests/core/test_arraytools.py +++ b/tests/core/test_arraytools.py @@ -157,7 +157,7 @@ def test_trapezoid_product(xp: ModuleType) -> None: s = glass.arraytools.trapezoid_product((x1, f1), (x2, f2)) - xpx_testing.assert_close(s, xp.ones_like(s)) + xpx_testing.assert_close(s, xp.asarray(1.0)) def test_cumulative_trapezoid(xp: ModuleType) -> None: diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index ce97040e..72de6458 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -202,8 +202,8 @@ def test_cls2cov_no_jax(xpb: ModuleType) -> None: assert cov.dtype == xpb.float64 xpx_testing.assert_close(cov[:, 0], xpb.asarray([0.5, 0.25, 0.15])) - xpx_testing.assert_close(cov[:, 1], xpb.zeros_like(cov[:, 1])) - xpx_testing.assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) + xpx_testing.assert_close(cov[:, 1], xpb.asarray(0.0), check_shape=False) + xpx_testing.assert_close(cov[:, 2], xpb.asarray(0.0), check_shape=False) # test negative value error @@ -373,7 +373,7 @@ def test_effective_cls(xp: ModuleType) -> None: result = glass.effective_cls(cls, weights1, lmax=5) assert result.shape == (1, 1, 6) - xpx_testing.assert_close(result[..., 6:], xp.zeros_like(result[..., 6:])) + xpx_testing.assert_close(result[..., 6:], xp.asarray(0.0), check_shape=False) # check with weights1 and weights2 and weights1 is weights2 From b06b1644432203cd53883399116ae5b71236ff08 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 10:56:03 +0100 Subject: [PATCH 31/43] Convert back to `xpx.testing` --- tests/benchmarks/test_arraytools.py | 8 +-- tests/benchmarks/test_fields.py | 16 +++--- tests/benchmarks/test_harmonics.py | 4 +- tests/benchmarks/test_lensing.py | 10 ++-- tests/benchmarks/test_shells.py | 4 +- tests/core/grf/test_solver.py | 16 +++--- tests/core/grf/test_transformations.py | 32 +++++------ tests/core/test_algorithm.py | 13 ++--- tests/core/test_arraytools.py | 26 ++++----- tests/core/test_fields.py | 60 ++++++++++---------- tests/core/test_galaxies.py | 12 ++-- tests/core/test_harmonics.py | 12 ++-- tests/core/test_healpix.py | 26 ++++----- tests/core/test_lensing.py | 30 +++++----- tests/core/test_observations.py | 22 ++++---- tests/core/test_points.py | 77 +++++++++++++------------- tests/core/test_shapes.py | 34 ++++++------ tests/core/test_shells.py | 30 +++++----- 18 files changed, 215 insertions(+), 217 deletions(-) diff --git a/tests/benchmarks/test_arraytools.py b/tests/benchmarks/test_arraytools.py index 8acec52d..63409f37 100644 --- a/tests/benchmarks/test_arraytools.py +++ b/tests/benchmarks/test_arraytools.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass.arraytools @@ -55,7 +55,7 @@ def test_cumulative_trapezoid_1d( ct = benchmark(glass.arraytools.cumulative_trapezoid, f, x) # Compare to int64 as old versions of glass round to int64 if `dtype` is not passed. - xpx_testing.assert_close( + xpx.testing.assert_close( xpb.asarray(ct[:4], dtype=xpb.int64), xpb.asarray([0, 1, 4, 7]), ) @@ -83,11 +83,11 @@ def test_cumulative_trapezoid_2d( expected_first_4_out = xpb.asarray([0, 1, 4, 7]) # Compare to int64 as old versions of glass round to int64 if `dtype` is not passed. - xpx_testing.assert_close( + xpx.testing.assert_close( xpb.asarray(ct[0, :4], dtype=xpb.int64), expected_first_4_out, ) - xpx_testing.assert_close( + xpx.testing.assert_close( xpb.asarray(ct[1, :4], dtype=xpb.int64), expected_first_4_out, ) diff --git a/tests/benchmarks/test_fields.py b/tests/benchmarks/test_fields.py index 75c7a145..ac6dfdd3 100644 --- a/tests/benchmarks/test_fields.py +++ b/tests/benchmarks/test_fields.py @@ -5,7 +5,7 @@ import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass import glass.fields @@ -120,7 +120,7 @@ def function_to_benchmark() -> list[Any]: j, a, s = results[0] assert j is None assert a.shape == (0,) - xpx_testing.assert_close(s, xpb.ones_like(s)) + xpx.testing.assert_close(s, xpb.ones_like(s)) @pytest.mark.stable @@ -148,9 +148,9 @@ def function_to_benchmark() -> list[Any]: assert cov.shape == (nl, nc + 1) assert cov.dtype == xpb.float64 - xpx_testing.assert_close(cov[:, 0], xpb.asarray([1.0, 1.5, 2.0])) - xpx_testing.assert_close(cov[:, 1], xpb.asarray([1.5, 2.0, 2.5])) - xpx_testing.assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) + xpx.testing.assert_close(cov[:, 0], xpb.asarray([1.0, 1.5, 2.0])) + xpx.testing.assert_close(cov[:, 1], xpb.asarray([1.5, 2.0, 2.5])) + xpx.testing.assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) @pytest.mark.stable @@ -213,7 +213,7 @@ def function_to_benchmark() -> list[Any]: for field in result: assert field.shape == (hp.nside2npix(nside),) - xpx_testing.assert_close(result[1], result[0] ** 2, atol=1e-05) + xpx.testing.assert_close(result[1], result[0] ** 2, atol=1e-05) @pytest.mark.unstable @@ -243,7 +243,7 @@ def test_getcl_lmax_0( ) expected = xpb.asarray([max(random_i, random_j)], dtype=xpb.float64) assert result.shape[0] == 1 - xpx_testing.assert_close(result, expected) + xpx.testing.assert_close(result, expected) @pytest.mark.unstable @@ -274,4 +274,4 @@ def test_getcl_lmax_larger_than_cls( ) expected = xpb.zeros((lmax - 1,), dtype=xpb.float64) assert result.shape[0] == lmax + 1 - xpx_testing.assert_close(result[2:], expected) + xpx.testing.assert_close(result[2:], expected) diff --git a/tests/benchmarks/test_harmonics.py b/tests/benchmarks/test_harmonics.py index d9985cf2..d0953bd6 100644 --- a/tests/benchmarks/test_harmonics.py +++ b/tests/benchmarks/test_harmonics.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx glass_harmonics = pytest.importorskip( "glass.harmonics", @@ -31,7 +31,7 @@ def test_multalm( result = benchmark(glass_harmonics.multalm, alm, bl) - xpx_testing.assert_close( + xpx.testing.assert_close( result[:5], xpb.asarray([scale_factor * x for x in [0.0, 3.0, 6.0, 9.0, 12.0]]), ) diff --git a/tests/benchmarks/test_lensing.py b/tests/benchmarks/test_lensing.py index 08201e39..27fc0f00 100644 --- a/tests/benchmarks/test_lensing.py +++ b/tests/benchmarks/test_lensing.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass @@ -38,8 +38,8 @@ def test_multi_plane_matrix( mat = glass.multi_plane_matrix(shells, cosmo) deltas = urngb.random((len(shells), 10)) - xpx_testing.assert_equal(mat, xpb.tril(mat)) - xpx_testing.assert_equal(xpb.triu(mat, k=1), xpb.zeros_like(mat)) + xpx.testing.assert_equal(mat, xpb.tril(mat)) + xpx.testing.assert_equal(xpb.triu(mat, k=1), xpb.zeros_like(mat)) def setup_shells_and_deltas() -> tuple[ tuple[ @@ -99,8 +99,8 @@ def test_multi_plane_weights( w_out = glass.multi_plane_weights(w_in, shells, cosmo) - xpx_testing.assert_equal(w_out, xpb.triu(w_out, 1)) - xpx_testing.assert_equal(xpb.tril(w_out), xpb.zeros_like(w_out)) + xpx.testing.assert_equal(w_out, xpb.triu(w_out, 1)) + xpx.testing.assert_equal(xpb.tril(w_out), xpb.zeros_like(w_out)) def setup_shells_deltas_and_weights() -> tuple[ tuple[ diff --git a/tests/benchmarks/test_shells.py b/tests/benchmarks/test_shells.py index c495fb1a..859a7d4e 100644 --- a/tests/benchmarks/test_shells.py +++ b/tests/benchmarks/test_shells.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass @@ -29,4 +29,4 @@ def test_radialwindow( w = benchmark(glass.RadialWindow, za, wa) - xpx_testing.assert_close(w.zeff, expected_zeff) + xpx.testing.assert_close(w.zeff, expected_zeff) diff --git a/tests/core/grf/test_solver.py b/tests/core/grf/test_solver.py index 7de7e996..d3f3e8ce 100644 --- a/tests/core/grf/test_solver.py +++ b/tests/core/grf/test_solver.py @@ -5,7 +5,7 @@ import numpy as np import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass.grf @@ -30,7 +30,7 @@ def test_one_transformation( gl1, _, _ = glass.grf.solve(cl, t) gl2, _, _ = glass.grf.solve(cl, t, t) - xpx_testing.assert_equal(gl1, gl2) + xpx.testing.assert_equal(gl1, gl2) def test_pad( @@ -61,7 +61,7 @@ def test_initial( gl1, _, _ = glass.grf.solve(cl, t) gl2, _, _ = glass.grf.solve(cl, t, initial=gl) - xpx_testing.assert_equal(gl1, gl2) + xpx.testing.assert_equal(gl1, gl2) def test_no_iterations(cl: FloatArray) -> None: @@ -70,7 +70,7 @@ def test_no_iterations(cl: FloatArray) -> None: gl1 = glass.grf.compute(cl, t) gl2, _, _ = glass.grf.solve(cl, t, maxiter=0) - xpx_testing.assert_equal(gl1, gl2) + xpx.testing.assert_equal(gl1, gl2) def test_lognormal( @@ -88,12 +88,12 @@ def test_lognormal( assert info > 0 - xpx_testing.assert_close(cl_[1 : cl.shape[0]], cl[1:], atol=0.0, rtol=cltol) + xpx.testing.assert_close(cl_[1 : cl.shape[0]], cl[1:], atol=0.0, rtol=cltol) gl_ = glass.grf.compute(cl_, t1, t2) assert gl[0] == gl0 - xpx_testing.assert_close(gl_[1 : gl.shape[0]], gl[1:]) + xpx.testing.assert_close(gl_[1 : gl.shape[0]], gl[1:]) def test_monopole( @@ -108,10 +108,10 @@ def test_monopole( gl, cl_out, _ = glass.grf.solve(cl, t, monopole=None, gltol=1e-8) assert gl[0] != 0.0 - xpx_testing.assert_close(cl_out[0], cl[0]) + xpx.testing.assert_close(cl_out[0], cl[0]) gl, cl_out, _ = glass.grf.solve(cl, t, monopole=gl0, gltol=1e-8) assert gl[0] == gl0 with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx_testing.assert_close(cl_out[0], cl[0]) + xpx.testing.assert_close(cl_out[0], cl[0]) diff --git a/tests/core/grf/test_transformations.py b/tests/core/grf/test_transformations.py index 987bd524..a24ad492 100644 --- a/tests/core/grf/test_transformations.py +++ b/tests/core/grf/test_transformations.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass.grf @@ -15,7 +15,7 @@ def test_normal(urng: UnifiedGenerator) -> None: t = glass.grf.Normal() x = urng.standard_normal(10) - xpx_testing.assert_equal(t(x, 1.0), x) + xpx.testing.assert_equal(t(x, 1.0), x) def test_lognormal( @@ -27,7 +27,7 @@ def test_lognormal( t = glass.grf.Lognormal(lam) x = urng.standard_normal(10) y = lam * xp.expm1(x - var / 2) - xpx_testing.assert_equal(t(x, var), y) + xpx.testing.assert_equal(t(x, var), y) def test_sqnormal( @@ -40,7 +40,7 @@ def test_sqnormal( t = glass.grf.SquaredNormal(a, lam) x = urng.standard_normal(10) y = lam * ((x - a) ** 2 - 1) - xpx_testing.assert_equal(t(x, var), y) + xpx.testing.assert_equal(t(x, var), y) def test_normal_normal( @@ -50,9 +50,9 @@ def test_normal_normal( t1 = glass.grf.Normal() t2 = glass.grf.Normal() x = urng.random(10) - xpx_testing.assert_equal(glass.grf.corr(t1, t2, x), x) - xpx_testing.assert_equal(glass.grf.icorr(t1, t2, x), x) - xpx_testing.assert_equal(glass.grf.dcorr(t1, t2, x), xp.ones_like(x)) + xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), x) + xpx.testing.assert_equal(glass.grf.icorr(t1, t2, x), x) + xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), xp.ones_like(x)) def test_lognormal_lognormal( @@ -69,9 +69,9 @@ def test_lognormal_lognormal( y = lam1 * lam2 * xp.expm1(x) dy = lam1 * lam2 * xp.exp(x) - xpx_testing.assert_equal(glass.grf.corr(t1, t2, x), y) - xpx_testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x) - xpx_testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) + xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) + xpx.testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x) + xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) def test_lognormal_normal( @@ -87,9 +87,9 @@ def test_lognormal_normal( y = lam1 * x dy = lam1 * xp.ones_like(x) - xpx_testing.assert_equal(glass.grf.corr(t1, t2, x), y) - xpx_testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x) - xpx_testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) + xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) + xpx.testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x) + xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) def test_sqnormal_sqnormal( @@ -109,6 +109,6 @@ def test_sqnormal_sqnormal( y = 2 * lam1 * lam2 * x * (x + 2 * a1 * a2) dy = 4 * lam1 * lam2 * (x + a1 * a2) - xpx_testing.assert_equal(glass.grf.corr(t1, t2, x), y) - xpx_testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x, nulp=8) - xpx_testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) + xpx.testing.assert_equal(glass.grf.corr(t1, t2, x), y) + xpx.testing.assert_close_nulp(glass.grf.icorr(t1, t2, y), x, nulp=8) + xpx.testing.assert_equal(glass.grf.dcorr(t1, t2, x), dy) diff --git a/tests/core/test_algorithm.py b/tests/core/test_algorithm.py index 1fc4fac8..83c1e433 100644 --- a/tests/core/test_algorithm.py +++ b/tests/core/test_algorithm.py @@ -5,7 +5,6 @@ import pytest import array_api_extra as xpx -import array_api_extra.testing as xpx_testing import glass.algorithm @@ -39,7 +38,7 @@ def test_nnls( x, tol=500 * xp.linalg.matrix_norm(a, ord=1) * xp.finfo(xp.float64).eps, ) - xpx_testing.assert_close(res, b, rtol=0.0, atol=1e-10) + xpx.testing.assert_close(res, b, rtol=0.0, atol=1e-10) # check matrix and vector's shape @@ -75,7 +74,7 @@ def test_cov_clip( # make sure all eigenvalues are positive h = xp.max(xp.linalg.eigvalsh(a)) - xpx_testing.assert_close(xp.linalg.eigvalsh(cov), h, check_shape=False) + xpx.testing.assert_close(xp.linalg.eigvalsh(cov), h, check_shape=False) def test_nearcorr(xp: ModuleType) -> None: @@ -96,11 +95,11 @@ def test_nearcorr(xp: ModuleType) -> None: ) x = glass.algorithm.nearcorr(a) - xpx_testing.assert_close(x, b, atol=1e-4) + xpx.testing.assert_close(x, b, atol=1e-4) # explicit tolerance x = glass.algorithm.nearcorr(a, tol=1e-10) - xpx_testing.assert_close(x, b, atol=1e-4) + xpx.testing.assert_close(x, b, atol=1e-4) # no iterations with pytest.warns( @@ -108,7 +107,7 @@ def test_nearcorr(xp: ModuleType) -> None: match="Nearest correlation matrix not found in 0 iterations", ): x = glass.algorithm.nearcorr(a, niter=0) - xpx_testing.assert_close(x, a) + xpx.testing.assert_close(x, a) # non-square matrix should raise with pytest.raises(ValueError, match="non-square matrix"): @@ -148,7 +147,7 @@ def test_cov_nearest( # make sure nearcorr was called with correct input nearcorr.assert_called_once() - xpx_testing.assert_close_nulp( + xpx.testing.assert_close_nulp( nearcorr.call_args_list[0].args[0], xp.divide(a, norm), ) diff --git a/tests/core/test_arraytools.py b/tests/core/test_arraytools.py index 1fdc9ff9..841a29b8 100644 --- a/tests/core/test_arraytools.py +++ b/tests/core/test_arraytools.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass.arraytools @@ -68,17 +68,17 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == () - xpx_testing.assert_close(y, xp.asarray(1.15), atol=1e-15) + xpx.testing.assert_close(y, xp.asarray(1.15), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (3,) - xpx_testing.assert_close(y, xp.asarray([1.15, 1.25, 1.35]), atol=1e-15) + xpx.testing.assert_close(y, xp.asarray([1.15, 1.25, 1.35]), atol=1e-15) x = xp.asarray([[0.5, 1.5], [2.5, 3.5]]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 2) - xpx_testing.assert_close(y, xp.asarray([[1.15, 1.25], [1.35, 1.45]]), atol=1e-15) + xpx.testing.assert_close(y, xp.asarray([[1.15, 1.25], [1.35, 1.45]]), atol=1e-15) # test n-dimensional interpolation in final axis @@ -87,12 +87,12 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2,) - xpx_testing.assert_close(y, xp.asarray([1.15, 2.15]), atol=1e-15) + xpx.testing.assert_close(y, xp.asarray([1.15, 2.15]), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 3) - xpx_testing.assert_close( + xpx.testing.assert_close( y, xp.asarray([[1.15, 1.25, 1.35], [2.15, 2.25, 2.35]]), atol=1e-15, @@ -101,7 +101,7 @@ def test_ndinterp(xp: ModuleType) -> None: x = xp.asarray([[0.5, 1.5], [2.5, 3.5]]) y = glass.arraytools.ndinterp(x, xq, yq) assert y.shape == (2, 2, 2) - xpx_testing.assert_close( + xpx.testing.assert_close( y, xp.asarray([[[1.15, 1.25], [1.35, 1.45]], [[2.15, 2.25], [2.35, 2.45]]]), atol=1e-15, @@ -116,12 +116,12 @@ def test_ndinterp(xp: ModuleType) -> None: x = 0.5 y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 1) - xpx_testing.assert_close(y, xp.asarray([[1.15], [2.15]]), atol=1e-15) + xpx.testing.assert_close(y, xp.asarray([[1.15], [2.15]]), atol=1e-15) x = xp.asarray([0.5, 1.5, 2.5]) y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 3, 1) - xpx_testing.assert_close( + xpx.testing.assert_close( y, xp.asarray([[[1.15], [1.25], [1.35]], [[2.15], [2.25], [2.35]]]), atol=1e-15, @@ -130,7 +130,7 @@ def test_ndinterp(xp: ModuleType) -> None: x = xp.asarray([[0.5, 1.5, 2.5, 3.5], [3.5, 2.5, 1.5, 0.5], [0.5, 3.5, 1.5, 2.5]]) y = glass.arraytools.ndinterp(x, xq, yq, axis=1) assert y.shape == (2, 3, 4, 1) - xpx_testing.assert_close( + xpx.testing.assert_close( y, xp.asarray([ [ @@ -157,7 +157,7 @@ def test_trapezoid_product(xp: ModuleType) -> None: s = glass.arraytools.trapezoid_product((x1, f1), (x2, f2)) - xpx_testing.assert_close(s, xp.asarray(1.0)) + xpx.testing.assert_close(s, xp.asarray(1.0)) def test_cumulative_trapezoid(xp: ModuleType) -> None: @@ -167,14 +167,14 @@ def test_cumulative_trapezoid(xp: ModuleType) -> None: x = xp.asarray([0, 1, 2, 3]) ct = glass.arraytools.cumulative_trapezoid(f, x) - xpx_testing.assert_close(ct, xp.asarray([0.0, 1.5, 4.0, 7.5])) + xpx.testing.assert_close(ct, xp.asarray([0.0, 1.5, 4.0, 7.5])) # 2D f and 1D x f = xp.asarray([[1, 4, 9, 16], [2, 3, 5, 7]]) x = xp.asarray([0, 1, 2.5, 4]) ct = glass.arraytools.cumulative_trapezoid(f, x) - xpx_testing.assert_close( + xpx.testing.assert_close( ct, xp.asarray([[0.0, 2.5, 12.25, 31.0], [0.0, 2.5, 8.5, 17.5]]), ) diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index 72de6458..2c07ebcd 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -6,7 +6,7 @@ import numpy as np import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass import glass.fields @@ -175,14 +175,14 @@ def test_cls2cov_jax(jnp: ModuleType) -> None: assert cov3.dtype == jnp.float64 # cov1 has the expected value for the first iteration (different to cov1_copy) - xpx_testing.assert_close(cov1[:, 0], jnp.asarray([0.5, 0.25, 0.15])) + xpx.testing.assert_close(cov1[:, 0], jnp.asarray([0.5, 0.25, 0.15])) # The copies should not be equal with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx_testing.assert_close(cov1, cov2) + xpx.testing.assert_close(cov1, cov2) with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx_testing.assert_close(cov2, cov3) + xpx.testing.assert_close(cov2, cov3) def test_cls2cov_no_jax(xpb: ModuleType) -> None: @@ -201,9 +201,9 @@ def test_cls2cov_no_jax(xpb: ModuleType) -> None: assert cov.shape == (nl, nc + 1) assert cov.dtype == xpb.float64 - xpx_testing.assert_close(cov[:, 0], xpb.asarray([0.5, 0.25, 0.15])) - xpx_testing.assert_close(cov[:, 1], xpb.asarray(0.0), check_shape=False) - xpx_testing.assert_close(cov[:, 2], xpb.asarray(0.0), check_shape=False) + xpx.testing.assert_close(cov[:, 0], xpb.asarray([0.5, 0.25, 0.15])) + xpx.testing.assert_close(cov[:, 1], xpb.asarray(0.0), check_shape=False) + xpx.testing.assert_close(cov[:, 2], xpb.asarray(0.0), check_shape=False) # test negative value error @@ -259,19 +259,19 @@ def test_cls2cov_no_jax(xpb: ModuleType) -> None: assert cov3.dtype == xpb.float64 # cov1|2|3 reuse the same data, so should all equal the third result - xpx_testing.assert_close(cov1[:, 0], xpb.asarray([0.45, 0.25, 0.15])) - xpx_testing.assert_close(cov1, cov2) - xpx_testing.assert_close(cov2, cov3) + xpx.testing.assert_close(cov1[:, 0], xpb.asarray([0.45, 0.25, 0.15])) + xpx.testing.assert_close(cov1, cov2) + xpx.testing.assert_close(cov2, cov3) # cov1 has the expected value for the first iteration (different to cov1_copy) - xpx_testing.assert_close(cov1_copy[:, 0], xpb.asarray([0.5, 0.25, 0.15])) + xpx.testing.assert_close(cov1_copy[:, 0], xpb.asarray([0.5, 0.25, 0.15])) # The copies should not be equal with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx_testing.assert_close(cov1_copy, cov2_copy) + xpx.testing.assert_close(cov1_copy, cov2_copy) with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx_testing.assert_close(cov2_copy, cov3) + xpx.testing.assert_close(cov2_copy, cov3) def test_lognormal_gls(xp: ModuleType) -> None: @@ -341,7 +341,7 @@ def test_discretized_cls(xp: ModuleType) -> None: for cl in result: n = min(cl.shape[0], pw.shape[0]) # ty: ignore[unresolved-attribute] expected = xp.ones(n) * pw[:n] ** 2 - xpx_testing.assert_close(cl[:n], expected) + xpx.testing.assert_close(cl[:n], expected) def test_effective_cls(xp: ModuleType) -> None: @@ -373,7 +373,7 @@ def test_effective_cls(xp: ModuleType) -> None: result = glass.effective_cls(cls, weights1, lmax=5) assert result.shape == (1, 1, 6) - xpx_testing.assert_close(result[..., 6:], xp.asarray(0.0), check_shape=False) + xpx.testing.assert_close(result[..., 6:], xp.asarray(0.0), check_shape=False) # check with weights1 and weights2 and weights1 is weights2 @@ -404,7 +404,7 @@ def test_generate_grf(xp: ModuleType) -> None: assert new_gaussian_fields[0].shape == (hp.nside2npix(nside),) - xpx_testing.assert_close(new_gaussian_fields[0], gaussian_fields[0]) + xpx.testing.assert_close(new_gaussian_fields[0], gaussian_fields[0]) with pytest.raises(ValueError, match="all gls are empty"): list(glass.fields._generate_grf([xp.asarray([])], nside)) @@ -457,7 +457,7 @@ def test_generate(xp: ModuleType) -> None: result = list(glass.generate(fields, gls, nside=nside)) - xpx_testing.assert_close(result[1], result[0] ** 2, atol=1e-05) + xpx.testing.assert_close(result[1], result[0] ** 2, atol=1e-05) def test_getcl(xp: ModuleType) -> None: @@ -472,19 +472,19 @@ def test_getcl(xp: ModuleType) -> None: for j in range(10): result = glass.getcl(cls, i, j) expected = xp.asarray([min(i, j), max(i, j)], dtype=xp.float64) - xpx_testing.assert_close(xp.sort(result), expected) + xpx.testing.assert_close(xp.sort(result), expected) # check slicing result = glass.getcl(cls, i, j, lmax=0) expected = xp.asarray([max(i, j)], dtype=xp.float64) assert result.shape[0] == 1 - xpx_testing.assert_close(result, expected) + xpx.testing.assert_close(result, expected) # check padding result = glass.getcl(cls, i, j, lmax=50) expected = xp.zeros((49,), dtype=xp.float64) assert result.shape[0] == 51 - xpx_testing.assert_close(result[2:], expected) + xpx.testing.assert_close(result[2:], expected) def test_is_inv_triangle_number(not_triangle_numbers: list[int]) -> None: @@ -528,17 +528,17 @@ def test_enumerate_spectra(xp: ModuleType) -> None: def test_spectra_indices(xp: ModuleType) -> None: - xpx_testing.assert_equal(glass.spectra_indices(0), np.zeros((0, 2), dtype=np.int64)) - xpx_testing.assert_equal( + xpx.testing.assert_equal(glass.spectra_indices(0), np.zeros((0, 2), dtype=np.int64)) + xpx.testing.assert_equal( glass.spectra_indices(0, xp=xp), xp.zeros((0, 2), dtype=xp.int64), ) - xpx_testing.assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) - xpx_testing.assert_equal( + xpx.testing.assert_equal(glass.spectra_indices(1, xp=xp), xp.asarray([[0, 0]])) + xpx.testing.assert_equal( glass.spectra_indices(2, xp=xp), xp.asarray([[0, 0], [1, 1], [1, 0]]), ) - xpx_testing.assert_equal( + xpx.testing.assert_equal( glass.spectra_indices(3, xp=xp), xp.asarray([[0, 0], [1, 1], [1, 0], [2, 2], [2, 1], [2, 0]]), ) @@ -670,7 +670,7 @@ def test_healpix_to_glass_spectra() -> None: def test_glass_to_healpix_alm(xp: ModuleType) -> None: inp = xp.asarray([00, 10, 11, 20, 21, 22, 30, 31, 32, 33], dtype=xp.complex128) out = glass.fields._glass_to_healpix_alm(inp) - xpx_testing.assert_equal( + xpx.testing.assert_equal( out, xp.asarray([00, 10, 20, 30, 11, 21, 31, 22, 32, 33], dtype=xp.complex128), ) @@ -692,7 +692,7 @@ def test_lognormal_shift_hilbert2011(xp: ModuleType) -> None: 0.1568, ]) - xpx_testing.assert_close(shifts, check, atol=1e-4, rtol=1e-4) + xpx.testing.assert_close(shifts, check, atol=1e-4, rtol=1e-4) def test_cov_from_spectra(xp: ModuleType) -> None: @@ -708,7 +708,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: ] ] - xpx_testing.assert_equal( + xpx.testing.assert_equal( glass.cov_from_spectra(spectra), xp.asarray([ [ @@ -734,7 +734,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: ]), ) - xpx_testing.assert_equal( + xpx.testing.assert_equal( glass.cov_from_spectra(spectra, lmax=1), xp.asarray([ [ @@ -750,7 +750,7 @@ def test_cov_from_spectra(xp: ModuleType) -> None: ]), ) - xpx_testing.assert_equal( + xpx.testing.assert_equal( glass.cov_from_spectra(spectra, lmax=4), xp.asarray([ [ diff --git a/tests/core/test_galaxies.py b/tests/core/test_galaxies.py index a5705bd4..e086784b 100644 --- a/tests/core/test_galaxies.py +++ b/tests/core/test_galaxies.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass @@ -218,13 +218,13 @@ def test_gaussian_phz( phz = glass.gaussian_phz(z, sigma_0) - xpx_testing.assert_equal(z, phz) + xpx.testing.assert_equal(z, phz) # test with rng phz = glass.gaussian_phz(z, sigma_0, rng=urng) - xpx_testing.assert_equal(z, phz) + xpx.testing.assert_equal(z, phz) # case: truncated normal @@ -270,7 +270,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - xpx_testing.assert_equal(z, phz) + xpx.testing.assert_equal(z, phz) # case: scalar redshift, array sigma_0 @@ -281,7 +281,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - xpx_testing.assert_equal(z * xp.ones_like(phz), phz) + xpx.testing.assert_equal(z * xp.ones_like(phz), phz) # case: array redshift, array sigma_0 @@ -292,7 +292,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (11, 10) - xpx_testing.assert_equal(xp.broadcast_to(z, (11, 10)), phz) + xpx.testing.assert_equal(xp.broadcast_to(z, (11, 10)), phz) # shape mismatch diff --git a/tests/core/test_harmonics.py b/tests/core/test_harmonics.py index 913abca2..e00d2b91 100644 --- a/tests/core/test_harmonics.py +++ b/tests/core/test_harmonics.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass.harmonics @@ -22,9 +22,9 @@ def test_multalm(xp: ModuleType) -> None: result = glass.harmonics.multalm(alm, bl) expected_result = xp.asarray([2.0, 1.0, 1.5, 4.0, 5.0, 6.0]) - xpx_testing.assert_close(result, expected_result) + xpx.testing.assert_close(result, expected_result) with pytest.raises(AssertionError, match="Not equal to tolerance"): - xpx_testing.assert_close(alm_copy, result) + xpx.testing.assert_close(alm_copy, result) # multiple with 1s @@ -32,7 +32,7 @@ def test_multalm(xp: ModuleType) -> None: bl = xp.ones(3) result = glass.harmonics.multalm(alm, bl) - xpx_testing.assert_close(result, alm) + xpx.testing.assert_close(result, alm) # multiple with 0s @@ -41,7 +41,7 @@ def test_multalm(xp: ModuleType) -> None: result = glass.harmonics.multalm(alm, bl) expected_result = xp.asarray([0.0, 2.0, 3.0, 0.0, 0.0, 0.0]) - xpx_testing.assert_close(result, expected_result) + xpx.testing.assert_close(result, expected_result) # empty arrays @@ -49,4 +49,4 @@ def test_multalm(xp: ModuleType) -> None: bl = xp.asarray([]) result = glass.harmonics.multalm(alm, bl) - xpx_testing.assert_close(result, alm) + xpx.testing.assert_close(result, alm) diff --git a/tests/core/test_healpix.py b/tests/core/test_healpix.py index f115217c..116e7f4f 100644 --- a/tests/core/test_healpix.py +++ b/tests/core/test_healpix.py @@ -9,7 +9,7 @@ import numpy as np import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass.healpix as hp from glass import _rng @@ -55,7 +55,7 @@ def test_alm2map_individual( pixwin=pixwin, pol=pol, ) - xpx_testing.assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -92,7 +92,7 @@ def test_alm2map_sequence( pixwin=pixwin, pol=pol, ) - xpx_testing.assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize("spin", [1, 2]) @@ -115,7 +115,7 @@ def test_alm2map_spin( assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xpx_testing.assert_equal(xp.asarray(old[i]), new[i]) + xpx.testing.assert_equal(xp.asarray(old[i]), new[i]) def test_almxfl( @@ -128,7 +128,7 @@ def test_almxfl( fl = healpix_inputs.fl(rng=urng) old = healpy.almxfl(alm, fl) new = hp.almxfl(alm, fl) - xpx_testing.assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -151,7 +151,7 @@ def test_ang2pix( # noqa: PLR0913 phis = healpix_inputs.latitudes(max_phi, rng=urng) old = healpix.ang2pix(healpix_inputs.nside, thetas, phis, lonlat=lonlat) new = hp.ang2pix(healpix_inputs.nside, thetas, phis, lonlat=lonlat, xp=xp) - xpx_testing.assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -177,7 +177,7 @@ def test_ang2vec( # noqa: PLR0913 assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xpx_testing.assert_equal(xp.asarray(old[i]), new[i]) + xpx.testing.assert_equal(xp.asarray(old[i]), new[i]) def test_get_nside( @@ -219,7 +219,7 @@ def test_map2alm_individual( pol=pol, use_pixel_weights=use_pixel_weights, ) - xpx_testing.assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.parametrize( @@ -254,7 +254,7 @@ def test_map2alm_sequence( pol=pol, use_pixel_weights=use_pixel_weights, ) - xpx_testing.assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) def test_npix2nside(healpix_inputs: type[HealpixInputs]) -> None: @@ -285,7 +285,7 @@ def test_pixwin( assert len(old) == len(new) for i in range(len(old)): - xpx_testing.assert_equal(xp.asarray(old[i], dtype=xp.float64), new[i]) + xpx.testing.assert_equal(xp.asarray(old[i], dtype=xp.float64), new[i]) @pytest.mark.parametrize("thetas", [((20, 80)), ((30, 90))]) @@ -306,7 +306,7 @@ def test_query_strip_float64( old[healpy.query_strip(healpix_inputs.nside, *thetas)] = 0 new = xp.ones(healpix_inputs.npix) new *= 1 - hp.query_strip(healpix_inputs.nside, thetas, dtype=xp.float64, xp=xp) - xpx_testing.assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) @pytest.mark.skipif(not HAVE_ARRAY_API_STRICT, reason="test requires array_api_strict") @@ -357,7 +357,7 @@ def test_randang( assert type(old) is type(new) assert len(old) == len(new) for i in range(len(old)): - xpx_testing.assert_equal(xp.asarray(old[i]), new[i]) + xpx.testing.assert_equal(xp.asarray(old[i]), new[i]) @pytest.mark.parametrize("coord", ["CE", "GC"]) @@ -375,4 +375,4 @@ def test_rotate_map_pixel( kappa = healpix_inputs.kappa(rng=urng) old = healpy.Rotator(coord=coord).rotate_map_pixel(np.asarray(kappa)) new = hp.Rotator(coord=coord).rotate_map_pixel(kappa) - xpx_testing.assert_equal(xp.asarray(old), new) + xpx.testing.assert_equal(xp.asarray(old), new) diff --git a/tests/core/test_lensing.py b/tests/core/test_lensing.py index 1fe761d7..155d5a3a 100644 --- a/tests/core/test_lensing.py +++ b/tests/core/test_lensing.py @@ -5,7 +5,7 @@ import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass import glass.healpix as hp @@ -69,8 +69,8 @@ def test_multi_plane_matrix( ) -> None: mat = glass.multi_plane_matrix(shells, cosmo) - xpx_testing.assert_equal(mat, xp.tril(mat)) - xpx_testing.assert_equal(xp.triu(mat, k=1), xp.zeros_like(mat)) + xpx.testing.assert_equal(mat, xp.tril(mat)) + xpx.testing.assert_equal(xp.triu(mat, k=1), xp.zeros_like(mat)) convergence = glass.MultiPlaneConvergence(cosmo) @@ -83,7 +83,7 @@ def test_multi_plane_matrix( if convergence.kappa is not None: kappas.append(xp.asarray(convergence.kappa, copy=True)) - xpx_testing.assert_close(mat @ deltas, xp.stack(kappas)) + xpx.testing.assert_close(mat @ deltas, xp.stack(kappas)) def test_multi_plane_weights( @@ -95,8 +95,8 @@ def test_multi_plane_weights( w_in = xp.eye(len(shells)) w_out = glass.multi_plane_weights(w_in, shells, cosmo) - xpx_testing.assert_equal(w_out, xp.triu(w_out, k=1)) - xpx_testing.assert_equal(xp.tril(w_out), xp.zeros_like(w_out)) + xpx.testing.assert_equal(w_out, xp.triu(w_out, k=1)) + xpx.testing.assert_equal(xp.tril(w_out), xp.zeros_like(w_out)) convergence = glass.MultiPlaneConvergence(cosmo) @@ -114,7 +114,7 @@ def test_multi_plane_weights( wmat = glass.multi_plane_weights(weights, shells, cosmo) - xpx_testing.assert_close(uxpx.einsum("ij,ik", wmat, deltas), kappa) + xpx.testing.assert_close(uxpx.einsum("ij,ik", wmat, deltas), kappa) @pytest.mark.parametrize("usecomplex", [True, False]) @@ -135,19 +135,19 @@ def alpha( # north lon, lat = glass.deflect(0.0, 0.0, alpha(r, 0, usecomplex=usecomplex), xp=xp) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d]), atol=1e-15) # south lon, lat = glass.deflect(0.0, 0.0, alpha(-r, 0, usecomplex=usecomplex), xp=xp) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.deflect(0.0, 0.0, alpha(0, r, usecomplex=usecomplex), xp=xp) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) # west lon, lat = glass.deflect(0.0, 0.0, alpha(0, -r, usecomplex=usecomplex), xp=xp) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # At least one input is an array lon, lat = glass.deflect( @@ -155,15 +155,15 @@ def alpha( xp.asarray(0.0), alpha(0, -r, usecomplex=usecomplex), ) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) lon, lat = glass.deflect( xp.asarray([0.0, 0.0]), xp.asarray([0.0, 0.0]), alpha(0, -r, usecomplex=usecomplex), ) - xpx_testing.assert_close(lon, xp.asarray([d, d]), atol=1e-15) - xpx_testing.assert_close(lat, xp.asarray([0.0, 0.0]), atol=1e-15) + xpx.testing.assert_close(lon, xp.asarray([d, d]), atol=1e-15) + xpx.testing.assert_close(lat, xp.asarray([0.0, 0.0]), atol=1e-15) # No inputs are arrays and xp not provided with pytest.raises( @@ -191,4 +191,4 @@ def test_deflect_many( dotp = x * x_ + y * y_ + z * z_ - xpx_testing.assert_close(dotp, xp.cos(abs_alpha)) + xpx.testing.assert_close(dotp, xp.cos(abs_alpha)) diff --git a/tests/core/test_observations.py b/tests/core/test_observations.py index 2227d1e6..cac05ccf 100644 --- a/tests/core/test_observations.py +++ b/tests/core/test_observations.py @@ -6,7 +6,7 @@ import numpy as np import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass import glass.healpix as hp @@ -35,7 +35,7 @@ def test_vmap_galactic_ecliptic(xp: ModuleType) -> None: # no rotation vmap = glass.vmap_galactic_ecliptic(n_side, galactic=(0, 0), ecliptic=(0, 0), xp=xp) - xpx_testing.assert_equal(vmap, xp.zeros_like(vmap)) + xpx.testing.assert_equal(vmap, xp.zeros_like(vmap)) # check errors raised @@ -64,13 +64,13 @@ def test_gaussian_nz( # check passing in the norm nz = glass.gaussian_nz(z, mean, sigma, norm=0) - xpx_testing.assert_equal(nz, xp.zeros_like(nz)) + xpx.testing.assert_equal(nz, xp.zeros_like(nz)) # check the value of each entry is close to the norm norm = 1 nz = glass.gaussian_nz(z, mean, sigma, norm=norm) - xpx_testing.assert_close( + xpx.testing.assert_close( xp.sum(nz) / nz.shape[0], xp.asarray(norm, dtype=xp.float64), rtol=1e-2, @@ -97,7 +97,7 @@ def test_smail_nz(xp: ModuleType) -> None: # check passing in the norm pz = glass.smail_nz(z, mode, alpha, beta, norm=0) - xpx_testing.assert_equal(pz, xp.zeros_like(pz)) + xpx.testing.assert_equal(pz, xp.zeros_like(pz)) def test_fixed_zbins_default_xp() -> None: @@ -116,14 +116,14 @@ def test_fixed_zbins_default_xp() -> None: ) zbins = glass.fixed_zbins(zmin, zmax, nbins=nbins) assert len(zbins) == nbins - xpx_testing.assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) + xpx.testing.assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) # check dz input dz = 0.2 zbins = glass.fixed_zbins(zmin, zmax, dz=dz) assert len(zbins) == math.ceil((zmax - zmin) / dz) - xpx_testing.assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) + xpx.testing.assert_close(np.asarray(zbins), expected_zbins, rtol=1e-15) # check dz for spacing which results in a max value above zmax @@ -154,14 +154,14 @@ def test_fixed_zbins_xp_provided(xp: ModuleType) -> None: ) zbins = glass.fixed_zbins(zmin, zmax, nbins=nbins, xp=xp) assert len(zbins) == nbins - xpx_testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) + xpx.testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check dz input dz = 0.2 zbins = glass.fixed_zbins(zmin, zmax, dz=dz, xp=xp) assert len(zbins) == math.ceil((zmax - zmin) / dz) - xpx_testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) + xpx.testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check dz for spacing which results in a max value above zmax @@ -188,7 +188,7 @@ def test_equal_dens_zbins(xp: ModuleType) -> None: ], ) zbins = glass.equal_dens_zbins(z, xp.ones_like(z), nbins) - xpx_testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) + xpx.testing.assert_close(xp.asarray(zbins), expected_zbins, rtol=1e-15) # check output shape @@ -204,7 +204,7 @@ def test_tomo_nz_gausserr(xp: ModuleType) -> None: # check zeros returned binned_nz = glass.tomo_nz_gausserr(z, xp.zeros_like(z), sigma_0, zbins) - xpx_testing.assert_equal(binned_nz, xp.zeros_like(binned_nz)) + xpx.testing.assert_equal(binned_nz, xp.zeros_like(binned_nz)) # check the shape of the output diff --git a/tests/core/test_points.py b/tests/core/test_points.py index a934d082..3402fc3c 100644 --- a/tests/core/test_points.py +++ b/tests/core/test_points.py @@ -6,7 +6,6 @@ import pytest import array_api_extra as xpx -import array_api_extra.testing as xpx_testing import glass import glass.healpix as hp @@ -35,17 +34,17 @@ def test_effective_bias( z = xp.linspace(0, 1, 10) bz = xp.zeros((10,)) - xpx_testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) + xpx.testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) z = xp.zeros((10,)) bz = xp.full_like(z, 0.5) - xpx_testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) + xpx.testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.0)) z = xp.linspace(0, 1, 10) bz = xp.full_like(z, 0.5) - xpx_testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.25)) + xpx.testing.assert_close(glass.effective_bias(z, bz, w), xp.asarray(0.25)) def test_linear_bias( @@ -57,21 +56,21 @@ def test_linear_bias( delta = xp.zeros((2, 2)) b = 2.0 - xpx_testing.assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) + xpx.testing.assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) # test with 0 b delta = urng.normal(5, 1, size=(2, 2)) b = 0.0 - xpx_testing.assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) + xpx.testing.assert_close(glass.linear_bias(delta, b), xp.zeros((2, 2))) # compare with original implementation delta = urng.normal(5, 1, size=(2, 2)) b = 2.0 - xpx_testing.assert_close(glass.linear_bias(delta, b), b * delta) + xpx.testing.assert_close(glass.linear_bias(delta, b), b * delta) def test_loglinear_bias( @@ -83,21 +82,21 @@ def test_loglinear_bias( delta = xp.zeros((2, 2)) b = 2.0 - xpx_testing.assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) + xpx.testing.assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) # test with 0 b delta = urng.normal(5, 1, size=(2, 2)) b = 0.0 - xpx_testing.assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) + xpx.testing.assert_close(glass.loglinear_bias(delta, b), xp.zeros((2, 2))) # compare with numpy implementation delta = urng.normal(5, 1, size=(2, 2)) b = 2.0 - xpx_testing.assert_close( + xpx.testing.assert_close( glass.loglinear_bias(delta, b), xp.expm1(b * xp.log1p(delta)), ) @@ -119,11 +118,11 @@ def test_broadcast_inputs(xp: ModuleType) -> None: assert dims == (3, 2) assert bias.shape == dims # ty: ignore[unresolved-attribute] assert xp.all(bias == bias_in) - xpx_testing.assert_equal(delta, xp.zeros_like(delta)) + xpx.testing.assert_equal(delta, xp.zeros_like(delta)) assert ngal.shape == dims # ty: ignore[unresolved-attribute] - xpx_testing.assert_equal(ngal[0, :], ngal_in) # ty: ignore[not-subscriptable] + xpx.testing.assert_equal(ngal[0, :], ngal_in) # ty: ignore[not-subscriptable] assert vis.shape == delta.shape # ty: ignore[unresolved-attribute] - xpx_testing.assert_equal(vis[0, 0, :], vis_in) # ty: ignore[not-subscriptable] + xpx.testing.assert_equal(vis[0, 0, :], vis_in) # ty: ignore[not-subscriptable] @pytest.mark.parametrize( @@ -150,7 +149,7 @@ def test_compute_density_contrast( ) assert n.shape[0] == delta.shape[-1] - xpx_testing.assert_equal(n, xp.zeros_like(n)) + xpx.testing.assert_equal(n, xp.zeros_like(n)) @pytest.mark.parametrize("remove_monopole", [False, True]) @@ -185,8 +184,8 @@ def test_apply_visibility(xp: ModuleType) -> None: vis, ) - xpx_testing.assert_equal(n[:6], xp.zeros_like(n[:6])) - xpx_testing.assert_equal(n[6:], n_in[6:]) + xpx.testing.assert_equal(n[:6], xp.zeros_like(n[:6])) + xpx.testing.assert_equal(n[6:], n_in[6:]) def test_sample_number_galaxies(xp: ModuleType) -> None: @@ -194,8 +193,8 @@ def test_sample_number_galaxies(xp: ModuleType) -> None: n = glass.points._sample_number_galaxies(n_in) - xpx_testing.assert_equal(n[:6], xp.zeros_like(n[:6], dtype=xp.int64)) - xpx_testing.assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) + xpx.testing.assert_equal(n[:6], xp.zeros_like(n[:6], dtype=xp.int64)) + xpx.testing.assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) def test_sample_number_galaxies_rng( @@ -206,8 +205,8 @@ def test_sample_number_galaxies_rng( n = glass.points._sample_number_galaxies(n_in, rng=urng) - xpx_testing.assert_equal(n[:6], xp.zeros_like(n[:6])) - xpx_testing.assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) + xpx.testing.assert_equal(n[:6], xp.zeros_like(n[:6])) + xpx.testing.assert_close(xp.asarray(n[6:], dtype=xp.float64), n_in[6:], atol=250) def test_sample_galaxies_per_pixel( @@ -306,8 +305,8 @@ def test_positions_from_delta( # noqa: PLR0915 ) assert int(count) == count - xpx_testing.assert_close(lon, xp.asarray([])) - xpx_testing.assert_close(lat, xp.asarray([])) + xpx.testing.assert_close(lon, xp.asarray([])) + xpx.testing.assert_close(lat, xp.asarray([])) # case: large delta @@ -465,7 +464,7 @@ def test_position_weights( ) expected = bias * expected - xpx_testing.assert_close(weights, expected) + xpx.testing.assert_close(weights, expected) def test_displace_arg_complex(xp: ModuleType) -> None: @@ -479,19 +478,19 @@ def test_displace_arg_complex(xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray(r + 0j)) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) # south lon, lat = glass.displace(lon0, lat0, xp.asarray(-r + 0j)) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray(1j * r)) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray(-1j * r)) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) def test_displace_arg_real(xp: ModuleType) -> None: @@ -505,19 +504,19 @@ def test_displace_arg_real(xp: ModuleType) -> None: # north lon, lat = glass.displace(lon0, lat0, xp.asarray([r, 0])) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, d])) # south lon, lat = glass.displace(lon0, lat0, xp.asarray([-r, 0])) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([0.0, -d]), atol=1e-15) # east lon, lat = glass.displace(lon0, lat0, xp.asarray([0, r])) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([d, 0.0]), atol=1e-15) # west lon, lat = glass.displace(lon0, lat0, xp.asarray([0, -r])) - xpx_testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) + xpx.testing.assert_close(xp.stack([lon, lat]), xp.asarray([-d, 0.0]), atol=1e-15) def test_displace_abs( @@ -540,7 +539,7 @@ def test_displace_abs( cos_a = xp.cos(th) * xp.cos(th_) + xp.cos(delta) * xp.sin(th) * xp.sin(th_) - xpx_testing.assert_close(cos_a, xp.cos(abs_alpha)) + xpx.testing.assert_close(cos_a, xp.cos(abs_alpha)) def test_displacement( @@ -576,7 +575,7 @@ def test_displacement( # test each displacement individually for from_lon, from_lat, to_lon, to_lat, alpha in data: alpha_ = glass.displacement(from_lon, from_lat, to_lon, to_lat) - xpx_testing.assert_close(alpha_, alpha) + xpx.testing.assert_close(alpha_, alpha) # test on an array alpha = glass.displacement( @@ -596,7 +595,7 @@ def test_displacement_zerodist( lon = urng.uniform(-180.0, 180.0, size=100) lat = urng.uniform(-90.0, 90.0, size=100) - xpx_testing.assert_close( + xpx.testing.assert_close( glass.displacement(lon, lat, lon, lat), xp.zeros(100, dtype=xp.complex128), ) @@ -626,7 +625,7 @@ def test_displacement_consistent( # measure displacement alpha_out = glass.displacement(from_lon, from_lat, to_lon, to_lat) - xpx_testing.assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) + xpx.testing.assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) def test_displacement_random( @@ -674,11 +673,11 @@ def test_displacement_random( ], axis=1, ) - xpx_testing.assert_close(rot @ xp.asarray([0.0, 0.0, 1.0]), u) + xpx.testing.assert_close(rot @ xp.asarray([0.0, 0.0, 1.0]), u) # meta-check that recovering theta and phi from vector works - xpx_testing.assert_close(xp.atan2(xp.hypot(u[:, 0], u[:, 1]), u[:, 2]), theta) - xpx_testing.assert_close(xp.atan2(u[:, 1], u[:, 0]), phi) + xpx.testing.assert_close(xp.atan2(xp.hypot(u[:, 0], u[:, 1]), u[:, 2]), theta) + xpx.testing.assert_close(xp.atan2(u[:, 1], u[:, 0]), phi) # build the displaced points near (0, 0, 1) and rotate near theta and phi v = xp.stack( @@ -705,4 +704,4 @@ def test_displacement_random( # compute displacement and compare to input alpha_in = r * xp.exp(1j * x) alpha_out = glass.displacement(from_lon, from_lat, to_lon, to_lat) - xpx_testing.assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) + xpx.testing.assert_close(alpha_out, alpha_in, atol=0.0, rtol=1e-10) diff --git a/tests/core/test_shapes.py b/tests/core/test_shapes.py index 4a97c0ff..f7c712f0 100644 --- a/tests/core/test_shapes.py +++ b/tests/core/test_shapes.py @@ -4,7 +4,7 @@ import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass @@ -151,36 +151,36 @@ def test_ellipticity_gaussian( assert eps.shape == (n,) - xpx_testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xpx_testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) - xpx_testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx.testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx.testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) eps = glass.ellipticity_gaussian(xp.asarray([n, n]), xp.asarray([0.128, 0.256])) assert eps.shape == (2 * n,) - xpx_testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xpx_testing.assert_close( + xpx.testing.assert_close( xp.std(xp.real(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0, ) - xpx_testing.assert_close( + xpx.testing.assert_close( xp.std(xp.imag(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0, ) - xpx_testing.assert_close( + xpx.testing.assert_close( xp.std(xp.real(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0, ) - xpx_testing.assert_close( + xpx.testing.assert_close( xp.std(xp.imag(eps)[n:]), xp.asarray(0.256), atol=1e-3, @@ -212,36 +212,36 @@ def test_ellipticity_intnorm( assert eps.shape == (n,) - xpx_testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xpx_testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) - xpx_testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx.testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) + xpx.testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) eps = glass.ellipticity_intnorm(xp.asarray([n, n]), xp.asarray([0.128, 0.256])) assert eps.shape == (2 * n,) - xpx_testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) - xpx_testing.assert_close( + xpx.testing.assert_close( xp.std(xp.real(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0, ) - xpx_testing.assert_close( + xpx.testing.assert_close( xp.std(xp.imag(eps)[:n]), xp.asarray(0.128), atol=1e-3, rtol=0, ) - xpx_testing.assert_close( + xpx.testing.assert_close( xp.std(xp.real(eps)[n:]), xp.asarray(0.256), atol=1e-3, rtol=0, ) - xpx_testing.assert_close( + xpx.testing.assert_close( xp.std(xp.imag(eps)[n:]), xp.asarray(0.256), atol=1e-3, diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index 47e9dc35..9f738f31 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -7,7 +7,7 @@ import numpy as np import pytest -import array_api_extra.testing as xpx_testing +import array_api_extra as xpx import glass from glass._array_api_utils import xp_additions as uxpx @@ -36,7 +36,7 @@ def test_distance_weight( # check values are decreasing - xpx_testing.assert_less(w[1:], w[:-1]) + xpx.testing.assert_less(w[1:], w[:-1]) def test_volume_weight( @@ -57,7 +57,7 @@ def test_volume_weight( # check values are increasing - xpx_testing.assert_less(w[:-1], w[1:]) + xpx.testing.assert_less(w[:-1], w[1:]) def test_density_weight(cosmo: Cosmology) -> None: @@ -75,7 +75,7 @@ def test_density_weight(cosmo: Cosmology) -> None: # check values are increasing - xpx_testing.assert_less(w[:-1], w[1:]) + xpx.testing.assert_less(w[:-1], w[1:]) def test_tophat_windows(xp: ModuleType) -> None: @@ -116,7 +116,7 @@ def test_linear_windows(xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.linear_windows(zgrid) - xpx_testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xpx.testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -124,7 +124,7 @@ def test_linear_windows(xp: ModuleType) -> None: # check values of zeff - xpx_testing.assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) + xpx.testing.assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) # check weight function input @@ -133,7 +133,7 @@ def test_linear_windows(xp: ModuleType) -> None: weight=lambda _: 0, ) for w in ws: - xpx_testing.assert_close(w.wa, xp.zeros_like(w.wa)) + xpx.testing.assert_close(w.wa, xp.zeros_like(w.wa)) # check error raised @@ -165,7 +165,7 @@ def test_cubic_windows(xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.cubic_windows(zgrid) - xpx_testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xpx.testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -173,7 +173,7 @@ def test_cubic_windows(xp: ModuleType) -> None: # check values of zeff - xpx_testing.assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) + xpx.testing.assert_close(xp.stack([w.zeff for w in ws]), zgrid[1:-1]) # check weight function input @@ -182,7 +182,7 @@ def test_cubic_windows(xp: ModuleType) -> None: weight=lambda _: 0, ) for w in ws: - xpx_testing.assert_close(w.wa, xp.zeros_like(w.wa)) + xpx.testing.assert_close(w.wa, xp.zeros_like(w.wa)) # check error raised @@ -275,7 +275,7 @@ def test_partition( assert part.shape == (len(shells), 3, 2) - xpx_testing.assert_close(xp.sum(part, axis=0), uxpx.trapezoid(fz, z)) + xpx.testing.assert_close(xp.sum(part, axis=0), uxpx.trapezoid(fz, z)) def test_redshift_grid_default_xp() -> None: @@ -358,7 +358,7 @@ def test_distance_grid(cosmo: Cosmology) -> None: # check decrease in distance x = glass.distance_grid(cosmo, zmin, zmax, dx=0.3) - xpx_testing.assert_less(x[1:], x[:-1]) + xpx.testing.assert_less(x[1:], x[:-1]) # check error raised @@ -411,10 +411,10 @@ def test_combine(xp: ModuleType) -> None: assert result.shape == z.shape # Check sum of result - xpx_testing.assert_close(xp.sum(result), xp.asarray(929.267284)) + xpx.testing.assert_close(xp.sum(result), xp.asarray(929.267284)) # Check integral w.r.t z has not changed - xpx_testing.assert_close(uxpx.trapezoid(result, z), xp.asarray(4.643139), rtol=1e-6) + xpx.testing.assert_close(uxpx.trapezoid(result, z), xp.asarray(4.643139), rtol=1e-6) def test_radial_window_immutable(xp: ModuleType) -> None: @@ -453,7 +453,7 @@ def test_radial_window_zeff_none(xp: ModuleType) -> None: w = glass.RadialWindow(za, wa) - xpx_testing.assert_close(w.zeff, xp.ones_like(w.zeff)) + xpx.testing.assert_close(w.zeff, xp.ones_like(w.zeff)) # check zeff is NaN when redshift array is empty From e61583e6b11abef22f4d1cb97958b46206d88ba5 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 11:08:19 +0100 Subject: [PATCH 32/43] More refining --- tests/core/test_points.py | 4 ++-- tests/core/test_shells.py | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/core/test_points.py b/tests/core/test_points.py index 3402fc3c..5e7fbe5d 100644 --- a/tests/core/test_points.py +++ b/tests/core/test_points.py @@ -305,8 +305,8 @@ def test_positions_from_delta( # noqa: PLR0915 ) assert int(count) == count - xpx.testing.assert_close(lon, xp.asarray([])) - xpx.testing.assert_close(lat, xp.asarray([])) + xpx.testing.assert_equal(lon, xp.asarray([])) + xpx.testing.assert_equal(lat, xp.asarray([])) # case: large delta diff --git a/tests/core/test_shells.py b/tests/core/test_shells.py index 9f738f31..29895915 100644 --- a/tests/core/test_shells.py +++ b/tests/core/test_shells.py @@ -102,7 +102,7 @@ def test_tophat_windows(xp: ModuleType) -> None: def test_linear_windows(xp: ModuleType) -> None: """Add unit tests for :func:`glass.linear_windows`.""" - dz = 1e-2 + dz = xp.asarray(1e-2) zgrid = xp.asarray( [ 0.0, @@ -116,7 +116,7 @@ def test_linear_windows(xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.linear_windows(zgrid) - xpx.testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xpx.testing.assert_close(dz, xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -151,7 +151,7 @@ def test_linear_windows(xp: ModuleType) -> None: def test_cubic_windows(xp: ModuleType) -> None: """Add unit tests for :func:`glass.cubic_windows`.""" - dz = 1e-2 + dz = xp.asarray(1e-2) zgrid = xp.asarray( [ 0.0, @@ -165,7 +165,7 @@ def test_cubic_windows(xp: ModuleType) -> None: # check spacing of redshift grid ws = glass.cubic_windows(zgrid) - xpx.testing.assert_close(xp.asarray(dz), xp.mean(xp.diff(ws[0].za)), atol=1e-2) + xpx.testing.assert_close(dz, xp.mean(xp.diff(ws[0].za)), atol=1e-2) # check number of windows @@ -453,7 +453,7 @@ def test_radial_window_zeff_none(xp: ModuleType) -> None: w = glass.RadialWindow(za, wa) - xpx.testing.assert_close(w.zeff, xp.ones_like(w.zeff)) + xpx.testing.assert_close(w.zeff, xp.asarray(1.0)) # check zeff is NaN when redshift array is empty From 2e742f9071439f32787c722f69c0c727cdc1066a Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 11:54:34 +0100 Subject: [PATCH 33/43] More shape ignoring --- tests/benchmarks/test_fields.py | 4 ++-- tests/benchmarks/test_lensing.py | 4 ++-- tests/core/test_lensing.py | 4 ++-- tests/core/test_shapes.py | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/benchmarks/test_fields.py b/tests/benchmarks/test_fields.py index ac6dfdd3..e22e1ed6 100644 --- a/tests/benchmarks/test_fields.py +++ b/tests/benchmarks/test_fields.py @@ -120,7 +120,7 @@ def function_to_benchmark() -> list[Any]: j, a, s = results[0] assert j is None assert a.shape == (0,) - xpx.testing.assert_close(s, xpb.ones_like(s)) + xpx.testing.assert_close(s, xpb.asarray(1.0)) @pytest.mark.stable @@ -150,7 +150,7 @@ def function_to_benchmark() -> list[Any]: xpx.testing.assert_close(cov[:, 0], xpb.asarray([1.0, 1.5, 2.0])) xpx.testing.assert_close(cov[:, 1], xpb.asarray([1.5, 2.0, 2.5])) - xpx.testing.assert_close(cov[:, 2], xpb.zeros_like(cov[:, 2])) + xpx.testing.assert_close(cov[:, 2], xpb.asarray(0.0),check_shape=False) @pytest.mark.stable diff --git a/tests/benchmarks/test_lensing.py b/tests/benchmarks/test_lensing.py index 27fc0f00..1684ae4d 100644 --- a/tests/benchmarks/test_lensing.py +++ b/tests/benchmarks/test_lensing.py @@ -39,7 +39,7 @@ def test_multi_plane_matrix( deltas = urngb.random((len(shells), 10)) xpx.testing.assert_equal(mat, xpb.tril(mat)) - xpx.testing.assert_equal(xpb.triu(mat, k=1), xpb.zeros_like(mat)) + xpx.testing.assert_equal(xpb.triu(mat, k=1), xpb.asarray(0.0), check_shape=False) def setup_shells_and_deltas() -> tuple[ tuple[ @@ -100,7 +100,7 @@ def test_multi_plane_weights( w_out = glass.multi_plane_weights(w_in, shells, cosmo) xpx.testing.assert_equal(w_out, xpb.triu(w_out, 1)) - xpx.testing.assert_equal(xpb.tril(w_out), xpb.zeros_like(w_out)) + xpx.testing.assert_equal(xpb.tril(w_out), xpb.asarray(0.0), check_shape=False) def setup_shells_deltas_and_weights() -> tuple[ tuple[ diff --git a/tests/core/test_lensing.py b/tests/core/test_lensing.py index 155d5a3a..63088a86 100644 --- a/tests/core/test_lensing.py +++ b/tests/core/test_lensing.py @@ -70,7 +70,7 @@ def test_multi_plane_matrix( mat = glass.multi_plane_matrix(shells, cosmo) xpx.testing.assert_equal(mat, xp.tril(mat)) - xpx.testing.assert_equal(xp.triu(mat, k=1), xp.zeros_like(mat)) + xpx.testing.assert_equal(xp.triu(mat, k=1), xp.asarray(0.0), check_shape=False) convergence = glass.MultiPlaneConvergence(cosmo) @@ -96,7 +96,7 @@ def test_multi_plane_weights( w_out = glass.multi_plane_weights(w_in, shells, cosmo) xpx.testing.assert_equal(w_out, xp.triu(w_out, k=1)) - xpx.testing.assert_equal(xp.tril(w_out), xp.zeros_like(w_out)) + xpx.testing.assert_equal(xp.tril(w_out), xp.asarray(0.0), check_shape=False) convergence = glass.MultiPlaneConvergence(cosmo) diff --git a/tests/core/test_shapes.py b/tests/core/test_shapes.py index f7c712f0..554cba2e 100644 --- a/tests/core/test_shapes.py +++ b/tests/core/test_shapes.py @@ -151,7 +151,7 @@ def test_ellipticity_gaussian( assert eps.shape == (n,) - xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.asarray(1.0), check_shape=False) xpx.testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) xpx.testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) @@ -160,7 +160,7 @@ def test_ellipticity_gaussian( assert eps.shape == (2 * n,) - xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.asarray(1.0), check_shape=False) xpx.testing.assert_close( xp.std(xp.real(eps)[:n]), @@ -212,7 +212,7 @@ def test_ellipticity_intnorm( assert eps.shape == (n,) - xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.asarray(1.0), check_shape=False) xpx.testing.assert_close(xp.std(xp.real(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) xpx.testing.assert_close(xp.std(xp.imag(eps)), xp.asarray(0.256), atol=1e-3, rtol=0) @@ -221,7 +221,7 @@ def test_ellipticity_intnorm( assert eps.shape == (2 * n,) - xpx.testing.assert_less(xp.abs(eps), xp.ones_like(eps, dtype=xp.float64)) + xpx.testing.assert_less(xp.abs(eps), xp.asarray(1.0), check_shape=False) xpx.testing.assert_close( xp.std(xp.real(eps)[:n]), From 85a3a43dfc5ab9fbfddbfb42501b6a2f33637d17 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 11:55:43 +0100 Subject: [PATCH 34/43] Format --- tests/benchmarks/test_fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/benchmarks/test_fields.py b/tests/benchmarks/test_fields.py index e22e1ed6..ef5042c6 100644 --- a/tests/benchmarks/test_fields.py +++ b/tests/benchmarks/test_fields.py @@ -150,7 +150,7 @@ def function_to_benchmark() -> list[Any]: xpx.testing.assert_close(cov[:, 0], xpb.asarray([1.0, 1.5, 2.0])) xpx.testing.assert_close(cov[:, 1], xpb.asarray([1.5, 2.0, 2.5])) - xpx.testing.assert_close(cov[:, 2], xpb.asarray(0.0),check_shape=False) + xpx.testing.assert_close(cov[:, 2], xpb.asarray(0.0), check_shape=False) @pytest.mark.stable From 860b8d731e95296212bf9bfa14d8f58069d6e563 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 12:02:31 +0100 Subject: [PATCH 35/43] Check shape False --- tests/core/test_lensing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_lensing.py b/tests/core/test_lensing.py index 63088a86..6ff56dbb 100644 --- a/tests/core/test_lensing.py +++ b/tests/core/test_lensing.py @@ -163,7 +163,7 @@ def alpha( alpha(0, -r, usecomplex=usecomplex), ) xpx.testing.assert_close(lon, xp.asarray([d, d]), atol=1e-15) - xpx.testing.assert_close(lat, xp.asarray([0.0, 0.0]), atol=1e-15) + xpx.testing.assert_close(lat, xp.asarray(0.0), atol=1e-15, check_shape=False) # No inputs are arrays and xp not provided with pytest.raises( From c022431eb035a080bf53d61630dd6392352f1faf Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 12:21:34 +0100 Subject: [PATCH 36/43] Explicitly broadcast --- tests/core/test_galaxies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_galaxies.py b/tests/core/test_galaxies.py index e086784b..6429ea89 100644 --- a/tests/core/test_galaxies.py +++ b/tests/core/test_galaxies.py @@ -281,7 +281,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - xpx.testing.assert_equal(z * xp.ones_like(phz), phz) + xpx.testing.assert_equal(xp.broadcast_to(1.0, phz.shape), phz) # case: array redshift, array sigma_0 From 0f3f38683c420ebd371396e1d3238206b633b2c8 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 12:28:29 +0100 Subject: [PATCH 37/43] Remove `3.10` from metadata --- pyproject.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f5097767..38b3c4d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,7 +59,6 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", @@ -96,7 +95,7 @@ optional-dependencies = {examples = [ "jupyter", "matplotlib", ]} -requires-python = ">=3.10" +requires-python = ">=3.11" [project.urls] Changelog = "https://glass.readthedocs.io/stable/manual/releases.html" From f8dd9c4d6f9e5e9d18e2f0de8c1b067edcb471df Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 12:28:42 +0100 Subject: [PATCH 38/43] Remove `3.10` from CI --- .github/workflows/test.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b91d3858..57b4ede9 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -87,7 +87,6 @@ jobs: strategy: matrix: python-version: - - "3.10" - "3.11" - "3.12" - "3.13" @@ -159,9 +158,9 @@ jobs: uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2 with: carryforward: - ${{ env.BENCH_COV_NAME }},${{ env.CORE_COV_NAME }}-3.10,${{ - env.CORE_COV_NAME }}-3.11,${{ env.CORE_COV_NAME }}-3.12,${{ - env.CORE_COV_NAME }}-3.13,${{ env.CORE_COV_NAME }}-3.14 + ${{ env.BENCH_COV_NAME }},${{ env.CORE_COV_NAME }}-3.11,${{ + env.CORE_COV_NAME }}-3.12,${{ env.CORE_COV_NAME }}-3.13,${{ + env.CORE_COV_NAME }}-3.14 parallel-finished: true build: From 964e8fc3be1af9f4dd3e0b7eb42957d9cb980133 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 12:28:52 +0100 Subject: [PATCH 39/43] Remove `3.10` from `nox` --- noxfile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 2d43fe79..a749ebbf 100644 --- a/noxfile.py +++ b/noxfile.py @@ -16,7 +16,6 @@ ] ALL_PYTHON = [ - "3.10", "3.11", "3.12", "3.13", From 49c0d61e4853d9673e23768cb6e6b733d380d44f Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 12:29:04 +0100 Subject: [PATCH 40/43] Update typing from `3.10` to `3.11` changes --- glass/arraytools.py | 4 +--- glass/jax.py | 3 ++- tests/benchmarks/test_lensing.py | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/glass/arraytools.py b/glass/arraytools.py index 903d8e44..49a27221 100644 --- a/glass/arraytools.py +++ b/glass/arraytools.py @@ -12,8 +12,6 @@ if TYPE_CHECKING: from types import ModuleType - from typing_extensions import Unpack - from glass._types import AnyArray, FloatArray, IntArray @@ -48,7 +46,7 @@ def broadcast_leading_axes( xp: ModuleType | None = None, ) -> tuple[ tuple[int, ...], - Unpack[tuple[FloatArray, ...]], + *tuple[FloatArray, ...], ]: """ Broadcast all but the last N axes. diff --git a/glass/jax.py b/glass/jax.py index 487721df..eab52e58 100644 --- a/glass/jax.py +++ b/glass/jax.py @@ -13,8 +13,9 @@ import jax.typing if TYPE_CHECKING: + from typing import Self + from jaxtyping import PRNGKeyArray - from typing_extensions import Self from glass._types import AnyArray, DTypeLike, FloatArray, IntArray diff --git a/tests/benchmarks/test_lensing.py b/tests/benchmarks/test_lensing.py index d220dd71..94e242f5 100644 --- a/tests/benchmarks/test_lensing.py +++ b/tests/benchmarks/test_lensing.py @@ -8,9 +8,9 @@ if TYPE_CHECKING: from types import ModuleType + from typing import Never from pytest_benchmark.fixture import BenchmarkFixture - from typing_extensions import Never from glass._types import FloatArray, UnifiedGenerator from glass.cosmology import Cosmology From 9f33d223afb07d77593117da95d1aee1f8e2f2ba Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 12:39:49 +0100 Subject: [PATCH 41/43] Fix tests --- tests/core/test_galaxies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_galaxies.py b/tests/core/test_galaxies.py index 6429ea89..9e108864 100644 --- a/tests/core/test_galaxies.py +++ b/tests/core/test_galaxies.py @@ -281,7 +281,7 @@ def test_gaussian_phz( assert phz.__array_namespace__() == xp assert phz.shape == (10,) - xpx.testing.assert_equal(xp.broadcast_to(1.0, phz.shape), phz) + xpx.testing.assert_equal(xp.broadcast_to(xp.asarray(1.0), phz.shape), phz) # case: array redshift, array sigma_0 From 872bb36bfef8e3bda7fd79f8ec8206938c2f92eb Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 12:49:58 +0100 Subject: [PATCH 42/43] Suppress linting errors --- glass/algorithm.py | 2 +- glass/fields.py | 6 +++--- glass/galaxies.py | 2 +- glass/lensing.py | 2 +- glass/points.py | 3 +-- glass/shapes.py | 4 ++-- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/glass/algorithm.py b/glass/algorithm.py index aa7b4fbe..cac245d0 100644 --- a/glass/algorithm.py +++ b/glass/algorithm.py @@ -99,7 +99,7 @@ def nnls( q = xpx.at(q)[x <= 0].set(False) x = xpx.at(x)[q].set(sq) x = xpx.at(x)[~q].set(0) - return x + return x # ty: ignore[invalid-return-type] def cov_clip( diff --git a/glass/fields.py b/glass/fields.py index 6a3cc626..3a561937 100644 --- a/glass/fields.py +++ b/glass/fields.py @@ -226,7 +226,7 @@ def cls2cov( cov = xpx.at(cov)[:n, i].set(cl) cov = xpx.at(cov)[n:, i].set(0.0) cov /= 2 - yield cov + yield cov # ty: ignore[invalid-yield] def discretized_cls( @@ -685,7 +685,7 @@ def effective_cls( out = xpx.at(out)[j1 + j2 + (...,)].set(cl) if weights2 is weights1 and j1 != j2: out = xpx.at(out)[j2 + j1 + (...,)].set(cl) - return out + return out # ty: ignore[invalid-return-type] def gaussian_fields( @@ -1023,7 +1023,7 @@ def cov_from_spectra( cov = xpx.at(cov)[:size, i, j].set(cl_flat[:size]) cov = xpx.at(cov)[:size, j, i].set(cl_flat[:size]) - return cov + return cov # ty: ignore[invalid-return-type] def check_posdef_spectra(spectra: AngularPowerSpectra) -> bool: diff --git a/glass/galaxies.py b/glass/galaxies.py index a36f1ee4..63f85540 100644 --- a/glass/galaxies.py +++ b/glass/galaxies.py @@ -154,7 +154,7 @@ def redshifts_from_nz( assert total == redshifts.size # noqa: S101 - return redshifts + return redshifts # ty: ignore[invalid-return-type] def galaxy_shear( # noqa: PLR0913 diff --git a/glass/lensing.py b/glass/lensing.py index 1ff198bc..aa21d31f 100644 --- a/glass/lensing.py +++ b/glass/lensing.py @@ -625,7 +625,7 @@ def multi_plane_matrix( for i, w in enumerate(shells): mpc.add_window(xp.asarray(wmat[i, :], copy=True), w) wmat = xpx.at(wmat)[i, :].set(mpc.kappa) - return wmat + return wmat # ty: ignore[invalid-return-type] def multi_plane_weights( diff --git a/glass/points.py b/glass/points.py index 39097c48..999a0d04 100644 --- a/glass/points.py +++ b/glass/points.py @@ -598,14 +598,13 @@ def uniform_positions( lat = uxpx.degrees(xp.asin(rng.uniform(-1, 1, size=size))) # report count - count: int | IntArray if dims: count = xp.zeros(dims, dtype=xp.int64) count = xpx.at(count)[k].set(ngal_sphere[k]) else: count = int(ngal_sphere[k]) - yield lon, lat, count + yield lon, lat, count # ty: ignore[invalid-yield] def position_weights( diff --git a/glass/shapes.py b/glass/shapes.py index eabfd694..dec0ad11 100644 --- a/glass/shapes.py +++ b/glass/shapes.py @@ -282,7 +282,7 @@ def ellipticity_gaussian( eps = xpx.at(eps)[i : i + count_broadcasted[k]].set(e) i += count_broadcasted[k] - return eps + return eps # ty: ignore[invalid-return-type] def ellipticity_intnorm( @@ -361,4 +361,4 @@ def ellipticity_intnorm( eps = xpx.at(eps)[i : i + count_broadcasted[k]].set(e) i += count_broadcasted[k] - return eps + return eps # ty: ignore[invalid-return-type] From 7064641a10816ebbe9633f9c2cfdd4844cb058c8 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 29 May 2026 12:51:10 +0100 Subject: [PATCH 43/43] Remove `array-api-extra` hash --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3c8bc3d1..fc3a77ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,6 @@ lint = [ "ty==0.0.35", ] test = [ - "array-api-extra @ git+https://github.com/data-apis/array-api-extra.git", "cosmology-api", "fitsio", "pytest",