示例#1
0
def trigintegrate(f, x):
    """Integrate f = Mul(trig) over x

       >>> from sympy import Symbol, sin, cos
       >>> from sympy.integrals.trigonometry import trigintegrate
       >>> from sympy.abc import x

       >>> trigintegrate(sin(x)*cos(x), x)
       sin(x)**2/2

       >>> trigintegrate(sin(x)**2, x)
       x/2 - cos(x)*sin(x)/2

       http://en.wikibooks.org/wiki/Calculus/Further_integration_techniques
    """

    pat, a,n,m = _pat_sincos(x)
    ##m - cos
    ##n - sin

    M = f.match(pat)

    if M is None:
        return

    n, m = M[n], M[m]   # should always be there
    if n is S.Zero and m is S.Zero:
        return x

    a = M[a]

    if n.is_integer and m.is_integer:

        if n.is_odd or m.is_odd:
            u = _u
            n_, m_ = n.is_odd, m.is_odd

            # take smallest n or m -- to choose simplest substitution
            if n_ and m_:
                n_ = n_ and     (n < m)  # NB: careful here, one of the
                m_ = m_ and not (n < m)  #     conditions *must* be true

            #  n      m       u=C        (n-1)/2    m
            # S(x) * C(x) dx  --> -(1-u^2)       * u  du
            if n_:
                ff = -(1-u**2)**((n-1)/2) * u**m
                uu = cos(a*x)

            #  n      m       u=S   n         (m-1)/2
            # S(x) * C(x) dx  -->  u  * (1-u^2)       du
            elif m_:
                ff = u**n * (1-u**2)**((m-1)/2)
                uu = sin(a*x)

            fi= sympy.integrals.integrate(ff, u)    # XXX cyclic deps
            fx= fi.subs(u, uu)
            return fx / a

        # n & m are even
        else:
            #               2k      2m                         2l       2l
            # we transform S (x) * C (x) into terms with only S (x) or C (x)
            #
            # example:
            #  100     4       100        2    2    100          4         2
            # S (x) * C (x) = S (x) * (1-S (x))  = S (x) * (1 + S (x) - 2*S (x))
            #
            #                  104       102     100
            #               = S (x) - 2*S (x) + S (x)
            #       2k
            # then S   is integrated with recursive formula

            # take largest n or m -- to choose simplest substitution
            n_ =  (abs(n) > abs(m))
            m_ =  (abs(m) > abs(n))
            res = S.Zero

            if n_:
                #  2k       2 k             i            2i
                # C   = (1-S )  = sum(i, (-) * B(k,i) * S  )
                if m > 0 :
                    for i in range(0,m/2+1):
                        res += (-1)**i * binomial(m/2,i) * sin_pow_integrate(n+2*i, x)

                elif m == 0:
                    res=sin_pow_integrate(n,x)
                else:
                    # m < 0 , |n| > |m|
                    #  /                                                           /
                    # |                                                           |
                    # |    m       n            -1        m+1     n-1     n - 1   |     m+2     n-2
                    # | cos (x) sin (x) dx =  ________ cos (x) sin (x) + _______  |  cos (x) sin (x) dx
                    # |                                                           |
                    # |                         m + 1                     m + 1   |
                    #/                                                           /
                    #
                    #
                    res=Rational(-1,m+1)*cos(x)**(m+1)*sin(x)**(n-1) + Rational(n-1,m+1)*trigintegrate(cos(x)**(m+2)*sin(x)**(n-2),x)


            elif m_:
                #  2k        2 k            i            2i
                # S   = (1 -C ) = sum(i, (-) * B(k,i) * C  )
                if n > 0:
                    #      /                            /
                    #     |                            |
                    #     |    m       n               |    -m         n
                    #     | cos (x)*sin (x) dx  or     | cos (x) * sin (x) dx
                    #     |                            |
                    #    /                            /
                    #
                    #    |m| > |n| ; m,n >0 ; m,n belong to Z - {0}
                    #       n                                        2
                    #    sin (x) term is expanded here interms of cos (x), and then integrated.
                    for i in range(0,n/2+1):
                        res += (-1)**i * binomial(n/2,i) * cos_pow_integrate(m+2*i, x)

                elif n == 0 :
                    ##  /
                    ## |
                    #  |  1
                    #  | _ _ _
                    #  |    m
                    #  | cos (x)
                    # /
                    res= cos_pow_integrate(m,x)
                else:
                    # n < 0 , |m| > |n|
                    #  /                                                         /
                    # |                                                         |
                    # |    m       n           1        m-1     n+1     m - 1   |     m-2     n+2
                    # | cos (x) sin (x) dx = _______ cos (x) sin (x) + _______  |  cos (x) sin (x) dx
                    # |                                                         |
                    # |                       n + 1                     n + 1   |
                    #/                                                         /
                    #
                    #
                    res= Rational(1,(n+1))*cos(x)**(m-1)*sin(x)**(n+1) + Rational(m-1,n+1)*trigintegrate(cos(x)**(m-2)*sin(x)**(n+2),x)

            else :
                if m == n:
                    ##Substitute sin(2x)/2 for sin(x)cos(x) and then Integrate.
                    res=sympy.integrals.integrate((Rational(1,2)*sin(2*x))**m,x)
                elif (m == -n):
                    if n < 0:
                        ##Same as the scheme described above.
                        res= Rational(1,(n+1))*cos(x)**(m-1)*sin(x)**(n+1) + Rational(m-1,n+1)*sympy.integrals.integrate(cos(x)**(m-2)*sin(x)**(n+2),x) ##the function argument to integrate in the end will be 1 , this cannot be integrated by trigintegrate. Hence use sympy.integrals.integrate.
                    else:
                        res=Rational(-1,m+1)*cos(x)**(m+1)*sin(x)**(n-1) + Rational(n-1,m+1)*sympy.integrals.integrate(cos(x)**(m+2)*sin(x)**(n-2),x)
            return res.subs(x, a*x) / a
示例#2
0
def test_cross_section():
    I = Symbol('I')
    l = Symbol('l')
    E = Symbol('E')
    C3, C4 = symbols('C3, C4')
    a, c, g, h, r, n = symbols('a, c, g, h, r, n')

    # test for second_moment and cross_section setter
    b0 = Beam(l, E, I)
    assert b0.second_moment == I
    assert b0.cross_section == None
    b0.cross_section = Circle((0, 0), 5)
    assert b0.second_moment == pi * Rational(625, 4)
    assert b0.cross_section == Circle((0, 0), 5)
    b0.second_moment = 2 * n - 6
    assert b0.second_moment == 2 * n - 6
    assert b0.cross_section == None
    with raises(ValueError):
        b0.second_moment = Circle((0, 0), 5)

    # beam with a circular cross-section
    b1 = Beam(50, E, Circle((0, 0), r))
    assert b1.cross_section == Circle((0, 0), r)
    assert b1.second_moment == pi * r * Abs(r)**3 / 4

    b1.apply_load(-10, 0, -1)
    b1.apply_load(R1, 5, -1)
    b1.apply_load(R2, 50, -1)
    b1.apply_load(90, 45, -2)
    b1.solve_for_reaction_loads(R1, R2)
    assert b1.load == (-10 * SingularityFunction(x, 0, -1) +
                       82 * SingularityFunction(x, 5, -1) / S(9) +
                       90 * SingularityFunction(x, 45, -2) +
                       8 * SingularityFunction(x, 50, -1) / 9)
    assert b1.bending_moment() == (10 * SingularityFunction(x, 0, 1) -
                                   82 * SingularityFunction(x, 5, 1) / 9 -
                                   90 * SingularityFunction(x, 45, 0) -
                                   8 * SingularityFunction(x, 50, 1) / 9)
    q = (-5 * SingularityFunction(x, 0, 2) +
         41 * SingularityFunction(x, 5, 2) / S(9) +
         90 * SingularityFunction(x, 45, 1) +
         4 * SingularityFunction(x, 50, 2) / S(9)) / (pi * E * r * Abs(r)**3)
    assert b1.slope() == C3 + 4 * q
    q = (-5 * SingularityFunction(x, 0, 3) / 3 +
         41 * SingularityFunction(x, 5, 3) / 27 +
         45 * SingularityFunction(x, 45, 2) +
         4 * SingularityFunction(x, 50, 3) / 27) / (pi * E * r * Abs(r)**3)
    assert b1.deflection() == C3 * x + C4 + 4 * q

    # beam with a recatangular cross-section
    b2 = Beam(20, E, Polygon((0, 0), (a, 0), (a, c), (0, c)))
    assert b2.cross_section == Polygon((0, 0), (a, 0), (a, c), (0, c))
    assert b2.second_moment == a * c**3 / 12
    # beam with a triangular cross-section
    b3 = Beam(15, E, Triangle((0, 0), (g, 0), (g / 2, h)))
    assert b3.cross_section == Triangle(Point2D(0, 0), Point2D(g, 0),
                                        Point2D(g / 2, h))
    assert b3.second_moment == g * h**3 / 36

    # composite beam
    b = b2.join(b3, "fixed")
    b.apply_load(-30, 0, -1)
    b.apply_load(65, 0, -2)
    b.apply_load(40, 0, -1)
    b.bc_slope = [(0, 0)]
    b.bc_deflection = [(0, 0)]

    assert b.second_moment == Piecewise((a * c**3 / 12, x <= 20),
                                        (g * h**3 / 36, x <= 35))
    assert b.cross_section == None
    assert b.length == 35
    assert b.slope().subs(x, 7) == 8400 / (E * a * c**3)
    assert b.slope().subs(
        x, 25) == 52200 / (E * g * h**3) + 39600 / (E * a * c**3)
    assert b.deflection().subs(
        x, 30) == -537000 / (E * g * h**3) - 712000 / (E * a * c**3)
示例#3
0
def roots_quartic(f):
    r"""
    Returns a list of roots of a quartic polynomial.

    There are many references for solving quartic expressions available [1-5].
    This reviewer has found that many of them require one to select from among
    2 or more possible sets of solutions and that some solutions work when one
    is searching for real roots but don't work when searching for complex roots
    (though this is not always stated clearly). The following routine has been
    tested and found to be correct for 0, 2 or 4 complex roots.

    The quasisymmetric case solution [6] looks for quartics that have the form
    `x**4 + A*x**3 + B*x**2 + C*x + D = 0` where `(C/A)**2 = D`.

    Although no general solution that is always applicable for all
    coefficients is known to this reviewer, certain conditions are tested
    to determine the simplest 4 expressions that can be returned:

      1) `f = c + a*(a**2/8 - b/2) == 0`
      2) `g = d - a*(a*(3*a**2/256 - b/16) + c/4) = 0`
      3) if `f != 0` and `g != 0` and `p = -d + a*c/4 - b**2/12` then
        a) `p == 0`
        b) `p != 0`

    Examples
    ========

        >>> from sympy import Poly, symbols, I
        >>> from sympy.polys.polyroots import roots_quartic

        >>> r = roots_quartic(Poly('x**4-6*x**3+17*x**2-26*x+20'))

        >>> # 4 complex roots: 1+-I*sqrt(3), 2+-I
        >>> sorted(str(tmp.evalf(n=2)) for tmp in r)
        ['1.0 + 1.7*I', '1.0 - 1.7*I', '2.0 + 1.0*I', '2.0 - 1.0*I']

    References
    ==========

    1. http://mathforum.org/dr.math/faq/faq.cubic.equations.html
    2. https://en.wikipedia.org/wiki/Quartic_function#Summary_of_Ferrari.27s_method
    3. http://planetmath.org/encyclopedia/GaloisTheoreticDerivationOfTheQuarticFormula.html
    4. http://staff.bath.ac.uk/masjhd/JHD-CA.pdf
    5. http://www.albmath.org/files/Math_5713.pdf
    6. http://www.statemaster.com/encyclopedia/Quartic-equation
    7. eqworld.ipmnet.ru/en/solutions/ae/ae0108.pdf
    """
    _, a, b, c, d = f.monic().all_coeffs()

    if not d:
        return [S.Zero] + roots([1, a, b, c], multiple=True)
    elif (c / a)**2 == d:
        x, m = f.gen, c / a

        g = Poly(x**2 + a * x + b - 2 * m, x)

        z1, z2 = roots_quadratic(g)

        h1 = Poly(x**2 - z1 * x + m, x)
        h2 = Poly(x**2 - z2 * x + m, x)

        r1 = roots_quadratic(h1)
        r2 = roots_quadratic(h2)

        return r1 + r2
    else:
        a2 = a**2
        e = b - 3 * a2 / 8
        f = _mexpand(c + a * (a2 / 8 - b / 2))
        g = _mexpand(d - a * (a * (3 * a2 / 256 - b / 16) + c / 4))
        aon4 = a / 4

        if f is S.Zero:
            y1, y2 = [sqrt(tmp) for tmp in roots([1, e, g], multiple=True)]
            return [tmp - aon4 for tmp in [-y1, -y2, y1, y2]]
        if g is S.Zero:
            y = [S.Zero] + roots([1, 0, e, f], multiple=True)
            return [tmp - aon4 for tmp in y]
        else:
            # Descartes-Euler method, see [7]
            sols = _roots_quartic_euler(e, f, g, aon4)
            if sols:
                return sols
            # Ferrari method, see [1, 2]
            a2 = a**2
            e = b - 3 * a2 / 8
            f = c + a * (a2 / 8 - b / 2)
            g = d - a * (a * (3 * a2 / 256 - b / 16) + c / 4)
            p = -e**2 / 12 - g
            q = -e**3 / 108 + e * g / 3 - f**2 / 8
            TH = Rational(1, 3)

            def _ans(y):
                w = sqrt(e + 2 * y)
                arg1 = 3 * e + 2 * y
                arg2 = 2 * f / w
                ans = []
                for s in [-1, 1]:
                    root = sqrt(-(arg1 + s * arg2))
                    for t in [-1, 1]:
                        ans.append((s * w - t * root) / 2 - aon4)
                return ans

            # p == 0 case
            y1 = e * Rational(-5, 6) - q**TH
            if p.is_zero:
                return _ans(y1)

            # if p != 0 then u below is not 0
            root = sqrt(q**2 / 4 + p**3 / 27)
            r = -q / 2 + root  # or -q/2 - root
            u = r**TH  # primary root of solve(x**3 - r, x)
            y2 = e * Rational(-5, 6) + u - p / u / 3
            if fuzzy_not(p.is_zero):
                return _ans(y2)

            # sort it out once they know the values of the coefficients
            return [
                Piecewise((a1, Eq(p, 0)), (a2, True))
                for a1, a2 in zip(_ans(y1), _ans(y2))
            ]
