Coverage for src/cvx/linalg/solve/det.py: 100%
16 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-01 07:23 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-01 07:23 +0000
1"""Matrix determinant with NaN-aware submatrix handling."""
3from __future__ import annotations
5import numpy as np
7from ..core.condition import DEFAULT_COND_THRESHOLD
8from ..core.condition import check_and_warn_condition as _check_and_warn_condition
9from ..core.exceptions import NonSquareMatrixError
10from ..core.types import Matrix
11from ..core.valid import valid
13_SENTINEL = float("nan")
16def det(
17 matrix: Matrix,
18 cond_threshold: float | None = DEFAULT_COND_THRESHOLD,
19) -> float:
20 """Return the determinant of a square matrix.
22 Rows and columns with non-finite diagonal entries are excluded before the
23 computation; when no valid rows or columns remain the function returns
24 ``nan``. When the condition number of the valid sub-matrix exceeds
25 *cond_threshold*, an ``IllConditionedMatrixWarning`` is emitted.
27 Args:
28 matrix: Square input matrix.
29 cond_threshold: Condition-number threshold above which a warning is
30 emitted. Defaults to ``1e12``. ``None`` skips the check, and the
31 SVD that computes the condition number, entirely.
33 Returns:
34 The determinant of the valid sub-matrix, or ``nan`` when no valid
35 entries exist.
37 Raises:
38 NonSquareMatrixError: If the matrix is not square.
40 Example:
41 >>> import numpy as np
42 >>> from cvx.linalg import det
43 >>> det(np.eye(3))
44 1.0
46 NaN-masked entries are skipped:
48 >>> matrix = np.array([[2.0, 0.0], [0.0, np.nan]])
49 >>> det(matrix)
50 2.0
51 """
52 if matrix.shape[0] != matrix.shape[1]:
53 raise NonSquareMatrixError(matrix.shape[0], matrix.shape[1])
55 mask, submatrix = valid(matrix)
57 if not mask.any():
58 return _SENTINEL
60 _check_and_warn_condition(submatrix, cond_threshold)
61 return float(np.linalg.det(submatrix))