Skip to content

Commit f25b88d

Browse files
committed
2 parents ec87d2e + 6e7754c commit f25b88d

File tree

8 files changed

+458
-205
lines changed

8 files changed

+458
-205
lines changed

src/ControlledReduction.jl

Lines changed: 212 additions & 191 deletions
Large diffs are not rendered by default.

src/DeRham.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ using Memoize
1414
#include("NemoAdditions.jl")
1515

1616
include("Utils.jl")
17+
include("GradedExpCache.jl")
1718
include("FindMonomialBasis.jl")
1819
include("SlopesPolygon.jl")
1920
include("PolynomialWithPole.jl")
@@ -31,6 +32,7 @@ include("ExamplePolynomials.jl")
3132

3233
include("ZetaFunction.jl")
3334
include("PointCounts.jl")
35+
include("NewtonPolygon.jl")
3436

3537
# TODO: export Zeta Function functions
3638

src/GradedExpCache.jl

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
2+
abstract type GradedExpCache end
3+
4+
#TODO: convert to SVector, that might help with allocation pressure
5+
#using StaticArrays
6+
7+
struct PolyExpCache <: GradedExpCache
8+
n::Int
9+
termorder::Symbol
10+
exp_vec_pieces::Vector{Union{Vector{Vector{Int64}},Nothing}}
11+
rev_look_pieces::Vector{Union{Dict{Vector{Int64},Int},Nothing}}
12+
13+
PolyExpCache(n,termorder) = new(n,termorder,[],[])
14+
end
15+
16+
17+
"""
18+
Gets the exponent vector cache for the degree d,
19+
returning it as a vector.
20+
21+
This throws an error if the cached degree doesn't exist.
22+
"""
23+
function Base.getindex(c::PolyExpCache,d::Int)
24+
if c.exp_vec_pieces[d] == nothing
25+
errormsg = "This PolyExpCache does not have degree=$d stored. "*
26+
"This probably means that the PolyExpCache hasn't been "*
27+
"fully initialized, or there is a bug. If you want to "*
28+
"initialize this cache to work for degree $d, use the "*
29+
"`get_forward` function."
30+
throw(ArgumentError(errormsg))
31+
end
32+
c.exp_vec_pieces[d]
33+
end
34+
35+
function Base.getindex(c::PolyExpCache,d::Int,kind::Symbol)
36+
if kind == :forward
37+
c[d]
38+
elseif kind == :reverse
39+
40+
if c.rev_look_pieces[d] == nothing
41+
errormsg = "This PolyExpCache does not have degree=$d stored for "*
42+
"reverse lookup. "*
43+
"This probably means that the PolyExpCache hasn't been "*
44+
"fully initialized, or there is a bug. If you want to "*
45+
"initialize this cache to work for degree $d, use the "*
46+
"`get_forward` function."
47+
throw(ArgumentError(errormsg))
48+
end
49+
c.rev_look_pieces[d]
50+
else
51+
throw(ArgumentError("Invalid option for indexing PolyExpCache"))
52+
end
53+
end
54+
55+
56+
function Base.show(io::IO, c::PolyExpCache)
57+
msg = """PolyExpCache for the graded ring k[x_1, ..., x_$(c.n)]
58+
Term order: $(c.termorder)
59+
Terms cached for degrees: $(cached_degrees(c))
60+
Reverse lookups cached for degrees: $(cached_reverse_lookups(c))
61+
"""
62+
print(io, msg)
63+
end
64+
65+
cached_degrees(c::PolyExpCache) = findall(c.exp_vec_pieces .!= nothing)
66+
cached_reverse_lookups(c::PolyExpCache) = findall(c.rev_look_pieces .!= nothing)
67+
68+
function get_forward(c::PolyExpCache,d)
69+
if c.exp_vec_pieces[d] == nothing
70+
generate_degree_forward(c,d)
71+
end
72+
c.exp_vec_pieces[d]
73+
end
74+
75+
function generate_degree_forward(c::PolyExpCache,d)
76+
l = length(c.exp_vec_pieces)
77+
if l < d
78+
append!(c.exp_vec_pieces,fill(nothing,d - l))
79+
end
80+
c.exp_vec_pieces[d] = gen_exp_vec(c.n,d,c.termorder)
81+
end
82+
83+
function generate_degree_reverse(c::PolyExpCache,d)
84+
evs = get_forward(c,d)
85+
86+
l = length(c.rev_look_pieces)
87+
if l < d
88+
append!(c.rev_look_pieces,fill(nothing,d - l))
89+
end
90+
c.rev_look_pieces[d] = Dict(evs[i] => i for i in 1:length(evs))
91+
end
92+
93+
function PolyExpCache(n,termorder,degrees_to_prefill,reverse_to_prefill)
94+
c = PolyExpCache(n,termorder)
95+
for d in degrees_to_prefill
96+
generate_degree_forward(c,d)
97+
end
98+
99+
for d in reverse_to_prefill
100+
generate_degree_reverse(c,d)
101+
end
102+
c
103+
end
104+
105+
function PolyExpCache(n,termorder,max_degree_prefill)
106+
PolyExpCache(n,termorder,1:max_degree_prefill,1:max_degree_prefill)
107+
end
108+
109+

