text:
@testset "1.2.2.7 P(x) (d+e x^2)^q (a+b x^2+c x^4)^p" begin
    (A, B, a, b, c, d, e, q, x, ) = @variables A B a b c d e q x

    #= ::Package:: =#

    #= ::Title::Closed:: =#
    #=Integrands*of*the*form*P(x)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^p=#

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*P2(x)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^p*when*b=0=#

    #= ::Subsection:: =#
    #=Integrands*of*the*form*(A+B*x^2)*(d+e*x^2)^q*(a+c*x^4)^p=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(A+B*x^2)*(d+e*x^2)^q*(a+c*x^4)^(p/2)=#

    #= ::Subsubsection:: =#
    #=p>0=#

    #= ::Subsubsection::Closed:: =#
    #=p<0=#

    @test_int [(A + B*x^2)*(d + e*x^2)^3/sqrt(a + c*x^4), x, 15, (e*(21*B*c*d^2 + 21*A*c*d*e - 5*a*B*e^2)*x*sqrt(a + c*x^4))/(21*c^2) + (e^2*(3*B*d + A*e)*x^3*sqrt(a + c*x^4))/(5*c) + (B*e^3*x^5*sqrt(a + c*x^4))/(7*c) + ((5*B*c*d^3 + 15*A*c*d^2*e - 9*a*B*d*e^2 - 3*a*A*e^3)*x*sqrt(a + c*x^4))/(5*c^(3/2)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*(5*B*c*d^3 + 15*A*c*d^2*e - 9*a*B*d*e^2 - 3*a*A*e^3)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(5*c^(7/4)*sqrt(a + c*x^4)) + ((105*A*c^2*d^3 + 25*a^2*B*e^3 - 105*a*c*d*e*(B*d + A*e) - 63*a^(3/2)*sqrt(c)*e^2*(3*B*d + A*e) + 105*sqrt(a)*c^(3/2)*d^2*(B*d + 3*A*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(210*a^(1/4)*c^(9/4)*sqrt(a + c*x^4)), -((5*a*B*e^3*x*sqrt(a + c*x^4))/(21*c^2)) + (d*e*(B*d + A*e)*x*sqrt(a + c*x^4))/c + (e^2*(3*B*d + A*e)*x^3*sqrt(a + c*x^4))/(5*c) + (B*e^3*x^5*sqrt(a + c*x^4))/(7*c) - (3*a*e^2*(3*B*d + A*e)*x*sqrt(a + c*x^4))/(5*c^(3/2)*(sqrt(a) + sqrt(c)*x^2)) + (d^2*(B*d + 3*A*e)*x*sqrt(a + c*x^4))/(sqrt(c)*(sqrt(a) + sqrt(c)*x^2)) + (3*a^(5/4)*e^2*(3*B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(5*c^(7/4)*sqrt(a + c*x^4)) - (a^(1/4)*d^2*(B*d + 3*A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(c^(3/4)*sqrt(a + c*x^4)) + (A*d^3*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*c^(1/4)*sqrt(a + c*x^4)) + (5*a^(7/4)*B*e^3*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(42*c^(9/4)*sqrt(a + c*x^4)) - (a^(3/4)*d*e*(B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*c^(5/4)*sqrt(a + c*x^4)) - (3*a^(5/4)*e^2*(3*B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(10*c^(7/4)*sqrt(a + c*x^4)) + (a^(1/4)*d^2*(B*d + 3*A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*c^(3/4)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^2/sqrt(a + c*x^4), x, 12, (e*(2*B*d + A*e)*x*sqrt(a + c*x^4))/(3*c) + (B*e^2*x^3*sqrt(a + c*x^4))/(5*c) + ((5*B*c*d^2 + 10*A*c*d*e - 3*a*B*e^2)*x*sqrt(a + c*x^4))/(5*c^(3/2)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*(5*B*c*d^2 + 10*A*c*d*e - 3*a*B*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(5*c^(7/4)*sqrt(a + c*x^4)) + ((15*A*c^(3/2)*d^2 - 9*a^(3/2)*B*e^2 - 5*a*sqrt(c)*e*(2*B*d + A*e) + 15*sqrt(a)*c*d*(B*d + 2*A*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(30*a^(1/4)*c^(7/4)*sqrt(a + c*x^4)), (e*(2*B*d + A*e)*x*sqrt(a + c*x^4))/(3*c) + (B*e^2*x^3*sqrt(a + c*x^4))/(5*c) - (3*a*B*e^2*x*sqrt(a + c*x^4))/(5*c^(3/2)*(sqrt(a) + sqrt(c)*x^2)) + (d*(B*d + 2*A*e)*x*sqrt(a + c*x^4))/(sqrt(c)*(sqrt(a) + sqrt(c)*x^2)) + (3*a^(5/4)*B*e^2*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(5*c^(7/4)*sqrt(a + c*x^4)) - (a^(1/4)*d*(B*d + 2*A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(c^(3/4)*sqrt(a + c*x^4)) + (A*d^2*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*c^(1/4)*sqrt(a + c*x^4)) - (3*a^(5/4)*B*e^2*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(10*c^(7/4)*sqrt(a + c*x^4)) - (a^(3/4)*e*(2*B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(6*c^(5/4)*sqrt(a + c*x^4)) + (a^(1/4)*d*(B*d + 2*A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*c^(3/4)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^1/sqrt(a + c*x^4), x, 8, (B*e*x*sqrt(a + c*x^4))/(3*c) + ((B*d + A*e)*x*sqrt(a + c*x^4))/(sqrt(c)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*(B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(c^(3/4)*sqrt(a + c*x^4)) + (a^(1/4)*(3*sqrt(c)*(B*d + A*e) + (3*A*c*d - a*B*e)/sqrt(a))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(6*c^(5/4)*sqrt(a + c*x^4)), (B*e*x*sqrt(a + c*x^4))/(3*c) + ((B*d + A*e)*x*sqrt(a + c*x^4))/(sqrt(c)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*(B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(c^(3/4)*sqrt(a + c*x^4)) + (A*d*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*c^(1/4)*sqrt(a + c*x^4)) - (a^(3/4)*B*e*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(6*c^(5/4)*sqrt(a + c*x^4)) + (a^(1/4)*(B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*c^(3/4)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^0/sqrt(a + c*x^4), x, 3, (B*x*sqrt(a + c*x^4))/(sqrt(c)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*B*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(c^(3/4)*sqrt(a + c*x^4)) + (a^(1/4)*(B + (A*sqrt(c))/sqrt(a))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*c^(3/4)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^1*sqrt(a + c*x^4)), x, 3, -(((B*d - A*e)*atan((sqrt(c*d^2 + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + c*x^4))))/(2*sqrt(d)*sqrt(e)*sqrt(c*d^2 + a*e^2))) - ((sqrt(a)*B - A*sqrt(c))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*c^(1/4)*(sqrt(c)*d - sqrt(a)*e)*sqrt(a + c*x^4)) + (a^(3/4)*((sqrt(c)*d)/sqrt(a) + e)^2*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*c^(1/4)*d*e*(c*d^2 - a*e^2)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^2*sqrt(a + c*x^4)), x, 6, (sqrt(c)*(B*d - A*e)*x*sqrt(a + c*x^4))/(2*d*(c*d^2 + a*e^2)*(sqrt(a) + sqrt(c)*x^2)) - (e*(B*d - A*e)*x*sqrt(a + c*x^4))/(2*d*(c*d^2 + a*e^2)*(d + e*x^2)) - ((B*c*d^3 - 3*A*c*d^2*e - a*B*d*e^2 - a*A*e^3)*atan((sqrt(c*d^2 + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + c*x^4))))/(4*d^(3/2)*sqrt(e)*(c*d^2 + a*e^2)^(3/2)) - (a^(1/4)*c^(1/4)*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*d*(c*d^2 + a*e^2)*sqrt(a + c*x^4)) + (A*c^(1/4)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*d*(sqrt(c)*d - sqrt(a)*e)*sqrt(a + c*x^4)) + ((sqrt(c)*d + sqrt(a)*e)*(B*c*d^3 - 3*A*c*d^2*e - a*B*d*e^2 - a*A*e^3)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(8*a^(1/4)*c^(1/4)*d^2*e*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^3*sqrt(a + c*x^4)), x, 7, (sqrt(c)*(5*B*c*d^3 - 9*A*c*d^2*e - a*B*d*e^2 - 3*a*A*e^3)*x*sqrt(a + c*x^4))/(8*d^2*(c*d^2 + a*e^2)^2*(sqrt(a) + sqrt(c)*x^2)) - (e*(B*d - A*e)*x*sqrt(a + c*x^4))/(4*d*(c*d^2 + a*e^2)*(d + e*x^2)^2) - (e*(5*B*c*d^3 - 9*A*c*d^2*e - a*B*d*e^2 - 3*a*A*e^3)*x*sqrt(a + c*x^4))/(8*d^2*(c*d^2 + a*e^2)^2*(d + e*x^2)) + ((3*A*e*(5*c^2*d^4 + 2*a*c*d^2*e^2 + a^2*e^4) - B*(3*c^2*d^5 - 10*a*c*d^3*e^2 - a^2*d*e^4))*atan((sqrt(c*d^2 + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + c*x^4))))/(16*d^(5/2)*sqrt(e)*(c*d^2 + a*e^2)^(5/2)) - (a^(1/4)*c^(1/4)*(5*B*c*d^3 - 9*A*c*d^2*e - a*B*d*e^2 - 3*a*A*e^3)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(8*d^2*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4)) + (c^(1/4)*(4*A*c*d^2 + sqrt(a)*sqrt(c)*d*(B*d - A*e) + a*e*(B*d + 3*A*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(8*a^(1/4)*d^2*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)*sqrt(a + c*x^4)) - ((sqrt(c)*d + sqrt(a)*e)*(3*A*e*(5*c^2*d^4 + 2*a*c*d^2*e^2 + a^2*e^4) - B*(3*c^2*d^5 - 10*a*c*d^3*e^2 - a^2*d*e^4))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(32*a^(1/4)*c^(1/4)*d^3*e*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4))]

    @test_int [(A + B*x^2)*(d + e*x^2)^3/(a + c*x^4)^(3/2), x, 12, (x*(A*c*d*(c*d^2 - 3*a*e^2) - a*B*e*(3*c*d^2 - a*e^2) + c*(B*c*d^3 + 3*A*c*d^2*e - 3*a*B*d*e^2 - a*A*e^3)*x^2))/(2*a*c^2*sqrt(a + c*x^4)) + (B*e^3*x*sqrt(a + c*x^4))/(3*c^2) + (e^2*(3*B*d + A*e)*x*sqrt(a + c*x^4))/(c^(3/2)*(sqrt(a) + sqrt(c)*x^2)) - ((B*c*d^3 + 3*A*c*d^2*e - 3*a*B*d*e^2 - a*A*e^3)*x*sqrt(a + c*x^4))/(2*a*c^(3/2)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*e^2*(3*B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(c^(7/4)*sqrt(a + c*x^4)) + ((B*c*d^3 + 3*A*c*d^2*e - 3*a*B*d*e^2 - a*A*e^3)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(3/4)*c^(7/4)*sqrt(a + c*x^4)) - (a^(3/4)*B*e^3*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(6*c^(9/4)*sqrt(a + c*x^4)) + (a^(1/4)*e^2*(3*B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*c^(7/4)*sqrt(a + c*x^4)) + (e*(3*B*c*d^2 + 3*A*c*d*e - a*B*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*c^(9/4)*sqrt(a + c*x^4)) + ((A*c^2*d^3 + a^2*B*e^3 - 3*a*c*d*e*(B*d + A*e) + a^(3/2)*sqrt(c)*e^2*(3*B*d + A*e) - sqrt(a)*c^(3/2)*d^2*(B*d + 3*A*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*a^(5/4)*c^(9/4)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^2/(a + c*x^4)^(3/2), x, 10, (x*(A*c*d^2 - 2*a*B*d*e - a*A*e^2 + (B*c*d^2 + 2*A*c*d*e - a*B*e^2)*x^2))/(2*a*c*sqrt(a + c*x^4)) + (B*e^2*x*sqrt(a + c*x^4))/(c^(3/2)*(sqrt(a) + sqrt(c)*x^2)) - ((B*c*d^2 + 2*A*c*d*e - a*B*e^2)*x*sqrt(a + c*x^4))/(2*a*c^(3/2)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*B*e^2*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(c^(7/4)*sqrt(a + c*x^4)) + ((B*c*d^2 + 2*A*c*d*e - a*B*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(3/4)*c^(7/4)*sqrt(a + c*x^4)) + (a^(1/4)*B*e^2*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*c^(7/4)*sqrt(a + c*x^4)) + (e*(2*B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*c^(5/4)*sqrt(a + c*x^4)) - ((B*c*d^2 + 2*A*c*d*e - a*B*e^2 - (sqrt(c)*(A*c*d^2 - 2*a*B*d*e - a*A*e^2))/sqrt(a))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*a^(3/4)*c^(7/4)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^1/(a + c*x^4)^(3/2), x, 7, (x*(A*c*d - a*B*e + c*(B*d + A*e)*x^2))/(2*a*c*sqrt(a + c*x^4)) - ((B*d + A*e)*x*sqrt(a + c*x^4))/(2*a*sqrt(c)*(sqrt(a) + sqrt(c)*x^2)) + ((B*d + A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(3/4)*c^(3/4)*sqrt(a + c*x^4)) + (B*e*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*c^(5/4)*sqrt(a + c*x^4)) + ((A*c*d - a*B*e - sqrt(a)*sqrt(c)*(B*d + A*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*a^(5/4)*c^(5/4)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^0/(a + c*x^4)^(3/2), x, 4, (x*(A + B*x^2))/(2*a*sqrt(a + c*x^4)) - (B*x*sqrt(a + c*x^4))/(2*a*sqrt(c)*(sqrt(a) + sqrt(c)*x^2)) + (B*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(3/4)*c^(3/4)*sqrt(a + c*x^4)) - ((sqrt(a)*B - A*sqrt(c))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*a^(5/4)*c^(3/4)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^1*(a + c*x^4)^(3/2)), x, 9, (x*(A*c*d + a*B*e + c*(B*d - A*e)*x^2))/(2*a*(c*d^2 + a*e^2)*sqrt(a + c*x^4)) - (sqrt(c)*(B*d - A*e)*x*sqrt(a + c*x^4))/(2*a*(c*d^2 + a*e^2)*(sqrt(a) + sqrt(c)*x^2)) - (e^(3/2)*(B*d - A*e)*atan((sqrt(c*d^2 + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + c*x^4))))/(2*sqrt(d)*(c*d^2 + a*e^2)^(3/2)) + (c^(1/4)*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(3/4)*(c*d^2 + a*e^2)*sqrt(a + c*x^4)) - (c^(1/4)*e*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)*sqrt(a + c*x^4)) + ((A*c*d + a*B*e - sqrt(a)*sqrt(c)*(B*d - A*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*a^(5/4)*c^(1/4)*(c*d^2 + a*e^2)*sqrt(a + c*x^4)) + (a^(3/4)*e*((sqrt(c)*d)/sqrt(a) + e)^2*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*c^(1/4)*d*(c^2*d^4 - a^2*e^4)*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^2*(a + c*x^4)^(3/2)), x, 15, (c*x*(A*c*d^2 + 2*a*B*d*e - a*A*e^2 + (B*c*d^2 - 2*A*c*d*e - a*B*e^2)*x^2))/(2*a*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4)) + (sqrt(c)*e^2*(B*d - A*e)*x*sqrt(a + c*x^4))/(2*d*(c*d^2 + a*e^2)^2*(sqrt(a) + sqrt(c)*x^2)) - (sqrt(c)*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*x*sqrt(a + c*x^4))/(2*a*(c*d^2 + a*e^2)^2*(sqrt(a) + sqrt(c)*x^2)) - (e^3*(B*d - A*e)*x*sqrt(a + c*x^4))/(2*d*(c*d^2 + a*e^2)^2*(d + e*x^2)) - (e^(3/2)*(B*d - A*e)*(3*c*d^2 + a*e^2)*atan((sqrt(c*d^2 + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + c*x^4))))/(4*d^(3/2)*(c*d^2 + a*e^2)^(5/2)) - (e^(3/2)*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*atan((sqrt(c*d^2 + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + c*x^4))))/(2*sqrt(d)*(c*d^2 + a*e^2)^(5/2)) - (a^(1/4)*c^(1/4)*e^2*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*d*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4)) + (c^(1/4)*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(3/4)*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4)) - (c^(1/4)*e*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*d*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)*sqrt(a + c*x^4)) - (c^(1/4)*e*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4)) - (c^(1/4)*(B*c*d^2 - 2*A*c*d*e - a*B*e^2 - (sqrt(c)*(A*c*d^2 + 2*a*B*d*e - a*A*e^2))/sqrt(a))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*a^(3/4)*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4)) + (e*(sqrt(c)*d + sqrt(a)*e)*(B*d - A*e)*(3*c*d^2 + a*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(8*a^(1/4)*c^(1/4)*d^2*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4)) + (a^(3/4)*e*((sqrt(c)*d)/sqrt(a) + e)^2*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*c^(1/4)*d*(c*d^2 - a*e^2)*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^3*(a + c*x^4)^(3/2)), x, 22, (c*x*(A*c*d*(c*d^2 - 3*a*e^2) + a*B*e*(3*c*d^2 - a*e^2) + c*(B*c*d^3 - 3*A*c*d^2*e - 3*a*B*d*e^2 + a*A*e^3)*x^2))/(2*a*(c*d^2 + a*e^2)^3*sqrt(a + c*x^4)) + (3*sqrt(c)*e^2*(B*d - A*e)*(3*c*d^2 + a*e^2)*x*sqrt(a + c*x^4))/(8*d^2*(c*d^2 + a*e^2)^3*(sqrt(a) + sqrt(c)*x^2)) + (sqrt(c)*e^2*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*x*sqrt(a + c*x^4))/(2*d*(c*d^2 + a*e^2)^3*(sqrt(a) + sqrt(c)*x^2)) - (c^(3/2)*(B*c*d^3 - 3*A*c*d^2*e - 3*a*B*d*e^2 + a*A*e^3)*x*sqrt(a + c*x^4))/(2*a*(c*d^2 + a*e^2)^3*(sqrt(a) + sqrt(c)*x^2)) - (e^3*(B*d - A*e)*x*sqrt(a + c*x^4))/(4*d*(c*d^2 + a*e^2)^2*(d + e*x^2)^2) - (3*e^3*(B*d - A*e)*(3*c*d^2 + a*e^2)*x*sqrt(a + c*x^4))/(8*d^2*(c*d^2 + a*e^2)^3*(d + e*x^2)) - (e^3*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*x*sqrt(a + c*x^4))/(2*d*(c*d^2 + a*e^2)^3*(d + e*x^2)) - (e^(3/2)*(3*c*d^2 + a*e^2)*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*atan((sqrt(c*d^2 + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + c*x^4))))/(4*d^(3/2)*(c*d^2 + a*e^2)^(7/2)) - (c*e^(3/2)*(B*c*d^3 - 3*A*c*d^2*e - 3*a*B*d*e^2 + a*A*e^3)*atan((sqrt(c*d^2 + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + c*x^4))))/(2*sqrt(d)*(c*d^2 + a*e^2)^(7/2)) - (3*e^(3/2)*(B*d - A*e)*(5*c^2*d^4 + 2*a*c*d^2*e^2 + a^2*e^4)*atan((sqrt(c*d^2 + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + c*x^4))))/(16*d^(5/2)*(c*d^2 + a*e^2)^(7/2)) - (3*a^(1/4)*c^(1/4)*e^2*(B*d - A*e)*(3*c*d^2 + a*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(8*d^2*(c*d^2 + a*e^2)^3*sqrt(a + c*x^4)) - (a^(1/4)*c^(1/4)*e^2*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*d*(c*d^2 + a*e^2)^3*sqrt(a + c*x^4)) + (c^(5/4)*(B*c*d^3 - 3*A*c*d^2*e - 3*a*B*d*e^2 + a*A*e^3)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(3/4)*(c*d^2 + a*e^2)^3*sqrt(a + c*x^4)) - (c^(1/4)*e*(B*d - A*e)*(4*c*d^2 - sqrt(a)*sqrt(c)*d*e + 3*a*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(8*a^(1/4)*d^2*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4)) - (c^(1/4)*e*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*d*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)^2*sqrt(a + c*x^4)) - (c^(5/4)*e*(B*c*d^3 - 3*A*c*d^2*e - 3*a*B*d*e^2 + a*A*e^3)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(2*a^(1/4)*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)^3*sqrt(a + c*x^4)) + (c^(3/4)*(A*c^2*d^3 - a^2*B*e^3 - sqrt(a)*c^(3/2)*d^2*(B*d - 3*A*e) + 3*a*c*d*e*(B*d - A*e) + a^(3/2)*sqrt(c)*e^2*(3*B*d - A*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*a^(5/4)*(c*d^2 + a*e^2)^3*sqrt(a + c*x^4)) + (e*(sqrt(c)*d + sqrt(a)*e)*(3*c*d^2 + a*e^2)*(B*c*d^2 - 2*A*c*d*e - a*B*e^2)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(8*a^(1/4)*c^(1/4)*d^2*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)^3*sqrt(a + c*x^4)) + (a^(3/4)*c^(3/4)*e*((sqrt(c)*d)/sqrt(a) + e)^2*(B*c*d^3 - 3*A*c*d^2*e - 3*a*B*d*e^2 + a*A*e^3)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(4*d*(c*d^2 - a*e^2)*(c*d^2 + a*e^2)^3*sqrt(a + c*x^4)) + (3*e*(sqrt(c)*d + sqrt(a)*e)*(B*d - A*e)*(5*c^2*d^4 + 2*a*c*d^2*e^2 + a^2*e^4)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), 1/2))/(32*a^(1/4)*c^(1/4)*d^3*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 + a*e^2)^3*sqrt(a + c*x^4))]

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(A+B*x^2)*(d+e*x^2)^q*(a+c*x^4)^p*when*q*symbolic=#

    @test_int [(A + B*x^2)*(d + e*x^2)^q/(a + c*x^4), x, 6, ((A - (sqrt(-a)*B)/sqrt(c))*x*(d + e*x^2)^q*AppellF1(1/2, 1, -q, 3/2, -((sqrt(c)*x^2)/sqrt(-a)), -((e*x^2)/d)))/((1 + (e*x^2)/d)^q*(2*a)) + ((A + (sqrt(-a)*B)/sqrt(c))*x*(d + e*x^2)^q*AppellF1(1/2, 1, -q, 3/2, (sqrt(c)*x^2)/sqrt(-a), -((e*x^2)/d)))/((1 + (e*x^2)/d)^q*(2*a))]

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*P2(x)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^p*when*c*d^2-b*d*e+a*e^2=0=#

    #= ::Subsection:: =#
    #=Integrands*of*the*form*P2(x)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^p*when*c*d^2-b*d*e+a*e^2=0=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*P2(x)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^(p/2)*when*c*d^2-b*d*e+a*e^2=0=#

    #= ::Subsubsection:: =#
    #=p>0=#

    #= ::Subsubsection::Closed:: =#
    #=p<0=#

    @test_int [(2 + x^2)/((1 + x^2)*sqrt(2 + 3*x^2 + x^4)), x, 2, (sqrt(2)*(2 + x^2)*Elliptic.E(atan(x), 1/2))/(sqrt((2 + x^2)/(1 + x^2))*sqrt(2 + 3*x^2 + x^4))]

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*P2(x)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^p=#

    #= ::Subsection:: =#
    #=Integrands*of*the*form*(A+B*x^2)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^p=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(A+B*x^2)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^(p/2)=#

    #= ::Subsubsection:: =#
    #=p>0=#

    #= ::Subsubsection::Closed:: =#
    #=p<0=#

    @test_int [(A + B*x^2)*(d + e*x^2)^3/sqrt(a + b*x^2 + c*x^4), x, 6, (e*(7*A*c*e*(15*c*d - 4*b*e) + B*(105*c^2*d^2 + 24*b^2*e^2 - c*e*(84*b*d + 25*a*e)))*x*sqrt(a + b*x^2 + c*x^4))/(105*c^3) + (e^2*(21*B*c*d - 6*b*B*e + 7*A*c*e)*x^3*sqrt(a + b*x^2 + c*x^4))/(35*c^2) + (B*e^3*x^5*sqrt(a + b*x^2 + c*x^4))/(7*c) + ((7*A*c*e*(45*c^2*d^2 + 8*b^2*e^2 - 3*c*e*(10*b*d + 3*a*e)) + B*(105*c^3*d^3 - 48*b^3*e^3 - 21*c^2*d*e*(10*b*d + 9*a*e) + 8*b*c*e^2*(21*b*d + 13*a*e)))*x*sqrt(a + b*x^2 + c*x^4))/(105*c^(7/2)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*(7*A*c*e*(45*c^2*d^2 + 8*b^2*e^2 - 3*c*e*(10*b*d + 3*a*e)) + B*(105*c^3*d^3 - 48*b^3*e^3 - 21*c^2*d*e*(10*b*d + 9*a*e) + 8*b*c*e^2*(21*b*d + 13*a*e)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(105*c^(15/4)*sqrt(a + b*x^2 + c*x^4)) + (1/(210*c^(15/4)*sqrt(a + b*x^2 + c*x^4)))*(a^(1/4)*(7*A*c*e*(45*c^2*d^2 + 8*b^2*e^2 - 3*c*e*(10*b*d + 3*a*e)) + B*(105*c^3*d^3 - 48*b^3*e^3 - 21*c^2*d*e*(10*b*d + 9*a*e) + 8*b*c*e^2*(21*b*d + 13*a*e)) + (sqrt(c)*(7*A*c*(15*c^2*d^3 - 15*a*c*d*e^2 + 4*a*b*e^3) - a*B*e*(105*c^2*d^2 + 24*b^2*e^2 - c*e*(84*b*d + 25*a*e))))/sqrt(a))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))]
    @test_int [(A + B*x^2)*(d + e*x^2)^2/sqrt(a + b*x^2 + c*x^4), x, 5, (e*(10*B*c*d - 4*b*B*e + 5*A*c*e)*x*sqrt(a + b*x^2 + c*x^4))/(15*c^2) + (B*e^2*x^3*sqrt(a + b*x^2 + c*x^4))/(5*c) + ((10*A*c*e*(3*c*d - b*e) + B*(15*c^2*d^2 + 8*b^2*e^2 - c*e*(20*b*d + 9*a*e)))*x*sqrt(a + b*x^2 + c*x^4))/(15*c^(5/2)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*(10*A*c*e*(3*c*d - b*e) + B*(15*c^2*d^2 + 8*b^2*e^2 - c*e*(20*b*d + 9*a*e)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(15*c^(11/4)*sqrt(a + b*x^2 + c*x^4)) + (a^(1/4)*(10*A*c*e*(3*c*d - b*e) + B*(15*c^2*d^2 + 8*b^2*e^2 - c*e*(20*b*d + 9*a*e)) - (sqrt(c)*(2*a*B*e*(5*c*d - 2*b*e) - 5*A*c*(3*c*d^2 - a*e^2)))/sqrt(a))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(30*c^(11/4)*sqrt(a + b*x^2 + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^1/sqrt(a + b*x^2 + c*x^4), x, 4, (B*e*x*sqrt(a + b*x^2 + c*x^4))/(3*c) + ((3*B*c*d - 2*b*B*e + 3*A*c*e)*x*sqrt(a + b*x^2 + c*x^4))/(3*c^(3/2)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*(3*B*c*d - 2*b*B*e + 3*A*c*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(3*c^(7/4)*sqrt(a + b*x^2 + c*x^4)) + (a^(1/4)*(3*B*c*d - 2*b*B*e + 3*A*c*e + (sqrt(c)*(3*A*c*d - a*B*e))/sqrt(a))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(6*c^(7/4)*sqrt(a + b*x^2 + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^0/sqrt(a + b*x^2 + c*x^4), x, 3, (B*x*sqrt(a + b*x^2 + c*x^4))/(sqrt(c)*(sqrt(a) + sqrt(c)*x^2)) - (a^(1/4)*B*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(c^(3/4)*sqrt(a + b*x^2 + c*x^4)) + (a^(1/4)*(B + (A*sqrt(c))/sqrt(a))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*c^(3/4)*sqrt(a + b*x^2 + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^1*sqrt(a + b*x^2 + c*x^4)), x, 3, -(((B*d - A*e)*atan((sqrt(c*d^2 - b*d*e + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + b*x^2 + c*x^4))))/(2*sqrt(d)*sqrt(e)*sqrt(c*d^2 - b*d*e + a*e^2))) - ((sqrt(a)*B - A*sqrt(c))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*a^(1/4)*c^(1/4)*(sqrt(c)*d - sqrt(a)*e)*sqrt(a + b*x^2 + c*x^4)) + (a^(3/4)*((sqrt(c)*d)/sqrt(a) + e)^2*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(4*c^(1/4)*d*e*(c*d^2 - a*e^2)*sqrt(a + b*x^2 + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^2*sqrt(a + b*x^2 + c*x^4)), x, 6, (sqrt(c)*(B*d - A*e)*x*sqrt(a + b*x^2 + c*x^4))/(2*d*(c*d^2 - b*d*e + a*e^2)*(sqrt(a) + sqrt(c)*x^2)) - (e*(B*d - A*e)*x*sqrt(a + b*x^2 + c*x^4))/(2*d*(c*d^2 - b*d*e + a*e^2)*(d + e*x^2)) - ((B*(c*d^3 - a*d*e^2) - A*e*(3*c*d^2 - e*(2*b*d - a*e)))*atan((sqrt(c*d^2 - b*d*e + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + b*x^2 + c*x^4))))/(4*d^(3/2)*sqrt(e)*(c*d^2 - b*d*e + a*e^2)^(3/2)) - (a^(1/4)*c^(1/4)*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*d*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4)) + (A*c^(1/4)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*a^(1/4)*d*(sqrt(c)*d - sqrt(a)*e)*sqrt(a + b*x^2 + c*x^4)) + ((sqrt(c)*d + sqrt(a)*e)*(B*(c*d^3 - a*d*e^2) - A*e*(3*c*d^2 - e*(2*b*d - a*e)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(8*a^(1/4)*c^(1/4)*d^2*e*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^3*sqrt(a + b*x^2 + c*x^4)), x, 7, -((sqrt(c)*(3*A*e*(3*c*d^2 - e*(2*b*d - a*e)) - B*d*(5*c*d^2 - e*(2*b*d + a*e)))*x*sqrt(a + b*x^2 + c*x^4))/(8*d^2*(c*d^2 - b*d*e + a*e^2)^2*(sqrt(a) + sqrt(c)*x^2))) - (e*(B*d - A*e)*x*sqrt(a + b*x^2 + c*x^4))/(4*d*(c*d^2 - b*d*e + a*e^2)*(d + e*x^2)^2) + (e*(3*A*e*(3*c*d^2 - e*(2*b*d - a*e)) - B*d*(5*c*d^2 - e*(2*b*d + a*e)))*x*sqrt(a + b*x^2 + c*x^4))/(8*d^2*(c*d^2 - b*d*e + a*e^2)^2*(d + e*x^2)) - ((B*d*(3*c^2*d^4 - 10*a*c*d^2*e^2 + a*e^3*(4*b*d - a*e)) - A*e*(15*c^2*d^4 - 2*c*d^2*e*(10*b*d - 3*a*e) + e^2*(8*b^2*d^2 - 8*a*b*d*e + 3*a^2*e^2)))*atan((sqrt(c*d^2 - b*d*e + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + b*x^2 + c*x^4))))/(16*d^(5/2)*sqrt(e)*(c*d^2 - b*d*e + a*e^2)^(5/2)) + (a^(1/4)*c^(1/4)*(3*A*e*(3*c*d^2 - e*(2*b*d - a*e)) - B*d*(5*c*d^2 - e*(2*b*d + a*e)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(8*d^2*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4)) + (c^(1/4)*(sqrt(a)*sqrt(c)*d*(B*d - A*e) + a*e*(B*d + 3*A*e) + 4*A*d*(c*d - b*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(8*a^(1/4)*d^2*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4)) + ((sqrt(c)*d + sqrt(a)*e)*(B*d*(3*c^2*d^4 - 10*a*c*d^2*e^2 + a*e^3*(4*b*d - a*e)) - A*e*(15*c^2*d^4 - 2*c*d^2*e*(10*b*d - 3*a*e) + e^2*(8*b^2*d^2 - 8*a*b*d*e + 3*a^2*e^2)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(32*a^(1/4)*c^(1/4)*d^3*e*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4))]

    @test_int [(A + B*x^2)*(d + e*x^2)^3/(a + b*x^2 + c*x^4)^(3/2), x, 5, (x*(A*c*(b^2*c*d^3 - 2*a*c*d*(c*d^2 - 3*a*e^2) - a*b*e*(3*c*d^2 + a*e^2)) + a*B*(a*b^2*e^3 + 2*a*c*e*(3*c*d^2 - a*e^2) - b*c*d*(c*d^2 + 3*a*e^2)) - (a*B*(2*c*d - b*e)*(c^2*d^2 + b^2*e^2 - c*e*(b*d + 3*a*e)) + A*c*(a*b^2*e^3 + 2*a*c*e*(3*c*d^2 - a*e^2) - b*c*d*(c*d^2 + 3*a*e^2)))*x^2))/(a*c^2*(b^2 - 4*a*c)*sqrt(a + b*x^2 + c*x^4)) + (B*e^3*x*sqrt(a + b*x^2 + c*x^4))/(3*c^2) + ((a*B*(6*c^3*d^3 - 8*b^3*e^3 - 9*c^2*d*e*(b*d + 6*a*e) + b*c*e^2*(18*b*d + 29*a*e)) + 3*A*c*(2*a*b^2*e^3 + 6*a*c*e*(c*d^2 - a*e^2) - b*c*d*(c*d^2 + 3*a*e^2)))*x*sqrt(a + b*x^2 + c*x^4))/(3*a*c^(5/2)*(b^2 - 4*a*c)*(sqrt(a) + sqrt(c)*x^2)) - ((a*B*(6*c^3*d^3 - 8*b^3*e^3 - 9*c^2*d*e*(b*d + 6*a*e) + b*c*e^2*(18*b*d + 29*a*e)) + 3*A*c*(2*a*b^2*e^3 + 6*a*c*e*(c*d^2 - a*e^2) - b*c*d*(c*d^2 + 3*a*e^2)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(3*a^(3/4)*c^(11/4)*(b^2 - 4*a*c)*sqrt(a + b*x^2 + c*x^4)) - ((3*A*c^3*d^3 - 5*a^2*B*c*e^3 - 3*sqrt(a)*c^(5/2)*d^2*(B*d + 3*A*e) + a*e*(3*c*d - 2*b*e)*(3*B*c*d - 4*b*B*e + 3*A*c*e) + 3*a^(3/2)*sqrt(c)*e^2*(9*B*c*d - 4*b*B*e + 3*A*c*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(6*a^(3/4)*(b - 2*sqrt(a)*sqrt(c))*c^(11/4)*sqrt(a + b*x^2 + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^2/(a + b*x^2 + c*x^4)^(3/2), x, 4, -((x*(a*B*(b*c*d^2 - 4*a*c*d*e + a*b*e^2) - A*c*(b^2*d^2 - 2*a*b*d*e - 2*a*(c*d^2 - a*e^2)) - (A*c*(b*c*d^2 - 4*a*c*d*e + a*b*e^2) - a*B*(2*c^2*d^2 + b^2*e^2 - 2*c*e*(b*d + a*e)))*x^2))/(a*c*(b^2 - 4*a*c)*sqrt(a + b*x^2 + c*x^4))) - ((A*c*(b*c*d^2 - 4*a*c*d*e + a*b*e^2) - 2*a*B*(c^2*d^2 + b^2*e^2 - c*e*(b*d + 3*a*e)))*x*sqrt(a + b*x^2 + c*x^4))/(a*c^(3/2)*(b^2 - 4*a*c)*(sqrt(a) + sqrt(c)*x^2)) + ((A*c*(b*c*d^2 - 4*a*c*d*e + a*b*e^2) - 2*a*B*(c^2*d^2 + b^2*e^2 - c*e*(b*d + 3*a*e)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(a^(3/4)*c^(7/4)*(b^2 - 4*a*c)*sqrt(a + b*x^2 + c*x^4)) - ((A*c^2*d^2 + 3*a^(3/2)*B*sqrt(c)*e^2 - sqrt(a)*c^(3/2)*d*(B*d + 2*A*e) + a*e*(2*B*c*d - 2*b*B*e + A*c*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*a^(3/4)*(b - 2*sqrt(a)*sqrt(c))*c^(7/4)*sqrt(a + b*x^2 + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^1/(a + b*x^2 + c*x^4)^(3/2), x, 4, -((x*(a*B*(b*d - 2*a*e) - A*(b^2*d - 2*a*c*d - a*b*e) - (A*c*(b*d - 2*a*e) - a*B*(2*c*d - b*e))*x^2))/(a*(b^2 - 4*a*c)*sqrt(a + b*x^2 + c*x^4))) - ((A*c*(b*d - 2*a*e) - a*B*(2*c*d - b*e))*x*sqrt(a + b*x^2 + c*x^4))/(a*sqrt(c)*(b^2 - 4*a*c)*(sqrt(a) + sqrt(c)*x^2)) + ((A*c*(b*d - 2*a*e) - a*B*(2*c*d - b*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(a^(3/4)*c^(3/4)*(b^2 - 4*a*c)*sqrt(a + b*x^2 + c*x^4)) + ((sqrt(a)*B - A*sqrt(c))*(sqrt(c)*d - sqrt(a)*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*a^(3/4)*(b - 2*sqrt(a)*sqrt(c))*c^(3/4)*sqrt(a + b*x^2 + c*x^4))]
    @test_int [(A + B*x^2)*(d + e*x^2)^0/(a + b*x^2 + c*x^4)^(3/2), x, 4, (x*(A*b^2 - a*b*B - 2*a*A*c + (A*b - 2*a*B)*c*x^2))/(a*(b^2 - 4*a*c)*sqrt(a + b*x^2 + c*x^4)) - ((A*b - 2*a*B)*sqrt(c)*x*sqrt(a + b*x^2 + c*x^4))/(a*(b^2 - 4*a*c)*(sqrt(a) + sqrt(c)*x^2)) + ((A*b - 2*a*B)*c^(1/4)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(a^(3/4)*(b^2 - 4*a*c)*sqrt(a + b*x^2 + c*x^4)) + ((sqrt(a)*B - A*sqrt(c))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*a^(3/4)*(b - 2*sqrt(a)*sqrt(c))*c^(1/4)*sqrt(a + b*x^2 + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^1*(a + b*x^2 + c*x^4)^(3/2)), x, 9, -((x*(a*b*c*(B*d - A*e) - (b^2 - 2*a*c)*(A*c*d - A*b*e + a*B*e) + c*(a*B*(2*c*d - b*e) - A*(b*c*d - b^2*e + 2*a*c*e))*x^2))/(a*(b^2 - 4*a*c)*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4))) + (sqrt(c)*(a*B*(2*c*d - b*e) - A*(b*c*d - b^2*e + 2*a*c*e))*x*sqrt(a + b*x^2 + c*x^4))/(a*(b^2 - 4*a*c)*(c*d^2 - b*d*e + a*e^2)*(sqrt(a) + sqrt(c)*x^2)) - (e^(3/2)*(B*d - A*e)*atan((sqrt(c*d^2 - b*d*e + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + b*x^2 + c*x^4))))/(2*sqrt(d)*(c*d^2 - b*d*e + a*e^2)^(3/2)) - (c^(1/4)*(a*B*(2*c*d - b*e) - A*(b*c*d - b^2*e + 2*a*c*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(a^(3/4)*(b^2 - 4*a*c)*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4)) + ((sqrt(a)*B - A*sqrt(c))*c^(1/4)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2 - b/(4*sqrt(a)*sqrt(c))))/(2*a^(3/4)*(b - 2*sqrt(a)*sqrt(c))*(sqrt(c)*d - sqrt(a)*e)*sqrt(a + b*x^2 + c*x^4)) + (a^(3/4)*e*((sqrt(c)*d)/sqrt(a) + e)^2*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(4*c^(1/4)*d*(c*d^2 - a*e^2)*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4)), -((x*(a*b*c*(B*d - A*e) - (b^2 - 2*a*c)*(A*c*d - A*b*e + a*B*e) + c*(a*B*(2*c*d - b*e) - A*(b*c*d - b^2*e + 2*a*c*e))*x^2))/(a*(b^2 - 4*a*c)*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4))) + (sqrt(c)*(a*B*(2*c*d - b*e) - A*(b*c*d - b^2*e + 2*a*c*e))*x*sqrt(a + b*x^2 + c*x^4))/(a*(b^2 - 4*a*c)*(c*d^2 - b*d*e + a*e^2)*(sqrt(a) + sqrt(c)*x^2)) - (e^(3/2)*(B*d - A*e)*atan((sqrt(c*d^2 - b*d*e + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + b*x^2 + c*x^4))))/(2*sqrt(d)*(c*d^2 - b*d*e + a*e^2)^(3/2)) - (c^(1/4)*(a*B*(2*c*d - b*e) - A*(b*c*d - b^2*e + 2*a*c*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(a^(3/4)*(b^2 - 4*a*c)*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4)) - (c^(1/4)*e*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*a^(1/4)*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4)) - (c^(1/4)*(a*B*e - sqrt(a)*sqrt(c)*(B*d - A*e) + A*(c*d - b*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*a^(3/4)*(b - 2*sqrt(a)*sqrt(c))*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4)) + (a^(3/4)*e*((sqrt(c)*d)/sqrt(a) + e)^2*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(4*c^(1/4)*d*(c*d^2 - a*e^2)*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4))]
    @test_int [(A + B*x^2)/((d + e*x^2)^2*(a + b*x^2 + c*x^4)^(3/2)), x, 15, (x*(a*b*c*(A*e*(2*c*d - b*e) - B*(c*d^2 - a*e^2)) + (b^2 - 2*a*c)*(a*B*e*(2*c*d - b*e) + A*(c^2*d^2 + b^2*e^2 - c*e*(2*b*d + a*e))) - c*(a*B*(2*c^2*d^2 + b^2*e^2 - 2*c*e*(b*d + a*e)) + A*(2*b^2*c*d*e - 4*a*c^2*d*e - b^3*e^2 - b*c*(c*d^2 - 3*a*e^2)))*x^2))/(a*(b^2 - 4*a*c)*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4)) + (sqrt(c)*(a*B*d*(-4*c^2*d^2 - 3*b^2*e^2 + 4*c*e*(b*d + 2*a*e)) + A*(2*b^3*d*e^2 + 2*b*c*d*(c*d^2 - 3*a*e^2) - 4*a*c*e*(-2*c*d^2 + a*e^2) + b^2*(-4*c*d^2*e + a*e^3)))*x*sqrt(a + b*x^2 + c*x^4))/(2*a*(-b^2 + 4*a*c)*d*(c*d^2 + e*((-b)*d + a*e))^2*(sqrt(a) + sqrt(c)*x^2)) - (e^3*(B*d - A*e)*x*sqrt(a + b*x^2 + c*x^4))/(2*d*(c*d^2 - b*d*e + a*e^2)^2*(d + e*x^2)) + (e^(3/2)*(A*e*(7*c*d^2 - e*(4*b*d - a*e)) - B*d*(5*c*d^2 - e*(2*b*d + a*e)))*atan((sqrt(c*d^2 - b*d*e + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + b*x^2 + c*x^4))))/(4*d^(3/2)*(c*d^2 - b*d*e + a*e^2)^(5/2)) - (c^(1/4)*(a*B*d*(4*c^2*d^2 + 3*b^2*e^2 - 4*c*e*(b*d + 2*a*e)) - A*(2*b^3*d*e^2 + 2*b*c*d*(c*d^2 - 3*a*e^2) - 4*a*c*e*(-2*c*d^2 + a*e^2) + b^2*(-4*c*d^2*e + a*e^3)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), 1/2 - b/(4*sqrt(a)*sqrt(c))))/(2*a^(3/4)*(b^2 - 4*a*c)*d*(c*d^2 + e*((-b)*d + a*e))^2*sqrt(a + b*x^2 + c*x^4)) + (c^(1/4)*(a*sqrt(c)*e*(B*d - 2*A*e) + sqrt(a)*(B*d - A*e)*(c*d - b*e) + A*sqrt(c)*d*((-c)*d + b*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), 1/2 - b/(4*sqrt(a)*sqrt(c))))/(2*a^(3/4)*(b - 2*sqrt(a)*sqrt(c))*d*((-sqrt(c))*d + sqrt(a)*e)*((-c)*d^2 + e*(b*d - a*e))*sqrt(a + b*x^2 + c*x^4)) - (e*(sqrt(c)*d + sqrt(a)*e)*(A*e*(7*c*d^2 - e*(4*b*d - a*e)) - B*d*(5*c*d^2 - e*(2*b*d + a*e)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(8*a^(1/4)*c^(1/4)*d^2*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4)), (1/(a*(b^2 - 4*a*c)*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4)))*x*(a*b*c*(A*e*(2*c*d - b*e) - B*(c*d^2 - a*e^2)) + (b^2 - 2*a*c)*(a*B*e*(2*c*d - b*e) + A*(c^2*d^2 + b^2*e^2 - c*e*(2*b*d + a*e))) - c*(a*B*(2*c^2*d^2 + b^2*e^2 - 2*c*e*(b*d + a*e)) + A*(2*b^2*c*d*e - 4*a*c^2*d*e - b^3*e^2 - b*c*(c*d^2 - 3*a*e^2)))*x^2) + (sqrt(c)*e^2*(B*d - A*e)*x*sqrt(a + b*x^2 + c*x^4))/(2*d*(c*d^2 - b*d*e + a*e^2)^2*(sqrt(a) + sqrt(c)*x^2)) + (sqrt(c)*(a*B*(2*c^2*d^2 + b^2*e^2 - 2*c*e*(b*d + a*e)) + A*(2*b^2*c*d*e - 4*a*c^2*d*e - b^3*e^2 - b*c*(c*d^2 - 3*a*e^2)))*x*sqrt(a + b*x^2 + c*x^4))/(a*(b^2 - 4*a*c)*(c*d^2 - b*d*e + a*e^2)^2*(sqrt(a) + sqrt(c)*x^2)) - (e^3*(B*d - A*e)*x*sqrt(a + b*x^2 + c*x^4))/(2*d*(c*d^2 - b*d*e + a*e^2)^2*(d + e*x^2)) - (e^(3/2)*(B*d - A*e)*(3*c*d^2 - e*(2*b*d - a*e))*atan((sqrt(c*d^2 - b*d*e + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + b*x^2 + c*x^4))))/(4*d^(3/2)*(c*d^2 - b*d*e + a*e^2)^(5/2)) + (e^(3/2)*(A*e*(2*c*d - b*e) - B*(c*d^2 - a*e^2))*atan((sqrt(c*d^2 - b*d*e + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + b*x^2 + c*x^4))))/(2*sqrt(d)*(c*d^2 - b*d*e + a*e^2)^(5/2)) - (a^(1/4)*c^(1/4)*e^2*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*d*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4)) - (c^(1/4)*(a*B*(2*c^2*d^2 + b^2*e^2 - 2*c*e*(b*d + a*e)) + A*(2*b^2*c*d*e - 4*a*c^2*d*e - b^3*e^2 - b*c*(c*d^2 - 3*a*e^2)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.E(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(a^(3/4)*(b^2 - 4*a*c)*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4)) - (c^(1/4)*e*(B*d - A*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*a^(1/4)*d*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 - b*d*e + a*e^2)*sqrt(a + b*x^2 + c*x^4)) + (c^(1/4)*e*(A*e*(2*c*d - b*e) - B*(c*d^2 - a*e^2))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*a^(1/4)*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4)) - (c^(1/4)*(a^(3/2)*B*sqrt(c)*e^2 + A*(c*d - b*e)^2 + a*e*(2*B*c*d - b*B*e - A*c*e) - sqrt(a)*sqrt(c)*(B*c*d^2 - A*e*(2*c*d - b*e)))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.F(2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(2*a^(3/4)*(b - 2*sqrt(a)*sqrt(c))*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4)) + (e*(sqrt(c)*d + sqrt(a)*e)*(B*d - A*e)*(3*c*d^2 - e*(2*b*d - a*e))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(8*a^(1/4)*c^(1/4)*d^2*(sqrt(c)*d - sqrt(a)*e)*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4)) - (a^(3/4)*e*((sqrt(c)*d)/sqrt(a) + e)^2*(A*e*(2*c*d - b*e) - B*(c*d^2 - a*e^2))*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(4*c^(1/4)*d*(c*d^2 - a*e^2)*(c*d^2 - b*d*e + a*e^2)^2*sqrt(a + b*x^2 + c*x^4))]

    @test_int [(sqrt(a) + sqrt(c)*x^2)/((d + e*x^2)*sqrt(a + b*x^2 + c*x^4)), x, 1, -(((sqrt(c)*d - sqrt(a)*e)*atan((sqrt(c*d^2 - b*d*e + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + b*x^2 + c*x^4))))/(2*sqrt(d)*sqrt(e)*sqrt(c*d^2 - b*d*e + a*e^2))) + ((sqrt(c)*d + sqrt(a)*e)*(sqrt(a) + sqrt(c)*x^2)*sqrt((a + b*x^2 + c*x^4)/(sqrt(a) + sqrt(c)*x^2)^2)*Elliptic.Pi(-((sqrt(c)*d - sqrt(a)*e)^2/(4*sqrt(a)*sqrt(c)*d*e)), 2*atan((c^(1/4)*x)/a^(1/4)), (1/4)*(2 - b/(sqrt(a)*sqrt(c)))))/(4*a^(1/4)*c^(1/4)*d*e*sqrt(a + b*x^2 + c*x^4))]

    @test_int [(1 + sqrt(c/a)*x^2)/((d + e*x^2)*sqrt(a + b*x^2 + c*x^4)), x, 1, -(((sqrt(c/a)*d - e)*atan((sqrt(c*d^2 - b*d*e + a*e^2)*x)/(sqrt(d)*sqrt(e)*sqrt(a + b*x^2 + c*x^4))))/(2*sqrt(d)*sqrt(e)*sqrt(c*d^2 - b*d*e + a*e^2))) + ((sqrt(c/a)*d + e)*(1 + sqrt(c/a)*x^2)*sqrt((a + b*x^2 + c*x^4)/(a*(1 + sqrt(c/a)*x^2)^2))*Elliptic.Pi(-((sqrt(c/a)*d - e)^2/(4*sqrt(c/a)*d*e)), 2*atan((c/a)^(1/4)*x), (1/4)*(2 - (b*sqrt(c/a))/c)))/(4*(c/a)^(1/4)*d*e*sqrt(a + b*x^2 + c*x^4))]

    @test_int [(946 + 315*x^2)/((7 + 5*x^2)*sqrt(2 + 3*x^2 + x^4)), x, 4, (631*(1 + x^2)*sqrt((2 + x^2)/(1 + x^2))*Elliptic.F(atan(x), 1/2))/(2*sqrt(2)*sqrt(2 + 3*x^2 + x^4)) - (2525*(2 + x^2)*Elliptic.Pi(2/7, atan(x), 1/2))/(14*sqrt(2)*sqrt((2 + x^2)/(1 + x^2))*sqrt(2 + 3*x^2 + x^4))]

    #= ::Subsection:: =#
    #=Integrands*of*the*form*(A+B*x^2)*(d+e*x^2)^(q/2)*(a+b*x^2+c*x^4)^p=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(A+B*x^2)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^p*when*q*symbolic=#

    @test_int [(A + B*x^2)*(d + e*x^2)^q/(a + b*x^2 + c*x^4), x, 6, ((B - (b*B - 2*A*c)/sqrt(b^2 - 4*a*c))*x*(d + e*x^2)^q*AppellF1(1/2, 1, -q, 3/2, -((2*c*x^2)/(b - sqrt(b^2 - 4*a*c))), -((e*x^2)/d)))/((1 + (e*x^2)/d)^q*(b - sqrt(b^2 - 4*a*c))) + ((B + (b*B - 2*A*c)/sqrt(b^2 - 4*a*c))*x*(d + e*x^2)^q*AppellF1(1/2, 1, -q, 3/2, -((2*c*x^2)/(b + sqrt(b^2 - 4*a*c))), -((e*x^2)/d)))/((1 + (e*x^2)/d)^q*(b + sqrt(b^2 - 4*a*c)))]

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*x^m*P2(x)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^p=#

    #= ::Subsection:: =#
    #=Integrands*of*the*form*x^m*P2(x)*(d+e*x^2)^q*(a+b*x^2+c*x^4)^p=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*x^m*P2(x)*(d+e*x^2)^(q/2)*(a+b*x^2+c*x^4)^p=#

    @test_int [x*(1 + 2*x^2)/(sqrt(1 + x^2)*(1 + x^2 + x^4)), x, 11, (-(1/2))*atan(sqrt(3) - 2*sqrt(1 + x^2)) + (1/2)*atan(sqrt(3) + 2*sqrt(1 + x^2)) + (1/4)*sqrt(3)*log(2 + x^2 - sqrt(3)*sqrt(1 + x^2)) - (1/4)*sqrt(3)*log(2 + x^2 + sqrt(3)*sqrt(1 + x^2))]

    #= ::Title::Closed:: =#
    #=Integrands*of*the*form*(d+e*x^4)^q*(a+b*x^2+c*x^4)^p=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(d+e*x^4)^q*(a+b*x^2+c*x^4)^(p/2)=#

    #= ::Subsubsection::Closed:: =#
    #=p>0=#

    @test_int [sqrt(a + b*x^2 + c*x^4)/(a*d - c*d*x^4), x, 4, -((sqrt(b - 2*sqrt(a)*sqrt(c))*atanh((sqrt(b - 2*sqrt(a)*sqrt(c))*x)/sqrt(a + b*x^2 + c*x^4)))/(4*sqrt(a)*sqrt(c)*d)) + (sqrt(b + 2*sqrt(a)*sqrt(c))*atanh((sqrt(b + 2*sqrt(a)*sqrt(c))*x)/sqrt(a + b*x^2 + c*x^4)))/(4*sqrt(a)*sqrt(c)*d)]
    @test_int [sqrt(a + b*x^2 - c*x^4)/(a*d + c*d*x^4), x, 1, -((sqrt(b + sqrt(b^2 + 4*a*c))*atan((sqrt(b + sqrt(b^2 + 4*a*c))*x*(b - sqrt(b^2 + 4*a*c) - 2*c*x^2))/(2*sqrt(2)*sqrt(a)*sqrt(c)*sqrt(a + b*x^2 - c*x^4))))/(2*sqrt(2)*sqrt(a)*sqrt(c)*d)) + (sqrt(-b + sqrt(b^2 + 4*a*c))*atanh((sqrt(-b + sqrt(b^2 + 4*a*c))*x*(b + sqrt(b^2 + 4*a*c) - 2*c*x^2))/(2*sqrt(2)*sqrt(a)*sqrt(c)*sqrt(a + b*x^2 - c*x^4))))/(2*sqrt(2)*sqrt(a)*sqrt(c)*d)]

    #= ::Subsubsection:: =#
    #=p<0=#

    #= ::Title::Closed:: =#
    #=Integrands*of*the*form*x^m*(d+e*x+f*x^2)^(n/2)*(a^2+2*a*b*x^2+b^2*x^4)^(p/2)=#

    @test_int [x^1*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*sqrt(c + e*x + d*x^2), x, 6, (e*(12*b*c*d - 16*a*d^2 - 7*b*e^2)*(e + 2*d*x)*sqrt(c + e*x + d*x^2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(128*d^4*(a + b*x^2)) + (b*x^2*(c + e*x + d*x^2)^(3/2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(5*d*(a + b*x^2)) - ((32*b*c*d - 80*a*d^2 - 35*b*e^2 + 42*b*d*e*x)*(c + e*x + d*x^2)^(3/2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(240*d^3*(a + b*x^2)) + (e*(4*c*d - e^2)*(12*b*c*d - 16*a*d^2 - 7*b*e^2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*atanh((e + 2*d*x)/(2*sqrt(d)*sqrt(c + e*x + d*x^2))))/(256*d^(9/2)*(a + b*x^2))]
    @test_int [x^0*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*sqrt(c + e*x + d*x^2), x, 6, -(((4*b*c*d - 16*a*d^2 - 5*b*e^2)*(e + 2*d*x)*sqrt(c + e*x + d*x^2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(64*d^3*(a + b*x^2))) - (5*b*e*(c + e*x + d*x^2)^(3/2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(24*d^2*(a + b*x^2)) + (b*x*(c + e*x + d*x^2)^(3/2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(4*d*(a + b*x^2)) - ((4*c*d - e^2)*(4*b*c*d - 16*a*d^2 - 5*b*e^2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*atanh((e + 2*d*x)/(2*sqrt(d)*sqrt(c + e*x + d*x^2))))/(128*d^(7/2)*(a + b*x^2))]
    @test_int [1/x^1*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*sqrt(c + e*x + d*x^2), x, 8, ((8*a*d^2 - b*e^2 - 2*b*d*e*x)*sqrt(c + e*x + d*x^2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(8*d^2*(a + b*x^2)) + (b*(c + e*x + d*x^2)^(3/2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(3*d*(a + b*x^2)) + (e*(8*a*d^2 - b*(4*c*d - e^2))*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*atanh((e + 2*d*x)/(2*sqrt(d)*sqrt(c + e*x + d*x^2))))/(16*d^(5/2)*(a + b*x^2)) - (a*sqrt(c)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*atanh((2*c + e*x)/(2*sqrt(c)*sqrt(c + e*x + d*x^2))))/(a + b*x^2)]
    @test_int [1/x^2*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*sqrt(c + e*x + d*x^2), x, 8, (((b*c + 4*a*d)*e + 2*d*(b*c + 2*a*d)*x)*sqrt(c + e*x + d*x^2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(4*c*d*(a + b*x^2)) - (a*(c + e*x + d*x^2)^(3/2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(c*x*(a + b*x^2)) + ((4*b*c*d + 8*a*d^2 - b*e^2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*atanh((e + 2*d*x)/(2*sqrt(d)*sqrt(c + e*x + d*x^2))))/(8*d^(3/2)*(a + b*x^2)) - (a*e*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*atanh((2*c + e*x)/(2*sqrt(c)*sqrt(c + e*x + d*x^2))))/(2*sqrt(c)*(a + b*x^2))]
    @test_int [1/x^3*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*sqrt(c + e*x + d*x^2), x, 8, ((a*e + 2*(2*b*c + a*d)*x)*sqrt(c + e*x + d*x^2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(4*c*x*(a + b*x^2)) - (a*(c + e*x + d*x^2)^(3/2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(2*c*x^2*(a + b*x^2)) + (b*e*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*atanh((e + 2*d*x)/(2*sqrt(d)*sqrt(c + e*x + d*x^2))))/(2*sqrt(d)*(a + b*x^2)) - ((8*b*c^2 + 4*a*c*d - a*e^2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*atanh((2*c + e*x)/(2*sqrt(c)*sqrt(c + e*x + d*x^2))))/(8*c^(3/2)*(a + b*x^2))]
    @test_int [1/x^4*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*sqrt(c + e*x + d*x^2), x, 8, ((2*a*c*e - (8*b*c^2 - a*e^2)*x)*sqrt(c + e*x + d*x^2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(8*c^2*x^2*(a + b*x^2)) - (a*(c + e*x + d*x^2)^(3/2)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4))/(3*c*x^3*(a + b*x^2)) + (b*sqrt(d)*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*atanh((e + 2*d*x)/(2*sqrt(d)*sqrt(c + e*x + d*x^2))))/(a + b*x^2) - (e*(8*b*c^2 - a*(4*c*d - e^2))*sqrt(a^2 + 2*a*b*x^2 + b^2*x^4)*atanh((2*c + e*x)/(2*sqrt(c)*sqrt(c + e*x + d*x^2))))/(16*c^(5/2)*(a + b*x^2))]
    end

max_stars_repo_path: test/1 Algebraic functions/1.2 Trinomial products/1.2.2 Quartic/1.2.2.7 P(x) (d+e x^2)^q (a+b x^2+c x^4)^p.jl


text:
# We write the tests like this to match the style of `testutils.jl`.
# We define this here, rather than in `testutils.jl` because we're not allowed to change the
# contents of that file, which should always match the PDMats v0.10 version of that file
# https://github.com/JuliaStats/PDMats.jl/blob/v0.10.0/test/testutils.jl
function pdtest_kron(C::AbstractPDMat, Cmat::Matrix, verbose::Int)
    Pd = PDMat(C + I)
    Psd = PSDMat(C + I)
    M = rand(eltype(C), size(Cmat))
    v = vec(M)
    for x in (Pd, Psd, M, v)
        _pdt(verbose, "kron with $(typeof(x))")
        @test kron(C, x) ≈ kron(Cmat, x)
        @test kron(x, C) ≈ kron(x, Cmat)
    end
end

@testset "PSDMat" begin
    verbose = 1
    @testset "Positive definite" begin
        M = TEST_MATRICES["Positive definite"]
        pivoted = cholesky(M, Val(true))
        C = PSDMat(M, pivoted)
        test_pdmat(
            C,
            M,
            cmat_eq=false,
            verbose=verbose,
            t_triprod=false,    # fails because of some floating point issues.
            t_whiten=false,     # Whiten doesn't produce an identity matrix with the upper triangular matrix
        )
        pdtest_kron(C, C.mat, verbose)
    end
    @testset "Positive semi-definite" begin
        M = TEST_MATRICES["Positive semi-definite"]
        @test !isposdef(M)
        pivoted = cholesky(M, Val(true); check=false)
        C = PSDMat(M, pivoted)
        test_pdmat(
            C,
            M,
            cmat_eq=true,
            verbose=verbose,
            t_logdet=false,     # We get an expected domain error
            t_rdiv=false,       # We get an expected RankDeficientExceptions
            t_quad=false,       # We get an expected RankDeficientExceptions
            t_triprod=false,    # fails because of expected RankDeficientExceptions
            t_whiten=false,     # Test calls chol_lower on the matrix which throws a PosDefException
        )
        pdtest_kron(C, C.mat, verbose)
    end
end

@testset "Degenerate MvNormal" begin
    # Similar test used in Distributions.jl/test/mvnormal.jl test_mvnormal
    means = rand(4)
    n_tsamples = 10^6

    @testset "Positive definite" begin
        g = MvNormal(means, PSDMat(TEST_MATRICES["Positive definite"]))
        d = length(g)
        μ = mean(g)
        Σ = cov(g)
        @test partype(g) == Float64
        @test isa(μ, Vector{Float64})
        @test isa(Σ, Matrix{Float64})
        @test length(μ) == d
        @test size(Σ) == (d, d)
        @test var(g)     ≈ diag(Σ)
        @test entropy(g) ≈ 0.5 * logdet(2π * ℯ * Σ)
        ldcov = logdetcov(g)
        @test ldcov ≈ logdet(Σ)
        @test g == typeof(g)(params(g)...)

        # test sampling for AbstractMatrix (here, a SubArray):
        subX = view(rand(d, 2d), :, 1:d)
        @test isa(rand!(g, subX), SubArray)

        # sampling
        @test isa(rand(g), Vector{Float64})

        X = rand(MersenneTwister(14), g, n_tsamples)
        Y = rand(MersenneTwister(14), g, n_tsamples)
        @test X == Y

        # evaluation of sqmahal & logpdf
        U = X .- μ
        sqm = vec(sum(U .* (Σ \ U), dims=1))
        for i = 1:min(100, n_tsamples)
            @test sqmahal(g, X[:,i]) ≈ sqm[i]
        end
        @test sqmahal(g, X) ≈ sqm

        lp = -0.5 .* sqm .- 0.5 * (d * log(2.0 * pi) + ldcov)
        for i = 1:min(100, n_tsamples)
            @test logpdf(g, X[:,i]) ≈ lp[i]
        end
        @test logpdf(g, X) ≈ lp

        # log likelihood
        @test loglikelihood(g, X) ≈ sum([Distributions._logpdf(g, X[:,i]) for i in 1:size(X, 2)])
    end

    @testset "Positive semi-definite" begin
        g = MvNormal(means, PSDMat(TEST_MATRICES["Positive semi-definite"]))
        d = length(g)
        μ = mean(g)
        Σ = cov(g)
        @test partype(g) == Float64
        @test isa(μ, Vector{Float64})
        @test isa(Σ, Matrix{Float64})
        @test length(μ) == d
        @test size(Σ) == (d, d)
        @test var(g) ≈ diag(Σ)
        etrpy = entropy(g)
        @test_throws DomainError etrpy ≈ 0.5 * logdet(2π * ℯ * Σ)
        ldcov = logdetcov(g)
        @test_throws DomainError ldcov ≈ logdet(Σ)
        @test g == typeof(g)(params(g)...)

        # test sampling for AbstractMatrix (here, a SubArray):
        subX = view(rand(d, 2d), :, 1:d)
        @test isa(rand!(g, subX), SubArray)

        # sampling
        @test isa(rand(g), Vector{Float64})

        X = rand(MersenneTwister(14), g, n_tsamples)
        Y = rand(MersenneTwister(14), g, n_tsamples)
        @test X == Y

        logpdf(g, X)
        sqmahal(g, X)
        loglikelihood(g, X)

        # sqmahal, logpdf and loglikelihood calculation should throw RankDeficientExceptions
        # for degenerate MvNormal Distributions
        # but loglikelihood used to give one and now doesn't, and the other two never did
    end
end

ext: jl


text:
using TensorNetworkCodes
using Test

@testset "edges" begin
    code = TensorNetworkCode(five_qubit_code())
    @test Set(edges(code)) == Set([Set([-1, i]) for i in 1:5])
end

@testset "new_indices" begin
    code1 = TensorNetworkCode(five_qubit_code())
    code1 = contract(code1,TensorNetworkCode(steane_code()),[[1,1],[2,2]])
    code2 = new_indices(code1)
    # check number of indices is correct
    length(edge_indices(code1)) == length(edge_indices(code2))
    length(node_indices(code1)) == length(node_indices(code2))
    # let's make sure all indices are new!
    @test length(intersect(edge_indices(code2),edge_indices(code1))) == 0
end

@testset "nodes" begin
    code = TensorNetworkCode(five_qubit_code())
    @test nodes(code) == [-1, 1, 2, 3, 4, 5]
end

@testset "num_nodes" begin
    code = TensorNetworkCode(five_qubit_code())
    @test num_nodes(code) == 6  # 5 physical and 1 logical qubits
end

@testset "physical_neighbours" begin
    code = TensorNetworkCode(five_qubit_code())
    @test physical_neighbours(code, -1) == Set(1:5)
    @test physical_neighbours(code, 2) == Set()
end

@testset "set_coords!" begin
    code = TensorNetworkCode(five_qubit_code())
    old_coords = deepcopy(coords(code))
    @test coords(code) == old_coords
    # let's put them in a line
    new_coords = [[0, i] for i in 1:num_nodes(code)]
    set_coords!(code, new_coords)
    @test coords(code) != old_coords
    @test [coords(code, n) for n in nodes(code)] == new_coords
end

@testset "shift_coords!" begin
    code = TensorNetworkCode(five_qubit_code())
    old_coords = deepcopy(coords(code))
    @test coords(code) == old_coords
    # let's shift a bit
    shift = [1, 2]
    shift_coords!(code, shift)
    @test coords(code) != old_coords
    @test coords(code) == Dict([k, v + shift] for (k, v) in old_coords)
end


text:
module Outliernicers

using Dates
using DataFrames
using Random
using Statistics
using StatsBase: iqr, quantile, sample

export fit!,transform!
export Outliernicer

import TSML.TSMLTypes.fit! # to overload
import TSML.TSMLTypes.transform! # to overload

using TSML.TSMLTypes
using TSML.TSMLTransformers
using TSML.Utils

"""
    Outliernicer(Dict())

Detects outliers below or above (q25-iqr,q75+iqr)
and replace them with missing so that ValNNer can
use nearest neighbors to replace the missings.
"""
mutable struct Outliernicer <: Transformer
  model
  args

  function Outliernicer(args=Dict())
    default_args = Dict(
        :dateinterval => Dates.Hour(1),
        :nnsize => 1,
        :missdirection => :symmetric
    )
    new(nothing, mergedict(default_args, args))
  end
end

function fit!(st::Outliernicer, features::T, labels::Vector=[]) where {T<:Union{Vector,Matrix,DataFrame}}
  typeof(features) <: DataFrame || error("Outliernicer.fit!: data should be a dataframe: Date,Val ")
  ncol(features) == 2 || error("dataframe must have 2 columns: Date, Val")
  st.model = st.args
end

function transform!(st::Outliernicer, features::T) where {T<:Union{Vector,Matrix,DataFrame}}
  features != [] || return DataFrame()
  typeof(features) <: DataFrame || error("Outliernicer.fit!: data should be a dataframe: Date,Val ")
  ncol(features) == 2 || error("dataframe must have 2 columns: Date, Val")
  sum(names(features) .== (:Date,:Value))  == 2 || error("wrong column names")
  mfeatures=deepcopy(features)
  rvals = mfeatures[:Value]
  # compute the outlier range
  # setup to store both missing and numbers
  mvals = Array{Union{Missing,eltype(rvals)},1}(missing,length(rvals))
  mvals .= rvals
  crvals = skipmissing(rvals) # stat of non-missing
  miqr = iqr(crvals)
  q25,q75 = quantile(crvals,[0.25,0.75])
  lower=q25-miqr; upper=q75+miqr
  missindx = findall(x -> !ismissing(x) && (x > upper || x < lower),rvals)
  mvals[missindx] .= missing
  mfeatures[:Value] = mvals
  # use ValNNer to replace missings
  valnner = DateValNNer(st.args)
  fit!(valnner,mfeatures)
  resdf = transform!(valnner,mfeatures)
  resdf[:Value] = collect(skipmissing(resdf[:Value]))
  resdf
end

end


text:
# Activate VectorAutoregressions project first
cd(@__DIR__)
include("../examples/lutkepohl_example.jl")
using LinearAlgebra

v = VAR(Y, 2)
p = v.lags
B = v.B
sigma = v.ΣU
K = size(B, 2)
h = 12

phi = VectorAutoregressions.simple_irf(B, K, p, h)
theta = VectorAutoregressions.orthogonal_irf(phi, sigma, K, h)

irf = VectorAutoregressions.IRF(v, h, orthogonal = false)
cirf = VectorAutoregressions.IRF(v, h, orthogonal = false, cumulative = true)


text:
mutable struct GenericKeyHandler <: AbstractKeyHandler
    name::AbstractString
    api_url::AbstractString
    key::AbstractString
end

function GenericKeyHandler(nm,url;kwargs...)
    kh = GenericKeyHandler(nm,url,"")
    key = load_key!(kh;kwargs...)
    return kh
end


text:
using VibronicToolkit: SamplingParameters

let sys = DenseSystem(test_params...),
    beta = 12.34,
    P = 256,
    sp = SamplingParameters(simplify(diag(sys)), beta, P)

    @test sp.tau == beta/P
    @test isapprox(weights(sp), [0.999996583, 3.41696734e-6, 1.16757213e-11])
    @test isapprox(weights(sp), weights(simplify(diag(sys)), beta))
end


text:
#####
##### Freelists
#####

abstract type AbstractFreelist{T} end

# Parameterize the freelist for testing purposts.
# Expected api for T:
#      .next
#      .previous
#      address
#      isnull
mutable struct Freelist{T} <: AbstractFreelist{T}
    base::T
end
Freelist{T}() where {T} = Freelist(T())
getbase(x::Freelist) = x.base
setbase!(x::Freelist{T}, v::T) where {T} = (x.base = v)

# Raw pointer based list
struct FreelistPtr{T} <: AbstractFreelist{T}
    ptr::Ptr{T}
end
getbase(x::FreelistPtr) = unsafe_load(x.ptr)
setbase!(x::FreelistPtr{T}, v::T) where {T} = unsafe_store!(x.ptr, v)

#####
##### Implementation
#####

function Base.length(x::AbstractFreelist)
    count = 0
    item = getbase(x)
    while !isnull(item)
        count += 1
        item = item.next
    end

    return count
end

Base.isempty(x::AbstractFreelist) = isnull(getbase(x))

function Base.pop!(x::AbstractFreelist{T}) where {T}
    # Pull out the base
    item = getbase(x)

    # Set the base block to the next block
    # If this hasn't emptied the freelist, null out the previous field
    setbase!(x, item.next)
    if !isempty(x)
        getbase(x).previous = T()
    end
    item.next = T()
    return item
end

function Base.push!(x::AbstractFreelist{T}, item::T) where {T}
    if isempty(x)
        item.next = T()
    else
        @check isnull(getbase(x).previous)
        getbase(x).previous = item
        item.next = getbase(x)
    end
    item.previous = T()
    setbase!(x, item)
    return x
end

function swap!(a::T, b::T) where {T}
    @check a.next == b
    @check b.previous == a

    # Swap neighbors
    isnull(a.previous) || (a.previous.next = b)
    isnull(b.next) || (b.next.previous = a)

    b.previous = a.previous
    a.next = b.next
    b.next = a
    a.previous = b
    return nothing
end

function remove!(x::AbstractFreelist{T}, item::T) where {T}
    # Update the linked-list.
    if isnull(item.previous)
        setbase!(x, item.next)
    else
        item.previous.next = item.next
    end

    if !isnull(item.next)
        item.next.previous = item.previous
    end
    item.next = item.previous = T()
    return nothing
end

# Sort the freelist by some parameter
# uses a simple bubble sort - so probably not that fast.
function Base.sort!(x::AbstractFreelist; lt = isless)
    isempty(x) && return nothing

    while true
        swapped = false
        current = getbase(x)

        next = current.next
        while !isnull(next)
            if lt(next, current)
                # Implicitly updates `block`.
                swap!(current, next)
                # Update the base element if needed.
                # Handling of `null` will be dealt with in `swap!`.
                current == getbase(x) && (setbase!(x, next))
                swapped = true
            else
                current = next
            end
            next = current.next
        end

        # If we haven't updated anything, then we're done.
        swapped || break
    end
    return nothing
end

function Base.iterate(x::AbstractFreelist, item = getbase(x))
    isnull(item) && return nothing
    return (item, item.next)
end


text:
using Pkg, PackageCompiler

# packages to install
packages_to_install = ["Plots",
    "DataFrames",
    "GR",
    "Query",
    "Parameters"]
Pkg.add(packages_to_install)

# packages to bake in
compile_package("Plots", "DataFrames", "Query", "GR", force = true)

max_stars_repo_name: davidanthoff/compiled-binder-postbuild

max_issues_repo_name: davidanthoff/compiled-binder-postbuild

max_forks_repo_name: davidanthoff/compiled-binder-postbuild


text:
module SimilarReferences
include("knr.jl")
include("kvp.jl")
end


text:
# elliptical slice sampler
struct ESS <: AbstractMCMC.AbstractSampler end

# state of the elliptical slice sampler
struct ESSState{S,L,C}
    "Sample of the elliptical slice sampler."
    sample::S
    "Log-likelihood of the sample."
    loglikelihood::L
    "Cache used for in-place sampling."
    cache::C
end

function ESSState(sample, loglikelihood)
    # create cache since it was not provided (initial sampling step)
    cache = ArrayInterfaceCore.ismutable(sample) ? similar(sample) : nothing
    return ESSState(sample, loglikelihood, cache)
end

# first step of the elliptical slice sampler
function AbstractMCMC.step(
    rng::Random.AbstractRNG,
    model::AbstractMCMC.AbstractModel,
    ::ESS;
    init_params=nothing,
    kwargs...,
)
    # initial sample from the Gaussian prior
    f = init_params === nothing ? initial_sample(rng, model) : init_params

    # compute log-likelihood of the initial sample
    loglikelihood = Distributions.loglikelihood(model, f)

    return f, ESSState(f, loglikelihood)
end

# subsequent steps of the elliptical slice sampler
function AbstractMCMC.step(
    rng::Random.AbstractRNG,
    model::AbstractMCMC.AbstractModel,
    ::ESS,
    state::ESSState;
    kwargs...,
)
    # obtain the prior
    prior = EllipticalSliceSampling.prior(model)

    # sample from Gaussian prior
    cache = state.cache
    if cache === nothing
        ν = Random.rand(rng, prior)
    else
        Random.rand!(rng, prior, cache)
        ν = cache
    end

    # sample log-likelihood threshold
    loglikelihood = state.loglikelihood
    threshold = loglikelihood - Random.randexp(rng)

    # sample initial angle
    θ = 2 * π * rand(rng)
    θmin = θ - 2 * π
    θmax = θ

    # compute the proposal
    f = state.sample
    fnext = proposal(prior, f, ν, θ)

    # compute the log-likelihood of the proposal
    loglikelihood = Distributions.loglikelihood(model, fnext)

    # stop if the log-likelihood threshold is reached
    while loglikelihood < threshold
        # shrink the bracket
        if θ < zero(θ)
            θmin = θ
        else
            θmax = θ
        end

        # sample angle
        θ = θmin + rand(rng) * (θmax - θmin)

        # recompute the proposal
        if ArrayInterfaceCore.ismutable(fnext)
            proposal!(fnext, prior, f, ν, θ)
        else
            fnext = proposal(prior, f, ν, θ)
        end

        # compute the log-likelihood of the proposal
        loglikelihood = Distributions.loglikelihood(model, fnext)
    end

    return fnext, ESSState(fnext, loglikelihood, cache)
end


text:
struct BenchmarkWrapper
    benchmark::BenchmarkTools.Benchmark
    cfg::PerfConfig
end

struct GroupWrapper
    benchmark::BenchmarkGroup
    cfg::PerfConfig
end

BenchPerf.wrap(b::BenchmarkTools.Benchmark; kwargs...) =
    BenchmarkWrapper(b, as_perf_config(; kwargs...))

BenchPerf.wrap(b::BenchmarkGroup; kwargs...) = GroupWrapper(b, as_perf_config(; kwargs...))

function Base.run(bp::Union{BenchmarkWrapper,GroupWrapper}; runopts...)
    b, p = execute(bp.benchmark, bp.cfg, runopts)
    return as_result(b, p)
end

function BenchPerf.perfpath(filepath::AbstractString)
    if endswith(filepath, ".json")
        return filepath[1:end-length(".json")] * "-perf.json"
    else
        error("Result `filepath` must have `.json` extension; got: ", filepath)
    end
end

function BenchmarkTools.save(filepath::AbstractString, result::GroupResult)
    perfpath = BenchPerf.perfpath(filepath)
    BenchmarkTools.save(filepath, result.benchmark)
    open(perfpath, write = true) do io
        JSON.print(io, result.perf)
    end
    return
end

BenchPerf.loadperf(perfpath) = from_json(JSON.parsefile(perfpath))

function from_json(d::Dict{String,Any})
    if (group = get(d, "group", nothing)) !== nothing
        group = group::Dict{String,Any}
        perf = GroupPerf()
        for (k, v) in group
            perf[k] = from_json(v)
        end
        return perf
    elseif (output = get(d, "output", nothing)) !== nothing
        return TrialPerf(output)
    else
        error("unrecognized dictionary: ", d)
    end
end


text:
using FEASTSolver
using LinearAlgebra
using DelimitedFiles
using Random

# A = diagm(-1 => fill(-1.0, 99), 0 => fill(2.0, 100), 1 => fill(-1.0, 99))
Random.seed!(1551)
A = randn(ComplexF64, 100, 100)
C, R = complex(0.0, 0.0), 2.0 # contour
# C, R = complex(0.1, 0.0), 0.1 # contour
X = rand(ComplexF64, 100, 20) # initial subspace

# contour = circular_contour_trapezoidal(C, R, 16)
# contour = rectangular_contour_gauss(-R-im*R, R + R*im, 16)
contour = rectangular_contour_trapezoidal(-R-im*R, R + R*im, 32)
writedlm("test/data/contour.dat", zip(real.(contour.nodes), imag.(contour.nodes)))
writedlm("test/data/weights.dat", zip(real.(contour.weights), imag.(contour.weights)))

# e, v, res = feast!(X, A, c=C, r=R, nodes=8, debug=true, ϵ=10e-15)
e, v, res = feast!(X, A, contour, debug=true, ϵ=10e-14)

# info(e,v,res,C,R)
convergence_info(e,v,res,contour)
display(e)
e = eigvals(A)
println()
display(e[abs.(e) .< R])


text:
using BenchmarkTools, Plots, Plots.PlotMeasures, LaTeXStrings
using BenchmarkTools: minimum, median

SUITE = BenchmarkGroup()
model = "SPRE21"
cases = [""]
SUITE[model] = BenchmarkGroup()

include("spacecraft.jl")
validation = []

# internal (non-exported functions)
using ReachabilityAnalysis: post, BoxVecClustering
using IntervalArithmetic
using LazySets: Interval
const IA = IntervalArithmetic
const RA = ReachabilityAnalysis

function _solve_spacecraft(prob)

    # solve first mode
    T = 200.0
    p1 = IVP(prob.s.modes[1], prob.x0[1][2])
    I1 = stateset(p1)
    I1c = complement(I1)
    alg = TMJets20(abstol=1e-5, maxsteps=10_000, orderT=5, orderQ=1, disjointness=ZonotopeEnclosure())
    @time sol1F = post(alg, p1, IA.Interval(0, T))
    sol1F.ext[:loc_id] = 1

    # find sets that take the jump 1 -> 2
    jump_rset_idx = findall(R -> !isdisjoint(R, I1c), sol1F)
    Xc_box = cluster(sol1F, jump_rset_idx, BoxVecClustering(100))
    @assert length(Xc_box) == 1

    # apply jump according to 1 -> 2 transition
    ot1 = first(out_transitions(prob.s, 1))
    tr12 = DiscreteTransition(prob.s, ot1)
    z12 = apply(tr12, Xc_box[1], TemplateHullIntersection(BoxDirections(5)))

    # solve second mode
    inv2 = HalfSpace([-1.0, 0, 0, 0, 0], 100.0) #  ∩ HalfSpace([0, 0, 0, 0, 1.0], 150.0)
    z12box = overapproximate(z12, Hyperrectangle)
    p2 = IVP(ConstrainedBlackBoxContinuousSystem(prob.s.modes[2].f, 5, inv2), z12box)
    alg = TMJets20(abstol=1e-7, maxsteps=10_000, orderT=4, orderQ=1, disjointness=ZonotopeEnclosure())
    Δt0 = tspan(Xc_box[1])
    tprev = tstart(Δt0)
    @time sol2F = post(alg, p2, IA.Interval(0, 150 - tprev); Δt0=Δt0)
    sol2F.ext[:loc_id] = 2
    sol2F_filtered = sol2F(120 .. 150)
    sol2F_fp = Flowpipe(sol2F_filtered)

    # cluster and zonotope enclosure of the sets that take the jump, using time information in the TM
    ngroups = 5
    sol2F_groups = RA.nfolds(sol2F_filtered, ngroups)
    out2_groups = [RA._cluster_decompose_zono(ai, [1:2, 3:4, 5:5], PolarDirections(20)) for ai in sol2F_groups]
    TM0_3 = [RA._overapproximate_structured(o, TaylorModelReachSet, orderT=4, orderQ=1) for o in out2_groups]

    # solve third mode
    p3 = [IVP(prob.s.modes[3], X0newi) for X0newi in TM0_3]
    alg3 = TMJets21b(abstol=1e-10, orderT=7, orderQ=1, disjointness=BoxEnclosure())
    Δt0 = tspan(sol2F_filtered)
    tprev = tstart(Δt0)
    @time sol3F = [post(alg, p3i, IA.Interval(0, T - tprev); Δt0=Δt0) for p3i in p3]
    for Fi in sol3F
        Fi.ext[:loc_id] = 3
    end

    return HybridFlowpipe(reduce(vcat, (sol1F, sol2F, sol3F)))
end

prob = spacecraft()
sol = _solve_spacecraft(prob)
solz = overapproximate(sol, Zonotope)

# verify that specifications hold
prop1 = line_of_sight(solz)
println("Line of sight property: $prop1")

prop2 = velocity_constraint(solz)
println("Velocity constraint property $prop2")

prop3 = target_avoidance(solz)
println("Target avoidance property: $prop3")

property = prop1 && prop2 && prop3
push!(validation, Int(property))

# benchmark
SUITE[model][cases[1]] = @benchmarkable _solve_spacecraft($prob)

# ==============================================================================
# Execute benchmarks and save benchmark results
# ==============================================================================

# tune parameters
tune!(SUITE)

# run the benchmarks
results = run(SUITE, verbose=true)

# return the sample with the smallest time value in each test
println("minimum time for each benchmark:\n", minimum(results))

# return the median for each test
println("median time for each benchmark:\n", median(results))

# export runtimes
runtimes = Dict()
for (i, c) in enumerate(cases)
    local t
    t = median(results[model][c]).time * 1e-9
    runtimes[c] = t
end

for (i, c) in enumerate(cases)
    print(io, "JuliaReach, $model, $c, $(validation[i]), $(runtimes[c])\n")
end

# ==============================================================================
# Plot
# ==============================================================================

idx_approaching = findall(==(1,), location.(sol))
idx_attempt = findall(==(2,), location.(sol))
idx_aborting = findall(==(3,), location.(sol))

fig = plot(legend=:bottomright, legendfontsize=18,
           tickfont=font(30, "Times"), guidefontsize=45,
           xlab=L"x", ylab=L"y",
           xtick=-800:200:0, ytick=-400:100:0,
           xlims=(-900, 100), ylims=(-500, 10.0),
           size=(1000, 1000))

[plot!(fig, s, vars=(1, 2), c=:blue, lw=0.0) for s in sol[idx_approaching]]
[plot!(fig, s, vars=(1, 2), c=:lightgreen, lw=0.0) for s in sol[idx_aborting]]
[plot!(fig, s, vars=(1, 2), c=:red, lw=0.0) for s in sol[idx_attempt]]

savefig(fig, "ARCH-COMP21-JuliaReach-Spacecraft.png")


text:
# ---
# title: 792. Number of Matching Subsequences
# id: problem792
# author: Indigo
# date: 2021-01-29
# difficulty: Medium
# categories: Array
# link: <https://leetcode.com/problems/number-of-matching-subsequences/description/>
# hidden: true
# ---
#
# Given string `S` and a dictionary of words `words`, find the number of
# `words[i]` that is a subsequence of `S`.
#
#
#
#     **Example :**
#     Input:
#     S = "abcde"
#     words = ["a", "bb", "acd", "ace"]
#     Output: 3
#     Explanation: There are three words in words that are a subsequence of S: "a", "acd", "ace".
#
#
# **Note:**
#
#   * All words in `words` and `S` will only consists of lowercase letters.
#   * The length of `S` will be in the range of `[1, 50000]`.
#   * The length of `words` will be in the range of `[1, 5000]`.
#   * The length of `words[i]` will be in the range of `[1, 50]`.
#
#
## @lc code=start
using LeetCode

function num_matching_subseq(S::String, words::Vector{String})
    map = Dict{Char, Vector{String}}((ch, []) for ch in 'a':'z')
    for w in words
        push!(map[w[1]], w[2:end])
    end
    res = 0
    for ch in S
        wds = String[]
        wds, map[ch] = map[ch], wds
        for w in wds
            if w == ""
                res += 1
            else
                push!(map[w[1]], w[2:end])
            end
        end
    end
    res
end
## @lc code=end


text:
module MCMC

using GaPLAC
using GaPLAC.AbstractGPs
using GaPLAC.Turing
using GaPLAC.CSV
using GaPLAC.DataFrames
using GaPLAC.Distributions
using Statistics

function run(args)
    @info "running 'mcmc'"
    gpspec = GaPLAC.gp_formula(args["formula"])

    @debug "GP formula" GaPLAC.formula(gpspec)

    df = CSV.read(args["data"], DataFrame)

    eq, vars = GaPLAC._apply_vars(GaPLAC.formula(gpspec))
    kernels = GaPLAC._walk_kernel(eq)
    length(vars) == length(kernels) || error("Something went wrong with equation parsing, number of variables should == number of kernels")
    inferable = Symbol.(args["infer"])

    y = df[!, GaPLAC.response(gpspec)]
    x = Matrix(df[!, vars])

    @debug "GP equation" eq
    @debug "Model variables" vars

    @model function inference_engine(Y, X, eq, inferable)
        ℓ ~ Uniform(0,20)
        gp, = GaPLAC._apply_vars(eq; hyperparams=Dict(v=> ℓ for v in inferable))

        fx ~ AbstractGPs.FiniteGP(GP(gp), RowVecs(X), 0.1)
        Y .~ Normal.(fx, 1)
    end

    m = inference_engine(y, x, GaPLAC.formula(gpspec), inferable)

    chain = sample(m, NUTS(0.65), args["samples"], progress=true)
    GaPLAC._df_output(chain, args)

    return chain
end

function _get_hyperparams(infer, kernels, vars)
    hyperparams = Dict{Symbol,Number}()
end

end

max_stars_repo_name: biobakery/GaPLAC

max_issues_repo_name: biobakery/GaPLAC

max_forks_repo_name: biobakery/GaPLAC


text:
using GroupsCore
using Test

include("conformance_test.jl")

include("cyclic.jl")
include("symmetric.jl")

@testset "GroupsCore.jl" begin

    include("test_notsatisfied.jl")

    @testset "Cyclic(12)" begin
        G = CyclicGroup(12)
        test_Group_interface(G)
        test_GroupElement_interface(rand(G, 2)...)
    end

    @testset "Symmetric(5)" begin
        G = AbstractAlgebra.SymmetricGroup(5)
        test_Group_interface(G)
        test_GroupElement_interface(rand(G, 2)...)
    end
end


text:
# test FluxModelsDistribution and serialization

using Test
using BSON, Flux, IncrementalInference
using TensorCast

##

@testset "FluxModelsDistribution serialization" begin

##

# can a model be serialized
mdls = [Chain(Dense(5,2),Dense(2,3)); Chain(Dense(5,4), Dense(4,3))]
fxd = FluxModelsDistribution((5,),(3,),mdls,rand(5), false, false)

# check sampler is working
measd = rand(fxd, 2)
@test measd |> size == (3,2)

# convert to flat string
fxp = convert(PackedSamplableBelief, fxd)
@test fxp isa String

# convert back to hydrated object
fxu = convert(SamplableBelief, fxp)
@test fxu isa FluxModelsDistribution

measu = rand(fxu, 2)

@test measd[1] - measu[1] |> norm < 1e-6

##

end

@testset "FluxModelsDistribution serialization" begin

##

mdls = [Chain(Dense(5,2),Dense(2,3)); Chain(Dense(5,4), Dense(4,3))]
fxd = FluxModelsDistribution((5,),(3,),mdls,rand(5), false, false)

fg = initfg()

addVariable!(fg, :x0, ContinuousEuclid{3})

pr = Prior(fxd)

addFactor!(fg, [:x0;], pr)

# check local product
localProduct(fg, :x0)

solveTree!(fg)

saveDFG("/tmp/fg_test_flux", fg)

fg_ = loadDFG("/tmp/fg_test_flux")

ff1 = getFactorType(fg_, :x0f1)
ff1.Z.shuffle[] = true

solveTree!(fg_);

# remove the testing file
Base.rm("/tmp/fg_test_flux.tar.gz")

##

end

@testset "FluxModelsDistribution as Mixture with relative factor" begin

##

mdls = [Chain(Dense(10,50, relu),Dense(50,20),softmax, Dense(20,1, tanh)) for i in 1:50];
fxd = FluxModelsDistribution((10,),(1,),mdls,rand(10), false, false)

fg = initfg()

addVariable!(fg, :x0, ContinuousEuclid{1})
addVariable!(fg, :x1, ContinuousEuclid{1})

# a prior
pr = Prior(Normal())
addFactor!(fg, [:x0;], pr)

# a relative mixture network
mfx = Mixture(LinearRelative, (naive=Normal(10, 10), nn=fxd), [0.5;0.5])
addFactor!(fg, [:x0;:x1], mfx)

# and test overall serialization before solving
saveDFG("/tmp/fg_test_flux", fg)

# solve existing fg
solveTree!(fg)

# prior should pin x0 pretty well
pts_ = getBelief(fg, :x0) |> getPoints
@cast pts[i,j] := pts_[j][i]
@test 80 < sum(-3 .< (pts) .< 3)
# at least some points should land according to the naive model
pts_ = getBelief(fg, :x1) |> getPoints
@cast pts[i,j] := pts_[j][i]
@test 5 < sum(5 .< (pts) .< 15)

# will predict from existing fg
f1 = getFactorType(fg, :x0x1f1)
predictions = map(f->f(f1.components.nn.data), f1.components.nn.models)

# unpack into new fg_
fg_ = loadDFG("/tmp/fg_test_flux")

# same predictions with deserialized object
f1_ = getFactorType(fg_, :x0x1f1)
predictions_ = map(f->f(f1_.components.nn.data), f1_.components.nn.models)

# check that all predictions line up
@show norm(predictions - predictions_)
@test norm(predictions - predictions_) < 1e-6

f1_.components.nn.shuffle[] = true

# test solving of the new object
solveTree!(fg_);

# prior should pin x0 pretty well
pts_ = getBelief(fg_, :x0) |> getPoints
@cast pts[i,j] := pts_[j][i]
@test 80 < sum(-3 .< (pts) .< 3)
# at least some points should land according to the naive model
pts_ = getBelief(fg_, :x1) |> getPoints
@cast pts[i,j] := pts_[j][i]
@test 5 < sum(5 .< (pts) .< 15)

# remove the testing file
Base.rm("/tmp/fg_test_flux.tar.gz")

##

end

@testset "MixtureFluxModels testing" begin

##

# some made up data
data = randn(10)
# Flux models
models = [Flux.Chain(softmax, Dense(10,5,σ), Dense(5,1, tanh)) for i in 1:20]
# mixture with user defined names (optional) -- could also just pass Vector or Tuple of components
mix = MixtureFluxModels(PriorCircular, models, (10,), data, (1,),
                        (naiveNorm=Normal(),naiveUnif=Uniform()),
                        [0.7; 0.2; 0.1],
                        shuffle=false )
#

# test by add to simple graph
fg = initfg()
addVariable!(fg, :testmix, Circular)
addFactor!(fg, [:testmix;], mix)

pts = approxConv(fg, :testmixf1, :testmix);

# look at proposal distribution from the only factor on :testmix
_,pts,__, = localProduct(fg, :testmix);

saveDFG("/tmp/fg_mfx", fg)

#
fg_ = loadDFG("/tmp/fg_mfx")

Base.rm("/tmp/fg_mfx.tar.gz")

solveTree!(fg_);

@test 10 < (getBelief(fg_, :testmix) |> getPoints |> length)

##

end

#


text:
struct CachedDataResourceString
    content::String
end
Base.show(io::IO, ::MIME"application/vnd.dataresource+json", source::CachedDataResourceString) = print(io, source.content)
Base.showable(::MIME"application/vnd.dataresource+json", dt::CachedDataResourceString) = true

function JSON_print_escaped(io, val::AbstractString)
    print(io, '"')
    for c in val
        if c == '"' || c == '\\'
            print(io, '\\')
            print(io, c)
        elseif c == '\b'
            print(io, '\\')
            print(io, 'b')
        elseif c == '\f'
            print(io, '\\')
            print(io, 'f')
        elseif c == '\n'
            print(io, '\\')
            print(io, 'n')
        elseif c == '\r'
            print(io, '\\')
            print(io, 'r')
        elseif c == '\t'
            print(io, '\\')
            print(io, 't')
        else
            print(io, c)
        end
    end
    print(io, '"')
end

function JSON_print_escaped(io, val)
    print(io, '"')
    print(io, val)
    print(io, '"')
end

function JSON_print_escaped(io, val::Missing)
    print(io, "null")
end

julia_type_to_schema_type(::Type{Union{}}) = "string"
julia_type_to_schema_type(::Type{T}) where {T} = "string"
julia_type_to_schema_type(::Type{T}) where {T <: AbstractFloat} = "number"
julia_type_to_schema_type(::Type{T}) where {T <: Integer} = "integer"
julia_type_to_schema_type(::Type{T}) where {T <: Bool} = "boolean"
julia_type_to_schema_type(::Type{T}) where {T <: Dates.Time} = "time"
julia_type_to_schema_type(::Type{T}) where {T <: Dates.Date} = "date"
julia_type_to_schema_type(::Type{T}) where {T <: Dates.DateTime} = "datetime"
julia_type_to_schema_type(::Type{T}) where {T <: AbstractString} = "string"

function printdataresource(io::IO, source)
    if Base.IteratorEltype(source) isa Base.EltypeUnknown
        first_el = first(source)
        col_names = String.(propertynames(first_el))
        col_types = [fieldtype(typeof(first_el), i) for i = 1:length(col_names)]
    else
        col_names = String.(fieldnames(eltype(source)))
        col_types = [fieldtype(eltype(source), i) for i = 1:length(col_names)]
    end

    print(io, "{")

    JSON_print_escaped(io, "schema")
    print(io, ": {")
    JSON_print_escaped(io, "fields")
    print(io, ":[")
    for i = 1:length(col_names)
        if i > 1
            print(io, ",")
        end

        print(io, "{")
        JSON_print_escaped(io, "name")
        print(io, ":")
        JSON_print_escaped(io, col_names[i])
        print(io, ",")
        JSON_print_escaped(io, "type")
        print(io, ":")
        JSON_print_escaped(io, julia_type_to_schema_type(col_types[i]))
        print(io, "}")
    end
    print(io, "]},")

    JSON_print_escaped(io, "data")
    print(io, ":[")

    for (row_i, row) in enumerate(source)
        if row_i > 1
            print(io, ",")
        end

        print(io, "{")
        for col in 1:length(col_names)
            if col > 1
                print(io, ",")
            end
            JSON_print_escaped(io, col_names[col])
            print(io, ":")
            # TODO This is not type stable, should really unroll the loop in a generated function
            JSON_print_escaped(io, row[col])
        end
        print(io, "}")
    end

    print(io, "]}")
end

function print_array_as_dataresource(io::IO, source::T) where {EL,T <: AbstractVector{EL}}
    print(io, "{")

    JSON_print_escaped(io, "schema")
    print(io, ": {")
    JSON_print_escaped(io, "fields")
    print(io, ":[")

    print(io, "{")
    JSON_print_escaped(io, "name")
    print(io, ":")
    JSON_print_escaped(io, "values")
    print(io, ",")
    JSON_print_escaped(io, "type")
    print(io, ":")
    JSON_print_escaped(io, julia_type_to_schema_type(EL))
    print(io, "}")

    print(io, "]},")

    JSON_print_escaped(io, "data")
    print(io, ":[")

    for (row_i, row) in enumerate(source)
        if row_i > 1
            print(io, ",")
        end

        print(io, "{")
        JSON_print_escaped(io, "values")
        print(io, ":")
        # TODO This is not type stable, should really unroll the loop in a generated function
        JSON_print_escaped(io, row)
        print(io, "}")
    end

    print(io, "]}")
end

function print_array_as_dataresource(io::IO, source::T) where {EL,T <: AbstractMatrix{EL}}
    nrow, ncol = size(source)

    print(io, "{")

    JSON_print_escaped(io, "schema")
    print(io, ": {")
    JSON_print_escaped(io, "fields")
    print(io, ":[")
    for i = 1:ncol
        if i > 1
            print(io, ",")
        end

        print(io, "{")
        JSON_print_escaped(io, "name")
        print(io, ":")
        JSON_print_escaped(io, string(i))
        print(io, ",")
        JSON_print_escaped(io, "type")
        print(io, ":")
        JSON_print_escaped(io, julia_type_to_schema_type(EL))
        print(io, "}")
    end
    print(io, "]},")

    JSON_print_escaped(io, "data")
    print(io, ":[")

    for row_i in 1:nrow
        if row_i > 1
            print(io, ",")
        end

        print(io, "{")
        for col_i in 1:ncol
            if col_i > 1
                print(io, ",")
            end
            JSON_print_escaped(io, string(col_i))
            print(io, ":")
            # TODO This is not type stable, should really unroll the loop in a generated function
            JSON_print_escaped(io, source[row_i, col_i])
        end
        print(io, "}")
    end

    print(io, "]}")
end

max_stars_repo_name: AbdulrhmnGhanem/julia-vscode

max_issues_repo_name: AbdulrhmnGhanem/julia-vscode

max_forks_repo_name: AbdulrhmnGhanem/julia-vscode


text:
module JungleHelperEscapeMovingPlatform

using ..Ahorn, Maple

const placements = Ahorn.PlacementDict(
    "Platform (Moving, Escape) (Jungle Helper)" => Ahorn.EntityPlacement(
        Maple.MovingPlatform,
        "rectangle",
        Dict{String, Any}(
          "texture" => "JungleHelper/escape"
        ),

        function(entity)
            x, y = Int(entity.data["x"]), Int(entity.data["y"])
            width = Int(get(entity.data, "width", 8))
            entity.data["x"], entity.data["y"] = x + width, y
            entity.data["nodes"] = [(x, y)]
        end
    )
)

end

max_stars_repo_name: Jackal-Celeste/JungleHelper

max_issues_repo_name: Jackal-Celeste/JungleHelper

max_forks_repo_name: Jackal-Celeste/JungleHelper


text:
# Approxiamte Search
# ==================
#
# Approximate sequence search tools.
#
# This file is a part of BioJulia.
# License is MIT: https://github.com/BioJulia/Bio.jl/blob/master/LICENSE.md

"""
Query type for approximate sequence search.
"""
immutable ApproximateSearchQuery{S<:Sequence}
    seq::S          # query sequence
    fPcom::Vector   # compatibility vector for forward search
    bPcom::Vector   # compatibility vector for backward search
    H::Vector{Int}  # distance vector for alignback function

    function ApproximateSearchQuery(seq::Sequence, direction::Symbol)
        if direction == :forward
            fPcom = approx_preprocess(seq, true)
            bPcom = []
        elseif direction == :backward
            fPcom = []
            bPcom = approx_preprocess(seq, false)
        elseif direction == :both
            fPcom = approx_preprocess(seq, true)
            bPcom = approx_preprocess(seq, false)
        else
            throw(ArgumentError("direction '$direction' is invalid"))
        end
        H = Vector{Int}(length(seq) + 1)
        return new(seq, fPcom, bPcom, H)
    end
end

"""
    ApproximateSearchQuery(pat::Sequence[, direction=:both])

Create an query object for approximate sequence search from the `pat` sequence.

# Arguments
* `pat`: Query sequence.
* `direction=:both`: Search direction (`:forward`, `:backward`, or `:both`).
"""
function ApproximateSearchQuery(pat::Sequence, direction::Symbol=:both)
    return ApproximateSearchQuery{typeof(pat)}(pat, direction)
end

function approx_preprocess(pat, forward)
    # select a bit vector type
    # TODO: BigInt is very slow, consider implementing "4.2 THE BLOCKS MODEL"
    m = length(pat)
    T = m ≤ 64 ? UInt64 : m ≤ 128 ? UInt128 : BigInt
    Σ = alphabet(eltype(pat))
    Pcom = zeros(T, length(Σ))
    for i in 1:m
        y = forward ? pat[i] : pat[end-i+1]
        for x in Σ
            if Seq.iscompatible(x, y)
                Pcom[UInt8(x)+1] |= one(T) << (i - 1)
            end
        end
    end
    return Pcom
end

"""
    approxsearch(seq, pat, k[, start=1[, stop=endof(seq)]])

Return the range of the first occurrence of `pat` in `seq[start:stop]` allowing
up to `k` errors; symbol comparison is done using `Bio.Seq.iscompatible`.
"""
function approxsearch(seq::Sequence, pat::Sequence, k::Integer,
                      start::Integer=1, stop::Integer=endof(seq))
    return approxsearch(seq, ApproximateSearchQuery(pat, :forward), k, start, stop)
end

function approxsearch(seq::Sequence, query::ApproximateSearchQuery, k::Integer,
                      start::Integer=1, stop::Integer=endof(seq))
    return _approxsearch(query, seq, k, start, stop, true)
end

"""
    approxrsearch(seq, pat, k[, start=endof(seq)[, stop=1]])

Return the range of the last occurrence of `pat` in `seq[stop:start]` allowing
up to `k` errors; symbol comparison is done using `Bio.Seq.iscompatible`.
"""
function approxrsearch(seq::Sequence, pat::Sequence, k::Integer,
                       start::Integer=endof(seq), stop::Integer=1)
    return approxrsearch(seq, ApproximateSearchQuery(pat, :backward), k, start, stop)
end

function approxrsearch(seq::Sequence, query::ApproximateSearchQuery, k::Integer,
                       start::Integer=endof(seq), stop::Integer=1)
    return _approxsearch(query, seq, k, start, stop, false)
end

"""
    approxsearchindex(seq, pat, k[, start=1[, stop=endof(seq)]])

Return the index of the first occurrence of `pat` in `seq[start:stop]` allowing
up to `k` errors; symbol comparison is done using `Bio.Seq.iscompatible`.
"""
function approxsearchindex(seq::Sequence, pat::Sequence, k::Integer,
                           start::Integer=1, stop::Integer=endof(seq))
    return first(approxsearch(seq, pat, k, start, stop))
end

function approxsearchindex(seq::Sequence, query::ApproximateSearchQuery, k::Integer,
                           start::Integer=1, stop::Integer=endof(seq))
    return first(approxsearch(seq, query, k, start, stop))
end

"""
    approxrsearchindex(seq, pat, k[, start=endof(seq)[, stop=1]])

Return the index of the last occurrence of `pat` in `seq[stop:start]` allowing
up to `k` errors; symbol comparison is done using `Bio.Seq.iscompatible`.
"""
function approxrsearchindex(seq::Sequence, pat::Sequence, k::Integer,
                            start::Integer=endof(seq), stop::Integer=1)
    return first(approxrsearch(seq, pat, k, start, stop))
end

function approxrsearchindex(seq::Sequence, query::ApproximateSearchQuery, k::Integer,
                            start::Integer=endof(seq), stop::Integer=1)
    return first(approxrsearch(seq, query, k, start, stop))
end

function _approxsearch(query, seq, k, start, stop, forward)
    if forward && isempty(query.fPcom)
        throw(ArgumentError("query is not preprocessed for forward search"))
    end
    if !forward && isempty(query.bPcom)
        throw(ArgumentError("query is not preprocessed for backward search"))
    end

    if k ≥ length(query.seq)
        return start:start-1
    end

    # search the approximate suffix
    matchstop, dist = search_approx_suffix(
        forward ? query.fPcom : query.bPcom,
        query.seq, seq, k, start, stop, forward)
    if matchstop == 0
        return 0:-1
    end

    # locate the starting position of the match
    matchstart = alignback!(query.H, query.seq, seq, dist, start, matchstop, forward)
    if forward
        return matchstart:matchstop
    else
        return matchstop:matchstart
    end
end

# This returns the end index of a suffix sequence with up to `k` errors.
# More formally, when `forward = true`, it returns the minimum `j ∈ start:stop`
# such that `min_{g ∈ 1:j} δ(pat, seq[g:j]) ≤ k` where `δ(s, t)` is the edit
# distance between `s` and `t` sequences. See Myers' paper for details:
# Myers, Gene. "A fast bit-vector algorithm for approximate string matching
# based on dynamic programming." Journal of the ACM (JACM) 46.3 (1999): 395-415.
# NOTE: `Pcom` corresponds to `Peq` in the paper.
function search_approx_suffix{T}(Pcom::Vector{T}, pat, seq, k, start, stop, forward)
    if k < 0
        throw(ArgumentError("the number of errors must be non-negative"))
    end

    m = length(pat)
    n = length(seq)
    @assert T == BigInt || m ≤ sizeof(T) * 8

    Pv::T = (one(T) << m) - one(T)
    Mv::T = zero(T)
    dist = m
    j = forward ? max(start, 1) : min(start, n)

    if dist ≤ k
        return j, dist
    end

    while (forward && j ≤ min(stop, n)) || (!forward && j ≥ max(stop, 1))
        Eq = Pcom[UInt8(seq[j])+1]
        Xv = Eq | Mv
        Xh = (((Eq & Pv) + Pv) $ Pv) | Eq

        Ph = Mv | ~(Xh | Pv)
        Mh = Pv & Xh
        if (Ph >> (m - 1)) & 1 != 0
            dist += 1
        elseif (Mh >> (m - 1)) & 1 != 0
            dist -= 1
        end

        if dist ≤ k
            return j, dist  # found
        end

        Ph <<= 1
        Mh <<= 1
        Pv = Mh | ~(Xv | Ph)
        Mv = Ph & Xv
        j += ifelse(forward, +1, -1)
    end

    return 0, -1  # not found
end

# run dynamic programming to get the starting position of the alignment
function alignback!(H, pat, seq, dist, start, matchstop, forward)
    m = length(pat)
    n = length(seq)

    # initialize the cost column
    for i in 0:m
        H[i+1] = i
    end

    j = ret = matchstop
    found = false
    while (forward && j ≥ max(start, 1)) || (!forward && j ≤ min(start, n))
        y = seq[j]
        h_diag = H[1]
        for i in 1:m
            x = forward ? pat[end-i+1] : pat[i]
            h = min(
                H[i] + 1,
                H[i+1] + 1,
                h_diag + ifelse(iscompatible(x, y), 0, 1))
            h_diag = H[i+1]
            H[i+1] = h
        end
        if H[m+1] == dist
            ret = j
            found = true
        end
        j += ifelse(forward, -1, +1)
    end
    @assert found

    return ret
end