示例#4
0
def test_finite_diff_weights():

    d = finite_diff_weights(1, [5, 6, 7], 5)
    assert d[1][2] == [Rational(-3, 2), 2, Rational(-1, 2)]

    # Table 1, p. 702 in doi:10.1090/S0025-5718-1988-0935077-0
    # --------------------------------------------------------
    xl = [0, 1, -1, 2, -2, 3, -3, 4, -4]

    # d holds all coefficients
    d = finite_diff_weights(4, xl, S.Zero)

    # Zeroeth derivative
    for i in range(5):
        assert d[0][i] == [S.One] + [S.Zero] * 8

    # First derivative
    assert d[1][0] == [S.Zero] * 9
    assert d[1][2] == [S.Zero, S.Half, Rational(-1, 2)] + [S.Zero] * 6
    assert d[1][4] == [
        S.Zero,
        Rational(2, 3),
        Rational(-2, 3),
        Rational(-1, 12),
        Rational(1, 12)
    ] + [S.Zero] * 4
    assert d[1][6] == [
        S.Zero,
        Rational(3, 4),
        Rational(-3, 4),
        Rational(-3, 20),
        Rational(3, 20),
        Rational(1, 60),
        Rational(-1, 60)
    ] + [S.Zero] * 2
    assert d[1][8] == [
        S.Zero,
        Rational(4, 5),
        Rational(-4, 5),
        Rational(-1, 5),
        Rational(1, 5),
        Rational(4, 105),
        Rational(-4, 105),
        Rational(-1, 280),
        Rational(1, 280)
    ]

    # Second derivative
    for i in range(2):
        assert d[2][i] == [S.Zero] * 9
    assert d[2][2] == [-S(2), S.One, S.One] + [S.Zero] * 6
    assert d[2][4] == [
        Rational(-5, 2),
        Rational(4, 3),
        Rational(4, 3),
        Rational(-1, 12),
        Rational(-1, 12)
    ] + [S.Zero] * 4
    assert d[2][6] == [
        Rational(-49, 18),
        Rational(3, 2),
        Rational(3, 2),
        Rational(-3, 20),
        Rational(-3, 20),
        Rational(1, 90),
        Rational(1, 90)
    ] + [S.Zero] * 2
    assert d[2][8] == [
        Rational(-205, 72),
        Rational(8, 5),
        Rational(8, 5),
        Rational(-1, 5),
        Rational(-1, 5),
        Rational(8, 315),
        Rational(8, 315),
        Rational(-1, 560),
        Rational(-1, 560)
    ]

    # Third derivative
    for i in range(3):
        assert d[3][i] == [S.Zero] * 9
    assert d[3][4] == [S.Zero, -S.One, S.One, S.Half,
                       Rational(-1, 2)] + [S.Zero] * 4
    assert d[3][6] == [
        S.Zero,
        Rational(-13, 8),
        Rational(13, 8), S.One, -S.One,
        Rational(-1, 8),
        Rational(1, 8)
    ] + [S.Zero] * 2
    assert d[3][8] == [
        S.Zero,
        Rational(-61, 30),
        Rational(61, 30),
        Rational(169, 120),
        Rational(-169, 120),
        Rational(-3, 10),
        Rational(3, 10),
        Rational(7, 240),
        Rational(-7, 240)
    ]

    # Fourth derivative
    for i in range(4):
        assert d[4][i] == [S.Zero] * 9
    assert d[4][4] == [S(6), -S(4), -S(4), S.One, S.One] + [S.Zero] * 4
    assert d[4][6] == [
        Rational(28, 3),
        Rational(-13, 2),
        Rational(-13, 2),
        S(2),
        S(2),
        Rational(-1, 6),
        Rational(-1, 6)
    ] + [S.Zero] * 2
    assert d[4][8] == [
        Rational(91, 8),
        Rational(-122, 15),
        Rational(-122, 15),
        Rational(169, 60),
        Rational(169, 60),
        Rational(-2, 5),
        Rational(-2, 5),
        Rational(7, 240),
        Rational(7, 240)
    ]

    # Table 2, p. 703 in doi:10.1090/S0025-5718-1988-0935077-0
    # --------------------------------------------------------
    xl = [[
        j / S(2)
        for j in list(range(-i * 2 + 1, 0, 2)) + list(range(1, i * 2 + 1, 2))
    ] for i in range(1, 5)]

    # d holds all coefficients
    d = [
        finite_diff_weights({
            0: 1,
            1: 2,
            2: 4,
            3: 4
        }[i], xl[i], 0) for i in range(4)
    ]

    # Zeroth derivative
    assert d[0][0][1] == [S.Half, S.Half]
    assert d[1][0][3] == [
        Rational(-1, 16),
        Rational(9, 16),
        Rational(9, 16),
        Rational(-1, 16)
    ]
    assert d[2][0][5] == [
        Rational(3, 256),
        Rational(-25, 256),
        Rational(75, 128),
        Rational(75, 128),
        Rational(-25, 256),
        Rational(3, 256)
    ]
    assert d[3][0][7] == [
        Rational(-5, 2048),
        Rational(49, 2048),
        Rational(-245, 2048),
        Rational(1225, 2048),
        Rational(1225, 2048),
        Rational(-245, 2048),
        Rational(49, 2048),
        Rational(-5, 2048)
    ]

    # First derivative
    assert d[0][1][1] == [-S.One, S.One]
    assert d[1][1][3] == [
        Rational(1, 24),
        Rational(-9, 8),
        Rational(9, 8),
        Rational(-1, 24)
    ]
    assert d[2][1][5] == [
        Rational(-3, 640),
        Rational(25, 384),
        Rational(-75, 64),
        Rational(75, 64),
        Rational(-25, 384),
        Rational(3, 640)
    ]
    assert d[3][1][7] == [
        Rational(5, 7168),
        Rational(-49, 5120),
        Rational(245, 3072),
        Rational(-1225, 1024),
        Rational(1225, 1024),
        Rational(-245, 3072),
        Rational(49, 5120),
        Rational(-5, 7168)
    ]

    # Reasonably the rest of the table is also correct... (testing of that
    # deemed excessive at the moment)
    raises(ValueError, lambda: finite_diff_weights(-1, [1, 2]))
    raises(ValueError, lambda: finite_diff_weights(1.2, [1, 2]))
    x = symbols('x')
    raises(ValueError, lambda: finite_diff_weights(x, [1, 2]))
示例#5
0
def test_Beam():
    E = Symbol('E')
    E_1 = Symbol('E_1')
    I = Symbol('I')
    I_1 = Symbol('I_1')
    A = Symbol('A')

    b = Beam(1, E, I)
    assert b.length == 1
    assert b.elastic_modulus == E
    assert b.second_moment == I
    assert b.variable == x

    # Test the length setter
    b.length = 4
    assert b.length == 4

    # Test the E setter
    b.elastic_modulus = E_1
    assert b.elastic_modulus == E_1

    # Test the I setter
    b.second_moment = I_1
    assert b.second_moment is I_1

    # Test the variable setter
    b.variable = y
    assert b.variable is y

    # Test for all boundary conditions.
    b.bc_deflection = [(0, 2)]
    b.bc_slope = [(0, 1)]
    assert b.boundary_conditions == {'deflection': [(0, 2)], 'slope': [(0, 1)]}

    # Test for slope boundary condition method
    b.bc_slope.extend([(4, 3), (5, 0)])
    s_bcs = b.bc_slope
    assert s_bcs == [(0, 1), (4, 3), (5, 0)]

    # Test for deflection boundary condition method
    b.bc_deflection.extend([(4, 3), (5, 0)])
    d_bcs = b.bc_deflection
    assert d_bcs == [(0, 2), (4, 3), (5, 0)]

    # Test for updated boundary conditions
    bcs_new = b.boundary_conditions
    assert bcs_new == {
        'deflection': [(0, 2), (4, 3), (5, 0)],
        'slope': [(0, 1), (4, 3), (5, 0)]
    }

    b1 = Beam(30, E, I)
    b1.apply_load(-8, 0, -1)
    b1.apply_load(R1, 10, -1)
    b1.apply_load(R2, 30, -1)
    b1.apply_load(120, 30, -2)
    b1.bc_deflection = [(10, 0), (30, 0)]
    b1.solve_for_reaction_loads(R1, R2)

    # Test for finding reaction forces
    p = b1.reaction_loads
    q = {R1: 6, R2: 2}
    assert p == q

    # Test for load distribution function.
    p = b1.load
    q = -8*SingularityFunction(x, 0, -1) + 6*SingularityFunction(x, 10, -1) \
    + 120*SingularityFunction(x, 30, -2) + 2*SingularityFunction(x, 30, -1)
    assert p == q

    # Test for shear force distribution function
    p = b1.shear_force()
    q = 8*SingularityFunction(x, 0, 0) - 6*SingularityFunction(x, 10, 0) \
    - 120*SingularityFunction(x, 30, -1) - 2*SingularityFunction(x, 30, 0)
    assert p == q

    # Test for shear stress distribution function
    p = b1.shear_stress()
    q = (8*SingularityFunction(x, 0, 0) - 6*SingularityFunction(x, 10, 0) \
    - 120*SingularityFunction(x, 30, -1) \
    - 2*SingularityFunction(x, 30, 0))/A
    assert p == q

    # Test for bending moment distribution function
    p = b1.bending_moment()
    q = 8*SingularityFunction(x, 0, 1) - 6*SingularityFunction(x, 10, 1) \
    - 120*SingularityFunction(x, 30, 0) - 2*SingularityFunction(x, 30, 1)
    assert p == q

    # Test for slope distribution function
    p = b1.slope()
    q = -4*SingularityFunction(x, 0, 2) + 3*SingularityFunction(x, 10, 2) \
    + 120*SingularityFunction(x, 30, 1) + SingularityFunction(x, 30, 2) \
    + Rational(4000, 3)
    assert p == q / (E * I)

    # Test for deflection distribution function
    p = b1.deflection()
    q = x*Rational(4000, 3) - 4*SingularityFunction(x, 0, 3)/3 \
    + SingularityFunction(x, 10, 3) + 60*SingularityFunction(x, 30, 2) \
    + SingularityFunction(x, 30, 3)/3 - 12000
    assert p == q / (E * I)

    # Test using symbols
    l = Symbol('l')
    w0 = Symbol('w0')
    w2 = Symbol('w2')
    a1 = Symbol('a1')
    c = Symbol('c')
    c1 = Symbol('c1')
    d = Symbol('d')
    e = Symbol('e')
    f = Symbol('f')

    b2 = Beam(l, E, I)

    b2.apply_load(w0, a1, 1)
    b2.apply_load(w2, c1, -1)

    b2.bc_deflection = [(c, d)]
    b2.bc_slope = [(e, f)]

    # Test for load distribution function.
    p = b2.load
    q = w0 * SingularityFunction(x, a1, 1) + w2 * SingularityFunction(
        x, c1, -1)
    assert p == q

    # Test for shear force distribution function
    p = b2.shear_force()
    q = -w0*SingularityFunction(x, a1, 2)/2 \
    - w2*SingularityFunction(x, c1, 0)
    assert p == q

    # Test for shear stress distribution function
    p = b2.shear_stress()
    q = (-w0*SingularityFunction(x, a1, 2)/2 \
    - w2*SingularityFunction(x, c1, 0))/A
    assert p == q

    # Test for bending moment distribution function
    p = b2.bending_moment()
    q = -w0 * SingularityFunction(x, a1, 3) / 6 - w2 * SingularityFunction(
        x, c1, 1)
    assert p == q

    # Test for slope distribution function
    p = b2.slope()
    q = (w0 * SingularityFunction(x, a1, 4) / 24 +
         w2 * SingularityFunction(x, c1, 2) / 2) / (
             E * I) + (E * I * f - w0 * SingularityFunction(e, a1, 4) / 24 -
                       w2 * SingularityFunction(e, c1, 2) / 2) / (E * I)
    assert expand(p) == expand(q)

    # Test for deflection distribution function
    p = b2.deflection()
    q = x*(E*I*f - w0*SingularityFunction(e, a1, 4)/24 \
    - w2*SingularityFunction(e, c1, 2)/2)/(E*I) \
    + (w0*SingularityFunction(x, a1, 5)/120 \
    + w2*SingularityFunction(x, c1, 3)/6)/(E*I) \
    + (E*I*(-c*f + d) + c*w0*SingularityFunction(e, a1, 4)/24 \
    + c*w2*SingularityFunction(e, c1, 2)/2 \
    - w0*SingularityFunction(c, a1, 5)/120 \
    - w2*SingularityFunction(c, c1, 3)/6)/(E*I)
    assert simplify(p - q) == 0

    b3 = Beam(9, E, I, 2)
    b3.apply_load(value=-2, start=2, order=2, end=3)
    b3.bc_slope.append((0, 2))
    C3 = symbols('C3')
    C4 = symbols('C4')

    p = b3.load
    q = -2*SingularityFunction(x, 2, 2) + 2*SingularityFunction(x, 3, 0) \
    + 4*SingularityFunction(x, 3, 1) + 2*SingularityFunction(x, 3, 2)
    assert p == q

    p = b3.shear_force()
    q = 2*SingularityFunction(x, 2, 3)/3 - 2*SingularityFunction(x, 3, 1) \
    - 2*SingularityFunction(x, 3, 2) - 2*SingularityFunction(x, 3, 3)/3
    assert p == q

    p = b3.shear_stress()
    q = SingularityFunction(x, 2, 3)/3 - 1*SingularityFunction(x, 3, 1) \
    - 1*SingularityFunction(x, 3, 2) - 1*SingularityFunction(x, 3, 3)/3
    assert p == q

    p = b3.slope()
    q = 2 - (SingularityFunction(x, 2, 5)/30 - SingularityFunction(x, 3, 3)/3 \
    - SingularityFunction(x, 3, 4)/6 - SingularityFunction(x, 3, 5)/30)/(E*I)
    assert p == q

    p = b3.deflection()
    q = 2*x - (SingularityFunction(x, 2, 6)/180 \
    - SingularityFunction(x, 3, 4)/12 - SingularityFunction(x, 3, 5)/30 \
    - SingularityFunction(x, 3, 6)/180)/(E*I)
    assert p == q + C4

    b4 = Beam(4, E, I, 3)
    b4.apply_load(-3, 0, 0, end=3)

    p = b4.load
    q = -3 * SingularityFunction(x, 0, 0) + 3 * SingularityFunction(x, 3, 0)
    assert p == q

    p = b4.shear_force()
    q = 3*SingularityFunction(x, 0, 1) \
    - 3*SingularityFunction(x, 3, 1)
    assert p == q

    p = b4.shear_stress()
    q = SingularityFunction(x, 0, 1) - SingularityFunction(x, 3, 1)
    assert p == q

    p = b4.slope()
    q = -3 * SingularityFunction(x, 0, 3) / 6 + 3 * SingularityFunction(
        x, 3, 3) / 6
    assert p == q / (E * I) + C3

    p = b4.deflection()
    q = -3 * SingularityFunction(x, 0, 4) / 24 + 3 * SingularityFunction(
        x, 3, 4) / 24
    assert p == q / (E * I) + C3 * x + C4

    # can't use end with point loads
    raises(ValueError, lambda: b4.apply_load(-3, 0, -1, end=3))
    with raises(TypeError):
        b4.variable = 1
示例#6
0
def GeneralizedMultivariateLogGammaOmega(syms, omega, v, lamda, mu):
    """
    Extends GeneralizedMultivariateLogGamma.

    Parameters
    ==========

    syms: list/tuple/set of symbols
        For identifying each component
    omega: A square matrix
           Every element of square matrix must be absolute value of
           square root of correlation coefficient
    v: Positive real number
    lamda: List of positive real numbers
    mu: List of positive real numbers

    Returns
    =======

    RandomSymbol

    Examples
    ========

    >>> from sympy.stats import density
    >>> from sympy.stats.joint_rv_types import GeneralizedMultivariateLogGammaOmega
    >>> from sympy import Matrix, symbols, S
    >>> omega = Matrix([[1, S.Half, S.Half], [S.Half, 1, S.Half], [S.Half, S.Half, 1]])
    >>> v = 1
    >>> l, mu = [1, 1, 1], [1, 1, 1]
    >>> G = GeneralizedMultivariateLogGammaOmega('G', omega, v, l, mu)
    >>> y = symbols('y_1:4', positive=True)
    >>> density(G)(y[0], y[1], y[2])
    sqrt(2)*Sum((1 - sqrt(2)/2)**n*exp((n + 1)*(y_1 + y_2 + y_3) - exp(y_1) -
    exp(y_2) - exp(y_3))/gamma(n + 1)**3, (n, 0, oo))/2

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Generalized_multivariate_log-gamma_distribution
    .. [2] https://www.researchgate.net/publication/234137346_On_a_multivariate_log-gamma_distribution_and_the_use_of_the_distribution_in_the_Bayesian_analysis

    Notes
    =====

    If the GeneralizedMultivariateLogGammaOmega is too long to type use,
    ``from sympy.stats.joint_rv_types import GeneralizedMultivariateLogGammaOmega as GMVLGO``

    """
    _value_check((omega.is_square, isinstance(omega, Matrix)),
                 "omega must be a"
                 " square matrix")
    for val in omega.values():
        _value_check(
            (val >= 0, val <= 1),
            "all values in matrix must be between 0 and 1(both inclusive).")
    _value_check(omega.diagonal().equals(ones(1, omega.shape[0])),
                 "all the elements of diagonal should be 1.")
    _value_check((omega.shape[0] == len(lamda), len(lamda) == len(mu)),
                 "lamda, mu should be of same length and omega should "
                 " be of shape (length of lamda, length of mu)")
    _value_check(
        len(lamda) > 1, "the distribution should have at least"
        " two random variables.")
    delta = Pow(Rational(omega.det()), Rational(1, len(lamda) - 1))
    return GeneralizedMultivariateLogGamma(syms, delta, v, lamda, mu)
