U
    ÃmœdK<  ã                   @   sØ   d Z ddlZddlZddlZddlmZ ddl	m
Z
 dd„ Zd-dd„Zd.d
d„Zd/dd„Zd0dd„Zdd„ Zd1dd„Zdd„ Zdd„ Zdd„ Zd2dd„Zd d!„ Zd"d#„ Zd$d%„ ZG d&d'„ d'eƒZd3d(d)„Zd4d+d,„ZdS )5z
Utility functions models code
é    N)Ú_is_using_pandas)Ú
array_likec                 C   s.   t | tƒr| S t | tƒr"|  d¡S t| ƒS d S )NÚlatin1)Ú
isinstanceÚstrÚbytesÚdecode)Ús© r
   úP/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/statsmodels/tools/tools.pyÚasstr2   s
    


r   c                 C   s&   i }t | ƒD ]\}}|||| < q|S )zd
    Helper function to create a dictionary mapping a column number
    to the name in tmp_arr.
    )Ú	enumerate)Ztmp_arrÚoffsetZcol_mapÚiZcol_namer
   r
   r   Ú_make_dictnames   s    r   é   c                 C   s¦   t  | ¡} | jdkr$| dd…df } |dk	rˆt  |¡}|jdkrP|dd…df }t  t  | ¡ |¡ t  |¡ |¡ ¡}| | || fS t  | ¡ |¡ }| | S dS )a�  
    Returns views on the arrays Y and X where missing observations are dropped.

    Y : array_like
    X : array_like, optional
    axis : int
        Axis along which to look for missing observations.  Default is 1, ie.,
        observations in rows.

    Returns
    -------
    Y : ndarray
        All Y where the
    X : ndarray

    Notes
    -----
    If either Y or X is 1d, it is reshaped to be 2d.
    r   N)ÚnpÚasarrayÚndimÚarrayÚlogical_andÚisnanÚany)ÚYÚXÚaxisZkeepidxr
   r
   r   Údrop_missing    s    



ÿr   Fc                 C   s   t dƒ‚dS )ax  
    Construct a dummy matrix from categorical variables

    .. deprecated:: 0.12

       Use pandas.get_dummies instead.

    Parameters
    ----------
    data : array_like
        An array, Series or DataFrame.  This can be either a 1d vector of
        the categorical variable or a 2d array with the column specifying
        the categorical variable specified by the col argument.
    col : {str, int, None}
        If data is a DataFrame col must in a column of data. If data is a
        Series, col must be either the name of the Series or None. For arrays,
        `col` can be an int that is the (zero-based) column index
        number.  `col` can only be None for a 1d array.  The default is None.
    dictnames : bool, optional
        If True, a dictionary mapping the column number to the categorical
        name is returned.  Used to have information about plain arrays.
    drop : bool
        Whether or not keep the categorical variable in the returned matrix.

    Returns
    -------
    dummy_matrix : array_like
        A matrix of dummy (indicator/binary) float variables for the
        categorical data.
    dictnames :  dict[int, str], optional
        Mapping between column numbers and categorical names.

    Notes
    -----
    This returns a dummy variable for *each* distinct variable.  If a
    a DaataFrame is provided, the names for the new variable is the
    old variable name - underscore - category name.  So if the a variable
    'vote' had answers as 'yes' or 'no' then the returned array would have to
    new variables-- 'vote_yes' and 'vote_no'.  There is currently
    no name checking.

    Examples
    --------
    >>> import numpy as np
    >>> import statsmodels.api as sm

    Univariate examples

    >>> import string
    >>> string_var = [string.ascii_lowercase[0:5],
    ...               string.ascii_lowercase[5:10],
    ...               string.ascii_lowercase[10:15],
    ...               string.ascii_lowercase[15:20],
    ...               string.ascii_lowercase[20:25]]
    >>> string_var *= 5
    >>> string_var = np.asarray(sorted(string_var))
    >>> design = sm.tools.categorical(string_var, drop=True)

    Or for a numerical categorical variable

    >>> instr = np.floor(np.arange(10,60, step=2)/10)
    >>> design = sm.tools.categorical(instr, drop=True)

    With a structured array

    >>> num = np.random.randn(25,2)
    >>> struct_ar = np.zeros((25,1),
    ...                      dtype=[('var1', 'f4'),('var2', 'f4'),
    ...                             ('instrument','f4'),('str_instr','a5')])
    >>> struct_ar['var1'] = num[:,0][:,None]
    >>> struct_ar['var2'] = num[:,1][:,None]
    >>> struct_ar['instrument'] = instr[:,None]
    >>> struct_ar['str_instr'] = string_var[:,None]
    >>> design = sm.tools.categorical(struct_ar, col='instrument', drop=True)

    Or

    >>> design2 = sm.tools.categorical(struct_ar, col='str_instr', drop=True)
    zcategorical has been removedN)ÚNotImplementedError)ÚdataÚcolZ	dictnamesZdropr
   r
   r   ÚcategoricalG   s    Pr    TÚskipc           	      C   s&  t | dƒr&ddlm} || d||d�S t | ¡}|j}|dkrP|dd…df }n|jdkrbtdƒ‚tj|dd	�dk}|tj|d
