text:
push!(LOAD_PATH,"../src/")

using Documenter
using DocumenterTools
using ExactDiagonalization

makedocs(
    format=     Documenter.HTML(
                    prettyurls= !("local" in ARGS),
                    canonical=  "https://quantum-many-body.github.io/ExactDiagonalization.jl/latest/",
                    assets=     ["assets/favicon.ico"],
                    analytics=  "UA-89508993-1",
                    ),
    clean=      false,
    sitename=   "ExactDiagonalization.jl",
    pages=      [
                "Home"      =>  "index.md",
                "Manul"     =>  [
                    "man/FED.md",
                    ]
                ]
)

deploydocs(
    repo=       "github.com/Quantum-Many-Body/ExactDiagonalization.jl.git",
    target=     "build",
    deps=       nothing,
    make=       nothing,
)


text:
__precompile__()
module Interleave

using SeqHax.Utils
using ArgParse

function add_join_args(argparser)
    add_common_args(argparser["join"])
    @add_arg_table argparser["join"] begin
        "--r1", "-f"
            help = "R1 read file"
            required = true
            arg_type = String
        "--r2", "-r"
            help = "R1 read file"
            required = true
            arg_type = String
        "--il", "-i"
            help = "Interleaved read file (default stdout)"
            arg_type = String
            default = "-"
        "--force"
            help = "Force overwriting output file(s)"
            action = :store_true
        "--zip", "-z"
            help = "GZip compression level"
            default = 0
            arg_type = Int
            required = false
    end
end

function join_main(args)
    r1f = args["r1"]
    r2f = args["r2"]
    ilf = args["il"]
    ziplvl = clamp(args["zip"], 0, 9)

    if isfile(ilf) && !args["force"]
        println(STDERR, "Output file exists. Refusing to overwrite it.")
        println(STDERR, "(NB, you're joining R1/R2 to '$ilf')")
        println(STDERR, "Use '--force' to force overwriting")
        return 1
    end
    ilout = open_zipped(ilf, "w", ziplvl)

    npair = foreach_seqpair(r1f, r2f) do idx, r1, r2
        write(ilout, r1)
        write(ilout, r2)
    end
end

function add_split_args(argparser)
    add_common_args(argparser["split"])
    @add_arg_table argparser["split"] begin
        "--il", "-i"
            help = "Interleaved read file"
            required = true
            arg_type = String
        "--r1", "-f"
            help = "R1 read file"
            required = true
            arg_type = String
        "--r2", "-r"
            help = "R1 read file"
            required = true
            arg_type = String
        "--force"
            help = "Force overwriting output file(s)"
            action = :store_true
        "--zip", "-z"
            help = "GZip compression level"
            default = 0
            arg_type = Int
            required = false
    end
end

function split_main(args)
    r1f = args["r1"]
    r2f = args["r2"]
    ilf = args["il"]
    ziplvl = clamp(args["zip"], 0, 9)
    if (isfile(r1f) || isfile(r2f)) && !args["force"]
        println(STDERR, "Output files exist. Refusing to overwrite them.")
        println(STDERR, "(NB, you're splitting '$ilf' to '$r1f' and '$r2f')")
        println(STDERR, "Use '--force' to force overwriting")
        return 1
    end
    r1out = open_zipped(r1f, "w", ziplvl)
    r2out = open_zipped(r2f, "w", ziplvl)
    npair = foreach_readpair(ilf) do idx, r1, r2
        write(r1out, r1)
        write(r2out, r2)
    end
end

end # module Interleave

ext: jl


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, Pkg

name = "diffutils"
version = v"3.7.0"

# Collection of sources required to complete build
sources = [
    ArchiveSource(
        "https://ftp.gnu.org/gnu/diffutils/diffutils-3.7.tar.xz",
        "b3a7a6221c3dc916085f0d205abf6b8e1ba443d4dd965118da364a1dc1cb3a26",
    ),
    DirectorySource("./bundled"),
]

# Bash recipe for building across all platforms
script = raw"""
cd $WORKSPACE/srcdir/diffutils-*/
if [[ "${target}" == *-mingw* ]]; then
    atomic_patch -p1 ../patches/win_signal_handling.patch
fi
./configure --prefix=${prefix} --build=${MACHTYPE} --host=${target}
# skip gnulib-tests on mingw
if [[ "${target}" == *-mingw* ]]; then
    make -j${nproc} SUBDIRS="lib src tests doc man po"
    make install SUBDIRS="lib src tests doc man po"
else
    make -j${nproc}
    make install
fi
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = supported_platforms()

# The products that we will ensure are always built
products = Product[
    ExecutableProduct("cmp", :_cmp)
    ExecutableProduct("diff", :_diff)
    ExecutableProduct("diff3", :diff3)
    ExecutableProduct("sdiff", :sdiff)
]

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

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

max_stars_repo_name: sharanry/Yggdrasil

max_issues_repo_name: sharanry/Yggdrasil

max_forks_repo_name: sharanry/Yggdrasil


text:
using TopologyOptimizationTools
using Test

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

max_stars_repo_name: MKAbdElrahman/TopologyOptimizationTools

max_issues_repo_name: MKAbdElrahman/TopologyOptimizationTools

max_forks_repo_name: MKAbdElrahman/TopologyOptimizationTools


text:
# Geometry for vectors/arrows/segments

struct SegmentGeometry <: Gadfly.GeometryElement
    default_statistic::Gadfly.StatisticElement
    arrow::Bool
    filled::Bool
    tag::Symbol
end
SegmentGeometry(default_statistic=Gadfly.Stat.identity(); arrow=false, filled=false, tag=empty_tag) =
    SegmentGeometry(default_statistic, arrow, filled, tag)

"""
    Geom.segment[(; arrow=false, filled=false)]

Draw line segments from `x`, `y` to `xend`, `yend`.  Optionally specify their
`color`.  If `arrow` is `true` a `Scale` object for both axes must be
provided.  If `filled` is `true` the arrows are drawn with a filled polygon,
otherwise with a stroked line.
"""
const segment = SegmentGeometry

# Leave this as a function, pending extra arguments e.g. arrow attributes
"""
    Geom.vector[(; filled=false)]

This geometry is equivalent to [`Geom.segment(arrow=true)`](@ref).
"""
vector(; filled::Bool=false) = SegmentGeometry(arrow=true, filled=filled)

"""
    Geom.hair[(; intercept=0.0, orientation=:vertical)]

Draw lines from `x`, `y` to y=`intercept` if `orientation` is `:vertical` or
x=`intercept` if `:horizontal`.  Optionally specify their `color`.  This geometry
is equivalent to [`Geom.segment`](@ref) with [`Stat.hair`](@ref).
"""
hair(; intercept=0.0, orientation=:vertical) =
    SegmentGeometry(Gadfly.Stat.hair(intercept, orientation))

"""
    Geom.vectorfield[(; smoothness=1.0, scale=1.0, samples=20, filled=false)]

