o
    * i|*                     @  sz   d dl mZ d dlZd dlmZ d dlZd dlZd dlm	Z	 d dl
mZ er2d dlmZ d dlmZ G dd	 d	ejZdS )
    )annotationsN)TYPE_CHECKING)	framework)distribution)Sequence)Tensorc                      s   e Zd ZU dZded< d" fddZed#d	d
Zed#ddZed#ddZ	d$ddZ
d$ddZg fd%ddZg fd%ddZd#ddZd$ddZd&d d!Z  ZS )'	GeometricaM  
    Geometric distribution parameterized by probs.

    In probability theory and statistics, the geometric distribution is one of
    discrete probability distributions, parameterized by one positive shape parameter, denoted by probs.
    In n Bernoulli trials, it takes k+1 trials to get the probability of success for the first time.
    In detail, it is: the probability that the first k times failed and the kth time succeeded.
    The geometric distribution is a special case of the Pascal distribution when r=1.

    The probability mass function (pmf) is

    .. math::
            Pr(Y=k)=(1-p)^kp

    where k is number of trials failed before seeing a success, and p is probability of success for each trial and k=0,1,2,3,4..., p belong to (0,1].

    Args:
        probs (Real|Tensor): Probability parameter.
            The value of probs must be positive. When the parameter is a tensor, probs is probability of success for each trial.

    Returns:
        Geometric distribution for instantiation of probs.

    Examples:

        .. code-block:: python

            >>> import paddle
            >>> from paddle.distribution import Geometric

            >>> geom = Geometric(0.5)

            >>> print(geom.mean)
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            1.)

            >>> print(geom.variance)
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            2.)

            >>> print(geom.stddev)
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            1.41421354)
    r   probsfloat | TensorreturnNonec                   s   t |tjtjtjtjjfrCt |tjrtj	d|tj
d}tj	|jd|jd}tj	|jd|jd}tj	|jdtd}||k}||k}n	tdt| t|j}|| _t | d S )N )shapeZ
fill_valuedtype   r   FzOExpected type of probs is Number.Real|Tensor|framework.Variable|Value, but got )
isinstancenumbersRealpaddler   r   VariablepirValuefullfloat32r   r   bool	TypeErrortypetupler	   super__init__)selfr	   all_onesZ	all_zerosZ	all_falseZ
lessthen_0Z
morethen_1Zbatch_shape	__class__r   i/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/paddle/distribution/geometric.pyr   P   s2   



zGeometric.__init__c                 C  s   d| j  d S )zMean of geometric distribution.      ?)r	   r    r   r   r$   meanq   s   zGeometric.meanc                 C  s"   t jd| j d | j | jjdS )z#Variance of geometric distribution.r%   r   )r   Z	to_tensorr	   r   r&   r   r   r$   variancev   s   zGeometric.variancec                 C  s   t | jS )z-Standard deviation of Geometric distribution.)r   sqrtr)   r&   r   r   r$   stddev~   s   zGeometric.stddevkint | Tensorc                 C  sB   t |tjtjtjjfrtd| j	 || j	 S t
dt| )aI  Probability mass function evaluated at k.

        .. math::

            P(X=k) = (1-p)^{k} p, \quad k=0,1,2,3,\ldots

        Args:
            k (int): Value to be evaluated.

        Returns:
            Tensor: Probability.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Geometric

                >>> geom = Geometric(0.5)
                >>> print(geom.pmf(2))
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                0.12500000)
        r%   DExpected type of k is number.Real|framework.Variable|Value, but got r   r   Integralr   r   r   r   r   powr	   r   r   r    r,   r   r   r$   pmf   s   zGeometric.pmfc                 C  s:   t |tjtjtjjfrt| 	|S t
