Exemple #1
0
    def __new__(cls, name, index, system, pretty_str, latex_str):
        name = str(name)
        pretty_str = str(pretty_str)
        latex_str = str(latex_str)
        # Verify arguments
        if index not in range(0, 3):
            raise ValueError("index must be 0, 1 or 2")
        if not isinstance(system, CoordSysCartesian):
            raise TypeError("system should be a CoordSysCartesian")
        # Initialize an object
        obj = super(BaseVector, cls).__new__(cls, Symbol(name), Integer(index),
                                             system, Symbol(pretty_str),
                                             Symbol(latex_str))
        # Assign important attributes
        obj._base_instance = obj
        obj._components = {obj: Integer(1)}
        obj._measure_number = Integer(1)
        obj._name = name
        obj._pretty_form = pretty_str
        obj._latex_form = latex_str
        obj._system = system

        assumptions = {}
        assumptions['commutative'] = True
        obj._assumptions = StdFactKB(assumptions)

        # This attr is used for re-expression to one of the systems
        # involved in the definition of the Vector. Applies to
        # VectorMul and VectorAdd too.
        obj._sys = system

        return obj
Exemple #2
0
def test_Singletons():
    protocols = [0, 1, 2, 3]
    copiers = [copy.copy, copy.deepcopy]
    copiers += [lambda x: pickle.loads(pickle.dumps(x, p)) for p in protocols]

    for obj in (Integer(-1), Integer(0), Integer(1), Rational(1, 2), pi, E, I,
                oo, -oo, zoo, nan, GoldenRatio, EulerGamma, Catalan,
                S.EmptySet, S.IdentityFunction):
        for func in copiers:
            assert func(obj) is obj
