Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ This release is compatible with NumPy 2.5.
* Added the `ndmax` keyword to `dpnp.array` for compatibility with NumPy [#3044](https://github.com/IntelPython/dpnp/pull/3044)
* Added `UsmNDArray_RemoveQueueRef` C API function to release a queue reference obtained from `UsmNDArray_GetQueueRef` [#3042](https://github.com/IntelPython/dpnp/pull/3042)
* Added a `rattler-build`-compatible conda recipe (`conda-recipe/rattler_recipe.yaml`) alongside the existing `conda-build` recipe [#3031](https://github.com/IntelPython/dpnp/pull/3031)
* Added support for the `"nuc"` (nuclear) norm in `dpnp.linalg.cond` [#3084](https://github.com/IntelPython/dpnp/pull/3084)

### Changed

Expand Down
14 changes: 9 additions & 5 deletions dpnp/linalg/dpnp_iface_linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,15 @@ def cond(x, p=None):
----------
x : {dpnp.ndarray, usm_ndarray}
The matrix whose condition number is sought.
p : {None, 1, -1, 2, -2, inf, -inf, "fro"}, optional
p : {None, 1, -1, 2, -2, inf, -inf, "fro", "nuc"}, optional
Order of the norm used in the condition number computation:

===== ============================
p norm for matrices
===== ============================
None 2-norm
'fro' Frobenius norm
'nuc' nuclear norm
inf max(sum(abs(x), axis=1))
-inf min(sum(abs(x), axis=1))
1 max(sum(abs(x), axis=0))
Expand All @@ -188,7 +189,8 @@ def cond(x, p=None):
===== ============================

``inf`` means the :obj:`dpnp.inf` object, and the Frobenius norm is
the root-of-sum-of-squares norm.
the root-of-sum-of-squares norm. The nuclear norm is the sum of the
singular values.

Default: ``None``.

Expand All @@ -204,9 +206,9 @@ def cond(x, p=None):
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 any of the norm: ``1``, ``-1``, ``inf``, ``-inf``, ``'fro'``, or
``'nuc'``. 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
Expand All @@ -221,6 +223,8 @@ def cond(x, p=None):
array(1.41421356)
>>> np.linalg.cond(a, 'fro')
array(3.16227766)
>>> np.linalg.cond(a, 'nuc')
array(9.24264069)
>>> np.linalg.cond(a, np.inf)
array(2.)
>>> np.linalg.cond(a, -np.inf)
Expand Down
4 changes: 2 additions & 2 deletions dpnp/tests/test_linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def test_cholesky_errors(self):


class TestCond:
_norms = [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro"]
_norms = [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro", "nuc"]

@pytest.mark.parametrize(
"shape", [(0, 4, 4), (4, 0, 3, 3)], ids=["(0, 4, 4)", "(4, 0, 3, 3)"]
Expand Down Expand Up @@ -325,7 +325,7 @@ def test_nan_to_inf(self, p):
# 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'
# DPNP raises LinAlgError for 1, -1, inf, -inf, 'fro', and 'nuc'
# due to use of gesv in the 2D case.
# For [None, 2, -2], DPNP does not raise.
if p in [None, 2, -2]:
Expand Down
2 changes: 1 addition & 1 deletion dpnp/tests/test_sycl_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -1619,7 +1619,7 @@ def test_cholesky(self, data, is_empty, device):
assert_sycl_queue_equal(result.sycl_queue, x.sycl_queue)

@pytest.mark.parametrize(
"p", [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro"]
"p", [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro", "nuc"]
)
def test_cond(self, device, p):
a = generate_random_numpy_array((2, 4, 4))
Expand Down
2 changes: 1 addition & 1 deletion dpnp/tests/test_usm_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -1447,7 +1447,7 @@ def test_cholesky(self, data, is_empty, usm_type):
assert x.usm_type == result.usm_type

@pytest.mark.parametrize(
"p", [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro"]
"p", [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro", "nuc"]
)
def test_cond(self, usm_type, p):
a = generate_random_numpy_array((2, 4, 4), seed_value=42)
Expand Down
Loading