3
OdR                 @   s  d dl mZ d dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZ d dlmZ d dlmZ d dlZddlmZ d	Zyd dljZW n ek
r   d
ZY nX e ZdddddddgZG dd deZdd Zdd ZdddZdddde fddZdddZ dd Z!dddZ"dS )    )warnN)asarray)isspmatrix_cscisspmatrix_csr
isspmatrixSparseEfficiencyWarning
csc_matrix
csr_matrix)is_pydata_spmatrix)LinAlgError   )_superluFT
use_solverspsolvespluspilu
factorizedMatrixRankWarningspsolve_triangularc               @   s   e Zd ZdS )r   N)__name__
__module____qualname__ r   r   W/var/www/html/virt/lib64/python3.6/site-packages/scipy/sparse/linalg/dsolve/linsolve.pyr      s   c              K   s6   d| kr| d t  d< tr2d| kr2tj| d d dS )ac  
    Select default sparse direct solver to be used.

    Parameters
    ----------
    useUmfpack : bool, optional
        Use UMFPACK over SuperLU. Has effect only if scikits.umfpack is
        installed. Default: True
    assumeSortedIndices : bool, optional
        Allow UMFPACK to skip the step of sorting indices for a CSR/CSC matrix.
        Has effect only if useUmfpack is True and scikits.umfpack is installed.
        Default: False

    Notes
    -----
    The default sparse solver is umfpack when available
    (scikits.umfpack is installed). This can be changed by passing
    useUmfpack = False, which then causes the always present SuperLU
    based solver to be used.

    Umfpack requires a CSR/CSC matrix to have sorted column/row indices. If
    sure that the matrix fulfills this, pass ``assumeSortedIndices=True``
    to gain some speed.

    
useUmfpackassumeSortedIndices)r   N)globalsr   umfpack	configure)kwargsr   r   r   r      s    c             C   s   t jt jfdt jt jfdt jt jfdt jt jfdi}t j| jj }t j| jjj }y|||f }W n( t	k
r   d||f }t
|Y nX |d d }tj| }t j| jdt jd	|_t j| jdt jd	|_||fS )
z8Get umfpack family string given the sparse matrix dtype.ZdiZzidlZzlzmonly float64 or complex128 matrices with int32 or int64 indices are supported! (got: matrix: %s, indices: %s)r   lF)copydtype)npfloat64Zint32Z
complex128Zint64Z
sctypeDictr#   nameindicesKeyError
ValueErrorr"   arrayindptr)AZ	_familiesZf_typeZi_typefamilymsgZA_newr   r   r   _get_umf_family<   s"    

r/   c          
   C   sD  t | r| j j } t| p"t| s6t| } tdt t|pDt |}|sRt	|}|j
