예제 #1
0
def convert_add(add):
    if add.ADD():
        lh = convert_add(add.additive(0))
        rh = convert_add(add.additive(1))
        return sympy.Add(lh, rh, evaluate=False)
    elif add.SUB():
        lh = convert_add(add.additive(0))
        rh = convert_add(add.additive(1))
        return sympy.Add(lh, sympy.Mul(-1, rh, evaluate=False), evaluate=False)
    else:
        return convert_mp(add.mp())
예제 #2
0
 def symbolic_shape(self):
     """
     The symbolic shape of the object. This includes the domain, halo, and
     padding regions. While halo and padding are known quantities (integers),
     the domain size is given as a symbol.
     """
     halo = [sympy.Add(*i, evaluate=False) for i in self._size_halo]
     padding = [sympy.Add(*i, evaluate=False) for i in self._size_padding]
     domain = [i.symbolic_size for i in self.dimensions]
     ret = tuple(sympy.Add(i, j, k, evaluate=False)
                 for i, j, k in zip(domain, halo, padding))
     return DimensionTuple(*ret, getters=self.dimensions)
예제 #3
0
def convert_add(add):
    if add.ADD():
        lh = convert_add(add.additive(0))
        rh = convert_add(add.additive(1))
        return sympy.Add(lh, rh, evaluate=False)
    elif add.SUB():
        lh = convert_add(add.additive(0))
        rh = convert_add(add.additive(1))
        # return sympy.Add(lh, -1 * rh, evaluate=False)
        # just keep the origin expression, don't simplify
        return sympy.Add(lh, sympy.Mul(-1, rh, evaluate=False), evaluate=False)
    else:
        return convert_mp(add.mp())
예제 #4
0
    def __generate_elementary_modes_via_fixed_size_constraint(self):
        fixed_size_constraint = self.model.solver.interface.Constraint(
            sympy.Add(*self.indicator_variables),
            name='fixed_size_constraint',
            lb=1,
            ub=1)
        self.model.solver._add_constraint(fixed_size_constraint, sloppy=True)

        while True:
            logger.debug("Looking for solutions with cardinality " +
                         str(fixed_size_constraint.lb))
            try:
                self.model.solver.problem.populate_solution_pool()
            except Exception as e:
                raise e
            solution_num = self.model.solver.problem.solution.pool.get_num()
            if solution_num > 0:
                exclusion_lists = list()
                for i in range(solution_num):
                    elementary_flux_mode = list()
                    exclusion_list = list()
                    problem_solution = self.model.solver.problem.solution
                    for reaction in self._reactions:
                        if problem_solution.pool.get_values(
                                i,
                                reaction._indicator_variable_fwd.name) >= 0.9:
                            reaction_copy = copy(reaction)
                            reaction_copy.lower_bound = 0
                            elementary_flux_mode.append(reaction_copy)
                            exclusion_list.append(
                                reaction._indicator_variable_fwd)
                        elif problem_solution.pool.get_values(
                                i,
                                reaction._indicator_variable_rev.name) >= 0.9:
                            reaction_copy = copy(reaction)
                            reaction_copy.upper_bound = 0
                            elementary_flux_mode.append(reaction_copy)
                            exclusion_list.append(
                                reaction._indicator_variable_rev)
                    exclusion_lists.append(exclusion_list)
                    yield elementary_flux_mode
                for exclusion_list in exclusion_lists:
                    exclusion_constraint = self.model.solver.interface.Constraint(
                        sympy.Add(*exclusion_list), ub=len(exclusion_list) - 1)
                    self.model.solver._add_constraint(exclusion_constraint,
                                                      sloppy=True)
            new_fixed_size = fixed_size_constraint.ub + 1
            if new_fixed_size > len(self._reactions):
                break
            fixed_size_constraint.ub, fixed_size_constraint.lb = new_fixed_size, new_fixed_size
