B
    Z                  @   s  d Z ddlmZ ddlmZmZ ddlZddlm	Z
 ddlmZ ddlmZmZmZmZmZmZ ddlZddlmZmZ dd	lmZ dd
dZdddZeejZeejZdddddZdddZdddZdd Z e!dkrej"#ddZ$e$ddddf ej"#dd Z%ee$e% ee$ ee$ ee$Z&e'j(e$Z)e*e+e,e&e)  ee$Z&e'j(e$Z)e*e+e,e&e)  dS )zylocal, adjusted version from scipy.linalg.basic.py


changes:
The only changes are that additional results are returned

    )print_function)lmaprangeN)svd)get_lapack_funcs)asarrayzerossum	conjugatedot	transpose)asarray_chkfinitesingle)LinAlgErrorc             C   s  t t| |f\}}|jdkr$td|j\}}|jdkrD|jd }	nd}	||jd kr^tdtd||f\}
||krt||	f|
jd}|jdkr||d|ddf< n||d|df< |}|p|| k	ot| d	 }|p||k	ot|d	 }|
j	dd
 dkrF|
||ddd }|d j
tj}|
||||||d\}}}}}}ntd|
j	 |dkrftd|dk r~td|  tg |jd}||k r|d| }||krt||d d dd}|}||||fS )a  Compute least-squares solution to equation :m:`a x = b`

    Compute a vector x such that the 2-norm :m:`|b - a x|` is minimised.

    Parameters
    ----------
    a : array, shape (M, N)
    b : array, shape (M,) or (M, K)
    cond : float
        Cutoff for 'small' singular values; used to determine effective
        rank of a. Singular values smaller than rcond*largest_singular_value
        are considered zero.
    overwrite_a : boolean
        Discard data in a (may enhance performance)
    overwrite_b : boolean
        Discard data in b (may enhance performance)

    Returns
    -------
    x : array, shape (N,) or (N, K) depending on shape of b
        Least-squares solution
    residues : array, shape () or (1,) or (K,)
        Sums of residues, squared 2-norm for each column in :m:`b - a x`
        If rank of matrix a is < N or > M this is an empty array.
        If b was 1-d, this is an (1,) shape array, otherwise the shape is (K,)
    rank : integer
        Effective rank of matrix a
    s : array, shape (min(M,N),)
        Singular values of a. The condition number of a is abs(s[0]/s[-1]).

    Raises LinAlgError if computation does not converge

       zexpected matrix   r   zincompatible dimensions)gelss)dtypeNZ	__array__   Zflapack)lwork   )condr   overwrite_aoverwrite_bzcalling gelss from %sz,SVD did not converge in Linear Least Squaresz0illegal value in %-th argument of internal gelss)axis)r   r   ndim
ValueErrorshaper   r   r   hasattrZmodule_namerealZastypenpintNotImplementedErrorr   r   r	   )abr   r   r   Za1Zb1mnZnrhsr   Zb2Zworkr   vxsZrankinfoZresidsZx1 r,   7lib/python3.7/site-packages/statsmodels/tools/linalg.pylstsq   sL    "










r.   c             C   s<   t | } tj| jd | jd}|dk	r*|}t| ||dd S )a  Compute the (Moore-Penrose) pseudo-inverse of a matrix.

    Calculate a generalized inverse of a matrix using a least-squares
    solver.

    Parameters
    ----------
    a : array, shape (M, N)
        Matrix to be pseudo-inverted
    cond, rcond : float
        Cutoff for 'small' singular values in the least-squares solver.
        Singular values smaller than rcond*largest_singular_value are
        considered zero.

    Returns
    -------
    B : array, shape (N, M)

    Raises LinAlgError if computation does not converge

    Examples
    --------
    >>> from numpy import *
    >>> a = random.randn(9, 6)
    >>> B = linalg.pinv(a)
    >>> allclose(a, dot(a, dot(B, a)))
    True
    >>> allclose(B, dot(B, dot(a, B)))
    True

    r   )r   N)r   )r   numpyZidentityr   r   r.   )r$   r   rcondr%   r,   r,   r-   pinvh   s
     r1   r   )fdFDc             C   s   t | } t| \}}}|jj}|dk	r*|}|dkrLtd td dt|  }| j\}}|tj	
