diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e67cdefd556..83abf35bea2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ This release achieves 100% compliance with Python Array API specification (revis * Updated FFT module to ensure an input array is Hermitian before calling complex-to-real FFT [#2444](https://github.com/IntelPython/dpnp/pull/2444) * Aligned `black` configuration with the list of supported python versions [#2457](https://github.com/IntelPython/dpnp/pull/2457) * Use `pyproject.toml` instead of `setup.py` aligning with current packaging best practices [#2462](https://github.com/IntelPython/dpnp/pull/2462) +* Added a clarification to `dpnp.linalg.cond` docstring about its behavior with singular matrices [#2500] (https://github.com/IntelPython/dpnp/pull/2500) ### Fixed diff --git a/dpnp/linalg/dpnp_iface_linalg.py b/dpnp/linalg/dpnp_iface_linalg.py index 904d935ebb72..137eed98d067 100644 --- a/dpnp/linalg/dpnp_iface_linalg.py +++ b/dpnp/linalg/dpnp_iface_linalg.py @@ -195,6 +195,14 @@ def cond(x, p=None): -------- :obj:`dpnp.linalg.norm` : Matrix or vector norm. + Notes + ----- + This function will raise :class:`dpnp.linalg.LinAlgError` on singular input + when using any of the norm: ``1``, ``-1``, ``inf``, ``-inf``, or ``'fro'``. + In contrast, :obj:`numpy.linalg.cond` will fill the result array with + ``inf`` values for each 2D batch in the input array that is singular + when using these norms. + Examples -------- >>> import dpnp as np diff --git a/dpnp/tests/test_linalg.py b/dpnp/tests/test_linalg.py index 65cd3bbc70d1..2f567f7a9e5c 100644 --- a/dpnp/tests/test_linalg.py +++ b/dpnp/tests/test_linalg.py @@ -326,29 +326,22 @@ def test_bool(self, p): @pytest.mark.parametrize( "p", [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro"] ) - def test_nan(self, p): - # dpnp.linalg.cond uses dpnp.linalg.inv() - # for the case when p is not None or p != -2 or p != 2 - # For singular matrices cuSolver raises an error - # while OneMKL returns nans - if is_cuda_device() and p in [-dpnp.inf, -1, 1, dpnp.inf, "fro"]: - pytest.skip("Different behavior on CUDA") - elif requires_intel_mkl_version("2025.2") and p in [ - -dpnp.inf, - -1, - 1, - dpnp.inf, - "fro", - ]: - pytest.skip("SAT-7966") - a = generate_random_numpy_array((2, 2, 2, 2)) - a[0, 0] = 0 - a[1, 1] = 0 + def test_nan_to_inf(self, p): + a = numpy.zeros((2, 2)) ia = dpnp.array(a) - result = dpnp.linalg.cond(ia, p=p) - expected = numpy.linalg.cond(a, p=p) - assert_dtype_allclose(result, expected) + # NumPy does not raise LinAlgError on singular matrices. + # It returns `inf`, `0`, or large/small finite values + # depending on the norm and the matrix content. + # DPNP raises LinAlgError for 1, -1, inf, -inf, and 'fro' + # due to use of gesv in the 2D case. + # For [None, 2, -2], DPNP does not raise. + if p in [None, 2, -2]: + result = dpnp.linalg.cond(ia, p=p) + expected = numpy.linalg.cond(a, p=p) + assert_dtype_allclose(result, expected) + else: + assert_raises(dpnp.linalg.LinAlgError, dpnp.linalg.cond, ia, p=p) @pytest.mark.parametrize( "p", [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro"]