U
    ZÊ¹j`6  ã                   @   sÜ   d dl mZ d dlmZ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 d d	lmZmZ d d
lmZmZmZmZmZmZ d dlmZ dd„ ZG dd„ deƒZdd„ Z dd„ Z!G dd„ deƒZ"dS )é    )ÚCounter)ÚMulÚsympify)ÚAdd)ÚExprBuilder)Údefault_sort_key)Úlog)Ú
MatrixExpr)Úvalidate_matadd_integer)Ú
ZeroMatrixÚ	OneMatrix)ÚunpackÚflattenÚ	conditionÚexhaustÚrm_idÚsort)Úsympy_deprecation_warningc                  G   s,   | st dƒ‚t| ƒdkr | d S t| Ž  ¡ S )au  
    Return the elementwise (aka Hadamard) product of matrices.

    Examples
    ========

    >>> from sympy import hadamard_product, MatrixSymbol
    >>> A = MatrixSymbol('A', 2, 3)
    >>> B = MatrixSymbol('B', 2, 3)
    >>> hadamard_product(A)
    A
    >>> hadamard_product(A, B)
    HadamardProduct(A, B)
    >>> hadamard_product(A, B)[0, 1]
    A[0, 1]*B[0, 1]
    z#Empty Hadamard product is undefinedé   r   )Ú	TypeErrorÚlenÚHadamardProductÚdoit)Zmatrices© r   úb/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/matrices/expressions/hadamard.pyÚhadamard_product   s
    r   c                       s`   e Zd ZdZdZdddœ‡ fdd„
Zedd	„ ƒZd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Z‡  ZS )r   a(  
    Elementwise product of matrix expressions

    Examples
    ========

    Hadamard product for matrix symbols:

    >>> from sympy import hadamard_product, HadamardProduct, MatrixSymbol
    >>> A = MatrixSymbol('A', 5, 5)
    >>> B = MatrixSymbol('B', 5, 5)
    >>> isinstance(hadamard_product(A, B), HadamardProduct)
    True

    Notes
    =====

    This is a symbolic object that simply stores its argument without
    evaluating it. To actually compute the product, use the function
    ``hadamard_product()`` or ``HadamardProduct.doit``
    TFN)ÚevaluateÚcheckc                   sˆ   t tt|ƒƒ}t|ƒdkr"tdƒ‚tdd„ |D ƒƒs<tdƒ‚|d k	rRtdddd	� |d
k	rbt|Ž  t	ƒ j
| f|žŽ }|r„|jd
d�}|S )Nr   z+HadamardProduct needs at least one argumentc                 s   s   | ]}t |tƒV  qd S ©N)Ú
isinstancer	   ©Ú.0Úargr   r   r   Ú	<genexpr>G   s     z*HadamardProduct.__new__.<locals>.<genexpr>z Mix of Matrix and Scalar symbolszjPassing check to HadamardProduct is deprecated and the check argument will be removed in a future version.z1.11z,remove-check-argument-from-matrix-operations)Zdeprecated_since_versionZactive_deprecations_targetF)Údeep)ÚlistÚmapr   r   Ú
ValueErrorÚallr   r   ÚvalidateÚsuperÚ__new__r   )Úclsr   r   ÚargsÚobj©Ú	__class__r   r   r+   A   s"    ýzHadamardProduct.__new__c                 C   s   | j d jS ©Nr   )r-   Úshape©Úselfr   r   r   r2   X   s    zHadamardProduct.shapec                    s   t ‡ ‡‡fdd„| jD ƒŽ S )Nc                    s   g | ]}|j ˆ ˆfˆŽ‘qS r   )Ú_entryr    ©ÚiÚjÚkwargsr   r   Ú
<listcomp>]   s     z*HadamardProduct._entry.<locals>.<listcomp>)r   r-   )r4   r7   r8   r9   r   r6   r   r5   \   s    zHadamardProduct._entryc                 C   s    ddl m} ttt|| jƒƒŽ S ©Nr   )Ú	transpose)Ú$sympy.matrices.expressions.transposer<   r   r%   r&   r-   ©r4   r<   r   r   r   Ú_eval_transpose_   s    zHadamardProduct._eval_transposec                    s’   | j ‡fdd„| jD ƒŽ }ddlm‰  ddlm} ‡ fdd„|jD ƒ‰ˆrŠ‡fdd„|jD ƒ}|d	d„ tˆŽ D ƒƒj| jŽ }t	|g| Ž }t
|ƒS )
Nc                 3   s   | ]}|j f ˆ ŽV  qd S r   )r   ©r!   r7   )Úhintsr   r   r#   d   s     z'HadamardProduct.doit.<locals>.<genexpr>r   ©Ú
MatrixBase)ÚImmutableMatrixc                    s   g | ]}t |ˆ ƒr|‘qS r   )r   r@   rB   r   r   r:   i   s     
 z(HadamardProduct.doit.<locals>.<listcomp>c                    s   g | ]}|ˆ kr|‘qS r   r   r@   )Úexplicitr   r   r:   k   s      c                 S   s   g | ]}t  |¡‘qS r   )r   Úfromiterr@   r   r   r   r:   l   s    )Úfuncr-   Zsympy.matrices.matrixbaserC   Zsympy.matrices.immutablerD   ÚzipZreshaper2   r   Úcanonicalize)r4   rA   ÚexprrD   Ú	remainderZexpl_matr   )rC   rE   rA   r   r   c   s    ÿþzHadamardProduct.doitc                 C   sd   g }t | jƒ}tt|ƒƒD ]>}|d |… ||  |¡g ||d d …  }| t|Ž ¡ qt |¡S ©Nr   )	r%   r-   Úranger   ÚdiffÚappendr   r   rF   )r4   ÚxZtermsr-   r7   Zfactorsr   r   r   Ú_eval_derivatives   s    
