def benchmark_maxradius(): print(" ndim | npts | duration") for ndim in 2, 4, 8, 16, 32, 64: plotpoints = [] np.random.seed(ndim) for npts in 100, 400, 1000, 4000: points = np.random.uniform(size=(npts, ndim)) transformLayer = ScalingLayer() region = MLFriends(points, transformLayer) niter = 0 total_duration = 0 while total_duration < 1: start = time.time() maxr = region.compute_maxradiussq(nbootstraps=20) total_duration += time.time() - start niter += 1 print('%5d | %5d | %.2fms val=%f' % (ndim, npts, total_duration * 1000 / niter, maxr)) plotpoints.append((npts, total_duration * 1000 / niter / npts**2)) plt.plot(*zip(*plotpoints), label='ndim=%d' % ndim) plt.xlabel('Number of live points') plt.ylabel('Duration [ms] / nlive$^2$') plt.yscale('log') plt.xscale('log') plt.legend(loc='best', prop=dict(size=10)) plt.savefig('testmaxradius.pdf', bbox_inches='tight') plt.close()
def test_aharm_sampler(): def loglike(theta): return -0.5 * (((theta - 0.5) / 0.01)**2).sum(axis=1) def transform(x): return x seed = 1 Nlive = 10 np.random.seed(seed) us = np.random.uniform(size=(Nlive, 2)) Ls = loglike(us) Lmin = Ls.min() transformLayer = ScalingLayer() region = MLFriends(us, transformLayer) region.maxradiussq, region.enlarge = region.compute_enlargement() region.create_ellipsoid() assert region.inside(us).all() nsteps = 10 sampler = AHARMSampler(nsteps=nsteps, region_filter=True) nfunccalls = 0 ncalls = 0 while True: u, p, L, nc = sampler.__next__(region, Lmin, us, Ls, transform, loglike) nfunccalls += 1 ncalls += nc if u is not None: break if nfunccalls > 100 + nsteps: assert False, ('infinite loop?', seed, nsteps, Nlive) print("done in %d function calls, %d likelihood evals" % (nfunccalls, ncalls))
def test_transform(): np.random.seed(1) corrs = np.arange(-1, 1, 0.1) corrs *= 0.999 for corr in corrs: for scaleratio in [1, 0.001]: covmatrix = np.array([[1., corr], [corr, 1.]]) points = np.random.multivariate_normal(np.zeros(2), covmatrix, size=1000) print(corr, scaleratio, covmatrix.flatten(), points.shape) points[:, 0] = points[:, 0] * 0.01 * scaleratio + 0.5 points[:, 1] = points[:, 1] * 0.01 + 0.5 layer = ScalingLayer() layer.optimize(points, points) tpoints = layer.transform(points) assert tpoints.shape == points.shape, (tpoints.shape, points.shape) points2 = layer.untransform(tpoints) assert tpoints.shape == points2.shape, (tpoints.shape, points2.shape) assert (points2 == points).all(), (points, tpoints, points2) # transform a single point points = points[0] tpoints = layer.transform(points) assert tpoints.shape == points.shape, (tpoints.shape, points.shape) points2 = layer.untransform(tpoints) assert tpoints.shape == points2.shape, (tpoints.shape, points2.shape) assert (points2 == points).all(), (points, tpoints, points2)
def run_aharm_sampler(): for seed in [733] + list(range(10)): print() print("SEED=%d" % seed) print() np.random.seed(seed) nsteps = max(1, int(10**np.random.uniform(0, 3))) Nlive = int(10**np.random.uniform(1.5, 3)) print("Nlive=%d nsteps=%d" % (Nlive, nsteps)) sampler = AHARMSampler(nsteps, adaptive_nsteps=False, region_filter=False) us = np.random.uniform(0.6, 0.8, size=(4000, 2)) Ls = loglike_vectorized(us) i = np.argsort(Ls)[-Nlive:] us = us[i,:] Ls = Ls[i] Lmin = Ls.min() transformLayer = ScalingLayer() transformLayer.optimize(us, us) region = MLFriends(us, transformLayer) region.maxradiussq, region.enlarge = region.compute_enlargement() region.create_ellipsoid() nfunccalls = 0 ncalls = 0 while True: u, p, L, nc = sampler.__next__(region, Lmin, us, Ls, transform, loglike) nfunccalls += 1 ncalls += nc if u is not None: break if nfunccalls > 100 + nsteps: assert False, ('infinite loop?', seed, nsteps, Nlive) print("done in %d function calls, %d likelihood evals" % (nfunccalls, ncalls))
def prepare_problem(problemname, ndim, nlive, sampler): loglike, grad, volume, warmup = get_problem(problemname, ndim=ndim) if hasattr(sampler, 'set_gradient'): sampler.set_gradient(grad) np.random.seed(1) us = np.random.uniform(size=(nlive, ndim)) if ndim > 1: transformLayer = AffineLayer() else: transformLayer = ScalingLayer() transformLayer.optimize(us, us) region = MLFriends(us, transformLayer) region.maxradiussq, region.enlarge = region.compute_enlargement( nbootstraps=30) region.create_ellipsoid(minvol=1.0) Ls = np.array([loglike(u) for u in us]) ncalls = 0 nok = 0 i = 0 while True: if i % int(nlive * 0.2) == 0: minvol = (1 - 1. / nlive)**i nextTransformLayer = transformLayer.create_new(us, region.maxradiussq, minvol=minvol) nextregion = MLFriends(us, nextTransformLayer) nextregion.maxradiussq, nextregion.enlarge = nextregion.compute_enlargement( nbootstraps=30) if nextregion.estimate_volume() <= region.estimate_volume(): region = nextregion transformLayer = region.transformLayer region.create_ellipsoid(minvol=minvol) # replace lowest likelihood point j = np.argmin(Ls) Lmin = float(Ls[j]) while True: u, v, logl, nc = sampler.__next__(region, Lmin, us, Ls, transform, loglike) ncalls += nc if logl is not None: break us[j, :] = u region.u[j, :] = u region.unormed[j, :] = region.transformLayer.transform(u) Ls[j] = logl i = i + 1 #print(i, Lmin, volume(Lmin, ndim)) if np.isfinite(volume(Lmin, ndim)): nok += 1 if nok > 2 * nlive + 1000: break return region, i, Lmin, us, Ls, transform, loglike
def test_ellipsoid_bracket(plot=False): for seed in range(20): print("seed:", seed) np.random.seed(seed) if seed % 2 == 0: us = np.random.normal(size=(2**np.random.randint(3, 10), 2)) us /= ((us**2).sum(axis=1)**0.5).reshape((-1, 1)) us = us * 0.1 + 0.5 else: us = np.random.uniform(size=(2**np.random.randint(3, 10), 2)) if plot: import matplotlib.pyplot as plt plt.plot(us[:, 0], us[:, 1], 'o ', ms=2) transformLayer = ScalingLayer() region = MLFriends(us, transformLayer) try: region.maxradiussq, region.enlarge = region.compute_enlargement() region.create_ellipsoid() except ValueError: continue print(region.ellipsoid_center) print(region.enlarge) print(region.ellipsoid_cov) print(region.ellipsoid_invcov) print(region.ellipsoid_axes) print(region.ellipsoid_inv_axes) ucurrent = np.array([2**0.5 * 0.1 / 2 + 0.5, 2**0.5 * 0.1 / 2 + 0.5]) ucurrent = np.array([0.4, 0.525]) v = np.array([1., 0]) if plot: plt.plot(ucurrent[0], ucurrent[1], 'o') print("from", ucurrent, "in direction", v) left, right = ellipsoid_bracket(ucurrent, v, region.ellipsoid_center, region.ellipsoid_inv_axes, region.enlarge) uleft = ucurrent + v * left uright = ucurrent + v * right if plot: plt.plot([uleft[0], uright[0]], [uleft[1], uright[1]], 'x-') plt.savefig('test_ellipsoid_bracket.pdf', bbox_inches='tight') plt.close() print("ellipsoid bracket:", left, right) assert left <= 0, left assert right >= 0, right assert_point_touches_ellipsoid(ucurrent, v, left, region.ellipsoid_center, region.ellipsoid_invcov, region.enlarge) assert_point_touches_ellipsoid(ucurrent, v, right, region.ellipsoid_center, region.ellipsoid_invcov, region.enlarge)
def make_region(ndim): us = np.random.uniform(size=(1000, ndim)) if ndim > 1: transformLayer = AffineLayer() else: transformLayer = ScalingLayer() transformLayer.optimize(us, us) region = MLFriends(us, transformLayer) region.maxradiussq, region.enlarge = region.compute_enlargement( nbootstraps=30) region.create_ellipsoid(minvol=1.0) return region
def test_region_sampling_scaling(plot=False): np.random.seed(1) upoints = np.random.uniform(0.2, 0.5, size=(1000, 2)) upoints[:, 1] *= 0.1 transformLayer = ScalingLayer(wrapped_dims=[]) transformLayer.optimize(upoints, upoints) region = MLFriends(upoints, transformLayer) region.maxradiussq, region.enlarge = region.compute_enlargement( nbootstraps=30) print("enlargement factor:", region.enlarge, 1 / region.enlarge) region.create_ellipsoid() nclusters = transformLayer.nclusters assert nclusters == 1 assert np.allclose(region.unormed, region.transformLayer.transform( upoints)), "transform should be reproducible" assert region.inside( upoints).all(), "live points should lie near live points" if plot: plt.plot(upoints[:, 0], upoints[:, 1], 'x ') for method in region.sampling_methods: points, nc = method(nsamples=400) plt.plot(points[:, 0], points[:, 1], 'o ', label=str(method.__name__)) plt.legend(loc='best') plt.savefig('test_regionsampling_scaling.pdf', bbox_inches='tight') plt.close() for method in region.sampling_methods: print("sampling_method:", method) newpoints = method(nsamples=4000) lo1, lo2 = newpoints.min(axis=0) hi1, hi2 = newpoints.max(axis=0) assert 0.15 < lo1 < 0.25, (method.__name__, newpoints, lo1, hi1, lo2, hi2) assert 0.015 < lo2 < 0.025, (method.__name__, newpoints, lo1, hi1, lo2, hi2) assert 0.45 < hi1 < 0.55, (method.__name__, newpoints, lo1, hi1, lo2, hi2) assert 0.045 < hi2 < 0.055, (method.__name__, newpoints, lo1, hi1, lo2, hi2) assert region.inside(newpoints).mean() > 0.99, region.inside( newpoints).mean() region.maxradiussq = 1e-90 assert np.allclose(region.unormed, region.transformLayer.transform( upoints)), "transform should be reproducible" assert region.inside( upoints).all(), "live points should lie very near themselves"
def test_clusteringcase_eggbox(): from ultranest.mlfriends import update_clusters, ScalingLayer, MLFriends points = np.loadtxt(os.path.join(here, "eggboxregion.txt")) transformLayer = ScalingLayer() transformLayer.optimize(points, points) region = MLFriends(points, transformLayer) maxr = region.compute_maxradiussq(nbootstraps=30) assert 1e-10 < maxr < 5e-10 print('maxradius:', maxr) nclusters, clusteridxs, overlapped_points = update_clusters( points, points, maxr) # plt.title('nclusters: %d' % nclusters) # for i in np.unique(clusteridxs): # x, y = points[clusteridxs == i].transpose() # plt.scatter(x, y) # plt.savefig('testclustering_eggbox.pdf', bbox_inches='tight') # plt.close() assert 14 < nclusters < 20, nclusters
def test_wrap(plot=False): np.random.seed(1) for Npoints in 10, 100, 1000: for wrapids in [[], [0], [1], [0, 1]]: print("Npoints=%d wrapped_dims=%s" % (Npoints, wrapids)) #wrapids = np.array(wrapids) points = np.random.normal(0.5, 0.01, size=(Npoints, 2)) for wrapi in wrapids: points[:, wrapi] = np.fmod(points[:, wrapi] + 0.5, 1) assert (points > 0).all(), points assert (points < 1).all(), points layer = ScalingLayer(wrapped_dims=wrapids) layer.optimize(points, points) tpoints = layer.transform(points) assert tpoints.shape == points.shape, (tpoints.shape, points.shape) points2 = layer.untransform(tpoints) assert tpoints.shape == points2.shape, (tpoints.shape, points2.shape) if plot: plt.subplot(1, 2, 1) plt.scatter(points[:, 0], points[:, 1]) plt.scatter(points2[:, 0], points2[:, 1], marker='x') plt.subplot(1, 2, 2) plt.scatter(tpoints[:, 0], tpoints[:, 1]) plt.savefig("testtransform_%d_wrap%d.pdf" % (Npoints, len(wrapids)), bbox_inches='tight') plt.close() assert np.allclose(points2, points), (points, tpoints, points2) layer = AffineLayer(wrapped_dims=wrapids) layer.optimize(points, points) tpoints = layer.transform(points) assert tpoints.shape == points.shape, (tpoints.shape, points.shape) points2 = layer.untransform(tpoints) assert tpoints.shape == points2.shape, (tpoints.shape, points2.shape)
def test_overclustering_eggbox_txt(): from ultranest.mlfriends import update_clusters, ScalingLayer, MLFriends np.random.seed(1) for i in [20, 23, 24, 27, 49]: print() print("==== TEST CASE %d =====================" % i) print() points = np.loadtxt(os.path.join(here, "overclustered_u_%d.txt" % i)) for k in range(3): transformLayer = ScalingLayer(wrapped_dims=[]) transformLayer.optimize(points, points) region = MLFriends(points, transformLayer) maxr = region.compute_maxradiussq(nbootstraps=30) region.maxradiussq = maxr nclusters = transformLayer.nclusters print("manual: r=%e nc=%d" % (region.maxradiussq, nclusters)) # assert 1e-10 < maxr < 5e-10 nclusters, clusteridxs, overlapped_points = update_clusters( points, points, maxr) print("reclustered: nc=%d" % (nclusters)) if False: plt.title('nclusters: %d' % nclusters) for k in np.unique(clusteridxs): x, y = points[clusteridxs == k].transpose() plt.scatter(x, y) plt.savefig('testoverclustering_eggbox_%d.pdf' % i, bbox_inches='tight') plt.close() assert 14 < nclusters < 20, (nclusters, i) for j in range(3): nclusters, clusteridxs, overlapped_points = update_clusters( points, points, maxr) assert 14 < nclusters < 20, (nclusters, i)
def evaluate_warmed_sampler(problemname, ndim, nlive, nsteps, sampler, seed=1, region_class=RobustEllipsoidRegion): loglike, grad, volume, warmup = get_problem(problemname, ndim=ndim) if hasattr(sampler, 'set_gradient'): sampler.set_gradient(grad) np.random.seed(seed) def multi_loglike(xs): return np.asarray([loglike(x) for x in xs]) us = np.array([warmup(ndim) for i in range(nlive)]) Ls = np.array([loglike(u) for u in us]) vol0 = volume(Ls.min(), ndim) nwarmup = 3 * nlive if ndim > 1: transformLayer = AffineLayer() else: transformLayer = ScalingLayer() transformLayer.optimize(us, us) region = region_class(us, transformLayer) region.maxradiussq, region.enlarge = region.compute_enlargement( nbootstraps=30) region.create_ellipsoid(minvol=vol0) assert region.ellipsoid_center is not None sampler.region_changed(Ls, region) Lsequence = [] stepsequence = [] ncalls = 0 for i in tqdm.trange(nsteps + nwarmup): if i % int(nlive * 0.2) == 0: minvol = (1 - 1. / nlive)**i * vol0 with warnings.catch_warnings(), np.errstate(all='raise'): try: nextTransformLayer = transformLayer.create_new( us, region.maxradiussq, minvol=minvol) nextregion = region_class(us, nextTransformLayer) nextregion.maxradiussq, nextregion.enlarge = nextregion.compute_enlargement( nbootstraps=30) if isinstance(nextregion, RobustEllipsoidRegion ) or nextregion.estimate_volume( ) <= region.estimate_volume(): nextregion.create_ellipsoid(minvol=minvol) region = nextregion transformLayer = region.transformLayer assert region.ellipsoid_center is not None sampler.region_changed(Ls, region) except Warning as w: print("not updating region because: %s" % w) except FloatingPointError as e: print("not updating region because: %s" % e) except np.linalg.LinAlgError as e: print("not updating region because: %s" % e) # replace lowest likelihood point j = np.argmin(Ls) Lmin = float(Ls[j]) while True: u, v, logl, nc = sampler.__next__(region, Lmin, us, Ls, transform, multi_loglike) if i > nwarmup: ncalls += nc if logl is not None: assert np.isfinite(u).all(), u assert np.isfinite(v).all(), v assert np.isfinite(logl), logl break if i > nwarmup: Lsequence.append(Lmin) stepsequence.append(quantify_step(us[sampler.starti, :], u)) us[j, :] = u Ls[j] = logl Lsequence = np.asarray(Lsequence) return Lsequence, ncalls, np.array(stepsequence)
def benchmark_transform(): npts = 400 for layer in 'scale', 'affine': print(" ndim | duration [%s]" % layer) tplotpoints = [] rplotpoints = [] nplotpoints = [] for ndim in 2, 4, 8, 16, 32, 64, 128, 256, : np.random.seed(ndim) points = np.random.uniform(0.4, 0.6, size=(npts, ndim)) transformLayer = ScalingLayer( ) if layer == 'scale' else AffineLayer() region = MLFriends(points, transformLayer) region.maxradiussq, region.enlarge = region.compute_enlargement( nbootstraps=30) region.create_ellipsoid() niter = 0 total_duration = 0 while total_duration < .1: start = time.time() u = region.transformLayer.untransform( np.random.normal(size=(ndim))) region.transformLayer.transform(u) total_duration += time.time() - start niter += 1 print('%5d | %.2fms ' % (ndim, total_duration * 1000 / niter)) tplotpoints.append((ndim, total_duration * 1000 / niter)) niter = 0 total_duration = 0 while total_duration < .1: u = np.random.normal(0.5, 0.1, size=(10, ndim)) start = time.time() region.inside(u) total_duration += time.time() - start niter += 1 print('%5d | %.2fms ' % (ndim, total_duration * 1000 / niter)) rplotpoints.append((ndim, total_duration * 1000 / niter)) niter = 0 total_duration = 0 while total_duration < .1: u = np.random.normal(0.5, 0.1, size=(10, ndim)) start = time.time() array = np.empty((10), dtype=int) array[:] = -1 array = np.empty((10), dtype=int) array[:] = -1 array = np.empty((10), dtype=int) array[:] = -1 total_duration += time.time() - start niter += 1 print('%5d | %.2fms ' % (ndim, total_duration * 1000 / niter)) nplotpoints.append((ndim, total_duration * 1000 / niter)) plt.plot(*zip(*tplotpoints), label=layer + ' transform') plt.plot(*zip(*rplotpoints), label=layer + ' region.inside') plt.plot(*zip(*nplotpoints), label=layer + ' array') plt.xlabel('Number of dimensions') plt.ylabel('Duration [ms]') plt.yscale('log') plt.xscale('log') plt.legend(loc='best', prop=dict(size=10)) plt.savefig('testtransform.pdf', bbox_inches='tight') plt.close()