U
    ©Ê¹j!  ã                   @   sJ   d dl mZ d dlZd dlmZmZ d dlmZ dgZG dd„ deƒZ	dS )é    )ÚDictN)ÚCategoricalÚconstraints)ÚDistributionÚMixtureSameFamilyc                       sÂ   e Zd ZU dZi Zeeejf e	d< dZ
d‡ fdd„	Zd ‡ fdd„	Zej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e ¡ fdd„Zdd„ Zdd„ Zdd„ Z‡  ZS )!r   aÇ  
    The `MixtureSameFamily` distribution implements a (batch of) mixture
    distribution where all component are from different parameterizations of
    the same distribution type. It is parameterized by a `Categorical`
    "selecting distribution" (over `k` component) and a component
    distribution, i.e., a `Distribution` with a rightmost batch shape
    (equal to `[k]`) which indexes each (batch of) component.

    Examples::

        >>> # xdoctest: +SKIP("undefined vars")
        >>> # Construct Gaussian Mixture Model in 1D consisting of 5 equally
        >>> # weighted normal distributions
        >>> mix = D.Categorical(torch.ones(5,))
        >>> comp = D.Normal(torch.randn(5,), torch.rand(5,))
        >>> gmm = MixtureSameFamily(mix, comp)

        >>> # Construct Gaussian Mixture Model in 2D consisting of 5 equally
        >>> # weighted bivariate normal distributions
        >>> mix = D.Categorical(torch.ones(5,))
        >>> comp = D.Independent(D.Normal(
        ...          torch.randn(5,2), torch.rand(5,2)), 1)
        >>> gmm = MixtureSameFamily(mix, comp)

        >>> # Construct a batch of 3 Gaussian Mixture Models in 2D each
        >>> # consisting of 5 random weighted bivariate normal distributions
        >>> mix = D.Categorical(torch.rand(3,5))
        >>> comp = D.Independent(D.Normal(
        ...         torch.randn(3,5,2), torch.rand(3,5,2)), 1)
        >>> gmm = MixtureSameFamily(mix, comp)

    Args:
        mixture_distribution: `torch.distributions.Categorical`-like
            instance. Manages the probability of selecting component.
            The number of categories must match the rightmost batch
            dimension of the `component_distribution`. Must have either
            scalar `batch_shape` or `batch_shape` matching
            `component_distribution.batch_shape[:-1]`
        component_distribution: `torch.distributions.Distribution`-like
            instance. Right-most batch dimension indexes component.
    Úarg_constraintsFNc                    s  || _ || _t| j tƒs tdƒ‚t| jtƒs4tdƒ‚| j j}| jjd d… }tt|ƒt|ƒƒD ]6\}}|dkr^|dkr^||kr^td|› d|› d�ƒ‚q^| j j	j
d }| jjd }	|d k	rÞ|	d k	rÞ||	krÞtd|› d	|	› d�ƒ‚|| _| jj}
t|
ƒ| _tƒ j||
|d
� d S )NzU The Mixture distribution needs to be an  instance of torch.distributions.CategoricalzUThe Component distribution need to be an instance of torch.distributions.Distributionéÿÿÿÿé   z$`mixture_distribution.batch_shape` (z>) is not compatible with `component_distribution.batch_shape`(ú)z"`mixture_distribution component` (z;) does not equal `component_distribution.batch_shape[-1]` (©Úbatch_shapeÚevent_shapeÚvalidate_args)Ú_mixture_distributionÚ_component_distributionÚ
isinstancer   Ú
ValueErrorr   r   ÚzipÚreversedÚlogitsÚshapeÚ_num_componentr   ÚlenÚ_event_ndimsÚsuperÚ__init__)ÚselfÚmixture_distributionÚcomponent_distributionr   ZmdbsZcdbsZsize1Zsize2ÚkmÚkcr   ©Ú	__class__© úf/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/distributions/mixture_same_family.pyr   7   s>    ÿÿÿÿ
  ÿzMixtureSameFamily.__init__c                    sx   t  |¡}|| jf }|  t|¡}| j |¡|_| j |¡|_| j|_| j|_|jj	}t
