text:
#=
    Contents: Given an existing connection object (c) whose status may or may not be connected, this file provides the following functions:
              1. new_connection(c), returns a new connection with connected status.
	      2. disconnect(c), disconnects c.
=#

using Redis

function ConnectionPools.new_connection(c::RedisConnection)
    RedisConnection(host = c.host, port = c.port, password = c.password, db = c.db)
end

function ConnectionPools.disconnect(c::RedisConnection)
    disconnect(c)
end

# EOF


text:
module JIT

using LLVM
import LLVM:TargetMachine

import GPUCompiler
import ..Compiler

export get_trampoline

struct CompilerInstance
    jit::LLVM.LLJIT
    lctm::Union{LLVM.LazyCallThroughManager, Nothing}
    ism::Union{LLVM.IndirectStubsManager, Nothing}
end

function LLVM.dispose(ci::CompilerInstance)
    dispose(ci.jit)
    if ci.lctm !== nothing
        dispose(ci.lctm)
    end
    if ci.ism !== nothing
        dispose(ci.ism)
    end
    return nothing
end

const jit = Ref{CompilerInstance}()
const tm = Ref{TargetMachine}() # for opt pipeline

get_tm() = tm[]

function absolute_symbol_materialization(name, ptr)
	address = LLVM.API.LLVMOrcJITTargetAddress(reinterpret(UInt, ptr))
	flags = LLVM.API.LLVMJITSymbolFlags(LLVM.API.LLVMJITSymbolGenericFlagsExported, 0)
	symbol = LLVM.API.LLVMJITEvaluatedSymbol(address, flags)
	gv = LLVM.API.LLVMJITCSymbolMapPair(name, symbol)

	return LLVM.absolute_symbols(Ref(gv))
end

function define_absolute_symbol(jd, name)
	ptr = LLVM.find_symbol(name)
	if ptr !== C_NULL
		LLVM.define(jd, absolute_symbol_materialization(name, ptr))
		return true
	end
	return false
end

function __init__()
    opt_level = Base.JLOptions().opt_level
    if opt_level < 2
        optlevel = LLVM.API.LLVMCodeGenLevelNone
    elseif opt_level == 2
        optlevel = LLVM.API.LLVMCodeGenLevelDefault
    else
        optlevel = LLVM.API.LLVMCodeGenLevelAggressive
    end

    tempTM = LLVM.JITTargetMachine(;optlevel=optlevel)
    LLVM.asm_verbosity!(tempTM, true)
    tm[] = tempTM

    tempTM = LLVM.JITTargetMachine(;optlevel)
    LLVM.asm_verbosity!(tempTM, true)

    if haskey(ENV, "ENABLE_GDBLISTENER")
        ollc = LLVM.ObjectLinkingLayerCreator() do es, triple
            oll = ObjectLinkingLayer(es)
            register!(oll, GDBRegistrationListener())
            return oll
        end

        GC.@preserve ollc begin
            builder = LLJITBuilder()
            LLVM.linkinglayercreator!(builder, ollc)
            tmb = TargetMachineBuilder(tempTM)
            LLVM.targetmachinebuilder!(builder, tmb)
            lljit = LLJIT(builder)
        end
    else
        lljit = LLJIT(;tm=tempTM)
    end

    jd_main = JITDylib(lljit)

    prefix = LLVM.get_prefix(lljit)
    dg = LLVM.CreateDynamicLibrarySearchGeneratorForProcess(prefix)
    LLVM.add!(jd_main, dg)

	if Sys.iswindows() && Int === Int64
		# TODO can we check isGNU?
		define_absolute_symbol(jd_main, mangle(lljit, "___chkstk_ms"))
	end

    es = ExecutionSession(lljit)
    try
        lctm = LLVM.LocalLazyCallThroughManager(triple(lljit), es)
        ism = LLVM.LocalIndirectStubsManager(triple(lljit))
        jit[] = CompilerInstance(lljit, lctm, ism)
    catch err
        @warn "OrcV2 initialization failed with" err
        jit[] = CompilerInstance(lljit, nothing, nothing)
    end

    atexit() do
        ci = jit[]
        dispose(ci)
        dispose(tm[])
    end
end

function move_to_threadsafe(ir)
    LLVM.verify(ir) # try to catch broken modules

    # So 1. serialize the module
    buf = convert(MemoryBuffer, ir)

    # 2. deserialize and wrap by a ThreadSafeModule
    return ThreadSafeContext() do ctx
        mod = parse(LLVM.Module, buf; ctx=context(ctx))
        ThreadSafeModule(mod; ctx)
    end
end

function get_trampoline(job)
    compiler = jit[]
    lljit = compiler.jit
    lctm  = compiler.lctm
    ism   = compiler.ism

    if lctm === nothing || ism === nothing
        error("Delayed compilation not available.")
    end

    # We could also use one dylib per job
    jd = JITDylib(lljit)

    entry_sym = String(gensym(:entry))
    target_sym = String(gensym(:target))
    flags = LLVM.API.LLVMJITSymbolFlags(
                LLVM.API.LLVMJITSymbolGenericFlagsCallable |
                LLVM.API.LLVMJITSymbolGenericFlagsExported, 0)
    entry = LLVM.API.LLVMOrcCSymbolAliasMapPair(
                mangle(lljit, entry_sym),
                LLVM.API.LLVMOrcCSymbolAliasMapEntry(
                    mangle(lljit, target_sym), flags))

    mu = LLVM.reexports(lctm, ism, jd, Ref(entry))
    LLVM.define(jd, mu)

    # 2. Lookup address of entry symbol
    addr = LLVM.lookup(lljit, entry_sym)

    # 3. add MU that will call back into the compiler
    sym = LLVM.API.LLVMOrcCSymbolFlagsMapPair(mangle(lljit, target_sym), flags)

    function materialize(mr)
        mod, adjoint_name, primal_name = Compiler._thunk(job)
        adjointf = functions(mod)[adjoint_name]

        # Rename adjointf to match target_sym
        # Really we should do:
        # Create a re-export for a unique name, and a custom materialization unit that makes the deferred decision. E.g. add "foo" -> "my_deferred_decision_sym.1". Then define a CustomMU whose materialization method looks like:
        # 1. Make the runtime decision about what symbol should implement "foo". Let's call this "foo.rt.impl".
        # 2 Add a module defining "foo.rt.impl" to the JITDylib.
        # 2. Call MR.replace(symbolAliases({"my_deferred_decision_sym.1" -> "foo.rt.impl"})).
        LLVM.name!(adjointf, target_sym)
        tsm = move_to_threadsafe(mod)

        il = LLVM.IRTransformLayer(lljit)
        LLVM.emit(il, mr, tsm)

        return nothing
    end

    function discard(jd, sym)
    end

    mu = LLVM.CustomMaterializationUnit(entry_sym, Ref(sym), materialize, discard)
    LLVM.define(jd, mu)
    return addr
end

function add!(mod)
    lljit = jit[].jit
    jd = LLVM.JITDylib(lljit)
    tsm = move_to_threadsafe(mod)
    LLVM.add!(lljit, jd, tsm)
    return nothing
end

function lookup(_, name)
    LLVM.lookup(jit[].jit, name)
end

end # module

ext: jl


