o
    0Gf@                  	   @   s  d Z ddlmZmZ ddlmZ ddlZddlm	Z
 ddlmZ dRddZd	d
 ZdSddZdd Zdd Zdd ZdTddZdTddZdUddZdTddZdTddZdTdd ZdVd#d$ZdWd&d'Zed(kred) ed* g d+Zg d,ZeD ]Zeee qyeD ]Zeee qeee eee g d-Z e
!d. e
"d/ e
#d0 e$dd!d1Z%e
&e%ee% e
!d. e
"d2 e
#d0 e$dd!d3Z%e
&e%eeee%d!e%  e'g d4g d5g d6gZ(e()dZ*e()d!Z+ee*Z,ee+Z-ee(Z.ee*e+e(Z/ee+e*e(Z0edej1e2e*e+ Z3edej1e2e+e* Z4ee*e+e(Z5ed7 ee,e-e.e/e0e3e4e5 ed8 e'g d9ZeeZ6e ed: ed; ed< ed= ed> ed?e*  ed@ d!e*d  Z7edAe7  ee7d!e7 gZ8edBe8  edCe8e7e9d  e/f  edD edE:e7e,d! e9dF  edG edH e'g dIg dJg dKgZ;ee; edL edMe<dee;d! ee;d gd! e9dF   edN e'g dOg dPg dQgZ=dS dS )Xa:  
Information Theoretic and Entropy Measures

References
----------
Golan, As. 2008. "Information and Entropy Econometrics -- A Review and
    Synthesis." Foundations And Trends in Econometrics 2(1-2), 1-145.

Golan, A., Judge, G., and Miller, D.  1996.  Maximum Entropy Econometrics.
    Wiley & Sons, Chichester.
    )lziplmap)statsN)pyplot)	logsumexpc                 C   sf   |du rt | S t| } t| j}d||< | j|d}tt| || j	|d}|| }|S )a-  
    Compute the log of the sum of exponentials log(e^{a_1}+...e^{a_n}) of a

    Avoids numerical overflow.

    Parameters
    ----------
    a : array_like
        The vector to exponentiate and sum
    axis : int, optional
        The axis along which to apply the operation.  Defaults is None.

    Returns
    -------
    sum(log(exp(a)))

    Notes
    -----
    This function was taken from the mailing list
    http://mail.scipy.org/pipermail/scipy-user/2009-October/022931.html

    This should be superceded by the ufunc when it is finished.
    N   )axis)
sp_logsumexpnpasarraylistshapemaxlogZexpZreshapesum)ar   ZshpZa_maxsZlse r   <lib/python3.10/site-packages/statsmodels/sandbox/infotheo.pyr   -   s   

"r   c                 C   s@   t | } t t | drt | dkrt | dksdS dS )zC
    Checks to see if `X` is a proper probability distribution
    r   r   FT)r
   r   Zallcloser   allXr   r   r   _isproperdistQ   s   
.r   efc                 C   s   t | }|du rtt|}|dkr t|t|  | }|dkrrt| t|  }t|| }t	| \}}t
|}d}|d }	|||d < td|D ]}
||
 |	| k rc||||
 < qR||
 }	|d7 }||||
 < qR|S )z
    Discretize `X`

    Parameters
    ----------
    bins : int, optional
        Number of bins.  Default is floor(sqrt(N))
    method : str
        "ef" is equal-frequency binning
        "ew" is equal-width binning

    Examples
    --------
    Nr   Zewr   r   )lenr
   ZfloorZsqrtZceilr   Zrankdatar   minZfastsortZzerosrange)r   methodZnbinsZnobsZdiscretewidthZsvecZivecZbinnumbaseir   r   r   
discretize[   s(   
r!   c                 C   s   t |t |  S )z
    There is a one-to-one transformation of the entropy value from
    a log base b to a log base a :

    H_{b}(X)=log_{b}(a)[H_{a}(X)]

    Returns
    -------
    log_{b}(a)
    )r
   r   )r   br   r   r   logbasechange   s   r#   c                 C   s   t tjd|  S )z$
    Converts from nats to bits
       r#   r
   er   r   r   r   
natstobits      r'   c                 C   s   t dtj|  S )z$
    Converts from bits to nats
    r$   r%   r   r   r   r   
bitstonats   r(   r)   r$   c                 C   sd   t | } t | dkrt | dkstdt t | t |   }|dkr0td|| S |S )aC  
    This is Shannon's entropy

    Parameters
    ----------
    logbase, int or np.e
        The base of the log
    px : 1d or 2d array_like
        Can be a discrete probability distribution, a 2d joint distribution,
        or a sequence of probabilities.

    Returns
    -----
    For log base 2 (bits) given a discrete distribution
        H(p) = sum(px * log2(1/px) = -sum(pk*log2(px)) = E[log2(1/p(X))]

    For log base 2 (bits) given a joint distribution
        H(px,py) = -sum_{k,j}*w_{kj}log2(w_{kj})

    Notes
    -----
    shannonentropy(0) is defined as 0
    r   r   &px does not define proper distributionr$   )r
   r   r   
