Beispiel #1
0
    def T(self, n):
        """
        Return matrix mod 2 of the n-th Hecke operator on the +1
        quotient of cuspidal modular symbols.

        INPUT:

            - `n` -- integer

        OUTPUT:

            matrix modulo 2

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.T(2)
            22 x 22 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries)
            sage: C.T(2)[0]
            (1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1)
        """
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print("T(%s) start" % (n))
        
        T = self.M.hecke_matrix(n).restrict(self.S_integral, check=False)
    
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "T created")
        if self.verbose: print("sparsity", len(T.nonzero_positions()) / RR(T.nrows()**2), T.nrows())
        T = matrix_modp(T)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "T reduced")
        #self.M._hecke_matrices={}
        #self.S._hecke_matrices={}
        #if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "T freed"
        return matrix_modp(T)
Beispiel #2
0
 def verify_gamma1(self,d,t,v):
     dependencies=[]
     if self.verbose: tm = cputime(); mem = get_memory_usage(); print "verif gamma1 start"
     satisfied=True
     message=""
     for i in xrange(d, (d - 1) // 2, -1):
     #We only need to start at d/2 since the dependencies(k,l) contains all neccesary
     #checks for largest partition of zise at most k and second largest at most l
         dependency = self.dependencies(t, i, d - i, v)
         dependencies.append(dependency)
         if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "dep (%s,%s)" % (i, d - i)
         assert dependency.degree() == len(self.coset_representatives_H()) * (d - i) + 2 * i - d
         assert dependency.degree() - dependency.dimension() <= self.S.dimension()
         if dependency.dimension() == 0:
             if self.verbose: print "...no dependencies found"
         elif dependency.dimension() > 12:
             satisfied=False
             print "dependency dimension to large to search through"
         else:
             if self.verbose: print "dependency dimension is:", dependency.dimension()
             min_dist = LinearCode(dependency).minimum_distance()
             if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "min dist"
             if self.verbose: print "...the smallest dependency has %s nonzero coefficients." % (min_dist)
             if min_dist > d:
                 if self.verbose: print i, d - i, "passed"
             else:
                 satisfied,message= False, "There is a dependency of weigt %s in dependencies(%s,%s)" % (min_dist, i, d - i)
     return satisfied, message,dependencies
Beispiel #3
0
def render_curve_webpage_by_label(label):
    cpt0 = cputime()
    t0 = time.time()
    data = WebEC.by_label(label)
    if data == "Invalid label":
        return elliptic_curve_jump_error(label, {})
    if data == "Curve not found":
        return elliptic_curve_jump_error(label, {}, missing_curve=True)
    try:
        lmfdb_label = data.lmfdb_label
    except AttributeError:
        return elliptic_curve_jump_error(label, {})

    data.modform_display = url_for(".modular_form_display", label=lmfdb_label, number="")

    code = data.code()
    code['show'] = {'magma':'','pari':'','sage':''} # use default show names
    T =  render_template("ec-curve.html",
                         properties=data.properties,
                         credit=ec_credit(),
                         data=data,
                         # set default show names but actually code snippets are filled in only when needed
                         code=code,
                         bread=data.bread, title=data.title,
                         friends=data.friends,
                         downloads=data.downloads,
                         KNOWL_ID="ec.q.%s"%lmfdb_label,
                         BACKUP_KNOWL_ID="ec.q.%s"%data.lmfdb_iso,
                         learnmore=learnmore_list())
    ec_logger.debug("Total walltime: %ss"%(time.time() - t0))
    ec_logger.debug("Total cputime: %ss"%(cputime(cpt0)))
    return T
Beispiel #4
0
def render_curve_webpage_by_label(label):
    cpt0 = cputime()
    t0 = time.time()
    data = WebEC.by_label(label)
    if data == "Invalid label":
        return elliptic_curve_jump_error(label, {}, wellformed_label=False)
    if data == "Curve not found":
        return elliptic_curve_jump_error(label, {}, wellformed_label=True, missing_curve=True)
    try:
        lmfdb_label = data.lmfdb_label
    except AttributeError:
        return elliptic_curve_jump_error(label, {}, wellformed_label=False)

    data.modform_display = url_for(".modular_form_display", label=lmfdb_label, number="")

    code = data.code()
    code['show'] = {'magma':'','pari':'','sage':''} # use default show names
    T =  render_template("ec-curve.html",
                         properties2=data.properties,
                         credit=ec_credit(),
                         data=data,
                         # set default show names but actually code snippets are filled in only when needed
                         code=code,
                         bread=data.bread, title=data.title,
                         friends=data.friends,
                         downloads=data.downloads,
                         KNOWL_ID="ec.q.%s"%label,
                         BACKUP_KNOWL_ID="ec.q.%s"%data.lmfdb_iso,
                         learnmore=learnmore_list())
    ec_logger.debug("Total walltime: %ss"%(time.time() - t0))
    ec_logger.debug("Total cputime: %ss"%(cputime(cpt0)))
    return T
Beispiel #5
0
def compute_ambient_space(N, k, i):
    if i == 'all':
        G = DirichletGroup(N).galois_orbits()
        sgn = (-1)**k
        for j, g in enumerate(G):
            if g[0](-1) == sgn:
                compute_ambient_space(N,k,j)
        return

    if i == 'quadratic':
        G = DirichletGroup(N).galois_orbits()
        sgn = (-1)**k
        for j, g in enumerate(G):
            if g[0](-1) == sgn and g[0].order()==2:
                compute_ambient_space(N,k,j)
        return

    filename = filenames.ambient(N, k, i)
    if os.path.exists(filename):
        return

    eps = character(N, i)
    t = cputime()
    M = ModularSymbols(eps, weight=k, sign=1)
    tm = cputime(t)
    save(M, filename)
    meta = {'cputime':tm, 'dim':M.dimension(), 'M':str(M), 'version':version()}
    save(meta, filenames.meta(filename))
Beispiel #6
0
    def T(self, n):
        """
        Return matrix mod 2 of the n-th Hecke operator on the +1
        quotient of cuspidal modular symbols.

        INPUT:

            - `n` -- integer

        OUTPUT:

            matrix modulo 2

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.T(2)
            22 x 22 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries)
            sage: C.T(2)[0]
            (1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1)
        """
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print "T(%s) start" % (n)
        
        T = self.M.hecke_matrix(n).restrict(self.S_integral, check=False)
    
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "T created"
        if self.verbose: print "sparsity", len(T.nonzero_positions()) / RR(T.nrows()**2), T.nrows()
        T = matrix_modp(T)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "T reduced"
        #self.M._hecke_matrices={}
        #self.S._hecke_matrices={}
        #if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "T freed"
        return matrix_modp(T)
Beispiel #7
0
def compute_atkin_lehner(N, k, i):
    filename = filenames.ambient(N, k, i)
    if not os.path.exists(filename):
        print "Ambient (%s,%s,%s) space not computed."%(N,k,i)
        return
        #compute_ambient_space(N, k, i)

    print "computing atkin-lehner for (%s,%s,%s)"%(N,k,i)
    m = filenames.number_of_known_factors(N, k, i)    
    M = load_ambient_space(N, k, i)
    for d in range(m):
        atkin_lehner_file = filenames.factor_atkin_lehner(N, k, i, d, False)
        if os.path.exists(atkin_lehner_file):
            print "skipping computing atkin_lehner for (%s,%s,%s,%s) since it already exists"%(N,k,i,d)
            # already done
            continue
        
        # compute atkin_lehner
        print "computing atkin_lehner for (%s,%s,%s,%s)"%(N,k,i,d)
        t = cputime()
        A = load_factor(N, k, i, d, M)
        al = ' '.join(['+' if a > 0 else '-' for a in atkin_lehner_signs(A)])
        print al
        open(atkin_lehner_file, 'w').write(al)
        tm = cputime(t)
        meta = {'cputime':tm, 'version':version()}
        save(meta, filenames.meta(atkin_lehner_file))
Beispiel #8
0
 def verify_gamma1(self,d,t,v):
     dependencies=[]
     if self.verbose: tm = cputime(); mem = get_memory_usage(); print("verif gamma1 start")
     satisfied=True
     message=""
     for i in range(d, (d - 1) // 2, -1):
     #We only need to start at d/2 since the dependencies(k,l) contains all neccesary
     #checks for largest partition of zise at most k and second largest at most l
         dependency = self.dependencies(t, i, d - i, v)
         dependencies.append(dependency)
         if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "dep (%s,%s)" % (i, d - i))
         assert dependency.degree() == len(self.coset_representatives_H()) * (d - i) + 2 * i - d
         assert dependency.degree() - dependency.dimension() <= self.S.dimension()
         if dependency.dimension() == 0:
             if self.verbose: print("...no dependencies found")
         elif dependency.dimension() > 12:
             satisfied=False
             print("dependency dimension to large to search through")
         else:
             if self.verbose: print("dependency dimension is:", dependency.dimension())
             min_dist = LinearCode(dependency).minimum_distance()
             if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "min dist")
             if self.verbose: print("...the smallest dependency has %s nonzero coefficients." % (min_dist))
             if min_dist > d:
                 if self.verbose: print(i, d - i, "passed")
             else:
                 satisfied,message= False, "There is a dependency of weigt %s in dependencies(%s,%s)" % (min_dist, i, d - i)
     return satisfied, message,dependencies
Beispiel #9
0
    def g(N):
        from sage.misc.misc import alarm, cancel_alarm
        alarm(maxtime)
        from sqlalchemy import create_engine
        from sqlalchemy.orm import sessionmaker
        engine = create_engine('postgresql://[email protected]:6432/mrc2', echo=False)
        s = sessionmaker(bind=engine)()
        t = cputime()
        x,y,z = ideal_to_tuple(N)
        q = s.query(Space).filter(Space.x==x).filter(Space.y==y).filter(Space.z==z)
        if q.count() > 0:
            M = q.one()
            if M.number_of_rational_newforms == len(M.rational_newforms):
                return "Already done with level %s (norm = %s)"%(N, N.norm())
            H = M.hmf()
        else:
            H = QuaternionicModule(N)
            M = store_space(s, H)
        V, rational_oldform_dimension = H.dual_rational_newforms(verb=verb)
        for vdual, aplist in V:
            f = RationalNewform()
            for p, ap in aplist:
                f.store_eigenvalue(p, ap)
            M.rational_newforms.append(f)
            f.dual_vector = ns_str(canonically_scale(vdual))
        M.number_of_rational_newforms = len(V)
        M.rational_oldform_dimension = int(rational_oldform_dimension)
        M.time_to_compute_newforms = cputime(t)
        s.commit()

        cancel_alarm()
        return N.norm(), cputime(t), len(V)
