a
    <b[U                     @   sx  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mZmZmZ d d	lmZmZmZmZmZmZm Z  d d
l!m"Z" G dd deZ#dd Z$G dd dZ%G dd dZ&G dd dZ'e%e'e&dZ(G dd de eZ)G dd de)Z*dd Z+G dd de)Z,dd Z-G d d! d!e)Z.d"d# Z/G d$d% d%e)Z0d&d' Z1d(S ))    )Basic)prod)pi)S)exp)
multigamma)sympify_sympify)	ImmutableMatrixInverseTraceDeterminantMatrixSymbol
MatrixBase	Transpose	MatrixSetmatrix2numpy)_value_checkRandomMatrixSymbolNamedArgsMixinPSpace_symbol_converterMatrixDomainDistribution)import_modulec                   @   sf   e Zd ZdZdd Zedd Zedd Zedd Zed	d
 Z	edd Z
dd ZdddZdS )MatrixPSpacezD
    Represents probability space for
    Matrix Distributions.
    c                 C   s@   t |}t|t| }}|jr&|js.tdt| ||||S )NzDimensions should be integers)r   r	   
is_integer
ValueErrorr   __new__)clssymdistributionZdim_nZdim_m r"   p/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/sympy/stats/matrix_distributions.pyr      s
    zMatrixPSpace.__new__c                 C   s
   | j d S )N   argsselfr"   r"   r#   <lambda>       zMatrixPSpace.<lambda>c                 C   s
   | j d S Nr   r%   r'   r"   r"   r#   r)       r*   c                 C   s   t | j| jjS N)r   symbolr!   setr'   r"   r"   r#   domain"   s    zMatrixPSpace.domainc                 C   s   t | j| jd | jd | S )N      )r   r-   r&   r'   r"   r"   r#   value&   s    zMatrixPSpace.valuec                 C   s   | j hS r,   )r2   r'   r"   r"   r#   values*   s    zMatrixPSpace.valuesc                 G   s4   | t}t|dks t|ts(td| j|S )Nr$   ztCurrently, no algorithm has been implemented to handle general expressions containing multiple matrix distributions.)Zatomsr   len
isinstanceNotImplementedErrorr!   pdf)r(   exprr&   Zrmsr"   r"   r#   compute_density.   s    
zMatrixPSpace.compute_densityr"   scipyNc                 C   s   | j | jj|||diS )zu
        Internal sample method

        Returns dictionary mapping RandomMatrixSymbol to realization value.
        )libraryseed)r2   r!   sample)r(   sizer;   r<   r"   r"   r#   r=   6   s    zMatrixPSpace.sample)r"   r:   N)__name__
__module____qualname____doc__r   propertyr!   r-   r/   r2   r3   r9   r=   r"   r"   r"   r#   r      s   


r   c                 C   sB   t tt|}|| }|j|  |j}t| ||d |d }|jS )Nr   r$   )listmapr   check	dimensionr   r2   )r-   r   r&   distZdimZpspacer"   r"   r#   rv?   s    
rI   c                   @   s&   e Zd ZdZdddZedd ZdS )SampleMatrixScipyz7Returns the sample from scipy of the given distributionNc                 C   s   |  |||S r,   )_sample_scipyr   rH   r>   r<   r"   r"   r#   r   J   s    zSampleMatrixScipy.__new__c           
         s   ddl m  ddl} fdd fddd}dd d	d d}| }|jj|vrXdS |du sjt|trz|jj	|d
}n|}||jj |t
||}	|	|||jj | S )zSample from SciPy.r   )statsNc                    s     j jt| jt| jt|dS )N)ZdfZscaler>   )Zwishartrvsintnr   scale_matrixfloatrH   r>   
rand_stateZscipy_statsr"   r#   r)   T   s   z1SampleMatrixScipy._sample_scipy.<locals>.<lambda>c                    s.    j jt| jtt| jtt| jt||dS )N)meanrowcovcolcovr>   Zrandom_state)Zmatrix_normalrN   r   location_matrixrR   scale_matrix_1scale_matrix_2rS   rU   r"   r#   r)   V   s   

