a
    h=1                     @   sp   d dl Z d dlmZ d dlmZ d dlZd dlmZ d dlmZ d dl	m
Z
 d dlmZ dgZG d	d dZdS )
    N)Optional)
deprecated)Tensor)constraints)lazy_property)_sizeDistributionc                       s  e Zd ZdZdZdZdZeeddddZ	e
 e
 dfe
je
jee dd fd	d
Zd>edddZee
jdddZee
jdddZeeeejf dddZeeej dddZeedddZeedddZeedddZeedddZe
 feedd d!Ze
 feedd"d#Ze d$e!d%e"ed&d'd(Z#eedd)d*Z$eedd+d,Z%eedd-d.Z&d?eed/d0d1Z'edd2d3Z(edd4d5Z)e
 fee
jdd6d7Z*eddd8d9Z+d@d:d;Z,edd<d=Z-  Z.S )Ar   aS  
    Distribution is the abstract base class for probability distributions.

    Args:
        batch_shape (torch.Size): The shape over which parameters are batched.
        event_shape (torch.Size): The shape of a single sample (without batching).
        validate_args (bool, optional): Whether to validate arguments. Default: None.
    FTN)valuereturnc                 C   s   | dvrt | t_dS )a  
        Sets whether validation is enabled or disabled.

        The default behavior mimics Python's ``assert`` statement: validation
        is on by default, but is disabled if Python is run in optimized mode
        (via ``python -O``). Validation may be expensive, so you may want to
        disable it once a model is working.

        Args:
            value (bool): Whether to enable validation.
        )TFN)
ValueErrorr   _validate_args)r	    r   N/var/www/auris/lib/python3.9/site-packages/torch/distributions/distribution.pyset_default_validate_args   s    z&Distribution.set_default_validate_args)batch_shapeevent_shapevalidate_argsr
   c           	         s  || _ || _|d ur|| _| jrz
| j}W n0 tyZ   i }t| j dd d  Y n0 | D ]\}}t	
|rxqd|| jvrttt| |trqdt| |}||}t|sdtd| dt|j dt|j dt|  dt| d	| qdt   d S )
Nz$ does not define `arg_constraints`. zAPlease set `arg_constraints = {}` or initialize the distribution z2with `validate_args=False` to turn off validation.zExpected parameter z (
 of shape z) of distribution z to satisfy the constraint , but found invalid values:
)_batch_shape_event_shaper   arg_constraintsNotImplementedErrorwarningswarn	__class__itemsr   Zis_dependent__dict__
isinstancegetattrtyper   checktorch_is_all_truer   __name__tupleshapereprsuper__init__)	selfr   r   r   r   param
constraintr	   validr   r   r   r)   /   sP    






zDistribution.__init__)r   c                 C   s   t dS )a/  
        Returns a new distribution instance (or populates an existing instance
        provided by a derived class) with batch dimensions expanded to
        `batch_shape`. This method calls :class:`~torch.Tensor.expand` on
        the distribution's parameters. As such, this does not allocate new
        memory for the expanded distribution instance. Additionally,
        this does not repeat any args checking or parameter broadcasting in
        `__init__.py`, when an instance is first created.

        Args:
            batch_shape (torch.Size): the desired expanded size.
            _instance: new instance provided by subclasses that
                need to override `.expand`.

        Returns:
            New distribution instance with batch dimensions expanded to
            `batch_size`.
        Nr   )r*   r   	_instancer   r   r   expandV   s    zDistribution.expand)r
   c                 C   s   | j S )zF
        Returns the shape over which parameters are batched.
        )r   r*   r   r   r   r   k   s    zDistribution.batch_shapec                 C   s   | j S )zJ
        Returns the shape of a single sample (without batching).
        )r   r2   r   r   r   r   r   s    zDistribution.event_shapec                 C   s   t dS )a
  
        Returns a dictionary from argument names to
        :class:`~torch.distributions.constraints.Constraint` objects that
        should be satisfied by each argument of this distribution. Args that
        are not tensors need not appear in this dict.
        Nr/   r2   r   r   r   r   y   s    zDistribution.arg_constraintsc                 C   s   t dS )z
        Returns a :class:`~torch.distributions.constraints.Constraint` object
        representing this distribution's support.
        Nr/   r2   r   r   r   support   s    zDistribution.supportc                 C   s   t dS )z7
        Returns the mean of the distribution.
        Nr/   r2   r   r   r   mean   s    zDistribution.meanc                 C   s   t | j ddS )z7
        Returns the mode of the distribution.
        z does not implement modeN)r   r   r2   r   r   r   mode   s    zDistribution.modec                 C   s   t dS )z;
        Returns the variance of the distribution.
        Nr/   r2   r   r   r   variance   s    zDistribution.variancec                 C   s
   | j  S )zE
        Returns the standard deviation of the distribution.
        )r6   sqrtr2   r   r   r   stddev   s    zDistribution.stddev)sample_shaper
   c                 C   s6   t   | |W  d   S 1 s(0    Y  dS )z
        Generates a sample_shape shaped sample or sample_shape shaped batch of
        samples if the distribution parameters are batched.
        N)r"   Zno_gradrsampler*   r9   r   r   r   sample   s    
