Tunes the scaling parameter for the proposal distribution
        according to the acceptance rate of the last k proposals:

        Rate    Variance adaptation
        ----    -------------------
        <0.001        x 0.1
        <0.05         x 0.5
        <0.2          x 0.9
        >0.5          x 1.1
        >0.75         x 2
        >0.95         x 10

        This method is called exclusively during the burn-in period of the
        sampling algorithm.

        May be overridden in subclasses.

def tune(self, divergence_threshold=1e10, verbose=0):
        """
        Tunes the scaling parameter for the proposal distribution
        according to the acceptance rate of the last k proposals:

        Rate    Variance adaptation
        ----    -------------------
        <0.001        x 0.1
        <0.05         x 0.5
        <0.2          x 0.9
        >0.5          x 1.1
        >0.75         x 2
        >0.95         x 10

        This method is called exclusively during the burn-in period of the
        sampling algorithm.

        May be overridden in subclasses.
        """

        if self.verbose > -1:
            verbose = self.verbose

        # Verbose feedback
        if verbose > 0:
            print_('\t%s tuning:' % self._id)

        # Flag for tuning state
        tuning = True

        # Calculate recent acceptance rate
        if not (self.accepted + self.rejected):
            return tuning
        acc_rate = self.accepted / (self.accepted + self.rejected)
        
        current_factor = self.adaptive_scale_factor

        # Switch statement
        if acc_rate < 0.001:
            # reduce by 90 percent
            self.adaptive_scale_factor *= 0.1
        elif acc_rate < 0.05:
            # reduce by 50 percent
            self.adaptive_scale_factor *= 0.5
        elif acc_rate < 0.2:
            # reduce by ten percent
            self.adaptive_scale_factor *= 0.9
        elif acc_rate > 0.95:
            # increase by factor of ten
            self.adaptive_scale_factor *= 10.0
        elif acc_rate > 0.75:
            # increase by double
            self.adaptive_scale_factor *= 2.0
        elif acc_rate > 0.5:
            # increase by ten percent
            self.adaptive_scale_factor *= 1.1
        else:
            tuning = False

        # Re-initialize rejection count
        self.rejected = 0.
        self.accepted = 0.
        
        # Prevent from tuning to zero
        if not self.adaptive_scale_factor:
            self.adaptive_scale_factor = current_factor
            return False

        # More verbose feedback, if requested
        if verbose > 0:
            if hasattr(self, 'stochastic'):
                print_('\t\tvalue:', self.stochastic.value)
            print_('\t\tacceptance rate:', acc_rate)
            print_('\t\tadaptive scale factor:', self.adaptive_scale_factor)
            print_()

        return tuning