dkpr|j
dkor|jd dk}| j  | j } tj| j|j}| j|kr| j|} |j|kr|j|}| j\}}||krtd||ff ||jd krtd| j|jd f |ot}|r|r|r.|j }	n|}	t	|	| jdj }	trRtd| jjd	krhtd
t| \}
} tj|
}|jtj| |	dd}n|r|r|j }d}|s*t| rd}nd}t|d}tj || j!| j"| j#| j$|||d\}}|dkrtdt% |j&tj' |r@|j }nt(| }t|pBt |sXtdt t|}g }g }g }xt)|jd D ]z}tj	|dd|f j* j }||}tj+|}|jd }|j,| |j,tj-||t.d |j,tj	|| | jd qtW tj/|}tj/|}tj/|}| j0|||ff|j| jd}t |r@|j0|}|S )a  Solve the sparse linear system Ax=b, where b may be a vector or a matrix.

    Parameters
    ----------
    A : ndarray or sparse matrix
        The square matrix A will be converted into CSC or CSR form
    b : ndarray or sparse matrix
        The matrix or vector representing the right hand side of the equation.
        If a vector, b.shape must be (n,) or (n, 1).
    permc_spec : str, optional
        How to permute the columns of the matrix for sparsity preservation.
        (default: 'COLAMD')

        - ``NATURAL``: natural ordering.
        - ``MMD_ATA``: minimum degree ordering on the structure of A^T A.
        - ``MMD_AT_PLUS_A``: minimum degree ordering on the structure of A^T+A.
        - ``COLAMD``: approximate minimum degree column ordering
    use_umfpack : bool, optional
        if True (default) then use umfpack for the solution.  This is
        only referenced if b is a vector and ``scikit-umfpack`` is installed.

    Returns
    -------
    x : ndarray or sparse matrix
        the solution of the sparse linear equation.
        If b is a vector, then x is a vector of size A.shape[1]
        If b is a matrix, then x is a matrix of size (A.shape[1], b.shape[1])

    Notes
    -----
    For solving the matrix expression AX = B, this solver assumes the resulting
    matrix X is sparse, as is often the case for very sparse inputs.  If the
    resulting X is dense, the construction of this sparse result will be
    relatively expensive.  In that case, consider converting A to a dense
    matrix and using scipy.linalg.solve or its variants.

    Examples
    --------
    >>> from scipy.sparse import csc_matrix
    >>> from scipy.sparse.linalg import spsolve
    >>> A = csc_matrix([[3, 2, 0], [1, -1, 0], [0, 5, 1]], dtype=float)
    >>> B = csc_matrix([[2, 0], [-1, 0], [2, 0]], dtype=float)
    >>> x = spsolve(A, B)
    >>> np.allclose(A.dot(x).todense(), B.todense())
    True
    z.spsolve requires A be CSC or CSR matrix formatr      z$matrix must be square (has shape %s)r   z)matrix - rhs dimension mismatch (%s - %s))r#   zScikits.umfpack not installed.dDzZconvert matrix data to double, please, using .astype(), or set linsolve.useUmfpack = FalseT)autoTransposeF)ColPerm)optionszMatrix is exactly singularzCspsolve is more efficient when sparse b is in the CSC matrix formatN)shaper#   )1r
   to_scipy_sparsetocscr   r   r   r   r   r   r   ndimr5   sum_duplicatesasfptyper$   Zpromote_typesr#   astyper)   r   ZtoarrayZravelnoScikitRuntimeErrorcharr/   r   UmfpackContextZlinsolve	UMFPACK_Adictr   Zgssvnnzdatar'   r+   r   fillnanr   rangeZtodenseZflatnonzeroappendfullintZconcatenate	__class__)r,   b
permc_specZuse_umfpackZb_is_sparseZb_is_vectorZresult_dtypeMNZb_vec
umf_familyumfxflagr4   infoZ
AfactsolveZ	data_segsZrow_segsZcol_segsjZbjZxjwZsegment_lengthZsparse_dataZ
sparse_rowZ
sparse_colr   r   r   r   [   s    0"














 




c       
   
   C   s   t | r(t| ddd}| j j } nt}t| sFt| } tdt | j  | j	 } | j
\}}||krptdt||||d}	|dk	r|	j| |	d d	krd
|	d< tj|| j| j| j| j|d|	dS )a^  
    Compute the LU decomposition of a sparse, square matrix.

    Parameters
    ----------
    A : sparse matrix
        Sparse matrix to factorize. Should be in CSR or CSC format.
    permc_spec : str, optional
        How to permute the columns of the matrix for sparsity preservation.
        (default: 'COLAMD')

        - ``NATURAL``: natural ordering.
        - ``MMD_ATA``: minimum degree ordering on the structure of A^T A.
        - ``MMD_AT_PLUS_A``: minimum degree ordering on the structure of A^T+A.
        - ``COLAMD``: approximate minimum degree column ordering

    diag_pivot_thresh : float, optional
        Threshold used for a diagonal entry to be an acceptable pivot.
        See SuperLU user's guide for details [1]_
    relax : int, optional
        Expert option for customizing the degree of relaxing supernodes.
        See SuperLU user's guide for details [1]_
    panel_size : int, optional
        Expert option for customizing the panel size.
        See SuperLU user's guide for details [1]_
    options : dict, optional
        Dictionary containing additional expert options to SuperLU.
        See SuperLU user guide [1]_ (section 2.4 on the 'Options' argument)
        for more details. For example, you can specify
        ``options=dict(Equil=False, IterRefine='SINGLE'))``
        to turn equilibration off and perform a single iterative refinement.

    Returns
    -------
    invA : scipy.sparse.linalg.SuperLU
        Object, which has a ``solve`` method.

    See also
    --------
    spilu : incomplete LU decomposition

    Notes
    -----
    This function uses the SuperLU library.

    References
    ----------
    .. [1] SuperLU http://crd.lbl.gov/~xiaoye/SuperLU/

    Examples
    --------
    >>> from scipy.sparse import csc_matrix
    >>> from scipy.sparse.linalg import splu
    >>> A = csc_matrix([[1., 0., 0.], [5., 0., 2.], [0., -1., 0.]], dtype=float)
    >>> B = splu(A)
    >>> x = np.array([1., 2., 3.], dtype=float)
    >>> B.solve(x)
    array([ 1. , -3. , -1.5])
    >>> A.dot(B.solve(x))
    array([ 1.,  2.,  3.])
    >>> B.solve(A.dot(x))
    array([ 1.,  2.,  3.])
    )clsc             W   s   | t | S )N)r   )rV   ar   r   r   <lambda>7  s    zsplu.<locals>.<lambda>zsplu requires CSC matrix formatzcan only factor square matrices)DiagPivotThreshr3   	PanelSizeRelaxNr3   NATURALTSymmetricModeF)csc_construct_funcilur4   )r
   typer6   r7   r   r   r   r   r9   r:   r5   r)   rA   updater   gstrfrB   rC   r'   r+   )
