def sampling_iteration(self): # states f_state = self.state.copy().F() l_state = self.state.copy().L() # aka L^-1 state flf_state = self.state.copy().FLF() r_state = self.state.copy().R() # rates l_rates = self.transition_rates(self.state, l_state) flf_rates = self.transition_rates(self.state, flf_state) f_rates = flf_rates - np.min((flf_rates, l_rates), axis=0) r_rates = self.p_r * np.ones((1, self.nbatch)) # draws from exponential distributions l_draws = draw_from(l_rates[0]) f_draws = draw_from(f_rates[0]) r_draws = draw_from(r_rates[0]) # choose min for each particle l_idx, f_idx, r_idx = min_idx([l_draws, f_draws, r_draws]) # record dwelling times self.dwelling_times = np.amin( np.concatenate((l_draws, f_draws, r_draws)), axis=0) # cache current state as FLF state for next L transition self.state.cache_flf_state(l_idx, self.state) # cache FL as FLF state for for particles that made transition to F # self.state.cache_flf_state(f_idx, l_state.F()) # update accepted proposed states self.state.update(l_idx, l_state) self.state.update(f_idx, f_state) self.state.update(r_idx, r_state) # clear flf cache for particles that transition to R, F self.state.clear_flf_cache(r_idx) self.state.clear_flf_cache(f_idx) self.l_count += len(l_idx) self.f_count += len(f_idx) self.r_count += len(r_idx)
def sampling_iteration(self): """Perform a single sampling step """ # F operator f_state = self.state.copy().F() # FL operator fl_state = self.state.copy().L().F() # rates fl_rates = self.transition_rates(self.state, fl_state) f_rates = np.ones((1, self.nbatch)) r_rates = self.p_r * np.ones((1, self.nbatch)) # draws from exponential distributions fl_draws = draw_from(fl_rates[0]) f_draws = draw_from(f_rates[0]) r_draws = draw_from(r_rates[0]) # choose min for each particle f_idx, fl_idx, r_idx = min_idx([f_draws, fl_draws, r_draws]) # record dwelling times self.dwelling_times = np.amin( np.concatenate((fl_draws, f_draws, r_draws)), axis=0) # update accepted FL transitions self.state.update(fl_idx, fl_state) # update accepted F transitions self.state.update(f_idx, f_state) # corrupt the momentum and update accepted R transition # inefficiently corrupts momentum for all state then selects a subset R_state = self.state.copy().R() self.state.update(r_idx, R_state) self.fl_count += len(fl_idx) self.f_count += len(f_idx) self.r_count += len(r_idx)
def sampling_iteration(self): # states f_state = self.state.copy().F() l_state = self.state.copy().L() # aka L^-1 state flf_state = self.state.copy().FLF() r_state = self.state.copy().R() try: # rates l_rates = self.transition_rates(self.state, l_state) flf_rates = self.transition_rates(self.state, flf_state) f_rates = flf_rates - np.min((flf_rates, l_rates), axis=0) r_rates = self.p_r * np.ones((1, self.nbatch)) # draws from exponential distributions l_draws = draw_from(l_rates[0]) f_draws = draw_from(f_rates[0]) r_draws = draw_from(r_rates[0]) # infinite rate due to taking too large of a step except ValueError: # take smaller steps, but go the same overall distance self.epsilon *= 0.5 self.num_leapfrog_steps *= 2 depth = np.log(self.original_epsilon / self.epsilon) / np.log(2) print("Ecountered infinite rate, doubling back. Depth: {}".format(depth)) # try again self.state.reset_flf_cache() self.sampling_iteration() # restore the old guys self.epsilon *= 2 self.num_leapfrog_steps = int(self.num_leapfrog_steps / 2) return # choose min for each particle l_idx, f_idx, r_idx = min_idx([l_draws, f_draws, r_draws]) # record dwelling times self.dwelling_times = np.amin( np.concatenate((l_draws, f_draws, r_draws)), axis=0) # cache current state as FLF state for next L transition self.state.cache_flf_state(l_idx, self.state) # cache FL as FLF state for for particles that made transition to F # self.state.cache_flf_state(f_idx, l_state.F()) # update accepted proposed states self.state.update(l_idx, l_state) self.state.update(f_idx, f_state) self.state.update(r_idx, r_state) # clear flf cache for particles that transition to R, F self.state.clear_flf_cache(r_idx) self.state.clear_flf_cache(f_idx) self.l_count += len(l_idx) self.f_count += len(f_idx) self.r_count += len(r_idx)