U
    ZÊ¹jQ9  ã                   @   s¶   d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	 ddl
mZ ddlmZmZ dd	lmZ dd
lmZmZmZmZ ddlmZmZ G dd„ deƒZG dd„ deeƒZeZdS )é    )ÚCallable)ÚDict)Úsympy_deprecation_warning©Úis_sequence)Úas_inté   )Ú
MatrixBase)ÚMutableRepMatrixÚ	RepMatrix)Ú_iszero)Ú_liupcÚ _row_structure_symbolic_choleskyÚ_cholesky_sparseÚ_LDLdecomposition_sparse)Ú_lower_triangular_solve_sparseÚ_upper_triangular_solve_sparsec                       s  e Zd ZdZe‡ fdd„ƒZedd„ ƒZdd„ Zdd	„ Z	d
d„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd*dd„Zd+dd„ZeedddƒZeedddƒZdd„ Zdd „ Zd,d"d#„Zd-d$d%„Zd&d'„ Zd(d)„ Zeje_eje_eje_eje_eje_eje_‡  ZS ).ÚSparseRepMatrixa  
    A sparse matrix (a matrix with a large number of zero elements).

    Examples
    ========

    >>> from sympy import SparseMatrix, ones
    >>> SparseMatrix(2, 2, range(4))
    Matrix([
    [0, 1],
    [2, 3]])
    >>> SparseMatrix(2, 2, {(1, 1): 2})
    Matrix([
    [0, 0],
    [0, 2]])

    A SparseMatrix can be instantiated from a ragged list of lists:

    >>> SparseMatrix([[1, 2, 3], [1, 2], [1]])
    Matrix([
    [1, 2, 3],
    [1, 2, 0],
    [1, 0, 0]])

    For safety, one may include the expected size and then an error
    will be raised if the indices of any element are out of range or
    (for a flat list) if the total number of elements does not match
    the expected shape:

    >>> SparseMatrix(2, 2, [1, 2])
    Traceback (most recent call last):
    ...
    ValueError: List length (2) != rows*columns (4)

    Here, an error is not raised because the list is not flat and no
    element is out of range:

    >>> SparseMatrix(2, 2, [[1, 2]])
    Matrix([
    [1, 2],
    [0, 0]])

    But adding another element to the first (and only) row will cause
    an error to be raised:

    >>> SparseMatrix(2, 2, [[1, 2, 3]])
    Traceback (most recent call last):
    ...
    ValueError: The location (0, 2) is out of designated range: (1, 1)

    To autosize the matrix, pass None for rows:

    >>> SparseMatrix(None, [[1, 2, 3]])
    Matrix([[1, 2, 3]])
    >>> SparseMatrix(None, {(1, 1): 1, (3, 3): 3})
    Matrix([
    [0, 0, 0, 0],
    [0, 1, 0, 0],
    [0, 0, 0, 0],
    [0, 0, 0, 3]])

    Values that are themselves a Matrix are automatically expanded:

    >>> SparseMatrix(4, 4, {(1, 1): ones(2)})
    Matrix([
    [0, 0, 0, 0],
    [0, 1, 1, 0],
    [0, 1, 1, 0],
    [0, 0, 0, 0]])

    A ValueError is raised if the expanding matrix tries to overwrite
    a different element already present:

    >>> SparseMatrix(3, 3, {(0, 0): ones(2), (1, 1): 2})
    Traceback (most recent call last):
    ...
    ValueError: collision at (1, 1)

    See Also
    ========
    DenseMatrix
    MutableSparseMatrix
    ImmutableSparseMatrix
    c              
      s  t |ƒdkrDt|d tƒrD|d j}|d j}|d  ¡ ‰||ˆfS i ‰t |ƒdkrn|d d krnd d |d g}t |ƒdk�rð|d d… \}}||  kr d kr®n n
d  }}n0d ||fkrÄtdƒ‚nt|d ƒt|d ƒ }}t|d tƒ�rŠ|d }d ||fk�rtd 	||¡ƒ‚‡ fdd„t
|ƒD ƒ}‡ fd	d„t
|ƒD ƒ}	|D ]:}
|	D ].}ˆ  ||
|ƒ¡}|ˆ jk�rL|ˆ|
|f< �qL�qD||ˆfS t|d ttfƒ�rt‡fd
d„}|d  ¡ D ]º\\}}}t|tƒ�r | ¡  ¡ D ]"\\}
}}|||
 || |ƒ �qÚnnt|ttfƒ�rRˆ j|f|Ž\}}‰ˆD ]&\}
}|||
 || ˆ|
