o
    * i$                     @  s  d dl mZ d dlZd dlZd dlmZmZ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 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 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$ 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. erd dlm/Z/ edZ0ddgZ1i Z2dNd dZ3dOd%dZ4d&d' Z5ej6G d(d) d)Z7e4e
e
d*d+ Z8e4eed,d- Z9e4eed.d/ Z:e4eed0d1 Z;e4eed2d3 Z<e4eed4d5 Z=e4eed6d7 Z>e4e(e(d8d9 Z?e4e&e&d:d; Z@e4e,e,d<d= ZAe4e"e"d>d? ZBe4e e d@dA ZCe4eedBdC ZDe4eedDdE ZEe4eedFdG ZFe4e$e$dHdI ZGe4e*e*dJdK ZHdLdM ZIdS )P    )annotationsN)TYPE_CHECKINGCallableTypeVar)	Bernoulli)Beta)Binomial)Categorical)Cauchy)ContinuousBernoulli)	Dirichlet)Distribution)Exponential)ExponentialFamily)Gamma)	Geometric)Laplace)	LogNormal)MultivariateNormal)Normal)Poisson)Uniform)in_dynamic_mode)Tensor_Tregister_klkl_divergencepr   qreturnr   c                 C  s   t t| t|| |S )a-  
    Kullback-Leibler divergence between distribution p and q.

    .. math::

        KL(p||q) = \int p(x)log\frac{p(x)}{q(x)} \mathrm{d}x

    Args:
        p (Distribution): ``Distribution`` object. Inherits from the Distribution Base class.
        q (Distribution): ``Distribution`` object. Inherits from the Distribution Base class.

    Returns:
        Tensor, Batchwise KL-divergence between distribution p and q.

    Examples:

        .. code-block:: python

            >>> import paddle

            >>> p = paddle.distribution.Beta(alpha=0.5, beta=0.5)
            >>> q = paddle.distribution.Beta(alpha=0.3, beta=0.7)

            >>> print(paddle.distribution.kl_divergence(p, q))
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                0.21193528)

    )	_dispatchtyper   r    r#   b/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/paddle/distribution/kl.pyr   4   s   cls_ptype[Distribution]cls_qCallable[[_T], _T]c                   s.   t  tr
t tstd fdd}|S )a  Decorator for register a KL divergence implementation function.

    The ``kl_divergence(p, q)`` function will search concrete implementation
    functions registered by ``register_kl``, according to multi-dispatch pattern.
    If an implementation function is found, it will return the result, otherwise,
    it will raise ``NotImplementError`` exception. Users can register
    implementation function by the decorator.

    Args:
        cls_p (type[Distribution]): The Distribution type of Instance p. Subclass derived from ``Distribution``.
        cls_q (type[Distribution]): The Distribution type of Instance q. Subclass derived from ``Distribution``.

    Examples:
        .. code-block:: python

            >>> import paddle

            >>> @paddle.distribution.register_kl(paddle.distribution.Beta, paddle.distribution.Beta)
            >>> def kl_beta_beta():
            ...     pass # insert implementation here
    z0cls_p and cls_q must be subclass of Distributionc                   s   | t  f< | S N)_REGISTER_TABLE)fr%   r'   r#   r$   	decoratorq   s   zregister_kl.<locals>.decorator)
issubclassr   	TypeError)r%   r'   r-   r#   r,   r$   r   T   s   c                   s    fddt D }|sttdd |D j\}}tdd |D j\}}t ||f t ||f urItd j dj d|j d|j d		t t ||f S )
z3Multiple dispatch into concrete implement function.c                   s,   g | ]\}}t  |rt |r||fqS r#   )r.   ).0Zsuper_pZsuper_qr,   r#   r$   
<listcomp>|   s    z_dispatch.<locals>.<listcomp>c                 s  s    | ]}t | V  qd S r)   )_Comparer0   mr#   r#   r$   	<genexpr>   s    z_dispatch.<locals>.<genexpr>c                 s  s    | ]	}t t| V  qd S r)   )r2   reversedr3   r#   r#   r$   r5      s    zAmbiguous kl_divergence(z, z). Please register_kl())r*   NotImplementedErrorminclasseswarningswarn__name__RuntimeWarning)r%   r'   matchesZleft_pZleft_qZright_pZright_qr#   r,   r$   r    x   s   $r    c                   @  s$   e Zd Zdd Zdd Zdd ZdS )r2   c                 G  s
   || _ d S r)   r:   )selfr:   r#   r#   r$   __init__   s   
