text:
using Rubin
using Tests
using Elliptic
using HypergeometricFunctions
using Polylogarithms
using SpecialFunctions

@test integrate((d+e*x)*(a+b*x^2+c*x^4), x) == :(a*d*x+(1/2)*a*e*x^2+1//3*b*d*x^3+1//4*b*e*x^4+1//5*c*d*x^5+1//6*c*e*x^6)
@test integrate((a+b*x^2+c*x^4)*(d+e*x+f*x^2), x) == :(x^3*(1//3*a*f+1//3*b*d)+x^5*(1//5*b*f+1//5*c*d)+a*d*x+(1/2)*a*e*x^2+1//4*b*e*x^4+1//6*c*e*x^6+1//7*c*f*x^7)
@test integrate((a+b*x^2+c*x^4)*(d+e*x+f*x^2+g*x^3), x) == :(x^3*(1//3*a*f+1//3*b*d)+x^4*(1//4*a*g+1//4*b*e)+x^5*(1//5*b*f+1//5*c*d)+x^6*(1//6*b*g+1//6*c*e)+a*d*x+(1/2)*a*e*x^2+1//7*c*f*x^7+1//8*c*g*x^8)
@test integrate((a+b*x^2+c*x^4)*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :(x^3*(1//3*a*f+1//3*b*d)+x^4*(1//4*a*g+1//4*b*e)+x^5*(1//5*a*h+1//5*b*f+1//5*c*d)+x^6*(1//6*b*g+1//6*c*e)+x^7*(1//7*b*h+1//7*c*f)+a*d*x+(1/2)*a*e*x^2+1//8*c*g*x^8+1//9*c*h*x^9)
@test integrate((a+b*x^2+c*x^4)*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :(x^3*(1//3*a*f+1//3*b*d)+x^4*(1//4*a*g+1//4*b*e)+x^5*(1//5*a*h+1//5*b*f+1//5*c*d)+x^6*(1//6*a*i+1//6*b*g+1//6*c*e)+x^7*(1//7*b*h+1//7*c*f)+x^8*(1//8*b*i+1//8*c*g)+a*d*x+(1/2)*a*e*x^2+1//9*c*h*x^9+1//10*c*i*x^10)
@test integrate((a+b*x^2+c*x^4)^2*(d+e*x), x) == :(d*x*a^2+d*x^5*(1//5*b^2+2//5*a*c)+e*x^6*(1//6*b^2+1//3*a*c)+(1/2)*e*a^2*x^2+1//9*d*c^2*x^9+1//10*e*c^2*x^10+(1/2)*a*b*e*x^4+1//4*b*c*e*x^8+2//3*a*b*d*x^3+2//7*b*c*d*x^7)
@test integrate((a+b*x^2+c*x^4)^2*(d+e*x+f*x^2), x) == :(x^5*(1//5*d*b^2+2//5*a*b*f+2//5*a*c*d)+x^7*(1//7*f*b^2+2//7*a*c*f+2//7*b*c*d)+d*x*a^2+e*x^6*(1//6*b^2+1//3*a*c)+(1/2)*e*a^2*x^2+1//3*a*x^3*(a*f+2*b*d)+1//9*c*x^9*(c*d+2*b*f)+1//10*e*c^2*x^10+1//11*f*c^2*x^11+(1/2)*a*b*e*x^4+1//4*b*c*e*x^8)
@test integrate((a+b*x^2+c*x^4)^2*(d+e*x+f*x^2+g*x^3), x) == :(x^5*(1//5*d*b^2+2//5*a*b*f+2//5*a*c*d)+x^6*(1//6*e*b^2+1//3*a*b*g+1//3*a*c*e)+x^7*(1//7*f*b^2+2//7*a*c*f+2//7*b*c*d)+x^8*(1//8*g*b^2+1//4*a*c*g+1//4*b*c*e)+d*x*a^2+(1/2)*e*a^2*x^2+1//3*a*x^3*(a*f+2*b*d)+1//4*a*x^4*(a*g+2*b*e)+1//9*c*x^9*(c*d+2*b*f)+1//10*c*x^10*(c*e+2*b*g)+1//11*f*c^2*x^11+1//12*g*c^2*x^12)
@test integrate((a+b*x^2+c*x^4)^2*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :(x^5*(1//5*a*(a*h+2*c*d)+1//5*d*b^2+2//5*a*b*f)+x^6*(1//6*e*b^2+1//3*a*b*g+1//3*a*c*e)+x^7*(1//7*f*b^2+2//7*b*(a*h+c*d)+2//7*a*c*f)+x^8*(1//8*g*b^2+1//4*a*c*g+1//4*b*c*e)+x^9*(1//9*d*c^2+1//9*h*b^2+2//9*c*(a*h+b*f))+d*x*a^2+(1/2)*e*a^2*x^2+1//3*a*x^3*(a*f+2*b*d)+1//4*a*x^4*(a*g+2*b*e)+1//10*c*x^10*(c*e+2*b*g)+1//11*c*x^11*(c*f+2*b*h)+1//12*g*c^2*x^12+1//13*h*c^2*x^13)
@test integrate((4+x^4+-5*x^2)^-1*(d+e*x), x) == :(-1//6*d*arctanh((1/2)*x)+-1//6*e*log(1+-1*x^2)+1//3*d*arctanh(x)+1//6*e*log(4+-1*x^2))
@test integrate((4+x^4+-5*x^2)^-1*(d+e*x+f*x^2), x) == :((-2//3*f+-1//6*d)*arctanh((1/2)*x)+(1//3*d+1//3*f)*arctanh(x)+-1//6*e*log(1+-1*x^2)+1//6*e*log(4+-1*x^2))
@test integrate((4+x^4+-5*x^2)^-1*(d+e*x+f*x^2+g*x^3), x) == :((-2//3*f+-1//6*d)*arctanh((1/2)*x)+(1//3*d+1//3*f)*arctanh(x)+(1//6*e+2//3*g)*log(4+-1*x^2)+-1*(1//6*e+1//6*g)*log(1+-1*x^2))
@test integrate((4+x^4+-5*x^2)^-1*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :(h*x+(1//6*e+2//3*g)*log(4+-1*x^2)+(1//3*d+1//3*f+1//3*h)*arctanh(x)+-1*(1//6*e+1//6*g)*log(1+-1*x^2)+-1*(1//6*d+2//3*f+8//3*h)*arctanh((1/2)*x))
@test integrate((4+x^4+-5*x^2)^-1*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :(h*x+(1//3*d+1//3*f+1//3*h)*arctanh(x)+(1//6*e+2//3*g+8//3*i)*log(4+-1*x^2)+(1/2)*i*x^2+-1*(1//6*d+2//3*f+8//3*h)*arctanh((1/2)*x)+-1*(1//6*e+1//6*g+1//6*i)*log(1+-1*x^2))
@test integrate((1+x^2+x^4)^-1*(d+e*x), x) == :(-1//4*d*log(1+x^2+-1x)+1//4*d*log(1+x+x^2)+-1//6*d*3^(1/2)*arctan(1//3*3^(1/2)*(1+-2x))+1//3*e*3^(1/2)*arctan(1//3*3^(1/2)*(1+2*x^2))+1//6*d*3^(1/2)*arctan(1//3*3^(1/2)*(1+2x)))
@test integrate((1+x^2+x^4)^-1*(d+e*x+f*x^2), x) == :((-1//4*f+1//4*d)*log(1+x+x^2)+-1*(-1//4*f+1//4*d)*log(1+x^2+-1x)+-1//6*3^(1/2)*(d+f)*arctan(1//3*3^(1/2)*(1+-2x))+1//3*e*3^(1/2)*arctan(1//3*3^(1/2)*(1+2*x^2))+1//6*3^(1/2)*(d+f)*arctan(1//3*3^(1/2)*(1+2x)))
@test integrate((1+x^2+x^4)^-1*(d+e*x+f*x^2+g*x^3), x) == :((-1//4*f+1//4*d)*log(1+x+x^2)+-1*(-1//4*f+1//4*d)*log(1+x^2+-1x)+1//4*g*log(1+x^2+x^4)+-1//6*3^(1/2)*(d+f)*arctan(1//3*3^(1/2)*(1+-2x))+1//6*3^(1/2)*(d+f)*arctan(1//3*3^(1/2)*(1+2x))+1//6*3^(1/2)*(-1g+2*e)*arctan(1//3*3^(1/2)*(1+2*x^2)))
@test integrate((1+x^2+x^4)^-1*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :(h*x+(-1//4*f+1//4*d)*log(1+x+x^2)+-1*(-1//4*f+1//4*d)*log(1+x^2+-1x)+1//4*g*log(1+x^2+x^4)+-1//6*3^(1/2)*(d+f+-2h)*arctan(1//3*3^(1/2)*(1+-2x))+1//6*3^(1/2)*(-1g+2*e)*arctan(1//3*3^(1/2)*(1+2*x^2))+1//6*3^(1/2)*(d+f+-2h)*arctan(1//3*3^(1/2)*(1+2x)))
@test integrate((1+x^2+x^4)^-1*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :(h*x+(-1//4*f+1//4*d)*log(1+x+x^2)+(-1//4*i+1//4*g)*log(1+x^2+x^4)+(1/2)*i*x^2+-1*(-1//4*f+1//4*d)*log(1+x^2+-1x)+-1//6*3^(1/2)*(d+f+-2h)*arctan(1//3*3^(1/2)*(1+-2x))+1//6*3^(1/2)*(d+f+-2h)*arctan(1//3*3^(1/2)*(1+2x))+1//6*3^(1/2)*(-1g+-1i+2*e)*arctan(1//3*3^(1/2)*(1+2*x^2)))
@test integrate((a+b*x^2+c*x^4)^-1*(d+e*x), x) == :(-1*e*(b^2+-4*a*c)^-1//2*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+d*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1//2*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2)+-1*d*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1//2*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-1*(d+e*x+f*x^2), x) == :(-1*e*(b^2+-4*a*c)^-1//2*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+(1/2)*2^(1/2)*c^-1//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(f+-1*(b^2+-4*a*c)^-1//2*(-1*b*f+2*c*d))*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+(1/2)*2^(1/2)*c^-1//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(f+(b^2+-4*a*c)^-1//2*(-1*b*f+2*c*d))*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-1*(d+e*x+f*x^2+g*x^3), x) == :(1//4*g*c^-1*log(a+b*x^2+c*x^4)+-1//2*c^-1*(b^2+-4*a*c)^-1//2*(-1*b*g+2*c*e)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+(1/2)*2^(1/2)*c^-1//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(f+-1*(b^2+-4*a*c)^-1//2*(-1*b*f+2*c*d))*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+(1/2)*2^(1/2)*c^-1//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(f+(b^2+-4*a*c)^-1//2*(-1*b*f+2*c*d))*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-1*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :(h*x*c^-1+1//4*g*c^-1*log(a+b*x^2+c*x^4)+-1//2*c^-1*(b^2+-4*a*c)^-1//2*(-1*b*g+2*c*e)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+(1/2)*2^(1/2)*c^-3//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(c*f+-1*b*h+-1*(b^2+-4*a*c)^-1//2*(h*b^2+2*d*c^2+-1*b*c*f+-2*a*c*h))*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+(1/2)*2^(1/2)*c^-3//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(c*f+(b^2+-4*a*c)^-1//2*(h*b^2+-1*c*(b*f+2*a*h)+2*d*c^2)+-1*b*h)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-1*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :(h*x*c^-1+(1/2)*i*c^-1*x^2+1//4*c^-2*(c*g+-1*b*i)*log(a+b*x^2+c*x^4)+-1//2*c^-2*(b^2+-4*a*c)^-1//2*(i*b^2+2*e*c^2+-1*b*c*g+-2*a*c*i)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+(1/2)*2^(1/2)*c^-3//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(c*f+-1*b*h+-1*(b^2+-4*a*c)^-1//2*(h*b^2+2*d*c^2+-1*b*c*f+-2*a*c*h))*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+(1/2)*2^(1/2)*c^-3//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(c*f+(b^2+-4*a*c)^-1//2*(h*b^2+-1*c*(b*f+2*a*h)+2*d*c^2)+-1*b*h)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-1*(d+e*x+f*x^2+g*x^3+h*x^4+j*x^5+k*x^6+l*x^7+m*x^8), x) == :(x*c^-3*(h*c^2+m*b^2+-1*c*(a*m+b*k))+(1/2)*c^-2*x^2*(c*j+-1*b*l)+1//3*c^-2*x^3*(c*k+-1*b*m)+1//4*l*c^-1*x^4+1//4*c^-3*(g*c^2+l*b^2+-1*c*(a*l+b*j))*log(a+b*x^2+c*x^4)+1//5*m*c^-1*x^5+-1//2*c^-3*(b^2+-4*a*c)^-1//2*(-1*l*b^3+-1*c^2*(b*g+2*a*j)+2*e*c^3+b*c*(b*j+3*a*l))*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+(1/2)*2^(1/2)*c^-7//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(f*c^3+-1*m*b^3+-1*c^2*(a*k+b*h)+-1*(b^2+-4*a*c)^-1//2*(m*b^4+c^2*(h*b^2+2*m*a^2+3*a*b*k)+-1*c^3*(b*f+2*a*h)+2*d*c^4+-1*c*b^2*(b*k+4*a*m))+b*c*(b*k+2*a*m))*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+(1/2)*2^(1/2)*c^-7//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(f*c^3+(b^2+-4*a*c)^-1//2*(m*b^4+c^2*(h*b^2+2*m*a^2+3*a*b*k)+-1*c^3*(b*f+2*a*h)+2*d*c^4+-1*c*b^2*(b*k+4*a*m))+-1*m*b^3+-1*c^2*(a*k+b*h)+b*c*(b*k+2*a*m))*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((4+x^4+-5*x^2)^-2*(d+e*x), x) == :(-1//27*e*log(4+-1*x^2)+-1//54*d*arctanh(x)+1//27*e*log(1+-1*x^2)+19//432*d*arctanh((1/2)*x)+e*(72+-90*x^2+18*x^4)^-1*(5+-2*x^2)+d*x*(288+-360*x^2+72*x^4)^-1*(17+-5*x^2))
@test integrate((4+x^4+-5*x^2)^-2*(d+e*x+f*x^2), x) == :((13//108*f+19//432*d)*arctanh((1/2)*x)+-1*(1//54*d+7//54*f)*arctanh(x)+-1//27*e*log(4+-1*x^2)+1//27*e*log(1+-1*x^2)+e*(72+-90*x^2+18*x^4)^-1*(5+-2*x^2)+x*(288+-360*x^2+72*x^4)^-1*(17d+20*f+-1*x^2*(5d+8*f)))
@test integrate((4+x^4+-5*x^2)^-2*(d+e*x+f*x^2+g*x^3), x) == :((72+-90*x^2+18*x^4)^-1*(5*e+8g+-1*x^2*(2*e+5g))+(1//27*e+5//54*g)*log(1+-1*x^2)+(13//108*f+19//432*d)*arctanh((1/2)*x)+-1*(1//27*e+5//54*g)*log(4+-1*x^2)+-1*(1//54*d+7//54*f)*arctanh(x)+x*(288+-360*x^2+72*x^4)^-1*(17d+20*f+-1*x^2*(5d+8*f)))
@test integrate((4+x^4+-5*x^2)^-2*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :((72+-90*x^2+18*x^4)^-1*(5*e+8g+-1*x^2*(2*e+5g))+(1//27*e+5//54*g)*log(1+-1*x^2)+(7//27*h+13//108*f+19//432*d)*arctanh((1/2)*x)+-1*(1//27*e+5//54*g)*log(4+-1*x^2)+-1*(1//54*d+7//54*f+13//54*h)*arctanh(x)+x*(288+-360*x^2+72*x^4)^-1*(17d+20*f+32h+-1*x^2*(5d+8*f+20h)))
@test integrate((4+x^4+-5*x^2)^-2*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :((72+-90*x^2+18*x^4)^-1*(5*e+8g+20i+-1*x^2*(2*e+5g+17i))+(1//27*e+4//27*i+5//54*g)*log(1+-1*x^2)+(7//27*h+13//108*f+19//432*d)*arctanh((1/2)*x)+-1*(1//27*e+4//27*i+5//54*g)*log(4+-1*x^2)+-1*(1//54*d+7//54*f+13//54*h)*arctanh(x)+x*(288+-360*x^2+72*x^4)^-1*(17d+20*f+32h+-1*x^2*(5d+8*f+20h)))
@test integrate((1+x^2+x^4)^-2*(d+e*x), x) == :(-1//4*d*log(1+x^2+-1x)+1//4*d*log(1+x+x^2)+e*(6+6*x^2+6*x^4)^-1*(1+2*x^2)+-1//9*d*3^(1/2)*arctan(1//3*3^(1/2)*(1+-2x))+1//9*d*3^(1/2)*arctan(1//3*3^(1/2)*(1+2x))+2//9*e*3^(1/2)*arctan(1//3*3^(1/2)*(1+2*x^2))+d*x*(6+6*x^2+6*x^4)^-1*(1+-1*x^2))
@test integrate((1+x^2+x^4)^-2*(d+e*x+f*x^2), x) == :((-1//8*f+1//4*d)*log(1+x+x^2)+-1*(-1//8*f+1//4*d)*log(1+x^2+-1x)+e*(6+6*x^2+6*x^4)^-1*(1+2*x^2)+x*(6+6*x^2+6*x^4)^-1*(d+f+-1*x^2*(d+-2*f))+-1//36*3^(1/2)*(f+4d)*arctan(1//3*3^(1/2)*(1+-2x))+1//36*3^(1/2)*(f+4d)*arctan(1//3*3^(1/2)*(1+2x))+2//9*e*3^(1/2)*arctan(1//3*3^(1/2)*(1+2*x^2)))
@test integrate((1+x^2+x^4)^-2*(d+e*x+f*x^2+g*x^3), x) == :((6+6*x^2+6*x^4)^-1*(e+-2g+x^2*(-1g+2*e))+(-1//8*f+1//4*d)*log(1+x+x^2)+-1*(-1//8*f+1//4*d)*log(1+x^2+-1x)+x*(6+6*x^2+6*x^4)^-1*(d+f+-1*x^2*(d+-2*f))+-1//36*3^(1/2)*(f+4d)*arctan(1//3*3^(1/2)*(1+-2x))+1//9*3^(1/2)*(-1g+2*e)*arctan(1//3*3^(1/2)*(1+2*x^2))+1//36*3^(1/2)*(f+4d)*arctan(1//3*3^(1/2)*(1+2x)))
@test integrate((1+x^2+x^4)^-2*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :((6+6*x^2+6*x^4)^-1*(e+-2g+x^2*(-1g+2*e))+(-1//8*f+1//4*d+1//8*h)*log(1+x+x^2)+-1*(-1//8*f+1//4*d+1//8*h)*log(1+x^2+-1x)+x*(6+6*x^2+6*x^4)^-1*(d+f+-2h+-1*x^2*(d+h+-2*f))+-1//36*3^(1/2)*(f+h+4d)*arctan(1//3*3^(1/2)*(1+-2x))+1//9*3^(1/2)*(-1g+2*e)*arctan(1//3*3^(1/2)*(1+2*x^2))+1//36*3^(1/2)*(f+h+4d)*arctan(1//3*3^(1/2)*(1+2x)))
@test integrate((1+x^2+x^4)^-2*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :((6+6*x^2+6*x^4)^-1*(e+i+-2g+x^2*(-1g+-1i+2*e))+(-1//8*f+1//4*d+1//8*h)*log(1+x+x^2)+-1*(-1//8*f+1//4*d+1//8*h)*log(1+x^2+-1x)+x*(6+6*x^2+6*x^4)^-1*(d+f+-2h+-1*x^2*(d+h+-2*f))+-1//36*3^(1/2)*(f+h+4d)*arctan(1//3*3^(1/2)*(1+-2x))+1//9*3^(1/2)*(-1g+2*e+2i)*arctan(1//3*3^(1/2)*(1+2*x^2))+1//36*3^(1/2)*(f+h+4d)*arctan(1//3*3^(1/2)*(1+2x)))
@test integrate((a+b*x^2+c*x^4)^-2*(d+e*x), x) == :(-1*e*(2*b^2+-8*a*c)^-1*(a+b*x^2+c*x^4)^-1*(b+2*c*x^2)+2*c*e*(b^2+-4*a*c)^-3//2*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+(1/2)*d*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(b^2+-2*a*c+b*c*x^2)+-1//4*d*2^(1/2)*a^-1*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-3//2*(b^2+-1*b*(b^2+-4*a*c)^(1/2)+-12*a*c)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//4*d*2^(1/2)*a^-1*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-3//2*(b^2+b*(b^2+-4*a*c)^(1/2)+-12*a*c)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-2*(d+e*x+f*x^2), x) == :(-1*e*(2*b^2+-8*a*c)^-1*(a+b*x^2+c*x^4)^-1*(b+2*c*x^2)+2*c*e*(b^2+-4*a*c)^-3//2*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+(1/2)*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(d*b^2+c*x^2*(b*d+-2*a*f)+-1*a*b*f+-2*a*c*d)+1//4*2^(1/2)*a^-1*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(b*d+-1*(b^2+-4*a*c)^-1//2*(d*b^2+-12*a*c*d+4*a*b*f)+-2*a*f)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//4*2^(1/2)*a^-1*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(b*d+(b^2+-4*a*c)^-1//2*(d*b^2+-12*a*c*d+4*a*b*f)+-2*a*f)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-2*(d+e*x+f*x^2+g*x^3), x) == :((b^2+-4*a*c)^-3//2*(-1*b*g+2*c*e)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+-1*(2*b^2+-8*a*c)^-1*(a+b*x^2+c*x^4)^-1*(b*e+x^2*(-1*b*g+2*c*e)+-2*a*g)+(1/2)*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(d*b^2+c*x^2*(b*d+-2*a*f)+-1*a*b*f+-2*a*c*d)+1//4*2^(1/2)*a^-1*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(b*d+-1*(b^2+-4*a*c)^-1//2*(d*b^2+-12*a*c*d+4*a*b*f)+-2*a*f)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//4*2^(1/2)*a^-1*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(b*d+(b^2+-4*a*c)^-1//2*(d*b^2+-12*a*c*d+4*a*b*f)+-2*a*f)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-2*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :((b^2+-4*a*c)^-3//2*(-1*b*g+2*c*e)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+-1*(2*b^2+-8*a*c)^-1*(a+b*x^2+c*x^4)^-1*(b*e+x^2*(-1*b*g+2*c*e)+-2*a*g)+(1/2)*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(d*b^2+x^2*(a*b*h+b*c*d+-2*a*c*f)+-2*a*(c*d+-1*a*h)+-1*a*b*f)+1//4*2^(1/2)*a^-1*c^-1//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(-1*(b^2+-4*a*c)^-1//2*(b^2*(c*d+-1*a*h)+-4*a*c*(a*h+3*c*d)+4*a*b*c*f)+a*b*h+b*c*d+-2*a*c*f)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//4*2^(1/2)*a^-1*c^-1//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*((b^2+-4*a*c)^-1//2*(b^2*(c*d+-1*a*h)+-4*a*c*(a*h+3*c*d)+4*a*b*c*f)+a*b*h+b*c*d+-2*a*c*f)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-2*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :((b^2+-4*a*c)^-3//2*(-1*b*g+2*a*i+2*c*e)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+(1/2)*c^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(-1*b*(a*i+c*e)+-1*x^2*(i*b^2+2*e*c^2+-1*b*c*g+-2*a*c*i)+2*a*c*g)+(1/2)*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(d*b^2+x^2*(a*b*h+b*c*d+-2*a*c*f)+-2*a*(c*d+-1*a*h)+-1*a*b*f)+1//4*2^(1/2)*a^-1*c^-1//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(-1*(b^2+-4*a*c)^-1//2*(b^2*(c*d+-1*a*h)+-4*a*c*(a*h+3*c*d)+4*a*b*c*f)+a*b*h+b*c*d+-2*a*c*f)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//4*2^(1/2)*a^-1*c^-1//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*((b^2+-4*a*c)^-1//2*(b^2*(c*d+-1*a*h)+-4*a*c*(a*h+3*c*d)+4*a*b*c*f)+a*b*h+b*c*d+-2*a*c*f)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-2*(d+e*x+f*x^2+g*x^3+h*x^4+j*x^5+k*x^6+l*x^7+m*x^8), x) == :(m*x*c^-2+1//4*l*c^-2*log(a+b*x^2+c*x^4)+(1/2)*c^-2*(b^2+-4*a*c)^-3//2*(l*b^3+-1*c^2*(-4*a*j+2*b*g)+4*e*c^3+-6*a*b*c*l)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+-1//2*c^-2*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(x^2*(-1*l*b^3+-1*c^2*(b*g+2*a*j)+2*e*c^3+b*c*(b*j+3*a*l))+b*c*(a*j+c*e)+-1*a*l*b^2+-2*a*c*(c*g+-1*a*l))+-1//2*x*a^-1*c^-2*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(x^2*(-1*a*m*b^3+-1*b*c*(d*c^2+-3*m*a^2+a*c*h)+2*a*c^2*(c*f+-1*a*k)+a*c*k*b^2)+-1*b^2*(d*c^2+m*a^2)+2*a*c*(d*c^2+m*a^2+-1*a*c*h)+a*b*c*(a*k+c*f))+1//4*2^(1/2)*a^-1*c^-5//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*((b^2+-4*a*c)^-1//2*(-1*c*b^2*(d*c^2+-19*m*a^2+-1*a*c*h)+-3*a*m*b^4+4*a*c^2*(-5*m*a^2+3*d*c^2+a*c*h)+a*c*k*b^3+-4*a*b*c^2*(c*f+2*a*k))+b*c*(d*c^2+13*m*a^2+a*c*h)+-3*a*m*b^3+-2*a*c^2*(c*f+3*a*k)+a*c*k*b^2)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//4*2^(1/2)*a^-1*c^-5//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(-1*(b^2+-4*a*c)^-1//2*(-1*c*b^2*(d*c^2+-19*m*a^2+-1*a*c*h)+-3*a*m*b^4+4*a*c^2*(-5*m*a^2+3*d*c^2+a*c*h)+a*c*k*b^3+-4*a*b*c^2*(c*f+2*a*k))+b*c*(d*c^2+13*m*a^2+a*c*h)+-3*a*m*b^3+-2*a*c^2*(c*f+3*a*k)+a*c*k*b^2)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((4+x^4+-5*x^2)^-3*(d+e*x), x) == :(-313//20736*d*arctanh((1/2)*x)+-1//81*e*log(1+-1*x^2)+1//81*e*log(4+-1*x^2)+13//648*d*arctanh(x)+-1*e*(216+-270*x^2+54*x^4)^-1*(5+-2*x^2)+1//36*e*(4+x^4+-5*x^2)^-2*(5+-2*x^2)+-1*d*x*(13824+-17280*x^2+3456*x^4)^-1*(59+-35*x^2)+1//144*d*x*(4+x^4+-5*x^2)^-2*(17+-5*x^2))
@test integrate((4+x^4+-5*x^2)^-3*(d+e*x+f*x^2), x) == :((13//648*d+25//648*f)*arctanh(x)+-1//81*e*log(1+-1*x^2)+-1//20736*(313d+820*f)*arctanh((1/2)*x)+1//81*e*log(4+-1*x^2)+-1*e*(216+-270*x^2+54*x^4)^-1*(5+-2*x^2)+-1*x*(13824+-17280*x^2+3456*x^4)^-1*(59d+380*f+-1*x^2*(35d+140*f))+1//36*e*(4+x^4+-5*x^2)^-2*(5+-2*x^2)+1//144*x*(4+x^4+-5*x^2)^-2*(17d+20*f+-1*x^2*(5d+8*f)))
@test integrate((4+x^4+-5*x^2)^-3*(d+e*x+f*x^2+g*x^3), x) == :((1//81*e+5//162*g)*log(4+-1*x^2)+(13//648*d+25//648*f)*arctanh(x)+-1*(1//81*e+5//162*g)*log(1+-1*x^2)+-1//20736*(313d+820*f)*arctanh((1/2)*x)+1//36*(4+x^4+-5*x^2)^-2*(5*e+8g+-1*x^2*(2*e+5g))+-1*x*(13824+-17280*x^2+3456*x^4)^-1*(59d+380*f+-1*x^2*(35d+140*f))+-1*(432+-540*x^2+108*x^4)^-1*(5+-2*x^2)*(2*e+5g)+1//144*x*(4+x^4+-5*x^2)^-2*(17d+20*f+-1*x^2*(5d+8*f)))
@test integrate((4+x^4+-5*x^2)^-3*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :((1//81*e+5//162*g)*log(4+-1*x^2)+(13//648*d+25//648*f+61//648*h)*arctanh(x)+-1*(1//81*e+5//162*g)*log(1+-1*x^2)+-1//20736*(313d+820*f+1936h)*arctanh((1/2)*x)+1//36*(4+x^4+-5*x^2)^-2*(5*e+8g+-1*x^2*(2*e+5g))+-1*x*(13824+-17280*x^2+3456*x^4)^-1*(59d+380*f+848h+-1*x^2*(35d+140*f+320h))+-1*(432+-540*x^2+108*x^4)^-1*(5+-2*x^2)*(2*e+5g)+1//144*x*(4+x^4+-5*x^2)^-2*(17d+20*f+32h+-1*x^2*(5d+8*f+20h)))
@test integrate((4+x^4+-5*x^2)^-3*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :((1//81*e+5//162*g+11//162*i)*log(4+-1*x^2)+(13//648*d+25//648*f+61//648*h)*arctanh(x)+-1*(1//81*e+5//162*g+11//162*i)*log(1+-1*x^2)+-1//20736*(313d+820*f+1936h)*arctanh((1/2)*x)+1//36*(4+x^4+-5*x^2)^-2*(5*e+8g+20i+-1*x^2*(2*e+5g+17i))+-1*x*(13824+-17280*x^2+3456*x^4)^-1*(59d+380*f+848h+-1*x^2*(35d+140*f+320h))+-1*(432+-540*x^2+108*x^4)^-1*(5+-2*x^2)*(2*e+5g+11i)+1//144*x*(4+x^4+-5*x^2)^-2*(17d+20*f+32h+-1*x^2*(5d+8*f+20h)))
@test integrate((1+x^2+x^4)^-3*(d+e*x), x) == :(-9//32*d*log(1+x^2+-1x)+9//32*d*log(1+x+x^2)+e*(6+6*x^2+6*x^4)^-1*(1+2*x^2)+-13//144*d*3^(1/2)*arctan(1//3*3^(1/2)*(1+-2x))+1//12*e*(1+x^2+x^4)^-2*(1+2*x^2)+2//9*e*3^(1/2)*arctan(1//3*3^(1/2)*(1+2*x^2))+13//144*d*3^(1/2)*arctan(1//3*3^(1/2)*(1+2x))+d*x*(24+24*x^2+24*x^4)^-1*(2+-7*x^2)+1//12*d*x*(1+x^2+x^4)^-2*(1+-1*x^2))
@test integrate((1+x^2+x^4)^-3*(d+e*x+f*x^2), x) == :((-1//8*f+9//32*d)*log(1+x+x^2)+-1*(-1//8*f+9//32*d)*log(1+x^2+-1x)+e*(6+6*x^2+6*x^4)^-1*(1+2*x^2)+x*(24+24*x^2+24*x^4)^-1*(2d+3*f+-1*x^2*(-7*f+7d))+-1//144*3^(1/2)*(2*f+13d)*arctan(1//3*3^(1/2)*(1+-2x))+1//12*e*(1+x^2+x^4)^-2*(1+2*x^2)+1//12*x*(1+x^2+x^4)^-2*(d+f+-1*x^2*(d+-2*f))+1//144*3^(1/2)*(2*f+13d)*arctan(1//3*3^(1/2)*(1+2x))+2//9*e*3^(1/2)*arctan(1//3*3^(1/2)*(1+2*x^2)))
@test integrate((1+x^2+x^4)^-3*(d+e*x+f*x^2+g*x^3), x) == :((-1//8*f+9//32*d)*log(1+x+x^2)+-1*(-1//8*f+9//32*d)*log(1+x^2+-1x)+1//12*(1+x^2+x^4)^-2*(e+-2g+x^2*(-1g+2*e))+x*(24+24*x^2+24*x^4)^-1*(2d+3*f+-1*x^2*(-7*f+7d))+(12+12*x^2+12*x^4)^-1*(1+2*x^2)*(-1g+2*e)+-1//144*3^(1/2)*(2*f+13d)*arctan(1//3*3^(1/2)*(1+-2x))+1//9*3^(1/2)*(-1g+2*e)*arctan(1//3*3^(1/2)*(1+2*x^2))+1//12*x*(1+x^2+x^4)^-2*(d+f+-1*x^2*(d+-2*f))+1//144*3^(1/2)*(2*f+13d)*arctan(1//3*3^(1/2)*(1+2x)))
@test integrate((1+x^2+x^4)^-3*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :((-1//8*f+3//32*h+9//32*d)*log(1+x+x^2)+-1*(-1//8*f+3//32*h+9//32*d)*log(1+x^2+-1x)+1//12*(1+x^2+x^4)^-2*(e+-2g+x^2*(-1g+2*e))+x*(24+24*x^2+24*x^4)^-1*(-1h+2d+3*f+-1*x^2*(-7*f+4h+7d))+(12+12*x^2+12*x^4)^-1*(1+2*x^2)*(-1g+2*e)+-1//144*3^(1/2)*(h+2*f+13d)*arctan(1//3*3^(1/2)*(1+-2x))+1//9*3^(1/2)*(-1g+2*e)*arctan(1//3*3^(1/2)*(1+2*x^2))+1//12*x*(1+x^2+x^4)^-2*(d+f+-2h+-1*x^2*(d+h+-2*f))+1//144*3^(1/2)*(h+2*f+13d)*arctan(1//3*3^(1/2)*(1+2x)))
@test integrate((1+x^2+x^4)^-3*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :((-1//8*f+3//32*h+9//32*d)*log(1+x+x^2)+-1*(-1//8*f+3//32*h+9//32*d)*log(1+x^2+-1x)+1//12*(1+x^2+x^4)^-2*(e+i+-2g+x^2*(-1g+-1i+2*e))+x*(24+24*x^2+24*x^4)^-1*(-1h+2d+3*f+-1*x^2*(-7*f+4h+7d))+(12+12*x^2+12*x^4)^-1*(1+2*x^2)*(i+-1g+2*e)+-1//144*3^(1/2)*(h+2*f+13d)*arctan(1//3*3^(1/2)*(1+-2x))+1//9*3^(1/2)*(i+-1g+2*e)*arctan(1//3*3^(1/2)*(1+2*x^2))+1//12*x*(1+x^2+x^4)^-2*(d+f+-2h+-1*x^2*(d+h+-2*f))+1//144*3^(1/2)*(h+2*f+13d)*arctan(1//3*3^(1/2)*(1+2x)))
@test integrate((a+b*x^2+c*x^4)^-3*(d+e*x), x) == :(-1*e*(4*b^2+-16*a*c)^-1*(a+b*x^2+c*x^4)^-2*(b+2*c*x^2)+-6*e*c^2*(b^2+-4*a*c)^-5//2*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+3//2*c*e*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(b+2*c*x^2)+1//4*d*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(b^2+-2*a*c+b*c*x^2)+1//8*d*x*a^-2*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*((b^2+-7*a*c)*(3*b^2+-4*a*c)+3*b*c*x^2*(b^2+-8*a*c))+3//16*d*2^(1/2)*a^-2*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*(b^3+-1*(b^2+-4*a*c)^-1//2*(b^4+56*a^2*c^2+-10*a*c*b^2)+-8*a*b*c)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+3//16*d*2^(1/2)*a^-2*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-5//2*(b^4+56*a^2*c^2+b*(b^2+-4*a*c)^(1/2)*(b^2+-8*a*c)+-10*a*c*b^2)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-3*(d+e*x+f*x^2), x) == :(-1*e*(4*b^2+-16*a*c)^-1*(a+b*x^2+c*x^4)^-2*(b+2*c*x^2)+-6*e*c^2*(b^2+-4*a*c)^-5//2*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+1//4*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(d*b^2+c*x^2*(b*d+-2*a*f)+-1*a*b*f+-2*a*c*d)+1//8*x*a^-2*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(3*d*b^4+a*f*b^3+c*x^2*(3*d*b^3+a*f*b^2+20*c*f*a^2+-24*a*b*c*d)+28*d*a^2*c^2+-25*a*c*d*b^2+8*b*c*f*a^2)+3//2*c*e*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(b+2*c*x^2)+1//16*2^(1/2)*a^-2*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*(-1*(b^2+-4*a*c)^-1//2*(3*d*b^4+a*f*b^3+168*d*a^2*c^2+-52*b*c*f*a^2+-30*a*c*d*b^2)+3*d*b^3+a*f*b^2+20*c*f*a^2+-24*a*b*c*d)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//16*2^(1/2)*a^-2*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-5//2*(b^3*(a*f+3*d*(b^2+-4*a*c)^(1/2))+3*d*b^4+-1*a*b^2*(-1*f*(b^2+-4*a*c)^(1/2)+30*c*d)+4*c*a^2*(5*f*(b^2+-4*a*c)^(1/2)+42*c*d)+-4*a*b*c*(6*d*(b^2+-4*a*c)^(1/2)+13*a*f))*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-3*(d+e*x+f*x^2+g*x^3), x) == :(-1*(4*b^2+-16*a*c)^-1*(a+b*x^2+c*x^4)^-2*(b*e+x^2*(-1*b*g+2*c*e)+-2*a*g)+-3*c*(b^2+-4*a*c)^-5//2*(-1*b*g+2*c*e)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+1//4*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(b+2*c*x^2)*(-3*b*g+6*c*e)+1//4*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(d*b^2+c*x^2*(b*d+-2*a*f)+-1*a*b*f+-2*a*c*d)+1//8*x*a^-2*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(3*d*b^4+a*f*b^3+c*x^2*(3*d*b^3+a*f*b^2+20*c*f*a^2+-24*a*b*c*d)+28*d*a^2*c^2+-25*a*c*d*b^2+8*b*c*f*a^2)+1//16*2^(1/2)*a^-2*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*(-1*(b^2+-4*a*c)^-1//2*(3*d*b^4+a*f*b^3+168*d*a^2*c^2+-52*b*c*f*a^2+-30*a*c*d*b^2)+3*d*b^3+a*f*b^2+20*c*f*a^2+-24*a*b*c*d)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//16*2^(1/2)*a^-2*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-5//2*(b^3*(a*f+3*d*(b^2+-4*a*c)^(1/2))+3*d*b^4+-1*a*b^2*(-1*f*(b^2+-4*a*c)^(1/2)+30*c*d)+4*c*a^2*(5*f*(b^2+-4*a*c)^(1/2)+42*c*d)+-4*a*b*c*(6*d*(b^2+-4*a*c)^(1/2)+13*a*f))*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-3*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :(-1*(4*b^2+-16*a*c)^-1*(a+b*x^2+c*x^4)^-2*(b*e+x^2*(-1*b*g+2*c*e)+-2*a*g)+-3*c*(b^2+-4*a*c)^-5//2*(-1*b*g+2*c*e)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+1//4*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(b+2*c*x^2)*(-3*b*g+6*c*e)+1//4*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(d*b^2+x^2*(a*b*h+b*c*d+-2*a*c*f)+-2*a*(c*d+-1*a*h)+-1*a*b*f)+1//8*x*a^-2*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(3*d*b^4+a*f*b^3+c*x^2*(3*d*b^3+a*f*b^2+-12*a*b*(a*h+2*c*d)+20*c*f*a^2)+-1*a*b^2*(7*a*h+25*c*d)+4*c*a^2*(a*h+7*c*d)+8*b*c*f*a^2)+1//16*2^(1/2)*a^-2*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*(-1*(b^2+-4*a*c)^-1//2*(3*d*b^4+a*f*b^3+-6*a*b^2*(-3*a*h+5*c*d)+24*c*a^2*(a*h+7*c*d)+-52*b*c*f*a^2)+3*d*b^3+a*f*b^2+-12*a*b*(a*h+2*c*d)+20*c*f*a^2)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//16*2^(1/2)*a^-2*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*((b^2+-4*a*c)^-1//2*(3*d*b^4+a*f*b^3+-6*a*b^2*(-3*a*h+5*c*d)+24*c*a^2*(a*h+7*c*d)+-52*b*c*f*a^2)+3*d*b^3+a*f*b^2+-12*a*b*(a*h+2*c*d)+20*c*f*a^2)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-3*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :(-1*(b^2+-4*a*c)^-5//2*(i*b^2+6*e*c^2+-3*b*c*g+2*a*c*i)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+1//4*c^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(-1*b*(a*i+c*e)+-1*x^2*(i*b^2+2*e*c^2+-1*b*c*g+-2*a*c*i)+2*a*c*g)+1//4*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(b+2*c*x^2)*(-3*b*g+2*a*i+6*c*e+i*b^2*c^-1)+1//4*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(d*b^2+x^2*(a*b*h+b*c*d+-2*a*c*f)+-2*a*(c*d+-1*a*h)+-1*a*b*f)+1//8*x*a^-2*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(3*d*b^4+a*f*b^3+c*x^2*(3*d*b^3+a*f*b^2+-12*a*b*(a*h+2*c*d)+20*c*f*a^2)+-1*a*b^2*(7*a*h+25*c*d)+4*c*a^2*(a*h+7*c*d)+8*b*c*f*a^2)+1//16*2^(1/2)*a^-2*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*(-1*(b^2+-4*a*c)^-1//2*(3*d*b^4+a*f*b^3+-6*a*b^2*(-3*a*h+5*c*d)+24*c*a^2*(a*h+7*c*d)+-52*b*c*f*a^2)+3*d*b^3+a*f*b^2+-12*a*b*(a*h+2*c*d)+20*c*f*a^2)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//16*2^(1/2)*a^-2*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*((b^2+-4*a*c)^-1//2*(3*d*b^4+a*f*b^3+-6*a*b^2*(-3*a*h+5*c*d)+24*c*a^2*(a*h+7*c*d)+-52*b*c*f*a^2)+3*d*b^3+a*f*b^2+-12*a*b*(a*h+2*c*d)+20*c*f*a^2)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-3*(d+e*x+f*x^2+g*x^3+h*x^4+j*x^5+k*x^6+l*x^7+m*x^8), x) == :(-1*(b^2+-4*a*c)^-5//2*(j*b^2+6*e*c^2+-3*a*b*l+-3*b*c*g+2*a*c*j)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+1//4*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(x^2*(2*j*b^2+12*e*c^2+-6*a*b*l+-6*b*c*g+4*a*c*j)+-1*b^2*(3g+-5*a*l*c^-1)+-16*l*a^2+2*b*(a*j+3*c*e)+j*b^3*c^-1+-1*l*b^4*c^-2)+-1//4*c^-2*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(x^2*(-1*l*b^3+-1*c^2*(b*g+2*a*j)+2*e*c^3+b*c*(b*j+3*a*l))+b*c*(a*j+c*e)+-1*a*l*b^2+-2*a*c*(c*g+-1*a*l))+-1//4*x*a^-1*c^-2*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(x^2*(-1*a*m*b^3+-1*b*c*(d*c^2+-3*m*a^2+a*c*h)+2*a*c^2*(c*f+-1*a*k)+a*c*k*b^2)+-1*b^2*(d*c^2+m*a^2)+2*a*c*(d*c^2+m*a^2+-1*a*c*h)+a*b*c*(a*k+c*f))+1//8*x*a^-2*c^-2*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(b^4*(-2*m*a^2+3*d*c^2)+c*x^2*(b^3*(m*a^2+3*d*c^2)+4*a^2*c^2*(3*a*k+5*c*f)+a*c*b^2*(c*f+3*a*k)+-4*a*b*c*(4*m*a^2+6*d*c^2+3*a*c*h))+4*a^2*c^2*(-9*m*a^2+7*d*c^2+a*c*h)+a*c*b^3*(c*f+2*a*k)+-1*a*c*b^2*(-11*m*a^2+25*d*c^2+7*a*c*h)+4*b*a^2*c^2*(a*k+2*c*f))+1//16*2^(1/2)*a^-2*c^-3//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*(b^3*(m*a^2+3*d*c^2)+-1*(b^2+-4*a*c)^-1//2*(b^4*(-1*m*a^2+3*d*c^2)+8*a^2*c^2*(5*m*a^2+21*d*c^2+3*a*c*h)+a*c*b^3*(c*f+-3*a*k)+-6*a*c*b^2*(-3*m*a^2+5*d*c^2+-3*a*c*h)+-4*b*a^2*c^2*(9*a*k+13*c*f))+4*a^2*c^2*(3*a*k+5*c*f)+a*c*b^2*(c*f+3*a*k)+-4*a*b*c*(4*m*a^2+6*d*c^2+3*a*c*h))*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//16*2^(1/2)*a^-2*c^-3//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*(b^3*(m*a^2+3*d*c^2)+(b^2+-4*a*c)^-1//2*(b^4*(-1*m*a^2+3*d*c^2)+8*a^2*c^2*(5*m*a^2+21*d*c^2+3*a*c*h)+a*c*b^3*(c*f+-3*a*k)+-6*a*c*b^2*(-3*m*a^2+5*d*c^2+-3*a*c*h)+-4*b*a^2*c^2*(9*a*k+13*c*f))+4*a^2*c^2*(3*a*k+5*c*f)+a*c*b^2*(c*f+3*a*k)+-4*a*b*c*(4*m*a^2+6*d*c^2+3*a*c*h))*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-2*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5+j*x^6+k*x^7), x) == :(1//4*k*c^-2*log(a+b*x^2+c*x^4)+(1/2)*c^-2*(b^2+-4*a*c)^-3//2*(k*b^3+-1*c^2*(-4*a*i+2*b*g)+4*e*c^3+-6*a*b*c*k)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+-1//2*c^-2*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(x^2*(-1*k*b^3+-1*c^2*(b*g+2*a*i)+2*e*c^3+b*c*(b*i+3*a*k))+b*c*(a*i+c*e)+-1*a*k*b^2+-2*a*c*(c*g+-1*a*k))+(1/2)*x*a^-1*c^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(c*(d*b^2+-2*a*(c*d+-1*a*h)+-1*a*b*c^-1*(a*j+c*f))+x^2*(b*c*(a*h+c*d)+-1*a*j*b^2+-2*a*c*(c*f+-1*a*j)))+1//4*2^(1/2)*a^-1*c^-1//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(b*(a*h+c*d)+-2*a*(c*f+3*a*j)+-1*c^-1*(b^2+-4*a*c)^-1//2*(c*b^2*(c*d+-1*a*h)+-1*a*j*b^3+-4*a*c^2*(a*h+3*c*d)+4*a*b*c*(c*f+2*a*j))+a*j*b^2*c^-1)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//4*2^(1/2)*a^-1*c^-1//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(b*(a*h+c*d)+-2*a*(c*f+3*a*j)+c^-1*(b^2+-4*a*c)^-1//2*(c*b^2*(c*d+-1*a*h)+-1*a*j*b^3+-4*a*c^2*(a*h+3*c*d)+4*a*b*c*(c*f+2*a*j))+a*j*b^2*c^-1)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-3*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5+j*x^8+k*x^11), x) == :(1//4*k*c^-3*log(a+b*x^2+c*x^4)+-1//2*c^-3*(b^2+-4*a*c)^-5//2*(-1*k*b^5+-1*c^4*(-4*a*i+6*b*g)+12*e*c^5+2*i*b^2*c^3+-30*b*k*a^2*c^2+10*a*c*k*b^3)*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+-1//4*c^-4*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(x^2*(-1*k*b^5+-1*c^4*(b*g+2*a*i)+2*e*c^5+i*b^2*c^3+-5*b*k*a^2*c^2+5*a*c*k*b^3)+b*c^3*(a*i+c*e)+-1*a*k*b^4+-2*a*c^2*(g*c^2+k*a^2)+4*c*k*a^2*b^2)+1//4*c^-3*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(x^2*(-2*c^4*(-2*a*i+3*b*g)+4*k*b^5+12*e*c^5+2*i*b^2*c^3+-30*a*c*k*b^3+50*b*k*a^2*c^2)+-3*b^2*(g*c^3+13*c*k*a^2)+i*b^3*c^2+-1*k*b^6*c^-1+2*b*c^3*(a*i+3*c*e)+11*a*k*b^4+32*k*a^3*c^2)+-1//4*x*a^-1*c^-2*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(c^2*(-1*b^2*(d+j*a^2*c^-2)+2*a*(c*d+-1*a*h+j*a^2*c^-1)+a*b*f)+x^2*(-1*a*j*b^3+-1*b*c*(d*c^2+-3*j*a^2+a*c*h)+2*a*f*c^3))+1//8*x*a^-2*c^-1*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(c*(b^4*(3d+-2*j*a^2*c^-2)+4*a^2*(-9*j*a^2+7*d*c^2+a*c*h)+a*f*b^3+-1*a*b^2*(7*a*h+25*c*d+-11*j*a^2*c^-1)+8*b*c*f*a^2)+x^2*(b^3*(j*a^2+3*d*c^2)+20*f*a^2*c^3+a*f*b^2*c^2+-4*a*b*c*(4*j*a^2+6*d*c^2+3*a*c*h)))+1//16*2^(1/2)*a^-2*c^-3//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*(b^3*(j*a^2+3*d*c^2)+-1*(b^2+-4*a*c)^-1//2*(b^4*(-1*j*a^2+3*d*c^2)+8*a^2*c^2*(5*j*a^2+21*d*c^2+3*a*c*h)+a*f*b^3*c^2+-52*b*f*a^2*c^3+-6*a*c*b^2*(-3*j*a^2+5*d*c^2+-3*a*c*h))+20*f*a^2*c^3+a*f*b^2*c^2+-4*a*b*c*(4*j*a^2+6*d*c^2+3*a*c*h))*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//16*2^(1/2)*a^-2*c^-3//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*(b^3*(j*a^2+3*d*c^2)+(b^2+-4*a*c)^-1//2*(b^4*(-1*j*a^2+3*d*c^2)+8*a^2*c^2*(5*j*a^2+21*d*c^2+3*a*c*h)+a*f*b^3*c^2+-52*b*f*a^2*c^3+-6*a*c*b^2*(-3*j*a^2+5*d*c^2+-3*a*c*h))+20*f*a^2*c^3+a*f*b^2*c^2+-4*a*b*c*(4*j*a^2+6*d*c^2+3*a*c*h))*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^3*(a*d+x^2*(a*f+b*d)+x^4*(b*f+c*d)+a*e*x+b*e*x^3+c*e*x^5+c*f*x^6), x) == :(x^9*(1//9*d*b^4+2//3*d*a^2*c^2+4//9*a*f*b^3+4//3*a*c*d*b^2+4//3*b*c*f*a^2)+x^11*(1//11*f*b^4+4//11*c*d*b^3+6//11*f*a^2*c^2+12//11*a*b*d*c^2+12//11*a*c*f*b^2)+d*x*a^4+e*x^10*(1//10*b^4+3//5*a^2*c^2+6//5*a*c*b^2)+(1/2)*e*a^4*x^2+1//3*a^3*x^3*(a*f+4*b*d)+1//17*c^3*x^17*(c*d+4*b*f)+1//18*e*c^4*x^18+1//19*f*c^4*x^19+2//5*a^2*x^5*(3*d*b^2+2*a*b*f+2*a*c*d)+2//7*a*x^7*(2*d*b^3+2*c*f*a^2+3*a*f*b^2+6*a*b*c*d)+2//13*c*x^13*(2*f*b^3+2*a*d*c^2+3*c*d*b^2+6*a*b*c*f)+2//15*c^2*x^15*(3*f*b^2+2*a*c*f+2*b*c*d)+b*e*a^3*x^4+1//3*e*a^2*x^6*(3*b^2+2*a*c)+1//4*b*e*c^3*x^16+1//7*e*c^2*x^14*(3*b^2+2*a*c)+(1/2)*a*b*e*x^8*(b^2+3*a*c)+1//3*b*c*e*x^12*(b^2+3*a*c))
@test integrate((a+b*x^2+c*x^4)^2*(a*d+x^2*(a*f+b*d)+x^4*(b*f+c*d)+a*e*x+b*e*x^3+c*e*x^5+c*f*x^6), x) == :(x^7*(1//7*d*b^3+3//7*a*f*b^2+3//7*c*f*a^2+6//7*a*b*c*d)+x^9*(1//9*f*b^3+1//3*a*d*c^2+1//3*c*d*b^2+2//3*a*b*c*f)+d*x*a^3+(1/2)*e*a^3*x^2+1//3*a^2*x^3*(a*f+3*b*d)+1//13*c^2*x^13*(c*d+3*b*f)+1//14*e*c^3*x^14+1//15*f*c^3*x^15+3//5*a*x^5*(d*b^2+a*b*f+a*c*d)+3//11*c*x^11*(f*b^2+a*c*f+b*c*d)+(1/2)*a*e*x^6*(b^2+a*c)+1//4*b*e*c^2*x^12+1//8*b*e*x^8*(b^2+6*a*c)+3//4*b*e*a^2*x^4+3//10*c*e*x^10*(b^2+a*c))
@test integrate((a+b*x^2+c*x^4)*(a*d+x^2*(a*f+b*d)+x^4*(b*f+c*d)+a*e*x+b*e*x^3+c*e*x^5+c*f*x^6), x) == :(x^5*(1//5*d*b^2+2//5*a*b*f+2//5*a*c*d)+x^7*(1//7*f*b^2+2//7*a*c*f+2//7*b*c*d)+d*x*a^2+e*x^6*(1//6*b^2+1//3*a*c)+(1/2)*e*a^2*x^2+1//3*a*x^3*(a*f+2*b*d)+1//9*c*x^9*(c*d+2*b*f)+1//10*e*c^2*x^10+1//11*f*c^2*x^11+(1/2)*a*b*e*x^4+1//4*b*c*e*x^8)
@test integrate((a+b*x^2+c*x^4)^-1*(a*d+x^2*(a*f+b*d)+x^4*(b*f+c*d)+a*e*x+b*e*x^3+c*e*x^5+c*f*x^6), x) == :(d*x+(1/2)*e*x^2+1//3*f*x^3)
@test integrate((a+b*x^2+c*x^4)^-2*(a*d+x^2*(a*f+b*d)+x^4*(b*f+c*d)+a*e*x+b*e*x^3+c*e*x^5+c*f*x^6), x) == :(-1*e*(b^2+-4*a*c)^-1//2*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+(1/2)*2^(1/2)*c^-1//2*(b+(b^2+-4*a*c)^(1/2))^-1//2*(f+-1*(b^2+-4*a*c)^-1//2*(-1*b*f+2*c*d))*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+(1/2)*2^(1/2)*c^-1//2*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(f+(b^2+-4*a*c)^-1//2*(-1*b*f+2*c*d))*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-3*(a*d+x^2*(a*f+b*d)+x^4*(b*f+c*d)+a*e*x+b*e*x^3+c*e*x^5+c*f*x^6), x) == :(-1*e*(2*b^2+-8*a*c)^-1*(a+b*x^2+c*x^4)^-1*(b+2*c*x^2)+2*c*e*(b^2+-4*a*c)^-3//2*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+(1/2)*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1*(d*b^2+c*x^2*(b*d+-2*a*f)+-1*a*b*f+-2*a*c*d)+1//4*2^(1/2)*a^-1*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(b*d+-1*(b^2+-4*a*c)^-1//2*(d*b^2+-12*a*c*d+4*a*b*f)+-2*a*f)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//4*2^(1/2)*a^-1*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-1*(b*d+(b^2+-4*a*c)^-1//2*(d*b^2+-12*a*c*d+4*a*b*f)+-2*a*f)*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((a+b*x^2+c*x^4)^-4*(a*d+x^2*(a*f+b*d)+x^4*(b*f+c*d)+a*e*x+b*e*x^3+c*e*x^5+c*f*x^6), x) == :(-1*e*(4*b^2+-16*a*c)^-1*(a+b*x^2+c*x^4)^-2*(b+2*c*x^2)+-6*e*c^2*(b^2+-4*a*c)^-5//2*arctanh((b^2+-4*a*c)^-1//2*(b+2*c*x^2))+1//4*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-2*(d*b^2+c*x^2*(b*d+-2*a*f)+-1*a*b*f+-2*a*c*d)+1//8*x*a^-2*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(3*d*b^4+a*f*b^3+c*x^2*(3*d*b^3+a*f*b^2+20*c*f*a^2+-24*a*b*c*d)+28*d*a^2*c^2+-25*a*c*d*b^2+8*b*c*f*a^2)+3//2*c*e*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1*(b+2*c*x^2)+1//16*2^(1/2)*a^-2*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-2*(-1*(b^2+-4*a*c)^-1//2*(3*d*b^4+a*f*b^3+168*d*a^2*c^2+-52*b*c*f*a^2+-30*a*c*d*b^2)+3*d*b^3+a*f*b^2+20*c*f*a^2+-24*a*b*c*d)*arctan(x*2^(1/2)*c^(1/2)*(b+(b^2+-4*a*c)^(1/2))^-1//2)+1//16*2^(1/2)*a^-2*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2*(b^2+-4*a*c)^-5//2*(b^3*(a*f+3*d*(b^2+-4*a*c)^(1/2))+3*d*b^4+-1*a*b^2*(-1*f*(b^2+-4*a*c)^(1/2)+30*c*d)+4*c*a^2*(5*f*(b^2+-4*a*c)^(1/2)+42*c*d)+-4*a*b*c*(6*d*(b^2+-4*a*c)^(1/2)+13*a*f))*arctan(x*2^(1/2)*c^(1/2)*(b+-1*(b^2+-4*a*c)^(1/2))^-1//2))
@test integrate((4+x^4+-5*x^2)^-1*(2+x^3+-1x+-2*x^2), x) == :(log(2+x))
@test integrate((4+x^4+-5*x^2)^-1*(d+e*x)*(2+x^3+-1x+-2*x^2), x) == :(e*x+(d+-2*e)*log(2+x))
@test integrate((4+x^4+-5*x^2)^-1*(d+e*x+f*x^2)*(2+x^3+-1x+-2*x^2), x) == :(x*(e+-4*f)+(d+-2*e+4*f)*log(2+x)+(1/2)*f*(2+x)^2)
@test integrate((4+x^4+-5*x^2)^-1*(2+x^3+-1x+-2*x^2)*(d+e*x+f*x^2+g*x^3), x) == :(x*(e+-4*f+12g)+(2+x)^2*((1/2)*f+-3g)+(d+-8g+-2*e+4*f)*log(2+x)+1//3*g*(2+x)^3)
@test integrate((4+x^4+-5*x^2)^-1*(2+x^3+-1x+-2*x^2)*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :(x*(e+-8h+-2*f+4g)+x^2*((1/2)*f+-1g+2h)+x^3*(-2//3*h+1//3*g)+(d+-8g+-2*e+4*f+16h)*log(2+x)+1//4*h*x^4)
@test integrate((4+x^4+-5*x^2)^-1*(2+x^3+-1x+-2*x^2)*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :(x*(e+-8h+-2*f+4g+16i)+x^2*((1/2)*f+-1g+-4i+2h)+x^3*(-2//3*h+1//3*g+4//3*i)+x^4*(-1//2*i+1//4*h)+(d+-32i+-8g+-2*e+4*f+16h)*log(2+x)+1//5*i*x^5)
@test integrate((4+x^4+-5*x^2)^-1*(2+x^2+-3x), x) == :(-1*log(2+x)+log(1+x))
@test integrate((4+x^4+-5*x^2)^-1*(d+e*x)*(2+x^2+-3x), x) == :((d+-1*e)*log(1+x)+-1*(d+-2*e)*log(2+x))
@test integrate((4+x^4+-5*x^2)^-1*(2+x^2+-3x)*(d+e*x+f*x^2), x) == :(f*x+(d+f+-1*e)*log(1+x)+-1*(d+-2*e+4*f)*log(2+x))
@test integrate((4+x^4+-5*x^2)^-1*(2+x^2+-3x)*(d+e*x+f*x^2+g*x^3), x) == :(x*(f+-3g)+(d+f+-1*e+-1g)*log(1+x)+(1/2)*g*x^2+-1*(d+-8g+-2*e+4*f)*log(2+x))
@test integrate((4+x^4+-5*x^2)^-1*(2+x^2+-3x)*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :(x*(f+-3g+7h)+x^2*((1/2)*g+-3//2*h)+(d+f+h+-1*e+-1g)*log(1+x)+-1*(d+-8g+-2*e+4*f+16h)*log(2+x)+1//3*h*x^3)
@test integrate((4+x^4+-5*x^2)^-1*(2+x^2+-3x)*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :(x*(f+-15i+-3g+7h)+x^2*((1/2)*g+-3//2*h+7//2*i)+x^3*(-1i+1//3*h)+(d+f+h+-1*e+-1g+-1i)*log(1+x)+-1*(d+-32i+-8g+-2*e+4*f+16h)*log(2+x)+1//4*i*x^4)
@test integrate((4+x^4+-5*x^2)^-1*(2+x), x) == :(-1//2*log(1+-1x)+1//3*log(2+-1x)+1//6*log(1+x))
@test integrate((4+x^4+-5*x^2)^-1*(2+x)*(d+e*x), x) == :((-1//2*d+-1//2*e)*log(1+-1x)+(-1//6*e+1//6*d)*log(1+x)+(1//3*d+2//3*e)*log(2+-1x))
@test integrate((4+x^4+-5*x^2)^-1*(2+x)*(d+e*x+f*x^2), x) == :((-1//2*d+-1//2*e+-1//2*f)*log(1+-1x)+(-1//6*e+1//6*d+1//6*f)*log(1+x)+(1//3*d+2//3*e+4//3*f)*log(2+-1x))
@test integrate((4+x^4+-5*x^2)^-1*(2+x)*(d+e*x+f*x^2+g*x^3), x) == :(g*x+(-1//6*e+-1//6*g+1//6*d+1//6*f)*log(1+x)+(1//3*d+2//3*e+4//3*f+8//3*g)*log(2+-1x)+-1*((1/2)*d+(1/2)*e+(1/2)*f+(1/2)*g)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-1*(2+x)*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :(x*(g+2h)+(-1//6*e+-1//6*g+1//6*d+1//6*f+1//6*h)*log(1+x)+(1//3*d+2//3*e+4//3*f+8//3*g+16//3*h)*log(2+-1x)+(1/2)*h*x^2+-1*((1/2)*d+(1/2)*e+(1/2)*f+(1/2)*g+(1/2)*h)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-1*(2+x)*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :(x*(g+2h+5i)+x^2*(i+(1/2)*h)+(-1//6*e+-1//6*g+-1//6*i+1//6*d+1//6*f+1//6*h)*log(1+x)+(1//3*d+2//3*e+4//3*f+8//3*g+16//3*h+32//3*i)*log(2+-1x)+-1*((1/2)*d+(1/2)*e+(1/2)*f+(1/2)*g+(1/2)*h+(1/2)*i)*log(1+-1x)+1//3*i*x^3)
@test integrate((4+x^4+-5*x^2)^-2*(2+x^3+-1x+-2*x^2), x) == :((24+12x)^-1+-19//144*log(2+x)+-1//18*log(1+-1x)+1//6*log(1+x)+1//48*log(2+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(d+e*x)*(2+x^3+-1x+-2*x^2), x) == :((24+12x)^-1*(d+-2*e)+(-1//6*e+1//6*d)*log(1+x)+(1//24*e+1//48*d)*log(2+-1x)+-1*(-13//72*e+19//144*d)*log(2+x)+-1*(1//18*d+1//18*e)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(d+e*x+f*x^2)*(2+x^3+-1x+-2*x^2), x) == :((24+12x)^-1*(d+-2*e+4*f)+(-1//6*e+1//6*d+1//6*f)*log(1+x)+(1//12*f+1//24*e+1//48*d)*log(2+-1x)+-1*(-13//72*e+7//36*f+19//144*d)*log(2+x)+-1*(1//18*d+1//18*e+1//18*f)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x^3+-1x+-2*x^2)*(d+e*x+f*x^2+g*x^3), x) == :((24+12x)^-1*(d+-8g+-2*e+4*f)+(-1//6*e+-1//6*g+1//6*d+1//6*f)*log(1+x)+(1//6*g+1//12*f+1//24*e+1//48*d)*log(2+-1x)+-1*(-13//72*e+-1//18*g+7//36*f+19//144*d)*log(2+x)+-1*(1//18*d+1//18*e+1//18*f+1//18*g)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x^3+-1x+-2*x^2)*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :((24+12x)^-1*(d+-8g+-2*e+4*f+16h)+(-1//6*e+-1//6*g+1//6*d+1//6*f+1//6*h)*log(1+x)+(1//3*h+1//6*g+1//12*f+1//24*e+1//48*d)*log(2+-1x)+-1*(-13//72*e+-5//9*h+-1//18*g+7//36*f+19//144*d)*log(2+x)+-1*(1//18*d+1//18*e+1//18*f+1//18*g+1//18*h)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x^3+-1x+-2*x^2)*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :(i*x+(24+12x)^-1*(d+-32i+-8g+-2*e+4*f+16h)+(-1//6*e+-1//6*g+-1//6*i+1//6*d+1//6*f+1//6*h)*log(1+x)+(1//3*h+1//6*g+1//12*f+1//24*e+1//48*d+2//3*i)*log(2+-1x)+-1*(-13//72*e+-5//9*h+-1//18*g+7//36*f+19//144*d+22//9*i)*log(2+x)+-1*(1//18*d+1//18*e+1//18*f+1//18*g+1//18*h+1//18*i)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x^2+-3x), x) == :(-7//36*log(1+x)+-1//36*log(1+-1x)+1//144*log(2+-1x)+31//144*log(2+x)+-1*(24+12*x^2+36x)^-1*(5+3x))
@test integrate((4+x^4+-5*x^2)^-2*(d+e*x)*(2+x^2+-3x), x) == :((-25//72*e+31//144*d)*log(2+x)+(1//72*e+1//144*d)*log(2+-1x)+-1*(24+12*x^2+36x)^-1*(-6*e+5d+x*(-4*e+3d))+-1*(-13//36*e+7//36*d)*log(1+x)+-1*(1//36*d+1//36*e)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x^2+-3x)*(d+e*x+f*x^2), x) == :((-25//72*e+19//36*f+31//144*d)*log(2+x)+(1//36*f+1//72*e+1//144*d)*log(2+-1x)+-1*(24+12*x^2+36x)^-1*(-6*e+5d+8*f+x*(-4*e+3d+6*f))+-1*(-13//36*e+7//36*d+19//36*f)*log(1+x)+-1*(1//36*d+1//36*e+1//36*f)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x^2+-3x)*(d+e*x+f*x^2+g*x^3), x) == :((-25//72*e+-13//18*g+19//36*f+31//144*d)*log(2+x)+(1//18*g+1//36*f+1//72*e+1//144*d)*log(2+-1x)+-1*(6+6x)^-1*(d+f+-1*e+-1g)+-1*(24+12x)^-1*(d+-8g+-2*e+4*f)+-1*(-25//36*g+-13//36*e+7//36*d+19//36*f)*log(1+x)+-1*(1//36*d+1//36*e+1//36*f+1//36*g)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x^2+-3x)*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :((-25//72*e+-13//18*g+7//9*h+19//36*f+31//144*d)*log(2+x)+(1//9*h+1//18*g+1//36*f+1//72*e+1//144*d)*log(2+-1x)+-1*(6+6x)^-1*(d+f+h+-1*e+-1g)+-1*(24+12x)^-1*(d+-8g+-2*e+4*f+16h)+-1*(-25//36*g+-13//36*e+7//36*d+19//36*f+31//36*h)*log(1+x)+-1*(1//36*d+1//36*e+1//36*f+1//36*g+1//36*h)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x^2+-3x)*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :((-25//72*e+-13//18*g+-2//9*i+7//9*h+19//36*f+31//144*d)*log(2+x)+(1//9*h+1//18*g+1//36*f+1//72*e+1//144*d+2//9*i)*log(2+-1x)+-1*(6+6x)^-1*(d+f+h+-1*e+-1g+-1i)+-1*(24+12x)^-1*(d+-32i+-8g+-2*e+4*f+16h)+-1*(-37//36*i+-25//36*g+-13//36*e+7//36*d+19//36*f+31//36*h)*log(1+x)+-1*(1//36*d+1//36*e+1//36*f+1//36*g+1//36*h+1//36*i)*log(1+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x), x) == :((12+-12x)^-1+(72+-36x)^-1+-1*(36+36x)^-1+-35//432*log(2+-1x)+1//18*log(1+-1x)+1//54*log(1+x)+1//144*log(2+x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x)*(d+e*x), x) == :((12+-12x)^-1*(d+e)+(72+-36x)^-1*(d+2*e)+(-1//72*e+1//144*d)*log(2+x)+(1//18*d+5//36*e)*log(1+-1x)+(1//54*d+1//108*e)*log(1+x)+-1*(36+36x)^-1*(d+-1*e)+-1*(29//216*e+35//432*d)*log(2+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x)*(d+e*x+f*x^2), x) == :((12+-12x)^-1*(d+e+f)+(72+-36x)^-1*(d+2*e+4*f)+(-1//27*f+1//54*d+1//108*e)*log(1+x)+(-1//72*e+1//36*f+1//144*d)*log(2+x)+(1//18*d+2//9*f+5//36*e)*log(1+-1x)+-1*(36+36x)^-1*(d+f+-1*e)+-1*(23//108*f+29//216*e+35//432*d)*log(2+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x)*(d+e*x+f*x^2+g*x^3), x) == :((12+-12x)^-1*(d+e+f+g)+(72+-36x)^-1*(d+2*e+4*f+8g)+(-1//18*g+-1//72*e+1//36*f+1//144*d)*log(2+x)+(-1//27*f+1//54*d+1//108*e+7//108*g)*log(1+x)+(1//18*d+2//9*f+5//36*e+11//36*g)*log(1+-1x)+-1*(36+36x)^-1*(d+f+-1*e+-1g)+-1*(17//54*g+23//108*f+29//216*e+35//432*d)*log(2+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x)*(d+e*x+f*x^2+g*x^3+h*x^4), x) == :((12+-12x)^-1*(d+e+f+g+h)+(72+-36x)^-1*(d+2*e+4*f+8g+16h)+(-5//54*h+-1//27*f+1//54*d+1//108*e+7//108*g)*log(1+x)+(-1//18*g+-1//72*e+1//9*h+1//36*f+1//144*d)*log(2+x)+(1//18*d+2//9*f+5//36*e+7//18*h+11//36*g)*log(1+-1x)+-1*(36+36x)^-1*(d+f+h+-1*e+-1g)+-1*(11//27*h+17//54*g+23//108*f+29//216*e+35//432*d)*log(2+-1x))
@test integrate((4+x^4+-5*x^2)^-2*(2+x)*(d+e*x+f*x^2+g*x^3+h*x^4+i*x^5), x) == :((12+-12x)^-1*(d+e+f+g+h+i)+(72+-36x)^-1*(d+2*e+4*f+8g+16h+32i)+(-5//54*h+-1//27*f+1//54*d+1//108*e+7//108*g+13//108*i)*log(1+x)+(-2//9*i+-1//18*g+-1//72*e+1//9*h+1//36*f+1//144*d)*log(2+x)+(1//18*d+2//9*f+5//36*e+7//18*h+11//36*g+17//36*i)*log(1+-1x)+-1*(36+36x)^-1*(d+f+h+-1*e+-1g+-1i)+-1*(10//27*i+11//27*h+17//54*g+23//108*f+29//216*e+35//432*d)*log(2+-1x))
@test integrate((a+b*x^2+c*x^4)^3//2*(d+e*x+f*x^2+g*x^3), x) == :(1//10*g*c^-1*(a+b*x^2+c*x^4)^5//2+1//32*c^-2*(a+b*x^2+c*x^4)^3//2*(b+2*c*x^2)*(-1*b*g+2*c*e)+1//63*x*c^-1*(a+b*x^2+c*x^4)^3//2*(3*b*f+9*c*d+7*c*f*x^2)+1//315*x*c^-2*(a+b*x^2+c*x^4)^(1/2)*(-4*f*b^3+3*c*x^2*(-4*f*b^2+9*b*c*d+14*a*c*f)+9*c*d*b^2+90*a*d*c^2+9*a*b*c*f)+3//512*c^-7//2*(b^2+-4*a*c)^2*(-1*b*g+2*c*e)*arctanh((1/2)*c^-1//2*(a+b*x^2+c*x^4)^-1//2*(b+2*c*x^2))+-1//256*c^-3*(a+b*x^2+c*x^4)^(1/2)*(b+2*c*x^2)*(3*b^2+-12*a*c)*(-1*b*g+2*c*e)+-1//315*x*c^-5//2*(a^(1/2)+c^(1/2)*x^2)^-1*(a+b*x^2+c*x^4)^(1/2)*(-8*f*b^4+-84*f*a^2*c^2+18*c*d*b^3+-144*a*b*d*c^2+57*a*c*f*b^2)+-1//630*a^1//4*c^-11//4*((a^(1/2)+c^(1/2)*x^2)^-2*(a+b*x^2+c*x^4))^(1/2)*(a+b*x^2+c*x^4)^-1//2*(a^(1/2)+c^(1/2)*x^2)*(-8*f*b^4+a^(1/2)*c^(1/2)*(-4*f*b^3+-180*a*d*c^2+9*c*d*b^2+24*a*b*c*f)+-84*f*a^2*c^2+18*c*d*b^3+-144*a*b*d*c^2+57*a*c*f*b^2)*Elliptic.F(2*arctan(x*a^-1//4*c^1//4),1/2+-1//4*b*a^-1//2*c^-1//2)+1//315*a^1//4*c^-11//4*((a^(1/2)+c^(1/2)*x^2)^-2*(a+b*x^2+c*x^4))^(1/2)*(a+b*x^2+c*x^4)^-1//2*(a^(1/2)+c^(1/2)*x^2)*(-8*f*b^4+-84*f*a^2*c^2+18*c*d*b^3+-144*a*b*d*c^2+57*a*c*f*b^2)*Elliptic.E(2*arctan(x*a^-1//4*c^1//4),1/2+-1//4*b*a^-1//2*c^-1//2))
@test integrate((a+b*x^2+c*x^4)^(1/2)*(d+e*x+f*x^2+g*x^3), x) == :(1//6*g*c^-1*(a+b*x^2+c*x^4)^3//2+-1//32*c^-5//2*(b^2+-4*a*c)*(-1*b*g+2*c*e)*arctanh((1/2)*c^-1//2*(a+b*x^2+c*x^4)^-1//2*(b+2*c*x^2))+1//15*x*c^-1*(a+b*x^2+c*x^4)^(1/2)*(b*f+5*c*d+3*c*f*x^2)+1//16*c^-2*(a+b*x^2+c*x^4)^(1/2)*(b+2*c*x^2)*(-1*b*g+2*c*e)+1//15*x*c^-3//2*(a^(1/2)+c^(1/2)*x^2)^-1*(a+b*x^2+c*x^4)^(1/2)*(-2*f*b^2+5*b*c*d+6*a*c*f)+-1//15*a^1//4*c^-7//4*((a^(1/2)+c^(1/2)*x^2)^-2*(a+b*x^2+c*x^4))^(1/2)*(a+b*x^2+c*x^4)^-1//2*(a^(1/2)+c^(1/2)*x^2)*(-2*f*b^2+5*b*c*d+6*a*c*f)*Elliptic.E(2*arctan(x*a^-1//4*c^1//4),1/2+-1//4*b*a^-1//2*c^-1//2)+1//30*a^1//4*c^-7//4*((a^(1/2)+c^(1/2)*x^2)^-2*(a+b*x^2+c*x^4))^(1/2)*(a+b*x^2+c*x^4)^-1//2*(b+2*a^(1/2)*c^(1/2))*(a^(1/2)+c^(1/2)*x^2)*(-2*b*f+5*c*d+3*f*a^(1/2)*c^(1/2))*Elliptic.F(2*arctan(x*a^-1//4*c^1//4),1/2+-1//4*b*a^-1//2*c^-1//2))
@test integrate((a+b*x^2+c*x^4)^-1//2*(d+e*x+f*x^2+g*x^3), x) == :((1/2)*g*c^-1*(a+b*x^2+c*x^4)^(1/2)+1//4*c^-3//2*(-1*b*g+2*c*e)*arctanh((1/2)*c^-1//2*(a+b*x^2+c*x^4)^-1//2*(b+2*c*x^2))+f*x*c^-1//2*(a^(1/2)+c^(1/2)*x^2)^-1*(a+b*x^2+c*x^4)^(1/2)+(1/2)*a^1//4*c^-3//4*((a^(1/2)+c^(1/2)*x^2)^-2*(a+b*x^2+c*x^4))^(1/2)*(a+b*x^2+c*x^4)^-1//2*(f+d*a^-1//2*c^(1/2))*(a^(1/2)+c^(1/2)*x^2)*Elliptic.F(2*arctan(x*a^-1//4*c^1//4),1/2+-1//4*b*a^-1//2*c^-1//2)+-1*f*a^1//4*c^-3//4*((a^(1/2)+c^(1/2)*x^2)^-2*(a+b*x^2+c*x^4))^(1/2)*(a+b*x^2+c*x^4)^-1//2*(a^(1/2)+c^(1/2)*x^2)*Elliptic.E(2*arctan(x*a^-1//4*c^1//4),1/2+-1//4*b*a^-1//2*c^-1//2))
@test integrate((a+b*x^2+c*x^4)^-3//2*(d+e*x+f*x^2+g*x^3), x) == :(-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1//2*(b*e+x^2*(-1*b*g+2*c*e)+-2*a*g)+x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1//2*(d*b^2+c*x^2*(b*d+-2*a*f)+-1*a*b*f+-2*a*c*d)+-1*x*a^-1*c^(1/2)*(a^(1/2)+c^(1/2)*x^2)^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^(1/2)*(b*d+-2*a*f)+a^-3//4*c^1//4*((a^(1/2)+c^(1/2)*x^2)^-2*(a+b*x^2+c*x^4))^(1/2)*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1//2*(a^(1/2)+c^(1/2)*x^2)*(b*d+-2*a*f)*Elliptic.E(2*arctan(x*a^-1//4*c^1//4),1/2+-1//4*b*a^-1//2*c^-1//2)+-1//2*a^-3//4*c^-1//4*((a^(1/2)+c^(1/2)*x^2)^-2*(a+b*x^2+c*x^4))^(1/2)*(b+-2*a^(1/2)*c^(1/2))^-1*(a+b*x^2+c*x^4)^-1//2*(a^(1/2)+c^(1/2)*x^2)*(d*c^(1/2)+-1*f*a^(1/2))*Elliptic.F(2*arctan(x*a^-1//4*c^1//4),1/2+-1//4*b*a^-1//2*c^-1//2))
@test integrate((a+b*x^2+c*x^4)^-5//2*(d+e*x+f*x^2+g*x^3), x) == :(-1*(3*b^2+-12*a*c)^-1*(a+b*x^2+c*x^4)^-3//2*(b*e+x^2*(-1*b*g+2*c*e)+-2*a*g)+1//3*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1//2*(b+2*c*x^2)*(-4*b*g+8*c*e)+1//3*x*a^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-3//2*(d*b^2+c*x^2*(b*d+-2*a*f)+-1*a*b*f+-2*a*c*d)+1//3*x*a^-2*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1//2*(2*d*b^4+a*f*b^3+c*x^2*(2*d*b^3+a*f*b^2+12*c*f*a^2+-16*a*b*c*d)+20*d*a^2*c^2+-17*a*c*d*b^2+4*b*c*f*a^2)+-1//3*x*a^-2*c^(1/2)*(a^(1/2)+c^(1/2)*x^2)^-1*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^(1/2)*(2*d*b^3+a*f*b^2+12*c*f*a^2+-16*a*b*c*d)+1//3*a^-7//4*c^1//4*((a^(1/2)+c^(1/2)*x^2)^-2*(a+b*x^2+c*x^4))^(1/2)*(b^2+-4*a*c)^-2*(a+b*x^2+c*x^4)^-1//2*(a^(1/2)+c^(1/2)*x^2)*(2*d*b^3+a*f*b^2+12*c*f*a^2+-16*a*b*c*d)*Elliptic.E(2*arctan(x*a^-1//4*c^1//4),1/2+-1//4*b*a^-1//2*c^-1//2)+-1//6*a^-7//4*c^1//4*((a^(1/2)+c^(1/2)*x^2)^-2*(a+b*x^2+c*x^4))^(1/2)*(b+-2*a^(1/2)*c^(1/2))^-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1//2*(a^(1/2)+c^(1/2)*x^2)*(2*d*b^2+a*b*f+-10*a*c*d+6*f*a^3//2*c^(1/2)+-3*b*d*a^(1/2)*c^(1/2))*Elliptic.F(2*arctan(x*a^-1//4*c^1//4),1/2+-1//4*b*a^-1//2*c^-1//2))
@test integrate((a+b*x^2+c*x^4)^-3//2*(a*g+-1*c*g*x^4), x) == :(g*x*(a+b*x^2+c*x^4)^-1//2)
@test integrate((a+b*x^2+c*x^4)^-3//2*(a*g+e*x+-1*c*g*x^4), x) == :(g*x*(a+b*x^2+c*x^4)^-1//2+-1*e*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1//2*(b+2*c*x^2))
@test integrate((a+b*x^2+c*x^4)^-3//2*(a*g+f*x^3+-1*c*g*x^4), x) == :(g*x*(a+b*x^2+c*x^4)^-1//2+f*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1//2*(2a+b*x^2))
@test integrate((a+b*x^2+c*x^4)^-3//2*(a*g+e*x+f*x^3+-1*c*g*x^4), x) == :(g*x*(a+b*x^2+c*x^4)^-1//2+-1*(b^2+-4*a*c)^-1*(a+b*x^2+c*x^4)^-1//2*(b*e+x^2*(-1*b*f+2*c*e)+-2*a*f))

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


text:
@testset "BSpline" begin
    include("constant.jl")
    include("linear.jl")
    include("quadratic.jl")
    include("cubic.jl")
    include("mixed.jl")
    include("multivalued.jl")
    include("non1.jl")
    include("regularization.jl")

    @test eltype(@inferred(interpolate(rand(Float16, 3, 3), BSpline(Linear())))) == Float16 # issue #308
end

ext: jl


text:
function positionLoops!(df; yOffset=0.2)
    loops = @view df[df.element .== "loop", :]
    loopNums = unique(loops.structMap)

    for i in loopNums
        loop = @view loops[loops.structMap .== i, :]
        startRes = loop[1,:resNum]
        n = size(loop, 1)
        prevX = median(df[df.structMap .== df[startRes-1, :structMap][1], :x])
        nxtX = median(df[df.structMap .== df[loop[end,:resNum]+1, :structMap][1], :x])

        ## Check if cytoplasmic or extracellular loop
        if df[startRes-1, :y][1] >= 0.5
            side = 1
            prevY = 1
        else
            side = -1
            prevY = 0
        end

        ## Just a line if it is small
        if n <= 5
            dX = (nxtX - prevX)/(n-1)
            for i in 1:size(loop, 1)
                loop[i, :x] = prevX + dX[1] * (i-1)
                loop[i, :y] = prevY + side * yOffset
            end

        ## Square parabola if it is fairly small
        elseif n > 5 && n <= 20
            ## Check if the loop has an odd or even length
            if n%2 != 0
                nBot = 5
            else
                nBot = 4
            end

            ## Divide loop among structure
            leg = div(n - nBot, 2)
            lft = 1:leg
            bot = leg+1:leg+1+nBot
            rgt = n-(leg-1):n

            ## Assign positions
            dY = 0.1
            dX = (nxtX-prevX)/(nBot-1)
            for i in lft
                loop[i, :x] = prevX
                loop[i, :y] = prevY + side*(yOffset + (i-1) * dY)
            end
            for i in bot
                loop[i, :x] = prevX + dX * (i-bot[1])
                loop[i, :y] = prevY + side*(yOffset + (bot[1]-1) * dY)
            end
            loop[rgt, :y] = reverse(loop[lft, :y])
            loop[rgt, :x] .= nxtX
        elseif n > 20 && n <= 120
            loopLayout!(loop, 4, n, prevX, nxtX, prevY, side)
        elseif n > 120 && n <= 240
            loopLayout!(loop, 6, n, prevX, nxtX, prevY, side)
        elseif n>240 && n<=480
            loopLayout!(loop, 14, n, prevX, nxtX, prevY, side, expand=10)
        else
            loopLayout!(loop, 20, n, prevX, nxtX, prevY, side, expand=10)
        end
    end

    nt = @view df[df.element .== "nterm", :]
    nnt = size(nt, 1)
    prevXnt = 0.5
    nxtXnt = 1.5

    ## Check if cytoplasmic or extracellular loop
    if df[nt[end, :resNum]+1,:y] >= 0.5
        side = 1
        prevYnt = 1
    else
        side = -1
        prevYnt = 0
    end

    ## Just a line if it is small
    if nnt <= 5
        dX = (nxtXnt - prevXnt)/(nnt-1)
        for i in 1:size(nt, 1)
            nt[i, :x] = prevXnt + dX[1] * (i-1)
            nt[i, :y] = prevYnt + side * yOffset
        end

    ## Square parabola if it is fairly small
    elseif nnt > 5 && nnt <= 20
        ## Check if the loop has an odd or even length
        if nnt%2 != 0
            nBot = 5
        else
            nBot = 4
        end

        ## Divide loop among structure
        leg = div(nnt - nBot, 2)
        lft = 1:leg
        bot = leg+1:leg+1+nBot
        rgt = nnt-(leg-1):nnt

        ## Assign positions
        dY = 0.1
        dX = (nxtXnt-prevXnt)/(nBot-1)
        for i in lft
            nt[i, :x] = prevXnt
            nt[i, :y] = prevYnt + side*(yOffset + (i-1) * dY)
        end
        for i in bot
            nt[i, :x] = prevXnt + dX * (i-bot[1])
            nt[i, :y] = prevYnt + side*(yOffset + (bot[1]-1) * dY)
        end
        nt[rgt, :y] = reverse(nt[lft, :y])
        nt[rgt, :x] .= nxtXnt
    elseif nnt > 20 && nnt <= 120
        loopLayout!(nt, 4, nnt, prevXnt, nxtXnt, prevYnt, side)
    elseif nnt > 120 && nnt <= 240
        loopLayout!(nt, 6, nnt, prevXnt, nxtXnt, prevYnt, side)
    elseif nnt>240 && nnt<=480
        loopLayout!(nt, 14, nnt, prevXntnt, nxtXnt, prevYnt, side, expand=10)
    else
        loopLayout!(nt, 20, nnt, prevXnt, nxtXnt, prevYnt, side, expand=10)
    end

    ct = @view df[df.element .== "cterm", :]
    nct = size(ct, 1)
    prevXct = median(df[df.structMap .== maximum(df.structMap)-0.5, :x])
    nxtXct = median(df[df.structMap .== maximum(df.structMap)-0.5, :x]) + 2

    ## Check if cytoplasmic or extracellular loop
    if df[ct[1, :resNum]-1,:y] >= 0.5
        side = 1
        prevYct = 1
    else
        side = -1
        prevYct = 0
    end

    ## Just a line if it is small
    if nct <= 5
        dX = (nxtXct - prevXct)/(nct-1)
        for i in 1:size(nt, 1)
            ct[i, :x] = prevXct + dX[1] * (i-1)
            ct[i, :y] = prevYct + side * yOffset
        end

    ## Square parabola if it is fairly small
    elseif nct > 5 && nct <= 20
        ## Check if the loop has an odd or even length
        if nct%2 != 0
            nBot = 5
        else
            nBot = 4
        end

        ## Divide loop among structure
        leg = div(nct - nBot, 2)
        lft = 1:leg
        bot = leg+1:leg+1+nBot
        rgt = nct-(leg-1):nct

        ## Assign positions
        dY = 0.1
        dX = (nxtXct-prevXct)/(nBot-1)
        for i in lft
            ct[i, :x] = prevXct
            ct[i, :y] = prevYct + side*(yOffset + (i-1) * dY)
        end
        for i in bot
            ct[i, :x] = prevXct + dX * (i-bot[1])
            ct[i, :y] = prevYct + side*(yOffset + (bot[1]-1) * dY)
        end
        ct[rgt, :y] = reverse(ct[lft, :y])
        ct[rgt, :x] .= nxtXct
    elseif nct > 20 && nct <= 120
        loopLayout!(ct, 4, nct, prevXct, nxtXct, prevYct, side)
    elseif nct > 120 && nct <= 240
        loopLayout!(ct, 6, nct, prevXct, nxtXct, prevYct, side)
    elseif nct>240 && nct<=480
        loopLayout!(ct, 14, nct, prevXntct, nxtXct, prevYct, side, expand=10)
    else
        loopLayout!(ct, 20, nct, prevXct, nxtXct, prevYct, side, expand=10)
    end
end


text:
#= Github Actions uses Intel CPUs, for which MKL is faster than OpenBLAS.
It is recommended to load MKL before any other package, so we load it here. =#
import MKL
import Documenter
import Literate
import RestrictedBoltzmannMachines as RBMs

ENV["JULIA_DEBUG"] = "Documenter,Literate,RestrictedBoltzmannMachines"

#=
We place Literate.jl source .jl files and the generated .md files inside docs/src/literate.
=#
const literate_dir = joinpath(@__DIR__, "src/literate")

#=
Helper function to remove all "*.md" files from a directory.
=#
function clear_md_files(dir::String)
    for (root, dirs, files) in walkdir(dir)
        for file in files
            if endswith(file, ".md")
                rm(joinpath(root, file))
            end
        end
    end
end

#=
Remove previously Literate.jl generated files. This removes all "*.md" files inside
`literate_dir`. This is a precaution: if we build docs locally and something fails,
and then change the name of a source file (".jl"), we will be left with a lingering
".md" file which will be included in the current docs build. The following line makes
sure this doesn't happen.
=#
clear_md_files(literate_dir)

#=
Run Literate.jl on the .jl source files within docs/src/literate (recursively).
For each .jl file, this creates a markdown .md file at the same location as
and with the same name as the corresponding .jl file, but with the extension
changed (.jl -> .md).
=#
for (root, dirs, files) in walkdir(literate_dir)
    for file in files
        if endswith(file, ".jl")
            Literate.markdown(joinpath(root, file), root; documenter=true)
        end
    end
end

#=
Build docs.
=#
Documenter.makedocs(
    modules = [RBMs],
    sitename = "RestrictedBoltzmannMachines.jl",
    pages = [
        "Home" => "index.md",
        "Examples" => [
            "MNIST" => "literate/MNIST.md",
            "Layers" => [
                "Gaussian" => "literate/layers/Gaussian.md",
                "ReLU" => "literate/layers/ReLU.md",
                "dReLU" => "literate/layers/dReLU.md",
            ],
            "Performance" => [
                "MKL" => "literate/performance/mkl.md",
                "Float32 vs. Float64" => "literate/performance/float32.md",
                "Zygote" => "literate/performance/ad.md",
            ],
            "Moment-matching" => "literate/moment_match.md",
            "Learning rate decay" => "literate/lr_decay.md",
            "No centering" => "literate/center.md",
            "AIS" => "literate/ais.md",
            "Metropolis" => "literate/metropolis.md",
        ],
        "Reference" => "reference.md"
    ],
    strict = true
)

#=
After the docs have been compiled, we can remove the *.md files generated by Literate.
=#
clear_md_files(literate_dir)

#=
Deploy docs to Github pages.
=#
Documenter.deploydocs(
    repo = "github.com/cossio/RestrictedBoltzmannMachines.jl.git",
    devbranch = "master"
)


text:
using .Turing: Turing, DynamicPPL, MCMCChains
using Accessors: Accessors

# utilities for working with Turing model parameter names using only the DynamicPPL API

"""
    flattened_varnames_list(model::DynamicPPL.Model) -> Vector{Symbol}

Get a vector of varnames as `Symbol`s with one-to-one correspondence to the
flattened parameter vector.

```julia
julia> @model function demo()
           s ~ Dirac(1)
           x = Matrix{Float64}(undef, 2, 4)
           x[1, 1] ~ Dirac(2)
           x[2, 1] ~ Dirac(3)
           x[3] ~ Dirac(4)
           y ~ Dirac(5)
           x[4] ~ Dirac(6)
           x[:, 3] ~ arraydist([Dirac(7), Dirac(8)])
           x[[2, 1], 4] ~ arraydist([Dirac(9), Dirac(10)])
           return s, x, y
       end
demo (generic function with 2 methods)

julia> flattened_varnames_list(demo())
10-element Vector{Symbol}:
 :s
 Symbol("x[1,1]")
 Symbol("x[2,1]")
 Symbol("x[3]")
 Symbol("x[4]")
 Symbol("x[:,3][1]")
 Symbol("x[:,3][2]")
 Symbol("x[[2, 1],4][1]")
 Symbol("x[[2, 1],4][2]")
 :y
```
"""
function flattened_varnames_list(model::DynamicPPL.Model)
    varnames_ranges = varnames_to_ranges(model)
    nsyms = maximum(maximum, values(varnames_ranges))
    syms = Vector{Symbol}(undef, nsyms)
    for (var_name, range) in varnames_to_ranges(model)
        sym = Symbol(var_name)
        if length(range) == 1
            syms[range[begin]] = sym
            continue
        end
        for i in eachindex(range)
            syms[range[i]] = Symbol("$sym[$i]")
        end
    end
    return syms
end

# code snippet shared by @torfjelde
"""
    varnames_to_ranges(model::DynamicPPL.Model)
    varnames_to_ranges(model::DynamicPPL.VarInfo)
    varnames_to_ranges(model::DynamicPPL.Metadata)

Get `Dict` mapping variable names in model to their ranges in a corresponding parameter vector.

# Examples

```julia
julia> @model function demo()
           s ~ Dirac(1)
           x = Matrix{Float64}(undef, 2, 4)
           x[1, 1] ~ Dirac(2)
           x[2, 1] ~ Dirac(3)
           x[3] ~ Dirac(4)
           y ~ Dirac(5)
           x[4] ~ Dirac(6)
           x[:, 3] ~ arraydist([Dirac(7), Dirac(8)])
           x[[2, 1], 4] ~ arraydist([Dirac(9), Dirac(10)])
           return s, x, y
       end
demo (generic function with 2 methods)

julia> demo()()
(1, Any[2.0 4.0 7 10; 3.0 6.0 8 9], 5)

julia> varnames_to_ranges(demo())
Dict{AbstractPPL.VarName, UnitRange{Int64}} with 8 entries:
  s           => 1:1
  x[4]        => 5:5
  x[:,3]      => 6:7
  x[1,1]      => 2:2
  x[2,1]      => 3:3
  x[[2, 1],4] => 8:9
  x[3]        => 4:4
  y           => 10:10
```
"""
function varnames_to_ranges end

varnames_to_ranges(model::DynamicPPL.Model) = varnames_to_ranges(DynamicPPL.VarInfo(model))
function varnames_to_ranges(varinfo::DynamicPPL.UntypedVarInfo)
    return varnames_to_ranges(varinfo.metadata)
end
function varnames_to_ranges(varinfo::DynamicPPL.TypedVarInfo)
    offset = 0
    dicts = map(varinfo.metadata) do md
        vns2ranges = varnames_to_ranges(md)
        vals = collect(values(vns2ranges))
        vals_offset = map(r -> offset .+ r, vals)
        offset += reduce((curr, r) -> max(curr, r[end]), vals; init=0)
        Dict(zip(keys(vns2ranges), vals_offset))
    end

    return reduce(merge, dicts)
end
function varnames_to_ranges(metadata::DynamicPPL.Metadata)
    idcs = map(Base.Fix1(getindex, metadata.idcs), metadata.vns)
    ranges = metadata.ranges[idcs]
    return Dict(zip(metadata.vns, ranges))
end

function pathfinder(
    model::DynamicPPL.Model;
    rng=Random.GLOBAL_RNG,
    init_scale=2,
    init_sampler=UniformSampler(init_scale),
    init=nothing,
    kwargs...,
)
    var_names = flattened_varnames_list(model)
    prob = Turing.optim_problem(model, Turing.MAP(); constrained=false, init_theta=init)
    init_sampler(rng, prob.prob.u0)
    result = pathfinder(prob.prob; rng, input=model, kwargs...)
    draws = reduce(vcat, transpose.(prob.transform.(eachcol(result.draws))))
    chns = MCMCChains.Chains(draws, var_names; info=(; pathfinder_result=result))
    result_new = Accessors.@set result.draws_transformed = chns
    return result_new
end

function multipathfinder(
    model::DynamicPPL.Model,
    ndraws::Int;
    rng=Random.GLOBAL_RNG,
    init_scale=2,
    init_sampler=UniformSampler(init_scale),
    nruns::Int,
    kwargs...,
)
    var_names = flattened_varnames_list(model)
    fun = Turing.optim_function(model, Turing.MAP(); constrained=false)
    init1 = fun.init()
    init = [init_sampler(rng, init1)]
    for _ in 2:nruns
        push!(init, init_sampler(rng, deepcopy(init1)))
    end
    result = multipathfinder(fun.func, ndraws; rng, input=model, init, kwargs...)
    draws = reduce(vcat, transpose.(fun.transform.(eachcol(result.draws))))
    chns = MCMCChains.Chains(draws, var_names; info=(; pathfinder_result=result))
    result_new = Accessors.@set result.draws_transformed = chns
    return result_new
end


text:
include("sampler_test_utils.jl")

describe("Transform Sampler") do

	describe("construction") do

		subsA = DataGenerators.UniformSampler([2.6, 3.1])
		s = DataGenerators.TransformSampler(subsA, x->2.0*x, x->0.5*x)

		test("numparams and paramranges") do
			@check DataGenerators.numparams(s) == DataGenerators.numparams(subsA)
			@check DataGenerators.paramranges(s) == DataGenerators.paramranges(subsA)
		end

		test("default params") do
			@check DataGenerators.getparams(s) == DataGenerators.getparams(subsA)
		end

		test("set params") do
			DataGenerators.setparams!(s, [-5.11, -3.22])
			@check DataGenerators.getparams(subsA) == [-5.11, -3.22]
			@check DataGenerators.getparams(s) == [-5.11, -3.22]
		end

	end

	describe("sampling") do

		subsA = DataGenerators.UniformSampler([2.6, 3.1])
		s = DataGenerators.TransformSampler(subsA, x->2.0*x, x->0.5*x)

		@repeat test("sampling within transformed range") do
			x, trace = DataGenerators.sample(s, (0,1))
			@check typeof(x) <: Float64
			@check 5.2 <= x <= 6.2
		end

	end

	describe("sampling where support affects outcome") do

		subsA = DataGenerators.AdjustParametersToSupportSampler(DataGenerators.UniformSampler())
		s = DataGenerators.TransformSampler(subsA, x->2.0*x, x->0.5*x)

		@repeat test("sampling within support") do
			x, trace = DataGenerators.sample(s, (110.7,190.4))
			@check typeof(x) <: Float64
			@check 110.7 <= x <= 190.4
		end

	end

	describe("estimate parameters") do

		test("estimates parameters of subsampler") do

			subs1A = DataGenerators.GeometricSampler()
			s1 = DataGenerators.TransformSampler(subs1A, x->x+10.0, x->x-10.0)
			params = [0.7]
			DataGenerators.setparams!(s1, params)

			subs2A = DataGenerators.GeometricSampler()
			s2 = DataGenerators.TransformSampler(subs2A, x->x+10.0, x->x-10.0)
			otherparams = [0.3]
			DataGenerators.setparams!(s2, otherparams)

			traces = map(1:100) do i
				x, trace = DataGenerators.sample(s1, (0, 1))
				trace
			end

			estimateparams!(s2, traces)

			@check isconsistentgeometric(subs2A, params[1:1])

		end

	end

end


text:
using PSCOPF

using Test
using Dates
using DataStructures

@testset verbose=true "test_schedule" begin

    @testset "test_market_empty_schedule" begin
        network = PSCOPF.Networks.Network()
        PSCOPF.Networks.add_new_bus!(network, "bus");
        PSCOPF.Networks.add_new_generator_to_bus!(network, "bus", "lim", PSCOPF.Networks.LIMITABLE, 0., 10., 0., 10., Dates.Second(0), Dates.Second(0))
        PSCOPF.Networks.add_new_generator_to_bus!(network, "bus", "imp", PSCOPF.Networks.PILOTABLE, 0., 10., 0., 10., Dates.Second(0), Dates.Second(0))
        PSCOPF.Networks.add_new_generator_to_bus!(network, "bus", "gen_pmin", PSCOPF.Networks.PILOTABLE, 1., 10., 1000., 10., Dates.Second(0), Dates.Second(0))

        TS = [DateTime("2015-01-01T11:00:00"),
                DateTime("2015-01-01T11:15:00"),
                DateTime("2015-01-01T11:30:00"),
                DateTime("2015-01-01T11:45:00")]
        scenarios = ["S1","S2"]
        ech = DateTime("2015-01-01T07:00:00")
        schedule = PSCOPF.Schedule(PSCOPF.Market(), ech)
        PSCOPF.init!(schedule, network, TS, scenarios)

        @test PSCOPF.is_market(schedule.decider_type)
        @test !PSCOPF.is_tso(schedule.decider_type)
        @test schedule.decision_time == ech
        @test length(schedule.generator_schedules) == 3

        # No commitment defined for generators with pmin=0
        @test isempty(PSCOPF.get_sub_schedule(schedule, "lim").commitment)
        @test length(PSCOPF.get_sub_schedule(schedule, "lim").production) == 4
        for ts in TS
            #"missing" is returned cause the values are not set yet
            @test ismissing(PSCOPF.get_prod_value(schedule, "lim", ts))
            #"missing" is returned even if the generator does not have commitment values
            @test ismissing(PSCOPF.get_commitment_value(schedule, "lim", ts))
        end

        # No commitment defined for generators with pmin=0
        @test isempty(PSCOPF.get_sub_schedule(schedule, "imp").commitment)
        @test length(PSCOPF.get_sub_schedule(schedule, "imp").production) == 4
        for ts in TS
            #"missing" is returned cause the values are not set yet
            @test ismissing(PSCOPF.get_prod_value(schedule, "imp", ts))
            #"missing" is returned even if the generator does not have commitment values
            @test ismissing(PSCOPF.get_commitment_value(schedule, "imp", ts))
        end

        # generator with pmin > 0
        @test length(PSCOPF.get_sub_schedule(schedule, "gen_pmin").commitment) == 4
        @test length(PSCOPF.get_sub_schedule(schedule, "gen_pmin").production) == 4
        for ts in TS
            #"missing" is returned cause the values are not set yet
            @test ismissing(PSCOPF.get_prod_value(schedule, "gen_pmin", ts))
            @test ismissing(PSCOPF.get_commitment_value(schedule, "gen_pmin", ts))
        end

    end

    @testset "test_compute_production_from_schedule" begin
        c_definitive_uncertain_value = PSCOPF.UncertainValue{PSCOPF.GeneratorState}(PSCOPF.OFF,
                                                SortedDict("S1"=>PSCOPF.ON,"S2"=>PSCOPF.ON))
        p_non_firm_uncertain_value = PSCOPF.UncertainValue{Float64}(missing,
                                                SortedDict("S1"=>10.,"S2"=>15.))
        p_definitive_uncertain_value = PSCOPF.UncertainValue{Float64}(10.,
                                                SortedDict("S1"=>10.,"S2"=>10.))
        schedule = PSCOPF.Schedule(PSCOPF.TSO(), Dates.DateTime("2015-01-01T07:00:00"), SortedDict(
                        "gen1" => PSCOPF.GeneratorSchedule("gen1",
                            SortedDict(Dates.DateTime("2015-01-01T11:00:00") => c_definitive_uncertain_value),
                            SortedDict(Dates.DateTime("2015-01-01T11:00:00") => PSCOPF.UncertainValue{Float64}(
                                                                                10., SortedDict("S1"=>10.,"S2"=>10.)))
                            ),
                        "gen2" => PSCOPF.GeneratorSchedule("gen2",
                            SortedDict(Dates.DateTime("2015-01-01T11:00:00") => c_definitive_uncertain_value),
                            SortedDict(Dates.DateTime("2015-01-01T11:00:00") => PSCOPF.UncertainValue{Float64}(
                                                                                missing, SortedDict("S1"=>15.,"S2"=>20.)))
                            )
                        ))

        @test PSCOPF.compute_prod(schedule, Dates.DateTime("2015-01-01T11:00:00"), "S1") ≈ 25.
        @test PSCOPF.compute_prod(schedule, Dates.DateTime("2015-01-01T11:00:00"), "S2") ≈ 30.
    end
end

max_stars_repo_name: klorel/pscopf

max_issues_repo_name: klorel/pscopf

max_forks_repo_name: klorel/pscopf


text:
# We implement Data Profiles for Benchmarking Derivative-Free (i.e. blackbox)
# optimizers as described in the paper:
#
# Jorge J. Moré and Stefan M. Wild (2008), "Benchmarking Derivative-Free
# Optimization Algorithms", Preprint ANL/MCS-P1471-1207, April 2008.
#

# Benchmark a set of optimizers on a set of problems.
# Returns: The data profiles for each of the optimizers on the problems. Each
# data profile uses three performance measures: time, function evaluations and
# iterations (since we always use an optimizer in iterations with one call to
# ask(opt) and one call to tell(opt) for each iteration).
# Both of the first two are relevant and all three can be easily collected
# during optimization. The number of iterations is not so critical to evaluate
# the overall performance of an optimizer, it is more of an internal measure.
# Still it gives an indication of how well an optimizer can be "stepped" and thus
# how flexibly we can use it in more elaborate/complex optimization schemes.
function benchmark(optimizers, problems)

  # We will collect a dict of dicts that map a problem to an opt to the performance
  # trace for that opt on that problem.
  profiles = Dict(Any, Any)

  # For each problem, run all the optimizers while collecting a quality profile.
  # Shuffle the order of the problems just in case they have some dependence.
  for(p in shuffle(problems))

    # Create the dict mapping opts to their performance trace on this problem.
    profiles[p] = Dict(Any, Any)

    # Shuffle the order of the optimizers for this problem (in case there is
    # some state/dependence between calls to a problem).
    for(opt in shuffle(optimizers))

    end

  end

end

function performance_ratio()


text:
#! julia
# Converts an atom-language-julia grammar into one compatible with vscode
# Requires:
#  - HTTP.jl to be installed;
#  - `cson2json` to be on your path. (Install via npm.)
import HTTP

url = "https://raw.githubusercontent.com/JuliaEditorSupport/atom-language-julia/master/grammars/julia.cson"

# get cson - download if filename not given
cson = isempty(ARGS) ? String(HTTP.get(url).body) : read(ARGS[1], String)

# convert cson to json
json = Ref(read(open(pipeline(`cson2json`, stdin=IOBuffer(cson))), String))

# apply substitutions
sub!(pr) = json.x = replace(json.x, pr; count=typemax(Int))

sub!(r"(\"include\"\s*:\s*\")source\.gfm(\")" => s"\1text.html.markdown.julia\2")

# Skip over-zealous top-level production in `source.cpp`. See offending pattern here:
# https://github.com/microsoft/vscode/blob/c3fe2d8acde04e579880413ae4622a1f551efdcc/extensions/cpp/syntaxes/cpp.tmLanguage.json#L745
sub!(r"(\"include\"\s*:\s*\"source\.cpp)(\")" => s"\1#root_context\2")

# Choose content names consistent with the vscode conventions for embedded code. Cf.:
# https://code.visualstudio.com/api/language-extensions/syntax-highlight-guide#embedded-languages
sub!(r"(\"contentName\"\s*:\s*\")source\.cpp(\")" => s"\1meta.embedded.inline.cpp\2")
sub!(r"(\"contentName\"\s*:\s*\")source\.gfm(\")" => s"\1meta.embedded.inline.markdown\2")
sub!(r"(\"contentName\"\s*:\s*\")source\.js(\")" => s"\1meta.embedded.inline.javascript\2")
sub!(r"(\"contentName\"\s*:\s*\")source\.r(\")" => s"\1meta.embedded.inline.r\2")
sub!(r"(\"contentName\"\s*:\s*\")source\.python(\")" => s"\1meta.embedded.inline.python\2")

# print out the transformed syntax
println(json.x)

max_stars_repo_name: caleb-allen/julia-vscode

max_issues_repo_name: caleb-allen/julia-vscode

max_forks_repo_name: caleb-allen/julia-vscode


text:
using Distributions, SpecialFunctions, Random
"""
Estimation of the transition matrix for outlier task via a Particle filter
"""
struct TParticleFilterJump <: TPs1a0s0
    nr_states::Int
    nr_actions::Int
    nparticles::Int # Per state and action
    Neffthrs::Float64 # Neff = approx nr of particles that have a weight which
                    # meaningfully contributes to the probability distribution.
    surpriseprobability::Float64
    stochasticity::Float64
    particlesjump::Array{Bool, 3} # wannabe nr_states x nr_actions x nparticles.
    weights::Array{Float64, 3} # wannabe nr_states x nr_actions x nparticles.
    Sgmparticles::Array{Float64, 1} # wannabe nparticles.
    Sgm::Array{Float64, 1}
    m::Float64
    γ_surprise::Array{Float64, 1}
    Ps1a0s0::Array{Dict{Tuple{Int, Int}, Float64}, 1}
    SPE::Array{Float64, 1}
    counts::Array{Array{Float64,1}, 3}
    seed::Any
    rng::MersenneTwister
    terminalstates::Array{Int,1}
end
function TParticleFilterJump(;nr_states = 10, nr_actions = 4, nparticles = 6,
                        surpriseprobability = .01,
                        stochasticity = .01, seed = 3)
    Neffthrs = nparticles/2.
    particlesjump = Array{Bool, 3}(undef, nr_actions, nr_states, nparticles)
    weights = Array{Float64, 3}(undef, nr_actions, nr_states, nparticles)
    Sgmparticles = Array{Float64, 1}(undef, nparticles)
    Ps1a0s0 = [Dict{Tuple{Int, Int}, Float64}() for _ in 1:nr_states]
    [Ps1a0s0[sprime][(a, s)] = 1. /nr_states for sprime in 1:nr_states for a in 1:nr_actions for s in 1:nr_states]
    counts = Array{Array{Float64,1}}(undef, nr_actions, nr_states, nparticles)
    rng = MersenneTwister(seed)
    [weights[a0, s0, i] = 1. /nparticles for a0 in 1:nr_actions for s0 in 1:nr_states for i in 1:nparticles]
    Sgmparticles .= 1.; Sgm = [1.]
    [counts[a0, s0, i] = zeros(nr_states) for a0 in 1:nr_actions for s0 in 1:nr_states for i in 1:nparticles]
    m = surpriseprobability/ (1. - surpriseprobability)
    γ_surprise = [m/(1. + m)]
    SPE = [1. - 1. / nr_states]

    TParticleFilterJump(nr_states, nr_actions, nparticles, Neffthrs, surpriseprobability, stochasticity,
                    particlesjump, weights, Sgmparticles, Sgm, m, γ_surprise, Ps1a0s0, SPE, counts, seed, rng, Int[])
end
export TParticleFilterJump
function updatet!(learnerT::TParticleFilterJump, s0, a0, s1, done)
    learnerT.particlesjump[a0, s0, :] .= false
    calcSPE!(learnerT, s0, a0, s1) # Calculate a hypothetical SPE
    calcSgm!(learnerT, s0, a0, s1)
    calcγ!(learnerT)
    stayterms = computestayterms(learnerT, s0, a0, s1)
    getweights!(learnerT, s0, a0, stayterms, 1. / learnerT.nr_states)
    sampleparticles!(learnerT, s0, a0, stayterms, 1. / learnerT.nr_states)
    Neff = 1. /sum(learnerT.weights[a0, s0, :] .^2)
    if Neff <= learnerT.Neffthrs; resample!(learnerT, s0, a0); end
    updatecounts!(learnerT, s0, a0, s1)
    computePs1a0s0!(learnerT, s0, a0)
    computeterminalPs1a0s0!(learnerT, s1, done)
end
export updatet!
function computestayterms(learnerT::TParticleFilterJump, s0, a0, s1)
    stayterms = zeros(learnerT.nparticles)
    for i in 1:learnerT.nparticles
        stayterms[i] = (learnerT.stochasticity + learnerT.counts[a0, s0, i][s1])
        stayterms[i] /= sum(learnerT.stochasticity .+ learnerT.counts[a0, s0, i])
    end
    stayterms
end
export computestayterms
function getweights!(learnerT::TParticleFilterJump, s0, a0, stayterms, jumpterm)
    for i in 1:learnerT.nparticles #firstratio = B(s + a(h_t-1)') / B(s + a(h_t-1)). secondratio = B(s + a(h_t=h_t-1 + 1)) / B(s)
        particleweightupdate = (1. - learnerT.surpriseprobability) * stayterms[i]
        particleweightupdate += learnerT.surpriseprobability * jumpterm
        learnerT.weights[a0, s0, i] *= particleweightupdate
    end

    learnerT.weights[a0, s0, :] ./= sum(learnerT.weights[a0, s0, :]) # Normalize

end
export getweights!
function sampleparticles!(learnerT::TParticleFilterJump,
                        s0, a0, stayterms, jumpterm)
    for i in 1:learnerT.nparticles
        particlestayprobability = computeproposaldistribution(learnerT, stayterms[i], jumpterm)

        r = rand(learnerT.rng) # Draw and possibly update
        if r > particlestayprobability
            # println("jump!")
            learnerT.particlesjump[a0, s0, i] = true
        end
    end
end
export sampleparticles!
function computeproposaldistribution(learnerT::TParticleFilterJump,
                                    istayterm, jumpterm)
    particlestayprobability = 1. /(1. + ((learnerT.surpriseprobability * jumpterm) /
                                ((1. - learnerT.surpriseprobability) * istayterm)))
end
export computeproposaldistribution
function updatecounts!(learnerT::TParticleFilterJump, s0, a0, s1)
    for i in 1:learnerT.nparticles
        if !learnerT.particlesjump[a0, s0, i] # if it is not a surprise trial: Integrate
            learnerT.counts[a0, s0, i][s1] += 1 # +1 for s'
        end
    end
end
export updatecounts!
function resample!(learnerT::TParticleFilterJump, s0, a0)
    tempcopyparticleweights = deepcopy(learnerT.weights[a0, s0, :])
    d = Categorical(tempcopyparticleweights)
    tempcopyparticlesjump = copy(learnerT.particlesjump[a0, s0, :])
    tempcopycounts = deepcopy(learnerT.counts[a0, s0, :])
    for i in 1:learnerT.nparticles
        sampledindex = rand(learnerT.rng, d)
        learnerT.particlesjump[a0, s0, i] = copy(tempcopyparticlesjump[sampledindex])
        learnerT.weights[a0, s0, i] = 1. /learnerT.nparticles
        learnerT.counts[a0, s0, i] = deepcopy(tempcopycounts[sampledindex])
    end
end
export resample!
function computePs1a0s0!(learnerT::TParticleFilterJump, s0, a0)
    thetasweighted = zeros(learnerT.nparticles, learnerT.nr_states)
    for i in 1:learnerT.nparticles
        thetas = (learnerT.stochasticity .+ learnerT.counts[a0, s0, i])
        thetas /= sum(learnerT.stochasticity .+ learnerT.counts[a0, s0, i])
        thetasweighted[i,:] = learnerT.weights[a0, s0, i] .* thetas
    end
    expectedvaluethetas = sum(thetasweighted, dims = 1)
    for s in 1:learnerT.nr_states
        learnerT.Ps1a0s0[s][(a0, s0)] = copy(expectedvaluethetas[s])
        # @show learnerT.Ps1a0s0[s][(a0, s0)]
    end
end
""" Outgoing transitions from goal state: set all to 0, except for 1 to itself
(absorbing state) """
function computeterminalPs1a0s0!(learnerT::TPs1a0s0, s1, done)
    if done
        if !in(s1, learnerT.terminalstates)
            push!(learnerT.terminalstates, s1)
            for a in 1:learnerT.nr_actions
                for s in 1:learnerT.nr_states
                    if s == s1
                        learnerT.Ps1a0s0[s][(a, s1)] = 1.
                    else
                        learnerT.Ps1a0s0[s][(a, s1)] = 0.
                    end
                end
            end
        end
    end
end
function calcSgmi(αt, α0, s1)
    p0 = α0[s1] / sum(α0)
    pt = αt[s1] / sum(αt)
    p0 / pt
end
function calcSgmparticles!(learnerT::TParticleFilterJump, s0, a0, s1)
    for i in 1:learnerT.nparticles
        learnerT.Sgmparticles[i] = calcSgmi(
                            learnerT.stochasticity .+ learnerT.counts[a0, s0, i],
                            learnerT.stochasticity .* ones(learnerT.nr_states),
                            s1)
    end
end
function calcSgm!(learnerT::TParticleFilterJump, s0, a0, s1)

    calcSgmparticles!(learnerT, s0, a0, s1)

    if any(isequal.(learnerT.Sgmparticles, 0.))
        learnerT.Sgm[1] = 0.
    else
        SgmInvWeighted = learnerT.weights[a0, s0, :] ./ learnerT.Sgmparticles
        learnerT.Sgm[1] = 1. / sum(SgmInvWeighted)
    end
end
function calcγ!(learnerT::TParticleFilterJump)
    learnerT.γ_surprise[1] = learnerT.m * learnerT.Sgm[1]/(1. + learnerT.m * learnerT.Sgm[1])
end
function calcExpectedHiddenState(learnerT::TParticleFilterJump, s0, a0)
    expectedhiddenstate = sum(Float64.(learnerT.particlesjump[a0, s0, :]) .*
                        learnerT.weights[a0, s0, :])
    expectedhiddenstate = round(expectedhiddenstate)
end
function calcExpectedHiddenStateNotRounded(learnerT::TParticleFilterJump, s0, a0)
    expectedhiddenstate = sum(Float64.(learnerT.particlesjump[a0, s0, :]) .*
                        learnerT.weights[a0, s0, :])
end
function calcSPE!(learnerT::TParticleFilterJump, s0, a0, s1)
    learnerT.SPE[1] = 1. - learnerT.Ps1a0s0[s1][(a0, s0)]
end