ValueErrorr   
nan_to_numlog2r#   )pxlogbaseentropyr   r   r   shannonentropy   s   
r1   c                 C   sX   t | } t | dkrt | dkstd|dkr&td| t |  S t |  S )z
    Shannon's information

    Parameters
    ----------
    px : float or array_like
        `px` is a discrete probability distribution

    Returns
    -------
    For logbase = 2
    np.log2(px)
    r   r   r*   r$   )r
   r   r   r+   r#   r-   )r.   r/   r   r   r   shannoninfo   s   
r2   c              	   C   s|   t | rt |std|durt |std|du r"t|| }t|tt||  }|dkr7|S td|| S )a  
    Return the conditional entropy of X given Y.

    Parameters
    ----------
    px : array_like
    py : array_like
    pxpy : array_like, optional
        If pxpy is None, the distributions are assumed to be independent
        and conendtropy(px,py) = shannonentropy(px)
    logbase : int or np.e

    Returns
    -------
    sum_{kj}log(q_{j}/w_{kj}

    where q_{j} = Y[j]
    and w_kj = X[k,j]
    1px or py is not a proper probability distributionN&pxpy is not a proper joint distribtionr$   )r   r+   r
   outerr   r,   r-   r#   )r.   pypxpyr/   condentr   r   r   condentropy   s   r9   c                 C   s`   t | rt |std|durt |std|du r"t|| }t| |dt| |||d S )aC  
    Returns the mutual information between X and Y.

    Parameters
    ----------
    px : array_like
        Discrete probability distribution of random variable X
    py : array_like
        Discrete probability distribution of random variable Y
    pxpy : 2d array_like
        The joint probability distribution of random variables X and Y.
        Note that if X and Y are independent then the mutual information
        is zero.
    logbase : int or np.e, optional
        Default is 2 (bits)

    Returns
    -------
    shannonentropy(px) - condentropy(px,py,pxpy)
    r3   Nr4   r/   )r   r+   r
   r5   r1   r9   r.   r6   r7   r/   r   r   r   
