Freivalds' algorithm
DefinitionFreivalds trial#✓fully proved
Given \(n \times n\) matrices \(A\), \(B\), \(C\) over \(\mathbb{F}_2 = \mathbb{Z}/2\), stored as arrays of rows, and a seed \(r \in \mathbb{F}_2^n\), the trial computes the column vectors \(Br\), \(A(Br)\) and \(Cr\), each by accumulating matrix products into a zero column, and returns true exactly when \(A(Br) = Cr\). Its cost is the pair (number of scalar multiplications, number of scalar additions), each multiply-add step counting one of each.
The coefficient domain is \(\mathbb{F}_2\) by intentional specialization, not by a restriction in the cited source.
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
@[no_expose] private def seedColumn {n : Nat} (r : Fin n → ZMod 2) :
_root_.Vector (_root_.Vector (ZMod 2) 1) n :=
_root_.Vector.ofFn fun i => _root_.Vector.replicate 1 (r i)
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:43
@[no_expose] private def zeroColumn (n : Nat) :
_root_.Vector (_root_.Vector (ZMod 2) 1) n :=
_root_.Vector.replicate n (_root_.Vector.replicate 1 0)
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:47
public def rectangularMatrixAccumulate {α : Type u} [Add α] [Mul α]
{p q r : Nat} (A : _root_.Vector (_root_.Vector α q) p)
(B : _root_.Vector (_root_.Vector α r) q) (C : _root_.Vector (_root_.Vector α r) p) :
TimeM (Nat × Nat) (_root_.Vector (_root_.Vector α r) p) :=
scanRows A B p 0 (by omega) (pure C)
CSLibExt/Algorithms/Lean/Matrix/Multiply.lean:279
Uses 1 · Used by 20
TheoremCost of the Freivalds trial#✓fully proved
For \(n \times n\) matrices \(A\), \(B\), \(C\) over \(\mathbb{F}_2\) and every seed \(r \in \mathbb{F}_2^n\), the Freivalds trial performs exactly \(3n^2\) scalar multiplications and exactly \(3n^2\) scalar additions.
These counts belong to the same run that returns the acceptance bit and include the additions into the zero-initialized accumulators.
theorem freivaldsTrial_time {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) :
(freivaldsTrial A B C r).time = (3 * n ^ 2, 3 * n ^ 2)
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
Uses 3 · Used by 2
DefinitionMatrix of a Freivalds input#✓fully proved
An \(n \times n\) array \(A\) of rows over \(\mathbb{F}_2 = \mathbb{Z}/2\) determines the \(n \times n\) matrix over \(\mathbb{F}_2\) whose \((i, j)\) entry is entry \(j\) of row \(i\) of \(A\).
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
Used by 13
TheoremAcceptance criterion of the Freivalds trial#✓fully proved
For \(n \times n\) matrices \(A\), \(B\), \(C\) over \(\mathbb{F}_2\) and every seed \(r \in \mathbb{F}_2^n\), the Freivalds trial on \(A\), \(B\), \(C\), \(r\) returns true if and only if \(A(Br) = Cr\).
theorem freivaldsTrial_accept_iff {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) :
(freivaldsTrial A B C r).ret = true ↔
(freivaldsMatrix A).mulVec ((freivaldsMatrix B).mulVec r) =
(freivaldsMatrix C).mulVec r
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:76
Uses 4 · Used by 2
TheoremAcceptance via the product discrepancy#✓fully proved
For \(n \times n\) matrices \(A\), \(B\), \(C\) over \(\mathbb{F}_2\) and every seed \(r \in \mathbb{F}_2^n\), the Freivalds trial on \(A\), \(B\), \(C\), \(r\) returns true if and only if \((AB - C)r = 0\).
theorem freivaldsTrial_accept_discrepancy_iff {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) :
(freivaldsTrial A B C r).ret = true ↔
(freivaldsMatrix A * freivaldsMatrix B - freivaldsMatrix C).mulVec r = 0
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:76
Uses 3 · Used by 2
TheoremCompleteness of the Freivalds trial#✓fully proved
Let \(A\), \(B\), \(C\) be \(n \times n\) matrices over \(\mathbb{F}_2\) with \(AB = C\). Then for every seed \(r \in \mathbb{F}_2^n\) the Freivalds trial on \(A\), \(B\), \(C\), \(r\) returns true. This includes the case \(n = 0\).
theorem freivaldsTrial_complete {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(h : freivaldsMatrix A * freivaldsMatrix B = freivaldsMatrix C)
(r : Fin n → ZMod 2) :
(freivaldsTrial A B C r).ret = true
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:76
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
Uses 3 · Used by 3
TheoremFreivalds trial on empty matrices#✓fully proved
For \(0 \times 0\) matrices \(A\), \(B\), \(C\) over \(\mathbb{F}_2\) and the empty seed \(r\), the Freivalds trial returns true at zero cost: it performs no scalar multiplications and no scalar additions.
theorem freivaldsTrial_empty
(A B C : _root_.Vector (_root_.Vector (ZMod 2) 0) 0)
(r : Fin 0 → ZMod 2) :
freivaldsTrial A B C r = pure true
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
Uses 4
TheoremSoundness of the Freivalds trial#✓fully proved
Let \(A\), \(B\), \(C\) be \(n \times n\) matrices over \(\mathbb{F}_2\) with \(AB \ne C\). Then twice the number of seeds \(r \in \mathbb{F}_2^n\) on which the Freivalds trial returns true is at most the number of all seeds in \(\mathbb{F}_2^n\); that is, at most half of the seeds accept.
Acceptance is the return value of the same charged run whose cost is counted.
theorem freivaldsTrial_acceptanceCard_bound {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(wrong : freivaldsMatrix A * freivaldsMatrix B ≠ freivaldsMatrix C) :
2 * Fintype.card {r : Fin n → ZMod 2 // (freivaldsTrial A B C r).ret = true} ≤
Fintype.card (Fin n → ZMod 2)
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:76
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
Uses 3 · Used by 1
DefinitionFreivalds trial law#✓fully proved
For \(n \times n\) matrices \(A\), \(B\), \(C\) over \(\mathbb{F}_2 = \mathbb{Z}/2\mathbb{Z}\), given as arrays, the Freivalds trial law is the probability distribution on \(\{\mathrm{true}, \mathrm{false}\}\) of the value returned by the Freivalds trial on \(A\), \(B\), \(C\) with seed \(r\), where \(r\) is drawn uniformly from \(\mathbb{F}_2^n\).
The seeds are exactly uniform; no pseudorandom generator or assumed error probability is involved.
noncomputable def freivaldsTrialLaw {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin n → ZMod 2)).map
fun r => (freivaldsTrial A B C r).ret
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
Uses 1 · Used by 8
TheoremUniform mass of a Freivalds seed#✓fully proved
Let \(\mathbb{F}_2 = \mathbb{Z}/2\mathbb{Z}\). For every \(n\) and every vector \(r \in \mathbb{F}_2^n\), the uniform probability distribution on \(\mathbb{F}_2^n\) assigns to \(r\) the probability \((2^n)^{-1}\).
TheoremAcceptance probability of the Freivalds trial as a seed count#✓fully proved
Let \(A\), \(B\), \(C\) be \(n \times n\) matrices over \(\mathbb{F}_2 = \mathbb{Z}/2\mathbb{Z}\), given as arrays. The probability that the Freivalds trial law of \(A\), \(B\), \(C\) returns true equals the number of seeds \(r \in \mathbb{F}_2^n\) on which the Freivalds trial on \(A\), \(B\), \(C\) with seed \(r\) accepts, divided by the number \(|\mathbb{F}_2^n|\) of all seeds.
theorem freivaldsTrialLaw_acceptance {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
freivaldsTrialLaw A B C true =
(Fintype.card {r : Fin n → ZMod 2 // (freivaldsTrial A B C r).ret = true} : ℝ≥0∞) /
Fintype.card (Fin n → ZMod 2)
noncomputable def freivaldsTrialLaw {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin n → ZMod 2)).map
fun r => (freivaldsTrial A B C r).ret
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Probability.lean:27
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
Uses 2 · Used by 4
TheoremThe Freivalds trial accepts a correct product with probability one#✓fully proved
Let \(A\), \(B\), \(C\) be \(n \times n\) matrices over \(\mathbb{F}_2 = \mathbb{Z}/2\mathbb{Z}\), given as arrays. If \(AB = C\), then the Freivalds trial law of \(A\), \(B\), \(C\) returns true with probability \(1\). This includes the case \(n = 0\) of empty matrices.
theorem freivaldsTrialLaw_complete {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(correct : freivaldsMatrix A * freivaldsMatrix B = freivaldsMatrix C) :
freivaldsTrialLaw A B C true = 1
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:76
noncomputable def freivaldsTrialLaw {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin n → ZMod 2)).map
fun r => (freivaldsTrial A B C r).ret
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Probability.lean:27
Uses 5 · Used by 1
TheoremThe Freivalds trial accepts a wrong product with probability at most one half#✓fully proved
Let \(A\), \(B\), \(C\) be \(n \times n\) matrices over \(\mathbb{F}_2 = \mathbb{Z}/2\mathbb{Z}\), given as arrays. If \(AB \ne C\), then the Freivalds trial law of \(A\), \(B\), \(C\) returns true with probability at most \(1/2\).
theorem freivaldsTrialLaw_sound {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(wrong : freivaldsMatrix A * freivaldsMatrix B ≠ freivaldsMatrix C) :
freivaldsTrialLaw A B C true ≤ (1 / 2 : ℝ≥0∞)
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:76
noncomputable def freivaldsTrialLaw {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin n → ZMod 2)).map
fun r => (freivaldsTrial A B C r).ret
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Probability.lean:27
Uses 5 · Used by 1
DefinitionRepeated Freivalds test on fixed seeds#✓fully proved
Given \(n \times n\) matrices \(A\), \(B\), \(C\) over \(\mathbb{Z}/2\) and seeds \(r_0, \dots, r_{k-1} \in (\mathbb{Z}/2)^n\), run the Freivalds trial on \(A\), \(B\), \(C\) with each seed \(r_0, \dots, r_{k-1}\) in order, including the trials after a rejection, and return the conjunction of their results (true when \(k = 0\)). The arithmetic cost of the run is the sum of the costs of the \(k\) trials.
public def freivaldsRepeat {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin k → Fin n → ZMod 2) : TimeM (Nat × Nat) Bool :=
(List.ofFn history).foldlM (repeatStep A B C) true
@[no_expose] private def repeatStep {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(accepted : Bool) (r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let current ← freivaldsTrial A B C r
pure (accepted && current)
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Repeat.lean:31
Uses 1 · Used by 8
TheoremCost of the repeated Freivalds test on fixed seeds#✓fully proved
For \(n \times n\) matrices \(A\), \(B\), \(C\) over \(\mathbb{Z}/2\) and seeds \(r_0, \dots, r_{k-1} \in (\mathbb{Z}/2)^n\), the repeated Freivalds test on these seeds performs exactly \(3kn^2\) scalar multiplications and \(3kn^2\) scalar additions.
theorem freivaldsRepeat_time {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin k → Fin n → ZMod 2) :
(freivaldsRepeat A B C history).time = (3 * k * n ^ 2, 3 * k * n ^ 2)
public def freivaldsRepeat {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin k → Fin n → ZMod 2) : TimeM (Nat × Nat) Bool :=
(List.ofFn history).foldlM (repeatStep A B C) true
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Repeat.lean:38
Uses 3 · Used by 2
TheoremAcceptance of the repeated Freivalds test on fixed seeds#✓fully proved
For \(n \times n\) matrices \(A\), \(B\), \(C\) over \(\mathbb{Z}/2\) and seeds \(r_0, \dots, r_{k-1} \in (\mathbb{Z}/2)^n\), the repeated Freivalds test on these seeds accepts if and only if, for every \(i < k\), the Freivalds trial on \(A\), \(B\), \(C\) with seed \(r_i\) accepts.
theorem freivaldsRepeat_accept_iff {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin k → Fin n → ZMod 2) :
(freivaldsRepeat A B C history).ret = true ↔
∀ i, (freivaldsTrial A B C (history i)).ret = true
public def freivaldsRepeat {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin k → Fin n → ZMod 2) : TimeM (Nat × Nat) Bool :=
(List.ofFn history).foldlM (repeatStep A B C) true
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Repeat.lean:38
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
TheoremCompleteness of the repeated Freivalds test on fixed seeds#✓fully proved
Let \(A\), \(B\), \(C\) be \(n \times n\) matrices over \(\mathbb{Z}/2\) with \(AB = C\). Then for every \(k\), including \(k = 0\), and all seeds \(r_0, \dots, r_{k-1} \in (\mathbb{Z}/2)^n\), the repeated Freivalds test on these seeds accepts.
theorem freivaldsRepeat_complete {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(correct : freivaldsMatrix A * freivaldsMatrix B = freivaldsMatrix C)
(history : Fin k → Fin n → ZMod 2) :
(freivaldsRepeat A B C history).ret = true
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:76
public def freivaldsRepeat {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin k → Fin n → ZMod 2) : TimeM (Nat × Nat) Bool :=
(List.ofFn history).foldlM (repeatStep A B C) true
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Repeat.lean:38
Uses 5 · Used by 1
TheoremRepeated Freivalds test with no trials#✓fully proved
For \(n \times n\) matrices \(A\), \(B\), \(C\) over \(\mathbb{Z}/2\), the repeated Freivalds test on the empty list of seeds (\(k = 0\)) accepts and performs no scalar multiplications or additions.
theorem freivaldsRepeat_zero {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin 0 → Fin n → ZMod 2) :
freivaldsRepeat A B C history = pure true
public def freivaldsRepeat {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin k → Fin n → ZMod 2) : TimeM (Nat × Nat) Bool :=
(List.ofFn history).foldlM (repeatStep A B C) true
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Repeat.lean:38
TheoremRepeated Freivalds test on empty matrices#✓fully proved
For \(0 \times 0\) matrices \(A\), \(B\), \(C\) over \(\mathbb{Z}/2\) and any number \(k\) of seeds (each the empty vector), the repeated Freivalds test accepts and performs no scalar multiplications or additions.
theorem freivaldsRepeat_empty {k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) 0) 0)
(history : Fin k → Fin 0 → ZMod 2) :
freivaldsRepeat A B C history = pure true
public def freivaldsRepeat {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin k → Fin n → ZMod 2) : TimeM (Nat × Nat) Bool :=
(List.ofFn history).foldlM (repeatStep A B C) true
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Repeat.lean:38
DefinitionOutput distribution of repeated Freivalds trials#✓fully proved
For natural numbers \(n, k\) and \(n \times n\) matrices \(A, B, C\) over \(\mathbb{F}_2\), this is the probability distribution on \(\{\mathrm{true}, \mathrm{false}\}\) of the result returned by the repeated Freivalds executor on \(A, B, C\) when its history of \(k\) seeds is drawn uniformly from \((\mathbb{F}_2^n)^k\).
noncomputable def freivaldsRepeatLaw {n : Nat} (k : Nat)
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin k → Fin n → ZMod 2)).map fun history =>
(freivaldsRepeat A B C history).ret
public def freivaldsRepeat {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin k → Fin n → ZMod 2) : TimeM (Nat × Nat) Bool :=
(List.ofFn history).foldlM (repeatStep A B C) true
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Repeat.lean:38
TheoremUniform mass of a Freivalds seed history#✓fully proved
For all natural numbers \(n\) and \(k\), under the uniform distribution on histories of \(k\) seeds, that is, on \((\mathbb{F}_2^n)^k\), every history has probability exactly \((2^{nk})^{-1}\). This includes the cases \(k = 0\) and \(n = 0\).
TheoremCounting accepted histories of repeated Freivalds trials#✓fully proved
Let \(n, k\) be natural numbers and let \(A, B, C\) be \(n \times n\) matrices over \(\mathbb{F}_2\). The number of histories \((r_1, \dots, r_k)\) of seeds \(r_i \in \mathbb{F}_2^n\) on which the repeated Freivalds executor accepts equals \(a^k\), where \(a\) is the number of seeds \(r \in \mathbb{F}_2^n\) on which a single Freivalds trial accepts.
theorem freivaldsRepeat_acceptanceCard {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
Fintype.card {history : Fin k → Fin n → ZMod 2 //
(freivaldsRepeat A B C history).ret = true} =
(Fintype.card {r : Fin n → ZMod 2 // (freivaldsTrial A B C r).ret = true}) ^ k
public def freivaldsRepeat {n k : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(history : Fin k → Fin n → ZMod 2) : TimeM (Nat × Nat) Bool :=
(List.ofFn history).foldlM (repeatStep A B C) true
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Repeat.lean:38
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
Uses 3 · Used by 1
TheoremAcceptance probability of repeated Freivalds trials#✓fully proved
Let \(n, k\) be natural numbers and let \(A, B, C\) be \(n \times n\) matrices over \(\mathbb{F}_2\). If the history of \(k\) seeds is drawn uniformly from \((\mathbb{F}_2^n)^k\), the probability that the repeated Freivalds executor accepts is \(p^k\), where \(p\) is the probability that a single Freivalds trial accepts on a seed drawn uniformly from \(\mathbb{F}_2^n\).
theorem freivaldsRepeatLaw_acceptance_power {n : Nat} (k : Nat)
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
freivaldsRepeatLaw k A B C true = (freivaldsTrialLaw A B C true) ^ k
noncomputable def freivaldsRepeatLaw {n : Nat} (k : Nat)
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin k → Fin n → ZMod 2)).map fun history =>
(freivaldsRepeat A B C history).ret
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Amplification.lean:37
noncomputable def freivaldsTrialLaw {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin n → ZMod 2)).map
fun r => (freivaldsTrial A B C r).ret
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Probability.lean:27
TheoremCompleteness of repeated Freivalds trials#✓fully proved
Let \(n, k\) be natural numbers and let \(A, B, C\) be \(n \times n\) matrices over \(\mathbb{F}_2\) with \(AB = C\). If the history of \(k\) seeds is drawn uniformly from \((\mathbb{F}_2^n)^k\), then the repeated Freivalds executor accepts with probability \(1\).
theorem freivaldsRepeatLaw_complete {n : Nat} (k : Nat)
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(correct : freivaldsMatrix A * freivaldsMatrix B = freivaldsMatrix C) :
freivaldsRepeatLaw k A B C true = 1
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:76
noncomputable def freivaldsRepeatLaw {n : Nat} (k : Nat)
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin k → Fin n → ZMod 2)).map fun history =>
(freivaldsRepeat A B C history).ret
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Amplification.lean:37
TheoremSoundness of repeated Freivalds trials#✓fully proved
Let \(n, k\) be natural numbers and let \(A, B, C\) be \(n \times n\) matrices over \(\mathbb{F}_2\) with \(AB \ne C\). If the history of \(k\) seeds is drawn uniformly from \((\mathbb{F}_2^n)^k\), then the repeated Freivalds executor accepts with probability at most \((2^k)^{-1}\).
theorem freivaldsRepeatLaw_sound {n : Nat} (k : Nat)
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(wrong : freivaldsMatrix A * freivaldsMatrix B ≠ freivaldsMatrix C) :
freivaldsRepeatLaw k A B C true ≤ ((2 : ℝ≥0∞) ^ k)⁻¹
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:76
noncomputable def freivaldsRepeatLaw {n : Nat} (k : Nat)
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin k → Fin n → ZMod 2)).map fun history =>
(freivaldsRepeat A B C history).ret
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Amplification.lean:37
TheoremThe sharp Freivalds example has a wrong product#✓fully proved
Let \(A = B = (1)\) and \(C = (0)\) be \(1 \times 1\) matrices over \(\mathbb{Z}/2\mathbb{Z}\). Then \(AB \neq C\).
theorem freivalds_one_wrong :
freivaldsMatrix
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (1 : ZMod 2))) *
freivaldsMatrix
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (1 : ZMod 2))) ≠
freivaldsMatrix
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (0 : ZMod 2)))
public def freivaldsMatrix {n : Nat}
(A : _root_.Vector (_root_.Vector (ZMod 2) n) n) :
_root_.Matrix (Fin n) (Fin n) (ZMod 2) :=
_root_.Matrix.of fun i j => (A.get i).get j
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:76
Uses 1
TheoremThe sharp Freivalds example accepts exactly the zero seed#✓fully proved
Let \(A = B = (1)\) and \(C = (0)\) be \(1 \times 1\) matrices over \(\mathbb{Z}/2\mathbb{Z}\). For every seed \(r \in (\mathbb{Z}/2\mathbb{Z})^1\), the Freivalds trial on \(A\), \(B\), \(C\) with seed \(r\), which compares \(A(Br)\) with \(Cr\), accepts if and only if the single entry \(r_0\) of \(r\) is \(0\).
theorem freivaldsTrial_one_accept_iff (r : Fin 1 → ZMod 2) :
(freivaldsTrial
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (1 : ZMod 2)))
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (1 : ZMod 2)))
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (0 : ZMod 2))) r).ret = true ↔
r 0 = 0
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
Uses 3 · Used by 1
TheoremThe sharp Freivalds example has exactly one accepted seed#✓fully proved
Let \(A = B = (1)\) and \(C = (0)\) be \(1 \times 1\) matrices over \(\mathbb{Z}/2\mathbb{Z}\). Exactly one seed \(r \in (\mathbb{Z}/2\mathbb{Z})^1\) is accepted by the Freivalds trial on \(A\), \(B\), \(C\).
theorem freivaldsTrial_one_acceptanceCard :
Fintype.card {r : Fin 1 → ZMod 2 //
(freivaldsTrial
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (1 : ZMod 2)))
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (1 : ZMod 2)))
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (0 : ZMod 2))) r).ret = true} =
1
public def freivaldsTrial {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n)
(r : Fin n → ZMod 2) : TimeM (Nat × Nat) Bool := do
let column := seedColumn r
let initial := zeroColumn n
let br ← rectangularMatrixAccumulate B column initial
let abr ← rectangularMatrixAccumulate A br initial
let cr ← rectangularMatrixAccumulate C column initial
pure (decide (abr = cr))
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Basic.lean:54
Uses 2 · Used by 1
TheoremThe sharp Freivalds example is accepted with probability one half#✓fully proved
Let \(A = B = (1)\) and \(C = (0)\) be \(1 \times 1\) matrices over \(\mathbb{Z}/2\mathbb{Z}\). When the seed is drawn uniformly from \((\mathbb{Z}/2\mathbb{Z})^1\), the Freivalds trial on \(A\), \(B\), \(C\) accepts with probability exactly \(1/2\).
Since \(AB \neq C\), this shows that the bound \(1/2\) on the probability that one trial accepts a wrong product cannot be improved.
theorem freivaldsTrialLaw_one_sharp :
freivaldsTrialLaw
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (1 : ZMod 2)))
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (1 : ZMod 2)))
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (0 : ZMod 2))) true =
(1 : ℝ≥0∞) / 2
noncomputable def freivaldsTrialLaw {n : Nat}
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin n → ZMod 2)).map
fun r => (freivaldsTrial A B C r).ret
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Probability.lean:27
Uses 4 · Used by 1
TheoremExact acceptance probability of repeated trials on the sharp Freivalds example#✓fully proved
Let \(A = B = (1)\) and \(C = (0)\) be \(1 \times 1\) matrices over \(\mathbb{Z}/2\mathbb{Z}\), and let \(k\) be a natural number. Run \(k\) Freivalds trials on \(A\), \(B\), \(C\) with seeds drawn independently and uniformly from \((\mathbb{Z}/2\mathbb{Z})^1\), accepting exactly when every trial accepts. Then the run accepts with probability exactly \(2^{-k}\).
Since \(AB \neq C\), the bound \(2^{-k}\) on the probability that \(k\) trials accept a wrong product cannot be improved.
theorem freivaldsRepeatLaw_one_sharp (k : Nat) :
freivaldsRepeatLaw k
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (1 : ZMod 2)))
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (1 : ZMod 2)))
(_root_.Vector.replicate 1 (_root_.Vector.replicate 1 (0 : ZMod 2))) true =
((2 : ℝ≥0∞) ^ k)⁻¹
noncomputable def freivaldsRepeatLaw {n : Nat} (k : Nat)
(A B C : _root_.Vector (_root_.Vector (ZMod 2) n) n) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype (Fin k → Fin n → ZMod 2)).map fun history =>
(freivaldsRepeat A B C history).ret
CSLibExt/Algorithms/Lean/Matrix/Freivalds/Amplification.lean:37
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.