o
    ,h!                     @   sb   d dl mZ d dlZd dlmZ d dlmZmZ d dlmZ d dl	m
Z
 dgZG dd de
ZdS )	    )OptionalN)Tensor)Categoricalconstraints)MixtureSameFamilyConstraint)DistributionMixtureSameFamilyc                	       s   e Zd ZU dZi Zeeejf e	d< dZ
	d#dededee ddf fd	d
Zd# fdd	Zejdd ZedefddZedefddZedefddZedef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_constraintsFNmixture_distributioncomponent_distributionvalidate_argsreturnc                    s  || _ || _t| j tstdt| jtstd| j j}| jjd d }tt|t|D ]\}}|dkrJ|dkrJ||krJtd| d| dq/| j j	j
d }| jjd }	|d uro|	d uro||	krot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_shaper   )_mixture_distribution_component_distribution
isinstancer   
ValueErrorr   r   zipreversedlogitsshape_num_componentr   len_event_ndimssuper__init__)selfr
   r   r   mdbscdbssize1size2kmkcr   	__class__ b/var/www/html/scripts/venv/lib/python3.10/site-packages/torch/distributions/mixture_same_family.pyr    <   sD   

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   _get_checked_instancer   r   expandr   r   r   r   r    _validate_args)r!   r   	_instancebatch_shape_compnewr   r(   r*   r+   r/   m   s   

zMixtureSameFamily.expandc                 C   s   t | jjS N)r   r   supportr!   r*   r*   r+   r5   ~   s   zMixtureSameFamily.supportc                 C      | j S r4   )r   r6   r*   r*   r+   r
         z&MixtureSameFamily.mixture_distributionc                 C   r7   r4   )r   r6   r*   r*   r+   r      r8   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!   r=   r*   r*   r+   r?      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       @)r<   r
   r=   r,   r>   r   variancer   r?   _padpow)r!   r=   mean_cond_varvar_cond_meanr*   r*   r+   r@      s   zMixtureSameFamily.variancec                 C   s0   |  |}| j|}| jj}tj|| ddS r9   )rA   r   cdfr
   r=   r,   r>   )r!   xcdf_xmix_probr*   r*   r+   rE      s   
zMixtureSameFamily.cdfc                 C   sJ   | j r| | | |}| j|}tj| jjdd}tj	|| ddS r9   )
r0   _validate_samplerA   r   log_probr,   log_softmaxr
   r   	logsumexp)r!   rF   
log_prob_xlog_mix_probr*   r*   r+   rJ      s   

zMixtureSameFamily.log_probc              	   C   s   t  Y t|}t| j}|| }| j}| j|}|j}| j|}|	|t 
dgt|d   }	|	t 
dgt| t 
dg | }	t |||	}
|
|W  d    S 1 s`w   Y  d S )Nr   )r,   no_gradr   r   r   r
   sampler   r   reshaper-   repeatgathersqueeze)r!   sample_shape
sample_len	batch_len
gather_dimes
mix_sample	mix_shapecomp_samplesmix_sample_rsamplesr*   r*   r+   rP      s"   

"$zMixtureSameFamily.samplec                 C   s   | d| j S )Nr   )	unsqueezer   )r!   rF   r*   r*   r+   rA      s   zMixtureSameFamily._padc                 C   st   t | j}t | jj}|dkrdn|| }|j}||d d t|dg  |dd   t| jdg  }|S )Nr   r   r   )r   r   r
   r   rQ   r,   r-   r   )r!   rF   dist_batch_ndimscat_batch_ndims	pad_ndimsxsr*   r*   r+   r<      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__r4   )"__name__
__module____qualname____doc__r	   dictstrr   
Constraint__annotations__has_rsampler   r   r   boolr    r/   dependent_propertyr5   propertyr
   r   r   r?   r@   rE   rJ   r,   r-   rP   rA   r<   re   __classcell__r*   r*   r(   r+   r      s>   
 *1

)typingr   r,   r   torch.distributionsr   r   torch.distributions.constraintsr    torch.distributions.distributionr   __all__r   r*   r*   r*   r+   <module>   s   