U
    dG                     @   s  d Z ddlZddddddd	d
dddddddddddddddddddddgZG d d deZG d!d" d"eZd#d ZG d$d% d%eeZG d&d' d'eZ	G d(d) d)eZ
G d*d+ d+eZG d,d- d-eZG d.d/ d/eZG d0d1 d1eZG d2d3 d3eZG d4d5 d5eZG d6d7 d7eZG d8d9 d9eZG d:d; d;eZG d<d= d=eZG d>d? d?eZG d@dA dAeZG dBdC dCeZG dDdE dEeZG dFdG dGeZG dHdI dIeZG dJdK dKeZG dLdM dMeZG dNdO dOeZG dPdQ dQeZG dRdS dSeZe Z eZ!e	Z"e
 Z#e Z$edZ%edTZ&eZ'e Z(e"e(dTZ)edUZ*edUZ+eZ,eZ-eZ.eZ/edUdVZ0eZ1eZ2e Z3e Z4e Z5e Z6e Z7e Z8e Z9e Z:eZ;eZ<dS )Wa  
The following constraints are implemented:

- ``constraints.boolean``
- ``constraints.cat``
- ``constraints.corr_cholesky``
- ``constraints.dependent``
- ``constraints.greater_than(lower_bound)``
- ``constraints.greater_than_eq(lower_bound)``
- ``constraints.independent(constraint, reinterpreted_batch_ndims)``
- ``constraints.integer_interval(lower_bound, upper_bound)``
- ``constraints.interval(lower_bound, upper_bound)``
- ``constraints.less_than(upper_bound)``
- ``constraints.lower_cholesky``
- ``constraints.lower_triangular``
- ``constraints.multinomial``
- ``constraints.nonnegative_integer``
- ``constraints.one_hot``
- ``constraints.positive_integer``
- ``constraints.positive``
- ``constraints.positive_semidefinite``
- ``constraints.positive_definite``
- ``constraints.real_vector``
- ``constraints.real``
- ``constraints.simplex``
- ``constraints.symmetric``
- ``constraints.stack``
- ``constraints.square``
- ``constraints.symmetric``
- ``constraints.unit_interval``
    N
Constraintbooleancatcorr_cholesky	dependentdependent_propertygreater_thangreater_than_eqindependentinteger_intervalintervalhalf_open_intervalis_dependent	less_thanlower_choleskylower_triangularmultinomialnonnegative_integerpositivepositive_semidefinitepositive_definitepositive_integerrealreal_vectorsimplexsquarestack	symmetricunit_intervalc                   @   s(   e Zd ZdZdZdZdd Zdd ZdS )	r   a  
    Abstract base class for constraints.

    A constraint object represents a region over which a variable is valid,
    e.g. within which a variable can be optimized.

    Attributes:
        is_discrete (bool): Whether constrained space is discrete.
            Defaults to False.
        event_dim (int): Number of rightmost dimensions that together define
            an event. The :meth:`check` method will remove this many dimensions
            when computing validity.
    Fr   c                 C   s   t dS )z
        Returns a byte tensor of ``sample_shape + batch_shape`` indicating
        whether each event in value satisfies this constraint.
        N)NotImplementedErrorselfvalue r#   C/tmp/pip-unpacked-wheel-ua33x9lu/torch/distributions/constraints.pycheckU   s    zConstraint.checkc                 C   s   | j jdd  d S )N   z())	__class____name__r!   r#   r#   r$   __repr__\   s    zConstraint.__repr__N)r(   
__module____qualname____doc__is_discrete	event_dimr%   r*   r#   r#   r#   r$   r   D   s
   c                       sX   e Zd ZdZeed fdd
Zedd Zedd Zeedd	d
Z	dd Z
  ZS )
