text:
include("object_ids.jl")

mutable struct Entity
    x::Float32
    y::Float32
    vx::Float32
    vy::Float32
    rx::Float32
    ry::Float32
    type::Int
    image_type::Int
    image_theme::Int

    render_z::Int

    will_erase::Bool
    collides_with_entities::Bool
    collision_margin::Float32
    rotation::Float32
    vrot::Float32
    is_reflected::Bool
    fire_time::Int
    spawn_time::Int
    life_time::Int
    expire_time::Int
    use_abs_coords::Bool

    friction::Float32
    smart_step::Bool
    avoids_collisions::Bool
    auto_erase::Bool

    alpha::Float32
    health::Float32
    theta::Float32
    grow_rate::Float32
    alpha_decay::Float32
    climber_spawn_x::Float32

    function Entity()

        x = 0.0
        y = 0.0
        vx = 0.0
        vy = 0.0
        rx = 0.0
        ry = 0.0
        type = 0
        image_type = 0
        image_theme = 0

        render_z = 0

        will_erase = false
        collides_with_entities = false
        collision_margin = 0.0
        rotation = 0.0
        vrot = 0.0
        is_reflected = false
        fire_time = 0
        spawn_time = 0
        life_time = 0
        expire_time = 0
        use_abs_coords = false

        friction = 0.0
        smart_step = false
        avoids_collisions = false
        auto_erase = false

        alpha = 0.0
        health = 0.0
        theta = 0.0
        grow_rate = 0.0
        alpha_decay = 0.0
        climber_spawn_x = 0.0

        new(
            x,
            y,
            vx,
            vy,
            rx,
            ry,
            type,
            image_type,
            image_theme,
            render_z,
            will_erase,
            collides_with_entities,
            collision_margin,
            rotation,
            vrot,
            is_reflected,
            fire_time,
            spawn_time,
            life_time,
            expire_time,
            use_abs_coords,
            friction,
            smart_step,
            avoids_collisions,
            auto_erase,
            alpha,
            health,
            theta,
            grow_rate,
            alpha_decay,
            climber_spawn_x,
        )
    end

    function Entity(_x::Float32, _y::Float32, _vx::Float32, _vy::Float32, _rx::Float32, _ry::Float32, _type::Int)

        x = _x
        y = _y
        vx = _vx
        vy = _vy
        rx = _rx
        ry = _ry
        type = _type
        image_type = _type
        image_theme = 0

        render_z = 0

        will_erase = false
        collides_with_entities = false
        collision_margin = 0.0
        rotation = 0.0
        vrot = 0.0
        is_reflected = false
        fire_time = -1
        spawn_time = -1
        life_time = 0
        expire_time = -1
        use_abs_coords = false

        friction = 1.0
        smart_step = false
        avoids_collisions = false
        auto_erase = true

        alpha = 1.0
        health = 1.0
        theta = -100.0
        grow_rate = 1.0
        alpha_decay = 1.0
        climber_spawn_x = 0.0

        if type == Int(EXPLOSION)
            grow_rate = 1.4
            expire_time = 4
        elseif type == Int(TRAIL)
            grow_rate = 1.05
            alpha_decay = 0.8
        end

        new(
            x,
            y,
            vx,
            vy,
            rx,
            ry,
            type,
            image_type,
            image_theme,
            render_z,
            will_erase,
            collides_with_entities,
            collision_margin,
            rotation,
            vrot,
            is_reflected,
            fire_time,
            spawn_time,
            life_time,
            expire_time,
            use_abs_coords,
            friction,
            smart_step,
            avoids_collisions,
            auto_erase,
            alpha,
            health,
            theta,
            grow_rate,
            alpha_decay,
            climber_spawn_x,
        )
    end

    function Entity(_x::Float32, _y::Float32, _vx::Float32, _vy::Float32, _r::Float32, _type::Int)
        Entity(_x, _y, _vx, _vy, _r, _r, _type)
    end
end

function step(ent::Entity)

    if !ent.smart_step
        ent.x += ent.vx
        ent.y += ent.vy
    end

    ent.rotation += ent.vrot

    ent.vx *= ent.friction
    ent.vy *= ent.friction
    ent.life_time += 1

    if ent.expire_time > 0 && ent.life_time > ent.expire_time
        ent.will_erase = true
    end

    if ent.type == Int(EXPLOSION)
        if ent.image_type < Int(EXPLOSION)
            ent.image_type += 1
        end
    end

    ent.rx *= ent.grow_rate
    ent.ry *= ent.grow_rate
    ent.alpha *= ent.alpha_decay
    return nothing
end

function face_direction(ent::Entity, dx::Float32, dy::Float32, rotation_offset::Float32)

    if dx !=0 || dy !=0
        ent.rotation = -1 * atan(dy, dx) + rotation_offset
    end
    return nothing
end


text:
import GaussQuadrature
using OffsetArrays
using PyPlot

include("FPDE_problem.jl")

Nx = 20
Nt = 12
Nquad = 15
u(x, t) = refsoln(x, t, α, Nquad)
rx = 4
rt = 3
Mt = 2rt
Mx = 2rx
ppImax = 15

store = Store(α, rt+1, Mt, ppImax)
x_ = collect(range(0, L, length=Nx+1))
x = OffsetVector(x_, 0:Nx)
grid = SpatialGrid(x, rx, ("essential", "essential"), Mx)

U0 = spatial_L2_projection(u0, grid)
t, U = FPDEDG(1.0, f, U0, grid, max_t, Nt, rt, Mt, store)
τ = range(-1, 1, length=ppImax)
pcwise_t, Uerr = L2error(U, u, t, τ, grid, Mx)

jump = evaluate_jumps(U, U0, t, grid, Mx)
Uhat, jumpU = reconstruction(U, U0, store)
pcwise_t, Uhaterr = L2error(Uhat, u, t, τ, grid, Mx)

figure(6)
line1 = semilogy(t[0:Nt-1], abs.(jump[0:Nt-1]), "C0o")
line2 = semilogy(pcwise_t, Uerr, "C1-")
line3 = semilogy(pcwise_t, Uhaterr, "k:")
legend((line1[1], line2[2], line3[1]),
       (L"jump in $U$", L"error in $U$", L"error in $\widehat U$"))
xlabel(L"$t$")
PyPlot.grid(true)
savefig("fig6a.eps")

ext: jl


text:
export purge!, purge

# Home of all extended merge! methods
@doc (@doc merge)
merge(S::SeisData; v::Integer=KW.v) = (U = deepcopy(S); merge!(U, v=v); return U)
merge!(S::SeisData, U::SeisData; v::Integer=KW.v) = ([append!(getfield(S, f), getfield(U, f)) for f in SeisIO.datafields]; S.n += U.n; merge!(S; v=v))
merge!(S::SeisData, C::SeisChannel; v::Integer=KW.v) = merge!(S, SeisData(C), v=v)

"""
    S = merge(A::Array{SeisData,1})

Merge an array of SeisData objects, creating a single output with the merged
input data.

See also: `merge!`
"""
function merge(A::Array{SeisData,1}; v::Integer=KW.v)
  L::Int64 = length(A)
  n = sum([A[i].n for i = 1:L])
  T = SeisData(n)
  [setfield!(T, f, vcat([getfield(A[i],f) for i = 1:L]...)) for f in SeisIO.datafields]
  merge!(T, v=v)
  return T
end
merge(S::SeisData, U::SeisData; v::Integer=KW.v) = merge(Array{SeisData,1}([S,U]), v=v)
merge(S::SeisData, C::SeisChannel; v::Integer=KW.v) = merge(S, SeisData(C), v=v)
merge(C::SeisChannel, S::SeisData; v::Integer=KW.v) = merge(SeisData(C), S, v=v)
merge(C::SeisChannel, D::SeisChannel; v::Integer=KW.v) = (S = SeisData(C,D); merge!(S, v=v); return S)

"""
    purge!(S::SeisData)

Remove empty and duplicated channels in S; alias to `merge!(S, purge_only=true)`

    purge(S::SeisData)

"Safe" purge to a new SeisData object. Alias to `merge(S, purge_only=true)``
"""
purge!(S::T, v::Integer=KW.v) where {T<:GphysData} = merge!(S, purge_only=true, v=v)
function purge(S::T, v::Integer=KW.v) where {T<:GphysData}
  U = deepcopy(S)
  merge!(U, v=v, purge_only=true)
  return U
end


text:
module It

import Base.getindex

"""
    Partial for count(...)
    count( func::Function ) -> iter->count(func, iter)
    [1,2,3,4] |> count(x->x>1) # 3
"""
count(f::Function) = iter->Base.count(f,iter)

"""
    Partial for all(...)
    all(func) -> iter->all(func, iter) -> Bool
    [1,2,3,4] |> all(x->x>0) # true
"""
all(f::Function) = iter->Base.all(f,iter)

"""
    Partial for ismatch(...)
    \"asd\" |> ismatch(r::Regex) -> str->ismatch(r,str)
"""
ismatch(r::Regex) = s->Base.ismatch(r, s)

"""
    Partial function for replace(...) without first argument.

    replace(args...) -> x->replace(x,args...)

    f.e. \"file.txt\" |> replace(r\"\.txt\", \".csv\")
"""
replace( args... ) = x->Base.replace(x, args...)

"""
    Partial for match(...)
    \"asd\" |> match(r::Regex) -> str->match(r,str)
"""
match(r::Regex, args...) = s->Base.match(r, s, args...)

"""
    Partial for spl(...)
    \"asd*sdf\" |> split('*')
    \"asd sdf\" |> split() # - note what parenthes are present.
"""
split(splitter::Char, other...) = s->Base.split(s,splitter,other...)
split(splitter::Regex, other...) = s->Base.split(s,splitter,other...)
split() = s->Base.split(s)

"""
    Partial for take(...)
    [\"a\"] |> take(2) |> collect
"""
take(n::Int) = itr->Base.take(itr,n)

"(3,4) |> getindex(1) # 3"
getindex(ind) = coll->Base.getindex(coll,ind)

"""Experimental!
[3,4,5]|>pager

Write iterator to tempname() and less() it
"""
function pager(itr)
    tmp = tempname()
    wio = open(tmp,"w")
    itr|>Iter.println(wio)
    close(wio)
    less(tmp)
    rm(tmp)
end

end # module

max_stars_repo_name: closescreen/It

max_issues_repo_name: closescreen/It

max_forks_repo_name: closescreen/It


text:
# SplineSpace represents a Spline, right now piecewise constant HeavisideSpace is only implemented case
struct SplineSpace{order,T,R} <: Space{PiecewiseSegment{T},R}
    domain::PiecewiseSegment{T}
end

SplineSpace{m,T}(d::PiecewiseSegment{T}) where {m,T} = SplineSpace{m,T,real(eltype(T))}(d)
SplineSpace{m,T}(d::AbstractVector) where {m,T} = SplineSpace{m}(PiecewiseSegment(sort(d)))

SplineSpace{m}(d::PiecewiseSegment{T}) where {m,T} = SplineSpace{m,T,real(eltype(T))}(d)
SplineSpace{m}(d::AbstractVector) where {m} = SplineSpace{m}(PiecewiseSegment(sort(d)))

const HeavisideSpace{T,R} = SplineSpace{0,T,R}
dimension(h::SplineSpace{λ}) where {λ} = length(h.domain.points)+λ-1

convert(::Type{HeavisideSpace},d::PiecewiseSegment) = HeavisideSpace{eltype(d)}(d)

convert(::Type{HeavisideSpace},d::AbstractVector) =
    HeavisideSpace(PiecewiseSegment(sort(d)))

spacescompatible(a::SplineSpace{λ},b::SplineSpace{λ}) where {λ} = domainscompatible(a,b)
canonicalspace(sp::HeavisideSpace) = PiecewiseSpace(map(Chebyshev,components(domain(sp))))

function evaluate(f::Fun{HeavisideSpace{T,R}},x::Real) where {T<:Real,R}
    p = domain(f).points
    c = f.coefficients
    for k=1:length(c)
        if p[k] ≤ x ≤ p[k+1]
            return c[k]
        end
    end
    return zero(T)
end

function evaluate(f::Fun{SplineSpace{1,T,R}},x::Real) where {T<:Real,R}
    p = domain(f).points
    c = f.coefficients
    for k=1:length(p)-1
        if p[k] ≤ x ≤ p[k+1]
            return (x-p[k])*c[k+1]/(p[k+1]-p[k]) + (p[k+1]-x)*c[k]/(p[k+1]-p[k])
        end
    end
    return zero(T)
end

function points(sp::HeavisideSpace,n)
    x=sp.domain.points
    (x[1:end-1] + diff(x)/2)[1:n]
end

points(sp::SplineSpace{1},n) = sp.domain.points[1:n]

for λ = [0,1]
    @eval begin
        function transform(S::SplineSpace{$λ},vals::AbstractVector,plan...)
            @assert length(vals) ≤ dimension(S)
            vals
        end
        itransform(S::SplineSpace{$λ},cfs::AbstractVector,plan...) = pad(cfs,dimension(S))
    end
end

conversion_rule(sp::HeavisideSpace,sp2::PiecewiseSpace{NTuple{k,PS}}) where {k,PS<:PolynomialSpace} = sp

Conversion(a::HeavisideSpace,b::PiecewiseSpace{NTuple{kk,CC},DD,RR}) where {kk,CC<:PolynomialSpace,DD<:Domain1d,RR<:Real} =
    ConcreteConversion(a,b)
bandwidths(::ConcreteConversion{HS,PiecewiseSpace{NTuple{kk,CC},DD,RR}}) where {HS<:HeavisideSpace,CC<:PolynomialSpace,DD<:Domain1d,RR<:Real,kk} =
    0,0

getindex(C::ConcreteConversion{HS,PiecewiseSpace{NTuple{kk,CC},DD,RR}},k::Integer,j::Integer) where {HS<:HeavisideSpace,CC<:PolynomialSpace,DD<:Domain1d,RR<:Real,kk} =
    k ≤ dimension(domainspace(C)) && j==k ? one(eltype(C)) : zero(eltype(C))

bandwidths(D::ConcreteDerivative{H}) where {H<:HeavisideSpace} = (0,1)
rangespace(D::ConcreteDerivative{H}) where {H<:HeavisideSpace} = DiracSpace(domain(D).points[2:end-1])

function getindex(D::ConcreteDerivative{H,<:Any,T},k::Integer,j::Integer) where {H<:HeavisideSpace,T}
    if k==j
        -one(T)
    elseif j==k+1
        one(T)
    else
        zero(T)
    end
end

Base.sum(f::Fun{HS}) where {HS<:HeavisideSpace} = dotu(f.coefficients,diff(space(f).domain.points))
function Base.sum(f::Fun{SplineSpace{1,T,R}}) where {T,R}
    vals=pad(f.coefficients,dimension(space(f)))
    dfs=diff(space(f).domain.points)
    ret=vals[1]*dfs[1]/2
    for k=2:length(vals)-1
        ret+=vals[k]*(dfs[k]+dfs[k+1])/2
    end
    ret+=vals[end]*dfs[end]/2
    ret
end

#diffentiate HeavisideSpace
function differentiate(f::Fun{<:HeavisideSpace})
    dp=domain(f).points
    cfs=f.coefficients
    diff=0.0
    for n=1:length(cfs)
        diff=diff+cfs[n]*(DiracDelta(dp[n])-DiracDelta(dp[n+1]))
    end
    return diff
end

#Derivative Operator for HeavisideSpace
function Derivative(H::HeavisideSpace, k::Int)
    @assert k == 1
    ConcreteDerivative(H)
end

differentiate(f::Fun{SplineSpace{1,T,R}}) where {T,R} =
    Fun(HeavisideSpace(space(f).domain),
        diff(pad(f.coefficients,dimension(space(f))))./diff(space(f).domain.points))

integrate(f::Fun{HeavisideSpace{T,R}}) where {T,R} =
    Fun(SplineSpace{1,T,R}(space(f).domain),
        [0;cumsum(f.coefficients).*diff(space(f).domain.points)])


text:
# ------------------------------------------------------------------
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------

@recipe function f(dv::DomainView, data::AbstractVector)
  @series begin
    collect(dv), data
  end
end

@recipe function f(dv::DomainView)
  @series begin
    collect(dv)
  end
end


text:
using Documenter, AstroLib

makedocs(
    modules = [AstroLib],
    sitename = "AstroLib",
    pages    = [
        "Introduction"   => "index.md",
        "Reference"      => "ref.md",
    ]
)

deploydocs(
    repo = "github.com/JuliaAstro/AstroLib.jl.git",
)


text:
using Velocimetry
using Test

@testset "Velocimetry.jl" begin
    # Write your tests here.
end


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

