Esempio n. 1
0
 def hecke_eigenvalue(self, m):
     '''
     Assuming self is an eigenform, returns mth Hecke eigenvalue.
     '''
     t = self._none_zero_tpl()
     K = self.base_ring
     if hasattr(K, "fraction_field"):
         K = K.fraction_field()
     if self.sym_wt == 0 and ZZ(m).is_prime_power() and factor(m)[0][1] == 2:
         p = factor(m)[0][0]
         lp = self.hecke_eigenvalue(p)
         return K(self._hecke_tp2_for_eigenform(p, t, lp)) / self[t]
     else:
         return K(self.hecke_operator(m, t) / self[t])
Esempio n. 2
0
    def dirichlet_series_coeffs(self, prec, eps=1e-10):
        """
        Return the coefficients of the Dirichlet series representation
        of self, up to the given precision.

        INPUT:
           - prec -- positive integer
           - eps -- None or a positive real; any coefficient with absolute
             value less than eps is set to 0.
        """
        # Use multiplicativity to compute the Dirichlet series
        # coefficients, then make a DirichletSeries object.
        zero = RDF(0)
        coeffs = [RDF(0), RDF(1)] + [None] * (prec - 2)

        from sage.all import log, floor  # TODO: slow

        # prime-power indexed coefficients
        for p in prime_range(2, prec):
            B = floor(log(prec, p)) + 1
            series = self._local_series(p, B)
            p_pow = p
            for i in range(1, B):
                coeffs[p_pow] = series[i] if (
                    eps is None or abs(series[i]) > eps) else zero
                p_pow *= p

        # non-prime-powers
        from sage.all import factor
        for n in range(2, prec):
            if coeffs[n] is None:
                a = prod(coeffs[p**e] for p, e in factor(n))
                coeffs[n] = a if (eps is None or abs(a) > eps) else zero

        return coeffs
Esempio n. 3
0
def list_to_factored_poly_otherorder(s):
    if len(s) == 1:
        return str(s[0])
    sfacts = factor(PolynomialRing(ZZ, 'T')(s))
    sfacts_fc = [[v[0],v[1]] for v in sfacts]
    if sfacts.unit() == -1:
        sfacts_fc[0][0] *= -1
    outstr = ''
    for v in sfacts_fc:
        vcf = v[0].list()
        started = False
        if len(sfacts) > 1 or v[1] > 1:
            outstr += '('
        for i in range(len(vcf)):
            if vcf[i] <> 0:
                if started and vcf[i] > 0:
                    outstr += '+'
                started = True
                if i == 0:
                    outstr += str(vcf[i])
                else:
                    if abs(vcf[i]) <> 1:
                        outstr += str(vcf[i])
                    elif vcf[i] == -1:
                        outstr += '-'
                    if i == 1:
                        outstr += 'T'
                    elif i > 1:
                        outstr += 'T^{' + str(i) + '}'
        if len(sfacts) > 1 or v[1] > 1:
            outstr += ')'
        if v[1] > 1:
            outstr += '^{' + str(v[1]) + '}'        
    return outstr
Esempio n. 4
0
    def dirichlet_series_coeffs(self, prec, eps=1e-10):
        """
        Return the coefficients of the Dirichlet series representation
        of self, up to the given precision.

        INPUT:
           - prec -- positive integer
           - eps -- None or a positive real; any coefficient with absolute
             value less than eps is set to 0.
        """
        # Use multiplicativity to compute the Dirichlet series
        # coefficients, then make a DirichletSeries object.
        zero = RDF(0)
        coeffs = [RDF(0),RDF(1)] + [None]*(prec-2)

        from sage.all import log, floor   # TODO: slow
        
        # prime-power indexed coefficients
        for p in prime_range(2, prec):
            B = floor(log(prec, p)) + 1
            series = self._local_series(p, B)
            p_pow = p
            for i in range(1, B):
                coeffs[p_pow] = series[i] if (eps is None or abs(series[i])>eps) else zero
                p_pow *= p

        # non-prime-powers
        from sage.all import factor
        for n in range(2, prec):
            if coeffs[n] is None:
                a = prod(coeffs[p**e] for p, e in factor(n))
                coeffs[n] = a if (eps is None or abs(a) > eps) else zero

        return coeffs
Esempio n. 5
0
def build_matrix(P, M, c=1000):
    factors_M = factor(M)
    rows = []

    # add logarithms
    for p in P:
        row = []
        for q, e in factors_M:
            row.extend(Zmod(q**e)(p).generalised_log()
                       )  # generalised_log() uses unit_gens() generators
        row = [c * x
               for x in row]  # multiply logs by a large constant to help LLL
        rows.append(row)

    height = len(rows)
    width = len(rows[0])

    # add unit matrix
    for i, row in enumerate(rows):
        row.extend([1 if j == i else 0 for j in range(0, height)])

    # add group orders
    generators_M = [g for q, e in factors_M for g in Zmod(q**e).unit_gens()]
    for i, g in enumerate(generators_M):
        rows.append([
            g.multiplicative_order() * c if j == i else 0
            for j in range(0, width + height)
        ])

    return Matrix(rows)
Esempio n. 6
0
def web_latex_factored_integer(x, enclose=True, equals=False):
    r"""
    Given any x that can be converted to a ZZ, creates latex string representing x in factored form
    Returns 0 for 0, replaces -1\cdot with -.

    If equals=true returns latex string for x = factorization but omits "= factorization" if abs(x)=0,1,prime
    """
    x = ZZ(x)
    if abs(x) in [0,1] or abs(x).is_prime():
        return web_latex(x, enclose=enclose)
    if equals:
        s = web_latex(factor(x), enclose=False).replace(r"-1 \cdot","-")
        s = " %s = %s " % (x, s)
    else:
        s = web_latex(factor(x), enclose=False).replace(r"-1 \cdot","-")
    return r"\( %s \)" % s if enclose else s
Esempio n. 7
0
def pohlig_hellman(g, h, group, order=None):
    """Pohlig-Hellman algorithm for computing discrete logarithms
    in a finite abelian group `group` whose order is a smooth integer.

        INPUT:
        - `g` must be a primitive element of `group`
        - `h` must be an element of `group`

        OUTPUT:
        - `x` such that ``g^x = h``

    See https://en.wikipedia.org/wiki/Pohlig%E2%80%93Hellman_algorithm
    for details.
    """

    if order is None:
        order = group.order()

    decomposition = factor(order)
    residues = []
    moduli = []

    for pi, ei in decomposition:
        # compute the residue of x mod pi^ni
        modulus = pi**ei
        ni = order // modulus
        gi, hi = g**ni, h**ni
        residue = pohlig_hellman_prime(gi, hi, group, pi, ei)
        residues.append(residue)
        moduli.append(modulus)

    x = CRT(residues, moduli)
    return x
Esempio n. 8
0
def factor(n):
    # For small n, use hand-rolled factoring algorithm to avoid slow imports.
    if n <= 2**16:
        return _factor(n)

    from sage.all import factor
    return factor(n)
Esempio n. 9
0
def list_to_factored_poly_otherorder(s):
    if len(s) == 1:
        return str(s[0])
    sfacts = factor(PolynomialRing(ZZ, 'T')(s))
    sfacts_fc = [[v[0], v[1]] for v in sfacts]
    if sfacts.unit() == -1:
        sfacts_fc[0][0] *= -1
    outstr = ''
    for v in sfacts_fc:
        vcf = v[0].list()
        started = False
        if len(sfacts) > 1 or v[1] > 1:
            outstr += '('
        for i in range(len(vcf)):
            if vcf[i] <> 0:
                if started and vcf[i] > 0:
                    outstr += '+'
                started = True
                if i == 0:
                    outstr += str(vcf[i])
                else:
                    if abs(vcf[i]) <> 1:
                        outstr += str(vcf[i])
                    elif vcf[i] == -1:
                        outstr += '-'
                    if i == 1:
                        outstr += 'T'
                    elif i > 1:
                        outstr += 'T^{' + str(i) + '}'
        if len(sfacts) > 1 or v[1] > 1:
            outstr += ')'
        if v[1] > 1:
            outstr += '^{' + str(v[1]) + '}'
    return outstr
Esempio n. 10
0
def pohlig_hellman(G, A, E):
    """Pohlig-Hellman algorithm for computing discrete logarithms
    in an elliptic curve `E` whose order is a smooth integer.

        INPUT:
        - `G` must be an element of `E`
        - `A` must be an element of the sub-group generated by `G`

        OUTPUT:
        - `n` such that `n*G = A`
    """

    n = G.order()
    decomposition = factor(n)
    residues = []
    moduli = []

    for pi, ei in decomposition:
        # compute the residue of x mod pi^ni
        modulus = pi**ei
        ni = n // modulus
        Gi, Ai = ni * G, ni * A
        x = pohlig_hellman_prime(Gi, Ai, E, pi, ei)

        residues.append(x)
        moduli.append(modulus)

    x = CRT(residues, moduli)
    return x
Esempio n. 11
0
def formtest(minD, maxD, k, eps=-1):
    ds = {}
    for D in range(minD, maxD + 1):
        if (eps * D) % 4 == 1:
            dif, d, dd = compare_formulas_2(eps * D, k)
            if dif <= 1e-6:
                print(D, factor(D))
                print(dif, d, dd)
Esempio n. 12
0
 def hecke_charpoly(self, m, var="x", algorithm='linbox'):
     p, i = factor(m)[0]
     if not (ZZ(m).is_prime_power() and 0 < i < 3):
         raise RuntimeError("m must be a prime or the square of a prime.")
     if i == 1:
         return self._hecke_tp_charpoly(p, var=var, algorithm=algorithm)
     if i == 2:
         return self._hecke_tp2_charpoly(p, var=var, algorithm=algorithm)
Esempio n. 13
0
def _prime_power_divisors(n):
    divisors = []
    for p, e in factor(n):
        for i in range(1, e + 1):
            divisors.append(p**i)

    divisors.sort()
    return divisors
def _polynomial_gcd_crt(a, b, modulus):
    gs = []
    ps = []
    for p, _ in factor(modulus):
        zmodp = Zmod(p)
        gs.append(_polynomial_gcd(a.change_ring(zmodp), b.change_ring(zmodp)).change_ring(ZZ))
        ps.append(p)

    return gs[0] if len(gs) == 1 else crt(gs, ps)
Esempio n. 15
0
 def myfunc(inp, n):
     fn = list(factor(inp))
     pvals = [[localfactorsa[self.any_prime_to_cc_index(z[0]) - 1], z[1]] for z in fn]
     # -1 is the marker that the prime divides the conductor
     for j in range(len(pvals)):
         if pvals[j][0] < 0:
             return -1
     pvals = sum([z[0] * z[1] for z in pvals])
     return pvals % n
Esempio n. 16
0
 def myfunc(inp, n):
     fn = list(factor(inp))
     pvals = [[localfactorsa[self.any_prime_to_cc_index(z[0])-1], z[1]] for z in fn]
     # -1 is the marker that the prime divides the conductor
     for j in range(len(pvals)):
         if pvals[j][0] < 0:
             return -1
     pvals = sum([z[0]*z[1] for z in pvals])
     return (pvals % n)
Esempio n. 17
0
def id_dirichlet(fun, N, n):
    N = Integer(N)
    if N == 1:
        return (1, 1)
    p2 = valuation(N, 2)
    N2 = 2**p2
    Nodd = N // N2
    Nfact = list(factor(Nodd))
    #print "n = "+str(n)
    #for j in range(20):
    #    print "chi(%d) = e(%d/%d)"%(j+2, fun(j+2,n), n)
    plist = [z[0] for z in Nfact]
    ppows = [z[0]**z[1] for z in Nfact]
    ppows2 = list(ppows)
    idems = [1 for z in Nfact]
    proots = [primitive_root(z) for z in ppows]
    # Get CRT idempotents
    if p2 > 0:
        ppows2.append(N2)
    for j in range(len(plist)):
        exps = [1 for z in idems]
        if p2 > 0:
            exps.append(1)
        exps[j] = proots[j]
        idems[j] = crt(exps, ppows2)
    idemvals = [fun(z, n) for z in idems]
    # now normalize to right root of unity base
    idemvals = [
        idemvals[j] * euler_phi(ppows[j]) / n for j in range(len(idemvals))
    ]
    ans = [
        Integer(mod(proots[j], ppows[j])**idemvals[j])
        for j in range(len(proots))
    ]
    ans = crt(ans, ppows)
    # There are cases depending on 2-part of N
    if p2 == 0:
        return (N, ans)
    if p2 == 1:
        return (N, crt([1, ans], [2, Nodd]))
    if p2 == 2:
        my3 = crt([3, 1], [N2, Nodd])
        if fun(my3, n) == 0:
            return (N, crt([1, ans], [4, Nodd]))
        else:
            return (N, crt([3, ans], [4, Nodd]))
    # Final case 2^3 | N

    my5 = crt([5, 1], [N2, Nodd])
    test1 = fun(my5, n) * N2 / 4 / n
    test1 = Integer(mod(5, N2)**test1)
    minusone = crt([-1, 1], [N2, Nodd])
    test2 = (fun(minusone, n) * N2 / 4 / n) % (N2 / 4)
    if test2 > 0:
        test1 = Integer(mod(-test1, N2))
    return (N, crt([test1, ans], [N2, Nodd]))
Esempio n. 18
0
def ll_common_denominator(f):
    """For a polynomial f with fractional coefficients, write out the
    polynomial such that there is only a single denominator."""
    # f should be a polynomial
    if not is_Polynomial(f):
        return ll_raw(f)
    # first determine the lcm of the denominators of the coefficients
    cd = reduce(lcm, [c.denominator() for c in f])
    if is_Polynomial(cd) and cd.degree() > 0:
        return "\\frac{" + ll_raw(cd * f) + "}{" + ll_raw(factor(cd)) + "}"
    else:
        return ll_raw(f)
Esempio n. 19
0
def factor_offline(n):
    print(
        "failed to factor in http://factordb.com\nThe length of n is %s\nIt might need a very long time and sagemath is required"
        % (len(n)))
    choice = input('Do you want to factor in your local computer?\n[y/n]')
    if choice[0] is 'y':
        try:
            from sage.all import factor
            p, q = map(int, re.split(r'\s*\*\s*', str(factor(n))))
            return (pp, qq)
        except ImportError as e:
            raise Exception("Can't factor n")
Esempio n. 20
0
 def properties(self):
     nilp_str = f"yes, of class {self.nilpotency_class}" if self.nilpotent else "no"
     solv_str = f"yes, of length {self.derived_length}" if self.solvable else "no"
     props = [
         ("Label", self.label),
         ("Order", web_latex(factor(self.order))),
         ("Exponent", web_latex(factor(self.exponent))),
         (None, self.image()),
     ]
     if self.abelian:
         props.append(("Abelian", "yes"))
         if self.simple:
             props.extend([("Simple", "yes"),
                           (r"#$\operatorname{Aut}(G)$", web_latex(factor(self.aut_order)))])
         else:
             props.append((r"#$\operatorname{Aut}(G)$", web_latex(factor(self.aut_order))))
     else:
         if self.simple:
             props.append(("Simple", "yes"))
         else:
             props.extend([("Nilpotent", nilp_str),
                           ("Solvable", solv_str)])
         props.extend([
             (r"#$G^{\mathrm{ab}}$", web_latex(self.Gab_order_factor())),
             ("#$Z(G)$", web_latex(self.cent_order_factor())),
             (r"#$\operatorname{Aut}(G)$", web_latex(factor(self.aut_order))),
             (r"#$\operatorname{Out}(G)$", web_latex(factor(self.outer_order))),
         ])
     props.extend([
         ("Rank", f"${self.rank}$"),
         ("Perm deg.", f"${self.transitive_degree}$"),
         # ("Faith. dim.", str(self.faithful_reps[0][0])),
     ])
     return props
