def importance_sample(self, logL_new, action='add', inplace=False): """Perform importance re-weighting on the log-likelihood. Parameters ---------- logL_new: np.array New log-likelihood values. Should have the same shape as `logL`. action: str, optional Can be any of {'add', 'replace', 'mask'}. * add: Add the new `logL_new` to the current `logL`. * replace: Replace the current `logL` with the new `logL_new`. * mask: treat `logL_new` as a boolean mask and only keep the corresponding (True) samples. default: 'add' inplace: bool, optional Indicates whether to modify the existing array, or return a new frame with importance sampling applied. default: False Returns ------- samples: NestedSamples Importance re-weighted samples. """ samples = super().importance_sample(logL_new, action=action) samples = samples[samples.logL > samples.logL_birth].recompute() return modify_inplace(self, samples, inplace)
def recompute(self, logL_birth=None, inplace=False): """Re-calculate the nested sampling contours and live points. Parameters ---------- logL_birth: array-like or int, optional array-like: the birth contours. int: the number of live points. default: use the existing birth contours to compute nlive inplace: bool, optional Indicates whether to modify the existing array, or return a new frame with contours resorted and nlive recomputed default: False """ samples = self.sort_values('logL').reset_index(drop=True) if is_int(logL_birth): nlive = logL_birth samples['nlive'] = nlive descending = np.arange(nlive, 0, -1) samples.loc[len(samples) - nlive:, 'nlive'] = descending else: if logL_birth is not None: samples['logL_birth'] = logL_birth samples.tex['logL_birth'] = r'$\log\mathcal{L}_{\rm birth}$' if 'logL_birth' not in samples: raise RuntimeError("Cannot recompute run without " "birth contours logL_birth.") invalid = samples.logL <= samples.logL_birth n_bad = invalid.sum() n_equal = (samples.logL == samples.logL_birth).sum() if n_bad: warnings.warn( "%i out of %i samples have logL <= logL_birth," "\n%i of which have logL == logL_birth." "\nThis may just indicate numerical rounding " "errors at the peak of the likelihood, but " "further investigation of the chains files is " "recommended." "\nDropping the invalid samples." % (n_bad, len(samples), n_equal), RuntimeWarning) samples = samples[~invalid].reset_index(drop=True) samples['nlive'] = compute_nlive(samples.logL, samples.logL_birth) samples.tex['nlive'] = r'$n_{\rm live}$' samples.beta = samples._beta return modify_inplace(self, samples, inplace)
def importance_sample(self, logL_new, action='add', inplace=False): """Perform importance re-weighting on the log-likelihood. Parameters ---------- logL_new: np.array New log-likelihood values. Should have the same shape as `logL`. action: str, optional Can be any of {'add', 'replace', 'mask'}. * add: Add the new `logL_new` to the current `logL`. * replace: Replace the current `logL` with the new `logL_new`. * mask: treat `logL_new` as a boolean mask and only keep the corresponding (True) samples. default: 'add' inplace: bool, optional Indicates whether to modify the existing array, or return a new frame with importance sampling applied. default: False Returns ------- samples: MCMCSamples Importance re-weighted samples. """ samples = self.copy() if action == 'add': samples.weights *= np.exp(logL_new - logL_new.max()) samples.logL += logL_new elif action == 'replace': logL_new2 = logL_new - samples.logL samples.weights *= np.exp(logL_new2 - logL_new2.max()) samples.logL = logL_new elif action == 'mask': samples = samples[logL_new] else: raise NotImplementedError("`action` needs to be one of " "{'add', 'replace', 'mask'}, but '%s' " "was requested." % action) return modify_inplace(self, samples, inplace)
def recompute(self, logL_birth=None, inplace=False): """Re-calculate the nested sampling contours and live points. Parameters ---------- logL_birth, array-like or int, optional array-like: the birth contours. int: the number of live points. default: use the existing birth contours to compute nlive inplace: bool, optional Indicates whether to modify the existing array, or return a new frame with contours resorted and nlive recomputed default: False """ samples = self.sort_values('logL').reset_index(drop=True) if is_int(logL_birth): nlive = logL_birth samples['nlive'] = nlive descending = np.arange(nlive, 0, -1) samples.loc[len(samples) - nlive:, 'nlive'] = descending else: if logL_birth is not None: samples['logL_birth'] = logL_birth samples.tex['logL_birth'] = r'$\log\mathcal{L}_{\rm birth}$' if 'logL_birth' not in samples: raise RuntimeError("Cannot recompute run without " "birth contours logL_birth.") if (samples.logL <= samples.logL_birth).any(): raise RuntimeError("Not a valid nested sampling run. " "Require logL > logL_birth.") samples['nlive'] = compute_nlive(samples.logL, samples.logL_birth) samples.tex['nlive'] = r'$n_{\rm live}$' samples.beta = samples._beta return modify_inplace(self, samples, inplace)