def _hamiltonian_step(self, start, p0, step_size): n_steps = max(1, int(self.path_length / step_size)) n_steps = min(self.max_steps, n_steps) energy_change = -np.inf state = start last = state div_info = None try: for _ in range(n_steps): last = state state = self.integrator.step(step_size, state) except IntegrationError as e: div_info = DivergenceInfo("Integration failed.", e, last, None) else: if not np.isfinite(state.energy): div_info = DivergenceInfo( "Divergence encountered, bad energy.", None, last, state) energy_change = start.energy - state.energy if np.isnan(energy_change): energy_change = -np.inf if np.abs(energy_change) > self.Emax: div_info = DivergenceInfo( "Divergence encountered, large integration error.", None, last, state) accept_stat = min(1, np.exp(energy_change)) if div_info is not None or np.random.rand() >= accept_stat: end = start accepted = False else: end = state accepted = True stats = { "path_length": self.path_length, "n_steps": n_steps, "accept": accept_stat, "energy_error": energy_change, "energy": state.energy, "accepted": accepted, "model_logp": state.model_logp, } return HMCStepData(end, accept_stat, div_info, stats)
def _hamiltonian_step(self, start, p0, step_size): n_steps = max(1, int(self.path_length / step_size)) n_steps = min(self.max_steps, n_steps) energy_change = -np.inf state = start div_info = None try: for _ in range(n_steps): state = self.integrator.step(step_size, state) except IntegrationError as e: div_info = DivergenceInfo('Divergence encountered.', e, state) else: if not np.isfinite(state.energy): div_info = DivergenceInfo( 'Divergence encountered, bad energy.', None, state) energy_change = start.energy - state.energy if np.isnan(energy_change): energy_change = -np.inf if np.abs(energy_change) > self.Emax: div_info = DivergenceInfo( 'Divergence encountered, large integration error.', None, state) accept_stat = min(1, np.exp(energy_change)) if div_info is not None or np.random.rand() >= accept_stat: end = start accepted = False else: end = state accepted = True stats = { 'path_length': self.path_length, 'n_steps': n_steps, 'accept': accept_stat, 'energy_error': energy_change, 'energy': state.energy, 'accepted': accepted, 'model_logp': state.model_logp, } return HMCStepData(end, accept_stat, div_info, stats)
def _hamiltonian_step(self, start, p0, step_size): if self.tune and self.iter_count < 200: max_treedepth = self.early_max_treedepth else: max_treedepth = self.max_treedepth tree = _Tree(len(p0), self.integrator, start, step_size, self.Emax) for _ in range(max_treedepth): direction = logbern(np.log(0.5)) * 2 - 1 divergence_info, turning = tree.extend(direction) if divergence_info or turning: break else: if not self.tune: self._reached_max_treedepth += 1 stats = tree.stats() accept_stat = stats["mean_tree_accept"] return HMCStepData(tree.proposal, accept_stat, divergence_info, stats)
def _hamiltonian_step(self, start, p0, step_size): path_length = np.random.rand() * self.path_length n_steps = max(1, int(path_length / step_size)) energy_change = -np.inf state = start div_info = None try: for _ in range(n_steps): state = self.integrator.step(step_size, state) except IntegrationError as e: div_info = DivergenceInfo('Divergence encountered.', e, state) else: if not np.isfinite(state.energy): div_info = DivergenceInfo('Divergence encountered, bad energy.', None, state) energy_change = start.energy - state.energy if np.abs(energy_change) > self.Emax: div_info = DivergenceInfo('Divergence encountered, large integration error.', None, state) accept_stat = min(1, np.exp(energy_change + state.log_jac)) if div_info is not None or np.random.rand() >= accept_stat: end = start accepted = False else: end = state accepted = True stats = { 'path_length': path_length, 'n_steps': n_steps, 'accept': accept_stat, 'energy_error': energy_change, 'energy': state.energy, 'accepted': accepted, # 'log_jacobian': state.log_jac, # TODO: backends/ndarray.py to allow this } return HMCStepData(end, accept_stat, div_info, stats)