Exemple #3
0
 def _eval_number(cls, arg):
     if arg.is_Number:
         if arg.is_Rational:
             return -Integer(-arg.p // arg.q)
         elif arg.is_Float:
             return Integer(int(arg.ceiling()))
         else:
             return arg
     if arg.is_NumberSymbol:
         return arg.approximation_interval(Integer)[1]
Exemple #4
0
def test_Number():
    assert precedence(Integer(0)) == PRECEDENCE["Atom"]
    assert precedence(Integer(1)) == PRECEDENCE["Atom"]
    assert precedence(Integer(-1)) == PRECEDENCE["Add"]
    assert precedence(Integer(10)) == PRECEDENCE["Atom"]
    assert precedence(Rational(5, 2)) == PRECEDENCE["Mul"]
    assert precedence(Rational(-5, 2)) == PRECEDENCE["Add"]
    assert precedence(Float(5)) == PRECEDENCE["Atom"]
    assert precedence(Float(-5)) == PRECEDENCE["Add"]
    assert precedence(oo) == PRECEDENCE["Atom"]
    assert precedence(-oo) == PRECEDENCE["Add"]
Exemple #5
0
def test_continued_fraction():
    pytest.raises(ValueError, lambda: cf_p(1, 0, 0))
    pytest.raises(ValueError, lambda: cf_p(1, 1, -1))
    assert cf_p(4, 3, 0) == [1, 3]
    assert cf_p(0, 3, 5) == [0, 1, [2, 1, 12, 1, 2, 2]]
    assert cf_p(1, 1, 0) == [1]
    assert cf_p(3, 4, 0) == [0, 1, 3]
    assert cf_p(4, 5, 0) == [0, 1, 4]
    assert cf_p(5, 6, 0) == [0, 1, 5]
    assert cf_p(11, 13, 0) == [0, 1, 5, 2]
    assert cf_p(16, 19, 0) == [0, 1, 5, 3]
    assert cf_p(27, 32, 0) == [0, 1, 5, 2, 2]
    assert cf_p(1, 2, 5) == [[1]]
    assert cf_p(0, 1, 2) == [1, [2]]
    assert cf_p(6, 7, 49) == [1, 1, 6]
    assert cf_p(3796, 1387, 0) == [2, 1, 2, 1, 4]
    assert cf_p(3245, 10000) == [0, 3, 12, 4, 13]
    assert cf_p(1932, 2568) == [0, 1, 3, 26, 2]
    assert cf_p(6589, 2569) == [2, 1, 1, 3, 2, 1, 3, 1, 23]

    assert list(itertools.islice(cf_i(Phi), 7)) == [1, 1, 1, 1, 1, 1, 1]
    assert list(itertools.islice(cf_i(pi), 7)) == [3, 7, 15, 1, 292, 1, 1]

    assert list(cf_i(Rational(17, 12))) == [1, 2, 2, 2]
    assert list(cf_i(Rational(-17, 12))) == [-2, 1, 1, 2, 2]

    assert list(cf_c([1, 6, 1, 8])) == [
        Integer(1),
        Rational(7, 6),
        Rational(8, 7),
        Rational(71, 62)
    ]
    assert list(cf_c([2])) == [Integer(2)]
    assert list(cf_c([1, 1, 1, 1, 1, 1, 1])) == [
        1,
        Integer(2),
        Rational(3, 2),
        Rational(5, 3),
        Rational(8, 5),
        Rational(13, 8),
        Rational(21, 13)
    ]
    assert list(cf_c([1, 6, Rational(
        -1, 2), 4])) == [1, Rational(7, 6),
                         Rational(5, 4),
                         Rational(3, 2)]

    assert cf_r([1, 6, 1, 8]) == Rational(71, 62)
    assert cf_r([3]) == Integer(3)
    assert cf_r([-1, 5, 1, 4]) == Rational(-24, 29)
    assert (cf_r([0, 1, 1, 7, [24, 8]]) - (sqrt(3) + 2) / 7).expand() == 0
    assert cf_r([1, 5, 9]) == Rational(55, 46)
    assert (cf_r([[1]]) - (sqrt(5) + 1) / 2).expand() == 0
Exemple #6
0
    def eval(cls, x, k=None):
        if k is S.Zero:
            return cls(x)
        elif k is None:
            k = S.Zero

        if k is S.Zero:
            if x is S.Zero:
                return S.Zero
            if x is S.Exp1:
                return S.One
            if x == -1/S.Exp1:
                return S.NegativeOne
            if x == -log(2)/2:
                return -log(2)
            if x is S.Infinity:
                return S.Infinity

        if k.is_nonzero:
            if x is S.Zero:
                return S.NegativeInfinity
        if k is S.NegativeOne:
            if x == -S.Pi/2:
                return -S.ImaginaryUnit*S.Pi/2
            elif x == -1/S.Exp1:
                return S.NegativeOne
            elif x == -2*exp(-2):
                return -Integer(2)
Exemple #7
0
 def __iter__(self):
     yield S.Zero
     i = Integer(1)
     while True:
         yield i
         yield -i
         i = i + 1
Exemple #8
0
    def __new__(cls, name, index, system, pretty_str, latex_str):
        name = str(name)
        pretty_str = str(pretty_str)
        latex_str = str(latex_str)
        from diofant.vector.coordsysrect import CoordSysCartesian
        obj = super(BaseScalar, cls).__new__(cls, name)
        if not isinstance(system, CoordSysCartesian):
            raise TypeError("system should be a CoordSysCartesian")
        if index not in range(0, 3):
            raise ValueError("Invalid index specified.")
        # The _id is used for equating purposes, and for hashing
        obj._id = (index, system)
        obj._name = name
        obj._pretty_form = pretty_str
        obj._latex_form = latex_str
        obj._system = system

        # Change the args for the object
        obj._args = tuple([
            Symbol(name),
            Integer(index), system,
            Symbol(pretty_str),
            Symbol(latex_str)
        ])

        return obj
Exemple #9
0
    def eval(cls, n):
        n = sympify(n)

        if n.is_Number:
            if n is S.Zero:
                return S.One
            elif n is S.Infinity:
                return S.Infinity
            elif n.is_Integer:
                if n.is_negative:
                    return S.ComplexInfinity
                else:
                    n, result = n.p, 1

                    if n < 20:
                        for i in range(2, n + 1):
                            result *= i
                    else:
                        N, bits = n, 0

                        while N != 0:
                            if N & 1 == 1:
                                bits += 1

                            N = N >> 1

                        result = cls._recursive(n)*2**(n - bits)

                    return Integer(result)
Exemple #10
0
def continued_fraction_convergents(cf):
    """Return an iterator over the convergents of a continued fraction.

    The parameter should be an iterable returning successive
    partial quotients of the continued fraction, such as might be
    returned by continued_fraction_iterator.  In computing the
    convergents, the continued fraction need not be strictly in
    canonical form (all integers, all but the first positive).
    Rational and negative elements may be present in the expansion.

    Examples
    ========

    >>> from diofant.core import Rational, pi
    >>> from diofant import S
    >>> from diofant.ntheory.continued_fraction import \
            continued_fraction_convergents, continued_fraction_iterator

    >>> list(continued_fraction_convergents([0, 2, 1, 2]))
    [0, 1/2, 1/3, 3/8]

    >>> list(continued_fraction_convergents([1, Rational(1, 2), -7, Rational(1, 4)]))
    [1, 3, 19/5, 7]

    >>> it = continued_fraction_convergents(continued_fraction_iterator(pi))
    >>> for n in range(7):
    ...     print(next(it))
    3
    22/7
    333/106
    355/113
    103993/33102
    104348/33215
    208341/66317

    See Also
    ========

    continued_fraction_iterator
    """
    p_2, q_2 = Integer(0), Integer(1)
    p_1, q_1 = Integer(1), Integer(0)
    for a in cf:
        p, q = a * p_1 + p_2, a * q_1 + q_2
        p_2, q_2 = p_1, q_1
        p_1, q_1 = p, q
        yield p / q
Exemple #11
0
def _eval_sum_hyper(f, i, a):
    """ Returns (res, cond). Sums from a to oo. """
    from diofant.functions import hyper
    from diofant.simplify import hyperexpand, hypersimp, fraction, simplify
    from diofant.polys.polytools import Poly, factor

    if a != 0:
        return _eval_sum_hyper(f.subs(i, i + a), i, 0)

    if f.subs(i, 0) == 0:
        if simplify(f.subs(i, Dummy('i', integer=True, positive=True))) == 0:
            return Integer(0), True
        return _eval_sum_hyper(f.subs(i, i + 1), i, 0)

    hs = hypersimp(f, i)
    if hs is None:
        return

    numer, denom = fraction(factor(hs))
    top, topl = numer.as_coeff_mul(i)
    bot, botl = denom.as_coeff_mul(i)
    ab = [top, bot]
    factors = [topl, botl]
    params = [[], []]
    for k in range(2):
        for fac in factors[k]:
            mul = 1
            if fac.is_Pow:
                mul = fac.exp
                fac = fac.base
                if not mul.is_Integer:
                    return
            p = Poly(fac, i)
            if p.degree() != 1:
                return
            m, n = p.all_coeffs()
            ab[k] *= m**mul
            params[k] += [n / m] * mul

    # Add "1" to numerator parameters, to account for implicit n! in
    # hypergeometric series.
    ap = params[0] + [1]
    bq = params[1]
    x = ab[0] / ab[1]
    h = hyper(ap, bq, x)

    e = h
    try:
        e = hyperexpand(h)
    except PolynomialError:
        pass
    if e is S.NaN and h.convergence_statement:
        e = h

    return f.subs(i, 0) * e, h.convergence_statement
Exemple #12
0
 def _eval_nseries(self, x, n, logx):
     if len(self.args) == 1:
         from diofant import O, Add, Integer, factorial
         x = self.args[0]
         o = O(x**n, x)
         l = S.Zero
         if n > 0:
             l += Add(*[Integer(-k)**(k - 1)*x**k/factorial(k)
                        for k in range(1, n)])
         return l + o
     return super(LambertW, self)._eval_nseries(x, n=n, logx=logx)
Exemple #13
0
def test_visual_factorint():
    assert factorint(1, visual=1) == 1
    forty2 = factorint(42, visual=True)
    assert type(forty2) == Mul
    assert str(forty2) == '2**1*3**1*7**1'
    assert factorint(1, visual=True) is Integer(1)
    no = {'evaluate': False}
    assert factorint(42**2, visual=True) == Mul(Pow(2, 2, **no),
                                                Pow(3, 2, **no),
                                                Pow(7, 2, **no), **no)
    assert -1 in factorint(-42, visual=True).args
Exemple #14
0
        def bkey(b, e=None):
            '''Return (b**s, c.q), c.p where e -> c*s. If e is not given then
            it will be taken by using as_base_exp() on the input b.
            e.g.
                x**3/2 -> (x, 2), 3
                x**y -> (x**y, 1), 1
                x**(2*y/3) -> (x**y, 3), 2
                exp(x/2) -> (exp(a), 2), 1

            '''
            if e is not None:  # coming from c_powers or from below
                if e.is_Integer:
                    return (b, S.One), e
                elif e.is_Rational:
                    return (b, Integer(e.q)), Integer(e.p)
                else:
                    c, m = e.as_coeff_Mul(rational=True)
                    if c is not S.One and b.is_positive:
                        return (b**m, Integer(c.q)), Integer(c.p)
                    else:
                        return (b**e, S.One), S.One
            else:
                return bkey(*b.as_base_exp())
def test_scalar_potential_difference():
    point1 = C.origin.locate_new('P1', 1 * i + 2 * j + 3 * k)
    point2 = C.origin.locate_new('P2', 4 * i + 5 * j + 6 * k)
    genericpointC = C.origin.locate_new('RP', x * i + y * j + z * k)
    genericpointP = P.origin.locate_new('PP',
                                        P.x * P.i + P.y * P.j + P.z * P.k)
    assert scalar_potential_difference(Integer(0), C, point1, point2) == 0
    assert (scalar_potential_difference(scalar_field, C, C.origin,
                                        genericpointC) == scalar_field)
    assert (scalar_potential_difference(grad_field, C, C.origin,
                                        genericpointC) == scalar_field)
    assert scalar_potential_difference(grad_field, C, point1, point2) == 948
    assert (scalar_potential_difference(y * z * i + x * z * j + x * y * k, C,
                                        point1,
                                        genericpointC) == x * y * z - 6)
    potential_diff_P = (2 * P.z * (P.x * sin(q) + P.y * cos(q)) *
                        (P.x * cos(q) - P.y * sin(q))**2)
    assert (scalar_potential_difference(
        grad_field, P, P.origin, genericpointP).simplify() == potential_diff_P)

    pytest.raises(
        TypeError,
        lambda: scalar_potential_difference(Integer(0), 1, point1, point2))
Exemple #16
0
 def _eval_aseries(self, n, args0, x, logx):
     from diofant import Order
     if args0[0] != oo:
         return super(loggamma, self)._eval_aseries(n, args0, x, logx)
     z = self.args[0]
     m = min(n, ceiling((n + Integer(1)) / 2))
     r = log(z) * (z - Rational(1, 2)) - z + log(2 * pi) / 2
     l = [
         bernoulli(2 * k) / (2 * k * (2 * k - 1) * z**(2 * k - 1))
         for k in range(1, m)
     ]
     o = None
     if m == 0:
         o = Order(1, x)
     else:
         o = Order(1 / z**(2 * m - 1), x)
     # It is very inefficient to first add the order and then do the nseries
     return (r + Add(*l))._eval_nseries(x, n, logx) + o
Exemple #17
0
def _real_to_rational(expr, tolerance=None):
    """
    Replace all reals in expr with rationals.

    >>> from diofant import nsimplify
    >>> from diofant.abc import x

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

    """
    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 < 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)
