Repository: sympy/sympy

Issue:
integrate(sqrt(x - y) * log(z / x), x) has no result
but with Mathematica I can get a solution:

2/9 (6 y^(3/2) ArcTan(Sqrt(x - y)/Sqrt(y)) + Sqrt(x - y) (2 (x - 4 y) + 3 (x - y) Log(z/x)))

Where in sympy would we have to do work to implement a solution?

Discussion:
lindsayad: Please let me know if there's additional work (or complete re-work!) that needs to be done in order for this to go in.
lindsayad: Can someone tell this contributing newbie why the different tests are failing?
jksuom: It looks like the code in manualintegrate is running in a loop. You could investigate by testing one new rule at a time.

Patch:
diff --git a/sympy/integrals/manualintegrate.py b/sympy/integrals/manualintegrate.py
index 50d75d5f92..e8cda04f04 100644
--- a/sympy/integrals/manualintegrate.py
+++ b/sympy/integrals/manualintegrate.py
@@ -47,7 +47,6 @@ def __eq__(self, other):
 TrigRule = Rule("TrigRule", "func arg")
 ExpRule = Rule("ExpRule", "base exp")
 ReciprocalRule = Rule("ReciprocalRule", "func")
-ArctanRule = Rule("ArctanRule")
 ArcsinRule = Rule("ArcsinRule")
 InverseHyperbolicRule = Rule("InverseHyperbolicRule", "func")
 AlternativeRule = Rule("AlternativeRule", "alternatives")
@@ -58,6 +57,9 @@ def __eq__(self, other):
 HeavisideRule = Rule("HeavisideRule", "harg ibnd substep")
 TrigSubstitutionRule = Rule("TrigSubstitutionRule",
                             "theta func rewritten substep restriction")
+ArctanRule = Rule("ArctanRule", "a b c")
+ArccothRule = Rule("ArccothRule", "a b c")
+ArctanhRule = Rule("ArctanhRule", "a b c")
 
 IntegralInfo = namedtuple('IntegralInfo', 'integrand symbol')
 
@@ -170,7 +172,7 @@ def _rewriter(integral):
             rewritten = rewrite(*integral)
             if rewritten != integrand:
                 substep = integral_steps(rewritten, symbol)