WishartDistributionMatrixNormalDistributionc                 S   s   | j jS r,   rQ   shaperH   r"   r"   r#   r)   ]   r*   c                 S   s   | j jS r,   rY   r`   ra   r"   r"   r#   r)   ^   r*   r<   )r:   rM   numpykeys	__class__r?   r5   rO   randomdefault_rngr   reshape)
r   rH   r>   r<   rd   Zscipy_rv_mapsample_shape	dist_listrT   sampr"   rU   r#   rK   M   s     


zSampleMatrixScipy._sample_scipy)N)r?   r@   rA   rB   r   classmethodrK   r"   r"   r"   r#   rJ   H   s   
rJ   c                   @   s&   e Zd ZdZdddZedd ZdS )SampleMatrixNumpyz7Returns the sample from numpy of the given distributionNc                 C   s   |  |||S r,   )_sample_numpyrL   r"   r"   r#   r   r   s    zSampleMatrixNumpy.__new__c           
      C   s   i }i }|  }|jj|vr dS ddl}|du s:t|trJ|jj|d}n|}||jj |t||}	|		|||jj | S )zSample from NumPy.Nr   rc   )
re   rf   r?   rd   r5   rO   rg   rh   r   ri   )
r   rH   r>   r<   Znumpy_rv_maprj   rk   rd   rT   rl   r"   r"   r#   ro   u   s    zSampleMatrixNumpy._sample_numpy)N)r?   r@   rA   rB   r   rm   ro   r"   r"   r"   r#   rn   n   s   
rn   c                   @   s&   e Zd ZdZdddZedd ZdS )SampleMatrixPymcz7Returns the sample from pymc3 of the given distributionNc                 C   s   |  |||S r,   )_sample_pymc3rL   r"   r"   r#   r      s    zSampleMatrixPymc.__new__c           	   	      s   ddl   fdd fddd}dd dd d	}| }|jj|vrLdS ddl}|d
|j   > ||jj |  j	t
|dd|dddd }W d   n1 s0    Y  ||||jj | S )zSample from PyMC3.r   Nc                    s0    j dt| jtt| jtt| jt| jjdS )NX)murW   rX   r`   )MatrixNormalr   rY   rR   rZ   r[   r`   ra   pymc3r"   r#   r)      s
   


z0SampleMatrixPymc._sample_pymc3.<locals>.<lambda>c                    s    j dt| jt| jtdS )Nrr   )nur   )ZWishartBartlettrO   rP   r   rQ   rR   ra   ru   r"   r#   r)      s   )r^   r]   c                 S   s   | j jS r,   r_   ra   r"   r"   r#   r)      r*   c                 S   s   | j jS r,   rb   ra   r"   r"   r#   r)      r*   r\   rv   r$   F)ZdrawsZchainsZprogressbarZrandom_seedZreturn_inferencedataZcompute_convergence_checksrr   )rv   re   rf   r?   logging	getLoggersetLevelERRORZModelr=   r   ri   )	r   rH   r>   r<   Zpymc3_rv_maprj   rk   rx   sampsr"   ru   r#   rq      s     


<zSampleMatrixPymc._sample_pymc3)N)r?   r@   rA   rB   r   rm   rq   r"   r"   r"   r#   rp      s   
rp   )r:   rv   rd   c                   @   s6   e Zd ZdZdd Zedd Zdd ZdddZd
S )MatrixDistributionz1
    Abstract class for Matrix Distribution.
    c                 G   s    dd |D }t j| g|R  S )Nc                 S   s&   g | ]}t |trt|nt|qS r"   )r5   rD   r
   r	   ).0argr"   r"   r#   