Exemple #18
0
    def _eval(cls, n, k):
        # n.is_Number and k.is_Integer and k != 1 and n != k
        if k.is_Integer:
            if n.is_Integer and n >= 0:
                n, k = int(n), int(k)

                if k > n:
                    return S.Zero
                elif k > n // 2:
                    k = n - k

                M, result = int(_sqrt(n)), 1

                for prime in sieve.primerange(2, n + 1):
                    if prime > n - k:
                        result *= prime
                    elif prime > n // 2:
                        continue
                    elif prime > M:
                        if n % prime < k % prime:
                            result *= prime
                    else:
                        N, K = n, k
                        exp = a = 0

                        while N > 0:
                            a = int((N % prime) < (K % prime + a))
                            N, K = N // prime, K // prime
                            exp = a + exp

                        if exp > 0:
                            result *= prime**exp
                return Integer(result)
            else:
                d = result = n - k + 1
                for i in range(2, k + 1):
                    d += 1
                    result *= d
                    result /= i
                return result
Exemple #19
0
    def _try_heuristics(f):
        """Find roots using formulas and some tricks. """
        if f.is_ground:
            return []
        if f.is_monomial:
            return [Integer(0)]*f.degree()

        if f.length() == 2:
            if f.degree() == 1:
                return list(map(cancel, roots_linear(f)))
            else:
                return roots_binomial(f)

        result = []

        for i in [-1, 1]:
            if not f.eval(i):
                f = f.quo(Poly(f.gen - i, f.gen))
                result.append(i)
                break

        n = f.degree()

        if n == 1:
            result += list(map(cancel, roots_linear(f)))
        elif n == 2:
            result += list(map(cancel, roots_quadratic(f)))
        elif f.is_cyclotomic:
            result += roots_cyclotomic(f)
        elif n == 3 and cubics:
            result += roots_cubic(f, trig=trig)
        elif n == 4 and quartics:
            result += roots_quartic(f)
        elif n == 5 and quintics:
            result += roots_quintic(f)

        return result
