Path: blob/master/sage/schemes/hyperelliptic_curves/hypellfrob.pyx
4126 views
r"""1Frobenius on Monsky-Washnitzer cohomology of a hyperelliptic curve over GF(p),2for largish p34This is a wrapper for the matrix() function in hypellfrob.cpp.56AUTHOR:7-- David Harvey (2007-05)8-- David Harvey (2007-12): rewrote for hypellfrob version 2.09"""1011#################################################################################12# Copyright (C) 2007 David Harvey <[email protected]>13# William Stein <[email protected]>14#15# Distributed under the terms of the GNU General Public License (GPL)16#17# http://www.gnu.org/licenses/18#*****************************************************************************192021from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ22from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX23from sage.libs.ntl.ntl_mat_ZZ cimport ntl_mat_ZZ24from sage.libs.ntl.all import ZZ, ZZX25from sage.matrix.all import Matrix26from sage.rings.all import Qp, O as big_oh27from sage.rings.arith import is_prime2829include "sage/libs/ntl/decl.pxi"30include "sage/ext/interrupt.pxi"313233cdef extern from "hypellfrob.h":34int hypellfrob_matrix "hypellfrob::matrix" (mat_ZZ_c output, ZZ_c p, int N, ZZX_c Q)353637def hypellfrob(p, N, Q):38r"""39Computes the matrix of Frobenius acting on the Monsky-Washnitzer cohomology40of a hyperelliptic curve $y^2 = Q(x)$, with respect to the basis $x^i dx/y$,41$0 \leq i < 2g$.4243INPUT:44p -- a prime45Q -- a monic polynomial in $\Z[x]$ of odd degree. Must have no multiple46roots mod p.47N -- precision parameter; the output matrix will be correct modulo $p^N$.4849PRECONDITIONS:50Must have $p > (2g+1)(2N-1)$, where $g = (\deg(Q)-1)/2$ is the genus51of the curve.5253ALGORITHM:54Described in ``Kedlaya's algorithm in larger characteristic'' by David55Harvey. Running time is theoretically soft-$O(p^{1/2} N^{5/2} g^3)$.5657TODO:58Remove the restriction on $p$. Probably by merging in Robert's code,59which eventually needs a fast C++/NTL implementation.6061EXAMPLES:62sage: from sage.schemes.hyperelliptic_curves.hypellfrob import hypellfrob63sage: R.<x> = PolynomialRing(ZZ)64sage: f = x^5 + 2*x^2 + x + 1; p = 10165sage: M = hypellfrob(p, 4, f); M66[ 91844754 + O(101^4) 38295665 + O(101^4) 44498269 + O(101^4) 11854028 + O(101^4)]67[ 93514789 + O(101^4) 48987424 + O(101^4) 53287857 + O(101^4) 61431148 + O(101^4)]68[ 77916046 + O(101^4) 60656459 + O(101^4) 101244586 + O(101^4) 56237448 + O(101^4)]69[ 58643832 + O(101^4) 81727988 + O(101^4) 85294589 + O(101^4) 70104432 + O(101^4)]70sage: -M.trace()717 + O(101^4)72sage: sum([legendre_symbol(f(i), p) for i in range(p)])73774sage: ZZ(M.det())751020176sage: M = hypellfrob(p, 1, f); M77[ 0 + O(101) 0 + O(101) 93 + O(101) 62 + O(101)]78[ 0 + O(101) 0 + O(101) 55 + O(101) 19 + O(101)]79[ 0 + O(101) 0 + O(101) 65 + O(101) 42 + O(101)]80[ 0 + O(101) 0 + O(101) 89 + O(101) 29 + O(101)]8182AUTHORS:83-- David Harvey (2007-05)84-- David Harvey (2007-12): updated for hypellfrob version 2.08586"""8788# Sage objects that wrap the NTL objects89cdef ntl_ZZ pp90cdef ntl_ZZX QQ91cdef ntl_mat_ZZ mm # the result will go in mm92cdef int i, j9394if N < 1:95raise ValueError, "N must be an integer >= 1"9697Q = Q.list()98if len(Q) < 4 or len(Q) % 2 or Q[-1] != 1:99raise ValueError, "Q must be a monic polynomial of odd degree >= 3"100QQ = ZZX(Q)101102bound = (len(Q) - 1) * (2*N - 1)103if p <= bound:104raise ValueError, "In the current implementation, p must be greater than (2g+1)(2N-1) = %s" % bound105106if not is_prime(p):107raise ValueError, "p (= %s) must be prime" % p108109pp = ZZ(p)110111cdef int g # the genus112g = (len(Q) / 2) - 1113114# Note: the C++ code actually resets the size of the matrix, but this seems115# to confuse the Sage NTL wrapper. So to be safe I'm setting it ahead of116# time.117mm = ntl_mat_ZZ(2*g, 2*g)118119cdef int result120sig_on()121result = hypellfrob_matrix(mm.x, pp.x, N, QQ.x)122sig_off()123124if not result:125raise ValueError, "Could not compute frobenius matrix, because the curve is singular at p."126127R = Qp(p, N, print_mode="terse")128prec = big_oh(p**N)129data = [[mm[j, i]._integer_() + prec for i from 0 <= i < 2*g] for j from 0 <= j < 2*g]130return Matrix(R, data)131132133################ end of file134135136