Example #1
0
def BigArithGroup(p,quat_data,level,base = None, grouptype = None,seed = None,use_sage_db = False,outfile = None, magma = None, timeout = 0, logfile = None, use_shapiro = True, character = None, nscartan = None, matrix_group = False):
    if magma is None:
        from sage.interfaces.magma import Magma
        magma = Magma(logfile = logfile)
        page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec'
        if seed is not None:
            magma.eval('SetSeed(%s)'%seed)
        magma.attach_spec(page_path)
    magma.eval('Page_initialized := true')
    a, b = None, None
    if logfile is not None:
        magma.eval('SetVerbose("Kleinian",2)')
    try:
        discriminant = ZZ(quat_data)
        if base is not None:
            assert base == QQ
        else:
            base = QQ
        fname = 'arithgroup%s_%s_%s_%s.sobj'%(seed,p,discriminant,level) # Fix this name
    except TypeError:
        a,b = quat_data
        if base is None:
            base = a.parent()
        discriminant = QuaternionAlgebra(base,a,b).discriminant()
        fname = 'arithgroup%s_%s_%s_%s.sobj'%(seed,p,discriminant,level) # Fix this name
    if base != QQ:
        use_sage_db = False # This is not implemented yet

    if grouptype is None:
        if base == QQ:
            grouptype = 'PSL2'
        else:
            grouptype = 'PGL2'

    if use_sage_db:
        try:
            newobj = db(fname)
        except IOError:
            verbose('Group not found in database. Computing from scratch.')
            newobj = BigArithGroup_class(base,p,discriminant,level,seed,outfile = outfile,grouptype = grouptype,magma = magma,timeout = timeout, use_shapiro = use_shapiro, character = character, nscartan = nscartan, matrix_group = matrix_group)
            newobj.save_to_db()
    else:
        if a is not None:
            newobj = BigArithGroup_class(base,p,discriminant,abtuple = (a,b),level = level,seed = seed,outfile = outfile,grouptype = grouptype,magma = magma,timeout = timeout, use_shapiro = use_shapiro, character = character, nscartan = nscartan, matrix_group = matrix_group)
        else:
            newobj = BigArithGroup_class(base,p,discriminant,level = level,seed = seed,outfile = outfile,grouptype = grouptype,magma = magma,timeout = timeout, use_shapiro = use_shapiro, character = character, nscartan = nscartan, matrix_group = matrix_group)
    return newobj
Example #2
0
def benchmark(pbound=[3, 2**10],
              nbound=[3, 2**8],
              cbound=[1, Infinity],
              obound=[1, Infinity],
              loops=10,
              tloop=Infinity,
              tmax=Infinity,
              prime=False,
              even=False,
              check=False,
              fname=None,
              write=False,
              overwrite=False,
              verbose=True,
              skip_pari=False,
              skip_magma=False,
              skip_rains=False,
              skip_kummer=False):
    if write:
        mode = 'w' if overwrite else 'a'
        f = open(fname, mode, 0)
    else:
        f = sys.stdout
    pmin, pmax = pbound
    nmin, nmax = nbound
    omin, omax = obound
    cmin, cmax = cbound
    M = Magma()
    for p in xrange(pmin, pmax):
        p = ZZ(p)
        if not p.is_prime():
            continue
        for n in xrange(nmin, nmax):
            n = ZZ(n)
            if (prime == 1 and not is_prime(n)) or (prime == 2
                                                    and not is_prime_power(n)):
                continue
            if n < 2:
                continue
            if n % p == 0:
                continue
            if (not even) and (n % 2 == 0):
                continue
            o, G = find_root_order(p, [n, n], n, verbose=False)
            m = G[0][0].parent().order()
            c = Mod(p, n).multiplicative_order()
            if verbose:
                sys.stdout.write("\r" + " " * 79)
                print("\rp = {}, n = {}, (o = {}, c = {})".format(p, n, o, c))
            if verbose:
                t = mytime()
                sys.stdout.write("Constructing fields ({})".format(
                    time.strftime("%c")))
                sys.stdout.flush()
            q = p**n
            k = GF(q, name='z')
            k_rand = GF(q, modulus='random', name='z')
            k_flint = GF_flint(p, k.modulus(), name='z')
            if verbose > 1:
                sys.stdout.write("\ntotal: {}s\n".format(mytime(t)))
                sys.stdout.flush()
            # Magma
            if verbose:
                sys.stdout.write("\r" + " " * 79)
                sys.stdout.write("\rMagma ({})".format(time.strftime("%c")))
                sys.stdout.flush()
            tloops = 0
            for l in xrange(loops):
                if skip_magma:
                    break
                if (o > omax) or (o == p):
                    break
                # let's assume that launching a new Magma instance is cheaper
                # than computing random irreducible polynomials
                try:
                    M._start()
                except OSError as err:
                    # but it can also cause fork issues...
                    # let's accept this
                    # and fail as the situation will only worsen
                    # unless it is "just" a memory issue
                    # which should be mitigated by COW but is not
                    #print(err)
                    if err.errno == errno.ENOMEM:
                        break
                    else:
                        raise
                try:
                    k_magma = M(k)
                    k_rand_magma = M(k_rand)
                    if tloop is not Infinity:
                        alarm(tloop)
                    t = mytime()
                    k_magma.Embed(k_rand_magma, nvals=0)
                    #M._eval_line("Embed(k_magma, k_rand_magma);", wait_for_prompt=False)
                    tloops += mytime(t)
                except TypeError:
                    # sage/magma interface sometimes gets confused
                    pass
                except (KeyboardInterrupt, AlarmInterrupt):
                    # sage interface eats KeyboardInterrupt
                    # and AlarmInterrupt derives from it
                    tloops = 0
                    break
                finally:
                    if tloop is not Infinity:
                        cancel_alarm()
                    M.quit()
                    # sage pexpect interface leaves zombies around
                    try:
                        while os.waitpid(-1, os.WNOHANG)[0]:
                            pass
                    # but sometimes every child is already buried
                    # and we get an ECHILD error...
                    except OSError:
                        pass
                if tloops > tmax:
                    break
            tmagma = tloops / (l + 1)
            if verbose > 1:
                sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(
                    tloops, tloops / (l + 1)))
                sys.stdout.flush()
            # Rains algorithms
            if verbose:
                sys.stdout.write("\r" + " " * 79)
                sys.stdout.write("\rCyclotomic Rains ({})".format(
                    time.strftime("%c")))
                sys.stdout.flush()
            trains = []
            tloops = 0
            for l in xrange(loops):
                if skip_rains:
                    break
                if (o > omax) or (o == p):
                    break
                try:
                    if tloop is not Infinity:
                        alarm(tloop)
                    t = mytime()
                    a, b = find_gens_cyclorains(k_flint,
                                                k_flint,
                                                use_lucas=False)
                    tloops += mytime(t)
                except (KeyboardInterrupt, AlarmInterrupt):
                    tloops = 0
                    break
                finally:
                    if tloop is not Infinity:
                        cancel_alarm()
                if check and (l == 0 or check > 1):
                    g = a.minpoly()
                    if g.degree() != n:
                        raise RuntimeError("wrong degree")
                    if g != b.minpoly():
                        raise RuntimeError("different minpolys")
                if tloops > tmax:
                    break
            trains.append(tloops / (l + 1))
            if verbose > 1:
                sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(
                    tloops, tloops / (l + 1)))
                sys.stdout.flush()
            # Conic Rains
            if verbose:
                sys.stdout.write("\r" + " " * 79)
                sys.stdout.write("\rConic Rains ({})".format(
                    time.strftime("%c")))
                sys.stdout.flush()
            tloops = 0
            for l in xrange(loops):
                if skip_rains:
                    break
                if (o != 2) or (o > omax) or (o == p):
                    break
                try:
                    if tloop is not Infinity:
                        alarm(tloop)
                    t = mytime()
                    a, b = find_gens_cyclorains(k_flint,
                                                k_flint,
                                                use_lucas=True)
                    tloops += mytime(t)
                except (KeyboardInterrupt, AlarmInterrupt):
                    tloops = 0
                    break
                finally:
                    if tloop is not Infinity:
                        cancel_alarm()
                if check and (l == 0 or check > 1):
                    g = a.minpoly()
                    if g.degree() != n:
                        raise RuntimeError("wrong degree")
                    if g != b.minpoly():
                        raise RuntimeError("different minpolys")
                if tloops > tmax:
                    break
            trains.append(tloops / (l + 1))
            if verbose > 1:
                sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(
                    tloops, tloops / (l + 1)))
                sys.stdout.flush()
            # Elliptic Rains
            if verbose:
                sys.stdout.write("\r" + " " * 79)
                sys.stdout.write("\rElliptic Rains ({})".format(
                    time.strftime("%c")))
                sys.stdout.flush()
            tloops = 0
            for l in xrange(loops):
                if skip_rains:
                    break
                try:
                    if tloop is not Infinity:
                        alarm(tloop)
                    t = mytime()
                    a, b = find_gens_ellrains(k_flint, k_flint)
                    tloops += mytime(t)
                except RuntimeError:
                    # sometimes no suitable elliptic curve exists
                    pass
                except (KeyboardInterrupt, AlarmInterrupt):
                    tloops = 0
                    break
                finally:
                    if tloop is not Infinity:
                        cancel_alarm()
                if check and (l == 0 or check > 1):
                    g = a.minpoly()
                    if g.degree() != n:
                        raise RuntimeError("wrong degree")
                    if g != b.minpoly():
                        raise RuntimeError("different minpolys")
                if tloops > tmax:
                    break
            trains.append(tloops / (l + 1))
            if verbose > 1:
                sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(
                    tloops, tloops / (l + 1)))
                sys.stdout.flush()
            # PARI/GP
            if verbose:
                sys.stdout.write("\r" + " " * 79)
                sys.stdout.write("\rPARI/GP ({})".format(time.strftime("%c")))
                sys.stdout.flush()
            tloops = 0
            for l in xrange(loops):
                if skip_pari:
                    break
                if c < cmin or c > cmax:
                    break
                try:
                    if tloop is not Infinity:
                        alarm(tloop)
                    t = mytime()
                    a, b = find_gens_pari(k, k)
                    tloops += mytime(t)
                except (KeyboardInterrupt, AlarmInterrupt):
                    tloops = 0
                    break
                finally:
                    if tloop is not Infinity:
                        cancel_alarm()
                if check and (l == 0 or check > 1):
                    g = a.minpoly()
                    if g.degree() != n:
                        raise RuntimeError("wrong degree")
                    if g != b.minpoly():
                        raise RuntimeError("different minpolys")
                if tloops > tmax:
                    break
            tpari = tloops / (l + 1)
            # Kummer algorithms
            tkummer = []
            # only linalg and modcomp implemented for c==1
            for i, algo in enumerate(kummer_algolist[2 * (c == 1):-2 *
                                                     (c == 1) - 1]):
                if verbose:
                    sys.stdout.write("\r" + " " * 79)
                    sys.stdout.write("\rKummer {} ({})".format(
                        kummer_namelist[2 * (c == 1) + i],
                        time.strftime("%c")))
                    sys.stdout.flush()
                tloops = 0
                for l in xrange(loops):
                    if skip_kummer:
                        break
                    if c < cmin or c > cmax:
                        break
                    try:
                        if tloop is not Infinity:
                            alarm(tloop)
                        t = mytime()
                        a, b = find_gens_kummer(k_flint, k_flint, n, algo)
                        tloops += mytime(t)
                    except (KeyboardInterrupt, AlarmInterrupt):
                        tloops = 0
                        break
                    finally:
                        if tloop is not Infinity:
                            cancel_alarm()
                    if check and (l == 0 or check > 1):
                        g = a.minpoly()
                        if g.degree() != n:
                            raise RuntimeError("wrong degree")
                        if g != b.minpoly():
                            raise RuntimeError("different minpolys")
                    if tloops > tmax:
                        break
                tkummer.append(tloops / (l + 1))
                if verbose > 1:
                    sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(
                        tloops, tloops / (l + 1)))
                    sys.stdout.flush()
            tkummer = 2 * (c == 1) * [0] + tkummer + 2 * (c == 1) * [0]
            if verbose:
                sys.stdout.write("\r")
                sys.stdout.flush()
            f.write(("{} {} ({}, {})" + " {}" + " {}" * len(trains) + " {}" +
                     " {}" * len(tkummer) + "\n").format(
                         p, n, o, c, *([tmagma] + trains + [tpari] + tkummer)))
    if write:
        f.close()