Exemple #20
0
    def __new__(cls, *args):
        from diofant.functions.elementary.integers import ceiling
        # expand range
        slc = slice(*args)
        start, stop, step = slc.start or 0, slc.stop, slc.step or 1
        try:
            start, stop, step = [
                w if w in [S.NegativeInfinity, S.Infinity] else Integer(
                    as_int(w)) for w in (start, stop, step)
            ]
        except ValueError:
            raise ValueError("Inputs to Range must be Integer Valued\n" +
                             "Use ImageSets of Ranges for other cases")

        if not step.is_finite:
            raise ValueError("Infinite step is not allowed")
        if start == stop:
            return S.EmptySet

        n = ceiling((stop - start) / step)
        if n <= 0:
            return S.EmptySet

        # normalize args: regardless of how they are entered they will show
        # canonically as Range(inf, sup, step) with step > 0
        if n.is_finite:
            start, stop = sorted((start, start + (n - 1) * step))
        else:
            start, stop = sorted((start, stop - step))

        step = abs(step)
        if (start, stop) == (S.NegativeInfinity, S.Infinity):
            raise ValueError("Both the start and end value of "
                             "Range cannot be unbounded")
        else:
            return Basic.__new__(cls, start, stop + step, step)
Exemple #21
0
    def eval(cls, arg):
        from diofant import im
        if arg.is_integer:
            return arg
        if arg.func is cls:
            return arg
        if arg.is_imaginary or (S.ImaginaryUnit * arg).is_extended_real:
            i = im(arg)
            if not i.has(S.ImaginaryUnit):
                return cls(i) * S.ImaginaryUnit
            return cls(arg, evaluate=False)

        v = cls._eval_number(arg)
        if v is not None:
            return v

        # Integral, numerical, symbolic part
        ipart = npart = spart = S.Zero

        # Extract integral (or complex integral) terms
        terms = Add.make_args(arg)

        for t in terms:
            if t.is_integer or (t.is_imaginary and im(t).is_integer):
                ipart += t
            elif t.has(Dummy, Symbol):
                spart += t
            else:
                npart += t

        if not (npart or spart):
            return ipart

        # Evaluate npart numerically if independent of spart
        if npart and (not spart or npart.is_extended_real and
                      (spart.is_imaginary or
                       (S.ImaginaryUnit * spart).is_extended_real)
                      or npart.is_imaginary and spart.is_extended_real):
            try:
                from diofant.core.evalf import DEFAULT_MAXPREC as TARGET
                prec = 10
                while True:
                    r, i = cls(npart,
                               evaluate=False).evalf(prec).as_real_imag()
                    if 2**prec > max(abs(int(r)), abs(int(i))) + 10:
                        break
                    else:
                        if prec >= TARGET:
                            raise PrecisionExhausted
                        prec += 10
                ipart += Integer(r) + Integer(i) * S.ImaginaryUnit
                npart = S.Zero
            except (PrecisionExhausted, NotImplementedError):
                pass

        spart += npart
        if not spart:
            return ipart
        elif spart.is_imaginary or (S.ImaginaryUnit * spart).is_extended_real:
            return ipart + cls(im(spart), evaluate=False) * S.ImaginaryUnit
        else:
            return ipart + cls(spart, evaluate=False)
Exemple #22
0
def test_del_operator():

    # Tests for curl
    assert (delop
            ^ Vector.zero == (Derivative(0, C.y) - Derivative(0, C.z)) * C.i +
            (-Derivative(0, C.x) + Derivative(0, C.z)) * C.j +
            (Derivative(0, C.x) - Derivative(0, C.y)) * C.k)
    assert ((delop ^ Vector.zero).doit() == Vector.zero == curl(
        Vector.zero, C))
    assert delop.cross(Vector.zero) == delop ^ Vector.zero
    assert (delop ^ i).doit() == Vector.zero
    assert delop.cross(2 * y**2 * j, doit=True) == Vector.zero
    assert delop.cross(2 * y**2 * j) == delop ^ 2 * y**2 * j
    v = x * y * z * (i + j + k)
    assert ((delop ^ v).doit() == (-x * y + x * z) * i + (x * y - y * z) * j +
            (-x * z + y * z) * k == curl(v, C))
    assert delop ^ v == delop.cross(v)
    assert (delop.cross(
        2 * x**2 *
        j) == (Derivative(0, C.y) - Derivative(2 * C.x**2, C.z)) * C.i +
            (-Derivative(0, C.x) + Derivative(0, C.z)) * C.j +
            (-Derivative(0, C.y) + Derivative(2 * C.x**2, C.x)) * C.k)
    assert (delop.cross(2 * x**2 * j, doit=True) == 4 * x * k == curl(
        2 * x**2 * j, C))

    # Tests for divergence
    assert delop & Vector.zero == Integer(0) == divergence(Vector.zero, C)
    assert (delop & Vector.zero).doit() == Integer(0)
    assert delop.dot(Vector.zero) == delop & Vector.zero
    assert (delop & i).doit() == Integer(0)
    assert (delop & x**2 * i).doit() == 2 * x == divergence(x**2 * i, C)
    assert (delop.dot(v, doit=True) == x * y + y * z + z * x == divergence(
        v, C))
    assert delop & v == delop.dot(v)
    assert delop.dot(1/(x*y*z) * (i + j + k), doit=True) == \
           - 1 / (x*y*z**2) - 1 / (x*y**2*z) - 1 / (x**2*y*z)
    v = x * i + y * j + z * k
    assert (delop & v == Derivative(C.x, C.x) + Derivative(C.y, C.y) +
            Derivative(C.z, C.z))
    assert delop.dot(v, doit=True) == 3 == divergence(v, C)
    assert delop & v == delop.dot(v)
    assert simplify((delop & v).doit()) == 3

    # Tests for gradient
    assert (delop.gradient(0, doit=True) == Vector.zero == gradient(0, C))
    assert delop.gradient(0) == delop(0)
    assert (delop(Integer(0))).doit() == Vector.zero
    assert (delop(x) == (Derivative(C.x, C.x)) * C.i +
            (Derivative(C.x, C.y)) * C.j + (Derivative(C.x, C.z)) * C.k)
    assert (delop(x)).doit() == i == gradient(x, C)
    assert (delop(x * y * z) == (Derivative(C.x * C.y * C.z, C.x)) * C.i +
            (Derivative(C.x * C.y * C.z, C.y)) * C.j +
            (Derivative(C.x * C.y * C.z, C.z)) * C.k)
    assert (delop.gradient(x * y * z, doit=True) ==
            y * z * i + z * x * j + x * y * k == gradient(x * y * z, C))
    assert delop(x * y * z) == delop.gradient(x * y * z)
    assert (delop(2 * x**2)).doit() == 4 * x * i
    assert ((delop(a * sin(y) / x)).doit() == -a * sin(y) / x**2 * i +
            a * cos(y) / x * j)

    # Tests for directional derivative
    assert (Vector.zero & delop)(a) == Integer(0)
    assert ((Vector.zero & delop)(a)).doit() == Integer(0)
    assert ((v & delop)(Vector.zero)).doit() == Vector.zero
    assert ((v & delop)(Integer(0))).doit() == Integer(0)
    assert ((i & delop)(x)).doit() == 1
    assert ((j & delop)(y)).doit() == 1
    assert ((k & delop)(z)).doit() == 1
    assert ((i & delop)(x * y * z)).doit() == y * z
    assert ((v & delop)(x)).doit() == x
    assert ((v & delop)(x * y * z)).doit() == 3 * x * y * z
    assert (v & delop)(x + y + z) == C.x + C.y + C.z
    assert ((v & delop)(x + y + z)).doit() == x + y + z
    assert ((v & delop)(v)).doit() == v
    assert ((i & delop)(v)).doit() == i
    assert ((j & delop)(v)).doit() == j
    assert ((k & delop)(v)).doit() == k
    assert ((v & delop)(Vector.zero)).doit() == Vector.zero
