Source code for means.approximation.mea.closure_scalar

"""
Scalar moment closure
------

This part of the package provides the original
(and default) closure :class:`~means.approximation.mea.closure_scalar.ScalarClosure`
as well as the base class for all closers.

"""


import sympy as sp
from means.util.sympyhelpers import substitute_all


[docs]class ClosureBase(object): """ A virtual class for closure methods. An implementation of `_compute_raw_moments()` must be provided in subclasses. """ _max_order = None _min_order = 1 def __init__(self,max_order, multivariate=True): """ :param max_order: the maximal order of moments to be modelled. :type max_order: `int` :param multivariate: whether to consider covariances :return: """ self._max_order = max_order self.__is_multivariate = multivariate if self._min_order > max_order: raise ValueError("This closure method requires `max_order` to be >= {0}".format(self._min_order)) @property def is_multivariate(self): return self.__is_multivariate @property def max_order(self): return self._max_order def _compute_raw_moments(self, n_counter, k_counter): raise NotImplementedError("ParametricCloser is an abstract class.\ `compute_closed_raw_moments()` is not implemented. ") def _compute_closed_central_moments(self, central_from_raw_exprs, n_counter, k_counter): r""" Computes parametric expressions (e.g. in terms of mean, variance, covariances) for all central moments up to max_order + 1 order. :param central_from_raw_exprs: the expression of central moments in terms of raw moments :param n_counter: a list of :class:`~means.core.descriptors.Moment`\s representing central moments :type n_counter: list[:class:`~means.core.descriptors.Moment`] :param k_counter: a list of :class:`~means.core.descriptors.Moment`\s representing raw moments :type k_counter: list[:class:`~means.core.descriptors.Moment`] :return: the central moments where raw moments have been replaced by parametric expressions :rtype: `sympy.Matrix` """ closed_raw_moments = self._compute_raw_moments(n_counter, k_counter) assert(len(central_from_raw_exprs) == len(closed_raw_moments)) # raw moment lef hand side symbol raw_symbols = [raw.symbol for raw in k_counter if raw.order > 1] # we want to replace raw moments symbols with closed raw moment expressions (in terms of variances/means) substitution_pairs = zip(raw_symbols, closed_raw_moments) # so we can obtain expression of central moments in terms of low order raw moments closed_central_moments = substitute_all(central_from_raw_exprs, substitution_pairs) return closed_central_moments
[docs] def close(self, mfk, central_from_raw_exprs, n_counter, k_counter): """ In MFK, replaces symbol for high order (order == max_order+1) by parametric expressions. That is expressions depending on lower order moments such as means, variances, covariances and so on. :param mfk: the right hand side equations containing symbols for high order central moments :param central_from_raw_exprs: expressions of central moments in terms of raw moments :param n_counter: a list of :class:`~means.core.descriptors.Moment`\s representing central moments :type n_counter: list[:class:`~means.core.descriptors.Moment`] :param k_counter: a list of :class:`~means.core.descriptors.Moment`\s representing raw moments :type k_counter: list[:class:`~means.core.descriptors.Moment`] :return: the modified MFK :rtype: `sympy.Matrix` """ # we obtain expressions for central moments in terms of variances/covariances closed_central_moments = self._compute_closed_central_moments(central_from_raw_exprs, n_counter, k_counter) # set mixed central moment to zero iff univariate closed_central_moments = self._set_mixed_moments_to_zero(closed_central_moments, n_counter) # retrieve central moments from problem moment. Typically, :math: `[yx2, yx3, ...,yxN]`. # now we want to replace the new mfk (i.e. without highest order moment) any # symbol for highest order central moment by the corresponding expression (computed above) positive_n_counter = [n for n in n_counter if n.order > 0] substitutions_pairs = [(n.symbol, ccm) for n,ccm in zip(positive_n_counter, closed_central_moments) if n.order > self.max_order] new_mfk = substitute_all(mfk, substitutions_pairs) return new_mfk
def _set_mixed_moments_to_zero(self, closed_central_moments, n_counter): r""" In univariate case, set the cross-terms to 0. :param closed_central_moments: matrix of closed central moment :param n_counter: a list of :class:`~means.core.descriptors.Moment`\s representing central moments :type n_counter: list[:class:`~means.core.descriptors.Moment`] :return: a matrix of new closed central moments with cross-terms equal to 0 """ positive_n_counter = [n for n in n_counter if n.order > 1] if self.is_multivariate: return closed_central_moments else: return [0 if n.is_mixed else ccm for n,ccm in zip(positive_n_counter, closed_central_moments)]
[docs]class ScalarClosure(ClosureBase): """ A class providing scalar closure to :class:`~means.approximation.mea.moment_expansion_approximation.MomentExpansionApproximation`. Expression for higher order (max_order + 1) central moments are set to a scalar. Typically, higher order central moments are replaced by zero. """ def __init__(self,max_order,value=0): """ :param max_order: the maximal order of moments to be modelled. :type max_order: `int` :param value: a scalar value for higher order moments """ super(ScalarClosure, self).__init__(max_order, False) self.__value = value @property def value(self): return self.__value def _compute_closed_central_moments(self, central_from_raw_exprs, n_counter, k_counter): r""" Replace raw moment terms in central moment expressions by parameters (e.g. mean, variance, covariances) :param central_from_raw_exprs: the expression of central moments in terms of raw moments :param n_counter: a list of :class:`~means.core.descriptors.Moment`\s representing central moments :type n_counter: list[:class:`~means.core.descriptors.Moment`] :param k_counter: a list of :class:`~means.core.descriptors.Moment`\s representing raw moments :type k_counter: list[:class:`~means.core.descriptors.Moment`] :return: the central moments where raw moments have been replaced by parametric expressions :rtype: `sympy.Matrix` """ closed_central_moments = sp.Matrix([sp.Integer(self.__value)] * len(central_from_raw_exprs)) return closed_central_moments