_DependentaI  
    Placeholder for variables whose support depends on other variables.
    These variables obey no simple coordinate-wise constraints.

    Args:
        is_discrete (bool): Optional value of ``.is_discrete`` in case this
            can be computed statically. If not provided, access to the
            ``.is_discrete`` attribute will raise a NotImplementedError.
        event_dim (int): Optional value of ``.event_dim`` in case this
            can be computed statically. If not provided, access to the
            ``.event_dim`` attribute will raise a NotImplementedError.
    r.   r/   c                   s   || _ || _t   d S N)_is_discrete
_event_dimsuper__init__r!   r.   r/   r'   r#   r$   r6   m   s    z_Dependent.__init__c                 C   s   | j tkrtd| j S )Nz,.is_discrete cannot be determined statically)r3   NotImplementedr   r)   r#   r#   r$   r.   r   s    
z_Dependent.is_discretec                 C   s   | j tkrtd| j S )Nz*.event_dim cannot be determined statically)r4   r9   r   r)   r#   r#   r$   r/   x   s    
z_Dependent.event_dimc                C   s(   |t kr| j}|t kr| j}t||dS )z
        Support for syntax to customize static attributes::

            constraints.dependent(is_discrete=True, event_dim=1)
        r1   )r9   r3   r4   r0   r7   r#   r#   r$   __call__~   s
    z_Dependent.__call__c                 C   s   t dd S )Nz1Cannot determine validity of dependent constraint)
ValueErrorr!   xr#   r#   r$   r%      s    z_Dependent.check)r(   r+   r,   r-   r9   r6   propertyr.   r/   r:   r%   __classcell__r#   r#   r8   r$   r0   `   s   

r0   c                 C   s
   t | tS r2   )
isinstancer0   )
constraintr#   r#   r$   r      s    c                       s2   e Zd ZdZdeed fddZdd Z  ZS )	_DependentPropertya  
    Decorator that extends @property to act like a `Dependent` constraint when
    called on a class and act like a property when called on an object.

    Example::

        class Uniform(Distribution):
            def __init__(self, low, high):
                self.low = low
                self.high = high
            @constraints.dependent_property(is_discrete=False, event_dim=0)
            def support(self):
                return constraints.interval(self.low, self.high)

    Args:
        fn (callable): The function to be decorated.
        is_discrete (bool): Optional value of ``.is_discrete`` in case this
            can be computed statically. If not provided, access to the
            ``.is_discrete`` attribute will raise a NotImplementedError.
        event_dim (int): Optional value of ``.event_dim`` in case this
            can be computed statically. If not provided, access to the
            ``.event_dim`` attribute will raise a NotImplementedError.
    Nr1   c                   s   t  | || _|| _d S r2   )r5   r6   r3   r4   )r!   fnr.   r/   r8   r#   r$   r6      s    z_DependentProperty.__init__c                 C   s   t || j| jdS )z
        Support for syntax to customize static attributes::

            @constraints.dependent_property(is_discrete=True, event_dim=1)
            def support(self):
                ...
        r1   )rB   r3   r4   )r!   rC   r#   r#   r$   r:      s    z_DependentProperty.__call__)N)r(   r+   r,   r-   r9   r6   r:   r?   r#   r#   r8   r$   rB      s   rB   c                       sH   e Zd ZdZ fddZedd Zedd Zdd	 Zd
d Z	  Z
S )_IndependentConstraintz
    Wraps a constraint by aggregating over ``reinterpreted_batch_ndims``-many
    dims in :meth:`check`, so that an event is valid only if all its
    independent entries are valid.
    c                    sB   t |tstt |tst|dks(t|| _|| _t   d S Nr   )r@   r   AssertionErrorintbase_constraintreinterpreted_batch_ndimsr5   r6   )r!   rH   rI   r8   r#   r$   r6      s    z_IndependentConstraint.__init__c                 C   s   | j jS r2   )rH   r.   r)   r#   r#   r$   r.      s    z"_IndependentConstraint.is_discretec                 C   s   | j j| j S r2   )rH   r/   rI   r)   r#   r#   r$   r/      s    z _IndependentConstraint.event_dimc                 C   sp   | j |}| | jk r@| j j| j }td| d|  ||jd | | j  d }|d}|S )NzExpected value.dim() >= z	 but got rK   )	rH   r%   dimrI   r/   r;   Zreshapeshapeall)r!   r"   resultexpectedr#   r#   r$   r%      s    "
