text:
# This file is a part of ValueShapes.jl, licensed under the MIT License (MIT).

"""
    ValueAccessor{S<:AbstractValueShape}

A value accessor provides a means to access a value with a given shape
stored in a flat real-valued data vector with a given offset position.

Constructor:

    ValueAccessor{S}(shape::S, offset::Int)

The offset is relative to the first index of a flat data array, so if
the value is stored at the beginning of the array, the offset will be zero.

An `ValueAccessor` can be used to index into a given flat data array.

Example:

```julia
acc = ValueAccessor(ArrayShape{Real}(2,3), 2)
valshape(acc) == ArrayShape{Real,2}((2, 3))
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
data[acc] == [3 5 7; 4 6 8]
```

Note: Subtypes of [`AbstractValueShape`](@ref) should specialize
[`ValueShapes.vs_getindex`](@ref), [`ValueShapes.vs_unsafe_view`](@ref) and
[`ValueShapes.vs_setindex!`](@ref) for their `ValueAccessor{...}`.
Specializing `Base.getindex`, `Base.view`, `Base.unsafe_view` or
`Base.setindex!` directly may result in method ambiguities with custom array
tapes that specialize these functions in a very generic fashion.
"""
struct ValueAccessor{S<:AbstractValueShape}
    shape::S
    offset::Int
    len::Int

    ValueAccessor{S}(shape::S, offset::Int) where {S<:AbstractValueShape} =
        new{S}(shape, offset, totalndof(shape))
end

export ValueAccessor

ValueAccessor(shape::S, offset::Int) where {S<:AbstractValueShape} = ValueAccessor{S}(shape, offset)

# Reserve broadcasting semantics for value accessors:
@inline Base.Broadcast.broadcastable(va::ValueAccessor) =
    throw(ArgumentError("broadcasting over `ValueAccessor`s is reserved"))

default_unshaped_eltype(va::ValueAccessor) = default_unshaped_eltype(va.shape)

Base.size(va::ValueAccessor) = size(va.shape)
Base.length(va::ValueAccessor) = length(va.shape)

# Can't use `idxs::Vararg{ValueAccessor,N}`, would cause ambiguities with
# Base for N == 0.
Base.to_indices(A::AbstractArray{T,1}, I::Tuple{ValueAccessor}) where {T<:Real} = I
Base.to_indices(A::AbstractArray{T,2}, I::Tuple{ValueAccessor,ValueAccessor}) where {T<:Real} = I
Base.to_indices(A::AbstractArray{T,3}, I::Tuple{ValueAccessor,ValueAccessor,ValueAccessor}) where {T<:Real} = I

Base.checkindex(::Type{Bool}, inds::AbstractUnitRange, i::ValueAccessor) =
    checkindex(Bool, inds, view_idxs(inds, i))

valshape(va::ValueAccessor) = va.shape

# Would this be useful?
# AbstractValueShape(va::ValueAccessor) = valshape(va)
# Base.convert(::Type{AbstractValueShape}, va::ValueAccessor) = AbstractValueShape(va)

function view_range end

@inline function view_range(idxs::AbstractUnitRange{<:Integer}, va::ValueAccessor)
    from = first(idxs) + va.offset
    to = from + va.len - 1
    from:to
end

function view_idxs end

@inline view_idxs(idxs::AbstractUnitRange{<:Integer}, va::ValueAccessor) = view_range(idxs, va)

"""
    ValueShapes.vs_getindex(data::AbstractArray{<:Real}, idxs::ValueAccessor...)

Specialize `ValueShapes.vs_getindex` instead of `Base.getindex` for
[`ValueShapes.ValueAccessor`](@ref)s, to avoid methods ambiguities with
with certain custom array types.
"""
function vs_getindex end

# Can't use `idxs::Vararg{ValueAccessor,N}`, would cause ambiguities with
# Base for N == 0.
Base.@propagate_inbounds Base._getindex(::IndexStyle, data::AbstractArray{<:Real,1}, idx1::ValueAccessor) =
    vs_getindex(data, idx1)
Base.@propagate_inbounds Base._getindex(::IndexStyle, data::AbstractArray{<:Real,2}, idx1::ValueAccessor, idx2::ValueAccessor) =
    vs_getindex(data, idx1, idx2)
Base.@propagate_inbounds Base._getindex(::IndexStyle, data::AbstractArray{<:Real,3}, idx1::ValueAccessor, idx2::ValueAccessor, idx3::ValueAccessor) =
    vs_getindex(data, idx1, idx2, idx3)

"""
    ValueShapes.vs_unsafe_view(data::AbstractArray{<:Real}, idxs::ValueAccessor...)

Specialize `ValueShapes.vs_unsafe_view` instead of `Base.view` or
`Base.unsafe_view` for [`ValueShapes.ValueAccessor`](@ref)s, to avoid methods
ambiguities with with certain custom array types.
"""
function vs_unsafe_view end

# Can't use `idxs::Vararg{ValueAccessor,N}`, would cause ambiguities with
# Base for N == 0.
Base.@propagate_inbounds Base.unsafe_view(data::AbstractArray{<:Real,1}, idx1::ValueAccessor) =
    vs_unsafe_view(data, idx1)
Base.@propagate_inbounds Base.unsafe_view(data::AbstractArray{<:Real,2}, idx1::ValueAccessor, idx2::ValueAccessor) =
    vs_unsafe_view(data, idx1, idx2)
Base.@propagate_inbounds Base.unsafe_view(data::AbstractArray{<:Real,3}, idx1::ValueAccessor, idx2::ValueAccessor, idx3::ValueAccessor) =
    vs_unsafe_view(data, idx1, idx2, idx3)

"""
    ValueShapes.vs_setindex!(data::AbstractArray{<:Real}, v, idxs::ValueAccessor...)

Specialize `ValueShapes.vs_setindex!` instead of `Base.setindex!` or for
[`ValueShapes.ValueAccessor`](@ref)s, to avoid methods ambiguities with with
certain custom array types.
"""
function vs_setindex! end

# Can't use `idxs::Vararg{ValueAccessor,N}`, would cause ambiguities with
# Base for N == 0.
Base.@propagate_inbounds Base._setindex!(::IndexStyle, data::AbstractArray{<:Real,1}, v, idx1::ValueAccessor) =
    vs_setindex!(data, v, idx1)
Base.@propagate_inbounds Base._setindex!(::IndexStyle, data::AbstractArray{<:Real,2}, v, idx1::ValueAccessor, idx2::ValueAccessor) =
    vs_setindex!(data, v, idx1, idx2)
Base.@propagate_inbounds Base._setindex!(::IndexStyle, data::AbstractArray{<:Real,3}, v, idx1::ValueAccessor, idx2::ValueAccessor, idx3::ValueAccessor) =
    vs_setindex!(data, v, idx1, idx2, idx3)


text:
# 'cstrt_regular_ngon' provides the vertices coordinates (a,b) of the
# regular small n-gon
function cstrt_regular_ngon(n)
if n >= 3
    a = zeros(n-1); b = zeros(n-1);
    if mod(n,2) == 1
        for i = 1:n-1
            a[i] = sin(2*pi*i/n)/(2*cos(pi/(2*n)));
            b[i] = (1 - cos(2*pi*i/n))/(2*cos(pi/(2*n)));
        end
    else
        for i = 1:n-1
            a[i] = sin(2*pi*i/n)/2;
            b[i] = (1 - cos(2*pi*i/n))/2;
        end
    end
    return(a,b)
end
end

ext: jl

max_stars_repo_name: cbingane/optigon

max_issues_repo_name: cbingane/optigon

max_forks_repo_name: cbingane/optigon


text:
#!/usr/bin/env julia

