# -*- coding: utf-8 -*-
"""
Created on Sat Aug 10 01:31:46 2024

@author: shara
"""
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import minimize_scalar
import scienceplots
plt.style.use(['science', 'grid'])

plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Times New Roman']
#plt.rcParams['axes.facecolor'] = '#f7f7f7'

def binary_entropy(p):
    if p == 0:
        return 0
    return -p * np.log2(p) - (1 - p) * np.log2(1 - p)

def inverse_H(val):
        # Define a function that returns the absolute difference between H(p) and the desired value
    func = lambda p: abs(binary_entropy(p) - val)
    # Use minimize_scalar to find the value of p that minimizes the absolute difference
    result = minimize_scalar(func, bounds=(1e-15, 1-1e-15), method='bounded')
    val = result.x
    if val > 0.5:
        val = 1 - val
    return val

def ub_for_plot( ):
    ub_func = lambda x: binary_entropy( 0.5 - inverse_H( 1 - x ) )
    X = np.linspace(0, 1, 10000)
    Y = [ ub_func(x) for x in X]
    return X, Y

X, Y = ub_for_plot()
#plt.figure(facecolor='#f7f7f7')
plt.plot( X, Y, label = '$h_B( 1/2 - h_B^{-1}( 1 - I(X;Y) ) )$', color = 'blue' )
plt.plot( X, X, label = 'Rate Lower Bound', color = '#2ca25f' )
plt.xlabel( '$I(X;Y)$', size = 10 )
plt.ylabel( 'Rate', size = 10 )
plt.tick_params(axis='both', which='major', color='0', labelsize=7)
plt.tick_params(axis='both', which='minor', color='0.3')
plt.grid(b=True, which='major', color='0.65', linestyle='-', linewidth = 0.2)
plt.savefig( 'Figure2.pdf' )