def alpha_alt_fn(data): try: alternating_group = AlternatingGroup(len(data)) data_perm = Permutation(alternating_group(data)) except TypeError: raise TypeError( "The data element given is not an element of the alternating group" ) def alpha_alt(roots, p): """ Computes invariant alpha in the 'ALT' case """ from sage.all import prod, Permutation tmp = prod(roots[i] - roots[j] for i in range(len(roots)) for j in range(i)) try: frob_perm = Permutation( alternating_group(frobenius_permutation(roots, p))) except TypeError: raise TypeError( "The Frobenius element does not generate an element of the alternating group" ) sign = -(-1)**are_conjugate_in_alternating(frob_perm, data_perm) return tmp * sign return alpha_alt
def switch_rows(A, i, j): r""" Switch the ith and the jth row of A. """ from sage.all import Permutation assert i >= 0 and i < A.nrows(), "i = {}, j = {}".format(i, j) assert j >= 0 and j < A.nrows(), "i = {}, j = {}".format(i, j) if i != j: A.permute_rows(Permutation([(i + 1, j + 1)]))
def cusp_sums_from_signature_to_standard_basis(cuspsums,signatures,level): """ Converts a list of cuspsums where each entry is a list of multiplicities with respect to the input signature order. To a list of cuspsums where each entry is a list of multiplicities with respect to the standard order of the cusps. """ P = Permutation([cusp_number_from_signature(s,level)+1 for s in signatures]).inverse() return [permutation_action(P,s) for s in cuspsums]
def MatrixToPermutation(P): n = P.dimensions()[1] ei = lambda i: vector([int(i == j) for j in range(n)]) def ie(v): for _ in range(n): if v[_] == 1: return _ for i in range(n): assert (ie(ei(i)) == i) # check p = [ie(P * ei(i)) + 1 for i in range(n)] # need to shift up by one return Permutation(p)
def factor_perm_repn(self, nfgg=None): if 'artincoefs' in self._data: return self._data['artincoefs'] try: if nfgg is not None: self._data["nfgg"] = nfgg elif "nfgg" not in self._data: from lmfdb.artin_representations.math_classes import NumberFieldGaloisGroup nfgg = NumberFieldGaloisGroup(self._data['coeffs']) self._data["nfgg"] = nfgg else: nfgg = self._data["nfgg"] cc = nfgg.conjugacy_classes() # cc is list, each has methods group, size, order, representative ccreps = [x.representative() for x in cc] ccns = [int(x.size()) for x in cc] ccreps = [Permutation(x).cycle_string() for x in ccreps] ccgen = '[' + ','.join(ccreps) + ']' ar = nfgg.artin_representations() # list of artin reps from db arfull = nfgg.artin_representations_full_characters( ) # list of artin reps from db gap.set( 'fixed', 'function(a,b) if a*b=a then return 1; else return 0; fi; end;' ) g = gap.Group(ccgen) h = g.Stabilizer('1') rc = g.RightCosets(h) # Permutation character for our field permchar = [gap.Sum(rc, 'j->fixed(j,' + x + ')') for x in ccreps] charcoefs = [0 for x in arfull] # list of lists (inner are giving char values ar2 = [x[0] for x in arfull] for j in range(len(ar)): fieldchar = int(arfull[j][1]) zet = CyclotomicField(fieldchar).gen() ar2[j] = [psum(zet, x) for x in ar2[j]] for j in range(len(ar)): charcoefs[j] = 0 for k in range(len(ccns)): charcoefs[j] += int(permchar[k]) * ccns[k] * ar2[j][k] charcoefs = [x / int(g.Size()) for x in charcoefs] self._data['artincoefs'] = charcoefs return charcoefs except AttributeError: return [] return []
def show(): r""" This gets called when an adress of that kind gets loaded: http://127.0.0.1:37777/Permutations/show?data=3.4.2.1 """ assert request.method == "GET", "request.method is assumed to be GET" data = str(request.args.get('data', '')) try: data = map(Integer, data.split('.')) p = Permutation(data) except (TypeError, ValueError): logger.info("Impossible to create a permutation from input.") flash_error("Ooops, impossible to create a permutation from given input!") return flask.redirect(url_for(".index")) return render_template("permutations.html", permutation=p, rankbread=get_bread())
def are_conjugate_in_alternating(rho, sigma): """ Tests whether rho and sigma are conjugate in the corresponding alternating group. Does not assume rho and sigma are the same length. """ # This seems 10x faster than calling corresponding IsConjugate on corresponding gap objects. # Only used in the ALT case rho_cycle_type = rho.cycle_type() sigma_cycle_type = sigma.cycle_type() if sum(rho_cycle_type) != sum(sigma_cycle_type): return False if rho_cycle_type != sigma_cycle_type: return False # Conjugacy classes in A_n are the same as in S_n, except when all the cycles are of odd and different lengths # In that case, S_n conjugacy classes split up in 2 A_n conjugacy classes if len(set(sigma_cycle_type)) != len(sigma_cycle_type): return True for x in sigma_cycle_type: if x % 2 == 0: return True # Now we know we only have odd length cycles, all different rho_augmented_cycles = sorted([(len(x), x) for x in rho.cycle_tuples()]) sigma_augmented_cycles = sorted([(len(x), x) for x in sigma.cycle_tuples()]) # Because sort bases itself first on the first argument of the tuple, the # cycles match up with their lengths tmp = [0 for i in range(sum(rho_cycle_type))] for i in range(len(rho_augmented_cycles)): rho_tuple = rho_augmented_cycles[i][1] sigma_tuple = sigma_augmented_cycles[i][1] for j in range(len(rho_tuple)): tmp[rho_tuple[j] - 1] = sigma_tuple[j] from sage.all import Permutation sig = Permutation(tmp).signature() if sig == -1: return False else: return True
def matching_permutation(a, b): r"""Determines if a is an "approximate" permuation of b. (Copied from Abelfunctions.) """ N = len(a) if N != len(b): raise ValueError, "Lists must be of same length." perm = [-1] * N eps = 0.5 * min([abs(a[i] - a[j]) for i in range(N) for j in range(i)]) for i in xrange(N): for j in xrange(N): dist = abs(a[i] - b[j]) if dist < eps: perm[j] = i + 1 break # an element is not accounted for if the numerical distance is too large if -1 in perm: raise ValueError, "Could not compute matching permutation " \ "between %s and %s." %(a,b) return Permutation(perm)
def render_passport(args): info = {} if 'passport_label' in args: label = clean_input(args['passport_label']) C = base.getDBConnection() dataz = C.curve_automorphisms.passports.find({'passport_label': label}) if dataz.count() is 0: bread = get_bread([("Search error", url_for('.search'))]) flash_error( "No refined passport with label %s was found in the database.", label) return redirect(url_for(".index")) data = dataz[0] g = data['genus'] GG = ast.literal_eval(data['group']) gn = GG[0] gt = GG[1] gp_string = str(gn) + '.' + str(gt) pretty_group = sg_pretty(gp_string) if gp_string == pretty_group: spname = False else: spname = True numb = dataz.count() try: numgenvecs = request.args['numgenvecs'] numgenvecs = int(numgenvecs) except: numgenvecs = 20 info['numgenvecs'] = numgenvecs title = 'One refined passport of genus ' + str( g) + ' with automorphism group $' + pretty_group + '$' smallgroup = "[" + str(gn) + "," + str(gt) + "]" prop2 = [ ('Genus', '\(%d\)' % g), ('Small Group', '\(%s\)' % pretty_group), ('Signature', '\(%s\)' % sign_display(ast.literal_eval(data['signature']))), ('Generating Vectors', '\(%d\)' % numb) ] info.update({ 'genus': data['genus'], 'cc': cc_display(data['con']), 'sign': sign_display(ast.literal_eval(data['signature'])), 'group': pretty_group, 'gpid': smallgroup, 'numb': numb, 'disp_numb': min(numb, numgenvecs) }) if spname: info.update({'specialname': True}) Ldata = [] HypColumn = False Lfriends = [] for i in range(0, min(numgenvecs, numb)): dat = dataz[i] x1 = dat['total_label'] if 'full_auto' in dat: x2 = 'No' if dat['full_label'] not in Lfriends: Lfriends.append(dat['full_label']) else: x2 = 'Yes' if 'hyperelliptic' in dat: x3 = tfTOyn(dat['hyperelliptic']) HypColumn = True else: x3 = ' ' x4 = [] for perm in dat['gen_vectors']: cycperm = Permutation(perm).cycle_string() x4.append(sep.join(split_perm(cycperm))) Ldata.append([x1, x2, x3, x4]) info.update({'genvects': Ldata, 'HypColumn': HypColumn}) info.update({'passport_cc': cc_display(ast.literal_eval(data['con']))}) if 'eqn' in data: info.update({'eqns': data['eqn']}) if 'ndim' in data: info.update({'Ndim': data['ndim']}) other_data = False if 'hyperelliptic' in data: info.update({'ishyp': tfTOyn(data['hyperelliptic'])}) other_data = True if 'hyp_involution' in data: inv = Permutation(data['hyp_involution']).cycle_string() info.update({'hypinv': sep.join(split_perm(inv))}) if 'cyclic_trigonal' in data: info.update({'iscyctrig': tfTOyn(data['cyclic_trigonal'])}) other_data = True if 'jacobian_decomp' in data: jcLatex, corrChar = decjac_format(data['jacobian_decomp']) info.update({'corrChar': corrChar, 'jacobian_decomp': jcLatex}) if 'cinv' in data: cinv = Permutation(data['cinv']).cycle_string() info.update({'cinv': sep.join(split_perm(cinv))}) info.update({'other_data': other_data}) if 'full_auto' in data: full_G = ast.literal_eval(data['full_auto']) full_gn = full_G[0] full_gt = full_G[1] full_gp_string = str(full_gn) + '.' + str(full_gt) full_pretty_group = sg_pretty(full_gp_string) info.update({ 'fullauto': full_pretty_group, 'signH': sign_display(ast.literal_eval(data['signH'])), 'higgenlabel': data['full_label'] }) urlstrng, br_g, br_gp, br_sign, refined_p = split_passport_label(label) if Lfriends: for Lf in Lfriends: friends = [("Full automorphism " + Lf, Lf), ("Family containing this refined passport ", urlstrng)] else: friends = [("Family containing this refined passport", urlstrng)] bread_sign = label_to_breadcrumbs(br_sign) bread_gp = label_to_breadcrumbs(br_gp) bread = get_bread([(br_g, './?genus=' + br_g), ('$' + pretty_group + '$', './?genus=' + br_g + '&group=' + bread_gp), (bread_sign, urlstrng), (data['cc'][0], ' ')]) learnmore = [('Completeness of the data', url_for(".completeness_page")), ('Source of the data', url_for(".how_computed_page")), ('Labeling convention', url_for(".labels_page"))] downloads = [('Download Magma code', url_for(".hgcwa_code_download", label=label, download_type='magma')), ('Download Gap code', url_for(".hgcwa_code_download", label=label, download_type='gap'))] return render_template("hgcwa-show-passport.html", title=title, bread=bread, info=info, properties2=prop2, friends=friends, learnmore=learnmore, downloads=downloads, credit=credit)
def MatrixToPermutation(P): return Permutation([list(v).index(1)+1 for v in P.columns()])
def perm_display(L): return [Permutation(ell).cycle_string() for ell in L]
def render_family(args): info = {} if 'label' in args: label = clean_input(args['label']) C = base.getDBConnection() dataz = C.curve_automorphisms.passports.find({'label': label}).sort('cc.0', pymongo.ASCENDING) if dataz.count() is 0: flash_error( "No family with label %s was found in the database.", label) return redirect(url_for(".index")) data=dataz[0] g = data['genus'] GG = ast.literal_eval(data['group']) gn = GG[0] gt = GG[1] gp_string=str(gn) + '.' + str(gt) pretty_group=sg_pretty(gp_string) if gp_string == pretty_group: spname=False else: spname=True title = 'Family of Genus ' + str(g) + ' Curves with Automorphism Group $' + pretty_group +'$' smallgroup="[" + str(gn) + "," +str(gt) +"]" prop2 = [ ('Genus', '\(%d\)' % g), ('Group', '\(%s\)' % pretty_group), ('Signature', '\(%s\)' % sign_display(ast.literal_eval(data['signature']))) ] info.update({'genus': data['genus'], 'sign': sign_display(ast.literal_eval(data['signature'])), 'group': pretty_group, 'g0':data['g0'], 'dim':data['dim'], 'r':data['r'], 'gpid': smallgroup }) if spname: info.update({'specialname': True}) Lcc=[] Lall=[] Ltopo_rep=[] #List of topological representatives Lelements=[] #List of lists of equivalence classes for dat in dataz: if ast.literal_eval(dat['con']) not in Lcc: urlstrng=dat['passport_label'] Lcc.append(ast.literal_eval(dat['con'])) Lall.append([cc_display(ast.literal_eval(dat['con'])),dat['passport_label'], urlstrng]) #Topological equivalence if 'topological' in dat: if dat['topological'] == dat['cc']: x1=[] #A list of permutations of generating vectors of topo_rep for perm in dat['gen_vectors']: x1.append(sep.join(split_perm(Permutation(perm).cycle_string()))) Ltopo_rep.append([dat['passport_label'], dat['total_label'], x1]) topo_class = C.curve_automorphisms.passports.find({'label': dat['label'], 'topological': dat['cc']}).sort('cc.0', pymongo.ASCENDING) elements=[] #An equivalence class for element in topo_class: elements.append((element['passport_label'], element['total_label'])) Lelements.append(elements) Ltopo_class = zip(Ltopo_rep, Lelements) topo_length = len(Ltopo_rep) #Add topological equivalence to info info.update({'topological_rep': Ltopo_rep}) info.update({'topological_class': Ltopo_class}) info.update({'topological_num': topo_length}) info.update({'passport': Lall}) info.update({'passport_num': len(Lall)}) g2List = ['[2,1]','[4,2]','[8,3]','[10,2]','[12,4]','[24,8]','[48,29]'] if g == 2 and data['group'] in g2List: g2url = "/Genus2Curve/Q/?geom_aut_grp_id=" + data['group'] friends = [("Genus 2 curves over $\Q$", g2url ) ] else: friends = [ ] br_g, br_gp, br_sign = split_family_label(label) bread_sign = label_to_breadcrumbs(br_sign) bread_gp = label_to_breadcrumbs(br_gp) bread = get_bread([(br_g, './?genus='+br_g),('$'+pretty_group+'$','./?genus='+br_g + '&group='+bread_gp), (bread_sign,' ')]) learnmore =[('Completeness of the data', url_for(".completeness_page")), ('Source of the data', url_for(".how_computed_page")), ('Labeling convention', url_for(".labels_page"))] if topo_length == 0: downloads = [('Download Magma code', url_for(".hgcwa_code_download", label=label, download_type='magma')), ('Download Gap code', url_for(".hgcwa_code_download", label=label, download_type='gap'))] else: downloads = [('Magma code', None), (u'\u2003 All vectors', url_for(".hgcwa_code_download", label=label, download_type='magma')), (u'\u2003 Up to topological equivalence', url_for(".hgcwa_code_download", label=label, download_type='topo_magma')), ('Gap code', None), (u'\u2003 All vectors', url_for(".hgcwa_code_download", label=label, download_type='gap')), (u'\u2003 Up to topological equivalence', url_for(".hgcwa_code_download", label=label, download_type='topo_gap'))] return render_template("hgcwa-show-family.html", title=title, bread=bread, info=info, properties2=prop2, friends=friends, learnmore=learnmore, downloads=downloads, credit=credit)
def switch_columns(A, i, j): r""" Switch the ith and the jth column of A. """ from sage.all import Permutation if i != j: A.permute_columns(Permutation([(i + 1, j + 1)]))
def render_passport(args): info = {} if 'passport_label' in args: label = clean_input(args['passport_label']) dataz = list(db.hgcwa_passports.search({'passport_label': label})) if not dataz: bread = get_bread([("Search Error", url_for('.index'))]) flash_error("No refined passport with label %s was found in the database.", label) return redirect(url_for(".index")) data=dataz[0] g = data['genus'] g0=data['g0'] GG = ast.literal_eval(data['group']) gn = GG[0] gt = GG[1] gp_string=str(gn) + '.' + str(gt) pretty_group=sg_pretty(gp_string) if gp_string == pretty_group: spname=False else: spname=True numb = len(dataz) try: numgenvecs = int(request.args['numgenvecs']) numbraidreps = int(request.args['numbraidreps']) except Exception: numgenvecs = 20 numbraidreps = 20 info['numgenvecs']=numgenvecs info['numbraidreps']=numbraidreps title = 'One refined passport of genus ' + str(g) + ' with automorphism group $' + pretty_group +'$' smallgroup="[" + str(gn) + "," +str(gt) +"]" prop2 = [ ('Label', label), ('Genus', r'\(%d\)' % g), ('Quotient genus', r'\(%d\)' % g0), ('Group', r'\(%s\)' % pretty_group), ('Signature', r'\(%s\)' % sign_display(ast.literal_eval(data['signature']))), ('Generating Vectors', r'\(%d\)' % numb) ] info.update({'genus': data['genus'], 'cc': cc_display(data['con']), 'sign': sign_display(ast.literal_eval(data['signature'])), 'group': pretty_group, 'gpid': smallgroup, 'numb': numb, 'disp_numb': min(numb, numgenvecs), 'g0': data['g0'] }) if spname: info.update({'specialname': True}) Ldata = [] HypColumn = False Lfriends = [] Lbraid = [] for i in range(0, min(numgenvecs,numb)): dat = dataz[i] x1 = dat['total_label'] if 'full_auto' in dat: x2 = 'no' if dat['full_label'] not in Lfriends: Lfriends.append(dat['full_label']) else: x2 = 'yes' if 'hyperelliptic' in dat: x3 = tfTOyn(dat['hyperelliptic']) HypColumn = True else: x3 = ' ' x4 = [] if dat['g0'] == 0: for perm in dat['gen_vectors']: cycperm = Permutation(perm).cycle_string() x4.append(sep.join(split_perm(cycperm))) elif dat['g0'] > 0: for perm in dat['gen_vectors']: cycperm = Permutation(perm).cycle_string() #if display_perm == '()': if cycperm == '()': x4.append('Id(G)') else: x4.append(sep.join(split_perm(cycperm))) Ldata.append([x1, x2, x3, x4]) info.update({'genvects': Ldata, 'HypColumn': HypColumn}) info.update({'passport_cc': cc_display(ast.literal_eval(data['con']))}) #Generate braid representatives if 'braid' in dataz[0]: braid_data = [entry for entry in dataz if entry['braid'] == entry['cc']] for dat in braid_data: x5 = [] for perm in dat['gen_vectors']: x5.append(sep.join(split_perm(Permutation(perm).cycle_string()))) Lbraid.append([dat['total_label'], x5]) braid_length = len(Lbraid) #Add braid equivalence into info info.update({'braid': Lbraid, 'braid_numb': braid_length, 'braid_disp_numb': min(braid_length, numbraidreps)}) if 'eqn' in data: info.update({'eqns': data['eqn']}) if 'ndim' in data: info.update({'Ndim': data['ndim']}) other_data = False if 'hyperelliptic' in data: info.update({'ishyp': tfTOyn(data['hyperelliptic'])}) other_data = True if 'hyp_involution' in data: inv=Permutation(data['hyp_involution']).cycle_string() info.update({'hypinv': sep.join(split_perm(inv))}) if 'cyclic_trigonal' in data: info.update({'iscyctrig': tfTOyn(data['cyclic_trigonal'])}) other_data = True if 'jacobian_decomp' in data: jcLatex, corrChar = decjac_format(data['jacobian_decomp']) info.update({'corrChar': corrChar, 'jacobian_decomp': jcLatex}) if 'cinv' in data: cinv=Permutation(data['cinv']).cycle_string() info.update({'cinv': sep.join(split_perm(cinv))}) info.update({'other_data': other_data}) if 'full_auto' in data: full_G = ast.literal_eval(data['full_auto']) full_gn = full_G[0] full_gt = full_G[1] full_gp_string = str(full_gn) + '.' + str(full_gt) full_pretty_group = sg_pretty(full_gp_string) info.update({'fullauto': full_pretty_group, 'signH': sign_display(ast.literal_eval(data['signH'])), 'higgenlabel': data['full_label']}) urlstrng, br_g, br_gp, br_sign, _ = split_passport_label(label) if Lfriends: friends = [("Full automorphism " + Lf, Lf) for Lf in Lfriends] friends += [("Family containing this refined passport ", urlstrng)] else: friends = [("Family containing this refined passport", urlstrng)] bread_sign = label_to_breadcrumbs(br_sign) bread_gp = label_to_breadcrumbs(br_gp) bread = get_bread([ (br_g, './?genus='+br_g), ('$'+pretty_group+'$', './?genus='+br_g + '&group='+bread_gp), (bread_sign, urlstrng), (data['cc'][0], ' ')]) if numb == 1 or braid_length == 0: downloads = [('Code to Magma', url_for(".hgcwa_code_download", label=label, download_type='magma')), ('Code to Gap', url_for(".hgcwa_code_download", label=label, download_type='gap'))] else: downloads = [('Code to Magma', None), (u'\u2003 All vectors', url_for(".hgcwa_code_download", label=label, download_type='magma')), (u'\u2003 Up to braid equivalence', url_for(".hgcwa_code_download", label=label, download_type='braid_magma')), ('Code to Gap', None), (u'\u2003 All vectors', url_for(".hgcwa_code_download", label=label, download_type='gap')), (u'\u2003 Up to braid equivalence', url_for(".hgcwa_code_download", label=label, download_type='braid_gap'))] downloads.append(('Underlying data', url_for(".hgcwa_data", label=label))) return render_template("hgcwa-show-passport.html", title=title, bread=bread, info=info, properties=prop2, friends=friends, learnmore=learnmore_list(), downloads=downloads, KNOWL_ID="curve.highergenus.aut.%s" % label)
def render_family(args): info = {} if 'label' in args: label = clean_input(args['label']) dataz = list(db.hgcwa_passports.search({'label':label})) if not dataz: flash_error("No family with label %s was found in the database.", label) return redirect(url_for(".index")) data = dataz[0] g = data['genus'] g0 = data['g0'] GG = ast.literal_eval(data['group']) gn = GG[0] gt = GG[1] gp_string = str(gn) + '.' + str(gt) pretty_group = sg_pretty(gp_string) if gp_string == pretty_group: spname = False else: spname = True title = 'Family of genus ' + str(g) + ' curves with automorphism group $' + pretty_group +'$' smallgroup="[" + str(gn) + "," +str(gt) + "]" prop2 = [ ('Label', label), ('Genus', r'\(%d\)' % g), ('Quotient genus', r'\(%d\)' % g0), ('Group', r'\(%s\)' % pretty_group), ('Signature', r'\(%s\)' % sign_display(ast.literal_eval(data['signature']))) ] info.update({'genus': data['genus'], 'sign': sign_display(ast.literal_eval(data['signature'])), 'group': pretty_group, 'g0': data['g0'], 'dim': data['dim'], 'r': data['r'], 'gpid': smallgroup, 'numb': len(dataz) }) if spname: info.update({'specialname': True}) Lcc=[] Lall=[] Ltopo_rep=[] #List of topological representatives for dat in dataz: if ast.literal_eval(dat['con']) not in Lcc: urlstrng = dat['passport_label'] Lcc.append(ast.literal_eval(dat['con'])) Lall.append([cc_display(ast.literal_eval(dat['con'])),dat['passport_label'], urlstrng,dat['cc']]) #Topological equivalence if 'topological' in dat: if dat['topological'] == dat['cc']: x1 = [] #A list of permutations of generating vectors of topo_rep for perm in dat['gen_vectors']: x1.append(sep.join(split_perm(Permutation(perm).cycle_string()))) Ltopo_rep.append([dat['total_label'], x1, dat['label'], 'T.' + '.'.join(str(x) for x in dat['cc']), dat['cc']]) #2nd to last element is used for webpage tag #Add topological equivalence to info info.update({'topological_rep': Ltopo_rep}) info.update({'topological_num': len(Ltopo_rep)}) info.update({'passport': Lall}) info.update({'passport_num': len(Lall)}) g2List = ['[2,1]', '[4,2]', '[8,3]', '[10,2]', '[12,4]', '[24,8]', '[48,29]'] if g == 2 and data['group'] in g2List: g2url = "/Genus2Curve/Q/?geom_aut_grp_label=" + ".".join(data['group'][1:-1].split(',')) friends = [(r"Genus 2 curves over $\Q$", g2url)] else: friends = [] br_g, br_gp, br_sign = split_family_label(label) bread_sign = label_to_breadcrumbs(br_sign) bread_gp = label_to_breadcrumbs(br_gp) bread = get_bread([(br_g, './?genus='+br_g), ('$'+pretty_group+'$', './?genus='+br_g + '&group='+bread_gp), (bread_sign,' ')]) if len(Ltopo_rep) == 0 or len(dataz) == 1: downloads = [('Code to Magma', url_for(".hgcwa_code_download", label=label, download_type='magma')), ('Code to Gap', url_for(".hgcwa_code_download", label=label, download_type='gap'))] else: downloads = [('Code to Magma', None), (u'\u2003 All vectors', url_for(".hgcwa_code_download", label=label, download_type='magma')), (u'\u2003 Up to topological equivalence', url_for(".hgcwa_code_download", label=label, download_type='topo_magma')), ('Code to Gap', None), (u'\u2003 All vectors', url_for(".hgcwa_code_download", label=label, download_type='gap')), (u'\u2003 Up to topological equivalence', url_for(".hgcwa_code_download", label=label, download_type='topo_gap'))] downloads.append(('Underlying data', url_for(".hgcwa_data", label=label))) return render_template("hgcwa-show-family.html", title=title, bread=bread, info=info, properties=prop2, friends=friends, KNOWL_ID="curve.highergenus.aut.%s" % label, learnmore=learnmore_list(), downloads=downloads)