<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Conditional Entropy
Step1:  Problem 1b
Create a function, phase_plot, that takes x, y, and $P$ as inputs to create a phase-folded light curve (i.e., plot the data at their respective phase values given the period $P$).
Include an optional argument, y_unc, to include uncertainties on the y values, when available.
Step2:  Problem 1c
Generate a signal with $A = 2$, $p = \pi$, and Gaussian noise with variance = 0.01 over a regular grid between 0 and 10. Plot the phase-folded results (and make sure the results behave as you would expect).
Hint - your simulated signal should have at least 100 data points.
Step3:  Note a couple changes from the previous helper function –– we have added a grid to the plot (this will be useful for visualizing the entropy), and we have also normalized the brightness measurements from 0 to 1. 
Problem 2) The Shannon entropy
As noted above, to calculate the Shannon entropy we need to sum the data over partitions in the normalized $(\phi, m)$ plane.
This is straightforward using histogram2d from numpy. 
Problem 2a 
Write a function shannon_entropy to calculate the Shannon entropy, $H_0$, for a timeseries, $m(t_i)$, at a given period, p.
Hint - use histogram2d and a 10 x 10 grid (as plotted above).
Step4:  Problem 2b
What is the Shannon entropy for the simulated signal at periods = 1, $\pi$-0.05, and $\pi$?
Do these results make sense given your understanding of the Shannon entropy?
Step5:  We know the correct period of the simulated data is $\pi$, so it makes sense that this period minimizes the Shannon entropy. 
Problem 2c
Write a function, se_periodogram to calculate the Shannon entropy for observations $m$, $t$ over a frequency grid f_grid.
Step6:  Problem 2d
Plot the Shannon entropy periodogram, and return the best-fit period from the periodogram.
Hint - recall what we learned about frequency grids earlier today.
Step7:  Problem 3) The Conditional Entropy
The CE is very similar to the Shannon entropy, though we need to condition the calculation on the occupation probability of the partitions in phase.
Problem 3a 
Write a function conditional_entropy to calculate the CE, $H_c$, for a timeseries, $m(t_i)$, at a given period, p.
Hint - if you use histogram2d be sure to sum along the correct axes
Hint 2 - recall from session 8 that we want to avoid for loops, try to vectorize your calculation.
Step8:  Problem 3b
What is the conditional entropy for the simulated signal at periods = 1, $\pi$-0.05, and $\pi$?
Do these results make sense given your understanding of CE?
Step9:  Problem 3c
Write a function, ce_periodogram, to calculate the conditional entropy for observations $m$, $t$ over a frequency grid f_grid.
Step10:  Problem 3d
Plot the conditional entropy periodogram, and return the best-fit period from the periodogram.
Step11:  The Shannon entropy and CE return nearly identical results for a simulated sinusoidal signal. Now we will examine how each performs with actual astronomical observations. 
Problem 4) SE vs. CE for real observations
Problem 4a
Load the data from our favorite eclipsing binary from this morning's LS exercise. Plot the light curve. 
Hint - if you haven't already, download the example light curve.
Step12:  Problem 4b 
Using the Shannon entropy, determine the best period for this light curve.
Hint - recall this morning's discussion about the optimal grid for a period search
Step13:  Problem 4c
Plot the Shannon entropy periodogram.
Step14:  Problem 4d
Plot the light curve phase-folded on the best-fit period, as measured by the Shannon entropy periodogram.
Does this look reasonable? Why or why not?
Hint - it may be helpful to zoom in on the periodogram.
Step15:  Problem 4e 
Using the conditional entropy, determine the best period for this light curve.
Step16:  Problem 4f
Plot the CE periodogram.
Step17:  Problem 4g
Plot the light curve phase-folded on the best-fit period, as measured by the CE periodogram.
Does this look reasonable? If not - can you make it look better?
<ASSISTANT_TASK:>
Python Code:
def gen_periodic_data(x, period=1, amplitude=1, phase=0, noise=0):
    '''Generate periodic data given the function inputs
    
    y = A*cos(x/p - phase) + noise
    
    Parameters
    ----------
    x : array-like
        input values to evaluate the array
    
    period : float (default=1)
        period of the periodic signal
    
    amplitude : float (default=1)
        amplitude of the periodic signal
    
    phase : float (default=0)
        phase offset of the periodic signal
    
    noise : float (default=0)
        variance of the noise term added to the periodic signal
    
    Returns
    -------
    y : array-like
        Periodic signal evaluated at all points x
    '''
    
    y = amplitude*np.sin(2*np.pi*x/(period) - phase) + np.random.normal(0, np.sqrt(noise), size=len(x))
    return y
