def _separatevars(expr, force):
    if len(expr.free_symbols) == 1:
        return expr
    # don't destroy a Mul since much of the work may already be done
    if expr.is_Mul:
        args = list(expr.args)
        changed = False
        for i, a in enumerate(args):
            args[i] = separatevars(a, force)
            changed = changed or args[i] != a
        if changed:
            expr = expr.func(*args)
        return expr

    # get a Pow ready for expansion
    if expr.is_Pow:
        expr = Pow(separatevars(expr.base, force=force), expr.exp)

    # First try other expansion methods
    expr = expr.expand(mul=False, multinomial=False, force=force)

    _expr, reps = posify(expr) if force else (expr, {})
    expr = factor(_expr).subs(reps)

    if not expr.is_Add:
        return expr

    # Find any common coefficients to pull out
    args = list(expr.args)
    commonc = args[0].args_cnc(cset=True, warn=False)[0]
    for i in args[1:]:
        commonc &= i.args_cnc(cset=True, warn=False)[0]
    commonc = Mul(*commonc)
    commonc = commonc.as_coeff_Mul()[1]  # ignore constants
    commonc_set = commonc.args_cnc(cset=True, warn=False)[0]

    # remove them
    for i, a in enumerate(args):
        c, nc = a.args_cnc(cset=True, warn=False)
        c = c - commonc_set
        args[i] = Mul(*c)*Mul(*nc)
    nonsepar = Add(*args)

    if len(nonsepar.free_symbols) > 1:
        _expr = nonsepar
        _expr, reps = posify(_expr) if force else (_expr, {})
        _expr = (factor(_expr)).subs(reps)

        if not _expr.is_Add:
            nonsepar = _expr

    return commonc*nonsepar
Esempio n. 2
0
    def eval(self):
        f, i, a, b = self.f, self.i, self.a, self.b

        # Exploit the linearity of the sum
        if not f.has(i):
            return f*(b-a+1)
        if isinstance(f, Mul):
            L, R = getab(f)
            if not L.has(i): return L*Sum2(R, (i, a, b))
            if not R.has(i): return R*Sum2(L, (i, a, b))
        if isinstance(f, Add):
            L, R = getab(f)
            lsum = Sum2(L, (i,a,b))
            rsum = Sum2(R, (i,a,b))
            if not isinstance(lsum, Sum2) and not isinstance(rsum, Sum2):
                return lsum + rsum

        # Polynomial terms with Faulhaber's formula
        if f == i:
            f = Pow(i, 1, evaluate=False) # TODO: match should handle this
        p = Wild('p')
        e = f.match(i**p)
        if e != None:
            c = p.subs_dict(e)
            B = Basic.bernoulli
            if c.is_integer and c >= 0:
                s = (B(c+1, b+1) - B(c+1, a))/(c+1)
                return s.expand()

        # Geometric terms
        if isinstance(f, Pow):
            r, k = f[:]
            if not r.has(i) and k == i:
                # TODO: Pow should be able to simplify x**oo depending
                # on whether |x| < 1 or |x| > 1 for non-rational x
                if b == oo and isinstance(r, Rational) and abs(r) < 1:
                    return r**a / (1-r)
                else:
                    return (r**a - r**(b+1)) / (1-r)

        # Should nothing else works, use brute force if possible
        if isinstance(a, Rational) and a.is_integer and \
           isinstance(b, Rational) and b.is_integer:
            s = 0
            for j in range(a, b+1):
                s += f.subs(i, j)
            return s

        return self
Esempio n. 3
0
def _dyad_div(one, other):
    """ Helper for division involving dyadics """
    if isinstance(one, Dyadic) and isinstance(other, Dyadic):
        raise TypeError("Cannot divide two dyadics")
    elif isinstance(one, Dyadic):
        return DyadicMul(one, Pow(other, S.NegativeOne))
    else:
        raise TypeError("Cannot divide by a dyadic")