Esempio n. 21
0
 def _hecke_eigen_needed_tuples(self, m):
     tpl = self._none_zero_tpl()
     p, i = factor(m)[0]
     if not (ZZ(m).is_prime_power() and 0 < i < 3):
         raise RuntimeError("m must be a prime or the square of a prime.")
     if i == 1:
         return uniq(reduced_form_with_sign(t)[0]
                     for t in self._hecke_tp_needed_tuples(p, tpl))
     if i == 2:
         l1 = self._hecke_eigen_needed_tuples(p)
         l = [reduced_form_with_sign(t)[0]
              for t in self._hecke_tp2_needed_tuples(p, tpl)]
         return uniq(l1 + l)
Esempio n. 22
0
def get_way_count(surface_count):
    n = (surface_count + 3) // 2
    factors = [x for x, _ in factor(n)]

    def f(x):
        first_k = (x * (-x % 3) - 2) // 3
        last_k = (n - 2) // 3
        last_k = last_k - (last_k - first_k) % x
        return (last_k - first_k) // x + 1

    return ((n - 2) // 3 + 1 + sum(
        (+1 if len(subset) % 2 == 0 else -1) * f(prod(subset))
        for subset in Subsets(factors) if subset))
Esempio n. 23
0
 def sylow_subgroups(self):
     """
     Returns a list of pairs (p, P) where P is a WebAbstractSubgroup representing a p-Sylow subgroup.
     """
     syl_dict = {}
     for sub in self.subgroups.values():
         if sub.sylow > 0:
             syl_dict[sub.sylow] = sub
     syl_list = []
     for p, e in factor(self.order):
         if p in syl_dict:
             syl_list.append((p, syl_dict[p]))
     return syl_list
Esempio n. 24
0
def id_dirichlet(fun, N, n):
    N = Integer(N)
    if N == 1:
        return (1, 1)
    p2 = valuation(N, 2)
    N2 = 2 ** p2
    Nodd = N / N2
    Nfact = list(factor(Nodd))
    # print "n = "+str(n)
    # for j in range(20):
    #    print "chi(%d) = e(%d/%d)"%(j+2, fun(j+2,n), n)
    plist = [z[0] for z in Nfact]
    ppows = [z[0] ** z[1] for z in Nfact]
    ppows2 = list(ppows)
    idems = [1 for z in Nfact]
    proots = [primitive_root(z) for z in ppows]
    # Get CRT idempotents
    if p2 > 0:
        ppows2.append(N2)
    for j in range(len(plist)):
        exps = [1 for z in idems]
        if p2 > 0:
            exps.append(1)
        exps[j] = proots[j]
        idems[j] = crt(exps, ppows2)
    idemvals = [fun(z, n) for z in idems]
    # now normalize to right root of unity base
    idemvals = [idemvals[j] * euler_phi(ppows[j]) / n for j in range(len(idemvals))]
    ans = [Integer(mod(proots[j], ppows[j]) ** idemvals[j]) for j in range(len(proots))]
    ans = crt(ans, ppows)
    # There are cases depending on 2-part of N
    if p2 == 0:
        return (N, ans)
    if p2 == 1:
        return (N, crt([1, ans], [2, Nodd]))
    if p2 == 2:
        my3 = crt([3, 1], [N2, Nodd])
        if fun(my3, n) == 0:
            return (N, crt([1, ans], [4, Nodd]))
        else:
            return (N, crt([3, ans], [4, Nodd]))
    # Final case 2^3 | N

    my5 = crt([5, 1], [N2, Nodd])
    test1 = fun(my5, n) * N2 / 4 / n
    test1 = Integer(mod(5, N2) ** test1)
    minusone = crt([-1, 1], [N2, Nodd])
    test2 = (fun(minusone, n) * N2 / 4 / n) % (N2 / 4)
    if test2 > 0:
        test1 = Integer(mod(-test1, N2))
    return (N, crt([test1, ans], [N2, Nodd]))
Esempio n. 25
0
def gen_unsafe_curve(bits, attempts=-1):
    """generates a random curve that has only small factors"""
    while attempts != 0:
        E, F = gen_random_curve(bits)
        factors = [x for x, y in factor(E.order())]
        bit_lengths = [int(f).bit_length() for f in factors]
        if all(l <= MAX_BITS_FOR_FACTOR for l in bit_lengths):
            a = E.ainvs()[3]
            b = E.ainvs()[4]
            p = F.cardinality()
            P = gen_generator(E)
            return a, b, p, P.xy()
        if attempts > 0:
            attempts -= 1
Esempio n. 26
0
def pohlighellman(g, h):
    phi = g.multiplicative_order()
    factors = factor(phi)
    chinese_pairs = []
    for pi, ei in factors:
        n = phi / (pi**ei)
        print("testing n = %s" % n)
        hn = h**n
        print(("Searching h^%d in subgroup "
               "g^%d using Baby-step giant-step") % (n, n))
        a = babystepgiantstep(g**n, hn)
        print("Found g^(%s * %s) == %s" % (n, a, hn))
        chinese_pairs.append([a, pi**ei])

    return crt(*map(list, zip(*chinese_pairs)))
Esempio n. 27
0
 def hecke_operator(self, m, tpl):
     '''
     Assumes m is a prime or the square of a prime. And returns the tpl th
     Fourier coefficient of T(m)self.
     cf Andrianov, Zhuravlev, Modular Forms and Hecke Operators, pp 242.
     '''
     p, i = factor(m)[0]
     if not (ZZ(m).is_prime_power() and 0 < i < 3):
         raise RuntimeError("m must be a prime or the square of a prime.")
     if self.sym_wt == 0:
         if i == 1:
             return self._hecke_tp(p, tpl)
         elif i == 2:
             return self._hecke_tp2(p, tpl)
     else:
         return self._hecke_op_vector_vld(p, i, tpl)
Esempio n. 28
0
def pohlig(E, H, P) -> int:
    # pohlig-hellman algorithm, factor the order of the curve
    # and use bsgs to solve for each factor, then use CRT to
    # get a solution.
    bases = []
    resids = []

    for i, j in factor(E.order()):
        e = i**j
        logging.info(f' pohlig: {e}')
        t = E.order() // e
        tH = H * t
        tP = P * t
        dlog = bsgs(tP, tH, (0, e), '+')
        bases.append(dlog)
        resids.append(e)
    return CRT_list(bases, resids)
Esempio n. 29
0
def pohlighellman(g, h):
    phi = g.multiplicative_order()
    factors = factor(phi)
    chinese_pairs = []
    for pi, ei in factors:
        n = phi / (pi ** ei)
        print("testing n = %s" % n)
        hn = h ** n
        print("h^%s = %s" % (n, hn))
        for i in range(pi ** ei):
            print("Testing g^(%s * %s) == %s" % (i, n, hn))
            if g ** (n * i) == hn:
                print("Found x mod %s = %s" % (pi ** ei, i))
                chinese_pairs.append([i, pi ** ei])
                break

    return crt(*map(list, zip(*chinese_pairs)))