Explanation: Conditional Entropy: Can Information Theory Beat the L-S Periodogram?
Version 0.2
By AA Miller
23 Sep 2021
Lecture IV focused on alternative methods to Lomb-Scargle when searching for periodic signals in astronomical time series. In this notebook you will develop the software necessary to search for periodicity via Conditional Entropy (my personal favorite method). 
Conditional Entropy
Conditional Entropy (CE; Graham et al. 2013), and other entropy based methods, aim to minimize the entropy in binned (normalized magnitude, phase) space. CE, in particular, is good at supressing signal due to the window function.
When tested on real observations, CE outperforms most of the alternatives (e.g., LS, PDM, etc).
<img style="display: block; margin-left: auto; margin-right: auto" src="./images/CE.png" align="middle">
<div align="right"> <font size="-3">(credit: Graham et al. 2013) </font></div>
Conditional Entropy
The focus of today's exercise is conditional entropy (CE), which uses information theory and thus, in principle, works better in the presence of noise and outliers. Furthermore, CE does not make any assumptions about the underlying shape of the signal, which is useful when looking for non-sinusoidal patterns (such as transiting planets or eclipsing binaries).
For full details on the CE algorithm, see Graham et al. (2013).
Briefly, CE is based on the using the Shannon entropy (Cincotta et al. 1995), which is determined as follows:
Normalize the time series data $m(t_i)$ to occupy a uniform square over phase, $\phi$, and magnitude, $m$, at a given trial period, $p$. 
Calculate the Shannon entropy, $H_0$, over the $k$ partitions in $(\phi, m)$:
$$H_0 = - \sum_{i=1}^{k} \mu_i \ln{(\mu_i)}\;\; \forall \mu_i \ne 0,$$
 where $\mu_i$ is the occupation probability for the $i^{th}$ partition, which is just the number of data points in that partition divided by the total number of points in the data set.
Iterate over multiple periods, and identify the period that minimizes the entropy (recall that entropy measures a lack of information)
As discussed in Graham et al. (2013), minimizing the Shannon entropy can be influenced by the window function, so they introduce the conditional entropy, $H_c(m|\phi)$, to help mitigate these effects. The CE can be calculated as:
$$H_c =  \sum_{i,j} p(m_i, \phi_j) \ln \left( \frac{p(\phi_j)}{p(m_i, \phi_j)} \right), $$
where $p(m_i, \phi_j)$ is the occupation probability for the $i^{th}$ partition in normalized magnitude and the $j^{th}$
partition in phase and $p(\phi_j)$ is the occupation probability of the $j^{th}$ phase partition
In this problem we will first calculate the Shannon entropy, then the CE to find the best-fit period of the eclipsing binary from the LS lecture.
Problem 1) Helper Functions
Problem 1a
Create a function, gen_periodic_data, that creates simulated data (including noise) over a grid of user supplied positions:
$$ y = A\,cos\left(\frac{2{\pi}x}{P} - \phi\right) + \sigma_y$$
where $A, P, \phi$ are inputs to the function. gen_periodic_data should include Gaussian noise, $\sigma_y$, for each output $y_i$.
End of explanation
def phase_plot(x, y, period, y_unc = 0.0):
    '''Create phase-folded plot of input data x, y
    
    Parameters
    ----------
    x : array-like
        data values along abscissa
    y : array-like
        data values along ordinate
    period : float
        period to fold the data
        
    y_unc : array-like
        uncertainty of the 
    '''    
    phases = (x/period) % 1
    if type(y_unc) == float:
        y_unc = np.zeros_like(x)
        
    plot_order = np.argsort(phases)
    norm_y = (y - np.min(y))/(np.max(y) - np.min(y))
    norm_y_unc = (y_unc)/(np.max(y) - np.min(y))
    
    plt.rc('grid', linestyle=":", color='0.8')
    fig, ax = plt.subplots()
    ax.errorbar(phases[plot_order], norm_y[plot_order], norm_y_unc[plot_order],
                 fmt='o', mec="0.2", mew=0.1)
    ax.set_xlabel("phase")
    ax.set_ylabel("signal")
    ax.set_yticks(np.linspace(0,1,11))
    ax.set_xticks(np.linspace(0,1,11))
    ax.grid()
    fig.tight_layout()