Exemple #23
0
def continued_fraction_reduce(cf):
    """Reduce a continued fraction to a rational or quadratic irrational.

    Compute the rational or quadratic irrational number from its
    terminating or periodic continued fraction expansion.  The
    continued fraction expansion (cf) should be supplied as a
    terminating iterator supplying the terms of the expansion.  For
    terminating continued fractions, this is equivalent to
    ``list(continued_fraction_convergents(cf))[-1]``, only a little more
    efficient.  If the expansion has a repeating part, a list of the
    repeating terms should be returned as the last element from the
    iterator.  This is the format returned by
    continued_fraction_periodic.

    For quadratic irrationals, returns the largest solution found,
    which is generally the one sought, if the fraction is in canonical
    form (all terms positive except possibly the first).

    Examples
    ========

    >>> from diofant.ntheory.continued_fraction import continued_fraction_reduce
    >>> continued_fraction_reduce([1, 2, 3, 4, 5])
    225/157
    >>> continued_fraction_reduce([-2, 1, 9, 7, 1, 2])
    -256/233
    >>> continued_fraction_reduce([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8]).n(10)
    2.718281835
    >>> continued_fraction_reduce([1, 4, 2, [3, 1]])
    (sqrt(21) + 287)/238
    >>> continued_fraction_reduce([[1]])
    1/2 + sqrt(5)/2
    >>> from diofant.ntheory.continued_fraction import continued_fraction_periodic
    >>> continued_fraction_reduce(continued_fraction_periodic(8, 5, 13))
    (sqrt(13) + 8)/5

    See Also
    ========

    continued_fraction_periodic
    """
    from diofant.core.symbol import Dummy
    from diofant.solvers import solve

    period = []
    x = Dummy('x')

    def untillist(cf):
        for nxt in cf:
            if isinstance(nxt, list):
                period.extend(nxt)
                yield x
                break
            yield nxt

    a = Integer(0)
    for a in continued_fraction_convergents(untillist(cf)):
        pass

    if period:
        y = Dummy('y')
        solns = solve(continued_fraction_reduce(period + [y]) - y, y)
        solns.sort()
        pure = solns[-1]
        return a.subs(x, pure).radsimp()
    else:
        return a
Exemple #24
0
def roots_cubic(f, trig=False):
    """Returns a list of roots of a cubic polynomial.

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Cubic_function, General
           formula for roots, (accessed November 17, 2014).
    """
    if trig:
        a, b, c, d = f.all_coeffs()
        p = (3*a*c - b**2)/3/a**2
        q = (2*b**3 - 9*a*b*c + 27*a**2*d)/(27*a**3)
        D = 18*a*b*c*d - 4*b**3*d + b**2*c**2 - 4*a*c**3 - 27*a**2*d**2
        if (D > 0) is S.true:
            rv = []
            for k in range(3):
                rv.append(2*sqrt(-p/3)*cos(acos(3*q/2/p*sqrt(-3/p))/3 - k*2*pi/3))
            return [i - b/3/a for i in rv]

    _, a, b, c = f.monic().all_coeffs()

    if c is S.Zero:
        x1, x2 = roots([1, a, b], multiple=True)
        return [x1, S.Zero, x2]

    p = b - a**2/3
    q = c - a*b/3 + 2*a**3/27

    pon3 = p/3
    aon3 = a/3

    u1 = None
    if p is S.Zero:
        if q is S.Zero:
            return [-aon3]*3
        if q.is_extended_real:
            if q.is_positive:
                u1 = -root(q, 3)
            elif q.is_negative:
                u1 = root(-q, 3)
    elif q is S.Zero:
        y1, y2 = roots([1, 0, p], multiple=True)
        return [tmp - aon3 for tmp in [y1, S.Zero, y2]]
    elif q.is_extended_real and q.is_negative:
        u1 = -root(-q/2 + sqrt(q**2/4 + pon3**3), 3)

    coeff = I*sqrt(3)/2
    if u1 is None:
        u1 = Integer(1)
        u2 = -S.Half + coeff
        u3 = -S.Half - coeff
        a, b, c, d = Integer(1), a, b, c
        D0 = b**2 - 3*a*c
        D1 = 2*b**3 - 9*a*b*c + 27*a**2*d
        C = root((D1 + sqrt(D1**2 - 4*D0**3))/2, 3)
        return [-(b + uk*C + D0/C/uk)/3/a for uk in [u1, u2, u3]]

    u2 = u1*(-S.Half + coeff)
    u3 = u1*(-S.Half - coeff)

    if p is S.Zero:
        return [u1 - aon3, u2 - aon3, u3 - aon3]

    soln = [
        -u1 + pon3/u1 - aon3,
        -u2 + pon3/u2 - aon3,
        -u3 + pon3/u3 - aon3
    ]

    return soln
