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

@test integrate(x^4*arcsin(a*x), x) == :(-2//15*a^-5*(1+-1*a^2*x^2)^3//2+1//5*a^-5*(1+-1*a^2*x^2)^(1/2)+1//5*x^5*arcsin(a*x)+1//25*a^-5*(1+-1*a^2*x^2)^5//2)
@test integrate(x^3*arcsin(a*x), x) == :(-3//32*a^-4*arcsin(a*x)+1//4*x^4*arcsin(a*x)+1//16*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)+3//32*x*a^-3*(1+-1*a^2*x^2)^(1/2))
@test integrate(x^2*arcsin(a*x), x) == :(-1//9*a^-3*(1+-1*a^2*x^2)^3//2+1//3*a^-3*(1+-1*a^2*x^2)^(1/2)+1//3*x^3*arcsin(a*x))
@test integrate(x*arcsin(a*x), x) == :((1/2)*x^2*arcsin(a*x)+-1//4*a^-2*arcsin(a*x)+1//4*x*a^-1*(1+-1*a^2*x^2)^(1/2))
@test integrate(arcsin(a*x), x) == :(x*arcsin(a*x)+a^-1*(1+-1*a^2*x^2)^(1/2))
@test integrate(x^-1*arcsin(a*x), x) == :(arcsin(a*x)*log(1+-1*exp(2*im*arcsin(a*x)))+-1//2*im*arcsin(a*x)^2+-1//2*im*Polylogarithms.polylog(2,exp(2*im*arcsin(a*x))))
@test integrate(x^-2*arcsin(a*x), x) == :(-1*a*arctanh((1+-1*a^2*x^2)^(1/2))+-1*x^-1*arcsin(a*x))
@test integrate(x^-3*arcsin(a*x), x) == :(-1//2*x^-2*arcsin(a*x)+-1//2*a*x^-1*(1+-1*a^2*x^2)^(1/2))
@test integrate(x^-4*arcsin(a*x), x) == :(-1//3*x^-3*arcsin(a*x)+-1//6*a^3*arctanh((1+-1*a^2*x^2)^(1/2))+-1//6*a*x^-2*(1+-1*a^2*x^2)^(1/2))
@test integrate(x^-5*arcsin(a*x), x) == :(-1//4*x^-4*arcsin(a*x)+-1//6*a^3*x^-1*(1+-1*a^2*x^2)^(1/2)+-1//12*a*x^-3*(1+-1*a^2*x^2)^(1/2))
@test integrate(x^-6*arcsin(a*x), x) == :(-3//40*a^5*arctanh((1+-1*a^2*x^2)^(1/2))+-1//5*x^-5*arcsin(a*x)+-3//40*a^3*x^-2*(1+-1*a^2*x^2)^(1/2)+-1//20*a*x^-4*(1+-1*a^2*x^2)^(1/2))
@test integrate(x^4*arcsin(a*x)^2, x) == :(-2//125*x^5+-16//75*x*a^-4+-8//225*a^-2*x^3+1//5*x^5*arcsin(a*x)^2+16//75*a^-5*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+2//25*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+8//75*a^-3*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x))
@test integrate(x^3*arcsin(a*x)^2, x) == :(-1//32*x^4+-3//32*a^-4*arcsin(a*x)^2+-3//32*a^-2*x^2+1//4*x^4*arcsin(a*x)^2+1//8*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+3//16*x*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x))
@test integrate(x^2*arcsin(a*x)^2, x) == :(-2//27*x^3+-4//9*x*a^-2+1//3*x^3*arcsin(a*x)^2+4//9*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+2//9*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x))
@test integrate(x*arcsin(a*x)^2, x) == :(-1//4*x^2+(1/2)*x^2*arcsin(a*x)^2+-1//4*a^-2*arcsin(a*x)^2+(1/2)*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x))
@test integrate(arcsin(a*x)^2, x) == :(-2x+x*arcsin(a*x)^2+2*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x))
@test integrate(x^-1*arcsin(a*x)^2, x) == :((1/2)*Polylogarithms.polylog(3,exp(2*im*arcsin(a*x)))+arcsin(a*x)^2*log(1+-1*exp(2*im*arcsin(a*x)))+-1//3*im*arcsin(a*x)^3+-1*im*Polylogarithms.polylog(2,exp(2*im*arcsin(a*x)))*arcsin(a*x))
@test integrate(x^-2*arcsin(a*x)^2, x) == :(-1*x^-1*arcsin(a*x)^2+-4*a*arcsin(a*x)*arctanh(exp(im*arcsin(a*x)))+-2*im*a*Polylogarithms.polylog(2,exp(im*arcsin(a*x)))+2*im*a*Polylogarithms.polylog(2,-1*exp(im*arcsin(a*x))))
@test integrate(x^-3*arcsin(a*x)^2, x) == :(a^2*log(x)+-1//2*x^-2*arcsin(a*x)^2+-1*a*x^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x))
@test integrate(x^-4*arcsin(a*x)^2, x) == :(-1//3*a^2*x^-1+-1//3*x^-3*arcsin(a*x)^2+-2//3*a^3*arcsin(a*x)*arctanh(exp(im*arcsin(a*x)))+-1//3*im*a^3*Polylogarithms.polylog(2,exp(im*arcsin(a*x)))+1//3*im*a^3*Polylogarithms.polylog(2,-1*exp(im*arcsin(a*x)))+-1//3*a*x^-2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x))
@test integrate(x^-5*arcsin(a*x)^2, x) == :(-1//4*x^-4*arcsin(a*x)^2+-1//12*a^2*x^-2+1//3*a^4*log(x)+-1//3*a^3*x^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+-1//6*a*x^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x))
@test integrate(x^4*arcsin(a*x)^3, x) == :(-298//375*a^-5*(1+-1*a^2*x^2)^(1/2)+-6//125*x^5*arcsin(a*x)+-6//625*a^-5*(1+-1*a^2*x^2)^5//2+1//5*x^5*arcsin(a*x)^3+76//1125*a^-5*(1+-1*a^2*x^2)^3//2+-16//25*x*a^-4*arcsin(a*x)+-8//75*a^-2*x^3*arcsin(a*x)+8//25*a^-5*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2+3//25*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2+4//25*a^-3*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2)
@test integrate(x^3*arcsin(a*x)^3, x) == :(-3//32*a^-4*arcsin(a*x)^3+-3//32*x^4*arcsin(a*x)+1//4*x^4*arcsin(a*x)^3+45//256*a^-4*arcsin(a*x)+-45//256*x*a^-3*(1+-1*a^2*x^2)^(1/2)+-9//32*a^-2*x^2*arcsin(a*x)+-3//128*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)+3//16*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2+9//32*x*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2)
@test integrate(x^2*arcsin(a*x)^3, x) == :(-14//9*a^-3*(1+-1*a^2*x^2)^(1/2)+-2//9*x^3*arcsin(a*x)+1//3*x^3*arcsin(a*x)^3+2//27*a^-3*(1+-1*a^2*x^2)^3//2+-4//3*x*a^-2*arcsin(a*x)+2//3*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2+1//3*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2)
@test integrate(x*arcsin(a*x)^3, x) == :((1/2)*x^2*arcsin(a*x)^3+-3//4*x^2*arcsin(a*x)+-1//4*a^-2*arcsin(a*x)^3+3//8*a^-2*arcsin(a*x)+-3//8*x*a^-1*(1+-1*a^2*x^2)^(1/2)+3//4*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2)
@test integrate(arcsin(a*x)^3, x) == :(x*arcsin(a*x)^3+-6*x*arcsin(a*x)+-6*a^-1*(1+-1*a^2*x^2)^(1/2)+3*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2)
@test integrate(x^-1*arcsin(a*x)^3, x) == :(arcsin(a*x)^3*log(1+-1*exp(2*im*arcsin(a*x)))+-1//4*im*arcsin(a*x)^4+3//2*Polylogarithms.polylog(3,exp(2*im*arcsin(a*x)))*arcsin(a*x)+3//4*im*Polylogarithms.polylog(4,exp(2*im*arcsin(a*x)))+-3//2*im*arcsin(a*x)^2*Polylogarithms.polylog(2,exp(2*im*arcsin(a*x))))
@test integrate(x^-2*arcsin(a*x)^3, x) == :(-1*x^-1*arcsin(a*x)^3+-6*a*Polylogarithms.polylog(3,-1*exp(im*arcsin(a*x)))+6*a*Polylogarithms.polylog(3,exp(im*arcsin(a*x)))+-6*a*arcsin(a*x)^2*arctanh(exp(im*arcsin(a*x)))+-6*im*a*Polylogarithms.polylog(2,exp(im*arcsin(a*x)))*arcsin(a*x)+6*im*a*Polylogarithms.polylog(2,-1*exp(im*arcsin(a*x)))*arcsin(a*x))
@test integrate(x^-3*arcsin(a*x)^3, x) == :(-1//2*x^-2*arcsin(a*x)^3+3*a^2*arcsin(a*x)*log(1+-1*exp(2*im*arcsin(a*x)))+-3//2*im*a^2*arcsin(a*x)^2+-3//2*im*a^2*Polylogarithms.polylog(2,exp(2*im*arcsin(a*x)))+-3//2*a*x^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2)
@test integrate(x^-4*arcsin(a*x)^3, x) == :(a^3*Polylogarithms.polylog(3,exp(im*arcsin(a*x)))+-1*a^3*Polylogarithms.polylog(3,-1*exp(im*arcsin(a*x)))+-1*a^3*arctanh((1+-1*a^2*x^2)^(1/2))+-1//3*x^-3*arcsin(a*x)^3+-1*a^2*x^-1*arcsin(a*x)+-1*a^3*arcsin(a*x)^2*arctanh(exp(im*arcsin(a*x)))+im*a^3*Polylogarithms.polylog(2,-1*exp(im*arcsin(a*x)))*arcsin(a*x)+-1*im*a^3*Polylogarithms.polylog(2,exp(im*arcsin(a*x)))*arcsin(a*x)+-1//2*a*x^-2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2)
@test integrate(x^-5*arcsin(a*x)^3, x) == :(-1//4*x^-4*arcsin(a*x)^3+a^4*arcsin(a*x)*log(1+-1*exp(2*im*arcsin(a*x)))+-1//2*im*a^4*arcsin(a*x)^2+-1//2*im*a^4*Polylogarithms.polylog(2,exp(2*im*arcsin(a*x)))+-1//4*a^2*x^-2*arcsin(a*x)+-1//4*a^3*x^-1*(1+-1*a^2*x^2)^(1/2)+-1//2*a^3*x^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2+-1//4*a*x^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^2)
@test integrate(x^5*arcsin(a*x)^4, x) == :(1//324*x^6+-5//96*a^-6*arcsin(a*x)^4+-1//18*x^6*arcsin(a*x)^2+1//6*x^6*arcsin(a*x)^4+65//3456*a^-2*x^4+245//1152*a^-6*arcsin(a*x)^2+245//1152*a^-4*x^2+-5//16*a^-4*x^2*arcsin(a*x)^2+-5//48*a^-2*x^4*arcsin(a*x)^2+-245//576*x*a^-5*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+-65//864*a^-3*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+-1//54*a^-1*x^5*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+1//9*a^-1*x^5*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3+5//24*x*a^-5*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3+5//36*a^-3*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3)
@test integrate(x^4*arcsin(a*x)^4, x) == :(24//3125*x^5+-12//125*x^5*arcsin(a*x)^2+1//5*x^5*arcsin(a*x)^4+1088//16875*a^-2*x^3+16576//5625*x*a^-4+-16576//5625*a^-5*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+-32//25*x*a^-4*arcsin(a*x)^2+-16//75*a^-2*x^3*arcsin(a*x)^2+32//75*a^-5*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3+-1088//5625*a^-3*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+-24//625*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+4//25*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3+16//75*a^-3*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3)
@test integrate(x^3*arcsin(a*x)^4, x) == :(3//128*x^4+-3//16*x^4*arcsin(a*x)^2+-3//32*a^-4*arcsin(a*x)^4+1//4*x^4*arcsin(a*x)^4+45//128*a^-4*arcsin(a*x)^2+45//128*a^-2*x^2+-9//16*a^-2*x^2*arcsin(a*x)^2+-45//64*x*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+-3//32*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+1//4*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3+3//8*x*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3)
@test integrate(x^2*arcsin(a*x)^4, x) == :(8//81*x^3+-4//9*x^3*arcsin(a*x)^2+1//3*x^3*arcsin(a*x)^4+160//27*x*a^-2+-160//27*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+-8//3*x*a^-2*arcsin(a*x)^2+8//9*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3+-8//27*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+4//9*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3)
@test integrate(x*arcsin(a*x)^4, x) == :(3//4*x^2+(1/2)*x^2*arcsin(a*x)^4+-3//2*x^2*arcsin(a*x)^2+-1//4*a^-2*arcsin(a*x)^4+3//4*a^-2*arcsin(a*x)^2+x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3+-3//2*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x))
@test integrate(arcsin(a*x)^4, x) == :(24x+x*arcsin(a*x)^4+-12*x*arcsin(a*x)^2+-24*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)+4*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3)
@test integrate(x^-1*arcsin(a*x)^4, x) == :(-3//2*Polylogarithms.polylog(5,exp(2*im*arcsin(a*x)))+arcsin(a*x)^4*log(1+-1*exp(2*im*arcsin(a*x)))+3*arcsin(a*x)^2*Polylogarithms.polylog(3,exp(2*im*arcsin(a*x)))+-1//5*im*arcsin(a*x)^5+-2*im*arcsin(a*x)^3*Polylogarithms.polylog(2,exp(2*im*arcsin(a*x)))+3*im*Polylogarithms.polylog(4,exp(2*im*arcsin(a*x)))*arcsin(a*x))
@test integrate(x^-2*arcsin(a*x)^4, x) == :(-1*x^-1*arcsin(a*x)^4+-24*im*a*Polylogarithms.polylog(4,-1*exp(im*arcsin(a*x)))+-24*a*Polylogarithms.polylog(3,-1*exp(im*arcsin(a*x)))*arcsin(a*x)+-8*a*arcsin(a*x)^3*arctanh(exp(im*arcsin(a*x)))+24*im*a*Polylogarithms.polylog(4,exp(im*arcsin(a*x)))+24*a*Polylogarithms.polylog(3,exp(im*arcsin(a*x)))*arcsin(a*x)+-12*im*a*arcsin(a*x)^2*Polylogarithms.polylog(2,exp(im*arcsin(a*x)))+12*im*a*arcsin(a*x)^2*Polylogarithms.polylog(2,-1*exp(im*arcsin(a*x))))
@test integrate(x^-3*arcsin(a*x)^4, x) == :(3*a^2*Polylogarithms.polylog(3,exp(2*im*arcsin(a*x)))+-1//2*x^-2*arcsin(a*x)^4+-2*im*a^2*arcsin(a*x)^3+6*a^2*arcsin(a*x)^2*log(1+-1*exp(2*im*arcsin(a*x)))+-6*im*a^2*Polylogarithms.polylog(2,exp(2*im*arcsin(a*x)))*arcsin(a*x)+-2*a*x^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3)
@test integrate(x^-4*arcsin(a*x)^4, x) == :(-1//3*x^-3*arcsin(a*x)^4+-8*a^3*arcsin(a*x)*arctanh(exp(im*arcsin(a*x)))+-4*im*a^3*Polylogarithms.polylog(2,exp(im*arcsin(a*x)))+-4*im*a^3*Polylogarithms.polylog(4,-1*exp(im*arcsin(a*x)))+-4*a^3*Polylogarithms.polylog(3,-1*exp(im*arcsin(a*x)))*arcsin(a*x)+-2*a^2*x^-1*arcsin(a*x)^2+4*im*a^3*Polylogarithms.polylog(2,-1*exp(im*arcsin(a*x)))+4*im*a^3*Polylogarithms.polylog(4,exp(im*arcsin(a*x)))+4*a^3*Polylogarithms.polylog(3,exp(im*arcsin(a*x)))*arcsin(a*x)+-4//3*a^3*arcsin(a*x)^3*arctanh(exp(im*arcsin(a*x)))+-2*im*a^3*arcsin(a*x)^2*Polylogarithms.polylog(2,exp(im*arcsin(a*x)))+2*im*a^3*arcsin(a*x)^2*Polylogarithms.polylog(2,-1*exp(im*arcsin(a*x)))+-2//3*a*x^-2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3)
@test integrate(x^6*arcsin(a*x)^-1, x) == :(-9//64*a^-7*cosintegral(3*arcsin(a*x))+-1//64*a^-7*cosintegral(7*arcsin(a*x))+5//64*a^-7*cosintegral(5*arcsin(a*x))+5//64*a^-7*cosintegral(arcsin(a*x)))
@test integrate(x^5*arcsin(a*x)^-1, x) == :(-1//8*a^-6*sinintegral(4*arcsin(a*x))+1//32*a^-6*sinintegral(6*arcsin(a*x))+5//32*a^-6*sinintegral(2*arcsin(a*x)))
@test integrate(x^4*arcsin(a*x)^-1, x) == :(-3//16*a^-5*cosintegral(3*arcsin(a*x))+1//8*a^-5*cosintegral(arcsin(a*x))+1//16*a^-5*cosintegral(5*arcsin(a*x)))
@test integrate(x^3*arcsin(a*x)^-1, x) == :(-1//8*a^-4*sinintegral(4*arcsin(a*x))+1//4*a^-4*sinintegral(2*arcsin(a*x)))
@test integrate(x^2*arcsin(a*x)^-1, x) == :(-1//4*a^-3*cosintegral(3*arcsin(a*x))+1//4*a^-3*cosintegral(arcsin(a*x)))
@test integrate(x*arcsin(a*x)^-1, x) == :((1/2)*a^-2*sinintegral(2*arcsin(a*x)))
@test integrate(arcsin(a*x)^-1, x) == :(a^-1*cosintegral(arcsin(a*x)))
@test integrate(x^6*arcsin(a*x)^-2, x) == :(-25//64*a^-7*sinintegral(5*arcsin(a*x))+-5//64*a^-7*sinintegral(arcsin(a*x))+7//64*a^-7*sinintegral(7*arcsin(a*x))+27//64*a^-7*sinintegral(3*arcsin(a*x))+-1*a^-1*x^6*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(x^5*arcsin(a*x)^-2, x) == :(-1//2*a^-6*cosintegral(4*arcsin(a*x))+3//16*a^-6*cosintegral(6*arcsin(a*x))+5//16*a^-6*cosintegral(2*arcsin(a*x))+-1*a^-1*x^5*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(x^4*arcsin(a*x)^-2, x) == :(-5//16*a^-5*sinintegral(5*arcsin(a*x))+-1//8*a^-5*sinintegral(arcsin(a*x))+9//16*a^-5*sinintegral(3*arcsin(a*x))+-1*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(x^3*arcsin(a*x)^-2, x) == :((1/2)*a^-4*cosintegral(2*arcsin(a*x))+-1//2*a^-4*cosintegral(4*arcsin(a*x))+-1*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(x^2*arcsin(a*x)^-2, x) == :(-1//4*a^-3*sinintegral(arcsin(a*x))+3//4*a^-3*sinintegral(3*arcsin(a*x))+-1*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(x*arcsin(a*x)^-2, x) == :(a^-2*cosintegral(2*arcsin(a*x))+-1*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(arcsin(a*x)^-2, x) == :(-1*a^-1*sinintegral(arcsin(a*x))+-1*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(x^4*arcsin(a*x)^-3, x) == :(-25//32*a^-5*cosintegral(5*arcsin(a*x))+-1//16*a^-5*cosintegral(arcsin(a*x))+5//2*x^5*arcsin(a*x)^-1+27//32*a^-5*cosintegral(3*arcsin(a*x))+-2*a^-2*x^3*arcsin(a*x)^-1+-1//2*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-2)
@test integrate(x^3*arcsin(a*x)^-3, x) == :(a^-4*sinintegral(4*arcsin(a*x))+2*x^4*arcsin(a*x)^-1+-1//2*a^-4*sinintegral(2*arcsin(a*x))+-3//2*a^-2*x^2*arcsin(a*x)^-1+-1//2*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-2)
@test integrate(x^2*arcsin(a*x)^-3, x) == :(-1//8*a^-3*cosintegral(arcsin(a*x))+3//2*x^3*arcsin(a*x)^-1+9//8*a^-3*cosintegral(3*arcsin(a*x))+-1*x*a^-2*arcsin(a*x)^-1+-1//2*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-2)
@test integrate(x*arcsin(a*x)^-3, x) == :(x^2*arcsin(a*x)^-1+-1*a^-2*sinintegral(2*arcsin(a*x))+-1//2*a^-2*arcsin(a*x)^-1+-1//2*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-2)
@test integrate(arcsin(a*x)^-3, x) == :((1/2)*x*arcsin(a*x)^-1+-1//2*a^-1*cosintegral(arcsin(a*x))+-1//2*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-2)
@test integrate(x^4*arcsin(a*x)^-4, x) == :(-27//32*a^-5*sinintegral(3*arcsin(a*x))+1//48*a^-5*sinintegral(arcsin(a*x))+5//6*x^5*arcsin(a*x)^-2+125//96*a^-5*sinintegral(5*arcsin(a*x))+-2//3*a^-2*x^3*arcsin(a*x)^-2+-2*a^-3*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1+-1//3*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-3+25//6*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(x^3*arcsin(a*x)^-4, x) == :(-1//3*a^-4*cosintegral(2*arcsin(a*x))+2//3*x^4*arcsin(a*x)^-2+4//3*a^-4*cosintegral(4*arcsin(a*x))+-1//2*a^-2*x^2*arcsin(a*x)^-2+-1*x*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1+-1//3*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-3+8//3*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(x^2*arcsin(a*x)^-4, x) == :((1/2)*x^3*arcsin(a*x)^-2+-9//8*a^-3*sinintegral(3*arcsin(a*x))+1//24*a^-3*sinintegral(arcsin(a*x))+-1//3*x*a^-2*arcsin(a*x)^-2+-1//3*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1+-1//3*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-3+3//2*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(x*arcsin(a*x)^-4, x) == :(-2//3*a^-2*cosintegral(2*arcsin(a*x))+-1//6*a^-2*arcsin(a*x)^-2+1//3*x^2*arcsin(a*x)^-2+-1//3*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-3+2//3*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(arcsin(a*x)^-4, x) == :(1//6*x*arcsin(a*x)^-2+1//6*a^-1*sinintegral(arcsin(a*x))+-1//3*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-3+1//6*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1)
@test integrate(x^4*arcsin(a*x)^(1/2), x) == :(1//5*x^5*arcsin(a*x)^(1/2)+-1//16*2^(1/2)*pi^(1/2)*a^-5*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+-1//800*10^(1/2)*pi^(1/2)*a^-5*fresnels(10^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+1//96*6^(1/2)*pi^(1/2)*a^-5*fresnels(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^3*arcsin(a*x)^(1/2), x) == :(-3//32*a^-4*arcsin(a*x)^(1/2)+1//4*x^4*arcsin(a*x)^(1/2)+1//16*pi^(1/2)*a^-4*fresnelc(2*pi^-1//2*arcsin(a*x)^(1/2))+-1//128*2^(1/2)*pi^(1/2)*a^-4*fresnelc(2*2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^2*arcsin(a*x)^(1/2), x) == :(1//3*x^3*arcsin(a*x)^(1/2)+-1//8*2^(1/2)*pi^(1/2)*a^-3*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+1//72*6^(1/2)*pi^(1/2)*a^-3*fresnels(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x*arcsin(a*x)^(1/2), x) == :((1/2)*x^2*arcsin(a*x)^(1/2)+-1//4*a^-2*arcsin(a*x)^(1/2)+1//8*pi^(1/2)*a^-2*fresnelc(2*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(arcsin(a*x)^(1/2), x) == :(x*arcsin(a*x)^(1/2)+-1//2*2^(1/2)*pi^(1/2)*a^-1*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^3*arcsin(a*x)^3//2, x) == :(-3//32*a^-4*arcsin(a*x)^3//2+1//4*x^4*arcsin(a*x)^3//2+-3//64*pi^(1/2)*a^-4*fresnels(2*pi^-1//2*arcsin(a*x)^(1/2))+3//32*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^(1/2)+3//1024*2^(1/2)*pi^(1/2)*a^-4*fresnels(2*2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+9//64*x*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^(1/2))
@test integrate(x^2*arcsin(a*x)^3//2, x) == :(1//3*x^3*arcsin(a*x)^3//2+1//3*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^(1/2)+-3//16*2^(1/2)*pi^(1/2)*a^-3*fresnelc(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+1//6*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^(1/2)+1//144*6^(1/2)*pi^(1/2)*a^-3*fresnelc(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x*arcsin(a*x)^3//2, x) == :((1/2)*x^2*arcsin(a*x)^3//2+-1//4*a^-2*arcsin(a*x)^3//2+-3//32*pi^(1/2)*a^-2*fresnels(2*pi^-1//2*arcsin(a*x)^(1/2))+3//8*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^(1/2))
@test integrate(arcsin(a*x)^3//2, x) == :(x*arcsin(a*x)^3//2+3//2*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^(1/2)+-3//4*2^(1/2)*pi^(1/2)*a^-1*fresnelc(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^3*arcsin(a*x)^5//2, x) == :(-15//256*x^4*arcsin(a*x)^(1/2)+-3//32*a^-4*arcsin(a*x)^5//2+1//4*x^4*arcsin(a*x)^5//2+225//2048*a^-4*arcsin(a*x)^(1/2)+-45//256*a^-2*x^2*arcsin(a*x)^(1/2)+-15//256*pi^(1/2)*a^-4*fresnelc(2*pi^-1//2*arcsin(a*x)^(1/2))+5//32*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3//2+15//64*x*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3//2+15//8192*2^(1/2)*pi^(1/2)*a^-4*fresnelc(2*2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^2*arcsin(a*x)^5//2, x) == :(-5//36*x^3*arcsin(a*x)^(1/2)+1//3*x^3*arcsin(a*x)^5//2+-5//6*x*a^-2*arcsin(a*x)^(1/2)+5//9*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3//2+-5//864*6^(1/2)*pi^(1/2)*a^-3*fresnels(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+5//18*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3//2+15//32*2^(1/2)*pi^(1/2)*a^-3*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x*arcsin(a*x)^5//2, x) == :((1/2)*x^2*arcsin(a*x)^5//2+-15//32*x^2*arcsin(a*x)^(1/2)+-1//4*a^-2*arcsin(a*x)^5//2+15//64*a^-2*arcsin(a*x)^(1/2)+-15//128*pi^(1/2)*a^-2*fresnelc(2*pi^-1//2*arcsin(a*x)^(1/2))+5//8*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3//2)
@test integrate(arcsin(a*x)^5//2, x) == :(x*arcsin(a*x)^5//2+-15//4*x*arcsin(a*x)^(1/2)+5//2*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^3//2+15//8*2^(1/2)*pi^(1/2)*a^-1*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^4*arcsin(a*x)^-1//2, x) == :(-1//16*6^(1/2)*pi^(1/2)*a^-5*fresnelc(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+1//8*2^(1/2)*pi^(1/2)*a^-5*fresnelc(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+1//80*10^(1/2)*pi^(1/2)*a^-5*fresnelc(10^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^3*arcsin(a*x)^-1//2, x) == :(1//4*pi^(1/2)*a^-4*fresnels(2*pi^-1//2*arcsin(a*x)^(1/2))+-1//16*2^(1/2)*pi^(1/2)*a^-4*fresnels(2*2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^2*arcsin(a*x)^-1//2, x) == :(-1//12*6^(1/2)*pi^(1/2)*a^-3*fresnelc(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+1//4*2^(1/2)*pi^(1/2)*a^-3*fresnelc(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x*arcsin(a*x)^-1//2, x) == :((1/2)*pi^(1/2)*a^-2*fresnels(2*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(arcsin(a*x)^-1//2, x) == :(2^(1/2)*pi^(1/2)*a^-1*fresnelc(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^6*arcsin(a*x)^-3//2, x) == :(-2*a^-1*x^6*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2+-5//32*2^(1/2)*pi^(1/2)*a^-7*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+-5//32*10^(1/2)*pi^(1/2)*a^-7*fresnels(10^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+1//32*14^(1/2)*pi^(1/2)*a^-7*fresnels(14^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+9//32*6^(1/2)*pi^(1/2)*a^-7*fresnels(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^5*arcsin(a*x)^-3//2, x) == :(5//8*pi^(1/2)*a^-6*fresnelc(2*pi^-1//2*arcsin(a*x)^(1/2))+-2*a^-1*x^5*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2+-1//2*2^(1/2)*pi^(1/2)*a^-6*fresnelc(2*2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+1//8*3^(1/2)*pi^(1/2)*a^-6*fresnelc(2*3^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^4*arcsin(a*x)^-3//2, x) == :(-2*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2+-1//4*2^(1/2)*pi^(1/2)*a^-5*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+-1//8*10^(1/2)*pi^(1/2)*a^-5*fresnels(10^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+3//8*6^(1/2)*pi^(1/2)*a^-5*fresnels(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^3*arcsin(a*x)^-3//2, x) == :(pi^(1/2)*a^-4*fresnelc(2*pi^-1//2*arcsin(a*x)^(1/2))+-2*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2+-1//2*2^(1/2)*pi^(1/2)*a^-4*fresnelc(2*2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^2*arcsin(a*x)^-3//2, x) == :((1/2)*6^(1/2)*pi^(1/2)*a^-3*fresnels(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+-2*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2+-1//2*2^(1/2)*pi^(1/2)*a^-3*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x*arcsin(a*x)^-3//2, x) == :(2*pi^(1/2)*a^-2*fresnelc(2*pi^-1//2*arcsin(a*x)^(1/2))+-2*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2)
@test integrate(arcsin(a*x)^-3//2, x) == :(-2*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2+-2*2^(1/2)*pi^(1/2)*a^-1*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^3*arcsin(a*x)^-5//2, x) == :(16//3*x^4*arcsin(a*x)^-1//2+-4*a^-2*x^2*arcsin(a*x)^-1//2+-4//3*pi^(1/2)*a^-4*fresnels(2*pi^-1//2*arcsin(a*x)^(1/2))+-2//3*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-3//2+4//3*2^(1/2)*pi^(1/2)*a^-4*fresnels(2*2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^2*arcsin(a*x)^-5//2, x) == :(4*x^3*arcsin(a*x)^-1//2+-8//3*x*a^-2*arcsin(a*x)^-1//2+6^(1/2)*pi^(1/2)*a^-3*fresnelc(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+-2//3*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-3//2+-1//3*2^(1/2)*pi^(1/2)*a^-3*fresnelc(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x*arcsin(a*x)^-5//2, x) == :(-4//3*a^-2*arcsin(a*x)^-1//2+8//3*x^2*arcsin(a*x)^-1//2+-8//3*pi^(1/2)*a^-2*fresnels(2*pi^-1//2*arcsin(a*x)^(1/2))+-2//3*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-3//2)
@test integrate(arcsin(a*x)^-5//2, x) == :(4//3*x*arcsin(a*x)^-1//2+-2//3*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-3//2+-4//3*2^(1/2)*pi^(1/2)*a^-1*fresnelc(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^4*arcsin(a*x)^-7//2, x) == :(4//3*x^5*arcsin(a*x)^-3//2+-16//15*a^-2*x^3*arcsin(a*x)^-3//2+-32//5*a^-3*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2+-9//10*6^(1/2)*pi^(1/2)*a^-5*fresnels(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+-2//5*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-5//2+1//15*2^(1/2)*pi^(1/2)*a^-5*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+5//6*10^(1/2)*pi^(1/2)*a^-5*fresnels(10^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+40//3*a^-1*x^4*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2)
@test integrate(x^3*arcsin(a*x)^-7//2, x) == :(16//15*x^4*arcsin(a*x)^-3//2+-16//15*pi^(1/2)*a^-4*fresnelc(2*pi^-1//2*arcsin(a*x)^(1/2))+-4//5*a^-2*x^2*arcsin(a*x)^-3//2+-16//5*x*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2+-2//5*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-5//2+32//15*2^(1/2)*pi^(1/2)*a^-4*fresnelc(2*2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+128//15*a^-1*x^3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2)
@test integrate(x^2*arcsin(a*x)^-7//2, x) == :(4//5*x^3*arcsin(a*x)^-3//2+-16//15*a^-3*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2+-8//15*x*a^-2*arcsin(a*x)^-3//2+-6//5*6^(1/2)*pi^(1/2)*a^-3*fresnels(6^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+-2//5*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-5//2+2//15*2^(1/2)*pi^(1/2)*a^-3*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2))+24//5*a^-1*x^2*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2)
@test integrate(x*arcsin(a*x)^-7//2, x) == :(-4//15*a^-2*arcsin(a*x)^-3//2+8//15*x^2*arcsin(a*x)^-3//2+-32//15*pi^(1/2)*a^-2*fresnelc(2*pi^-1//2*arcsin(a*x)^(1/2))+-2//5*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-5//2+32//15*x*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2)
@test integrate(arcsin(a*x)^-7//2, x) == :(4//15*x*arcsin(a*x)^-3//2+-2//5*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-5//2+8//15*a^-1*(1+-1*a^2*x^2)^(1/2)*arcsin(a*x)^-1//2+8//15*2^(1/2)*pi^(1/2)*a^-1*fresnels(2^(1/2)*pi^-1//2*arcsin(a*x)^(1/2)))
@test integrate(x^3*arcsin(a*x)^n, x) == :(2^(-6+-2n)*a^-4*(im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,4*im*arcsin(a*x))+2^(-6+-2n)*a^-4*(-1*im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,-4*im*arcsin(a*x))+-1*2^(-4+-1n)*a^-4*(im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,2*im*arcsin(a*x))+-1*2^(-4+-1n)*a^-4*(-1*im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,-2*im*arcsin(a*x)))
@test integrate(x^2*arcsin(a*x)^n, x) == :(-1//8*im*a^-3*(-1*im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,-1*im*arcsin(a*x))+1//8*im*a^-3*(im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,im*arcsin(a*x))+-1//8*im*3^(-1+-1n)*a^-3*(im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,3*im*arcsin(a*x))+1//8*im*3^(-1+-1n)*a^-3*(-1*im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,-3*im*arcsin(a*x)))
@test integrate(x*arcsin(a*x)^n, x) == :(-1*2^(-3+-1n)*a^-2*(im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,2*im*arcsin(a*x))+-1*2^(-3+-1n)*a^-2*(-1*im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,-2*im*arcsin(a*x)))
@test integrate(arcsin(a*x)^n, x) == :((1/2)*im*a^-1*(im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,im*arcsin(a*x))+-1//2*im*a^-1*(-1*im*arcsin(a*x))^(-1n)*arcsin(a*x)^n*SpecialFunctions.gamma(1+n,-1*im*arcsin(a*x)))
@test integrate(x^3*(a+b*arcsin(c*x)), x) == :(1//4*x^4*(a+b*arcsin(c*x))+-3//32*b*c^-4*arcsin(c*x)+1//16*b*c^-1*x^3*(1+-1*c^2*x^2)^(1/2)+3//32*b*x*c^-3*(1+-1*c^2*x^2)^(1/2))
@test integrate(x^2*(a+b*arcsin(c*x)), x) == :(1//3*x^3*(a+b*arcsin(c*x))+-1//9*b*c^-3*(1+-1*c^2*x^2)^3//2+1//3*b*c^-3*(1+-1*c^2*x^2)^(1/2))
@test integrate(x*(a+b*arcsin(c*x)), x) == :((1/2)*x^2*(a+b*arcsin(c*x))+-1//4*b*c^-2*arcsin(c*x)+1//4*b*x*c^-1*(1+-1*c^2*x^2)^(1/2))
@test integrate(a+b*arcsin(c*x), x) == :(a*x+b*x*arcsin(c*x)+b*c^-1*(1+-1*c^2*x^2)^(1/2))
@test integrate(x^-1*(a+b*arcsin(c*x)), x) == :((a+b*arcsin(c*x))*log(1+-1*exp(2*im*arcsin(c*x)))+-1//2*im*b*Polylogarithms.polylog(2,exp(2*im*arcsin(c*x)))+-1//2*im*b^-1*(a+b*arcsin(c*x))^2)
@test integrate(x^-2*(a+b*arcsin(c*x)), x) == :(-1*x^-1*(a+b*arcsin(c*x))+-1*b*c*arctanh((1+-1*c^2*x^2)^(1/2)))
@test integrate(x^-3*(a+b*arcsin(c*x)), x) == :(-1//2*x^-2*(a+b*arcsin(c*x))+-1//2*b*c*x^-1*(1+-1*c^2*x^2)^(1/2))
@test integrate(x^-4*(a+b*arcsin(c*x)), x) == :(-1//3*x^-3*(a+b*arcsin(c*x))+-1//6*b*c^3*arctanh((1+-1*c^2*x^2)^(1/2))+-1//6*b*c*x^-2*(1+-1*c^2*x^2)^(1/2))
@test integrate(x^2*(a+b*arcsin(c*x))^2, x) == :(-2//27*b^2*x^3+1//3*x^3*(a+b*arcsin(c*x))^2+-4//9*x*b^2*c^-2+4//9*b*c^-3*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))+2//9*b*c^-1*x^2*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x)))
@test integrate(x*(a+b*arcsin(c*x))^2, x) == :((1/2)*x^2*(a+b*arcsin(c*x))^2+-1//4*b^2*x^2+-1//4*c^-2*(a+b*arcsin(c*x))^2+(1/2)*b*x*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x)))
@test integrate((a+b*arcsin(c*x))^2, x) == :(x*(a+b*arcsin(c*x))^2+-2*x*b^2+2*b*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x)))
@test integrate(x^-1*(a+b*arcsin(c*x))^2, x) == :((a+b*arcsin(c*x))^2*log(1+-1*exp(2*im*arcsin(c*x)))+(1/2)*b^2*Polylogarithms.polylog(3,exp(2*im*arcsin(c*x)))+-1//3*im*b^-1*(a+b*arcsin(c*x))^3+-1*im*b*(a+b*arcsin(c*x))*Polylogarithms.polylog(2,exp(2*im*arcsin(c*x))))
@test integrate(x^-2*(a+b*arcsin(c*x))^2, x) == :(-1*x^-1*(a+b*arcsin(c*x))^2+-4*b*c*(a+b*arcsin(c*x))*arctanh(exp(im*arcsin(c*x)))+-2*im*c*b^2*Polylogarithms.polylog(2,exp(im*arcsin(c*x)))+2*im*c*b^2*Polylogarithms.polylog(2,-1*exp(im*arcsin(c*x))))
@test integrate(x^2*(a+b*arcsin(c*x))^3, x) == :(1//3*x^3*(a+b*arcsin(c*x))^3+-14//9*b^3*c^-3*(1+-1*c^2*x^2)^(1/2)+-2//9*b^2*x^3*(a+b*arcsin(c*x))+2//27*b^3*c^-3*(1+-1*c^2*x^2)^3//2+-4//3*a*x*b^2*c^-2+-4//3*x*b^3*c^-2*arcsin(c*x)+2//3*b*c^-3*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^2+1//3*b*c^-1*x^2*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^2)
@test integrate(x*(a+b*arcsin(c*x))^3, x) == :((1/2)*x^2*(a+b*arcsin(c*x))^3+-1//4*c^-2*(a+b*arcsin(c*x))^3+-3//4*b^2*x^2*(a+b*arcsin(c*x))+3//8*b^3*c^-2*arcsin(c*x)+-3//8*x*b^3*c^-1*(1+-1*c^2*x^2)^(1/2)+3//4*b*x*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^2)
@test integrate((a+b*arcsin(c*x))^3, x) == :(x*(a+b*arcsin(c*x))^3+-6*a*x*b^2+-6*x*b^3*arcsin(c*x)+-6*b^3*c^-1*(1+-1*c^2*x^2)^(1/2)+3*b*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^2)
@test integrate(x^-1*(a+b*arcsin(c*x))^3, x) == :((a+b*arcsin(c*x))^3*log(1+-1*exp(2*im*arcsin(c*x)))+-1//4*im*b^-1*(a+b*arcsin(c*x))^4+3//2*b^2*(a+b*arcsin(c*x))*Polylogarithms.polylog(3,exp(2*im*arcsin(c*x)))+3//4*im*b^3*Polylogarithms.polylog(4,exp(2*im*arcsin(c*x)))+-3//2*im*b*(a+b*arcsin(c*x))^2*Polylogarithms.polylog(2,exp(2*im*arcsin(c*x))))
@test integrate(x^-2*(a+b*arcsin(c*x))^3, x) == :(-1*x^-1*(a+b*arcsin(c*x))^3+-6*c*b^3*Polylogarithms.polylog(3,-1*exp(im*arcsin(c*x)))+6*c*b^3*Polylogarithms.polylog(3,exp(im*arcsin(c*x)))+-6*b*c*(a+b*arcsin(c*x))^2*arctanh(exp(im*arcsin(c*x)))+-6*im*c*b^2*(a+b*arcsin(c*x))*Polylogarithms.polylog(2,exp(im*arcsin(c*x)))+6*im*c*b^2*(a+b*arcsin(c*x))*Polylogarithms.polylog(2,-1*exp(im*arcsin(c*x))))
@test integrate(x^2*(a+b*arcsin(c*x))^-1, x) == :(-1//4*b^-1*c^-3*cos(3*a*b^-1)*cosintegral(3*arcsin(c*x)+3*a*b^-1)+-1//4*b^-1*c^-3*sin(3*a*b^-1)*sinintegral(3*arcsin(c*x)+3*a*b^-1)+1//4*b^-1*c^-3*cos(a*b^-1)*cosintegral(a*b^-1+arcsin(c*x))+1//4*b^-1*c^-3*sin(a*b^-1)*sinintegral(a*b^-1+arcsin(c*x)))
@test integrate(x*(a+b*arcsin(c*x))^-1, x) == :((1/2)*b^-1*c^-2*cos(2*a*b^-1)*sinintegral(2*arcsin(c*x)+2*a*b^-1)+-1//2*b^-1*c^-2*cosintegral(2*arcsin(c*x)+2*a*b^-1)*sin(2*a*b^-1))
@test integrate((a+b*arcsin(c*x))^-1, x) == :(b^-1*c^-1*cos(a*b^-1)*cosintegral(b^-1*(a+b*arcsin(c*x)))+b^-1*c^-1*sin(a*b^-1)*sinintegral(b^-1*(a+b*arcsin(c*x))))
@test integrate(x^2*(a+b*arcsin(c*x))^-2, x) == :(-3//4*b^-2*c^-3*cosintegral(3*arcsin(c*x)+3*a*b^-1)*sin(3*a*b^-1)+-1//4*b^-2*c^-3*cos(a*b^-1)*sinintegral(a*b^-1+arcsin(c*x))+1//4*b^-2*c^-3*cosintegral(a*b^-1+arcsin(c*x))*sin(a*b^-1)+3//4*b^-2*c^-3*cos(3*a*b^-1)*sinintegral(3*arcsin(c*x)+3*a*b^-1)+-1*b^-1*c^-1*x^2*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-1)
@test integrate(x*(a+b*arcsin(c*x))^-2, x) == :(b^-2*c^-2*cos(2*a*b^-1)*cosintegral(2*arcsin(c*x)+2*a*b^-1)+b^-2*c^-2*sin(2*a*b^-1)*sinintegral(2*arcsin(c*x)+2*a*b^-1)+-1*x*b^-1*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-1)
@test integrate((a+b*arcsin(c*x))^-2, x) == :(b^-2*c^-1*cosintegral(a*b^-1+arcsin(c*x))*sin(a*b^-1)+-1*b^-1*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-1+-1*b^-2*c^-1*cos(a*b^-1)*sinintegral(a*b^-1+arcsin(c*x)))
@test integrate(x^2*(a+b*arcsin(c*x))^-3, x) == :(3//2*b^-2*x^3*(a+b*arcsin(c*x))^-1+b^-3*c^-3*cos(a*b^-1)*cosintegral(b^-1*(a+b*arcsin(c*x)))+b^-3*c^-3*sin(a*b^-1)*sinintegral(b^-1*(a+b*arcsin(c*x)))+-1*x*b^-2*c^-2*(a+b*arcsin(c*x))^-1+-9//8*b^-3*c^-3*cos(a*b^-1)*cosintegral(a*b^-1+arcsin(c*x))+-9//8*b^-3*c^-3*sin(a*b^-1)*sinintegral(a*b^-1+arcsin(c*x))+9//8*b^-3*c^-3*cos(3*a*b^-1)*cosintegral(3*arcsin(c*x)+3*a*b^-1)+9//8*b^-3*c^-3*sin(3*a*b^-1)*sinintegral(3*arcsin(c*x)+3*a*b^-1)+-1//2*b^-1*c^-1*x^2*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-2)
@test integrate(x*(a+b*arcsin(c*x))^-3, x) == :(b^-2*x^2*(a+b*arcsin(c*x))^-1+-1//2*b^-2*c^-2*(a+b*arcsin(c*x))^-1+b^-3*c^-2*cosintegral(2*arcsin(c*x)+2*a*b^-1)*sin(2*a*b^-1)+-1*b^-3*c^-2*cos(2*a*b^-1)*sinintegral(2*arcsin(c*x)+2*a*b^-1)+-1//2*x*b^-1*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-2)
@test integrate((a+b*arcsin(c*x))^-3, x) == :((1/2)*x*b^-2*(a+b*arcsin(c*x))^-1+-1//2*b^-1*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-2+-1//2*b^-3*c^-1*cos(a*b^-1)*cosintegral(b^-1*(a+b*arcsin(c*x)))+-1//2*b^-3*c^-1*sin(a*b^-1)*sinintegral(b^-1*(a+b*arcsin(c*x))))
@test integrate(x^2*(a+b*arcsin(c*x))^(1/2), x) == :(1//3*x^3*(a+b*arcsin(c*x))^(1/2)+-1//8*2^(1/2)*pi^(1/2)*b^(1/2)*c^-3*cos(a*b^-1)*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-1//72*6^(1/2)*pi^(1/2)*b^(1/2)*c^-3*fresnelc(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(3*a*b^-1)+1//8*2^(1/2)*pi^(1/2)*b^(1/2)*c^-3*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1)+1//72*6^(1/2)*pi^(1/2)*b^(1/2)*c^-3*cos(3*a*b^-1)*fresnels(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2)))
@test integrate(x*(a+b*arcsin(c*x))^(1/2), x) == :((1/2)*x^2*(a+b*arcsin(c*x))^(1/2)+-1//4*c^-2*(a+b*arcsin(c*x))^(1/2)+1//8*pi^(1/2)*b^(1/2)*c^-2*cos(2*a*b^-1)*fresnelc(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+1//8*pi^(1/2)*b^(1/2)*c^-2*fresnels(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(2*a*b^-1))
@test integrate((a+b*arcsin(c*x))^(1/2), x) == :(x*(a+b*arcsin(c*x))^(1/2)+(1/2)*2^(1/2)*pi^(1/2)*b^(1/2)*c^-1*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1)+-1//2*2^(1/2)*pi^(1/2)*b^(1/2)*c^-1*cos(a*b^-1)*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2)))
@test integrate(x^2*(a+b*arcsin(c*x))^3//2, x) == :(1//3*x^3*(a+b*arcsin(c*x))^3//2+1//3*b*c^-3*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^(1/2)+1//6*b*c^-1*x^2*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^(1/2)+-3//16*2^(1/2)*pi^(1/2)*b^3//2*c^-3*cos(a*b^-1)*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-3//16*2^(1/2)*pi^(1/2)*b^3//2*c^-3*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1)+1//144*6^(1/2)*pi^(1/2)*b^3//2*c^-3*cos(3*a*b^-1)*fresnelc(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+1//144*6^(1/2)*pi^(1/2)*b^3//2*c^-3*fresnels(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(3*a*b^-1))
@test integrate(x*(a+b*arcsin(c*x))^3//2, x) == :((1/2)*x^2*(a+b*arcsin(c*x))^3//2+-1//4*c^-2*(a+b*arcsin(c*x))^3//2+-3//32*pi^(1/2)*b^3//2*c^-2*cos(2*a*b^-1)*fresnels(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+3//8*b*x*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^(1/2)+3//32*pi^(1/2)*b^3//2*c^-2*fresnelc(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(2*a*b^-1))
@test integrate((a+b*arcsin(c*x))^3//2, x) == :(x*(a+b*arcsin(c*x))^3//2+3//2*b*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^(1/2)+-3//4*2^(1/2)*pi^(1/2)*b^3//2*c^-1*cos(a*b^-1)*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-3//4*2^(1/2)*pi^(1/2)*b^3//2*c^-1*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1))
@test integrate(x^2*(a+b*arcsin(c*x))^5//2, x) == :(1//3*x^3*(a+b*arcsin(c*x))^5//2+-5//36*b^2*x^3*(a+b*arcsin(c*x))^(1/2)+-5//6*x*b^2*c^-2*(a+b*arcsin(c*x))^(1/2)+5//9*b*c^-3*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^3//2+5//18*b*c^-1*x^2*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^3//2+-15//32*2^(1/2)*pi^(1/2)*b^5//2*c^-3*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1)+-5//864*6^(1/2)*pi^(1/2)*b^5//2*c^-3*cos(3*a*b^-1)*fresnels(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+5//864*6^(1/2)*pi^(1/2)*b^5//2*c^-3*fresnelc(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(3*a*b^-1)+15//32*2^(1/2)*pi^(1/2)*b^5//2*c^-3*cos(a*b^-1)*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2)))
@test integrate(x*(a+b*arcsin(c*x))^5//2, x) == :((1/2)*x^2*(a+b*arcsin(c*x))^5//2+-1//4*c^-2*(a+b*arcsin(c*x))^5//2+-15//32*b^2*x^2*(a+b*arcsin(c*x))^(1/2)+15//64*b^2*c^-2*(a+b*arcsin(c*x))^(1/2)+-15//128*pi^(1/2)*b^5//2*c^-2*cos(2*a*b^-1)*fresnelc(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-15//128*pi^(1/2)*b^5//2*c^-2*fresnels(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(2*a*b^-1)+5//8*b*x*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^3//2)
@test integrate((a+b*arcsin(c*x))^5//2, x) == :(x*(a+b*arcsin(c*x))^5//2+-15//4*x*b^2*(a+b*arcsin(c*x))^(1/2)+5//2*b*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^3//2+-15//8*2^(1/2)*pi^(1/2)*b^5//2*c^-1*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1)+15//8*2^(1/2)*pi^(1/2)*b^5//2*c^-1*cos(a*b^-1)*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2)))
@test integrate(x^2*(a+b*arcsin(c*x))^-1//2, x) == :(-1//12*6^(1/2)*pi^(1/2)*b^-1//2*c^-3*cos(3*a*b^-1)*fresnelc(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-1//12*6^(1/2)*pi^(1/2)*b^-1//2*c^-3*fresnels(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(3*a*b^-1)+1//4*2^(1/2)*pi^(1/2)*b^-1//2*c^-3*cos(a*b^-1)*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+1//4*2^(1/2)*pi^(1/2)*b^-1//2*c^-3*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1))
@test integrate(x*(a+b*arcsin(c*x))^-1//2, x) == :((1/2)*pi^(1/2)*b^-1//2*c^-2*cos(2*a*b^-1)*fresnels(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-1//2*pi^(1/2)*b^-1//2*c^-2*fresnelc(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(2*a*b^-1))
@test integrate((a+b*arcsin(c*x))^-1//2, x) == :(2^(1/2)*pi^(1/2)*b^-1//2*c^-1*cos(a*b^-1)*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+2^(1/2)*pi^(1/2)*b^-1//2*c^-1*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1))
@test integrate(x^2*(a+b*arcsin(c*x))^-3//2, x) == :(-2*b^-1*c^-1*x^2*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-1//2+(1/2)*2^(1/2)*pi^(1/2)*b^-3//2*c^-3*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1)+(1/2)*6^(1/2)*pi^(1/2)*b^-3//2*c^-3*cos(3*a*b^-1)*fresnels(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-1//2*2^(1/2)*pi^(1/2)*b^-3//2*c^-3*cos(a*b^-1)*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-1//2*6^(1/2)*pi^(1/2)*b^-3//2*c^-3*fresnelc(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(3*a*b^-1))
@test integrate(x*(a+b*arcsin(c*x))^-3//2, x) == :(-2*x*b^-1*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-1//2+2*pi^(1/2)*b^-3//2*c^-2*cos(2*a*b^-1)*fresnelc(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+2*pi^(1/2)*b^-3//2*c^-2*fresnels(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(2*a*b^-1))
@test integrate((a+b*arcsin(c*x))^-3//2, x) == :(-2*b^-1*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-1//2+-2*2^(1/2)*pi^(1/2)*b^-3//2*c^-1*cos(a*b^-1)*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+2*2^(1/2)*pi^(1/2)*b^-3//2*c^-1*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1))
@test integrate(x^2*(a+b*arcsin(c*x))^-5//2, x) == :(4*b^-2*x^3*(a+b*arcsin(c*x))^-1//2+-8//3*x*b^-2*c^-2*(a+b*arcsin(c*x))^-1//2+-2//3*b^-1*c^-1*x^2*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-3//2+6^(1/2)*pi^(1/2)*b^-5//2*c^-3*cos(3*a*b^-1)*fresnelc(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+6^(1/2)*pi^(1/2)*b^-5//2*c^-3*fresnels(6^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(3*a*b^-1)+-1//3*2^(1/2)*pi^(1/2)*b^-5//2*c^-3*cos(a*b^-1)*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-1//3*2^(1/2)*pi^(1/2)*b^-5//2*c^-3*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1))
@test integrate(x*(a+b*arcsin(c*x))^-5//2, x) == :(-4//3*b^-2*c^-2*(a+b*arcsin(c*x))^-1//2+8//3*b^-2*x^2*(a+b*arcsin(c*x))^-1//2+-8//3*pi^(1/2)*b^-5//2*c^-2*cos(2*a*b^-1)*fresnels(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-2//3*x*b^-1*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-3//2+8//3*pi^(1/2)*b^-5//2*c^-2*fresnelc(2*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(2*a*b^-1))
@test integrate((a+b*arcsin(c*x))^-5//2, x) == :(4//3*x*b^-2*(a+b*arcsin(c*x))^-1//2+-2//3*b^-1*c^-1*(1+-1*c^2*x^2)^(1/2)*(a+b*arcsin(c*x))^-3//2+-4//3*2^(1/2)*pi^(1/2)*b^-5//2*c^-1*cos(a*b^-1)*fresnelc(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))+-4//3*2^(1/2)*pi^(1/2)*b^-5//2*c^-1*fresnels(2^(1/2)*pi^-1//2*b^-1//2*(a+b*arcsin(c*x))^(1/2))*sin(a*b^-1))
@test integrate((d*x)^5//2*(a+b*arcsin(c*x)), x) == :(2//7*d^-1*(d*x)^7//2*(a+b*arcsin(c*x))+-20//147*b*c^-7//2*d^5//2*Elliptic.F(arcsin(c^(1/2)*d^-1//2*(d*x)^(1/2)),-1)+4//49*b*c^-1*(d*x)^5//2*(1+-1*c^2*x^2)^(1/2)+20//147*b*c^-3*d^2*(d*x)^(1/2)*(1+-1*c^2*x^2)^(1/2))
@test integrate((d*x)^3//2*(a+b*arcsin(c*x)), x) == :(2//5*d^-1*(d*x)^5//2*(a+b*arcsin(c*x))+-12//25*b*c^-5//2*d^3//2*Elliptic.E(arcsin(c^(1/2)*d^-1//2*(d*x)^(1/2)),-1)+4//25*b*c^-1*(d*x)^3//2*(1+-1*c^2*x^2)^(1/2)+12//25*b*c^-5//2*d^3//2*Elliptic.F(arcsin(c^(1/2)*d^-1//2*(d*x)^(1/2)),-1))
@test integrate((d*x)^(1/2)*(a+b*arcsin(c*x)), x) == :(2//3*d^-1*(d*x)^3//2*(a+b*arcsin(c*x))+-4//9*b*c^-3//2*d^(1/2)*Elliptic.F(arcsin(c^(1/2)*d^-1//2*(d*x)^(1/2)),-1)+4//9*b*c^-1*(d*x)^(1/2)*(1+-1*c^2*x^2)^(1/2))
@test integrate((d*x)^-1//2*(a+b*arcsin(c*x)), x) == :(2*d^-1*(d*x)^(1/2)*(a+b*arcsin(c*x))+-4*b*c^-1//2*d^-1//2*Elliptic.E(arcsin(c^(1/2)*d^-1//2*(d*x)^(1/2)),-1)+4*b*c^-1//2*d^-1//2*Elliptic.F(arcsin(c^(1/2)*d^-1//2*(d*x)^(1/2)),-1))
@test integrate((d*x)^-3//2*(a+b*arcsin(c*x)), x) == :(-1*d^-1*(d*x)^-1//2*(2a+2*b*arcsin(c*x))+4*b*c^(1/2)*d^-3//2*Elliptic.F(arcsin(c^(1/2)*d^-1//2*(d*x)^(1/2)),-1))
@test integrate((d*x)^-5//2*(a+b*arcsin(c*x)), x) == :(-1//3*d^-1*(d*x)^-3//2*(2a+2*b*arcsin(c*x))+-4//3*b*c^3//2*d^-5//2*Elliptic.E(arcsin(c^(1/2)*d^-1//2*(d*x)^(1/2)),-1)+4//3*b*c^3//2*d^-5//2*Elliptic.F(arcsin(c^(1/2)*d^-1//2*(d*x)^(1/2)),-1)+-4//3*b*c*d^-2*(d*x)^-1//2*(1+-1*c^2*x^2)^(1/2))

max_stars_repo_path: test/5 Inverse trig functions/5.1 Inverse sine/5.1.2 (d x)^m (a+b arcsin(c x))^n.jl


text:
using Unitful

import PhysicalConstants.CODATA2018: h, k_B, R_∞, c_0, m_e, m_u, e, ε_0, a_0

const E_∞ = R_∞ * c_0 * h
const hc = h * c_0
const Ry = R_∞ * c_0 * h  # Rydberg energy
const αp = 4.5 * 4*π * ε_0 * a_0^3   # Polarisability of hydrogen [F m^2]
const inv_4πε0 = 1. / (4 * π * ε_0)
const mass_H = 1.008 * m_u
const mass_He = 4.003 * m_u
const abund_He = 10^10.99 / 10^12  # From RH

@derived_dimension PerLength Unitful.𝐋^-1
@derived_dimension PerArea Unitful.𝐋^-2
@derived_dimension NumberDensity Unitful.𝐋^-3
@derived_dimension ColumnDensity Unitful.𝐋^-2
@derived_dimension Volume Unitful.𝐋^3
@derived_dimension UnitsIntensity_λ Unitful.𝐋^-1 * Unitful.𝐌 * Unitful.𝐓^-3

"""
    Structure containing atmospheric grid and physical values at grid point
"""
struct Atmosphere
    z::Vector{typeof(1.0u"m")}
    x::Vector{typeof(1.0u"m")}
    y::Vector{typeof(1.0u"m")}
    temperature::Array{typeof(1.0u"K"), 3}
    electron_density::Array{typeof(1.0u"m^-3"), 3}
    hydrogen_populations::Array{typeof(1.0u"m^-3"), 3}
    velocity_z::Array{typeof(1.0u"m*s^-1"), 3}
    velocity_x::Array{typeof(1.0u"m*s^-1"), 3}
    velocity_y::Array{typeof(1.0u"m*s^-1"), 3}
    # Would be nice to include these things in the structure, but I couldn't get it to work
    # nz::Integer
    # nx::Integer
    # ny::Integer
    # Δx::Unitful.Length
    # Δy::Unitful.Length
    # function Atmosphere(z::Vector{<:Unitful.Length{T}},
    #                     x::Vector{<:Unitful.Length{T}},
    #                     y::Vector{<:Unitful.Length{T}}) where T <: AbstractFloat
    #                     # temperature::Array{<:Unitful.Temperature{T}, 3},
    #                     # electron_density::Array{<:NumberDensity{T}, 3},
    #                     # hydrogen_populations::Array{<:NumberDensity{T}, 3}) where T <: AbstractFloat
    #     #Funcy func
    #     nz = length(z)
    #     nx = length(x)
    #     ny = length(y)
    #     Δx = x[2] - x[1]
    #     Δy = y[2] - y[1]
    #     new{T}(z, x, y, nz, nx, ny, Δx, Δy)
    #            # temperature, electron_density, hydrogen_populations,
    #            # nz, nx, ny, Δx, Δy)
    # end
end

"""
    get_atmos()
Reads and slices atmosphere parameters from a bifrost atmosphere. Atmosphere
has to be stored in a hdf5 file. Returns atmosphere dimensions, velocity,
temperature, electron_density and hydrogen populations.

Original author: Ida Risnes Hansen
"""
function get_atmos(file_path; periodic=true, skip=1)
    println("---Extracting atmospheric data---")

    local x, y, z, temperature, electron_density, hydrogen_populations, velocity_z, velocity_x, velocity_y

    h5open(file_path, "r") do atmos
        z = read(atmos, "z")[1:skip:end]*u"m"
        x = read(atmos, "x")[1:skip:end]*u"m"
        y = read(atmos, "y")[1:skip:end]*u"m"

        velocity_z = read(atmos, "velocity_z")[1:skip:end, 1:skip:end, 1:skip:end]*u"m/s"
        velocity_x = read(atmos, "velocity_x")[1:skip:end, 1:skip:end, 1:skip:end]*u"m/s"
        velocity_y = read(atmos, "velocity_y")[1:skip:end, 1:skip:end, 1:skip:end]*u"m/s"

        temperature = read(atmos, "temperature")[1:skip:end, 1:skip:end, 1:skip:end]u"K"
        electron_density = read(atmos, "electron_density")[1:skip:end, 1:skip:end, 1:skip:end]u"m^-3"
        hydrogen_populations = read(atmos, "hydrogen_populations")[1:skip:end, 1:skip:end, 1:skip:end, 1, 1]u"m^-3"
    end

    #=
    if length(size(z)) == 2
        z = z[:,1]
        velocity_x = velocity_x[:,:,:,1]
        velocity_y = velocity_y[:,:,:,1]
        velocity_z = velocity_z[:,:,:,1]
        temperature = temperature[:,:,:,1]
        electron_density = electron_density[:,:,:,1]
        hydrogen_populations = hydrogen_populations[:,:,:,1,1]
    end
    =#

    if z[1] > z[end]
        reverse!(z)
        reverse!(velocity_x, dims=1)
        reverse!(velocity_y, dims=1)
        reverse!(velocity_z, dims=1)
        reverse!(temperature, dims=1)
        reverse!(electron_density, dims=1)
        reverse!(hydrogen_populations, dims=1)
    end

    if x[1] > x[end]
        reverse!(x)
        reverse!(velocity_x, dims=2)
        reverse!(velocity_y, dims=2)
        reverse!(velocity_z, dims=2)
        reverse!(temperature, dims=2)
        reverse!(electron_density, dims=2)
        reverse!(hydrogen_populations, dims=2)
    end

    if y[1] > y[end]
        reverse!(y)
        reverse!(velocity_x, dims=3)
        reverse!(velocity_y, dims=3)
        reverse!(velocity_z, dims=3)
        reverse!(temperature, dims=3)
        reverse!(electron_density, dims=3)
        reverse!(hydrogen_populations, dims=3)
    end

    if periodic
        println("---Periodic boundaries in x and y---")
        # Fix periodic boundaries with 'ghost' values

        # Fix grid
        x_periodic = periodic_borders(x)
        y_periodic = periodic_borders(y)

        # Add ghost layers on each side in x and y
        size_add = (0, 2, 2)

        # Temperature
        temperature_periodic = periodic_borders(temperature)

        # electron_density
        electron_density_periodic = periodic_borders(electron_density)

        # Hydrogen_populations
        hydrogen_populations_periodic = periodic_borders(hydrogen_populations)

        # velocity_z
        velocity_z_periodic = periodic_borders(velocity_z)

        # velocity_z
        velocity_x_periodic = periodic_borders(velocity_x)

        # velocity_z
        velocity_y_periodic = periodic_borders(velocity_y)

        return z, x_periodic, y_periodic, temperature_periodic, electron_density_periodic, hydrogen_populations_periodic, velocity_z_periodic, velocity_x_periodic, velocity_y_periodic
    end

    return z, x, y, temperature, electron_density, hydrogen_populations, velocity_z, velocity_x, velocity_y
end

"""
    periodic(vec::Vector{T}) where T<:Unitful.Quantity

Function to make boundaries of a vector correspond to periodic quantities in the
grid. Returns a new 'periodic' vector which has lenght 2+length(vec)
"""
function periodic_borders(vec::Vector{T}) where T<:Unitful.Quantity

    # Allocate space for periodic vector with same type as original vector
    periodic_vec = Vector{typeof(vec[1])}(undef, length(vec)+2)

    # Step size
    Δl = vec[2] - vec[1]

    # Fix boundaries
    periodic_vec[1] = vec[1] - Δl
    periodic_vec[end] = vec[end] + Δl

    # Fill in the 'body' of the vector
    periodic_vec[2:end-1] .= vec[:]

    return periodic_vec
end

"""
    periodic(arr::Array{T, 3}) where T<:Unitful.Quantity

Function to make boundaries of an array periodic. Returns a new periodic
array which has size (0,2,2)+size(arr)
"""
function periodic_borders(arr::Array{T, 3}) where T<:Unitful.Quantity

    # Allocate space for periodic vector with same type as original vector
    periodic_arr = Array{typeof(arr[1,1,1]), 3}(undef, size(arr).+(0,2,2))

    # Fix inner box
    periodic_arr[:, 2:end-1, 2:end-1] .= arr

    # x-direction
    periodic_arr[:,1,2:end-1] .= arr[:,end,:]
    periodic_arr[:,end,2:end-1] .= arr[:,1,:]

    # y-direction
    periodic_arr[:,2:end-1,end] .= arr[:,:,1]
    periodic_arr[:,2:end-1,1] .= arr[:,:,end]

    # fix corners
    periodic_arr[:,1,1] .= arr[:,end,end]
    periodic_arr[:,1,end] .= arr[:,end,1]
    periodic_arr[:,end,1] .= arr[:,1,end]
    periodic_arr[:,end,end] .= arr[:,1,1]

    return periodic_arr
end

function periodic_borders(arr::Array{T, 4}) where T<:Unitful.Quantity

    # Allocate space for periodic vector with same type as original vector
    periodic_arr = Array{typeof(arr[1,1,1,1]), 4}(undef, size(arr).+(0,0,2,2))

    # Fix inner box
    periodic_arr[:, :, 2:end-1, 2:end-1] .= arr

    # x-direction
    periodic_arr[:,:,1,2:end-1] .= arr[:,:,end,:]
    periodic_arr[:,:,end,2:end-1] .= arr[:,:,1,:]

    # y-direction
    periodic_arr[:,:,2:end-1,end] .= arr[:,:,:,1]
    periodic_arr[:,:,2:end-1,1] .= arr[:,:,:,end]

    # fix corners
    periodic_arr[:,:,1,1] .= arr[:,:,end,end]
    periodic_arr[:,:,1,end] .= arr[:,:,end,1]
    periodic_arr[:,:,end,1] .= arr[:,:,1,end]
    periodic_arr[:,:,end,end] .= arr[:,:,1,1]

    return periodic_arr
end

function periodic_pops(arr::Array{T, 4}) where T<:NumberDensity

    # Allocate space for periodic vector with same type as original vector
    periodic_arr = Array{typeof(arr[1,1,1,1]), 4}(undef, size(arr).+(0,2,2,0))

    # Fix inner box
    periodic_arr[:, 2:end-1, 2:end-1, :] .= arr

    # x-direction
    periodic_arr[:,1,2:end-1,:] .= arr[:,end,:,:]
    periodic_arr[:,end,2:end-1,:] .= arr[:,1,:,:]

    # y-direction
    periodic_arr[:,2:end-1,end,:] .= arr[:,:,1,:]
    periodic_arr[:,2:end-1,1,:] .= arr[:,:,end,:]

    # fix corners
    periodic_arr[:,1,1,:] .= arr[:,end,end,:]
    periodic_arr[:,1,end,:] .= arr[:,end,1,:]
    periodic_arr[:,end,1,:] .= arr[:,1,end,:]
    periodic_arr[:,end,end,:] .= arr[:,1,1,:]

    return periodic_arr
end

ext: jl

max_stars_repo_name: meudnaes/VoronoiRT

max_issues_repo_name: meudnaes/VoronoiRT

max_forks_repo_name: meudnaes/VoronoiRT


text:
# This file is a part of SimilaritySearch.jl
# License is Apache 2.0: https://www.apache.org/licenses/LICENSE-2.0.txt

export jaccard_distance, dice_distance, union_intersection, intersection_distance

"""
    union_intersection(a::T, b::T)

Computes both the size of the unions an the size the intersections of `a` and `b`;
specified as ordered sequences.
"""
function union_intersection(a::T, b::T) where {T <: AbstractVector}
    len_a::Int = length(a)
    len_b::Int = length(b)
    ia::Int = 1
    ib::Int = 1
    intersection_size::Int = 0
    c::Int = 0
    @inbounds while ia <= len_a && ib <= len_b
        c = cmp(a[ia], b[ib])
        if c == 0
            ia += 1
            ib += 1
            intersection_size += 1
        elseif c < 0
            ia += 1
        else
            ib += 1
        end
    end

    return len_a + len_b - intersection_size, intersection_size
end

"""
    jaccard_distance(a, b)::Float64

Computes the Jaccard's distance of `a` and `b` both sets specified as
sorted vectors.
"""

function jaccard_distance(a, b)::Float64
    u, i = union_intersection(a, b)
    return 1.0 - i / u
end

"""
    dice_distance(a, b)::Float64

Computes the Dice's distance of `a` and `b` both sets specified as
sorted vectors.
"""
function dice_distance(a, b)::Float64
    u, i = union_intersection(a, b)
    return 1.0 - 2 * i / (length(a) + length(b))
end

"""
    intersection_distance(a, b)::Float64
(a, b)::Float64

Uses the intersection as a distance function (non-metric)
"""
function intersection_distance(a, b)::Float64
    u, i = union_intersection(a, b)

    return 1.0 - i / min(length(a), length(b))
end


text:
using .Turing: DynamicPPL, Prior

function (alg::ThermInt)(model::DynamicPPL.Model)
    ΔlogZ = @showprogress [evaluate_loglikelihood(model, alg, β) for β in alg.schedule]
    return trapz(alg.schedule, ΔlogZ)
end

function evaluate_loglikelihood(model::DynamicPPL.Model, alg::ThermInt, β::Real)
    powerlogπ = power_logjoint(model, β)
    loglikelihood = get_loglikelihood(model)
    x_init = vec(Array(sample(model, Prior(), 1))) # Bad ugly hack cause I don't know how to sample from the prior
    samples = sample_powerlogπ(powerlogπ, alg, x_init)
    return mean(loglikelihood, samples)
end

function power_logjoint(model, β)
    ctx = DynamicPPL.MiniBatchContext(DynamicPPL.DefaultContext(), β)
    spl = DynamicPPL.SampleFromPrior()
    vi = DynamicPPL.VarInfo(model)
    return function f(z)
        varinfo = DynamicPPL.VarInfo(vi, spl, z)
        model(varinfo, spl, ctx)
        return DynamicPPL.getlogp(varinfo)
    end
end

function get_loglikelihood(model)
    ctx = DynamicPPL.LikelihoodContext()
    spl = DynamicPPL.SampleFromPrior()
    vi = DynamicPPL.VarInfo(model)
    return function f(z)
        varinfo = DynamicPPL.VarInfo(vi, spl, z)
        model(varinfo, spl, ctx)
        return DynamicPPL.getlogp(varinfo)
    end
end


text:
# Solving the Potts model on a SquareLattice

export potts_bondtensor, δ, solve_potts

"""
    potts_bondtensor(T, Val(q), J; digits=5)

`T` is the matrix element type,
`J` is the coupling strength,
`q` is the degree of freedom of each spin,
`digits` will make the floating point numbers to have better numeric properties, it is important to the success of degeneracy counting!
"""
function potts_bondtensor(::Type{T}, ::Val{q}, J; digits=5) where {T, q}
    angles = cos.(2π .* ((1:q) ./ q))
    res = zeros(T, q, q)
    for i=1:q
        for j=1:q
            res[i,j] = T(round(J*angles[mod1(abs(j-i), q)]; digits=5))
        end
    end
    res
end

function δ(::Type{T}, ::Val{q}, n::Int) where {T, q}
    res = zeros(T, fill(q, n)...)
    for i=1:q
        res[fill(i, n)...] = one(T)
    end
    res
end

function sequential_tree(n::Int)
    n == 1 && return 1
    TropicalTensors.ContractionTree(sequential_tree(n-1), n)
end

function solve_potts(::Type{T}, ::Val{q}, lt::SquareLattice, J::Dict; usecuda=false, digits=5) where {T, q}
    # generate tensors
    tensors = Matrix{Any}(undef,lt.Nx, lt.Ny)

    for i=1:lt.Nx
        for j=1:lt.Ny
            v = δ(T, Val(q), 4)
            labels = [(i,j-1)=>(i,j), (i-1,j)=>(i,j), (i,j)=>(i,j+1), (i,j)=>(i+1,j)]
            mask = [j==1, i==1, j==lt.Ny, i==lt.Nx]
            if i!=lt.Nx
                b = potts_bondtensor(T, Val(q), J[(i,j)=>(i+1,j)]; digits=digits)
                v = tensorcontract((1,2,3,4), v, (4,5), b, (1,2,3,5))
            end
            if j!=lt.Ny
                a = potts_bondtensor(T, Val(q), J[(i,j)=>(i,j+1)]; digits=digits)
                v = tensorcontract((1,2,3,4), v, (3,5), a, (1,2,5,4))
            end
            w = dropdims(sum(v, dims=findall(mask)); dims=(findall(mask)...,))
            tensors[i,j] = LabeledTensor(w, labels[(!).(mask)])
        end
    end
    tn = TensorNetwork(tensors)
    if usecuda
        tn = TropicalTensors.togpu(tn)
    end

    # construct contraction tree
    tree = sequential_tree(length(tensors))

    # contract
    Array(TropicalTensors.contract(tn, tree).array)[]
end

function potts_randpm_J(lt::SquareLattice)
    d = Dict{Pair{Tuple{Int,Int},Tuple{Int,Int}},Int}()
    for i=1:lt.Nx
        for j=1:lt.Ny
            if i!=lt.Nx
                d[(i,j)=>(i+1,j)] = rand([1,-1])
            end
            if j!=lt.Ny
                d[(i,j)=>(i,j+1)] = rand([1,-1])
            end
        end
    end
    return d
end


text:
"""
    MIPVerify(optimizer)

MIPVerify computes maximum allowable disturbance using mixed integer linear programming.

# Problem requirement
1. Network: any depth, ReLU activation
2. Input: hyperrectangle
3. Output: PolytopeComplement

# Return
`AdversarialResult`

# Method
MILP encoding. Use presolve to compute a tight node-wise bounds first.
Default `optimizer` is `GLPKSolverMIP()`.

# Property
Sound and complete.

# Reference

V. Tjeng, K. Xiao, and R. Tedrake,
["Evaluating Robustness of Neural Networks with Mixed Integer Programming,"
*ArXiv Preprint ArXiv:1711.07356*, 2017.](https://arxiv.org/abs/1711.07356)

[https://github.com/vtjeng/MIPVerify.jl](https://github.com/vtjeng/MIPVerify.jl)
"""
@with_kw struct MIPVerify <: Solver
    optimizer = GLPK.Optimizer
end

function solve(solver::MIPVerify, problem::Problem)
    model = Model(solver)
    z = init_vars(model, problem.network, :z, with_input=true)
    δ = init_vars(model, problem.network, :δ, binary=true)
    # get the pre-activation bounds:
    model[:bounds] = get_bounds(problem, false)
    model[:before_act] = true

    add_set_constraint!(model, problem.input, first(z))
    add_complementary_set_constraint!(model, problem.output, last(z))
    encode_network!(model, problem.network, BoundedMixedIntegerLP())
    o = max_disturbance!(model, first(z) - problem.input.center)
    optimize!(model)
    if termination_status(model) == OPTIMAL
        return AdversarialResult(:violated, value(o))
    end
    return AdversarialResult(:holds)
end


text:
export MDFDatasetStore, MDFStore, addStudy, getMDFStudyFolderName, calibdir, getMDFStore, getCalibStudy

struct MDFDatasetStore <: DatasetStore
  path::String

  function MDFDatasetStore(path::String)
    path = abspath(path)
    mkpath(path)
    mkpath(joinpath(path,"measurements"))
    mkpath(joinpath(path,"reconstructions"))
    mkpath(joinpath(path,"calibrations"))
    #try_chmod(joinpath(path,"path"), 0o777, recursive=true) # we should get rid of this
    return new(path)
  end
end

if ispath("/opt/mpidata/Bruker")
  const MDFStore = MDFDatasetStore("/opt/data/Bruker")
end
path(e::Experiment{MDFDatasetStore}) = joinpath( path(e.study), string(e.num)*".mdf" )
path(s::Study{MDFDatasetStore}, numExp::Integer) = joinpath(path(s),string(numExp)*".mdf")
iscalib(e::Experiment{MDFDatasetStore}) = e.study.foldername ==
                             ".."*Base.Filesystem.path_separator*"calibrations"
readonly(::MDFDatasetStore) = false
changeParam(e::Experiment{MDFDatasetStore}, paramName::AbstractString, paramValue) =
               changeParam(path(e), paramName, paramValue)

studydir(d::MDFDatasetStore) = joinpath(d.path,"measurements")
calibdir(d::MDFDatasetStore) = joinpath(d.path,"calibrations")

function getMDFStore(study::Study{MDFDatasetStore})
    return study.store
end

function getMDFStore(experiment::Experiment{MDFDatasetStore})
    return getMDFStore(experiment.study)
end

function getStudy(d::MDFDatasetStore, studyfolder::String)
  study = nothing
  studypath = joinpath( studydir(d), studyfolder)
  if length(studyfolder) >= 15 &&
     isascii(studyfolder[1:15]) &&
     all([tryparse(Int,studyfolder[l:l])!=nothing for l=union(1:8,10:15)])

    w = split(studyfolder,'_')
    dateStr = w[1]
    timeStr = w[2]
    date = DateTime(string(dateStr[1:4],"-",dateStr[5:6],"-",dateStr[7:8],"T",
			   timeStr[1:2],":",timeStr[3:4],":",timeStr[5:6]))
    name = join(w[3:end],"_")
  else
    date = Dates.unix2datetime(stat(studypath).mtime)
    name = studyfolder
  end

  subject = ""
  study = Study(d, name, studyfolder, date, subject )
  return study
end

function getCalibStudy(d::MDFDatasetStore)
  return Study(d, "calibrations";
       foldername=".."*Base.Filesystem.path_separator*"calibrations")
end

function getExperiments(s::Study{MDFDatasetStore})
  files = readdir(path(s))

  experiments = Experiment[]

  @debug "Time for get Experiments"
  for file in files
    prefix, ext = splitext(file)
    if !isdir(file) && tryparse(Int64,prefix) != nothing &&
       (ext == ".mdf" || ext == ".hdf" || ext == ".h5") &&
       isfile(joinpath(path(s),file))
       num = tryparse(Int64, prefix)
       if num != nothing
        exp = getExperiment(s, num)
        push!(experiments, exp)
       end
    end
  end
  sort!(experiments,lt=(a,b)->(a.num < b.num))
  return experiments
end

getMDFStudyFolderName(study::Study) = getMDFStudyFolderName(study.name, study.date)

function getMDFStudyFolderName(name::String, date::DateTime)
  return string(split(string(date),"T")[1][union(1:4,6:7,9:10)],"_",
                split(string(date),"T")[2][union(1:2,4:5,7:8)],"_",name)
end

function addStudy(d::MDFDatasetStore, study::Study)
  studypath = joinpath( studydir(d), getMDFStudyFolderName(study))
  mkpath(studypath)
  try_chmod(studypath, 0o770, recursive=true)

  nothing
end

function Base.empty!(d::MDFDatasetStore)
  studies = getStudies(d)
  remove.(studies)
  rm(calibdir(d), recursive=true)
  mkpath(calibdir(d))
end

function getNewCalibNum(d::MDFDatasetStore)
  return getNewNumInFolder(calibdir(d))
end

function getNewCalibPath(d::MDFDatasetStore)
    calibNum = getNewCalibNum(d)
    path = joinpath(calibdir(d),string(calibNum)*".mdf")
    # touch new mdf file
    touch(path)
    try_chmod(path, 0o660)
    return path
end


text:
include("lib_for_robot.jl")
function task8(r)
    i=0
    side=West
    while isborder(r,Nord)==true
        for tmp in 0:i
            move!(r,side)
        end
        side=reverse(side)
        i+=1
    end
end


text:
function compare_to(obj::Enum, arg0::Enum)
    return jcall(obj, "compareTo", jint, (Enum,), arg0)
end

function describe_constable(obj::Enum)
    return jcall(obj, "describeConstable", Optional, ())
end

function equals(obj::Enum, arg0::Object)
    return jcall(obj, "equals", jboolean, (Object,), arg0)
end

function get_declaring_class(obj::Enum)
    return jcall(obj, "getDeclaringClass", Class, ())
end

function hash_code(obj::Enum)
    return jcall(obj, "hashCode", jint, ())
end

function motion(obj::Direction, arg0::Mesh_Node, arg1::jdouble, arg2::jdouble)
    return jcall(obj, "motion", Vector3D, (Mesh_Node, jdouble, jdouble), arg0, arg1, arg2)
end

function name(obj::Enum)
    return jcall(obj, "name", JString, ())
end

function neighbor_across_index(obj::Direction, arg0::Mesh_Node)
    return jcall(obj, "neighborAcrossIndex", jint, (Mesh_Node,), arg0)
end

function neighbor_along_index(obj::Direction, arg0::Mesh_Node)
    return jcall(obj, "neighborAlongIndex", jint, (Mesh_Node,), arg0)
end

function next(obj::Direction)
    return jcall(obj, "next", Direction, ())
end

function ordinal(obj::Enum)
    return jcall(obj, "ordinal", jint, ())
end

function to_string(obj::Enum)
    return jcall(obj, "toString", JString, ())
end

function value_of(::Type{Direction}, arg0::JString)
    return jcall(Direction, "valueOf", Direction, (JString,), arg0)
end

function value_of(::Type{Enum}, arg0::Class, arg1::JString)
    return jcall(Enum, "valueOf", Enum, (Class, JString), arg0, arg1)
end

function values(::Type{Direction})
    return jcall(Direction, "values", Vector{Direction}, ())
end


text:
struct RibbonGeometry <: Gadfly.GeometryElement
    default_statistic::Gadfly.StatisticElement
    tag::Symbol
end
RibbonGeometry(default_statistic=Gadfly.Stat.identity(); tag=empty_tag) =
        RibbonGeometry(default_statistic, tag)

const ribbon = RibbonGeometry

default_statistic(geom::RibbonGeometry) = geom.default_statistic

element_aesthetics(::RibbonGeometry) = [:x, :ymin, :ymax, :color]

function render(geom::RibbonGeometry, theme::Gadfly.Theme, aes::Gadfly.Aesthetics)
    Gadfly.assert_aesthetics_defined("Geom.ribbon", aes, :x, :ymin, :ymax)
    Gadfly.assert_aesthetics_equal_length("Geom.ribbon", aes,
                                          element_aesthetics(geom)...)

    default_aes = Gadfly.Aesthetics()
    default_aes.color = discretize_make_ia(RGB{Float32}[theme.default_color])
    aes = inherit(aes, default_aes)

    aes_x, aes_ymin, aes_ymax = concretize(aes.x, aes.ymin, aes.ymax)

    if length(aes.color) == 1 &&
        !(isa(aes.color, IndirectArray) && length(filter(!ismissing, aes.color.values)) > 1)
        max_points = collect(zip(aes_x, aes_ymax))
        sort!(max_points, by=first)

        min_points = collect(zip(aes_x, aes_ymin))
        sort!(min_points, by=first, rev=true)

        ctx = compose!(
            context(),
            Compose.polygon([collect(chain(min_points, max_points))]),
            fill(theme.lowlight_color(aes.color[1])))
    else
        XT, YT = eltype(aes_x), promote_type(eltype(aes_ymin), eltype(aes_ymax))
        max_points = Dict{RGB{Float32}, Vector{(Tuple{XT, YT})}}()
        for (x, y, c) in zip(aes_x, aes_ymax, aes.color)
            if !haskey(max_points, c)
                max_points[c] = Array{Tuple{XT, YT}}(0)
            end
            push!(max_points[c], (x, y))
        end

        min_points = Dict{RGB{Float32}, Vector{(Tuple{XT, YT})}}()
        for (x, y, c) in zip(aes.x, aes.ymin, aes.color)
            if !haskey(min_points, c)
                min_points[c] = Array{Tuple{XT, YT}}(0)
            end
            push!(min_points[c], (x, y))
        end

        for c in keys(max_points)
            sort!(max_points[c], by=first)
            sort!(min_points[c], by=first, rev=true)
        end

        ctx = compose!(
            context(),
            Compose.polygon([collect((Tuple{XT, YT}), chain(min_points[c], max_points[c]))
                     for c in keys(max_points)], geom.tag),
            fill([theme.lowlight_color(c) for c in keys(max_points)]))
    end

    return compose!(
        ctx,
        svgclass("geometry"),
        stroke(nothing),
        linewidth(theme.line_width))
end


text:
function write_input(	file_path::String,
						data_file_path::String,
						model::String,
						number_of_components::Int64,
						Lx::Float64,
						Ly::Float64,
						Lz::Float64,
						kmin::Int64,
						number_of_de_bins::Int64,
						ub_de::Float64,
						lb_m::Float64,
						ub_m::Float64,
						lb_c::Float64,
						ub_c::Float64,
						lb_az::Float64,
						ub_az::Float64,
						number_of_abc_samples::Int64,
						gamma_initial::Float64,
						gamma_adaptive::Bool,
						delta_gamma::Float64,
						weighting_scheme::String,
						ub_average_number_of_trials::Int64,
						output_file_path::String)

	file_stream::IOStream = open(file_path, "w")

	@printf(file_stream, "%s", "<input>\n")

	write_key(file_stream, "data_file_path", data_file_path)
	write_key(file_stream, "model", model)
	write_key(file_stream, "number_of_components", number_of_components)
	write_key(file_stream, "Lx", Lx)
	write_key(file_stream, "Ly", Ly)
	write_key(file_stream, "Lz", Lz)
	write_key(file_stream, "kmin", kmin)
	write_key(file_stream, "number_of_de_bins", number_of_de_bins)
	write_key(file_stream, "ub_de", ub_de)
	write_key(file_stream, "lb_m", lb_m)
	write_key(file_stream, "ub_m", ub_m)
	write_key(file_stream, "lb_c", lb_c)
	write_key(file_stream, "ub_c", ub_c)
	write_key(file_stream, "lb_az", lb_az)
	write_key(file_stream, "ub_az", ub_az)
	write_key(file_stream, "number_of_abc_samples", number_of_abc_samples)
	write_key(file_stream, "gamma_initial", gamma_initial)
	write_key(file_stream, "gamma_adaptive", gamma_adaptive)
	write_key(file_stream, "delta_gamma", delta_gamma)
	write_key(file_stream, "weighting_scheme", weighting_scheme)
	write_key(file_stream, "ub_average_number_of_trials", ub_average_number_of_trials)
	write_key(file_stream, "output_file_path", output_file_path)

	@printf(file_stream, "%s", "</input>")

	close(file_stream)

	nothing
end


text:
using Behavior: suggestmissingsteps, ParseOptions

parseoptions = ParseOptions(allow_any_step_order=true)
suggestmissingsteps(joinpath(@__DIR__,
    "behaviour/features/connection/database.feature"),
    joinpath(@__DIR__, "behaviour/connection/database"),
    parseoptions=parseoptions)


text:
function evaluate_kinetics_model(t,x,data_dictionary)

    # get stuff from the data_dictionary -
    stochiometric_matrix = data_dictionary["stochiometric_matrix"]
    number_of_compartments = data_dictionary["number_of_compartments"]
    number_of_states_per_compartment = data_dictionary["number_of_states_per_compartment"]
    number_of_rates_per_compartment = data_dictionary["number_of_rates_per_compartment"]
    compartment_volume_array = data_dictionary["compartment_volume_array"]

    # what is my kinetics function pointer?
    kinetics_function_pointer = data_dictionary["kinetics_function_pointer"]

    # assemble the overall rate vector -
    overall_kinetics_vector = Array{Float64,1}()
    for compartment_index = 1:number_of_compartments

        # calc the rates -
        rates_in_this_compartment = kinetics_function_pointer(t,x,compartment_index,data_dictionary)
        volume = compartment_volume_array[compartment_index]
        rate_array = stochiometric_matrix*(rates_in_this_compartment*volume)

        # package -
        for value in rate_array
            push!(overall_kinetics_vector,value)
        end
    end

    # return -
    return overall_kinetics_vector
end

function evaluate_transport_model(t,x,data_dictionary)

    # get stuff from the data_dictionary -
    number_of_compartments = data_dictionary["number_of_compartments"]
    number_of_states_per_compartment = data_dictionary["number_of_states_per_compartment"]

    # what is my transport function pointer?
    transport_function_pointer = data_dictionary["transport_function_pointer"]

    # assemble transport terms -
    overall_transport_vector = Array{Float64,1}()
    for compartment_index = 1:number_of_compartments

        # calc the transport terms -
        compartment_transport_terms = transport_function_pointer(t,x,compartment_index,data_dictionary)
        for value in compartment_transport_terms
            push!(overall_transport_vector,value)
        end
    end

    # return -
    return overall_transport_vector
end

function balances(dx,x,data_dictionary,t)

    # what is my system size?
    compartment_volume_array = data_dictionary["compartment_volume_array"]
    number_of_states_per_compartment = data_dictionary["number_of_states_per_compartment"]
    number_of_compartments = data_dictionary["number_of_compartments"]
    number_of_states = number_of_states_per_compartment*number_of_compartments

    # compute mass matrix -
    mass_vector = Array{Float64,1}()
    for compartment_index = 1:number_of_compartments
        volume = compartment_volume_array[compartment_index]
        for state_index = 1:number_of_states_per_compartment
            push!(mass_vector,volume)
        end
    end

    # compute the transport, and kinetics terms -
    transport_terms = evaluate_transport_model(t,x,data_dictionary)
    kinetic_terms = evaluate_kinetics_model(t,x,data_dictionary)

    # compute the right hand side of the balances -
    dxdt = transport_terms + kinetic_terms

    # package -
    for index = 1:number_of_states
        dx[index] = mass_vector[index]*dxdt[index]
    end
end

max_stars_repo_name: varnerlab/N-Compartment-Chip-Model

max_issues_repo_name: varnerlab/N-Compartment-Chip-Model

max_forks_repo_name: varnerlab/N-Compartment-Chip-Model


text:
function bubblesort!(data::Array)
	for i in length(data) - 1 : -1 : 1
		for j in i : length(data) - 1
			if data[j] > data[j + 1]
				data[j], data[j + 1] = data[j + 1], data[j]
			end
		end
	end
end


text:
using Counters
export jonah_solver, score_guess, best_guess, filter_space

"""
`score_guess(g::Int, search_space::Vector{Int}`: Given a code guess `g` and
a list of code `search_space` partition `search_space` based on the score of
`(g,c)` and return the size of the largest part.
"""
function score_guess(g::Int, search_space::Vector{Int})
    if length(search_space) <= 1
        return length(search_space)
    end

    count = Counter{Tuple{Int,Int}}()

    for c in search_space
        bm = bm_count(g, c)
        count[bm] += 1
    end

    return sum(t * t for t in values(count))
    # return maximum(values(count))
end

"""
`best_guess(search_space::Vector{Int}` chooses a code from `search_space`
that minimizes the score returned by `score_guess`.
"""
function best_guess(search_space::Vector{Int}, full_list::Bool = false)
    if length(search_space) == 1
        return search_space[1]
    end

    best_score = length(search_space)^2
    best_g = search_space[1]

    candidates = search_space
    if full_list
        candidates = collect(0:9999)
    end
    shuffle!(candidates)

    ## DEBUG ##
    # println("\tConsidering $(length(candidates)) candidates")

    for g in candidates
        score = score_guess(g, search_space)
        if score < best_score
            best_score = score
            best_g = g
            ## DEBUG ##
            # println("\t\tImproved guess to $(string4(g)) with score $best_score")
        end
    end

    ## DEBUG ##
    # if !in(best_g,search_space)
    #     println("\t\tNot in the search space!\n")
    # else
    #     println()
    # end

    return best_g
end

"""
`filter_space(g::Int, bm::Tuple{Int,Int}, search_space::Vector{Int})`
returns a shortened copy of `search_space` of codes `c` such that
`bm_count(g,c)==bm`.
"""
function filter_space(g::Int, bm::Tuple{Int,Int}, search_space::Vector{Int})
    [c for c in search_space if bm_count(g, c) == bm]
end

"""
`jonah_solver(code::Int, verbose::Bool=true, full_list_limit=0)` implements another solving
strategy proposed by my son.
"""
function jonah_solver(code::Int, verbose::Bool = true, full_list_limit::Int = 0)
    ss = collect(0:9999)
    shuffle!(ss)
    steps = 0

    while true
        if steps == 0
            g = random_code()
        elseif steps <= full_list_limit
            g = best_guess(ss, true)
        else
            g = best_guess(ss, false)
        end
        steps += 1
        bm = bm_count(g, code)
        ss = filter_space(g, bm, ss)

        if verbose
            print("Guess $steps:\t", string4(g), "\t", bm)
            println("\tsearch space size is now ", length(ss))
        end

        if bm == (4, 0)
            if verbose
                println("Solved! Code is $(string4(g))")
            end
            return steps
        end
    end
end


text:
# Standard rectlin layer: f(A,x,b)=rectlin(A*x+b)
# Note that the bias (a column vector) gets expanded here to match the dimension of A*x

FabsAXplusBias(A,X,b)=begin; a=A*X+b*ones(1,size(X,2)); return (abs(a),sign(a)); end

function FabsAXplusBias_inplace(value,aux,A,X,b)
    a=A*X+b*ones(1,size(X,2))
    copy!(value,abs(a))
    copy!(aux,sign(a))
end

function DabsAXplusBias(derivativeIDX,f_c,faux_c,grad_c,grad_n,A,X,b)
    if derivativeIDX==1
        axpy!(1.0,(grad_c.*faux_c)*X',grad_n)
    elseif derivativeIDX==2
        axpy!(1.0,A'*(grad_c.*faux_c),grad_n)
    elseif derivativeIDX==3
        axpy!(1.0,sum(grad_c.*faux_c,2),grad_n)
    end
end

if PROC=="GPU"

    function FabsAXplusBias_inplace(value,aux,A::CudaArray,X::CudaArray,b::CudaArray)
        FAXplusBias_inplace(value,aux,A,X,b)
        copy!(aux,value)
        abs!(value,value)
    end

    function DabsAXplusBias(derivativeIDX,f_c,faux_c,grad_c,grad_n,A::CudaArray,X::CudaArray,b::CudaArray)
        tmp=CudaArray(Float64,size(grad_c)); fill!(tmp,0.0)
        xsigny_update!(grad_c,faux_c,tmp)
        if derivativeIDX==1
            gemm!('N','T',1.0,tmp,X,1.0,grad_n)
        elseif derivativeIDX==2
            gemm!('T','N',1.0,A,tmp,1.0,grad_n)
        elseif derivativeIDX==3
            ons=CudaArray(Float64,(size(X,2),1)); fill!(ons,1.0)
            gemm!('N','N',1.0,tmp,ons,1.0,grad_n)
            free(ons)
        end
        free(tmp)
    end

end

Derivative[FabsAXplusBias]=DabsAXplusBias
Inplace[FabsAXplusBias]=FabsAXplusBias_inplace

absAXplusBias(A,X,b)=ADnode(FabsAXplusBias,[A X b])
export absAXplusBias

max_stars_repo_name: davidbarber/AutoDiff

max_issues_repo_name: davidbarber/AutoDiff

max_forks_repo_name: davidbarber/AutoDiff


text:
abstract type DataItem end

Base.Broadcast.broadcastable(obj::DataItem) = Ref(obj)

include(joinpath("dataitem", "variable.jl"))
include(joinpath("dataitem", "variablestd.jl"))


text:
module Match
using MLStyle.Err
using MLStyle.Private

export @match, @def, Pattern, Case, Failed, failed, PatternDef, pattern_match, app_pattern_match, register_app_pattern, register_meta_pattern

struct Failed end
failed = Failed()

struct Pattern
    shape
    guard
end

struct Case
    patterns :: Vector{Pattern}
    body
end

# """
# e.g:
# register_meta_pattern((expr :: Expr) -> <conditional>) do  expr, guard, tag, mod
#   <return quote>
# end
# """
global meta_dispatchers = Vector{Tuple{Function, Function}}()

# """
# e.g
#
# register_app_pattern(ty) do args, guard, tag, mod
#     <return quote>
# end
# where `ty` is constructor or any other custom pattern(see @pattern)
# """
global app_dispatchers = Dict{Any, Function}()

global _count = 0
function mangling(apply, repr_ast)
    global _count = _count + 1
    let symbol = Symbol("<", repr(repr_ast), ".", _count, ">")
        ret = apply(symbol)
        global _count = _count - 1
        ret
    end
end

@inline function collect_guard(arg)
    if isa(arg, Expr) && arg.head == :curly
    let args = arg.args
        Pattern(args[1],
                Expr(:block,
                     reduce( (a, b) -> Expr(:&&, a, b), args[2:end])
                     ))
    end
    else
        Pattern(arg, nothing)
    end
end

function collect_fallthrough(c :: Channel, arg)

    if isa(arg, Expr) && arg.head == :call && arg.args[1] == :|

        let nested = arg.args[2:end-1], last = collect_guard(arg.args[end])

            if isempty(nested)
                put!(c, last)
            else
                foreach(nested) do n
                    collect_fallthrough(c, n)
                end
                put!(c, last)
            end

        end

    else
        put!(c, collect_guard(arg))
    end
end

function collect_fallthrough(arg)
    Channel(c -> collect_fallthrough(c, arg))
end

_warned = false
function merge_cases(cases :: Vector{Case})

    global _warned
    if !_warned
        @warn "Pattern optimization not implemented yet."
        _warned = true
    end

    cases
end

pattern_match_maker(tag :: Symbol, case :: Case, mod :: Module) =
    if isempty(case.patterns)
        InternalException("Internal Error 0") |> throw
    else let body = case.body,
             cond = map(case.patterns) do pattern
                    pattern_match(pattern.shape, pattern.guard, tag, mod)
                    end |>
                    function (last)
                        reduce((a, b) -> Expr(:||, a, b), last)
                    end
        quote
            if $cond
                $(case.body)
            else
                $failed
            end
        end
        end
    end

function make_case(arg)
    if !(arg.head == :call && arg.args[1] == :(=>))
            SyntaxError("A case should be something like <pattern> => <body>") |> throw
    end

    let args = arg.args, pattern = args[2], body = args[3]
        Case(append!([], collect_fallthrough(pattern)), body)
    end
end

function make_cases(args)
    map(args) do arg
        if isa(arg, LineNumberNode)
            arg
        else
            make_case(arg)
        end
    end
end

function make_match_body(
                tag,
                tag_sym,
                mod :: Module,
                cases)

    final = quote
                throw(($InternalException)("Non-exhaustive pattern found!"))
            end
    mangled = Symbol("case", ".", "test")

    foldr(cases, init=final) do case, last
        if isa(case, LineNumberNode)
            Expr(:block, case, last)
        else
        pattern_match_maker(tag_sym, case, mod) |>
        function (expr)
            quote
                let $mangled =
                    let
                        $expr
                    end
                if $mangled === $failed
                    $last
                else
                    $mangled
                end
                end
            end
        end
        end

    end |>

    function (quoted)
        quote
          let $tag_sym = $tag
            $quoted
          end
        end
    end

end

macro def(fn_name, pattern_def)
    if !isa(pattern_def, Expr) || !(pattern_def.head in (:braces, :bracescat, :block))
        SyntaxError("Invalid leading marker of match body.") |> throw
    end

    mangling(fn_name) do arg_prefix

        erl_dispatcher = Dict()
        cases = make_cases(filter(it -> !isa(it, LineNumberNode), pattern_def.args))
        new_cases = []

        foreach(cases) do case
            if length(case.patterns) == 1
                append!(new_cases, map(pat -> Case([pat], case.body), case.patterns))
            else
                push!(new_cases, case)
            end
        end

        foreach(new_cases) do case
            dispatch_key =
                begin
                    pattern = case.patterns[1]
                    if !(isa(pattern.shape, Expr) && pattern.shape.head == :tuple)
                        1
                    else
                        length(pattern.shape.args)
                    end
                end

            dispatch_value = get(erl_dispatcher, dispatch_key) do
                erl_dispatcher[dispatch_key] = []
            end

            push!(dispatch_value, case)

        end

        map(collect(erl_dispatcher)) do (argnum, cases)
            map(1:argnum) do arg_idx
                Symbol(arg_prefix, "[", arg_idx, "]")
            end |>
            function (args)
                body =
                    if length(args) > 1
                        make_match_body(Expr(:tuple, args...), arg_prefix, __module__, cases)
                    elseif length(args) === 1
                        make_match_body(args[1], arg_prefix, __module__, cases)
                    else
                        cases[1].body
                    end

                :($fn_name($(args...)) = $body)
            end
        end |>
        function (fns)
            Expr(:block, fns..., fn_name) |> esc
        end
    end

end

macro match(target, pattern_def)
    if !isa(pattern_def, Expr) || !(pattern_def.head in (:braces, :bracescat, :block))
        SyntaxError("Invalid leading marker of match body.") |> throw
    end

    mangling(target) do tag_sym
        cases = make_cases(pattern_def.args)
        make_match_body(target, tag_sym, __module__, cases) |> esc
    end
end

function pattern_match(expr :: Expr, guard, tag, mod :: Module)

    for (dispatcher_test, dispatch) in meta_dispatchers
        if dispatcher_test(expr)
            return dispatch(expr, guard, tag, mod)
        end
    end
    PatternUnsolvedException(expr) |> throw

end

function app_pattern_match(destructor, args, guard, tag, mod :: Module)
    global app_dispatchers
    fn =
        let destructor = get_most_union_all(destructor, mod)
                get(app_dispatchers, destructor, nothing)
        end

    if fn === nothing
        PatternUnsolvedException(:($destructor($(args...)))) |> throw
    else
        fn(args, guard, tag, mod)
    end

end

function register_meta_pattern(dispatch :: Function, dispatcher_test :: Function)
    global meta_dispatchers
    push!(meta_dispatchers, (dispatcher_test, dispatch));
end

function register_app_pattern(dispatch :: Function, destructor :: Any)
    global app_dispatchers
    push!(app_dispatchers, (destructor => dispatch))
end

# """
# builtin meta pattern(for application pattern)
# """
register_meta_pattern(expr :: Expr -> expr.head === :call) do expr, guard, tag, mod
    destructor = expr.args[1]
    app_pattern_match(destructor, expr.args[2:end], guard, tag, mod)
end

# """
# builtin application pattern(for dictionaries)
#
# x = "9"
# dict = Dict(1 => Dict(x => 3), 2 => 3)
#
# @match dict begin
#     Dict(1 => Dict(&x => a), 2 =>b) => a == b
# end
#
# # => true
#
# """
register_app_pattern(Dict) do args, guard, tag, mod

    matching =
        map(args) do kv
            if !(isa(kv, Expr) && kv.head === :call && (@eval mod $(kv.args[1])) === Pair)
                SyntaxError("Dictionary destruct must take patterns like Dict(<expr> => <pattern>)") |> throw
            end
            let (k, v) = kv.args[2:end]
                mangling(tag) do tag!
                    let tag! = Symbol(tag!, "[", k, "]"),
                        action = pattern_match(v, nothing, tag!, mod)

                        quote
                            $tag! = $get($tag, $k) do
                                    $failed
                            end
                            if $failed !== $tag!
                                $action
                            else
                                false
                            end
                        end
                    end
                end
            end
        end |>
        function (last)
            reduce((a, b) -> Expr(:&&, a, b), last, init=:($isa($tag, $Dict)))
        end

    check_ty = :($isa($tag, $Dict))

    if guard === nothing
        quote
            $check_ty && $matching
        end
    else
        quote
            $check_ty && $matching && $guard
        end
    end
end

register_app_pattern(in) do args, guard, tag, mod

    pattern, name = args

    let pat1 = pattern_match(pattern, nothing, tag, mod),
        pat2 = quote
                  $name = $tag
                  true
              end

        :($pat1 && $pat2) |>
        function (last)
            if guard === nothing
                last
            else
                :($last && $guard)
            end
        end
    end
end

module PatternDef
    import MLStyle.Match: register_app_pattern, register_meta_pattern

    App  = register_app_pattern
    Meta = register_meta_pattern
end

end # module


text:
# Gradient tests for adjoint extended modeling
# Author: Philipp Witte, pwitte3@gatech.edu
# Date: April 2020
#

using JUDI, SegyIO, JOLI, Flux, JUDI4Flux, Test
using ImageFiltering, LinearAlgebra, Random

Random.seed!(11)

# Set up model structure
n = (120, 100)   # (x,y,z) or (x,z)
d = (10., 10.)
o = (0., 0.)

# Velocity [km/s]
v = ones(Float32,n) .+ 0.4f0
v[:, Int(round(end/2)):end] .= 4f0
v0 = imfilter(v, Float32.(Kernel.gaussian(10)))

# Slowness squared [s^2/km^2]
m = (1f0 ./ v).^2
m0 = (1f0 ./ v0).^2

# Setup info and model structure
nsrc = 1	# number of sources
model = Model(n, d, o, m)

# Set up receiver geometry
nxrec = 120
xrec = range(50f0, stop=1150f0, length=nxrec)
yrec = 0f0
zrec = range(50f0, stop=50f0, length=nxrec)

# receiver sampling and recording time
time = 1000f0   # receiver recording time [ms]
dt = 1f0    # receiver sampling interval [ms]

# Set up receiver structure
recGeometry = Geometry(xrec, yrec, zrec; dt=dt, t=time, nsrc=nsrc)

# setup wavelet
f0 = 0.01f0     # MHz
wavelet = ricker_wavelet(time, dt, f0)

# Set up info structure for linear operators
ntComp = get_computational_nt(recGeometry, model)
info = Info(prod(n), nsrc, ntComp)

# return linearized data as Julia array
opt = Options(return_array=true, dt_comp=dt, sum_padding=true)

# Linear operators
Pr = judiProjection(info, recGeometry)
A_inv = judiModeling(info, model; options=opt)
Pw = judiLRWF(info, wavelet)
F = Pr*A_inv*adjoint(Pw)

#####################################################################################

G = ExtendedQAdjoint(F)

misfit(y, m, x) = Flux.mse(G(y, m), x)

function loss(y, m, x)
    f = misfit(y, m, x)
    gs = gradient(() -> misfit(y, m, x), params(y, m))
    return f, gs[y], gs[m]
end

# Nonlinear modeling
m = reshape(m, n[1], n[2], 1, 1)
x = randn(Float32, n[1], n[2], 1, 1)
y = randn(Float32, recGeometry.nt[1], nxrec, 1, 1)
y0 = randn(Float32, recGeometry.nt[1], nxrec, 1, 1)
dy = y - y0

# Gradient test for extended modeling: weights
f0, g = loss(y0, m, x)[1:2]
h = .1f0
maxiter = 6

err1 = zeros(Float32, maxiter)
err2 = zeros(Float32, maxiter)

print("\nGradient test extended source weights\n")
for j=1:maxiter
    f = loss(y0 + h*dy, m, x)[1]
    err1[j] = abs(f - f0)
    err2[j] = abs(f - f0 - h*dot(dy, g))
    print(err1[j], "; ", err2[j], "\n")
    global h = h/2f0
end

@test isapprox(err1[end] / (err1[1]/2^(maxiter-1)), 1f0; atol=1f1)
@test isapprox(err2[end] / (err2[1]/4^(maxiter-1)), 1f0; atol=1f1)

# Gradient test for extended modeling: model
y = randn(Float32, recGeometry.nt[1], nxrec, 1, 1)
m = reshape(m, n[1], n[2], 1, 1)
m0 = reshape(m0, n[1], n[2], 1, 1)
dm = m - m0

f0, gy, gm = loss(y, m0, x)
h = .1f0
maxiter = 4

err3 = zeros(Float32, maxiter)
err4 = zeros(Float32, maxiter)

print("\nGradient test extended source model\n")
for j=1:maxiter
    f = loss(y, m0 + h*dm, x)[1]
    err3[j] = abs(f - f0)
    err4[j] = abs(f - f0 - h*dot(dm, gm))
    print(err3[j], "; ", err4[j], "\n")
    global h = h/2f0
end

@test isapprox(err3[end] / (err3[1]/2^(maxiter-1)), 1f0; atol=1f1)
@test isapprox(err4[end] / (err4[1]/4^(maxiter-1)), 1f0; atol=1f1)


text:
ROS.@include std_srvs: SetBool

srv_callback_enabled = false

function testServiceServer()
    ROS.init("testSS")
    nh = ROS.NodeHandle()

    srv = ROS.advertiseService(nh, "test_srv", ROS.std_srvs_SetBool_Request, ROS.std_srvs_SetBool_Response, srv_callback)

    @test ROS.getService(srv) == "/test_srv"

    loop = 100
    global srv_callback_enabled = false
    while loop > 0 && !srv_callback_enabled
        println("Service server at loop: $loop")
        loop -= 1
        ROS.sleep(ROS.Rate(10))
        ROS.spinOnce()
    end
    @test srv_callback_enabled

    ROS.shutdown(srv)
    ROS.shutdown(nh)

    println("All $(basename(@__FILE__)) tests passed.")
end

function srv_callback(req,res)
    res.success = true
    res.message = ":D"
    global srv_callback_enabled = true
    return true
end