Example #1
0
def pow_to_mul(expr):
    if expr.is_Atom or expr.is_Indexed:
        return expr
    elif expr.is_Pow:
        base, exp = expr.as_base_exp()
        if exp <= 0 or not exp.is_integer:
            # Cannot handle powers containing non-integer non-positive exponents
            return expr
        else:
            return sympy.Mul(*[base] * exp, evaluate=False)
    else:
        return expr.func(*[pow_to_mul(i) for i in expr.args], evaluate=False)
Example #2
0
def my_sympify(expr, normphase=False, matrix=False, abcsym=False, do_qubit=False, symtab=None):
    # make all lowercase real?
    if symtab:
        varset = symtab
    else:
        varset = {'p': sympy.Symbol('p'),
                  'g': sympy.Symbol('g'),
                  'e': sympy.E,			# for exp
                  'i': sympy.I,			# lowercase i is also sqrt(-1)
                  'Q': sympy.Symbol('Q'),	 # otherwise it is a sympy "ask key"
                  'I': sympy.Symbol('I'),	 # otherwise it is sqrt(-1)
                  'N': sympy.Symbol('N'),	 # or it is some kind of sympy function
                  #'X':sympy.sympify('Matrix([[0,1],[1,0]])'),
                  #'Y':sympy.sympify('Matrix([[0,-I],[I,0]])'),
                  #'Z':sympy.sympify('Matrix([[1,0],[0,-1]])'),
                  'ZZ': sympy.Symbol('ZZ'),	 # otherwise it is the PythonIntegerRing
                  'XI': sympy.Symbol('XI'),	 # otherwise it is the capital \XI
                  'hat': sympy.Function('hat'),	 # for unit vectors (8.02)
                  }
    if do_qubit:		# turn qubit(...) into Qubit instance
        varset.update({'qubit': sympy.physics.quantum.qubit.Qubit,
                       'Ket': sympy.physics.quantum.state.Ket,
                       'dot': dot,
                       'bit': sympy.Function('bit'),
                       })
    if abcsym:			# consider all lowercase letters as real symbols, in the parsing
        for letter in string.lowercase:
            if letter in varset:	 # exclude those already done
                continue
            varset.update({letter: sympy.Symbol(letter, real=True)})

    sexpr = sympify(expr, locals=varset)
    if normphase:	 # remove overall phase if sexpr is a list
        if type(sexpr) == list:
            if sexpr[0].is_number:
                ophase = sympy.sympify('exp(-I*arg(%s))' % sexpr[0])
                sexpr = [sympy.Mul(x, ophase) for x in sexpr]

    def to_matrix(x):		# if x is a list of lists, and is rectangular, then return Matrix(x)
        if not type(x) == list:
            return x
        for row in x:
            if (not type(row) == list):
                return x
        rdim = len(x[0])
        for row in x:
            if not len(row) == rdim:
                return x
        return sympy.Matrix(x)

    if matrix:
        sexpr = to_matrix(sexpr)
    return sexpr
Example #3
0
def convert_mp(mp):
    if hasattr(mp, 'mp'):
        mp_left = mp.mp(0)
        mp_right = mp.mp(1)
    else:
        mp_left = mp.mp_nofunc(0)
        mp_right = mp.mp_nofunc(1)

    if mp.MUL() or mp.CMD_TIMES() or mp.CMD_CDOT():
        lh = convert_mp(mp_left)
        rh = convert_mp(mp_right)
        return sympy.Mul(lh, rh, evaluate=False)
    elif mp.DIV() or mp.CMD_DIV() or mp.COLON():
        lh = convert_mp(mp_left)
        rh = convert_mp(mp_right)
        return sympy.Mul(lh, sympy.Pow(rh, -1, evaluate=False), evaluate=False)
    else:
        if hasattr(mp, 'unary'):
            return convert_unary(mp.unary())
        else:
            return convert_unary(mp.unary_nofunc())
Example #4
0
def element_to_sympy(elem):
    if isinstance(elem, formula.Frac):
        return sympy.Mul(elementlist_to_sympy(elem.numerator),
                         sympy.Pow(elementlist_to_sympy(elem.denominator), -1))
    elif isinstance(elem, formula.Abs):
        return sympy.Abs(elementlist_to_sympy(elem.argument))
    elif isinstance(elem, formula.Radical):
        index = elementlist_to_sympy(elem.index) or 2
        return sympy.Pow(elementlist_to_sympy(elem.radicand),
                         sympy.Pow(index, -1))
    else:
        raise NotImplementedError
