'Computes the confidence interval for the parameter given by param_num
using Empirical Likelihood
Parameters
param_num : float
The parameter for which the confidence interval is desired
sig : float
The significance level.  Default is .05
upper_bound : float
The maximum value the upper limit can be.  Default is the
99.9% confidence value under OLS assumptions.
lower_bound : float
The minimum value the lower limit can be.  Default is the 99.9%
confidence value under OLS assumptions.
method : string
Can either be \'nm\' for Nelder-Mead or \'powell\' for Powell.  The
optimization method that optimizes over nuisance parameters.
Default is \'nm\'
Returns
ci : tuple
The confidence interval
See Also
el_test
Notes
This function uses brentq to find the value of beta where
test_beta([beta], param_num)[1] is equal to the critical
value.
The function returns the results of each iteration of brentq at
each value of beta.
The current function value of the last printed optimization
should be the critical value at the desired significance level.
For alpha=.05, the value is 3.841459.
To ensure optimization terminated successfully, it is suggested to
do el_test([lower_limit], [param_num])
If the optimization does not terminate successfully, consider switching
optimization algorithms.
If optimization is still not successful, try changing the values of
start_int_params.  If the current function value repeatedly jumps
from a number between 0 and the critical value and a very large number
(>50), the starting parameters of the interior minimization need
to be changed.'

def conf_int_el(self, param_num, sig=0.05, upper_bound=None, lower_bound=None, method='nm', stochastic_exog=1):

    r0 = stats.chi2.ppf((1 - sig), 1)
    if (upper_bound is None):
        upper_bound = self.conf_int(0.01)[param_num][1]
    if (lower_bound is None):
        lower_bound = self.conf_int(0.01)[param_num][0]
    f = (lambda b0: (self.el_test(np.array([b0]), np.array([param_num]), method=method, stochastic_exog=stochastic_exog)[0] - r0))
    lowerl = optimize.brenth(f, lower_bound, self.params[param_num])
    upperl = optimize.brenth(f, self.params[param_num], upper_bound)
    return (lowerl, upperl)