Beispiel #10
0
def compute_aplists(N, k, i, *args):
    if i == 'all':
        G = DirichletGroup(N).galois_orbits()
        sgn = (-1)**k
        for j, g in enumerate(G):
            if g[0](-1) == sgn:
                compute_aplists(N,k,j,*args)
        return

    if i == 'quadratic':
        G = DirichletGroup(N).galois_orbits()
        sgn = (-1)**k
        for j, g in enumerate(G):
            if g[0](-1) == sgn and g[0].order()==2:
                compute_aplists(N,k,j,*args)
        return

    if len(args) == 0:
        args = (100, )

    filename = filenames.ambient(N, k, i)
    if not os.path.exists(filename):
        print "Ambient (%s,%s,%s) space not computed."%(N,k,i)
        return
        #compute_ambient_space(N, k, i)

    print "computing aplists for (%s,%s,%s)"%(N,k,i)
        
    m = filenames.number_of_known_factors(N, k, i)

    if m == 0:
        # nothing to do
        return
    
    M = load_ambient_space(N, k, i)
    for d in range(m):
        aplist_file = filenames.factor_aplist(N, k, i, d, False, *args)
        if os.path.exists(aplist_file):
            print "skipping computing aplist(%s) for (%s,%s,%s,%s) since it already exists"%(args, N,k,i,d)
            # already done
            continue
        
        # compute aplist
        print "computing aplist(%s) for (%s,%s,%s,%s)"%(args, N,k,i,d)
        t = cputime()
        A = load_factor(N, k, i, d, M)
        aplist, _ = A.compact_system_of_eigenvalues(prime_range(*args), 'a')
        print aplist, aplist_file
        save(aplist, aplist_file)
        tm = cputime(t)
        meta = {'cputime':tm, 'version':version()}
        save(meta, filenames.meta(aplist_file))
Beispiel #11
0
def compute_decompositions(N, k, i):
    if i == 'all':
        G = DirichletGroup(N).galois_orbits()
        sgn = (-1)**k
        for j, g in enumerate(G):
            if g[0](-1) == sgn:
                compute_decompositions(N,k,j)
        return

    if i == 'quadratic':
        G = DirichletGroup(N).galois_orbits()
        sgn = (-1)**k
        for j, g in enumerate(G):
            if g[0](-1) == sgn and g[0].order()==2:
                compute_decompositions(N,k,j)
        return

    filename = filenames.ambient(N, k, i)
    if not os.path.exists(filename):
        print "Ambient space (%s,%s,%s) not computed."%(N,k,i)
        return
        #compute_ambient_space(N, k, i)
    if not os.path.exists(filename):
        return 
    
    eps = DirichletGroup(N).galois_orbits()[i][0]

    if os.path.exists(filenames.factor(N, k, i, 0, makedir=False)):
        return
    
    t = cputime()
    M = load_ambient_space(N, k, i)
    D = M.cuspidal_subspace().new_subspace().decomposition()
    for d in range(len(D)):
        f = filenames.factor_basis_matrix(N, k, i, d)
        if os.path.exists(f):
            continue
        A = D[d]
        B  = A.free_module().basis_matrix()
        Bd = A.dual_free_module().basis_matrix()
        v  = A.dual_eigenvector(names='a', lift=False)    # vector over number field
        nz = A._eigen_nonzero()
        
        save(B, filenames.factor_basis_matrix(N, k, i, d))
        save(Bd, filenames.factor_dual_basis_matrix(N, k, i, d))
        save(v, filenames.factor_dual_eigenvector(N, k, i, d))
        save(nz, filenames.factor_eigen_nonzero(N, k, i, d))
        
    tm = cputime(t)
    meta = {'cputime':tm, 'number':len(D), 'version':version()}
    save(meta, filenames.decomp_meta(N, k, i))
def process_curve_batch(folder, batch, digits=600, power=15):
    #    cursor = list(C.genus2_curves.curves.find({'is_simple_geom': true,'real_geom_end_alg': u'R x R'}).sort([("cond", ASCENDING)]))
    totalcurves = len(batch)
    D = {}
    success = 0
    total = 0
    failed = []
    for i, curve in enumerate(batch):
        label = curve['label']
        stdout_filename = os.path.join(folder, label + ".stdout")
        output_filename = os.path.join(folder, label + ".sage")

        print "%d of %d : label = %s" % (i + 1, totalcurves, label)

        sys.stdout = open(stdout_filename, 'w')

        c, w = cputime(), walltime()
        data, sout = process_curve_lmfdb(curve,
                                         digits,
                                         power=power,
                                         verbose=True,
                                         internalverbose=False)
        print "Time: CPU %.2f s, Wall: %.2f s" % (
            cputime(c),
            walltime(w),
        )
        output_file = open(output_filename, 'w')
        output_file.write(sout)
        output_file.close()
        D[label] = True

        sys.stdout.flush()
        os.fsync(sys.stdout.fileno())
        sys.stdout = sys.__stdout__
        total += 1
        if label in D.keys():
            success += 1
            print "Done: label = %s" % (label)
            print os.popen("tail -n 1 %s" % stdout_filename).read()
        else:
            failed += [label]
            print "ERROR: label = %s\n" % (label)
        print "Success rate: %.0f%%\n" % (100. * success / total)
        print "Failed so far %s" % failed
def ambient_integral_structure_matrix(M,verbose=False):
    """
    In certatain cases (weight two any level) this might return the integral structure of a
    an ambient modular symbol space. I wrote this because for high level this is very slow
    in sage because there is no good sparse hermite normal form code in sage for huge matrices.
    """
    if verbose: tm = cputime(); mem = get_memory_usage(); print "Int struct start"
    #This code is the same as the firs part of M.integral_structure
    G = set([i for i, _ in M._mod2term])
    G = list(G)
    G.sort()
    #if there is a two term relation between two manin symbols we only need one of the two
    #so that's why we only use elements from G instead of all manin symbols.
    if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "G"
    B = M._manin_gens_to_basis.matrix_from_rows(list(G)).sparse_matrix()
    if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "B"
    #The collums of B now span M.integral_structure as ZZ-module
    B, d = B._clear_denom()
    if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Clear denom"
    if d == 1:
        #for explanation see d == 2
        assert len(set([B.nonzero_positions_in_row(i)[0] for i in xrange(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 1])) == B.ncols(), "B doesn't contain the Identity"
        if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Check Id"
        ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1)
        if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis"
    elif d == 2:
        #in this case the matrix B will contain 2*Id as a minor this allows us to compute the hermite normal form of B in a very efficient way. This will give us the integral basis ZZbasis.
        #if it turns out to be nessecarry this can be generalized to the case d%4==2 if we don't mind to only get the right structure localized at 2
        assert len(set([B.nonzero_positions_in_row(i)[0] for i in xrange(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 2])) == B.ncols(), "B doesn't contain 2*Identity"    
        if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Check 2*Id"
        E = matrix_modp(B,sparse=True)
        if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "matmodp"
        E = E.echelon_form()
        if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "echelon"
        ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1)
        for (pivot_row, pivot_col) in zip(E.pivot_rows(), E.pivots()):
            for j in E.nonzero_positions_in_row(pivot_row):
                ZZbasis[pivot_col, j] = QQ(1) / 2 
        if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis"
    else:
        raise NotImplementedError
    return ZZbasis
Beispiel #14
0
def ambient_integral_structure_matrix(M,verbose=False):
    """
    In certatain cases (weight two any level) this might return the integral structure of a
    an ambient modular symbol space. I wrote this because for high level this is very slow
    in sage because there is no good sparse hermite normal form code in sage for huge matrices.
    """
    if verbose: tm = cputime(); mem = get_memory_usage(); print("Int struct start")
    #This code is the same as the firs part of M.integral_structure
    G = set([i for i, _ in M._mod2term])
    G = list(G)
    G.sort()
    #if there is a two term relation between two manin symbols we only need one of the two
    #so that's why we only use elements from G instead of all manin symbols.
    if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "G")
    B = M._manin_gens_to_basis.matrix_from_rows(list(G)).sparse_matrix()
    if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "B")
    #The collums of B now span M.integral_structure as ZZ-module
    B, d = B._clear_denom()
    if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Clear denom")
    if d == 1:
        #for explanation see d == 2
        assert len(set([B.nonzero_positions_in_row(i)[0] for i in range(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 1])) == B.ncols(), "B doesn't contain the Identity"
        if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Check Id")
        ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1)
        if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis")
    elif d == 2:
        #in this case the matrix B will contain 2*Id as a minor this allows us to compute the hermite normal form of B in a very efficient way. This will give us the integral basis ZZbasis.
        #if it turns out to be nessecarry this can be generalized to the case d%4==2 if we don't mind to only get the right structure localized at 2
        assert len(set([B.nonzero_positions_in_row(i)[0] for i in range(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 2])) == B.ncols(), "B doesn't contain 2*Identity"    
        if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Check 2*Id")
        E = matrix_modp(B,sparse=True)
        if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "matmodp")
        E = E.echelon_form()
        if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "echelon")
        ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1)
        for (pivot_row, pivot_col) in zip(E.pivot_rows(), E.pivots()):
            for j in E.nonzero_positions_in_row(pivot_row):
                ZZbasis[pivot_col, j] = QQ(1) / 2 
        if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis")
    else:
        raise NotImplementedError
    return ZZbasis
Beispiel #15
0
    def dbd(self, d):
        """
        Return matrix of <d>.

        INPUT:

            - `d` -- integer

        OUTPUT:

            - a matrix modulo 2

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.dbd(2)
            22 x 22 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries)
            sage: C.dbd(2)^14==1
            True
            sage: C.dbd(2)[0]
            (0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1)
        """
        d=ZZ(d)
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print "dbd start"
        try: return self._dbd[d % self.p]
        except AttributeError: pass
        # Find generators of the integers modulo p:
        gens = Integers(self.p).unit_gens()
        orders = [g.multiplicative_order() for g in gens]
        # Compute corresponding <z> operator on integral cuspidal modular symbols
        
        X = [self.M.diamond_bracket_operator(z).matrix() for z in gens]
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "create d"
        X = [x.restrict(self.S_integral, check=False) for x in X]
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "restrict d"
        
        X = [matrix_modp(x) for x in X]
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "mod d"
        # Take combinations to make list self._dbd of all dbd's such that
        # self._dbd[d] = <d>
        from itertools import product
        v = [None] * self.p
        for ei in product(*[range(i) for i in orders]):
            di = prod(g**e for e,g in zip(ei,gens)).lift()
            m = prod(g**e for e,g in zip(ei,X))
            v[di] = m
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "mul"

        assert v.count(None) == (self.p-euler_phi(self.p))
        self._dbd = v
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "bdb finnished"
        return v[d % self.p]