,z HadamardProduct._eval_derivativec                    s<  ddl m} ddl m} ddlm} ‡fdd„tˆ jƒD ƒ}g }|D ]ò}ˆ jd |… }ˆ j|d d … }	ˆ j|  ˆ¡}
t|	| Ž }dd	g}‡ fd
d„t|ƒD ƒ}|
D ]Ž}|j	|j
 }|j	|j }t|t|t||gƒ|t||gƒgƒf|•ƒ}|jd jd j|_d|_|jd jd j|_d|_|g|_	| |¡ q¦qD|S )Nr   ©ÚArrayDiagonal©ÚArrayTensorProduct©Ú_make_matrixc                    s   g | ]\}}|  ˆ ¡r|‘qS r   )Úhas)r!   r7   r"   ©rP   r   r   r:   €   s     
 zAHadamardProduct._eval_derivative_matrix_lines.<locals>.<listcomp>r   )r   é   ©é   é   c                    s"   g | ]\}}ˆ j | d kr|‘qS ©r   )r2   ©r!   r8   Úer3   r   r   r:   ‰   s      rZ   )Ú0sympy.tensor.array.expressions.array_expressionsrS   rU   Ú"sympy.matrices.expressions.matexprrW   Ú	enumerater-   Ú_eval_derivative_matrix_linesr   Ú_linesÚ_first_line_indexÚ_second_line_indexr   Ú_first_pointer_parentÚ_first_pointer_indexÚ_second_pointer_parentÚ_second_pointer_indexrO   )r4   rP   rS   rU   rW   Z
