Beispiel #1
0
def irreps(p, q):
    """
    Returns the irreducible representations of the cyclic group C_p
    over the field F_q, where p and q are distinct primes.

    Each representation is given by a matrix over F_q giving the
    action of the preferred generator of C_p.

       sage: [M.nrows() for M in irreps(3, 7)]
       [1, 1, 1]
       sage: [M.nrows() for M in irreps(7, 11)]
       [1, 3, 3]
       sage: sum(M.nrows() for M in irreps(157, 13))
       157
    """
    p, q = ZZ(p), ZZ(q)
    assert p.is_prime() and q.is_prime() and p != q
    R = PolynomialRing(GF(q), 'x')
    x = R.gen()
    polys = [f for f, e in (x**p - 1).factor()]
    polys.sort(key=lambda f: (f.degree(), -f.constant_coefficient()))
    reps = [poly_to_rep(f) for f in polys]
    assert all(A**p == 1 for A in reps)
    assert reps[0] == 1
    return reps
Beispiel #2
0
def get_AB_primes(q, epsilons, q_class_group_order):

    output_dict_AB = {}
    alphas = (q ** q_class_group_order).gens_reduced()
    assert len(alphas) == 1, "q^q_class_group_order not principal, which is very bad"
    alpha = alphas[0]
    rat_q = ZZ(q.norm())
    assert rat_q.is_prime(), "somehow the degree 1 prime is not prime"
    for eps in epsilons:
        alpha_to_eps = group_ring_exp(alpha, eps)
        A = (alpha_to_eps - 1).norm()
        B = (alpha_to_eps - (rat_q ** (12 * q_class_group_order))).norm()
        output_dict_AB[eps] = lcm(A, B)
    return output_dict_AB
Beispiel #3
0
 def includes_composite(s):
     s = s.replace(' ', '').replace('..', '-')
     for interval in s.split(','):
         if '-' in interval[1:]:
             ix = interval.index('-', 1)
             a, b = int(interval[:ix]), int(interval[ix + 1:])
             if b == a:
                 if a != 1 and not a.is_prime():
                     return True
             if b > a and b > 3:
                 return True
         else:
             a = ZZ(interval)
             if a != 1 and not a.is_prime():
                 return True
Beispiel #4
0
 def includes_composite(s):
     s = s.replace(" ", "").replace("..", "-")
     for interval in s.split(","):
         if "-" in interval[1:]:
             ix = interval.index("-", 1)
             a, b = int(interval[:ix]), int(interval[ix + 1 :])
             if b == a:
                 if a != 1 and not a.is_prime():
                     return True
             if b > a and b > 3:
                 return True
         else:
             a = ZZ(interval)
             if a != 1 and not a.is_prime():
                 return True
Beispiel #5
0
 def includes_composite(s):
     s = s.replace(' ','').replace('..','-')
     for interval in s.split(','):
         if '-' in interval[1:]:
             ix = interval.index('-',1)
             a,b = int(interval[:ix]), int(interval[ix+1:])
             if b == a:
                 if a != 1 and not a.is_prime():
                     return True
             if b > a and b > 3:
                 return True
         else:
             a = ZZ(interval)
             if a != 1 and not a.is_prime():
                 return True
Beispiel #6
0
def get_the_lcm(C_K, gen_list):

    K = C_K.number_field()
    epsilons = {(6, 6): "type-2"}
    running_lcm = 1
    for q in gen_list:
        q_class_group_order = C_K(q).multiplicative_order()
        AB_lcm = get_AB_primes(q, epsilons, q_class_group_order)[(6, 6)]
        C_o = get_C_primes(K, q, epsilons, q_class_group_order, ordinary=True)[(6, 6)]
        rat_q = ZZ(q.norm())
        assert (
            rat_q.is_prime()
        ), "Somehow there is a split prime ideal whose norm is not prime!"
        running_lcm = lcm([running_lcm, AB_lcm, C_o, rat_q])
    return running_lcm
Beispiel #7
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()))
Beispiel #8
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()))