a
    RG5d4                     @   s   d Z ddlmZ ddlmZmZmZ ddlmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZ G dd deZddlmZ d	S )
a  

Module for the DDM class.

The DDM class is an internal representation used by DomainMatrix. The letters
DDM stand for Dense Domain Matrix. A DDM instance represents a matrix using
elements from a polynomial Domain (e.g. ZZ, QQ, ...) in a dense-matrix
representation.

Basic usage:

    >>> from sympy import ZZ, QQ
    >>> from sympy.polys.matrices.ddm import DDM
    >>> A = DDM([[ZZ(0), ZZ(1)], [ZZ(-1), ZZ(0)]], (2, 2), ZZ)
    >>> A.shape
    (2, 2)
    >>> A
    [[0, 1], [-1, 0]]
    >>> type(A)
    <class 'sympy.polys.matrices.ddm.DDM'>
    >>> A @ A
    [[-1, 0], [0, -1]]

The ddm_* functions are designed to operate on DDM as well as on an ordinary
list of lists:

    >>> from sympy.polys.matrices.dense import ddm_idet
    >>> ddm_idet(A, QQ)
    1
    >>> ddm_idet([[0, 1], [-1, 0]], QQ)
    1
    >>> A
    [[-1, 0], [0, -1]]

Note that ddm_idet modifies the input matrix in-place. It is recommended to
use the DDM.det method as a friendlier interface to this instead which takes
care of copying the matrix:

    >>> B = DDM([[ZZ(0), ZZ(1)], [ZZ(-1), ZZ(0)]], (2, 2), ZZ)
    >>> B.det()
    1

Normally DDM would not be used directly and is just part of the internal
representation of DomainMatrix which adds further functionality including e.g.
unifying domains.

The dense format used by DDM is a list of lists of elements e.g. the 2x2
identity matrix is like [[1, 0], [0, 1]]. The DDM class itself is a subclass
of list and its list items are plain lists. Elements are accessed as e.g.
ddm[i][j] where ddm[i] gives the ith row and ddm[i][j] gets the element in the
jth column of that row. Subclassing list makes e.g. iteration and indexing
very efficient. We do not override __getitem__ because it would lose that
benefit.

The core routines are implemented by the ddm_* functions defined in dense.py.
Those functions are intended to be able to operate on a raw list-of-lists
representation of matrices with most functions operating in-place. The DDM
class takes care of copying etc and also stores a Domain object associated
with its elements. This makes it possible to implement things like A + B with
domain checking and also shape checking so that the list of lists
representation is friendlier.

    )chain   )DMBadInputErrorDMShapeErrorDMDomainError)ddm_transposeddm_iaddddm_isubddm_inegddm_imul	ddm_irmulddm_imatmul	ddm_irrefddm_idetddm_iinvddm_ilu_splitddm_ilu_solveddm_berkc                       s  e Zd ZdZdZ f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 Zdd Zdd Zdd Zdd Zdd  Z fd!d"Zd#d$ Zed%d& Zed'd( Zed)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!ed;d< Z"d=d> Z#d?d@ Z$dAdB Z%dCdD Z&dEdF Z'dGdH Z(dIdJ Z)dKdL Z*dMdN Z+dOdP Z,dQdR Z-dSdT Z.dUdV Z/dWdX Z0dYdZ Z1d[d\ Z2d]d^ Z3d_d` Z4dadb Z5dcdd Z6dedf Z7dgdh Z8  Z9S )iDDMzDense matrix based on polys domain elements

    This is a list subclass and is a wrapper for a list of lists that supports
    basic matrix arithmetic +, -, *, **.
    densec                    sZ   t  | | | _ \| _| _\} || _t| |krNt fdd| D sVtdd S )Nc                 3   s   | ]}t | kV  qd S N)len.0rown T/var/www/html/django/DPS/env/lib/python3.9/site-packages/sympy/polys/matrices/ddm.py	<genexpr>c       zDDM.__init__.<locals>.<genexpr>zInconsistent row-list/shape)	super__init__shaperowscolsdomainr   allr   )selfrowslistr#   r&   m	__class__r   r   r"   ^   s
    "zDDM.__init__c                 C   s   | | | S r   r   )r(   ijr   r   r   getitemf   s    zDDM.getitemc                 C   s   || | |< d S r   r   )r(   r-   r.   valuer   r   r   setitemi   s    zDDM.setitemc                    sV    fdd| | D }t |}|r.t |d nt t| jd   }t|||f| jS )Nc                    s   g | ]}|  qS r   r   r   slice2r   r   
