o
    pin                     @  sB  U d dl mZ d dlZd dlmZmZ d dlmZmZ d dl	Z	d dl	m
Z
 d dlmZmZ d dlmZmZmZ dd	lmZmZ dd
lmZ ddlmZmZmZ ddlmZ ddlmZ erod dlm Z  d dl	m!Z! d dl"m#Z# ed Z$de%d< g Z&eddgddg			dTddddUd&d'Z'edgdgd(				dVddd)dWd.d/Z(		0		dXdYd1d2Z)dZd[d3d4Z*e	5	5	5d\d]d:d;Z+e	5	5	5	5d^d_d=d;Z+			>	d`d?d;Z+e	5	5	5	5d^d]d@dAZ,e	5	5	5	5d^dadCdAZ,eddgddgd7dDg			>	d`dEdAZ,			F	dbdcdLdMZ-			FdddedOdPZ.			FdddfdRdSZ/dS )g    )annotationsN)TYPE_CHECKINGLiteral)	TypeAliasoverload)_C_ops)in_dynamic_modein_dynamic_or_pir_mode)ParamAliasDecoratorparam_two_aliasparam_two_alias_one_default   )
check_typecheck_variable_and_dtype)Variable)LayerHelperconvert_np_dtype_to_dtype_core   )cast)_get_reduce_axis_with_tensor)Sequence)Tensor)	DTypeLike)linearhigherlowermidpointnearestr   _InterpolationxinputaxisdimF)dtypeoutr   int | Sequence[int] | Nonekeepdimboolname
str | Noner$   DTypeLike | Noner%   Tensor | Nonereturnc                C  s   |durt |tjjtjfst|}| j|krt| |} t r(t	j
| |||dS t|| \}}t| dg dd t|dttttfd t |ttfrX|D ]}t|dttfd qLtdi t }|||d	}	|| j}
|jd
d| id|
i|	d |
S )aX  
    Computes the mean of the input tensor's elements along ``axis``.

    Args:
        x (Tensor): The input Tensor with data type bool, bfloat16, float16, float32,
            float64, int32, int64, complex64, complex128.
            alias: ``input``
        axis (int|list|tuple|None, optional): The axis along which to perform mean
            calculations. ``axis`` should be int, list(int) or tuple(int). If
            ``axis`` is a list/tuple of dimension(s), mean is calculated along
            all element(s) of ``axis`` . ``axis`` or element(s) of ``axis``
            should be in range [-D, D), where D is the dimensions of ``x`` . If
            ``axis`` or element(s) of ``axis`` is less than 0, it works the
            same way as :math:`axis + D` . If ``axis`` is None, mean is
            calculated over all elements of ``x``. Default is None.
            alias: ``dim``
        keepdim (bool, optional): Whether to reserve the reduced dimension(s)
            in the output Tensor. If ``keepdim`` is True, the dimensions of
            the output Tensor is the same as ``x`` except in the reduced
            dimensions(it is of size 1 in this case). Otherwise, the shape of
            the output Tensor is squeezed in ``axis`` . Default is False.
        name (str|None, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.
        dtype (str): The desired data type of returned tensor. Default: None.
        out(Tensor|None, optional): The output tensor. Default: None.

    Returns:
        Tensor, results of average along ``axis`` of ``x``, with the same data
        type as ``x``.

    Examples:
        .. code-block:: python

            >>> import paddle

            >>> x = paddle.to_tensor([[[1., 2., 3., 4.],
            ...                        [5., 6., 7., 8.],
            ...                        [9., 10., 11., 12.]],
            ...                       [[13., 14., 15., 16.],
            ...                        [17., 18., 19., 20.],
            ...                        [21., 22., 23., 24.]]])
            >>> out1 = paddle.mean(x)
            >>> print(out1.numpy())
            12.5
            >>> out2 = paddle.mean(x, axis=-1)
            >>> print(out2.numpy())
            [[ 2.5  6.5 10.5]
             [14.5 18.5 22.5]]
            >>> out3 = paddle.mean(x, axis=-1, keepdim=True)
            >>> print(out3.numpy())
            [[[ 2.5]
              [ 6.5]
              [10.5]]
             [[14.5]
              [18.5]
              [22.5]]]
            >>> out4 = paddle.mean(x, axis=[0, 2])
            >>> print(out4.numpy())
            [ 8.5 12.5 16.5]
            >>> out5 = paddle.mean(x, dtype='float64')
            >>> out5
            Tensor(shape=[], dtype=float64, place=Place(gpu:0), stop_gradient=True,
                12.50000000)
    N)r%   zx/input)	r(   uint16float16float32float64int32int64Z	complex64Z
complex128zmean/reduce_meanzaxis/dimzelements of axis/dimmean)r#   Zkeep_dim
reduce_allZreduce_meanXOuttypeinputsoutputsattrs)r4   )
isinstancer   VarDescVarTypeZDataTyper   r$   r   r	   r   r4   r   r   r   intlisttupler   r   locals"create_variable_for_type_inference	append_op)r    r"   r'   r)   r$   r%   r5   itemhelperr<   
out_tensor rI   Y/home/app/PaddleOCR-VL/.venv_paddleocr/lib/python3.10/site-packages/paddle/tensor/stat.pyr4   4   sF   J

