import math

def get_b_0(k, epsilon, ell, u):
    #    plot([(1+(1+u)*epsilon*x)/((1-ell)*x+(1+u)*epsilon*x+1), 0.25], (x, 0, 1))
    return ((1+(1+u)*epsilon*k)/((1-ell)*k+(1+u)*epsilon*k+1))

def get_delta_e(phi_e, gamma, K, n, epsilon):
    return math.sqrt(abs(math.log(phi_e)*32*epsilon/(gamma*K**2*math.log(n))))

def get_phi_e(delta_e, gamma, K, n, epsilon):
    return math.exp(-1*gamma*((delta_e*K)**2)*math.log(n)/(32*epsilon))

def get_delta_age_ell(phi_age_ell, c, K, n):
    C=c*math.log(n)
    return math.sqrt((2*C*K/n) - (2*math.log(phi_age_ell)/C))

def get_phi_age_ell(delta_age_ell, C, K, n):
    return math.exp(((C**2)*K/n) - ((delta_age_ell**2)*C/2))

def get_delta_age_u(u, c, K, n):
    C=c*math.log(n)
    #delta_age_u**2/(1+delta_age_u)=A
    A = ((2*C*K/n) - (2*math.log(u)/C))
    #quadratic of the form x^2 - A*x - A = 0
    #only one positive root as A is always positive.
    root = 0.5 * (A + math.sqrt(A**2+4*A))
    return root

def get_phi_age_u(delta_age_u, C, K, n):
    return math.exp(((C**2)*K/n) - ((delta_age_u**2)*C/(2*(1+delta_age_u))))

def get_delta_n(gamma, epsilon, K, n):
    return gamma*K*(math.log(n))**3/(epsilon*n)

def get_delta_ell(delta_e, delta_age_ell, delta_n):
    return delta_e + delta_age_ell - (delta_e * delta_age_ell) - ((1 - delta_e) * delta_n)

def get_delta_u(delta_e, delta_age_u, delta_n):
    return delta_e + delta_age_u + delta_e * delta_age_u + ((1 + delta_e) * delta_n)

def get_p_i(phi_e, epsilon, phi_age_ell, phi_age_u, C):
    phi_e_honest = phi_e**C
    print(phi_e_honest)
    phi_e_byz = (phi_e**(epsilon**2))**C
    print(phi_e_byz)
    p1 = phi_e_honest + 2*phi_age_ell + phi_e_byz
    p2 = phi_e_honest + 2*phi_age_u + phi_e_byz
    p3 = phi_e_honest + phi_age_ell
    p4 = phi_e_byz + phi_age_u
    return [p1, p2, p3, p4]

n=10**8
K=20
c=40
C=c*math.log(n)
gamma=1
epsilon=0.2

delta_e = 0.1
delta_age_ell = 0.12
delta_age_u = 0.11

#phi_age_ell_1=0.02
#phi_age_u_1=0.02
#phi_e=5*(10**-30)

#delta_age_u_1 = get_delta_age_u(phi_age_u_1, c, K, n)
#print("delta_age_u is: ", delta_age_u_1)

#delta_age_ell_1 = get_delta_age_ell(phi_age_ell_1, c, K, n)
#print("delta_age_l is: ", delta_age_ell_1)

delta_e_2 = get_delta_e(5*(10**-30), gamma, K, n, epsilon)
print("delta_e_2 is: ", delta_e_2)

delta_n = get_delta_n(gamma, epsilon, K, n)
print("delta_n is: ", delta_n)

delta_ell = get_delta_ell(delta_e, delta_age_ell, delta_n)
print("delta_ell is: ", delta_ell)

delta_u = get_delta_u(delta_e, delta_age_ell, delta_n)
print("delta_u is: ", delta_u)

b_0 = get_b_0(K, epsilon, delta_ell, delta_u)
print("b_0 is: ", b_0)

phi_age_ell = get_phi_age_ell(delta_age_ell, C, K, n)
print("phi_age_ell is: ", phi_age_ell)

phi_age_u = get_phi_age_u(delta_age_u, C, K, n)
print("phi_age_u is: ", phi_age_u)

phi_e = get_phi_e(delta_e, gamma, K, n, epsilon)
print("phi_e is: ", phi_e)
print("phi_e^(epsilon^2) is: ", phi_e**(epsilon**2))

[p1, p2, p3, p4] = get_p_i(phi_e, epsilon, phi_age_ell, phi_age_u, C)
print(p1, p2, p3, p4)