# This is an example invocation of `pull_docker_image()` to steal the `julia:alpine` image from Docker
using Sandbox, Pkg, Pkg.Artifacts, Scratch, ghr_jll, SHA

docker_image = "julia:alpine"

artifact_hash = create_artifact() do dir
    @info("Pulling $(docker_image)")
    Sandbox.pull_docker_image(docker_image, dir; verbose=true)
    @info("Hashing")
end

# Write out to a file
tarball_path = joinpath(@get_scratch!("archived"), "julia_alpine.tar.gz")
@info("Archiving out to $(tarball_path)")
archive_artifact(artifact_hash, tarball_path)

# Hash the tarball
@info("Hashing tarball")
tarball_hash = open(io -> bytes2hex(sha256(io)), tarball_path)

# Upload to `staticfloat/Sandbox.jl`, create a tag based on this docker image
docker_image_dash = replace(docker_image, ":" => "-")
tag_name = "$(docker_image_dash)-$(bytes2hex(artifact_hash.bytes[end-3:end]))"
@info("Uploading to staticfloat/Sandbox.jl@$(tag_name)")
run(`$(ghr_jll.ghr()) -replace $(tag_name) $(tarball_path)`)

# Bind it into `Artifacts.toml`
tarball_url = "https://github.com/staticfloat/Sandbox.jl/releases/download/$(tag_name)/$(basename(tarball_path))"
bind_artifact!(
    joinpath(dirname(@__DIR__), "Artifacts.toml"),
    "$(docker_image_dash)-rootfs",
    artifact_hash;
    download_info=[(tarball_url, tarball_hash)],
    lazy=true,
    force=true,
)


text:
using MLJBase
using TextAnalysis

@testset "basic use" begin
    # add some test docs
    docs = ["Hi my name is Sam.", "How are you today?"]

    # convert to ngrams
    ngram_vec = ngrams.(documents(Corpus(NGramDocument.(docs))))

    # train tfidf transformer
    tfidf_transformer = MLJText.TfidfTransformer()
    test_tfidf_machine = @test_logs machine(tfidf_transformer, ngram_vec)
    MLJBase.fit!(test_tfidf_machine)

    # train count transformer
    count_transformer = MLJText.CountTransformer()
    test_count_machine = @test_logs machine(count_transformer, ngram_vec)
    MLJBase.fit!(test_count_machine)

    # train bm25 transformer
    bm25_transformer = MLJText.BM25Transformer()
    test_bm25_machine = @test_logs machine(bm25_transformer, ngram_vec)
    MLJBase.fit!(test_bm25_machine)

    test_machines = [test_tfidf_machine, test_count_machine, test_bm25_machine]

    # test single doc
    test_doc1 = ngrams(NGramDocument("Another sentence ok"))
    for mach = test_machines
        test_doc_transform = transform(mach, [test_doc1])
        @test sum(test_doc_transform, dims=2)[1] == 0.0
        @test size(test_doc_transform) == (1, 11)
    end

    # test another single doc
    test_doc2 = ngrams(NGramDocument("Listen Sam, today is not the day."))
    for mach = test_machines
        test_doc_transform = transform(mach, [test_doc2])
        @test sum(test_doc_transform, dims=2)[1] > 0.0
        @test size(test_doc_transform) == (1, 11)
    end

    # test two docs
    test_doc3 = ngrams.(
        Corpus([NGramDocument("Another sentence ok"), NGramDocument("Listen Sam, today is not the day.")])
    )
    for mach = test_machines
        test_doc_transform = transform(mach, test_doc3)
        @test sum(test_doc_transform, dims=2)[1] == 0.0
        @test sum(test_doc_transform, dims=2)[2] > 0.0
        @test size(test_doc_transform) == (2, 11)
    end

    # test tokenized docs
    test_doc4 = [["Another", "sentence", "ok"], ["Listen", "Sam", ",", "today", "is", "not", "the", "day", "."]]
    for mach = test_machines
        test_doc_transform = transform(mach, test_doc4)
        @test sum(test_doc_transform, dims=2)[1] == 0.0
        @test sum(test_doc_transform, dims=2)[2] > 0.0
        @test size(test_doc_transform) == (2, 11)
    end

    # test proper fit:
    # here we are testing to make sure the size of the corpus to be
    # transformed does not alter the transformation that the model
    # is doing.
    for mach = test_machines
        single_doc_transform = transform(mach, [test_doc2])
        multiple_doc_transform = transform(mach, [test_doc2, test_doc2])
        @test single_doc_transform[1, :] == multiple_doc_transform[1, :]
    end
end

@testset "bag of words use" begin
    # test with bag of words
    bag_of_words = Dict(
        "cat in" => 1,
        "the hat" => 1,
        "the" => 2,
        "cat" => 1,
        "hat" => 1,
        "in the" => 1,
        "in" => 1,
        "the cat" => 1
    )
    bag = Dict(Tuple(String.(split(k))) => v for (k, v) in bag_of_words)

    # train tfidf transformer
    tfidf_transformer = MLJText.TfidfTransformer()
    test_tfidf_machine2 = @test_logs machine(tfidf_transformer, [bag])
    MLJBase.fit!(test_tfidf_machine2)

    # train count transformer
    count_transformer = MLJText.CountTransformer()
    test_count_machine2 = @test_logs machine(count_transformer, [bag])
    MLJBase.fit!(test_count_machine2)

    # train bm25 transformer
    bm25_transformer = MLJText.BM25Transformer()
    test_bm25_machine2 = @test_logs machine(bm25_transformer, [bag])
    MLJBase.fit!(test_bm25_machine2)

    test_doc5 = ["How about a cat in a hat"]
    for mach = [test_tfidf_machine2, test_count_machine2, test_bm25_machine2]
        test_doc_transform = transform(mach, test_doc5)
        @test sum(test_doc_transform, dims=2)[1] > 0.0
        @test size(test_doc_transform) == (1, 8)
    end
end

@testset "min max features use" begin
    # test min/max features
    docs = [
        "the BIL opens the door to new possibilities and should raise our collective expectations",
        "about what we can achieve in the near term.",
        "the following projects are not yet at a stage where they could be competitive",
        "for construction dollars over the next five years,",
        "but with some attention and preliminary work, our transportation leaders could turn",
        "these stretch projects into shovel-worthy ones."
    ]
    ngram_vec = ngrams.(documents(Corpus(NGramDocument.(docs))))

    # train tfidf transformer
    tfidf_transformer = MLJText.TfidfTransformer(max_doc_freq=0.8, min_doc_freq=0.2)
    test_tfidf_machine3 = @test_logs machine(tfidf_transformer, ngram_vec)
    MLJBase.fit!(test_tfidf_machine3)

    # train count transformer
    count_transformer = MLJText.CountTransformer(max_doc_freq=0.8)
    test_count_machine3 = @test_logs machine(count_transformer, ngram_vec)
    MLJBase.fit!(test_count_machine3)

    # train bm25 transformer
    bm25_transformer = MLJText.BM25Transformer(max_doc_freq=0.8, min_doc_freq=0.2)
    test_bm25_machine3 = @test_logs machine(bm25_transformer, ngram_vec)
    MLJBase.fit!(test_bm25_machine3)

    # test all three machines
    test_doc_transform = transform(test_tfidf_machine3, ngram_vec)
    @test (Vector(vec(sum(test_doc_transform, dims=2))) .> 0.2) == Bool[1, 1, 1, 1, 1, 1]

    test_doc_transform = transform(test_count_machine3, ngram_vec)
    @test Vector(vec(sum(test_doc_transform, dims=2))) == [14, 10, 14, 9, 13, 7]

    test_doc_transform = transform(test_bm25_machine3, ngram_vec)
    @test (Vector(vec(sum(test_doc_transform, dims=2))) .> 0.8) == Bool[1, 1, 1, 1, 1, 1]