r,   rL   diag_pivot_threshrelax
panel_sizer4   r^   rM   rN   _optionsr   r   r   r      s*    B



c	          
   C   s   t | r(t| ddd}	| j j } nt}	t| sFt| } tdt | j  | j	 } | j
\}
}|
|krptdt|||||||d}|dk	r|j| |d d	krd
|d< tj|| j| j| j| j|	d
|dS )aB  
    Compute an incomplete LU decomposition for a sparse, square matrix.

    The resulting object is an approximation to the inverse of `A`.

    Parameters
    ----------
    A : (N, N) array_like
        Sparse matrix to factorize
    drop_tol : float, optional
        Drop tolerance (0 <= tol <= 1) for an incomplete LU decomposition.
        (default: 1e-4)
    fill_factor : float, optional
        Specifies the fill ratio upper bound (>= 1.0) for ILU. (default: 10)
    drop_rule : str, optional
        Comma-separated string of drop rules to use.
        Available rules: ``basic``, ``prows``, ``column``, ``area``,
        ``secondary``, ``dynamic``, ``interp``. (Default: ``basic,area``)

        See SuperLU documentation for details.

    Remaining other options
        Same as for `splu`

    Returns
    -------
    invA_approx : scipy.sparse.linalg.SuperLU
        Object, which has a ``solve`` method.

    See also
    --------
    splu : complete LU decomposition

    Notes
    -----
    To improve the better approximation to the inverse, you may need to
    increase `fill_factor` AND decrease `drop_tol`.

    This function uses the SuperLU library.

    Examples
    --------
    >>> from scipy.sparse import csc_matrix
    >>> from scipy.sparse.linalg import spilu
    >>> A = csc_matrix([[1., 0., 0.], [5., 0., 2.], [0., -1., 0.]], dtype=float)
    >>> B = spilu(A)
    >>> x = np.array([1., 2., 3.], dtype=float)
    >>> B.solve(x)
    array([ 1. , -3. , -1.5])
    >>> A.dot(B.solve(x))
    array([ 1.,  2.,  3.])
    >>> B.solve(A.dot(x))
    array([ 1.,  2.,  3.])
    )rV   c             W   s   | t | S )N)r   )rV   rW   r   r   r   rX     s    zspilu.<locals>.<lambda>zsplu requires CSC matrix formatzcan only factor square matrices)ZILU_DropRuleZILU_DropTolZILU_FillFactorrY   r3   rZ   r[   Nr3   r\   Tr]   )r^   r_   r4   )r
   r`   r6   r7   r   r   r   r   r9   r:   r5   r)   rA   ra   r   rb   rB   rC   r'   r+   )r,   Zdrop_tolZfill_factorZ	drop_rulerL   rc   rd   re   r4   r^   rM   rN   rf   r   r   r   r   V  s.    9



c                s   t  r j j  trtr$tdt s>t  tdt	  j
   jjdkrZtdt \} tj|j   fdd}|S t jS dS )a  
    Return a function for solving a sparse linear system, with A pre-factorized.

    Parameters
    ----------
    A : (N, N) array_like
        Input.

    Returns
    -------
    solve : callable
        To solve the linear system of equations given in `A`, the `solve`
        callable should be passed an ndarray of shape (N,).

    Examples
    --------
    >>> from scipy.sparse.linalg import factorized
    >>> A = np.array([[ 3. ,  2. , -1. ],
    ...               [ 2. , -2. ,  4. ],
    ...               [-1. ,  0.5, -1. ]])
    >>> solve = factorized(A) # Makes LU decomposition.
    >>> rhs1 = np.array([1, -2, 0])
    >>> solve(rhs1) # Uses the LU factors.
    array([ 1., -2., -2.])

    zScikits.umfpack not installed.zsplu requires CSC matrix formatr1   zZconvert matrix data to double, please, using .astype(), or set linsolve.useUmfpack = Falsec                s   j tj | ddS )NT)r2   )solver   r@   )rK   )r,   rP   r   r   rg     s    zfactorized.<locals>.solveN)r
   r6   r7   r   r<   r=   r   r   r   r   r:   r#   r>   r)   r/   r   r?   numericr   rg   )r,   rO   rg   r   )r,   rP   r   r     s"    


c             C   s,  t | r| j j } t| s0tdt t| } n|s<| j } | jd | jd kr`t	dj
| j| j  tj|}|jdkrt	dj
|j| jd |jd krt	dj
| j|jtj| j|tj}|rtj|j|dd	r|}nt	d
j
|j|n|j|dd}|rtt|}ntt|d dd}x|D ]}	| j|	 }
| j|	d  }|rl|d }t|
|d }n|
}t|
d |}| r||
ks| j| |	k rtdj
|	| j| |	krtdj
|	| j| | j| }| j| }||	  tj|| j|8  < |s2||	  | j|   < q2W |S )a  
    Solve the equation `A x = b` for `x`, assuming A is a triangular matrix.

    Parameters
    ----------
    A : (M, M) sparse matrix
        A sparse square triangular matrix. Should be in CSR format.
    b : (M,) or (M, N) array_like
        Right-hand side matrix in `A x = b`
    lower : bool, optional
        Whether `A` is a lower or upper triangular matrix.
        Default is lower triangular matrix.
    overwrite_A : bool, optional
        Allow changing `A`. The indices of `A` are going to be sorted and zero
        entries are going to be removed.
        Enabling gives a performance gain. Default is False.
    overwrite_b : bool, optional
        Allow overwriting data in `b`.
        Enabling gives a performance gain. Default is False.
        If `overwrite_b` is True, it should be ensured that
        `b` has an appropriate dtype to be able to store the result.
    unit_diagonal : bool, optional
        If True, diagonal elements of `a` are assumed to be 1 and will not be
        referenced.

        .. versionadded:: 1.4.0

    Returns
    -------
    x : (M,) or (M, N) ndarray
        Solution to the system `A x = b`. Shape of return matches shape of `b`.

    Raises
    ------
    LinAlgError
        If `A` is singular or not triangular.
    ValueError
        If shape of `A` or shape of `b` do not match the requirements.

    Notes
    -----
    .. versionadded:: 0.19.0

    Examples
    --------
    >>> from scipy.sparse import csr_matrix
    >>> from scipy.sparse.linalg import spsolve_triangular
    >>> A = csr_matrix([[3, 0, 0], [1, -1, 0], [2, 0, 1]], dtype=float)
    >>> B = np.array([[2, 0], [-1, 0], [2, 0]], dtype=float)
    >>> x = spsolve_triangular(A, B)
    >>> np.allclose(A.dot(x), B)
    True
    z8CSR matrix format is required. Converting to CSR matrix.r   r   z.A must be a square matrix but its shape is {}.r0   z,b must have 1 or 2 dims but its shape is {}.zThe size of the dimensions of A must be equal to the size of the first dimension of b but the shape of A is {} and the shape of b is {}.Z	same_kind)Zcastingz5Cannot overwrite b (dtype {}) with result of type {}.T)r"   z#A is singular: diagonal {} is zero.z*A is not triangular: A[{}, {}] is nonzero.)r   r0   ri   )r
   r6   Ztocsrr   r   r   r	   r"   r5   r)   formatr9   r$   Z
asanyarrayr8   Zresult_typerC   r%   Zcan_castr#   r;   rF   lenr+   slicer'   r   dotT)r,   rK   lowerZoverwrite_AZoverwrite_bZunit_diagonalZx_dtyperQ   Zrow_indicesiZindptr_startZindptr_stopZA_diagonal_index_row_iZA_off_diagonal_indices_row_iZA_column_indices_in_row_iZA_values_in_row_ir   r   r   r     sj    8






)NT)NNNNNNNN)TFFF)#warningsr   Znumpyr$   r   Zscipy.sparser   r   r   r   r   r	   Zscipy.sparse.sputilsr
   Zscipy.linalgr   r"    r   r<   Zscikits.umfpackr   ImportErrorr   __all__UserWarningr   r   r/   r   rA   r   r   r   r   r   r   r   r   <module>   s6    


 a 
Z: 