Esempio n. 4
0
    def _print_Mul(self, expr):

        prec = precedence(expr)

        c, e = expr.as_coeff_Mul()
        if c < 0:
            expr = _keep_coeff(-c, e)
            sign = "-"
        else:
            sign = ""

        a = []  # items in the numerator
        b = []  # items that are in the denominator (if any)

        if self.order not in ('old', 'none'):
            args = expr.as_ordered_factors()
        else:
            # use make_args in case expr was something like -x -> x
            args = Mul.make_args(expr)

        # Gather args for numerator/denominator
        for item in args:
            if item.is_commutative and item.is_Pow and item.exp.is_Rational and item.exp.is_negative:
                if item.exp != -1:
                    b.append(Pow(item.base, -item.exp, evaluate=False))
                else:
                    b.append(Pow(item.base, -item.exp))
            elif item.is_Rational and item is not S.Infinity:
                if item.p != 1:
                    a.append(Rational(item.p))
                if item.q != 1:
                    b.append(Rational(item.q))
            else:
                a.append(item)

        a = a or [S.One]

        a_str = [self.parenthesize(x, prec) for x in a]
        b_str = [self.parenthesize(x, prec) for x in b]

        if len(b) == 0:
            return sign + '*'.join(a_str)
        elif len(b) == 1:
            return sign + '*'.join(a_str) + "/" + b_str[0]
        else:
            return sign + '*'.join(a_str) + "/(%s)" % '*'.join(b_str)
Esempio n. 5
0
def test_pow_as_base_exp():
    x = Symbol('x')
    assert (S.Infinity**(2 - x)).as_base_exp() == (S.Infinity, 2 - x)
    assert (S.Infinity**(x - 2)).as_base_exp() == (S.Infinity, x - 2)
    p = S.Half**x
    assert p.base, p.exp == p.as_base_exp() == (S(2), -x)
    # issue 8344:
    assert Pow(1, 2, evaluate=False).as_base_exp() == (S.One, S(2))
Esempio n. 6
0
def _real_to_rational(expr, tolerance=None):
    """
    Replace all reals in expr with rationals.

    >>> from sympy import nsimplify
    >>> from sympy.abc import x

    >>> nsimplify(.76 + .1*x**.5, rational=True)
    sqrt(x)/10 + 19/25

    """
    inf = Float('inf')
    p = expr
    reps = {}
    reduce_num = None
    if tolerance is not None and tolerance < 1:
        reduce_num = ceiling(1 / tolerance)
    for float in p.atoms(Float):
        key = float
        if reduce_num is not None:
            r = Rational(float).limit_denominator(reduce_num)
        elif (tolerance is not None and tolerance >= 1
              and float.is_Integer is False):
            r = Rational(tolerance *
                         round(float / tolerance)).limit_denominator(
                             int(tolerance))
        else:
            r = nsimplify(float, rational=False)
            # e.g. log(3).n() -> log(3) instead of a Rational
            if float and not r:
                r = Rational(float)
            elif not r.is_Rational:
                if float == inf or float == -inf:
                    r = S.ComplexInfinity
                elif float < 0:
                    float = -float
                    d = Pow(10, int((mpmath.log(float) / mpmath.log(10))))
                    r = -Rational(str(float / d)) * d
                elif float > 0:
                    d = Pow(10, int((mpmath.log(float) / mpmath.log(10))))
                    r = Rational(str(float / d)) * d
                else:
                    r = Integer(0)
        reps[key] = r
    return p.subs(reps, simultaneous=True)
Esempio n. 7
0
    def _print_Mul(self, expr):

        prec = precedence(expr)

        c, e = expr.as_coeff_Mul()
        if c < 0:
            expr = _keep_coeff(-c, e)
            sign = "-"
        else:
            sign = ""

        a = []  # items in the numerator
        b = []  # items that are in the denominator (if any)

        if self.order not in ('old', 'none'):
            args = expr.as_ordered_factors()
        else:
            # use make_args in case expr was something like -x -> x
            args = Mul.make_args(expr)

        # Gather args for numerator/denominator
        for item in args:
            if item.is_commutative and item.is_Pow and item.exp.is_Rational and item.exp.is_negative:
                if item.exp != -1:
                    b.append(Pow(item.base, -item.exp, evaluate=False))
                else:
                    b.append(Pow(item.base, -item.exp))
            else:
                a.append(item)

        a = a or [S.One]

        a_str = map(lambda x: self.parenthesize(x, prec), a)
        b_str = map(lambda x: self.parenthesize(x, prec), b)

        if len(b) == 0:
            return sign + '*'.join(a_str)
        elif len(b) == 1:
            if len(a) == 1 and not (a[0].is_Atom or a[0].is_Add):
                return sign + "%s/" % a_str[0] + '*'.join(b_str)
            else:
                return sign + '*'.join(a_str) + "/%s" % b_str[0]
        else:
            return sign + '*'.join(a_str) + "/(%s)" % '*'.join(b_str)
