Exemple #1
0
def swinnerton_dyer_poly(n, x=None, **args):
    """Generates n-th Swinnerton-Dyer polynomial in `x`.  """
    from .numberfields import minimal_polynomial
    if n <= 0:
        raise ValueError(
            "can't generate Swinnerton-Dyer polynomial of order %s" % n)

    if x is not None:
        sympify(x)
    else:
        x = Dummy('x')

    if n > 3:
        p = 2
        a = [sqrt(2)]
        for i in range(2, n + 1):
            p = nextprime(p)
            a.append(sqrt(p))
        return minimal_polynomial(Add(*a), x, polys=args.get('polys', False))

    if n == 1:
        ex = x**2 - 2
    elif n == 2:
        ex = x**4 - 10 * x**2 + 1
    elif n == 3:
        ex = x**8 - 40 * x**6 + 352 * x**4 - 960 * x**2 + 576
    if not args.get('polys', False):
        return ex
    else:
        return PurePoly(ex, x)
Exemple #2
0
    def eval(cls, x, k):
        x = sympify(x)
        k = sympify(k)

        if k.is_Integer:
            if k is S.Zero:
                return S.One
            else:
                if k.is_positive:
                    if x is S.Infinity:
                        return S.Infinity
                    elif x is S.NegativeInfinity:
                        if k.is_odd:
                            return S.NegativeInfinity
                        else:
                            return S.Infinity
                    else:
                        return reduce(lambda r, i: r*(x - i), range(0, int(k)), 1)
                else:
                    if x is S.Infinity:
                        return S.Infinity
                    elif x is S.NegativeInfinity:
                        return S.Infinity
                    else:
                        return 1/reduce(lambda r, i: r*(x + i), range(1, abs(int(k)) + 1), 1)
Exemple #3
0
def singularities(f, x):
    """Find singularities of real-valued function `f` with respect to `x`.

    Examples
    ========

    >>> from diofant import Symbol, exp, log
    >>> from diofant.abc import x

    >>> singularities(1/(1 + x), x) == {-1}
    True

    >>> singularities(exp(1/x) + log(x + 1), x) == {-1, 0}
    True

    >>> singularities(exp(1/log(x + 1)), x) == {0}
    True

    Notes
    =====

    Removable singularities are not supported now.

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Mathematical_singularity
    """
    f, x = sympify(f), sympify(x)
    guess, res = set(), set()

    assert x.is_Symbol

    if f.is_number:
        return set()
    elif f.is_polynomial(x):
        return set()
    elif f.func in (Add, Mul):
        guess = guess.union(*[singularities(a, x) for a in f.args])
    elif f.func is Pow:
        if f.exp.is_number and f.exp.is_negative:
            guess = {v for v in solve(f.base, x) if v.is_real}
        else:
            guess |= singularities(log(f.base)*f.exp, x)
    elif f.func in (log, sign) and len(f.args) == 1:
        guess |= singularities(f.args[0], x)
        guess |= {v for v in solve(f.args[0], x) if v.is_real}
    else:  # pragma: no cover
        raise NotImplementedError

    for s in guess:
        l = Limit(f, x, s, dir="real")
        try:
            r = l.doit()
            if r == l or f.subs(x, s) != r:  # pragma: no cover
                raise NotImplementedError
        except PoleError:
            res.add(s)

    return res
Exemple #4
0
def bisect(f, a, b, tol):
    """
    Implements bisection. This function is used in RootOf.eval_rational() and
    it needs to be robust.

    Examples
    ========

    >>> from diofant import Rational

    >>> bisect(lambda x: x**2-1, -10, 0, Rational(1, 10)**2)
    -1025/1024
    >>> bisect(lambda x: x**2-1, -10, 0, Rational(1, 10)**4)
    -131075/131072
    """
    a = sympify(a)
    b = sympify(b)
    fa = f(a)
    fb = f(b)
    if fa * fb >= 0:
        raise ValueError("bisect: f(a) and f(b) must have opposite signs")
    while (b - a > tol):
        c = (a + b) / 2
        fc = f(c)
        if (fc == 0):
            return c  # We need to make sure f(c) is not zero below
        if (fa * fc < 0):
            b = c
            fb = fc
        else:
            a = c
            fa = fc
    return (a + b) / 2
