text:
#this file contains a list of file specific functions which each produce a dataframe
#The objective here is to minimize lines of code specific to each file
#Each function takes in the input dataframe only. A linker function selects
#the correct function from a symbol and a constant lookup table

const MAP = Dict(

)

max_stars_repo_name: clintonTE/CCA

max_issues_repo_name: clintonTE/CCA

max_forks_repo_name: clintonTE/CCA


text:
module Corebot
using Dates

function get_charset_r(date::Dates.Date, nr_b, r)
    year, month, day = Dates.year(date), Dates.month(date), Dates.day(date)
    r = (r + year + (nr_b<<16 + (month<<8)|day)) & 0xFFFFFFFF
    charset = "abcdefghijklmnopqrstuvwxyz0123456789"
    return charset, r
end

function gen_domain(charset, r, tld)
    domain = ""
    len_l, len_u = 0xC, 0x18
    r = (1664525*r + 1013904223) & 0xFFFFFFFF
    len_domain = len_l + r%(len_u-len_l)
    for _ in len_domain:-1:1
        r = ((1664525*r) + 1013904223) & 0xFFFFFFFF
        domain *= charset[r%length(charset)+1]
    end
    domain *= tld
    return r, domain
end

function gen_one(seed="1DBA8930", date=missing, tld="", nr_b=1, num=1)
    domain = ""
    if date === missing
        date = Dates.Date(Dates.now())
    end
    charset, r = get_charset_r(date, nr_b, parse(Int64, seed, base=16))
    for _ in 1:num
        r, domain = gen_domain(charset, r, tld)
    end
    return domain
end

function gen_many(cnt=100)
    res = []
    seed = "1DBA8930"
    date = Dates.Date(Dates.now())
    charset, r = get_charset_r(date, 1, parse(Int64, seed, base=16))
    for _ in 1:cnt
        r, domain = gen_domain(charset, r, "")
        res = [res...,domain]
    end
    return res
end

end  # module Corebot

ext: jl


text:
struct MetaStrategy{RS <: RestartStrategy, TS <: TabuStrategy}
    restart::RS
    tabu::TS
end

function MetaStrategy(model;
    tenure = min(length_vars(model) ÷ 2, 10),
    tabu = tabu(tenure, tenure ÷ 2),
    restart = restart(tabu, Val(:universal)),
)
    return MetaStrategy(restart, tabu)
end

# forwards from RestartStrategy
@forward MetaStrategy.restart check_restart!

# forwards from TabuStrategy
@forward MetaStrategy.tabu decrease_tabu!, delete_tabu!, decay_tabu!
@forward MetaStrategy.tabu length_tabu, insert_tabu!, empty_tabu!, tabu_list


text:
# Basic serial console.
# Data is read from a serial device and lines (but not individual keypresses)
# are written to the device asynchronously.

using LibSerialPort

function serial_loop(sp::SerialPort)
    input_line = ""
    mcu_message = ""

    println("Starting I/O loop. Press ESC [return] to quit")

    while true
        # Poll for new data without blocking
        @async input_line = readline(keep=true)
        @async mcu_message *= read(sp, String)

        # Alternative read method:
        # Requires setting a timeout and may cause bottlenecks
        # @async mcu_message = readuntil(sp, "\r\n", 50)

        occursin("\e", input_line) && exit()

        # Send user input to device
        if endswith(input_line, '\n')
            write(sp, "$input_line")
            input_line = ""
        end

        # Print message from device
        if occursin("\r\n", mcu_message)
            lines = split(mcu_message, "\r\n")
            while length(lines) > 1
                println(popfirst!(lines))
            end
            mcu_message = lines[1]
        end

        # Give the queued tasks a chance to run
        sleep(0.0001)
    end
end

function console(args...)

    if length(args) != 2
        println("Usage: $(basename(@__FILE__)) port baudrate")
        println("Available ports:")
        list_ports()
        return
    end

    # Open a serial connection to the microcontroller
    mcu = open(args[1], parse(Int, args[2]))

    serial_loop(mcu)
end

console(ARGS...)


text:
"""
    distance_profile(dist, Q, T; kwargs...)

Calculate the distance profile corresponding to sliding `Q` over `T` and measuring distances between time windows using `dist`

The output is a vector of length `length(T) - length(Q) + 1`.
If inputs are matrices or higher-dimensional arrays, time is considered to be the last axis, and windows on the form `T[:, t:t+lastlength(Q)-1]`, where `lastlength` measures the length along the last axis, are compared.

Keyword arguments are sent to `dist`, which is called like this `dist(Q,T; kwargs...)`. `dist` can be a function or a distance from Distances.jl.

`distance_profile!(D, dist, Q, T; kwargs...)` is an in-place version.
"""
function distance_profile(dist, Q::AbstractArray{S}, T::AbstractArray{S}; kwargs...) where S
    m = lastlength(Q)
    n = lastlength(T)
    n >= m || throw(ArgumentError("Q cannot be longer than T"))
    l = n-m+1
    D = map(1:l) do i
        dist(Q, getwindow(T, m, i); kwargs...)
    end
end

"$(SIGNATURES)"
function distance_profile!(D::AbstractArray, dist, Q::AbstractArray{S}, T::AbstractArray{S}; kwargs...) where S
    m = lastlength(Q)
    n = lastlength(T)
    n >= m || throw(ArgumentError("Q cannot be longer than T"))
    l = n-m+1
    length(D) >= l || throw(ArgumentError("D is too short"))
    map!(D, 1:l) do i
        dist(Q, getwindow(T, m, i); kwargs...)
    end
end

"$(SIGNATURES)"
function distance_profile!(D::AbstractVector{S},::ZEuclidean, QT::AbstractVector{S}, μ, σ, m::Int, i::Int) where S <: Number
    @assert i <= length(D)
    @avx for j = eachindex(D)
        frac = (QT[j] - m*μ[i]*μ[j]) / (m*σ[i]*σ[j])
        D[j] = sqrt(max(2m*(1-frac), 0))
    end
    D[i] = typemax(eltype(D))
    D
end

"$(SIGNATURES)"
distance_profile(
    ::ZEuclidean,
    QT::AbstractVector{S},
    μ::AbstractVector{S},
    σ::AbstractVector{S},
    m::Int,
) where {S<:Number} = distance_profile!(similar(μ), ZEuclidean(), QT, μ, σ, m, 1)

"""
    $(SIGNATURES)

Accepts precomputed sliding mean and std of the input arrays. `QT` is the windowed dot product and `i` is the index into `T` (the longer time series).
"""
function distance_profile!(D::AbstractVector{S},::ZEuclidean, QT::AbstractVector{S}, μA, σA, μT, σT, m::Int, i::Int) where S <: Number
    @assert i <= length(μA)
    @avx for j = eachindex(D,QT,μT,σT)
        frac = (QT[j] - m*μA[i]*μT[j]) / (m*σA[i]*σT[j])
        D[j] = sqrt(max(2m*(1-frac), 0))
    end
    D
end

"$(SIGNATURES)"
distance_profile(::ZEuclidean, QT::AbstractVector{S}, μA, σA, μT, σT, m::Int) where {S<:Number} =
    distance_profile!(similar(μT), ZEuclidean(), QT, μA, σA, μT, σT, m, 1)

"""
    distance_profile(::ZEuclidean, Q, T)

Compute the z-normalized Euclidean distance profile corresponding to sliding `Q` over `T`
"""
function distance_profile!(
    D::AbstractVector{S},
    ::ZEuclidean,
    Q::AbstractVector{S},
    T::AbstractVector{S},
) where {S<:Number}
    m = length(Q)
    μ, σ = sliding_mean_std(T, m)
    QT = window_dot(znorm(Q), T) # TODO: allocates a new znorm(Q) each time
    @avx for j in eachindex(D,QT,σ)
        frac = QT[j] / (m * σ[j])
        D[j] = sqrt(max(2m * (1 - frac), 0))
    end
    D
end

"$(SIGNATURES)"
distance_profile(::ZEuclidean, Q::AbstractArray{S}, T::AbstractArray{S}) where {S} =
    distance_profile!(similar(T, length(T) - length(Q) + 1), ZEuclidean(), Q, T)

"""
The dot product between query Q and all subsequences of the same length as Q in time series T
"""
function window_dot(Q, T)
    n   = length(T)
    m   = length(Q)
    QT  = conv(reverse(Q), T)
    return QT[m:n]
end

"""
    $(SIGNATURES)

return vectors with mean and std of sliding windows of length `m`
"""
function sliding_mean_std(x::AbstractVector{T}, m) where T
    @assert length(x) >= m
    n = length(x)-m+1
    s = ss = zero(float(T))
    μ = Vector{float(T)}(undef, n)
    σ = Vector{float(T)}(undef, n)
    @avx for i = 1:m
        s  += x[i]
        ss += x[i]^2
    end
    μ[1] = s/m
    σ[1] = sqrt(max(ss/m - μ[1]^2, 0))
    @fastmath @inbounds for i = 1:n-1 # fastmath making it more accurate here as well, but not faster
        s -= x[i]
        ss -= x[i]^2
        s += x[i+m]
        ss += x[i+m]^2
        μ[i+1] = s/m
        σ[i+1] = sqrt(max(ss/m - μ[i+1]^2, 0))
    end
    μ,σ
end

@inbounds @fastmath function sliding_mean_std(x::AbstractMatrix{T}, m) where T
    @assert lastlength(x) >= m
    n = lastlength(x)-m+1
    s  = zeros(T, size(x,1))
    ss = zeros(T, size(x,1))
    μ = Matrix{float(T)}(undef, size(x,1), n)
    σ = Matrix{float(T)}(undef, size(x,1), n)
    for i = 1:m
        @avx s  .+= view(x, :, i)
        @avx ss .+= view(x, :, i).^2
    end
    @avx μ[:,1] .= s./m
    @avx σ[:,1] .= sqrt.(max.(ss./m .- view(μ, :, 1).^2, 0))
    for i = 1:n-1 # fastmath making it more accurate here as well, but not faster
        @avx s .-= view(x, :, i)
        @avx ss .-= view(x, :, i).^2
        @avx s .+= view(x, :, i+m)
        @avx ss .+= view(x, :, i+m).^2
        @avx μ[:,i+1] .= s./m
        @avx σ[:,i+1] .= sqrt.(max.(ss./m .- view(μ, :, i+1).^2, 0))
    end
    μ,σ
end

"""
    $(SIGNATURES)

return mean of sliding windows of length `m`. Operates in-place and stores result in first argument
"""
function sliding_mean!(μ,x::AbstractVector{T}, m) where T
    n = length(x)-m+1
    @assert length(x) >= m
    @assert length(μ) >= n

    s = zero(T)
    @avx for i = 1:m
        s += x[i]
    end
    μ[1] = s/m
    @fastmath @inbounds for i = 1:n-1 # fastmath making it more accurate here as well, but not faster
        s -= x[i]
        s += x[i+m]
        μ[i+1] = s/m
    end
    μ
end

"""
$(SIGNATURES)

Returns the sliding-window entropy
"""
function sliding_entropy(x::AbstractVecOrMat{T}, m=actuallastlength(x)) where T
    N = actuallastlength(x)
    n = N-m+1
    e = Vector{T}(undef, n)
    if x isa AbstractVector
        ent = vmap(x->x*log(x), x)
    else
        ent = zeros(T, N)
        @avx for i = 1:N
            for j = 1:size(x,1)
                ent[i] += x[j,i]*log(x[j,i])
            end
        end
    end
    e0 = zero(T)
    @avx for i = 1:m
        e0 += ent[i]
    end
    e[1] = e0
    @fastmath @inbounds for i = 1:n-1
        e0 -= ent[i]
        e0 += ent[i+m]
        e[i+1] = e0
    end
    e .= .-e
end

"""
$(SIGNATURES)

Returns the sliding-window entropy, normalized to have unit sum for each feature channel.
"""
function sliding_entropy_normalized(x::AbstractArray{T}, m=actuallastlength(x)) where T
    sums = sum(x, dims=ndims(x))
    sliding_entropy(x ./ sums, m)
end


text:
using Pkg
Pkg.activate(".")
Pkg.status()
Pkg.offline()
Pkg.instantiate()

using Pidoh
mergeexperiments("./results")

max_stars_repo_name: DTUComputeTONIA/SDRLS

max_issues_repo_name: DTUComputeTONIA/SDRLS

max_forks_repo_name: DTUComputeTONIA/SDRLS


text:
# parser

