Пример #1
0
    def gammas(self):
        def subdict(d, v):
            if d[v] > 1:
                d[v] -= 1
            else:
                del d[v]

        a = defaultdict(int)
        b = defaultdict(int)
        for x in self.A:
            a[x] += 1
        for x in self.B:
            b[x] += 1
        gamma = [[], []]
        ab = [a, b]
        while a or b:
            m = max(list(a) + list(b))
            wh = 0 if m in a else 1
            gamma[wh].append(m)
            subdict(ab[wh], m)
            for d in integer_divisors(m)[:-1]:
                if d in ab[wh]:
                    subdict(ab[wh], d)
                else:
                    ab[1 - wh][d] += 1
        gamma[1] = [-1 * z for z in gamma[1]]
        gamma = gamma[1] + gamma[0]
        gamma.sort()
        return gamma
Пример #2
0
def __JacobiDimension(k, m):
    if (k % 2) == 0:
        x = 0
        if k == 2:
            x = (len(integer_divisors(m)) - 1) // 2
        for j in range(1, m + 1):
            x += (__S1k(k + 2 * j) - ((j * j) // (4 * m)))
        return x
    x = 0
    for j in range(1, m):
        x += (__S1k(k + 2 * j - 1) - ((j * j) // (4 * m)))
    return x
Пример #3
0
def subfield_display(n, subs):
    if n == 1:
        return 'Degree 1 - None'
    degs = integer_divisors(ZZ(str(n)))[1:-1]
    if len(degs) == 0:
        return 'Prime degree - none'
    ans = ''
    substrs = defaultdict(str)
    for (n, t), cnt in subs:
        label = base_label(n, t)
        if substrs[n] != '':
            substrs[n] += ', '
        substrs[n] += transitive_group_display_knowl(label)
        if cnt > 1:
            substrs[n] += f'<span style="font-size: small"> x {cnt}</span>'
    for deg in degs:
        ans += f'<p>Degree {deg}: '
        if substrs[deg] == '':
            substrs[deg] = 'None'
        ans += substrs[deg] + '</p>'
    return ans
Пример #4
0
def ab2gammas(A, B):
    ab = [{}, {}]
    for x in A:
        incdict(ab[0], x)
    for x in B:
        incdict(ab[1], x)
    gamma = [[], []]
    while ab[0] or ab[1]:
        m = max(list(ab[0]) + list(ab[1]))
        wh = 0 if m in ab[0] else 1
        gamma[wh].append(m)
        subdict(ab[wh], m)
        for d in integer_divisors(m)[:-1]:
            if d in ab[wh]:
                subdict(ab[wh], d)
            else:
                incdict(ab[1 - wh], d)
    gamma[1] = [-1 * z for z in gamma[1]]
    gamma = gamma[1] + gamma[0]
    gamma.sort()
    return gamma
Пример #5
0
def divisors_in_interval(n, a, b):
    """ given a nonzero integer n and an interval [a,b] returns a list of the divisors of n in [a,b] """
    return [d for d in integer_divisors(n) if a <= d and d <= b]
Пример #6
0
 def relevant_degs(self):
     return integer_divisors(Integer(self.geometric_extension_degree))[1:-1]
Пример #7
0
def elliptic_curve_search(info, query):
    parse_rational_to_list(info, query, 'jinv', 'j-invariant')
    parse_ints(info, query, 'conductor')
    if info.get('conductor_type'):
        if info['conductor_type'] == 'prime':
            query['num_bad_primes'] = 1
            query['semistable'] = True
        elif info['conductor_type'] == 'prime_power':
            query['num_bad_primes'] = 1
        elif info['conductor_type'] == 'squarefree':
            query['semistable'] = True
        elif info['conductor_type'] == 'divides':
            if not isinstance(query.get('conductor'), int):
                err = "You must specify a single conductor"
                flash_error(err)
                raise ValueError(err)
            else:
                query['conductor'] = {'$in': integer_divisors(ZZ(query['conductor']))}
    parse_signed_ints(info, query, 'discriminant', qfield=('signD', 'absD'))
    parse_ints(info,query,'rank')
    parse_ints(info,query,'sha','analytic order of &#1064;')
    parse_ints(info,query,'num_int_pts','num_int_pts')
    parse_ints(info,query,'class_size','class_size')
    if info.get('class_deg'):
        parse_ints(info,query,'class_deg','class_deg')
        if not isinstance(query.get('class_deg'), int):
            err = "You must specify a single isogeny class degree"
            flash_error(err)
            raise ValueError(err)
    parse_floats(info,query,'regulator','regulator')
    parse_floats(info, query, 'faltings_height', 'faltings_height')
    if info.get('reduction'):
        if info['reduction'] == 'semistable':
            query['semistable'] = True
        elif info['reduction'] == 'not semistable':
            query['semistable'] = False
        elif info['reduction'] == 'potentially good':
            query['potential_good_reduction'] = True
        elif info['reduction'] == 'not potentially good':
            query['potential_good_reduction'] = False
    if info.get('torsion'):
        if info['torsion'][0] == '[':
            parse_bracketed_posints(info,query,'torsion',qfield='torsion_structure',maxlength=2,check_divisibility='increasing')
        else:
            parse_ints(info,query,'torsion')
    # speed up slow torsion_structure searches by also setting torsion
    #if 'torsion_structure' in query and not 'torsion' in query:
    #    query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1)
    if 'cm' in info:
        if info['cm'] == 'noCM':
            query['cm'] = 0
        elif info['cm'] == 'CM':
            query['cm'] = {'$ne' : 0}
        else:
            parse_ints(info,query,field='cm',qfield='cm')
    parse_element_of(info,query,'isogeny_degrees',split_interval=200,contained_in=get_stats().isogeny_degrees)
    parse_primes(info, query, 'nonmax_primes', name='non-maximal primes',
                 qfield='nonmax_primes', mode=info.get('nonmax_quantifier'), radical='nonmax_rad')
    parse_primes(info, query, 'bad_primes', name='bad primes',
                 qfield='bad_primes',mode=info.get('bad_quantifier'))
    parse_primes(info, query, 'sha_primes', name='sha primes',
                 qfield='sha_primes',mode=info.get('sha_quantifier'))
    if info.get('galois_image'):
        labels = [a.strip() for a in info['galois_image'].split(',')]
        elladic_labels = [a for a in labels if elladic_image_label_regex.fullmatch(a) and is_prime_power(elladic_image_label_regex.match(a)[1])]
        modell_labels = [a for a in labels if modell_image_label_regex.fullmatch(a) and is_prime(modell_image_label_regex.match(a)[1])]
        if len(elladic_labels)+len(modell_labels) != len(labels):
            err = "Unrecognized Galois image label, it should be the label of a subgroup of GL(2,Z_ell), such as %s, or the label of a subgroup of GL(2,F_ell), such as %s, or a list of such labels"
            flash_error(err, "13.91.3.2", "13S4")
            raise ValueError(err)
        if elladic_labels:
            query['elladic_images'] = {'$contains': elladic_labels}
        if modell_labels:
            query['modell_images'] = {'$contains': modell_labels}
        if 'cm' not in query:
            query['cm'] = 0
            info['cm'] = "noCM"
        if query['cm']:
            # try to help the user out if they specify the normalizer of a Cartan in the CM case (these are either maximal or impossible
            if any(a.endswith("Nn") for a in modell_labels) or any(a.endswith("Ns") for a in modell_labels):
                err = "To search for maximal images, exclude non-maximal primes"
                flash_error(err)
                raise ValueError(err)
        else:
            # if the user specifies full mod-ell image with ell > 3, automatically exclude nonmax primes (if possible)
            max_labels = [a for a in modell_labels if a.endswith("G") and int(modell_image_label_regex.match(a)[1]) > 3]
            if max_labels:
                if info.get('nonmax_primes') and info['nonmax_quantifier'] != 'exclude':
                    err = "To search for maximal images, exclude non-maximal primes"
                    flash_error(err)
                    raise ValueError(err)
                else:
                    modell_labels = [a for a in modell_labels if a not in max_labels]
                    max_primes = [modell_image_label_regex.match(a)[1] for a in max_labels]
                    if info.get('nonmax_primes'):
                        max_primes += [l.strip() for l in info['nonmax_primes'].split(',') if not l.strip() in max_primes]
                    max_primes.sort(key=int)
                    info['nonmax_primes'] = ','.join(max_primes)
                    info['nonmax_quantifier'] = 'exclude'
                    parse_primes(info, query, 'nonmax_primes', name='non-maximal primes',
                                 qfield='nonmax_primes', mode=info.get('nonmax_quantifier'), radical='nonmax_rad')
                    info['galois_image'] = ','.join(modell_labels + elladic_labels)
                query['modell_images'] = { '$contains': modell_labels }

    # The button which used to be labelled Optimal only no/yes"
    # (default: no) has been renamed "Curves per isogeny class
    # all/one" (default: all).  When this option is "one" we only list
    # one curve in each class, currently choosing the curve with
    # minimal Faltings heights, which is conjecturally the
    # Gamma_1(N)-optimal curve.
    if 'optimal' in info and info['optimal'] == 'on':
        query["__one_per__"] = "lmfdb_iso"

    info['curve_ainvs'] = lambda dbc: str([ZZ(ai) for ai in dbc['ainvs']])
    info['curve_url_LMFDB'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number'])
    info['iso_url_LMFDB'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1])
    info['cremona_bound'] = CREMONA_BOUND
    info['curve_url_Cremona'] = lambda dbc: url_for(".by_ec_label", label=dbc['Clabel'])
    info['iso_url_Cremona'] = lambda dbc: url_for(".by_ec_label", label=dbc['Ciso'])
    info['FH'] = lambda dbc: RealField(20)(dbc['faltings_height'])