z_Compare.__init__c                 C  s   | j |j kS r)   r@   )rA   otherr#   r#   r$   __eq__   s   z_Compare.__eq__c                 C  s:   t | j|jD ]\}}t||s dS ||ur dS qdS )NFT)zipr:   r.   )rA   rC   Zcls_xZcls_yr#   r#   r$   __le__   s   
z_Compare.__le__N)r=   
__module____qualname__rB   rD   rF   r#   r#   r#   r$   r2      s    r2   c                 C  
   |  |S r)   r   r"   r#   r#   r$   _kl_bernoulli_bernoulli      
rK   c                 C  s   |j  |j  | j | j   | j  | j  |j |j    | j |j  | j    | j|j | j   |j |j | j | j  | j | j    S r)   )alphalgammabetadigammar"   r#   r#   r$   _kl_beta_beta   s   ""rQ   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_binomial_binomial   rL   rR   c                 C  sl   | j d |j d  | j  |j   d | j |j  | j  | j d d  d S )N)ZconcentrationsumrN   rP   Z	unsqueezer"   r#   r#   r$   _kl_dirichlet_dirichlet   s   
rU   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_categorical_categorical   rL   rV   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_cauchy_cauchy   rL   rW   c                 C  rI   r)   rJ   r"   r#   r#   r$   +_kl_continuousbernoulli_continuousbernoulli   rL   rX   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_normal_normal   rL   rY   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_mvn_mvn   rL   rZ   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_uniform_uniform   rL   r[   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_laplace_laplace   rL   r\   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_geometric_geometric   rL   r]   c              
   C  s   t | t |ks
tg }| jD ]}| }d|_|| q|j}| j| }zt r3tj	||dd}ntj
||}W n tyW } ztdjt | jt |jd|d}~ww |j| | }t|||D ]\}	}
}|
|	 | }|t|t|j8 }qe|S )zuCompute kl-divergence using `Bregman divergences <https://www.lix.polytechnique.fr/~nielsen/EntropyEF-ICIP2010.pdf>`_FT)Zcreate_graphzkCan't compute kl_divergence({cls_p}, {cls_q}) use bregman divergence. Please register_kl({cls_p}, {cls_q}).r,   N)r!   r8   Z_natural_parametersdetachZstop_gradientappendZ_log_normalizerr   paddleZgradZstaticZ	gradientsRuntimeErrorr/   formatr=   rE   _sum_rightmostlenZevent_shape)r   r   Zp_natural_paramsparamZq_natural_paramsZ
p_log_normZp_gradseklZp_paramZq_paramZp_gradtermr#   r#   r$   _kl_expfamily_expfamily   sB   

ri   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_exponential_exponential  rL   rj   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_gamma_gamma  rL   rk   c                 C  s   | j |j S r)   )_baser   r"   r#   r#   r$   _kl_lognormal_lognormal$  s   rm   c                 C  rI   r)   rJ   r"   r#   r#   r$   _kl_poisson_poisson)  rL   rn   c                 C  s"   |dkr|  tt| dS | S )Nr   )rT   listrange)valuenr#   r#   r$   rc   .  s   "rc   )r   r   r   r   r   r   )r%   r&   r'   r&   r   r(   )J
__future__r   	functoolsr;   typingr   r   r   r`   Zpaddle.distribution.bernoullir   Zpaddle.distribution.betar   Zpaddle.distribution.binomialr   Zpaddle.distribution.categoricalr	   Zpaddle.distribution.cauchyr
   Z(paddle.distribution.continuous_bernoullir   Zpaddle.distribution.dirichletr   Z paddle.distribution.distributionr   Zpaddle.distribution.exponentialr   Z&paddle.distribution.exponential_familyr   Zpaddle.distribution.gammar   Zpaddle.distribution.geometricr   Zpaddle.distribution.laplacer   Zpaddle.distribution.lognormalr   Z'paddle.distribution.multivariate_normalr   Zpaddle.distribution.normalr   Zpaddle.distribution.poissonr   Zpaddle.distribution.uniformr   Zpaddle.frameworkr   r   r   __all__r*   r   r   r    total_orderingr2   rK   rQ   rR   rU   rV   rW   rX   rY   rZ   r[   r\   r]   ri   rj   rk   rm   rn   rc   r#   r#   r#   r$   <module>   s   

 $












'



