Example #1
0
    def cdf_grid(self):
        if self._cdf_grid is None:
            if self._FINITE:
                pad = (1 + _NUM_PAD)
                args = [-pad, pad]
            else:
                args = [-6, 6]

            num = np.diff(args)[0] * _INTERP_NUM_PER_STD
            args = args + [int(num), ]

            xc = np.linspace(*args)
            if self._CDF_INTERP:
                yy = self.evaluate(xc)
                csum = utils.cumtrapz(yy, xc, prepend=False)
            else:
                csum = self.cdf(xc)

            norm = csum[-1]
            if not np.isclose(norm, 1.0, rtol=1e-5):
                err = "Failed to reach unitarity in CDF grid norm: {:.4e}!".format(norm)
                raise ValueError(err)

            # csum = csum / norm
            # xc = np.concatenate([[args[0]], [args[0]], xc, [args[1]], [args[1]]], axis=0)
            # csum = np.concatenate([[0.0 - _NUM_PAD], [0.0], csum, [1.0], [1.0+_NUM_PAD]], axis=0)
            self._cdf_grid = [xc, csum]

        return self._cdf_grid
Example #2
0
    def cdf(self, pnts, params=None, reflect=None):
        """Cumulative Distribution Function based on KDE smoothed data.

        Arguments
        ---------
        pnts : ([D,]N,) array_like of scalar
            Target evaluation points

        Returns
        -------
        cdf : (N,) ndarray of scalar
            CDF Values at the target points

        """
        if params is not None:
            raise NotImplementedError(
                "`params` is not yet implemented for CDF!")

        if reflect is not None:
            raise NotImplementedError(
                "`reflect` is not yet implemented for CDF!")

        if self._cdf_func is None:
            points = self.points

            # Calculate PDF at grid locations
            pdf = self.pdf(points, grid=True)[1]
            # Convert to CDF using trapezoid rule
            cdf = utils.cumtrapz(pdf, points)
            # Normalize to the maximum value
            cdf /= cdf.max()

            ndim = np.ndim(cdf)
            # points = np.atleast_2d(points)
            if ndim == 1 and np.ndim(points) == 1:
                points = np.atleast_2d(points)

            self._cdf_grid = (points, cdf)
            self._cdf_func = sp.interpolate.RegularGridInterpolator(
                *self._cdf_grid, bounds_error=False, fill_value=None)

        # `scipy.interplate.RegularGridInterpolator` expects shape (N,D,) -- so transpose
        pnts = np.asarray(pnts).T
        cdf = self._cdf_func(pnts)
        return cdf