Ë
    M²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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     úk/var/www/html/ia-enhanced/venv/lib/python3.12/site-packages/torch/distributions/transformed_distribution.pyú	<genexpr>z3TransformedDistribution.__init__.<locals>.<genexpr>?   s   è ø€ ÒD°A”z !¤Y×/ÑDùs   ‚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¤)Ô,àðˆD�Oô ˜
¤DÔ)ÜÑD¸ÔDÔDÜ ØLóð ð )ˆD�OäØBÀ:À,ÐOóð ð
 '×2Ñ2Ð5F×5RÑ5RÑRˆ
ÜÐ.×:Ñ:Ó;ˆÜ$ T§_¡_Ó5ˆ	Üˆz‹?˜Y×-Ñ-×7Ñ7Ò7ÜØKÈI×L\ÑL\×LfÑLfÐKgÐgqÐr|Ðq}Ð}~Ðóð ð "×/Ñ/°
Ó;ˆØ'×5Ñ5°mÓDÐØÐ,Ò,Ø2Ø;”#Ð)Ó*¨^Ñ;ð Ðð !2× 8Ñ 8Ð9IÓ JÐØ$-×$4Ñ$4×$>Ñ$>ÀÑ$OÐ!Ø$ qÒ(Ü +Ø!Ð#<ó!Ðð +ˆŒð ×Ñ×(Ñ(¨9×+;Ñ+;×+EÑ+EÑEð 	&ô Ø×Ñ×(Ñ(ØÐ:Ñ:ó
ˆ	ô ˆ}Ó 	Ò)Ü Ø'¬¨MÓ(:Ð';Ð;QÐR[ÐQ\Ð]óð ô �-Ó  9Ñ,ˆØ# D SÐ)ˆØ# C DÐ)ˆÜ‰Ñ˜ 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ˆÜ—j‘j Ó-ˆØ˜d×.Ñ.Ñ.ˆÜ˜$Ÿ/™/Ó*ò 	+ˆAØ—O‘O EÓ*‰Eð	+à Ð!O¤3 u£:´°D·N±N×4NÑ4NÓ0OÑ#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×-Ñ-Ó.°×1BÑ1BÑ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Ó3ˆAØ!Ÿ_™_ò !�	Ù˜a“L‘ð!à÷		÷ 	ò 	ú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   € ð �N‰N×"Ñ" <Ó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Ñ3°i×6HÑ6H×6RÑ6RÑRÑRˆIØ¤.Ø×.Ñ.¨q°!Ó4Ø˜I×,Ñ,×6Ñ6Ñ6ó#ñ ˆHð ‰Að	ð œnØ�N‰N×#Ñ# AÓ&¨	´C¸¿¹×8RÑ8RÓ4SÑ(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ð	)ä�dœCÔ  T¨Q¢YØˆLØ�u˜s‘{Ñ# 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Ø—M‘M %Ó(‰Eð	)à×ÒØ�N‰N×+Ñ+¨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 :<€O�T˜#˜{×5Ñ5Ð5Ñ6Ó;ð &*ñ	:Pà'ð:Pð   Y¡Ñ/ð:Pð ˜d‘{ð	:Pð
 
õ:Põxð $€[×#Ñ#°Ô6ñó 7ðð ð*˜Tò *ó ð*ð #- %§*¡*£,ó ð -7¨E¯J©J«Lñ 
 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   