Skip to content

Commit 6fccd48

Browse files
committed
feat: add lemmas about doubly stochastic matrices (#33394)
This PR adds a few basic lemmas about doubly stochastic matrices.
1 parent 9cae144 commit 6fccd48

File tree

2 files changed

+57
-17
lines changed

2 files changed

+57
-17
lines changed

Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ Authors: Bhavik Mehta
55
-/
66
module
77

8-
public import Mathlib.Analysis.Convex.Basic
9-
public import Mathlib.LinearAlgebra.Matrix.Permutation
108
public import Mathlib.LinearAlgebra.Matrix.Stochastic
119

1210
/-!
@@ -23,11 +21,6 @@ public import Mathlib.LinearAlgebra.Matrix.Stochastic
2321
* `convex_doublyStochastic`: The set of doubly stochastic matrices is convex.
2422
* `permMatrix_mem_doublyStochastic`: Any permutation matrix is doubly stochastic.
2523
26-
## TODO
27-
28-
Define the submonoids of row-stochastic and column-stochastic matrices.
29-
Show that the submonoid of doubly stochastic matrices is the meet of them, or redefine it as such.
30-
3124
## Tags
3225
3326
Doubly stochastic, Birkhoff's theorem, Birkhoff-von Neumann theorem
@@ -67,7 +60,7 @@ lemma mem_doublyStochastic_iff_sum :
6760

6861
/-- A matrix is doubly stochastic if and only if it is both row and
6962
column stochastic. -/
70-
@[grind =]
63+
@[local grind =]
7164
lemma doublyStochastic_eq_rowStochastic_inf_colStochastic :
7265
doublyStochastic R n = rowStochastic R n ⊓ colStochastic R n := by
7366
ext M
@@ -112,17 +105,32 @@ lemma convex_doublyStochastic : Convex R (doublyStochastic R n : Set (Matrix n n
112105
simp [add_nonneg, ha, hb, mul_nonneg, hx, hy, sum_add_distrib, ← mul_sum, h]
113106

114107
/-- Any permutation matrix is doubly stochastic. -/
108+
@[simp, grind ←]
115109
lemma permMatrix_mem_doublyStochastic {σ : Equiv.Perm n} :
116-
σ.permMatrix R ∈ doublyStochastic R n := by
117-
grind only [= doublyStochastic_eq_rowStochastic_inf_colStochastic, = Submonoid.mem_inf,
118-
← permMatrix_mem_rowStochastic, ← permMatrix_mem_colStochastic]
110+
σ.permMatrix R ∈ doublyStochastic R n := by grind
119111

120112
/-- A matrix is doubly stochastic iff its transpose is doubly stochastic -/
113+
@[grind =]
121114
lemma transpose_mem_doublyStochastic_iff :
122-
M.transpose ∈ doublyStochastic R n ↔ M ∈ doublyStochastic R n := by
123-
grind only [= doublyStochastic_eq_rowStochastic_inf_colStochastic, = Submonoid.mem_inf,
124-
= transpose_mem_rowStochastic_iff_mem_colStochastic, = mem_rowStochastic,
125-
= transpose_mem_colStochastic_iff_mem_rowStochastic, = mem_colStochastic]
115+
Mᵀ ∈ doublyStochastic R n ↔ M ∈ doublyStochastic R n := by grind
116+
117+
/-- Reindexing a matrix preserves double stochasticity. -/
118+
@[aesop safe apply]
119+
lemma reindex_mem_doublyStochastic {m : Type*} [Fintype m] [DecidableEq m] {M : Matrix n n R}
120+
{e₁ e₂ : n ≃ m} (hM : M ∈ doublyStochastic R n) : M.reindex e₁ e₂ ∈ doublyStochastic R m := by
121+
grind
122+
123+
/-- Reindexing a matrix preserves double stochasticity. -/
124+
@[grind =]
125+
lemma reindex_mem_doublyStochastic_iff {m : Type*} [Fintype m] [DecidableEq m] {M : Matrix n n R}
126+
{e₁ e₂ : n ≃ m} : M.reindex e₁ e₂ ∈ doublyStochastic R m ↔ M ∈ doublyStochastic R n := by
127+
grind
128+
129+
/-- Applying a doubly stochastic matrix to a vector preserves its sum. -/
130+
lemma sum_mulVec_of_mem_doublyStochastic {M : Matrix n n R} {x : n → R}
131+
(hA : M ∈ doublyStochastic R n) : ∑ i, (M *ᵥ x) i = ∑ i, x i := by
132+
apply sum_mulVec_of_mem_colStochastic
133+
grind
126134

127135
end OrderedSemiring
128136

Mathlib/LinearAlgebra/Matrix/Stochastic.lean

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ def rowStochastic (R n : Type*) [Fintype n] [DecidableEq n] [Semiring R] [Partia
5252
one_mem' := by
5353
simp [zero_le_one_elem]
5454

55-
@[grind =]
5655
lemma mem_rowStochastic :
5756
M ∈ rowStochastic R n ↔ (∀ i j, 0 ≤ M i j) ∧ M *ᵥ 1 = 1 :=
5857
Iff.rfl
@@ -139,7 +138,6 @@ def colStochastic (R n : Type*) [Fintype n] [DecidableEq n] [Semiring R] [Partia
139138
one_mem' := by
140139
simp [zero_le_one_elem]
141140

142-
@[grind =]
143141
lemma mem_colStochastic :
144142
M ∈ colStochastic R n ↔ (∀ i j, 0 ≤ M i j) ∧ 1 ᵥ* M = 1 :=
145143
Iff.rfl
@@ -195,6 +193,13 @@ lemma mulVec_dotProduct_one_eq_one_colStochastic (hM : M ∈ colStochastic R n)
195193
(hx : 1 ⬝ᵥ x = 1) : 1 ⬝ᵥ (M *ᵥ x) = 1 := by
196194
rw [dotProduct_mulVec, hM.2, hx]
197195

196+
/-- Applying a column-stochastic matrix to a vector preserves its sum. -/
197+
lemma sum_mulVec_of_mem_colStochastic {M : Matrix n n R} {x : n → R}
198+
(hA : M ∈ colStochastic R n) : ∑ i, (M *ᵥ x) i = ∑ i, x i := by
199+
simp only [Matrix.mulVec, dotProduct]
200+
rw [Finset.sum_comm]
201+
simp [sum_col_of_mem_colStochastic hA, ← Finset.sum_mul]
202+
198203
/-- The set of column stochastic matrices is convex. -/
199204
lemma convex_colStochastic : Convex R (colStochastic R n : Set (Matrix n n R)) := by
200205
intro x hx y hy a b ha hb h
@@ -226,4 +231,31 @@ lemma transpose_mem_colStochastic_iff_mem_rowStochastic :
226231
and_congr_left_iff]
227232
exact fun _ ↦ forall_swap
228233

234+
/-- Reindexing a matrix preserves row-stochasticity. -/
235+
@[aesop safe apply]
236+
lemma reindex_mem_rowStochastic {m : Type*} [Fintype m] [DecidableEq m] {M : Matrix n n R}
237+
{e₁ e₂ : n ≃ m} (hM : M ∈ rowStochastic R n) : M.reindex e₁ e₂ ∈ rowStochastic R m :=
238+
fun _ _ ↦ by simpa using nonneg_of_mem_rowStochastic hM, by simp [submatrix_mulVec_equiv, hM.2]⟩
239+
240+
/-- Reindexing a matrix preserves row-stochasticity. -/
241+
@[grind =]
242+
lemma reindex_mem_rowStochastic_iff {m : Type*} [Fintype m] [DecidableEq m] {M : Matrix n n R}
243+
{e₁ e₂ : n ≃ m} : M.reindex e₁ e₂ ∈ rowStochastic R m ↔ M ∈ rowStochastic R n := by
244+
refine ⟨fun h => ?_, reindex_mem_rowStochastic⟩
245+
have : M = (M.reindex e₁ e₂).reindex e₁.symm e₂.symm := by simp
246+
rw [this]
247+
exact reindex_mem_rowStochastic h
248+
249+
/-- Reindexing a matrix preserves column-stochasticity. -/
250+
@[grind =]
251+
lemma reindex_mem_colStochastic_iff {m : Type*} [Fintype m] [DecidableEq m] {M : Matrix n n R}
252+
{e₁ e₂ : n ≃ m} : M.reindex e₁ e₂ ∈ colStochastic R m ↔ M ∈ colStochastic R n := by
253+
rw [← transpose_transpose (reindex e₁ e₂ M), transpose_reindex,
254+
transpose_mem_colStochastic_iff_mem_rowStochastic, reindex_mem_rowStochastic_iff,
255+
← transpose_mem_colStochastic_iff_mem_rowStochastic, transpose_transpose]
256+
257+
/-- Reindexing a matrix preserves column-stochasticity. -/
258+
@[aesop safe apply]
259+
alias ⟨_, reindex_mem_colStochastic⟩ := reindex_mem_colStochastic_iff
260+
229261
end Matrix

0 commit comments

Comments
 (0)