<listcomp>   s   z.MatrixDistribution.__new__.<locals>.<listcomp>)r   r   )r   r&   r"   r"   r#   r      s    zMatrixDistribution.__new__c                  G   s   d S r,   r"   r%   r"   r"   r#   rF      s    zMatrixDistribution.checkc                 C   s   t |trt|}| |S r,   )r5   rD   r
   r7   )r(   r8   r"   r"   r#   __call__   s    
zMatrixDistribution.__call__r"   r:   Nc                 C   sh   g d}||vr t dt| t|s4td| t| | ||}|durP|S t d| jj|f dS )zo
        Internal sample method

        Returns dictionary mapping RandomSymbol to realization value.
        )r:   rd   rv   z&Sampling from %s is not supported yet.zFailed to import %sNz4Sampling for %s is not currently implemented from %s)r6   strr   r   _get_sample_class_matrixrvrf   r?   )r(   r>   r;   r<   	librariesr|   r"   r"   r#   r=      s    
zMatrixDistribution.sample)r"   r:   N)	r?   r@   rA   rB   r   staticmethodrF   r   r=   r"   r"   r"   r#   r}      s   
r}   c                   @   s<   e Zd ZdZedd Zedd Zedd Zdd	 Z	d
S )MatrixGammaDistributionalphabetarQ   c                 C   s>   t |tst|jd t|jd t| jd t|jd d S )N+The shape matrix must be positive definite.Should be square matrix#Shape parameter should be positive.z#Scale parameter should be positive.r5   r   r   is_positive_definite	is_squareis_positiver   r"   r"   r#   rF      s
    
zMatrixGammaDistribution.checkc                 C   s   | j jd }t||tjS r+   rQ   r`   r   r   Realsr(   kr"   r"   r#   r.      s    zMatrixGammaDistribution.setc                 C   s   | j jS r,   r_   r'   r"   r"   r#   rG      s    z!MatrixGammaDistribution.dimensionc           
      C   s   | j | j| j  }}}|jd }t|tr2t|}t|ttfsPt	dt
| t| | | }tt||||  t||  }t||  }t||t|d d   }	|| |	 S )Nr   4%s should be an isinstance of Matrix or MatrixSymbolr$   r0   )r   r   rQ   r`   r5   rD   r
   r   r   r   r   r   r   r   r   r   r   )
r(   xr   r   rQ   psigma_inv_xterm1term2term3r"   r"   r#   r7     s    

"zMatrixGammaDistribution.pdfN
r?   r@   rA   Z	_argnamesr   rF   rC   r.   rG   r7   r"   r"   r"   r#   r      s   
	

r   c                 C   s$   t |trt|}t| t|||fS )a  
    Creates a random variable with Matrix Gamma Distribution.

    The density of the said distribution can be found at [1].

    Parameters
    ==========

    alpha: Positive Real number
        Shape Parameter
    beta: Positive Real number
        Scale Parameter
    scale_matrix: Positive definite real square matrix
        Scale Matrix

    Returns
    =======

    RandomSymbol

    Examples
    ========

    >>> from sympy.stats import density, MatrixGamma
    >>> from sympy import MatrixSymbol, symbols
    >>> a, b = symbols('a b', positive=True)
    >>> M = MatrixGamma('M', a, b, [[2, 1], [1, 2]])
    >>> X = MatrixSymbol('X', 2, 2)
    >>> density(M)(X).doit()
    exp(Trace(Matrix([
    [-2/3,  1/3],
    [ 1/3, -2/3]])*X)/b)*Determinant(X)**(a - 3/2)/(3**a*sqrt(pi)*b**(2*a)*gamma(a)*gamma(a - 1/2))
    >>> density(M)([[1, 0], [0, 1]]).doit()
    exp(-4/(3*b))/(3**a*sqrt(pi)*b**(2*a)*gamma(a)*gamma(a - 1/2))


    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Matrix_gamma_distribution

    )r5   rD   r
   rI   r   )r-   r   r   rQ   r"   r"   r#   MatrixGamma  s    +
