
    קg!                         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
mZ d dlmZ d dlmZ d	gZ G d
 d	e          ZdS )    )DictN)constraints)Distribution)Independent)ComposeTransform	Transform)_sum_rightmost)_sizeTransformedDistributionc                       e Zd ZU dZi Zeeej        f         e	d<   d fd	Z
d fd	Z ej        d          d             Zed	             Z ej                    fd
Z ej                    fdedej        fdZd Zd Zd Zd Z xZS )r   a  
    Extension of the Distribution class, which applies a sequence of Transforms
    to a base distribution.  Let f be the composition of transforms applied::

        X ~ BaseDistribution
        Y = f(X) ~ TransformedDistribution(BaseDistribution, f)
        log p(Y) = log p(X) + log |det (dX/dY)|

    Note that the ``.event_shape`` of a :class:`TransformedDistribution` is the
    maximum shape of its base distribution and its transforms, since transforms
    can introduce correlations among events.

    An example for the usage of :class:`TransformedDistribution` would be::

        # Building a Logistic Distribution
        # X ~ Uniform(0, 1)
        # f = a + b * logit(X)
        # Y ~ f(X) ~ Logistic(a, b)
        base_distribution = Uniform(0, 1)
        transforms = [SigmoidTransform().inv, AffineTransform(loc=a, scale=b)]
        logistic = TransformedDistribution(base_distribution, transforms)

    For more examples, please look at the implementations of
    :class:`~torch.distributions.gumbel.Gumbel`,
    :class:`~torch.distributions.half_cauchy.HalfCauchy`,
    :class:`~torch.distributions.half_normal.HalfNormal`,
    :class:`~torch.distributions.log_normal.LogNormal`,
    :class:`~torch.distributions.pareto.Pareto`,
    :class:`~torch.distributions.weibull.Weibull`,
    :class:`~torch.distributions.relaxed_bernoulli.RelaxedBernoulli` and
    :class:`~torch.distributions.relaxed_categorical.RelaxedOneHotCategorical`
    arg_constraintsNc                    t          |t                    r	|g| _        nWt          |t                    r0t	          d |D                       st          d          || _        nt          d|           |j        |j        z   }t          |j                  }t          | j                  }t          |          |j
        j        k     r t          d|j
        j         d| d          |                    |          }|                    |          }||k    r/|d t          |          |z
           }	|                    |	          }|j
        j        |z
  }
|
dk    rt          ||
          }|| _        |j        j        |j
        j        z
  }t%          |j        j        ||z             }t          |          |k    sJ t          |          |z
  }|d |         }||d          }t'                                          |||           d S )	Nc              3   @   K   | ]}t          |t                    V  d S N)
isinstancer   ).0ts     h/var/www/html/ai-engine/env/lib/python3.11/site-packages/torch/distributions/transformed_distribution.py	<genexpr>z3TransformedDistribution.__init__.<locals>.<genexpr>9   s,      DDAz!Y//DDDDDD    z6transforms must be a Transform or a list of Transformsz0transforms must be a Transform or list, but was z9base_distribution needs to have shape with size at least z
, but got .r   validate_args)r   r   
transformslistall
ValueErrorbatch_shapeevent_shapelenr   domain	event_dimforward_shapeinverse_shapeexpandr   	base_distcodomainmaxsuper__init__)selfbase_distributionr   r   
base_shapebase_event_dim	transformr#   expanded_base_shapebase_batch_shapereinterpreted_batch_ndimstransform_change_in_event_dimr"   cutr   r   	__class__s                   r   r*   z TransformedDistribution.__init__3   s`   j),, 	DOO 
D)) 		DDDDDDD  L   )DOOO:OO  
 '25F5RR