end


text:
using PositiveFactorizations
using LinearAlgebra, Test

@testset "PositiveFactorizations" begin
for pivot in (Val{false}, Val{true})
    A = [1 0; 0 1]
    F = cholesky(Positive, A, pivot)
    @test Matrix(F) ≈ A
    F, d = ldlt(Positive, A, pivot)
    @test Matrix(F) ≈ A
    @test d == [1,1]

    A = [1 0; 0 -1]
    F = cholesky(Positive, A, pivot)
    @test Matrix(F) ≈ Matrix(1.0I,2,2)
    F, d = ldlt(Positive, A, pivot)
    @test Matrix(F) ≈ Matrix(1.0I,2,2)
    @test d == [1,-1]

    A = [-1 0.5; 0.5 4]
    target = pivot == Val{false} ? [1 -0.5; -0.5 4.5] : [1.125 0.5; 0.5 4]
    dtarget = pivot == Val{false} ? [-1,1] : [1,-1]
    F = cholesky(Positive, A, pivot)
    @test Matrix(F) ≈ target
    F = cholesky(Positive, 10*A, pivot)
    @test Matrix(F) ≈ 10*target
    F, d = ldlt(Positive, A, pivot)
    @test Matrix(F) ≈ target
    @test d == dtarget

    A = [0 1; 1 0]
    F = cholesky(Positive, A, pivot)
    @test Matrix(F) ≈ Matrix(1.0I,2,2)
    F, d = ldlt(Positive, A, pivot)
    @test Matrix(F) ≈ Matrix(1.0I,2,2)
    @test d == [0,0]

    A = rand(201,200); A = A'*A
    F = cholesky(Positive, A, pivot)
    @test Matrix(F) ≈ A
    F, d = ldlt(Positive, A, pivot)
    @test Matrix(F) ≈ A
    @test all(d .== 1)

    # factorization of (not too small) BigFloat matrices passes
    a = BigFloat.(1:15); A = a * a'
    F = cholesky(Positive, A, pivot)
    F, d = ldlt(Positive, A, pivot)
end

A = [1 0; 0 -2]
F = eigen(Positive, A)

# TODO: Use this when we drop v0.4 support
# @test Matrix(F) ≈ abs.(A)
absA = abs.(A)
absA = convert(Array{Int}, absA) # v0.4 fix
@test Matrix(F) ≈ absA

A = [1 0; 0 0]
F = eigen(Positive, A)
@test Matrix(F) ≈ Matrix(1.0I,2,2)

# Test whether necessary matrix operations are supported for SubArrays
n = PositiveFactorizations.default_blocksize(Float64)
B = rand(n+3,n+4); C = rand(size(B)...); A = B'*B - C'*C
ldlt!(Positive, A)
end   # @testset


text:
using Base: @kwdef

"""
    SDM

A sigma-delta modulator. Converts a floating-point value to a deterministic bit.
"""
@kwdef mutable struct SDM
    error::Float64 = 0
end

"""
    (ΣΔ::SDM)(x::Real)

Evaluate `ΣΔ` on `x` returning a `DBit`.
"""
function (ΣΔ::SDM)(x::Real)
    y = DBit(x >= ΣΔ.error)
    ΣΔ.error += float(y) - x

    return y
end


text:
tests = ["rmath", "generic", "misc", "chainrules", "inverse"]

for t in tests
    fp = "$t.jl"
    println("* running $fp")
    include(fp)
end


text:
"""
    pullfile(server::String, server_dir::String, local_dir::String, filename::String)

Pulls a file from the specified server and server dir to the local dir.
"""
function pullfile(server::String, server_dir::String, local_dir::String, filename::String)
    run(`scp $(server * ":" * server_dir * filename) $local_dir`)
    pulled_files = searchdir(local_dir, filename)
    if !isempty(pulled_files)
        return pulled_files[1]
    end
end