示例#7
0
def test_CRootOf___new__():
    assert rootof(x, 0) == 0
    assert rootof(x, -1) == 0

    assert rootof(x, S.Zero) == 0

    assert rootof(x - 1, 0) == 1
    assert rootof(x - 1, -1) == 1

    assert rootof(x + 1, 0) == -1
    assert rootof(x + 1, -1) == -1

    assert rootof(x**2 + 2 * x + 3, 0) == -1 - I * sqrt(2)
    assert rootof(x**2 + 2 * x + 3, 1) == -1 + I * sqrt(2)
    assert rootof(x**2 + 2 * x + 3, -1) == -1 + I * sqrt(2)
    assert rootof(x**2 + 2 * x + 3, -2) == -1 - I * sqrt(2)

    r = rootof(x**2 + 2 * x + 3, 0, radicals=False)
    assert isinstance(r, RootOf) is True

    r = rootof(x**2 + 2 * x + 3, 1, radicals=False)
    assert isinstance(r, RootOf) is True

    r = rootof(x**2 + 2 * x + 3, -1, radicals=False)
    assert isinstance(r, RootOf) is True

    r = rootof(x**2 + 2 * x + 3, -2, radicals=False)
    assert isinstance(r, RootOf) is True

    assert rootof((x - 1) * (x + 1), 0, radicals=False) == -1
    assert rootof((x - 1) * (x + 1), 1, radicals=False) == 1
    assert rootof((x - 1) * (x + 1), -1, radicals=False) == 1
    assert rootof((x - 1) * (x + 1), -2, radicals=False) == -1

    assert rootof((x - 1) * (x + 1), 0, radicals=True) == -1
    assert rootof((x - 1) * (x + 1), 1, radicals=True) == 1
    assert rootof((x - 1) * (x + 1), -1, radicals=True) == 1
    assert rootof((x - 1) * (x + 1), -2, radicals=True) == -1

    assert rootof((x - 1) * (x**3 + x + 3), 0) == rootof(x**3 + x + 3, 0)
    assert rootof((x - 1) * (x**3 + x + 3), 1) == 1
    assert rootof((x - 1) * (x**3 + x + 3), 2) == rootof(x**3 + x + 3, 1)
    assert rootof((x - 1) * (x**3 + x + 3), 3) == rootof(x**3 + x + 3, 2)
    assert rootof((x - 1) * (x**3 + x + 3), -1) == rootof(x**3 + x + 3, 2)
    assert rootof((x - 1) * (x**3 + x + 3), -2) == rootof(x**3 + x + 3, 1)
    assert rootof((x - 1) * (x**3 + x + 3), -3) == 1
    assert rootof((x - 1) * (x**3 + x + 3), -4) == rootof(x**3 + x + 3, 0)

    assert rootof(x**4 + 3 * x**3, 0) == -3
    assert rootof(x**4 + 3 * x**3, 1) == 0
    assert rootof(x**4 + 3 * x**3, 2) == 0
    assert rootof(x**4 + 3 * x**3, 3) == 0

    raises(GeneratorsNeeded, lambda: rootof(0, 0))
    raises(GeneratorsNeeded, lambda: rootof(1, 0))

    raises(PolynomialError, lambda: rootof(Poly(0, x), 0))
    raises(PolynomialError, lambda: rootof(Poly(1, x), 0))
    raises(PolynomialError, lambda: rootof(x - y, 0))
    # issue 8617
    raises(PolynomialError, lambda: rootof(exp(x), 0))

    raises(NotImplementedError, lambda: rootof(x**3 - x + sqrt(2), 0))
    raises(NotImplementedError, lambda: rootof(x**3 - x + I, 0))

    raises(IndexError, lambda: rootof(x**2 - 1, -4))
    raises(IndexError, lambda: rootof(x**2 - 1, -3))
    raises(IndexError, lambda: rootof(x**2 - 1, 2))
    raises(IndexError, lambda: rootof(x**2 - 1, 3))
    raises(ValueError, lambda: rootof(x**2 - 1, x))

    assert rootof(Poly(x - y, x), 0) == y

    assert rootof(Poly(x**2 - y, x), 0) == -sqrt(y)
    assert rootof(Poly(x**2 - y, x), 1) == sqrt(y)

    assert rootof(Poly(x**3 - y, x), 0) == y**Rational(1, 3)

    assert rootof(y * x**3 + y * x + 2 * y, x, 0) == -1
    raises(NotImplementedError, lambda: rootof(x**3 + x + 2 * y, x, 0))

    assert rootof(x**3 + x + 1, 0).is_commutative is True