Draw a gradient vector field of the 2D function or a matrix in the `z`
aesthetic.  This geometry is equivalent to [`Geom.segment`](@ref) with
[`Stat.vectorfield`](@ref); see the latter for more information.
"""
function vectorfield(;smoothness=1.0, scale=1.0, samples=20, filled::Bool=false)
    return SegmentGeometry(
        Gadfly.Stat.vectorfield(smoothness, scale, samples),
        arrow=true, filled=filled )
end

default_statistic(geom::SegmentGeometry) = geom.default_statistic
element_aesthetics(::SegmentGeometry) = [:x, :y, :xend, :yend, :color, :linestyle]

function render(geom::SegmentGeometry, theme::Gadfly.Theme, aes::Gadfly.Aesthetics)

    Gadfly.assert_aesthetics_defined("Geom.segment", aes, :x, :y, :xend, :yend)

    function arrow(x::Real, y::Real, xmax::Real, ymax::Real, xyrange::Vector{<:Real})
        dx = xmax-x
        dy = ymax-y
        vl = 0.225*hypot(dy/xyrange[2], dx/xyrange[1])
        θ =  atan(dy/xyrange[2], dx/xyrange[1])
        ϕ = pi/15
        xr = -vl*xyrange[1]*[cos(θ+ϕ), cos(θ-ϕ)]
        yr = -vl*xyrange[2]*[sin(θ+ϕ), sin(θ-ϕ)]
        [ (xmax+xr[1],ymax+yr[1]), (xmax,ymax), (xmax+xr[2],ymax+yr[2]) ]
    end

    default_aes = Gadfly.Aesthetics()
    default_aes.color = [theme.default_color]
    default_aes.linestyle = theme.line_style[1:1]
    aes = inherit(aes, default_aes)

    # Render lines, using multivariate groupings:
    XT, YT = eltype(aes.x), eltype(aes.y)
    CT, LST = eltype(aes.color), eltype(aes.linestyle)
    groups = collect(Tuple{CT, LST}, Compose.cyclezip(aes.color, aes.linestyle))
    ugroups = unique(groups)
    ulength1 = length(ugroups)==1

    # Geom.vector requires information about scales
    if geom.arrow
        check = [aes.xviewmin, aes.xviewmax, aes.yviewmin, aes.yviewmax ]
        if any( map(x -> x === nothing, check) )
            error("For Geom.vector, Scale minvalue and maxvalue must be manually provided for both axes")
        end
         xyrange = [aes.xviewmax-aes.xviewmin, aes.yviewmax-aes.yviewmin]

         arrows = [ arrow(x, y, xend, yend, xyrange)
                for (x, y, xend, yend) in Compose.cyclezip(aes.x, aes.y, aes.xend, aes.yend) ]
    end

    segments = [[(x,y), (xend,yend)]
        for (x, y, xend, yend) in Compose.cyclezip(aes.x, aes.y, aes.xend, aes.yend)]

    nsegs = length(segments)
    cs = Vector{CT}(undef, ulength1 ? 1 : nsegs)
    lss = Vector{LST}(undef, ulength1 ? 1 : nsegs)
    linestyle_palette_length = length(theme.line_style)
    if ulength1
        cs[1], lss[1] = groups[1]
    else
        for (k,(s,g)) in enumerate(zip(segments, cycle(groups)))
            cs[k], lss[k] = g
        end
    end

    linestyles = Gadfly.get_stroke_vector.(LST<:Int ?
        theme.line_style[mod1.(lss, linestyle_palette_length)] : lss)

    classes = svg_color_class_from_label.(aes.color_label(cs))

    ctx = context()
    compose!(ctx, (context(), Compose.line(segments, geom.tag),
                stroke(cs), linewidth(theme.line_width),
                strokedash(linestyles), svgclass(classes)),
              svgclass("geometry"))
    if geom.arrow
        if geom.filled
            compose!(ctx, (context(), Compose.polygon(arrows), fill(cs), strokedash([])))
        else
            compose!(ctx, (context(), Compose.line(arrows), stroke(cs), linewidth(theme.line_width),
            strokedash([])))
        end
    end

    return ctx
end


text:
include("../src/MAB.jl")
using .MAB
using Statistics
using Plots
using Distributions
using StatsBase

struct  CABEnv
    mean_rewards::Vector{Float64}
    sample_weights::StatsBase.FrequencyWeights
    total_time::Int
    function CABEnv(mean_rewards::Vector{Float64}, sample_weights::Vector{Float64}, total_time::Int)
        new(mean_rewards,  FrequencyWeights(sample_weights), total_time)
    end
end

function sample_arms(env::CABEnv, size::Int)
    return sample(env.mean_rewards, env.sample_weights, size)
end

function alg_adaptively_greedy(env::CABEnv,init_size::Int, init_epsilon::Float64, alg)
    arms = []
    cumu_rewards = [0]
    # play each arm once

    init_means = sample_arms(env, init_size)
    for m in init_means
        push!(arms, Arms.Bernoulli(m))
    end

    for t = 1:env.total_time
        epislon = minimum([1, init_epsilon / t ])
        if t > init_size && rand(Bernoulli(epislon))
            # explore
            # println("prev: $(length(arms))")
            push!(arms, Arms.Bernoulli(sample_arms(env, 1)[1]))
            # println("next: $(length(arms))")
            add_arms!(alg, 1)
            # println(length(arms))
        end
        if get_arm_index(alg) > length(arms)
            # exploit
            println(get_arm_index(alg), length(arms))
        end
        reward = Arms.pull!(arms[get_arm_index(alg)])

        update_reward!(alg, reward)
        push!(cumu_rewards, last(cumu_rewards) + reward)
    end
    return arms, cumu_rewards[2:end]
end

function alg_fixed_set(env::CABEnv, candidate_size::Int, alg)
    arms = []
    cumu_rewards = [0]
    # play each arm once

    init_means = sample_arms(env, candidate_size)
    for m in init_means
        push!(arms, Arms.Bernoulli(m))
    end

    for t = 1:env.total_time
        reward = Arms.pull!(arms[get_arm_index(alg)])
        update_reward!(alg, reward)
        push!(cumu_rewards, last(cumu_rewards) + reward)
    end
    return arms, cumu_rewards[2:end]
end

mutable struct ArmInfo
    arm
    counts::Int
    mean_reward::Float64
end
function alg_elimination(env::CABEnv, init_size::Int, pull_times, decay_ratio)
    candidate_set = []
    init_means = sample_arms(env, init_size)
    for m in init_means
        push!(candidate_set, ArmInfo(Arms.Bernoulli(m), 0, 0))
    end

    round = 1
    t = 0
    cumu_rewards = [0]
    while round <= trunc(Int, env.total_time / pull_times / init_size)
        for arm in candidate_set
            cumu_reward = 0
            for i = 1:pull_times
                reward  = Arms.pull!(arm.arm)
                cumu_reward += reward
                push!(cumu_rewards, last(cumu_rewards) + reward)
                t += 1
            end
            arm.mean_reward = (cumu_reward + arm.mean_reward * arm.counts )/ (pull_times + arm.counts)
            arm.counts += pull_times
        end
        if length(candidate_set) > 1
            sort!(candidate_set, by = x -> x.mean_reward, rev=true)
            candidate_set = candidate_set[1:trunc(Int, length(candidate_set) * (1 - 1 / (1 + round)))]
            next_means = sample_arms(env, trunc(Int, length(candidate_set) / (round + 1)))
            for m in next_means
                push!(candidate_set, ArmInfo(Arms.Bernoulli(m), 0, 0))
            end
        else
            break
        end

        round += 1
    end

    while t < env.total_time
        push!(cumu_rewards, last(cumu_rewards) + Arms.pull!(candidate_set[1].arm))
        t += 1
    end

    return candidate_set, cumu_rewards[2:end]
end

total_time = 10000
mean_rewards = collect(0.1:0.2:0.9)
alpha = 0.2
env = CABEnv(mean_rewards, [(1-alpha)/(length(mean_rewards)-1) .* ones(length(mean_rewards)-1); alpha], total_time)
env = CABEnv(mean_rewards, [(1-alpha)/(length(mean_rewards)-1) .* ones(length(mean_rewards)-1); alpha], total_time)
candidate_size = trunc(Int, log(env.total_time) / alpha)
arms, rewards = alg_elimination(env,candidate_size, trunc(Int, log(total_time)), 1)


text:
module TestReturn

include("preamble.jl")
using InteractiveCodeSearch: seenkey, SeenKey

@testset "seenkey" begin
    @testset for x in [
                sin,
                Base,
                Array,
                Vector,
                Union{AbstractArray{T,1}, AbstractArray{T,2}} where T,
                Union{Int, Bool},
            ]
        @test seenkey(x) isa SeenKey
    end
end

@testset "@searchreturn" begin
    s = @eval @searchreturn Vector Pkg
    @test_nothrow @time wait(s.task)

    s = @eval @searchreturn Bool Base
    kill(s)
    _, t = @timed wait(s.task)
    @test t < 0.5

    # Check "Variable `_s3` exists!" path:
    global _s3 = nothing
    s = @eval @searchreturn Vector Pkg
    @test_nothrow @time wait(s.task)
end

end  # module


text:
module AutoImports

import JuliaVariables
using Base.Meta: isexpr
using CSTParser: CSTParser, Tokens
using JuliaVariables.MLStyle
using JuliaFormatter: format_text
using Pkg: TOML

include("utils.jl")
include("global_variables.jl")
include("add_using.jl")
include("sort_using.jl")
include("api.jl")

end # module


text:
# measures.jl
function _hist_add!{T}(counts::Dict{T,Int}, labels::Vector{T}, region::Range1{Int})
    for i in region
        lbl = labels[i]
        counts[lbl] = get(counts, lbl, 0) + 1
    end
    return counts
end

function _hist_sub!{T}(counts::Dict{T,Int}, labels::Vector{T}, region::Range1{Int})
    for i in region
        lbl = labels[i]
        counts[lbl] -= 1
    end
    return counts
end

function _hist_shift!{T}(counts_from::Dict{T,Int}, counts_to::Dict{T,Int}, labels::Vector{T}, region::Range1{Int})
    for i in region
        lbl = labels[i]
        counts_from[lbl] -= 1
        counts_to[lbl] = get(counts_to, lbl, 0) + 1
    end
end

_hist{T}(labels::Vector{T}, region::Range1{Int} = 1:endof(labels)) = _hist_add!(Dict{T,Int}(), labels, region)

function _info_gain{T}(N1::Int, counts1::Dict{T,Int}, N2::Int, counts2::Dict{T,Int})
    N = N1 + N2
    H = - N1/N * _set_entropy(counts1, N1) - N2/N * _set_entropy(counts2, N2)
    return H
end

function _neg_z1_loss{T<:Real}(labels::Vector, weights::Vector{T})
    missmatches = labels .!= majority_vote(labels)
    loss = sum(weights[missmatches])
    return -loss
end

function _weighted_error{T<:Real}(actual::Vector, predicted::Vector, weights::Vector{T})
    mismatches = actual .!= predicted
    err = sum(weights[mismatches]) / sum(weights)
    return err
end

function majority_vote(labels::Vector)
    if length(labels) == 0
        return nothing
    end
    counts = _hist(labels)
    top_vote = labels[1]
    top_count = -1
    for (k,v) in counts
        if v > top_count
            top_vote = k
            top_count = v
        end
    end
    return top_vote
end

function adaboost_train_error(y, X, model, coeffs)
    y_hat = apply_adaboost_stumps(model, coeffs, X)
    return mean(y .!= y_hat)
end

function matthews_corrcoef(y_hat, y)
    n = length(y)
    tp = 0
    fp = 0
    tn = 0
    fn = 0
    for i = 1:n
        if y_hat[i] == 1
            if y[i] == 1
                tp += 1
            else
                fp += 1
            end
        elseif y_hat[i] == 0
            if y[i] == 0
                tn += 1
            else
                fn += 1
            end
        end
    end
    mcc = (tp * tn - fp * fn)/sqrt((tp + fp) * (tp + fn) * (tn + fp) * (tn + fn))
    return mcc
end

max_stars_repo_name: paulstey/boosting

max_issues_repo_name: paulstey/boosting

max_forks_repo_name: paulstey/boosting


text:
"""
    Pattern

A pattern is just a wrapper around a `Tuple` which enables searching and
filtering for matching components and dimension paths in a [`KeyedDataset`](@ref).
Special symbols `:_` and `:__` are used as wildcards, similar to `*` and `**` in glob
pattern matching.