text:
@testset "6.6.1 (c+d x)^m (a+b csch)^n" begin
    (a, b, c, d, e, f, x, ) = @variables a b c d e f x

    #= ::Package:: =#

    #= ::Title::Closed:: =#
    #=Integrands*of*the*form*(e+f*x)^m*(a+b*csch(c+d*x))^p=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(c+d*x)^m*csch(a+b*x)^p=#

    @test_int [(c + d*x)^3*csch(a + b*x), x, 9, -((2*(c + d*x)^3*atanh(ℯ^(a + b*x)))/b) - (3*d*(c + d*x)^2*PolyLog(2, -ℯ^(a + b*x)))/b^2 + (3*d*(c + d*x)^2*PolyLog(2, ℯ^(a + b*x)))/b^2 + (6*d^2*(c + d*x)*PolyLog(3, -ℯ^(a + b*x)))/b^3 - (6*d^2*(c + d*x)*PolyLog(3, ℯ^(a + b*x)))/b^3 - (6*d^3*PolyLog(4, -ℯ^(a + b*x)))/b^4 + (6*d^3*PolyLog(4, ℯ^(a + b*x)))/b^4]
    @test_int [(c + d*x)^2*csch(a + b*x), x, 7, -((2*(c + d*x)^2*atanh(ℯ^(a + b*x)))/b) - (2*d*(c + d*x)*PolyLog(2, -ℯ^(a + b*x)))/b^2 + (2*d*(c + d*x)*PolyLog(2, ℯ^(a + b*x)))/b^2 + (2*d^2*PolyLog(3, -ℯ^(a + b*x)))/b^3 - (2*d^2*PolyLog(3, ℯ^(a + b*x)))/b^3]
    @test_int [(c + d*x)^1*csch(a + b*x), x, 5, -((2*(c + d*x)*atanh(ℯ^(a + b*x)))/b) - (d*PolyLog(2, -ℯ^(a + b*x)))/b^2 + (d*PolyLog(2, ℯ^(a + b*x)))/b^2]
    @test_int [1/x^1*csch(a + b*x), x, 0, Unintegrable(csch(a + b*x)/x, x)]

    @test_int [(c + d*x)^3*csch(a + b*x)^2, x, 6, -((c + d*x)^3/b) - ((c + d*x)^3*coth(a + b*x))/b + (3*d*(c + d*x)^2*log(1 - ℯ^(2*(a + b*x))))/b^2 + (3*d^2*(c + d*x)*PolyLog(2, ℯ^(2*(a + b*x))))/b^3 - (3*d^3*PolyLog(3, ℯ^(2*(a + b*x))))/(2*b^4)]
    @test_int [(c + d*x)^2*csch(a + b*x)^2, x, 5, -((c + d*x)^2/b) - ((c + d*x)^2*coth(a + b*x))/b + (2*d*(c + d*x)*log(1 - ℯ^(2*(a + b*x))))/b^2 + (d^2*PolyLog(2, ℯ^(2*(a + b*x))))/b^3]
    @test_int [(c + d*x)^1*csch(a + b*x)^2, x, 2, -(((c + d*x)*coth(a + b*x))/b) + (d*log(sinh(a + b*x)))/b^2]
    @test_int [1/x^1*csch(a + b*x)^2, x, 0, Unintegrable(csch(a + b*x)^2/x, x)]

    @test_int [(c + d*x)^3*csch(a + b*x)^3, x, 15, -((6*d^2*(c + d*x)*atanh(ℯ^(a + b*x)))/b^3) + ((c + d*x)^3*atanh(ℯ^(a + b*x)))/b - (3*d*(c + d*x)^2*csch(a + b*x))/(2*b^2) - ((c + d*x)^3*coth(a + b*x)*csch(a + b*x))/(2*b) - (3*d^3*PolyLog(2, -ℯ^(a + b*x)))/b^4 + (3*d*(c + d*x)^2*PolyLog(2, -ℯ^(a + b*x)))/(2*b^2) + (3*d^3*PolyLog(2, ℯ^(a + b*x)))/b^4 - (3*d*(c + d*x)^2*PolyLog(2, ℯ^(a + b*x)))/(2*b^2) - (3*d^2*(c + d*x)*PolyLog(3, -ℯ^(a + b*x)))/b^3 + (3*d^2*(c + d*x)*PolyLog(3, ℯ^(a + b*x)))/b^3 + (3*d^3*PolyLog(4, -ℯ^(a + b*x)))/b^4 - (3*d^3*PolyLog(4, ℯ^(a + b*x)))/b^4]
    @test_int [(c + d*x)^2*csch(a + b*x)^3, x, 9, ((c + d*x)^2*atanh(ℯ^(a + b*x)))/b - (d^2*atanh(cosh(a + b*x)))/b^3 - (d*(c + d*x)*csch(a + b*x))/b^2 - ((c + d*x)^2*coth(a + b*x)*csch(a + b*x))/(2*b) + (d*(c + d*x)*PolyLog(2, -ℯ^(a + b*x)))/b^2 - (d*(c + d*x)*PolyLog(2, ℯ^(a + b*x)))/b^2 - (d^2*PolyLog(3, -ℯ^(a + b*x)))/b^3 + (d^2*PolyLog(3, ℯ^(a + b*x)))/b^3]
    @test_int [(c + d*x)^1*csch(a + b*x)^3, x, 6, ((c + d*x)*atanh(ℯ^(a + b*x)))/b - (d*csch(a + b*x))/(2*b^2) - ((c + d*x)*coth(a + b*x)*csch(a + b*x))/(2*b) + (d*PolyLog(2, -ℯ^(a + b*x)))/(2*b^2) - (d*PolyLog(2, ℯ^(a + b*x)))/(2*b^2)]
    @test_int [1/x^1*csch(a + b*x)^3, x, 0, Unintegrable(csch(a + b*x)^3/x, x)]

    #= ::Subsection:: =#
    #=Integrands*of*the*form*(c+d*x)^(m/2)*csch(a+b*x)^p=#

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

    @test_int [x/csch(x)^(3/2) + x*sqrt(csch(x))/3, x, 4, -(4/(9*csch(x)^(3/2))) + (2*x*cosh(x))/(3*sqrt(csch(x)))]
    @test_int [x/csch(x)^(5/2) + 3*x/(5*sqrt(csch(x))), x, 4, -(4/(25*csch(x)^(5/2))) + (2*x*cosh(x))/(5*csch(x)^(3/2))]
    @test_int [x/csch(x)^(7/2) - (5/21)*x*sqrt(csch(x)), x, 5, -(4/(49*csch(x)^(7/2))) + (2*x*cosh(x))/(7*csch(x)^(5/2)) + 20/(63*csch(x)^(3/2)) - (10*x*cosh(x))/(21*sqrt(csch(x)))]
    @test_int [x^2/csch(x)^(3/2) + (1/3)*x^2*sqrt(csch(x)), x, 7, -((8*x)/(9*csch(x)^(3/2))) + (16*cosh(x))/(27*sqrt(csch(x))) + (2*x^2*cosh(x))/(3*sqrt(csch(x))) - (16/27)*im*sqrt(csch(x))*Elliptic.F(pi/4 - (im*x)/2, 2)*sqrt(im*sinh(x))]

    #= ::Title::Closed:: =#
    #=Integrands*of*the*form*(e+f*x)^m*sinh(c+d*x)^n*(a+b*csch(c+d*x))^p=#

    #= ::Section:: =#
    #=Integrands*of*the*form*(e+f*x)^m*sinh(c+d*x)^n*(a+b*csch(c+d*x))^p*with*a^2+b^2=0=#

    #= ::Section:: =#
    #=Integrands*of*the*form*(e+f*x)^m*sinh(c+d*x)^n*(a+b*csch(c+d*x))^p=#

    #= ::Title::Closed:: =#
    #=Integrands*of*the*form*(e+f*x)^m*cosh(c+d*x)^n*(a+b*csch(c+d*x))^p=#

    #= ::Section:: =#
    #=Integrands*of*the*form*(e+f*x)^m*cosh(c+d*x)^n*(a+b*csch(c+d*x))^p*with*a^2+b^2=0=#

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*(e+f*x)^m*cosh(c+d*x)^n*(a+b*csch(c+d*x))^p=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*(e+f*x)^m*cosh(c+d*x)^n / (a+b*csch(c+d*x))^1=#

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

    @test_int [((e + f*x)^3*cosh(c + d*x))/(a + b*csch(c + d*x)), x, 17, (b*(e + f*x)^4)/(4*a^2*f) - (6*f^3*cosh(c + d*x))/(a*d^4) - (3*f*(e + f*x)^2*cosh(c + d*x))/(a*d^2) - (b*(e + f*x)^3*log(1 + (a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2))))/(a^2*d) - (b*(e + f*x)^3*log(1 + (a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2))))/(a^2*d) - (3*b*f*(e + f*x)^2*PolyLog(2, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^2*d^2) - (3*b*f*(e + f*x)^2*PolyLog(2, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^2*d^2) + (6*b*f^2*(e + f*x)*PolyLog(3, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^2*d^3) + (6*b*f^2*(e + f*x)*PolyLog(3, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^2*d^3) - (6*b*f^3*PolyLog(4, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^2*d^4) - (6*b*f^3*PolyLog(4, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^2*d^4) + (6*f^2*(e + f*x)*sinh(c + d*x))/(a*d^3) + ((e + f*x)^3*sinh(c + d*x))/(a*d)]
    @test_int [((e + f*x)^2*cosh(c + d*x))/(a + b*csch(c + d*x)), x, 14, (b*(e + f*x)^3)/(3*a^2*f) - (2*f*(e + f*x)*cosh(c + d*x))/(a*d^2) - (b*(e + f*x)^2*log(1 + (a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2))))/(a^2*d) - (b*(e + f*x)^2*log(1 + (a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2))))/(a^2*d) - (2*b*f*(e + f*x)*PolyLog(2, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^2*d^2) - (2*b*f*(e + f*x)*PolyLog(2, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^2*d^2) + (2*b*f^2*PolyLog(3, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^2*d^3) + (2*b*f^2*PolyLog(3, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^2*d^3) + (2*f^2*sinh(c + d*x))/(a*d^3) + ((e + f*x)^2*sinh(c + d*x))/(a*d)]
    @test_int [((e + f*x)*cosh(c + d*x))/(a + b*csch(c + d*x)), x, 11, (b*(e + f*x)^2)/(2*a^2*f) - (f*cosh(c + d*x))/(a*d^2) - (b*(e + f*x)*log(1 + (a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2))))/(a^2*d) - (b*(e + f*x)*log(1 + (a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2))))/(a^2*d) - (b*f*PolyLog(2, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^2*d^2) - (b*f*PolyLog(2, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^2*d^2) + ((e + f*x)*sinh(c + d*x))/(a*d)]
    @test_int [cosh(c + d*x)/(a + b*csch(c + d*x)), x, 5, -((b*log(b + a*sinh(c + d*x)))/(a^2*d)) + sinh(c + d*x)/(a*d)]
    @test_int [cosh(c + d*x)/((e + f*x)*(a + b*csch(c + d*x))), x, 1, Unintegrable((cosh(c + d*x)*sinh(c + d*x))/((e + f*x)*(b + a*sinh(c + d*x))), x)]

    @test_int [((e + f*x)^3*cosh(c + d*x)^2)/(a + b*csch(c + d*x)), x, 24, (3*e*f^2*x)/(4*a*d^2) + (3*f^3*x^2)/(8*a*d^2) + (e + f*x)^4/(8*a*f) + (b^2*(e + f*x)^4)/(4*a^3*f) - (6*b*f^2*(e + f*x)*cosh(c + d*x))/(a^2*d^3) - (b*(e + f*x)^3*cosh(c + d*x))/(a^2*d) - (3*f^3*cosh(c + d*x)^2)/(8*a*d^4) - (3*f*(e + f*x)^2*cosh(c + d*x)^2)/(4*a*d^2) - (b*sqrt(a^2 + b^2)*(e + f*x)^3*log(1 + (a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2))))/(a^3*d) + (b*sqrt(a^2 + b^2)*(e + f*x)^3*log(1 + (a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2))))/(a^3*d) - (3*b*sqrt(a^2 + b^2)*f*(e + f*x)^2*PolyLog(2, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^3*d^2) + (3*b*sqrt(a^2 + b^2)*f*(e + f*x)^2*PolyLog(2, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^3*d^2) + (6*b*sqrt(a^2 + b^2)*f^2*(e + f*x)*PolyLog(3, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^3*d^3) - (6*b*sqrt(a^2 + b^2)*f^2*(e + f*x)*PolyLog(3, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^3*d^3) - (6*b*sqrt(a^2 + b^2)*f^3*PolyLog(4, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^3*d^4) + (6*b*sqrt(a^2 + b^2)*f^3*PolyLog(4, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^3*d^4) + (6*b*f^3*sinh(c + d*x))/(a^2*d^4) + (3*b*f*(e + f*x)^2*sinh(c + d*x))/(a^2*d^2) + (3*f^2*(e + f*x)*cosh(c + d*x)*sinh(c + d*x))/(4*a*d^3) + ((e + f*x)^3*cosh(c + d*x)*sinh(c + d*x))/(2*a*d)]
    @test_int [((e + f*x)^2*cosh(c + d*x)^2)/(a + b*csch(c + d*x)), x, 21, (f^2*x)/(4*a*d^2) + (e + f*x)^3/(6*a*f) + (b^2*(e + f*x)^3)/(3*a^3*f) - (2*b*f^2*cosh(c + d*x))/(a^2*d^3) - (b*(e + f*x)^2*cosh(c + d*x))/(a^2*d) - (f*(e + f*x)*cosh(c + d*x)^2)/(2*a*d^2) - (b*sqrt(a^2 + b^2)*(e + f*x)^2*log(1 + (a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2))))/(a^3*d) + (b*sqrt(a^2 + b^2)*(e + f*x)^2*log(1 + (a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2))))/(a^3*d) - (2*b*sqrt(a^2 + b^2)*f*(e + f*x)*PolyLog(2, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^3*d^2) + (2*b*sqrt(a^2 + b^2)*f*(e + f*x)*PolyLog(2, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^3*d^2) + (2*b*sqrt(a^2 + b^2)*f^2*PolyLog(3, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^3*d^3) - (2*b*sqrt(a^2 + b^2)*f^2*PolyLog(3, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^3*d^3) + (2*b*f*(e + f*x)*sinh(c + d*x))/(a^2*d^2) + (f^2*cosh(c + d*x)*sinh(c + d*x))/(4*a*d^3) + ((e + f*x)^2*cosh(c + d*x)*sinh(c + d*x))/(2*a*d)]
    @test_int [((e + f*x)*cosh(c + d*x)^2)/(a + b*csch(c + d*x)), x, 16, (e*x)/(2*a) + (b^2*e*x)/a^3 + (f*x^2)/(4*a) + (b^2*f*x^2)/(2*a^3) - (b*(e + f*x)*cosh(c + d*x))/(a^2*d) - (f*cosh(c + d*x)^2)/(4*a*d^2) - (b*sqrt(a^2 + b^2)*(e + f*x)*log(1 + (a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2))))/(a^3*d) + (b*sqrt(a^2 + b^2)*(e + f*x)*log(1 + (a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2))))/(a^3*d) - (b*sqrt(a^2 + b^2)*f*PolyLog(2, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^3*d^2) + (b*sqrt(a^2 + b^2)*f*PolyLog(2, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^3*d^2) + (b*f*sinh(c + d*x))/(a^2*d^2) + ((e + f*x)*cosh(c + d*x)*sinh(c + d*x))/(2*a*d)]
    @test_int [cosh(c + d*x)^2/(a + b*csch(c + d*x)), x, 6, ((a^2 + 2*b^2)*x)/(2*a^3) + (2*b*sqrt(a^2 + b^2)*atanh((a - b*tanh((c + d*x)/2))/sqrt(a^2 + b^2)))/(a^3*d) - (cosh(c + d*x)*(2*b - a*sinh(c + d*x)))/(2*a^2*d)]

    @test_int [((e + f*x)^3*cosh(c + d*x)^3)/(a + b*csch(c + d*x)), x, 31, (-3*b*f^3*x)/(8*a^2*d^3) - (b*(e + f*x)^3)/(4*a^2*d) + (b*(a^2 + b^2)*(e + f*x)^4)/(4*a^4*f) - (40*f^3*cosh(c + d*x))/(9*a*d^4) - (6*b^2*f^3*cosh(c + d*x))/(a^3*d^4) - (2*f*(e + f*x)^2*cosh(c + d*x))/(a*d^2) - (3*b^2*f*(e + f*x)^2*cosh(c + d*x))/(a^3*d^2) - (2*f^3*cosh(c + d*x)^3)/(27*a*d^4) - (f*(e + f*x)^2*cosh(c + d*x)^3)/(3*a*d^2) - (b*(a^2 + b^2)*(e + f*x)^3*log(1 + (a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2))))/(a^4*d) - (b*(a^2 + b^2)*(e + f*x)^3*log(1 + (a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2))))/(a^4*d) - (3*b*(a^2 + b^2)*f*(e + f*x)^2*PolyLog(2, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^4*d^2) - (3*b*(a^2 + b^2)*f*(e + f*x)^2*PolyLog(2, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^4*d^2) + (6*b*(a^2 + b^2)*f^2*(e + f*x)*PolyLog(3, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^4*d^3) + (6*b*(a^2 + b^2)*f^2*(e + f*x)*PolyLog(3, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^4*d^3) - (6*b*(a^2 + b^2)*f^3*PolyLog(4, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^4*d^4) - (6*b*(a^2 + b^2)*f^3*PolyLog(4, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^4*d^4) + (40*f^2*(e + f*x)*sinh(c + d*x))/(9*a*d^3) + (6*b^2*f^2*(e + f*x)*sinh(c + d*x))/(a^3*d^3) + (2*(e + f*x)^3*sinh(c + d*x))/(3*a*d) + (b^2*(e + f*x)^3*sinh(c + d*x))/(a^3*d) + (3*b*f^3*cosh(c + d*x)*sinh(c + d*x))/(8*a^2*d^4) + (3*b*f*(e + f*x)^2*cosh(c + d*x)*sinh(c + d*x))/(4*a^2*d^2) + (2*f^2*(e + f*x)*cosh(c + d*x)^2*sinh(c + d*x))/(9*a*d^3) + ((e + f*x)^3*cosh(c + d*x)^2*sinh(c + d*x))/(3*a*d) - (3*b*f^2*(e + f*x)*sinh(c + d*x)^2)/(4*a^2*d^3) - (b*(e + f*x)^3*sinh(c + d*x)^2)/(2*a^2*d)]
    @test_int [((e + f*x)^2*cosh(c + d*x)^3)/(a + b*csch(c + d*x)), x, 24, -(b*e*f*x)/(2*a^2*d) - (b*f^2*x^2)/(4*a^2*d) + (b*(a^2 + b^2)*(e + f*x)^3)/(3*a^4*f) - (4*f*(e + f*x)*cosh(c + d*x))/(3*a*d^2) - (2*b^2*f*(e + f*x)*cosh(c + d*x))/(a^3*d^2) - (2*f*(e + f*x)*cosh(c + d*x)^3)/(9*a*d^2) - (b*(a^2 + b^2)*(e + f*x)^2*log(1 + (a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2))))/(a^4*d) - (b*(a^2 + b^2)*(e + f*x)^2*log(1 + (a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2))))/(a^4*d) - (2*b*(a^2 + b^2)*f*(e + f*x)*PolyLog(2, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^4*d^2) - (2*b*(a^2 + b^2)*f*(e + f*x)*PolyLog(2, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^4*d^2) + (2*b*(a^2 + b^2)*f^2*PolyLog(3, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^4*d^3) + (2*b*(a^2 + b^2)*f^2*PolyLog(3, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^4*d^3) + (14*f^2*sinh(c + d*x))/(9*a*d^3) + (2*b^2*f^2*sinh(c + d*x))/(a^3*d^3) + (2*(e + f*x)^2*sinh(c + d*x))/(3*a*d) + (b^2*(e + f*x)^2*sinh(c + d*x))/(a^3*d) + (b*f*(e + f*x)*cosh(c + d*x)*sinh(c + d*x))/(2*a^2*d^2) + ((e + f*x)^2*cosh(c + d*x)^2*sinh(c + d*x))/(3*a*d) - (b*f^2*sinh(c + d*x)^2)/(4*a^2*d^3) - (b*(e + f*x)^2*sinh(c + d*x)^2)/(2*a^2*d) + (2*f^2*sinh(c + d*x)^3)/(27*a*d^3)]
    @test_int [((e + f*x)*cosh(c + d*x)^3)/(a + b*csch(c + d*x)), x, 18, -(b*f*x)/(4*a^2*d) + (b*(a^2 + b^2)*(e + f*x)^2)/(2*a^4*f) - (2*f*cosh(c + d*x))/(3*a*d^2) - (b^2*f*cosh(c + d*x))/(a^3*d^2) - (f*cosh(c + d*x)^3)/(9*a*d^2) - (b*(a^2 + b^2)*(e + f*x)*log(1 + (a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2))))/(a^4*d) - (b*(a^2 + b^2)*(e + f*x)*log(1 + (a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2))))/(a^4*d) - (b*(a^2 + b^2)*f*PolyLog(2, -((a*ℯ^(c + d*x))/(b - sqrt(a^2 + b^2)))))/(a^4*d^2) - (b*(a^2 + b^2)*f*PolyLog(2, -((a*ℯ^(c + d*x))/(b + sqrt(a^2 + b^2)))))/(a^4*d^2) + (2*(e + f*x)*sinh(c + d*x))/(3*a*d) + (b^2*(e + f*x)*sinh(c + d*x))/(a^3*d) + (b*f*cosh(c + d*x)*sinh(c + d*x))/(4*a^2*d^2) + ((e + f*x)*cosh(c + d*x)^2*sinh(c + d*x))/(3*a*d) - (b*(e + f*x)*sinh(c + d*x)^2)/(2*a^2*d)]
    @test_int [cosh(c + d*x)^3/(a + b*csch(c + d*x)), x, 5, -((b*(a^2 + b^2)*log(b + a*sinh(c + d*x)))/(a^4*d)) + ((a^2 + b^2)*sinh(c + d*x))/(a^3*d) - (b*sinh(c + d*x)^2)/(2*a^2*d) + sinh(c + d*x)^3/(3*a*d)]

    #= ::Subsubsection:: =#
    #=n<0=#
    end

max_stars_repo_path: test/6 Hyperbolic functions/6.6 Hyperbolic cosecant/6.6.1 (c+d x)^m (a+b csch)^n.jl


text:
module ZeroMeanFESpacesTests

using Test
using Gridap.Geometry
using Gridap.Fields
using Gridap.Integration
using Gridap.FESpaces
using Gridap.CellData

domain = (0,1,0,1)
partition = (4,4)
model = CartesianDiscreteModel(domain,partition)

order = 2

trian = get_triangulation(model)
degree = order
quad = CellQuadrature(trian,degree)

_V = TestFESpace(
  model=model,
  reffe=:Lagrangian,
  valuetype=Float64,
  order=order,
  conformity=:L2)

V = ZeroMeanFESpace(_V,trian,quad)
matvecdata = ([],[],[])
matdata = ([],[],[])
vecdata = ([],[])
test_single_field_fe_space(V,matvecdata,matdata,vecdata)

U = TrialFESpace(V)
test_single_field_fe_space(U,matvecdata,matdata,vecdata)
@test isa(U,ZeroMeanFESpace)
@test is_trial(get_cell_basis(U))

fun(x) = sin(4*pi*(x[1]+x[2]^2)) + 3
uh = interpolate(fun, U)

mean1 = sum(integrate(uh,trian,quad))

tol = 1.0e-10
@test abs(mean1) < tol

end # module


text:
# AUTO GENERATED FILE - DO NOT EDIT

export 'feffery'_antdanchor

"""
    'feffery'_antdanchor(;kwargs...)

An AntdAnchor component.

Keyword arguments:
- `id` (String; optional)
- `align` (String; optional)
- `className` (String; optional)
- `containerId` (String; optional)
- `linkDict` (optional)
- `loading_state` (optional): . loading_state has the following type: lists containing elements 'is_loading', 'prop_name', 'component_name'.
Those elements have the following types:
  - `is_loading` (Bool; optional): Determines if the component is loading or not
  - `prop_name` (String; optional): Holds which property is loading
  - `component_name` (String; optional): Holds the name of the component that is loading
- `style` (Dict; optional)
- `targetOffset` (Real; optional)
"""
function 'feffery'_antdanchor(; kwargs...)
        available_props = Symbol[:id, :align, :className, :containerId, :linkDict, :loading_state, :style, :targetOffset]
        wild_props = Symbol[]
        return Component("'feffery'_antdanchor", "AntdAnchor", "feffery_antd_components", available_props, wild_props; kwargs...)
end

max_stars_repo_name: Beddow/feffery-antd-components

max_issues_repo_name: Beddow/feffery-antd-components

max_forks_repo_name: Beddow/feffery-antd-components


text:
@require TypedTables begin

immutable EnumerableTypedTable{T, TS} <: Enumerable{T}
    df::TypedTables.Table
    # This field hols a tuple with the columns of the DataFrame.
    # Having a tuple of the columns here allows the iterator
    # functions to access the columns in a type stable way.
    columns::TS
end

function query(df::TypedTables.Table)
    col_expressions = Array{Expr,1}()
    df_columns_tuple_type = Expr(:curly, :Tuple)
    for i in 1:length(df.data)
        push!(col_expressions, Expr(:(::), names(df)[i], eltype(df.data[i])))
        push!(df_columns_tuple_type.args, typeof(df.data[i]))
    end
    t_expr = NamedTuples.make_tuple(col_expressions)

    t2 = :(Query.EnumerableTypedTable{Float64,Float64})
    t2.args[2] = t_expr
    t2.args[3] = df_columns_tuple_type

    eval(NamedTuples, :(import Query))
    t = eval(NamedTuples, t2)

    e_df = t(df, df.data)

    return e_df
end

function length{T,TS}(iter::EnumerableTypedTable{T,TS})
    return size(iter.df,1)
end

function eltype{T,TS}(iter::EnumerableTypedTable{T,TS})
    return T
end

function start{T,TS}(iter::EnumerableTypedTable{T,TS})
    return 1
end

@generated function next{T,TS}(iter::EnumerableTypedTable{T,TS}, state)
    constructor_call = Expr(:call, :($T))
    for i in 1:length(iter.types[2].types)
        push!(constructor_call.args, :(columns[$i][i]))
    end

    quote
        i = state
        columns = iter.columns
        a = $constructor_call
        return a, state+1
    end
end

function done{T,TS}(iter::EnumerableTypedTable{T,TS}, state)
    return state>size(iter.df,1)
end

end


text:
"""
    AbstractFieldStyle

The supertype of all broadcasting-like operations on Fields.
"""
abstract type AbstractFieldStyle <: Base.BroadcastStyle end

"""
    FieldStyle{DS <: DataStyle}

Standard broadcasting on Fields. Delegates the actual work to `DS`.
"""
struct FieldStyle{DS <: DataStyle} <: AbstractFieldStyle end

FieldStyle(::DS) where {DS <: DataStyle} = FieldStyle{DS}()

Base.Broadcast.BroadcastStyle(::Type{Field{V, M}}) where {V, M} =
    FieldStyle(DataStyle(V))

Base.Broadcast.BroadcastStyle(
    ::Base.Broadcast.AbstractArrayStyle{0},
    b::AbstractFieldStyle,
) = b

Base.Broadcast.broadcastable(field::Field) = field

Base.eltype(bc::Base.Broadcast.Broadcasted{<:AbstractFieldStyle}) =
    Base.Broadcast.combine_eltypes(bc.f, bc.args)

# we implement our own to avoid the type-widening code, and throw a more useful error
function Base.copy(
    bc::Base.Broadcast.Broadcasted{Style},
) where {Style <: AbstractFieldStyle}
    ElType = eltype(bc)
    if Base.isconcretetype(ElType)
        # We can trust it and defer to the simpler `copyto!`
        return copyto!(similar(bc, ElType), bc)
    end
    error("cannot infer concrete eltype of $(bc.f) on $(map(eltype, bc.args))")
end

function slab(
    bc::Base.Broadcast.Broadcasted{Style},
    v,
    h,
) where {Style <: AbstractFieldStyle}
    _args = map(a -> slab(a, v, h), bc.args)
    _axes = slab(axes(bc), v, h)
    Base.Broadcast.Broadcasted{Style}(bc.f, _args, _axes)
end

function column(
    bc::Base.Broadcast.Broadcasted{Style},
    i,
    j,
    h,
) where {Style <: AbstractFieldStyle}
    _args = map(a -> column(a, i, j, h), bc.args)
    _axes = column(axes(bc), i, j, h)
    Base.Broadcast.Broadcasted{Style}(bc.f, _args, _axes)
end

# Return underlying DataLayout object, DataStyle of broadcasted
# for `Base.similar` of a Field
todata(obj) = obj
todata(field::Field) = Fields.field_values(field)
function todata(bc::Base.Broadcast.Broadcasted{FieldStyle{DS}}) where {DS}
    Base.Broadcast.Broadcasted{DS}(bc.f, map(todata, bc.args))
end

# same logic as Base.Broadcasted (which only defines it for Tuples)
Base.axes(bc::Base.Broadcast.Broadcasted{<:AbstractFieldStyle}) =
    _axes(bc, bc.axes)
_axes(bc, ::Nothing) = Base.Broadcast.combine_axes(bc.args...)
_axes(bc, axes) = axes

function Base.similar(
    bc::Base.Broadcast.Broadcasted{<:AbstractFieldStyle},
    ::Type{Eltype},
) where {Eltype}
    return Field(similar(todata(bc), Eltype), axes(bc))
end

function Base.copyto!(
    dest::Field,
    bc::Base.Broadcast.Broadcasted{<:AbstractFieldStyle},
)
    copyto!(field_values(dest), todata(bc))
    return dest
end

function Base.Broadcast.broadcast_shape(
    space1::AbstractSpace,
    space2::AbstractSpace,
)
    if space1 !== space2
        error("Mismatched spaces\n$space1\n$space2")
    end
    return space1
end
Base.Broadcast.broadcast_shape(space::AbstractSpace, ::Tuple{}) = space
Base.Broadcast.broadcast_shape(::Tuple{}, space::AbstractSpace) = space

# Overload broadcast axes shape checking for more useful error message for Field Spaces
function Base.Broadcast.check_broadcast_shape(
    space1::AbstractSpace,
    space2::AbstractSpace,
)
    if space1 !== space2
        error("Mismatched spaces\n$(summary(space1))\n$(summary(space2))")
    end
    return nothing
end

function Base.Broadcast.check_broadcast_shape(::AbstractSpace, ::Tuple{})
    return nothing
end

function Base.Broadcast.check_broadcast_shape(::AbstractSpace, ax2::Tuple)
    error("$ax2 is not a AbstractSpace")
end

# Specialize handling of +, *, muladd, so that we can support broadcasting over NamedTuple element types
# Required for ODE solvers
Base.Broadcast.broadcasted(fs::AbstractFieldStyle, ::typeof(+), args...) =
    Base.Broadcast.broadcasted(fs, RecursiveApply.:⊞, args...)

Base.Broadcast.broadcasted(fs::AbstractFieldStyle, ::typeof(-), args...) =
    Base.Broadcast.broadcasted(fs, RecursiveApply.:⊟, args...)

Base.Broadcast.broadcasted(fs::AbstractFieldStyle, ::typeof(*), args...) =
    Base.Broadcast.broadcasted(fs, RecursiveApply.:⊠, args...)

Base.Broadcast.broadcasted(fs::AbstractFieldStyle, ::typeof(/), args...) =
    Base.Broadcast.broadcasted(fs, RecursiveApply.rdiv, args...)

Base.Broadcast.broadcasted(fs::AbstractFieldStyle, ::typeof(muladd), args...) =
    Base.Broadcast.broadcasted(fs, RecursiveApply.rmuladd, args...)

# Specialize handling of vector-based functions to automatically add LocalGeometry information
function Base.Broadcast.broadcasted(
    fs::AbstractFieldStyle,
    ::typeof(LinearAlgebra.norm),
    arg,
)
    space = Fields.axes(arg)
    # wrap in a Field so that the axes line up correctly (it just get's unwraped so effectively a no-op)
    Base.Broadcast.broadcasted(
        fs,
        Geometry._norm,
        arg,
        local_geometry_field(space),
    )
end
function Base.Broadcast.broadcasted(
    fs::AbstractFieldStyle,
    ::typeof(LinearAlgebra.norm_sqr),
    arg,
)
    space = Fields.axes(arg)
    # wrap in a Field so that the axes line up correctly (it just get's unwraped so effectively a no-op)
    Base.Broadcast.broadcasted(
        fs,
        Geometry._norm_sqr,
        arg,
        local_geometry_field(space),
    )
end

function Base.Broadcast.broadcasted(
    fs::AbstractFieldStyle,
    ::typeof(LinearAlgebra.cross),
    arg1,
    arg2,
)
    space = Fields.axes(arg1)
    # wrap in a Field so that the axes line up correctly (it just get's unwraped so effectively a no-op)
    Base.Broadcast.broadcasted(
        fs,
        Geometry._cross,
        arg1,
        arg2,
        local_geometry_field(space),
    )
end
function Base.Broadcast.broadcasted(
    fs::AbstractFieldStyle,
    ::typeof(Geometry.transform),
    arg1,
    arg2,
)
    space = Fields.axes(arg2)
    # wrap in a Field so that the axes line up correctly (it just get's unwraped so effectively a no-op)
    Base.Broadcast.broadcasted(
        fs,
        Geometry.transform,
        arg1,
        arg2,
        local_geometry_field(space),
    )
end

function Base.Broadcast.broadcasted(
    fs::AbstractFieldStyle,
    ::Type{V},
    arg,
) where {V <: Geometry.AxisVector}
    space = Fields.axes(arg)
    # wrap in a Field so that the axes line up correctly (it just get's unwraped so effectively a no-op)
    Base.Broadcast.broadcasted(fs, V, arg, local_geometry_field(space))
end

function Base.Broadcast.copyto!(
    field::Field,
    bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{0}},
)
    copyto!(Fields.field_values(field), bc)
    return field
end
function Base.Broadcast.copyto!(field::Field, nt::NamedTuple)
    copyto!(
        field,
        Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{0}}(
            identity,
            (nt,),
            axes(field),
        ),
    )
end

Base.fill!(field::Fields.Field, val) = field .= val


text:
#
# Functions, and types for downloading and interpolating
# solar system ephemeric data.
#
# This functionality is enabled by JPL HORIZONS and
# HORIZONS.jl!
#

export ephemeris

"""
Given a celestial body's name, or the NAIF ID of the body,
return a DataFrame of ephemeris data for the specified
`timespan` and `intervol` between time steps.

!!! warning
    The [license file](../../LICENSE) for this package applies to all code
    in this package, but note
    that the ephemeris data handling functionality of this package
    (e.g. the `ephemeris` function) uses copyrighted tools with their
    own usage and code sharing restrictions. These copyrighted tools are
    owned by the Jet Propulsion Laboratory at the California Institute
    of Technology. These copyrighted tools are, in part, located at
    ftp://ssd.jpl.nasa.gov/pub/ssd/SCRIPTS/.

    Open source wrappers for these copyrighted tools exist, e.g.
    `HORIZONS.jl` and AstroPy's `astroquery`. The ephemeris handling
    functionality of this package uses `HORIZONS.jl`.

    It is the responsibility of the user to verify they meet the necessary
    requirements, as specifed by JPL in their copyrighted tools (e.g. `vec_tbl`),
    before they share or use those tools.
"""
function ephemeris(
        body::Union{<:AbstractString, <:Integer},
        timespan::Tuple{<:Dates.AbstractDateTime, <:Dates.AbstractDateTime} = (now() - Year(5), now() + Year(5)),
        intervol::Dates.Period = Day(1);
        continuous  = Val{false},
        type        = Float64,
        email       = "",
        wrt         = "@ssb",
        epoch       = "J2000",
    )

    if continuous == Val{true}
        if "Interpolations" ∉ map(string, Base.loaded_modules_array())
            throw(ArgumentError("The `continuous` keyword argument requires Interpolations.jl to be loaded!"))
        end
    elseif continuous != Val{false}
        throw(ArgumentError("The `continuous` keyword argument must be set to `Val{true}` or `Val{false}`!"))
    end

    if isnothing(email)
        EMAIL_ADDR = ""
    elseif isempty(email)
        @warn """No email was provided throuh the `email` keyword argument! The JPL HORIZONS servers accept an email address with each request. Provide an email address using `email = "my-email@provider.com"`, or set `email = nothing` to suppress this warning."""
        EMAIL_ADDR = ""
    else
        EMAIL_ADDR = email
    end

    ID = body isa AbstractString ? naifcode(body) : body

    options = (
        EMAIL_ADDR = EMAIL_ADDR,
        CENTER = wrt,
        REF_SYSTEM = epoch,
        REF_PLANE = "FRAME",
        CSV_FORMAT = true,
        VEC_TABLE = 2,
        VEC_CORR = 1,
        OUT_UNITS = 1,
        VEC_LABELS = false,
        VEC_DELTA_T = false,
    )

    data, = HORIZONS.vec_tbl_csv(ID, timespan[1], timespan[2], intervol; options...)

    if data[1,:] == ["JDTDB", "Calendar_Date_TDB", "X", "Y", "Z", "VX", "VY", "VZ"]
        # Units in Julian Days since J2000, km, km/s
        ephemeris = DataFrame(
            :dⱼ => type.(data[2:end,1]),
            :x  => type.(data[2:end,3]),
            :y  => type.(data[2:end,4]),
            :z  => type.(data[2:end,5]),
            :ẋ  => type.(data[2:end,6]),
            :ẏ  => type.(data[2:end,7]),
            :ż  => type.(data[2:end,8]),
        )
    else
        @warn "Invalid columns! $(data[1,:])"
        throw(ErrorException("Ephemeris data downloaded successfully, but the column format is different than expected!"))
    end

    if continuous == Val{true}
        return ContinuousEphemeris(ephemeris)
    else
        return ephemeris
    end
end

"""
Returns the Cartesian state vector of the requested body at the provided date and time!
All `kwargs` are passed directly to the `timespan` method for `ephemeris`.

!!! warning
    The [license file](../../LICENSE) for this package applies to all code
    in this package, but note
    that the ephemeris data handling functionality of this package
    (e.g. the `ephemeris` function) uses copyrighted tools with their
    own usage and code sharing restrictions. These copyrighted tools are
    owned by the Jet Propulsion Laboratory at the California Institute
    of Technology. These copyrighted tools are, in part, located at
    ftp://ssd.jpl.nasa.gov/pub/ssd/SCRIPTS/.

    Open source wrappers for these copyrighted tools exist, e.g.
    `HORIZONS.jl` and AstroPy's `astroquery`. The ephemeris handling
    functionality of this package uses `HORIZONS.jl`.

    It is the responsibility of the user to verify they meet the necessary
    requirements, as specifed by JPL in their copyrighted tools (e.g. `vec_tbl`),
    before they share or use those tools.
"""
function ephemeris(body::Union{<:Integer, <:AbstractString}, time::Dates.AbstractDateTime; kwargs...)
    override = (; continuous = Val{false})
    options  = merge(kwargs, override)
    data     = ephemeris(body, (time, time + Year(1)), Year(1); options...)
    return DataFrame(data[1,2:end])
end


text:
function update_weights(data, e, closest_same, closest_other, weights, m, max_f_vals, min_f_vals)
	for t = 1:size(data, 2)
		weights[t] = weights[t] - (abs(e[t] - closest_same[t])/(max_f_vals[t] - min_f_vals[t] + eps(Float64)))/m +
			(abs(e[t] - closest_other[t])/(max_f_vals[t] - min_f_vals[t] + eps(Float64)))/m
	end
	return weights
end

max_stars_repo_name: Architecton/diplomska-naloga-koda

max_issues_repo_name: Architecton/diplomska-naloga-koda

max_forks_repo_name: Architecton/diplomska-naloga-koda


text:
# unif.jl
# types for dvc unify

#include("misc.jl")
#include("primitives.jl")
#include("types.jl")
#include("unifybase.jl")
#include("subst.jl")

## unification
function unify0(vars::Vlist, t1::Number, t2::Number)
 if t1==t2; return () end
 throw(ICMP(t1,t2,:unify0nn))
end

function unify0(vars::Vlist, t1::Number, t2::Expr)
 throw(ICMP(t1,t2,:unify0ne))
end

function unify0(vars::Vlist, t1::Expr, t2::Number)
 throw(ICMP(t1,t2,:unify0en))
end

function unify0(vars::Vlist, t1::Number, t2::Symbol)
##@show :unify0ns,vars,t1,t2
 if isvar(t2,vars); return (t2,t1) end
 throw(ICMP(t1,t2,:unify0ns))
end

function unify0(vars::Vlist, t1::Symbol, t2::Number)
#@show :unify0sn,vars,t1,t2
 if isvar(t1,vars); return (t1,t2) end
 throw(ICMP(t1,t2,:unify0sn))
end

function unify0(vars::Vlist, t1::Symbol, t2::Symbol)
#@show :unify0ss,t1,t2
 if t1==t2; return () end
 if isvar(t1,vars) && isvar(t2,vars)
   if isinvar(t1); return (t2,t1) end
   if isinvar(t2); return (t1,t2) end
 end
 if isvar(t1,vars); return (t1,t2) end
 if isvar(t2,vars); return (t2,t1) end
 if t1!=t2; throw(ICMP(t1,t2,:unify0ss)) end
end

function unify0(vars::Vlist, t1::Symbol, t2::Expr)
#@show :unify0se,t1,t2
 isvar(t1,vars) && !loopcheck(t1,t2) && return (t1,t2)
 if t1!=t2; throw(ICMP(t1,t2,:unify0se)) end
end

function unify0(vars::Vlist, t1::Expr, t2::Symbol)
#@show :unify0es,t1,t2
 isvar(t2,vars)&&!loopcheck(t2,t1)&&return(t2,t1)
 if t1!=t2; throw(ICMP(t1,t2,:unify0es)) end
end

function unify0(vars::Vlist, t1::Expr, t2::Expr)
#@show :unify0ee,t1,t2
 if t1==t2; return () end
 for i in 1:length(t1.args)
  if t1.args[i]==t2.args[i]; continue end
  σi=unify0(vars,t1.args[i],t2.args[i])
  if σi!=(); return σi end
 end
 return ()
end

### unify do unification
# t1,t2 are literal(without sign, without or/and.

function unify1(vars::Vlist, t1::Number, t2::Number, subst::Tlist)
#@show :unify1vnn,t1,t2,subst
 if t1==t2; return subst end
 throw(ICMP(t1,t2,:unify1nn))
end

function unify1(vars::Vlist, t1::Expr, t2::Number, subst::Tlist)
#@show :unify1ven,t1,t2,subst
 throw(ICMP(t1,t2,:unify1en))
end
function unify1(vars::Vlist, t1::Number, t2::Expr, subst::Tlist)
#@show :unify1vne,t1,t2,subst
 throw(ICMP(t1,t2,:unify1ne))
end

"""
replace v with t in σ when v is var. and fixed point of σ.
if v<-s in σ, and s is var, replace v with t.
otherwise exception
"""
function putsubst(vars, v::Symbol, t::Any, subst::Tlist)
 if v == t; return subst end

 ix = vindex(vars, v)
 if ix == 0; println("unknown var $v in putsubst");return subst end

 ot = subst[ix]
 if ot == t; return subst end
 if !isvar(ot, vars)
  if ot == t; return subst
  elseif isvar(t, vars)
    v = t
    t = ot
    ix = vindex(vars, v)
    if ix == 0; throw(ICMP(ot,t,:putsubst)) end
  else
   throw(ICMP(ot,t,:putsubst))
  end

  subst=putarray(subst, ix, t)
  return subst
 else
  subst=putarray(subst, ix, t)

  rsubst=[]
  while subst != rsubst
   ix = vindex(vars, ot)
   if ix == 0; println("unknown var $v in putsubst")
     throw(ICMP(ot,t,:unify1ss3))
   end
#@show ix
   rsubst=putsubst(vars, ot, t, subst) # backward subst
   subst=rsubst
#@show subst,rsubst
   ot = subst[ix]
  end
  fsubst = fp_subst(vars, rsubst) # forward subst
  return fsubst
 end
#@show "$ot is not ovar"
 if t == ot; return fp_subst(vars, subst) end
 throw(ICMP(v,t,:unify1ne))
end

function unify1(vars::Vlist, t1::Symbol, t2::Number, subst::Tlist)
#@show :unify1vsn,t1,t2,subst
 putsubst(vars, t1, t2, subst)
end

function unify1(vars::Vlist, t1::Number, t2::Symbol, subst::Tlist)
#@show :unify1vns,t1,t2,subst
 putsubst(vars, t2, t1, subst)
end

function unify1(vars::Vlist, t1::Symbol, t2::Symbol, subst::Tlist)
#@show :unify1vss,t1,t2,subst
 if t1==t2;return subst end

 if isvar(t1,vars)
   return putsubst(vars, t1, t2, subst)
 end
 if isvar(t2,vars)
   return putsubst(vars, t2, t1, subst)
 end

 throw(ICMP(t1,t2,:unify1ss3))
# if isvar(t1,vars)
#  ix = findfirst(x->x==t1,vars)
#  if t1 == subst[ix] # t1 is var and havn't substituted yet.
#    subst[ix] = t2
#  elseif isvar(subst[ix],vars)
#@show :unify1vss1, vars, t1, t2, subst[ix], vars
##    if t2!=subst[ix]; throw(ICMPIn(t1,t2,subst,:unify1ss1))end
#    subst[ix] = t2
#  end
#  return subst
# end
#
# if isvar(t2,vars)
#  ix = findfirst(x->x==t2,vars)
#  if isvar(subst[ix], vars)
#@show :unify1vss2, vars, t1, t2, subst[ix], vars
#    subst[ix] = t1
#  end
#  return subst
# end
# throw(ICMP(t1,t2,:unify1ss3))
end

function unify1(vars::Vlist, t1::Symbol, t2::Expr, subst::Tlist)
#@show :unify1vse,t1,t2,subst
 if isvar(t1,vars);return putsubst(vars, t1, t2, subst) end
# if isvar(t1,vars);return t2 end
 throw(ICMP(t1,t2,:unify1se))
end

function unify1(vars::Vlist, t1::Expr, t2::Symbol, subst::Tlist)
#@show :unify1ves,t1,t2,subst
 if isvar(t2,vars);return putsubst(vars, t2, t1, subst) end
# if isvar(t2,vars);return t2 end
 throw(ICMP(t1,t2,:unify1))
end

"""
unify1 has a var subst for internal use
"""
function unify1(vars::Vlist, t1::Expr, t2::Expr, subst::Tlist)
#@show :unifyvee,t1,t2,subst
 if t1==t2;
  return subst
 end

 if t1.args[1] != t2.args[1];
  throw(ICMP(t1,t2,:unify1ee_1))
 end

 if length(t1.args) != length(t2.args); return vars end
 while true
#@show :unify0,vars,t1,t2
  pp = unify0(vars, t1, t2)
  if isempty(pp); break end
  subst = putasubst(vars, pp[1], pp[2], subst)
  t1 = apply(vars,t1,subst)
  t2 = apply(vars,t2,subst)
 end
 subst
end

"""
unify is a main interface for unification
"""

function loopcheck_sigma(vars::Vlist, subst::Tlist)
  for ix in 1:length(vars)
    if typeof(subst[ix]) != Symbol
      loopcheck(vars[ix], subst[ix])
    end
  end
  return false
end

function fp_subst(vars::Vlist, subst::Tlist)
#@show vars, subst
## make a fixed point of sigma(ss)
 sb = subst
 sa = apply(vars, subst, subst)
 while sb != sa
   loopcheck_sigma(vars, sa)
   sb, sa = sa, apply(vars, sa, sa)
 end
 return sa
end

function fp_subst2(vars::Vlist, subst::Tlist)
## make a fixed point of sigma(ss)
 sb = subst
 sa = apply(vars, subst, subst)
 return sa
end

function unify(vars::Vlist, t1::Number, t2::Number)
#@show :unifynn,t1,t2
  if t1 != t2; throw(ICMP(t1,t2,:unify1nn))end
  vars
end

function unify(vars::Vlist, t1::Number, t2::Symbol)
#@show :unifyns,t1,t2
  if t1 == t2; return vars end
  unify1(vars, t1, t2, vars)
end

function unify(vars::Vlist, t1::Symbol, t2::Number)
#@show :unifysn,t1,t2
  if t1 == t2; return vars end
  unify1(vars, t1, t2, vars)
end

function unify(vars::Vlist, t1::Symbol, t2::Symbol)
#@show :unifyss,t1,t2
  if t1 == t2; return vars end
  unify1(vars, t1, t2, deepcopy(vars))
end

function unify(vars::Vlist, t1::Number, t2::Expr)
#@show :unifyne,t1,t2
  unify1(vars, t1, t2, vars)
end

function unify(vars::Vlist, t1::Symbol, t2::Expr)
#@show :unifyse,t1,t2
  unify1(vars, t1, t2, vars)
end

function unify(vars::Vlist, t1::Expr, t2::Number)
#@show :unifyen,t1,t2
  unify1(vars, t1, t2, vars)
end

function unify(vars::Vlist, t1::Expr, t2::Symbol)
#@show :unifyes,t1,t2
  unify1(vars, t1, t2, vars)
end

function unify(vars::Vlist, t1::Expr, t2::Expr)
#@show :unifyee,t1,t2
 ss = unify1(vars, t1, t2, vars)
#@show vars, ss
 fs = fp_subst(vars, ss)
 return fs
end

max_stars_repo_name: sazare/cheapViews

max_issues_repo_name: sazare/cheapViews

max_forks_repo_name: sazare/cheapViews


text:
####################################################################
#######                     MUFFIN                           #######
####### Multi-Frequency Sparse Radio Interferometric imaging #######
####################################################################

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

# psfst, skyst, algost, admmst, toolst = muffin(nitermax = 30);

# demo = string(Pkg.dir("Muffin"),"/src/muffindemo.jl")

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

module Muffin
    using FITSIO
    using Images
    using Wavelets
    using GHF

    export muffin,savedata

    include("muffintype.jl")

    #export admmst

    include("muffinfunc.jl")
    include("muffinload.jl")
    include("savedata.jl")

end

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

# Pkg.clone("https://github.com/andferrari/GHF.jl.git")
# Pkg.add("PyPlot")
# Pkg.add("FITSIO")
# Pkg.add("Images")
# Pkg.add("Wavelets")
# Pkg.add("HDF5")

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


text:
using Test
using GreyDecision

# Testing Core Library
@info "Testing Grey Numbers and their operations"
include("./testgreynumber.jl")

@info "Testing Stats"
include("./teststats.jl")

@info "Testing utility functions"
include("./testutility.jl")

@info "Testing Random module"
include("./testrandom.jl")

@info "Linear Algebra operations"
include("./testlinearalgebra.jl")

# Testing Grey Decision Methods
@info "Testing topsis"
include("./testtopsis.jl")

@info "Testing Vikor"
include("./testvikor.jl")

@info "Testing Saw"
include("./testsaw.jl")

@info "Testing NDS"
include("./testnds.jl")

@info "Testing Moora"
include("./testmoora.jl")

@info "Testing electre"
include("./testelectre.jl")

@info "Testing WPM"
include("./testwpm.jl")

@info "Testing Marcos"
include("./testmarcos.jl")

@info "Testing Aras"
include("./testaras.jl")


text:
"""
    calculate_center_of_mass(x, m)

Calculates the center of mass for given positions `x` and masses `m`.
"""
function calculate_center_of_mass(x, m)

    dt = typeof(m[1])
    com = zeros(dt, 3)

    for i = 1:length(m)
        com[1] += m[i] * x[i,1]
        com[2] += m[i] * x[i,2]
        com[3] += m[i] * x[i,3]
    end
    mtot = sum(m)

    com ./= mtot

    return com
end

max_stars_repo_name: LudwigBoess/GadJet

max_issues_repo_name: LudwigBoess/GadJet

max_forks_repo_name: LudwigBoess/GadJet


text:
module DZPolynomials

export ExponentVector, Polynomial, reduce!, dict_add!, dict_sub!

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

struct ExponentVector
    data::Vector{Int}
end

const EMPTY_EXPONENT_VECTOR = ExponentVector([])

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

import Base: length, isempty, getindex, ==, hash, isless, show

@inline length(v::ExponentVector)                    = length(v.data)
@inline isempty(v::ExponentVector)                   = isempty(v.data)
@inline getindex(v::ExponentVector, i::Int)          = getindex(v.data, i)
@inline ==(v::ExponentVector, w::ExponentVector)     = (v.data == w.data)
@inline hash(v::ExponentVector, h::UInt)             = hash(v.data, h)
@inline isless(v::ExponentVector, w::ExponentVector) = isless(v.data, w.data)

const VARIABLE_NAMES       = Ref{Vector{String}}(String[])
const UNICODE_SUBSCRIPTS   = Dict(map(Pair, "0123456789", "₀₁₂₃₄₅₆₇₈₉"))
const UNICODE_SUPERSCRIPTS = Dict(map(Pair, "0123456789", "⁰¹²³⁴⁵⁶⁷⁸⁹"))
subscript_string(n::Int)   = map(c -> UNICODE_SUBSCRIPTS[c]  , string(n))
superscript_string(n::Int) = map(c -> UNICODE_SUPERSCRIPTS[c], string(n))

function show(io::IO, v::ExponentVector)
    for (i, e) in enumerate(v.data)
        if i <= length(VARIABLE_NAMES[])
            var = VARIABLE_NAMES[][i]
        else
            var = "x" * subscript_string(i)
        end
        if e == 1
            write(io, var)
        elseif e > 1
            write(io, var, superscript_string(e))
        end
    end
end

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

import Base: +, -, lcm

function +(v::ExponentVector, w::ExponentVector)
    len_v = length(v)
    len_w = length(w)
    m, n = minmax(len_v, len_w)
    r = Vector{Int}(undef, n)
    @simd ivdep for i = 1 : m
        @inbounds r[i] = v[i] + w[i]
    end
    @simd ivdep for i = m + 1 : len_v
        @inbounds r[i] = v[i]
    end
    @simd ivdep for i = m + 1 : len_w
        @inbounds r[i] = w[i]
    end
    ExponentVector(r)
end

function -(v::ExponentVector, w::ExponentVector)
    len_v = length(v)
    len_w = length(w)
    if len_v < len_w
        error("invalid ExponentVector subtraction")
    elseif len_v == len_w
        n = 0
        for i = len_v : -1 : 1
            if v[i] == w[i]
                n += 1
            else
                break
            end
        end
        r = Vector{Int}(undef, len_v - n)
        @simd ivdep for i = 1 : len_v - n
            @inbounds r[i] = v[i] - w[i]
        end
        ExponentVector(r)
    else
        r = Vector{Int}(undef, len_v)
        @simd ivdep for i = 1 : len_w
            @inbounds r[i] = v[i] - w[i]
        end
        @simd ivdep for i = len_w + 1 : len_v
            @inbounds r[i] = v[i]
        end
        ExponentVector(r)
    end
end

function lcm(v::ExponentVector, w::ExponentVector)
    len_v = length(v)
    len_w = length(w)
    m, n = minmax(len_v, len_w)
    r = Vector{Int}(undef, n)
    @simd ivdep for i = 1 : m
        @inbounds r[i] = max(v[i], w[i])
    end
    @simd ivdep for i = m + 1 : len_v
        @inbounds r[i] = v[i]
    end
    @simd ivdep for i = m + 1 : len_w
        @inbounds r[i] = w[i]
    end
    ExponentVector(r)
end

function isdivisible(v::ExponentVector, w::ExponentVector)
    len_v = length(v)
    len_w = length(w)
    if len_v > len_w
        false
    else
        all(v[i] <= w[i] for i = 1 : len_v)
    end
end

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

struct Polynomial{R <: Real}
    data::Dict{ExponentVector,R}
end

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

import Base: zero, iszero, convert, show

@inline zero(::Type{Polynomial{R}}) where {R <: Real} =
    Polynomial{R}(Dict{ExponentVector,R}())

@inline iszero(p::Polynomial{R}) where {R <: Real} = iszero(length(p.data))

convert(::Type{Polynomial{R}}, x::Real) where {R <: Real} = Polynomial{R}(
    Dict{ExponentVector,R}(EMPTY_EXPONENT_VECTOR => convert(R, x)))

function show(io::IO, p::Polynomial{R}) where {R <: Real}
    data = [(k, v) for (k, v) in p.data]
    sort!(data, rev=true)
    if isempty(data)
        write(io, '0')
    end
    for (i, (k, v)) in enumerate(data)
        if (i == 1) && signbit(v)
            write(io, '-')
        elseif i > 1
            if signbit(v)
                write(io, " - ")
            else
                write(io, " + ")
            end
        end
        v = abs(v)
        if isempty(k) || !isone(v)
            # if isone(denominator(v))
                show(io, v)
            # else
            #     show(io, numerator(v))
            #     write(io, '/')
            #     show(io, denominator(v))
            #     if !isempty(k)
            #         #write(io, ' ')
            #     end
            # end
        end
        show(io, k)
    end
end

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

import Base: +, -, *, ^, %

function dict_add!(dict::Dict{K,V}, key::K, val::W) where {K, V, W}
    if haskey(dict, key)
        prev = dict[key]
        new = prev + val
        if iszero(new)
            delete!(dict, key)
        else
            dict[key] = new
        end
    else
        dict[key] = val
    end
end

function dict_sub!(dict::Dict{K,V}, key::K, val::W) where {K, V, W}
    if haskey(dict, key)
        prev = dict[key]
        new = prev - val
        if iszero(new)
            delete!(dict, key)
        else
            dict[key] = new
        end
    else
        dict[key] = -val
    end
end

function +(p::Polynomial{R}) where {R <: Real}
    r = Dict{ExponentVector,R}()
    for (k, v) in p.data
        r[k] = +v
    end
    Polynomial{R}(r)
end

function -(p::Polynomial{R}) where {R <: Real}
    r = Dict{ExponentVector,R}()
    for (k, v) in p.data
        r[k] = -v
    end
    Polynomial{R}(r)
end

function +(p::Polynomial{R}, q::Polynomial{R}) where {R <: Real}
    r = Dict{ExponentVector,R}()
    for (k, v) in p.data
        dict_add!(r, k, v)
    end
    for (k, v) in q.data
        dict_add!(r, k, v)
    end
    Polynomial{R}(r)
end

function +(p::Polynomial{R}, c::T) where {R <: Real, T <: Real}
    r = Dict{ExponentVector,R}()
    if !iszero(c)
        r[EMPTY_EXPONENT_VECTOR] = convert(R, c)
    end
    for (k, v) in p.data
        dict_add!(r, k, v)
    end
    Polynomial{R}(r)
end

@inline +(c::T, p::Polynomial{R}) where {R <: Real, T <: Real} = p + c

function -(p::Polynomial{R}, q::Polynomial{R}) where {R <: Real}
    r = Dict{ExponentVector,R}()
    for (k, v) in p.data
        dict_add!(r, k, v)
    end
    for (k, v) in q.data
        dict_sub!(r, k, v)
    end
    Polynomial{R}(r)
end

function -(p::Polynomial{R}, c::T) where {R <: Real, T <: Real}
    r = Dict{ExponentVector,R}()
    if !iszero(c)
        r[EMPTY_EXPONENT_VECTOR] = convert(R, -c)
    end
    for (k, v) in p.data
        dict_add!(r, k, v)
    end
    Polynomial{R}(r)
end

function -(c::T, p::Polynomial{R}) where {R <: Real, T <: Real}
    r = Dict{ExponentVector,R}()
    if !iszero(c)
        r[EMPTY_EXPONENT_VECTOR] = convert(R, c)
    end
    for (k, v) in p.data
        dict_sub!(r, k, v)
    end
    Polynomial{R}(r)
end

function *(p::Polynomial{R}, q::Polynomial{R}) where {R <: Real}
    r = Dict{ExponentVector,R}()
    for (kp, vp) in p.data
        for (kq, vq) in q.data
            dict_add!(r, kp + kq, vp * vq)
        end
    end
    Polynomial{R}(r)
end

function *(p::Polynomial{R}, c::T) where {R <: Real, T <: Real}
    r = Dict{ExponentVector,R}()
    if !iszero(c)
        for (kp, vp) in p.data
            r[kp] = vp * c
        end
    end
    Polynomial{R}(r)
end

@inline *(c::T, p::Polynomial{R}) where {R <: Real, T <: Real} = p * c

function ^(p::Polynomial{R}, n::Int) where {R <: Real}
    if n < 0
        error("cannot raise Polynomial to negative power")
    elseif n == 0
        convert(Polynomial{R}, 1)
    elseif n == 1
        p
    elseif n % 2 == 0
        q = p^div(n, 2)
        q * q
    else
        q = p^div(n, 2)
        q * q * p
    end
end

function reduce!(p::Polynomial{R}, g::Vector{Polynomial{R}}) where {R <: Real}
    result = Tuple{ExponentVector,R}[]
    ltg = [maximum(h.data) for h in g]
    while !iszero(p)
        moved = false
        ltp, lcp = maximum(p.data)
        for (h, (lth, lch)) in zip(g, ltg)
            if isdivisible(lth, ltp)
                t = ltp - lth
                c = lcp / lch
                for (k, v) in h.data
                    dict_sub!(p.data, k + t, v * c)
                end
                moved = true
                break
            end
        end
        if !moved
            push!(result, (ltp, lcp))
            delete!(p.data, ltp)
        end
    end
    for (k, v) in result
        p.data[k] = v
    end
end

end # module DZPolynomials


text:
using   ColorTypes,
        CoordinateTransformations,
        DSP,
        FixedPointNumbers,
        IdentityRanges,
        ImageCore,
        ImageFiltering,
        ImageInTerminal,
        ImageTransformations,
        Interpolations,
        MappedArrays,
        MLDataPattern,
        OffsetArrays,
        Random,
        SparseArrays,
        StaticArrays,
        Statistics

# extras
using TestImages, ReferenceTests, Test

# removed
# ComputationalResources

# check for ambiguities
refambs = detect_ambiguities(ImageTransformations, Base, Core)
using Augmentor
ambs = detect_ambiguities(Augmentor, ImageTransformations, Base, Core)
# The 3 is from plain_axes with a Tuple{} (so its spurious)
#@test Set(setdiff(ambs, refambs)) == Set{Tuple{Method,Method}}()
@test length(setdiff(ambs, refambs)) == 3

str_show(obj) = @io2str show(::IO, obj)
str_showcompact(obj) = @io2str show(IOContext(::IO, :compact=>true), obj)
str_showconst(obj) = @io2str Augmentor.showconstruction(::IO, obj)

camera = testimage("cameraman")
cameras = similar(camera, size(camera)..., 2)
copyto!(view(cameras,:,:,1), camera)
copyto!(view(cameras,:,:,2), camera)
square = Gray{N0f8}[0.1 0.2 0.3; 0.4 0.5 0.6; 0.7 0.6 0.9]
square2 = rand(Gray{N0f8}, 4, 4)
rect = Gray{N0f8}[0.1 0.2 0.3; 0.4 0.5 0.6]
checkers = Gray{N0f8}[1 0 1 0 1; 0 1 0 1 0; 1 0 1 0 1]
rgb_rect = rand(RGB{N0f8}, 2, 3)

#################
# to be removed
# cd(joinpath(dirname(pathof(Augmentor)), "..", "test"))
#################
##
tests = [
    "tst_utils.jl",
    "operations/tst_channels.jl",
    "operations/tst_dims.jl",
    "operations/tst_convert.jl",
    "operations/tst_mapfun.jl",
    "operations/tst_noop.jl",
    "operations/tst_cache.jl",
    "operations/tst_rotation.jl",
    "operations/tst_shear.jl",
    "operations/tst_flip.jl",
    "operations/tst_crop.jl",
    "operations/tst_resize.jl",
    "operations/tst_scale.jl",
    "operations/tst_zoom.jl",
    "operations/tst_distortions.jl",
    "operations/tst_either.jl", # Bugs left
    "tst_operations.jl",
    "tst_pipeline.jl",
    "tst_augment.jl",
    "tst_augmentbatch.jl",
    "tst_distortedview.jl",
]

@testset "Augmentor" begin
    @info "Testing Augmentor"

    for t in tests
        @testset "$t" begin
            include(t)
        end
    end
end


text:
abstract Instrument

type GenericInstrument <: Instrument
	handle::ViObject
	connected::Bool
	bufSize::UInt32
end
GenericInstrument() = GenericInstrument(0, false, 1024)

function connect!(instr::Instrument, address::AbstractString)
	if !instr.connected
		instr.handle = viOpen(rm, address)
		instr.connected = true
	end
end

function disconnect!(instr::Instrument)
	if instr.connected
		viClose(instr.handle)
		instr.connected = false
	end
end

#String reads and writes
check_connected(instr::Instrument) = @assert instr.connected "Instrument is not connected!"

macro check_connected(ex)
	funcproto = ex.args[1]
	body = ex.args[2]
	instrument_obj = funcproto.args[2]
	checkbody = quote
		check_connected($(instrument_obj))
		$body
	end
	return Expr(:function, esc(funcproto), esc(checkbody))
end

@check_connected write(instr::Instrument, msg::ASCIIString) = viWrite(instr.handle, msg)

@check_connected read(instr::Instrument) = rstrip(bytestring(viRead(instr.handle; bufSize=instr.bufSize)), ['\r', '\n'])

@check_connected readavailable(instr::Instrument) = readavailable(instr.handle)

function query(instr::Instrument, msg::ASCIIString; delay::Real=0)
	write(instr, msg)
	sleep(delay)
	read(instr)
end


text:
using Flux, XConv, BSON, IterTools
using Flux: onecold, logitcrossentropy, @epochs
using CUDA
using Parameters: @with_kw
using ProgressMeter

datasets = ["MNIST", "CIFAR10"]
name = length(ARGS) > 0 ? (ARGS[1] in datasets ? ARGS[1] : "MNIST") : "MNIST"
@show name

CUDA.unsafe_free!(h::Flux.OneHotMatrix) = CUDA.unsafe_free!(h.data)

cd(dirname(@__FILE__))

if CUDA.has_cuda()
    device = gpu
    CUDA.allowscalar(false)
    iterator = CuIterator
    @info "Training on GPU"
else
    iterator = ()
    device = cpu
    @info "Training on CPU"
end

include("./datautils.jl")
include("./modelutils.jl")

@with_kw mutable struct Args
    name::String = "MNIST"
    batchsize::Int = 128
    η::Float64 = 3e-3
    η_fact::Float64 = .9
    progress_fact::Float64 = .001
    epochs::Int = 20
    splitr_::Float64 = 0.1
    probe_size::Int = 8
    mode::String = "TrueGrad"
    savepath::String = "./$(name)_bench"
end

function accuracy(test_data, m)
    correct, total = 0, 0
    for (x, y) in iterator(test_data)
        correct += sum(onecold(cpu(m(x)), 0:9) .== onecold(cpu(y), 0:9))
        total += size(y, 2)
    end
    test_accuracy = correct / total
    test_accuracy
end

augment(x) = x .+ device(0.1f0*randn(eltype(x), size(x)))
filename(args) = joinpath(args.savepath, "$(args.name)_conv_$(args.mode)_$(args.batchsize)_$(args.probe_size).bson")

function check(fname)
    isfile(fname) ? (BSON.@load fname acc) : (return false)
    acc < .1 ? rm(fname) : (return true)
    false
end

function train(; kws...)
    # Initialize the hyperparameters
    args = Args(; kws...)
    check(filename(args)) && return

    # Load the train, validation data
    train_data, val_data = get_train_data(args)
    test_data = get_test_data(args)

    @info("Constructing Model")
    # Defining the loss and accuracy functions
    m = build_model(args.name) |> device
    loss(x, y) = logitcrossentropy(m(x), y)

    @info("Training $(args.name) with batch size $(args.batchsize)")
    lhist = []

    # Defining the optimizer
    opt = ADAM(args.η)
    ps = Flux.params(m)

    # Initialize gradient mode
    XConv.initXConv(args.probe_size, args.mode)
    # Starting to train models
    p = Progress(length(train_data) * args.epochs)
    best = 0
    for epoch in 1:args.epochs
        Base.flush(Base.stdout)
        local l, acc
	acc = accuracy(val_data, m)
	n = length(train_data)
        for (x, y) in iterator(train_data)
            gs = Flux.gradient(ps) do
                l = loss(x, y)
                l
            end
            Flux.update!(opt, ps, gs)
            push!(lhist, l)
	    ProgressMeter.next!(p; showvalues = [(:loss, l), (:epoch, epoch), (:Mode, args.mode), (:ps, args.probe_size), (:η, args.η), (:accuracy, acc)])
	end

        validation_loss = 0f0
        for (x, y) in iterator(val_data)
            validation_loss += loss(x, y)
        end
        validation_loss /= length(val_data)
        acc_loc = accuracy(val_data, m)
	(acc_loc/acc - 1) < args.progress_fact && (args.η *= args.η_fact)
        @info "Epoch $epoch validation with $(XConv._params) loss = $(validation_loss), accuracy = $(acc_loc)"
    end
    acc = accuracy(test_data, m)
    BSON.@save filename(args) params=cpu.(params(m)) acc lhist
    GC.gc()
end

b_sizes = [2^i for i=5:11]
ps_sizes = [0..., [2^i for i=1:7]...]

for d in datasets
    for b in b_sizes
        for ps in ps_sizes
	    η = d == "CIFAR10" ? 3e-4 : 3e-3
            train(;η=η, epochs=10+2*log2(b),batchsize=b, probe_size=ps, name=d, mode= ps>0 ? "EVGrad" : "TrueGrad")
        end
    end
end

#for lr in Float32.((.1:.1:10)*1e-3)
#    train(;η=lr, epochs=10,batchsize=128, probe_size=8, name=name, mode="EVGrad", savepath="./MNIST_lr")
#end

max_stars_repo_name: sheevy/XConv

max_issues_repo_name: sheevy/XConv

max_forks_repo_name: sheevy/XConv


text:
# test new core
using Test

#include("newcore.jl")
#include("utils.jl")

@testset "stringtoclause" begin
 sc = stringtoclause(:C10, Meta.parse("[x].[-P(x),+Q(x,f(x))]"))
 @test sc.cid  == :C10
 @test sc.vars ==  [:x_C10]
 @test sc.body ==  [Meta.parse("-P(x_C10)"), Meta.parse("+Q(x_C10,f(x_C10))")]

end

@testset "id and etc" begin
 @test cidof(123) == :C123
 @test lidof(3339) == :L3339
 @test ridof(233) == :R233

 @test origof(:xy_C12) == :xy
 @test origof(:xy_C12_JJ) == :xy
 @test origof(:xy) == :xy

 @test origtermof(Meta.parse("xy_C12")) == :xy
 @test origtermof(Meta.parse("xy")) == :xy
 @test origtermof(Meta.parse("f(xy_C12,x)")) == Meta.parse("f(xy, x)")
 @test origtermof(Meta.parse("f(g(xy_C12,y),h(u_C12R22),g(x))")) == Meta.parse("f(g(xy,y),h(u),g(x))")

 @test numof(:C123) == 123
 @test numof(:L22) == 22
 @test numof(:R2333) == 2333

 ctest = CORE("test", 0,[0],0,0,0,0,0,0,0,[],[0],[0])
 @test ctest.name == "test"
 @test newrid(ctest) == :R1
 @test newrid(ctest) == :R2
 @test newrid(ctest) == :R3

 @test isrid(:R23_C22)
 @test !isrid(:C23_C22)
 @test !isrid(:L23_C22)
 @test iscid(:C23_C22)
 @test !iscid(:R23_C22)
 @test !iscid(:L23_C22)
 @test !islid(:R23_C22)
 @test !islid(:C23_C22)
 @test islid(:L23_C22)
end

@testset "analyze core" begin
 @test analyze_term([], Meta.parse("a")) == ([], [:a], [])
 @test analyze_term([:a], Meta.parse("a")) == ([:a], [], [])
 @test analyze_term([], Meta.parse("a()")) == ([], [], [:a])
 @test analyze_term([], Meta.parse("a(b)")) == ([], [:b], [:a])
 @test analyze_term([], Meta.parse("a(b,c)")) == ([], [:b,:c], [:a])
 @test analyze_term([:c], Meta.parse("a(b,c)")) == ([:c], [:b], [:a])
 @test analyze_term([], Meta.parse("a(b())")) == ([], [], [:a,:b])
 @test analyze_term([], Meta.parse("a(b(c))")) == ([], [:c], [:a,:b])
 @test analyze_term([:d,:g], Meta.parse("a(b(c),d,e(f,g))")) == ([:d,:g], [:c,:f], [:a,:b,:e])

 @test analyze_term([:x,:y,:z], Meta.parse("+P(x,c,f(x,c))").args[2]) == ([:x,:x], [:c,:c], [:P,:f])

 @test analyze_lit([:x,:y,:z], Meta.parse("+P(x,c,f(x,c))").args[2]) == ([:x,:x], [:c,:c], [:f],:P)

 cnf = "[x].[+P(x,f(x))]
[x].[-P(x,f(h(x)))]
[x,y,z].[+P(h(y),pi, f(k(x))),-Q(e,g(x,y))]"
 ccnf = readcore(IOBuffer(cnf))

asm = analyze_sym(ccnf)

 @test asm.vsyms == Set(Any[:y_C3, :x_C3, :x_C1, :x_C2])
 @test asm.csyms == Set(Any[:e, :pi])
 @test asm.fsyms == Set(Any[:f,:k,:h,:g])
 @test asm.psyms == Set(Any[:P,:Q])
end

@testset "core proc" begin
 evalproc(["x=12"])
 @test x==12

end


text:
"""
    Genser.Encoding{encoding}

Encoding for binary values when converted to and from string values.
"""
struct Encoding{encoding} end

"""
    Genser.Encoding(encoding)

Construct an encoding.
"""
Encoding(encoding) = Encoding{Symbol(encoding)}()

show(io::IO, ::Encoding{encoding}) where {encoding} = print(io, "Genser.Encoding(", string(encoding), ")")
print(io::IO, ::Encoding{encoding}) where {encoding} = print(io, encoding)

function genser_converter_for_encoding end

function fieldencoding(a, b) Encoding{:none} end

module Base64Converter
    using Base64
    using Genser

    base64encoding = Genser.Encoding("base64")
    Base64Encoding = typeof(base64encoding)

    function decode(str::AbstractString)
        base64decode(str)
    end

    function encode(buff::Vector{UInt8})
        base64encode(buff)
    end

    Genser.genser_converter_for_encoding(::Type{Base64Encoding}) = Base64Converter
end

module HexConverter
    using Genser

    hexencoding = Genser.Encoding("hex")
    HexEncoding = typeof(hexencoding)

    function decode(str::AbstractString)
        length(str) % 2 == 0 || throw(ArgumentError("malformed hex sequence"))

        bytes = Vector{UInt8}()
        for i = 1:2:length(str)
            push!(bytes, parse(UInt8, str[i:i+1], base=16))
        end

        bytes
    end

    function encode(buff::Vector{UInt8})
        strs = map(buff) do byte
            string(byte, base=16, pad = 2)
        end

        join(strs)
    end

    Genser.genser_converter_for_encoding(::Type{HexEncoding}) = HexConverter
end


text:
__precompile__()

module MappingRobots

using Ev3dev
using Base.Dates
using StateMachineIterators
using AffineTransforms

import Base: start, next, done, +

export run_mapping,
       Sides,
       Map,
       Robot,
       Brick

type Sides{T}
    right::T
    left::T
end

start(sides::Sides) = :right
next(sides::Sides, state::Symbol) = (state == :right) ? (sides.right, :left) : (sides.left, :done)
done(sides::Sides, state::Symbol) = (state == :done)

type Odometer
    motor::Ev3dev.Device
    ticks_per_revolution
    meters_per_tick
    last_position
    total_distance
end

function Odometer(motor::Ev3dev.Device, meters_per_revolution::Real)
    ticks_per_revolution = motor.io.count_per_rot()
    meters_per_tick = meters_per_revolution / ticks_per_revolution
    current_position = motor.io.position()
    Odometer(motor, ticks_per_revolution, meters_per_tick, current_position, 0.0)
end

function update!(odo::Odometer)
    current_position = odo.motor.io.position()
    delta = current_position - odo.last_position
    odo.last_position = current_position
    new_distance = delta * odo.meters_per_tick
    odo.total_distance += new_distance
    odo.total_distance
end

type State
    pose::AffineTransform
    last_wheel_distances::Sides
    last_orientation::Number
end

type SensorData
    gyro::Number
    ultrasound::Number
    total_wheel_distances::Sides
    head_angle::Number

    SensorData() = new()
end

type MappingSensors
    gyro::GyroSensor
    ultrasound::UltrasoundSensor
    odos::Sides{Odometer}
end

type RobotConfig
    brick::Brick
    meters_per_revolution::Number
    motor_port_names::Sides
    distance_between_wheels::Number
    T_origin_to_ultrasound::AffineTransform
end

type Robot
    config::RobotConfig
    motors::Sides{LargeMotor}
    head::MediumMotor
    sensors::MappingSensors
end

function Robot(config::RobotConfig)
    motors = Sides(find_device_at_address(LargeMotor, config.brick, config.motor_port_names.right),
                   find_device_at_address(LargeMotor, config.brick, config.motor_port_names.left))
    head = find_devices(MediumMotor, config.brick)[1]
    odos = Sides(Odometer(motors.right, config.meters_per_revolution), Odometer(motors.left, config.meters_per_revolution))
    gyro = find_devices(GyroSensor, config.brick)[1]
    ultrasound = find_devices(UltrasoundSensor, config.brick)[1]
    sensors = MappingSensors(gyro, ultrasound, odos)
    Robot(config, motors, head, sensors)
end

type BehaviorInputs
    robot::Robot
    time::TimePeriod
    state::State
    sensor_data::SensorData
end

function update_sensors!(inputs::BehaviorInputs)
    inputs.sensor_data.gyro = -scaled_values(inputs.robot.sensors.gyro)[1] * pi / 180
    inputs.sensor_data.ultrasound = scaled_values(inputs.robot.sensors.ultrasound)[1] / 100
    inputs.sensor_data.total_wheel_distances = Sides(map(update!, inputs.robot.sensors.odos)...)
    inputs.sensor_data.head_angle = -inputs.robot.head.io.position() * 12 / 36 * pi / 180
end

function update_state!(inputs::BehaviorInputs)
    angle_change = inputs.sensor_data.gyro - inputs.state.last_orientation
    wheel_distances = [getfield(inputs.sensor_data.total_wheel_distances, field) - getfield(inputs.state.last_wheel_distances, field) for field in [:right, :left]]
    inputs.state.pose *= tformrigid([angle_change, mean(wheel_distances), 0])
    inputs.state.last_wheel_distances = inputs.sensor_data.total_wheel_distances
    inputs.state.last_orientation = inputs.sensor_data.gyro
end

type Map
    points::Vector{Tuple{Real, Real}}
    path::Vector{AffineTransform}
end

Map() = Map(Tuple{Real,Real}[], AffineTransform[])

function prep!(robot::Robot)
    robot.head.io.speed_sp(130)
    map(stop, robot.motors)
    stop(robot.head)
	map(m -> m.io.position(0), robot.motors)
end

function shutdown!(robot::Robot)
    map(stop, robot.motors)
    stop(robot.head)
end

include("mapping_behaviors.jl")

function run_mapping(robot::Robot; timeout=Second(30), initial_pose=tformeye(2))
    machines = mapping_state_machines(timeout)

    state = State(initial_pose,
                  Sides(0.0, 0.0),
                  -scaled_values(robot.sensors.gyro)[1] * pi / 180)
    start_time = unix2datetime(time())

    behavior_inputs = BehaviorInputs(robot, Millisecond(0), state, SensorData())
    prep!(robot)
    update_sensors!(behavior_inputs)
    update_state!(behavior_inputs)
    local_map = Map()

    iters = [StateMachineIterator(machine, () -> behavior_inputs) for machine in machines]
    try
        for behaviors in zip(iters...)
            behavior_inputs.time = unix2datetime(time()) - start_time
            update_sensors!(behavior_inputs)
            update_state!(behavior_inputs)
            if behavior_inputs.sensor_data.ultrasound < 2
                new_map_point = behavior_inputs.state.pose * robot.config.T_origin_to_ultrasound * tformrotate(behavior_inputs.sensor_data.head_angle) * tformtranslate([behavior_inputs.sensor_data.ultrasound, 0])
                push!(local_map.points, (new_map_point.offset...))
            end
            push!(local_map.path, behavior_inputs.state.pose)
            for behavior in behaviors
                mapping_behaviors[behavior](behavior_inputs)
            end
        end
    finally
        shutdown!(robot)
    end
    local_map
end

function Robot(brick::Brick)
    meters_per_revolution = 37.2 * 2.54 / 100 / 5 # 37.2 inches in 5 revolutions
    motor_ports = Sides("outD", "outB")
    distance_between_wheels = 4.5
    T_origin_to_ultrasound = tformtranslate(0.0254 * [2.0, 0.0])
    Robot(RobotConfig(brick,
                      meters_per_revolution,
                      motor_ports,
                      distance_between_wheels,
                      T_origin_to_ultrasound))
end

end


text:
using Potree
using Visualization
using BenchmarkTools
using Profile
using DataStructures

# potree source folder
potreeBin = "C:/Users/Alessio/.julia/dev/Potree/potree/stairsBIN(v1.7)" # replace this path with local potree directory
potreeLas = "C:/Users/Alessio/.julia/dev/Potree/potree/stairsLAS(v1.7)" # replace this path with local potree directory

# potree source folder
println("bin loading...")
Vtot = Potree.bin2pointcloud(potreeBin)
println("las loading...")
Vtot2 = Potree.source2pc(potreeLas, -1)

println("las new loading...")
Vtot3 = Potree.bin2pointcloudNEW(potreeBin)

println("Same number of points?")
println(size(Vtot)==size(Vtot2.coordinates))
println(size(Vtot)==size(Vtot3.coordinates))
 GL.VIEW(
      [
      Visualization.points(Vtot)
      ]
  )

  GL.VIEW(
    [
    Visualization.points(Vtot2.coordinates)
    ]
)
GL.VIEW(
  [
  Visualization.points(Vtot3.coordinates)
  ]
)


text:
using TwiliteTimeline
using Test

@testset "Test for collector.jl" begin
    @testset "Validate Types" begin
        err = try ResourceParams("realDonaldTrump", count=-1) catch ex; ex; end
        @test err isa Exception
        err = try ResourceParams("realDonaldTrump", count=0) catch ex; ex; end
        @test err isa Exception
        test_param = ResourceParams("realDonaldTrump", trim_user=true)
        @test test_param isa ResourceParams
    end

    @testset "Test for params_to_dict" begin
        expected = Dict("include_rts" => 1,"count" => 100,"trim_user" => "true","screen_name" => "realDonaldTrump","exclude_replies" => "true")
        params = ResourceParams("realDonaldTrump", count=100, trim_user=true)
        params_dict = TwiliteTimeline.params_to_dict(params)
        @test params_dict == expected
    end
    # @testset "Test for collect_tweets" begin
    #     creds = Authentictor(ENV["CKEY"], ENV["CSEC"], ENV["OTOK"], ENV["OSEC"]);
    #     params = ResourceParams("rustlang", count=2);
    #     tweets = collect_tweets(creds, params)
    #     @test length(tweets) > 0
    # end
end

@testset "Test for parameters.jl" begin
    @testset "Validate Type ParamsPostTweet" begin
        expected = Dict("status" => "asdf asdf asdf.", "auto_populate_reply_metadata" => "false", "fail_dmcommands" => "true", "enable_dmcommands" => "false", "trim_user" => "false", "possibly_sensitive" => "false")
        params =  ParamsPostTweet("asdf asdf asdf.")
        params_dict = TwiliteTimeline.params_to_dict(params)
        @test params_dict == expected
    end

    @testset "Validate Type ParamsGetTweets" begin
        expected = Dict("include_rts" => 1,"count" => 100,"trim_user" => "true","screen_name" => "realDonaldTrump","exclude_replies" => "true")
        params = ParamsGetTweets("realDonaldTrump", count=100, trim_user=true)
        params_dict = TwiliteTimeline.params_to_dict(params)
        @test params_dict == expected
    end
end

# @testset "Test for Caller Functions" begin
#     @testset "Test for get_tweets" begin
#         creds = Authentictor(ENV["CKEY"], ENV["CSEC"], ENV["OTOK"], ENV["OSEC"]);
#         params = ParamsGetTweets("rustlang", count=2);
#         tweets = get_tweets(creds, params);
#         @test length(tweets) > 0
#     end
#
#     @testset "Test for post_tweet" begin
#         creds = Authentictor(ENV["CKEY"], ENV["CSEC"], ENV["OTOK"], ENV["OSEC"]);
#         params = ParamsPostTweet("... asdf asdf test tweet using TwiliteTimeline.jl");
#         tweet = post_tweet(creds, params);
#         @test strip(tweet["text"]) == strip(params.status)
#     end
# end


text:
module Exchequer

using CSV
using ColorSchemes
using DataFrames
using Dates
using Plots
using Query

export move_downloads
export load_expenses, load_incomes, load_fxs
export exchange!
export aggregate
export plot_categories, plot_monthly, plot_weekly

COLORS = colorschemes[:Paired_12][1:end]
MONTHS = Dict(1=>"J", 2=>"F", 3=>"M", 4=>"A", 5=>"M", 6=>"J",
             7=>"J", 8=>"A", 9=>"S", 10=>"O", 11=>"N", 12=>"D")

include("preprocessing.jl")
include("aggregation.jl")
include("plotting.jl")

end

max_stars_repo_name: mzgubic/exchequer

max_issues_repo_name: mzgubic/exchequer

max_forks_repo_name: mzgubic/exchequer


text:
function testIntervals(A,V,W)
    #const n = size(A,1);
    n = size(A,1);

    roots = map( x ->
                 endPoints(A,V,x)[1],
                 [15; 25; 35; 45])          |>
                     Base.Iterators.flatten |>
                     collect                |>
                     sort

    intvls = Base.Iterators.product( roots, roots) |> collect |> vec

    # post-process intervals
    intvls = filter(intvls) do  x
        count = sum(x[1] .<= W .<= x[2])
        return n*0.05 <= count <= n*0.2
    end

    intvls = map(intvls) do x
        count = sum(x[1] .<= W .<= x[2])
        return (x...,count)
    end
end

function testIntervals(B,V)

    W = eigen(Matrix(B)).values
    c = (W[1] + W[end]) / 2 ;
    d = (W[end] - W[1]) / 2 ;

    A = (B - I.*c) / d;
    W = (W .- c) / d;

    intvls = testIntervals(A,V,W)

return intvls,W

end


text:
@testset "Sin approximation" begin
    @testset "Int16 with quarter bits $i" for i in 3:7
        x = -1 << (3 + i):1 << (3 + i) # 4π
        y_approx = fpsin.(Int16.(x), Val(i))
        y = sin.(x / 1 << i * π / 2) .* 1 << i
        @test all(abs.(y_approx .- y) .< 2.0)
    end

    @testset "Int32 with quarter bits $i" for i in 8:14
        x = -1 << (3 + i):1 << (3 + i) # 4π
        y_approx = fpsin.(Int32.(x), Val(i))
        y = sin.(x / 1 << i * π / 2) .* 1 << i
        @test all(abs.(y_approx .- y) .< 2.5)
    end
end

@testset "Cos approximation" begin
    @testset "Int16 with quarter bits $i" for i in 3:7
        x = -1 << (3 + i):1 << (3 + i) # 4π
        y_approx = fpcos.(Int16.(x), Val(i))
        y = cos.(x / 1 << i * π / 2) .* 1 << i
        @test all(abs.(y_approx .- y) .< 2.0)
    end

    @testset "Int32 with quarter bits $i" for i in 8:14
        x = -1 << (3 + i):1 << (3 + i) # 4π
        y_approx = fpcos.(Int32.(x), Val(i))
        y = cos.(x / 1 << i * π / 2) .* 1 << i
        @test all(abs.(y_approx .- y) .< 2.5)
    end
end