src/NewtonPolygon.jl

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
vp(a, p)
3+
Returns the p-adic valuation of a
4+
5+
INPUTS:
6+
* "a" -- integer
7+
* "p" -- integer, a prime number
8+
"""
9+
function vp(a, p)
10+
@assert is_prime(p)
11+
if a == 0
12+
return Inf
13+
end
14+
15+
e = 0
16+
while mod(a, p) == 0
17+
a = div(a, p)
18+
e = e + 1
19+
end
20+
21+
return e
22+
end
23+
24+
"""
25+
newton_polygon(f, p)
26+
Returns the Newton polygon of f
27+
28+
INPUTS:
29+
* "f" -- list, coefficients of a polynomial, constant term first
30+
* "p" -- integer, a prime number
31+
"""
32+
function newton_polygon(f, p)
33+
@assert is_prime(p)
34+
35+
pts = []
36+
for (i, a) in enumerate(f)
37+
if a != 0
38+
push!(pts, (i-1, vp(a, p)))
39+
end
40+
end
41+
42+
# compute the lower convex hull of points
43+
hull = Tuple{Int64, Int64}[]
44+
for pt in pts
45+
while length(hull) >= 2
46+
(x1, y1) = hull[end-1]
47+
(x2, y2) = hull[end]
48+
(x3, y3) = pt
49+
# Compute cross product to decide whether pt is "below" the last segment.
50+
cp = (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1)
51+
if cp <= 0
52+
pop!(hull)
53+
else
54+
break
55+
end
56+
end
57+
push!(hull, pt)
58+
end
59+
return SlopesPolygon(hull)
60+
#return hull
61+
end
62+
63+
64+

src/SlopesPolygon.jl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,22 @@ end
103103
"""
104104
Given an array of vertices
105105
"""
106-
function SlopesPolygon(vertices::Array{Tuple{Int,Int}})
106+
#function SlopesPolygon(vertices::Array{Tuple{Int,Int}})
107+
function SlopesPolygon(vertices::Vector{Tuple{Int64, Int64}})
107108
#TODO implement
108109

109110
n = length(vertices)-1
110111
slopelengths = zeros(Int,n)
111112
slopes = zeros(Rational{Int},n)
112-
for i = 2:n
113+
for i = 2:n+1
113114
slopevec = vertices[i] .- vertices[i-1]
114-
push!(slopes, slopevec[2] // slopevec[1])
115-
push!(slopelengths,slopevec[2])
115+
#push!(slopes, slopevec[2] // slopevec[1])
116+
#push!(slopelengths,slopevec[2])
117+
slopes[i-1] = slopevec[2] // slopevec[1]
118+
slopelengths[i-1] = slopevec[2]
116119
end
117-
120+
println(slopelengths)
121+
println(slopes)
118122
SlopesPolygon(slopes,slopelengths,values(slopes,slopelengths)...)
119123
end
120124

src/Utils.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ partials = [ derivative(polynomial, i) for i in 1:(n+1) ]
2828
# TODO: Ensure partials are not all zero.
2929

3030
"""
31-
t gen_exp_vec(n, d, order)
31+
gen_exp_vec(n, d, order)
3232
3333
Returns all nonnegative integer lists of length n who entires sum to d
3434

src/ZetaFunction.jl

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,48 @@ end
3333

3434
default_params() = ZetaFunctionParams(false,false,:costachunks,:invlex,true,false,false,false)
3535