z_IndependentConstraint.checkc                 C   s"   d | jjdd  t| j| jS )Nz
{}({}, {})r&   )formatr'   r(   reprrH   rI   r)   r#   r#   r$   r*      s    z_IndependentConstraint.__repr__)r(   r+   r,   r-   r6   r>   r.   r/   r%   r*   r?   r#   r#   r8   r$   rD      s   

	rD   c                   @   s   e Zd ZdZdZdd ZdS )_Booleanz/
    Constrain to the two values `{0, 1}`.
    Tc                 C   s   |dk|dkB S )Nr   r&   r#   r    r#   r#   r$   r%      s    z_Boolean.checkN)r(   r+   r,   r-   r.   r%   r#   r#   r#   r$   rS      s   rS   c                   @   s    e Zd ZdZdZdZdd ZdS )_OneHotz'
    Constrain to one-hot vectors.
    Tr&   c                 C   s.   |dk|dkB }| dd}|d|@ S )Nr   r&   rK   )sumeqrN   )r!   r"   Z
is_booleanis_normalizedr#   r#   r$   r%      s    z_OneHot.checkN)r(   r+   r,   r-   r.   r/   r%   r#   r#   r#   r$   rT      s   rT   c                       s4   e Zd ZdZdZ fddZdd Zdd Z  ZS )	_IntegerIntervalzH
    Constrain to an integer interval `[lower_bound, upper_bound]`.
    Tc                    s   || _ || _t   d S r2   lower_boundupper_boundr5   r6   r!   rZ   r[   r8   r#   r$   r6      s    z_IntegerInterval.__init__c                 C   s    |d dk| j |k@ || jk@ S Nr&   r   rZ   r[   r    r#   r#   r$   r%      s    z_IntegerInterval.checkc                 C   s(   | j jdd  }|d| j| j7 }|S Nr&   z (lower_bound={}, upper_bound={})r'   r(   rQ   rZ   r[   r!   Z
fmt_stringr#   r#   r$   r*     s    z_IntegerInterval.__repr__	r(   r+   r,   r-   r.   r6   r%   r*   r?   r#   r#   r8   r$   rX      s
   rX   c                       s4   e Zd ZdZdZ fddZdd Zdd Z  ZS )	_IntegerLessThanzA
    Constrain to an integer interval `(-inf, upper_bound]`.
    Tc                    s   || _ t   d S r2   r[   r5   r6   r!   r[   r8   r#   r$   r6     s    z_IntegerLessThan.__init__c                 C   s   |d dk|| j k@ S r]   r[   r    r#   r#   r$   r%     s    z_IntegerLessThan.checkc                 C   s$   | j jdd  }|d| j7 }|S Nr&   z(upper_bound={})r'   r(   rQ   r[   ra   r#   r#   r$   r*     s    z_IntegerLessThan.__repr__rb   r#   r#   r8   r$   rc   	  s
   rc   c                       s4   e Zd ZdZdZ fddZdd Zdd Z  ZS )	_IntegerGreaterThanz@
    Constrain to an integer interval `[lower_bound, inf)`.
    Tc                    s   || _ t   d S r2   rZ   r5   r6   r!   rZ   r8   r#   r$   r6   "  s    z_IntegerGreaterThan.__init__c                 C   s   |d dk|| j k@ S r]   rZ   r    r#   r#   r$   r%   &  s    z_IntegerGreaterThan.checkc                 C   s$   | j jdd  }|d| j7 }|S Nr&   z(lower_bound={})r'   r(   rQ   rZ   ra   r#   r#   r$   r*   )  s    z_IntegerGreaterThan.__repr__rb   r#   r#   r8   r$   ri     s
   ri   c                   @   s   e Zd ZdZdd ZdS )_RealzF
    Trivially constrain to the extended real line `[-inf, inf]`.
    c                 C   s   ||kS r2   r#   r    r#   r#   r$   r%   3  s    z_Real.checkN)r(   r+   r,   r-   r%   r#   r#   r#   r$   ro   /  s   ro   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )_GreaterThanz=
    Constrain to a real half line `(lower_bound, inf]`.
    c                    s   || _ t   d S r2   rj   rk   r8   r#   r$   r6   ;  s    z_GreaterThan.__init__c                 C   s
   | j |k S r2   rl   r    r#   r#   r$   r%   ?  s    z_GreaterThan.checkc                 C   s$   | j jdd  }|d| j7 }|S rm   rn   ra   r#   r#   r$   r*   B  s    z_GreaterThan.__repr__r(   r+   r,   r-   r6   r%   r*   r?   r#   r#   r8   r$   rp   7  s   rp   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )_GreaterThanEqz=
    Constrain to a real half line `[lower_bound, inf)`.
    c                    s   || _ t   d S r2   rj   rk   r8   r#   r$   r6   L  s    z_GreaterThanEq.__init__c                 C   s
   | j |kS r2   rl   r    r#   r#   r$   r%   P  s    z_GreaterThanEq.checkc                 C   s$   | j jdd  }|d| j7 }|S rm   rn   ra   r#   r#   r$   r*   S  s    z_GreaterThanEq.__repr__rq   r#   r#   r8   r$   rr   H  s   rr   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )	_LessThanz>
    Constrain to a real half line `[-inf, upper_bound)`.
    c                    s   || _ t   d S r2   rd   re   r8   r#   r$   r6   ]  s    z_LessThan.__init__c                 C   s
   || j k S r2   rf   r    r#   r#   r$   r%   a  s    z_LessThan.checkc                 C   s$   | j jdd  }|d| j7 }|S rg   rh   ra   r#   r#   r$   r*   d  s    z_LessThan.__repr__rq   r#   r#   r8   r$   rs   Y  s   rs   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )	_IntervalzD
    Constrain to a real interval `[lower_bound, upper_bound]`.
    c                    s   || _ || _t   d S r2   rY   r\   r8   r#   r$   r6   n  s    z_Interval.__init__c                 C   s   | j |k|| jk@ S r2   r^   r    r#   r#   r$   r%   s  s    z_Interval.checkc                 C   s(   | j jdd  }|d| j| j7 }|S r_   r`   ra   r#   r#   r$   r*   v  s    z_Interval.__repr__rq   r#   r#   r8   r$   rt   j  s   rt   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )_HalfOpenIntervalzD
    Constrain to a real interval `[lower_bound, upper_bound)`.
    c                    s   || _ || _t   d S r2   rY   r\   r8   r#   r$   r6     s    z_HalfOpenInterval.__init__c                 C   s   | j |k|| jk @ S r2   r^   r    r#   r#   r$   r%     s    z_HalfOpenInterval.checkc                 C   s(   | j jdd  }|d| j| j7 }|S r_   r`   ra   r#   r#   r$   r*     s    z_HalfOpenInterval.__repr__rq   r#   r#   r8   r$   ru   |  s   ru   c                   @   s   e Zd ZdZdZdd ZdS )_Simplexz
    Constrain to the unit simplex in the innermost (rightmost) dimension.
    Specifically: `x >= 0` and `x.sum(-1) == 1`.
    r&   c                 C   s(   t j|dkdd|dd  dk @ S )Nr   rK   rL   r&   ư>)torchrN   rU   absr    r#   r#   r$   r%     s    z_Simplex.checkNr(   r+   r,   r-   r/   r%   r#   r#   r#   r$   rv     s   rv   c                   @   s(   e Zd ZdZdZdZdd Zdd ZdS )	_Multinomiala3  
    Constrain to nonnegative integer values summing to at most an upper bound.

    Note due to limitations of the Multinomial distribution, this currently
    checks the weaker condition ``value.sum(-1) <= upper_bound``. In the future
    this may be strengthened to ``value.sum(-1) == upper_bound``.
    Tr&   c                 C   s
   || _ d S r2   rf   re   r#   r#   r$   r6     s    z_Multinomial.__init__c                 C   s"   |dkj dd|jdd| jk@ S )Nr   rK   rw   )rN   rU   r[   r<   r#   r#   r$   r%     s    z_Multinomial.checkN)r(   r+   r,   r-   r.   r/   r6   r%   r#   r#   r#   r$   r|     s
   r|   c                   @   s   e Zd ZdZdZdd ZdS )_LowerTriangularz8
    Constrain to lower-triangular square matrices.
       c                 C   s.   |  }||k|jd d d dd S )NrJ   rK   r   )trilviewrM   min)r!   r"   