.:;;$T_55	z??Y-777IL\Lfr|   "//
;;'55mDD,,,2;#)**^;;  !2 8 89I J J$-$4$>$O!$q(( +!#<! ! + (9+;+EE 	& (::
 
	 =!!Y....-  9,#DSD)#CDD)kOOOOOr   c                    |                      t          |          }t          j        |          }|| j        z   }t          | j                  D ]}|                    |          }|d t          |          t          | j	        j                  z
           }| j	        
                    |          |_	        | j        |_        t          t          |                              || j        d           | j        |_        |S )NFr   )_get_checked_instancer   torchSizer   reversedr   r$   r    r&   r%   r)   r*   _validate_args)r+   r   	_instancenewshaper   r1   r5   s          r   r%   zTransformedDistribution.expandg   s    (()@)LLj--d..$/** 	+ 	+AOOE**EE !O3u::DN4N0O0O#O!OP--.>??%s++44) 	5 	
 	
 	
 "0
r   F)is_discretec                     | j         s| j        j        S | j         d         j        }t	          | j                  |j        k    r/t          j        |t	          | j                  |j        z
            }|S )N)	r   r&   supportr'   r    r   r"   r   independent)r+   rB   s     r   rB   zTransformedDistribution.supportv   sp     	*>))/"%.t  7#444!-T-..1BB G r   c                     | j         j        S r   )r&   has_rsample)r+   s    r   rE   z#TransformedDistribution.has_rsample   s    ~))r   c                     t          j                    5  | j                            |          }| j        D ]} ||          }|cddd           S # 1 swxY w Y   dS )a  
        Generates a sample_shape shaped sample or sample_shape shaped batch of
        samples if the distribution parameters are batched. Samples first from
        base distribution and applies `transform()` for every transform in the
        list.
        N)r8   no_gradr&   sampler   r+   sample_shapexr/   s       r   rH   zTransformedDistribution.sample   s     ]__ 	 	%%l33A!_ ! !	IaLL		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   1AAArJ   returnc                 d    | j                             |          }| j        D ]} ||          }|S )a$  
        Generates a sample_shape shaped reparameterized sample or sample_shape
        shaped batch of reparameterized samples if the distribution parameters
        are batched. Samples first from base distribution and applies
        `transform()` for every transform in the list.
        )r&   rsampler   rI   s       r   rN   zTransformedDistribution.rsample   s>     N""<00 	 	I	!AAr   c                    | j         r|                     |           t          | j                  }d}|}t	          | j                  D ]i}|                    |          }||j        j        |j	        j        z
  z  }|t          |                    ||          ||j        j        z
            z
  }|}j|t          | j                            |          |t          | j        j                  z
            z   }|S )z
        Scores the sample by inverting the transform(s) and computing the score
        using the score of the base distribution and the log abs det jacobian.
        g        )r;   _validate_sampler    r   r:   r   invr!   r"   r'   r	   log_abs_det_jacobianr&   log_prob)r+   valuer"   rS   yr/   rK   s          r   rS   z TransformedDistribution.log_prob   s   
  	)!!%(((())	!$/22 	 	Ia  A)3i6H6RRRI...q!44I,66# # H AAnN##A&&	C8R4S4S(S
 
 
 r   c                 ~    d}| j         D ]}||j        z  }t          |t                    r|dk    r|S ||dz
  z  dz   S )zu
        This conditionally flips ``value -> 1-value`` to ensure :meth:`cdf` is
        monotone increasing.
           g      ?)r   signr   int)r+   rT   rX   r/   s       r   _monotonize_cdfz'TransformedDistribution._monotonize_cdf   s[    
  	) 	)I).(DDdC   	TQYYLus{#c))r   c                     | j         ddd         D ]}|                    |          }| j        r| j                            |           | j                            |          }|                     |          }|S )z
        Computes the cumulative distribution function by inverting the
        transform(s) and computing the score of the base distribution.
        NrA   )r   rQ   r;   r&   rP   cdfrZ   r+   rT   r/   s      r   r\   zTransformedDistribution.cdf   s    
 2. 	) 	)IMM%((EE 	3N++E222""5))$$U++r   c                     |                      |          }| j                            |          }| j        D ]} ||          }|S )z
        Computes the inverse cumulative distribution function using
        transform(s) and computing the score of the base distribution.
        )rZ   r&   icdfr   r]   s      r   r_   zTransformedDistribution.icdf   sS    
 $$U++##E** 	% 	%IIe$$EEr   r   )__name__
__module____qualname____doc__r   r   strr   
Constraint__annotations__r*   r%   dependent_propertyrB   propertyrE   r8   r9   rH   r
   TensorrN   rS   rZ   r\   r_   __classcell__)r5   s   @r   r   r      sh         @ :<OT#{556;;;2P 2P 2P 2P 2P 2Ph      $[#666  76 * * X* #-%*,,     -7EJLL 
 
E 
U\ 
 
 
 
  0
* 
* 
*  	 	 	 	 	 	 	r   )typingr   r8   torch.distributionsr    torch.distributions.distributionr   torch.distributions.independentr   torch.distributions.transformsr   r   torch.distributions.utilsr	   torch.typesr
   __all__r    r   r   <module>rt      s           + + + + + + 9 9 9 9 9 9 7 7 7 7 7 7 F F F F F F F F 4 4 4 4 4 4       %
%H H H H Hl H H H H Hr   