peel.py
3.9 kB · python · 129 lines
1import json2import os3import sys4from time import perf_counter56from mpmath import mp, mpc, log, sqrt78mp.dps = 409P = 1410SHIFT = 6011CUT = 3012T = [[1, 1], [1, 0]]13GAM = [[0, 0], [1, 0]]14LN2 = log(2)1516low, mid = [], [[], []]17for n in range(1, 1 << P):18 if n & (n << 1):19 continue20 if n.bit_length() < P:21 low.append(n)22 else:23 mid[n & 1].append(n)242526def mv(m, v):27 return [sum(mpc(m[i][j]) * v[j] for j in range(2)) for i in range(2)]282930def solve(x, rhs):31 a = [[1 - x * T[0][0], -x * T[0][1]], [-x * T[1][0], 1 - x * T[1][1]]]32 det = a[0][0] * a[1][1] - a[0][1] * a[1][0]33 return [(a[1][1] * rhs[0] - a[0][1] * rhs[1]) / det,34 (a[0][0] * rhs[1] - a[1][0] * rhs[0]) / det]353637def epoly(w):38 return [sum(mpc(n) ** (-w) for n in mid[u]) for u in range(2)]394041def ladder(s):42 levels = int(mp.ceil(SHIFT - s.real))43 rows = levels + CUT + 244 g = [[mpc(0), mpc(0)] for _ in range(rows)]45 num = None46 for j in range(levels - 1, -1, -1):47 w = s + j48 acc = epoly(w)49 c = mpc(1)50 for l in range(1, CUT + 1):51 c = c * (-w - (l - 1)) / l52 weight = c * mpc(2) ** (-w - l)53 lift = mv(GAM, g[j + l])54 acc = [acc[i] + weight * lift[i] for i in range(2)]55 if j == 0:56 num = acc57 g[j] = solve(mpc(2) ** (-w), acc)58 return g[0], num596061def zeta(s):62 g, _ = ladder(s)63 return sum(mpc(n) ** (-s) for n in low) + g[0] + g[1]646566def cofactor(s):67 _, num = ladder(s)68 x = mpc(2) ** (-s)69 det = 1 - x - x * x70 adj = [[mpc(1), x], [x, 1 - x]]71 return det * sum(mpc(n) ** (-s) for n in low) + sum(mv(adj, num))727374CONTROL = os.path.join(os.path.dirname(os.path.abspath(__file__)), "control.json")757677def control():78 start = perf_counter()79 phi = (1 + sqrt(5)) / 280 alpha = log(phi) / LN281 period = 2 * mp.pi / LN282 half = mp.pi / LN283 rows = []84 for kind, s in [("zeta", mpc(3)), ("zeta", mpc("0.8")), ("Z", mpc(3)), ("Z", mpc(2)),85 ("Z", mpc("0.8")), ("Z", mpc("-0.95", 20)), ("Z", mpc(0, 30)),86 ("Z", mpc("-0.693919320380", "9.492981163426")),87 ("Z", mpc("-0.737611737911", "14.343440171295")),88 ("Z", mpc("-0.708500086380", "27.443172842651")),89 ("Z", mpc("0.665353220372", "18.164471712166")),90 ("Z", mpc("-0.315485550754", "23.209873760385")),91 ("residue", mpc(alpha, period)), ("residue", mpc(-alpha, half * 5))]:92 v = zeta(s) if kind == "zeta" else cofactor(s) if kind == "Z" else residue(s)93 rows.append({"kind": kind, "re": mp.nstr(s.real, 25), "im": mp.nstr(s.imag, 25),94 "value": [mp.nstr(v.real, 25), mp.nstr(v.imag, 25)]})95 json.dump({"source": "lab/py/memory-zeta peel.py control", "dps": mp.dps, "peel": P,96 "shift": SHIFT, "cut": CUT, "rows": rows}, open(CONTROL, "w"), indent=1)97 print("control.json", len(rows), "rows,", round(perf_counter() - start, 2), "s")9899100def residue(w0):101 _, num = ladder(w0)102 x = mpc(2) ** (-w0)103 adj = [[mpc(1), x], [x, 1 - x]]104 top = sum(mv(adj, num))105 den = -x * LN2 * (-1 - 2 * x)106 return top / den107108109def main():110 start = perf_counter()111 phi = (1 + sqrt(5)) / 2112 alpha = log(phi) / LN2113 period = 2 * mp.pi / LN2114 half = mp.pi / LN2115 print("code 7, k = 2, dps", mp.dps, "peel", P, "shift", SHIFT, "cut", CUT)116 print("alpha", mp.nstr(alpha, 25))117 for s in [mpc(3), mpc(2), mpc("0.8"), mpc("1.2", 9)]:118 print("zeta", s, mp.nstr(zeta(s), 25))119 for j in range(3):120 print("comb one j", j, mp.nstr(residue(mpc(alpha, period * j)), 25))121 for j in range(3):122 print("comb two j", j, mp.nstr(residue(mpc(-alpha, half * (2 * j + 1))), 25))123 print("runtime", round(perf_counter() - start, 2), "s")124125126if len(sys.argv) > 1 and sys.argv[1] == "control":127 control()128else:129 main()