r   c                   @   s<   e Zd ZdZedd Zedd Zedd Zdd	 Z	d
S )r]   rP   rQ   c                 C   s2   t |tst|jd t|jd t| jd d S )Nr   r   r   r   r   r"   r"   r#   rF   G  s    
zWishartDistribution.checkc                 C   s   | j jd }t||tjS r+   r   r   r"   r"   r#   r.   P  s    zWishartDistribution.setc                 C   s   | j jS r,   r_   r'   r"   r"   r#   rG   U  s    zWishartDistribution.dimensionc           	      C   s   | j | j }}|jd }t|tr*t|}t|ttfsHtdt	| t
| | td }tt|d|| td  t|td |  }t|| td  }t|t|| d d  }|| | S )Nr   r   r0   r$   )rP   rQ   r`   r5   rD   r
   r   r   r   r   r   r   r   r   r   r   )	r(   r   rP   rQ   r   r   r   r   r   r"   r"   r#   r7   Y  s    

2zWishartDistribution.pdfNr   r"   r"   r"   r#   r]   C  s   


r]   c                 C   s"   t |trt|}t| t||fS )a  
    Creates a random variable with Wishart Distribution.

    The density of the said distribution can be found at [1].

    Parameters
    ==========

    n: Positive Real number
        Represents degrees of freedom
    scale_matrix: Positive definite real square matrix
        Scale Matrix

    Returns
    =======

    RandomSymbol

    Examples
    ========

    >>> from sympy.stats import density, Wishart
    >>> from sympy import MatrixSymbol, symbols
    >>> n = symbols('n', positive=True)
    >>> W = Wishart('W', n, [[2, 1], [1, 2]])
    >>> X = MatrixSymbol('X', 2, 2)
    >>> density(W)(X).doit()
    exp(Trace(Matrix([
    [-1/3,  1/6],
    [ 1/6, -1/3]])*X))*Determinant(X)**(n/2 - 3/2)/(2**n*3**(n/2)*sqrt(pi)*gamma(n/2)*gamma(n/2 - 1/2))
    >>> density(W)([[1, 0], [0, 1]]).doit()
    exp(-2/3)/(2**n*3**(n/2)*sqrt(pi)*gamma(n/2)*gamma(n/2 - 1/2))

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Wishart_distribution

    )r5   rD   r
   rI   r]   )r-   rP   rQ   r"   r"   r#   Wishartg  s    (
r   c                   @   s<   e Zd ZdZedd Zedd Zedd Zdd	 Z	d
S )r^   )rY   rZ   r[   c                 C   s   t |tst|jd t |ts,t|jd t|jd t|jd | jd }| jd }t|jd |kdt|t|f  t|jd |kdt|t|f  d S )Nr   )Scale matrix 1 should be be square matrix)Scale matrix 2 should be be square matrixr   r$   )Scale matrix 1 should be of shape %s x %s)Scale matrix 2 should be of shape %s x %s)r5   r   r   r   r   r`   r   )rY   rZ   r[   rP   r   r"   r"   r#   rF     s    



zMatrixNormalDistribution.checkc                 C   s   | j j\}}t||tjS r,   rY   r`   r   r   r   r(   rP   r   r"   r"   r#   r.     s    zMatrixNormalDistribution.setc                 C   s   | j jS r,   rb   r'   r"   r"   r#   rG     s    z"MatrixNormalDistribution.dimensionc           
      C   s   | j | j| j  }}}|j\}}t|tr2t|}t|ttfsPt	dt
| t|t||  t| ||  }tt| td }dt t|| d  t|t|  d t|t|  d }	||	 S )Nr   r0   )rY   rZ   r[   r`   r5   rD   r
   r   r   r   r   r   r   r   r   r   r   r   )
r(   r   MUVrP   r   r   numZdenr"   r"   r#   r7     s    

$@zMatrixNormalDistribution.pdfNr   r"   r"   r"   r#   r^     s   


r^   c                 C   sL   t |trt|}t |tr$t|}t |tr6t|}|||f}t| t|S )a  
    Creates a random variable with Matrix Normal Distribution.

    The density of the said distribution can be found at [1].

    Parameters
    ==========

    location_matrix: Real ``n x p`` matrix
        Represents degrees of freedom
    scale_matrix_1: Positive definite matrix
        Scale Matrix of shape ``n x n``
    scale_matrix_2: Positive definite matrix
        Scale Matrix of shape ``p x p``

    Returns
    =======

    RandomSymbol

    Examples
    ========

    >>> from sympy import MatrixSymbol
    >>> from sympy.stats import density, MatrixNormal
    >>> M = MatrixNormal('M', [[1, 2]], [1], [[1, 0], [0, 1]])
    >>> X = MatrixSymbol('X', 1, 2)
    >>> density(M)(X).doit()
    2*exp(-Trace((Matrix([
    [-1],
    [-2]]) + X.T)*(Matrix([[-1, -2]]) + X))/2)/pi
    >>> density(M)([[3, 4]]).doit()
    2*exp(-4)/pi

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Matrix_normal_distribution

    )r5   rD   r
   rI   r^   )r-   rY   rZ   r[   r&   r"   r"   r#   rt     s    )



rt   c                   @   s<   e Zd ZdZedd Zedd Zedd Zdd	 Z	d
S )MatrixStudentTDistribution)rw   rY   rZ   r[   c                 C   s   t |tst|jdkd t |ts4t|jdkd t|jdkd t|jdkd |jd }|jd }t|jd |kdt|t|f  t|jd |kdt|t|f  t| jdkd	 d S )
NFr   r   r   r   r$   r   r   z#Degrees of freedom must be positive)r5   r   r   r   r   r`   r   r   )rw   rY   rZ   r[   rP   r   r"   r"   r#   rF     s    



