r"""Sets variables for covariance adaptation.

        When :meth:`.adapt` is called, the proposal's covariance matrix is
        adapted in order to improve the chain's performance. The aim
        is to improve the efficiency of the chain by making better
        proposals and forcing the acceptance rate :math:`\alpha` of
        the chain to lie in an interval ensuring good exploration:

        :param force_acceptance_max:

            Float, the upper limit (in (0,1])

            Default: :math:`\alpha_{max}=.35`


        :param force_acceptance_min:

            Float, the lower limit (in [0,1))

            Default: :math:`\alpha_{min}=.15`


        This is achieved in two steps:

        1. **Estimate the target covariance**: compute the sample
        covariance from the last (the t-th) run as :math:`S^t`
        then combine with previous estimate :math:`\Sigma^{t-1}`
        with a weight damping out over time as

        .. math::

            \Sigma^t = (1-a^t) \Sigma^{t-1} + a^t S^t

        where the weight is given by

        .. math::

            a^t = 1/t^{\lambda}.

        :param damping:

            Float, see formula above

            Default: :math:`\lambda=.5`


        The ``damping`` :math:`\lambda` is neccessary to assure
        convergence and should be in [0,1]. A default value of 0.5 was
        found to work well in practice. For details, see [HST01]_.

        2. **Rescale the covariance matrix**: Remember that the goal
        is to force the acceptance rate into a specific interval.
        Suppose that the chain already is in a region of significant
        probability mass (should be the case before adapting it).
        When the acceptance rate is close to zero, the chain cannot
        move at all; i.e., the proposed points have a low probability
        relative to the current point. In this case the proposal
        covariance should decrease to increase "locality" of the
        chain.  In the opposite case, when the acceptance rate is
        close to one, the chain most probably only explores a small
        volume of the target.  Then enlarging the covariance matrix
        decreases "locality".  In this implementation, the proposal
        covariance matrix is :math:`c \Sigma^t`

        :param covar_scale_factor:

            Float, this number ``c`` is multiplied to :math:`\Sigma^t`
            after it has been recalculated. The higher the dimension
            :math:`d`, the smaller it should be. For a Gaussian
            proposal and target, the optimal factor is
            :math:`2.38^2/d`. Use this argument to increase
            performance from the start before any adaptation.

            Default: :math:`c=2.38^2/d`


        ``covar_scale_factor`` is updated using :math:`\beta`

        :param covar_scale_multiplier:

            Float;
            if the acceptance rate is larger than ``force_acceptance_max``,
            :math:`c \to \beta c`.
            If the acceptance rate is smaller than ``force_acceptance_min``,
            :math:`c \to c / \beta`.

            Default :math:`\beta=1.5`


        Additionally, an upper and a lower limit on
        ``covar_scale_factor`` can be provided. This is useful to hint
        at bugs in the target or MC implementation that cause the
        efficiency to run away.

        :param covar_scale_factor_max:

            Float, ``covar_scale_factor`` is kept below this value.

            Default: :math:`c_{max}=100`


        :param covar_scale_factor_min:

            Float, ``covar_scale_factor`` is kept above this value.

            Default: :math:`c_{max}=10^{-4}`

def set_adapt_params(self, *args, **kwargs):
        r"""Sets variables for covariance adaptation.

        When :meth:`.adapt` is called, the proposal's covariance matrix is
        adapted in order to improve the chain's performance. The aim
        is to improve the efficiency of the chain by making better
        proposals and forcing the acceptance rate :math:`\alpha` of
        the chain to lie in an interval ensuring good exploration:

        :param force_acceptance_max:

            Float, the upper limit (in (0,1])

            Default: :math:`\alpha_{max}=.35`


        :param force_acceptance_min:

            Float, the lower limit (in [0,1))

            Default: :math:`\alpha_{min}=.15`


        This is achieved in two steps:

        1. **Estimate the target covariance**: compute the sample
        covariance from the last (the t-th) run as :math:`S^t`
        then combine with previous estimate :math:`\Sigma^{t-1}`
        with a weight damping out over time as

        .. math::

            \Sigma^t = (1-a^t) \Sigma^{t-1} + a^t S^t

        where the weight is given by

        .. math::

            a^t = 1/t^{\lambda}.

        :param damping:

            Float, see formula above

            Default: :math:`\lambda=.5`


        The ``damping`` :math:`\lambda` is neccessary to assure
        convergence and should be in [0,1]. A default value of 0.5 was
        found to work well in practice. For details, see [HST01]_.

        2. **Rescale the covariance matrix**: Remember that the goal
        is to force the acceptance rate into a specific interval.
        Suppose that the chain already is in a region of significant
        probability mass (should be the case before adapting it).
        When the acceptance rate is close to zero, the chain cannot
        move at all; i.e., the proposed points have a low probability
        relative to the current point. In this case the proposal
        covariance should decrease to increase "locality" of the
        chain.  In the opposite case, when the acceptance rate is
        close to one, the chain most probably only explores a small
        volume of the target.  Then enlarging the covariance matrix
        decreases "locality".  In this implementation, the proposal
        covariance matrix is :math:`c \Sigma^t`

        :param covar_scale_factor:

            Float, this number ``c`` is multiplied to :math:`\Sigma^t`
            after it has been recalculated. The higher the dimension
            :math:`d`, the smaller it should be. For a Gaussian
            proposal and target, the optimal factor is
            :math:`2.38^2/d`. Use this argument to increase
            performance from the start before any adaptation.

            Default: :math:`c=2.38^2/d`


        ``covar_scale_factor`` is updated using :math:`\beta`

        :param covar_scale_multiplier:

            Float;
            if the acceptance rate is larger than ``force_acceptance_max``,
            :math:`c \to \beta c`.
            If the acceptance rate is smaller than ``force_acceptance_min``,
            :math:`c \to c / \beta`.

            Default :math:`\beta=1.5`


        Additionally, an upper and a lower limit on
        ``covar_scale_factor`` can be provided. This is useful to hint
        at bugs in the target or MC implementation that cause the
        efficiency to run away.

        :param covar_scale_factor_max:

            Float, ``covar_scale_factor`` is kept below this value.

            Default: :math:`c_{max}=100`


        :param covar_scale_factor_min:

            Float, ``covar_scale_factor`` is kept above this value.

            Default: :math:`c_{max}=10^{-4}`


        """

        if args != (): raise TypeError('keyword args only; try set_adapt_parameters(keyword = value)')

        self.covar_scale_multiplier = kwargs.pop('covar_scale_multiplier' , self.covar_scale_multiplier)

        self.covar_scale_factor     = kwargs.pop('covar_scale_factor'     , self.covar_scale_factor    )
        self.covar_scale_factor_max = kwargs.pop('covar_scale_factor_max' , self.covar_scale_factor_max)
        self.covar_scale_factor_min = kwargs.pop('covar_scale_factor_min' , self.covar_scale_factor_min)

        self.force_acceptance_max   = kwargs.pop('force_acceptance_max'   , self.force_acceptance_max  )
        self.force_acceptance_min   = kwargs.pop('force_acceptance_min'   , self.force_acceptance_min  )

        self.damping                = kwargs.pop('damping'                , self.damping               )


        if not kwargs == {}: raise TypeError('unexpected keyword(s): ' + str(kwargs.keys()))