# Example
```jldoctest
julia> using AxisSets: Pattern;

julia> items = [
           (:train, :input, :load, :time),
           (:train, :input, :load, :id),
           (:train, :input, :temperature, :time),
           (:train, :input, :temperature, :id),
           (:train, :output, :load, :time),
           (:train, :output, :load, :id),
       ];

julia> filter(in(Pattern(:__, :time)), items)
3-element Vector{NTuple{4, Symbol}}:
 (:train, :input, :load, :time)
 (:train, :input, :temperature, :time)
 (:train, :output, :load, :time)

julia> filter(in(Pattern(:__, :load, :_)), items)
4-element Vector{NTuple{4, Symbol}}:
 (:train, :input, :load, :time)
 (:train, :input, :load, :id)
 (:train, :output, :load, :time)
 (:train, :output, :load, :id)
```
"""
@auto_hash_equals struct Pattern{T<:Tuple}
    segments::T

    # We reduce the segments on construction to remove extra wildcards
    # e.g., `(:_, :__, ...)` reduces to`(:__, ...`)
    # NOTE: Since these patterns shouldn't be very long it seemed alright to do in an
    # inner constructor
    function Pattern(segments::Tuple)
        n = length(segments)
        mask = trues(n)

        # Prev index used for lookup up segment and mask values as we iterate through
        j = 1

        # Iterating forwards and backwards seemed like the easiest way to
        # remove extra wildcards on either side of a `:__`
        for i in Iterators.flatten([2:n, n-1:-1:1])
            curr = segments[i]
            curr_mask = mask[i]
            prev = segments[j]
            prev_mask = mask[j]

            if curr_mask
                if curr === :__ && prev in (:_, :__) && prev_mask
                    mask[j] = false
                else
                    j = i
                end
            end
        end

        vals = segments[mask]
        return new{typeof(vals)}(vals)
    end
end

Pattern(segments...) = Pattern(segments)
Base.convert(::Type{Pattern}, x::Tuple) = Pattern(x)

Base.show(io::IO, pattern::Pattern) = print(io, "Pattern($(pattern.segments))")

function Base.in(item::Tuple, pattern::Pattern)
    # If our pattern has more segments than the item then it isn't going to match
    length(pattern.segments) <= length(item) || return false

    # Setup our item and pattern iterators
    item_iter = iterate(item)
    pat_iter = iterate(pattern.segments)

    # Loop as long as neither iterator is exhausted
    while item_iter !== nothing && pat_iter !== nothing
        # Extract values and states
        item_val, item_st = item_iter
        pat_val, pat_st = pat_iter

        # Iterate as normal if the pattern value matches, is a subtype or it's :_
        if (
            (item_val isa Type && pat_val isa Type && item_val <: pat_val) ||
            item_val == pat_val ||
            pat_val === :_
        )
            pat_iter = iterate(pattern.segments, pat_st)
            item_iter = iterate(item, item_st)
        # Look ahead when we see a multi-value wildcard to see if the next value matches
        elseif pat_val === :__
            next_iter = iterate(pattern.segments, pat_st)

            # Early exit if we've reached the end of our pattern
            next_iter === nothing && return true
            next_val, next_st = next_iter

            # If the next value will match then bump the pattern iterator state
            # otherwise just bump the item iterate and we'll check again next time.
            if (
                (item_val isa Type && next_val isa Type && item_val <: next_val) ||
                item_val == next_val
            )
                pat_iter = next_iter
            else
                item_iter = iterate(item, item_st)
            end
        else
            # Early exit if it isn't a match or a wildcard
            return false
        end
    end

    # Return `true` if we've exhausted both iterators
    return item_iter === nothing && pat_iter === nothing
end


text:
# # Quantum GAN
using Yao
using QuAlgorithmZoo

# ## DATA: Target Wave Function
# here we learn a 3 qubit state
nbit = 3
target_state = rand_state(nbit)

# ## MODEL: Quantum Circuit and Loss
# using a 4-layer random differential circuit for both generator and discriminator
# we build the qcgan setup.
depth_gen = 4
generator = dispatch!(random_diff_circuit(nbit, depth_gen, pair_ring(nbit)), :random) |> autodiff(:QC);

#------------------------------
depth_disc = 4
discriminator = dispatch!(random_diff_circuit(nbit+1, depth_disc, pair_ring(nbit+1)), :random) |> autodiff(:QC)
qg = QuGAN(target_state, generator, discriminator);

# ## TRAINING: Gradient Descent
# using a proper learning parameters, we perform 1000 steps of training
g_learning_rate=0.2
d_learning_rate=0.5
niter=1000
for info in QuGANGo!(qg, g_learning_rate, d_learning_rate, niter)
    i = info["step"]
    (i*20)%niter==0 && println("Step = $i, Trace Distance = $(tracedist(qg)), loss = $(qg |> loss)")
end


text:
@testset "rss_prep" begin
    F.def_GLOBAL_VARS!()
    F.set_var!(F.GLOBAL_VARS, "generate_rss", false)
    F.set_var!(F.GLOBAL_VARS, "website_description", "Description")
    F.set_var!(F.GLOBAL_VARS, "website_url", "URL")
    F.set_var!(F.GLOBAL_VARS, "website_title", "Title")
    F.prepare_for_rss()
    # because things are defined, switch to true
    @test F.globvar(:generate_rss)
    @test isdir(F.path(:rss))
    @test isfile(joinpath(F.path(:rss), "head.xml"))
    @test isfile(joinpath(F.path(:rss), "item.xml"))
end


text:
using Base.Filesystem: rm

@testset "video rendering" begin
    if VERSION >= v"1.3-"
        # Prior to Julia 1.3, we can't use the new FFMPEG_jll binaries
        # which ensure that FFMPEG is available.
        mktempdir() do tmpdir
            target = joinpath(tmpdir, "output.mp4")
            MeshCat.convert_frames_to_video(
                joinpath(@__DIR__, "data", "frames.tar"),
                target)
            @test isfile(target)
        end
    end
end


text:
using QuNet
using Plots

function get_costs_with_time(network::QNetwork, tmax::Float64, path::Array{<:QChannel, 1})
    # Initialise dictionary of costs over time
    costs = Dict()
    for key in keys(zero_costvector())
        costs[key] = []
    end

    # Main
    if network.time != Float64(0)
        update(network, Float64(0))
    end
    while network.time < tmax
        pathcost = get_pathcv(path)
        for key in keys(zero_costvector())
            push!(costs[key], pathcost[key])
        end
        update(network)
    end

    # Reset network back to default time
    update(network, Float64(0))

    # Return array of costs
    return [QuNet.dB_to_P.(costs["loss"]), QuNet.dB_to_Z.(costs["Z"])]
end

"""
This function takes a list of paths, purifies them and returns the costs over
time.
"""
function purify_costs_with_time(network::QNetwork, tmax::Float64,
    paths::Vector{Vector})

    loss_arr = []
    Z_arr = []

    if network.time != Float64(0)
        update(network, Float64(0))
    end

    while network.time < tmax
        path_costs = Array{Dict{Any, Any}, 1}()
        for path in paths
            path_cost = get_pathcv(path)
            push!(path_costs, path_cost)
        end

        # Purify path costs together, add to respective arrays
        cost_vector = purify(path_costs, false)
        push!(loss_arr, cost_vector["loss"])
        push!(Z_arr, cost_vector["Z"])

        # Update Network
        update(Q)
    end
    return loss_arr, Z_arr
end

function best_classical_z(cost1, cost2)
    best_arr = []
    i = 1
    maxint = length(cost1)
    while i <= maxint
        if cost1[i] > cost2[i]
            push!(best_arr, cost1[i])
        else
            push!(best_arr, cost2[i])
        end
        i += 1
    end
    return best_arr
end

# Main
Q = QNetwork()
A = BasicNode("A")
B = BasicNode("B")
S = PlanSatNode("S")

B.location = Coords(500, 0, 0)
S.location = Coords(-2000,0,1000)
S.velocity = Velocity(1000, 0)

AB = BasicChannel(A, B, exp_cost=true)
AS = QuNet.AirChannel(A, S)
SB = QuNet.AirChannel(S, B)

for i in [A, S, AB, AS, SB]
    add(Q, i)
end

# Set time, get time array
tmax = 10.0
times = collect(0:QuNet.TIME_STEP:tmax)

# Collect data
c1 = get_costs_with_time(Q, tmax, [AS, SB])
c2 = get_costs_with_time(Q, tmax, [AB])

# Convert probabilities to loss
c1[1] = 1 .- c1[1]
c2[1] = 1 .- c2[1]

# function purify(cost_vectors::Array{Dict{String,Float64}, 1})
pur_loss, pur_z = purify_costs_with_time(Q, tmax, [[AS, SB], [AB]])
pur_loss = 1 .- pur_loss

# Get best classical cost
best_arr = best_classical_z(c1[2], c2[2])

# Plot data
plot(times, c1, title="Costs of Satellite Network over Time",
label=["A-S-B (loss)" "A-S-B (Z)"], linewidth=1.5, ylims=(0.0,1.0))
plot!(times, c2, label=["A-B (loss)" "A-B (Z)"], linewidth=1.5)

# Plot purified data
plot!(times, pur_loss, label="pur_loss", linewidth = 1.5)
plot!(times, pur_z, label="pur_z", linewidth = 1.5)

# Plot extraneous things
plot!(times, best_arr, label="best classical", style=:dash, lc="black", linewidth = 1.5)
xlabel!("Time (seconds)")
ylabel!("Network Costs")

max_stars_repo_name: FalafelGood/QuNet

max_issues_repo_name: FalafelGood/QuNet

max_forks_repo_name: FalafelGood/QuNet


text:
using SpikingNN
using Plots
using Distributions
using CUDA

# simulation parameters
T = 20000
# neuron parameters
vᵣ = 0
τᵣ = 1.0
vth = 1.0
weights = rand(Uniform(-2,1),100,100)
pop = Population(weights; cell = () -> LIF(τᵣ, vᵣ),
                          synapse = Synapse.Alpha,
                          threshold = () -> Threshold.Ideal(vth))
pop = cpu(pop)
# breaks
#pop = gpu(pop)

# create input currents
low = ConstantRate(0.14)
high = ConstantRate(0.1499)
switch(t; dt = 1) = (t < Int(T/2)) ? low(t; dt = dt) : high(t; dt = dt)
n1synapse = QueuedSynapse(Synapse.Alpha())
n2synapse = QueuedSynapse(Synapse.Alpha())
excite!(n1synapse, filter(x -> x != 0, [low(t) for t = 1:T]))
excite!(n2synapse, filter(x -> x != 0, [switch(t) for t = 1:T]))
voltage_array_size = size(weights)[1]
voltages = Dict([(i, Float64[]) for i in 1:voltage_array_size])
cb = () -> begin
    for id in 1:size(pop)
        push!(voltages[id], getvoltage(pop[id]))
    end
end
input1 = [ (t; dt) -> 0 for i in 1:voltage_array_size/3]
input2 = [ n2synapse for i in voltage_array_size/3+1:2*voltage_array_size/3]
input3 = [ (t; dt) -> 0 for i in 2*voltage_array_size/3:voltage_array_size]
input = vcat(input2, input1, input3)
outputs = simulate!(pop, T; cb = cb, inputs=input)
labels = [ "input $i" for i in 1:voltage_array_size]
rasterplot(outputs, label = labels)#["Input 1", "Input 2","Input 3", "Inhibitor"])
title!("Raster Plot")
xlabel!("Time (sec)")


text:
function exchange!(A, i, j)
    tmp = A[i]
    A[i] = A[j]
    A[j] = tmp
end

max_stars_repo_name: blallen/CodePractice

max_issues_repo_name: blallen/CodePractice

max_forks_repo_name: blallen/CodePractice


text:
function softmax(x;k=1.)
    thresh = 500.
    g = map(x) do xi
        if k*xi < -thresh
            (log(1. + exp(k*xi)))/k
        elseif k*xi > thresh
            (k*xi + log(1. + exp(-k*xi)))/k
        else
            log(exp(k*xi) + 1.)/k
        end
    end
    g
end

function gsoftmax(x;k=1.)
    thresh = 500.
    g = map(x) do xi
        if k*xi > thresh
            1. / (1. + exp(-k*xi))
        else
            exp(k*xi) / (1. + exp(k*xi))
        end
    end
    Matrix(Diagonal(g))
end

function L(x,λ,f,h,c)
    f(x) - dot(λ,h(x)) + .5*c*dot(h(x),h(x))
end

function auglag(fun, num_eqs, num_ineqs, x0, options)
    num_fosteps = get(options, "num_fosteps", 3)
    num_sosteps = get(options, "num_sosteps", 2)
    c = get(options, "c", 1.)
    c_fos = get(options, "c_fos", 10.)
    c_sos = get(options, "c_sos", 10.)
    ls_method = get(options, "ls_method", :pinv)

    num_x = length(x0)
    rtol = eps(1.) * (num_eqs + num_ineqs)

    x = vcat(copy(x0), zeros(num_ineqs))
    λ = zeros(num_eqs + num_ineqs)

    for i = 1:num_fosteps
        # TODO inplace
        obj, eqs, ineqs, gobj, geqs, gineqs, Hobj = fun(x[1:num_x])

        ∇f = vcat(gobj, zeros(eltype(gobj), num_ineqs))
        Hf = zeros(eltype(Hobj), num_x+num_ineqs, num_x+num_ineqs)
        Hf[1:num_x, 1:num_x] .= Hobj
        hx = vcat(eqs, ineqs + softmax(x[num_x+1:end]))
        ∇h = hcat(vcat(geqs, gineqs), vcat(zeros(eltype(x),num_eqs,num_ineqs),gsoftmax(x[num_x+1:end])))

        gL = ∇f - ∇h'*λ + c*∇h'*hx
        HL = Hf + c*∇h'*∇h

        δx = (HL + (sum(HL.^2)+rtol)*I) \ (-gL)
        δλ = -c * hx

        x += δx
        λ += δλ

        c *= c_fos
    end

    for i = 1:num_sosteps
        # TODO inplace
        obj, eqs, ineqs, gobj, geqs, gineqs, Hobj = fun(x[1:num_x])

        ∇f = vcat(gobj, zeros(eltype(gobj),num_ineqs))
        Hf = zeros(eltype(Hobj), num_x+num_ineqs, num_x+num_ineqs)
        Hf[1:num_x, 1:num_x] .= Hobj

        hx = vcat(eqs, ineqs + softmax(x[num_x+1:end]))
        ∇h = hcat(vcat(geqs, gineqs), vcat(zeros(eltype(x),num_eqs,num_ineqs),gsoftmax(x[num_x+1:end])))

        gL = ∇f - ∇h'*λ + c*∇h'*hx
        HL = Hf + c*∇h'*∇h

        A = vcat(hcat(HL,∇h'),hcat(∇h,zeros(eltype(∇h),num_eqs+num_ineqs,num_eqs+num_ineqs)))
        b = -vcat(gL,hx)

        # for numerical stability
        tol = 1e-12
        A[abs.(A) .<= tol] .= 0.
        b[abs.(b) .<= tol] .= 0.

        if (ls_method == :pinv)
            Apinv = pinv(A)
            δxλ = Apinv * b
        elseif (ls_method == :least_squares)
            δxλ = least_squares(A,b)
        else
            U,S,V = svd(A)
            tol = rtol*maximum(S)
            ksig = 100.
            Sinv = 1. ./ (1. .+ exp.(-ksig*(S .- tol)/tol)) .* (1. ./ S)
            Sinv[isinf.(Sinv)] .= 0.
            Apinv = V * (Diagonal(Sinv) * U')
            δxλ = Apinv * b
        end

        δx = δxλ[1:num_x+num_ineqs]
        δλ = δxλ[num_x+num_ineqs+1:num_x+num_ineqs+num_eqs+num_ineqs]

        x += δx
        λ += δλ

        c *= c_sos
    end

    x[1:num_x], "Finished successfully"
end


text:
export HarmonicBond

"""
    HarmonicBond(; b0, kb)