Example #5
0
def expand_mul(expr):
    assert isinstance(expr, sp.Mul)

    commutative, other = split_commutative(expr)

    commutative = [(apply_characteristic(v) if isinstance(v, sp.Number) else v)
                   for v in commutative]
    commutative = sp.Mul(*commutative)
    if commutative == 0:
        return S.Zero

    terms = [expand_with_transformers_impl(term) for term in other]

    for tr in config['mul']:
        terms = apply_transformer_termwise(terms, tr)

    def catch_zeros(expr):
        s = str(expr)
        for z in zeros_mul:
            if z in s:
                return S.Zero
        for z in zeros_pow:
            if z in s:
                return S.Zero
        return expr

    def postprocess(expr):
        # TODO: are these actually needed?
        # expr = sp.powsimp(expr)
        # expr = sp.expand_mul(expr)
        # TODO: get rid of this
        expr = catch_zeros(expr)
        return expr

    # FIXME: THIS COULD BE A BUG if one of the transformers yielded something
    # like an Add whose part could be matched by catch_zeros and thus the whole
    # expression would be marked as zero, which it is not. Currently there are no
    # such transformers in mul, but there may be.
    # Anyway, catch_zeros is evil and should be abandoned.
    return commutative * postprocess(sp.Mul(*terms))
Example #6
0
def out_add_f(expr01, cof_list, cof_dict, vector_add):
    if isinstance(expr01, sympy.Add):
        wiss = [sympy.Symbol("W%s" % i) for i, j in enumerate(expr01.args)]
        args_new = [(wi, sympy.Mul(wi, ei)) if not ei.is_number else (None, ei) for ei, wi in
                    zip(expr01.args, wiss)]
        wis, we = zip(*args_new)
        cof_list.extend([wi for wi in wis if wi is not None])
        argss = sympy.Add(*we)
        expr01 = argss

    elif isinstance(expr01, M3):

        exprin1 = expr01.args[0]
        conu = expr01.conu
        if isinstance(exprin1, sympy.Add):
            wiss = [sympy.Symbol("W%s" % i) for i, j in enumerate(exprin1.args)]
            args_new = [(wi, sympy.Mul(wi, ei)) if not ei.is_number else (None, ei) for ei, wi in
                        zip(exprin1.args, wiss)]
            wis, we = zip(*args_new)
            cof_list.extend([wi for wi in wis if wi is not None])
            argss = sympy.Add(*we)
            expr01 = expr01.func(argss)

        if vector_add:
            if conu > 1:
                Wi = sympy.Symbol("V")
                arg = expr01.args[0]
                expr02 = expr01.func(sympy.Mul(Wi, arg))
                cof_dict[Wi] = conu
                expr01 = expr02
        else:
            A = sympy.Symbol("A")
            expr01 = sympy.Mul(expr01, A)
            cof_list.append(A)

    else:
        A = sympy.Symbol("A")
        expr01 = sympy.Mul(expr01, A)
        cof_list.append(A)
    return expr01
Example #7
0
 def eval(cls, A, B):
     if not A != B:
         return sp.S.Zero
     if A.is_commutative or B.is_commutative:
         return sp.S.Zero
     if isinstance(A, sp.Add):
         sargs = []
         for term in A.args:
             sargs.append(Corxet(term, B))
         return sp.Add(*sargs)
     if isinstance(B, sp.Add):
         sargs = []
         for term in B.args:
             sargs.append(Corxet(A, term))
         return sp.Add(*sargs)
     cA, ncA = A.args_cnc()
     cB, ncB = B.args_cnc()
     c_part = cA + cB
     if c_part:
         return sp.Mul(sp.Mul(*c_part),
                       cls(sp.Mul._from_args(ncA), sp.Mul._from_args(ncB)))
     if A.compare(B) == 1:
         return sp.S.NegativeOne * cls.eval(cls, B, A)
     i, j, k, l = A.i, A.j, B.i, B.j
     if A.t != B.t:
         printe("Els objectes %s i %s no pertanyen a la mateixa base." %
                (A, B))
         exit(-1)
     if A.t == "E":
         ll = rl.corxetErel(i, j, k, l)
     elif A.t == "Z":
         ll = rl.corxetZrel(i, j, k, l)
     else:
         printe("No hi ha cap base definida amb %s." % (A.t))
         exit(-1)
     args = []
     for it in ll:
         elem = sp.Mul(sp.Rational(it[0], it[1]), Eel(it[2], it[3], A.t))
         args.append(elem)
     return sp.Add(*args)
