o
    8VaS@                     @   sn  d Z ddlmZ 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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 m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ G d
d de,Z-G dd de Z.G dd de.Z/G dd de!e.Z0G dd de"e0Z1G dd de+e)Z2G dd de#Z3G dd de%e3Z4G dd de$e3Z5dS )zq
Finite Discrete Random Variables Module

See Also
========
sympy.stats.frv_types
sympy.stats.rv
sympy.stats.crv
    )product)BasicSymbolcacheitsympifyMulAndOr	PiecewiseEqLambdaexpIDummynanSumIntersectionS)Dict)Logic)
Relational)_sympify	FiniteSet)RandomDomainProductDomainConditionalDomainPSpaceIndependentProductPSpaceSinglePSpacerandom_symbolssumsetsrv_subsNamedArgsMixinDensityDistributionc                   @   $   e Zd ZdZdd Zedd ZdS )FiniteDensityz'
    A domain with Finite Density.
    c                 C   s   t |}|| v r| | S dS )z
        Make instance of a class callable.

        If item belongs to current instance of a class, return it.

        Otherwise, return 0.
        r   r   )selfitem r+   1/usr/lib/python3/dist-packages/sympy/stats/frv.py__call__   s   zFiniteDensity.__call__c                 C   s   t | S )z,
        Return item as dictionary.
        )dictr)   r+   r+   r,   r.   +   s   zFiniteDensity.dictN)__name__
__module____qualname____doc__r-   propertyr.   r+   r+   r+   r,   r'      s
    r'   c                   @   sP   e Zd ZdZdZedd Zedd Zedd Zd	d
 Z	dd Z
dd ZdS )FiniteDomainzS
    A domain with discrete finite support

    Represented using a FiniteSet.
    Tc                 C   s   t dd | jD S )Nc                 s   s    | ]\}}|V  qd S Nr+   .0symvalr+   r+   r,   	<genexpr><       z'FiniteDomain.symbols.<locals>.<genexpr>r   elementsr/   r+   r+   r,   symbols:      zFiniteDomain.symbolsc                 C   
   | j d S Nr   argsr/   r+   r+   r,   r>   >      
zFiniteDomain.elementsc                 C      t dd | jD  S )Nc                 S   s   g | ]}t t|qS r+   )r   r.   )r8   elr+   r+   r,   
<listcomp>D       z%FiniteDomain.dict.<locals>.<listcomp>r=   r/   r+   r+   r,   r.   B   r@   zFiniteDomain.dictc                 C   
   || j v S r6   )r>   r)   otherr+   r+   r,   __contains__F      
zFiniteDomain.__contains__c                 C   s
   | j  S r6   )r>   __iter__r/   r+   r+   r,   rO   I   rN   zFiniteDomain.__iter__c                 C   s   t dd | D  S )Nc                 S   s   g | ]}t d d |D  qS )c                 S   s   g | ]	\}}t ||qS r+   )r   r7   r+   r+   r,   rH   M       z6FiniteDomain.as_boolean.<locals>.<listcomp>.<listcomp>)r   )r8   r*   r+   r+   r,   rH   M   s    z+FiniteDomain.as_boolean.<locals>.<listcomp>)r	   r/   r+   r+   r,   
as_booleanL   s   zFiniteDomain.as_booleanN)r0   r1   r2   r3   	is_Finiter4   r?   r>   r.   rM   rO   rQ   r+   r+   r+   r,   r5   2   s    


r5   c                   @   sX   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	dd Z
dd ZdS )SingleFiniteDomainzi
    A FiniteDomain over a single symbol/set

    Example: The possibilities of a *single* die roll.
    c                 C   s*   t |tst |tst| }t| ||S r6   )
isinstancer   r   r   __new__)clssymbolsetr+   r+   r,   rU   W   s
   
zSingleFiniteDomain.__new__c                 C   rA   rB   rC   r/   r+   r+   r,   rW   ]   rE   zSingleFiniteDomain.symbolc                 C   
   t | jS r6   r   rW   r/   r+   r+   r,   r?   a   rE   zSingleFiniteDomain.symbolsc                 C   rA   N   rC   r/   r+   r+   r,   rX   e   rE   zSingleFiniteDomain.setc                    s   t  fdd jD  S )Nc                    s   g | ]
}t  j|ffqS r+   	frozensetrW   r8   elemr/   r+   r,   rH   k       z/SingleFiniteDomain.elements.<locals>.<listcomp>)r   rX   r/   r+   r/   r,   r>   i   s   zSingleFiniteDomain.elementsc                        fdd j D S )Nc                 3   s     | ]}t  j|ffV  qd S r6   r]   r_   r/   r+   r,   r;   n   s    z.SingleFiniteDomain.__iter__.<locals>.<genexpr>rX   r/   r+   r/   r,   rO   m      zSingleFiniteDomain.__iter__c                 C   s$   t |d \}}|| jko|| jv S rB   )tuplerW   rX   )r)   rL   r9   r:   r+   r+   r,   rM   p   s   zSingleFiniteDomain.__contains__N)r0   r1   r2   r3   rU   r4   rW   r?   rX   r>   rO   rM   r+   r+   r+   r,   rS   P   s    