示例#8
0
    def eval(cls, arg):
        if arg.is_Number:
            if arg is S.NaN:
                return S.NaN
            if arg is S.Zero:
                return S.ComplexInfinity

        if arg.could_extract_minus_sign():
            return -cls(-arg)

        i_coeff = arg.as_coefficient(S.ImaginaryUnit)
        if i_coeff is not None:
            return -S.ImaginaryUnit * C.coth(i_coeff)

        pi_coeff = _pi_coeff(arg, 2)
        if pi_coeff is not None:
            if pi_coeff.is_integer:
                return S.ComplexInfinity

            if not pi_coeff.is_Rational:
                narg = pi_coeff * S.Pi
                if narg != arg:
                    return cls(narg)
                return None

            cst_table = {2: S.Zero, 3: 1 / sqrt(3), 4: S.One, 6: sqrt(3)}

            try:
                result = cst_table[pi_coeff.q]

                if (2 * pi_coeff.p // pi_coeff.q) % 4 in (1, 3):
                    return -result
                else:
                    return result
            except KeyError:
                if pi_coeff.p > pi_coeff.q:
                    p, q = pi_coeff.p % pi_coeff.q, pi_coeff.q
                    if 2 * p > q:
                        return -cls(Rational(q - p, q) * S.Pi)
                    return cls(Rational(p, q) * S.Pi)

        if arg.is_Add:
            x, m = _peeloff_pi(arg)
            if m:
                if (m * 2 / S.Pi) % 2 == 0:
                    return cot(x)
                else:
                    return -tan(x)

        if arg.func is acot:
            return arg.args[0]

        if arg.func is atan:
            x = arg.args[0]
            return 1 / x

        if arg.func is asin:
            x = arg.args[0]
            return sqrt(1 - x**2) / x

        if arg.func is acos:
            x = arg.args[0]
            return x / sqrt(1 - x**2)
示例#9
0
def test_diophantine():
    assert check_solutions((x - y) * (y - z) * (z - x))
    assert check_solutions((x - y) * (x**2 + y**2 - z**2))
    assert check_solutions((x - 3 * y + 7 * z) * (x**2 + y**2 - z**2))
    assert check_solutions(x**2 - 3 * y**2 - 1)
    assert check_solutions(y**2 + 7 * x * y)
    assert check_solutions(x**2 - 3 * x * y + y**2)
    assert check_solutions(z * (x**2 - y**2 - 15))
    assert check_solutions(x * (2 * y - 2 * z + 5))
    assert check_solutions((x**2 - 3 * y**2 - 1) * (x**2 - y**2 - 15))
    assert check_solutions((x**2 - 3 * y**2 - 1) * (y - 7 * z))
    assert check_solutions((x**2 + y**2 - z**2) * (x - 7 * y - 3 * z + 4 * w))
    # Following test case caused problems in parametric representation
    # But this can be solved by factoring out y.
    # No need to use methods for ternary quadratic equations.
    assert check_solutions(y**2 - 7 * x * y + 4 * y * z)
    assert check_solutions(x**2 - 2 * x + 1)

    assert diophantine(x - y) == diophantine(Eq(x, y))
    # 18196
    eq = x**4 + y**4 - 97
    assert diophantine(eq, permute=True) == diophantine(-eq, permute=True)
    assert diophantine(3 * x * pi - 2 * y * pi) == {(2 * t_0, 3 * t_0)}
    eq = x**2 + y**2 + z**2 - 14
    base_sol = {(1, 2, 3)}
    assert diophantine(eq) == base_sol
    complete_soln = set(signed_permutations(base_sol.pop()))
    assert diophantine(eq, permute=True) == complete_soln

    assert diophantine(x**2 + x * Rational(15, 14) - 3) == set()
    # test issue 11049
    eq = 92 * x**2 - 99 * y**2 - z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == \
           {(9, 7, 51)}
    assert diophantine(eq) == {
        (891 * p**2 + 9 * q**2, -693 * p**2 - 102 * p * q + 7 * q**2,
         5049 * p**2 - 1386 * p * q - 51 * q**2)
    }
    eq = 2 * x**2 + 2 * y**2 - z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == \
           {(1, 1, 2)}
    assert diophantine(eq) == {(2 * p**2 - q**2, -2 * p**2 + 4 * p * q - q**2,
                                4 * p**2 - 4 * p * q + 2 * q**2)}
    eq = 411 * x**2 + 57 * y**2 - 221 * z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == \
           {(2021, 2645, 3066)}
    assert diophantine(eq) == \
           {(115197*p**2 - 446641*q**2, -150765*p**2 + 1355172*p*q -
             584545*q**2, 174762*p**2 - 301530*p*q + 677586*q**2)}
    eq = 573 * x**2 + 267 * y**2 - 984 * z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == \
           {(49, 233, 127)}
    assert diophantine(eq) == \
           {(4361*p**2 - 16072*q**2, -20737*p**2 + 83312*p*q - 76424*q**2,
             11303*p**2 - 41474*p*q + 41656*q**2)}
    # this produces factors during reconstruction
    eq = x**2 + 3 * y**2 - 12 * z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == \
           {(0, 2, 1)}
    assert diophantine(eq) == \
           {(24*p*q, 2*p**2 - 24*q**2, p**2 + 12*q**2)}
    # solvers have not been written for every type
    raises(NotImplementedError, lambda: diophantine(x * y**2 + 1))

    # rational expressions
    assert diophantine(1 / x) == set()
    assert diophantine(1 / x + 1 / y - S.Half) == {(6, 3), (-2, 1), (4, 4),
                                                   (1, -2), (3, 6)}
    assert diophantine(x**2 + y**2 +3*x- 5, permute=True) == \
           {(-1, 1), (-4, -1), (1, -1), (1, 1), (-4, 1), (-1, -1), (4, 1), (4, -1)}

    #test issue 18186
    assert diophantine(y**4 + x**4 - 2**4 - 3**4, syms=(x, y), permute=True) == \
           {(-3, -2), (-3, 2), (-2, -3), (-2, 3), (2, -3), (2, 3), (3, -2), (3, 2)}
    assert diophantine(y**4 + x**4 - 2**4 - 3**4, syms=(y, x), permute=True) == \
           {(-3, -2), (-3, 2), (-2, -3), (-2, 3), (2, -3), (2, 3), (3, -2), (3, 2)}

    # issue 18122
    assert check_solutions(x**2 - y)
    assert check_solutions(y**2 - x)
    assert diophantine((x**2 - y), t) == {(t, t**2)}
    assert diophantine((y**2 - x), t) == {(t**2, -t)}
示例#10
0
def test_issue_15471():
    f = log(x)*cos(log(x))/x**Rational(3, 4)
    F = -128*x**Rational(1, 4)*sin(log(x))/289 + 240*x**Rational(1, 4)*cos(log(x))/289 + (16*x**Rational(1, 4)*sin(log(x))/17 + 4*x**Rational(1, 4)*cos(log(x))/17)*log(x)
    assert_is_integral_of(f, F)
示例#11
0
def test_quadratic_denom():
    f = (5*x + 2)/(3*x**2 - 2*x + 8)
    assert manualintegrate(f, x) == 5*log(3*x**2 - 2*x + 8)/6 + 11*sqrt(23)*atan(3*sqrt(23)*(x - Rational(1, 3))/23)/69
    g = 3/(2*x**2 + 3*x + 1)
    assert manualintegrate(g, x) == 3*log(4*x + 2) - 3*log(4*x + 4)
示例#12
0
def test_find_substitutions():
    assert find_substitutions((cot(x)**2 + 1)**2*csc(x)**2*cot(x)**2, x, u) == \
        [(cot(x), 1, -u**6 - 2*u**4 - u**2)]
    assert find_substitutions((sec(x)**2 + tan(x) * sec(x)) / (sec(x) + tan(x)),
                              x, u) == [(sec(x) + tan(x), 1, 1/u)]
    assert (-x**2, Rational(-1, 2), exp(u)) in find_substitutions(x * exp(-x**2), x, u)
示例#13
0
def test_manualintegrate_inversetrig():
    # atan
    assert manualintegrate(exp(x) / (1 + exp(2*x)), x) == atan(exp(x))
    assert manualintegrate(1 / (4 + 9 * x**2), x) == atan(3 * x/2) / 6
    assert manualintegrate(1 / (16 + 16 * x**2), x) == atan(x) / 16
    assert manualintegrate(1 / (4 + x**2), x) == atan(x / 2) / 2
    assert manualintegrate(1 / (1 + 4 * x**2), x) == atan(2*x) / 2
    ra = Symbol('a', real=True)
    rb = Symbol('b', real=True)
    assert manualintegrate(1/(ra + rb*x**2), x) == \
        Piecewise((atan(x/sqrt(ra/rb))/(rb*sqrt(ra/rb)), ra/rb > 0),
                  (-acoth(x/sqrt(-ra/rb))/(rb*sqrt(-ra/rb)), And(ra/rb < 0, x**2 > -ra/rb)),
                  (-atanh(x/sqrt(-ra/rb))/(rb*sqrt(-ra/rb)), And(ra/rb < 0, x**2 < -ra/rb)))
    assert manualintegrate(1/(4 + rb*x**2), x) == \
        Piecewise((atan(x/(2*sqrt(1/rb)))/(2*rb*sqrt(1/rb)), 4/rb > 0),
                  (-acoth(x/(2*sqrt(-1/rb)))/(2*rb*sqrt(-1/rb)), And(4/rb < 0, x**2 > -4/rb)),
                  (-atanh(x/(2*sqrt(-1/rb)))/(2*rb*sqrt(-1/rb)), And(4/rb < 0, x**2 < -4/rb)))
    assert manualintegrate(1/(ra + 4*x**2), x) == \
        Piecewise((atan(2*x/sqrt(ra))/(2*sqrt(ra)), ra/4 > 0),
                  (-acoth(2*x/sqrt(-ra))/(2*sqrt(-ra)), And(ra/4 < 0, x**2 > -ra/4)),
                  (-atanh(2*x/sqrt(-ra))/(2*sqrt(-ra)), And(ra/4 < 0, x**2 < -ra/4)))
    assert manualintegrate(1/(4 + 4*x**2), x) == atan(x) / 4

    assert manualintegrate(1/(a + b*x**2), x) == atan(x/sqrt(a/b))/(b*sqrt(a/b))

    # asin
    assert manualintegrate(1/sqrt(1-x**2), x) == asin(x)
    assert manualintegrate(1/sqrt(4-4*x**2), x) == asin(x)/2
    assert manualintegrate(3/sqrt(1-9*x**2), x) == asin(3*x)
    assert manualintegrate(1/sqrt(4-9*x**2), x) == asin(x*Rational(3, 2))/3

    # asinh
    assert manualintegrate(1/sqrt(x**2 + 1), x) == \
        asinh(x)
    assert manualintegrate(1/sqrt(x**2 + 4), x) == \
        asinh(x/2)
    assert manualintegrate(1/sqrt(4*x**2 + 4), x) == \
        asinh(x)/2
    assert manualintegrate(1/sqrt(4*x**2 + 1), x) == \
        asinh(2*x)/2
    assert manualintegrate(1/sqrt(a*x**2 + 1), x) == \
        Piecewise((sqrt(-1/a)*asin(x*sqrt(-a)), a < 0), (sqrt(1/a)*asinh(sqrt(a)*x), a > 0))
    assert manualintegrate(1/sqrt(a + x**2), x) == \
        Piecewise((asinh(x*sqrt(1/a)), a > 0), (acosh(x*sqrt(-1/a)), a < 0))

    # acosh
    assert manualintegrate(1/sqrt(x**2 - 1), x) == \
        acosh(x)
    assert manualintegrate(1/sqrt(x**2 - 4), x) == \
        acosh(x/2)
    assert manualintegrate(1/sqrt(4*x**2 - 4), x) == \
        acosh(x)/2
    assert manualintegrate(1/sqrt(9*x**2 - 1), x) == \
        acosh(3*x)/3
    assert manualintegrate(1/sqrt(a*x**2 - 4), x) == \
        Piecewise((sqrt(1/a)*acosh(sqrt(a)*x/2), a > 0))
    assert manualintegrate(1/sqrt(-a + 4*x**2), x) == \
        Piecewise((asinh(2*x*sqrt(-1/a))/2, -a > 0), (acosh(2*x*sqrt(1/a))/2, -a < 0))

    # From https://www.wikiwand.com/en/List_of_integrals_of_inverse_trigonometric_functions
    # asin
    assert manualintegrate(asin(x), x) == x*asin(x) + sqrt(1 - x**2)
    assert manualintegrate(asin(a*x), x) == Piecewise(((a*x*asin(a*x) + sqrt(-a**2*x**2 + 1))/a, Ne(a, 0)), (0, True))
    assert manualintegrate(x*asin(a*x), x) == -a*Integral(x**2/sqrt(-a**2*x**2 + 1), x)/2 + x**2*asin(a*x)/2
    # acos
    assert manualintegrate(acos(x), x) == x*acos(x) - sqrt(1 - x**2)
    assert manualintegrate(acos(a*x), x) == Piecewise(((a*x*acos(a*x) - sqrt(-a**2*x**2 + 1))/a, Ne(a, 0)), (pi*x/2, True))
    assert manualintegrate(x*acos(a*x), x) == a*Integral(x**2/sqrt(-a**2*x**2 + 1), x)/2 + x**2*acos(a*x)/2
    # atan
    assert manualintegrate(atan(x), x) == x*atan(x) - log(x**2 + 1)/2
    assert manualintegrate(atan(a*x), x) == Piecewise(((a*x*atan(a*x) - log(a**2*x**2 + 1)/2)/a, Ne(a, 0)), (0, True))
    assert manualintegrate(x*atan(a*x), x) == -a*(x/a**2 - atan(x/sqrt(a**(-2)))/(a**4*sqrt(a**(-2))))/2 + x**2*atan(a*x)/2
    # acsc
    assert manualintegrate(acsc(x), x) == x*acsc(x) + Integral(1/(x*sqrt(1 - 1/x**2)), x)
    assert manualintegrate(acsc(a*x), x) == x*acsc(a*x) + Integral(1/(x*sqrt(1 - 1/(a**2*x**2))), x)/a
    assert manualintegrate(x*acsc(a*x), x) == x**2*acsc(a*x)/2 + Integral(1/sqrt(1 - 1/(a**2*x**2)), x)/(2*a)
    # asec
    assert manualintegrate(asec(x), x) == x*asec(x) - Integral(1/(x*sqrt(1 - 1/x**2)), x)
    assert manualintegrate(asec(a*x), x) == x*asec(a*x) - Integral(1/(x*sqrt(1 - 1/(a**2*x**2))), x)/a
    assert manualintegrate(x*asec(a*x), x) == x**2*asec(a*x)/2 - Integral(1/sqrt(1 - 1/(a**2*x**2)), x)/(2*a)
    # acot
    assert manualintegrate(acot(x), x) == x*acot(x) + log(x**2 + 1)/2
    assert manualintegrate(acot(a*x), x) == Piecewise(((a*x*acot(a*x) + log(a**2*x**2 + 1)/2)/a, Ne(a, 0)), (pi*x/2, True))
    assert manualintegrate(x*acot(a*x), x) == a*(x/a**2 - atan(x/sqrt(a**(-2)))/(a**4*sqrt(a**(-2))))/2 + x**2*acot(a*x)/2

    # piecewise
    assert manualintegrate(1/sqrt(a-b*x**2), x) == \
        Piecewise((sqrt(a/b)*asin(x*sqrt(b/a))/sqrt(a), And(-b < 0, a > 0)),
                  (sqrt(-a/b)*asinh(x*sqrt(-b/a))/sqrt(a), And(-b > 0, a > 0)),
                  (sqrt(a/b)*acosh(x*sqrt(b/a))/sqrt(-a), And(-b > 0, a < 0)))
    assert manualintegrate(1/sqrt(a + b*x**2), x) == \
        Piecewise((sqrt(-a/b)*asin(x*sqrt(-b/a))/sqrt(a), And(a > 0, b < 0)),
                  (sqrt(a/b)*asinh(x*sqrt(b/a))/sqrt(a), And(a > 0, b > 0)),
                  (sqrt(-a/b)*acosh(x*sqrt(-b/a))/sqrt(-a), And(a < 0, b > 0)))
示例#14
0
    def eval(cls, arg, base=None):
        from sympy import unpolarify
        from sympy.calculus import AccumBounds
        from sympy.sets.setexpr import SetExpr
        from sympy.functions.elementary.complexes import Abs

        arg = sympify(arg)

        if base is not None:
            base = sympify(base)
            if base == 1:
                if arg == 1:
                    return S.NaN
                else:
                    return S.ComplexInfinity
            try:
                # handle extraction of powers of the base now
                # or else expand_log in Mul would have to handle this
                n = multiplicity(base, arg)
                if n:
                    return n + log(arg / base**n) / log(base)
                else:
                    return log(arg) / log(base)
            except ValueError:
                pass
            if base is not S.Exp1:
                return cls(arg) / cls(base)
            else:
                return cls(arg)

        if arg.is_Number:
            if arg.is_zero:
                return S.ComplexInfinity
            elif arg is S.One:
                return S.Zero
            elif arg is S.Infinity:
                return S.Infinity
            elif arg is S.NegativeInfinity:
                return S.Infinity
            elif arg is S.NaN:
                return S.NaN
            elif arg.is_Rational and arg.p == 1:
                return -cls(arg.q)

        I = S.ImaginaryUnit
        if isinstance(arg, exp) and arg.args[0].is_extended_real:
            return arg.args[0]
        elif isinstance(arg, exp) and arg.args[0].is_number:
            r_, i_ = match_real_imag(arg.args[0])
            if i_ and i_.is_comparable:
                i_ %= 2 * S.Pi
                if i_ > S.Pi:
                    i_ -= 2 * S.Pi
                return r_ + expand_mul(i_ * I, deep=False)
        elif isinstance(arg, exp_polar):
            return unpolarify(arg.exp)
        elif isinstance(arg, AccumBounds):
            if arg.min.is_positive:
                return AccumBounds(log(arg.min), log(arg.max))
            else:
                return
        elif isinstance(arg, SetExpr):
            return arg._eval_func(cls)

        if arg.is_number:
            if arg.is_negative:
                return S.Pi * I + cls(-arg)
            elif arg is S.ComplexInfinity:
                return S.ComplexInfinity
            elif arg is S.Exp1:
                return S.One

        if arg.is_zero:
            return S.ComplexInfinity

        # don't autoexpand Pow or Mul (see the issue 3351):
        if not arg.is_Add:
            coeff = arg.as_coefficient(I)

            if coeff is not None:
                if coeff is S.Infinity:
                    return S.Infinity
                elif coeff is S.NegativeInfinity:
                    return S.Infinity
                elif coeff.is_Rational:
                    if coeff.is_nonnegative:
                        return S.Pi * I * S.Half + cls(coeff)
                    else:
                        return -S.Pi * I * S.Half + cls(-coeff)

        if arg.is_number and arg.is_algebraic:
            # Match arg = coeff*(r_ + i_*I) with coeff>0, r_ and i_ real.
            coeff, arg_ = arg.as_independent(I, as_Add=False)
            if coeff.is_negative:
                coeff *= -1
                arg_ *= -1
            arg_ = expand_mul(arg_, deep=False)
            r_, i_ = arg_.as_independent(I, as_Add=True)
            i_ = i_.as_coefficient(I)
            if coeff.is_real and i_ and i_.is_real and r_.is_real:
                if r_.is_zero:
                    if i_.is_positive:
                        return S.Pi * I * S.Half + cls(coeff * i_)
                    elif i_.is_negative:
                        return -S.Pi * I * S.Half + cls(coeff * -i_)
                else:
                    from sympy.simplify import ratsimp
                    # Check for arguments involving rational multiples of pi
                    t = (i_ / r_).cancel()
                    t1 = (-t).cancel()
                    atan_table = {
                        # first quadrant only
                        sqrt(3):
                        S.Pi / 3,
                        1:
                        S.Pi / 4,
                        sqrt(5 - 2 * sqrt(5)):
                        S.Pi / 5,
                        sqrt(2) * sqrt(5 - sqrt(5)) / (1 + sqrt(5)):
                        S.Pi / 5,
                        sqrt(5 + 2 * sqrt(5)):
                        S.Pi * Rational(2, 5),
                        sqrt(2) * sqrt(sqrt(5) + 5) / (-1 + sqrt(5)):
                        S.Pi * Rational(2, 5),
                        sqrt(3) / 3:
                        S.Pi / 6,
                        sqrt(2) - 1:
                        S.Pi / 8,
                        sqrt(2 - sqrt(2)) / sqrt(sqrt(2) + 2):
                        S.Pi / 8,
                        sqrt(2) + 1:
                        S.Pi * Rational(3, 8),
                        sqrt(sqrt(2) + 2) / sqrt(2 - sqrt(2)):
                        S.Pi * Rational(3, 8),
                        sqrt(1 - 2 * sqrt(5) / 5):
                        S.Pi / 10,
                        (-sqrt(2) + sqrt(10)) / (2 * sqrt(sqrt(5) + 5)):
                        S.Pi / 10,
                        sqrt(1 + 2 * sqrt(5) / 5):
                        S.Pi * Rational(3, 10),
                        (sqrt(2) + sqrt(10)) / (2 * sqrt(5 - sqrt(5))):
                        S.Pi * Rational(3, 10),
                        2 - sqrt(3):
                        S.Pi / 12,
                        (-1 + sqrt(3)) / (1 + sqrt(3)):
                        S.Pi / 12,
                        2 + sqrt(3):
                        S.Pi * Rational(5, 12),
                        (1 + sqrt(3)) / (-1 + sqrt(3)):
                        S.Pi * Rational(5, 12)
                    }
                    if t in atan_table:
                        modulus = ratsimp(coeff * Abs(arg_))
                        if r_.is_positive:
                            return cls(modulus) + I * atan_table[t]
                        else:
                            return cls(modulus) + I * (atan_table[t] - S.Pi)
                    elif t1 in atan_table:
                        modulus = ratsimp(coeff * Abs(arg_))
                        if r_.is_positive:
                            return cls(modulus) + I * (-atan_table[t1])
                        else:
                            return cls(modulus) + I * (S.Pi - atan_table[t1])
示例#15
0
def test_subs_noncommutative():
    w, x, y, z, L = symbols('w x y z L', commutative=False)
    alpha = symbols('alpha', commutative=True)
    someint = symbols('someint', commutative=True, integer=True)

    assert (x * y).subs(x * y, L) == L
    assert (w * y * x).subs(x * y, L) == w * y * x
    assert (w * x * y * z).subs(x * y, L) == w * L * z
    assert (x * y * x * y).subs(x * y, L) == L**2
    assert (x * x * y).subs(x * y, L) == x * L
    assert (x * x * y * y).subs(x * y, L) == x * L * y
    assert (w * x * y).subs(x * y * z, L) == w * x * y
    assert (x * y**z).subs(x, L) == L * y**z
    assert (x * y**z).subs(y, L) == x * L**z
    assert (x * y**z).subs(z, L) == x * y**L
    assert (w * x * y * z * x * y).subs(x * y * z, L) == w * L * x * y
    assert (w * x * y * y * w * x * x * y * x * y * y * x * y).subs(
        x * y, L) == w * L * y * w * x * L**2 * y * L

    # Check fractional power substitutions. It should not do
    # substitutions that choose a value for noncommutative log,
    # or inverses that don't already appear in the expressions.
    assert (x * x * x).subs(x * x, L) == L * x
    assert (x * x * x * y * x * x * x * x).subs(x * x, L) == L * x * y * L**2
    for p in range(1, 5):
        for k in range(10):
            assert (y * x**k).subs(x**p, L) == y * L**(k // p) * x**(k % p)
    assert (x**Rational(3, 2)).subs(x**S.Half, L) == x**Rational(3, 2)
    assert (x**S.Half).subs(x**S.Half, L) == L
    assert (x**Rational(-1, 2)).subs(x**S.Half, L) == x**Rational(-1, 2)
    assert (x**Rational(-1, 2)).subs(x**Rational(-1, 2), L) == L

    assert (x**(2 * someint)).subs(x**someint, L) == L**2
    assert (x**(2 * someint + 3)).subs(x**someint, L) == L**2 * x**3
    assert (x**(3 * someint + 3)).subs(x**someint, L) == L**3 * x**3
    assert (x**(3 * someint)).subs(x**(2 * someint), L) == L * x**someint
    assert (x**(4 * someint)).subs(x**(2 * someint), L) == L**2
    assert (x**(4 * someint + 1)).subs(x**(2 * someint), L) == L**2 * x
    assert (x**(4 * someint)).subs(x**(3 * someint), L) == L * x**someint
    assert (x**(4 * someint + 1)).subs(x**(3 * someint),
                                       L) == L * x**(someint + 1)

    assert (x**(2 * alpha)).subs(x**alpha, L) == x**(2 * alpha)
    assert (x**(2 * alpha + 2)).subs(x**2, L) == x**(2 * alpha + 2)
    assert ((2 * z)**alpha).subs(z**alpha, y) == (2 * z)**alpha
    assert (x**(2 * someint * alpha)).subs(x**someint,
                                           L) == x**(2 * someint * alpha)
    assert (x**(2 * someint + alpha)).subs(x**someint,
                                           L) == x**(2 * someint + alpha)

    # This could in principle be substituted, but is not currently
    # because it requires recognizing that someint**2 is divisible by
    # someint.
    assert (x**(someint**2 + 3)).subs(x**someint, L) == x**(someint**2 + 3)

    # alpha**z := exp(log(alpha) z) is usually well-defined
    assert (4**z).subs(2**z, y) == y**2

    # Negative powers
    assert (x**(-1)).subs(x**3, L) == x**(-1)
    assert (x**(-2)).subs(x**3, L) == x**(-2)
    assert (x**(-3)).subs(x**3, L) == L**(-1)
    assert (x**(-4)).subs(x**3, L) == L**(-1) * x**(-1)
    assert (x**(-5)).subs(x**3, L) == L**(-1) * x**(-2)

    assert (x**(-1)).subs(x**(-3), L) == x**(-1)
    assert (x**(-2)).subs(x**(-3), L) == x**(-2)
    assert (x**(-3)).subs(x**(-3), L) == L
    assert (x**(-4)).subs(x**(-3), L) == L * x**(-1)
    assert (x**(-5)).subs(x**(-3), L) == L * x**(-2)

    assert (x**1).subs(x**(-3), L) == x
    assert (x**2).subs(x**(-3), L) == x**2
    assert (x**3).subs(x**(-3), L) == L**(-1)
    assert (x**4).subs(x**(-3), L) == L**(-1) * x
    assert (x**5).subs(x**(-3), L) == L**(-1) * x**2
示例#16
0
def test_solve_ics():
    # Basic tests that things work from dsolve.
    assert dsolve(f(x).diff(x) - 1/f(x), f(x), ics={f(1): 2}) == \
        Eq(f(x), sqrt(2 * x + 2))
    assert dsolve(f(x).diff(x) - f(x), f(x), ics={f(0): 1}) == Eq(f(x), exp(x))
    assert dsolve(f(x).diff(x) - f(x), f(x), ics={f(x).diff(x).subs(x, 0): 1}) == Eq(f(x), exp(x))
    assert dsolve(f(x).diff(x, x) + f(x), f(x), ics={f(0): 1,
        f(x).diff(x).subs(x, 0): 1}) == Eq(f(x), sin(x) + cos(x))
    assert dsolve([f(x).diff(x) - f(x) + g(x), g(x).diff(x) - g(x) - f(x)],
        [f(x), g(x)], ics={f(0): 1, g(0): 0}) == [Eq(f(x), exp(x)*cos(x)), Eq(g(x), exp(x)*sin(x))]

    # Test cases where dsolve returns two solutions.
    eq = (x**2*f(x)**2 - x).diff(x)
    assert dsolve(eq, f(x), ics={f(1): 0}) == [Eq(f(x),
        -sqrt(x - 1)/x), Eq(f(x), sqrt(x - 1)/x)]
    assert dsolve(eq, f(x), ics={f(x).diff(x).subs(x, 1): 0}) == [Eq(f(x),
        -sqrt(x - S.Half)/x), Eq(f(x), sqrt(x - S.Half)/x)]

    eq = cos(f(x)) - (x*sin(f(x)) - f(x)**2)*f(x).diff(x)
    assert dsolve(eq, f(x),
        ics={f(0):1}, hint='1st_exact', simplify=False) == Eq(x*cos(f(x)) + f(x)**3/3, Rational(1, 3))
    assert dsolve(eq, f(x),
        ics={f(0):1}, hint='1st_exact', simplify=True) == Eq(x*cos(f(x)) + f(x)**3/3, Rational(1, 3))

    assert solve_ics([Eq(f(x), C1*exp(x))], [f(x)], [C1], {f(0): 1}) == {C1: 1}
    assert solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2],
        {f(0): 1, f(pi/2): 1}) == {C1: 1, C2: 1}

    assert solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2],
        {f(0): 1, f(x).diff(x).subs(x, 0): 1}) == {C1: 1, C2: 1}

    assert solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2], {f(0): 1}) == \
        {C2: 1}

    # Some more complicated tests Refer to PR #16098

    assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(0):0, f(x).diff(x).subs(x, 1):0})) == \
        {Eq(f(x), 0), Eq(f(x), x ** 3 / 6 - x / 2)}
    assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(0):0})) == \
        {Eq(f(x), 0), Eq(f(x), C2*x + x**3/6)}

    K, r, f0 = symbols('K r f0')
    sol = Eq(f(x), K*f0*exp(r*x)/((-K + f0)*(f0*exp(r*x)/(-K + f0) - 1)))
    assert (dsolve(Eq(f(x).diff(x), r * f(x) * (1 - f(x) / K)), f(x), ics={f(0): f0})) == sol


    #Order dependent issues Refer to PR #16098
    assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(x).diff(x).subs(x,0):0, f(0):0})) == \
        {Eq(f(x), 0), Eq(f(x), x ** 3 / 6)}
    assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(0):0, f(x).diff(x).subs(x,0):0})) == \
        {Eq(f(x), 0), Eq(f(x), x ** 3 / 6)}

    # XXX: Ought to be ValueError
    raises(ValueError, lambda: solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2], {f(0): 1, f(pi): 1}))

    # Degenerate case. f'(0) is identically 0.
    raises(ValueError, lambda: solve_ics([Eq(f(x), sqrt(C1 - x**2))], [f(x)], [C1], {f(x).diff(x).subs(x, 0): 0}))

    EI, q, L = symbols('EI q L')

    # eq = Eq(EI*diff(f(x), x, 4), q)
    sols = [Eq(f(x), C1 + C2*x + C3*x**2 + C4*x**3 + q*x**4/(24*EI))]
    funcs = [f(x)]
    constants = [C1, C2, C3, C4]
    # Test both cases, Derivative (the default from f(x).diff(x).subs(x, L)),
    # and Subs
    ics1 = {f(0): 0,
        f(x).diff(x).subs(x, 0): 0,
        f(L).diff(L, 2): 0,
        f(L).diff(L, 3): 0}
    ics2 = {f(0): 0,
        f(x).diff(x).subs(x, 0): 0,
        Subs(f(x).diff(x, 2), x, L): 0,
        Subs(f(x).diff(x, 3), x, L): 0}

    solved_constants1 = solve_ics(sols, funcs, constants, ics1)
    solved_constants2 = solve_ics(sols, funcs, constants, ics2)
    assert solved_constants1 == solved_constants2 == {
        C1: 0,
        C2: 0,
        C3: L**2*q/(4*EI),
        C4: -L*q/(6*EI)}