"""
    pullfile(server_dir::String, local_dir::String, filename::String; server=getdefault_server())

Pulls a file from the default server if the default server is specified.
"""
function pullfile(server_dir::String, local_dir::String, filename::String; server=getdefault_server())
    if server != ""
        run(`scp $(server * ":" * server_dir * filename) $local_dir`)
        pulled_files = searchdir(local_dir, filename)
        if !isempty(pulled_files)
            return pulled_files[1]
        end
    else
        error("Define a default server first using 'setdefault_server!(...)'.\n
        Or use function 'pullfile(server::String, server_dir::String, local_dir::String, filename::String)'.")
    end
end

function pullfiles(server_dir::String, local_dir::String, filenames::Vector{String}; serv=getdefault_server())
    pulled_files = String[]
    for file in filenames
       push!(pulled_files, pullfile(server_dir, local_dir, file, serv))
    end
    return pulled_files
end

"""
    pullfile(filepath::String, local_dir::String; server=getdefault_server(), local_filename=nothing)

Pulls a file from the default server if the default server is specified.
"""
function pullfile(filepath::String, local_dir::String; server=getdefault_server(), local_filename=nothing)
    local_dir = formdirectory(local_dir)
    if server != ""
        if local_filename != nothing
            run(`scp $(server * ":" * filepath) $(local_dir * local_filename)`)
            return searchdir(local_dir, local_filename)[1]
        else
            run(`scp $(server * ":" * filepath) $(local_dir)`)
            return searchdir(local_dir, splitdir(filepath)[2])[1]
        end
    else
        error("Define a default server first using 'setdefault_server!(...)'.\n
        Or use function 'pullfile(server::String, server_dir::String, local_dir::String, filename::String)'.")
    end
end

#TODO: doesn't work for abinit
#TODO: local pulloutputs!
"""
    pulloutputs(job::DFJob, server="", server_dir="", local_dir=""; job_fuzzy="*job*", extras=String[])

First pulls the job file (specified by job_fuzzy), reads the possible output files and tries to pull them.
Extra files to pull can be specified by the `extras` keyword, works with fuzzy filenames.
"""
function pulloutputs(job::DFJob, server="", server_dir="", local_dir=""; job_fuzzy="*job*", extras=String[], ignore=String[], overwrite=true)
    if job.server == "" && server == ""
        error("Error: No job server specified. Please specify it first.")
    elseif server != ""
        job.server = server
    end
    if job.server_dir == "" && server_dir == ""
        error("Error: No job server_dir specified. Please specify it first.")
    elseif server_dir != ""
        job.server_dir = server_dir
    end
    if job.local_dir == "" && local_dir == ""
        error("Error: No job local/home directory specified. Please specify it first.")
    elseif server != ""
        job.local_dir = local_dir
    end
    if !ispath(job.local_dir)
        mkpath(job.local_dir)
    end
    pull_server_file(filename) = pullfile(job.server, job.server_dir, job.local_dir, filename)

    # pull_server_file(job_fuzzy)

    # job_file = searchdir(job.local_dir, strip(job_fuzzy, '*'))[1]
    # inputs, pulloutputs= read_job_filenames(job.local_dir * job_file)
    pulled_outputs = String[]
    for calc in job.inputs
        ofile = outfilename(calc)
        if any(occursin.(ignore, ofile)) || (ispath(outpath(calc)) && !overwrite)
            continue
        end
        try
            pull_server_file(ofile)
            push!(pulled_outputs, ofile)
        catch
            nothing
        end
    end

    for fuzzy in extras
        pull_server_file(fuzzy)
        push!(pulled_outputs, searchdir(job.local_dir, strip(fuzzy,'*'))...)
    end
    return joinpath.(job.local_dir, pulled_outputs)
end

sshcmd(server, cmd) = run(`ssh -t $server $cmd`)
sshreadstring(server, cmd) = read(`ssh -t $server $cmd`, String)

"Deletes the job from the local or server queue."
qdel(server::String, id::Int) = sshcmd(server, "qdel $id")
qdel(id::Int) = run(`qdel $id`)
function qdel(job::DFJob)
    if runslocal(job)
        qdel(slurm_jobid(job))
    else
        qdel(job.server, slurm_jobid(job))
    end
end

function qsub(job::DFJob; rm_prev=true)
    outstr = ""
    if !runslocal(job)
        push(job)
        outstr = read(`ssh -t $(job.server) cd $(job.server_dir) '&&' qsub job.tt`, String)
    else
        curdir = pwd()
        cd(job.local_dir)
        if rm_prev
	        prev_files = searchdir(job.local_dir, "job.tt.")
	        for p in prev_files
		        rm(joinpath(job.local_dir, p))
	        end
        end
        try
            outstr = read(`qsub job.tt`, String)
        catch
            error("Tried submitting on the local machine but got an error executing `qsub`.")
        end
        cd(curdir)
    end
    return parse(Int, chomp(outstr))
end

"Tests whether a directory exists on a server and if not, creates it."
function mkserverdir(server, dir)
    testfile = joinpath(dir, "tmp.in")
    try
        run(`ssh -t $server touch $testfile`)
        run(`ssh -t $server rm $testfile`)
    catch
        run(`ssh -t $server mkdir -p $dir`)
        @info "$dir did not exist on $server, it was created."
    end
end

"""
    pulljob(server::String, server_dir::String, local_dir::String; job_fuzzy="*job*")

Pulls job from server. If no specific inputs are supplied it pulls all .in and .tt files.
"""
function pulljob(server::String, server_dir::String, local_dir::String; job_fuzzy="*job*")
    server_dir = server_dir
    local_dir  = local_dir
    if !ispath(local_dir)
        mkpath(local_dir)
    end

    pull_server_file(filename) = pullfile(server, server_dir, local_dir, filename)
    pull_server_file(job_fuzzy)
    job_file = searchdir(local_dir, strip(job_fuzzy, '*'))[1]

    if job_file != nothing
        input_files, output_files = read_job_filenames(joinpath(local_dir, job_file))
        for file in input_files
            pull_server_file(file)
        end
    end
end

pulljob(args...; kwargs...) = pulljob(getdefault_server(), args..., kwargs...)

"""
    push(job::DFJob)

Pushes a DFJob from it's local directory to its server side directory.
"""
function push(job::DFJob)
    mkserverdir(job.server, job.server_dir)
    scp(file) = run(`scp $(job.local_dir * file) $(job.server * ":" * job.server_dir)`)
    for i in inputs(job)
        scp(i.filename)
    end
    scp("job.tt")
end

#Gives the reverse (last job is listed first) of the output, omitting the header lines
slurm_process_command(cmd) = strip.(reverse(readlines(cmd)))[1:end-2]


text:
#Code written by Skipper af Rosenborg and Esben Bager
function loadDiabetes(path)
    cd(path)
    mainData = CSV.read("Diabetes/diabetes.csv", delim = ";", nullable=false)
    return mainData
end

function loadWineQuality(path)
    cd(path)
    mainData = CSV.read("WineQualityRed/winequality-red.csv", delim = ";", nullable=false, types=fill(Float64,12))
    return mainData
end

function loadHousingData(path)
    cd(path)
    mainData = CSV.read("AmesHousingModClean.csv", delim = ';', nullable=false)
    return mainData
end

function loadConcrete(path)
    cd(path)
    mainData = CSV.read("Concrete_Data.csv", delim = ',', nullable=false, types=Dict(3=>Float64))
    return mainData
end

function loadCPUData(path)
    cd(path)
    mainData = CSV.read("machine.csv", header=["MYCT",
    	"MMIN","MMAX","CACH","CHMIN","CHMAX","PRP"], datarow=1, nullable=false)
    return mainData
end

function loadIndexDataLOGReturn(industry, path)
    cd(path)
    mainData = CSV.read("monthly"*industry*"LOGReturn2.csv", header=["NoDur","Durbl",
        "Manuf","Enrgy","HiTec","Telcm","Shops", "Hlth","Utils","Other","Index",
        "D12","E12","b.m","tbl","AAA","BAA","lty","ntis","Rfree","infl","ltr",
        "corpr","svar","csp","CRSP_SPvw","CRSP_SPvwx","VIX","Ycol","Date","Resession"],
        delim = ',', nullable=false, types=Dict(25=>Float64, 28=>Float64))
    return mainData
end

function loadRiskFreeRate(industry, path)
    cd(path)
    mainData = CSV.read("riskFreeRateLOG.csv",header =["RfreeRate"],delim = ',', nullable = false)
    return mainData
end

max_stars_repo_path: ML/Code to hand in/DataLoad.jl

max_stars_repo_name: skipperafrosenborg/Thesis

max_issues_repo_path: ML/Code to hand in/DataLoad.jl

max_issues_repo_name: skipperafrosenborg/Thesis

max_forks_repo_path: ML/Code to hand in/DataLoad.jl

max_forks_repo_name: skipperafrosenborg/Thesis


text:
codegen_reverse_autodiff_target(method::Symbol, f::Function, fargtype::Symbol, init) =
  codegen_reverse_autodiff_target(Val{method}, f, fargtype, init)

function codegen_reverse_autodiff_target(::Type{Val{:hessian}}, f::Function, fargtype::Symbol, init::Tuple)
  adfunction = ReverseDiffSource.rdiff(f, (init[2],), order=2, allorders=false)

  @gensym reverse_autodiff_target
  quote
    function $reverse_autodiff_target($(init[1])::$fargtype)
      -$(adfunction)($(init[1]))
    end
  end
end

function codegen_reverse_autodiff_target(::Type{Val{:hessian}}, f::Function, fargtype::Symbol, init::Vector)
  adfunction = ReverseDiffSource.rdiff(f, (init[1][2], init[2][2]), ignore=[init[2][1]], order=2, allorders=false)

  @gensym reverse_autodiff_target
  quote
    function $reverse_autodiff_target($(init[1][1])::$fargtype, $(init[2][1])::Vector)
      -$(adfunction)($(init[1][1]), $(init[2][1]))
    end
  end
end

codegen_reverse_autodiff_uptotarget(method::Symbol, f::Function, fargtype::Symbol, init) =
  codegen_reverse_autodiff_uptotarget(Val{method}, f, fargtype, init)

function codegen_reverse_autodiff_uptotarget(::Type{Val{:hessian}}, f::Function, fargtype::Symbol, init::Tuple)
  adfunction = ReverseDiffSource.rdiff(f, (init[2],), order=2, allorders=true)

  @gensym reverse_autodiff_uptotarget
  quote
    function $reverse_autodiff_uptotarget($(init[1])::$fargtype)
      v, g, h = $(adfunction)($(init[1]))
      return v, g, -h
    end
  end
end

function codegen_reverse_autodiff_uptotarget(::Type{Val{:hessian}}, f::Function, fargtype::Symbol, init::Vector)
  adfunction = ReverseDiffSource.rdiff(f, (init[1][2], init[2][2]), ignore=[init[2][1]], order=2, allorders=true)

  @gensym reverse_autodiff_uptotarget
  quote
    function $reverse_autodiff_uptotarget($(init[1][1])::$fargtype, $(init[2][1])::Vector)
      v, g, h = $(adfunction)($(init[1][1]), $(init[2][1]))
      return v, g, -h
    end
  end
end

function codegen_reverse_autodiff_function(f::Expr, fargtype::Symbol, init::Tuple, order::Integer, allorders::Bool=true)
  @gensym reverse_autodiff_function
  Expr(
    :function,
    Expr(:call, reverse_autodiff_function, Expr(:(::), init[1], fargtype)),
    eval(Expr(
      :call,
      :(ReverseDiffSource.rdiff),
      :($(Expr(:quote, f))),
      Expr(:kw, init...),
      Expr(:kw, :order, order),
      Expr(:kw, :allorders, allorders)
    ))
  )
end

function codegen_reverse_autodiff_function(f::Expr, fargtype::Symbol, init::Vector, order::Integer, allorders::Bool=true)
  @gensym reverse_autodiff_function
  Expr(
    :function,
    Expr(:call, reverse_autodiff_function, Expr(:(::), init[1][1], fargtype), Expr(:(::), init[2][1], :Vector)),
    eval(Expr(
      :call,
      :(ReverseDiffSource.rdiff),
      :($(Expr(:quote, f))),
      Expr(:kw, init[1]...),
      Expr(:kw, init[2]...),
      Expr(:kw, :ignore, [init[2][1]]),
      Expr(:kw, :order, order),
      Expr(:kw, :allorders, allorders),
    ))
  )
end

codegen_reverse_autodiff_target(method::Symbol, f::Expr, fargtype::Symbol, init) =
  codegen_reverse_autodiff_target(Val{method}, f, fargtype, init)

function codegen_reverse_autodiff_target(::Type{Val{:hessian}}, f::Expr, fargtype::Symbol, init::Tuple)
  @gensym reverse_autodiff_target
  Expr(
    :function,
    Expr(:call, reverse_autodiff_target, Expr(:(::), init[1], fargtype)),
    Expr(
      :call,
      :-,
      eval(Expr(
        :call,
        :(ReverseDiffSource.rdiff),
        :($(Expr(:quote, f))),
        Expr(:kw, init...),
        Expr(:kw, :order, 2),
        Expr(:kw, :allorders, false)
      ))
    )
  )
end

function codegen_reverse_autodiff_target(::Type{Val{:hessian}}, f::Expr, fargtype::Symbol, init::Vector)
  @gensym reverse_autodiff_target
  Expr(
    :function,
    Expr(:call, reverse_autodiff_target, Expr(:(::), init[1][1], fargtype), Expr(:(::), init[2][1], :Vector)),
    Expr(
      :call,
      :-,
      eval(Expr(
        :call,
        :(ReverseDiffSource.rdiff),
        :($(Expr(:quote, f))),
        Expr(:kw, init[1]...),
        Expr(:kw, init[2]...),
        Expr(:kw, :ignore, [init[2][1]]),
        Expr(:kw, :order, 2),
        Expr(:kw, :allorders, false),
      ))
    )
  )
end

codegen_reverse_autodiff_uptotarget(method::Symbol, f::Expr, fargtype::Symbol, init) =
  codegen_reverse_autodiff_uptotarget(Val{method}, f, fargtype, init)

function codegen_reverse_autodiff_uptotarget(::Type{Val{:hessian}}, f::Expr, fargtype::Symbol, init::Tuple)
  adfunction = eval(Expr(
    :call,
    :(ReverseDiffSource.rdiff),
    :($(Expr(:quote, f))),
    Expr(:kw, init...),
    Expr(:kw, :order, 2),
    Expr(:kw, :allorders, true)
  ))

  @gensym reverse_autodiff_uptotarget
  quote
    function $reverse_autodiff_uptotarget($(init[1])::$fargtype)
      v, g, h = $(adfunction)($(init[1]))
      return v, g, -h
    end
  end
end

function codegen_reverse_autodiff_uptotarget(::Type{Val{:hessian}}, f::Expr, fargtype::Symbol, init::Vector)
  adfunction = eval(Expr(
    :call,
    :(ReverseDiffSource.rdiff),
    :($(Expr(:quote, f))),
    Expr(:kw, init[1]...),
    Expr(:kw, init[2]...),
    Expr(:kw, :ignore, [init[2][1]]),
    Expr(:kw, :order, 2),
    Expr(:kw, :allorders, true),
  ))

  @gensym reverse_autodiff_uptotarget
  quote
    function $reverse_autodiff_uptotarget($(init[1][1])::$fargtype, $(init[2][1])::Vector)
      v, g, h = $(adfunction)($(init[1][1]), $(init[2][1]))
      return v, g, -h
    end
  end
end


text:
# Contains T-norms
# ----------------------------------
"""
	Compute the minimum value of the tmp_strengths vector

    minimum_value(tmp_strengths<:AbstractFloat)
"""
function minimum_value(tmp_strengths::Vector{<:AbstractFloat})
    return minimum(tmp_strengths)
end

"""
	Compute the algebraic product of the tmp_strengths vector

    algebraic_product(tmp_strengths<:AbstractFloat)
"""
function algebraic_product(tmp_strengths::Vector{<:AbstractFloat})
    return prod(tmp_strengths)
end

"""
	Compute the bounded difference of the tmp_strengths vector

    bounded_difference(tmp_strengths<:AbstractFloat)
"""
function bounded_difference(tmp_strengths::Vector{<:AbstractFloat})
    if  length(tmp_strengths) > 1
        val = tmp_strengths[1]
        for i=2:length(tmp_strengths)
            val = max(0.0, val + tmp_strengths[i] - 1.0)
        end
        return val
    else
        return tmp_strengths[1]
    end
end

"""
	Compute the drastic product of the tmp_strengths vector

    drastic_product(tmp_strengths<:AbstractFloat)
"""
function drastic_product(tmp_strengths::Vector{<:AbstractFloat})
    if  length(tmp_strengths) > 1
        val = tmp_strengths[1]
        for i = 2:length(tmp_strengths)
            if max(val, tmp_strengths[i]) == 1.0
                val = min(val, tmp_strengths[i])
            else
                val = 0.0
            end
        end
        return val
    else
        return tmp_strengths[1]
    end
end

"""
	Compute the Einstein product of the tmp_strengths vector

    einstein_product(tmp_strengths<:AbstractFloat)
"""
function einstein_product(tmp_strengths::Vector{<:AbstractFloat})
    if  length(tmp_strengths) > 1
        val = tmp_strengths[1]
        for i=2:length(tmp_strengths)
            val = (val * tmp_strengths[i]) / (2.0 - (val + tmp_strengths[i] - val * tmp_strengths[i]))
        end
        return val
    else
        return tmp_strengths[1]
    end
end

"""
	Compute the Hamacher product of the tmp_strengths vector

    hamacher_product(tmp_strengths<:AbstractFloat)
"""
function hamacher_product(tmp_strengths::Vector{<:AbstractFloat})
    if  length(tmp_strengths) > 1
        val = tmp_strengths[1]
        for i=2:length(tmp_strengths)
            val=(val * tmp_strengths[i]) / (val + tmp_strengths[i] - val * tmp_strengths[i])
        end
        return val
    else
        return tmp_strengths[1]
    end
end


text:
#! /usr/bin/julia

# Rosetta Code, Loops/For

for i in 1:5
    for j in 1:i
        print("*")
    end
    println()
end

max_stars_repo_name: MichaeLeroy/rosetta-code

max_issues_repo_name: MichaeLeroy/rosetta-code

max_forks_repo_name: MichaeLeroy/rosetta-code


text:
using Test

using LazyJSON

dir = @__DIR__
jsonfileurl = "https://raw.githubusercontent.com/exercism/problem-specifications/master/exercises/perfect-numbers/canonical-data.json"
jsonfilename = "canonical-data.json"
jsonfile = download(jsonfileurl, joinpath(dir,jsonfilename))
outputfile = "parse code.txt"

f = LazyJSON.parse(read(joinpath(dir,jsonfile)))

CODE = """
# canonical data version $(f["version"])
using Test

include("perfect-numbers.jl")

"""
for i in f["cases"]
    global CODE *= """
    @testset \"$(i["description"])\" begin
    """
    for j in i["cases"]
        des = String(j["description"])
        inp = j["input"]["number"]
        exped = j["expected"]
        property = j["property"]

        if i["description"] != "Invalid inputs"
            global CODE *= """

                @testset \"$des\" begin
                    @test is$exped($inp)
                end
            """
        else
            global CODE *= """

                @testset \"$des\" begin
                    @test_throws DomainError isdeficient($inp)
                    @test_throws DomainError isperfect($inp)
                    @test_throws DomainError isabundant($inp)
                end
            """
        end

    end
    global CODE *= """
    end

    """
end

write(joinpath(dir,outputfile), CODE)


text:
"""
    Parameter(value::Float64, vary::Bool, prior::Distrbutions.UnivariateDistribution)

A parameter that can be optimised in the analysis procress.

### Parameters
- `value::Float64` or `Distributions.UnivariateDistribution` : the value for the given parameter.
"""
mutable struct Parameter
    value
end

"""
    make_layer
"""
function make_layer(thick, sld, isld, rough)
    return Layer(Parameter(thick), Parameter(sld), Parameter(isld), Parameter(rough))
end

"""
    Layer(thick::Jeff.Parameter, sld::Jeff.Parameter, isld::Jeff.Parameter, rough::Jeff.Parameter)

A description of a layer in a system.

### Parameters
- `thick::Jeff.Parameter` : the layer thickness.
- `sld::Jeff.Parameter` : layer real scattering length density.
- `isld::Jeff.Parameter` : layer imaginary scattering length density.
- `rough::Jeff.Parameter` : roughness with layer above.
"""
mutable struct Layer
    thick::Jeff.Parameter
    sld::Jeff.Parameter
    isld::Jeff.Parameter
    rough::Jeff.Parameter
end

"""
    Model(scale::Jeff.Parmeter, bkg::Jeff.Parameter, layers::Array{Jeff.Layer})

The model from which the reflectometry should be calculated.

### Parameters
- `scale::Jeff.Parameter` : scale factor for reflectometry.
- `bkg::Jeff.Parameter` : uniform background.
- `layers::Array{Jeff.Layer}` : the array of [`Jeff.Layer`] objects that describe the model.
"""
mutable struct Model
    scale::Jeff.Parameter
    bkg::Jeff.Parameter
    layers::Array{Jeff.Layer}
end

"""
    layers_to_array(layers::Array{Jeff.Layer})

Convert from an array of N Jeff.Layer objects to an Nx4 array.

### Parameters
- `layers::Array{Jeff.Layer}`: layers to be converted.

### Returns
- `::Array{Any, 2}` : an array describing the layers.
"""
function layers_to_array(layers::Array{Jeff.Layer})
    nlayers = size(layers, 1)
    array = Array{Any}(undef, nlayers, 4)
    for i in 1:nlayers
        array[i, 1] = layers[i].thick.value
        array[i, 2] = layers[i].sld.value
        array[i, 3] = layers[i].isld.value
        array[i, 4] = layers[i].rough.value
    end
    return array
end


text:
function _hex_escape(s::String)
    tcstr = transcode(UInt8, s)
    strs = String[]
    for tcchar in tcstr
        s = string("\\x", string(tcchar; pad = sizeof(tcchar)<<1, base = 16))
        push!(strs, s)
    end
    strs
end
_hex_escape(s) = _hex_escape(string(s))


text:
##################
# `AbstractPass` #
##################

abstract type AbstractPass end

struct NoPass <: AbstractPass end

(::Type{NoPass})(::Any, ::Any, code_info) = code_info

#########
# `Tag` #
#########

# this @pure annotation has official vtjnash approval :p
Base.@pure _pure_objectid(x) = objectid(x)

abstract type AbstractContextName end

struct Tag{N<:AbstractContextName,X,E#=<:Union{Nothing,Tag}=#} end

Tag(::Type{N}, ::Type{X}) where {N,X} = Tag(N, X, Nothing)

Tag(::Type{N}, ::Type{X}, ::Type{E}) where {N,X,E} = Tag{N,_pure_objectid(X),E}()

#################
# `BindingMeta` #
#################
# We define these here because we need them to define `Context`,
# but most code that works with these types is in src/tagged.jl

mutable struct BindingMeta
    data::Any
    BindingMeta() = new()
end

const BindingMetaDict = Dict{Symbol,BindingMeta}
const BindingMetaDictCache = IdDict{Module,BindingMetaDict}

#############
# `Context` #
#############

"""
```
Context{N<:Cassette.AbstractContextName,
        M<:Any,
        P<:Cassette.AbstractPass,
        T<:Union{Nothing,Cassette.Tag},
        B<:Union{Nothing,Cassette.BindingMetaDictCache}}
```

A type representing a Cassette execution context. This type is normally interacted with
through type aliases constructed via `Cassette.@context`:

```
julia> Cassette.@context MyCtx
Cassette.Context{nametype(MyCtx),M,P,T,B} where B<:Union{Nothing,IdDict{Module,Dict{Symbol,BindingMeta}}}
                                          where P<:Cassette.AbstractPass
                                          where T<:Union{Nothing,Tag}
                                          where M
```

# Constructors

Given a context type alias named e.g. `MyCtx`, an instance of the type can be constructed via:

```
MyCtx(; metadata = nothing, pass = Cassette.NoPass())
```

To construct a new context instance using an existing context instance as a template, see
the `similarcontext` function.

To enable contextual tagging for a given context instance, see the `enabletagging` function.

# Fields

- `name::N<:Cassette.AbstractContextName`: a parameter used to disambiguate different
    contexts for overloading purposes (e.g. distinguishes `MyCtx` from other `Context` type
    aliases).

- `metadata::M<:Any`: trace-local metadata as provided to the context constructor

- `pass::P<:Cassette.AbstractPass`: the Cassette pass that will be applied to all method
    bodies encountered during contextual execution (see the `@pass` macro for details).

- `tag::T<:Union{Nothing,Tag}`: the tag object that is attached to values when they are
    tagged w.r.t. the context instance

- `bindingscache::B<:Union{Nothing,BindingMetaDictCache}}`: storage for metadata associated
    with tagged module bindings
"""
struct Context{N<:AbstractContextName,
               M<:Any,
               P<:AbstractPass,
               T<:Union{Nothing,Tag},
               B<:Union{Nothing,BindingMetaDictCache}}
    name::N
    metadata::M
    pass::P
    tag::T
    bindingscache::B
    function Context(name::N, metadata::M, pass::P, ::Nothing, ::Nothing) where {N,M,P}
        return new{N,M,P,Nothing,Nothing}(name, metadata, pass, nothing, nothing)
    end
    function Context(name::N, metadata::M, pass::P, tag::Tag{N}, bindingscache::BindingMetaDictCache) where {N,M,P}
        return new{N,M,P,typeof(tag),BindingMetaDictCache}(name, metadata, pass, tag, bindingscache)
    end
end

const ContextWithTag{T} = Context{<:AbstractContextName,<:Any,<:AbstractPass,T}
const ContextWithPass{P} = Context{<:AbstractContextName,<:Any,P}

function Context(name::AbstractContextName; metadata = nothing, pass::AbstractPass = NoPass())
    return Context(name, metadata, pass, nothing, nothing)
end

"""
```
similarcontext(context::Context;
               metadata = context.metadata,
               pass = context.pass,
               tag = context.tag,
               bindingscache = context.bindingscache)
```

Return a copy of the given `context`, replacing field values in the returned instance with
those provided via the keyword arguments.
"""
function similarcontext(context::Context;
                        metadata = context.metadata,
                        pass = context.pass,
                        tag = context.tag,
                        bindingscache = context.bindingscache)
    return Context(context.name, metadata, pass, tag, bindingscache)
end

"""
```
enabletagging(context::Cassette.Context, f)
```

Return a copy of the given `context` with the tagging system enabled for the contextual
execution of `f`.

Cassette uses the type of `f` to generate the `tag` field of the returned instance.

Note that it is generally unsafe to use the returned instance to contextually execute
functions other than `f`. Specifically, in cases of nested contextual execution where
both inner and outer contexts employ the tagging system, improper application of the
tagged system could cause (for example) separate contexts to erroneously interfere with
each other's metadata propagation.

See also: [`hastagging`](@ref)
"""
function enabletagging(context::Context, f)
    return similarcontext(context;
                          tag = Tag(typeof(context.name), typeof(f)),
                          bindingscache = BindingMetaDictCache())
end

"""
```
hastagging(::Type{<:Cassette.Context})
```

Returns `true` if the given type indicates that the contextual tagging system is enabled
for context instances of the type, returns `false` otherwise.

# Example

```
julia> Cassette.@context MyCtx;

julia> ctx = MyCtx();

julia> Cassette.hastagging(typeof(ctx))
false

julia> ctx = Cassette.enabletagging(ctx, sum);

julia> Cassette.hastagging(typeof(ctx))
true
```

See also: [`enabletagging`](@ref)
"""
hastagging(::Type{<:ContextWithTag{<:Tag}}) = true
hastagging(::Type{<:ContextWithTag{Nothing}}) = false

tagtype(::C) where {C<:Context} = tagtype(C)
tagtype(::Type{<:ContextWithTag{T}}) where {T} = T

nametype(::Type{<:Context{N}}) where {N} = N

############
# @context #
############

"""
```
Cassette.@context Ctx
```

Define a new Cassette context type with the name `Ctx`. In reality, `Ctx` is simply a type
alias for `Cassette.Context{Cassette.nametype(Ctx)}`.

Note that `Cassette.execute` is automatically overloaded w.r.t. `Ctx` to define several
primitives by default. A full list of these default primitives can be obtained by running:

```
methods(Cassette.execute, (Ctx, Vararg{Any}))
```

Note also that many of the default primitives' signatures only match when contextual tagging
is enabled.

See also: [`Context`](@ref)
"""
macro context(Ctx)
    @assert isa(Ctx, Symbol) "context name must be a Symbol"
    CtxName = gensym(string(Ctx, "Name"))
    TaggedCtx = gensym(string(Ctx, "Tagged"))
    Typ = :(Core.Typeof)
    return esc(quote
        struct $CtxName <: $Cassette.AbstractContextName end

        Base.show(io::IO, ::Type{$CtxName}) = print(io, "nametype(", $(string(Ctx)), ")")

        const $Ctx{M,T<:Union{Nothing,$Cassette.Tag},P<:$Cassette.AbstractPass} = $Cassette.Context{$CtxName,M,P,T}
        const $TaggedCtx = $Ctx{<:Any,<:$Cassette.Tag}

        $Ctx(; kwargs...) = $Cassette.Context($CtxName(); kwargs...)

        @doc (@doc $Cassette.Context) $Ctx

        @inline $Cassette.execute(::C, ::$Typ($Cassette.Tag), ::Type{N}, ::Type{X}) where {C<:$Ctx,N,X} = $Cassette.Tag(N, X, $Cassette.tagtype(C))

        # TODO: There are certain non-`Core.Builtin` functions which the compiler often
        # relies upon constant propagation to infer, such as `isdispatchtuple`. Such
        # functions should generally be contextual primitives by default for the sake of
        # performance, and we should add more of them here as we encounter them.
        @inline $Cassette.execute(ctx::$Ctx, f::$Typ(Base.isdispatchtuple), T::Type) = $Cassette.fallback(ctx, f, T)
        @inline $Cassette.execute(ctx::$Ctx, f::$Typ(Base.eltype), T::Type) = $Cassette.fallback(ctx, f, T)
        @inline $Cassette.execute(ctx::$Ctx, f::$Typ(Base.convert), T::Type, t::Tuple) = $Cassette.fallback(ctx, f, T, t)
        @inline $Cassette.execute(ctx::$Ctx{<:Any,Nothing}, f::$Typ(Base.getproperty), x::Any, s::Symbol) = $Cassette.fallback(ctx, f, x, s)

        # the below primitives are only active when the tagging system is enabled (`typeof(ctx) <: TaggedCtx`)

        @inline $Cassette.execute(ctx::C, f::$Typ($Cassette.tag), value, ::C, metadata) where {C<:$TaggedCtx} = $Cassette.fallback(ctx, f, value, ctx, metadata)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Array{T,N}), undef::UndefInitializer, args...) where {T,N} = $Cassette.tagged_new_array(ctx, Array{T,N}, undef, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Core.Module), args...) = $Cassette.tagged_new_module(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Core.tuple), args...) = $Cassette.tagged_new_tuple(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Base.nameof), args...) = $Cassette.tagged_nameof(ctx, m)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Core.getfield), args...) = $Cassette.tagged_getfield(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Core.setfield!), args...) = $Cassette.tagged_setfield!(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Core.arrayref), args...) = $Cassette.tagged_arrayref(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Core.arrayset), args...) = $Cassette.tagged_arrayset(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Base._growbeg!), args...) = $Cassette.tagged_growbeg!(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Base._growend!), args...) = $Cassette.tagged_growend!(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Base._growat!), args...) = $Cassette.tagged_growat!(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Base._deletebeg!), args...) = $Cassette.tagged_deletebeg!(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Base._deleteend!), args...) = $Cassette.tagged_deleteend!(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Base._deleteat!), args...) = $Cassette.tagged_deleteat!(ctx, args...)
        @inline $Cassette.execute(ctx::$TaggedCtx, ::$Typ(Core.typeassert), args...) = $Cassette.tagged_typeassert(ctx, args...)

        @inline function $Cassette.execute(ctx::$TaggedCtx, f::Core.IntrinsicFunction, args...)
            if f === Base.sitofp
                return $Cassette.tagged_sitofp(ctx, args...)
            elseif f === Base.sle_int
                return $Cassette.tagged_sle_int(ctx, args...)
            else # TODO: add more cases
                return $Cassette.fallback(ctx, f, args...)
            end
        end

        $Ctx
    end)
