Skip to content
Open
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
4 changes: 3 additions & 1 deletion diff_diff/linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ def _detect_rank_deficiency(
pivot : ndarray of int
Column permutation from QR decomposition.
"""
n, k = X.shape
_, k = X.shape
if k == 0:
return 0, np.array([], dtype=int), np.array([], dtype=int)

# R's qr() uses tol = 1e-07 by default (sqrt(eps) ≈ 1.49e-08); we use 1e-07.
if rcond is None:
Expand Down
14 changes: 14 additions & 0 deletions tests/test_linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,20 @@ def test_solve_ols_rank_zero_returns_nan_not_indexerror(self):
np.testing.assert_allclose(resid, y) # fitted = 0
assert vcov.shape == (3, 3) and np.all(np.isnan(vcov))

def test_rank_detection_zero_column_matrix_returns_empty_contract(self):
"""An ``(n, 0)`` design has rank 0, no dropped columns, and no pivot."""
from diff_diff.linalg import _detect_rank_deficiency

X = np.empty((5, 0))

rank, dropped, pivot = _detect_rank_deficiency(X)

assert rank == 0
assert dropped.dtype == int
assert pivot.dtype == int
assert dropped.shape == (0,)
assert pivot.shape == (0,)

def test_rank_detection_scale_repair_preserves_raw_drop_selection(self):
"""The scale-invariance repair must NOT change which column is dropped in a
genuinely collinear, well-scaled design: the dropped column equals the raw
Expand Down
Loading