示例#17
0
def ratsimpmodprime(expr, G, *gens, **args):
    """
    Simplifies a rational expression ``expr`` modulo the prime ideal
    generated by ``G``.  ``G`` should be a Groebner basis of the
    ideal.

    >>> from sympy.simplify.ratsimp import ratsimpmodprime
    >>> from sympy.abc import x, y
    >>> eq = (x + y**5 + y)/(x - y)
    >>> ratsimpmodprime(eq, [x*y**5 - x - y], x, y, order='lex')
    (-x**2 - x*y - x - y)/(-x**2 + x*y)

    If ``polynomial`` is False, the algorithm computes a rational
    simplification which minimizes the sum of the total degrees of
    the numerator and the denominator.

    If ``polynomial`` is True, this function just brings numerator and
    denominator into a canonical form. This is much faster, but has
    potentially worse results.

    References
    ==========

    .. [1] M. Monagan, R. Pearce, Rational Simplification Modulo a Polynomial
    Ideal,
    http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.163.6984
    (specifically, the second algorithm)
    """
    from sympy import solve

    quick = args.pop('quick', True)
    polynomial = args.pop('polynomial', False)
    debug('ratsimpmodprime', expr)

    # usual preparation of polynomials:

    num, denom = cancel(expr).as_numer_denom()

    try:
        polys, opt = parallel_poly_from_expr([num, denom] + G, *gens, **args)
    except PolificationFailed:
        return expr

    domain = opt.domain

    if domain.has_assoc_Field:
        opt.domain = domain.get_field()
    else:
        raise DomainError("can't compute rational simplification over %s" %
                          domain)

    # compute only once
    leading_monomials = [g.LM(opt.order) for g in polys[2:]]
    tested = set()

    def staircase(n):
        """
        Compute all monomials with degree less than ``n`` that are
        not divisible by any element of ``leading_monomials``.
        """
        if n == 0:
            return [1]
        S = []
        for mi in combinations_with_replacement(range(len(opt.gens)), n):
            m = [0] * len(opt.gens)
            for i in mi:
                m[i] += 1
            if all([monomial_div(m, lmg) is None
                    for lmg in leading_monomials]):
                S.append(m)

        return [Monomial(s).as_expr(*opt.gens) for s in S] + staircase(n - 1)

    def _ratsimpmodprime(a, b, allsol, N=0, D=0):
        r"""
        Computes a rational simplification of ``a/b`` which minimizes
        the sum of the total degrees of the numerator and the denominator.

        The algorithm proceeds by looking at ``a * d - b * c`` modulo
        the ideal generated by ``G`` for some ``c`` and ``d`` with degree
        less than ``a`` and ``b`` respectively.
        The coefficients of ``c`` and ``d`` are indeterminates and thus
        the coefficients of the normalform of ``a * d - b * c`` are
        linear polynomials in these indeterminates.
        If these linear polynomials, considered as system of
        equations, have a nontrivial solution, then `\frac{a}{b}
        \equiv \frac{c}{d}` modulo the ideal generated by ``G``. So,
        by construction, the degree of ``c`` and ``d`` is less than
        the degree of ``a`` and ``b``, so a simpler representation
        has been found.
        After a simpler representation has been found, the algorithm
        tries to reduce the degree of the numerator and denominator
        and returns the result afterwards.

        As an extension, if quick=False, we look at all possible degrees such
        that the total degree is less than *or equal to* the best current
        solution. We retain a list of all solutions of minimal degree, and try
        to find the best one at the end.
        """
        c, d = a, b
        steps = 0

        maxdeg = a.total_degree() + b.total_degree()
        if quick:
            bound = maxdeg - 1
        else:
            bound = maxdeg
        while N + D <= bound:
            if (N, D) in tested:
                break
            tested.add((N, D))

            M1 = staircase(N)
            M2 = staircase(D)
            debug('%s / %s: %s, %s' % (N, D, M1, M2))

            Cs = symbols("c:%d" % len(M1), cls=Dummy)
            Ds = symbols("d:%d" % len(M2), cls=Dummy)
            ng = Cs + Ds

            c_hat = Poly(sum([Cs[i] * M1[i] for i in range(len(M1))]),
                         opt.gens + ng)
            d_hat = Poly(sum([Ds[i] * M2[i] for i in range(len(M2))]),
                         opt.gens + ng)

            r = reduced(a * d_hat - b * c_hat,
                        G,
                        opt.gens + ng,
                        order=opt.order,
                        polys=True)[1]

            S = Poly(r, gens=opt.gens).coeffs()
            sol = solve(S, Cs + Ds, particular=True, quick=True)

            if sol and not all([s == 0 for s in sol.values()]):
                c = c_hat.subs(sol)
                d = d_hat.subs(sol)

                # The "free" variables occurring before as parameters
                # might still be in the substituted c, d, so set them
                # to the value chosen before:
                c = c.subs(dict(list(zip(Cs + Ds, [1] * (len(Cs) + len(Ds))))))
                d = d.subs(dict(list(zip(Cs + Ds, [1] * (len(Cs) + len(Ds))))))

                c = Poly(c, opt.gens)
                d = Poly(d, opt.gens)
                if d == 0:
                    raise ValueError('Ideal not prime?')

                allsol.append((c_hat, d_hat, S, Cs + Ds))
                if N + D != maxdeg:
                    allsol = [allsol[-1]]

                break

            steps += 1
            N += 1
            D += 1

        if steps > 0:
            c, d, allsol = _ratsimpmodprime(c, d, allsol, N, D - steps)
            c, d, allsol = _ratsimpmodprime(c, d, allsol, N - steps, D)

        return c, d, allsol

    # preprocessing. this improves performance a bit when deg(num)
    # and deg(denom) are large:
    num = reduced(num, G, opt.gens, order=opt.order)[1]
    denom = reduced(denom, G, opt.gens, order=opt.order)[1]

    if polynomial:
        return (num / denom).cancel()

    c, d, allsol = _ratsimpmodprime(Poly(num, opt.gens, domain=opt.domain),
                                    Poly(denom, opt.gens, domain=opt.domain),
                                    [])
    if not quick and allsol:
        debug('Looking for best minimal solution. Got: %s' % len(allsol))
        newsol = []
        for c_hat, d_hat, S, ng in allsol:
            sol = solve(S, ng, particular=True, quick=False)
            newsol.append((c_hat.subs(sol), d_hat.subs(sol)))
        c, d = min(newsol, key=lambda x: len(x[0].terms()) + len(x[1].terms()))

    if not domain.is_Field:
        cn, c = c.clear_denoms(convert=True)
        dn, d = d.clear_denoms(convert=True)
        r = Rational(cn, dn)
    else:
        r = Rational(1)

    return (c * r.q) / (d * r.p)
