
    9j=#                         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y)    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                    t        |t              r	|g| _        nCt        |t              r%t	        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      |j                  |      }|j                  |      }||k7  r"|d t        |      |z
   }	|j                  |	      }|j                  j                  |z
  }
|
dkD  rt        ||
      }|| _        |j"                  j                  |j                  j                  z
  }t%        |j"                  j                  ||z         }t        |      |k  rt'        dt        |       d	|       t        |      |z
  }|d | }||d  }t(        | U  |||
       y )Nc              3   <   K   | ]  }t        |t                y wN)
isinstancer   ).0ts     l/media/conek/DATA/Code/OCR/venv/lib/python3.12/site-packages/torch/distributions/transformed_distribution.py	<genexpr>z3TransformedDistribution.__init__.<locals>.<genexpr>?   s     DAz!Y/Ds   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   s6    j),DO 
D)DDD L  )DOB:,O 
 '225F5R5RR
.::;$T__5	z?Y--777KIL\L\LfLfKggqr|q}}~  "//
;'55mD,,2;#)*^;  !2 8 89I J$-$4$4$>$>$O!$q( +!#<! + ((9+;+;+E+EE 	& ((::
	 }	) 'M(:';;QR[Q\]  - 9,#DS)#CD)kO    c                    | j                  t        |      }t        j                  |      }|| j                  z   }t        | j                        D ]  }|j                  |      } |d t        |      t        | j                  j                        z
   }| j                  j                  |      |_	        | j                  |_        t        t        |3  || j                  d       | j                  |_        |S )NFr   )_get_checked_instancer   torchSizer    reversedr   r%   r!   r'   r&   r+   r,   _validate_args)r-   r   	_instancenewshaper   r2   r6   s          r   r&   zTransformedDistribution.expandp   s    (()@)Ljj-d...$//* 	+AOOE*E	+ !O3u:DNN4N4N0O#OP--.>?%s4)) 	5 	
 "00
r7   F)is_discretec                 ,   | j                   s| j                  j                  S | j                   d   j                  }t	        | j
                        |j                  kD  r6t        j                  |t	        | j
                        |j                  z
        }|S )N)	r   r'   supportr(   r!   r    r#   r   independent)r-   rD   s     r   rD   zTransformedDistribution.support   sz     >>)))//"%..t 7#4#44!--T--.1B1BBG r7   c                 .    | j                   j                  S r   )r'   has_rsample)r-   s    r   rG   z#TransformedDistribution.has_rsample   s    ~~)))r7   c                     t        j                         5  | j                  j                  |      }| j                  D ]
  } ||      } |cddd       S # 1 sw Y   yxY w)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xr0   s       r   rJ   zTransformedDistribution.sample   sU     ]]_ 	%%l3A!__ !	aL!		 	 	s   6AArL   c                 n    | j                   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   s9     NN""<0 	I!A	r7   c                 (   | j                   r| j                  |       t        | j                        }d}|}t	        | j
                        D ]{  }|j                  |      }||j                  j                  |j                  j                  z
  z  }|t        |j                  ||      ||j                  j                  z
        z
  }|}} |t        | j                  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   yr0   rM   s          r   rT   z TransformedDistribution.log_prob   s    
 !!%((()	#&!$//2 	Ia A))33i6H6H6R6RRRI...q!4I,,666# H A	 nNN##A&	C8R8R4S(S
 
 r7   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   r0   s       r   _monotonize_cdfz'TransformedDistribution._monotonize_cdf   sS    
  	)I)..(D	)dC TQYLus{#c))r7   c                     | j                   ddd   D ]  }|j                  |      } | j                  r| j                  j	                  |       | j                  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   r0   s      r   r]   zTransformedDistribution.cdf   sr    
 2. 	)IMM%(E	)NN++E2""5)$$U+r7   c                     | j                  |      }| j                  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   sJ    
 $$U+##E* 	%Ie$E	%r7   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__)r6   s   @r   r   r      s    B :<OT#{5556; &*	:P':P Y/:P d{	:P
 
:Px $[##6 7 *T * * #-%**,  -7EJJL 
E 
V 
0
*	r7   )r:   r   torch.distributionsr    torch.distributions.distributionr   torch.distributions.independentr   torch.distributions.transformsr   r   torch.distributions.utilsr	   torch.typesr
   __all__r    r7   r   <module>ru      s7      + 9 7 F 4  %
%Rl Rr7   