예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)