U
    9%e(                     @   s   d dl 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 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 G dd deeZG dd deeZG dd deeZdS )    N)Add)Expr)expand)Mul)S)
ShapeError)
MatrixExpr)MatMul)
ZeroMatrix)RandomSymbol	is_random)_sympify)Variance
CovarianceExpectationc                   @   s.   e Zd ZdZd	ddZedd Zdd ZdS )
ExpectationMatrixa0  
    Expectation of a random matrix expression.

    Examples
    ========

    >>> from sympy.stats import ExpectationMatrix, Normal
    >>> from sympy.stats.rv import RandomMatrixSymbol
    >>> from sympy import symbols, MatrixSymbol, Matrix
    >>> k = symbols("k")
    >>> A, B = MatrixSymbol("A", k, k), MatrixSymbol("B", k, k)
    >>> X, Y = RandomMatrixSymbol("X", k, 1), RandomMatrixSymbol("Y", k, 1)
    >>> ExpectationMatrix(X)
    ExpectationMatrix(X)
    >>> ExpectationMatrix(A*X).shape
    (k, 1)

    To expand the expectation in its expression, use ``expand()``:

    >>> ExpectationMatrix(A*X + B*Y).expand()
    A*ExpectationMatrix(X) + B*ExpectationMatrix(Y)
    >>> ExpectationMatrix((X + Y)*(X - Y).T).expand()
    ExpectationMatrix(X*X.T) - ExpectationMatrix(X*Y.T) + ExpectationMatrix(Y*X.T) - ExpectationMatrix(Y*Y.T)

    To evaluate the ``ExpectationMatrix``, use ``doit()``:

    >>> N11, N12 = Normal('N11', 11, 1), Normal('N12', 12, 1)
    >>> N21, N22 = Normal('N21', 21, 1), Normal('N22', 22, 1)
    >>> M11, M12 = Normal('M11', 1, 1), Normal('M12', 2, 1)
    >>> M21, M22 = Normal('M21', 3, 1), Normal('M22', 4, 1)
    >>> x1 = Matrix([[N11, N12], [N21, N22]])
    >>> x2 = Matrix([[M11, M12], [M21, M22]])
    >>> ExpectationMatrix(x1 + x2).doit()
    Matrix([
    [12, 14],
    [24, 26]])

    Nc                 C   sR   t |}|d kr*t|s|S t| |}nt |}t| ||}|j|_||_|S N)r   r   r   __new__shape_shape
_condition)clsexpr	conditionobj r   l/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/sympy/stats/symbolic_multivariate_probability.pyr   8   s    zExpectationMatrix.__new__c                 C   s   | j S r   r   selfr   r   r   r   F   s    zExpectationMatrix.shapec                    s  | j d }| j t|s|S t|tr@t fdd|j D S t|}t|trlt fdd|j D S t|ttfrg }g }g }|j D ]R}t|r|r|	| n
|	| g }|
| q|jr|
| q|
| qt|dkr| S t|tt| d t| S | S )Nr   c                 3   s   | ]}t | d  V  qdS r   Nr   r   .0ar!   r   r   	<genexpr>Q   s   z+ExpectationMatrix.expand.<locals>.<genexpr>c                 3   s   | ]}t | d  V  qdS r    r"   r#   r!   r   r   r&   V   s   r!   )argsr   r   
isinstancer   fromiter_expandr   r	   extendappendZ	is_Matrixlenr   )r   hintsr   Zexpand_exprrvnonrvZpostnonr%   r   r!   r   r   J   sF    




zExpectationMatrix.expand)N__name__
__module____qualname____doc__r   propertyr   r   r   r   r   r   r      s
   &

r   c                   @   s.   e Zd ZdZd	ddZedd Zdd ZdS )
VarianceMatrixak  
    Variance of a random matrix probability expression. Also known as
    Covariance matrix, auto-covariance matrix, dispersion matrix,
    or variance-covariance matrix.

    Examples
    ========

    >>> from sympy.stats import VarianceMatrix
    >>> from sympy.stats.rv import RandomMatrixSymbol
    >>> from sympy import symbols, MatrixSymbol
    >>> k = symbols("k")
    >>> A, B = MatrixSymbol("A", k, k), MatrixSymbol("B", k, k)
    >>> X, Y = RandomMatrixSymbol("X", k, 1), RandomMatrixSymbol("Y", k, 1)
    >>> VarianceMatrix(X)
    VarianceMatrix(X)
    >>> VarianceMatrix(X).shape
    (k, k)

    To expand the variance in its expression, use ``expand()``:

    >>> VarianceMatrix(A*X).expand()
    A*VarianceMatrix(X)*A.T
    >>> VarianceMatrix(A*X + B*Y).expand()
    2*A*CrossCovarianceMatrix(X, Y)*B.T + A*VarianceMatrix(X)*A.T + B*VarianceMatrix(Y)*B.T
    Nc                 C   s   t |}d|jkrtd|jd dkr<|jd |jd fn|jd |jd f}|rdt| ||}nt| |}||_||_|S )N   Expression is not a vectorr   r   r   r   r   r   r   r   )r   argr   r   r   r   r   r   r      s    