Beispiel #16
0
    def dbd(self, d):
        """
        Return matrix of <d>.

        INPUT:

            - `d` -- integer

        OUTPUT:

            - a matrix modulo 2

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.dbd(2)
            22 x 22 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries)
            sage: C.dbd(2)^14==1
            True
            sage: C.dbd(2)[0]
            (0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1)
        """
        d=ZZ(d)
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print("dbd start")
        try: return self._dbd[d % self.p]
        except AttributeError: pass
        # Find generators of the integers modulo p:
        gens = Integers(self.p).unit_gens()
        orders = [g.multiplicative_order() for g in gens]
        # Compute corresponding <z> operator on integral cuspidal modular symbols
        
        X = [self.M.diamond_bracket_operator(z).matrix() for z in gens]
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "create d")
        X = [x.restrict(self.S_integral, check=False) for x in X]
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "restrict d")
        
        X = [matrix_modp(x) for x in X]
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "mod d")
        # Take combinations to make list self._dbd of all dbd's such that
        # self._dbd[d] = <d>
        from itertools import product
        v = [None] * self.p
        for ei in product(*[list(range(i)) for i in orders]):
            di = prod(g**e for e,g in zip(ei,gens)).lift()
            m = prod(g**e for e,g in zip(ei,X))
            v[di] = m
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "mul")

        assert v.count(None) == (self.p-euler_phi(self.p))
        self._dbd = v
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "bdb finnished")
        return v[d % self.p]
def cuspidal_integral_structure_matrix(M,verbose=False):
    """
    Computes the cuspidal integral structure matrix of a modular symbols space in a runningtime hopefully faster then that of sage
    
    Input:
    
    - M - a modular symbols space
    
    Output:
    
    - a matrix whose rows give a ZZ basis for the cuspidals supspace with respect to the standard basis of M
    
    Tests::

        sage: from mdsage import *
        sage: M = ModularSymbols(Gamma1(15))
        sage: cuspidal_integral_structure_matrix(M)
        [ 0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0]
        [ 0  0  0  0  0  1  0  0  1  0  0 -1  0  0  0  0  0]
    
    """
    #now we compute the integral kernel of the boundary map with respect to the integral basis. This will give us the integral cuspidal submodule.
    if verbose: tm = cputime(); mem = get_memory_usage(); 
    ZZbasis = ambient_integral_structure_matrix(M,verbose=verbose)              
    boundary_matrix = M.boundary_map().matrix()
    if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Boundary matrix"
    ZZboundary_matrix=(ZZbasis*boundary_matrix).change_ring(ZZ)
    if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZBoundary matrix"
    left_kernel_matrix=ZZboundary_matrix.transpose().dense_matrix()._right_kernel_matrix(algorithm='pari')
    if type(left_kernel_matrix)==tuple:
        left_kernel_matrix=left_kernel_matrix[1]
    if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "kernel matrix"
    ZZcuspidal_basis=left_kernel_matrix*ZZbasis
    if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZkernel matrix"
    S=M.cuspidal_subspace()
    assert ZZcuspidal_basis.change_ring(QQ).echelon_form()==S.basis_matrix() , "the calculated integral basis does not span the right QQ vector space" # a little sanity check. This shows that the colums of ZZcuspidal_basis really span the right QQ vectorspace
    if verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "finnished"
    return ZZcuspidal_basis
Beispiel #18
0
def cuspidal_integral_structure_matrix(M,verbose=False):
    """
    Computes the cuspidal integral structure matrix of a modular symbols space in a runningtime hopefully faster then that of sage
    
    Input:
    
    - M - a modular symbols space
    
    Output:
    
    - a matrix whose rows give a ZZ basis for the cuspidals supspace with respect to the standard basis of M
    
    Tests::

        sage: from mdsage import *
        sage: M = ModularSymbols(Gamma1(15))
        sage: cuspidal_integral_structure_matrix(M)
        [ 0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0]
        [ 0  0  0  0  0  1  0  0  1  0  0 -1  0  0  0  0  0]
    
    """
    #now we compute the integral kernel of the boundary map with respect to the integral basis. This will give us the integral cuspidal submodule.
    if verbose: tm = cputime(); mem = get_memory_usage(); 
    ZZbasis = ambient_integral_structure_matrix(M,verbose=verbose)              
    boundary_matrix = M.boundary_map().matrix()
    if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Boundary matrix")
    ZZboundary_matrix=(ZZbasis*boundary_matrix).change_ring(ZZ)
    if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZBoundary matrix")
    left_kernel_matrix=ZZboundary_matrix.transpose().dense_matrix()._right_kernel_matrix(algorithm='pari')
    if type(left_kernel_matrix)==tuple:
        left_kernel_matrix=left_kernel_matrix[1]
    if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "kernel matrix")
    ZZcuspidal_basis=left_kernel_matrix*ZZbasis
    if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZkernel matrix")
    S=M.cuspidal_subspace()
    assert ZZcuspidal_basis.change_ring(QQ).echelon_form()==S.basis_matrix() , "the calculated integral basis does not span the right QQ vector space" # a little sanity check. This shows that the colums of ZZcuspidal_basis really span the right QQ vectorspace
    if verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "finnished")
    return ZZcuspidal_basis
def certify_heuristic(g,
                      label=None,
                      digits=600,
                      power=15,
                      verbose=True,
                      internalverbose=False):
    from heuristic_endomorphisms import EndomorphismData
    out = ""
    curve_dict = {}
    curve_dict['label'] = label
    curve_dict['digits'] = digits
    prec = ceil(log(10) / log(2) * digits)
    curve_dict['prec'] = prec
    buffer = "curve_dict = {};\n"
    for key in ['digits', 'prec']:
        buffer += "curve_dict['%s'] = %s;\n" % (key, curve_dict[key])
    buffer += "curve_dict['%s'] = '%s';\n" % ('label', label)
    if verbose:
        print buffer
    out += buffer

    #Ambient ring
    buffer = ""
    buffer += "\n# basic rings\n"
    buffer += "curve_dict['%s'] = %s;\n" % ('QQx', 'PolynomialRing(QQ, \'x\')')
    buffer += "# curve_dict, x, and the number field's generator are the only variables are the only global variables\n\n"
    buffer += "x = curve_dict['QQx'].gen();\n\n"
    out += buffer

    Qx = PolynomialRing(QQ, "x")
    x = Qx.gen()
    curve_dict['QQx'] = Qx

    # force g in Qx
    g = Qx(g.list())

    # Compute EndomorphismData
    # field of definition
    # and endomorphisms
    xsubs_list = [x, x + 1, x - 1, 1 - x, -1 - x, x + 2, x - 2, -x - 2, 2 - x]
    if label == '540800.a.540800.1':
        xsubs_list = xsubs_list[1:]
    for xsubs in xsubs_list:
        try:
            gtry = g(xsubs)
            if gtry.degree() == 5:
                gtry = Qx(gtry(x**(-1)) * x**6)
            if gtry.degree() == 5:
                gtry = Qx(gtry((x - 1) / x) * x**6)

            if verbose:
                print "Computing the EndomorphismData..."
                c, w = cputime(), walltime()
                End = EndomorphismData(gtry, prec=digits)
                print "Time: CPU %.2f s, Wall: %.2f s" % (
                    cputime(c),
                    walltime(w),
                )
            else:
                End = EndomorphismData(gtry, prec=digits)
            geo = End.geometric_representations()
            K = End.field_of_definition()
            g = gtry
            break
        except TypeError:
            pass

    if label == '810.a.196830.1':
        power += 2

    buffer = "#working with the model y^2 = g(x)\n"
    buffer += "curve_dict['%s'] = %s;\n" % ('g', g.list())
    curve_dict['g'] = g.list()

    out += buffer
    if verbose:
        print buffer

    # initialize numerical methods

    iaj = InvertAJglobal(g, prec, internalverbose)
    #CCap = iaj.C;

    buffer += "curve_dict['%s'] = %s;\n" % ('CCap', ' ComplexField(%s)' %
                                            curve_dict['prec'])
    #buffer += "CCap = curve_dict['CCap'];\n\n"

    # generator is r
    K = End.field_of_definition()
    if K.degree() == 1:
        K = QQ

    buffer = "# Field of definition of alpha\n"
    buffer += "curve_dict['%s'] = %s;\n" % ('K',
                                            sage_str_numberfield(K, 'x', 'r'))
    buffer += "K = %s\n" % ("curve_dict['K']")
    if K is not QQ:
        buffer += "r_approx = %s\n" % (K.gen().complex_embedding(), )
    out += buffer
    out += "r = K.gen();\n"

    if verbose:
        print buffer

    #get the matrices over K
    geo = End.geometric_representations()

    #convert to sage
    # we also must take the transpose
    alphas = [convert_magma_matrix_to_sage(y, K).transpose() for y in geo[0]]
    alphas_geo = [y.sage() for y in geo[2]]

    d = len(alphas)
    out += "curve_dict['alphas_K'] = [None] * %d\n\n" % d
    out += "curve_dict['alphas_geo'] = [None] * %d\n\n" % d
    for i, _ in enumerate(alphas):
        alpha = alphas[i]
        alpha_geo = alphas_geo[i]
        buffer = "curve_dict['alphas_K'][%d] = Matrix(K, %s);\n" % (
            i,
            alpha.rows(),
        )
        buffer += "curve_dict['alphas_geo'][%d] = Matrix(%s);\n\n" % (
            i,
            alpha_geo.rows(),
        )
        out += buffer
        if verbose:
            print buffer
    curve_dict['alphas_K'] = alphas
    curve_dict['alphas_geo'] = alphas_geo

    out += "# where we stored all the data, for each alpha\n"
    out += "curve_dict['data'] = [{} for _ in range(%d) ] ;" % d
    curve_dict['data'] = [{} for _ in range(d)]

    for i in range(d):
        if alphas[i] == Matrix([[1, 0], [0, 1]]):
            curve_dict['data'][i] = None
        else:
            if verbose:
                print "Computing alpha(P + P)"
                print "where alpha = Matrix(K, %s)\n" % (alphas[i].rows(), )

            # Pick a rational point, or a point over a quadratic extension with small discriminant
            for j, P0 in enumerate(find_rational_point(g)):
                if label in [
                        '540800.a.540800.1', '529.a.529.1', '1521.a.41067.1',
                        '12500.a.12500.1', '18225.c.164025.1'
                ] and j < 2:
                    pass
                elif label in ['810.a.196830.1'] and i == 2 and j == 0:
                    pass
                else:
                    if verbose:
                        print "j = %s" % j
                    sys.stdout.flush()
                    sys.stderr.flush()
                    try:

                        output_alpha = compute_alpha_point(g,
                                                           iaj,
                                                           alphas[i],
                                                           P0,
                                                           digits,
                                                           power,
                                                           verbose=verbose,
                                                           aggressive=True,
                                                           append=str(i))

                        verified, trace_and_norm = add_trace_and_norm_ladic(
                            g, output_alpha, alphas_geo[i], verbose=verbose)
                        break
                    except ZeroDivisionError:
                        pass
                    except OverflowError:
                        if verbose:
                            print "the mesh for numerical integral is too big"
                        pass
                    if verbose:
                        print "trying with a new point\n"

            if verbose:
                print "\n\n\n"

            output_alpha['trace_and_norm'] = trace_and_norm
            output_alpha['verified'] = verified
            output_alpha['alphas_geo'] = alphas_geo[i]
            internal_out = "\n"
            #local_dict = {}\n\n";
            #

            # the fields
            internal_out += "# L the field where P and the algx_poly are defined\n"
            internal_out += "curve_dict['data'][%d]['L'] = %s\n" % (
                i,
                sage_str_numberfield(output_alpha['L'], 'x', 'b' + str(i)),
            )
            if output_alpha['L'] is not QQ:
                internal_out += "b%d = curve_dict['data'][%d]['L'].gen()\n" % (
                    i, i)
                internal_out += "curve_dict['data'][%d]['Lgen_approx'] = %s\n" % (
                    i, output_alpha['L'].gen().complex_embedding())
            internal_out += "\n"

            internal_out += "curve_dict['data'][%d]['alpha'] = Matrix(curve_dict['data'][%d]['L'], %s) \n\n" % (
                i, i, [[elt for elt in row]
                       for row in output_alpha['alpha'].rows()])
            internal_out += "curve_dict['data'][%d]['alpha_geo'] = curve_dict['alphas_geo'][%d]\n\n" % (
                i, i)

            internal_out += "curve_dict['data'][%d]['P'] = vector(curve_dict['data'][%d]['L'], %s)\n\n" % (
                i, i, output_alpha['P'])

            internal_out += "# alpha(P + P) - \inf = R0 + R1 - \inf\n"

            internal_out += "\n\n\n"
            for key in [
                    'algx_poly', 'R', 'x_poly', 'trace_and_norm', 'verified'
            ]:
                internal_out += "curve_dict['data'][%d]['%s'] = %s;\n" % (
                    i, key, output_alpha[key])

            # this just clutters the file,
            # internal_out += "curve_dict['data'][%d]['ajP'] = vector(%s)\n\n" % (i, output_alpha['ajP']);
            # internal_out += "curve_dict['data'][%d]['alpha2P0'] = alphas_ap[%d] * 2 * local_dict['ajP']\n\n" % (i, i)

            internal_out += "\n\n\n"
            curve_dict['data'][i] = output_alpha
            out += internal_out
    verified = all(
        [elt['verified'] for elt in curve_dict['data'] if elt is not None])
    out += "curve_dict['verified'] = %s\n\n" % verified
    return curve_dict, out, verified
