Skip to content

Commit 0be623a

Browse files
committed
feat: Define the regulator of a number field (#12504)
This PR defines the regulator of a number field `K` as the covolume of its `unitLattice K`. Basic results about the regulator are proved including the fact that it is equal to the absolute value of the matrix with entries `mult w * Real.log w (fundSystem K i)` where `fundSystem K` is the fundamental system of units and `w` runs through all the infinite places of `K` but one.
1 parent 00d112f commit 0be623a

File tree

6 files changed

+173
-29
lines changed

6 files changed

+173
-29
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3213,6 +3213,7 @@ import Mathlib.NumberTheory.NumberField.FractionalIdeal
32133213
import Mathlib.NumberTheory.NumberField.Norm
32143214
import Mathlib.NumberTheory.NumberField.Units.Basic
32153215
import Mathlib.NumberTheory.NumberField.Units.DirichletTheorem
3216+
import Mathlib.NumberTheory.NumberField.Units.Regulator
32163217
import Mathlib.NumberTheory.Ostrowski
32173218
import Mathlib.NumberTheory.Padics.Hensel
32183219
import Mathlib.NumberTheory.Padics.PadicIntegers

Mathlib/Algebra/Ring/NegOnePow.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ lemma negOnePow_eq_neg_one_iff (n : ℤ) : n.negOnePow = -1 ↔ Odd n := by
7070
contradiction
7171
· exact negOnePow_odd n
7272

73+
@[simp]
74+
theorem abs_negOnePow (n : ℤ) : |(n.negOnePow : ℤ)| = 1 := by
75+
rw [abs_eq_natAbs, Int.units_natAbs, Nat.cast_one]
76+
7377
@[simp]
7478
lemma negOnePow_neg (n : ℤ) : (-n).negOnePow = n.negOnePow := by
7579
dsimp [negOnePow]

Mathlib/GroupTheory/Perm/Sign.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,11 @@ theorem sign_prod_list_swap {l : List (Perm α)} (hl : ∀ g ∈ l, IsSwap g) :
462462
rw [← List.prod_replicate, ← h₁, List.prod_hom _ (@sign α _ _)]
463463
#align equiv.perm.sign_prod_list_swap Equiv.Perm.sign_prod_list_swap
464464

465+
@[simp]
466+
theorem sign_abs (f : Perm α) :
467+
|(Equiv.Perm.sign f : ℤ)| = 1 := by
468+
rw [Int.abs_eq_natAbs, Int.units_natAbs, Nat.cast_one]
469+
465470
variable (α)
466471

467472
theorem sign_surjective [Nontrivial α] : Function.Surjective (sign : Perm α → ℤˣ) := fun a =>

Mathlib/NumberTheory/NumberField/Units/Basic.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ end coe
9393

9494
open NumberField.InfinitePlace
9595

96+
@[simp]
97+
protected theorem norm [NumberField K] (x : (𝓞 K)ˣ) :
98+
|Algebra.norm ℚ (x : K)| = 1 := by
99+
rw [← RingOfIntegers.coe_norm, isUnit_iff_norm.mp x.isUnit]
100+
96101
section torsion
97102

98103
/-- The torsion subgroup of the group of units. -/

Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ def w₀ : InfinitePlace K := (inferInstance : Nonempty (InfinitePlace K)).some
7272
variable (K)
7373

7474
/-- The logarithmic embedding of the units (seen as an `Additive` group). -/
75-
def logEmbedding : Additive ((𝓞 K)ˣ) →+ ({w : InfinitePlace K // w ≠ w₀} → ℝ) :=
75+
def _root_.NumberField.Units.logEmbedding :
76+
Additive ((𝓞 K)ˣ) →+ ({w : InfinitePlace K // w ≠ w₀} → ℝ) :=
7677
{ toFun := fun x w => mult w.val * Real.log (w.val ↑(Additive.toMul x))
7778
map_zero' := by simp; rfl
7879
map_add' := fun _ _ => by simp [Real.log_mul, mul_add]; rfl }
@@ -86,8 +87,7 @@ theorem logEmbedding_component (x : (𝓞 K)ˣ) (w : {w : InfinitePlace K // w
8687
theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
8788
∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
8889
have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
89-
rw [show |(Algebra.norm ℚ) (x : K)| = 1 from isUnit_iff_norm.mp x.isUnit, Rat.cast_one,
90-
Real.log_one, Real.log_prod] at h
90+
rw [Units.norm, Rat.cast_one, Real.log_one, Real.log_prod] at h
9191
· simp_rw [Real.log_pow] at h
9292
rw [← insert_erase (mem_univ w₀), sum_insert (not_mem_erase w₀ univ), add_comm,
9393
add_eq_zero_iff_eq_neg] at h
@@ -374,6 +374,29 @@ theorem unitLattice_rank :
374374
finrank ℤ (unitLattice K) = Units.rank K := by
375375
rw [← Units.finrank_eq_rank, Zlattice.rank ℝ]
376376

377+
/-- The map obtained by quotienting by the kernel of `logEmbedding`. -/
378+
def logEmbeddingQuot :
379+
Additive ((𝓞 K)ˣ ⧸ (torsion K)) →+ ({w : InfinitePlace K // w ≠ w₀} → ℝ) :=
380+
MonoidHom.toAdditive' <|
381+
(QuotientGroup.kerLift (AddMonoidHom.toMultiplicative' (logEmbedding K))).comp
382+
(QuotientGroup.quotientMulEquivOfEq (by
383+
ext
384+
rw [MonoidHom.mem_ker, AddMonoidHom.toMultiplicative'_apply_apply, ofAdd_eq_one,
385+
← logEmbedding_eq_zero_iff]
386+
rfl)).toMonoidHom
387+
388+
@[simp]
389+
theorem logEmbeddingQuot_apply (x : (𝓞 K)ˣ) :
390+
logEmbeddingQuot K ⟦x⟧ = logEmbedding K x := rfl
391+
392+
theorem logEmbeddingQuot_injective :
393+
Function.Injective (logEmbeddingQuot K) := by
394+
unfold logEmbeddingQuot
395+
intro _ _ h
396+
simp_rw [MonoidHom.toAdditive'_apply_apply, MonoidHom.coe_comp, MulEquiv.coe_toMonoidHom,
397+
Function.comp_apply, EmbeddingLike.apply_eq_iff_eq] at h
398+
exact (EmbeddingLike.apply_eq_iff_eq _).mp <| (QuotientGroup.kerLift_injective _).eq_iff.mp h
399+
377400
#adaptation_note
378401
/--
379402
After https://github.com/leanprover/lean4/pull/4119
@@ -386,36 +409,25 @@ local instance : CommGroup (𝓞 K)ˣ := inferInstance
386409
-/
387410
set_option maxSynthPendingDepth 2 -- Note this is active for the remainder of the file.
388411

389-
private theorem unitLatticeEquiv_aux1 :
390-
(logEmbedding K).ker = (MonoidHom.toAdditive (QuotientGroup.mk' (torsion K))).ker := by
391-
ext
392-
rw [MonoidHom.coe_toAdditive_ker, QuotientGroup.ker_mk', AddMonoidHom.mem_ker,
393-
logEmbedding_eq_zero_iff]
394-
rfl
412+
/-- The linear equivalence between `(𝓞 K)ˣ ⧸ (torsion K)` as an additive `ℤ`-module and
413+
`unitLattice` . -/
414+
def logEmbeddingEquiv :
415+
Additive ((𝓞 K)ˣ ⧸ (torsion K)) ≃ₗ[ℤ] (unitLattice K) :=
416+
(AddEquiv.ofBijective (AddMonoidHom.codRestrict (logEmbeddingQuot K) _
417+
(Quotient.ind fun x ↦ logEmbeddingQuot_apply K _ ▸ AddSubgroup.mem_map_of_mem _ trivial))
418+
fun _ _ ↦ by
419+
rw [AddMonoidHom.codRestrict_apply, AddMonoidHom.codRestrict_apply, Subtype.mk.injEq]
420+
apply logEmbeddingQuot_injective K, fun ⟨a, ⟨b, _, ha⟩⟩ ↦ ⟨⟦b⟧, by simp [ha]⟩⟩).toIntLinearEquiv
395421

396-
private theorem unitLatticeEquiv_aux2 :
397-
Function.Surjective (MonoidHom.toAdditive (QuotientGroup.mk' (torsion K))) := by
398-
intro x
399-
refine ⟨Additive.ofMul x.out', ?_⟩
400-
simp only [MonoidHom.toAdditive_apply_apply, toMul_ofMul, QuotientGroup.mk'_apply,
401-
QuotientGroup.out_eq']
402-
rfl
403-
404-
/-- The linear equivalence between `unitLattice` and `(𝓞 K)ˣ ⧸ (torsion K)` as an additive
405-
`ℤ`-module. -/
406-
def unitLatticeEquiv : (unitLattice K) ≃ₗ[ℤ] Additive ((𝓞 K)ˣ ⧸ (torsion K)) :=
407-
AddEquiv.toIntLinearEquiv <|
408-
(AddEquiv.addSubgroupCongr (AddMonoidHom.range_eq_map (logEmbedding K)).symm).trans <|
409-
(QuotientAddGroup.quotientKerEquivRange (logEmbedding K)).symm.trans <|
410-
(QuotientAddGroup.quotientAddEquivOfEq (unitLatticeEquiv_aux1 K)).trans <|
411-
QuotientAddGroup.quotientKerEquivOfSurjective
412-
(MonoidHom.toAdditive (QuotientGroup.mk' (torsion K))) (unitLatticeEquiv_aux2 K)
422+
@[simp]
423+
theorem logEmbeddingEquiv_apply (x : (𝓞 K)ˣ) :
424+
logEmbeddingEquiv K ⟦x⟧ = logEmbedding K x := rfl
413425

414426
instance : Module.Free ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) :=
415-
Module.Free.of_equiv (unitLatticeEquiv K)
427+
Module.Free.of_equiv (logEmbeddingEquiv K).symm
416428

417429
instance : Module.Finite ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) :=
418-
Module.Finite.equiv (unitLatticeEquiv K)
430+
Module.Finite.equiv (logEmbeddingEquiv K).symm
419431

420432
-- Note that we prove this instance first and then deduce from it the instance
421433
-- `Monoid.FG (𝓞 K)ˣ`, and not the other way around, due to no `Subgroup` version
@@ -439,7 +451,7 @@ instance : Monoid.FG (𝓞 K)ˣ := by
439451

440452
theorem rank_modTorsion :
441453
FiniteDimensional.finrank ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) = rank K := by
442-
rw [← LinearEquiv.finrank_eq (unitLatticeEquiv K), unitLattice_rank]
454+
rw [← LinearEquiv.finrank_eq (logEmbeddingEquiv K).symm, unitLattice_rank]
443455

444456
/-- A basis of the quotient `(𝓞 K)ˣ ⧸ (torsion K)` seen as an additive ℤ-module. -/
445457
def basisModTorsion : Basis (Fin (rank K)) ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) :=
@@ -452,6 +464,12 @@ def fundSystem : Fin (rank K) → (𝓞 K)ˣ :=
452464
-- `:)` prevents the `⧸` decaying to a quotient by `leftRel` when we unfold this later
453465
fun i => Quotient.out' (Additive.toMul (basisModTorsion K i) :)
454466

467+
theorem fundSystem_mk (i : Fin (rank K)) :
468+
Additive.ofMul ⟦fundSystem K i⟧ = (basisModTorsion K i) := by
469+
rw [fundSystem, Equiv.apply_eq_iff_eq_symm_apply, @Quotient.mk_eq_iff_out,
470+
Quotient.out', Quotient.out_equiv_out]
471+
rfl
472+
455473
/-- The exponents that appear in the unique decomposition of a unit as the product of
456474
a root of unity and powers of the units of the fundamental system `fundSystem` (see
457475
`exist_unique_eq_mul_prod`) are given by the representation of the unit on `basisModTorsion`. -/
@@ -488,4 +506,5 @@ theorem exist_unique_eq_mul_prod (x : (𝓞 K)ˣ) : ∃! ζe : torsion K × (Fin
488506

489507
end statements
490508

509+
491510
end NumberField.Units
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/-
2+
Copyright (c) 2024 Xavier Roblot. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Xavier Roblot
5+
-/
6+
import Mathlib.Algebra.Module.Zlattice.Covolume
7+
import Mathlib.LinearAlgebra.Matrix.Determinant.Misc
8+
import Mathlib.NumberTheory.NumberField.Units.DirichletTheorem
9+
10+
/-!
11+
# Regulator of a number field
12+
13+
We define and prove basic results about the regulator of a number field `K`.
14+
15+
## Main definitions and results
16+
17+
* `NumberField.Units.regulator`: the regulator of the number field `K`.
18+
19+
* `Number.Field.Units.regulator_eq_det`: For any infinite place `w'`, the regulator is equal to
20+
the absolute value of the determinant of the matrix `(mult w * log w (fundSystem K i)))_i, w`
21+
where `w` runs through the infinite places distinct from `w'`.
22+
23+
## Tags
24+
number field, units, regulator
25+
-/
26+
27+
open scoped NumberField
28+
29+
noncomputable section
30+
31+
namespace NumberField.Units
32+
33+
variable (K : Type*) [Field K]
34+
35+
open MeasureTheory Classical BigOperators NumberField.InfinitePlace
36+
NumberField NumberField.Units.dirichletUnitTheorem
37+
38+
variable [NumberField K]
39+
40+
/-- The regulator of a number fied `K`. -/
41+
def regulator : ℝ := Zlattice.covolume (unitLattice K)
42+
43+
theorem regulator_ne_zero : regulator K ≠ 0 := Zlattice.covolume_ne_zero (unitLattice K) volume
44+
45+
theorem regulator_pos : 0 < regulator K := Zlattice.covolume_pos (unitLattice K) volume
46+
47+
#adaptation_note
48+
/--
49+
After https://github.com/leanprover/lean4/pull/4119
50+
the `Module ℤ (Additive ((𝓞 K)ˣ ⧸ NumberField.Units.torsion K))` instance required below isn't found
51+
unless we use `set_option maxSynthPendingDepth 2`, or add
52+
explicit instances:
53+
```
54+
local instance : CommGroup (𝓞 K)ˣ := inferInstance
55+
```
56+
-/
57+
set_option maxSynthPendingDepth 2 -- Note this is active for the remainder of the file.
58+
59+
theorem regulator_eq_det' (e : {w : InfinitePlace K // w ≠ w₀} ≃ Fin (rank K)) :
60+
regulator K = |(Matrix.of fun i ↦ (logEmbedding K) (fundSystem K (e i))).det| := by
61+
simp_rw [regulator, Zlattice.covolume_eq_det _
62+
(((basisModTorsion K).map (logEmbeddingEquiv K)).reindex e.symm), Basis.coe_reindex,
63+
Function.comp, Basis.map_apply, ← fundSystem_mk, Equiv.symm_symm]
64+
rfl
65+
66+
/-- Let `u : Fin (rank K) → (𝓞 K)ˣ` be a family of units and let `w₁` and `w₂` be two infinite
67+
places. Then, the two square matrices with entries `(mult w * log w (u i))_i, {w ≠ w_i}`, `i = 1,2`,
68+
have the same determinant in absolute value. -/
69+
theorem abs_det_eq_abs_det (u : Fin (rank K) → (𝓞 K)ˣ)
70+
{w₁ w₂ : InfinitePlace K} (e₁ : {w // w ≠ w₁} ≃ Fin (rank K))
71+
(e₂ : {w // w ≠ w₂} ≃ Fin (rank K)) :
72+
|(Matrix.of fun i w : {w // w ≠ w₁} ↦ (mult w.val : ℝ) * (w.val (u (e₁ i) : K)).log).det| =
73+
|(Matrix.of fun i w : {w // w ≠ w₂} ↦ (mult w.val : ℝ) * (w.val (u (e₂ i) : K)).log).det| := by
74+
-- We construct an equiv `Fin (rank K + 1) ≃ InfinitePlace K` from `e₂.symm`
75+
let f : Fin (rank K + 1) ≃ InfinitePlace K :=
76+
(finSuccEquiv _).trans ((Equiv.optionSubtype _).symm e₁.symm).val
77+
-- And `g` corresponds to the restriction of `f⁻¹` to `{w // w ≠ w₂}`
78+
let g : {w // w ≠ w₂} ≃ Fin (rank K) :=
79+
(Equiv.subtypeEquiv f.symm (fun _ ↦ by simp [f])).trans
80+
(finSuccAboveEquiv (f.symm w₂)).toEquiv.symm
81+
have h_col := congr_arg abs <| Matrix.det_permute (g.trans e₂.symm)
82+
(Matrix.of fun i w : {w // w ≠ w₂} ↦ (mult w.val : ℝ) * (w.val (u (e₂ i) : K)).log)
83+
rw [abs_mul, ← Int.cast_abs, Equiv.Perm.sign_abs, Int.cast_one, one_mul] at h_col
84+
rw [← h_col]
85+
have h := congr_arg abs <| Matrix.submatrix_succAbove_det_eq_negOnePow_submatrix_succAbove_det'
86+
(Matrix.of fun i w ↦ (mult (f w) : ℝ) * ((f w) (u i)).log) ?_ 0 (f.symm w₂)
87+
rw [← Matrix.det_reindex_self e₁, ← Matrix.det_reindex_self g]
88+
· rw [Units.smul_def, abs_zsmul, Int.abs_negOnePow, one_smul] at h
89+
convert h
90+
· ext; simp only [ne_eq, Matrix.reindex_apply, Matrix.submatrix_apply, Matrix.of_apply,
91+
Equiv.apply_symm_apply, Equiv.trans_apply, Fin.succAbove_zero, id_eq, finSuccEquiv_succ,
92+
Equiv.optionSubtype_symm_apply_apply_coe, f]
93+
· ext; simp only [ne_eq, Equiv.coe_trans, Matrix.reindex_apply, Matrix.submatrix_apply,
94+
Function.comp_apply, Equiv.apply_symm_apply, id_eq, Matrix.of_apply]; rfl
95+
· intro _
96+
simp_rw [Matrix.of_apply, ← Real.log_pow]
97+
rw [← Real.log_prod, Equiv.prod_comp f (fun w ↦ (w (u _) ^ (mult w))), prod_eq_abs_norm,
98+
Units.norm, Rat.cast_one, Real.log_one]
99+
exact fun _ _ ↦ pow_ne_zero _ <| (map_ne_zero _).mpr (coe_ne_zero _)
100+
101+
/-- For any infinite place `w'`, the regulator is equal to the absolute value of the determinant
102+
of the matrix `(mult w * log w (fundSystem K i)))_i, {w ≠ w'}`. -/
103+
theorem regulator_eq_det (w' : InfinitePlace K) (e : {w // w ≠ w'} ≃ Fin (rank K)) :
104+
regulator K =
105+
|(Matrix.of fun i w : {w // w ≠ w'} ↦ (mult w.val : ℝ) *
106+
Real.log (w.val (fundSystem K (e i) : K))).det| := by
107+
let e' : {w : InfinitePlace K // w ≠ w₀} ≃ Fin (rank K) := Fintype.equivOfCardEq (by
108+
rw [Fintype.card_subtype_compl, Fintype.card_ofSubsingleton, Fintype.card_fin, rank])
109+
simp_rw [regulator_eq_det' K e', logEmbedding, AddMonoidHom.coe_mk, ZeroHom.coe_mk]
110+
exact abs_det_eq_abs_det K (fun i ↦ fundSystem K i) e' e

0 commit comments

Comments
 (0)