o
    8Va                     @   sL   d dl mZ d dlmZmZmZmZmZ d dlm	Z	m
Z
 G dd deZdS )    )
MatrixExpr)
MatrixBaseDummyLambdaFunctionFunctionClass)sympify_sympifyc                   @   sl   e Zd ZdZ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dd Zdd ZdS )ElementwiseApplyFunctiona|  
    Apply function to a matrix elementwise without evaluating.

    Examples
    ========

    It can be created by calling ``.applyfunc(<function>)`` on a matrix
    expression:

    >>> from sympy.matrices.expressions import MatrixSymbol
    >>> from sympy.matrices.expressions.applyfunc import ElementwiseApplyFunction
    >>> from sympy import exp
    >>> X = MatrixSymbol("X", 3, 3)
    >>> X.applyfunc(exp)
    Lambda(_d, exp(_d)).(X)

    Otherwise using the class constructor:

    >>> from sympy import eye
    >>> expr = ElementwiseApplyFunction(exp, eye(3))
    >>> expr
    Lambda(_d, exp(_d)).(Matrix([
    [1, 0, 0],
    [0, 1, 0],
    [0, 0, 1]]))
    >>> expr.doit()
    Matrix([
    [E, 1, 1],
    [1, E, 1],
    [1, 1, E]])

    Notice the difference with the real mathematical functions:

    >>> exp(eye(3))
    Matrix([
    [E, 0, 0],
    [0, E, 0],
    [0, 0, E]])
    c                 C   s   t |}|jstd||jdkr||}t|tr|S t|ttfs0t	d}t|||}t
|}t|ttfsBtd|d|jvrNtd|t|ts^t	d}t|||}t| ||}|S )Nz{} must be a matrix instance.)   r   dz4{} should be compatible with SymPy function classes.r   z({} should be able to accept 1 arguments.)r	   Z	is_Matrix
ValueErrorformatshape
isinstancer   r   r   r   r   nargs__new__)clsfunctionexprretr   obj r   F/usr/lib/python3/dist-packages/sympy/matrices/expressions/applyfunc.pyr   /   s2   



z ElementwiseApplyFunction.__new__c                 C   
   | j d S )Nr   argsselfr   r   r   r   P      
z!ElementwiseApplyFunction.functionc                 C   r   )Nr   r   r   r   r   r   r   T   r   zElementwiseApplyFunction.exprc                 C   s   | j jS N)r   r   r   r   r   r   r   X   s   zElementwiseApplyFunction.shapec                    s~   | dd}j |r jdi | j}t|tr |jr  S t tr+ jS t t	r=t	 fdd j S S )NdeepTc                    s      | S r    )r   )xr   r   r   r   <lambda>i   s    z/ElementwiseApplyFunction.doit.<locals>.<lambda>r   )
getr   doitr   r   r   Zis_identityr   Z	applyfuncr
   )r   kwargsr!   r   r   r#   r   r&   \   s"   

zElementwiseApplyFunction.doitc                 K   s   |  | jj||fi |S r    )r   r   _entry)r   ijr'   r   r   r   r(   o   s   zElementwiseApplyFunction._entryc                 C   s@   t d}| |}||}t|trt|}|S t||}|S )Nr   )r   r   diffr   r   typer   )r   r   r   fdiffr   r   r   _get_function_fdiffr   s   



z,ElementwiseApplyFunction._get_function_fdiffc                 C   s2   ddl m} | j|}|  }||t|| jS )Nr   )hadamard_product)sympyr/   r   r+   r.   r
   )r   r"   r/   Zdexprr-   r   r   r   _eval_derivative|   s   
z)ElementwiseApplyFunction._eval_derivativec              
   C   s  ddl m} ddlm} ddlm} ddlm} ddlm} |  }| j	
|}t|| j	}	d|jv r| jd dk}
|D ]E}|
rK|j}|| jd }n
|| jd }|j}|||||	||g|
rbdnd	g|jd
}|g|_|jd j|_d|_|jd j|_d|_q<|S |D ]A}|j}|j}||jd }||jd }|||||||	||gddg|jd
}|jd j|_d|_|jd j|_d|_|g|_q|S )Nr   )Identity)ArrayContraction)ArrayDiagonal)ArrayTensorProduct)ExprBuilderr   )r      )r      )Z	validatorr7   )r   r7   r8   )         r8   )r0   r2   Z0sympy.tensor.array.expressions.array_expressionsr3   r4   r5   Zsympy.core.exprr6   r.   r   _eval_derivative_matrix_linesr
   r   Zfirst_pointerZsecond_pointerZ	_validateZ_linesr   Z_first_pointer_parentZ_first_pointer_indexZ_second_pointer_parentZ_second_pointer_index)r   r"   r2   r3   r4   r5   r6   r-   ZlrZewdiffZiscolumnr)   Zptr1Zptr2ZsubexprZnewptr1Znewptr2r   r   r   r<      sr   


z6ElementwiseApplyFunction._eval_derivative_matrix_linesc                 C   s$   ddl m} | | j|| j S )Nr   )	Transpose)r0   r=   funcr   r   r&   )r   r=   r   r   r   _eval_transpose   s   z(ElementwiseApplyFunction._eval_transposeN)__name__
__module____qualname____doc__r   propertyr   r   r   r&   r(   r.   r1   r<   r?   r   r   r   r   r
      s    (!



	Cr
   N)Zsympy.matrices.expressionsr   r0   r   r   r   r   r   Zsympy.core.sympifyr   r	   r
   r   r   r   r   <module>   s    