Skip to content

Commit 05fcca8

Browse files
author
peng.li24
committed
fix(linalg.inv): zero output on failure to prevent silent data corruption
When blas_ops::inv returns false (LAPACK unavailable or singular), the output buffer previously held the unmodified copy of A — which callers could mistake for a valid inverse. Now zeros the output on failure so the caller sees unambiguous garbage rather than the original matrix disguised as the inverse. Callers MUST check the return value. The pybind11 wrapper already throws std::runtime_error on failure.
1 parent 64f66ad commit 05fcca8

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

numpycpp/linalg.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,17 @@ inline void norm_axis(const T* src, T* dst,
9999
/// numpy.linalg.inv(a) — matrix inverse (square N×N)
100100
/// Uses DGESV (bitexact) or Gauss-Jordan (std backend).
101101
/// Returns true on success; false if matrix is singular or LAPACK unavailable.
102+
/// On failure, A_inv is zeroed (caller MUST check the return value).
102103
template<typename T>
103104
inline bool inv(const T* A, T* A_inv, size_t N) {
104-
// Copy input to output buffer (inv modifies in-place)
105+
// Copy input to output buffer (blas_ops::inv modifies in-place)
105106
for (size_t i = 0; i < N * N; ++i) A_inv[i] = A[i];
106107
bool ok = numpy::detail::blas_ops<T>::inv(A_inv, N);
108+
if (!ok) {
109+
// Zero output on failure — prevents the caller from reading
110+
// the unmodified copy of A as if it were the inverse.
111+
for (size_t i = 0; i < N * N; ++i) A_inv[i] = T(0);
112+
}
107113
return ok;
108114
}
109115

0 commit comments

Comments
 (0)