forked from HastD/QCMod-NF-old
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauxpolys.m
135 lines (120 loc) · 3.18 KB
/
auxpolys.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
freeze;
function auxpolys(Q)
// Compute the polynomials r,Delta,s.
Delta:=Discriminant(Q);
r:=Numerator(Delta/GCD(Delta,Derivative(Delta)));
K := BaseRing(BaseRing(Q));
Kx<x>:=RationalFunctionField(K);
Kxy<y>:=PolynomialRing(Kx);
d:=Degree(Q);
// Syl is (the transpose of) the Sylvester matrix for f, df/dy
Syl:=ZeroMatrix(Kx,2*d-1,2*d-1);
coefs1:=Reverse(Coefficients(Q));
coefs2:=Reverse(Coefficients(Derivative(Q)));
for i:=1 to d-1 do
for j:=1 to d+1 do
Syl[i,i+j-1]:=coefs1[j];
end for;
end for;
for i:=d to 2*d-1 do
for j:=1 to d do
Syl[i,i-d+j]:=coefs2[j];
end for;
end for;
v:=[Kx|];
for i:=1 to 2*d-2 do
v[i]:=0;
end for;
v[2*d-1]:=Delta;
M:=RModule(Kx,2*d-1);
sol:=Solution(Syl,M!v);
com_fac:=Delta;
for i:=1 to d do
com_fac:=GCD(com_fac,Numerator(sol[2*d-i]));
end for;
Delta:=Numerator(Delta/com_fac);
for i:=1 to d do
sol[2*d-i]:=sol[2*d-i]/com_fac;
end for;
s:=Parent(Q)!0;
for i:=1 to d do
s:=s+(BaseRing(Parent(Q))!Numerator(sol[2*d-i]))*(Parent(Q).1)^(i-1);
end for;
// (s*Derivative(Q)-Delta)/Q; // test
return BaseRing(Parent(Q))!r,BaseRing(Parent(Q))!Delta,Parent(Q)!s;
end function;
function genus(Q,p)
// Computes the genus of the smooth projective curve defined by Q
K := BaseRing(BaseRing(Q));
if IsCoercible(K, p) then
p := p*Integers(K);
end if;
if not IsPrime(p) then
genera := [genus(Q, pri[1]) : pri in Factorization(p)];
assert &and[g eq genera[1] : g in genera];
return genera[1];
end if;
Fp,res:=ResidueClassField(p);
A2:=AffineSpace(Fp,2);
Fpxy:=CoordinateRing(A2);
Qmodp:=Fpxy!0;
C:=Coefficients(Q);
for i:=1 to #C do
D:=Coefficients(C[i]);
for j:=1 to #D do
Qmodp+:=res(D[j])*Fpxy.1^(j-1)*Fpxy.2^(i-1);
end for;
end for;
if not IsIrreducible(Qmodp) then
error "bad prime";
end if;
g:=Genus(Curve(A2,Qmodp));
return g;
end function;
function smooth(f,p)
// Is f mod p separable?
K := BaseRing(f);
if IsCoercible(K, p) then
p := p*Integers(K);
end if;
if not IsPrime(p) then
return &and[smooth(f, pri[1]) : pri in Factorization(p)];
end if;
Fp,res:=ResidueClassField(p);
Fpx:=PolynomialRing(Fp);
fmodp := &+[res(Coefficient(f, i))*Fpx.1^i : i in [0 .. Degree(f)]];
return (Degree(fmodp) eq Degree(f) and IsSeparable(fmodp));
end function;
function log(p,x)
if x gt 0 then
return Log(p,x);
else
return 0;
end if;
end function;
function is_integral(A,p)
// Is the matrix A p-adically integral?
K := BaseRing(BaseRing(A));
if IsCoercible(K, p) then
p := p*Integers(K);
end if;
if not IsPrime(p) then
return &and[is_integral(A, pri[1]) : pri in Factorization(p)];
end if;
A:=A*Denominator(A);
for i:=1 to NumberOfRows(A) do
for j:=1 to NumberOfColumns(A) do
if A[i,j] ne 0 then
coeffs := Coefficients(Numerator(A[i,j]));
if K eq Rationals() then
ChangeUniverse(~coeffs, RationalsAsNumberField());
end if;
m:=Minimum([Valuation(x,p) : x in Coefficients(Numerator(A[i,j]))]);
if m lt 0 then
return false;
end if;
end if;
end for;
end for;
return true;
end function;