o
    8Va9                     @   s  d dl mZmZmZmZmZmZmZmZm	Z	m
Z
mZmZmZmZmZ d dlmZ d dlmZmZmZmZ d dlmZ d dlmZ d dlmZ g dZeedd	 ZG d
d deZ G dd de Z!G dd de!Z"G dd de!Z#G dd de!Z$dd Z%dd Z&dd Z'dd Z(G dd de Z)G dd de)Z*G d d! d!e)Z+G d"d# d#e)Z,d$d% Z-d&d' Z.d(d) Z/d*d+ Z0d,d- Z1d.d/ Z2d0d1 Z3d2S )3    )BasicexppiLambdaTraceSMatrixSymbolIntegralgammaProductDummySumAbsIndexedBaseI)_sympify)_symbol_converterDensityRandomMatrixSymbol	is_random)JointDistributionHandmade)RandomMatrixPSpace)ArrayComprehension)CircularEnsembleCircularUnitaryEnsembleCircularOrthogonalEnsembleCircularSymplecticEnsembleGaussianEnsembleGaussianUnitaryEnsembleGaussianOrthogonalEnsembleGaussianSymplecticEnsemblejoint_eigen_distributionJointEigenDistributionlevel_spacing_distributionc                 C   s   dS )NT )xr$   r$   B/usr/lib/python3/dist-packages/sympy/stats/random_matrix_models.py_   s   r'   c                   @   sB   e Zd ZdZdddZedd Zedd Zdd	 Zd
d Z	dS )RandomMatrixEnsembleModelz
    Base class for random matrix ensembles.
    It acts as an umbrella and contains
    the methods common to all the ensembles
    defined in sympy.stats.random_matrix_models.
    Nc                 C   s6   t |t|}}|jdkrtd| t| ||S )NFzGDimension of the random matrices must be integers, received %s instead.)r   r   
is_integer
ValueErrorr   __new__)clssymdimr$   r$   r&   r+   #   s   
z!RandomMatrixEnsembleModel.__new__c                 C   
   | j d S )Nr   argsselfr$   r$   r&   <lambda>*      
 z"RandomMatrixEnsembleModel.<lambda>c                 C   r/   )N   r0   r2   r$   r$   r&   r4   +   r5   c                 C   s   t |S N)r   r3   exprr$   r$   r&   density-   s   z!RandomMatrixEnsembleModel.densityc                 C   s
   |  |S r7   )r:   r8   r$   r$   r&   __call__0   s   
z"RandomMatrixEnsembleModel.__call__r7   )
__name__
__module____qualname____doc__r+   propertysymbol	dimensionr:   r;   r$   r$   r$   r&   r(      s    
r(   c                   @       e Zd ZdZdd Zdd ZdS )GaussianEnsembleModela  
    Abstract class for Gaussian ensembles.
    Contains the properties common to all the
    gaussian ensembles.

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Random_matrix#Gaussian_ensembles
    .. [2] https://arxiv.org/pdf/1712.07903.pdf
    c                    s~   t |} fdd}tdddd}t|||d|f }d |   | |d  d |d   }dt |d  }|| | S )	a  
        Helper function for computing normalization
        constant for joint probability density of eigen
        values of Gaussian ensembles.

        References
        ==========

        .. [1] https://en.wikipedia.org/wiki/Selberg_integral#Mehta's_integral
        c                    s.   t d t|  d  t tj td   S )Nr6      )r
   r   One)jbetar$   r&   r4   K   s   . zGGaussianEnsembleModel._compute_normalization_constant.<locals>.<lambda>rG   TintegerZpositiver6   rE      )r   r   r   doitr   )r3   rI   nZ	prod_termrG   term1term2Zterm3r$   rH   r&   _compute_normalization_constant?   s   (z5GaussianEnsembleModel._compute_normalization_constantc                 C   s   | j }| ||}td}tdddd}tdddd}tdddd}tt| d t|| d |d|f  }t|t	t
|| ||  | ||d |f}	t	|	| |d|d f }
t|| |d|f }tt|||
 | S )	z
        Helper function for computing the joint
        probability distribution of eigen values
        of the random matrix.
        liTrJ   rG   krE   r6   )rB   rQ   r   r   r   r   r   rM   r   r   r   r   tuple)r3   rI   rN   ZbnrR   rS   rG   rT   rO   Zsub_termrP   symsr$   r$   r&   !_compute_joint_eigen_distributionR   s   .. z7GaussianEnsembleModel._compute_joint_eigen_distributionN)r<   r=   r>   r?   rQ   rX   r$   r$   r$   r&   rD   3   s    rD   c                   @   0   e Zd Zedd Zdd Zdd Zdd Zd	S )
