U
    ©Ê¹j1	  ã                   @   s.   d dl Z d dlmZ dgZG dd„ deƒZdS )é    N)ÚDistributionÚExponentialFamilyc                   @   s8   e Zd ZdZedd„ ƒZdd„ Zedd„ ƒZdd	„ Zd
S )r   aÒ  
    ExponentialFamily is the abstract base class for probability distributions belonging to an
    exponential family, whose probability mass/density function has the form is defined below

    .. math::

        p_{F}(x; \theta) = \exp(\langle t(x), \theta\rangle - F(\theta) + k(x))

    where :math:`\theta` denotes the natural parameters, :math:`t(x)` denotes the sufficient statistic,
    :math:`F(\theta)` is the log normalizer function for a given family and :math:`k(x)` is the carrier
    measure.

    Note:
        This class is an intermediary between the `Distribution` class and distributions which belong
        to an exponential family mainly to check the correctness of the `.entropy()` and analytic KL
        divergence methods. We use this class to compute the entropy and KL divergence using the AD
        framework and Bregman divergences (courtesy of: Frank Nielsen and Richard Nock, Entropies and
        Cross-entropies of Exponential Families).
    c                 C   s   t ‚dS )zv
        Abstract method for natural parameters. Returns a tuple of Tensors based
        on the distribution
        N©ÚNotImplementedError©Úself© r   ú]/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/distributions/exp_family.pyÚ_natural_params   s    z!ExponentialFamily._natural_paramsc                 G   s   t ‚dS )zƒ
        Abstract method for log normalizer function. Returns a log normalizer based on
        the distribution and input
        Nr   )r   Znatural_paramsr   r   r	   Ú_log_normalizer$   s    z!ExponentialFamily._log_normalizerc                 C   s   t ‚dS )zp
        Abstract method for expected carrier measure, which is required for computing
        entropy.
        Nr   r   r   r   r	   Ú_mean_carrier_measure+   s    z'ExponentialFamily._mean_carrier_measurec                 C   sv   | j  }dd„ | jD ƒ}| j|Ž }tjj| ¡ |dd�}||7 }t||ƒD ]&\}}|||  | j	d ¡ d¡8 }qJ|S )z_
        Method to compute the entropy using Bregman divergence of the log normalizer.
        c                 S   s   g | ]}|  ¡  ¡ ‘qS r   )ÚdetachZrequires_grad_)Ú.0Úpr   r   r	   Ú
<listcomp>8   s     z-ExponentialFamily.entropy.<locals>.<listcomp>T)Zcreate_graph)éÿÿÿÿr   )
r   r
   r   ÚtorchZautogradZgradÚsumÚzipZreshapeZ_batch_shape)r   ÚresultÚnparamsZ	lg_normalZ	gradientsÚnpÚgr   r   r	   Úentropy3   s    
 zExponentialFamily.entropyN)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úpropertyr
   r   r   r   r   r   r   r	   r      s   

)r   Z torch.distributions.distributionr   Ú__all__r   r   r   r   r	   Ú<module>   s   