Beispiel #1
1
def finite_field():
    """
    Create a random finite field with degree at most 20 and prime at most 10^6.

    OUTPUT:
        a finite field

    EXAMPLES:
        sage: sage.rings.tests.finite_field()
        Finite Field in a of size 161123^4
    """
    from sage.all import ZZ, GF
    p = ZZ.random_element(x=2, y=10**6-18).next_prime()
    d = ZZ.random_element(x=1, y=20)
    return GF(p**d,'a')
Beispiel #2
0
def su2_mu_info(w,n):
    """ return data for ST group SU(2) x mu(n) (of any wt > 0); these groups are not stored in the database """
    assert w > 0 and n > 0
    n = ZZ(n)
    rec = {}
    rec['label'] = "%d.2.3.c%d"%(w,n)
    rec['weight'] = w
    rec['degree'] = 2
    rec['rational'] = boolean_name(True if n <= 2 else False)
    rec['name'] = 'SU(2)[C%d]'%n if n > 1 else 'SU(2)'
    rec['pretty'] = r'\mathrm{SU}(2)[C_{%d}]'%n if n > 1 else r'\mathrm{SU}(2)'
    rec['real_dimension'] = 3
    rec['components'] = int(n)
    rec['ambient'] = '\mathrm{U}(2)'
    rec['connected'] = boolean_name(rec['components'] == 1)
    rec['st0_name'] = 'SU(2)'
    rec['identity_component'] = st0_pretty(rec['st0_name'])
    rec['st0_description'] = r'\left\{\begin{bmatrix}\alpha&\beta\\-\bar\beta&\bar\alpha\end{bmatrix}:\alpha\bar\alpha+\beta\bar\beta = 1,\ \alpha,\beta\in\mathbb{C}\right\}'
    rec['component_group'] = 'C_{%d}'%n
    rec['abelian'] = boolean_name(True)
    rec['cyclic'] = boolean_name(True)
    rec['solvable'] = boolean_name(True)
    rec['trace_zero_density']='0'
    rec['gens'] = r'\begin{bmatrix} 1 & 0 \\ 0 & \zeta_{%d}\end{bmatrix}'%n
    rec['numgens'] = 1
    rec['subgroups'] = comma_separated_list([st_link("%d.2.3.c%d"%(w,n/p)) for p in n.prime_factors()])
    rec['supgroups'] = comma_separated_list([st_link("%d.2.3.c%d"%(w,p*n)) for p in [2,3,5]] + ["$\ldots$"])
    rec['moments'] = [['x'] + [ '\\mathrm{E}[x^{%d}]'%m for m in range(13)]]
    su2moments = ['1','0','1','0','2','0','5','0','14','0','42','0','132']
    rec['moments'] += [['a_1'] + [su2moments[m] if m % n == 0  else '0' for m in range(13)]]
    rec['trace_moments'] = trace_moments(rec['moments'])
    rec['counts'] = []
    return rec
Beispiel #3
0
def niceideals(F, ideals): #HNF + sage ideal + label
    """Convert a list of ideas from strongs to actual NumberField ideals

    F is a Sage NumberField

    ideals is a list of strings representing ideals I in the field, of
    the form [N,a,alpha] where N is the norm of I, a the least
    positive integer in I, and alpha a field element such that I is
    generated by a and alpha.

    The output is a list

    """
    nideals = []
    ilabel = 1
    norm = ZZ(0)
    for i in range(len(ideals)):
        N,n,idl,_ = str2ideal(F,ideals[i])
        assert idl.norm() == N and idl.smallest_integer() == n
        if N != norm:
            ilabel = ZZ(1)
            norm = N
        label = N.str() + '.' + ilabel.str()
        hnf = idl.pari_hnf().python()
        nideals.append([hnf, idl, label])
        ilabel += 1
    return nideals
Beispiel #4
0
def nu1_mu_info(w,n):
    """ return data for ST group N(U(1)) x mu(n) (of any wt > 0); these groups are not stored in the database """
    assert w > 0 and n > 0
    n = ZZ(n)
    rec = {}
    rec['label'] = "%d.2.1.d%d"%(w,n)
    rec['weight'] = w
    rec['degree'] = 2
    rec['rational'] = boolean_name(True if n <= 2 else False)
    rec['name'] = 'U(1)[D%d]'%n if n > 1 else 'N(U(1))'
    rec['pretty'] = r'\mathrm{U}(1)[D_{%d}]'%n if n > 1 else r'N(\mathrm{U}(1))'
    rec['real_dimension'] = 1
    rec['components'] = int(2*n)
    rec['ambient'] = '\mathrm{U}(2)'
    rec['connected'] = boolean_name(rec['components'] == 1)
    rec['st0_name'] = 'U(1)'
    rec['identity_component'] = st0_pretty(rec['st0_name'])
    rec['st0_description'] = '\\left\\{\\begin{bmatrix}\\alpha&0\\\\0&\\bar\\alpha\\end{bmatrix}:\\alpha\\bar\\alpha = 1,\\ \\alpha\\in\\mathbb{C}\\right\\}'
    rec['component_group'] = 'D_{%d}'%n
    rec['abelian'] = boolean_name(n <= 2)
    rec['cyclic'] = boolean_name(n <= 1)
    rec['solvable'] = boolean_name(True)
    rec['trace_zero_density']='1/2'
    rec['gens'] = r'\left\{\begin{bmatrix} 0 & 1\\ -1 & 0\end{bmatrix}, \begin{bmatrix} 1 & 0 \\ 0 & \zeta_{%d}\end{bmatrix}\right\}'%n
    rec['numgens'] = 2
    rec['subgroups'] = comma_separated_list([st_link("%d.2.1.d%d"%(w,n/p)) for p in n.prime_factors()])
    rec['supgroups'] = comma_separated_list([st_link("%d.2.1.d%d"%(w,p*n)) for p in [2,3,5]] + ["$\ldots$"])
    rec['moments'] = [['x'] + [ '\\mathrm{E}[x^{%d}]'%m for m in range(13)]]
    nu1moments = ['1','0','1','0','3','0','10','0','35','0','126','0','462']
    rec['moments'] += [['a_1'] + [nu1moments[m] if m % n == 0  else '0' for m in range(13)]]
    rec['trace_moments'] = trace_moments(rec['moments'])
    rec['counts'] = [['a_1', [[0,n]]]]
    return rec
Beispiel #5
0
def aplist(E, B=100):
    """
    Compute aplist for an elliptic curve E over Q(sqrt(5)), as a
    string->number dictionary.

    INPUT:
        - E -- an elliptic curve
        - B -- a positive integer (default: 100)

    OUTPUT:
        - dictionary mapping strings (labeled primes) to Python ints,
          with keys the primes of P with norm up to B such that the
          norm of the conductor is coprime to the characteristic of P.
    """
    from psage.modform.hilbert.sqrt5.tables import canonical_gen    
    v = {}
    from psage.modform.hilbert.sqrt5.sqrt5 import F
    labels, primes = labeled_primes_of_bounded_norm(F, B)

    from sage.all import ZZ
    N = E.conductor()
    try:
        N = ZZ(N.norm())
    except:
        N = ZZ(N)
    
    for i in range(len(primes)):
        p = primes[i]
        k = p.residue_field()
        if N.gcd(k.cardinality()) == 1:
            v[labels[i]] = int(k.cardinality() + 1 - E.change_ring(k).cardinality())
    return v
Beispiel #6
0
 def randomize(self, prime):
     assert not self.randomized
     prev = None
     for i in xrange(0, len(self.bp)):
         d_i_minus_one = self.bp[i].zero.nrows()
         d_i = self.bp[i].zero.ncols()
         MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_i_minus_one, d_i)
         MSZp_square = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_i, d_i)
         if i != 0:
             MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_i_minus_one, d_i)
             self.bp[i] = self.bp[i].group(MSZp, prime).mult_left(prev.adjoint())
         if i != len(self.bp) - 1:
             cur = MSZp_square.random_element()
             self.bp[i] = self.bp[i].group(MSZp, prime).mult_right(cur)
             prev = cur
     # compute S * B_0
     d_0 = self.bp[0].zero.nrows()
     d_1 = self.bp[0].zero.ncols()
     S = matrix.identity(d_0)
     for i in xrange(d_0):
         S[i, i] = random.randint(0, prime - 1)
     MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_0, d_1)
     self.bp[0] = self.bp[0].group(MSZp, prime).mult_left(S)
     # compute B_ell * T
     r = self.bp[-1].zero.nrows()
     c = self.bp[-1].zero.ncols()
     T = matrix.identity(c)
     for i in xrange(c):
         T[i, i] = random.randint(0, prime - 1)
     MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), r, c)
     self.bp[-1] = self.bp[-1].group(MSZp, prime).mult_right(T)
     self.randomized = True
Beispiel #7
0
def factor_out_p(val, p):
    val = ZZ(val)
    if val == 0 or val == -1:
        return str(val)
    if val==1:
        return '+1'
    s = 1
    if val<0:
        s = -1
        val = -val
    ord = val.valuation(p)
    val = val/p**ord
    out = ''
    if s == -1:
        out += '-'
    else:
        out += '+'
    if ord==1:
        out +=  str(p)
    elif ord>1:
        out +=  '%d^{%d}' % (p, ord)
    if val>1:
        if ord ==1:
            out += r'\cdot '
        out += str(val)
    return out
Beispiel #8
0
def nextchr(c):
    s = ord('a') - 1  # really 96
    l = [ZZ(ord(j) - s) for j in list(c)]
    l.reverse()
    tot = ZZ(l, 27) + 1
    newl = tot.digits(27)
    newl.reverse()
    newl = map(lambda x: x + 1 if x == 0 else x, newl)
    return ''.join([chr(j + s) for j in newl])
Beispiel #9
0
def render_hgm_webpage(args):
    data = None
    info = {}
    if 'label' in args:
        label = clean_input(args['label'])
        C = base.getDBConnection()
        data = C.hgm.motives.find_one({'label': label})
        if data is None:
            bread = get_bread([("Search error", url_for('.search'))])
            info['err'] = "Motive " + label + " was not found in the database."
            info['label'] = label
            return search_input_error(info, bread)
        title = 'Hypergeometric Motive:' + label
        A = data['A']
        B = data['B']
        tn,td = data['t']
        t = latex(QQ(str(tn)+'/'+str(td)))
        primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
        locinfo = data['locinfo']
        for j in range(len(locinfo)):
            locinfo[j] = [primes[j]] + locinfo[j]
            locinfo[j][2] = poly_with_factored_coeffs(locinfo[j][2], primes[j])
        hodge = data['hodge']
        prop2 = [
            ('Degree', '\(%s\)' % data['degree']),
            ('Weight',  '\(%s\)' % data['weight']),
            ('Conductor', '\(%s\)' % data['cond']),
        ]
        # Now add factorization of conductor
        Cond = ZZ(data['cond'])
        if not (Cond.abs().is_prime() or Cond == 1):
            data['cond'] = "%s=%s" % (str(Cond), factorint(data['cond']))

        info.update({
                    'A': A,
                    'B': B,
                    't': t,
                    'degree': data['degree'],
                    'weight': data['weight'],
                    'sign': data['sign'],
                    'sig': data['sig'],
                    'hodge': hodge,
                    'cond': data['cond'],
                    'req': data['req'],
                    'locinfo': locinfo
                    })
        AB_data, t_data = data["label"].split("_t")
        #AB_data = data["label"].split("_t")[0]
        friends = [("Motive family "+AB_data.replace("_"," "), url_for(".by_family_label", label = AB_data))]
        friends.append(('L-function', url_for("l_functions.l_function_hgm_page", label=AB_data, t='t'+t_data)))
#        if rffriend != '':
#            friends.append(('Discriminant root field', rffriend))


        bread = get_bread([(label, ' ')])
        return render_template("hgm-show-motive.html", credit=HGM_credit, title=title, bread=bread, info=info, properties2=prop2, friends=friends)
def _i_func(q):
    '''Return i(B) in Katsurada's paper.
    '''
    m = ZZ(2) * (q.matrix()) ** (-1)
    i = valuation(gcd(m.list()), ZZ(2))
    m = ZZ(2) ** (-i) * m
    if all(m[a, a] % 2 == 0 for a in range(m.ncols())):
        return - i - 1
    else:
        return - i
Beispiel #11
0
def read_line(line, debug=0):
    r""" Parses one line from input file.  Returns and a dict containing
    fields with keys as above.

    Sample line: 11 a 1 0,-1,1,-10,-20 7 1,0 0,1,0 0,0 0,1

    Fields: label (3 fields)
            a-invariants
            p0
            For each bad  prime:  'a'                if additive
                                  lambda,mu          if multiplicative (or 'o?' if unknown)
            For each good prime:  lambda,mu          if ordinary (or 'o?' if unknown)
                                  lambda+,lambda-,mu if supersingular (or 's?' if unknown)
    """
    data = {}
    if debug: print("Parsing input line {}".format(line[:-1]))
    fields = line.split()
    label = fields[0]+fields[1]+fields[2]
    data['label'] = label
    N = ZZ(fields[0])
    badp = N.support()
    nbadp = len(badp)
    p0 = int(fields[4])
    data['iwp0'] = p0
    if debug: print("p0={}".format(p0))

    iwdata = {}

    # read data for bad primes

    for p,pdat in zip(badp,fields[5:5+nbadp]):
        p = str(p)
        if debug>1: print("p={}, pdat={}".format(p,pdat))
        if pdat in ['o?','a']:
            iwdata[p]=pdat
        else:
            iwdata[p]=[int(x) for x in pdat.split(",")]

    # read data for all primes

    for p,pdat in zip(primes(1000),fields[5+nbadp:]):
        p = str(p)
        if debug>1: print("p={}, pdat={}".format(p,pdat))
        if pdat in ['s?','o?','a']:
            iwdata[p]=pdat
        else:
            iwdata[p]=[int(x) for x in pdat.split(",")]

    data['iwdata'] = iwdata
    if debug: print("label {}, data {}".format(label,data))
    return label, data
Beispiel #12
0
 def includes_composite(s):
     s = s.replace(" ", "").replace("..", "-")
     for interval in s.split(","):
         if "-" in interval[1:]:
             ix = interval.index("-", 1)
             a, b = int(interval[:ix]), int(interval[ix + 1 :])
             if b == a:
                 if a != 1 and not a.is_prime():
                     return True
             if b > a and b > 3:
                 return True
         else:
             a = ZZ(interval)
             if a != 1 and not a.is_prime():
                 return True
