Beispiel #1
0
    def _test_sample(self, kernel):
        kern = kernel()

        NUM = int(1e6)
        bw = 1.0
        pad = 4.0
        xe, xc, dx = kale.utils.bins(-pad * bw, pad * bw, 100)
        samp = kern.sample(NUM)

        hist, _ = np.histogram(samp, xe, density=True)
        pdf = kern.evaluate(xc)

        cum_pdf = utils.trapz_dens_to_mass(pdf, xc)
        cum_pdf = np.cumsum(cum_pdf)

        cum_pdf = np.append([0.0], cum_pdf)
        cdf = kern.cdf(xc)

        # Compare 'analytic' PDF/CDF with distribution of samples
        # CDF tend not to match as well, so use larger tolerance
        for aa, bb, name, tol in zip([hist, cum_pdf], [pdf, cdf],
                                     ['pdf', 'cdf'], [1e-2, 1e-1]):
            idx = (aa > 0.0) & (bb > 0.0)
            dof = np.count_nonzero(idx) - 1
            x2 = np.sum(np.square(aa[idx] - bb[idx]) / bb[idx]**2)
            x2 = x2 / dof

            print("Distribution: {} :: {} : x2/dof = {:.4e}".format(
                kern.name(), name, x2))
            print("\t" + kale.utils.array_str(aa[idx]))
            print("\t" + kale.utils.array_str(bb[idx]))
            utils.alltrue(x2 < tol)

        return
Beispiel #2
0
    def _test_evaluate(self, kernel):
        print(kernel)

        hh = 1.0
        edges = np.linspace(-4 * hh, 4 * hh, 10000)
        cents = kale.utils.midpoints(edges, 'lin')

        yy = kernel.evaluate(cents)
        # Make sure kernel is callable
        # tools.assert_true(np.allclose(yy, kernel().evaluate(cents)))

        # Make sure kernel is normalized
        tot = np.trapz(yy, cents)
        msg = "Kernel is {fail:} unitary"
        utils.allclose(tot, 1.0, rtol=1e-3, msg=msg)

        # Make sure kernels have expected support
        tools.assert_true(np.all(yy >= 0.0))
        if kernel._FINITE:
            outside = (cents < -hh) | (hh < cents)
            inside = (-hh < cents) & (cents < hh)
        else:
            outside = []
            inside = np.ones_like(yy, dtype=bool)

        utils.allclose(yy[outside], 0.0, rtol=1e-4, atol=1e-4)
        utils.alltrue(yy[inside] > 0.0)

        return
Beispiel #3
0
    def _test_ndim_a2(self, ndim):
        from kalepy import utils

        BIN_SIZE_RANGE = [10, 30]
        num_bins = np.random.randint(*BIN_SIZE_RANGE, ndim)

        edges = []
        for nb in num_bins:
            ee = np.cumsum(np.random.uniform(0.0, 2.0, nb))
            edges.append(ee)

        grid = np.meshgrid(*edges, indexing='ij')
        shp = np.array([len(ee) for ee in edges])

        for axis in np.ndindex(*([ndim] * 2)):
            if len(np.unique(axis)) != len(axis):
                continue

            axis = np.asarray(axis)
            not_axis = np.array(list(set(range(ndim)) - set(axis)))
            print("\nndim = {}, axis = {}, other = {}".format(
                ndim, axis, not_axis))

            bcast_norm = [np.newaxis for ii in range(ndim)]
            for na in not_axis:
                bcast_norm[na] = slice(None)

            bcast_norm = tuple(bcast_norm)
            norm = np.random.uniform(0.0, 10.0, shp[not_axis])[bcast_norm]

            widths = []
            for ii in range(ndim):
                dim_len_inn = shp[ii]
                if ii in axis:
                    wid = np.diff(edges[ii])
                else:
                    wid = np.ones(dim_len_inn)

                # Create new axes along all by the current dimension, slice along the current dimension
                cut = [np.newaxis for ii in range(ndim)]
                cut[ii] = slice(None)
                temp = wid[tuple(cut)]
                widths.append(temp)

            wids = np.product(np.array(widths, dtype=object),
                              axis=0).astype(float)

            pdf = np.ones_like(grid[0]) * norm
            pmf = utils.trapz_dens_to_mass(pdf, edges, axis=axis)

            new_shp = [ss for ss in shp]
            for aa in axis:
                new_shp[aa] -= 1

            utils.alltrue(
                np.shape(pmf) == np.array(new_shp),
                "Output shape is {fail:}correct")
            utils.alltrue(pmf == norm * wids, 'Values do {fail:}match')

        return