end

###############################
# contextual dispatch methods #
###############################

struct OverdubInstead end

"""
```
prehook(context::Context, f, args...)
```

Overload this Cassette method w.r.t. a given context in order to define a new contextual
prehook for that context.

To understand when/how this method is called, see the documentation for [`overdub`](@ref).

Invoking `prehook` is a no-op by default (it immediately returns `nothing`).

See also: [`overdub`](@ref), [`posthook`](@ref), [`execute`](@ref), [`fallback`](@ref)

# Examples

Simple trace logging:

```
julia> Cassette.@context PrintCtx;

julia> Cassette.prehook(::PrintCtx, f, args...) = println(f, args)

julia> Cassette.overdub(PrintCtx(), /, 1, 2)
float(1,)
AbstractFloat(1,)
Float64(1,)
sitofp(Float64, 1)
float(2,)
AbstractFloat(2,)
Float64(2,)
sitofp(Float64, 2)
/(1.0, 2.0)
div_float(1.0, 2.0)
0.5
```

Counting the number of method invocations with one or more arguments of a given type:

```
julia> mutable struct Count{T}
           count::Int
       end

julia> Cassette.@context CountCtx;

julia> Cassette.prehook(ctx::CountCtx{Count{T}}, f, arg::T, args::T...) where {T} = (ctx.metadata.count += 1)

# count the number of calls of the form `f(::Float64, ::Float64...)`
julia> ctx = CountCtx(metadata = Count{Float64}(0));

julia> Cassette.overdub(ctx, /, 1, 2)
0.5

julia> ctx.metadata.count
2
```
"""
@inline prehook(::Context, ::Vararg{Any}) = nothing

