From b883f485b24fa1206f23a84a7d4c920bd219fc40 Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Thu, 28 Nov 2024 14:43:07 +0000 Subject: [PATCH] gh-440: remove scipy as a test dependency --- .github/test-constraints.txt | 3 --- pyproject.toml | 1 - tests/core/test_algorithm.py | 38 +++++++++++++++---------------- tests/core/test_array.py | 44 +++++++++++++++--------------------- 4 files changed, 37 insertions(+), 49 deletions(-) diff --git a/.github/test-constraints.txt b/.github/test-constraints.txt index 5d050c40..d3c772ec 100644 --- a/.github/test-constraints.txt +++ b/.github/test-constraints.txt @@ -1,9 +1,6 @@ numpy --only-binary numpy -scipy ---only-binary scipy - healpy --only-binary healpy diff --git a/pyproject.toml b/pyproject.toml index 5265e963..3c292882 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,7 +61,6 @@ test = [ "pytest-doctestplus", "pytest-mock", "pytest-rerunfailures", - "scipy", ] [project.urls] diff --git a/tests/core/test_algorithm.py b/tests/core/test_algorithm.py index fa1badf9..8e6dcc68 100644 --- a/tests/core/test_algorithm.py +++ b/tests/core/test_algorithm.py @@ -1,33 +1,33 @@ -import importlib.util - import numpy as np import pytest -from glass.core.algorithm import nnls as nnls_glass - -# check if scipy is available for testing -HAVE_SCIPY = importlib.util.find_spec("scipy") is not None +from glass.core.algorithm import nnls -@pytest.mark.skipif(not HAVE_SCIPY, reason="test requires SciPy") def test_nnls(rng: np.random.Generator) -> None: - from scipy.optimize import nnls as nnls_scipy - - # cross-check output with scipy's nnls + # check output - a = rng.standard_normal((100, 20)) - b = rng.standard_normal((100,)) + a = np.arange(25.0).reshape(-1, 5) + b = np.arange(5.0) + y = a @ b + res = nnls(a, y) + assert np.linalg.norm((a @ res) - y) < 1e-7 - x_glass = nnls_glass(a, b) - x_scipy, _ = nnls_scipy(a, b) - - np.testing.assert_allclose(x_glass, x_scipy) + a = rng.uniform(low=-10, high=10, size=[50, 10]) + b = np.abs(rng.uniform(low=-2, high=2, size=[10])) + b[::2] = 0 + x = a @ b + res = nnls(a, x, tol=500 * np.linalg.norm(a, 1) * np.spacing(1.0)) + np.testing.assert_allclose(res, b, rtol=0.0, atol=1e-10) # check matrix and vector's shape + a = rng.standard_normal((100, 20)) + b = rng.standard_normal((100,)) + with pytest.raises(ValueError, match="input `a` is not a matrix"): - nnls_glass(b, a) + nnls(b, a) with pytest.raises(ValueError, match="input `b` is not a vector"): - nnls_glass(a, a) + nnls(a, a) with pytest.raises(ValueError, match="the shapes of `a` and `b` do not match"): - nnls_glass(a.T, b) + nnls(a.T, b) diff --git a/tests/core/test_array.py b/tests/core/test_array.py index 4dd5973c..23b01409 100644 --- a/tests/core/test_array.py +++ b/tests/core/test_array.py @@ -1,5 +1,3 @@ -import importlib.util - import numpy as np import numpy.typing as npt import pytest @@ -12,9 +10,6 @@ trapezoid_product, ) -# check if scipy is available for testing -HAVE_SCIPY = importlib.util.find_spec("scipy") is not None - def test_broadcast_first() -> None: a = np.ones((2, 3, 4)) @@ -156,50 +151,47 @@ def test_trapezoid_product() -> None: np.testing.assert_allclose(s, 1.0) -@pytest.mark.skipif(not HAVE_SCIPY, reason="test requires SciPy") def test_cumulative_trapezoid() -> None: - import scipy.integrate as spi - # 1D f and x f = np.array([1, 2, 3, 4]) x = np.array([0, 1, 2, 3]) - # default dtype (int - not supported by scipy) + # default dtype (int) - glass_ct = cumulative_trapezoid(f, x) - np.testing.assert_allclose(glass_ct, np.array([0, 1, 4, 7])) + ct = cumulative_trapezoid(f, x) + np.testing.assert_allclose(ct, np.array([0, 1, 4, 7])) # explicit dtype (float) - glass_ct = cumulative_trapezoid(f, x, dtype=float) - scipy_ct = spi.cumulative_trapezoid(f, x, initial=0) - np.testing.assert_allclose(glass_ct, scipy_ct) + ct = cumulative_trapezoid(f, x, dtype=float) + np.testing.assert_allclose(ct, np.array([0.0, 1.5, 4.0, 7.5])) # explicit return array - result = cumulative_trapezoid(f, x, dtype=float, out=np.zeros((4,))) - scipy_ct = spi.cumulative_trapezoid(f, x, initial=0) - np.testing.assert_allclose(result, scipy_ct) + out = np.zeros((4,)) + ct = cumulative_trapezoid(f, x, dtype=float, out=out) + np.testing.assert_equal(ct, out) # 2D f and 1D x f = np.array([[1, 4, 9, 16], [2, 3, 5, 7]]) x = np.array([0, 1, 2.5, 4]) - # default dtype (int - not supported by scipy) + # default dtype (int) - glass_ct = cumulative_trapezoid(f, x) - np.testing.assert_allclose(glass_ct, np.array([[0, 2, 12, 31], [0, 2, 8, 17]])) + ct = cumulative_trapezoid(f, x) + np.testing.assert_allclose(ct, np.array([[0, 2, 12, 31], [0, 2, 8, 17]])) # explicit dtype (float) - glass_ct = cumulative_trapezoid(f, x, dtype=float) - scipy_ct = spi.cumulative_trapezoid(f, x, initial=0) - np.testing.assert_allclose(glass_ct, scipy_ct) + ct = cumulative_trapezoid(f, x, dtype=float) + np.testing.assert_allclose( + ct, np.array([[0.0, 2.5, 12.25, 31.0], [0.0, 2.5, 8.5, 17.5]]) + ) # explicit return array - glass_ct = cumulative_trapezoid(f, x, dtype=float, out=np.zeros((2, 4))) - scipy_ct = spi.cumulative_trapezoid(f, x, initial=0) - np.testing.assert_allclose(glass_ct, scipy_ct) + out = np.zeros((2, 4)) + ct = cumulative_trapezoid(f, x, dtype=float, out=out) + np.testing.assert_equal(ct, out)