Пример #1
0
def sample_rwalk_parallel_with_act(args):
    """ A dynesty sampling method optimised for parallel_bilby

    """

    # Unzipping.
    (u, loglstar, axes, scale, prior_transform, loglikelihood, kwargs) = args
    rstate = np.random
    # Bounds
    nonbounded = kwargs.get("nonbounded", None)
    periodic = kwargs.get("periodic", None)
    reflective = kwargs.get("reflective", None)

    # Setup.
    n = len(u)
    walks = kwargs.get("walks", 50)  # minimum number of steps
    maxmcmc = kwargs.get("maxmcmc", 10000)  # maximum number of steps
    nact = kwargs.get("nact", 10)  # number of act

    accept = 0
    reject = 0
    nfail = 0
    act = np.inf
    u_list = []
    v_list = []
    logl_list = []

    drhat, dr, du, u_prop, logl_prop = np.nan, np.nan, np.nan, np.nan, np.nan
    while len(u_list) < nact * act:
        # Propose a direction on the unit n-sphere.
        drhat = rstate.randn(n)
        drhat /= linalg.norm(drhat)

        # Scale based on dimensionality.
        dr = drhat * rstate.rand()**(1.0 / n)

        # Transform to proposal distribution.
        du = np.dot(axes, dr)
        u_prop = u + scale * du

        # Wrap periodic parameters
        if periodic is not None:
            u_prop[periodic] = np.mod(u_prop[periodic], 1)
        # Reflect
        if reflective is not None:
            u_prop[reflective] = reflect(u_prop[reflective])

        # Check unit cube constraints.
        if unitcheck(u_prop, nonbounded):
            pass
        else:
            nfail += 1
            if accept > 0:
                u_list.append(u_list[-1])
                v_list.append(v_list[-1])
                logl_list.append(logl_list[-1])
            continue

        # Check proposed point.
        v_prop = prior_transform(u_prop)
        logl_prop = loglikelihood(v_prop)
        if logl_prop >= loglstar:
            u = u_prop
            v = v_prop
            logl = logl_prop
            accept += 1
            u_list.append(u)
            v_list.append(v)
            logl_list.append(logl)
        else:
            reject += 1
            if accept > 0:
                u_list.append(u_list[-1])
                v_list.append(v_list[-1])
                logl_list.append(logl_list[-1])

        # If we've taken the minimum number of steps, calculate the ACT
        if accept + reject > walks:
            act = bilby.core.sampler.dynesty.estimate_nmcmc(
                accept_ratio=accept / (accept + reject + nfail),
                old_act=walks,
                maxmcmc=maxmcmc,
                safety=5,
            )

        # If we've taken too many likelihood evaluations then break
        if accept + reject > maxmcmc:
            logger.warning(
                "Hit maximum number of walks {} with accept={}, reject={}, "
                "nfail={}, and act={}. Try increasing maxmcmc".format(
                    maxmcmc, accept, reject, nfail, act))
            break

    # If the act is finite, pick randomly from within the chain
    factor = 0.1
    if len(u_list) == 0:
        logger.warning("No accepted points: returning -inf")
        u = u
        v = prior_transform(u)
        logl = -np.inf
    elif np.isfinite(act) and int(factor * nact * act) < len(u_list):
        idx = np.random.randint(int(factor * nact * act), len(u_list))
        u = u_list[idx]
        v = v_list[idx]
        logl = logl_list[idx]
    else:
        logger.warning(
            "len(u_list)={}<{}: returning the last point in the chain".format(
                len(u_list), int(factor * nact * act)))
        u = u_list[-1]
        v = v_list[-1]
        logl = logl_list[-1]

    blob = {"accept": accept, "reject": reject, "fail": nfail, "scale": scale}

    ncall = accept + reject
    return u, v, logl, ncall, blob
