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
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
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
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
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]
def relevant_degs(self): return integer_divisors(Integer(self.geometric_extension_degree))[1:-1]
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 Ш') 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'])