t|ƒj||dd� | j|_|S )NFr   )ÚtorchÚSizer   Z_get_checked_instancer   r   Úexpandr   r   r   r   r   Ú_validate_args)r   r   Z	_instanceZbatch_shape_compÚnewr   r!   r#   r$   r'   e   s"    
ÿ
  ÿzMixtureSameFamily.expandc                 C   s   | j jS ©N)r   Úsupport©r   r#   r#   r$   r+   v   s    zMixtureSameFamily.supportc                 C   s   | j S r*   )r   r,   r#   r#   r$   r   |   s    z&MixtureSameFamily.mixture_distributionc                 C   s   | j S r*   )r   r,   r#   r#   r$   r   €   s    z(MixtureSameFamily.component_distributionc                 C   s*   |   | jj¡}tj|| jj d| j d�S ©Nr   ©Údim)Ú_pad_mixture_dimensionsr   Úprobsr%   Úsumr   Úmeanr   )r   r1   r#   r#   r$   r3   „   s
    
 ÿzMixtureSameFamily.meanc                 C   s`   |   | jj¡}tj|| jj d| j d�}tj|| jj|  	| j¡  
d¡ d| j d�}|| S )Nr   r.   g       @)r0   r   r1   r%   r2   r   Úvariancer   r3   Ú_padÚpow)r   r1   Zmean_cond_varZvar_cond_meanr#   r#   r$   r4   ‹   s    
 ÿþzMixtureSameFamily.variancec                 C   s0   |   |¡}| j |¡}| jj}tj|| dd�S r-   )r5   r   Úcdfr   r1   r%   r2   )r   ÚxZcdf_xZmix_probr#   r#   r$   r7   ˜   s    
zMixtureSameFamily.cdfc                 C   sJ   | j r|  |¡ |  |¡}| j |¡}tj| jjdd�}tj	|| dd�S r-   )
r(   Z_validate_sampler5   r   Úlog_probr%   Zlog_softmaxr   r   Z	logsumexp)r   r8   Z
log_prob_xZlog_mix_probr#   r#   r$   r9   Ÿ   s    

 ÿzMixtureSameFamily.log_probc              
   C   sÂ   t  ¡ �° t|ƒ}t| jƒ}|| }| j}| j |¡}|j}| j |¡}| 	|t  
dgt|ƒd  ¡ ¡}	|	 t  
dgt|ƒ ¡t  
dg¡ | ¡}	t  |||	¡}
|
 |¡W  5 Q R £ S Q R X d S )Nr	   )r%   Zno_gradr   r   r   r   Úsampler   r   Úreshaper&   ÚrepeatZgatherZsqueeze)r   Zsample_shapeZ
sample_lenZ	batch_lenZ
gather_dimÚesZ
mix_sampleZ	mix_shapeZcomp_samplesZmix_sample_rZsamplesr#   r#   r$   r:   ©   s     

ÿ"ÿzMixtureSameFamily.samplec                 C   s   |  d| j ¡S )Nr   )Z	unsqueezer   )r   r8   r#   r#   r$   r5   Â   s    zMixtureSameFamily._padc                 C   st   | j  ¡ }| jj  ¡ }|dkr"dn|| }|j}| |d d… t |dg ¡ |dd …  t | jdg ¡ ¡}|S )Nr	   r   r   )r   Znumelr   r   r;   r%   r&   r   )r   r8   Zdist_batch_ndimsZcat_batch_ndimsZ	pad_ndimsZxsr#   r#   r$   r0   Å   s    

ÿ
þýÿz)MixtureSameFamily._pad_mixture_dimensionsc                 C   s    d| j › d| j› �}d| d S )Nz
  z,
  zMixtureSameFamily(r
   )r   r   )r   Úargs_stringr#   r#   r$   Ú__repr__Ò   s    ÿzMixtureSameFamily.__repr__)N)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Ústrr   Ú
ConstraintÚ__annotations__Zhas_rsampler   r'   Zdependent_propertyr+   Úpropertyr   r   r3   r4   r7   r9   r%   r&   r:   r5   r0   r?   Ú__classcell__r#   r#   r!   r$   r   
   s,   
) ÿ.





)
Útypingr   r%   Ztorch.distributionsr   r   Z torch.distributions.distributionr   Ú__all__r   r#   r#   r#   r$   Ú<module>   s
   