mutualinfo   s   r<   c                 C   s`   t | rt |std|durt |std|du r"t|| }t| |||dt||d S )aa  
    An information theoretic correlation measure.

    Reflects linear and nonlinear correlation between two random variables
    X and Y, characterized by the discrete probability distributions px and py
    respectively.

    Parameters
    ----------
    px : array_like
        Discrete probability distribution of random variable X
    py : array_like
        Discrete probability distribution of random variable Y
    pxpy : 2d array_like, optional
        Joint probability distribution of X and Y.  If pxpy is None, X and Y
        are assumed to be independent.
    logbase : int or np.e, optional
        Default is 2 (bits)

    Returns
    -------
    mutualinfo(px,py,pxpy,logbase=logbase)/shannonentropy(py,logbase=logbase)

    Notes
    -----
    This is also equivalent to

    corrent(px,py,pxpy) = 1 - condent(px,py,pxpy)/shannonentropy(py)
    r3   Nr4   r:   )r   r+   r
   r5   r<   r1   r;   r   r   r   corrent  s   r=   c                 C   sd   t | rt |std|durt |std|du r"t|| }t| |||dt|| ||d S )ak  
    An information theoretic covariance measure.

    Reflects linear and nonlinear correlation between two random variables
    X and Y, characterized by the discrete probability distributions px and py
    respectively.

    Parameters
    ----------
    px : array_like
        Discrete probability distribution of random variable X
    py : array_like
        Discrete probability distribution of random variable Y
    pxpy : 2d array_like, optional
        Joint probability distribution of X and Y.  If pxpy is None, X and Y
        are assumed to be independent.
    logbase : int or np.e, optional
        Default is 2 (bits)

    Returns
    -------
    condent(px,py,pxpy,logbase=logbase) + condent(py,px,pxpy,
            logbase=logbase)

    Notes
    -----
    This is also equivalent to

    covent(px,py,pxpy) = condent(px,py,pxpy) + condent(py,px,pxpy)
    r3   Nr4   r:   )r   r+   r
   r5   r8   r;   r   r   r   covent=  s   r>   r   Rc                 C   s   t | stdt|}|dkr!t| }|dkrtd|| S |S dt| v s.|tjkr7t	t
|  S | | } t	|  }|dkrNdd|  | S dd|  td| | S )as  
    Renyi's generalized entropy

    Parameters
    ----------
    px : array_like
        Discrete probability distribution of random variable X.  Note that
        px is assumed to be a proper probability distribution.
    logbase : int or np.e, optional
        Default is 2 (bits)
    alpha : float or inf
        The order of the entropy.  The default is 1, which in the limit
        is just Shannon's entropy.  2 is Renyi (Collision) entropy.  If
        the string "inf" or numpy.inf is specified the min-entropy is returned.
    measure : str, optional
        The type of entropy measure desired.  'R' returns Renyi entropy
        measure.  'T' returns the Tsallis entropy measure.

    Returns
    -------
    1/(1-alpha)*log(sum(px**alpha))

    In the limit as alpha -> 1, Shannon's entropy is returned.

    In the limit as alpha -> inf, min-entropy is returned.
    z+px is not a proper probability distributionr   r$   inf)r   r+   floatr1   r#   strlowerr
   r@   r   r   r   )r.   alphar/   measureZgenentr   r   r   renyientropyk  s   rF   Tc                 C   s   dS )a  
    Generalized cross-entropy measures.

    Parameters
    ----------
    px : array_like
        Discrete probability distribution of random variable X
    py : array_like
        Discrete probability distribution of random variable Y
    pxpy : 2d array_like, optional
        Joint probability distribution of X and Y.  If pxpy is None, X and Y
        are assumed to be independent.
    logbase : int or np.e, optional
        Default is 2 (bits)
    measure : str, optional
        The measure is the type of generalized cross-entropy desired. 'T' is
        the cross-entropy version of the Tsallis measure.  'CR' is Cressie-Read
        measure.
    Nr   )r.   r6   r7   rD   r/   rE   r   r   r   gencrossentropy  s    rH   __main__zQFrom Golan (2008) "Information and Entropy Econometrics -- A Review and Synthesisz	Table 3.1)皙?rJ   rJ   rJ   rJ   )S㥛?g;On?g'1Z?gK?gMbp?)gh㈵>g-C6?gMbP?g{Gz?g?g333333?rJ   g      ?g333333?gffffff?g?g?      ?o   ZInformationZProbabilityi ZEntropye   )r   r   UUUUUU?)qq?rP   rP   )gqq?rP   UUUUUU?z	Table 3.3zdiscretize functions)2g3333335@g     @F@g      ?@g     3@gLD@gYC@g333333&@g/@gfffff?@g9@g3333334@gffffff,@g      8@g      5@g&@g      2@L0@g3333336@g333333@g;@rR   ǧA@-@g1@g333333<@gffffff0@g     0@g      G@g      #@g2@g@@g:@g0@g333333@gffffff5@g      4@gL=@rS   g @g     6@g)@gfffff:@g     9@gfffff6@gffffff&@g333334@g333333:@g"@g%@g333333/@z0Example in section 3.6 of Golan, using table 3.3z'Bounding errors using Fano's inequalityz"H(P_{e}) + P_{e}log(K-1) >= H(X|Y)zor, a weaker inequalityzP_{e} >= [H(X|Y) - 1]/log(K)z	P(x) = %sz?X = 3 has the highest probability, so this is the estimate Xhatz1The probability of error Pe is 1 - p(X=3) = %0.4gzH(Pe) = %0.4g and K=3z-H(Pe) + Pe*log(K-1) = %0.4g >= H(X|Y) = %0.4gzor using the weaker inequalityz+Pe = {:0.4g} >= [H(X) - 1]/log(K) = {:0.4g}   z>Consider now, table 3.5, where there is additional informationz.The conditional probabilities of P(X|Y=y) are )        rU   g      ?)rO   rO   rO   )rQ   rO   rL   z2The probability of error given this information iszPe = [H(X|Y) -1]/log(K) = %0.4gz+such that more information lowers the error)gV-?gV-?gw/?)g(\?g+?g%C?)gzG?rK   gPn?)N)r   N)r$   )Nr$   )r   r$   r?   )r   r$   rG   )>__doc__Zstatsmodels.compat.pythonr   r   Zscipyr   Znumpyr
   Z
matplotlibr   ZpltZscipy.specialr   r	   r   r!   r#   r'   r)   r1   r2   r9   r<   r=   r>   rF   rH   __name__printr   Yr    pZsubplotZylabelZxlabelZlinspacexZplotZarraywr   r.   r6   ZH_XZH_YZH_XYZ	H_XgivenYZ	H_YgivenXr&   r0   ZD_YXZD_XYZI_XYZdiscXZpeZH_per-   formatZw2ZmeanZmarkovchainr   r   r   r   <module>   s    "
$

(

#

 

(
.
3








6 