|f ƒ �q(nˆ  |¡}|||ˆ  |¡ƒ �q¶nÈt|d ƒ�r<tdd„ |d D ƒƒ }|�sºˆ j|d f|Ž\}}‰n‚|d }t |ƒ|| k�rêtd 	t |ƒ||¡ƒ‚t
|ƒD ]H}
t
|ƒD ]8}||
| |  }ˆ  |¡}|ˆ jk�rþ|ˆ|
|f< �qþ�qò|d k�r�ˆ ¡ }|�rjtdd„ |D ƒƒd nd}|�rŠtdd„ |D ƒƒd nd}nVˆ ¡ D ]L\}
}|
�r°|
|k�sÀ|�r˜||k�r˜td 	|
|fd|d d|d ¡ƒ‚�q˜||ˆfS t |ƒdk�r¨t|d ttfƒ�r¨|d }d}t|ƒD ]`\}
}t|ttfƒ�sD|g}t|ƒD ](\}}|ˆ jk�rLˆ  |¡ˆ|
|f< �qLt|t |ƒƒ}�q&|�r–t |ƒnd}|}||ˆfS tƒ j|Ž \}}}t
|ƒD ]>}
t
|ƒD ].}|||
 |  }|ˆ jk�rÎ|ˆ|
|f< �qÎ�qÂ||ˆfS d S )Nr   r   é   é   z*Pass rows=None and no cols for autosizing.z2{} and {} must be integers for this specification.c                    s   g | ]}ˆ   |¡‘qS © ©Ú_sympify©Ú.0Úi©Úclsr   úT/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/matrices/sparse.pyÚ
<listcomp>Š   s     z;SparseRepMatrix._handle_creation_inputs.<locals>.<listcomp>c                    s   g | ]}ˆ   |¡‘qS r   r   )r   Újr   r   r   r   ‹   s     c                    sN   |rJ| |fˆ kr>|ˆ | |f kr>t d | |f|ˆ | |f ¡ƒ‚|ˆ | |f< d S )Nz)There is a collision at {} for {} and {}.)Ú
ValueErrorÚformat)r   r    Úv)Úsmatr   r   Úupdate–   s      
ÿÿz7SparseRepMatrix._handle_creation_inputs.<locals>.updatec                 s   s   | ]}t |ƒV  qd S ©Nr   r   r   r   r   Ú	<genexpr>®   s     z:SparseRepMatrix._handle_creation_inputs.<locals>.<genexpr>zMThe length of the flat list ({}) does not match the specified size ({} * {}).c                 s   s   | ]\}}|V  qd S r&   r   )r   ÚrÚ_r   r   r   r'   Ä   s     c                 s   s   | ]\}}|V  qd S r&   r   )r   r)   Úcr   r   r   r'   Å   s     z?The location {} is out of the designated range[{}, {}]x[{}, {}])ÚlenÚ
isinstancer	   ÚrowsÚcolsÚtodokr!   r   r   r"   Úranger   ÚzeroÚdictr   ÚitemsÚlistÚtupleÚ_handle_creation_inputsr   ÚanyÚkeysÚmaxÚ	enumerateÚsuper)r   ÚargsÚkwargsr-   r.   r(   r*   ÚopZrow_indicesZcol_indicesr   r    Úvaluer%   r#   Zvvr)   ZflatZ	flat_listr8   ÚrowZmat©Ú	__class__)r   r$   r   r6   k   sÌ    



ÿ ÿÿ
"
ÿ
  þÿ

 "     þÿ
"
z'SparseRepMatrix._handle_creation_inputsc                 C   s   t dddd� |  ¡ S )Nz�
            The private _smat attribute of SparseMatrix is deprecated. Use the
            .todok() method instead.
            z1.9z$deprecated-private-matrix-attributes)Zdeprecated_since_versionZactive_deprecations_target)r   r/   ©Úselfr   r   r   Ú_smatì   s    ú	zSparseRepMatrix._smatc                 K   s(   | j | dd¡| dt¡| dd¡d�S )NÚmethodÚLDLÚ
iszerofuncÚtry_block_diagF)rF   rH   rI   )ÚinvÚgetr   )rD   r=   r   r   r   Ú_eval_inverseú   s    

þzSparseRepMatrix._eval_inversec                 C   sT   t |ƒstdƒ‚i }|  ¡  ¡ D ] \}}||ƒ}|dkr |||< q |  | j| j|¡S )aX  Apply a function to each element of the matrix.

        Examples
        ========

        >>> from sympy import SparseMatrix
        >>> m = SparseMatrix(2, 2, lambda i, j: i*2+j)
        >>> m
        Matrix([
        [0, 1],
        [2, 3]])
        >>> m.applyfunc(lambda i: 2*i)
        Matrix([
        [0, 2],
        [4, 6]])

        z`f` must be callable.r   )ÚcallableÚ	TypeErrorr/   r3   Ú_newr-   r.   )rD   ÚfZdokÚkr#   Zfvr   r   r   Ú	applyfuncÿ   s    
zSparseRepMatrix.applyfuncc                 C   s   ddl m} || ƒS )z,Returns an Immutable version of this Matrix.r   )ÚImmutableSparseMatrix)Z	immutablerS   )rD   rS   r   r   r   Úas_immutable  s    zSparseRepMatrix.as_immutablec                 C   s   t | ƒS )aC  Returns a mutable version of this matrix.

        Examples
        ========

        >>> from sympy import ImmutableMatrix
        >>> X = ImmutableMatrix([[1, 2], [3, 4]])
        >>> Y = X.as_mutable()
        >>> Y[1, 1] = 5 # Can set values in Y
        >>> Y
        Matrix([
        [1, 2],
        [3, 5]])
        )ÚMutableSparseMatrixrC   r   r   r   Ú
as_mutable$  s    zSparseRepMatrix.as_mutablec                    s&   ‡ fdd„t ˆ  ¡  ¡ dd„ d�D ƒS )a£  Returns a column-sorted list of non-zero elements of the matrix.

        Examples
        ========

        >>> from sympy import SparseMatrix
        >>> a=SparseMatrix(((1, 2), (3, 4)))
        >>> a
        Matrix([
        [1, 2],
        [3, 4]])
        >>> a.CL
        [(0, 0, 1), (1, 0, 3), (0, 1, 2), (1, 1, 4)]

        See Also
        ========

        sympy.matrices.sparse.SparseMatrix.row_list
        c                    s   g | ]}t |ˆ | f ƒ‘qS r   ©r5   ©r   rQ   rC   r   r   r   I  s     z,SparseRepMatrix.col_list.<locals>.<listcomp>c                 S   s   t t| ƒƒS r&   )r4   Úreversed)rQ   r   r   r   Ú<lambda>I  ó    z*SparseRepMatrix.col_list.<locals>.<lambda>©Úkey)Úsortedr/   r8   rC   r   rC   r   Úcol_list5  s    zSparseRepMatrix.col_listc                 C   s   t |  ¡ ƒS )z2Returns the number of non-zero elements in Matrix.)r+   r/   rC   r   r   r   ÚnnzK  s    zSparseRepMatrix.nnzc                    s"   ‡ fdd„t ˆ  ¡  ¡ td�D ƒS )a¢  Returns a row-sorted list of non-zero elements of the matrix.

        Examples
        ========

        >>> from sympy import SparseMatrix
        >>> a = SparseMatrix(((1, 2), (3, 4)))
        >>> a
        Matrix([
        [1, 2],
        [3, 4]])
        >>> a.RL
        [(0, 0, 1), (0, 1, 2), (1, 0, 3), (1, 1, 4)]

        See Also
        ========

        sympy.matrices.sparse.SparseMatrix.col_list
        c                    s   g | ]}t |ˆ | f ƒ‘qS r   rW   rX   rC   r   r   r   c  s     z,SparseRepMatrix.row_list.<locals>.<listcomp>r\   )r^   r/   r8   r4   rC   r   rC   r   Úrow_listO  s    
ÿzSparseRepMatrix.row_listc                 C   s   ||  S )z"Scalar element-wise multiplicationr   )rD   Zscalarr   r   r   Úscalar_multiplyf  s    zSparseRepMatrix.scalar_multiplyrG   c                 C   s   | j }||  j|d�| | S )aô  Return the least-square fit to the data.

        By default the cholesky_solve routine is used (method='CH'); other
        methods of matrix inversion can be used. To find out which are
        available, see the docstring of the .inv() method.

        Examples
        ========

        >>> from sympy import SparseMatrix, Matrix, ones
        >>> A = Matrix([1, 2, 3])
        >>> B = Matrix([2, 3, 4])
        >>> S = SparseMatrix(A.row_join(B))
        >>> S
        Matrix([
        [1, 2],
        [2, 3],
        [3, 4]])

        If each line of S represent coefficients of Ax + By
        and x and y are [2, 3] then S*xy is:

        >>> r = S*Matrix([2, 3]); r
        Matrix([
        [ 8],
        [13],
        [18]])

        But let's add 1 to the middle value and then solve for the
        least-squares value of xy:

        >>> xy = S.solve_least_squares(Matrix([8, 14, 18])); xy
        Matrix([
        [ 5/3],
        [10/3]])

        The error is given by S*xy - r:

        >>> S*xy - r
        Matrix([
        [1/3],
        [1/3],
        [1/3]])
        >>> _.norm().n(2)
        0.58

        If a different xy is used, the norm will be higher:

        >>> xy += ones(2, 1)/10
        >>> (S*xy - r).norm().n(2)
        1.5

        ©rF   )ÚTrJ   )rD   ÚrhsrF   Útr   r   r   Úsolve_least_squaresj  s    6z#SparseRepMatrix.solve_least_squaresc                 C   sH   | j s2| j| jk rtdƒ‚qD| j| jkrDtdƒ‚n| j|d� |¡S dS )z–Return solution to self*soln = rhs using given inversion method.

        For a list of possible inversion methods, see the .inv() docstring.
        zUnder-determined system.z]For over-determined system, M, having more rows than columns, try M.solve_least_squares(rhs).rc   N)Z	is_squarer-   r.   r!   rJ   Úmultiply)rD   re   rF   r   r   r   Úsolve£  s    

zSparseRepMatrix.solveNzAlternate faster representationc                 C   s   t | ƒS r&   )r   rC   r   r   r   Úliupc´  s    zSparseRepMatrix.liupcc                 C   s   t | ƒS r&   )r   rC   r   r   r   Úrow_structure_symbolic_cholesky·  s    z/SparseRepMatrix.row_structure_symbolic_choleskyTc                 C   s   t | |d�S ©N)Ú	hermitian)r   ©rD   rm   r   r   r   Úcholeskyº  s    zSparseRepMatrix.choleskyc                 C   s   t | |d�S rl   )r   rn   r   r   r   ÚLDLdecomposition½  s    z SparseRepMatrix.LDLdecompositionc                 C   s
   t | |ƒS r&   )r   ©rD   re   r   r   r   Úlower_triangular_solveÀ  s    z&SparseRepMatrix.lower_triangular_solvec                 C   s
   t | |ƒS r&   )r   rq   r   r   r   Úupper_triangular_solveÃ  s    z&SparseRepMatrix.upper_triangular_solve)rG   )rG   )T)T)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úclassmethodr6   ÚpropertyrE   rL   rR   rT   rV   r_   r`   ra   rb   rg   ri   ZRLZCLrj   rk   ro   rp   rr   rs   r   r   r   r   Ú__classcell__r   r   rA   r   r      s<   U 
 
9


r   c                   @   s   e Zd Zedd„ ƒZdS )rU   c                 O   s*   | j ||Ž\}}}|  |||¡}|  |¡S r&   )r6   Z_smat_to_DomainMatrixZ_fromrep)r   r<   r=   r-   r.   r$   Úrepr   r   r   rO   Ð  s    zMutableSparseMatrix._newN)rt   ru   rv   rx   rO   r   r   r   r   rU   Î  s   rU   N)Úcollections.abcr   Zsympy.core.containersr   Zsympy.utilities.exceptionsr   Zsympy.utilities.iterablesr   Zsympy.utilities.miscr   Z
matrixbaser	   Z	repmatrixr
   r   Z	utilitiesr   Zdecompositionsr   r   r   r   Zsolversr   r   r   rU   ZSparseMatrixr   r   r   r   Ú<module>   s      <