Esempio n. 8
0
def ratsimp(expr):
    """
    == Usage ==
        ratsimp(expr) -> joins two rational expressions and returns the simples form

    == Notes ==
        Currently can simplify only simple expressions, for this to be really usefull
        multivariate polynomial algorithms are needed

    == Examples ==
        >>> from sympy import *
        >>> x = Symbol('x')
        >>> y = Symbol('y')
        >>> e = ratsimp(1/x + 1/y)
    """
    expr = sympify(expr)
    if expr.is_Pow:
        return Pow(ratsimp(expr.base), ratsimp(expr.exp))
    elif expr.is_Mul:
        res = []
        for x in expr.args:
            res.append(ratsimp(x))
        return Mul(*res)
    elif expr.is_Function:
        return expr.func(*[ratsimp(t) for t in expr.args])

    #elif expr.is_Function:
    #    return type(expr)( ratsimp(expr[0]) )
    elif not expr.is_Add:
        return expr

    def get_num_denum(x):
        """Matches x = a/b and returns a/b."""
        a, b = map(Wild, 'ab')
        r = x.match(a / b)
        if r is not None and len(r) == 2:
            return r[a], r[b]
        return x, S.One

    x = expr.args[0]
    y = Add(*expr.args[1:])

    a, b = get_num_denum(ratsimp(x))
    c, d = get_num_denum(ratsimp(y))

    num = a * d + b * c
    denum = b * d

    # Check to see if the numerator actually expands to 0
    if num.expand() == 0:
        return 0

    return num / denum
Esempio n. 9
0
def test_Pow():
    assert maple_code(x ** 3) == "x^3"
    assert maple_code(x ** (y ** 3)) == "x^(y^3)"

    assert maple_code((x ** 3) ** y) == "(x^3)^y"
    assert maple_code(x ** Rational(2, 3)) == 'x^(2/3)'

    g = implemented_function('g', Lambda(x, 2 * x))
    assert maple_code(1 / (g(x) * 3.5) ** (x - y ** x) / (x ** 2 + y)) == \
           "(3.5*2*x)^(-x + y^x)/(x^2 + y)"
    # For issue 14160
    assert maple_code(Mul(-2, x, Pow(Mul(y, y, evaluate=False), -1, evaluate=False),
                          evaluate=False)) == '-2*x/(y*y)'
