U
    9%e;                     @   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/Darija-Ai-API/env/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""