Beispiel #20
0
 def integral_cuspidal_subspace(self):
     """
     In certatain cases this might return the integral structure of the cuspidal subspace.
     This code is mainly a way to compute the integral structe faster than sage does now. 
     It returns None if it cannot find the integral subspace. 
     """
     if self.verbose: tm = cputime(); mem = get_memory_usage(); print("Int struct start")
     #This code is the same as the firs part of self.M.integral_structure
     G = set([i for i, _ in self.M._mod2term])
     G = list(G)
     G.sort()
     #if there is a two term relation between two manin symbols we only need one of the two
     #so that's why we only use elements from G instead of all manin symbols.
     if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "G")
     B = self.M._manin_gens_to_basis.matrix_from_rows(list(G)).sparse_matrix()
     if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "B")
     #The collums of B now span self.M.integral_structure as ZZ-module
     B, d = B._clear_denom()
     if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Clear denom")
     if d == 1:
         #for explanation see d == 2
         assert len(set([B.nonzero_positions_in_row(i)[0] for i in range(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 1])) == B.ncols(), "B doesn't contain the Identity"
         if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Check Id")
         ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1)
         if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis")
     elif d == 2:
         #in this case the matrix B will contain 2*Id as a minor this allows us to compute the hermite normal form of B in a very efficient way. This will give us the integral basis ZZbasis.
         #if it turns out to be nessecarry this can be generalized to the case d%4==2 if we don't mind to only get the right structure localized at 2
         assert len(set([B.nonzero_positions_in_row(i)[0] for i in range(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 2])) == B.ncols(), "B doesn't contain 2*Identity"    
         if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Check 2*Id")
         E = matrix_modp(B,sparse=True)
         if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "matmodp")
         E = E.echelon_form()
         if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "echelon")
         ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1)
         for (pivot_row, pivot_col) in zip(E.pivot_rows(), E.pivots()):
             for j in E.nonzero_positions_in_row(pivot_row):
                 ZZbasis[pivot_col, j] = QQ(1) / 2 
         if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis")
     else:
         return None
     #now we compute the integral kernel of the boundary map with respect to the integral basis. This will give us the integral cuspidal submodule.                 
     boundary_matrix = self.M.boundary_map().matrix()
     if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Boundary matrix")
     ZZboundary_matrix=(ZZbasis*boundary_matrix).change_ring(ZZ)
     if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZBoundary matrix")
     left_kernel_matrix=ZZboundary_matrix.transpose().dense_matrix()._right_kernel_matrix(algorithm='pari')
     if type(left_kernel_matrix)==tuple:
         left_kernel_matrix=left_kernel_matrix[1]
     if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "kernel matrix")
     ZZcuspidal_basis=left_kernel_matrix*ZZbasis
     if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZkernel matrix")
     assert ZZcuspidal_basis.change_ring(QQ).echelon_form()==self.S.basis_matrix() , "the calculated integral basis does not span the right QQ vector space" # a little sanity check. This shows that the colums of ZZcuspidal_basis really span the right QQ vectorspace
     if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "check")
     #finally create the sub-module, we delibarately do this as a QQ vector space with custom basis, because this is faster then dooing the calculations over ZZ since sage will then use a slow hermite normal form algorithm.
     ambient_module=VectorSpace(QQ,ZZcuspidal_basis.ncols())
     int_struct = ambient_module.submodule_with_basis(ZZcuspidal_basis.rows())
     if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "finnished")
     return int_struct
def compute_alpha_point(g,
                        iaj,
                        alpha,
                        P0,
                        digits,
                        power,
                        verbose,
                        aggressive=True,
                        append=""):
    # input:
    # * g, defining polynomial of the hyperelliptic curve
    # * iaj = InvertAJglobal class
    # * alpha = analytic representation of the endomorphism acting on the tangent space
    # * digits = how many digits to work with
    # * power, we will divide by 2**power before inverting the abel jacobi map
    # * P0, a point in the curve for which we will compute alpha*2(P - \infty) = P1 + P2 - \infty
    # * verbose
    # * agressive, raise ZeroDivisionError  if we get a P1[0] = P2[0] or one of the points is infty
    # * append, a string to append to the numberfield generators
    #
    # output: a dictionary with the following keys
    # TODO add the keys

    output = {}
    K = alpha.base_ring()
    CCap = iaj.C
    prec = CCap.precision()
    output['prec'] = prec
    x0, y0 = P0
    Kz = PolynomialRing(K, "z")
    z = Kz.gen()
    if verbose:
        print "compute_alpha_point()"
        print "P0 = %s" % (P0, )
    #deal with the field of definition
    if y0 in K:
        if K is QQ:
            L = K
            from_K_to_L = QQ.hom(1, QQ)
        else:
            L = K.change_names("b" + append)
            from_K_to_L = L.structure()[1]
    else:
        L, from_K_to_L = (z**2 - g(x0)).splitting_field("b" + append,
                                                        simplify_all=True,
                                                        map=True)

    output['L'] = L
    #    output['L_str'] = sage_str_numberfield(L, 'x','b'+append);
    output['from_K_to_L'] = from_K_to_L
    #    output['L_gen'] =  toCCap(L.gen(), 53);

    # figure out y0 in L
    y0_ap = toCCap(y0, prec)
    y0s = [elt for elt, _ in (z**2 - g(x0)).roots(L)]
    assert len(y0s) == 2
    y0s_ap = [toCCap(elt, prec) for elt in y0s]
    if norm(y0_ap - y0s_ap[0]) < norm(y0_ap - y0s_ap[1]):
        y0 = y0s[0]
    else:
        y0 = y0s[1]

    P0 = vector(L, [x0, y0])

    alpha_L = Matrix(L, [[from_K_to_L(elt) for elt in row]
                         for row in alpha.rows()])
    alpha_ap = Matrix(CCap, [toCCap_list(row, prec) for row in alpha_L.rows()])

    output['P'] = P0
    output['alpha'] = alpha_L

    if verbose:
        print "L = %s" % L
        print "%s = %s" % (L.gen(), toCCap(L.gen(), 53))
        print "P0 = %s" % (P0, )
        print "alpha = %s" % ([[elt for elt in row]
                               for row in alpha_L.rows()], )

    P0_ap = vector(CCap, toCCap_list(P0, prec + 192))

    if verbose:
        print "P0_ap = %s" % (vector(CC, P0_ap), )

    if verbose:
        print "Computing AJ of P0..."
        c, w = cputime(), walltime()
        ajP0 = vector(CCap, AJ1_digits(g, P0_ap, digits))
        print "Time: CPU %.2f s, Wall: %.2f s" % (
            cputime(c),
            walltime(w),
        )
        print
    else:
        ajP0 = vector(CCap, AJ1_digits(g, P0_ap, digits))

    output['ajP'] = ajP0

    aj2P0 = 2 * ajP0
    alpha2P0_an = alpha_ap * aj2P0
    if verbose:
        print "Working over %s" % CCap

    invertAJ_tries = 3
    for i in range(invertAJ_tries):
        #try invertAJ_tries times to invertAJ
        try:
            if verbose:
                print "\n\ninverting AJ..."
                c, w = cputime(), walltime()
                alpha2P0_div = iaj.invertAJ(alpha2P0_an, power)
                print "Time: CPU %.2f s, Wall: %.2f s" % (
                    cputime(c),
                    walltime(w),
                )
                print "\n\n"
            else:
                alpha2P0_div = iaj.invertAJ(alpha2P0_an, power)
            break
        except AssertionError as error:
            print error
            if verbose:
                print "an assertion failed while inverting AJ.."
            if i == invertAJ_tries - 1:
                if verbose:
                    print "retrying with a new P0"
                    print
                raise ZeroDivisionError
            else:
                iaj.iajlocal.set_basepoints()
                if verbose:
                    print "retrying again with a new set of base points"

    if verbose:
        print "Computing the Mumford coordinates of alpha(2*P0 - 2*W)"
        c, w = cputime(), walltime()
        R0, R1 = alpha2P0_div.coordinates()
        print "Time: CPU %.2f s, Wall: %.2f s" % (
            cputime(c),
            walltime(w),
        )
    else:
        R0, R1 = alpha2P0_div.coordinates()

    points = [R0, R1]
    x_poly = alpha2P0_div.x_coordinates()
    output['R'] = points
    output['x_poly'] = x_poly

    if (R0 in [+Infinity, -Infinity]) or (R1 in [+Infinity, -Infinity]):
        if aggressive:
            # we want to avoid these situations
            if verbose:
                print "One of the coordinates is at infinity"
                if R0 in [+Infinity, -Infinity]:
                    print "R0 = %s" % (R0, )
                else:
                    print "R1 = %s" % (R1, )
                print "retrying with a new P0"
                print
            raise ZeroDivisionError
        else:
            return output

    buffer = "# R0 = %s\n" % (vector(CC, R0), )
    buffer += "# R1 = %s\n" % (vector(CC, R1), )
    buffer += "# and \n# x_poly = %s\n" % (vector(CC, x_poly), )

    if verbose:
        print buffer
    assert len(x_poly) == 3

    algx_poly = [NF_embedding(coeff, L) for coeff in x_poly]
    buffer = "algx_poly = %s;\n" % (algx_poly, )
    if L != QQ:
        buffer += "#where %s ~ %s\n" % (L.gen(), L.gen().complex_embedding())
    buffer += "\n"
    if verbose:
        print buffer
        sys.stdout.flush()
        sys.stderr.flush()

    output['algx_poly'] = algx_poly

    if None in algx_poly:
        if aggressive:
            if verbose:
                print "No algebraic expression  for the polynomial"
                print "retrying with a new P0"
                sys.stdout.flush()
                sys.stderr.flush()
            raise ZeroDivisionError
        else:
            return output
    #c, b, a = algx_poly
    #if aggressive and b**2 - 4*a*c == 0:
    #    raise ZeroDivisionError
    if verbose:
        print "Done compute_alpha_point()"
    return output