function read_instance(MyFileName::String)
  path = "./Instances/" * MyFileName
  path_Affinity = path * "Affinity.txt"
  path_Commodity = path * "Commodity.txt"
  path_Fct_commod = path * "Fct_commod.txt"
  path_Functions = path * "Functions.txt"
  path_Graph = path * "Graph.txt"

  # Variables
  cout_ouverture = 1

  # Graph
  if isfile(path_Graph)
    myFile = open(path_Graph)
    readline(myFile)
    nb_nodes = parse(Int64, split(readline(myFile), " ")[2])
    nb_arcs = parse(Int64, split(readline(myFile), " ")[2])
    latency = Array{Any,2}(zeros(nb_nodes,nb_nodes))
    nb_functions_per_node = Array{Int64,1}(zeros(nb_nodes))
    for i in 1:nb_arcs
      line = split(replace(readline(myFile), "  " => " "), " ")
      line5 = parse.(Float64, line[5])
      line = parse.(Int64, line[1:4])
      latency[line[1]+1,line[2]+1] = line5
      nb_functions_per_node[line[1]+1] = line[3]
      nb_functions_per_node[line[2]+1] = line[4]
    end
    close(myFile)
  end

  # Commodity
  if isfile(path_Commodity)
    myFile = open(path_Commodity)
    readline(myFile)
    nb_commodities = parse(Int64, split(readline(myFile), " ")[2])
    commodity = Array{Any,2}(zeros(nb_commodities,4))
    for i in 1:nb_commodities
      line = parse.(Float64, split(readline(myFile), " "))
      commodity[i,1] = Int(line[1]) + 1
      commodity[i,2] = Int(line[2]) + 1
      commodity[i,3] = Int(line[3])
      commodity[i,4] = line[4]
    end
    close(myFile)
  end

  # Functions
  if isfile(path_Functions)
    myFile = open(path_Functions)
    readline(myFile)
    nb_func = parse(Int64, split(readline(myFile), " ")[2])
    func_capacity = Array{Int64,1}(zeros(nb_func))
    func_cost = Array{Int64,2}(zeros(nb_func,nb_nodes))
    for i in 1:nb_func
      line = parse.(Int64, split(readline(myFile), " "))
      func_capacity[i] = line[1]
      popfirst!(line)
      for j in 1:nb_nodes
        func_cost[i,j] = line[j]
      end
    end
    close(myFile)
  end

  # Fct_commod
  if isfile(path_Fct_commod)
    myFile = open(path_Fct_commod)
    Fct_commod = Array{Int64,2}(zeros(nb_commodities,nb_func))
		for i in 1:nb_commodities
      line = parse.(Int64, split(readline(myFile), " ")[1:5])
      cpt=1
      for f in line
        Fct_commod[i,f+1]=cpt
        cpt=cpt+1
      end
    end
    close(myFile)
  end

  # Affinity
  if isfile(path_Affinity)
    myFile = open(path_Affinity)
    exclusion = Array{Int64,2}(zeros(nb_commodities,2))
    for i in 1:nb_commodities
      myLine = readline(myFile)
      if myLine != "" && myLine != " "
        line = parse.(Int64, split(myLine, " "))
        if length(line) >=2
          exclusion[i,1] = line[1] + 1
          exclusion[i,2] = line[2] + 1
        end
      end
    end
    close(myFile)
  end
  return cout_ouverture, Fct_commod, func_cost, func_capacity, nb_nodes, nb_arcs, nb_commodities, latency, nb_functions_per_node, commodity, nb_func, exclusion
end

function write_results(fileName,e,x_ikf)

  cout_ouverture, Fct_commod, func_cost, func_capacity, nb_nodes, nb_arcs, nb_commodities, latency, node_capacity, commodity, nb_func, exclusion = read_instance(fileName)

  if !isfile("./Resultats/"*fileName*".txt")
		touch("./Resultats/"*fileName*".txt")
	end
	file = open("./Resultats/"*fileName*".txt","w")

	for k in 1:nb_commodities
    size_fk=length( findall( y -> y > 0, Fct_commod[k,:]))
		tab_fk=sortperm( Fct_commod[k,:])[1:size_fk]
		write(file,"commod "*string(k)*'\n')

    #write source to first function
		s=commodity[k,1]
		p= findall( y -> y == 1., x_ikf[:,k,tab_fk[1]])[1,1,1]
		sol=string(s)
		i=s
		while i!=p
			i=findall(y->y==1., e[i,:,k,tab_fk[1]])[1,1,1,1]
			sol=sol*" "*string(i)
		end
		sol=sol*'\n'
		write(file,sol)

    #write function to function
		for f in tab_fk[2:end]
			s=p
			p= findall( y -> y == 1., x_ikf[:,k,f])[1,1,1]
			sol=string(s)
			i=s
			while i!=p
				i=findall(y->y==1., e[i,:,k,f])[1,1,1,1]
				sol=sol*" "*string(i)
			end
			sol=sol*'\n'
			write(file,sol)
		end

    #write function to sink
    s=p
    p=commodity[k,2]
    sol=string(s)
    i=s
    while i!=p
      i=findall(y->y==1., e[i,:,k,end])[1,1,1,1]
      sol=sol*" "*string(i)
    end
    sol=sol*'\n'
    write(file,sol)
	end

	close(file)
end

max_stars_repo_name: VSpitzer/RORT

max_issues_repo_name: VSpitzer/RORT

max_forks_repo_name: VSpitzer/RORT


text:
split_tokenizer=split

punctremover_tokenizer

max_stars_repo_name: oxinabox/MLNLPP

max_issues_repo_name: oxinabox/MLNLPP

max_forks_repo_name: oxinabox/MLNLPP


text:
using StatisticalRethinking
using Literate
using Documenter

# The idea: generate both docs and notebooks using Literate
# Based on ideas and work from Tamas Papp!

DOC_ROOT = rel_path("..", "docs")
DocDir =  rel_path("..", "docs", "src")

page_list = Array{Pair{String, Any}, 1}();
append!(page_list, [Pair("Home", "intro.md")]);
append!(page_list, [Pair("Layout", "layout.md")])
append!(page_list, [Pair("Versions", "versions.md")]);
append!(page_list, [Pair("Acknowledgements", "acknowledgements.md")]);
append!(page_list, [Pair("References", "references.md")])

for chapter in keys(script_dict)
  ProjDir = rel_path( "..", "scripts", chapter)
  DocDir =  rel_path("..", "docs", "src", chapter)

  !isdir(ProjDir) && break

  cd(ProjDir) do

    script_list = Array{Pair{String, Any}, 1}();
    for script in script_dict[chapter]
      if script.doc
        file = script.scriptfile
        append!(script_list, [Pair(file[1:end-3], "$(chapter)/$(file[1:end-3]).md")])
        if script.exe && isfile(file)
          isfile(joinpath(DocDir, file[1:end-3], ".md")) &&
            rm(joinpath(DocDir, file[1:end-3], ".md"))
          Literate.markdown(joinpath(ProjDir, file), DocDir, documenter=true)
        end
      end
    end

    # Remove tmp directory used by cmdstan
    append!(page_list, [Pair("Chapter $(chapter)", script_list)])
    isdir("tmp") && rm("tmp", recursive=true);
    println("\nCompleted documentation generation for chapter $chapter\n")

  end # cd
end # for chapter

append!(page_list, [Pair("Functions", "index.md")])

makedocs(root = DOC_ROOT,
    modules = Module[],
    sitename = "StatisticalRethinking.jl",
    authors = "Rob Goedman, Richard Torkar, and contributors.",
    pages = page_list
)

deploydocs(root = DOC_ROOT,
    repo = "github.com/StatisticalRethinkingJulia/StatisticalRethinking.jl.git",
 )


text:
using CubicEoS
using LinearAlgebra

