Example #1
0
def test_roots_preprocessed():
    E, F, J, L = symbols("E,F,J,L")

    f = -21601054687500000000*E**8*J**8/L**16 + \
        508232812500000000*F*x*E**7*J**7/L**14 - \
        4269543750000000*E**6*F**2*J**6*x**2/L**12 + \
        16194716250000*E**5*F**3*J**5*x**3/L**10 - \
        27633173750*E**4*F**4*J**4*x**4/L**8 + \
        14840215*E**3*F**5*J**3*x**5/L**6 + \
        54794*E**2*F**6*J**2*x**6/(5*L**4) - \
        1153*E*J*F**7*x**7/(80*L**2) + \
        633*F**8*x**8/160000

    assert roots(f, x) == {}

    R1 = roots(f.evalf(), x, multiple=True)
    R2 = [-1304.88375606366, 97.1168816800648, 186.946430171876, 245.526792947065,
          503.441004174773, 791.549343830097, 1273.16678129348, 1850.10650616851]

    w = Wild('w')
    p = w*E*J/(F*L**2)

    assert len(R1) == len(R2)

    for r1, r2 in zip(R1, R2):
        match = r1.match(p)
        assert match is not None and abs(match[w] - r2) < 1e-10
Example #2
0
def test_roots2():
    """Just test that calculating these roots does not hang
    (final result is not checked)
    """
    a, b, c, d, x = symbols("a b c d x")
    f1 = x**2*c + (a/b) + x*c*d - a
    f2 = x**2*(a + b*(c-d)*a) + x*a*b*c/(b*d-d) + (a*d-c/d)
    assert roots(f1, x).values() == [1, 1]
    assert roots(f2, x).values() == [1, 1]
Example #3
0
def test_roots_inexact():
    R1 = sorted([ r.evalf() for r in roots(x**2 + x + 1,   x) ])
    R2 = sorted([ r         for r in roots(x**2 + x + 1.0, x) ])

    for r1, r2 in zip(R1, R2):
        assert abs(r1 - r2) < 1e-12

    f = x**4 + 3.0*sqrt(2.0)*x**3 - (78.0 + 24.0*sqrt(3.0))*x**2 + 144.0*(2*sqrt(3.0) + 9.0)

    R1 = sorted(roots(f, multiple=True))
    R2 = sorted([-12.7530479110482, -3.85012393732929, 4.89897948556636, 7.46155167569183])

    for r1, r2 in zip(R1, R2):
        assert abs(r1 - r2) < 1e-10
Example #4
0
    def _indicial(self):
        list_coeff = self.annihilator.listofpoly
        R = self.annihilator.parent.base
        x = self.x
        s = R.zero
        y = R.one

        def _pole_degree(poly):
            root_all = roots(poly.rep, filter='Z')
            if 0 in root_all.keys():
                return root_all[0]
            else:
                return 0

        degree = [j.degree() for j in list_coeff]
        degree = max(degree)
        inf = 10 * (max(1, degree) + max(1, self.annihilator.order))

        deg = lambda q: inf if q.is_zero else _pole_degree(q)
        b = deg(list_coeff[0])
        print (b)

        for j in range(1, len(list_coeff)):
            b = min(b, deg(list_coeff[j]) - j)
            print(b)

        for i, j in enumerate(list_coeff):
            listofdmp = j.all_coeffs()
            degree = len(listofdmp) - 1
            if - i - b <= 0:
                s = s + listofdmp[degree - i - b] * y
            y *= x - i
        return roots(s.rep, filter='R').keys()
Example #5
0
def test_roots_binomial():
    assert roots_binomial(Poly(5*x, x)) == [0]
    assert roots_binomial(Poly(5*x**4, x)) == [0, 0, 0, 0]
    assert roots_binomial(Poly(5*x + 2, x)) == [-Rational(2, 5)]

    A = 10**Rational(3, 4)/10

    assert roots_binomial(Poly(5*x**4 + 2, x)) == \
        [-A - A*I, -A + A*I, A - A*I, A + A*I]

    a1 = Symbol('a1', nonnegative=True)
    b1 = Symbol('b1', nonnegative=True)

    r0 = roots_quadratic(Poly(a1*x**2 + b1, x))
    r1 = roots_binomial(Poly(a1*x**2 + b1, x))

    assert powsimp(r0[0]) == powsimp(r1[0])
    assert powsimp(r0[1]) == powsimp(r1[1])
    for a, b, s, n in cartes((1, 2), (1, 2), (-1, 1), (2, 3, 4, 5)):
        if a == b and a != 1:  # a == b == 1 is sufficient
            continue
        p = Poly(a*x**n + s*b)
        ans = roots_binomial(p)
        assert ans == _nsort(ans)

    # issue 8813
    assert roots(Poly(2*x**3 - 16*y**3, x)) == {
        2*y*(-S(1)/2 - sqrt(3)*I/2): 1,
        2*y: 1,
        2*y*(-S(1)/2 + sqrt(3)*I/2): 1}
Example #6
0
def test_roots2():
    """Just test that calculating these roots does not hang
    (final result is not checked)
    """
    a, b, c, d, x = symbols("a,b,c,d,x")

    f1 = x**2*c + (a/b) + x*c*d - a
    f2 = x**2*(a + b*(c-d)*a) + x*a*b*c/(b*d-d) + (a*d-c/d)

    assert roots(f1, x).values() == [1, 1]
    assert roots(f2, x).values() == [1, 1]

    (zz, yy, xx, zy, zx, yx, k) = symbols("zz,yy,xx,zy,zx,yx,k")

    e1 = (zz-k)*(yy-k)*(xx-k) + zy*yx*zx + zx-zy-yx
    e2 = (zz-k)*yx*yx + zx*(yy-k)*zx + zy*zy*(xx-k)

    assert roots(e1 - e2, k).values() == [1, 1, 1]
def test_roots2():
    """Just test that calculating these roots does not hang
    (final result is not checked)
    """
    a, b, c, d, x = symbols("a,b,c,d,x")

    f1 = x**2 * c + (a / b) + x * c * d - a
    f2 = x**2 * (a + b *
                 (c - d) * a) + x * a * b * c / (b * d - d) + (a * d - c / d)

    assert roots(f1, x).values() == [1, 1]
    assert roots(f2, x).values() == [1, 1]

    (zz, yy, xx, zy, zx, yx, k) = symbols("zz,yy,xx,zy,zx,yx,k")

    e1 = (zz - k) * (yy - k) * (xx - k) + zy * yx * zx + zx - zy - yx
    e2 = (zz - k) * yx * yx + zx * (yy - k) * zx + zy * zy * (xx - k)

    assert roots(e1 - e2, k).values() == [1, 1, 1]
Example #8
0
    def doit(self, **hints):
        if not hints.get('roots', True):
            return self

        _roots = roots(self.poly, multiple=True)

        if len(_roots) < self.poly.degree():
            return self
        else:
            return Add(*[self.fun(r) for r in _roots])
Example #9
0
def test_roots_inexact():
    R1 = roots(x ** 2 + x + 1, x, multiple=True)
    R2 = roots(x ** 2 + x + 1.0, x, multiple=True)

    for r1, r2 in zip(R1, R2):
        assert abs(r1 - r2) < 1e-12

    f = (
        x ** 4
        + 3.0 * sqrt(2.0) * x ** 3
        - (78.0 + 24.0 * sqrt(3.0)) * x ** 2
        + 144.0 * (2 * sqrt(3.0) + 9.0)
    )

    R1 = roots(f, multiple=True)
    R2 = (-12.7530479110482, -3.85012393732929, 4.89897948556636, 7.46155167569183)

    for r1, r2 in zip(R1, R2):
        assert abs(r1 - r2) < 1e-10
Example #10
0
    def doit(self, **hints):
        if not hints.get('roots', True):
            return self

        _roots = roots(self.poly, multiple=True)

        if len(_roots) < self.poly.degree():
            return self
        else:
            return Add(*[self.fun(r) for r in _roots])
Example #11
0
def test_legendre():
    assert legendre(0, x) == 1
    assert legendre(1, x) == x
    assert legendre(2, x) == ((3 * x**2 - 1) / 2).expand()
    assert legendre(3, x) == ((5 * x**3 - 3 * x) / 2).expand()
    assert legendre(4, x) == ((35 * x**4 - 30 * x**2 + 3) / 8).expand()
    assert legendre(5, x) == ((63 * x**5 - 70 * x**3 + 15 * x) / 8).expand()
    assert legendre(6, x) == ((231 * x**6 - 315 * x**4 + 105 * x**2 - 5) /
                              16).expand()

    assert legendre(10, -1) == 1
    assert legendre(11, -1) == -1
    assert legendre(10, 1) == 1
    assert legendre(11, 1) == 1
    assert legendre(10, 0) != 0
    assert legendre(11, 0) == 0

    assert legendre(-1, x) == 1
    k = Symbol('k')
    assert legendre(5 - k, x).subs(k, 2) == ((5 * x**3 - 3 * x) / 2).expand()

    assert roots(legendre(4, x), x) == {
        sqrt(Rational(3, 7) - Rational(2, 35) * sqrt(30)): 1,
        -sqrt(Rational(3, 7) - Rational(2, 35) * sqrt(30)): 1,
        sqrt(Rational(3, 7) + Rational(2, 35) * sqrt(30)): 1,
        -sqrt(Rational(3, 7) + Rational(2, 35) * sqrt(30)): 1,
    }

    n = Symbol("n")

    X = legendre(n, x)
    assert isinstance(X, legendre)
    assert unchanged(legendre, n, x)

    assert legendre(n,
                    0) == sqrt(pi) / (gamma(S.Half - n / 2) * gamma(n / 2 + 1))
    assert legendre(n, 1) == 1
    assert legendre(n, oo) is oo
    assert legendre(-n, x) == legendre(n - 1, x)
    assert legendre(n, -x) == (-1)**n * legendre(n, x)
    assert unchanged(legendre, -n + k, x)

    assert conjugate(legendre(n, x)) == legendre(n, conjugate(x))

    assert diff(legendre(n, x), x) == \
        n*(x*legendre(n, x) - legendre(n - 1, x))/(x**2 - 1)
    assert diff(legendre(n, x), n) == Derivative(legendre(n, x), n)

    _k = Dummy('k')
    assert legendre(n, x).rewrite("polynomial").dummy_eq(
        Sum((-1)**_k * (S.Half - x / 2)**_k * (x / 2 + S.Half)**(-_k + n) *
            binomial(n, _k)**2, (_k, 0, n)))
    raises(ArgumentIndexError, lambda: legendre(n, x).fdiff(1))
    raises(ArgumentIndexError, lambda: legendre(n, x).fdiff(3))
Example #12
0
    def simplify(self, x):
        """simplify(self, x)

           Compute a simplified representation of the function using
           property number 4.

           x can be:

           - a symbol

           Examples
           ========

           >>> from sympy import DiracDelta
           >>> from sympy.abc import x, y

           >>> DiracDelta(x*y).simplify(x)
           DiracDelta(x)/Abs(y)
           >>> DiracDelta(x*y).simplify(y)
           DiracDelta(y)/Abs(x)

           >>> DiracDelta(x**2 + x - 2).simplify(x)
           DiracDelta(x - 1)/3 + DiracDelta(x + 2)/3

           See Also
           ========

           is_simple, Diracdelta

        """
        from sympy.polys.polyroots import roots

        if not self.args[0].has(x) or (len(self.args) > 1
                                       and self.args[1] != 0):
            return self
        try:
            argroots = roots(self.args[0], x)
            result = 0
            valid = True
            darg = abs(diff(self.args[0], x))
            for r, m in argroots.items():
                if r.is_real is not False and m == 1:
                    result += self.func(x - r) / darg.subs(x, r)
                else:
                    # don't handle non-real and if m != 1 then
                    # a polynomial will have a zero in the derivative (darg)
                    # at r
                    valid = False
                    break
            if valid:
                return result
        except PolynomialError:
            pass
        return self
Example #13
0
def test_roots_slow():
    """Just test that calculating these roots does not hang. """
    a, b, c, d, x = symbols("a,b,c,d,x")

    f1 = x**2*c + (a/b) + x*c*d - a
    f2 = x**2*(a + b*(c - d)*a) + x*a*b*c/(b*d - d) + (a*d - c/d)

    assert list(roots(f1, x).values()) == [1, 1]
    assert list(roots(f2, x).values()) == [1, 1]

    (zz, yy, xx, zy, zx, yx, k) = symbols("zz,yy,xx,zy,zx,yx,k")

    e1 = (zz - k)*(yy - k)*(xx - k) + zy*yx*zx + zx - zy - yx
    e2 = (zz - k)*yx*yx + zx*(yy - k)*zx + zy*zy*(xx - k)

    assert list(roots(e1 - e2, k).values()) == [1, 1, 1]

    f = x**3 + 2*x**2 + 8
    R = list(roots(f).keys())

    assert not any(i for i in [f.subs(x, ri).n(chop=True) for ri in R])
Example #14
0
    def simplify(self, x):
        """simplify(self, x)

           Compute a simplified representation of the function using
           property number 4.

           x can be:

           - a symbol

           Examples
           ========

           >>> from sympy import DiracDelta
           >>> from sympy.abc import x, y

           >>> DiracDelta(x*y).simplify(x)
           DiracDelta(x)/Abs(y)
           >>> DiracDelta(x*y).simplify(y)
           DiracDelta(y)/Abs(x)

           >>> DiracDelta(x**2 + x - 2).simplify(x)
           DiracDelta(x - 1)/3 + DiracDelta(x + 2)/3

           See Also
           ========

           is_simple, Directdelta

        """
        from sympy.polys.polyroots import roots

        if not self.args[0].has(x) or (len(self.args) > 1
                                       and self.args[1] != 0):
            return self
        try:
            argroots = roots(self.args[0], x, \
                                                     multiple=True)
            result = 0
            valid = True
            darg = diff(self.args[0], x)
            for r in argroots:
                #should I care about multiplicities of roots?
                if r.is_real and not darg.subs(x, r).is_zero:
                    result = result + DiracDelta(x - r) / abs(darg.subs(x, r))
                else:
                    valid = False
                    break
            if valid:
                return result
        except PolynomialError:
            pass
        return self
