text:
@testset "1.1.1.7 P(x) (a+b x)^m (c+d x)^n (e+f x)^p (g+h x)^q" begin
    (A, B, C, a, b, c, d, e, f, g, h, x, ) = @variables A B C a b c d e f g h x

    #= ::Package:: =#

    #= ::Title:: =#
    #=Integrands*of*the*form*P2(x)*(a+b*x)^m*(c+d*x)^n*(e+f*x)^p*(g+h*x)^q=#

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*(a+b*x)^m*(c+d*x)^(n/2)*(A+B*x) / (Sqrte+f*x)*sqrt(g+h*x))=#

    #= ::Subsubsection:: =#
    #=n>0=#

    #= ::Subsubsection::Closed:: =#
    #=n<0=#

    #= [(a + b*x)^3*(A + B*x)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 10, (1/(105*d^3*f^3*h^3))*(2*b*(5*d*f*h*(7*a*(2*A*b + a*B)*d*f*h - b*B*(5*b*(d*e*g + c*f*g + c*e*h) + 2*a*(d*f*g + d*e*h + c*f*h))) + 2*(a*d*f*h - 2*b*(d*f*g + d*e*h + c*f*h))*(11*a*B*d*f*h + b*(7*A*d*f*h - 6*B*(d*f*g + d*e*h + c*f*h))))*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)) + (2*b*(11*a*B*d*f*h + b*(7*A*d*f*h - 6*B*(d*f*g + d*e*h + c*f*h)))*(a + b*x)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(35*d^2*f^2*h^2) + (2*b*B*(a + b*x)^2*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(7*d*f*h) - (1/(105*d^4*f^(7/2)*h^4*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))))*(2*sqrt((-d)*e + c*f)*(2*b*(d*f*g + d*e*h + c*f*h)*(5*d*f*h*(7*a*(2*A*b + a*B)*d*f*h - b*B*(5*b*(d*e*g + c*f*g + c*e*h) + 2*a*(d*f*g + d*e*h + c*f*h))) + 2*(a*d*f*h - 2*b*(d*f*g + d*e*h + c*f*h))*(11*a*B*d*f*h + b*(7*A*d*f*h - 6*B*(d*f*g + d*e*h + c*f*h)))) + 3*d*f*h*(b*(3*b*(d*e*g + c*f*g + c*e*h) + 2*a*(d*f*g + d*e*h + c*f*h))*(11*a*B*d*f*h + b*(7*A*d*f*h - 6*B*(d*f*g + d*e*h + c*f*h))) + 5*d*f*h*(4*b^3*B*c*e*g - 7*a^3*B*d*f*h + 6*a*b^2*B*(d*e*g + c*f*g + c*e*h) - a^2*b*(21*A*d*f*h - 2*B*(d*f*g + d*e*h + c*f*h)))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h)))) - (1/(105*d^4*f^(7/2)*h^4*sqrt(e + f*x)*sqrt(g + h*x)))*(2*sqrt((-d)*e + c*f)*(105*a^3*d^3*f^3*h^3*(B*g - A*h) + 105*a^2*b*d^2*f^2*h^2*(3*A*d*f*g*h - B*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h))) - 21*a*b^2*d*f*h*(5*A*d*f*h*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h)) - B*(4*c^2*f*h^2*(f*g - e*h) + c*d*h*(3*f^2*g^2 + e*f*g*h - 4*e^2*h^2) + d^2*g*(8*f^2*g^2 + 3*e*f*g*h + 4*e^2*h^2))) + b^3*(7*A*d*f*h*(4*c^2*f*h^2*(f*g - e*h) + c*d*h*(3*f^2*g^2 + e*f*g*h - 4*e^2*h^2) + d^2*g*(8*f^2*g^2 + 3*e*f*g*h + 4*e^2*h^2)) - B*(24*c^3*f^2*h^3*(f*g - e*h) + c^2*d*f*h^2*(17*f^2*g^2 + 6*e*f*g*h - 23*e^2*h^2) + 2*c*d^2*h*(8*f^3*g^3 + e*f^2*g^2*h + 3*e^2*f*g*h^2 - 12*e^3*h^3) + d^3*g*(48*f^3*g^3 + 16*e*f^2*g^2*h + 17*e^2*f*g*h^2 + 24*e^3*h^3))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))] =#
    @test_int [(a + b*x)^2*(A + B*x)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 9, (2*b*(7*a*B*d*f*h + b*(5*A*d*f*h - 4*B*(d*f*g + d*e*h + c*f*h)))*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(15*d^2*f^2*h^2) + (2*b*B*(a + b*x)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(5*d*f*h) + (1/(15*d^3*f^(5/2)*h^3*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))))*(2*sqrt((-d)*e + c*f)*(15*a^2*B*d^2*f^2*h^2 + 10*a*b*d*f*h*(3*A*d*f*h - 2*B*(d*f*g + d*e*h + c*f*h)) - b^2*(10*A*d*f*h*(d*f*g + d*e*h + c*f*h) - B*(8*c^2*f^2*h^2 + 7*c*d*f*h*(f*g + e*h) + d^2*(8*f^2*g^2 + 7*e*f*g*h + 8*e^2*h^2))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h)))) - (1/(15*d^3*f^(5/2)*h^3*sqrt(e + f*x)*sqrt(g + h*x)))*(2*sqrt((-d)*e + c*f)*(15*a^2*d^2*f^2*h^2*(B*g - A*h) + 10*a*b*d*f*h*(3*A*d*f*g*h - B*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h))) - b^2*(5*A*d*f*h*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h)) - B*(4*c^2*f*h^2*(f*g - e*h) + c*d*h*(3*f^2*g^2 + e*f*g*h - 4*e^2*h^2) + d^2*g*(8*f^2*g^2 + 3*e*f*g*h + 4*e^2*h^2))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))]
    @test_int [(a + b*x)^1*(A + B*x)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 8, (2*b*B*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*d*f*h) + (2*sqrt((-d)*e + c*f)*(3*a*B*d*f*h + b*(3*A*d*f*h - 2*B*(d*f*g + d*e*h + c*f*h)))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(3*d^2*f^(3/2)*h^2*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) - (2*sqrt((-d)*e + c*f)*(3*a*d*f*h*(B*g - A*h) + b*(3*A*d*f*g*h - B*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(3*d^2*f^(3/2)*h^2*sqrt(e + f*x)*sqrt(g + h*x))]
    @test_int [(a + b*x)^0*(A + B*x)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 6, (2*B*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(d*sqrt(f)*h*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) - (2*sqrt((-d)*e + c*f)*(B*g - A*h)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(d*sqrt(f)*h*sqrt(e + f*x)*sqrt(g + h*x))]
    @test_int [(A + B*x)/((a + b*x)^1*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 9, (2*B*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(b*d*sqrt(f)*sqrt(e + f*x)*sqrt(g + h*x)) - (2*(A - (a*B)/b)*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.Pi(-((b*(d*e - c*f))/((b*c - a*d)*f)), asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/((b*c - a*d)*sqrt(f)*sqrt(e + f*x)*sqrt(g + h*x))]
    @test_int [(A + B*x)/((a + b*x)^2*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 12, -((b*(A*b - a*B)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*(a + b*x))) + ((A*b - a*B)*sqrt(f)*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) - ((A*b - a*B)*sqrt(f)*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(b*(b*c - a*d)*(b*e - a*f)*sqrt(e + f*x)*sqrt(g + h*x)) + (sqrt((-d)*e + c*f)*(3*a^2*A*b*d*f*h - a^3*B*d*f*h - b^3*(2*B*c*e*g - A*(d*e*g + c*f*g + c*e*h)) + a*b^2*(B*(d*e*g + c*f*g + c*e*h) - 2*A*(d*f*g + d*e*h + c*f*h)))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.Pi(-((b*(d*e - c*f))/((b*c - a*d)*f)), asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(b*(b*c - a*d)^2*sqrt(f)*(b*e - a*f)*(b*g - a*h)*sqrt(e + f*x)*sqrt(g + h*x))]
    #= [(A + B*x)/((a + b*x)^3*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 13, -((b*(A*b - a*B)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(2*(b*c - a*d)*(b*e - a*f)*(b*g - a*h)*(a + b*x)^2)) - (b*(5*a^3*B*d*f*h + b^3*(4*B*c*e*g - 3*A*(d*e*g + c*f*g + c*e*h)) - a*b^2*(B*(d*e*g + c*f*g + c*e*h) - 6*A*(d*f*g + d*e*h + c*f*h)) - a^2*b*(9*A*d*f*h + 2*B*(d*f*g + d*e*h + c*f*h)))*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(4*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*(a + b*x)) + (sqrt(f)*sqrt((-d)*e + c*f)*(5*a^3*B*d*f*h + b^3*(4*B*c*e*g - 3*A*(d*e*g + c*f*g + c*e*h)) - a*b^2*(B*(d*e*g + c*f*g + c*e*h) - 6*A*(d*f*g + d*e*h + c*f*h)) - a^2*b*(9*A*d*f*h + 2*B*(d*f*g + d*e*h + c*f*h)))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(4*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) - (sqrt(f)*sqrt((-d)*e + c*f)*(3*a^3*B*d*f*h - a^2*b*d*f*(2*B*g + 7*A*h) + b^3*(4*B*c*e*g - A*(3*d*e*g + 3*c*f*g + c*e*h)) - a*b^2*(B*(d*e*g + c*f*g + 3*c*e*h) - 2*A*(3*d*f*g + 2*d*e*h + 2*c*f*h)))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(4*b*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)*sqrt(e + f*x)*sqrt(g + h*x)) - (sqrt((-d)*e + c*f)*(15*a^4*A*b*d^2*f^2*h^2 - 3*a^5*B*d^2*f^2*h^2 + 10*a^3*b^2*d*f*h*(B*(d*e*g + c*f*g + c*e*h) - 2*A*(d*f*g + d*e*h + c*f*h)) + a*b^4*(B*(d^2*e^2*g^2 + 14*c*d*e*g*(f*g + e*h) + c^2*(f^2*g^2 + 14*e*f*g*h + e^2*h^2)) - 4*A*(2*d^2*e*g*(f*g + e*h) + 2*c^2*f*h*(f*g + e*h) + c*d*(2*f^2*g^2 + 3*e*f*g*h + 2*e^2*h^2))) - b^5*(4*B*c*e*g*(d*e*g + c*f*g + c*e*h) - A*(3*d^2*e^2*g^2 + 2*c*d*e*g*(f*g + e*h) + c^2*(3*f^2*g^2 + 2*e*f*g*h + 3*e^2*h^2))) - 2*a^2*b^3*(2*B*(d^2*e*g*(f*g + e*h) + c^2*f*h*(f*g + e*h) + c*d*(f^2*g^2 + 9*e*f*g*h + e^2*h^2)) - A*(4*c^2*f^2*h^2 + 11*c*d*f*h*(f*g + e*h) + d^2*(4*f^2*g^2 + 11*e*f*g*h + 4*e^2*h^2))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.Pi(-((b*(d*e - c*f))/((b*c - a*d)*f)), asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(4*b*(b*c - a*d)^3*sqrt(f)*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(e + f*x)*sqrt(g + h*x))] =#

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*(a+b*x)^(m/2)*(c+d*x)^(n/2)*(A+B*x) / (Sqrte+f*x)*sqrt(g+h*x))=#

    #= ::Subsubsection:: =#
    #=n>0=#

    #= ::Subsubsection::Closed:: =#
    #=n<0=#

    @test_int [(a + b*x)^(3/2)*(A + B*x)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 10, ((5*a*B*d*f*h + b*(4*A*d*f*h - 3*B*(d*f*g + d*e*h + c*f*h)))*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(4*d*f^2*h^2*sqrt(c + d*x)) + (b*B*sqrt(a + b*x)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(2*d*f*h) - (sqrt(d*g - c*h)*sqrt(f*g - e*h)*(5*a*B*d*f*h + b*(4*A*d*f*h - 3*B*(d*f*g + d*e*h + c*f*h)))*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(4*d^2*f^2*h^2*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) - ((b*e - a*f)*sqrt(b*g - a*h)*(3*a*B*d*f*h + b*(4*A*d*f*h - B*(c*f*h + 3*d*(f*g + e*h))))*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(4*b*d*f^2*h^2*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) + (sqrt((-d)*g + c*h)*(4*d*f*h*(2*a*(2*A*b + a*B)*d*f*h - b*B*(b*(d*e*g + c*f*g + c*e*h) + a*(d*f*g + d*e*h + c*f*h))) - (a*d*f*h + b*(d*f*g + d*e*h + c*f*h))*(5*a*B*d*f*h + b*(4*A*d*f*h - 3*B*(d*f*g + d*e*h + c*f*h))))*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))/(4*b*d^2*sqrt(b*c - a*d)*f^2*h^3*sqrt(c + d*x)*sqrt(e + f*x))]
    @test_int [(a + b*x)^(1/2)*(A + B*x)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 7, (B*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(f*h*sqrt(c + d*x)) - (B*sqrt(d*g - c*h)*sqrt(f*g - e*h)*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(d*f*h*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) - (B*(b*e - a*f)*sqrt(b*g - a*h)*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(b*f*h*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) + (sqrt((-d)*g + c*h)*(2*A*b*d*f*h + B*(a*d*f*h - b*(d*f*g + d*e*h + c*f*h)))*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))/(b*d*sqrt(b*c - a*d)*f*h^2*sqrt(c + d*x)*sqrt(e + f*x))]
    @test_int [(A + B*x)/((a + b*x)^(1/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 5, (2*(A*b - a*B)*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(b*sqrt(b*g - a*h)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) + (2*B*sqrt((-d)*g + c*h)*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))/(b*sqrt(b*c - a*d)*h*sqrt(c + d*x)*sqrt(e + f*x))]
    @test_int [(A + B*x)/((a + b*x)^(3/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 7, (2*(A*b - a*B)*d*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(c + d*x)) - (2*b*(A*b - a*B)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(a + b*x)) - (2*(A*b - a*B)*sqrt(d*g - c*h)*sqrt(f*g - e*h)*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) + (2*(B*c - A*d)*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/((b*c - a*d)*sqrt(b*g - a*h)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x)))))]
    @test_int [(A + B*x)/((a + b*x)^(5/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 8, (2*d*(3*a^3*B*d*f*h + b^3*(3*B*c*e*g - 2*A*(d*e*g + c*f*g + c*e*h)) - a*b^2*(B*(d*e*g + c*f*g + c*e*h) - 4*A*(d*f*g + d*e*h + c*f*h)) - a^2*b*(6*A*d*f*h + B*(d*f*g + d*e*h + c*f*h)))*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(c + d*x)) - (2*b*(A*b - a*B)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)*(b*e - a*f)*(b*g - a*h)*(a + b*x)^(3/2)) - (2*b*(3*a^3*B*d*f*h + b^3*(3*B*c*e*g - 2*A*(d*e*g + c*f*g + c*e*h)) - a*b^2*(B*(d*e*g + c*f*g + c*e*h) - 4*A*(d*f*g + d*e*h + c*f*h)) - a^2*b*(6*A*d*f*h + B*(d*f*g + d*e*h + c*f*h)))*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(a + b*x)) - (2*sqrt(d*g - c*h)*sqrt(f*g - e*h)*(3*a^3*B*d*f*h + b^3*(3*B*c*e*g - 2*A*(d*e*g + c*f*g + c*e*h)) - a*b^2*(B*(d*e*g + c*f*g + c*e*h) - 4*A*(d*f*g + d*e*h + c*f*h)) - a^2*b*(6*A*d*f*h + B*(d*f*g + d*e*h + c*f*h)))*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) - (2*(3*a^2*d*(B*c - A*d)*f*h + b^2*(3*B*c*d*e*g - A*(2*d^2*e*g - c^2*f*h + c*d*(f*g + e*h))) + a*b*(3*A*d^2*(f*g + e*h) - B*(d^2*e*g + c^2*f*h + 2*c*d*(f*g + e*h))))*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(3*(b*c - a*d)^2*(b*e - a*f)*(b*g - a*h)^(3/2)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x)))))]

    @test_int [(a + b*x)^(3/2)*(d*e + c*f + 2*d*f*x)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 10, ((5*a*d*f*h - b*(3*d*f*g + d*e*h + c*f*h))*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(2*f*h^2*sqrt(c + d*x)) + (b*sqrt(a + b*x)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/h - (sqrt(d*g - c*h)*sqrt(f*g - e*h)*(5*a*d*f*h - b*(3*d*f*g + d*e*h + c*f*h))*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(2*d*f*h^2*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) - ((b*e - a*f)*sqrt(b*g - a*h)*(3*a*d*f*h + b*(c*f*h - d*(3*f*g + e*h)))*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(2*b*f*h^2*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) - (1/(2*b*d*sqrt(b*c - a*d)*f*h^3*sqrt(c + d*x)*sqrt(e + f*x)))*(sqrt((-d)*g + c*h)*(6*a*b*d^2*f^2*g*h - 3*a^2*d^2*f^2*h^2 + b^2*(2*c*d*e*f*h^2 - c^2*f^2*h^2 - d^2*(3*f^2*g^2 + e^2*h^2)))*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))]
    @test_int [(a + b*x)^(1/2)*(d*e + c*f + 2*d*f*x)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 5, (2*b*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(h*sqrt(a + b*x)) - (2*sqrt(b*g - a*h)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))*Elliptic.E(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(h*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)) - (2*d*(b*g - a*h)^(3/2)*sqrt(((f*g - e*h)*(a + b*x))/((b*g - a*h)*(e + f*x)))*sqrt(((f*g - e*h)*(c + d*x))/((d*g - c*h)*(e + f*x)))*(e + f*x)*Elliptic.Pi((f*(b*g - a*h))/((b*e - a*f)*h), asin((sqrt(b*e - a*f)*sqrt(g + h*x))/(sqrt(b*g - a*h)*sqrt(e + f*x))), ((d*e - c*f)*(b*g - a*h))/((b*e - a*f)*(d*g - c*h))))/(sqrt(b*e - a*f)*h^2*sqrt(a + b*x)*sqrt(c + d*x))]
    @test_int [(d*e + c*f + 2*d*f*x)/((a + b*x)^(1/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 5, (2*(b*d*e + b*c*f - 2*a*d*f)*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(b*sqrt(b*g - a*h)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) + (4*d*f*sqrt((-d)*g + c*h)*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))/(b*sqrt(b*c - a*d)*h*sqrt(c + d*x)*sqrt(e + f*x))]
    @test_int [(d*e + c*f + 2*d*f*x)/((a + b*x)^(3/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 7, (2*d*(b*d*e + b*c*f - 2*a*d*f)*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(c + d*x)) - (2*b*(b*d*e + b*c*f - 2*a*d*f)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(a + b*x)) - (2*(b*d*e + b*c*f - 2*a*d*f)*sqrt(d*g - c*h)*sqrt(f*g - e*h)*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) - (2*d*(d*e - c*f)*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/((b*c - a*d)*sqrt(b*g - a*h)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x)))))]
    @test_int [(d*e + c*f + 2*d*f*x)/((a + b*x)^(5/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 8, (4*d*(3*a^3*d^2*f^2*h - a^2*b*d*f*(d*f*g + 4*d*e*h + 4*c*f*h) - b^3*(d^2*e^2*g - c*d*e*(f*g - e*h) + c^2*f*(f*g + e*h)) + a*b^2*(2*c^2*f^2*h + d^2*e*(f*g + 2*e*h) + c*d*f*(f*g + 3*e*h)))*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(c + d*x)) - (2*b*(b*d*e + b*c*f - 2*a*d*f)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)*(b*e - a*f)*(b*g - a*h)*(a + b*x)^(3/2)) - (4*b*(3*a^3*d^2*f^2*h - a^2*b*d*f*(d*f*g + 4*d*e*h + 4*c*f*h) - b^3*(d^2*e^2*g - c*d*e*(f*g - e*h) + c^2*f*(f*g + e*h)) + a*b^2*(2*c^2*f^2*h + d^2*e*(f*g + 2*e*h) + c*d*f*(f*g + 3*e*h)))*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(a + b*x)) - (4*sqrt(d*g - c*h)*sqrt(f*g - e*h)*(3*a^3*d^2*f^2*h - a^2*b*d*f*(d*f*g + 4*d*e*h + 4*c*f*h) - b^3*(d^2*e^2*g - c*d*e*(f*g - e*h) + c^2*f*(f*g + e*h)) + a*b^2*(2*c^2*f^2*h + d^2*e*(f*g + 2*e*h) + c*d*f*(f*g + 3*e*h)))*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) + (2*(d*e - c*f)*(3*a^2*d^2*f*h - a*b*d*(d*f*g + 3*d*e*h + 2*c*f*h) + b^2*(2*d^2*e*g - c*d*f*g + c*d*e*h + c^2*f*h))*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(3*(b*c - a*d)^2*(b*e - a*f)*(b*g - a*h)^(3/2)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x)))))]

    #= ::Title:: =#
    #=Integrands*of*the*form*P3(x)*(a+b*x)^m*(c+d*x)^n*(e+f*x)^p*(g+h*x)^q=#

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*(a+b*x)^m*(c+d*x)^(n/2)*(e+f*x)^(p/2)*(g+h*x)^(q/2)*(A+B*x+C*x^2)*with*A*b^2-a*b*B+a^2*C=0=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(a+b*x)^m*(c+d*x)^(n/2)*(A+B*x+C*x^2) / (Sqrte+f*x)*sqrt(g+h*x))=#

    #= ::Subsubsection:: =#
    #=n>0=#

    #= ::Subsubsection::Closed:: =#
    #=n<0=#

    @test_int [(a + b*x)^1*(a*b*B - a^2*C + b^2*B*x + b^2*C*x^2)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 8, (2*b^2*(5*b*B*d*f*h + 2*C*(a*d*f*h - 2*b*(d*f*g + d*e*h + c*f*h)))*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(15*d^2*f^2*h^2) + (2*b^2*C*(a + b*x)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(5*d*f*h) - (1/(15*d^3*f^(5/2)*h^3*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))))*(2*b*sqrt((-d)*e + c*f)*(15*a^2*C*d^2*f^2*h^2 - 10*a*b*d*f*h*(3*B*d*f*h - C*(d*f*g + d*e*h + c*f*h)) + b^2*(10*B*d*f*h*(d*f*g + d*e*h + c*f*h) - C*(8*c^2*f^2*h^2 + 7*c*d*f*h*(f*g + e*h) + d^2*(8*f^2*g^2 + 7*e*f*g*h + 8*e^2*h^2))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h)))) - (1/(15*d^3*f^(5/2)*h^3*sqrt(e + f*x)*sqrt(g + h*x)))*(2*sqrt((-d)*e + c*f)*(15*a^3*C*d^2*f^2*h^3 - 15*a^2*b*d^2*f^2*h^2*(C*g + B*h) + 5*a*b^2*d*f*h*(6*B*d*f*g*h - C*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h))) - b^3*(5*B*d*f*h*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h)) - C*(4*c^2*f*h^2*(f*g - e*h) + c*d*h*(3*f^2*g^2 + e*f*g*h - 4*e^2*h^2) + d^2*g*(8*f^2*g^2 + 3*e*f*g*h + 4*e^2*h^2))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))]
    @test_int [(a + b*x)^0*(a*b*B - a^2*C + b^2*B*x + b^2*C*x^2)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 7, (2*b^2*C*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*d*f*h) + (2*b^2*sqrt((-d)*e + c*f)*(3*B*d*f*h - 2*C*(d*f*g + d*e*h + c*f*h))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(3*d^2*f^(3/2)*h^2*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) + (2*sqrt((-d)*e + c*f)*(3*a*b*B*d*f*h^2 - 3*a^2*C*d*f*h^2 - b^2*(3*B*d*f*g*h - C*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(3*d^2*f^(3/2)*h^2*sqrt(e + f*x)*sqrt(g + h*x))]
    @test_int [(a*b*B - a^2*C + b^2*B*x + b^2*C*x^2)/((a + b*x)^1*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 7, (2*b*C*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(d*sqrt(f)*h*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) - (2*sqrt((-d)*e + c*f)*(b*C*g - b*B*h + a*C*h)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(d*sqrt(f)*h*sqrt(e + f*x)*sqrt(g + h*x))]
    @test_int [(a*b*B - a^2*C + b^2*B*x + b^2*C*x^2)/((a + b*x)^2*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 10, (2*C*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(d*sqrt(f)*sqrt(e + f*x)*sqrt(g + h*x)) - (2*(b*B - 2*a*C)*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.Pi(-((b*(d*e - c*f))/((b*c - a*d)*f)), asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/((b*c - a*d)*sqrt(f)*sqrt(e + f*x)*sqrt(g + h*x))]
    @test_int [(a*b*B - a^2*C + b^2*B*x + b^2*C*x^2)/((a + b*x)^3*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 13, -((b^2*(b*B - 2*a*C)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*(a + b*x))) + (b*(b*B - 2*a*C)*sqrt(f)*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) - ((b*B - 2*a*C)*sqrt(f)*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/((b*c - a*d)*(b*e - a*f)*sqrt(e + f*x)*sqrt(g + h*x)) - (sqrt((-d)*e + c*f)*(4*a^3*C*d*f*h + 2*a*b^2*B*(d*f*g + d*e*h + c*f*h) - b^3*(B*d*e*g - c*(2*C*e*g - B*f*g - B*e*h)) - a^2*b*(3*B*d*f*h + 2*C*(d*f*g + d*e*h + c*f*h)))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.Pi(-((b*(d*e - c*f))/((b*c - a*d)*f)), asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/((b*c - a*d)^2*sqrt(f)*(b*e - a*f)*(b*g - a*h)*sqrt(e + f*x)*sqrt(g + h*x))]

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(a+b*x)^(m/2)*(c+d*x)^(n/2)*(A+B*x+C*x^2) / (Sqrte+f*x)*sqrt(g+h*x))=#

    #= ::Subsubsection:: =#
    #=n>0=#

    #= ::Subsubsection::Closed:: =#
    #=n<0=#

    @test_int [(a + b*x)^(1/2)*(a*b*B - a^2*C + b^2*B*x + b^2*C*x^2)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 9, (b*(4*b*B*d*f*h + C*(a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h)))*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(4*d*f^2*h^2*sqrt(c + d*x)) + (b^2*C*sqrt(a + b*x)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(2*d*f*h) - (b*sqrt(d*g - c*h)*sqrt(f*g - e*h)*(4*b*B*d*f*h + C*(a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h)))*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(4*d^2*f^2*h^2*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) + ((b*e - a*f)*sqrt(b*g - a*h)*(a*C*d*f*h - b*(4*B*d*f*h - C*(3*d*f*g + 3*d*e*h + c*f*h)))*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(4*d*f^2*h^2*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) - (1/(4*d^2*sqrt(b*c - a*d)*f^2*h^3*sqrt(c + d*x)*sqrt(e + f*x)))*(sqrt((-d)*g + c*h)*((a*d*f*h + b*(d*f*g + d*e*h + c*f*h))*(4*b*B*d*f*h + C*(a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h))) + 4*d*f*h*(2*a^2*C*d*f*h + b^2*C*(d*e*g + c*f*g + c*e*h) - a*b*(4*B*d*f*h - C*(d*f*g + d*e*h + c*f*h))))*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))]
    @test_int [(a*b*B - a^2*C + b^2*B*x + b^2*C*x^2)/((a + b*x)^(1/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 8, (b*C*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(f*h*sqrt(c + d*x)) - (b*C*sqrt(d*g - c*h)*sqrt(f*g - e*h)*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(d*f*h*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) - (C*(b*e - a*f)*sqrt(b*g - a*h)*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(f*h*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) - (sqrt((-d)*g + c*h)*(a*C*d*f*h - b*(2*B*d*f*h - C*(d*f*g + d*e*h + c*f*h)))*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))/(d*sqrt(b*c - a*d)*f*h^2*sqrt(c + d*x)*sqrt(e + f*x))]
    @test_int [(a*b*B - a^2*C + b^2*B*x + b^2*C*x^2)/((a + b*x)^(3/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 6, (2*(b*B - 2*a*C)*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(sqrt(b*g - a*h)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) + (2*C*sqrt((-d)*g + c*h)*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))/(sqrt(b*c - a*d)*h*sqrt(c + d*x)*sqrt(e + f*x))]
    @test_int [(a*b*B - a^2*C + b^2*B*x + b^2*C*x^2)/((a + b*x)^(5/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 8, (2*b*(b*B - 2*a*C)*d*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(c + d*x)) - (2*b^2*(b*B - 2*a*C)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(a + b*x)) - (2*b*(b*B - 2*a*C)*sqrt(d*g - c*h)*sqrt(f*g - e*h)*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) + (2*(b*c*C - b*B*d + a*C*d)*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/((b*c - a*d)*sqrt(b*g - a*h)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x)))))]
    @test_int [(a*b*B - a^2*C + b^2*B*x + b^2*C*x^2)/((a + b*x)^(7/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 9, (2*b*d*(9*a^3*C*d*f*h - b^3*(2*B*d*e*g - c*(3*C*e*g - 2*B*f*g - 2*B*e*h)) + a*b^2*(C*(d*e*g + c*f*g + c*e*h) + 4*B*(d*f*g + d*e*h + c*f*h)) - a^2*b*(6*B*d*f*h + 5*C*(d*f*g + d*e*h + c*f*h)))*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(c + d*x)) - (2*b^2*(b*B - 2*a*C)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)*(b*e - a*f)*(b*g - a*h)*(a + b*x)^(3/2)) - (2*b^2*(9*a^3*C*d*f*h - b^3*(2*B*d*e*g - c*(3*C*e*g - 2*B*f*g - 2*B*e*h)) + a*b^2*(C*(d*e*g + c*f*g + c*e*h) + 4*B*(d*f*g + d*e*h + c*f*h)) - a^2*b*(6*B*d*f*h + 5*C*(d*f*g + d*e*h + c*f*h)))*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(a + b*x)) - (2*b*sqrt(d*g - c*h)*sqrt(f*g - e*h)*(9*a^3*C*d*f*h - b^3*(2*B*d*e*g - c*(3*C*e*g - 2*B*f*g - 2*B*e*h)) + a*b^2*(C*(d*e*g + c*f*g + c*e*h) + 4*B*(d*f*g + d*e*h + c*f*h)) - a^2*b*(6*B*d*f*h + 5*C*(d*f*g + d*e*h + c*f*h)))*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) - (2*(3*a^3*C*d^2*f*h - b^3*(2*B*d^2*e*g - B*c^2*f*h - c*d*(3*C*e*g - B*f*g - B*e*h)) - 3*a^2*b*d*(B*d*f*h + C*(d*f*g + d*e*h - c*f*h)) + a*b^2*(3*B*d^2*(f*g + e*h) + C*(d^2*e*g - c*d*f*g - c*d*e*h - 2*c^2*f*h)))*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(3*(b*c - a*d)^2*(b*e - a*f)*(b*g - a*h)^(3/2)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x)))))]

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*(a+b*x)^m*(c+d*x)^(n/2)*(e+f*x)^(p/2)*(g+h*x)^(q/2)*(A+B*x+C*x^2)*with*B=0=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(a+b*x)^m*(c+d*x)^(n/2)*(A+B*x+C*x^2) / (Sqrte+f*x)*sqrt(g+h*x))=#

    #= ::Subsubsection:: =#
    #=n>0=#

    #= ::Subsubsection::Closed:: =#
    #=n<0=#

    @test_int [(a + b*x)^2*(A + C*x^2)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 9, (2*(4*C*(2*a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h))*(a*d*f*h - 2*b*(d*f*g + d*e*h + c*f*h)) + 5*b*d*f*h*(7*A*b*d*f*h - C*(5*b*(d*e*g + c*f*g + c*e*h) + 2*a*(d*f*g + d*e*h + c*f*h))))*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(105*d^3*f^3*h^3) + (4*C*(2*a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h))*(a + b*x)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(35*d^2*f^2*h^2) + (2*C*(a + b*x)^2*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(7*d*f*h) - (1/(105*d^4*f^(7/2)*h^4*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))))*(4*sqrt((-d)*e + c*f)*(35*a^2*C*d^2*f^2*h^2*(d*f*g + d*e*h + c*f*h) - 7*a*b*d*f*h*(15*A*d^2*f^2*h^2 + C*(8*c^2*f^2*h^2 + 7*c*d*f*h*(f*g + e*h) + d^2*(8*f^2*g^2 + 7*e*f*g*h + 8*e^2*h^2))) + b^2*(35*A*d^2*f^2*h^2*(d*f*g + d*e*h + c*f*h) + 2*C*(12*c^3*f^3*h^3 + 10*c^2*d*f^2*h^2*(f*g + e*h) + c*d^2*f*h*(10*f^2*g^2 + 9*e*f*g*h + 10*e^2*h^2) + 2*d^3*(6*f^3*g^3 + 5*e*f^2*g^2*h + 5*e^2*f*g*h^2 + 6*e^3*h^3))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h)))) + (1/(105*d^4*f^(7/2)*h^4*sqrt(e + f*x)*sqrt(g + h*x)))*(2*sqrt((-d)*e + c*f)*(35*a^2*d^2*f^2*h^2*(3*A*d*f*h^2 + C*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h))) - 14*a*b*d*f*h*(15*A*d^2*f^2*g*h^2 + C*(4*c^2*f*h^2*(f*g - e*h) + c*d*h*(3*f^2*g^2 + e*f*g*h - 4*e^2*h^2) + d^2*g*(8*f^2*g^2 + 3*e*f*g*h + 4*e^2*h^2))) + b^2*(35*A*d^2*f^2*h^2*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h)) + C*(24*c^3*f^2*h^3*(f*g - e*h) + c^2*d*f*h^2*(17*f^2*g^2 + 6*e*f*g*h - 23*e^2*h^2) + 2*c*d^2*h*(8*f^3*g^3 + e*f^2*g^2*h + 3*e^2*f*g*h^2 - 12*e^3*h^3) + d^3*g*(48*f^3*g^3 + 16*e*f^2*g^2*h + 17*e^2*f*g*h^2 + 24*e^3*h^3))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))]
    @test_int [(a + b*x)^1*(A + C*x^2)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 8, (4*C*(a*d*f*h - 2*b*(d*f*g + d*e*h + c*f*h))*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(15*d^2*f^2*h^2) + (2*C*(a + b*x)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(5*d*f*h) - (2*sqrt((-d)*e + c*f)*(10*a*C*d*f*h*(d*f*g + d*e*h + c*f*h) - b*(15*A*d^2*f^2*h^2 + C*(8*c^2*f^2*h^2 + 7*c*d*f*h*(f*g + e*h) + d^2*(8*f^2*g^2 + 7*e*f*g*h + 8*e^2*h^2))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(15*d^3*f^(5/2)*h^3*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) + (1/(15*d^3*f^(5/2)*h^3*sqrt(e + f*x)*sqrt(g + h*x)))*(2*sqrt((-d)*e + c*f)*(5*a*d*f*h*(3*A*d*f*h^2 + C*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h))) - b*(15*A*d^2*f^2*g*h^2 + C*(4*c^2*f*h^2*(f*g - e*h) + c*d*h*(3*f^2*g^2 + e*f*g*h - 4*e^2*h^2) + d^2*g*(8*f^2*g^2 + 3*e*f*g*h + 4*e^2*h^2))))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))]
    @test_int [(a + b*x)^0*(A + C*x^2)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 7, (2*C*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*d*f*h) - (4*C*sqrt((-d)*e + c*f)*(d*f*g + d*e*h + c*f*h)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(3*d^2*f^(3/2)*h^2*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) + (2*sqrt((-d)*e + c*f)*(3*A*d*f*h^2 + C*(c*h*(f*g - e*h) + d*g*(2*f*g + e*h)))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(3*d^2*f^(3/2)*h^2*sqrt(e + f*x)*sqrt(g + h*x))]
    @test_int [(A + C*x^2)/((a + b*x)^1*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 11, (2*C*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(b*d*sqrt(f)*h*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) - (2*C*sqrt((-d)*e + c*f)*(b*g + a*h)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(b^2*d*sqrt(f)*h*sqrt(e + f*x)*sqrt(g + h*x)) - (2*(A + (a^2*C)/b^2)*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.Pi(-((b*(d*e - c*f))/((b*c - a*d)*f)), asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/((b*c - a*d)*sqrt(f)*sqrt(e + f*x)*sqrt(g + h*x))]
    @test_int [(A + C*x^2)/((a + b*x)^2*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 12, -(((A*b^2 + a^2*C)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*(a + b*x))) + ((A*b + (a^2*C)/b)*sqrt(f)*sqrt((-d)*e + c*f)*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt(g + h*x)*Elliptic.E(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(e + f*x)*sqrt((d*(g + h*x))/(d*g - c*h))) + (sqrt((-d)*e + c*f)*(a^2*C*d*f - 2*a*b*C*(d*e + c*f) + b^2*(2*c*C*e - A*d*f))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.F(asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))/(b^2*d*(b*c - a*d)*sqrt(f)*(b*e - a*f)*sqrt(e + f*x)*sqrt(g + h*x)) - (1/(b^2*(b*c - a*d)^2*sqrt(f)*(b*e - a*f)*(b*g - a*h)*sqrt(e + f*x)*sqrt(g + h*x)))*(sqrt((-d)*e + c*f)*(a^4*C*d*f*h - A*b^4*(d*e*g + c*f*g + c*e*h) - 2*a^3*b*C*(d*f*g + d*e*h + c*f*h) - 2*a*b^3*(2*c*C*e*g - A*d*f*g - A*d*e*h - A*c*f*h) - 3*a^2*b^2*(A*d*f*h - C*(d*e*g + c*f*g + c*e*h)))*sqrt((d*(e + f*x))/(d*e - c*f))*sqrt((d*(g + h*x))/(d*g - c*h))*Elliptic.Pi(-((b*(d*e - c*f))/((b*c - a*d)*f)), asin((sqrt(f)*sqrt(c + d*x))/sqrt((-d)*e + c*f)), ((d*e - c*f)*h)/(f*(d*g - c*h))))]

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(a+b*x)^(m/2)*(c+d*x)^(n/2)*(A+B*x+C*x^2) / (Sqrte+f*x)*sqrt(g+h*x))=#

    #= ::Subsubsection:: =#
    #=n>0=#

    #= ::Subsubsection::Closed:: =#
    #=n<0=#

    @test_int [(a + b*x)^(3/2)*(A + C*x^2)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 10, ((C*(3*a*d*f*h - 5*b*(d*f*g + d*e*h + c*f*h))*(a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h)) + 8*b*d*f*h*(3*A*b*d*f*h - C*(2*b*(d*e*g + c*f*g + c*e*h) + a*(d*f*g + d*e*h + c*f*h))))*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(24*b*d^2*f^3*h^3*sqrt(c + d*x)) + (C*(3*a*d*f*h - 5*b*(d*f*g + d*e*h + c*f*h))*sqrt(a + b*x)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(12*d^2*f^2*h^2) + (C*(a + b*x)^(3/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*d*f*h) - (sqrt(d*g - c*h)*sqrt(f*g - e*h)*(C*(3*a*d*f*h - 5*b*(d*f*g + d*e*h + c*f*h))*(a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h)) + 8*b*d*f*h*(3*A*b*d*f*h - C*(2*b*(d*e*g + c*f*g + c*e*h) + a*(d*f*g + d*e*h + c*f*h))))*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(24*b*d^3*f^3*h^3*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) + ((b*e - a*f)*sqrt(b*g - a*h)*(3*a^2*C*d^2*f^2*h^2 + 6*a*b*C*d*f*h*(c*f*h + 2*d*(f*g + e*h)) - b^2*(24*A*d^2*f^2*h^2 + C*(5*c^2*f^2*h^2 + 4*c*d*f*h*(f*g + e*h) + d^2*(15*f^2*g^2 + 14*e*f*g*h + 15*e^2*h^2))))*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(24*b^2*d^2*f^3*h^3*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) - (1/(24*b^2*d^3*sqrt(b*c - a*d)*f^3*h^4*sqrt(c + d*x)*sqrt(e + f*x)))*(sqrt((-d)*g + c*h)*(4*b*d*f*h*(C*(b*(d*e*g + c*f*g + c*e*h) + a*(d*f*g + d*e*h + c*f*h))*(3*a*d*f*h - 5*b*(d*f*g + d*e*h + c*f*h)) + 2*d*f*h*(3*b^2*c*C*e*g + 2*a^2*C*(d*f*g + d*e*h + c*f*h) - a*b*(12*A*d*f*h - 5*C*(d*e*g + c*f*g + c*e*h)))) + (a*d*f*h + b*(d*f*g + d*e*h + c*f*h))*(C*(3*a*d*f*h - 5*b*(d*f*g + d*e*h + c*f*h))*(a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h)) + 8*b*d*f*h*(3*A*b*d*f*h - C*(2*b*(d*e*g + c*f*g + c*e*h) + a*(d*f*g + d*e*h + c*f*h)))))*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))]
    @test_int [(a + b*x)^(1/2)*(A + C*x^2)/(sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 9, (C*(a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h))*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(4*b*d*f^2*h^2*sqrt(c + d*x)) + (C*sqrt(a + b*x)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(2*d*f*h) - (C*sqrt(d*g - c*h)*sqrt(f*g - e*h)*(a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h))*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(4*b*d^2*f^2*h^2*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) + (C*(b*e - a*f)*sqrt(b*g - a*h)*(a*d*f*h + b*(c*f*h + 3*d*(f*g + e*h)))*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(4*b^2*d*f^2*h^2*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) - (sqrt((-d)*g + c*h)*(C*(a*d*f*h - 3*b*(d*f*g + d*e*h + c*f*h))*(a*d*f*h + b*(d*f*g + d*e*h + c*f*h)) - 4*b*d*f*h*(2*A*b*d*f*h - C*(b*(d*e*g + c*f*g + c*e*h) + a*(d*f*g + d*e*h + c*f*h))))*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))/(4*b^2*d^2*sqrt(b*c - a*d)*f^2*h^3*sqrt(c + d*x)*sqrt(e + f*x))]
    @test_int [(A + C*x^2)/((a + b*x)^(1/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 8, (C*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(b*f*h*sqrt(c + d*x)) - (C*sqrt(d*g - c*h)*sqrt(f*g - e*h)*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(b*d*f*h*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) + ((a^2*C*f*h + a*b*C*(f*g + e*h) - b^2*(C*e*g - 2*A*f*h))*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(b^2*f*h*sqrt(b*g - a*h)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) - (C*sqrt((-d)*g + c*h)*(a*d*f*h + b*(d*f*g + d*e*h + c*f*h))*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))/(b^2*d*sqrt(b*c - a*d)*f*h^2*sqrt(c + d*x)*sqrt(e + f*x))]
    @test_int [(A + C*x^2)/((a + b*x)^(3/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 9, (2*(A*b^2 + a^2*C)*d*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(b*(b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(c + d*x)) - (2*(A*b^2 + a^2*C)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/((b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(a + b*x)) - (2*(A*b^2 + a^2*C)*sqrt(d*g - c*h)*sqrt(f*g - e*h)*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(b*(b*c - a*d)*(b*e - a*f)*(b*g - a*h)*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) - (2*(2*a*b*c*C + A*b^2*d - a^2*C*d)*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(b^2*(b*c - a*d)*sqrt(b*g - a*h)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x))))) + (2*C*sqrt((-d)*g + c*h)*(a + b*x)*sqrt(((b*g - a*h)*(c + d*x))/((d*g - c*h)*(a + b*x)))*sqrt(((b*g - a*h)*(e + f*x))/((f*g - e*h)*(a + b*x)))*Elliptic.Pi(-((b*(d*g - c*h))/((b*c - a*d)*h)), asin((sqrt(b*c - a*d)*sqrt(g + h*x))/(sqrt((-d)*g + c*h)*sqrt(a + b*x))), ((b*e - a*f)*(d*g - c*h))/((b*c - a*d)*(f*g - e*h))))/(b^2*sqrt(b*c - a*d)*h*sqrt(c + d*x)*sqrt(e + f*x))]
    @test_int [(A + C*x^2)/((a + b*x)^(5/2)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x)), x, 8, -((4*d*(A*b^3*(d*e*g + c*f*g + c*e*h) + a^3*C*(d*f*g + d*e*h + c*f*h) + a^2*b*(3*A*d*f*h - 2*C*(d*e*g + c*f*g + c*e*h)) - a*b^2*(2*A*d*(f*g + e*h) - c*(3*C*e*g - 2*A*f*h)))*sqrt(a + b*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(c + d*x))) - (2*(A*b^2 + a^2*C)*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)*(b*e - a*f)*(b*g - a*h)*(a + b*x)^(3/2)) + (4*b*(A*b^3*(d*e*g + c*f*g + c*e*h) + a^3*C*(d*f*g + d*e*h + c*f*h) + a^2*b*(3*A*d*f*h - 2*C*(d*e*g + c*f*g + c*e*h)) - a*b^2*(2*A*d*(f*g + e*h) - c*(3*C*e*g - 2*A*f*h)))*sqrt(c + d*x)*sqrt(e + f*x)*sqrt(g + h*x))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(a + b*x)) + (4*sqrt(d*g - c*h)*sqrt(f*g - e*h)*(A*b^3*(d*e*g + c*f*g + c*e*h) + a^3*C*(d*f*g + d*e*h + c*f*h) + a^2*b*(3*A*d*f*h - 2*C*(d*e*g + c*f*g + c*e*h)) - a*b^2*(2*A*d*(f*g + e*h) - c*(3*C*e*g - 2*A*f*h)))*sqrt(a + b*x)*sqrt(-(((d*e - c*f)*(g + h*x))/((f*g - e*h)*(c + d*x))))*Elliptic.E(asin((sqrt(d*g - c*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(c + d*x))), ((b*c - a*d)*(f*g - e*h))/((b*e - a*f)*(d*g - c*h))))/(3*(b*c - a*d)^2*(b*e - a*f)^2*(b*g - a*h)^2*sqrt(((d*e - c*f)*(a + b*x))/((b*e - a*f)*(c + d*x)))*sqrt(g + h*x)) - (2*(3*a*b*(c^2*C + A*d^2)*(f*g + e*h) - b^2*(2*A*d^2*e*g + A*c*d*(f*g + e*h) + c^2*(3*C*e*g - A*f*h)) - a^2*(3*A*d^2*f*h - C*(d^2*e*g - c*d*f*g - c*d*e*h - 2*c^2*f*h)))*sqrt(((b*e - a*f)*(c + d*x))/((d*e - c*f)*(a + b*x)))*sqrt(g + h*x)*Elliptic.F(asin((sqrt(b*g - a*h)*sqrt(e + f*x))/(sqrt(f*g - e*h)*sqrt(a + b*x))), -(((b*c - a*d)*(f*g - e*h))/((d*e - c*f)*(b*g - a*h)))))/(3*(b*c - a*d)^2*(b*e - a*f)*(b*g - a*h)^(3/2)*sqrt(f*g - e*h)*sqrt(c + d*x)*sqrt(-(((b*e - a*f)*(g + h*x))/((f*g - e*h)*(a + b*x)))))]
    end

max_stars_repo_path: test/1 Algebraic functions/1.1 Binomial products/1.1.1 Linear/1.1.1.7 P(x) (a+b x)^m (c+d x)^n (e+f x)^p (g+h x)^q.jl


text:
__precompile__(false)
module ANNBN
    # __precompile__()
    using Plots, Statistics, Dates, LinearAlgebra, Random, SpecialFunctions, Clustering, IterativeSolvers
    using Base.Threads
    # using CUDAdrv, CUDAnative, CuArrays
    # __precompile__()

    function sigm1(x) 1.0/(1.0+exp(-x)) end
    function isigm1(x) -log((1.0-x)/x) end
    # function sigm1(x) atan(x) end
    # function isigm1(x) tan(x) end
    # function sigm1(x) 2atan(pi*x/2)/pi end
    # function isigm1(x) 2tan(pi*x/2)/pi end
    # function sigm1(x) x^2 end
    # function isigm1(x) sqrt(x) end
    # function sigm1(x) max(0,x) end
    # function isigm1(x) if x>0.1 return x else return -1.0 end end
    # function sigm1(x) log(1.0+exp(x)) end
    # function isigm1(x) log(exp(x)-1.0) end
    # function sigm1(x) if x<-1.0 -1.0 elseif x<1.0 x else 1.0 end end
    # function isigm1(x) if x<-1.0 -10.0 elseif x<1.0 x else 10.0 end end
    # function sigm1(x) 1.0/(1.0+exp(-1000.0x)) end
    # function isigm1(x) -log((1.0-1000.0x)/1000.0x) end
    # function sigm1(x) erf(x) end
    # function isigm1(x) erfi(x) end
    # function sigm1(x) exp(x) end
    # function isigm1(x) log(x) end
    # function sigm1(x) x^3 end
    # function isigm1(x) x^(1/3) end

    include("___clustering.jl")
    # include("new_clustering.jl")
    # include("___augment_data.jl")

    include("calc_phi.jl")
    include("calc_phi_deriv.jl")
    include("calc_phi_deriv_deriv.jl")
    include("predict_new.jl")
    include("predict_new_rbf.jl")
    include("predict_new_rbf_deriv.jl")
    include("predict_new_rbf_deriv_deriv.jl")
    include("train_layer_1_rbf.jl")
    include("train_layer_1_rbf_pde.jl")
    include("train_layer_1_sigmoid.jl")
    include("train_layer_1_sigmoid_fast.jl")
    include("train_layer_1_sigmoid_fast2.jl")
    include("train_layer_1_rbf_fast.jl")
    include("train_layer_1_rbf_deriv.jl")

    include("fit_nfolds!.jl")
    include("predict_nfolds.jl")
    include("fit_nfolds_sigmoid.jl")
    include("predict_nfolds_sigmoid.jl")

    include("deep_nnm.jl")
    include("initialize_deep_weights_per_layer.jl")
    # include("run_iit.jl")

    # include("train_layer_1_rbf_fast.jl")
    include("train_layer_1_rbf_new.jl")

    export ___clustering,new_clustering,
    calc_phi,calc_phi_deriv,calc_phi_deriv_deriv,
    predict_new,predict_new_rbf,predict_new_rbf_deriv,predict_new_rbf_deriv_deriv,
    train_layer_1_rbf,train_layer_1_rbf_pde,train_layer_1_sigmoid,
    fit_nfolds!,predict_nfolds,fit_nfolds_sigmoid,predict_nfolds_sigmoid,train_layer_1_rbf_fast,
    deep_nnm,initialize_deep_weights_per_layer,run_iit,train_layer_1_rbf_new,train_layer_1_rbf_deriv,
	train_layer_1_sigmoid_fast,train_layer_1_sigmoid_fast2

    # precompile(sigm1, (Float64,))
    # precompile(isigm1, (Float64,))
    # precompile(deep_nnm, (Array{Float64,1},Array{Float64,2},Array{Float64,2},Int64,Int64,Int64))
    # precompile(calc_phi, (Array{Float64,2},Array{Float64,2},Int64,Int64,Float64,Int64))

end

ext: jl


text:
@testset "Pagerank" begin
    g5 = DiGraph(4)
    add_edge!(g5, 1, 2); add_edge!(g5, 2, 3); add_edge!(g5, 1, 3); add_edge!(g5, 3, 4)
    for g in testdigraphs(g5)
      @test pagerank(g)[3] ≈ 0.318 atol = 0.001
      @test length(@inferred(pagerank(g))) == nv(g)
      @test_throws ErrorException pagerank(g, 2)
      @test_throws ErrorException pagerank(g, 0.85, 2)
    end
end


text:
"""
    struct DefaultReward <: AbstractReward end

This is the default reward, that will be used if no custom reward is specified when constructing the `LearnedHeuristic`.
"""
mutable struct DefaultReward <: AbstractReward
    value::Float32
end

DefaultReward(model::CPModel) = DefaultReward(0)

"""
    set_reward!(::StepPhase, lh::LearnedHeuristic{DefaultReward, A}, model::CPModel, symbol::Union{Nothing, Symbol})

Change the "current_reward" attribute of the LearnedHeuristic at the StepPhase.
"""
function set_reward!(::Type{StepPhase}, lh::LearnedHeuristic{SR, DefaultReward, A}, model::CPModel, symbol::Union{Nothing, Symbol}) where {
    SR <: AbstractStateRepresentation,
    A <: ActionOutput
}
    if symbol == :Infeasible
        lh.reward.value -= 10*model.statistics.numberOfNodes

    elseif symbol == :FoundSolution
        lh.reward.value -= 1

    elseif symbol == :Feasible
        lh.reward.value -= 1

    elseif symbol == :BackTracking
        lh.reward.value -= 1
    end
end

"""
    set_reward!(::DecisionPhase, lh::LearnedHeuristic{DefaultReward, O}, model::CPModel)

Change the current reward at the DecisionPhase. This is called right before making the next decision, so you know you have the very last state before the new decision
and every computation like fixPoints and backtracking has been done.
"""
function set_reward!(::Type{DecisionPhase}, lh::LearnedHeuristic{SR, DefaultReward, A}, model::CPModel) where {
    SR <: AbstractStateRepresentation,
    A <: ActionOutput
}
    lh.reward.value += -1/40

end

"""
    set_reward!(::EndingPhase, lh::LearnedHeuristic{DefaultReward, A}, model::CPModel, symbol::Union{Nothing, Symbol})

Increment the current reward at the EndingPhase. Called when the search is finished by an optimality proof or by a limit in term of nodes or
in terms of number of solution. This is useful to add some general results to the reward like the number of ndoes visited during the episode for instance.
"""
function set_reward!(::Type{EndingPhase}, lh::LearnedHeuristic{SR, DefaultReward, A}, model::CPModel, symbol::Union{Nothing, Symbol}) where {
    SR <: AbstractStateRepresentation,
    A <: ActionOutput
}
    lh.reward.value += 1

end


text:
a = 2
b = 3
c = 5

mf = BellMF(a, b, c)

# Evaluation tests
@assert mf.eval(c) == 1
@assert mf.eval(c - a) == mf.eval(c + a) == 0.5

# Mean finding tests
@assert mf.mean_at(1) == mf.mean_at(0.6) == mf.mean_at(0.3) == mf.mean_at(0) == c


text:
module GameServiceImpl

using Niancat.Gameface
using Niancat.Persistence
using Niancat.Http
using Niancat.Users
using Niancat.Scores
using Niancat.Formatters
using Niancat.Languages
import Niancat.Gameface: score!, gameinstanceid, notify!, event!, finddictionary

"""
ConcreteGameService is merely the implementation of the `GameService` interface.
The interface is abstract for testing purposes.
"""
struct ConcreteGameService <: GameService
    instanceinfo::InstanceInfo
    gameinstanceid::Int
    persistence::GameEventPersistence
    httpclient::HttpClient
end

Gameface.score!(g::ConcreteGameService, user::User, score::Score) = score!(g.persistence, user, score)
Gameface.gameinstanceid(g::ConcreteGameService) = g.gameinstanceid

function notifytext!(g::ConcreteGameService, text::String)
    endpoints = getnotificationendpoints(g.persistence, g.instanceinfo.databaseid)

    for endpoint in endpoints
        post(g.httpclient, endpoint, text)
    end
end

function Gameface.notify!(g::ConcreteGameService, notif::GameNotification)
    formatter = SlackFormatter()
    text = format(formatter, notif)

    notifytext!(g, text)
end

# SolutionboardNotifications only carry instructions that allow ConcreteGameService to
# find all the actual information that should be included in the notification.
# So instead of showing the notification itself, we fetch a solution board and show that.
function Gameface.notify!(g::ConcreteGameService, notif::SolutionboardNotification)
    board = getsolutionboard(g.persistence, notif.instanceid, notif.round)

    # TODO A real implementation should get the formatter for each team
    #      and format the notification accordingly.
    #      This skeleton implementation just uses a SlackFormatter.

    formatter = SlackFormatter()
    text = format(formatter, board)

    notifytext!(g, text)
end

function Gameface.notify!(g::ConcreteGameService, notif::ScoreboardNotification)
    board = getscoreboard(g.persistence, notif.instanceid, notif.round)

    # TODO A real implementation should get the formatter for each team
    #      and format the notification accordingly.
    #      This skeleton implementation just uses a SlackFormatter.

    formatter = SlackFormatter()
    text = format(formatter, board)

    notifytext!(g, text)
end

function Gameface.finddictionary(g::ConcreteGameService, dictionaryid::AbstractString) :: LanguageDictionary
    SwedishDictionary([
        "DATORSPEL",
        "LEDARPOST",
        "PUSSGURKA",
        "ORDPUSSEL"
    ])
end

function Gameface.event!(g::ConcreteGameService, event::GameUserEvent)
    recordevent!(g.persistence, g.gameinstanceid, event)
end
function Gameface.event!(g::ConcreteGameService, event::GameEvent)
    recordevent!(g.persistence, g.gameinstanceid, event)
end

export ConcreteGameService

end


text:
include("wrapper/exprs.jl")
include("wrapper/type_conversions.jl")
include("wrapper/naming_conventions.jl")
include("wrapper/conventions.jl")
include("wrapper/config.jl")
include("wrapper/wrap.jl")

include("wrapper/dependency_resolution.jl")
include("wrapper/write.jl")

export
    # Naming Conventions
    ### Convention types
    CamelCaseLower,
    CamelCaseUpper,
    SnakeCaseLower,
    SnakeCaseUpper,

    ### Convention utilities
    detect_convention,
    nc_convert,
    remove_parts,
    remove_prefix,
    struct_name,

    # Expr
    name,
    category,
    deconstruct,
    reconstruct,
    rmlines,
    striplines,
    unblock,
    prettify,
    concat_exs,
    broadcast_ex,
    is_broadcast,
    to_expr,

    # Wrapping
    WrapperConfig,
    Platform,
    Linux,
    Windows,
    MacOS,
    BSD,
    extensions,
    filter_specs,
    VulkanWrapper,
    wrap,
    resolve_types,
    resolve_dependencies,

    ### Utility
    is_flag,
    is_returnedonly,
    contains_api_structs,
    promote_hl,

    ### Wrapper types
    WrapperNode,
    Definition,
    ConstantDefinition,
    EnumDefinition,
    BitmaskDefinition,
    StructDefinition,
    HandleDefinition,
    Constructor,
    Documented,
    MethodDefinition,
    AliasDeclaration,
    FromVk,
    Convert,
    GetProperty,
    APIFunction,
    Parent,
    exports

max_stars_repo_name: JuliaGPU/VulkanAbstraction

max_issues_repo_name: JuliaGPU/VulkanAbstraction

max_forks_repo_name: JuliaGPU/VulkanAbstraction


text:
# Replicate Kaplan Violante 2010
# Allen Peters
# November 7, 2019
using Plots, LinearAlgebra, Statistics, Random, Roots, Interpolations
using QuantEcon

###############################################################################
# Omit if using my development version of QuantEcon
# command 'free QuantEcon' to revert to proper version of QuantEcon

import QuantEcon._rouwenhorst

@doc doc"""
Extended Rouwenhorst's method to approximate non-stationary AR(1) processes,
following Fella, Gallipoli, Pan (2019).

The process follows

```math
    y_t = \rho_t y_{t-1} + \epsilon_t
```

where ``\epsilon_t \sim N (0, \sigma_t^2)``

##### Arguments
- `N::Integer` : Number of points in markov process
- `T::Integer` : Length of simulation
- `ρ::Array or Real` : Persistence parameter(s) in AR(1) process, can be >=1
- `σ::Array or Real` : Standard deviation(s) of random component of AR(1) process
- `σ_y0::Real` : Standard deviation of initial y value y_0

##### Returns

- `mc::Vector{MarkovChain}` : Vector of Markov chains (length T) holding
                                the state values and transition matrix

"""
function rouwenhorst_ns(N::Integer, T::Integer, ρ::Array, σ::Array, σ_y0::Real)
    #for input to _rouwenhorst(), because μ is not implemented
    m = 0.0

    # a cheap way to initialize a vector of MarkovChains
    MarkovChains = fill(rouwenhorst(N, 0.9, σ[1]), T)

    for t in 1:T
        σ_yt = sqrt(ρ[t]^2 * σ_y0^2 + σ[t]^2)
        p  = (1+ρ[t]*σ_y0/σ_yt)/2
        Θ = [p 1-p; 1-p p]
        ψ = sqrt(N-1) * σ_yt
        state_values, p = _rouwenhorst(p, p, m, ψ, N)
        MarkovChains[t] = MarkovChain(p, state_values)
        σ_y0 = σ_yt
    end
    return MarkovChains
end

function rouwenhorst_ns(N::Integer, T::Integer, ρ::Real, σ::Real, σ_y0::Real)
    rouwenhorst_ns(N, T, ρ.*ones(T), σ.*ones(T), σ_y0)
end

@doc doc"""
Simulate one sample path of the non-stationary vector of Markov chains `mcs`.
The resulting vector has the state values of `mcs` as elements.

### Arguments

- `mcs::Vector{MarkovChain}` : Vector of MarkovChains.
- `;init::Int` : Index of initial state

### Returns

- `X::Vector` : Vector containing the sample path, with length
  length(mcs)+1 (includes initial state)
"""
function simulate_ns(mcs::Vector, init::Int)
    ind_0 = init
    ind = zeros(Int, length(mcs))
    X = zeros(Real, length(mcs))

    for t in eachindex(mcs)
        X[t] = simulate(mcs[t], 2, init = ind_0)[2]
        ind[t] = findmin( abs.(mcs[t].state_values .- X[t]) )[2]
        if t < length(mcs)
            ind_0 = ind[t]
        end
    end
    ind = [init; ind]
    X = [mcs[1].state_values[init]; X]
end
###############################################################################

# Parameters
## Demographics
N = 50000
T_ret = 35
T = 70
t = 1:T   # period T is last period of life, T_ret is last period of work
age = t .+ 24

## Uncondtional probability of surviving to age t
# Data from NCHS 1992 (Chung 1994)
age_data = [60:5:85; 95.]
S_data = [85.89; 80.08; 72.29; 61.52; 48.13; 32.33; 0]./100
S_interp = LinearInterpolation(age_data, S_data)
ξ_ret = map(S_interp,collect(60:95))
ξ_raw = [ones(Float64,T_ret); ξ_ret]
plot(age, ξ_raw[1:end-1], label = "Data",
 title="Unconditional Survival Probability", xlabel="Age", ylabel="Data",
 linestyle=:dash, grid=false)
ξ = [ones(Float64,T_ret); ξ_ret .+ (1-ξ_ret[1])]
plot!(age, ξ[1:end-1], title="Unconditional Survival Probability",
 label="Adjusted")
savefig("survival_prob.png")

## Preferences
γ = 2.

## Discount factor and interest rate
r = 0.03
β = 0.971
WI_ratio = 2.5  # aggregate wealth-income ratio

## Income process
# KV 2010: "The estimated profile peaks after 21 years of labor market experience
# at roughly twice the initial value, and then it slowly declines to about 80
# percent of the peak value."

# From master's thesis (estimated from Hansen?)
# Ey = 161/0.768.*[0.5676772162;0.6084932081;0.6493091999;0.6901819595;0.7290110811;
#  0.7678969704;0.8067828597;0.845668749;0.8845546383;0.9234405276;0.9623264169;
#  0.9773698632;0.9899155296;1.0075135233;1.0226137373;1.0376571835;1.0527573975;
#  1.0678008437;1.0828442899;1.0979445039;1.1129879501;1.1139530014;1.1149180526;
#  1.1159398716;1.1169049229;1.1178699742;1.1188350254;1.1198000767;1.120765128;
#  1.1217301792;1.1226952305;1.1183241159;1.1139530014;1.1095818868;1.1052107722;
#  1.1008396577;1.0964685431;1.0920974285;1.087726314;1.0833551994;1.0789840849;
#  1.0419147626;1.0048454404;0.9677761182;0.9307635637]
# # plot!([20:64],Ey./maximum(Ey).*161/0.768)
# y_interp = LinearInterpolation(20:64, Ey, extrapolation_bc = Line())

# From Huggett et al. 2006, PSID data up to 1992
age_y = [20; 25; 30; 35; 40; 45; 50; 55; 57.5]
y_data = [55.12; 76.59; 91.38; 101.63; 106.67; 107.64; 106.67; 103.58; 100]
 # trim down last couple points and compress ages to match KV's description
y_data[8] *= 0.95
y_data[9] *= 0.85
age_y = range(25, stop=57.5, length=length(age_y))
y_data .*= 15/55.12 # scale to match plot in KV2010, work in 1000's
# Assume KV's description is about levels. Then my data peaks slightly later and
# doesn't decline as much as KV describes.
y_interp = LinearInterpolation(age_y, y_data, extrapolation_bc = Line())
κ = log.(map(y_interp,collect(25:59)))

# Net labour income
function Y(N, T_ret, σ_ε, σ_η, σ_z0, κ)
# Takes standard deviations as arguments (not varicances)!
    Y = zeros(Float64, N, T_ret)
    z = similar(Y)
    ε = similar(Y)
    z[:,1] = σ_z0 .* randn(N) + σ_η .* randn(N)

    for t in 1:(T_ret)
        ε[:,t] = σ_ε .* randn(N)
        Y[:,t] = exp.( κ[t] .+ z[:,t] + ε[:,t] )
        t < (T_ret) ? z[:,t+1] = z[:,t] + σ_η .* randn(N) : nothing
    end
    return (Y, z, ε)
end

# Gross earnings Y_tilde
τ_b = 0.258
τ_ρ = 0.768
τ(Y_tilde,τ_s) = τ_b*(Y_tilde-(Y_tilde^(-τ_ρ) + τ_s)^(-1/τ_ρ))
Y_tilde_fn(Y, τ_s) = find_zero(Y_tilde -> Y_tilde - τ(Y_tilde,τ_s) - Y, Y)

# Iterate to calibrate τ_s (Returns gross labour income)
function G(Y_l; τ_s_0 = 0.25, Kp = .4, Kd = .07, tol = 1E-2, max_iter = 1000,
 nonconvergence_message = true, verbose = false)
    verbose ? println("Solving for gross labour income") : nothing
    #iterate to
    Y_tilde = similar(Y_l)
    τ_s = τ_s_0
    err = tol + 0.1
    iter = 1
    while abs(err) > tol && iter <= max_iter
        Y_tilde = Y_tilde_fn.(Y_l,τ_s)
        err_old = err
        err = sum(τ.(Y_tilde,τ_s))/sum(Y_l) - 0.25
        verbose ? println("error=", err, " τs=", τ_s) : nothing
        τ_s_old = τ_s
        τ_s += -Kp*err + Kd*(err-err_old)
        iter += 1
    end
    iter <= max_iter ?
        (Y_tilde = Y_tilde, τ_s = τ_s, iters = iter - 1, err = err) :
        ( !nonconvergence_message ? (Y_tilde = Y_tilde, iters = iter - 1) :
        println("Did not converge after $(iter-1) iterations") )
end

# Social security benefits (After tax retirement income)
function P(Y_tilde_l)
    Y_tilde_l_iave = mean(Y_tilde_l, dims = 2)
    # Denoted \tilde{Y}_i^SS in the paper just to be confusing.
    # This is each individual's average lifetime earnings
    y_tilde_l_ave = mean(Y_tilde_l_iave) # Average lifetime earnings across individuals
    SS_schedule(y) = y < 0.18*y_tilde_l_ave ? 0.9*y : (y > 1.1*y_tilde_l_ave ?
     0.9*0.18*y_tilde_l_ave + 0.32*(1.1-0.18)*y_tilde_l_ave +
     0.15*(y-1.1*y_tilde_l_ave) : 0.9*0.18*y_tilde_l_ave + 0.32*
     (y-0.18*y_tilde_l_ave) )
    Y_tilde_SS = 0.45*y_tilde_l_ave/SS_schedule(y_tilde_l_ave).*
     replace(SS_schedule, Y_tilde_l_iave)
    Y_SS = Y_tilde_SS - τ.(0.85.*Y_tilde_SS, τ_s)
end

# Directly from KV2010
σ_η = sqrt(0.01)
σ_z0 = sqrt(0.15)
σ_ε = sqrt(0.05)

# Discretize permanent component of income
# 39 equally spaced points on an age-varying grid chosen to match the
# age-specific unconditional variances
z_gridpoints = 39
mcs_z = rouwenhorst_ns(z_gridpoints, T_ret, 1., σ_η, σ_z0)
# Discretize transitory component of income
# transitory component is approximated with 19 equally spaced points
ε_gridpoints = 19
mc_ε = rouwenhorst(ε_gridpoints, 0., σ_ε)

function invert_rule(A, A_vals; extrapolation_bc = Throw())
    #linear interpolation of a column of Y on that column of X, evaluated at point x
    A_vals_interp = similar(A)
    for col in eachindex(A[1,:])
        li = LinearInterpolation(A[:,col], A_vals, extrapolation_bc=extrapolation_bc)
        A_vals_interp[:,col] = li(A_vals)
    end
    return A_vals_interp
end

function invert_rule_3d(A3d, A_vals; extrapolation_bc = Throw())
    wrapper(A) = invert_rule(A,A_vals,extrapolation_bc = extrapolation_bc)
    A3d_inv = mapslices(wrapper, A3d, dims=1)
end

# Policy function via endogenous grid method, as per footnote 23
# 100 exponentially spaced grid points for assets.
## Borrowing limit defined by a_min. Default is ZBC
# how to calc NBC? A_min = ...
a_gridpoints = 100
a_min = 0.
a_max = 220.

# The grid for lifetime average earnings has 19 points.
# I will build a grid on P(y_tilde) rather than y_tilde because
# don't have to worry about matching mean for accuracy
PY_tilde_gridpoints = 19
# Based on simulating the income process:
# histogram(Y_SS, bins = 100)
# minimum(Y_SS)
# maximum(Y_SS)
PY_tilde_vals = range(0., stop = 45., length = PY_tilde_gridpoints)
# scatter!(PY_tilde_vals,zeros(length(PY_tilde_vals)))
# histogram!(Y_SS, normalize=:true, bins = PY_tilde_vals, alpha = 0.5)

function policyfn(mcs_z, mc_ε, r, β, γ, PY_tilde_vals, z_gridpoints, ε_gridpoints, a_gridpoints, a_max, a_min = 0.)
    println("Policy function calculation...")
    A_vals = exp10.( range(log10(a_min+1), stop = log10(a_max+1), length =
     a_gridpoints) ) .- 1

    # We have 3 state variables: age (t), wealth (a),
    # and either permanent component of income (z)
    # or average lifetime earnings y_tilde
    # Matrices of form a x z/y_tilde
    A = vcat(fill(zeros(Float64, a_gridpoints, z_gridpoints, ε_gridpoints), T_ret+1),
     fill(zeros(Float64, a_gridpoints, PY_tilde_gridpoints), (T+2)-(T_ret+1)) )

    # Last period and period after last (for A[t+2] when t = T-1)
    A[T+2] = zeros(Float64, a_gridpoints, PY_tilde_gridpoints)
    A[T+1] = zeros(Float64, a_gridpoints, PY_tilde_gridpoints)
    # no need to shift grid because all zeros

    println("Retirement")
    A_grid_ret = repeat(A_vals, 1, PY_tilde_gridpoints)
    PY_tilde_grid = repeat(PY_tilde_vals', a_gridpoints, 1)

    for t in reverse(T_ret+1:T-1)
        println(t)
        C_t1 = (1+r).*A_grid_ret + PY_tilde_grid - A[t+2]
        C_t = ( β*ξ[t+1]/ξ[t]*(1+r) )^(-1/γ) .* C_t1
        A_t = 1/(1+r) .* (C_t - PY_tilde_grid + A_grid_ret)
        A[t+1] = invert_rule( A_t, A_vals, extrapolation_bc = a_min )
        # extrapolation_bc affects borrowing constraint
    end

    println("Year before retirement")
    for t = T_ret
        C_t1 = (1+r).*A_grid_ret + PY_tilde_grid - A[t+2]
        C_t = ( β*ξ[t+1]/ξ[t]*(1+r) )^(-1/γ) .* C_t1
        # interpolate for shifting onto 3d grid
        C_li = LinearInterpolation((A_vals, PY_tilde_vals), C_t,
         extrapolation_bc = (Flat(), Line()) )
        # Be careful with this extrapolation
        A_t = zeros(Float64, a_gridpoints, z_gridpoints, ε_gridpoints)
        for (ε_ind, ε) in enumerate(mc_ε.state_values), (z_ind,
         z) in enumerate(mcs_z[t].state_values), (a_t1_ind, a_t1) in enumerate(A_vals)

            A_t[a_t1_ind, z_ind, ε_ind] = 1/(1+r) * ( C_li(a_t1,
             exp(κ[t] + z + ε)) - exp(κ[t] + z + ε) + a_t1 )
        end
        A[t+1] = invert_rule_3d(A_t, A_vals, extrapolation_bc = a_min)
        # extrapolation_bc affects borrowing constraint
    end

    println("Working years")
    for t in reverse(1:T_ret-1)
        println(t)
        A_t2 = LinearInterpolation((A_vals, mcs_z[t+1].state_values,
         mc_ε.state_values), A[t+2])
        # interpolate for shifting A[t+2] to z[t] grid vals
        A_t = zeros(a_gridpoints,z_gridpoints,ε_gridpoints)
        # i = 0
        for (ε_ind, ε) in enumerate(mc_ε.state_values), (z_ind,
         z) in enumerate(mcs_z[t].state_values), (a_t1_ind, a_t1) in enumerate(A_vals)
            # @show i += 1
            Ec = 0.
            for (ε_t1_ind, ε_t1) in enumerate(mc_ε.state_values), (z_t1_ind,
             z_t1) in enumerate(mcs_z[t].state_values)

                Ec += mcs_z[t].p[z_ind, z_t1_ind] * mc_ε.p[1,ε_t1_ind] *
                 ( (1+r).*a_t1 + exp(κ[t+1] + z_t1 + ε_t1) - A_t2(a_t1, z_t1,
                 ε_t1) )^(-γ)
            end
            A_t[a_t1_ind, z_ind, ε_ind] = 1/(1+r) * ( ( β*(1+r)*Ec )^(-1/γ) -
             exp(κ[t] + z + ε) + a_t1 )
        end
        A[t+1] = invert_rule_3d(A_t, A_vals, extrapolation_bc = a_min)
        # extrapolation_bc affects borrowing constraint
    end

    return A
end

function simulate_economy(A, z_l, ε_l, κ, mcs_z, mc_ε, PY_tilde_vals, a_max, a_min, a_gridpoints, r)
    A_vals = exp10.( range(log10(a_min+1), stop = log10(a_max+1),
     length = a_gridpoints) ) .- 1
    Ai = zeros(Float64, N, T+2)
    Ci = similar(Ai)
    # Optional: Do empirical one too
    # "Precisely, we target the empirical distribution of financial wealth-earnings
    # ratios in the population of households aged 20-30 in the SCF. We assume
    # that the initial draw of earnings is independent of the initial draw of this
    # ratio, since in the data the empirical correlation is 0.02."

    ## Initial wealth is zero => Ai[:,1]=0.
    for t in 1:T_ret
        li = LinearInterpolation((A_vals, mcs_z[t].state_values,
         mc_ε.state_values), A[t+1], extrapolation_bc = Flat())
         #extrapolate with boundary rules
        Ai[:,t+1] = li.(Ai[:,t], z_l[:,t], ε_l[:,t])
        Ci[:,t] = (1+r) .* Ai[:,t] + exp.(κ[t] .+ z_l[:,t] + ε_l[:,t]) - Ai[:,t+1]
    end
    for t in T_ret+1:T
        li = LinearInterpolation((A_vals, PY_tilde_vals),
         A[t+1], extrapolation_bc = Flat()) #extrapolate with boundary rules
        Ai[:,t+1] = li.(Ai[:,t], Y_SS)
        Ci[:,t] = (1+r) .* Ai[:,t] + Y_SS - Ai[:,t+1]
    end
    return (Ai, Ci)
end

# Main program
A = policyfn(mcs_z, mc_ε, r, β, γ, PY_tilde_vals, z_gridpoints, ε_gridpoints, a_gridpoints, a_max, a_min)
# A[69]
# plot()
# heatmap(A[67])
# A[1][:,:,1]
# heatmap(A[35][:,:,10])
using JLD2, FileIO
vec_A = vec(A)
size_A = size(A)
@save "A.jld2" vec_A size_A
# @load "A.jld2" vec_A size_A
# A1 = reshape(vec_A, size_A[1])
# @test dropdims(sol.V, dims = 3) == V

Random.seed!(1234)
(Y_l, z_l, ε_l) = Y(N, T_ret, σ_ε, σ_η, σ_z0, κ)
# histogram(vec(Y_l), bins = 100)
(Y_tilde_l, τ_s) = G(Y_l, τ_s_0 = 0.105, verbose = true)
# Had 0.04057 before
#Should use 0.031, which is initial guess from Gouveia Strauss 1994
Y_SS = P(Y_tilde_l)
Y_tot = hcat(Y_l, repeat(Y_SS, 1, T-T_ret) )
# i = 100
# plot(age,Y_tot[i,:], ylims=(0,2000))
(Ai, Ci) = simulate_economy(A, z_l, ε_l, κ, mcs_z, mc_ε, PY_tilde_vals, a_max, a_min, a_gridpoints, r)

### Plotting
# Life-cycle means
Ci_ave = mean(Ci, dims = 1)'
plot(age, Ci_ave[1:T], label = "Consumption", linestyle=:dash,
 xlabel="Age", ylabel="\$ (,000)", title="Life-cycle Means (ZBC)",
 grid=false, ylims=(-20,200), xlims=(25,95), xticks=25:5:95)

Yi_ave = mean(Y_tot, dims = 1)'
plot!(age, Yi_ave, linestyle=:dash, label = "Income")

Ai_ave = mean(Ai, dims = 1)'
plot!(age, Ai_ave[1:T], label = "Wealth", linestyle=:dash)
savefig("zbc_lifecycle_means.png")

plot(age[1:T_ret], exp.(κ), legend=:false, title="Average Income Profile",
 xlabel="Age", ylabel="\$ (,000)", ylims=(0,30), grid=false)
savefig("kappa.png")

#
# # "Initial should be"
# 54/168*0.5
# Yi_ave[1]
# # "Max should be"
# 127/168*0.5
# maximum(Yi_ave)
# # Pension should be
# 64/235*0.5
# Yi_ave[36]
# # All are quite close!!

# Life-cycle Inequality
Ci_varlog = var(log.(Ci), dims = 1)'
plot(age, Ci_varlog[1:T], label = "Consumption", linestyle=:dash,
 title="Life-cycle Inequality (ZBC)",
 ylims=(0.05,0.6), xlims=(25,95), yticks=0.05:0.05:0.55, grid=false)

Yi_varlog = var(log.(Y_tot), dims = 1)'
plot!(age, Yi_varlog[1:T], label = "Income", linestyle=:dash)

savefig("zbc_lifecycle_inequality.png")

max_stars_repo_path: src/KV 2010.jl

max_issues_repo_path: src/KV 2010.jl

max_forks_repo_path: src/KV 2010.jl


text:
function dayNumber(inDate::Date)
    return Dates.date2epochdays(inDate)::Integer
end

excelcostant = 693959;

"""
From Excel Number Format to Date

		Date=fromExcelNumberToDate(ExcelNumber)

Where:\n
		ExcelNumber = Integer representing a date in the excel format.

		Date      = Date representing the input in the Julia object format.

# Example
```julia-repl
julia> fromExcelNumberToDate(45000)
2023-03-15
```
"""
function fromExcelNumberToDate(num::Integer)::Date
    return Dates.Dates.epochdays2date(excelcostant + num)
end

"""
Actual Number of days between two dates

		ndays=daysact(Date1,Date2)

Where:\n
		Date1 = Start date.
		Date2 = End date.

		ndays      = Actual Number of days between Start Date and End Date.

# Example
```julia-repl
julia> daysact(Date(1996,10,12),Date(1998,1,10))
455
```
"""
function daysact(Date1::Date, Date2::Date)::Integer
    D1 = dayNumber(Date1)
    D2 = dayNumber(Date2)
    dayCount = D2 - D1
    return dayCount
end

function isLastOfFebruary(inDate::Date)::Bool
    return (Dates.isleapyear(Dates.year(inDate)) && (Dates.day(inDate) == 29) && (Dates.month(inDate) == 2)) || ((!Dates.isleapyear(Dates.year(inDate))) && (Dates.day(inDate) == 28) && (Dates.month(inDate) == 2))
end

currMaxImplemented = 7;

"""
Fraction of year between two Dates according the following convention

		yfr=yearfrac(Date1,Date2,basis)

Where:\n
		Date1 = Start date.
		Date2 = End date.
		basis = Integer representing the following conventions:
				- 0 = (ACT/ACT)
				- 1 = (30/360 SIA)
				- 2 = (ACT/360)
				- 3 = (ACT/365)
				- 4 = (30/360 PSA)
				- 5 = (30/360 ISDA)
				- 6 = (30E/360)
				- 7 = (ACT/365 JPN)

		yfr      = fraction of year between start and end date according to basis.

# Example
```julia-repl
julia> yearfrac(Date(1996,10,12),Date(1998,1,10),1)
1.2444444444444445
```
"""
function yearfrac(startDate::Date, endDate::Date, convention::Integer)::Real
    if (convention < 0)
        error("Negative basis are not defined, check the help")
    end
    if (convention > currMaxImplemented)
        error("Convention not implemented yet")
    end
    if (startDate > endDate)
        return -yearfrac(endDate, startDate, convention)
    elseif (startDate == endDate)
        return 0.0
    end
    yearFrac = 0.0
    y1 = Dates.year(startDate)
    m1 = Dates.month(startDate)
    y2 = Dates.year(endDate)
    m2 = Dates.month(endDate)
    d1 = Dates.day(startDate)
    d2 = Dates.day(endDate)
    if (convention == 0)#(ACT/ACT)
        Nday = daysact(startDate, endDate)
        EndOFYear = Date(1)
        if (isLastOfFebruary(startDate) && (Dates.day(startDate) == 29))
            EndOFYear = Date(Dates.year(startDate) + 1, 3, 1)
        else
            EndOFYear = Date(Dates.year(startDate) + 1, Dates.month(startDate), Dates.day(startDate))
        end
        yearFrac = (Nday) / daysact(startDate, EndOFYear)
    elseif (convention == 1)  #(30/360 SIA)
        if (isLastOfFebruary(startDate) && isLastOfFebruary(endDate))
            d2 = 30
        end
        if (isLastOfFebruary(startDate) || Dates.day(startDate) == 31)
            d1 = 30
        end
        if (d1 == 30 && d2 == 31)
            d2 = 30
        end
        dy = y2 - y1
        dm = m2 - m1
        dd = d2 - d1
        yearFrac = (360.0 * dy + 30.0 * dm + dd) / 360.0
    elseif (convention == 2)#(ACT/360)
        Nday = daysact(startDate, endDate)
        yearFrac = (Nday) / 360.0
    elseif (convention == 3)# (ACT/365)
        Nday = daysact(startDate, endDate)
        yearFrac = (Nday) / 365.0
    elseif (convention == 4)# (30/360 PSA)
        if ((Dates.day(startDate) == 31) || isLastOfFebruary(startDate))
            d1 = 30
        end
        if ((Dates.day(startDate) == 30 || isLastOfFebruary(startDate)) && Dates.day(endDate) == 31)
            d2 = 30
        end
        dy = y2 - y1
        dm = m2 - m1
        dd = d2 - d1
        yearFrac = (360.0 * dy + 30.0 * dm + dd) / 360.0

    elseif (convention == 5)#(30/360 ISDA)
        y1 = Dates.year(startDate)
        m1 = Dates.month(startDate)
        y2 = Dates.year(endDate)
        m2 = Dates.month(endDate)
        if (Dates.day(startDate) < 31)
            d1 = Dates.day(startDate)
        else
            d1 = 30
        end
        if ((Dates.day(endDate) == 31) && (d1 > 29))
            d2 = 30
        else
            d2 = Dates.day(endDate)
        end
        yearFrac = (360.0 * ((y2 - y1)) + 30.0 * ((m2 - m1)) + (d2 - d1)) / 360.0

    elseif (convention == 6)#(30E/360)
        if (d1 == 31)
            d1 = 30
        end
        if (d2 == 31)
            d2 = 30
        end
        dy = y2 - y1
        dm = m2 - m1
        dd = d2 - d1
        yearFrac = (360.0 * dy + 30.0 * dm + dd) / 360.0
    elseif (convention == 7)#(ACT/365 JPN)
        daydistance = [0; 31; 59; 90; 120; 151; 181; 212; 243; 273; 304; 334]
        dy = y2 - y1
        dd = d2 - d1
        dayCount = (365.0 * dy + daydistance[m2] - daydistance[m1] + dd)
        yearFrac = dayCount / 365.0
    end

    return yearFrac
end


text:
# Configuration
# =============

struct Config
    # worker IDs
    workers::Vector{Int}

    # remotecall multiplicity per worker
    multiplicity::Int

    # maximum chunk size for parallel map
    chunksize::Int

    # minimum snapshot interval
    snapshot_interval::UInt64

    # show runtime statistics at last
    show_stats::Bool

    # show runtime trace at last
    show_trace::Bool

    # output of debug info (stats, trace, etc.)
    output::IO
end

function Config(workers;
                multiplicity::Integer=2,
                chunksize::Integer=64,
                snapshot_interval::Integer=10^9,
                show_stats::Bool=false,
                show_trace::Bool=false,
                output::IO=STDERR)
    return Config(
        workers, multiplicity, chunksize,
        snapshot_interval, show_stats, show_trace,
        output)
end

function chunksize(config::Config)
    return config.chunksize
end

function nworkers(config::Config)
    return length(config.workers)
end

function snapshot_interval(config::Config)
    return config.snapshot_interval
end


text:
function parallel_transport_along! end

@doc raw"""
    Y = parallel_transport_along(M::AbstractManifold, p, X, c)

Compute the parallel transport of the vector `X` from the tangent space at `p`
along the curve `c`.

To be precise let ``c(t)`` be a curve ``c(0)=p`` for [`vector_transport_along`](@ref) ``\mathcal P^cY``

THen In the result ``Y\in T_p\mathcal M`` is the vector ``X`` from the tangent space at ``p=c(0)``
to the tangent space at ``c(1)``.

Let ``Z\colon [0,1] \to T\mathcal M``, ``Z(t)\in T_{c(t)}\mathcal M`` be a smooth vector field
along the curve ``c`` with ``Z(0) = Y``, such that ``Z`` is _parallel_, i.e.
its covariant derivative ``\frac{\mathrm{D}}{\mathrm{d}t}Z`` is zero. Note that such a ``Z`` always exists and is unique.

Then the parallel transport is given by ``Z(1)``.
"""
function parallel_transport_along(M::AbstractManifold, p, X, c::AbstractVector)
    Y = allocate_result(M, vector_transport_along, X, p)
    return parallel_transport_along!(M, Y, p, X, c)
end

function parallel_transport_direction!(M::AbstractManifold, Y, p, X, d)
    return parallel_transport_to!(M, Y, p, X, exp(M, p, d))
end

@doc raw"""
    parallel_transport_direction(M::AbstractManifold, p, X, d)

Compute the [`parallel_transport_along`](@ref) the curve ``c(t) = γ_{p,q}(t)``,
i.e. the * the unique geodesic ``c(t)=γ_{p,X}(t)`` from ``γ_{p,d}(0)=p`` into direction ``\dot γ_{p,d}(0)=d``, of the tangent vector `X`.

By default this function calls [`parallel_transport_to`](@ref)`(M, p, X, q)`, where ``q=\exp_pX``.
"""
function parallel_transport_direction(M::AbstractManifold, p, X, d)
    return parallel_transport_to(M, p, X, exp(M, p, d))
end

function parallel_transport_to! end

@doc raw"""
    parallel_transport_to(M::AbstractManifold, p, X, q)

Compute the [`parallel_transport_along`](@ref) the curve ``c(t) = γ_{p,q}(t)``,
i.e. the (assumed to be unique) [`geodesic`](@ref) connecting `p` and `q`, of the tangent vector `X`.
"""
function parallel_transport_to(M::AbstractManifold, p, X, q)
    Y = allocate_result(M, vector_transport_to, X, p, q)
    return parallel_transport_to!(M, Y, p, X, q)
end