GaussianUnitaryEnsembleModelc                 C   s*   | j }dt|d  tt|d d   S NrE   )rB   r   r   )r3   rN   r$   r$   r&   normalization_constante   s   $z3GaussianUnitaryEnsembleModel.normalization_constantc                 C   sV   | j | j}}td| d}td|||d}t|tt| d t|d  | |S NPmodelHpspacerE   rB   r\   r   r   r   r   r   r   )r3   r9   rN   ZZGUEh_pspacera   r$   r$   r&   r:   j      ,z$GaussianUnitaryEnsembleModel.densityc                 C      |  tdS r[   rX   r   r2   r$   r$   r&   r!   p      z5GaussianUnitaryEnsembleModel.joint_eigen_distributionc                 C   s:   t d}dtd  |d  tdt |d   }t||S )Ns    rE   r   r   r   r   r3   rj   fr$   r$   r&   r#   s   s   (
z7GaussianUnitaryEnsembleModel.level_spacing_distributionNr<   r=   r>   r@   r\   r:   r!   r#   r$   r$   r$   r&   rZ   d   s    
rZ   c                   @   rY   )
GaussianOrthogonalEnsembleModelc                 C   s4   | j }td||}ttt| d t|d  S )N_HrL   rE   rB   r   r	   r   r   r   r3   rN   rr   r$   r$   r&   r\   y   s   "z6GaussianOrthogonalEnsembleModel.normalization_constantc                 C   sV   | j | j}}td| d}td|||d}t|tt| d t|d  | |S )Nr^   r_   ra   rb   rL   rE   rd   )r3   r9   rN   ZZGOEre   ra   r$   r$   r&   r:      rf   z'GaussianOrthogonalEnsembleModel.densityc                 C      |  tjS r7   rX   r   rF   r2   r$   r$   r&   r!         z8GaussianOrthogonalEnsembleModel.joint_eigen_distributionc                 C   s4   t d}td | tt d |d   }t||S )Nrj   rE   rL   rm   rn   r$   r$   r&   r#      s   "
z:GaussianOrthogonalEnsembleModel.level_spacing_distributionNrp   r$   r$   r$   r&   rq   x       
rq   c                   @   rY   )
GaussianSymplecticEnsembleModelc                 C   s0   | j }td||}ttt| t|d  S )Nrr   rE   rs   rt   r$   r$   r&   r\      s   z6GaussianSymplecticEnsembleModel.normalization_constantc                 C   sR   | j | j}}td| d}td|||d}t|tt| t|d  | |S r]   rd   )r3   r9   rN   ZZGSEre   ra   r$   r$   r&   r:      s   (z'GaussianSymplecticEnsembleModel.densityc                 C   rg   NrL   rh   r2   r$   r$   r&   r!      ri   z8GaussianSymplecticEnsembleModel.joint_eigen_distributionc                 C   sR   t d}tdd tdd td   |d  tddt  |d   }t||S )	Nrj   rE            rL   i	   )r   r   r   r   r   rn   r$   r$   r&   r#      s   @
z:GaussianSymplecticEnsembleModel.level_spacing_distributionNrp   r$   r$   r$   r&   ry      rx   ry   c                 C   8   t | t|} }t| |}t| |d}t| |||dS Nr_   rb   )r   r   rD   r   r   r-   r.   r`   Zrmpr$   r$   r&   r         
r   c                 C   r   )a-  
    Represents Gaussian Unitary Ensembles.

    Examples
    ========

    >>> from sympy.stats import GaussianUnitaryEnsemble as GUE, density
    >>> from sympy import MatrixSymbol
    >>> G = GUE('U', 2)
    >>> X = MatrixSymbol('X', 2, 2)
    >>> density(G)(X)
    exp(-Trace(X**2))/(2*pi**2)
    r_   rb   )r   r   rZ   r   r   r   r$   r$   r&   r         
r   c                 C   r   )aN  
    Represents Gaussian Orthogonal Ensembles.

    Examples
    ========

    >>> from sympy.stats import GaussianOrthogonalEnsemble as GOE, density
    >>> from sympy import MatrixSymbol
    >>> G = GOE('U', 2)
    >>> X = MatrixSymbol('X', 2, 2)
    >>> density(G)(X)
    exp(-Trace(X**2)/2)/Integral(exp(-Trace(_H**2)/2), _H)
    r_   rb   )r   r   rq   r   r   r   r$   r$   r&   r      r   r   c                 C   r   )aN  
    Represents Gaussian Symplectic Ensembles.

    Examples
    ========

    >>> from sympy.stats import GaussianSymplecticEnsemble as GSE, density
    >>> from sympy import MatrixSymbol
    >>> G = GSE('U', 2)
    >>> X = MatrixSymbol('X', 2, 2)
    >>> density(G)(X)
    exp(-2*Trace(X**2))/Integral(exp(-2*Trace(_H**2)), _H)
    r_   rb   )r   r   ry   r   r   r   r$   r$   r&   r       r   r    c                   @   rC   )CircularEnsembleModelz
    Abstract class for Circular ensembles.
    Contains the properties and methods
    common to all the circular ensembles.

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Circular_ensemble
    c                 C   s   t d|  )NzeSupport for Haar measure hasn't been implemented yet, therefore the density of %s cannot be computed.)NotImplementedErrorr8   r$   r$   r&   r:      s   zCircularEnsembleModel.densityc           
      C   s   | j }dt | t|| d d tt|d d |   }td}tdddtdddtddd}}}t|| |d|f }ttt	t
t||  t
t||   | ||d |f |d|d f }	tt||	| S )	z
        Helper function to compute the joint distribution of phases
        of the complex eigen values of matrices belonging to any
        circular ensembles.
        rE   r6   trS   T)rK   rG   rT   )rB   r   r
   r   r   r   r   rM   r   r   r   r   r   rU   )
r3   rI   rN   rV   r   rS   rG   rT   rW   ro   r$   r$   r&   rX      s   8

<z7CircularEnsembleModel._compute_joint_eigen_distributionN)r<   r=   r>   r?   r:   rX   r$   r$   r$   r&   r      s    
r   c                   @      e Zd Zdd ZdS )CircularUnitaryEnsembleModelc                 C   rg   r[   rh   r2   r$   r$   r&   r!     ri   z5CircularUnitaryEnsembleModel.joint_eigen_distributionNr<   r=   r>   r!   r$   r$   r$   r&   r         r   c                   @   r   )CircularOrthogonalEnsembleModelc                 C   ru   r7   rv   r2   r$   r$   r&   r!     rw   z8CircularOrthogonalEnsembleModel.joint_eigen_distributionNr   r$   r$   r$   r&   r     r   r   c                   @   r   )CircularSymplecticEnsembleModelc                 C   rg   rz   rh   r2   r$   r$   r&   r!     ri   z8CircularSymplecticEnsembleModel.joint_eigen_distributionNr   r$   r$   r$   r&   r     r   r   c                 C   r   r   )r   r   r   r   r   r   r$   r$   r&   r     r   r   c                 C   r   )a7  
    Represents Cicular Unitary Ensembles.

    Examples
    ========

    >>> from sympy.stats import CircularUnitaryEnsemble as CUE
    >>> from sympy.stats import joint_eigen_distribution
    >>> C = CUE('U', 1)
    >>> joint_eigen_distribution(C)
    Lambda(t[1], Product(Abs(exp(I*t[_j]) - exp(I*t[_k]))**2, (_j, _k + 1, 1), (_k, 1, 0))/(2*pi))

    Note
    ====

    As can be seen above in the example, density of CiruclarUnitaryEnsemble
    is not evaluated becuase the exact definition is based on haar measure of
    unitary group which is not unique.
    r_   rb   )r   r   r   r   r   r   r$   r$   r&   r        
r   c                 C   r   )a=  
    Represents Cicular Orthogonal Ensembles.

    Examples
    ========

    >>> from sympy.stats import CircularOrthogonalEnsemble as COE
    >>> from sympy.stats import joint_eigen_distribution
    >>> C = COE('O', 1)
    >>> joint_eigen_distribution(C)
    Lambda(t[1], Product(Abs(exp(I*t[_j]) - exp(I*t[_k])), (_j, _k + 1, 1), (_k, 1, 0))/(2*pi))

    Note
    ====

    As can be seen above in the example, density of CiruclarOrthogonalEnsemble
    is not evaluated becuase the exact definition is based on haar measure of
    unitary group which is not unique.
    r_   rb   )r   r   r   r   r   r   r$   r$   r&   r   .  r   r   c                 C   r   )a@  
    Represents Cicular Symplectic Ensembles.

    Examples
    ========

    >>> from sympy.stats import CircularSymplecticEnsemble as CSE
    >>> from sympy.stats import joint_eigen_distribution
    >>> C = CSE('S', 1)
    >>> joint_eigen_distribution(C)
    Lambda(t[1], Product(Abs(exp(I*t[_j]) - exp(I*t[_k]))**4, (_j, _k + 1, 1), (_k, 1, 0))/(2*pi))

    Note
    ====

    As can be seen above in the example, density of CiruclarSymplecticEnsemble
    is not evaluated becuase the exact definition is based on haar measure of
    unitary group which is not unique.
    r_   rb   )r   r   r   r   r   r   r$   r$   r&   r   G  r   r   c                 C   s"   t | tstd|  | jj S )aA  
    For obtaining joint probability distribution
    of eigen values of random matrix.

    Parameters
    ==========

    mat: RandomMatrixSymbol
        The matrix symbol whose eigen values are to be considered.

    Returns
    =======

    Lambda

    Examples
    ========

    >>> from sympy.stats import GaussianUnitaryEnsemble as GUE
    >>> from sympy.stats import joint_eigen_distribution
    >>> U = GUE('U', 2)
    >>> joint_eigen_distribution(U)
    Lambda((l[1], l[2]), exp(-l[1]**2 - l[2]**2)*Product(Abs(l[_i] - l[_j])**2, (_j, _i + 1, 2), (_i, 1, 1))/pi)
    z&%s is not of type, RandomMatrixSymbol.)
isinstancer   r*   rc   r`   r!   matr$   r$   r&   r!   `  s   
r!   c                 C   s2   | j dd}tdd t|D rtdt| S )a  
    Creates joint distribution of eigen values of matrices with random
    expressions.

    Parameters
    ==========

    mat: Matrix
        The matrix under consideration.

    Returns
    =======

    JointDistributionHandmade

    Examples
    ========

    >>> from sympy.stats import Normal, JointEigenDistribution
    >>> from sympy import Matrix
    >>> A = [[Normal('A00', 0, 1), Normal('A01', 0, 1)],
    ... [Normal('A10', 0, 1), Normal('A11', 0, 1)]]
    >>> JointEigenDistribution(Matrix(A))
    JointDistributionHandmade(-sqrt(A00**2 - 2*A00*A11 + 4*A01*A10 + A11**2)/2
    + A00/2 + A11/2, sqrt(A00**2 - 2*A00*A11 + 4*A01*A10 + A11**2)/2 + A00/2 + A11/2)

    T)Zmultiplec                 s   s    | ]}t | V  qd S r7   )r   ).0Zeigenvalr$   r$   r&   	<genexpr>  s    z)JointEigenDistribution.<locals>.<genexpr>zVEigen values don't have any random expression, joint distribution cannot be generated.)	eigenvalsanysetr*   r   )r   r   r$   r$   r&   r"   }  s   r"   c                 C   s   | j j S )a  
    For obtaining distribution of level spacings.

    Parameters
    ==========

    mat: RandomMatrixSymbol
        The random matrix symbol whose eigen values are
        to be considered for finding the level spacings.

    Returns
    =======

    Lambda

    Examples
    ========

    >>> from sympy.stats import GaussianUnitaryEnsemble as GUE
    >>> from sympy.stats import level_spacing_distribution
    >>> U = GUE('U', 2)
    >>> level_spacing_distribution(U)
    Lambda(_s, 32*_s**2*exp(-4*_s**2/pi)/pi**2)

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Random_matrix#Distribution_of_level_spacings
    )rc   r`   r#   r   r$   r$   r&   r#     s   r#   N)4Zsympyr   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   Zsympy.core.sympifyr   Zsympy.stats.rvr   r   r   r   Zsympy.stats.joint_rv_typesr   Zsympy.stats.random_matrixr   Zsympy.tensor.arrayr   __all__registerr'   r(   rD   rZ   rq   ry   r   r   r   r    r   r   r   r   r   r   r   r   r!   r"   r#   r$   r$   r$   r&   <module>   s:   D 
1""