@@ -7,6 +7,7 @@ import Mathlib.NumberTheory.Cyclotomic.PrimitiveRoots
7
7
import Mathlib.FieldTheory.Finite.Trace
8
8
import Mathlib.Algebra.Group.AddChar
9
9
import Mathlib.Data.ZMod.Units
10
+ import Mathlib.Analysis.Complex.Polynomial
10
11
11
12
#align_import number_theory.legendre_symbol.add_character from "leanprover-community/mathlib" @"0723536a0522d24fc2f159a096fb3304bef77472"
12
13
@@ -47,12 +48,29 @@ section Additive
47
48
-- The domain and target of our additive characters. Now we restrict to a ring in the domain.
48
49
variable {R : Type u} [CommRing R] {R' : Type v} [CommMonoid R']
49
50
51
+ /-- The values of an additive character on a ring of positive characteristic are roots of unity. -/
52
+ lemma val_mem_rootsOfUnity (φ : AddChar R R') (a : R) (h : 0 < ringChar R) :
53
+ (φ.val_isUnit a).unit ∈ rootsOfUnity (ringChar R).toPNat' R' := by
54
+ simp only [mem_rootsOfUnity', IsUnit.unit_spec, Nat.toPNat'_coe, h, ↓reduceIte, ← map_nsmul_pow,
55
+ nsmul_eq_mul, CharP.cast_eq_zero, zero_mul, map_zero_one]
56
+
50
57
/-- An additive character is *primitive* iff all its multiplicative shifts by nonzero
51
58
elements are nontrivial. -/
52
59
def IsPrimitive (ψ : AddChar R R') : Prop :=
53
60
∀ a : R, a ≠ 0 → IsNontrivial (mulShift ψ a)
54
61
#align add_char.is_primitive AddChar.IsPrimitive
55
62
63
+ /-- The composition of a primitive additive character with an injective mooid homomorphism
64
+ is also primitive. -/
65
+ lemma IsPrimitive.compMulHom_of_isPrimitive {R'' : Type *} [CommMonoid R''] {φ : AddChar R R'}
66
+ {f : R' →* R''} (hφ : φ.IsPrimitive) (hf : Function.Injective f) :
67
+ (f.compAddChar φ).IsPrimitive := by
68
+ intro a a_ne_zero
69
+ obtain ⟨r, ne_one⟩ := hφ a a_ne_zero
70
+ rw [mulShift_apply] at ne_one
71
+ simp only [IsNontrivial, mulShift_apply, f.coe_compAddChar, Function.comp_apply]
72
+ exact ⟨r, fun H ↦ ne_one <| hf <| f.map_one ▸ H⟩
73
+
56
74
/-- The map associating to `a : R` the multiplicative shift of `ψ` by `a`
57
75
is injective when `ψ` is primitive. -/
58
76
theorem to_mulShift_inj_of_isPrimitive {ψ : AddChar R R'} (hψ : IsPrimitive ψ) :
@@ -87,33 +105,22 @@ lemma not_isPrimitive_mulShift [Finite R] (e : AddChar R R') {r : R}
87
105
exact ⟨x, h', by simp only [mulShift_mulShift, mul_comm r, h, mulShift_zero, not_ne_iff,
88
106
isNontrivial_iff_ne_trivial]⟩
89
107
90
- -- Porting note: Using `structure` gives a timeout, see
91
- -- https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/mysterious.20finsupp.20related.20timeout/near/365719262 and
92
- -- https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/mysterious.20finsupp.20related.20timeout
93
- -- In Lean4, `set_option genInjectivity false in` may solve this issue.
94
- -- can't prove that they always exist (referring to providing an `Inhabited` instance)
95
108
/-- Definition for a primitive additive character on a finite ring `R` into a cyclotomic extension
96
109
of a field `R'`. It records which cyclotomic extension it is, the character, and the
97
110
fact that the character is primitive. -/
98
111
-- Porting note(#5171): this linter isn't ported yet.
112
+ -- can't prove that they always exist (referring to providing an `Inhabited` instance)
99
113
-- @[nolint has_nonempty_instance]
100
- def PrimitiveAddChar (R : Type u) [CommRing R] (R' : Type v) [Field R'] :=
101
- Σ n : ℕ+, Σ' char : AddChar R (CyclotomicField n R'), IsPrimitive char
114
+ structure PrimitiveAddChar (R : Type u) [CommRing R] (R' : Type v) [Field R'] where
115
+ /-- The first projection from `PrimitiveAddChar`, giving the cyclotomic field. -/
116
+ n : ℕ+
117
+ /-- The second projection from `PrimitiveAddChar`, giving the character. -/
118
+ char : AddChar R (CyclotomicField n R')
119
+ /-- The third projection from `PrimitiveAddChar`, showing that `χ.char` is primitive. -/
120
+ prim : IsPrimitive char
102
121
#align add_char.primitive_add_char AddChar.PrimitiveAddChar
103
-
104
- /-- The first projection from `PrimitiveAddChar`, giving the cyclotomic field. -/
105
- noncomputable def PrimitiveAddChar.n {R : Type u} [CommRing R] {R' : Type v} [Field R'] :
106
- PrimitiveAddChar R R' → ℕ+ := fun χ => χ.1
107
122
#align add_char.primitive_add_char.n AddChar.PrimitiveAddChar.n
108
-
109
- /-- The second projection from `PrimitiveAddChar`, giving the character. -/
110
- noncomputable def PrimitiveAddChar.char {R : Type u} [CommRing R] {R' : Type v} [Field R'] :
111
- ∀ χ : PrimitiveAddChar R R', AddChar R (CyclotomicField χ.n R') := fun χ => χ.2 .1
112
123
#align add_char.primitive_add_char.char AddChar.PrimitiveAddChar.char
113
-
114
- /-- The third projection from `PrimitiveAddChar`, showing that `χ.char` is primitive. -/
115
- theorem PrimitiveAddChar.prim {R : Type u} [CommRing R] {R' : Type v} [Field R'] :
116
- ∀ χ : PrimitiveAddChar R R', IsPrimitive χ.char := fun χ => χ.2 .2
117
124
#align add_char.primitive_add_char.prim AddChar.PrimitiveAddChar.prim
118
125
119
126
/-!
@@ -225,9 +232,10 @@ end Additive
225
232
226
233
/-- There is a primitive additive character on the finite field `F` if the characteristic
227
234
of the target is different from that of `F`.
235
+
228
236
We obtain it as the composition of the trace from `F` to `ZMod p` with a primitive
229
237
additive character on `ZMod p`, where `p` is the characteristic of `F`. -/
230
- noncomputable def primitiveCharFiniteField (F F' : Type *) [Field F] [Finite F] [Field F']
238
+ noncomputable def FiniteField.primitiveChar (F F' : Type *) [Field F] [Finite F] [Field F']
231
239
(h : ringChar F' ≠ ringChar F) : PrimitiveAddChar F F' := by
232
240
let p := ringChar F
233
241
haveI hp : Fact p.Prime := ⟨CharP.char_is_prime F _⟩
@@ -245,13 +253,13 @@ noncomputable def primitiveCharFiniteField (F F' : Type*) [Field F] [Finite F] [
245
253
rw [one_mul] at ha
246
254
exact ⟨a, fun hf => ha <| (ψ.prim.zmod_char_eq_one_iff pp <| Algebra.trace (ZMod p) F a).mp hf⟩
247
255
exact ⟨ψ.n, ψ', hψ'.isPrimitive⟩
248
- #align add_char.primitive_char_finite_field AddChar.primitiveCharFiniteField
256
+ #align add_char.primitive_char_finite_field AddChar.FiniteField.primitiveChar
257
+ @[deprecated (since := "2024-05-30")] alias primitiveCharFiniteField := FiniteField.primitiveChar
249
258
250
259
/-!
251
260
### The sum of all character values
252
261
-/
253
262
254
-
255
263
section sum
256
264
257
265
variable {R : Type *} [AddGroup R] [Fintype R] {R' : Type *} [CommRing R']
@@ -294,4 +302,49 @@ theorem sum_mulShift {R : Type*} [CommRing R] [Fintype R] [DecidableEq R]
294
302
exact mod_cast sum_eq_zero_of_isNontrivial (hψ b h)
295
303
#align add_char.sum_mul_shift AddChar.sum_mulShift
296
304
305
+ /-!
306
+ ### Complex-valued additive characters
307
+ -/
308
+
309
+ section Ring
310
+
311
+ variable {R : Type *} [CommRing R]
312
+
313
+ /-- Post-composing an additive character to `ℂ` with complex conjugation gives the inverse
314
+ character. -/
315
+ lemma starComp_eq_inv (hR : 0 < ringChar R) {φ : AddChar R ℂ} :
316
+ (starRingEnd ℂ).compAddChar φ = φ⁻¹ := by
317
+ ext1 a
318
+ simp only [RingHom.toMonoidHom_eq_coe, MonoidHom.coe_compAddChar, MonoidHom.coe_coe,
319
+ Function.comp_apply, inv_apply']
320
+ have H := Complex.norm_eq_one_of_mem_rootsOfUnity <| φ.val_mem_rootsOfUnity a hR
321
+ exact (Complex.inv_eq_conj H).symm
322
+
323
+ lemma starComp_apply (hR : 0 < ringChar R) {φ : AddChar R ℂ} (a : R) :
324
+ (starRingEnd ℂ) (φ a) = φ⁻¹ a := by
325
+ rw [← starComp_eq_inv hR]
326
+ rfl
327
+
328
+ end Ring
329
+
330
+ section Field
331
+
332
+ variable (F : Type *) [Field F] [Finite F] [DecidableEq F]
333
+
334
+ private lemma ringChar_ne : ringChar ℂ ≠ ringChar F := by
335
+ simpa only [ringChar.eq_zero] using (CharP.ringChar_ne_zero_of_finite F).symm
336
+
337
+ /-- A primitive additive character on the finite field `F` with values in `ℂ`. -/
338
+ noncomputable def FiniteField.primitiveChar_to_Complex : AddChar F ℂ := by
339
+ refine MonoidHom.compAddChar ?_ (primitiveChar F ℂ <| ringChar_ne F).char
340
+ exact (IsCyclotomicExtension.algEquiv ?n ℂ (CyclotomicField ?n ℂ) ℂ : CyclotomicField ?n ℂ →* ℂ)
341
+
342
+ lemma FiniteField.primitiveChar_to_Complex_isPrimitive :
343
+ (primitiveChar_to_Complex F).IsPrimitive := by
344
+ refine IsPrimitive.compMulHom_of_isPrimitive (PrimitiveAddChar.prim _) ?_
345
+ let nn := (primitiveChar F ℂ <| ringChar_ne F).n
346
+ exact (IsCyclotomicExtension.algEquiv nn ℂ (CyclotomicField nn ℂ) ℂ).injective
347
+
348
+ end Field
349
+
297
350
end AddChar
0 commit comments