rS   c                   @   r&   )ProductFiniteDomainz
    A Finite domain consisting of several other FiniteDomains

    Example: The possibilities of the rolls of three independent dice
    c                 C   s   t | j }dd |D S )Nc                 s   s    | ]}t |V  qd S r6   )r!   )r8   itemsr+   r+   r,   r;   ~   r<   z/ProductFiniteDomain.__iter__.<locals>.<genexpr>)r   Zdomains)r)   proditerr+   r+   r,   rO   |   s   
zProductFiniteDomain.__iter__c                 C   s   t |  S r6   r   r/   r+   r+   r,   r>      s   zProductFiniteDomain.elementsN)r0   r1   r2   r3   rO   r4   r>   r+   r+   r+   r,   rf   u   s
    rf   c                   @   sD   e Zd ZdZdd Zdd Zdd Zdd	 Zed
d Z	dd Z
dS )ConditionalFiniteDomainz
    A FiniteDomain that has been restricted by a condition

    Example: The possibilities of a die roll under the condition that the
    roll is even.
    c                 C   s"   |du r|S t |}t| ||S )zH
        Create a new instance of ConditionalFiniteDomain class
        T)r"   r   rU   )rV   domain	conditioncondr+   r+   r,   rU      s   zConditionalFiniteDomain.__new__c                 C   s>   | j t|}|dv r|S |jr|j|jkS tdt| )z
        Test the value. If value is boolean, return it. If value is equality
        relational (two objects are equal), return it with left-hand side
        being equal to right-hand side. Otherwise, raise ValueError exception.
        )TFzUndecidable if %s)rk   xreplacer.   Zis_Equalitylhsrhs