A harmonic bond between two atoms.
"""
struct HarmonicBond{D, K} <: SpecificInteraction
    b0::D
    kb::K
end

HarmonicBond(; b0, kb) = HarmonicBond{typeof(b0), typeof(kb)}(b0, kb)

@inline @inbounds function force(b::HarmonicBond, coord_i, coord_j, box_size)
    ab = vector(coord_i, coord_j, box_size)
    c = b.kb * (norm(ab) - b.b0)
    f = c * normalize(ab)
    return SpecificForce2Atoms(f, -f)
end

@inline @inbounds function potential_energy(b::HarmonicBond, coord_i, coord_j, box_size)
    dr = vector(coord_i, coord_j, box_size)
    r = norm(dr)
    return (b.kb / 2) * (r - b.b0) ^ 2
end


text:
const OBJECTIDS_QUEUED_FOR_FREEING = WeakKeyDict{Any, Vector{String}}()

function start_gc_task()
    @async begin
        while true
            try
                for (session, objects) in OBJECTIDS_QUEUED_FOR_FREEING
                    if session === nothing # got gc'ed
                        empty!(objects)
                        continue
                    end
                    if length(objects) > 100
                        delete_objects(session, objects)
                        empty!(objects)
                    end
                end
            catch e
                @warn "Error while freeing!" exception=CapturedException(e, Base.catch_backtrace())
            end
            sleep(5)
        end
    end
end

function remove_js_reference(object::JSObject)
    objects = get!(OBJECTIDS_QUEUED_FOR_FREEING, session(object), String[])
    push!(objects, uuidstr(object))
end

struct JSGlobal <: AbstractJSObject
    name::Symbol
end

macro jsglobal(name)
    JSGlobal(Symbol(name))
end

"""
    JSObject(jso::JSObject, typ::Symbol)

Copy constructor with a new `typ`
"""
function JSObject(jso::JSObject, typ::Symbol)
    jsonew = JSObject(name(jso), session(jso), typ)
    # point new object to old one on the javascript side:
    evaljs(session(jso), js"put_on_heap($(uuidstr(jsonew)), $jso); undefined;")
    return jsonew
end

function JSObject(session::Session, name::Symbol)
    return JSObject(name, session, :variable)
end

# define accessors
for name in (:name, :session, :typ, :uuid)
    @eval $(name)(jso::JSObject) = getfield(jso, $(QuoteNode(name)))
end

"""
    uuidstr(jso::JSObject)

Returns the uuid as a string
"""
uuidstr(jso::JSObject) = string(uuid(jso))

"""
Overloading getproperty to allow the same semantic as Javascript.
Since there is no `new` keyword in Julia like in JS, we missuse
jsobject.new, to return an instance of jsobject with a new modifier.

So this Javascript:
```js
obj = new Module.Constructor()
```

Will translates to the following Julia code:
```Julia
obj = Module.new.Constructor()
```
"""
function Base.getproperty(jso::AbstractJSObject, field::Symbol)
    if field === :new
        # Create a new instance of jso, with the `new` modifier
        return JSObject(jso, :new)
    else
        result = JSObject(field, session(jso), typ(jso))
        send(
            session(jso),
            msg_type = JSGetIndex,
            object = jso,
            field = field,
            result = uuidstr(result),
        )
        return result
    end
end

function Base.setproperty!(jso::AbstractJSObject, field::Symbol, value)
    send(
        session(jso),
        msg_type = JSSetIndex,
        object = jso,
        value = value,
        field = field
    )
    return value
end

"""
    construct_arguments(args, keyword_arguments)
Constructs the arguments for a JS call.
Can only use either keyword arguments or positional arguments.
"""
function construct_arguments(args, keyword_arguments)
    if isempty(keyword_arguments)
        return args
    elseif isempty(args)
        # tojs isn't recursive bug:
        return keyword_arguments
    else
        # TODO: I'm not actually sure about this :D
        error("""
        Javascript only supports keyword arguments OR arguments.
        Found posititional arguments and keyword arguments
        """)
    end
end

"""
    jsobject(args...; kw_args...)