Example #15
0
def test_roots_slow():
    """Just test that calculating these roots does not hang. """
    a, b, c, d, x = symbols("a,b,c,d,x")

    f1 = x**2*c + (a/b) + x*c*d - a
    f2 = x**2*(a + b*(c - d)*a) + x*a*b*c/(b*d - d) + (a*d - c/d)

    assert list(roots(f1, x).values()) == [1, 1]
    assert list(roots(f2, x).values()) == [1, 1]

    (zz, yy, xx, zy, zx, yx, k) = symbols("zz,yy,xx,zy,zx,yx,k")

    e1 = (zz - k)*(yy - k)*(xx - k) + zy*yx*zx + zx - zy - yx
    e2 = (zz - k)*yx*yx + zx*(yy - k)*zx + zy*zy*(xx - k)

    assert list(roots(e1 - e2, k).values()) == [1, 1, 1]

    f = x**3 + 2*x**2 + 8
    R = list(roots(f).keys())

    assert not any(i for i in [f.subs(x, ri).n(chop=True) for ri in R])
Example #16
0
    def simplify(self, x):
        """simplify(self, x)

           Compute a simplified representation of the function using
           property number 4.

           x can be:

           - a symbol

           Examples
           ========

           >>> from sympy import DiracDelta
           >>> from sympy.abc import x, y

           >>> DiracDelta(x*y).simplify(x)
           DiracDelta(x)/Abs(y)
           >>> DiracDelta(x*y).simplify(y)
           DiracDelta(y)/Abs(x)

           >>> DiracDelta(x**2 + x - 2).simplify(x)
           DiracDelta(x - 1)/3 + DiracDelta(x + 2)/3

           See Also
           ========

           is_simple, Directdelta

        """
        from sympy.polys.polyroots import roots

        if not self.args[0].has(x) or (len(self.args) > 1 and self.args[1] != 0 ):
            return self
        try:
            argroots = roots(self.args[0], x)
            result = 0
            valid = True
            darg = abs(diff(self.args[0], x))
            for r, m in argroots.items():
                if r.is_real is not False and m == 1:
                    result += self.func(x - r)/darg.subs(x, r)
                else:
                    # don't handle non-real and if m != 1 then
                    # a polynomial will have a zero in the derivative (darg)
                    # at r
                    valid = False
                    break
            if valid:
                return result
        except PolynomialError:
            pass
        return self
Example #17
0
def test_issue_14522():
    eq = Poly(
        x ** 4
        + x ** 3 * (16 + 32 * I)
        + x ** 2 * (-285 + 386 * I)
        + x * (-2824 - 448 * I)
        - 2058
        - 6053 * I,
        x,
    )
    roots_eq = roots(eq)
    assert all(eq(r) == 0 for r in roots_eq)
Example #18
0
    def simplify(self, x):
        """simplify(self, x)

           Compute a simplified representation of the function using
           property number 4.

           x can be:

           - a symbol

           Examples
           ========

           >>> from sympy import DiracDelta
           >>> from sympy.abc import x, y

           >>> DiracDelta(x*y).simplify(x)
           DiracDelta(x)/Abs(y)
           >>> DiracDelta(x*y).simplify(y)
           DiracDelta(y)/Abs(x)

           >>> DiracDelta(x**2 + x - 2).simplify(x)
           DiracDelta(x - 1)/3 + DiracDelta(x + 2)/3

           See Also
           ========

           is_simple, Directdelta

        """
        from sympy.polys.polyroots import roots

        if not self.args[0].has(x) or (len(self.args)>1 and self.args[1] != 0 ):
            return self
        try:
            argroots = roots(self.args[0], x, \
                                                     multiple=True)
            result = 0
            valid = True
            darg = diff(self.args[0], x)
            for r in argroots:
                #should I care about multiplicities of roots?
                if r.is_real and not darg.subs(x,r).is_zero:
                    result = result + DiracDelta(x - r)/abs(darg.subs(x,r))
                else:
                    valid = False
                    break
            if valid:
                return result
        except PolynomialError:
            pass
        return self
Example #19
0
def test_roots_slow():
    """Just test that calculating these roots does not hang. """
    a, b, c, d, x = symbols("a,b,c,d,x")

    f1 = x**2*c + (a/b) + x*c*d - a
    f2 = x**2*(a + b*(c-d)*a) + x*a*b*c/(b*d-d) + (a*d-c/d)

    assert roots(f1, x).values() == [1, 1]
    assert roots(f2, x).values() == [1, 1]

    (zz, yy, xx, zy, zx, yx, k) = symbols("zz,yy,xx,zy,zx,yx,k")

    e1 = (zz-k)*(yy-k)*(xx-k) + zy*yx*zx + zx-zy-yx
    e2 = (zz-k)*yx*yx + zx*(yy-k)*zx + zy*zy*(xx-k)

    assert roots(e1 - e2, k).values() == [1, 1, 1]

    f = x**3 + 2*x**2 + 8
    R = roots(f).keys()

    assert f.subs(x, R[0]).simplify() == 0
    assert f.subs(x, R[1]).simplify() == 0
    assert f.subs(x, R[2]).simplify() == 0
Example #20
0
def test_roots_preprocessed():
    E, F, J, L = symbols("E,F,J,L")

    f = (
        -21601054687500000000 * E ** 8 * J ** 8 / L ** 16
        + 508232812500000000 * F * x * E ** 7 * J ** 7 / L ** 14
        - 4269543750000000 * E ** 6 * F ** 2 * J ** 6 * x ** 2 / L ** 12
        + 16194716250000 * E ** 5 * F ** 3 * J ** 5 * x ** 3 / L ** 10
        - 27633173750 * E ** 4 * F ** 4 * J ** 4 * x ** 4 / L ** 8
        + 14840215 * E ** 3 * F ** 5 * J ** 3 * x ** 5 / L ** 6
        + 54794 * E ** 2 * F ** 6 * J ** 2 * x ** 6 / (5 * L ** 4)
        - 1153 * E * J * F ** 7 * x ** 7 / (80 * L ** 2)
        + 633 * F ** 8 * x ** 8 / 160000
    )

    assert roots(f, x) == {}

    R1 = roots(f.evalf(), x, multiple=True)
    R2 = [
        -1304.88375606366,
        97.1168816800648,
        186.946430171876,
        245.526792947065,
        503.441004174773,
        791.549343830097,
        1273.16678129348,
        1850.10650616851,
    ]

    w = Wild("w")
    p = w * E * J / (F * L ** 2)

    assert len(R1) == len(R2)

    for r1, r2 in zip(R1, R2):
        match = r1.match(p)
        assert match is not None and abs(match[w] - r2) < 1e-10
Example #21
0
def test_roots_slow():
    """Just test that calculating these roots does not hang. """
    a, b, c, d, x = symbols("a,b,c,d,x")

    f1 = x**2 * c + (a / b) + x * c * d - a
    f2 = x**2 * (a + b *
                 (c - d) * a) + x * a * b * c / (b * d - d) + (a * d - c / d)

    assert roots(f1, x).values() == [1, 1]
    assert roots(f2, x).values() == [1, 1]

    (zz, yy, xx, zy, zx, yx, k) = symbols("zz,yy,xx,zy,zx,yx,k")

    e1 = (zz - k) * (yy - k) * (xx - k) + zy * yx * zx + zx - zy - yx
    e2 = (zz - k) * yx * yx + zx * (yy - k) * zx + zy * zy * (xx - k)

    assert roots(e1 - e2, k).values() == [1, 1, 1]

    f = x**3 + 2 * x**2 + 8
    R = roots(f).keys()

    assert f.subs(x, R[0]).simplify() == 0
    assert f.subs(x, R[1]).simplify() == 0
    assert f.subs(x, R[2]).simplify() == 0
Example #22
0
def test_roots_cubic():
    assert roots_cubic(Poly(2*x**3, x)) == [0, 0, 0]
    assert roots_cubic(Poly(x**3 - 3*x**2 + 3*x - 1, x)) == [1, 1, 1]

    assert roots_cubic(Poly(x**3 + 1, x)) == \
        [-1, S.Half - I*sqrt(3)/2, S.Half + I*sqrt(3)/2]
    assert roots_cubic(Poly(2*x**3 - 3*x**2 - 3*x - 1, x))[0] == \
         S.Half + 3**Rational(1, 3)/2 + 3**Rational(2, 3)/2
    eq = -x**3 + 2*x**2 + 3*x - 2
    assert roots(eq, trig=True, multiple=True) == \
           roots_cubic(Poly(eq, x), trig=True) == [
        Rational(2, 3) + 2*sqrt(13)*cos(acos(8*sqrt(13)/169)/3)/3,
        -2*sqrt(13)*sin(-acos(8*sqrt(13)/169)/3 + pi/6)/3 + Rational(2, 3),
        -2*sqrt(13)*cos(-acos(8*sqrt(13)/169)/3 + pi/3)/3 + Rational(2, 3),
        ]
Example #23
0
def test_roots_cubic():
    assert roots_cubic(Poly(2*x**3, x)) == [0, 0, 0]
    assert roots_cubic(Poly(x**3 - 3*x**2 + 3*x - 1, x)) == [1, 1, 1]

    assert roots_cubic(Poly(x**3 + 1, x)) == \
        [-1, S.Half - I*sqrt(3)/2, S.Half + I*sqrt(3)/2]
    assert roots_cubic(Poly(2*x**3 - 3*x**2 - 3*x - 1, x))[0] == \
         S.Half + 3**Rational(1, 3)/2 + 3**Rational(2, 3)/2
    eq = -x**3 + 2*x**2 + 3*x - 2
    assert roots(eq, trig=True, multiple=True) == \
           roots_cubic(Poly(eq, x), trig=True) == [
        S(2)/3 + 2*sqrt(13)*cos(acos(8*sqrt(13)/169)/3)/3,
        -2*sqrt(13)*sin(-acos(8*sqrt(13)/169)/3 + pi/6)/3 + S(2)/3,
        -2*sqrt(13)*cos(-acos(8*sqrt(13)/169)/3 + pi/3)/3 + S(2)/3,
        ]
Example #24
0
    def evalf(self, points, method='RK4'):
        """
        Finds numerical value of a holonomic function using numerical methods.
        (RK4 by default). A set of points (real or complex) must be provided
        which will be the path for the numerical integration.

        The path should be given as a list [x1, x2, ... xn]. The numerical
        values will be computed at each point in this order x1 --> x2 --> x3
        ... --> xn.

        Returns values of the function at x1, x2, ... xn in a list.

        Examples
        =======

        >>> from sympy.holonomic.holonomic import HolonomicFunction, DifferentialOperators
        >>> from sympy.polys.domains import ZZ, QQ
        >>> from sympy import symbols
        >>> x = symbols('x')
        >>> R, Dx = DifferentialOperators(QQ.old_poly_ring(x),'Dx')
        >>> # a straight line on the real axis from (0 to 1)
        >>> r = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]

        # using Runge-Kutta 4th order on e^x from 0.1 to 1.
        # exact solution at 1 is 2.71828182845905
        >>> HolonomicFunction(Dx - 1, x, 0, [1]).evalf(r)
        [1.10517083333333, 1.22140257085069, 1.34985849706254, 1.49182424008069,
        1.64872063859684, 1.82211796209193, 2.01375162659678, 2.22553956329232,
        2.45960141378007, 2.71827974413517]

        # using Euler's method for the same
        >>> HolonomicFunction(Dx - 1, x, 0, [1]).evalf(r, method='Euler')
        [1.1, 1.21, 1.331, 1.4641, 1.61051, 1.771561, 1.9487171, 2.14358881,
        2.357947691, 2.5937424601]

        One can also observe that the value obtained using Runge-Kutta 4th order
        is much more accurate than Euler's method.
        """

        from sympy.holonomic.numerical import _evalf
        for i in roots(self.annihilator.listofpoly[-1].rep):
            if i == self.x0 or i in points:
                raise TypeError("Provided path contains a singularity")
        return _evalf(self, points, method=method)
Example #25
0
def test_roots_cubic():
    assert roots_cubic(Poly(2 * x**3, x)) == [0, 0, 0]
    assert roots_cubic(Poly(x**3 - 3 * x**2 + 3 * x - 1, x)) == [1, 1, 1]

    # valid for arbitrary y (issue 21263)
    r = root(y, 3)
    assert roots_cubic(Poly(x**3 - y, x)) == [
        r, r * (-S.Half + sqrt(3) * I / 2), r * (-S.Half - sqrt(3) * I / 2)
    ]
    # simpler form when y is negative
    assert roots_cubic(Poly(x**3 - -1, x)) == \
        [-1, S.Half - I*sqrt(3)/2, S.Half + I*sqrt(3)/2]
    assert roots_cubic(Poly(2*x**3 - 3*x**2 - 3*x - 1, x))[0] == \
         S.Half + 3**Rational(1, 3)/2 + 3**Rational(2, 3)/2
    eq = -x**3 + 2 * x**2 + 3 * x - 2
    assert roots(eq, trig=True, multiple=True) == \
           roots_cubic(Poly(eq, x), trig=True) == [
        Rational(2, 3) + 2*sqrt(13)*cos(acos(8*sqrt(13)/169)/3)/3,
        -2*sqrt(13)*sin(-acos(8*sqrt(13)/169)/3 + pi/6)/3 + Rational(2, 3),
        -2*sqrt(13)*cos(-acos(8*sqrt(13)/169)/3 + pi/3)/3 + Rational(2, 3),
        ]
Example #26
0
def test_roots_mixed():
    f = -1936 - 5056 * x - 7592 * x ** 2 + 2704 * x ** 3 - 49 * x ** 4

    _re, _im = intervals(f, all=True)
    _nroots = nroots(f)
    _sroots = roots(f, multiple=True)

    _re = [Interval(a, b) for (a, b), _ in _re]
    _im = [Interval(re(a), re(b)) * Interval(im(a), im(b)) for (a, b), _ in _im]

    _intervals = _re + _im
    _sroots = [r.evalf() for r in _sroots]

    _nroots = sorted(_nroots, key=lambda x: x.sort_key())
    _sroots = sorted(_sroots, key=lambda x: x.sort_key())

    for _roots in (_nroots, _sroots):
        for i, r in zip(_intervals, _roots):
            if r.is_real:
                assert r in i
            else:
                assert (re(r), im(r)) in i
Example #27
0
def test_roots_mixed():
    f = -1936 - 5056*x - 7592*x**2 + 2704*x**3 - 49*x**4

    _re, _im = intervals(f, all=True)
    _nroots = nroots(f)
    _sroots = roots(f, multiple=True)

    _re = [ Interval(a, b) for (a, b), _ in _re ]
    _im = [ Interval(re(a), re(b))*Interval(im(a), im(b)) for (a, b), _ in _im ]

    _intervals = _re + _im
    _sroots = [ r.evalf() for r in _sroots ]

    _nroots = sorted(_nroots, key=lambda x: x.sort_key())
    _sroots = sorted(_sroots, key=lambda x: x.sort_key())

    for _roots in (_nroots, _sroots):
        for i, r in zip(_intervals, _roots):
            if r.is_real:
                assert r in i
            else:
                assert (re(r), im(r)) in i