Beispiel #4
0
    def test_1d(self):
        aa = np.random.uniform(*[-100, 100], 1000)
        bounds = [-23, 43]
        print(aa)
        print(bounds)

        for out in [False, True]:
            idx = utils.bound_indices(aa, bounds, outside=out)
            test_yes = aa[idx]
            test_not = aa[~idx]
            print("\n", out, idx)

            for val, test in zip([out, not out], [test_yes, test_not]):
                if len(test) == 0:
                    continue

                outside = (test < bounds[0]) | (bounds[1] < test)
                inside = (bounds[0] < test) & (test < bounds[1])

                print("outside = {}, out = {}, val = {}".format(
                    np.all(outside), out, val))
                utils.alltrue(outside == val)

                print("inside  = {}, out = {}, val = {}".format(
                    np.all(inside), out, val))
                utils.alltrue(inside == (not val))

        return
Beispiel #5
0
    def _test_ndim_a1(self, ndim):
        from kalepy import utils

        BIN_SIZE_RANGE = [10, 30]
        num_bins = np.random.randint(*BIN_SIZE_RANGE, ndim)
        # num_bins = [3, 4]

        edges = []
        for nb in num_bins:
            ee = np.cumsum(np.random.uniform(0.0, 2.0, nb))
            edges.append(ee)

        grid = np.meshgrid(*edges, indexing='ij')
        shp = [len(ee) for ee in edges]

        for axis in range(ndim):
            not_axis = (axis + 1) % ndim
            print("\nndim = {}, axis = {}, other = {}".format(
                ndim, axis, not_axis))

            bcast_norm = [np.newaxis for ii in range(ndim)]
            bcast_norm[not_axis] = slice(None)
            bcast_norm = tuple(bcast_norm)
            norm = np.random.uniform(0.0, 10.0, shp[not_axis])[bcast_norm]

            bcast_wids = [np.newaxis for ii in range(ndim)]
            bcast_wids[axis] = slice(None)
            bcast_wids = tuple(bcast_wids)
            wids = np.diff(edges[axis])[bcast_wids]

            pdf = np.ones_like(grid[0]) * norm
            pmf = utils.trapz_dens_to_mass(pdf, edges, axis=axis)

            new_shp = [ss for ss in shp]
            new_shp[axis] -= 1
            utils.alltrue(
                np.shape(pmf) == np.array(new_shp),
                "Output shape is {fail:}correct")

            utils.alltrue(pmf == norm * wids, 'Values do {fail:}match')

            # print(pdf)
            # print(wids)
            # print(pmf)

        return
Beispiel #6
0
    def test_parse(self):
        from kalepy.kernels import Distribution

        ndim_max = 5
        for ndim in range(ndim_max):
            # Use `ndim` to make sure that a scalar (non-array) is valid, but this still counts
            # as a "one-dimensional" value (i.e. a single-variate distribution), so set ndim=1
            if ndim == 0:
                xx = 0.5
                ndim = 1
            else:
                nvals = np.random.randint(2, 10)
                # Squeeze this array to test that (N,) will be expanded to (1, N)
                xx = np.random.uniform(-10.0, 10.0,
                                       nvals * ndim).reshape(ndim,
                                                             nvals).squeeze()

            yy, _ndim, squeeze = Distribution._parse(xx)
            # Make sure number of dimensions are accurate
            utils.alltrue(_ndim == ndim)
            # Squeeze should be true for less than 2D
            utils.alltrue(squeeze == (ndim < 2))
            # Make sure values are the same, but 2d
            utils.allclose(yy, xx)
            utils.alltrue(np.ndim(yy) == 2)

        return
Beispiel #7
0
    def _test_evaluate(self, kernel):
        print("\n|Test_Kernels_Generic:_test_evaluate()|")
        print(kernel)

        # bandwidth should always be scaled to 1.0
        # yy, ndim, nval, squeeze = kernel.scale(hh, 0.0, hh)
        # tools.assert_true(np.isclose(yy, 1.0))
        # tools.assert_true(ndim == 1)
        # tools.assert_true(nval == 1)

        hh = 1.0
        edges = np.linspace(-10 * hh, 10 * hh, 10000)
        cents = kale.utils.midpoints(edges, 'lin')
        # width = np.diff(edges)
        yy = kernel.evaluate(cents[np.newaxis, :], 1).squeeze()
        # Make sure kernel is callable
        # tools.assert_true(np.allclose(yy, kernel().evaluate(cents)))

        # Make sure kernel is normalized
        # tot = np.sum(yy*width)
        tot = np.trapz(yy, cents)
        # print("\t\ttot = {:.4e}".format(tot))
        tools.assert_almost_equal(tot, 1.0, delta=1e-3)

        # Make sure kernels have expected support
        tools.assert_true(np.all(yy >= 0.0))
        if kernel._FINITE:
            outside = (cents < -hh) | (hh < cents)
            inside = (-hh < cents) & (cents < hh)
        else:
            outside = []
            inside = np.ones_like(yy, dtype=bool)

        utils.allclose(yy[outside], 0.0, rtol=1e-4, atol=1e-4)
        utils.alltrue(yy[inside] > 0.0)

        return