text:
@testset "Events/Markup Declarations" begin
    # These test sets are a grab bag of negative tests that really fit anywhere else.
    #
    evaluate(s) = collect(E.events(L.State(IOBuffer(s))))

    E = Events
    L = Events.Lexical

    DC = E.DataContent
    ME = E.MarkupError

    @testset "Events/Markup Declarations (Negative ... invalid token after <!)" begin
        events = evaluate("<!")
        @test (events == [ ME("ERROR: Expecting the start of a markup declaration.", L.Location("a buffer", -1)) ])

        events = evaluate("<! ")
        @test length(events) == 2
        @test (events == [ ME("ERROR: Expecting the start of a markup declaration.", L.Location("a buffer", -1)),
                           DC(" ", true, L.Location("a buffer", -1)) ])

        # Check that some random token is caught.
        #
        events = evaluate("<!bob")
        @test length(events) == 2
        @test (events == [ ME("ERROR: Expecting the start of a markup declaration.", L.Location("a buffer", -1)),
                           DC("bob", false, L.Location("a buffer", -1)) ])

        # Look for the lowercased-versions of the correct keywords. These are valid in SGML, but invalid in XML.
        #
        events = evaluate("<!doctype")
        @test length(events) == 2
        @test (events == [ ME("ERROR: The keyword 'doctype' must be uppercased.", L.Location("a buffer", -1)),
                           ME("ERROR: Expecting a root element name.", L.Location("a buffer", -1)) ])

        events = evaluate("<!entity")
        @test length(events) == 3
        @test (events == [ ME("ERROR: The keyword 'entity' must be uppercased.", L.Location("a buffer", -1)),
                           ME("ERROR: White space is required following the 'ENTITY' keyword.", L.Location("a buffer", -1)),
                           ME("ERROR: Expecting an entity name.", L.Location("a buffer", -1)) ])

        events = evaluate("<!notation")
        @test length(events) == 2
        @test (events == [ ME("ERROR: The keyword 'notation' must be uppercased.", L.Location("a buffer", -1)),
                           ME("ERROR: Expecting a notation name.", L.Location("a buffer", -1)) ])

        # Look for the remaining SGML keywords.
        #
        events = evaluate("<!sgml")
        @test length(events) == 2
        @test (events == [ ME("ERROR: The keyword 'SGML' is not available in XML.", L.Location("a buffer", -1)),
                           DC("sgml", false, L.Location("a buffer", -1)) ])

        events = evaluate("<!shortref")
        @test length(events) == 2
        @test (events == [ ME("ERROR: The keyword 'SHORTREF' is not available in XML.", L.Location("a buffer", -1)),
                           DC("shortref", false, L.Location("a buffer", -1)) ])

        events = evaluate("<!usemap")
        @test length(events) == 2
        @test (events == [ ME("ERROR: The keyword 'USEMAP' is not available in XML.", L.Location("a buffer", -1)),
                           DC("usemap", false, L.Location("a buffer", -1)) ])
    end
end

max_stars_repo_name: jlegare/NativeXML

max_issues_repo_name: jlegare/NativeXML

max_forks_repo_name: jlegare/NativeXML


text:
@testset "Testing `sample.txt`" begin
    str = read(joinpath(@__DIR__, "sample.txt"), String)
    d = XMem.parseresult(str)

    # Go through the list - make sure everything is correct
    vals = [
        "Benchmark Type" => "throughput",
        "Working set per thread" => 256,

        "Using MMap" => false,
        "CPU NUMA Node" => 0,
        "Memory NUMA Node" => 0,
        "Chunk Size" => 256,
        "Access Pattern" => "sequential",
        "Read/Write Mode" => "read",
        "Number of worker threads" => 48,

        "25th Percentile" => 107127,
        "Median" => 107136,
        "75th Percentile" => 107147,
        "95th Percentile" => 107185,
        "99th Percentile" => 107185,
        "Min" => 107125,
        "Max" => 107185,
        "Mode" => 107185,
        "Mean" => 107144
    ]

    @test length(d) == length(vals)
    for (a, b) in vals
        @test d[a] == b
    end

end

ext: jl


text:
# Autogenerated wrapper script for XSLT_jll for aarch64-linux-musl
export libexslt, libxslt

