Skip to content

Commit e4c839c

Browse files
committed
Optionally pass root of unity to DirichletCharacter
1 parent d9c930c commit e4c839c

File tree

2 files changed

+65
-21
lines changed

2 files changed

+65
-21
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Magma
22
Utilities and extensions of various Magma intrinsics plus intrinsics for efficiently working with Conrey characters and their Galois orbits, integrated with Magma's built-in support for Dirichlet characters, an intrinsics for working more efficiently with subgroups of GL(2,Z/NZ).
33

4-
You can create the Dirichlet character with Conrey label `13.3` in the Galois orbit with LMFDB label `13.c` using either `chi:=DirichletCharacter("13.2");` or `chi:=DirichletCharacter(`13.c`);` and you can recover these labels using `ConreyLabel(chi)` or `CharacterOrbitLabel(chi)`.
4+
You can create the Dirichlet character with Conrey label `13.3` in the Galois orbit with LMFDB label `13.c` using either `chi:=DirichletCharacter("13.2");` or `chi:=DirichletCharacter("13.c");` and you can recover these labels using `ConreyLabel(chi);` or `CharacterOrbitLabel(chi);`.
55

6-
To use this package add `AttachSpec("somewhere/magma.spec")` to your Magma startup script.
6+
To use this package add `AttachSpec("somewhere/magma.spec");` to your Magma startup script.

chars.m

