
    _Mhb                         d dl Z d dlZd dlmZmZ d dlmZ d dlmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZ d dlZddlmZ ddlmZmZ dgZ e j                    Z  G d	 d          Z!d
 Z"dS )    N)linalgspecial)check_random_state)asarray
atleast_2dreshapezerosnewaxisexppisqrtravelpower
atleast_1dsqueezesum	transposeonescov   )_mvn)gaussian_kernel_estimategaussian_kernel_estimate_loggaussian_kdec                       e Zd ZdZddZd ZeZd Zd ZddZ	d Z
dd	Zd
 Zd ZeZde_        ddZd Zed             Zd Zd Zd Zed             Zed             ZdS )r   a&  Representation of a kernel-density estimate using Gaussian kernels.

    Kernel density estimation is a way to estimate the probability density
    function (PDF) of a random variable in a non-parametric way.
    `gaussian_kde` works for both uni-variate and multi-variate data.   It
    includes automatic bandwidth determination.  The estimation works best for
    a unimodal distribution; bimodal or multi-modal distributions tend to be
    oversmoothed.

    Parameters
    ----------
    dataset : array_like
        Datapoints to estimate from. In case of univariate data this is a 1-D
        array, otherwise a 2-D array with shape (# of dims, # of data).
    bw_method : str, scalar or callable, optional
        The method used to calculate the estimator bandwidth.  This can be
        'scott', 'silverman', a scalar constant or a callable.  If a scalar,
        this will be used directly as `kde.factor`.  If a callable, it should
        take a `gaussian_kde` instance as only parameter and return a scalar.
        If None (default), 'scott' is used.  See Notes for more details.
    weights : array_like, optional
        weights of datapoints. This must be the same shape as dataset.
        If None (default), the samples are assumed to be equally weighted

    Attributes
    ----------
    dataset : ndarray
        The dataset with which `gaussian_kde` was initialized.
    d : int
        Number of dimensions.
    n : int
        Number of datapoints.
    neff : int
        Effective number of datapoints.

        .. versionadded:: 1.2.0
    factor : float
        The bandwidth factor, obtained from `kde.covariance_factor`. The square
        of `kde.factor` multiplies the covariance matrix of the data in the kde
        estimation.
    covariance : ndarray
        The covariance matrix of `dataset`, scaled by the calculated bandwidth
        (`kde.factor`).
    inv_cov : ndarray
        The inverse of `covariance`.

    Methods
    -------
    evaluate
    __call__
    integrate_gaussian
    integrate_box_1d
    integrate_box
    integrate_kde
    pdf
    logpdf
    resample
    set_bandwidth
    covariance_factor

    Notes
    -----
    Bandwidth selection strongly influences the estimate obtained from the KDE
    (much more so than the actual shape of the kernel).  Bandwidth selection
    can be done by a "rule of thumb", by cross-validation, by "plug-in
    methods" or by other means; see [3]_, [4]_ for reviews.  `gaussian_kde`
    uses a rule of thumb, the default is Scott's Rule.

    Scott's Rule [1]_, implemented as `scotts_factor`, is::

        n**(-1./(d+4)),

    with ``n`` the number of data points and ``d`` the number of dimensions.
    In the case of unequally weighted points, `scotts_factor` becomes::

        neff**(-1./(d+4)),

    with ``neff`` the effective number of datapoints.
    Silverman's Rule [2]_, implemented as `silverman_factor`, is::

        (n * (d + 2) / 4.)**(-1. / (d + 4)).

    or in the case of unequally weighted points::

        (neff * (d + 2) / 4.)**(-1. / (d + 4)).

    Good general descriptions of kernel density estimation can be found in [1]_
    and [2]_, the mathematics for this multi-dimensional implementation can be
    found in [1]_.

    With a set of weighted samples, the effective number of datapoints ``neff``
    is defined by::

        neff = sum(weights)^2 / sum(weights^2)

    as detailed in [5]_.

    `gaussian_kde` does not currently support data that lies in a
    lower-dimensional subspace of the space in which it is expressed. For such
    data, consider performing principal component analysis / dimensionality
    reduction and using `gaussian_kde` with the transformed data.

    References
    ----------
    .. [1] D.W. Scott, "Multivariate Density Estimation: Theory, Practice, and
           Visualization", John Wiley & Sons, New York, Chicester, 1992.
    .. [2] B.W. Silverman, "Density Estimation for Statistics and Data
           Analysis", Vol. 26, Monographs on Statistics and Applied Probability,
           Chapman and Hall, London, 1986.
    .. [3] B.A. Turlach, "Bandwidth Selection in Kernel Density Estimation: A
           Review", CORE and Institut de Statistique, Vol. 19, pp. 1-33, 1993.
    .. [4] D.M. Bashtannyk and R.J. Hyndman, "Bandwidth selection for kernel
           conditional density estimation", Computational Statistics & Data
           Analysis, Vol. 36, pp. 279-298, 2001.
    .. [5] Gray P. G., 1969, Journal of the Royal Statistical Society.
           Series A (General), 132, 272

    Examples
    --------
    Generate some random two-dimensional data:

    >>> import numpy as np
    >>> from scipy import stats
    >>> def measure(n):
    ...     "Measurement model, return two coupled measurements."
    ...     m1 = np.random.normal(size=n)
    ...     m2 = np.random.normal(scale=0.5, size=n)
    ...     return m1+m2, m1-m2

    >>> m1, m2 = measure(2000)
    >>> xmin = m1.min()
    >>> xmax = m1.max()
    >>> ymin = m2.min()
    >>> ymax = m2.max()

    Perform a kernel density estimate on the data:

    >>> X, Y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
    >>> positions = np.vstack([X.ravel(), Y.ravel()])
    >>> values = np.vstack([m1, m2])
    >>> kernel = stats.gaussian_kde(values)
    >>> Z = np.reshape(kernel(positions).T, X.shape)

    Plot the results:

    >>> import matplotlib.pyplot as plt
    >>> fig, ax = plt.subplots()
    >>> ax.imshow(np.rot90(Z), cmap=plt.cm.gist_earth_r,
    ...           extent=[xmin, xmax, ymin, ymax])
    >>> ax.plot(m1, m2, 'k.', markersize=2)
    >>> ax.set_xlim([xmin, xmax])
    >>> ax.set_ylim([ymin, ymax])
    >>> plt.show()

    Nc                    t          t          |                    | _        | j        j        dk    st	          d          | j        j        \  | _        | _        |t          |          	                    t                    | _        | xj        t          | j                  z  c_        | j        j        dk    rt	          d          t          | j                  | j        k    rt	          d          dt          | j        dz            z  | _        | j        | j        k    rd}t	          |          	 |                     |           d S # t$          j        $ r}d}t%          j        |          |d }~ww xY w)	Nr   z.`dataset` input should have multiple elements.z*`weights` input should be one-dimensional.z%`weights` input should be of length n   a1  Number of dimensions is greater than number of samples. This results in a singular data covariance matrix, which cannot be treated using the algorithms implemented in `gaussian_kde`. Note that `gaussian_kde` interprets each *column* of `dataset` to be a point; consider transposing the input to `dataset`.	bw_methodab  The data appears to lie in a lower-dimensional subspace of the space in which it is expressed. This has resulted in a singular data covariance matrix, which cannot be treated using the algorithms implemented in `gaussian_kde`. Consider performing principal component analysis / dimensionality reduction and using `gaussian_kde` with the transformed data.)r   r   datasetsize