zDistribution.samplec                 C   s   t dS )z
        Generates a sample_shape shaped reparameterized sample or sample_shape
        shaped batch of reparameterized samples if the distribution parameters
        are batched.
        Nr/   r;   r   r   r   r:      s    zDistribution.rsamplez=`sample_n(n)` will be deprecated. Use `sample((n,))` instead.)category)nr
   c                 C   s   |  t|fS )zq
        Generates n samples or n batches of samples if the distribution
        parameters are batched.
        )r<   r"   Size)r*   r>   r   r   r   sample_n   s    	zDistribution.sample_nc                 C   s   t dS )z
        Returns the log of the probability density/mass function evaluated at
        `value`.

        Args:
            value (Tensor):
        Nr/   r*   r	   r   r   r   log_prob   s    zDistribution.log_probc                 C   s   t dS )z
        Returns the cumulative density/mass function evaluated at
        `value`.

        Args:
            value (Tensor):
        Nr/   rA   r   r   r   cdf   s    zDistribution.cdfc                 C   s   t dS )z
        Returns the inverse cumulative density/mass function evaluated at
        `value`.

        Args:
            value (Tensor):
        Nr/   rA   r   r   r   icdf   s    zDistribution.icdf)r1   r
   c                 C   s   t dS )ar  
        Returns tensor containing all values supported by a discrete
        distribution. The result will enumerate over dimension 0, so the shape
        of the result will be `(cardinality,) + batch_shape + event_shape`
        (where `event_shape = ()` for univariate distributions).

        Note that this enumerates over all batched tensors in lock-step
        `[[0, 0], [1, 1], ...]`. With `expand=False`, enumeration happens
        along dim 0, but with the remaining batch dimensions being
        singleton dimensions, `[[0], [1], ..`.

        To iterate over the full Cartesian product use
        `itertools.product(m.enumerate_support())`.

        Args:
            expand (bool): whether to expand the support over the
                batch dims to match the distribution's `batch_shape`.

        Returns:
            Tensor iterating over dimension 0.
        Nr/   )r*   r1   r   r   r   enumerate_support   s    zDistribution.enumerate_supportc                 C   s   t dS )z
        Returns entropy of distribution, batched over batch_shape.

        Returns:
            Tensor of shape batch_shape.
        Nr/   r2   r   r   r   entropy   s    zDistribution.entropyc                 C   s   t |  S )z
        Returns perplexity of distribution, batched over batch_shape.

        Returns:
            Tensor of shape batch_shape.
        )r"   exprF   r2   r   r   r   
perplexity  s    zDistribution.perplexityc                 C   s,   t |tjst|}t|| j | j S )ax  
        Returns the size of the sample returned by the distribution, given
        a `sample_shape`. Note, that the batch and event shapes of a distribution
        instance are fixed at the time of construction. If this is empty, the
        returned shape is upcast to (1,).

        Args:
            sample_shape (torch.Size): the size of the sample to be drawn.
        )r   r"   r?   r   r   r;   r   r   r   _extended_shape
  s    

zDistribution._extended_shapec           	      C   sV  t |tjstdt| t| j }| |d | jkr\td|  d| j d| }| j| j }tt	|t	|D ]6\}}|dkr|dkr||krtd| d| dqz
| j
}W n. ty   t| j dd	 d
  Y dS 0 |dusJ ||}t|sRtdt|j dt|j dt| dt|  d| 
dS )a  
        Argument validation for distribution methods such as `log_prob`,
        `cdf` and `icdf`. The rightmost dimensions of a value to be
        scored via these methods must agree with the distribution's batch
        and event shapes.

        Args:
            value (Tensor): the tensor whose log probability is to be
                computed by the `log_prob` method.
        Raises
            ValueError: when the rightmost dimensions of `value` do not match the
                distribution's batch and event shapes.
        z/The value argument to log_prob must be a TensorNz5The right-most size of value must match event_shape: z vs .   z9Value is not broadcastable with batch_shape+event_shape: z% does not define `support` to enable z;sample validation. Please initialize the distribution with z-`validate_args=False` to turn off validation.zExpected value argument (r   z) to be within the support (z) of the distribution r   )r   r"   r   r   lensizer   r   zipreversedr3   r   r   r   r   r!   r#   r    r$   r%   r&   r'   )	r*   r	   Zevent_dim_startZactual_shapeZexpected_shapeijr3   r-   r   r   r   _validate_sample  sR    


zDistribution._validate_samplec                 C   sN   |d u r4t | j|jkr4td| jj d|j d|d u rJ| t | S |S )Nz	Subclass z of zR that defines a custom __init__ method must also define a custom .expand() method.)r    r)   r   r   r$   __new__)r*   clsr0   r   r   r   _get_checked_instanceJ  s
    z"Distribution._get_checked_instancec                    sD    fdd j  D }d fdd|D } jjd | d S )Nc                    s   g | ]\}}| j v r|qS r   )r   ).0k_r2   r   r   
<listcomp>S      z)Distribution.__repr__.<locals>.<listcomp>z, c                    s@   g | ]8}| d  j |  dkr* j | n j |   qS )z: rK   )r   ZnumelrM   )rV   pr2   r   r   rY   U  s   ())r   r   joinr   r$   )r*   Zparam_namesargs_stringr   r2   r   __repr__R  s    
zDistribution.__repr__)N)T)N)/r$   
__module____qualname____doc__Zhas_rsampleZhas_enumerate_supportr   staticmethodboolr   r"   r?   r   r)   r   r1   propertyr   r   dictstrr   
Constraintr   r3   r   r4   r5   r6   r8   r<   r:   r   FutureWarningintr@   rB   rC   rD   rE   rF   rH   rI   rR   rU   r`   __classcell__r   r   r.   r   r      sb   	'	


		2
)r   typingr   Ztyping_extensionsr   r"   r   Ztorch.distributionsr   Ztorch.distributions.utilsr   Ztorch.typesr   __all__r   r   r   r   r   <module>   s   