z MatrixStudentTDistribution.checkc                 C   s   | j j\}}t||tjS r,   r   r   r"   r"   r#   r.     s    zMatrixStudentTDistribution.setc                 C   s   | j jS r,   rb   r'   r"   r"   r#   rG     s    z$MatrixStudentTDistribution.dimensionc           
      C   s  ddl m} t|trt|}t|ttfs<tdt| | j	| j
| j| jf\}}}}|j\}}t|| | d d |t|| d   t|| d   t|| d  t|| d d |  }	|	t||t|||  t| t||   || | d  d   S )Nr   )eyer   r$   r0   )Zsympy.matrices.denser   r5   rD   r
   r   r   r   r   rw   rY   rZ   r[   r`   r   r   r   r   r   )
r(   r   r   rw   r   OmegaSigmarP   r   Kr"   r"   r#   r7     s    

<$0zMatrixStudentTDistribution.pdfNr   r"   r"   r"   r#   r     s   


r   c                 C   sN   t |trt|}t |tr$t|}t |tr6t|}||||f}t| t|S )a  
    Creates a random variable with Matrix Gamma Distribution.

    The density of the said distribution can be found at [1].

    Parameters
    ==========

    nu: Positive Real number
        degrees of freedom
    location_matrix: Positive definite real square matrix
        Location Matrix of shape ``n x p``
    scale_matrix_1: Positive definite real square matrix
        Scale Matrix of shape ``p x p``
    scale_matrix_2: Positive definite real square matrix
        Scale Matrix of shape ``n x n``

    Returns
    =======

    RandomSymbol

    Examples
    ========

    >>> from sympy import MatrixSymbol,symbols
    >>> from sympy.stats import density, MatrixStudentT
    >>> v = symbols('v',positive=True)
    >>> M = MatrixStudentT('M', v, [[1, 2]], [[1, 0], [0, 1]], [1])
    >>> X = MatrixSymbol('X', 1, 2)
    >>> density(M)(X)
    gamma(v/2 + 1)*Determinant((Matrix([[-1, -2]]) + X)*(Matrix([
    [-1],
    [-2]]) + X.T) + Matrix([[1]]))**(-v/2 - 1)/(pi**1.0*gamma(v/2)*Determinant(Matrix([[1]]))**1.0*Determinant(Matrix([
    [1, 0],
    [0, 1]]))**0.5)

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Matrix_t-distribution

    )r5   rD   r
   rI   r   )r-   rw   rY   rZ   r[   r&   r"   r"   r#   MatrixStudentT*  s    ,


r   N)2Zsympy.core.basicr   Zsympy.core.mulr   Zsympy.core.numbersr   Zsympy.core.singletonr   Z&sympy.functions.elementary.exponentialr   Z'sympy.functions.special.gamma_functionsr   Zsympy.core.sympifyr   r	   Zsympy.matricesr
   r   r   r   r   r   r   r   r   Zsympy.stats.rvr   r   r   r   r   r   r   Zsympy.externalr   r   rI   rJ   rn   rp   r   r}   r   r   r]   r   r^   rt   r   r   r"   r"   r"   r#   <module>   s6   ,$,	&&
0%2$/-52