コード例 #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)
コード例 #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)
コード例 #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
コード例 #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
コード例 #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
コード例 #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
コード例 #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")
コード例 #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()])
コード例 #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)
コード例 #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)
コード例 #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))]
コード例 #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)
コード例 #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
コード例 #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
コード例 #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)
コード例 #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)
コード例 #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()}
コード例 #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
コード例 #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))
コード例 #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
コード例 #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))
コード例 #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
コード例 #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))
コード例 #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
コード例 #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)
コード例 #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
コード例 #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
コード例 #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)
コード例 #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()
コード例 #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)