-                if not isinstance(substep, DontKnowRule):
+                if not isinstance(substep, DontKnowRule) and substep:
                     return RewriteRule(
                         rewritten,
                         substep,
@@ -286,12 +288,12 @@ def make_inverse_trig(RuleClass, base_exp, a, sign_a, b, sign_b):
 
         substep = RuleClass(current_base ** base_exp, current_symbol)
         if u_func is not None:
-            if u_constant != 1:
+            if u_constant != 1 and substep is not None:
                 substep = ConstantTimesRule(
                     u_constant, current_base ** base_exp, substep,
                     u_constant * current_base ** base_exp, symbol)
             substep = URule(u_var, u_func, u_constant, substep, factored, symbol)
-        if constant is not None:
+        if constant is not None and substep is not None:
             substep = ConstantTimesRule(constant, factored, substep, integrand, symbol)
         return substep
 
@@ -300,9 +302,7 @@ def make_inverse_trig(RuleClass, base_exp, a, sign_a, b, sign_b):
     # list of (rule, base_exp, a, sign_a, b, sign_b, condition)
     possibilities = []
 
-    if sympy.simplify(exp + 1) == 0 and not (negative(a) or negative(b)):
-        possibilities.append((ArctanRule, exp, a, 1, b, 1, sympy.And(a > 0, b > 0)))
-    elif sympy.simplify(2*exp + 1) == 0:
+    if sympy.simplify(2*exp + 1) == 0:
         possibilities.append((ArcsinRule, exp, a, 1, -b, -1, sympy.And(a > 0, b < 0)))
         possibilities.append((ArcsinhRule, exp, a, 1, b, 1, sympy.And(a > 0, b > 0)))
         possibilities.append((ArccoshRule, exp, -a, -1, b, 1, sympy.And(a < 0, b > 0)))
@@ -330,22 +330,25 @@ def mul_rule(integral):
 
     # Constant times function case
     coeff, f = integrand.as_independent(symbol)
+    next_step = integral_steps(f, symbol)
 
-    if coeff != 1:
+    if coeff != 1 and next_step is not None:
         return ConstantTimesRule(
             coeff, f,
-            integral_steps(f, symbol),
+            next_step,
             integrand, symbol)
 
 def _parts_rule(integrand, symbol):
     # LIATE rule:
-    # log, inverse trig, algebraic (polynomial), trigonometric, exponential
-    def pull_out_polys(integrand):
-        integrand = integrand.together()
-        polys = [arg for arg in integrand.args if arg.is_polynomial(symbol)]
-        if polys:
-            u = sympy.Mul(*polys)
-            dv = integrand / u
+    # log, inverse trig, algebraic, trigonometric, exponential
+    def pull_out_algebraic(integrand):
+        integrand = integrand.cancel().together()
+        algebraic = [arg for arg in integrand.args if arg.is_algebraic_expr(symbol)]
+        if algebraic:
+            u = sympy.Mul(*algebraic)
+            dv = (integrand / u).cancel()
+            if not u.is_polynomial() and isinstance(dv, sympy.exp):
+                return
             return u, dv
 
     def pull_out_u(*functions):
@@ -361,7 +364,7 @@ def pull_out_u_rl(integrand):
         return pull_out_u_rl
 
     liate_rules = [pull_out_u(sympy.log), pull_out_u(sympy.atan, sympy.asin, sympy.acos),
-                   pull_out_polys, pull_out_u(sympy.sin, sympy.cos),
+                   pull_out_algebraic, pull_out_u(sympy.sin, sympy.cos),
                    pull_out_u(sympy.exp)]
 
 
@@ -386,9 +389,9 @@ def pull_out_u_rl(integrand):
             for rule in liate_rules[index + 1:]:
                 r = rule(integrand)
                 # make sure dv is amenable to integration
-                if r and r[0].subs(dummy, 1) == dv:
+                if r and sympy.simplify(r[0].subs(dummy, 1)) == sympy.simplify(dv):
                     du = u.diff(symbol)
-                    v_step = integral_steps(dv, symbol)
+                    v_step = integral_steps(sympy.simplify(dv), symbol)
                     v = _manualintegrate(v_step)
 
                     return u, dv, v, du, v_step
@@ -408,6 +411,8 @@ def parts_rule(integral):
             return
 
         while True:
+            if (integrand / (v * du)).cancel() == 1:
+                break
             if symbol not in (integrand / (v * du)).cancel().free_symbols:
                 coefficient = ((v * du) / integrand).cancel()
                 rule = CyclicPartsRule(
@@ -416,7 +421,7 @@ def parts_rule(integral):
                     (-1) ** len(steps) * coefficient,
                     integrand, symbol
                 )
-                if constant != 1:
+                if (constant != 1) and rule:
                     rule = ConstantTimesRule(constant, integrand, rule,
                                              constant * integrand, symbol)
                 return rule
@@ -436,14 +441,18 @@ def make_second_step(steps, integrand):
                              make_second_step(steps[1:], v * du),
                              integrand, symbol)
         else:
-            return integral_steps(integrand, symbol)
+            steps = integral_steps(integrand, symbol)
+            if steps:
+                return steps
+            else:
+                return DontKnowRule(integrand, symbol)
 
     if steps:
         u, dv, v, du, v_step = steps[0]
         rule = PartsRule(u, dv, v_step,
                          make_second_step(steps[1:], v * du),
                          integrand, symbol)
-        if constant != 1:
+        if (constant != 1) and rule:
             rule = ConstantTimesRule(constant, integrand, rule,
                                      constant * integrand, symbol)
         return rule
@@ -498,7 +507,7 @@ def trig_product_rule(integral):
 
     if symbol not in q.free_symbols:
         rule = TrigRule('sec*tan', symbol, sectan, symbol)
-        if q != 1:
+        if q != 1 and rule:
             rule = ConstantTimesRule(q, sectan, rule, integrand, symbol)
 
         return rule