Call overload for JSObjects.
Only supports keyword arguments OR positional arguments.
"""
function jscall(jso::AbstractJSObject, args, kw_args)
    result = JSObject(:result, session(jso), :call)
    send(
        session(jso),
        msg_type = JSCall,
        func = jso,
        needs_new = getfield(jso, :typ) === :new,
        arguments = construct_arguments(args, kw_args),
        result = uuidstr(result)
    )
    return result
end

(jso::JSObject)(args...; kw_args...) = jscall(jso, args, kw_args)

struct JSModule <: AbstractJSObject
    session::Session
    mod::JSObject
    document::JSObject
    window::JSObject
    this::JSObject
    display_func # A function that gets called on show with the modules Scope
end

session(x::JSModule) = getfield(x, :session)
fuse(f, jso::JSObject) = fuse(f, session(jso))

"""
    jsobject(session::Session, js::JSCode, name = :object)

Returns the JSObject referencing the return value of `js`
"""
function jsobject(session::Session, js::JSCode, name = :object)
    result = JSObject(session, name)
    evaljs(session, js"""
        var object = $(js)
        put_on_heap($(uuidstr(result)), object);
    """)
    return result
end


text:
module ListBoxes

Base.Experimental.@optlevel 1

using Redux
using CImGui
import ..ReduxImGui: get_label

# actions
abstract type AbstractListBoxAction <: AbstractSyncAction end

"""
    Rename(label, new_label)
Change label to `new_label`.
Note that renaming may also change the identifier, please refer to `help?> CImGui.PushID`.
"""
struct Rename <: AbstractListBoxAction
    label::String
    new_label::String
end

"""
    ChangeItems(label, items)
Change widget's items to `items`.
"""
struct ChangeItems <: AbstractListBoxAction
    label::String
    items::Vector{String}
end

"""
    ChangeIndex(label, idx)
Change current item to the one indexed by `idx`.
"""
struct ChangeIndex <: AbstractListBoxAction
    label::String
    idx::Cint
end

"""
    ChangeHeight(label, height)
Change widget's height to `height`-items.
"""
struct ChangeHeight <: AbstractListBoxAction
    label::String
    height::Cint
end

# state
struct State <: AbstractImmutableState
    label::String
    items::Vector{String}
    idx::Cint
    height::Cint
end
State(label::AbstractString, items::Vector{<:AbstractString}, idx = 1) =
    State(label, items, idx, -1)

# reducers
listbox(state::AbstractState, action::AbstractAction) = state
listbox(state::Vector{<:AbstractState}, action::AbstractAction) = state
listbox(state::Dict{String,<:AbstractState}, action::AbstractAction) = state

function listbox(state::Dict{String,State}, action::AbstractListBoxAction)
    s = Dict{String,State}()
    for (k, v) in state
        s[k] = get_label(v) == action.label ? listbox(v, action) : v
    end
    return s
end

listbox(s::State, a::Rename) = State(a.new_label, s.items, s.idx, s.height)
listbox(s::State, a::ChangeItems) = State(s.label, a.items, s.idx, s.height)
listbox(s::State, a::ChangeIndex) = State(s.label, s.items, a.idx, s.height)
listbox(s::State, a::ChangeHeight) = State(s.label, s.items, s.idx, a.height)

# helper
"""
    ListBox(store::AbstractStore, get_state=Redux.get_state) -> Bool
