Exemple #1
0
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"))
Exemple #2
0
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)})}
Exemple #3
0
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}
Exemple #4
0
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"))
Exemple #5
0
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'))
Exemple #6
0
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)
Exemple #7
0
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()
        },
    ]
Exemple #8
0
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
Exemple #9
0
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>.'