-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcurve_ff.m
186 lines (136 loc) · 5.84 KB
/
curve_ff.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
load "pcontent.m";
load "curve_funcs.m";
// load "curve_funcs.m";
/*
This file is dedicated to all functions that relate to function fields of curves, including differentials.
TODO: improve comments.
TODO: the line "reduce coordinate ring of curve modulo p" might crash if there are p-s in the denominator
*/
// function SaturatedIdealOfCurveAtPrime(C,p)
// if "SaturatedIdeal" in GetAttributes(Type(C)) and
// assigned C`SaturatedIdeal and
// IsDefined(C`SaturatedIdeal, p) then
// return C`SaturatedIdeal[p];
// end if;
// if not "SaturatedIdeal" in GetAttributes(Type(C)) then
// AddAttribute(Type(C), "SaturatedIdeal");
// end if;
// if not assigned C`SaturatedIdeal then
// C`SaturatedIdeal := [];
// end if;
// I := Ideal(C);
// basisI := [ClearDenominators(b) : b in Basis(I)];
// I := Ideal(basisI);
// ambR := CoordinateRing(Ambient(C));
// ambRZ := ChangeRing(ambR, Integers());
// IZ := Ideal([ambRZ ! b:b in basisI]);
// IZsat := Saturation(IZ, ambRZ ! p);
// // C`SaturatedIdeal[p] := IZsat;
// return IZsat;
// end function;
/*
Given a rational function with integer coefficients, we want to reduce the function mod p,
to the function field of the curve modulo p.
TODO: the functions currently only work well with projective curves,
otherwise if affine the function Curve(FF) will return a different curve each time it is called.
To do this we reduce the numerator and denominator modulo the curve ideal,
we then need to reduce the fraction by the highest p-power before reducing modulo p.
Uses external functions:
* ReduceCurveModp
* pContentModI
*/
// intrinsic ReduceRationalFunctionModp(f::FldFunFracSchElt,p::RngIntElt) -> FldFunFracSchElt
// { Reduce rational function element of function field modulo p}
function ReduceRationalFunctionModp(f,p)
assert IsPrime(p);
FF := Parent(f); // The function field of the function f
C := Curve(FF); // The curve defining the function field. CAREFUL: This function does not return the original curve C if C is not projective!
R := CoordinateRing(C);
I := Ideal(C);
basisI := [ClearDenominators(b) : b in Basis(I)]; // make sure that coefficients of the basis of I are integers
I := Ideal(basisI);
ambR := CoordinateRing(Ambient(C));
ambRp := ChangeRing(ambR, GF(p)); // reduce coordinate ring of curve modulo p
// IZsat := SaturatedIdealOfCurveAtPrime(C,p);
// ambRZ := Generic(IZsat);
I := Ideal(C);
basisI := [ClearDenominators(b) : b in Basis(I)];
ambRZ := ChangeRing(ambR, Integers());
IZ := Ideal([ambRZ ! b:b in basisI]); // TODO: We assume that the ideal IZ is saturated at p!
Cp := ReduceCurveModp(C,p);
FFp := FunctionField(Cp);
Ip := Ideal(Cp);
basisIp := Basis(Ip);
Ip := Ideal([ambRp ! b : b in basisIp]);
Rp<[a]> := CoordinateRing(Ambient(Cp));
num1, den1 := IntegralSplit(f,C); // num and den are in ambR, this function is VERY SLOW :(
num2, lcd_num1 := ClearDenominators(num1);
den2, lcd_den1 := ClearDenominators(den1);
num3 := ambRZ ! num2;
den3 := ambRZ ! den2;
content_num3, num4 := ContentAndPrimitivePart(num3);
content_den3, den4 := ContentAndPrimitivePart(den3);
num4p := ambRp ! num4;
den4p := ambRp ! den4;
coeff4 := (lcd_den1 * content_num3) / (lcd_num1 * content_den3);
if not den4p in Ip and Valuation(coeff4, p) ge 0 then
return FFp ! (Evaluate((coeff4 * num4p), a) / Evaluate(den4p,a));
end if;
// if we can't fix the numerator then we will never be able to fix either the denominator
// or the bad coefficient.
if not num4p in Ip then
error "Error in reducing rational function. Nothing we can do to fix p in denominator.";
end if;
coeff_num5,num5 := pContentModI(num4, p, IZ);
if den4p in Ip then
coeff_den5, den5 := pContentModI(den4, p, IZ);
else
coeff_den5 := 1;
den5 := den4;
end if;
num5p := ambRp ! num5;
den5p := ambRp ! den5;
// sanity check:
assert not num5p in Ip and not den5p in Ip;
coeff5 := coeff4 * coeff_num5 / coeff_den5;
if Valuation(coeff5, p) lt 0 then
error "Failed to reduce rational function mod p";
end if;
return FFp ! (Evaluate((coeff5 * num5p), a) / Evaluate(den5p,a));
end function;
// intrinsic ReduceDifferentialModp(d::DiffCrvElt, p::RngIntElt, uni::FldFunFracSchElt) -> DiffCrvElt
// {returns reduction of differential mod p}
function ReduceDifferentialModp(d, p, uni)
C := Curve(d);
du := Differential(uni);
f := d / du;
f_p := ReduceRationalFunctionModp(f,p);
uni_p := ReduceRationalFunctionModp(uni, p);
duni_p := Differential(uni_p);
return f_p * duni_p;
end function;
// intrinsic ValuationOfRationalFunction(f::FldFunFracSchElt,p::RngIntElt) -> RngIntElt
// {returns valuation of a rational function of a curve at a prime p}
function ValuationOfRationalFunction(f,p)
FF := Parent(f);
C := Curve(FF);
// IZsat := SaturatedIdealOfCurveAtPrime(C,p);
// ambRZ := Generic(IZsat);
ambR := CoordinateRing(Ambient(C));
I := Ideal(C);
basisI := [ClearDenominators(b) : b in Basis(I)];
ambRZ := ChangeRing(ambR, Integers());
IZ := Ideal([ambRZ ! b:b in basisI]); // TODO: We assume that the ideal IZ is saturated at p!
num1, den1 := IntegralSplit(f,C); // num and den are in ambR
num2, lcd_num1 := ClearDenominators(num1);
den2, lcd_den1 := ClearDenominators(den1);
num3 := ambRZ ! num2;
den3 := ambRZ ! den2;
content_num3, num4 := ContentAndPrimitivePart(num3);
content_den3, den4 := ContentAndPrimitivePart(den3);
coeff_num5, num5 := pContentModI(num4, p, IZ);
coeff_den5, den5 := pContentModI(num5, p, IZ);
coeff := (lcd_den1 * content_num3 * coeff_num5) / (lcd_num1 * content_den3 * coeff_den5);
v := Valuation(coeff,p);
return v;
end function;