Example #8
0
def _arg_func_from_proto(
    func: v2.program_pb2.ArgFunction,
    *,
    arg_function_language: str,
    required_arg_name: Optional[str] = None,
) -> Optional[ARG_LIKE]:
    supported = SUPPORTED_FUNCTIONS_FOR_LANGUAGE.get(arg_function_language)
    if supported is None:
        raise ValueError(f'Unrecognized arg_function_language: {arg_function_language!r}')

    if func.type not in supported:
        raise ValueError(
            f'Unrecognized function type {func.type!r} '
            f'for arg_function_language={arg_function_language!r}'
        )

    if func.type == 'add':
        return sympy.Add(
            *[
                arg_from_proto(
                    a,
                    arg_function_language=arg_function_language,
                    required_arg_name='An addition argument',
                )
                for a in func.args
            ]
        )

    if func.type == 'mul':
        return sympy.Mul(
            *[
                arg_from_proto(
                    a,
                    arg_function_language=arg_function_language,
                    required_arg_name='A multiplication argument',
                )
                for a in func.args
            ]
        )

    if func.type == 'pow':
        return sympy.Pow(
            *[
                arg_from_proto(
                    a,
                    arg_function_language=arg_function_language,
                    required_arg_name='A power argument',
                )
                for a in func.args
            ]
        )
    return None
Example #9
0
    def get_spontaneous_decay_rate(self,
                                   z=sp.Symbol('Z', real=True),
                                   mu=sp.Symbol('mu', real=True),
                                   algo="auto"):
        """
        Get the spontaneous decay rate of the transition
        :param z: atomic number (int)
        :param mu: reduced mass (float)
        :return: the spontaneous decay rate (float)
        """
        # check if spontaneous_decay_rate is already calculated
        if self.spontaneous_decay_rate is not None:
            return self.spontaneous_decay_rate
        elif self.repr_without_spin(
        ) in Transition.n_ell_m_ell_state_to_rs.keys():
            self.spontaneous_decay_rate = Transition.n_ell_m_ell_state_to_rs[
                self.repr_without_spin()]
            return self.spontaneous_decay_rate

        r, theta, phi = sp.Symbol("r", real=True, positive=True), sp.Symbol("theta", real=True),\
                        sp.Symbol("phi", real=True)
        coeff = (4 * const.alpha *
                 (self.get_delta_energy(z, mu)**3)) / (3 * (const.hbar**3) *
                                                       (const.c**2))
        psi = self._initial_quantum_state.get_wave_function(z, mu)
        psi_prime = self._ending_quantum_state.get_wave_function(z, mu)

        if algo == "auto":
            if self._initial_quantum_state.hydrogen and self._ending_quantum_state.hydrogen:
                algo = "sympy_ns"
            else:
                algo = "scipy_nquad"

        # \Vec{r} = x + y + z
        r_operator = r * (sp.sin(theta) * sp.cos(phi) +
                          sp.sin(theta) * sp.sin(phi) + sp.cos(theta))

        # Process the integral with algo
        bracket_product = QuantumFactory.bracket_product(
            psi, psi_prime, r_operator, algo)

        bracket_product_norm_square = sp.Mul(sp.conjugate(bracket_product),
                                             bracket_product).evalf()
        # print(bracket_product_norm_square)

        self.spontaneous_decay_rate = sp.Float(coeff *
                                               bracket_product_norm_square)

        # updating Transition static attribute
        Transition.n_ell_m_ell_state_to_rs[
            self.repr_without_spin()] = self.spontaneous_decay_rate
        return self.spontaneous_decay_rate
Example #10
0
def f1(x, xT, P, A):
    """
    :param x: matrix
    :param xT: transpose of x
    :param P: matrix
    :param A: matrix
    :return: x^T (A^T P + P A) x
    """
    AT = sp.Transpose(A)
    e0 = sp.Mul(AT, P, evaluate=False)
    e1 = sp.Mul(P, A, evaluate=False)
    e2 = sp.Add(e0, e1, evaluate=False)
    e = sp.Mul(xT, e2, evaluate=False)
    e = sp.Mul(e, x, evaluate=False)
    m = {
        str(P[r, c]): P[r, c]
        for r in range(P.shape[0]) for c in range(P.shape[0])
    }
    m.update({str(x): x for x in x})
    e = parse_expr(str(e), local_dict=m)
    # res = sp.expand((xT * (AT * P + P * A) * x)[0])
    return sp.expand(e[0])
