o
    8Va'                     @   s   d dl Z d dlmZmZmZmZmZmZmZm	Z	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)	
MatrixExprExpr
ShapeError
ZeroMatrixAddMulMatMulSexpand)RandomSymbol	is_random)_sympify)Variance
CovarianceExpectationc                   @   .   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 u rt|s|S t| |}nt |}t| ||}|j|_||_|S N)r   r   r   __new__shape_shape
_condition)clsexpr	conditionobj r   O/usr/lib/python3/dist-packages/sympy/stats/symbolic_multivariate_probability.pyr   1   s   zExpectationMatrix.__new__c                 C      | j S r   r   selfr   r   r   r   ?      zExpectationMatrix.shapec                    s  | j d }| j t|s|S t|tr t fdd|j D S t|}t|tr6t fdd|j D S t|ttfrg }g }g }|j D ])}t|ra|rT|	| n|	| g }|
| qF|jrj|
| qF|
| qFt|dkrx| S t|tt| d t| S | S )Nr   c                 3        | ]}t | d  V  qdS r   Nr   r
   .0ar%   r   r   	<genexpr>J       z+ExpectationMatrix.expand.<locals>.<genexpr>c                 3   r#   r$   r&   r'   r%   r   r   r*   O   r+   r%   )argsr   r   
isinstancer   fromiter_expandr   r   extendappendZ	is_Matrixlenr   )r!   hintsr   Zexpand_exprrvnonrvZpostnonr)   r   r%   r   r
   C   sF   




zExpectationMatrix.expandr   __name__
__module____qualname____doc__r   propertyr   r
   r   r   r   r   r   
   s    
&
r   c                   @   r   )
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vrtd|jd dkr|jd |jd fn	|jd |jd f}|r2t| ||}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   r   r   r   r    r   r   r   r      r"   zVarianceMatrix.shapec           	         s>  | j d }| j t|st| j S t|tr| S t|trNg }|j D ]}t|r-|| q"tt	 fdd| } fdd}tt	|t
|d }|| S t|ttfrg }g }|j D ]}t|rh|| q\|| q\t|dkryt| j S t|dkr| S t|dkr| S t|tt|  t|  S | S )Nr   c                    s   t |   S r   )r   r
   )Zxvr%   r   r   <lambda>   s    z'VarianceMatrix.expand.<locals>.<lambda>c                    s   dt | d i  S )N   r   )r   r
   )xr%   r   r   rA      s    rB   r=   )r,   r   r   r   r   r-   r   r   r1   map	itertoolscombinationsr   r   r2   r.   r   	transpose)	r!   r3   r@   r4   r)   Z	variancesZmap_to_covarZcovariancesr5   r   r%   r   r
      sF   







zVarianceMatrix.expandr   r6   r   r   r   r   r<   m   s    

r<   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vsd|jvs|jd |jd kr td|jd dkr8|jd dkr8|jd |jd fnd}|rEt| |||}nt| ||}||_||_|S )Nr=   r>   r   )r=   r=   r?   )r   arg1arg2r   r   r   r   r   r   r      s   (0zCrossCovarianceMatrix.__new__c                 C   r   r   r   r    r   r   r   r      r"   zCrossCovarianceMatrix.shapec                    s   | j d }| j d }| j||krt| S t|r t|s%t| j S t|tr5t|tr5t	||S | 
| }| 
|   fdd|D }t|S )Nr   r=   c              	      s8   g | ]\}} D ]\}}|t ||d  |  qqS )r%   )rH   rG   )r(   r)   Zr1bZr2Zcoeff_rv_list2r   r   r   
<listcomp>  s
     z0CrossCovarianceMatrix.expand.<locals>.<listcomp>)r,   r   r<   r
   r   r   r   r-   r   rH   _expand_single_argumentr   r.   )r!   r3   rI   rJ   Zcoeff_rv_list1Zaddendsr   rL   r   r
      s   



zCrossCovarianceMatrix.expandc                 C   s   t |trtj|fgS t |tr6g }|jD ]}t |ttfr'|| 	| qt
|r3|tj|f q|S t |ttfrC| 	|gS t
|rMtj|fgS d S r   )r-   r   r	   ZOner   r,   r   r   r1   _get_mul_nonrv_rv_tupler   )r   r   Zoutvalr)   r   r   r   rN     s    


z-CrossCovarianceMatrix._expand_single_argumentc                 C   sF   g }g }|j D ]}t|r|| q|| qt|t|fS r   )r,   r   r1   r   r.   )r   mr4   r5   r)   r   r   r   rO   $  s   
z-CrossCovarianceMatrix._get_mul_nonrv_rv_tupler   )r7   r8   r9   r:   r   r;   r   r
   classmethodrN   rO   r   r   r   r   rH      s    


rH   )rE   Zsympyr   r   r   r   r   r   r   r	   r
   r/   Zsympy.stats.rvr   r   Zsympy.core.sympifyr   Z sympy.stats.symbolic_probabilityr   r   r   r   r<   rH   r   r   r   r   <module>   s    ,cX