"""Algebra/numerical consistency checks, not a one-loop determinant calculation."""
from fractions import Fraction as F
from math import pi, log, exp
from pathlib import Path
import json

def c_local(r2, a, c, b):
    # L=1; David et al., eq. (3.11).
    return 4*((c-a)+(2*c-3*a+6*b)*r2+(c-6*b)*r2*r2)/(1+3*r2)

for a in (F(-11,24), F(53,45), F(1,360)):
    for c in (F(0), F(137,60), F(1,120)):
        for b in (F(-13,36), F(0), F(7,9)):
            assert c_local(F(1),a,c,b)==4*(c-a)
assert c_local(F(1),F(-11,24),F(0),F(-13,36))==F(11,6)

def bisect(fn, lo, hi):
    assert fn(lo)*fn(hi)<0
    for _ in range(80):
        mid=(lo+hi)/2
        if fn(lo)*fn(mid)<=0:
            hi=mid
        else:
            lo=mid
    return (lo+hi)/2

out={"local_coefficient_at_HP":"11/6","coefficient_checks":27,"shift_checks":[]}
# L=1. The AdS4 choice G=1/N^2 here is only a synthetic small parameter.
for dim in (4,5):
    for correction in (-0.2,0.2):
        previous=None
        for n in (16,32,64,128):
            if dim==4:
                g=1/n**2
                temp=lambda r:(1+3*r*r)/(4*pi*r)
                free=lambda r:r*(1-r*r)/(4*g)
                entropy=pi/g
                fprime=-1/(2*g)
                tprime=1/(2*pi)
            else:
                g=pi/(2*n**2)
                temp=lambda r:(2*r*r+1)/(2*pi*r)
                free=lambda r:pi*r*r*(1-r*r)/(8*g)
                entropy=pi*pi/(2*g)
                fprime=-pi/(4*g)
                tprime=1/(2*pi)
            assert abs(fprime/tprime/(-entropy)-1)<1e-14
            rstar=bisect(lambda r:free(r)+correction,.95,1.05)
            dt=temp(rstar)-temp(1)
            predicted=correction/entropy
            err=abs(dt/predicted-1)
            assert dt*correction>0
            assert err<0.02, (dim,n,correction,err)
            if previous is not None:
                assert err<previous*.3
            previous=err
            out["shift_checks"].append(
                dict(dim=dim,n=n,synthetic_F1=correction,
                     delta_T=dt,linear_delta_T=predicted,relative_error=err))

# Logistic two-saddle width, within the linearized action difference.
for ds in (10,100,1000):
    half=log(9)/ds
    assert abs(1/(1+exp(ds*half))-.1)<1e-14
    assert abs(1/(1+exp(-ds*half))-.9)<1e-14

# A normalized Tc/sqrt(sigma) correction need not be a Tc correction.
T0=.5949
s1=-2*.458/T0
ratio_coeff=0-T0*s1/2
assert abs(ratio_coeff-.458)<1e-14
out["normalization_counterexample"]={
    "synthetic_T0":T0,"synthetic_T1":0,"synthetic_sigma0":1,
    "synthetic_sigma1":s1,"ratio_1_over_N2_coefficient":ratio_coeff}
out["status"]="All checks passed. Synthetic checks; no experimental fit or determinant."
Path(__file__).with_suffix(".json").write_text(json.dumps(out,indent=2)+"\n")
print(json.dumps({"status":out["status"],"local_coefficient":"11/6",
                  "shift_checks":len(out["shift_checks"]),
                  "max_relative_linearization_error":
                  max(r["relative_error"] for r in out["shift_checks"])},indent=2))