Пример #2
0
def sample_rwalk_bilby(args):
    """ Modified bilby-implemented version of dynesty.sampling.sample_rwalk """
    from dynesty.utils import unitcheck

    # Unzipping.
    (u, loglstar, axes, scale,
     prior_transform, loglikelihood, kwargs) = args
    rstate = np.random

    # Bounds
    nonbounded = kwargs.get('nonbounded', None)
    periodic = kwargs.get('periodic', None)
    reflective = kwargs.get('reflective', None)

    # Setup.
    n = len(u)
    walks = kwargs.get('walks', 100)  # minimum number of steps
    maxmcmc = kwargs.get('maxmcmc', 5000)  # Maximum number of steps
    nact = kwargs.get('nact', 5)  # Number of ACT
    old_act = kwargs.get('old_act', walks)

    # Initialize internal variables
    accept = 0
    reject = 0
    nfail = 0
    act = np.inf
    u_list = []
    v_list = []
    logl_list = []

    ii = 0
    while ii < nact * act:
        ii += 1

        # Propose a direction on the unit n-sphere.
        drhat = rstate.randn(n)
        drhat /= np.linalg.norm(drhat)

        # Scale based on dimensionality.
        dr = drhat * rstate.rand() ** (1.0 / n)

        # Transform to proposal distribution.
        du = np.dot(axes, dr)
        u_prop = u + scale * du

        # Wrap periodic parameters
        if periodic is not None:
            u_prop[periodic] = np.mod(u_prop[periodic], 1)
        # Reflect
        if reflective is not None:
            u_prop[reflective] = reflect(u_prop[reflective])

        # Check unit cube constraints.
        if unitcheck(u_prop, nonbounded):
            pass
        else:
            nfail += 1
            # Only start appending to the chain once a single jump is made
            if accept > 0:
                u_list.append(u_list[-1])
                v_list.append(v_list[-1])
                logl_list.append(logl_list[-1])
            continue

        # Check proposed point.
        v_prop = prior_transform(np.array(u_prop))
        logl_prop = loglikelihood(np.array(v_prop))
        if logl_prop > loglstar:
            u = u_prop
            v = v_prop
            logl = logl_prop
            accept += 1
            u_list.append(u)
            v_list.append(v)
            logl_list.append(logl)
        else:
            reject += 1
            # Only start appending to the chain once a single jump is made
            if accept > 0:
                u_list.append(u_list[-1])
                v_list.append(v_list[-1])
                logl_list.append(logl_list[-1])

        # If we've taken the minimum number of steps, calculate the ACT
        if accept + reject > walks:
            act = estimate_nmcmc(
                accept_ratio=accept / (accept + reject + nfail),
                old_act=old_act, maxmcmc=maxmcmc)

        # If we've taken too many likelihood evaluations then break
        if accept + reject > maxmcmc:
            warnings.warn(
                "Hit maximum number of walks {} with accept={}, reject={}, "
                "and nfail={} try increasing maxmcmc"
                .format(maxmcmc, accept, reject, nfail))
            break

    # If the act is finite, pick randomly from within the chain
    if np.isfinite(act) and int(.5 * nact * act) < len(u_list):
        idx = np.random.randint(int(.5 * nact * act), len(u_list))
        u = u_list[idx]
        v = v_list[idx]
        logl = logl_list[idx]
    else:
        logger.debug("Unable to find a new point using walk: returning a random point")
        u = np.random.uniform(size=n)
        v = prior_transform(u)
        logl = loglikelihood(v)

    blob = {'accept': accept, 'reject': reject, 'fail': nfail, 'scale': scale}
    kwargs["old_act"] = act

    ncall = accept + reject
    return u, v, logl, ncall, blob
