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
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
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