with_x_indÚlinesÚindZ	left_argsZ
right_argsÚdZhadamÚdiagonalr7   Úl1Úl2Úsubexprr   )r4   rP   r   rd   {   sF    

ýþÿ	÷þz-HadamardProduct._eval_derivative_matrix_lines)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zis_HadamardProductr+   Úpropertyr2   r5   r?   r   rQ   rd   Ú__classcell__r   r   r/   r   r   )   s   
r   c                 C   sÖ   t dd„ tƒ}t|ƒ}|| ƒ} t dd„ tdd„ ƒƒ}|| ƒ} dd„ }t dd„ |ƒ}|| ƒ} t| tƒr°t| jƒ}g }| ¡ D ],\}}|dkr–| 	|¡ qz| 	t
||ƒ¡ qzt|Ž } t d	d„ ttƒƒ}|| ƒ} t| ƒ} | S )
aò  Canonicalize the Hadamard product ``x`` with mathematical properties.

    Examples
    ========

    >>> from sympy import MatrixSymbol, HadamardProduct
    >>> from sympy import OneMatrix, ZeroMatrix
    >>> from sympy.matrices.expressions.hadamard import canonicalize
    >>> from sympy import init_printing
    >>> init_printing(use_unicode=False)

    >>> A = MatrixSymbol('A', 2, 2)
    >>> B = MatrixSymbol('B', 2, 2)
    >>> C = MatrixSymbol('C', 2, 2)

    Hadamard product associativity:

    >>> X = HadamardProduct(A, HadamardProduct(B, C))
    >>> X
    A.*(B.*C)
    >>> canonicalize(X)
    A.*B.*C

    Hadamard product commutativity:

    >>> X = HadamardProduct(A, B)
    >>> Y = HadamardProduct(B, A)
    >>> X
    A.*B
    >>> Y
    B.*A
    >>> canonicalize(X)
    A.*B
    >>> canonicalize(Y)
    A.*B

    Hadamard product identity:

    >>> X = HadamardProduct(A, OneMatrix(2, 2))
    >>> X
    A.*1
    >>> canonicalize(X)
    A

    Absorbing element of Hadamard product:

    >>> X = HadamardProduct(A, ZeroMatrix(2, 2))
    >>> X
    A.*0
    >>> canonicalize(X)
    0

    Rewriting to Hadamard Power

    >>> X = HadamardProduct(A, A, A)
    >>> X
    A.*A.*A
    >>> canonicalize(X)
     .3
    A

    Notes
    =====

    As the Hadamard product is associative, nested products can be flattened.

    The Hadamard product is commutative so that factors can be sorted for
    canonical form.

    A matrix of only ones is an identity for Hadamard product,
    so every matrices of only ones can be removed.

    Any zero matrix will make the whole product a zero matrix.

    Duplicate elements can be collected and rewritten as HadamardPower

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Hadamard_product_(matrices)
    c                 S   s
   t | tƒS r   ©r   r   rY   r   r   r   Ú<lambda>û   ó    zcanonicalize.<locals>.<lambda>c                 S   s
   t | tƒS r   ry   rY   r   r   r   rz     r{   c                 S   s
   t | tƒS r   )r   r   rY   r   r   r   rz     r{   c                 S   s&   t dd„ | jD ƒƒrt| jŽ S | S d S )Nc                 s   s   | ]}t |tƒV  qd S r   )r   r   )r!   Úcr   r   r   r#   
  s     z/canonicalize.<locals>.absorb.<locals>.<genexpr>)Úanyr-   r   r2   rY   r   r   r   Úabsorb	  s    
zcanonicalize.<locals>.absorbc                 S   s
   t | tƒS r   ry   rY   r   r   r   rz     r{   r   c                 S   s
   t | tƒS r   ry   rY   r   r   r   rz   #  r{   )r   r   r   r   r   r   r   r-   ÚitemsrO   ÚHadamardPowerr   r   r   )rP   ÚruleZfunr~   ZtallyZnew_argÚbaseÚexpr   r   r   rI   §   s@    Sþ
þþ

þrI   c                 C   sB   t | ƒ} t |ƒ}|dkr| S | js*| | S |jr8tdƒ‚t| |ƒS )Nr   z#cannot raise expression to a matrix)r   Ú	is_Matrixr'   r€   )r‚   rƒ   r   r   r   Úhadamard_power-  s    r…   c                       sd   e Zd ZdZ‡ fdd„Zedd„ ƒZedd„ ƒZedd	„ ƒZd
d„ Z	dd„ Z
dd„ Zdd„ Z‡  ZS )r€   a¤  
    Elementwise power of matrix expressions

    Parameters
    ==========

    base : scalar or matrix

    exp : scalar or matrix

    Notes
    =====

    There are four definitions for the hadamard power which can be used.
    Let's consider `A, B` as `(m, n)` matrices, and `a, b` as scalars.

    Matrix raised to a scalar exponent:

    .. math::
        A^{\circ b} = \begin{bmatrix}
        A_{0, 0}^b   & A_{0, 1}^b   & \cdots & A_{0, n-1}^b   \\
        A_{1, 0}^b   & A_{1, 1}^b   & \cdots & A_{1, n-1}^b   \\
        \vdots       & \vdots       & \ddots & \vdots         \\
        A_{m-1, 0}^b & A_{m-1, 1}^b & \cdots & A_{m-1, n-1}^b
        \end{bmatrix}

    Scalar raised to a matrix exponent:

    .. math::
        a^{\circ B} = \begin{bmatrix}
        a^{B_{0, 0}}   & a^{B_{0, 1}}   & \cdots & a^{B_{0, n-1}}   \\
        a^{B_{1, 0}}   & a^{B_{1, 1}}   & \cdots & a^{B_{1, n-1}}   \\
        \vdots         & \vdots         & \ddots & \vdots           \\
        a^{B_{m-1, 0}} & a^{B_{m-1, 1}} & \cdots & a^{B_{m-1, n-1}}
        \end{bmatrix}

    Matrix raised to a matrix exponent:

    .. math::
        A^{\circ B} = \begin{bmatrix}
        A_{0, 0}^{B_{0, 0}}     & A_{0, 1}^{B_{0, 1}}     &
        \cdots & A_{0, n-1}^{B_{0, n-1}}     \\
        A_{1, 0}^{B_{1, 0}}     & A_{1, 1}^{B_{1, 1}}     &
        \cdots & A_{1, n-1}^{B_{1, n-1}}     \\
        \vdots                  & \vdots                  &
        \ddots & \vdots                      \\
        A_{m-1, 0}^{B_{m-1, 0}} & A_{m-1, 1}^{B_{m-1, 1}} &
        \cdots & A_{m-1, n-1}^{B_{m-1, n-1}}
        \end{bmatrix}

    Scalar raised to a scalar exponent:

    .. math::
        a^{\circ b} = a^b
    c                    sV   t |ƒ}t |ƒ}|jr$|jr$|| S t|tƒrBt|tƒrBt||ƒ tƒ  | ||¡}|S r   )r   Ú	is_scalarr   r	   r)   r*   r+   )r,   r‚   rƒ   r.   r/   r   r   r+   r  s    