예제 #5
0
 def symbolic_shape(self):
     """
     Return the symbolic shape of the object. This includes the padding,
     halo, and domain regions. While halo and padding are known quantities
     (integers), the domain size is represented by a symbol.
     """
     halo_sizes = [sympy.Add(*i, evaluate=False) for i in self._extent_halo]
     padding_sizes = [
         sympy.Add(*i, evaluate=False) for i in self._extent_padding
     ]
     domain_sizes = [i.symbolic_size for i in self.indices]
     return tuple(
         sympy.Add(i, j, k, evaluate=False)
         for i, j, k in zip(domain_sizes, halo_sizes, padding_sizes))
예제 #6
0
    def generatef():
        z = sympy.Symbol("z")
        # The k is mapped to the positive and negative powers of exp, respectively.
        # Note that some implementations of the fft gives the order differently. I had to use examples to figure out how this one worked.
        pos_terms = lambda k: sympy.exp(k * sympy.I * z) * coefs[k]
        neg_terms = lambda k: sympy.exp((k - N) * sympy.I * z) * coefs[k]

        # The first part of the function is the summation of the positive powers of exp, and the last part is the summation of the negative powers.
        first = sympy.Add(*map(pos_terms, range(0, N // 2 + 1)))
        last = sympy.Add(*map(neg_terms, range(N // 2 + 1, N)))

        # The function C^2 -> C^2 that graphs the orbit is finally scaled.
        f = sympy.Add(first, last) / N
        print "f(z) = ", f,
예제 #7
0
    def check_quadratic_equations(self):
        # Look for something quadratic to solve 'x^2 * (u) + x * (v) + (w) = 0'
        for eq in self.cl_eqs:
            eq_expand = sp.expand(eq)
            if not eq_expand.is_Add:
                continue

            for x in [ s for s in eq_expand.free_symbols if s in self.vars and sp.degree(eq_expand, s) == 2]:                
                w = sp.Add(*[ t for t in eq_expand.args if x not in t.free_symbols ])
                v = sp.cancel(sp.Add(*[ t for t in eq_expand.args if sp.degree(t, x) == 1 ]) / x)
                u = sp.cancel((eq_expand - w - v * x) / x**2)
                
                # The discriminant must be a square, otherwise the isomorphism we want to setup is not an algebraic map!
                discr = v**2 - 4*u*w
                sqrt_D = is_square(discr)
                if sqrt_D == None:
                    continue
                
                # Case (u) = 0:
                if u.is_complex:
                    c_u_is_zero = 0
                else:
                    c_u_is_zero = System(self.vars, [ e for e in self.cl_eqs if e != eq ] + [ u, x * v + w ], self.op_eqs).compute_class()
                    if c_u_is_zero == None:
                        continue
                
                # Case (u) != 0:
                # Case A: discr = 0 and x = -v / (2 * u)
                c_A_cl_eqs = [ eq_subs_by_fraction(e, x, -v, 2*u) for e in self.cl_eqs if e != eq ] + [ discr ]
                c_A_op_eqs = [ eq_subs_by_fraction(e, x, -v, 2*u) for e in self.op_eqs ] + [ u ]
                c_A = System(self.vars.difference({x,}), c_A_cl_eqs, c_A_op_eqs).compute_class()
                if c_A == None:
                    continue
                # Case B: discr != 0 and x = (-v + sqrt_D) / (2 * u)
                c_B_cl_eqs = [ eq_subs_by_fraction(e, x, -v + sqrt_D, 2*u) for e in self.cl_eqs if e != eq ]
                c_B_op_eqs = [ eq_subs_by_fraction(e, x, -v + sqrt_D, 2*u) for e in self.op_eqs ] + [ u, discr ]
                c_B = System(self.vars.difference({x,}), c_B_cl_eqs, c_B_op_eqs).compute_class()
                if c_B == None:
                    continue
                # Case C: discr != 0 and x = (-v - sqrt_D) / (2 * u)
                c_C_cl_eqs = [ eq_subs_by_fraction(e, x, -v - sqrt_D, 2*u) for e in self.cl_eqs if e != eq ]
                c_C_op_eqs = [ eq_subs_by_fraction(e, x, -v - sqrt_D, 2*u) for e in self.op_eqs ] + [ u, discr ]
                c_C = System(self.vars.difference({x,}), c_C_cl_eqs, c_C_op_eqs).compute_class()
                if c_C == None:
                    continue
                    
                return c_u_is_zero + c_A + c_B + c_C
            
        return None
예제 #8
0
    def appendTwoPointsRestriction(self):  # Ограничение совпадение двух точек

        self.oldPoints = self.Points.copy()
        ind_point = []
        for i in range(len(self.chsTwoPoint)):
            ind_point.append(self.pointsFlatten.index(self.chsTwoPoint[i]))
        self.chsTwoPoint.clear()
        list_of_la.append(globals()['la%s' % str(self.counter_la)])
        self.function_with_restriction.append(sp.Mul(list_of_la[self.counter_la],
                                                     list_of_sym_coord[ind_point[2]] - list_of_sym_coord[ind_point[0]]))
        self.counter_la += 1
        list_of_la.append(globals()['la%s' % str(self.counter_la)])  # Добавили новую лямбду в массив всех текущих лябмд
        self.function_with_restriction.append(sp.Mul(list_of_la[self.counter_la],
                                                     list_of_sym_coord[ind_point[3]] - list_of_sym_coord[ind_point[1]]))
        self.counter_la += 1
        list_of_la.append(globals()['la%s' % str(self.counter_la)])
        self.function_with_restriction.append(sp.Mul(list_of_la[self.counter_la],
                                                     list_of_sym_coord[ind_point[2]] - self.pointsFlatten[ind_point[2]]))
        self.counter_la += 1
        list_of_la.append(globals()['la%s' % str(self.counter_la)])
        self.function_with_restriction.append(sp.Mul(list_of_la[self.counter_la],
                                                     list_of_sym_coord[ind_point[3]] - self.pointsFlatten[ind_point[3]]))
        self.counter_la += 1
        #self.function_with_restriction = sp.Add(*self.function_with_restriction)
        #print("hh", self.function_with_restriction)
        #print("jjj", self.function_no_restriction)
        self.Restriction = sp.Add(sp.Add(*self.function_with_restriction), sp.Add(*self.function_no_restriction))  # Сложили две части уравнений
        print("Current function: ", self.Restriction)
        list_of_sym = list_of_sym_coord + list_of_la
        print("List of sym = ", list_of_sym)
        list_diff = list(sp.diff(self.Restriction, x) for x in list_of_sym)  # Находим производные для функции
        # по всем символьным переменным
        print(list_diff)
        cur_point = sp.solve(list_diff, list(list_of_sym))  # Здесь решили уравнение и получили новое значение в виде словаря,
        print(cur_point)
        # надо откинуть лямбды

        cur_point_without_lambda = []
        i = 0
        while i < len(list_of_sym_coord):
            cur_two_coord = []
            cur_two_coord.append(cur_point.get(list_of_sym[i]))
            cur_two_coord.append(cur_point.get(list_of_sym[i+1]))
            cur_point_without_lambda.append(cur_two_coord)
            i += 2
        for i in range(len(cur_point_without_lambda)):
            #self.Points[i] = cur_point_without_lambda[i]
            self.repaintByPoint(self.Points[i][0],self.Points[i][1],cur_point_without_lambda[i][0],cur_point_without_lambda[i][1])
        print("New points: ", self.Points)
예제 #9
0
def add_flat(lh, rh):
    if hasattr(lh, 'is_Add') and lh.is_Add or hasattr(rh,
                                                      'is_Add') and rh.is_Add:
        args = []
        if hasattr(lh, 'is_Add') and lh.is_Add:
            args += list(lh.args)
        else:
            args += [lh]
        if hasattr(rh, 'is_Add') and rh.is_Add:
            args = args + list(rh.args)
        else:
            args += [rh]
        return sympy.Add(*args, evaluate=False)
    else:
        return sympy.Add(lh, rh, evaluate=False)
예제 #10
0
파일: response.py 프로젝트: zoidy/puq
    def simplify(self, sig=1e-6, debug=False):
        """
        Simplify a polynomial response function by removing less significant terms.
        This returns a new copy of the response function and does not update the
        original one.

        Args:
          sig(float): Significance.  Default is 1.0e-6.
        Returns:
          New response equation.

        .. note::
            May reduce accuracy of response surface.  Use
            with care.
        """
        import itertools
        if not self.eqn.is_polynomial():
            return self.eqn
        ranges = [y for _x, y in self.vars]
        terms = []
        if not isinstance(self.eqn, sympy.Add):
            return self.eqn
        for term in self.eqn.args:
            mabs = 0
            for p in itertools.product(*ranges):
                res = abs(term.subs(zip(self.vnames, p)))
                if res > mabs:
                    mabs = res
            if debug:
                print "%s\t has maximum of %s" % (term, mabs)
            terms.append((term, mabs))
        maxval = max([val for _t, val in terms])
        eqn = sympy.Add(*[t for t, val in terms if val/maxval > sig])
        return sympy.simplify(eqn)
예제 #11
0
def sum(A_expr, axis=None):

    assert axis is None or axis == 0 or axis == 1
    if axis is None:
        A_sum_expr = sympy.Add(*A_expr)
        return A_sum_expr
    if axis == 0:
        A_sum_expr = sympy.Matrix.zeros(1, A_expr.cols)
        for c in range(A_expr.cols):
            A_sum_expr[0, c] = sympy.Add(*A_expr[:, c])
        return A_sum_expr
    if axis == 1:
        A_sum_expr = sympy.Matrix.zeros(A_expr.rows, 1)
        for r in range(A_expr.rows):
            A_sum_expr[r, 0] = sympy.Add(*A_expr[r, :])
        return A_sum_expr
예제 #12
0
def create_milp_problem(kernel, metabolites, Model, Variable, Constraint,
                        Objective):
    """
    Create the MILP as defined by equation (13) in [1]_.

    Parameters
    ----------
    kernel : numpy.array
        A 2-dimensional array that represents the left nullspace of the
        stoichiometric matrix which is the nullspace of the transpose of the
        stoichiometric matrix.
    metabolites : iterable
        The metabolites in the nullspace. The length of this vector must equal
        the first dimension of the nullspace.
    Model : optlang.Model
        Model class for a specific optlang interface.
    Variable : optlang.Variable
        Variable class for a specific optlang interface.
    Constraint : optlang.Constraint
        Constraint class for a specific optlang interface.
    Objective : optlang.Objective
        Objective class for a specific optlang interface.

    References
    ----------
    .. [1] Gevorgyan, A., M. G Poolman, and D. A Fell.
           "Detection of Stoichiometric Inconsistencies in Biomolecular
           Models."
           Bioinformatics 24, no. 19 (2008): 2245.

    """
    assert len(metabolites) == kernel.shape[0],\
        "metabolite vector and first nullspace dimension must be equal"
    ns_problem = Model()
    k_vars = list()
    for met in metabolites:
        # The element y[i] of the mass vector.
        y_var = Variable(met.id)
        k_var = Variable("k_{}".format(met.id), type="binary")
        k_vars.append(k_var)
        ns_problem.add([y_var, k_var])
        # This constraint is equivalent to 0 <= y[i] <= k[i].
        ns_problem.add(Constraint(
            y_var - k_var, ub=0, name="switch_{}".format(met.id)))
    ns_problem.update()
    # add nullspace constraints
    for (j, column) in enumerate(kernel.T):
        expression = sympy.Add(
            *[coef * ns_problem.variables[met.id]
              for (met, coef) in zip(metabolites, column) if coef != 0.0])
        constraint = Constraint(expression, lb=0, ub=0,
                                name="ns_{}".format(j))
        ns_problem.add(constraint)
    # The objective is to minimize the binary indicators k[i], subject to
    # the above inequality constraints.
    ns_problem.objective = Objective(1)
    ns_problem.objective.set_linear_coefficients(
        {k_var: 1. for k_var in k_vars})
    ns_problem.objective.direction = "min"
    return ns_problem, k_vars
예제 #13
0
def add_cut(problem, indicators, bound, Constraint):
    """
    Add an integer cut to the problem.

    Ensure that the same solution involving these indicator variables cannot be
    found by enforcing their sum to be less than before.

    Parameters
    ----------
    problem : optlang.Model
        Specific optlang interface Model instance.
    indicators : iterable
        Binary indicator `optlang.Variable`s.
    bound : int
        Should be one less than the sum of indicators. Corresponds to P - 1 in
        equation (14) in [1]_.
    Constraint : optlang.Constraint
        Constraint class for a specific optlang interface.

    References
    ----------
    .. [1] Gevorgyan, A., M. G Poolman, and D. A Fell.
           "Detection of Stoichiometric Inconsistencies in Biomolecular
           Models."
           Bioinformatics 24, no. 19 (2008): 2245.

    """
    cut = Constraint(sympy.Add(*indicators), ub=bound)
    problem.add(cut)
    return cut
예제 #14
0
 def testAdd(self):
     self.compare(
         mathics.Expression(
             'Plus', mathics.Integer(1), mathics.Symbol('Global`x')),
         sympy.Add(
             sympy.Integer(1),
             sympy.Symbol('_Mathics_User_Global`x')))
예제 #15
0
def wiener_filtering(complex_field: Field, output_weight_field: Field, sigma):
    assert complex_field.index_dimensions == 3
    assert output_weight_field.index_dimensions == 1

    assignments = []

    norm_factor = complex_field.index_shape[0] * complex_field.index_shape[1]
    wiener_sum = []

    for stack_index in range(complex_field.index_shape[0]):
        for patch_index in range(complex_field.index_shape[1]):

            magnitude = sum(complex_field.center(stack_index, patch_index, i) ** 2 for i in (0, 1))
            val = magnitude / norm_factor  # implementation differ whether to apply norm_factor on val on wien
            wien = val / (val + sigma * sigma)

            wiener_sum.append(wien**2)

            assignments.extend(
                pystencils.Assignment(complex_field.center(stack_index, patch_index, i),
                                      complex_field.center(stack_index, patch_index, i) * wien)
                for i in (0, 1)
            )

        assignments.append(pystencils.Assignment(
            output_weight_field.center(stack_index), 1 / sympy.Add(*wiener_sum)
        ))

    return AssignmentCollection(assignments)
예제 #16
0
 def _print_Add(self, expr):
     args = expr.args
     new = []
     for arg in args:
         new.append(self._print(arg))
     return super()._print_Add(sympy.Add(*args, evaluate=False),
                               order='none')
예제 #17
0
def single_block_matching(
    input_field: Field,
    comparision_field: Field,
    output_block_scores: Field,
    block_stencil,
    matching_offset,
    match_index,
    matching_function=pystencils_reco.functions.squared_difference,
):

    assignments = []

    i, m = match_index, matching_offset
    rhs = []

    for s in block_stencil:
        shifted = tuple(i + j for i, j in zip(s, m))
        rhs.append(
            matching_function(input_field[s], comparision_field[shifted]))

    lhs = output_block_scores(i)
    assignment = pystencils.Assignment(lhs, sympy.Add(*rhs))
    assignments.append(assignment)

    return AssignmentCollection(assignments, perform_cse=False)
def MLE_(a_i,t_i,s_i):
    l, p, m1, m2 = sym.symbols('l,p,m1,m2', positive=True)

    L1 = p ** a * (1 - p) ** (1 - a)
    J1 = np.prod([L1.subs(a, i) for i in a_i])
    print(J1)

    L2 = l * sym.exp(-l * t)
    J2 = np.prod([L2.subs(t, i) for i in t_i])
    print(J2)

    L3 = sym.Add((1 - a) * m1 * sym.exp(-m1 * s), a * m2 * sym.exp(-m2 * s))
    J3 = np.prod([L3.subs({a: i, s: s_i[j]}) for j, i in enumerate(a_i)])
    print(J3)
    print(sym.expand_log(sym.log(J3)))
    logJ = sym.expand_log(sym.log(J1 * J2 * J3))
    print(logJ)

    sol_p = float(sym.solve(sym.diff(logJ, p), p)[0])
    sol_l = float(sym.solve(sym.diff(logJ, l), l)[0])
    sol_m1 = float(sym.solve(sym.diff(logJ, m1), m1)[0])
    sol_m2 = float(sym.solve(sym.diff(logJ, m2), m2)[0])

    print(sol_p, sol_l, sol_m1, sol_m2)
    return sol_p, sol_l, sol_m1, sol_m2
예제 #19
0
def hard_thresholding(complex_field: Field, output_weight_field, threshold):
    assert complex_field.index_dimensions == 3
    assert output_weight_field.index_dimensions == 1

    assignments = []

    for stack_index in range(complex_field.index_shape[0]):
        num_nonzeros = []
        for patch_index in range(complex_field.index_shape[1]):

            magnitude = sum(complex_field.center(stack_index, patch_index, i) ** 2 for i in (0, 1))
            assignments.extend(
                pystencils.Assignment(complex_field.center(stack_index, patch_index, i),
                                      sympy.Piecewise(
                    (complex_field.center(stack_index, patch_index, i),
                     magnitude > threshold ** 2), (0, True)))
                for i in (0, 1)
            )
            num_nonzeros.append(sympy.Piecewise((1, magnitude > threshold ** 2), (0, True)))

        assignments.append(pystencils.Assignment(
            output_weight_field.center(stack_index), sympy.Add(*num_nonzeros)
        ))

    return AssignmentCollection(assignments)
예제 #20
0
파일: response.py 프로젝트: wang159/puq
    def trunc(self, digits=6):
        """
        Truncates coefficients of the response equation to a certain number of digits.
        This returns a new copy of the response function and does not update the
        original one.

        Args:
          digits: How many significant digits to keep.
          Default is 6.

        Returns:
          New response equation.

        .. note::
            May reduce accuracy of response surface.  Use with care.
        """
        if not isinstance(self._eqn, sympy.Add):
            return self._eqn
        print[t.as_coeff_Mul() for t in self._eqn.args]
        print[(t.as_coeff_Mul()[0].evalf(digits), t.as_coeff_Mul()[1])
              for t in self._eqn.args]
        return sympy.Add(*[
            sympy.Mul(t.as_coeff_Mul()[0].evalf(digits),
                      t.as_coeff_Mul()[1]) for t in self._eqn.args
        ])
예제 #21
0
 def __buildProp(self, variables):
     diffs = [_sp.diff(self.__func, symb) for symb in self.__variables]
     tmp = diffs[0]**2
     for diff, deltas in zip(diffs, self.__errorSymbs):
         tmp = _sp.Add(tmp, _sp.MatMul(diff**2, deltas**2))
     return (tmp - diffs[0]**2)**(
         1 / 2)  # propagation assuming no correlations between errors
예제 #22
0
    def integrals_solving_possibilities(self) -> List['Expression']:

        integrals = []
        for exp in preorder_traversal(self.sympy_expr):
            exp = Expression(exp)
            if exp.is_integral():
                integrals.append(exp)

        possibilities = []
        for integral in integrals:
            applied_integral = integral.apply_integral()

            # without integral constant
            integral_solved = self.get_copy()
            integral_solved.replace(integral, applied_integral)
            possibilities.append(integral_solved)

            # with integral constant
            integral_solved = self.get_copy()
            integral_solved.replace(integral, applied_integral)
            c = sympy.symbols('c')
            expression_with_constant = Expression(
                sympy.Add(integral_solved.sympy_expr, c))
            possibilities.append(expression_with_constant)

        return possibilities
예제 #23
0
    def __init__(self, constants, embeddings, bottom_embedding, dry_run=False):
        self._operands = list(constants)
        self._embeddings = [embedding for embedding in embeddings]

        # number of unknown variables
        self._n_nuknown = 0

        # stack which stores (val, embed) tuples
        self._stack = []

        # equations got from applying `=` on the stack
        self._equations = []
        self.stack_log = []

        # functions operate on value
        self._val_funcs = {
            OPERATIONS.ADD: sympy.Add,
            OPERATIONS.SUB: lambda a, b: sympy.Add(-a, b),
            OPERATIONS.MUL: sympy.Mul,
            OPERATIONS.DIV: lambda a, b: sympy.Mul(1 / a, b)
        }
        self._op_chars = {
            OPERATIONS.ADD: '+',
            OPERATIONS.SUB: '-',
            OPERATIONS.MUL: '*',
            OPERATIONS.DIV: '/',
            OPERATIONS.EQL: '='
        }

        self._bottom_embed = bottom_embedding

        if dry_run:
            self.apply = self.apply_embed_only
예제 #24
0
def parameter_term(expression, symbol):
    """
    Determine the term, e.g. T*log(T) that belongs to the symbol in expression

    Parameters
    ----------
    expression :
    symbol :

    Returns
    -------

    """
    if expression == symbol:
        # the parameter is the symbol, so the multiplicative term is 1.
        term = 1
    else:
        if isinstance(expression, sympy.Piecewise):
            expression = expression.args[0][0]
        if isinstance(expression, sympy.Symbol):
            # this is not mathematically correct, but we just need to be able to split it into args
            expression = sympy.Add(expression, 1)
        if not isinstance(expression, sympy.Add):
            raise ValueError('Parameter {} is a {} not a sympy.Add or a Piecewise Add'.format(expression, type(expression)))

        expression_terms = expression.args
        term = None
        for term_coeff in expression_terms:
            coeff, root = term_coeff.as_coeff_mul(symbol)
            if root == (symbol,):
                term = coeff
                break
    if term is None:
        raise ValueError('No multiplicative terms found for Symbol {} in parameter {}'.format(symbol, expression))
    return term
예제 #25
0
def jacobi(dst, src):
    assert dst.spatial_dimensions == src.spatial_dimensions
    assert src.index_dimensions == 0 and dst.index_dimensions == 0
    neighbors = []
    for d in range(src.spatial_dimensions):
        neighbors += [src.neighbor(d, offset) for offset in (1, -1)]
    return ps.Assignment(dst.center, sp.Add(*neighbors) / len(neighbors))
예제 #26
0
    def constitutive_relations(self):

        if not self.components:
            return []

        coords, mappings, lin_op, nlin_op, constraints = self.system_model()
        inv_tm, inv_js, _ = mappings
        out_ports = [idx for p, idx in inv_js.items() if p in self.ports]
        logger.debug("Getting IO ports: %s", out_ports)
        network_size = len(inv_js)  # number of ports
        n = len(inv_tm)  # number of state space coords

        coord_vect = sp.Matrix(coords)
        relations = [
            sp.Add(l, r)
            for i, (l, r) in enumerate(zip(lin_op * coord_vect, nlin_op))
            if not n <= i < n + 2 * (network_size - len(out_ports))  # noqa
        ]
        if isinstance(constraints, list):
            for constraint in constraints:
                logger.debug("Adding constraint %s", repr(constraint))
                if constraint:
                    relations.append(constraint)
        else:
            logger.warning("Constraints %s is not a list. Discarding",
                           repr(constraints))
        subs = []

        for local_idx, c_idx in enumerate(out_ports):
            p, = {pp for pp in self.ports if pp.index == local_idx}
            label = p.index
            subs.append(sp.symbols((f"e_{c_idx}", f"e_{label}")))
            subs.append(sp.symbols((f"f_{c_idx}", f"f_{label}")))

        return [r.subs(subs).simplify().nsimplify() for r in relations if r]
예제 #27
0
def convert_postfix(postfix):
    if hasattr(postfix, 'exp'):
        exp_nested = postfix.exp()
    else:
        exp_nested = postfix.exp_nofunc()

    exp = convert_exp(exp_nested)
    for op in postfix.postfix_op():
        if op.BANG():
            if isinstance(exp, list):
                raise LaTeXParsingError("Cannot apply postfix to derivative")
            exp = sympy.factorial(exp, evaluate=False)
        elif op.eval_at():
            ev = op.eval_at()
            at_b = None
            at_a = None
            if ev.eval_at_sup():
                at_b = do_subs(exp, ev.eval_at_sup())
            if ev.eval_at_sub():
                at_a = do_subs(exp, ev.eval_at_sub())
            if at_b is not None and at_a is not None:
                exp = sympy.Add(at_b, -1 * at_a, evaluate=False)
            elif at_b is not None:
                exp = at_b
            elif at_a is not None:
                exp = at_a

    return exp
예제 #28
0
    def check_linear_equations(self):
        # Look for something of the form 'x * (w) + (u) = 0' with x not in (w), (u)
        for eq in self.cl_eqs:
            eq_expand = sp.expand(eq)
            if not eq_expand.is_Add:
                continue

            for x in [ s for s in eq_expand.free_symbols if s in self.vars and sp.degree(eq_expand, s) == 1]:
                u = sp.Add(*[ t for t in eq_expand.args if x not in t.free_symbols ])
                w = sp.expand((eq_expand - u) / x)
                
                # Now either (w) = 0 (implying (u) = 0 as well):
                if w.is_complex:
                    c_1 = 0
                else:
                    c_1 = System(self.vars, [ e for e in self.cl_eqs if e != eq ] + [ w, u ], self.op_eqs).compute_class()
                    if c_1 == None:
                        continue

                # Or (w) != 0 and we can use the equation to solve for x = -u / w:
                c_2_cl_eqs = [ eq_subs_by_fraction(e, x, -u, w) for e in self.cl_eqs if e != eq ]
                c_2_op_eqs = [ eq_subs_by_fraction(e, x, -u, w) for e in self.op_eqs ] + [ w ]
                c_2 = System(self.vars.difference({x,}), c_2_cl_eqs, c_2_op_eqs).compute_class()
                if c_2 == None:
                    continue
                return c_1 + c_2
            
        return None
예제 #29
0
def expand_diff_products(expr):
    """Fully expands all derivatives by applying product rule"""
    if isinstance(expr, Diff):
        arg = expand_diff_products(expr.args[0])
        if arg.func == sp.Add:
            new_args = [
                Diff(e, target=expr.target, superscript=expr.superscript)
                for e in arg.args
            ]
            return sp.Add(*new_args)
        if arg.func not in (sp.Mul, sp.Pow):
            return Diff(arg, target=expr.target, superscript=expr.superscript)
        else:
            prod_list = normalize_product(arg)
            result = 0
            for i in range(len(prod_list)):
                pre_factor = prod(prod_list[j] for j in range(len(prod_list))
                                  if i != j)
                result += pre_factor * Diff(prod_list[i],
                                            target=expr.target,
                                            superscript=expr.superscript)
            return result
    else:
        new_args = [expand_diff_products(e) for e in expr.args]
        return expr.func(*new_args) if new_args else expr
예제 #30
0
def apply_wieners(complex_field: Field, wieners: Field, output_weight_field: Field):
    assert complex_field.index_dimensions == 3
    assert wieners.index_dimensions == 2
    assert output_weight_field.index_dimensions == 1

    assignments = []
    wiener_sum = []

    for stack_index in range(complex_field.index_shape[0]):
        for patch_index in range(complex_field.index_shape[1]):

            wien = wieners(stack_index, patch_index)

            wiener_sum.append(wien**2)

            assignments.extend(
                pystencils.Assignment(complex_field.center(stack_index, patch_index, i),
                                      complex_field.center(stack_index, patch_index, i) * wien)
                for i in (0, 1)
            )

        assignments.append(pystencils.Assignment(
            output_weight_field.center(stack_index), 1 / sympy.Add(*wiener_sum)
        ))

    return AssignmentCollection(assignments)