mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-08-17 21:50:35 +00:00
docs: AdjugateMatrix det_self_inverse — Q16_16 obstruction documented
The exact det_self_inverse theorem is NOT provable over saturating Q16_16 due to integer truncation in div/mul. Documented with concrete counterexample (diag(3,1,...,1) gives 1 LSB error). Proven base case: det_self_inverse_identity (identity matrix, native_decide). The exact version requires either: (a) Bounded-error variant (each entry within 1 LSB of I) (b) Precondition: det divides all cofactor products exactly (c) Proof over ℚ via Mathlib matrix library
This commit is contained in:
parent
c7db0e66a5
commit
88b944aace
1 changed files with 86 additions and 5 deletions
|
|
@ -232,19 +232,90 @@ def cayleyTransform (skew : Matrix8) : Option Matrix8 :=
|
||||||
| some inv => some (matrixMultiply iMinusA inv)
|
| some inv => some (matrixMultiply iMinusA inv)
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════════════════════
|
-- ═══════════════════════════════════════════════════════════════════════════
|
||||||
-- §9 Theorems (stubs — proofs deferred to TODO(lean-port))
|
-- §9 Theorems
|
||||||
-- ═══════════════════════════════════════════════════════════════════════════
|
-- ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
/-- If matrixInverse returns `some inv`, then `m × inv = I`.
|
/-- If matrixInverse returns `some inv`, then `m × inv = I`.
|
||||||
TODO(lean-port): Prove from the algebraic identity A·adj(A) = det(A)·I
|
|
||||||
and the cancellation det(A) ≠ 0 → A·(adj(A)/det(A)) = I.
|
MATHEMATICAL PROOF SKETCH (exact arithmetic over a field F):
|
||||||
The fixed-point saturation complicates the proof; a bounded-error
|
|
||||||
version may be more tractable. -/
|
1. From `h`, extract `d := det8 m ≠ 0`.
|
||||||
|
2. By definition of `matrixInverse` and `adjugate`,
|
||||||
|
`inv[i][j] = cofactor8 m j i / d` (note the transpose: adj = cof^T).
|
||||||
|
3. The Laplace cofactor identity gives:
|
||||||
|
Σ_k m[i][k] · cofactor8 m j k = det8 m · δ(i,j)
|
||||||
|
This holds because:
|
||||||
|
- When i = j, the left side is exactly the cofactor expansion of
|
||||||
|
det8 m along row i.
|
||||||
|
- When i ≠ j, the left side is the determinant of a matrix with
|
||||||
|
two identical rows (row i replaced by row j), hence 0.
|
||||||
|
4. Dividing by d: Σ_k m[i][k] · (cofactor8 m j k / d) = δ(i,j).
|
||||||
|
5. Therefore (m × inv)[i][j] = δ(i,j), i.e., m × inv = I.
|
||||||
|
|
||||||
|
Q16_16 OBSTRUCTION:
|
||||||
|
|
||||||
|
This theorem is **not exactly true** over saturating Q16_16 fixed-point
|
||||||
|
arithmetic. The source of error is integer truncation in `div` and `mul`:
|
||||||
|
|
||||||
|
- `div a b` = ofRawInt ((a * 65536) / b) — truncates toward zero
|
||||||
|
- `mul a b` = ofRawInt ((a * b) / 65536) — truncates toward zero
|
||||||
|
|
||||||
|
When `det8 m` does not divide the adjugate entries exactly, `div`
|
||||||
|
introduces a truncation error of up to 1 LSB per entry. This error
|
||||||
|
propagates through `mul` and `add` in the matrix multiply.
|
||||||
|
|
||||||
|
Concrete counterexample: m = diag(3, 1, 1, 1, 1, 1, 1, 1).
|
||||||
|
det(m) = 3, inv[0][0] = div(65536, 196608) = ofRawInt(21845)
|
||||||
|
(exact 1/3 would be 21845.333…; truncation gives 21845).
|
||||||
|
(m × inv)[0][0] = mul(196608, 21845) = ofRawInt(65535) ≠ 65536 = one.
|
||||||
|
Error: 1 LSB.
|
||||||
|
|
||||||
|
For matrices where `det8 m` divides all adjugate entries exactly
|
||||||
|
(e.g., permutation matrices, power-of-2 diagonal matrices), the
|
||||||
|
identity holds. `native_decide` confirms it for the identity matrix
|
||||||
|
(see `identity8_self_inverse` and `det_self_inverse_identity` below).
|
||||||
|
|
||||||
|
TODO(lean-port): Prove one of:
|
||||||
|
(a) A bounded-error variant: each entry of `m × inv` is within 1 LSB
|
||||||
|
of `identity8`. This requires bounding the accumulated truncation
|
||||||
|
error through 8 multiply-accumulate steps.
|
||||||
|
(b) An exact version with a precondition that det8 m divides all
|
||||||
|
cofactor products exactly (e.g., det8 m is a power of 2, or
|
||||||
|
all entries are small enough to avoid truncation).
|
||||||
|
(c) A version over ℚ using Mathlib's matrix library, where the
|
||||||
|
Laplace cofactor identity has a clean proof. -/
|
||||||
theorem det_self_inverse {m : Matrix8} {inv : Matrix8}
|
theorem det_self_inverse {m : Matrix8} {inv : Matrix8}
|
||||||
(h : matrixInverse m = some inv) :
|
(h : matrixInverse m = some inv) :
|
||||||
matrixMultiply m inv = identity8 := by
|
matrixMultiply m inv = identity8 := by
|
||||||
sorry
|
sorry
|
||||||
|
|
||||||
|
/-- The 8×8 identity matrix is its own inverse. Proved by computation. -/
|
||||||
|
theorem identity8_self_inverse :
|
||||||
|
matrixInverse identity8 = some identity8 := by
|
||||||
|
native_decide
|
||||||
|
|
||||||
|
/-- Multiplying the 8×8 identity by itself yields the identity. -/
|
||||||
|
theorem identity8_mul_self :
|
||||||
|
matrixMultiply identity8 identity8 = identity8 := by
|
||||||
|
native_decide
|
||||||
|
|
||||||
|
/-- det(identity8) = 1 in Q16_16. -/
|
||||||
|
theorem det8_identity :
|
||||||
|
det8 identity8 = one := by
|
||||||
|
native_decide
|
||||||
|
|
||||||
|
/-- `det_self_inverse` holds for the identity matrix: if
|
||||||
|
`matrixInverse identity8 = some inv`, then `identity8 × inv = identity8`.
|
||||||
|
Follows from `identity8_self_inverse` and `identity8_mul_self`. -/
|
||||||
|
theorem det_self_inverse_identity {inv : Matrix8}
|
||||||
|
(h : matrixInverse identity8 = some inv) :
|
||||||
|
matrixMultiply identity8 inv = identity8 := by
|
||||||
|
have hinv : inv = identity8 := by
|
||||||
|
rw [identity8_self_inverse] at h
|
||||||
|
exact (Option.some_injective _ h).symm
|
||||||
|
subst hinv
|
||||||
|
exact identity8_mul_self
|
||||||
|
|
||||||
/-- Cayley-transformed skew-symmetric matrix is orthogonal:
|
/-- Cayley-transformed skew-symmetric matrix is orthogonal:
|
||||||
Q^T Q = I. Follows from the algebraic identity
|
Q^T Q = I. Follows from the algebraic identity
|
||||||
(I-A)(I+A)^{-1} · ((I-A)(I+A)^{-1})^T = I when A^T = -A.
|
(I-A)(I+A)^{-1} · ((I-A)(I+A)^{-1})^T = I when A^T = -A.
|
||||||
|
|
@ -288,4 +359,14 @@ theorem cayley_is_orthogonal {skew : Matrix8} {q : Matrix8}
|
||||||
| some q => (getEntry q 0 0).toInt
|
| some q => (getEntry q 0 0).toInt
|
||||||
| none => (-1 : Int)
|
| none => (-1 : Int)
|
||||||
|
|
||||||
|
-- det_self_inverse counterexample: diag(3,1,...,1) has 1-LSB error.
|
||||||
|
-- det(m) = 3 (Q16_16: 196608); entry (0,0) of m × m⁻¹ = 65535 ≠ 65536.
|
||||||
|
-- This demonstrates that det_self_inverse is not exactly true in Q16_16.
|
||||||
|
-- expect: 65535 (one LSB below identity)
|
||||||
|
#eval! let m := Array.ofFn (n := 8) fun (i : Fin 8) =>
|
||||||
|
Array.ofFn (n := 8) fun (j : Fin 8) =>
|
||||||
|
if i.val = j.val then (if i.val = 0 then ofInt 3 else one) else zero
|
||||||
|
let inv := (matrixInverse m).getD identity8
|
||||||
|
(getEntry (matrixMultiply m inv) 0 0).toInt
|
||||||
|
|
||||||
end Semantics.AdjugateMatrix
|
end Semantics.AdjugateMatrix
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue