示例#1
0
def test_region_mean_distances():
    np.random.seed(1)
    points = np.random.uniform(0.4, 0.6, size=(10000, 2))
    #points[:,1] *= 0.5
    mask = np.abs((points[:, 0] - 0.5)**2 +
                  (points[:, 1] - 0.5)**2 - 0.08**2) < 0.02**2
    print('circle:', mask.sum())
    points = points[mask]
    mask = points[:, 0] < 0.5
    print('half-circle:', mask.sum())
    points = points[mask]

    transformLayer = AffineLayer(wrapped_dims=[])
    transformLayer.optimize(points, points)
    region = MLFriends(points, transformLayer)
    region.maxradiussq, region.enlarge = region.compute_enlargement(
        nbootstraps=30)
    print("enlargement factor:", region.enlarge, 1 / region.enlarge)
    region.create_ellipsoid()
    meandist = region.compute_mean_pair_distance()

    t = transformLayer.transform(region.u)
    d = 0
    N = 0
    for i in range(len(t)):
        for j in range(i):
            d += ((t[i, :] - t[j, :])**2).sum()**0.5
            #print(i, j, t[i,:], t[j,:], ((t[i,:] - t[j,:])**2).sum())
            N += 1

    print((meandist, d, N, t))
    assert np.isclose(meandist, d / N), (meandist, d, N)
示例#2
0
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
示例#3
0
def test_affine_transform(plot=False):
    np.random.seed(1)
    corrs = [0, 0.6, 0.95, 0.999]
    for corr in corrs:
        for scaleratio in [1]:  #, 0.001]:
            covmatrix = np.array([[1., corr], [corr, 1.]])
            # should draw uniformly sampled points
            points = genpoints_following_cov(covmatrix, size=400)
            print('settings: corr:', corr, 'scaleratio:', scaleratio,
                  'covmatrix:', covmatrix.flatten(), points.shape)
            points[:, 0] = points[:, 0] * 0.01 * scaleratio + 0.5
            points[:, 1] = points[:, 1] * 0.01 + 0.5

            layer = AffineLayer()
            layer.optimize(points, points)
            points3 = layer.untransform(
                genpoints_following_cov(np.diag([1, 1]), size=400))
            #print('cov:', layer.cov, 'covmatrix:', covmatrix, 'ratio:', layer.cov / covmatrix)
            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 and scaleratio == 1:
                plt.figure(figsize=(9, 4))
                plt.subplot(1, 2, 1)
                plt.scatter(points[:, 0], points[:, 1])
                plt.scatter(points2[:, 0], points2[:, 1], marker='x')
                plt.scatter(points3[:, 0], points3[:, 1], marker='+')
                plt.subplot(1, 2, 2)
                plt.scatter(tpoints[:, 0], tpoints[:, 1])
                lo, hi = plt.xlim()
                lo2, hi2 = plt.ylim()
                lo, hi = min(lo, lo2), max(hi, hi2)
                plt.xlim(lo, hi)
                plt.ylim(lo, hi)
                plt.savefig("testtransform_affine_corr%s_scale%s.pdf" %
                            (corr, scaleratio),
                            bbox_inches='tight')
                plt.close()
            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)
示例#4
0
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
示例#5
0
def test_ellipsoids():
    tpoints = np.random.uniform(0.4, 0.6, size=(1000, 1))
    tregion = WrappingEllipsoid(tpoints)
    print(tregion.variable_dims)
    tregion.enlarge = tregion.compute_enlargement(nbootstraps=30)
    tregion.create_ellipsoid()

    for umax in 0.6, 0.5:
        print()
        print(umax)
        points = np.random.uniform(0.4, 0.6, size=(1000, 3))
        points = points[points[:, 0] < umax]
        tpoints = points * 10
        tpoints[:, 0] = np.floor(tpoints[:, 0])
        print(points, tpoints)

        transformLayer = AffineLayer(wrapped_dims=[])
        transformLayer.optimize(points, points)

        region = MLFriends(points, transformLayer)
        region.maxradiussq, region.enlarge = region.compute_enlargement(
            nbootstraps=30)
        region.create_ellipsoid()
        inside = region.inside(points)
        assert inside.shape == (len(points), ), (inside.shape, points.shape)
        assert inside.all()

        region = RobustEllipsoidRegion(points, transformLayer)
        region.maxradiussq, region.enlarge = region.compute_enlargement(
            nbootstraps=30)
        region.create_ellipsoid()
        inside = region.inside(points)
        assert inside.shape == (len(points), ), (inside.shape, points.shape)
        assert inside.all()

        region = SimpleRegion(points, transformLayer)
        region.maxradiussq, region.enlarge = region.compute_enlargement(
            nbootstraps=30)
        region.create_ellipsoid()
        inside = region.inside(points)
        assert inside.shape == (len(points), ), (inside.shape, points.shape)
        assert inside.all()

        tregion = WrappingEllipsoid(tpoints)
        print(tregion.variable_dims)
        tregion.enlarge = tregion.compute_enlargement(nbootstraps=30)
        tregion.create_ellipsoid()
        inside = tregion.inside(tpoints)
        assert inside.shape == (len(tpoints), ), (inside.shape, tpoints.shape)
        assert inside.all()