Exemple #25
0
def roots_quintic(f):
    """
    Calulate exact roots of a solvable quintic
    """
    result = []
    coeff_5, coeff_4, p, q, r, s = f.all_coeffs()

    # Eqn must be of the form x^5 + px^3 + qx^2 + rx + s
    if coeff_4:
        return result

    if coeff_5 != 1:
        l = [p/coeff_5, q/coeff_5, r/coeff_5, s/coeff_5]
        if not all(coeff.is_Rational for coeff in l):
            return result
        f = Poly(f/coeff_5)
    quintic = PolyQuintic(f)

    # Eqn standardized. Algo for solving starts here
    if not f.is_irreducible:
        return result

    f20 = quintic.f20
    # Check if f20 has linear factors over domain Z
    if f20.is_irreducible:
        return result

    # Now, we know that f is solvable
    for _factor in f20.factor_list()[1]:
        if _factor[0].is_linear:
            theta = _factor[0].root(0)
            break
    d = discriminant(f)
    delta = sqrt(d)
    # zeta = a fifth root of unity
    zeta1, zeta2, zeta3, zeta4 = quintic.zeta
    T = quintic.T(theta, d)
    tol = Float(1e-10)
    alpha = T[1] + T[2]*delta
    alpha_bar = T[1] - T[2]*delta
    beta = T[3] + T[4]*delta
    beta_bar = T[3] - T[4]*delta

    disc = alpha**2 - 4*beta
    disc_bar = alpha_bar**2 - 4*beta_bar

    l0 = quintic.l0(theta)

    l1 = _quintic_simplify((-alpha + sqrt(disc)) / Integer(2))
    l4 = _quintic_simplify((-alpha - sqrt(disc)) / Integer(2))

    l2 = _quintic_simplify((-alpha_bar + sqrt(disc_bar)) / Integer(2))
    l3 = _quintic_simplify((-alpha_bar - sqrt(disc_bar)) / Integer(2))

    order = quintic.order(theta, d)
    test = (order*delta.n()) - ( (l1.n() - l4.n())*(l2.n() - l3.n()) )
    # Comparing floats
    if not comp(test, 0, tol):
        l2, l3 = l3, l2

    # Now we have correct order of l's
    R1 = l0 + l1*zeta1 + l2*zeta2 + l3*zeta3 + l4*zeta4
    R2 = l0 + l3*zeta1 + l1*zeta2 + l4*zeta3 + l2*zeta4
    R3 = l0 + l2*zeta1 + l4*zeta2 + l1*zeta3 + l3*zeta4
    R4 = l0 + l4*zeta1 + l3*zeta2 + l2*zeta3 + l1*zeta4

    Res = [None, [None]*5, [None]*5, [None]*5, [None]*5]
    Res_n = [None, [None]*5, [None]*5, [None]*5, [None]*5]
    sol = Symbol('sol')

    # Simplifying improves performace a lot for exact expressions
    R1 = _quintic_simplify(R1)
    R2 = _quintic_simplify(R2)
    R3 = _quintic_simplify(R3)
    R4 = _quintic_simplify(R4)

    # Solve imported here. Causing problems if imported as 'solve'
    # and hence the changed name
    from diofant.solvers.solvers import solve as _solve
    a, b = symbols('a b', cls=Dummy)
    _sol = _solve( sol**5 - a - I*b, sol)
    for i in range(5):
        _sol[i] = factor(_sol[i])
    R1 = R1.as_real_imag()
    R2 = R2.as_real_imag()
    R3 = R3.as_real_imag()
    R4 = R4.as_real_imag()

    for i, root in enumerate(_sol):
        Res[1][i] = _quintic_simplify(root.subs({ a: R1[0], b: R1[1] }))
        Res[2][i] = _quintic_simplify(root.subs({ a: R2[0], b: R2[1] }))
        Res[3][i] = _quintic_simplify(root.subs({ a: R3[0], b: R3[1] }))
        Res[4][i] = _quintic_simplify(root.subs({ a: R4[0], b: R4[1] }))

    for i in range(1, 5):
        for j in range(5):
            Res_n[i][j] = Res[i][j].n()
            Res[i][j] = _quintic_simplify(Res[i][j])
    r1 = Res[1][0]
    r1_n = Res_n[1][0]

    for i in range(5):
        if comp(im(r1_n*Res_n[4][i]), 0, tol):
            r4 = Res[4][i]
            break

    u, v = quintic.uv(theta, d)
    sqrt5 = math.sqrt(5)

    # Now we have various Res values. Each will be a list of five
    # values. We have to pick one r value from those five for each Res
    u, v = quintic.uv(theta, d)
    testplus = (u + v*delta*sqrt(5)).n()
    testminus = (u - v*delta*sqrt(5)).n()

    # Evaluated numbers suffixed with _n
    # We will use evaluated numbers for calculation. Much faster.
    r4_n = r4.n()
    r2 = r3 = None

    for i in range(5):
        r2temp_n = Res_n[2][i]
        for j in range(5):
            # Again storing away the exact number and using
            # evaluated numbers in computations
            r3temp_n = Res_n[3][j]

            if (comp(r1_n*r2temp_n**2 + r4_n*r3temp_n**2 - testplus, 0, tol) and
                    comp(r3temp_n*r1_n**2 + r2temp_n*r4_n**2 - testminus, 0, tol)):
                r2 = Res[2][i]
                r3 = Res[3][j]
                break
        if r2:
            break

    # Now, we have r's so we can get roots
    x1 = (r1 + r2 + r3 + r4)/5
    x2 = (r1*zeta4 + r2*zeta3 + r3*zeta2 + r4*zeta1)/5
    x3 = (r1*zeta3 + r2*zeta1 + r3*zeta4 + r4*zeta2)/5
    x4 = (r1*zeta2 + r2*zeta4 + r3*zeta1 + r4*zeta3)/5
    x5 = (r1*zeta1 + r2*zeta2 + r3*zeta3 + r4*zeta4)/5
    result = [x1, x2, x3, x4, x5]

    # Now check if solutions are distinct

    saw = set()
    for r in result:
        r = r.n(2)
        if r in saw:
            # Roots were identical. Abort, return []
            # and fall back to usual solve
            return []
        saw.add(r)
    return result