Exemple #5
0
def nthroot(expr, n, max_len=4, prec=15):
    """
    compute a real nth-root of a sum of surds

    Parameters
    ==========

    expr : sum of surds
    n : integer
    max_len : maximum number of surds passed as constants to ``nsimplify``

    Notes
    =====

    First ``nsimplify`` is used to get a candidate root; if it is not a
    root the minimal polynomial is computed; the answer is one of its
    roots.

    Examples
    ========

    >>> from diofant.simplify.simplify import nthroot
    >>> from diofant import sqrt
    >>> nthroot(90 + 34*sqrt(7), 3)
    sqrt(7) + 3
    """
    expr = sympify(expr)
    n = sympify(n)
    p = expr**Rational(1, n)
    if not n.is_integer:
        return p
    if not _is_sum_surds(expr):
        return p
    surds = []
    coeff_muls = [x.as_coeff_Mul() for x in expr.args]
    for x, y in coeff_muls:
        if not x.is_rational:
            return p
        if y is S.One:
            continue
        if not (y.is_Pow and y.exp == S.Half and y.base.is_integer):
            return p
        surds.append(y)
    surds.sort()
    surds = surds[:max_len]
    if expr < 0 and n % 2 == 1:
        p = (-expr)**Rational(1, n)
        a = nsimplify(p, constants=surds)
        res = a if _mexpand(a**n) == _mexpand(-expr) else p
        return -res
    a = nsimplify(p, constants=surds)
    if _mexpand(a) is not _mexpand(p) and _mexpand(a**n) == _mexpand(expr):
        return _mexpand(a)
    expr = _nthroot_solve(expr, n, prec)
    if expr is None:
        return p
    return expr
Exemple #6
0
 def eval(cls, arg, k=0):
     k = sympify(k)
     if not k.is_Integer or k.is_negative:
         raise ValueError(
             "Error: the second argument of DiracDelta must be \
         a non-negative integer, %s given instead." % (k, ))
     arg = sympify(arg)
     if arg.is_positive or arg.is_negative:
         return S.Zero
Exemple #7
0
def test_trick_indent_with_end_else_words():
    # words starting with "end" or "else" do not confuse the indenter
    t1 = sympify('endless')
    t2 = sympify('elsewhere')
    pw = Piecewise((t1, x < 0), (t2, x <= 1), (1, True))
    assert mcode(pw, inline=False) == ("if (x < 0)\n"
                                       "  endless\n"
                                       "elseif (x <= 1)\n"
                                       "  elsewhere\n"
                                       "else\n"
                                       "  1\n"
                                       "end")
Exemple #8
0
 def eval(cls, n, k=1):
     n = sympify(n)
     k = sympify(k)
     if n.is_prime:
         return 1 + n**k
     if n.is_Integer:
         if n <= 0:
             raise ValueError("n must be a positive integer")
         else:
             return Mul(*[(p**(k * (e + 1)) - 1) /
                          (p**k - 1) if k != 0 else e + 1
                          for p, e in factorint(n).items()])
Exemple #9
0
    def __new__(cls, f, x, index=None, radicals=True, expand=True):
        """Construct a new ``RootOf`` object for ``k``-th root of ``f``. """
        x = sympify(x)

        if index is None and x.is_Integer:
            x, index = None, x
        else:
            index = sympify(index)

        if index is not None and index.is_Integer:
            index = int(index)
        else:
            raise ValueError("expected an integer root index, got %s" % index)

        poly = PurePoly(f, x, greedy=False, expand=expand)

        if not poly.is_univariate:
            raise PolynomialError("only univariate polynomials are allowed")

        degree = poly.degree()

        if degree <= 0:
            raise PolynomialError("can't construct RootOf object for %s" % f)

        if index < -degree or index >= degree:
            raise IndexError("root index out of [%d, %d] range, got %d" %
                             (-degree, degree - 1, index))
        elif index < 0:
            index += degree

        dom = poly.get_domain()

        if not dom.is_Exact:
            poly = poly.to_exact()

        roots = cls._roots_trivial(poly, radicals)

        if roots is not None:
            return roots[index]

        coeff, poly = preprocess_roots(poly)
        dom = poly.get_domain()

        if not dom.is_ZZ:
            raise NotImplementedError("RootOf is not supported over %s" % dom)

        root = cls._indexed_root(poly, index)
        return coeff * cls._postprocess_root(root, radicals)