Example #11
0
def pow_to_mul(expr):
    if expr.is_Atom or expr.is_Indexed:
        return expr
    elif expr.is_Pow:
        base, exp = expr.as_base_exp()
        if exp > 10 or exp < -10 or int(exp) != exp or exp == 0:
            # Large and non-integer powers remain untouched
            return expr
        elif exp == -1:
            # Reciprocals also remain untouched, but we traverse the base
            # looking for other Pows
            return expr.func(pow_to_mul(base), exp, evaluate=False)
        elif exp > 0:
            return sympy.Mul(*[base]*int(exp), evaluate=False)
        else:
            # SymPy represents 1/x as Pow(x,-1). Also, it represents
            # 2/x as Mul(2, Pow(x, -1)). So we shouldn't end up here,
            # but just in case SymPy changes its internal conventions...
            posexpr = sympy.Mul(*[base]*(-int(exp)), evaluate=False)
            return sympy.Pow(posexpr, -1, evaluate=False)
    else:
        return expr.func(*[pow_to_mul(i) for i in expr.args], evaluate=False)
Example #12
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())
Example #13
0
    def ma(self):
        """Return the mass action monomial associated to the complex.

        :Example:

        >>> c1 = Complex({'S': 2, 'E': 1})
        >>> c1.ma()
        E*S**2

        :rtype: sympy expression.
        """
        if self == {}: return 1
        return sp.Mul(*(sp.Symbol(r)**self[r] for r in self))
Example #14
0
    def hack_simplify_sum(expr):
        # https://stackoverflow.com/questions/62679575/why-cant-sympy-simplify-these-sum-expressions-of-indexed-variables
        # https://github.com/sympy/sympy/issues/19685

        if expr.func is sym.concrete.summations.Sum:
            body, (idx, lower, upper) = expr.args
            if idx not in body.free_symbols:
                factor = (upper + 1) - lower
                return factor * body
            else:
                if body.func is sym.Mul:
                    factor_out = []
                    factor_in = []
                    for sub_arg in body.args:
                        if idx in sub_arg.free_symbols:
                            factor_in.append(sub_arg)
                        else:
                            factor_out.append(sub_arg)
                    outer = sym.Mul(*factor_out)
                    return outer * sym.summation(sym.Mul(*factor_in),
                                                 (idx, lower, upper))
        return expr
Example #15
0
    def residue(self, pole, poles):
        """Determine residue for given pole."""

        expr = self.expr
        var = self.var

        # Remove occurrence of pole; sym.cancel
        # doesn't always work, for example, for complex poles.
        occurrences = []
        for p in poles:
            occurrences += [p.n - 1 if p.expr == pole else p.n]

        numer, denom = expr.as_numer_denom()
        Dpoly = sym.Poly(denom, var)
        K = Dpoly.LC()

        D = [(var - p.expr)**o for p, o in zip(poles, occurrences)]
        denom = sym.Mul(K, *D)

        # Could calculate all residues simultaneously using
        # system of linear equations.

        def method1(numer, denom, var, pole):

            d = sym.limit(denom, var, pole)

            if d != 0:
                tmp = (numer / denom).simplify()

                # Sometimes this takes ages...
                return sym.limit(tmp, var, pole)

            # Use l'Hopital's rule
            tmp = numer / denom
            tmp = sym.diff(tmp, var)

            return sym.limit(tmp, var, pole)

        def method2(numer, denom, var, pole):

            d = denom.subs(var, pole)
            n = numer.subs(var, pole)

            if d != 0:
                return n / d

            ddenom = sym.diff(denom, var)
            return n / ddenom.subs(pole)

        m2 = method2(numer, denom, var, pole)
        return m2.cancel()