Esempio n. 10
0
def test_NumPyPrinter():
    from sympy.core.function import Lambda
    from sympy.matrices.expressions.adjoint import Adjoint
    from sympy.matrices.expressions.diagonal import (DiagMatrix,
                                                     DiagonalMatrix,
                                                     DiagonalOf)
    from sympy.matrices.expressions.funcmatrix import FunctionMatrix
    from sympy.matrices.expressions.hadamard import HadamardProduct
    from sympy.matrices.expressions.kronecker import KroneckerProduct
    from sympy.matrices.expressions.special import (OneMatrix, ZeroMatrix)
    from sympy.abc import a, b
    p = NumPyPrinter()
    assert p.doprint(sign(x)) == 'numpy.sign(x)'
    A = MatrixSymbol("A", 2, 2)
    B = MatrixSymbol("B", 2, 2)
    C = MatrixSymbol("C", 1, 5)
    D = MatrixSymbol("D", 3, 4)
    assert p.doprint(A**(-1)) == "numpy.linalg.inv(A)"
    assert p.doprint(A**5) == "numpy.linalg.matrix_power(A, 5)"
    assert p.doprint(Identity(3)) == "numpy.eye(3)"

    u = MatrixSymbol('x', 2, 1)
    v = MatrixSymbol('y', 2, 1)
    assert p.doprint(MatrixSolve(A, u)) == 'numpy.linalg.solve(A, x)'
    assert p.doprint(MatrixSolve(A, u) + v) == 'numpy.linalg.solve(A, x) + y'

    assert p.doprint(ZeroMatrix(2, 3)) == "numpy.zeros((2, 3))"
    assert p.doprint(OneMatrix(2, 3)) == "numpy.ones((2, 3))"
    assert p.doprint(FunctionMatrix(4, 5, Lambda((a, b), a + b))) == \
        "numpy.fromfunction(lambda a, b: a + b, (4, 5))"
    assert p.doprint(HadamardProduct(A, B)) == "numpy.multiply(A, B)"
    assert p.doprint(KroneckerProduct(A, B)) == "numpy.kron(A, B)"
    assert p.doprint(Adjoint(A)) == "numpy.conjugate(numpy.transpose(A))"
    assert p.doprint(DiagonalOf(A)) == "numpy.reshape(numpy.diag(A), (-1, 1))"
    assert p.doprint(DiagMatrix(C)) == "numpy.diagflat(C)"
    assert p.doprint(DiagonalMatrix(D)) == "numpy.multiply(D, numpy.eye(3, 4))"

    # Workaround for numpy negative integer power errors
    assert p.doprint(x**-1) == 'x**(-1.0)'
    assert p.doprint(x**-2) == 'x**(-2.0)'

    expr = Pow(2, -1, evaluate=False)
    assert p.doprint(expr) == "2**(-1.0)"

    assert p.doprint(S.Exp1) == 'numpy.e'
    assert p.doprint(S.Pi) == 'numpy.pi'
    assert p.doprint(S.EulerGamma) == 'numpy.euler_gamma'
    assert p.doprint(S.NaN) == 'numpy.nan'
    assert p.doprint(S.Infinity) == 'numpy.PINF'
    assert p.doprint(S.NegativeInfinity) == 'numpy.NINF'
Esempio n. 11
0
def test_power_dispatcher():

    class NewBase(Expr):
        pass
    class NewPow(NewBase, Pow):
        pass
    a, b = Symbol('a'), NewBase()

    @power.register(Expr, NewBase)
    @power.register(NewBase, Expr)
    @power.register(NewBase, NewBase)
    def _(a, b):
        return NewPow(a, b)

    # Pow called as fallback
    assert power(2, 3) == 8*S.One
    assert power(a, 2) == Pow(a, 2)
    assert power(a, a) == Pow(a, a)

    # NewPow called by dispatch
    assert power(a, b) == NewPow(a, b)
    assert power(b, a) == NewPow(b, a)
    assert power(b, b) == NewPow(b, b)
Esempio n. 12
0
    def _find_opts(expr):

        if not isinstance(expr, Basic):
            return

        if expr.is_Atom or expr.is_Order:
            return

        if iterable(expr):
            list(map(_find_opts, expr))
            return

        if expr in seen_subexp:
            return expr
        seen_subexp.add(expr)

        list(map(_find_opts, expr.args))

        if _coeff_isneg(expr):
            neg_expr = -expr
            if not neg_expr.is_Atom:
                opt_subs[expr] = Mul(S.NegativeOne, neg_expr, evaluate=False)
                seen_subexp.add(neg_expr)
                expr = neg_expr

        if isinstance(expr, (Mul, MatMul)):
            muls.add(expr)

        elif isinstance(expr, (Add, MatAdd)):
            adds.add(expr)

        elif isinstance(expr, (Pow, MatPow)):
            if _coeff_isneg(expr.exp):
                opt_subs[expr] = Pow(Pow(expr.base, -expr.exp),
                                     S.NegativeOne,
                                     evaluate=False)
