def reset_weights(self): """Reset weights after a resampling step. """ if self.fk.isAPF: lw = (rs.log_mean_exp(self.logetat, W=self.W) - self.logetat[self.A]) self.wgts = rs.Weights(lw=lw) else: self.wgts = rs.Weights()
def __init__(self, fk=None, N=100, qmc=False, resampling="systematic", ESSrmin=0.5, store_history=False, verbose=False, summaries=True, **sum_options): self.fk = fk self.N = N self.qmc = qmc self.resampling = resampling self.ESSrmin = ESSrmin self.verbose = verbose # initialisation self.t = 0 self.rs_flag = False # no resampling at time 0, by construction self.logLt = 0. self.wgts = rs.Weights() self.aux = None self.X, self.Xp, self.A = None, None, None if qmc: self.h_order = None # summaries computed at every t if summaries: self.summaries = collectors.Summaries(**sum_options) else: self.summaries = None self.hist = smoothing.generate_hist_obj(store_history, fk, qmc)
def __init__(self, fk: FeynmanKacNew, N, max_memory_in_MB: float = np.inf, seed=None, verbose=False, print_datetime=True): self.fk = fk self.fk.pf_debug_access = self self.fk.verbose = verbose self.N = N self.seed = seed self.X = None self.t = 0 self.logLt = 0 self.loglt = [] self.wgts = rs.Weights(np.zeros(N)) self.verbose = verbose self.print_datetime = print_datetime self.dt_identifier = None if print_datetime: self.dt_identifier = str(datetime.datetime.now()) print('Identifier {} with seed {} started'.format( self.dt_identifier, self.seed), flush=True) self.max_memory_in_MB = max_memory_in_MB ut.memory_tracker_add(0)
def apply_MCMC_then_flatten(self, t:int, starting_points: np.ndarray, target_N: int, starting_lw:np.ndarray) -> np.ndarray: # We will not use the parameter `target_N`, instead, it will be read as an attribute of self. tg = TargetedReproducer(starting_points=starting_points, starting_W=rs.Weights(starting_lw).W, target_ess=self.target_N, kernel=lambda _x: self.model.MCMC(t, _x), f=lambda _x: self.model.diag_function_for_adaptive_MCMC(t, _x), method=self.method_for_choosing_MCMC_length, union_function=self.collector, max_N_particles=self.max_N_particles, verbose=self.verbose, forceful=True) res = tg.run() ut.memory_tracker_add(t) self.logging.thinning.append(tg.k) self.logging.chain_length.append(tg.kernel_call + 1) return res
def rejuvenate(self, t, xp, w): ancestors = rs.resampling(self.resampling_scheme, w.W) x = xp[ancestors] for _ in tqdm(range(self.k), disable= not self.verbose): x = self.model.MCMC(t, x) self.logging.compact_particle_history.add(lw=np.zeros(len(x)), ancestor=ancestors, last_particles=x) ut.memory_tracker_add(t) return x, rs.Weights(lw=np.zeros(len(xp)))
def rejuvenate(self, t: int, xp: np.ndarray, w: rs.Weights) -> tp.Tuple[np.ndarray, rs.Weights]: if self.outer_ess_r_calc_mode == 'standard': essrmin_outer_command = self.ESSrmin_outer # we let the resampler determine whether to outer-resample or not elif self.outer_ess_r_calc_mode == 'conservative': essrmin_outer_command = int(self.histories_between_two_outer_resampling[-1].outer_ess_ratio < self.ESSrmin_outer) # we decide in avance else: raise ValueError('Unknown method to calculate outer ESS ratio.') resampler = AdaptivelySampleStartingPoints(xp=xp, w=w, M=self.M_resample, M1=self.M1, ESSrmin_outer=essrmin_outer_command, inner_resampling_mode=self.inner_resampling_scheme, outer_resampling_mode=self.outer_resampling_scheme) starting_points = resampler.final_starting_points self.logging.resampling_mode.append(1 if not resampler.outer_resampling_needed else 2) self.last_resampling_mode = 1 if not resampler.outer_resampling_needed else 2 x = self.apply_MCMC_then_flatten(t=t, starting_points=starting_points, target_N = len(xp), starting_lw=resampler.final_inner_lw(1)) P = len(x) // self.M_resample new_inner_weights = rs.Weights(resampler.final_inner_lw(P)) self.inner_lw_just_after_last_rejuvenate = new_inner_weights.lw self.logging.weight_cumulator.update_M(new_weights=new_inner_weights, normalize=resampler.outer_resampling_needed, normalize_info=resampler.chosen_outer_ancestors) return x, new_inner_weights
def M(self, t: int, xp: np.ndarray, w: rs.Weights) -> typing.Tuple[np.ndarray, rs.Weights]: resampling_needed = ut.ESS_ratio(w) < self.ESSrmin self.logging.punctual_logging[ t] = GenericParticleFilterPunctualLogging() self.logging.punctual_logging[t].ESS_ratio = ut.ESS_ratio(w) self.logging.punctual_logging[t].ESS = w.ESS self.logging.punctual_logging[t].resampled = resampling_needed if resampling_needed: ancestors = rs.resampling(self.resampling_mode, w.W) xp = xp[ancestors] w = rs.Weights(lw=np.zeros(len(xp))) self.logging.compact_particle_history.add(lw=w.lw, ancestor=ancestors, last_particles=xp) x = self.fk_model.M(t, xp) return x, w
def run(self, N=100): """ Parameter --------- N: int number of particles Returns ------- wgts: Weights object The importance weights (with attributes lw, W, and ESS) X: ThetaParticles object The N particles (with attributes theta, logpost) norm_cst: float Estimate of the normalising constant of the target """ th = self.proposal.rvs(size=N) self.X = ThetaParticles(theta=th, lpost=None) self.X.lpost = self.model.logpost(th) lw = self.X.lpost - self.proposal.logpdf(th) self.wgts = rs.Weights(lw=lw) self.norm_cst = rs.log_mean_exp(lw)
def __init__(self, model: SMCSamplerModel): super().__init__() self.model = model self.verbose = False # Mutable attributes self.current_post_rejuvenate_w: rs.Weights = rs.Weights()
def outer_weights(self) -> rs.Weights: return rs.Weights(lw=self.outer_lw)
def calculate_QT(self, phi: typing.Callable[[np.ndarray], np.ndarray]) -> float: """Alternative way to calculate QT(phi). Used for debugging purpose """ # noinspection PyTypeChecker return np.sum(rs.Weights(self._logG[-1]).W * phi(self._X_last))
def ESS_ratio(self, t: int) -> typing.Union[float, None]: if t >= len(self._logG): return None return ut.ESS_ratio(rs.Weights(lw=self._logG[t]))