Return `true` when triggered.
"""
function ListBox(store::AbstractStore, get_state = Redux.get_state)
    s = get_state(store)
    c_idx = Ref{Cint}(s.idx - 1)
    is_triggered = CImGui.ListBox(s.label, c_idx, s.items, length(s.items), s.height)
    is_triggered && dispatch!(store, ChangeIndex(s.label, c_idx[]+1))
    return is_triggered
end

get_label(s::State) = s.label
get_items(s::State) = s.items
get_item(s::State) = s.items[s.idx]

end # module


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

mutable struct EncryptionIdentity <: SwaggerModel
    type::Any # spec type: Union{ Nothing, String } # spec name: type
    principalId::Any # spec type: Union{ Nothing, String } # spec name: principalId
    tenantId::Any # spec type: Union{ Nothing, String } # spec name: tenantId

    function EncryptionIdentity(;type=nothing, principalId=nothing, tenantId=nothing)
        o = new()
        validate_property(EncryptionIdentity, Symbol("type"), type)
        setfield!(o, Symbol("type"), type)
        validate_property(EncryptionIdentity, Symbol("principalId"), principalId)
        setfield!(o, Symbol("principalId"), principalId)
        validate_property(EncryptionIdentity, Symbol("tenantId"), tenantId)
        setfield!(o, Symbol("tenantId"), tenantId)
        o
    end
end # type EncryptionIdentity

const _property_map_EncryptionIdentity = Dict{Symbol,Symbol}(Symbol("type")=>Symbol("type"), Symbol("principalId")=>Symbol("principalId"), Symbol("tenantId")=>Symbol("tenantId"))
const _property_types_EncryptionIdentity = Dict{Symbol,String}(Symbol("type")=>"String", Symbol("principalId")=>"String", Symbol("tenantId")=>"String")
Base.propertynames(::Type{ EncryptionIdentity }) = collect(keys(_property_map_EncryptionIdentity))
Swagger.property_type(::Type{ EncryptionIdentity }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_EncryptionIdentity[name]))}
Swagger.field_name(::Type{ EncryptionIdentity }, property_name::Symbol) =  _property_map_EncryptionIdentity[property_name]

const _allowed_EncryptionIdentity_type = ["SystemAssigned"]

function check_required(o::EncryptionIdentity)
    true
end

function validate_property(::Type{ EncryptionIdentity }, name::Symbol, val)
    if name === Symbol("type")
        Swagger.validate_param(name, "EncryptionIdentity", :enum, val, _allowed_EncryptionIdentity_type)
    end
end


text:
@testset "BostonHousing" begin
    n_obs = 506
    n_features = 13
    n_targets = 1
    feature_names = ["CRIM", "ZN", "INDUS", "CHAS", "NOX", "RM", "AGE", "DIS", "RAD", "TAX", "PTRATIO", "B", "LSTAT"]
    target_names = ["MEDV"]

    # TODO remove
    @testset "deprecated interface" begin
        X  = BostonHousing.features()
        Y  = BostonHousing.targets()
        names = BostonHousing.feature_names()
        @test X isa Matrix{Float64}
        @test Y isa Matrix{Float64}
        @test names == lowercase.(feature_names)
        @test size(X) == (13, 506)
        @test size(Y) == (1, 506)
    end
end

@testset "Iris" begin
    n_obs = 150
    n_features = 4
    n_targets = 1

    # TODO remove
    @testset "deprecated interface" begin
        X  = Iris.features()
        Y  = Iris.labels()
        @test X isa Matrix{Float64}
        @test Y isa Vector{<:AbstractString}
        @test size(X) == (4, 150)
        @test size(Y) == (150,)
    end
end

@testset "Mutagenesis" begin

    @testset "deprecated interface" begin
        train_x, train_y = Mutagenesis.traindata()
        test_x, test_y = Mutagenesis.testdata()
        val_x, val_y = Mutagenesis.valdata()

        @test length(train_x) == length(train_y) == 100
        @test length(test_x) == length(test_y) == 44
        @test length(val_x) == length(val_y) == 44
        # test that label is not contained in features
        @test !any(haskey.(train_x, :mutagenic))
        @test !any(haskey.(test_x, :mutagenic))
        @test !any(haskey.(val_x, :mutagenic))
        # test data is materialized
        @test train_x isa Vector{<:Dict}
        @test test_x isa Vector{<:Dict}
        @test val_x isa Vector{<:Dict}
    end
end

@testset "Titanic" begin
    n_obs = 891
    n_features = 11
    n_targets = 1
    feature_names = ["PassengerId","Pclass", "Name", "Sex", "Age", "SibSp", "Parch", "Ticket", "Fare", "Cabin", "Embarked"]
    target_names = ["Survived"]

    # TODO remove
    @testset "deprecated interface" begin
        X = Titanic.features()
        Y = Titanic.targets()
        names = Titanic.feature_names()
        @test X isa Matrix
        @test Y isa Matrix
        @test names == feature_names
        @test size(X) == (11, 891)
        @test size(Y) == (1, 891)
    end
end


text:
@testset "Agent" begin
    @testset "Default selection" begin
        agent = get_default_agent()
        @test agent !== nothing

        AMDGPU.set_default_agent!(:gpu)
        agent = get_default_agent()
        @test AMDGPU.device_type(agent) == :gpu

        agent_name = AMDGPU.get_name(agent)
        @test length(agent_name) > 0
        @test !occursin('\0', agent_name)
    end

    @testset "ISAs" begin
        agent = get_default_agent()
        agent_isa = get_first_isa(agent)
        @test length(agent_isa) > 0
    end
end


text:
# ---
# title: 1232. Check If It Is a Straight Line
# id: problem1232
# author: Tian Jun
# date: 2020-10-31
# difficulty: Easy
# categories: Array, Math, Geometry
# link: <https://leetcode.com/problems/check-if-it-is-a-straight-line/description/>
# hidden: true
# ---
#
# You are given an array `coordinates`, `coordinates[i] = [x, y]`, where `[x,
# y]` represents the coordinate of a point. Check if these points make a
# straight line in the XY plane.
#
#
#
#
#
# **Example 1:**
#
# ![](https://assets.leetcode.com/uploads/2019/10/15/untitled-diagram-2.jpg)
#
#
#
#     Input: coordinates = [[1,2],[2,3],[3,4],[4,5],[5,6],[6,7]]
#     Output: true
#
#
# **Example 2:**
#
# **![](https://assets.leetcode.com/uploads/2019/10/09/untitled-diagram-1.jpg)**
#
#
#
#     Input: coordinates = [[1,1],[2,2],[3,4],[4,5],[5,6],[7,7]]
#     Output: false
#
#
#
#
# **Constraints:**
#
#   * `2 <= coordinates.length <= 1000`
#   * `coordinates[i].length == 2`
#   * `-10^4 <= coordinates[i][0], coordinates[i][1] <= 10^4`
#   * `coordinates` contains no duplicate point.
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end


text:
module ITensorGLMakie

using Reexport
using GLMakie

@reexport using ITensorMakie

end # module


text:
# support for device-side exceptions

## exception type

struct KernelException <: Exception
    dev::CuDevice
end

function Base.showerror(io::IO, err::KernelException)
    print(io, "KernelException: exception thrown during kernel execution on device $(name(err.dev))")
end

## exception handling

const exception_flags = Dict{CuContext, Mem.HostBuffer}()

# create a CPU/GPU exception flag for error signalling, and put it in the module
function create_exceptions!(mod::CuModule)
    exception_flag = get!(exception_flags, mod.ctx,
                          Mem.alloc(Mem.Host, sizeof(Int), Mem.HOSTALLOC_DEVICEMAP))
    return reinterpret(Ptr{Cvoid}, convert(CuPtr{Cvoid}, exception_flag))
end

# check the exception flags on every API call, similarly to how CUDA handles errors
function check_exceptions()
    for (ctx,buf) in exception_flags
        if isvalid(ctx)
            ptr = convert(Ptr{Int}, buf)
            flag = unsafe_load(ptr)
            if flag != 0
                unsafe_store!(ptr, 0)
                dev = device(ctx)
                throw(KernelException(dev))
            end
        end
    end
    return
end


text: struct HillClimb <: BaseStructureLearning end


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

function bat_marginalmode_impl(samples::DensitySampleVector; nbins::Union{Integer, Symbol} = 200)
    shape = varshape(samples)
    flat_samples = flatview(unshaped.(samples.v))
    n_params = size(flat_samples)[1]
    nt_samples = ntuple(i -> flat_samples[i,:], n_params)
    marginalmode_params = Vector{Float64}()

    for param in Base.OneTo(n_params)
        if typeof(nbins) == Symbol
            number_of_bins = _auto_binning_nbins(nt_samples, param, mode=nbins)
        else
            number_of_bins = nbins
        end

        marginalmode_param = find_marginalmodes(get_marginal_dist(samples, param, bins=number_of_bins).result)

        if length(marginalmode_param[1]) > 1
            @warn "More than one bin with the same weight is found. Returned the first one"
        end
        push!(marginalmode_params, marginalmode_param[1][1])
    end
    (result = strip_realscalar(shape(marginalmode_params)),)
end

# From Plots.jl, original authors Oliver Schulz and Michael K. Borregaard
function _auto_binning_nbins(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) where N
    max_bins = 10_000
    _cl(x) = min(ceil(Int, max(x, one(x))), max_bins)
    _iqr(v) = (q = quantile(v, 0.75) - quantile(v, 0.25); q > 0 ? q : oftype(q, 1))
    _span(v) = maximum(v) - minimum(v)

    n_samples = length(LinearIndices(first(vs)))

    # The nd estimator is the key to most automatic binning methods, and is modified for twodimensional histograms to include correlation
    nd = n_samples^(1/(2+N))
    nd = N == 2 ? min(n_samples^(1/(2+N)), nd / (1-cor(first(vs), last(vs))^2)^(3//8)) : nd # the >2-dimensional case does not have a nice solution to correlations

    v = vs[dim]

    if mode == :auto
        mode = :fd
    end

    if mode == :sqrt  # Square-root choice
        _cl(sqrt(n_samples))
    elseif mode == :sturges  # Sturges' formula
        _cl(log2(n_samples) + 1)
    elseif mode == :rice  # Rice Rule
        _cl(2 * nd)
    elseif mode == :scott  # Scott's normal reference rule
        _cl(_span(v) / (3.5 * std(v) / nd))
    elseif mode == :fd  # Freedman–Diaconis rule
        _cl(_span(v) / (2 * _iqr(v) / nd))
    elseif mode == :wand
        _cl(wand_edges(v))  # this makes this function not type stable, but the type instability does not propagate
    else
        error("Unknown auto-binning mode $mode")
    end
end


text:
export getLinearOperatorsSystemsFaces,getInjectionOperatorsSystemsFaces,MGsetupSystems,getFacesStaggeredIndicesOfCell
## n is always in cells in this file

function getInjectionOperatorsSystemsFaces(n::Array{Int64},withCellsBlock::Bool)
	if length(n) == 2
		R1, = getRestrictionFacesInjectionUj(n,1);
		R2, = getRestrictionFacesInjectionUj(n,2);

		if withCellsBlock
			R3, = getRestrictionCellCentered(n);
			Rinj = blkdiag(R1,R2,R3);
		else
			Rinj = blkdiag(R1,R2);
		end
	else
		R1, = getRestrictionFacesInjectionUj(n,1);
		R2, = getRestrictionFacesInjectionUj(n,2);
		R3, = getRestrictionFacesInjectionUj(n,3);
		if withCellsBlock
			R4, = getRestrictionCellCentered(n);
			Rinj = blkdiag(R1,R2,R3,R4);
		else
			Rinj = blkdiag(R1,R2,R3);
		end
	end
	return Rinj;
end

function getLinearOperatorsSystemsFaces(n::Array{Int64},withCellsBlock::Bool)
	if length(n) == 2
		(P1,nc) = getLinearInterpolationFacesUj(n,1);
		P2, = getLinearInterpolationFacesUj(n,2);
		if withCellsBlock
			P3, = getLinearInterpolationCellCentered(n);
			P  = blkdiag(P1,P2,P3);
		else
			P  = blkdiag(P1,P2);
		end
		R1, = getRestrictionFacesFullWeightUj(n,1);
		R2, = getRestrictionFacesFullWeightUj(n,2);
		if withCellsBlock
			R3, = getRestrictionCellCentered(n);
			R  = blkdiag(R1,R2,R3);
		else
			R  = blkdiag(R1,R2);
		end
	else
		(P1,nc) = getLinearInterpolationFacesUj(n,1);
		P2, = getLinearInterpolationFacesUj(n,2);
		P3, = getLinearInterpolationFacesUj(n,3);

		if withCellsBlock
			P4, = getLinearInterpolationCellCentered(n);
			P  = blkdiag(P1,P2,P3,P4);
		else
			P  = blkdiag(P1,P2,P3);
		end
		R1, = getRestrictionFacesFullWeightUj(n,1);
		R2, = getRestrictionFacesFullWeightUj(n,2);
		R3, = getRestrictionFacesFullWeightUj(n,3);
		if withCellsBlock
			R4, = getRestrictionCellCentered(n);
			R  = blkdiag(R1,R2,R3,R4);
		else
			R  = blkdiag(R1,R2,R3);
		end
	end
	return (P,R,nc);
end

function get1DRestrictionCells(n::Int64)
	## R is an 2X1 aggregation restriction.
	if n < 16
		return speye(n),n;
	end
	nc = div(n,2);
	if 2*nc != n
		error("Err: get1DRestrictionCells(): size should be a multiplication of 2");
	end
	R = 1/2*spdiagm((ones(n-1),ones(n-1)),[0,1],n-1,n);
	R = R[1:2:n,:];
	return R,nc;
end

function get1DNodeInjection(n_cells::Int64)
	## R is a node injection operator - C,F,C,F,...,C
	n = n_cells;
	if n < 16
		return speye(n+1),n;
	end
	nc = div(n,2);
	if 2*nc != n
		error("Err: get1DNodeInjection(): size should be a multiplication of 2");
	end
	R = speye(n+1);
	R = R[1:2:n+1,:];
	return R,nc;
end

function get1DNodeFullWeightRestriction(n_cells::Int64)
	## R is a full weighting X2 restriction: 0.25 , 0.5 , 0.25 operates on nodes.
	## B.C: Here we need to choose what happens at boundaries - we choose injection
	n = n_cells;
	if n < 16
		return speye(n+1),n;
	end
	nc = div(n,2);
	if 2*nc != n
		error("Err: get1DNodeFullWeightRestriction(): size should be a multiplication of 2");
	end
	Qtr = 0.25*ones(n);
	R = spdiagm((Qtr,0.5*ones(n+1),Qtr),[-1,0,1],n+1,n+1);
    R = R[:,1:2:end]';
	R[1,1:2] = [0.75 0.25];
	R[end,end-1:end] = [0.25 0.75];
	return R,nc;
end

function get1DProlongationCellCentered(ncells_fine::Int64)
	## P takes a two cells [C,C] into [F,F,F,F]
	n = ncells_fine;
	if n < 16
		return speye(n),n;
	end
	nc = div(n,2);
	if 2*nc != n
		error("Err: get1DProlongationCellCentered(): size should be a multiplication of 2");
	end
	P  = spdiagm(((1/4)*ones(n-2),(3/4)*ones(n-1),(3/4)*ones(n),(1/4)*ones(n-1)),[-2,-1,0,1],n,n);
	P = P[:,1:2:end];
	P[1,1:2] = [5/4,-1/4];
	P[end,end-1:end] = [-1/4,5/4];
	return P,nc;
end

function get1DProlongationNodes(ncells_fine::Int64)
	## P takes a two cells [C,C] into [F,F,F,F]
	n = ncells_fine;
	if n < 16
		return speye(n+1),n;
	end
	nc = div(n,2);
	if 2*nc != n
		error("Err: get1DProlongationNodes(): size should be a multiplication of 2");
	end
	Half = 0.5*ones(n);
	P = spdiagm((Half,ones(n+1),Half),[-1,0,1],n+1,n+1);
    P = P[:,1:2:end];
	return P,nc;
end

function getRestrictionCellCentered(n::Array{Int64})
	if length(n) == 3
		(R1,nc1) = get1DRestrictionCells(n[1]);
		(R2,nc2) = get1DRestrictionCells(n[2]);
		(R3,nc3) = get1DRestrictionCells(n[3]);
		R = kron(R3,kron(R2,R1));
		nc = [nc1;nc2;nc3];
	elseif length(n) == 2
		(R1,nc1) = get1DRestrictionCells(n[1]);
		(R2,nc2) = get1DRestrictionCells(n[2]);
		R = kron(R2,R1);
		nc = [nc1;nc2];
	else
		error("getRestrictionCells() : Dimension not supported!");
	end
	return R,nc
end

function getRestrictionFacesInjectionUj(n::Array{Int64},j::Int64)
    # n here is number of cells.
	R = Array(SparseMatrixCSC,length(n));
	nc = zeros(Int64,length(n));
	for kk = 1:length(n)
		if kk == j
			(R[kk],nc[kk]) = get1DNodeInjection(n[kk]);
		else
			(R[kk],nc[kk]) = get1DRestrictionCells(n[kk]);
		end
	end
	if length(n) == 3
		R = kron(R[3],kron(R[2],R[1]));
	elseif length(n) == 2
		R = kron(R[2],R[1]);
	else
		error("getRestrictionFacesInjectionUj() : Dimension not supported!");
	end
	return R,nc;
end

function getRestrictionFacesFullWeightUj(n::Array{Int64},j::Int64)
    # n here is number of cells.
	R = Array(SparseMatrixCSC,length(n));
	nc = zeros(Int64,length(n));
	for kk = 1:length(n)
		if kk == j
			(R[kk],nc[kk]) = get1DNodeFullWeightRestriction(n[kk]);
		else
			(R[kk],nc[kk]) = get1DRestrictionCells(n[kk]);
		end
	end
	if length(n) == 3
		R = kron(R[3],kron(R[2],R[1]));
	elseif length(n) == 2
		R = kron(R[2],R[1]);
	else
		error("getRestrictionFacesFullWeightUj() : Dimension not supported!");
	end
	return R,nc;
end

function getLinearInterpolationFacesUj(n::Array{Int64},j::Int64)
	P = Array(SparseMatrixCSC,length(n));
	nc = zeros(Int64,length(n));
	for kk = 1:length(n)
		if kk == j
			(P[kk],nc[kk]) = get1DProlongationNodes(n[kk]);
		else
			(P[kk],nc[kk]) = get1DProlongationCellCentered(n[kk]);
		end
	end
	if length(n) == 3
		P = kron(P[3],kron(P[2],P[1]));
	elseif length(n) == 2
		P = kron(P[2],P[1]);
	else
		error("getLinearInterpolationFacesUj() : Dimension not supported!");
	end
	return P,nc;
end

function getLinearInterpolationCellCentered(n::Array{Int64})
	nc = zeros(Int64,length(n));
	if length(n) == 3
		(P1,nc1) = get1DProlongationCellCentered(n[1]);
		(P2,nc2) = get1DProlongationCellCentered(n[2]);
		(P3,nc3) = get1DProlongationCellCentered(n[3]);
		P = kron(P3,kron(P2,P1));
		nc = [nc1;nc2;nc3];
	elseif length(n) == 2
		(P1,nc1) = get1DProlongationCellCentered(n[1]);
		(P2,nc2) = get1DProlongationCellCentered(n[2]);
		P = kron(P2,P1);
		nc = [nc1;nc2];
	else
		error("getLinearInterpolationCellCentered() : Dimension not supported!");
	end
	return P,nc;
end


text:
using SafeTestsets

@safetestset "Bare Differentiation Operator Backends (out-of-place)" begin
    using DerivableFunctionsBase, Test, ForwardDiff
    Metric3(x) = [sinh(x[3]) exp(x[1])*sin(x[2]) 0; 0 cosh(x[2]) cos(x[2])*x[3]*x[2]; exp(x[2]) cos(x[3])*x[1]*x[2] 1.]

    X = ForwardDiff.gradient(x->x[1]^2 + exp(x[2]), [5,10.])
    Y = ForwardDiff.jacobian(x->[x[1]^2, exp(x[2])], [5,10.])
    Z = ForwardDiff.hessian(x->x[1]^2 + exp(x[2]) + x[1]*x[2], [5,10.])
    Mat = reshape(ForwardDiff.jacobian(vec∘Metric3, [5,10,15.]), 3, 3, 3)
    Djac = reshape(ForwardDiff.jacobian(p->vec(ForwardDiff.jacobian(x->[exp(x[1])*sin(x[2]), cosh(x[2])*x[1]*x[2]],p)), [5,10.]), 2,2,2)

    function MyTest(ADmode::Symbol; atol::Real=1e-5, kwargs...)
        Grad, Jac, Hess = GetGrad(ADmode; kwargs...), GetJac(ADmode; kwargs...), GetHess(ADmode; kwargs...)
        MatrixJac = GetMatrixJac(ADmode; order=8, kwargs...)

        @test isapprox(Grad(x->x[1]^2 + exp(x[2]), [5,10.]), X; atol=atol)
        @test isapprox(Jac(x->[x[1]^2, exp(x[2])], [5,10.]), Y; atol=atol)
        @test isapprox(Hess(x->x[1]^2 + exp(x[2]) + x[1]*x[2], [5,10.]), Z; atol=atol)
        @test maximum(abs.(MatrixJac(Metric3, [5,10,15.]) - Mat)) < atol
    end

    for ADmode ∈ [:ForwardDiff]
        MyTest(ADmode)
    end

    function TestDoubleJac(ADmode::Symbol; atol::Real=1e-5, kwargs...)
        DoubleJac = GetDoubleJac(ADmode; order=8, kwargs...)
        maximum(abs.(DoubleJac(x->[exp(x[1])*sin(x[2]), cosh(x[2])*x[1]*x[2]], [5,10.]) - Djac)) < atol
    end

    for ADmode ∈ [:ForwardDiff]
        @test TestDoubleJac(ADmode)
    end
end

@safetestset "Bare Differentiation Operator Backends (in-place)" begin
    using DerivableFunctionsBase, Test, ForwardDiff
    Metric3(x) = [sinh(x[3]) exp(x[1])*sin(x[2]) 0; 0 cosh(x[2]) cos(x[2])*x[3]*x[2]; exp(x[2]) cos(x[3])*x[1]*x[2] 1.]

    X = ForwardDiff.gradient(x->x[1]^2 + exp(x[2]), [5,10.])
    Y = ForwardDiff.jacobian(x->[x[1]^2, exp(x[2])], [5,10.])
    Z = ForwardDiff.hessian(x->x[1]^2 + exp(x[2]) + x[1]*x[2], [5,10.])
    Mat = reshape(ForwardDiff.jacobian(vec∘Metric3, [5,10,15.]), 3, 3, 3)

    function MyInplaceTest(ADmode::Symbol; kwargs...)
        Grad! = GetGrad!(ADmode, x->x[1]^2 + exp(x[2]); kwargs...)
        Jac! = GetJac!(ADmode, x->[x[1]^2, exp(x[2])]; kwargs...)
        Hess! = GetHess!(ADmode, x->x[1]^2 + exp(x[2]) + x[1]*x[2]; kwargs...)
        MatrixJac! = GetMatrixJac!(ADmode, Metric3; order=8, kwargs...)

        Xres = similar(X);  Yres = similar(Y);  Zres = similar(Z);  Matres = similar(Mat)

        Grad!(Xres, [5,10.]);   @test Xres ≈ X
        Jac!(Yres, [5,10.]);   @test Yres ≈ Y
        Hess!(Zres, [5,10.]);   @test Zres ≈ Z
        MatrixJac!(Matres, [5,10,15.]);   @test maximum(abs.(Matres - Mat)) < 1e-5
    end

    for ADmode ∈ [:ForwardDiff]
        MyInplaceTest(ADmode)
    end
end

@safetestset "Symbolic Passthrough" begin
    include("SymbolicTests.jl")
end

@safetestset "DFunctions with symbolic derivatives (out-of-place)" begin
    using DerivableFunctionsBase, Test, RuntimeGeneratedFunctions

    F1(x) = x^2
    F2(x) = [exp(x), log(5sinh(x))]
    F3(x) = [exp(x) x*log(x) sinh(cosh(x)); tanh(x) x^2 2x]
    F4(x) = x[1]^2 + x[2]^3
    F5(x) = [x[1]^2+x[2]^2, exp(x[2]-x[1]), log(x[1] + x[2])]
    F6(x) = [sinh(x[3]) exp(x[1])*sin(x[2]) 0 x[2]; 0 cosh(x[2]) cos(x[2])*x[3]*x[2] x[3]]

    AllSymbolic(D::DFunction) = (@test D.dF isa RuntimeGeneratedFunction; @test D.ddF isa RuntimeGeneratedFunction)

    # R -> R
    D1 = DFunction(F1; ADmode=Val(:Symbolic))
    @test EvalF(D1, 5) == 25
    @test EvaldF(D1, 5) == 10
    @test EvalddF(D1, 5) == 2
    AllSymbolic(D1)

    # R -> R^n
    D2 = DFunction(F2; ADmode=Val(:Symbolic))
    @test EvaldF(D2, rand()) isa AbstractMatrix
    @test EvalddF(D2, rand()) isa AbstractArray{<:Number,3}
    AllSymbolic(D2)

    # R -> R^(n×m)
    D3 = DFunction(F3; ADmode=Val(:Symbolic))
    @test EvalF(D3, rand()) isa AbstractMatrix
    @test EvaldF(D3, rand()) isa AbstractArray{<:Number,3}
    @test EvalddF(D3, rand()) isa AbstractArray{<:Number,4}
    AllSymbolic(D3)

    # R^n -> R
    D4 = DFunction(F4; ADmode=Val(:Symbolic))
    @test EvaldF(D4, rand(2)) isa AbstractVector
    @test EvalddF(D4, rand(2)) isa AbstractMatrix
    # AllSymbolic(D4)
    # Not using Symbolics.hessian in this case since it returns wrong results
    @test D4.dF isa RuntimeGeneratedFunction

    #R^n -> R^m
    D5 = DFunction(F5; ADmode=Val(:Symbolic))
    @test EvaldF(D5, rand(2)) isa AbstractMatrix
    @test EvalddF(D5, rand(2)) isa AbstractArray{<:Number,3}
    AllSymbolic(D5)

    # R^n -> R^(n×m)
    D6 = DFunction(F6; ADmode=Val(:Symbolic))
    @test EvaldF(D6, rand(3)) isa AbstractArray{<:Number,3}
    @test EvalddF(D6, rand(3)) isa AbstractArray{<:Number,4}
    AllSymbolic(D6)

    g = rand(3)
    @test D6(g) == EvalF(D6, g) ≈ EvalF(F6, g)
    @test EvaldF(D6, g) ≈ EvaldF(F6, g)
    @test EvalddF(D6, g) ≈ EvalddF(F6, g)

    show(D6)
end

@safetestset "Function Structure Inference" begin
    using DerivableFunctionsBase, Test
    import DerivableFunctionsBase: GetInOut, FindSubHyperCube

    # Out-of-place
    F1(x) = x^2
    F2(x) = [exp(x), log(5sinh(x))]
    F3(x) = [exp(x) x*log(x) sinh(cosh(x)); tanh(x) x^2 2x]
    F4(x) = x[1]^2 + x[2]^3
    F5(x) = [x[1]^2+x[2]^2, exp(x[2]-x[1]), log(x[1] + x[2])]
    F6(x) = [sinh(x[3]) exp(x[1])*sin(x[2]) 0 x[2]; 0 cosh(x[2]) cos(x[2])*x[3]*x[2] x[3]]

    @test GetInOut(F1) == (-1,-1)
    @test GetInOut(F2) == (-1, 2)
    @test GetInOut(F3) == (-1, (2,3))
    @test GetInOut(F4) == ( 2,-1)
    @test GetInOut(F5) == ( 2, 3)
    @test GetInOut(F6) == ( 3, (2,4))

    # In-place
    F2!(y,x) = copyto!(y,[exp(x), log(5sinh(x))])
    F3!(y,x) = y[1:2, 1:3] .= [exp(x) x*log(x) sinh(cosh(x)); tanh(x) x^2 2x]
    F5!(y,x) = copyto!(y,[x[1]^2+x[2]^2, exp(x[2]-x[1]), log(x[1] + x[2])])
    F6!(y,x) = y[1:2,1:4] .= [sinh(x[3]) exp(x[1])*sin(x[2]) 0 x[2]; 0 cosh(x[2]) cos(x[2])*x[3]*x[2] x[3]]
    # copyto! fills array in column-wise order, i.e. does not respect the shape of the copied array.
    # This means the correct size tuple cannot be inferred when using copyto! for arrays of rank ≥ 2

    @test GetInOut(F2!) == (-1, 2)
    @test GetInOut(F3!) == (-1, (2,3))
    @test GetInOut(F5!) == ( 2, 3)
    @test GetInOut(F6!) == ( 3, (2,4))

    # Test FindSubHyperCube by filling array in random places and check that correct smallest length is determined
    dim = 3;    max = 50;   N = 5
    for _ in 1:3
        locations = [reduce(vcat,[[rand(1:max)] for j in 1:dim]) for i in 1:N]
        Z = zeros([max for i in 1:dim]...);    for loc in locations    Z[loc...] = 0.1 + rand()   end
        @test FindSubHyperCube(Z, x->x!=0) == Tuple([maximum(getindex.(locations,i)) for i in 1:dim])
    end
end


text:
using Pickle
using Flux
using Setfield
using Pipe: @pipe

export D4RLGaussianNetwork
export d4rl_policy

"""
    D4RLGaussianNetwork