Example #3
0
from pymongo.mongo_client import MongoClient
import pymongo
import yaml
from bson import ObjectId
from sage.interfaces.magma import Magma
from sets import Set

magma = Magma()

C = MongoClient(port=int(27017))
cap = C.curve_automorphisms.passports

helper_code = '''
/* helper functions for orbits */
/* L is list of IDs */
PrtOrbit:=function(L);
   prtstring:="  - [";
   for i in [1..#L-1] do
      prtstring:=prtstring cat "'" cat L[i] cat "'";
      prtstring:=prtstring cat ",";
   end for;
   prtstring:=prtstring cat "'" cat  L[#L] cat "'" cat "]";
   return prtstring; 
end function;
Qi:=function(k,L);
   left_unchanged:=[L[i] : i in [1..k-1]];
   braid:=[L[k]*L[k+1]*L[k]^-1,L[k]];
   right_unchanged:=[L[i]: i in [k+2..#L] ];
   return left_unchanged cat braid cat right_unchanged;
end function;
BrdOrbit:=function(L,r);
Example #4
0
def find_curve(P, DB, NE, prec, sign_ap = None, magma = None, return_all = False, initial_data = None, ramification_at_infinity = None, **kwargs):
    r'''
    EXAMPLES:

    First example::

    sage: from darmonpoints.findcurve import find_curve
    sage: find_curve(5,6,30,20) # long time # optional - magma
    # B = F<i,j,k>, with i^2 = -1 and j^2 = 3
    ...
    '(1, 0, 1, -289, 1862)'

    A second example, now over a real quadratic::

    sage: from darmonpoints.findcurve import find_curve
    sage: F.<r> = QuadraticField(5)
    sage: P = F.ideal(3/2*r + 1/2)
    sage: D = F.ideal(3)
    sage: find_curve(P,D,P*D,30,ramification_at_infinity = F.real_places()[:1]) # long time # optional - magma
    ...

    Now over a cubic of mixed signature::

    sage: from darmonpoints.findcurve import find_curve
    sage: F.<r> = NumberField(x^3 -3)
    sage: P = F.ideal(r-2)
    sage: D = F.ideal(r-1)
    sage: find_curve(P,D,P*D,30) # long time # optional - magma
    ...

    '''
    config = ConfigParser.ConfigParser()
    config.read('config.ini')
    param_dict = config_section_map(config, 'General')
    param_dict.update(config_section_map(config, 'FindCurve'))
    param_dict.update(kwargs)
    param = Bunch(**param_dict)

    # Get general parameters
    outfile = param.get('outfile')
    use_ps_dists = param.get('use_ps_dists',False)
    use_shapiro = param.get('use_shapiro',True)
    use_sage_db = param.get('use_sage_db',False)
    magma_seed = param.get('magma_seed',1515316)
    parallelize = param.get('parallelize',False)
    Up_method = param.get('up_method','naive')
    use_magma = param.get('use_magma',True)
    progress_bar = param.get('progress_bar',True)
    sign_at_infinity = param.get('sign_at_infinity',ZZ(1))

    # Get find_curve specific parameters
    grouptype = param.get('grouptype')
    hecke_bound = param.get('hecke_bound',3)
    timeout = param.get('timeout',0)
    check_conductor = param.get('check_conductor',True)

    if initial_data is None:
        page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec'
        if magma is None:
            from sage.interfaces.magma import Magma
            quit_when_done = True
            magma = Magma()
        else:
            quit_when_done = False
        if magma_seed is not None:
            magma.eval('SetSeed(%s)'%magma_seed)
        magma.attach_spec(page_path)
        magma.eval('Page_initialized := true')
    else:
        quit_when_done = False

    sys.setrecursionlimit(10**6)

    # global qE, Linv, G, Coh, phiE, xgen, xi1, xi2, Phi

    try:
        F = P.ring()
        Fdisc = F.discriminant()
        if not (P*DB).divides(NE):
            raise ValueError,'Conductor (NE) should be divisible by P*DB'
        p = ZZ(P.norm()).abs()

    except AttributeError:
        F = QQ
        P = ZZ(P)
        p = ZZ(P)
        Fdisc = ZZ(1)
        if NE % (P*DB) != 0:
            raise ValueError,'Conductor (NE) should be divisible by P*DB'

    Ncartan = kwargs.get('Ncartan',None)
    Np = NE / (P * DB)
    if Ncartan is not None:
        Np = Np / Ncartan**2
    if use_ps_dists is None:
        use_ps_dists = False # More efficient our own implementation

    if not p.is_prime():
        raise ValueError,'P (= %s) should be a prime, of inertia degree 1'%P

    working_prec = max([2 * prec + 10, 100])

    sgninfty = 'plus' if sign_at_infinity == 1 else 'minus'
    fname = 'moments_%s_%s_%s_%s_%s_%s.sobj'%(Fdisc,p,DB,NE,sgninfty,prec)

    if outfile == 'log':
        outfile = '%s_%s_%s_%s_%s.log'%(P,NE,sgninfty,prec,datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
        outfile = outfile.replace('/','div')
        outfile = '/tmp/findcurve_' + outfile

    if F != QQ and ramification_at_infinity is None:
        if F.signature()[0] > 1:
            if F.signature()[1] == 1:
                ramification_at_infinity = F.real_places(prec = Infinity) # Totally 'definite'
            else:
                raise ValueError,'Please specify the ramification at infinity'
        elif F.signature()[0] == 1:
            if len(F.ideal(DB).factor()) % 2 == 0:
                ramification_at_infinity = [] # Split at infinity
            else:
                ramification_at_infinity = F.real_places(prec = Infinity) # Ramified at infinity
        else:
            ramification_at_infinity = None

    if outfile is not None:
        print("Partial results will be saved in %s"%outfile)

    if initial_data is not None:
        G,phiE = initial_data
    else:
        # Define the S-arithmetic group
        try:
            if F == QQ:
                abtuple = QuaternionAlgebra(DB).invariants()
            else:
                abtuple = quaternion_algebra_invariants_from_ramification(F,DB,ramification_at_infinity)
            G = BigArithGroup(P, abtuple, Np, use_sage_db = use_sage_db, grouptype = grouptype, magma = magma, seed = magma_seed, timeout = timeout, use_shapiro = use_shapiro, nscartan = Ncartan)
        except RuntimeError as e:
            if quit_when_done:
                magma.quit()
            mystr = str(e)
            if len(mystr) > 30:
                mystr = mystr[:14] + ' ... ' + mystr[-14:]
            if return_all:
                return ['Error when computing G: ' + mystr]
            else:
                return 'Error when computing G: ' + mystr

        # Define phiE, the cohomology class associated to the system of eigenvalues.
        Coh = ArithCoh(G)
        try:
            phiE = Coh.get_rational_cocycle(sign = sign_at_infinity,bound = hecke_bound,return_all = return_all,use_magma = True)
        except Exception as e:
            if quit_when_done:
                magma.quit()
            if return_all:
                return ['Error when finding cohomology class: ' + str(e)]
            else:
                return 'Error when finding cohomology class: ' + str(e)
        if use_sage_db:
            G.save_to_db()
        fwrite('Cohomology class found', outfile)
    try:
        ker = [G.inverse_shapiro(o) for o in G.get_homology_kernel()]
    except Exception as e:
        if quit_when_done:
            magma.quit()
        if return_all:
            return ['Problem calculating homology kernel: ' + str(e)]
        else:
            return 'Problem calculating homology kernel: ' + str(e)

    if not return_all:
        phiE = [phiE]
    ret_vals = []
    for phi in phiE:
        try:
            Phi = get_overconvergent_class_quaternionic(P,phi,G,prec,sign_at_infinity,sign_ap,use_ps_dists,method = Up_method, progress_bar = progress_bar)
        except ValueError as e:
            ret_vals.append('Problem when getting overconvergent class: ' + str(e))
            continue
        fwrite('Done overconvergent lift', outfile)
        # Find an element x of Gpn for not in the kernel of phi,
        # and such that both x and wp^-1 * x * wp are trivial in the abelianization of Gn.
        try:
            found = False
            for o in ker:
                phi_o = sum( [phi.evaluate(t**a) for t, a in o], 0 )
                if use_shapiro:
                    phi_o = phi_o.evaluate_at_identity()
                if phi_o != 0:
                    found = True
                    break
            if not found:
                raise RuntimeError('Cocycle evaluates always to zero')
        except Exception as e:
            ret_vals.append('Problem when choosing element in kernel: ' + str(e))
            continue
        xgenlist = o
        found = False
        while not found:
            try:
                xi1, xi2 = lattice_homology_cycle(G,xgenlist,working_prec,outfile = outfile)
                found = True
            except PrecisionError:
                working_prec  = 2 * working_prec
                verbose('Setting working_prec to %s'%working_prec)
            except Exception as e:
                ret_vals.append('Problem when computing homology cycle: ' + str(e))
                verbose('Exception occurred: ' + str(e))
                break
        if not found:
            continue
        try:
            qE1 = integrate_H1(G,xi1,Phi,1,method = 'moments',prec = working_prec, twist = False,progress_bar = progress_bar)
            qE2 = integrate_H1(G,xi2,Phi,1,method = 'moments',prec = working_prec, twist = True,progress_bar = progress_bar)
        except Exception as e:
            ret_vals.append('Problem with integration: %s'%str(e))
            continue

        qE = qE1/qE2
        qE = qE.add_bigoh(prec + qE.valuation())
        Linv = qE.log(p_branch = 0)/qE.valuation()

        fwrite('Integral done. Now trying to recognize the curve', outfile)
        fwrite('F.<r> = NumberField(%s)'%(F.gen(0).minpoly()),outfile)
        fwrite('N_E = %s = %s'%(NE,factor(NE)),outfile)
        fwrite('D_B = %s = %s'%(DB,factor(DB)),outfile)
        fwrite('Np = %s = %s'%(Np,factor(Np)),outfile)
        if Ncartan is not None:
            fwrite('Ncartan = %s'%(Ncartan),outfile)
        fwrite('Calculation with p = %s and prec = %s+%s'%(P,prec,working_prec-prec),outfile)
        fwrite('qE = %s'%qE,outfile)
        fwrite('Linv = %s'%Linv,outfile)
        curve = discover_equation(qE,G._F_to_local,NE,prec,check_conductor = check_conductor)
        if curve is None:
            if quit_when_done:
                magma.quit()
            ret_vals.append('None')
        else:
            try:
                curve = curve.global_minimal_model()
            except AttributeError,NotImplementedError:
                pass
            fwrite('EllipticCurve(F, %s )'%(list(curve.a_invariants())), outfile)
            fwrite('=' * 60, outfile)
            ret_vals.append(str(curve.a_invariants()))
Example #5
0
def find_curve(P,
               DB,
               NE,
               prec,
               sign_ap=None,
               magma=None,
               return_all=False,
               initial_data=None,
               ramification_at_infinity=None,
               implementation=None,
               **kwargs):
    r'''
    EXAMPLES:

    First example::

    sage: from darmonpoints.findcurve import find_curve
    sage: find_curve(5,6,30,20) # long time # optional - magma
    # B = F<i,j,k>, with i^2 = -1 and j^2 = 3
    ...
    '(1, 0, 1, -289, 1862)'

    A second example, now over a real quadratic::

    sage: from darmonpoints.findcurve import find_curve
    sage: F.<r> = QuadraticField(5)
    sage: P = F.ideal(3/2*r + 1/2)
    sage: D = F.ideal(3)
    sage: find_curve(P,D,P*D,30,ramification_at_infinity = F.real_places()[:1]) # long time # optional - magma
    ...

    Now over a cubic of mixed signature::

    sage: from darmonpoints.findcurve import find_curve
    sage: F.<r> = NumberField(x^3 -3)
    sage: P = F.ideal(r-2)
    sage: D = F.ideal(r-1)
    sage: find_curve(P,D,P*D,30) # long time # optional - magma
    ...

    '''
    config = ConfigParser.ConfigParser()
    config.read('config.ini')
    param_dict = config_section_map(config, 'General')
    param_dict.update(config_section_map(config, 'FindCurve'))
    param_dict.update(kwargs)
    param = Bunch(**param_dict)

    # Get general parameters
    outfile = param.get('outfile')
    use_ps_dists = param.get('use_ps_dists', False)
    use_shapiro = param.get('use_shapiro', False)
    use_sage_db = param.get('use_sage_db', False)
    magma_seed = param.get('magma_seed', 1515316)
    parallelize = param.get('parallelize', False)
    Up_method = param.get('up_method', 'naive')
    use_magma = param.get('use_magma', True)
    progress_bar = param.get('progress_bar', True)
    sign_at_infinity = param.get('sign_at_infinity', ZZ(1))

    # Get find_curve specific parameters
    grouptype = param.get('grouptype')
    hecke_bound = param.get('hecke_bound', 3)
    timeout = param.get('timeout', 0)
    check_conductor = param.get('check_conductor', True)

    if initial_data is None:
        page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec'
        if magma is None:
            from sage.interfaces.magma import Magma
            quit_when_done = True
            magma = Magma()
        else:
            quit_when_done = False
        if magma_seed is not None:
            magma.eval('SetSeed(%s)' % magma_seed)
        magma.attach_spec(page_path)
        magma.eval('Page_initialized := true')
    else:
        quit_when_done = False

    sys.setrecursionlimit(10**6)

    # global qE, Linv, G, Coh, phiE, xgen, xi1, xi2, Phi

    try:
        F = P.ring()
        Fdisc = F.discriminant()
        if not (P * DB).divides(NE):
            raise ValueError('Conductor (NE) should be divisible by P*DB')
        p = ZZ(P.norm()).abs()

    except AttributeError:
        F = QQ
        P = ZZ(P)
        p = ZZ(P)
        Fdisc = ZZ(1)
        if NE % (P * DB) != 0:
            raise ValueError('Conductor (NE) should be divisible by P*DB')

    Ncartan = kwargs.get('Ncartan', None)
    param_dict['nscartan'] = Ncartan
    Np = NE / (P * DB)
    if Ncartan is not None:
        Np = Np / Ncartan**2
    if use_ps_dists is None:
        use_ps_dists = False  # More efficient our own implementation

    if not p.is_prime():
        raise ValueError('P (= %s) should be a prime, of inertia degree 1' % P)

    working_prec = max([2 * prec + 10, 100])

    sgninfty = 'plus' if sign_at_infinity == 1 else 'minus'
    fname = 'moments_%s_%s_%s_%s_%s_%s.sobj' % (Fdisc, p, DB, NE, sgninfty,
                                                prec)

    if outfile == 'log':
        outfile = '%s_%s_%s_%s_%s.log' % (
            P, NE, sgninfty, prec,
            datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
        outfile = outfile.replace('/', 'div')
        outfile = '/tmp/findcurve_' + outfile

    if F != QQ and ramification_at_infinity is None:
        if F.signature()[0] > 1:
            if F.signature()[1] == 1:
                ramification_at_infinity = F.real_places(
                    prec=Infinity)  # Totally 'definite'
            else:
                raise ValueError('Please specify the ramification at infinity')
        elif F.signature()[0] == 1:
            if len(F.ideal(DB).factor()) % 2 == 0:
                ramification_at_infinity = []  # Split at infinity
            else:
                ramification_at_infinity = F.real_places(
                    prec=Infinity)  # Ramified at infinity
        else:
            ramification_at_infinity = None

    if outfile is not None:
        print("Partial results will be saved in %s" % outfile)

    if initial_data is not None:
        G, phiE = initial_data
    else:
        # Define the S-arithmetic group
        try:
            if F == QQ:
                abtuple = QuaternionAlgebra(DB).invariants()
            else:
                abtuple = quaternion_algebra_invariants_from_ramification(
                    F, DB, ramification_at_infinity, magma=magma)
            G = BigArithGroup(P,
                              abtuple,
                              Np,
                              magma=magma,
                              seed=magma_seed,
                              **param_dict)
        except RuntimeError as e:
            if quit_when_done:
                magma.quit()
            mystr = str(e)
            if len(mystr) > 30:
                mystr = mystr[:14] + ' ... ' + mystr[-14:]
            if return_all:
                return ['Error when computing G: ' + mystr]
            else:
                return 'Error when computing G: ' + mystr

        # Define phiE, the cohomology class associated to the system of eigenvalues.
        Coh = ArithCoh(G)
        try:
            phiE = Coh.get_rational_cocycle(sign=sign_at_infinity,
                                            bound=hecke_bound,
                                            return_all=return_all,
                                            use_magma=True)
        except Exception as e:
            if quit_when_done:
                magma.quit()
            if return_all:
                return ['Error when finding cohomology class: ' + str(e)]
            else:
                return 'Error when finding cohomology class: ' + str(e)
        if use_sage_db:
            G.save_to_db()
        fwrite('Cohomology class found', outfile)
    try:
        ker = [G.inverse_shapiro(o) for o in G.get_homology_kernel()]
    except Exception as e:
        if quit_when_done:
            magma.quit()
        if return_all:
            return ['Problem calculating homology kernel: ' + str(e)]
        else:
            return 'Problem calculating homology kernel: ' + str(e)

    if not return_all:
        phiE = [phiE]
    ret_vals = []
    for phi in phiE:
        try:
            Phi = get_overconvergent_class_quaternionic(
                P,
                phi,
                G,
                prec,
                sign_at_infinity,
                sign_ap,
                use_ps_dists,
                method=Up_method,
                progress_bar=progress_bar)
        except ValueError as e:
            ret_vals.append('Problem when getting overconvergent class: ' +
                            str(e))
            continue
        fwrite('Done overconvergent lift', outfile)
        # Find an element x of Gpn for not in the kernel of phi,
        # and such that both x and wp^-1 * x * wp are trivial in the abelianization of Gn.
        try:
            found = False
            for o in ker:
                phi_o = sum([phi.evaluate(t**a) for t, a in o], 0)
                if use_shapiro:
                    phi_o = phi_o.evaluate_at_identity()
                if phi_o != 0:
                    found = True
                    break
            if not found:
                raise RuntimeError('Cocycle evaluates always to zero')
        except Exception as e:
            ret_vals.append('Problem when choosing element in kernel: ' +
                            str(e))
            continue
        xgenlist = o
        found = False
        while not found:
            try:
                xi1, xi2 = lattice_homology_cycle(p,
                                                  G.Gn,
                                                  G.wp(),
                                                  xgenlist,
                                                  working_prec,
                                                  outfile=outfile)
                found = True
            except PrecisionError:
                working_prec = 2 * working_prec
                verbose('Setting working_prec to %s' % working_prec)
            except Exception as e:
                ret_vals.append('Problem when computing homology cycle: ' +
                                str(e))
                verbose('Exception occurred: ' + str(e))
                break
        if not found:
            continue
        try:
            qE1 = integrate_H1(G,
                               xi1,
                               Phi,
                               1,
                               method='moments',
                               prec=working_prec,
                               twist=False,
                               progress_bar=progress_bar)
            qE2 = integrate_H1(G,
                               xi2,
                               Phi,
                               1,
                               method='moments',
                               prec=working_prec,
                               twist=True,
                               progress_bar=progress_bar)
        except Exception as e:
            ret_vals.append('Problem with integration: %s' % str(e))
            continue

        qE = qE1 / qE2
        qE = qE.add_bigoh(prec + qE.valuation())
        Linv = qE.log(p_branch=0) / qE.valuation()

        fwrite('Integral done. Now trying to recognize the curve', outfile)
        fwrite('F.<r> = NumberField(%s)' % (F.gen(0).minpoly()), outfile)
        fwrite('N_E = %s = %s' % (NE, factor(NE)), outfile)
        fwrite('D_B = %s = %s' % (DB, factor(DB)), outfile)
        fwrite('Np = %s = %s' % (Np, factor(Np)), outfile)
        if Ncartan is not None:
            fwrite('Ncartan = %s' % (Ncartan), outfile)
        fwrite(
            'Calculation with p = %s and prec = %s+%s' %
            (P, prec, working_prec - prec), outfile)
        fwrite('qE = %s' % qE, outfile)
        fwrite('Linv = %s' % Linv, outfile)
        curve = discover_equation(qE,
                                  G._F_to_local,
                                  NE,
                                  prec,
                                  check_conductor=check_conductor)
        if curve is None:
            if quit_when_done:
                magma.quit()
            ret_vals.append('None')
        else:
            try:
                curve = curve.global_minimal_model()
            except AttributeError, NotImplementedError:
                pass
            fwrite('EllipticCurve(F, %s )' % (list(curve.a_invariants())),
                   outfile)
            fwrite('=' * 60, outfile)
            ret_vals.append(str(curve.a_invariants()))
Example #6
0
def BigArithGroup(p,
                  quat_data,
                  level,
                  base=None,
                  grouptype=None,
                  seed=None,
                  use_sage_db=False,
                  magma=None,
                  logfile=None,
                  **kwargs):
    if magma is None:
        from sage.interfaces.magma import Magma
        magma = Magma(logfile=logfile)
    if seed is not None:
        magma.eval('SetSeed(%s)' % seed)
    if not is_page_initialized(magma):
        attach_kleinian_code(magma)
    a, b = None, None
    if logfile is not None:
        magma.eval('SetVerbose("Kleinian",2)')
    try:
        discriminant = ZZ(quat_data)
        if base is not None:
            assert base == QQ
        else:
            base = QQ
        fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level
                                                )  # Fix this name
    except TypeError:
        a, b = quat_data
        if base is None:
            base = a.parent()
        discriminant = QuaternionAlgebra(base, a, b).discriminant()
        fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level
                                                )  # Fix this name
    if base != QQ:
        use_sage_db = False  # This is not implemented yet

    if grouptype is None:
        if base == QQ:
            grouptype = 'PSL2'
        else:
            grouptype = 'PSL2'  # DEBUG, was PGL2

    if use_sage_db:
        try:
            newobj = db(fname)
        except IOError:
            verbose('Group not found in database. Computing from scratch.')
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         level,
                                         seed,
                                         grouptype=grouptype,
                                         magma=magma,
                                         **kwargs)
            newobj.save_to_db()
    else:
        if a is not None:
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         abtuple=(a, b),
                                         level=level,
                                         seed=seed,
                                         grouptype=grouptype,
                                         magma=magma,
                                         **kwargs)
        else:
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         level=level,
                                         seed=seed,
                                         grouptype=grouptype,
                                         magma=magma,
                                         **kwargs)
    return newobj
Example #7
0
def Lpvalue(f,g,h,p,prec,N = None,modformsring = False, weightbound = False, eps = None, orthogonal_form = None, data_idx=None, magma_args = None,force_computation=False, algorithm='threestage', derivative_order=1, lauders_advice = False, use_magma = True, magma = None, num_coeffs_qexpansion = 20000, max_primes=5, outfile = None):
    if magma_args is None:
        magma_args = {}
    if algorithm not in ['twostage','threestage']:
        raise ValueError('Algorithm should be one of "twostage" (default) or "threestage"')

    if magma is None:
        from sage.interfaces.magma import Magma
        magma = Magma(**magma_args)
    if hasattr(g,'j_invariant'):
        elliptic_curve = g
        g = g.modular_form()
    else:
        elliptic_curve = None
    data = None
    if h is None:
        if hasattr(f, 'modulus'):
            # Assume we need to create f and h from Dirichlet character
            kronecker_character = f
            f, _, h = define_qexpansions_from_dirichlet_character(p, prec, kronecker_character, num_coeffs_qexpansion, magma)
        else:
            kronecker_character = None
            # Assume that f contains a list of lines of text to initialize both f and h
            data = f
            f, h = get_magma_qexpansions(data, data_idx, max(prec,200), Qp(p,prec), magma=magma)
            eps = f.character_full()


    ll,mm = g.weight(),h.weight()
    t = 0 # Assume t = 0 here
    kk = ll + mm - 2 * (1 + t) # Is this correct?
    p = ZZ(p)
    if N is None:
        N = lcm([ZZ(f.level()),ZZ(g.level()),ZZ(h.level())])
        nu = N.valuation(p)
        N = N.prime_to_m_part(p)
    else:
        N = ZZ(N)
        nu = N.valuation(p)
    if outfile is None:
        outfile = "output_iterated_integral_%s_%s_%s_%s.txt"%(p,g.level(), h.level(), prec)
    print("Writing output to file %s"%outfile)
    fwrite("######### STARTING COMPUTATION OF Lp ###########", outfile)

    if elliptic_curve is not None:
        fwrite("E = EllipticCurve(%s)"%list(elliptic_curve.ainvs()), outfile)
        fwrite("  cond(E) = %s"%elliptic_curve.conductor(), outfile)
    if kronecker_character is not None:
        fwrite("kronecker_character = %s"%kronecker_character, outfile)
        fwrite("  conductor = %s"%kronecker_character.conductor(), outfile)
    if data is not None:
        fwrite("Data for weight-1 forms:", outfile)
        for line in data:
            fwrite(line, outfile)
    fwrite("Tame level N = %s, prime p = %s, nu = %s"%(N,p,nu), outfile)
    fwrite("precision = %s"%prec, outfile)
    fwrite("------ parameters --------------------", outfile)
    fwrite("modformsring = %s"%modformsring, outfile)
    fwrite("weightbound = %s"%weightbound, outfile)
    fwrite("eps = %s"%eps, outfile)
    fwrite("orthogonal_form = %s"%orthogonal_form, outfile)
    fwrite("magma_args = %s"%magma_args, outfile)
    fwrite("force_computation = %s"%force_computation, outfile)
    fwrite("algorithm = %s"%algorithm, outfile)
    fwrite("derivative_order = %s"%derivative_order, outfile)
    fwrite("lauders_advice = %s"%lauders_advice, outfile)
    fwrite("use_magma = %s"%use_magma, outfile)
    fwrite("num_coeffs_qexpansion = %s"%num_coeffs_qexpansion, outfile)
    fwrite("##########################################", outfile)
    prec = ZZ(prec)

    fwrite("Step 1: Compute the Up matrix", outfile)
    if algorithm == "twostage":
        computation_name = '%s_%s_%s_%s_%s_%s_%s'%(p,N,nu,kk,prec,'triv' if eps is None else 'char',algorithm)
    else:
        computation_name = '%s_%s_%s_%s_%s_%s'%(p,N,nu,kk,prec,'triv' if eps is None else 'char')
    if use_magma:
        tmp_filename = '/tmp/magma_mtx_%s.tmp'%computation_name
        import os.path
        from sage.misc.persist import db, db_save
        try:
            if force_computation:
                raise IOError
            V = db('Lpvalue_Apow_ordbasis_eimat_%s'%computation_name)
            ord_basis, eimat, zetapm, elldash, mdash = V[:5]
            Apow_data = V[5:]
        except IOError:
            if force_computation or not os.path.exists(tmp_filename):
                if eps is not None:
                    eps_magma = sage_character_to_magma(eps,N,magma=magma)
                    magma.load("overconvergent_alan.m")
                    # Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData(p, eps_magma, kk, prec,WeightBound=weightbound,nvals=5)
                    Am, zetapm, eimatm, elldash, mdash = magma.HigherLevelUpGj(p, kk, prec, weightbound, eps_magma,'"B"',nvals=5)
                else:
                    # Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData(p, N, kk, prec,WeightBound=weightbound,nvals=5)
                    magma.load("overconvergent_alan.m")
                    Am, zetapm, eimatm, elldash, mdash = magma.HigherLevelUpGj(p, kk, prec, weightbound, N,'"B"',nvals=5)
                fwrite(" ..Converting to Sage...", outfile)
                Amodulus = Am[1,1].Parent().Modulus().sage()
                Aprec = Amodulus.valuation(p)
                Arows = Am.NumberOfRows().sage()
                Acols = Am.NumberOfColumns().sage()
                Emodulus = eimatm[1,1].Parent().Modulus().sage()
                Eprec = Emodulus.valuation(p)
                Erows = eimatm.NumberOfRows().sage()
                Ecols = eimatm.NumberOfColumns().sage()
                magma.load("get_qexpansions.m")
                magma.eval('F := Open("%s", "w");'%tmp_filename)
                magma.eval('fprintf F, "%s, %s, %s, %s \\n"'%(p,Aprec,Arows,Acols)) # parameters
                magma.eval('save_matrix(%s, F)'%(Am.name()))
                # for i in range(1,Arows+1):
                #     magma.eval('fprintf F, "%%o\\n", %s[%s]'%(Am.name(),i))
                magma.eval('fprintf F, "%s, %s, %s, %s \\n"'%(p,Eprec,Erows,Ecols)) # parameters
                magma.eval('save_matrix(%s, F)'%(eimatm.name()))
                # for i in range(1,Erows+1):
                #     magma.eval('fprintf F, "%%o\\n", %s[%s]'%(eimatm.name(),i))
                magma.eval('fprintf F, "%s\\n"'%zetapm)
                magma.eval('fprintf F, "%s\\n"'%elldash)
                magma.eval('fprintf F, "%s\\n"'%mdash)
                magma.eval('delete F;')
                magma.quit()

            # Read A and eimat from file
            from sage.structure.sage_object import load
            from sage.misc.sage_eval import sage_eval
            with open(tmp_filename,'r') as fmagma:
                A = read_matrix_from_file(fmagma)
                eimat = read_matrix_from_file(fmagma)
                zetapm= sage_eval(fmagma.readline())
                elldash = sage_eval(fmagma.readline())
                mdash = sage_eval(fmagma.readline())

            fwrite("Step 3b: Apply Up^(r-1) to H", outfile)
            if algorithm == 'twostage':
                V0  = list(find_Apow_and_ord_two_stage(A, eimat, p, prec))
            else:
                V0 = list(find_Apow_and_ord_three_stage(A,eimat,p,prec))
            ord_basis = V0[0]
            Apow_data = V0[1:]
            V = [ord_basis]
            V.extend([eimat, zetapm, elldash, mdash])
            V.extend(Apow_data)
            db_save(V,'Lpvalue_Apow_ordbasis_eimat_%s'%computation_name)
            from posix import remove
            remove(tmp_filename)

    else:
        A, eimat, elldash, mdash = UpOperator(p,N,kk,prec, modformsring = False, weightbound = 6)

    fwrite("Step 2: p-depletion, Coleman primitive, and multiply", outfile)
    fwrite(".. Need %s coefficients of the q-expansion..."%(p**(nu+1) * elldash), outfile)
    if data is not None:
        f, h = get_magma_qexpansions(data, data_idx, (p**(nu+1) * elldash) + 200, Qp(p,prec), magma=magma)

    H = depletion_coleman_multiply(g, h, p, p**(nu+1) * elldash, t=0)

    fwrite("Step 3a: Compute ordinary projection", outfile)

    if len(Apow_data) == 1:
        Hord = compute_ordinary_projection_two_stage(H, Apow_data, eimat, elldash,p)
    else:
        Hord = compute_ordinary_projection_three_stage(H, [ord_basis] + Apow_data, eimat, elldash,p,nu)
    fwrite('Changing Hord to ring %s'%g[1].parent(), outfile)
    Hord = Hord.change_ring(h[1].parent())
    print [Hord[i] for i in range(30)]
    fwrite("Step 4: Project onto f-component", outfile)
    while True:
        try:
            ell, piHord, epstwist = project_onto_eigenspace(f, ord_basis, Hord, kk, N * p, p = p, derivative_order=derivative_order, max_primes=max_primes)
            break
        except RuntimeError:
            derivative_order += 1
            verbose("Increasing experimental derivative order to %s"%derivative_order)
        except ValueError:
            verbose("Experimental derivative order (%s) seems too high"%derivative_order)
            fwrite("Experimental derivative_order = %s"%derivative_order, outfile)
            fwrite("Seems too high...", outfile)
            fwrite("######################################", outfile)
            assert 0
    n = 1
    while f[n] == 0:
        n = next_prime(n)
    if lauders_advice == True or orthogonal_form is None:
        Lpa =  piHord[n] / (f[n] * epstwist(n))
        fwrite("Experimental derivative_order = %s"%derivative_order, outfile)
        fwrite("Checking Lauder's coincidence... (following should be a bunch of 'large' valuations)", outfile)
        fwrite(str([(i,(Lpa * f[i] * epstwist(i) - piHord[i]).valuation(p)) for i in prime_range(50)]), outfile)
        fwrite("Done", outfile)
    else:
        gplus, gminus = f, orthogonal_form
        l1 = 2
        while N*p*ell % l1 == 0 or gplus[l1] == 0:
            l1 = next_prime(l1)
        proj_mat = matrix([[gplus[l1],gplus[p]],[gminus[l1],gminus[p]]])
        Lpalist =  (matrix([piHord[l1],piHord[p]]) * proj_mat**-1).list()
        Lpa = Lpalist[0]
        if Lpa.valuation() > prec / 2: # this is quite arbitrary!
            Lpa = Lpalist[1]
        Lpa = Lpa / f[n]
    fwrite("ell = %s"%ell, outfile)
    fwrite("######### FINISHED COMPUTATION ###########", outfile)
    fwrite("Lp = %s"%Lpa, outfile)
    fwrite("##########################################", outfile)
    return Lpa, ell
Example #8
0
def Lpvalue(f,
            g,
            h,
            p,
            prec,
            N=None,
            modformsring=False,
            weightbound=6,
            eps=None,
            orthogonal_form=None,
            magma_args=None,
            force_computation=False,
            algorithm='twostage'):
    if magma_args is None:
        magma_args = {}
    if algorithm not in ['twostage', 'threestage']:
        raise ValueError(
            'Algorithm should be one of "twostage" (default) or "threestage"')
    from sage.interfaces.magma import Magma
    magma = Magma(**magma_args)
    ll, mm = g.weight(), h.weight()
    t = 0  # Assume t = 0 here
    kk = ll + mm - 2 * (1 + t)  # Is this correct?
    p = ZZ(p)
    if N is None:
        N = LCM([ZZ(f.level()), ZZ(g.level()), ZZ(h.level())])
        N = N.prime_to_m_part(p)

    print("Tame level N = %s, prime p = %s" % (N, p))
    prec = ZZ(prec)

    print("Step 1: Compute the Up matrix")
    computation_name = '%s_%s_%s_%s_%s_%s' % (
        p, N, kk, prec, 'triv' if eps is None else 'char', algorithm)
    tmp_filename = '/tmp/magma_mtx_%s.tmp' % computation_name
    import os.path
    from sage.misc.persist import db, db_save
    try:
        if force_computation:
            raise IOError
        V = db('Lpvalue_Apow_ordbasis_eimat_%s' % computation_name)
        ord_basis, eimat, zetapm, elldash, mdash = V[:5]
        Apow_data = V[5:]
    except IOError:
        if force_computation or not os.path.exists(tmp_filename):
            if eps is not None:
                eps_magma = sage_character_to_magma(eps, magma=magma)
                Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData(
                    p, eps_magma, kk, prec, nvals=5)
            else:
                Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData(
                    p, N, kk, prec, nvals=5)
            print(" ..Converting to Sage...")
            Amodulus = Am[1, 1].Parent().Modulus().sage()
            Arows = Am.NumberOfRows().sage()
            Acols = Am.NumberOfColumns().sage()
            Emodulus = eimatm[1, 1].Parent().Modulus().sage()
            Erows = eimatm.NumberOfRows().sage()
            Ecols = eimatm.NumberOfColumns().sage()
            magma.eval('F := Open("%s", "w");' % tmp_filename)
            magma.eval('fprintf F, "Matrix(Zmod(%s),%s, %s, "' %
                       (Amodulus, Arows, Acols))
            magma.eval('fprintf F, "%%o", ElementToSequence(%s)' % Am.name())
            magma.eval('fprintf F, ") \\n"')
            magma.eval('fprintf F, "Matrix(Zmod(%s),%s, %s, "' %
                       (Emodulus, Erows, Ecols))
            magma.eval('fprintf F, "%%o", ElementToSequence(%s)' %
                       eimatm.name())
            magma.eval('fprintf F, ") \\n"')
            magma.eval('fprintf F, "%%o\\n", %s' % zetapm.name())
            magma.eval('fprintf F, "%%o\\n", %s' % elldash.name())
            magma.eval('fprintf F, "%%o\\n", %s' % mdash.name())
            magma.eval('delete F;')
            magma.quit()

        # Read A and eimat from file
        from sage.structure.sage_object import load
        from sage.misc.sage_eval import sage_eval
        with open(tmp_filename, 'r') as fmagma:
            A = sage_eval(fmagma.readline(), preparse=False)
            eimat = sage_eval(fmagma.readline(), preparse=False)
            zetapm = sage_eval(fmagma.readline())
            elldash = sage_eval(fmagma.readline())
            mdash = sage_eval(fmagma.readline())

        print("Step 3b: Apply Up^(r-1) to H")
        if algorithm == 'twostage':
            V0 = list(find_Apow_and_ord(A, eimat, p, prec))
        else:
            V0 = list(find_Apow_and_ord_three_stage(A, eimat, p, prec))
        ord_basis = V0[0]
        Apow_data = V0[1:]
        V = [ord_basis]
        V.extend([eimat, zetapm, elldash, mdash])
        V.extend(Apow_data)
        db_save(V, 'Lpvalue_Apow_ordbasis_eimat_%s' % computation_name)
        from posix import remove
        remove(tmp_filename)

    print("Step 2: p-depletion, Coleman primitive, and multiply")
    H = depletion_coleman_multiply(g, h, p, p * elldash, t=0)

    print("Step 3a: Compute Up(H)")
    UpH = vector([H(p * n) for n in range(elldash)])

    if len(Apow_data) == 1:
        Hord = compute_ordinary_projection_two_stage(UpH, Apow_data, eimat,
                                                     elldash)
    else:
        Hord = compute_ordinary_projection_three_stage(UpH,
                                                       [ord_basis] + Apow_data,
                                                       eimat, elldash)
    Hord = Hord.change_ring(Apow_data[0].parent().base_ring())

    print("Step 4: Project onto f-component")
    R = Qp(p, prec)
    if orthogonal_form is None:
        ell, piHord = project_onto_eigenspace(f, ord_basis,
                                              Hord.change_ring(R), kk, N * p,
                                              eps)
        n = 1
        while f[n] == 0:
            n += 1
        Lpa = R(piHord[n]) / R(f[n])
    else:
        ell, piHord = project_onto_eigenspace(f,
                                              ord_basis,
                                              Hord.change_ring(R),
                                              kk,
                                              N * p,
                                              eps,
                                              derivative_order=2)
        gplus, gminus = f, orthogonal_form
        l1 = 2
        while N * p * ell % l1 == 0 or gplus[l1] == 0:
            l1 = next_prime(l1)
        proj_mat = matrix([[gplus[l1], gplus[p]], [gminus[l1], gminus[p]]])
        Lpalist = (matrix([piHord[l1], piHord[p]]) * proj_mat**-1).list()
        Lpa = Lpalist[0]
        if Lpa.valuation() > prec / 2:  # this is quite arbitrary!
            Lpa = Lpalist[1]
        n = 1
        while f[n] == 0:
            n += 1
        Lpa = Lpa / f[n]
    return Lpa, ell
Example #9
0
def get_magma_qexpansions(filename, i1, prec, base_ring, magma=None):
    if magma is None:
        from sage.interfaces.magma import Magma
        magma = Magma()
    magma.set('prec',prec)
    magma.load("get_qexpansions.m")
    if i1 is None:
        for line in filename:
            print line
            magma.eval(line)
        magma.eval("f := g") # In case text is reversed
        f = 'f'
        eps_data_f = 'eps_on_gens'
    else:
        magma.load(filename)
        f = 'eigenforms_list[%s][1]'%i1
        eps_data_f = 'eigenforms_list[%s][2]'%i1
    qexpm = magma.extend_qexpansion(f, eps_data_f, prec)
    F0 = [0] * qexpm.Valuation().sage() + [o.sage() for o in qexpm.ElementToSequence()]
    K = F0[-1].parent()
    a = K.gen()
    phi = find_embeddings(K,base_ring)[0]
    F = [phi(o) for o in F0]
    eps_f = magma.get_character(f, eps_data_f).ValueList().sage()
    eps_f_full = magma.get_character_full(f, eps_data_f).ValueList().sage()
    N = len(eps_f)
    Geps = DirichletGroup(N, base_ring = K)

    eps_f = Geps([eps_f[i - 1] for i in Geps.unit_gens()])
    Geps_full = DirichletGroup(N)
    psi = eps_f_full[0].parent().embeddings(Geps_full.base_ring())[0]
    eps_f_full = Geps_full([psi(eps_f_full[i - 1]) for i in Geps_full.unit_gens()])

    if a == 1:
        sigma = lambda x:x
    else:
        try:
            sigma = next((s for s in K.automorphisms() if s(a)*a == 1))
        except StopIteration:
            raise NotImplementedError
    G = [phi(sigma(o)) for o in F0]
    eps_g = eps_f**-1
    eps_g_full = eps_f_full**-1
    F = ModFormqExp(F, base_ring, weight=1, level = N, character = eps_f, character_full = eps_f_full)
    G = ModFormqExp(G, base_ring, weight=1, level = N, character = eps_g, character_full = eps_g_full)
    return F, G
Example #10
0
def BigArithGroup(p,
                  quat_data,
                  level,
                  base=None,
                  grouptype=None,
                  seed=None,
                  use_sage_db=False,
                  outfile=None,
                  magma=None,
                  timeout=0,
                  logfile=None,
                  use_shapiro=True,
                  character=None,
                  nscartan=None,
                  matrix_group=False):
    if magma is None:
        from sage.interfaces.magma import Magma
        magma = Magma(logfile=logfile)
        page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec'
        if seed is not None:
            magma.eval('SetSeed(%s)' % seed)
        magma.attach_spec(page_path)
    magma.eval('Page_initialized := true')
    a, b = None, None
    if logfile is not None:
        magma.eval('SetVerbose("Kleinian",2)')
    try:
        discriminant = ZZ(quat_data)
        if base is not None:
            assert base == QQ
        else:
            base = QQ
        fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level
                                                )  # Fix this name
    except TypeError:
        a, b = quat_data
        if base is None:
            base = a.parent()
        discriminant = QuaternionAlgebra(base, a, b).discriminant()
        fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level
                                                )  # Fix this name
    if base != QQ:
        use_sage_db = False  # This is not implemented yet

    if grouptype is None:
        if base == QQ:
            grouptype = 'PSL2'
        else:
            grouptype = 'PGL2'

    if use_sage_db:
        try:
            newobj = db(fname)
        except IOError:
            verbose('Group not found in database. Computing from scratch.')
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         level,
                                         seed,
                                         outfile=outfile,
                                         grouptype=grouptype,
                                         magma=magma,
                                         timeout=timeout,
                                         use_shapiro=use_shapiro,
                                         character=character,
                                         nscartan=nscartan,
                                         matrix_group=matrix_group)
            newobj.save_to_db()
    else:
        if a is not None:
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         abtuple=(a, b),
                                         level=level,
                                         seed=seed,
                                         outfile=outfile,
                                         grouptype=grouptype,
                                         magma=magma,
                                         timeout=timeout,
                                         use_shapiro=use_shapiro,
                                         character=character,
                                         nscartan=nscartan,
                                         matrix_group=matrix_group)
        else:
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         level=level,
                                         seed=seed,
                                         outfile=outfile,
                                         grouptype=grouptype,
                                         magma=magma,
                                         timeout=timeout,
                                         use_shapiro=use_shapiro,
                                         character=character,
                                         nscartan=nscartan,
                                         matrix_group=matrix_group)
    return newobj
Example #11
0
def darmon_point(P,
                 E,
                 beta,
                 prec,
                 ramification_at_infinity=None,
                 input_data=None,
                 magma=None,
                 working_prec=None,
                 recognize_point=True,
                 **kwargs):
    r'''

    EXAMPLES:

    We first need to import the module::

    sage: from darmonpoints.darmonpoints import darmon_point

    A first example (Stark--Heegner point)::

    sage: from darmonpoints.darmonpoints import darmon_point
    sage: darmon_point(7,EllipticCurve('35a1'),41,20, cohomological=False, use_magma=False, use_ps_dists = True)
    Starting computation of the Darmon point
    ...
    (-70*alpha + 449 : 2100*alpha - 13444 : 1)

    A quaternionic (Greenberg) point::

    sage: darmon_point(13,EllipticCurve('78a1'),5,20) # long time # optional - magma

    A Darmon point over a cubic (1,1) field::

    sage: F.<r> = NumberField(x^3 - x^2 - x + 2)
    sage: E = EllipticCurve([-r -1, -r, -r - 1,-r - 1, 0])
    sage: N = E.conductor()
    sage: P = F.ideal(r^2 - 2*r - 1)
    sage: beta = -3*r^2 + 9*r - 6
    sage: darmon_point(P,E,beta,20) # long time # optional - magma

    '''
    # global G, Coh, phiE, Phi, dK, J, J1, cycleGn, nn, Jlist

    config = ConfigParser.ConfigParser()
    config.read('config.ini')
    param_dict = config_section_map(config, 'General')
    param_dict.update(config_section_map(config, 'DarmonPoint'))
    param_dict.update(kwargs)
    param = Bunch(**param_dict)

    # Get general parameters
    outfile = param.get('outfile')
    use_ps_dists = param.get('use_ps_dists', False)
    use_shapiro = param.get('use_shapiro', False)
    use_sage_db = param.get('use_sage_db', False)
    magma_seed = param.get('magma_seed', 1515316)
    parallelize = param.get('parallelize', False)
    Up_method = param.get('up_method', 'naive')
    use_magma = param.get('use_magma', True)
    progress_bar = param.get('progress_bar', True)
    sign_at_infinity = param.get('sign_at_infinity', ZZ(1))

    # Get darmon_point specific parameters
    idx_orientation = param.get('idx_orientation')
    idx_embedding = param.get('idx_embedding', 0)
    algorithm = param.get('algorithm')
    quaternionic = param.get('quaternionic')
    cohomological = param.get('cohomological', True)

    if Up_method == "bigmatrix" and use_shapiro == True:
        import warnings
        warnings.warn(
            'Use of "bigmatrix" for Up iteration is incompatible with Shapiro Lemma trick. Using "naive" method for Up.'
        )
        Up_method = 'naive'

    if working_prec is None:
        working_prec = max([2 * prec + 10, 30])

    if use_magma:
        page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec'
        if magma is None:
            from sage.interfaces.magma import Magma
            magma = Magma()
            quit_when_done = True
        else:
            quit_when_done = False
        magma.attach_spec(page_path)
    else:
        quit_when_done = False

    sys.setrecursionlimit(10**6)

    F = E.base_ring()
    beta = F(beta)
    DB, Np, Ncartan = get_heegner_params(P, E, beta)
    if quaternionic is None:
        quaternionic = (DB != 1)
    if cohomological is None:
        cohomological = quaternionic
    if quaternionic and not cohomological:
        raise ValueError(
            "Need cohomological algorithm when dealing with quaternions")
    if use_ps_dists is None:
        use_ps_dists = False if cohomological else True
    try:
        p = ZZ(P)
    except TypeError:
        p = ZZ(P.norm())
    if not p.is_prime():
        raise ValueError('P (= %s) should be a prime, of inertia degree 1' % P)

    if F == QQ:
        dK = ZZ(beta)
        extra_conductor_sq = dK / fundamental_discriminant(dK)
        assert ZZ(extra_conductor_sq).is_square()
        extra_conductor = extra_conductor_sq.sqrt()
        dK = dK / extra_conductor_sq
        assert dK == fundamental_discriminant(dK)
        if dK % 4 == 0:
            dK = ZZ(dK / 4)
        beta = dK
    else:
        dK = beta

    # Compute the completion of K at p
    x = QQ['x'].gen()
    K = F.extension(x * x - dK, names='alpha')
    if F == QQ:
        dK = K.discriminant()
    else:
        dK = K.relative_discriminant()

    hK = K.class_number()

    sgninfty = 'plus' if sign_at_infinity == 1 else 'minus'
    if hasattr(E, 'cremona_label'):
        Ename = E.cremona_label()
    elif hasattr(E, 'ainvs'):
        Ename = E.ainvs()
    else:
        Ename = 'unknown'
    fname = 'moments_%s_%s_%s_%s.sobj' % (P, Ename, sgninfty, prec)

    if use_sage_db:
        print("Moments will be stored in database as %s" % (fname))

    if outfile == 'log':
        outfile = '%s_%s_%s_%s_%s_%s.log' % (
            P, Ename, dK, sgninfty, prec,
            datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
        outfile = outfile.replace('/', 'div')
        outfile = '/tmp/darmonpoint_' + outfile

    fwrite("Starting computation of the Darmon point", outfile)
    fwrite('D_B = %s  %s' % (DB, factor(DB)), outfile)
    fwrite('Np = %s' % Np, outfile)
    if Ncartan is not None:
        fwrite('Ncartan = %s' % Ncartan, outfile)
    fwrite('dK = %s (class number = %s)' % (dK, hK), outfile)
    fwrite('Calculation with p = %s and prec = %s' % (P, prec), outfile)
    fwrite('Elliptic curve %s: %s' % (Ename, E), outfile)
    if outfile is not None:
        print("Partial results will be saved in %s" % outfile)

    if input_data is None:
        if cohomological:
            # Define the S-arithmetic group
            if F != QQ and ramification_at_infinity is None:
                if F.signature()[0] > 1:
                    if F.signature()[1] == 1:
                        ramification_at_infinity = F.real_places(
                            prec=Infinity)  # Totally 'definite'
                    else:
                        raise ValueError(
                            'Please specify the ramification at infinity')
                elif F.signature()[0] == 1:
                    if len(F.ideal(DB).factor()) % 2 == 0:
                        ramification_at_infinity = []  # Split at infinity
                    else:
                        ramification_at_infinity = F.real_places(
                            prec=Infinity)  # Ramified at infinity
                else:
                    ramification_at_infinity = None
            if F == QQ:
                abtuple = QuaternionAlgebra(DB).invariants()
            else:
                abtuple = quaternion_algebra_invariants_from_ramification(
                    F, DB, ramification_at_infinity, magma=magma)

            G = BigArithGroup(P,
                              abtuple,
                              Np,
                              base=F,
                              outfile=outfile,
                              seed=magma_seed,
                              use_sage_db=use_sage_db,
                              magma=magma,
                              use_shapiro=use_shapiro,
                              nscartan=Ncartan)

            # Define the cycle ( in H_1(G,Div^0 Hp) )
            Coh = ArithCoh(G)
            while True:
                try:
                    cycleGn, nn, ell = construct_homology_cycle(
                        p,
                        G.Gn,
                        beta,
                        working_prec,
                        lambda q: Coh.hecke_matrix(q).minpoly(),
                        outfile=outfile,
                        elliptic_curve=E)
                    break
                except PrecisionError:
                    working_prec *= 2
                    verbose(
                        'Encountered precision error, trying with higher precision (= %s)'
                        % working_prec)
                except ValueError:
                    fwrite(
                        'ValueError occurred when constructing homology cycle. Returning the S-arithmetic group.',
                        outfile)
                    if quit_when_done:
                        magma.quit()
                    return G
                except AssertionError as e:
                    fwrite(
                        'Assertion occurred when constructing homology cycle. Returning the S-arithmetic group.',
                        outfile)
                    fwrite('%s' % str(e), outfile)
                    if quit_when_done:
                        magma.quit()
                    return G
            eisenstein_constant = -ZZ(E.reduction(ell).count_points())
            fwrite(
                'r = %s, so a_r(E) - r - 1 = %s' % (ell, eisenstein_constant),
                outfile)
            fwrite('exponent = %s' % nn, outfile)
            phiE = Coh.get_cocycle_from_elliptic_curve(E,
                                                       sign=sign_at_infinity)
            if hasattr(E, 'ap'):
                sign_ap = E.ap(P)
            else:
                try:
                    sign_ap = ZZ(P.norm() + 1 - E.reduction(P).count_points())
                except ValueError:
                    sign_ap = ZZ(P.norm() + 1 - Curve(E).change_ring(
                        P.residue_field()).count_points(1)[0])

            Phi = get_overconvergent_class_quaternionic(
                P,
                phiE,
                G,
                prec,
                sign_at_infinity,
                sign_ap,
                use_ps_dists=use_ps_dists,
                use_sage_db=use_sage_db,
                parallelize=parallelize,
                method=Up_method,
                progress_bar=progress_bar,
                Ename=Ename)
            # Integration with moments
            tot_time = walltime()
            J = integrate_H1(G,
                             cycleGn,
                             Phi,
                             1,
                             method='moments',
                             prec=working_prec,
                             parallelize=parallelize,
                             twist=True,
                             progress_bar=progress_bar)
            verbose('integration tot_time = %s' % walltime(tot_time))
            if use_sage_db:
                G.save_to_db()
        else:  # not cohomological
            nn = 1
            eisenstein_constant = 1
            if algorithm is None:
                if Np == 1:
                    algorithm = 'darmon_pollack'
                else:
                    algorithm = 'guitart_masdeu'
            w = K.maximal_order().ring_generators()[0]
            r0, r1 = w.coordinates_in_terms_of_powers()(K.gen())
            QQp = Qp(p, working_prec)
            Cp = QQp.extension(w.minpoly().change_ring(QQp), names='g')
            v0 = K.hom([r0 + r1 * Cp.gen()])

            # Optimal embeddings of level one
            fwrite("Computing optimal embeddings of level one...", outfile)
            Wlist = find_optimal_embeddings(K,
                                            use_magma=use_magma,
                                            extra_conductor=extra_conductor)
            fwrite("Found %s such embeddings." % len(Wlist), outfile)
            if idx_embedding is not None:
                if idx_embedding >= len(Wlist):
                    fwrite(
                        'There are not enough embeddings. Taking the index modulo %s'
                        % len(Wlist), outfile)
                    idx_embedding = idx_embedding % len(Wlist)
                fwrite('Taking only embedding number %s' % (idx_embedding),
                       outfile)
                Wlist = [Wlist[idx_embedding]]

            # Find the orientations
            orients = K.maximal_order().ring_generators()[0].minpoly().roots(
                Zmod(Np), multiplicities=False)
            fwrite("Possible orientations: %s" % orients, outfile)
            if len(Wlist) == 1 or idx_orientation == -1:
                fwrite("Using all orientations, since hK = 1", outfile)
                chosen_orientation = None
            else:
                fwrite("Using orientation = %s" % orients[idx_orientation],
                       outfile)
                chosen_orientation = orients[idx_orientation]

            emblist = []
            for i, W in enumerate(Wlist):
                tau, gtau, sign, limits = find_tau0_and_gtau(
                    v0,
                    Np,
                    W,
                    algorithm=algorithm,
                    orientation=chosen_orientation,
                    extra_conductor=extra_conductor)
                fwrite(
                    'n_evals = %s' % sum(
                        (num_evals(t1, t2) for t1, t2 in limits)), outfile)
                emblist.append((tau, gtau, sign, limits))

            # Get the cohomology class from E
            Phi = get_overconvergent_class_matrices(P,
                                                    E,
                                                    prec,
                                                    sign_at_infinity,
                                                    use_ps_dists=use_ps_dists,
                                                    use_sage_db=use_sage_db,
                                                    parallelize=parallelize,
                                                    progress_bar=progress_bar)

            J = 1
            Jlist = []
            for i, emb in enumerate(emblist):
                fwrite(
                    "Computing %s-th period, attached to the embedding: %s" %
                    (i, Wlist[i].list()), outfile)
                tau, gtau, sign, limits = emb
                n_evals = sum((num_evals(t1, t2) for t1, t2 in limits))
                fwrite(
                    "Computing one period...(total of %s evaluations)" %
                    n_evals, outfile)
                newJ = prod((double_integral_zero_infty(Phi, t1, t2)
                             for t1, t2 in limits))**ZZ(sign)
                Jlist.append(newJ)
                J *= newJ
    else:  # input_data is not None
        Phi, J = input_data[1:3]
    fwrite('Integral done. Now trying to recognize the point', outfile)
    fwrite('J_psi = %s' % J, outfile)
    fwrite('g belongs to %s' % J.parent(), outfile)
    #Try to recognize a generator
    if quaternionic:
        local_embedding = G.base_ring_local_embedding(working_prec)
        twopowlist = [
            4, 3, 2, 1,
            QQ(1) / 2,
            QQ(3) / 2,
            QQ(1) / 3,
            QQ(2) / 3,
            QQ(1) / 4,
            QQ(3) / 4,
            QQ(5) / 2,
            QQ(4) / 3
        ]
    else:
        local_embedding = Qp(p, working_prec)
        twopowlist = [
            4, 3, 2, 1,
            QQ(1) / 2,
            QQ(3) / 2,
            QQ(1) / 3,
            QQ(2) / 3,
            QQ(1) / 4,
            QQ(3) / 4,
            QQ(5) / 2,
            QQ(4) / 3
        ]

    known_multiple = QQ(
        nn * eisenstein_constant
    )  # It seems that we are not getting it with present algorithm.
    while known_multiple % p == 0:
        known_multiple = ZZ(known_multiple / p)

    if not recognize_point:
        fwrite('known_multiple = %s' % known_multiple, outfile)
        if quit_when_done:
            magma.quit()
        return J, Jlist

    candidate, twopow, J1 = recognize_J(E,
                                        J,
                                        K,
                                        local_embedding=local_embedding,
                                        known_multiple=known_multiple,
                                        twopowlist=twopowlist,
                                        prec=prec,
                                        outfile=outfile)

    if candidate is not None:
        HCF = K.hilbert_class_field(names='r1') if hK > 1 else K
        if hK == 1:
            try:
                verbose('candidate = %s' % candidate)
                Ptsmall = E.change_ring(HCF)(candidate)
                fwrite('twopow = %s' % twopow, outfile)
                fwrite(
                    'Computed point:  %s * %s * %s' %
                    (twopow, known_multiple, Ptsmall), outfile)
                fwrite('(first factor is not understood, second factor is)',
                       outfile)
                fwrite(
                    '(r satisfies %s = 0)' %
                    (Ptsmall[0].parent().gen().minpoly()), outfile)
                fwrite('================================================',
                       outfile)
                if quit_when_done:
                    magma.quit()
                return Ptsmall
            except (TypeError, ValueError):
                verbose("Could not recognize the point.")
        else:
            verbose('candidate = %s' % candidate)
            fwrite('twopow = %s' % twopow, outfile)
            fwrite(
                'Computed point:  %s * %s * (x,y)' % (twopow, known_multiple),
                outfile)
            fwrite('(first factor is not understood, second factor is)',
                   outfile)
            try:
                pols = [HCF(c).relative_minpoly() for c in candidate[:2]]
            except AttributeError:
                pols = [HCF(c).minpoly() for c in candidate[:2]]
            fwrite('Where x satisfies %s' % pols[0], outfile)
            fwrite('and y satisfies %s' % pols[1], outfile)
            fwrite('================================================', outfile)
            if quit_when_done:
                magma.quit()
            return candidate
    else:
        fwrite('================================================', outfile)
        if quit_when_done:
            magma.quit()
        return []
Example #12
0
def darmon_point(P, E, beta, prec, ramification_at_infinity = None, input_data = None, magma = None, working_prec = None, **kwargs):
    r'''

    EXAMPLES:

    We first need to import the module::

    sage: from darmonpoints.darmonpoints import darmon_point

    A first example (Stark--Heegner point)::

    sage: from darmonpoints.darmonpoints import darmon_point
    sage: darmon_point(7,EllipticCurve('35a1'),41,20, cohomological=False, use_magma=False, use_ps_dists = True)
    Starting computation of the Darmon point
    ...
    (-70*alpha + 449 : 2100*alpha - 13444 : 1)

    A quaternionic (Greenberg) point::

    sage: darmon_point(13,EllipticCurve('78a1'),5,20) # long time # optional - magma

    A Darmon point over a cubic (1,1) field::

    sage: F.<r> = NumberField(x^3 - x^2 - x + 2)
    sage: E = EllipticCurve([-r -1, -r, -r - 1,-r - 1, 0])
    sage: N = E.conductor()
    sage: P = F.ideal(r^2 - 2*r - 1)
    sage: beta = -3*r^2 + 9*r - 6
    sage: darmon_point(P,E,beta,20) # long time # optional - magma

    '''
    # global G, Coh, phiE, Phi, dK, J, J1, cycleGn, nn, Jlist

    config = ConfigParser.ConfigParser()
    config.read('config.ini')
    param_dict = config_section_map(config, 'General')
    param_dict.update(config_section_map(config, 'DarmonPoint'))
    param_dict.update(kwargs)
    param = Bunch(**param_dict)

    # Get general parameters
    outfile = param.get('outfile')
    use_ps_dists = param.get('use_ps_dists',False)
    use_shapiro = param.get('use_shapiro',True)
    use_sage_db = param.get('use_sage_db',False)
    magma_seed = param.get('magma_seed',1515316)
    parallelize = param.get('parallelize',False)
    Up_method = param.get('up_method','naive')
    use_magma = param.get('use_magma',True)
    progress_bar = param.get('progress_bar',True)
    sign_at_infinity = param.get('sign_at_infinity',ZZ(1))

    # Get darmon_point specific parameters
    idx_orientation = param.get('idx_orientation')
    idx_embedding = param.get('idx_embedding',0)
    algorithm = param.get('algorithm')
    quaternionic = param.get('quaternionic')
    cohomological = param.get('cohomological',True)

    if Up_method == "bigmatrix" and use_shapiro == True:
        import warnings
        warnings.warn('Use of "bigmatrix" for Up iteration is incompatible with Shapiro Lemma trick. Using "naive" method for Up.')
        Up_method = 'naive'

    if working_prec is None:
        working_prec = max([2 * prec + 10, 30])

    if use_magma:
        page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec'
        if magma is None:
            from sage.interfaces.magma import Magma
            magma = Magma()
            quit_when_done = True
        else:
            quit_when_done = False
        magma.attach_spec(page_path)
    else:
        quit_when_done = False

    sys.setrecursionlimit(10**6)

    F = E.base_ring()
    beta = F(beta)
    DB,Np,Ncartan = get_heegner_params(P,E,beta)
    if quaternionic is None:
        quaternionic = ( DB != 1 )
    if cohomological is None:
        cohomological = quaternionic
    if quaternionic and not cohomological:
        raise ValueError("Need cohomological algorithm when dealing with quaternions")
    if use_ps_dists is None:
        use_ps_dists = False if cohomological else True
    try:
        p = ZZ(P)
    except TypeError:
        p = ZZ(P.norm())
    if not p.is_prime():
        raise ValueError,'P (= %s) should be a prime, of inertia degree 1'%P

    if F == QQ:
        dK = ZZ(beta)
        extra_conductor_sq = dK/fundamental_discriminant(dK)
        assert ZZ(extra_conductor_sq).is_square()
        extra_conductor = extra_conductor_sq.sqrt()
        dK = dK / extra_conductor_sq
        assert dK == fundamental_discriminant(dK)
        if dK % 4 == 0:
            dK = ZZ(dK/4)
        beta = dK
    else:
        dK = beta

    # Compute the completion of K at p
    x = QQ['x'].gen()
    K = F.extension(x*x - dK,names = 'alpha')
    if F == QQ:
        dK = K.discriminant()
    else:
        dK = K.relative_discriminant()

    hK = K.class_number()

    sgninfty = 'plus' if sign_at_infinity == 1 else 'minus'
    if hasattr(E,'cremona_label'):
        Ename = E.cremona_label()
    elif hasattr(E,'ainvs'):
        Ename = E.ainvs()
    else:
        Ename = 'unknown'
    fname = 'moments_%s_%s_%s_%s.sobj'%(P,Ename,sgninfty,prec)

    if use_sage_db:
        print("Moments will be stored in database as %s"%(fname))

    if outfile == 'log':
        outfile = '%s_%s_%s_%s_%s_%s.log'%(P,Ename,dK,sgninfty,prec,datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
        outfile = outfile.replace('/','div')
        outfile = '/tmp/darmonpoint_' + outfile

    fwrite("Starting computation of the Darmon point",outfile)
    fwrite('D_B = %s  %s'%(DB,factor(DB)),outfile)
    fwrite('Np = %s'%Np,outfile)
    if Ncartan is not None:
        fwrite('Ncartan = %s'%Ncartan,outfile)
    fwrite('dK = %s (class number = %s)'%(dK,hK),outfile)
    fwrite('Calculation with p = %s and prec = %s'%(P,prec),outfile)
    fwrite('Elliptic curve %s: %s'%(Ename,E),outfile)
    if outfile is not None:
        print("Partial results will be saved in %s"%outfile)

    if input_data is None:
        if cohomological:
            # Define the S-arithmetic group
            if F != QQ and ramification_at_infinity is None:
                if F.signature()[0] > 1:
                    if F.signature()[1] == 1:
                        ramification_at_infinity = F.real_places(prec = Infinity) # Totally 'definite'
                    else:
                        raise ValueError,'Please specify the ramification at infinity'
                elif F.signature()[0] == 1:
                    if len(F.ideal(DB).factor()) % 2 == 0:
                        ramification_at_infinity = [] # Split at infinity
                    else:
                        ramification_at_infinity = F.real_places(prec = Infinity) # Ramified at infinity
                else:
                    ramification_at_infinity = None
            if F == QQ:
                abtuple = QuaternionAlgebra(DB).invariants()
            else:
                abtuple = quaternion_algebra_invariants_from_ramification(F, DB, ramification_at_infinity)

            G = BigArithGroup(P,abtuple,Np,base = F,outfile = outfile,seed = magma_seed,use_sage_db = use_sage_db,magma = magma, use_shapiro = use_shapiro, nscartan=Ncartan)

            # Define the cycle ( in H_1(G,Div^0 Hp) )
            Coh = ArithCoh(G)
            while True:
                try:
                    cycleGn,nn,ell = construct_homology_cycle(G,beta,working_prec,lambda q: Coh.hecke_matrix(q).minpoly(), outfile = outfile, elliptic_curve = E)
                    break
                except PrecisionError:
                    working_prec *= 2
                    verbose('Encountered precision error, trying with higher precision (= %s)'%working_prec)
                except ValueError:
                    fwrite('ValueError occurred when constructing homology cycle. Returning the S-arithmetic group.', outfile)
                    if quit_when_done:
                        magma.quit()
                    return G
                except AssertionError as e:
                    fwrite('Assertion occurred when constructing homology cycle. Returning the S-arithmetic group.', outfile)
                    fwrite('%s'%str(e), outfile)
                    if quit_when_done:
                        magma.quit()
                    return G
            eisenstein_constant = -ZZ(E.reduction(ell).count_points())
            fwrite('r = %s, so a_r(E) - r - 1 = %s'%(ell,eisenstein_constant), outfile)
            fwrite('exponent = %s'%nn, outfile)
            phiE = Coh.get_cocycle_from_elliptic_curve(E, sign = sign_at_infinity)
            if hasattr(E,'ap'):
                sign_ap = E.ap(P)
            else:
                try:
                    sign_ap = ZZ(P.norm() + 1 - E.reduction(P).count_points())
                except ValueError:
                    sign_ap = ZZ(P.norm() + 1 - Curve(E).change_ring(P.residue_field()).count_points(1)[0])

            Phi = get_overconvergent_class_quaternionic(P,phiE,G,prec,sign_at_infinity,sign_ap,use_ps_dists = use_ps_dists,use_sage_db = use_sage_db,parallelize = parallelize,method = Up_method, progress_bar = progress_bar,Ename = Ename)
            # Integration with moments
            tot_time = walltime()
            J = integrate_H1(G,cycleGn,Phi,1,method = 'moments',prec = working_prec,parallelize = parallelize,twist = True,progress_bar = progress_bar)
            verbose('integration tot_time = %s'%walltime(tot_time))
            if use_sage_db:
                G.save_to_db()
        else: # not cohomological
            nn = 1
            eisenstein_constant = 1
            if algorithm is None:
                if Np == 1:
                    algorithm = 'darmon_pollack'
                else:
                    algorithm = 'guitart_masdeu'
            w = K.maximal_order().ring_generators()[0]
            r0,r1 = w.coordinates_in_terms_of_powers()(K.gen())
            QQp = Qp(p,working_prec)
            Cp = QQp.extension(w.minpoly().change_ring(QQp),names = 'g')
            v0 = K.hom([r0 + r1 * Cp.gen()])

            # Optimal embeddings of level one
            fwrite("Computing optimal embeddings of level one...", outfile)
            Wlist = find_optimal_embeddings(K,use_magma = use_magma, extra_conductor = extra_conductor)
            fwrite("Found %s such embeddings."%len(Wlist), outfile)
            if idx_embedding is not None:
                if idx_embedding >= len(Wlist):
                    fwrite('There are not enough embeddings. Taking the index modulo %s'%len(Wlist), outfile)
                    idx_embedding = idx_embedding % len(Wlist)
                fwrite('Taking only embedding number %s'%(idx_embedding), outfile)
                Wlist = [Wlist[idx_embedding]]

            # Find the orientations
            orients = K.maximal_order().ring_generators()[0].minpoly().roots(Zmod(Np),multiplicities = False)
            fwrite("Possible orientations: %s"%orients, outfile)
            if len(Wlist) == 1 or idx_orientation == -1:
                fwrite("Using all orientations, since hK = 1", outfile)
                chosen_orientation = None
            else:
                fwrite("Using orientation = %s"%orients[idx_orientation], outfile)
                chosen_orientation = orients[idx_orientation]

            emblist = []
            for i,W in enumerate(Wlist):
                tau, gtau,sign,limits = find_tau0_and_gtau(v0,Np,W,algorithm = algorithm,orientation = chosen_orientation,extra_conductor = extra_conductor)
                fwrite('n_evals = %s'%sum((num_evals(t1,t2) for t1,t2 in limits)), outfile)
                emblist.append((tau,gtau,sign,limits))

            # Get the cohomology class from E
            Phi = get_overconvergent_class_matrices(P,E,prec,sign_at_infinity,use_ps_dists = use_ps_dists,use_sage_db = use_sage_db,parallelize = parallelize,progress_bar = progress_bar)

            J = 1
            Jlist = []
            for i,emb in enumerate(emblist):
                fwrite("Computing %s-th period, attached to the embedding: %s"%(i,Wlist[i].list()), outfile)
                tau, gtau,sign,limits = emb
                n_evals = sum((num_evals(t1,t2) for t1,t2 in limits))
                fwrite("Computing one period...(total of %s evaluations)"%n_evals, outfile)
                newJ = prod((double_integral_zero_infty(Phi,t1,t2) for t1,t2 in limits))**ZZ(sign)
                Jlist.append(newJ)
                J *= newJ
    else: # input_data is not None
        Phi,J = input_data[1:3]
    fwrite('Integral done. Now trying to recognize the point', outfile)
    fwrite('J_psi = %s'%J,outfile)
    fwrite('g belongs to %s'%J.parent(),outfile)
    #Try to recognize a generator
    if quaternionic:
        local_embedding = G.base_ring_local_embedding(working_prec)
        twopowlist = [4, 3, 2, 1, QQ(1)/2, QQ(3)/2, QQ(1)/3, QQ(2)/3, QQ(1)/4, QQ(3)/4, QQ(5)/2, QQ(4)/3]
    else:
        local_embedding = Qp(p,working_prec)
        twopowlist = [4, 3, 2, 1, QQ(1)/2, QQ(3)/2, QQ(1)/3, QQ(2)/3, QQ(1)/4, QQ(3)/4, QQ(5)/2, QQ(4)/3]

    known_multiple = QQ(nn * eisenstein_constant) # It seems that we are not getting it with present algorithm.
    while known_multiple % p == 0:
        known_multiple = ZZ(known_multiple / p)

    candidate,twopow,J1 = recognize_J(E,J,K,local_embedding = local_embedding,known_multiple = known_multiple,twopowlist = twopowlist,prec = prec, outfile = outfile)

    if candidate is not None:
        HCF = K.hilbert_class_field(names = 'r1') if hK > 1 else K
        if hK == 1:
            try:
                verbose('candidate = %s'%candidate)
                Ptsmall = E.change_ring(HCF)(candidate)
                fwrite('twopow = %s'%twopow,outfile)
                fwrite('Computed point:  %s * %s * %s'%(twopow,known_multiple,Ptsmall),outfile)
                fwrite('(first factor is not understood, second factor is)',outfile)
                fwrite('(r satisfies %s = 0)'%(Ptsmall[0].parent().gen().minpoly()),outfile)
                fwrite('================================================',outfile)
                if quit_when_done:
                    magma.quit()
                return Ptsmall
            except (TypeError,ValueError):
                verbose("Could not recognize the point.")
        else:
            verbose('candidate = %s'%candidate)
            fwrite('twopow = %s'%twopow,outfile)
            fwrite('Computed point:  %s * %s * (x,y)'%(twopow,known_multiple),outfile)
            fwrite('(first factor is not understood, second factor is)',outfile)
            try:
                pols = [HCF(c).relative_minpoly() for c in candidate[:2]]
            except AttributeError:
                pols = [HCF(c).minpoly() for c in candidate[:2]]
            fwrite('Where x satisfies %s'%pols[0],outfile)
            fwrite('and y satisfies %s'%pols[1],outfile)
            fwrite('================================================',outfile)
            if quit_when_done:
                magma.quit()
            return candidate
    else:
        fwrite('================================================',outfile)
        if quit_when_done:
            magma.quit()
        return []
Example #13
0
def benchmark(pbound = [3, 2**10], nbound = [3, 2**8], cbound = [1, Infinity], obound = [1, Infinity], loops = 10, tloop = Infinity, tmax = Infinity, prime = False, even = False, check = False, fname = None, write = False, overwrite = False, verbose = True, skip_pari = False, skip_magma = False, skip_rains = False, skip_kummer = False):
    if write:
        mode = 'w' if overwrite else 'a'
        f = open(fname, mode, 0)
    else:
        f = sys.stdout
    pmin, pmax = pbound
    nmin, nmax = nbound
    omin, omax = obound
    cmin, cmax = cbound
    M = Magma()
    for p in xrange(pmin, pmax):
        p = ZZ(p)
        if not p.is_prime():
            continue
        for n in xrange(nmin, nmax):
            n = ZZ(n)
            if (prime == 1 and not is_prime(n)) or (prime == 2 and not is_prime_power(n)):
                continue
            if n < 2:
                continue
            if n % p == 0:
                continue
            if (not even) and (n % 2 == 0):
                continue
            o, G = find_root_order(p, [n, n], n, verbose=False)
            m = G[0][0].parent().order()
            c = Mod(p,n).multiplicative_order()
            if verbose:
                sys.stdout.write("\r"+" "*79)
                print("\rp = {}, n = {}, (o = {}, c = {})".format(p, n, o, c))
            if verbose:
                t = mytime()
                sys.stdout.write("Constructing fields ({})".format(time.strftime("%c")))
                sys.stdout.flush()
            q = p**n
            k = GF(q, name='z')
            k_rand = GF(q, modulus='random', name='z')
            k_flint = GF_flint(p, k.modulus(), name='z')
            if verbose > 1:
                sys.stdout.write("\ntotal: {}s\n".format(mytime(t)))
                sys.stdout.flush()
            # Magma
            if verbose:
                sys.stdout.write("\r"+" "*79)
                sys.stdout.write("\rMagma ({})".format(time.strftime("%c")))
                sys.stdout.flush()
            tloops = 0
            for l in xrange(loops):
                if skip_magma:
                    break
                if (o > omax) or (o == p):
                    break
                # let's assume that launching a new Magma instance is cheaper
                # than computing random irreducible polynomials
                try:
                    M._start()
                except OSError as err:
                    # but it can also cause fork issues...
                    # let's accept this
                    # and fail as the situation will only worsen
                    # unless it is "just" a memory issue
                    # which should be mitigated by COW but is not
                    #print(err)
                    if err.errno == errno.ENOMEM:
                        break
                    else:
                        raise
                try:
                    k_magma = M(k)
                    k_rand_magma = M(k_rand)
                    if tloop is not Infinity:
                        alarm(tloop)
                    t = mytime()
                    k_magma.Embed(k_rand_magma, nvals=0)
                    #M._eval_line("Embed(k_magma, k_rand_magma);", wait_for_prompt=False)
                    tloops += mytime(t)
                except TypeError:
                    # sage/magma interface sometimes gets confused
                    pass
                except (KeyboardInterrupt, AlarmInterrupt):
                    # sage interface eats KeyboardInterrupt
                    # and AlarmInterrupt derives from it
                    tloops = 0
                    break
                finally:
                    if tloop is not Infinity:
                        cancel_alarm()
                    M.quit()
                    # sage pexpect interface leaves zombies around
                    try:
                        while os.waitpid(-1, os.WNOHANG)[0]:
                            pass
                    # but sometimes every child is already buried
                    # and we get an ECHILD error...
                    except OSError:
                        pass
                if tloops > tmax:
                    break
            tmagma = tloops / (l+1)
            if verbose > 1:
                sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(tloops, tloops/(l+1)))
                sys.stdout.flush()
            # Rains algorithms
            if verbose:
                sys.stdout.write("\r"+" "*79)
                sys.stdout.write("\rCyclotomic Rains ({})".format(time.strftime("%c")))
                sys.stdout.flush()
            trains = []
            tloops = 0
            for l in xrange(loops):
                if skip_rains:
                    break
                if (o > omax) or (o == p):
                    break
                try:
                    if tloop is not Infinity:
                        alarm(tloop)
                    t = mytime()
                    a, b = find_gens_cyclorains(k_flint, k_flint, use_lucas = False)
                    tloops += mytime(t)
                except (KeyboardInterrupt, AlarmInterrupt):
                    tloops = 0
                    break
                finally:
                    if tloop is not Infinity:
                        cancel_alarm()
                if check and (l == 0 or check > 1):
                    g = a.minpoly()
                    if g.degree() != n:
                        raise RuntimeError("wrong degree")
                    if g != b.minpoly():
                        raise RuntimeError("different minpolys")
                if tloops > tmax:
                    break
            trains.append(tloops / (l+1))
            if verbose > 1:
                sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(tloops, tloops/(l+1)))
                sys.stdout.flush()
            # Conic Rains
            if verbose:
                sys.stdout.write("\r"+" "*79)
                sys.stdout.write("\rConic Rains ({})".format(time.strftime("%c")))
                sys.stdout.flush()
            tloops = 0
            for l in xrange(loops):
                if skip_rains:
                    break
                if (o != 2) or (o > omax) or (o == p):
                    break
                try:
                    if tloop is not Infinity:
                        alarm(tloop)
                    t = mytime()
                    a, b = find_gens_cyclorains(k_flint, k_flint, use_lucas = True)
                    tloops += mytime(t)
                except (KeyboardInterrupt, AlarmInterrupt):
                    tloops = 0
                    break
                finally:
                    if tloop is not Infinity:
                        cancel_alarm()
                if check and (l == 0 or check > 1):
                    g = a.minpoly()
                    if g.degree() != n:
                        raise RuntimeError("wrong degree")
                    if g != b.minpoly():
                        raise RuntimeError("different minpolys")
                if tloops > tmax:
                    break
            trains.append(tloops / (l+1))
            if verbose > 1:
                sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(tloops, tloops/(l+1)))
                sys.stdout.flush()
            # Elliptic Rains
            if verbose:
                sys.stdout.write("\r"+" "*79)
                sys.stdout.write("\rElliptic Rains ({})".format(time.strftime("%c")))
                sys.stdout.flush()
            tloops = 0
            for l in xrange(loops):
                if skip_rains:
                    break
                try:
                    if tloop is not Infinity:
                        alarm(tloop)
                    t = mytime()
                    a, b = find_gens_ellrains(k_flint, k_flint)
                    tloops += mytime(t)
                except RuntimeError:
                    # sometimes no suitable elliptic curve exists
                    pass
                except (KeyboardInterrupt, AlarmInterrupt):
                    tloops = 0
                    break
                finally:
                    if tloop is not Infinity:
                        cancel_alarm()
                if check and (l == 0 or check > 1):
                    g = a.minpoly()
                    if g.degree() != n:
                        raise RuntimeError("wrong degree")
                    if g != b.minpoly():
                        raise RuntimeError("different minpolys")
                if tloops > tmax:
                    break
            trains.append(tloops / (l+1))
            if verbose > 1:
                sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(tloops, tloops/(l+1)))
                sys.stdout.flush()
            # PARI/GP
            if verbose:
                sys.stdout.write("\r"+" "*79)
                sys.stdout.write("\rPARI/GP ({})".format(time.strftime("%c")))
                sys.stdout.flush()
            tloops = 0
            for l in xrange(loops):
                if skip_pari:
                    break
                if c < cmin or c > cmax:
                    break
                try:
                    if tloop is not Infinity:
                        alarm(tloop)
                    t = mytime()
                    a, b = find_gens_pari(k, k)
                    tloops += mytime(t)
                except (KeyboardInterrupt, AlarmInterrupt):
                    tloops = 0
                    break
                finally:
                    if tloop is not Infinity:
                        cancel_alarm()
                if check and (l == 0 or check > 1):
                    g = a.minpoly()
                    if g.degree() != n:
                        raise RuntimeError("wrong degree")
                    if g != b.minpoly():
                        raise RuntimeError("different minpolys")
                if tloops > tmax:
                    break
            tpari = tloops / (l+1)
            # Kummer algorithms
            tkummer = []
            # only linalg and modcomp implemented for c==1
            for i, algo in enumerate(kummer_algolist[2*(c==1):-2*(c==1)-1]):
                if verbose:
                    sys.stdout.write("\r"+" "*79)
                    sys.stdout.write("\rKummer {} ({})".format(kummer_namelist[2*(c==1)+i], time.strftime("%c")))
                    sys.stdout.flush()
                tloops = 0
                for l in xrange(loops):
                    if skip_kummer:
                        break
                    if c < cmin or c > cmax:
                        break
                    try:
                        if tloop is not Infinity:
                            alarm(tloop)
                        t = mytime()
                        a, b = find_gens_kummer(k_flint, k_flint, n, algo)
                        tloops += mytime(t)
                    except (KeyboardInterrupt, AlarmInterrupt):
                        tloops = 0
                        break
                    finally:
                        if tloop is not Infinity:
                            cancel_alarm()
                    if check and (l == 0 or check > 1):
                        g = a.minpoly()
                        if g.degree() != n:
                            raise RuntimeError("wrong degree")
                        if g != b.minpoly():
                            raise RuntimeError("different minpolys")
                    if tloops > tmax:
                        break
                tkummer.append(tloops / (l+1))
                if verbose > 1:
                    sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(tloops, tloops/(l+1)))
                    sys.stdout.flush()
            tkummer = 2*(c == 1)*[0] + tkummer + 2*(c == 1)*[0]
            if verbose:
                sys.stdout.write("\r")
                sys.stdout.flush()
            f.write(("{} {} ({}, {})" + " {}" + " {}"*len(trains) + " {}" + " {}"*len(tkummer)+"\n").format(p, n, o, c, *([tmagma] + trains + [tpari] + tkummer)))
    if write:
        f.close()