Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 5b527bd

Browse files
committed
refactor(linear_algebra/quadratic_form): split file (#9781)
The section on quadratic forms over complex numbers required pulling in the developing of the complex power function, which significantly increases the import depth. Splitting this file allows `clifford_algebra` to be compiled much earlier. Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
1 parent 27a777b commit 5b527bd

File tree

4 files changed

+180
-139
lines changed

4 files changed

+180
-139
lines changed

src/linear_algebra/clifford_algebra/basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Authors: Eric Wieser, Utensil Song
77
import algebra.ring_quot
88
import linear_algebra.tensor_algebra
99
import linear_algebra.exterior_algebra
10-
import linear_algebra.quadratic_form
10+
import linear_algebra.quadratic_form.basic
1111

1212
/-!
1313
# Clifford Algebras

src/linear_algebra/quadratic_form.lean renamed to src/linear_algebra/quadratic_form/basic.lean

Lines changed: 0 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import algebra.invertible
88
import linear_algebra.bilinear_form
99
import linear_algebra.matrix.determinant
1010
import linear_algebra.special_linear_group
11-
import analysis.special_functions.pow
12-
import data.real.sign
1311

1412
/-!
1513
# Quadratic forms
@@ -941,140 +939,4 @@ begin
941939
exact ⟨λ i, units.mk0 _ (hv₂ i), ⟨Q.isometry_weighted_sum_squares v hv₁⟩⟩,
942940
end
943941

944-
section complex
945-
946-
/-- The isometry between a weighted sum of squares on the complex numbers and the
947-
sum of squares, i.e. `weighted_sum_squares` with weights 1 or 0. -/
948-
noncomputable def isometry_sum_squares [decidable_eq ι] (w' : ι → ℂ) :
949-
isometry (weighted_sum_squares ℂ w')
950-
(weighted_sum_squares ℂ (λ i, if w' i = 0 then 0 else 1 : ι → ℂ)) :=
951-
begin
952-
let w := λ i, if h : w' i = 0 then (1 : units ℂ) else units.mk0 (w' i) h,
953-
have hw' : ∀ i : ι, (w i : ℂ) ^ - (1 / 2 : ℂ) ≠ 0,
954-
{ intros i hi,
955-
exact (w i).ne_zero ((complex.cpow_eq_zero_iff _ _).1 hi).1 },
956-
convert (weighted_sum_squares ℂ w').isometry_basis_repr
957-
((pi.basis_fun ℂ ι).units_smul (λ i, (is_unit_iff_ne_zero.2 $ hw' i).unit)),
958-
ext1 v,
959-
erw [basis_repr_apply, weighted_sum_squares_apply, weighted_sum_squares_apply],
960-
refine sum_congr rfl (λ j hj, _),
961-
have hsum : (∑ (i : ι), v i • ((is_unit_iff_ne_zero.2 $ hw' i).unit : ℂ) •
962-
(pi.basis_fun ℂ ι) i) j = v j • w j ^ - (1 / 2 : ℂ),
963-
{ rw [finset.sum_apply, sum_eq_single j, pi.basis_fun_apply, is_unit.unit_spec,
964-
linear_map.std_basis_apply, pi.smul_apply, pi.smul_apply, function.update_same,
965-
smul_eq_mul, smul_eq_mul, smul_eq_mul, mul_one],
966-
intros i _ hij,
967-
rw [pi.basis_fun_apply, linear_map.std_basis_apply, pi.smul_apply, pi.smul_apply,
968-
function.update_noteq hij.symm, pi.zero_apply, smul_eq_mul, smul_eq_mul,
969-
mul_zero, mul_zero],
970-
intro hj', exact false.elim (hj' hj) },
971-
simp_rw basis.units_smul_apply,
972-
erw [hsum, smul_eq_mul],
973-
split_ifs,
974-
{ simp only [h, zero_smul, zero_mul]},
975-
have hww' : w' j = w j,
976-
{ simp only [w, dif_neg h, units.coe_mk0] },
977-
simp only [hww', one_mul],
978-
change v j * v j = ↑(w j) * ((v j * ↑(w j) ^ -(1 / 2 : ℂ)) * (v j * ↑(w j) ^ -(1 / 2 : ℂ))),
979-
suffices : v j * v j = w j ^ - (1 / 2 : ℂ) * w j ^ - (1 / 2 : ℂ) * w j * v j * v j,
980-
{ rw [this], ring },
981-
rw [← complex.cpow_add _ _ (w j).ne_zero, show - (1 / 2 : ℂ) + - (1 / 2) = -1, by ring,
982-
complex.cpow_neg_one, inv_mul_cancel (w j).ne_zero, one_mul],
983-
end
984-
985-
/-- The isometry between a weighted sum of squares on the complex numbers and the
986-
sum of squares, i.e. `weighted_sum_squares` with weight `λ i : ι, 1`. -/
987-
noncomputable def isometry_sum_squares_units [decidable_eq ι] (w : ι → units ℂ) :
988-
isometry (weighted_sum_squares ℂ w) (weighted_sum_squares ℂ (1 : ι → ℂ)) :=
989-
begin
990-
have hw1 : (λ i, if (w i : ℂ) = 0 then 0 else 1 : ι → ℂ) = 1,
991-
{ ext i : 1, exact dif_neg (w i).ne_zero },
992-
have := isometry_sum_squares (coe ∘ w),
993-
rw hw1 at this,
994-
exact this,
995-
end
996-
997-
/-- A nondegenerate quadratic form on the complex numbers is equivalent to
998-
the sum of squares, i.e. `weighted_sum_squares` with weight `λ i : ι, 1`. -/
999-
theorem equivalent_sum_squares {M : Type*} [add_comm_group M] [module ℂ M]
1000-
[finite_dimensional ℂ M] (Q : quadratic_form ℂ M) (hQ : (associated Q).nondegenerate) :
1001-
equivalent Q (weighted_sum_squares ℂ (1 : fin (finite_dimensional.finrank ℂ M) → ℂ)) :=
1002-
let ⟨w, ⟨hw₁⟩⟩ := Q.equivalent_weighted_sum_squares_units_of_nondegenerate' hQ in
1003-
⟨hw₁.trans (isometry_sum_squares_units w)⟩
1004-
1005-
end complex
1006-
1007-
section real
1008-
1009-
open real
1010-
1011-
/-- The isometry between a weighted sum of squares with weights `u` on the
1012-
(non-zero) real numbers and the weighted sum of squares with weights `sign ∘ u`. -/
1013-
noncomputable def isometry_sign_weighted_sum_squares
1014-
[decidable_eq ι] (w : ι → ℝ) :
1015-
isometry (weighted_sum_squares ℝ w) (weighted_sum_squares ℝ (sign ∘ w)) :=
1016-
begin
1017-
let u := λ i, if h : w i = 0 then (1 : units ℝ) else units.mk0 (w i) h,
1018-
have hu' : ∀ i : ι, (sign (u i) * u i) ^ - (1 / 2 : ℝ) ≠ 0,
1019-
{ intro i, refine (ne_of_lt (real.rpow_pos_of_pos
1020-
(sign_mul_pos_of_ne_zero _ $ units.ne_zero _) _)).symm},
1021-
convert ((weighted_sum_squares ℝ w).isometry_basis_repr
1022-
((pi.basis_fun ℝ ι).units_smul (λ i, (is_unit_iff_ne_zero.2 $ hu' i).unit))),
1023-
ext1 v,
1024-
rw [basis_repr_apply, weighted_sum_squares_apply, weighted_sum_squares_apply],
1025-
refine sum_congr rfl (λ j hj, _),
1026-
have hsum : (∑ (i : ι), v i • ((is_unit_iff_ne_zero.2 $ hu' i).unit : ℝ) •
1027-
(pi.basis_fun ℝ ι) i) j = v j • (sign (u j) * u j) ^ - (1 / 2 : ℝ),
1028-
{ rw [finset.sum_apply, sum_eq_single j, pi.basis_fun_apply, is_unit.unit_spec,
1029-
linear_map.std_basis_apply, pi.smul_apply, pi.smul_apply, function.update_same,
1030-
smul_eq_mul, smul_eq_mul, smul_eq_mul, mul_one],
1031-
intros i _ hij,
1032-
rw [pi.basis_fun_apply, linear_map.std_basis_apply, pi.smul_apply, pi.smul_apply,
1033-
function.update_noteq hij.symm, pi.zero_apply, smul_eq_mul, smul_eq_mul,
1034-
mul_zero, mul_zero],
1035-
intro hj', exact false.elim (hj' hj) },
1036-
simp_rw basis.units_smul_apply,
1037-
erw [hsum],
1038-
simp only [u, function.comp, smul_eq_mul],
1039-
split_ifs,
1040-
{ simp only [h, zero_smul, zero_mul, sign_zero] },
1041-
have hwu : w j = u j,
1042-
{ simp only [u, dif_neg h, units.coe_mk0] },
1043-
simp only [hwu, units.coe_mk0],
1044-
suffices : (u j : ℝ).sign * v j * v j = (sign (u j) * u j) ^ - (1 / 2 : ℝ) *
1045-
(sign (u j) * u j) ^ - (1 / 2 : ℝ) * u j * v j * v j,
1046-
{ erw [← mul_assoc, this], ring },
1047-
rw [← real.rpow_add (sign_mul_pos_of_ne_zero _ $ units.ne_zero _),
1048-
show - (1 / 2 : ℝ) + - (1 / 2) = -1, by ring, real.rpow_neg_one, mul_inv₀,
1049-
inv_sign, mul_assoc (sign (u j)) (u j)⁻¹,
1050-
inv_mul_cancel (units.ne_zero _), mul_one],
1051-
apply_instance
1052-
end
1053-
1054-
/-- **Sylvester's law of inertia**: A nondegenerate real quadratic form is equivalent to a weighted
1055-
sum of squares with the weights being ±1. -/
1056-
theorem equivalent_one_neg_one_weighted_sum_squared
1057-
{M : Type*} [add_comm_group M] [module ℝ M] [finite_dimensional ℝ M]
1058-
(Q : quadratic_form ℝ M) (hQ : (associated Q).nondegenerate) :
1059-
∃ w : fin (finite_dimensional.finrank ℝ M) → ℝ,
1060-
(∀ i, w i = -1 ∨ w i = 1) ∧ equivalent Q (weighted_sum_squares ℝ w) :=
1061-
let ⟨w, ⟨hw₁⟩⟩ := Q.equivalent_weighted_sum_squares_units_of_nondegenerate' hQ in
1062-
⟨sign ∘ coe ∘ w,
1063-
λ i, sign_apply_eq_of_ne_zero (w i) (w i).ne_zero,
1064-
⟨hw₁.trans (isometry_sign_weighted_sum_squares (coe ∘ w))⟩⟩
1065-
1066-
/-- **Sylvester's law of inertia**: A real quadratic form is equivalent to a weighted
1067-
sum of squares with the weights being ±1 or 0. -/
1068-
theorem equivalent_one_zero_neg_one_weighted_sum_squared
1069-
{M : Type*} [add_comm_group M] [module ℝ M] [finite_dimensional ℝ M]
1070-
(Q : quadratic_form ℝ M) :
1071-
∃ w : fin (finite_dimensional.finrank ℝ M) → ℝ,
1072-
(∀ i, w i = -1 ∨ w i = 0 ∨ w i = 1) ∧ equivalent Q (weighted_sum_squares ℝ w) :=
1073-
let ⟨w, ⟨hw₁⟩⟩ := Q.equivalent_weighted_sum_squares in
1074-
⟨sign ∘ coe ∘ w,
1075-
λ i, sign_apply_eq (w i),
1076-
⟨hw₁.trans (isometry_sign_weighted_sum_squares w)⟩⟩
1077-
1078-
end real
1079-
1080942
end quadratic_form
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/-
2+
Copyright (c) 2020 Anne Baanen. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Anne Baanen, Kexing Ying, Eric Wieser
5+
-/
6+
import linear_algebra.quadratic_form.basic
7+
import analysis.special_functions.pow
8+
9+
/-!
10+
# Quadratic forms over the complex numbers
11+
12+
`equivalent_sum_squares`: A nondegenerate quadratic form over the complex numbers is equivalent to
13+
a sum of squares.
14+
15+
-/
16+
17+
namespace quadratic_form
18+
19+
open_locale big_operators
20+
open finset
21+
22+
variables {ι : Type*} [fintype ι]
23+
24+
/-- The isometry between a weighted sum of squares on the complex numbers and the
25+
sum of squares, i.e. `weighted_sum_squares` with weights 1 or 0. -/
26+
noncomputable def isometry_sum_squares [decidable_eq ι] (w' : ι → ℂ) :
27+
isometry (weighted_sum_squares ℂ w')
28+
(weighted_sum_squares ℂ (λ i, if w' i = 0 then 0 else 1 : ι → ℂ)) :=
29+
begin
30+
let w := λ i, if h : w' i = 0 then (1 : units ℂ) else units.mk0 (w' i) h,
31+
have hw' : ∀ i : ι, (w i : ℂ) ^ - (1 / 2 : ℂ) ≠ 0,
32+
{ intros i hi,
33+
exact (w i).ne_zero ((complex.cpow_eq_zero_iff _ _).1 hi).1 },
34+
convert (weighted_sum_squares ℂ w').isometry_basis_repr
35+
((pi.basis_fun ℂ ι).units_smul (λ i, (is_unit_iff_ne_zero.2 $ hw' i).unit)),
36+
ext1 v,
37+
erw [basis_repr_apply, weighted_sum_squares_apply, weighted_sum_squares_apply],
38+
refine sum_congr rfl (λ j hj, _),
39+
have hsum : (∑ (i : ι), v i • ((is_unit_iff_ne_zero.2 $ hw' i).unit : ℂ) •
40+
(pi.basis_fun ℂ ι) i) j = v j • w j ^ - (1 / 2 : ℂ),
41+
{ rw [finset.sum_apply, sum_eq_single j, pi.basis_fun_apply, is_unit.unit_spec,
42+
linear_map.std_basis_apply, pi.smul_apply, pi.smul_apply, function.update_same,
43+
smul_eq_mul, smul_eq_mul, smul_eq_mul, mul_one],
44+
intros i _ hij,
45+
rw [pi.basis_fun_apply, linear_map.std_basis_apply, pi.smul_apply, pi.smul_apply,
46+
function.update_noteq hij.symm, pi.zero_apply, smul_eq_mul, smul_eq_mul,
47+
mul_zero, mul_zero],
48+
intro hj', exact false.elim (hj' hj) },
49+
simp_rw basis.units_smul_apply,
50+
erw [hsum, smul_eq_mul],
51+
split_ifs,
52+
{ simp only [h, zero_smul, zero_mul]},
53+
have hww' : w' j = w j,
54+
{ simp only [w, dif_neg h, units.coe_mk0] },
55+
simp only [hww', one_mul],
56+
change v j * v j = ↑(w j) * ((v j * ↑(w j) ^ -(1 / 2 : ℂ)) * (v j * ↑(w j) ^ -(1 / 2 : ℂ))),
57+
suffices : v j * v j = w j ^ - (1 / 2 : ℂ) * w j ^ - (1 / 2 : ℂ) * w j * v j * v j,
58+
{ rw [this], ring },
59+
rw [← complex.cpow_add _ _ (w j).ne_zero, show - (1 / 2 : ℂ) + - (1 / 2) = -1, by ring,
60+
complex.cpow_neg_one, inv_mul_cancel (w j).ne_zero, one_mul],
61+
end
62+
63+
/-- The isometry between a weighted sum of squares on the complex numbers and the
64+
sum of squares, i.e. `weighted_sum_squares` with weight `λ i : ι, 1`. -/
65+
noncomputable def isometry_sum_squares_units [decidable_eq ι] (w : ι → units ℂ) :
66+
isometry (weighted_sum_squares ℂ w) (weighted_sum_squares ℂ (1 : ι → ℂ)) :=
67+
begin
68+
have hw1 : (λ i, if (w i : ℂ) = 0 then 0 else 1 : ι → ℂ) = 1,
69+
{ ext i : 1, exact dif_neg (w i).ne_zero },
70+
have := isometry_sum_squares (coe ∘ w),
71+
rw hw1 at this,
72+
exact this,
73+
end
74+
75+
/-- A nondegenerate quadratic form on the complex numbers is equivalent to
76+
the sum of squares, i.e. `weighted_sum_squares` with weight `λ i : ι, 1`. -/
77+
theorem equivalent_sum_squares {M : Type*} [add_comm_group M] [module ℂ M]
78+
[finite_dimensional ℂ M] (Q : quadratic_form ℂ M) (hQ : (associated Q).nondegenerate) :
79+
equivalent Q (weighted_sum_squares ℂ (1 : fin (finite_dimensional.finrank ℂ M) → ℂ)) :=
80+
let ⟨w, ⟨hw₁⟩⟩ := Q.equivalent_weighted_sum_squares_units_of_nondegenerate' hQ in
81+
⟨hw₁.trans (isometry_sum_squares_units w)⟩
82+
83+
end quadratic_form
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/-
2+
Copyright (c) 2020 Anne Baanen. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Anne Baanen, Kexing Ying, Eric Wieser
5+
-/
6+
import linear_algebra.quadratic_form.basic
7+
import analysis.special_functions.pow
8+
import data.real.sign
9+
10+
/-!
11+
# Real quadratic forms
12+
13+
Sylvester's law of inertia `equivalent_one_neg_one_weighted_sum_squared`:
14+
A real quadratic form is equivalent to a weighted
15+
sum of squares with the weights being ±1 or 0.
16+
17+
When the real quadratic form is nondegerate we can take the weights to be ±1,
18+
as in `equivalent_one_zero_neg_one_weighted_sum_squared`.
19+
20+
-/
21+
22+
namespace quadratic_form
23+
24+
open_locale big_operators
25+
open real finset
26+
27+
variables {ι : Type*} [fintype ι]
28+
29+
/-- The isometry between a weighted sum of squares with weights `u` on the
30+
(non-zero) real numbers and the weighted sum of squares with weights `sign ∘ u`. -/
31+
noncomputable def isometry_sign_weighted_sum_squares
32+
[decidable_eq ι] (w : ι → ℝ) :
33+
isometry (weighted_sum_squares ℝ w) (weighted_sum_squares ℝ (sign ∘ w)) :=
34+
begin
35+
let u := λ i, if h : w i = 0 then (1 : units ℝ) else units.mk0 (w i) h,
36+
have hu' : ∀ i : ι, (sign (u i) * u i) ^ - (1 / 2 : ℝ) ≠ 0,
37+
{ intro i, refine (ne_of_lt (real.rpow_pos_of_pos
38+
(sign_mul_pos_of_ne_zero _ $ units.ne_zero _) _)).symm},
39+
convert ((weighted_sum_squares ℝ w).isometry_basis_repr
40+
((pi.basis_fun ℝ ι).units_smul (λ i, (is_unit_iff_ne_zero.2 $ hu' i).unit))),
41+
ext1 v,
42+
rw [basis_repr_apply, weighted_sum_squares_apply, weighted_sum_squares_apply],
43+
refine sum_congr rfl (λ j hj, _),
44+
have hsum : (∑ (i : ι), v i • ((is_unit_iff_ne_zero.2 $ hu' i).unit : ℝ) •
45+
(pi.basis_fun ℝ ι) i) j = v j • (sign (u j) * u j) ^ - (1 / 2 : ℝ),
46+
{ rw [finset.sum_apply, sum_eq_single j, pi.basis_fun_apply, is_unit.unit_spec,
47+
linear_map.std_basis_apply, pi.smul_apply, pi.smul_apply, function.update_same,
48+
smul_eq_mul, smul_eq_mul, smul_eq_mul, mul_one],
49+
intros i _ hij,
50+
rw [pi.basis_fun_apply, linear_map.std_basis_apply, pi.smul_apply, pi.smul_apply,
51+
function.update_noteq hij.symm, pi.zero_apply, smul_eq_mul, smul_eq_mul,
52+
mul_zero, mul_zero],
53+
intro hj', exact false.elim (hj' hj) },
54+
simp_rw basis.units_smul_apply,
55+
erw [hsum],
56+
simp only [u, function.comp, smul_eq_mul],
57+
split_ifs,
58+
{ simp only [h, zero_smul, zero_mul, sign_zero] },
59+
have hwu : w j = u j,
60+
{ simp only [u, dif_neg h, units.coe_mk0] },
61+
simp only [hwu, units.coe_mk0],
62+
suffices : (u j : ℝ).sign * v j * v j = (sign (u j) * u j) ^ - (1 / 2 : ℝ) *
63+
(sign (u j) * u j) ^ - (1 / 2 : ℝ) * u j * v j * v j,
64+
{ erw [← mul_assoc, this], ring },
65+
rw [← real.rpow_add (sign_mul_pos_of_ne_zero _ $ units.ne_zero _),
66+
show - (1 / 2 : ℝ) + - (1 / 2) = -1, by ring, real.rpow_neg_one, mul_inv₀,
67+
inv_sign, mul_assoc (sign (u j)) (u j)⁻¹,
68+
inv_mul_cancel (units.ne_zero _), mul_one],
69+
apply_instance
70+
end
71+
72+
/-- **Sylvester's law of inertia**: A nondegenerate real quadratic form is equivalent to a weighted
73+
sum of squares with the weights being ±1. -/
74+
theorem equivalent_one_neg_one_weighted_sum_squared
75+
{M : Type*} [add_comm_group M] [module ℝ M] [finite_dimensional ℝ M]
76+
(Q : quadratic_form ℝ M) (hQ : (associated Q).nondegenerate) :
77+
∃ w : fin (finite_dimensional.finrank ℝ M) → ℝ,
78+
(∀ i, w i = -1 ∨ w i = 1) ∧ equivalent Q (weighted_sum_squares ℝ w) :=
79+
let ⟨w, ⟨hw₁⟩⟩ := Q.equivalent_weighted_sum_squares_units_of_nondegenerate' hQ in
80+
⟨sign ∘ coe ∘ w,
81+
λ i, sign_apply_eq_of_ne_zero (w i) (w i).ne_zero,
82+
⟨hw₁.trans (isometry_sign_weighted_sum_squares (coe ∘ w))⟩⟩
83+
84+
/-- **Sylvester's law of inertia**: A real quadratic form is equivalent to a weighted
85+
sum of squares with the weights being ±1 or 0. -/
86+
theorem equivalent_one_zero_neg_one_weighted_sum_squared
87+
{M : Type*} [add_comm_group M] [module ℝ M] [finite_dimensional ℝ M]
88+
(Q : quadratic_form ℝ M) :
89+
∃ w : fin (finite_dimensional.finrank ℝ M) → ℝ,
90+
(∀ i, w i = -1 ∨ w i = 0 ∨ w i = 1) ∧ equivalent Q (weighted_sum_squares ℝ w) :=
91+
let ⟨w, ⟨hw₁⟩⟩ := Q.equivalent_weighted_sum_squares in
92+
⟨sign ∘ coe ∘ w,
93+
λ i, sign_apply_eq (w i),
94+
⟨hw₁.trans (isometry_sign_weighted_sum_squares w)⟩⟩
95+
96+
end quadratic_form

0 commit comments

Comments
 (0)