def test_get_factorial_term(self): """ Given the tuples of integers a and b, Then, the "factorial term" should be exactly "a_result" and "b_result", respectively :return: """ a = (2, 3, 4) b = (0, 1, 6) a_expected = sp.S(1) / (sp.factorial(2) * sp.factorial(3) * sp.factorial(4)) b_expected = sp.S(1) / (sp.factorial(6)) a_result = get_one_over_n_factorial(a) b_result = get_one_over_n_factorial(b) self.assertEqual(a_expected, a_result) self.assertEqual(b_expected, b_result)
def generate_dmu_over_dt(species, propensity, n_counter, stoichiometry_matrix): r""" Calculate :math:`\frac{d\mu_i}{dt}` in eq. 6 (see Ale et al. 2013). .. math:: \frac{d\mu_i}{dt} = S \begin{bmatrix} \sum_{l} \sum_{n_1=0}^{\infty} ... \sum_{n_d=0}^{\infty} \frac{1}{\mathbf{n!}} \frac{\partial^n \mathbf{n}a_l(\mathbf{x})}{\partial \mathbf{x^n}} |_{x=\mu} \mathbf{M_{x^n}} \end{bmatrix} :param species: the name of the species/variables (typically `['y_0', 'y_1', ..., 'y_n']`) :type species: list[`sympy.Symbol`] :param propensity: the reactions describes by the model :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 stoichiometry_matrix: the stoichiometry matrix :type stoichiometry_matrix: `sympy.Matrix` :return: a matrix in which each row corresponds to a reaction, and each column to an element of counter. """ # compute derivatives :math:`\frac{\partial^n \mathbf{n}a_l(\mathbf{x})}{\partial \mathbf{x^n}}` # for EACH REACTION and EACH entry in COUNTER derives =[derive_expr_from_counter_entry(reac, species, c.n_vector) for (reac, c) in itertools.product(propensity, n_counter)] # Computes the factorial terms (:math:`\frac{1}{\mathbf{n!}}`) for EACH REACTION and EACH entry in COUNTER # this does not depend of the reaction, so we just repeat the result for each reaction factorial_terms = [get_one_over_n_factorial(tuple(c.n_vector)) for c in n_counter] * len(propensity) # we make a matrix in which every element is the entry-wise multiplication of `derives` and factorial_terms taylor_exp_matrix = sp.Matrix(len(propensity), len(n_counter), [d*f for (d, f) in zip(derives, factorial_terms)]) # dmu_over_dt is the product of the stoichiometry matrix by the taylor expansion matrix return stoichiometry_matrix * taylor_exp_matrix
def _make_f_expectation(self, expr): """ Calculates :math:`<F>` in eq. 12 (see Ale et al. 2013) to calculate :math:`<F>` for EACH VARIABLE combination. :param expr: an expression :return: a column vector. Each row correspond to an element of counter. :rtype: :class:`sympy.Matrix` """ # compute derivatives for EACH ENTRY in COUNTER derives = sp.Matrix([ derive_expr_from_counter_entry(expr, self.__species, tuple(c.n_vector)) for c in self.__n_counter ]) # Computes the factorial terms for EACH entry in COUNTER factorial_terms = sp.Matrix([ get_one_over_n_factorial(tuple(c.n_vector)) for c in self.__n_counter ]) # Element wise product of the two vectors te_vector = derives.multiply_elementwise(factorial_terms) return te_vector
def _make_f_expectation(self, expr): """ Calculates :math:`<F>` in eq. 12 (see Ale et al. 2013) to calculate :math:`<F>` for EACH VARIABLE combination. :param expr: an expression :return: a column vector. Each row correspond to an element of counter. :rtype: :class:`sympy.Matrix` """ # compute derivatives for EACH ENTRY in COUNTER derives = sp.Matrix([derive_expr_from_counter_entry(expr, self.__species, tuple(c.n_vector)) for c in self.__n_counter]) # Computes the factorial terms for EACH entry in COUNTER factorial_terms = sp.Matrix([get_one_over_n_factorial(tuple(c.n_vector)) for c in self.__n_counter]) # Element wise product of the two vectors te_vector= derives.multiply_elementwise(factorial_terms) return te_vector
def generate_dmu_over_dt(species, propensity, n_counter, stoichiometry_matrix): r""" Calculate :math:`\frac{d\mu_i}{dt}` in eq. 6 (see Ale et al. 2013). .. math:: \frac{d\mu_i}{dt} = S \begin{bmatrix} \sum_{l} \sum_{n_1=0}^{\infty} ... \sum_{n_d=0}^{\infty} \frac{1}{\mathbf{n!}} \frac{\partial^n \mathbf{n}a_l(\mathbf{x})}{\partial \mathbf{x^n}} |_{x=\mu} \mathbf{M_{x^n}} \end{bmatrix} :param species: the name of the species/variables (typically `['y_0', 'y_1', ..., 'y_n']`) :type species: list[`sympy.Symbol`] :param propensity: the reactions describes by the model :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 stoichiometry_matrix: the stoichiometry matrix :type stoichiometry_matrix: `sympy.Matrix` :return: a matrix in which each row corresponds to a reaction, and each column to an element of counter. """ # compute derivatives :math:`\frac{\partial^n \mathbf{n}a_l(\mathbf{x})}{\partial \mathbf{x^n}}` # for EACH REACTION and EACH entry in COUNTER derives = [ derive_expr_from_counter_entry(reac, species, c.n_vector) for (reac, c) in itertools.product(propensity, n_counter) ] # Computes the factorial terms (:math:`\frac{1}{\mathbf{n!}}`) for EACH REACTION and EACH entry in COUNTER # this does not depend of the reaction, so we just repeat the result for each reaction factorial_terms = [ get_one_over_n_factorial(tuple(c.n_vector)) for c in n_counter ] * len(propensity) # we make a matrix in which every element is the entry-wise multiplication of `derives` and factorial_terms taylor_exp_matrix = sp.Matrix( len(propensity), len(n_counter), [d * f for (d, f) in zip(derives, factorial_terms)]) # dmu_over_dt is the product of the stoichiometry matrix by the taylor expansion matrix return stoichiometry_matrix * taylor_exp_matrix