ValueErrorshapednr   astypefloat_weightsr   weightsndimlen_neffset_bandwidthr   LinAlgError)selfr    r   r)   msges         P/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/scipy/stats/_kde.py__init__zgaussian_kde.__init__   sk   !''"2"233| 1$$MNNN+&w//66u==DMMMS///MM| A%% !MNNN4=!!TV++ !HIII3t}a/000DJ 6DF??-C S//!
	133333! 	1 	1 	1?C $S))q0	1s   6E E9E44E9c                    t          t          |                    }|j        \  }}|| j        k    rG|dk    r%|| j        k    rt	          || j        df          }d}nd| d| j         }t          |          t          | j        |          \  }}t          |         | j	        j
        | j        dddf         |j
        | j        |          }|dddf         S )a  Evaluate the estimated pdf on a set of points.

        Parameters
        ----------
        points : (# of dimensions, # of points)-array
            Alternatively, a (# of dimensions,) vector can be passed in and
            treated as a single point.

        Returns
        -------
        values : (# of points,)-array
            The values at each point.

        Raises
        ------
        ValueError : if the dimensionality of the input points is different than
                     the dimensionality of the KDE.

        r   points have dimension , dataset has dimension Nr   )r   r   r#   r$   r   r"   _get_output_dtype
covariancer   r    Tr)   cho_cov)r/   pointsr$   mr0   output_dtypespecresults           r2   evaluatezgaussian_kde.evaluate   s    ( GFOO,,|1;;Avv!tv++ $&!559 9 9049 9 oo%.tGGd)$/LNDLD1HdlL2 2 aaad|    c                    t          t          |                    }t          |          }|j        | j        fk    rt          d| j                   |j        | j        | j        fk    rt          d| j                   |ddt          f         }| j        |z   }t          j	        |          }| j
        |z
  }t          j        ||          }t          j        t          j        |d                             }t          dt           z  |j        d         dz            |z  }t#          ||z  d          dz  }	t#          t%          |	           | j        z  d          |z  }