Beispiel #22
0
def trace_and_norm_ladic(L,
                         M,
                         P0,
                         P1,
                         P2,
                         f,
                         alpha,
                         degree_bound,
                         primes=120,
                         bits=62,
                         verbose=True):
    if verbose:
        print "trace_and_norm_ladic()"
        print "primes = %d, bits = %d" % (primes, bits)
    # Input:
    # * L the number field where P0, alpha, norm and trace are defined over
    # * M a relative extension of L where P1 and P2 are defined over
    # * P0 initial point already embedded in M
    # * P1, P2 image points alpha(2 * P0 - \infty) = P1 + P2 - \infty
    # * alpha the matrix represing the endomorphism on the tangent space in M
    # * f the defining polynomial of the curve such that y^2 = f(x)
    # * degree bound for the trace and norm as rational maps
    # Note: Due to inconsistencies of the complex embeddings of L and M we require P0 and alpha to be given in M
    # Output:
    # * [trace_numberator, trace_denominator, norm_numberator, norm_denominator]
    # represented as lists of elements in L

    for arg in [P0, P1, P2, alpha]:
        assert arg.base_ring() is M

    hard_bound = 2 * degree_bound + 1
    soft_bound = hard_bound + 10
    if verbose:
        print "hard_bound = %d\nsoft_bound = %d" % (hard_bound, soft_bound)
        print "Generating split primes..."
        c, w = cputime(), walltime()
        ps_roots = random_split_primes(field=L,
                                       bits=bits,
                                       primes=primes,
                                       relative_ext=M.relative_polynomial())
        print "Time: CPU %.2f s, Wall: %.2f s" % (
            cputime(c),
            walltime(w),
        )
    else:
        ps_roots = random_split_primes(field=L,
                                       bits=bits,
                                       primes=primes,
                                       relative_ext=M.relative_polynomial())

    to_lift_raw = []
    if verbose:
        print "Applying newton lift at each prime"
    for p_root in ps_roots:
        ell, root = p_root

        FF = FiniteField(ell)
        FF_xell = PolynomialRing(FF, "xell")

        Lpoly = FF_xell(
            reduce_list_split(M.relative_polynomial().list(), p_root))
        assert Lpoly.degree() == len(Lpoly.roots())
        Lroot = Lpoly.roots()[0][0].lift()

        PSring_ell = PowerSeriesRing(FF, "Tell", default_prec=soft_bound)

        P0_ell = vector(FF, reduce_list_split_relative(P0, p_root, Lroot))
        P1_ell = vector(FF, reduce_list_split_relative(P1, p_root, Lroot))
        P2_ell = vector(FF, reduce_list_split_relative(P2, p_root, Lroot))

        f_ell = FF_xell(reduce_list_split(f.list(), p_root))
        alpha_ell = reduce_matrix_split_relative(alpha, p_root, Lroot)

        x1_ell, x2_ell = newton_linear(P0_ell, P1_ell, P2_ell, f_ell,
                                       alpha_ell, PSring_ell, soft_bound)

        trace_series_ell = x1_ell + x2_ell

        norm_series_ell = x1_ell * x2_ell

        trace_numerator_ell, trace_denominator_ell = rational_reconstruct_poly(
            FF_xell(trace_series_ell.list()),
            FF_xell.gen()**trace_series_ell.prec())
        norm_numerator_ell, norm_denominator_ell = rational_reconstruct_poly(
            FF_xell(norm_series_ell.list()),
            FF_xell.gen()**norm_series_ell.prec())

        # shift the series back to zero
        shift = FF_xell.gen() - P0_ell[0]

        factors_ell = [
            trace_numerator_ell(shift).list(),
            trace_denominator_ell(shift).list(),
            norm_numerator_ell(shift).list(),
            norm_denominator_ell(shift).list()
        ]
        degrees_ell = tuple([len(elt) for elt in factors_ell])
        to_lift_raw.append((p_root, degrees_ell, factors_ell))
    if verbose:
        print "Getting rid of bad primes..."
    # get rid of badprimes
    degrees_count = {}
    for _, degrees_ell, _ in to_lift_raw:
        if degrees_ell in degrees_count:
            degrees_count[degrees_ell] += 1
        else:
            degrees_count[degrees_ell] = 1
    max_value = 0
    max_arg = None

    for degrees_ell, count in degrees_count.items():
        if count > max_value:
            max_arg = degrees_ell
            max_value = count

    output = [None] * 4
    for i, elt in enumerate(max_arg):
        output[i] = [0] * elt

    to_lift = []
    ps_roots = []

    for p_root, degrees_ell, factors_ell in to_lift_raw:
        if degrees_ell == max_arg:
            ps_roots.append(p_root)
            to_lift.append(factors_ell)

    extra_factor = to_lift[-1]
    extra_p_root = ps_roots[-1]

    to_lift = to_lift[:-1]
    ps_roots = ps_roots[:-1]

    OL = L.ring_of_integers()
    p_ideals = [OL.ideal(p,
                         L.gen() - r) for p, r in ps_roots]
    I = prod(p_ideals)
    if L is QQ:
        BI_coordinates = None
    else:
        BI = I.basis()
        # basis as a ZZ-module
        BI_coordinates = [OL.coordinates(b) for b in BI]

    if verbose:
        print "Lifting everything"
    for i, lift in enumerate(output):
        for j, elt in enumerate(lift):
            residues = [residue[i][j] for residue in to_lift]
            output[i][j] = fractional_CRT_split(residues=residues,
                                                ps_roots=ps_roots,
                                                K=L,
                                                BI_coordinates=BI_coordinates)
            assert reduce_constant_split(output[i][j],
                                         extra_p_root) == extra_factor[i][j]
    if verbose:
        print "trace_and_norm_ladic() Done"

    return output
Beispiel #23
0
    def __init__(self, p, congruence_type=1, sign=1, algorithm="custom", verbose=False, dump_dir=None):
        """
        Create a Kamienny criterion object.

        INPUT:

            - `p` -- prime -- verify that there is no order p torsion
              over a degree `d` field
            - `sign` -- 1 (default),-1 or 0 -- the sign of the modular symbols space to use 
            - ``algorithm`` -- "default" or "custom" whether to use a custom (faster)
              integral structure algorithm or to use the sage builtin algortihm
            - ``verbose`` -- bool; whether to print extra stuff while
              running.

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29, algorithm="custom", verbose=False); C
            Kamienny's Criterion for p=29
            sage: C.use_custom_algorithm
            True
            sage: C.p
            29
            sage: C.verbose
            False        
        """
        self.verbose = verbose
        self.dump_dir = dump_dir
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print "init"
        assert congruence_type == 0 or congruence_type == 1
        self.congruence_type=congruence_type
        try:
            p = ZZ(p)
            if congruence_type==0:
                self.congruence_group = Gamma0(p)
            if congruence_type==1:
                self.congruence_group = GammaH(p,[-1])
        except TypeError:
            self.congruence_group = GammaH(p.level(),[-1]+p._generators_for_H())
            self.congruence_type = ("H",self.congruence_group._list_of_elements_in_H())
            
        self.p = self.congruence_group.level()
  
        self.algorithm=algorithm
        self.sign=sign
        
        self.M = ModularSymbols(self.congruence_group, sign=sign)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "modsym"
        self.S = self.M.cuspidal_submodule()
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "cuspsub"
        self.use_custom_algorithm = False
        if algorithm=="custom":
            self.use_custom_algorithm = True
        if self.use_custom_algorithm:
            int_struct = self.integral_cuspidal_subspace()
            if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "custom int_struct"
        else:    
            int_struct = self.S.integral_structure()
            if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "sage int_struct"
        self.S_integral = int_struct
        v = VectorSpace(GF(2), self.S.dimension()).random_element()
        self.v=v
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "rand_vect"
        if dump_dir:
            v.dump(dump_dir+"/vector%s_%s" % (p,congruence_type))
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "dump"
Beispiel #24
0
def silke(A, c, beta, h, m=None, scale=1, float_type="double"):
    """

    :param A:    LWE matrix
    :param c:    LWE vector
    :param beta: BKW block size
    :param m:    number of samples to consider
    :param scale: scale rhs of lattice by this factor

    """
    from fpylll import BKZ, IntegerMatrix, LLL, GSO
    from fpylll.algorithms.bkz2 import BKZReduction as BKZ2

    if m is None:
        m = A.nrows()

    L = dual_instance1(A, scale=scale)
    L = IntegerMatrix.from_matrix(L)
    L = LLL.reduction(L, flags=LLL.VERBOSE)
    M = GSO.Mat(L, float_type=float_type)
    bkz = BKZ2(M)
    t = 0.0
    param = BKZ.Param(block_size=beta,
                      strategies=BKZ.DEFAULT_STRATEGY,
                      auto_abort=True,
                      max_loops=16,
                      flags=BKZ.VERBOSE | BKZ.AUTO_ABORT | BKZ.MAX_LOOPS)
    bkz(param)
    t += bkz.stats.total_time

    H = copy(L)

    import pickle
    pickle.dump(L, open("L-%d-%d.sobj" % (L.nrows, beta), "wb"))

    E = []
    Y = set()
    V = set()
    y_i = vector(ZZ, tuple(L[0]))
    Y.add(tuple(y_i))
    E.append(apply_short1(y_i, A, c, scale=scale)[1])

    v = L[0].norm()
    v_ = v / sqrt(L.ncols)
    v_r = 3.2 * sqrt(L.ncols - A.ncols()) * v_ / scale
    v_l = sqrt(h) * v_

    fmt = u"{\"t\": %5.1fs, \"log(sigma)\": %5.1f, \"log(|y|)\": %5.1f, \"log(E[sigma]):\" %5.1f}"

    print
    print fmt % (t, log(abs(E[-1]), 2), log(L[0].norm(),
                                            2), log(sqrt(v_r**2 + v_l**2), 2))
    print
    for i in range(m):
        t = cputime()
        M = GSO.Mat(L, float_type=float_type)
        bkz = BKZ2(M)
        t = cputime()
        bkz.randomize_block(0, L.nrows, stats=None, density=3)
        LLL.reduction(L)
        y_i = vector(ZZ, tuple(L[0]))
        l_n = L[0].norm()
        if L[0].norm() > H[0].norm():
            L = copy(H)
        t = cputime(t)

        Y.add(tuple(y_i))
        V.add(y_i.norm())
        E.append(apply_short1(y_i, A, c, scale=scale)[1])
        if len(V) >= 2:
            fmt = u"{\"i\": %4d, \"t\": %5.1fs, \"log(|e_i|)\": %5.1f, \"log(|y_i|)\": %5.1f,"
            fmt += u"\"log(sigma)\": (%5.1f,%5.1f), \"log(|y|)\": (%5.1f,%5.1f), |Y|: %5d}"
            print fmt % (i + 2, t, log(abs(E[-1]), 2), log(
                l_n,
                2), log_mean(E), log_var(E), log_mean(V), log_var(V), len(Y))

    return E
