U
    9%e$0                     @   sd   d dl Z d dlmZmZmZmZ d dl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)AnyDictOptionalTuple)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 fd	d
Zd=e
j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 dddZee
jdddZee
jdddZee
jdddZee
jdddZe
 fe
je
jdd d!Ze
 fe
je
jdd"d#Ze e
jd$d%d&Z!e
je
jdd'd(Z"e
je
jdd)d*Z#e
je
jdd+d,Z$d>ee
jd-d.d/Z%e
jdd0d1Z&e
jdd2d3Z'e
 fe(e)e d4f dd5d6Z*e
jddd7d8Z+d?d9d:Z,edd;d<Z-  Z.S )@r	   zP
    Distribution is the abstract base class for probability distributions.
    FTN)valuereturnc                 C   s   | dk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   _/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/torch/distributions/distribution.pyset_default_validate_args   s    z&Distribution.set_default_validate_args)batch_shapeevent_shapevalidate_argsc           	         s  || _ || _|d k	r|| _| jrz
| j}W n2 tk
r\   i }t| j dd d  Y nX | D ]\}}t	
|rzqf|| jkrttt| |trqft| |}||}| sftd| dt|j dt|j dt|  dt| d	| qft   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allr   __name__tupleshapereprsuper__init__)	selfr   r   r   r   param
constraintr
   validr   r   r   r)   &   s>    



 

: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   expandM   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   b   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   i   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   p   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   supportz   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   s*   t   | |W  5 Q R  S Q R X dS )z
        Generates a sample_shape shaped sample or sample_shape shaped batch of
        samples if the distribution parameters are batched.
        N)torchZ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.rsample)nr   c                 C   s   t dt | t|fS )zq
        Generates n samples or n batches of samples if the distribution
        parameters are batched.
        z6sample_n will be deprecated. Use .sample((n,)) instead)r   r   UserWarningr=   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/   rB   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/   rB   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:   exprG   r2   r   r   r   
perplexity   s    zDistribution.perplexity.c                 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 n0 tk
r   t| j dd	 d
  Y dS X |dk	s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:   Tensorr   lensizer   r   zipreversedr3   r   r   r   r   AssertionErrorr"   r#   r!   r$   r%   r&   r'   )	r*   r
   Zevent_dim_startZactual_shapeZexpected_shapeijr3   r-   r   r   r   _validate_sample  s>    



4zDistribution._validate_samplec                 C   sN   |d kr4t | j|jkr4td| jj d|j d|d k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_instance@  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 kr|qS r   )r   ).0k_r2   r   r   
<listcomp>I  s     
 z)Distribution.__repr__.<locals>.<listcomp>z, c                    s@   g | ]8}| d  j |  dkr* j | n j |   qS )z: rL   )r   ZnumelrO   )rY   pr2   r   r   r\   K  s   ())r   r   joinr   r$   )r*   Zparam_namesargs_stringr   r2   r   __repr__H  s    
zDistribution.__repr__)N)T)N)/r$   
__module____qualname____doc__Zhas_rsampleZhas_enumerate_supportr   staticmethodboolr   r:   r@   r   r)   r1   propertyr   r   r   strr   
Constraintr   r   r3   rM   r4   r5   r6   r8   r=   r;   intrA   rC   rD   rE   rF   rG   rI   r   r   rJ   rU   rX   rb   __classcell__r   r   r.   r   r	      sX   '	



		 2
)r   typingr   r   r   r   r:   Ztorch.distributionsr   Ztorch.distributions.utilsr   Ztorch.typesr   __all__r	   r   r   r   r   <module>   s   