Beispiel #13
0
def rsa(bits):
    # only prove correctness up to 1024bits
    proof = (bits <= 1024)
    p = next_prime(ZZ.random_element(2**(bits // 2 + 1)),
                   proof=proof)
    q = next_prime(ZZ.random_element(2**(bits // 2 + 1)),
                   proof=proof)
    n = p * q
    phi_n = (p - 1) * (q - 1)
    while True:
        e = ZZ.random_element(1, phi_n)
        if gcd(e, phi_n) == 1:
            break
    d = lift(Mod(e, phi_n)**(-1))
    return e, d, n
Beispiel #14
0
 def includes_composite(s):
     s = s.replace(' ','').replace('..','-')
     for interval in s.split(','):
         if '-' in interval[1:]:
             ix = interval.index('-',1)
             a,b = int(interval[:ix]), int(interval[ix+1:])
             if b == a:
                 if a != 1 and not a.is_prime():
                     return True
             if b > a and b > 3:
                 return True
         else:
             a = ZZ(interval)
             if a != 1 and not a.is_prime():
                 return True
Beispiel #15
0
    def random_element(self, x=None, y=None, distribution=None):
        """
        Return a random integer in Pari.

        NOTE:

        The given arguments are passed to ``ZZ.random_element(...)``.

        INPUT:

        - `x`, `y` -- optional integers, that are lower and upper bound
          for the result. If only `x` is provided, then the result is
          between 0 and `x-1`, inclusive. If both are provided, then the
          result is between `x` and `y-1`, inclusive.

        - `distribution` -- optional string, so that ``ZZ`` can make sense
          of it as a probability distribution.

        EXAMPLE::

            sage: R = PariRing()
            sage: R.random_element()
            -8
            sage: R.random_element(5,13)
            12
            sage: [R.random_element(distribution="1/n") for _ in range(10)]
            [0, 1, -1, 2, 1, -95, -1, -2, -12, 0]

        """
        from sage.all import ZZ
        return self(ZZ.random_element(x,y,distribution))
Beispiel #16
0
def relative_number_field(n=2, maxdeg=2):
    """
    Return a tower of at most n extensions each of degree at most maxdeg.

    EXAMPLES:
        sage: sage.rings.tests.relative_number_field(3)
        Number Field in aaa with defining polynomial x^2 - 15*x + 17 over its base field
    """
    from sage.all import ZZ
    K = absolute_number_field(maxdeg)
    n -= 1
    var = 'aa'
    R = ZZ['x']
    while n >= 1:
        while True:
            f = R.random_element(degree=ZZ.random_element(x=1,y=maxdeg),x=-100,y=100)
            if f.degree() <= 0: continue
            f = f * f.denominator()  # bug trac #4781
            f = f + R.gen()**maxdeg  # make monic
            if f.is_irreducible():
                break
        K = K.extension(f,var)
        var += 'a'
        n -= 1
    return K
Beispiel #17
0
def rings1():
    """
    Return an iterator over random rings.
    Return a list of pairs (f, desc), where f is a function that
    outputs a random ring that takes a ring and possibly
    some other data as constructor.

    RINGS::
        - polynomial ring in one variable over a rings0() ring.
        - polynomial ring over a rings1() ring.
        - multivariate polynomials

    EXAMPLES::

        sage: import sage.rings.tests
        sage: type(sage.rings.tests.rings0())
        <type 'list'>
    """
    v = rings0()
    X = random_rings(level=0)
    from sage.all import PolynomialRing, ZZ
    v = [(lambda : PolynomialRing(next(X), names='x'), 'univariate polynomial ring over level 0 ring'),
         (lambda : PolynomialRing(next(X), abs(ZZ.random_element(x=2,y=10)), names='x'),
                     'multivariate polynomial ring in between 2 and 10 variables over a level 0 ring')]
    return v
Beispiel #18
0
def allbsd(line):
    r""" Parses one line from an allbsd file.  Returns the label and a
    dict containing fields with keys 'conductor', 'iso', 'number',
    'ainvs', 'rank', 'torsion', 'torsion_primes', 'tamagawa_product',
    'real_period', 'special_value', 'regulator', 'sha_an', 'sha',
    'sha_primes', all values being strings or floats or ints or lists
    of ints.

    Input line fields:

    conductor iso number ainvs rank torsion tamagawa_product real_period special_value regulator sha_an

    Sample input line:

    11 a 1 [0,-1,1,-10,-20] 0 5 5 1.2692093042795534217 0.25384186085591068434 1 1.00000000000000000000

    """
    data = split(line)
    label = data[0] + data[1] + data[2]
    ainvs = parse_ainvs(data[3])

    torsion = ZZ(data[5])
    sha_an = RR(data[10])
    sha = sha_an.round()
    sha_primes = sha.prime_divisors()
    torsion_primes = torsion.prime_divisors()

    data = {
        'conductor': int(data[0]),
        'iso': data[0] + data[1],
        'number': int(data[2]),
        'ainvs': ainvs,
        'rank': int(data[4]),
        'tamagawa_product': int(data[6]),
        'real_period': float(data[7]),
        'special_value': float(data[8]),
        'regulator': float(data[9]),
        'sha_an': float(sha_an),
        'sha':  int(sha),
        'sha_primes':  [int(p) for p in sha_primes],
        'torsion':  int(torsion),
        'torsion_primes':  [int(p) for p in torsion_primes]
        }

    return label, data
Beispiel #19
0
    def init_dir_char(self, chi):
        """
        Initiate with a Web Dirichlet character.
        """
        self.original_object = [chi]
        chi = chi.chi.primitive_character()
        self.object_type = "dirichletcharacter"
        self.dim = 1
        self.motivic_weight = 0
        self.conductor = ZZ(chi.conductor())
        self.bad_semistable_primes = []
        self.bad_pot_good = self.conductor.prime_factors()
        if chi.is_odd():
            aa = 1
            bb = I
        else:
            aa = 0
            bb = 1
        self.sign = chi.gauss_sum_numerical() / (bb * float(sqrt(chi.modulus())) )
        # this has now type python complex. later we need a gp complex
        self.sign = ComplexField()(self.sign)
        self.mu_fe = [aa]
        self.nu_fe = []
        self.gammaV = [aa]
        self.langlands = True
        self.selfdual = (chi.multiplicative_order() <= 2)
        # rather than all(  abs(chi(m).imag) < 0.0001 for m in range(chi.modulus() ) )
        self.primitive = True
        self.set_dokchitser_Lfunction()
        self.set_number_of_coefficients()
        self.dirichlet_coefficients = [ chi(m) for m in range(self.numcoeff + 1) ]
        if self.selfdual:
            self.coefficient_type = 2
        else:
            self.coefficient_type = 3
        self.coefficient_period = chi.modulus()
        self.besancon_bound = 10000

        def eu(p):
            """
            local euler factor
            """
            if self.selfdual:
                K = QQ
            else:
                K = ComplexField()
            R = PolynomialRing(K, "T")
            T = R.gens()[0]
            if self.conductor % p != 0:
                return  1 - ComplexField()(chi(p)) * T
            else:
                return R(1)

        self.local_euler_factor = eu
        self.ld.gp().quit()
Beispiel #20
0
def twoadic(line):
    r""" Parses one line from a 2adic file.  Returns the label and a dict
    containing fields with keys '2adic_index', '2adic_log_level',
    '2adic_gens' and '2adic_label'.

    Input line fields:

    conductor iso number ainvs index level gens label

    Sample input lines:

    110005 a 2 [1,-1,1,-185793,29503856] 12 4 [[3,0,0,1],[3,2,2,3],[3,0,0,3]] X24
    27 a 1 [0,0,1,0,-7] inf inf [] CM
    """
    data = split(line)
    assert len(data)==8
    label = data[0] + data[1] + data[2]
    model = data[7]
    if model == 'CM':
        return label, {
            '2adic_index': int(0),
            '2adic_log_level': None,
            '2adic_gens': None,
            '2adic_label': None,
        }

    index = int(data[4])
    level = ZZ(data[5])
    log_level = int(level.valuation(2))
    assert 2**log_level==level
    if data[6]=='[]':
        gens=[]
    else:
        gens = data[6][1:-1].replace('],[','];[').split(';')
        gens = [[int(c) for c in g[1:-1].split(',')] for g in gens]

    return label, {
            '2adic_index': index,
            '2adic_log_level': log_level,
            '2adic_gens': gens,
            '2adic_label': model,
    }
Beispiel #21
0
def integer_mod_ring():
    """
    Return a random ring of integers modulo n with n at most 50000.

    EXAMPLES:
        sage: sage.rings.tests.integer_mod_ring()
        Ring of integers modulo 30029
    """
    from sage.all import ZZ, IntegerModRing
    n = ZZ.random_element(x=2,y=50000)
    return IntegerModRing(n)
Beispiel #22
0
def quadratic_number_field():
    """
    Return a quadratic extension of QQ.

    EXAMPLES:
        sage: sage.rings.tests.quadratic_number_field()
        Number Field in a with defining polynomial x^2 - 61099
    """
    from sage.all import ZZ, QuadraticField
    while True:
        d = ZZ.random_element(x=-10**5, y=10**5)
        if not d.is_square():
            return QuadraticField(d,'a')
Beispiel #23
0
 def randomize(self, prime):
     assert not self.randomized
     MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), self.size)
     def random_matrix():
         while True:
             m = MSZp.random_element()
             if not m.is_singular() and m.rank() == self.size:
                 return m, m.inverse()
     m0, m0i = random_matrix()
     self.bp[0] = self.bp[0].group(MSZp, prime).mult_left(m0)
     for i in xrange(1, len(self.bp)):
         mi, mii = random_matrix()
         self.bp[i-1] = self.bp[i-1].group(MSZp, prime).mult_right(mii)
         self.bp[i] = self.bp[i].group(MSZp, prime).mult_left(mi)
     self.bp[-1] = self.bp[-1].group(MSZp, prime).mult_right(m0i)
     VSZp = VectorSpace(ZZ.residue_field(ZZ.ideal(prime)), self.size)
     self.s = copy(VSZp.zero())
     self.s[0] = 1
     self.t = copy(VSZp.zero())
     self.t[len(self.t) - 1] = 1
     self.m0, self.m0i = m0, m0i
     self.randomized = True
Beispiel #24
0
def get_cusp_expansions_of_newform(k, N=1, fi=0, prec=10):
    r"""
    Get and return Fourier coefficients of all cusps where there exist Atkin-Lehner involutions for these cusps.

    INPUT:

     - ''k'' -- positive integer : the weight
     - ''N'' -- positive integer (default 1) : level
     - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi]
     - ''prec'' -- integer (the number of coefficients to get)

     OUTPUT:

     - ''s'' string giving the Atkin-Lehner eigenvalues corresponding to the Cusps (where possible)
    """
    res = dict()
    (t, f) = _get_newform(k, N, 0, fi)
    if(not t):
        return s
    res[Infinity] = 1
    for c in f.group().cusps():
        if(c == Cusp(Infinity)):
            continue
        res[c] = list()
        cusp = QQ(c)
        q = cusp.denominator()
        p = cusp.numerator()
        d = ZZ(cusp * N)
        if(d == 0):
            ep = f.atkin_lehner_eigenvalue()
        if(d.divides(N) and gcd(ZZ(N / d), ZZ(d)) == 1):
            ep = f.atkin_lehner_eigenvalue(ZZ(d))
        else:
            # this case is not known...
            res[c] = None
            continue
        res[c] = ep
    s = html.table([res.keys(), res.values()])
    return s
Beispiel #25
0
def test_eigenvalues(prec=100,nmax=10,dimmax=10):
    r"""
    Test the eigenvalue computations for some random matrices.
    """
    F = MPComplexField(prec)
    dim = ZZ.random_element(2,dimmax)
    M = MatrixSpace(F,dim)
    for n in range(nmax):
	A,U,l=random_matrix_eigenvalues(F,dim)
	ev = A.eigenvalues()
	ev.sort(); l.sort()
	test = max([abs(ev[j]-l[j]) for j in range(len(ev))])
	assert test < A.eps()*100
Beispiel #26
0
def prime_finite_field():
    """
    Create a random prime finite field with cardinality at most 10^20.

    OUTPUT:
        a prime finite field

    EXAMPLES:
        sage: sage.rings.tests.prime_finite_field()
        Finite Field of size 64748301524082521489
    """
    from sage.all import ZZ, GF
    return GF(ZZ.random_element(x=2, y=10**20 - 12).next_prime())
Beispiel #27
0
    def init_elliptic_modular_form(self, F, number):
        """
        Initiate with an Elliptic Modular Form.
        """
        self.number = number
        self.original_object = [[F,number]]
        self.object_type = "Elliptic Modular newform"
        self.dim = 2
        self.weight = ZZ(F.weight)
        self.motivic_weight = ZZ(F.weight) - 1
        self.conductor = ZZ(F.level)
        self.bad_semistable_primes = [fa[0] for fa in self.conductor.factor() if fa[1]==1 ]
        # should be including primes of bad red that are pot good
        # however I don't know how to recognise them
        self.bad_pot_good = []
        self.langlands = True
        self.mu_fe = []
        self.nu_fe = [ZZ(F.weight-1)/ZZ(2)]
        self.primitive = True
        self.selfdual = True
        self.coefficient_type = 2
        self.coefficient_period = 0
        self.sign = (-1) ** (self.weight / 2.)
        if self.conductor != 1:
            for p, ev in F.atkin_lehner_eigenvals:
                self.sign *= ev**(self.conductor.valuation(p))
        self.gammaV = [0,1]
        self.set_dokchitser_Lfunction()
        self.set_number_of_coefficients()
        self.besancon_bound = 300

        def eu(p):
            """
            Local euler factor
            """
            # There was no function q_expansion_embeddings before the transition to postgres
            # so I'm not sure what this is supposed to do.
            ans = F.q_expansion_embeddings(p + 1)
            K = ComplexField()
            R = PolynomialRing(K, "T")
            T = R.gens()[0]
            N = self.conductor
            if N % p != 0 : # good reduction
                return 1 - ans[p-1][self.number] * T + T**2
            elif N % (p**2) != 0: # semistable reduction
                return 1 - ans[p-1][self.number] * T
            else:
                return R(1)

        self.local_euler_factor = eu
        self.ld.gp().quit()
Beispiel #28
0
 def _iter_ideals(self, primes=False, number=None):
     """
     Iterator through all ideals of self.  Delivers dicts with keys
     'label' and 'ideal'.
     """
     count = 0
     ilabel = 1
     norm = ZZ(0)
     ideals = self.ideals
     if primes:
         ideals = self.primes
     for idlstr in ideals:
         N,n,idl,_ = str2ideal(self.K(),idlstr)
         assert idl.norm() == N and idl.smallest_integer() == n
         if N != norm:
             ilabel = ZZ(1)
             norm = N
         label = N.str() + '.' + ilabel.str()
         yield {'label':label, 'ideal':idl}
         ilabel += 1
         count += 1
         if count==number:
             raise StopIteration
Beispiel #29
0
def mu_info(n):
    """ return data for ST group mu(n); for n > 2 these groups are irrational and not stored in the database """
    n = ZZ(n)
    rec = {}
    rec['label'] = "0.1.%d"%n
    rec['weight'] = 0
    rec['degree'] = 1
    rec['rational'] = boolean_name(True if n <= 2 else False)
    rec['name'] = 'mu(%d)'%n
    rec['pretty'] = '\mu(%d)'%n
    rec['real_dimension'] = 0
    rec['components'] = int(n)
    rec['ambient'] = '\mathrm{O}(1)' if n <= 2 else '\mathrm{U}(1)'
    rec['connected'] = boolean_name(rec['components'] == 1)
    rec['st0_name'] = '\mathrm{SO}(1)'
    rec['identity_component'] = st0_pretty(rec['st0_name'])
    rec['st0_description'] = '\\mathrm{trivial}'
    rec['component_group'] = 'C_{%d}'%n
    rec['trace_zero_density']='0'
    rec['abelian'] = boolean_name(True)
    rec['cyclic'] = boolean_name(True)
    rec['solvable'] = boolean_name(True)
    rec['gens'] = r'\left[\zeta_{%d}\right]'%n
    rec['numgens'] = 1
    rec['subgroups'] = comma_separated_list([st_link("0.1.%d"%(n/p)) for p in n.prime_factors()])
    # only list supgroups with the same ambient (i.e.if mu(n) lies in O(1) don't list supgroups that are not)
    if n == 1:
        rec['supgroups'] = st_link("0.1.2")
    elif n > 2:
        rec['supgroups'] = comma_separated_list([st_link("0.1.%d"%(p*n)) for p in [2,3,5]] + ["$\ldots$"])
    rec['moments'] = [['x'] + [ '\\mathrm{E}[x^{%d}]'%m for m in range(13)]]
    rec['moments'] += [['a_1'] + ['1' if m % n == 0  else '0' for m in range(13)]]
    rec['trace_moments'] = trace_moments(rec['moments'])
    rational_traces = [1] if n%2 else [1,-1]
    rec['counts'] = [['a_1', [[t,1] for t in rational_traces]]]
    rec['probabilities'] = [['\\mathrm{P}[a_1=%d]=\\frac{1}{%d}'%(m,n)] for m in rational_traces]
    return rec
Beispiel #30
0
def add_sha_tor_primes(N1,N2):
    """
    Add the 'sha', 'sha_primes', 'torsion_primes' fields to every
    curve in the database whose conductor is between N1 and N2
    inclusive.
    """
    query = {}
    query['conductor'] = { '$gte': int(N1), '$lte': int(N2) }
    res = curves.find(query)
    res = res.sort([('conductor', pymongo.ASCENDING)])
    n = 0
    for C in res:
        label = C['lmfdb_label']
        if n%1000==0: print label
        n += 1
        torsion = ZZ(C['torsion'])
        sha = RR(C['sha_an']).round()
        sha_primes = sha.prime_divisors()
        torsion_primes = torsion.prime_divisors()
        data = {}
        data['sha'] = int(sha)
        data['sha_primes'] = [int(p) for p in sha_primes]
        data['torsion_primes'] = [int(p) for p in torsion_primes]
        curves.update({'lmfdb_label': label}, {"$set": data}, upsert=True)
Beispiel #31
0
        except Exception as e:
            print(self.client_address[0], e)  # logging
            self.wfile.write(str(e).encode() + b'\n')
            return

        # the signature is valid -> looks like the backdoor does exist!
        self.wfile.write(flag + b'\n')

        # logging
        print(self.client_address[0], "got FLAG!")


if __name__ == "__main__":
    from yaecc_secret import a, A, flag

    assert ZZ(a) * G == A
    with open("public_key.txt", "w") as f:
        f.write(str(A))

    HOST, PORT = "0.0.0.0", 5555  # maybe updated
    server = socketserver.ForkingTCPServer((HOST, PORT), Handler, False)
    server.allow_reuse_address = True
    server.server_bind()
    server.server_activate()

    def timeout_handler(_, __):
        raise TimeoutError("Timeout!")

    signal.signal(signal.SIGALRM, timeout_handler)

    print("Serving at", HOST, PORT)
Beispiel #32
0
def factorint(inp):
    return latex(ZZ(inp).factor())
Beispiel #33
0
def ideal_from_label(K, lab):
    r"""Returns the ideal with label lab in the quadratic field K.
    """
    N, c, d = [ZZ(c) for c in lab.split(".")]
    a = N // d
    return K.ideal(a, K([c, d]))
def read_line(line):
    r""" Parses one line from input file.  Returns the hash and a
    dict containing fields with keys as above.
    """
    fields = line.split(":")
    assert len(fields) == 6
    label = fields[
        1]  # use this isogeny class label to get info about the curve
    E = curves.find_one({'iso': label})

    data = constant_data()
    instances = {}

    # Set the fields in the Instances collection:

    cond = data['conductor'] = int(E['conductor'])
    iso = E['lmfdb_iso'].split('.')[1]
    instances['url'] = 'EllipticCurve/Q/%s/%s' % (cond, iso)
    instances['Lhash'] = Lhash = fields[0]
    instances['type'] = 'ECQ'

    # Set the fields in the Lfunctions collection:

    data['Lhash'] = Lhash
    data['root_number'] = int(fields[2])
    data['order_of_vanishing'] = int(E['rank'])
    data['central_character'] = '%s.1' % cond
    data['st_group'] = 'N(U(1))' if E['cm'] else 'SU(2)'
    data['leading_term'] = float(E['special_value'])

    # Zeros

    zeros = fields[4][1:-1].split(",")
    # omit negative ones and 0, using only string tests:
    data['positive_zeros'] = [y for y in zeros if y != '0' and y[0] != '-']
    data['z1'] = data['positive_zeros'][0]
    data['z2'] = data['positive_zeros'][1]
    data['z3'] = data['positive_zeros'][2]

    # plot data

    plot_xy = [[float(v) for v in vv.split(",")]
               for vv in fields[5][2:-3].split("],[")]
    # constant difference in x-coordinate sequence:
    data['plot_delta'] = plot_xy[1][0] - plot_xy[0][0]
    # list of y coordinates for x>0:
    data['plot_values'] = [y for x, y in plot_xy if x >= 0]

    # Euler factors: we need the ap which are currently not in the
    # database so we call Sage.  It might be a good idea to store in
    # the ec database (1) all ap for p<100; (2) all ap for bad p.
    Esage = EllipticCurve([ZZ(a) for a in E['ainvs']])
    data['bad_lfactors'] = make_bad_lfactors(Esage)
    data['euler_factors'] = make_euler_factors(Esage)

    # Dirichlet coefficients

    an = Esage.anlist(10)
    for n in range(2, 11):
        data['A%s' % n] = str(an[n])
        data['a%s' % n] = [an[n] / sqrt(float(n)), 0]

    return Lhash, data, instances
Beispiel #35
0
def make_conductor(ecnfdata, hfield):
    N, c, d = [ZZ(c) for c in ecnfdata['conductor_ideal'][1:-1].split(',')]
    return hfield.K().ideal([N // d, c + d * hfield.K().gen()])
Beispiel #36
0
def render_group_webpage(args):
    data = {}
    if 'label' in args:
        label = clean_input(args['label'])
        label = label.replace('t', 'T')
        data = db.gps_transitive.lookup(label)
        if data is None:
            if re.match(r'^\d+T\d+$', label):
                flash_error("Group %s was not found in the database.", label)
            else:
                flash_error("%s is not a valid label for a Galois group.",
                            label)
            return redirect(url_for(".index"))
        data['label_raw'] = label.lower()
        title = 'Galois Group: ' + label
        wgg = WebGaloisGroup.from_nt(data['n'], data['t'])
        data['wgg'] = wgg
        n = data['n']
        t = data['t']
        data['yesno'] = yesno
        order = data['order']
        data['orderfac'] = latex(ZZ(order).factor())
        orderfac = latex(ZZ(order).factor())
        data['ordermsg'] = "$%s=%s$" % (order, latex(orderfac))
        if order == 1:
            data['ordermsg'] = "$1$"
        if ZZ(order).is_prime():
            data['ordermsg'] = "$%s$ (is prime)" % order
        pgroup = len(ZZ(order).prime_factors()) < 2
        if wgg.num_conjclasses() < 50:
            data['cclasses'] = wgg.conjclasses()
        if ZZ(order) < ZZ(10000000) and wgg.num_conjclasses() < 21:
            data['chartable'] = chartable(n, t)
        data['gens'] = wgg.generator_string()
        if n == 1 and t == 1:
            data['gens'] = 'None needed'
        data['num_cc'] = comma(wgg.num_conjclasses())
        data['parity'] = "$%s$" % data['parity']
        data['subinfo'] = subfield_display(n, data['subfields'])
        data['resolve'] = resolve_display(data['quotients'])
        if data['gapid'] == 0:
            data['gapid'] = "Data not available"
        else:
            data['gapid'] = small_group_display_knowl(
                int(data['order']), int(data['gapid']),
                str([int(data['order']),
                     int(data['gapid'])]))
        data['otherreps'] = wgg.otherrep_list()
        ae = data['arith_equiv']
        if ae > 0:
            if ae > 1:
                data[
                    'arith_equiv'] = r'A number field with this Galois group has %d <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields.' % ae
            else:
                data[
                    'arith_equiv'] = r'A number field with this Galois group has exactly one <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> field.'
        elif ae > -1:
            data[
                'arith_equiv'] = r'A number field with this Galois group has no <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields.'
        else:
            data[
                'arith_equiv'] = r'Data on whether or not a number field with this Galois group has <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields has not been computed.'
        intreps = list(db.gps_gmodules.search({'n': n, 't': t}))
        if len(intreps) > 0:
            data['int_rep_classes'] = [str(z[0]) for z in intreps[0]['gens']]
            for onerep in intreps:
                onerep['gens'] = [
                    list_to_latex_matrix(z[1]) for z in onerep['gens']
                ]
            data['int_reps'] = intreps
            data['int_reps_complete'] = int_reps_are_complete(intreps)
            dcq = data['moddecompuniq']
            if dcq[0] == 0:
                data['decompunique'] = 0
            else:
                data['decompunique'] = dcq[0]
                data['isoms'] = [[mult2mult(z[0]),
                                  mult2mult(z[1])] for z in dcq[1]]
                data['isoms'] = [[
                    modules2string(n, t, z[0]),
                    modules2string(n, t, z[1])
                ] for z in data['isoms']]
                #print dcq[1]
                #print data['isoms']

        friends = []
        if db.nf_fields.exists({'degree': n, 'galt': t}):
            friends.append(
                ('Number fields with this Galois group',
                 url_for('number_fields.number_field_render_webpage') +
                 "?galois_group=%dT%d" % (n, t)))
        prop2 = [
            ('Label', label),
            ('Order', r'\(%s\)' % order),
            ('n', r'\(%s\)' % data['n']),
            ('Cyclic', yesno(data['cyc'])),
            ('Abelian', yesno(data['ab'])),
            ('Solvable', yesno(data['solv'])),
            ('Primitive', yesno(data['prim'])),
            ('$p$-group', yesno(pgroup)),
        ]
        pretty = group_display_short(n, t, emptyifnotpretty=True)
        if len(pretty) > 0:
            prop2.extend([('Group:', pretty)])
            data['pretty_name'] = pretty
        data['name'] = re.sub(r'_(\d+)', r'_{\1}', data['name'])
        data['name'] = re.sub(r'\^(\d+)', r'^{\1}', data['name'])
        data['nilpotency'] = '$%s$' % data['nilpotency']
        if data['nilpotency'] == '$-1$':
            data['nilpotency'] += ' (not nilpotent)'

        bread = get_bread([(label, ' ')])
        return render_template("gg-show-group.html",
                               credit=GG_credit,
                               title=title,
                               bread=bread,
                               info=data,
                               properties=prop2,
                               friends=friends,
                               KNOWL_ID="gg.%s" % data['label_raw'],
                               learnmore=learnmore_list())
Beispiel #37
0
def make_order_key(order):
    order1 = int(ZZ(order).log(10))
    return '%03d%s' % (order1, str(order))
Beispiel #38
0
def set_info_for_web_newform(level=None,
                             weight=None,
                             character=None,
                             label=None,
                             **kwds):
    r"""
    Set the info for on modular form.

    """
    info = to_dict(kwds)
    info['level'] = level
    info['weight'] = weight
    info['character'] = character
    info['label'] = label
    if level is None or weight is None or character is None or label is None:
        s = "In set info for one form but do not have enough args!"
        s += "level={0},weight={1},character={2},label={3}".format(
            level, weight, character, label)
        emf_logger.critical(s)
    emf_logger.debug("In set_info_for_one_mf: info={0}".format(info))
    prec = my_get(info, 'prec', default_prec, int)
    bprec = my_get(info, 'bprec', default_display_bprec, int)
    emf_logger.debug("PREC: {0}".format(prec))
    emf_logger.debug("BITPREC: {0}".format(bprec))
    try:
        WNF = WebNewForm_cached(level=level,
                                weight=weight,
                                character=character,
                                label=label)
        if not WNF.has_updated():
            raise IndexError(
                "Unfortunately, we do not have this newform in the database.")
        info['character_order'] = WNF.character.order
        info['code'] = WNF.code
        emf_logger.debug("defined webnewform for rendering!")
    except IndexError as e:
        info['error'] = e.message
    url1 = url_for("emf.render_elliptic_modular_forms")
    url2 = url_for("emf.render_elliptic_modular_forms", level=level)
    url3 = url_for("emf.render_elliptic_modular_forms",
                   level=level,
                   weight=weight)
    url4 = url_for("emf.render_elliptic_modular_forms",
                   level=level,
                   weight=weight,
                   character=character)
    bread = [(EMF_TOP, url1)]
    bread.append(("Level %s" % level, url2))
    bread.append(("Weight %s" % weight, url3))
    bread.append(("Character \( %s \)" % (WNF.character.latex_name), url4))
    bread.append(
        ("Newform %d.%d.%d.%s" % (level, weight, int(character), label), ''))
    info['bread'] = bread

    properties2 = list()
    friends = list()
    space_url = url_for('emf.render_elliptic_modular_forms',
                        level=level,
                        weight=weight,
                        character=character)
    friends.append(
        ('\( S_{%s}(%s, %s)\)' %
         (WNF.weight, WNF.level, WNF.character.latex_name), space_url))
    if hasattr(WNF.base_ring, "lmfdb_url") and WNF.base_ring.lmfdb_url:
        friends.append(('Number field ' + WNF.base_ring.lmfdb_pretty,
                        WNF.base_ring.lmfdb_url))
    if hasattr(WNF.coefficient_field,
               "lmfdb_url") and WNF.coefficient_field.lmfdb_label:
        friends.append(('Number field ' + WNF.coefficient_field.lmfdb_pretty,
                        WNF.coefficient_field.lmfdb_url))
    friends = uniq(friends)
    friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)",
                    WNF.character.url()))

    if WNF.dimension == 0 and not info.has_key('error'):
        info['error'] = "This space is empty!"
    info['title'] = 'Newform ' + WNF.hecke_orbit_label
    info['learnmore'] = [('History of Modular forms',
                          url_for('holomorphic_mf_history'))]
    if 'error' in info:
        return info
    ## Until we have figured out how to do the embeddings correctly we don't display the Satake
    ## parameters for non-trivial characters....

    ## Example to illustrate the different cases
    ## base              = CyclotomicField(n) -- of degree phi(n)
    ## coefficient_field = NumberField( p(x)) for some p in base['x'] of degree m
    ##   we would then have cdeg = m*phi(n) and bdeg = phi(n)
    ##   and rdeg = m
    ## Unfortunately, for e.g. base = coefficient_field = CyclotomicField(6)
    ## we get coefficient_field.relative_degree() == 2 although it should be 1
    cdeg = WNF.coefficient_field.absolute_degree()
    bdeg = WNF.base_ring.absolute_degree()
    if cdeg == 1:
        rdeg = 1
    else:
        ## just setting rdeg = WNF.coefficient_field.relative_degree() does not give correct result...
        ##
        rdeg = QQ(cdeg) / QQ(bdeg)
    cf_is_QQ = (cdeg == 1)
    br_is_QQ = (bdeg == 1)
    if cf_is_QQ:
        info['satake'] = WNF.satake
    if WNF.complexity_of_first_nonvanishing_coefficients(
    ) > default_max_height:
        info['qexp'] = ""
        info['qexp_display'] = ''
        info['hide_qexp'] = True
        n, c = WNF.first_nonvanishing_coefficient()
        info['trace_nv'] = latex(WNF.first_nonvanishing_coefficient_trace())
        info['norm_nv'] = '\\approx ' + latex(
            WNF.first_nonvanishing_coefficient_norm().n())
        info['index_nv'] = n
    else:
        if WNF.prec < prec:
            #get WNF record at larger prec
            WNF.prec = prec
            WNF.update_from_db()
        info['qexp'] = WNF.q_expansion_latex(prec=10, name='\\alpha ')
        info['qexp_display'] = url_for(".get_qexp_latex",
                                       level=level,
                                       weight=weight,
                                       character=character,
                                       label=label)
        info["hide_qexp"] = False
    info['max_cn_qexp'] = WNF.q_expansion.prec()
    ## All combinations should be tested...
    ## 13/4/4/a -> base ring = coefficient_field = QQ(zeta_6)
    ## 13/3/8/a ->  base_ring = QQ(zeta_4), coefficient_field has poly x^2+(2\zeta_4+2x-3\zeta_$ over base_ring
    ## 13/4/3/a ->  base_ring = coefficient_field = QQ(zeta_3)
    ## 13/4/1/a -> all rational
    ## 13/6/1/a/ -> base_ring = QQ, coefficient_field = Q(sqrt(17))
    ## These are variables which needs to be set properly below
    info['polvars'] = {'base_ring': 'x', 'coefficient_field': '\\alpha'}
    if not cf_is_QQ:
        if rdeg > 1:  # not WNF.coefficient_field == WNF.base_ring:
            ## Here WNF.base_ring should be some cyclotomic field and we have an extension over this.
            p1 = WNF.coefficient_field.relative_polynomial()
            c_pol_ltx = web_latex_poly(p1,
                                       '\\alpha')  # make the variable \alpha
            c_pol_ltx_x = web_latex_poly(p1, 'x')
            zeta = p1.base_ring().gens()[0]
            #           p2 = zeta.minpoly() #this is not used anymore
            #           b_pol_ltx = web_latex_poly(p2, latex(zeta)) #this is not used anymore
            z1 = zeta.multiplicative_order()
            info['coeff_field'] = [
                WNF.coefficient_field.absolute_polynomial_latex('x'),
                c_pol_ltx_x, z1
            ]
            if hasattr(WNF.coefficient_field,
                       "lmfdb_url") and WNF.coefficient_field.lmfdb_url:
                info['coeff_field_pretty'] = [
                    WNF.coefficient_field.lmfdb_url,
                    WNF.coefficient_field.lmfdb_pretty,
                    WNF.coefficient_field.lmfdb_label
                ]
            if z1 == 4:
                info[
                    'polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).</div><br/>'.format(
                        c_pol_ltx)
                info['polvars']['base_ring'] = 'i'
            elif z1 <= 2:
                info[
                    'polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format(
                        c_pol_ltx)
            else:
                info[
                    'polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\) ' % (
                        c_pol_ltx, z1, z1)
                info['polvars']['base_ring'] = '\zeta_{{ {0} }}'.format(z1)
                if z1 == 3:
                    info[
                        'polynomial_st'] += 'is a primitive cube root of unity.'
                else:
                    info[
                        'polynomial_st'] += 'is a primitive {0}-th root of unity.'.format(
                            z1)
        elif not br_is_QQ:
            ## Now we have base and coefficient field being equal, meaning that since the coefficient field is not QQ it is some cyclotomic field
            ## generated by some \zeta_n
            p1 = WNF.coefficient_field.absolute_polynomial()
            z1 = WNF.coefficient_field.gens()[0].multiplicative_order()
            c_pol_ltx = web_latex_poly(p1, '\\zeta_{{{0}}}'.format(z1))
            c_pol_ltx_x = web_latex_poly(p1, 'x')
            info['coeff_field'] = [
                WNF.coefficient_field.absolute_polynomial_latex('x'),
                c_pol_ltx_x
            ]
            if hasattr(WNF.coefficient_field,
                       "lmfdb_url") and WNF.coefficient_field.lmfdb_url:
                info['coeff_field_pretty'] = [
                    WNF.coefficient_field.lmfdb_url,
                    WNF.coefficient_field.lmfdb_pretty,
                    WNF.coefficient_field.lmfdb_label
                ]
            if z1 == 4:
                info[
                    'polynomial_st'] = '<div class="where">where \(\zeta_4=e^{{\\frac{{\\pi i}}{{ 2 }} }}=i \).</div>'.format(
                        c_pol_ltx)
                info['polvars']['coefficient_field'] = 'i'
            elif z1 <= 2:
                info['polynomial_st'] = ''
            else:
                info[
                    'polynomial_st'] = '<div class="where">where \(\zeta_{{{0}}}=e^{{\\frac{{2\\pi i}}{{ {0} }} }}\) '.format(
                        z1)
                info['polvars']['coefficient_field'] = '\zeta_{{{0}}}'.format(
                    z1)
                if z1 == 3:
                    info[
                        'polynomial_st'] += 'is a primitive cube root of unity.</div>'
                else:
                    info[
                        'polynomial_st'] += 'is a primitive {0}-th root of unity.</div>'.format(
                            z1)
    else:
        info['polynomial_st'] = ''
    if info["hide_qexp"]:
        info['polynomial_st'] = ''
    info['degree'] = int(cdeg)
    if cdeg == 1:
        info['is_rational'] = 1
        info['coeff_field_pretty'] = [
            WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty
        ]
    else:
        info['is_rational'] = 0
    emf_logger.debug("PREC2: {0}".format(prec))
    info['embeddings'] = WNF._embeddings[
        'values']  #q_expansion_embeddings(prec, bprec,format='latex')
    info['embeddings_len'] = len(info['embeddings'])
    properties2 = [('Level', str(level)), ('Weight', str(weight)),
                   ('Character', '$' + WNF.character.latex_name + '$'),
                   ('Label', WNF.hecke_orbit_label),
                   ('Dimension of Galois orbit', str(WNF.dimension))]
    if (ZZ(level)).is_squarefree():
        info['twist_info'] = WNF.twist_info
        if isinstance(info['twist_info'],
                      list) and len(info['twist_info']) > 0:
            info['is_minimal'] = info['twist_info'][0]
            if (info['twist_info'][0]):
                s = 'Is minimal<br>'
            else:
                s = 'Is a twist of lower level<br>'
            properties2 += [('Twist info', s)]
    else:
        info['twist_info'] = 'Twist info currently not available.'
        properties2 += [('Twist info', 'not available')]
    args = list()
    for x in range(5, 200, 10):
        args.append({'digits': x})
    alev = None
    CM = WNF._cm_values
    if CM is not None:
        if CM.has_key('tau') and len(CM['tau']) != 0:
            info['CM_values'] = CM
    info['is_cm'] = WNF.is_cm
    if WNF.is_cm == 1:
        info['cm_field'] = "2.0.{0}.1".format(-WNF.cm_disc)
        info['cm_disc'] = WNF.cm_disc
        info['cm_field_knowl'] = nf_display_knowl(
            info['cm_field'], getDBConnection(),
            field_pretty(info['cm_field']))
        info['cm_field_url'] = url_for("number_fields.by_label",
                                       label=info["cm_field"])
    if WNF.is_cm is None or WNF.is_cm == -1:
        s = '- Unknown (insufficient data)<br>'
    elif WNF.is_cm == 1:
        s = 'Yes<br>'
    else:
        s = 'No<br>'
    properties2.append(('CM', s))
    alev = WNF.atkin_lehner_eigenvalues()
    info['atkinlehner'] = None
    if isinstance(alev, dict) and len(alev.keys()) > 0 and level != 1:
        s1 = " Atkin-Lehner eigenvalues "
        s2 = ""
        for Q in alev.keys():
            s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q])
        properties2.append((s1, s2))
        emf_logger.debug("properties={0}".format(properties2))
        # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps()
        # if isinstance(alev,dict) and len(alev.keys())>0:
        #     emf_logger.debug("alev={0}".format(alev))
        #     info['atkinlehner'] = list()
        #     for Q in alev.keys():
        #         s = "\(" + latex(c) + "\)"
        #         Q = alev[c][0]
        #         ev = alev[c][1]
        #         info['atkinlehner'].append([Q, c, ev])
    if (level == 1):
        poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6', '')
        if poly != '':
            d, monom, coeffs = poly
            emf_logger.critical("poly={0}".format(poly))
            info['explicit_formulas'] = '\('
            for i in range(len(coeffs)):
                c = QQ(coeffs[i])
                s = ""
                if d > 1 and i > 0 and c > 0:
                    s = "+"
                if c < 0:
                    s = "-"
                if c.denominator() > 1:
                    cc = "\\frac{{ {0} }}{{ {1} }}".format(
                        abs(c.numerator()), c.denominator())
                else:
                    cc = str(abs(c))
                s += "{0} \cdot ".format(cc)
                a = monom[i][0]
                b = monom[i][1]
                if a == 0 and b != 0:
                    s += "E_6^{{ {0} }}".format(b)
                elif b == 0 and a != 0:
                    s += "E_4^{{ {0} }}".format(a)
                else:
                    s += "E_4^{{ {0} }}E_6^{{ {1} }}".format(a, b)
                info['explicit_formulas'] += s
            info['explicit_formulas'] += " \)"
    cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + \
        '&label=' + str(label)
    if len(WNF.parent.hecke_orbits) > 1:
        for label_other in WNF.parent.hecke_orbits.keys():
            if (label_other != label):
                s = 'Modular form '
                if character:
                    s += newform_label(level, weight, character, label_other)
                else:
                    s += newform_label(level, weight, 1, label_other)

                url = url_for('emf.render_elliptic_modular_forms',
                              level=level,
                              weight=weight,
                              character=character,
                              label=label_other)
                friends.append((s, url))

    s = 'L-Function '
    if character:
        s += newform_label(level, weight, character, label)
    else:
        s += newform_label(level, weight, 1, label)
    # url =
    # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s"
    # %(level,weight,character,label,0)
    url = '/L' + url_for('emf.render_elliptic_modular_forms',
                         level=level,
                         weight=weight,
                         character=character,
                         label=label)
    if WNF.coefficient_field_degree > 1:
        for h in range(WNF.coefficient_field_degree):
            s0 = s + ".{0}".format(h)
            url0 = url + "{0}/".format(h)
            friends.append((s0, url0))
    else:
        friends.append((s, url))
    # if there is an elliptic curve over Q associated to self we also list that
    if WNF.weight == 2 and WNF.coefficient_field_degree == 1:
        llabel = str(level) + '.' + label
        s = 'Elliptic curve isogeny class ' + llabel
        url = '/EllipticCurve/Q/' + llabel
        friends.append((s, url))
    info['properties2'] = properties2
    info['friends'] = friends
    info['max_cn'] = WNF.max_available_prec()
    return info
Beispiel #39
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
        # actual elliptic curve E, and compute some further (easy)
        # data about it.
        #

        # Weierstrass equation

        data = self.data = {}
        data['ainvs'] = [int(ai) for ai in self.ainvs]
        self.E = EllipticCurve(data['ainvs'])
        data['equation'] = web_latex(self.E)

        # conductor, j-invariant and discriminant

        data['conductor'] = N = ZZ(self.conductor)
        bad_primes = N.prime_factors()
        try:
            data['j_invariant'] = QQ(str(self.jinv))
        except KeyError:
            data['j_invariant'] = self.E.j_invariant()
        data['j_inv_factor'] = latex(0)
        if data['j_invariant']:
            data['j_inv_factor'] = latex(data['j_invariant'].factor())
        data['j_inv_str'] = unicode(str(data['j_invariant']))
        data['j_inv_latex'] = web_latex(data['j_invariant'])
        data['disc'] = D = self.E.discriminant()
        data['disc_latex'] = web_latex(data['disc'])
        data['disc_factor'] = latex(data['disc'].factor())
        data['cond_factor'] = latex(N.factor())
        data['cond_latex'] = web_latex(N)

        # CM and endomorphism ring

        data['CMD'] = self.cm
        data['CM'] = "no"
        data['EndE'] = "\(\Z\)"
        if self.cm:
            data['CM'] = "yes (\(D=%s\))" % data['CMD']
            if data['CMD'] % 4 == 0:
                d4 = ZZ(data['CMD']) // 4
                data['EndE'] = "\(\Z[\sqrt{%s}]\)" % d4
            else:
                data['EndE'] = "\(\Z[(1+\sqrt{%s})/2]\)" % data['CMD']

        # modular degree

        try:
            data['degree'] = self.degree
        except AttributeError:
            try:
                data['degree'] = self.E.modular_degree()
            except RuntimeError:
                data['degree']  # invalid, but will be displayed nicely

        # Minimal quadratic twist

        E_pari = self.E.pari_curve()
        from sage.libs.pari.all import PariError
        try:
            minq, minqD = self.E.minimal_quadratic_twist()
        except PariError:  # this does occur with 164411a1
            ec.debug(
                "PariError computing minimal quadratic twist of elliptic curve %s"
                % lmfdb_label)
            minq = self.E
            minqD = 1
        data['minq_D'] = minqD
        if self.E == minq:
            data['minq_label'] = self.lmfdb_label
            data['minq_info'] = '(itself)'
        else:
            minq_ainvs = [str(c) for c in minq.ainvs()]
            data['minq_label'] = db_ec().find_one({'ainvs':
                                                   minq_ainvs})['lmfdb_label']
            data['minq_info'] = '(by %s)' % minqD

        minq_N, minq_iso, minq_number = split_lmfdb_label(data['minq_label'])

        # rational and integral points

        mw = self.mw = {}

        xintpoints_projective = [self.E.lift_x(x) for x in self.xintcoords]
        xintpoints = [P.xy() for P in xintpoints_projective]
        mw['int_points'] = ', '.join(web_latex(P) for P in xintpoints)

        # Generators of infinite order

        mw['rank'] = self.rank
        try:
            self.generators = [self.E(g) for g in parse_points(self.gens)]
            mw['generators'] = [web_latex(P.xy()) for P in self.generators]
            mw['heights'] = [P.height() for P in self.generators]
        except AttributeError:
            mw['generators'] = ''
            mw['heights'] = []

        # Torsion subgroup: order, structure, generators

        mw['tor_order'] = self.torsion
        tor_struct = [int(c) for c in self.torsion_structure]
        if mw['tor_order'] == 1:
            mw['tor_struct'] = '\mathrm{Trivial}'
            mw['tor_gens'] = ''
        else:
            mw['tor_struct'] = ' \\times '.join(
                ['\Z/{%s}\Z' % n for n in tor_struct])
            mw['tor_gens'] = ', '.join(
                web_latex(self.E(g).xy())
                for g in parse_points(self.torsion_generators))

        # Images of Galois representations

        try:
            data['galois_images'] = [
                trim_galois_image_code(s) for s in self.galois_images
            ]
            data['non_surjective_primes'] = self.non_surjective_primes
        except AttributeError:
            #print "No Galois image data"
            data['galois_images'] = []
            data['non_surjective_primes'] = []

        data['galois_data'] = [{
            'p': p,
            'image': im
        } for p, im in zip(data['non_surjective_primes'],
                           data['galois_images'])]

        if self.twoadic_gens:
            from sage.matrix.all import Matrix
            data['twoadic_gen_matrices'] = ','.join(
                [latex(Matrix(2, 2, M)) for M in self.twoadic_gens])
            data[
                'twoadic_rouse_url'] = ROUSE_URL_PREFIX + self.twoadic_label + ".html"
        # Leading term of L-function & BSD data

        bsd = self.bsd = {}

        r = self.rank
        if r >= 2:
            bsd['lder_name'] = "L^{(%s)}(E,1)/%s!" % (r, r)
        elif r:
            bsd['lder_name'] = "L'(E,1)"
        else:
            bsd['lder_name'] = "L(E,1)"

        bsd['reg'] = self.regulator
        bsd['omega'] = self.real_period
        bsd['sha'] = int(0.1 + self.sha_an)
        bsd['lder'] = self.special_value

        # Optimality (the optimal curve in the class is the curve
        # whose Cremona label ends in '1' except for '990h' which was
        # labelled wrongly long ago)

        if self.iso == '990h':
            data['Gamma0optimal'] = bool(self.number == 3)
        else:
            data['Gamma0optimal'] = bool(self.number == 1)

        data['p_adic_data_exists'] = False
        if data['Gamma0optimal']:
            data['p_adic_data_exists'] = (padic_db().find({
                'lmfdb_iso':
                self.lmfdb_iso
            }).count()) > 0
        data['p_adic_primes'] = [
            p for p in sage.all.prime_range(5, 100)
            if self.E.is_ordinary(p) and not p.divides(N)
        ]

        # Local data

        local_data = self.local_data = []
        # if we use E.tamagawa_numbers() it calls E.local_data(p) which
        # used to crash on some curves e.g. 164411a1
        tamagawa_numbers = []
        for p in bad_primes:
            local_info = self.E.local_data(p, algorithm="generic")
            local_data_p = {}
            local_data_p['p'] = p
            local_data_p['tamagawa_number'] = local_info.tamagawa_number()
            tamagawa_numbers.append(ZZ(local_info.tamagawa_number()))
            local_data_p['kodaira_symbol'] = web_latex(
                local_info.kodaira_symbol()).replace('$', '')
            local_data_p['reduction_type'] = local_info.bad_reduction_type()
            local_data_p['ord_cond'] = local_info.conductor_valuation()
            local_data_p['ord_disc'] = local_info.discriminant_valuation()
            local_data_p['ord_den_j'] = max(0,
                                            -self.E.j_invariant().valuation(p))
            local_data.append(local_data_p)

        cp_fac = [cp.factor() for cp in tamagawa_numbers]
        cp_fac = [
            latex(cp) if len(cp) < 2 else '(' + latex(cp) + ')'
            for cp in cp_fac
        ]
        bsd['tamagawa_factors'] = r'\cdot'.join(cp_fac)
        bsd['tamagawa_product'] = sage.misc.all.prod(tamagawa_numbers)

        cond, iso, num = split_lmfdb_label(self.lmfdb_label)
        data['newform'] = web_latex(self.E.q_eigenform(10))

        self.make_code_snippets()

        self.friends = [('Isogeny class ' + self.lmfdb_iso,
                         url_for(".by_double_iso_label",
                                 conductor=N,
                                 iso_label=iso)),
                        ('Minimal quadratic twist %s %s' %
                         (data['minq_info'], data['minq_label']),
                         url_for(".by_triple_label",
                                 conductor=minq_N,
                                 iso_label=minq_iso,
                                 number=minq_number)),
                        ('All twists ',
                         url_for(".rational_elliptic_curves", jinv=self.jinv)),
                        ('L-function',
                         url_for("l_functions.l_function_ec_page",
                                 label=self.lmfdb_label)),
                        ('Symmetric square L-function',
                         url_for("l_functions.l_function_ec_sym_page",
                                 power='2',
                                 label=self.lmfdb_iso)),
                        ('Symmetric 4th power L-function',
                         url_for("l_functions.l_function_ec_sym_page",
                                 power='4',
                                 label=self.lmfdb_iso)),
                        ('Modular form ' + self.lmfdb_iso.replace('.', '.2'),
                         url_for("emf.render_elliptic_modular_forms",
                                 level=int(N),
                                 weight=2,
                                 character=1,
                                 label=iso))]

        self.downloads = [('Download coefficients of q-expansion',
                           url_for(".download_EC_qexp",
                                   label=self.lmfdb_label,
                                   limit=100)),
                          ('Download all stored data',
                           url_for(".download_EC_all",
                                   label=self.lmfdb_label))]

        self.plot = encode_plot(self.E.plot())
        self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot
        self.properties = [('Label', self.lmfdb_label), (None, self.plot_link),
                           ('Conductor', '\(%s\)' % data['conductor']),
                           ('Discriminant', '\(%s\)' % data['disc']),
                           ('j-invariant', '%s' % data['j_inv_latex']),
                           ('CM', '%s' % data['CM']),
                           ('Rank', '\(%s\)' % mw['rank']),
                           ('Torsion Structure', '\(%s\)' % mw['tor_struct'])]

        self.title = "Elliptic Curve %s (Cremona label %s)" % (
            self.lmfdb_label, self.label)

        self.bread = [('Elliptic Curves', url_for("ecnf.index")),
                      ('$\Q$', url_for(".rational_elliptic_curves")),
                      ('%s' % N, url_for(".by_conductor", conductor=N)),
                      ('%s' % iso,
                       url_for(".by_double_iso_label",
                               conductor=N,
                               iso_label=iso)), ('%s' % num, ' ')]
Beispiel #40
0
def render_hgm_family_webpage(label):
    data = None
    info = {}
    data = db.hgm_families.lookup(label)
    if data is None:
        abort(404, "Hypergeometric motive family " + label + " was not found in the database.")
    title = 'Hypergeometric Motive Family:' + label
    A = data['A']
    B = data['B']
    hodge = data['famhodge']
    mydet = data['det']
    detexp = QQ(data['weight']*data['degree'])
    detexp = -detexp/2
    mydet = r'\Q(%s)\otimes\Q(\sqrt{'%str(detexp)
    if int(data['det'][0]) != 1:
        mydet += str(data['det'][0])
    if len(data['det'][1])>0:
        mydet += data['det'][1]
    if int(data['det'][0]) == 1 and len(data['det'][1])==0:
        mydet += '1'
    mydet += '})'
    bezoutmat = matrix(data['bezout'])
    bezoutdet = bezoutmat.det()
    bezoutmat = latex(bezoutmat)
    snf = data['snf']
    snf = list2Cnstring(snf)
    typee = 'Orthogonal'
    if (data['weight'] % 2) == 1 and (data['degree'] % 2) == 0:
        typee = 'Symplectic'
    ppart = [[2, [data['A2'],data['B2'],data['C2']]],
        [3, [data['A3'],data['B3'],data['C3']]],
        [5, [data['A5'],data['B5'],data['C5']]],
        [7, [data['A7'],data['B7'],data['C7']]]]
    prop2 = [
        ('Degree', '\(%s\)' % data['degree']),
        ('Weight',  '\(%s\)' % data['weight'])
    ]
    mono = [m for m in data['mono'] if m[1] != 0]
    mono = [[m[0], dogapthing(m[1]),
      getgroup(m[1],m[0]),
      latex(ZZ(m[1][0]).factor())] for m in mono]
    mono = [[m[0], m[1], m[2][0], splitint(m[1][0]/m[2][1],m[0]), m[3]] for m in mono]
    info.update({
                'A': A,
                'B': B,
                'degree': data['degree'],
                'weight': data['weight'],
                'hodge': hodge,
                'det': mydet,
                'snf': snf,
                'bezoutmat': bezoutmat,
                'bezoutdet': bezoutdet,
                'mono': mono,
                'imprim': data['imprim'],
                'ppart': ppart,
                'type': typee,
                'junk': small_group_display_knowl(18,2),
                'showlist': showlist
                })
    friends = [('Motives in the family', url_for('hypergm.index')+"?A=%s&B=%s" % (str(A), str(B)))]
#    if unramfriend != '':
#        friends.append(('Unramified subfield', unramfriend))
#    if rffriend != '':
#        friends.append(('Discriminant root field', rffriend))

    info.update({"plotcircle":  url_for(".hgm_family_circle_image", AB  =  "A"+".".join(map(str,A))+"_B"+".".join(map(str,B)))})
    info.update({"plotlinear": url_for(".hgm_family_linear_image", AB  = "A"+".".join(map(str,A))+"_B"+".".join(map(str,B)))})
    info.update({"plotconstant": url_for(".hgm_family_constant_image", AB  = "A"+".".join(map(str,A))+"_B"+".".join(map(str,B)))})
    bread = get_bread([(label, ' ')])
    return render_template("hgm-show-family.html", credit=HGM_credit, title=title, bread=bread, info=info, properties2=prop2, friends=friends, learnmore=learnmore_list())
Beispiel #41
0
def nice_coset_reps(G):
    r"""
        Compute a better/nicer list of right coset representatives [V_j]
        i.e. SL2Z = \cup G V_j
        Use this routine for known congruence subgroups.

        EXAMPLES::


            sage: G=MySubgroup(Gamma0(5))
            sage: G._get_coset_reps_from_G(Gamma0(5))
            [[1 0]
            [0 1], [ 0 -1]
            [ 1  0], [ 0 -1]
            [ 1  1], [ 0 -1]
            [ 1 -1], [ 0 -1]
            [ 1  2], [ 0 -1]
            [ 1 -2]]
    
        """
    cl = list()
    S, T = SL2Z.gens()
    lvl = G.generalised_level()
    # Start with identity rep.
    cl.append(SL2Z([1, 0, 0, 1]))
    if (not S in G):
        cl.append(S)
    # If the original group is given as a Gamma0 then
    # the reps are not the one we want
    # I.e. we like to have a fundamental domain in
    # -1/2 <=x <= 1/2 for Gamma0, Gamma1, Gamma
    for j in range(1, ZZ(ceil(RR(lvl / 2.0)) + 2)):
        for ep in [1, -1]:
            if (len(cl) >= G.index()):
                break
            # The ones about 0 are all of this form
            A = SL2Z([0, -1, 1, ep * j])
            # just make sure they are inequivalent
            try:
                for V in cl:
                    if ((A != V and A * V**-1 in G) or cl.count(A) > 0):
                        raise StopIteration()
                cl.append(A)
            except StopIteration:
                pass
    # We now add the rest of the "flips" of these reps.
    # So that we end up with a connected domain
    i = 1
    while (True):
        lold = len(cl)
        for V in cl:
            for A in [S, T, T**-1]:
                B = V * A
                try:
                    for W in cl:
                        if ((B * W**-1 in G) or cl.count(B) > 0):
                            raise StopIteration()
                    cl.append(B)
                except StopIteration:
                    pass
        if (len(cl) >= G.index() or lold >= len(cl)):
            # If we either did not add anything or if we added enough
            # we exit
            break
    # If we missed something (which is unlikely)
    if len(cl) != G.index():
        print("cl=", cl)
        raise ValueError("Problem getting coset reps! Need %s and got %s" %
                         (G.index(), len(cl)))
    return cl
Beispiel #42
0
    def make_E(self):
        #print("Creating ECNF object for {}".format(self.label))
        #sys.stdout.flush()
        K = self.field.K()

        # a-invariants
        self.ainvs = parse_ainvs(K, self.ainvs)
        self.latex_ainvs = web_latex(self.ainvs)
        self.numb = str(self.number)

        # Conductor, discriminant, j-invariant
        if self.conductor_norm == 1:
            N = K.ideal(1)
        else:
            N = ideal_from_string(K, self.conductor_ideal)
        # The following can trigger expensive computations!
        #self.cond = web_latex(N)
        self.cond = pretty_ideal(N)
        self.cond_norm = web_latex(self.conductor_norm)
        local_data = self.local_data

        # NB badprimes is a list of primes which divide the
        # discriminant of this model.  At most one of these might
        # actually be a prime of good reduction, if the curve has no
        # global minimal model.
        badprimes = [ideal_from_string(K, ld['p']) for ld in local_data]
        badnorms = [ZZ(ld['normp']) for ld in local_data]
        mindisc_ords = [ld['ord_disc'] for ld in local_data]

        # Assumption: the curve models stored in the database are
        # either global minimal models or minimal at all but one
        # prime, so the list here has length 0 or 1:

        self.non_min_primes = [ideal_from_string(K, P) for P in self.non_min_p]
        self.is_minimal = (len(self.non_min_primes) == 0)
        self.has_minimal_model = self.is_minimal
        disc_ords = [ld['ord_disc'] for ld in local_data]
        if not self.is_minimal:
            Pmin = self.non_min_primes[0]
            P_index = badprimes.index(Pmin)
            self.non_min_prime = pretty_ideal(Pmin)
            disc_ords[P_index] += 12

        if self.conductor_norm == 1:  # since the factorization of (1) displays as "1"
            self.fact_cond = self.cond
            self.fact_cond_norm = '1'
        else:
            Nfac = Factorization([(P, ld['ord_cond'])
                                  for P, ld in zip(badprimes, local_data)])
            self.fact_cond = web_latex_ideal_fact(Nfac)
            Nnormfac = Factorization([(q, ld['ord_cond'])
                                      for q, ld in zip(badnorms, local_data)])
            self.fact_cond_norm = web_latex(Nnormfac)

        # D is the discriminant ideal of the model
        D = prod([P**e for P, e in zip(badprimes, disc_ords)], K.ideal(1))
        self.disc = pretty_ideal(D)
        Dnorm = D.norm()
        self.disc_norm = web_latex(Dnorm)
        if Dnorm == 1:  # since the factorization of (1) displays as "1"
            self.fact_disc = self.disc
            self.fact_disc_norm = '1'
        else:
            Dfac = Factorization([(P, e)
                                  for P, e in zip(badprimes, disc_ords)])
            self.fact_disc = web_latex_ideal_fact(Dfac)
            Dnormfac = Factorization([(q, e)
                                      for q, e in zip(badnorms, disc_ords)])
            self.fact_disc_norm = web_latex(Dnormfac)

        if not self.is_minimal:
            Dmin = ideal_from_string(K, self.minD)
            self.mindisc = pretty_ideal(Dmin)
            Dmin_norm = Dmin.norm()
            self.mindisc_norm = web_latex(Dmin_norm)
            if Dmin_norm == 1:  # since the factorization of (1) displays as "1"
                self.fact_mindisc = self.mindisc
                self.fact_mindisc_norm = self.mindisc
            else:
                Dminfac = Factorization([
                    (P, e) for P, edd in zip(badprimes, mindisc_ords)
                ])
                self.fact_mindisc = web_latex_ideal_fact(Dminfac)
                Dminnormfac = Factorization([
                    (q, e) for q, e in zip(badnorms, mindisc_ords)
                ])
                self.fact_mindisc_norm = web_latex(Dminnormfac)

        j = self.field.parse_NFelt(self.jinv)
        # if j:
        #     d = j.denominator()
        #     n = d * j  # numerator exists for quadratic fields only!
        #     g = GCD(list(n))
        #     n1 = n / g
        #     self.j = web_latex(n1)
        #     if d != 1:
        #         if n1 > 1:
        #         # self.j = "("+self.j+")\(/\)"+web_latex(d)
        #             self.j = web_latex(r"\frac{%s}{%s}" % (self.j, d))
        #         else:
        #             self.j = web_latex(d)
        #         if g > 1:
        #             if n1 > 1:
        #                 self.j = web_latex(g) + self.j
        #             else:
        #                 self.j = web_latex(g)
        self.j = web_latex(j)

        self.fact_j = None
        # See issue 1258: some j factorizations work but take too long
        # (e.g. EllipticCurve/6.6.371293.1/1.1/a/1).  Note that we do
        # store the factorization of the denominator of j and display
        # that, which is the most interesting part.

        # The equation is stored in the database as a latex string.
        # Some of these have extraneous double quotes at beginning and
        # end, shich we fix here.  We also strip out initial \( and \)
        # (if present) which are added in the template.
        self.equation = self.equation.replace('"', '').replace('\\(',
                                                               '').replace(
                                                                   '\\)', '')

        # Images of Galois representations

        if not hasattr(self, 'galois_images'):
            #print "No Galois image data"
            self.galois_images = "?"
            self.non_surjective_primes = "?"
            self.galois_data = []
        else:
            self.galois_data = [{
                'p': p,
                'image': im
            } for p, im in zip(self.non_surjective_primes, self.galois_images)]

        # CM and End(E)
        self.cm_bool = "no"
        self.End = "\(\Z\)"
        if self.cm:
            self.rational_cm = K(self.cm).is_square()
            self.cm_sqf = ZZ(self.cm).squarefree_part()
            self.cm_bool = "yes (\(%s\))" % self.cm
            if self.cm % 4 == 0:
                d4 = ZZ(self.cm) // 4
                self.End = "\(\Z[\sqrt{%s}]\)" % (d4)
            else:
                self.End = "\(\Z[(1+\sqrt{%s})/2]\)" % self.cm

        # Galois images in CM case:
        if self.cm and self.galois_images != '?':
            self.cm_ramp = [
                p for p in ZZ(self.cm).support()
                if not p in self.non_surjective_primes
            ]
            self.cm_nramp = len(self.cm_ramp)
            if self.cm_nramp == 1:
                self.cm_ramp = self.cm_ramp[0]
            else:
                self.cm_ramp = ", ".join([str(p) for p in self.cm_ramp])

        # Sato-Tate:
        # The lines below will need to change once we have curves over non-quadratic fields
        # that contain the Hilbert class field of an imaginary quadratic field
        if self.cm:
            if self.signature == [0, 1] and ZZ(
                    -self.abs_disc * self.cm).is_square():
                self.ST = st_link_by_name(1, 2, 'U(1)')
            else:
                self.ST = st_link_by_name(1, 2, 'N(U(1))')
        else:
            self.ST = st_link_by_name(1, 2, 'SU(2)')

        # Q-curve / Base change
        try:
            qc = self.q_curve
            if qc == True:
                self.qc = "yes"
            elif qc == False:
                self.qc = "no"
            else:  # just in case
                self.qc = "not determined"
        except AttributeError:
            self.qc = "not determined"

        # Torsion
        self.ntors = web_latex(self.torsion_order)
        self.tr = len(self.torsion_structure)
        if self.tr == 0:
            self.tor_struct_pretty = "Trivial"
        if self.tr == 1:
            self.tor_struct_pretty = "\(\Z/%s\Z\)" % self.torsion_structure[0]
        if self.tr == 2:
            self.tor_struct_pretty = r"\(\Z/%s\Z\times\Z/%s\Z\)" % tuple(
                self.torsion_structure)

        torsion_gens = [parse_point(K, P) for P in self.torsion_gens]
        self.torsion_gens = ",".join([web_point(P) for P in torsion_gens])

        # Rank or bounds
        try:
            self.rk = web_latex(self.rank)
        except AttributeError:
            self.rk = "?"
        try:
            self.rk_bnds = "%s...%s" % tuple(self.rank_bounds)
        except AttributeError:
            self.rank_bounds = [0, Infinity]
            self.rk_bnds = "not available"

        # Generators
        try:
            gens = [parse_point(K, P) for P in self.gens]
            self.gens = ", ".join([web_point(P) for P in gens])
            if self.rk == "?":
                self.reg = "not available"
            else:
                if gens:
                    try:
                        self.reg = self.reg
                    except AttributeError:
                        self.reg = "not available"
                    pass  # self.reg already set
                else:
                    self.reg = 1  # otherwise we only get 1.00000...

        except AttributeError:
            self.gens = "not available"
            self.reg = "not available"
            try:
                if self.rank == 0:
                    self.reg = 1
            except AttributeError:
                pass

        # Local data

        # Fix for Kodaira symbols, which in the database start and end
        # with \( and \) and may have multiple backslashes.  Note that
        # to put a single backslash into a python string you have to
        # use '\\' which will display as '\\' but only counts as one
        # character in the string.  which are added in the template.
        def tidy_kod(kod):
            while '\\\\' in kod:
                kod = kod.replace('\\\\', '\\')
            kod = kod.replace('\\(', '').replace('\\)', '')
            return kod

        for P, ld in zip(badprimes, local_data):
            ld['p'] = web_latex(P)
            ld['norm'] = P.norm()
            ld['kod'] = tidy_kod(ld['kod'])

        # URLs of self and related objects:
        self.urls = {}
        # It's useful to be able to use this class out of context, when calling url_for will fail:
        try:
            self.urls['curve'] = url_for(".show_ecnf",
                                         nf=self.field_label,
                                         conductor_label=quote(
                                             self.conductor_label),
                                         class_label=self.iso_label,
                                         number=self.number)
        except RuntimeError:
            return
        self.urls['class'] = url_for(".show_ecnf_isoclass",
                                     nf=self.field_label,
                                     conductor_label=quote(
                                         self.conductor_label),
                                     class_label=self.iso_label)
        self.urls['conductor'] = url_for(".show_ecnf_conductor",
                                         nf=self.field_label,
                                         conductor_label=quote(
                                             self.conductor_label))
        self.urls['field'] = url_for(".show_ecnf1", nf=self.field_label)

        # Isogeny information

        self.one_deg = ZZ(self.class_deg).is_prime()
        isodegs = [str(d) for d in self.isogeny_degrees if d > 1]
        if len(isodegs) < 3:
            self.isogeny_degrees = " and ".join(isodegs)
        else:
            self.isogeny_degrees = " and ".join(
                [", ".join(isodegs[:-1]), isodegs[-1]])

        sig = self.signature
        totally_real = sig[1] == 0
        imag_quadratic = sig == [0, 1]

        if totally_real:
            self.hmf_label = "-".join(
                [self.field.label, self.conductor_label, self.iso_label])
            self.urls['hmf'] = url_for('hmf.render_hmf_webpage',
                                       field_label=self.field.label,
                                       label=self.hmf_label)
            lfun_url = url_for("l_functions.l_function_ecnf_page",
                               field_label=self.field_label,
                               conductor_label=self.conductor_label,
                               isogeny_class_label=self.iso_label)
            origin_url = lfun_url.lstrip('/L/').rstrip('/')
            if sig[0] <= 2 and db.lfunc_instances.exists({'url': origin_url}):
                self.urls['Lfunction'] = lfun_url
            elif self.abs_disc**2 * self.conductor_norm < 70000:
                # we shouldn't trust the Lfun computed on the fly for large conductor
                self.urls['Lfunction'] = url_for(
                    "l_functions.l_function_hmf_page",
                    field=self.field_label,
                    label=self.hmf_label,
                    character='0',
                    number='0')

        if imag_quadratic:
            self.bmf_label = "-".join(
                [self.field.label, self.conductor_label, self.iso_label])
            self.bmf_url = url_for('bmf.render_bmf_webpage',
                                   field_label=self.field_label,
                                   level_label=self.conductor_label,
                                   label_suffix=self.iso_label)
            lfun_url = url_for("l_functions.l_function_ecnf_page",
                               field_label=self.field_label,
                               conductor_label=self.conductor_label,
                               isogeny_class_label=self.iso_label)
            origin_url = lfun_url.lstrip('/L/').rstrip('/')
            if db.lfunc_instances.exists({'url': origin_url}):
                self.urls['Lfunction'] = lfun_url

        # most of this code is repeated in isog_class.py
        # and should be refactored
        self.friends = []
        self.friends += [('Isogeny class ' + self.short_class_label,
                          self.urls['class'])]
        self.friends += [('Twists',
                          url_for('ecnf.index',
                                  field=self.field_label,
                                  jinv=rename_j(j)))]
        if totally_real and not 'Lfunction' in self.urls:
            self.friends += [('Hilbert modular Form ' + self.hmf_label,
                              self.urls['hmf'])]

        if imag_quadratic:
            if "CM" in self.label:
                self.friends += [('Bianchi modular Form is not cuspidal', '')]
            elif not 'Lfunction' in self.urls:
                if db.bmf_forms.label_exists(self.bmf_label):
                    self.friends += [
                        ('Bianchi modular Form %s' % self.bmf_label,
                         self.bmf_url)
                    ]
                else:
                    self.friends += [
                        ('(Bianchi modular Form %s)' % self.bmf_label, '')
                    ]

        self.properties = [('Base field', self.field.field_pretty()),
                           ('Label', self.label)]

        # Plot
        if K.signature()[0]:
            self.plot = encode_plot(
                EC_nf_plot(K, self.ainvs, self.field.generator_name()))
            self.plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format(
                self.plot)
            self.properties += [(None, self.plot_link)]

        self.properties += [
            ('Conductor', self.cond),
            ('Conductor norm', self.cond_norm),
            # See issue #796 for why this is hidden (can be very large)
            # ('j-invariant', self.j),
            ('CM', self.cm_bool)
        ]

        if self.base_change:
            self.properties += [
                ('base-change',
                 'yes: %s' % ','.join([str(lab) for lab in self.base_change]))
            ]
        else:
            self.base_change = []  # in case it was False instead of []
            self.properties += [('base-change', 'no')]
        self.properties += [('Q-curve', self.qc)]

        r = self.rk
        if r == "?":
            r = self.rk_bnds
        self.properties += [
            ('Torsion order', self.ntors),
            ('Rank', r),
        ]

        for E0 in self.base_change:
            self.friends += [('Base-change of %s /\(\Q\)' % E0,
                              url_for("ec.by_ec_label", label=E0))]

        self._code = None  # will be set if needed by get_code()

        self.downloads = [('All stored data to text',
                           url_for(".download_ECNF_all",
                                   nf=self.field_label,
                                   conductor_label=quote(self.conductor_label),
                                   class_label=self.iso_label,
                                   number=self.number))]
        for lang in [["Magma", "magma"], ["SageMath", "sage"], ["GP", "gp"]]:
            self.downloads.append(
                ('Code to {}'.format(lang[0]),
                 url_for(".ecnf_code_download",
                         nf=self.field_label,
                         conductor_label=quote(self.conductor_label),
                         class_label=self.iso_label,
                         number=self.number,
                         download_type=lang[1])))

        if 'Lfunction' in self.urls:
            Lfun = get_lfunction_by_url(
                self.urls['Lfunction'].lstrip('/L').rstrip('/'),
                projection=['degree', 'trace_hash', 'Lhash'])
            if Lfun is None:
                self.friends += [('L-function not available', "")]
            else:
                instances = get_instances_by_Lhash_and_trace_hash(
                    Lfun['Lhash'], Lfun['degree'], Lfun.get('trace_hash'))
                exclude = {
                    elt[1].rstrip('/').lstrip('/')
                    for elt in self.friends if elt[1]
                }
                self.friends += names_and_urls(instances, exclude=exclude)
                self.friends += [('L-function', self.urls['Lfunction'])]
        else:
            self.friends += [('L-function not available', "")]
Beispiel #43
0
def render_hgm_webpage(args):
    data = None
    info = {}
    if 'label' in args:
        label = clean_input(args['label'])
        data = motivedb().find_one({'label': label})
        if data is None:
            bread = get_bread([("Search error", url_for('.search'))])
            info['err'] = "Motive " + label + " was not found in the database."
            info['label'] = label
            return search_input_error(info, bread)
        title = 'Hypergeometric Motive:' + label
        A = data['A']
        B = data['B']
        myfam = familydb().find_one({'A': A, 'B': B})
        if myfam is None:
            det = 'data not computed'
        else:
            det = myfam['det']
            det = [det[0],str(det[1])]
            d1 = det[1]
            d1 = re.sub(r'\s','', d1)
            d1 = re.sub(r'(.)\(', r'\1*(', d1)
            R = PolynomialRing(ZZ, 't')
            if det[1]=='':
                d2 = R(1)
            else:
                d2 = R(d1)
            det = d2(QQ(data['t']))*det[0]
        t = latex(QQ(data['t']))
        typee = 'Orthogonal'
        if (data['weight'] % 2) == 1 and (data['degree'] % 2) == 0:
            typee = 'Symplectic'
        primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
        locinfo = data['locinfo']
        for j in range(len(locinfo)):
            locinfo[j] = [primes[j]] + locinfo[j]
            #locinfo[j][2] = poly_with_factored_coeffs(locinfo[j][2], primes[j])
            locinfo[j][2] = list_to_factored_poly_otherorder(locinfo[j][2], vari='x')
        hodge = string2list(data['hodge'])
        famhodge = string2list(data['famhodge'])
        prop2 = [
            ('Degree', '\(%s\)' % data['degree']),
            ('Weight',  '\(%s\)' % data['weight']),
            ('Hodge vector',  '\(%s\)' % hodge),
            ('Conductor', '\(%s\)' % data['cond']),
        ]
        # Now add factorization of conductor
        Cond = ZZ(data['cond'])
        if not (Cond.abs().is_prime() or Cond == 1):
            data['cond'] = "%s=%s" % (str(Cond), factorint(data['cond']))

        info.update({
                    'A': A,
                    'B': B,
                    't': t,
                    'degree': data['degree'],
                    'weight': data['weight'],
                    'sign': data['sign'],
                    'sig': data['sig'],
                    'hodge': hodge,
                    'famhodge': famhodge,
                    'cond': data['cond'],
                    'req': data['req'],
                    'lcms': data['lcms'],
                    'type': typee,
                    'det': det,
                    'locinfo': locinfo
                    })
        AB_data, t_data = data["label"].split("_t")
        friends = [("Motive family "+AB_data.replace("_"," "), url_for(".by_family_label", label = AB_data))]
        friends.append(('L-function', url_for("l_functions.l_function_hgm_page", label=AB_data, t='t'+t_data)))
#        if rffriend != '':
#            friends.append(('Discriminant root field', rffriend))


        bread = get_bread([(label, ' ')])
        return render_template("hgm-show-motive.html", credit=HGM_credit, title=title, bread=bread, info=info, properties2=prop2, friends=friends, learnmore=learnmore_list())
Beispiel #44
0
def fundamental_discriminants(A, B):
    """Return the fundamental discriminants between A and B (inclusive), as Sage integers,
    ordered by absolute value, with negatives first when abs same."""
    v = [ZZ(D) for D in range(A, B + 1) if is_fundamental_discriminant(D)]
    v.sort(lambda x, y: cmp((abs(x), sgn(x)), (abs(y), sgn(y))))
    return v
Beispiel #45
0
def make_cond_key(D):
    D1 = ZZ(D)
    if D1 < 1:
        D1 = ZZ.one()
    D1 = int(D1.log(10))
    return '%04d%s' % (D1, str(D))
Beispiel #46
0
def rational_euler_factors(traces, euler_factors_cc, level, weight):
    dirichlet = [1] * 11
    dirichlet[0] = 0
    euler_factors = []
    bad_lfactors = []
    halfdegree = len(euler_factors_cc)
    PS = PowerSeriesRing(ZZ, "X")
    CCCx = PolynomialRing(CCC, "x")
    todo = list(enumerate(primes_first_n(30)))
    for p in sorted(ZZ(level).prime_divisors()):
        p_index = prime_pi(p) - 1
        if p_index >= 30:
            todo.append((p_index, p))
    for p_index, p in todo:
        if p_index > len(euler_factors_cc[0]):
            assert level % p == 0
            bad_lfactors.append([int(p), [int(1)] + [None] * halfdegree])
            continue

        #try to guess the rest by multiplying them
        roots = []
        for lf in euler_factors_cc:
            roots += reciprocal_roots(lf[p_index])
        root_powers = [None] * (halfdegree + 1)
        for j in range(1, halfdegree + 1):
            try:
                root_powers[j] = RRR(sum(map(lambda z: (z**j).real(),
                                             roots))).unique_integer()
            except ValueError:
                root_powers = root_powers[:j]
                break
        partial_efzz = from_power_sums(root_powers)
        efzz = map(
            int, partial_efzz) + [None] * (halfdegree + 1 - len(partial_efzz))
        if len(traces) > p:
            if efzz[1] is None:
                efzz[1] = int(-traces[p - 1])
            else:
                assert efzz[1] == -traces[p - 1]

        # to check that from_power_sums is correct
        ef = prod([CCCx(lf[p_index]) for lf in euler_factors_cc])
        for j, elt in enumerate(ef.list()[:len(partial_efzz)]):
            try:
                efj = RRR(elt.real()).unique_integer()
            except ValueError:
                break
            assert efj == efzz[j]

        if level % p != 0:
            sign = RRR(ef.list()[-1].real() /
                       p**((halfdegree) * (weight - 1))).unique_integer()
            assert sign in [1, -1], "%s\n%s" % (RRR(
                prod(lf[p_index][2]
                     for lf in euler_factors_cc).real()).unique_integer(), p**(
                         (halfdegree) * (weight - 1)))
            efzz2 = [None] * halfdegree
            for i, elt in enumerate(reversed(efzz[:-1])):
                if elt is None:
                    efzz2[i] = None
                else:
                    efzz2[i] = int(sign * p**((i + 1) * (weight - 1)) * elt)
            efzz += efzz2
            euler_factors.append(efzz)
        else:
            if None not in efzz:
                k = len(efzz)
                while efzz[k - 1] == 0 and k >= 1:
                    k -= 1
                efzz = efzz[:k]
            bad_lfactors.append([int(p), efzz])
            if p_index < 30:
                euler_factors.append(efzz)
        if p < 11:
            if p == 2:
                foo = (1 / PS(efzz[:4])).padded_list(4)
                for i in range(1, 4):
                    dirichlet[p**i] = foo[i]
            elif p == 3:
                foo = (1 / PS(efzz[:3])).padded_list(4)
                for i in range(1, 3):
                    dirichlet[p**i] = foo[i]
            else:
                dirichlet[p] = -efzz[1] if len(efzz) > 1 else 0
            assert dirichlet[p] == traces[
                p - 1], "p = %s, ap = %s, tp = %s, efzz = %s" % (
                    p, dirichlet[p], traces[p - 1], efzz)

        extend_multiplicatively(dirichlet)

    assert len(euler_factors) == 30

    return euler_factors, bad_lfactors, dirichlet
Beispiel #47
0
 def __init__(self, seed):
     self.s = ZZ(bytes_to_long(seed))
Beispiel #48
0
def angles_euler_factors(coeffs, level, weight, chi):
    """
    - ``coeffs`` -- a list of Dirichlet coefficients, as elements of CCC
    - ``level`` -- the level N
    - ``weight`` -- the weight k
    - ``chi`` -- the index of the Dirichlet character in the Conrey labeling
    returns a triple: (angles, euler_factos, bad_euler_factors)
    """
    G = DirichletGroup_conrey(level, CCC)
    char = DirichletCharacter_conrey(G, chi)
    euler = []
    bad_euler = []
    angles = []
    for p in prime_range(to_store):
        b = -coeffs[p]
        c = 1
        if p.divides(level):
            bad_euler.append([p, [c, b]])
            euler.append([c, b])
            a = 0
            angles.append(None)
        else:
            charval = CCC(2 * char.logvalue(int(p))).exppii()
            if charval.contains_exact(ZZ(1)):
                charval = 1
            elif charval.contains_exact(ZZ(-1)):
                charval = -1
            a = (p**QQ(weight - 1)) * charval
            euler.append([c, b, a])
            # alpha solves T^2 - a_p T + chi(p)*p^(k-1)
            sqrt_disc = sqrt_hack(b**2 - 4 * a * c)
            thetas = []
            for sign in [1, -1]:
                alpha = (-b + sign * sqrt_disc) / (2 * c)
                theta = (arg_hack(alpha) / (2 * CCC.pi().real())).mid()
                if theta > 0.5:
                    theta -= 1
                elif theta <= -0.5:
                    theta += 1
                assert theta <= 0.5 and theta > -0.5, "%s %s %s" % (
                    theta, arg_hack(alpha), alpha)
                thetas.append(theta)
            angles.append(float(min(thetas)))
        if len(coeffs) > p**2:
            if coeffs[p**2].abs().contains_zero():
                match = (coeffs[p**2] - (b**2 - a)).abs().mid() < 1e-5
            else:
                match = ((coeffs[p**2] -
                          (b**2 - a)).abs() / coeffs[p**2].abs()).mid() < 1e-5
            if not match:
                print "coeffs[p**2] doesn't match euler recursion"
                print zip(range(len(coeffs)), map(CDF, coeffs))
                print "(level, weight, chi, p) = %s\n%s != %s\na_p2**2 -  (b**2 - a)= %s\n b**2  - a = %s\na_p2 = %s\na=%s\nb = %s\nap = %s" % (
                    (level, weight, chi, p), CDF(coeffs[p**2]), CDF(b**2 - a),
                    coeffs[p**2] - (b**2 - a), b**2 - a, coeffs[p**2], CDF(a),
                    CDF(b), CDF(coeffs[p]))
                assert False
    an_f = [
        CBF_to_pair(RRR(n)**(QQ(-(weight - 1)) / 2) * c)
        for n, c in enumerate(coeffs[:to_store + 1])
    ]
    return an_f, angles, euler, bad_euler
Beispiel #49
0
def rational_euler_factors(euler_factors_cc, level, weight, an_list_bound = 11):
    dirichlet = [1]*an_list_bound
    dirichlet[0] = 0
    euler_factors = []
    bad_lfactors = []
    halfdegree = len(euler_factors_cc)
    PS = PowerSeriesRing(ZZ, "X")
    CCCx = PolynomialRing(CCC, "x")
    todo = list(enumerate(primes_first_n(30)))
    for p in sorted(ZZ(level).prime_divisors()):
        p_index = prime_pi(p) - 1
        if p_index >= 30:
            todo.append((p_index, p))
    for p_index, p in todo:
        if p_index >= len(euler_factors_cc[0]):
            assert level % p == 0, "%s, %s, %s"  % (level, weight, len(euler_factors_cc))
            bad_lfactors.append([int(p), [int(1)] + [None]*halfdegree])
            continue

        #try to guess the rest by multiplying them
        roots = []
        for lf in euler_factors_cc:
            roots += reciprocal_roots(lf[p_index])
        root_powers = [None] * (halfdegree + 1)
        for j in range(1,halfdegree + 1):
            try:
                root_powers[j] = RRR(sum( map(lambda z: (z**j).real(), roots) )).unique_integer()
            except ValueError:
                root_powers = root_powers[:j]
                break
        partial_efzz = from_power_sums(root_powers)
        efzz = map(int, partial_efzz) + [None]*(halfdegree +1 - len(partial_efzz))
        # to check that from_power_sums is correct
        ef = prod([CCCx(lf[p_index]) for lf in euler_factors_cc])
        for j, elt in enumerate(ef.list()[:len(partial_efzz)]):
            try:
                efj = int(RRR(elt.real()).unique_integer())
            except ValueError:
                #print j
                #print RRR(elt.real())
                #print p
                #print "[%s]" % (", ".join(["[%s]" % (", ".join(map(print_CCC, lf[p_index]))) for ef in euler_factors_cc]))
                #assert False
                break;
            assert efj == efzz[j], "%s, %s, %s, %s != %s"  % (level, weight, len(euler_factors_cc), efj, efzz[j])


        if (level % p) != 0:
            sign = RRR(ef.list()[-1].real()/p**((halfdegree)*(weight - 1))).unique_integer()
            assert sign in [1,-1], "%s\n%s" % (RRR(prod( lf[p_index][2] for lf in euler_factors_cc).real()).unique_integer(),p**((halfdegree)*(weight - 1)))
            efzz2 = [None] * halfdegree
            for i, elt in enumerate(reversed(efzz[:-1])):
                if elt is None:
                    efzz2[i] = None
                else:
                    efzz2[i] = int(sign*p**((i+1)*(weight - 1)) * elt)
            efzz += efzz2
            euler_factors.append(efzz)
        else:
            if None not in efzz:
                k = len(efzz)
                while efzz[k - 1] == 0 and k >= 1:
                    k -= 1
                efzz = efzz[:k]
            bad_lfactors.append([int(p), efzz])
            if p_index < 30:
                euler_factors.append(efzz)
        if p < an_list_bound:
            k = RR(an_list_bound).log(p).floor()+1
            foo = (1/PS(efzz)).padded_list(k)
            for i in range(1, k):
                dirichlet[p**i] = foo[i]

    extend_multiplicatively(dirichlet)

    assert len(euler_factors) == 30, "%s, %s, %s, %s != 30"  % (level, weight, len(euler_factors_cc), len(euler_factors))

    return euler_factors, bad_lfactors, dirichlet
Beispiel #50
0
def nf_string_to_label(F):  # parse Q, Qsqrt2, Qsqrt-4, Qzeta5, etc
    if F == 'Q':
        return '1.1.1.1'
    if F == 'Qi' or F == 'Q(i)':
        return '2.0.4.1'
    # Change unicode dash with minus sign
    F = F.replace(u'\u2212', '-')
    # remove non-ascii characters from F
    F = F.decode('utf8').encode('ascii', 'ignore')
    if len(F) == 0:
        raise ValueError(
            "Entry for the field was left blank.  You need to enter a field label, field name, or a polynomial."
        )
    if F[0] == 'Q':
        if '(' in F and ')' in F:
            F = F.replace('(', '').replace(')', '')
        if F[1:5] in ['sqrt', 'root']:
            try:
                d = ZZ(str(F[5:])).squarefree_part()
            except (TypeError, ValueError):
                d = 0
            if d == 0:
                raise ValueError(
                    "After {0}, the remainder must be a nonzero integer.  Use {0}5 or {0}-11 for example."
                    .format(F[:5]))
            if d == 1:
                return '1.1.1.1'
            if d % 4 in [2, 3]:
                D = 4 * d
            else:
                D = d
            absD = D.abs()
            s = 0 if D < 0 else 2
            return '2.%s.%s.1' % (s, str(absD))
        if F[1:5] == 'zeta':
            if '_' in F:
                F = F.replace('_', '')
            try:
                d = ZZ(str(F[5:]))
            except ValueError:
                d = 0
            if d < 1:
                raise ValueError(
                    "After {0}, the remainder must be a positive integer.  Use {0}5 for example."
                    .format(F[:5]))
            if d % 4 == 2:
                d /= 2  # Q(zeta_6)=Q(zeta_3), etc)
            if d == 1:
                return '1.1.1.1'
            deg = euler_phi(d)
            if deg > 23:
                raise ValueError('%s is not in the database.' % F)
            adisc = CyclotomicField(d).discriminant().abs()  # uses formula!
            return '%s.0.%s.1' % (deg, adisc)
        raise ValueError(
            'It is not a valid field name or label, or a defining polynomial.')
    # check if a polynomial was entered
    F = F.replace('X', 'x')
    if 'x' in F:
        F1 = F.replace('^', '**')
        # print F
        from lmfdb.number_fields.number_field import poly_to_field_label
        F1 = poly_to_field_label(F1)
        if F1:
            return F1
        raise ValueError('%s does not define a number field in the database.' %
                         F)
    # Expand out factored labels, like 11.11.11e20.1
    if not re.match(r'\d+\.\d+\.[0-9e_]+\.\d+', F):
        raise ValueError("It must be of the form d.r.D.n, such as 2.2.5.1.")
    parts = F.split(".")

    def raise_power(ab):
        if ab.count("e") == 0:
            return ZZ(ab)
        elif ab.count("e") == 1:
            a, b = ab.split("e")
            return ZZ(a)**ZZ(b)
        else:
            raise ValueError(
                "Malformed absolute discriminant.  It must be a sequence of strings AeB for A and B integers, joined by _s.  For example, 2e7_3e5_11."
            )

    parts[2] = str(prod(raise_power(c) for c in parts[2].split("_")))
    return ".".join(parts)
Beispiel #51
0
def lattice_search(**args):
    info = to_dict(args)  # what has been entered in the search boxes

    if 'download' in info:
        return download_search(info)

    if 'label' in info and info.get('label'):
        return lattice_by_label_or_name(info.get('label'))

    query = {}
    try:
        for field, name in (('dim', 'Dimension'), ('det', 'Determinant'),
                            ('level', None), ('minimum',
                                              'Minimal vector length'),
                            ('class_number', None), ('aut', 'Group order')):
            parse_ints(info, query, field, name)
        # Check if length of gram is triangular
        gram = info.get('gram')
        if gram and not (9 + 8 * ZZ(gram.count(','))).is_square():
            flash(
                Markup(
                    "Error: <span style='color:black'>%s</span> is not a valid input for Gram matrix.  It must be a list of integer vectors of triangular length, such as [1,2,3]."
                    % (gram)), "error")
            raise ValueError
        parse_list(info, query, 'gram', process=vect_to_sym)
    except ValueError as err:
        info['err'] = str(err)
        return search_input_error(info)

    count = parse_count(info, 50)
    start = parse_start(info)

    info['query'] = dict(query)
    res = lattice_db().find(query).sort([('dim', ASC), ('det', ASC),
                                         ('level', ASC), ('class_number', ASC),
                                         ('label', ASC), ('minimum', ASC),
                                         ('aut', ASC)
                                         ]).skip(start).limit(count)
    nres = res.count()

    # here we are checking for isometric lattices if the user enters a valid gram matrix but not one stored in the database_names, this may become slow in the future: at the moment we compare against list of stored matrices with same dimension and determinant (just compare with respect to dimension is slow)

    if nres == 0 and info.get('gram'):
        A = query['gram']
        n = len(A[0])
        d = matrix(A).determinant()
        result = [
            B for B in lattice_db().find({
                'dim': int(n),
                'det': int(d)
            }) if isom(A, B['gram'])
        ]
        if len(result) > 0:
            result = result[0]['gram']
            query_gram = {'gram': result}
            query.update(query_gram)
            res = lattice_db().find(query)
            nres = res.count()

    if (start >= nres):
        start -= (1 + (start - nres) / count) * count
    if (start < 0):
        start = 0

    info['number'] = nres
    info['start'] = int(start)
    info['more'] = int(start + count < nres)
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres == 0:
            info['report'] = 'no matches'
        else:
            if nres > count or start != 0:
                info['report'] = 'displaying matches %s-%s of %s' % (
                    start + 1, min(nres, start + count), nres)
            else:
                info['report'] = 'displaying all %s matches' % nres

    res_clean = []
    for v in res:
        v_clean = {}
        v_clean['label'] = v['label']
        v_clean['dim'] = v['dim']
        v_clean['det'] = v['det']
        v_clean['level'] = v['level']
        v_clean['class_number'] = v['class_number']
        v_clean['min'] = v['minimum']
        v_clean['aut'] = v['aut']

        res_clean.append(v_clean)

    info['lattices'] = res_clean

    t = 'Integral Lattices Search Results'
    bread = [('Lattices', url_for(".lattice_render_webpage")),
             ('Search Results', ' ')]
    properties = []
    return render_template("lattice-search.html",
                           info=info,
                           title=t,
                           properties=properties,
                           bread=bread,
                           learnmore=learnmore_list())
Beispiel #52
0
def get_satake_parameters(k, N=1, chi=0, fi=0, prec=10, bits=53, angles=False):
    r""" Compute the Satake parameters and return an html-table.

    INPUT:
    - ''k'' -- positive integer : the weight
    - ''N'' -- positive integer (default 1) : level
    - ''chi'' -- non-neg. integer (default 0) use character nr. chi    - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi]
    -''prec'' -- compute parameters for p <=prec
    -''bits'' -- do real embedings intoi field of bits precision
    -''angles''-- return the angles t_p instead of the alpha_p
                  here alpha_p=p^((k-1)/2)exp(i*t_p)

    """
    (t, f) = _get_newform(k, N, chi, fi)
    if(not t):
        return f
    K = f.base_ring()
    RF = RealField(bits)
    CF = ComplexField(bits)
    if(K != QQ):
        M = len(K.complex_embeddings())
        ems = dict()
        for j in range(M):
            ems[j] = list()
    ps = prime_range(prec)
    alphas = list()
    for p in ps:
        ap = f.coefficients(ZZ(prec))[p]
        if(K == QQ):
            f1 = QQ(4 * p ** (k - 1) - ap ** 2)
            alpha_p = (QQ(ap) + I * f1.sqrt()) / QQ(2)
            # beta_p=(QQ(ap)-I*f1.sqrt())/QQ(2)
            # satake[p]=(alpha_p,beta_p)
            ab = RF(p ** ((k - 1) / 2))
            norm_alpha = alpha_p / ab
            t_p = CF(norm_alpha).argument()
            if(angles):
                alphas.append(t_p)
            else:
                alphas.append(alpha_p)

        else:
            for j in range(M):
                app = ap.complex_embeddings(bits)[j]
                f1 = (4 * p ** (k - 1) - app ** 2)
                alpha_p = (app + I * f1.sqrt()) / RealField(bits)(2)
                ab = RF(p ** ((k - 1) / 2))
                norm_alpha = alpha_p / ab
                t_p = CF(norm_alpha).argument()
                if(angles):
                    ems[j].append(t_p)
                else:
                    ems[j].append(alpha_p)

    tbl = dict()
    tbl['headersh'] = ps
    if(K == QQ):
        tbl['headersv'] = [""]
        tbl['data'] = [alphas]
        tbl['corner_label'] = "$p$"
    else:
        tbl['data'] = list()
        tbl['headersv'] = list()
        tbl['corner_label'] = "Embedding \ $p$"
        for j in ems.keys():
            tbl['headersv'].append(j)
            tbl['data'].append(ems[j])
    # logger.debug(tbl)
    s = html_table(tbl)
    return s
Beispiel #53
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'])))
        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['abs_disc'])
            data['disc'] = curve['disc_sign'] * data['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 item in tama:
                if item['tamagawa_number'] > 0:
                    tamgwnr = str(item['tamagawa_number'])
                else:
                    tamgwnr = 'N/A'
                data['tama'] += tamgwnr + ' (p = ' + str(item['p']) + '), '
            data['tama'] = data['tama'][:-2]  # trim last ", "
            if ratpts:
                if len(ratpts['rat_pts']):
                    data['rat_pts'] = ',  '.join(
                        web_latex('(' + ' : '.join(map(str, 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],
                    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]))
        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":
                list_to_min_eqn(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'] = """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'] = 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:
            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']),
            ('\(\\End(J_{\\overline{\\Q}}) \\otimes \\Q\)',
             '\(%s\)' % data['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 = []
        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")),
                              ('$\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);'
        }
Beispiel #54
0
def find_inverse_images_of_twists(k, N=1, chi=0, fi=0, prec=10, verbose=0):
    r"""
    Checks if f is minimal and if not, returns the associated
    minimal form to precision prec.

    INPUT:

    - ''k'' -- positive integer : the weight
    - ''N'' -- positive integer (default 1) : level
    - ''chi'' -- non-neg. integer (default 0) use character nr. chi
    - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi]
    - ''prec'' -- integer (the number of coefficients to get)
    - ''verbose'' -- integer
    OUTPUT:

    -''[t,l]'' -- tuple of a Bool t and a list l. The list l contains all tuples of forms which twists to the given form.
              The actual minimal one is the first element of this list.

    EXAMPLES::



    """
    (t, f) = _get_newform(k, N, chi, fi)

    if(not t):
        return f
    if(is_squarefree(ZZ(N))):
        return [True, f]
    # We need to check all square factors of N
    logger.info("investigating: %s" % f)
    N_sqfree = squarefree_part(ZZ(N))
    Nsq = ZZ(N / N_sqfree)
    twist_candidates = list()
    KF = f.base_ring()
    # check how many Hecke eigenvalues we need to check
    max_nump = number_of_hecke_to_check(f)
    maxp = max(primes_first_n(max_nump))
    for d in divisors(N):
        # we look at all d such that d^2 divdes N
        if(not ZZ(d ** 2).divides(ZZ(N))):
            continue
        D = DirichletGroup(d)
        # check possible candidates to twist into f
        # g in S_k(M,chi) wit M=N/d^2
        M = ZZ(N / d ** 2)
        logger.info("Checking level %s" % M)
        for xig in range(euler_phi(M)):
            (t, glist) = _get_newform(k, M, xig)
            if(not t):
                return glist
            for g in glist:
                logger.debug("Comparing to function %s" % g)
                KG = g.base_ring()
                # we now see if twisting of g by xi in D gives us f
                for xi in D:
                    try:
                        for p in primes_first_n(max_nump):
                            if(ZZ(p).divides(ZZ(N))):
                                continue
                            bf = f.q_expansion(maxp + 1)[p]
                            bg = g.q_expansion(maxp + 1)[p]
                            if(bf == 0 and bg == 0):
                                continue
                            elif(bf == 0 and bg != 0 or bg == 0 and bf != 0):
                                raise StopIteration()
                            if(ZZ(p).divides(xi.conductor())):
                                raise ArithmeticError("")
                            xip = xi(p)
                            # make a preliminary check that the base rings match with respect to being
                            # real or not
                            try:
                                QQ(xip)
                                XF = QQ
                                if(KF != QQ or KG != QQ):
                                    raise StopIteration
                            except TypeError:
                                # we have a  non-rational (i.e. complex) value of the character
                                XF = xip.parent()
                                if((KF == QQ or KF.is_totally_real()) and (KG == QQ or KG.is_totally_real())):
                                    raise StopIteration
                            ## it is diffcult to compare elements from diferent rings in general but we make some checcks
                            # is it possible to see if there is a larger ring which everything can be
                            # coerced into?
                            ok = False
                            try:
                                a = KF(bg / xip)
                                b = KF(bf)
                                ok = True
                                if(a != b):
                                    raise StopIteration()
                            except TypeError:
                                pass
                            try:
                                a = KG(bg)
                                b = KG(xip * bf)
                                ok = True
                                if(a != b):
                                    raise StopIteration()
                            except TypeError:
                                pass
                            if(not ok):  # we could coerce and the coefficients were equal
                                return "Could not compare against possible candidates!"
                            # otherwise if we are here we are ok and found a candidate
                        twist_candidates.append([dd, g.q_expansion(prec), xi])
                    except StopIteration:
                        # they are not equal
                        pass
    # logger.debug("Candidates=%s" % twist_candidates)
    if(len(twist_candidates) == 0):
        return (True, None)
    else:
        return (False, twist_candidates)
Beispiel #55
0
def rep_galois_modl_search(**args):
    C = getDBConnection()
    info = to_dict(args)  # what has been entered in the search boxes

    if 'download' in info:
        return download_search(info)

    if 'label' in info and info.get('label'):
        return rep_galois_modl_by_label_or_name(info.get('label'), C)
    query = {}
    try:
        for field, name in (('dim', 'Dimension'), ('det', 'Determinant'),
                            ('level', None), ('minimum',
                                              'Minimal vector length'),
                            ('class_number', None), ('aut', 'Group order')):
            parse_ints(info, query, field, name)
        # Check if length of gram is triangular
        gram = info.get('gram')
        if gram and not (9 + 8 * ZZ(gram.count(','))).is_square():
            flash(
                Markup(
                    "Error: <span style='color:black'>%s</span> is not a valid input for Gram matrix.  It must be a list of integer vectors of triangular length, such as [1,2,3]."
                    % (gram)), "error")
            raise ValueError
        parse_list(info, query, 'gram', process=vect_to_sym)
    except ValueError as err:
        info['err'] = str(err)
        return search_input_error(info)

    count = parse_count(info, 50)
    start = parse_start(info)

    info['query'] = dict(query)
    res = C.mod_l_galois.reps.find(query).sort([('dim', ASC), ('det', ASC),
                                                ('level', ASC),
                                                ('class_number', ASC),
                                                ('label', ASC)
                                                ]).skip(start).limit(count)
    nres = res.count()

    if (start >= nres):
        start -= (1 + (start - nres) / count) * count
    if (start < 0):
        start = 0

    info['number'] = nres
    info['start'] = int(start)
    info['more'] = int(start + count < nres)
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres == 0:
            info['report'] = 'no matches'
        else:
            if nres > count or start != 0:
                info['report'] = 'displaying matches %s-%s of %s' % (
                    start + 1, min(nres, start + count), nres)
            else:
                info['report'] = 'displaying all %s matches' % nres

    res_clean = []
    for v in res:
        v_clean = {}
        v_clean['label'] = v['label']
        v_clean['dim'] = v['dim']
        v_clean['det'] = v['det']
        v_clean['level'] = v['level']
        v_clean['gram'] = vect_to_matrix(v['gram'])
        res_clean.append(v_clean)

    info['rep_galois_modls'] = res_clean

    t = 'Mod &#x2113; Galois representations Search Results'

    bread = [('Representations', "/Representation"),
             ("mod &#x2113;", url_for(".index")), ('Search Results', ' ')]
    properties = []
    return render_template("rep_galois_modl-search.html",
                           info=info,
                           title=t,
                           properties=properties,
                           bread=bread,
                           learnmore=learnmore_list())
Beispiel #56
0
def render_hgm_webpage(label):
    data = None
    info = {}
    data = db.hgm_motives.lookup(label)
    if data is None:
        abort(
            404, "Hypergeometric motive " + label +
            " was not found in the database.")
    title = 'Hypergeometric Motive:' + label
    A = data['A']
    B = data['B']

    alpha = cyc_to_QZ(A)
    beta = cyc_to_QZ(B)
    gammas = ab2gammas(A, B)

    det = db.hgm_families.lucky({'A': A, 'B': B}, 'det')
    if det is None:
        det = 'data not computed'
    else:
        det = [det[0], str(det[1])]
        d1 = det[1]
        d1 = re.sub(r'\s', '', d1)
        d1 = re.sub(r'(.)\(', r'\1*(', d1)
        R = PolynomialRing(ZZ, 't')
        if det[1] == '':
            d2 = R(1)
        else:
            d2 = R(d1)
        det = d2(QQ(data['t'])) * det[0]
    t = latex(QQ(data['t']))
    typee = 'Orthogonal'
    if (data['weight'] % 2) == 1 and (data['degree'] % 2) == 0:
        typee = 'Symplectic'
    primes = [
        2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67,
        71
    ]
    locinfo = data['locinfo']
    for j in range(len(locinfo)):
        locinfo[j] = [primes[j]] + locinfo[j]
        #locinfo[j][2] = poly_with_factored_coeffs(locinfo[j][2], primes[j])
        locinfo[j][2] = list_to_factored_poly_otherorder(locinfo[j][2],
                                                         vari='x')
    hodge = data['hodge']
    famhodge = data['famhodge']
    prop2 = [
        ('Label', '%s' % data['label']),
        ('A', r'\(%s\)' % A),
        ('B', r'\(%s\)' % B),
        ('Degree', r'\(%s\)' % data['degree']),
        ('Weight', r'\(%s\)' % data['weight']),
        ('Hodge vector', r'\(%s\)' % hodge),
        ('Conductor', r'\(%s\)' % data['cond']),
    ]
    # Now add factorization of conductor
    Cond = ZZ(data['cond'])
    if not (Cond.abs().is_prime() or Cond == 1):
        data['cond'] = "%s=%s" % (str(Cond), factorint(data['cond']))

    info.update({
        'A': A,
        'B': B,
        'alpha': web_latex(alpha),
        'beta': web_latex(beta),
        'gammas': gammas,
        't': t,
        'degree': data['degree'],
        'weight': data['weight'],
        'sign': data['sign'],
        'sig': data['sig'],
        'hodge': hodge,
        'famhodge': famhodge,
        'cond': data['cond'],
        'req': data['req'],
        'lcms': data['lcms'],
        'type': typee,
        'det': det,
        'locinfo': locinfo
    })
    AB_data, t_data = data["label"].split("_t")
    friends = [("Motive family " + AB_data.replace("_", " "),
                url_for(".by_family_label", label=AB_data))]
    friends.append(('L-function',
                    url_for("l_functions.l_function_hgm_page",
                            label=AB_data,
                            t='t' + t_data)))
    #    if rffriend != '':
    #        friends.append(('Discriminant root field', rffriend))

    AB = 'A = ' + str(A) + ', B = ' + str(B)
    t_data = str(QQ(data['t']))

    bread = get_bread([('family ' + str(AB),
                        url_for(".by_family_label", label=AB_data)),
                       ('t = ' + t_data, ' ')])
    return render_template("hgm-show-motive.html",
                           credit=HGM_credit,
                           title=title,
                           bread=bread,
                           info=info,
                           properties=prop2,
                           friends=friends,
                           learnmore=learnmore_list())
Beispiel #57
0
    def monodromy(self):
        def dogapthing(m1):
            mnew = str(m1[2])
            mnew = mnew.replace(' ', '')
            if GAP_ID_RE.match(mnew):
                mnew = mnew[1:-1]
                two = mnew.split(',')
                two = [int(j) for j in two]
                try:
                    m1[2] = small_group_display_knowl(two[0], two[1])
                except TypeError:
                    m1[2] = 'Gap[%d,%d]' % (two[0], two[1])
            else:
                # Fix multiple backslashes
                m1[2] = re.sub(r'\\+', r'\\', m1[2])
                m1[2] = '$%s$' % m1[2]
            return m1

        def getgroup(m1, ell):
            pind = {2: 0, 3: 1, 5: 2, 7: 3, 11: 4, 13: 5}
            if not m1[3][2]:
                return [m1[2], m1[0]]
            myA = m1[3][0]
            myB = m1[3][1]
            if not myA and not myB:  # myA = myB = []
                return [small_group_display_knowl(1, 1), 1]
            mono = db.hgm_families.lucky({
                'A': myA,
                'B': myB
            },
                                         projection="mono")
            if mono is None:
                return ['??', 1]
            newthing = mono[pind[ell]]
            newthing = dogapthing(newthing[1])
            return [newthing[2], newthing[0]]

        def splitint(a, p):
            if a == 1:
                return ' '
            j = valuation(a, p)
            if j == 0:
                return str(a)
            a = a / p**j
            if a == 1:
                return latex(ZZ(p**j).factor())
            return str(a) + r'\cdot' + latex(ZZ(p**j).factor())

        # # this will have a new data format in the future
        # converted = [[ell,
        #     dogapthing(m1),
        #     getgroup(m1, ell),
        #     latex(ZZ(m1[0]).factor())] for ell, m1 in self.mono if m1 != 0]
        # return [[m[0], m[1], m[2][0],
        #         splitint(m[1][0]/m[2][1], m[0]), m[3]] for m in converted]

        mono = [m for m in self.mono if m[1] != 0]
        mono = [[
            m[0],
            dogapthing(m[1]),
            getgroup(m[1], m[0]),
            latex(ZZ(m[1][0]).factor())
        ] for m in mono]
        mono = [[
            m[0], m[1], m[2][0],
            splitint(ZZ(m[1][0]) / m[2][1], m[0]), m[3]
        ] for m in mono]
        return mono
Beispiel #58
0
    def make_E(self):
        coeffs = self.ainvs  # list of 5 lists of d strings
        self.ainvs = [self.field.parse_NFelt(x) for x in coeffs]
        self.latex_ainvs = web_latex(self.ainvs)
        from sage.schemes.elliptic_curves.all import EllipticCurve
        self.E = E = EllipticCurve(self.ainvs)
        self.equn = web_latex(E)
        self.numb = str(self.number)

        # Conductor, discriminant, j-invariant
        N = E.conductor()
        self.cond = web_latex(N)
        self.cond_norm = web_latex(N.norm())
        if N.norm() == 1:  # since the factorization of (1) displays as "1"
            self.fact_cond = self.cond
        else:
            self.fact_cond = web_latex_ideal_fact(N.factor())
        self.fact_cond_norm = web_latex(N.norm().factor())

        D = self.field.K().ideal(E.discriminant())
        self.disc = web_latex(D)
        self.disc_norm = web_latex(D.norm())
        if D.norm() == 1:  # since the factorization of (1) displays as "1"
            self.fact_disc = self.disc
        else:
            self.fact_disc = web_latex_ideal_fact(D.factor())
        self.fact_disc_norm = web_latex(D.norm().factor())

        # Minimal model?
        #
        # All curves in the database should be given
        # by models which are globally minimal if possible, else
        # minimal at all but one prime.  But we do not rely on this
        # here, and the display should be correct if either (1) there
        # exists a global minimal model but this model is not; or (2)
        # this model is non-minimal at more than one prime.
        #
        self.non_min_primes = non_minimal_primes(E)
        self.is_minimal = (len(self.non_min_primes) == 0)
        self.has_minimal_model = True
        if not self.is_minimal:
            self.non_min_prime = ','.join([web_latex(P) for P in self.non_min_primes])
            self.has_minimal_model = has_global_minimal_model(E)

        if not self.is_minimal:
            Dmin = minimal_discriminant_ideal(E)
            self.mindisc = web_latex(Dmin)
            self.mindisc_norm = web_latex(Dmin.norm())
            if Dmin.norm() == 1:  # since the factorization of (1) displays as "1"
                self.fact_mindisc = self.mindisc
            else:
                self.fact_mindisc = web_latex_ideal_fact(Dmin.factor())
            self.fact_mindisc_norm = web_latex(Dmin.norm().factor())

        j = E.j_invariant()
        if j:
            d = j.denominator()
            n = d * j  # numerator exists for quadratic fields only!
            g = GCD(list(n))
            n1 = n / g
            self.j = web_latex(n1)
            if d != 1:
                if n1 > 1:
                # self.j = "("+self.j+")\(/\)"+web_latex(d)
                    self.j = web_latex(r"\frac{%s}{%s}" % (self.j, d))
                else:
                    self.j = web_latex(d)
                if g > 1:
                    if n1 > 1:
                        self.j = web_latex(g) + self.j
                    else:
                        self.j = web_latex(g)
        self.j = web_latex(j)

        self.fact_j = None
        if j.is_zero():
            self.fact_j = web_latex(j)
        else:
            try:
                self.fact_j = web_latex(j.factor())
            except (ArithmeticError, ValueError):  # if not all prime ideal factors principal
                pass

        # CM and End(E)
        self.cm_bool = "no"
        self.End = "\(\Z\)"
        if self.cm:
            self.cm_bool = "yes (\(%s\))" % self.cm
            if self.cm % 4 == 0:
                d4 = ZZ(self.cm) // 4
                self.End = "\(\Z[\sqrt{%s}]\)" % (d4)
            else:
                self.End = "\(\Z[(1+\sqrt{%s})/2]\)" % self.cm

        # Q-curve / Base change
        self.qc = "no"
        try:
            if self.q_curve:
                self.qc = "yes"
        except AttributeError:  # in case the db entry does not have this field set
            pass

        # Torsion
        self.ntors = web_latex(self.torsion_order)
        self.tr = len(self.torsion_structure)
        if self.tr == 0:
            self.tor_struct_pretty = "Trivial"
        if self.tr == 1:
            self.tor_struct_pretty = "\(\Z/%s\Z\)" % self.torsion_structure[0]
        if self.tr == 2:
            self.tor_struct_pretty = r"\(\Z/%s\Z\times\Z/%s\Z\)" % tuple(self.torsion_structure)
        torsion_gens = [E([self.field.parse_NFelt(x) for x in P])
                        for P in self.torsion_gens]
        self.torsion_gens = ",".join([web_latex(P) for P in torsion_gens])

        # Rank or bounds
        try:
            self.rk = web_latex(self.rank)
        except AttributeError:
            self.rk = "?"
        try:
            self.rk_bnds = "%s...%s" % tuple(self.rank_bounds)
        except AttributeError:
            self.rank_bounds = [0, Infinity]
            self.rk_bnds = "not recorded"

        # Generators
        try:
            gens = [E([self.field.parse_NFelt(x) for x in P])
                    for P in self.gens]
            self.gens = ", ".join([web_latex(P) for P in gens])
            if self.rk == "?":
                self.reg = "unknown"
            else:
                if gens:
                    self.reg = E.regulator_of_points(gens)
                else:
                    self.reg = 1  # otherwise we only get 1.00000...

        except AttributeError:
            self.gens = "not recorded"
            self.reg = "unknown"
            try:
                if self.rank == 0:
                    self.reg = 1
            except AttributeError:
                pass

        # Local data
        self.local_data = []
        for p in N.prime_factors():
            self.local_info = E.local_data(p, algorithm="generic")
            self.local_data.append({'p': web_latex(p),
                                    'norm': web_latex(p.norm().factor()),
                                    'tamagawa_number': self.local_info.tamagawa_number(),
                                    'kodaira_symbol': web_latex(self.local_info.kodaira_symbol()).replace('$', ''),
                                    'reduction_type': self.local_info.bad_reduction_type(),
                                    'ord_den_j': max(0, -E.j_invariant().valuation(p)),
                                    'ord_mindisc': self.local_info.discriminant_valuation(),
                                    'ord_cond': self.local_info.conductor_valuation()
                                    })

        # URLs of self and related objects:
        self.urls = {}
        # It's useful to be able to use this class out of context, when calling url_for will fail:
        try:
            self.urls['curve'] = url_for(".show_ecnf", nf=self.field_label, conductor_label=self.conductor_label, class_label=self.iso_label, number=self.number)
        except RuntimeError:
            return
        self.urls['class'] = url_for(".show_ecnf_isoclass", nf=self.field_label, conductor_label=self.conductor_label, class_label=self.iso_label)
        self.urls['conductor'] = url_for(".show_ecnf_conductor", nf=self.field_label, conductor_label=self.conductor_label)
        self.urls['field'] = url_for(".show_ecnf1", nf=self.field_label)

        if self.field.is_real_quadratic():
            self.hmf_label = "-".join([self.field.label, self.conductor_label, self.iso_label])
            self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field.label, label=self.hmf_label)

        if self.field.is_imag_quadratic():
            self.bmf_label = "-".join([self.field.label, self.conductor_label, self.iso_label])

        self.friends = []
        self.friends += [('Isogeny class ' + self.short_class_label, self.urls['class'])]
        self.friends += [('Twists', url_for('ecnf.index', field_label=self.field_label, jinv=self.jinv))]
        if self.field.is_real_quadratic():
            self.friends += [('Hilbert Modular Form ' + self.hmf_label, self.urls['hmf'])]
        if self.field.is_imag_quadratic():
            self.friends += [('Bianchi Modular Form %s not yet available' % self.bmf_label, '')]

        self.properties = [
            ('Base field', self.field.field_pretty()),
            ('Label', self.label)]

        # Plot
        if E.base_field().signature()[0]:
            self.plot = encode_plot(EC_nf_plot(E, self.field.generator_name()))
            self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot
            self.properties += [(None, self.plot_link)]

        self.properties += [
            ('Conductor', self.cond),
            ('Conductor norm', self.cond_norm),
            ('j-invariant', self.j),
            ('CM', self.cm_bool)]

        if self.base_change:
            self.properties += [('base-change', 'yes: %s' % ','.join([str(lab) for lab in self.base_change]))]
        else:
            self.base_change = []  # in case it was False instead of []
            self.properties += [('Q-curve', self.qc)]

        r = self.rk
        if r == "?":
            r = self.rk_bnds
        self.properties += [
            ('Torsion order', self.ntors),
            ('Rank', r),
        ]

        for E0 in self.base_change:
            self.friends += [('Base-change of %s /\(\Q\)' % E0, url_for("ec.by_ec_label", label=E0))]
Beispiel #59
0
def get_values_at_CM_points(k, N=1, chi=0, fi=0, digits=12, verbose=0):
    r""" Computes and returns a list of values of f at a collection of CM points as complex floating point numbers.

    INPUT:

    - ''k'' -- positive integer : the weight
    - ''N'' -- positive integer (default 1) : level
    - ''chi'' -- non-neg. integer (default 0) use character nr. chi    - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi]
    -''digits'' -- we want this number of corrrect digits in the value

    OUTPUT:
    -''s'' string representation of a dictionary {I:f(I):rho:f(rho)}.

    TODO: Get explicit, algebraic values if possible!
    """
    (t, f) = _get_newform(k, N, chi, fi)
    if(not t):
        return f
    bits = max(53, ceil(digits * 4))
    CF = ComplexField(bits)
    RF = ComplexField(bits)
    eps = RF(10 ** -(digits + 1))
    logger.debug("eps=" % eps)
    K = f.base_ring()
    cm_vals = dict()
    # the points we want are i and rho. More can be added later...
    rho = CyclotomicField(3).gen()
    zi = CyclotomicField(4).gen()
    points = [rho, zi]
    maxprec = 1000  # max size of q-expansion
    minprec = 10  # max size of q-expansion
    for tau in points:
        q = CF(exp(2 * pi * I * tau))
        fexp = dict()
        if(K == QQ):
            v1 = CF(0)
            v2 = CF(1)
            try:
                for prec in range(minprec, maxprec, 10):
                    logger.debug("prec=%s" % prec)
                    v2 = f.q_expansion(prec)(q)
                    err = abs(v2 - v1)
                    logger.debug("err=%s" % err)
                    if(err < eps):
                        raise StopIteration()
                    v1 = v2
                cm_vals[tau] = ""
            except StopIteration:
                cm_vals[tau] = str(fq)
        else:
            v1 = dict()
            v2 = dict()
            err = dict()
            cm_vals[tau] = dict()
            for h in range(K.degree()):
                v1[h] = 1
                v2[h] = 0
            try:
                for prec in range(minprec, maxprec, 10):
                    logger.debug("prec=%s" % prec)
                    for h in range(K.degree()):
                        fexp[h] = list()
                        v2[h] = 0
                        for n in range(prec):
                            c = f.coefficients(ZZ(prec))[n]
                            cc = c.complex_embeddings(CF.prec())[h]
                            v2[h] = v2[h] + cc * q ** n
                        err[h] = abs(v2[h] - v1[h])
                        logger.debug("v1[%s]=%s" % (h, v1[h]))
                        logger.debug("v2[%s]=%s" % (h, v2[h]))
                        logger.debug("err[%s]=%s" % (h, err[h]))
                        if(max(err.values()) < eps):
                            raise StopIteration()
                        v1[h] = v2[h]
            except StopIteration:
                pass
            for h in range(K.degree()):
                if(err[h] < eps):
                    cm_vals[tau][h] = v2[h]
                else:
                    cm_vals[tau][h] = ""

    logger.debug("vals=%s" % cm_vals)
    logger.debug("errs=%s" % err)
    tbl = dict()
    tbl['corner_label'] = ['$\tau$']
    tbl['headersh'] = ['$\\rho=\zeta_{3}$', '$i$']
    if(K == QQ):
        tbl['headersv'] = ['$f(\\tau)$']
        tbl['data'] = [cm_vals]
    else:
        tbl['data'] = list()
        tbl['headersv'] = list()
        for h in range(K.degree()):
            tbl['headersv'].append("$\sigma_{%s}(f(\\tau))$" % h)
            row = list()
            for tau in points:
                row.append(cm_vals[tau][h])
            tbl['data'].append(row)

    s = html_table(tbl)
    # s=html.table([cm_vals.keys(),cm_vals.values()])
    return s
Beispiel #60
0
def dim_error_tradeoff(A,
                       c,
                       u,
                       beta,
                       h,
                       k,
                       alpha=None,
                       tau=None,
                       float_type="mpfr",
                       use_lll=True):
    """

    :param A:    LWE matrix
    :param c:    LWE vector
    :param u:	 Uniform vector
    :param beta: BKW block size
    :param h: 	 Hamming weight of secret
    :param k:    LWE dim after tradeoff
    :param tau:  number of new samples to generate
    :param use_lll: 	If True, run BKZ only once and then run LLL
    					If False, run BKZ iteratively

    * secret vector s is used to see the error term of new LWE(-like) samples.

    """

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

    n = A.ncols()
    q = A.base_ring().order()
    K = GF(q, proof=False)

    if alpha is None:
        alpha = 8 / q

    if tau is None:
        tau = 30

    m = A.nrows() / n

    scale = round(alpha * q * sqrt(m) / sqrt(2 * pi * h))
    scale = ZZ(scale)

    count = 0

    A_k = matrix(ZZ, 1, k)
    c_k = []
    u_k = []
    length = 0

    while count < tau:

        r = count * m
        T = A.matrix_from_rows([i + r for i in range(m)])
        ct = c[r:r + m]
        ut = u[r:r + m]

        T1 = T.matrix_from_columns([i for i in range(n - k)])

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

        H = copy(L)

        y = vector(ZZ, tuple(L[0]))
        length += y.norm()

        T2 = T.matrix_from_columns([n - k + i for i in range(k)])

        A_kt, c_kt, u_kt = apply_short1(y, T2, ct, ut, scale=scale)
        if r == 0:
            A_k[0] = A_kt
        else:
            A_k = A_k.stack(A_kt)
        c_k.append(c_kt)
        u_k.append(u_kt)

        count += 1

    length = float(length / tau)
    A_k = A_k.change_ring(K)
    c_k = vector(K, c_k)
    u_k = vector(K, u_k)

    B = float(2 + 1 / sqrt(2 * pi)) * (alpha * q)
    B = B * B * m / (m + n)
    B = sqrt(B) * length / scale

    print '(A_k, c_k) is k-dim LWE samples (with secret s[-k:]) / (A_k, u_k) is uniform samples. '

    return A_k, c_k, u_k, B