Problem
_detect_rank_deficiency() currently assumes the QR diagonal has at least one entry. For a design matrix with shape (n, 0), pivoted QR returns an empty diagonal and the helper indexes r_diag[0], raising an IndexError.
That leaves the helper without an explicit contract for a valid but empty design matrix.
Proposed behaviour
Treat an (n, 0) design as:
- rank
0;
- no dropped columns;
- empty pivot array.
This matches the mathematical rank of an empty-column matrix and avoids forcing callers to special-case a design that has no columns to drop.
Proposed scope
- Add a direct regression test for
_detect_rank_deficiency(np.empty((n, 0))).
- Add a small early return for
k == 0 before pivoted QR.
- Avoid broader rank-deficiency, OLS, or estimator behaviour changes.
Validation
PYTHONPATH=. DIFF_DIFF_BACKEND=python pytest tests/test_linalg.py::TestNumericalStability::test_rank_detection_zero_column_matrix_returns_empty_contract -q
PYTHONPATH=. DIFF_DIFF_BACKEND=python pytest tests/test_linalg.py::TestNumericalStability -q
PYTHONPATH=. DIFF_DIFF_BACKEND=python pytest tests/test_linalg.py -q
PYTHONPATH=. DIFF_DIFF_BACKEND=python .venv-py39/bin/python -m pytest tests/test_linalg.py::TestNumericalStability::test_rank_detection_zero_column_matrix_returns_empty_contract -q
git diff --check
Problem
_detect_rank_deficiency()currently assumes the QR diagonal has at least one entry. For a design matrix with shape(n, 0), pivoted QR returns an empty diagonal and the helper indexesr_diag[0], raising anIndexError.That leaves the helper without an explicit contract for a valid but empty design matrix.
Proposed behaviour
Treat an
(n, 0)design as:0;This matches the mathematical rank of an empty-column matrix and avoids forcing callers to special-case a design that has no columns to drop.
Proposed scope
_detect_rank_deficiency(np.empty((n, 0))).k == 0before pivoted QR.Validation
PYTHONPATH=. DIFF_DIFF_BACKEND=python pytest tests/test_linalg.py::TestNumericalStability::test_rank_detection_zero_column_matrix_returns_empty_contract -qPYTHONPATH=. DIFF_DIFF_BACKEND=python pytest tests/test_linalg.py::TestNumericalStability -qPYTHONPATH=. DIFF_DIFF_BACKEND=python pytest tests/test_linalg.py -qPYTHONPATH=. DIFF_DIFF_BACKEND=python .venv-py39/bin/python -m pytest tests/test_linalg.py::TestNumericalStability::test_rank_detection_zero_column_matrix_returns_empty_contract -qgit diff --check