forked from leanprover-community/mathlib4
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMatrix.lean
More file actions
296 lines (236 loc) · 13.6 KB
/
Copy pathMatrix.lean
File metadata and controls
296 lines (236 loc) · 13.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/-
Copyright (c) 2022 Hans Parshall. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Hans Parshall
-/
module
public import Mathlib.Analysis.InnerProductSpace.Adjoint
public import Mathlib.Analysis.Matrix.Normed
public import Mathlib.Analysis.RCLike.Basic
public import Mathlib.LinearAlgebra.UnitaryGroup
public import Mathlib.Topology.UniformSpace.Matrix
/-!
# Analytic properties of the `star` operation on matrices
This transports the operator norm on `EuclideanSpace 𝕜 n →L[𝕜] EuclideanSpace 𝕜 m` to
`Matrix m n 𝕜`. See the file `Mathlib/Analysis/Matrix.lean` for many other matrix norms.
## Main definitions
* `Matrix.instNormedRingL2Op`: the (necessarily unique) normed ring structure on `Matrix n n 𝕜`
which ensure it is a `CStarRing` in `Matrix.instCStarRing`. This is a scoped instance in the
namespace `Matrix.Norms.L2Operator` in order to avoid choosing a global norm for `Matrix`.
## Main statements
* `entry_norm_bound_of_unitary`: the entries of a unitary matrix are uniformly bound by `1`.
## Implementation details
We take care to ensure the topology and uniformity induced by `Matrix.instMetricSpaceL2Op`
coincide with the existing topology and uniformity on matrices.
-/
@[expose] public section
open WithLp
open scoped Matrix
variable {𝕜 m n l E : Type*}
section EntrywiseSupNorm
variable [RCLike 𝕜] [Fintype n] [DecidableEq n]
theorem entry_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜)
(i j : n) : ‖U i j‖ ≤ 1 := by
-- The norm squared of an entry is at most the L2 norm of its row.
have norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x, ‖U i x‖ ^ 2 := by
apply Multiset.single_le_sum
· intro x h_x
rw [Multiset.mem_map] at h_x
obtain ⟨a, h_a⟩ := h_x
rw [← h_a.2]
apply sq_nonneg
· rw [Multiset.mem_map]
use j
simp only [Finset.mem_univ_val, and_self_iff]
-- The L2 norm of a row is a diagonal entry of U * Uᴴ
have diag_eq_norm_sum : (U * Uᴴ) i i = (∑ x : n, ‖U i x‖ ^ 2 : ℝ) := by
simp only [Matrix.mul_apply, Matrix.conjTranspose_apply, ← starRingEnd_apply, RCLike.mul_conj]
norm_cast
-- The L2 norm of a row is a diagonal entry of U * Uᴴ, real part
have re_diag_eq_norm_sum : RCLike.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2 := by
rw [RCLike.ext_iff] at diag_eq_norm_sum
rw [diag_eq_norm_sum.1]
norm_cast
-- Since U is unitary, the diagonal entries of U * Uᴴ are all 1
have mul_eq_one : U * Uᴴ = 1 := Unitary.mul_star_self_of_mem hU
have diag_eq_one : RCLike.re ((U * Uᴴ) i i) = 1 := by
simp only [mul_eq_one, Matrix.one_apply_eq, RCLike.one_re]
-- Putting it all together
rw [← sq_le_one_iff₀ (norm_nonneg (U i j)), ← diag_eq_one, re_diag_eq_norm_sum]
exact norm_sum
set_option backward.isDefEq.respectTransparency false in
open scoped Matrix.Norms.Elementwise in
/-- The entrywise sup norm of a unitary matrix is at most 1. -/
theorem entrywise_sup_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜) :
‖U‖ ≤ 1 := by
simp_rw [pi_norm_le_iff_of_nonneg zero_le_one]
intros
exact entry_norm_bound_of_unitary hU _ _
end EntrywiseSupNorm
noncomputable section L2OpNorm
namespace Matrix
open LinearMap
variable [RCLike 𝕜]
variable [Fintype m] [Fintype n] [DecidableEq n] [Fintype l] [DecidableEq l]
/-- The natural star algebra equivalence between matrices and continuous linear endomorphisms
of Euclidean space induced by the orthonormal basis `EuclideanSpace.basisFun`.
This is a more-bundled version of `Matrix.toEuclideanLin`, for the special case of square matrices,
followed by a more-bundled version of `LinearMap.toContinuousLinearMap`. -/
def toEuclideanCLM :
Matrix n n 𝕜 ≃⋆ₐ[𝕜] (EuclideanSpace 𝕜 n →L[𝕜] EuclideanSpace 𝕜 n) :=
toMatrixOrthonormal (EuclideanSpace.basisFun n 𝕜) |>.symm.trans <|
{ toContinuousLinearMap with
map_mul' := fun _ _ ↦ rfl
map_star' := adjoint_toContinuousLinearMap }
lemma coe_toEuclideanCLM_eq_toEuclideanLin (A : Matrix n n 𝕜) :
(toEuclideanCLM (n := n) (𝕜 := 𝕜) A : _ →ₗ[𝕜] _) = toEuclideanLin A :=
rfl
@[simp]
lemma toEuclideanCLM_toLp (A : Matrix n n 𝕜) (x : n → 𝕜) :
toEuclideanCLM (n := n) (𝕜 := 𝕜) A (toLp _ x) = toLp _ (A *ᵥ x) := rfl
@[simp]
lemma ofLp_toEuclideanCLM (A : Matrix n n 𝕜) (x : EuclideanSpace 𝕜 n) :
ofLp (toEuclideanCLM (n := n) (𝕜 := 𝕜) A x) = A *ᵥ ofLp x := rfl
set_option backward.isDefEq.respectTransparency false in
open scoped RealInnerProductSpace in
lemma inner_toEuclideanCLM (A : Matrix n n ℝ) (x y : EuclideanSpace ℝ n) :
⟪x, toEuclideanCLM (𝕜 := ℝ) A y⟫ = x ⬝ᵥ A *ᵥ y := by
simp only [toEuclideanCLM, AddHom.toFun_eq_coe, LinearMap.coe_toAddHom, LinearEquiv.coe_coe,
LinearEquiv.invFun_eq_symm, LinearMap.coe_toContinuousLinearMap_symm, StarAlgEquiv.trans_apply,
LinearMap.toMatrixOrthonormal_symm_apply, LinearMap.toMatrix_symm, StarAlgEquiv.coe_mk,
StarRingEquiv.coe_mk, RingEquiv.coe_mk, Equiv.coe_fn_mk, LinearMap.coe_toContinuousLinearMap',
toLin_apply, mulVec_eq_sum, OrthonormalBasis.coe_toBasis_repr_apply,
EuclideanSpace.basisFun_repr, op_smul_eq_smul, Finset.sum_apply, Pi.smul_apply, transpose_apply,
smul_eq_mul, OrthonormalBasis.coe_toBasis, EuclideanSpace.basisFun_apply, PiLp.inner_apply,
ofLp_sum, ofLp_smul, PiLp.ofLp_single, RCLike.inner_apply, conj_trivial, dotProduct]
congr with i
rw [mul_comm (x.ofLp i)]
simp [Pi.single_apply]
/-- An auxiliary definition used only to construct the true `NormedAddCommGroup` (and `Metric`)
structure provided by `Matrix.instMetricSpaceL2Op` and `Matrix.instNormedAddCommGroupL2Op`. -/
@[implicit_reducible]
def l2OpNormedAddCommGroupAux : NormedAddCommGroup (Matrix m n 𝕜) :=
@NormedAddCommGroup.induced ((Matrix m n 𝕜) ≃ₗ[𝕜] (EuclideanSpace 𝕜 n →L[𝕜] EuclideanSpace 𝕜 m)) _
_ _ _ ContinuousLinearMap.toNormedAddCommGroup.toNormedAddGroup _ _ <|
(toEuclideanLin.trans toContinuousLinearMap).injective
/-- An auxiliary definition used only to construct the true `NormedRing` (and `Metric`) structure
provided by `Matrix.instMetricSpaceL2Op` and `Matrix.instNormedRingL2Op`. -/
@[implicit_reducible]
def l2OpNormedRingAux : NormedRing (Matrix n n 𝕜) :=
@NormedRing.induced ((Matrix n n 𝕜) ≃⋆ₐ[𝕜] (EuclideanSpace 𝕜 n →L[𝕜] EuclideanSpace 𝕜 n)) _
_ _ _ ContinuousLinearMap.toNormedRing _ _ toEuclideanCLM.injective
open Bornology Filter
open scoped Topology Uniformity
set_option backward.isDefEq.respectTransparency false in
/-- The metric on `Matrix m n 𝕜` arising from the operator norm given by the identification with
(continuous) linear maps of `EuclideanSpace`. -/
@[instance_reducible]
def instL2OpMetricSpace : MetricSpace (Matrix m n 𝕜) := by
/- We first replace the topology so that we can automatically replace the uniformity using
`IsUniformAddGroup.toUniformSpace_eq`. -/
letI normed_add_comm_group : NormedAddCommGroup (Matrix m n 𝕜) :=
{ l2OpNormedAddCommGroupAux.replaceTopology <|
(toEuclideanLin (𝕜 := 𝕜) (m := m) (n := n)).trans toContinuousLinearMap
|>.toContinuousLinearEquiv.toHomeomorph.isInducing.eq_induced with
norm := l2OpNormedAddCommGroupAux.norm
dist_eq := l2OpNormedAddCommGroupAux.dist_eq }
exact normed_add_comm_group.replaceUniformity <| by
congr
rw [← @IsUniformAddGroup.rightUniformSpace_eq _ (Matrix.instUniformSpace m n 𝕜) _ _]
rw [@IsUniformAddGroup.rightUniformSpace_eq _ PseudoEMetricSpace.toUniformSpace _ _]
scoped[Matrix.Norms.L2Operator] attribute [instance] Matrix.instL2OpMetricSpace
open scoped Matrix.Norms.L2Operator
/-- The norm structure on `Matrix m n 𝕜` arising from the operator norm given by the identification
with (continuous) linear maps of `EuclideanSpace`. -/
@[instance_reducible]
def instL2OpNormedAddCommGroup : NormedAddCommGroup (Matrix m n 𝕜) where
norm := l2OpNormedAddCommGroupAux.norm
dist_eq := l2OpNormedAddCommGroupAux.dist_eq
scoped[Matrix.Norms.L2Operator] attribute [instance] Matrix.instL2OpNormedAddCommGroup
lemma l2_opNorm_def (A : Matrix m n 𝕜) :
‖A‖ = ‖(toEuclideanLin (𝕜 := 𝕜) (m := m) (n := n)).trans toContinuousLinearMap A‖ := rfl
lemma l2_opNNNorm_def (A : Matrix m n 𝕜) :
‖A‖₊ = ‖(toEuclideanLin (𝕜 := 𝕜) (m := m) (n := n)).trans toContinuousLinearMap A‖₊ := rfl
lemma l2_opNorm_conjTranspose [DecidableEq m] (A : Matrix m n 𝕜) : ‖Aᴴ‖ = ‖A‖ := by
rw [l2_opNorm_def, toEuclideanLin_eq_toLin_orthonormal, LinearEquiv.trans_apply,
toLin_conjTranspose, adjoint_toContinuousLinearMap]
exact ContinuousLinearMap.adjoint.norm_map _
lemma l2_opNNNorm_conjTranspose [DecidableEq m] (A : Matrix m n 𝕜) : ‖Aᴴ‖₊ = ‖A‖₊ :=
Subtype.ext <| l2_opNorm_conjTranspose _
lemma l2_opNorm_conjTranspose_mul_self (A : Matrix m n 𝕜) : ‖Aᴴ * A‖ = ‖A‖ * ‖A‖ := by
classical
rw [l2_opNorm_def, toEuclideanLin_eq_toLin_orthonormal, LinearEquiv.trans_apply,
Matrix.toLin_mul (v₂ := (EuclideanSpace.basisFun m 𝕜).toBasis), toLin_conjTranspose]
exact ContinuousLinearMap.norm_adjoint_comp_self _
lemma l2_opNNNorm_conjTranspose_mul_self (A : Matrix m n 𝕜) : ‖Aᴴ * A‖₊ = ‖A‖₊ * ‖A‖₊ :=
Subtype.ext <| l2_opNorm_conjTranspose_mul_self _
-- note: with only a type ascription in the left-hand side, Lean picks the wrong norm.
lemma l2_opNorm_mulVec (A : Matrix m n 𝕜) (x : EuclideanSpace 𝕜 n) :
‖(EuclideanSpace.equiv m 𝕜).symm <| A *ᵥ x‖ ≤ ‖A‖ * ‖x‖ :=
toEuclideanLin (n := n) (m := m) (𝕜 := 𝕜) |>.trans toContinuousLinearMap A |>.le_opNorm x
lemma l2_opNNNorm_mulVec (A : Matrix m n 𝕜) (x : EuclideanSpace 𝕜 n) :
‖(EuclideanSpace.equiv m 𝕜).symm <| A *ᵥ x‖₊ ≤ ‖A‖₊ * ‖x‖₊ :=
A.l2_opNorm_mulVec x
lemma l2_opNorm_mul (A : Matrix m n 𝕜) (B : Matrix n l 𝕜) :
‖A * B‖ ≤ ‖A‖ * ‖B‖ := by
simp only [l2_opNorm_def]
have := (toEuclideanLin (n := n) (m := m) (𝕜 := 𝕜) ≪≫ₗ toContinuousLinearMap) A
|>.opNorm_comp_le <| (toEuclideanLin (n := l) (m := n) (𝕜 := 𝕜) ≪≫ₗ toContinuousLinearMap) B
convert this
ext1 x
exact congr(toLp 2 ($(Matrix.toLin'_mul A B) x))
lemma l2_opNNNorm_mul (A : Matrix m n 𝕜) (B : Matrix n l 𝕜) : ‖A * B‖₊ ≤ ‖A‖₊ * ‖B‖₊ :=
l2_opNorm_mul A B
lemma l2_opNorm_toEuclideanCLM (A : Matrix n n 𝕜) :
‖toEuclideanCLM (n := n) (𝕜 := 𝕜) A‖ = ‖A‖ := rfl
@[simp]
lemma l2_opNorm_diagonal (v : n → 𝕜) : ‖(diagonal v : Matrix n n 𝕜)‖ = ‖v‖ := by
set T := toEuclideanCLM (n := n) (𝕜 := 𝕜) (diagonal v)
rw [← l2_opNorm_toEuclideanCLM]
refine le_antisymm ?_ ?_
· refine T.opNorm_le_bound (norm_nonneg _) fun x ↦ ?_
refine (sq_le_sq₀ (by positivity) (by positivity)).mp ?_
simp only [(T x).norm_sq_eq, ofLp_toEuclideanCLM, mulVec_diagonal, norm_mul, T]
calc _ ≤ _ := Finset.sum_le_sum fun i _ ↦ by grw [mul_pow, norm_le_pi_norm v i]
_ = _ := by simp [mul_pow, EuclideanSpace.norm_sq_eq x, Finset.mul_sum]
· refine (pi_norm_le_iff_of_nonneg (norm_nonneg T)).mpr fun i ↦ ?_
calc _ = ‖T (toLp 2 (Pi.single i (1 : 𝕜)))‖ := by
rw [toEuclideanCLM_toLp (diagonal v) (Pi.single i (1 : 𝕜))]
simp
_ ≤ _ := by grw [T.le_opNorm]; simp
@[simp]
lemma l2_opNNNorm_diagonal (v : n → 𝕜) : ‖(diagonal v : Matrix n n 𝕜)‖₊ = ‖v‖₊ :=
Subtype.ext <| l2_opNorm_diagonal (n := n) (𝕜 := 𝕜) v
/-- The normed algebra structure on `Matrix n n 𝕜` arising from the operator norm given by the
identification with (continuous) linear endomorphisms of `EuclideanSpace 𝕜 n`. -/
@[instance_reducible]
def instL2OpNormedSpace : NormedSpace 𝕜 (Matrix m n 𝕜) where
norm_smul_le r x := by
rw [l2_opNorm_def, map_smul]
exact norm_smul_le r ((toEuclideanLin (𝕜 := 𝕜) (m := m) (n := n)).trans toContinuousLinearMap x)
scoped[Matrix.Norms.L2Operator] attribute [instance] Matrix.instL2OpNormedSpace
/-- The normed ring structure on `Matrix n n 𝕜` arising from the operator norm given by the
identification with (continuous) linear endomorphisms of `EuclideanSpace 𝕜 n`. -/
@[instance_reducible]
def instL2OpNormedRing : NormedRing (Matrix n n 𝕜) where
dist_eq := l2OpNormedRingAux.dist_eq
norm_mul_le := l2OpNormedRingAux.norm_mul_le
scoped[Matrix.Norms.L2Operator] attribute [instance] Matrix.instL2OpNormedRing
/-- This is the same as `Matrix.l2_opNorm_def`, but with a more bundled RHS for square matrices. -/
lemma cstar_norm_def (A : Matrix n n 𝕜) : ‖A‖ = ‖toEuclideanCLM (n := n) (𝕜 := 𝕜) A‖ := rfl
/-- This is the same as `Matrix.l2_opNNNorm_def`, but with a more bundled RHS for square
matrices. -/
lemma cstar_nnnorm_def (A : Matrix n n 𝕜) : ‖A‖₊ = ‖toEuclideanCLM (n := n) (𝕜 := 𝕜) A‖₊ := rfl
/-- The normed algebra structure on `Matrix n n 𝕜` arising from the operator norm given by the
identification with (continuous) linear endomorphisms of `EuclideanSpace 𝕜 n`. -/
@[instance_reducible]
def instL2OpNormedAlgebra : NormedAlgebra 𝕜 (Matrix n n 𝕜) where
norm_smul_le := norm_smul_le
scoped[Matrix.Norms.L2Operator] attribute [instance] Matrix.instL2OpNormedAlgebra
/-- The operator norm on `Matrix n n 𝕜` given by the identification with (continuous) linear
endomorphisms of `EuclideanSpace 𝕜 n` makes it into a `L2OpRing`. -/
lemma instCStarRing : CStarRing (Matrix n n 𝕜) where
norm_mul_self_le M := le_of_eq <| Eq.symm <| l2_opNorm_conjTranspose_mul_self M
scoped[Matrix.Norms.L2Operator] attribute [instance] Matrix.instCStarRing
end Matrix
end L2OpNorm