Exemple #10
0
def use(expr, func, level=0, args=(), kwargs={}):
    """
    Use ``func`` to transform ``expr`` at the given level.

    Examples
    ========

    >>> from diofant import use, expand
    >>> from diofant.abc import x, y

    >>> f = (x + y)**2*x + 1

    >>> use(f, expand, level=2)
    x*(x**2 + 2*x*y + y**2) + 1
    >>> expand(f)
    x**3 + 2*x**2*y + x*y**2 + 1

    """
    def _use(expr, level):
        if not level:
            return func(expr, *args, **kwargs)
        else:
            if expr.is_Atom:
                return expr
            else:
                level -= 1
                _args = []

                for arg in expr.args:
                    _args.append(_use(arg, level))

                return expr.__class__(*_args)

    return _use(sympify(expr), level)
Exemple #11
0
def reps_toposort(r):
    """Sort replacements `r` so (k1, v1) appears before (k2, v2)
    if k2 is in v1's free symbols. This orders items in the
    way that cse returns its results (hence, in order to use the
    replacements in a substitution option it would make sense
    to reverse the order).

    Examples
    ========

    >>> from diofant.simplify.cse_main import reps_toposort
    >>> from diofant.abc import x, y
    >>> from diofant import Eq
    >>> for l, r in reps_toposort([(x, y + 1), (y, 2)]):
    ...     print(Eq(l, r))
    ...
    Eq(y, 2)
    Eq(x, y + 1)

    """
    r = sympify(r)
    E = []
    for c1, (k1, v1) in enumerate(r):
        for c2, (k2, v2) in enumerate(r):
            if k1 in v2.free_symbols:
                E.append((c1, c2))
    return [r[i] for i in topological_sort((range(len(r)), E))]
Exemple #12
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 #13
0
 def nsimplify_real(x):
     orig = mpmath.mp.dps
     xv = x._to_mpmath(bprec)
     try:
         # We'll be happy with low precision if a simple fraction
         if not (tolerance or full):
             mpmath.mp.dps = 15
             rat = mpmath.findpoly(xv, 1)
             if rat is not None:
                 return Rational(-int(rat[1]), int(rat[0]))
         mpmath.mp.dps = prec
         newexpr = mpmath.identify(xv,
                                   constants=constants_dict,
                                   tol=tolerance,
                                   full=full)
         if not newexpr:
             raise ValueError
         if full:
             newexpr = newexpr[0]
         expr = sympify(newexpr)
         if x and not expr:  # don't let x become 0
             raise ValueError
         if expr.is_finite is False and xv not in [mpmath.inf, mpmath.ninf]:
             raise ValueError
         return expr
     finally:
         # even though there are returns above, this is executed
         # before leaving
         mpmath.mp.dps = orig
Exemple #14
0
def sqrtdenest(expr, max_iter=3):
    """Denests sqrts in an expression that contain other square roots
    if possible, otherwise returns the expr unchanged. This is based on the
    algorithms of [1].

    Examples
    ========

    >>> from diofant.simplify.sqrtdenest import sqrtdenest
    >>> from diofant import sqrt
    >>> sqrtdenest(sqrt(5 + 2 * sqrt(6)))
    sqrt(2) + sqrt(3)

    See Also
    ========
    diofant.solvers.solvers.unrad

    References
    ==========
    [1] http://researcher.watson.ibm.com/researcher/files/us-fagin/symb85.pdf

    [2] D. J. Jeffrey and A. D. Rich, 'Symplifying Square Roots of Square Roots
    by Denesting' (available at http://www.cybertester.com/data/denest.pdf)

    """
    expr = expand_mul(sympify(expr))
    for i in range(max_iter):
        z = _sqrtdenest0(expr)
        if expr == z:
            return expr
        expr = z
    return expr