def test_clebsch_gordan5():
    j_1 = Rational(5, 2)
    j_2 = S.One
    m = Rational(7, 2)
    j = Rational(7, 2)
    m_1 = Rational(5, 2)
    m_2 = 1
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1

    j_1 = Rational(5, 2)
    j_2 = S.One
    m = Rational(5, 2)
    j = Rational(5, 2)
    m_1 = Rational(5, 2)
    m_2 = 0
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == sqrt(5) / sqrt(7)

    j_1 = Rational(5, 2)
    j_2 = S.One
    m = Rational(3, 2)
    j = Rational(3, 2)
    m_1 = S.Half
    m_2 = 1
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1 / sqrt(15)
示例#19
0
def test_Normal():
    m = Normal('A', [1, 2], [[1, 0], [0, 1]])
    A = MultivariateNormal('A', [1, 2], [[1, 0], [0, 1]])
    assert m == A
    assert density(m)(1, 2) == 1 / (2 * pi)
    assert m.pspace.distribution.set == ProductSet(S.Reals, S.Reals)
    raises(ValueError, lambda: m[2])
    n = Normal('B', [1, 2, 3], [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    p = Normal('C', Matrix([1, 2]), Matrix([[1, 0], [0, 1]]))
    assert density(m)(x, y) == density(p)(x, y)
    assert marginal_distribution(n, 0, 1)(1, 2) == 1 / (2 * pi)
    raises(ValueError, lambda: marginal_distribution(m))
    assert integrate(density(m)(x, y), (x, -oo, oo), (y, -oo, oo)).evalf() == 1
    N = Normal('N', [1, 2], [[x, 0], [0, y]])
    assert density(N)(0, 0) == exp(-((4 * x + y) /
                                     (2 * x * y))) / (2 * pi * sqrt(x * y))

    raises(ValueError, lambda: Normal('M', [1, 2], [[1, 1], [1, -1]]))
    # symbolic
    n = symbols('n', integer=True, positive=True)
    mu = MatrixSymbol('mu', n, 1)
    sigma = MatrixSymbol('sigma', n, n)
    X = Normal('X', mu, sigma)
    assert density(X) == MultivariateNormalDistribution(mu, sigma)
    raises(NotImplementedError, lambda: median(m))
    # Below tests should work after issue #17267 is resolved
    # assert E(X) == mu
    # assert variance(X) == sigma

    # test symbolic multivariate normal densities
    n = 3

    Sg = MatrixSymbol('Sg', n, n)
    mu = MatrixSymbol('mu', n, 1)
    obs = MatrixSymbol('obs', n, 1)

    X = MultivariateNormal('X', mu, Sg)
    density_X = density(X)

    eval_a = density_X(obs).subs({
        Sg: eye(3),
        mu: Matrix([0, 0, 0]),
        obs: Matrix([0, 0, 0])
    }).doit()
    eval_b = density_X(0, 0, 0).subs({
        Sg: eye(3),
        mu: Matrix([0, 0, 0])
    }).doit()

    assert eval_a == sqrt(2) / (4 * pi**Rational(3 / 2))
    assert eval_b == sqrt(2) / (4 * pi**Rational(3 / 2))

    n = symbols('n', integer=True, positive=True)

    Sg = MatrixSymbol('Sg', n, n)
    mu = MatrixSymbol('mu', n, 1)
    obs = MatrixSymbol('obs', n, 1)

    X = MultivariateNormal('X', mu, Sg)
    density_X_at_obs = density(X)(obs)

    expected_density = MatrixElement(
        exp((S(1)/2) * (mu.T - obs.T) * Sg**(-1) * (-mu + obs)) / \
        sqrt((2*pi)**n * Determinant(Sg)), 0, 0)

    assert density_X_at_obs == expected_density
def test_clebsch_gordan2():
    j_1 = S.One
    j_2 = S.Half
    m = Rational(3, 2)
    j = Rational(3, 2)
    m_1 = 1
    m_2 = S.Half
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1

    j_1 = S.One
    j_2 = S.Half
    m = S.Half
    j = Rational(3, 2)
    m_1 = 1
    m_2 = Rational(-1, 2)
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1 / sqrt(3)

    j_1 = S.One
    j_2 = S.Half
    m = S.Half
    j = S.Half
    m_1 = 1
    m_2 = Rational(-1, 2)
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == sqrt(2) / sqrt(3)

    j_1 = S.One
    j_2 = S.Half
    m = S.Half
    j = S.Half
    m_1 = 0
    m_2 = S.Half
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == -1 / sqrt(3)

    j_1 = S.One
    j_2 = S.Half
    m = S.Half
    j = Rational(3, 2)
    m_1 = 0
    m_2 = S.Half
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == sqrt(2) / sqrt(3)

    j_1 = S.One
    j_2 = S.One
    m = S(2)
    j = S(2)
    m_1 = 1
    m_2 = 1
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1

    j_1 = S.One
    j_2 = S.One
    m = 1
    j = S(2)
    m_1 = 1
    m_2 = 0
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1 / sqrt(2)

    j_1 = S.One
    j_2 = S.One
    m = 1
    j = S(2)
    m_1 = 0
    m_2 = 1
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1 / sqrt(2)

    j_1 = S.One
    j_2 = S.One
    m = 1
    j = 1
    m_1 = 1
    m_2 = 0
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1 / sqrt(2)

    j_1 = S.One
    j_2 = S.One
    m = 1
    j = 1
    m_1 = 0
    m_2 = 1
    assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == -1 / sqrt(2)
示例#21
0
def test_eval_approx_relative():
    CRootOf.clear_cache()
    t = [CRootOf(x**3 + 10 * x + 1, i) for i in range(3)]
    assert [i.eval_rational(1e-1) for i in t] == [
        Rational(-21, 220),
        Rational(15, 256) - I * 805 / 256,
        Rational(15, 256) + I * 805 / 256
    ]
    t[0]._reset()
    assert [i.eval_rational(1e-1, 1e-4) for i in t] == [
        Rational(-21, 220),
        Rational(3275, 65536) - I * 414645 / 131072,
        Rational(3275, 65536) + I * 414645 / 131072
    ]
    assert S(t[0]._get_interval().dx) < 1e-1
    assert S(t[1]._get_interval().dx) < 1e-1
    assert S(t[1]._get_interval().dy) < 1e-4
    assert S(t[2]._get_interval().dx) < 1e-1
    assert S(t[2]._get_interval().dy) < 1e-4
    t[0]._reset()
    assert [i.eval_rational(1e-4, 1e-4) for i in t] == [
        Rational(-2001, 20020),
        Rational(6545, 131072) - I * 414645 / 131072,
        Rational(6545, 131072) + I * 414645 / 131072
    ]
    assert S(t[0]._get_interval().dx) < 1e-4
    assert S(t[1]._get_interval().dx) < 1e-4
    assert S(t[1]._get_interval().dy) < 1e-4
    assert S(t[2]._get_interval().dx) < 1e-4
    assert S(t[2]._get_interval().dy) < 1e-4
    # in the following, the actual relative precision is
    # less than tested, but it should never be greater
    t[0]._reset()
    assert [i.eval_rational(n=2) for i in t] == [
        Rational(-202201, 2024022),
        Rational(104755, 2097152) - I * 6634255 / 2097152,
        Rational(104755, 2097152) + I * 6634255 / 2097152
    ]
    assert abs(S(t[0]._get_interval().dx) / t[0]) < 1e-2
    assert abs(S(t[1]._get_interval().dx) / t[1]).n() < 1e-2
    assert abs(S(t[1]._get_interval().dy) / t[1]).n() < 1e-2
    assert abs(S(t[2]._get_interval().dx) / t[2]).n() < 1e-2
    assert abs(S(t[2]._get_interval().dy) / t[2]).n() < 1e-2
    t[0]._reset()
    assert [i.eval_rational(n=3) for i in t] == [
        Rational(-202201, 2024022),
        Rational(1676045, 33554432) - I * 106148135 / 33554432,
        Rational(1676045, 33554432) + I * 106148135 / 33554432
    ]
    assert abs(S(t[0]._get_interval().dx) / t[0]) < 1e-3
    assert abs(S(t[1]._get_interval().dx) / t[1]).n() < 1e-3
    assert abs(S(t[1]._get_interval().dy) / t[1]).n() < 1e-3
    assert abs(S(t[2]._get_interval().dx) / t[2]).n() < 1e-3
    assert abs(S(t[2]._get_interval().dy) / t[2]).n() < 1e-3

    t[0]._reset()
    a = [i.eval_approx(2) for i in t]
    assert [str(i) for i in a] == ['-0.10', '0.05 - 3.2*I', '0.05 + 3.2*I']
    assert all(abs(((a[i] - t[i]) / t[i]).n()) < 1e-2 for i in range(len(a)))
示例#22
0
def test_core_numbers():
    for c in (Integer(2), Rational(2, 3), Float("1.2")):
        check(c)
示例#23
0
文件: add.py 项目: msgoff/sympy
    def as_content_primitive(self, radical=False, clear=True):
        """Return the tuple (R, self/R) where R is the positive Rational
        extracted from self. If radical is True (default is False) then
        common radicals will be removed and included as a factor of the
        primitive expression.

        Examples
        ========

        >>> from sympy import sqrt
        >>> (3 + 3*sqrt(2)).as_content_primitive()
        (3, 1 + sqrt(2))

        Radical content can also be factored out of the primitive:

        >>> (2*sqrt(2) + 4*sqrt(10)).as_content_primitive(radical=True)
        (2, sqrt(2)*(1 + 2*sqrt(5)))

        See docstring of Expr.as_content_primitive for more examples.
        """
        con, prim = self.func(*[
            _keep_coeff(*a.as_content_primitive(radical=radical, clear=clear))
            for a in self.args
        ]).primitive()
        if not clear and not con.is_Integer and prim.is_Add:
            con, d = con.as_numer_denom()
            _p = prim / d
            if any(a.as_coeff_Mul()[0].is_Integer for a in _p.args):
                prim = _p
            else:
                con /= d
        if radical and prim.is_Add:
            # look for common radicals that can be removed
            args = prim.args
            rads = []
            common_q = None
            for m in args:
                term_rads = defaultdict(list)
                for ai in Mul.make_args(m):
                    if ai.is_Pow:
                        b, e = ai.as_base_exp()
                        if e.is_Rational and b.is_Integer:
                            term_rads[e.q].append(abs(int(b))**e.p)
                if not term_rads:
                    break
                if common_q is None:
                    common_q = set(term_rads.keys())
                else:
                    common_q = common_q & set(term_rads.keys())
                    if not common_q:
                        break
                rads.append(term_rads)
            else:
                # process rads
                # keep only those in common_q
                for r in rads:
                    for q in list(r.keys()):
                        if q not in common_q:
                            r.pop(q)
                    for q in r:
                        r[q] = prod(r[q])
                # find the gcd of bases for each q
                G = []
                for q in common_q:
                    g = reduce(igcd, [r[q] for r in rads], 0)
                    if g != 1:
                        G.append(g**Rational(1, q))
                if G:
                    G = Mul(*G)
                    args = [ai / G for ai in args]
                    prim = G * prim.func(*args)

        return con, prim
示例#24
0
def test_point():
    x = Symbol('x', real=True)
    y = Symbol('y', real=True)
    x1 = Symbol('x1', real=True)
    x2 = Symbol('x2', real=True)
    y1 = Symbol('y1', real=True)
    y2 = Symbol('y2', real=True)
    half = S.Half
    p1 = Point(x1, x2)
    p2 = Point(y1, y2)
    p3 = Point(0, 0)
    p4 = Point(1, 1)
    p5 = Point(0, 1)
    line = Line(Point(1, 0), slope=1)

    assert p1 in p1
    assert p1 not in p2
    assert p2.y == y2
    assert (p3 + p4) == p4
    assert (p2 - p1) == Point(y1 - x1, y2 - x2)
    assert -p2 == Point(-y1, -y2)
    raises(TypeError, lambda: Point(1))
    raises(ValueError, lambda: Point([1]))
    raises(ValueError, lambda: Point(3, I))
    raises(ValueError, lambda: Point(2 * I, I))
    raises(ValueError, lambda: Point(3 + I, I))

    assert Point(34.05, sqrt(3)) == Point(Rational(681, 20), sqrt(3))
    assert Point.midpoint(p3, p4) == Point(half, half)
    assert Point.midpoint(p1, p4) == Point(half + half * x1, half + half * x2)
    assert Point.midpoint(p2, p2) == p2
    assert p2.midpoint(p2) == p2
    assert p1.origin == Point(0, 0)

    assert Point.distance(p3, p4) == sqrt(2)
    assert Point.distance(p1, p1) == 0
    assert Point.distance(p3, p2) == sqrt(p2.x**2 + p2.y**2)
    raises(TypeError, lambda: Point.distance(p1, 0))
    raises(TypeError, lambda: Point.distance(p1, GeometryEntity()))

    # distance should be symmetric
    assert p1.distance(line) == line.distance(p1)
    assert p4.distance(line) == line.distance(p4)

    assert Point.taxicab_distance(p4, p3) == 2

    assert Point.canberra_distance(p4, p5) == 1
    raises(ValueError, lambda: Point.canberra_distance(p3, p3))

    p1_1 = Point(x1, x1)
    p1_2 = Point(y2, y2)
    p1_3 = Point(x1 + 1, x1)
    assert Point.is_collinear(p3)

    with warns(UserWarning):
        assert Point.is_collinear(p3, Point(p3, dim=4))
    assert p3.is_collinear()
    assert Point.is_collinear(p3, p4)
    assert Point.is_collinear(p3, p4, p1_1, p1_2)
    assert Point.is_collinear(p3, p4, p1_1, p1_3) is False
    assert Point.is_collinear(p3, p3, p4, p5) is False

    raises(TypeError, lambda: Point.is_collinear(line))
    raises(TypeError, lambda: p1_1.is_collinear(line))

    assert p3.intersection(Point(0, 0)) == [p3]
    assert p3.intersection(p4) == []
    assert p3.intersection(line) == []
    assert Point.intersection(Point(0, 0, 0), Point(0, 0)) == [Point(0, 0, 0)]

    x_pos = Symbol('x', positive=True)
    p2_1 = Point(x_pos, 0)
    p2_2 = Point(0, x_pos)
    p2_3 = Point(-x_pos, 0)
    p2_4 = Point(0, -x_pos)
    p2_5 = Point(x_pos, 5)
    assert Point.is_concyclic(p2_1)
    assert Point.is_concyclic(p2_1, p2_2)
    assert Point.is_concyclic(p2_1, p2_2, p2_3, p2_4)
    for pts in permutations((p2_1, p2_2, p2_3, p2_5)):
        assert Point.is_concyclic(*pts) is False
    assert Point.is_concyclic(p4, p4 * 2, p4 * 3) is False
    assert Point(0, 0).is_concyclic((1, 1), (2, 2), (2, 1)) is False
    assert Point.is_concyclic(Point(0, 0, 0, 0), Point(1, 0, 0, 0),
                              Point(1, 1, 0, 0), Point(1, 1, 1, 0)) is False

    assert p1.is_scalar_multiple(p1)
    assert p1.is_scalar_multiple(2 * p1)
    assert not p1.is_scalar_multiple(p2)
    assert Point.is_scalar_multiple(Point(1, 1), (-1, -1))
    assert Point.is_scalar_multiple(Point(0, 0), (0, -1))
    # test when is_scalar_multiple can't be determined
    raises(
        Undecidable, lambda: Point.is_scalar_multiple(
            Point(sympify("x1%y1"), sympify("x2%y2")), Point(0, 1)))

    assert Point(0, 1).orthogonal_direction == Point(1, 0)
    assert Point(1, 0).orthogonal_direction == Point(0, 1)

    assert p1.is_zero is None
    assert p3.is_zero
    assert p4.is_zero is False
    assert p1.is_nonzero is None
    assert p3.is_nonzero is False
    assert p4.is_nonzero

    assert p4.scale(2, 3) == Point(2, 3)
    assert p3.scale(2, 3) == p3

    assert p4.rotate(pi, Point(0.5, 0.5)) == p3
    assert p1.__radd__(p2) == p1.midpoint(p2).scale(2, 2)
    assert (-p3).__rsub__(p4) == p3.midpoint(p4).scale(2, 2)

    assert p4 * 5 == Point(5, 5)
    assert p4 / 5 == Point(0.2, 0.2)
    assert 5 * p4 == Point(5, 5)

    raises(ValueError, lambda: Point(0, 0) + 10)

    # Point differences should be simplified
    assert Point(x * (x - 1), y) - Point(x**2 - x, y + 1) == Point(0, -1)

    a, b = S.Half, Rational(1, 3)
    assert Point(a, b).evalf(2) == \
        Point(a.n(2), b.n(2), evaluate=False)
    raises(ValueError, lambda: Point(1, 2) + 1)

    # test project
    assert Point.project((0, 1), (1, 0)) == Point(0, 0)
    assert Point.project((1, 1), (1, 0)) == Point(1, 0)
    raises(ValueError, lambda: Point.project(p1, Point(0, 0)))

    # test transformations
    p = Point(1, 0)
    assert p.rotate(pi / 2) == Point(0, 1)
    assert p.rotate(pi / 2, p) == p
    p = Point(1, 1)
    assert p.scale(2, 3) == Point(2, 3)
    assert p.translate(1, 2) == Point(2, 3)
    assert p.translate(1) == Point(2, 1)
    assert p.translate(y=1) == Point(1, 2)
    assert p.translate(*p.args) == Point(2, 2)

    # Check invalid input for transform
    raises(ValueError, lambda: p3.transform(p3))
    raises(ValueError, lambda: p.transform(Matrix([[1, 0], [0, 1]])))

    # test __contains__
    assert 0 in Point(0, 0, 0, 0)
    assert 1 not in Point(0, 0, 0, 0)

    # test affine_rank
    assert Point.affine_rank() == -1
示例#25
0
def test_Beam3D():
    l, E, G, I, A = symbols('l, E, G, I, A')
    R1, R2, R3, R4 = symbols('R1, R2, R3, R4')

    b = Beam3D(l, E, G, I, A)
    m, q = symbols('m, q')
    b.apply_load(q, 0, 0, dir="y")
    b.apply_moment_load(m, 0, 0, dir="z")
    b.bc_slope = [(0, [0, 0, 0]), (l, [0, 0, 0])]
    b.bc_deflection = [(0, [0, 0, 0]), (l, [0, 0, 0])]
    b.solve_slope_deflection()

    assert b.polar_moment() == 2 * I
    assert b.shear_force() == [0, -q * x, 0]
    assert b.shear_stress() == [0, -q * x / A, 0]
    assert b.axial_stress() == 0
    assert b.bending_moment() == [0, 0, -m * x + q * x**2 / 2]
    expected_deflection = (
        x *
        (A * G * q * x**3 / 4 + A * G * x**2 *
         (-l * (A * G * l * (l * q - 2 * m) + 12 * E * I * q) /
          (A * G * l**2 + 12 * E * I) / 2 - m) + 3 * E * I * l *
         (A * G * l *
          (l * q - 2 * m) + 12 * E * I * q) / (A * G * l**2 + 12 * E * I) + x *
         (-A * G * l**2 * q / 2 + 3 * A * G * l**2 *
          (A * G * l * (l * q - 2 * m) + 12 * E * I * q) /
          (A * G * l**2 + 12 * E * I) / 4 + A * G * l * m * Rational(3, 2) -
          3 * E * I * q)) / (6 * A * E * G * I))
    dx, dy, dz = b.deflection()
    assert dx == dz == 0
    assert simplify(dy - expected_deflection) == 0

    b2 = Beam3D(30, E, G, I, A, x)
    b2.apply_load(50, start=0, order=0, dir="y")
    b2.bc_deflection = [(0, [0, 0, 0]), (30, [0, 0, 0])]
    b2.apply_load(R1, start=0, order=-1, dir="y")
    b2.apply_load(R2, start=30, order=-1, dir="y")
    b2.solve_for_reaction_loads(R1, R2)
    assert b2.reaction_loads == {R1: -750, R2: -750}

    b2.solve_slope_deflection()
    assert b2.slope() == [
        0, 0,
        25 * x**3 / (3 * E * I) - 375 * x**2 / (E * I) + 3750 * x / (E * I)
    ]
    expected_deflection = 25*x**4/(12*E*I) - 125*x**3/(E*I) + 1875*x**2/(E*I) - \
        25*x**2/(A*G) + 750*x/(A*G)
    dx, dy, dz = b2.deflection()
    assert dx == dz == 0
    assert dy == expected_deflection

    # Test for solve_for_reaction_loads
    b3 = Beam3D(30, E, G, I, A, x)
    b3.apply_load(8, start=0, order=0, dir="y")
    b3.apply_load(9 * x, start=0, order=0, dir="z")
    b3.apply_load(R1, start=0, order=-1, dir="y")
    b3.apply_load(R2, start=30, order=-1, dir="y")
    b3.apply_load(R3, start=0, order=-1, dir="z")
    b3.apply_load(R4, start=30, order=-1, dir="z")
    b3.solve_for_reaction_loads(R1, R2, R3, R4)
    assert b3.reaction_loads == {R1: -120, R2: -120, R3: -1350, R4: -2700}
示例#26
0
def test_point3D():
    x = Symbol('x', real=True)
    y = Symbol('y', real=True)
    x1 = Symbol('x1', real=True)
    x2 = Symbol('x2', real=True)
    x3 = Symbol('x3', real=True)
    y1 = Symbol('y1', real=True)
    y2 = Symbol('y2', real=True)
    y3 = Symbol('y3', real=True)
    half = S.Half
    p1 = Point3D(x1, x2, x3)
    p2 = Point3D(y1, y2, y3)
    p3 = Point3D(0, 0, 0)
    p4 = Point3D(1, 1, 1)
    p5 = Point3D(0, 1, 2)

    assert p1 in p1
    assert p1 not in p2
    assert p2.y == y2
    assert (p3 + p4) == p4
    assert (p2 - p1) == Point3D(y1 - x1, y2 - x2, y3 - x3)
    assert -p2 == Point3D(-y1, -y2, -y3)

    assert Point(34.05, sqrt(3)) == Point(Rational(681, 20), sqrt(3))
    assert Point3D.midpoint(p3, p4) == Point3D(half, half, half)
    assert Point3D.midpoint(p1,
                            p4) == Point3D(half + half * x1, half + half * x2,
                                           half + half * x3)
    assert Point3D.midpoint(p2, p2) == p2
    assert p2.midpoint(p2) == p2

    assert Point3D.distance(p3, p4) == sqrt(3)
    assert Point3D.distance(p1, p1) == 0
    assert Point3D.distance(p3, p2) == sqrt(p2.x**2 + p2.y**2 + p2.z**2)

    p1_1 = Point3D(x1, x1, x1)
    p1_2 = Point3D(y2, y2, y2)
    p1_3 = Point3D(x1 + 1, x1, x1)
    Point3D.are_collinear(p3)
    assert Point3D.are_collinear(p3, p4)
    assert Point3D.are_collinear(p3, p4, p1_1, p1_2)
    assert Point3D.are_collinear(p3, p4, p1_1, p1_3) is False
    assert Point3D.are_collinear(p3, p3, p4, p5) is False

    assert p3.intersection(Point3D(0, 0, 0)) == [p3]
    assert p3.intersection(p4) == []

    assert p4 * 5 == Point3D(5, 5, 5)
    assert p4 / 5 == Point3D(0.2, 0.2, 0.2)
    assert 5 * p4 == Point3D(5, 5, 5)

    raises(ValueError, lambda: Point3D(0, 0, 0) + 10)

    # Test coordinate properties
    assert p1.coordinates == (x1, x2, x3)
    assert p2.coordinates == (y1, y2, y3)
    assert p3.coordinates == (0, 0, 0)
    assert p4.coordinates == (1, 1, 1)
    assert p5.coordinates == (0, 1, 2)
    assert p5.x == 0
    assert p5.y == 1
    assert p5.z == 2

    # Point differences should be simplified
    assert Point3D(x*(x - 1), y, 2) - Point3D(x**2 - x, y + 1, 1) == \
        Point3D(0, -1, 1)

    a, b, c = S.Half, Rational(1, 3), Rational(1, 4)
    assert Point3D(a, b, c).evalf(2) == \
        Point(a.n(2), b.n(2), c.n(2), evaluate=False)
    raises(ValueError, lambda: Point3D(1, 2, 3) + 1)

    # test transformations
    p = Point3D(1, 1, 1)
    assert p.scale(2, 3) == Point3D(2, 3, 1)
    assert p.translate(1, 2) == Point3D(2, 3, 1)
    assert p.translate(1) == Point3D(2, 1, 1)
    assert p.translate(z=1) == Point3D(1, 1, 2)
    assert p.translate(*p.args) == Point3D(2, 2, 2)

    # Test __new__
    assert Point3D(0.1, 0.2, evaluate=False,
                   on_morph='ignore').args[0].is_Float

    # Test length property returns correctly
    assert p.length == 0
    assert p1_1.length == 0
    assert p1_2.length == 0

    # Test are_colinear type error
    raises(TypeError, lambda: Point3D.are_collinear(p, x))

    # Test are_coplanar
    assert Point.are_coplanar()
    assert Point.are_coplanar((1, 2, 0), (1, 2, 0), (1, 3, 0))
    assert Point.are_coplanar((1, 2, 0), (1, 2, 3))
    with warns(UserWarning):
        raises(ValueError, lambda: Point2D.are_coplanar((1, 2), (1, 2, 3)))
    assert Point3D.are_coplanar((1, 2, 0), (1, 2, 3))
    assert Point.are_coplanar((0, 0, 0), (1, 1, 0), (1, 1, 1),
                              (1, 2, 1)) is False
    planar2 = Point3D(1, -1, 1)
    planar3 = Point3D(-1, 1, 1)
    assert Point3D.are_coplanar(p, planar2, planar3) == True
    assert Point3D.are_coplanar(p, planar2, planar3, p3) == False
    assert Point.are_coplanar(p, planar2)
    planar2 = Point3D(1, 1, 2)
    planar3 = Point3D(1, 1, 3)
    assert Point3D.are_coplanar(p, planar2, planar3)  # line, not plane
    plane = Plane((1, 2, 1), (2, 1, 0), (3, 1, 2))
    assert Point.are_coplanar(
        *[plane.projection(((-1)**i, i)) for i in range(4)])

    # all 2D points are coplanar
    assert Point.are_coplanar(Point(x, y), Point(x, x + y), Point(
        y, x + 2)) is True

    # Test Intersection
    assert planar2.intersection(Line3D(p, planar3)) == [Point3D(1, 1, 2)]

    # Test Scale
    assert planar2.scale(1, 1, 1) == planar2
    assert planar2.scale(2, 2, 2, planar3) == Point3D(1, 1, 1)
    assert planar2.scale(1, 1, 1, p3) == planar2

    # Test Transform
    identity = Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
    assert p.transform(identity) == p
    trans = Matrix([[1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1], [0, 0, 0, 1]])
    assert p.transform(trans) == Point3D(2, 2, 2)
    raises(ValueError, lambda: p.transform(p))
    raises(ValueError, lambda: p.transform(Matrix([[1, 0], [0, 1]])))

    # Test Equals
    assert p.equals(x1) == False

    # Test __sub__
    p_4d = Point(0, 0, 0, 1)
    with warns(UserWarning):
        assert p - p_4d == Point(1, 1, 1, -1)
    p_4d3d = Point(0, 0, 1, 0)
    with warns(UserWarning):
        assert p - p_4d3d == Point(1, 1, 0, 0)
示例#27
0
def roots_cubic(f, trig=False):
    """Returns a list of roots of a cubic polynomial.

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

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

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

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

    pon3 = p / 3
    aon3 = a / 3

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

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

    u2 = u1 * (Rational(-1, 2) + coeff)
    u3 = u1 * (Rational(-1, 2) - coeff)

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

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

    return soln
示例#28
0
def powsimp(expr, deep=False, combine='all', force=False, measure=count_ops):
    """
    reduces expression by combining powers with similar bases and exponents.

    Notes
    =====

    If deep is True then powsimp() will also simplify arguments of
    functions. By default deep is set to False.

    If force is True then bases will be combined without checking for
    assumptions, e.g. sqrt(x)*sqrt(y) -> sqrt(x*y) which is not true
    if x and y are both negative.

    You can make powsimp() only combine bases or only combine exponents by
    changing combine='base' or combine='exp'.  By default, combine='all',
    which does both.  combine='base' will only combine::

         a   a          a                          2x      x
        x * y  =>  (x*y)   as well as things like 2   =>  4

    and combine='exp' will only combine
    ::

         a   b      (a + b)
        x * x  =>  x

    combine='exp' will strictly only combine exponents in the way that used
    to be automatic.  Also use deep=True if you need the old behavior.

    When combine='all', 'exp' is evaluated first.  Consider the first
    example below for when there could be an ambiguity relating to this.
    This is done so things like the second example can be completely
    combined.  If you want 'base' combined first, do something like
    powsimp(powsimp(expr, combine='base'), combine='exp').

    Examples
    ========

    >>> from sympy import powsimp, exp, log, symbols
    >>> from sympy.abc import x, y, z, n
    >>> powsimp(x**y*x**z*y**z, combine='all')
    x**(y + z)*y**z
    >>> powsimp(x**y*x**z*y**z, combine='exp')
    x**(y + z)*y**z
    >>> powsimp(x**y*x**z*y**z, combine='base', force=True)
    x**y*(x*y)**z

    >>> powsimp(x**z*x**y*n**z*n**y, combine='all', force=True)
    (n*x)**(y + z)
    >>> powsimp(x**z*x**y*n**z*n**y, combine='exp')
    n**(y + z)*x**(y + z)
    >>> powsimp(x**z*x**y*n**z*n**y, combine='base', force=True)
    (n*x)**y*(n*x)**z

    >>> x, y = symbols('x y', positive=True)
    >>> powsimp(log(exp(x)*exp(y)))
    log(exp(x)*exp(y))
    >>> powsimp(log(exp(x)*exp(y)), deep=True)
    x + y

    Radicals with Mul bases will be combined if combine='exp'

    >>> from sympy import sqrt, Mul
    >>> x, y = symbols('x y')

    Two radicals are automatically joined through Mul:

    >>> a=sqrt(x*sqrt(y))
    >>> a*a**3 == a**4
    True

    But if an integer power of that radical has been
    autoexpanded then Mul does not join the resulting factors:

    >>> a**4 # auto expands to a Mul, no longer a Pow
    x**2*y
    >>> _*a # so Mul doesn't combine them
    x**2*y*sqrt(x*sqrt(y))
    >>> powsimp(_) # but powsimp will
    (x*sqrt(y))**(5/2)
    >>> powsimp(x*y*a) # but won't when doing so would violate assumptions
    x*y*sqrt(x*sqrt(y))

    """
    from sympy.matrices.expressions.matexpr import MatrixSymbol

    def recurse(arg, **kwargs):
        _deep = kwargs.get('deep', deep)
        _combine = kwargs.get('combine', combine)
        _force = kwargs.get('force', force)
        _measure = kwargs.get('measure', measure)
        return powsimp(arg, _deep, _combine, _force, _measure)

    expr = sympify(expr)

    if (not isinstance(expr, Basic) or isinstance(expr, MatrixSymbol)
            or (expr.is_Atom or expr in (exp_polar(0), exp_polar(1)))):
        return expr

    if deep or expr.is_Add or expr.is_Mul and _y not in expr.args:
        expr = expr.func(*[recurse(w) for w in expr.args])

    if expr.is_Pow:
        return recurse(expr * _y, deep=False) / _y

    if not expr.is_Mul:
        return expr

    # handle the Mul
    if combine in ('exp', 'all'):
        # Collect base/exp data, while maintaining order in the
        # non-commutative parts of the product
        c_powers = defaultdict(list)
        nc_part = []
        newexpr = []
        coeff = S.One
        for term in expr.args:
            if term.is_Rational:
                coeff *= term
                continue
            if term.is_Pow:
                term = _denest_pow(term)
            if term.is_commutative:
                b, e = term.as_base_exp()
                if deep:
                    b, e = [recurse(i) for i in [b, e]]
                if b.is_Pow or isinstance(b, exp):
                    # don't let smthg like sqrt(x**a) split into x**a, 1/2
                    # or else it will be joined as x**(a/2) later
                    b, e = b**e, S.One
                c_powers[b].append(e)
            else:
                # This is the logic that combines exponents for equal,
                # but non-commutative bases: A**x*A**y == A**(x+y).
                if nc_part:
                    b1, e1 = nc_part[-1].as_base_exp()
                    b2, e2 = term.as_base_exp()
                    if (b1 == b2 and e1.is_commutative and e2.is_commutative):
                        nc_part[-1] = Pow(b1, Add(e1, e2))
                        continue
                nc_part.append(term)

        # add up exponents of common bases
        for b, e in ordered(iter(c_powers.items())):
            # allow 2**x/4 -> 2**(x - 2); don't do this when b and e are
            # Numbers since autoevaluation will undo it, e.g.
            # 2**(1/3)/4 -> 2**(1/3 - 2) -> 2**(1/3)/4
            if (b and b.is_Rational and not all(ei.is_Number for ei in e) and \
                    coeff is not S.One and
                    b not in (S.One, S.NegativeOne)):
                m = multiplicity(abs(b), abs(coeff))
                if m:
                    e.append(m)
                    coeff /= b**m
            c_powers[b] = Add(*e)
        if coeff is not S.One:
            if coeff in c_powers:
                c_powers[coeff] += S.One
            else:
                c_powers[coeff] = S.One

        # convert to plain dictionary
        c_powers = dict(c_powers)

        # check for base and inverted base pairs
        be = list(c_powers.items())
        skip = set()  # skip if we already saw them
        for b, e in be:
            if b in skip:
                continue
            bpos = b.is_positive or b.is_polar
            if bpos:
                binv = 1 / b
                if b != binv and binv in c_powers:
                    if b.as_numer_denom()[0] is S.One:
                        c_powers.pop(b)
                        c_powers[binv] -= e
                    else:
                        skip.add(binv)
                        e = c_powers.pop(binv)
                        c_powers[b] -= e

        # check for base and negated base pairs
        be = list(c_powers.items())
        _n = S.NegativeOne
        for b, e in be:
            if (b.is_Symbol or b.is_Add) and -b in c_powers and b in c_powers:
                if (b.is_positive is not None or e.is_integer):
                    if e.is_integer or b.is_negative:
                        c_powers[-b] += c_powers.pop(b)
                    else:  # (-b).is_positive so use its e
                        e = c_powers.pop(-b)
                        c_powers[b] += e
                    if _n in c_powers:
                        c_powers[_n] += e
                    else:
                        c_powers[_n] = e

        # filter c_powers and convert to a list
        c_powers = [(b, e) for b, e in c_powers.items() if e]

        # ==============================================================
        # check for Mul bases of Rational powers that can be combined with
        # separated bases, e.g. x*sqrt(x*y)*sqrt(x*sqrt(x*y)) ->
        # (x*sqrt(x*y))**(3/2)
        # ---------------- helper functions

        def ratq(x):
            '''Return Rational part of x's exponent as it appears in the bkey.
            '''
            return bkey(x)[0][1]

        def bkey(b, e=None):
            '''Return (b**s, c.q), c.p where e -> c*s. If e is not given then
            it will be taken by using as_base_exp() on the input b.
            e.g.
                x**3/2 -> (x, 2), 3
                x**y -> (x**y, 1), 1
                x**(2*y/3) -> (x**y, 3), 2
                exp(x/2) -> (exp(a), 2), 1

            '''
            if e is not None:  # coming from c_powers or from below
                if e.is_Integer:
                    return (b, S.One), e
                elif e.is_Rational:
                    return (b, Integer(e.q)), Integer(e.p)
                else:
                    c, m = e.as_coeff_Mul(rational=True)
                    if c is not S.One:
                        if m.is_integer:
                            return (b, Integer(c.q)), m * Integer(c.p)
                        return (b**m, Integer(c.q)), Integer(c.p)
                    else:
                        return (b**e, S.One), S.One
            else:
                return bkey(*b.as_base_exp())

        def update(b):
            '''Decide what to do with base, b. If its exponent is now an
            integer multiple of the Rational denominator, then remove it
            and put the factors of its base in the common_b dictionary or
            update the existing bases if necessary. If it has been zeroed
            out, simply remove the base.
            '''
            newe, r = divmod(common_b[b], b[1])
            if not r:
                common_b.pop(b)
                if newe:
                    for m in Mul.make_args(b[0]**newe):
                        b, e = bkey(m)
                        if b not in common_b:
                            common_b[b] = 0
                        common_b[b] += e
                        if b[1] != 1:
                            bases.append(b)

        # ---------------- end of helper functions

        # assemble a dictionary of the factors having a Rational power
        common_b = {}
        done = []
        bases = []
        for b, e in c_powers:
            b, e = bkey(b, e)
            if b in common_b:
                common_b[b] = common_b[b] + e
            else:
                common_b[b] = e
            if b[1] != 1 and b[0].is_Mul:
                bases.append(b)
        bases.sort(key=default_sort_key)  # this makes tie-breaking canonical
        bases.sort(key=measure, reverse=True)  # handle longest first
        for base in bases:
            if base not in common_b:  # it may have been removed already
                continue
            b, exponent = base
            last = False  # True when no factor of base is a radical
            qlcm = 1  # the lcm of the radical denominators
            while True:
                bstart = b
                qstart = qlcm

                bb = []  # list of factors
                ee = []  # (factor's expo. and it's current value in common_b)
                for bi in Mul.make_args(b):
                    bib, bie = bkey(bi)
                    if bib not in common_b or common_b[bib] < bie:
                        ee = bb = []  # failed
                        break
                    ee.append([bie, common_b[bib]])
                    bb.append(bib)
                if ee:
                    # find the number of integral extractions possible
                    # e.g. [(1, 2), (2, 2)] -> min(2/1, 2/2) -> 1
                    min1 = ee[0][1] // ee[0][0]
                    for i in range(1, len(ee)):
                        rat = ee[i][1] // ee[i][0]
                        if rat < 1:
                            break
                        min1 = min(min1, rat)
                    else:
                        # update base factor counts
                        # e.g. if ee = [(2, 5), (3, 6)] then min1 = 2
                        # and the new base counts will be 5-2*2 and 6-2*3
                        for i in range(len(bb)):
                            common_b[bb[i]] -= min1 * ee[i][0]
                            update(bb[i])
                        # update the count of the base
                        # e.g. x**2*y*sqrt(x*sqrt(y)) the count of x*sqrt(y)
                        # will increase by 4 to give bkey (x*sqrt(y), 2, 5)
                        common_b[base] += min1 * qstart * exponent
                if (last  # no more radicals in base
                        or len(common_b) == 1  # nothing left to join with
                        or all(k[1] == 1
                               for k in common_b)  # no rad's in common_b
                    ):
                    break
                # see what we can exponentiate base by to remove any radicals
                # so we know what to search for
                # e.g. if base were x**(1/2)*y**(1/3) then we should
                # exponentiate by 6 and look for powers of x and y in the ratio
                # of 2 to 3
                qlcm = lcm([ratq(bi) for bi in Mul.make_args(bstart)])
                if qlcm == 1:
                    break  # we are done
                b = bstart**qlcm
                qlcm *= qstart
                if all(ratq(bi) == 1 for bi in Mul.make_args(b)):
                    last = True  # we are going to be done after this next pass
            # this base no longer can find anything to join with and
            # since it was longer than any other we are done with it
            b, q = base
            done.append((b, common_b.pop(base) * Rational(1, q)))

        # update c_powers and get ready to continue with powsimp
        c_powers = done
        # there may be terms still in common_b that were bases that were
        # identified as needing processing, so remove those, too
        for (b, q), e in common_b.items():
            if (b.is_Pow or isinstance(b, exp)) and \
                    q is not S.One and not b.exp.is_Rational:
                b, be = b.as_base_exp()
                b = b**(be / q)
            else:
                b = root(b, q)
            c_powers.append((b, e))
        check = len(c_powers)
        c_powers = dict(c_powers)
        assert len(c_powers) == check  # there should have been no duplicates
        # ==============================================================

        # rebuild the expression
        newexpr = expr.func(*(newexpr +
                              [Pow(b, e) for b, e in c_powers.items()]))
        if combine == 'exp':
            return expr.func(newexpr, expr.func(*nc_part))
        else:
            return recurse(expr.func(*nc_part), combine='base') * \
                recurse(newexpr, combine='base')

    elif combine == 'base':

        # Build c_powers and nc_part.  These must both be lists not
        # dicts because exp's are not combined.
        c_powers = []
        nc_part = []
        for term in expr.args:
            if term.is_commutative:
                c_powers.append(list(term.as_base_exp()))
            else:
                nc_part.append(term)

        # Pull out numerical coefficients from exponent if assumptions allow
        # e.g., 2**(2*x) => 4**x
        for i in range(len(c_powers)):
            b, e = c_powers[i]
            if not (all(x.is_nonnegative for x in b.as_numer_denom())
                    or e.is_integer or force or b.is_polar):
                continue
            exp_c, exp_t = e.as_coeff_Mul(rational=True)
            if exp_c is not S.One and exp_t is not S.One:
                c_powers[i] = [Pow(b, exp_c), exp_t]

        # Combine bases whenever they have the same exponent and
        # assumptions allow
        # first gather the potential bases under the common exponent
        c_exp = defaultdict(list)
        for b, e in c_powers:
            if deep:
                e = recurse(e)
            c_exp[e].append(b)
        del c_powers

        # Merge back in the results of the above to form a new product
        c_powers = defaultdict(list)
        for e in c_exp:
            bases = c_exp[e]

            # calculate the new base for e

            if len(bases) == 1:
                new_base = bases[0]
            elif e.is_integer or force:
                new_base = expr.func(*bases)
            else:
                # see which ones can be joined
                unk = []
                nonneg = []
                neg = []
                for bi in bases:
                    if bi.is_negative:
                        neg.append(bi)
                    elif bi.is_nonnegative:
                        nonneg.append(bi)
                    elif bi.is_polar:
                        nonneg.append(
                            bi)  # polar can be treated like non-negative
                    else:
                        unk.append(bi)
                if len(unk) == 1 and not neg or len(neg) == 1 and not unk:
                    # a single neg or a single unk can join the rest
                    nonneg.extend(unk + neg)
                    unk = neg = []
                elif neg:
                    # their negative signs cancel in groups of 2*q if we know
                    # that e = p/q else we have to treat them as unknown
                    israt = False
                    if e.is_Rational:
                        israt = True
                    else:
                        p, d = e.as_numer_denom()
                        if p.is_integer and d.is_integer:
                            israt = True
                    if israt:
                        neg = [-w for w in neg]
                        unk.extend([S.NegativeOne] * len(neg))
                    else:
                        unk.extend(neg)
                        neg = []
                    del israt

                # these shouldn't be joined
                for b in unk:
                    c_powers[b].append(e)
                # here is a new joined base
                new_base = expr.func(*(nonneg + neg))

                # if there are positive parts they will just get separated
                # again unless some change is made

                def _terms(e):
                    # return the number of terms of this expression
                    # when multiplied out -- assuming no joining of terms
                    if e.is_Add:
                        return sum([_terms(ai) for ai in e.args])
                    if e.is_Mul:
                        return prod([_terms(mi) for mi in e.args])
                    return 1

                xnew_base = expand_mul(new_base, deep=False)
                if len(Add.make_args(xnew_base)) < _terms(new_base):
                    new_base = factor_terms(xnew_base)

            c_powers[new_base].append(e)

        # break out the powers from c_powers now
        c_part = [Pow(b, ei) for b, e in c_powers.items() for ei in e]

        # we're done
        return expr.func(*(c_part + nc_part))

    else:
        raise ValueError("combine must be one of ('all', 'exp', 'base').")
示例#29
0
文件: add.py 项目: yukoba/sympy
    def primitive(self):
        """
        Return ``(R, self/R)`` where ``R``` is the Rational GCD of ``self```.

        ``R`` is collected only from the leading coefficient of each term.

        Examples
        ========

        >>> from sympy.abc import x, y

        >>> (2*x + 4*y).primitive()
        (2, x + 2*y)

        >>> (2*x/3 + 4*y/9).primitive()
        (2/9, 3*x + 2*y)

        >>> (2*x/3 + 4.2*y).primitive()
        (1/3, 2*x + 12.6*y)

        No subprocessing of term factors is performed:

        >>> ((2 + 2*x)*x + 2).primitive()
        (1, x*(2*x + 2) + 2)

        Recursive subprocessing can be done with the as_content_primitive()
        method:

        >>> ((2 + 2*x)*x + 2).as_content_primitive()
        (2, x*(x + 1) + 1)

        See also: primitive() function in polytools.py

        """

        terms = []
        inf = False
        for a in self.args:
            c, m = a.as_coeff_Mul()
            if not c.is_Rational:
                c = S.One
                m = a
            inf = inf or m is S.ComplexInfinity
            terms.append((c.p, c.q, m))

        if not inf:
            ngcd = reduce(igcd, [t[0] for t in terms], 0)
            dlcm = reduce(ilcm, [t[1] for t in terms], 1)
        else:
            ngcd = reduce(igcd, [t[0] for t in terms if t[1]], 0)
            dlcm = reduce(ilcm, [t[1] for t in terms if t[1]], 1)

        if ngcd == dlcm == 1:
            return S.One, self
        if not inf:
            for i, (p, q, term) in enumerate(terms):
                terms[i] = _keep_coeff(Rational((p//ngcd)*(dlcm//q)), term)
        else:
            for i, (p, q, term) in enumerate(terms):
                if q:
                    terms[i] = _keep_coeff(Rational((p//ngcd)*(dlcm//q)), term)
                else:
                    terms[i] = _keep_coeff(Rational(p, q), term)

        # we don't need a complete re-flattening since no new terms will join
        # so we just use the same sort as is used in Add.flatten. When the
        # coefficient changes, the ordering of terms may change, e.g.
        #     (3*x, 6*y) -> (2*y, x)
        #
        # We do need to make sure that term[0] stays in position 0, however.
        #
        if terms[0].is_Number or terms[0] is S.ComplexInfinity:
            c = terms.pop(0)
        else:
            c = None
        _addsort(terms)
        if c:
            terms.insert(0, c)
        return Rational(ngcd, dlcm), self._new_rawargs(*terms)
 def test_equality(r, alg="Greedy"):
     return r == Add(*[Rational(1, i) for i in egyptian_fraction(r, alg)])
示例#31
0
def trigintegrate(f, x):
    """Integrate f = Mul(trig) over x

       >>> from sympy import Symbol, sin, cos, tan, sec, csc, cot
       >>> from sympy.integrals.trigonometry import trigintegrate
       >>> from sympy.abc import x

       >>> trigintegrate(sin(x)*cos(x), x)
       sin(x)**2/2

       >>> trigintegrate(sin(x)**2, x)
       x/2 - sin(x)*cos(x)/2

       >>> trigintegrate(tan(x)*sec(x),x)
       1/cos(x)

       >>> trigintegrate(sin(x)*tan(x),x)
       -log(sin(x) - 1)/2 + log(sin(x) + 1)/2 - sin(x)

       http://en.wikibooks.org/wiki/Calculus/Further_integration_techniques

    See Also
    ========

    sympy.integrals.integrals.Integral.doit
    sympy.integrals.integrals.Integral
    """

    pat, a,n,m = _pat_sincos(x)
    pat1, s,t,q,r = _pat_gen(x)


    M_ = f.match(pat1)


    if M_ is None:
        return

    q = M_[q]
    r = M_[r]


  ###
  ###  f =  function1(written in terms of sincos) X function2(written in terms of sincos)
  ###
    if q is not S.Zero and r is not S.Zero:
        s = M_[s]
        t = M_[t]
        if s.args is not () and t.args is not () \
            and Trig_Check(s) and Trig_Check(t):

            f = s._eval_rewrite_as_sincos(s.args[0])**q * t._eval_rewrite_as_sincos(t.args[0])**r

    if q is S.Zero and r is S.Zero:
        return x

    if q is S.Zero and r is not S.Zero:
        t = M_[t]
        if t.args is not () and Trig_Check(t):
            f = t._eval_rewrite_as_sincos(t.args[0])**r

    if r is S.Zero and q is not S.Zero:
        s = M_[s]
        if s.args is not () and Trig_Check(s):
            f = s._eval_rewrite_as_sincos(s.args[0])**q


    M= f.match(pat)   # matching the rewritten function with the sincos pattern


    if M is None:
        return

    n, m  = M[n], M[m]
    if n is S.Zero and m is S.Zero:
        return x

    a = M[a]

    if n.is_integer and m.is_integer:

        if n.is_odd or m.is_odd:
            u = _u
            n_, m_ = n.is_odd, m.is_odd

            # take smallest n or m -- to choose simplest substitution
            if n_ and m_:
                n_ = n_ and     (n < m)  # NB: careful here, one of the
                m_ = m_ and not (n < m)  #     conditions *must* be true

            #  n      m       u=C        (n-1)/2    m
            # S(x) * C(x) dx  --> -(1-u^2)       * u  du
            if n_:
                ff = -(1-u**2)**((n-1)/2) * u**m
                uu = cos(a*x)

            #  n      m       u=S   n         (m-1)/2
            # S(x) * C(x) dx  -->  u  * (1-u^2)       du
            elif m_:
                ff = u**n * (1-u**2)**((m-1)/2)
                uu = sin(a*x)

            fi= sympy.integrals.integrate(ff, u)    # XXX cyclic deps
            fx= fi.subs(u, uu)
            return fx / a

        # n & m are even
        else:
            #               2k      2m                         2l       2l
            # we transform S (x) * C (x) into terms with only S (x) or C (x)
            #
            # example:
            #  100     4       100        2    2    100          4         2
            # S (x) * C (x) = S (x) * (1-S (x))  = S (x) * (1 + S (x) - 2*S (x))
            #
            #                  104       102     100
            #               = S (x) - 2*S (x) + S (x)
            #       2k
            # then S   is integrated with recursive formula

            # take largest n or m -- to choose simplest substitution
            n_ =  (abs(n) > abs(m))
            m_ =  (abs(m) > abs(n))
            res = S.Zero

            if n_:
                #  2k       2 k             i            2i
                # C   = (1-S )  = sum(i, (-) * B(k,i) * S  )
                if m > 0 :
                    for i in range(0,m/2+1):
                        res += (-1)**i * binomial(m/2,i) * _sin_pow_integrate(n+2*i, x)

                elif m == 0:
                    res=_sin_pow_integrate(n,x)
                else:
                    # m < 0 , |n| > |m|
                    #  /                                                           /
                    # |                                                           |
                    # |    m       n            -1        m+1     n-1     n - 1   |     m+2     n-2
                    # | cos (x) sin (x) dx =  ________ cos (x) sin (x) + _______  |  cos (x) sin (x) dx
                    # |                                                           |
                    # |                         m + 1                     m + 1   |
                    #/                                                           /
                    #
                    #
                    res=Rational(-1,m+1)*cos(x)**(m+1)*sin(x)**(n-1) + Rational(n-1,m+1)*trigintegrate(cos(x)**(m+2)*sin(x)**(n-2),x)


            elif m_:
                #  2k        2 k            i            2i
                # S   = (1 -C ) = sum(i, (-) * B(k,i) * C  )
                if n > 0:
                    #      /                            /
                    #     |                            |
                    #     |    m       n               |    -m         n
                    #     | cos (x)*sin (x) dx  or     | cos (x) * sin (x) dx
                    #     |                            |
                    #    /                            /
                    #
                    #    |m| > |n| ; m,n >0 ; m,n belong to Z - {0}
                    #       n                                        2
                    #    sin (x) term is expanded here interms of cos (x), and then integrated.
                    for i in range(0,n/2+1):
                        res += (-1)**i * binomial(n/2,i) * _cos_pow_integrate(m+2*i, x)

                elif n == 0 :
                    ##  /
                    ## |
                    #  |  1
                    #  | _ _ _
                    #  |    m
                    #  | cos (x)
                    # /
                    res= _cos_pow_integrate(m,x)
                else:
                    # n < 0 , |m| > |n|
                    #  /                                                         /
                    # |                                                         |
                    # |    m       n           1        m-1     n+1     m - 1   |     m-2     n+2
                    # | cos (x) sin (x) dx = _______ cos (x) sin (x) + _______  |  cos (x) sin (x) dx
                    # |                                                         |
                    # |                       n + 1                     n + 1   |
                    #/                                                         /
                    #
                    #
                    res= Rational(1,(n+1))*cos(x)**(m-1)*sin(x)**(n+1) + Rational(m-1,n+1)*trigintegrate(cos(x)**(m-2)*sin(x)**(n+2),x)

            else :
                if m == n:
                    ##Substitute sin(2x)/2 for sin(x)cos(x) and then Integrate.
                    res=sympy.integrals.integrate((Rational(1,2)*sin(2*x))**m,x)
                elif (m == -n):
                    if n < 0:
                        ##Same as the scheme described above.
                        res= Rational(1,(n+1))*cos(x)**(m-1)*sin(x)**(n+1) + Rational(m-1,n+1)*sympy.integrals.integrate(cos(x)**(m-2)*sin(x)**(n+2),x) ##the function argument to integrate in the end will be 1 , this cannot be integrated by trigintegrate. Hence use sympy.integrals.integrate.
                    else:
                        res=Rational(-1,m+1)*cos(x)**(m+1)*sin(x)**(n-1) + Rational(n-1,m+1)*sympy.integrals.integrate(cos(x)**(m+2)*sin(x)**(n-2),x)
            return res.subs(x, a*x) / a
示例#32
0
def test_logexppow():  # no eval()
    x = Symbol('x', real=True)
    w = Symbol('w')
    e = (3**(1 + x) + 2**(1 + x)) / (3**x + 2**x)
    assert e.subs(2**x, w) != e
    assert e.subs(exp(x * log(Rational(2))), w) != e