36+
"""
37+
Give the minimal PolyExpCache needed for controlled reduction
38+
as in Prop 1.15 of Costa's thesis.
39+
40+
n in this function is the number of variables minus one,
41+
i.e. the weight of the affine Monsky-Washnitzer homology module.
42+
43+
the d we need are
44+
45+
FORWARD:
46+
h*d - n - 1 for h in 1:n (if such values are positive)
47+
d*n - n
48+
d*n - n - 1
49+
d*n - n - length(S),
50+
d*n - n - length(S) + 1,
51+
d*n - n + d - length(S) + 1,
52+
d
53+
54+
REVERSE:
55+
d
56+
n*d - n
57+
58+
"""
59+
function controlled_reduction_cache(n,d,S,termorder)
60+
degsforward = [d*n - n,
61+
d*n - n - 1,
62+
d*n - n - length(S),
63+
d*n - n - length(S) + 1,
64+
d*n - n + d - length(S),
65+
d]
66+
for h in 1:n
67+
if 0 < h*d - n - 1
68+
append!(degsforward,h*d - n - 1)
69+
end
70+
end
71+
#append!(degsforward,[h*d - n - 1 for h in 1:n])
72+
73+
degsreverse = [d,n*d - n]
74+
75+
PolyExpCache(n+1,termorder,degsforward,degsreverse)
76+
end
77+
3678
"""
3779
compute_frobenius_matrix(n,d,Reductions,T)
3880
@@ -44,15 +86,18 @@ INPUTS:
4486
* "N" -- integer, series precision
4587
* "Reductions" -- output of computeReductionOfTransformLA
4688
* "T" -- output of computeT
89+
* "Basis" -- ?????
90+
* "params" -- the ControlledReductionParamaters
91+
* "cache" -- the GradedExpCache used for this controlled reduction
4792
"""
48-
function compute_frobenius_matrix(n, p, d, N_m, Reductions, T, Basis, params)
93+
function compute_frobenius_matrix(n, p, d, N_m, Reductions, T, Basis, params, cache)
4994
verbose = params.verbose
5095
termorder = params.termorder
5196
(9 < verbose) && println("Terms after controlled reduction: $Reductions")
5297
R = parent(T[1,1])
5398
frob_mat_temp = []
5499
denomArray = []
55-
ev = gen_exp_vec(n+1,d*n-n-1,termorder)
100+
ev = cache[d*n-n-1]#gen_exp_vec(n+1,d*n-n-1,termorder)
56101
VS = matrix_space(R,length(ev),1)
57102
for i in 1:length(Reductions)
58103
e = Basis[i][2] # pole order of basis element
@@ -281,9 +326,14 @@ function zeta_function(f; S=[-1], verbose=false, givefrobmat=false, algorithm=:c
281326
n = nvars(PR) - 1
282327
d = total_degree(f)
283328
R = coefficient_ring(PR)
329+
if S == [-1]
330+
S = collect(0:n)
331+
end
284332

285333
params = ZetaFunctionParams(verbose,givefrobmat,algorithm,termorder,vars_reversed,fastevaluation,always_use_bigints,use_gpu)
286334

335+
cache = controlled_reduction_cache(n,d,S,termorder)
336+
287337
(9 < verbose) && println("Working with a degree $d hypersurface in P^$n")
288338

289339
basis = compute_monomial_bases(f, R, PR, params.termorder) # basis of cohomology
@@ -317,9 +367,6 @@ function zeta_function(f; S=[-1], verbose=false, givefrobmat=false, algorithm=:c
317367
precisionringpoly, pvars = polynomial_ring(precisionring, ["x$i" for i in 0:n])
318368

319369
#S = SmallestSubsetSmooth.smallest_subset_s_smooth(fLift,n)
320-
if S == [-1]
321-
S = collect(0:n)
322-
end
323370

324371
if (0 < verbose)
325372
println("Starting linear algebra problem")
@@ -409,7 +456,7 @@ function zeta_function(f; S=[-1], verbose=false, givefrobmat=false, algorithm=:c
409456
#end
410457
#TODO: check which algorithm we're using
411458
(2 < verbose) && println("Pseudo inverse matrix:\n$pseudo_inverse_mat")
412-
Reductions = reducetransform(FBasis, N_m, S, fLift, pseudo_inverse_mat, p, params)
459+
Reductions = reducetransform(FBasis, N_m, S, fLift, pseudo_inverse_mat, p, params, cache)
413460
(1 < verbose) && println(Reductions)
414461
#return Reductions
415462
#if (1 < verbose)
@@ -420,9 +467,10 @@ function zeta_function(f; S=[-1], verbose=false, givefrobmat=false, algorithm=:c
420467
# println()
421468
# end
422469
#end
423-
ev = gen_exp_vec(n+1,n*d-n-1,termorder)
470+
ev = cache[n*d - n - 1]
471+
#ev = gen_exp_vec(n+1,n*d-n-1,termorder)
424472
(9 < verbose) && println(convert_p_to_m([Reductions[1][1][1],Reductions[2][1][1]],ev))
425-
FM = compute_frobenius_matrix(n, p, d, N_m, Reductions, T, Basis, params)
473+
FM = compute_frobenius_matrix(n, p, d, N_m, Reductions, T, Basis, params, cache)
426474
# display(FM)
427475
(9 < verbose) && println("The Frobenius matrix is $FM")
428476

test/varieties/failing.csv

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,8 @@ n;p;f;zeta_function
1010
3;19;x1^4*x2 + x1*x3^4 + x2^4*x3;ZZRingElem[]
1111
3;11;5*x1^6*x2 + 3*x1^6*x3 + 7*x1^5*x2^2 + 9*x1^5*x2*x3 + x1^5*x3^2 + 8*x1^4*x2^3 + x1^4*x2^2*x3 + 5*x1^4*x2*x3^2 + 6*x1^3*x2^4 + 6*x1^3*x2^3*x3 + 9*x1^3*x2^2*x3^2 + 8*x1^3*x2*x3^3 + 5*x1^3*x3^4 + 5*x1^2*x2^5 + 2*x1^2*x2^4*x3 + 7*x1^2*x2^3*x3^2 + 4*x1^2*x2*x3^4 + 10*x1^2*x3^5 + 7*x1*x2^6 + 3*x1*x2^5*x3 + 5*x1*x2^4*x3^2 + 8*x1*x2^3*x3^3 + 2*x1*x2^2*x3^4 + 3*x1*x2*x3^5 + 5*x1*x3^6 + 2*x2^7 + 4*x2^6*x3 + 2*x2^5*x3^2 + 2*x2^4*x3^3 + 9*x2^3*x3^4 + 7*x2^2*x3^5 + 4*x2*x3^6 + 2*x3^7;ZZRingElem[4177248169415651,-1518999334332964,655931530734689,-200859416110144,34237400473320,-8455600419926,858292959524,-267305524607,68887149485,-21921295814,5806049601,2472191414,-1995260839,889046048,-336993701,104438702,-30635791,7347488,-1499069,168854,36051,-12374,3535,-1247,364,-326,120,-64,19,-4,1]
1212
3;17;x1^3 + x2^3 + x3^3;ZZRingElem[]
13+
4;11;x1^3 + x1^2*x2 + x1^2*x3 + x1^2*x4 + x1*x2^2 + x1*x2*x3 + x1*x2*x4 + x1*x3^2 + x1*x3*x4 + x1*x4^2 + x2^3 + x2^2*x3 + x2^2*x4 + x2*x3^2 + x2*x3*x4 + x2*x4^2 + x3^3 + x3^2*x4 + x3*x4^2 + x4^3;ZZRingElem[]
14+
3;11;x1^3*x2 + 6*x1^3*x3 + 3*x1^2*x2^2 + 5*x1^2*x3^2 + 5*x1*x2^3 + 10*x1*x2^2*x3 + 9*x1*x3^3 + 8*x2^4 + 7*x2^3*x3 + 7*x2^2*x3^2 + x2*x3^3 + 3*x3^4;ZZRingElem[]
15+
4;13;9*x1^3 + 9*x1^2*x2 + 3*x1^2*x3 + 2*x1^2*x4 + 7*x1*x2^2 + x1*x2*x3 + 12*x1*x2*x4 + 3*x1*x3^2 + 6*x1*x3*x4 + 2*x1*x4^2 + 9*x2^3 + 12*x2^2*x3 + 3*x2^2*x4 + 3*x2*x3^2 + 3*x2*x3*x4 + 3*x2*x4^2 + 12*x3^3 + 3*x3^2*x4 + 9*x3*x4^2;ZZRingElem[]
16+
4;13;x1^3 + x1^2*x2 + x1^2*x3 + x1^2*x4 + x1*x2^2 + x1*x2*x3 + x1*x2*x4 + x1*x3^2 + x1*x3*x4 + x1*x4^2 + x2^3 + x2^2*x3 + x2^2*x4 + x2*x3^2 + x2*x3*x4 + x2*x4^2 + x3^3 + x3^2*x4 + x3*x4^2 + x4^3;ZZRingElem[]
17+
3;13;x1^3 + x1*x3^2 + x2^3;ZZRingElem[13,-2,1]

0 commit comments

Comments
 (0)