Esempio n. 30
0
def pohlig_hellman(g,h,p):
    '''
    Pohlig Hellman Algorithm:
    - currently only applicable to <g> = Fp
    '''
    n = p - 1 # order of group
    print('n=',n)

    # factor n
    n_factors = factor(n)
    print('n_factors=', n_factors)
    
    i = 0
    eqs  = []

    for i, f in enumerate(n_factors):
        q, e = f
        q, e = int(q), int(e)

        pi = int(pow(q,e))
        exp = int( n // pi )
        gi = pow(g, exp)
        hi = pow(h, exp)  
        print('--------------------')
        print(f'p{i}={pi}')
        print(f'exp{i}={exp}')
        print(f'g{i}={gi}')
        print(f'h{i}={hi}')

        # Solve the DLP: gi^yi = hi (mod p)
        yi = babygiantstep(p, gi, hi)
        print(f'y{i}={yi}')

        # Generate equation to solve using Chinese Remainder Theorem
        eqs.append((yi, pi))
        print(f'x{i}={yi} (mod {pi})')

    print('--------------------')
    # Knit together the smaller DLP solutions using the Chinese 
    # Remainder Theorem to get the actual solution

    x, m = chinese_remainder_theorem(eqs)
    print('x=', x)

    return x
Esempio n. 31
0
def compute_dirichlet_series(p_list, PREC):
    ''' computes the dirichlet series for a Lfunction_SMF2_scalar_valued
    '''
    # p_list is a list of pairs (p,y) where p is a prime and y is the list of roots of the Euler factor at x
    LL = [0] * PREC
    # create an empty list of the right size and now populate it with the powers of p
    for (p, y) in p_list:
        # FIXME p_prec is never used, but perhaps it should be?
        # p_prec = log(PREC) / log(p) + 1
        ep = euler_p_factor(y, PREC)
        for n in range(ep.prec()):
            if p ** n < PREC:
                LL[p ** n] = ep.coefficients()[n]
    for i in range(1, PREC):
        f = factor(i)
        if len(f) > 1:  # not a prime power
            LL[i] = prod([LL[p ** e] for (p, e) in f])
    return LL[1:]
Esempio n. 32
0
def compute_dirichlet_series(p_list, PREC):
    ''' computes the dirichlet series for a Lfunction_SMF2_scalar_valued
    '''
    # p_list is a list of pairs (p,y) where p is a prime and y is the list of roots of the Euler factor at x
    LL = [0] * PREC
    # create an empty list of the right size and now populate it with the powers of p
    for (p, y) in p_list:
        # FIXME p_prec is never used, but perhaps it should be?
        # p_prec = log(PREC) / log(p) + 1
        ep = euler_p_factor(y, PREC)
        for n in range(ep.prec()):
            if p ** n < PREC:
                LL[p ** n] = ep.coefficients()[n]
    for i in range(1, PREC):
        f = factor(i)
        if len(f) > 1:  # not a prime power
            LL[i] = prod([LL[p ** e] for (p, e) in f])
    return LL[1:]
 def show_factored_eqs(eqs, only_print=False, numbers=False,
                       variables=False, print_latex=False,
                       print_eqs=True):
     r"""
     Show given equations factored.
     """
     for i, eq in enumerate(eqs):
         factors = factor(eq)
         if numbers:
             print(i)
         if variables:
             print(latex(eq.variables()))
         if print_latex:
             print(latex(factors) + '=0\,, \\\\')
         if print_eqs:
             if only_print:
                 print(factors)
             else:
                 show(factors)
Esempio n. 34
0
def get_composite_discrete_root(a, m):

    # Prime factorization of m
    m_factors = factor(m)  # returns [(base, exp), (base,exp)...]

    cr = []

    for m_factor in m_factors:

        p = m_factor[0]

        # Find x s.t. x^ = p
        y1, y2 = get_discrete_root(a, p)
        y1, y2 = int(y1), int(y2)

        factor_roots = ((y1, p), (y2, p))
        cr.append(factor_roots)

        y = y1 if y1 < y2 else y2

    roots = []
    n = len(cr)

    i = 0
    while i < math.ceil(n / 2):
        factor_roots = cr[i]
        for j, froot in enumerate(factor_roots):
            k = 0
            while k < n:
                if k != i:
                    k_root = cr[k]
                    for other_root in k_root:
                        sys_eq = [froot, other_root]
                        x, m = chinese_remainder_theorem(sys_eq)
                        roots.append(x)
                k = k + 1
        i = i + 1

    return roots
Esempio n. 35
0
    def __init__(self, K, N_max=10**5):
        """
        Compute J working over the field K.
        """
        self.N_max   = N_max
        self.K = K

        from sage.all import prime_powers, factor
        PP = prime_powers(N_max+1)[1:]

        n  = len(PP)
        self.a   = [K(0)]*n
        self.s   = [K(0)]*n
        self.pv  = [0]*n
        i = 0
        for pv in PP:
            F = factor(pv)
            p, v = F[0]
            self.pv[i] = K(pv)
            logp = K(p).log()
            self.a[i] = logp/K(pv).sqrt()
            self.s[i] = v*logp
            i += 1
Esempio n. 36
0
    def __init__(self, K, N_max=10**5):
        """
        Compute J working over the field K.
        """
        self.N_max = N_max
        self.K = K

        from sage.all import prime_powers, factor
        PP = prime_powers(N_max + 1)[1:]

        n = len(PP)
        self.a = [K(0)] * n
        self.s = [K(0)] * n
        self.pv = [0] * n
        i = 0
        for pv in PP:
            F = factor(pv)
            p, v = F[0]
            self.pv[i] = K(pv)
            logp = K(p).log()
            self.a[i] = logp / K(pv).sqrt()
            self.s[i] = v * logp
            i += 1
Esempio n. 37
0
def zfactor(n):
    return factor(n) if n != 0 else 0
Esempio n. 38
0
    def make_object(self, curve, endo, tama, ratpts, is_curve):
        from lmfdb.genus2_curves.main import url_for_curve_label

        # all information about the curve, its Jacobian, isogeny class, and endomorphisms goes in the data dictionary
        # most of the data from the database gets polished/formatted before we put it in the data dictionary
        data = self.data = {}

        data['label'] = curve['label'] if is_curve else curve['class']
        data['slabel'] = data['label'].split('.')

        # set attributes common to curves and isogeny classes here
        data['Lhash'] = str(curve['Lhash'])
        data['cond'] = ZZ(curve['cond'])
        data['cond_factor_latex'] = web_latex(factor(int(
            data['cond']))).replace(r"-1 \cdot", "-")
        data['analytic_rank'] = ZZ(curve['analytic_rank'])
        data['mw_rank'] = ZZ(0) if curve.get('mw_rank') is None else ZZ(
            curve['mw_rank'])  # 0 will be marked as a lower bound
        data['mw_rank_proved'] = curve['mw_rank_proved']
        data['analytic_rank_proved'] = curve['analytic_rank_proved']
        data['hasse_weil_proved'] = curve['hasse_weil_proved']
        data['st_group'] = curve['st_group']
        data['st_group_link'] = st_link_by_name(1, 4, data['st_group'])
        data['st0_group_name'] = st0_group_name(curve['real_geom_end_alg'])
        data['is_gl2_type'] = curve['is_gl2_type']
        data['root_number'] = ZZ(curve['root_number'])
        data['lfunc_url'] = url_for("l_functions.l_function_genus2_page",
                                    cond=data['slabel'][0],
                                    x=data['slabel'][1])
        data['bad_lfactors'] = literal_eval(curve['bad_lfactors'])
        data['bad_lfactors_pretty'] = [(c[0],
                                        list_to_factored_poly_otherorder(c[1]))
                                       for c in data['bad_lfactors']]
        if is_curve:
            # invariants specific to curve
            data['class'] = curve['class']
            data['abs_disc'] = ZZ(curve['abs_disc'])
            data['disc'] = curve['disc_sign'] * data['abs_disc']
            data['min_eqn'] = literal_eval(curve['eqn'])
            data['min_eqn_display'] = min_eqns_pretty(data['min_eqn'])
            data['disc_factor_latex'] = web_latex(factor(
                data['disc'])).replace(r"-1 \cdot", "-")
            data['igusa_clebsch'] = [
                ZZ(a) for a in literal_eval(curve['igusa_clebsch_inv'])
            ]
            data['igusa'] = [ZZ(a) for a in literal_eval(curve['igusa_inv'])]
            data['g2'] = [QQ(a) for a in literal_eval(curve['g2_inv'])]
            data['igusa_clebsch_factor_latex'] = [
                web_latex(zfactor(i)).replace(r"-1 \cdot", "-")
                for i in data['igusa_clebsch']
            ]
            data['igusa_factor_latex'] = [
                web_latex(zfactor(j)).replace(r"-1 \cdot", "-")
                for j in data['igusa']
            ]
            data['aut_grp'] = small_group_label_display_knowl(
                '%d.%d' % tuple(literal_eval(curve['aut_grp_id'])))
            data['geom_aut_grp'] = small_group_label_display_knowl(
                '%d.%d' % tuple(literal_eval(curve['geom_aut_grp_id'])))
            data['num_rat_wpts'] = ZZ(curve['num_rat_wpts'])
            data['has_square_sha'] = "square" if curve[
                'has_square_sha'] else "twice a square"
            P = curve['non_solvable_places']
            if len(P):
                sz = "except over "
                sz += ", ".join([QpName(p) for p in P])
                last = " and"
                if len(P) > 2:
                    last = ", and"
                sz = last.join(sz.rsplit(",", 1))
            else:
                sz = "everywhere"
            data['non_solvable_places'] = sz
            data['two_selmer_rank'] = ZZ(curve['two_selmer_rank'])
            data['torsion_order'] = curve['torsion_order']

            data['end_ring_base'] = endo['ring_base']
            data['end_ring_geom'] = endo['ring_geom']
            data['real_period'] = decimal_pretty(str(curve['real_period']))
            data['regulator'] = decimal_pretty(
                str(curve['regulator']
                    )) if curve['regulator'] > -0.5 else 'unknown'
            if data['mw_rank'] == 0 and data['mw_rank_proved']:
                data['regulator'] = '1'  # display an exact 1 when we know this

            data['tamagawa_product'] = ZZ(
                curve['tamagawa_product']) if curve.get(
                    'tamagawa_product') else 0
            data['analytic_sha'] = ZZ(
                curve['analytic_sha']) if curve.get('analytic_sha') else 0
            data['leading_coeff'] = decimal_pretty(
                str(curve['leading_coeff']
                    )) if curve['leading_coeff'] else 'unknown'

            data['rat_pts'] = ratpts['rat_pts']
            data['rat_pts_v'] = ratpts['rat_pts_v']
            data['rat_pts_table'] = ratpts_table(ratpts['rat_pts'],
                                                 ratpts['rat_pts_v'])

            data['mw_gens_v'] = ratpts['mw_gens_v']
            lower = len([n for n in ratpts['mw_invs'] if n == 0])
            upper = data['analytic_rank']
            invs = ratpts[
                'mw_invs'] if data['mw_gens_v'] or lower >= upper else [
                    0 for n in range(upper - lower)
                ] + ratpts['mw_invs']
            if len(invs) == 0:
                data['mw_group'] = 'trivial'
            else:
                data['mw_group'] = r'\(' + r' \times '.join([
                    (r'\Z' if n == 0 else r'\Z/{%s}\Z' % n) for n in invs
                ]) + r'\)'
            if lower >= upper:
                data['mw_gens_table'] = mw_gens_table(ratpts['mw_invs'],
                                                      ratpts['mw_gens'],
                                                      ratpts['mw_heights'],
                                                      ratpts['rat_pts'])

            if curve['two_torsion_field'][0]:
                data['two_torsion_field_knowl'] = nf_display_knowl(
                    curve['two_torsion_field'][0],
                    field_pretty(curve['two_torsion_field'][0]))
            else:
                t = curve['two_torsion_field']
                data[
                    'two_torsion_field_knowl'] = r"splitting field of \(%s\) with Galois group %s" % (
                        intlist_to_poly(
                            t[1]), group_display_knowl(t[2][0], t[2][1]))

            tamalist = [[item['p'], item['tamagawa_number']] for item in tama]
            data['local_table'] = local_table(data['abs_disc'], data['cond'],
                                              tamalist,
                                              data['bad_lfactors_pretty'])

        else:
            # invariants specific to isogeny class
            curves_data = list(
                db.g2c_curves.search({"class": curve['class']},
                                     ['label', 'eqn']))
            if not curves_data:
                raise KeyError(
                    "No curves found in database for isogeny class %s of genus 2 curve %s."
                    % (curve['class'], curve['label']))
            data['curves'] = [{
                "label":
                c['label'],
                "equation_formatted":
                min_eqn_pretty(literal_eval(c['eqn'])),
                "url":
                url_for_curve_label(c['label'])
            } for c in curves_data]
            lfunc_data = db.lfunc_lfunctions.lucky(
                {'Lhash': str(curve['Lhash'])})
            if not lfunc_data:
                raise KeyError(
                    "No Lfunction found in database for isogeny class of genus 2 curve %s."
                    % curve['label'])
            if lfunc_data and lfunc_data.get('euler_factors'):
                data['good_lfactors'] = [
                    [nth_prime(n + 1), lfunc_data['euler_factors'][n]]
                    for n in range(len(lfunc_data['euler_factors']))
                    if nth_prime(n + 1) < 30 and (data['cond'] %
                                                  nth_prime(n + 1))
                ]
                data['good_lfactors_pretty'] = [
                    (c[0], list_to_factored_poly_otherorder(c[1]))
                    for c in data['good_lfactors']
                ]

        # Endomorphism data over QQ:
        data['gl2_statement_base'] = gl2_statement_base(
            endo['factorsRR_base'], r'\(\Q\)')
        data['factorsQQ_base'] = endo['factorsQQ_base']
        data['factorsRR_base'] = endo['factorsRR_base']
        data['end_statement_base'] = (
            r"Endomorphism %s over \(\Q\):<br>" %
            ("ring" if is_curve else "algebra") +
            end_statement(data['factorsQQ_base'],
                          endo['factorsRR_base'],
                          ring=data['end_ring_base'] if is_curve else None))

        # Field over which all endomorphisms are defined
        data['end_field_label'] = endo['fod_label']
        data['end_field_poly'] = intlist_to_poly(endo['fod_coeffs'])
        data['end_field_statement'] = end_field_statement(
            data['end_field_label'], data['end_field_poly'])

        # Endomorphism data over QQbar:
        data['factorsQQ_geom'] = endo['factorsQQ_geom']
        data['factorsRR_geom'] = endo['factorsRR_geom']
        if data['end_field_label'] != '1.1.1.1':
            data['gl2_statement_geom'] = gl2_statement_base(
                data['factorsRR_geom'], r'\(\overline{\Q}\)')
            data['end_statement_geom'] = (
                r"Endomorphism %s over \(\overline{\Q}\):" %
                ("ring" if is_curve else "algebra") + end_statement(
                    data['factorsQQ_geom'],
                    data['factorsRR_geom'],
                    field=r'\overline{\Q}',
                    ring=data['end_ring_geom'] if is_curve else None))
        data['real_geom_end_alg_name'] = real_geom_end_alg_name(
            curve['real_geom_end_alg'])
        data['geom_end_alg_name'] = geom_end_alg_name(curve['geom_end_alg'])

        # Endomorphism data over intermediate fields not already treated (only for curves, not necessarily isogeny invariant):
        if is_curve:
            data['end_lattice'] = (endo['lattice'])[1:-1]
            if data['end_lattice']:
                data['end_lattice_statement'] = end_lattice_statement(
                    data['end_lattice'])

        # Field over which the Jacobian decomposes (base field if Jacobian is geometrically simple)
        data['is_simple_geom'] = endo['is_simple_geom']
        data['split_field_label'] = endo['spl_fod_label']
        data['split_field_poly'] = intlist_to_poly(endo['spl_fod_coeffs'])
        data['split_field_statement'] = split_field_statement(
            data['is_simple_geom'], data['split_field_label'],
            data['split_field_poly'])

        # Elliptic curve factors for non-simple Jacobians
        if not data['is_simple_geom']:
            data['split_coeffs'] = endo['spl_facs_coeffs']
            if 'spl_facs_labels' in endo and len(
                    endo['spl_facs_labels']) == len(endo['spl_facs_coeffs']):
                data['split_labels'] = endo['spl_facs_labels']
            data['split_condnorms'] = endo['spl_facs_condnorms']
            data['split_statement'] = split_statement(data['split_coeffs'],
                                                      data.get('split_labels'),
                                                      data['split_condnorms'])

        # Properties
        self.properties = properties = [('Label', data['label'])]
        if is_curve:
            plot_from_db = db.g2c_plots.lucky({"label": curve['label']})
            if (plot_from_db is None):
                self.plot = encode_plot(
                    eqn_list_to_curve_plot(
                        data['min_eqn'], ratpts['rat_pts'] if ratpts else []))
            else:
                self.plot = plot_from_db['plot']
            plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format(
                self.plot)

            properties += [
                (None, plot_link),
                ('Conductor', str(data['cond'])),
                ('Discriminant', str(data['disc'])),
            ]
            if data['mw_rank_proved']:
                properties += [('Mordell-Weil group', data['mw_group'])]
        properties += [
            ('Sato-Tate group', data['st_group_link']),
            (r'\(\End(J_{\overline{\Q}}) \otimes \R\)',
             r'\(%s\)' % data['real_geom_end_alg_name']),
            (r'\(\End(J_{\overline{\Q}}) \otimes \Q\)',
             r'\(%s\)' % data['geom_end_alg_name']),
            (r'\(\overline{\Q}\)-simple', bool_pretty(data['is_simple_geom'])),
            (r'\(\mathrm{GL}_2\)-type', bool_pretty(data['is_gl2_type'])),
        ]

        # Friends
        self.friends = friends = []
        if is_curve:
            friends.append(('Isogeny class %s.%s' %
                            (data['slabel'][0], data['slabel'][1]),
                            url_for(".by_url_isogeny_class_label",
                                    cond=data['slabel'][0],
                                    alpha=data['slabel'][1])))

        # first deal with EC
        ecs = []
        if 'split_labels' in data:
            for friend_label in data['split_labels']:
                if is_curve:
                    ecs.append(("Elliptic curve " + friend_label,
                                url_for_ec(friend_label)))
                else:
                    ecs.append(
                        ("Isogeny class " + ec_label_class(friend_label),
                         url_for_ec_class(friend_label)))

        ecs.sort(key=lambda x: key_for_numerically_sort(x[0]))

        # then again EC from lfun
        instances = []
        for elt in db.lfunc_instances.search(
            {
                'Lhash': data['Lhash'],
                'type': 'ECQP'
            }, 'url'):
            instances.extend(elt.split('|'))

        # and then the other isogeny friends
        instances.extend([
            elt['url'] for elt in get_instances_by_Lhash_and_trace_hash(
                data["Lhash"], 4, int(data["Lhash"]))
        ])
        exclude = {
            elt[1].rstrip('/').lstrip('/')
            for elt in self.friends if elt[1]
        }
        exclude.add(data['lfunc_url'].lstrip('/L/').rstrip('/'))
        for elt in ecs + names_and_urls(instances, exclude=exclude):
            # because of the splitting we must use G2C specific code
            add_friend(friends, elt)
        if is_curve:
            friends.append(('Twists',
                            url_for(".index_Q",
                                    g20=str(data['g2'][0]),
                                    g21=str(data['g2'][1]),
                                    g22=str(data['g2'][2]))))

        friends.append(('L-function', data['lfunc_url']))

        # Breadcrumbs
        self.bread = bread = [('Genus 2 Curves', url_for(".index")),
                              (r'$\Q$', url_for(".index_Q")),
                              ('%s' % data['slabel'][0],
                               url_for(".by_conductor",
                                       cond=data['slabel'][0])),
                              ('%s' % data['slabel'][1],
                               url_for(".by_url_isogeny_class_label",
                                       cond=data['slabel'][0],
                                       alpha=data['slabel'][1]))]
        if is_curve:
            bread += [('%s' % data['slabel'][2],
                       url_for(".by_url_isogeny_class_discriminant",
                               cond=data['slabel'][0],
                               alpha=data['slabel'][1],
                               disc=data['slabel'][2])),
                      ('%s' % data['slabel'][3],
                       url_for(".by_url_curve_label",
                               cond=data['slabel'][0],
                               alpha=data['slabel'][1],
                               disc=data['slabel'][2],
                               num=data['slabel'][3]))]

        # Title
        self.title = "Genus 2 " + ("Curve " if is_curve else
                                   "Isogeny Class ") + data['label']

        # Code snippets (only for curves)
        if not is_curve:
            return
        self.code = code = {}
        code['show'] = {'sage': '', 'magma': ''}  # use default show names
        f, h = fh = data['min_eqn']
        g = simplify_hyperelliptic(fh)
        code['curve'] = {
            'sage':
            'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s));'
            % (f, h),
            'magma':
            'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);'
            % (f, h)
        }
        code['simple_curve'] = {
            'sage': 'X = HyperellipticCurve(R(%s))' % (g),
            'magma': 'X,pi:= SimplifiedModel(C);'
        }
        if data['abs_disc'] % 4096 == 0:
            ind2 = [a[0] for a in data['bad_lfactors']].index(2)
            bad2 = data['bad_lfactors'][ind2][1]
            magma_cond_option = ': ExcFactors:=[*<2,Valuation(' + str(
                data['cond']) + ',2),R!' + str(bad2) + '>*]'
        else:
            magma_cond_option = ''
        code['cond'] = {
            'magma':
            'Conductor(LSeries(C%s)); Factorization($1);' % magma_cond_option
        }
        code['disc'] = {
            'magma': 'Discriminant(C); Factorization(Integers()!$1);'
        }
        code['geom_inv'] = {
            'sage':
            'C.igusa_clebsch_invariants(); [factor(a) for a in _]',
            'magma':
            'IgusaClebschInvariants(C); IgusaInvariants(C); G2Invariants(C);'
        }
        code['aut'] = {'magma': 'AutomorphismGroup(C); IdentifyGroup($1);'}
        code['autQbar'] = {
            'magma':
            'AutomorphismGroup(ChangeRing(C,AlgebraicClosure(Rationals()))); IdentifyGroup($1);'
        }
        code['num_rat_wpts'] = {
            'magma': '#Roots(HyperellipticPolynomials(SimplifiedModel(C)));'
        }
        if ratpts:
            code['rat_pts'] = {
                'magma':
                '[' + ','.join([
                    "C![%s,%s,%s]" % (p[0], p[1], p[2])
                    for p in ratpts['rat_pts']
                ]) + '];'
            }
        code['mw_group'] = {'magma': 'MordellWeilGroupGenus2(Jacobian(C));'}
        code['two_selmer'] = {
            'magma': 'TwoSelmerGroup(Jacobian(C)); NumberOfGenerators($1);'
        }
        code['has_square_sha'] = {'magma': 'HasSquareSha(Jacobian(C));'}
        code['locally_solvable'] = {
            'magma':
            'f,h:=HyperellipticPolynomials(C); g:=4*f+h^2; HasPointsEverywhereLocally(g,2) and (#Roots(ChangeRing(g,RealField())) gt 0 or LeadingCoefficient(g) gt 0);'
        }
        code['torsion_subgroup'] = {
            'magma':
            'TorsionSubgroup(Jacobian(SimplifiedModel(C))); AbelianInvariants($1);'
        }
Esempio n. 39
0
def zfactor(n):
    return factor(n) if n != 0 else 0
Esempio n. 40
0
    def make_curve(self):
        # To start with the data fields of self are just those from the
        # databases.  We reformat these, while computing some further (easy)
        # data about the curve on the fly.

        # Initialize data:
        data = self.data = {}
        endodata = self.endodata = {}

        # Polish data from database before putting it into the data dictionary:
        disc = ZZ(self.disc_sign) * ZZ(self.disc_key[3:])
        # to deal with disc_key, uncomment line above and comment line below
        #disc = ZZ(self.disc_sign) * ZZ(self.abs_disc)
        data['disc'] = disc
        data['abs_disc'] = ZZ(self.disc_key[3:])
        data['cond'] = ZZ(self.cond)
        data['min_eqn'] = self.min_eqn
        data['min_eqn_display'] = list_to_min_eqn(self.min_eqn)
        data['disc_factor_latex'] = web_latex(factor(data['disc']))
        data['cond_factor_latex'] = web_latex(factor(int(self.cond)))
        data['aut_grp_id'] = self.aut_grp_id
        data['geom_aut_grp_id'] = self.geom_aut_grp_id
        data['igusa_clebsch'] = [ZZ(a) for a in self.igusa_clebsch]
        data['igusa'] = [ZZ(a) for a in self.igusa]
        data['g2'] = self.g2inv
        data['ic_norm'] = data['igusa_clebsch']
        data['igusa_norm'] = data['igusa']
        # Should we ever want to normalize the invariants further, then
        # uncomment the following lines:
        #data['ic_norm'] = normalize_invariants(data['igusa_clebsch'], [2, 4, 6,
        #    10])
        #data['igusa_norm'] = normalize_invariants(data['igusa'], [2, 4, 6, 8,
        #    10])
        data['ic_norm_factor_latex'] = [web_latex(zfactor(i)) for i in data['ic_norm']]
        data['igusa_norm_factor_latex'] = [ web_latex(zfactor(j)) for j in data['igusa_norm'] ]
        data['num_rat_wpts'] = ZZ(self.num_rat_wpts)
        data['two_selmer_rank'] = ZZ(self.two_selmer_rank)
        data['analytic_rank'] = ZZ(self.analytic_rank)
        data['has_square_sha'] = "square" if self.has_square_sha else "twice a square"
        data['locally_solvable'] = "yes" if self.locally_solvable else "no"
        if len(self.torsion) == 0:
            data['tor_struct'] = '\mathrm{trivial}'
        else:
            tor_struct = [ ZZ(a) for a in self.torsion ]
            data['tor_struct'] = ' \\times '.join([ '\Z/{%s}\Z' % n for n in tor_struct ])

        # Data derived from Sato-Tate group:
        isogeny_class = g2cdb().isogeny_classes.find_one({'label' : isogeny_class_label(self.label)})
        st_data = get_st_data(isogeny_class)
        for key in st_data.keys():
            data[key] = st_data[key]

        # GL_2 statement over the base field
        endodata['gl2_statement_base'] = \
            gl2_statement_base(self.factorsRR_base, r'\(\Q\)')

        # NOTE: In what follows there is some copying of code and data that is
        # stupid from the point of view of efficiency but likely better from
        # that of maintenance.

        # Endomorphism data over QQ:
        endodata['factorsQQ_base'] = self.factorsQQ_base
        endodata['factorsRR_base'] = self.factorsRR_base
        endodata['ring_base'] = self.ring_base
        endodata['endo_statement_base'] = \
            """Endomorphism ring over \(\Q\):""" + \
            endo_statement(endodata['factorsQQ_base'],
                endodata['factorsRR_base'], endodata['ring_base'], r'')
        # Field of definition data:
        endodata['fod_label'] = self.fod_label
        endodata['fod_poly'] = intlist_to_poly(self.fod_coeffs)
        endodata['fod_statement'] = fod_statement(endodata['fod_label'],
            endodata['fod_poly'])
        # Endomorphism data over QQbar:
        endodata['factorsQQ_geom'] = self.factorsQQ_geom
        endodata['factorsRR_geom'] = self.factorsRR_geom
        endodata['ring_geom'] = self.ring_geom
        if self.fod_label != '1.1.1.1':
            endodata['gl2_statement_geom'] = \
                gl2_statement_base(self.factorsRR_geom, r'\(\overline{\Q}\)')
            endodata['endo_statement_geom'] = \
                """Endomorphism ring over \(\overline{\Q}\):""" + \
                endo_statement(
                    endodata['factorsQQ_geom'],
                    endodata['factorsRR_geom'],
                    endodata['ring_geom'],
                    r'\overline{\Q}')

        # Full endomorphism lattice minus entries already treated:
        N = len(self.lattice)
        endodata['lattice'] = (self.lattice)[1:N - 1]
        if endodata['lattice']:
            endodata['lattice_statement_preamble'] = lattice_statement_preamble()
            endodata['lattice_statement'] = lattice_statement(endodata['lattice'])

        # Splitting field description:
        #endodata['is_simple_base'] = self.is_simple_base
        endodata['is_simple_geom'] = self.is_simple_geom
        endodata['spl_fod_label'] = self.spl_fod_label
        endodata['spl_fod_poly'] = intlist_to_poly(self.spl_fod_coeffs)
        endodata['spl_fod_statement'] = spl_fod_statement(
            endodata['is_simple_geom'],
            endodata['spl_fod_label'], endodata['spl_fod_poly'])

        # Isogeny factors:
        if not endodata['is_simple_geom']:
            endodata['spl_facs_coeffs'] = self.spl_facs_coeffs
            # This could be done non-uniformly as well... later.
            if len(self.spl_facs_labels) == len(self.spl_facs_coeffs):
                endodata['spl_facs_labels'] = self.spl_facs_labels
            else:
                endodata['spl_facs_labels'] = ['' for coeffs in
                    self.spl_facs_coeffs]
            endodata['spl_facs_condnorms'] = self.spl_facs_condnorms
            endodata['spl_statement'] = spl_statement(
                endodata['spl_facs_coeffs'],
                endodata['spl_facs_labels'],
                endodata['spl_facs_condnorms'])

        # Title
        self.title = "Genus 2 Curve %s" % (self.label)

        alpha = self.label.split('.')[1]
        num = self.label.split('.')[3]

        # Lady Gaga box
        self.plot = encode_plot(eqn_list_to_curve_plot(self.min_eqn))
        self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot
        self.properties = (
            ('Label', self.label),
            (None, self.plot_link),
            ('Conductor','%s' % self.cond),
            ('Discriminant', '%s' % data['disc']),
            ('Invariants', '%s </br> %s </br> %s </br> %s' % tuple(data['ic_norm'])),
            ('Sato-Tate group', data['st_group_href']),
            ('\(%s\)' % data['real_geom_end_alg_disp'][0],
             '\(%s\)' % data['real_geom_end_alg_disp'][1]),
            ('\(\mathrm{GL}_2\)-type','%s' % data['is_gl2_type_name'])
            )
        self.friends = [
            ('Isogeny class %s' % isogeny_class_label(self.label),
             url_for(".by_url_isogeny_class_label", cond = self.cond,alpha =alpha)),
            ('L-function', url_for("l_functions.l_function_genus2_page", cond=self.cond,x=alpha)),
            ('Twists', url_for(".index_Q", g20 = self.g2inv[0], g21 = self.g2inv[1], g22 = self.g2inv[2]))
            #('Siegel modular form someday', '.')
            ]

        if not endodata['is_simple_geom']:
            self.friends += [('Elliptic curve %s' % lab,url_for_ec(lab)) for lab in endodata['spl_facs_labels'] if lab != '']
        #self.downloads = [('Download all stored data', '.')]

        # Breadcrumbs
        self.bread = (
             ('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")),
             ('%s' % self.cond, url_for(".by_conductor", cond=self.cond)),
             ('%s' % alpha, url_for(".by_url_isogeny_class_label", cond=self.cond, alpha=alpha)),
             ('%s' % self.abs_disc, url_for(".by_url_isogeny_class_discriminant", cond=self.cond, alpha=alpha, disc=self.abs_disc)),
             ('%s' % num, url_for(".by_url_curve_label", cond=self.cond, alpha=alpha, disc=self.abs_disc, num=num))
             )

        # Make code that is used on the page:
        self.code = {}
        self.code['show'] = {'sage':'','magma':''} # use default show names
        self.code['curve'] = {'sage':'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s))'%(self.data['min_eqn'][0],self.data['min_eqn'][1]),
                              'magma':'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);'%(self.data['min_eqn'][0],self.data['min_eqn'][1])}
        if self.data['disc'] % 4096 == 0:
            ind2 = [a[0] for a in self.data['isogeny_class']['bad_lfactors']].index(2)
            bad2 = self.data['isogeny_class']['bad_lfactors'][ind2][1]
            magma_cond_option = ': ExcFactors:=[*<2,Valuation('+str(self.data['cond'])+',2),R!'+str(bad2)+'>*]'
        else:
            magma_cond_option = ''
        self.code['cond'] = {'magma': 'Conductor(LSeries(C%s)); Factorization($1);'% magma_cond_option}
        self.code['disc'] = {'magma':'Discriminant(C); Factorization(Integers()!$1);'}
        self.code['igusa_clebsch'] = {'sage':'C.igusa_clebsch_invariants(); [factor(a) for a in _]',
                                      'magma':'IgusaClebschInvariants(C); [Factorization(Integers()!a): a in $1];'}
        self.code['igusa'] = {'magma':'IgusaInvariants(C); [Factorization(Integers()!a): a in $1];'}
        self.code['g2'] = {'magma':'G2Invariants(C);'}
        self.code['aut'] = {'magma':'AutomorphismGroup(C); IdentifyGroup($1);'}
        self.code['autQbar'] = {'magma':'AutomorphismGroup(ChangeRing(C,AlgebraicClosure(Rationals()))); IdentifyGroup($1);'}
        self.code['num_rat_wpts'] = {'magma':'#Roots(HyperellipticPolynomials(SimplifiedModel(C)));'}
        self.code['two_selmer'] = {'magma':'TwoSelmerGroup(Jacobian(C)); NumberOfGenerators($1);'}
        self.code['has_square_sha'] = {'magma':'HasSquareSha(Jacobian(C));'}
        self.code['locally_solvable'] = {'magma':'f,h:=HyperellipticPolynomials(C); g:=4*f+h^2; HasPointsLocallyEverywhere(g,2) and (#Roots(ChangeRing(g,RealField())) gt 0 or LeadingCoefficient(g) gt 0);'}
        self.code['tor_struct'] = {'magma':'TorsionSubgroup(Jacobian(SimplifiedModel(C))); AbelianInvariants($1);'}
Esempio n. 41
0
def modn_exponent(n):
    """ given a nonzero integer n, returns the group exponent of (Z/nZ)* """
    return lcm([(p - 1) * p**(e - 1)
                for (p, e) in factor(n)]) // (1 if n % 8 else 2)
Esempio n. 42
0
    def make_object(self, curve, endo, tama, ratpts, is_curve):
        from lmfdb.genus2_curves.main import url_for_curve_label

        # all information about the curve, its Jacobian, isogeny class, and endomorphisms goes in the data dictionary
        # most of the data from the database gets polished/formatted before we put it in the data dictionary
        data = self.data = {}

        data['label'] = curve['label'] if is_curve else curve['class']
        data['slabel'] = data['label'].split('.')

        # set attributes common to curves and isogeny classes here
        data['Lhash'] = curve['Lhash']
        data['cond'] = ZZ(curve['cond'])
        data['cond_factor_latex'] = web_latex(factor(int(data['cond'])))
        data['analytic_rank'] = ZZ(curve['analytic_rank'])
        data['st_group'] = curve['st_group']
        data['st_group_link'] = st_link_by_name(1,4,data['st_group'])
        data['st0_group_name'] = st0_group_name(curve['real_geom_end_alg'])
        data['is_gl2_type'] = curve['is_gl2_type']
        data['root_number'] = ZZ(curve['root_number'])
        data['lfunc_url'] = url_for("l_functions.l_function_genus2_page", cond=data['slabel'][0], x=data['slabel'][1])
        data['bad_lfactors'] = literal_eval(curve['bad_lfactors'])
        data['bad_lfactors_pretty'] = [ (c[0], list_to_factored_poly_otherorder(c[1])) for c in data['bad_lfactors']]

        if is_curve:
            # invariants specific to curve
            data['class'] = curve['class']
            data['abs_disc'] = ZZ(curve['disc_key'][3:]) # use disc_key rather than abs_disc (will work when abs_disc > 2^63)
            data['disc'] = curve['disc_sign'] * curve['abs_disc']
            data['min_eqn'] = literal_eval(curve['eqn'])
            data['min_eqn_display'] = list_to_min_eqn(data['min_eqn'])
            data['disc_factor_latex'] = web_latex(factor(data['disc']))
            data['igusa_clebsch'] = [ZZ(a) for a in literal_eval(curve['igusa_clebsch_inv'])]
            data['igusa'] = [ZZ(a) for a in literal_eval(curve['igusa_inv'])]
            data['g2'] = [QQ(a) for a in literal_eval(curve['g2_inv'])]
            data['igusa_clebsch_factor_latex'] = [web_latex(zfactor(i)) for i in data['igusa_clebsch']]
            data['igusa_factor_latex'] = [ web_latex(zfactor(j)) for j in data['igusa'] ]
            data['aut_grp_id'] = curve['aut_grp_id']
            data['geom_aut_grp_id'] = curve['geom_aut_grp_id']
            data['num_rat_wpts'] = ZZ(curve['num_rat_wpts'])
            data['two_selmer_rank'] = ZZ(curve['two_selmer_rank'])
            data['has_square_sha'] = "square" if curve['has_square_sha'] else "twice a square"
            P = curve['non_solvable_places']
            if len(P):
                sz = "except over "
                sz += ", ".join([QpName(p) for p in P])
                last = " and"
                if len(P) > 2:
                    last = ", and"
                sz = last.join(sz.rsplit(",",1))
            else:
                sz = "everywhere"
            data['non_solvable_places'] = sz
            data['torsion_order'] = curve['torsion_order']
            data['torsion_factors'] = [ ZZ(a) for a in literal_eval(curve['torsion_subgroup']) ]
            if len(data['torsion_factors']) == 0:
                data['torsion_subgroup'] = '\mathrm{trivial}'
            else:
                data['torsion_subgroup'] = ' \\times '.join([ '\Z/{%s}\Z' % n for n in data['torsion_factors'] ])
            data['end_ring_base'] = endo['ring_base']
            data['end_ring_geom'] = endo['ring_geom']
            data['tama'] = ''
            for i in range(tama.count()):
            	item = tama.next()
            	if item['tamagawa_number'] > 0:
            		tamgwnr = str(item['tamagawa_number'])
            	else:
            		tamgwnr = 'N/A'
            	data['tama'] += tamgwnr + ' (p = ' + str(item['p']) + ')'
            	if (i+1 < tama.count()):
            		data['tama'] += ', '
            if ratpts:
                if len(ratpts['rat_pts']):
                    data['rat_pts'] = ',  '.join(web_latex('(' +' : '.join(P) + ')') for P in ratpts['rat_pts'])
                data['rat_pts_v'] =  2 if ratpts['rat_pts_v'] else 1
                # data['mw_rank'] = ratpts['mw_rank']
                # data['mw_rank_v'] = ratpts['mw_rank_v']
            else:
                data['rat_pts_v'] = 0
            if curve['two_torsion_field'][0]:
                data['two_torsion_field_knowl'] = nf_display_knowl (curve['two_torsion_field'][0], getDBConnection(), field_pretty(curve['two_torsion_field'][0]))
            else:
                t = curve['two_torsion_field']
                data['two_torsion_field_knowl'] = """splitting field of \(%s\) with Galois group %s"""%(intlist_to_poly(t[1]),group_display_knowl(t[2][0],t[2][1],getDBConnection()))
        else:
            # invariants specific to isogeny class
            curves_data = g2c_db_curves().find({"class" : curve['class']},{'_id':int(0),'label':int(1),'eqn':int(1),'disc_key':int(1)}).sort([("disc_key", ASCENDING), ("label", ASCENDING)])
            if not curves_data:
                raise KeyError("No curves found in database for isogeny class %s of genus 2 curve %s." %(curve['class'],curve['label']))
            data['curves'] = [ {"label" : c['label'], "equation_formatted" : list_to_min_eqn(literal_eval(c['eqn'])), "url": url_for_curve_label(c['label'])} for c in curves_data ]
            lfunc_data = g2c_db_lfunction_by_hash(curve['Lhash'])
            if not lfunc_data:
                raise KeyError("No Lfunction found in database for isogeny class of genus 2 curve %s." %curve['label'])
            if lfunc_data and lfunc_data.get('euler_factors'):
                data['good_lfactors'] = [[nth_prime(n+1),lfunc_data['euler_factors'][n]] for n in range(len(lfunc_data['euler_factors'])) if nth_prime(n+1) < 30 and (data['cond'] % nth_prime(n+1))]
                data['good_lfactors_pretty'] = [ (c[0], list_to_factored_poly_otherorder(c[1])) for c in data['good_lfactors']]
        # Endomorphism data over QQ:
        data['gl2_statement_base'] = gl2_statement_base(endo['factorsRR_base'], r'\(\Q\)')
        data['factorsQQ_base'] = endo['factorsQQ_base']
        data['factorsRR_base'] = endo['factorsRR_base']
        data['end_statement_base'] = """Endomorphism %s over \(\Q\):<br>""" %("ring" if is_curve else "algebra") + \
            end_statement(data['factorsQQ_base'], endo['factorsRR_base'], ring=data['end_ring_base'] if is_curve else None)

        # Field over which all endomorphisms are defined
        data['end_field_label'] = endo['fod_label']
        data['end_field_poly'] = intlist_to_poly(endo['fod_coeffs'])
        data['end_field_statement'] = end_field_statement(data['end_field_label'], data['end_field_poly'])
        
        # Endomorphism data over QQbar:
        data['factorsQQ_geom'] = endo['factorsQQ_geom']
        data['factorsRR_geom'] = endo['factorsRR_geom']
        if data['end_field_label'] != '1.1.1.1':
            data['gl2_statement_geom'] = gl2_statement_base(data['factorsRR_geom'], r'\(\overline{\Q}\)')
            data['end_statement_geom'] = """Endomorphism %s over \(\overline{\Q}\):""" %("ring" if is_curve else "algebra") + \
                end_statement(data['factorsQQ_geom'], data['factorsRR_geom'], field=r'\overline{\Q}', ring=data['end_ring_geom'] if is_curve else None)
        data['real_geom_end_alg_name'] = end_alg_name(curve['real_geom_end_alg'])

        # Endomorphism data over intermediate fields not already treated (only for curves, not necessarily isogeny invariant):
        if is_curve:
            data['end_lattice'] = (endo['lattice'])[1:-1]
            if data['end_lattice']:
                data['end_lattice_statement'] = end_lattice_statement(data['end_lattice'])

        # Field over which the Jacobian decomposes (base field if Jacobian is geometrically simple)
        data['is_simple_geom'] = endo['is_simple_geom']
        data['split_field_label'] = endo['spl_fod_label']
        data['split_field_poly'] = intlist_to_poly(endo['spl_fod_coeffs'])
        data['split_field_statement'] = split_field_statement(data['is_simple_geom'], data['split_field_label'], data['split_field_poly'])

        # Elliptic curve factors for non-simple Jacobians
        if not data['is_simple_geom']:
            data['split_coeffs'] = endo['spl_facs_coeffs']
            if 'spl_facs_labels' in endo and len(endo['spl_facs_labels']) == len(endo['spl_facs_coeffs']):
                data['split_labels'] = endo['spl_facs_labels']
            data['split_condnorms'] = endo['spl_facs_condnorms']
            data['split_statement'] = split_statement(data['split_coeffs'], data.get('split_labels'), data['split_condnorms'])

        # Properties
        self.properties = properties = [('Label', data['label'])]
        if is_curve:
            self.plot = encode_plot(eqn_list_to_curve_plot(data['min_eqn'], data['rat_pts'].split(',') if 'rat_pts' in data else []))
            plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format(self.plot)

            properties += [
                (None, plot_link),
                ('Conductor',str(data['cond'])),
                ('Discriminant', str(data['disc'])),
                ]
        properties += [
            ('Sato-Tate group', data['st_group_link']),
            ('\(\\End(J_{\\overline{\\Q}}) \\otimes \\R\)', '\(%s\)' % data['real_geom_end_alg_name']),
            ('\(\\overline{\\Q}\)-simple', bool_pretty(data['is_simple_geom'])),
            ('\(\mathrm{GL}_2\)-type', bool_pretty(data['is_gl2_type'])),
            ]

        # Friends
        self.friends = friends = [('L-function', data['lfunc_url'])]
        if is_curve:
            friends.append(('Isogeny class %s.%s' % (data['slabel'][0], data['slabel'][1]), url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1])))
        for friend in g2c_db_lfunction_instances().find({'Lhash':data['Lhash']},{'_id':False,'url':True}):
            if 'url' in friend:
                add_friend (friends, lfunction_friend_from_url(friend['url']))
            if 'urls' in friend:
                for url in friends['urls']:
                    add_friend (friends, lfunction_friend_from_url(friend['url']))
        if 'split_labels' in data:
            for friend_label in data['split_labels']:
                if is_curve:
                    add_friend (friends, ("Elliptic curve " + friend_label, url_for_ec(friend_label)))
                else:
                    add_friend (friends, ("EC isogeny class " + ec_label_class(friend_label), url_for_ec_class(friend_label)))
        if is_curve:
            friends.append(('Twists', url_for(".index_Q", g20 = str(data['g2'][0]), g21 = str(data['g2'][1]), g22 = str(data['g2'][2]))))

        # Breadcrumbs
        self.bread = bread = [
             ('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")),
             ('%s' % data['slabel'][0], url_for(".by_conductor", cond=data['slabel'][0])),
             ('%s' % data['slabel'][1], url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1]))
             ]
        if is_curve:
            bread += [
                ('%s' % data['slabel'][2], url_for(".by_url_isogeny_class_discriminant", cond=data['slabel'][0], alpha=data['slabel'][1], disc=data['slabel'][2])),
                ('%s' % data['slabel'][3], url_for(".by_url_curve_label", cond=data['slabel'][0], alpha=data['slabel'][1], disc=data['slabel'][2], num=data['slabel'][3]))
                ]

        # Title
        self.title = "Genus 2 " + ("Curve " if is_curve else "Isogeny Class ") + data['label']

        # Code snippets (only for curves)
        if not is_curve:
            return
        self.code = code = {}
        code['show'] = {'sage':'','magma':''} # use default show names
        code['curve'] = {'sage':'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s))'%(data['min_eqn'][0],data['min_eqn'][1]),
                              'magma':'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);'%(data['min_eqn'][0],data['min_eqn'][1])}
        if data['abs_disc'] % 4096 == 0:
            ind2 = [a[0] for a in data['bad_lfactors']].index(2)
            bad2 = data['bad_lfactors'][ind2][1]
            magma_cond_option = ': ExcFactors:=[*<2,Valuation('+str(data['cond'])+',2),R!'+str(bad2)+'>*]'
        else:
            magma_cond_option = ''
        code['cond'] = {'magma': 'Conductor(LSeries(C%s)); Factorization($1);'% magma_cond_option}
        code['disc'] = {'magma':'Discriminant(C); Factorization(Integers()!$1);'}
        code['igusa_clebsch'] = {'sage':'C.igusa_clebsch_invariants(); [factor(a) for a in _]',
                                      'magma':'IgusaClebschInvariants(C); [Factorization(Integers()!a): a in $1];'}
        code['igusa'] = {'magma':'IgusaInvariants(C); [Factorization(Integers()!a): a in $1];'}
        code['g2'] = {'magma':'G2Invariants(C);'}
        code['aut'] = {'magma':'AutomorphismGroup(C); IdentifyGroup($1);'}
        code['autQbar'] = {'magma':'AutomorphismGroup(ChangeRing(C,AlgebraicClosure(Rationals()))); IdentifyGroup($1);'}
        code['num_rat_wpts'] = {'magma':'#Roots(HyperellipticPolynomials(SimplifiedModel(C)));'}
        if ratpts:
            code['rat_pts'] = {'magma': '[' + ','.join(["C![%s,%s,%s]"%(p[0],p[1],p[2]) for p in ratpts['rat_pts']]) + '];' }
        code['two_selmer'] = {'magma':'TwoSelmerGroup(Jacobian(C)); NumberOfGenerators($1);'}
        code['has_square_sha'] = {'magma':'HasSquareSha(Jacobian(C));'}
        code['locally_solvable'] = {'magma':'f,h:=HyperellipticPolynomials(C); g:=4*f+h^2; HasPointsEverywhereLocally(g,2) and (#Roots(ChangeRing(g,RealField())) gt 0 or LeadingCoefficient(g) gt 0);'}
        code['torsion_subgroup'] = {'magma':'TorsionSubgroup(Jacobian(SimplifiedModel(C))); AbelianInvariants($1);'}