Exemple #15
0
    def __new__(cls, p1, pt=None, slope=None, **kwargs):
        if isinstance(p1, LinearEntity):
            p1, pt = p1.args
        else:
            p1 = Point(p1)
        if pt is not None and slope is None:
            try:
                p2 = Point(pt)
            except NotImplementedError:
                raise ValueError('The 2nd argument was not a valid Point. '
                'If it was a slope, enter it with keyword "slope".')
        elif slope is not None and pt is None:
            slope = sympify(slope)
            if slope.is_finite is False:
                # when infinite slope, don't change x
                dx = 0
                dy = 1
            else:
                # go over 1 up slope
                dx = 1
                dy = slope
            # XXX avoiding simplification by adding to coords directly
            p2 = Point(p1.x + dx, p1.y + dy)
        else:
            raise ValueError('A 2nd Point or keyword "slope" must be used.')

        return LinearEntity.__new__(cls, p1, p2, **kwargs)
Exemple #16
0
    def preprocess(cls, modulus):
        modulus = sympify(modulus)

        if modulus.is_Integer and modulus > 0:
            return int(modulus)
        else:
            raise OptionError("'modulus' must a positive integer, got %s" %
                              modulus)
Exemple #17
0
def posify(eq):
    """Return eq (with generic symbols made positive) and a
    dictionary containing the mapping between the old and new
    symbols.

    Any symbol that has positive=None will be replaced with a positive dummy
    symbol having the same name. This replacement will allow more symbolic
    processing of expressions, especially those involving powers and
    logarithms.

    A dictionary that can be sent to subs to restore eq to its original
    symbols is also returned.

    >>> from diofant import posify, Symbol, log, solve
    >>> from diofant.abc import x
    >>> posify(x + Symbol('p', positive=True) + Symbol('n', negative=True))
    (n + p + _x, {_x: x})

    >>> eq = 1/x
    >>> log(eq).expand()
    log(1/x)
    >>> log(posify(eq)[0]).expand()
    -log(_x)
    >>> p, rep = posify(eq)
    >>> log(p).expand().subs(rep)
    -log(x)

    It is possible to apply the same transformations to an iterable
    of expressions:

    >>> eq = x**2 - 4
    >>> solve(eq, x)
    [-2, 2]
    >>> eq_x, reps = posify([eq, x]); eq_x
    [_x**2 - 4, _x]
    >>> solve(*eq_x)
    [2]
    """
    eq = sympify(eq)
    if iterable(eq):
        f = type(eq)
        eq = list(eq)
        syms = set()
        for e in eq:
            syms = syms.union(e.atoms(Symbol))
        reps = {}
        for s in syms:
            reps.update({v: k for k, v in posify(s)[1].items()})
        for i, e in enumerate(eq):
            eq[i] = e.subs(reps)
        return f(eq), {r: s for s, r in reps.items()}

    reps = {
        s: Dummy(s.name, positive=True)
        for s in eq.free_symbols if s.is_positive is None
    }
    eq = eq.subs(reps)
    return eq, {r: s for s, r in reps.items()}
Exemple #18
0
    def __init__(self, monom, gens=None):
        if not iterable(monom):
            rep, gens = dict_from_expr(sympify(monom), gens=gens)
            if len(rep) == 1 and list(rep.values())[0] == 1:
                monom = list(rep.keys())[0]
            else:
                raise ValueError("Expected a monomial got %s" % monom)

        self.exponents = tuple(map(int, monom))
        self.gens = gens
Exemple #19
0
    def __new__(cls, function, limits):
        fun = sympify(function)
        if not is_sequence(fun) or len(fun) != 2:
            raise ValueError("Function argument should be (x(t), y(t)) "
                "but got %s" % str(function))
        if not is_sequence(limits) or len(limits) != 3:
            raise ValueError("Limit argument should be (t, tmin, tmax) "
                "but got %s" % str(limits))

        return GeometryEntity.__new__(cls, Tuple(*fun), Tuple(*limits))
