Ejemplo n.º 1
0
def get_sol_2F1_hypergeometric(eq, func, match_object):
    x = func.args[0]
    from sympy.simplify.hyperexpand import hyperexpand
    from sympy.polys.polytools import factor
    C0, C1 = get_numbered_constants(eq, num=2)
    a = match_object['a']
    b = match_object['b']
    c = match_object['c']
    A = match_object['A']

    sol = None

    if c.is_integer == False:
        sol = C0 * hyper([a, b], [c], x) + C1 * hyper([a - c + 1, b - c + 1],
                                                      [2 - c], x) * x**(1 - c)
    elif c == 1:
        y2 = Integral(
            exp(Integral((-(a + b + 1) * x + c) / (x**2 - x), x)) /
            (hyperexpand(hyper([a, b], [c], x))**2), x) * hyper([a, b], [c], x)
        sol = C0 * hyper([a, b], [c], x) + C1 * y2
    elif (c - a - b).is_integer == False:
        sol = C0 * hyper([a, b], [1 + a + b - c], 1 - x) + C1 * hyper(
            [c - a, c - b], [1 + c - a - b], 1 - x) * (1 - x)**(c - a - b)

    if sol:
        # applying transformation in the solution
        subs = match_object['mobius']
        dtdx = simplify(1 / (subs.diff(x)))
        _B = ((a + b + 1) * x - c).subs(x, subs) * dtdx
        _B = factor(_B + ((x**2 - x).subs(x, subs)) * (dtdx.diff(x) * dtdx))
        _A = factor((x**2 - x).subs(x, subs) * (dtdx**2))
        e = exp(logcombine(Integral(cancel(_B / (2 * _A)), x), force=True))
        sol = sol.subs(x, match_object['mobius'])
        sol = sol.subs(x, x**match_object['k'])
        e = e.subs(x, x**match_object['k'])

        if not A.is_zero:
            e1 = Integral(A / 2, x)
            e1 = exp(logcombine(e1, force=True))
            sol = cancel((e / e1) * x**((-match_object['k'] + 1) / 2)) * sol
            sol = Eq(func, sol)
            return sol

        sol = cancel((e) * x**((-match_object['k'] + 1) / 2)) * sol
        sol = Eq(func, sol)
    return sol
Ejemplo n.º 2
0
def sign(e, x):
    """
    Returns a sign of an expression e(x) for x->oo.

    ::

        e >  0 for x sufficiently large ...  1
        e == 0 for x sufficiently large ...  0
        e <  0 for x sufficiently large ... -1

    The result of this function is currently undefined if e changes sign
    arbitrarily often for arbitrarily large x (e.g. sin(x)).

    Note that this returns zero only if e is *constantly* zero
    for x sufficiently large. [If e is constant, of course, this is just
    the same thing as the sign of e.]
    """
    if not isinstance(e, Basic):
        raise TypeError("e should be an instance of Basic")

    if e.is_positive:
        return 1
    elif e.is_negative:
        return -1
    elif e.is_zero:
        return 0

    elif not e.has(x):
        from sympy.simplify import logcombine
        e = logcombine(e)
        return _sign(e)
    elif e == x:
        return 1
    elif e.is_Mul:
        a, b = e.as_two_terms()
        sa = sign(a, x)
        if not sa:
            return 0
        return sa * sign(b, x)
    elif isinstance(e, exp):
        return 1
    elif e.is_Pow:
        if e.base == S.Exp1:
            return 1
        s = sign(e.base, x)
        if s == 1:
            return 1
        if e.exp.is_Integer:
            return s**e.exp
    elif isinstance(e, log):
        return sign(e.args[0] - 1, x)

    # if all else fails, do it the hard way
    c0, e0 = mrv_leadterm(e, x)
    return sign(c0, x)