Skip to content

Commit c4b7ae4

Browse files
committed
feat(LegendreSymbol/AddCharacter): std add char of ZMod N is primitive (#14495)
The standard additive character of `ZMod N` is a primitive character.
1 parent d487a5f commit c4b7ae4

File tree

4 files changed

+87
-51
lines changed

4 files changed

+87
-51
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,7 @@ import Mathlib.Analysis.SpecialFunctions.Complex.Analytic
12521252
import Mathlib.Analysis.SpecialFunctions.Complex.Arctan
12531253
import Mathlib.Analysis.SpecialFunctions.Complex.Arg
12541254
import Mathlib.Analysis.SpecialFunctions.Complex.Circle
1255+
import Mathlib.Analysis.SpecialFunctions.Complex.CircleAddChar
12551256
import Mathlib.Analysis.SpecialFunctions.Complex.Log
12561257
import Mathlib.Analysis.SpecialFunctions.Complex.LogBounds
12571258
import Mathlib.Analysis.SpecialFunctions.Complex.LogDeriv

Mathlib/Analysis/Fourier/ZMod.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Copyright (c) 2024 David Loeffler. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: David Loeffler
55
-/
6-
import Mathlib.Analysis.SpecialFunctions.Complex.Circle
6+
import Mathlib.Analysis.SpecialFunctions.Complex.CircleAddChar
77
import Mathlib.Analysis.Fourier.FourierTransform
88
import Mathlib.NumberTheory.DirichletCharacter.GaussSum
99

Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean

Lines changed: 3 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ Copyright (c) 2021 Yury G. Kudryashov. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Yury G. Kudryashov
55
-/
6-
import Mathlib.Algebra.Group.AddChar
76
import Mathlib.Analysis.Complex.Circle
87
import Mathlib.Analysis.SpecialFunctions.Complex.Log
98

@@ -155,6 +154,9 @@ theorem toCircle_add (x : AddCircle T) (y : AddCircle T) :
155154
induction y using QuotientAddGroup.induction_on'
156155
simp_rw [← coe_add, toCircle_apply_mk, mul_add, expMapCircle_add]
157156

157+
lemma toCircle_zero : toCircle (0 : AddCircle T) = 1 := by
158+
rw [← QuotientAddGroup.mk_zero, toCircle_apply_mk, mul_zero, expMapCircle_zero]
159+
158160
theorem continuous_toCircle : Continuous (@toCircle T) :=
159161
continuous_coinduced_dom.mpr (expMapCircle.continuous.comp <| continuous_const.mul continuous_id')
160162

@@ -205,52 +207,3 @@ open AddCircle
205207
lemma isLocalHomeomorph_expMapCircle : IsLocalHomeomorph expMapCircle := by
206208
have : Fact (0 < 2 * π) := ⟨by positivity⟩
207209
exact homeomorphCircle'.isLocalHomeomorph.comp (isLocalHomeomorph_coe (2 * π))
208-
209-
namespace ZMod
210-
211-
/-!
212-
### Additive characters valued in the complex circle
213-
-/
214-
215-
open scoped Real
216-
217-
variable {N : ℕ} [NeZero N]
218-
219-
/-- The additive character from `ZMod N` to the unit circle in `ℂ`, sending `j mod N` to
220-
`exp (2 * π * I * j / N)`. -/
221-
noncomputable def toCircle : AddChar (ZMod N) circle where
222-
toFun := fun j ↦ (toAddCircle j).toCircle
223-
map_add_eq_mul' a b := by simp_rw [map_add, AddCircle.toCircle_add]
224-
map_zero_eq_one' := by simp_rw [map_zero, AddCircle.toCircle, ← QuotientAddGroup.mk_zero,
225-
Function.Periodic.lift_coe, mul_zero, expMapCircle_zero]
226-
227-
lemma toCircle_intCast (j : ℤ) :
228-
toCircle (j : ZMod N) = exp (2 * π * I * j / N) := by
229-
rw [toCircle, AddChar.coe_mk, AddCircle.toCircle, toAddCircle_intCast,
230-
Function.Periodic.lift_coe, expMapCircle_apply]
231-
push_cast
232-
ring_nf
233-
234-
lemma toCircle_natCast (j : ℕ) :
235-
toCircle (j : ZMod N) = exp (2 * π * I * j / N) := by
236-
simpa using toCircle_intCast (N := N) j
237-
238-
/--
239-
Explicit formula for `toCircle j`. Note that this is "evil" because it uses `ZMod.val`. Where
240-
possible, it is recommended to lift `j` to `ℤ` and use `toCircle_intCast` instead.
241-
-/
242-
lemma toCircle_apply (j : ZMod N) :
243-
toCircle j = exp (2 * π * I * j.val / N) := by
244-
rw [← toCircle_natCast, natCast_zmod_val]
245-
246-
/-- The additive character from `ZMod N` to `ℂ`, sending `j mod N` to `exp (2 * π * I * j / N)`. -/
247-
noncomputable def stdAddChar : AddChar (ZMod N) ℂ := circle.subtype.compAddChar toCircle
248-
249-
lemma stdAddChar_coe (j : ℤ) :
250-
stdAddChar (j : ZMod N) = exp (2 * π * I * j / N) := by
251-
simp only [stdAddChar, MonoidHom.coe_compAddChar, Function.comp_apply,
252-
Submonoid.coe_subtype, toCircle_intCast]
253-
254-
lemma stdAddChar_apply (j : ZMod N) : stdAddChar j = ↑(toCircle j) := rfl
255-
256-
end ZMod
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/-
2+
Copyright (c) 2024 David Loeffler. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: David Loeffler
5+
-/
6+
import Mathlib.Analysis.SpecialFunctions.Complex.Circle
7+
import Mathlib.NumberTheory.LegendreSymbol.AddCharacter
8+
9+
/-!
10+
# Additive characters valued in the unit circle
11+
12+
This file defines additive characters, valued in the unit circle, from either
13+
* the ring `ZMod N` for any non-zero natural `N`,
14+
* the additive circle `ℝ / T ⬝ ℤ`, for any real `T`.
15+
16+
These results are separate from `Analysis.SpecialFunctions.Complex.Circle` in order to reduce
17+
the imports of that file.
18+
-/
19+
20+
open Complex Function
21+
22+
open scoped Real
23+
24+
/-- The canonical map from the additive to the multiplicative circle, as an `AddChar`. -/
25+
noncomputable def AddCircle.toCircle_addChar {T : ℝ} : AddChar (AddCircle T) circle where
26+
toFun := toCircle
27+
map_zero_eq_one' := toCircle_zero
28+
map_add_eq_mul' := toCircle_add
29+
30+
open AddCircle
31+
32+
namespace ZMod
33+
34+
variable {N : ℕ} [NeZero N]
35+
36+
/-- The additive character from `ZMod N` to the unit circle in `ℂ`, sending `j mod N` to
37+
`exp (2 * π * I * j / N)`. -/
38+
noncomputable def toCircle : AddChar (ZMod N) circle :=
39+
toCircle_addChar.compAddMonoidHom toAddCircle
40+
41+
lemma toCircle_intCast (j : ℤ) :
42+
toCircle (j : ZMod N) = exp (2 * π * I * j / N) := by
43+
rw [toCircle, AddChar.compAddMonoidHom_apply, toCircle_addChar, AddChar.coe_mk,
44+
AddCircle.toCircle, toAddCircle_intCast, Function.Periodic.lift_coe, expMapCircle_apply]
45+
push_cast
46+
ring_nf
47+
48+
lemma toCircle_natCast (j : ℕ) :
49+
toCircle (j : ZMod N) = exp (2 * π * I * j / N) := by
50+
simpa using toCircle_intCast (N := N) j
51+
52+
/--
53+
Explicit formula for `toCircle j`. Note that this is "evil" because it uses `ZMod.val`. Where
54+
possible, it is recommended to lift `j` to `ℤ` and use `toCircle_intCast` instead.
55+
-/
56+
lemma toCircle_apply (j : ZMod N) :
57+
toCircle j = exp (2 * π * I * j.val / N) := by
58+
rw [← toCircle_natCast, natCast_zmod_val]
59+
60+
lemma injective_toCircle : Injective (toCircle : ZMod N → circle) :=
61+
(AddCircle.injective_toCircle one_ne_zero).comp (toAddCircle_injective N)
62+
63+
/-- The additive character from `ZMod N` to `ℂ`, sending `j mod N` to `exp (2 * π * I * j / N)`. -/
64+
noncomputable def stdAddChar : AddChar (ZMod N) ℂ := circle.subtype.compAddChar toCircle
65+
66+
lemma stdAddChar_coe (j : ℤ) :
67+
stdAddChar (j : ZMod N) = exp (2 * π * I * j / N) := by
68+
simp only [stdAddChar, MonoidHom.coe_compAddChar, Function.comp_apply,
69+
Submonoid.coe_subtype, toCircle_intCast]
70+
71+
lemma stdAddChar_apply (j : ZMod N) : stdAddChar j = ↑(toCircle j) := rfl
72+
73+
lemma injective_stdAddChar : Injective (stdAddChar : AddChar (ZMod N) ℂ) :=
74+
Subtype.coe_injective.comp injective_toCircle
75+
76+
/-- The standard additive character `ZMod N → ℂ` is primitive. -/
77+
lemma isPrimitive_stdAddChar (N : ℕ) [NeZero N] :
78+
(stdAddChar (N := N)).IsPrimitive := by
79+
refine AddChar.zmod_char_primitive_of_eq_one_only_at_zero _ _ (fun t ht ↦ ?_)
80+
rwa [← (stdAddChar (N := N)).map_zero_eq_one, injective_stdAddChar.eq_iff] at ht
81+
82+
end ZMod

0 commit comments

Comments
 (0)