Example #16
0
def _parse_reaction(model, line, reaction_cache):
    """Parse a 'reaction' line from a BNGL net file."""
    (number, reactants, products, rate, rule) = line.strip().split(' ', 4)
    # the -1 is to switch from one-based to zero-based indexing
    reactants = tuple(int(r) - 1 for r in reactants.split(',') if r != '0')
    products = tuple(int(p) - 1 for p in products.split(',') if p != '0')
    rate = rate.rsplit('*')
    (rule_list, unit_conversion) = re.match(
        r'#([\w,\(\)]+)(?: unit_conversion=(.*))?\s*$', rule).groups()
    rule_list = rule_list.split(',')  # BNG lists all rules that generate a rxn
    # Support new (BNG 2.2.6-stable or greater) and old BNG naming convention
    # for reverse rules
    rule_name, is_reverse = zip(
        *[re.subn('^_reverse_|\(reverse\)$', '', r) for r in rule_list])
    is_reverse = tuple(bool(i) for i in is_reverse)
    r_names = ['__s%d' % r for r in reactants]
    rate_param = [
        model.parameters.get(r) or model.expressions.get(r)
        or model._derived_parameters.get(r)
        or model._derived_expressions.get(r) or float(r) for r in rate
    ]
    combined_rate = sympy.Mul(*[sympy.S(t) for t in r_names + rate_param])
    reaction = {
        'reactants': reactants,
        'products': products,
        'rate': combined_rate,
        'rule': rule_name,
        'reverse': is_reverse,
    }
    model.reactions.append(reaction)
    # bidirectional reactions
    key = (reactants, products)
    key_reverse = (products, reactants)
    if key in reaction_cache:
        reaction_bd = reaction_cache.get(key)
        reaction_bd['rate'] += combined_rate
        reaction_bd['rule'] += tuple(r for r in rule_name
                                     if r not in reaction_bd['rule'])
    elif key_reverse in reaction_cache:
        reaction_bd = reaction_cache.get(key_reverse)
        reaction_bd['reversible'] = True
        reaction_bd['rate'] -= combined_rate
        reaction_bd['rule'] += tuple(r for r in rule_name
                                     if r not in reaction_bd['rule'])
    else:
        # make a copy of the reaction dict
        reaction_bd = dict(reaction)
        # default to false until we find a matching reverse reaction
        reaction_bd['reversible'] = False
        reaction_cache[key] = reaction_bd
        model.reactions_bidirectional.append(reaction_bd)
Example #17
0
    def std_latex_array(self, out_var=None):
        l_scalar, r_scalar = self.get_scalar()

        l_part = []
        r_part = [sympy.latex(r_scalar)]

        for variable in self.variables:

            l_coeff, r_coeff = self.get_coeff(variable)
            substitution = self.substitutions.get(variable, variable)

            if l_coeff != 0:
                l_part.append(sympy.latex(sympy.Mul(l_coeff, substitution, evaluate=False)))

            if r_coeff < 0:
                r_part.append("-")
                r_part.append(sympy.latex(sympy.Mul(-r_coeff, substitution, evaluate=False)))
            elif r_coeff > 0:
                r_part.append("+")
                r_part.append(sympy.latex(sympy.Mul(r_coeff, substitution, evaluate=False)))
            elif out_var:
                if variable in out_var:
                    r_part += ["", ""]
                else:
                    pass
            else:
                r_part += ["", ""]

        l_part = " & ".join(l_part)
        r_part = " & ".join(r_part)

        comp = {
            'LEQ' : r"""\leq""",
            'EQ' : r"""=""",
            'GEQ' : r"""\geq""",
            }[self.comp]

        return l_part + " & " + comp + " & " + r_part + r"""\\"""
Example #18
0
    def parse_term(self, expr):
        syms = []
        cons = []

        if type(expr) == sy.Symbol:
            syms.append(expr)
            cons.append(1)
        elif type(expr) == sy.Pow:
            var, exponent = expr.args
            if type(var) == sy.Symbol:
                syms.append(expr)
                cons.append(1)
            else:
                cons.append(expr)
        else:
            for arg in expr.args:
                if type(arg) == sy.Symbol:
                    syms.append(arg)
                elif type(arg) == sy.Pow:
                    var, exponent = arg.args
                    if type(var) == sy.Symbol:
                        syms.append(arg)
                    else:
                        cons.append(arg)
                else:
                    cons.append(arg)

        const_term = 1
        syms_term = None
        if len(cons) == 1:
            const_term = cons[0]
        elif len(cons) > 1:
            const_term = sy.Mul(*cons)
        if len(syms) == 1:
            syms_term = syms[0]
        elif len(syms) > 0:
            syms_term = sy.Mul(*syms)
        return const_term, syms_term
