
    /j=#                         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 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 )    N)Tensor)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de
deee         z  dedz  ddf fdZd fd		Z ej        d
          d             Zedefd            Z ej                    fdZ ej                    fdede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_constraintsNbase_distribution
transformsvalidate_argsreturnc                 Z   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     r"t'          dt          |           d	|           t          |          |z
  }|d |         }||d          }t)                                          |||
           d S )Nc              3   @   K   | ]}t          |t                    V  d S N)
isinstancer   ).0ts     q/home/longshao/multi-rider-rag/.venv/lib/python3.11/site-packages/torch/distributions/transformed_distribution.py	<genexpr>z3TransformedDistribution.__init__.<locals>.<genexpr>?   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   zforward_shape length z must be >= event_dim r   )r   r   r   listall
ValueErrorbatch_shapeevent_shapelenr   domain	event_dimforward_shapeinverse_shapeexpandr   	base_distcodomainmaxAssertionErrorsuper__init__)selfr   r   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__4   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 	& (::
 
	 }	)) ]M(:(:]]R[]]   -  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   r3   r7   s          r   r'   zTransformedDistribution.expandp   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.   rD   s     r   rD   zTransformedDistribution.support   sr      	*>))/"%.t  7#444!-T-..1BB G r   c                     | j         j        S r   )r(   has_rsample)r.   s    r   rG   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)r:   no_gradr(   sampler   r.   sample_shapexr1   s       r   rJ   zTransformedDistribution.sample   s     ]__ 	 	%%l33A!_ ! !	IaLL		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   1AAArL   c                 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   rK   s       r   rO   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$   rT   yr1   rM   s          r   rT   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.   rU   rY   r1   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.
        NrC   )r   rR   r=   r(   rQ   cdfr[   r.   rU   r1   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.
        )r[   r(   icdfr   r^   s      r   r`   zTransformedDistribution.icdf   sS    
 $$U++##E** 	% 	%IIe$$EEr   r   )__name__
__module____qualname____doc__r   dictstrr   
Constraint__annotations__r   r   r   boolr-   r'   dependent_propertyrD   propertyrG   r:   r;   rJ   r
   r   rO   rT   r[   r]   r`   __classcell__)r7   s   @r   r   r      s         B :<OT#{556;;; &*	:P :P':P Y/:P d{	:P
 
:P :P :P :P :P :Px      $[#666  76 *T * * * X* #-%*,,     -7EJLL 
 
E 
V 
 
 
 
  0
* 
* 
*  	 	 	 	 	 	 	r   )r:   r   torch.distributionsr    torch.distributions.distributionr   torch.distributions.independentr   torch.distributions.transformsr   r   torch.distributions.utilsr	   torch.typesr
   __all__r    r   r   <module>ru      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       %
%R R R R Rl R R R R Rr   