value_trilr#   r#   r$   r%     s    z_LowerTriangular.checkNr{   r#   r#   r#   r$   r}     s   r}   c                   @   s   e Zd ZdZdZdd ZdS )_LowerCholeskyzP
    Constrain to lower-triangular square matrices with positive diagonals.
    r~   c                 C   sR   |  }||k|jd d d dd }|jddddkdd }||@ S )Nr   rJ   rK   r   )Zdim1Zdim2)r   r   rM   r   Zdiagonal)r!   r"   r   r   Zpositive_diagonalr#   r#   r$   r%     s    &z_LowerCholesky.checkNr{   r#   r#   r#   r$   r     s   r   c                   @   s   e Zd ZdZdZdd ZdS )_CorrCholeskyz}
    Constrain to lower-triangular square matrices with positive diagonals and each
    row vector being of unit length.
    r~   c                 C   sZ   t |jj|d d }t jj| dd}|d  	|j
dd}t ||@ S )NrK   
   rw         ?)ry   ZfinfodtypeZepssizelinalgZnormdetachrz   lerN   r   r%   )r!   r"   ZtolZrow_normZunit_row_normr#   r#   r$   r%     s    z_CorrCholesky.checkNr{   r#   r#   r#   r$   r     s   r   c                   @   s   e Zd ZdZdZdd ZdS )_Squarez'
    Constrain to square matrices.
    r~   c                 C   s0   t j|jd d |jd |jd kt j|jdS )Nr   rK   )r   Z