Beispiel #25
0
def check_unproven_ranks(jobs=1,
                         jobid=0,
                         use_weak_bsd=False,
                         skip_real_char=False):
    todo = list(
        db.mf_newforms.search({
            u'analytic_rank': {
                '$gt': int(1)
            },
            u'analytic_rank_proved': False
        }))
    todo2 = []
    todo3 = []
    todo4 = []
    cnt = 0
    vcnt = 0
    for i in range(len(todo)):
        if i % jobs != jobid:
            continue
        start = cputime()
        data = todo[i]
        if skip_real_char and data[u"char_is_real"]:
            continue
        if use_weak_bsd and data[u'weight'] == 2 and data[
                u'dim'] == 1 and data[u'char_orbit_index'] == 1:
            ec_label = "%d.%s1" % (
                data[u'level'], cremona_letter_code(data[u'hecke_orbit'] - 1))
            r = db.ec_curves.lookup(ec_label)[u'rank']
            if data[u'analytic_rank'] != r:
                print "*** winding element is nonzero, positive analytic rank %d for newform %s appears to be wrong ***" % (
                    data[u'rank'], data[u'label'])
                print data[u'label']
                todo2.append(data[u'label'])
            else:
                print "verified that analytic rank %d of newform %s matches Mordell-Weil rank of elliptic curve %s" % (
                    data[u'analytic_rank'], data[u'label'], ec_label)
            continue
        print "Checking newform %s of dimension %d with analytic rank <= %d..." % (
            data[u'label'], data[u'dim'], data[u'analytic_rank'])
        w = windingelement_hecke_cutter_projected(data, extra_cutter_bound=100)
        if w != 0:
            print "*** winding element is nonzero, positive analytic rank %d for newform %s appears to be wrong ***" % (
                data[u'rank'], data[u'label'])
            print data[u'label']
            todo2.append(data[u'label'])
        else:
            if data[u'analytic_rank'] == 2 and data["is_self_dual"]:
                print "Verified analytic rank is 2."
                vcnt += 1
            else:
                print "Verified analytic rank > 0"
                todo3.append(data[u'label'])
        print "Processed newform %s in %.3f CPU seconds" % (data[u'label'],
                                                            cputime() - start)
        cnt += 1

    todo = list(
        db.mf_newforms.search({
            u'analytic_rank': int(1),
            u'is_self_dual': False,
            u'analytic_rank_proved': False
        }))
    for i in range(len(todo)):
        if i % jobs != jobid:
            continue
        start = cputime()
        data = todo[i]
        if skip_real_char and data[u"char_is_real"]:
            continue
        print "Checking non-self-dual newform %s of dimension %d with analytic rank <= %d..." % (
            data[u'label'], data[u'dim'], data[u'analytic_rank'])
        w = windingelement_hecke_cutter_projected(data, extra_cutter_bound=100)
        if w != 0:
            print "*** winding element is nonzero, positive analytic rank appears to be wrong ***"
            print data[u'label']
            todo4.append(data[u'label'])
        else:
            print "Verified analytic rank is 1."
            vcnt += 1
        print "Processed newform %s in %.3f CPU seconds" % (data[u'label'],
                                                            cputime() - start)
        cnt += 1

    print "Checked analytic ranks of %d newforms, of which %d were verified" % (
        cnt, vcnt)
    if len(todo2) > 0 or len(todo4) > 0:
        print "The following newforms appear to have the wrong analytic rank:"
        for r in todo2:
            print "    %s (claimed analytic rank %d)" % (r[u'lable'],
                                                         r[u'analytic_rank'])
        for r in todo4:
            print "    %s (claimed analytic rank %d)" % (r[u'lable'],
                                                         r[u'analytic_rank'])
    if len(todo3) > 0:
        print "The following newforms have positive but unverified analytic ranks:"
        for r in todo2:
            print "    %s (claimed analytic rank %d, proved nonzero)" % (
                r[u'lable'], r[u'analytic_rank'])
    def solve(self, beta, max_iterations=100, tolerance=None, x0=None):
        # solve \sum_j (\int_bj ^{P_j} w_i)_i = beta
        # assumes beta is small

        if tolerance == None:
            tolerance = mpmath.mpf(2)**(-mpmath.mp.prec + 3)
        #print "tolerance = %s" % tolerance
        beta = mpmath.matrix([b for b in beta])
        while True:
            try:
                basepoints = self.get_basepoints()

                if x0 is None:
                    x = mpmath.matrix([b[0] for b in basepoints])
                    value = mpmath.matrix([0 for _ in range(self.genus)])
                else:
                    assert len(x0) == self.genus
                    x = mpmath.matrix(x0)

                    if self.verbose:
                        c, w = cputime(), walltime()
                        value = self.to_J_sum(x)
                        print "Time: CPU %.2f s, Wall: %.2f s" % (
                            cputime(c),
                            walltime(w),
                        )
                    else:
                        value = self.to_J_sum(x)

                previous_norm = 1
                divg_bound = 3
                divergingQ = 0
                for k in range(max_iterations):
                    J = self.jacobian(x)

                    # J y = f(x) - beta
                    y = mpmath.lu_solve(J, value - beta)
                    x = x - y

                    norm = mpmath.norm(y) / mpmath.norm(x)
                    if self.verbose:
                        print "k = %d norm = %.3e" % (k, norm)
                    if norm < tolerance:
                        return (x, y)

                    if norm / previous_norm > 1.5:
                        divergingQ += 1
                    else:
                        divergingQ = 0

                    previous_norm = norm

                    if divergingQ > divg_bound:
                        raise RuntimeWarning(
                            "method failed: the error diverged")
                    if self.verbose:
                        c, w = cputime(), walltime()
                        value = self.to_J_sum(x)
                        print "Time: CPU %.2f s, Wall: %.2f s" % (
                            cputime(c),
                            walltime(w),
                        )
                    else:
                        value = self.to_J_sum(x)
                else:
                    raise RuntimeWarning(
                        "method failed: max number of iterations reached")

            except NotImplementedError as e:
                print e
                print "Generating new basepoints"
                self.set_basepoints()
Beispiel #27
0
    def t1_prime(self, n=5, p=65521):
        """
        Return a multiple of element t1 of the Hecke algebra mod 2,
        computed using the Hecke operator $T_n$, where n is self.n.
        To make computation faster we only check if ...==0 mod p.
        Hence J will contain more elements, hence we get a multiple.
        
        INPUT:
        
            - `n` -- integer (optional default=5)
            - `p` -- prime (optional default=65521)

        OUTPUT:

            - a mod 2 matrix

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.t1_prime()
            22 x 22 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries)
            sage: C.t1_prime(n=3) == 1
            True
            sage: C = KamiennyCriterion(37)
            sage: C.t1_prime()[0]
            (1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0)
        """
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print "t1 start"
        T = self.S.hecke_matrix(n)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "hecke 1"
        f = self.hecke_polynomial(n) # this is the same as T.charpoly()
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "char 1"
        Fint = f.factor()
        if all(i[1]!=1 for i in Fint):
            return matrix_modp(zero_matrix(T.nrows()))
        #    raise ValueError("T_%s needs to be a generator of the hecke algebra"%n)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "factor 1, Fint = %s"%(Fint)
        R = f.parent().change_ring(GF(p))
        F = Fint.base_change(R)
        # Compute the iterators of T acting on the winding element.
        e = self.M([0, oo]).element().dense_vector().change_ring(GF(p))
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "wind"
        t = matrix_modp(self.M.hecke_matrix(n).dense_matrix(), p)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "hecke 2"
        g = t.charpoly()
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "char 2"
        Z = t.iterates(e, t.nrows(), rows=True)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "iter"
        # We find all factors F[i][0] for f such that
        # (g/F[i][0])(t) * e = 0.
        # We do this by computing the polynomial
        #       h = g/F[i][0],
        # turning it into a vector v, and computing
        # the matrix product v * Z.  If the product
        # is 0, then e is killed by h(t).
        J = []
        for i in range(len(F)):
            if F[i][1]!=1:
                J.append(i)
                continue
            h, r = g.quo_rem(F[i][0] ** F[i][1])
            assert r == 0
            v = vector(GF(p), h.padded_list(t.nrows()))
            if v * Z == 0:
                J.append(i)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "zero check"

        if self.verbose: print "J =", J
        if len(J) == 0:
            # The annihilator of e is the 0 ideal.
            return matrix_modp(identity_matrix(T.nrows()))

        # Finally compute t1.  I'm concerned about how
        # long this will take, so we reduce T mod 2 first.

        # It is important to call "self.T(2)" to get the mod-2
        # reduction of T2 with respect to the right basis (e.g., the
        # integral basis in case use_integral_structure is true.
        Tmod2 = self.T(n)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "hecke mod" 
        g = prod(Fint[i][0].change_ring(GF(2)) ** Fint[i][1] for i in J)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "g has degree %s"%(g.degree())
        t1 = g(Tmod2)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "t1 finnished"
        return t1        