Exemple #20
0
 def eval(cls, n):
     n = sympify(n)
     if n.is_Integer:
         if n < 1:
             raise ValueError("n must be a positive integer")
         factors = factorint(n)
         t = 1
         for p, k in factors.items():
             t *= (p - 1) * p**(k - 1)
         return t
Exemple #21
0
 def _eval_Eq(self, other):
     # RootOf represents a Root, so if other is that root, it should set
     # the expression to zero *and* it should be in the interval of the
     # RootOf instance. It must also be a number that agrees with the
     # is_real value of the RootOf instance.
     if type(self) == type(other):
         return sympify(self.__eq__(other))
     if not (other.is_number and not other.has(AppliedUndef)):
         return S.false
     if not other.is_finite:
         return S.false
     z = self.expr.subs(self.expr.free_symbols.pop(), other).is_zero
     if z is False:  # all roots will make z True but we don't know
         # whether this is the right root if z is True
         return S.false
     o = other.is_extended_real, other.is_imaginary
     s = self.is_extended_real, self.is_imaginary
     if o != s and None not in o and None not in s:
         return S.false
     i = self._get_interval()
     was = i.a, i.b
     need = [True] * 2
     # make sure it would be distinct from others
     while any(need):
         i = i.refine()
         a, b = i.a, i.b
         if need[0] and a != was[0]:
             need[0] = False
         if need[1] and b != was[1]:
             need[1] = False
     re, im = other.as_real_imag()
     if not im:
         if self.is_extended_real:
             a, b = [Rational(str(i)) for i in (a, b)]
             return sympify(a < other and other < b)
         return S.false
     if self.is_extended_real:
         return S.false
     z = r1, r2, i1, i2 = [
         Rational(str(j)) for j in (i.ax, i.bx, i.ay, i.by)
     ]
     return sympify((r1 < re and re < r2) and (i1 < im and im < i2))
Exemple #22
0
    def eval(cls, n, m, theta, phi):
        n, m, th, ph = [sympify(x) for x in (n, m, theta, phi)]

        if m.is_positive:
            zz = (Ynm(n, m, th, ph) + Ynm_c(n, m, th, ph)) / sqrt(2)
            return zz
        elif m.is_zero:
            return Ynm(n, m, th, ph)
        elif m.is_negative:
            zz = (Ynm(n, m, th, ph) - Ynm_c(n, m, th, ph)) / (sqrt(2)*I)
            return zz
Exemple #23
0
    def convert(self, element, base=None):
        """Convert ``element`` to ``self.dtype``. """
        if base is not None:
            return self.convert_from(element, base)

        if self.of_type(element):
            return element

        from diofant.polys.domains import PythonIntegerRing, GMPYIntegerRing, GMPYRationalField, RealField, ComplexField

        if isinstance(element, int):
            return self.convert_from(element, PythonIntegerRing())

        if HAS_GMPY:
            integers = GMPYIntegerRing()
            if isinstance(element, integers.tp):
                return self.convert_from(element, integers)

            rationals = GMPYRationalField()
            if isinstance(element, rationals.tp):
                return self.convert_from(element, rationals)

        if isinstance(element, float):
            parent = RealField(tol=False)
            return self.convert_from(parent(element), parent)

        if isinstance(element, complex):
            parent = ComplexField(tol=False)
            return self.convert_from(parent(element), parent)

        if isinstance(element, DomainElement):
            return self.convert_from(element, element.parent())

        # TODO: implement this in from_ methods
        if self.is_Numerical and getattr(element, 'is_ground', False):
            return self.convert(element.LC())

        if isinstance(element, Basic):
            try:
                return self.from_diofant(element)
            except (TypeError, ValueError):
                pass
        else:  # TODO: remove this branch
            if not is_sequence(element):
                try:
                    element = sympify(element)

                    if isinstance(element, Basic):
                        return self.from_diofant(element)
                except (TypeError, ValueError):
                    pass

        raise CoercionFailed("can't convert %s of type %s to %s" %
                             (element, type(element), self))
Exemple #24
0
 def eval(cls, arg):
     arg = sympify(arg)
     if im(arg).is_nonzero:
         raise ValueError(
             "Function defined only for Real Values. Complex part: %s  found in %s ."
             % (repr(im(arg)), repr(arg)))
     elif arg.is_negative:
         return S.Zero
     elif arg.is_zero:
         return S.Half
     elif arg.is_positive:
         return S.One