fill_valuer   device)ry   fullrM   boolr   r    r#   r#   r$   r%     s    z_Square.checkNr{   r#   r#   r#   r$   r     s   r   c                       s    e Zd ZdZ fddZ  ZS )
_Symmetricz1
    Constrain to Symmetric square matrices.
    c                    s6   t  |}| s|S tj||jddddS )Nrx   )Zatolr   rK   )r5   r%   rN   ry   iscloseZmT)r!   r"   Zsquare_checkr8   r#   r$   r%     s    z_Symmetric.checkr(   r+   r,   r-   r%   r?   r#   r#   r8   r$   r     s   r   c                       s    e Zd ZdZ fddZ  ZS )_PositiveSemidefinitez6
    Constrain to positive-semidefinite matrices.
    c                    s0   t  |}| s|S tj|ddS )Nr   rK   )r5   r%   rN   ry   r   Zeigvalshger!   r"   Z	sym_checkr8   r#   r$   r%     s    z_PositiveSemidefinite.checkr   r#   r#   r8   r$   r     s   r   c                       s    e Zd ZdZ fddZ  ZS )_PositiveDefinitez2
    Constrain to positive-definite matrices.
    c                    s,   t  |}| s|S tj|jdS rE   )r5   r%   rN   ry   r   Zcholesky_exinforV   r   r8   r#   r$   r%     s    z_PositiveDefinite.checkr   r#   r#   r8   r$   r     s   r   c                       sB   e Zd ZdZd fdd	Zedd Zedd	 Zd