6zVarianceMatrix.__new__c                 C   s   | j S r   r   r   r   r   r   r      s    zVarianceMatrix.shapec           	         sD  | j d }| j t|s"t| j S t|tr0| S t|trg }|j D ]}t|rD|| qDt fdd|D  } fdd}tt	|t
|d }|| S t|ttfr@g }g }|j D ]"}t|r|| q|| qt|dkrt| j S t|dkr| S t|dkr| S t|tt|  t|  S | S )Nr   c                 3   s   | ]}t |  V  qd S r   )r   r   )r$   Zxvr!   r   r   r&      s     z(VarianceMatrix.expand.<locals>.<genexpr>c                    s   dt | d i  S )N   r   )r   r   )xr!   r   r   <lambda>       z'VarianceMatrix.expand.<locals>.<lambda>r<   r8   )r'   r   r   r
   r   r(   r   r   r,   map	itertoolscombinationsr   r	   r-   r)   r   	transpose)	r   r.   r;   r/   r%   Z	variancesZmap_to_covarZcovariancesr0   r   r!   r   r      sD    






zVarianceMatrix.expand)Nr1   r   r   r   r   r7   t   s
   

r7   c                   @   sF   e Zd ZdZdddZedd Zdd Zed	d
 Z	edd Z
dS )CrossCovarianceMatrixa  
    Covariance of a random matrix probability expression.

    Examples
    ========

    >>> from sympy.stats import CrossCovarianceMatrix
    >>> from sympy.stats.rv import RandomMatrixSymbol
    >>> from sympy import symbols, MatrixSymbol
    >>> k = symbols("k")
    >>> A, B = MatrixSymbol("A", k, k), MatrixSymbol("B", k, k)
    >>> C, D = MatrixSymbol("C", k, k), MatrixSymbol("D", k, k)
    >>> X, Y = RandomMatrixSymbol("X", k, 1), RandomMatrixSymbol("Y", k, 1)
    >>> Z, W = RandomMatrixSymbol("Z", k, 1), RandomMatrixSymbol("W", k, 1)
    >>> CrossCovarianceMatrix(X, Y)
    CrossCovarianceMatrix(X, Y)
    >>> CrossCovarianceMatrix(X, Y).shape
    (k, k)

    To expand the covariance in its expression, use ``expand()``:

    >>> CrossCovarianceMatrix(X + Y, Z).expand()
    CrossCovarianceMatrix(X, Z) + CrossCovarianceMatrix(Y, Z)
    >>> CrossCovarianceMatrix(A*X, Y).expand()
    A*CrossCovarianceMatrix(X, Y)
    >>> CrossCovarianceMatrix(A*X, B.T*Y).expand()
    A*CrossCovarianceMatrix(X, Y)*B
    >>> CrossCovarianceMatrix(A*X + B*Y, C.T*Z + D.T*W).expand()
    A*CrossCovarianceMatrix(X, W)*D + A*CrossCovarianceMatrix(X, Z)*C + B*CrossCovarianceMatrix(Y, W)*D + B*CrossCovarianceMatrix(Y, Z)*C

    Nc                 C   s   t |}t |}d|jks8d|jks8|jd |jd kr@td|jd dkrp|jd dkrp|jd |jd fnd}|rt| |||}nt| ||}||_||_|S )Nr8   r9   r   )r8   r8   r:   )r   arg1arg2r   r   r   r   r   r   r      s    (0zCrossCovarianceMatrix.__new__c                 C   s   | j S r   r   r   r   r   r   r      s    zCrossCovarianceMatrix.shapec                    s   | j d }| j d }| j||kr0t| S t|r@t|sJt| j S t|trjt|trjt	||S | 
| }| 
|   fdd|D }t|S )Nr   r8   c              	      s8   g | ]0\}} D ]"\}}|t ||d  |  qqS )r!   )rD   rC   )r$   r%   r1br2Zcoeff_rv_list2r   r   r   
<listcomp>  s     z0CrossCovarianceMatrix.expand.<locals>.<listcomp>)r'   r   r7   r   r   r
   r   r(   r   rD   _expand_single_argumentr   r)   )r   r.   rE   rF   Zcoeff_rv_list1Zaddendsr   rJ   r   r     s    


zCrossCovarianceMatrix.expandc                 C   s   t |trtj|fgS t |trlg }|jD ]<}t |ttfrN|| 	| q*t
|r*|tj|f q*|S t |ttfr| 	|gS t
|rtj|fgS d S r   )r(   r   r   ZOner   r'   r   r	   r,   _get_mul_nonrv_rv_tupler   )r   r   Zoutvalr%   r   r   r   rL     s    


z-CrossCovarianceMatrix._expand_single_argumentc                 C   sF   g }g }|j D ]"}t|r&|| q|| qt|t|fS r   )r'   r   r,   r   r)   )r   mr/   r0   r%   r   r   r   rM   +  s    
z-CrossCovarianceMatrix._get_mul_nonrv_rv_tuple)N)r2   r3   r4   r5   r   r6   r   r   classmethodrL   rM   r   r   r   r   rD      s   


rD   ) rA   Zsympy.core.addr   Zsympy.core.exprr   Zsympy.core.functionr   r*   Zsympy.core.mulr   Zsympy.core.singletonr   Zsympy.matrices.commonr   Z"sympy.matrices.expressions.matexprr   Z!sympy.matrices.expressions.matmulr	   Z"sympy.matrices.expressions.specialr
   Zsympy.stats.rvr   r   Zsympy.core.sympifyr   Z sympy.stats.symbolic_probabilityr   r   r   r   r7   rD   r   r   r   r   <module>   s   cX