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
def test_axis(self): """With axis given, this just needs to match `numpy.cumsum` results. """ # Start with a known input and output test = [[1, 2, 3, 4], [0, 2, 1, 2], [3, 1, 0, 0]] chk_a1 = [[1, 3, 6, 10], [0, 2, 3, 5], [3, 4, 4, 4]] chk_a0 = [[1, 2, 3, 4], [1, 4, 4, 6], [4, 5, 4, 6]] checks = [chk_a0, chk_a1] print("input = \n", test) for aa, chk in enumerate(checks): print("---- axis=", aa) res = utils.cumsum(test, axis=aa) chk_np = np.cumsum(test, axis=aa) print("output = \n", res) print("numpy truth = \n", chk_np) msg = "`cumsum` does {{fail:}}match numpy result along axis={}".format( aa) utils.allclose(res, chk_np, rtol=1e-10, msg=msg) print("output = \n", res) print("brute-force truth = \n", chk) msg = "`cumsum` does {{fail:}}match known result along axis={}".format( aa) utils.allclose(res, chk, rtol=1e-10, msg=msg) for nd in range(1, 5): for ax in range(nd): self._test_axis_ndim(nd, ax) return
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
def test_2d(self): print("\n|Test_Trapz:test_2d()|") from kalepy import utils extr = [sorted(np.random.uniform(-10, 10, 2)) for ii in range(2)] edges = [np.linspace(*ex, 100) for ex in extr] grid = np.meshgrid(*edges, indexing='ij') shp = np.shape(grid[0]) vals = np.random.uniform(0.0, 1.0, size=shp) test = utils.trapz_nd(vals, edges) def sum_corner(ii, jj): area = np.diff(edges[0]) * np.diff(edges[1]) temp = area * vals[ii, jj] return np.sum(temp) tot = 0.0 for ii in range(2): for jj in range(2): cuts = [] for kk in [ii, jj]: if kk == 0: cuts.append(slice(None, -1, None)) else: cuts.append(slice(1, None, None)) tot += sum_corner(*cuts) * 0.25 print("test = {}, tot = {}".format(test, tot)) utils.allclose(test, tot) return
def test_1d(self): print("\n|Test_Trapz:test_1d()|") from kalepy import utils extr = sorted(np.random.uniform(-10, 10, 2)) xx = np.linspace(*extr, 1000) yy = np.random.uniform(0.0, 1.0, xx.size) np_trapz = np.trapz(yy, xx) test = utils.trapz_nd(yy, xx) utils.allclose(test, np_trapz) return
def test_no_axis(self): # Start with a known input and output test = [[1, 2, 3, 4], [0, 2, 1, 2], [3, 1, 0, 0]] check = [[1, 3, 6, 10], [1, 5, 9, 15], [4, 9, 13, 19]] res = utils.cumsum(test) print("input = \n", test) print("output = \n", res) print("brute-force truth = \n", check) utils.allclose(res, check, rtol=1e-10, msg="`cumsum` does {fail:}match known result") for nd in range(1, 5): self._test_no_axis_ndim(nd) return
def _test_dim(dim, num=1e7): from kalepy import utils num_per_dim = int(np.power(num, 1 / dim)) norm = np.random.normal(10.0, 1.0) extr = [sorted(np.random.uniform(-10, 10, 2)) for ii in range(dim)] edges = [np.linspace(*ex, num_per_dim) for ex in extr] shp = [len(ed) for ed in edges] vals = norm * np.ones(shp) tot = utils.trapz_nd(vals, edges) truth = np.product(np.diff(extr, axis=-1)) * norm print("\t{:.4e} vs {:.4e}".format(tot, truth)) utils.allclose(tot, truth) return
def _test_ndim(self, ndim): from kalepy import utils print("`ndim` = {}".format(ndim)) BIN_SIZE_RANGE = [10, 30] extr = [[0.0, np.random.uniform(0.0, 2.0)] for ii in range(ndim)] norm = np.random.uniform(0.0, 10.0) # extr = [[0.0, 1.0] for ii in range(ndim)] # norm = 1.0 edges = [ np.linspace(*ex, np.random.randint(*BIN_SIZE_RANGE)) for ex in extr ] grid = np.meshgrid(*edges, indexing='ij') lengths = np.max(extr, axis=-1) xx = np.min(np.moveaxis(grid, 0, -1) / lengths, axis=-1) pdf = norm * xx area = np.product(lengths) pmf = utils.trapz_dens_to_mass(pdf, edges) # Known area of a pyramid in ndim vol = area * norm / (ndim + 1) tot = np.sum(pmf) print("Volume = {:.4e}, Total Mass = {:.4e}; ratio = {:.4e}".format( vol, tot, tot / vol)) utils.allclose(vol, tot, rtol=1e-2, msg="total volume does {fail:}match analytic value") test = utils.trapz_nd(pdf, edges) print("Volume = {:.4e}, Total Mass = {:.4e}; ratio = {:.4e}".format( test, tot, tot / test)) utils.allclose(vol, tot, rtol=1e-2, msg="total volume does {fail:}match `trapz_nd` value") return
def _test_no_axis_ndim(self, ndim): """Test cumsum over all axes (i.e. "no" axis given) for a `ndim` array """ # Construct a random shape in `ndim` dimensions shape = np.random.randint(2, 7, ndim) # Fill with random values vals = np.random.uniform(-20.0, 20.0, shape) # Get the `cumsum` result res = utils.cumsum(vals) # Get the brute-force result for comparison chk = self._brute_force_cumsum(vals) # Make sure they match print("input = \n", vals) print("output = \n", res) print("brute-force truth = \n", chk) msg = "cumsum ndim={} does {{fail:}}match brute-force values.".format( ndim) utils.allclose(res, chk, rtol=1e-10, msg=msg) return
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