Exemple #26
0
def roots(f, *gens, **flags):
    """
    Computes symbolic roots of a univariate polynomial.

    Given a univariate polynomial f with symbolic coefficients (or
    a list of the polynomial's coefficients), returns a dictionary
    with its roots and their multiplicities.

    Only roots expressible via radicals will be returned.  To get
    a complete set of roots use RootOf class or numerical methods
    instead. By default cubic and quartic formulas are used in
    the algorithm. To disable them because of unreadable output
    set ``cubics=False`` or ``quartics=False`` respectively. If cubic
    roots are real but are expressed in terms of complex numbers
    (casus irreducibilis [1]) the ``trig`` flag can be set to True to
    have the solutions returned in terms of cosine and inverse cosine
    functions.

    To get roots from a specific domain set the ``filter`` flag with
    one of the following specifiers: Z, Q, R, I, C. By default all
    roots are returned (this is equivalent to setting ``filter='C'``).

    By default a dictionary is returned giving a compact result in
    case of multiple roots.  However to get a list containing all
    those roots set the ``multiple`` flag to True; the list will
    have identical roots appearing next to each other in the result.
    (For a given Poly, the all_roots method will give the roots in
    sorted numerical order.)

    Examples
    ========

    >>> from diofant import Poly, roots, sqrt
    >>> from diofant.abc import x, y

    >>> roots(x**2 - 1, x) == {-1: 1, 1: 1}
    True

    >>> p = Poly(x**2-1, x)
    >>> roots(p) == {-1: 1, 1: 1}
    True

    >>> p = Poly(x**2-y, x, y)

    >>> roots(Poly(p, x)) == {-sqrt(y): 1, sqrt(y): 1}
    True

    >>> roots(x**2 - y, x) == {-sqrt(y): 1, sqrt(y): 1}
    True

    >>> roots([1, 0, -1]) == {-1: 1, 1: 1}
    True

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Cubic_function#Trigonometric_.28and_hyperbolic.29_method
    """
    from diofant.polys.polytools import to_rational_coeffs
    flags = dict(flags)

    auto = flags.pop('auto', True)
    cubics = flags.pop('cubics', True)
    trig = flags.pop('trig', False)
    quartics = flags.pop('quartics', True)
    quintics = flags.pop('quintics', False)
    multiple = flags.pop('multiple', False)
    filter = flags.pop('filter', None)
    predicate = flags.pop('predicate', None)

    if isinstance(f, list):
        if gens:
            raise ValueError('redundant generators given')

        x = Dummy('x')

        poly, i = {}, len(f) - 1

        for coeff in f:
            poly[i], i = sympify(coeff), i - 1

        f = Poly(poly, x, field=True)
    else:
        try:
            f = Poly(f, *gens, **flags)
            if f.length == 2 and f.degree() != 1:
                # check for foo**n factors in the constant
                n = f.degree()
                npow_bases = []
                expr = f.as_expr()
                con = expr.as_independent(*gens)[0]
                for p in Mul.make_args(con):
                    if p.is_Pow and not p.exp % n:
                        npow_bases.append(p.base**(p.exp/n))
                    else:
                        other.append(p)
                    if npow_bases:
                        b = Mul(*npow_bases)
                        B = Dummy()
                        d = roots(Poly(expr - con + B**n*Mul(*others), *gens,
                            **flags), *gens, **flags)
                        rv = {}
                        for k, v in d.items():
                            rv[k.subs(B, b)] = v
                        return rv

        except GeneratorsNeeded:
            if multiple:
                return []
            else:
                return {}

        if f.is_multivariate:
            raise PolynomialError('multivariate polynomials are not supported')

    def _update_dict(result, root, k):
        if root in result:
            result[root] += k
        else:
            result[root] = k

    def _try_decompose(f):
        """Find roots using functional decomposition. """
        factors, roots = f.decompose(), []

        for root in _try_heuristics(factors[0]):
            roots.append(root)

        for factor in factors[1:]:
            previous, roots = list(roots), []

            for root in previous:
                g = factor - Poly(root, f.gen)

                for root in _try_heuristics(g):
                    roots.append(root)

        return roots

    def _try_heuristics(f):
        """Find roots using formulas and some tricks. """
        if f.is_ground:
            return []
        if f.is_monomial:
            return [Integer(0)]*f.degree()

        if f.length() == 2:
            if f.degree() == 1:
                return list(map(cancel, roots_linear(f)))
            else:
                return roots_binomial(f)

        result = []

        for i in [-1, 1]:
            if not f.eval(i):
                f = f.quo(Poly(f.gen - i, f.gen))
                result.append(i)
                break

        n = f.degree()

        if n == 1:
            result += list(map(cancel, roots_linear(f)))
        elif n == 2:
            result += list(map(cancel, roots_quadratic(f)))
        elif f.is_cyclotomic:
            result += roots_cyclotomic(f)
        elif n == 3 and cubics:
            result += roots_cubic(f, trig=trig)
        elif n == 4 and quartics:
            result += roots_quartic(f)
        elif n == 5 and quintics:
            result += roots_quintic(f)

        return result

    (k,), f = f.terms_gcd()

    if not k:
        zeros = {}
    else:
        zeros = {Integer(0): k}

    coeff, f = preprocess_roots(f)

    if auto and f.get_domain().has_Ring:
        f = f.to_field()

    rescale_x = None
    translate_x = None

    result = {}

    if not f.is_ground:
        if not f.get_domain().is_Exact:
            for r in f.nroots():
                _update_dict(result, r, 1)
        elif f.degree() == 1:
            result[roots_linear(f)[0]] = 1
        elif f.length() == 2:
            roots_fun = roots_quadratic if f.degree() == 2 else roots_binomial
            for r in roots_fun(f):
                _update_dict(result, r, 1)
        else:
            _, factors = Poly(f.as_expr()).factor_list()
            if len(factors) == 1 and f.degree() == 2:
                for r in roots_quadratic(f):
                    _update_dict(result, r, 1)
            else:
                if len(factors) == 1 and factors[0][1] == 1:
                    if f.get_domain().is_EX:
                        res = to_rational_coeffs(f)
                        if res:
                            if res[0] is None:
                                translate_x, f = res[2:]
                            else:
                                rescale_x, f = res[1], res[-1]
                            result = roots(f)
                            if not result:
                                for root in _try_decompose(f):
                                    _update_dict(result, root, 1)
                    else:
                        for root in _try_decompose(f):
                            _update_dict(result, root, 1)
                else:
                    for factor, k in factors:
                        for r in _try_heuristics(Poly(factor, f.gen, field=True)):
                            _update_dict(result, r, k)

    if coeff is not S.One:
        _result, result, = result, {}

        for root, k in _result.items():
            result[coeff*root] = k

    result.update(zeros)

    if filter not in [None, 'C']:
        handlers = {
            'Z': lambda r: r.is_Integer,
            'Q': lambda r: r.is_Rational,
            'R': lambda r: r.is_extended_real,
            'I': lambda r: r.is_imaginary,
        }

        try:
            query = handlers[filter]
        except KeyError:
            raise ValueError("Invalid filter: %s" % filter)

        for zero in dict(result).keys():
            if not query(zero):
                del result[zero]

    if predicate is not None:
        for zero in dict(result).keys():
            if not predicate(zero):
                del result[zero]
    if rescale_x:
        result1 = {}
        for k, v in result.items():
            result1[k*rescale_x] = v
        result = result1
    if translate_x:
        result1 = {}
        for k, v in result.items():
            result1[k + translate_x] = v
        result = result1

    if not multiple:
        return result
    else:
        zeros = []

        for zero in ordered(result):
            zeros.extend([zero]*result[zero])

        return zeros