Esempio n. 13
0
    def _print_Mul(self, expr):
        coeff, terms = expr.as_coeff_mul()
        if coeff.is_negative:
            coeff = -coeff
            if coeff is not S.One:
                terms = (coeff, ) + terms
            sign = "-"
        else:
            terms = (coeff, ) + terms
            sign = ""

        a = []  # items in the numerator
        b = []  # items that are in the denominator (if any)

        if self.order not in ('old', 'none'):
            args = expr._new_rawargs(*terms).as_ordered_factors()
        else:
            args = terms

        # Gather args for numerator/denominator
        for item in args:
            if item.is_commutative and item.is_Pow and item.exp.is_Rational and item.exp.is_negative:
                b.append(Pow(item.base, -item.exp))
            elif item.is_Rational and item is not S.Infinity:
                if item.p != 1:
                    a.append(Rational(item.p))
                if item.q != 1:
                    b.append(Rational(item.q))
            else:
                a.append(item)

        if len(a) == 0:
            a = [S.One]

        prec = precedence(expr)
        a_str = map(lambda x: self.parenthesize(x, prec), a)
        b_str = map(lambda x: self.parenthesize(x, prec), b)

        if len(b) == 0:
            return sign + '*'.join(a_str)
        elif len(b) == 1:
            if len(a) == 1 and not (a[0].is_Atom or a[0].is_Add):
                return sign + "%s/" % a_str[0] + '*'.join(b_str)
            else:
                return sign + '*'.join(a_str) + "/%s" % b_str[0]
        else:
            return sign + '*'.join(a_str) + "/(%s)" % '*'.join(b_str)
Esempio n. 14
0
    def __rpow__(self, other):
        if other.is_real and other.is_extended_nonnegative and (
                self.max - self.min).is_extended_positive:
            if other is S.One:
                return S.One
            if other.is_extended_positive:
                a, b = [other**i for i in self.args]
                if min(a, b) != a:
                    a, b = b, a
                return self.func(a, b)
            if other.is_zero:
                if self.min.is_zero:
                    return self.func(0, 1)
                if self.min.is_extended_positive:
                    return S.Zero

        return Pow(other, self, evaluate=False)
Esempio n. 15
0
def test_idempotence():
    x = Symbol('x', idempotent=True)
    n = Symbol('n', positive=True)
    y = Symbol('y')

    # positive powers equal the element
    assert x**2 == x
    assert x**125 == x
    assert x**n == x
    assert x**(n + 1) == x

    # empty product
    assert x**0 == 1

    # not-necessarily-positive powers are left untouched
    assert x**y == Pow(x, y, evaluate=False)
    assert x**y != x
Esempio n. 16
0
def _parallel_dict_from_expr_if_gens(exprs, opt):
    """Transform expressions into a multinomial form given generators. """
    k, indices = len(opt.gens), {}

    for i, g in enumerate(opt.gens):
        indices[g] = i

    polys = []

    for expr in exprs:
        poly = {}

        for term in Add.make_args(expr):
            coeff, monom = [], [0] * k

            for factor in Mul.make_args(term):
                if factor.is_Number:
                    coeff.append(factor)
                else:
                    try:
                        base, exp = decompose_power(factor)

                        if exp < 0:
                            exp, base = -exp, Pow(base, -S.One)

                        monom[indices[base]] = exp
                    except KeyError:
                        if not factor.has(*opt.gens):
                            coeff.append(factor)
                        else:
                            raise PolynomialError(
                                "%s contains an element of the generators set"
                                % factor)

            monom = tuple(monom)

            if monom in poly:
                poly[monom] += Mul(*coeff)
            else:
                poly[monom] = Mul(*coeff)

        polys.append(poly)

    return polys, opt.gens
