zerr.py
2.5 kB · python · 74 lines
1import mpmath as mp2import sympy as sp34DPS = 505SAMPLES = 5067def symbolic_residuals():8 a, u = sp.symbols("a u", positive=True)9 r = 1 - a**2 + a**2 * u**210 cube = (-a * u + sp.sqrt(r)) ** 311 t1 = -(a**3) * u**312 t2 = 3 * a**2 * u**2 * sp.sqrt(r)13 t3 = -3 * a * u * r14 t4 = r ** sp.Rational(3, 2)15 even = sp.sqrt(r) * (1 - a**2 + 4 * a**2 * u**2)16 prim = u * r ** sp.Rational(3, 2)17 res = {18 "cube minus its four terms": sp.simplify(sp.expand(cube - (t1 + t2 + t3 + t4))),19 "even part minus sqrt(R)(1-a^2+4a^2u^2)": sp.simplify(even - (t2 + t4)),20 "d/du[u R^(3/2)] minus even part": sp.simplify(sp.diff(prim, u) - even),21 }22 boundary = sp.simplify(prim.subs(u, 1) - prim.subs(u, -1))23 closed = sp.simplify(sp.integrate(cube, (u, -1, 1)))24 return res, boundary, closed2526def inner_integral(a):27 return mp.quad(lambda u: (-a * u + mp.sqrt(1 - a**2 + a**2 * u**2)) ** 3, [-1, 0, 1])2829def chord(a, phi):30 return -a * mp.cos(phi) + mp.sqrt(1 - a**2 * mp.sin(phi) ** 2)3132def i_diam_direct():33 half = mp.pi / 234 return mp.quad(35 lambda a, phi: chord(a, phi) ** 3 * mp.sin(phi),36 [-1, 0, 1],37 [0, half, mp.pi],38 )3940def main():41 mp.mp.dps = DPS42 print("ZERR DECOMPOSITION")43 res, boundary, closed = symbolic_residuals()44 for name, value in res.items():45 print(f" residual {name} = {value}")46 print(f" boundary [u R^(3/2)] from -1 to 1 = {boundary}")47 print(f" closed form of the inner integral = {closed}")4849 worst = mp.mpf(0)50 for i in range(SAMPLES):51 a = mp.mpf(i + 1) / (SAMPLES + 1)52 worst = max(worst, abs(inner_integral(a) - 2))53 print(f" inner integral at {SAMPLES} values of a, working digits {DPS}")54 print(f" max deviation from 2 = {mp.nstr(worst, 5)}")5556 i_diam = mp.quad(inner_integral, [-1, 0, 1])57 print(f" I_diam by the constant inner integral = {mp.nstr(i_diam, 30)}")5859 mp.mp.dps = 2560 direct = i_diam_direct()61 print(f" I_diam by direct chord-cube quadrature = {mp.nstr(direct, 20)}")6263 mp.mp.dps = DPS64 area = mp.pi / 265 prob = mp.mpf(4) / (3 * area**2)66 exact = 16 / (3 * mp.pi**2)67 print(f" Area(H) = pi/2, Area(H)^2 = pi^2/4 = {mp.nstr(area**2, 20)}")68 print(f" P(chord crosses the diameter) = I_diam/(3 Area(H)^2) = {mp.nstr(prob, 20)}")69 print(f" 16/(3 Pi^2) = {mp.nstr(exact, 20)}")70 print(f" 16/(3 Pi^2) to 16 places = {mp.nstr(exact, 16)}")71 print(f" 1 - 16/(3 Pi^2) to 16 places = {mp.nstr(1 - exact, 16)}")72 print(f" |P - 16/(3 Pi^2)| = {mp.nstr(abs(prob - exact), 5)}")7374main()