Exemple #27
0
def test_core_numbers():
    for c in (Integer(2), Rational(2, 3), Float("1.2")):
        check(c)
Exemple #28
0
def test_sympyissue_6981():
    S = set(divisors(4)).union(set(divisors(Integer(2))))
    assert S == {1, 2, 4}
Exemple #29
0
    def dot(self, other):
        """
        Returns the dot product of this Vector, either with another
        Vector, or a Dyadic, or a Del operator.
        If 'other' is a Vector, returns the dot product scalar (Diofant
        expression).
        If 'other' is a Dyadic, the dot product is returned as a Vector.
        If 'other' is an instance of Del, returns the directional
        derivate operator as a Python function. If this function is
        applied to a scalar expression, it returns the directional
        derivative of the scalar field wrt this Vector.

        Parameters
        ==========

        other: Vector/Dyadic/Del
            The Vector or Dyadic we are dotting with, or a Del operator .

        Examples
        ========

        >>> from diofant.vector import CoordSysCartesian
        >>> C = CoordSysCartesian('C')
        >>> C.i.dot(C.j)
        0
        >>> C.i & C.i
        1
        >>> v = 3*C.i + 4*C.j + 5*C.k
        >>> v.dot(C.k)
        5
        >>> (C.i & C.delop)(C.x*C.y*C.z)
        C.y*C.z
        >>> d = C.i.outer(C.i)
        >>> C.i.dot(d)
        C.i

        """

        from diofant.vector.functions import express
        # Check special cases
        if isinstance(other, Dyadic):
            if isinstance(self, VectorZero):
                return Vector.zero
            outvec = Vector.zero
            for k, v in other.components.items():
                vect_dot = k.args[0].dot(self)
                outvec += vect_dot * v * k.args[1]
            return outvec
        from diofant.vector.deloperator import Del
        if not isinstance(other, Vector) and not isinstance(other, Del):
            raise TypeError(str(other) + " is not a vector, dyadic or " +
                            "del operator")

        # Check if the other is a del operator
        if isinstance(other, Del):
            def directional_derivative(field):
                field = express(field, other.system, variables=True)
                out = self.dot(other._i) * df(field, other._x)
                out += self.dot(other._j) * df(field, other._y)
                out += self.dot(other._k) * df(field, other._z)
                if out == 0 and isinstance(field, Vector):
                    out = Vector.zero
                return out
            return directional_derivative

        if isinstance(self, VectorZero) or isinstance(other, VectorZero):
            return Integer(0)

        v1 = express(self, other._sys)
        v2 = express(other, other._sys)
        dotproduct = Integer(0)
        for x in other._sys.base_vectors():
            dotproduct += (v1.components.get(x, 0) *
                           v2.components.get(x, 0))

        return dotproduct
Exemple #30
0
 def as_base_exp(self):
     if self.exp == 0:
         return self, Integer(1)
     return self.func(1), Mul(*self.args)