Esempio n. 17
0
def test_ccode_Pow():
    assert ccode(x ** 3) == "pow(x, 3)"
    assert ccode(x ** (y ** 3)) == "pow(x, pow(y, 3))"
    g = implemented_function("g", Lambda(x, 2 * x))
    assert (
        ccode(1 / (g(x) * 3.5) ** (x - y ** x) / (x ** 2 + y))
        == "pow(3.5*2*x, -x + pow(y, x))/(pow(x, 2) + y)"
    )
    assert ccode(x ** -1.0) == "1.0/x"
    assert ccode(x ** Rational(2, 3)) == "pow(x, 2.0/3.0)"
    assert (
        ccode(x ** Rational(2, 3), type_aliases={real: float80}) == "powl(x, 2.0L/3.0L)"
    )
    _cond_cfunc = [
        (lambda base, exp: exp.is_integer, "dpowi"),
        (lambda base, exp: not exp.is_integer, "pow"),
    ]
    assert ccode(x ** 3, user_functions={"Pow": _cond_cfunc}) == "dpowi(x, 3)"
    assert ccode(x ** 0.5, user_functions={"Pow": _cond_cfunc}) == "pow(x, 0.5)"
    assert (
        ccode(x ** Rational(16, 5), user_functions={"Pow": _cond_cfunc})
        == "pow(x, 16.0/5.0)"
    )
    _cond_cfunc2 = [
        (lambda base, exp: base == 2, lambda base, exp: "exp2(%s)" % exp),
        (lambda base, exp: base != 2, "pow"),
    ]
    # Related to gh-11353
    assert ccode(2 ** x, user_functions={"Pow": _cond_cfunc2}) == "exp2(x)"
    assert ccode(x ** 2, user_functions={"Pow": _cond_cfunc2}) == "pow(x, 2)"
    # For issue 14160
    assert (
        ccode(
            Mul(
                -2,
                x,
                Pow(Mul(y, y, evaluate=False), -1, evaluate=False),
                evaluate=False,
            )
        )
        == "-2*x/(y*y)"
    )
Esempio n. 18
0
def is_nilpotent_number(n):
    """
    Check whether `n` is a nilpotent number. A number `n` is said to be
    nilpotent if and only if every finite group of order `n` is nilpotent.
    For more information see [1]_.

    Examples
    ========

    >>> from sympy.combinatorics.group_numbers import is_nilpotent_number
    >>> from sympy import randprime
    >>> is_nilpotent_number(21)
    False
    >>> is_nilpotent_number(randprime(1, 30)**12)
    True

    References
    ==========

    .. [1] Pakianathan, J., Shankar, K., *Nilpotent Numbers*,
            The American Mathematical Monthly, 107(7), 631-634.


    """
    if n <= 0 or int(n) != n:
        raise ValueError("n must be a positive integer, not %i" % n)

    n = Integer(n)
    prime_factors = list(factorint(n).items())
    is_nilpotent = True
    for p_j, a_j in prime_factors:
        for p_i, a_i in prime_factors:
            if any([Mod(Pow(p_i, k), p_j) == 1 for k in range(1, a_i + 1)]):
                is_nilpotent = False
                break
        if not is_nilpotent:
            break

    return is_nilpotent
Esempio n. 19
0
        def perform_operation(self, lhs, rhs, op):
            """Performs operation supported by the SymPy core

            Returns
            =======

            combined_variable: list
                contains variable content and type of variable

            """
            lhs_value = self.get_expr_for_operand(lhs)
            rhs_value = self.get_expr_for_operand(rhs)
            if op == '+':
                return [Add(lhs_value, rhs_value), 'expr']
            if op == '-':
                return [Add(lhs_value, -rhs_value), 'expr']
            if op == '*':
                return [Mul(lhs_value, rhs_value), 'expr']
            if op == '/':
                return [Mul(lhs_value, Pow(rhs_value, Integer(-1))), 'expr']
            if op == '%':
                return [Mod(lhs_value, rhs_value), 'expr']
            if op in ['<', '<=', '>', '>=', '==', '!=']:
                return [Rel(lhs_value, rhs_value, op), 'expr']
            if op == '&&':
                return [
                    And(as_Boolean(lhs_value), as_Boolean(rhs_value)), 'expr'
                ]
            if op == '||':
                return [
                    Or(as_Boolean(lhs_value), as_Boolean(rhs_value)), 'expr'
                ]
            if op == '=':
                return [Assignment(Variable(lhs_value), rhs_value), 'expr']
            if op in ['+=', '-=', '*=', '/=', '%=']:
                return [
                    aug_assign(Variable(lhs_value), op[0], rhs_value), 'expr'
                ]