|
S )aW  
        Multiply estimated density by a multivariate Gaussian and integrate
        over the whole space.

        Parameters
        ----------
        mean : aray_like
            A 1-D array, specifying the mean of the Gaussian.
        cov : array_like
            A 2-D array, specifying the covariance matrix of the Gaussian.

        Returns
        -------
        result : scalar
            The value of the integral.

        Raises
        ------
        ValueError
            If the mean or covariance of the input Gaussian differs from
            the KDE's dimensionality.

        zmean does not have dimension z#covariance does not have dimension Nr   r          @axis)r   r   r   r#   r$   r"   r
   r8   r   
cho_factorr    	cho_solvenpproddiagonalr   r   r   r   r)   )r/   meanr   sum_covsum_cov_choldifftdiffsqrt_det
norm_constenergiesr?   s              r2   integrate_gaussianzgaussian_kde.integrate_gaussian  sR   0 '$--((oo:$&""ETVEEFFF9(((K46KKLLL AAAwJ/C'
 (11|d" t4472;|A77881r67=#3c#9::XE
te|!,,,s2S(^^DL0q999JFrA   c                 v   | j         dk    rt          d          t          t          | j                            d         }t          || j        z
  |z            }t          || j        z
  |z            }t          j        | j        t          j
        |          t          j
        |          z
  z            }|S )a  
        Computes the integral of a 1D pdf between two bounds.

        Parameters
        ----------
        low : scalar
            Lower bound of integration.
        high : scalar
            Upper bound of integration.

        Returns
        -------
        value : scalar
            The result of the integral.

        Raises
        ------
        ValueError
            If the KDE is over more than one dimension.

        r   z'integrate_box_1d() only handles 1D pdfsr   )r$   r"   r   r   r8   r    rH   r   r)   r   ndtr)r/   lowhighstdevnormalized_lownormalized_highvalues          r2   integrate_box_1dzgaussian_kde.integrate_box_1dL  s    , 6Q;;FGGGd4?++,,Q/dl 2e;<<!4 =>>t|_55^4456 7 7 rA   c                     |d|i}ni }t           5  t          j        ||| j        | j        | j        fi |\  }}ddd           n# 1 swxY w Y   |r#d| j        dz   }t          j        |d           |S )a  Computes the integral of a pdf over a rectangular interval.

        Parameters
        ----------
        low_bounds : array_like
            A 1-D array containing the lower bounds of integration.
        high_bounds : array_like
            A 1-D array containing the upper bounds of integration.
        maxpts : int, optional
            The maximum number of points to use for integration.

        Returns
        -------
        value : scalar
            The result of the integral.

        Nmaxptsz4An integral in _mvn.mvnun requires more points than i  r   )