<listcomp>m   r    z%DDM.extract_slice.<locals>.<listcomp>r   r   )r   ranger#   r   r&   )r(   slice1r3   ddmr$   r%   r   r2   r   extract_slicel   s    &zDDM.extract_slicec                    sH   g }|D ]$}| |  |  fdd|D  qt|t|t|f| jS )Nc                    s   g | ]} | qS r   r   r   r.   rowir   r   r4   v   r    zDDM.extract.<locals>.<listcomp>)appendr   r   r&   )r(   r$   r%   r7   r-   r   r:   r   extractr   s
    zDDM.extractc                 C   s   t | S r   )listr(   r   r   r   to_listy   s    zDDM.to_listc                 C   s   g }| D ]}| | q|S r   extend)r(   flatr   r   r   r   to_list_flat|   s    zDDM.to_list_flatc                 C   s
   t | S r   )r   from_iterabler?   r   r   r   flatiter   s    zDDM.flatiterc                 C   s   g }| D ]}| | q|S r   rA   )r(   itemsr   r   r   r   rC      s    zDDM.flatc                 C   s   dd t | D S )Nc                 S   s,   i | ]$\}}t |D ]\}}||f|qqS r   	enumerate)r   r-   r   r.   er   r   r   
<dictcomp>   r    zDDM.to_dok.<locals>.<dictcomp>rH   r?   r   r   r   to_dok   s    z
DDM.to_dokc                 C   s   | S r   r   r?   r   r   r   to_ddm   s    z
DDM.to_ddmc                 C   s   t | | j| jS r   )SDM	from_listr#   r&   r?   r   r   r   to_sdm   s    z
DDM.to_sdmc                    s8   | j  kr|  S  fdd| D }t|| j S )Nc                 3   s"   | ]} fd d|D V  qdS )c                    s   g | ]}  |qS r   )convert_from)r   rJ   KZKoldr   r   r4      r    z,DDM.convert_to.<locals>.<genexpr>.<listcomp>Nr   r   rR   r   r   r      r    z!DDM.convert_to.<locals>.<genexpr>)r&   copyr   r#   )r(   rS   r$   r   rR   r   
convert_to   s
    zDDM.convert_toc                 C   s   dd | D }dd | S )Nc                 S   s    g | ]}d d tt| qS )[%s], )joinmapstrr   r   r   r   r4      r    zDDM.__str__.<locals>.<listcomp>rV   rW   )rX   )r(   Zrowsstrr   r   r   __str__   s    zDDM.__str__c                 C   s(   t | j}t| }d||| j| jf S )Nz%s(%s, %s, %s))type__name__r>   __repr__r#   r&   )r(   clsr$   r   r   r   r^      s    

zDDM.__repr__c                    s&   t |tsdS t |o$| j|jkS )NF)
isinstancer   r!   __eq__r&   r(   otherr+   r   r   ra      s    
z
DDM.__eq__c                 C   s   |  | S r   )ra   rb   r   r   r   __ne__   s    z
DDM.__ne__c                    s2   |j |\}  fddt|D }t|||S )Nc                 3   s   | ]}g  V  qd S r   r   r   _r   zr   r   r      r    zDDM.zeros.<locals>.<genexpr>)zeror5   r   )r_   r#   r&   r*   r)   r   rg   r   zeros   s    z	DDM.zerosc                    s2   |j |\}  fddt|D }t|||S )Nc                 3   s   | ]}g  V  qd S r   r   re   r   oner   r   r      r    zDDM.ones.<locals>.<genexpr>)rl   r5   r   )r_   r#   r&   r*   Zrowlistr   rk   r   ones   s    zDDM.onesc                 C   s4   |j }| ||f|}t|D ]}||| |< q|S r   )rl   rj   r5   )r_   sizer&   rl   r7   r-   r   r   r   eye   s
    zDDM.eyec                 C   s   dd | D }t || j| jS )Nc                 s   s   | ]}|d d  V  qd S r   r   r   r   r   r   r      r    zDDM.copy.<locals>.<genexpr>)r   r#   r&   )r(   Zcopyrowsr   r   r   rT      s    zDDM.copyc                 C   s4   | j \}}|rt| }n
g g| }t|||f| jS r   )r#   r   r   r&   )r(   r$   r%   ZddmTr   r   r   	transpose   s
    


