-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQuaternionicQM.lean
More file actions
302 lines (264 loc) Β· 15.5 KB
/
Copy pathQuaternionicQM.lean
File metadata and controls
302 lines (264 loc) Β· 15.5 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
297
298
299
300
301
302
import Jordan.JordanAlgebra
import Jordan.FormallyReal
import Jordan.MooreDeterminant
import Mathlib.Algebra.Quaternion
import Mathlib.Data.Matrix.Basic
import Mathlib.LinearAlgebra.Matrix.ConjTranspose
import Mathlib.LinearAlgebra.Matrix.Trace
import Mathlib.Algebra.Star.UnitaryStarAlgAut
import Mathlib.Algebra.Star.SelfAdjoint
import Mathlib.Tactic.LinearCombination
/-!
# The Jordan algebra of quaternionic Hermitian matrices over a general base ring
The `n Γ n` quaternionic Hermitian matrices form a Jordan algebra under the symmetrized product
`A β B = (A * B + B * A) / 2`. As with `ComplexQM`, the only thing this needs from `β` is `2`
being invertible; the quaternions themselves are just `R` adjoined `i, j` (with `k := i * j`)
satisfying `i * i = cβ + cβ * i`, `j * j = cβ`, `j * i = cβ * j - k` (Mathlib's
`QuaternionAlgebra R cβ cβ cβ`, notation `β[R, cβ, cβ, cβ]`), for *any* `cβ cβ cβ : R` -- not just
Hamilton's `cβ = cβ = -1, cβ = 0` (notation `β[R]`). We work over any commutative ring `R` with `2`
invertible, using the associative (non-commutative!) `R`-algebra `Matrix n n β[R, cβ, cβ, cβ]`
with the conjugate-transpose involution (quaternion conjugate on entries). Specializing
`R := β`, `cβ := -1`, `cβ := 0`, `cβ := -1` recovers the classical example.
Note `cβ` only deforms the `i`-square, not the `j`-square: `i * i = cβ + cβ * i` is exactly the
same "complete the square" generalization as `QuadraticAlgebra R a b`'s `i ^ 2 = a + b * i`
(needed so the construction still works in characteristic 2, where halving the linear term isn't
possible), applied to build the `i`-direction quadratic extension that the quaternions are then
doubled from; the `j`-extension is a plain Cayley-Dickson doubling step with no such obstruction.
This is also why `star`'s correction term `cβ * star z.imI` below only touches the `i`-component:
it's exactly the asymmetry already present in the multiplication table, not a separate one.
As in `ComplexQM`, we ask `R` to have a trivial star (it plays the role of `β`, the field fixed by
quaternion conjugation, and could be a proper subring such as `β`). Mathlib's
`QuaternionAlgebra.star` is defined purely from `R`'s ring operations and never looks at any
`Star R` instance; `star_eq_conj_components` records that it agrees with the "conjugate every
component via `R`'s own star" formula precisely because that star is trivial.
-/
open scoped Quaternion
namespace QuaternionicQM
variable (R : Type*) [CommRing R] [StarRing R] [TrivialStar R] [Invertible (2 : R)]
variable (n : Type*) [Fintype n] [DecidableEq n]
section
variable (cβ cβ cβ : R)
omit [Invertible (2 : R)] in
theorem star_eq_conj_components (z : β[R, cβ, cβ, cβ]) :
star z = β¨star z.re + cβ * star z.imI, -star z.imI, -star z.imJ, -star z.imKβ© := by
apply QuaternionAlgebra.ext <;> simp [star_trivial]
omit [Invertible (2 : R)] in
set_option linter.unusedSectionVars false in
theorem star_algebraMap_eq (r : R) :
star (algebraMap R (Matrix n n β[R, cβ, cβ, cβ]) r) =
algebraMap R (Matrix n n β[R, cβ, cβ, cβ]) r := by
ext i j : 1
rw [Matrix.star_apply, Matrix.algebraMap_matrix_apply, Matrix.algebraMap_matrix_apply]
by_cases h : i = j
Β· subst h
apply QuaternionAlgebra.ext <;> simp
Β· simp [h, Ne.symm h]
/-- The `n Γ n` quaternionic Hermitian matrices over `R`, as an `R`-Jordan algebra. -/
def hermitianMatrices : Submodule R (Matrix n n β[R, cβ, cβ, cβ]) :=
HermitianJordan.hermitian (star_algebraMap_eq R n cβ cβ cβ)
noncomputable instance : JordanAlgebra R (hermitianMatrices R n cβ cβ cβ) :=
HermitianJordan.ofInvolutiveAlgebra (star_algebraMap_eq R n cβ cβ cβ)
end
/-! ### Formal reality
Over an ordered `R`, restricting to `cβ = 0` (no loss of generality: `2` invertible already lets
us complete the square, as elsewhere in this file) with `cβ < 0` and `cβ < 0` (generalizing
`cβ = cβ = -1`, genuine Hamilton quaternions) making the norm form positive-definite, the `n x n`
quaternionic Hermitian matrices are formally real. -/
section FormallyReal
variable [LinearOrder R] [IsStrictOrderedRing R] (cβ cβ : R)
omit [StarRing R] [TrivialStar R] [Invertible (2 : R)] [LinearOrder R] [IsStrictOrderedRing R] in
/-- The "norm" of a quaternion (with `cβ = 0`), as the real part of `q * star q`: a pure ring
identity, no positivity needed. -/
private theorem mul_star_re_eq (q : β[R, cβ, 0, cβ]) :
(q * star q).re =
q.re * q.re - cβ * q.imI * q.imI - cβ * q.imJ * q.imJ + cβ * cβ * q.imK * q.imK := by
show q.re * (star q).re + cβ * q.imI * (star q).imI + cβ * q.imJ * (star q).imJ +
(0 : R) * cβ * q.imJ * (star q).imK - cβ * cβ * q.imK * (star q).imK = _
simp only [QuaternionAlgebra.re_star, QuaternionAlgebra.imI_star, QuaternionAlgebra.imJ_star,
QuaternionAlgebra.imK_star]
ring
omit [StarRing R] [TrivialStar R] [Invertible (2 : R)] in
private theorem norm_nonneg (hcβ : cβ < 0) (hcβ : cβ < 0) (q : β[R, cβ, 0, cβ]) :
0 β€ (q * star q).re := by
rw [mul_star_re_eq]
have h1 : 0 β€ q.re * q.re := mul_self_nonneg _
have h2 : 0 β€ -cβ * (q.imI * q.imI) := mul_nonneg (by linarith) (mul_self_nonneg _)
have h3 : 0 β€ -cβ * (q.imJ * q.imJ) := mul_nonneg (by linarith) (mul_self_nonneg _)
have h4 : 0 β€ cβ * cβ * (q.imK * q.imK) :=
mul_nonneg (mul_pos_of_neg_of_neg hcβ hcβ).le (mul_self_nonneg _)
nlinarith
omit [StarRing R] [TrivialStar R] [Invertible (2 : R)] in
private theorem norm_eq_zero_iff (hcβ : cβ < 0) (hcβ : cβ < 0) (q : β[R, cβ, 0, cβ]) :
(q * star q).re = 0 β q = 0 := by
refine β¨fun hq => ?_, fun hq => by simp [hq]β©
rw [mul_star_re_eq] at hq
have h1 : 0 β€ q.re * q.re := mul_self_nonneg _
have h2 : 0 β€ -cβ * (q.imI * q.imI) := mul_nonneg (by linarith) (mul_self_nonneg _)
have h3 : 0 β€ -cβ * (q.imJ * q.imJ) := mul_nonneg (by linarith) (mul_self_nonneg _)
have h4 : 0 β€ cβ * cβ * (q.imK * q.imK) :=
mul_nonneg (mul_pos_of_neg_of_neg hcβ hcβ).le (mul_self_nonneg _)
have hre : q.re * q.re = 0 := by nlinarith
have hI : -cβ * (q.imI * q.imI) = 0 := by nlinarith
have hJ : -cβ * (q.imJ * q.imJ) = 0 := by nlinarith
have hK : cβ * cβ * (q.imK * q.imK) = 0 := by nlinarith
have hre0 : q.re = 0 := mul_self_eq_zero.mp hre
have hI0 : q.imI = 0 := by
rcases mul_eq_zero.mp hI with h | h
Β· exact absurd h (by linarith)
Β· exact mul_self_eq_zero.mp h
have hJ0 : q.imJ = 0 := by
rcases mul_eq_zero.mp hJ with h | h
Β· exact absurd h (by linarith)
Β· exact mul_self_eq_zero.mp h
have hK0 : q.imK = 0 := by
rcases mul_eq_zero.mp hK with h | h
Β· exact absurd h (by nlinarith)
Β· exact mul_self_eq_zero.mp h
apply QuaternionAlgebra.ext <;> simp [hre0, hI0, hJ0, hK0]
omit [Invertible (2 : R)] [DecidableEq n] [LinearOrder R] [IsStrictOrderedRing R] in
set_option linter.unusedSectionVars false in
/-- The trace of the Jordan square of a Hermitian matrix corresponds to the sum of norms of its
entries (as a scalar -- `Matrix.trace (A * A)` lands in `β[R, cβ, 0, cβ]`, but it equals the image
of the `R`-valued sum of norms under `algebraMap`). The `[StarRing R] [TrivialStar R]` hypotheses
aren't used by the proof, but are kept as an explicit obligation: they're what justify reading
`star A = A` as the genuine "Hermitian" condition in the first place. -/
theorem trace_mul_self_eq_sum_norm (A : Matrix n n β[R, cβ, 0, cβ]) (hA : star A = A) :
Matrix.trace (A * A) = algebraMap R β[R, cβ, 0, cβ] (β p, β q, (A p q * star (A p q)).re) := by
simp only [Matrix.trace, Matrix.diag_apply, Matrix.mul_apply, map_sum]
refine Finset.sum_congr rfl fun p _ => Finset.sum_congr rfl fun q _ => ?_
have h : A q p = star (A p q) := by
have h' := congrFun (congrFun hA p) q
simp only [Matrix.star_apply] at h'
rw [β h', star_star]
rw [h]
exact QuaternionAlgebra.mul_star_eq_coe _
set_option linter.unusedSectionVars false in
/-- The `[StarRing R] [TrivialStar R]` hypotheses aren't used directly by this proof, but are kept
as an explicit obligation: they're what justify `hermitianMatrices` meaning genuine "quaternionic
Hermitian matrices" at all (see the file docstring). -/
theorem isFormallyReal (hcβ : cβ < 0) (hcβ : cβ < 0) :
IsFormallyReal R (hermitianMatrices R n cβ 0 cβ) := by
refine β¨fun {ΞΉ} _ X hX i => ?_β©
have hsum1 : β k, (X k).1 * (X k).1 = 0 := by
have heq : β k, (X k).1 * (X k).1 = (β k, X k * X k : hermitianMatrices R n cβ 0 cβ).1 := by
rw [Submodule.coe_sum]
exact Finset.sum_congr rfl
fun k _ => (HermitianJordan.mul_self_eq (star_algebraMap_eq R n cβ 0 cβ) (X k)).symm
rw [heq]
exact congrArg Subtype.val hX
have htraceR : β k, β p, β q, ((X k).1 p q * star ((X k).1 p q)).re = 0 := by
have htrace : β k, Matrix.trace ((X k).1 * (X k).1) = 0 := by
rw [β Matrix.trace_sum, hsum1, Matrix.trace_zero]
have h2 : algebraMap R β[R, cβ, 0, cβ]
(β k, β p, β q, ((X k).1 p q * star ((X k).1 p q)).re) = 0 := by
rw [map_sum]
rw [Finset.sum_congr rfl
fun k (_ : k β Finset.univ) =>
(trace_mul_self_eq_sum_norm R n cβ cβ (X k).1 (X k).2).symm]
exact htrace
have h3 := congrArg QuaternionAlgebra.re h2
set internal := (β k, β p, β q, ((X k : Matrix n n β[R,cβ,cβ]) p q * star ((X k : Matrix n n β[R,cβ,cβ]) p q)).re)
rw [QuaternionAlgebra.algebraMap_eq] at h3
simpa using h3
have hnn : β k β (Finset.univ : Finset ΞΉ),
0 β€ β p, β q, ((X k).1 p q * star ((X k).1 p q)).re := by
intro k _
exact Finset.sum_nonneg fun p _ => Finset.sum_nonneg fun q _ => norm_nonneg R cβ cβ hcβ hcβ _
have heach : β p, β q, ((X i).1 p q * star ((X i).1 p q)).re = 0 :=
(Finset.sum_eq_zero_iff_of_nonneg hnn).mp htraceR i (Finset.mem_univ i)
have hpq : β p β (Finset.univ : Finset n),
β q, ((X i).1 p q * star ((X i).1 p q)).re = 0 :=
(Finset.sum_eq_zero_iff_of_nonneg
(fun p _ => Finset.sum_nonneg fun q _ => norm_nonneg R cβ cβ hcβ hcβ _)).mp heach
apply Subtype.ext
apply Matrix.ext
intro p q
have hq := (Finset.sum_eq_zero_iff_of_nonneg
(fun q _ => norm_nonneg R cβ cβ hcβ hcβ _)).mp (hpq p (Finset.mem_univ p)) q (Finset.mem_univ q)
exact (norm_eq_zero_iff R cβ cβ hcβ hcβ _).mp hq
/-! #### Generic trace and determinant
The ordinary matrix trace lands directly in `R` after reading off `.re` (the trace of a Hermitian
matrix is genuinely real, though that isn't proved here, matching `ComplexQM`'s house style). The
determinant, however, has no `Matrix.det` to fall back on at all -- `β[R, cβ, 0, cβ]` is
non-commutative -- so it's built from `MooreDeterminant.mooreDetSum` instead: a concrete,
`R`-linear (in the scaling-degree sense of `det_smul`) alternating sum over permutations, read off
via `.re` exactly as the trace is. -/
variable [LinearOrder n]
/-- The `n x n` quaternionic Hermitian matrices have a generic trace and determinant of rank
`Fintype.card n`: the real parts of the ordinary matrix trace and of `mooreDetSum`. -/
noncomputable def detTrace (hcβ : cβ < 0) (hcβ : cβ < 0) :
@IsFormallyRealDetTrace R (hermitianMatrices R n cβ 0 cβ) _ _
(isFormallyReal R n cβ cβ hcβ hcβ) := by
letI := isFormallyReal R n cβ cβ hcβ hcβ
exact
{ rank := Fintype.card n
trace := (QuaternionAlgebra.reβ cβ 0 cβ).comp
((Matrix.traceLinearMap n R β[R, cβ, 0, cβ]).comp (hermitianMatrices R n cβ 0 cβ).subtype)
det := fun x => (mooreDetSum x.1).re
det_smul := fun r x => by
show (mooreDetSum (r β’ x.1)).re = r ^ Fintype.card n β’ (mooreDetSum x.1).re
rw [mooreDetSum_smul, QuaternionAlgebra.re_smul]
trace_one := by
show (Matrix.trace (1 : Matrix n n β[R, cβ, 0, cβ])).re = (Fintype.card n : R)
rw [Matrix.trace_one]
norm_cast
det_one := by
show (mooreDetSum (1 : Matrix n n β[R, cβ, 0, cβ])).re = 1
rw [mooreDetSum_one]
rfl }
end FormallyReal
/-! ### Towards conjugation acting on the imaginary part
Over `β`, conjugating Hamilton's quaternions by a `q` with `q * star q = 1` (`x β¦ q * x * star q`)
is an algebra automorphism whose restriction to the "pure imaginary" part `{x | x.re = 0}` (the
span of `i, j, k`) is an honest rotation, i.e. lands in `SO(3)` -- the classical fact that such
quaternions double-cover `SO(3)`, underlying hyperkΓ€hler-rotation arguments. `SO(3)` is meaningless
over a general commutative ring `R` (it's a real Lie group, defined using the positive-definite
real inner product), but the algebraic skeleton underneath it -- conjugation by such a `q`
preserving the pure imaginary part -- is purely ring/star-algebra theoretic and makes sense for any
`R`. That skeleton is all this section records.
Specifically: conjugation by any `q` with `q * star q = 1` (what Mathlib calls `unitary`, a name
really suited to the `β`/`β` case rather than a general star ring) is automatically a `*`-algebra
automorphism (`Unitary.conjStarAlgAut`, true in any star ring, nothing quaternion-specific about
it), and any `*`-algebra automorphism preserves the skew-adjoint elements `{x | star x = -x}`
(again completely general). For `cβ = 0`, the skew-adjoint elements of `β[R, cβ, 0, cβ]` are
exactly the pure imaginary ones, so this conjugation does preserve that subspace. We make no claim
about *what* this action is (it's only literally a rotation when `R = β`), nor whether every
automorphism of the imaginary part arises this way. -/
section Rotation
variable {R} (cβ cβ : R)
omit [TrivialStar R] [Invertible (2 : R)] in
/-- Any `*`-algebra automorphism (indeed, any additive `star`-commuting map) sends skew-adjoint
elements to skew-adjoint elements. -/
theorem map_mem_skewAdjoint {A : Type*} [Ring A] [StarRing A] {F : Type*} [FunLike F A A]
[RingHomClass F A A] [StarHomClass F A A] (f : F) {x : A} (hx : x β skewAdjoint A) :
f x β skewAdjoint A := by
rw [skewAdjoint.mem_iff] at hx β’
rw [β map_star, hx, map_neg]
omit [StarRing R] [TrivialStar R] in
/-- When `cβ = 0`, the skew-adjoint quaternions are exactly the pure imaginary ones. -/
theorem mem_skewAdjoint_iff_re_eq_zero (z : β[R, cβ, 0, cβ]) :
z β skewAdjoint β[R, cβ, 0, cβ] β z.re = 0 := by
rw [skewAdjoint.mem_iff]
constructor
Β· intro h
have hre : z.re = -z.re := by simpa using congrArg QuaternionAlgebra.re h
have h2 : (2 : R) * z.re = 0 := by linear_combination hre
calc z.re = (β
(2 : R) * 2) * z.re := by rw [invOf_mul_self, one_mul]
_ = β
(2 : R) * ((2 : R) * z.re) := by rw [mul_assoc]
_ = 0 := by rw [h2, mul_zero]
Β· intro h
apply QuaternionAlgebra.ext <;> simp [h]
omit [TrivialStar R] [Invertible (2 : R)] in
/-- The group homomorphism sending `q` (with `q * star q = 1`) to the automorphism of
`β[R, cβ, 0, cβ]` given by conjugating by it, `x β¦ q * x * star q`. -/
def conjAut : unitary β[R, cβ, 0, cβ] β* (β[R, cβ, 0, cβ] βββ[R] β[R, cβ, 0, cβ]) :=
Unitary.conjStarAlgAut R β[R, cβ, 0, cβ]
omit [StarRing R] [TrivialStar R] [Invertible (2 : R)] in
/-- Conjugation by a `q` with `q * star q = 1` preserves the pure imaginary part of
`β[R, cβ, 0, cβ]`. -/
theorem conjAut_mem_skewAdjoint (q : unitary β[R, cβ, 0, cβ]) {x : β[R, cβ, 0, cβ]}
(hx : x β skewAdjoint β[R, cβ, 0, cβ]) :
conjAut cβ cβ q x β skewAdjoint β[R, cβ, 0, cβ] :=
map_mem_skewAdjoint (conjAut cβ cβ q) hx
end Rotation
end QuaternionicQM