import numpy as np from numpy.testing import assert_allclose from pytest import raises as assert_raises from scipy.optimize import nnls class TestNNLS: def setup_method(self): self.rng = np.random.default_rng(1685225766635251) def test_nnls(self): a = np.arange(25.0).reshape(-1, 5) x = np.arange(5.0) y = a @ x x, res = nnls(a, y) assert res < 1e-7 assert np.linalg.norm((a @ x) - y) < 1e-7 def test_nnls_tall(self): a = self.rng.uniform(low=-10, high=10, size=[50, 10]) x = np.abs(self.rng.uniform(low=-2, high=2, size=[10])) x[::2] = 0 b = a @ x xact, rnorm = nnls(a, b, atol=500*np.linalg.norm(a, 1)*np.spacing(1.)) assert_allclose(xact, x, rtol=0., atol=1e-10) assert rnorm < 1e-12 def test_nnls_wide(self): # If too wide then problem becomes too ill-conditioned ans starts # emitting warnings, hence small m, n difference. a = self.rng.uniform(low=-10, high=10, size=[100, 120]) x = np.abs(self.rng.uniform(low=-2, high=2, size=[120])) x[::2] = 0 b = a @ x xact, rnorm = nnls(a, b, atol=500*np.linalg.norm(a, 1)*np.spacing(1.)) assert_allclose(xact, x, rtol=0., atol=1e-10) assert rnorm < 1e-12 def test_maxiter(self): # test that maxiter argument does stop iterations a = self.rng.uniform(size=(5, 10)) b = self.rng.uniform(size=5) with assert_raises(RuntimeError): nnls(a, b, maxiter=1)