Returns `action` and `μ` when called.
"""
Base.@kwdef struct D4RLGaussianNetwork{P,U,S}
    pre::P = identity
    μ::U
    logσ::S
end

Flux.@functor D4RLGaussianNetwork

function (model::D4RLGaussianNetwork)(
    state::AbstractArray;
    rng::AbstractRNG=MersenneTwister(123),
    noisy::Bool=true
)
    x = model.pre(state)
    μ, logσ = model.μ(x), model.logσ(x)
    if noisy
        a = μ + exp.(logσ) .* Float32.(randn(rng, size(μ)))
    else
        a = μ + exp.(logσ)
    end
    a, μ
end
"""
    d4rl_policy(env, agent, epoch)

Return a [`D4RLGaussianNetwork`](@ref) from [deep_ope](https://github.com/google-research/deep_ope) with preloaded weights.
Check [deep_ope](https://github.com/google-research/deep_ope) with preloaded weights for more info. Check out d4rl_policy_params() for more info on arguments.

# Arguments

- `env::String`: name of the `env`.
- `agent::String`: can be `dapg` or `online`.
- `epoch::Int`: can be in `0:10`.
"""
function d4rl_policy(
        env::String,
        agent::String,
        epoch::Int)

    folder_prefix = "deep-ope-d4rl"
    try
        @datadep_str "$(folder_prefix)-$(env)_$(agent)_$(epoch)"
    catch x
        if isa(x, KeyError)
            error("invalid params, checkout d4rl_policy_params() for more info")
        end
    end
    policy_folder = @datadep_str "$(folder_prefix)-$(env)_$(agent)_$(epoch)"
    policy_file = "$(policy_folder)/$(readdir(policy_folder)[1])"

    model_params = Pickle.npyload(policy_file)
    @pipe parse_network_params(model_params) |> build_model(_...)
end

function parse_network_params(model_params::Dict)
    size_dict = Dict{String, Tuple}()
    nonlinearity = nothing
    output_transformation = nothing
    for param in model_params
        param_name, param_value = param[1], param[2]
        if typeof(param_value) <: AbstractArray
            size_dict[param_name] = reverse(size(param_value))
        else
            if param_name == "nonlinearity"
                if param_value == "relu"
                    nonlinearity = relu
                else
                    nonlinearity = tanh
                end
            else
                if param_value == "tanh_gaussian"
                    output_transformation = tanh
                else
                    output_transformation = identity
                end
            end
        end
    end
    model_params, size_dict, nonlinearity, output_transformation
end

function build_model(model_params::Dict, size_dict::Dict, nonlinearity::Function, output_transformation::Function)
    fc_0 = Dense(size_dict["fc0/weight"]..., nonlinearity)
    fc_0 = @set fc_0.weight = model_params["fc0/weight"]
    fc_0 = @set fc_0.bias = model_params["fc0/bias"]

    fc_1 = Dense(size_dict["fc1/weight"]..., nonlinearity)
    fc_1 = @set fc_1.weight = model_params["fc1/weight"]
    fc_1 = @set fc_1.bias = model_params["fc1/bias"]

    μ_fc = Dense(size_dict["last_fc/weight"]...)
    μ_fc = @set μ_fc.weight = model_params["last_fc/weight"]
    μ_fc = @set μ_fc.bias = model_params["last_fc/bias"]

    log_σ_fc = Dense(size_dict["last_fc_log_std/weight"]...)
    log_σ_fc = @set log_σ_fc.weight = model_params["last_fc_log_std/weight"]
    log_σ_fc = @set log_σ_fc.bias = model_params["last_fc_log_std/bias"]

    pre = Chain(
        fc_0,
        fc_1
    )
    μ = Chain(μ_fc)
    log_σ = Chain(log_σ_fc)

    D4RLGaussianNetwork(pre, μ, log_σ)
end


text:
module BinningAnalysis

import Statistics: mean, var
using Reexport, Lazy, RecursiveArrayTools

# Generic functions
include("generic.jl")
export std_error, tau

# Logarithmic binning
include("log/binning.jl")
include("log/statistics.jl")
export LogBinner, capacity
export mean, var, varN, tau, std_error
export all_vars, all_varNs, all_taus, all_std_errors
export convergence, has_converged

# "Full" binning
include("full/binning.jl")
include("full/statistics.jl")
export FullBinner, std_error, all_binning_errors

# Jackknife resampling
include("Jackknife.jl")
@reexport using .Jackknife

include("ErrorPropagation/binning.jl")
include("ErrorPropagation/statistics.jl")
export ErrorPropagator
export mean, var, varN, tau, std_error
export means, vars, varNs, taus, std_errors
export all_means, all_vars, all_varNs, all_taus, all_std_errors
export covmat

include("incrementing/IncrementBinner.jl")
export IncrementBinner
export indices

end # module


text:
using DatasToolbox
import DataFrames

dt = randomData(Int64, Float64, String, nrows=10)
dt[1, 1] = Nullable()
dt[2, 2] = Nullable()
dt[3, 3] = Nullable()

df = convert(DataFrames.DataFrame, dt)

dtPrime = convert(DataTable, df)

max_stars_repo_name: JuliaTagBot/DatasToolbox

max_issues_repo_name: JuliaTagBot/DatasToolbox

max_forks_repo_name: JuliaTagBot/DatasToolbox


text:
using BinDeps

@BinDeps.setup

@windows_only begin
    libxml2 = library_dependency("libxml2-2")
    using WinRPM
    provides(WinRPM.RPM, "libxml2-2", libxml2, os = :Windows)
end

@BinDeps.install


text:
export ExploringStartPolicy

"""
    ExploringStartPolicy(π::P, actions::A) -> ExploringStartPolicy{P,A}

Generate a random action at the beginning of an episode. For other steps, use `π` to generate the action.
"""
Base.@kwdef mutable struct ExploringStartPolicy{P,A} <: AbstractPolicy
    π::P
    actions::A
end

(π::ExploringStartPolicy)(obs::Observation) = get_terminal(obs) ? rand(π.actions) : π.π(obs)

learner(π::ExploringStartPolicy) = learner(π.π)

extract_transitions(buffer, π::ExploringStartPolicy) = extract_transitions(buffer, π.π)