Lines changed: 63 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -292,17 +292,34 @@ intrinsic CharacterOrbitReps (N::RngIntElt:RepTable:=false,OrderBound:=0) -> Lis
292292
{ The list of Galois orbit representatives of the full Dirichlet group of modulus N with minimal codomains sorted by order and trace vectors.
293293
If the optional boolean argument RepTable is set then a table mapping Dirichlet characters to indexes in this list is returned as the second return value. }
294294
require N gt 0: "Modulus N must be a positive integer";
295-
if OrderBound eq 1 then chi1:=DirichletGroup(N)!1; if RepTable then T:=AssociativeArray(Parent(chi1)); T[chi1]:=1; return [chi1],T; else return [chi1]; end if; end if;
296-
if not RepTable and OrderBound eq 0 and IsCyclic(N) then return [* DirichletCharacter(s):s in ConreyCharacterOrbitReps(N) *]; end if;
297-
// The call to MinimalBaseRingCharacter can be very slow when N is large (this makes no sense it should be easy) */
298-
G := [* MinimalBaseRingCharacter(chi): chi in GaloisConjugacyRepresentatives(FullDirichletGroup(N)) *];
295+
if OrderBound eq 1 then
296+
chi1:=DirichletGroup(N)!1;
297+
if RepTable then
298+
T:=AssociativeArray(Parent(chi1));
299+
T[chi1]:=1;
300+
return [chi1],T;
301+
else
302+
return [chi1];
303+
end if;
304+
end if;
305+
if not RepTable and OrderBound eq 0 then
306+
return [* DirichletCharacter(s) : s in ConreyCharacterOrbitReps(N) *];
307+
end if;
308+
G := [* DirichletCharacter(s) : s in ConreyCharacterOrbitReps(N) *];
299309
X := [i:i in [1..#G]];
300310
X := Sort(X,func<i,j|CompareCharacters(G[i],G[j])>);
301311
G := OrderBound eq 0 select [* G[i] : i in X *] else [* G[i] : i in X | Order(G[i]) le OrderBound *];
302312
if not RepTable then return G; end if;
303313
H := Elements(FullDirichletGroup(N));
304314
A := AssociativeArray();
305-
for i:=1 to #G do v:=[OrderOfRootOfUnity(a,Order(G[i])):a in ValuesOnUnitGenerators(G[i])]; if IsDefined(A,v) then Append(~A[v],i); else A[v]:=[i]; end if; end for;
315+
for i:=1 to #G do
316+
v:=[OrderOfRootOfUnity(a,Order(G[i])):a in ValuesOnUnitGenerators(G[i])];
317+
if IsDefined(A,v) then
318+
Append(~A[v],i);
319+
else
320+
A[v]:=[i];
321+
end if;
322+
end for;
306323
if OrderBound gt 0 then H := [chi : chi in H | Order(chi) le OrderBound]; end if;
307324
T := AssociativeArray(Parent(H[1]));
308325
for h in H do
@@ -853,12 +870,12 @@ intrinsic Parity (q::RngIntElt, n::RngIntElt) -> RngIntElt
853870
return &*[Integers()|KroneckerSymbol(n,p):p in PrimeDivisors(q)|IsOdd(p)]*(q mod 4 ne 0 or n mod 4 eq 1 select 1 else -1);
854871
end intrinsic;
855872

856-
intrinsic IsEven (q::RngIntElt, n::RngIntElt) -> RngIntElt
873+
intrinsic IsEven (q::RngIntElt, n::RngIntElt) -> BoolElt
857874
{ The parity of the Conrey character q.n. }
858875
return Parity(q,n) eq 1;
859876
end intrinsic;
860877

861-
intrinsic IsOff (q::RngIntElt, n::RngIntElt) -> RngIntElt
878+
intrinsic IsOdd (q::RngIntElt, n::RngIntElt) -> BoolElt
862879
{ The parity of the Conrey character q.n. }
863880
return Parity(q,n) eq -1;
864881
end intrinsic;
@@ -1110,8 +1127,12 @@ intrinsic DirichletCharacterFromAngles (N::RngIntElt,u::SeqEnum[RngIntElt],v::Se
11101127
return DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,F),[F|F.1^(Integers()!(n*e)) : e in V]);
11111128
end intrinsic;
11121129

1113-
intrinsic DirichletCharacterFromAngles (N::RngIntElt,v::SeqEnum) -> GrpDrchElt
1114-
{ Given a modulus N, a positive integer n, a list of integers u giving standard generates for (Z/NZ)*, and a suitable list of integers v, returns the Dirichlet character with values in Q(zeta_n) mapping u[i] to zeta_n^v[i]. }
1130+
intrinsic DirichletCharacterFromAngles (N::RngIntElt,v::SeqEnum: zeta:=0, r:=0) -> GrpDrchElt
1131+
{ Given a modulus N, a positive integer n, a list of integers u giving standard generates for (Z/NZ)*, and a suitable list of integers v, returns the Dirichlet character with values in Q(zeta_n) mapping u[i] to zeta_n^v[i]. If the optional parameter zeta is given, then it is assumed to be a root of unity of order r with r a multiple of n and zeta^(r/n) is used instead of zeta_n.}
1132+
if zeta ne 0 then
1133+
R := Parent(zeta);
1134+
return DirichletCharacterFromAngles (N, v, R, zeta, r);
1135+
end if;
11151136
require N gt 0: "Modulus N must a positive integer";
11161137
if N lt 3 then assert #v eq 0; return DirichletGroup(N)!1; end if;
11171138
n := LCM([Denominator(e):e in v]);
@@ -1121,6 +1142,19 @@ intrinsic DirichletCharacterFromAngles (N::RngIntElt,v::SeqEnum) -> GrpDrchElt
11211142
return DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,F),[F|F.1^(Integers()!(n*e)) : e in v]);
11221143
end intrinsic;
11231144

1145+
intrinsic DirichletCharacterFromAngles (N::RngIntElt,v::SeqEnum, R::Rng, zeta::RngElt, r::RngIntElt) -> GrpDrchElt
1146+
{ Given a modulus N, a positive integer n, a list of integers u giving standard generates for (Z/NZ)*, and a suitable list of integers v, returns the Dirichlet character with values in R mapping u[i] to zeta^(r/n*v[i]). If agrument zeta is assumed to be a root of unity of order r in R. And r should be a multiple of n.}
1147+
require N gt 0: "Modulus N must a positive integer";
1148+
if N lt 3 then assert #v eq 0; return DirichletGroup(N, R, zeta^r, 1)!1; end if;
1149+
n := LCM([Denominator(e):e in v]);
1150+
assert (r mod n) eq 0;
1151+
zeta := zeta^(r div n);
1152+
if n eq 1 then return DirichletGroup(N, R, zeta, n)!1; end if;
1153+
if n eq 2 then return DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N, R, zeta, n),[(-1)^(Integers()!(n*e)) : e in v]); end if;
1154+
return DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,R, zeta, n),[R|zeta^(Integers()!(n*e)) : e in v]);
1155+
end intrinsic;
1156+
1157+
11241158
intrinsic SquareRoots (chi::GrpDrchElt) -> SeqEnum[GrpDrchElt]
11251159
{ A list of the Dirichlet characters psi in the ambient group of chi for which psi^2 = chi (note that only psi in the ambient group of chi will be returned). }
11261160
if IsOdd(Order(chi)) then
@@ -1137,14 +1171,21 @@ intrinsic SquareRoots (chi::GrpDrchElt) -> SeqEnum[GrpDrchElt]
11371171
return [Parent(chi)|psi*xi : xi in Elements(DirichletGroup(Modulus(chi)))];
11381172
end intrinsic;
11391173