function quadratic(M::AbstractMatrix)
    @assert isposdef(M)
    @assert abs(det(M)) > 0

    F(x) = x' * M * x
    dF!(g, x) = begin g .= (M' + M) * x; g end
    ddF!(H, x) = begin H .= (M' + M); H end

    return F, dF!, ddF!
end

function quadratic(M::AbstractMatrix, b::AbstractVector)
    @assert isposdef(M)
    @assert abs(det(M)) > 0

    F(x) = x' * M * x - 2 * x' * b
    dF!(g, x) = begin g .= (M' + M) * x .- 2 .* b; g end
    ddF!(H, x) = begin H .= (M' + M); H end

    return F, dF!, ddF!
end

function system_test(M::AbstractMatrix, b::AbstractVector)
    f, df, ddf = quadratic(M, b)
    x₀ = 1000 .* rand(size(M, 1))
    optresult = CubicEoS.newton(f, df, ddf, x₀;
        maxiter=100,
        gtol=1e-3,
        constrain_step=(x, δ)->1.0,
    )
    dump(optresult)
    @show norm(optresult.argument, 2)

    @show f(optresult.argument)

    @show M \ b
    @show f(M \ b)
end

function quadratic_test(M::AbstractMatrix)
    f, df, ddf = quadratic(M)

    x₀ = 1000 .* rand(size(M, 1))
    optresult = CubicEoS.newton(f, df, ddf, x₀;
        maxiter=100,
        gtol=1e-6,
        constrain_step=(x, δ)->1.0,
    )
    dump(optresult)
    @show norm(optresult.argument, 2)
end

function quadratic_test(n::Integer=20)
    A = rand(n, n)
    return quadratic_test(A*A')
end

# quadratic_test(40)
# let A = [1 2; 4 5]
#     system_test(A*A', [1, 1])
# end
let n = 10, A = rand(n, n)
    system_test(A*A', rand(n))
end

max_stars_repo_name: vvpisarev/CubicEoS

max_issues_repo_name: vvpisarev/CubicEoS

max_forks_repo_name: vvpisarev/CubicEoS


text:
__precompile__(true)
module Foo
import Bar, Baz, Qux
this = "Foo1"
which = "depot"
end

max_stars_repo_name: nreigl/julia

max_issues_repo_name: BenChung/Julia-BTI

max_forks_repo_name: BenChung/Julia-BTI


text:
const caches = Dict{AbstractString, Dict}()

function writeObjectToCache(cacheType::AbstractString, searchKey::Dict{Symbol, Any}, object::Dict)
    if !haskey(caches, cacheType)
        caches[cacheType] = Dict()
    end

    # Store object in cache for 1 hour
    object["lastCached"] = now()

    for ky in keys(searchKey)
        k = string(ky)
        v = haskey(object, k) ? object[k] : haskey(object, "attributes") && haskey(object["attributes"], k) ? object["attributes"][k] : nothing

        if v != nothing
            caches[cacheType]["$(k)_$(v)"] =  object
        end
    end
end

function getObjectFromCache(cacheType::AbstractString, searchKey::Dict{Symbol, Any}, fetchStale::Bool=false)
    if !haskey(caches, cacheType)
        return nothing
    end

    cache = caches[cacheType]

    for (k, v) in searchKey
        if isa(v, Number) ? v > 0 : v != ""
            if haskey(cache, "$(k)_$(v)") && (fetchStale || cache["$(k)_$(v)"]["lastCached"] > now() - Dates.Hour(1))
                return cache["$(k)_$(v)"]
            end
        end
    end

    return nothing
end

# Internal convenience method for clearing object cache
function clearObjectCache(cacheType::AbstractString, searchKey::Dict{Symbol, Any})
    local object = getObjectFromCache(cacheType, searchKey)

    if object == nothing
        return false
    end

    done = false
    if isa(object, Dict)
        for ky in keys(searchKey)
            k = string(ky)
            v = haskey(object, k) ? object[k] : haskey(object["attributes"], k) ? object["attributes"][k] : nothing

            if typeof(v) != Void
                delete!(caches[cacheType], "$(ky)_$(v)")
                done = true
            end
        end
    end

    return done
end

"""
Expire an entry from the domain cache.  Use this if the domain has changed.

#### Keyword Arguments
`domainID::Int64`
:    The ID of the domain to expire.

`appKey::AbstractString`
:    The App Key (formerly known as API key) associated with the domain.  This is available from the mPulse domain configuration dialog.

`appName::AbstractString`
:    The App name in mPulse.  This can be got from the mPulse domain configuration dialog.

#### Returns
`true`
:    on success

`false`
:    if the entry was not in cache

"""
clearDomainCache(;domainID::Int64=0, appKey::AbstractString="", appName::AbstractString="") = clearObjectCache("domain", Dict{Symbol, Any}(:id => domainID, :key => appKey, :name => appName))

"""
Expire an entry from the tenant cache.  Use this if the tenant has changed.

#### Keyword Arguments
`tenantID::Int64`
:    The ID of the tenant to expire.

`name::AbstractString`
:    The Tenant name in mPulse.  This is got from the mPulse domain configuration dialog.

#### Returns
`true`
:    on success

`false`
:    if the entry was not in cache

"""
clearTenantCache(;tenantID::Int64=0, name::AbstractString="") = clearObjectCache("tenant", Dict{Symbol, Any}(:id => tenantID, :name => name))

"""
Expire an entry from the token cache.  Use this if the token associated with this tenant is no longer valid.

#### Arguments
`tenant::AbstractString`
:    The tenant name whose token needs to be expired

#### Returns
`true`
:    on success

`false`
:    if the entry was not in cache

"""
function clearTokenCache(tenant::AbstractString)
    # Unlike the other caches, this one only resets the timestamp
    # because we still want to cache credentials that were passed
    # in previously to make authentication easier
    if haskey(caches["token"], tenant)
        caches["token"][tenant]["tokenTimestamp"] = Date()
        return true
    end

    return false
end

"""
Expire an entry from the alert cache.  Use this if the alert has changed.

#### Keyword Arguments
`alertID::Int64`
:    The ID of the alert to expire.

`alertName::AbstractString`
:    The Alert name in mPulse.  This can be found from the mPulse alert configuration dialog.

#### Returns
`true`
:    on success

`false`
:    if the entry was not in cache

"""
clearAlertCache(;alertID::Int64=0, alertName::AbstractString="") = clearObjectCache("alert", Dict{Symbol, Any}(:id => alertID, :name => alertName))

"""
Expire an entry from the statistical model cache.  Use this if the model has changed.

#### Keyword Arguments
`statModelID::Int64`
:    The ID of the statistical model to expire.

`statModelName::AbstractString`
:    The statistical model name in mPulse.  This can be found from the mPulse statistical model configuration dialog.

#### Returns
`true`
:    on success

`false`
:    if the entry was not in cache

"""
clearStatModelCache(;statModelID::Int64=0, statModelName::AbstractString="") = clearObjectCache("statisticalmodel", Dict{Symbol, Any}(:id => statModelID, :name => statModelName))


text:
#=
This module contains functions that parse and structure data into a
dict for use with the NGL Molecule Viewer component.
One or multiple input data files in the PDB or .cif.gz format can be
entered to return a dict to input as the `data` param of the component.
=#

"""
  single_split(string, sep)

Helper function to split `string` into 2 sub string based on `sep`
# Example
```julia
  a,b = DashBioUtils.NglParser.single_split("hello.app",".")
```
"""
function single_split(string, sep)
  parts = split(string, sep)
  if length(parts) > 2
    ct = count(c -> c == only(sep), collect(string))
    throw("expected $(sep) once, found $(ct) in $(string)")
  end
  return parts
end

"""
get_highlights(string, sep, atom_indicator)

Helper function to set highlights using `string`, `sep`, `atom_indicator`

# Example
a,b = DashBioUtils.NglParser.get_highlights("Hello.app", ".", "a")
"""
function get_highlights(string, sep, atom_indicator)
  residues_list = []
  atoms_list = []

  str_, _str = single_split(string, sep)

  for e in split(_str, ",")
    if occursin(atom_indicator, e)
      push!(atoms_list, e)
    else
      push!(residues_list, e)
    end
  end
  return (str_, Dict("atoms" => join(atoms_list, ","), "residues" => join(residues_list, ",")))
end

"""
get_data(data_path, pdb_id, color; reset_view=false, lc=true)
"""
function get_data(data_path, pdb_id, color; reset_view=false, loc=true)
  chain = "ALL"
  aa_range = "ALL"
  highlight_dic = Dict("atoms" => "", "residues" => "")

  # Check if only one chain should be shown
  if occursin(".", pdb_id)
    pdb_id, chain = single_split(pdb_id, ".")
    highlights_sep = "@"
    atom_indicator = "a"

    # Check if only a specified amino acids range should be shown:
    if occursin(":", chain)
      chain, aa_range = single_split(chain, ":")

      # Check if atoms should be highlighted
      if occursin(highlights_sep,aa_range)
        aa_range, highlight_dic = get_highlights(
          aa_range, highlights_sep, atom_indicator
        )
      end
    else
      if occursin(highlights_sep, chain)
        chain, highlight_dic = get_highlights(
          chain, highlights_sep, atom_indicator
        )
      end
    end
  end
  if loc
    fname = [f for f in glob(string(data_path, pdb_id, ".*"))][1]
    if occursin("gz", fname)
      ext = split(fname, ".")[end-1]
      f = GZip.gzopen(fname,"r")
      rf = GZip.readline(f)
      content  = decode(rf, "UTF-8")
    else
      ext = split(fname, ".")[end]
      f = GZip.gzopen(fname,"r")
      content = GZip.readline(f)
    end
  else
    fname =  string(single_split(pdb_id, ".")[1], ".pdb")
    ext = split(fname, ".")[end]
    req = HTTP.request("GET", string(data_path, fname))
    content= decode(req.body, "UTF-8")
  end
  return Dict(
    "filename" => split(fname, "/")[end],
    "ext" => ext,
    "selectedValue" => pdb_id,
    "chain" => chain,
    "aaRange" => aa_range,
    "chosen" => highlight_dic,
    "color" => color,
    "config" => Dict("type" => "text/plain", "input" => content),
    "resetView" => reset_view,
    "uploaded" => false,
  )
end


text:
@inline function issquare(m::AbstractArray{T,2}) where {T<:Number}
    r, c = size(m)
    return r === c
end

@inline function issquare(m::Array{DoubleFloat{T},2}) where {T<:IEEEFloat}
    r, c = size(m)
    return r === c
end


text:
# using Soss
# using TransformVariables, Parameters, Flux, Distributions, Statistics, StatsFuns

# function fluxify(model)
#     t = getTransform(model)
#     z = randn(t.dimension) |> Flux.param

#     fpre = @eval $(logdensity(model))
#     f(par, data) = Base.invokelatest(fpre, par, data)

#     loss(data) = -f(transform(t, z), data)

#     ps = Flux.params(z)

#     (loss=loss, ps=ps, t=t)
# end

# @unpack loss, ps, t = fluxify(normalModel)

# using DataFrames

# df = DataFrame(x=randn(1000))
# data = Iterators.repeated((df,),100);

# history = []
# function evalcb(; df=train)
#     old = 1e100
#     function cb()
#         train_loss = loss(df) |> Tracker.data
#         @show train_loss
#         # old - train_loss > 1e-10 && Flux.stop()
#         append!(history, train_loss)
#         old = train_loss
#     end

#     cb
# end

# function makecb(; df=df)
#     history = DataFrame(; (ps.order[1].data |> t)...)
#     function cb()
#         push!(history, ps.order[1].data |> t)
#     end
# end

# cb = makecb()

# using Flux: @epochs
# @epochs 10 Flux.train!(loss, ps, data, ADAM(), cb= Flux.throttle(cb, 0.5))

# @show cb.history

# @show ps.order[1].data |> t

# zSize = 100

# # encode = Chain(
# #     x -> reshape(x, (1, 28, 28. :)
# #   , Conv((4,4), elu, stride=2)
# # )

# # decode = Chain(
# #     Dense(zSize, elu)
# #   , Dense()
# #   , x ->
# #   , Conv()
# #   , Dropout()
# #   , Conv()
# #   , elu
# # # )

# # vae = @model decode x
# #     xSize = size(x)
# #     n = prod(xSize)
# #     z ~ Normal(0,1) |> iid(n)
# #     ε = x - encode(z)
# #     ε ~ Normal(0,1)
# # end

# function loss()


text:
using Pkg
Pkg.activate(@__DIR__)
Pkg.instantiate()
include(joinpath(@__DIR__, "ex_C2_linear.jl"))
include(joinpath(@__DIR__, "ex_S4.jl"))
include(joinpath(@__DIR__, "ex_motzkin.jl"))
include(joinpath(@__DIR__, "ex_robinson_form.jl"))


text:
using JuMP, EAGO

                     m = Model()

                     EAGO.register_eago_operators!(m)

                     @variable(m, -1 <= x[i=1:2] <= 1)

                     @variable(m, -0.9705716506753843 <= q <= 1.6199082189427347)

                     add_NL_constraint(m, :(log(1 + exp(0.27812717705086953 + -0.4967460082986306*log(1 + exp(-0.6740257057257448 + -0.0007917455797805673*log(1 + exp(-0.08584163188401472 + 0.6683752749724832*log(1 + exp(0.3679628458703208 + -0.7706264460934666*$(x[1]) + -0.03424767458492983*$(x[2]))) + -0.39230803394698555*log(1 + exp(0.40575897127542815 + 0.13151803175485233*$(x[1]) + 0.5944153777408365*$(x[2]))))) + 0.5330540695702357*log(1 + exp(-0.7769463282105753 + 0.25325339074048747*log(1 + exp(0.3679628458703208 + -0.7706264460934666*$(x[1]) + -0.03424767458492983*$(x[2]))) + 0.5840452662855768*log(1 + exp(0.40575897127542815 + 0.13151803175485233*$(x[1]) + 0.5944153777408365*$(x[2]))))))) + -0.883304587160544*log(1 + exp(0.3709718635886192 + -0.47514710764751555*log(1 + exp(-0.08584163188401472 + 0.6683752749724832*log(1 + exp(0.3679628458703208 + -0.7706264460934666*$(x[1]) + -0.03424767458492983*$(x[2]))) + -0.39230803394698555*log(1 + exp(0.40575897127542815 + 0.13151803175485233*$(x[1]) + 0.5944153777408365*$(x[2]))))) + 0.6627028336583534*log(1 + exp(-0.7769463282105753 + 0.25325339074048747*log(1 + exp(0.3679628458703208 + -0.7706264460934666*$(x[1]) + -0.03424767458492983*$(x[2]))) + 0.5840452662855768*log(1 + exp(0.40575897127542815 + 0.13151803175485233*$(x[1]) + 0.5944153777408365*$(x[2]))))))))) + log(1 + exp(0.48450040123340576 + -0.32897580116872405*log(1 + exp(-0.6740257057257448 + -0.0007917455797805673*log(1 + exp(-0.08584163188401472 + 0.6683752749724832*log(1 + exp(0.3679628458703208 + -0.7706264460934666*$(x[1]) + -0.03424767458492983*$(x[2]))) + -0.39230803394698555*log(1 + exp(0.40575897127542815 + 0.13151803175485233*$(x[1]) + 0.5944153777408365*$(x[2]))))) + 0.5330540695702357*log(1 + exp(-0.7769463282105753 + 0.25325339074048747*log(1 + exp(0.3679628458703208 + -0.7706264460934666*$(x[1]) + -0.03424767458492983*$(x[2]))) + 0.5840452662855768*log(1 + exp(0.40575897127542815 + 0.13151803175485233*$(x[1]) + 0.5944153777408365*$(x[2]))))))) + 0.43090905819531766*log(1 + exp(0.3709718635886192 + -0.47514710764751555*log(1 + exp(-0.08584163188401472 + 0.6683752749724832*log(1 + exp(0.3679628458703208 + -0.7706264460934666*$(x[1]) + -0.03424767458492983*$(x[2]))) + -0.39230803394698555*log(1 + exp(0.40575897127542815 + 0.13151803175485233*$(x[1]) + 0.5944153777408365*$(x[2]))))) + 0.6627028336583534*log(1 + exp(-0.7769463282105753 + 0.25325339074048747*log(1 + exp(0.3679628458703208 + -0.7706264460934666*$(x[1]) + -0.03424767458492983*$(x[2]))) + 0.5840452662855768*log(1 + exp(0.40575897127542815 + 0.13151803175485233*$(x[1]) + 0.5944153777408365*$(x[2]))))))))) - $q <= 0.0))

                     @objective(m, Min, q)

                     return m

max_stars_repo_name: PSORLab/RSActivationFunctions

max_issues_repo_name: PSORLab/RSActivationFunctions

max_forks_repo_name: PSORLab/RSActivationFunctions


text:
module CommunalHelperEquationMoveBlock

using ..Ahorn, Maple
using Ahorn.CommunalHelper

@mapdef Entity "CommunalHelper/EquationMoveBlock" EquationMoveBlock(
    x::Integer,
    y::Integer,
    width::Integer=Maple.defaultBlockWidth,
    height::Integer=Maple.defaultBlockWidth,
    direction::String="Right",
    moveSpeed::Number=60.0,
    customBlockTexture::String="",
    equation::Integer=3,
	constantA::Number=10,
	constantB::Number=0.05,
	idleColor::String="474070",
    pressedColor::String="30b335",
    breakColor::String="cc2541",
)

const placements = Ahorn.PlacementDict(
    "Equation Move Block (Beta) ($direction) (Communal Helper)" => Ahorn.EntityPlacement(
        EquationMoveBlock,
        "rectangle",
        Dict{String,Any}(
            "direction" => direction,
        ),
    ) for direction in Maple.move_block_directions
)

placements["Equation Move Block (Beta) (Reskinnable) (Communal Helper)"] = Ahorn.EntityPlacement(
    EquationMoveBlock,
    "rectangle",
    Dict{String,Any}(
        "customBlockTexture" => "CommunalHelper/customConnectedBlock/customConnectedBlock",
    ),
)

placements["Equation Move Block (Beta) (Flag-controlled) (Communal Helper)"] = Ahorn.EntityPlacement(
    EquationMoveBlock,
    "rectangle",
    Dict{String,Any}(
        "activatorFlags" => "_pressed",
		"breakerFlags" => "_obstructed",
		"onActivateFlags" => "",
		"onBreakFlags" => "",
		"barrierBlocksFlags" => false,
		"waitForFlags" => false,
    ),
)

Ahorn.editingOptions(entity::EquationMoveBlock) = Dict{String,Any}(
    "direction" => Maple.move_block_directions,
    "moveSpeed" => Dict{String,Number}(
        "Slow" => 60.0,
        "Fast" => 75.0,
    ),
)
Ahorn.minimumSize(entity::EquationMoveBlock) = 16, 16
Ahorn.resizable(entity::EquationMoveBlock) = true, true

Ahorn.selection(entity::EquationMoveBlock) = Ahorn.getEntityRectangle(entity)

const arrows = Dict{String,String}(
    "up" => "objects/moveBlock/arrow02",
    "left" => "objects/moveBlock/arrow04",
    "right" => "objects/moveBlock/arrow00",
    "down" => "objects/moveBlock/arrow06",
)
const customArrowSprites = Dict{String,String}(
    "up" => "/arrow02",
    "left" => "/arrow04",
    "right" => "/arrow00",
    "down" => "/arrow06",
)

const buttonColor = (71, 64, 112, 255) ./ 255
const button = "objects/moveBlock/button"

const midColor = (4, 3, 23, 255) ./ 255
const highlightColor = (59, 50, 101, 255) ./ 255

function Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::EquationMoveBlock, room::Maple.Room)
    x = Int(get(entity.data, "x", 0))
    y = Int(get(entity.data, "y", 0))

    width = Int(get(entity.data, "width", 32))
    height = Int(get(entity.data, "height", 32))

    tileWidth = div(width, 8)
    tileHeight = div(height, 8)

    Ahorn.drawRectangle(ctx, 1, 1, width - 2, height - 2, highlightColor, highlightColor)
    Ahorn.drawRectangle(ctx, 8, 8, width - 16, height - 16, midColor)

    atlas = Ahorn.getAtlas("Gameplay")
    customBlockTexture = String(get(entity.data, "customBlockTexture", ""))
    hasCustomTexture = customBlockTexture != ""
    txOffset = 0

    direction = lowercase(get(entity.data, "direction", "up"))
    arrowSprite = get(atlas, arrows[direction], nothing)

    blockPath, innerCornersPath = "objects/moveBlock/base", "objects/CommunalHelper/connectedMoveBlock/innerCorners"

    if hasCustomTexture
        arrowSprite = get(atlas, "objects/" * customBlockTexture * customArrowSprites[direction], arrowSprite)
        blockPath = innerCornersPath = "objects/" * customBlockTexture
        txOffset = 24
    end

    block = get(atlas, blockPath, nothing)
    if (block === nothing)
        block = get(atlas, blockPath * "/tileset", Ahorn.fileNotFoundSpriteHolder)
    end

    innerCorners = get(atlas, innerCornersPath, nothing)
    if (innerCorners === nothing)
        innerCorners = get(atlas, innerCornersPath * "/tileset", Ahorn.fileNotFoundSpriteHolder)
    end

    arrowSprite = arrowSprite.sprite
    block = typeof(block) == Ahorn.SpriteHolder ? block.sprite : block
    innerCorners = typeof(innerCorners) == Ahorn.SpriteHolder ? innerCorners.sprite : innerCorners

    rects = getExtensionRectangles(room)
    rect = Ahorn.Rectangle(x, y, width, height)
    if !(rect in rects)
        push!(rects, rect)
    end

    for i in 1:tileWidth, j in 1:tileHeight
        drawX, drawY = (i - 1) * 8, (j - 1) * 8

        closedLeft = !notAdjacent(entity, drawX - 8, drawY, rects)
        closedRight = !notAdjacent(entity, drawX + 8, drawY, rects)
        closedUp = !notAdjacent(entity, drawX, drawY - 8, rects)
        closedDown = !notAdjacent(entity, drawX, drawY + 8, rects)
        completelyClosed = closedLeft && closedRight && closedUp && closedDown

        if completelyClosed
            if notAdjacent(entity, drawX + 8, drawY - 8, rects)
                # up right
                Ahorn.drawImage(ctx, innerCorners, drawX, drawY, 8 + txOffset, 0, 8, 8)

            elseif notAdjacent(entity, drawX - 8, drawY - 8, rects)
                # up left
                Ahorn.drawImage(ctx, innerCorners, drawX, drawY, 0 + txOffset, 0, 8, 8)

            elseif notAdjacent(entity, drawX + 8, drawY + 8, rects)
                # down right
                Ahorn.drawImage(ctx, innerCorners, drawX, drawY, 8 + txOffset, 8, 8, 8)

            elseif notAdjacent(entity, drawX - 8, drawY + 8, rects)
                # down left
                Ahorn.drawImage(ctx, innerCorners, drawX, drawY, 0 + txOffset, 8, 8, 8)

            else
                # entirely surrounded, fill tile
                Ahorn.drawImage(ctx, block, drawX, drawY, 8, 8, 8, 8)
            end
        else
            if closedLeft && closedRight && !closedUp && closedDown
                Ahorn.drawImage(ctx, block, drawX, drawY, 8, 0, 8, 8)

            elseif closedLeft && closedRight && closedUp && !closedDown
                Ahorn.drawImage(ctx, block, drawX, drawY, 8, 16, 8, 8)

            elseif closedLeft && !closedRight && closedUp && closedDown
                Ahorn.drawImage(ctx, block, drawX, drawY, 16, 8, 8, 8)

            elseif !closedLeft && closedRight && closedUp && closedDown
                Ahorn.drawImage(ctx, block, drawX, drawY, 0, 8, 8, 8)

            elseif closedLeft && !closedRight && !closedUp && closedDown
                Ahorn.drawImage(ctx, block, drawX, drawY, 16, 0, 8, 8)

            elseif !closedLeft && closedRight && !closedUp && closedDown
                Ahorn.drawImage(ctx, block, drawX, drawY, 0, 0, 8, 8)

            elseif !closedLeft && closedRight && closedUp && !closedDown
                Ahorn.drawImage(ctx, block, drawX, drawY, 0, 16, 8, 8)

            elseif closedLeft && !closedRight && closedUp && !closedDown
                Ahorn.drawImage(ctx, block, drawX, drawY, 16, 16, 8, 8)
            end
        end
    end

    Ahorn.drawRectangle(ctx, div(width - arrowSprite.width, 2) + 1, div(height - arrowSprite.height, 2) + 1, 8, 8, highlightColor, highlightColor)
    Ahorn.drawImage(ctx, arrowSprite, div(width - arrowSprite.width, 2), div(height - arrowSprite.height, 2))
end

end


text:
t = time()
client = connect(2000)
for i::Int=1:1000000
  read(client, UInt8)
  if i::Int === 1 t::Float64 = time() end
  if i::Int === 1000000
    t::Float64 = time() - t::Float64
    println("rps: ", i::Int / t::Float64, ", time: ", t::Float64)
  end
end

max_stars_repo_name: tmptrash/jevo

max_issues_repo_name: tmptrash/jevo

max_forks_repo_name: tmptrash/jevo


text:
using ApproxManifoldProducts

# using JLD2
# @load "mmdse2.jld2" pred meas

# x,y,theta
pred = randn(3,100)
meas = randn(3,100)

val = [0.0]
mmd!(val, pred, meas, SE2_Manifold)

val

## Can visualize two poses with

using RoMEPlotting, RoME

plotFactorValues(meas, pred, Pose2Pose2)


text:
tests = [
    "sparsevec",
    "sparsemat",
    "math",
    "linalg"]

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


text:
import StatsBase: countmap

abstract Dist

type Euclidean <: Dist
end

abstract KNN

type KnnClassifier <: KNN
    k::Integer
    dis_func::Dist
    X::Matrix
    y::Vector
end

type KnnRegression <: KNN
    k::Integer
    dis_func::Dist
    X::Matrix
    y::Vector
end

function KnnClassifier(;
                       k::Integer = 5,
                       dist_func::Dist = Euclidean(),
                       X::Matrix = zeros(2,2),
                       y::Vector = zeros(2))
    return KnnClassifier(k,dist_func,X,y)
end

function KnnRegression(;
                       k::Integer = 5,
                       dist_func::Dist = Euclidean(),
                       X::Matrix = zeros(2,2),
                       y::Vector = zeros(2))
    return KnnClassifier(k,dist_func,X,y)
end

function train!(model::KnnClassifier, X::Matrix, y::Vector)
    model.X = X
    model.y = y
end

function predict(model::KnnClassifier,
                 x::Matrix)
    n = size(x,1)
    res = zeros(n)
    for i = 1:n
        res[i] = predict(model, x[i,:])
    end
    return res
end

function predict(model::KnnClassifier,
                 x::Vector)
    n = size(model.X,1)
    res = zeros(n)
    for i = 1:n
        res[i] = dist(model.X[i,:],x,model.dis_func)
    end
    ind = sortperm(res)
    y_cos = model.y[ind[1:model.k]]
    label = 0
    label_freq = 0
    for (key,value) in countmap(y_cos)
        if value > label_freq
            label_freq = value
            label = key
        end
    end
    return label

end

function predict(model::KnnRegression,
                 x::Vector)
    n = size(model.X,1)
    res = zeros(n)
    for i = 1:n
        res[i] = dist(model.X[i,:],x,model.dis_func)
    end
    ind = sortperm(res)
    y_cos = model.y[ind[1:model.k]]
    return mean(y_cos)
end

function dist(x::Vector, y::Vector, dist_func::Euclidean)
    return norm(x-y)
end

function test_kneast_regression()

    X_train, X_test, y_train, y_test = make_reg(n_features = 1)

    model = KnnRegression()
    train!(model,X_train, y_train)
    predictions = predict(model,X_test)
    print("regression msea", mean_squared_error(y_test, predictions))
    PyPlot.scatter(X_test, y_test, color = "black")
    PyPlot.scatter(X_test, predictions, color = "green")
    legend(loc="upper right",fancybox="true")
end

function test_kneast_classification()
    X_train, X_test, y_train, y_test = make_digits()
    model = KnnClassifier()
    train!(model,X_train, y_train)
    predictions = predict(model,X_test)
    print("classification accuracy", accuracy(y_test, predictions))

    #PCA

    pca_model = PCA()
    train!(pca_model, X_test)
    plot_in_2d(pca_model, X_test, predictions, "kneast_classification")

end


text:
"""
Mutable Struct: Contains the created scale factors from code to physical units
"""
mutable struct ScalesType
# exported

   # length
   Mpc::Float64
   kpc::Float64
   pc::Float64
   mpc::Float64
   ly::Float64
   Au::Float64
   km::Float64
   m::Float64
   cm::Float64
   mm::Float64
   μm::Float64

   # volume
   Mpc3::Float64
   kpc3::Float64
   pc3::Float64
   mpc3::Float64
   ly3::Float64
   Au3::Float64
   km3::Float64
   m3::Float64
   cm3::Float64
   mm3::Float64
   μm3::Float64

   # density
   Msol_pc3::Float64
   g_cm3::Float64

   # surface
   Msol_pc2::Float64
   g_cm2::Float64

   # time
   Gyr::Float64
   Myr::Float64
   yr::Float64
   s::Float64
   ms::Float64

   # mass
   Msol::Float64
   Mearth::Float64
   Mjupiter::Float64
   g::Float64

   # speed
   km_s::Float64
   m_s::Float64
   cm_s::Float64

   nH::Float64
   erg::Float64
   g_cms2::Float64

   T_mu::Float64
   Ba::Float64
   ScalesType() = new()
end

"""
Mutable Struct: Contains the physical constants in cgs units
"""
 mutable struct PhysicalUnitsType
# exported
    # in cgs units
     Au::Float64#cm: Astronomical unit
     Mpc::Float64 #cm: Parsec
     kpc::Float64 #cm: Parsec
     pc::Float64 #cm: Parsec
     mpc::Float64 #cm: MilliParsec
     ly::Float64 #cm: Light year
     Msol::Float64 #g: Solar mass
     Mearth::Float64 #g: Earth mass
     Mjupiter::Float64 #g: Jupiter mass
     Rsol::Float64 #cm: Solar radius
    # Lsol = #erg s-2: Solar luminosity
    # Mearth = #g: Earh mass

     me::Float64 #g: electron mass
     mp::Float64 #g: proton mass
     mn::Float64 #g: neutron mass
     mH::Float64 #g: hydrogen mass
     amu::Float64 #g: atomic mass unit
     NA::Float64 # Avagadro's number
     c::Float64 #cm s-1: speed of light in a vacuum
    # h = #erg s: Planck constant
    # hbar = #erg s
     G::Float64 # cm3 g-1 g-2 Gravitational constant
     kB::Float64 #erg k-1 Boltzmann constant
     Gyr::Float64 #sec: defined as 365.25 days
     Myr::Float64 #sec: defined as 365.25 days
     yr::Float64 #sec: defined as 365.25 days
     PhysicalUnitsType() = new()
end

mutable struct FileNamesType
    output::String
    info::String
    amr::String
    hydro::String
    hydro_descriptor::String
    gravity::String
    particles::String
    part_descriptor::String
    rt::String
    rt_descriptor::String
    rt_descriptor_v0::String
    clumps::String
    timer::String
    header::String
    namelist::String
    compilation::String
    makefile::String
    patchfile::String
    FileNamesType() = new()
end

"""
Mutable Struct: Contains the collected information about grid
"""
mutable struct GridInfoType
# exported
    ngridmax::Int
    nstep_coarse::Int
    nx::Int
    ny::Int
    nz::Int
    nlevelmax::Int
    nboundary::Int
    ngrid_current::Int
    bound_key::Array{Float64,1}
    cpu_read::Array{Bool,1}
    GridInfoType() = new()
end

"""
Mutable Struct: Contains the collected information about particles
"""
mutable struct PartInfoType
# exported
    eta_sn::Float64
    age_sn::Float64
    f_w::Float64
    Npart::Int
    Ndm::Int
    Nstars::Int
    Nsinks::Int
    Ncloud::Int
    Ndebris::Int
    Nother::Int
    Nundefined::Int
    other_tracer1::Int
    debris_tracer::Int
    cloud_tracer::Int
    star_tracer::Int
    other_tracer2::Int
    gas_tracer::Int
    PartInfoType() = new()
end

"""
Mutable Struct: Contains the collected information about the compilation of RAMSES
"""
mutable struct CompilationInfoType
# exported
    compile_date::String
    patch_dir::String
    remote_repo::String
    local_branch::String
    last_commit::String
    CompilationInfoType() = new()
end

"""
Mutable Struct: Contains the collected information about the descriptors
"""
mutable struct DescriptorType
# exported
    hversion::Int
    hydro::Array{Symbol,1}
    htypes::Array{String,1}
    usehydro::Bool
    hydrofile::Bool

    pversion::Int
    particles::Array{Symbol,1}
    ptypes::Array{String,1}
    useparticles::Bool
    particlesfile::Bool

    gravity::Array{Symbol,1}
    usegravity::Bool
    gravityfile::Bool

    rtversion::Int
    rt::Dict{Any,Any}
    rtPhotonGroups::Dict{Any,Any}
    usert::Bool
    rtfile::Bool

    clumps::Array{Symbol,1}
    useclumps::Bool
    clumpsfile::Bool

    sinks::Array{Symbol,1}
    usesinks::Bool
    sinksfile::Bool

    DescriptorType() = new()
end

mutable struct FilesContentType
    makefile::Array{String,1}
    timerfile::Array{String,1}
    patchfile::Array{String,1}
    FilesContentType() = new()
end

"""
Mutable Struct: Collected information about the selected simulation output
"""
mutable struct InfoType
    # exported
    output::Real
    path::String
    fnames::FileNamesType
    simcode::String
    mtime::DateTime
    ctime::DateTime
    ncpu::Int
    ndim::Int
    levelmin::Int
    levelmax::Int
    boxlen::Float64
    time::Float64
    aexp::Float64
    H0::Float64
    omega_m::Float64
    omega_l::Float64
    omega_k::Float64
    omega_b::Float64
    unit_l::Float64
    unit_d::Float64
    unit_m::Float64
    unit_v::Float64
    unit_t::Float64
    gamma::Float64

    hydro::Bool
    nvarh::Int   # number of hydro variables
    nvarp::Int   # number of particle variables
    nvarrt::Int  # number of rt variables

    variable_list::Array{Symbol,1}  # hydro variable list
    gravity_variable_list::Array{Symbol,1}
    particles_variable_list::Array{Symbol,1}
    rt_variable_list::Array{Symbol,1}
    clumps_variable_list::Array{Symbol,1}
    sinks_variable_list::Array{Symbol,1}
    descriptor::DescriptorType

    amr::Bool
    gravity::Bool
    particles::Bool
    rt::Bool
    clumps::Bool
    sinks::Bool

    namelist::Bool
    namelist_content::Dict{Any,Any}
    headerfile::Bool
    makefile::Bool
    files_content::FilesContentType
    timerfile::Bool
    compilationfile::Bool
    patchfile::Bool
    Narraysize::Int
    scale::ScalesType
    grid_info::GridInfoType
    part_info::PartInfoType
    compilation::CompilationInfoType
    constants::PhysicalUnitsType
    #overview::simulation_overview
    #cpu_overview::cpu_overview_type
    #boxcenter::Array{Float64,1}
    InfoType() = new()
end

mutable struct LevelType
  imin::Int
  imax::Int
  jmin::Int
  jmax::Int
  kmin::Int
  kmax::Int
end

"""
Abstract Supertype of all the different dataset types
> HydroPartType <: ContainMassDataSetType <: DataSetType
"""
abstract type DataSetType end # exported

"""
Abstract Supertype of all datasets that contain mass variables
> HydroPartType <: ContainMassDataSetType <: DataSetType
"""
abstract type ContainMassDataSetType <: DataSetType end # exported

"""
Abstract Supertype of data-sets that contain hydro and particle data
> HydroPartType <: ContainMassDataSetType <: DataSetType
"""
abstract type HydroPartType <: ContainMassDataSetType end # exported

"""
Mutable Struct: Contains hydro data and information about the selected simulation
> HydroDataType <: HydroPartType
"""
mutable struct HydroDataType <: HydroPartType
    # exported
    data::JuliaDB.AbstractIndexedTable
    info::InfoType
    lmin::Int
    lmax::Int
    boxlen::Float64
    ranges::Array{Float64,1}
    selected_hydrovars::Array{Int,1}
    used_descriptors::Dict{Any,Any}
    smallr::Float64
    smallc::Float64
    scale::ScalesType
    HydroDataType() = new()
end

# exported
# mutable struct GravDataType <: DataSetType
#     data
#     info::InfoType
#     lmin::Int
#     lmax::Int
#     boxlen::Float64
#     ranges::Array{Float64,1}
#     selected_gravvars::Array{Int,1}
#     scale::ScalesType
#     GravDataType() = new()
# end

"""
Mutable Struct: Contains particle data and information about the selected simulation
> PartDataType <: HydroPartType
"""
mutable struct PartDataType <: HydroPartType
#exported
    data::JuliaDB.AbstractIndexedTable
    info::InfoType
    lmin::Int
    lmax::Int
    boxlen::Float64
    ranges::Array{Float64,1}
    selected_partvars::Array{Symbol,1}
    used_descriptors::Dict{Any,Any}
    scale::ScalesType
    PartDataType() = new()
end

"""
Mutable Struct: Contains clump data and information about the selected simulation
> ClumpDataType <: ContainMassDataSetType
"""
mutable struct ClumpDataType <: ContainMassDataSetType
# exported
    data
    info::InfoType
    boxlen::Float64
    ranges::Array{Float64,1}
    selected_clumpvars::Array{Symbol,1}
    used_descriptors::Dict{Any,Any}
    scale::ScalesType
    ClumpDataType() = new()
end

"""
Union Type: Mask-array that is of type Bool or BitArray
MaskType = Union{Array{Bool,1},BitArray{1}}
"""
MaskType = Union{Array{Bool,1},BitArray{1}} # exported

MaskArrayType = Union{ Array{Array{Bool,1},1}, Array{BitArray{1},1} }
MaskArrayAbstractType = Union{ MaskArrayType, Array{AbstractArray{Bool,1},1} } # used for the combined center_of_mass function
#HydroPartType = Union{HydroDataType, PartDataType}

"""
Mutable Struct: Contains the output statistics returned by wstat
"""
mutable struct WStatType
    mean::Float64
    median::Float64
    std::Float64
    skewness::Float64
    kurtosis::Float64
    min::Float64
    max::Float64
end

"""
Abstract Supertype of all the different dataset type maps
HydroMapsType <: DataMapsType
PartMapsType <: DataMapsType
"""
abstract type DataMapsType end # exported

"""
Mutable Struct: Contains the maps/units returned by the hydro-projection information about the selected simulation
"""
mutable struct HydroMapsType <: DataMapsType
    maps::DataStructures.SortedDict{Any,Any,Base.Order.ForwardOrdering}
    maps_unit::DataStructures.SortedDict{Any,Any,Base.Order.ForwardOrdering}
    maps_lmax::DataStructures.SortedDict{Any,Any,Base.Order.ForwardOrdering}
    maps_mode::DataStructures.SortedDict{Any,Any,Base.Order.ForwardOrdering}
    lmax_projected::Real
    lmin::Int
    lmax::Int
    ranges::Array{Float64,1}
    extent::Array{Float64,1}
    cextent::Array{Float64,1}
    ratio::Float64
    boxlen::Float64
    smallr::Float64
    smallc::Float64
    scale::ScalesType
    info::InfoType
end

"""
Mutable Struct: Contains the maps/units returned by the particles-projection information about the selected simulation
"""
mutable struct PartMapsType <: DataMapsType
    maps::DataStructures.SortedDict{Any,Any,Base.Order.ForwardOrdering}
    maps_unit::DataStructures.SortedDict{Any,Any,Base.Order.ForwardOrdering}
    maps_lmax::DataStructures.SortedDict{Any,Any,Base.Order.ForwardOrdering}
    maps_mode::DataStructures.SortedDict{Any,Any,Base.Order.ForwardOrdering}
    lmax_projected::Real
    lmin::Int
    lmax::Int
    ref_time::Real
    ranges::Array{Float64,1}
    extent::Array{Float64,1}
    cextent::Array{Float64,1}
    ratio::Float64
    boxlen::Float64
    scale::ScalesType
    info::InfoType
end

"""
Mutable Struct: Contains the 2D histogram returned by the function: histogram2 and information about the selected simulation
"""
mutable struct Histogram2DMapType
    map::Array{Float64,2}
    closed::Symbol
    weight::Tuple{Symbol,Symbol}
    nbins::Array{Int,1}
    xrange::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}
    yrange::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}
    extent::Array{Float64,1}
    ratio::Float64
    scale::ScalesType
    info::InfoType
end

"""
Mutable Struct: Contains the existing simulation snapshots in a folder and a list of the empty output-folders
"""
mutable struct CheckOutputNumberType
    outputs::Array{Int,1}
    missing::Array{Int,1}
end


text:
"""
defines generic Dynamic type
"""

module DynamicDefinition

using ValidatedNumerics
using TaylorSeries:Taylor1
export Dynamic, MarkovDynamic, preim, nbranches, plottable, is_full_branch, domain, derivative, distorsion, endpoints, branch, expansivity, max_distorsion, orientation

abstract type Dynamic end
abstract type MarkovDynamic <: Dynamic end

domain(S::Dynamic) = @error "Not implemented"
nbranches(S::Dynamic) = @error "Not implemented"
branch(S::Dynamic, k) = @error "Not implemented"
plottable(S::Dynamic) = @error "Not implemented"

"""
preim(S::Dynamic, k, y, ϵ)

Computes the preim of y in branch k of a dynamic, with accuracy ϵ
"""
function preim end
is_full_branch(S::Dynamic) = @error "Not implemented"

"""
Endpoints of the branches, in increasing order (returned as a vector of intervals)
"""
endpoints(S::Dynamic) = @error "Not implemented"

# Derivative and distorsion of a generic function (*not* a dynamic). Here for convenience,

# the isempty check is required because otherwise derivative(x -> 4*x, ∅) == 4.
"""
Nth derivative of a function (or a dynamic)
"""
derivative(f, x) = derivative(1, f, x)
derivative(n, f, x) = isempty(x) ?  ∅ : f(Taylor1([x, 1], n))[n] * factorial(n)

"""
Distorsion of a function (or a dynamic), i.e., |f′′ / f′^2|
"""
function distorsion(f, x)
	if isempty(x)
		return ∅
	end
	series = f(Taylor1([x, 1], 2))
	f′ = series[1]
	f′′ = 2*series[2]
	return abs(f′′ / f′^2)
end

"""
Maximum of |1/T'|
"""
function expansivity(D::Dynamic, tol=1e-3)
	v = endpoints(D)
	return maximum(maximise(x -> abs(1/derivative(branch(D,k), x)), hull(v[k], v[k+1]), tol=tol)[1] for k in 1:nbranches(D))
end

"""
Maximum of distorsion(D, x) = |T''| / (T')^2, over all branches
"""
function max_distorsion(D::Dynamic, tol=1e-3)
	v = endpoints(D)
	return maximum(maximise(x -> distorsion(branch(D, k) , x), hull(v[k], v[k+1]), tol=tol)[1] for k in 1:nbranches(D))
end

"""
orientation(D, k)

Orientation of branch k: 1. for increasing, -1. for decreasing
"""
function orientation end

end


text:
## TODO: fix for non-unity partition dimensions

export AdditiveCouplingLayer

import Base: eltype

@doc raw"""
The additive coupling layer specifies an invertible function ``{\bf{y}} = g({\bf{x}})`` following the specific structure (for the mapping ``g: \mathbb{R}^2 \rightarrow \mathbb{R}^2``):

```math
    \begin{align}
        y_1 &= x_1 \\
        y_2 &= x_2 + f(x_1)
    \end{align}
```

where ``f(\cdot)`` denotes an arbitrary function with mapping ``f: \mathbb{R} \rightarrow \mathbb{R}``. This function can be chosen arbitrarily complex. Non-linear functions (neural networks) are often chosen to model complex relationships. From the definition of the model, invertibility can be easily achieved as

```math
    \begin{align}
        x_1 &= y_1 \\
        x_2 &= y_2 - f(y_1)
    \end{align}
```

The current implementation only allows for the mapping ``g: \mathbb{R}^2 \rightarrow \mathbb{R}^2``, although this layer can be generalized for arbitrary input dimensions.

`AdditiveCouplingLayer(f <: AbstractCouplingFlow)` creates the layer structure with function `f`.

### Example
```julia
f = PlanarFlow()
layer = AdditiveCouplingLayer(f)
```

This layer structure has been introduced in:

Dinh, Laurent, David Krueger, and Yoshua Bengio. "Nice: Non-linear independent components estimation." _arXiv preprint_ arXiv:1410.8516 (2014).
"""
struct AdditiveCouplingLayer{ T <: NTuple{N,AbstractCouplingFlow} where { N } } <: AbstractCouplingLayer
    dim           :: Int
    f             :: T
    partition_dim :: Int
end
struct AdditiveCouplingLayerEmpty{ T <: NTuple{N,AbstractCouplingFlowEmpty} where { N } } <: AbstractCouplingLayer
    dim           :: Int
    f             :: T
    partition_dim :: Int
end
struct AdditiveCouplingLayerPlaceholder{T <: AbstractCouplingFlowEmpty, B } <: AbstractLayerPlaceholder
    f             :: T
    partition_dim :: Int
    permute       :: Val{B}
end
function AdditiveCouplingLayer(flow::T; partition_dim::Int=1, permute::Bool=true) where { T <: AbstractCouplingFlowPlaceholder }
    return AdditiveCouplingLayerPlaceholder(prepare(partition_dim, flow), partition_dim, Val(permute))
end

# include permute as value type for type stability
function _prepare(dim::Int, layer::AdditiveCouplingLayerPlaceholder{T, true}) where { T }
    ## TODO: generalize for non-1 partition dim and overlap
    @assert dim % getpartitiondim(layer) == 0 "The input dimensionality is not exactly divisible by the partition dimension."
    nr_maps = ( dim ÷ getpartitiondim(layer) ) - 1
    maps = ntuple((x) -> getf(layer), Val(nr_maps))
    return AdditiveCouplingLayerEmpty(dim, maps, getpartitiondim(layer)), PermutationLayer(dim)
end
function _prepare(dim::Int, layer::AdditiveCouplingLayerPlaceholder{T, false}) where { T }
    ## TODO: generalize for non-1 partition dim and overlap
    @assert dim % getpartitiondim(layer) == 0 "The input dimensionality is not exactly divisible by the partition dimension."
    nr_maps = ( dim ÷ getpartitiondim(layer) ) - 1
    maps = ntuple((x) -> getf(layer), Val(nr_maps))
    return AdditiveCouplingLayerEmpty(dim, maps, getpartitiondim(layer))
end

# compile layer (tuples are compiled according to compile in flow_model.jl)
compile(layer::AdditiveCouplingLayerEmpty)          = AdditiveCouplingLayer(getdim(layer), compile(getf(layer)), getpartitiondim(layer))
compile(layer::AdditiveCouplingLayerEmpty, params)  = AdditiveCouplingLayer(getdim(layer), compile(getf(layer), params), getpartitiondim(layer))

# calculates the number of parameters in the model
nr_params(layer::AdditiveCouplingLayer)             = mapreduce(nr_params, +, getf(layer))
nr_params(layer::AdditiveCouplingLayerEmpty)        = mapreduce(nr_params, +, getf(layer))

# get-functions for the AdditiveCouplingLayer structure
getf(layer::AdditiveCouplingLayer)              = layer.f
getflow(layer::AdditiveCouplingLayer)           = layer.f
getdim(layer::AdditiveCouplingLayer)            = layer.dim
getpartitiondim(layer::AdditiveCouplingLayer)   = layer.partition_dim

# get-functions for the AdditiveCouplingLayerPlaceholder structure
getf(layer::AdditiveCouplingLayerPlaceholder)               = layer.f
getflow(layer::AdditiveCouplingLayerPlaceholder)            = layer.f
getpartitiondim(layer::AdditiveCouplingLayerPlaceholder)    = layer.partition_dim

# get-functions for the AdditiveCouplingLayerEmpty structure
getdim(layer::AdditiveCouplingLayerEmpty)           = layer.dim
getf(layer::AdditiveCouplingLayerEmpty)             = layer.f
getflow(layer::AdditiveCouplingLayerEmpty)          = layer.f
getpartitiondim(layer::AdditiveCouplingLayerEmpty)  = layer.partition_dim

# custom Base function for the AdditiveCouplingLayer structure
eltype(layer::AdditiveCouplingLayer{T})  where { T }              = promote_type(map(eltype, getf(layer))...)

# forward pass through the additive coupling layer
function _forward(layer::AdditiveCouplingLayer, input::AbstractVector{ <: Real })

    # allocate result
    result = similar(input)

    # calculate result
    forward!(result, layer, input)

    # return result
    return result

end
forward(layer::AdditiveCouplingLayer, input::AbstractVector{ <: Real }) = _forward(layer, input)
Broadcast.broadcasted(::typeof(forward), layer::AdditiveCouplingLayer, input::AbstractVector{ <: AbstractVector{ <: Real } }) = broadcast(_forward, Ref(layer), input)

# inplace forward pass through the additive coupling layer
function forward!(output::AbstractVector{ <: Real }, layer::AdditiveCouplingLayer, input::AbstractVector{ <: Real })

    # fetch variables
    f = getf(layer)
    dim = getdim(layer)
    pdim = getpartitiondim(layer)

    # check dimensionality
    @assert length(input) == dim "The dimensionality of the AdditiveCouplingLayer does not correspond to the length of the passed input/output."

    # optimized version for scalar partition dimension
    if pdim == 1
        output[1] = input[1]
        for k = 2:dim
            output[k] = input[k]
            output[k] += forward(f[k-1], input[k-1])
        end
    else
        view(output, 1:pdim) .= view(input, 1:pdim)
        for k = 2:dim÷pdim
            view(output, 1+(k-1)*pdim:k*pdim) .= view(input, 1+(k-1)*pdim:k*pdim)
            view(output, 1+(k-1)*pdim:k*pdim) .+= forward(f[k-1], view(input, 1+(k-2)*pdim:(k-1)*pdim))
        end
    end

end

# backward pass through the additive coupling layer
function _backward(layer::AdditiveCouplingLayer, output::AbstractVector{ <: Real })

    # allocate result
    result = similar(output)

    # calculate result
    backward!(result, layer, output)

    # return result
    return result

end
backward(layer::AdditiveCouplingLayer, output::AbstractVector{ <: Real }) = _backward(layer, output)
Broadcast.broadcasted(::typeof(backward), layer::AdditiveCouplingLayer, output::AbstractVector{ <: AbstractVector{ <: Real } }) = broadcast(_backward, Ref(layer), output)

# inplace backward pass through the additive coupling layer
function backward!(input::AbstractVector{ <: Real }, layer::AdditiveCouplingLayer, output::AbstractVector{ <: Real })

    # fetch variables
    f = getf(layer)
    dim = getdim(layer)
    pdim = getpartitiondim(layer)

    # check dimensionality
    @assert length(input) == dim "The dimensionality of the AdditiveCouplingLayer does not correspond to the length of the passed input/output."

    # determine result
    if pdim == 1
        input[1] = output[1]
        for k = 2:dim
            input[k] = output[k]
            input[k] -= forward(f[k-1], input[k-1])
        end
    else
        view(input, 1:pdim) .= view(output, 1:pdim)
        for k = 2:dim÷pdim
            view(input, 1+(k-1)*pdim:k*pdim) .= view(output, 1+(k-1)*pdim:k*pdim)
            view(input, 1+(k-1)*pdim:k*pdim) .-= forward(f[k-1], view(input, 1+(k-2)*pdim:(k-1)*pdim))
        end
    end

end

# jacobian of the additive coupling layer
function _jacobian(layer::AdditiveCouplingLayer, input::AbstractVector{T}) where { T <: Real }

    # fetch variables
    dim = getdim(layer)

    # allocate jacobian
    Ti = promote_type(eltype(layer), T)
    result = zeros(Ti, dim, dim)

    # determine result
    jacobian!(result, layer, input)

    # return result
    return LowerTriangular(result)

end
jacobian(layer::AdditiveCouplingLayer, input::AbstractVector{ <: Real }) = _jacobian(layer, input)
Broadcast.broadcasted(::typeof(jacobian), layer::AdditiveCouplingLayer, input::AbstractVector{ <: AbstractVector{ <: Real } }) = broadcast(_jacobian, Ref(layer), input)

# inplace jacobian through the additive coupling layer
function jacobian!(result::AbstractMatrix{T}, layer::AdditiveCouplingLayer, input::AbstractVector{ <: Real }) where { T <: Real }

    # fetch variables
    f = getf(layer)
    dim = getdim(layer)
    pdim = getpartitiondim(layer)

    # check dimensionality
    @assert length(input) == dim "The dimensionality of the AdditiveCouplingLayer does not correspond to the length of the passed input/output."

    # determine result
    result .= zero(T)
    for k = 1:dim÷pdim
        result[k,k] = one(T)
    end
    for k = 1:dim÷pdim-1
        result[1+k*pdim:(k+1)*pdim, 1+(k-1)*pdim:k*pdim] .+= jacobian(f[k], input[1+(k-1)*pdim:k*pdim])
    end

end

# inverse jacobian of the additive coupling layer
function _inv_jacobian(layer::AdditiveCouplingLayer, output::AbstractVector{T}) where { T <: Real }

    # fetch variables
    dim = getdim(layer)

    # allocate jacobian
    Ti = promote_type(eltype(layer), T)
    result = zeros(Ti, dim, dim)

    # determine result
    inv_jacobian!(result, layer, output)

    # return result
    return LowerTriangular(result)

end
inv_jacobian(layer::AdditiveCouplingLayer, output::AbstractVector{ <: Real }) = _inv_jacobian(layer, output)
Broadcast.broadcasted(::typeof(inv_jacobian), layer::AdditiveCouplingLayer, output::AbstractVector{ <: AbstractVector{ <: Real } }) = broadcast(_inv_jacobian, Ref(layer), output)

# inplace inv_jacobian through the additive coupling layer
function inv_jacobian!(result::AbstractMatrix{T}, layer::AdditiveCouplingLayer, output::AbstractVector{ <: Real }) where { T <: Real }

    # fetch variables
    f = getf(layer)
    dim = getdim(layer)
    pdim = getpartitiondim(layer)

    # check dimensionality
    @assert length(output) == dim "The dimensionality of the AdditiveCouplingLayer does not correspond to the length of the passed input/output."

    # calculate input of layer for simpler jacobian calculation
    input = backward(layer, output)

    # determine result
    result .= zero(T)
    for k = 1:dim÷pdim
        result[k:end,k] .= one(T)
    end
    for k = 1:dim÷pdim-1
        result[k+1:end, 1:k] .*= -jacobian(f[k], input[1+(k-1)*pdim:k*pdim])
    end

end

# extra utility functions
det_jacobian(layer::AdditiveCouplingLayer, input::AbstractVector{ <: Real })           = 1.0
absdet_jacobian(layer::AdditiveCouplingLayer, input::AbstractVector{ <: Real })        = 1.0
logdet_jacobian(layer::AdditiveCouplingLayer, input::AbstractVector{ <: Real })        = 0.0
logabsdet_jacobian(layer::AdditiveCouplingLayer, input::AbstractVector{ <: Real })     = 0.0

detinv_jacobian(layer::AdditiveCouplingLayer, output::AbstractVector{ <: Real })       = 1.0
absdetinv_jacobian(layer::AdditiveCouplingLayer, output::AbstractVector{ <: Real })    = 1.0
logdetinv_jacobian(layer::AdditiveCouplingLayer, output::AbstractVector{ <: Real })    = 0.0
logabsdetinv_jacobian(layer::AdditiveCouplingLayer, output::AbstractVector{ <: Real }) = 0.0


text:
module Confirms

export @confirm

CONFIRMS = get(ENV, "JULIA_CONFIRMS", "false") === "true"

if (CONFIRMS)
    macro confirm(expr)
        :(@assert :(esc($$expr)))
    end
else
    macro confirm(expr)
    end
end

end # Confirms


text:
module FloatOperators

import MachineGa.ByteWorks
import MachineGa.RawOperators

function nearbytemutation(
    values::Array{Float64,1};
    mutateprob::Float64 = 0.10,
)::Array{Float64,1}
    return RawOperators.nearbytemutation(
        ByteWorks.floatstobytes(values),
        mutateprob = mutateprob,
    ) |> ByteWorks.bytestofloats
end

function randombytemutation(
    values::Array{Float64,1};
    mutateprob::Float64 = 0.10,
)::Array{Float64,1}
    return RawOperators.randombytemutation(
        ByteWorks.floatstobytes(values),
        mutateprob = mutateprob,
    ) |> ByteWorks.bytestofloats
end

function onepointcrossover(
    fvals::Array{Float64,1},
    svals::Array{Float64,1},
)::Array{Float64,1}
    return RawOperators.onepointcrossover(
        ByteWorks.floatstobytes(fvals),
        ByteWorks.floatstobytes(svals),
    ) |> ByteWorks.bytestofloats
end

function uniformcrossover(
    fvals::Array{Float64,1},
    svals::Array{Float64,1},
)::Array{Float64,1}
    return RawOperators.uniformcrossover(
        ByteWorks.floatstobytes(fvals),
        ByteWorks.floatstobytes(svals),
    ) |> ByteWorks.bytestofloats
end

end # end of module


text:
using Photosynthesis
using PkgUtility
using PlantHydraulics
using StomataModels
using Test

include("test_StomataModels.jl")


text:
# this replicates the results in the paper-
# it can use threads, so set JULIA_NUM_THREADS
# appropriately for your system.
using SimulatedNeuralMoments, Flux
using BSON:@save
using BSON:@load
include("MNlib.jl")
include("Analyze.jl")

function main()
    lb, ub = PriorSupport()
    model = SNMmodel("Mixture of Normals example model", lb, ub, InSupport, Prior, PriorDraw, auxstat)
    # train the net, and save it and the transformation info
    # nnmodel, nninfo = MakeNeuralMoments(model)
    # @save "neuralmodel.bson" nnmodel nninfo  # use this line to save the trained neural net
    @load "neuralmodel.bson" nnmodel nninfo # use this to load a trained net
    R = 1000
    results = zeros(R, 20)
    Threads.@threads for r = 1:R
        m = NeuralMoments(TrueParameters(), 1, model, nnmodel, nninfo) # the estimate
        chain, junk, junk = MCMC(m, 10500, model, nnmodel, nninfo)
        println("r: ", r)
        results[r,:] = vcat(median(chain[501:end,:], dims=1)[:], Analyze(chain))
    end
    return results
end

@time results = main()

theta = TrueParameters()
nParams = size(theta,1)
println("Results")
println("parameter estimates (pos. median)")
est = results[:,1:nParams]
err = est .- TrueParameters()'
b = mean(err, dims=1)
s = std(err, dims=1)
rmse = sqrt.(b.^2 + s.^2)
prettyprint([b' rmse'], ["bias", "rmse"])
dstats(est; short=true)
println("CI coverage")
clabels = ["99%","95%","90%"]
prettyprint(reshape(mean(results[:,nParams+1:end],dims=1),nParams,3),clabels)


text:
module TiramisuPrepass
export detector

using ..ParallelAccelerator

SupportedNode = Union{LabelNode, GotoNode, Expr, NewvarNode, LineNumberNode,
                      SlotNumber}

mk_expr(sym, varargs...) = Expr(:call, GlobalRef(TiramisuPrepass, sym),
                                varargs...)

type Future
  matcher::Function
end

Matcher = Union{Function, Future}

# A matcher takes three variables:
# - An expression::Expr
# - The index of the expression in the top level of the AST
# - A state (doesn't matter in the first matcher)
# It returns:
# - A boolean saying whether there is a match
# - A state to use for the next matcher, or validator
# A validator is called with the state returned from the last matcher
# when a pattern is accepted
type Pattern
  matchers::Vector{Matcher}
  validator::Function
end

type Changer
  ignore::Set{Integer}
  changers::Dict{Integer, Function}
end

abstract State

type NoState <: State
end

function onlyExpr(f::Function)
  return function(node::SupportedNode, index::Integer, state::State)
    if !(typeof(node) <: Expr)
      return false, NoState()
    end
    return f(node, index, state)
  end
end

function onlyLabelNode(f::Function)
  return function(node::SupportedNode, index::Integer, state::State)
    if !(typeof(node) <: LabelNode)
      return false, NoState()
    end
    return f(node, index, state)
  end
end

function onlyGotoNode(f::Function)
  return function(node::SupportedNode, index::Integer, state::State)
    if !(typeof(node) <: GotoNode)
      return false, NoState()
    end
    return f(node, index, state)
  end
end

function onlyExprB(f::Function)
  return function(node::SupportedNode, index::Integer, state::State)
    if !(typeof(node) <: Expr)
      return false
    end
    return f(node, index, state)
  end
end

function onlyLabelNodeB(f::Function)
  return function(node::SupportedNode, index::Integer, state::State)
    if !(typeof(node) <: LabelNode)
      return false
    end
    return f(node, index, state)
  end
end

function onlyGotoNodeB(f::Function)
  return function(node::SupportedNode, index::Integer, state::State)
    if !(typeof(node) <: GotoNode)
      return false
    end
    return f(node, index, state)
  end
end

type ForLoopData <: State
  id::Union{Void, Integer} # assigned id
  from::Union{Void, Integer, SlotNumber} # lower bound of loop
  ssa_from::Union{Void, SSAValue} # lower bound of loop
  to::Union{Void, Integer, SlotNumber} # upper bound of loop
  protec_to::Union{Void, SSAValue} # Computed upper bound of loop
  loop_var::Union{Void, SlotNumber} # Actual loop variable
  used_loop_var::Union{Void, SlotNumber} # Exposed loop variable (if variable is used)
  begin_label::Union{Void, Int64} # Label for reloop
  cont_label::Union{Void, Int64} # Label for continue
  end_label::Union{Void, Int64} # Label to end loop
  temp_loop_var::Union{Void, SSAValue} # In case of used_loop_var, original value stored here
  inc_loop_var::Union{Void, SSAValue} # In case of used_loop_var, original value stored here
  header_index::Union{Void, Integer} # Index of loop header
  top_index::Union{Void, Integer}
  bottom_index::Union{Void, Integer} # Index of Goto at loop end
end

function process(state::ForLoopData, expr)
  if expr === state.ssa_from
    return state.from
  end
  return expr
end

isForLoopMeta = onlyExpr(function(expr::Expr, index::Integer, state::NoState)
  is_valid = expr.head === :meta && expr.args[1] === :forloop

  if is_valid
    state = ForLoopData(repeated(nothing, length(fieldnames(ForLoopData)))...)
    state.id = expr.args[2]
    state.header_index = index
    return true, state
  end
  return false, NoState()
end)

isForLoopSSAFrom = onlyExpr(function(expr::Expr, index::Integer, state::ForLoopData)
  if expr.head === :(=) && isa(expr.args[1], SSAValue) && isa(expr.args[2], SlotNumber)
    state.ssa_from = expr.args[1]
    state.from = expr.args[2]
    return true, state
  end
  return false, NoState()
end)

isForLoopHeader = onlyExpr(function(expr::Expr, index::Integer, state::ForLoopData)
  is_valid = (expr.head === :(=))

  if !is_valid
    return false, NoState()
  end

  sel_expr = expr.args[2]

  is_valid = (isa(sel_expr, Expr) &&
              sel_expr.head === :call &&
              sel_expr.args[1] === GlobalRef(Base, :select_value))

  if !is_valid
    return false, NoState()
  end

  comp_expr = sel_expr.args[2]

  is_valid &= (isa(comp_expr, Expr) &&
               comp_expr.head === :call &&
               comp_expr.args[1] === GlobalRef(Base, :sle_int))

  if !is_valid
    return false, NoState()
  end

  from = comp_expr.args[2]
  to = comp_expr.args[3]

  is_valid &= sel_expr.args[3] === to

  if !is_valid
    return false, NoState()
  end

  box_expr = sel_expr.args[4]

  is_valid &= (isa(box_expr, Expr) &&
               box_expr.head === :call &&
               box_expr.args[1] === GlobalRef(Base, :box) &&
               box_expr.args[2] === Int64)

  if !is_valid
    return false, NoState()
  end

  sub_expr = box_expr.args[3]

  is_valid &= (isa(sub_expr, Expr) &&
               sub_expr.head === :call &&
               sub_expr.args[1] === GlobalRef(Base, :sub_int) &&
               sub_expr.args[2] === from &&
               sub_expr.args[3] === 1)

  if is_valid
    state.from = from
    state.to = to
    state.protec_to = expr.args[1]
  end

  return is_valid, state
end)

isForLoopVarInit = onlyExpr(function(expr::Expr, index::Integer, state::ForLoopData)
  is_valid = (expr.head === :(=) &&
              isa(expr.args[1], SlotNumber) &&
              process(state, expr.args[2]) === process(state, state.from))
  state.loop_var = expr.args[1]
  return is_valid, state
end)

isForLoopBeginLabel = onlyLabelNode(function(label::LabelNode, index::Integer, state::ForLoopData)
  state.begin_label = label.label
  return true, state
end)

isForLoopTestGoto = onlyExpr(function(expr::Expr, index::Integer, state::ForLoopData)
  is_valid = expr.head === :gotoifnot

  if !is_valid
    return false, state
  end

  box_expr = expr.args[1]

  is_valid &= (isa(box_expr, Expr) &&
               box_expr.head === :call &&
               box_expr.args[1] === GlobalRef(Base, :box) &&
               box_expr.args[2] === GlobalRef(Base, :Bool))

  if !is_valid
    return false, state
  end

  not_expr = box_expr.args[3]

  is_valid &= (isa(not_expr, Expr) &&
               not_expr.head === :call &&
               not_expr.args[1] === GlobalRef(Base, :not_int))

  if !is_valid
    return false, state
  end

  comp_expr = not_expr.args[2]

  is_valid &= (isa(comp_expr, Expr) &&
               comp_expr.args[1] === GlobalRef(Base, :(===)) &&
               comp_expr.args[2] === state.loop_var)

  if !is_valid
    return false, state
  end

  box_expr = comp_expr.args[3]

  is_valid &= (isa(box_expr, Expr) &&
               box_expr.head === :call &&
               box_expr.args[1] === GlobalRef(Base, :box) &&
               box_expr.args[2] === Int64)

  if !is_valid
    return false, state
  end

  add_expr = box_expr.args[3]

  is_valid &= (isa(add_expr, Expr) &&
               add_expr.head === :call &&
               add_expr.args[1] === GlobalRef(Base, :add_int) &&
               add_expr.args[2] === state.protec_to &&
               add_expr.args[3] === 1)

  if is_valid
    state.end_label = expr.args[2]
  end

  return is_valid, state
end)

isForLoopVarSave = onlyExpr(function(expr::Expr, index::Integer, state::ForLoopData)
  is_valid = (expr.head === :(=) &&
              isa(expr.args[1], SSAValue) &&
              expr.args[2] === state.loop_var)
  if is_valid
    state.temp_loop_var = expr.args[1]
  end
  return is_valid, state
end)

isForLoopVarInc = onlyExpr(function(expr::Expr, index::Integer, state::ForLoopData)
  is_valid = (expr.head === :(=) &&
              isa(expr.args[1], SSAValue))

  if !is_valid
    return false, state
  end

  box_expr = expr.args[2]

  is_valid &= (isa(box_expr, Expr) &&
               box_expr.head === :call &&
               box_expr.args[1] === GlobalRef(Base, :box) &&
               box_expr.args[2] === Int64)

  if !is_valid
    return false, state
  end

  add_expr = box_expr.args[3]

  is_valid &= (isa(add_expr, Expr) &&
               add_expr.head === :call &&
               add_expr.args[1] === GlobalRef(Base, :add_int) &&
               add_expr.args[2] === state.loop_var &&
               add_expr.args[3] === 1)

  if is_valid
    state.inc_loop_var = expr.args[1]
  end

  return is_valid, state
end)

isForLoopUsedVar = onlyExpr(function(expr::Expr, index::Integer, state::ForLoopData)
  is_valid = (expr.head === :(=) &&
              isa(expr.args[1], SlotNumber) &&
              expr.args[2] === state.temp_loop_var)
  if is_valid
    state.used_loop_var = expr.args[1]
  end

  return is_valid, state
end)

isForLoopUpdateVar = onlyExpr(function(expr::Expr, index::Integer, state::ForLoopData)
  is_valid = (expr.head === :(=) &&
              expr.args[1] === state.loop_var &&
              expr.args[2] === state.inc_loop_var)

  if is_valid
    state.top_index = index
  end

  return is_valid, state
end)

for_loop_changer = Changer(Set(1:0), Dict{Integer, Function}())

function forLoopHeaderValidator(state::ForLoopData, ast::Expr)

  for (i, expr) in enumerate(ast.args)
    # order is important
    if (isForLoopEndGoto(expr, i,  state) &&
        isForLoopContLabel(ast.args[i - 1], i - 1,  state) &&
        isForLoopEndLabel(ast.args[i + 1], i + 1, state))
      union!(for_loop_changer.ignore,
             Set((state.header_index + 1):state.top_index))
      push!(for_loop_changer.ignore, state.bottom_index - 1)
      push!(for_loop_changer.ignore, state.bottom_index + 1)
      for_loop_changer.changers[state.header_index] = function()
        return mk_expr(:for_loop_start, state.id,
                       state.from, state.to, 1,
                       state.loop_var, state.used_loop_var)
      end
      for_loop_changer.changers[state.bottom_index] = function()
        return mk_expr(:for_loop_end, state.id)
      end
      break
    end
  end
end

isForLoopEndGoto = onlyGotoNodeB(function(expr::GotoNode, index::Integer, state::ForLoopData)
  is_valid = expr.label == state.begin_label
  if is_valid
    state.bottom_index = index
  end
  return is_valid
end)

isForLoopContLabel = onlyLabelNodeB(function(expr::LabelNode, index::Integer, state::ForLoopData)
  state.cont_label = expr.label
  return true
end)

isForLoopEndLabel = onlyLabelNodeB(function(expr::LabelNode, index::Integer, state::ForLoopData)
  return state.end_label == expr.label
end)

type IfData <: State
  id::Union{Void, Integer}
  condition::Any
  changer::Changer
end

isIfMeta = onlyExpr(function(expr::Expr, index::Integer, state::NoState)
  is_valid = expr.head === :meta && expr.args[1] === :if
  if is_valid
    state = IfData(expr.args[2], nothing, Changer(Set(), Dict()))
    push!(state.changer.ignore, index)
  end
  return is_valid, state
end)

isIfGotoIfNot = Future(onlyExpr(function(expr::Expr, index::Integer, state::IfData)
  is_valid = expr.head === :gotoifnot
  if is_valid
    state.condition = expr.args[1]
    state.changer.changers[index] = () -> mk_expr(:if, state.id, state.condition)
  end
  return is_valid, state
end))

if_changer = Changer(Set(), Dict())

function ifValidator(state::IfData, ast::Expr)
  union!(if_changer.ignore, state.changer.ignore)
  merge!(if_changer.changers, state.changer.changers)
end

type ContinueData <: State
  id::Union{Void, Integer}
  changer::Changer
end

isContinueMeta = onlyExpr(function(expr::Expr, index::Integer, state::NoState)
  is_valid = expr.head === :meta && expr.args[1] === :continue
  if is_valid
    state = ContinueData(expr.args[2], Changer(Set(), Dict()))
    state.changer.changers[index] = () -> mk_expr(:continue, state.id)
  end
  return is_valid, state
end)

isContinueGoto = onlyGotoNode(function(expr::GotoNode, index::Integer, state::ContinueData)
  push!(state.changer.ignore, index)
  return true, state
end)

continue_changer = Changer(Set(), Dict())

function continueValidator(state::ContinueData, ast::Expr)
  union!(continue_changer.ignore, state.changer.ignore)
  merge!(continue_changer.changers, state.changer.changers)
end

type EndifData <: State
  id::Union{Void, Integer}
  changer::Changer
end

isEndifMeta = onlyExpr(function(expr::Expr, index::Integer, state::NoState)
  is_valid = expr.head === :meta && expr.args[1] === :endif
  if is_valid
    state = EndifData(expr.args[2], Changer(Set(), Dict()))
    state.changer.changers[index] = () -> mk_expr(:endif, state.id)
  end
  return is_valid, state
end)

isEndifLabel = onlyLabelNode(function(expr::LabelNode, index::Integer, state::EndifData)
  push!(state.changer.ignore, index)
  return true, state
end)

endif_changer = Changer(Set(), Dict())

function endifValidator(state::EndifData, ast::Expr)
  union!(endif_changer.ignore, state.changer.ignore)
  merge!(endif_changer.changers, state.changer.changers)
end

type ElseData <: State
  id::Union{Void, Integer}
  changer::Changer
end

isElseGoto = onlyGotoNode(function(expr::GotoNode, index::Integer, state::NoState)
  state = ElseData(nothing, Changer(Set(), Dict()))
  push!(state.changer.ignore, index)
  return true, state
end)

isElseLabel = onlyLabelNode(function(expr::LabelNode, index::Integer, state::ElseData)
  push!(state.changer.ignore, index)
  return true, state
end)

isElseMeta = onlyExpr(function(expr::Expr, index::Integer, state::ElseData)
  is_valid = expr.head === :meta && expr.args[1] === :else
  if is_valid
    state.id = expr.args[2]
    state.changer.changers[index] = () -> mk_expr(:else, state.id)
  end
  return is_valid, state
end)

else_changer = Changer(Set(), Dict())

function elseValidator(state::ElseData, ast::Expr)
  union!(else_changer.ignore, state.changer.ignore)
  merge!(else_changer.changers, state.changer.changers)
end
###########

for_loop_used_pattern = Pattern([isForLoopMeta,
                                 isForLoopHeader,
                                 isForLoopVarInit,
                                 isForLoopBeginLabel,
                                 isForLoopTestGoto,
                                 isForLoopVarSave,
                                 isForLoopVarInc,
                                 isForLoopUsedVar,
                                 isForLoopUpdateVar], forLoopHeaderValidator)

for_loop_unused_pattern = Pattern([isForLoopMeta,
                                   isForLoopHeader,
                                   isForLoopVarInit,
                                   isForLoopBeginLabel,
                                   isForLoopTestGoto,
                                   isForLoopVarInc,
                                   isForLoopUpdateVar], forLoopHeaderValidator)

for_loop_used_pattern_ssa = Pattern([isForLoopMeta,
                                 isForLoopSSAFrom,
                                 isForLoopHeader,
                                 isForLoopVarInit,
                                 isForLoopBeginLabel,
                                 isForLoopTestGoto,
                                 isForLoopVarSave,
                                 isForLoopVarInc,
                                 isForLoopUsedVar,
                                 isForLoopUpdateVar], forLoopHeaderValidator)

for_loop_unused_pattern_ssa = Pattern([isForLoopMeta,
                                     isForLoopSSAFrom,
                                     isForLoopHeader,
                                     isForLoopVarInit,
                                     isForLoopBeginLabel,
                                     isForLoopTestGoto,
                                     isForLoopVarInc,
                                     isForLoopUpdateVar], forLoopHeaderValidator)
if_pattern = Pattern([isIfMeta, isIfGotoIfNot], ifValidator)

continue_pattern = Pattern([isContinueMeta, isContinueGoto], continueValidator)

endif_pattern = Pattern([isEndifMeta, isEndifLabel], endifValidator)

else_pattern = Pattern([isElseGoto, isElseLabel, isElseMeta], elseValidator)

patterns = [for_loop_used_pattern, for_loop_unused_pattern,
            for_loop_used_pattern_ssa, for_loop_unused_pattern_ssa,
            if_pattern,
            continue_pattern, endif_pattern, else_pattern] #, for_loop_test_pattern]

changers = [for_loop_changer, if_changer, continue_changer, endif_changer,
            else_changer]

function detector(ast::Expr)
  clean!(ast)
  detector(ast, patterns)
  change!(ast, changers)
end

function clean!(ast)
    ast.args = [e for e in ast.args if !(
                  isa(e, LineNumberNode) ||
                  isa(e, NewvarNode) ||
                  isa(e, Slot))]
end

function change!(ast::Expr, changers::Vector{Changer})
  new_args = Vector{Any}()
  for (i, e) in enumerate(ast.args)
    ignore = any(i in c.ignore for c in changers)
    new_nodes = [c.changers[i]() for c in changers if haskey(c.changers, i)]
    # TODO store level from pretag, sort changers by level, asc or descending
    new_args = vcat(new_args, new_nodes)

    if !ignore && isempty(new_nodes)
      push!(new_args, e)
    end
  end
  # for e in new_args
  #   dump(e)
  # end
  ast.args = new_args
end

function call_matcher(f::Function, params)
  return f(params...)..., false
end

function call_matcher(f::Future, params)
  return f.matcher(params...)..., true
end

function detector(ast::Expr, patterns::Vector{Pattern})
  states = State[NoState() for state in patterns]
  indices = [1 for expr in patterns]
  for (e_i, expr) in enumerate(ast.args)
    # dump(expr)
    for (p_i, pattern) in enumerate(patterns)
      @label pattern_check
      matched, state, future = call_matcher(pattern.matchers[indices[p_i]],
                                            (expr, e_i, states[p_i]))
      if matched
        if indices[p_i] == length(pattern.matchers)
          # pattern matched!
          pattern.validator(state, ast)

          states[p_i] = NoState()
          indices[p_i] = 1
        else
          # pattern not matched yet
          indices[p_i] += 1
          states[p_i] = state
        end
      elseif !future
        restart_pattern = indices[p_i] > 1
        indices[p_i] = 1
        states[p_i] = NoState()
        if restart_pattern
          @goto pattern_check # TODO: gotos are evil and need to be stopped
        end
      end
    end
  end
end

end

max_stars_repo_name: malekbr/julia-to-tiramisu

max_issues_repo_name: malekbr/julia-to-tiramisu

max_forks_repo_name: malekbr/julia-to-tiramisu