stacklevel)	MVN_LOCKr   mvnun_weightedr    r)   r8   r$   warningswarn)r/   
low_boundshigh_boundsr^   
extra_kwdsr[   informr0   s           r2   integrate_boxzgaussian_kde.integrate_boxo  s    $ "F+JJJ 	O 	O /
K04dl04O OCMO OME6	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O  	-XRVXXCM#!,,,,s   )AA
A
c                    |j         | j         k    rt          d          |j        | j        k     r|}| }n| }|}|j        |j        z   }t	          j        |          }d}t          |j                  D ]}|j        dd|t          f         }|j        |z
  }	t	          j	        ||	          }
t          |	|
z  d          dz  }|t          t          |           |j        z  d          |j        |         z  z  }t          j        t          j        |d                             }t!          dt"          z  |j        d         dz            |z  }||z  }|S )a  
        Computes the integral of the product of this  kernel density estimate
        with another.

        Parameters
        ----------
        other : gaussian_kde instance
            The other kde.

        Returns
        -------
        value : scalar
            The result of the integral.

        Raises
        ------
        ValueError
            If the KDEs have different dimensionality.

        z$KDEs are not the same dimensionalityg        Nr   rD   rC   r   )r$   r"   r%   r8   r   rF   ranger    r
   rG   r   r   r)   rH   rI   rJ   r   r   r#   )r/   othersmalllargerL   rM   r?   irK   rN   rO   rR   rP   rQ   s                 r2   integrate_kdezgaussian_kde.integrate_kde  sZ   * 7dfCDDD 7TVEEEEE"U%55(11uw 	Q 	QA=Aw/D=4'D$\488E4%<a00036Hc#xi..6Q???a@PPPFF72;|A77881r67=#3c#9::XE
*rA   c                 B   |t          | j                  }t          |          }t          |                    t          | j        ft                    | j        |                    }|	                    | j
        || j                  }| j        dd|f         }||z   S )aA  Randomly sample a dataset from the estimated pdf.

        Parameters
        ----------
        size : int, optional
            The number of samples to draw.  If not provided, then the size is
            the same as the effective number of samples in the underlying
            dataset.
        seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
            If `seed` is None (or `np.random`), the `numpy.random.RandomState`
            singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used,
            seeded with `seed`.
            If `seed` is already a ``Generator`` or ``RandomState`` instance then
            that instance is used.

        Returns
        -------
        resample : (self.d, `size`) ndarray
            The sampled dataset.

        N)r!   )r!   p)intneffr   r   multivariate_normalr	   r$   r'   r8   choicer%   r)   r    )r/   r!   seedrandom_statenormindicesmeanss          r2   resamplezgaussian_kde.resample  s    . <ty>>D)$//9946)U##T_4 : 
 
   %%df44<%HHQQQZ(t|rA   c                 B    t          | j        d| j        dz   z            S )zoCompute Scott's factor.

        Returns
        -------
        s : float
            Scott's factor.
                 r   rs   r$   r/   s    r2   scotts_factorzgaussian_kde.scotts_factor  s      TYTVAX///rA   c                 ^    t          | j        | j        dz   z  dz  d| j        dz   z            S )z{Compute the Silverman factor.

        Returns
        -------
        s : float
            The silverman factor.
        rC   g      @r}   r~   r   r   s    r2   silverman_factorzgaussian_kde.silverman_factor  s0     TYs
