Wiki
Research notes on every problem, and a library of the papers behind them. Built from the open erdos repository.
erdos_699_bft_asymmetric.py
py
"""Explicit asymmetric cofactor bounds from BFT Section 7.
This retains the two seed prime-power logarithms separately and avoids
the final symmetric maximum in BFT Theorem 2.4. See the accompanying
../methods/details/asymmetric_cofactors.md for the threshold proof.
"""
from __future__ import annotations
from fractions import Fraction
import json
from pathlib import Path
from mpmath import iv
from erdos_699_bft_explicit_thresholds import explicit_bound, interval_max
from erdos_699_bft_pair_extension import rational
from erdos_699_prime_pair_savings import EXPLICIT_EDGES
from erdos_699_weighted_ramps import capacities, exact_power_of_ten, off_maximum_constant
iv.dps = 80
def asymmetric_bound(p_power, q_power, a, b, c, d, log_l1, m0,
gap, target_p, target_q):
"""Certify u>x**target_p OR v>x**target_q for bounded-gap inputs.
The p and q labels follow the oriented seed powers, not sorted primes.
x is the minimum of the two inputs. log_l1 and m0 must certify BFT
(2.8). The returned integer B guarantees the assertion for x>=10**B.
"""
target_p, target_q = Fraction(target_p), Fraction(target_q)
assert 0 < target_p < 1 and 0 < target_q < 1
# Kappas do not depend on epsilon; this call reuses their exact integrals.
data = explicit_bound(p_power, q_power, a, b, c, d,
log_l1, m0, gap, Fraction(1, 100))
log_p, log_q = iv.log(p_power), iv.log(q_power)
s = rational(Fraction(c, d))
k = iv.log(max(p_power, q_power)) + data["log_omega4"] / s
l = interval_max([
log_p / (1 - rational(target_p)),
log_q / (1 - rational(target_q)),
])
assert l < k
m = interval_max([
iv.mpf(m0), iv.log(data["kappa1"]) / (d*data["log_omega3"]),
])
terms = [
iv.log(gap),
c*l*(m + 1),
l*(c*k + iv.log(2) - iv.log(data["kappa2"])) / (k - l),
]
threshold = interval_max(terms)
cap = int(float((threshold / iv.log(10)).b)) + 1
while not threshold < cap*iv.log(10):
cap += 1
return {
"seed": [p_power, q_power, a, b, c, d],
"gap": gap,
"m0": m0,
"targets": [str(target_p), str(target_q)],
"limiting_exponents": [iv.nstr(1 - log_p/k, 24),
iv.nstr(1 - log_q/k, 24)],
"log_omega3": iv.nstr(data["log_omega3"], 24),
"log_omega4": iv.nstr(data["log_omega4"], 24),
"kappa1": iv.nstr(data["kappa1"], 24),
"kappa2": iv.nstr(data["kappa2"], 24),
"K": iv.nstr(k, 24), "L": iv.nstr(l, 24),
"M": iv.nstr(m, 24),
"log_threshold_terms": [iv.nstr(term, 24) for term in terms],
"log_threshold": iv.nstr(threshold, 24),
"threshold_power_of_ten": cap,
}
def main():
choices = [
((5, 7), (25, 49, 2, 1, 8, 5), "1.5407", 53, ".29", ".20"),
((5, 7), (25, 49, 2, 1, 8, 5), "1.5407", 53, ".35", ".22"),
((5, 7), (25, 49, 2, 1, 8, 5), "1.5407", 53, ".35", ".20"),
((2, 7), (8, 7, 1, 1, 3, 2), "1.5395", 138, ".24", ".29"),
]
rows = []
for pair, seed, l1, m0, target_p, target_q in choices:
result = asymmetric_bound(
*seed, iv.log(rational(l1)), m0, 100, target_p, target_q,
)
rows.append({"pair": pair, "L1": l1, **result})
primes = (2, 3, 5, 7)
positions = {p: k for k, p in enumerate(primes)}
edges = [
(positions[p], positions[q], Fraction(w, 10000), Fraction(w, 10000))
for p, q, w in EXPLICIT_EDGES if p in positions and q in positions
] + [(positions[5], positions[7], Fraction(29, 100), Fraction(1, 5))]
gains = []
configurations = 0
for choices in range(1 << len(edges)):
values = [Fraction(0)]*4
for bit, (p, q, target_p, target_q) in enumerate(edges):
vertex, value = ((q, target_q) if choices & (1 << bit)
else (p, target_p))
values[vertex] = max(values[vertex], value)
scaled = tuple(int(10000*value) for value in values)
for caps in capacities(scaled):
configurations += 1
gains.append(43 - sum(Fraction((14 - r)*value, 10000)
for r, value in enumerate(caps)))
gain = min(gains)
assert gain == Fraction(13, 125)
off_maximum, factors = off_maximum_constant(11, [14 - t for t in range(11)], primes)
constant = Fraction(1000*11**14*off_maximum, 999*2**56)
cap = exact_power_of_ten(constant, gain, 945000)
assert cap == 711
result = {
"source": "BFT Section 7 before taking the symmetric maximum",
"scope": "Numerical analytic parameters; no binomial rows enumerated.",
"pairs": rows,
"index_11": {
"orientations_checked": 1 << len(edges),
"capacity_configurations_checked": configurations,
"minimum_weighted_gain": str(gain),
"off_maximum_factors": factors,
"elementary_threshold": 945000,
"comparison_constant": str(constant),
"algebraic_cap_power_of_ten": cap,
"full_row_cap_power_of_ten": max(cap, rows[0]["threshold_power_of_ten"] + 1),
},
}
output = Path(__file__).with_suffix(".json")
output.write_text(json.dumps(result, indent=2) + "\n")
print(json.dumps({
"certificates": [{"pair": row["pair"], "targets": row["targets"],
"threshold_power_of_ten": row["threshold_power_of_ten"]}
for row in rows],
"index_11": result["index_11"],
"output": str(output),
}, indent=2))
if __name__ == "__main__":
main()
Graph