Example #19
0
def add_coefficient(expr01, inter_add=True, inner_add=False, vector_add=False, out_add=False, flat_add=False):
    """
    Try add the placeholder coefficient to sympy expression.
    1. Add Wi,A,B normal coefficients to expression.
    2. Add V, Vi vector coefficients to expression, for this type of coefficient ,
    there should be with expr01.conu for Function("MAdd"), Function("MSub").
    more details can be found in ..translate.simple

    Parameters
    ----------
    expr01: Expr
        sympy expressions
    inter_add: bool
        bool
    inner_add: bool
        bool
    vector_add:bool
        bool
    flat_add:bool
        bool
    out_add:bool
        bool
    Returns
    -------
    expr
    """
    cof_list = []
    cof_dict = {}
    assert len([i for i in [inner_add, out_add, flat_add] if i is True]) <= 1, \
        "For the 'out_add','flat_add'and 'out_add', you should just choose one of them."

    if out_add:  # out layer
        expr01 = out_add_f(expr01, cof_list, cof_dict, vector_add)

    elif inner_add:  # out and inner layer each add and Madd...
        expr01 = inner_add_f(expr01, cof_list, cof_dict, vector_add)

    elif flat_add:  # out and inner layer each add and Madd... just open by add.
        expr01 = flatten_add_f(expr01, cof_list, cof_dict, vector_add)
    else:
        A = sympy.Symbol("A")
        expr01 = sympy.Mul(expr01, A)
        cof_list.append(A)

    if inter_add:  # intercept
        B = sympy.Symbol("B")
        expr01 = sympy.Add(expr01, B)
        cof_list.append(B)

    return expr01, cof_list, cof_dict
Example #20
0
def oneEpsAsDeltas(eps, **tempOverride):
    '''Takes an instance of Eps and rewrites it as Deltas'''
    dim, indexRange = delta.getTempDimAndIndexRange(**tempOverride)
    if not isinstance(eps, Eps):
        raise TypeError('Error: input must be an Eps(*indecis)')
    if not len(eps.index) == dim:
        raise TypeError('Error: Eps must have dim number of indices')
    termList = []
    for perm in permute_all(eps.index):
        factorList = [perm['parity']]
        for (pos, index) in enumerate(perm['perm']):
            factorList.append(delta.Delta(pos + 1, index))
        termList.append(sympy.Mul(*factorList))
    return sympy.Add(*termList)
Example #21
0
    def _print_Pow(self, expr):
        result = self._scalarFallback('_print_Pow', expr)
        if result:
            return result

        one = self.instruction_set['makeVecConst'].format(1.0, **self._kwargs)

        if expr.exp.is_integer and expr.exp.is_number and 0 < expr.exp < 8:
            return "(" + self._print(sp.Mul(*[expr.base] * expr.exp, evaluate=False)) + ")"
        elif expr.exp == -1:
            one = self.instruction_set['makeVecConst'].format(1.0, **self._kwargs)
            return self.instruction_set['/'].format(one, self._print(expr.base), **self._kwargs)
        elif expr.exp == 0.5:
            return self.instruction_set['sqrt'].format(self._print(expr.base), **self._kwargs)
        elif expr.exp == -0.5:
            root = self.instruction_set['sqrt'].format(self._print(expr.base), **self._kwargs)
            return self.instruction_set['/'].format(one, root, **self._kwargs)
        elif expr.exp.is_integer and expr.exp.is_number and - 8 < expr.exp < 0:
            return self.instruction_set['/'].format(one,
                                                    self._print(sp.Mul(*[expr.base] * (-expr.exp), evaluate=False)),
                                                    **self._kwargs)
        else:
            raise ValueError("Generic exponential not supported: " + str(expr))
 def pow_to_mul(expr):
     """
     Convert integer powers in an expression to Muls, like a**2 => a*a.
     """
     pows = list(expr.atoms(sympy.Pow))
     if any(not e.is_Integer for b, e in (i.as_base_exp() for i in pows)):
         raise ValueError("A power contains a non-integer exponent")
     print(pows)
     for b, e in (i.as_base_exp() for i in pows):
         print(b, e)
     repl = zip(pows, (sympy.Mul(*[b] * e, evaluate=False)
                       for b, e in (i.as_base_exp() for i in pows)))
     #print repl
     return expr.subs(repl)
Example #23
0
def zeros_to_coeffs(*z_list, **kwargs):
    """
    calculates the coeffs corresponding to a poly with provided zeros
    """

    s = sp.Symbol("s")
    p = sp.Mul(*[s-s0 for s0 in z_list])

    real_coeffs = kwargs.get("real_coeffs", True)
    c = np.array(coeffs(p, s), dtype=np.float)

    if real_coeffs:
        c = np.real(c)
    return c
