inverse of a singular matrix over RR or CC returns the zero matrix instead of erroring
Nobody has claimed this yet.
- Dominant language
- Macaulay2
- Stars
- 435
- Forks
- 297
- Avg merge
- 4d 20h
- Merged PRs (30d)
- 11
Description
> **Written by Claude** (Claude Opus 5, via Claude Code), not by @d-torrance, and filed under his account. He reviewed it and agrees it is a bug, but the investigation, the wording and the reading of the engine source below are the model's. Please weigh it accordingly, and treat the suggested fix as a starting point rather than a conclusion.
Over an inexact field, `inverse` on a square matrix of less than full rank returns a matrix of zeros instead of raising `matrix not invertible`.
```m2
i1 : inverse matrix {{1., 2.}, {2., 4.}}
o1 = 0
2 2
o1 : Matrix RR <-- RR
53 53
i2 : inverse matrix {{1_QQ, 2}, {2, 4}}
stdio:2:7:(3):[1]: error: matrix not invertible
```
Everything else that looks at the same matrix gets it right — only `inverse` reports success:
```m2
i3 : m = matrix{{1.,2.},{2.,4.}};
i4 : (rank m, det m)
o4 = (1, -0)
i5 : solve(m, id_(RR^2)) === null
o5 = true
```
`^-1` behaves the same, as does any rank deficit, and the wrong answer propagates rather than surfacing:
```m2
i6 : a = matrix{{1.,2.,3.},{2.,4.,6.},{1.,1.,1.}}; -- rank 2 of 3
i7 : a * inverse a
o7 = 0
3 3
o7 : Matrix RR <-- RR
53 53
```
Reproduced on 1.26.06 at `RR_53`, `CC_53` and `RR_200`, and on `CC` matrices whose singularity involves the imaginary parts. It is not a tolerance question: `matrix{{1.,2.},{2.,4.0000001}}` has determinant `1e-7` and inverts correctly, so exact rank deficiency is what trips it.
### Scope
Inexact fields only. `ZZ/5` and `ZZ/32003` raise `matrix not invertible`, through the `inverse` specializations in `dmat-lu-zzp-ffpack.hpp` and `dmat-lu-zzp-flint.hpp` that do return their invertibility result. `ZZ` and `QQ` raise it from the non-engine branch at `M2/Macaulay2/m2/matrix1.m2:629`.
### Cause
`matrix1.m2:626` sends every `InexactField` to `basicInverse` → `rawLinAlgInverse` → the generic `DMatLinAlg::inverse`, which ends:
https://github.com/Macaulay2/M2/blob/79c7ac4fc5d4de37a18aae03ac9eb8c0db1e3c7b/M2/Macaulay2/e/basic-mutable-matrices/dmat-lu.hpp#L529-L542
```cpp
solve(id, X);
return true;
```
`solve` returns `false` for an inconsistent system (`dmat-lu.hpp:379`) and that value is discarded. `rawLinAlgInverse` already checks for a null result and would raise `matrix not invertible` if it ever received one, so the fix appears to be `return solve(id, X);`.
### Relation to existing issues
This is the part of #2208 that was never fixed. That issue reported the same thing on `ZZ/5` and was closed by #2241 (a032f77d13), which changed element-level inversion in `ZZp.cpp`, `aring-zzp*.hpp`, `aring-gf-flint.hpp` and `ZZ.cpp` — the exact rings — and did not touch `dmat-lu.hpp`, so the generic path used by the inexact fields kept the hole.
Distinct from #4506, which is a non-square matrix over `ZZ` on the non-engine branch with no squareness check, and from #3738, which concerns `inverse` of a map of non-free modules.
Found while triaging `bugs/dan/1-CC-inverse` for #36, which asks that the removed `bugs/` directory be gone through. The bug file itself asks for LU via LAPACK over `RR` and `CC`, and that part works — this turned up in checking that it also fails correctly. The transcripts above are from an actual 1.26.06 session; the claim that the zeros are unintended rather than a deliberate convention for inexact fields is not verified — no commit, comment or test asserting either way was found.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the RR and CC examples from the issue, then read M2/Macaulay2/m2/matrix1.m2:626-629 and the generic inverse implementation in M2/Macaulay2/e/basic-mutable-matrices/dmat-lu.hpp:529-542, including solve near line 379. Confirm that singular inexact matrices raise “matrix not invertible” while nonsingular cases and the cited exact-field paths retain their behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100