d Z  Z	S )_Catz
    Constraint functor that applies a sequence of constraints
    `cseq` at the submatrices at dimension `dim`,
    each of size `lengths[dim]`, in a way compatible with :func:`torch.cat`.
    r   Nc                    sn   t dd |D stt|| _|d kr8dgt| j }t|| _t| jt| jksZt|| _t   d S )Nc                 s   s   | ]}t |tV  qd S r2   r@   r   .0cr#   r#   r$   	<genexpr>
  s     z _Cat.__init__.<locals>.<genexpr>r&   )	rN   rF   listcseqlenlengthsrL   r5   r6   )r!   r   rL   r   r8   r#   r$   r6   	  s    

z_Cat.__init__c                 C   s   t dd | jD S )Nc                 s   s   | ]}|j V  qd S r2   r.   r   r#   r#   r$   r     s     z#_Cat.is_discrete.<locals>.<genexpr>anyr   r)   r#   r#   r$   r.     s    z_Cat.is_discretec                 C   s   t dd | jD S )Nc                 s   s   | ]}|j V  qd S r2   r/   r   r#   r#   r$   r     s     z!_Cat.event_dim.<locals>.<genexpr>)maxr   r)   r#   r#   r$   r/     s    z_Cat.event_dimc                 C   s|   |   | j   kr |  k s&n tg }d}t| j| jD ]0\}}|| j ||}||| || }q<t	|| j S rE   )
rL   rF   zipr   r   Znarrowappendr%   ry   r   )r!   r"   Zchecksstartconstrlengthvr#   r#   r$   r%     s    &
z
_Cat.check)r   N
r(   r+   r,   r-   r6   r>   r.   r/   r%   r?   r#   r#   r8   r$   r     s   


r   c                       sB   e Zd ZdZd fdd	Zedd Zedd Zd	d
 Z  Z	S )_Stackz
    Constraint functor that applies a sequence of constraints
    `cseq` at the submatrices at dimension `dim`,
    in a way compatible with :func:`torch.stack`.
    r   c                    s4   t dd |D stt|| _|| _t   d S )Nc                 s   s   | ]}t |tV  qd S r2   r   r   r#   r#   r$   r   -  s     z"_Stack.__init__.<locals>.<genexpr>)rN   rF   r   r   rL   r5   r6   )r!   r   rL   r8   r#   r$   r6   ,  s    
z_Stack.__init__c                 C   s   t dd | jD S )Nc                 s   s   | ]}|j V  qd S r2   r   r   r#   r#   r$   r   4  s     z%_Stack.is_discrete.<locals>.<genexpr>r   r)   r#   r#   r$   r.   2  s    z_Stack.is_discretec                 C   s.   t dd | jD }| j| dk r*|d7 }|S )Nc                 s   s   | ]}|j V  qd S r2   r   r   r#   r#   r$   r   8  s     z#_Stack.event_dim.<locals>.<genexpr>r   r&   )r   r   rL   )r!   rL   r#   r#   r$   r/   6  s    z_Stack.event_dimc                    sf       j   kr   k s&n t fddt j D }tdd t| jD  j S )Nc                    s   g | ]}  j|qS r#   )selectrL   )r   ir    r#   r$   
<listcomp>?  s     z _Stack.check.<locals>.<listcomp>c                 S   s   g | ]\}}| |qS r#   )r%   )r   r   r   r#   r#   r$   r   @  s   )rL   rF   ranger   ry   r   r   r   )r!   r"   vsr#   r    r$   r%   =  s    & 

z_Stack.check)r   r   r#   r#   r8   r$   r   &  s   

r   r&   g        r   )=r-   ry   __all__objectr   r0   r   r>   rB   rD   rS   rT   rX   rc   ri   ro   rp   rr   rs   rt   ru   rv   r|   r}   r   r   r   r   r   r   r   r   r   r   r
   r   Zone_hotr   r   r   r   r   r   Znonnegativer   r	   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r#   r#   r#   r$   <module>   s    !.($
#