Example #24
0
def distribute(e, x):
    """Helper method to apply distributive multiplication.
    This helps by allowing the use of 'subs' instead of 'limit'
    in special circumstances
    """

    # traverse the operations graph
    if e.is_Add:
        return sp.Add(*[distribute(a, x) for a in e.args])
    elif e.is_Mul:
        o = sp.Integer(1)
        done = False
        for a in e.args:
            if x in a.atoms() and not done:
                # prefer multiply where x is found
                # seek for simplification
                o = sp.Mul(o, distribute(a, x))
                done = True
            else:
                o = sp.Mul(o, a)
        return o if done else sp.Mul(o, x)
    else:
        return sp.Mul(e, x)
Example #25
0
def _interpolate_Function(expr):
    path = 'None'
    factor = 'None'
    change = False
    summand_0 = 'None'
    summand_1 = 'None'
    res = expr
    for i in np.arange(len(expr.args)):
        argument = sympy.expand(expr.args[i])
        if argument.func == sympy.Add:
            for j in np.arange(len(argument.args)):
                summand = argument.args[j]
                if summand.func == sympy.Mul:
                    for k in np.arange(len(summand.args)):
                        temp = 0
                        if summand.args[k] == sympy.Symbol('a'):
                            temp = sympy.Mul(sympy.Mul(*summand.args[:k]),
                                             sympy.Mul(*summand.args[k + 1:]))
                            #print(temp)
                        if not temp == int(temp):
                            #print('found one')
                            factor = (temp)
                            path = np.array([i, j, k])
    if not factor == 'None':
        change = True

        sign = np.sign(factor)
        offsets = np.array([int(factor), sign * (int(sign * factor) + 1)])
        weights = 1 / np.abs(offsets - factor)
        weights = weights / np.sum(weights)

        res = (weights[0] *
               _interchange(expr, offsets[0] * sympy.Symbol('a'), path[:-1]) +
               weights[1] *
               _interchange(expr, offsets[1] * sympy.Symbol('a'), path[:-1]))

    return sympy.expand(res), change
Example #26
0
 def expected(expr):
     cls = expr.__class__
     if cls == sp.Add:
         return sp.Add(*[expected(elem) for elem in expr.args])
     if cls == sp.Mul:
         return sp.Mul(*[expected(elem) for elem in expr.args])
     if cls == sp.Pow and isinstance(expr.args[0],RandomVar):
         if (not expr.args[1].is_integer):
             raise Exception("Can't do expected values of non-integer powers")                
         if expr.args[1]<0:
             raise Exception("Can't do expected values of negative powers (including division)")
         return moment(expr.args[0], expr.args[1])
     if isinstance(expr, RandomVar):
         return moment(expr, 1)
     return expr
Example #27
0
def expand_tp(expr):
    l, r = expr.args
    l = expand_with_transformers_impl(l)
    r = expand_with_transformers_impl(r)
    if l == 0 or r == 0:
        return S.Zero

    if isinstance(l, sp.Add):
        expr = sp.Add(*[TP(arg, r) for arg in l.args])
        return expand_with_transformers_impl(expr)
    if isinstance(r, sp.Add):
        expr = sp.Add(*[TP(l, arg) for arg in r.args])
        return expand_with_transformers_impl(expr)

    lc, lnc = split_commutative(l) if isinstance(l, sp.Mul) else ([S.One], [l])
    rc, rnc = split_commutative(r) if isinstance(r, sp.Mul) else ([S.One], [r])

    lnc = sp.Mul(*lnc)
    rnc = sp.Mul(*rnc)

    commutative = sp.Mul(*(lc + rc))
    tp = TP(lnc, rnc)

    return commutative * tp