r4   )r    r"   )
correctionr%   unbiasedbool | NonerK   floatc                C  s  |dur|dkrt d|dur|rdnd}nt|}t s't| dg dd t| |d	|}| jtjkr7tjn| j}	tj	t
| | d
||||	d}
tt| dtt|
d }||	}|dkr|| }t|t|}t rt|dkrtjdd
d n|}d	|_|
| }
dd }d| jv r||
}
t| jdkr|dkrtjd|
jd}
|
j| jkr|
| j}n|
}|durt|| |S |S )ay	  
    Computes the variance of ``x`` along ``axis`` .

    .. note::
        Alias Support: The parameter name ``input`` can be used as an alias for ``x``, and ``dim`` can be used as an alias for ``axis``.
        For example, ``var(input=tensor_x, dim=1, ...)`` is equivalent to ``var(x=tensor_x, axis=1, ...)``.

    Args:
        x (Tensor): The input Tensor with data type float16, float32, float64.
            alias: ``input``.
        axis (int|list|tuple|None, optional): The axis along which to perform variance calculations. ``axis`` should be int, list(int) or tuple(int).
            alias: ``dim``.

            - If ``axis`` is a list/tuple of dimension(s), variance is calculated along all element(s) of ``axis`` . ``axis`` or element(s) of ``axis`` should be in range [-D, D), where D is the dimensions of ``x`` .
            - If ``axis`` or element(s) of ``axis`` is less than 0, it works the same way as :math:`axis + D` .
            - If ``axis`` is None, variance is calculated over all elements of ``x``. Default is None.

        unbiased (bool, optional): Whether to use the unbiased estimation. If ``unbiased`` is True, the divisor used in the computation is :math:`N - 1`, where :math:`N` represents the number of elements along ``axis`` , otherwise the divisor is :math:`N`. Default is True.
        keep_dim (bool, optional): Whether to reserve the reduced dimension in the output Tensor. The result tensor will have one fewer dimension than the input unless keep_dim is true. Default is False.
        name (str|None, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.
        correction (int|float, optional): Difference between the sample size and sample degrees of freedom.
            Defaults to 1 (Bessel's correction). If unbiased is specified, this parameter is ignored.
        out (Tensor|None, optional): Output tensor. Default is None.

    Returns:
        Tensor, results of variance along ``axis`` of ``x``, with the same data type as ``x``.

    Examples:
        .. code-block:: python

            >>> import paddle

            >>> x = paddle.to_tensor([[1.0, 2.0, 3.0], [1.0, 4.0, 5.0]])
            >>> out1 = paddle.var(x)
            >>> print(out1.numpy())
            2.6666667
            >>> out2 = paddle.var(x, axis=1)
            >>> print(out2.numpy())
            [1.         4.3333335]
    Nr   z0Only one of unbiased and correction may be giveng      ?g        r    r/   r0   r1   varTr   )r'   r)   r$   r3   r   zDegrees of freedom is <= 0.)
stacklevelc                 S  s6   t j|  dd}t |  |dtd| j}|S )Nr3   r$   r   nan)paddleZarangenumelZ
index_fillflattenrN   reshapeshape)r%   indicesZout_nanrI   rI   rJ   _replace_nan  s   zvar.<locals>._replace_nan)stop_gradient)
ValueErrorrN   r   r   r4   r$   rT   r/   r0   sumpowr   rU   astypemaximumZ
zeros_likeanywarningswarnr[   rX   len	to_tensorZassign)r    r"   rL   r'   r)   rK   r%   Zactual_correctionur$   rH   nZcorrected_nrZ   resultrI   rI   rJ   rP      sR   3