dt| )aF  Log probability mass function evaluated at k.

        .. math::
            \log P(X = k) = \log(1-p)^k p

        Args:
            k (int): Value to be evaluated.

        Returns:
            Tensor: Log probability.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Geometric

                >>> geom = Geometric(0.5)
                >>> print(geom.log_pmf(2))
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                -2.07944131)
        r.   )r   r   r0   r   r   r   r   r   logr3   r   r   r2   r   r   r$   log_pmf   s   zGeometric.log_pmfr   Sequence[int]c                 C  s6   t   | |W  d   S 1 sw   Y  dS )a  Sample from Geometric distribution with sample shape.

        Args:
            shape (Sequence[int]): Sample shape.

        Returns:
            Sampled data with shape `sample_shape` + `batch_shape` + `event_shape`.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Geometric

                >>> paddle.seed(2023)
                >>> geom = Geometric(0.5)
                >>> print(geom.sample((2,2)))
                Tensor(shape=[2, 2], dtype=float32, place=Place(cpu), stop_gradient=True,
                [[0., 0.],
                 [1., 0.]])
        N)r   Zno_gradrsample)r    r   r   r   r$   sample   s   
$zGeometric.samplec                 C  sR   t jj| |d}tj|ttjddjd| j	j
d}tt|t| j	  S )a  Generate samples of the specified shape.

        Args:
            shape(Sequence[int]): The shape of generated samples.

        Returns:
            Tensor: A sample tensor that fits the Geometric distribution.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Geometric

                >>> paddle.seed(2023)
                >>> geom = Geometric(0.5)
                >>> print(geom.rsample((2,2)))
                Tensor(shape=[2, 2], dtype=float32, place=Place(cpu), stop_gradient=True,
                [[0., 0.],
                 [1., 0.]])

        )Zsample_shaper   r(   r%   )r   minmaxr   )r   DistributionZ_extend_shaper   uniformfloatnpZfinfoZtinyr	   r   floorr4   log1p)r    r   r<   r   r   r$   r7      s   zGeometric.rsamplec                 C  s<   d| j  td| j   }| j t| j  }||  | j  S )a  Entropy of dirichlet distribution.

        .. math::

            H(X) = -\left[\frac{1}{p} \log p + \frac{1-p}{p^2} \log (1-p) \right]

        Returns:
            Tensor: Entropy.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Geometric

                >>> geom = Geometric(0.5)
                >>> print(geom.entropy())
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                1.38629425)
        r%   )r	   r   r4   )r    xyr   r   r$   entropy  s   zGeometric.entropyc                 C  sD   t |tjtjtjjfrdtd| j	 |d  S t
dt| )aD  Cdf of geometric distribution.

        .. math::

            F(X \leq k) = 1 - (1-p)^(k+1), \quad k=0,1,2,\ldots

        Args:
            k: The number of trials performed.

        Returns:
            Tensor: Entropy.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Geometric

                >>> geom = Geometric(0.5)
                >>> print(geom.cdf(4))
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                0.96875000)
        r%   r   r.   r/   r2   r   r   r$   cdf   s   zGeometric.cdfotherc                 C  sZ   t |tr$| j|j}}|t||  d| td| d|    S tdt| )a  Calculate the KL divergence KL(self || other) with two Geometric instances.

        .. math::

            KL(P \| Q) = \frac{p}{q} \log \frac{p}{q} + \log (1-p) - \log (1-q)

        Args:
            other (Geometric): An instance of Geometric.

        Returns:
            Tensor: The kl-divergence between two geometric distributions.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Geometric

                >>> geom_p = Geometric(0.5)
                >>> geom_q = Geometric(0.1)
                >>> print(geom_p.kl_divergence(geom_q))
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                0.51082563)
        r%   z6Exacted type of other is geometric.Geometric, but got )r   r   r	   r   r4   r   r   )r    rE   pqr   r   r$   kl_divergenceB  s   
zGeometric.kl_divergence)r	   r
   r   r   )r   r   )r,   r-   r   r   )r   r6   r   r   )rE   r   r   r   )__name__
__module____qualname____doc____annotations__r   propertyr'   r)   r+   r3   r5   r8   r7   rC   rD   rH   __classcell__r   r   r"   r$   r       s"   
 -!

"!
%
"r   )
__future__r   r   typingr   numpyr>   r   Zpaddle.baser   Zpaddle.distributionr   collections.abcr   r   r;   r   r   r   r   r$   <module>   s   