{{{id=10| /// }}} {{{id=1| %python from sage.misc.cachefunc import CachedFunction @cached_function def Cartier_matrix(self): r""" INPUT: - 'self' - Hyperelliptic Curve of the form y^2 = f(x) over a finite field, Fq OUTPUT: - 'matrix(Fq,M)' The matrix M = (c_(pi-j)), f(x)^((p-1)/2) = \sum c_i x^i - 'Coeff' List of Coeffs of F, this is needed for Hasse-Witt function. - 'g' genus of the curve self, this is needed by a-number. - 'Fq' is the base field of self, and it is needed for Hasse-Witt - 'p' is the char(Fq), this is needed for Hasse-Witt. """ #Compute the finite field and prime p. Fq=self.base_ring(); p=Fq.characteristic() #checks if p == 2: raise ValueError, "p must be odd"; g = self.genus() #retrieve the function f(x) ,where y^2=f(x) f,h = self.hyperelliptic_polynomials() #This implementation only deals with h=0 if h !=0: raise ValueError, "E must be of the form y^2 = f(x)" d = f.degree() #this implementation is for odd degree only, even degree will be handled later. if d%2 == 0: raise ValueError, "In this implementation the degree of f must be odd" #Compute resultant to make sure no repeated roots df=f.derivative() R=df.resultant(f) if R == 0: raise ValueError, "so curve is not smooth" #computing F, since the entries of the matrix are c_i where F= \sum c_i x^i F = f**((p-1)/2) #coefficients returns a_0, ... , a_n where f(x) = a_n x^n + ... + a_0 Coeff = F.list() #inserting zeros when necessary-- that is, when deg(F) < p*g-1, (simplified if p <2g-1) #which is the highest powered coefficient needed for our matrix #So we don't have enough coefficients we add extra zeros to have the same poly, #but enough coeff. zeros = [0 for i in range(p*g-len(Coeff))] Coeff = Coeff + zeros # compute each row of matrix as list and then M=list of lists(rows) M=[]; for j in range(1,g+1): H=[Coeff[i] for i in range((p*j-1), (p*j-g-1),-1)] M.append(H); return matrix(Fq,M), Coeff, g, Fq,p /// }}} {{{id=5| %python @cached_function def Hasse_Witt(self): r""" INPUT: - 'self' - Hyperelliptic Curve of the form y^2 = f(x) over a finite field OUTPUT: - 'N' - The matrix N = M M^(p)...M^(p^(g-1)) where M = (c_(pi-j)), f(x)^((p-1)/2) = \sum c_i x^i """ # If Cartier Matrix is already cached for this curve, use that or evaluate it to get M, #Coeffs, genus, Fq=base field of self, p=char(Fq). This is so we have one less matrix to #compute. A=Cartier_matrix.get_cache(); print A.keys()[-1][0][0], self if A.keys()[-1][0][0]==self: print "c cached"; M,Coeffs,g, Fq, p = A.items()[-1][1]; else: A.clear() M, Coeffs,g, Fq, p= Cartier_matrix(self) def frob_mat(Coeffs, k): a = p**k mat = [] Coeffs_pow = [c**a for c in Coeffs] for i in range(1,g+1): H=[(Coeffs[j]) for j in range((p*i-1), (p*i - g-1), -1)] mat.append(H); return matrix(Fq,mat) #Computes all the different possible action of frobenius on matrix M and stores in list Mall Mall = [M] + [frob_mat(Coeffs,k) for k in srange(1,g)] #initial N=I, so we can go through Mall and multiply all matrices with I and #get the Hasse-Witt matrix. N = identity_matrix(Fq,g) for l in Mall: N = N*l; return N /// }}} {{{id=2| %python def a_number(self): r""" INPUT: - 'self' - Hyperelliptic Curve of the form y^2 = f(x) over a finite field, Fq OUTPUT: - 'a' - a-number """ A=Cartier_matrix.get_cache(); if A.keys()[-1][0][0]==self: print "c cached in a"; M,Coeffs,g, Fq, p = A.items()[0][1]; else: A.clear() M, Coeffs,g, Fq, p= Cartier_matrix(self) a=g-rank(M); return a; /// }}} {{{id=6| %python def p_rank(self): r""" INPUT: - 'self' - Hyperelliptic Curve of the form y^2 = f(x) over a finite field, Fq OUTPUT: - 'pr' - r-rank """ A=Hasse_Witt.get_cache(); if A.keys()[-1][0][0]==self: print "H is cached"; N = A.items()[0][1]; else: A.clear() N= Hasse_Witt(self) pr=rank(N); return pr /// }}} {{{id=3| for p in srange(7,20): if p.is_prime(): P.=GF(p,'a')[]; E = HyperellipticCurve(x^11+x+1,0); # print p, Cartier_matrix1(E),Hasse_Witt(E),a_number(E), p_rank(E); print p, timeit('Cartier_matrix(E)'), timeit('Hasse_Witt(E)'), timeit('a_number(E)'), timeit('p_rank(E)'); /// 7 625 loops, best of 3: 1.27 ms per loop None 625 loops, best of 3: 1.27 ms per loop None 625 loops, best of 3: 31.7 µs per loop None 625 loops, best of 3: 30.9 µs per loop None 11 625 loops, best of 3: 1.26 ms per loop None 625 loops, best of 3: 1.27 ms per loop None 625 loops, best of 3: 31.6 µs per loop None 625 loops, best of 3: 30.7 µs per loop None 13 625 loops, best of 3: 1.26 ms per loop None 625 loops, best of 3: 1.26 ms per loop None 625 loops, best of 3: 31.5 µs per loop None 625 loops, best of 3: 30.8 µs per loop None 17 625 loops, best of 3: 1.27 ms per loop None 625 loops, best of 3: 1.27 ms per loop None 625 loops, best of 3: 31.5 µs per loop None 625 loops, best of 3: 30.9 µs per loop None 19 625 loops, best of 3: 1.26 ms per loop None 625 loops, best of 3: 1.28 ms per loop None 625 loops, best of 3: 31.8 µs per loop None 625 loops, best of 3: 30.9 µs per loop None }}} {{{id=4| /// }}} {{{id=12| /// 4 }}} {{{id=14| /// }}}