@test integrate(x^5*arccot(a*x), x) == :(-1//6*a^-6*arctan(a*x)+-1//18*a^-3*x^3+1//6*x*a^-5+1//6*x^6*arccot(a*x)+1//30*a^-1*x^5)
@test integrate(x^4*arccot(a*x), x) == :(-1//10*a^-3*x^2+1//5*x^5*arccot(a*x)+1//10*a^-5*log(1+a^2*x^2)+1//20*a^-1*x^4)
@test integrate(x^3*arccot(a*x), x) == :(-1//4*x*a^-3+1//4*a^-4*arctan(a*x)+1//4*x^4*arccot(a*x)+1//12*a^-1*x^3)
@test integrate(x^2*arccot(a*x), x) == :(-1//6*a^-3*log(1+a^2*x^2)+1//3*x^3*arccot(a*x)+1//6*a^-1*x^2)
@test integrate(x*arccot(a*x), x) == :((1/2)*x*a^-1+(1/2)*x^2*arccot(a*x)+-1//2*a^-2*arctan(a*x))
@test integrate(arccot(a*x), x) == :(x*arccot(a*x)+(1/2)*a^-1*log(1+a^2*x^2))
@test integrate(x^-1*arccot(a*x), x) == :((1/2)*im*Polylogarithms.polylog(2,im*a^-1*x^-1)+-1//2*im*Polylogarithms.polylog(2,-1*im*a^-1*x^-1))
@test integrate(x^-2*arccot(a*x), x) == :((1/2)*a*log(1+a^2*x^2)+-1*a*log(x)+-1*x^-1*arccot(a*x))
@test integrate(x^-3*arccot(a*x), x) == :((1/2)*a*x^-1+(1/2)*a^2*arctan(a*x)+-1//2*x^-2*arccot(a*x))
@test integrate(x^-4*arccot(a*x), x) == :(-1//3*x^-3*arccot(a*x)+-1//6*a^3*log(1+a^2*x^2)+1//3*a^3*log(x)+1//6*a*x^-2)
@test integrate(x^-5*arccot(a*x), x) == :(-1//4*a^3*x^-1+-1//4*a^4*arctan(a*x)+-1//4*x^-4*arccot(a*x)+1//12*a*x^-3)
@test integrate(x^5*arccot(a*x)^2, x) == :(-4//45*a^-4*x^2+1//6*a^-6*arccot(a*x)^2+1//6*x^6*arccot(a*x)^2+1//60*a^-2*x^4+23//90*a^-6*log(1+a^2*x^2)+-1//9*a^-3*x^3*arccot(a*x)+1//3*x*a^-5*arccot(a*x)+1//15*a^-1*x^5*arccot(a*x))
@test integrate(x^4*arccot(a*x)^2, x) == :(-3//10*x*a^-4+1//5*x^5*arccot(a*x)^2+1//30*a^-2*x^3+3//10*a^-5*arctan(a*x)+-2//5*a^-5*arccot(a*x)*log(2*(1+im*a*x)^-1)+-1//5*a^-3*x^2*arccot(a*x)+1//5*im*a^-5*arccot(a*x)^2+1//5*im*a^-5*Polylogarithms.polylog(2,1+-2*(1+im*a*x)^-1)+1//10*a^-1*x^4*arccot(a*x))
@test integrate(x^3*arccot(a*x)^2, x) == :(-1//3*a^-4*log(1+a^2*x^2)+-1//4*a^-4*arccot(a*x)^2+1//4*x^4*arccot(a*x)^2+1//12*a^-2*x^2+-1//2*x*a^-3*arccot(a*x)+1//6*a^-1*x^3*arccot(a*x))
@test integrate(x^2*arccot(a*x)^2, x) == :(-1//3*a^-3*arctan(a*x)+1//3*x*a^-2+1//3*x^3*arccot(a*x)^2+-1//3*im*a^-3*arccot(a*x)^2+-1//3*im*a^-3*Polylogarithms.polylog(2,1+-2*(1+im*a*x)^-1)+1//3*a^-1*x^2*arccot(a*x)+2//3*a^-3*arccot(a*x)*log(2*(1+im*a*x)^-1))
@test integrate(x*arccot(a*x)^2, x) == :((1/2)*a^-2*arccot(a*x)^2+(1/2)*a^-2*log(1+a^2*x^2)+(1/2)*x^2*arccot(a*x)^2+x*a^-1*arccot(a*x))
@test integrate(arccot(a*x)^2, x) == :(x*arccot(a*x)^2+im*a^-1*arccot(a*x)^2+im*a^-1*Polylogarithms.polylog(2,1+-2*(1+im*a*x)^-1)+-2*a^-1*arccot(a*x)*log(2*(1+im*a*x)^-1))
@test integrate(x^-1*arccot(a*x)^2, x) == :((1/2)*Polylogarithms.polylog(3,1+-2*a*x*(im+a*x)^-1)+-1//2*Polylogarithms.polylog(3,1+-2*im*(im+a*x)^-1)+2*arccot(a*x)^2*arccoth(1+-2*(1+im*a*x)^-1)+im*Polylogarithms.polylog(2,1+-2*a*x*(im+a*x)^-1)*arccot(a*x)+-1*im*Polylogarithms.polylog(2,1+-2*im*(im+a*x)^-1)*arccot(a*x))
@test integrate(x^-2*arccot(a*x)^2, x) == :(-1*x^-1*arccot(a*x)^2+-1*im*a*arccot(a*x)^2+-1*im*a*Polylogarithms.polylog(2,-1+2*(1+-1*im*a*x)^-1)+-2*a*arccot(a*x)*log(2+-2*(1+-1*im*a*x)^-1))
@test integrate(x^-3*arccot(a*x)^2, x) == :(a^2*log(x)+-1//2*a^2*arccot(a*x)^2+-1//2*a^2*log(1+a^2*x^2)+-1//2*x^-2*arccot(a*x)^2+a*x^-1*arccot(a*x))
@test integrate(x^-4*arccot(a*x)^2, x) == :(-1//3*a^2*x^-1+-1//3*a^3*arctan(a*x)+-1//3*x^-3*arccot(a*x)^2+1//3*im*a^3*arccot(a*x)^2+1//3*im*a^3*Polylogarithms.polylog(2,-1+2*(1+-1*im*a*x)^-1)+1//3*a*x^-2*arccot(a*x)+2//3*a^3*arccot(a*x)*log(2+-2*(1+-1*im*a*x)^-1))
@test integrate(x^-5*arccot(a*x)^2, x) == :(-2//3*a^4*log(x)+-1//4*x^-4*arccot(a*x)^2+-1//12*a^2*x^-2+1//3*a^4*log(1+a^2*x^2)+1//4*a^4*arccot(a*x)^2+-1//2*a^3*x^-1*arccot(a*x)+1//6*a*x^-3*arccot(a*x))
@test integrate(x^5*arccot(a*x)^3, x) == :(-19//60*x*a^-5+1//6*a^-6*arccot(a*x)^3+1//6*x^6*arccot(a*x)^3+1//60*a^-3*x^3+19//60*a^-6*arctan(a*x)+(1/2)*x*a^-5*arccot(a*x)^2+-23//15*a^-6*arccot(a*x)*log(2*(1+im*a*x)^-1)+-4//15*a^-4*x^2*arccot(a*x)+-1//6*a^-3*x^3*arccot(a*x)^2+1//10*a^-1*x^5*arccot(a*x)^2+1//20*a^-2*x^4*arccot(a*x)+23//30*im*a^-6*arccot(a*x)^2+23//30*im*a^-6*Polylogarithms.polylog(2,1+-2*(1+im*a*x)^-1))
@test integrate(x^4*arccot(a*x)^3, x) == :(-9//20*a^-5*arccot(a*x)^2+-3//10*a^-5*Polylogarithms.polylog(3,1+-2*(1+im*a*x)^-1)+-1//2*a^-5*log(1+a^2*x^2)+1//5*x^5*arccot(a*x)^3+1//20*a^-3*x^2+-9//10*x*a^-4*arccot(a*x)+-3//5*a^-5*arccot(a*x)^2*log(2*(1+im*a*x)^-1)+-3//10*a^-3*x^2*arccot(a*x)^2+1//5*im*a^-5*arccot(a*x)^3+1//10*a^-2*x^3*arccot(a*x)+3//20*a^-1*x^4*arccot(a*x)^2+3//5*im*a^-5*Polylogarithms.polylog(2,1+-2*(1+im*a*x)^-1)*arccot(a*x))
@test integrate(x^3*arccot(a*x)^3, x) == :(-1//4*a^-4*arccot(a*x)^3+-1//4*a^-4*arctan(a*x)+1//4*x*a^-3+1//4*x^4*arccot(a*x)^3+-1*im*a^-4*arccot(a*x)^2+-1*im*a^-4*Polylogarithms.polylog(2,1+-2*(1+im*a*x)^-1)+2*a^-4*arccot(a*x)*log(2*(1+im*a*x)^-1)+-3//4*x*a^-3*arccot(a*x)^2+1//4*a^-1*x^3*arccot(a*x)^2+1//4*a^-2*x^2*arccot(a*x))
@test integrate(x^2*arccot(a*x)^3, x) == :((1/2)*a^-3*arccot(a*x)^2+(1/2)*a^-3*Polylogarithms.polylog(3,1+-2*(1+im*a*x)^-1)+(1/2)*a^-3*log(1+a^2*x^2)+1//3*x^3*arccot(a*x)^3+x*a^-2*arccot(a*x)+a^-3*arccot(a*x)^2*log(2*(1+im*a*x)^-1)+(1/2)*a^-1*x^2*arccot(a*x)^2+-1//3*im*a^-3*arccot(a*x)^3+-1*im*a^-3*Polylogarithms.polylog(2,1+-2*(1+im*a*x)^-1)*arccot(a*x))
@test integrate(x*arccot(a*x)^3, x) == :((1/2)*a^-2*arccot(a*x)^3+(1/2)*x^2*arccot(a*x)^3+-3*a^-2*arccot(a*x)*log(2*(1+im*a*x)^-1)+3//2*im*a^-2*arccot(a*x)^2+3//2*im*a^-2*Polylogarithms.polylog(2,1+-2*(1+im*a*x)^-1)+3//2*x*a^-1*arccot(a*x)^2)
@test integrate(arccot(a*x)^3, x) == :(x*arccot(a*x)^3+-3//2*a^-1*Polylogarithms.polylog(3,1+-2*(1+im*a*x)^-1)+im*a^-1*arccot(a*x)^3+-3*a^-1*arccot(a*x)^2*log(2*(1+im*a*x)^-1)+3*im*a^-1*Polylogarithms.polylog(2,1+-2*(1+im*a*x)^-1)*arccot(a*x))
@test integrate(x^-1*arccot(a*x)^3, x) == :(2*arccot(a*x)^3*arccoth(1+-2*(1+im*a*x)^-1)+-3//2*Polylogarithms.polylog(3,1+-2*im*(im+a*x)^-1)*arccot(a*x)+-3//4*im*Polylogarithms.polylog(4,1+-2*a*x*(im+a*x)^-1)+3//2*Polylogarithms.polylog(3,1+-2*a*x*(im+a*x)^-1)*arccot(a*x)+3//4*im*Polylogarithms.polylog(4,1+-2*im*(im+a*x)^-1)+-3//2*im*arccot(a*x)^2*Polylogarithms.polylog(2,1+-2*im*(im+a*x)^-1)+3//2*im*arccot(a*x)^2*Polylogarithms.polylog(2,1+-2*a*x*(im+a*x)^-1))
@test integrate(x^-2*arccot(a*x)^3, x) == :(-1*x^-1*arccot(a*x)^3+-3//2*a*Polylogarithms.polylog(3,-1+2*(1+-1*im*a*x)^-1)+-1*im*a*arccot(a*x)^3+-3*a*arccot(a*x)^2*log(2+-2*(1+-1*im*a*x)^-1)+-3*im*a*Polylogarithms.polylog(2,-1+2*(1+-1*im*a*x)^-1)*arccot(a*x))
@test integrate(x^-3*arccot(a*x)^3, x) == :(-1//2*a^2*arccot(a*x)^3+-1//2*x^-2*arccot(a*x)^3+3*a^2*arccot(a*x)*log(2+-2*(1+-1*im*a*x)^-1)+3//2*im*a^2*arccot(a*x)^2+3//2*im*a^2*Polylogarithms.polylog(2,-1+2*(1+-1*im*a*x)^-1)+3//2*a*x^-1*arccot(a*x)^2)
@test integrate(x^-4*arccot(a*x)^3, x) == :((1/2)*a^3*arccot(a*x)^2+(1/2)*a^3*Polylogarithms.polylog(3,-1+2*(1+-1*im*a*x)^-1)+(1/2)*a^3*log(1+a^2*x^2)+-1*a^3*log(x)+-1//3*x^-3*arccot(a*x)^3+a^3*arccot(a*x)^2*log(2+-2*(1+-1*im*a*x)^-1)+(1/2)*a*x^-2*arccot(a*x)^2+-1*a^2*x^-1*arccot(a*x)+1//3*im*a^3*arccot(a*x)^3+im*a^3*Polylogarithms.polylog(2,-1+2*(1+-1*im*a*x)^-1)*arccot(a*x))
@test integrate(x^-5*arccot(a*x)^3, x) == :(-1//4*x^-4*arccot(a*x)^3+1//4*a^3*x^-1+1//4*a^4*arccot(a*x)^3+1//4*a^4*arctan(a*x)+-1*im*a^4*arccot(a*x)^2+-1*im*a^4*Polylogarithms.polylog(2,-1+2*(1+-1*im*a*x)^-1)+-2*a^4*arccot(a*x)*log(2+-2*(1+-1*im*a*x)^-1)+-3//4*a^3*x^-1*arccot(a*x)^2+-1//4*a^2*x^-2*arccot(a*x)+1//4*a*x^-3*arccot(a*x)^2)
@test integrate(x^4*(1+x^2)^-1*arccot(x), x) == :(-2//3*log(1+x^2)+-1//2*arccot(x)^2+1//6*x^2+-1*x*arccot(x)+1//3*x^3*arccot(x))
@test integrate(x^3*(1+x^2)^-1*arccot(x), x) == :((1/2)*x+-1//2*arctan(x)+arccot(x)*log(2*(1+im*x)^-1)+(1/2)*x^2*arccot(x)+-1//2*im*arccot(x)^2+-1//2*im*Polylogarithms.polylog(2,1+-2*(1+im*x)^-1))
@test integrate(x^2*(1+x^2)^-1*arccot(x), x) == :((1/2)*arccot(x)^2+(1/2)*log(1+x^2)+x*arccot(x))
@test integrate(x*(1+x^2)^-1*arccot(x), x) == :((1/2)*im*arccot(x)^2+(1/2)*im*Polylogarithms.polylog(2,1+-2*(1+im*x)^-1)+-1*arccot(x)*log(2*(1+im*x)^-1))
@test integrate((1+x^2)^-1*arccot(x), x) == :(-1//2*arccot(x)^2)
@test integrate(x^-1*(1+x^2)^-1*arccot(x), x) == :(arccot(x)*log(2+-2*(1+-1*im*x)^-1)+(1/2)*im*arccot(x)^2+(1/2)*im*Polylogarithms.polylog(2,-1+2*(1+-1*im*x)^-1))
@test integrate(x^-2*(1+x^2)^-1*arccot(x), x) == :((1/2)*arccot(x)^2+(1/2)*log(1+x^2)+-1*log(x)+-1*x^-1*arccot(x))
@test integrate(x^-3*(1+x^2)^-1*arccot(x), x) == :((1/2)*x^-1+(1/2)*arctan(x)+-1*arccot(x)*log(2+-2*(1+-1*im*x)^-1)+-1//2*im*arccot(x)^2+-1//2*im*Polylogarithms.polylog(2,-1+2*(1+-1*im*x)^-1)+-1//2*x^-2*arccot(x))
@test integrate(x^-4*(1+x^2)^-1*arccot(x), x) == :(-2//3*log(1+x^2)+-1//2*arccot(x)^2+1//6*x^-2+4//3*log(x)+x^-1*arccot(x)+-1//3*x^-3*arccot(x))
@test integrate(x^2*(1+x^2)^-1*arccot(c*x), x) == :(-1//4*Polylogarithms.polylog(2,1+2*im*(1+c)^-1*(1+-1*im*x)^-1*(im+c*x))+1//4*Polylogarithms.polylog(2,1+2*im*(1+-1c)^-1*(1+-1*im*x)^-1*(im+-1*c*x))+x*arccot(c*x)+(1/2)*c^-1*log(1+c^2*x^2)+(1/2)*im*arctan(x)*log(-2*im*(1+-1c)^-1*(1+-1*im*x)^-1*(im+-1*c*x))+(1/2)*im*arctan(x)*log(1+im*c^-1*x^-1)+-1//2*im*arctan(x)*log(-2*im*(1+c)^-1*(1+-1*im*x)^-1*(im+c*x))+-1//2*im*arctan(x)*log(1+-1*im*c^-1*x^-1))
@test integrate(x*(1+x^2)^-1*arccot(c*x), x) == :((1/2)*arccot(c*x)*log(-2*im*c*(1+c)^-1*(1+-1*im*c*x)^-1*(im+x))+(1/2)*arccot(c*x)*log(2*im*c*(1+-1c)^-1*(1+-1*im*c*x)^-1*(im+-1x))+-1*arccot(c*x)*log(2*(1+-1*im*c*x)^-1)+-1//2*im*Polylogarithms.polylog(2,1+-2*(1+-1*im*c*x)^-1)+1//4*im*Polylogarithms.polylog(2,1+-2*im*c*(1+-1c)^-1*(1+-1*im*c*x)^-1*(im+-1x))+1//4*im*Polylogarithms.polylog(2,1+2*im*c*(1+c)^-1*(1+-1*im*c*x)^-1*(im+x)))
@test integrate((1+x^2)^-1*arccot(c*x), x) == :(-1//4*Polylogarithms.polylog(2,1+2*im*(1+-1c)^-1*(1+-1*im*x)^-1*(im+-1*c*x))+1//4*Polylogarithms.polylog(2,1+2*im*(1+c)^-1*(1+-1*im*x)^-1*(im+c*x))+(1/2)*im*arctan(x)*log(-2*im*(1+c)^-1*(1+-1*im*x)^-1*(im+c*x))+(1/2)*im*arctan(x)*log(1+-1*im*c^-1*x^-1)+-1//2*im*arctan(x)*log(-2*im*(1+-1c)^-1*(1+-1*im*x)^-1*(im+-1*c*x))+-1//2*im*arctan(x)*log(1+im*c^-1*x^-1))
@test integrate(x^-1*(1+x^2)^-1*arccot(c*x), x) == :(arccot(c*x)*log(2*(1+-1*im*c*x)^-1)+(1/2)*im*Polylogarithms.polylog(2,im*c^-1*x^-1)+(1/2)*im*Polylogarithms.polylog(2,1+-2*(1+-1*im*c*x)^-1)+-1//2*im*Polylogarithms.polylog(2,-1*im*c^-1*x^-1)+-1//2*arccot(c*x)*log(-2*im*c*(1+c)^-1*(1+-1*im*c*x)^-1*(im+x))+-1//2*arccot(c*x)*log(2*im*c*(1+-1c)^-1*(1+-1*im*c*x)^-1*(im+-1x))+-1//4*im*Polylogarithms.polylog(2,1+-2*im*c*(1+-1c)^-1*(1+-1*im*c*x)^-1*(im+-1x))+-1//4*im*Polylogarithms.polylog(2,1+2*im*c*(1+c)^-1*(1+-1*im*c*x)^-1*(im+x)))
@test integrate(x^-2*(1+x^2)^-1*arccot(c*x), x) == :(-1//4*Polylogarithms.polylog(2,1+2*im*(1+c)^-1*(1+-1*im*x)^-1*(im+c*x))+1//4*Polylogarithms.polylog(2,1+2*im*(1+-1c)^-1*(1+-1*im*x)^-1*(im+-1*c*x))+(1/2)*c*log(1+c^2*x^2)+-1*c*log(x)+-1*x^-1*arccot(c*x)+(1/2)*im*arctan(x)*log(-2*im*(1+-1c)^-1*(1+-1*im*x)^-1*(im+-1*c*x))+(1/2)*im*arctan(x)*log(1+im*c^-1*x^-1)+-1//2*im*arctan(x)*log(-2*im*(1+c)^-1*(1+-1*im*x)^-1*(im+c*x))+-1//2*im*arctan(x)*log(1+-1*im*c^-1*x^-1))
@test integrate((1+x^2)^-1*arccot(x)^-1, x) == :(-1*log(arccot(x)))
@test integrate((1+x^2)^-1*arccot(x)^n, x) == :(-1*(1+n)^-1*arccot(x)^(1+n))
@test integrate((c+d*x^2)^4*arccot(a*x), x) == :(x*c^4*arccot(a*x)+1//9*d^4*x^9*arccot(a*x)+1//72*a^-1*d^4*x^8+1//630*a^-9*(35*d^4+315*a^8*c^4+-420*d*a^6*c^3+-180*c*a^2*d^3+378*a^4*c^2*d^2)*log(1+a^2*x^2)+1//378*a^-3*d^3*x^6*(-7d+36*c*a^2)+1//630*d*a^-7*x^2*(-35*d^3+420*a^6*c^3+-378*d*a^4*c^2+180*c*a^2*d^2)+1//1260*a^-5*d^2*x^4*(35*d^2+378*a^4*c^2+-180*c*d*a^2)+4//3*d*c^3*x^3*arccot(a*x)+4//7*c*d^3*x^7*arccot(a*x)+6//5*c^2*d^2*x^5*arccot(a*x))
@test integrate((c+d*x^2)^3*arccot(a*x), x) == :(x*c^3*arccot(a*x)+1//7*d^3*x^7*arccot(a*x)+1//42*a^-1*d^3*x^6+1//70*a^-7*(-5*d^3+35*a^6*c^3+-35*d*a^4*c^2+21*c*a^2*d^2)*log(1+a^2*x^2)+d*c^2*x^3*arccot(a*x)+1//70*d*a^-5*x^2*(5*d^2+35*a^4*c^2+-21*c*d*a^2)+1//140*a^-3*d^2*x^4*(-5d+21*c*a^2)+3//5*c*d^2*x^5*arccot(a*x))
@test integrate((c+d*x^2)^2*arccot(a*x), x) == :(x*c^2*arccot(a*x)+1//5*d^2*x^5*arccot(a*x)+1//20*a^-1*d^2*x^4+1//30*a^-5*(3*d^2+15*a^4*c^2+-10*c*d*a^2)*log(1+a^2*x^2)+1//30*d*a^-3*x^2*(-3d+10*c*a^2)+2//3*c*d*x^3*arccot(a*x))
@test integrate((c+d*x^2)*arccot(a*x), x) == :(c*x*arccot(a*x)+1//3*d*x^3*arccot(a*x)+1//6*d*a^-1*x^2+1//6*a^-3*(-1d+3*c*a^2)*log(1+a^2*x^2))
@test integrate((c+d*x^2)^-1*arccot(a*x), x) == :(-1//4*c^-1//2*d^-1//2*Polylogarithms.polylog(2,1+-2*im*c^(1/2)*d^(1/2)*(c^(1/2)+-1*im*x*d^(1/2))^-1*(-1*d^(1/2)+a*c^(1/2))^-1*(im+-1*a*x))+1//4*c^-1//2*d^-1//2*Polylogarithms.polylog(2,1+2*im*c^(1/2)*d^(1/2)*(c^(1/2)+-1*im*x*d^(1/2))^-1*(d^(1/2)+a*c^(1/2))^-1*(im+a*x))+(1/2)*im*c^-1//2*d^-1//2*arctan(x*c^-1//2*d^(1/2))*log(-2*im*c^(1/2)*d^(1/2)*(c^(1/2)+-1*im*x*d^(1/2))^-1*(d^(1/2)+a*c^(1/2))^-1*(im+a*x))+(1/2)*im*c^-1//2*d^-1//2*arctan(x*c^-1//2*d^(1/2))*log(1+-1*im*a^-1*x^-1)+-1//2*im*c^-1//2*d^-1//2*arctan(x*c^-1//2*d^(1/2))*log(2*im*c^(1/2)*d^(1/2)*(c^(1/2)+-1*im*x*d^(1/2))^-1*(-1*d^(1/2)+a*c^(1/2))^-1*(im+-1*a*x))+-1//2*im*c^-1//2*d^-1//2*arctan(x*c^-1//2*d^(1/2))*log(1+im*a^-1*x^-1))
@test integrate((c+d*x^2)^-2*arccot(a*x), x) == :((1/2)*x*c^-1*(c+d*x^2)^-1*arccot(a*x)+(1/2)*c^-3//2*d^-1//2*arccot(a*x)*arctan(x*c^-1//2*d^(1/2))+-1//4*a*c^-1*(-1d+c*a^2)^-1*log(c+d*x^2)+1//4*a*c^-1*(-1d+c*a^2)^-1*log(1+a^2*x^2)+-1//8*im*a*c^-3//2*d^-1//2*(-1*a^2)^-1//2*Polylogarithms.polylog(2,(-1*a^2)^(1/2)*(c^(1/2)*(-1*a^2)^(1/2)+-1*im*d^(1/2))^-1*(c^(1/2)+im*x*d^(1/2)))+-1//8*im*a*c^-3//2*d^-1//2*(-1*a^2)^-1//2*Polylogarithms.polylog(2,(-1*a^2)^(1/2)*(c^(1/2)*(-1*a^2)^(1/2)+-1*im*d^(1/2))^-1*(c^(1/2)+-1*im*x*d^(1/2)))+1//8*im*a*c^-3//2*d^-1//2*(-1*a^2)^-1//2*Polylogarithms.polylog(2,(-1*a^2)^(1/2)*(im*d^(1/2)+c^(1/2)*(-1*a^2)^(1/2))^-1*(c^(1/2)+im*x*d^(1/2)))+1//8*im*a*c^-3//2*d^-1//2*(-1*a^2)^-1//2*Polylogarithms.polylog(2,(-1*a^2)^(1/2)*(im*d^(1/2)+c^(1/2)*(-1*a^2)^(1/2))^-1*(c^(1/2)+-1*im*x*d^(1/2)))+-1//8*im*a*c^-3//2*d^-1//2*(-1*a^2)^-1//2*log(d^(1/2)*(d^(1/2)+im*c^(1/2)*(-1*a^2)^(1/2))^-1*(1+x*(-1*a^2)^(1/2)))*log(1+im*x*c^-1//2*d^(1/2))+-1//8*im*a*c^-3//2*d^-1//2*(-1*a^2)^-1//2*log(d^(1/2)*(d^(1/2)+im*c^(1/2)*(-1*a^2)^(1/2))^-1*(1+-1*x*(-1*a^2)^(1/2)))*log(1+-1*im*x*c^-1//2*d^(1/2))+1//8*im*a*c^-3//2*d^-1//2*(-1*a^2)^-1//2*log(-1*d^(1/2)*(-1*d^(1/2)+im*c^(1/2)*(-1*a^2)^(1/2))^-1*(1+x*(-1*a^2)^(1/2)))*log(1+-1*im*x*c^-1//2*d^(1/2))+1//8*im*a*c^-3//2*d^-1//2*(-1*a^2)^-1//2*log(-1*d^(1/2)*(-1*d^(1/2)+im*c^(1/2)*(-1*a^2)^(1/2))^-1*(1+-1*x*(-1*a^2)^(1/2)))*log(1+im*x*c^-1//2*d^(1/2)))
@test integrate((c+d*x^2)^-3//2*arccot(a*x), x) == :(-1*c^-1*(-1d+c*a^2)^-1//2*arctanh(a*(c+d*x^2)^(1/2)*(-1d+c*a^2)^-1//2)+x*c^-1*(c+d*x^2)^-1//2*arccot(a*x))
@test integrate((c+d*x^2)^-5//2*arccot(a*x), x) == :(-1//3*c^-2*(-1d+c*a^2)^-3//2*(-2d+3*c*a^2)*arctanh(a*(c+d*x^2)^(1/2)*(-1d+c*a^2)^-1//2)+1//3*a*c^-1*(c+d*x^2)^-1//2*(-1d+c*a^2)^-1+1//3*x*c^-1*(c+d*x^2)^-3//2*arccot(a*x)+2//3*x*c^-2*(c+d*x^2)^-1//2*arccot(a*x))
@test integrate((c+d*x^2)^-7//2*arccot(a*x), x) == :(-1//15*c^-3*(-1d+c*a^2)^-5//2*(8*d^2+15*a^4*c^2+-20*c*d*a^2)*arctanh(a*(c+d*x^2)^(1/2)*(-1d+c*a^2)^-1//2)+1//5*x*c^-1*(c+d*x^2)^-5//2*arccot(a*x)+1//15*a*c^-1*(c+d*x^2)^-3//2*(-1d+c*a^2)^-1+4//15*x*c^-2*(c+d*x^2)^-3//2*arccot(a*x)+8//15*x*c^-3*(c+d*x^2)^-1//2*arccot(a*x)+1//15*a*c^-2*(c+d*x^2)^-1//2*(-1d+c*a^2)^-2*(-4d+7*c*a^2))
@test integrate((c+d*x^2)^-9//2*arccot(a*x), x) == :(-1//35*c^-4*(-1d+c*a^2)^-7//2*(-16*d^3+35*a^6*c^3+-70*d*a^4*c^2+56*c*a^2*d^2)*arctanh(a*(c+d*x^2)^(1/2)*(-1d+c*a^2)^-1//2)+1//7*x*c^-1*(c+d*x^2)^-7//2*arccot(a*x)+1//35*a*c^-1*(c+d*x^2)^-5//2*(-1d+c*a^2)^-1+6//35*x*c^-2*(c+d*x^2)^-5//2*arccot(a*x)+8//35*x*c^-3*(c+d*x^2)^-3//2*arccot(a*x)+16//35*x*c^-4*(c+d*x^2)^-1//2*arccot(a*x)+1//35*a*c^-3*(c+d*x^2)^-1//2*(-1d+c*a^2)^-3*(8*d^2+19*a^4*c^2+-22*c*d*a^2)+1//105*a*c^-2*(c+d*x^2)^-3//2*(-1d+c*a^2)^-2*(-6d+11*c*a^2))
@test integrate((a+a*x^2)^(1/2)*arccot(x), x) == :((1/2)*(a+a*x^2)^(1/2)+(1/2)*x*(a+a*x^2)^(1/2)*arccot(x)+(1/2)*im*a*(1+x^2)^(1/2)*(a+a*x^2)^-1//2*Polylogarithms.polylog(2,im*(1+im*x)^(1/2)*(1+-1*im*x)^-1//2)+-1//2*im*a*(1+x^2)^(1/2)*(a+a*x^2)^-1//2*Polylogarithms.polylog(2,-1*im*(1+im*x)^(1/2)*(1+-1*im*x)^-1//2)+-1*im*a*(1+x^2)^(1/2)*(a+a*x^2)^-1//2*arccot(x)*arctan((1+im*x)^(1/2)*(1+-1*im*x)^-1//2))
@test integrate((a+a*x^2)^-1//2*arccot(x), x) == :(im*(1+x^2)^(1/2)*(a+a*x^2)^-1//2*Polylogarithms.polylog(2,im*(1+im*x)^(1/2)*(1+-1*im*x)^-1//2)+-1*im*(1+x^2)^(1/2)*(a+a*x^2)^-1//2*Polylogarithms.polylog(2,-1*im*(1+im*x)^(1/2)*(1+-1*im*x)^-1//2)+-2*im*(1+x^2)^(1/2)*(a+a*x^2)^-1//2*arccot(x)*arctan((1+im*x)^(1/2)*(1+-1*im*x)^-1//2))
@test integrate((a+a*x^2)^-3//2*arccot(x), x) == :(-1*a^-1*(a+a*x^2)^-1//2+x*a^-1*(a+a*x^2)^-1//2*arccot(x))
@test integrate((a+a*x^2)^-5//2*arccot(x), x) == :(-2//3*a^-2*(a+a*x^2)^-1//2+-1//9*a^-1*(a+a*x^2)^-3//2+1//3*x*a^-1*(a+a*x^2)^-3//2*arccot(x)+2//3*x*a^-2*(a+a*x^2)^-1//2*arccot(x))
@test integrate((a+a*x^2)^-7//2*arccot(x), x) == :(-8//15*a^-3*(a+a*x^2)^-1//2+-4//45*a^-2*(a+a*x^2)^-3//2+-1//25*a^-1*(a+a*x^2)^-5//2+1//5*x*a^-1*(a+a*x^2)^-5//2*arccot(x)+4//15*x*a^-2*(a+a*x^2)^-3//2*arccot(x)+8//15*x*a^-3*(a+a*x^2)^-1//2*arccot(x))
@test integrate(x*(1+x^2)^-2*arccot(x), x) == :(-1//4*arctan(x)+-1*x*(4+4*x^2)^-1+-1*(2+2*x^2)^-1*arccot(x))
@test integrate(x*(1+x^2)^-3*arccot(x), x) == :(-3//32*arctan(x)+-3*x*(32+32*x^2)^-1+-1//4*(1+x^2)^-2*arccot(x)+-1//16*x*(1+x^2)^-2)
@test integrate((1+x^2)^-2*arccot(x), x) == :(-1*(4+4*x^2)^-1+-1//4*arccot(x)^2+x*(2+2*x^2)^-1*arccot(x))
@test integrate((1+x^2)^-2*arccot(x)^2, x) == :(-1//4*arctan(x)+-1//6*arccot(x)^3+-1*x*(4+4*x^2)^-1+-1*(2+2*x^2)^-1*arccot(x)+x*(2+2*x^2)^-1*arccot(x)^2)
@test integrate(x^5*arccot(a*x^2), x) == :(-1//12*a^-3*log(1+a^2*x^4)+1//6*x^6*arccot(a*x^2)+1//12*a^-1*x^4)
@test integrate(x^3*arccot(a*x^2), x) == :(-1//4*a^-2*arctan(a*x^2)+1//4*a^-1*x^2+1//4*x^4*arccot(a*x^2))
@test integrate(x*arccot(a*x^2), x) == :((1/2)*x^2*arccot(a*x^2)+1//4*a^-1*log(1+a^2*x^4))
@test integrate(x^-1*arccot(a*x^2), x) == :(-1//4*im*Polylogarithms.polylog(2,-1*im*a^-1*x^-2)+1//4*im*Polylogarithms.polylog(2,im*a^-1*x^-2))
@test integrate(x^-3*arccot(a*x^2), x) == :(-1*a*log(x)+-1//2*x^-2*arccot(a*x^2)+1//4*a*log(1+a^2*x^4))
@test integrate(x^-5*arccot(a*x^2), x) == :(-1//4*x^-4*arccot(a*x^2)+1//4*a*x^-2+1//4*a^2*arctan(a*x^2))
@test integrate(x^4*arccot(a*x^2), x) == :(1//5*x^5*arccot(a*x^2)+2//15*a^-1*x^3+-1//10*2^(1/2)*a^-5//2*arctan(1+x*2^(1/2)*a^(1/2))+-1//20*2^(1/2)*a^-5//2*log(1+a*x^2+-1*x*2^(1/2)*a^(1/2))+1//10*2^(1/2)*a^-5//2*arctan(1+-1*x*2^(1/2)*a^(1/2))+1//20*2^(1/2)*a^-5//2*log(1+a*x^2+x*2^(1/2)*a^(1/2)))
@test integrate(x^2*arccot(a*x^2), x) == :(1//3*x^3*arccot(a*x^2)+2//3*x*a^-1+-1//6*2^(1/2)*a^-3//2*arctan(1+x*2^(1/2)*a^(1/2))+-1//12*2^(1/2)*a^-3//2*log(1+a*x^2+x*2^(1/2)*a^(1/2))+1//6*2^(1/2)*a^-3//2*arctan(1+-1*x*2^(1/2)*a^(1/2))+1//12*2^(1/2)*a^-3//2*log(1+a*x^2+-1*x*2^(1/2)*a^(1/2)))
@test integrate(arccot(a*x^2), x) == :(x*arccot(a*x^2)+(1/2)*2^(1/2)*a^-1//2*arctan(1+x*2^(1/2)*a^(1/2))+-1//2*2^(1/2)*a^-1//2*arctan(1+-1*x*2^(1/2)*a^(1/2))+-1//4*2^(1/2)*a^-1//2*log(1+a*x^2+x*2^(1/2)*a^(1/2))+1//4*2^(1/2)*a^-1//2*log(1+a*x^2+-1*x*2^(1/2)*a^(1/2)))
@test integrate(x^-2*arccot(a*x^2), x) == :(-1*x^-1*arccot(a*x^2)+(1/2)*2^(1/2)*a^(1/2)*arctan(1+-1*x*2^(1/2)*a^(1/2))+-1//2*2^(1/2)*a^(1/2)*arctan(1+x*2^(1/2)*a^(1/2))+-1//4*2^(1/2)*a^(1/2)*log(1+a*x^2+x*2^(1/2)*a^(1/2))+1//4*2^(1/2)*a^(1/2)*log(1+a*x^2+-1*x*2^(1/2)*a^(1/2)))
@test integrate(x^-4*arccot(a*x^2), x) == :(-1//3*x^-3*arccot(a*x^2)+2//3*a*x^-1+-1//6*2^(1/2)*a^3//2*arctan(1+-1*x*2^(1/2)*a^(1/2))+-1//12*2^(1/2)*a^3//2*log(1+a*x^2+x*2^(1/2)*a^(1/2))+1//6*2^(1/2)*a^3//2*arctan(1+x*2^(1/2)*a^(1/2))+1//12*2^(1/2)*a^3//2*log(1+a*x^2+-1*x*2^(1/2)*a^(1/2)))
@test integrate(x^2*arccot(x^(1/2)), x) == :(-1//3*arctan(x^(1/2))+-1//9*x^3//2+1//3*x^(1/2)+1//15*x^5//2+1//3*x^3*arccot(x^(1/2)))
@test integrate(x*arccot(x^(1/2)), x) == :((1/2)*arctan(x^(1/2))+-1//2*x^(1/2)+1//6*x^3//2+(1/2)*x^2*arccot(x^(1/2)))
@test integrate(arccot(x^(1/2)), x) == :(x^(1/2)+-1*arctan(x^(1/2))+x*arccot(x^(1/2)))
@test integrate(x^-1*arccot(x^(1/2)), x) == :(im*Polylogarithms.polylog(2,im*x^-1//2)+-1*im*Polylogarithms.polylog(2,-1*im*x^-1//2))
@test integrate(x^-2*arccot(x^(1/2)), x) == :(x^-1//2+-1*x^-1*arccot(x^(1/2))+arctan(x^(1/2)))
@test integrate(x^-3*arccot(x^(1/2)), x) == :(-1//2*x^-1//2+-1//2*arctan(x^(1/2))+1//6*x^-3//2+-1//2*x^-2*arccot(x^(1/2)))
@test integrate(x^3//2*arccot(x^(1/2)), x) == :(-1//5*x+1//5*log(1+x)+1//10*x^2+2//5*x^5//2*arccot(x^(1/2)))
@test integrate(x^(1/2)*arccot(x^(1/2)), x) == :(-1//3*log(1+x)+1//3*x+2//3*x^3//2*arccot(x^(1/2)))
@test integrate(x^-1//2*arccot(x^(1/2)), x) == :(2*x^(1/2)*arccot(x^(1/2))+log(1+x))
@test integrate(x^-3//2*arccot(x^(1/2)), x) == :(-1*log(x)+-2*x^-1//2*arccot(x^(1/2))+log(1+x))
@test integrate(x^-5//2*arccot(x^(1/2)), x) == :(-1//3*log(1+x)+1//3*x^-1+1//3*log(x)+-2//3*x^-3//2*arccot(x^(1/2)))
@test integrate(arccot(x^-1), x) == :(-1//2*log(1+x^2)+x*arccot(x^-1))
@test integrate(x^-1*arccot(a*x^n), x) == :((1/2)*im*n^-1*Polylogarithms.polylog(2,im*a^-1*x^(-1n))+-1//2*im*n^-1*Polylogarithms.polylog(2,-1*im*a^-1*x^(-1n)))
@test integrate(x^-1*arccot(a*x^5), x) == :(-1//10*im*Polylogarithms.polylog(2,-1*im*a^-1*x^-5)+1//10*im*Polylogarithms.polylog(2,im*a^-1*x^-5))
@test integrate(x^3*arccot(a+b*x), x) == :(1//4*x^4*arccot(a+b*x)+1//12*b^-4*(a+b*x)^3+-1//2*a*b^-4*(a+b*x)^2+-1//4*x*b^-3*(1+-6*a^2)+1//4*b^-4*(1+a^4+-6*a^2)*arctan(a+b*x)+(1/2)*a*b^-4*(1+-1*a^2)*log(1+(a+b*x)^2))
@test integrate(x^2*arccot(a+b*x), x) == :(1//3*x^3*arccot(a+b*x)+1//6*b^-3*(a+b*x)^2+-1*a*x*b^-2+-1//6*b^-3*(1+-3*a^2)*log(1+(a+b*x)^2)+1//3*a*b^-3*(3+-1*a^2)*arctan(a+b*x))
@test integrate(x*arccot(a+b*x), x) == :((1/2)*x*b^-1+(1/2)*x^2*arccot(a+b*x)+-1//2*a*b^-2*log(1+(a+b*x)^2)+-1//2*b^-2*(1+-1*a^2)*arctan(a+b*x))
@test integrate(arccot(a+b*x), x) == :((1/2)*b^-1*log(1+(a+b*x)^2)+b^-1*(a+b*x)*arccot(a+b*x))
@test integrate(x^-1*arccot(a+b*x), x) == :(arccot(a+b*x)*log(2*b*x*(1+-1*im*(a+b*x))^-1*(im+-1a)^-1)+(1/2)*im*Polylogarithms.polylog(2,1+-2*b*x*(1+-1*im*(a+b*x))^-1*(im+-1a)^-1)+-1*arccot(a+b*x)*log(2*(1+-1*im*(a+b*x))^-1)+-1//2*im*Polylogarithms.polylog(2,1+-2*(1+-1*im*(a+b*x))^-1))
@test integrate(x^-2*arccot(a+b*x), x) == :(-1*x^-1*arccot(a+b*x)+b*(2+2*a^2)^-1*log(1+(a+b*x)^2)+-1*b*(1+a^2)^-1*log(x)+a*b*(1+a^2)^-1*arctan(a+b*x))
@test integrate(x^-3*arccot(a+b*x), x) == :(-1//2*x^-2*arccot(a+b*x)+b*x^-1*(2+2*a^2)^-1+a*b^2*(1+a^2)^-2*log(x)+(1/2)*b^2*(1+a^2)^-2*(1+-1*a^2)*arctan(a+b*x)+-1//2*a*b^2*(1+a^2)^-2*log(1+(a+b*x)^2))
@test integrate(x^-4*arccot(a+b*x), x) == :(-1//3*x^-3*arccot(a+b*x)+b*x^-2*(6+6*a^2)^-1+-2//3*a*b^2*x^-1*(1+a^2)^-2+-1//6*b^3*(1+a^2)^-3*(1+-3*a^2)*log(1+(a+b*x)^2)+1//3*b^3*(1+a^2)^-3*(1+-3*a^2)*log(x)+-1//3*a*b^3*(1+a^2)^-3*(3+-1*a^2)*arctan(a+b*x))
@test integrate((c+d*x^2)^-1*arccot(a+b*x), x) == :(-1//4*c^-1//2*d^-1//2*Polylogarithms.polylog(2,(a+b*x)^-1*(b*c^(1/2)+d^(1/2)*(1+-1*im*a))^-1*(b*c^(1/2)+-1*im*a*d^(1/2))*(im+a+b*x))+-1//4*c^-1//2*d^-1//2*Polylogarithms.polylog(2,-1*(a+b*x)^-1*(b*c^(1/2)+d^(1/2)*(1+im*a))^-1*(b*c^(1/2)+im*a*d^(1/2))*(im+-1a+-1*b*x))+1//4*c^-1//2*d^-1//2*Polylogarithms.polylog(2,(a+b*x)^-1*(b*c^(1/2)+im*d^(1/2)*(im+a))^-1*(b*c^(1/2)+im*a*d^(1/2))*(im+a+b*x))+1//4*c^-1//2*d^-1//2*Polylogarithms.polylog(2,-1*(a+b*x)^-1*(b*c^(1/2)+-1*d^(1/2)*(1+im*a))^-1*(b*c^(1/2)+-1*im*a*d^(1/2))*(im+-1a+-1*b*x))+-1//4*c^-1//2*d^-1//2*log((a+b*x)^-1*(im+a+b*x))*log(-1*b*(a+b*x)^-1*(b*c^(1/2)+d^(1/2)*(1+-1*im*a))^-1*(im*c^(1/2)+-1*x*d^(1/2)))+-1//4*c^-1//2*d^-1//2*log(-1*(a+b*x)^-1*(im+-1a+-1*b*x))*log(b*(a+b*x)^-1*(b*c^(1/2)+d^(1/2)*(1+im*a))^-1*(im*c^(1/2)+x*d^(1/2)))+1//4*c^-1//2*d^-1//2*log((a+b*x)^-1*(im+a+b*x))*log(-1*b*(a+b*x)^-1*(b*c^(1/2)+im*d^(1/2)*(im+a))^-1*(im*c^(1/2)+x*d^(1/2)))+1//4*c^-1//2*d^-1//2*log(-1*(a+b*x)^-1*(im+-1a+-1*b*x))*log(im*b*(a+b*x)^-1*(b*c^(1/2)+-1*d^(1/2)*(1+im*a))^-1*(c^(1/2)+im*x*d^(1/2))))
@test integrate((c+d*x)^-1*arccot(a+b*x), x) == :(d^-1*arccot(a+b*x)*log(2*b*(1+-1*im*(a+b*x))^-1*(im*d+b*c+-1*a*d)^-1*(c+d*x))+(1/2)*im*d^-1*Polylogarithms.polylog(2,1+-2*b*(1+-1*im*(a+b*x))^-1*(im*d+b*c+-1*a*d)^-1*(c+d*x))+-1*d^-1*arccot(a+b*x)*log(2*(1+-1*im*(a+b*x))^-1)+-1//2*im*d^-1*Polylogarithms.polylog(2,1+-2*(1+-1*im*(a+b*x))^-1))
@test integrate((c+d*x^(1/2))^-1*arccot(a+b*x), x) == :(im*c*d^-2*Polylogarithms.polylog(2,b^(1/2)*(c*b^(1/2)+d*(im+-1a)^(1/2))^-1*(c+d*x^(1/2)))+im*c*d^-2*Polylogarithms.polylog(2,b^(1/2)*(c*b^(1/2)+-1*d*(im+-1a)^(1/2))^-1*(c+d*x^(1/2)))+im*d^-1*x^(1/2)*log(-1*(a+b*x)^-1*(im+-1a+-1*b*x))+-1*im*c*d^-2*Polylogarithms.polylog(2,b^(1/2)*(c*b^(1/2)+d*(-1im+-1a)^(1/2))^-1*(c+d*x^(1/2)))+-1*im*c*d^-2*Polylogarithms.polylog(2,b^(1/2)*(c*b^(1/2)+-1*d*(-1im+-1a)^(1/2))^-1*(c+d*x^(1/2)))+-1*im*d^-1*x^(1/2)*log((a+b*x)^-1*(im+a+b*x))+im*c*d^-2*log((a+b*x)^-1*(im+a+b*x))*log(c+d*x^(1/2))+im*c*d^-2*log(d*(c*b^(1/2)+d*(im+-1a)^(1/2))^-1*((im+-1a)^(1/2)+-1*b^(1/2)*x^(1/2)))*log(c+d*x^(1/2))+im*c*d^-2*log(-1*d*(c*b^(1/2)+-1*d*(im+-1a)^(1/2))^-1*((im+-1a)^(1/2)+b^(1/2)*x^(1/2)))*log(c+d*x^(1/2))+-1*im*c*d^-2*log(-1*(a+b*x)^-1*(im+-1a+-1*b*x))*log(c+d*x^(1/2))+-1*im*c*d^-2*log(d*(c*b^(1/2)+d*(-1im+-1a)^(1/2))^-1*((-1im+-1a)^(1/2)+-1*b^(1/2)*x^(1/2)))*log(c+d*x^(1/2))+-1*im*c*d^-2*log(-1*d*(c*b^(1/2)+-1*d*(-1im+-1a)^(1/2))^-1*((-1im+-1a)^(1/2)+b^(1/2)*x^(1/2)))*log(c+d*x^(1/2))+-2*im*b^-1//2*d^-1*(im+a)^(1/2)*arctan(b^(1/2)*x^(1/2)*(im+a)^-1//2)+2*im*b^-1//2*d^-1*(im+-1a)^(1/2)*arctanh(b^(1/2)*x^(1/2)*(im+-1a)^-1//2))
@test integrate((c+d*x^-1//2)^-1*arccot(a+b*x), x) == :(im*c^-3*d^2*Polylogarithms.polylog(2,b^(1/2)*(c*(-1im+-1a)^(1/2)+d*b^(1/2))^-1*(d+c*x^(1/2)))+im*c^-3*d^2*Polylogarithms.polylog(2,-1*b^(1/2)*(c*(-1im+-1a)^(1/2)+-1*d*b^(1/2))^-1*(d+c*x^(1/2)))+(1/2)*im*x*c^-1*log(-1*(a+b*x)^-1*(im+-1a+-1*b*x))+(1/2)*b^-1*c^-1*(1+im*a)*log(im+-1a+-1*b*x)+(1/2)*b^-1*c^-1*(1+-1*im*a)*log(im+a+b*x)+-1*im*c^-3*d^2*Polylogarithms.polylog(2,b^(1/2)*(c*(im+-1a)^(1/2)+d*b^(1/2))^-1*(d+c*x^(1/2)))+-1*im*c^-3*d^2*Polylogarithms.polylog(2,-1*b^(1/2)*(c*(im+-1a)^(1/2)+-1*d*b^(1/2))^-1*(d+c*x^(1/2)))+-1//2*im*x*c^-1*log((a+b*x)^-1*(im+a+b*x))+im*d*c^-2*x^(1/2)*log((a+b*x)^-1*(im+a+b*x))+im*c^-3*d^2*log(-1*(a+b*x)^-1*(im+-1a+-1*b*x))*log(d+c*x^(1/2))+im*c^-3*d^2*log(c*(c*(-1im+-1a)^(1/2)+d*b^(1/2))^-1*((-1im+-1a)^(1/2)+-1*b^(1/2)*x^(1/2)))*log(d+c*x^(1/2))+im*c^-3*d^2*log(c*(c*(-1im+-1a)^(1/2)+-1*d*b^(1/2))^-1*((-1im+-1a)^(1/2)+b^(1/2)*x^(1/2)))*log(d+c*x^(1/2))+-1*im*d*c^-2*x^(1/2)*log(-1*(a+b*x)^-1*(im+-1a+-1*b*x))+-1*im*c^-3*d^2*log((a+b*x)^-1*(im+a+b*x))*log(d+c*x^(1/2))+-1*im*c^-3*d^2*log(c*(c*(im+-1a)^(1/2)+d*b^(1/2))^-1*((im+-1a)^(1/2)+-1*b^(1/2)*x^(1/2)))*log(d+c*x^(1/2))+-1*im*c^-3*d^2*log(c*(c*(im+-1a)^(1/2)+-1*d*b^(1/2))^-1*((im+-1a)^(1/2)+b^(1/2)*x^(1/2)))*log(d+c*x^(1/2))+-2*im*d*b^-1//2*c^-2*(im+-1a)^(1/2)*arctanh(b^(1/2)*x^(1/2)*(im+-1a)^-1//2)+2*im*d*b^-1//2*c^-2*(im+a)^(1/2)*arctan(b^(1/2)*x^(1/2)*(im+a)^-1//2))
@test integrate((a+b*x+c*x^2)^-1*arccot(d+e*x), x) == :((b^2+-4*a*c)^-1//2*arccot(d+e*x)*log(2*e*(1+-1*im*(d+e*x))^-1*(e*(b+-1*(b^2+-4*a*c)^(1/2))+2*c*(im+-1d))^-1*(b+-1*(b^2+-4*a*c)^(1/2)+2*c*x))+(1/2)*im*(b^2+-4*a*c)^-1//2*Polylogarithms.polylog(2,1+(1+-1*im*(d+e*x))^-1*(b*e+-1*e*(b^2+-4*a*c)^(1/2)+-2*c*d+2*im*c)^-1*(-4*c*(d+e*x)+-2*e*(b+-1*(b^2+-4*a*c)^(1/2))+4*c*d))+-1*(b^2+-4*a*c)^-1//2*arccot(d+e*x)*log(2*e*(1+-1*im*(d+e*x))^-1*(e*(b+(b^2+-4*a*c)^(1/2))+2*c*(im+-1d))^-1*(b+(b^2+-4*a*c)^(1/2)+2*c*x))+-1//2*im*(b^2+-4*a*c)^-1//2*Polylogarithms.polylog(2,1+(1+-1*im*(d+e*x))^-1*(e*(b+(b^2+-4*a*c)^(1/2))+2*c*(im+-1d))^-1*(-4*c*(d+e*x)+-2*e*(b+(b^2+-4*a*c)^(1/2))+4*c*d)))
@test integrate((1+a^2+b^2*x^2+2*a*b*x)^-1//2*arccot(a+b*x), x) == :(im*b^-1*Polylogarithms.polylog(2,im*(1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2)+-1*im*b^-1*Polylogarithms.polylog(2,-1*im*(1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2)+-2*im*b^-1*arccot(a+b*x)*arctan((1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2))
@test integrate((c*(1+a^2)+c*b^2*x^2+2*a*b*c*x)^-1//2*arccot(a+b*x), x) == :(im*b^-1*(1+(a+b*x)^2)^(1/2)*(c+c*(a+b*x)^2)^-1//2*Polylogarithms.polylog(2,im*(1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2)+-1*im*b^-1*(1+(a+b*x)^2)^(1/2)*(c+c*(a+b*x)^2)^-1//2*Polylogarithms.polylog(2,-1*im*(1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2)+-2*im*b^-1*(1+(a+b*x)^2)^(1/2)*(c+c*(a+b*x)^2)^-1//2*arccot(a+b*x)*arctan((1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2))
@test integrate((a+b*x)^2*(1+a^2+b^2*x^2+2*a*b*x)^-1//2*arccot(a+b*x), x) == :((1/2)*b^-1*(1+(a+b*x)^2)^(1/2)+(1/2)*im*b^-1*Polylogarithms.polylog(2,-1*im*(1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2)+-1//2*im*b^-1*Polylogarithms.polylog(2,im*(1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2)+im*b^-1*arccot(a+b*x)*arctan((1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2)+(1/2)*b^-1*(1+(a+b*x)^2)^(1/2)*(a+b*x)*arccot(a+b*x))
@test integrate((a+b*x)^2*(c*(1+a^2)+c*b^2*x^2+2*a*b*c*x)^-1//2*arccot(a+b*x), x) == :((1/2)*b^-1*c^-1*(c+c*(a+b*x)^2)^(1/2)+(1/2)*im*b^-1*(1+(a+b*x)^2)^(1/2)*(c+c*(a+b*x)^2)^-1//2*Polylogarithms.polylog(2,-1*im*(1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2)+(1/2)*b^-1*c^-1*(c+c*(a+b*x)^2)^(1/2)*(a+b*x)*arccot(a+b*x)+-1//2*im*b^-1*(1+(a+b*x)^2)^(1/2)*(c+c*(a+b*x)^2)^-1//2*Polylogarithms.polylog(2,im*(1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2)+im*b^-1*(1+(a+b*x)^2)^(1/2)*(c+c*(a+b*x)^2)^-1//2*arccot(a+b*x)*arctan((1+im*(a+b*x))^(1/2)*(1+-1*im*(a+b*x))^-1//2))
@test integrate((a+b*x)^2*arccot(a+b*x), x) == :(-1//6*b^-1*log(1+(a+b*x)^2)+1//6*b^-1*(a+b*x)^2+1//3*b^-1*(a+b*x)^3*arccot(a+b*x))
@test integrate((a+b*x)*arccot(a+b*x), x) == :((1/2)*x+-1//2*b^-1*arctan(a+b*x)+(1/2)*b^-1*(a+b*x)^2*arccot(a+b*x))
@test integrate((a+b*x)^-1*arccot(a+b*x), x) == :((1/2)*im*b^-1*Polylogarithms.polylog(2,im*(a+b*x)^-1)+-1//2*im*b^-1*Polylogarithms.polylog(2,-1*im*(a+b*x)^-1))
@test integrate((a+b*x)^-2*arccot(a+b*x), x) == :((1/2)*b^-1*log(1+(a+b*x)^2)+-1*b^-1*log(a+b*x)+-1*b^-1*(a+b*x)^-1*arccot(a+b*x))
@test integrate((2+2x)^-1*arccot(1+x), x) == :(-1//4*im*Polylogarithms.polylog(2,-1*im*(1+x)^-1)+1//4*im*Polylogarithms.polylog(2,im*(1+x)^-1))
@test integrate((d*x+a*d*b^-1)^-1*arccot(a+b*x), x) == :((1/2)*im*d^-1*Polylogarithms.polylog(2,im*(a+b*x)^-1)+-1//2*im*d^-1*Polylogarithms.polylog(2,-1*im*(a+b*x)^-1))
@test integrate((e+f*x)^3*(a+b*arccot(c+d*x)), x) == :(1//4*f^-1*(e+f*x)^4*(a+b*arccot(c+d*x))+1//12*b*d^-4*f^3*(c+d*x)^3+(1/2)*b*d^-4*f^2*(c+d*x)^2*(d*e+-1*c*f)+1//4*b*f*x*d^-3*(-1*f^2*(1+-6*c^2)+6*d^2*e^2+-12*c*d*e*f)+1//4*b*d^-4*f^-1*(d^4*e^4+f^4*(1+c^4+-6*c^2)+-1*d^2*e^2*f^2*(6+-6*c^2)+-4*c*f*d^3*e^3+4*c*d*e*f^3*(3+-1*c^2))*arctan(c+d*x)+(1/2)*b*d^-4*(d*e+-1*c*f)*(d*e+-1*f*(1+c))*(f+d*e+-1*c*f)*log(1+(c+d*x)^2))
@test integrate((e+f*x)^2*(a+b*arccot(c+d*x)), x) == :(1//3*f^-1*(e+f*x)^3*(a+b*arccot(c+d*x))+1//6*b*d^-3*f^2*(c+d*x)^2+1//6*b*d^-3*(-1*f^2*(1+-3*c^2)+3*d^2*e^2+-6*c*d*e*f)*log(1+(c+d*x)^2)+b*f*x*d^-2*(d*e+-1*c*f)+1//3*b*d^-3*f^-1*(d*e+-1*c*f)*(d^2*e^2+-1*f^2*(3+-1*c^2)+-2*c*d*e*f)*arctan(c+d*x))
@test integrate((a+b*arccot(c+d*x))*(e+f*x), x) == :((1/2)*f^-1*(e+f*x)^2*(a+b*arccot(c+d*x))+(1/2)*b*f*x*d^-1+(1/2)*b*d^-2*(d*e+-1*c*f)*log(1+(c+d*x)^2)+(1/2)*b*d^-2*f^-1*(d*e+-1*f*(1+c))*(f+d*e+-1*c*f)*arctan(c+d*x))
@test integrate(a+b*arccot(c+d*x), x) == :(a*x+(1/2)*b*d^-1*log(1+(c+d*x)^2)+b*d^-1*(c+d*x)*arccot(c+d*x))
@test integrate((e+f*x)^-1*(a+b*arccot(c+d*x)), x) == :(f^-1*(a+b*arccot(c+d*x))*log(2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+-1*f^-1*(a+b*arccot(c+d*x))*log(2*(1+-1*im*(c+d*x))^-1)+(1/2)*im*b*f^-1*Polylogarithms.polylog(2,1+-2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+-1//2*im*b*f^-1*Polylogarithms.polylog(2,1+-2*(1+-1*im*(c+d*x))^-1))
@test integrate((e+f*x)^-2*(a+b*arccot(c+d*x)), x) == :(-1*f^-1*(e+f*x)^-1*(a+b*arccot(c+d*x))+b*d*(2*d^2*e^2+2*f^2*(1+c^2)+-4*c*d*e*f)^-1*log(1+c^2+d^2*x^2+2*c*d*x)+-1*b*d*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*log(e+f*x)+-1*b*d*f^-1*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*(d*e+-1*c*f)*arctan(c+d*x))
@test integrate((e+f*x)^-3*(a+b*arccot(c+d*x)), x) == :(-1//2*f^-1*(e+f*x)^-2*(a+b*arccot(c+d*x))+b*d*(e+f*x)^-1*(2*d^2*e^2+2*f^2*(1+c^2)+-4*c*d*e*f)^-1+(1/2)*b*d^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-2*(d*e+-1*c*f)*log(1+c^2+d^2*x^2+2*c*d*x)+-1*b*d^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-2*(d*e+-1*c*f)*log(e+f*x)+-1//2*b*d^2*f^-1*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-2*(d*e+-1*f*(1+c))*(f+d*e+-1*c*f)*arctan(c+d*x))
@test integrate((a+b*arccot(c+d*x))^2*(e+f*x)^2, x) == :(1//3*f^-1*(a+b*arccot(c+d*x))^2*(e+f*x)^3+-1//3*b^2*d^-3*f^2*arctan(c+d*x)+1//3*im*d^-3*(a+b*arccot(c+d*x))^2*(-1*f^2*(1+-3*c^2)+3*d^2*e^2+-6*c*d*e*f)+1//3*x*b^2*d^-2*f^2+f*b^2*d^-3*(d*e+-1*c*f)*log(1+(c+d*x)^2)+-2//3*b*d^-3*(a+b*arccot(c+d*x))*(-1*f^2*(1+-3*c^2)+3*d^2*e^2+-6*c*d*e*f)*log(2*(1+im*(c+d*x))^-1)+-1//3*d^-3*f^-1*(a+b*arccot(c+d*x))^2*(d*e+-1*c*f)*(d^2*e^2+-1*f^2*(3+-1*c^2)+-2*c*d*e*f)+1//3*im*b^2*d^-3*(-1*f^2*(1+-3*c^2)+3*d^2*e^2+-6*c*d*e*f)*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1)+1//3*b*d^-3*f^2*(c+d*x)^2*(a+b*arccot(c+d*x))+2*a*b*f*x*d^-2*(d*e+-1*c*f)+2*f*b^2*d^-3*(c+d*x)*(d*e+-1*c*f)*arccot(c+d*x))
@test integrate((a+b*arccot(c+d*x))^2*(e+f*x), x) == :((1/2)*f^-1*(a+b*arccot(c+d*x))^2*(e+f*x)^2+im*d^-2*(a+b*arccot(c+d*x))^2*(d*e+-1*c*f)+(1/2)*f*b^2*d^-2*log(1+(c+d*x)^2)+im*b^2*d^-2*(d*e+-1*c*f)*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1)+a*b*f*x*d^-1+f*b^2*d^-2*(c+d*x)*arccot(c+d*x)+-2*b*d^-2*(a+b*arccot(c+d*x))*(d*e+-1*c*f)*log(2*(1+im*(c+d*x))^-1)+-1//2*d^-2*f^-1*(a+b*arccot(c+d*x))^2*(d*e+-1*f*(1+c))*(f+d*e+-1*c*f))
@test integrate((a+b*arccot(c+d*x))^2, x) == :(im*d^-1*(a+b*arccot(c+d*x))^2+d^-1*(a+b*arccot(c+d*x))^2*(c+d*x)+im*b^2*d^-1*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1)+-2*b*d^-1*(a+b*arccot(c+d*x))*log(2*(1+im*(c+d*x))^-1))
@test integrate((a+b*arccot(c+d*x))^2*(e+f*x)^-1, x) == :(f^-1*(a+b*arccot(c+d*x))^2*log(2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+(1/2)*b^2*f^-1*Polylogarithms.polylog(3,1+-2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+-1*f^-1*(a+b*arccot(c+d*x))^2*log(2*(1+-1*im*(c+d*x))^-1)+-1//2*b^2*f^-1*Polylogarithms.polylog(3,1+-2*(1+-1*im*(c+d*x))^-1)+im*b*f^-1*(a+b*arccot(c+d*x))*Polylogarithms.polylog(2,1+-2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+-1*im*b*f^-1*(a+b*arccot(c+d*x))*Polylogarithms.polylog(2,1+-2*(1+-1*im*(c+d*x))^-1))
@test integrate((a+b*arccot(c+d*x))^2*(e+f*x)^-2, x) == :(-1*f^-1*(a+b*arccot(c+d*x))^2*(e+f*x)^-1+im*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)^2+im*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1)+im*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*Polylogarithms.polylog(2,1+-2*(1+-1*im*(c+d*x))^-1)+a*b*d*(f^2+(d*e+-1*c*f)^2)^-1*log(1+(c+d*x)^2)+-1*im*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*Polylogarithms.polylog(2,1+-2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+-2*a*b*d*(f^2+(d*e+-1*c*f)^2)^-1*log(e+f*x)+-2*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)*log(2*(1+im*(c+d*x))^-1)+-2*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)*log(2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+2*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)*log(2*(1+-1*im*(c+d*x))^-1)+d*b^2*f^-1*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)^2*(d*e+-1*c*f)+-2*a*b*d*f^-1*(f^2+(d*e+-1*c*f)^2)^-1*(d*e+-1*c*f)*arctan(c+d*x))
@test integrate((a+b*arccot(c+d*x))^3*(e+f*x)^2, x) == :(1//3*f^-1*(a+b*arccot(c+d*x))^3*(e+f*x)^3+(1/2)*b*d^-3*f^2*(a+b*arccot(c+d*x))^2+(1/2)*b^3*d^-3*f^2*log(1+(c+d*x)^2)+-1//2*b^3*d^-3*(-1*f^2*(1+-3*c^2)+3*d^2*e^2+-6*c*d*e*f)*Polylogarithms.polylog(3,1+-2*(1+im*(c+d*x))^-1)+1//3*im*d^-3*(a+b*arccot(c+d*x))^3*(-1*f^2*(1+-3*c^2)+3*d^2*e^2+-6*c*d*e*f)+a*x*b^2*d^-2*f^2+b^3*d^-3*f^2*(c+d*x)*arccot(c+d*x)+(1/2)*b*d^-3*f^2*(a+b*arccot(c+d*x))^2*(c+d*x)^2+-1*b*d^-3*(a+b*arccot(c+d*x))^2*(-1*f^2*(1+-3*c^2)+3*d^2*e^2+-6*c*d*e*f)*log(2*(1+im*(c+d*x))^-1)+-1//3*d^-3*f^-1*(a+b*arccot(c+d*x))^3*(d*e+-1*c*f)*(d^2*e^2+-1*f^2*(3+-1*c^2)+-2*c*d*e*f)+im*b^2*d^-3*(a+b*arccot(c+d*x))*(-1*f^2*(1+-3*c^2)+3*d^2*e^2+-6*c*d*e*f)*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1)+-6*f*b^2*d^-3*(a+b*arccot(c+d*x))*(d*e+-1*c*f)*log(2*(1+im*(c+d*x))^-1)+3*im*b*f*d^-3*(a+b*arccot(c+d*x))^2*(d*e+-1*c*f)+3*im*f*b^3*d^-3*(d*e+-1*c*f)*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1)+3*b*f*d^-3*(a+b*arccot(c+d*x))^2*(c+d*x)*(d*e+-1*c*f))
@test integrate((a+b*arccot(c+d*x))^3*(e+f*x), x) == :((1/2)*f^-1*(a+b*arccot(c+d*x))^3*(e+f*x)^2+im*d^-2*(a+b*arccot(c+d*x))^3*(d*e+-1*c*f)+-3//2*b^3*d^-2*(d*e+-1*c*f)*Polylogarithms.polylog(3,1+-2*(1+im*(c+d*x))^-1)+-3*b*d^-2*(a+b*arccot(c+d*x))^2*(d*e+-1*c*f)*log(2*(1+im*(c+d*x))^-1)+-3*f*b^2*d^-2*(a+b*arccot(c+d*x))*log(2*(1+im*(c+d*x))^-1)+-1//2*d^-2*f^-1*(a+b*arccot(c+d*x))^3*(d*e+-1*f*(1+c))*(f+d*e+-1*c*f)+3//2*im*b*f*d^-2*(a+b*arccot(c+d*x))^2+3//2*im*f*b^3*d^-2*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1)+3//2*b*f*d^-2*(a+b*arccot(c+d*x))^2*(c+d*x)+3*im*b^2*d^-2*(a+b*arccot(c+d*x))*(d*e+-1*c*f)*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1))
@test integrate((a+b*arccot(c+d*x))^3, x) == :(im*d^-1*(a+b*arccot(c+d*x))^3+d^-1*(a+b*arccot(c+d*x))^3*(c+d*x)+-3//2*b^3*d^-1*Polylogarithms.polylog(3,1+-2*(1+im*(c+d*x))^-1)+-3*b*d^-1*(a+b*arccot(c+d*x))^2*log(2*(1+im*(c+d*x))^-1)+3*im*b^2*d^-1*(a+b*arccot(c+d*x))*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1))
@test integrate((a+b*arccot(c+d*x))^3*(e+f*x)^-1, x) == :(f^-1*(a+b*arccot(c+d*x))^3*log(2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+-1*f^-1*(a+b*arccot(c+d*x))^3*log(2*(1+-1*im*(c+d*x))^-1)+-3//2*b^2*f^-1*(a+b*arccot(c+d*x))*Polylogarithms.polylog(3,1+-2*(1+-1*im*(c+d*x))^-1)+-3//4*im*b^3*f^-1*Polylogarithms.polylog(4,1+-2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+3//2*b^2*f^-1*(a+b*arccot(c+d*x))*Polylogarithms.polylog(3,1+-2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+3//4*im*b^3*f^-1*Polylogarithms.polylog(4,1+-2*(1+-1*im*(c+d*x))^-1)+-3//2*im*b*f^-1*(a+b*arccot(c+d*x))^2*Polylogarithms.polylog(2,1+-2*(1+-1*im*(c+d*x))^-1)+3//2*im*b*f^-1*(a+b*arccot(c+d*x))^2*Polylogarithms.polylog(2,1+-2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x)))
@test integrate((a+b*arccot(c+d*x))^3*(e+f*x)^-2, x) == :(-1*f^-1*(a+b*arccot(c+d*x))^3*(e+f*x)^-1+-3*d*b^3*(2*d^2*e^2+2*f^2*(1+c^2)+-4*c*d*e*f)^-1*Polylogarithms.polylog(3,1+-2*(1+im*(c+d*x))^-1)+-3*d*b^3*(2*d^2*e^2+2*f^2*(1+c^2)+-4*c*d*e*f)^-1*Polylogarithms.polylog(3,1+-2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+3*d*b^3*(2*d^2*e^2+2*f^2*(1+c^2)+-4*c*d*e*f)^-1*Polylogarithms.polylog(3,1+-2*(1+-1*im*(c+d*x))^-1)+im*d*b^3*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)^3+-3*b*d*a^2*(f^2+(d*e+-1*c*f)^2)^-1*log(e+f*x)+-3*d*b^3*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)^2*log(2*(1+im*(c+d*x))^-1)+-3*d*b^3*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)^2*log(2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+3*b*d*a^2*(2*f^2+2*(d*e+-1*c*f)^2)^-1*log(1+(c+d*x)^2)+3*d*b^3*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)^2*log(2*(1+-1*im*(c+d*x))^-1)+d*b^3*f^-1*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)^3*(d*e+-1*c*f)+-6*a*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)*log(2*(1+im*(c+d*x))^-1)+-6*a*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)*log(2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+-3*im*a*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*Polylogarithms.polylog(2,1+-2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))+-3*im*d*b^3*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*Polylogarithms.polylog(2,1+-2*d*(1+-1*im*(c+d*x))^-1*(im*f+d*e+-1*c*f)^-1*(e+f*x))*arccot(c+d*x)+3*im*a*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)^2+3*im*a*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1)+3*im*a*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*Polylogarithms.polylog(2,1+-2*(1+-1*im*(c+d*x))^-1)+3*im*d*b^3*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*Polylogarithms.polylog(2,1+-2*(1+im*(c+d*x))^-1)*arccot(c+d*x)+3*im*d*b^3*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*Polylogarithms.polylog(2,1+-2*(1+-1*im*(c+d*x))^-1)*arccot(c+d*x)+6*a*d*b^2*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)*log(2*(1+-1*im*(c+d*x))^-1)+-3*b*d*a^2*f^-1*(f^2+(d*e+-1*c*f)^2)^-1*(d*e+-1*c*f)*arctan(c+d*x)+3*a*d*b^2*f^-1*(d^2*e^2+f^2*(1+c^2)+-2*c*d*e*f)^-1*arccot(c+d*x)^2*(d*e+-1*c*f))
@test integrate(x^3*arccot(a+b*x^4), x) == :(1//8*b^-1*log(1+(a+b*x^4)^2)+1//4*b^-1*(a+b*x^4)*arccot(a+b*x^4))
@test integrate(x^(-1+n)*arccot(a+b*x^n), x) == :((1/2)*b^-1*n^-1*log(1+(a+b*x^n)^2)+b^-1*n^-1*(a+b*x^n)*arccot(a+b*x^n))
@test integrate((1+-1*c^2*x^2)^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2)))^3, x) == :(-2*c^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2)))^3*arccoth(1+-2*(1+im*(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1)+-3//2*b^2*c^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2)))*Polylogarithms.polylog(3,1+-2*(1+c*x)^-1//2*(1+-1*c*x)^(1/2)*(im+(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1)+-3//4*im*b^3*c^-1*Polylogarithms.polylog(4,1+-2*im*(im+(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1)+3//2*b^2*c^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2)))*Polylogarithms.polylog(3,1+-2*im*(im+(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1)+3//4*im*b^3*c^-1*Polylogarithms.polylog(4,1+-2*(1+c*x)^-1//2*(1+-1*c*x)^(1/2)*(im+(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1)+-3//2*im*b*c^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2)))^2*Polylogarithms.polylog(2,1+-2*(1+c*x)^-1//2*(1+-1*c*x)^(1/2)*(im+(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1)+3//2*im*b*c^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2)))^2*Polylogarithms.polylog(2,1+-2*im*(im+(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1))
@test integrate((1+-1*c^2*x^2)^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2)))^2, x) == :((1/2)*b^2*c^-1*Polylogarithms.polylog(3,1+-2*im*(im+(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1)+-2*c^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2)))^2*arccoth(1+-2*(1+im*(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1)+-1//2*b^2*c^-1*Polylogarithms.polylog(3,1+-2*(1+c*x)^-1//2*(1+-1*c*x)^(1/2)*(im+(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1)+im*b*c^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2)))*Polylogarithms.polylog(2,1+-2*im*(im+(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1)+-1*im*b*c^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2)))*Polylogarithms.polylog(2,1+-2*(1+c*x)^-1//2*(1+-1*c*x)^(1/2)*(im+(1+c*x)^-1//2*(1+-1*c*x)^(1/2))^-1))
@test integrate((1+-1*c^2*x^2)^-1*(a+b*arccot((1+c*x)^-1//2*(1+-1*c*x)^(1/2))), x) == :(-1*a*c^-1*log((1+c*x)^-1//2*(1+-1*c*x)^(1/2))+(1/2)*im*b*c^-1*Polylogarithms.polylog(2,-1*im*(1+c*x)^(1/2)*(1+-1*c*x)^-1//2)+-1//2*im*b*c^-1*Polylogarithms.polylog(2,im*(1+c*x)^(1/2)*(1+-1*c*x)^-1//2))
@test integrate(arccot(tan(a+b*x)), x) == :(-1//2*b^-1*arccot(tan(a+b*x))^2)
@test integrate(x^2*arccot(c+d*tan(a+b*x)), x) == :(-1//8*b^-3*Polylogarithms.polylog(4,-1*(c+im*(1+d))^-1*(c+im*(1+-1d))*exp(2*im*a+2*im*b*x))+1//3*x^3*arccot(c+d*tan(a+b*x))+1//8*b^-3*Polylogarithms.polylog(4,-1*(1+-1d+im*c)^-1*(1+d+im*c)*exp(2*im*a+2*im*b*x))+-1//4*b^-1*x^2*Polylogarithms.polylog(2,-1*(1+-1d+im*c)^-1*(1+d+im*c)*exp(2*im*a+2*im*b*x))+-1//6*im*x^3*log(1+(1+-1d+im*c)^-1*(1+d+im*c)*exp(2*im*a+2*im*b*x))+1//4*b^-1*x^2*Polylogarithms.polylog(2,-1*(c+im*(1+d))^-1*(c+im*(1+-1d))*exp(2*im*a+2*im*b*x))+1//6*im*x^3*log(1+(c+im*(1+d))^-1*(c+im*(1+-1d))*exp(2*im*a+2*im*b*x))+-1//4*im*x*b^-2*Polylogarithms.polylog(3,-1*(1+-1d+im*c)^-1*(1+d+im*c)*exp(2*im*a+2*im*b*x))+1//4*im*x*b^-2*Polylogarithms.polylog(3,-1*(c+im*(1+d))^-1*(c+im*(1+-1d))*exp(2*im*a+2*im*b*x)))
@test integrate(x*arccot(c+d*tan(a+b*x)), x) == :((1/2)*x^2*arccot(c+d*tan(a+b*x))+-1//4*im*x^2*log(1+(1+-1d+im*c)^-1*(1+d+im*c)*exp(2*im*a+2*im*b*x))+-1//4*x*b^-1*Polylogarithms.polylog(2,-1*(1+-1d+im*c)^-1*(1+d+im*c)*exp(2*im*a+2*im*b*x))+-1//8*im*b^-2*Polylogarithms.polylog(3,-1*(1+-1d+im*c)^-1*(1+d+im*c)*exp(2*im*a+2*im*b*x))+1//4*im*x^2*log(1+(c+im*(1+d))^-1*(c+im*(1+-1d))*exp(2*im*a+2*im*b*x))+1//4*x*b^-1*Polylogarithms.polylog(2,-1*(c+im*(1+d))^-1*(c+im*(1+-1d))*exp(2*im*a+2*im*b*x))+1//8*im*b^-2*Polylogarithms.polylog(3,-1*(c+im*(1+d))^-1*(c+im*(1+-1d))*exp(2*im*a+2*im*b*x)))
@test integrate(arccot(c+d*tan(a+b*x)), x) == :(x*arccot(c+d*tan(a+b*x))+-1//4*b^-1*Polylogarithms.polylog(2,-1*(1+-1d+im*c)^-1*(1+d+im*c)*exp(2*im*a+2*im*b*x))+1//4*b^-1*Polylogarithms.polylog(2,-1*(c+im*(1+d))^-1*(c+im*(1+-1d))*exp(2*im*a+2*im*b*x))+(1/2)*im*x*log(1+(c+im*(1+d))^-1*(c+im*(1+-1d))*exp(2*im*a+2*im*b*x))+-1//2*im*x*log(1+(1+-1d+im*c)^-1*(1+d+im*c)*exp(2*im*a+2*im*b*x)))
@test integrate(x^2*arccot(c+(1+im*c)*tan(a+b*x)), x) == :(-1//8*b^-3*Polylogarithms.polylog(4,im*c*exp(2*im*a+2*im*b*x))+1//3*x^3*arccot(c+(1+im*c)*tan(a+b*x))+1//12*b*x^4+1//4*b^-1*x^2*Polylogarithms.polylog(2,im*c*exp(2*im*a+2*im*b*x))+1//6*im*x^3*log(1+-1*im*c*exp(2*im*a+2*im*b*x))+1//4*im*x*b^-2*Polylogarithms.polylog(3,im*c*exp(2*im*a+2*im*b*x)))
@test integrate(x*arccot(c+(1+im*c)*tan(a+b*x)), x) == :((1/2)*x^2*arccot(c+(1+im*c)*tan(a+b*x))+1//6*b*x^3+1//4*im*x^2*log(1+-1*im*c*exp(2*im*a+2*im*b*x))+1//4*x*b^-1*Polylogarithms.polylog(2,im*c*exp(2*im*a+2*im*b*x))+1//8*im*b^-2*Polylogarithms.polylog(3,im*c*exp(2*im*a+2*im*b*x)))
@test integrate(arccot(c+(1+im*c)*tan(a+b*x)), x) == :(x*arccot(c+(1+im*c)*tan(a+b*x))+(1/2)*b*x^2+1//4*b^-1*Polylogarithms.polylog(2,im*c*exp(2*im*a+2*im*b*x))+(1/2)*im*x*log(1+-1*im*c*exp(2*im*a+2*im*b*x)))
@test integrate(x^2*arccot(c+-1*(1+-1*im*c)*tan(a+b*x)), x) == :(-1//12*b*x^4+1//3*x^3*arccot(c+-1*(1+-1*im*c)*tan(a+b*x))+1//8*b^-3*Polylogarithms.polylog(4,-1*im*c*exp(2*im*a+2*im*b*x))+-1//4*b^-1*x^2*Polylogarithms.polylog(2,-1*im*c*exp(2*im*a+2*im*b*x))+-1//6*im*x^3*log(1+im*c*exp(2*im*a+2*im*b*x))+-1//4*im*x*b^-2*Polylogarithms.polylog(3,-1*im*c*exp(2*im*a+2*im*b*x)))
@test integrate(x*arccot(c+-1*(1+-1*im*c)*tan(a+b*x)), x) == :((1/2)*x^2*arccot(c+-1*(1+-1*im*c)*tan(a+b*x))+-1//6*b*x^3+-1//4*im*x^2*log(1+im*c*exp(2*im*a+2*im*b*x))+-1//4*x*b^-1*Polylogarithms.polylog(2,-1*im*c*exp(2*im*a+2*im*b*x))+-1//8*im*b^-2*Polylogarithms.polylog(3,-1*im*c*exp(2*im*a+2*im*b*x)))
@test integrate(arccot(c+-1*(1+-1*im*c)*tan(a+b*x)), x) == :(x*arccot(c+-1*(1+-1*im*c)*tan(a+b*x))+-1//2*b*x^2+-1//4*b^-1*Polylogarithms.polylog(2,-1*im*c*exp(2*im*a+2*im*b*x))+-1//2*im*x*log(1+im*c*exp(2*im*a+2*im*b*x)))
@test integrate(arccot(cot(a+b*x)), x) == :((1/2)*b^-1*arccot(cot(a+b*x))^2)
@test integrate(x^2*arccot(c+d*cot(a+b*x)), x) == :(-1//8*b^-3*Polylogarithms.polylog(4,(c+im*(1+-1d))^-1*(c+im*(1+d))*exp(2*im*a+2*im*b*x))+1//3*x^3*arccot(c+d*cot(a+b*x))+1//8*b^-3*Polylogarithms.polylog(4,(1+d+im*c)^-1*(1+-1d+im*c)*exp(2*im*a+2*im*b*x))+-1//4*b^-1*x^2*Polylogarithms.polylog(2,(1+d+im*c)^-1*(1+-1d+im*c)*exp(2*im*a+2*im*b*x))+-1//6*im*x^3*log(1+-1*(1+d+im*c)^-1*(1+-1d+im*c)*exp(2*im*a+2*im*b*x))+1//4*b^-1*x^2*Polylogarithms.polylog(2,(c+im*(1+-1d))^-1*(c+im*(1+d))*exp(2*im*a+2*im*b*x))+1//6*im*x^3*log(1+-1*(c+im*(1+-1d))^-1*(c+im*(1+d))*exp(2*im*a+2*im*b*x))+-1//4*im*x*b^-2*Polylogarithms.polylog(3,(1+d+im*c)^-1*(1+-1d+im*c)*exp(2*im*a+2*im*b*x))+1//4*im*x*b^-2*Polylogarithms.polylog(3,(c+im*(1+-1d))^-1*(c+im*(1+d))*exp(2*im*a+2*im*b*x)))
@test integrate(x*arccot(c+d*cot(a+b*x)), x) == :((1/2)*x^2*arccot(c+d*cot(a+b*x))+-1//4*im*x^2*log(1+-1*(1+d+im*c)^-1*(1+-1d+im*c)*exp(2*im*a+2*im*b*x))+-1//4*x*b^-1*Polylogarithms.polylog(2,(1+d+im*c)^-1*(1+-1d+im*c)*exp(2*im*a+2*im*b*x))+-1//8*im*b^-2*Polylogarithms.polylog(3,(1+d+im*c)^-1*(1+-1d+im*c)*exp(2*im*a+2*im*b*x))+1//4*im*x^2*log(1+-1*(c+im*(1+-1d))^-1*(c+im*(1+d))*exp(2*im*a+2*im*b*x))+1//4*x*b^-1*Polylogarithms.polylog(2,(c+im*(1+-1d))^-1*(c+im*(1+d))*exp(2*im*a+2*im*b*x))+1//8*im*b^-2*Polylogarithms.polylog(3,(c+im*(1+-1d))^-1*(c+im*(1+d))*exp(2*im*a+2*im*b*x)))
@test integrate(arccot(c+d*cot(a+b*x)), x) == :(x*arccot(c+d*cot(a+b*x))+-1//4*b^-1*Polylogarithms.polylog(2,(1+d+im*c)^-1*(1+-1d+im*c)*exp(2*im*a+2*im*b*x))+1//4*b^-1*Polylogarithms.polylog(2,(c+im*(1+-1d))^-1*(c+im*(1+d))*exp(2*im*a+2*im*b*x))+(1/2)*im*x*log(1+-1*(c+im*(1+-1d))^-1*(c+im*(1+d))*exp(2*im*a+2*im*b*x))+-1//2*im*x*log(1+-1*(1+d+im*c)^-1*(1+-1d+im*c)*exp(2*im*a+2*im*b*x)))
@test integrate(x^2*arccot(c+(1+-1*im*c)*cot(a+b*x)), x) == :(-1//12*b*x^4+1//3*x^3*arccot(c+(1+-1*im*c)*cot(a+b*x))+1//8*b^-3*Polylogarithms.polylog(4,im*c*exp(2*im*a+2*im*b*x))+-1//4*b^-1*x^2*Polylogarithms.polylog(2,im*c*exp(2*im*a+2*im*b*x))+-1//6*im*x^3*log(1+-1*im*c*exp(2*im*a+2*im*b*x))+-1//4*im*x*b^-2*Polylogarithms.polylog(3,im*c*exp(2*im*a+2*im*b*x)))
@test integrate(x*arccot(c+(1+-1*im*c)*cot(a+b*x)), x) == :((1/2)*x^2*arccot(c+(1+-1*im*c)*cot(a+b*x))+-1//6*b*x^3+-1//4*im*x^2*log(1+-1*im*c*exp(2*im*a+2*im*b*x))+-1//4*x*b^-1*Polylogarithms.polylog(2,im*c*exp(2*im*a+2*im*b*x))+-1//8*im*b^-2*Polylogarithms.polylog(3,im*c*exp(2*im*a+2*im*b*x)))
@test integrate(arccot(c+(1+-1*im*c)*cot(a+b*x)), x) == :(x*arccot(c+(1+-1*im*c)*cot(a+b*x))+-1//2*b*x^2+-1//4*b^-1*Polylogarithms.polylog(2,im*c*exp(2*im*a+2*im*b*x))+-1//2*im*x*log(1+-1*im*c*exp(2*im*a+2*im*b*x)))
@test integrate(x^2*arccot(c+-1*(1+im*c)*cot(a+b*x)), x) == :(-1//8*b^-3*Polylogarithms.polylog(4,-1*im*c*exp(2*im*a+2*im*b*x))+1//3*x^3*arccot(c+-1*(1+im*c)*cot(a+b*x))+1//12*b*x^4+1//4*b^-1*x^2*Polylogarithms.polylog(2,-1*im*c*exp(2*im*a+2*im*b*x))+1//6*im*x^3*log(1+im*c*exp(2*im*a+2*im*b*x))+1//4*im*x*b^-2*Polylogarithms.polylog(3,-1*im*c*exp(2*im*a+2*im*b*x)))
@test integrate(x*arccot(c+-1*(1+im*c)*cot(a+b*x)), x) == :((1/2)*x^2*arccot(c+-1*(1+im*c)*cot(a+b*x))+1//6*b*x^3+1//4*im*x^2*log(1+im*c*exp(2*im*a+2*im*b*x))+1//4*x*b^-1*Polylogarithms.polylog(2,-1*im*c*exp(2*im*a+2*im*b*x))+1//8*im*b^-2*Polylogarithms.polylog(3,-1*im*c*exp(2*im*a+2*im*b*x)))
@test integrate(arccot(c+-1*(1+im*c)*cot(a+b*x)), x) == :(x*arccot(c+-1*(1+im*c)*cot(a+b*x))+(1/2)*b*x^2+1//4*b^-1*Polylogarithms.polylog(2,-1*im*c*exp(2*im*a+2*im*b*x))+(1/2)*im*x*log(1+im*c*exp(2*im*a+2*im*b*x)))
@test integrate((e+f*x)^3*arccot(tanh(a+b*x)), x) == :(1//4*f^-1*(e+f*x)^4*arccot(tanh(a+b*x))+1//4*f^-1*(e+f*x)^4*arctan(exp(2a+2*b*x))+-3//16*im*b^-4*f^3*Polylogarithms.polylog(5,im*exp(2a+2*b*x))+-1//4*im*b^-1*(e+f*x)^3*Polylogarithms.polylog(2,-1*im*exp(2a+2*b*x))+1//4*im*b^-1*(e+f*x)^3*Polylogarithms.polylog(2,im*exp(2a+2*b*x))+3//16*im*b^-4*f^3*Polylogarithms.polylog(5,-1*im*exp(2a+2*b*x))+-3//8*im*f*b^-2*(e+f*x)^2*Polylogarithms.polylog(3,im*exp(2a+2*b*x))+-3//8*im*b^-3*f^2*(e+f*x)*Polylogarithms.polylog(4,-1*im*exp(2a+2*b*x))+3//8*im*f*b^-2*(e+f*x)^2*Polylogarithms.polylog(3,-1*im*exp(2a+2*b*x))+3//8*im*b^-3*f^2*(e+f*x)*Polylogarithms.polylog(4,im*exp(2a+2*b*x)))
@test integrate((e+f*x)^2*arccot(tanh(a+b*x)), x) == :(1//3*f^-1*(e+f*x)^3*arccot(tanh(a+b*x))+1//3*f^-1*(e+f*x)^3*arctan(exp(2a+2*b*x))+-1//4*im*b^-1*(e+f*x)^2*Polylogarithms.polylog(2,-1*im*exp(2a+2*b*x))+-1//8*im*b^-3*f^2*Polylogarithms.polylog(4,-1*im*exp(2a+2*b*x))+1//4*im*b^-1*(e+f*x)^2*Polylogarithms.polylog(2,im*exp(2a+2*b*x))+1//8*im*b^-3*f^2*Polylogarithms.polylog(4,im*exp(2a+2*b*x))+-1//4*im*f*b^-2*(e+f*x)*Polylogarithms.polylog(3,im*exp(2a+2*b*x))+1//4*im*f*b^-2*(e+f*x)*Polylogarithms.polylog(3,-1*im*exp(2a+2*b*x)))
@test integrate((e+f*x)*arccot(tanh(a+b*x)), x) == :((1/2)*f^-1*(e+f*x)^2*arccot(tanh(a+b*x))+(1/2)*f^-1*(e+f*x)^2*arctan(exp(2a+2*b*x))+-1//4*im*b^-1*(e+f*x)*Polylogarithms.polylog(2,-1*im*exp(2a+2*b*x))+-1//8*im*f*b^-2*Polylogarithms.polylog(3,im*exp(2a+2*b*x))+1//4*im*b^-1*(e+f*x)*Polylogarithms.polylog(2,im*exp(2a+2*b*x))+1//8*im*f*b^-2*Polylogarithms.polylog(3,-1*im*exp(2a+2*b*x)))
@test integrate(arccot(tanh(a+b*x)), x) == :(x*arccot(tanh(a+b*x))+x*arctan(exp(2a+2*b*x))+-1//4*im*b^-1*Polylogarithms.polylog(2,-1*im*exp(2a+2*b*x))+1//4*im*b^-1*Polylogarithms.polylog(2,im*exp(2a+2*b*x)))
@test integrate(x^2*arccot(c+d*tanh(a+b*x)), x) == :(1//3*x^3*arccot(c+d*tanh(a+b*x))+-1//6*im*x^3*log(1+(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+-1//8*im*b^-3*Polylogarithms.polylog(4,-1*(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+1//6*im*x^3*log(1+(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+1//8*im*b^-3*Polylogarithms.polylog(4,-1*(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+-1//4*im*x*b^-2*Polylogarithms.polylog(3,-1*(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+-1//4*im*b^-1*x^2*Polylogarithms.polylog(2,-1*(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+1//4*im*x*b^-2*Polylogarithms.polylog(3,-1*(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+1//4*im*b^-1*x^2*Polylogarithms.polylog(2,-1*(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x)))
@test integrate(x*arccot(c+d*tanh(a+b*x)), x) == :((1/2)*x^2*arccot(c+d*tanh(a+b*x))+-1//4*im*x^2*log(1+(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+-1//8*im*b^-2*Polylogarithms.polylog(3,-1*(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+1//4*im*x^2*log(1+(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+1//8*im*b^-2*Polylogarithms.polylog(3,-1*(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+-1//4*im*x*b^-1*Polylogarithms.polylog(2,-1*(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+1//4*im*x*b^-1*Polylogarithms.polylog(2,-1*(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x)))
@test integrate(arccot(c+d*tanh(a+b*x)), x) == :(x*arccot(c+d*tanh(a+b*x))+(1/2)*im*x*log(1+(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+-1//2*im*x*log(1+(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+-1//4*im*b^-1*Polylogarithms.polylog(2,-1*(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+1//4*im*b^-1*Polylogarithms.polylog(2,-1*(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x)))
@test integrate(x^2*arccot(c+(im+c)*tanh(a+b*x)), x) == :(1//3*x^3*arccot(c+(im+c)*tanh(a+b*x))+-1//6*im*x^3*log(1+im*c*exp(2a+2*b*x))+-1//8*im*b^-3*Polylogarithms.polylog(4,-1*im*c*exp(2a+2*b*x))+1//12*im*b*x^4+-1//4*im*b^-1*x^2*Polylogarithms.polylog(2,-1*im*c*exp(2a+2*b*x))+1//4*im*x*b^-2*Polylogarithms.polylog(3,-1*im*c*exp(2a+2*b*x)))
@test integrate(x*arccot(c+(im+c)*tanh(a+b*x)), x) == :((1/2)*x^2*arccot(c+(im+c)*tanh(a+b*x))+-1//4*im*x^2*log(1+im*c*exp(2a+2*b*x))+1//6*im*b*x^3+1//8*im*b^-2*Polylogarithms.polylog(3,-1*im*c*exp(2a+2*b*x))+-1//4*im*x*b^-1*Polylogarithms.polylog(2,-1*im*c*exp(2a+2*b*x)))
@test integrate(arccot(c+(im+c)*tanh(a+b*x)), x) == :(x*arccot(c+(im+c)*tanh(a+b*x))+(1/2)*im*b*x^2+-1//2*im*x*log(1+im*c*exp(2a+2*b*x))+-1//4*im*b^-1*Polylogarithms.polylog(2,-1*im*c*exp(2a+2*b*x)))
@test integrate(x^2*arccot(c+-1*(im+-1c)*tanh(a+b*x)), x) == :(1//3*x^3*arccot(c+-1*(im+-1c)*tanh(a+b*x))+-1//12*im*b*x^4+1//6*im*x^3*log(1+-1*im*c*exp(2a+2*b*x))+1//8*im*b^-3*Polylogarithms.polylog(4,im*c*exp(2a+2*b*x))+-1//4*im*x*b^-2*Polylogarithms.polylog(3,im*c*exp(2a+2*b*x))+1//4*im*b^-1*x^2*Polylogarithms.polylog(2,im*c*exp(2a+2*b*x)))
@test integrate(x*arccot(c+-1*(im+-1c)*tanh(a+b*x)), x) == :((1/2)*x^2*arccot(c+-1*(im+-1c)*tanh(a+b*x))+-1//6*im*b*x^3+-1//8*im*b^-2*Polylogarithms.polylog(3,im*c*exp(2a+2*b*x))+1//4*im*x^2*log(1+-1*im*c*exp(2a+2*b*x))+1//4*im*x*b^-1*Polylogarithms.polylog(2,im*c*exp(2a+2*b*x)))
@test integrate(arccot(c+-1*(im+-1c)*tanh(a+b*x)), x) == :(x*arccot(c+-1*(im+-1c)*tanh(a+b*x))+(1/2)*im*x*log(1+-1*im*c*exp(2a+2*b*x))+-1//2*im*b*x^2+1//4*im*b^-1*Polylogarithms.polylog(2,im*c*exp(2a+2*b*x)))
@test integrate((e+f*x)^3*arccot(coth(a+b*x)), x) == :(-1//4*f^-1*(e+f*x)^4*arctan(exp(2a+2*b*x))+1//4*f^-1*(e+f*x)^4*arccot(coth(a+b*x))+-3//16*im*b^-4*f^3*Polylogarithms.polylog(5,-1*im*exp(2a+2*b*x))+-1//4*im*b^-1*(e+f*x)^3*Polylogarithms.polylog(2,im*exp(2a+2*b*x))+1//4*im*b^-1*(e+f*x)^3*Polylogarithms.polylog(2,-1*im*exp(2a+2*b*x))+3//16*im*b^-4*f^3*Polylogarithms.polylog(5,im*exp(2a+2*b*x))+-3//8*im*f*b^-2*(e+f*x)^2*Polylogarithms.polylog(3,-1*im*exp(2a+2*b*x))+-3//8*im*b^-3*f^2*(e+f*x)*Polylogarithms.polylog(4,im*exp(2a+2*b*x))+3//8*im*f*b^-2*(e+f*x)^2*Polylogarithms.polylog(3,im*exp(2a+2*b*x))+3//8*im*b^-3*f^2*(e+f*x)*Polylogarithms.polylog(4,-1*im*exp(2a+2*b*x)))
@test integrate((e+f*x)^2*arccot(coth(a+b*x)), x) == :(-1//3*f^-1*(e+f*x)^3*arctan(exp(2a+2*b*x))+1//3*f^-1*(e+f*x)^3*arccot(coth(a+b*x))+-1//4*im*b^-1*(e+f*x)^2*Polylogarithms.polylog(2,im*exp(2a+2*b*x))+-1//8*im*b^-3*f^2*Polylogarithms.polylog(4,im*exp(2a+2*b*x))+1//4*im*b^-1*(e+f*x)^2*Polylogarithms.polylog(2,-1*im*exp(2a+2*b*x))+1//8*im*b^-3*f^2*Polylogarithms.polylog(4,-1*im*exp(2a+2*b*x))+-1//4*im*f*b^-2*(e+f*x)*Polylogarithms.polylog(3,-1*im*exp(2a+2*b*x))+1//4*im*f*b^-2*(e+f*x)*Polylogarithms.polylog(3,im*exp(2a+2*b*x)))
@test integrate((e+f*x)*arccot(coth(a+b*x)), x) == :((1/2)*f^-1*(e+f*x)^2*arccot(coth(a+b*x))+-1//2*f^-1*(e+f*x)^2*arctan(exp(2a+2*b*x))+-1//4*im*b^-1*(e+f*x)*Polylogarithms.polylog(2,im*exp(2a+2*b*x))+-1//8*im*f*b^-2*Polylogarithms.polylog(3,-1*im*exp(2a+2*b*x))+1//4*im*b^-1*(e+f*x)*Polylogarithms.polylog(2,-1*im*exp(2a+2*b*x))+1//8*im*f*b^-2*Polylogarithms.polylog(3,im*exp(2a+2*b*x)))
@test integrate(arccot(coth(a+b*x)), x) == :(x*arccot(coth(a+b*x))+-1*x*arctan(exp(2a+2*b*x))+-1//4*im*b^-1*Polylogarithms.polylog(2,im*exp(2a+2*b*x))+1//4*im*b^-1*Polylogarithms.polylog(2,-1*im*exp(2a+2*b*x)))
@test integrate(x^2*arccot(c+d*coth(a+b*x)), x) == :(1//3*x^3*arccot(c+d*coth(a+b*x))+-1//6*im*x^3*log(1+-1*(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+-1//8*im*b^-3*Polylogarithms.polylog(4,(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+1//6*im*x^3*log(1+-1*(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+1//8*im*b^-3*Polylogarithms.polylog(4,(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+-1//4*im*x*b^-2*Polylogarithms.polylog(3,(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+-1//4*im*b^-1*x^2*Polylogarithms.polylog(2,(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+1//4*im*x*b^-2*Polylogarithms.polylog(3,(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+1//4*im*b^-1*x^2*Polylogarithms.polylog(2,(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x)))
@test integrate(x*arccot(c+d*coth(a+b*x)), x) == :((1/2)*x^2*arccot(c+d*coth(a+b*x))+-1//4*im*x^2*log(1+-1*(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+-1//8*im*b^-2*Polylogarithms.polylog(3,(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+1//4*im*x^2*log(1+-1*(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+1//8*im*b^-2*Polylogarithms.polylog(3,(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+-1//4*im*x*b^-1*Polylogarithms.polylog(2,(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+1//4*im*x*b^-1*Polylogarithms.polylog(2,(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x)))
@test integrate(arccot(c+d*coth(a+b*x)), x) == :(x*arccot(c+d*coth(a+b*x))+(1/2)*im*x*log(1+-1*(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x))+-1//2*im*x*log(1+-1*(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+-1//4*im*b^-1*Polylogarithms.polylog(2,(im+d+-1c)^-1*(im+-1c+-1d)*exp(2a+2*b*x))+1//4*im*b^-1*Polylogarithms.polylog(2,(im+c+-1d)^-1*(im+c+d)*exp(2a+2*b*x)))
@test integrate(x^2*arccot(c+(im+c)*coth(a+b*x)), x) == :(1//3*x^3*arccot(c+(im+c)*coth(a+b*x))+-1//6*im*x^3*log(1+-1*im*c*exp(2a+2*b*x))+-1//8*im*b^-3*Polylogarithms.polylog(4,im*c*exp(2a+2*b*x))+1//12*im*b*x^4+-1//4*im*b^-1*x^2*Polylogarithms.polylog(2,im*c*exp(2a+2*b*x))+1//4*im*x*b^-2*Polylogarithms.polylog(3,im*c*exp(2a+2*b*x)))
@test integrate(x*arccot(c+(im+c)*coth(a+b*x)), x) == :((1/2)*x^2*arccot(c+(im+c)*coth(a+b*x))+-1//4*im*x^2*log(1+-1*im*c*exp(2a+2*b*x))+1//6*im*b*x^3+1//8*im*b^-2*Polylogarithms.polylog(3,im*c*exp(2a+2*b*x))+-1//4*im*x*b^-1*Polylogarithms.polylog(2,im*c*exp(2a+2*b*x)))
@test integrate(arccot(c+(im+c)*coth(a+b*x)), x) == :(x*arccot(c+(im+c)*coth(a+b*x))+(1/2)*im*b*x^2+-1//2*im*x*log(1+-1*im*c*exp(2a+2*b*x))+-1//4*im*b^-1*Polylogarithms.polylog(2,im*c*exp(2a+2*b*x)))
@test integrate(x^2*arccot(c+-1*(im+-1c)*coth(a+b*x)), x) == :(1//3*x^3*arccot(c+-1*(im+-1c)*coth(a+b*x))+-1//12*im*b*x^4+1//6*im*x^3*log(1+im*c*exp(2a+2*b*x))+1//8*im*b^-3*Polylogarithms.polylog(4,-1*im*c*exp(2a+2*b*x))+-1//4*im*x*b^-2*Polylogarithms.polylog(3,-1*im*c*exp(2a+2*b*x))+1//4*im*b^-1*x^2*Polylogarithms.polylog(2,-1*im*c*exp(2a+2*b*x)))
@test integrate(x*arccot(c+-1*(im+-1c)*coth(a+b*x)), x) == :((1/2)*x^2*arccot(c+-1*(im+-1c)*coth(a+b*x))+-1//6*im*b*x^3+-1//8*im*b^-2*Polylogarithms.polylog(3,-1*im*c*exp(2a+2*b*x))+1//4*im*x^2*log(1+im*c*exp(2a+2*b*x))+1//4*im*x*b^-1*Polylogarithms.polylog(2,-1*im*c*exp(2a+2*b*x)))
@test integrate(arccot(c+-1*(im+-1c)*coth(a+b*x)), x) == :(x*arccot(c+-1*(im+-1c)*coth(a+b*x))+(1/2)*im*x*log(1+im*c*exp(2a+2*b*x))+-1//2*im*b*x^2+1//4*im*b^-1*Polylogarithms.polylog(2,-1*im*c*exp(2a+2*b*x)))
@test integrate(x^-1*(a+b*arccot(c*x^n))*(d+e*log(f*x^m)), x) == :(a*d*log(x)+(1/2)*a*e*m^-1*log(f*x^m)^2+(1/2)*im*b*d*n^-1*Polylogarithms.polylog(2,im*c^-1*x^(-1n))+-1//2*im*b*d*n^-1*Polylogarithms.polylog(2,-1*im*c^-1*x^(-1n))+(1/2)*im*b*e*m*n^-2*Polylogarithms.polylog(3,im*c^-1*x^(-1n))+(1/2)*im*b*e*n^-1*Polylogarithms.polylog(2,im*c^-1*x^(-1n))*log(f*x^m)+-1//2*im*b*e*m*n^-2*Polylogarithms.polylog(3,-1*im*c^-1*x^(-1n))+-1//2*im*b*e*n^-1*Polylogarithms.polylog(2,-1*im*c^-1*x^(-1n))*log(f*x^m))
@test integrate(arccot(exp(x)), x) == :((1/2)*im*Polylogarithms.polylog(2,im*exp(-1x))+-1//2*im*Polylogarithms.polylog(2,-1*im*exp(-1x)))
@test integrate(x*arccot(exp(x)), x) == :((1/2)*im*Polylogarithms.polylog(3,im*exp(-1x))+-1//2*im*Polylogarithms.polylog(3,-1*im*exp(-1x))+(1/2)*im*x*Polylogarithms.polylog(2,im*exp(-1x))+-1//2*im*x*Polylogarithms.polylog(2,-1*im*exp(-1x)))
@test integrate(x^2*arccot(exp(x)), x) == :(im*Polylogarithms.polylog(4,im*exp(-1x))+-1*im*Polylogarithms.polylog(4,-1*im*exp(-1x))+im*x*Polylogarithms.polylog(3,im*exp(-1x))+(1/2)*im*x^2*Polylogarithms.polylog(2,im*exp(-1x))+-1*im*x*Polylogarithms.polylog(3,-1*im*exp(-1x))+-1//2*im*x^2*Polylogarithms.polylog(2,-1*im*exp(-1x)))
@test integrate(arccot(exp(a+b*x)), x) == :((1/2)*im*b^-1*Polylogarithms.polylog(2,im*exp(-1a+-1*b*x))+-1//2*im*b^-1*Polylogarithms.polylog(2,-1*im*exp(-1a+-1*b*x)))
@test integrate(x*arccot(exp(a+b*x)), x) == :((1/2)*im*b^-2*Polylogarithms.polylog(3,im*exp(-1a+-1*b*x))+-1//2*im*b^-2*Polylogarithms.polylog(3,-1*im*exp(-1a+-1*b*x))+(1/2)*im*x*b^-1*Polylogarithms.polylog(2,im*exp(-1a+-1*b*x))+-1//2*im*x*b^-1*Polylogarithms.polylog(2,-1*im*exp(-1a+-1*b*x)))
@test integrate(x^2*arccot(exp(a+b*x)), x) == :(im*b^-3*Polylogarithms.polylog(4,im*exp(-1a+-1*b*x))+-1*im*b^-3*Polylogarithms.polylog(4,-1*im*exp(-1a+-1*b*x))+im*x*b^-2*Polylogarithms.polylog(3,im*exp(-1a+-1*b*x))+(1/2)*im*b^-1*x^2*Polylogarithms.polylog(2,im*exp(-1a+-1*b*x))+-1*im*x*b^-2*Polylogarithms.polylog(3,-1*im*exp(-1a+-1*b*x))+-1//2*im*b^-1*x^2*Polylogarithms.polylog(2,-1*im*exp(-1a+-1*b*x)))
@test integrate(arccot(a+b*f^(c+d*x)), x) == :(d^-1*log(f)^-1*arccot(a+b*f^(c+d*x))*log(2*b*f^(c+d*x)*(1+-1*im*(a+b*f^(c+d*x)))^-1*(im+-1a)^-1)+(1/2)*im*d^-1*log(f)^-1*Polylogarithms.polylog(2,1+-2*b*f^(c+d*x)*(1+-1*im*(a+b*f^(c+d*x)))^-1*(im+-1a)^-1)+-1*d^-1*log(f)^-1*arccot(a+b*f^(c+d*x))*log(2*(1+-1*im*(a+b*f^(c+d*x)))^-1)+-1//2*im*d^-1*log(f)^-1*Polylogarithms.polylog(2,1+-2*(1+-1*im*(a+b*f^(c+d*x)))^-1))
@test integrate(x*arccot(a+b*f^(c+d*x)), x) == :(-1//4*im*x^2*log(1+im*(a+b*f^(c+d*x))^-1)+-1//4*im*x^2*log(1+-1*b*f^(c+d*x)*(im+-1a)^-1)+1//4*im*x^2*log(1+-1*im*(a+b*f^(c+d*x))^-1)+1//4*im*x^2*log(1+b*f^(c+d*x)*(im+a)^-1)+(1/2)*im*d^-2*log(f)^-2*Polylogarithms.polylog(3,b*f^(c+d*x)*(im+-1a)^-1)+-1//2*im*d^-2*log(f)^-2*Polylogarithms.polylog(3,-1*b*f^(c+d*x)*(im+a)^-1)+(1/2)*im*x*d^-1*log(f)^-1*Polylogarithms.polylog(2,-1*b*f^(c+d*x)*(im+a)^-1)+-1//2*im*x*d^-1*log(f)^-1*Polylogarithms.polylog(2,b*f^(c+d*x)*(im+-1a)^-1))
@test integrate(x^2*arccot(a+b*f^(c+d*x)), x) == :(-1//6*im*x^3*log(1+im*(a+b*f^(c+d*x))^-1)+-1//6*im*x^3*log(1+-1*b*f^(c+d*x)*(im+-1a)^-1)+1//6*im*x^3*log(1+-1*im*(a+b*f^(c+d*x))^-1)+1//6*im*x^3*log(1+b*f^(c+d*x)*(im+a)^-1)+im*d^-3*log(f)^-3*Polylogarithms.polylog(4,-1*b*f^(c+d*x)*(im+a)^-1)+-1*im*d^-3*log(f)^-3*Polylogarithms.polylog(4,b*f^(c+d*x)*(im+-1a)^-1)+im*x*d^-2*log(f)^-2*Polylogarithms.polylog(3,b*f^(c+d*x)*(im+-1a)^-1)+(1/2)*im*d^-1*x^2*log(f)^-1*Polylogarithms.polylog(2,-1*b*f^(c+d*x)*(im+a)^-1)+-1*im*x*d^-2*log(f)^-2*Polylogarithms.polylog(3,-1*b*f^(c+d*x)*(im+a)^-1)+-1//2*im*d^-1*x^2*log(f)^-1*Polylogarithms.polylog(2,b*f^(c+d*x)*(im+-1a)^-1))
@test integrate(arccot(exp(x))*exp(-1x), x) == :((1/2)*log(1+exp(2x))+-1x+-1*arccot(exp(x))*exp(-1x))
@test integrate((a+a*x^2)^-1*(b+-2*b*arccot(x))^-1, x) == :((1/2)*a^-1*b^-1*log(1+-2*arccot(x)))
@test integrate(arccot(sinh(a*c+b*c*x))*exp(c*(a+b*x)), x) == :(b^-1*c^-1*log(1+exp(2*c*(a+b*x)))+b^-1*c^-1*arccot(sinh(c*(a+b*x)))*exp(a*c+b*c*x))
@test integrate(arccot(cosh(a*c+b*c*x))*exp(c*(a+b*x)), x) == :(b^-1*c^-1*arccot(cosh(c*(a+b*x)))*exp(a*c+b*c*x)+(1/2)*b^-1*c^-1*(1+2^(1/2))*log(3+2*2^(1/2)+exp(2*c*(a+b*x)))+(1/2)*b^-1*c^-1*(1+-1*2^(1/2))*log(3+-2*2^(1/2)+exp(2*c*(a+b*x))))
@test integrate(arccot(tanh(a*c+b*c*x))*exp(c*(a+b*x)), x) == :(b^-1*c^-1*arccot(tanh(c*(a+b*x)))*exp(a*c+b*c*x)+(1/2)*2^(1/2)*b^-1*c^-1*arctan(1+2^(1/2)*exp(a*c+b*c*x))+-1//2*2^(1/2)*b^-1*c^-1*arctan(1+-1*2^(1/2)*exp(a*c+b*c*x))+-1//4*2^(1/2)*b^-1*c^-1*log(1+2^(1/2)*exp(a*c+b*c*x)+exp(2*c*(a+b*x)))+1//4*2^(1/2)*b^-1*c^-1*log(1+-1*2^(1/2)*exp(a*c+b*c*x)+exp(2*c*(a+b*x))))
@test integrate(arccot(coth(a*c+b*c*x))*exp(c*(a+b*x)), x) == :(b^-1*c^-1*arccot(coth(c*(a+b*x)))*exp(a*c+b*c*x)+(1/2)*2^(1/2)*b^-1*c^-1*arctan(1+-1*2^(1/2)*exp(a*c+b*c*x))+-1//2*2^(1/2)*b^-1*c^-1*arctan(1+2^(1/2)*exp(a*c+b*c*x))+-1//4*2^(1/2)*b^-1*c^-1*log(1+-1*2^(1/2)*exp(a*c+b*c*x)+exp(2*c*(a+b*x)))+1//4*2^(1/2)*b^-1*c^-1*log(1+2^(1/2)*exp(a*c+b*c*x)+exp(2*c*(a+b*x))))
@test integrate(arccot(sech(a*c+b*c*x))*exp(c*(a+b*x)), x) == :(b^-1*c^-1*arccot(sech(c*(a+b*x)))*exp(a*c+b*c*x)+-1//2*b^-1*c^-1*(1+2^(1/2))*log(3+2*2^(1/2)+exp(2*c*(a+b*x)))+-1//2*b^-1*c^-1*(1+-1*2^(1/2))*log(3+-2*2^(1/2)+exp(2*c*(a+b*x))))
@test integrate(arccot(csch(a*c+b*c*x))*exp(c*(a+b*x)), x) == :(-1*b^-1*c^-1*log(1+exp(2*c*(a+b*x)))+b^-1*c^-1*arccot(csch(c*(a+b*x)))*exp(a*c+b*c*x))

max_stars_repo_path: test/5 Inverse trig functions/5.4 Inverse cotangent/5.4.1 Inverse cotangent functions.jl


text:
using Meshes
using Printf

function check_file(filename)
    overwrite = true

    if isfile(filename)
        fname = basename(filename)
        print("File " * fname * " already exists in the chosen directory. ")
        print("Do you wish to overwrite it? [Y/n] ")
        choice = readline()

        if lowercase(first(choice)) == "n"
            overwrite = false
        end
    end

    overwrite
end

const MESH_FORMATS = ["Compact", "GMSH"]

function save_mesh(g::CartesianGrid, filename::AbstractString; format="Compact")

    if !(format in MESH_FORMATS)
        print("Mesh was not saved: Format not supported")
    elseif !check_file(filename)
        print("Mesh was not saved: File already exists.")

    elseif format == "Compact"

        open(filename, "w") do f
            write(f, "CartesianGrid\n")

            minim = string.( minimum(g).coords )
            write(f, "Minimum: " * join(minim, " ") * '\n')

            maxim = string.( maximum(g).coords )
            write(f, "Maximum: " * join(minim, " ") * '\n')

            step = string.( g.spacing )
            write(f, "Spacing: " * join(step, " "))
        end

    else
        save_gmsh(g, filename, file_checked=true)
    end

    nothing
end

function save_mesh(m::UnstructuredMesh, filename::AbstractString; format="GMSH")
    if format != "GMSH"
        print("Mesh was not saved: Format not supported")
    elseif !check_file(filename)
        print("Mesh was not saved: File already exists.")
    else
        save_gmsh(m, filename, file_checked=true)
    end
    nothing
end

function save_gmsh(m::Mesh, filename::AbstractString; file_checked=false)
    nothing
end

max_stars_repo_name: tremelow/StiffKinetic

max_issues_repo_name: tremelow/StiffKinetic

max_forks_repo_name: tremelow/StiffKinetic


text:
using BenchmarkTools
using Distances

const SUITE = BenchmarkGroup()

function create_distances(w, Q)
    dists = [
        SqEuclidean(),
        Euclidean(),
        PeriodicEuclidean(w),
        Cityblock(),
        TotalVariation(),
        Chebyshev(),
        Minkowski(3.0),
        Hamming(),

        CosineDist(),
        CorrDist(),
        ChiSqDist(),

        BhattacharyyaDist(),
        HellingerDist(),

        # Haversine(6371.),

        BrayCurtis(),

        WeightedSqEuclidean(w),
        WeightedEuclidean(w),
        WeightedCityblock(w),
        WeightedMinkowski(w, 3.0),
        WeightedHamming(w),

        SqMahalanobis(Q),
        Mahalanobis(Q),
    ]

    divs = [
        KLDivergence(),
        RenyiDivergence(0),
        RenyiDivergence(1),
        RenyiDivergence(2),
        RenyiDivergence(Inf),
        JSDivergence(),
    ]
    return dists, divs
end

###########
# Colwise #
###########

SUITE["colwise"] = BenchmarkGroup()

function evaluate_colwise(dist, x, y)
    n = size(x, 2)
    T = typeof(evaluate(dist, x[:, 1], y[:, 1]))
    r = Vector{T}(undef, n)
    for j = 1:n
        r[j] = @views evaluate(dist, x[:, j], y[:, j])
    end
    return r
end

function add_colwise_benchmarks!(SUITE)

    m = 200
    n = 10000

    x = rand(m, n)
    y = rand(m, n)

    p = x
    q = y
    for i = 1:n
        p[:, i] /= sum(x[:, i])
        q[:, i] /= sum(y[:, i])
    end

    w = rand(m)

    Q = rand(m, m)
    Q = Q' * Q

    _dists, divs = create_distances(w, Q)

    for (dists, (a, b)) in [(_dists, (x,y)), (divs, (p,q))]
        for dist in (dists)
            Tdist = typeof(dist)
            SUITE["colwise"][Tdist] = BenchmarkGroup()
            SUITE["colwise"][Tdist]["loop"]        = @benchmarkable evaluate_colwise($dist, $a, $b)
            SUITE["colwise"][Tdist]["specialized"] = @benchmarkable colwise($dist, $a, $b)
        end
    end
end

add_colwise_benchmarks!(SUITE)

############
# Pairwise #
############

SUITE["pairwise"] = BenchmarkGroup()

function evaluate_pairwise(dist, x, y)
    nx = size(x, 2)
    ny = size(y, 2)
    T = typeof(evaluate(dist, x[:, 1], y[:, 1]))
    r = Matrix{T}(undef, nx, ny)
    for j = 1:ny
        @inbounds for i = 1:nx
            r[i, j] = @views evaluate(dist, x[:, i], y[:, j])
        end
    end
    return r
end

function add_pairwise_benchmarks!(SUITE)
    m = 100
    nx = 200
    ny = 250

    x = rand(m, nx)
    y = rand(m, ny)

    p = x
    for i = 1:nx
        p[:, i] /= sum(x[:, i])
    end

    q = y
    for i = 1:ny
        q[:, i] /= sum(y[:, i])
    end

    w = rand(m)
    Q = rand(m, m)
    Q = Q' * Q

    _dists, divs = create_distances(w, Q)

     for (dists, (a, b)) in [(_dists, (x,y)), (divs, (p,q))]
        for dist in (dists)
            Tdist = typeof(dist)
            SUITE["pairwise"][Tdist] = BenchmarkGroup()
            SUITE["pairwise"][Tdist]["loop"]        = @benchmarkable evaluate_pairwise($dist, $a, $b)
            SUITE["pairwise"][Tdist]["specialized"] = @benchmarkable pairwise($dist, $a, $b; dims=2)
        end
    end
end

add_pairwise_benchmarks!(SUITE)


text:
export ACTheory

using Combinatorics
using DataStructures

struct ACTheory <: AbstractTheory end

struct ACTerm <: AbstractTerm
    root::Σ
    args::OrderedDict{Union{Variable,AbstractTerm},UInt}
    ACTerm(root, args) = new(root, sort(args, lt=(>ₜ), rev=true))
end

function term(::ACTheory, root, args)
    @assert !isempty(args)
    length(args) == 1 && return first(args)

    dict = OrderedDict{Union{Variable,AbstractTerm},UInt}()
    for arg ∈ args
        if isa(arg, ACTerm) && arg.root == root
            merge!(+, dict, arg.args)
        else
            dict[arg] = get(dict, arg, 0) + 1
        end
    end
    return ACTerm(root, dict)
end

_lt_pair_term(a, b) = b.first >ₜ a.first
function Base.convert(::Type{Expr}, t::ACTerm)
    targs = sort(collect(t.args), lt=_lt_pair_term)
    ex = Expr(:call, t.root)

    for (s, k) ∈ targs
        append!(ex.args, fill(convert(Expr, s), k))
    end

    ex
end

theory(::Type{ACTerm}) = ACTheory()
priority(::Type{ACTerm}) = 20

vars(t::ACTerm) = mapreduce(vars, ∪, keys(t.args); init=Set{Variable}())

Base.:(==)(a::ACTerm, b::ACTerm) = a.root == b.root && a.args == b.args

function (a::ACTerm >ₜ b::ACTerm)
    a.root == b.root || return a.root >ₑ b.root
    length(a.args) == length(b.args) || return length(a.args) > length(b.args)

    for ((p, i), (q, j)) ∈ zip(a.args, b.args)
        i == j || return i > j
        p == q || return p >ₜ q
    end

    return false
end

Base.hash(t::ACTerm, h::UInt) = hash(t.args, hash(t.root, hash(ACTerm, h)))

function Base.map(f, p::ACTerm)
    dict = OrderedDict{Union{Variable,AbstractTerm},UInt}()

    for (t, k) ∈ p.args
        t′ = f(t)
        if isa(t′, ACTerm) && t′.root == p.root
            for (u, i) ∈ t′.args
                dict[u] = get(dict, u, 0) + i*k
            end
        else
            dict[t′] = get(dict, t′, 0) + k
        end
    end

    return ACTerm(p.root, dict)
end

struct ACMatcherSC <: AbstractMatcher
    root::Σ
    ground_subterms::Dict{AbstractTerm,UInt}
    alien_subterms::Vector{AbstractMatcher}
    linear_variables::Vector{Variable}
end

function matcher(t::ACTerm, V)
    ground_subterms = Dict{AbstractTerm,UInt}()
    alien_subterms = AbstractMatcher[]
    linear_variables = Variable[]

    V′ = copy(V)

    for (s, k) ∈ t.args
        if isempty(vars(s))
            ground_subterms[s] = k
        elseif isa(s, AbstractTerm) && k == 1
            svars = setdiff(vars(s), V)
            for other ∈ keys(t.args)
                other == s && continue
                isempty(svars ∩ vars(other)) || error("AC pattern not yet supported: $t")
            end

            s_matcher, sV = matcher(s, V)
            push!(alien_subterms, s_matcher)
            union!(V′, sV)
        elseif isa(s, Variable) && k == 1 && s ∉ V
            push!(linear_variables, s)
        else
            error("AC pattern not yet supported: $t")
        end
    end

    isempty(linear_variables) && error("AC pattern not yet supported: $t")
    length(alien_subterms) ≤ 1 || error("AC pattern not yet supported: $t")

    union!(V′, linear_variables)

    return ACMatcherSC(t.root, ground_subterms, alien_subterms, linear_variables), V′
end

struct ACSubproblemSC <: AbstractSubproblem
    iter
end

function _multiplicities_to_vector(dict)
    args = AbstractTerm[]

    for (s, k) ∈ dict
        append!(args, fill(s, k))
    end

    args
end
_build_ac((root, linear_variables), partition) = Dict(
    x => term(ACTheory(), root, args)
    for (x, args) ∈ zip(linear_variables, partition)
)
_build_ac(A::ACMatcherSC) = Base.Fix1(_build_ac, (A.root, A.linear_variables))
_merge(d) = Base.Fix1(merge, d)
function match!(σ, A::ACMatcherSC, t::ACTerm)
    isa(t, ACTerm) || return
    t.root == A.root || return nothing

    args = _match_ac_args(A, t)
    args === nothing && return nothing

    nargs = sum(values(args))
    naliens = length(A.alien_subterms)
    nargs ≥ length(A.linear_variables) + naliens || return nothing
    if naliens == 0
        return _match_ac_0(A, args, σ)
    elseif naliens == 1
        return _match_ac_1(A, args, σ)
    else
        error("Unsupported state")
    end
end
function _match_ac_args(A, t)
    args = copy(t.args)

    for (s, k) ∈ A.ground_subterms
        get(args, s, 0) ≥ k || return nothing
        args[s] -= k
        args[s] == 0 && delete!(args, s)
    end

    return args
end
function _match_ac_0(A, args, σ)
    parts = partitions(_multiplicities_to_vector(args), length(A.linear_variables))
    iter = LazyMap(_build_ac(A), LazyFlatten(LazyMap(permutations, parts)))
    return ACSubproblemSC(LazyMap(_merge(σ), iter))
end
function _match_ac_1(A, args, σ)
    alien = A.alien_subterms[1]
    iters = []

    for (s, q) ∈ args
        σ′ = copy(σ)
        subproblem = match!(σ′, alien, s)
        subproblem === nothing && continue

        args′ = Dict(s′ => q′ for (s′, q′) ∈ args if s′ ≠ s)
        q == 1 || (args′[s] = q - 1)

        parts = partitions(_multiplicities_to_vector(args′), length(A.linear_variables))
        linear_iter = LazyMap(_build_ac(A), LazyFlatten(LazyMap(permutations, parts)))
        s_iters = LazyMap(m -> LazyMap(_merge(m), linear_iter), Matches(σ′, subproblem))
        push!(iters, LazyFlatten(s_iters))
    end

    return ACSubproblemSC(LazyFlatten(iters))
end

function compile(A::ACMatcherSC, V)
    fn_name = gensym(:match!_ac)

    nlinear = length(A.linear_variables)
    naliens = length(A.alien_subterms)

    body = if naliens == 0
        :(_match_ac_0($A, args, σ))
    elseif naliens == 1
        :(_match_ac_1($A, args, σ))
    else
        error("Unsupported state")
    end

    return fn_name, quote
        function $fn_name(σ, t)
            isa(t, $ACTerm) || return
            t.root == $(Meta.quot(A.root)) || return

            args = _match_ac_args($A, t)
            args === nothing && return

            nargs = sum(values(args))
            nargs ≥ $(nlinear + naliens) || return

            $body
        end
    end
end

Base.iterate(iter::Matches{ACSubproblemSC}) = iterate(iter.s.iter)
Base.iterate(iter::Matches{ACSubproblemSC}, state) = iterate(iter.s.iter, state)

struct ACRewriter <: AbstractRewriter
    rules::Dict{Σ,Vector{Pair{ACMatcherSC,Any}}}
end

rewriter(::ACTheory) = ACRewriter(Dict{Σ,Vector{Pair{ACMatcherSC,Any}}}())
function Base.push!(rw::ACRewriter, (p, b)::Pair{ACTerm})
    haskey(rw.rules, p.root) || (rw.rules[p.root] = Pair{ACMatcherSC,Any}[])
    push!(rw.rules[p.root], matcher(p) => b)
    rw
end

function compile(rw::ACRewriter)
    fn_name = gensym(:rewrite_ac)

    matcher_exprs = Expr[]

    rules = Dict()
    for (root, matchers) ∈ rw.rules
        rules[root] = []
        for (p, b) ∈ matchers
            fn, expr = compile(p)
            push!(matcher_exprs, expr)
            push!(rules[root], fn => b)
        end
    end

    index = gensym(:rewrite_ac_map)

    fn_name, quote
        $(matcher_exprs...)
        $index = Dict($((
            :($(Meta.quot(root)) => $(:([$((:($fn => $b) for (fn, b) ∈ rs)...)])))
            for (root, rs) ∈ rules
        )...))
        function $fn_name(t)
            $haskey($rules, t.root) || return

            σ = $Substitution()

            for (match_fn, builder) ∈ $index[t.root]
                m = match_fn(σ, t)
                m === nothing && continue
                next = iterate($Matches(σ, m))
                next === nothing && continue
                σ = next[1]
                return builder(σ)::$AbstractTerm
            end

            return
        end
    end
end


text:
@testset "Output" begin

@testset "Plain, no newline" begin
    function kernel(oc)
        @rocprint oc "Hello World!"
        nothing
    end

    iob = IOBuffer()
    oc = OutputContext(iob)
    @roc kernel(oc)
    sleep(1)
    @test String(take!(iob)) == "Hello World!"
end

@testset "Plain, with newline" begin
    function kernel(oc)
        @rocprintln oc "Hello World!"
        nothing
    end

    iob = IOBuffer()
    oc = OutputContext(iob)
    @roc kernel(oc)
    sleep(1)
    @test String(take!(iob)) == "Hello World!\n"
end

@testset "Plain, multiple calls" begin
    function kernel(oc)
        @rocprint oc "Hello World!"
        @rocprintln oc "Goodbye World!"
        nothing
    end

    iob = IOBuffer()
    oc = OutputContext(iob)
    @roc kernel(oc)
    sleep(1)
    @test String(take!(iob)) == "Hello World!Goodbye World!\n"
end

#= TODO
@testset "Interpolated string" begin
    inner_str = "to the"
    function kernel(oc)
        @rocprintln oc "Hello $inner_str World!"
        nothing
    end

    iob = IOBuffer()
    oc = OutputContext(iob)
    @roc kernel(oc)
    sleep(1)
    @test String(take!(iob)) == "Hello to the World!\n"
end
=#

end


text:
export RotBasis, randpolar, polar2u, u2polar, rot_basis, basis_rotor

"""
    RotBasis{T} <: PrimitiveBlock{1, Complex{T}}

A special rotation block that transform basis to angle θ and ϕ in bloch sphere.
"""
mutable struct RotBasis{T} <: PrimitiveBlock{1}
    theta::T
    phi::T
end

_make_rot_mat(I, block, theta) = I * cos(theta / 2) - im * sin(theta / 2) * block
# chain -> *
# mat(rb::RotBasis{T}) where T = mat(Ry(-rb.theta))*mat(Rz(-rb.phi))
function Yao.mat(::Type{TM}, x::RotBasis{T}) where {TM, T}
    R1 = _make_rot_mat(IMatrix{2, Complex{T}}(), mat(TM, Z), -x.phi)
    R2 = _make_rot_mat(IMatrix{2, Complex{T}}(), mat(TM, Y), -x.theta)
    R2 * R1
end

Base.:(==)(rb1::RotBasis, rb2::RotBasis) = rb1.theta == rb2.theta && rb1.phi == rb2.phi

Base.copy(block::RotBasis{T}) where T = RotBasis{T}(block.theta, block.phi)
Yao.dispatch!(block::RotBasis, params::Vector) = ((block.theta, block.phi) = params; block)

Yao.getiparams(rb::RotBasis) = (rb.theta, rb.phi)
function Yao.setiparams!(rb::RotBasis, θ::Real, ϕ::Real)
    rb.theta, rb.phi = θ, ϕ
    rb
end
Yao.niparams(::Type{<:RotBasis}) = 2
Yao.niparams(::RotBasis) = 2
Yao.render_params(r::RotBasis, ::Val{:random}) = rand()*π, rand()*2π

function Yao.print_block(io::IO, R::RotBasis)
    print(io, "RotBasis($(R.theta), $(R.phi))")
end

function Base.hash(gate::RotBasis, h::UInt)
    hash(hash(gate.theta, gate.phi, objectid(gate)), h)
end

Yao.cache_key(gate::RotBasis) = (gate.theta, gate.phi)

rot_basis(num_bit::Int) = dispatch!(chain(num_bit, put(i=>RotBasis(0.0, 0.0)) for i=1:num_bit), randpolar(num_bit) |> vec)

"""
    u2polar(vec::Array) -> Array

transform su(2) state vector to polar angle, apply to the first dimension of size 2.
"""
function u2polar(vec::Vector)
    ratio = vec[2]/vec[1]
    [atan(abs(ratio))*2, angle(ratio)]
end

"""
    polar2u(vec::Array) -> Array

transform polar angle to su(2) state vector, apply to the first dimension of size 2.
"""
function polar2u(polar::Vector)
    theta, phi = polar
    [cos(theta/2)*exp(-im*phi/2), sin(theta/2)*exp(im*phi/2)]
end

u2polar(arr::Array) = mapslices(u2polar, arr, dims=[1])
polar2u(arr::Array) = mapslices(polar2u, arr, dims=[1])

"""
    randpolar(params::Int...) -> Array

random polar basis, number of basis
"""
randpolar(params::Int...) = rand(2, params...)*pi

"""
    basis_rotor(::ZGate) -> AbstractBlock
    basis_rotor(basis::PauliGate, nbit, locs) -> AbstractBlock

Return a block to rotate the basis to pauli basis for measurements.
"""
basis_rotor(::ZGate) = I2Gate()
basis_rotor(::XGate) = Ry(-0.5π)
basis_rotor(::YGate) = Rx(0.5π)

basis_rotor(basis::PauliGate, nbit, locs) = repeat(nbit, basis_rotor(basis), locs)

Yao.YaoBlocks.@dumpload_fallback RotBasis RotBasis

max_stars_repo_name: QuantumBFS/YaoExtensions

max_issues_repo_name: QuantumBFS/YaoExtensions

max_forks_repo_name: QuantumBFS/YaoExtensions


text:
# native target for CPU execution

## target

export NativeCompilerTarget

Base.@kwdef struct NativeCompilerTarget <: AbstractCompilerTarget
    cpu::String=(LLVM.version() < v"8") ? "" : unsafe_string(LLVM.API.LLVMGetHostCPUName())
    features::String=(LLVM.version() < v"8") ? "" : unsafe_string(LLVM.API.LLVMGetHostCPUFeatures())
end

llvm_triple(::NativeCompilerTarget) = Sys.MACHINE

function llvm_machine(target::NativeCompilerTarget)
    triple = llvm_triple(target)

    t = Target(triple=triple)

    tm = TargetMachine(t, triple, target.cpu, target.features)
    asm_verbosity!(tm, true)

    return tm
end

## job

runtime_slug(job::CompilerJob{NativeCompilerTarget}) = "native_$(job.target.cpu)-$(hash(job.target.features))"