Esempio n. 43
0
def list_to_factored_poly(s):
    return str(factor(PolynomialRing(ZZ, 't')(s))).replace('*','')
Esempio n. 44
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()))
Esempio n. 45
0
    def coefficient_n_recursive(self, n):
        r"""
          Reimplement the recursive algorithm in sage modular/hecke/module.py
          We do this because of a bug in sage with .eigenvalue()
        """
        from sage.all import factor
        ev = self.eigenvalues

        c2 = self._coefficients.get(2)
        if c2 is not None:
            K = c2.parent()
        else:
            if ev.max_coefficient_in_db() >= 2:
                if not ev.has_eigenvalue(2):
                    ev.init_dynamic_properties()
            else:
                raise StopIteration,"Newform does not have eigenvalue a(2)!"
            self._coefficients[2]=ev[2]
            K = ev[2].parent()
        prod = K(1)
        if K.absolute_degree()>1 and K.is_relative():
            KZ = K.base_field()
        else:
            KZ = K
        #emf_logger.debug("K= {0}".format(K))
        F = factor(n)
        for p, r in F:
            #emf_logger.debug("parent_char_val[{0}]={1}".format(p,self.parent.character_used_in_computation.value(p)))
            #emf_logger.debug("char_val[{0}]={1}".format(p,self.character.value(p)))
            (p, r) = (int(p), int(r))
            pr = p**r
            cp = self._coefficients.get(p)
            if cp is None:
                if ev.has_eigenvalue(p):
                    cp = ev[p]
                elif ev.max_coefficient_in_db() >= p:
                    ev.init_dynamic_properties()
                    cp = ev[p]
            #emf_logger.debug("c{0} = {1}, parent={2}".format(p,cp,cp.parent()))
            if cp is None:
                raise IndexError,"p={0} is outside the range of computed primes (primes up to {1})! for label:{2}".format(p,max(ev.primes()),self.label)
            if self._coefficients.get(pr) is None:
                if r == 1:
                    c = cp
                else:
                    # a_{p^r} := a_p * a_{p^{r-1}} - eps(p)p^{k-1} a_{p^{r-2}}
                    apr1 = self.coefficient_n_recursive(pr//p)
                    #ap = self.coefficient_n_recursive(p)
                    apr2 = self.coefficient_n_recursive(pr//(p*p))
                    val = self.character.value(p)
                    if val == 0:
                        c = cp*apr1
                    else:
                        eps = KZ(val)
                        c = cp*apr1 - eps*(p**(self.weight-1)) * apr2
                    #emf_logger.debug("c({0})={1}".format(pr,c))
                            #ev[pr]=c
                self._coefficients[pr]=c
            try:
                prod *= K(self._coefficients[pr])
            except:
                if hasattr(self._coefficients[pr],'vector'):
                    if len(self._coefficients[pr].vector()) == len(K.power_basis()):
                        prod *= K(self._coefficients[pr].vector())
                    else:
                        emf_logger.debug("vec={0}".format(self._coefficients[pr].vector()))
                        raise ArithmeticError,"Wrong size of vectors!"
                else:
                    raise ArithmeticError,"Can not compute product of coefficients!"
            
        return prod
Esempio n. 46
0
    def make_curve(self):
        # To start with the data fields of self are just those from
        # the database.  We need to reformat these, construct the
        # and compute some further (easy) data about it.
        #

        # Weierstrass equation

        data = self.data = {}

        disc = ZZ(self.disc_sign) * ZZ(self.disc_key[3:]) 
        # to deal with disc_key, uncomment line above and remove line below
        #disc = ZZ(self.disc_sign) * ZZ(self.abs_disc)
        data['disc'] = disc
        data['cond'] = ZZ(self.cond)
        data['min_eqn'] = list_to_min_eqn(self.min_eqn)
        data['disc_factor_latex'] = web_latex(factor(data['disc']))
        data['cond_factor_latex'] = web_latex(factor(int(self.cond)))
        data['aut_grp'] = groupid_to_meaningful(self.aut_grp)
        data['geom_aut_grp'] = groupid_to_meaningful(self.geom_aut_grp)
        data['igusa_clebsch'] = [ZZ(a)  for a in self.igusa_clebsch]
        if len(self.torsion) == 0:
            data['tor_struct'] = '\mathrm{trivial}'
        else:
            tor_struct = [ZZ(a)  for a in self.torsion]
            data['tor_struct'] = ' \\times '.join(['\Z/{%s}\Z' % n for n in tor_struct])
        isogeny_class = db_g2c().isogeny_classes.find_one({'label' : isog_label(self.label)})

        for endalgtype in ['end_ring', 'rat_end_alg', 'real_end_alg', 'geom_end_ring', 'rat_geom_end_alg', 'real_geom_end_alg']:
            if endalgtype in isogeny_class:
                data[endalgtype + '_name'] = end_alg_name(isogeny_class[endalgtype])
            else:
                data[endalgtype + '_name'] = ''

        data['geom_end_field'] = isogeny_class['geom_end_field']
        if data['geom_end_field'] <> '':
            data['geom_end_field_name'] = field_pretty(data['geom_end_field'])
        else:
            data['geom_end_field_name'] = ''        

        data['st_group_name'] = st_group_name(isogeny_class['st_group'])
        if isogeny_class['is_gl2_type']:
            data['is_gl2_type_name'] = 'yes'
        else:
            data['is_gl2_type_name'] = 'no'
        if 'is_simple' in isogeny_class:
            if isogeny_class['is_simple']:
                data['is_simple_name'] = 'yes'
            else:
                data['is_simple_name'] = 'no'
        else:
            data['is_simple_name'] = '?'
        if 'is_geom_simple' in isogeny_class:
            if isogeny_class['is_geom_simple']:
                data['is_geom_simple_name'] = 'yes'
            else:
                data['is_geom_simple_name'] = 'no'
        else:
            data['is_geom_simple_name'] = '?'

        x = self.label.split('.')[1]
        self.friends = [
            ('Isogeny class %s' % isog_label(self.label), url_for(".by_double_iso_label", conductor = self.cond, iso_label = x)),
            ('L-function', url_for("l_functions.l_function_genus2_page", cond=self.cond,x=x)),
            ('Siegel modular form someday', '.')]
        self.downloads = [
             ('Download Euler factors', '.')]
        iso = self.label.split('.')[1]
        num = '.'.join(self.label.split('.')[2:4])
        self.plot = encode_plot(eqn_list_to_curve_plot(self.min_eqn))
        self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot
        self.properties = [('Label', self.label),
                           (None, self.plot_link),
                           ('Conductor','%s' % self.cond),
                           ('Discriminant', '%s' % data['disc']),
                           ('Invariants', '%s </br> %s </br> %s </br> %s'% tuple(data['igusa_clebsch'])), 
                           ('Sato-Tate group', '\(%s\)' % data['st_group_name']), 
                           ('\(\mathrm{End}(J_{\overline{\Q}}) \otimes \R\)','\(%s\)' % data['real_geom_end_alg_name']),
                           ('\(\mathrm{GL}_2\)-type','%s' % data['is_gl2_type_name'])]
        self.title = "Genus 2 Curve %s" % (self.label)
        self.bread = [
             ('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")),
             ('%s' % self.cond, url_for(".by_conductor", conductor=self.cond)),
             ('%s' % iso, url_for(".by_double_iso_label", conductor=self.cond, iso_label=iso)),
             ('Genus 2 curve %s' % num, url_for(".by_g2c_label", label=self.label))]
Esempio n. 47
0
    def make_object(self, curve, endo, is_curve):
        from lmfdb.genus2_curves.main import url_for_curve_label

        # all information about the curve, its Jacobian, isogeny class, and endomorphisms goes in the data dictionary
        # most of the data from the database gets polished/formatted before we put it in the data dictionary
        data = self.data = {}

        data['label'] = curve['label'] if is_curve else curve['class']
        data['slabel'] = data['label'].split('.')

        # set attributes common to curves and isogeny classes here
        data['Lhash'] = curve['Lhash']
        data['cond'] = ZZ(curve['cond'])
        data['cond_factor_latex'] = web_latex(factor(int(data['cond'])))
        data['analytic_rank'] = ZZ(curve['analytic_rank'])
        data['st_group'] = curve['st_group']
        data['st_group_link'] = st_link_by_name(1, 4, data['st_group'])
        data['st0_group_name'] = st0_group_name(curve['real_geom_end_alg'])
        data['is_gl2_type'] = curve['is_gl2_type']
        data['root_number'] = ZZ(curve['root_number'])
        data['lfunc_url'] = url_for("l_functions.l_function_genus2_page",
                                    cond=data['slabel'][0],
                                    x=data['slabel'][1])
        data['bad_lfactors'] = literal_eval(curve['bad_lfactors'])
        data['bad_lfactors_pretty'] = [(c[0],
                                        list_to_factored_poly_otherorder(c[1]))
                                       for c in data['bad_lfactors']]

        if is_curve:
            # invariants specific to curve
            data['class'] = curve['class']
            data['abs_disc'] = ZZ(
                curve['disc_key'][3:]
            )  # use disc_key rather than abs_disc (will work when abs_disc > 2^63)
            data['disc'] = curve['disc_sign'] * curve['abs_disc']
            data['min_eqn'] = literal_eval(curve['eqn'])
            data['min_eqn_display'] = list_to_min_eqn(data['min_eqn'])
            data['disc_factor_latex'] = web_latex(factor(data['disc']))
            data['igusa_clebsch'] = [
                ZZ(a) for a in literal_eval(curve['igusa_clebsch_inv'])
            ]
            data['igusa'] = [ZZ(a) for a in literal_eval(curve['igusa_inv'])]
            data['g2'] = [QQ(a) for a in literal_eval(curve['g2_inv'])]
            data['igusa_clebsch_factor_latex'] = [
                web_latex(zfactor(i)) for i in data['igusa_clebsch']
            ]
            data['igusa_factor_latex'] = [
                web_latex(zfactor(j)) for j in data['igusa']
            ]
            data['aut_grp_id'] = curve['aut_grp_id']
            data['geom_aut_grp_id'] = curve['geom_aut_grp_id']
            data['num_rat_wpts'] = ZZ(curve['num_rat_wpts'])
            data['two_selmer_rank'] = ZZ(curve['two_selmer_rank'])
            data['has_square_sha'] = "square" if curve[
                'has_square_sha'] else "twice a square"
            data['locally_solvable'] = "yes" if curve[
                'locally_solvable'] else "no"
            data['torsion_order'] = curve['torsion_order']
            data['torsion_factors'] = [
                ZZ(a) for a in literal_eval(curve['torsion_subgroup'])
            ]
            if len(data['torsion_factors']) == 0:
                data['torsion_subgroup'] = '\mathrm{trivial}'
            else:
                data['torsion_subgroup'] = ' \\times '.join(
                    ['\Z/{%s}\Z' % n for n in data['torsion_factors']])
            data['end_ring_base'] = endo['ring_base']
            data['end_ring_geom'] = endo['ring_geom']
        else:
            # invariants specific to isogeny class
            curves_data = g2c_db_curves().find({
                "class": curve['class']
            }, {
                '_id': int(0),
                'label': int(1),
                'eqn': int(1),
                'disc_key': int(1)
            }).sort([("disc_key", ASCENDING), ("label", ASCENDING)])
            if not curves_data:
                raise KeyError(
                    "No curves found in database for isogeny class %s of genus 2 curve %s."
                    % (curve['class'], curve['label']))
            data['curves'] = [{
                "label":
                c['label'],
                "equation_formatted":
                list_to_min_eqn(literal_eval(c['eqn'])),
                "url":
                url_for_curve_label(c['label'])
            } for c in curves_data]
            lfunc_data = g2c_db_lfunction_by_hash(curve['Lhash'])
            if not lfunc_data:
                raise KeyError(
                    "No Lfunction found in database for isogeny class of genus 2 curve %s."
                    % curve['label'])
            if lfunc_data and lfunc_data.get('euler_factors'):
                data['good_lfactors'] = [
                    [nth_prime(n + 1), lfunc_data['euler_factors'][n]]
                    for n in range(len(lfunc_data['euler_factors']))
                    if nth_prime(n + 1) < 30 and (data['cond'] %
                                                  nth_prime(n + 1))
                ]
                data['good_lfactors_pretty'] = [
                    (c[0], list_to_factored_poly_otherorder(c[1]))
                    for c in data['good_lfactors']
                ]
        # Endomorphism data over QQ:
        data['gl2_statement_base'] = gl2_statement_base(
            endo['factorsRR_base'], r'\(\Q\)')
        data['factorsQQ_base'] = endo['factorsQQ_base']
        data['factorsRR_base'] = endo['factorsRR_base']
        data['end_statement_base'] = """Endomorphism %s over \(\Q\):<br>""" %("ring" if is_curve else "algebra") + \
            end_statement(data['factorsQQ_base'], endo['factorsRR_base'], ring=data['end_ring_base'] if is_curve else None)

        # Field over which all endomorphisms are defined
        data['end_field_label'] = endo['fod_label']
        data['end_field_poly'] = intlist_to_poly(endo['fod_coeffs'])
        data['end_field_statement'] = end_field_statement(
            data['end_field_label'], data['end_field_poly'])

        # Endomorphism data over QQbar:
        data['factorsQQ_geom'] = endo['factorsQQ_geom']
        data['factorsRR_geom'] = endo['factorsRR_geom']
        if data['end_field_label'] != '1.1.1.1':
            data['gl2_statement_geom'] = gl2_statement_base(
                data['factorsRR_geom'], r'\(\overline{\Q}\)')
            data['end_statement_geom'] = """Endomorphism %s over \(\overline{\Q}\):""" %("ring" if is_curve else "algebra") + \
                end_statement(data['factorsQQ_geom'], data['factorsRR_geom'], field=r'\overline{\Q}', ring=data['end_ring_geom'] if is_curve else None)
        data['real_geom_end_alg_name'] = end_alg_name(
            curve['real_geom_end_alg'])

        # Endomorphism data over intermediate fields not already treated (only for curves, not necessarily isogeny invariant):
        if is_curve:
            data['end_lattice'] = (endo['lattice'])[1:-1]
            if data['end_lattice']:
                data['end_lattice_statement'] = end_lattice_statement(
                    data['end_lattice'])

        # Field over which the Jacobian decomposes (base field if Jacobian is geometrically simple)
        data['is_simple_geom'] = endo['is_simple_geom']
        data['split_field_label'] = endo['spl_fod_label']
        data['split_field_poly'] = intlist_to_poly(endo['spl_fod_coeffs'])
        data['split_field_statement'] = split_field_statement(
            data['is_simple_geom'], data['split_field_label'],
            data['split_field_poly'])

        # Elliptic curve factors for non-simple Jacobians
        if not data['is_simple_geom']:
            data['split_coeffs'] = endo['spl_facs_coeffs']
            if 'spl_facs_labels' in endo and len(
                    endo['spl_facs_labels']) == len(endo['spl_facs_coeffs']):
                data['split_labels'] = endo['spl_facs_labels']
            data['split_condnorms'] = endo['spl_facs_condnorms']
            data['split_statement'] = split_statement(data['split_coeffs'],
                                                      data.get('split_labels'),
                                                      data['split_condnorms'])

        # Properties
        self.properties = properties = [('Label', data['label'])]
        if is_curve:
            self.plot = encode_plot(eqn_list_to_curve_plot(data['min_eqn']))
            plot_link = '<img src="%s" width="200" height="150"/>' % self.plot
            properties += [
                (None, plot_link),
                ('Conductor', str(data['cond'])),
                ('Discriminant', str(data['disc'])),
            ]
        properties += [
            ('Sato-Tate group', data['st_group_link']),
            ('\(\\End(J_{\\overline{\\Q}}) \\otimes \\R\)',
             '\(%s\)' % data['real_geom_end_alg_name']),
            ('\(\\overline{\\Q}\)-simple',
             bool_pretty(data['is_simple_geom'])),
            ('\(\mathrm{GL}_2\)-type', bool_pretty(data['is_gl2_type'])),
        ]

        # Friends
        self.friends = friends = [('L-function', data['lfunc_url'])]
        if is_curve:
            friends.append(('Isogeny class %s.%s' %
                            (data['slabel'][0], data['slabel'][1]),
                            url_for(".by_url_isogeny_class_label",
                                    cond=data['slabel'][0],
                                    alpha=data['slabel'][1])))
        for friend in g2c_db_lfunction_instances().find(
            {'Lhash': data['Lhash']}, {
                '_id': False,
                'url': True
            }):
            if 'url' in friend:
                add_friend(friends, lfunction_friend_from_url(friend['url']))
            if 'urls' in friend:
                for url in friends['urls']:
                    add_friend(friends,
                               lfunction_friend_from_url(friend['url']))
        if 'split_labels' in data:
            for friend_label in data['split_labels']:
                if is_curve:
                    add_friend(friends, ("Elliptic curve " + friend_label,
                                         url_for_ec(friend_label)))
                else:
                    add_friend(
                        friends,
                        ("EC isogeny class " + ec_label_class(friend_label),
                         url_for_ec_class(friend_label)))
        if is_curve:
            friends.append(('Twists',
                            url_for(".index_Q",
                                    g20=str(data['g2'][0]),
                                    g21=str(data['g2'][1]),
                                    g22=str(data['g2'][2]))))

        # Breadcrumbs
        self.bread = bread = [('Genus 2 Curves', url_for(".index")),
                              ('$\Q$', url_for(".index_Q")),
                              ('%s' % data['slabel'][0],
                               url_for(".by_conductor",
                                       cond=data['slabel'][0])),
                              ('%s' % data['slabel'][1],
                               url_for(".by_url_isogeny_class_label",
                                       cond=data['slabel'][0],
                                       alpha=data['slabel'][1]))]
        if is_curve:
            bread += [('%s' % data['slabel'][2],
                       url_for(".by_url_isogeny_class_discriminant",
                               cond=data['slabel'][0],
                               alpha=data['slabel'][1],
                               disc=data['slabel'][2])),
                      ('%s' % data['slabel'][3],
                       url_for(".by_url_curve_label",
                               cond=data['slabel'][0],
                               alpha=data['slabel'][1],
                               disc=data['slabel'][2],
                               num=data['slabel'][3]))]

        # Title
        self.title = "Genus 2 " + ("Curve " if is_curve else
                                   "Isogeny Class ") + data['label']

        # Code snippets (only for curves)
        if not is_curve:
            return
        self.code = code = {}
        code['show'] = {'sage': '', 'magma': ''}  # use default show names
        code['curve'] = {
            'sage':
            'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s))'
            % (data['min_eqn'][0], data['min_eqn'][1]),
            'magma':
            'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);'
            % (data['min_eqn'][0], data['min_eqn'][1])
        }
        if data['abs_disc'] % 4096 == 0:
            ind2 = [a[0] for a in data['bad_lfactors']].index(2)
            bad2 = data['bad_lfactors'][ind2][1]
            magma_cond_option = ': ExcFactors:=[*<2,Valuation(' + str(
                data['cond']) + ',2),R!' + str(bad2) + '>*]'
        else:
            magma_cond_option = ''
        code['cond'] = {
            'magma':
            'Conductor(LSeries(C%s)); Factorization($1);' % magma_cond_option
        }
        code['disc'] = {
            'magma': 'Discriminant(C); Factorization(Integers()!$1);'
        }
        code['igusa_clebsch'] = {
            'sage':
            'C.igusa_clebsch_invariants(); [factor(a) for a in _]',
            'magma':
            'IgusaClebschInvariants(C); [Factorization(Integers()!a): a in $1];'
        }
        code['igusa'] = {
            'magma':
            'IgusaInvariants(C); [Factorization(Integers()!a): a in $1];'
        }
        code['g2'] = {'magma': 'G2Invariants(C);'}
        code['aut'] = {'magma': 'AutomorphismGroup(C); IdentifyGroup($1);'}
        code['autQbar'] = {
            'magma':
            'AutomorphismGroup(ChangeRing(C,AlgebraicClosure(Rationals()))); IdentifyGroup($1);'
        }
        code['num_rat_wpts'] = {
            'magma': '#Roots(HyperellipticPolynomials(SimplifiedModel(C)));'
        }
        code['two_selmer'] = {
            'magma': 'TwoSelmerGroup(Jacobian(C)); NumberOfGenerators($1);'
        }
        code['has_square_sha'] = {'magma': 'HasSquareSha(Jacobian(C));'}
        code['locally_solvable'] = {
            'magma':
            'f,h:=HyperellipticPolynomials(C); g:=4*f+h^2; HasPointsLocallyEverywhere(g,2) and (#Roots(ChangeRing(g,RealField())) gt 0 or LeadingCoefficient(g) gt 0);'
        }
        code['torsion_subgroup'] = {
            'magma':
            'TorsionSubgroup(Jacobian(SimplifiedModel(C))); AbelianInvariants($1);'
        }
Esempio n. 48
0
    def make_curve(self):
        # To start with the data fields of self are just those from the
        # databases.  We reformat these, while computing some further (easy)
        # data about the curve on the fly.

        # Initialize data:
        data = self.data = {}
        endodata = self.endodata = {}

        # Polish data from database before putting it into the data dictionary:
        disc = ZZ(self.disc_sign) * ZZ(self.disc_key[3:])
        # to deal with disc_key, uncomment line above and comment line below
        #disc = ZZ(self.disc_sign) * ZZ(self.abs_disc)
        data['disc'] = disc
        data['cond'] = ZZ(self.cond)
        data['min_eqn'] = self.min_eqn
        data['min_eqn_display'] = list_to_min_eqn(self.min_eqn)
        data['disc_factor_latex'] = web_latex(factor(data['disc']))
        data['cond_factor_latex'] = web_latex(factor(int(self.cond)))
        data['aut_grp'] = groupid_to_meaningful(self.aut_grp)
        data['geom_aut_grp'] = groupid_to_meaningful(self.geom_aut_grp)
        data['igusa_clebsch'] = [ZZ(a) for a in self.igusa_clebsch]
        data['igusa'] = [ZZ(a) for a in self.igusa]
        data['g2'] = self.g2inv
        data['ic_norm'] = data['igusa_clebsch']
        data['igusa_norm'] = data['igusa']
        # Should we ever want to normalize the invariants further, then
        # uncomment the following lines:
        #data['ic_norm'] = normalize_invariants(data['igusa_clebsch'], [2, 4, 6,
        #    10])
        #data['igusa_norm'] = normalize_invariants(data['igusa'], [2, 4, 6, 8,
        #    10])
        data['ic_norm_factor_latex'] = [
            web_latex(zfactor(i)) for i in data['ic_norm']
        ]
        data['igusa_norm_factor_latex'] = [
            web_latex(zfactor(j)) for j in data['igusa_norm']
        ]
        data['num_rat_wpts'] = ZZ(self.num_rat_wpts)
        data['two_selmer_rank'] = ZZ(self.two_selmer_rank)
        if len(self.torsion) == 0:
            data['tor_struct'] = '\mathrm{trivial}'
        else:
            tor_struct = [ZZ(a) for a in self.torsion]
            data['tor_struct'] = ' \\times '.join(
                ['\Z/{%s}\Z' % n for n in tor_struct])

        # Data derived from Sato-Tate group:
        isogeny_class = db_g2c().isogeny_classes.find_one(
            {'label': isog_label(self.label)})
        st_data = get_st_data(isogeny_class)
        for key in st_data.keys():
            data[key] = st_data[key]

        # GL_2 statement over the base field
        endodata['gl2_statement_base'] = \
            gl2_statement_base(self.factorsRR_base, r'\(\Q\)')

        # NOTE: In what follows there is some copying of code and data that is
        # stupid from the point of view of efficiency but likely better from
        # that of maintenance.

        # Endomorphism data over QQ:
        endodata['factorsQQ_base'] = self.factorsQQ_base
        endodata['factorsRR_base'] = self.factorsRR_base
        endodata['ring_base'] = self.ring_base
        endodata['endo_statement_base'] = \
            """Endomorphism ring over \(\Q\):""" + \
            endo_statement(endodata['factorsQQ_base'],
                endodata['factorsRR_base'], endodata['ring_base'], r'')
        # Field of definition data:
        endodata['fod_label'] = self.fod_label
        endodata['fod_poly'] = intlist_to_poly(self.fod_coeffs)
        endodata['fod_statement'] = fod_statement(endodata['fod_label'],
                                                  endodata['fod_poly'])
        # Endomorphism data over QQbar:
        endodata['factorsQQ_geom'] = self.factorsQQ_geom
        endodata['factorsRR_geom'] = self.factorsRR_geom
        endodata['ring_geom'] = self.ring_geom
        if self.fod_label != '1.1.1.1':
            endodata['gl2_statement_geom'] = \
                gl2_statement_base(self.factorsRR_geom, r'\(\overline{\Q}\)')
            endodata['endo_statement_geom'] = \
            """Endomorphism ring over \(\overline{\Q}\):""" + \
            endo_statement(endodata['factorsQQ_geom'],
                endodata['factorsRR_geom'], endodata['ring_geom'],
                r'\overline{\Q}')

        # Full endomorphism lattice minus entries already treated:
        N = len(self.lattice)
        endodata['lattice'] = (self.lattice)[1:N - 1]
        if endodata['lattice']:
            endodata['lattice_statement_preamble'] = \
                lattice_statement_preamble()
            endodata['lattice_statement'] = \
                lattice_statement(endodata['lattice'])

        # Splitting field description:
        #endodata['is_simple_base'] = self.is_simple_base
        endodata['is_simple_geom'] = self.is_simple_geom
        endodata['spl_fod_label'] = self.spl_fod_label
        endodata['spl_fod_poly'] = intlist_to_poly(self.spl_fod_coeffs)
        endodata['spl_fod_statement'] = \
            spl_fod_statement(endodata['is_simple_geom'],
                endodata['spl_fod_label'], endodata['spl_fod_poly'])

        # Isogeny factors:
        if not endodata['is_simple_geom']:
            endodata['spl_facs_coeffs'] = self.spl_facs_coeffs
            # This could be done non-uniformly as well... later.
            if len(self.spl_facs_labels) == len(self.spl_facs_coeffs):
                endodata['spl_facs_labels'] = self.spl_facs_labels
            else:
                endodata['spl_facs_labels'] = [
                    '' for coeffs in self.spl_facs_coeffs
                ]
            endodata['spl_facs_condnorms'] = self.spl_facs_condnorms
            endodata['spl_statement'] = \
                spl_statement(endodata['spl_facs_coeffs'],
                    endodata['spl_facs_labels'],
                    endodata['spl_facs_condnorms'])

        # Title
        self.title = "Genus 2 Curve %s" % (self.label)

        # Lady Gaga box
        self.plot = encode_plot(eqn_list_to_curve_plot(self.min_eqn))
        self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot
        self.properties = [
            ('Label', self.label), (None, self.plot_link),
            ('Conductor', '%s' % self.cond),
            ('Discriminant', '%s' % data['disc']),
            ('Invariants',
             '%s </br> %s </br> %s </br> %s' % tuple(data['ic_norm'])),
            ('Sato-Tate group', '\(%s\)' % data['st_group_name']),
            ('\(%s\)' % data['real_geom_end_alg_disp'][0],
             '\(%s\)' % data['real_geom_end_alg_disp'][1]),
            ('\(\mathrm{GL}_2\)-type', '%s' % data['is_gl2_type_name'])
        ]
        x = self.label.split('.')[1]
        self.friends = [
            ('Isogeny class %s' % isog_label(self.label),
             url_for(".by_double_iso_label", conductor=self.cond,
                     iso_label=x)),
            ('L-function',
             url_for("l_functions.l_function_genus2_page", cond=self.cond,
                     x=x)),
            ('Twists',
             url_for(".index_Q",
                     g20=self.g2inv[0],
                     g21=self.g2inv[1],
                     g22=self.g2inv[2]))
            #('Twists2',
            #   url_for(".index_Q",
            #       igusa_clebsch = str(self.igusa_clebsch)))  #doesn't work.
            #('Siegel modular form someday', '.')
        ]
        self.downloads = [('Download all stored data', '.')]

        # Breadcrumbs
        iso = self.label.split('.')[1]
        num = '.'.join(self.label.split('.')[2:4])
        self.bread = [('Genus 2 Curves', url_for(".index")),
                      ('$\Q$', url_for(".index_Q")),
                      ('%s' % self.cond,
                       url_for(".by_conductor", conductor=self.cond)),
                      ('%s' % iso,
                       url_for(".by_double_iso_label",
                               conductor=self.cond,
                               iso_label=iso)),
                      ('Genus 2 curve %s' % num,
                       url_for(".by_g2c_label", label=self.label))]

        # Make code that is used on the page:
        self.make_code_snippets()
Esempio n. 49
0
 def enum_points(I):
     possibleValues = get_elements()
     R = I.ring()
     F = R.base()
     ch = F.characteristic()
     n = R.ngens()
     if n == 0:
         if I.is_zero():
             yield []
         return
     if I.is_one():
         return
     if all(map(lambda _: _.degree() == 1,
                I.gens())) and (ch > 0 or I.dimension() == 0):
         # solve using linear algebra
         f = R.hom(n * [0], F)
         A = matrix([f(g.coefficient(xi)) for xi in R.gens()]
                    for g in I.gens())
         b = vector(-g.constant_coefficient() for g in I.gens())
         v0 = A.solve_right(b)
         r = A.rank()
         if r == n:
             yield list(v0)
         else:
             K = A.right_kernel().matrix()
             for v in F**(n - r):
                 yield list(v * K + v0)
         return
     if ch > 0 and I.is_homogeneous():
         yield [F(0)] * n
         for pt in enum_proj_points(I):
             for sca in get_elements():
                 if sca != 0:
                     yield [x * sca for x in pt]
         return
     elim = I.elimination_ideal(I.ring().gens()[1:])
     g = elim.gens()[0]
     if g != 0:
         S = F['u']
         pr1 = R.hom([S.gen()] + [0] * (n - 1), S)
         possibleValues = (v[0] for v in pr1(g).roots() if bound == None or
                           global_height([v[0], F(1)]) <= bound + tolerance)
         if split:
             nonSplit = (f[0] for f in factor(pr1(g)) if f[0].degree() > 1)
             for f in nonSplit:
                 if ch == 0:
                     F_ = f.splitting_field('a')
                     # `polredbest` from PARI/GP, improves performance significantly
                     f = gen_to_sage(
                         pari(F_.gen().minpoly('x')).polredbest(),
                         {'x': S.gen()})
                 F_ = f.splitting_field('a')
                 R_ = PolynomialRing(F_, 'x', n)
                 I = R_.ideal(
                     [f.change_ring(base_change(F, F_)) for f in I.gens()])
                 for pt in enum_points(I):
                     yield pt
                 return
     R_ = PolynomialRing(F, 'x', n - 1)
     if n == 1:
         for v in possibleValues:
             yield [v]
     else:
         for v in possibleValues:
             pr2 = R.hom([v] + list(R_.gens()), R_)
             for rest in enum_points(pr2(I)):
                 yield [v] + rest
Esempio n. 50
0
def main5():
    n = 32295194023343
    e = 29468811804857
    d = 11127763319273
    print(crack_given_decrypt(n, e * d - 1))
    print(factor(n))
Esempio n. 51
0
def list_to_factored_poly_otherorder(s, galois=False, vari = 'T'):
    """ Either return the polynomial in a nice factored form,
        or return a pair, with first entry the factored polynomial
        and the second entry a list describing the Galois groups
        of the factors.
        vari allows to choose the variable of the polynomial to be returned.
    """
    gal_list=[]
    if len(s) == 1:
        if galois:
            return [str(s[0]), [[0,0]]]
        return str(s[0])
    sfacts = factor(PolynomialRing(ZZ, 'T')(s))
    sfacts_fc = [[v[0],v[1]] for v in sfacts]
    if sfacts.unit() == -1:
        sfacts_fc[0][0] *= -1
    outstr = ''
    x = var('x')
    for v in sfacts_fc:
        this_poly = v[0]
        # if the factor is -1+T^2, replace it by 1-T^2
        # this should happen an even number of times, mod powers
        if this_poly.substitute(T=0) == -1:
            this_poly = -1*this_poly
            v[0] = this_poly
        if galois:
            this_degree = this_poly.degree()
                # hack because currently sage only handles monic polynomials:
            this_poly = expand(x**this_degree*this_poly.substitute(T=1/x))
            this_number_field = NumberField(this_poly, "a")
            this_gal = this_number_field.galois_group(type='pari')
            this_t_number = this_gal.group().__pari__()[2].sage()
            gal_list.append([this_degree, this_t_number])
        vcf = v[0].list()
        started = False
        if len(sfacts) > 1 or v[1] > 1:
            outstr += '('
        for i in range(len(vcf)):
            if vcf[i] != 0:
                if started and vcf[i] > 0:
                    outstr += '+'
                started = True
                if i == 0:
                    outstr += str(vcf[i])
                else:
                    if abs(vcf[i]) != 1:
                        outstr += str(vcf[i])
                    elif vcf[i] == -1:
                        outstr += '-'
                    if i == 1:
                        outstr += vari #instead of putting in T for the variable, put in a variable of your choice
                    elif i > 1:
                        outstr += vari + '^{' + str(i) + '}'
        if len(sfacts) > 1 or v[1] > 1:
            outstr += ')'
        if v[1] > 1:
            outstr += '^{' + str(v[1]) + '}'
    if galois:
        if galois and len(sfacts_fc)==2:
            if sfacts[0][0].degree()==2 and sfacts[1][0].degree()==2:
                troubletest = sfacts[0][0].disc()*sfacts[1][0].disc()
                if troubletest.is_square():
                    gal_list=[[2,1]]
        return [outstr, gal_list]
    return outstr
Esempio n. 52
0
    def general_webpagedata(self):
        info = {}
        try:
            info['support'] = self.support
        except AttributeError:
            info['support'] = ''

        info['Ltype'] = self.Ltype()
        info['label'] = self.label
        info['credit'] = self.credit

        info['degree'] = int(self.degree)
        info['conductor'] = self.level
        if not is_prime(int(self.level)):
            info['conductor_factored'] = latex(factor(int(self.level)))

        info['sign'] = "$" + styleTheSign(self.sign) + "$"
        info['algebraic'] = self.algebraic
        if self.selfdual:
            info['selfdual'] = 'yes'
        else:
            info['selfdual'] = 'no'
        if self.primitive:
            info['primitive'] = 'yes'
        else:
            info['primitive'] = 'no'
        info['dirichlet'] = lfuncDShtml(self, "analytic")
        # Hack, fix this more general?
        info['dirichlet'] = info['dirichlet'].replace('*I','<em>i</em>')
        
        info['eulerproduct'] = lfuncEPtex(self, "abstract")
        info['functionalequation'] = lfuncFEtex(self, "analytic")
        info['functionalequationSelberg'] = lfuncFEtex(self, "selberg")

        if hasattr(self, 'positive_zeros'):
            info['positive_zeros'] = self.positive_zeros
            info['negative_zeros'] = self.negative_zeros

        if hasattr(self, 'plot'):
            info['plot'] = self.plot

        if hasattr(self, 'factorization'):
            info['factorization'] = self.factorization
            
        if self.fromDB and self.algebraic:
            info['dirichlet_arithmetic'] = lfuncDShtml(self, "arithmetic")
            info['eulerproduct_arithmetic'] = lfuncEPtex(self, "arithmetic")
            info['functionalequation_arithmetic'] = lfuncFEtex(self, "arithmetic")

            if self.motivic_weight % 2 == 0:
               arith_center = "\\frac{" + str(1 + self.motivic_weight) + "}{2}"
            else:
               arith_center = str(ZZ(1)/2 + self.motivic_weight/2)
            svt_crit = specialValueTriple(self, 0.5, '\\frac12',arith_center)
            info['sv_critical'] = svt_crit[0] + "\\ =\\ " + svt_crit[2]
            info['sv_critical_analytic'] = [svt_crit[0], svt_crit[2]]
            info['sv_critical_arithmetic'] = [svt_crit[1], svt_crit[2]]

            if self.motivic_weight % 2 == 1:
               arith_edge = "\\frac{" + str(2 + self.motivic_weight) + "}{2}"
            else:
               arith_edge = str(ZZ(1) + self.motivic_weight/2)

            svt_edge = specialValueTriple(self, 1, '1',arith_edge)
            info['sv_edge'] = svt_edge[0] + "\\ =\\ " + svt_edge[2]
            info['sv_edge_analytic'] = [svt_edge[0], svt_edge[2]]
            info['sv_edge_arithmetic'] = [svt_edge[1], svt_edge[2]]

            info['st_group'] = self.st_group
            info['st_link'] = self.st_link
            info['rank'] = self.order_of_vanishing
            info['motivic_weight'] = self.motivic_weight
        
        elif self.Ltype() != "artin" or (self.Ltype() == "artin" and self.sign != 0):
            try:
                info['sv_edge'] = specialValueString(self, 1, '1')
                info['sv_critical'] = specialValueString(self, 0.5, '1/2')
            except:
                info['sv_critical'] = "L(1/2): not computed"
                info['sv_edge'] = "L(1): not computed"

        return info
Esempio n. 53
0
    def make_curve(self):
        # To start with the data fields of self are just those from
        # the database.  We need to reformat these, construct the
        # and compute some further (easy) data about it.
        #

        # Weierstrass equation

        data = self.data = {}

        disc = ZZ(self.disc_sign) * ZZ(self.disc_key[3:]) 
        # to deal with disc_key, uncomment line above and remove line below
        #disc = ZZ(self.disc_sign) * ZZ(self.abs_disc)
        data['disc'] = disc
        data['cond'] = ZZ(self.cond)
        data['min_eqn'] = self.min_eqn
        data['min_eqn_display'] = list_to_min_eqn(self.min_eqn)
        data['disc_factor_latex'] = web_latex(factor(data['disc']))
        data['cond_factor_latex'] = web_latex(factor(int(self.cond)))
        data['aut_grp'] = groupid_to_meaningful(self.aut_grp)
        data['geom_aut_grp'] = groupid_to_meaningful(self.geom_aut_grp)
        data['igusa_clebsch'] = [ZZ(a) for a in self.igusa_clebsch]
        data['igusa'] = igusa_clebsch_to_igusa(data['igusa_clebsch'])
        data['g2'] = igusa_to_g2(data['igusa'])
        data['ic_norm'] = normalize_invariants(data['igusa_clebsch'],[1,2,3,5])
        data['igusa_norm'] = normalize_invariants(data['igusa'],[1,2,3,4,5])
        data['ic_norm_factor_latex'] = [web_latex(zfactor(i)) for i in data['ic_norm']]
        data['igusa_norm_factor_latex'] = [web_latex(zfactor(j)) for j in data['igusa_norm']]
        data['num_rat_wpts'] = ZZ(self.num_rat_wpts)
        data['two_selmer_rank'] = ZZ(self.two_selmer_rank)
        if len(self.torsion) == 0:
            data['tor_struct'] = '\mathrm{trivial}'
        else:
            tor_struct = [ZZ(a)  for a in self.torsion]
            data['tor_struct'] = ' \\times '.join(['\Z/{%s}\Z' % n for n in tor_struct])
        isogeny_class = db_g2c().isogeny_classes.find_one({'label' : isog_label(self.label)})
        end_data = get_end_data(isogeny_class)
        for key in end_data.keys():
            data[key] = end_data[key]
        x = self.label.split('.')[1]

        self.make_code_snippets()

        self.friends = [
            ('Isogeny class %s' % isog_label(self.label), url_for(".by_double_iso_label", conductor = self.cond, iso_label = x)),
            ('L-function', url_for("l_functions.l_function_genus2_page", cond=self.cond,x=x)),
            
            ('Twists',url_for(".index_Q", ic0 = self.igusa_clebsch[0], ic1 = self.igusa_clebsch[1],ic2 = self.igusa_clebsch[2],ic3 = self.igusa_clebsch[3])),
            #('Twists2',url_for(".index_Q", igusa_clebsch = str(self.igusa_clebsch)))  #doesn't work.
            #('Siegel modular form someday', '.')
            ]
        self.downloads = [
             ('Download all stored data', '.')]
        iso = self.label.split('.')[1]
        num = '.'.join(self.label.split('.')[2:4])
        self.plot = encode_plot(eqn_list_to_curve_plot(self.min_eqn))
        self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot
        self.properties = [('Label', self.label),
                           (None, self.plot_link),
                           ('Conductor','%s' % self.cond),
                           ('Discriminant', '%s' % data['disc']),
                           ('Invariants', '%s </br> %s </br> %s </br> %s'% tuple(data['ic_norm'])), 
                           ('Sato-Tate group', '\(%s\)' % data['st_group_name']), 
                           ('\(%s\)' % data['real_geom_end_alg_name'][0],'\(%s\)' % data['real_geom_end_alg_name'][1]),
                           ('\(\mathrm{GL}_2\)-type','%s' % data['is_gl2_type_name'])]
        self.title = "Genus 2 Curve %s" % (self.label)
        self.bread = [
             ('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")),
             ('%s' % self.cond, url_for(".by_conductor", conductor=self.cond)),
             ('%s' % iso, url_for(".by_double_iso_label", conductor=self.cond, iso_label=iso)),
             ('Genus 2 curve %s' % num, url_for(".by_g2c_label", label=self.label))]
Esempio n. 54
0
def list_to_factored_poly(s):
    return str(factor(PolynomialRing(ZZ, 't')(s))).replace('*', '')
Esempio n. 55
0
def modn_exponent(n):
    """ given a nonzero integer n, returns the group exponent of (Z/nZ)* """
    return lcm( [ (p-1)*p**(e-1) for (p,e) in factor(n) ] ) // (1 if n%8 else 2)
Esempio n. 56
0
    def make_curve(self):
        # To start with the data fields of self are just those from the
        # databases.  We reformat these, while computing some further (easy)
        # data about the curve on the fly.

        # Initialize data:
        data = self.data = {}
        endodata = self.endodata = {}

        # Polish data from database before putting it into the data dictionary:
        disc = ZZ(self.disc_sign) * ZZ(self.disc_key[3:])
        # to deal with disc_key, uncomment line above and comment line below
        #disc = ZZ(self.disc_sign) * ZZ(self.abs_disc)
        data['disc'] = disc
        data['cond'] = ZZ(self.cond)
        data['min_eqn'] = self.min_eqn
        data['min_eqn_display'] = list_to_min_eqn(self.min_eqn)
        data['disc_factor_latex'] = web_latex(factor(data['disc']))
        data['cond_factor_latex'] = web_latex(factor(int(self.cond)))
        data['aut_grp'] = groupid_to_meaningful(self.aut_grp)
        data['geom_aut_grp'] = groupid_to_meaningful(self.geom_aut_grp)
        data['igusa_clebsch'] = [ZZ(a) for a in self.igusa_clebsch]
        data['igusa'] = [ZZ(a) for a in self.igusa]
        data['g2'] = self.g2inv
        data['ic_norm'] = data['igusa_clebsch']
        data['igusa_norm'] = data['igusa']
        # Should we ever want to normalize the invariants further, then
        # uncomment the following lines:
        #data['ic_norm'] = normalize_invariants(data['igusa_clebsch'], [2, 4, 6,
        #    10])
        #data['igusa_norm'] = normalize_invariants(data['igusa'], [2, 4, 6, 8,
        #    10])
        data['ic_norm_factor_latex'] = [web_latex(zfactor(i)) for i in
            data['ic_norm']]
        data['igusa_norm_factor_latex'] = [ web_latex(zfactor(j)) for j in
            data['igusa_norm'] ]
        data['num_rat_wpts'] = ZZ(self.num_rat_wpts)
        data['two_selmer_rank'] = ZZ(self.two_selmer_rank)
        data['analytic_rank'] = ZZ(self.analytic_rank)
        data['has_square_sha'] = "square" if self.has_square_sha else "twice a square"
        data['locally_solvable'] = "yes" if self.locally_solvable else "no"
        if len(self.torsion) == 0:
            data['tor_struct'] = '\mathrm{trivial}'
        else:
            tor_struct = [ ZZ(a) for a in self.torsion ]
            data['tor_struct'] = ' \\times '.join([ '\Z/{%s}\Z' % n for n in
                tor_struct ])

        # Data derived from Sato-Tate group:
        isogeny_class = g2cdb().isogeny_classes.find_one({'label' :
            isog_label(self.label)})
        st_data = get_st_data(isogeny_class)
        for key in st_data.keys():
            data[key] = st_data[key]

        # GL_2 statement over the base field
        endodata['gl2_statement_base'] = \
            gl2_statement_base(self.factorsRR_base, r'\(\Q\)')

        # NOTE: In what follows there is some copying of code and data that is
        # stupid from the point of view of efficiency but likely better from
        # that of maintenance.

        # Endomorphism data over QQ:
        endodata['factorsQQ_base'] = self.factorsQQ_base
        endodata['factorsRR_base'] = self.factorsRR_base
        endodata['ring_base'] = self.ring_base
        endodata['endo_statement_base'] = \
            """Endomorphism ring over \(\Q\):""" + \
            endo_statement(endodata['factorsQQ_base'],
                endodata['factorsRR_base'], endodata['ring_base'], r'')
        # Field of definition data:
        endodata['fod_label'] = self.fod_label
        endodata['fod_poly'] = intlist_to_poly(self.fod_coeffs)
        endodata['fod_statement'] = fod_statement(endodata['fod_label'],
            endodata['fod_poly'])
        # Endomorphism data over QQbar:
        endodata['factorsQQ_geom'] = self.factorsQQ_geom
        endodata['factorsRR_geom'] = self.factorsRR_geom
        endodata['ring_geom'] = self.ring_geom
        if self.fod_label != '1.1.1.1':
            endodata['gl2_statement_geom'] = \
                gl2_statement_base(self.factorsRR_geom, r'\(\overline{\Q}\)')
            endodata['endo_statement_geom'] = \
            """Endomorphism ring over \(\overline{\Q}\):""" + \
            endo_statement(endodata['factorsQQ_geom'],
                endodata['factorsRR_geom'], endodata['ring_geom'],
                r'\overline{\Q}')

        # Full endomorphism lattice minus entries already treated:
        N = len(self.lattice)
        endodata['lattice'] = (self.lattice)[1:N - 1]
        if endodata['lattice']:
            endodata['lattice_statement_preamble'] = \
                lattice_statement_preamble()
            endodata['lattice_statement'] = \
                lattice_statement(endodata['lattice'])

        # Splitting field description:
        #endodata['is_simple_base'] = self.is_simple_base
        endodata['is_simple_geom'] = self.is_simple_geom
        endodata['spl_fod_label'] = self.spl_fod_label
        endodata['spl_fod_poly'] = intlist_to_poly(self.spl_fod_coeffs)
        endodata['spl_fod_statement'] = \
            spl_fod_statement(endodata['is_simple_geom'],
                endodata['spl_fod_label'], endodata['spl_fod_poly'])

        # Isogeny factors:
        if not endodata['is_simple_geom']:
            endodata['spl_facs_coeffs'] = self.spl_facs_coeffs
            # This could be done non-uniformly as well... later.
            if len(self.spl_facs_labels) == len(self.spl_facs_coeffs):
                endodata['spl_facs_labels'] = self.spl_facs_labels
            else:
                endodata['spl_facs_labels'] = ['' for coeffs in
                    self.spl_facs_coeffs]
            endodata['spl_facs_condnorms'] = self.spl_facs_condnorms
            endodata['spl_statement'] = \
                spl_statement(endodata['spl_facs_coeffs'],
                    endodata['spl_facs_labels'],
                    endodata['spl_facs_condnorms'])

        # Title
        self.title = "Genus 2 Curve %s" % (self.label)

        # Lady Gaga box
        self.plot = encode_plot(eqn_list_to_curve_plot(self.min_eqn))
        self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot
        self.properties = [
                ('Label', self.label),
               (None, self.plot_link),
               ('Conductor','%s' % self.cond),
               ('Discriminant', '%s' % data['disc']),
               ('Invariants', '%s </br> %s </br> %s </br> %s' % tuple(data['ic_norm'])),
               ('Sato-Tate group', data['st_group_href']),
               ('\(%s\)' % data['real_geom_end_alg_disp'][0],
                '\(%s\)' % data['real_geom_end_alg_disp'][1]),
               ('\(\mathrm{GL}_2\)-type','%s' % data['is_gl2_type_name'])]
        x = self.label.split('.')[1]
        self.friends = [
            ('Isogeny class %s' % isog_label(self.label),
                url_for(".by_double_iso_label",
                    conductor = self.cond,
                    iso_label = x)),
            ('L-function',
                url_for("l_functions.l_function_genus2_page",
                    cond=self.cond,x=x)),
            ('Twists',
                url_for(".index_Q",
                    g20 = self.g2inv[0],
                    g21 = self.g2inv[1],
                    g22 = self.g2inv[2]))
            #('Siegel modular form someday', '.')
            ]

        if not endodata['is_simple_geom']:
            self.friends += [('Elliptic curve %s' % lab,url_for_ec(lab)) for lab in endodata['spl_facs_labels'] if lab != '']
        #self.downloads = [('Download all stored data', '.')]

        # Breadcrumbs
        iso = self.label.split('.')[1]
        num = '.'.join(self.label.split('.')[2:4])
        self.bread = [
             ('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")),
             ('%s' % self.cond, url_for(".by_conductor", conductor=self.cond)),
             ('%s' % iso, url_for(".by_double_iso_label", conductor=self.cond,
                 iso_label=iso)),
             ('Genus 2 curve %s' % num, url_for(".by_g2c_label",
                 label=self.label))
             ]

        # Make code that is used on the page:
        self.make_code_snippets()
Esempio n. 57
0
    def make_curve(self):
        # To start with the data fields of self are just those from the
        # databases.  We reformat these, while computing some further (easy)
        # data about the curve on the fly.

        # Get data from databases:
        data = self.data = {}
        endodata = self.endodata = {}

        # Polish data from database before putting it into the data dictionary:
        disc = ZZ(self.disc_sign) * ZZ(self.disc_key[3:]) 
        # to deal with disc_key, uncomment line above and comment line below
        #disc = ZZ(self.disc_sign) * ZZ(self.abs_disc)
        data['disc'] = disc
        data['cond'] = ZZ(self.cond)
        data['min_eqn'] = self.min_eqn
        data['min_eqn_display'] = list_to_min_eqn(self.min_eqn)
        data['disc_factor_latex'] = web_latex(factor(data['disc']))
        data['cond_factor_latex'] = web_latex(factor(int(self.cond)))
        data['aut_grp'] = groupid_to_meaningful(self.aut_grp)
        data['geom_aut_grp'] = groupid_to_meaningful(self.geom_aut_grp)
        data['igusa_clebsch'] = [ZZ(a) for a in self.igusa_clebsch]
        data['igusa'] = igusa_clebsch_to_igusa(data['igusa_clebsch'])
        data['g2'] = igusa_to_g2(data['igusa'])
        data['ic_norm'] = normalize_invariants(data['igusa_clebsch'],[1,2,3,5])
        data['igusa_norm'] = normalize_invariants(data['igusa'],[1,2,3,4,5])
        data['ic_norm_factor_latex'] = [web_latex(zfactor(i)) for i in
                data['ic_norm']]
        data['igusa_norm_factor_latex'] = [web_latex(zfactor(j)) for j in
                data['igusa_norm']]
        data['num_rat_wpts'] = ZZ(self.num_rat_wpts)
        data['two_selmer_rank'] = ZZ(self.two_selmer_rank)
        if len(self.torsion) == 0:
            data['tor_struct'] = '\mathrm{trivial}'
        else:
            tor_struct = [ZZ(a)  for a in self.torsion]
            data['tor_struct'] = ' \\times '.join(['\Z/{%s}\Z' % n for n in
                tor_struct])

        # Data from old endomorphism functionality, used in isogeny class as
        # well. Calls the get_end_data function above.
        isogeny_class = db_g2c().isogeny_classes.find_one({'label' :
            isog_label(self.label)})
        end_data = get_end_data(isogeny_class)
        for key in end_data.keys():
            data[key] = end_data[key]

        # GL_2 statement over the base field
        endodata['gl2_statement_base'] = gl2_statement(self.factorsRR_base,
                r'\(\Q\)')
        
        # NOTE: In what follows there is some copying of code and data that is
        # stupid from the point of view of efficiency but likely better from
        # that of maintenance.
        
        # Endomorphism data over QQ:
        endodata['factorsQQ_base'] = self.factorsQQ_base
        endodata['factorsRR_base'] = self.factorsRR_base
        endodata['ring_base'] = self.ring_base
        endodata['endo_statement_base'] = \
        """Endomorphism ring over \(\Q\):<br>""" + \
        endo_statement(endodata['factorsQQ_base'], endodata['factorsRR_base'],
                endodata['ring_base'], r'')
        # Field of definition data:
        endodata['fod_label'] = self.fod_label
        endodata['fod_poly'] = intlist_to_poly(self.fod_coeffs)
        endodata['fod_statement'] = fod_statement(endodata['fod_label'],
                endodata['fod_poly'])
        # Endomorphism data over QQbar:
        endodata['factorsQQ_geom'] = self.factorsQQ_geom
        endodata['factorsRR_geom'] = self.factorsRR_geom
        endodata['ring_geom'] = self.ring_geom
        if self.fod_label != '1.1.1.1':
            endodata['endo_statement_geom'] = \
            """Endomorphism ring over \(\overline{\Q}\):<br>""" + \
            endo_statement(endodata['factorsQQ_geom'],
                    endodata['factorsRR_geom'], endodata['ring_geom'],
                    r'\overline{\Q}')

        # Full endomorphism lattice:
        endodata['lattice'] = self.lattice[1:len(self.lattice) - 1]
        if endodata['lattice']:
            endodata['lattice_statement_preamble'] = \
            lattice_statement_preamble()
            endodata['lattice_statement'] = \
            lattice_statement(endodata['lattice'])

        # Splitting field description:
        #endodata['is_simple_base'] = self.is_simple_base
        endodata['is_simple_geom'] = self.is_simple_geom
        endodata['spl_fod_label'] = self.spl_fod_label
        endodata['spl_fod_poly'] = intlist_to_poly(self.spl_fod_coeffs)
        endodata['spl_fod_statement'] = \
        spl_fod_statement(endodata['is_simple_geom'],
                endodata['spl_fod_label'], endodata['spl_fod_poly'])
        
        # Isogeny factors:
        if not endodata['is_simple_geom']:
            endodata['spl_facs_coeffs'] = self.spl_facs_coeffs
            # This could be done non-uniformly as well... later.
            if len(self.spl_facs_labels) == len(self.spl_facs_coeffs):
                endodata['spl_facs_labels'] = self.spl_facs_labels
            else:
                endodata['spl_facs_labels'] = ['' for coeffs in
                        self.spl_facs_coeffs]
            endodata['spl_facs_condnorms'] = self.spl_facs_condnorms
            endodata['spl_statement'] = \
            spl_statement(endodata['spl_facs_coeffs'],
                    endodata['spl_facs_labels'],
                    endodata['spl_facs_condnorms'])

        x = self.label.split('.')[1]
        self.make_code_snippets()
        self.friends = [
            ('Isogeny class %s' % isog_label(self.label), url_for(".by_double_iso_label", conductor = self.cond, iso_label = x)),
            ('L-function', url_for("l_functions.l_function_genus2_page", cond=self.cond,x=x)),
            
            ('Twists',url_for(".index_Q", ic0 = self.igusa_clebsch[0], ic1 = self.igusa_clebsch[1],ic2 = self.igusa_clebsch[2],ic3 = self.igusa_clebsch[3])),
            #('Twists2',url_for(".index_Q", igusa_clebsch = str(self.igusa_clebsch)))  #doesn't work.
            #('Siegel modular form someday', '.')
            ]
        self.downloads = [
             ('Download all stored data', '.')]
        iso = self.label.split('.')[1]
        num = '.'.join(self.label.split('.')[2:4])
        self.plot = encode_plot(eqn_list_to_curve_plot(self.min_eqn))
        self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot
        self.properties = [('Label', self.label),
                           (None, self.plot_link),
                           ('Conductor','%s' % self.cond),
                           ('Discriminant', '%s' % data['disc']),
                           ('Invariants', '%s </br> %s </br> %s </br> %s'% tuple(data['ic_norm'])), 
                           ('Sato-Tate group', '\(%s\)' % data['st_group_name']), 
                           ('\(%s\)' % data['real_geom_end_alg_name'][0],'\(%s\)' % data['real_geom_end_alg_name'][1]),
                           ('\(\mathrm{GL}_2\)-type','%s' % data['is_gl2_type_name'])]
        self.title = "Genus 2 Curve %s" % (self.label)
        self.bread = [
             ('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")),
             ('%s' % self.cond, url_for(".by_conductor", conductor=self.cond)),
             ('%s' % iso, url_for(".by_double_iso_label", conductor=self.cond, iso_label=iso)),
             ('Genus 2 curve %s' % num, url_for(".by_g2c_label", label=self.label))]