示例#6
0
def test_region_sampling_affine(plot=False):
    np.random.seed(1)
    upoints = np.random.uniform(size=(1000, 2))
    upoints[:, 1] *= 0.5

    transformLayer = AffineLayer(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_affine.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 <= lo1 < 0.1, (method.__name__, newpoints, lo1, hi1, lo2, hi2)
        assert 0 <= lo2 < 0.1, (method.__name__, newpoints, lo1, hi1, lo2, hi2)
        assert 0.95 < hi1 <= 1, (method.__name__, newpoints, lo1, hi1, lo2,
                                 hi2)
        assert 0.45 <= hi2 < 0.55, (method.__name__, newpoints, lo1, hi1, lo2,
                                    hi2)
        assert region.inside(newpoints).all()

    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"
示例#7
0
def test_region_ellipsoid(plot=False):
    np.random.seed(1)
    points = np.random.uniform(0.4, 0.6, size=(1000, 2))
    points[:, 1] *= 0.5

    transformLayer = AffineLayer(wrapped_dims=[])
    transformLayer.optimize(points, points)
    region = MLFriends(points, 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

    bpts = np.random.uniform(size=(100, 2))
    mask = region.inside_ellipsoid(bpts)

    d = (bpts - region.ellipsoid_center)
    mask2 = np.einsum('ij,jk,ik->i', d, region.ellipsoid_invcov,
                      d) <= region.enlarge

    assert_allclose(mask, mask2)
示例#8
0
def test_reversible_gradient(plot=False):
    def loglike(x):
        x, y = x.transpose()
        return -0.5 * (x**2 + ((y - 0.5) / 0.2)**2)

    def transform(u):
        return u

    Lmin = -0.5

    for i in [84] + list(range(1, 100)):
        print("setting seed = %d" % i)
        np.random.seed(i)
        points = np.random.uniform(size=(10000, 2))
        L = loglike(points)
        mask = L > Lmin
        points = points[mask, :][:100, :]
        active_u = points
        active_values = L[mask][:100]

        transformLayer = AffineLayer(wrapped_dims=[])
        transformLayer.optimize(points, points)
        region = MLFriends(points, transformLayer)
        region.maxradiussq, region.enlarge = region.compute_enlargement(
            nbootstraps=30)
        region.create_ellipsoid()
        nclusters = transformLayer.nclusters
        assert nclusters == 1
        assert np.allclose(region.unormed,
                           region.transformLayer.transform(
                               points)), "transform should be reproducible"
        assert region.inside(
            points).all(), "live points should lie near live points"

        if i == 84:
            v = np.array([0.03477044, -0.01977415])
            reflpoint = np.array([0.09304075, 0.29114574])
        elif i == 4:
            v = np.array([0.03949306, -0.00634806])
            reflpoint = np.array([0.9934771, 0.55358031])

        else:
            v = np.random.normal(size=2)
            v /= (v**2).sum()**0.5
            v *= 0.04
            j = np.random.randint(len(active_u))
            reflpoint = np.random.normal(active_u[j, :], 0.04)
            if not (reflpoint < 1).all() and not (reflpoint > 0).all():
                continue

        bpts = region.transformLayer.transform(reflpoint).reshape((1, -1))
        tt = get_sphere_tangents(region.unormed, bpts)
        t = region.transformLayer.untransform(tt * 1e-3 +
                                              region.unormed) - region.u
        # compute new vector
        normal = t / norm(t, axis=1).reshape((-1, 1))
        print("reflecting at  ", reflpoint, "with direction", v)
        mask_forward1, angles, anglesnew = get_reflection_angles(normal, v)
        if mask_forward1.any():
            j = np.argmin(
                ((region.unormed[mask_forward1, :] - bpts)**2).sum(axis=1))
            k = np.arange(len(normal))[mask_forward1][j]
            angles_used = angles[k]
            normal_used = normal[k, :]
            print("chose normal", normal_used, k)
            #chosen_point = region.u[k,:]
            vnew = -(v - 2 * angles_used * normal_used)
            assert vnew.shape == v.shape

            mask_forward2, angles2, anglesnew2 = get_reflection_angles(
                normal, vnew)
            #j2 = np.argmin(((region.unormed[mask_forward2,:] - bpts)**2).sum(axis=1))
            #chosen_point2 = region.u[mask_forward2,:][0,:]
            #assert j2 == j, (j2, j)
            assert mask_forward2[k]
            #assert_allclose(chosen_point, chosen_point2)

            #for m, a, b, m2, a2, b2 in zip(mask_forward1, angles, anglesnew, mask_forward2, angles2, anglesnew2):
            #    if m != m2:
            #        print('  ', m, a, b, m2, a2, b2)

            #print("using normal", normal)
            #print("changed v from", v, "to", vnew)

            #angles2 = -(normal * (vnew / norm(vnew))).sum(axis=1)
            #mask_forward2 = angles < 0
            if plot:
                plt.figure(figsize=(5, 5))
                plt.title('%d' % mask_forward1.sum())
                plt.plot((reflpoint + v)[0], (reflpoint + v)[1],
                         '^',
                         color='orange')
                plt.plot((reflpoint + vnew)[:, 0], (reflpoint + vnew)[:, 1],
                         '^ ',
                         color='lime')
                plt.plot(reflpoint[0], reflpoint[1], '^ ', color='r')
                plt.plot(region.u[:, 0], region.u[:, 1], 'x ', ms=2, color='k')
                plt.plot(region.u[mask_forward1, 0],
                         region.u[mask_forward1, 1],
                         'o ',
                         ms=6,
                         mfc='None',
                         mec='b')
                plt.plot(region.u[mask_forward2, 0],
                         region.u[mask_forward2, 1],
                         's ',
                         ms=8,
                         mfc='None',
                         mec='g')
                plt.xlim(0, 1)
                plt.ylim(0, 1)
                plt.savefig('test_flatnuts_reversible_gradient_%d.png' % i,
                            bbox_inches='tight')
                plt.close()
            assert mask_forward1[k] == mask_forward2[k], (mask_forward1[k],
                                                          mask_forward2[k])

            print("reflecting at  ", reflpoint, "with direction", v)
            # make that step, then try to go back
            j = np.arange(len(normal))[mask_forward1][0]
            normal = normal[j, :]
            angles = (normal * (v / norm(v))).sum()
            v2 = v - 2 * angle(normal, v) * normal

            print("reflecting with", normal, "new direction", v2)

            #newpoint = reflpoint + v2
            #angles2 = (normal * (v2 / norm(v2))).sum()
            v3 = v2 - 2 * angle(normal, v2) * normal

            print("re-reflecting gives direction", v3)
            assert_allclose(v3, v)

            print()
            print("FORWARD:", v, reflpoint)
            samplingpath = SamplingPath(reflpoint - v, v, active_values[0])
            contourpath = ContourSamplingPath(samplingpath, region)
            normal = contourpath.gradient(reflpoint)
            if normal is not None:
                assert normal.shape == v.shape, (normal.shape, v.shape)

                print("BACKWARD:", v, reflpoint)
                v2 = -(v - 2 * angle(normal, v) * normal)
                normal2 = contourpath.gradient(reflpoint)
                assert_allclose(normal, normal2)
                normal2 = normal
                v3 = -(v2 - 2 * angle(normal2, v2) * normal2)
                assert_allclose(v3, v)
示例#9
0
def test_detailed_balance():
    def loglike(x):
        x, y = x.transpose()
        return -0.5 * (x**2 + ((y - 0.5) / 0.2)**2)

    def transform(u):
        return u

    Lmin = -0.5
    for i in range(1, 100):
        print()
        print("---- seed=%d ----" % i)
        print()
        np.random.seed(i)
        points = np.random.uniform(size=(10000, 2))
        L = loglike(points)
        mask = L > Lmin
        points = points[mask, :][:400, :]
        active_u = points
        active_values = L[mask][:400]

        transformLayer = AffineLayer(wrapped_dims=[])
        transformLayer.optimize(points, points)
        region = MLFriends(points, transformLayer)
        region.maxradiussq, region.enlarge = region.compute_enlargement(
            nbootstraps=30)
        region.create_ellipsoid()
        nclusters = transformLayer.nclusters
        assert nclusters == 1
        assert np.allclose(region.unormed,
                           region.transformLayer.transform(
                               points)), "transform should be reproducible"
        assert region.inside(
            points).all(), "live points should lie near live points"

        v = np.random.normal(size=2)
        v /= (v**2).sum()**0.5
        v *= 0.04

        print("StepSampler ----")
        print("FORWARD SAMPLING FROM", 0, active_u[0], v, active_values[0])
        samplingpath = SamplingPath(active_u[0], v, active_values[0])
        problem = dict(loglike=loglike, transform=transform, Lmin=Lmin)
        sampler = ClockedStepSampler(ContourSamplingPath(samplingpath, region))
        check_starting_point(sampler, active_u[0], active_values[0], **problem)
        sampler.expand_onestep(fwd=True, **problem)
        sampler.expand_onestep(fwd=True, **problem)
        sampler.expand_onestep(fwd=True, **problem)
        sampler.expand_onestep(fwd=True, **problem)
        sampler.expand_onestep(fwd=False, **problem)
        sampler.expand_to_step(4, **problem)
        sampler.expand_to_step(-4, **problem)
        check_starting_point(sampler, active_u[0], active_values[0], **problem)

        starti, startx, startv, startL = max(sampler.points)

        print()
        print("BACKWARD SAMPLING FROM", starti, startx, startv, startL)
        samplingpath2 = SamplingPath(startx, -startv, startL)
        sampler2 = ClockedStepSampler(
            ContourSamplingPath(samplingpath2, region))
        check_starting_point(sampler2, startx, startL, **problem)
        sampler2.expand_to_step(starti, **problem)
        check_starting_point(sampler2, startx, startL, **problem)

        starti2, startx2, startv2, startL2 = max(sampler2.points)
        assert_allclose(active_u[0], startx2)
        assert_allclose(v, -startv2)

        starti, startx, startv, startL = min(sampler.points)
        print()
        print("BACKWARD SAMPLING FROM", starti, startx, startv, startL)
        samplingpath3 = SamplingPath(startx, startv, startL)
        sampler3 = ClockedStepSampler(
            ContourSamplingPath(samplingpath3, region))
        check_starting_point(sampler3, startx, startL, **problem)
        sampler3.expand_to_step(-starti, **problem)
        check_starting_point(sampler3, startx, startL, **problem)

        starti3, startx3, startv3, startL3 = max(sampler3.points)
        assert_allclose(active_u[0], startx3)
        assert_allclose(v, startv3)
        print()

        print("BisectSampler ----")
        log = dict(log=True)
        print("FORWARD SAMPLING FROM", 0, active_u[0], v, active_values[0])
        samplingpath = SamplingPath(active_u[0], v, active_values[0])
        sampler = ClockedBisectSampler(
            ContourSamplingPath(samplingpath, region), **log)
        check_starting_point(sampler, active_u[0], active_values[0], **problem)
        sampler.expand_to_step(10, **problem)
        check_starting_point(sampler, active_u[0], active_values[0], **problem)

        starti, startx, startv, startL = max(sampler.points)
        print()
        print("BACKWARD SAMPLING FROM", starti, startx, startv, startL)
        samplingpath2 = SamplingPath(startx, -startv, startL)
        sampler2 = ClockedBisectSampler(
            ContourSamplingPath(samplingpath2, region), **log)
        check_starting_point(sampler2, startx, startL, **problem)
        sampler2.expand_to_step(starti, **problem)
        check_starting_point(sampler2, startx, startL, **problem)

        starti2, startx2, startv2, startL2 = max(sampler2.points)
        if gap_free_path(sampler, 0, starti, **problem) and gap_free_path(
                sampler2, 0, starti2, **problem):
            assert_allclose(active_u[0], startx2)
            assert_allclose(v, -startv2)

        starti, startx, startv, startL = min(sampler.points)
        print()
        print("BACKWARD SAMPLING FROM", starti, startx, startv, startL)
        samplingpath3 = SamplingPath(startx, -startv, startL)
        sampler3 = ClockedBisectSampler(
            ContourSamplingPath(samplingpath3, region), **log)
        check_starting_point(sampler3, startx, startL, **problem)
        sampler3.expand_to_step(starti, **problem)
        check_starting_point(sampler3, startx, startL, **problem)

        starti3, startx3, startv3, startL3 = min(sampler3.points)
        if gap_free_path(sampler, 0, starti, **problem) and gap_free_path(
                sampler3, 0, starti3, **problem):
            assert_allclose(active_u[0], startx3)
            assert_allclose(v, -startv3)
        print()

        print("NUTSSampler ----")
        print("FORWARD SAMPLING FROM", 0, active_u[0], v, active_values[0])
        samplingpath = SamplingPath(active_u[0], v, active_values[0])
        np.random.seed(i)
        sampler = ClockedNUTSSampler(ContourSamplingPath(samplingpath, region))
        sampler.get_independent_sample(**problem)
示例#10
0
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)