"""
```
posthook(context::Context, output, f, args...)
```

Overload this Cassette method w.r.t. a given context in order to define a new contextual
posthook for that context.

To understand when/how this method is called, see the documentation for [`overdub`](@ref).

Invoking `posthook` is a no-op by default (it immediately returns `nothing`).

See also: [`overdub`](@ref), [`prehook`](@ref), [`execute`](@ref), [`fallback`](@ref)

# Examples

Simple trace logging:

```
julia> Cassette.@context PrintCtx;

julia> Cassette.posthook(::PrintCtx, output, f, args...) = println(output, " = ", f, args)

julia> Cassette.overdub(PrintCtx(), /, 1, 2)
1.0 = sitofp(Float64, 1)
1.0 = Float64(1,)
1.0 = AbstractFloat(1,)
1.0 = float(1,)
2.0 = sitofp(Float64, 2)
2.0 = Float64(2,)
2.0 = AbstractFloat(2,)
2.0 = float(2,)
0.5 = div_float(1.0, 2.0)
0.5 = /(1.0, 2.0)
0.5
```

Accumulate the sum of all numeric scalar outputs encountered in the trace:

```
julia> mutable struct Accum
           x::Number
       end

julia> Cassette.@context AccumCtx;

julia> Cassette.posthook(ctx::AccumCtx{Accum}, out::Number, f, args...) = (ctx.metadata.x += out)

julia> ctx = AccumCtx(metadata = Accum(0));

julia> Cassette.overdub(ctx, /, 1, 2)
0.5

julia> ctx.metadata.x
13.0
```
"""
@inline posthook(::Context, ::Vararg{Any}) = nothing