Example #28
0
    def _indicial(self):
        """Computes the roots of Indicial equation.
        """

        list_coeff = self.annihilator.listofpoly
        R = self.annihilator.parent.base
        x = self.x
        s = R.zero
        y = R.one

        def _pole_degree(poly):
            root_all = roots(poly.rep, filter='Z')
            if 0 in root_all.keys():
                return root_all[0]
            else:
                return 0

        degree = [j.degree() for j in list_coeff]
        degree = max(degree)
        inf = 10 * (max(1, degree) + max(1, self.annihilator.order))

        deg = lambda q: inf if q.is_zero else _pole_degree(q)
        b = deg(list_coeff[0])
        print (b)

        for j in range(1, len(list_coeff)):
            b = min(b, deg(list_coeff[j]) - j)
            print(b)

        for i, j in enumerate(list_coeff):
            listofdmp = j.all_coeffs()
            degree = len(listofdmp) - 1
            if - i - b <= 0:
                s = s + listofdmp[degree - i - b] * y
            y *= x - i
        return roots(s.rep, filter='R').keys()
Example #29
0
def test_roots_binomial():
    assert roots_binomial(Poly(5 * x, x)) == [0]
    assert roots_binomial(Poly(5 * x ** 4, x)) == [0, 0, 0, 0]
    assert roots_binomial(Poly(5 * x + 2, x)) == [Rational(-2, 5)]

    A = 10 ** Rational(3, 4) / 10

    assert roots_binomial(Poly(5 * x ** 4 + 2, x)) == [
        -A - A * I,
        -A + A * I,
        A - A * I,
        A + A * I,
    ]
    _check(roots_binomial(Poly(x ** 8 - 2)))

    a1 = Symbol("a1", nonnegative=True)
    b1 = Symbol("b1", nonnegative=True)

    r0 = roots_quadratic(Poly(a1 * x ** 2 + b1, x))
    r1 = roots_binomial(Poly(a1 * x ** 2 + b1, x))

    assert powsimp(r0[0]) == powsimp(r1[0])
    assert powsimp(r0[1]) == powsimp(r1[1])
    for a, b, s, n in cartes((1, 2), (1, 2), (-1, 1), (2, 3, 4, 5)):
        if a == b and a != 1:  # a == b == 1 is sufficient
            continue
        p = Poly(a * x ** n + s * b)
        ans = roots_binomial(p)
        assert ans == _nsort(ans)

    # issue 8813
    assert roots(Poly(2 * x ** 3 - 16 * y ** 3, x)) == {
        2 * y * (Rational(-1, 2) - sqrt(3) * I / 2): 1,
        2 * y: 1,
        2 * y * (Rational(-1, 2) + sqrt(3) * I / 2): 1,
    }
Example #30
0
def test_issue_13340():
    eq = Poly(y**3 + exp(x)*y + x, y, domain='EX')
    roots_d = roots(eq)
    assert len(roots_d) == 3
Example #31
0
def _monotonic_sign(self):
    """Return the value closest to 0 that ``self`` may have if all symbols
    are signed and the result is uniformly the same sign for all values of symbols.
    If a symbol is only signed but not known to be an
    integer or the result is 0 then a symbol representative of the sign of self
    will be returned. Otherwise, None is returned if a) the sign could be positive
    or negative or b) self is not in one of the following forms:

    - L(x, y, ...) + A: a function linear in all symbols x, y, ... with an
      additive constant; if A is zero then the function can be a monomial whose
      sign is monotonic over the range of the variables, e.g. (x + 1)**3 if x is
      nonnegative.
    - A/L(x, y, ...) + B: the inverse of a function linear in all symbols x, y, ...
      that does not have a sign change from positive to negative for any set
      of values for the variables.
    - M(x, y, ...) + A: a monomial M whose factors are all signed and a constant, A.
    - A/M(x, y, ...) + B: the inverse of a monomial and constants A and B.
    - P(x): a univariate polynomial

    Examples
    ========

    >>> from sympy.core.exprtools import _monotonic_sign as F
    >>> from sympy import Dummy, S
    >>> nn = Dummy(integer=True, nonnegative=True)
    >>> p = Dummy(integer=True, positive=True)
    >>> p2 = Dummy(integer=True, positive=True)
    >>> F(nn + 1)
    1
    >>> F(p - 1)
    _nneg
    >>> F(nn*p + 1)
    1
    >>> F(p2*p + 1)
    2
    >>> F(nn - 1)  # could be negative, zero or positive
    """
    if not self.is_real:
        return

    if (-self).is_Symbol:
        rv = _monotonic_sign(-self)
        return rv if rv is None else -rv

    if self.is_Symbol:
        s = self
        if s.is_prime:
            if s.is_odd:
                return S(3)
            else:
                return S(2)
        elif s.is_positive:
            if s.is_even:
                return S(2)
            elif s.is_integer:
                return S.One
            else:
                return _eps
        elif s.is_negative:
            if s.is_even:
                return S(-2)
            elif s.is_integer:
                return S.NegativeOne
            else:
                return -_eps
        if s.is_zero or s.is_nonpositive or s.is_nonnegative:
            return S.Zero
        return None

    # univariate polynomial
    free = self.free_symbols
    if len(free) == 1:
        if self.is_polynomial():
            from sympy.polys.polytools import real_roots
            from sympy.polys.polyroots import roots
            from sympy.polys.polyerrors import PolynomialError
            x = free.pop()
            x0 = _monotonic_sign(x)
            if x0 == _eps or x0 == -_eps:
                x0 = S.Zero
            if x0 is not None:
                d = self.diff(x)
                if d.is_number:
                    roots = []
                else:
                    try:
                        roots = real_roots(d)
                    except (PolynomialError, NotImplementedError):
                        roots = [r for r in roots(d, x) if r.is_real]
                y = self.subs(x, x0)
                if x.is_nonnegative and all(r <= x0 for r in roots):
                    if y.is_nonnegative and d.is_positive:
                        if y:
                            return y if y.is_positive else Dummy('pos', positive=True)
                        else:
                            return Dummy('nneg', nonnegative=True)
                    if y.is_nonpositive and d.is_negative:
                        if y:
                            return y if y.is_negative else Dummy('neg', negative=True)
                        else:
                            return Dummy('npos', nonpositive=True)
                elif x.is_nonpositive and all(r >= x0 for r in roots):
                    if y.is_nonnegative and d.is_negative:
                        if y:
                            return Dummy('pos', positive=True)
                        else:
                            return Dummy('nneg', nonnegative=True)
                    if y.is_nonpositive and d.is_positive:
                        if y:
                            return Dummy('neg', negative=True)
                        else:
                            return Dummy('npos', nonpositive=True)
        else:
            n, d = self.as_numer_denom()
            den = None
            if n.is_number:
                den = _monotonic_sign(d)
            elif not d.is_number:
                if _monotonic_sign(n) is not None:
                    den = _monotonic_sign(d)
            if den is not None and (den.is_positive or den.is_negative):
                v = n*den
                if v.is_positive:
                    return Dummy('pos', positive=True)
                elif v.is_nonnegative:
                    return Dummy('nneg', nonnegative=True)
                elif v.is_negative:
                    return Dummy('neg', negative=True)
                elif v.is_nonpositive:
                    return Dummy('npos', nonpositive=True)
        return None

    # multivariate
    c, a = self.as_coeff_Add()
    v = None
    if not a.is_polynomial():
        # F/A or A/F where A is a number and F is a signed, rational monomial
        n, d = a.as_numer_denom()
        if not (n.is_number or d.is_number):
            return
        if (
                a.is_Mul or a.is_Pow) and \
                a.is_rational and \
                all(p.exp.is_Integer for p in a.atoms(Pow) if p.is_Pow) and \
                (a.is_positive or a.is_negative):
            v = S(1)
            for ai in Mul.make_args(a):
                if ai.is_number:
                    v *= ai
                    continue
                reps = {}
                for x in ai.free_symbols:
                    reps[x] = _monotonic_sign(x)
                    if reps[x] is None:
                        return
                v *= ai.subs(reps)
    elif c:
        # signed linear expression
        if not any(p for p in a.atoms(Pow) if not p.is_number) and (a.is_nonpositive or a.is_nonnegative):
            free = list(a.free_symbols)
            p = {}
            for i in free:
                v = _monotonic_sign(i)
                if v is None:
                    return
                p[i] = v or (_eps if i.is_nonnegative else -_eps)
            v = a.xreplace(p)
    if v is not None:
        rv = v + c
        if v.is_nonnegative and rv.is_positive:
            return rv.subs(_eps, 0)
        if v.is_nonpositive and rv.is_negative:
            return rv.subs(_eps, 0)
Example #32
0
def test_roots():
    assert roots(1, x) == {}
    assert roots(x, x) == {S.Zero: 1}
    assert roots(x**9, x) == {S.Zero: 9}
    assert roots(((x-2)*(x+3)*(x-4)).expand(), x) == {-S(3): 1, S(2): 1, S(4): 1}

    assert roots(2*x+1, x) == {-S.Half: 1}
    assert roots((2*x+1)**2, x) == {-S.Half: 2}
    assert roots((2*x+1)**5, x) == {-S.Half: 5}
    assert roots((2*x+1)**10, x) == {-S.Half: 10}

    assert roots(x**4 - 1, x) == {I: 1, S.One: 1, -S.One: 1, -I: 1}
    assert roots((x**4 - 1)**2, x) == {I: 2, S.One: 2, -S.One: 2, -I: 2}

    assert roots(((2*x-3)**2).expand(), x) == { Rational(3,2): 2}
    assert roots(((2*x+3)**2).expand(), x) == {-Rational(3,2): 2}

    assert roots(((2*x-3)**3).expand(), x) == { Rational(3,2): 3}
    assert roots(((2*x+3)**3).expand(), x) == {-Rational(3,2): 3}

    assert roots(((2*x-3)**5).expand(), x) == { Rational(3,2): 5}
    assert roots(((2*x+3)**5).expand(), x) == {-Rational(3,2): 5}

    assert roots(((a*x-b)**5).expand(), x) == { b/a: 5}
    assert roots(((a*x+b)**5).expand(), x) == {-b/a: 5}

    assert roots(x**4-2*x**2+1, x) == {S.One: 2, -S.One: 2}

    assert roots(x**6-4*x**4+4*x**3-x**2, x) == \
        {S.One: 2, -1 - sqrt(2): 1, S.Zero: 2, -1 + sqrt(2): 1}

    assert roots(x**8-1, x) == {
         2**S.Half/2 + I*2**S.Half/2: 1,
         2**S.Half/2 - I*2**S.Half/2: 1,
        -2**S.Half/2 + I*2**S.Half/2: 1,
        -2**S.Half/2 - I*2**S.Half/2: 1,
        S.One: 1, -S.One: 1, I: 1, -I: 1
    }

    f = -2016*x**2 - 5616*x**3 - 2056*x**4 + 3324*x**5 + 2176*x**6 - 224*x**7 - 384*x**8 - 64*x**9

    assert roots(f) == {S(0): 2, -S(2): 2, S(2): 1, -S(7)/2: 1, -S(3)/2: 1, -S(1)/2: 1, S(3)/2: 1}

    assert roots((a+b+c)*x - (a+b+c+d), x) == {(a+b+c+d)/(a+b+c): 1}

    assert roots(x**3+x**2-x+1, x, cubics=False) == {}
    assert roots(((x-2)*(x+3)*(x-4)).expand(), x, cubics=False) == {-S(3): 1, S(2): 1, S(4): 1}
    assert roots(((x-2)*(x+3)*(x-4)*(x-5)).expand(), x, cubics=False) == \
            {-S(3): 1, S(2): 1, S(4): 1, S(5): 1}
    assert roots(x**3 + 2*x**2 + 4*x + 8, x) == {-S(2): 1, -2*I: 1, 2*I: 1}
    assert roots(x**3 + 2*x**2 + 4*x + 8, x, cubics=True) == \
                {-2*I: 1, 2*I: 1, -S(2): 1}
    assert roots((x**2 - x)*(x**3 + 2*x**2 + 4*x + 8), x ) == \
                {S(1): 1, S(0): 1, -S(2): 1, -2*I: 1, 2*I: 1}

    r1_2, r1_3, r1_9, r4_9, r19_27 = [ Rational(*r) \
        for r in ((1,2), (1,3), (1,9), (4,9), (19,27)) ]

    U = -r1_2 - r1_2*I*3**r1_2
    V = -r1_2 + r1_2*I*3**r1_2
    W = (r19_27 + r1_9*33**r1_2)**r1_3

    assert roots(x**3+x**2-x+1, x, cubics=True) == {
        -r1_3 - U*W - r4_9*(U*W)**(-1): 1,
        -r1_3 - V*W - r4_9*(V*W)**(-1): 1,
        -r1_3 -   W - r4_9*(  W)**(-1): 1,
    }

    f = (x**2+2*x+3).subs(x, 2*x**2 + 3*x).subs(x, 5*x-4)

    r1_2, r13_20, r1_100 = [ Rational(*r) \
        for r in ((1,2), (13,20), (1,100)) ]

    assert roots(f, x) == {
        r13_20 + r1_100*(25 - 200*I*2**r1_2)**r1_2: 1,
        r13_20 - r1_100*(25 - 200*I*2**r1_2)**r1_2: 1,
        r13_20 + r1_100*(25 + 200*I*2**r1_2)**r1_2: 1,
        r13_20 - r1_100*(25 + 200*I*2**r1_2)**r1_2: 1,
    }

    f = x**4 + x**3 + x**2 + x + 1

    r1_4, r1_8, r5_8 = [ Rational(*r) for r in ((1,4), (1,8), (5,8)) ]

    assert roots(f, x) == {
        -r1_4 + r1_4*5**r1_2 + I*(r5_8 + r1_8*5**r1_2)**r1_2: 1,
        -r1_4 + r1_4*5**r1_2 - I*(r5_8 + r1_8*5**r1_2)**r1_2: 1,
        -r1_4 - r1_4*5**r1_2 + I*(r5_8 - r1_8*5**r1_2)**r1_2: 1,
        -r1_4 - r1_4*5**r1_2 - I*(r5_8 - r1_8*5**r1_2)**r1_2: 1,
    }

    f = z**3 + (-2 - y)*z**2 + (1 + 2*y - 2*x**2)*z - y + 2*x**2

    assert roots(f, z) == {
        S.One: 1,
        S.Half + S.Half*y + S.Half*(1 - 2*y + y**2 + 8*x**2)**S.Half: 1,
        S.Half + S.Half*y - S.Half*(1 - 2*y + y**2 + 8*x**2)**S.Half: 1,
    }

    assert roots(a*b*c*x**3 + 2*x**2 + 4*x + 8, x, cubics=False) == {}
    assert roots(a*b*c*x**3 + 2*x**2 + 4*x + 8, x, cubics=True) != {}

    assert roots(x**4-1, x, filter='Z') == {S.One: 1, -S.One: 1}
    assert roots(x**4-1, x, filter='I') == {I: 1, -I: 1}

    assert roots((x-1)*(x+1), x) == {S.One: 1, -S.One: 1}
    assert roots((x-1)*(x+1), x, predicate=lambda r: r.is_positive) == {S.One: 1}

    assert roots(x**4-1, x, filter='Z', multiple=True) == [-S.One, S.One]
    assert roots(x**4-1, x, filter='I', multiple=True) == [-I, I]

    assert roots(x**3, x, multiple=True) == [S.Zero, S.Zero, S.Zero]
    assert roots(1234, x, multiple=True) == []

    f = x**6 - x**5 + x**4 - x**3 + x**2 - x + 1

    assert roots(f) == {
        -I*sin(pi/7)   + cos(pi/7):   1,
        -I*sin(2*pi/7) - cos(2*pi/7): 1,
        -I*sin(3*pi/7) + cos(3*pi/7): 1,
         I*sin(pi/7)   + cos(pi/7):   1,
         I*sin(2*pi/7) - cos(2*pi/7): 1,
         I*sin(3*pi/7) + cos(3*pi/7): 1,
    }

    g = ((x**2 + 1)*f**2).expand()

    assert roots(g) == {
        -I*sin(pi/7)   + cos(pi/7):   2,
        -I*sin(2*pi/7) - cos(2*pi/7): 2,
        -I*sin(3*pi/7) + cos(3*pi/7): 2,
         I*sin(pi/7)   + cos(pi/7):   2,
         I*sin(2*pi/7) - cos(2*pi/7): 2,
         I*sin(3*pi/7) + cos(3*pi/7): 2,
        -I: 1, I: 1,
    }
