def sis_r(db, ob, particles): num_particles = cmd_args.num_particles weights = torch.ones([num_particles, 1], dtype=torch.float).to(DEVICE) / num_particles # re-weight reweight = torch.zeros(weights.shape, dtype=weights.dtype).to(DEVICE) for ob_i in ob: reweight += db.log_likelihood(ob_i.reshape([1, -1]), particles) reweight = torch.exp(reweight) weights = weights * reweight # re-sample weights = weights / torch.sum(weights) mnrnd = torch.distributions.multinomial.Multinomial( num_particles, torch.reshape(torch.relu(weights), [num_particles])) idx = mnrnd.sample().int() nonzero_cluster = idx.nonzero() indx = 0 new_xi = torch.zeros(particles.shape, dtype=particles.dtype) for iter in range(nonzero_cluster.shape[0]): nonzero_idx = nonzero_cluster[iter][0] new_xi[indx:indx + idx[nonzero_idx], :] = particles[ nonzero_cluster[iter][0]].repeat(int(idx[nonzero_idx]), 1) indx += idx[nonzero_cluster[iter][0]] particles = new_xi ess = torch.sum(weights)**2 / torch.sum(weights * weights) if ess <= cmd_args.threshold * num_particles: # generate new location kde = KDE(particles) particles = kde.get_samples(cmd_args.num_particles) return particles
def onepass_smc(db, ob, particles, alpha): num_particles = cmd_args.num_particles # re-weight reweight = torch.zeros(alpha.shape, dtype=alpha.dtype) for ob_i in ob: reweight += db.log_likelihood(ob_i.reshape([1, -1]), particles).view(reweight.size()) reweight = torch.exp(reweight) alpha = alpha * reweight # re-sample ess = torch.sum(alpha)**2 / torch.sum(alpha * alpha) if ess <= cmd_args.threshold * num_particles: alpha = alpha / torch.sum(alpha) mnrnd = torch.distributions.multinomial.Multinomial( num_particles, torch.reshape(torch.abs(alpha), [num_particles])) idx = mnrnd.sample().int() nonzero_cluster = idx.nonzero() indx = 0 new_xi = torch.zeros(particles.shape, dtype=particles.dtype).to(DEVICE) for iter in range(nonzero_cluster.shape[0]): nonzero_idx = nonzero_cluster[iter][0] new_xi[indx:indx + idx[nonzero_idx], :] = particles[ nonzero_cluster[iter][0]].repeat(int(idx[nonzero_idx]), 1) indx += idx[nonzero_cluster[iter][0]] # generate new location kde = KDE(new_xi) xi = kde.get_samples(cmd_args.num_particles) alpha = torch.ones([num_particles, 1], dtype=torch.float) / num_particles else: alpha = alpha / torch.sum(alpha) xi = particles return xi, alpha