U
    ZÊ¹jà;  ã                   @   s  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 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!m"Z"m#Z# d dl$m%Z% d dl&m'Z' d dl(m)Z) dddddddddddg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.ƒZ0G d)d*„ d*e.ƒZ1d+d„ Z2d,d„ Z3d-d„ Z4d.d„ Z5G d/d0„ d0e-ƒZ6G d1d2„ d2e6ƒZ7G d3d4„ d4e6ƒZ8G d5d6„ d6e6ƒZ9d7d„ Z:d8d„ Z;d9d„ Z<d:d„ Z=d;d„ Z>d<d„ Z?d=d„ Z@d>S )?é    )ÚProduct)ÚSum)ÚBasic)ÚLambda)ÚIÚpi)ÚS)ÚDummy)ÚAbs)Úexp)Úgamma)ÚIntegral)ÚMatrixSymbol)ÚTrace)ÚIndexedBase)Ú_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$   ú_/var/www/html/bwave/python/venv/lib/python3.8/site-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   s
   | j d S )Nr   ©Úargs©Úselfr$   r$   r&   Ú<lambda>6   ó    z"RandomMatrixEnsembleModel.<lambda>c                 C   s
   | j d S )Né   r/   r1   r$   r$   r&   r3   7   r4   c                 C   s   t |ƒS ©N)r   ©r2   Úexprr$   r$   r&   Údensity9   s    z!RandomMatrixEnsembleModel.densityc                 C   s
   |   |¡S r6   )r9   r7   r$   r$   r&   Ú__call__<   s    z"RandomMatrixEnsembleModel.__call__)N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r+   ÚpropertyÚsymbolÚ	dimensionr9   r:   r$   r$   r$   r&   r(   (   s   
r(   c                   @   s    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 )Nr5   é   )r   r   ÚOne)Új©Úbetar$   r&   r3   W   r4   zGGaussianEnsembleModel._compute_normalization_constant.<locals>.<lambda>rE   T©ÚintegerZpositiver5   rC   é   )r   r	   r   Údoitr   )r2   rG   ÚnZ	prod_termrE   Úterm1Úterm2Zterm3r$   rF   r&   Ú_compute_normalization_constantK   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ÚiTrH   rE   ÚkrC   r5   )rA   rO   r   r	   r   r   r   rK   r   r   r
   r   Útuple)r2   rG   rL   ÚZbnrP   rQ   rE   rR   rM   Zsub_termrN   Úsymsr$   r$   r&   Ú!_compute_joint_eigen_distribution^   s    .. z7GaussianEnsembleModel._compute_joint_eigen_distributionN)r;   r<   r=   r>   rO   rV   r$   r$   r$   r&   rB   ?   s   rB   c                   @   s0   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 ©NrC   )rA   r   r   )r2   rL   r$   r$   r&   Únormalization_constantq   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©ÚpspacerC   ©rA   rY   r   r   r   r   r   r   )r2   r8   rL   ZZGUEÚh_pspacer^   r$   r$   r&   r9   v   s    z$GaussianUnitaryEnsembleModel.densityc                 C   s   |   tdƒ¡S rX   ©rV   r   r1   r$   r$   r&   r!   |   s    z5GaussianUnitaryEnsembleModel.joint_eigen_distributionc                 C   s:   t dƒ}dtd  |d  tdt |d  ƒ }t||ƒS )NÚsé    rC   éüÿÿÿ©r	   r   r   r   ©r2   rd   Úfr$   r$   r&   r#      s    (z7GaussianUnitaryEnsembleModel.level_spacing_distributionN©r;   r<   r=   r?   rY   r9   r!   r#   r$   r$   r$   r&   rW   p   s
   
rW   c                   @   s0   e Zd Zedd„ ƒZdd„ Zdd„ Zdd„ Zd	S )
ÚGaussianOrthogonalEnsembleModelc                 C   s4   | j }td||ƒ}ttt|ƒ d t|d ƒ ƒƒS )NÚ_HrJ   rC   ©rA   r   r   r   r   r   ©r2   rL   rl   r$   r$   r&   rY   …   s    z6GaussianOrthogonalEnsembleModel.normalization_constantc                 C   sV   | j | j }}td| d�}td|||d�}t|tt|ƒ d t|d ƒ ƒ| ƒ|ƒS )Nr[   r\   r^   r_   rJ   rC   ra   )r2   r8   rL   ZZGOErb   r^   r$   r$   r&   r9   ‹   s    z'GaussianOrthogonalEnsembleModel.densityc                 C   s   |   tj¡S r6   ©rV   r   rD   r1   r$   r$   r&   r!   ‘   s    z8GaussianOrthogonalEnsembleModel.joint_eigen_distributionc                 C   s4   t dƒ}td | tt d |d  ƒ }t||ƒS )Nrd   rC   rJ   rg   rh   r$   r$   r&   r#   ”   s    "z:GaussianOrthogonalEnsembleModel.level_spacing_distributionNrj   r$   r$   r$   r&   rk   „   s
   
rk   c                   @   s0   e Zd Zedd„ ƒZdd„ Zdd„ Zdd„ Zd	S )
ÚGaussianSymplecticEnsembleModelc                 C   s0   | j }td||ƒ}ttt|ƒ t|d ƒ ƒƒS )Nrl   rC   rm   rn   r$   r$   r&   rY   š   s    z6GaussianSymplecticEnsembleModel.normalization_constantc                 C   sR   | j | j }}td| d�}td|||d�}t|tt|ƒ t|d ƒ ƒ| ƒ|ƒS rZ   ra   )r2   r8   rL   ZZGSErb   r^   r$   r$   r&   r9       s    z'GaussianSymplecticEnsembleModel.densityc                 C   s   |   tdƒ¡S ©NrJ   rc   r1   r$   r$   r&   r!   ¦   s    z8GaussianSymplecticEnsembleModel.joint_eigen_distributionc                 C   sR   t dƒ}tdƒd tdƒd td   |d  tddt  |d  ƒ }t||ƒS )	Nrd   rC   é   é   é   rJ   iÀÿÿÿé	   )r	   r   r   r   r   rh   r$   r$   r&   r#   ©   s    @z:GaussianSymplecticEnsembleModel.level_spacing_distributionNrj   r$   r$   r$   r&   rp   ™   s
   