1140-
intrinsic CyclotomicConreyCharacter (q::RngIntElt,n::RngIntElt) -> GrpDrchElt
1141-
{ The Dirichlet character with Conrey label q.n. }
1142-
return DirichletCharacterFromAngles(q,UnitGenerators(q),ConreyCharacterAngles(q,n));
1174+
intrinsic CyclotomicConreyCharacter (q::RngIntElt,n::RngIntElt : zeta:=0, r:=0) -> GrpDrchElt
1175+
{ The Dirichlet character with Conrey label q.n.
1176+
Optionally one can pass in a root of unity using the parameter zeta. This zeta will be used to construct
1177+
the dirichlet character, if zeta is nonzero then r should be nonzero as well and it is assumed to be the
1178+
order of zeta.
1179+
}
1180+
return DirichletCharacterFromAngles(q, ConreyCharacterAngles(q,n) : zeta:=zeta, r:=r);
11431181
end intrinsic;
11441182

1145-
intrinsic CyclotomicConreyCharacter (s::MonStgElt) -> GrpDrchElt
1146-
{ The Dirichlet character with the specified Conrey label or character orbit label. }
1147-
return CyclotomicConreyCharacter (a[1],a[2]) where a := SplitCharacterLabel(s);
1183+
intrinsic CyclotomicConreyCharacter (s::MonStgElt : zeta:=0, r:=0) -> GrpDrchElt
1184+
{ The Dirichlet character with the specified Conrey label or character orbit label.
1185+
Optionally one can pass in a root of unity using the parameter zeta. This zeta will be used to construct
1186+
the dirichlet character, if zeta is nonzero then r should be nonzero as well and it is assumed to be the
1187+
order of zeta.}
1188+
return CyclotomicConreyCharacter (a[1],a[2] : zeta:=zeta, r:=r) where a := SplitCharacterLabel(s);
11481189
end intrinsic;
11491190

11501191
intrinsic DirichletCharacter (chi:GrpDrchElt) -> GrpDrchElt
@@ -1154,12 +1195,15 @@ intrinsic DirichletCharacter (chi:GrpDrchElt) -> GrpDrchElt
11541195

11551196
intrinsic DirichletCharacter (q::RngIntElt,n::RngIntElt) -> GrpDrchElt
11561197
{ The Dirichlet character with Conrey label q.n, equivalent to CyclotomicConreyCharacter(q,n). }
1157-
return DirichletCharacterFromAngles(q,UnitGenerators(q),ConreyCharacterAngles(q,n));
1198+
return DirichletCharacterFromAngles(q, ConreyCharacterAngles(q,n));
11581199
end intrinsic;
11591200

1160-
intrinsic DirichletCharacter (s::MonStgElt) -> GrpDrchElt
1161-
{ Returns the Dirichlet character with the specified Conrey label or character orbit label. }
1162-
return CyclotomicConreyCharacter(a[1],a[2]) where a := SplitCharacterLabel(s);
1201+
intrinsic DirichletCharacter (s::MonStgElt : zeta:=0, r:=0) -> GrpDrchElt
1202+
{ Returns the Dirichlet character with the specified Conrey label or character orbit label.
1203+
Optionally one can pass in a root of unity using the parameter zeta. This zeta will be used to construct
1204+
the dirichlet character, if zeta is nonzero then r should be nonzero as well and it is assumed to be the
1205+
order of zeta.}
1206+
return CyclotomicConreyCharacter(a[1],a[2]: zeta:=zeta, r:=r) where a := SplitCharacterLabel(s);
11631207
end intrinsic;
11641208

11651209
intrinsic Conjugates (chi::GrpDrchElt) -> SeqEnum[GrpDrchElt]

0 commit comments

Comments
 (0)