@@ -508,11 +517,53 @@ def trig_product_rule(integral):
 
     if symbol not in q.free_symbols:
         rule = TrigRule('csc*cot', symbol, csccot, symbol)
-        if q != 1:
+        if q != 1 and rule:
             rule = ConstantTimesRule(q, csccot, rule, integrand, symbol)
 
         return rule
 
+def quadratic_denom_rule(integral):
+    integrand, symbol = integral
+    a = sympy.Wild('a', exclude=[symbol])
+    b = sympy.Wild('b', exclude=[symbol])
+    c = sympy.Wild('c', exclude=[symbol])
+    match = integrand.match(a / (b * symbol ** 2 + c))
+
+    if not match:
+        return
+
+    a, b, c = match[a], match[b], match[c]
+    return PiecewiseRule([(ArctanRule(a, b, c, integrand, symbol), sympy.Gt(c / b, 0)),
+                          (ArccothRule(a, b, c, integrand, symbol), sympy.And(sympy.Gt(symbol ** 2, -c / b), sympy.Lt(c / b, 0))),
+                          (ArctanhRule(a, b, c, integrand, symbol), sympy.And(sympy.Lt(symbol ** 2, -c / b), sympy.Lt(c / b, 0))),
+    ], integrand, symbol)
+
+def root_mul_rule(integral):
+    integrand, symbol = integral
+    a = sympy.Wild('a', exclude=[symbol])
+    b = sympy.Wild('b', exclude=[symbol])
+    c = sympy.Wild('c')
+    match = integrand.match(sympy.sqrt(a * symbol + b) * c)
+
+    if not match:
+        return
+
+    a, b, c = match[a], match[b], match[c]
+    d = sympy.Wild('d', exclude=[symbol])
+    e = sympy.Wild('e', exclude=[symbol])
+    f = sympy.Wild('f')
+    recursion_test = c.match(sympy.sqrt(d * symbol + e) * f)
+    if recursion_test:
+        return
+
+    u = sympy.Dummy('u')
+    u_func = sympy.sqrt(a * symbol + b)
+    integrand = integrand.subs(u_func, u)
+    integrand = integrand.subs(symbol, (u**2 - b) / a)
+    integrand = integrand * 2 * u / a
+    next_step = integral_steps(integrand, u)
+    if next_step:
+        return URule(u, u_func, None, next_step, integrand, symbol)
 
 @sympy.cacheit
 def make_wilds(symbol):
@@ -761,7 +812,8 @@ def substitution_rule(integral):
 
             if sympy.simplify(c - 1) != 0:
                 _, denom = c.as_numer_denom()
-                subrule = ConstantTimesRule(c, substituted, subrule, substituted, u_var)
+                if subrule:
+                    subrule = ConstantTimesRule(c, substituted, subrule, substituted, u_var)
 
                 if denom.free_symbols:
                     piecewise = []
@@ -808,6 +860,12 @@ def substitution_rule(integral):
     lambda integrand, symbol: integrand.is_rational_function(),
     lambda integrand, symbol: integrand.apart(symbol))
 
