class GaloisStats(StatsDisplay): table = db.gps_transitive baseurl_func = ".index" stat_list = [ {"cols": ["n", "order"], "totaler": totaler(), "proportioner": proportioners.per_row_total}, {"cols": ["solv", "n"], "totaler": totaler(), "proportioner": proportioners.per_col_total}, {"cols": ["prim", "n"], "totaler": totaler(), "proportioner": proportioners.per_col_total}, {"cols": ["arith_equiv","n"], "totaler": totaler(), "proportioner": proportioners.per_col_total}, {"cols": ["n", "nilpotency"], "totaler": totaler(), "proportioner": proportioners.per_row_total}, ] knowls = {"n": "gg.degree", "order": "group.order", "nilpotency": "group.nilpotent", "arith_equiv": "gg.arithmetically_equivalent", "solv": "group.solvable", "prim": "gg.primitive", } top_titles = {"nilpotency": "nilpotency classes", "solv": "solvability", "arith_equiv": "number of arithmetic equivalent siblings", "prim": "primitivity"} short_display = {"n": "degree", "nilpotency": "nilpotency class", "solv": "solvable", "arith_equiv": "arithmetic equivalent count", "prim": "primitive", } formatters = {"solv": yesone, "prim": yesone, "arith_equiv": fixminus1} query_formatters = {"solv": eqyesone("solv"), "prim": eqyesone("prim"), "arith_equiv": undominus1} buckets = { "n": ["1-3", "4-7", "8", "9-11", "12", "13-15", "16", "17-23", "24", "25-31", "32", "33-35", "36", "37-39", "40", "41-47"], "order": ["1-15", "16-31", "32-63", "64-127", "128-255", "256-511", "512-1023", "1024-2047", "2048-65535", "65536-40000000000", "40000000000-"] } def __init__(self): self.ngroups = db.gps_transitive.count() @property def summary(self): return r"The database currently contains $%s$ transitive subgroups of $S_n$, including all subgroups (up to conjugacy) for $n \le 47$ and $n \ne 32$. Among the $2{,}801{,}324$ groups in degree $32$, all those with order less than $512$ or greater than $40{,}000{,}000{,}000$ are included." % latex_comma(self.ngroups) @property def short_summary(self): return r'The database current contains $%s$ groups, including all transitive subgroups of $S_n$ (up to conjugacy) for $n \le 47$ and $n \ne 32$. Here are some <a href="%s">further statistics</a>.' % (latex_comma(self.ngroups), url_for(".statistics"))
def discdisp(p): return {'cols': ['n', 'c'], 'constraint': {'p': p, 'n': {'$lte': 15}}, 'top_title':[('degree', 'lf.degree'), ('and', None), ('discriminant exponent', 'lf.discriminant_exponent'), ('for %s-adic fields'%p, None)], 'totaler': totaler(col_counts=False), 'proportioner': proportioners.per_row_query(lambda n: {'n':int(n)})}
def ramdisp(p): return {'cols': ['n', 'e'], 'constraint': {'p': p, 'n': {'$lte': 15}}, 'top_title':[('degree', 'lf.degree'), ('and', None), ('ramification index', 'lf.ramification_index'), ('for %s-adic fields'%p, None)], 'totaler': totaler(col_counts=False), 'proportioner': proportioners.per_row_total}
class DirichStats(StatsDisplay): table = db.char_dir_orbits baseurl_func = ".render_DirichletNavigation" stat_list = [ {"cols": ["conductor"]}, {"cols": ["order", "modulus"], "title_joiner": " by ", "totaler": totaler(), "proportioner": proportioners.per_col_total}, {"cols": ["is_primitive", "modulus"], "title_joiner": " by ", "totaler": totaler(), "proportioner": proportioners.per_col_total}, {"cols": ["is_real", "modulus"], "title_joiner": " by ", "totaler": totaler(), "proportioner": proportioners.per_col_total}, {"cols": ["is_minimal", "modulus"], "title_joiner": " by ", "totaler": totaler(), "proportioner": proportioners.per_col_total}, ] buckets = {"conductor": ["1-10", "11-100", "101-1000", "1001-10000"], "modulus": ["1-10", "11-100", "101-1000", "1001-10000"], "order": ["1-10", "11-100", "101-1000", "1001-10000"]} knowls = {"conductor": "character.dirichlet.conductor", "modulus": "character.dirichlet.modulus", "order": "character.dirichlet.order", "is_minimal": "character.dirichlet.minimal", "is_primitive": "character.dirichlet.primitive", "is_real": "character.dirichlet.real"} short_display = {"is_minimal": "minimal", "is_primitive": "primitive", "is_real": "real"} top_titles = {"order": "order", "is_minimal": "minimality", "is_primitive": "primitivity", "is_real": "real characters"} formatters = {"is_minimal": yesno, "is_primitive": yesno, "is_real": yesno} def __init__(self): self.nchars = db.char_dir_values.count() self.norbits = db.char_dir_orbits.count() self.maxmod = db.char_dir_orbits.max("modulus") @property def short_summary(self): return 'The database currently contains %s %s of %s up to %s, lying in %s %s. Among these, L-functions are available for characters of modulus up to 2,800 (and some of higher modulus). Here are some <a href="%s">further statistics</a>.' % ( comma(self.nchars), display_knowl("character.dirichlet", "Dirichlet characters"), display_knowl("character.dirichlet.modulus", "modulus"), comma(self.maxmod), comma(self.norbits), display_knowl("character.dirichlet.galois_orbit", "Galois orbits"), url_for(".statistics")) @property def summary(self): return "The database currently contains %s %s of %s up to %s, lying in %s %s. The tables below show counts of Galois orbits." % ( comma(self.nchars), display_knowl("character.dirichlet", "Dirichlet characters"), display_knowl("character.dirichlet.modulus", "modulus"), comma(self.maxmod), comma(self.norbits), display_knowl("character.dirichlet.galois_orbit", "Galois orbits"))
class STStats(StatsDisplay): table = db.gps_sato_tate baseurl_func = ".index" stat_list = [ { "cols": ["component_group", "identity_component"], "totaler": totaler(), "proportioner": proportioners.per_col_total }, { "cols": ["identity_component"], "constraint": { "maximal": True }, "top_title": [("maximal subgroups", "st_group.supgroups"), ("per", None), ("identity component", "st_group.identity_component")], }, { "cols": ["trace_zero_density", "identity_component"], "totaler": totaler(), "proportioner": proportioners.per_col_total }, { "cols": ["second_trace_moment", "identity_component"], "totaler": totaler(), "proportioner": proportioners.per_col_total }, { "cols": ["fourth_trace_moment", "identity_component"], "totaler": totaler(), "proportioner": proportioners.per_col_total }, { "cols": ["first_a2_moment", "identity_component"], "totaler": totaler(), "proportioner": proportioners.per_col_total }, ] formatters = { "component_group": compformatter, "identity_component": idformatter } sort_keys = {"component_group": compdata, "trace_zero_density": QQ} query_formatters = { "component_group": (lambda comp: "component_group=%s" % compunformatter(comp)), "identity_component": (lambda grp: "identity_component=%s" % (idunformatter(grp))) } top_titles = { "trace_zero_density": "trace zero densities", "first_a2_moment": "first $a_2$ moment" } knowls = { "identity_component": "st_group.identity_component", "component_group": "st_group.component_group", "trace_zero_density": "st_group.trace_zero_density", "second_trace_moment": "st_group.moments", "fourth_trace_moment": "st_group.moments", "first_a2_moment": "st_group.moments" } def __init__(self): self.ngroups = db.gps_sato_tate.count() @property def summary(self): return r"The database currently contains %s %s. The statistics below omit the infinite family $\mu(n)$ with trivial %s since they are generated dynamically in search results." % ( self.ngroups, display_knowl('st_group.definition', 'Sato-Tate groups'), display_knowl('st_group.identity_component', 'identity component')) @property def short_summary(self): return r'The database currently contains all %s %s of %s 1 and %s up to 4, as well as all Sato-Tate groups of weight 0 and degree 1 with %s of order at most $10^{20}$. Here are some <a href="%s">further statistics</a>.' % ( display_knowl('st_group.rational', 'rational'), display_knowl('st_group.definition', 'Sato-Tate groups'), display_knowl('st_group.weight', 'weight'), display_knowl('st_group.degree', 'degree'), display_knowl('st_group.component_group', 'component group'), url_for('.statistics'))
class ECNF_stats(StatsDisplay): table = db.ec_nfcurves baseurl_func = ".index" stat_list = [ { 'cols': ['degree', 'conductor_norm'], 'totaler': totaler(), 'proportioner': proportioners.per_row_total }, { 'cols': ['degree', 'rank'], 'totaler': totaler(), 'proportioner': proportioners.per_row_total, 'intro': ['Only curves where the rank has been computed are shown.'] }, { 'cols': ['degree', 'torsion_structure'], 'totaler': totaler(), 'proportioner': proportioners.per_row_total }, ] buckets = { 'conductor_norm': [ '1-100', '101-1000', '1001-10000', '10001-50000', '50001-100000', '100001-150000' ] } formatters = {'torsion_structure': latex_tor} query_formatters = { 'degree': (lambda x: 'bf_deg=%s' % x), 'torsion_structure': (lambda x: 'torsion_structure=%s' % (str(tor_invs(x)).replace(" ", ""))) } sort_keys = {'torsion_structure': tor_sort_key} knowls = { 'degree': 'nf.degree', 'conductor_norm': 'ec.conductor', 'rank': 'ec.rank', 'torsion_structure': 'ec.torsion_subgroup' } ec_knowls = '<a knowl="ec">elliptic curves</a>' ec_knowl = '<a knowl="ec">elliptic curve</a>' iso_knowls = '<a knowl="ec.isogeny_class">isogeny classes</a>' iso_knowl = '<a knowl="ec.isogeny_class">isogeny class</a>' nf_knowls = '<a knowl="nf">number fields</a>' nf_knowl = '<a knowl="nf">number field</a>' deg_knowl = '<a knowl="nf.degree">degree</a>' cond_knowls = '<a knowl="ec.conductor">conductors</a>' cond_knowl = '<a knowl="ec.conductor">conductor</a>' @lazy_attribute def ncurves(self): return db.ec_nfcurves.count() @lazy_attribute def nclasses(self): return db.ec_nfcurves.count({'number': 1}) @lazy_attribute def field_counts(self): return db.ec_nfcurves.stats.column_counts('field_label') @lazy_attribute def field_classes(self): return db.ec_nfcurves.stats.column_counts('field_label', {'number': 1}) @lazy_attribute def sig_counts(self): return db.ec_nfcurves.stats.column_counts('signature') @lazy_attribute def sig_classes(self): return db.ec_nfcurves.stats.column_counts('signature', {'number': 1}) @lazy_attribute def deg_counts(self): return db.ec_nfcurves.stats.column_counts('degree') @lazy_attribute def deg_classes(self): return db.ec_nfcurves.stats.column_counts('degree', {'number': 1}) @lazy_attribute def torsion_counts(self): return db.ec_nfcurves.stats.column_counts('torsion_structure') @lazy_attribute def field_normstats(self): D = db.ec_nfcurves.stats.numstats('conductor_norm', 'field_label') return { label: { 'ncurves': self.field_counts[label], 'nclasses': self.field_classes[label], 'max_norm': D[label]['max'] } for label in D } @lazy_attribute def sig_normstats(self): D = db.ec_nfcurves.stats.numstats('conductor_norm', 'signature') return { sig: { 'ncurves': self.sig_counts[sig], 'nclasses': self.sig_classes[sig], 'max_norm': D[sig]['max'] } for sig in D } @lazy_attribute def deg_normstats(self): D = db.ec_nfcurves.stats.numstats('conductor_norm', 'degree') return { deg: { 'ncurves': self.deg_counts[deg], 'nclasses': self.deg_classes[deg], 'max_norm': D[deg]['max'] } for deg in D } @lazy_attribute def maxdeg(self): return db.ec_nfcurves.max('degree') @staticmethod def _get_sig(nflabel): d, r = map(int, nflabel.split('.', 2)[:2]) return (r, (d - r) // 2) @staticmethod def _get_deg(nflabel): return int(nflabel.split('.', 1)[0]) def _fields_by(self, func): D = defaultdict(list) for label, count in self.field_counts.items(): if count: D[func(label)].append(label) for fields in D.values(): fields.sort(key=sort_field) return D @lazy_attribute def fields_by_sig(self): return self._fields_by(self._get_sig) @lazy_attribute def fields_by_deg(self): return self._fields_by(self._get_deg) @lazy_attribute def sigs_by_deg(self): def _get_deg_s(sig): r, s = sig return r + 2 * s D = defaultdict(list) for sig in self.sig_counts: D[_get_deg_s(sig)].append(sig) for sigs in D.values(): sigs.sort() return D @property def summary(self): return ''.join([ r'The database currently contains {} '.format(comma(self.ncurves)), self.ec_knowls, r' in {} '.format(comma(self.nclasses)), self.iso_knowls, r', over {} '.format(len(self.field_counts)), self.nf_knowls, ' of ', self.deg_knowl, r' 2 to {}.'.format(self.maxdeg), r' Elliptic curves defined over $\mathbb{Q}$ are contained in a <a href="/EllipticCurve/Q/">separate database</a>.' ]) @property def short_summary(self): return self.summary + ' Here are some <a href="%s">further statistics</a>.' % ( url_for(".statistics")) @cached_method def field_summary(self, field): stats = self.field_normstats[field] ncurves = stats['ncurves'] nclasses = stats['nclasses'] max_norm = stats['max_norm'] ec_knowl = self.ec_knowl if ncurves == 1 else self.ec_knowls iso_knowl = self.iso_knowl if ncurves == 1 else self.iso_knowls nf_knowl = self.nf_knowl if ncurves == 1 else self.nf_knowls cond_knowl = self.cond_knowl if ncurves == 1 else self.cond_knowls s = '' if max_norm == 1 else 'up to ' norm_phrase = ' of norm {}{}.'.format(s, max_norm) return ''.join([ r'The database currently contains {} '.format(ncurves), ec_knowl, r' defined over the ', nf_knowl, r' {}, in {} '.format(field_pretty(field), nclasses), iso_knowl, r', with ', cond_knowl, norm_phrase ]) @cached_method def signature_summary(self, sig): r, s = sig d = r + 2 * s stats = self.sig_normstats[r, s] ncurves = stats['ncurves'] nclasses = stats['nclasses'] max_norm = stats['max_norm'] return ''.join([ r'The database currently contains {} '.format(ncurves), self.ec_knowls, r' defined over ', self.nf_knowls, r' of signature ({},{}) (degree {}), in {} '.format( r, s, d, nclasses), self.iso_knowls, r', with ', self.cond_knowls, r' of norm up to {}.'.format(max_norm) ]) @cached_method def degree_summary(self, d): stats = self.deg_normstats[d] ncurves = stats['ncurves'] nclasses = stats['nclasses'] max_norm = stats['max_norm'] return ''.join([ r'The database currently contains {} '.format(ncurves), self.ec_knowls, r' defined over ', self.nf_knowls, r' of degree {}, in {} '.format(d, nclasses), self.iso_knowls, r', with ', self.cond_knowls, r' of norm up to {}.'.format(max_norm) ]) @cached_method def isogeny_degrees(self): cur = db._execute( SQL("SELECT UNIQ(SORT(ARRAY_AGG(elements ORDER BY elements))) FROM ec_nfcurves, UNNEST(isodeg) as elements" )) return cur.fetchone()[0] def setup(self, attributes=None, delete=False): if attributes is None: # The following statistics aren't updated by the normal setup function # The assert is for pyflakes assert self.field_normstats assert self.sig_normstats assert self.deg_normstats assert self.torsion_counts super().setup(attributes, delete)
class Lattice_stats(StatsDisplay): def __init__(self): self.nlats = comma(db.lat_lattices.count()) self.max_cn = db.lat_lattices.max("class_number") self.max_dim = db.lat_lattices.max("dim") self.max_det = db.lat_lattices.max("det") self.kposdef = display_knowl('lattice.postive_definite', 'positive definite') self.kintegral = display_knowl('lattice.definition', 'integral lattices') self.kcatalogue = display_knowl('lattice.catalogue_of_lattices', 'Catalogue of Lattices') self.kcn = display_knowl('lattice.class_number', 'class number') self.kdim = display_knowl('lattice.dimension', 'dimension') self.kdet = display_knowl('lattice.determinant', 'determinant') self.kpri = display_knowl('lattice.primitive', 'primitive') @property def short_summary(self): return 'The database currently contains {} {} {}. It includes data from the {}. The largest {} is {}, the largest {} is {}, and the largest {} is {}. Here are some <a href="{}">further statistics</a>.'.format( self.nlats, self.kposdef, self.kintegral, self.kcatalogue, self.kcn, self.max_cn, self.kdim, self.max_dim, self.kdet, comma(self.max_det), url_for(".statistics"), ) table = db.lat_lattices baseurl_func = ".lattice_render_webpage" buckets = { "dim": ["1", "2", "3", "4", "5", "6", "7", "8-15", "16-31"], "det": [ "1", "2-10", "11-100", "101-1000", "1001-10000", "10001-100000", "100001-1000000" ], "minimum": ["1", "2", "3", "4-7", "8-15", "16-31", "32-63", "64-127", "128-255"], "class_number": ["1", "2", "3", "4-7", "8-15", "16-31", "32-63"], "aut": [ "2", "4", "8", "12", "16", "24", "32", "33-128", "129-512", "513-2048", "2049-16384", "16385-262144", "262145-8388608", "8388609-191102976" ] } knowls = { 'dim': 'lattice.dimension', 'det': 'lattice.determinant', 'minimum': 'lattice.minimal_vector', 'class_number': 'lattice.class_number', 'aut': 'lattice.group_order' } short_display = { 'dim': 'dimension', 'det': 'determinant', 'minimum': 'minimal length', 'aut': 'automorphism order' } top_titles = { 'minimum': 'minimal vector length', 'aut': 'automorphism group order' } stat_list = [ { "cols": ["det", "dim"], "proportioner": proportioners.per_col_total, "totaler": totaler() }, { "cols": ["minimum", "dim"], "proportioner": proportioners.per_col_total, "totaler": totaler() }, { "cols": ["class_number", "dim"], "proportioner": proportioners.per_col_total, "totaler": totaler() }, { "cols": ["aut", "dim"], "proportioner": proportioners.per_col_total, "totaler": totaler() }, ]
class AbvarFqStats(StatsDisplay): extent_knowl = "rcs.cande.av.fq" table = db.av_fq_isog baseurl_func = ".abelian_varieties" buckets = { "q": ["2", "3", "4", "5-8", "9-16", "17-32", "37-64", "67-128", "131-211", "223-1024"], "geometric_extension_degree": ["1", "2", "3-8", "9-24", "25-64", "65-168"], "jacobian_count": ["0", "1", "2", "3-8", "9-16", "17-256", "257-6375"], "hyp_count": ["0", "1", "2", "3-8", "9-16", "17-256", "257-6375"], "size": ["1", "2", "3-16", "17-256", "257-12240"], "twist_count": ["1", "2", "3-8", "9-24", "25-64", "65-390"], } knowls = { "q": "ag.base_field", "g": "ag.dimension", "p_rank": "av.fq.p_rank", "angle_rank": "av.fq.angle_rank", "galois_group": "nf.galois_group", "size": "av.fq.isogeny_class_size", "geometric_extension_degree": "av.endomorphism_field", "jacobian_count": "av.jacobian_count", "hyp_count": "av.hyperelliptic_count", "twist_count": "av.twist", "max_twist_degree": "av.twist", "is_simple": "av.simple", "is_geometrically_simple": "av.geometrically_simple", "is_primitive": "ag.primitive", "has_jacobian": "ag.jacobian", "has_principal_polarization": "av.princ_polarizable", } top_titles = { "q": "base field", "g": "dimension", "p_rank": "$p$-rank", "galois_group": "Galois group", "size": "isogeny class size", "geometric_extension_degree": "degree of Endomorphism field", "jacobian_count": "number of Jacobians", "hyp_count": "number of hyperelliptic curves", "twist_count": "number of twists", "max_twist_degree": "maximum twist degree", "is_geometrically_simple": "geometrically simple", "is_simple": "simple", "is_primitive": "primitive", "has_jacobian": "Jacobian", "has_principal_polarization": "principally polarizable", } short_display = { "q": "q", "g": "g", "size": "size", "geometric_extension_degree": "End. degree", "jacobian_count": "# Jacobians", "hyp_count": "# Hyp. curves", "twist_count": "# twists", "max_twist_degree": "max twist degree", "is_geometrically_simple": "geom. simple", "is_simple": "simple", "is_primitive": "primitive", "has_jacobian": "Jacobian", "has_principal_polarization": "princ. polarizable", } formatters = {"is_geometrically_simple": yn, "is_simple": yn, "is_primitive": yn, "has_jacobian": ynu, "has_principal_polarization": ynu, } query_formatters = {"is_geometrically_simple": (lambda t: "geom_simple=%s" % (yn(t))), "is_simple": (lambda t: "simple=%s" % (yn(t))), "is_primitive": (lambda t: "primitive=%s" % (yn(t))), "has_jacobian": (lambda t: "jacobian=%s" % (ynu(t))), "has_principal_polarization": (lambda t: "polarizable=%s" % (ynu(t))), "jacobian_count": (lambda t: "jac_cnt=%s" % t), "hyp_count": (lambda t: "hyp_cnt=%s" % t), } stat_list = [ {"cols": ["g", "q"], "proportioner": proportioners.per_total, "totaler": totaler()}, {"cols": ["g", "p_rank"], "proportioner": proportioners.per_row_total, "totaler": totaler()}, {"cols": ["g", "twist_count"], "proportioner": proportioners.per_row_total, "totaler": totaler()}, {"cols": ["g", "max_twist_degree"], "proportioner": proportioners.per_row_total, "totaler": totaler()}, {"cols": ["g", "geometric_extension_degree"], "proportioner": proportioners.per_row_total, "totaler": totaler()}, {"cols": ["g", "is_geometrically_simple"], "constraint": {"is_simple": True}, "proportioner": proportioners.per_row_total, "totaler": totaler(), "top_title": display_knowl("av.geometrically_simple", "geometrically simple") + " isogeny classes among those that are " + display_knowl("av.simple", "simple")}, {"cols": ["has_principal_polarization", "q"], "constraint": {"g": 2}, "buckets": {"q":["2", "3", "4", "5", "7", "8", "9", "11", "13", "16", "17", "19", "23", "25"]}, "proportioner": proportioners.per_col_total, "top_title": display_knowl("av.princ_polarizable", "principally polarizable") + " abelian surfaces"}, {"cols": ["has_jacobian", "q"], "constraint": {"g": 2}, "buckets": {"q":["2", "3", "4", "5", "7", "8", "9", "11", "13", "16", "17", "19", "23", "25"]}, "proportioner": proportioners.per_col_total, "top_title": display_knowl("ag.jacobian", "Jacobians") + " among isogeny classes of abelian surfaces"}, {"cols": ["has_jacobian", "q"], "constraint": {"g": 3}, "buckets": {"q":["2", "3", "4", "5", "7", "8", "9", "11", "13", "16", "17", "19", "23", "25"]}, "proportioner": proportioners.per_col_total, "top_title": display_knowl("ag.jacobian", "Jacobians") + " among isogeny classes of abelian threefolds"}, {"cols": ["jacobian_count", "q"], "constraint": {"g": 2}, "buckets": {"q":["2", "3", "4", "5", "7", "8", "9", "11", "13", "16", "17", "19", "23", "25"], "jacobian_count": ["0", "1", "2", "3-8", "9-16", "17-256"]}, "proportioner": proportioners.per_col_total, "top_title": display_knowl("av.jacobian_count", "Jacobian counts") + " among isogeny classes of abelian surfaces"}, {"cols": ["jacobian_count", "q"], "constraint": {"g": 3}, "buckets": {"q":["2", "3", "5"], "jacobian_count": ["0", "1", "2", "3-8", "9-16", "17-256", "257-6375"]}, "proportioner": proportioners.per_col_total, "top_title": display_knowl("av.jacobian_count", "Jacobian counts") + " among isogeny classes of abelian threefolds"}, {"cols": ["hyp_count", "q"], "constraint": {"g": 3}, "buckets": {"q":["2", "3", "5", "7", "9", "11", "13"], "hyp_count": ["0", "1", "2", "3-8", "9-16", "17-256", "257-6375"]}, "proportioner": proportioners.per_col_total, "top_title": display_knowl("av.hyperelliptic_count", "hyperelliptic Jacobian counts") + " among isogeny classes of abelian threefolds"}, {"cols": ["is_primitive", "q"], "constraint": {"g": 2}, "buckets": {"q":["4", "8", "9", "16", "25", "27", "32", "49", "64", "81", "125", "128", "243", "256", "343", "512", "625", "729", "1024"]}, "proportioner": proportioners.per_col_total, "top_title": display_knowl("ag.primitive", "primitive") + " abelian surfaces"}, {"cols": ["is_primitive", "q"], "constraint": {"g":3}, "buckets": {"q":["4", "8", "9", "16", "25"]}, "proportioner": proportioners.per_col_total, "top_title": display_knowl("ag.primitive", "primitive") + " abelian threefolds"}, ] @staticmethod def dynamic_parse(info, query): from lmfdb.abvar.fq.main import common_parse common_parse(info, query) dynamic_parent_page = "abvarfq-refine-search.html" dynamic_cols = ["q", "g", "p_rank", "angle_rank", "size", "geometric_extension_degree", "jacobian_count", "hyp_count", "twist_count", "max_twist_degree", "is_simple", "is_geometrically_simple", "is_primitive", "has_jacobian", "has_principal_polarization", "jacobian_count", "hyp_count"] @lazy_attribute def _counts(self): return db.av_fq_isog.stats.column_counts(["g", "q"]) @lazy_attribute def qs(self): return sorted(set(q for g, q in self._counts)) @lazy_attribute def gs(self): return sorted(set(g for g, q in self._counts)) @lazy_attribute def isogeny_knowl(self): return display_knowl("av.isogeny_class", "isogeny classes") @lazy_attribute def abvar_knowl(self): return display_knowl("ag.abelian_variety", "abelian varieties") @lazy_attribute def short_summary(self): return r"The database currently contains %s %s of %s of dimension up to %s over finite fields." % ( self.counts["nclasses_c"], self.isogeny_knowl, self.abvar_knowl, max(self.gs), ) @lazy_attribute def summary(self): return r"The database currently contains %s %s of %s of dimension up to %s over finite fields. In addition to the statistics below, you can also <a href='%s'>create your own</a>." % ( self.counts["nclasses_c"], self.isogeny_knowl, self.abvar_knowl, max(self.gs), url_for("abvarfq.dynamic_statistics"), ) @lazy_attribute def counts(self): counts = {} counts["nclasses"] = ncurves = sum(self._counts.values()) counts["nclasses_c"] = comma(ncurves) counts["gs"] = self.gs counts["qs"] = self.qs counts["qg_count"] = defaultdict(lambda: defaultdict(int)) for (g, q), cnt in self._counts.items(): counts["qg_count"][q][g] = cnt return counts @lazy_attribute def maxq(self): return {g: max(q for gg, q in self._counts if g == gg) for g in self.gs} @lazy_attribute def maxg(self): maxg = {q: max(g for g, qq in self._counts if q == qq) for q in self.qs} # maxg[None] used in decomposition search maxg[None] = max(self.gs) return maxg
class GroupStats(StatsDisplay): extent_knowl = "rcs.cande.groups.abstract" table = db.gps_groups baseurl_func = ".index" buckets = { "aut_order": [ "1-7", "8-32", "33-128", "129-512", "513-2048", "2049-8192", "8193-65536", "65537-" ], "outer_order": [ "1", "2-7", "8-32", "33-128", "129-512", "513-2048", "2049-8192", "8193-65536", "65537-" ], } knowls = group_knowls short_display = { "exponents_of_order": "order factorization", } formatters = { "exponents_of_order": elist_formatter, "abelian": formatters.yesno, "solvable": formatters.yesno, "supersolvable": formatters.yesno, "Zgroup": formatters.yesno, "cyclic": formatters.yesno, "nilpotency_class": nilp_formatter, "solvability_type": stype_formatter, } query_formatters = { "exponents_of_order": elist_qformatter, "nilpotency_class": nilp_qformatter, "solvability_type": stype_qformatter, } sort_keys = { "exponents_of_order": lambda elist: [sum(elist)] + [-e for e in elist], } stat_list = [ { "cols": ["solvability_type", "exponents_of_order"], "top_title": f"Solvability as a function of {display_knowl('group.order', 'order')}", "proportioner": proportioners.per_col_total, "totaler": totaler() }, { "cols": ["nilpotency_class", "exponents_of_order"], "top_title": f"{display_knowl('group.nilpotent', 'nilpotency class')} as a function of {display_knowl('group.order', 'order')}", "proportioner": proportioners.per_col_total, "totaler": totaler() }, { "cols": ["rank", "exponents_of_order"], "top_title": f"{display_knowl('group.rank', 'rank')} as a function of {display_knowl('group.order', 'order')}", "proportioner": proportioners.per_col_total, "totaler": totaler() }, { "cols": ["derived_length", "exponents_of_order"], "top_title": f"{display_knowl('group.derived_series', 'derived length')} among {display_knowl('group.solvable', 'solvable')} groups as a function of {display_knowl('group.order', 'order')}", "constraint": { "solvable": True }, "proportioner": proportioners.per_col_total, "totaler": totaler() }, { "cols": ["aut_order", "exponents_of_order"], "top_title": f"{display_knowl('group.automorphism', 'automorphism group order')} as a function of {display_knowl('group.order', 'order')} for {display_knowl('group.abelian', 'nonabelian')} groups", "constraint": { "abelian": False }, "proportioner": proportioners.per_col_total, "totaler": totaler() }, { "cols": ["outer_order", "exponents_of_order"], "top_title": f"{display_knowl('group.outer_aut', 'outer aut. group order')} as a function of {display_knowl('group.order', 'order')} for {display_knowl('group.abelian', 'nonabelian')} groups", "constraint": { "abelian": False }, "proportioner": proportioners.per_col_total, "totaler": totaler() }, ] @staticmethod def dynamic_parse(info, query): from .main import group_parse group_parse(info, query) dynamic_parent_page = "abstract-search.html" dynamic_cols = ["order", "exponents_of_order", "abelian"] @lazy_attribute def short_summary(self): return fr'The database currently contains {comma(db.gps_groups.count())} {display_knowl("group", "groups")} of {display_knowl("group.order", "order")} $n\leq {db.gps_groups.max("order")}$ together with {comma(db.gps_subgroups.count())} of their {display_knowl("group.subgroup", "subgroups")} and {comma(db.gps_char.count())} of their {display_knowl("group.representation.character", "irreducible complex characters")}. You can <a href="{url_for(".statistics")}">browse further statistics</a>.' # or <a href="{url_for(".dynamic_statistics")}">create your own</a>.' @lazy_attribute def summary(self): return fr'The database currently contains {comma(db.gps_groups.count())} {display_knowl("group", "groups")} of {display_knowl("group.order", "order")} $n\leq {db.gps_groups.max("order")}$ together with {comma(db.gps_subgroups.count())} of their {display_knowl("group.subgroup", "subgroups")} and {comma(db.gps_char.count())} of their {display_knowl("group.representation.character", "irreducible complex characters")}.' # In addition to the statistics below, you can also <a href="{url_for(".dynamic_statistics")}">create your own</a>.'