Beispiel #28
0
    def verify_criterion(self, d, t=None, n=5, p=65521, q=3, v=None, use_rand_vec=False, verbose=False):
        """
        Attempt to verify the criterion at p using the input t. If t is not
        given compute it using n, p and q

        INPUT:
            
            - `t` -- hecke operator (optional default=None)
            - `n` -- integer (optional default=5), used in computing t1
            - `p` -- prime (optional default=46337), used in computing t1
            - `q` -- prime (optional default=3), used in computing t2
            - `verbose` -- bool (default: True); if true, print to
              stdout as the computation is performed.

        OUTPUT:

            - bool -- True if criterion satisfied; otherwise, False
            - string -- message about what happened or went wrong

        EXAMPLES:

        We can't get p=29 to work no matter what I try, which nicely illustrates
        the various ways the criterion can fail::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.verify_criterion(4,n=5)
            dependency dimension to large to search through
            (False,
             'There is a dependency of weigt 2 in dependencies(3,1)',
             [Vector space of degree 4 and dimension 0 over Finite Field of size 2
              Basis matrix:
              [], Vector space of degree 16 and dimension 8 over Finite Field of size 2
              Basis matrix:
              [1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
              [0 1 0 0 0 0 1 0 1 1 0 1 1 1 0 0]
              [0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0]
              [0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0]
              [0 0 0 0 1 0 1 0 1 1 0 1 1 1 0 0]
              [0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0]
              [0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0], Vector space of degree 28 and dimension 19 over Finite Field of size 2
              Basis matrix:
              [1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1]
              [0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0]
              [0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0]
              [0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
              [0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0]
              [0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
              [0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0]
              [0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1]
              [0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1]
              [0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 1 1 1]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 1 1 1]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0]])
        
        With p=43 the criterion is satisfied for d=4, thus proving that 43 is
        not the order of a torsion point on any elliptic curve over
        a quartic field::

            sage: C = KamiennyCriterion(43); C
            Kamienny's Criterion for p=43
            sage: C.verify_criterion(4)
            (True,
             'All conditions are satified for Gamma1 d=4 p=43. Using n=5, modp=65521, q=3 in Kamienny Version 1.5 and SageMath version ...',
             [Vector space of degree 4 and dimension 0 over Finite Field of size 2
              Basis matrix:
              [], Vector space of degree 23 and dimension 2 over Finite Field of size 2
              Basis matrix:
              [1 1 0 1 0 0 1 1 1 0 1 0 1 1 1 1 1 1 0 0 1 0 0]
              [0 0 1 0 1 1 1 0 1 1 0 1 1 1 1 0 1 1 1 1 0 0 0], Vector space of degree 42 and dimension 11 over Finite Field of size 2
              Basis matrix:
              [1 0 0 0 0 0 0 1 0 1 1 1 0 1 1 0 1 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 1 1 1 1 1 1]
              [0 1 0 0 0 0 0 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 0 0 1 0 0]
              [0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0]
              [0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 0]
              [0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0]
              [0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 1 1 1 1 1 1 0 1 0 0 1 1 0 0 1 1 1 0 0 1 0 0 0 1 1 0 1]
              [0 0 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 0 0 1 0 0 0 1 0 1 0 1 0 0 1 1 0 0 0 1 1 1 1]
              [0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 1 1 0 1 1 0 0 0]])
        """
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print "verif start"
        if self.p < (1 + 2 ** (d / 2)) ** 2 and self.verbose:
            print "WARNING: p must be at least (1+2^(d/2))^2 for the criterion to work."
        if t == None:
            t = self.t(n, p, q)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "t"
        if v==None:
            if use_rand_vec:
                v=self.v
            else:
                v=t.parent()(1)
        if self.congruence_type==0:
            verified,message,dependencies=self.verify_gamma0(d,t,v)
        else:
            verified,message,dependencies=self.verify_gamma1(d,t,v)
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "total verif time"
        if not verified:
            return verified,message,dependencies
        return True, "All conditions are satified for Gamma%s d=%s p=%s. Using n=%s, modp=%s, q=%s in Kamienny Version %s and %s" % (self.congruence_type,d, self.p, n, p, q, Kamienny_Version, version()),dependencies
Beispiel #29
0
    def verify_criterion(self, d, t=None, n=5, p=65521, q=3, v=None, use_rand_vec=False, verbose=False):
        """
        Attempt to verify the criterion at p using the input t. If t is not
        given compute it using n, p and q

        INPUT:
            
            - `t` -- hecke operator (optional default=None)
            - `n` -- integer (optional default=5), used in computing t1
            - `p` -- prime (optional default=46337), used in computing t1
            - `q` -- prime (optional default=3), used in computing t2
            - `verbose` -- bool (default: True); if true, print to
              stdout as the computation is performed.

        OUTPUT:

            - bool -- True if criterion satisfied; otherwise, False
            - string -- message about what happened or went wrong

        EXAMPLES:

        We can't get p=29 to work no matter what I try, which nicely illustrates
        the various ways the criterion can fail::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.verify_criterion(4,n=5)
            dependency dimension to large to search through
            (False,
             'There is a dependency of weigt 2 in dependencies(3,1)',
             [Vector space of degree 4 and dimension 0 over Finite Field of size 2
              Basis matrix:
              [], Vector space of degree 16 and dimension 8 over Finite Field of size 2
              Basis matrix:
              [1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
              [0 1 0 0 0 0 1 0 1 1 0 1 1 1 0 0]
              [0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0]
              [0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0]
              [0 0 0 0 1 0 1 0 1 1 0 1 1 1 0 0]
              [0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0]
              [0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0], Vector space of degree 28 and dimension 19 over Finite Field of size 2
              Basis matrix:
              [1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1]
              [0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0]
              [0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0]
              [0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
              [0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0]
              [0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
              [0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0]
              [0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1]
              [0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1]
              [0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 1 1 1]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 1 1 1]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0]])
        
        With p=43 the criterion is satisfied for d=4, thus proving that 43 is
        not the order of a torsion point on any elliptic curve over
        a quartic field::

            sage: C = KamiennyCriterion(43); C
            Kamienny's Criterion for p=43
            sage: C.verify_criterion(4)
            (True,
             'All conditions are satified for Gamma1 d=4 p=43. Using n=5, modp=65521, q=3 in Kamienny Version 1.5 and SageMath version ...',
             [Vector space of degree 4 and dimension 0 over Finite Field of size 2
              Basis matrix:
              [], Vector space of degree 23 and dimension 2 over Finite Field of size 2
              Basis matrix:
              [1 1 0 1 0 0 1 1 1 0 1 0 1 1 1 1 1 1 0 0 1 0 0]
              [0 0 1 0 1 1 1 0 1 1 0 1 1 1 1 0 1 1 1 1 0 0 0], Vector space of degree 42 and dimension 11 over Finite Field of size 2
              Basis matrix:
              [1 0 0 0 0 0 0 1 0 1 1 1 0 1 1 0 1 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 1 1 1 1 1 1]
              [0 1 0 0 0 0 0 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 0 0 1 0 0]
              [0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0]
              [0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 0]
              [0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0]
              [0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 1 1 1 1 1 1 0 1 0 0 1 1 0 0 1 1 1 0 0 1 0 0 0 1 1 0 1]
              [0 0 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 0 0 1 0 0 0 1 0 1 0 1 0 0 1 1 0 0 0 1 1 1 1]
              [0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0]
              [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 1 1 0 1 1 0 0 0]])
        """
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print("verif start")
        if self.p < (1 + 2 ** (d / 2)) ** 2 and self.verbose:
            print("WARNING: p must be at least (1+2^(d/2))^2 for the criterion to work.")
        if t == None:
            t = self.t(n, p, q)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "t")
        if v==None:
            if use_rand_vec:
                v=self.v
            else:
                v=t.parent()(1)
        if self.congruence_type==0:
            verified,message,dependencies=self.verify_gamma0(d,t,v)
        else:
            verified,message,dependencies=self.verify_gamma1(d,t,v)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "total verif time")
        if not verified:
            return verified,message,dependencies
        return True, "All conditions are satified for Gamma%s d=%s p=%s. Using n=%s, modp=%s, q=%s in Kamienny Version %s and %s" % (self.congruence_type,d, self.p, n, p, q, Kamienny_Version, version()),dependencies
def process_curve_standalone(label,
                             digits=600,
                             power=15,
                             verbose=True,
                             internalverbose=False,
                             folder=None):
    import os
    set_random_seed(1)
    import random
    random.seed(1)
    C = lmfdb.getDBconnection()
    curve = C.genus2_curves.curves.find_one({'label': label})
    if curve is None:
        print "Wrong label"
        return 2
    endo_alg = curve['real_geom_end_alg']
    # deals with the default folders
    if folder is None:
        if not '__datadir__' in globals():
            import os
            import inspect
            filename = inspect.getframeinfo(inspect.currentframe())[0]
            __datadir__ = os.path.dirname(filename) + "/data/"
        base_folder = __datadir__
        if endo_alg == 'R':
            print "End = QQ, Nothing to do"
            return 0
        elif endo_alg == 'R x R':
            if curve['is_simple_geom']:
                type_folder = 'simple/RM'
            else:
                type_folder = 'split/nonCM_times_nonCM'
        elif endo_alg == 'C x R':
            type_folder = 'split/CM_times_nonCM'
        elif endo_alg == 'C x C':
            if curve['is_simple_geom']:
                type_folder = 'simple/CM'
            else:
                type_folder = 'split/CM_times_CM'
        elif endo_alg == 'M_2(R)':
            if curve['is_simple_geom']:
                type_folder = 'simple/QM'
            else:
                type_folder = 'split/nonCM_square'
        elif endo_alg == 'M_2(C)':
            type_folder = 'split/CM_square'
        else:
            print "did I forget a case?"
            return 1
        folder = os.path.join(base_folder, type_folder)
        if not os.path.exists(folder):
            print "Creating dir: %s" % folder
            os.makedirs(folder)

    assert os.path.exists(folder)
    #filenames
    stdout_filename = os.path.join(folder, label + ".stdout")
    stderr_filename = os.path.join(folder, label + ".stderr")
    output_filename = os.path.join(folder, label + ".sage")

    sys.stdout = open(stdout_filename, 'w', int(0))
    sys.stderr = open(stderr_filename, 'w')

    c, w = cputime(), walltime()
    data, sout, verified = process_curve_lmfdb(curve,
                                               digits,
                                               power=power,
                                               verbose=True,
                                               internalverbose=False)
    print "Time: CPU %.2f s, Wall: %.2f s" % (
        cputime(c),
        walltime(w),
    )
    output_file = open(output_filename, 'w')
    output_file.write(sout)
    output_file.close()

    sys.stdout.flush()
    os.fsync(sys.stdout.fileno())
    sys.stderr.flush()
    os.fsync(sys.stderr.fileno())
    sys.stdout = sys.__stdout__
    sys.stderr = sys.__stderr__
    print "Done: label = %s, verified = %s" % (label, verified)
    print os.popen("tail -n 1 %s" % stdout_filename).read()
    if verified:
        return 0
    else:
        return 1
