diff --git a/lmfdb/number_fields/number_field.py b/lmfdb/number_fields/number_field.py index f350f55060..e614ca7395 100644 --- a/lmfdb/number_fields/number_field.py +++ b/lmfdb/number_fields/number_field.py @@ -839,7 +839,7 @@ def number_field_jump(info): MathCol("torsion_order", "nf.unit_group", "Unit group torsion", align="center", default=False), MultiProcessedCol("unit_rank", "nf.rank", "Unit group rank", ["r2", "degree"], lambda r2, degree: degree - r2 - 1, align="center", mathmode=True, default=False), MathCol("regulator", "nf.regulator", "Regulator", align="left", default=False)], - db_cols=["class_group", "coeffs", "degree", "r2", "disc_abs", "disc_sign", "galois_label", "label", "ramps", "used_grh", "cm", "is_galois", "torsion_order", "regulator", "rd", "grd", "monogenic", "num_ram"]) + db_cols=["class_group", "coeffs", "degree", "r2", "disc_abs", "disc_sign", "galois_label", "label", "ramps", "used_grh", "cm", "is_galois", "torsion_order", "regulator", "rd", "grd", "monogenic", "num_ram", "relative_class_number"]) def nf_postprocess(res, info, query): galois_labels = [rec["galois_label"] for rec in res if rec.get("galois_label")] @@ -895,6 +895,7 @@ def number_field_search(info, query): parse_floats(info, query, 'rd') parse_floats(info, query, 'regulator') parse_posints(info,query,'class_number') + parse_posints(info,query,'relative_class_number') parse_ints(info,query,'num_ram') parse_bool(info,query,'cm_field',qfield='cm') parse_bool(info,query,'is_galois') @@ -1196,6 +1197,11 @@ def __init__(self): knowl="nf.ideal_class_group", example="[2,4]", example_span="[ ], [3], or [2,4]") + relative_class_number = TextBox( + name="relative_class_number", + label="Relative class number", + knowl="nf.relative_class_number", + example="3") num_ram = TextBox( name="num_ram", label="Ramified prime count", @@ -1258,13 +1264,20 @@ def __init__(self): [class_number, class_group], [ram_primes, ur_primes], [regulator, cm_field], - [completion, subfield], - [index, inessentialprimes], - [monogenic, is_minimal_sibling], - [count]] + [completion, relative_class_number], + [index, subfield], + [monogenic, inessentialprimes], + [count, is_minimal_sibling]] self.refine_array = [ - [degree, signature, class_number, class_group, cm_field], - [num_ram, ram_primes, ur_primes, gal, is_galois], - [discriminant, rd, grd, regulator, subfield], - [completion, is_minimal_sibling, monogenic, index, inessentialprimes]] + [degree, signature, num_ram, ram_primes, ur_primes ], + [gal, is_galois, subfield, class_group, class_number], + [discriminant, rd, grd, cm_field, relative_class_number], + [regulator, completion, monogenic, index, inessentialprimes], + [is_minimal_sibling]] + + #[degree, signature, class_number, class_group, cm_field], + #[num_ram, ram_primes, ur_primes, gal, is_galois], + #[discriminant, rd, grd, regulator, subfield], + #[completion, is_minimal_sibling, monogenic, index, inessentialprimes], + #[relative_class_number]] diff --git a/lmfdb/number_fields/templates/nf-show-field.html b/lmfdb/number_fields/templates/nf-show-field.html index dd3657fdf8..a9c1e0689e 100644 --- a/lmfdb/number_fields/templates/nf-show-field.html +++ b/lmfdb/number_fields/templates/nf-show-field.html @@ -82,6 +82,12 @@

{{ KNOWL('nf.ideal_class_group', title='Class group') }} and {{ KNOWL('nf. {{ info.grh_label|safe }} {{ place_code('class_group') }}

+ {% if nf.is_cm_field() %} +

+ {{KNOWL('nf.relative_class_number','Relative class number')}}: {{ nf.relh() }} + {{ info.grh_label|safe }} +

+ {% endif %}

{{ KNOWL('nf.unit_group', title='Unit group') }}

diff --git a/lmfdb/number_fields/test_numberfield.py b/lmfdb/number_fields/test_numberfield.py index 19c2739095..2b4d82c1cb 100644 --- a/lmfdb/number_fields/test_numberfield.py +++ b/lmfdb/number_fields/test_numberfield.py @@ -77,6 +77,9 @@ def test_signature_search(self): self.check_args('/NumberField/?start=0°ree=6&signature=%5B0%2C3%5D&count=100', '6.0.61131.1') self.check_args('/NumberField/?start=0°ree=7&signature=%5B3%2C2%5D&count=100', '7.3.1420409.1') + def test_relative_class_number(self): + self.check_args('/NumberField/4.0.1327873600.2', '2108') + def test_fundamental_units(self): self.check_args('NumberField/2.2.10069.1', '43388173') self.check_args('NumberField/3.3.10004569.1', '22153437467081345') diff --git a/lmfdb/number_fields/web_number_field.py b/lmfdb/number_fields/web_number_field.py index 0b9575289a..4d543b554e 100644 --- a/lmfdb/number_fields/web_number_field.py +++ b/lmfdb/number_fields/web_number_field.py @@ -798,16 +798,18 @@ def units(self): # fundamental units def cnf(self): if self.degree()==1: return r'=\mathstrut & \frac{2^1 (2\pi)^0 \cdot 1\cdot 1}{2\cdot\sqrt 1}' + r'\cr' + r'= \mathstrut & 1' - if not self.haskey('class_group'): - return r'$ '+na_text() - # Otherwise we should have what we need [r1,r2] = self.signature() - reg = self.regulator() - h = self.class_number() w = self.root_of_1_order() r1term= r'2^{%s}\cdot'% r1 r2term= r'(2\pi)^{%s}\cdot'% r2 disc = ZZ(self._data['disc_abs']) + approx1 = r'= \mathstrut &' + if not self.haskey('class_group'): + ltx = r'%s\frac{%s%s %s \cdot %s}{%s\cdot\sqrt{%s}}'%(approx1,r1term,r2term,'R','h',w,disc) + return ltx+r'\cr\mathstrut & \text{ some values not computed }' + # Otherwise we should have what we need + reg = self.regulator() + h = self.class_number() approx1 = r'\approx' if self.unit_rank()>0 else r'=' approx1 += r"\mathstrut &" ltx = r'%s\frac{%s%s %s \cdot %s}{%s\cdot\sqrt{%s}}'%(approx1,r1term,r2term,str(reg),h,w,disc) @@ -867,6 +869,11 @@ def can_class_number(self): return True return False + def relh(self): + if self.haskey('relative_class_number'): + return f"${self._data['relative_class_number']}$" + return dnc + def is_null(self): return self._data is None