Example #33
0
def test_roots_composite():
    assert len(roots(Poly(y**3 + y**2*sqrt(x) + y + x, y, composite=True))) == 3
Example #34
0
def _lambert(eq, x, domain=S.Complexes):
    """
    Given an expression assumed to be in the form
        ``F(X, a..f) = a*log(b*X + c) + d*X + f = 0``
    where X = g(x) and x = g^-1(X), return the Lambert solution,
        ``x = g^-1(-c/b + (a/d)*W(d/(a*b)*exp(c*d/a/b)*exp(-f/a)))``.
    """
    eq = _mexpand(expand_log(eq))
    mainlog = _mostfunc(eq, log, x)
    if not mainlog:
        return []  # violated assumptions
    other = eq.subs(mainlog, 0)
    if isinstance(-other, log):
        eq = (eq - other).subs(mainlog, mainlog.args[0])
        mainlog = mainlog.args[0]
        if not isinstance(mainlog, log):
            return []  # violated assumptions
        other = -(-other).args[0]
        eq += other
    if not x in other.free_symbols:
        return [] # violated assumptions
    d, f, X2 = _linab(other, x)
    logterm = collect(eq - other, mainlog)
    a = logterm.as_coefficient(mainlog)
    if a is None or x in a.free_symbols:
        return []  # violated assumptions
    logarg = mainlog.args[0]
    b, c, X1 = _linab(logarg, x)
    if X1 != X2:
        return []  # violated assumptions

    # invert the generator X1 so we have x(u)
    u = Dummy('rhs')
    xusolns = solve(X1 - u, x)

    # There are infinitely many branches for LambertW
    # but only branches for k = -1 and 0 might be real. The k = 0
    # branch is real and the k = -1 branch is real if the LambertW argumen
    # in in range [-1/e, 0]. Since `solve` does not return infinite
    # solutions we will only include the -1 branch if it tests as real.
    # Otherwise, inclusion of any LambertW in the solution indicates to
    #  the user that there are imaginary solutions corresponding to
    # different k values.
    lambert_real_branches = [-1, 0]
    sol = []

    # solution of the given Lambert equation is like
    # sol = -c/b + (a/d)*LambertW(arg, k),
    # where arg = d/(a*b)*exp((c*d-b*f)/a/b) and k in lambert_real_branches.
    # Instead of considering the single arg, `d/(a*b)*exp((c*d-b*f)/a/b)`,
    # the individual `p` roots obtained when writing `exp((c*d-b*f)/a/b)`
    # as `exp(A/p) = exp(A)**(1/p)`, where `p` is an Integer, are used.

    # calculating args for LambertW
    num, den = ((c*d-b*f)/a/b).as_numer_denom()
    p, den = den.as_coeff_Mul()
    e = exp(num/den)
    t = Dummy('t')

    if p == 1:
        t = e
        args = [d/(a*b)*t]
    elif domain.is_subset(S.Reals):
        # print(l090)
        ind_ls = [d/(a*b)*t for t in roots(t**p - e, t).keys()]
        args = []
        j = -1
        for i in ind_ls:
            j += 1
            if not isinstance(i,int):
                if not i.has(I):
                    args.append(ind_ls[j])
            elif isinstance(i,int):
                args.append(ind_ls[j])
    else:
        args = [d/(a*b)*t for t in roots(t**p - e, t).keys()]
    if len(args) == 0:
        return S.EmptySet
    # calculating solutions from args
    for arg in args:
        for k in lambert_real_branches:
            w = LambertW(arg, k)
            if k and not w.is_real:
                continue
            rhs = -c/b + (a/d)*w

            for xu in xusolns:
                sol.append(xu.subs(u, rhs))
    return sol
Example #35
0
    def to_sequence(self):
        """
        Finds the recurrence relation in power series expansion
        of the function.

        Examples
        ========

        >>> from sympy.holonomic.holonomic import HolonomicFunction, DifferentialOperators
        >>> from sympy.polys.domains import ZZ, QQ
        >>> from sympy import symbols
        >>> x = symbols('x')
        >>> R, Dx = DifferentialOperators(QQ.old_poly_ring(x),'Dx')

        >>> HolonomicFunction(Dx - 1, x, 0, [1]).to_sequence()
        HolonomicSequence((-1) + (n + 1)Sn, n), u(0) = 1

        See Also
        ========

        HolonomicFunction.series

        References
        ==========

        hal.inria.fr/inria-00070025/document
        """

        dict1 = {}
        n = symbols('n', integer=True)
        dom = self.annihilator.parent.base.dom
        R, _ = RecurrenceOperators(dom.old_poly_ring(n), 'Sn')

        for i, j in enumerate(self.annihilator.listofpoly):
            listofdmp = j.all_coeffs()
            degree = len(listofdmp) - 1
            for k in range(degree + 1):
                coeff = listofdmp[degree - k]
                if coeff == 0:
                    continue
                if i - k in dict1:
                    dict1[i - k] += (coeff * rf(n - k + 1, i))
                else:
                    dict1[i - k] = (coeff * rf(n - k + 1, i))

        sol = []
        lower = min(dict1.keys())
        upper = max(dict1.keys())

        for j in range(lower, upper + 1):
            if j in dict1.keys():
                sol.append(dict1[j].subs(n, n - lower))
            else:
                sol.append(S(0))
        # recurrence relation
        sol = RecurrenceOperator(sol, R)

        if not self._have_init_cond:
            return HolonomicSequence(sol)
        if self.x0 != 0:
            return HolonomicSequence(sol)
        # computing the initial conditions for recurrence
        order = sol.order
        all_roots = roots(sol.listofpoly[-1].rep, filter='Z')
        all_roots = all_roots.keys()

        if all_roots:
            max_root = max(all_roots)
            if max_root >= 0:
                order += max_root + 1

        y0 = _extend_y0(self, order)
        u0 = []
        # u(n) = y^n(0)/factorial(n)
        for i, j in enumerate(y0):
            u0.append(j / factorial(i))

        return HolonomicSequence(sol, u0)
Example #36
0
def test_roots():
    assert roots(1, x) == {}
    assert roots(x, x) == {S.Zero: 1}
    assert roots(x**9, x) == {S.Zero: 9}
    assert roots(((x - 2) * (x + 3) * (x - 4)).expand(), x) == {
        -S(3): 1,
        S(2): 1,
        S(4): 1
    }

    assert roots(2 * x + 1, x) == {-S.Half: 1}
    assert roots((2 * x + 1)**2, x) == {-S.Half: 2}
    assert roots((2 * x + 1)**5, x) == {-S.Half: 5}
    assert roots((2 * x + 1)**10, x) == {-S.Half: 10}

    assert roots(x**4 - 1, x) == {I: 1, S.One: 1, -S.One: 1, -I: 1}
    assert roots((x**4 - 1)**2, x) == {I: 2, S.One: 2, -S.One: 2, -I: 2}

    assert roots(((2 * x - 3)**2).expand(), x) == {Rational(3, 2): 2}
    assert roots(((2 * x + 3)**2).expand(), x) == {-Rational(3, 2): 2}

    assert roots(((2 * x - 3)**3).expand(), x) == {Rational(3, 2): 3}
    assert roots(((2 * x + 3)**3).expand(), x) == {-Rational(3, 2): 3}

    assert roots(((2 * x - 3)**5).expand(), x) == {Rational(3, 2): 5}
    assert roots(((2 * x + 3)**5).expand(), x) == {-Rational(3, 2): 5}

    assert roots(((a * x - b)**5).expand(), x) == {b / a: 5}
    assert roots(((a * x + b)**5).expand(), x) == {-b / a: 5}

    assert roots(x**4 - 2 * x**2 + 1, x) == {S.One: 2, -S.One: 2}

    assert roots(x**6 - 4*x**4 + 4*x**3 - x**2, x) == \
        {S.One: 2, -1 - sqrt(2): 1, S.Zero: 2, -1 + sqrt(2): 1}

    assert roots(x**8 - 1, x) == {
        sqrt(2) / 2 + I * sqrt(2) / 2: 1,
        sqrt(2) / 2 - I * sqrt(2) / 2: 1,
        -sqrt(2) / 2 + I * sqrt(2) / 2: 1,
        -sqrt(2) / 2 - I * sqrt(2) / 2: 1,
        S.One: 1,
        -S.One: 1,
        I: 1,
        -I: 1
    }

    f = -2016*x**2 - 5616*x**3 - 2056*x**4 + 3324*x**5 + 2176*x**6 - \
        224*x**7 - 384*x**8 - 64*x**9

    assert roots(f) == {
        S(0): 2,
        -S(2): 2,
        S(2): 1,
        -S(7) / 2: 1,
        -S(3) / 2: 1,
        -S(1) / 2: 1,
        S(3) / 2: 1
    }

    assert roots((a + b + c) * x - (a + b + c + d), x) == {
        (a + b + c + d) / (a + b + c): 1
    }

    assert roots(x**3 + x**2 - x + 1, x, cubics=False) == {}
    assert roots(((x - 2) * (x + 3) * (x - 4)).expand(), x, cubics=False) == {
        -S(3): 1,
        S(2): 1,
        S(4): 1
    }
    assert roots(((x - 2)*(x + 3)*(x - 4)*(x - 5)).expand(), x, cubics=False) == \
        {-S(3): 1, S(2): 1, S(4): 1, S(5): 1}
    assert roots(x**3 + 2 * x**2 + 4 * x + 8, x) == {
        -S(2): 1,
        -2 * I: 1,
        2 * I: 1
    }
    assert roots(x**3 + 2*x**2 + 4*x + 8, x, cubics=True) == \
        {-2*I: 1, 2*I: 1, -S(2): 1}
    assert roots((x**2 - x)*(x**3 + 2*x**2 + 4*x + 8), x ) == \
        {S(1): 1, S(0): 1, -S(2): 1, -2*I: 1, 2*I: 1}

    r1_2, r1_3, r1_9, r4_9, r19_27 = [
        Rational(*r) for r in ((1, 2), (1, 3), (1, 9), (4, 9), (19, 27))
    ]

    U = -r1_2 - r1_2 * I * 3**r1_2
    V = -r1_2 + r1_2 * I * 3**r1_2
    W = (r19_27 + r1_9 * 33**r1_2)**r1_3

    assert roots(x**3 + x**2 - x + 1, x, cubics=True) == {
        -r1_3 - U * W - r4_9 * (U * W)**(-1): 1,
        -r1_3 - V * W - r4_9 * (V * W)**(-1): 1,
        -r1_3 - W - r4_9 * (W)**(-1): 1,
    }

    f = (x**2 + 2 * x + 3).subs(x, 2 * x**2 + 3 * x).subs(x, 5 * x - 4)

    r13_20, r1_20 = [Rational(*r) for r in ((13, 20), (1, 20))]

    s2 = sqrt(2)
    assert roots(f, x) == {
        r13_20 + r1_20 * sqrt(1 - 8 * I * s2): 1,
        r13_20 - r1_20 * sqrt(1 - 8 * I * s2): 1,
        r13_20 + r1_20 * sqrt(1 + 8 * I * s2): 1,
        r13_20 - r1_20 * sqrt(1 + 8 * I * s2): 1,
    }

    f = x**4 + x**3 + x**2 + x + 1

    r1_4, r1_8, r5_8 = [Rational(*r) for r in ((1, 4), (1, 8), (5, 8))]

    assert roots(f, x) == {
        -r1_4 + r1_4 * 5**r1_2 + I * (r5_8 + r1_8 * 5**r1_2)**r1_2: 1,
        -r1_4 + r1_4 * 5**r1_2 - I * (r5_8 + r1_8 * 5**r1_2)**r1_2: 1,
        -r1_4 - r1_4 * 5**r1_2 + I * (r5_8 - r1_8 * 5**r1_2)**r1_2: 1,
        -r1_4 - r1_4 * 5**r1_2 - I * (r5_8 - r1_8 * 5**r1_2)**r1_2: 1,
    }

    f = z**3 + (-2 - y) * z**2 + (1 + 2 * y - 2 * x**2) * z - y + 2 * x**2

    assert roots(f, z) == {
        S.One: 1,
        S.Half + S.Half * y + S.Half * sqrt(1 - 2 * y + y**2 + 8 * x**2): 1,
        S.Half + S.Half * y - S.Half * sqrt(1 - 2 * y + y**2 + 8 * x**2): 1,
    }

    assert roots(a * b * c * x**3 + 2 * x**2 + 4 * x + 8, x,
                 cubics=False) == {}
    assert roots(a * b * c * x**3 + 2 * x**2 + 4 * x + 8, x, cubics=True) != {}

    assert roots(x**4 - 1, x, filter='Z') == {S.One: 1, -S.One: 1}
    assert roots(x**4 - 1, x, filter='I') == {I: 1, -I: 1}

    assert roots((x - 1) * (x + 1), x) == {S.One: 1, -S.One: 1}
    assert roots((x - 1) * (x + 1), x, predicate=lambda r: r.is_positive) == {
        S.One: 1
    }

    assert roots(x**4 - 1, x, filter='Z', multiple=True) == [-S.One, S.One]
    assert roots(x**4 - 1, x, filter='I', multiple=True) == [-I, I]

    assert roots(x**3, x, multiple=True) == [S.Zero, S.Zero, S.Zero]
    assert roots(1234, x, multiple=True) == []

    f = x**6 - x**5 + x**4 - x**3 + x**2 - x + 1

    assert roots(f) == {
        -I * sin(pi / 7) + cos(pi / 7): 1,
        -I * sin(2 * pi / 7) - cos(2 * pi / 7): 1,
        -I * sin(3 * pi / 7) + cos(3 * pi / 7): 1,
        I * sin(pi / 7) + cos(pi / 7): 1,
        I * sin(2 * pi / 7) - cos(2 * pi / 7): 1,
        I * sin(3 * pi / 7) + cos(3 * pi / 7): 1,
    }

    g = ((x**2 + 1) * f**2).expand()

    assert roots(g) == {
        -I * sin(pi / 7) + cos(pi / 7): 2,
        -I * sin(2 * pi / 7) - cos(2 * pi / 7): 2,
        -I * sin(3 * pi / 7) + cos(3 * pi / 7): 2,
        I * sin(pi / 7) + cos(pi / 7): 2,
        I * sin(2 * pi / 7) - cos(2 * pi / 7): 2,
        I * sin(3 * pi / 7) + cos(3 * pi / 7): 2,
        -I: 1,
        I: 1,
    }

    r = roots(x**3 + 40 * x + 64)
    real_root = [rx for rx in r if rx.is_real][0]
    cr = 4 + 2 * sqrt(1074) / 9
    assert real_root == -2 * cr**(S(1) / 3) + 20 / (3 * cr**(S(1) / 3))

    eq = Poly((7 + 5 * sqrt(2)) * x**3 + (-6 - 4 * sqrt(2)) * x**2 +
              (-sqrt(2) - 1) * x + 2,
              x,
              domain='EX')
    assert roots(eq) == {-1 + sqrt(2): 1, -2 + 2 * sqrt(2): 1, -sqrt(2) + 1: 1}

    eq = Poly(41 * x**5 + 29 * sqrt(2) * x**5 - 153 * x**4 -
              108 * sqrt(2) * x**4 + 175 * x**3 + 125 * sqrt(2) * x**3 -
              45 * x**2 - 30 * sqrt(2) * x**2 - 26 * sqrt(2) * x - 26 * x + 24,
              x,
              domain='EX')
    assert roots(eq) == {
        -sqrt(2) + 1: 1,
        -2 + 2 * sqrt(2): 1,
        -1 + sqrt(2): 1,
        -4 + 4 * sqrt(2): 1,
        -3 + 3 * sqrt(2): 1
    }

    eq = Poly(x**3 - 2 * x**2 + 6 * sqrt(2) * x**2 - 8 * sqrt(2) * x + 23 * x -
              14 + 14 * sqrt(2),
              x,
              domain='EX')
    assert roots(eq) == {
        -2 * sqrt(2) + 2: 1,
        -2 * sqrt(2) + 1: 1,
        -2 * sqrt(2) - 1: 1
    }

    assert roots(Poly((x + sqrt(2))**3 - 7, x, domain='EX')) == \
        {-sqrt(2) - 7**(S(1)/3)/2 - sqrt(3)*7**(S(1)/3)*I/2: 1,
         -sqrt(2) - 7**(S(1)/3)/2 + sqrt(3)*7**(S(1)/3)*I/2: 1,
         -sqrt(2) + 7**(S(1)/3): 1}