rP   Tc                 C  s2   t  st| dg dd tdi t }t|S )aP	  
    Computes the standard-deviation of ``x`` along ``axis`` .

    Args:
        x (Tensor): The input Tensor with data type float16, float32, float64.
        axis (int|list|tuple|None, optional): The axis along which to perform
            standard-deviation calculations. ``axis`` should be int, list(int)
            or tuple(int). If ``axis`` is a list/tuple of dimension(s),
            standard-deviation is calculated along all element(s) of ``axis`` .
            ``axis`` or element(s) of ``axis`` should be in range [-D, D),
            where D is the dimensions of ``x`` . If ``axis`` or element(s) of
            ``axis`` is less than 0, it works the same way as :math:`axis + D` .
            If ``axis`` is None, standard-deviation is calculated over all
            elements of ``x``. Default is None.
        unbiased (bool, optional): Whether to use the unbiased estimation. If
            ``unbiased`` is True, the standard-deviation is calculated via the
            unbiased estimator. If ``unbiased`` is True,  the divisor used in
            the computation is :math:`N - 1`, where :math:`N` represents the
            number of elements along ``axis`` , otherwise the divisor is
            :math:`N`. Default is True.
        keepdim (bool, optional): Whether to reserve the reduced dimension(s)
            in the output Tensor. If ``keepdim`` is True, the dimensions of
            the output Tensor is the same as ``x`` except in the reduced
            dimensions(it is of size 1 in this case). Otherwise, the shape of
            the output Tensor is squeezed in ``axis`` . Default is False.
        name (str|None, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor, results of standard-deviation along ``axis`` of ``x``, with the
        same data type as ``x``.

    Examples:
        .. code-block:: python

            >>> import paddle

            >>> x = paddle.to_tensor([[1.0, 2.0, 3.0], [1.0, 4.0, 5.0]])
            >>> out1 = paddle.std(x)
            >>> print(out1.numpy())
            1.6329932
            >>> out2 = paddle.std(x, unbiased=False)
            >>> print(out2.numpy())
            1.490712
            >>> out3 = paddle.std(x, axis=1)
            >>> print(out3.numpy())
            [1.       2.081666]

    r    rO   stdNrI   )r	   r   rP   rC   rT   sqrt)r    r"   rL   r'   r)   r%   rI   rI   rJ   ri      s   8
ri   c                 C  s`   t  rt| S t| tstdtd	i t }|jt	j
jjd}|jdd| id|id |S )
a  
    Returns the number of elements for a tensor, which is a 0-D int64 Tensor with shape [].

    Args:
        x (Tensor): The input Tensor, it's data type can be bool, float16, float32, float64, uint8, int8, int32, int64, complex64, complex128.
        name (str|None, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor: The number of elements for the input Tensor, whose shape is [].

    Examples:
        .. code-block:: python

            >>> import paddle

            >>> x = paddle.full(shape=[4, 5, 7], fill_value=0, dtype='int32')
            >>> numel = paddle.numel(x)
            >>> print(numel.numpy())
            140


    zx must be a Tensor in numelrU   rR   sizeZInputr7   )r9   r:   r;   N)rU   )r	   r   rU   r=   r   	TypeErrorr   rC   rD   r   r>   r?   ZINT64rE   )r    r)   rG   r%   rI   rI   rJ   rU   `  s   

rU   .r@   modeLiteral['min']tuple[Tensor, Tensor]c                 C     d S NrI   r    r"   r'   rm   r)   rI   rI   rJ   	nanmedian     rs   Literal['avg', 'min']c                 C  rp   rq   rI   rr   rI   rI   rJ   rs     rt   avgc           
      C  s@  t | ttjjfstdt |ttfrt|dkrt	d|dvr*t	d| d|duo5t |ttf }|du r=g }nt |trGt|}nt |t