Exemple #25
0
    def eval(cls, n, m, theta, phi):
        n, m, theta, phi = [sympify(x) for x in (n, m, theta, phi)]

        # Handle negative index m and arguments theta, phi
        if m.could_extract_minus_sign():
            m = -m
            return S.NegativeOne**m * exp(-2*I*m*phi) * Ynm(n, m, theta, phi)
        if theta.could_extract_minus_sign():
            theta = -theta
            return Ynm(n, m, theta, phi)
        if phi.could_extract_minus_sign():
            phi = -phi
            return exp(-2*I*m*phi) * Ynm(n, m, theta, phi)
Exemple #26
0
    def __new__(cls, e, z, z0, dir="+"):
        e = sympify(e)
        z = sympify(z)
        z0 = sympify(z0)

        if z0 is S.Infinity:
            dir = "-"
        elif z0 is S.NegativeInfinity:
            dir = "+"

        if isinstance(dir, str):
            dir = Symbol(dir)
        elif not isinstance(dir, Symbol):
            raise TypeError("direction must be of type str or Symbol, not %s" %
                            type(dir))
        if str(dir) not in ('+', '-', 'real'):
            raise ValueError(
                "direction must be either '+' or '-' or 'real', not %s" % dir)

        obj = Expr.__new__(cls)
        obj._args = (e, z, z0, dir)
        return obj
Exemple #27
0
    def __new__(cls, label, shape=None, **kw_args):
        if isinstance(label, str):
            label = Symbol(label)
        elif isinstance(label, (Dummy, Symbol)):
            pass
        else:
            raise TypeError("Base label should be a string or Symbol.")

        obj = Expr.__new__(cls, label, **kw_args)
        if is_sequence(shape):
            obj._shape = Tuple(*shape)
        else:
            obj._shape = sympify(shape)
        return obj
Exemple #28
0
    def __new__(cls,
                center=None,
                hradius=None,
                vradius=None,
                eccentricity=None,
                **kwargs):
        hradius = sympify(hradius)
        vradius = sympify(vradius)

        eccentricity = sympify(eccentricity)

        if center is None:
            center = Point(0, 0)
        else:
            center = Point(center)

        if len(center) != 2:
            raise ValueError(
                'The center of "{0}" must be a two dimensional point'.format(
                    cls))

        if len(list(filter(None, (hradius, vradius, eccentricity)))) != 2:
            raise ValueError(
                'Exactly two arguments of "hradius", '
                '"vradius", and "eccentricity" must not be None."')

        if eccentricity is not None:
            if hradius is None:
                hradius = vradius / sqrt(1 - eccentricity**2)
            elif vradius is None:
                vradius = hradius * sqrt(1 - eccentricity**2)

        if hradius == vradius:
            return Circle(center, hradius, **kwargs)

        return GeometryEntity.__new__(cls, center, hradius, vradius, **kwargs)
Exemple #29
0
    def __lt__(self, other):
        """
        Checks if a partition is less than the other.

        Examples
        ========

        >>> from diofant.combinatorics.partitions import Partition
        >>> a = Partition([1, 2], [3, 4, 5])
        >>> b = Partition([1], [2, 3], [4], [5])
        >>> a.rank, b.rank
        (9, 34)
        >>> a < b
        true
        """
        return self.sort_key() < sympify(other).sort_key()
Exemple #30
0
    def _eval_Eq(self, other):
        """Helper method for Equality with matrices.

        Relational automatically converts matrices to ImmutableMatrix
        instances, so this method only applies here.  Returns True if the
        matrices are definitively the same, False if they are definitively
        different, and None if undetermined (e.g. if they contain Symbols).
        Returning None triggers default handling of Equalities.

        """
        if not hasattr(other, 'shape') or self.shape != other.shape:
            return S.false
        if isinstance(other,
                      MatrixExpr) and not isinstance(other, ImmutableMatrix):
            return
        diff = self - other
        return sympify(diff.is_zero)