zDDM.transposec                 C   s   t |tstS | |S r   )r`   r   NotImplementedaddabr   r   r   __add__   s    
zDDM.__add__c                 C   s   t |tstS | |S r   )r`   r   rq   subrs   r   r   r   __sub__   s    
zDDM.__sub__c                 C   s   |   S r   )negrt   r   r   r   __neg__   s    zDDM.__neg__c                 C   s   || j v r| |S tS d S r   r&   mulrq   rs   r   r   r   __mul__   s    

zDDM.__mul__c                 C   s   || j v r| |S tS d S r   r|   rs   r   r   r   __rmul__   s    

zDDM.__rmul__c                 C   s   t |tr| |S tS d S r   )r`   r   matmulrq   rs   r   r   r   
__matmul__   s    

zDDM.__matmul__c                 C   sL   |j |j kr&d|j ||j f }t|||krHd|j||jf }t|d S )NzDomain mismatch: %s %s %szShape mismatch: %s %s %s)r&   r   r#   r   )r_   rt   opru   ashapebshapemsgr   r   r   _check   s    z
DDM._checkc                 C   s,   |  | d|| j|j |  }t|| |S )za + b+)r   r#   rT   r   rt   ru   cr   r   r   rr      s    
zDDM.addc                 C   s,   |  | d|| j|j |  }t|| |S )za - b-)r   r#   rT   r	   r   r   r   r   rw      s    
zDDM.subc                 C   s   |   }t| |S )z-a)rT   r
   rs   r   r   r   ry     s    zDDM.negc                 C   s   |   }t|| |S r   )rT   r   r   r   r   r   r}   
  s    
zDDM.mulc                 C   s   |   }t|| |S r   )rT   r   r   r   r   r   rmul  s    
zDDM.rmulc                 C   sH   | j \}}|j \}}| | d||| | ||f| j}t|| | |S )za @ b (matrix product)*)r#   r   rj   r&   r   )rt   ru   r*   oZo2r   r   r   r   r   r     s    

z
DDM.matmulc                 C   sD   | j |j ksJ | j|jks J dd t| |D }t|| j | jS )Nc                 S   s$   g | ]\}}d d t ||D qS )c                 S   s   g | ]\}}|| qS r   r   )r   ZaijZbijr   r   r   r4      r    z2DDM.mul_elementwise.<locals>.<listcomp>.<listcomp>)zip)r   aibir   r   r   r4      r    z'DDM.mul_elementwise.<locals>.<listcomp>)r#   r&   r   r   r   r   r   r   mul_elementwise  s    zDDM.mul_elementwisec                 G   s   t |  }| j\}}| j}|D ]P}|j\}}||ks:J |j|ksHJ ||7 }t|D ]\}	}
||	 |
 qXq t|||f| jS )a	  Horizontally stacks :py:class:`~.DDM` matrices.

        Examples
        ========

        >>> from sympy import ZZ
        >>> from sympy.polys.matrices.sdm import DDM

        >>> A = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
        >>> B = DDM([[ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ)
        >>> A.hstack(B)
        [[1, 2, 5, 6], [3, 4, 7, 8]]

        >>> C = DDM([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ)
        >>> A.hstack(B, C)
        [[1, 2, 5, 6, 9, 10], [3, 4, 7, 8, 11, 12]]
        )r>   rT   r#   r&   rI   rB   r   )ABAnewr$   r%   r&   BkBkrowsBkcolsr-   ZBkir   r   r   hstack#  s    

z
DDM.hstackc           	      G   sr   t |  }| j\}}| j}|D ]>}|j\}}||ks:J |j|ksHJ ||7 }||  q t|||f| jS )a  Vertically stacks :py:class:`~.DDM` matrices.

        Examples
        ========

        >>> from sympy import ZZ
        >>> from sympy.polys.matrices.sdm import DDM

        >>> A = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
        >>> B = DDM([[ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ)
        >>> A.vstack(B)
        [[1, 2], [3, 4], [5, 6], [7, 8]]

        >>> C = DDM([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ)
        >>> A.vstack(B, C)
        [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
        )r>   rT   r#   r&   rB   r   )	r   r   r   r$   r%   r&   r   r   r   r   r   r   vstackE  s    

z
DDM.vstackc                    s     fdd| D }t || j|S )Nc                 3   s   | ]}t t |V  qd S r   )r>   rY   r   funcr   r   r   g  r    z DDM.applyfunc.<locals>.<genexpr>)r   r#   )r(   r   r&   elementsr   r   r   	applyfuncf  s    zDDM.applyfuncc                 C   s   |    S )a  Strongly connected components of a square matrix *a*.

        Examples
        ========

        >>> from sympy import ZZ
        >>> from sympy.polys.matrices.sdm import DDM
        >>> A = DDM([[ZZ(1), ZZ(0)], [ZZ(0), ZZ(1)]], (2, 2), ZZ)
        >>> A.scc()
        [[0], [1]]

        See also
        ========

        sympy.polys.matrices.domainmatrix.DomainMatrix.scc

        )rP   sccrz   r   r   r   r   j  s    zDDM.sccc                 C   s.   |   }| j}|jp|j}t||d}||fS )z0Reduced-row echelon form of a and list of pivots)Z_partial_pivot)rT   r&   is_RealFieldis_ComplexFieldr   )rt   ru   rS   Zpartial_pivotpivotsr   r   r   rref~  s
    zDDM.rrefc           
         s   |   \}}| j\}}| j g }g }t|D ]d|v r:q,|  fddt|D }t|D ] \}}	||	  ||  8  < qd|| q,t|t||f |fS )Nc                    s    g | ]}|kr j n jqS r   )rl   ri   r9   r&   r-   r   r   r4     r    z!DDM.nullspace.<locals>.<listcomp>)r   r#   r&   r5   r<   rI   r   r   )
rt   r   r   r$   r%   basis	nonpivotsveciijjr   r   r   	nullspace  s    

zDDM.nullspacec                 C   s   |     S r   )rP   
particularrM   rz   r   r   r   r     s    zDDM.particularc                 C   s6   | j \}}||krtd|  }|j}t||}|S )zDeterminant of a Determinant of non-square matrix)r#   r   rT   r&   r   )rt   r*   r   ru   rS   Zdetar   r   r   det  s    

zDDM.detc                 C   s8   | j \}}||krtd|  }| j}t|| | |S )zInverse of ar   )r#   r   rT   r&   r   )rt   r*   r   ainvrS   r   r   r   inv  s    
zDDM.invc                 C   s:   | j \}}| j}|  }| ||}t|||}|||fS )zL, U decomposition of a)r#   r&   rT   ro   r   )rt   r*   r   rS   ULswapsr   r   r   lu  s    
zDDM.luc           
      C   sZ   | j \}}|j \}}| | d||| |  \}}}| ||f| j}	t|	|||| |	S )zx where a*x = blu_solve)r#   r   r   rj   r&   r   )
rt   ru   r*   r   m2r   r   r   r   xr   r   r   r     s    

zDDM.lu_solvec                    sH   | j }| j\}}||kr tdt| |  fddt|d D }|S )z.Coefficients of characteristic polynomial of azCharpoly of non-square matrixc                    s   g | ]} | d  qS )r   r   )r   r-   r   r   r   r4     r    z DDM.charpoly.<locals>.<listcomp>r   )r&   r#   r   r   r5   )rt   rS   r*   r   coeffsr   r   r   charpoly  s    

zDDM.charpolyc                    s"   | j j t fdd|  D S )z@
        Says whether this matrix has all zero entries.
        c                 3   s   | ]}| kV  qd S r   r   )r   Mijri   r   r   r     r    z%DDM.is_zero_matrix.<locals>.<genexpr>)r&   ri   r'   rF   r?   r   r   r   is_zero_matrix  s    zDDM.is_zero_matrixc                    s"   | j j t fddt| D S )z~
        Says whether this matrix is upper-triangular. True can be returned
        even if the matrix is not square.
        c                 3   s,   | ]$\}}|d | D ]}| kV  qqd S r   r   r   r-   ZMir   r   r   r   r     r    zDDM.is_upper.<locals>.<genexpr>r&   ri   r'   rI   r?   r   r   r   is_upper  s    zDDM.is_upperc                    s"   | j j t fddt| D S )z~
        Says whether this matrix is lower-triangular. True can be returned
        even if the matrix is not square.
        c                 3   s0   | ](\}}||d  d D ]}| kV  qqdS )r   Nr   r   r   r   r   r     r    zDDM.is_lower.<locals>.<genexpr>r   r?   r   r   r   is_lower  s    zDDM.is_lower):r]   
__module____qualname____doc__fmtr"   r/   r1   r8   r=   r@   rD   rF   rC   rL   rM   rP   rU   r[   r^   ra   rd   classmethodrj   rm   ro   rT   rp   rv   rx   r{   r~   r   r   r   rr   rw   ry   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r+   r   r   U   sr   



	"!


r   )rN   N)r   	itertoolsr   
exceptionsr   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r>   r   sdmrN   r   r   r   r   <module>   s   ?<   