| }	t||f|}
x8tt|D ](}|| |	krdt||  |
||f< qW tttt||
|S )aS  Compute the (Moore-Penrose) pseudo-inverse of a matrix.

    Calculate a generalized inverse of a matrix using its
    singular-value decomposition and including all 'large' singular
    values.

    Parameters
    ----------
    a : array, shape (M, N)
        Matrix to be pseudo-inverted
    cond, rcond : float or None
        Cutoff for 'small' singular values.
        Singular values smaller than rcond*largest_singular_value are
        considered zero.

        If None or -1, suitable machine precision is used.

    Returns
    -------
    B : array, shape (N, M)

    Raises LinAlgError if SVD computation does not converge

    Examples
    --------
    >>> from numpy import *
    >>> a = random.randn(9, 6)
    >>> B = linalg.pinv2(a)
    >>> allclose(a, dot(a, dot(B, a)))
    True
    >>> allclose(B, dot(B, dot(a, B)))
    True

    N)Nr   g     @@g    .A)r   r   g      ?)r   
decomp_svdr   charfepseps_array_precisionr   r/   Zmaximumreducer   r   lenr
   r   r   )r$   r   r0   ur*   Zvhtr&   r'   cutoffZpsigmair,   r,   r-   pinv2   s    #
rA   Fc             C   sR   ddl m} |r(t| | jks(td|j| dd\}}dtt|	  S )z
    Return log(det(m)) asserting positive definiteness of m.

    Parameters
    ----------
    m : array-like
        2d array that is positive-definite (and symmetric)

    Returns
    -------
    logdet : float
        The log-determinant of m.
    r   )linalgzm is not symmetric.T)lowerr   )
scipyrB   r!   allTr   Z
cho_factorr	   logZdiagonal)r&   Z
check_symmrB   c_r,   r,   r-   logdet_symm   s    rJ   c       
   
   C   sj  | dd }|j }|j dkr,|dddf }|ddddf }xtdt|D ]}| d| ddd }||ddf t|| dt||ddd   }|t|ddd | }tj||dddf fdd}|t|d krP | | }	|	t|| dt||ddd   }|||ddd   }t|tj| f}qRW |dkrf|dddf }|S )aH  
    Solve a linear system for a Toeplitz correlation matrix.

    A Toeplitz correlation matrix represents the covariance of a
    stationary series with unit variance.

    Parameters
    ----------
    r : array-like
        A vector describing the coefficient matrix.  r[0] is the first
        band next to the diagonal, r[1] is the second band, etc.
    b : array-like
        The right-hand side for which we are solving, i.e. we solve
        Tx = b and return b, where T is the Toeplitz coefficient matrix.

    Returns
    -------
    The solution to the linear system.
    r   r   Nr   )r   )r   r   r<   r!   r   ZouterZconcatenateZr_)
rr%   ZdbZdimr)   jZrfr$   zZrnr,   r,   r-   stationary_solve   s&    
6*
rN   __main__d   
      )Nr   r   )NN)NN)F)-__doc__Z
__future__r   Zstatsmodels.compat.pythonr   r   r/   r!   Zscipy.linalgr   r6   Zscipy.linalg.lapackr   r   r   r	   r
   r   r   r   r   Znumpy.linalgr   r.   r1   Zfinfofloatr9   r8   r:   rA   rJ   rN   __name__ZrandomZrandnZa0Zb0r)   rD   rB   Zx2printmaxabsr,   r,   r,   r-   <module>   s:    
S
'
4
1
$