Example #28
0
def convert_frac(frac):
    diff_op = False
    partial_op = False
    lower_itv = frac.lower.getSourceInterval()
    lower_itv_len = lower_itv[1] - lower_itv[0] + 1
    if (frac.lower.start == frac.lower.stop
            and frac.lower.start.type == PSLexer.DIFFERENTIAL):
        wrt = get_differential_var_str(frac.lower.start.text)
        diff_op = True
    elif (lower_itv_len == 2 and frac.lower.start.type == PSLexer.SYMBOL
          and frac.lower.start.text == '\\partial'
          and (frac.lower.stop.type == PSLexer.LETTER_NO_E
               or frac.lower.stop.type == PSLexer.SYMBOL)):
        partial_op = True
        wrt = frac.lower.stop.text
        if frac.lower.stop.type == PSLexer.SYMBOL:
            wrt = wrt[1:]

    if diff_op or partial_op:
        wrt = sympy.Symbol(wrt, real=True, positive=True)
        if (diff_op and frac.upper.start == frac.upper.stop
                and frac.upper.start.type == PSLexer.LETTER_NO_E
                and frac.upper.start.text == 'd'):
            return [wrt]
        elif (partial_op and frac.upper.start == frac.upper.stop
              and frac.upper.start.type == PSLexer.SYMBOL
              and frac.upper.start.text == '\\partial'):
            return [wrt]
        upper_text = rule2text(frac.upper)

        expr_top = None
        if diff_op and upper_text.startswith('d'):
            expr_top = process_sympy(upper_text[1:])
        elif partial_op and frac.upper.start.text == '\\partial':
            expr_top = process_sympy(upper_text[len('\\partial'):])
        if expr_top:
            return sympy.Derivative(expr_top, wrt)

    expr_top = convert_expr(frac.upper)
    expr_bot = convert_expr(frac.lower)
    if expr_top.is_Matrix or expr_bot.is_Matrix:
        return sympy.MatMul(expr_top,
                            sympy.Pow(expr_bot, -1, evaluate=False),
                            evaluate=False)
    else:
        return sympy.Mul(expr_top,
                         sympy.Pow(expr_bot, -1, evaluate=False),
                         evaluate=False)
Example #29
0
 def check_filter_equations(self):
     made_changes = False
     
     # Expand, and remove instances of '0 = 0' and 'non-zero number != 0'
     len_cl, len_op = len(self.cl_eqs), len(self.op_eqs)
     self.cl_eqs = list({ sp.expand(e) for e in self.cl_eqs if e != 0 })
     self.op_eqs = list({ sp.expand(e) for e in self.op_eqs if not e.is_complex or e == 0 })
     if len(self.cl_eqs) != len_cl or len(self.op_eqs) != len_op:
         made_changes = True
     
     # If any equation is of the form 'x = 0', we can solve for x = 0 and continue with the remaining system
     for x in [ eq for eq in self.cl_eqs if eq.is_Symbol and eq in self.vars ]:
         self.vars = self.vars.difference({x,})
         self.cl_eqs = [ e.subs(x, 0) for e in self.cl_eqs ]
         self.op_eqs = [ e.subs(x, 0) for e in self.op_eqs ]
         made_changes = True
     
     for eq in self.cl_eqs:
         eq_factor = sp.factor(eq)
     
         # If any equation is of the form '(...)^n = 0', we can simply substitute with '(...) = 0' (provided n is positive)
         if eq_factor.is_Pow:
             if eq_factor.args[1] < 0:
                 return 0
             
             self.cl_eqs = [ eq_factor.args[0] if e == eq else e for e in self.cl_eqs]
         
         # If any equation is a product, we can remove all denominators and all numeric factors. Also, one can remove all higher multiplicities
         if eq_factor.is_Mul:
             unnecessary_factors = [ a for a in eq_factor.args if a.is_complex or (a.is_Pow and a.args[1] < 0) ]
             higher_multiplicity = [ a for a in eq_factor.args if a.is_Pow and a.args[1] > 0 ]
             if unnecessary_factors or higher_multiplicity:
                 replacement = sp.Mul(*( f.args[0] if f in higher_multiplicity else f for f in eq_factor.args if f not in unnecessary_factors ))
                 self.cl_eqs = [ replacement if e == eq else e for e in self.cl_eqs ]
                 made_changes = True
     
     for eq in self.op_eqs:
         eq_factor = sp.factor(eq)
         
         # If an equation is of the form '(u) * ... * (v) != 0', replace by '(u) != 0 & ... & (v) != 0'
         if eq_factor.is_Mul:
             self.op_eqs = [ e for e in self.op_eqs if e != eq ] + [ f for f in eq_factor.args if not f.is_complex]
             made_changes = True
     
     if made_changes:
         return self.compute_class()
     
     return None
 def seperate_coeff(big_term):
     coefficients = []
     terms = []
     for term in big_term:
         if term.func == sympy.Pow:
             coefficients.append(1)
             mul2 = [term.args[0]] * term.args[1]
         else:
             mul2 = []
             for arg in term.args:
                 if arg.is_Integer is True:
                     coefficients.append(arg)
                 else:
                     mul2.append(arg)
         terms.append(sympy.Mul(*mul2))
     return (terms, coefficients)