
    M/Phn                         d Z ddlZddlmZ ddZ G d d          Z G d d	e          Z G d
 de          ZddZ	dS )z
Empirical CDF Functions
    N)interp1d皙?c                     t          |           }t          j        t          j        d|z            d|z  z            }t          j        | |z
  dd          }t          j        | |z   dd          }||fS )a  
    Constructs a Dvoretzky-Kiefer-Wolfowitz confidence band for the eCDF.

    Parameters
    ----------
    F : array_like
        The empirical distributions
    alpha : float
        Set alpha for a (1 - alpha) % confidence band.

    Notes
    -----
    Based on the DKW inequality.

    .. math:: P \left( \sup_x \left| F(x) - \hat(F)_n(X) \right| >
       \epsilon \right) \leq 2e^{-2n\epsilon^2}

    References
    ----------
    Wasserman, L. 2006. `All of Nonparametric Statistics`. Springer.
    g       @   r      )lennpsqrtlogclip)Falphanobsepsilonloweruppers         p/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/statsmodels/distributions/empirical_distribution.py	_conf_setr      sm    , q66DgbfRX&&!d(344GGAKA&&EGAKA&&E%<    c                        e Zd ZdZddZd ZdS )	StepFunctiona>  
    A basic step function.

    Values at the ends are handled in the simplest way possible:
    everything to the left of x[0] is set to ival; everything
    to the right of x[-1] is set to y[-1].

    Parameters
    ----------
    x : array_like
    y : array_like
    ival : float
        ival is the value given to the values to the left of x[0]. Default
        is 0.
    sorted : bool
        Default is False.
    side : {'left', 'right'}, optional
        Default is 'left'. Defines the shape of the intervals constituting the
        steps. 'right' correspond to [a, b) intervals and 'left' to (a, b].

    Examples
    --------
    >>> import numpy as np
    >>> from statsmodels.distributions.empirical_distribution import (
    >>>     StepFunction)
    >>>
    >>> x = np.arange(20)
    >>> y = np.arange(20)
    >>> f = StepFunction(x, y)
    >>>
    >>> print(f(3.2))
    3.0
    >>> print(f([[3.2,4.5],[24,-3.1]]))
    [[  3.   4.]
     [ 19.   0.]]
    >>> f2 = StepFunction(x, y, side='right')
    >>>
    >>> print(f(3.0))
    2.0
    >>> print(f2(3.0))
    3.0
            Fleftc                    |                                 dvrd}t          |          || _        t          j        |          }t          j        |          }|j        |j        k    rd}t          |          t          |j                  dk    rd}t          |          t          j        t          j         |f         | _	        t          j        ||f         | _
        |sYt          j        | j	                  }	t          j        | j	        |	d          | _	        t          j        | j
        |	d          | _
        | j	        j        d         | _        d S )N)rightr   z*side can take the values 'right' or 'left'z"x and y do not have the same shaper   zx and y must be 1-dimensionalr   )r   
ValueErrorsider	   asarrayshaper   r_infxyargsorttaken)
selfr"   r#   ivalsortedr   msg_x_yasorts
             r   __init__zStepFunction.__init__Q   s   ::<<000>CS//!	Z]]Z]]8rx6CS//!rx==A1CS//!w{#tRx 	/Jtv&&EWTVUA..DFWTVUA..DFar   c                 b    t          j        | j        || j                  dz
  }| j        |         S )Nr   )r	   searchsortedr"   r   r#   )r'   timetinds      r   __call__zStepFunction.__call__k   s*    tvtTY77!;vd|r   N)r   Fr   )__name__