kdd	�M }| 	¡ rð|dkrž|S |dkrð|dkr¸tdƒ‚n8t 
|jd ¡}d dd„ || D ƒ¡}td|› d�ƒ‚t |jd ¡|g}|�r|n|ddd… }t |¡S )aq  
    Add a column of ones to an array.

    Parameters
    ----------
    data : array_like
        A column-ordered design matrix.
    prepend : bool
        If true, the constant is in the first column.  Else the constant is
        appended (last column).
    has_constant : str {'raise', 'add', 'skip'}
        Behavior if ``data`` already has a constant. The default will return
        data without adding another constant. If 'raise', will raise an
        error if any column has a constant value. Using 'add' will add a
        column of 1s if a constant column is present.

    Returns
    -------
    array_like
        The original values with a constant (column of ones) as the first or
        last column. Returned value type depends on input type.

    Notes
    -----
    When the input is a pandas Series or DataFrame, the added column's name
    is 'const'.
    Nr   )Ú	add_trendÚc)ZtrendÚprependÚhas_constantr   é   z)Only implemented for 2-dimensional arrays©r   ç        r!   Úraisezdata is constant.ú,c                 S   s   g | ]}t |ƒ‘qS r
   )r   )Ú.0r#   r
   r
   r   Ú
<listcomp>Í   s     z add_constant.<locals>.<listcomp>z
Column(s) z are constant.éÿÿÿÿ)r   Zstatsmodels.tsa.tsatoolsr"   r   r   r   Ú
ValueErrorZptpÚallr   ZarangeÚshapeÚjoinZonesZcolumn_stack)	r   r$   r%   r"   Úxr   Zis_nonzero_constÚcolumnsÚcolsr
   r
   r   Úadd_constant›   s.    