"""
```
execute(context::Context, f, args...)
```

Overload this Cassette method w.r.t. a given context in order to define a new contextual
execution primitive for that context.

To understand when/how this method is called, see the documentation for [`overdub`](@ref).

Invoking `execute` immediately returns `Cassette.OverdubInstead()` by default.

See also: [`overdub`](@ref), [`prehook`](@ref), [`posthook`](@ref), [`fallback`](@ref)
"""
@inline execute(::Context, ::Vararg{Any}) = OverdubInstead()

"""
```
fallback(context::Context, f, args...)
```

Overload this Cassette method w.r.t. a given context in order to define a new contextual
execution fallback for that context.

To understand when/how this method is called, see the documentation for [`overdub`](@ref) and
[`canoverdub`](@ref).

By default, invoking `fallback(context, f, args...)` will simply call `f(args...)` (with all
arguments automatically untagged, if `hastagging(typeof(context))`).

See also:  [`canoverdub`](@ref), [`overdub`](@ref), [`execute`](@ref), [`prehook`](@ref), [`posthook`](@ref)
"""
@inline fallback(ctx::Context, args...) = call(ctx, args...)

@inline call(::ContextWithTag{Nothing}, f, args...) = f(args...)
@inline call(context::Context, f, args...) = untag(f, context)(ntuple(i -> untag(args[i], context), Val(nfields(args)))...)