Beispiel #31
0
def silke(A, c, beta, h, m=None, scale=1, float_type="double"):
    """

    :param A:    LWE matrix
    :param c:    LWE vector
    :param beta: BKW block size
    :param m:    number of samples to consider
    :param scale: scale rhs of lattice by this factor

    """
    from fpylll import BKZ, IntegerMatrix, LLL, GSO
    from fpylll.algorithms.bkz2 import BKZReduction as BKZ2

    if m is None:
        m = A.nrows()

    L = dual_instance1(A, scale=scale)
    L = IntegerMatrix.from_matrix(L)
    L = LLL.reduction(L, flags=LLL.VERBOSE)
    M = GSO.Mat(L, float_type=float_type)
    bkz = BKZ2(M)
    t = 0.0
    param = BKZ.Param(block_size=beta,
                      strategies=BKZ.DEFAULT_STRATEGY,
                      auto_abort=True,
                      max_loops=16,
                      flags=BKZ.VERBOSE|BKZ.AUTO_ABORT|BKZ.MAX_LOOPS)
    bkz(param)
    t += bkz.stats.total_time

    H = copy(L)

    import pickle
    pickle.dump(L, open("L-%d-%d.sobj"%(L.nrows, beta), "wb"))

    E = []
    Y = set()
    V = set()
    y_i = vector(ZZ, tuple(L[0]))
    Y.add(tuple(y_i))
    E.append(apply_short1(y_i, A, c, scale=scale)[1])

    v = L[0].norm()
    v_ = v/sqrt(L.ncols)
    v_r = 3.2*sqrt(L.ncols - A.ncols())*v_/scale
    v_l = sqrt(h)*v_

    fmt = u"{\"t\": %5.1fs, \"log(sigma)\": %5.1f, \"log(|y|)\": %5.1f, \"log(E[sigma]):\" %5.1f}"

    print
    print fmt%(t,
               log(abs(E[-1]), 2),
               log(L[0].norm(), 2),
               log(sqrt(v_r**2 + v_l**2), 2))
    print
    for i in range(m):
        t = cputime()
        M = GSO.Mat(L, float_type=float_type)
        bkz = BKZ2(M)
        t = cputime()
        bkz.randomize_block(0, L.nrows, stats=None, density=3)
        LLL.reduction(L)
        y_i = vector(ZZ, tuple(L[0]))
        l_n = L[0].norm()
        if L[0].norm() > H[0].norm():
            L = copy(H)
        t = cputime(t)

        Y.add(tuple(y_i))
        V.add(y_i.norm())
        E.append(apply_short1(y_i, A, c, scale=scale)[1])
        if len(V) >= 2:
            fmt =  u"{\"i\": %4d, \"t\": %5.1fs, \"log(|e_i|)\": %5.1f, \"log(|y_i|)\": %5.1f,"
            fmt += u"\"log(sigma)\": (%5.1f,%5.1f), \"log(|y|)\": (%5.1f,%5.1f), |Y|: %5d}"
            print fmt%(i+2, t, log(abs(E[-1]), 2), log(l_n, 2), log_mean(E), log_var(E), log_mean(V), log_var(V), len(Y))

    return E
Beispiel #32
0
    def t1_prime(self, n=5, p=65521):
        """
        Return a multiple of element t1 of the Hecke algebra mod 2,
        computed using the Hecke operator $T_n$, where n is self.n.
        To make computation faster we only check if ...==0 mod p.
        Hence J will contain more elements, hence we get a multiple.
        
        INPUT:
        
            - `n` -- integer (optional default=5)
            - `p` -- prime (optional default=65521)

        OUTPUT:

            - a mod 2 matrix

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.t1_prime()
            22 x 22 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries)
            sage: C.t1_prime(n=3) == 1
            True
            sage: C = KamiennyCriterion(37)
            sage: C.t1_prime()[0]
            (1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0)
        """
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print("t1 start")
        T = self.S.hecke_matrix(n)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "hecke 1")
        f = self.hecke_polynomial(n) # this is the same as T.charpoly()
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "char 1")
        Fint = f.factor()
        if all(i[1]!=1 for i in Fint):
            return matrix_modp(zero_matrix(T.nrows()))
        #    raise ValueError("T_%s needs to be a generator of the hecke algebra"%n)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "factor 1, Fint = %s"%(Fint))
        R = f.parent().change_ring(GF(p))
        F = Fint.base_change(R)
        # Compute the iterators of T acting on the winding element.
        e = self.M([0, oo]).element().dense_vector().change_ring(GF(p))
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "wind")
        t = matrix_modp(self.M.hecke_matrix(n).dense_matrix(), p)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "hecke 2")
        g = t.charpoly()
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "char 2")
        Z = t.iterates(e, t.nrows(), rows=True)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "iter")
        # We find all factors F[i][0] for f such that
        # (g/F[i][0])(t) * e = 0.
        # We do this by computing the polynomial
        #       h = g/F[i][0],
        # turning it into a vector v, and computing
        # the matrix product v * Z.  If the product
        # is 0, then e is killed by h(t).
        J = []
        for i in range(len(F)):
            if F[i][1]!=1:
                J.append(i)
                continue
            h, r = g.quo_rem(F[i][0] ** F[i][1])
            assert r == 0
            v = vector(GF(p), h.padded_list(t.nrows()))
            if v * Z == 0:
                J.append(i)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "zero check")

        if self.verbose: print("J =", J)
        if len(J) == 0:
            # The annihilator of e is the 0 ideal.
            return matrix_modp(identity_matrix(T.nrows()))

        # Finally compute t1.  I'm concerned about how
        # long this will take, so we reduce T mod 2 first.

        # It is important to call "self.T(2)" to get the mod-2
        # reduction of T2 with respect to the right basis (e.g., the
        # integral basis in case use_integral_structure is true.
        Tmod2 = self.T(n)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "hecke mod") 
        g = prod(Fint[i][0].change_ring(GF(2)) ** Fint[i][1] for i in J)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "g has degree %s"%(g.degree()))
        t1 = g(Tmod2)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "t1 finnished")
        return t1        
Beispiel #33
0
 def integral_cuspidal_subspace(self):
     """
     In certatain cases this might return the integral structure of the cuspidal subspace.
     This code is mainly a way to compute the integral structe faster than sage does now. 
     It returns None if it cannot find the integral subspace. 
     """
     if self.verbose: tm = cputime(); mem = get_memory_usage(); print "Int struct start"
     #This code is the same as the firs part of self.M.integral_structure
     G = set([i for i, _ in self.M._mod2term])
     G = list(G)
     G.sort()
     #if there is a two term relation between two manin symbols we only need one of the two
     #so that's why we only use elements from G instead of all manin symbols.
     if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "G"
     B = self.M._manin_gens_to_basis.matrix_from_rows(list(G)).sparse_matrix()
     if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "B"
     #The collums of B now span self.M.integral_structure as ZZ-module
     B, d = B._clear_denom()
     if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Clear denom"
     if d == 1:
         #for explanation see d == 2
         assert len(set([B.nonzero_positions_in_row(i)[0] for i in xrange(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 1])) == B.ncols(), "B doesn't contain the Identity"
         if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Check Id"
         ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1)
         if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis"
     elif d == 2:
         #in this case the matrix B will contain 2*Id as a minor this allows us to compute the hermite normal form of B in a very efficient way. This will give us the integral basis ZZbasis.
         #if it turns out to be nessecarry this can be generalized to the case d%4==2 if we don't mind to only get the right structure localized at 2
         assert len(set([B.nonzero_positions_in_row(i)[0] for i in xrange(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 2])) == B.ncols(), "B doesn't contain 2*Identity"    
         if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Check 2*Id"
         E = matrix_modp(B,sparse=True)
         if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "matmodp"
         E = E.echelon_form()
         if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "echelon"
         ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1)
         for (pivot_row, pivot_col) in zip(E.pivot_rows(), E.pivots()):
             for j in E.nonzero_positions_in_row(pivot_row):
                 ZZbasis[pivot_col, j] = QQ(1) / 2 
         if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis"
     else:
         return None
     #now we compute the integral kernel of the boundary map with respect to the integral basis. This will give us the integral cuspidal submodule.                 
     boundary_matrix = self.M.boundary_map().matrix()
     if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Boundary matrix"
     ZZboundary_matrix=(ZZbasis*boundary_matrix).change_ring(ZZ)
     if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZBoundary matrix"
     left_kernel_matrix=ZZboundary_matrix.transpose().dense_matrix()._right_kernel_matrix(algorithm='pari')
     if type(left_kernel_matrix)==tuple:
         left_kernel_matrix=left_kernel_matrix[1]
     if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "kernel matrix"
     ZZcuspidal_basis=left_kernel_matrix*ZZbasis
     if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZkernel matrix"
     assert ZZcuspidal_basis.change_ring(QQ).echelon_form()==self.S.basis_matrix() , "the calculated integral basis does not span the right QQ vector space" # a little sanity check. This shows that the colums of ZZcuspidal_basis really span the right QQ vectorspace
     if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "check"
     #finally create the sub-module, we delibarately do this as a QQ vector space with custom basis, because this is faster then dooing the calculations over ZZ since sage will then use a slow hermite normal form algorithm.
     ambient_module=VectorSpace(QQ,ZZcuspidal_basis.ncols())
     int_struct = ambient_module.submodule_with_basis(ZZcuspidal_basis.rows())
     if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "finnished"
     return int_struct
Beispiel #34
0
    def __init__(self, p, congruence_type=1, sign=1, algorithm="custom", verbose=False, dump_dir=None):
        """
        Create a Kamienny criterion object.

        INPUT:

            - `p` -- prime -- verify that there is no order p torsion
              over a degree `d` field
            - `sign` -- 1 (default),-1 or 0 -- the sign of the modular symbols space to use 
            - ``algorithm`` -- "default" or "custom" whether to use a custom (faster)
              integral structure algorithm or to use the sage builtin algortihm
            - ``verbose`` -- bool; whether to print extra stuff while
              running.

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29, algorithm="custom", verbose=False); C
            Kamienny's Criterion for p=29
            sage: C.use_custom_algorithm
            True
            sage: C.p
            29
            sage: C.verbose
            False        
        """
        self.verbose = verbose
        self.dump_dir = dump_dir
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print("init")
        assert congruence_type == 0 or congruence_type == 1
        self.congruence_type=congruence_type
        try:
            p = ZZ(p)
            if congruence_type==0:
                self.congruence_group = Gamma0(p)
            if congruence_type==1:
                self.congruence_group = GammaH(p,[-1])
        except TypeError:
            self.congruence_group = GammaH(p.level(),[-1]+p._generators_for_H())
            self.congruence_type = ("H",self.congruence_group._list_of_elements_in_H())
            
        self.p = self.congruence_group.level()
  
        self.algorithm=algorithm
        self.sign=sign
        
        self.M = ModularSymbols(self.congruence_group, sign=sign)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "modsym")
        self.S = self.M.cuspidal_submodule()
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "cuspsub")
        self.use_custom_algorithm = False
        if algorithm=="custom":
            self.use_custom_algorithm = True
        if self.use_custom_algorithm:
            int_struct = self.integral_cuspidal_subspace()
            if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "custom int_struct")
        else:    
            int_struct = self.S.integral_structure()
            if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "sage int_struct")
        self.S_integral = int_struct
        v = VectorSpace(GF(2), self.S.dimension()).random_element()
        self.v=v
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "rand_vect")
        if dump_dir:
            v.dump(dump_dir+"/vector%s_%s" % (p,congruence_type))
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "dump")