r5   c                 C   sŽ   t | ddd�} t |ddd�}| jdkr6| ddd…f n| } | jd |jd kr`td|jd  ƒ‚t | |g¡}tj |¡tj |¡krŠd	S d
S )a6  
    True if (Q, P) contrast `c` is estimable for (N, P) design `d`.

    From an Q x P contrast matrix `C` and an N x P design matrix `D`, checks if
    the contrast `C` is estimable by looking at the rank of ``vstack([C,D])``
    and verifying it is the same as the rank of `D`.

    Parameters
    ----------
    c : array_like
        A contrast matrix with shape (Q, P). If 1 dimensional assume shape is
        (1, P).
    d : array_like
        The design matrix, (N, P).

    Returns
    -------
    bool
        True if the contrast `c` is estimable on design `d`.

    Examples
    --------
    >>> d = np.array([[1, 1, 1, 0, 0, 0],
    ...               [0, 0, 0, 1, 1, 1],
    ...               [1, 1, 1, 1, 1, 1]]).T
    >>> isestimable([1, 0, 0], d)
    False
    >>> isestimable([1, -1, 0], d)
    True
    r#   r&   )ZmaxdimÚd©r   r   NzContrast should have %d columnsFT)r   r   r0   r.   r   ZvstackÚlinalgÚmatrix_rank)r#   r6   Únewr
   r
   r   ÚisestimableÕ   s    r;   çVçž¯Ò<c              	   C   sÆ   t  | ¡} |  ¡ } t j | d¡\}}}t  |¡}|jd }|jd }|t j |¡ }t	t
||ƒƒD ]*}	||	 |kr„d||	  ||	< qbd||	< qbt  t  |¡t  |dd…t jjf t  |¡¡¡}
|
|fS )z}
    Return the pinv of an array X as well as the singular values
    used in computation.

    Code adapted from numpy.
    Fr   r   ç      ð?r(   N)r   r   Ú	conjugater8   ÚsvdÚcopyr0   ÚmaximumÚreduceÚrangeÚminÚdotÚ	transposeÚmultiplyÚcoreZnewaxis)r2   ZrcondÚur	   ÚvtZs_origÚmÚnÚcutoffr   Úresr
   r
   r   Úpinv_extendedÿ   s    




"ÿrO   c                 C   sj   t  | ¡} t j| t jd�}t  | j¡}| }|| | j| dk@ ||< d| j|  |j|< t j|j|< |S )zì
    Reciprocal of an array with entries less than or equal to 0 set to 0.

    Parameters
    ----------
    x : array_like
        The input array.

    Returns
    -------
    ndarray
        The array with 0-filled reciprocals.
    ©Zdtyper   r=   ©r   r   Z
zeros_likeÚfloat64r   ZflatÚnan)r2   ÚoutÚnansÚposr
   r
   r   Úrecipr  s    
rW   c                 C   sj   t  | ¡} t j| t jd�}t  | j¡}| }|| | j| dk@ ||< d| j|  |j|< t j|j|< |S )zà
    Reciprocal of an array with entries less than 0 set to 0.

    Parameters
    ----------
    x : array_like
        The input array.

    Returns
    -------
    ndarray
        The array with 0-filled reciprocals.
    rP   r   r=   rQ   )r2   rT   rU   Znon_zeror
   r
   r   Úrecipr0/  s    
rX   c                    s:   t j ˆ d d¡}‡ fdd„t  |¡D ƒ}t  t  |¡¡S )zÖ
    Erase columns of zeros: can save some time in pseudoinverse.

    Parameters
    ----------
    matrix : ndarray
        The array to clean.

    Returns
    -------
    ndarray
        The cleaned array.
    r&   r   c                    s   g | ]}ˆ d d …|f ‘qS ©Nr
   )r+   r   ©Úmatrixr
   r   r,   V  s     zclean0.<locals>.<listcomp>)r   ÚaddrB   Zflatnonzeror   rF   )r[   ZcolsumÚvalr
   rZ   r   Úclean0G  s    r^   c                 C   s†   |dkrt j | ¡}t jj| dd�\}}}t  |¡}|ddd… }g }t|ƒD ]}| |dd…|| f ¡ qNt  t  |¡¡ 	t j
¡S )aÖ  
    Return an array whose column span is the same as x.

    Parameters
    ----------
    x : ndarray
        The array to adjust, 2d.
    r : int, optional
        The rank of x. If not provided, determined by `np.linalg.matrix_rank`.

    Returns
    -------
    ndarray
        The array adjusted to have full rank.

    Notes
    -----
    If the rank of x is known it can be specified as r -- no check
    is made to ensure that this really is the rank of x.
    NF)Zfull_matricesr-   )r   r8   r9   r?   ZargsortrC   Úappendr   rF   ZastyperR   )r2   ÚrÚvr6   rI   ÚorderÚvaluer   r
   r
   r   ÚfullrankZ  s    
rd   c                 C   s   t |ƒ}d||< |  |¡S )aW  
    Unsqueeze a collapsed array.

    Parameters
    ----------
    data : ndarray
        The data to unsqueeze.
    axis : int
        The axis to unsqueeze.
    oldshape : tuple[int]
        The original shape before the squeeze or reduce operation.

    Returns
    -------
    ndarray
        The unsqueezed array.

    Examples
    --------
    >>> from numpy import mean
    >>> from numpy.random import standard_normal
    >>> x = standard_normal((3,4,5))
    >>> m = mean(x, axis=1)
    >>> m.shape
    (3, 5)
    >>> m = unsqueeze(m, 1, x.shape)
    >>> m.shape
    (3, 1, 5)
    >>>
    r   )ÚlistZreshape)r   r   ZoldshapeZnewshaper
   r
   r   Ú	unsqueeze{  s    rf   c                 C   sZ   t  t  | ¡|dk¡}t  | dkt  |¡¡}|| }t  t  | ¡t  |¡¡}t j||< |S )z«
    Returns np.dot(left_matrix, right_matrix) with the convention that
    nan * 0 = 0 and nan * x = nan if x != 0.

    Parameters
    ----------
    A, B : ndarray
    r   )r   rE   r   Z
nan_to_numrS   )ÚAÚBZshould_be_nan_1Zshould_be_nan_2Zshould_be_nanÚCr
   r
   r   Únan_dotŸ  s    

rj   c                 C   s   t | d| ƒS )zˆ
    Gets raw results back from wrapped results.

    Can be used in plotting functions or other post-estimation type
    routines.
    Z_results)Úgetattr)Úresultsr
   r
   r   Úmaybe_unwrap_results¶  s    rm   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚBuncha  
    Returns a dict-like object with keys accessible via attribute lookup.

    Parameters
    ----------
    *args
        Arguments passed to dict constructor, tuples (key, value).
    **kwargs
        Keyword agument passed to dict constructor, key=value.
    c                    s   t t| ƒj||Ž | | _d S rY   )Úsuperrn   Ú__init__Ú__dict__)ÚselfÚargsÚkwargs©Ú	__class__r
   r   rp   Ë  s    zBunch.__init__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rp   Ú__classcell__r
   r
   ru   r   rn   À  s   
rn   c                 C   sˆ   | dkr| S t | dƒ}| jdkr8|r.| | jfS | dfS n| jdkrJtdƒ‚|rT| jnd}|rvt | ¡dd…df |fS t | ¡|fS dS )aå  

    Parameters
    ----------
    x : ndarray, Series, DataFrame or None
        Input to verify dimensions, and to transform as necesary
    ndarray : bool
        Flag indicating whether to always return a NumPy array. Setting False
        will return an pandas DataFrame when the input is a Series or a
        DataFrame.

    Returns
    -------
    out : ndarray, DataFrame or None
        array or DataFrame with 2 dimensiona.  One dimensional arrays are
        returned as nobs by 1. None is returned if x is None.
    names : list of str or None
        list containing variables names when the input is a pandas datatype.
        Returns None if the input is an ndarray.

    Notes
    -----
    Accepts None for simplicity
    Nr&   zx mst be 1 or 2-dimensional.)	r   r   r3   r.   Únamer   r   ÚpdZ	DataFrame)r2   ZndarrayZ	is_pandasr|   r
   r
   r   Ú
_ensure_2dÐ  s    




r~   Úqrc                 C   sÜ   t | ddd�} |dkrh| dd…tj| dkdd�f } | t | d  d¡¡ } | j|  } tjj| |dd	�S |d
krÈtjj	| dd�\}t 
t |¡¡}|dkr¸|d | jd  t t¡j }t||k ¡ ƒS tjj| |d�S dS )a(  
    Matrix rank calculation using QR or SVD

    Parameters
    ----------
    m : array_like
        A 2-d array-like object to test
    tol : float, optional
        The tolerance to use when testing the matrix rank. If not provided
        an appropriate value is selected.
    method : {"ip", "qr", "svd"}
        The method used. "ip" uses the inner-product of a normalized version
        of m and then computes the rank using NumPy's matrix_rank.
        "qr" uses a QR decomposition and is the default. "svd" defers to
        NumPy's matrix_rank.

    Returns
    -------
    int
        The rank of m.

    Notes
    -----
    When using a QR factorization, the rank is determined by the number of
    elements on the leading diagonal of the R matrix that are above tol
    in absolute value.
    rK   r&   r7   ÚipNr   r'   T)ÚtolZ	hermitianr   r`   )Úmoder   )r�   )r   r   r   ÚsqrtÚsumÚTr8   r9   Úscipyr   ÚabsZdiagr0   ZfinfoÚfloatZepsÚint)rK   r�   Úmethodr`   Zabs_diagr
   r
   r   r9   û  s    
r9   )r   )Nr   )NFF)Tr!   )r<   )N)F)Nr   )rz   Únumpyr   Zpandasr}   Zscipy.linalgr†   Zstatsmodels.tools.datar   Zstatsmodels.tools.validationr   r   r   r   r    r5   r;   rO   rW   rX   r^   rd   rf   rj   rm   Údictrn   r~   r9   r
   r
   r
   r   Ú<module>   s,   	

'
T
:*

!$

+