o
    Me                     @   sJ   d dl Z d dlmZ d dlmZ d dlmZ G dd dejZdd ZdS )	    N)distribution)	transform)independentc                       s2   e Zd ZdZ fddZd	ddZdd Z  ZS )
TransformedDistributiona(      
    Applies a sequence of Transforms to a base distribution. 

    Args:
        base (Distribution): The base distribution.
        transforms (Sequence[Transform]): A sequence of ``Transform`` .

    Examples:

        .. code-block:: python
        
            import paddle 
            from paddle.distribution import transformed_distribution

            d = transformed_distribution.TransformedDistribution(
                paddle.distribution.Normal(0., 1.), 
                [paddle.distribution.AffineTransform(paddle.to_tensor(1.), paddle.to_tensor(2.))]
            )

            print(d.sample([10]))
            # Tensor(shape=[10], dtype=float32, place=Place(gpu:0), stop_gradient=True,
            #        [-0.10697651,  3.33609009, -0.86234951,  5.07457638,  0.75925219,
            #         -4.17087793,  2.22579336, -0.93845034,  0.66054249,  1.50957513])
            print(d.log_prob(paddle.to_tensor(0.5)))
            # Tensor(shape=[1], dtype=float32, place=Place(gpu:0), stop_gradient=True,
            #        [-1.64333570])
    c                    s<  t |tjstdt| dt |tjs tdt| dtdd |D s-tdt	|}t
|j|j |jjk rMtd|jj dt
t d|jjt
|jkrdt||jjt
|j f}|| _|| _||j|j }|jjtt
|j|jj d	 }tt| |d t
||  |t
|| d   d S )
Nz1Expected type of 'base' is Distribution, but got .zGExpected type of 'transforms' is Sequence[Transform] or Chain, but got c                 s   s    | ]	}t |tjV  qd S )N)
isinstancer   Z	Transform).0t r
   \D:\Projects\ConvertPro\env\Lib\site-packages\paddle/distribution/transformed_distribution.py	<genexpr><   s    z3TransformedDistribution.__init__.<locals>.<genexpr>z1All element of transforms must be Transform type.z.'base' needs to have shape with size at least z
, bug got r   )r   r   Distribution	TypeErrortypetypingSequenceallr   ZChainTransformlenZbatch_shapeevent_shape_domain
event_rank
ValueErrorZ
base_shaper   ZIndependent_base_transformsZforward_shape	_codomainmaxsuperr   __init__)selfbaseZ
transformschainZtransformed_shapeZtransformed_event_rank	__class__r
   r   r   3   s>   

z TransformedDistribution.__init__r
   c                 C   s&   | j |}| jD ]}||}q	|S )zSample from ``TransformedDistribution``.

        Args:
            shape (tuple, optional): The sample shape. Defaults to ().

        Returns:
            [Tensor]: The sample result.
        )r   sampler   forward)r   shapexr	   r
   r
   r   r#   R   s   	
zTransformedDistribution.samplec                 C   s   d}|}t | j}t| jD ]!}||}||jj|jj 7 }|t|	|||jj  }|}q|t| j
||t | j
j 7 }|S )zThe log probability evaluated at value.

        Args:
            value (Tensor): The value to be evaluated.

        Returns:
            Tensor: The log probability.
        g        )r   r   reversedr   Zinverser   r   r   _sum_rightmostZforward_log_det_jacobianr   log_prob)r   valuer)   yr   r	   r&   r
   r
   r   r)   `   s$   	


z TransformedDistribution.log_prob)r
   )__name__
__module____qualname____doc__r   r#   r)   __classcell__r
   r
   r!   r   r      s
    
r   c                 C   s"   |dkr|  tt| dS | S )Nr   )sumlistrange)r*   nr
   r
   r   r(   x   s   "r(   )r   Zpaddle.distributionr   r   r   r   r   r(   r
   r
   r
   r   <module>   s   b