Example #37
0
def test_issue_16589():
    eq = Poly(
        x**4 - 8 * sqrt(2) * x**3 + 4 * x**3 - 64 * sqrt(2) * x**2 + 1024 * x,
        x)
    roots_eq = roots(eq)
    assert 0 in roots_eq
Example #38
0
def test_issue_13340():
    eq = Poly(y**3 + exp(x) * y + x, y, domain='EX')
    roots_d = roots(eq)
    assert len(roots_d) == 3
Example #39
0
def solve_riccati(fx, x, b0, b1, b2, gensol=False):
    """
    The main function that gives particular/general
    solutions to Riccati ODEs that have atleast 1
    rational particular solution.
    """
    # Step 1 : Convert to Normal Form
    a = -b0*b2 + b1**2/4 - b1.diff(x)/2 + 3*b2.diff(x)**2/(4*b2**2) + b1*b2.diff(x)/(2*b2) - \
        b2.diff(x, 2)/(2*b2)
    a_t = a.together()
    num, den = [Poly(e, x, extension=True) for e in a_t.as_numer_denom()]
    num, den = num.cancel(den, include=True)

    # Step 2
    presol = []

    # Step 3 : a(x) is 0
    if num == 0:
        presol.append(1/(x + Dummy('C1')))

    # Step 4 : a(x) is a non-zero constant
    elif x not in num.free_symbols.union(den.free_symbols):
        presol.extend([sqrt(a), -sqrt(a)])

    # Step 5 : Find poles and valuation at infinity
    poles = roots(den, x)
    poles, muls = list(poles.keys()), list(poles.values())
    val_inf = val_at_inf(num, den, x)

    if len(poles):
        # Check necessary conditions (outlined in the module docstring)
        if not check_necessary_conds(val_inf, muls):
            raise ValueError("Rational Solution doesn't exist")

        # Step 6
        # Construct c-vectors for each singular point
        c = construct_c(num, den, x, poles, muls)

        # Construct d vectors for each singular point
        d = construct_d(num, den, x, val_inf)

        # Step 7 : Iterate over all possible combinations and return solutions
        # For each possible combination, generate an array of 0's and 1's
        # where 0 means pick 1st choice and 1 means pick the second choice.

        # NOTE: We could exit from the loop if we find 3 particular solutions,
        # but it is not implemented here as -
        #   a. Finding 3 particular solutions is very rare. Most of the time,
        #      only 2 particular solutions are found.
        #   b. In case we exit after finding 3 particular solutions, it might
        #      happen that 1 or 2 of them are redundant solutions. So, instead of
        #      spending some more time in computing the particular solutions,
        #      we will end up computing the general solution from a single
        #      particular solution which is usually slower than computing the
        #      general solution from 2 or 3 particular solutions.
        c.append(d)
        choices = product(*c)
        for choice in choices:
            m, ybar = compute_m_ybar(x, poles, choice, -val_inf//2)
            numy, deny = [Poly(e, x, extension=True) for e in ybar.together().as_numer_denom()]
            # Step 10 : Check if a valid solution exists. If yes, also check
            # if m is a non-negative integer
            if m.is_nonnegative == True and m.is_integer == True:

                # Step 11 : Find polynomial solutions of degree m for the auxiliary equation
                psol, coeffs, exists = solve_aux_eq(num, den, numy, deny, x, m)

                # Step 12 : If valid polynomial solution exists, append solution.
                if exists:
                    # m == 0 case
                    if psol == 1 and coeffs == 0:
                        # p(x) = 1, so p'(x)/p(x) term need not be added
                        presol.append(ybar)
                    # m is a positive integer and there are valid coefficients
                    elif len(coeffs):
                        # Substitute the valid coefficients to get p(x)
                        psol = psol.xreplace(coeffs)
                        # y(x) = ybar(x) + p'(x)/p(x)
                        presol.append(ybar + psol.diff(x)/psol)

    # Remove redundant solutions from the list of existing solutions
    remove = set()
    for i in range(len(presol)):
        for j in range(i+1, len(presol)):
            rem = remove_redundant_sols(presol[i], presol[j], x)
            if rem is not None:
                remove.add(rem)
    sols = [x for x in presol if x not in remove]

    # Step 15 : Inverse transform the solutions of the equation in normal form
    bp = -b2.diff(x)/(2*b2**2) - b1/(2*b2)

    # If general solution is required, compute it from the particular solutions
    if gensol:
        sols = [get_gen_sol_from_part_sol(sols, a, x)]

    # Inverse transform the particular solutions
    presol = [Eq(fx, riccati_inverse_normal(y, x, b1, b2, bp).cancel(extension=True)) for y in sols]
    return presol
Example #40
0
def test_issue_14522():
    eq = Poly(x**4 + x**3*(16 + 32*I) + x**2*(-285 + 386*I) + x*(-2824 - 448*I) - 2058 - 6053*I, x)
    roots_eq = roots(eq)
    assert all(eq(r) == 0 for r in roots_eq)
Example #41
0
 def _pole_degree(poly):
     root_all = roots(poly.rep, filter='Z')
     if 0 in root_all.keys():
         return root_all[0]
     else:
         return 0
Example #42
0
def test_roots():
    assert roots(1, x) == {}
    assert roots(x, x) == {S.Zero: 1}
    assert roots(x ** 9, x) == {S.Zero: 9}
    assert roots(((x - 2) * (x + 3) * (x - 4)).expand(), x) == {-S(3): 1, S(2): 1, S(4): 1}

    assert roots(2 * x + 1, x) == {-S.Half: 1}
    assert roots((2 * x + 1) ** 2, x) == {-S.Half: 2}
    assert roots((2 * x + 1) ** 5, x) == {-S.Half: 5}
    assert roots((2 * x + 1) ** 10, x) == {-S.Half: 10}

    assert roots(x ** 4 - 1, x) == {I: 1, S.One: 1, -S.One: 1, -I: 1}
    assert roots((x ** 4 - 1) ** 2, x) == {I: 2, S.One: 2, -S.One: 2, -I: 2}

    assert roots(((2 * x - 3) ** 2).expand(), x) == {Rational(3, 2): 2}
    assert roots(((2 * x + 3) ** 2).expand(), x) == {-Rational(3, 2): 2}

    assert roots(((2 * x - 3) ** 3).expand(), x) == {Rational(3, 2): 3}
    assert roots(((2 * x + 3) ** 3).expand(), x) == {-Rational(3, 2): 3}

    assert roots(((2 * x - 3) ** 5).expand(), x) == {Rational(3, 2): 5}
    assert roots(((2 * x + 3) ** 5).expand(), x) == {-Rational(3, 2): 5}

    assert roots(((a * x - b) ** 5).expand(), x) == {b / a: 5}
    assert roots(((a * x + b) ** 5).expand(), x) == {-b / a: 5}

    assert roots(x ** 4 - 2 * x ** 2 + 1, x) == {S.One: 2, -S.One: 2}

    assert roots(x ** 6 - 4 * x ** 4 + 4 * x ** 3 - x ** 2, x) == {
        S.One: 2,
        -1 - sqrt(2): 1,
        S.Zero: 2,
        -1 + sqrt(2): 1,
    }

    R1 = sorted([r.evalf() for r in roots(x ** 2 + x + 1, x)])
    R2 = sorted([r for r in roots(x ** 2 + x + 1.0, x)])

    assert R1 == R2

    assert roots(x ** 8 - 1, x) == {
        2 ** S.Half / 2 + I * 2 ** S.Half / 2: 1,
        2 ** S.Half / 2 - I * 2 ** S.Half / 2: 1,
        -2 ** S.Half / 2 + I * 2 ** S.Half / 2: 1,
        -2 ** S.Half / 2 - I * 2 ** S.Half / 2: 1,
        S.One: 1,
        -S.One: 1,
        I: 1,
        -I: 1,
    }

    assert roots(
        -2016 * x ** 2
        - 5616 * x ** 3
        - 2056 * x ** 4
        + 3324 * x ** 5
        + 2176 * x ** 6
        - 224 * x ** 7
        - 384 * x ** 8
        - 64 * x ** 9,
        x,
    ) == {S(0): 2, -S(2): 2, S(2): 1, -S(7) / 2: 1, -S(3) / 2: 1, -S(1) / 2: 1, S(3) / 2: 1}

    assert roots((a + b + c) * x - (a + b + c + d), x) == {(a + b + c + d) / (a + b + c): 1}

    assert roots(x ** 3 + x ** 2 - x + 1, x, cubics=False) == {}
    assert roots(((x - 2) * (x + 3) * (x - 4)).expand(), x, cubics=False) == {-S(3): 1, S(2): 1, S(4): 1}
    assert roots(((x - 2) * (x + 3) * (x - 4) * (x - 5)).expand(), x, cubics=False) == {
        -S(3): 1,
        S(2): 1,
        S(4): 1,
        S(5): 1,
    }
    assert roots(x ** 3 + 2 * x ** 2 + 4 * x + 8, x) == {-S(2): 1, -2 * I: 1, 2 * I: 1}
    assert roots(x ** 3 + 2 * x ** 2 + 4 * x + 8, x, cubics=True) == {-2 * I: 1, 2 * I: 1, -S(2): 1}
    assert roots((x ** 2 - x) * (x ** 3 + 2 * x ** 2 + 4 * x + 8), x) == {
        S(1): 1,
        S(0): 1,
        -S(2): 1,
        -2 * I: 1,
        2 * I: 1,
    }

    r1_2, r1_3, r1_9, r4_9, r19_27 = [Rational(*r) for r in ((1, 2), (1, 3), (1, 9), (4, 9), (19, 27))]

    U = r1_2 + r1_2 * I * 3 ** r1_2
    V = r1_2 - r1_2 * I * 3 ** r1_2
    W = (r19_27 + r1_9 * 33 ** r1_2) ** r1_3

    assert roots(x ** 3 + x ** 2 - x + 1, x, cubics=True) == {
        -r1_3 + U * W + r4_9 * (U * W) ** (-1): 1,
        -r1_3 + V * W + r4_9 * (V * W) ** (-1): 1,
        -r1_3 - W - r4_9 * (W) ** (-1): 1,
    }

    f = (x ** 2 + 2 * x + 3).subs(x, 2 * x ** 2 + 3 * x).subs(x, 5 * x - 4)

    r1_2, r13_20, r1_100 = [Rational(*r) for r in ((1, 2), (13, 20), (1, 100))]

    assert roots(f, x) == {
        r13_20 + r1_100 * (25 - 200 * I * 2 ** r1_2) ** r1_2: 1,
        r13_20 - r1_100 * (25 - 200 * I * 2 ** r1_2) ** r1_2: 1,
        r13_20 + r1_100 * (25 + 200 * I * 2 ** r1_2) ** r1_2: 1,
        r13_20 - r1_100 * (25 + 200 * I * 2 ** r1_2) ** r1_2: 1,
    }

    f = x ** 4 + x ** 3 + x ** 2 + x + 1

    r1_2, r1_4, r5_2 = [Rational(*r) for r in ((1, 2), (1, 4), (5, 2))]

    assert roots(f, x) == {
        -r1_4 + r1_4 * 5 ** r1_2 + r1_2 * (-r5_2 - r1_2 * 5 ** r1_2) ** r1_2: 1,
        -r1_4 + r1_4 * 5 ** r1_2 - r1_2 * (-r5_2 - r1_2 * 5 ** r1_2) ** r1_2: 1,
        -r1_4 - r1_4 * 5 ** r1_2 + r1_2 * (-r5_2 + r1_2 * 5 ** r1_2) ** r1_2: 1,
        -r1_4 - r1_4 * 5 ** r1_2 - r1_2 * (-r5_2 + r1_2 * 5 ** r1_2) ** r1_2: 1,
    }

    f = z ** 3 + (-2 - y) * z ** 2 + (1 + 2 * y - 2 * x ** 2) * z - y + 2 * x ** 2

    assert roots(f, z) == {
        S.One: 1,
        S.Half + S.Half * y + S.Half * (1 - 2 * y + y ** 2 + 8 * x ** 2) ** S.Half: 1,
        S.Half + S.Half * y - S.Half * (1 - 2 * y + y ** 2 + 8 * x ** 2) ** S.Half: 1,
    }

    assert roots(a * b * c * x ** 3 + 2 * x ** 2 + 4 * x + 8, x, cubics=False) == {}
    assert roots(a * b * c * x ** 3 + 2 * x ** 2 + 4 * x + 8, x, cubics=True) != {}

    assert roots(x ** 4 - 1, x, filter="Z") == {S.One: 1, -S.One: 1}
    assert roots(x ** 4 - 1, x, filter="I") == {I: 1, -I: 1}

    assert roots((x - 1) * (x + 1), x) == {S.One: 1, -S.One: 1}
    assert roots((x - 1) * (x + 1), x, predicate=lambda r: r.is_positive) == {S.One: 1}

    assert roots(x ** 4 - 1, x, filter="Z", multiple=True) == [S.One, -S.One]
    assert roots(x ** 4 - 1, x, filter="I", multiple=True) in ([I, -I], [-I, I])

    assert roots(x ** 3, x, multiple=True) == [S.Zero, S.Zero, S.Zero]
    assert roots(1234, x, multiple=True) == []
Example #43
0
    def series(self, n=6, coefficient=False, order=True):
        """
        Finds the power series expansion of given holonomic function.

        Examples
        ========

        >>> from sympy.holonomic.holonomic import HolonomicFunction, DifferentialOperators
        >>> from sympy.polys.domains import ZZ, QQ
        >>> from sympy import symbols
        >>> x = symbols('x')
        >>> R, Dx = DifferentialOperators(QQ.old_poly_ring(x),'Dx')

        >>> HolonomicFunction(Dx - 1, x, 0, [1]).series()  # e^x
        1 + x + x**2/2 + x**3/6 + x**4/24 + x**5/120 + O(x**6)

        >>> HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]).series(n=8)  # sin(x)
        x - x**3/6 + x**5/120 - x**7/5040 + O(x**8)

        See Also
        ========

        HolonomicFunction.to_sequence
        """

        recurrence = self.to_sequence()
        l = len(recurrence.u0) - 1
        k = recurrence.recurrence.order
        x = self.x
        seq_dmp = recurrence.recurrence.listofpoly
        R = recurrence.recurrence.parent.base
        K = R.get_field()
        seq = []

        if 0 in roots(seq_dmp[-1].rep, filter='Z').keys():
            singular = True
        else:
            singular = False

        for i, j in enumerate(seq_dmp):
            seq.append(K.new(j.rep))

        sub = [-seq[i] / seq[k] for i in range(k)]
        sol = [i for i in recurrence.u0]

        if l + 1 >= n:
            pass
        else:
            # use the initial conditions to find the next term
            for i in range(l + 1 - k, n - k):
                coeff = S(0)
                for j in range(k):
                    if i + j >= 0:
                        coeff += DMFsubs(sub[j], i) * sol[i + j]
                sol.append(coeff)

        if coefficient:
            return sol

        ser = S(0)
        for i, j in enumerate(sol):
            ser += x**i * j
        if order:
            return ser + Order(x**n, x)
        else:
            return ser
Example #44
0
def test_issue_19113():
    eq = cos(x)**3 - cos(x) + 1
    raises(PolynomialError, lambda: roots(eq))
Example #45
0
    def _eval_expand_diracdelta(self, **hints):
        """
        Compute a simplified representation of the function using
        property number 4. Pass ``wrt`` as a hint to expand the expression
        with respect to a particular variable.

        Explanation
        ===========

        ``wrt`` is:

        - a variable with respect to which a DiracDelta expression will
        get expanded.

        Examples
        ========

        >>> from sympy import DiracDelta
        >>> from sympy.abc import x, y

        >>> DiracDelta(x*y).expand(diracdelta=True, wrt=x)
        DiracDelta(x)/Abs(y)
        >>> DiracDelta(x*y).expand(diracdelta=True, wrt=y)
        DiracDelta(y)/Abs(x)

        >>> DiracDelta(x**2 + x - 2).expand(diracdelta=True, wrt=x)
        DiracDelta(x - 1)/3 + DiracDelta(x + 2)/3

        See Also
        ========

        is_simple, Diracdelta

        """
        from sympy.polys.polyroots import roots

        wrt = hints.get('wrt', None)
        if wrt is None:
            free = self.free_symbols
            if len(free) == 1:
                wrt = free.pop()
            else:
                raise TypeError(filldedent('''
            When there is more than 1 free symbol or variable in the expression,
            the 'wrt' keyword is required as a hint to expand when using the
            DiracDelta hint.'''))

        if not self.args[0].has(wrt) or (len(self.args) > 1 and self.args[1] != 0 ):
            return self
        try:
            argroots = roots(self.args[0], wrt)
            result = 0
            valid = True
            darg = abs(diff(self.args[0], wrt))
            for r, m in argroots.items():
                if r.is_real is not False and m == 1:
                    result += self.func(wrt - r)/darg.subs(wrt, r)
                else:
                    # don't handle non-real and if m != 1 then
                    # a polynomial will have a zero in the derivative (darg)
                    # at r
                    valid = False
                    break
            if valid:
                return result
        except PolynomialError:
            pass
        return self
Example #46
0
def test_issue_17454():
    assert roots([1, -3 * (-4 - 4 * I)**2 / 8 + 12 * I, 0],
                 multiple=True) == [0, 0]
Example #47
0
def test_roots():
    assert roots(1, x) == {}
    assert roots(x, x) == {S.Zero: 1}
    assert roots(x**9, x) == {S.Zero: 9}
    assert roots(((x - 2)*(x + 3)*(x - 4)).expand(), x) == {-S(3): 1, S(2): 1, S(4): 1}

    assert roots(2*x + 1, x) == {-S.Half: 1}
    assert roots((2*x + 1)**2, x) == {-S.Half: 2}
    assert roots((2*x + 1)**5, x) == {-S.Half: 5}
    assert roots((2*x + 1)**10, x) == {-S.Half: 10}

    assert roots(x**4 - 1, x) == {I: 1, S.One: 1, -S.One: 1, -I: 1}
    assert roots((x**4 - 1)**2, x) == {I: 2, S.One: 2, -S.One: 2, -I: 2}

    assert roots(((2*x - 3)**2).expand(), x) == { Rational(3, 2): 2}
    assert roots(((2*x + 3)**2).expand(), x) == {-Rational(3, 2): 2}

    assert roots(((2*x - 3)**3).expand(), x) == { Rational(3, 2): 3}
    assert roots(((2*x + 3)**3).expand(), x) == {-Rational(3, 2): 3}

    assert roots(((2*x - 3)**5).expand(), x) == { Rational(3, 2): 5}
    assert roots(((2*x + 3)**5).expand(), x) == {-Rational(3, 2): 5}

    assert roots(((a*x - b)**5).expand(), x) == { b/a: 5}
    assert roots(((a*x + b)**5).expand(), x) == {-b/a: 5}

    assert roots(x**2 + (-a - 1)*x + a, x) == {a: 1, S.One: 1}

    assert roots(x**4 - 2*x**2 + 1, x) == {S.One: 2, -S.One: 2}

    assert roots(x**6 - 4*x**4 + 4*x**3 - x**2, x) == \
        {S.One: 2, -1 - sqrt(2): 1, S.Zero: 2, -1 + sqrt(2): 1}

    assert roots(x**8 - 1, x) == {
        sqrt(2)/2 + I*sqrt(2)/2: 1,
        sqrt(2)/2 - I*sqrt(2)/2: 1,
        -sqrt(2)/2 + I*sqrt(2)/2: 1,
        -sqrt(2)/2 - I*sqrt(2)/2: 1,
        S.One: 1, -S.One: 1, I: 1, -I: 1
    }

    f = -2016*x**2 - 5616*x**3 - 2056*x**4 + 3324*x**5 + 2176*x**6 - \
        224*x**7 - 384*x**8 - 64*x**9

    assert roots(f) == {S(0): 2, -S(2): 2, S(2): 1, -S(7)/2: 1, -S(3)/2: 1, -S(1)/2: 1, S(3)/2: 1}

    assert roots((a + b + c)*x - (a + b + c + d), x) == {(a + b + c + d)/(a + b + c): 1}

    assert roots(x**3 + x**2 - x + 1, x, cubics=False) == {}
    assert roots(((x - 2)*(
        x + 3)*(x - 4)).expand(), x, cubics=False) == {-S(3): 1, S(2): 1, S(4): 1}
    assert roots(((x - 2)*(x + 3)*(x - 4)*(x - 5)).expand(), x, cubics=False) == \
        {-S(3): 1, S(2): 1, S(4): 1, S(5): 1}
    assert roots(x**3 + 2*x**2 + 4*x + 8, x) == {-S(2): 1, -2*I: 1, 2*I: 1}
    assert roots(x**3 + 2*x**2 + 4*x + 8, x, cubics=True) == \
        {-2*I: 1, 2*I: 1, -S(2): 1}
    assert roots((x**2 - x)*(x**3 + 2*x**2 + 4*x + 8), x ) == \
        {S(1): 1, S(0): 1, -S(2): 1, -2*I: 1, 2*I: 1}

    r1_2, r1_3, r1_9, r4_9, r19_27 = [ Rational(*r)
        for r in ((1, 2), (1, 3), (1, 9), (4, 9), (19, 27)) ]

    U = -r1_2 - r1_2*I*3**r1_2
    V = -r1_2 + r1_2*I*3**r1_2
    W = (r19_27 + r1_9*33**r1_2)**r1_3

    assert roots(x**3 + x**2 - x + 1, x, cubics=True) == {
        -r1_3 - U*W - r4_9*(U*W)**(-1): 1,
        -r1_3 - V*W - r4_9*(V*W)**(-1): 1,
        -r1_3 - W - r4_9*(  W)**(-1): 1,
    }

    f = (x**2 + 2*x + 3).subs(x, 2*x**2 + 3*x).subs(x, 5*x - 4)

    r13_20, r1_20 = [ Rational(*r)
        for r in ((13, 20), (1, 20)) ]

    s2 = sqrt(2)
    assert roots(f, x) == {
        r13_20 + r1_20*sqrt(1 - 8*I*s2): 1,
        r13_20 - r1_20*sqrt(1 - 8*I*s2): 1,
        r13_20 + r1_20*sqrt(1 + 8*I*s2): 1,
        r13_20 - r1_20*sqrt(1 + 8*I*s2): 1,
    }

    f = x**4 + x**3 + x**2 + x + 1

    r1_4, r1_8, r5_8 = [ Rational(*r) for r in ((1, 4), (1, 8), (5, 8)) ]

    assert roots(f, x) == {
        -r1_4 + r1_4*5**r1_2 + I*(r5_8 + r1_8*5**r1_2)**r1_2: 1,
        -r1_4 + r1_4*5**r1_2 - I*(r5_8 + r1_8*5**r1_2)**r1_2: 1,
        -r1_4 - r1_4*5**r1_2 + I*(r5_8 - r1_8*5**r1_2)**r1_2: 1,
        -r1_4 - r1_4*5**r1_2 - I*(r5_8 - r1_8*5**r1_2)**r1_2: 1,
    }

    f = z**3 + (-2 - y)*z**2 + (1 + 2*y - 2*x**2)*z - y + 2*x**2

    assert roots(f, z) == {
        S.One: 1,
        S.Half + S.Half*y + S.Half*sqrt(1 - 2*y + y**2 + 8*x**2): 1,
        S.Half + S.Half*y - S.Half*sqrt(1 - 2*y + y**2 + 8*x**2): 1,
    }

    assert roots(a*b*c*x**3 + 2*x**2 + 4*x + 8, x, cubics=False) == {}
    assert roots(a*b*c*x**3 + 2*x**2 + 4*x + 8, x, cubics=True) != {}

    assert roots(x**4 - 1, x, filter='Z') == {S.One: 1, -S.One: 1}
    assert roots(x**4 - 1, x, filter='I') == {I: 1, -I: 1}

    assert roots((x - 1)*(x + 1), x) == {S.One: 1, -S.One: 1}
    assert roots(
        (x - 1)*(x + 1), x, predicate=lambda r: r.is_positive) == {S.One: 1}

    assert roots(x**4 - 1, x, filter='Z', multiple=True) == [-S.One, S.One]
    assert roots(x**4 - 1, x, filter='I', multiple=True) == [I, -I]

    assert roots(x**3, x, multiple=True) == [S.Zero, S.Zero, S.Zero]
    assert roots(1234, x, multiple=True) == []

    f = x**6 - x**5 + x**4 - x**3 + x**2 - x + 1

    assert roots(f) == {
        -I*sin(pi/7) + cos(pi/7): 1,
        -I*sin(2*pi/7) - cos(2*pi/7): 1,
        -I*sin(3*pi/7) + cos(3*pi/7): 1,
        I*sin(pi/7) + cos(pi/7): 1,
        I*sin(2*pi/7) - cos(2*pi/7): 1,
        I*sin(3*pi/7) + cos(3*pi/7): 1,
    }

    g = ((x**2 + 1)*f**2).expand()

    assert roots(g) == {
        -I*sin(pi/7) + cos(pi/7): 2,
        -I*sin(2*pi/7) - cos(2*pi/7): 2,
        -I*sin(3*pi/7) + cos(3*pi/7): 2,
        I*sin(pi/7) + cos(pi/7): 2,
        I*sin(2*pi/7) - cos(2*pi/7): 2,
        I*sin(3*pi/7) + cos(3*pi/7): 2,
        -I: 1, I: 1,
    }

    r = roots(x**3 + 40*x + 64)
    real_root = [rx for rx in r if rx.is_real][0]
    cr = 4 + 2*sqrt(1074)/9
    assert real_root == -2*root(cr, 3) + 20/(3*root(cr, 3))

    eq = Poly((7 + 5*sqrt(2))*x**3 + (-6 - 4*sqrt(2))*x**2 + (-sqrt(2) - 1)*x + 2, x, domain='EX')
    assert roots(eq) == {-1 + sqrt(2): 1, -2 + 2*sqrt(2): 1, -sqrt(2) + 1: 1}

    eq = Poly(41*x**5 + 29*sqrt(2)*x**5 - 153*x**4 - 108*sqrt(2)*x**4 +
    175*x**3 + 125*sqrt(2)*x**3 - 45*x**2 - 30*sqrt(2)*x**2 - 26*sqrt(2)*x -
    26*x + 24, x, domain='EX')
    assert roots(eq) == {-sqrt(2) + 1: 1, -2 + 2*sqrt(2): 1, -1 + sqrt(2): 1,
                         -4 + 4*sqrt(2): 1, -3 + 3*sqrt(2): 1}

    eq = Poly(x**3 - 2*x**2 + 6*sqrt(2)*x**2 - 8*sqrt(2)*x + 23*x - 14 +
            14*sqrt(2), x, domain='EX')
    assert roots(eq) == {-2*sqrt(2) + 2: 1, -2*sqrt(2) + 1: 1, -2*sqrt(2) - 1: 1}

    assert roots(Poly((x + sqrt(2))**3 - 7, x, domain='EX')) == \
        {-sqrt(2) - root(7, 3)/2 - sqrt(3)*root(7, 3)*I/2: 1,
         -sqrt(2) - root(7, 3)/2 + sqrt(3)*root(7, 3)*I/2: 1,
         -sqrt(2) + root(7, 3): 1}
Example #48
0
    def _eval_expand_diracdelta(self, **hints):
        """Compute a simplified representation of the function using
           property number 4. Pass wrt as a hint to expand the expression
           with respect to a particular variable.

           wrt is:

           - a variable with respect to which a DiracDelta expression will
           get expanded.

           Examples
           ========

           >>> from sympy import DiracDelta
           >>> from sympy.abc import x, y

           >>> DiracDelta(x*y).expand(diracdelta=True, wrt=x)
           DiracDelta(x)/Abs(y)
           >>> DiracDelta(x*y).expand(diracdelta=True, wrt=y)
           DiracDelta(y)/Abs(x)

           >>> DiracDelta(x**2 + x - 2).expand(diracdelta=True, wrt=x)
           DiracDelta(x - 1)/3 + DiracDelta(x + 2)/3

           See Also
           ========

           is_simple, Diracdelta

        """
        from sympy.polys.polyroots import roots

        wrt = hints.get('wrt', None)
        if wrt is None:
            free = self.free_symbols
            if len(free) == 1:
                wrt = free.pop()
            else:
                raise TypeError(filldedent('''
            When there is more than 1 free symbol or variable in the expression,
            the 'wrt' keyword is required as a hint to expand when using the
            DiracDelta hint.'''))

        if not self.args[0].has(wrt) or (len(self.args) > 1 and self.args[1] != 0 ):
            return self
        try:
            argroots = roots(self.args[0], wrt)
            result = 0
            valid = True
            darg = abs(diff(self.args[0], wrt))
            for r, m in argroots.items():
                if r.is_real is not False and m == 1:
                    result += self.func(wrt - r)/darg.subs(wrt, r)
                else:
                    # don't handle non-real and if m != 1 then
                    # a polynomial will have a zero in the derivative (darg)
                    # at r
                    valid = False
                    break
            if valid:
                return result
        except PolynomialError:
            pass
        return self
Example #49
0
def test_roots0():
    assert roots(1, x) == {}
    assert roots(x, x) == {S.Zero: 1}
    assert roots(x**9, x) == {S.Zero: 9}
    assert roots(((x - 2) * (x + 3) * (x - 4)).expand(), x) == {
        -S(3): 1,
        S(2): 1,
        S(4): 1
    }

    assert roots(2 * x + 1, x) == {Rational(-1, 2): 1}
    assert roots((2 * x + 1)**2, x) == {Rational(-1, 2): 2}
    assert roots((2 * x + 1)**5, x) == {Rational(-1, 2): 5}
    assert roots((2 * x + 1)**10, x) == {Rational(-1, 2): 10}

    assert roots(x**4 - 1, x) == {I: 1, S.One: 1, -S.One: 1, -I: 1}
    assert roots((x**4 - 1)**2, x) == {I: 2, S.One: 2, -S.One: 2, -I: 2}

    assert roots(((2 * x - 3)**2).expand(), x) == {Rational(3, 2): 2}
    assert roots(((2 * x + 3)**2).expand(), x) == {Rational(-3, 2): 2}

    assert roots(((2 * x - 3)**3).expand(), x) == {Rational(3, 2): 3}
    assert roots(((2 * x + 3)**3).expand(), x) == {Rational(-3, 2): 3}

    assert roots(((2 * x - 3)**5).expand(), x) == {Rational(3, 2): 5}
    assert roots(((2 * x + 3)**5).expand(), x) == {Rational(-3, 2): 5}

    assert roots(((a * x - b)**5).expand(), x) == {b / a: 5}
    assert roots(((a * x + b)**5).expand(), x) == {-b / a: 5}

    assert roots(x**2 + (-a - 1) * x + a, x) == {a: 1, S.One: 1}

    assert roots(x**4 - 2 * x**2 + 1, x) == {S.One: 2, S.NegativeOne: 2}

    assert roots(x**6 - 4*x**4 + 4*x**3 - x**2, x) == \
        {S.One: 2, -1 - sqrt(2): 1, S.Zero: 2, -1 + sqrt(2): 1}

    assert roots(x**8 - 1, x) == {
        sqrt(2) / 2 + I * sqrt(2) / 2: 1,
        sqrt(2) / 2 - I * sqrt(2) / 2: 1,
        -sqrt(2) / 2 + I * sqrt(2) / 2: 1,
        -sqrt(2) / 2 - I * sqrt(2) / 2: 1,
        S.One: 1,
        -S.One: 1,
        I: 1,
        -I: 1
    }

    f = -2016*x**2 - 5616*x**3 - 2056*x**4 + 3324*x**5 + 2176*x**6 - \
        224*x**7 - 384*x**8 - 64*x**9

    assert roots(f) == {
        S.Zero: 2,
        -S(2): 2,
        S(2): 1,
        Rational(-7, 2): 1,
        Rational(-3, 2): 1,
        Rational(-1, 2): 1,
        Rational(3, 2): 1
    }

    assert roots((a + b + c) * x - (a + b + c + d), x) == {
        (a + b + c + d) / (a + b + c): 1
    }

    assert roots(x**3 + x**2 - x + 1, x, cubics=False) == {}
    assert roots(((x - 2) * (x + 3) * (x - 4)).expand(), x, cubics=False) == {
        -S(3): 1,
        S(2): 1,
        S(4): 1
    }
    assert roots(((x - 2)*(x + 3)*(x - 4)*(x - 5)).expand(), x, cubics=False) == \
        {-S(3): 1, S(2): 1, S(4): 1, S(5): 1}
    assert roots(x**3 + 2 * x**2 + 4 * x + 8, x) == {
        -S(2): 1,
        -2 * I: 1,
        2 * I: 1
    }
    assert roots(x**3 + 2*x**2 + 4*x + 8, x, cubics=True) == \
        {-2*I: 1, 2*I: 1, -S(2): 1}
    assert roots((x**2 - x)*(x**3 + 2*x**2 + 4*x + 8), x ) == \
        {S.One: 1, S.Zero: 1, -S(2): 1, -2*I: 1, 2*I: 1}

    r1_2, r1_3 = S.Half, Rational(1, 3)

    x0 = (3 * sqrt(33) + 19)**r1_3
    x1 = 4 / x0 / 3
    x2 = x0 / 3
    x3 = sqrt(3) * I / 2
    x4 = x3 - r1_2
    x5 = -x3 - r1_2
    assert roots(x**3 + x**2 - x + 1, x, cubics=True) == {
        -x1 - x2 - r1_3: 1,
        -x1 / x4 - x2 * x4 - r1_3: 1,
        -x1 / x5 - x2 * x5 - r1_3: 1,
    }

    f = (x**2 + 2 * x + 3).subs(x, 2 * x**2 + 3 * x).subs(x, 5 * x - 4)

    r13_20, r1_20 = [Rational(*r) for r in ((13, 20), (1, 20))]

    s2 = sqrt(2)
    assert roots(f, x) == {
        r13_20 + r1_20 * sqrt(1 - 8 * I * s2): 1,
        r13_20 - r1_20 * sqrt(1 - 8 * I * s2): 1,
        r13_20 + r1_20 * sqrt(1 + 8 * I * s2): 1,
        r13_20 - r1_20 * sqrt(1 + 8 * I * s2): 1,
    }

    f = x**4 + x**3 + x**2 + x + 1

    r1_4, r1_8, r5_8 = [Rational(*r) for r in ((1, 4), (1, 8), (5, 8))]

    assert roots(f, x) == {
        -r1_4 + r1_4 * 5**r1_2 + I * (r5_8 + r1_8 * 5**r1_2)**r1_2: 1,
        -r1_4 + r1_4 * 5**r1_2 - I * (r5_8 + r1_8 * 5**r1_2)**r1_2: 1,
        -r1_4 - r1_4 * 5**r1_2 + I * (r5_8 - r1_8 * 5**r1_2)**r1_2: 1,
        -r1_4 - r1_4 * 5**r1_2 - I * (r5_8 - r1_8 * 5**r1_2)**r1_2: 1,
    }

    f = z**3 + (-2 - y) * z**2 + (1 + 2 * y - 2 * x**2) * z - y + 2 * x**2

    assert roots(f, z) == {
        S.One: 1,
        S.Half + S.Half * y + S.Half * sqrt(1 - 2 * y + y**2 + 8 * x**2): 1,
        S.Half + S.Half * y - S.Half * sqrt(1 - 2 * y + y**2 + 8 * x**2): 1,
    }

    assert roots(a * b * c * x**3 + 2 * x**2 + 4 * x + 8, x,
                 cubics=False) == {}
    assert roots(a * b * c * x**3 + 2 * x**2 + 4 * x + 8, x, cubics=True) != {}

    assert roots(x**4 - 1, x, filter='Z') == {S.One: 1, -S.One: 1}
    assert roots(x**4 - 1, x, filter='I') == {I: 1, -I: 1}

    assert roots((x - 1) * (x + 1), x) == {S.One: 1, -S.One: 1}
    assert roots((x - 1) * (x + 1), x, predicate=lambda r: r.is_positive) == {
        S.One: 1
    }

    assert roots(x**4 - 1, x, filter='Z', multiple=True) == [-S.One, S.One]
    assert roots(x**4 - 1, x, filter='I', multiple=True) == [I, -I]

    ar, br = symbols('a, b', real=True)
    p = x**2 * (ar - br)**2 + 2 * x * (br - ar) + 1
    assert roots(p, x, filter='R') == {1 / (ar - br): 2}

    assert roots(x**3, x, multiple=True) == [S.Zero, S.Zero, S.Zero]
    assert roots(1234, x, multiple=True) == []

    f = x**6 - x**5 + x**4 - x**3 + x**2 - x + 1

    assert roots(f) == {
        -I * sin(pi / 7) + cos(pi / 7): 1,
        -I * sin(pi * Rational(2, 7)) - cos(pi * Rational(2, 7)): 1,
        -I * sin(pi * Rational(3, 7)) + cos(pi * Rational(3, 7)): 1,
        I * sin(pi / 7) + cos(pi / 7): 1,
        I * sin(pi * Rational(2, 7)) - cos(pi * Rational(2, 7)): 1,
        I * sin(pi * Rational(3, 7)) + cos(pi * Rational(3, 7)): 1,
    }

    g = ((x**2 + 1) * f**2).expand()

    assert roots(g) == {
        -I * sin(pi / 7) + cos(pi / 7): 2,
        -I * sin(pi * Rational(2, 7)) - cos(pi * Rational(2, 7)): 2,
        -I * sin(pi * Rational(3, 7)) + cos(pi * Rational(3, 7)): 2,
        I * sin(pi / 7) + cos(pi / 7): 2,
        I * sin(pi * Rational(2, 7)) - cos(pi * Rational(2, 7)): 2,
        I * sin(pi * Rational(3, 7)) + cos(pi * Rational(3, 7)): 2,
        -I: 1,
        I: 1,
    }

    r = roots(x**3 + 40 * x + 64)
    real_root = [rx for rx in r if rx.is_real][0]
    cr = 108 + 6 * sqrt(1074)
    assert real_root == -2 * root(cr, 3) / 3 + 20 / root(cr, 3)

    eq = Poly((7 + 5 * sqrt(2)) * x**3 + (-6 - 4 * sqrt(2)) * x**2 +
              (-sqrt(2) - 1) * x + 2,
              x,
              domain='EX')
    assert roots(eq) == {-1 + sqrt(2): 1, -2 + 2 * sqrt(2): 1, -sqrt(2) + 1: 1}

    eq = Poly(41 * x**5 + 29 * sqrt(2) * x**5 - 153 * x**4 -
              108 * sqrt(2) * x**4 + 175 * x**3 + 125 * sqrt(2) * x**3 -
              45 * x**2 - 30 * sqrt(2) * x**2 - 26 * sqrt(2) * x - 26 * x + 24,
              x,
              domain='EX')
    assert roots(eq) == {
        -sqrt(2) + 1: 1,
        -2 + 2 * sqrt(2): 1,
        -1 + sqrt(2): 1,
        -4 + 4 * sqrt(2): 1,
        -3 + 3 * sqrt(2): 1
    }

    eq = Poly(x**3 - 2 * x**2 + 6 * sqrt(2) * x**2 - 8 * sqrt(2) * x + 23 * x -
              14 + 14 * sqrt(2),
              x,
              domain='EX')
    assert roots(eq) == {
        -2 * sqrt(2) + 2: 1,
        -2 * sqrt(2) + 1: 1,
        -2 * sqrt(2) - 1: 1
    }

    assert roots(Poly((x + sqrt(2))**3 - 7, x, domain='EX')) == \
        {-sqrt(2) + root(7, 3)*(-S.Half - sqrt(3)*I/2): 1,
         -sqrt(2) + root(7, 3)*(-S.Half + sqrt(3)*I/2): 1,
         -sqrt(2) + root(7, 3): 1}
Example #50
0
def _monotonic_sign(self):
    """Return the value closest to 0 that ``self`` may have if all symbols
    are signed and the result is uniformly the same sign for all values of symbols.
    If a symbol is only signed but not known to be an
    integer or the result is 0 then a symbol representative of the sign of self
    will be returned. Otherwise, None is returned if a) the sign could be positive
    or negative or b) self is not in one of the following forms:

    - L(x, y, ...) + A: a function linear in all symbols x, y, ... with an
      additive constant; if A is zero then the function can be a monomial whose
      sign is monotonic over the range of the variables, e.g. (x + 1)**3 if x is
      nonnegative.
    - A/L(x, y, ...) + B: the inverse of a function linear in all symbols x, y, ...
      that does not have a sign change from positive to negative for any set
      of values for the variables.
    - M(x, y, ...) + A: a monomial M whose factors are all signed and a constant, A.
    - A/M(x, y, ...) + B: the inverse of a monomial and constants A and B.
    - P(x): a univariate polynomial

    Examples
    ========

    >>> from sympy.core.exprtools import _monotonic_sign as F
    >>> from sympy import Dummy
    >>> nn = Dummy(integer=True, nonnegative=True)
    >>> p = Dummy(integer=True, positive=True)
    >>> p2 = Dummy(integer=True, positive=True)
    >>> F(nn + 1)
    1
    >>> F(p - 1)
    _nneg
    >>> F(nn*p + 1)
    1
    >>> F(p2*p + 1)
    2
    >>> F(nn - 1)  # could be negative, zero or positive
    """
    if not self.is_extended_real:
        return

    if (-self).is_Symbol:
        rv = _monotonic_sign(-self)
        return rv if rv is None else -rv

    if not self.is_Add and self.as_numer_denom()[1].is_number:
        s = self
        if s.is_prime:
            if s.is_odd:
                return S(3)
            else:
                return S(2)
        elif s.is_composite:
            if s.is_odd:
                return S(9)
            else:
                return S(4)
        elif s.is_positive:
            if s.is_even:
                if s.is_prime is False:
                    return S(4)
                else:
                    return S(2)
            elif s.is_integer:
                return S.One
            else:
                return _eps
        elif s.is_extended_negative:
            if s.is_even:
                return S(-2)
            elif s.is_integer:
                return S.NegativeOne
            else:
                return -_eps
        if s.is_zero or s.is_extended_nonpositive or s.is_extended_nonnegative:
            return S.Zero
        return None

    # univariate polynomial
    free = self.free_symbols
    if len(free) == 1:
        if self.is_polynomial():
            from sympy.polys.polytools import real_roots
            from sympy.polys.polyroots import roots
            from sympy.polys.polyerrors import PolynomialError
            x = free.pop()
            x0 = _monotonic_sign(x)
            if x0 == _eps or x0 == -_eps:
                x0 = S.Zero
            if x0 is not None:
                d = self.diff(x)
                if d.is_number:
                    currentroots = []
                else:
                    try:
                        currentroots = real_roots(d)
                    except (PolynomialError, NotImplementedError):
                        currentroots = [r for r in roots(d, x) if r.is_extended_real]
                y = self.subs(x, x0)
                if x.is_nonnegative and all(r <= x0 for r in currentroots):
                    if y.is_nonnegative and d.is_positive:
                        if y:
                            return y if y.is_positive else Dummy('pos', positive=True)
                        else:
                            return Dummy('nneg', nonnegative=True)
                    if y.is_nonpositive and d.is_negative:
                        if y:
                            return y if y.is_negative else Dummy('neg', negative=True)
                        else:
                            return Dummy('npos', nonpositive=True)
                elif x.is_nonpositive and all(r >= x0 for r in currentroots):
                    if y.is_nonnegative and d.is_negative:
                        if y:
                            return Dummy('pos', positive=True)
                        else:
                            return Dummy('nneg', nonnegative=True)
                    if y.is_nonpositive and d.is_positive:
                        if y:
                            return Dummy('neg', negative=True)
                        else:
                            return Dummy('npos', nonpositive=True)
        else:
            n, d = self.as_numer_denom()
            den = None
            if n.is_number:
                den = _monotonic_sign(d)
            elif not d.is_number:
                if _monotonic_sign(n) is not None:
                    den = _monotonic_sign(d)
            if den is not None and (den.is_positive or den.is_negative):
                v = n*den
                if v.is_positive:
                    return Dummy('pos', positive=True)
                elif v.is_nonnegative:
                    return Dummy('nneg', nonnegative=True)
                elif v.is_negative:
                    return Dummy('neg', negative=True)
                elif v.is_nonpositive:
                    return Dummy('npos', nonpositive=True)
        return None

    # multivariate
    c, a = self.as_coeff_Add()
    v = None
    if not a.is_polynomial():
        # F/A or A/F where A is a number and F is a signed, rational monomial
        n, d = a.as_numer_denom()
        if not (n.is_number or d.is_number):
            return
        if (
                a.is_Mul or a.is_Pow) and \
                a.is_rational and \
                all(p.exp.is_Integer for p in a.atoms(Pow) if p.is_Pow) and \
                (a.is_positive or a.is_negative):
            v = S.One
            for ai in Mul.make_args(a):
                if ai.is_number:
                    v *= ai
                    continue
                reps = {}
                for x in ai.free_symbols:
                    reps[x] = _monotonic_sign(x)
                    if reps[x] is None:
                        return
                v *= ai.subs(reps)
    elif c:
        # signed linear expression
        if not any(p for p in a.atoms(Pow) if not p.is_number) and (a.is_nonpositive or a.is_nonnegative):
            free = list(a.free_symbols)
            p = {}
            for i in free:
                v = _monotonic_sign(i)
                if v is None:
                    return
                p[i] = v or (_eps if i.is_nonnegative else -_eps)
            v = a.xreplace(p)
    if v is not None:
        rv = v + c
        if v.is_nonnegative and rv.is_positive:
            return rv.subs(_eps, 0)
        if v.is_nonpositive and rv.is_negative:
            return rv.subs(_eps, 0)
Example #51
0
def test_roots_composite():
    assert len(roots(Poly(y**3 + y**2 * sqrt(x) + y + x, y,
                          composite=True))) == 3
Example #52
0
def test_roots():
    assert roots(1, x) == {}
    assert roots(x, x) == {S.Zero: 1}
    assert roots(x**9, x) == {S.Zero: 9}
    assert roots(((x-2)*(x+3)*(x-4)).expand(), x) == {-S(3): 1, S(2): 1, S(4): 1}

    assert roots(2*x+1, x) == {-S.Half: 1}
    assert roots((2*x+1)**2, x) == {-S.Half: 2}
    assert roots((2*x+1)**5, x) == {-S.Half: 5}
    assert roots((2*x+1)**10, x) == {-S.Half: 10}

    assert roots(x**4 - 1, x) == {I: 1, S.One: 1, -S.One: 1, -I: 1}
    assert roots((x**4 - 1)**2, x) == {I: 2, S.One: 2, -S.One: 2, -I: 2}

    assert roots(((2*x-3)**2).expand(), x) == { Rational(3,2): 2}
    assert roots(((2*x+3)**2).expand(), x) == {-Rational(3,2): 2}

    assert roots(((2*x-3)**3).expand(), x) == { Rational(3,2): 3}
    assert roots(((2*x+3)**3).expand(), x) == {-Rational(3,2): 3}

    assert roots(((2*x-3)**5).expand(), x) == { Rational(3,2): 5}
    assert roots(((2*x+3)**5).expand(), x) == {-Rational(3,2): 5}

    assert roots(((a*x-b)**5).expand(), x) == { b/a: 5}
    assert roots(((a*x+b)**5).expand(), x) == {-b/a: 5}

    assert roots(x**4-2*x**2+1, x) == {S.One: 2, -S.One: 2}

    assert roots(x**6-4*x**4+4*x**3-x**2, x) == \
        {S.One: 2, -1 - sqrt(2): 1, S.Zero: 2, -1 + sqrt(2): 1}

    assert roots(x**8-1, x) == {
         2**S.Half/2 + I*2**S.Half/2: 1,
         2**S.Half/2 - I*2**S.Half/2: 1,
        -2**S.Half/2 + I*2**S.Half/2: 1,
        -2**S.Half/2 - I*2**S.Half/2: 1,
        S.One: 1, -S.One: 1, I: 1, -I: 1
    }

    f = -2016*x**2 - 5616*x**3 - 2056*x**4 + 3324*x**5 + 2176*x**6 - 224*x**7 - 384*x**8 - 64*x**9

    assert roots(f) == {S(0): 2, -S(2): 2, S(2): 1, -S(7)/2: 1, -S(3)/2: 1, -S(1)/2: 1, S(3)/2: 1}

    assert roots((a+b+c)*x - (a+b+c+d), x) == {(a+b+c+d)/(a+b+c): 1}

    assert roots(x**3+x**2-x+1, x, cubics=False) == {}
    assert roots(((x-2)*(x+3)*(x-4)).expand(), x, cubics=False) == {-S(3): 1, S(2): 1, S(4): 1}
    assert roots(((x-2)*(x+3)*(x-4)*(x-5)).expand(), x, cubics=False) == \
            {-S(3): 1, S(2): 1, S(4): 1, S(5): 1}
    assert roots(x**3 + 2*x**2 + 4*x + 8, x) == {-S(2): 1, -2*I: 1, 2*I: 1}
    assert roots(x**3 + 2*x**2 + 4*x + 8, x, cubics=True) == \
                {-2*I: 1, 2*I: 1, -S(2): 1}
    assert roots((x**2 - x)*(x**3 + 2*x**2 + 4*x + 8), x ) == \
                {S(1): 1, S(0): 1, -S(2): 1, -2*I: 1, 2*I: 1}

    r1_2, r1_3, r1_9, r4_9, r19_27 = [ Rational(*r) \
        for r in ((1,2), (1,3), (1,9), (4,9), (19,27)) ]

    U = r1_2 + r1_2*I*3**r1_2
    V = r1_2 - r1_2*I*3**r1_2
    W = (r19_27 + r1_9*33**r1_2)**r1_3

    assert roots(x**3+x**2-x+1, x, cubics=True) == {
        -r1_3 + U*W + r4_9*(U*W)**(-1): 1,
        -r1_3 + V*W + r4_9*(V*W)**(-1): 1,
        -r1_3 -   W - r4_9*(  W)**(-1): 1,
    }

    f = (x**2+2*x+3).subs(x, 2*x**2 + 3*x).subs(x, 5*x-4)

    r1_2, r13_20, r1_100 = [ Rational(*r) \
        for r in ((1,2), (13,20), (1,100)) ]

    assert roots(f, x) == {
        r13_20 + r1_100*(25 - 200*I*2**r1_2)**r1_2: 1,
        r13_20 - r1_100*(25 - 200*I*2**r1_2)**r1_2: 1,
        r13_20 + r1_100*(25 + 200*I*2**r1_2)**r1_2: 1,
        r13_20 - r1_100*(25 + 200*I*2**r1_2)**r1_2: 1,
    }

    f = x**4 + x**3 + x**2 + x + 1

    r1_4, r1_8, r5_8 = [ Rational(*r) for r in ((1,4), (1,8), (5,8)) ]

    assert roots(f, x) == {
        -r1_4 + r1_4*5**r1_2 + I*(r5_8 + r1_8*5**r1_2)**r1_2: 1,
        -r1_4 + r1_4*5**r1_2 - I*(r5_8 + r1_8*5**r1_2)**r1_2: 1,
        -r1_4 - r1_4*5**r1_2 + I*(r5_8 - r1_8*5**r1_2)**r1_2: 1,
        -r1_4 - r1_4*5**r1_2 - I*(r5_8 - r1_8*5**r1_2)**r1_2: 1,
    }

    f = z**3 + (-2 - y)*z**2 + (1 + 2*y - 2*x**2)*z - y + 2*x**2

    assert roots(f, z) == {
        S.One: 1,
        S.Half + S.Half*y + S.Half*(1 - 2*y + y**2 + 8*x**2)**S.Half: 1,
        S.Half + S.Half*y - S.Half*(1 - 2*y + y**2 + 8*x**2)**S.Half: 1,
    }

    assert roots(a*b*c*x**3 + 2*x**2 + 4*x + 8, x, cubics=False) == {}
    assert roots(a*b*c*x**3 + 2*x**2 + 4*x + 8, x, cubics=True) != {}

    assert roots(x**4-1, x, filter='Z') == {S.One: 1, -S.One: 1}
    assert roots(x**4-1, x, filter='I') == {I: 1, -I: 1}

    assert roots((x-1)*(x+1), x) == {S.One: 1, -S.One: 1}
    assert roots((x-1)*(x+1), x, predicate=lambda r: r.is_positive) == {S.One: 1}

    assert roots(x**4-1, x, filter='Z', multiple=True) == [S.One, -S.One]
    assert roots(x**4-1, x, filter='I', multiple=True) in ([I, -I], [-I, I])

    assert roots(x**3, x, multiple=True) == [S.Zero, S.Zero, S.Zero]
    assert roots(1234, x, multiple=True) == []

    f = x**6 - x**5 + x**4 - x**3 + x**2 - x + 1

    assert roots(f) == {
        -I*sin(pi/7)   + cos(pi/7):   1,
        -I*sin(2*pi/7) - cos(2*pi/7): 1,
        -I*sin(3*pi/7) + cos(3*pi/7): 1,
         I*sin(pi/7)   + cos(pi/7):   1,
         I*sin(2*pi/7) - cos(2*pi/7): 1,
         I*sin(3*pi/7) + cos(3*pi/7): 1,
    }

    g = ((x**2 + 1)*f**2).expand()

    assert roots(g) == {
        -I*sin(pi/7)   + cos(pi/7):   2,
        -I*sin(2*pi/7) - cos(2*pi/7): 2,
        -I*sin(3*pi/7) + cos(3*pi/7): 2,
         I*sin(pi/7)   + cos(pi/7):   2,
         I*sin(2*pi/7) - cos(2*pi/7): 2,
         I*sin(3*pi/7) + cos(3*pi/7): 2,
        -I: 1, I: 1,
    }