+cancel_rule = rewriter(
+    # lambda integrand, symbol: integrand.is_algebraic_expr(),
+    # lambda integrand, symbol: isinstance(integrand, sympy.Mul),
+    lambda integrand, symbol: True,
+    lambda integrand, symbol: integrand.cancel())
+
 distribute_expand_rule = rewriter(
     lambda integrand, symbol: (
         all(arg.is_Pow or arg.is_polynomial(symbol) for arg in integrand.args)
@@ -855,8 +913,10 @@ def integral_steps(integrand, symbol, **options):
     >>> print(repr(integral_steps(exp(x) / (1 + exp(2 * x)), x))) \
     # doctest: +NORMALIZE_WHITESPACE
     URule(u_var=_u, u_func=exp(x), constant=1,
-        substep=ArctanRule(context=1/(_u**2 + 1), symbol=_u),
-        context=exp(x)/(exp(2*x) + 1), symbol=x)
+    substep=PiecewiseRule(subfunctions=[(ArctanRule(a=1, b=1, c=1, context=1/(_u**2 + 1), symbol=_u), True),
+        (ArccothRule(a=1, b=1, c=1, context=1/(_u**2 + 1), symbol=_u), False),
+        (ArctanhRule(a=1, b=1, c=1, context=1/(_u**2 + 1), symbol=_u), False)],
+    context=1/(_u**2 + 1), symbol=_u), context=exp(x)/(exp(2*x) + 1), symbol=x)
     >>> print(repr(integral_steps(sin(x), x))) \
     # doctest: +NORMALIZE_WHITESPACE
     TrigRule(func='sin', arg=x, context=sin(x), symbol=x)
@@ -914,12 +974,14 @@ def _integral_is_subclass(integral):
 
     result = do_one(
         null_safe(switch(key, {
-            sympy.Pow: do_one(null_safe(power_rule), null_safe(inverse_trig_rule)),
+            sympy.Pow: do_one(null_safe(power_rule), null_safe(inverse_trig_rule), \
+                              null_safe(quadratic_denom_rule)),
             sympy.Symbol: power_rule,
             sympy.exp: exp_rule,
             sympy.Add: add_rule,
             sympy.Mul: do_one(null_safe(mul_rule), null_safe(trig_product_rule), \
-                null_safe(heaviside_rule)),
+                              null_safe(heaviside_rule), null_safe(quadratic_denom_rule), \
+                              null_safe(root_mul_rule)),
             sympy.Derivative: derivative_rule,
             TrigonometricFunction: trig_rule,
             sympy.Heaviside: heaviside_rule,
@@ -933,6 +995,9 @@ def _integral_is_subclass(integral):
                 condition(
                     integral_is_subclass(sympy.Mul, sympy.Pow),
                     partial_fractions_rule),
+                condition(
+                    integral_is_subclass(sympy.Mul, sympy.Pow),
+                    cancel_rule),
                 condition(
                     integral_is_subclass(sympy.Mul, sympy.log, sympy.atan, sympy.asin, sympy.acos),
                     parts_rule),
@@ -975,6 +1040,7 @@ def eval_u(u_var, u_func, constant, substep, integrand, symbol):
 @evaluates(PartsRule)
 def eval_parts(u, dv, v_step, second_step, integrand, symbol):
     v = _manualintegrate(v_step)
+
     return u * v - _manualintegrate(second_step)
 
 @evaluates(CyclicPartsRule)
@@ -1004,14 +1070,22 @@ def eval_trig(func, arg, integrand, symbol):
     elif func == 'csc**2':
         return -sympy.cot(arg)
 
+@evaluates(ArctanRule)
+def eval_arctan(a, b, c, integrand, symbol):
+    return a / b * 1 / sympy.sqrt(c / b) * sympy.atan(symbol / sympy.sqrt(c / b))
+
+@evaluates(ArccothRule)
+def eval_arccoth(a, b, c, integrand, symbol):
+    return - a / b * 1 / sympy.sqrt(-c / b) * sympy.acoth(symbol / sympy.sqrt(-c / b))
+
+@evaluates(ArctanhRule)
+def eval_arctanh(a, b, c, integrand, symbol):
+    return - a / b * 1 / sympy.sqrt(-c / b) * sympy.atanh(symbol / sympy.sqrt(-c / b))
+
 @evaluates(ReciprocalRule)
 def eval_reciprocal(func, integrand, symbol):
     return sympy.ln(func)
 
-@evaluates(ArctanRule)
-def eval_arctan(integrand, symbol):
-    return sympy.atan(symbol)
-
 @evaluates(ArcsinRule)
 def eval_arcsin(integrand, symbol):
     return sympy.asin(symbol)
@@ -1093,6 +1167,7 @@ def eval_dontknowrule(integrand, symbol):
 def _manualintegrate(rule):
     evaluator = evaluators.get(rule.__class__)
     if not evaluator:
+
         raise ValueError("Cannot evaluate rule %s" % repr(rule))
     return evaluator(*rule)
 


Test patch:
diff --git a/sympy/integrals/tests/test_manual.py b/sympy/integrals/tests/test_manual.py
index 6c968fb059..f6ee9ab49e 100644
--- a/sympy/integrals/tests/test_manual.py
+++ b/sympy/integrals/tests/test_manual.py
@@ -1,11 +1,11 @@
 from sympy import (sin, cos, tan, sec, csc, cot, log, exp, atan, asin, acos,
                    Symbol, Integral, integrate, pi, Dummy, Derivative,
-                   diff, I, sqrt, erf, Piecewise, Eq, symbols,
-                   And, Heaviside, S, asinh, acosh)
+                   diff, I, sqrt, erf, Piecewise, Eq, symbols, Rational,
+                   And, Heaviside, S, asinh, acosh, atanh, acoth, expand)
 from sympy.integrals.manualintegrate import manualintegrate, find_substitutions, \
     _parts_rule
 
-x, y, u, n, a, b = symbols('x y u n a b')
+x, y, z, u, n, a, b, c = symbols('x y z u n a b c')
 
 
 def test_find_substitutions():
@@ -45,7 +45,7 @@ def test_manualintegrate_parts():
     assert manualintegrate(x * log(x), x) == x**2*log(x)/2 - x**2/4
     assert manualintegrate(log(x), x) == x * log(x) - x
     assert manualintegrate((3*x**2 + 5) * exp(x), x) == \
-        -6*x*exp(x) + (3*x**2 + 5)*exp(x) + 6*exp(x)
+        3*x**2*exp(x) - 6*x*exp(x) + 11*exp(x)
     assert manualintegrate(atan(x), x) == x*atan(x) - log(x**2 + 1)/2
 
     # Make sure _parts_rule doesn't pick u = constant but can pick dv =
@@ -99,11 +99,17 @@ def test_manualintegrate_inversetrig():
     assert manualintegrate(1 / (4 + x**2), x) == atan(x / 2) / 2
     assert manualintegrate(1 / (1 + 4 * x**2), x) == atan(2*x) / 2
     assert manualintegrate(1/(a + b*x**2), x) == \
-        Piecewise(((sqrt(a/b)*atan(x*sqrt(b/a))/a), And(a > 0, b > 0)))
+        Piecewise((atan(x/sqrt(a/b))/(b*sqrt(a/b)), a/b > 0), \
+                  (-acoth(x/sqrt(-a/b))/(b*sqrt(-a/b)), And(a/b < 0, x**2 > -a/b)), \
+                  (-atanh(x/sqrt(-a/b))/(b*sqrt(-a/b)), And(a/b < 0, x**2 < -a/b)))
     assert manualintegrate(1/(4 + b*x**2), x) == \
-        Piecewise((sqrt(1/b)*atan(sqrt(b)*x/2)/2, b > 0))
+        Piecewise((atan(x/(2*sqrt(1/b)))/(2*b*sqrt(1/b)), 4/b > 0), \
+                  (-acoth(x/(2*sqrt(-1/b)))/(2*b*sqrt(-1/b)), And(4/b < 0, x**2 > -4/b)), \
+                  (-atanh(x/(2*sqrt(-1/b)))/(2*b*sqrt(-1/b)), And(4/b < 0, x**2 < -4/b)))
     assert manualintegrate(1/(a + 4*x**2), x) == \
-        Piecewise((atan(2*x*sqrt(1/a))/(2*sqrt(a)), a > 0))
+        Piecewise((atan(2*x/sqrt(a))/(2*sqrt(a)), a/4 > 0), \
+                  (-acoth(2*x/sqrt(-a))/(2*sqrt(-a)), And(a/4 < 0, x**2 > -a/4)), \
+                  (-atanh(2*x/sqrt(-a))/(2*sqrt(-a)), And(a/4 < 0, x**2 < -a/4)))
     assert manualintegrate(1/(4 + 4*x**2), x) == atan(x) / 4
 
     # asin
@@ -165,8 +171,8 @@ def test_manualintegrate_trig_substitution():
 
 
 def test_manualintegrate_rational():
-    assert manualintegrate(1/(4 - x**2), x) == -log(x - 2)/4 + log(x + 2)/4
-    assert manualintegrate(1/(-1 + x**2), x) == log(x - 1)/2 - log(x + 1)/2
+    assert manualintegrate(1/(4 - x**2), x) == Piecewise((acoth(x/2)/2, x**2 > 4), (atanh(x/2)/2, x**2 < 4))
+    assert manualintegrate(1/(-1 + x**2), x) == Piecewise((-acoth(x), x**2 > 1), (-atanh(x), x**2 < 1))
 
 
 def test_manualintegrate_derivative():
@@ -247,7 +253,10 @@ def test_issue_6746():
         (y + 1)**(n*x)/(n*log(y + 1))
     a = Symbol('a', negative=True)
     assert manualintegrate(1 / (a + b*x**2), x) == \
-        Integral(1/(a + b*x**2), x)
+        Piecewise((atan(x/sqrt(a/b))/(b*sqrt(a/b)), a/b > 0), \
+        (-acoth(x/sqrt(-a/b))/(b*sqrt(-a/b)), And(a/b < 0, x**2 > -a/b)), \
+        (-atanh(x/sqrt(-a/b))/(b*sqrt(-a/b)), And(a/b < 0, x**2 < -a/b)))
+
 
 
 def test_issue_2850():
@@ -258,6 +267,46 @@ def test_issue_2850():
     assert manualintegrate(atan(x)*log(x), x) == -x*atan(x) + (x*atan(x) - \
             log(x**2 + 1)/2)*log(x) + log(x**2 + 1)/2 + Integral(log(x**2 + 1)/x, x)/2
 
+def test_issue_9462():
+    assert manualintegrate(sin(2*x)*exp(x), x) == -3*exp(x)*sin(2*x) \
+                           - 2*exp(x)*cos(2*x) + 4*Integral(2*exp(x)*cos(2*x), x)
+    assert manualintegrate((x - 3) / (x**2 - 2*x + 2)**2, x) == \
+                           Integral(x/(x**4 - 4*x**3 + 8*x**2 - 8*x + 4), x) \
+                           - 3*Integral(1/(x**4 - 4*x**3 + 8*x**2 - 8*x + 4), x)
+
+def test_issue_10847():
+    assert manualintegrate(x**2 / (x**2 - c), x) == c*Piecewise((atan(x/sqrt(-c))/sqrt(-c), -c > 0), \
+                                                                (-acoth(x/sqrt(c))/sqrt(c), And(-c < 0, x**2 > c)), \
+                                                                (-atanh(x/sqrt(c))/sqrt(c), And(-c < 0, x**2 < c))) + x
+    assert manualintegrate(sqrt(x - y) * log(z / x), x) == 4*y**2*Piecewise((atan(sqrt(x - y)/sqrt(y))/sqrt(y), y > 0), \
+                                                                            (-acoth(sqrt(x - y)/sqrt(-y))/sqrt(-y), \
+                                                                             And(x - y > -y, y < 0)), \
+                                                                            (-atanh(sqrt(x - y)/sqrt(-y))/sqrt(-y), \
+                                                                             And(x - y < -y, y < 0)))/3 \
+                                                                             - 4*y*sqrt(x - y)/3 + 2*(x - y)**(3/2)*log(z/x)/3 \
+                                                                             + 4*(x - y)**(3/2)/9
+
+    assert manualintegrate(sqrt(x) * log(x), x) == 2*x**(3/2)*log(x)/3 - 4*x**(3/2)/9
+    assert manualintegrate(sqrt(a*x + b) / x, x) == -2*b*Piecewise((-atan(sqrt(a*x + b)/sqrt(-b))/sqrt(-b), -b > 0), \
+                                                               (acoth(sqrt(a*x + b)/sqrt(b))/sqrt(b), And(-b < 0, a*x + b > b)), \
+                                                               (atanh(sqrt(a*x + b)/sqrt(b))/sqrt(b), And(-b < 0, a*x + b < b))) \
+                                                               + 2*sqrt(a*x + b)
+
+    assert expand(manualintegrate(sqrt(a*x + b) / (x + c), x)) == -2*a*c*Piecewise((atan(sqrt(a*x + b)/sqrt(a*c - b))/sqrt(a*c - b), \
+        a*c - b > 0), (-acoth(sqrt(a*x + b)/sqrt(-a*c + b))/sqrt(-a*c + b), And(a*c - b < 0, a*x + b > -a*c + b)), \
+        (-atanh(sqrt(a*x + b)/sqrt(-a*c + b))/sqrt(-a*c + b), And(a*c - b < 0, a*x + b < -a*c + b))) \
+        + 2*b*Piecewise((atan(sqrt(a*x + b)/sqrt(a*c - b))/sqrt(a*c - b), a*c - b > 0), \
+        (-acoth(sqrt(a*x + b)/sqrt(-a*c + b))/sqrt(-a*c + b), And(a*c - b < 0, a*x + b > -a*c + b)), \
+        (-atanh(sqrt(a*x + b)/sqrt(-a*c + b))/sqrt(-a*c + b), And(a*c - b < 0, a*x + b < -a*c + b))) + 2*sqrt(a*x + b)
+
+    assert manualintegrate((4*x**4 + 4*x**3 + 16*x**2 + 12*x + 8) \
+                           / (x**6 + 2*x**5 + 3*x**4 + 4*x**3 + 3*x**2 + 2*x + 1), x) == \
+                           2*x/(x**2 + 1) + 3*atan(x) - 1/(x**2 + 1) - 3/(x + 1)
+    assert manualintegrate(sqrt(2*x + 3) / (x + 1), x) == 2*sqrt(2*x + 3) - log(sqrt(2*x + 3) + 1) + log(sqrt(2*x + 3) - 1)
+    assert manualintegrate(sqrt(2*x + 3) / 2 * x, x) == (2*x + 3)**(5/2)/20 - (2*x + 3)**(3/2)/4
+    assert manualintegrate(x**Rational(3,2) * log(x), x) == 2*x**Rational(5,2)*log(x)/5 - 4*x**Rational(5/2)/25
+    assert manualintegrate(x**(-3) * log(x), x) == -log(x)/(2*x**2) - 1/(4*x**2)
+    assert manualintegrate(log(y)/(y**2*(1 - 1/y)), y) == (-log(y) + log(y - 1))*log(y) + log(y)**2/2 - Integral(log(y - 1)/y, y)
 
 def test_constant_independent_of_symbol():
     assert manualintegrate(Integral(y, (x, 1, 2)), x) == x*Integral(y, (x, 1, 2))
diff --git a/sympy/integrals/tests/test_prde.py b/sympy/integrals/tests/test_prde.py
index b4ba49f756..dd1821acd3 100644
--- a/sympy/integrals/tests/test_prde.py
+++ b/sympy/integrals/tests/test_prde.py
@@ -221,8 +221,10 @@ def test_parametric_log_deriv():
 
 
 def test_issue_10798():
-    from sympy import integrate, pi, I, log, polylog, exp_polar
+    from sympy import integrate, pi, I, log, polylog, exp_polar, Piecewise, meijerg, Abs
     from sympy.abc import x, y
     assert integrate(1/(1-(x*y)**2), (x, 0, 1), y) == \
-        I*pi*log(y)/2 + polylog(2, exp_polar(I*pi)/y)/2 - \
-        polylog(2, exp_polar(2*I*pi)/y)/2
+        -Piecewise((I*pi*log(y) - polylog(2, y), Abs(y) < 1), (-I*pi*log(1/y) - polylog(2, y), Abs(1/y) < 1), \
+                   (-I*pi*meijerg(((), (1, 1)), ((0, 0), ()), y) + I*pi*meijerg(((1, 1), ()), ((), (0, 0)), y) - polylog(2, y), True))/2 \
+                   - log(y)*log(1 - 1/y)/2 + log(y)*log(1 + 1/y)/2 + log(y)*log(y - 1)/2 \
+                   - log(y)*log(y + 1)/2 + I*pi*log(y)/2 - polylog(2, y*exp_polar(I*pi))/2