Runs a single sampling iteration to return a sample

def _sample(self, position, trajectory_length, stepsize, lsteps=None):
        """
        Runs a single sampling iteration to return a sample
        """
        # Resampling momentum
        momentum = np.reshape(np.random.normal(0, 1, len(position)), position.shape)

        # position_m here will be the previous sampled value of position
        position_bar, momentum_bar = position.copy(), momentum

        # Number of steps L to simulate dynamics
        if lsteps is None:
            lsteps = int(max(1, round(trajectory_length / stepsize, 0)))

        grad_bar, _ = self.grad_log_pdf(position_bar, self.model).get_gradient_log_pdf()

        for _ in range(lsteps):
            position_bar, momentum_bar, grad_bar =\
                self.simulate_dynamics(self.model, position_bar, momentum_bar,
                                       stepsize, self.grad_log_pdf, grad_bar).get_proposed_values()

        acceptance_prob = self._acceptance_prob(position, position_bar, momentum, momentum_bar)

        # Metropolis acceptance probability
        alpha = min(1, acceptance_prob)

        # Accept or reject the new proposed value of position, i.e position_bar
        if np.random.rand() < alpha:
            position = position_bar.copy()
            self.accepted_proposals += 1.0

        return position, alpha