rp   c                 C   s8   t | ƒt|ƒ } }t| |ƒ}t| |d�}t| |||d�S ©Nr\   r_   )r   r   rB   r   r   ©r-   r.   r]   Zrmpr$   r$   r&   r   ®   s    
c                 C   s8   t | ƒt|ƒ } }t| |ƒ}t| |d�}t| |||d�S )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\   r_   )r   r   rW   r   r   rw   r$   r$   r&   r   ´   s    
c                 C   s8   t | ƒt|ƒ } }t| |ƒ}t| |d�}t| |||d�S )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\   r_   )r   r   rk   r   r   rw   r$   r$   r&   r   Ç   s    
c                 C   s8   t | ƒt|ƒ } }t| |ƒ}t| |d�}t| |||d�S )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\   r_   )r   r   rp   r   r   rw   r$   r$   r&   r    Ú   s    
c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú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|  ƒ‚d S )NzeSupport for Haar measure hasn't been implemented yet, therefore the density of %s cannot be computed.)ÚNotImplementedErrorr7   r$   r$   r&   r9   ø   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.
        rC   r5   ÚtrQ   T)rI   rE   rR   )rA   r   r   r   r   r	   r   rK   r   r
   r   r   r   rS   )
r2   rG   rL   rT   rz   rQ   rE   rR   rU   ri   r$   r$   r&   rV   ÿ   s    8
ÿ
<ÿz7CircularEnsembleModel._compute_joint_eigen_distributionN)r;   r<   r=   r>   r9   rV   r$   r$   r$   r&   rx   í   s   
rx   c                   @   s   e Zd Zdd„ ZdS )ÚCircularUnitaryEnsembleModelc                 C   s   |   tdƒ¡S rX   rc   r1   r$   r$   r&   r!     s    z5CircularUnitaryEnsembleModel.joint_eigen_distributionN©r;   r<   r=   r!   r$   r$   r$   r&   r{     s   r{   c                   @   s   e Zd Zdd„ ZdS )ÚCircularOrthogonalEnsembleModelc                 C   s   |   tj¡S r6   ro   r1   r$   r$   r&   r!     s    z8CircularOrthogonalEnsembleModel.joint_eigen_distributionNr|   r$   r$   r$   r&   r}     s   r}   c                   @   s   e Zd Zdd„ ZdS )ÚCircularSymplecticEnsembleModelc                 C   s   |   tdƒ¡S rq   rc   r1   r$   r$   r&   r!     s    z8CircularSymplecticEnsembleModel.joint_eigen_distributionNr|   r$   r$   r$   r&   r~     s   r~   c                 C   s8   t | ƒt|ƒ } }t| |ƒ}t| |d�}t| |||d�S rv   )r   r   rx   r   r   rw   r$   r$   r&   r     s    
c                 C   s8   t | ƒt|ƒ } }t| |ƒ}t| |d�}t| |||d�S )a8  
    Represents Circular 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 because the exact definition is based on haar measure of
    unitary group which is not unique.
    r\   r_   )r   r   r{   r   r   rw   r$   r$   r&   r   !  s    
c                 C   s8   t | ƒt|ƒ } }t| |ƒ}t| |d�}t| |||d�S )a>  
    Represents Circular 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 because the exact definition is based on haar measure of
    unitary group which is not unique.
    r\   r_   )r   r   r}   r   r   rw   r$   r$   r&   r   :  s    
c                 C   s8   t | ƒt|ƒ } }t| |ƒ}t| |d�}t| |||d�S )aA  
    Represents Circular 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 because the exact definition is based on haar measure of
    unitary group which is not unique.
    r\   r_   )r   r   r~   r   r   rw   r$   r$   r&   r   S  s    
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*   r`   r]   r!   ©Úmatr$   r$   r&   r!   l  s    
c                 C   s2   | j dd�}tdd„ t|ƒD ƒƒs*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 r6   )r   )Ú.0Zeigenvalr$   r$   r&   Ú	<genexpr>¦  s     z)JointEigenDistribution.<locals>.<genexpr>zWEigen values do not have any random expression, joint distribution cannot be generated.)Ú	eigenvalsÚallÚsetr*   r   )r�   r„   r$   r$   r&   r"   ‰  s    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
    )r`   r]   r#   r€   r$   r$   r&   r#   «  s    N)AZsympy.concrete.productsr   Zsympy.concrete.summationsr   Zsympy.core.basicr   Zsympy.core.functionr   Zsympy.core.numbersr   r   Zsympy.core.singletonr   Zsympy.core.symbolr	   Z$sympy.functions.elementary.complexesr
   Z&sympy.functions.elementary.exponentialr   Z'sympy.functions.special.gamma_functionsr   Zsympy.integrals.integralsr   Z"sympy.matrices.expressions.matexprr   Z sympy.matrices.expressions.tracer   Zsympy.tensor.indexedr   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(   rB   rW   rk   rp   r   r   r   r    rx   r{   r}   r~   r   r   r   r   r!   r"   r#   r$   r$   r$   r&   Ú<module>   sh   õ
1""