+C/dfQh@@@rA   a0  Computes the coefficient (`kde.factor`) that
        multiplies the data covariance matrix to obtain the kernel covariance
        matrix. The default is `scotts_factor`.  A subclass can overwrite this
        method to provide a different method, or set it through a call to
        `kde.set_bandwidth`.c                 ^    ndk    r j          _        ndk    r j         _        nmt          j                  r't          t                    sd _        fd _        n2t                    r _         fd _        nd}t          |           
                                 dS )aX  Compute the estimator bandwidth with given method.

        The new bandwidth calculated after a call to `set_bandwidth` is used
        for subsequent evaluations of the estimated density.

        Parameters
        ----------
        bw_method : str, scalar or callable, optional
            The method used to calculate the estimator bandwidth.  This can be
            'scott', 'silverman', a scalar constant or a callable.  If a
            scalar, this will be used directly as `kde.factor`.  If a callable,
            it should take a `gaussian_kde` instance as only parameter and
            return a scalar.  If None (default), nothing happens; the current
            `kde.covariance_factor` method is kept.

        Notes
        -----
        .. versionadded:: 0.11

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.stats as stats
        >>> x1 = np.array([-7, -5, 1, 4, 5.])
        >>> kde = stats.gaussian_kde(x1)
        >>> xs = np.linspace(-10, 10, num=50)
        >>> y1 = kde(xs)
        >>> kde.set_bandwidth(bw_method='silverman')
        >>> y2 = kde(xs)
        >>> kde.set_bandwidth(bw_method=kde.factor / 3.)
        >>> y3 = kde(xs)

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x1, np.full(x1.shape, 1 / (4. * x1.size)), 'bo',
        ...         label='Data points (rescaled)')
        >>> ax.plot(xs, y1, label='Scott (default)')
        >>> ax.plot(xs, y2, label='Silverman')
        >>> ax.plot(xs, y3, label='Const (1/3 * Silverman)')
        >>> ax.legend()
        >>> plt.show()

        Nscott	silvermanzuse constantc                       S N r   s   r2   <lambda>z,gaussian_kde.set_bandwidth.<locals>.<lambda>5  s    Y rA   c                  .                                     S r   )
_bw_methodr   s   r2   r   z,gaussian_kde.set_bandwidth.<locals>.<lambda>8  s    T__T-B-B rA   zC`bw_method` should be 'scott', 'silverman', a scalar or a callable.)r   covariance_factorr   rH   isscalar
isinstancestrr   callabler"   _compute_covariance)r/   r   r0   s   `` r2   r-   zgaussian_kde.set_bandwidth  s    X '!!%)%7D""+%%%)%:D""[## 		"Jy#,F,F 		",DO%6%6%6%6D""i   	"'DO%B%B%B%BD""#CS//!  """""rA   c           
      J   |                                  | _        t          | d          sOt          t	          | j        dd| j                            | _        t          j	        | j        d          | _
        | j        | j        dz  z  | _        | j
        | j        z                      t          j                  | _        dt          j        t          j        | j        t          j        dt&          z            z                                                      z  | _        dS )	zcComputes the covariance matrix for each Gaussian kernel using
        covariance_factor().
        _data_cho_covr   FrowvarbiasaweightsT)lowerr   N)r   factorhasattrr   r   r    r)   _data_covariancer   choleskyr   r8   r&   rH   float64r:   logdiagr   r   r   log_detr   s    r2   r   z gaussian_kde._compute_covariance@  s    ,,..t_-- 	=$.s4<498<0F 0F 0F %G %GD! "(1F7;"= "= "=D /$+q.@*T[8@@LL*,'!B$--)8 !9 !9 : ::=#%%@rA   c                     |                                  | _        t          t          | j        dd| j                            | _        t          j        | j                  | j        dz  z  S )Nr   Fr   r   )	r   r   r   r   r    r)   r   r   invr   s    r2   inv_covzgaussian_kde.inv_covR  sj     ,,.. *3t|A05,N ,N ,N !O !Oz$/004;>AArA   c                 ,    |                      |          S )z
        Evaluate the estimated pdf on a provided set of points.

        Notes
        -----
        This is an alias for `gaussian_kde.evaluate`.  See the ``evaluate``
        docstring for more details.

        )r@   )r/   xs     r2   pdfzgaussian_kde.pdf^  s     }}QrA   c                    t          |          }|j        \  }}|| j        k    rG|dk    r%|| j        k    rt          || j        df          }d}nd| d| j         }t	          |          t          | j        |          \  }}t          |         | j        j	        | j
        dddf         |j	        | j        |          }|dddf         S )zT
        Evaluate the log of the estimated pdf on a provided set of points.
        r   r5   r6   Nr   )r   r#   r$   r   r"   r7   r8   r   r    r9   r)   r:   )	r/   r   r;   r$   r<   r0   r=   r>   r?   s	            r2   logpdfzgaussian_kde.logpdfj  s     A|1;;Avv!tv++ $&!559 9 9049 9 oo%.tGGd-d3LNDLD1HdlL2 2 aaad|rA   c                    t          j        |          }t          j        |j        t           j                  sd}t          |          t          | j                  }|                                }|||dk              z   ||dk     <   t          t          j	        |                    t          |          k    rd}t          |          |dk     ||k    z  }t          j
        |          rd||          d| d}t          |          | j        |         }| j        }t          ||                                 |          S )a)  Return a marginal KDE distribution

        Parameters
        ----------
        dimensions : int or 1-d array_like
            The dimensions of the multivariate distribution corresponding
            with the marginal variables, that is, the indices of the dimensions
            that are being retained. The other dimensions are marginalized out.

        Returns
        -------
        marginal_kde : gaussian_kde
            An object representing the marginal distribution.

        Notes
        -----
        .. versionadded:: 1.10.0

        zaElements of `dimensions` must be integers - the indices of the marginal variables being retained.r   z,All elements of `dimensions` must be unique.zDimensions z# are invalid for a distribution in z dimensions.)r   r)   )rH   r   