ValueErrorstr)r)   r`   r:   r+   r+   r,   _test   s   zConditionalFiniteDomain._testc                 C   s   || j v o	| |S r6   )
fulldomainrr   rK   r+   r+   r,   rM      rd   z$ConditionalFiniteDomain.__contains__c                    rb   )Nc                 3   s    | ]
}  |r|V  qd S r6   rr   r_   r/   r+   r,   r;      s    z3ConditionalFiniteDomain.__iter__.<locals>.<genexpr>)rs   r/   r+   r/   r,   rO      rd   z ConditionalFiniteDomain.__iter__c                    s.   t  jtrt fdd jjD  S td)Nc                    s&   g | ]}t  jj|ff v r|qS r+   )r^   rs   rW   r_   r/   r+   r,   rH      s    
z/ConditionalFiniteDomain.set.<locals>.<listcomp>z7Not implemented on multi-dimensional conditional domain)rT   rs   rS   r   rX   NotImplementedErrorr/   r+   r/   r,   rX      s
   zConditionalFiniteDomain.setc                 C   s
   t | S r6   )r5   rQ   r/   r+   r+   r,   rQ      rN   z"ConditionalFiniteDomain.as_booleanN)r0   r1   r2   r3   rU   rr   rM   rO   r4   rX   rQ   r+   r+   r+   r,   ri      s    	
ri   c                   @   s   e Zd Zdd Zedd Zeed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edd Zdd Zdd ZdS )SingleFiniteDistributionc                 G   s    t tt|}tj| g|R  S r6   )listmapr   r   rU   )rV   rD   r+   r+   r,   rU      s   z SingleFiniteDistribution.__new__c                  G   s   d S r6   r+   rC   r+   r+   r,   check   s   zSingleFiniteDistribution.checkc                    s"    j rt S  fdd jD S )Nc                    s   i | ]}|  |qS r+   pmf)r8   kr/   r+   r,   
<dictcomp>   rI   z1SingleFiniteDistribution.dict.<locals>.<dictcomp>)is_symbolicr$   rX   r/   r+   r/   r,   r.      s   zSingleFiniteDistribution.dictc                 G      t  r6   ru   r)   rD   r+   r+   r,   r{      s   zSingleFiniteDistribution.pmfc                 C   r   r6   r   r/   r+   r+   r,   rX      s   zSingleFiniteDistribution.setc                 C      | j jS r6   )r.   valuesr/   r+   r+   r,   <lambda>       z!SingleFiniteDistribution.<lambda>c                 C   r   r6   )r.   rg   r/   r+   r+   r,   r      r   c                 C   s   dS )NFr+   r/   r+   r+   r,   r      s    c                 C   r   r6   )r.   rO   r/   r+   r+   r,   r      r   c                 C   r   r6   )r.   __getitem__r/   r+   r+   r,   r      r   c                 G   s
   | j | S r6   rz   r   r+   r+   r,   r-      rN   z!SingleFiniteDistribution.__call__c                 C   rJ   r6   rc   rK   r+   r+   r,   rM      rN   z%SingleFiniteDistribution.__contains__N)r0   r1   r2   rU   staticmethodry   r4   r   r.   r{   rX   r   rg   r~   rO   r   r-   rM   r+   r+   r+   r,   rv      s"    

rv   c                   @   s   e Zd ZdZdZdd Zdd Zdd Zd	d
 Ze	dd Z
e	d!ddZe	dd Ze	dd Zd"ddZdd Zdd Zdd Zd#dd ZdS )$FinitePSpacezd
    A Finite Probability Space

    Represents the probabilities of a finite number of events.
    Tc                 C   s2   dd |  D }t|}t| ||}||_|S )Nc                 S   s   i | ]\}}t |t |qS r+   r(   r8   keyr:   r+   r+   r,   r}      s    z(FinitePSpace.__new__.<locals>.<dictcomp>)rg   r   r   rU   _density)rV   rj   densityZpublic_densityobjr+   r+   r,   rU      s   zFinitePSpace.__new__c                 C   sL   t |}| j}tt| d tr||tjS |t	|d d tjS )Nr   r\   )
r   r   rT   rw   keysr   getr   Zerore   )r)   r`   r   r+   r+   r,   prob_of   s
   zFinitePSpace.prob_ofc                    s*   t  fddt|D sJ t j|S )Nc                 3   s    | ]	}|j  jv V  qd S r6   )rW   r?   )r8   rr/   r+   r,   r;      s    z%FinitePSpace.where.<locals>.<genexpr>)allr    ri   rj   r)   rk   r+   r/   r,   where   s   zFinitePSpace.wherec                 C   sP   t || j}t }| jD ]}|t|}| |}||tj	| ||< q|S r6   )
r"   r   r'   rj   rm   r.   r   r   r   r   )r)   exprdr`   r:   probr+   r+   r,   compute_density   s   