Пример #3
0
def sample_rwalk_bilby(args):
    """ Modified bilby-implemented version of dynesty.sampling.sample_rwalk """

    # Unzipping.
    (u, loglstar, axes, scale, prior_transform, loglikelihood, kwargs) = args
    rstate = np.random

    # Bounds
    nonbounded = kwargs.get('nonbounded', None)
    periodic = kwargs.get('periodic', None)
    reflective = kwargs.get('reflective', None)

    # Setup.
    n = len(u)
    walks = kwargs.get('walks', 25)  # minimum number of steps
    maxmcmc = kwargs.get('maxmcmc', 2000)  # Maximum number of steps
    nact = kwargs.get('nact', 5)  # Number of ACT

    # Initialize internal variables
    accept = 0
    reject = 0
    nfail = 0
    act = np.inf
    u_list = [u]
    v_list = [prior_transform(u)]
    logl_list = [loglikelihood(v_list[-1])]
    max_walk_warning = True

    drhat, dr, du, u_prop, logl_prop = np.nan, np.nan, np.nan, np.nan, np.nan
    while len(u_list) < nact * act:

        if scale == 0.:
            raise RuntimeError("The random walk sampling is stuck! "
                               "Some useful output quantities:\n"
                               "u: {0}\n"
                               "drhat: {1}\n"
                               "dr: {2}\n"
                               "du: {3}\n"
                               "u_prop: {4}\n"
                               "loglstar: {5}\n"
                               "logl_prop: {6}\n"
                               "axes: {7}\n"
                               "scale: {8}.".format(u, drhat, dr, du, u_prop,
                                                    loglstar, logl_prop, axes,
                                                    scale))

        # Propose a direction on the unit n-sphere.
        drhat = rstate.randn(n)
        drhat /= linalg.norm(drhat)

        # Scale based on dimensionality.
        # dr = drhat * rstate.rand()**(1. / n)  # CHANGED FROM DYNESTY 1.0
        dr = drhat * rstate.rand(n)

        # Transform to proposal distribution.
        du = np.dot(axes, dr)
        u_prop = u + scale * du

        # Wrap periodic parameters
        if periodic is not None:
            u_prop[periodic] = np.mod(u_prop[periodic], 1)
        # Reflect
        if reflective is not None:
            u_prop[reflective] = reflect(u_prop[reflective])

        # Check unit cube constraints.
        if unitcheck(u_prop, nonbounded):
            pass
        else:
            nfail += 1
            # Only start appending to the chain once a single jump is made
            if accept > 0:
                u_list.append(u_list[-1])
                v_list.append(v_list[-1])
                logl_list.append(logl_list[-1])
            continue

        # Check if we're stuck generating bad numbers.
        if nfail > 100 * walks:
            warnings.warn("Random number generation appears to be "
                          "extremely inefficient. Adjusting the "
                          "scale-factor accordingly.")
            nfail = 0
            scale *= math.exp(-1. / n)

        # Check proposed point.
        v_prop = prior_transform(np.array(u_prop))
        logl_prop = loglikelihood(np.array(v_prop))
        if logl_prop >= loglstar:
            u = u_prop
            v = v_prop
            logl = logl_prop
            accept += 1
            u_list.append(u)
            v_list.append(v)
            logl_list.append(logl)
        else:
            reject += 1
            # Only start appending to the chain once a single jump is made
            if accept > 0:
                u_list.append(u_list[-1])
                v_list.append(v_list[-1])
                logl_list.append(logl_list[-1])

        # If we've taken the minimum number of steps, calculate the ACT
        if accept + reject > walks:
            act = estimate_nmcmc(accept_ratio=accept /
                                 (accept + reject + nfail),
                                 maxmcmc=maxmcmc)

        # If we've taken too many likelihood evaluations then break
        if accept + reject > maxmcmc and accept > 0:
            if max_walk_warning:
                warnings.warn(
                    "Hit maximum number of walks {} with accept={}, reject={}, "
                    "and nfail={} try increasing maxmcmc".format(
                        maxmcmc, accept, reject, nfail))
                max_walk_warning = False
            if accept > 0:
                # Break if we are above maxmcmc and have at least one accepted point
                break

        # Check if we're stuck generating bad points.
        if accept + reject > 50 * walks:
            scale *= math.exp(-1. / n)
            warnings.warn("Random walk proposals appear to be "
                          "extremely inefficient. Adjusting the "
                          "scale-factor accordingly.")

    # If the act is finite, pick randomly from within the chain
    if np.isfinite(act) and act < len(u_list):
        idx = np.random.randint(act, len(u_list))
        u = u_list[idx]
        v = v_list[idx]
        logl = logl_list[idx]
    elif len(u_list) == 1:
        logger.warning("Returning the only point in the chain")
        u = u_list[-1]
        v = v_list[-1]
        logl = logl_list[-1]
    else:
        idx = np.random.randint(int(len(u_list) / 2), len(u_list))
        logger.warning("Returning random point in second half of the chain")
        u = u_list[idx]
        v = v_list[idx]
        logl = logl_list[idx]

    blob = {'accept': accept, 'reject': reject, 'fail': nfail, 'scale': scale}

    ncall = accept + reject
    return u, v, logl, ncall, blob