Explanation: Problem 1b
Create a function, phase_plot, that takes x, y, and $P$ as inputs to create a phase-folded light curve (i.e., plot the data at their respective phase values given the period $P$).
Include an optional argument, y_unc, to include uncertainties on the y values, when available.
End of explanation
x = np.linspace( # complete
y = # complete
# complete plot
Explanation: Problem 1c
Generate a signal with $A = 2$, $p = \pi$, and Gaussian noise with variance = 0.01 over a regular grid between 0 and 10. Plot the phase-folded results (and make sure the results behave as you would expect).
Hint - your simulated signal should have at least 100 data points.
End of explanation
def shannon_entropy(m, t, p):
    '''Calculate the Shannon entropy
    
    Parameters
    ----------
    m : array-like
        brightness measurements of the time-series data
    
    t : array-like (default=1)
        timestamps corresponding to the brightness measurements
    
    p : float
        period of the periodic signal
        
    Returns
    -------
    H0 : float
        Shannon entropy for m(t) at period p
    '''
    
    m_norm = # complete
    phases = # complete
    H, _, _ = np.histogram2d( # complete
    
    occupied = np.where(H > 0)
    H0 = # complete
    
    return H0
Explanation: Note a couple changes from the previous helper function –– we have added a grid to the plot (this will be useful for visualizing the entropy), and we have also normalized the brightness measurements from 0 to 1. 
Problem 2) The Shannon entropy
As noted above, to calculate the Shannon entropy we need to sum the data over partitions in the normalized $(\phi, m)$ plane.
This is straightforward using histogram2d from numpy. 
Problem 2a 
Write a function shannon_entropy to calculate the Shannon entropy, $H_0$, for a timeseries, $m(t_i)$, at a given period, p.
Hint - use histogram2d and a 10 x 10 grid (as plotted above).
End of explanation
print('For p = 1, \t\tH_0 = {:.5f}'.format( # complete
print('For p = pi - 0.05, \tH_0 = {:.5f}'.format( # complete
print('For p = pi, \t\tH_0 = {:.5f}'.format( # complete
Explanation: Problem 2b
What is the Shannon entropy for the simulated signal at periods = 1, $\pi$-0.05, and $\pi$?
Do these results make sense given your understanding of the Shannon entropy?
End of explanation
def se_periodogram(m, t, f_grid):
    '''Calculate the Shannon entropy at every freq in f_grid
    
    Parameters
    ----------
    m : array-like
        brightness measurements of the time-series data
    
    t : array-like
        timestamps corresponding to the brightness measurements
    
    f_grid : array-like
        trial periods for the periodic signal
        
    Returns
    -------
    se_p : array-like
        Shannon entropy for m(t) at every trial freq
    '''
    
    # complete
    for # complete in # complete
        # complete
    
    return se_p
Explanation: We know the correct period of the simulated data is $\pi$, so it makes sense that this period minimizes the Shannon entropy. 
Problem 2c
Write a function, se_periodogram to calculate the Shannon entropy for observations $m$, $t$ over a frequency grid f_grid.
End of explanation
f_grid = # complete
se_p = # complete
fig,ax = plt.subplots()
# complete
# complete
# complete
print("The best fit period is: {:.4f}".format( # complete
Explanation: Problem 2d
Plot the Shannon entropy periodogram, and return the best-fit period from the periodogram.
Hint - recall what we learned about frequency grids earlier today.
End of explanation
def conditional_entropy(m, t, p):
    '''Calculate the conditional entropy
    
    Parameters
    ----------
    m : array-like
        brightness measurements of the time-series data
    
    t : array-like
        timestamps corresponding to the brightness measurements
    
    p : float
        period of the periodic signal
        
    Returns
    -------
    Hc : float
        Conditional entropy for m(t) at period p
    '''
    
    m_norm = # complete
    phases = # complete
    # complete
    # complete
    # complete
    Hc = # complete
    
    return Hc
Explanation: Problem 3) The Conditional Entropy
The CE is very similar to the Shannon entropy, though we need to condition the calculation on the occupation probability of the partitions in phase.
Problem 3a 
Write a function conditional_entropy to calculate the CE, $H_c$, for a timeseries, $m(t_i)$, at a given period, p.
Hint - if you use histogram2d be sure to sum along the correct axes
Hint 2 - recall from session 8 that we want to avoid for loops, try to vectorize your calculation.
End of explanation
print('For p = 1, \t\tH_c = {:.5f}'.format( # complete
print('For p = pi - 0.05, \tH_c = {:.5f}'.format( # complete
print('For p = pi, \t\tH_c = {:.5f}'.format( # complete
Explanation: Problem 3b
What is the conditional entropy for the simulated signal at periods = 1, $\pi$-0.05, and $\pi$?
Do these results make sense given your understanding of CE?
End of explanation
def ce_periodogram(m, t, f_grid):
    '''Calculate the conditional entropy at every freq in f_grid
    
    Parameters
    ----------
    m : array-like
        brightness measurements of the time-series data
    
    t : array-like
        timestamps corresponding to the brightness measurements
    
    f_grid : array-like
        trial periods for the periodic signal
        
    Returns
    -------
    ce_p : array-like
        conditional entropy for m(t) at every trial freq
    '''
    
    # complete
    for # complete in # complete
        # complete
    
    return ce_p
Explanation: Problem 3c
Write a function, ce_periodogram, to calculate the conditional entropy for observations $m$, $t$ over a frequency grid f_grid.
End of explanation
f_grid = # complete
ce_p = # complete
fig,ax = plt.subplots()
# complete
# complete
# complete
print("The best fit period is: {:.4f}".format( # complete
Explanation: Problem 3d
Plot the conditional entropy periodogram, and return the best-fit period from the periodogram.
End of explanation
data = pd.read_csv("example_asas_lc.dat")
fig, ax = plt.subplots()
ax.errorbar( # complete
ax.set_xlabel('HJD (d)')
ax.set_ylabel('V (mag)')
ax.set_ylim(ax.get_ylim()[::-1])
fig.tight_layout()
Explanation: The Shannon entropy and CE return nearly identical results for a simulated sinusoidal signal. Now we will examine how each performs with actual astronomical observations. 
Problem 4) SE vs. CE for real observations
Problem 4a
Load the data from our favorite eclipsing binary from this morning's LS exercise. Plot the light curve. 
Hint - if you haven't already, download the example light curve.
End of explanation
f_min = # complete
f_max = # complete
delta_f = # complete
f_grid = # complete
se_p = # complete
print("The best fit period is: {:.9f}".format( # complete
Explanation: Problem 4b 
Using the Shannon entropy, determine the best period for this light curve.
Hint - recall this morning's discussion about the optimal grid for a period search
End of explanation
fig, ax = plt.subplots()
# complete
# complete
# complete
Explanation: Problem 4c
Plot the Shannon entropy periodogram.
End of explanation
phase_plot(# complete
Explanation: Problem 4d
Plot the light curve phase-folded on the best-fit period, as measured by the Shannon entropy periodogram.
Does this look reasonable? Why or why not?
Hint - it may be helpful to zoom in on the periodogram.
End of explanation
ce_p = # complete
print("The best fit period is: {:.9f}".format( # complete
Explanation: Problem 4e 
Using the conditional entropy, determine the best period for this light curve.
End of explanation
fig, ax = plt.subplots()
# complete
# complete
# complete
Explanation: Problem 4f
Plot the CE periodogram.
End of explanation
phase_plot( # complete
Explanation: Problem 4g
Plot the light curve phase-folded on the best-fit period, as measured by the CE periodogram.
Does this look reasonable? If not - can you make it look better?
End of explanation
<END_TASK>