issubdtypedtypeintegerr"   r+   r    copyuniqueanyr)   r   r   )	r/   
dimensionsdimsr0   r%   original_dims	i_invalidr    r)   s	            r2   marginalzgaussian_kde.marginal  s=   * }Z((}TZ44 	"?CS//!		T$(^+TAXry3t99,,ACS//!AX$!),	6) 	"<y!9 < <,-< < <CS//!,t$,Gt/E/E/G/G$+- - - 	-rA   c                     	 | j         S # t          $ r+ t          | j                  | j        z  | _         | j         cY S w xY wr   )r(   AttributeErrorr   r%   r   s    r2   r)   zgaussian_kde.weights  sN    	!=  	! 	! 	! LL/DM=   	!s   	 2>>c                 ~    	 | j         S # t          $ r) dt          | j        dz            z  | _         | j         cY S w xY w)Nr   r   )r,   r   r   r)   r   s    r2   rs   zgaussian_kde.neff  sR    	: 	 	 	3t|Q///DJ:	s   	 0<<)NNr   )__name__
__module____qualname____doc__r3   r@   __call__rS   r\   rh   ro   r{   r   r   r   r-   r   propertyr   r   r   r   r)   rs   r   rA   r2   r   r   +   s       Z Zv$1 $1 $1 $1L& & &P H3 3 3j! ! !F   B0 0 0d! ! ! !F0 0 0A A A &! =# =# =# =#~@ @ @$ 	B 	B X	B
  
  
   0/- /- /-b ! ! X!   X  rA   c                     t          j        | |          }t          j        |          j        }|dk    rd}n$|dk    rd}n|dv rd}nt	          | d|           ||fS )z
    Calculates the output dtype and the "spec" (=C type name).

    This was necessary in order to deal with the fused types in the Cython
    routine `gaussian_kernel_estimate`. See gh-10824 for details.
    r~   r'      double)      zlong doublez has unexpected item size: )rH   common_typer   itemsizer"   )r8   r;   r=   r   r>   s        r2   r7   r7     s     >*f55Lx%%.H1}}	Q	X		FFHFF  	 rA   )#	threadingrb   scipyr   r   scipy._lib._utilr   numpyr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   rH    r   _statsr   r   __all__Lockr`   r   r7   r   rA   r2   <module>r      s  *      " ! ! ! ! ! ! ! / / / / / /                                              J J J J J J J J 
9>V
 V
 V
 V
 V
 V
 V
 V
r    rA   