def update(self, smc): prev_Phi = self.Phi.copy() mq = rs.MultinomialQueue(self.prev_W) nprop = 0 for n in range(self.N): As = np.empty(self.Nparis, 'int') for m in range(self.Nparis): while True: a = mq.dequeue(1) nprop += 1 lp = (smc.fk.logpt(smc.t, self.prev_X[a], smc.X[n]) - smc.fk.upper_bound_log_pt(t)) if np.log(random.rand()) < lp: break As[m] = a mod_Phi = (self.prev_Phi[As] + smc.fk.add_func(smc.t, self.prev_X[As], smc.X[n])) self.Phi[n] = np.average(mod_Phi, axis=0) self.nprop.append(nprop)
def _backward_sampling_ON(self, M, idx): """O(N) version of backward sampling. not meant to be called directly, see backward_sampling """ nattempts = 0 for t in reversed(range(self.T - 1)): where_rejected = np.arange(M) who_rejected = self.X[t + 1][idx[t + 1, :]] nrejected = M gen = rs.MultinomialQueue(self.wgts[t].W, M=M) while nrejected > 0: nattempts += nrejected nprop = gen.dequeue(nrejected) lpr_acc = ( self.fk.logpt(t + 1, self.X[t][nprop], who_rejected) - self.fk.upper_bound_trans(t + 1)) newly_accepted = np.log(random.rand(nrejected)) < lpr_acc still_rejected = np.logical_not(newly_accepted) idx[t, where_rejected[newly_accepted]] = nprop[newly_accepted] where_rejected = where_rejected[still_rejected] who_rejected = who_rejected[still_rejected] nrejected -= sum(newly_accepted) return (M * (self.T - 1)) / nattempts