From 3b031bbac9e8fba0b27dc828ceb4ff3823d16dd8 Mon Sep 17 00:00:00 2001 From: John Cremona Date: Thu, 5 Dec 2024 05:09:49 -0500 Subject: [PATCH 1/7] Hide BMF L-ratio while data is fixed --- lmfdb/bianchi_modular_forms/templates/bmf-newform.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lmfdb/bianchi_modular_forms/templates/bmf-newform.html b/lmfdb/bianchi_modular_forms/templates/bmf-newform.html index 0984fd0ef5..7ff03eae08 100644 --- a/lmfdb/bianchi_modular_forms/templates/bmf-newform.html +++ b/lmfdb/bianchi_modular_forms/templates/bmf-newform.html @@ -33,9 +33,9 @@

{{ KNOWL('mf.bianchi.newform', 'Form') }}

{{ KNOWL('mf.bianchi.spaces', title='Newspace')}}:{{data.newspace_label}} (dimension {{ data.newspace_dimension }}) {{ KNOWL('mf.bianchi.sign',title="Sign of functional equation") }}: {{data.sign}} {{ KNOWL('mf.bianchi.anr',title="Analytic rank")}}: {{data.anrank}} -{% if data.Lratio %} - {{ KNOWL('mf.bianchi.anr',title="L-ratio")}}: {{data.Lratio}} -{% endif %} +{# See issue #6288 + {{ KNOWL('mf.bianchi.L-ratio',title="L-ratio")}}: {{data.Lratio}} +#}

From 033a961575b226ebb1aadde4ef5e90ff136ac741 Mon Sep 17 00:00:00 2001 From: John Cremona Date: Thu, 5 Dec 2024 09:57:31 -0500 Subject: [PATCH 2/7] ECNF: added Neron-Tate regulator to curve home page --- lmfdb/ecnf/WebEllipticCurve.py | 13 +++++++++++-- lmfdb/ecnf/templates/ecnf-curve.html | 20 +++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lmfdb/ecnf/WebEllipticCurve.py b/lmfdb/ecnf/WebEllipticCurve.py index bd8651fcc0..ea5f8c65df 100644 --- a/lmfdb/ecnf/WebEllipticCurve.py +++ b/lmfdb/ecnf/WebEllipticCurve.py @@ -566,15 +566,24 @@ def make_E(self): if self.bsd_status in ["conditional", "unconditional"]: if self.ar == 0: self.reg = web_latex(1) # otherwise we only get 1.00000... + self.NTreg = web_latex(1) # otherwise we only get 1.00000... else: try: - self.reg = web_latex(self.reg) + R = self.reg + self.reg = web_latex(R) + self.NTreg = web_latex(R * K.degree()**self.rank) except AttributeError: self.reg = "not available" + self.NTreg = "not available" elif self.rk != "not available": - self.reg = web_latex(self.reg) if self.rank else web_latex(1) + R = self.reg + self.reg = web_latex(R) if self.rank else web_latex(1) + self.NTreg = web_latex(R * K.degree()**self.rank) if self.rank else web_latex(1) else: self.reg = "not available" + self.NTreg = "not available" + print(f"reg = {self.reg}") + print(f"NTreg = {self.NTreg}") # Generators try: diff --git a/lmfdb/ecnf/templates/ecnf-curve.html b/lmfdb/ecnf/templates/ecnf-curve.html index d5a48fa4d7..6d0a9ab19b 100644 --- a/lmfdb/ecnf/templates/ecnf-curve.html +++ b/lmfdb/ecnf/templates/ecnf-curve.html @@ -296,7 +296,7 @@

{{ KNOWL('ec.bsdconjecture', title='BSD invariants') }}

{% endif %} $\mathrm{Reg}(E/K)$ - {% if ec.rk == 0 %}={% else %}≈{% endif %} + {% if ec.rank == 0 %}={% else %}≈{% endif %} {% if ec.reg=='not available' %} not available @@ -305,6 +305,24 @@

{{ KNOWL('ec.bsdconjecture', title='BSD invariants') }}

{% endif %} + + + {% if ec.bsd_status == "conditional" %} + {{ KNOWL('ec.regulator', title='Néron-Tate Regulator*') }}: + {% else %} + {{ KNOWL('ec.regulator', title='Néron-Tate Regulator') }}: + {% endif %} + + $\mathrm{Reg}_{\mathrm{NT}}(E/K)$ + {% if ec.rank == 0 %}={% else %}≈{% endif %} + + {% if ec.NTreg=='not available' %} + not available + {% else %} + {{ ec.NTreg }} + {% endif %} + + {{ KNOWL('ec.period', title='Global period') }}: From 75f8cbc373696ae29a74c02894e51a0ba332435f Mon Sep 17 00:00:00 2001 From: John Cremona Date: Thu, 5 Dec 2024 12:17:40 -0500 Subject: [PATCH 3/7] ECNF: added BSD formula to curve home page where possible --- lmfdb/ecnf/WebEllipticCurve.py | 73 +++++++++++++++++++++++----- lmfdb/ecnf/templates/ecnf-curve.html | 23 ++++++++- 2 files changed, 81 insertions(+), 15 deletions(-) diff --git a/lmfdb/ecnf/WebEllipticCurve.py b/lmfdb/ecnf/WebEllipticCurve.py index ea5f8c65df..2c6838e3cb 100644 --- a/lmfdb/ecnf/WebEllipticCurve.py +++ b/lmfdb/ecnf/WebEllipticCurve.py @@ -2,7 +2,7 @@ from flask import url_for from urllib.parse import quote from markupsafe import Markup, escape -from sage.all import (Infinity, PolynomialRing, QQ, RDF, ZZ, KodairaSymbol, +from sage.all import (Infinity, PolynomialRing, QQ, RDF, ZZ, RR, KodairaSymbol, implicit_plot, plot, prod, rainbow, sqrt, text, var) from lmfdb import db from lmfdb.utils import (encode_plot, names_and_urls, web_latex, display_knowl, @@ -494,7 +494,8 @@ def make_E(self): self.mw_struct = "unknown" # Torsion - self.ntors = web_latex(self.torsion_order) + BSDntors = self.torsion_order + self.ntors = web_latex(BSDntors) self.tr = len(self.torsion_structure) if self.tr == 0: self.tor_struct_pretty = "$0$" @@ -563,27 +564,28 @@ def make_E(self): self.bsd_status = "missing_gens" # Regulator only in conditional/unconditional cases, or when we know the rank: + BSDReg = None if self.bsd_status in ["conditional", "unconditional"]: if self.ar == 0: - self.reg = web_latex(1) # otherwise we only get 1.00000... - self.NTreg = web_latex(1) # otherwise we only get 1.00000... + BSDReg = 1 + self.reg = self.NTreg = web_latex(BSDReg) # otherwise we only get 1.00000... else: try: R = self.reg + BSDReg = R * K.degree()**self.rank self.reg = web_latex(R) - self.NTreg = web_latex(R * K.degree()**self.rank) + self.NTreg = web_latex(BSDReg) except AttributeError: self.reg = "not available" self.NTreg = "not available" elif self.rk != "not available": R = self.reg + BSDReg = R * K.degree()**self.rank self.reg = web_latex(R) if self.rank else web_latex(1) - self.NTreg = web_latex(R * K.degree()**self.rank) if self.rank else web_latex(1) + self.NTreg = web_latex(BSDReg) if self.rank else web_latex(1) else: self.reg = "not available" self.NTreg = "not available" - print(f"reg = {self.reg}") - print(f"NTreg = {self.NTreg}") # Generators try: @@ -594,17 +596,24 @@ def make_E(self): self.gens = [] self.gens_and_heights = [] - # Global period + # Global period -- see issue #5409 for why we multiply by 2**nc + BSDomega = None try: - self.omega = web_latex(self.omega) + BSDomega = self.omega + nc = self.signature[1] # number of complex places + if nc: + BSDomega *= 2**nc + self.omega = web_latex(BSDomega) except AttributeError: self.omega = "not available" # L-value + BSDLvalue = None try: r = int(self.analytic_rank) # lhs = "L(E,1) = " if r==0 else "L'(E,1) = " if r==1 else "L^{{({})}}(E,1)/{}! = ".format(r,r) - self.Lvalue = web_latex(self.Lvalue) + BSDLvalue = self.Lvalue + self.Lvalue = web_latex(BSDLvalue) except (TypeError, AttributeError): self.Lvalue = "not available" @@ -616,14 +625,52 @@ def make_E(self): self.tamagawa_factors = r'\cdot'.join(cp_fac) else: self.tamagawa_factors = None - self.tamagawa_product = web_latex(prod(tamagawa_numbers,1)) + BSDprodcp = prod(tamagawa_numbers,1) + self.tamagawa_product = web_latex(BSDprodcp) # Analytic Sha + BSDsha = None try: - self.sha = web_latex(self.sha) + " (rounded)" + BSDsha = self.sha + self.sha = web_latex(BSDsha) + " (rounded)" except AttributeError: self.sha = "not available" + # Check analytic Sha value compatible with formula in the knowl (see issue #5409) + + BSDrootdisc = RR(K.discriminant().abs()).sqrt() + if BSDLvalue and BSDsha and BSDReg and BSDsha: + BSDsha_numerator = BSDrootdisc * BSDntors**2 + BSDsha_denominator = BSDReg * BSDomega * BSDprodcp + BSDsha_from_formula = BSDLvalue * BSDsha_numerator / BSDsha_denominator + BSDLvalue_from_formula = BSDsha * BSDsha_denominator / BSDsha_numerator + self.BSDsha = web_latex(BSDsha_from_formula) + self.BSDLvalue = web_latex(BSDLvalue_from_formula) + else: + self.BSDsha = "not available" + self.BSDLvalue = "not available" + + # The BSD formula for display + + dot = '\\cdot' + approx = '\\approx' + frac = '\\frac' + Sha = '\\# Ш(E/K)' + Om = '\\Omega(E/K)' + Reg = '\\mathrm{Reg}_{\\mathrm{NT}}(E/K)' + prodcp = '\\prod_{\\mathfrak{p}} c_{\\mathfrak{p}}' + tors2 = '\\#E(K)_{\\mathrm{tor}}^2' + rootD = '\\left|D_K\\right|' + + lder_name = rf"L^{({r})}(E,1)/{r}!" if r>=2 else "L'(E,1)" if r else "L(E,1)" + lhs_num = rf'{Sha} {dot} {Om} {dot} {Reg} {dot} {prodcp}' + lhs_den = rf'{tors2} {dot} {rootD}' + lhs = rf'{frac}{{ {lhs_num} }} {{ {lhs_den} }}' + rhs_num = rf'{BSDsha} {dot} {BSDomega:0.6f} {dot} {BSDReg:0.6f} {dot} {BSDprodcp}' + rhs_den = rf'{{{BSDntors}^2 {dot} {BSDrootdisc:0.6f}}}' + rhs = rf'{frac}{{ {rhs_num} }} {{ {rhs_den} }}' + self.bsd_formula = rf'{BSDLvalue:0.9f} {approx} {lder_name} = {lhs} {approx} {rhs} {approx} {BSDLvalue_from_formula:0.9f}' + # Local data # The Kodaira symbol is stored as an int in pari encoding. The diff --git a/lmfdb/ecnf/templates/ecnf-curve.html b/lmfdb/ecnf/templates/ecnf-curve.html index 6d0a9ab19b..03442abe92 100644 --- a/lmfdb/ecnf/templates/ecnf-curve.html +++ b/lmfdb/ecnf/templates/ecnf-curve.html @@ -367,8 +367,19 @@

{{ KNOWL('ec.bsdconjecture', title='BSD invariants') }}

Ш${}_{\mathrm{an}}$= {{ ec.sha }} +{# + + + {{ KNOWL('ec.analytic_sha_order', title='Analytic order of Ш (from formula)') }}: + + Ш${}_{\mathrm{an}}$= + {{ ec.BSDsha }} + +#} -

+{# %%%%%%%%%%%%%%%% END OF TABLE %%%%%%%%%%%%%%%%%%% #} +

+ {% if ec.bsd_status == "conditional" %}

* Conditional on {{ KNOWL('ec.bsdconjecture', title='BSD') }}: assuming rank = analytic rank. @@ -382,8 +393,16 @@

{{ KNOWL('ec.bsdconjecture', title='BSD invariants') }}

{% endif %} {% endif %} + -{# %%%%%%%%%%%%%%%% END OF TABLE %%%%%%%%%%%%%%%%%%% #} +

{{ KNOWL('ec.bsdconjecture', title='BSD formula') }}

+
+

+$\displaystyle {{ ec.bsd_formula|safe }}$ +

+
+{{ place_code('bsd_formula') }} +

{{KNOWL('ec.local_data', title='Local data')}} at {{KNOWL('ec.bad_reduction', title='primes of bad reduction')}}

From 96e17b9d87ad07ebcc6ef8de86aed909dfff8833 Mon Sep 17 00:00:00 2001 From: John Cremona Date: Fri, 6 Dec 2024 05:21:23 -0500 Subject: [PATCH 4/7] ECNF: BSD formula tweaks, no display or error when not all data available --- lmfdb/ecnf/WebEllipticCurve.py | 49 +++++++++++++++------------- lmfdb/ecnf/templates/ecnf-curve.html | 6 +++- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/lmfdb/ecnf/WebEllipticCurve.py b/lmfdb/ecnf/WebEllipticCurve.py index 2c6838e3cb..8ce2afac53 100644 --- a/lmfdb/ecnf/WebEllipticCurve.py +++ b/lmfdb/ecnf/WebEllipticCurve.py @@ -639,38 +639,43 @@ def make_E(self): # Check analytic Sha value compatible with formula in the knowl (see issue #5409) BSDrootdisc = RR(K.discriminant().abs()).sqrt() - if BSDLvalue and BSDsha and BSDReg and BSDsha: + if BSDLvalue and BSDsha and BSDReg and (self.rank is not None): BSDsha_numerator = BSDrootdisc * BSDntors**2 BSDsha_denominator = BSDReg * BSDomega * BSDprodcp BSDsha_from_formula = BSDLvalue * BSDsha_numerator / BSDsha_denominator BSDLvalue_from_formula = BSDsha * BSDsha_denominator / BSDsha_numerator self.BSDsha = web_latex(BSDsha_from_formula) self.BSDLvalue = web_latex(BSDLvalue_from_formula) + + # The BSD formula for display + + dot = '\\cdot' + approx = '\\approx' + frac = '\\frac' + Sha = '\\# Ш(E/K)' + Om = '\\Omega(E/K)' + Reg = '\\mathrm{Reg}_{\\mathrm{NT}}(E/K)' + prodcp = '\\prod_{\\mathfrak{p}} c_{\\mathfrak{p}}' + tors2 = '\\#E(K)_{\\mathrm{tor}}^2' + rootD = '\\left|d_K\\right|^{1/2}' + + lder_name = rf"L^{{({r})}}(E/K,1)/{r}!" if r>=2 else "L'(E/K,1)" if r else "L(E/K,1)" + lhs_num = rf'{Sha} {dot} {Om} {dot} {Reg} {dot} {prodcp}' + lhs_den = rf'{tors2} {dot} {rootD}' + lhs = rf'{frac}{{ {lhs_num} }} {{ {lhs_den} }}' + rhs_num = rf'{BSDsha} {dot} {BSDomega:0.6f} {dot} {BSDReg} {dot} {BSDprodcp}' + if r: + rhs_num = rf'{BSDsha} {dot} {BSDomega:0.6f} {dot} {BSDReg:0.6f} {dot} {BSDprodcp}' + rhs_den = rf'{{{BSDntors}^2 {dot} {BSDrootdisc:0.6f}}}' + rhs = rf'{frac}{{ {rhs_num} }} {{ {rhs_den} }}' + self.bsd_formula = rf'{BSDLvalue:0.9f} {approx} {lder_name} = {lhs} {approx} {rhs} {approx} {BSDLvalue_from_formula:0.9f}' + else: self.BSDsha = "not available" self.BSDLvalue = "not available" + self.bsd_formula = None - # The BSD formula for display - - dot = '\\cdot' - approx = '\\approx' - frac = '\\frac' - Sha = '\\# Ш(E/K)' - Om = '\\Omega(E/K)' - Reg = '\\mathrm{Reg}_{\\mathrm{NT}}(E/K)' - prodcp = '\\prod_{\\mathfrak{p}} c_{\\mathfrak{p}}' - tors2 = '\\#E(K)_{\\mathrm{tor}}^2' - rootD = '\\left|D_K\\right|' - - lder_name = rf"L^{({r})}(E,1)/{r}!" if r>=2 else "L'(E,1)" if r else "L(E,1)" - lhs_num = rf'{Sha} {dot} {Om} {dot} {Reg} {dot} {prodcp}' - lhs_den = rf'{tors2} {dot} {rootD}' - lhs = rf'{frac}{{ {lhs_num} }} {{ {lhs_den} }}' - rhs_num = rf'{BSDsha} {dot} {BSDomega:0.6f} {dot} {BSDReg:0.6f} {dot} {BSDprodcp}' - rhs_den = rf'{{{BSDntors}^2 {dot} {BSDrootdisc:0.6f}}}' - rhs = rf'{frac}{{ {rhs_num} }} {{ {rhs_den} }}' - self.bsd_formula = rf'{BSDLvalue:0.9f} {approx} {lder_name} = {lhs} {approx} {rhs} {approx} {BSDLvalue_from_formula:0.9f}' - + print(f"BSD: {self.bsd_formula}") # Local data # The Kodaira symbol is stored as an int in pari encoding. The diff --git a/lmfdb/ecnf/templates/ecnf-curve.html b/lmfdb/ecnf/templates/ecnf-curve.html index 03442abe92..e288520570 100644 --- a/lmfdb/ecnf/templates/ecnf-curve.html +++ b/lmfdb/ecnf/templates/ecnf-curve.html @@ -274,7 +274,7 @@

{{ KNOWL('ec.bsdconjecture', title='BSD invariants') }}

{{ KNOWL('ec.rank', title="Mordell-Weil rank")}}: {% if ec.rk == "not available" %} - $r$? + $r?$   {% if ec.rank_bounds != "not available" %} \({{ ec.rk_lb }} \le r \le {{ec.rk_ub}}\) @@ -395,6 +395,8 @@

{{ KNOWL('ec.bsdconjecture', title='BSD invariants') }}

{% endif %} +{% if ec.bsd_formula %} +

{{ KNOWL('ec.bsdconjecture', title='BSD formula') }}

@@ -405,6 +407,8 @@

{{ KNOWL('ec.bsdconjecture', title='BSD formula') }}

+{% endif %} +

{{KNOWL('ec.local_data', title='Local data')}} at {{KNOWL('ec.bad_reduction', title='primes of bad reduction')}}

{{ place_code('localdata') }} From 2ccd9ec9e2ed315329417e77997edea8a4f08d64 Mon Sep 17 00:00:00 2001 From: John Cremona Date: Fri, 6 Dec 2024 06:38:48 -0500 Subject: [PATCH 5/7] ECNF: adjust global period where necessary --- lmfdb/ecnf/WebEllipticCurve.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/lmfdb/ecnf/WebEllipticCurve.py b/lmfdb/ecnf/WebEllipticCurve.py index 8ce2afac53..47dbb5c17d 100644 --- a/lmfdb/ecnf/WebEllipticCurve.py +++ b/lmfdb/ecnf/WebEllipticCurve.py @@ -596,7 +596,14 @@ def make_E(self): self.gens = [] self.gens_and_heights = [] - # Global period -- see issue #5409 for why we multiply by 2**nc + # Global period -- see issue #5409 for why we multiply by + # 2**nc in most cases. However, data computed after + # 2024-07-09 (including all data for imaginary quadratic + # fields of absolute discriminant > 600 as well as some larger + # conductors for other IQFs) already has the extra factor of + # 2. As a fail-safe until we fix the data in all cases, we + # will test (using the BSD formula) whether to remove the + # factor of 2 added here. BSDomega = None try: BSDomega = self.omega @@ -639,10 +646,23 @@ def make_E(self): # Check analytic Sha value compatible with formula in the knowl (see issue #5409) BSDrootdisc = RR(K.discriminant().abs()).sqrt() + BSDok = True if BSDLvalue and BSDsha and BSDReg and (self.rank is not None): BSDsha_numerator = BSDrootdisc * BSDntors**2 BSDsha_denominator = BSDReg * BSDomega * BSDprodcp BSDsha_from_formula = BSDLvalue * BSDsha_numerator / BSDsha_denominator + BSDok = BSDsha_from_formula.round() == BSDsha + if not BSDok: + # this means that we doubled BSDomega when we should + # not have, so BSDsha_denominator is doubled and + # BSDsha_from formula is halved + print(f"BSD normalization: adjusting Omega for {self.label}: stored Sha = {BSDsha} but formula gives {BSDsha_from_formula} which rounds to {BSDsha_from_formula.round()}") + BSDok = ((BSDsha/BSDsha_from_formula)-2).abs() < 0.01 + if not BSDok: + print(f"BSD normalization issue with {self.label}: stored Sha = {BSDsha} but formula gives {BSDsha_from_formula}") + BSDomega /= 2 + BSDsha_denominator /= 2 + BSDsha_from_formula *= 2 BSDLvalue_from_formula = BSDsha * BSDsha_denominator / BSDsha_numerator self.BSDsha = web_latex(BSDsha_from_formula) self.BSDLvalue = web_latex(BSDLvalue_from_formula) @@ -675,7 +695,9 @@ def make_E(self): self.BSDLvalue = "not available" self.bsd_formula = None - print(f"BSD: {self.bsd_formula}") + if not BSDok: # don't display the formula if it is not correct + self.bsd_formula = None + # Local data # The Kodaira symbol is stored as an int in pari encoding. The From ec8312b89419fbe8c1c73b55d4ca6be71752b6e8 Mon Sep 17 00:00:00 2001 From: John Cremona Date: Mon, 9 Dec 2024 06:03:40 -0500 Subject: [PATCH 6/7] add ? to = in BSD formula --- lmfdb/ecnf/WebEllipticCurve.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lmfdb/ecnf/WebEllipticCurve.py b/lmfdb/ecnf/WebEllipticCurve.py index 47dbb5c17d..7b3ab91cba 100644 --- a/lmfdb/ecnf/WebEllipticCurve.py +++ b/lmfdb/ecnf/WebEllipticCurve.py @@ -671,6 +671,7 @@ def make_E(self): dot = '\\cdot' approx = '\\approx' + eq_query = '\\overset{?}{=}' frac = '\\frac' Sha = '\\# Ш(E/K)' Om = '\\Omega(E/K)' @@ -688,7 +689,7 @@ def make_E(self): rhs_num = rf'{BSDsha} {dot} {BSDomega:0.6f} {dot} {BSDReg:0.6f} {dot} {BSDprodcp}' rhs_den = rf'{{{BSDntors}^2 {dot} {BSDrootdisc:0.6f}}}' rhs = rf'{frac}{{ {rhs_num} }} {{ {rhs_den} }}' - self.bsd_formula = rf'{BSDLvalue:0.9f} {approx} {lder_name} = {lhs} {approx} {rhs} {approx} {BSDLvalue_from_formula:0.9f}' + self.bsd_formula = rf'{BSDLvalue:0.9f} {approx} {lder_name} {eq_query} {lhs} {approx} {rhs} {approx} {BSDLvalue_from_formula:0.9f}' else: self.BSDsha = "not available" From 81ac07e1d253857547e5caf25011996b19e5a4eb Mon Sep 17 00:00:00 2001 From: John Cremona Date: Mon, 9 Dec 2024 09:34:57 -0500 Subject: [PATCH 7/7] ECNF: fixing the global period adjustment fix --- lmfdb/ecnf/WebEllipticCurve.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lmfdb/ecnf/WebEllipticCurve.py b/lmfdb/ecnf/WebEllipticCurve.py index 7b3ab91cba..22b64cb83b 100644 --- a/lmfdb/ecnf/WebEllipticCurve.py +++ b/lmfdb/ecnf/WebEllipticCurve.py @@ -651,18 +651,24 @@ def make_E(self): BSDsha_numerator = BSDrootdisc * BSDntors**2 BSDsha_denominator = BSDReg * BSDomega * BSDprodcp BSDsha_from_formula = BSDLvalue * BSDsha_numerator / BSDsha_denominator - BSDok = BSDsha_from_formula.round() == BSDsha + BSDsha_from_formula_rounded = BSDsha_from_formula.round() + BSDok = (BSDsha_from_formula_rounded == BSDsha) and ((BSDsha_from_formula_rounded -BSDsha_from_formula).abs() < 0.001) + #print(f"{BSDsha_from_formula=}") + #print(f"{BSDsha_from_formula_rounded=}") + #print(f"{BSDsha=}") + #print(f"{BSDok=}") if not BSDok: # this means that we doubled BSDomega when we should # not have, so BSDsha_denominator is doubled and # BSDsha_from formula is halved - print(f"BSD normalization: adjusting Omega for {self.label}: stored Sha = {BSDsha} but formula gives {BSDsha_from_formula} which rounds to {BSDsha_from_formula.round()}") + print(f"BSD normalization: adjusting Omega for {self.label}: stored Sha = {BSDsha} but formula gives {BSDsha_from_formula}") BSDok = ((BSDsha/BSDsha_from_formula)-2).abs() < 0.01 if not BSDok: print(f"BSD normalization issue with {self.label}: stored Sha = {BSDsha} but formula gives {BSDsha_from_formula}") BSDomega /= 2 BSDsha_denominator /= 2 BSDsha_from_formula *= 2 + BSDsha_from_formula_rounded = BSDsha_from_formula.round() BSDLvalue_from_formula = BSDsha * BSDsha_denominator / BSDsha_numerator self.BSDsha = web_latex(BSDsha_from_formula) self.BSDLvalue = web_latex(BSDLvalue_from_formula)