# TODO: This is currently needed to force the compiler to specialize on the type arguments
# to `Core.apply_type`. In the future, it would be best for Julia's compiler to better handle
# varargs calls to such functions with type arguments, or at least provide a better way to
# force specialization on the type arguments.
@inline call(::ContextWithTag{Nothing}, f::typeof(Core.apply_type), ::Type{A}, ::Type{B}) where {A,B} = f(A, B)
@inline call(::Context, f::typeof(Core.apply_type), ::Type{A}, ::Type{B}) where {A,B} = f(A, B)

"""
```
canoverdub(context::Context, f, args...)
```

Return `true` if `f(args...)` has a lowered IR representation that Cassette can overdub,
return `false` otherwise.

Alternatively, but equivalently:

Return `false` if `overdub(context, f, args...)` directly translates to
`fallback(context, f, args...)`, return `true` otherwise.

Note that unlike `execute`, `fallback`, etc., this function is not intended to be overloaded.

See also:  [`overdub`](@ref), [`fallback`](@ref), [`execute`](@ref)
"""
@inline canoverdub(ctx::Context, f, ::Vararg{Any}) = !isa(untag(f, ctx), Core.Builtin)
@inline canoverdub(ctx::Context, ::typeof(Core._apply), f, args...) = canoverdub(ctx, f, apply_args(ctx, args...)...)
@inline canoverdub(ctx::Context, ::typeof(Core.invoke), f, args...) = canoverdub(ctx, f, args...)


text: Dict{String,Any}("test" => Dict{String,Any}("value" => "\"one\"","type" => "string"))

max_stars_repo_name: SmiteWindows/julia

max_issues_repo_name: SmiteWindows/julia

max_forks_repo_name: SmiteWindows/julia


text:
function single_scatter_test()
    print("Testing single scatterer against an analytic solution with a random position and two random radii across a range of wavenumbers...")

    listener = [-10.0, 0.0];
    xp = 10*rand(2);
    a1 = 10*rand();
    a2 = 10*rand();
    k_arr = LinRange(0.01,2.0,200)
    M1 = Int(round(a1)); #largest hankelh1 order
    M2 = Int(round(a2)); #largest hankelh1 order

    # incident plane wave
    uin(x,k) = exp(im * k * (x[1] - listener[1]))

    # known solution for the scattering coefficients for a single scattering
    function exact_single_scatter(x, k, a, M)
        A(n,k) = -exp(im * k * (xp[1] - listener[1]) + im * n * pi / 2);
        θ = atan(x[2] - xp[2], x[1] - xp[1])
        r = norm(x - xp)
        u = 0.0im
        for m = -M:M
            u += A(m, k) * besselj(m, a * k) / hankelh1(m, a * k) * hankelh1(m, k * r) * exp(im * m * θ)
        end
        return u
    end
    u1(x,k) = exact_single_scatter(x, k, a1, M1)
    u2(x,k) = exact_single_scatter(x, k, a2, M2)

    resp1 = [u1(listener, k) for k in k_arr];
    resp2 = [u2(listener, k) for k in k_arr];

    # Add on incoming wave for the total solution
    resp1 += [uin(listener, k) for k in k_arr];
    resp2 += [uin(listener, k) for k in k_arr];

    # Using the MultipleScattering package
    simulation1 = FrequencySimulation([Particle(xp,a1)], collect(k_arr);
                            listener_positions=listener,
                            source_direction=[1.0, 0.0],
                            hankel_order=M1
    );

    # Build a similar simulation with a different radius and hankel_order
    simulation2 = FrequencySimulation([Particle(xp,a2)], collect(k_arr);
                            listener_positions=listener,
                            source_direction=[1.;0.],
                            hankel_order=M2
    );

    # Take the L^2 error between the analytic solution and our simulation
    err1 = mean(abs.(resp1 - simulation1.response[:]));
    err2 = mean(abs.(resp2 - simulation2.response[:]));

    print("completed for radius=$a1 and $a2 with errors $err1 and $err2 \n")
    if err1 < 1e-9 && err2 < 1e-9
        return true
    else
        return false
    end

end