zHadamardPower.__new__c                 C   s
   | j d S r1   ©Ú_argsr3   r   r   r   r‚     s    zHadamardPower.basec                 C   s
   | j d S rL   r‡   r3   r   r   r   rƒ   ƒ  s    zHadamardPower.expc                 C   s   | j jr| j jS | jjS r   )r‚   r„   r2   rƒ   r3   r   r   r   r2   ‡  s    zHadamardPower.shapec                 K   sx   | j }| j}|jr$|j||f|Ž}n|jr0|}ntd |¡ƒ‚|jrV|j||f|Ž}n|jrb|}ntd |¡ƒ‚|| S )Nz)The base {} must be a scalar or a matrix.z-The exponent {} must be a scalar or a matrix.)r‚   rƒ   r„   r5   r†   r'   Úformat)r4   r7   r8   r9   r‚   rƒ   ÚaÚbr   r   r   r5   �  s"    ÿÿzHadamardPower._entryc                 C   s   ddl m} t|| jƒ| jƒS r;   )r=   r<   r€   r‚   rƒ   r>   r   r   r   r?   £  s    zHadamardPower._eval_transposec                 C   s:   | j  |¡}| j t¡}| |¡}t|| | j |  | ƒS r   )rƒ   rN   r‚   Z	applyfuncr   r   )r4   rP   ZdexpZlogbaseZdlbaser   r   r   rQ   §  s    
þzHadamardPower._eval_derivativec                    s  ddl m} ddl m} ddlm} ˆ j |¡}|D ]È}ddg}‡ fdd„t|ƒD ƒ}|j|j	 }|j|j
 }	t|t|t||gƒˆ jtˆ jˆ jd	 ƒ t||	gƒgƒf|•|jd
�}
|
jd jd j|_d|_d|_	|
jd jd j|_d|_d|_
|
g|_q4|S )Nr   rT   rR   rV   )r   rZ   r[   c                    s$   g | ]\}}ˆ j j| d kr|‘qS r^   )r‚   r2   r_   r3   r   r   r:   ¸  s      z?HadamardPower._eval_derivative_matrix_lines.<locals>.<listcomp>r   )Ú	validatorrZ   )ra   rU   rS   rb   rW   r‚   rd   rc   re   rf   rg   r   rƒ   r…   Ú	_validater-   rh   ri   rj   rk   )r4   rP   rU   rS   rW   Úlrr7   ro   rp   rq   rr   r   r3   r   rd   °  s>    

ýþÿ	÷
ô
z+HadamardPower._eval_derivative_matrix_lines)rs   rt   ru   rv   r+   rw   r‚   rƒ   r2   r5   r?   rQ   rd   rx   r   r   r/   r   r€   9  s   8


	r€   N)#Úcollectionsr   Z
sympy.corer   r   Zsympy.core.addr   Zsympy.core.exprr   Zsympy.core.sortingr   Z&sympy.functions.elementary.exponentialr   rb   r	   Z!sympy.matrices.expressions._shaper
   r)   Z"sympy.matrices.expressions.specialr   r   Zsympy.strategiesr   r   r   r   r   r   Zsympy.utilities.exceptionsr   r   r   rI   r…   r€   r   r   r   r   Ú<module>   s     ~ 