__module____qualname____doc__r.   r3    r   r   r   r   %   sB        ) )V! ! ! !4    r   r   c                   $     e Zd ZdZd fd	Z xZS )ECDFa  
    Return the Empirical CDF of an array as a step function.

    Parameters
    ----------
    x : array_like
        Observations
    side : {'left', 'right'}, optional
        Default is 'right'. Defines the shape of the intervals constituting the
        steps. 'right' correspond to [a, b) intervals and 'left' to (a, b].

    Returns
    -------
    Empirical CDF as a step function.

    Examples
    --------
    >>> import numpy as np
    >>> from statsmodels.distributions.empirical_distribution import ECDF
    >>>
    >>> ecdf = ECDF([3, 3, 1, 4])
    >>>
    >>> ecdf([3, 55, 0.5, 1.5])
    array([ 0.75,  1.  ,  0.  ,  0.25])
    r   c                     t          j        |d          }|                                 t          |          }t          j        d|z  d|          }t                                          |||d           d S )NT)copyg      ?r   r   r)   )r	   arraysortr   linspacesuperr.   )r'   r"   r   r   r#   	__class__s        r   r.   zECDF.__init__   sm    HQT"""	1vvK4D))AD66666r   )r   r4   r5   r6   r7   r.   __classcell__rB   s   @r   r:   r:   q   sG         27 7 7 7 7 7 7 7 7 7r   r:   c                   $     e Zd ZdZd fd	Z xZS )ECDFDiscreteaZ  
    Return the Empirical Weighted CDF of an array as a step function.

    Parameters
    ----------
    x : array_like
        Data values. If freq_weights is None, then x is treated as observations
        and the ecdf is computed from the frequency counts of unique values
        using nunpy.unique.
        If freq_weights is not None, then x will be taken as the support of the
        mass point distribution with freq_weights as counts for x values.
        The x values can be arbitrary sortable values and need not be integers.
    freq_weights : array_like
        Weights of the observations.  sum(freq_weights) is interpreted as nobs
        for confint.
        If freq_weights is None, then the frequency counts for unique values
        will be computed from the data x.
    side : {'left', 'right'}, optional
        Default is 'right'. Defines the shape of the intervals constituting the
        steps. 'right' correspond to [a, b) intervals and 'left' to (a, b].

    Returns
    -------
    Weighted ECDF as a step function.

    Examples
    --------
    >>> import numpy as np
    >>> from statsmodels.distributions.empirical_distribution import (
    >>>     ECDFDiscrete)
    >>>
    >>> ewcdf = ECDFDiscrete([3, 3, 1, 4])
    >>> ewcdf([3, 55, 0.5, 1.5])
    array([0.75, 1.  , 0.  , 0.25])
    >>>
    >>> ewcdf = ECDFDiscrete([3, 1, 4], [1.25, 2.5, 5])
    >>>
    >>> ewcdf([3, 55, 0.5, 1.5])
    array([0.42857143, 1., 0. , 0.28571429])
    >>> print('e1 and e2 are equivalent ways of defining the same ECDF')
    e1 and e2 are equivalent ways of defining the same ECDF
    >>> e1 = ECDFDiscrete([3.5, 3.5, 1.5, 1, 4])
    >>> e2 = ECDFDiscrete([3.5, 1.5, 1, 4], freq_weights=[2, 1, 1, 1])
    >>> print(e1.x, e2.x)
    [-inf  1.   1.5  3.5  4. ] [-inf  1.   1.5  3.5  4. ]
    >>> print(e1.y, e2.y)
    [0.  0.2 0.4 0.8 1. ] [0.  0.2 0.4 0.8 1. ]
    Nr   c                    |t          j        |d          \  }}nt          j        |          }t          |          t          |          k    sJ t          j        |          }t          j        |          }|dk    sJ |                                }||         }t          j        ||                   }||z  }t                                          |||d           d S )NT)return_countsr   r=   )	r	   uniquer   r   sumr$   cumsumrA   r.   )	r'   r"   freq_weightsr   wswaxr#   rB   s	           r   r.   zECDFDiscrete.__init__   s     i>>>OA||
1A<  CFF****J|$$VAYYAvvvvYY[[bEIaeFAD66666r   )Nr   rC   rE   s   @r   rG   rG      sH        / /`7 7 7 7 7 7 7 7 7 7r   rG   Tc                    t          j        |          }|r
 | |fi |}n7g }|D ]}|                     | |fi |           t          j        |          }t          j        |          }t          ||         ||                   S )z
    Given a monotone function fn (no checking is done to verify monotonicity)
    and a set of x values, return an linearly interpolated approximation
    to its inverse from its values on x.
    )r	   r   appendr>   r$   r   )fnr"   
vectorizedkeywordsr#   r+   as          r   monotone_fn_inverterrW      s     	
1A BqH 	) 	)BHHRR''h''((((HQKK

1AAaD!A$r   )r   )T)
r7   numpyr	   scipy.interpolater   r   r   r:   rG   rW   r8   r   r   <module>rZ      s         & & & & & &   :I I I I I I I IX7 7 7 7 7< 7 7 7P>7 >7 >7 >7 >7< >7 >7 >7B           r   