rO|g}t r`t| |||\}}d|_n4t| d	g d
d tdi t }|||d}	|| j}|tj}|jdd	| i||d|	d d|_|dkr|r||fS |S )a?  
    Compute the median along the specified axis, while ignoring NaNs.

    If the valid count of elements is a even number,
    the average value of both elements in the middle is calculated as the median.

    Args:
        x (Tensor): The input Tensor, it's data type can be int32, int64, float16, bfloat16, float32, float64.
        axis (None|int|list|tuple, optional):
            The axis along which to perform median calculations ``axis`` should be int or list of int.
            ``axis`` should be in range [-D, D), where D is the dimensions of ``x`` .
            If ``axis`` is less than 0, it works the same way as :math:`axis + D`.
            If ``axis`` is None, median is calculated over all elements of ``x``. Default is None.
        keepdim (bool, optional): Whether to reserve the reduced dimension(s)
            in the output Tensor. If ``keepdim`` is True, the dimensions of
            the output Tensor is the same as ``x`` except in the reduced
            dimensions(it is of size 1 in this case). Otherwise, the shape of
            the output Tensor is squeezed in ``axis`` . Default is False.
        mode (str, optional): Whether to use mean or min operation to calculate
            the nanmedian values when the input tensor has an even number of non-NaN elements
            along the dimension ``axis``. Support 'avg' and 'min'. Default is 'avg'.
        name (str|None, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor or tuple of Tensor. If ``mode`` == 'min' and ``axis`` is int, the result
        will be a tuple of two tensors (nanmedian value and nanmedian index). Otherwise,
        only nanmedian value will be returned.

    Examples:
        .. code-block:: python

            >>> import paddle
            >>> x = paddle.to_tensor([[float('nan'), 2. , 3. ], [0. , 1. , 2. ]])

            >>> y1 = x.nanmedian()
            >>> print(y1.numpy())
            2.0

            >>> y2 = x.nanmedian(0)
            >>> print(y2.numpy())
            [0.  1.5 2.5]

            >>> y3 = x.nanmedian(0, keepdim=True)
            >>> print(y3.numpy())
            [[0.  1.5 2.5]]

            >>> y4 = x.nanmedian((0, 1))
            >>> print(y4.numpy())
            2.0

            >>> y5 = x.nanmedian(mode='min')
            >>> print(y5.numpy())
            2.0

            >>> y6, y6_index = x.nanmedian(0, mode='min')
            >>> print(y6.numpy())
            [0. 1. 2.]
            >>> print(y6_index.numpy())
            [1 1 1]

            >>> y7, y7_index = x.nanmedian(1, mode='min')
            >>> print(y7.numpy())
            [2. 1.]
            >>> print(y7_index.numpy())
            [1 1]

            >>> y8 = x.nanmedian((0,1), mode='min')
            >>> print(y8.numpy())
            2.0
    *In median, the input x should be a Tensor.r   Axis list should not be empty.rv   minMode & is not supported. Must be avg or min.NTr6   )r2   r3   r/   r0   r1   r.   rs   )r"   r'   rm   )r7   ZMedianIndexr8   rz   )rs   )r=   r   rT   pirValuerl   rA   rB   rd   r\   r@   r	   r   rs   r[   r   r   rC   rD   r$   r3   rE   )
r    r"   r'   rm   r)   Z
need_indexr%   rY   rG   r<   rI   rI   rJ   rs     sH   N


c                 C  rp   rq   rI   rr   rI   rI   rJ   median  rt   r   
int | Nonec                 C  rp   rq   rI   rr   rI   rI   rJ   r     rt   rz   c           
      C  s(  t | ttjjfstdt |ttfrt|dkrt	dt| j
}|dkr0|dv s/J dn|durFt |trB||k rB|| ksFt	d|dvrRt	d	| d
|du}|du r\d}|du rcg }nt |trk|g}|dkr{| jtjks{| tj} t| |||\}}	d|	_|dkr|r||	fS |S )a  
    Compute the median along the specified axis.

    .. note::
        Alias Support: The parameter name ``input`` can be used as an alias for ``x``, and ``dim`` can be used as an alias for ``axis``.
        When an alias replacement occurs, the default parameter for mode setting is min instead of avg.
        For example, ``median(input=tensor_x, dim=1, ...)`` is equivalent to ``median(x=tensor_x, axis=1, ...)``.

    Args:
        x (Tensor): The input Tensor, it's data type can be bfloat16, float16, float32, float64, int32, int64.
            alias: ``input``.
        axis (int|None, optional): The axis along which to perform median calculations ``axis`` should be int.
            alias: ``dim``.
            ``axis`` should be in range [-D, D), where D is the dimensions of ``x`` .
            If ``axis`` is less than 0, it works the same way as :math:`axis + D`.
            If ``axis`` is None, median is calculated over all elements of ``x``. Default is None.
        keepdim (bool, optional): Whether to reserve the reduced dimension(s)
            in the output Tensor. If ``keepdim`` is True, the dimensions of
            the output Tensor is the same as ``x`` except in the reduced
            dimensions(it is of size 1 in this case). Otherwise, the shape of
            the output Tensor is squeezed in ``axis`` . Default is False.
        mode (str, optional): Whether to use mean or min operation to calculate
            the median values when the input tensor has an even number of elements
            in the dimension ``axis``. Support 'avg' and 'min'. Default is 'avg'.
            When an alias replacement occurs, the default parameter for mode setting is min instead of avg.
        name (str|None, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor or tuple of Tensor.
        If ``mode`` == 'avg', the result will be the tensor of median values;
        If ``mode`` == 'min' and ``axis`` is None, the result will be the tensor of median values;
        If ``mode`` == 'min' and ``axis`` is not None, the result will be a tuple of two tensors
        containing median values and their indices.

        When ``mode`` == 'avg', if data type of ``x`` is float64, data type of median values will be float64,
        otherwise data type of median values will be float32.
        When ``mode`` == 'min', the data type of median values will be the same as ``x``. The data type of
        indices will be int64.

    Examples:
        .. code-block:: python

            >>> import paddle
            >>> import numpy as np

            >>> x = paddle.arange(12).reshape([3, 4])
            >>> print(x)
            Tensor(shape=[3, 4], dtype=int64, place=Place(cpu), stop_gradient=True,
            [[0 , 1 , 2 , 3 ],
             [4 , 5 , 6 , 7 ],
             [8 , 9 , 10, 11]])

            >>> y1 = paddle.median(x)
            >>> print(y1)
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            5.50000000)

            >>> y2 = paddle.median(x, axis=0)
            >>> print(y2)
            Tensor(shape=[4], dtype=float32, place=Place(cpu), stop_gradient=True,
            [4., 5., 6., 7.])

            >>> y3 = paddle.median(x, axis=1)
            >>> print(y3)
            Tensor(shape=[3], dtype=float32, place=Place(cpu), stop_gradient=True,
            [1.50000000, 5.50000000, 9.50000000])

            >>> y4 = paddle.median(x, axis=0, keepdim=True)
            >>> print(y4)
            Tensor(shape=[1, 4], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[4., 5., 6., 7.]])

            >>> y5 = paddle.median(x, mode='min')
            >>> print(y5)
            Tensor(shape=[], dtype=int64, place=Place(cpu), stop_gradient=True,
            5)

            >>> median_value, median_indices = paddle.median(x, axis=1, mode='min')
            >>> print(median_value)
            Tensor(shape=[3], dtype=int64, place=Place(cpu), stop_gradient=True,
            [1, 5, 9])
            >>> print(median_indices)
            Tensor(shape=[3], dtype=int64, place=Place(cpu), stop_gradient=True,
            [1, 1, 1])

            >>> # cases containing nan values
            >>> x = paddle.to_tensor(np.array([[1,float('nan'),3,float('nan')],[1,2,3,4],[float('nan'),1,2,3]]))

            >>> y6 = paddle.median(x, axis=-1, keepdim=True)
            >>> print(y6)
            Tensor(shape=[3, 1], dtype=float64, place=Place(cpu), stop_gradient=True,
            [[nan       ],
             [2.50000000],
             [nan       ]])

            >>> median_value, median_indices = paddle.median(x, axis=1, keepdim=True, mode='min')
            >>> print(median_value)
            Tensor(shape=[3, 1], dtype=float64, place=Place(cpu), stop_gradient=True,
            [[nan],
             [2. ],
             [nan]])
            >>> print(median_indices)
            Tensor(shape=[3, 1], dtype=int64, place=Place(cpu), stop_gradient=True,
            [[1],
             [1],
             [0]])
    rw   r   rx   )r   Nz8when input 0-D, axis can only be [-1, 0] or default NoneNzJIn median, axis should be none or an integer in range [-rank(x), rank(x)).ry   r{   r|   Trv   rz   )r=   r   rT   r}   r~   rl   rA   rB   rd   r\   rX   r@   r$   r1   r_   r0   r   r   r[   )
r    r"   r'   rm   r)   dimsZneed_idxZ
is_flattenr%   rY   rI   rI   rJ   r   (  s<   t


r   q'float | Sequence[float] | Tensor | Noneint | list[int] | Noneinterpolation
ignore_nanc                   s\  t ttjjfstdt |ttfr|g}n5t |tt	fr*t
|dkr)tdn#t |ttjjfrIt
|jdkr>tdt
|jdkrH|g}ntd|D ]}t s_t |ttjjfr_ n|dk sg|dkrktdqOdvrwtd	 t
j}tj} d
u rtd dg| }nt  trg g }	}
 D ]%}t |tr||k r|| kstd|dk r|| }|	| d||< qttt
  d}
t|	|
t
|
dkrtd n2t|
d |
d |
d  n"t  tr |k r | kstd dk r |7  d| <  }| j dd}g }|D ]B}t r4tj|jd}|rB|||d   q&||d  }j  d }tj||d}t|j dd||}|| q&t  fdd}g }|D ]}||}|stj| d}n||}|| q|t
|dkrt|d}|S |d }|S )a  
    Compute the quantile of the input along the specified axis.

    Args:
        x (Tensor): The input Tensor, it's data type can be float32, float64, int32, int64.
        q (int|float|list|Tensor): The q for calculate quantile, which should be in range [0, 1]. If q is a list or
            a 1-D Tensor, each element of q will be calculated and the first dimension of output is same to the number of ``q`` .
            If q is a 0-D Tensor, it will be treated as an integer or float.
        axis (int|list, optional): The axis along which to calculate quantile. ``axis`` should be int or list of int.
            ``axis`` should be in range [-D, D), where D is the dimensions of ``x`` .
            If ``axis`` is less than 0, it works the same way as :math:`axis + D`.
            If ``axis`` is a list, quantile is calculated over all elements of given axes.
            If ``axis`` is None, quantile is calculated over all elements of ``x``. Default is None.
        keepdim (bool, optional): Whether to reserve the reduced dimension(s)
            in the output Tensor. If ``keepdim`` is True, the dimensions of
            the output Tensor is the same as ``x`` except in the reduced
            dimensions(it is of size 1 in this case). Otherwise, the shape of
            the output Tensor is squeezed in ``axis`` . Default is False.
        interpolation (str, optional): The interpolation method to use
            when the desired quantile falls between two data points. Must be one of linear, higher,
            lower, midpoint and nearest. Default is linear.
        ignore_nan: (bool, optional): Whether to ignore NaN of input Tensor.
            If ``ignore_nan`` is True, it will calculate nanquantile.
            Otherwise it will calculate quantile. Default is False.

    Returns:
        Tensor, results of quantile along ``axis`` of ``x``.
        In order to obtain higher precision, data type of results will be float64.
    zinput x should be a Tensor.r   zq should not be emptyr   z(q should be a 0-D tensor or a 1-D tensorz8Type of q should be int, float, list or tuple, or tensorzq should be in range [0, 1])r   r   r   r   r   z[interpolation must be one of 'linear', 'lower', 'higher', 'nearest' or 'midpoint', but got NzQAxis should be None, int, or a list, element should in range [-rank(x), rank(x)).r   T)r"   r'   rR   )Z
fill_valuec                   s   dkrt | t j}t j| dS t | t j}dkr*t j| d}dkr0|S t | t j}t j| d}dkrG|S dkrQ|| d S | || j j}t |j|j|S )Nr   r"   r   r   r   r   )	rT   roundr_   r2   Ztake_along_axisfloorceilr$   Zlerp)indexidxZindices_belowZtensor_belowZindices_upperZtensor_upperweightsr"   r   Zsorted_tensorr    rI   rJ   _compute_indexJ  s0   

z)_compute_quantile.<locals>._compute_indexr   )r=   r   rT   r}   r~   rl   r@   rN   rA   rB   rd   r\   rX   r   rV   appendrangeZmoveaxisisnanZlogical_notr]   r	   re   r$   Z	full_likewherera   sortZsqueezerW   stack)r    r   r"   r'   r   r   Zq_numr   Z	out_shapeZaxis_srcZaxis_dstZaxis_singlemaskZvalid_countsrY   r   
last_indexnumsr   r;   r%   rI   r   rJ   _compute_quantile  s   &









"
 
r    float | Sequence[float] | Tensorc                 C     t | ||||ddS )a  
    Compute the quantile of the input along the specified axis.
    If any values in a reduced row are NaN, then the quantiles for that reduction will be NaN.

    Args:
        x (Tensor): The input Tensor, it's data type can be float32, float64, int32, int64.
        q (int|float|list|Tensor): The q for calculate quantile, which should be in range [0, 1]. If q is a list or
            a 1-D Tensor, each element of q will be calculated and the first dimension of output is same to the number of ``q`` .
            If q is a 0-D Tensor, it will be treated as an integer or float.
        axis (int|list, optional): The axis along which to calculate quantile. ``axis`` should be int or list of int.
            ``axis`` should be in range [-D, D), where D is the dimensions of ``x`` .
            If ``axis`` is less than 0, it works the same way as :math:`axis + D`.
            If ``axis`` is a list, quantile is calculated over all elements of given axes.
            If ``axis`` is None, quantile is calculated over all elements of ``x``. Default is None.
        keepdim (bool, optional): Whether to reserve the reduced dimension(s)
            in the output Tensor. If ``keepdim`` is True, the dimensions of
            the output Tensor is the same as ``x`` except in the reduced
            dimensions(it is of size 1 in this case). Otherwise, the shape of
            the output Tensor is squeezed in ``axis`` . Default is False.
        interpolation (str, optional): The interpolation method to use
            when the desired quantile falls between two data points. Must be one of linear, higher,
            lower, midpoint and nearest. Default is linear.
        name (str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor, results of quantile along ``axis`` of ``x``.

    Examples:
        .. code-block:: python

            >>> import paddle

            >>> y = paddle.arange(0, 8 ,dtype="float32").reshape([4, 2])
            >>> print(y)
            Tensor(shape=[4, 2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[0., 1.],
             [2., 3.],
             [4., 5.],
             [6., 7.]])

            >>> y1 = paddle.quantile(y, q=0.5, axis=[0, 1])
            >>> print(y1)
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            3.50000000)

            >>> y2 = paddle.quantile(y, q=0.5, axis=1)
            >>> print(y2)
            Tensor(shape=[4], dtype=float32, place=Place(cpu), stop_gradient=True,
            [0.50000000, 2.50000000, 4.50000000, 6.50000000])

            >>> y3 = paddle.quantile(y, q=[0.3, 0.5], axis=0)
            >>> print(y3)
            Tensor(shape=[2, 2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[1.80000000, 2.80000000],
             [3.        , 4.        ]])

            >>> y[0,0] = float("nan")
            >>> y4 = paddle.quantile(y, q=0.8, axis=1, keepdim=True)
            >>> print(y4)
            Tensor(shape=[4, 1], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[nan       ],
             [2.80000000],
             [4.80000000],
             [6.80000000]])

    Fr"   r'   r   r   r   r    r   r"   r'   r   rI   rI   rJ   quantile}  s   Jr   list[int] | int | Nonec                 C  r   )a  
    Compute the quantile of the input as if NaN values in input did not exist.
    If all values in a reduced row are NaN, then the quantiles for that reduction will be NaN.

    Args:
        x (Tensor): The input Tensor, it's data type can be float32, float64, int32, int64.
        q (int|float|list|Tensor): The q for calculate quantile, which should be in range [0, 1]. If q is a list or
            a 1-D Tensor, each element of q will be calculated and the first dimension of output is same to the number of ``q`` .
            If q is a 0-D Tensor, it will be treated as an integer or float.
        axis (int|list, optional): The axis along which to calculate quantile. ``axis`` should be int or list of int.
            ``axis`` should be in range [-D, D), where D is the dimensions of ``x`` .
            If ``axis`` is less than 0, it works the same way as :math:`axis + D`.
            If ``axis`` is a list, quantile is calculated over all elements of given axes.
            If ``axis`` is None, quantile is calculated over all elements of ``x``. Default is None.
        keepdim (bool, optional): Whether to reserve the reduced dimension(s)
            in the output Tensor. If ``keepdim`` is True, the dimensions of
            the output Tensor is the same as ``x`` except in the reduced
            dimensions(it is of size 1 in this case). Otherwise, the shape of
            the output Tensor is squeezed in ``axis`` . Default is False.
        interpolation (str, optional): The interpolation method to use
            when the desired quantile falls between two data points. Must be one of linear, higher,
            lower, midpoint and nearest. Default is linear.
        name (str|None, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor, results of quantile along ``axis`` of ``x``.

    Examples:
        .. code-block:: python

            >>> import paddle

            >>> x = paddle.to_tensor(
            ...     [[0, 1, 2, 3, 4],
            ...      [5, 6, 7, 8, 9]],
            ...     dtype="float32")
            >>> x[0,0] = float("nan")

            >>> y1 = paddle.nanquantile(x, q=0.5, axis=[0, 1])
            >>> print(y1)
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            5.)

            >>> y2 = paddle.nanquantile(x, q=0.5, axis=1)
            >>> print(y2)
            Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [2.50000000, 7.        ])

            >>> y3 = paddle.nanquantile(x, q=[0.3, 0.5], axis=0)
            >>> print(y3)
            Tensor(shape=[2, 5], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[5.        , 2.50000000, 3.50000000, 4.50000000, 5.50000000],
             [5.        , 3.50000000, 4.50000000, 5.50000000, 6.50000000]])

            >>> y4 = paddle.nanquantile(x, q=0.8, axis=1, keepdim=True)
            >>> print(y4)
            Tensor(shape=[2, 1], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[3.40000000],
             [8.20000000]])

            >>> nan = paddle.full(shape=[2, 3], fill_value=float("nan"))
            >>> y5 = paddle.nanquantile(nan, q=0.8, axis=1, keepdim=True)
            >>> print(y5)
            Tensor(shape=[2, 1], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[nan],
             [nan]])

    Tr   r   r   rI   rI   rJ   nanquantile  s   Lr   )NFN)r    r   r"   r&   r'   r(   r)   r*   r$   r+   r%   r,   r-   r   )NNFN)r    r   r"   r&   rL   rM   r'   r(   r)   r*   rK   rN   r%   r,   r-   r   )NTFN)r    r   r"   r&   rL   r(   r'   r(   r)   r*   r-   r   rq   )r    r   r)   r*   r-   r   )...)r    r   r"   r@   r'   r(   rm   rn   r)   r*   r-   ro   )....)r    r   r"   r&   r'   r(   rm   ru   r)   r*   r-   r   )NFrv   N)r    r   r"   r   r'   r(   rm   ru   r)   r*   r-   r   )NFr   F)r    r   r   r   r"   r   r'   r(   r   r   r   r(   r-   r   )NFr   )r    r   r   r   r"   r   r'   r(   r   r   r-   r   )r    r   r   r   r"   r   r'   r(   r   r   r-   r   )0
__future__r   rb   typingr   r   Ztyping_extensionsr   r   rT   r   Zpaddle.frameworkr   r	   Zpaddle.utils.decorator_utilsr
   r   r   Zbase.data_feederr   r   Zcommon_ops_importr   Z	frameworkr   r   r   Zmanipulationr   mathr   collections.abcr   r   Zpaddle._typingr   r   __annotations____all__r4   rP   ri   rU   rs   r   r   r   r   rI   rI   rI   rJ   <module>   s   |p@%	
{		   <W