using Libgpg_error_jll
using Libgcrypt_jll
using Libiconv_jll
using XML2_jll
using Zlib_jll
JLLWrappers.@generate_wrapper_header("XSLT")
JLLWrappers.@declare_library_product(libexslt, "libexslt.so.0")
JLLWrappers.@declare_library_product(libxslt, "libxslt.so.1")
function __init__()
    JLLWrappers.@generate_init_header(Libgpg_error_jll, Libgcrypt_jll, Libiconv_jll, XML2_jll, Zlib_jll)
    JLLWrappers.@init_library_product(
        libexslt,
        "lib/libexslt.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@init_library_product(
        libxslt,
        "lib/libxslt.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
const SOLUTION_MAX_PRINT_LENGTH = 10

abstract type OptimizationAlgorithm end

solver_step!(alg::OptimizationAlgorithm) = error("solver_step! not implemented for $(typeof(alg))")
hessian(alg::OptimizationAlgorithm, args...) = error("hessian not implemented for $(typeof(alg))")
linesearch(alg::OptimizationAlgorithm, args...) = error("linesearch not implemented for $(typeof(alg))")
update!(::OptimizerResult, alg::OptimizationAlgorithm) = error("update! not implemented for $(typeof(alg))")
OptimizerState(alg::OptimizationAlgorithm, args...) = error("OptimizerState not implemented for $(typeof(alg))")

struct Optimizer{ALG <: NonlinearMethod,
                 OBJ <: MultivariateObjective,
                 OPT <: Options,
                 RES <: OptimizerResult,
                 AST <: OptimizationAlgorithm} <: NonlinearSolver
    algorithm::ALG
    objective::OBJ
    config::OPT
    result::RES
    state::AST
end

function Optimizer(x::VT, objective::MultivariateObjective; algorithm = BFGS(), linesearch = Bisection(), config = Options()) where {XT, VT <: AbstractVector{XT}}
    y = value(objective, x)
    result = OptimizerResult(x, y)
    astate = OptimizerState(algorithm, objective, x, y; linesearch = linesearch)

    Optimizer{typeof(algorithm), typeof(objective), typeof(config), typeof(result), typeof(astate)}(algorithm, objective, config, result, astate)
end

function Optimizer(x::AbstractVector, F::Function; ∇F! = nothing, kwargs...)
    G = GradientParameters(∇F!, F, x)
    objective = MultivariateObjective(F, G, x)
    Optimizer(x, objective; kwargs...)
end

config(opt::Optimizer) = opt.config
result(opt::Optimizer) = opt.result
status(opt::Optimizer) = opt.result.status
state(opt::Optimizer) = opt.state
objective(opt::Optimizer) = opt.objective
algorithm(opt::Optimizer) = opt.algorithm
linesearch(opt::Optimizer) = linesearch(opt.state)

Base.minimum(opt::Optimizer) = minimum(result(opt))
minimizer(opt::Optimizer) = minimizer(result(opt))

function Base.show(io::IO, opt::Optimizer)
    c = config(opt)
    s = status(opt)

    @printf io "\n"
    @printf io " * Algorithm: %s \n" algorithm(opt)
    @printf io "\n"
    @printf io " * Linesearch: %s\n" linesearch(opt)
    @printf io "\n"
    @printf io " * Iterations\n"
    @printf io "\n"
    @printf io "    n = %i\n" iterations(s)
    @printf io "\n"
    @printf io " * Convergence measures\n"
    @printf io "\n"
    @printf io "    |x - x'|               = %.2e %s %.1e\n"  x_abschange(s) x_abschange(s) ≤ x_abstol(c) ? "≤" : "≰" x_abstol(c)
    @printf io "    |x - x'|/|x'|          = %.2e %s %.1e\n"  x_relchange(s) x_relchange(s) ≤ x_reltol(c) ? "≤" : "≰" x_reltol(c)
    @printf io "    |f(x) - f(x')|         = %.2e %s %.1e\n"  f_abschange(s) f_abschange(s) ≤ f_abstol(c) ? "≤" : "≰" f_abstol(c)
    @printf io "    |f(x) - f(x')|/|f(x')| = %.2e %s %.1e\n"  f_relchange(s) f_relchange(s) ≤ f_reltol(c) ? "≤" : "≰" f_reltol(c)
    @printf io "    |g(x)|                 = %.2e %s %.1e\n"  g_residual(s)  g_residual(s)  ≤ g_restol(c) ? "≤" : "≰" g_restol(c)
    @printf io "\n"

    @printf io " * Candidate solution\n"
    @printf io "\n"
    length(minimizer(opt)) > SOLUTION_MAX_PRINT_LENGTH || @printf io  "    Final solution value:     [%s]\n" join([@sprintf "%e" x for x in minimizer(opt)], ", ")
    @printf io "    Final objective value:     %e\n" minimum(opt)
    @printf io "\n"

end

check_gradient(opt::Optimizer) = check_gradient(gradient(objective(opt)))
print_gradient(opt::Optimizer) = print_gradient(gradient(objective(opt)))
print_status(opt::Optimizer) = print_status(status(opt), config(opt))

assess_convergence(opt::Optimizer) = assess_convergence(status(opt), config(opt))
meets_stopping_criteria(opt::Optimizer) = meets_stopping_criteria(status(opt), config(opt))

function initialize!(opt::Optimizer, x::AbstractVector)
    clear!(objective(opt))
    initialize!(result(opt), x, value!(objective(opt), x), gradient!(objective(opt), x))
    initialize!(state(opt), x)
end

"compute objective and gradient at new solution and update result"
function update!(opt::Optimizer, x::AbstractVector)
    update!(result(opt), x, value!(objective(opt), x), gradient!(objective(opt), x))
end

function solve!(x, opt::Optimizer)
    initialize!(opt, x)

    while !meets_stopping_criteria(opt)
        next_iteration!(result(opt))
        solver_step!(x, state(opt))
        update!(opt, x)
    end

    warn_iteration_number(status(opt), config(opt))
    print_status(status(opt), config(opt))

    return x
end


text:
module Generate

using Compat, Compat.Pkg, Compat.LibGit2, Compat.Dates
import ..PkgDev: readlicense, LICENSES

copyright_year() =  string(Dates.year(Dates.today()))
copyright_name(repo::GitRepo) = LibGit2.getconfig(repo, "user.name", "")
github_user() = LibGit2.getconfig("github.user", "")

function git_contributors(repo::GitRepo, n::Int=typemax(Int))
    contrib = Dict()
    for sig in LibGit2.authors(repo)
        if haskey(contrib, sig.email)
            contrib[sig.email][1] += 1
        else
            contrib[sig.email] = [1, sig.name]
        end
    end

    names = Dict()
    for (commits,name) in values(contrib)
        names[name] = get(names,name,0) + commits
    end
    names = sort!(collect(keys(names)),by=name->names[name],rev=true)
    length(names) <= n ? names : [names[1:n]; "et al."]
end

function package(
    pkg::AbstractString,
    license::AbstractString;
    force::Bool = false,
    authors::Union{AbstractString,Array} = "",
    years::Union{Int,AbstractString} = copyright_year(),
    user::AbstractString = github_user(),
    config::Dict = Dict(),
    path::AbstractString = Pkg.Dir.path(),
    travis::Bool = true,
    appveyor::Bool = true,
    coverage::Bool = true,
)
    pkg_path = joinpath(path,pkg)
    isnew = !ispath(pkg_path)
    try
        repo = if isnew
            url = isempty(user) ? "" : "https://github.com/$user/$pkg.jl.git"
            Generate.init(pkg_path,url,config=config)
        else
            repo = GitRepo(pkg_path)
            if LibGit2.isdirty(repo)
                finalize(repo)
                throw(Pkg.PkgError("$pkg is dirty – commit or stash your changes"))
            end
            repo
        end

        LibGit2.transact(repo) do repo
            if isempty(authors)
                authors = isnew ? copyright_name(repo) : git_contributors(repo,5)
            end

            files = [Generate.license(pkg_path,license,years,authors,force=force),
                     Generate.readme(pkg_path,user,force=force,coverage=coverage),
                     Generate.entrypoint(pkg_path,force=force),
                     Generate.tests(pkg_path,force=force),
                     Generate.require(pkg_path,force=force),
                     Generate.gitignore(pkg_path,force=force) ]

            travis && push!(files, Generate.travis(pkg_path,force=force,coverage=coverage))
            appveyor && push!(files, Generate.appveyor(pkg_path,force=force))
            coverage && push!(files, Generate.codecov(pkg_path, force=force))

            msg = """
            $pkg.jl $(isnew ? "generated" : "regenerated") files.

                license:  $license
                authors:  $(join(vcat(authors),", "))
                years:    $years
                user:     $user

            Julia Version $VERSION [$(Base.GIT_VERSION_INFO.commit_short)]
            """
            LibGit2.add!(repo, files..., flags = LibGit2.Consts.INDEX_ADD_FORCE)
            if isnew
                Compat.@info("Committing $pkg generated files")
                LibGit2.commit(repo, msg)
            elseif LibGit2.isdirty(repo)
                LibGit2.remove!(repo, files...)
                Compat.@info("Regenerated files left unstaged, use `git add -p` to select")
                open(io->print(io,msg), joinpath(LibGit2.gitdir(repo),"MERGE_MSG"), "w")
            else
                Compat.@info("Regenerated files are unchanged")
            end
        end
    catch
        isnew && Base.rm(pkg_path, recursive=true)
        rethrow()
    end
    return
end

function init(pkg::AbstractString, url::AbstractString=""; config::Dict=Dict())
    if !ispath(pkg)
        pkg_name = basename(pkg)
        Compat.@info("Initializing $pkg_name repo: $pkg")
        repo = LibGit2.init(pkg)
        try
            with(GitConfig, repo) do cfg
                for (key,val) in config
                    LibGit2.set!(cfg, key, val)
                end
            end
            LibGit2.commit(repo, "initial empty commit")
        catch err
            throw(Pkg.PkgError("Unable to initialize $pkg_name package: $err"))
        end
    else
        repo = GitRepo(pkg)
    end
    try
        if !isempty(url)
            Compat.@info("Origin: $url")
            with(LibGit2.GitRemote, repo, "origin", url) do rmt
                LibGit2.save(rmt)
            end
            LibGit2.set_remote_url(repo, url)
        end
    end
    return repo
end

function genfile(f::Function, pkg::AbstractString, file::AbstractString, force::Bool=false)
    path = joinpath(pkg,file)
    if force || !ispath(path)
        Compat.@info("Generating $file")
        mkpath(dirname(path))
        open(f, path, "w")
        return file
    end
    return ""
end

function license(pkg::AbstractString,
                 license::AbstractString,
                 years::Union{Int,AbstractString},
                 authors::Union{AbstractString,Array};
                 force::Bool=false)
    pkg_name = basename(pkg)
    file = genfile(pkg,"LICENSE.md",force) do io
        if !haskey(LICENSES, license)
            licenses = join(sort!(collect(keys(LICENSES)), by=lowercase), ", ")
            throw(Pkg.PkgError("$license is not a known license choice, choose one of: $licenses."))
        end
        println(io, "The $pkg_name.jl package is licensed under the $(LICENSES[license]):")
        println(io)
        println(io, copyright(years,authors))
        lic=readlicense(license)
        for l in split(lic,['\n','\r'])
            println(io, ">", length(l) > 0 ? " " : "", l)
        end
    end
    !isempty(file) || Compat.@info("License file exists, leaving unmodified; use `force=true` to overwrite")
    file
end

function readme(pkg::AbstractString, user::AbstractString=""; force::Bool=false, coverage::Bool=true)
    pkg_name = basename(pkg)
    genfile(pkg,"README.md",force) do io
        println(io, "# $pkg_name")
        isempty(user) && return
        url = "https://travis-ci.org/$user/$pkg_name.jl"
        println(io, "\n[![Build Status]($url.svg?branch=master)]($url)")
        if coverage
            coveralls_badge = "https://coveralls.io/repos/$user/$pkg_name.jl/badge.svg?branch=master&service=github"
            coveralls_url = "https://coveralls.io/github/$user/$pkg_name.jl?branch=master"
            println(io, "\n[![Coverage Status]($coveralls_badge)]($coveralls_url)")
            codecov_badge = "http://codecov.io/github/$user/$pkg_name.jl/coverage.svg?branch=master"
            codecov_url = "http://codecov.io/github/$user/$pkg_name.jl?branch=master"
            println(io, "\n[![codecov.io]($codecov_badge)]($codecov_url)")
        end
    end
end

function tests(pkg::AbstractString; force::Bool=false)
    pkg_name = basename(pkg)
    genfile(pkg,"test/runtests.jl",force) do io
        print(io, """
        using $pkg_name
        @static if VERSION < v"0.7.0-DEV.2005"
            using Base.Test
        else
            using Test
        end

        # write your own tests here
        @test 1 == 2
        """)
    end
end

function versionfloor(ver::VersionNumber)
    # return "major.minor" for the most recent release version relative to ver
    # for prereleases with ver.minor == ver.patch == 0, return "major-" since we
    # don't know what the most recent minor version is for the previous major
    if isempty(ver.prerelease) || ver.patch > 0
        return string(ver.major, '.', ver.minor)
    elseif ver.minor > 0
        return string(ver.major, '.', ver.minor - 1)
    else
        return string(ver.major, '-')
    end
end

function require(pkg::AbstractString; force::Bool=false)
    genfile(pkg,"REQUIRE",force) do io
        print(io, """
        julia $(versionfloor(VERSION))
        """)
    end
end

function travis(pkg::AbstractString; force::Bool=false, coverage::Bool=true)
    pkg_name = basename(pkg)
    c = coverage ? "" : "#"
    vf = versionfloor(VERSION)
    if vf[end] == '-' # don't know what previous release was
        vf = string(VERSION.major, '.', VERSION.minor)
        release = "#  - $vf"
    else
        release = "  - $vf"
    end
    genfile(pkg,".travis.yml",force) do io
        print(io, """
        ## Documentation: http://docs.travis-ci.com/user/languages/julia/
        language: julia
        os:
          - linux
          - osx
        julia:
        $release
          - nightly
        notifications:
          email: false
        git:
          depth: 99999999

        ## uncomment the following lines to allow failures on nightly julia
        ## (tests will run but not make your overall status red)
        #matrix:
        #  allow_failures:
        #  - julia: nightly

        ## uncomment and modify the following lines to manually install system packages
        #addons:
        #  apt: # apt-get for linux
        #    packages:
        #    - gfortran
        #before_script: # homebrew for mac
        #  - if [ \$TRAVIS_OS_NAME = osx ]; then brew install gcc; fi

        ## uncomment the following lines to override the default test script
        #script:
        #  - julia -e 'Pkg.clone(pwd()); Pkg.build("$pkg_name"); Pkg.test("$pkg_name"; coverage=true)'
        $(c)after_success:
        $(c)  # push coverage results to Coveralls
        $(c)  - julia -e 'cd(Pkg.dir("$pkg_name")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
        $(c)  # push coverage results to Codecov
        $(c)  - julia -e 'cd(Pkg.dir("$pkg_name")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
        """)
    end
end

function appveyor(pkg::AbstractString; force::Bool=false)
    pkg_name = basename(pkg)
    vf = versionfloor(VERSION)
    if vf[end] == '-' # don't know what previous release was
        vf = string(VERSION.major, '.', VERSION.minor)
        rel32 = "#  - JULIA_URL: \"https://julialang-s3.julialang.org/bin/winnt/x86/$vf/julia-$vf-latest-win32.exe\""
        rel64 = "#  - JULIA_URL: \"https://julialang-s3.julialang.org/bin/winnt/x64/$vf/julia-$vf-latest-win64.exe\""
    else
        rel32 = "  - JULIA_URL: \"https://julialang-s3.julialang.org/bin/winnt/x86/$vf/julia-$vf-latest-win32.exe\""
        rel64 = "  - JULIA_URL: \"https://julialang-s3.julialang.org/bin/winnt/x64/$vf/julia-$vf-latest-win64.exe\""
    end
    genfile(pkg,"appveyor.yml",force) do io
        print(io, """
        environment:
          matrix:
        $rel32
        $rel64
          - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
          - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

        ## uncomment the following lines to allow failures on nightly julia
        ## (tests will run but not make your overall status red)
        #matrix:
        #  allow_failures:
        #  - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
        #  - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

        branches:
          only:
            - master
            - /release-.*/

        notifications:
          - provider: Email
            on_build_success: false
            on_build_failure: false
            on_build_status_changed: false

        install:
          - ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
        # If there's a newer build queued for the same PR, cancel this one
          - ps: if (\$env:APPVEYOR_PULL_REQUEST_NUMBER -and \$env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
                https://ci.appveyor.com/api/projects/\$env:APPVEYOR_ACCOUNT_NAME/\$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
                Where-Object pullRequestId -eq \$env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
                throw "There are newer queued builds for this pull request, failing early." }
        # Download most recent Julia Windows binary
          - ps: (new-object net.webclient).DownloadFile(
                \$env:JULIA_URL,
                "C:\\projects\\julia-binary.exe")
        # Run installer silently, output to C:\\projects\\julia
          - C:\\projects\\julia-binary.exe /S /D=C:\\projects\\julia

        build_script:
        # Need to convert from shallow to complete for Pkg.clone to work
          - IF EXIST .git\\shallow (git fetch --unshallow)
          - C:\\projects\\julia\\bin\\julia -e "versioninfo();
              Pkg.clone(pwd(), \\"$pkg_name\\"); Pkg.build(\\"$pkg_name\\")"

        test_script:
          - C:\\projects\\julia\\bin\\julia -e "Pkg.test(\\"$pkg_name\\")"
        """)
    end
end

function codecov(pkg::AbstractString; force::Bool=false)
    genfile(pkg, ".codecov.yml", force) do io
        print(io, """
        comment: false
        """)
    end
end

function gitignore(pkg::AbstractString; force::Bool=false)
    genfile(pkg,".gitignore",force) do io
        print(io, """
        *.jl.cov
        *.jl.*.cov
        *.jl.mem
        """)
    end
end

function entrypoint(pkg::AbstractString; force::Bool=false)
    pkg_name = basename(pkg)
    genfile(pkg,"src/$pkg_name.jl",force) do io
        print(io, """
        module $pkg_name

        # package code goes here

        end # module
        """)
    end
end

copyright(years::AbstractString, authors::AbstractString) = "> Copyright (c) $years: $authors."

function copyright(years::AbstractString, authors::Array)
    text = "> Copyright (c) $years:"
    for author in authors
        text *= "\n>  * $author"
    end
    return text
end

end # module


text:
module TestTournamentAPI

  using Test, Dates
  using NumerAPI.Tournament
  using NumerAPI.Tournament: PUBLIC_DATASETS_URL

  public_id = ENV["NUMERAI_PUBLIC_ID"]
  secret_key = ENV["NUMERAI_SECRET_KEY"]
  username = ENV["TOURNAMENT_USERNAME"]
  model_id = ENV["TOURNAMENT_MODEL_ID"]

  tournament_api = TournamentAPI(public_id, secret_key)

  @testset "test get_dataset_url" begin
    url = get_dataset_url(tournament_api)

    @test typeof(url) === String
    @test occursin("numerai-datasets", url)
  end

  @testset "test download_current_dataset" begin
    current_round = get_current_round(tournament_api)
    dataset_path = download_current_dataset(tournament_api)

    @test dataset_path === "./numerai_dataset_$(current_round).zip"

    rm(dataset_path, force=true)
  end

  @testset "test get_latest_data_url" begin
    data_type = "tournament"
    extension = "csv"
    url = get_latest_data_url(tournament_api, data_type, extension)

    @test url == "$(PUBLIC_DATASETS_URL)/latest_numerai_$(data_type)_data.$(extension)"

    try
      get_latest_data_url("not_valid_data_type", "csv")
    catch ArgumentError
      @test true
    end

  end

  @testset "test download_latest_data" begin
    data_type = "training"
    extension = "csv"
    download_latest_data(tournament_api, data_type, extension, show_progress_bar=true)

    file_path = "./latest_numerai_$(data_type)_data.$(extension)"
    @test isfile(file_path)

    rm(file_path, force=true)
  end

  @testset "test get_competitions" begin
    rounds = get_competitions(tournament_api)

    @test typeof(rounds) <: AbstractVector

    round = rounds[1]
    @test haskey(round, "datasetId")
    @test haskey(round, "number")
    @test haskey(round, "openTime")
    @test haskey(round, "participants")
    @test haskey(round, "prizePoolNmr")
    @test haskey(round, "prizePoolUsd")
    @test haskey(round, "resolveTime")
    @test haskey(round, "resolvedGeneral")
    @test haskey(round, "resolvedStaking")
    @test haskey(round, "ruleset")

    @test typeof(round["openTime"]) <: Union{DateTime,Nothing}
    @test typeof(round["resolveTime"]) <: Union{DateTime,Nothing}
    @test typeof(round["prizePoolNmr"]) <: Union{Float64,Nothing}
    @test typeof(round["prizePoolUsd"]) <: Union{Float64,Nothing}
  end

  @testset "test get_current_round" begin
    round_num = get_current_round(tournament_api)

    @test typeof(round_num) <: Union{Real,Nothing}
  end

  @testset "test get_tournaments" begin
    tournaments = get_tournaments(tournament_api)

    @test typeof(tournaments) <: AbstractArray
    @test length(tournaments) === 1

    tournaments = get_tournaments(tournament_api, only_active=false)

    @test length(tournaments) > 1
  end

  @testset "test get_user_activities" begin
    activities = get_user_activities(tournament_api, username)

    submission_dates = map(x -> x["submission"]["date"], activities)
    submissions = isnothing.(submission_dates)
    @test all(map(x->!x,submissions))
  end

  @testset "test get_submission_filenames" begin
    filenames = get_submission_filenames(tournament_api, model_id=model_id)

    @test typeof(filenames) <: AbstractArray
    @test !isempty(filenames)
    @test typeof(filenames[1]["round_num"]) == Int
    @test typeof(filenames[1]["tournament"]) == Int
    @test typeof(filenames[1]["filename"]) <: AbstractString
  end

  @testset "test get_payments" begin
    payments = get_payments(tournament_api, model_id=model_id)

    @test typeof(payments) <: AbstractDict
    @test typeof(payments["payments"]) <: AbstractArray
    @test typeof(payments["reputationPayments"]) <: AbstractArray
    @test typeof(payments["otherUsdIssuances"]) <: AbstractArray
  end

  @testset "test submission_status" begin
    latest_submission = submission_status(tournament_api, model_id=model_id)

    @test ((typeof(latest_submission) <: Dict) || (isnothing(latest_submission)))
    if !isnothing(latest_submission)
      @test haskey(latest_submission, "filename")
    end
  end

  @testset "test upload_predictions" begin
    current_round = get_current_round(tournament_api)
    prediction_data_path = "./numerai_dataset_$(current_round)/example_predictions.csv"
    submission_id = upload_predictions(tournament_api, prediction_data_path; model_id=model_id)

    @test isa(submission_id, String)

    rm("./numerai_dataset_$(current_round)", force=true, recursive=true)
  end

  @testset "test check_new_round" begin
    HOURS = 48
    is_new_round = check_new_round(tournament_api, hours=HOURS)

    if 5 < Dates.dayofweek(today()) <= 7
      @test is_new_round
    else
      @test !is_new_round
    end
  end

  @testset "test tournament_number2name" begin
    tournament_name = tournament_number2name(tournament_api, 8)

    @test tournament_name === "kazutsugi"
  end

  @testset "test tournament_name2number" begin
    tournament_number = tournament_name2number(tournament_api, "kazutsugi")

    @test tournament_number === 8
  end

  @testset "test get_leaderboard" begin
    leaderboard = get_leaderboard(tournament_api)

    @test length(leaderboard) === 50

    leader1 = get_leaderboard(tournament_api, limit=1)
    @test leader1[1] == leaderboard[1]

    leader2 = get_leaderboard(tournament_api, limit=1, offset=1)
    @test leader2[1] == leaderboard[2]
  end

  @testset "test public_user_profile" begin
    user_profile = public_user_profile(tournament_api, username)

    @test user_profile["username"] === username
    @test user_profile["id"] === model_id
  end

  @testset "test daily_user_performances" begin
    performances = daily_user_performances(tournament_api, username)

    @test typeof(performances) === Vector{Dict}
  end

  @testset "test round_details" begin
    performances = round_details(tournament_api, 253)

    @test typeof(performances) === Vector{Dict}
  end

  @testset "test daily_submissions_performances" begin
    performances = daily_submissions_performances(tournament_api, username)

    @test performances[1]["date"] ≥ performances[2]["date"]
  end

end # module


text:
module ProbabilityDistributions

using   SIMDPirates, SLEEFPirates, SpecialFunctions, DistributionParameters,
        PaddedMatrices, StructuredMatrices, ScatteredArrays, LinearAlgebra,
        VectorizationBase, LoopVectorization, StackPointers, Parameters

using PaddedMatrices:
    DynamicPtrMatrix, AbstractMutableFixedSizeArray, simplify_expr,
    AbstractFixedSizeVector, AbstractFixedSizeMatrix, AbstractFixedSizeArray, AbstractPaddedMatrix,
    AbstractMutableFixedSizeVector, AbstractMutableFixedSizeMatrix

using ScatteredArrays: AbstractScatteredArray
using StructuredMatrices: AbstractAutoregressiveMatrix, AbstractLowerTriangularMatrix
using DistributionParameters: AbstractCorrCholesky, AbstractCovarCholesky, AbstractFixedSizeCovarianceMatrix, invdiag, logdiag
using VectorizationBase: pick_vector_width, pick_vector_width_shift
using ReverseDiffExpressionsBase: isinitialized, uninitialized
using MacroTools: postwalk

abstract type AbstractProbabilityDistribution{track} end
struct Updated∇ end

function return_expression(return_expr)
    length(return_expr.args) == 1 ? return_expr.args[1] : return_expr
end
function return_expression(return_expr, sp::Bool, spexpr = :sp)
    expr = length(return_expr.args) == 1 ? return_expr.args[1] : return_expr
    sp ? Expr(:tuple, spexpr, expr) : expr
end

include("distribution_functions.jl")
include("normal/normal.jl")
include("normal/univariate_normal.jl")
include("normal/multivariate_normal.jl")
# include("normal/matrix_normal.jl")

# _precompile_()

end # module


text:
function solver_OPF(optimizer::Type{<:AbstractOptimizer},resultfile::String="")
#function solver_DeterministicEquivalent(optimizer::Type{<:AbstractOptimizer},resultfile::String="",load_st2::Type{<:AbstractArray{Int64,2}})
#Deterministic Equivalent------------------------------------------------------#
println("Loading inputs...")
#=
(load_st2,Carbprice) = loadinputs("data")

for i in set_scenarios
D[i]=maximum(load_st2[:,i])
end
=#

(syscost_det,p_G_value,p_D_value,Dual_constraint6,f_value)=OPF(optimizer,set_generators,set_nodes,set_demands,generators,demands,capacity,varcost,load_node,utility_node,links,F_max_dict,B_dict,MapG,MapD)

#=
println("")
for j in set_opt
println("x[$j] = ", px_1_det[j])
end
=#

resultfile != "" && open(resultfile, truncate = true) do f

    println(f,"*****************OPF Solution*****************")
    println(f,"")
    println(f,"Objective Function:",syscost_det)
    println(f,"")
    println(f,"Production level of generator g:",p_G_value)
    println(f,"")
    println(f,"Consumption level of demand d:",p_D_value)
    println(f,"")
    println(f,"Electricity Price:",Dual_constraint6)
    println(f,"")
    println(f,"Power Flow:", f_value)
    println(f,"")
    global j=1
    for k in links
    println(f,"Power Flow line $k:", f_value[j])
    global j=j+1
    end
    #=
    println(f,"Second Stage Dispatch Decisions:")
    println(f,p_y_det)
    =#
end
return (syscost_det,p_G_value,p_D_value,Dual_constraint6,f_value)
end


text:
import Dates: DateTime, Period, Second, Nanosecond, unix2datetime, datetime2unix

struct ROSTime <: Readable
    secs::UInt32
    nsecs::UInt32
end
ROSTime(d::DateTime) = convert(ROSTime, d)
ROSTime(s::String) = convert(ROSTime, s)

Base.convert(::Type{UInt64},   t::ROSTime) = UInt64(t.secs) << 32 + t.nsecs
Base.convert(::Type{DateTime}, t::ROSTime) = unix2datetime(t.secs) + Nanosecond(t.nsecs)
# Note: converting ROSTime to DateTime will truncate to millisecond precision

function Base.convert(::Type{ROSTime},  d::DateTime)
    ms = round(Int64, datetime2unix(d) * 1000)
    ROSTime(ms ÷ 1000, (ms % 1000) * 1000000)
end

function Base.convert(::Type{ROSTime}, s::String)
    # We could just call ROSTime(DateTime(s)), but
    # let's be extra nice and parse nanoseconds.
    point = findlast(".", s)
    if point != nothing
        frac = parse(Float64, s[first(point):end])
        nsecs = 1000000000*frac
        secs = datetime2unix(DateTime(s[1:first(point)-1]))
    else
        nsecs = 0.0
        secs = datetime2unix(DateTime(s))
    end
    ROSTime(trunc(UInt32, secs), trunc(UInt32, nsecs))
end

Base.isequal(t1::ROSTime, t2::ROSTime) = convert(UInt64, t1) == convert(UInt64, t2)
Base.isless(t1::ROSTime, t2::ROSTime) = convert(UInt64, t1) < convert(UInt64, t2)

function Base.show(io::IO, t::ROSTime)
    dt = unix2datetime(t.secs)
    print(io, typeof(t), "(\"", dt, ".", lpad(string(t.nsecs), 9, '0'), "\")")
end

struct ROSDuration <: Readable
    secs::Int32
    nsecs::Int32
end
Base.convert(::Type{Period}, t::ROSDuration) = Second(t.secs) + Nanosecond(t.nsecs)

import Base: -, +
time_normed(T, secs, nsecs) = T(secs + nsecs ÷ 1000000000, nsecs % 1000000000)
time_op(T, op, t1, t2) = time_normed(T, op(t1.secs, t2.secs), op(t1.nsecs, t2.nsecs))
-(t1::ROSDuration, t2::ROSDuration) = time_op(ROSDuration, -, t1, t2)
+(t1::ROSDuration, t2::ROSDuration) = time_op(ROSDuration, +, t1, t2)
-(t1::ROSTime,     t2::ROSDuration) = time_op(ROSTime, -, t1, t2)
+(t1::ROSTime,     t2::ROSDuration) = time_op(ROSTime, +, t1, t2)
-(t1::ROSTime,     t2::ROSTime)     = time_op(ROSDuration, (a,b)->Int64(a)-Int64(b), t1, t2)

struct ROSTimespan
    start_time::ROSTime
    end_time::ROSTime
end
(::Colon)(t1::ROSTime, t2::ROSTime) = ROSTimespan(t1, t2)
Base.in(t, span::ROSTimespan) = span.start_time <= convert(ROSTime, t) <= span.end_time

struct Header <: Readable
    seq::UInt32
    time::ROSTime
    frame_id::String
end


text:
"""
Approximate K-Means clustering of multivariate data.

```julia
o = KMeans(y, 3, LearningRate())
value(o)
```
"""
type KMeans{W<:Weight} <: OnlineStat{VectorInput}
    value::MatF
    v::VecF
    weight::W
    n::Int
    nups::Int
end
function KMeans(d::Integer, k::Integer, wgt::Weight = LearningRate())
    KMeans(randn(d, k), zeros(k), wgt, 0, 0)
end
function KMeans{T<:Real}(x::AMat{T}, k::Integer, wgt::Weight = LearningRate())
    o = KMeans(size(x, 2), k, wgt)
    fit!(o, x)
    o
end
function KMeans{T<:Real}(x::AMat{T}, k::Integer, b::Integer, wgt::Weight = LearningRate())
    o = KMeans(size(x, 2), k, wgt)
    fit!(o, x, b)
    o
end
function Base.show(io::IO, o::KMeans)
    printheader(io, "KMeans")
    print_item(io, "value", value(o))
    print_item(io, "K", size(o.v, 2))
    print_item(io, "nobs", nobs(o))
end

function _fit!{T<:Real}(o::KMeans, x::AVec{T}, γ::Float64)
    d, k = size(o.value)
    @assert length(x) == d
    for j in 1:k
        o.v[j] = sumabs2(x - col(o.value, j))
    end
    kstar = indmin(o.v)
    for i in 1:d
        o.value[i, kstar] = smooth(o.value[i, kstar], x[i], γ)
    end
end
function _fitbatch!{T<:Real}(o::KMeans, x::AMat{T}, γ::Float64)
    d, k = size(o.value)
    @assert size(x, 2) == d
    x̄ = vec(mean(x, 1))
    for j in 1:k
        o.v[j] = sumabs2(x̄ - col(o.value, j))
    end
    kstar = indmin(o.v)
    for i in 1:d
        o.value[i, kstar] = smooth(o.value[i, kstar], x̄[i], γ)
    end
end


text:
@testset "Jammer" begin

    @testset "Create jammer with integers" begin
        jammer = CWJammer(
            1,
            12dB,
            doppler = 1100Hz,
            phase = 1,
            exists = true,
            doa = SVector(0, 0, 1)
        )
        @test @inferred(get_jammer_to_noise_ratio(jammer)) == 12dB
        @test @inferred(get_carrier_doppler(jammer)) == 1100Hz
    end

    @testset "CW Jammer" begin
        jammer = CWJammer(
            1,
            12dB,
            doppler = 1100.0Hz,
            phase = π,
            exists = true,
            doa = SVector(0, 0, 1)
        )
        @test @inferred(get_jammer_to_noise_ratio(jammer)) == 12dB
        @test @inferred(get_amplitude(jammer.jnr, 2/Hz, 1000Hz)) ≈ sqrt(10^(12/10) * 2000)
        @test @inferred(get_existence(jammer)) == true
        @test @inferred(get_id(jammer)) == 1
        @test @inferred(get_carrier_doppler(jammer)) == 1100Hz
        @test @inferred(get_carrier_phase(jammer)) ≈ π

        rng = MersenneTwister(1234)
        signal = @inferred GNSSSimulator.gen_signal!(
            jammer,
            2.5e6Hz,
            100Hz,
            1/Hz,
            2500,
            rng
        )

        reference_signal = cis.(2π .* (0:2499) .* (1100Hz .+ 100Hz) ./ 2.5e6Hz .+ π) .*
            sqrt(10^(12/10) * 2.5e6)

        @test sqrt(sum(abs2.(signal .- reference_signal)) / 2500) < 1e-2 *
            sqrt(10^(12/10) * 2.5e6)

        next_jammer = @inferred GNSSSimulator.propagate(
            jammer,
            2500,
            100.0Hz,
            2.5e6Hz,
            1.0/Hz,
            Random.GLOBAL_RNG
        )
        @test @inferred(get_carrier_phase(next_jammer)) ≈ mod2pi(
            π + 2π * 1200.0Hz * 2500 / 2.5e6Hz + π
        ) - π
        @test @inferred(get_carrier_doppler(next_jammer)) == 1100.0Hz
        @test @inferred(get_jammer_to_noise_ratio(next_jammer)) == 12dB
        @test @inferred(get_existence(next_jammer)) == true
        @test @inferred(get_id(next_jammer)) == 1
        @test @inferred(get_doa(next_jammer)) == SVector(0.0, 0.0, 1.0)

        jammer = @inferred CWJammer(1, 10.0dB)
        @test get_id(jammer) == 1
        @test get_jammer_to_noise_ratio(jammer) == 10.0dB
    end

    @testset "Noise Jammer" begin
        noise_jammer = NoiseJammer(1, 12dB, exists = true, doa = SVector(0, 0, 1))
        @test @inferred(get_jammer_to_noise_ratio(noise_jammer)) == 12dB
        @test @inferred(get_amplitude(noise_jammer.jnr, 2/Hz, 1000Hz)) ≈
            sqrt(10^(12/10) * 2000)
        @test @inferred(get_existence(noise_jammer)) == true
        @test @inferred(get_id(noise_jammer)) == 1

        rng = MersenneTwister(1234)
        signal = @inferred GNSSSimulator.gen_signal!(
            noise_jammer,
            2.5e6Hz,
            120Hz,
            1/Hz,
            2500,
            rng
        )
        rng = MersenneTwister(1234)
        @test signal ≈ randn(rng, ComplexF64, 2500) .* sqrt(10^(12/10) * 2.5e6)

        next_jammer = @inferred GNSSSimulator.propagate(
            noise_jammer,
            2500,
            100.0Hz,
            2.5e6Hz,
            1.0/Hz,
            Random.GLOBAL_RNG
        )
        @test @inferred(get_jammer_to_noise_ratio(next_jammer)) == 12dB
        @test @inferred(get_existence(next_jammer)) == true
        @test @inferred(get_doa(next_jammer)) == SVector(0.0, 0.0, 1.0)
        @test @inferred(get_id(next_jammer)) == 1
    end
end


text:
# we need to install a special package in order to use the gamma function
using Pkg
Pkg.add("SpecialFunctions")
using SpecialFunctions

# we write a function that returns the exact volume of a hypersphere in d dimensions
function exactVol(d)
    vol = pi^(d/2) / gamma(1 + d/2)
    return vol
end


text:
using Test
using Statistics
using RoME

##

@testset "Testing tree init prior usage" begin

##

fg = generateCanonicalFG_Circle(4;graphinit=true)
# deleteVariable!.(fg, [:x3, :x4, :l1])

# fg.solverParams.showtree = true
# fg.solverParams.drawtree = true
# fg.solverParams.dbg = true
fg.solverParams.useMsgLikelihoods = true

# now move the graph prior somewhere else (ie all init is wrong)
deleteFactor!(fg, :x0f1)
prpo = PriorPose2(MvNormal([5.,0.,0.0], 0.01*diagm([1;1;1.])))
addFactor!(fg, [:x0], prpo)

##

smtasks = Task[]
tree = solveTree!(fg, smtasks=smtasks); #, recordcliqs=ls(fg));

# hists = fetchCliqHistoryAll!(smtasks)
# printCSMHistoryLogical(hists)

##

X4 = getPoints(fg, :x4)
μX4 =  mean(getManifold(Pose2), X4)

@error("Must first fix IIF #913")
@test 2.0 < μX4.parts[1][1]
@test -1.5 < μX4.parts[1][2] < 1.5

##
end


text:
# Julia stores arrays in column-major order, whereas NumPy stores arrays in row-major order.
# Both languages save arrays to HDF5 following their memory layout, so arrays that were saved
# using h5py are transposed in Julia and vice versa. To guarantee compatibility for backed files,
# we need an additional translation layer that transposes array accesses

struct TransposedDataset{T, N} <: AbstractArray{T, N}
    dset::HDF5.Dataset

    function TransposedDataset(dset::HDF5.Dataset)
        return new{eltype(dset), ndims(dset)}(dset)
    end
end

function Base.getproperty(dset::TransposedDataset, s::Symbol)
    if s === :id
        return getfield(dset, :dset).id
    elseif s === :file
        return getfield(dset, :dset).file
    elseif s === :xfer
        return getfield(dset, :dset).xfer
    else
        return getfield(dset, s)
    end
end

HDF5.filename(dset::TransposedDataset) = HDF5.filename(dset.dset)
HDF5.copy_object(
    src_obj::TransposedDataset,
    dst_parent::Union{HDF5.File, HDF5.Group},
    dst_path::AbstractString,
) = copy_object(src_obj.dset, dst_parent, dst_path)
HDF5.isvalid(dset::TransposedDataset) = isvalid(dset.dset)

Base.to_index(A::HDF5.Dataset, I::AbstractUnitRange{<:Unsigned}) =
    Base.to_index(A, UnitRange{Int}(I)) # hyperslab only supports Int indexes
Base.ndims(dset::TransposedDataset) = ndims(dset.dset)
Base.size(dset::TransposedDataset) = reverse(size(dset.dset))
Base.size(dset::TransposedDataset, d::Integer) = size(dset.dset, ndims(dset.dset) - d + 1)

Base.lastindex(dset::TransposedDataset) = length(dset)
Base.lastindex(dset::TransposedDataset, d::Int) = size(dset, d)
HDF5.datatype(dset::TransposedDataset) = datatype(dset.dset)
Base.read(dset::TransposedDataset) = read_matrix(dset.dset)

Base.getindex(dset::TransposedDataset, i::Integer) = getindex(dset.dset, to_indices(dset, (CartesianIndices(dset)[i],)))
function Base.getindex(dset::TransposedDataset, I::Vararg{<:Integer, N}) where {N}
    mat = getindex(dset.dset, reverse(I)...)
    return ndims(mat) == 1 ? mat : mat'
end
function Base.getindex(dset::TransposedDataset{T, N}, I...) where {T, N}
    @boundscheck checkbounds(dset, I...)
    I = to_indices(dset, I)
    emptydims = Vector{UInt8}()
    for (j, i) in enumerate(I)
        if !(i isa Colon) && isempty(i) # Colon doesn't support isempty
            push!(emptydims, j)
        end
    end
    if !isempty(emptydims)
        dims = collect(size(dset))
        dims[emptydims] .= UInt8(0)
        @inbounds return Array{T, N}(undef, dims...)[I...]
    end

    # HDF5.Dataset doesn't support indexing with integer arrays
    vectordims = findall(x -> !(x isa AbstractRange) && x isa AbstractVector{<:Integer}, I)
    @inbounds if length(vectordims) > 0
        dims = Vector{Int}(undef, length(I))
        for (i, j) in enumerate(I)
            dims[i] = (j isa Colon) ? size(dset, i) : length(j) # Colon doesn't support length
        end
        _ndims = length(dims)
        mat = Array{T, N}(undef, dims...)
        outidx = Vector{Union{Colon, Int}}(undef, _ndims)
        dims_todrop = Vector{Int}()
        for (i, j) in enumerate(I)
            if j isa Number
                push!(dims_todrop, i)
                outidx[i] = 1
            else
                outidx[i] = (:)
            end
        end
        outidx[vectordims] .= 0
        inidx = Vector{Union{typeof.(I)..., (eltype(I[i]) for i in vectordims)...}}(undef, _ndims)
        inidx .= reverse(I)

        for ix in Iterators.product((1:length(I[i]) for i in vectordims)...)
            for (i, j) in enumerate(ix)
                outidx[vectordims[i]] = j
                inidx[_ndims - vectordims[i] + 1] = I[vectordims[i]][j]
            end
            mat[outidx...] = dset.dset[inidx...]
        end
        return dropdims(mat, dims=Tuple(dims_todrop))
    else
        mat = getindex(dset.dset, reverse(I)...)
        return ndims(mat) == 1 ? mat : mat'
    end
end
Base.setindex!(dset::TransposedDataset, v, i::Int) =
    setindex!(dset.dset, v, ndims(dset.dset) - d + 1)
function Base.setindex!(dset::TransposedDataset, v, I::Vararg{Int, N}) where {N}
    if ndims(v) > 1
        v = copy(v')
    end
    setindex!(dset.dset, v, reverse(I)...)
end
function Base.setindex!(dset::TransposedDataset, v, I...)
    if ndims(v) > 1
        v = copy(v')
    end
    setindex!(dset.dset, v, reverse(I)...)
end

Base.eachindex(dset::TransposedDataset) = CartesianIndices(size(dset))

function Base.show(io::IO, dset::TransposedDataset)
    if isvalid(dset)
        print(
            io,
            "Transposed HDF5 dataset: ",
            HDF5.name(dset.dset),
            " (file: ",
            dset.file.filename,
            " xfer_mode: ",
            dset.xfer.id,
            ")",
        )
    else
        print(io, "Transposed HDF5 datset: (invalid)")
    end
end

function Base.show(io::IO, ::MIME"text/plain", dset::TransposedDataset)
    if get(io, :compact, false)::Bool
        show(io, dset)
    else
        print(io, HDF5._tree_icon(HDF5.Dataset), " ", dset)
    end
end


text:
@testset "Testing methods diagnostic tracing" begin
    rosenbrock(x) = sum(i -> 100*abs2(x[i+1] - x[i]^2) + abs2(x[i] - 1), Base.OneTo(length(x)-1))
    schaffer1(x) = (sum(abs2, x), sum(xx -> abs2(xx - 2.0), x))

    @testset "trace_state()" begin
        for mode in [:silent, :compact, :verbose]
            @testset "$mode" begin
                for method in keys(BlackBoxOptim.SingleObjectiveMethods)
                    opt = bbsetup(rosenbrock; Method=method,
                                            SearchRange = (-5.0, 5.0), NumDimensions = 2,
                                            MaxSteps = 1, TraceMode = :silent)
                    BlackBoxOptim.run!(opt)
                    BlackBoxOptim.trace_state(devnull, BlackBoxOptim.optimizer(BlackBoxOptim.lastrun(opt)), mode)
                end
                for method in keys(BlackBoxOptim.MultiObjectiveMethods)
                    opt = bbsetup(schaffer1; Method=method,
                                            SearchRange = [(-10.0, 10.0), (-10.0, 10.0)],
                                            FitnessScheme=ParetoFitnessScheme{2}(is_minimizing=true), ϵ=0.01,
                                            MaxSteps = 1, TraceMode = :silent)
                    BlackBoxOptim.run!(opt)
                    BlackBoxOptim.trace_state(devnull, BlackBoxOptim.optimizer(BlackBoxOptim.lastrun(opt)), mode)
                end
            end
        end
    end
end


text:
"""
    validate_solver_options_and_add_default_values!(options)

Validates that the given solver options are supported and adds default values for most
unspecified options.

### Input

- `options` -- an `Options` object, a dictionary of options

Supported options:

- `:verbosity`     -- controls logging output
- `:logfile`       -- name of a log file
- `:mode`          -- main analysis mode
- `:property`      -- `nothing`, a safety property, or a mapping from a location
                      to a safety property
- `:T`             -- time horizon; alias `:time_horizon`
- `:ε_proj`        -- error bound for the approximation of the states during
                      projection
- `:set_type_proj` -- set type for the approximation of the states during
                      projection
- `:coordinate_transformation` -- coordinate transformation method
- `:projection_matrix`         -- projection matrix
- `:project_reachset`          -- switch for applying projection
- `:max_jumps`     -- maximum number of discrete jumps in a hybrid automaton;
                      `-1` for deactivation
- `:fixpoint_check` -- check for a fixpoint when analyzing a hybrid automaton
- `:clustering`    -- clustering strategy when analyzing a hybrid automaton
- `:plot_vars`     -- variables for projection and plotting;
                      alias: `:output_variables`
- `:n`             -- system's dimension

We add default values for almost all undefined options, i.e., modify the input
options. The benefit is that the user can print the options that were actually
used. For supporting aliases, we create another copy that is actually used where
we only keep those option names that are used internally.
"""
function validate_solver_options_and_add_default_values!(options::Options)::Options
    global LOGGER

    dict = options.dict
    options_copy = Options()
    dict_copy = options_copy.dict

    # first read the verbosity option and set global log level accordingly
    LOGGER = haskey(dict, :verbosity) ?
        configure_logger(dict[:verbosity]) :
        configure_logger()
    check_aliases_and_add_default_value!(dict, dict_copy, [:verbosity], getlevel(LOGGER))
    if haskey(dict, :logfile)
        add_file_logger(dict[:logfile])
        check_aliases!(dict, dict_copy, [:logfile])
    end

    # check for aliases and use default values for unspecified options
    check_aliases_and_add_default_value!(dict, dict_copy, [:mode], "reach")
    check_aliases_and_add_default_value!(dict, dict_copy, [:property], nothing)
    check_aliases_and_add_default_value!(dict, dict_copy, [:coordinate_transformation], "")
    check_aliases_and_add_default_value!(dict, dict_copy, [:projection_matrix], nothing)
    check_aliases_and_add_default_value!(dict, dict_copy, [:project_reachset], false)
    check_aliases_and_add_default_value!(dict, dict_copy, [:max_jumps], -1)
    check_aliases_and_add_default_value!(dict, dict_copy, [:clustering], :chull)
    check_aliases_and_add_default_value!(dict, dict_copy, [:fixpoint_check], :eager)
    check_aliases_and_add_default_value!(dict, dict_copy, [:n], nothing)
    check_aliases_and_add_default_value!(dict, dict_copy, [:transformation_matrix], nothing)
    check_aliases_and_add_default_value!(dict, dict_copy, [:plot_vars, :output_variables], [0, 1])
    check_aliases_and_add_default_value!(dict, dict_copy, [:ε_proj], Inf)
    check_aliases_and_add_default_value!(dict, dict_copy, [:set_type_proj], Hyperrectangle)

    # special option: T
    check_aliases!(dict, dict_copy, [:T, :time_horizon])

    # validate that all input keywords are recognized
    check_valid_option_keywords(dict)

    # validation
    for kv_pair in dict_copy
        key::Symbol = kv_pair.first
        value = kv_pair.second

        # define type/domain constraints for each known key
        domain_constraints = (v  ->  true)
        if key == :verbosity
            expected_type = Union{String, Int}
        elseif key == :logfile
            expected_type = String
        elseif key == :mode
            expected_type = String
            domain_constraints = (v::String  ->  v in ["reach", "check"])
            if value == "check" && dict_copy[:property] == nothing
                error("No property has been defined.")
            end
        elseif key == :property
            expected_type = Union{Nothing, Property, Dict{Int, <:Property}, Function, Dict{Int, <:Function}}
        elseif key == :T
            expected_type = Float64
            domain_constraints = (v::Float64  ->  v > 0.)
        elseif key == :ε_proj
            expected_type = Float64
            domain_constraints = (v  ->  v > 0.)
        elseif key == :set_type_proj
            expected_type = Union{Type{HPolygon}, Type{Hyperrectangle},
                                  Type{LazySets.Interval}}
        elseif key == :coordinate_transformation
            expected_type = String
            domain_constraints = (v::String  ->  v in ["", "schur"])
        elseif key == :projection_matrix
            expected_type = Union{AbstractMatrix, Nothing}
        elseif key == :project_reachset
            expected_type = Bool
        elseif key == :max_jumps
            expected_type = Int
            domain_constraints = (v::Int  ->  v >= -1)
        elseif key == :fixpoint_check
            expected_type = Symbol
            domain_constraints = (v::Symbol  ->  v in [:none, :eager, :lazy])
        elseif key == :clustering
            expected_type = Symbol
            domain_constraints = (v::Symbol  ->  v in [:chull, :none, :none_oa])
        elseif key == :plot_vars
            expected_type = Vector{Int}
            domain_constraints = (v::Vector{Int}  ->  length(v) == 2)
        elseif key == :n
            expected_type = Int
            domain_constraints = (v::Int  ->  v > 0)
        elseif key == :transformation_matrix
            expected_type = Any
        else
            error(get_unrecognized_key_message(key))
        end

        # check value type
        if !(value isa expected_type)
            error("Option :$key must be of '$expected_type' type.")
        end
        # check value domain constraints
        if !domain_constraints(value)
            error("$value is not a valid value for option :$key.")
        end
    end
    # ε-close approximation
    if dict_copy[:ε_proj] < Inf && dict_copy[:set_type_proj] != HPolygon
        throw(DomainError("ε-close approximation is only supported with the " *
                          "set type 'HPolygon'"))
    end

    return options_copy
end


text:
mutable struct Carray{T, N, S} <: AbstractArray{T, 1}
	mem::NTuple{S, UInt8}

	Carray{T, N, S}(::UndefInitializer) where {T, N, S} = new{T, N, S}()
end
Carray{T, N}(u::UndefInitializer) where {T, N} = Carray{T, N, sizeof(Carray{T, N})}(u)
Carray(::Type{T}, ::Val{N}) where {T, N} = Carray{T, N, sizeof(Carray{T, N})}

function (::Type{CA})() where {CA<:Carray}
	result = CA(undef)
	setfield!(result, :mem, map(zero, getfield(result, :mem)))
	return result
end

Base.zero(::Type{CA}) where {CA<:Union{Caggregate, Carray}} = CA()
Base.sizeof(::Type{CA}) where {T, N, CA<:Carray{T, N}} = sizeof(T)*N
Base.isequal(x::Carray, y::Carray) = length(x) == length(y) && all(i -> x[i] == y[i], eachindex(x))
Base.:(==)(x::Carray, y::Carray) = isequal(x, y)

function Ctypespec(::Type{CA}) where {T, N, CA<:Carray{T, N}}
	_fix(::Type{Tuple{typ}}) where {typ} = Tuple{Carray(typ, Val(N))}
	_fix(::Type{Tuple{typ, bits}}) where {typ, bits} = error("A Carray of a bit field is not supported")
	_fix(::Type{spec}) where {spec<:Ctypespec} = Ctypespec{Carray(type(spec), Val(N)), opaque(spec), strategy(spec), specification(spec)}
	return _fix(Ctypespec(eltype(CA)))
end

macro carray(exprs...) _carray(__module__, nothing, exprs...) end

function _carray(mod::Module, deps::Union{Vector{Pair{Symbol, Expr}}, Nothing}, expr::Expr)
	Base.is_expr(expr, :ref, 2) || error("Expected C array definition to be of the form `ElementType[N]`")

	isOuter = isnothing(deps)
	deps = isOuter ? Pair{Symbol, Expr}[] : deps
	expr.args[1] = _expand(mod, deps, expr.args[1])
	expr.args[2] = _expand(mod, deps, expr.args[2])
	def = :(Carray{$(expr.args[1]), $(expr.args[2]), sizeof(Carray{$(expr.args[1]), $(expr.args[2])})})

	return isOuter ? quote $(map(last, deps)...) ; $(def) end : def
end


text:
using Test

include("allergies.jl")

#canonical data
@testset "testing for single allergies" begin
    @testset "testing for eggs allergy" begin
        @test !allergic_to(0, "eggs")
        @test  allergic_to(1, "eggs")
        @test  allergic_to(3, "eggs")
        @test !allergic_to(2, "eggs")
        @test  allergic_to(255, "eggs")
    end

    @testset "testing for peanuts allergy" begin
        @test !allergic_to(0, "peanuts")
        @test  allergic_to(2, "peanuts")
        @test  allergic_to(7, "peanuts")
        @test !allergic_to(5, "peanuts")
        @test  allergic_to(255, "peanuts")
    end

    @testset "testing for shellfish allergy" begin
        @test !allergic_to(0, "shellfish")
        @test  allergic_to(4, "shellfish")
        @test  allergic_to(14, "shellfish")
        @test !allergic_to(10, "shellfish")
        @test  allergic_to(255, "shellfish")
    end

    @testset "testing for strawberries allergy" begin
        @test !allergic_to(0, "strawberries")
        @test  allergic_to(8, "strawberries")
        @test  allergic_to(28, "strawberries")
        @test !allergic_to(20, "strawberries")
        @test  allergic_to(255, "strawberries")
    end

    @testset "testing for tomatoes allergy" begin
        @test !allergic_to(0, "tomatoes")
        @test  allergic_to(16, "tomatoes")
        @test  allergic_to(56, "tomatoes")
        @test !allergic_to(40, "tomatoes")
        @test  allergic_to(255, "tomatoes")
    end

    @testset "testing for chocolate allergy" begin
        @test !allergic_to(0, "chocolate")
        @test  allergic_to(32, "chocolate")
        @test  allergic_to(112, "chocolate")
        @test !allergic_to(80, "chocolate")
        @test  allergic_to(255, "chocolate")
    end

    @testset "testing for pollen allergy" begin
        @test !allergic_to(0, "pollen")
        @test  allergic_to(64, "pollen")
        @test  allergic_to(224, "pollen")
        @test !allergic_to(160, "pollen")
        @test  allergic_to(255, "pollen")
    end

    @testset "testing for cats allergy" begin
        @test !allergic_to(0, "cats")
        @test  allergic_to(128, "cats")
        @test  allergic_to(192, "cats")
        @test !allergic_to(64, "cats")
        @test  allergic_to(255, "cats")
    end
end

@testset "testing the allergy_list" begin
        @testset "testing single allergies" begin
        @test allergy_list(0) == Set([])
        @test allergy_list(1) == Set(["eggs"])
        @test allergy_list(2) == Set(["peanuts"])
        @test allergy_list(8) == Set(["strawberries"])
    end

    @testset "testing for more allergies" begin
        @test allergy_list(3) == Set(["eggs", "peanuts"])
        @test allergy_list(5) == Set(["eggs", "shellfish"])
        @test allergy_list(248) == Set(["strawberries", "tomatoes", "chocolate", "pollen", "cats"])
        @test allergy_list(255) == Set(["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"])
        @test allergy_list(509) == Set(["eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"])
    end
end


text:
#=
This file is auto-generated. Do not edit.
=#

#! format: off

"""
    mutable struct AverageConverter <: Converter
        rated_voltage::Float64
        rated_current::Float64
        ext::Dict{String, Any}
        states::Vector{Symbol}
        n_states::Int
    end

Parameters of an average converter model

# Arguments
- `rated_voltage::Float64`: rated voltage, validation range: `(0, nothing)`
- `rated_current::Float64`: rated VA, validation range: `(0, nothing)`
- `ext::Dict{String, Any}`
- `states::Vector{Symbol}`
- `n_states::Int`: AverageConverter has no states
"""
mutable struct AverageConverter <: Converter
    "rated voltage"
    rated_voltage::Float64
    "rated VA"
    rated_current::Float64
    ext::Dict{String, Any}
    states::Vector{Symbol}
    "AverageConverter has no states"
    n_states::Int
end

function AverageConverter(rated_voltage, rated_current, ext=Dict{String, Any}(), )
    AverageConverter(rated_voltage, rated_current, ext, Vector{Symbol}(), 0, )
end

function AverageConverter(; rated_voltage, rated_current, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, )
    AverageConverter(rated_voltage, rated_current, ext, states, n_states, )
end

# Constructor for demo purposes; non-functional.
function AverageConverter(::Nothing)
    AverageConverter(;
        rated_voltage=0,
        rated_current=0,
        ext=Dict{String, Any}(),
    )
end

"""Get [`AverageConverter`](@ref) `rated_voltage`."""
get_rated_voltage(value::AverageConverter) = value.rated_voltage
"""Get [`AverageConverter`](@ref) `rated_current`."""
get_rated_current(value::AverageConverter) = value.rated_current
"""Get [`AverageConverter`](@ref) `ext`."""
get_ext(value::AverageConverter) = value.ext
"""Get [`AverageConverter`](@ref) `states`."""
get_states(value::AverageConverter) = value.states
"""Get [`AverageConverter`](@ref) `n_states`."""
get_n_states(value::AverageConverter) = value.n_states

"""Set [`AverageConverter`](@ref) `rated_voltage`."""
set_rated_voltage!(value::AverageConverter, val) = value.rated_voltage = val
"""Set [`AverageConverter`](@ref) `rated_current`."""
set_rated_current!(value::AverageConverter, val) = value.rated_current = val
"""Set [`AverageConverter`](@ref) `ext`."""
set_ext!(value::AverageConverter, val) = value.ext = val


text:
function solve_009()

    # Just gonna brute force this one!
    for a = 1:1000
        for b = 1:1000
            for c = 1:1000
                if a+b+c == 1000 && a^2 + b^2 == c^2
                    return (a,b,c)
                    break
                end
            end
        end
    end

end


text:
# Note that this script can accept some limited command-line arguments, run
# `julia build_tarballs.jl --help` to see a usage message.
using BinaryBuilder

name = "ROCmDeviceLibsDownloader"
version = v"2.2.0"

# Collection of sources required to download ROCm-Device-Libs
sources = [
    "http://repo.radeon.com/rocm/archive/apt_2.2.0.tar.bz2" =>
    "a0013c4b4282f6295cb3f34566b0f13e0db030bb39c4364430f4108d16782f97",

]

# Bash recipe for building across all platforms
script = raw"""
cd $WORKSPACE/srcdir
mv ./apt* apt/
mv apt/pool/main/r/rocm-device-libs/rocm-device-libs_0.0.1_amd64.deb .
ar x rocm-device-libs_0.0.1_amd64.deb
tar xf data.tar.gz
mv opt/rocm/lib/ ../destdir/

"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = [
    Linux(:x86_64, :glibc),
    Linux(:x86_64, :musl)
]

# The products that we will ensure are always built
products(prefix) = [
    # TODO: A better way to emulate a FolderProduct would be nice
    FileProduct(prefix, "lib/ockl.amdgcn.bc", :rocmdevlibdir),
]

# Dependencies that must be installed before this package can be built
dependencies = [

]

# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies)

max_stars_repo_name: JuliaGPU/ROCmDeviceLibsDownloader

max_issues_repo_name: JuliaGPU/ROCmDeviceLibsDownloader

max_forks_repo_name: JuliaGPU/ROCmDeviceLibsDownloader


text:
function tokenize(line)
    (if all(isdigit, m.match); parse(Int, m.match) else Symbol(m.match) end for m in eachmatch(r"[0-9]+|[^ ]", line))
end

function postfix(tokens, precedence = false)
    ops = Symbol[]
    rpn = Union{Symbol,Int}[]
    for t in tokens
        if t isa Integer
            push!(rpn, t)
        elseif t in (:+, :*)
            while !isempty(ops) && ops[end] != Symbol("(")
                if precedence && t == :+ && ops[end] == :*
                    break
                end
                push!(rpn, pop!(ops))
            end
            push!(ops, t)
        elseif t == Symbol("(")
            push!(ops, t)
        elseif t == Symbol(")")
            op = pop!(ops)
            while op != Symbol("(")
                push!(rpn, op)
                op = pop!(ops)
            end
        end
    end
    while !isempty(ops)
        push!(rpn, pop!(ops))
    end
    return rpn
end

function evaluate(rpn)
    stack = Int[]
    for t in rpn
        if t isa Integer
            push!(stack, t)
        elseif t == :+
            push!(stack, pop!(stack) + pop!(stack))
        elseif t == :*
            push!(stack, pop!(stack) * pop!(stack))
        end
    end
    return first(stack)
end

function shuntingyard(tokens; precedence = false)
    rpn = postfix(tokens, precedence)
    return evaluate(rpn)
end

lines = readlines("d18.in")
tokens = [tokenize(line) for line in lines]

p1 = map(t -> shuntingyard(t), tokens)
p2 = map(t -> shuntingyard(t; precedence=true), tokens)

println("P1: ", sum(p1))
println("P2: ", sum(p2))

max_stars_repo_name: eduellery/adventofcode

max_issues_repo_name: eduellery/adventofcode

max_forks_repo_name: eduellery/adventofcode


text:
using Unitful: @u_str, ustrip, uconvert, Unitful

const energy_unit = u"kJ/mol" / Unitful.Na

# Energies converted to eV, distances in Angstrom, forces in eV/Angstrom.

const A₀ = ustrip(uconvert(u"eV", 457095 * energy_unit))
const α₀ = 3.7594
const B₀ = ustrip(uconvert(u"eV", 30707 * energy_unit))
const β₀ = 3.0082
const F₀ = ustrip(uconvert(u"eV", 638.5 * energy_unit))
const γ₀ = 2.743
const r₀NO = 1.15077

const A₁ = A₀
const α₁ = α₀
const B₁ = ustrip(uconvert(u"eV", 24.056 * energy_unit))
const β₁ = 1.9649
const r₁AuN = 2.3491
const D = ustrip(uconvert(u"eV", 347.22 * energy_unit))
const C = 1.2423
const zimage = 1.1536
const F₁ = ustrip(uconvert(u"eV", 495.98 * energy_unit))
const γ₁ = 2.4890
const r₁NO = 1.2904
const ϕ = ustrip(uconvert(u"eV", 511.37 * energy_unit))
const Eₐ = ustrip(uconvert(u"eV", -0.67540 * energy_unit))

const A₂ = ustrip(uconvert(u"eV", 11.842 * energy_unit))
const A₃ = 0.0061803
const γ₂ = 1.3693
const B₂ = ustrip(uconvert(u"eV", 50 * energy_unit))
const B₃ = 0.0047213
const γ₃ = 2.0194

const α = ustrip(uconvert(u"eV*Å^-2", -4.94u"N/m"))
const β = ustrip(uconvert(u"eV*Å^-2", 17.15u"N/m"))
const γ = ustrip(uconvert(u"eV*Å^-2", 19.40u"N/m"))

const rcutoff = 10.0

const D1 = SMatrix{3,3}([α 0 0;
                         0 β γ;
                         0 γ β])
const D2 = SMatrix{3,3}([α 0 0;
                         0 β -γ;
                         0 -γ β])
const D3 = SMatrix{3,3}([β 0 γ;
                         0 α 0;
                         γ 0 β])
const D4 = SMatrix{3,3}([β 0 -γ;
                         0 α 0;
                         -γ 0 β])
const D5 = SMatrix{3,3}([β γ 0;
                         γ β 0;
                         0 0 α])
const D6 = SMatrix{3,3}([β -γ 0;
                         -γ β 0;
                         0 0 α])
const force_tensors = [D1, D2, D3, D4, D5, D6,
                       D1, D2, D3, D4, D5, D6]

const one = SVector{3}(0, 1, 1) * 2.04
const two = SVector{3}(0, 1, -1) * 2.04
const three = SVector{3}(1, 0, 1) * 2.04
const four = SVector{3}(-1, 0, 1) * 2.04
const five = SVector{3}(1, 1, 0) * 2.04
const six = SVector{3}(1, -1, 0) * 2.04
const direction_vectors = [one, two, three, four, five, six,
                          -one,-two,-three,-four,-five,-six]


text:
include("regression.jl")
include("classification.jl")
include("multiclass.jl")
include("event.jl")
include("generic_likelihood.jl")
function pdf(l::Likelihood{T},y::Real,f::Real) where T
    @error "pdf not implemented"
end

@inline logpdf(l::Likelihood{T},y::Real,f::Real) where T = log(pdf(l,y,f))

isaugmented(::Likelihood) = false

Base.length(::Likelihood) = 1

Base.iterate(l::Likelihood) = (l,nothing)
Base.iterate(l::Likelihood, ::Any) = nothing


text:
import Base.size
import Base.convert
import Distributions.dim
import LinearAlgebra.norm

export Lattice
export dim, size, sites, bonds, numsites, numbonds, neighbors, neighborsites, neighborbonds
export source, target, sitetype, bondtype
export sitecoordinate, bonddirection, cellcoordinate

mutable struct Site
    id :: Int
    sitetype :: Int
    neighborsites :: Vector{Int}
    neighborbonds :: Vector{Int}
    coord :: Vector{Float64}
    localsite :: Int
    cellcoord :: Vector{Int}
end
convert(::Type{Int}, s::Site) = s.id

mutable struct Bond
    id :: Int
    bondtype :: Int
    source :: Int
    target :: Int
    direction :: Vector{Float64}
end
convert(::Type{Int}, b::Bond) = b.id

mutable struct Lattice
    latticevector :: Matrix{Float64}
    L :: Vector{Int}
    sites :: Vector{Site}
    siteswithtype :: Vector{SubArray{Site,1,Vector{Site},Tuple{Vector{Int}},false}}
    bonds :: Vector{Bond}
    bondswithtype :: Vector{SubArray{Bond,1,Vector{Bond},Tuple{Vector{Int}},false}}

    function Lattice(latvec,L,sites,bonds)
        nsitetypes = 0
        swt = Vector{Int}[]
        for s in sites
            st = s.sitetype
            while st > nsitetypes
                push!(swt, Int[])
                nsitetypes += 1
            end
            push!(swt[st], s.id)
        end
        siteswithtype = [view(sites, swt[st]) for st in 1:nsitetypes]

        nbondtypes = 0
        bwt = Vector{Int}[]
        for b in bonds
            bt = b.bondtype
            while bt > nbondtypes
                push!(bwt, Int[])
                nbondtypes += 1
            end
            push!(bwt[bt], b.id)

            push!(sites[source(b)].neighborsites, target(b))
            push!(sites[source(b)].neighborbonds, b.id)
            push!(sites[target(b)].neighborsites, source(b))
            push!(sites[target(b)].neighborbonds, b.id)
        end
        bondswithtype = [view(bonds, bwt[bt]) for bt in 1:nbondtypes]

        return new(latvec, L,
                   sites, siteswithtype,
                   bonds, bondswithtype,
                  )
    end
end

@doc """
    dim(lat::Lattice)
    dim(model::Model)

Returns the dimension of lattice.
"""
@inline dim(lat::Lattice) = size(lat.latticevector,1)
@inline dim(model::Model) = dim(model.lat)

@doc """
    size(lat::Lattice, [dim::Integer])
    size(model::Model, [dim::Integer])

Returns the size of lattice.
"""
@inline size(lat::Lattice) = lat.L
@inline size(lat::Lattice, dim::Integer) = size(lat)[dim]
@inline size(model::Model) = size(model.lat)
@inline size(model::Model, dim::Integer) = size(model.lat,dim)

@doc """
    sites(lat::Lattice, [sitetype::Integer])
    sites(model::Model, [sitetype::Integer])

Returns an iterator over sites with `sitetype` (if omitted, over all sites)
"""
@inline sites(lat::Lattice) = lat.sites
@inline sites(model::Model) = sites(model.lat)
@inline sites(lat::Lattice, sitetype::Integer) = lat.siteswithtype[sitetype]
@inline sites(model::Model, sitetype::Integer) = sites(model.lat, sitetype)

@doc """
    numsites(lat::Lattice)
    numsites(model::Model)

Returns the number of all sites.
"""
@inline numsites(lat::Lattice) = length(lat.sites)
@inline numsites(model::Model) = numsites(model.lat)

@doc """
    numsites(lat::Lattice, sitetype::Integer)
    numsites(model::Model, sitetype::Integer)

Returns the number of `sitetype` sites.
"""
@inline numsites(lat::Lattice, sitetype::Integer) = length(lat.siteswithtype[sitetype])
@inline numsites(model::Model, sitetype::Integer) = numsites(model.lat, sitetype)

@doc """
    bonds(lat::Lattice, [bondtype::Integer])
    bonds(model::Model, [bondtype::Integer])

Returns an iterator over bonds with `bondtype` (if omitted, over all bonds)
"""
@inline bonds(lat::Lattice) = lat.bonds
@inline bonds(model::Model) = bonds(model.lat)
@inline bonds(lat::Lattice, bondtype::Integer) = lat.bondswithtype[bondtype]
@inline bonds(model::Model, bondtype::Integer) = bonds(model.lat, bondtype)

@doc """
    numbonds(lat::Lattice)
    numbonds(model::Model)

Returns the number of all bonds.
"""
@inline numbonds(lat::Lattice) = length(lat.bonds)
@inline numbonds(model::Model) = numbonds(model.lat)

@doc """
    numbonds(lat::Lattice, bondtype::Integer)
    numbonds(model::Model, bondtype::Integer)

Returns the number of `bondtype` bonds.
"""
@inline numbonds(lat::Lattice, bondtype::Integer) = length(lat.bondswithtype[bondtype])
@inline numbonds(model::Model, bondtype::Integer) = numbonds(model.lat, bondtype)

@doc """
    numsitetypes(lat::Lattice)
    numsitetypes(model::Model)

Returns the number of sitetypes.
"""
@inline numsitetypes(lat::Lattice) = length(lat.siteswithtype)
@inline numsitetypes(model::Model) = numsitetypes(model.lat)

@doc """
    numbondtypes(lat::Lattice)
    numbondtypes(model::Model)

Returns the number of bondtypes.
"""
@inline numbondtypes(lat::Lattice) = length(lat.bondswithtype)
@inline numbondtypes(model::Model) = numbondtypes(model.lat)

@doc """
    neighborsites(site::Site)
    neighborsites(lat::Lattice, site::Integer)
    neighborsites(model::Model, site::Integer)

Returns the indecies of neighbor sites of `site`.
"""
@inline neighborsites(site::Site) = site.neighborsites
@inline neighborsites(lat::Lattice, site::Integer) = neighborsites(lat.sites[site])
@inline neighborsites(model::Model, site::Integer) = neighborsites(model.lat, site)

@doc """
    neighborbonds(site::Site)
    neighborbonds(lat::Lattice, site::Integer)
    neighborbonds(model::Model, site::Integer)

Returns the indecies of neighbor bonds of `site`.
"""
@inline neighborbonds(site::Site) = site.neighborbonds
@inline neighborbonds(lat::Lattice, site::Integer) = neighborbonds(lat.sites[site])
@inline neighborbonds(model::Model, site::Integer) = neighborbonds(model.lat, site)

@doc """
    neighbors(site::Site)
    neighbors(lat::Lattice, site::Integer)
    neighbors(model::Model, site::Integer)

Returns the index pairs of neighbor sites and bonds of `site`.
"""
@inline neighbors(site::Site) = zip(site.neighborsites, site.neighborbonds)
@inline neighbors(lat::Lattice, site::Integer) = neighbors(lat.sites[site])
@inline neighbors(model::Model, site::Integer) = neighbors(model.lat, site)

@doc """
    source(bond::Bond)
    source(lat::Lattice, bond::Integer)
    source(model::Model, bond::Integer)

Returns the source site index of `bond`.
"""
@inline source(bond::Bond) = bond.source
@inline source(lat::Lattice, bond::Integer) = source(lat.bonds[bond])
@inline source(model::Model, bond::Integer) = source(model.lat, bond)

@doc """
    target(bond::Bond)
    target(lat::Lattice, bond::Integer)
    target(model::Model, bond::Integer)

Returns the target site of `bond`.
"""
@inline target(bond::Bond) = bond.target
@inline target(lat::Lattice, bond::Integer) = target(lat.bonds[bond])
@inline target(model::Model, bond::Integer) = target(model.lat, bond)

@doc """
    sitecoordinate(site::Site)
    sitecoordinate(lat::Lattice, site::Integer)
    sitecoordinate(model::Model, site::Integer)

Returns the coordinate of the `site` in the Cartesian system
"""
@inline sitecoordinate(site::Site) = site.coord
@inline sitecoordinate(lat::Lattice, site::Integer) = sitecoordinate(lat.sites[site])
@inline sitecoordinate(model::Model, site::Integer) = sitecoordinate(model.lat, site)

@doc """
    cellcoordinate(site::Site)
    cellcoordinate(lat::Lattice, site::Integer)
    cellcoordinate(model::Model, site::Integer)

Returns the coordinate of the `cell` including `site` in the Lattice system
"""
@inline cellcoordinate(site::Site) = site.cellcoord
@inline cellcoordinate(lat::Lattice, site::Integer) = cellcoordinate(lat.sites[site])
@inline cellcoordinate(model::Model, site::Integer) = cellcoordinate(model.lat, site)

@doc """
    sitetype(site::Site)
    sitetype(lat::Lattice, site::Integer)
    sitetype(model::Model, site::Integer)

Returns the type of `site`
"""
@inline sitetype(site::Site) = site.sitetype
@inline sitetype(lat::Lattice, site::Integer) = sitetype(lat.sites[site])
@inline sitetype(model::Model, site::Integer) = sitetype(model.lat, site)

@doc """
    bondtype(bond::Bond)
    bondtype(lat::Lattice, bond::Integer)
    bondtype(model::Model, bond::Integer)

Returns the type of `bond`.
"""
@inline bondtype(bond::Bond) = bond.bondtype
@inline bondtype(lat::Lattice, bond::Integer) = bondtype(lat.bonds[bond])
@inline bondtype(model::Model, bond::Integer) = bondtype(model.lat, bond)

@doc """
    bonddirection(bond::Bond)
    bonddirection(lat::Lattice, bond::Integer)
    bonddirection(model::Model, bond::Integer)

Returns the unnormalized direction of the `bond` as vector in the Cartesian system
"""
bonddirection(bond::Bond) = bond.direction
bonddirection(lat::Lattice, bond::Integer) = bonddirection(lat.bonds[bond])
bonddirection(model::Model, bond::Integer) = bonddirection(model.lat, bond)


text:
module MetaGraphsNext
using LightGraphs
using JLD2

import Base:
    eltype,
    show,
    ==,
    Tuple,
    copy,
    length,
    size,
    issubset,
    zero,
    getindex,
    haskey,
    setindex!,
    delete!

import LightGraphs:
    AbstractGraph,
    edgetype,
    nv,
    ne,
    vertices,
    edges,
    is_directed,
    add_vertex!,
    add_edge!,
    rem_vertex!,
    rem_edge!,
    has_vertex,
    has_edge,
    inneighbors,
    outneighbors,
    weights,
    induced_subgraph,
    loadgraph,
    savegraph,
    AbstractGraphFormat,
    reverse

import LightGraphs.SimpleGraphs: SimpleGraph, SimpleDiGraph, fadj, badj

export MetaGraph, weighttype, defaultweight, weightfunction, MGFormat, DOTFormat, reverse

include("metagraph.jl")

function show(
    io::IO,
    g::MetaGraph{<:Any,Label,<:Any,VertexMeta,EdgeMeta},
) where {Label,VertexMeta,EdgeMeta}
    print(
        io,
        "Meta graph based on a $(g.graph) with vertices indexed by $Label(s), $VertexMeta(s) vertex metadata, $EdgeMeta(s) edge metadata, $(repr(g.gprops)) as graph metadata, and default weight $(g.defaultweight)",
    )
end

@inline fadj(g::MetaGraph, x...) = fadj(g.graph, x...)
@inline badj(g::MetaGraph, x...) = badj(g.graph, x...)

eltype(g::MetaGraph) = eltype(g.graph)
edgetype(g::MetaGraph) = edgetype(g.graph)
nv(g::MetaGraph) = nv(g.graph)
vertices(g::MetaGraph) = vertices(g.graph)

ne(g::MetaGraph) = ne(g.graph)
edges(g::MetaGraph) = edges(g.graph)

has_vertex(g::MetaGraph, x...) = has_vertex(g.graph, x...)
@inline has_edge(g::MetaGraph, x...) = has_edge(g.graph, x...)

inneighbors(g::MetaGraph, v::Integer) = inneighbors(g.graph, v)
outneighbors(g::MetaGraph, v::Integer) = fadj(g.graph, v)

issubset(g::T, h::T) where {T<:MetaGraph} = issubset(g.graph, h.graph)

"""
    add_edge!(g, u, v, val)

Add an edge `(u, v)` to MetaGraph `g` having value `val`.

Return true if the edge has been added, false otherwise.
"""
function add_edge!(g::MetaGraph, u::Integer, v::Integer, val)
    added = add_edge!(g.graph, u, v)
    if added
        metaindex = g.metaindex
        g.eprops[arrange(g, metaindex[u], metaindex[v], u, v)] = val
    end
    added
end

@inline function rem_edge!(g::MetaGraph, u::Integer, v::Integer)
    metaindex = g.metaindex
    removed = rem_edge!(g.graph, u, v)
    if removed
        delete!(g.eprops, arrange(g, metaindex[u], metaindex[v], u, v))
    end
    removed
end

"""
    add_vertex!(g, label, val)

Add a vertex to MetaGraph `g` with label `label` having value `val`.

Return true if the vertex has been added, false otherwise.
"""
function add_vertex!(g::MetaGraph, label, val)
    added = add_vertex!(g.graph)
    if added
        v = nv(g)
        g.vprops[label] = (v, val)
        g.metaindex[v] = label
    end
    added
end

function _rem_vertex!(g, label, v)
    vprops = g.vprops
    eprops = g.eprops
    metaindex = g.metaindex
    lastv = nv(g)
    for n in outneighbors(g, v)
        delete!(eprops, arrange(g, label, metaindex[n], v, n))
    end
    for n in inneighbors(g, v)
        delete!(eprops, arrange(g, metaindex[n], label, n, v))
    end
    removed = rem_vertex!(g.graph, v)
    if removed
        if v != lastv # ignore if we're removing the last vertex.
            lastl = metaindex[lastv]
            _, lastvprops = vprops[lastl]
            vprops[lastl] = v, lastvprops
            metaindex[v] = lastl
        end
        delete!(vprops, label)
        delete!(metaindex, lastv)
    end
    removed
end

function rem_vertex!(g::MetaGraph, v::Integer)
    exists = has_vertex(g, v)
    if exists
        _rem_vertex!(g, g.metaindex[v], v)
    else
        false
    end
end

struct MetaWeights{InnerMetaGraph,U<:Real} <: AbstractMatrix{U}
    meta_graph::InnerMetaGraph
end

show(io::IO, x::MetaWeights) = print(io, "metaweights")
show(io::IO, z::MIME"text/plain", x::MetaWeights) = show(io, x)

MetaWeights(g::MetaGraph) = MetaWeights{typeof(g),weighttype(g)}(g)

function getindex(w::MetaWeights, u::Int, v::Int)
    g = w.meta_graph
    metaindex = g.metaindex
    if has_edge(g, u, v)
        g.weightfunction(g[arrange(g, metaindex[u], metaindex[v], u, v)...])
    else
        g.defaultweight
    end
end

function size(d::MetaWeights)
    vertices = nv(d.meta_graph)
    (vertices, vertices)
end

weights(g::MetaGraph) = MetaWeights(g)

getindex(g::MetaGraph) = g.gprops
function getindex(g::MetaGraph, label)
    _, val = g.vprops[label]
    val
end
getindex(g::MetaGraph, label_1, label_2) = g.eprops[arrange(g, label_1, label_2)]

"""
    haskey(g, :label)

Determine whether a graph `g` contains the vertex `:label`.

```jldoctest; setup = :(using MetaGraphsNext; using LightGraphs: Graph)
julia> colors = MetaGraph(Graph(), VertexMeta = String, EdgeMeta = Symbol, gprops = "special");

julia> colors[:red] = "warm";

julia> haskey(colors, :red)
true

julia> haskey(colors, :blue)
false
```
"""
haskey(g::MetaGraph, label) = haskey(g.vprops, label)

"""
    haskey(g, :v1, :v2)

Determine whether a graph `g` contains an edge from `:v1` to `:v2`. The order of `:v1` and `:v2`
only matters if `g` is a digraph.

```jldoctest; setup = :(using MetaGraphsNext; using LightGraphs: Graph)
julia> colors = MetaGraph(Graph(), VertexMeta = String, EdgeMeta = Symbol, gprops = "special");

julia> colors[:red] = "warm"; colors[:blue] = "cool"; colors[:red, :blue] = :purple
:purple

julia> haskey(colors, :red, :blue) && haskey(colors, :blue, :red)
true

julia> haskey(colors, :red, :yellow)
false
```
"""
haskey(g::MetaGraph, label_1, label_2) = haskey(g, label_1) && haskey(g, label_2) && haskey(g.eprops, arrange(g, label_1, label_2))

function setindex!(g::MetaGraph, val, label)
    vprops = g.vprops
    v = if haskey(vprops, label)
        (v, _) = vprops[label]
        v
    else
        add_vertex!(g.graph)
        v = nv(g)
        g.metaindex[v] = label
        v
    end
    vprops[label] = (v, val)
    return nothing
end

function setindex!(g::MetaGraph, val, label_1, label_2)
    vprops = g.vprops
    u, _ = vprops[label_1]
    v, _ = vprops[label_2]
    add_edge!(g.graph, u, v)
    g.eprops[arrange(g, label_1, label_2, u, v)] = val
    return nothing
end

function delete!(g::MetaGraph, label)
    if haskey(g, label)
        v, _ = g.vprops[label]
        _rem_vertex!(g, label, v)
    end
    return nothing
end
function delete!(g::MetaGraph, label_1, label_2)
    vprops = g.vprops
    u, _ = vprops[label_1]
    v, _ = vprops[label_2]
    rem_edge!(g.graph, u, v)
    delete!(g.eprops, arrange(g, label_1, label_2, u, v))
    return nothing
end

"""
    weighttype(g)

Return the weight type for metagraph `g`.

```jldoctest
julia> using MetaGraphsNext

julia> using LightGraphs: Graph

julia> weighttype(MetaGraph(Graph(), defaultweight = 1.0))
Float64
```
"""
weighttype(g::MetaGraph{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,Weight}) where {Weight} =
    Weight

"""
    weightfunction(g)

Return the weight function for metagraph `g`.

```jldoctest
julia> using MetaGraphsNext

julia> using LightGraphs: Graph

julia> weightfunction(MetaGraph(Graph(), weightfunction = identity))(0)
0
```
"""
weightfunction(g::MetaGraph) = g.weightfunction

"""
    defaultweight(g)

Return the default weight for metagraph `g`.

```jldoctest
julia> using MetaGraphsNext

julia> using LightGraphs: Graph

julia> defaultweight(MetaGraph(Graph(), defaultweight = 2))
2
```
"""
defaultweight(g::MetaGraph) = g.defaultweight

function _copy_props!(oldg::T, newg::T, vmap) where {T<:MetaGraph}
    for (newv, oldv) in enumerate(vmap)
        oldl = oldg.metaindex[oldv]
        _, meta = oldg.vprops[oldl]
        newg.metaindex[newv] = oldl
        newg.vprops[oldl] = (newv, meta)
    end
    for newe in edges(newg.graph)
        metaindex = newg.metaindex
        u, v = Tuple(newe)
        label_1 = metaindex[u]
        label_2 = metaindex[v]
        newg.eprops[arrange(newg, label_1, label_2, u, v)] =
            oldg.eprops[arrange(oldg, label_1, label_2)]
    end
    return nothing
end

function induced_subgraph(
    g::T,
    v::AbstractVector{U},
) where {T<:MetaGraph} where {U<:Integer}
    inducedgraph, vmap = induced_subgraph(g.graph, v)
    newg = MetaGraph(
        inducedgraph,
        empty(g.vprops),
        empty(g.eprops),
        g.gprops,
        g.weightfunction,
        g.defaultweight,
        empty(g.metaindex),
    )
    _copy_props!(g, newg, vmap)
    return newg, vmap
end

# TODO - would be nice to be able to apply a function to properties. Not sure
# how this might work, but if the property is a vector, a generic way to append to
# it would be a good thing.

==(x::MetaGraph, y::MetaGraph) = x.graph == y.graph

copy(g::T) where {T<:MetaGraph} = deepcopy(g)

"""
    code_for(meta::MetaGraph, vertex_label)

Find the code associated with a `vertex_label`. This can be useful to pass
to methods inherited from `LightGraphs`. Note, however, that vertex codes could be
reassigned after vertex deletion.

```jldoctest
julia> using MetaGraphsNext

julia> using LightGraphs: Graph

julia> meta = MetaGraph(Graph());

julia> meta[:a] = nothing

julia> code_for(meta, :a)
1
```
"""
function code_for(meta::MetaGraph, vertex_label)
    code, _ = meta.vprops[vertex_label]
    code
end
export code_for

"""
    label_for(meta::MetaGraph, vertex_code)

Find the label associated with a `vertex_code`. This can be useful to interpret the results of methods
inherited from `LightGraphs`. Note, however, that vertex codes could be reassigned after vertex deletion.

```jldoctest
julia> using MetaGraphsNext

julia> using LightGraphs: Graph

julia> meta = MetaGraph(Graph());

julia> meta[:a] = nothing

julia> label_for(meta, 1)
:a
```
"""
function label_for(meta::MetaGraph, vertex_code)
    meta.metaindex[vertex_code]
end
export label_for

include("metadigraph.jl")
include("overrides.jl")
include("persistence.jl")

end # module


text:
## Copyright (c) 2018 Miguel Bazdresch
##
## This file is distributed under the 2-clause BSD License.

# Calculate the path loss using the Okumura-Hata model.
# References:
#   Hata, M, "Empirical Formula for Propagation Loss in Land Mobile Radio
#   Services", IEEE Transactions on Vehicular Technology, August 1980,
#   pp. 317–325.
#
#   Wikipedia: https://en.wikipedia.org/wiki/Hata_model

module OkumuraHata

using NumericIO

export loss_oh

struct LossOH
    large_city :: Float64
    small_city :: Float64
    suburban   :: Float64
    rural      :: Float64
end

function Base.getindex(l::LossOH, i::Symbol)
    i == :large_city && return l.large_city
    i == :small_city && return l.small_city
    i == :suburban && return l.suburban
    i == :rural && return l.rural
end

function Base.show(io::IO, l::LossOH)
    f(x) = formatted(x, :SI, ndigits=5, charset=:ASCII)

    println("Losses according to Okumura-Hata model (all in dB):")
    println("  Loss in large city:    ", f(l.large_city))
    println("  Loss in small city:    ", f(l.small_city))
    println("  Loss in suburban area: ", f(l.suburban))
    println("  Loss in rural area:    ", f(l.rural))
end

"""
loss_oh(f, d, hb, hm)

Calculate the path loss according to the Okumura-Hata model.

  f is the carrier frequency in MHz, in the range 150 <= f <= 1500
  d is the distance between base station and mobile in km; 1 <= d <= 10
  hb is the base station antenna height in m; 30 <= hb <= 200
  hm is the mobile antenna height in m; 1 <= hm <= 10

The loss in decibels is calculated for large cities, small cities,
suburban areas and rural areas.

Returns the four calculated losses in a struct of type LossOH, which can be
accessed by property name (`loss.small_city`) or by indexing
(`loss[:suburban]`).
"""
function loss_oh(f, d, hb, hm)

    (150 <= f <= 1500) || error("Invalid frequency f = $f: must be in range [150, 1500]")
    (1 <= d <= 10) || error("Invalid distance d = $d: must be in rage [1,10]")
    (30 <= hb <= 200) || error("Invalid base station antenna height hb = $hb: must be in range [30,200]")
    (1 <= hm <= 10) || error("Invalid mobile station antenna height hm = $hm: must be in range [1,10]")

    Ch_small = 0.8 + hm*(1.1log10(f)-0.7) - 1.56log10(f)
    if 150 <= f <= 200
        Ch_large = 8.29*(log10(1.54hm))^2 - 1.1
    else
        Ch_large = 3.2*(log10(11.75hm))^2 - 4.97
    end

    Lu = 69.55 + 26.16log10(f) - 13.82log10(hb) + log10(d)*(44.9-6.55log10(hb))

    Lu_large = Lu - Ch_large
    Lu_small = Lu - Ch_small
    Lu_suburban = Lu_small - 2*(log10(f/28)^2) - 5.4
    Lu_rural = Lu_small - 4.78*(log10(f)^2) + 18.33log10(f) - 40.94

    return LossOH(Lu_large, Lu_small, Lu_suburban, Lu_rural)

end

end

max_stars_repo_name: mbaz/OkumuraHata

max_issues_repo_name: mbaz/OkumuraHata

max_forks_repo_name: mbaz/OkumuraHata


text:
function hello(args::Dict)
  hello()
end

function hello()
  println("Hello, World!")
end


text:
tmp_file = tempname()
@testset "write_opf: read, write, read again and compare -> simple_plant" begin
    mtg = read_opf("files/simple_plant.opf", Dict)
    PlantGeom.write_opf(tmp_file, mtg)
    mtg2 = read_opf(tmp_file, Dict)
    # Compare each node one by one:
    @test traverse(mtg, node -> node) == traverse(mtg2, node -> node)
end

@testset "write_opf: read, write, read again and compare -> coffee" begin
    mtg = read_opf("files/coffee.opf", Dict)
    PlantGeom.write_opf(tmp_file, mtg)
    mtg2 = read_opf(tmp_file, Dict)
    # Compare each node one by one:
    @test traverse(mtg, node -> node) == traverse(mtg2, node -> node)
end


text:
function linsolve(A, b)
    x = similar(b)

    for k in lastindex(b):-1:firstindex(b)
        x[k] = (b[k] - sum(A[k, k+1:lastindex(A, 2)].*x[k+1:lastindex(x)]))/A[k,k]
    end

    return x
end


text:
module LatBo

export SandBox, run!, geometry, index, gridcoords, LB, Playground, Units
export velocity, momentum, density

# Type defining the feature of the simulation playground
abstract Simulation{T <: AbstractFloat, I <: Int}
abstract AbstractLattice

include("indices/indices.jl")
include("playground.jl")
include("units.jl")

include("geometry.jl")
include("lb/lb.jl")

importall .Indices
using .LB
using .Units

include("sandbox.jl")

# Runs lattice boltzmann for single step
function run!(observer::Function, sim::Simulation;
    doinit::Bool=true, nsteps::Integer=1, kernel=LB.local_kernel)
    # First initializes lattice
    if doinit
        LB.initialize(sim)
    end
    # Then run for N steps
    for step in 1:nsteps
        # run local kernel for each site
        kernel(sim)
        # swap populations
        sim.populations, sim.next_populations = sim.next_populations, sim.populations
        # run observer at each step
        observer()
    end
end

# Run simulation for N numbers of steps without observing
run!(sim::Simulation; kwargs...) = run!(()->nothing, sim; kwargs...)

include("setups.jl")

end # module


text:
# Bhattacharyya distances. Much like for KLDivergence we assume the vectors to
# be compared are probability distributions, frequencies or counts rather than
# vectors of samples. Pre-calc accordingly if you have samples.

struct BhattacharyyaDist <: SemiMetric end

struct HellingerDist <: Metric end

# Bhattacharyya coefficient

function bhattacharyya_coeff(a::AbstractVector{T}, b::AbstractVector{T}) where {T <: Number}
    if length(a) != length(b)
        throw(DimensionMismatch("first array has length $(length(a)) which does not match the length of the second, $(length(b))."))
    end

    n = length(a)
    sqab = zero(T)
    # We must normalize since we cannot assume that the vectors are normalized to probability vectors.
    asum = zero(T)
    bsum = zero(T)

    @simd for i = 1:n
        @inbounds ai = a[i]
        @inbounds bi = b[i]
        sqab += sqrt(ai * bi)
        asum += ai
        bsum += bi
    end

    sqab / sqrt(asum * bsum)
end

bhattacharyya_coeff(a::T, b::T) where {T <: Number} = throw("Bhattacharyya coefficient cannot be calculated for scalars")

# Faster pair- and column-wise versions TBD...

# Bhattacharyya distance
evaluate(dist::BhattacharyyaDist, a::AbstractVector{T}, b::AbstractVector{T}) where {T <: Number} = -log(bhattacharyya_coeff(a, b))
bhattacharyya(a::AbstractVector, b::AbstractVector) = evaluate(BhattacharyyaDist(), a, b)
evaluate(dist::BhattacharyyaDist, a::T, b::T) where {T <: Number} = throw("Bhattacharyya distance cannot be calculated for scalars")
bhattacharyya(a::T, b::T) where {T <: Number} = evaluate(BhattacharyyaDist(), a, b)

# Hellinger distance
evaluate(dist::HellingerDist, a::AbstractVector{T}, b::AbstractVector{T}) where {T <: Number} = sqrt(1 - bhattacharyya_coeff(a, b))
hellinger(a::AbstractVector, b::AbstractVector) = evaluate(HellingerDist(), a, b)
evaluate(dist::HellingerDist, a::T, b::T) where {T <: Number} = throw("Hellinger distance cannot be calculated for scalars")
hellinger(a::T, b::T) where {T <: Number} = evaluate(HellingerDist(), a, b)


text:
# Load the shape file
mexicopath = joinpath(testdatapath, "shape_eg_data", "mexico")
states = open_shapefile(joinpath(mexicopath, "states.shp"))

# Create plots and test whether they output a Compose.Context (i.e. check if they run)

# Create choropleth with random colors and test that it returns a Compose.Context type
num_shapes = length(states.shapes)
canvas = choropleth(states.shapes, rand(num_shapes), colormap("blues"), transform=log)
test = (typeof(canvas) == Compose.Context)


text:
using Test

@testset "Testing Lab 5" begin
   include("test1.jl")
   include("test2.jl")
   #include("test3.jl")
end;