zFinitePSpace.compute_densityc                 C   sH   |  |}tj}g }t|D ]}|| }||7 }|||f qt|S r6   )r   r   r   sortedappendr.   )r)   r   r   cum_probcdfr   r   r+   r+   r,   compute_cdf  s   
zFinitePSpace.compute_cdfFc                 C   s<   |  |}t| }t|dd d}|rdd |D }|S )Nc                 S   s   | d S r[   r+   )Zval_cumprobr+   r+   r,   r     r   z)FinitePSpace.sorted_cdf.<locals>.<lambda>)r   c                 S   s   g | ]
\}}|t |fqS r+   )float)r8   vr   r+   r+   r,   rH     s    z+FinitePSpace.sorted_cdf.<locals>.<listcomp>)r   rw   rg   r   )r)   r   Zpython_floatr   rg   Zsorted_itemsr+   r+   r,   
sorted_cdf  s   
zFinitePSpace.sorted_cdfc                    6   |  |}tddd t t fdd| D S )NtTrealc                 3   s(    | ]\}}t t|   | V  qd S r6   )r   r   r8   r|   r   r   r+   r,   r;     s   & z?FinitePSpace.compute_characteristic_function.<locals>.<genexpr>r   r   r   sumrg   r)   r   r   r+   r   r,   compute_characteristic_function     
 z,FinitePSpace.compute_characteristic_functionc                    r   )Nr   Tr   c                 3   s$    | ]\}}t |  | V  qd S r6   )r   r   r   r+   r,   r;   &  s   " zBFinitePSpace.compute_moment_generating_function.<locals>.<genexpr>r   r   r+   r   r,   "compute_moment_generating_function!  r   z/FinitePSpace.compute_moment_generating_functionNc                    s   |pj }t | fddjD }t ttfr.dd jD } fddjD }n fddjD }dd jD }tdd t|||D S )Nc                    s   g | ]}  |qS r+   r   r_   r/   r+   r,   rH   +  s    z4FinitePSpace.compute_expectation.<locals>.<listcomp>c                 S   s   g | ]
}t |d  d qS )r   r\   )re   r_   r+   r+   r,   rH   -  ra   c                       g | ]	}  t|qS r+   rm   r.   r_   r   r+   r,   rH   .  rP   c                    r   r+   r   r_   r   r+   r,   rH   0  rP   c                 S   s   g | ]}d qS Tr+   r_   r+   r+   r,   rH   1  s    c                 S   s*   g | ]\}}}t || |ftjd fqS r   )r
   r   r   )r8   r   r`   Zblvr+   r+   r,   rH   2  s    )r   r"   rj   rT   r   r   r   zip)r)   r   rvskwargsprobsZparse_domainZboolsr+   )r   r)   r,   compute_expectation(  s   


z FinitePSpace.compute_expectationc                 C   s^   |  |}tddd}t|dk |dkB ff}| D ]\}}||||kff }qt|t| S )NpTr   r   r\   )r   r   r   rg   r   r
   )r)   r   r   r   rX   r   valuer+   r+   r,   compute_quantile5  s   
zFinitePSpace.compute_quantilec                    s   t dd t D }t }|js tdt|j  t trG|j	j
j	sGt jtr6 jn jt fddj
D S ttfdd D S )Nc                 s   s    | ]}|j V  qd S r6   )rW   )r8   Zrsr+   r+   r,   r;   >  s    z+FinitePSpace.probability.<locals>.<genexpr>z)Cannot compare foreign random symbols, %sc                 3   s>    | ]}t | t|d  d ftjdfV  qdS )r   r\   TN)r
   r   subsrw   r   r   r_   rk   rvr)   r+   r,   r;   F  s     c                 3   s    | ]}  |V  qd S r6   r   r_   r/   r+   r,   r;   I  s    )r^   r    r"   issubsetr?   rp   rq   rT   r   Zfree_symbolsrj   ro   r   rn   r   r   r   )r)   rk   Zcond_symbolsrl   r+   r   r,   probability=  s   
 zFinitePSpace.probabilityc                    s8   |  | | | fdd| j D }t |S )Nc                    $   i | ]\}}  |r|| qS r+   rt   r   rj   r   r+   r,   r}   N      z2FinitePSpace.conditional_space.<locals>.<dictcomp>)r   r   r   rg   r   r)   rk   r   r+   r   r,   conditional_spaceK  s   


zFinitePSpace.conditional_spacer+   scipyc                 C   s   | j | j|||iS )zo
        Internal sample method

        Returns dictionary mapping RandomSymbol to realization value.
        )r   distributionsample)r)   sizeZlibraryZseedr+   r+   r,   r   R  s   zFinitePSpace.sample)Fr6   )r+   r   N)r0   r1   r2   r3   rR   rU   r   r   r   r   r   r   r   r   r   r   r   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ee	d
d Z
e	dd Ze	dd Zdd Zdd Zdd ZdddZdd Zdd ZdS )SingleFinitePSpacea  
    A single finite probability space

    Represents the probabilities of a set of random events that can be
    attributed to a single variable/symbol.

    This class is implemented by many of the standard FiniteRV types such as
    Die, Bernoulli, Coin, etc....
    c                 C   s   t | j| jjS r6   )rS   rW   r   rX   r/   r+   r+   r,   rj   e  s   zSingleFinitePSpace.domainc                 C   r   )z
        Helper property to check if the distribution
        of the random variable is having symbolic
        dimension.
        )r   r~   r/   r+   r+   r,   _is_symbolici  s   zSingleFinitePSpace._is_symbolicc                 C   rA   r[   rC   r/   r+   r+   r,   r   r  rE   zSingleFinitePSpace.distributionc                 C   s   | j |S r6   )r   r{   r)   r   r+   r+   r,   r{   v     zSingleFinitePSpace.pmfc                    s    fdd j j D S )Nc                    s    i | ]\}}t  j|f|qS r+   rZ   )r8   r:   r   r/   r+   r,   r}   |  s    z/SingleFinitePSpace._density.<locals>.<dictcomp>)r   r.   rg   r/   r+   r/   r,   r   y  s   

zSingleFinitePSpace._densityc                 C   s~   | j r/| |}tddd}td}t|t||tt| |  || jd j| jd j	fS t
|| j}t| j| j|S Nr   Tr   kir\   )r   r   r   r   r   r   r   rD   lowhighr"   r   r   rj   r   r   r)   r   r   r   r   r+   r+   r,   r     s   
:z2SingleFinitePSpace.compute_characteristic_functionc                 C   sz   | j r-| |}tddd}td}t|t||t||  || jd j| jd jfS t	|| j
}t| j| j|S r   )r   r   r   r   r   r   rD   r   r   r"   r   r   rj   r   r   r   r+   r+   r,   r     s   
6z5SingleFinitePSpace.compute_moment_generating_functionc                 C   s.   | j rtdt|| j}t| j| j|S )NzComputing quantile for random variables with symbolic dimension because the bounds of searching the required value is undetermined.)r   ru   r"   r   r   rj   r   r   r   r+   r+   r,   r     s   z#SingleFinitePSpace.compute_quantilec              	   C   s   | j r@tt|d }tddd}t|ttfsdn|||}t|t	| 
|t|| jd jk|| jd jk|ftjdfS t|| j}t| j| j|S )Nr   r|   TZintegerr\   )r   rw   r    r   rT   r   r   r   r   r
   r{   r   rD   r   r   r   r   r"   r   r   rj   r   r   )r)   r   r   r|   rl   r+   r+   r,   r     s   
z"SingleFinitePSpace.compute_densityc                 C   sb   | j r!| |}td}td}t|t|||| jd j|fS t|| j}t	| j
| j|S )Nr|   r   r\   )r   r   r   r   r   rD   r   r"   r   r   rj   r   r   )r)   r   r   r|   r   r+   r+   r,   r     s   
"zSingleFinitePSpace.compute_cdfNc                 K   s   | j rHt|d }tddd}|||}t|ttfsdn|}|dkr+| || n| || }tt	||ft
jdf|| jj| jjf S t|}t||}t| j| jj||fi |S )Nr   r|   Tr   )r   r    r   r   rT   r   r   r{   r   r
   r   r   r   r   r   Zdoitr   r"   r   rj   r   )r)   r   r   r   r   r|   rl   funcr+   r+   r,   r     s    $
z&SingleFinitePSpace.compute_expectationc                 C   s*   | j rtdt|}t| j| j|S )NzhCurrently, probability queries are not supported for random variables with symbolic sized distributions.)r   ru   r"   r   rj   r   r   r   r+   r+   r,   r     s   zSingleFinitePSpace.probabilityc                    sB   | j r|  | | | | fdd| j D }t |S )z
        This method is used for transferring the
        computation to probability method because
        conditional space of random variables with
        symbolic dimensions is currently not possible.
        c                    r   r+   rt   r   r   r+   r,   r}     r   z8SingleFinitePSpace.conditional_space.<locals>.<dictcomp>)r   r   r   r   rg   r   r   r+   r   r,   r     s   


z$SingleFinitePSpace.conditional_spacer6   )r0   r1   r2   r3   r4   rj   r   r   r{   r   r   r   r   r   r   r   r   r   r   r+   r+   r+   r,   r   [  s,    	



	
	
	r   c                   @   sL   e Zd ZdZedd Zeedd Zeedd Zdd	 Z	d
d Z
dS )ProductFinitePSpacezG
    A collection of several independent finite probability spaces
    c                 C   rF   )Nc                 S   s   g | ]}|j qS r+   )rj   r8   Zspacer+   r+   r,   rH     s    z.ProductFinitePSpace.domain.<locals>.<listcomp>)rf   spacesr/   r+   r+   r,   rj     r@   zProductFinitePSpace.domainc                 C   s`   t dd | jD  }i }|D ]}tt| \}}t|}t| }||tj| ||< qt	|S )Nc                 S   s   g | ]	}t |j qS r+   )iterr   rg   r   r+   r+   r,   rH     s    z0ProductFinitePSpace._density.<locals>.<listcomp>)
r   r   rw   r   r!   r   r   r   r   r   )r)   rh   r   rg   Zelemsr   r`   r   r+   r+   r,   r     s   zProductFinitePSpace._densityc                 C   rY   r6   )r   r   r/   r+   r+   r,   r     s   
zProductFinitePSpace.densityc                 C      t | |S r6   )r   r   r   r+   r+   r,   r     r   zProductFinitePSpace.probabilityc                 C   r   r6   )r   r   r   r+   r+   r,   r     r   z#ProductFinitePSpace.compute_densityN)r0   r1   r2   r3   r4   rj   r   r   r   r   r   r+   r+   r+   r,   r     s    
r   N)6r3   	itertoolsr   Zsympyr   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   Zsympy.core.containersr   Zsympy.core.logicr   Zsympy.core.relationalr   Zsympy.core.sympifyr   Zsympy.sets.setsr   Zsympy.stats.rvr   r   r   r   r   r   r    r!   r"   r#   r$   r%   r.   r'   r5   rS   rf   ri   rv   r   r   r   r+   r+   r+   r,   <module>   s$    	L8%1)||