text:
#=  For research purposes, it is helpful to consider a nonatomic or continuous form of the
    DA algorithm. Instead of a fixed number of students with individual preferences lists,
    there is a continuum of students drawn from a fixed set of preference profiles. That
    is, a certain proportion of the students have preference list 1, another set has list
    2, etc. Then the school capacities represent the fraction of the total student volume.
    I prefer the term "nonatomic" because it relates this problem to the nonatomic routing
    games used in transportation studies; the "continuum" terminology draws on measure
    theory and is more common in the literature. Refer to Azevedo and Leshno (2016).   =#

using Plots
using DeferredAcceptance
using Random

n = 30          # Number of student profiles in continuum
m = 10          # Number of schools
α = 1.1         # Proportion by which overdemanded mkt is overdemanded
β = 0.9         # Proportion by which underdemanded mkt is underdemanded

#=  This time, we have no school preference orders. Schools are assumed to have a strict
    preference order over the students, but since the students are nonatomic, there is no
    notion of a "particular" student with higher preferability. Instead, schools define a
    minimal cutoff which they steadily increase as more applications come in in order to
    maintain a full roster.                                =#

students = hcat((randperm(m) for i = 1:n)...)   # Student profiles
students_dist = rand(n)                         # Percentage of total student population
students_dist /= sum(students_dist)             # associated with each profile

capacities = rand(m)                            # Percentage of total student population
capacities /= (α * sum(capacities))             # that each school can accommodate

#=  The output format is necessarily a little different from DA(). Instead of an assignment
    for each student, we get an array that indicates the volume of students of type j sent
    to school i. The second item in the output term indicates the volume of students whose
    assignment corresponds to each rank.                =#

assn, rdist = nonatomicdeferredacceptance(students, students_dist, nothing, capacities)
display(assn)
println(rdist)

# Sanity checks. These ineqs. should hold, with at least one of the two middle entries 0.
println("Unassigned students: 0 ≤ ", sum(students_dist) - sum(assn[1:m, :]),
        " ≤ ", sum(assn[m + 1, :]))
println("Remaining capacity:  0 ≤ ", sum(capacities) - sum(assn[1:m, :]),
        " ≤ ", max(sum(capacities) - sum(students_dist), 0))

# Compare with underdemanded market
capacities2 = capacities / (β * sum(capacities))
assn2, rdist2 = nonatomicdeferredacceptance(students, students_dist, nothing, capacities2)

p = plot([cumsum(rdist), cumsum(rdist2)],
         label=["Overdemanded (α = 1.1)" "Underdemanded (α = 0.9)"],
         title="Cumulative rank distribution in nonatomic DA",
         titlefontsize=11,
         lc=[:dodgerblue :olivedrab],
         legend=:bottomright,
         xlabel="rank",
         ylabel= "volume of students")

display(p)

#=  Now let's consider the case where schools have a preference order over the student
    profiles. In forward DA, each school's choice is piecewise linear root finding.
    Each school accepts all of the demand from their favorite student profiles until
    its capacity is full; it partially accepts the demand from the marginal profile,
    then rejects all the rest.                         =#

schools = hcat((randperm(n) for i = 1:m)...)

assn_het, rdist_het = nonatomicdeferredacceptance(students, students_dist, schools, capacities)
assn_het2, rdist_het2 = nonatomicdeferredacceptance(students, students_dist, schools, capacities2, verbose=true)

q = plot([cumsum(rdist_het), cumsum(rdist_het2)],
          label=["Overdemanded (α = 1.1)" "Underdemanded (α = 0.9)"],
          title="Cumulative rank distribution in nonatomic DA,\nwith heterogenous student preferability",
          titlefontsize=11,
          lc = [:dodgerblue :olivedrab],
          legend = :bottomright,
          xlabel = "rank", ylabel= "volume of students")

display(q)

max_stars_repo_name: maxkapur/DeferredAcceptance

max_issues_repo_name: maxkapur/DeferredAcceptance

max_forks_repo_name: maxkapur/DeferredAcceptance


text:
Maybe.Extras.maybe(f::F) where {F} = MaybeFunction(f)

struct MaybeFunction{F} <: Function
    f::F
end
MaybeFunction(::Type{T}) where {T} = MaybeFunction{Type{T}}(T)
@inline (f::MaybeFunction)(args...; kwargs...) = maybecall(f.f, args...; kwargs...)

@inline function maybecall(f, args...; kwargs...)
    any(isnothing, args) && return nothing
    any(isnothing, Tuple(values(kwargs))) && return nothing
    return ensure_maybe(f(_somethings(args)...; _somethings(values(kwargs))...))
end

@inline _somethings(xs::Tuple) = map(something, xs)
@inline _somethings(xs::NamedTuple{names}) where {names} =
    NamedTuple{names}(_somethings(Tuple(xs)))

Maybe.Extras.ifnothing(f) = x -> Maybe.Extras.ifnothing(f, x)
Maybe.Extras.ifnothing(f, ::Nothing) = f()
Maybe.Extras.ifnothing(_, x::Some) = something(x)

Maybe.Extras.defaultto(c) = Maybe.Extras.ifnothing(() -> c)

@inline Maybe.Extras.getnested(x, k) = Maybe.get(x, k)
@inline Maybe.Extras.getnested(x, k, keys...) =
    Maybe.Extras.getnested(@something(Maybe.get(x, k), return), keys...)
@inline Maybe.Extras.getnested(x) = Some(x)

ext: jl


text:
# used in clumping (langxiang) and (currently unused) slope method of Espana
"Return segments of pixelring [θ1, θ2] in n azimuth groups between 0 and 2π"
function segments(polim::PolarImage, θ1::Real, θ2::Real, n::Int)
    checkθ1θ2(θ1,θ2)
    ind_first, ind_last = firstlastind(polim, θ1, θ2)
    segmvec = [eltype(polim)[] for i = 1:n]
    imgsort = polim.imgsort
    ϕsort = getϕsort(polim)

    if !hasmask(polim)
        adj = n/2π
        for ind in ind_first:ind_last
            ϕ = ϕsort[ind]
            indn = ceil(Int, (ϕ + pi) * adj)
            push!(segmvec[indn], imgsort[ind])
        end
    else
        _, ϕmin, ϕmax = params(polim.mask)
        maskrange = ϕmax - ϕmin
        adj = n / (2π - maskrange)
        for ind in ind_first:ind_last
            ϕ = ϕsort[ind]
            ϕ += ifelse(ϕ < ϕmax, maskrange, 0)
            indn = ceil(Int, (ϕ + pi - maskrange) * adj)
            push!(segmvec[indn], imgsort[ind])
        end
    end
    segmvec
end

"Return the first and last index for the sorted image to abtain pixels in a given zenith range."
function firstlastind(polim::PolarImage, θ1::Real, θ2::Real)
    checkθ1θ2(θ1,θ2)

    ρ²sort = hasmask(polim) ? polim.mask.mask_ρ²sort : polim.cl.ρ²sort
    if hasslope(polim)
        α, ε = params(polim.slope)
        θ2 = min(θ2, pi/2 - α)
    end
    ind_first = searchsortedfirst(ρ²sort, polim.cl.fθρ(θ1)^2)
    ind_last  = searchsortedlast( ρ²sort, polim.cl.fθρ(θ2)^2)
    ind_first, ind_last
end

"Return all image pixels between two given zenith angles."
function pixels(polim::PolarImage, θ1::Real, θ2::Real)
    ind_first, ind_last = firstlastind(polim, θ1, θ2)
    view(polim.imgsort, ind_first:ind_last)
end
pixels(polim::PolarImage) = pixels(polim, 0, π/2)


text:
using Test

@testset "uninformed search" begin
    @testset "bfs" begin
        #  1
        # 2 3
        fn2(node::DesignAutomation.TreeNode) = node.value * 2
        fn3(node::DesignAutomation.TreeNode) = node.value * 3
        s_fns = [fn2 fn3]
        seed = 1

        res = bfs(seed, 2, s_fns)

        @test res.value == 2
        @test res.depth == 2

        #    1
        #   2 3
        #  4 6 12
        fn2(node::DesignAutomation.TreeNode) = node.value * 2
        fn3(node::DesignAutomation.TreeNode) = node.value * 3
        s_fns = [fn2 fn3]
        seed = 1

        res = bfs(seed, 6, s_fns)

        @test res.value == 6
        @test res.depth == 3
    end

    @testset "dfs" begin
        #  1
        # 2 3
        fn2(node::DesignAutomation.TreeNode) = node.value * 2
        fn3(node::DesignAutomation.TreeNode) = node.value * 3
        s_fns = [fn2 fn3]
        seed = 1

        res = dfs(seed, 2, s_fns, 3)

        @test res.value == 2
        @test res.depth == 2

        #     1
        #    2 3
        #  4 6 6 9
        fn2(node::DesignAutomation.TreeNode) = node.value * 2
        fn3(node::DesignAutomation.TreeNode) = node.value * 3
        s_fns = [fn2 fn3]
        seed = 1

        res = dfs(seed, 6, s_fns, 3)

        @test res.value == 6
        @test res.depth == 3
    end
end

max_stars_repo_name: camirmas/DesignAutomation

max_issues_repo_name: camirmas/DesignAutomation

max_forks_repo_name: camirmas/DesignAutomation


text:
mutable struct myresponse
  status::Int
  headers::Dict
  body::String
  function myresponse(code)
      new(code,Dict(),"")
  end
end

mutable struct myrequest
  query::Dict
  params::RegexMatch
  body::Any
  version::VersionNumber
  headers::Array
  function myrequest()
    new(Dict(),match(r"\s"," "),"",VersionNumber(1),[])
  end
end

my_headers= HTTP.mkheaders(["Content-Type" => "text/plain"])

function searchroute_regex(ruta::String)
  for i in 1:length(routes_patterns_array)
    if(occursin(routes_patterns_array[i],ruta))
      return routes_patterns_array[i]
    end
 end
 return ""
end

function handler(request::HTTP.Request)
  data = split(request.target,"?")
  url=data[1]
  searchroute = request.method*url

  my_request=myrequest()
  my_request.version=request.version
  my_request.headers=request.headers
  if (length(data)>1) my_request.query= HTTP.queryparams(data[2]) end

  response = myresponse(200)

  if ((request.method=="POST"  )||(request.method=="PUT"  )||(request.method=="PATCH"))
    header_content_type = HTTP.header(request, "Content-Type")
    if((length(header_content_type)>0) && (haskey(formats,header_content_type)))
      my_request.body= getindex(formats, header_content_type)(String(request.body))
    else
      my_request.body = getindex(formats, "*/*")(String(request.body))
    end
  end

  if (searchroute in routes_array)
    response.body = getindex(routes, searchroute)(my_request,response)
  else
    pattern = searchroute_regex(searchroute)
    if (typeof(pattern) <:Regex)
      my_request.params = match(pattern,searchroute)
      _function = getindex(routes_patterns,pattern)
      response.body = _function(my_request,response)
      sal = collect((m.match for m = eachmatch(Regex("{{(\\w\\d*)+}}"), response.body)))
      for i in sal
        response.body = replace(response.body,Regex(i) => my_request.params["$(i[3:end-2])"])
      end
    else
      response.body = getindex(routes, "notfound")(my_request,response)
    end
  end
  responsefinal = HTTP.Response(response.status,my_headers, body=response.body)
  for (key, value) in response.headers
    HTTP.setheader(responsefinal,key => value )
  end
  return responsefinal
end

struct app
  notfound::Function
  start::Function
  useCORS::Function
  webserverfiles::Function
  webserverpath::Function
  headersalways::Function

  function app()
    rootbase=pwd()

    function File(roop::String,file::String)
      path = normpath(rootbase*"/"*roop, file)
      return String(read(path))
    end

    function File(file::String)
      path = normpath(rootbase, file)
      return String(read(path))
    end

    function files(roop::String,file::String)
        extension="text/plain"
        ext= split(file,".")
        if(length(ext)>1)
          my_extension = ext[2]
          if (haskey(mimetypes,my_extension))
            extension=mimetypes[my_extension]
          end
        end
        data = File(roop,file[1:end])
        roop = replace(roop,"\\" => "/")
        createurl("GET"*roop*"/"*file,(req,res)->(begin
          res.headers["Content-Type"]= extension
          res.status = 200
          res.body= data
        end))
    end

    function WebServer(ruta::String,exten::String)
      cd(rootbase*"/"*ruta)
      ls= readdir()
      for i=1:length(ls)
        cd(rootbase*"/"*ruta)
        if isfile(ls[i])
          if ( (occursin(Regex("((.)*\\.(?!($exten)))"),ls[i])) && (!occursin(r"^(\.)",ls[i])))
            files(ruta,ls[i])
          end
        end
        if isdir(ls[i])
            WebServer(ruta*"/"*ls[i],exten)
        end
      end
    end

    function useCORS(activate::Bool)
     HTTP.setheader(my_headers,"Access-Control-Allow-Origin" => "*")
     HTTP.setheader(my_headers,"Access-Control-Allow-Methods" => "POST,GET,OPTIONS")
     return true
    end

    function headersalways(head::AbstractString,value::AbstractString)
      HTTP.setheader(my_headers,head => value)
    end

    function notfound(text::String)
      if occursin(".html", text)
        notfound_message= File(text)
        addnotfound(notfound_message)
      else
        addnotfound(text)
      end
    end

    function webserverfiles(load::AbstractString)
      if load=="*"
        WebServer("","")
      else
        WebServer("",load)
      end
    end

    function webserverpath(path::AbstractString)
      rootbase = path
    end

    function start(;config=Dict("host" => "127.0.0.1","port" => 8000)::Dict,verbose=false::Bool)
      port=get(config, "port", 8000)::Int
      my_host = get(config, "host", "127.0.0.1")::String
      if ('.' in my_host) host=Sockets.IPv4(my_host) end
      if (':' in my_host) host=Sockets.IPv6(my_host) end

      HTTP.serve(handler, host, port,verbose=verbose)
    end

    return new(notfound,start,useCORS,webserverfiles,webserverpath,headersalways)
  end
end


text:
using MakieLayout
using Makie

begin
    scene = Scene(camera=campixel!)
    display(scene)

    topgl = GridLayout(scene, alignmode=Outside(30))
    gl = topgl[1, 1] = GridLayout()
    la = gl[1, 1] = LAxis(scene)
    lc2 = gl[1, 2] = LColorbar(scene, width=50)

    gl[2, :] = LSlider(scene, height=40, range=1:1000)
    bgl = gl[3, :] = GridLayout(halign=:left)
    bs = bgl[1, 1:5] = [LButton(scene, height=40, width=Auto(), label="xx" ^ i) for i in 1:5]
    bgl2 = gl[4, :] = GridLayout()
    b1 = bgl2[1, 1] = LButton(scene, width = Auto(), label="prev")
    sl1 = bgl2[1, 2] = LSlider(scene, height=40)
    b2 = bgl2[1, 3] = LButton(scene, width = Auto(), label="next")

    te = gl[0, :] = LText(scene, text="Buttons on Buttons", textsize=50)
    nothing
end


text:
using GeoJSON, Turf, FactCheck

point1 = GeoJSON.Feature(GeoJSON.Point(Float64[1, 2]), @compat Dict{AbstractString,Any}("team" => "Red Sox"))
point2 = GeoJSON.Feature(GeoJSON.Point(Float64[2, 1]), @compat Dict{AbstractString,Any}("team" => "Yankees"))
point3 = GeoJSON.Feature(GeoJSON.Point(Float64[3, 1]), @compat Dict{AbstractString,Any}("team" => "Nationals"))
point4 = GeoJSON.Feature(GeoJSON.Point(Float64[2, 2]), @compat Dict{AbstractString,Any}("team" => "Yankees"))
point5 = GeoJSON.Feature(GeoJSON.Point(Float64[2, 3]), @compat Dict{AbstractString,Any}("team" => "Red Sox"))
point6 = GeoJSON.Feature(GeoJSON.Point(Float64[4, 2]), @compat Dict{AbstractString,Any}("team" => "Yankees"))
pointFC = GeoJSON.FeatureCollection(GeoJSON.Feature[point1, point2, point3, point4, point5, point6])

# test "remove"
newFC = Turf.remove(pointFC, "team", "Yankees")
@fact length(newFC.features) --> 3
for feature in newFC.features
    @fact (feature.properties["team"] == "Yankees") --> false
end

# test `filter`
newFC = Turf.remove(pointFC, "team", "Nationals")
@fact length(newFC.features) --> 1
@fact newFC.features[1].properties["team"] --> "Nationals"


text:
# Generalized Bayes: https://arxiv.org/pdf/2006.05451.pdf

using Distributions

struct State
  cluster::Vector{Int}
  Z::Matrix{Bool}
  v::Vector{Float64}
  alpha::Float64
end

function loss(yi::Vector{Bool}, zk::Vector{bool})
  return sum(abs.(yi - zk))
end

function loss(y::Matrix{Bool}, i::Integer, s::State)
  return loss(y[i, :], s.Z[s.cluster[i]])
end

function loss(y::Matrix{Bool}, s::State)
  N = length(s.cluster)
  return sum([loss(y, i, s) for i in 1:N])
end

function log_prior_Z(s::State, phi::Float64)
  # TODO
end

function update_c!(s::State, i::Integer, y::Matrix{Bool}, lam::Float64)
  K = size(s.Z, 2)
  log_prob = [-lam * loss(y[i], s.Z[:, k]) for k in 1:K]
  unnormalized_prob = exp.(log_prob - max(log_prob))
  prob = unnormalized_prob ./ sum(unnormalized_prob)
  s.cluster[i] = wsample(prob)
  return
end

function update_c!(s::State, y::Matrix{Bool}, lam::Float64)
  N = length(s.cluster)
  for i in 1:N
    update_c!(s, i, y, lam)
  end
end

function update_Z!(s::State, j:Integer, k::Integer, y::Matrix{Bool}, lam::Float64)
  # TODO
end

function update_Z!(s::State, y::Matrix{Bool}, lam::Float64)
  J, K = size(s.Z)
  for j in 1:J
    for k in 1:K
      update_Z(s, j, k, y, lam)
    end
  end
end


text:
using TinySegmenter
using Base.Test

@test tokenize("私の名前は中野です") == ["私", "の", "名前", "は", "中野", "です"]
@test tokenize("TinySegmenterは25kBで書かれています。")　== ["TinySegmenter", "は", "2", "5", "kB", "で", "書か", "れ", "て", "い", "ます", "。"]
@test tokenize("") == []

f = open("timemachineu8j.txt");
s = join(readlines(f));
result_text = join(TinySegmenter.tokenize(s), " | ");
f2 = open("timemachineu8j.tokenized.txt")
js_result_text = join(readlines(f2));
@test result_text == js_result_text

import TinySegmenter.ctype
@test ctype('一') == UInt8('M')
@test ctype('〆') == UInt8('H')
@test ctype('名') == UInt8('H')
@test ctype('あ') == UInt8('I')
@test ctype('ア') == UInt8('K')
@test ctype('Ｚ') == UInt8('A')
@test ctype('９') == UInt8('N')


text:
######################################################################
# searchdomain.jl
# Handles the type and functions required for the search domain.kl;w
######################################################################
"""
type `SearchDomain`

Constructors:

`SearchDomain(length, theta_x, theta_y)`

Makes a square search domain with a side-length of `length`. The RF source is located at `(theta_x, theta_y)`.

`SearchDomain(length)`

Assumes a random location to the RF source (theta).
"""
mutable struct SearchDomain{M <: MotionModel}
    length::Float64
    theta::LocTuple
    motion_model::M
end
function SearchDomain(length::Real, theta::NTuple{2,Real}, mm::MotionModel=NoMotion())
    return SearchDomain(length, (theta[1], theta[2], 0.0, 0.0), mm)
end

function SearchDomain(length::Real, theta_x::Real, theta_y::Real, mm::MotionModel=NoMotion())
    length = float(length)
    theta_x = float(theta_x)
    theta_y = float(theta_y)
    @assert theta_x <= length
    @assert theta_y <= length
    return SearchDomain(length, (theta_x, theta_y, 0.0, 0.0), mm)
end
function SearchDomain(length::Real, mm::MotionModel=NoMotion())
    length = float(length)
    theta_x = length * rand()
    theta_y = length * rand()
    return SearchDomain(length, (theta_x, theta_y, 0.0, 0.0), mm)
end

"""
`theta!(m::SearchDomain, xj::Real, yj::Real)`

`theta!(m::SearchDomain, theta::LocTuple)`

`theta!(m::SearchDomain)`

Change the jammer location of the search domain.

If no location is provided, a random one is selected.
"""
theta!(m::SearchDomain) = theta!(m, m.length * rand(), m.length * rand())

function theta!(m::SearchDomain, xj::Real, yj::Real)
    theta!( m, (float(xj), float(yj), 0.0, 0.0) )
end
function theta!(m::SearchDomain, theta::TargetTuple)
    @assert theta[1] <= m.length
    @assert theta[2] <= m.length
    m.theta = theta
end

function move_target!(m::SearchDomain)
    m.theta = move_target(m.motion_model, m.theta, m.length)
end


text:
# ---
# title: 910. Smallest Range II
# id: problem910
# author: Tian Jun
# date: 2020-10-31
# difficulty: Medium
# categories: Math, Greedy
# link: <https://leetcode.com/problems/smallest-range-ii/description/>
# hidden: true
# ---
#
# Given an array `A` of integers, for each integer `A[i]` we need to choose
# **either  `x = -K` or `x = K`**, and add `x` to `A[i] **(only once)**`.
#
# After this process, we have some array `B`.
#
# Return the smallest possible difference between the maximum value of `B` and
# the minimum value of `B`.
#
#
#
# **Example 1:**
#
#
#
#     Input: A = [1], K = 0
#     Output: 0
#     **Explanation** : B = [1]
#
#
# **Example 2:**
#
#
#
#     Input: A = [0,10], K = 2
#     Output: 6
#     **Explanation** : B = [2,8]
#
#
# **Example 3:**
#
#
#
#     Input: A = [1,3,6], K = 3
#     Output: 3
#     **Explanation** : B = [4,6,3]
#
#
#
#
# **Note:**
#
#   1. `1 <= A.length <= 10000`
#   2. `0 <= A[i] <= 10000`
#   3. `0 <= K <= 10000`
#
#
## @lc code=start
using LeetCode

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


text:
function create_differential_adhesion_matrix(grn::NamedTuple,grn_config::FGRNConfig)

    behavioral_products = zeros(Int,(size(grn_config.substrate_protein,1),size(grn_config.substrate_protein,2),4))

    for m in 1:4
        protein = zeros(Int,size(grn_config.substrate_protein))
        decode = reverse(digits(m-1,base = 2,pad = 2))
        @inbounds for j in 1:grn_config.protein_size
            @inbounds for i in 1:grn_config.protein_size
                for k in 1:2
                    if (decode[k] != 0) && (grn.beh_coding[:,:,2:3][i,j,k] > protein[i,j]) #check this logic
                        protein[i,j] = grn.beh_coding[:,:,2:3][i,j,k]
                    end
                end
            end
        end
        behavioral_products[:,:,m] = protein
    end

    J = zeros(Float64,5,5)

    for k in 1:size(behavioral_products,3)
        J[1,k+1] = 1
        J[k+1,1] = J[1,k+1]
    end

    for j in 1:size(behavioral_products,3)
        for i in 1:size(behavioral_products,3)
            J[i+1,j+1] = calculate_affinity(behavioral_products[:,:,i],behavioral_products[:,:,j])
        end
    end

    return J

end

# This is an optimised metropolis-style update and is therefore quite fiddly. It essentailly tries to avoid allocation when comparing the energy of two different configurations.

function environment_update2!(grn::NamedTuple,environment::Array{Float64,3},all_cells::Array{Float64,1},diff_adhesion::Array{Float64,2},
    cell_area_targets::Dict{Float64,Float64},cell_config::CellularConfig,exp_config::ExperimentalConfig)

    n_mcs = 16*(size(all_cells,1) + 1)

    @inbounds for j in 1:size(environment,2)
        @inbounds for i in 1:size(environment,1)
            if environment[i,j,1] != 0
                if cell_area_targets[environment[i,j,1]] == 0
                    for k in 1:size(environment,3)
                        if (k ∉ 2 .+ grn.env_id)
                            environment[i,j,k] = 0
                        end
                    end
                end
            end
        end
    end

    filter!(c-> cell_area_targets[c] != 0,all_cells)

    for t in 1:n_mcs

        source_i = rand(1:size(environment,1))
        source_j = rand(1:size(environment,2))

        target_i = rand(max(1,source_i - 1):min(size(environment,1),source_i + 1))
        target_j = rand(max(1,source_j - 1):min(size(environment,2),source_j + 1))

        if (environment[source_i,source_j,1] != environment[target_i,target_j,1])

            total_surface_sum_original = 0.
            total_surface_sum_proposed = 0.

            @inbounds for j in 1:size(environment,2)
                @inbounds for i in 1:size(environment,1)
                    if (i == target_i) && (j == target_j)
                        @inbounds for jk in max(1,j - 1):min(size(environment,2),j + 1)
                            @inbounds for ik in max(1,i - 1):min(size(environment,2),i + 1)
                                if environment[source_i,source_j,1] != environment[ik,jk,1]
                                    total_surface_sum_proposed += diff_adhesion[Int(environment[source_i,source_j,2])+1,Int(environment[ik,jk,2])+1]
                                end

                                if environment[i,j,1] != environment[ik,jk,1]
                                    total_surface_sum_original += diff_adhesion[Int(environment[i,j,2])+1,Int(environment[ik,jk,2])+1]
                                end
                            end
                        end
                    else
                        @inbounds for jk in max(1,j - 1):min(size(environment,2),j + 1)
                            @inbounds for ik in max(1,i - 1):min(size(environment,2),i + 1)
                                if (ik == target_i) && (jk == target_j)
                                    if environment[i,j,1] != environment[source_i,source_j,1]
                                        total_surface_sum_proposed += diff_adhesion[Int(environment[i,j,2])+1,Int(environment[source_i,source_j,2])+1]
                                    end

                                    if environment[i,j,1] != environment[ik,jk,1]
                                        total_surface_sum_original += diff_adhesion[Int(environment[i,j,2])+1,Int(environment[ik,jk,2])+1]
                                    end
                                else
                                    if environment[i,j,1] != environment[ik,jk,1]
                                        total_surface_sum_proposed += diff_adhesion[Int(environment[i,j,2])+1,Int(environment[ik,jk,2])+1]
                                        total_surface_sum_original += diff_adhesion[Int(environment[i,j,2])+1,Int(environment[ik,jk,2])+1]
                                    end
                                end
                            end
                        end
                    end
                end
            end

            total_sum_original = 0.
            total_sum_proposed = 0.

            @inbounds for cell in all_cells
                cell_size_proposed = 0.
                cell_size_original = 0.
                @inbounds for j in 1:size(environment,2)
                    @inbounds for i in 1:size(environment,1)
                        if (i == target_i) && (j == target_j)
                            if environment[source_i,source_j,1] == cell
                                cell_size_proposed += 1.
                            end

                            if environment[i,j,1] == cell
                                cell_size_original += 1.
                            end
                        else
                            if environment[i,j,1] == cell
                                cell_size_proposed += 1.
                                cell_size_original += 1.
                            end
                        end
                    end
                end
                total_sum_original += (cell_size_original - cell_area_targets[cell])^2
                total_sum_proposed += (cell_size_proposed - cell_area_targets[cell])^2
            end

            if exp_config.chemotaxis_mu == "evolve"
                chemo_multiplier = 1 - calculate_affinity(grn.env_coding[:,:,1],grn.rec_prom[:,:,5])
                proposed_energy = total_surface_sum_proposed + total_sum_proposed - cell_config.chemotaxis_max_strength*chemo_multiplier*(environment[target_i,target_j,2 .+ grn.env_id[1]] - environment[source_i,source_j,2 .+ grn.env_id[1]])
                original_energy = total_surface_sum_original + total_sum_original
            else
                proposed_energy = total_surface_sum_proposed + total_sum_proposed - exp_config.chemotaxis_mu*(environment[target_i,target_j,2 .+ grn.env_id[1]] - environment[source_i,source_j,2 .+ grn.env_id[1]])
                original_energy = total_surface_sum_original + total_sum_original
            end

            if proposed_energy < original_energy
                @inbounds for k in 1:size(environment,3)
                    if (k == 1) || (k == 2) || (k in 2 .+ grn.env_id)
                        environment[target_i,target_j,k] = environment[source_i,source_j,k]
                    else
                        split_p = rand()
                        environment[target_i,target_j,k] = split_p*environment[source_i,source_j,k]
                        environment[source_i,source_j,k] = (1-split_p)*environment[source_i,source_j,k]
                    end
                end
            else
                if rand() < exp(-(proposed_energy - original_energy)/cell_config.temperature)
                    @inbounds for k in 1:size(environment,3)
                        if (k == 1) || (k == 2) || (k in 2 .+ grn.env_id) # dont want to copy diffusing proteins
                            environment[target_i,target_j,k] = environment[source_i,source_j,k]
                        else
                            split_p = rand()
                            environment[target_i,target_j,k] = split_p*environment[source_i,source_j,k]
                            environment[source_i,source_j,k] = (1-split_p)*environment[source_i,source_j,k]
                        end
                    end
                end
            end
        end
    end

    environment[1,:,:] .= 0
    environment[end,:,:] .= 0

    environment[:,1,:] .= 0
    environment[:,end,:] .= 0

end

function measure_energy(grn::NamedTuple,environment::Array{Float64,3},all_cells::Array{Float64,1},diff_adhesion::Array{Float64,2},
    cell_area_targets::Dict{Float64,Float64},cell_config::CellularConfig,exp_config::ExperimentalConfig)

    # @inbounds for j in 1:size(environment,2)
    #     @inbounds for i in 1:size(environment,1)
    #         if environment[i,j,1] != 0
    #             if cell_area_targets[environment[i,j,1]] == 0
    #                 for k in 1:size(environment,3)
    #                     if (k ∉ 2 .+ grn.env_id)
    #                         environment[i,j,k] = 0
    #                     end
    #                 end
    #             end
    #         end
    #     end
    # end

    # filter!(c-> cell_area_targets[c] != 0,all_cells)

    total_surface_sum_original = 0.

    @inbounds for j in 1:size(environment,2)
        @inbounds for i in 1:size(environment,1)
                @inbounds for jk in max(1,j - 1):min(size(environment,2),j + 1)
                    @inbounds for ik in max(1,i - 1):min(size(environment,2),i + 1)

                        if environment[i,j,1] != environment[ik,jk,1]
                            total_surface_sum_original += diff_adhesion[Int(environment[i,j,2])+1,Int(environment[ik,jk,2])+1]
                        end
                    end
                end
        end
    end

    total_sum_original = 0.

    @inbounds for cell in all_cells
        cell_size_original = 0.
        @inbounds for j in 1:size(environment,2)
            @inbounds for i in 1:size(environment,1)
                if environment[i,j,1] == cell
                    cell_size_original += 1.
                end
            end
        end

        total_sum_original += (cell_size_original - cell_area_targets[cell])^2
    end

    return total_surface_sum_original + total_sum_original

end

max_stars_repo_name: harrybooth/FractalDevelopment

max_issues_repo_name: harrybooth/FractalDevelopment

max_forks_repo_name: harrybooth/FractalDevelopment


text:
module jlpkg

# --compile=min segfaults Julia 1.0 and the fix can't trivially be backported.
@static if VERSION < v"1.1"
    const default_julia_flags = ["--color=yes", "--startup-file=no", "-q", "-O0"]
else
    const default_julia_flags = ["--color=yes", "--startup-file=no", "-q", "--compile=min", "-O0"]
end

"""
    jlpkg.install(; kwargs...)

Install the command line interface.

*Keyword arguments:*
 - `command`: name of the executable command, defaults to `jlpkg`.
 - `julia`: path to julia executable, defaults to the path of the
   current running julia.
 - `destdir`: writable directory (available in PATH) for the executable,
   defaults to `~/.julia/bin`.
 - `julia_flags`: vector with command line flags for the julia executable,
   defaults to `["--color=yes", "--startup-file=no", "-q", "--compile=min", "-O0"]`.
 - `force`: boolean used to remove any existing commands.
"""
function install(; julia::String=joinpath(Sys.BINDIR, Base.julia_exename()),
                   command::String="jlpkg",
                   destdir::String=joinpath(DEPOT_PATH[1], "bin"),
                   julia_flags::Vector{String}=default_julia_flags,
                   force::Bool=false)
    Sys.iswindows() && (command *= ".cmd")
    destdir = abspath(expanduser(destdir))
    exec = joinpath(destdir, command)
    if ispath(exec) && !force
        error("file `$(exec)` already exists; use `jlpkg.install(force=true)` to overwrite.")
    end
    mkpath(destdir)
    open(exec, "w") do f
        if Sys.iswindows()
            # TODO: Find a way to embed the script in the file
            print(f, """
                @ECHO OFF
                $(julia) $(join(julia_flags, ' ')) $(abspath(@__DIR__, "cli.jl")) %*
                """)
        else # unix
            print(f, """
                #!/usr/bin/env bash
                #=
                exec $(julia) $(join(julia_flags, ' ')) "\${BASH_SOURCE[0]}" "\$@"
                =#
                """)
            open(abspath(@__DIR__, "cli.jl"), "r") do cli
                write(f, cli)
            end
        end
    end
    chmod(exec, 0o0100775) # equivalent to -rwxrwxr-x (chmod +x exec)
    if Sys.which(command) === nothing
        @warn """
              `Sys.which(\"$(command)\")` returns `nothing`, meaning that `command`
              can not be found in PATH. Either make sure that `$(destdir)` is in PATH,
              or manually add a symlink from a directory in PATH to the installed
              program file.
              Path to installed program:
                  $(exec)
              """
    elseif realpath(Sys.which(command)) !== realpath(exec)
        @warn """
              `Sys.which(\"$(command)\")` points to a different program than the one
              just installed. Please check your PATH.
              `Sys.which(\"$(command)\")`:
                  $(Sys.which(command))
              Path to installed program:
                  $(exec)
              """
    end
    return
end

end # module


text:
using Pkg

Pkg.add("SCARGC")

using SCARGC

data = extractValuesFromFile("../src/datasets/synthetic/1CDT.txt", 16000, 3)

predictedLabels, _ = scargc_1NN(data, 5.0, 300, 2)

predictedLabels, accuracy = scargc_1NN(data, 5.0, 300, 2)

println("Predicted labels: ", predictedLabels)
println("Accuracy: ", accuracy, "%")


text:
#= Digit / Decimal helper functions =#

function digitseparate(amt::Integer, sep::AbstractString, rule::Tuple{Int, Int})
    untilnext = rule[1]
    result = []
    for d in digits(amt)
        if untilnext == 0
            push!(result, sep)
            untilnext = rule[2]
        end
        push!(result, string(d))
        untilnext -= 1
    end
    join(reverse(result))
end

function digitseparate(amt::Integer, dsrule::DigitSeparator)
    digitseparate(amt, dsrule.sep, dsrule.rule)
end


text:
# DESCRIPTION
# Control input time history.
#
# ------------------------------------------------------------------------------

function finp(t)
    # amplitude of perturbation from trim controls
    amp=5
    # controls history
    if t < 1
        u = [0.0; 0.0; 0.0; 0.0]
    elseif t < 3
        u = [amp; 0.0; 0.0; 0.0]
    elseif t < 5
        u = [-amp; 0.0; 0.0; 0.0]
    else
        u = [0.0; 0.0; 0.0; 0.0]
    end
end

max_stars_repo_name: umbertosaetti/J-GenHel

max_issues_repo_name: umbertosaetti/J-SimpleHel

max_forks_repo_name: umbertosaetti/J-SimpleHel


text:
#=
https://docs.mongodb.com/manual/tutorial/deploy-replica-set/

mkdir tmp
cd tmp

mkdir db1
mkdir db2
mkdir db3

mongod --dbpath ./db1 --port 27021 --replSet "rs0" --bind_ip 127.0.0.1
mongod --dbpath ./db2 --port 27022 --replSet "rs0" --bind_ip 127.0.0.1
mongod --dbpath ./db3 --port 27023 --replSet "rs0" --bind_ip 127.0.0.1

mongo --port 27021 replica_set_initiate.js

=#

import Mongoc

using Test
using Dates

const DB_REPLICA_NAME = "mongoc_replica"

@testset "Connect to ReplicaSet" begin
    client = Mongoc.Client("mongodb://127.0.0.1:27021,127.0.0.1:27022,127.0.0.1:27023/?replicaSet=rs0")
    database = client[DB_REPLICA_NAME]
    collection = database["my_collection"]
    @test isempty(collection)
    push!(collection, Mongoc.BSON("""{ "hey" : 1  }"""))
    @test length(collection) == 1
    doc = collect(collection)[1]
    @test doc["hey"] == 1
    empty!(collection)
end

@testset "Transaction API" begin
    client = Mongoc.Client("mongodb://127.0.0.1:27021,127.0.0.1:27022,127.0.0.1:27023/?replicaSet=rs0")
    database = client[DB_REPLICA_NAME]
    collection = database["transaction"]
    @test isempty(collection)
    push!(collection, Mongoc.BSON("""{ "outside_transaction" : 1 }"""))
    @test length(collection) == 1

    session = Mongoc.Session(client)

    Mongoc.start_transaction!(session)
    @test Mongoc.in_transaction(session)
    collection_session = session[DB_REPLICA_NAME]["transaction"]
    push!(collection_session, Mongoc.BSON("""{ "inside_transaction" : 1 }"""))
    @test length(collection_session) == 2
    @test length(collection) == 1

    Mongoc.abort_transaction!(session)
    @test !Mongoc.in_transaction(session)
    @test length(collection_session) == 1

    Mongoc.start_transaction!(session)
    @test Mongoc.in_transaction(session)
    push!(collection_session, Mongoc.BSON("""{ "inside_transaction" : 2 }"""))
    @test length(collection_session) == 2
    @test length(collection) == 1

    Mongoc.commit_transaction!(session)
    @test length(collection_session) == 2
    @test length(collection) == 2

    empty!(collection)
end

@testset "Transaction High-Level API" begin
    client = Mongoc.Client("mongodb://127.0.0.1:27021,127.0.0.1:27022,127.0.0.1:27023/?replicaSet=rs0")

    collection_unbounded = client[DB_REPLICA_NAME]["transaction"]
    @assert isempty(collection_unbounded) # test precondition

    Mongoc.transaction(client) do session # session = Mongoc.Session(client); Mongoc.start_transaction!(session)
        @test Mongoc.in_transaction(session)

        database = session[DB_REPLICA_NAME]
        collection = database["transaction"]
        @test isempty(collection)

        let # insert_many
            items = Vector{Mongoc.BSON}()
            push!(items, Mongoc.BSON("""{ "item" : 1 }"""))
            push!(items, Mongoc.BSON("""{ "item" : 2 }"""))
            push!(items, Mongoc.BSON("""{ "item" : 3 }"""))
            append!(collection, items)
            @test length(collection) == 3
            @test isempty(collection_unbounded)
            empty!(collection)
        end

        @test isempty(collection)
        @test Mongoc.in_transaction(session)

        let # insert_one
            new_item = Mongoc.BSON()
            new_item["inserted"] = true
            push!(collection, new_item)
            @test isempty(collection_unbounded)
            @test !isempty(collection)
        end

        @test Mongoc.in_transaction(session)

        let # delete_one
            item_to_delete = Mongoc.BSON()
            item_to_delete["inserted"] = true
            item_to_delete["to_delete"] = true
            push!(collection, item_to_delete)

            @test length(collection) == 2
            @test isempty(collection_unbounded)

            Mongoc.delete_one(collection, Mongoc.BSON("""{ "to_delete" : true }"""))

            @test length(collection) == 1
            @test isempty(collection_unbounded)
        end

        @test Mongoc.in_transaction(session)

        let # delete_many
            item_to_delete = Mongoc.BSON()
            item_to_delete["inserted"] = true
            item_to_delete["to_delete"] = true
            push!(collection, item_to_delete)

            @test length(collection) == 2
            @test isempty(collection_unbounded)

            Mongoc.delete_many(collection, Mongoc.BSON("""{ "to_delete" : true }"""))

            @test length(collection) == 1
            @test isempty(collection_unbounded)
        end

        @test Mongoc.in_transaction(session)

        let # update_one
            selector = Mongoc.BSON()
            update = Mongoc.BSON("""{ "\$set" : { "update_one" : true } }""")
            Mongoc.update_one(collection, selector, update)
        end

        @test Mongoc.in_transaction(session)

        let # update_many
            selector = Mongoc.BSON()
            update = Mongoc.BSON("""{ "\$set" : { "update_many" : true } }""")
            Mongoc.update_many(collection, selector, update)
        end

        @test Mongoc.in_transaction(session)

        let # check updates
            doc = Mongoc.find_one(collection, Mongoc.BSON())
            @test doc["update_one"]
            @test doc["update_many"]
            @test isempty(collection_unbounded)
        end

        @test Mongoc.in_transaction(session)
    end

    @test !isempty(collection_unbounded)
    empty!(collection_unbounded)

    try
        Mongoc.transaction(client) do session
            database = session[DB_REPLICA_NAME]
            collection = database["transaction"]
            new_item = Mongoc.BSON()
            new_item["inserted"] = true
            push!(collection, new_item)
            @test isempty(collection_unbounded)
            @test !isempty(collection)
            error("abort transaction")
        end
    catch e
        println("got an error: $e")
    end

    @test isempty(collection_unbounded)
end


text:
const IVec8 = SVector{8, Int}

struct DSubHuntPOMDP <: POMDP{SubState, Int, IVec8}
    cp::SubHuntPOMDP
    binsize::Float64
end

struct DSubObsDist
    cd::SubObsDist
    binsize::Float64
end

Base.rand(rng::AbstractRNG, d::DSubObsDist) = floor.(Int, (rand(rng, d.cd)./d.binsize)::Vec8)::IVec8

function Distributions.pdf(d::DSubObsDist, o::IVec8)
    p = 1.0
    cd = d.cd
    for i in 1:length(o)
        lo = d.binsize * o[i]
        hi = lo + d.binsize
        if i == cd.abeam
            p *= cdf(cd.an, hi) - cdf(cd.an, lo)
        else
            p *= cdf(cd.n, hi) - cdf(cd.n, lo)
        end
    end
    return p
end

POMDPs.observation(p::DSubHuntPOMDP, a::Int, sp::SubState) = DSubObsDist(observation(p.cp, a, sp), p.binsize)
n_states(p::DSubHuntPOMDP) = n_states(p.cp)
POMDPs.stateindex(p::DSubHuntPOMDP, s::SubState) = stateindex(p.cp, s)
POMDPs.states(p::DSubHuntPOMDP) = states(p.cp)
POMDPs.initialstate(p::DSubHuntPOMDP) = initialstate(p.cp)
POMDPs.actions(p::DSubHuntPOMDP) = actions(p.cp)
POMDPs.actionindex(p::DSubHuntPOMDP, i::Int) = actionindex(p.cp, i)
n_actions(p::DSubHuntPOMDP) = n_actions(p.cp)
POMDPs.transition(p::DSubHuntPOMDP, s::SubState, a::Int) = transition(p.cp, s, a)
POMDPs.discount(p::DSubHuntPOMDP) = discount(p.cp)
POMDPs.isterminal(p::DSubHuntPOMDP, s::SubState) = isterminal(p.cp, s)
POMDPs.reward(p::DSubHuntPOMDP, s::SubState, a::Int, sp::SubState) = reward(p.cp, s, a, sp)


text:
@testset "bezier" begin
    line = LineString([
      [
        121.025390625,
        -22.91792293614603
      ],
      [
        130.6494140625,
        -19.394067895396613
      ],
      [
        138.33984375,
        -25.681137335685307
      ],
      [
        138.3837890625,
        -32.026706293336126
      ]
    ])

    @test bezier(line).coordinates[2] ≈ [121.02555091028576,-22.917812175967313]
end


text:
@testset "Integers" begin
    let table = [0, 1, 2, 2, 3, 3, 4, 3, 4, 4,
                 5, 4, 5, 5, 5, 4, 5, 5, 6, 5,
                 6, 6, 6, 5, 6, 6, 6, 6, 7, 6,
                 7, 5, 6, 6, 7, 6, 7, 7, 7, 6,
                 7, 7, 7, 7, 7, 7, 8, 6, 7, 7,
                 7, 7, 8, 7, 8, 7, 8, 8, 8, 7,
                 8, 8, 8, 6, 7, 7, 8, 7, 8, 8,
                 9, 7, 8, 8, 8, 8, 8, 8, 9, 7,
                 8, 8, 8, 8, 8, 8, 9, 8, 9, 8,
                 9, 8, 9, 9, 9, 7, 8, 8, 8, 8]

        for (n, expected) in enumerate(table)
            try
                @test thurber(n) == expected
            catch
                @error "Test failed on" n
                rethrow
            end
        end
    end

    let table = [1, 2, 3, 5, 7, 11, 19, 29, 47, 71, 127, 191, 379, 607]
        for (i, n) in enumerate(table)
            expected = i - 1
            try
                @test thurber(n) == expected
            catch
                @error "Test failed on" n
                rethrow
            end
        end

        for i in 2:10, n in table[i-1]:table[i]-1
            expected = i - 1
            try
                @test thurber(n) < expected
            catch
                @error "Test failed on" n
                rethrow
            end
        end
    end
end


text:
mutable struct Edge
    rev::Int
    from::Int
    to::Int
    cap::Int
end

function push!(G::Vector{Vector{Edge}}, from, to, cap)
    fromrev = length(G[from]) + 1
    torev = length(G[to]) + 1
    Base.push!(G[from], Edge(torev, from, to, cap))
    Base.push!(G[to], Edge(fromrev, to, from, 0))
end

function run_flow!(G::Vector{Vector{Edge}}, e::Edge, f)
    e.cap -= f
    G[e.to][e.rev].cap += f
    return G
end

function fodfs(G, v, t, f, seens)
    v == t && return f

    seens[v] = true
    for e ∈ G[v]
        if seens[e.to] || e.cap == 0
            # Skip
        else
            flow = fodfs(G, e.to, t, min(f, e.cap), seens)
            if flow == 0
                # Skip
            else
                run_flow!(G, e, flow)
                return flow
            end
        end
    end

    return 0
end

function FordFulkerson(G, s, t)
    INF = 10^9
    res = 0

    while true
        flow = fodfs(G, s, t, INF, falses(length(G)))
        if flow == 0
            return res
        else
            res += flow
        end
    end

    return 0
end

function main()
    N, G, E = parse.(Int, split(readline()))
    ps = parse.(Int, split(readline())) .+ 1

    H = [Vector{Edge}() for _ = 1:N+1] # Count the super node
    for _ = 1:E
        a, b = parse.(Int, split(readline())) .+ 1
        push!(H, a, b, 1)
        push!(H, b, a, 1)
    end

    for p in ps
        push!(H, p, N+1, 1)
        push!(H, N+1, p, 1)
    end

    println(FordFulkerson(H, 1, N+1))
end

main()


text:
module FileOperations

#
# Function that determines the basename of a file,
# removing the path and the extension
#

clearname(filename::String) = remove_extension(basename(filename))

#
# Function that removes the extension of a file name
#

function remove_extension(filename::String)
    i = length(filename)
    idot = i + 1
    while i > 0
        if filename[i] == '.'
            idot = i
            break
        end
        i = i - 1
    end
    return filename[1:idot-1]
end

#
# Function that return only the extension of the file
#

function file_extension(filename::String)
    i = length(filename)
    idot = 1
    while i > 0
        if filename[i] == '.'
            idot = i
            break
        end
        i = i - 1
    end
    return filename[idot+1:length(filename)]
end

#
# Function that determines if a character is empty
#

function empty_char(char::Char)
    if char == Char(9) || char == Char(32)
        return true
    else
        return false
    end
end

#
# Function that checks if a line is a comment line or if it is empty
#

function commentary(string::String)
    i = 1
    while empty_char(string[i]) && i < length(string)
        i = i + 1
    end
    if string[i] == '#' || i == length(string)
        return true
    else
        return false
    end
end

end


text:
using Reel
using AutomotiveDrivingModels
using AutoViz
# using Multilane
using Interact
# using POMDPToolbox
using Cairo

function interp_state(s, sp, frac)
    a = frac
    b = 1.0 - frac
    cars = CarState[]
    nb_leaving = 0
    for (i,c) in enumerate(s.cars)
        if length(sp.cars) >= i-nb_leaving
            cp = sp.cars[i-nb_leaving]
        else
            break
        end
        if cp.id != c.id
            nb_leaving += 1
            continue
        else # c and cp have same id
            x = a*cp.x + b*c.x
            y = a*cp.y + b*c.y
            vel = a*cp.vel + b*c.vel
            lane_change = c.lane_change
            id = c.id
            push!(cars, CarState(x, y, vel, lane_change, c.behavior, id))
        end
    end
    x = a*sp.x + b*s.x
    t = a*sp.t + b*s.t
    return MLState(x, t, cars, s.terminal)
end

function visualize(p, s, r;
                   tree=nothing,
                   surface=CairoRGBSurface(AutoViz.DEFAULT_CANVAS_WIDTH, AutoViz.DEFAULT_CANVAS_HEIGHT)
                  )
    pp = p.dmodel.phys_param
    stuff = []
    roadway = gen_straight_roadway(pp.nb_lanes, p.dmodel.max_dist+200.0, lane_width=pp.w_lane)
    push!(stuff, roadway)
    str = @sprintf("t: %6.2f\nx: %6.2f\nvel: %6.2f", s.t, s.x, s.cars[1].vel)
    if r !== nothing
        str *= @sprintf("\nr: %6.2f", r)
    end
    push!(stuff, str)
    if tree !== nothing
        # push!(stuff, RelativeRender(tree, s.t, s.cars[1].vel))
        # use the velocity at the root so it doesn't move
        v = tree.node.tree.root_belief.physical.cars[1].vel
        push!(stuff, RelativeRender(tree, s.t, v))
    end
    for (i,c) in enumerate(s.cars)
        if i == 1
            color = colorant"green"
        elseif c isa CarState
            agg = aggressiveness(Multilane.STANDARD_CORRELATED, c.behavior)
            color = weighted_color_mean(agg, colorant"red", colorant"blue")
        else
            @assert c isa CarPhysicalState
            color = colorant"magenta"
        end
        ac = ArrowCar([c.x+s.x, (c.y-1.0)*pp.w_lane], id=i, color=color)
        push!(stuff, ac)
    end

    AutoViz.render(stuff, cam=CarFollowCamera(1, 8.5), surface=surface)
end

# start with just lines

struct RelativeRender{T} <: Renderable
    object::T
    t::Float64     # time that this is being rendered
    vel::Float64
end

struct NodeWithRollouts{N<:POWTreeObsNode}
    node::N
    rollouts::Vector
end

function AutoViz.render!(rm::RenderModel, r::RelativeRender{N}) where {N<:NodeWithRollouts}
    node = r.object.node
    tree = node.tree
    if isroot(node)
        b = tree.root_belief
    else
        b = tree.sr_beliefs[node.node].b
    end
    m = last(tree.sr_beliefs).model
    pp = m.dmodel.phys_param
    t = r.t
    dt = pp.dt

    # draw dots and find o_children
    a_children = tree.tried[node.node]
    o_children = Int[]
    for ac in a_children
        onodes = [last(oi) for oi in tree.generated[ac]]
        append!(o_children, onodes)
        value = tree.v[ac]
        if value > 0.0
            color = weighted_color_mean(value, colorant"yellow", colorant"green")
        else
            color = weighted_color_mean(clamp(-value, 0.0, 1.0), colorant"yellow", colorant"red")
        end
        if !isempty(onodes)
            ps = tree.o_labels[first(onodes)]
            c = first(ps.cars)
            x = ps.x + c.x - (ps.t-t)*r.vel
            # x, y, r, fill, stroke, linewidth
            add_instruction!(rm, render_circle, (x, (c.y-1.0)*pp.w_lane, 0.2, color, color, 0.0))
        end
    end
    o_children

    # draw all the lines
    # XXX hack: should be most likely instead of rand
    s = rand(Random.GLOBAL_RNG, b)
    for oc in o_children
        sp = rand(Random.GLOBAL_RNG, tree.sr_beliefs[oc].b)
        render_rel_lines!(rm, pp, s, sp, t, r.vel)
    end

    # render the children
    for oc in o_children
        nwr = NodeWithRollouts(POWTreeObsNode(tree, oc), r.object.rollouts)
        render!(rm, RelativeRender(nwr, t, r.vel))
        ro = r.object.rollouts[oc]
        for (s, sp) in eachstep(ro, "s,sp")
            render_rel_lines!(rm, pp, s, sp, t, r.vel)
            # render_rel_ego_line!(rm, pp, s, sp, t, r.vel)
        end
    end
end

function render_rel_ego_line!(rm::RenderModel, pp, s, sp, t, vel)
    c = first(s.cars)
    cp = first(sp.cars)
    x1 = s.x + c.x - (s.t-t)*vel
    y1 = (c.y - 1.0)*pp.w_lane
    x2 = sp.x + cp.x - (sp.t-t)*vel
    y2 = (cp.y - 1.0)*pp.w_lane
    width = 0.1
    color = RGBA(0.8, 0.8, 0.8, 0.2)
    add_instruction!(rm, render_line_segment, (x1, y1, x2, y2, color, width))
end

function render_rel_lines!(rm::RenderModel, pp, s, sp, t, vel)
    nb_leaving = 0
    for (i,c) in enumerate(s.cars)
        if length(sp.cars) >= i-nb_leaving
            cp = sp.cars[i-nb_leaving]
        else
            break
        end
        if cp.id != c.id
            nb_leaving += 1
            continue
        else # c and cp have same id
            # for x, if the point is in the future, you want it to be way behind where it should be
            # if the point is in the past, you want it to be way ahead
            x1 = s.x + c.x - (s.t-t)*vel
            y1 = (c.y - 1.0)*pp.w_lane
            x2 = sp.x + cp.x - (sp.t-t)*vel
            y2 = (cp.y - 1.0)*pp.w_lane
            width = 0.1
            if c.id == 1
                color = RGBA(0.8, 0.8, 0.8, 0.2)
            else
                agg = aggressiveness(Multilane.STANDARD_CORRELATED, c.behavior)
                color = weighted_color_mean(agg, RGBA(1.0, 0.0, 0.0, 0.2), RGBA(0.0, 0.0, 1.0, 0.2))
            end
            add_instruction!(rm, render_line_segment, (x1, y1, x2, y2, color, width))
        end
    end
end

function make_rollouts(planner, tree)
    t0 = tree.root_belief.physical.t
    m = planner.problem
    dt = m.dmodel.phys_param.dt
    rop = solve(SimpleSolver(), m)
    rollouts = Vector{Any}(undef, length(tree.sr_beliefs))
    for i in 2:length(tree.sr_beliefs)
        srb = tree.sr_beliefs[i]
        b = srb.b
        ps = b.physical
        start_t = srb.b.physical.t
        completed = round(Int, (start_t - t0)/dt)
        steps = planner.solver.max_depth - completed
        hr = HistoryRecorder(max_steps=steps)
        cars = [CarState(ps.cars[i], first(b.particles[i])) for i in 1:length(b.particles)]
        state = MLState(ps, cars)
        mdp = NoCrashMDP{typeof(m.rmodel), typeof(m.dmodel.behaviors)}(m.dmodel, m.rmodel, m.discount, m.throw)
        hist = POMDPs.simulate(hr, mdp, rop, state)
        rollouts[i] = hist
    end
    return rollouts
end

#=
function AutoViz.render!(rm::RenderModel, t::RelativeRender{P}) where {P<:POMCPOWTree}
    render!(rm, RelativeRender(POWTreeObsNode(t.object, 1), t.t, t.vel))
end

function AutoViz.render!(rm::RenderModel, r::RelativeRender{N}) where {N<:POWTreeObsNode}
    node = r.object
    tree = node.tree
    if isroot(node)
        b = tree.root_belief
    else
        b = tree.sr_beliefs[node.node].b
    end
    m = last(tree.sr_beliefs).model
    pp = m.dmodel.phys_param
    t = r.t
    dt = pp.dt

    a_children = tree.tried[node.node]
    # value = maximum(tree.v[c] for c in a_children)
    o_children = Int[]
    for ac in a_children
        append!(o_children, [last(oi) for oi in tree.generated[ac]])
    end
    o_children

    # draw all the lines
    s = b.physical
    for oc in o_children
        sp = tree.sr_beliefs[oc].b.physical
        render_rel_lines!(rm, pp, s, sp, t, r.vel)
    end

    # render the children
    for oc in o_children
        render!(rm, RelativeRender(POWTreeObsNode(tree, oc), t, r.vel))
    end
end

=#

BEHAVIOR_COLORS = Dict{Float64,AbstractString}(0.5=>"#0101DF",0.25=>"#D7DF01",0.0=>"#FF0000")

function visualize(mdp::Union{MLMDP,MLPOMDP}, s::MLState, a::MLAction, sp::MLState;
                   idx::Union{Nothing,Int}=nothing)
    pp = mdp.dmodel.phys_param
    roadway = gen_straight_roadway(pp.nb_lanes,
                                   pp.lane_length,
                                   lane_width=pp.w_lane)

    hbol = HardBrakeOverlay(pp, braking_ids(mdp, s, sp))
    iol = InfoOverlay(pp, idx,
                      s.cars[1].vel,
                      max_braking(mdp, s, sp),
                      is_crash(mdp, s, sp))
    cidol = CarIDOverlay()
    cvol = CarVelOverlay()

    scene = Scene()
    for cs in s.cars
        push!(scene, Vehicle(VehicleState(VecSE2(cs.x, (cs.y-1.0)*pp.w_lane, 0.0), roadway, cs.vel),
                                VehicleDef(AgentClass.CAR, pp.l_car, pp.w_car), cs.id))
                                # VehicleDef(cs.id, AgentClass.CAR, pp.l_car, pp.w_car)))
    end
    AutoViz.render(scene, roadway, [hbol, iol, cidol, cvol], cam=FitToContentCamera())
end

visualize(mdp::Union{MLMDP,MLPOMDP}, s::MLState) = visualize(mdp.dmodel.phys_param, s)

function visualize(pp::PhysicalParam, s::MLState)
    roadway = gen_straight_roadway(pp.nb_lanes,
                                   pp.lane_length,
                                   lane_width=pp.w_lane)
    scene = Scene()
    for cs in s.cars
        push!(scene, Vehicle(VehicleState(VecSE2(cs.x, (cs.y-1.0)*pp.w_lane, 0.0), roadway, cs.vel),
                                VehicleDef(AgentClass.CAR, pp.l_car, pp.w_car), cs.id))
                                # VehicleDef(cs.id, AgentClass.CAR, pp.l_car, pp.w_car)))
    end
    AutoViz.render(scene, roadway, [CarIDOverlay(), CarVelOverlay()], cam=FitToContentCamera())
end

mutable struct HardBrakeOverlay <: SceneOverlay
    pp::PhysicalParam
    ids::Vector{Int}
end

function AutoViz.render!(rm::RenderModel, o::HardBrakeOverlay, scene::Scene, roadway::Roadway)
    for veh in scene
        if veh.id in o.ids
            for (size, offset) in [(1.2,0.4), (1.0,0.8), (0.8,1.2)]
                top = VecE2(veh.state.posG) + VecE2(-((1 .+ offset)*o.pp.l_car/2), size*o.pp.w_car/2)
                bottom = VecE2(veh.state.posG) + VecE2(-((1 .+ offset)*o.pp.l_car/2), -size*o.pp.w_car/2)
                add_instruction!(rm, render_line_segment, (top.x, top.y, bottom.x, bottom.y, colorant"red", 0.3))
            end
        end
    end
    # if !isempty(o.ids)
    #     add_instruction!(rendermodel, render_text, ("Hard Brake(s)!", 0, 15, 12, colorant"red"))
    # end
end

mutable struct InfoOverlay <: SceneOverlay
    pp::PhysicalParam
    state_index::Union{Nothing,Int}
    vel::Float64
    max_braking::Float64
    iscrash::Bool
end

function AutoViz.render!(rm::RenderModel, o::InfoOverlay, scene::Scene, roadway::Roadway)
    line_delta = 1.6
    top_line_y = -o.pp.w_lane/2.0 - line_delta
    y = top_line_y
    if nothing !== (o.state_index)
        add_instruction!(rm, render_text,
                         ("state index: $(o.state_index)", 0, y, 12, colorant"white"))
        y -= line_delta
    end
    add_instruction!(rm, render_text,
                     (@sprintf("velocity: %5.2f m/s", o.vel), 0, y, 12, colorant"white"))
    y -= line_delta
    add_instruction!(rm, render_text,
                     (@sprintf("max braking: %5.2f m/s", o.max_braking), 0, y, 12,
                      o.max_braking==o.pp.brake_limit ? colorant"red" : colorant"white"))
    y -= line_delta
    if o.iscrash
        add_instruction!(rm, render_text,
                         ("crash!", 0, y, 12, colorant"red"))
        y -= line_delta
    end
end

mutable struct CarIDOverlay <: SceneOverlay end

function AutoViz.render!(rm::RenderModel, o::CarIDOverlay, scene::Scene, roadway::Roadway)
    for (i,v) in enumerate(scene)
        cx = v.state.posG.x
        cy = v.state.posG.y
        nx = cx - v.def.length/2
        ny = cy + v.def.width/2 - 0.6
        add_instruction!(rm, render_text,
                         (@sprintf("%02.d",i), nx, ny, 7, colorant"white"))
        idx = cx - v.def.length/2
        idy = cy - v.def.width/2 + 0.1
        add_instruction!(rm, render_text,
                         (@sprintf("id %02.d",v.id), idx, idy, 7, colorant"white"))
    end
end

mutable struct CarVelOverlay <: SceneOverlay end

function AutoViz.render!(rm::RenderModel, o::CarVelOverlay, scene::Scene, roadway::Roadway)
    for (i,v) in enumerate(scene)
        cx = v.state.posG.x
        cy = v.state.posG.y
        vx = cx + v.def.length/2 - 1.4
        vy = cy + v.def.width/2 - 0.6
        add_instruction!(rm, render_text,
                         (@sprintf("%04.1f",v.state.v), vx, vy, 7, colorant"white"))
    end
end


text:
module SmartShockFinder

using BSON: @save
using Distributions: Uniform
using Downloads: download
using Flux
using Flux: onecold, crossentropy, @epochs, Data.DataLoader, params
using HDF5: h5open
using OffsetArrays: OffsetArray, OffsetVector
using StaticArrays: SVector
using Statistics: mean
using Random: shuffle!
using Trixi: TreeMesh, leaf_cells, length_at_cell, vandermonde_legendre, multiply_dimensionwise!, legendre_polynomial_and_derivative, n_directions
using Trixi: has_neighbor, has_children, polynomial_interpolation_matrix, has_any_neighbor, gauss_lobatto_nodes_weights

include("inputdata/inputdata1d.jl")
include("inputdata/inputdata2d.jl")
include("functions/function1d.jl")
include("functions/function2d.jl")
include("meshes/1d/mesh1d.jl")
include("meshes/2d/mesh2d.jl")
include("traindata1d.jl")
include("traindata2d.jl")
include("validdata1d.jl")
include("validdata2d.jl")
include("network1d.jl")
include("network2d.jl")

export generate_inputdata1d, generate_inputXi1d
export generate_inputdata2d, generate_inputXi2d
export train_network1d, train_network2d, train_network2dcnn,  generate_traindataset1d, generate_traindataset2d
export generate_validdataset1d, generate_validdataset2d

end # module

## TODO
# Regularisierung in network.jl
# h5 statt bson


text:
x0  = 1.5 * ones(6)
nlp = ADNLPModel(rosenbrock,  x0)

#The traditional way to solve an optimization problem using NLPModelsIpopt
#https://github.com/JuliaSmoothOptimizers/NLPModelsIpopt.jl
printstyled("Oth scenario:\n")

stats = ipopt(nlp, print_level = 0, x0 = x0)
#Use y0 (general), zL (lower bound), zU (upper bound)
#for initial guess of Lagrange multipliers.
@show stats.solution, stats.status

nlp_at_x = NLPAtX(x0)
stop = NLPStopping(nlp, nlp_at_x, optimality_check = unconstrained_check)

#1st scenario, we solve again the problem with the buffer solver
printstyled("1st scenario:\n")
solveIpopt(stop)
@show stop.current_state.x, status(stop)
nbiter = stop.meta.nb_of_stop

#2nd scenario: we check that we control the maximum iterations.
printstyled("2nd scenario:\n")
#rstate is set as true to allow reinit! modifying the State
reinit!(stop, rstate = true, x = x0)
stop.meta.max_iter = max(nbiter-4,1)

solveIpopt(stop)
#Final status is :IterationLimit
@show stop.current_state.x, status(stop)

printstyled("3rd scenario:\n")
mpcc = MPCCNLPs(nlp)
test = NLMPCC(mpcc)
nlp_at_x = NLPAtX(x0)
stop_2 = NLPStopping(test, nlp_at_x, optimality_check = unconstrained_check)

solveIpopt(stop_2)
@show stop_2.current_state.x, status(stop_2)

printstyled("4th scenario:\n")
nlp_at_x = MPCCAtX(mpcc.meta.x0, zeros(0))
stop_nlp = MPCCStopping(mpcc, nlp_at_x, optimality_check = SStat)

@test mpcc.meta.ncc  == 0
@test mpcc.meta.ncon == 0
@test status(stop_nlp) == :Unknown

solveIpopt(stop_nlp)
#Final status is :IterationLimit
@show stop_nlp.current_state.x, status(stop_nlp)


text:
using DataFrames, CSV, Statistics
data = CSV.read("data/purchaseData.csv", DataFrame)

rowsKeep = .!(ismissing.(data.Grade) .& ismissing.(data.Price))
data = data[rowsKeep, :]

replace!(x -> ismissing(x) ? "QQ" : x, data.Name)
replace!(x -> ismissing(x) ? "31/06/2008" : x, data.Date)

grPr = combine(groupby(dropmissing(data), :Grade),
    :Price=> (x -> round(mean(x), digits=-3)) => :AvgPrice)

d = Dict(grPr[:,1] .=> grPr[:,2])
nearIndx(v, x) = findmin(abs.(v.-x))[2]
for i in 1:nrow(data)
    if ismissing(data[i, :Price])
        data[i, :Price] = d[data[i, :Grade]]
    end
    if ismissing(data[i, :Grade])
        data[i, :Grade] = grPr[ nearIndx(grPr[:,2], data[i, :Price]), :Grade]
    end
end

println(first(data, 5), "\n")
println(describe(data))

max_stars_repo_name: newptcai/StatsWithJuliaBook

max_issues_repo_name: newptcai/StatsWithJuliaBook

max_forks_repo_name: newptcai/StatsWithJuliaBook


text:
mutable struct SumAcc{T}
    s :: T
end

sumAcc(T) = SumAcc(vzero(T))

function add!(acc::SumAcc, x)
    SIMDops.@fusible acc.s += x
end

function add!(acc::SumAcc{T}, x::SumAcc{T}) where {T}
    SIMDops.@fusible acc.s += x.s
end

Base.sum(acc::SumAcc{T}) where {T<:Vec}  = SumAcc(vsum(acc.s))
Base.sum(acc::SumAcc{T}) where {T<:Real} = acc.s


text:
@testset "Correction param. write" begin
	corrpar = DataFrame(column=[1,2,3], id = [3,2,1],
						x1 = [DateTime(2010,01,01,04,30,00),
							  DateTime(2010,01,01,08,00,00),
							  DateTime(2010,01,02,04,00,00)],
					  	x2 = [DateTime(2010,01,01,07,30,00),
							  DateTime(2010,01,01,09,30,09),
							  DateTime(2010,01,02,06,30,00)],
						y1 = [NaN,NaN,10.],y2 = [NaN,NaN,0.0],
						comment = ["first", "second", "third"]);
	fileout = joinpath(dirname(@__DIR__),"test","output","writecorrpar_out.txt");
	FileTools.writecorrpar(corrpar,fileout,decimal=1)
	t = readdlm(fileout,comments=true,comment_char='%');
	@test t[:,1] == [3,2,1]
	@test t[:,2] == [1,2,3]
	@test t[:,3] == repeat([2010],3)
	@test t[:,4] == repeat([1],3)
	@test t[:,5] == [1,1,2];
	@test t[:,6] == [4,8,4];
	@test t[:,7] == [30,0,0];
	@test t[:,8] == [0,0,0];
	@test t[:,9] == repeat([2010],3)
	@test t[:,10] == repeat([1],3)
	@test t[:,11] == [1,1,2];
	@test t[:,12] == [7,9,6];
	@test t[:,13] == [30,30,30];
	@test t[:,14] == [0,9,0];
	for i in 1:2
		for j in 15:16
			@test isnan(t[i,j])
		end
	end
	@test t[3,15] == 10.;
	@test t[3,16] == 0.;
	@test t[:,17] == convert(Vector{String},corrpar[:comment]);
	# Return for next test
	return corrpar,fileout
end

@testset "Correction param. read" begin
	corrpar = DataFrame(column=[1,2,3], id = [3,2,1],
					x1 = [DateTime(2010,01,01,04,30,00),
						  DateTime(2010,01,01,08,00,00),
						  DateTime(2010,01,02,04,00,00)],
					x2 = [DateTime(2010,01,01,07,30,00),
						  DateTime(2010,01,01,09,30,09),
						  DateTime(2010,01,02,06,30,00)],
					y1 = [NaN,NaN,10.],y2 = [NaN,NaN,0.0],
					comment = ["first", "second", "third"]);
	fileout = joinpath(dirname(@__DIR__),"test","input","corrpar_in.txt");
	corrpar_read = FileTools.readcorrpar(fileout)
	for i in names(corrpar)
		if i != :y1 && i != :y2
			@test corrpar_read[i] == corrpar[i]
		end
	end
	@test all(isnan.(corrpar_read[:y1][1:2]))
	@test all(isnan.(corrpar_read[:y2][1:2]))
	@test corrpar_read[:y1][3] == corrpar[:y1][3]
	@test corrpar_read[:y2][3] == corrpar[:y2][3]
end


text:
const WEIGHTS = [
    "resnet50",
    "densenet121",
    "googlenet",
    "squeezenet",
    "vgg19",
]

const CHECKSUMS = [
    "88e9196c1d451186139dbc93d538092e21824978c5ec647a6599ad4152e79870",
    "",
    "",
    "",
    "",
]

function initdatadeps()
    for (name, checksum) in zip(WEIGHTS, CHECKSUMS)

        DataDeps.register(DataDep(
            "weights-$name",
            """
            Pretrained weights for model "$name".
            """,
            "https://github.com/darsnack/MetalheadWeights/raw/main/$name.bson",
            checksum,
        ))
    end
end


text:
using Distributed
using JLD2

include("../BioClim/src/required.jl")
# include("expandlayers_vulpes_vulpes.jl")

taxa_occ[2]

#using new_predictions from north america only
newlayers = new_predictions

#create empty array
presence_all = []
# fill pred/prey pp_presence matrix with binary values (1 if present, 0 if not)
@time for i in 1:length(newlayers)     # iterate through all species
    # create new empty matrix for predator presence, dimensions of predator newlayers[1]
        pp_presence = zeros(Int64, size(newlayers[1]))
        for j in 1:length(newlayers[1].grid)   # iterate through all coordinates
            if isnan(newlayers[i][j])
                pp_presence[j] = 0
            else
                pp_presence[j] = 1
            end
        end
        push!(presence_all, pp_presence)
    end
presence_all

##get sum
sum_all = copy(presence_all[1])
#add arrays to pred array
for k in 2:length(presence_all)
    sum_all .+= presence_all[k]
end

#replace zeros to NaN
sum_all = replace(sum_all, 0 => NaN)

#save as SDMLayer
sum_lay = SDMLayer(sum_all, newlayers[1].left, newlayers[1].right, newlayers[1].bottom, newlayers[1].top)

plot_sum = plotSDM(sum_lay)
plot_sum = plot!(title="All species overlap")

#crop to americas range only
long_range = (-180.0, -46.0)
lat_range = (-90.0, 90.0)
#specify the range of sum_lay
sum_lay_Am = sum_lay[long_range, lat_range]

plot_am = plotSDM(sum_lay_Am)
plot_sum = plot!(title="All species overlap")

#####################
##get sum where only predator is present
sum_on_pred = copy(presence_all[1])
#add arrays to pred array
for k in 2:length(presence_all)
    for j in 1:length(presence_all[1])
    #only add where predator species is present
         if presence_all[1][j] == 1
            sum_on_pred[j] = sum_on_pred[j] .+ presence_all[k][j]
        end
    end
end

#replace zeros to NaN
sum_on_pred = replace(sum_on_pred, 0 => NaN)

#save as SDMLayer
sum_lay_pred = SDMLayer(sum_on_pred, newlayers[1].left, newlayers[1].right, newlayers[1].bottom, newlayers[1].top)

plot_sum_on_pred = plotSDM(sum_lay_pred)
plot_sum_on_pred = plot!(title="Presence map: vulpes vulpes")
savefig("../SDM/figures/vulpes_vulpes/sdm_map-vulpes_northamerica.pdf")

#crop to americas range only
long_range = (-180.0, -46.0)
lat_range = (-90.0, 90.0)
#specify the range of sum_lay_pred
sum_lay_Am = sum_lay_pred[long_range, lat_range]

plot_am = plotSDM(sum_lay_Am)
plot_am = plot!(title="All species overlap")
savefig("../SDM/figures/vulpes_vulpes/sdm_map-vulpes_vulpes_america.pdf")

###############################
###plot individual sp map
taxa_occ[4]

plot1 = plotSDM(new_predictions[1])
plot1 = plot!(title="Vulpes vulpes")
savefig("../SDM/figures/vulpes_vulpes/sdm_map-vulpes_vulpes_newpredictions.pdf")

plot2 = plotSDM(new_predictions[2])
plot2 = plot!(title="Cynomys ludovicianus")
savefig("../SDM/figures/vulpes_vulpes/sdm_map-cynomys_ludovicianus.pdf")

plot3 = plotSDM(new_predictions[3])
plot3 = plot!(title="Tetrix subulata")
savefig("../SDM/figures/vulpes_vulpes/sdm_map-tetrix_subulata.pdf")

plot4 = plotSDM(new_predictions[4])
plot4 = plot!(title="Lepus europaeus")
savefig("../SDM/figures/vulpes_vulpes/sdm_map-lepus_europaeus.pdf")

max_stars_repo_name: kiristern/SDM

max_issues_repo_name: kiristern/SDM

max_forks_repo_name: kiristern/SDM


text:
module HomConBase

    #using Reexport
    import Base: eltype

    import FixedPolySystem: AbstractPolySystem, Poly, PolySystem,
        nvariables, variables, removepoly, degrees,
        evaluate, evaluate!, substitute, differentiate,
        ishomogenous, homogenize, homogenized, dehomogenize,
        weyldot, weylnorm, coefftype
    # Exports from FixedPolySystem
    export AbstractPolySystem, Poly, PolySystem,
        nvariables, variables, polynomials, degrees,
        evaluate, evaluate!, differentiate, substitute, removepoly,
        ishomogenous, homogenize, homogenized, dehomogenize,
        weyldot, weylnorm

    export AbstractHomotopy
    abstract type AbstractHomotopy{T<:Number} end

    abstract type HomConAlgorithm end

    export HomConAlgorithm

    function init end
    function solve end

    export init, solve

    include("homotopy.jl")
    include("utilities.jl")

    export evaluate, substitute, startsystem, targetsystem,
        differentiate, dt, ∂t, nvariables, degrees,
        nequations, removepoly, ishomogenous, homogenize, homogenized, weylnorm, coefftype

    export affine, projective, totaldegree, randomsystem
end


text:
using Flux
using Flux: onehotbatch, argmax, crossentropy, throttle, @epochs
using Base.Iterators: repeated, partition
using MLDatasets

BATCH_SIZE = 100

# load CIFAR-10 training set
trainX, trainY = CIFAR10.traindata()
testX,  testY  = CIFAR10.testdata()

# MLDatasets returns UInt8 thus convert it to Float64
trainX = Array{Float64}(trainX)
testX = Array{Float64}(testX)
println("conversion is done")

# construct one-hot vectors from labels
trainY = onehotbatch(trainY, 0:9)
testY = onehotbatch(testY, 0:9)

train = (trainX, trainY)

# TODO convert below to list comprehension
# TODO shuffle
# split training set into batches
# train_data contains whole data in batches
train_data = Array{Any}(div(50000, BATCH_SIZE))
for i = 0:div(50000, BATCH_SIZE) - 1
    train_data[i+1] = train[1][:,:,:, 1 + i*BATCH_SIZE:(i+1)*BATCH_SIZE],
                      train[2][:, 1 + i*BATCH_SIZE:(i+1)*BATCH_SIZE]
end

println("data is ready to be learnt")

m = Chain(
  Conv((3,3), 3=>16, relu),
  x -> maxpool(x, (2,2)),
  Conv((2,2), 16=>8, relu),
  x -> maxpool(x, (2,2)),
  x -> reshape(x, :, size(x, 4)),
  Dense(8*7*7 , 10), softmax)

m(train_data[1][1])
loss(x, y) = crossentropy(m(x), y)
accuracy(x, y) = mean(argmax(m(x)) .== argmax(y))
evalcb = throttle(() -> @show(accuracy(testX, testY)), 10)
opt = ADAM(params(m))

# Flux.train!() runs for 1 epoch, default.
# Change 15 to train for different epochs using @epochs macro
@epochs 15 Flux.train!(loss, train, opt, cb = evalcb)


text:
export localips, launch

@init global const port = get(ENV, "BLINK_PORT", rand(2_000:10_000))

const ippat = r"([0-9]+\.){3}[0-9]+"

@static if is_unix()
    localips() = map(IPv4, readlines(`ifconfig` |>
                      `grep -Eo $("inet (addr:)?$(ippat.pattern)")` |>
                      `grep -Eo $(ippat.pattern)` |>
                      `grep -v $("127.0.0.1")`))
end

# Browser Window

@static if is_apple()
    launch(x) = run(`open $x`)
elseif is_linux()
    launch(x) = run(`xdg-open $x`)
elseif is_windows()
    launch(x) = run(`cmd /C start $x`)
end

localurl(p::Page) = "http://127.0.0.1:$port/$(id(p))"

launch(p::Page) = (launch(localurl(p)); p)


text:
export PushForward

import Bijectors
import Base

struct PushForward{F,M} <: AbstractMeasure
    f::F
    μ::M
end

function logdensity(d::PushForward{F,M}, y) where {F <: Bijectors.Bijector, M}
    res = Bijectors.forward(inv(d.f), y)
    return logdensity(d.μ, res.rv) + res.logabsdetjac
end

for F in [
      Bijectors.ADBijector
    , Bijectors.Composed
    , Bijectors.Exp
    , Bijectors.Identity
    , Bijectors.Inverse
    , Bijectors.InvertibleBatchNorm
    , Bijectors.Log
    , Bijectors.Logit
    , Bijectors.PDBijector
    , Bijectors.Permute
    , Bijectors.PlanarLayer
    , Bijectors.RadialLayer
    , Bijectors.Scale
    , Bijectors.Shift
    , Bijectors.SimplexBijector
    , Bijectors.Stacked
    , Bijectors.TruncatedBijector]
    @eval (f::$F)(μ::M) where {M <: AbstractMeasure} = PushForward(f,μ)
end

Base.rand(d::PushForward) = d.f(rand(d.μ))


text:
module Math

using LinearAlgebra
using InlineExports
using StaticArrays

@export begin
   const Vec{N} = SVector{N,  Cfloat}
   const Mat{N} = SMatrix{N, N, Cfloat}
   const Mat2   = Mat{2}
   const Mat3   = Mat{3}
   const Mat4   = Mat{4}
end

Vec(coords::Vararg{<:Real, N}) where {N} = Vec{N}(coords...)
Mat{N}() where {N} = Mat{N}(StaticArrays.I)

include("quaternions.jl")

@export translate(x::Real, y::Real, z::Real) = Mat4([
   1 0 0 x
   0 1 0 y
   0 0 1 z
   0 0 0 1
])

@export scale(x::Real, y::Real, z::Real) = Mat4([
   x 0 0 0
   0 y 0 0
   0 0 z 0
   0 0 0 1
])

scale(s::Real) = scale(s, s, s)

@export rotate(axis::Vec{3}, θ::Real) = rotation(Qt(axis, θ))
rotate(pairs::Pair{Vec{3}, <:Real}...) = prod(Qt(axis, θ) for (axis, θ) in pairs) |> rotation

@export rotateX(θ::Real) = rotate(X => θ)
@export rotateY(θ::Real) = rotate(Y => θ)
@export rotateZ(θ::Real) = rotate(Z => θ)

@export scaleX(x::Real) = scale(x, 1, 1)
@export scaleY(y::Real) = scale(1, y, 1)
@export scaleZ(z::Real) = scale(1, 1, z)

@export translateX(x::Real) = translate(x, 1, 1)
@export translateY(y::Real) = translate(1, y, 1)
@export translateZ(z::Real) = translate(1, 1, z)

@export function lookAt(eye::Vec{3}, center::Vec{3}, up::Vec{3})
   Z = normalize(center - eye)
   X = normalize(Z × up)
   Y = X × Z

   Mat4([
      X.x X.y X.z (-(X ⋅ eye))
      Y.x Y.y Y.z (-(Y ⋅ eye))
      Z.x Z.y Z.z (-(Z ⋅ eye))
      0   0   0   1
   ])
end

@export function ortho(left::Real, right::Real, bottom::Real, top::Real, near::Real, far::Real)
   Mat4([
      (2 / (right - left)) 0 0 (- ((right + left) / (right - left)))
      0 (2 / (top - bottom)) 0 (- ((top + bottom) / (top - bottom)))
      0 0 (-(2 / (far - near)))  (- ((far + near) / (far - near)))
      0 0 0 1
   ])
end

@export function perspective(fov::Real, aspect::Real, near::Real, far::Real)
   α = tan(deg2rad(fov) / 2)
   Mat4([
      (1 / (aspect * α)) 0 0 0
      0 (1 / α) 0 0
      0 0 (-((far + near) / (far - near))) (-((2far * near) / (far - near)))
      0 0 -1 0
   ])
end

end # module

max_stars_repo_name: jorge-brito/Glutils

max_issues_repo_name: jorge-brito/Glutils

max_forks_repo_name: jorge-brito/Glutils


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 = "ViennaRNA"
version = v"2.5.1"

# Collection of sources required to complete build
sources = [
    ArchiveSource("https://github.com/ViennaRNA/ViennaRNA/releases/download/v$(version)/ViennaRNA-$(version).tar.gz",
                  "be4414d574825ef7236533e2885b2bd795f6e833487236ad1ff45cdd4b7e44b7"),
    DirectorySource("./bundled")
]

# Bash recipe for building across all platforms
# Build issues
# - openmp not found on darwin, possible with CompilerSupportLibraries?
# - powerpc64le: build fails in vectorisation routines of dlib
script = raw"""
cd $WORKSPACE/srcdir/ViennaRNA-*/

# configure script needs bash
sed -i -e '1s|#! /bin/sh|#! /bin/bash|' configure

# set this explicitly for the libsvm Makefile, which would
# otherwise use g++
export CC=cc
export CXX=c++

# where to find dependencies
export CPPFLAGS="-I${includedir}"
export LDFLAGS="-L${libdir}"

if [[ $target == *-w64-mingw32* ]]; then
    # time measurement in RNAforester doesn't compile on windows (mingw32),
    # so we disable it
    atomic_patch -p1 ../patches/windows-forester-remove-time-measurement.patch

    # needed for compilation of dlib on windows
    export LIBS="-lwinmm"

    # fix for missing nonstandard strcasestr function on windows
    atomic_patch -p1 ../patches/windows-strcasestr-fix.patch
fi

# configure script fails (only in sandbox) without
# setting ac_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes
ac_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes \
    ./configure \
    --prefix=${prefix} --build=${MACHTYPE} --host=${target} \
    --with-pic --disable-c11 \
    --with-mpfr --with-json --with-svm --with-gsl \
    --with-cluster --with-kinwalker \
    --without-perl --without-python --without-python3 \
    --without-doc --without-tutorial --without-cla

make -j${nproc}
make install

# create and install a shared library libRNA
ldflags="$LDFLAGS -g -O2 -fno-strict-aliasing -ftree-vectorize -pthread"
libs="-lpthread -lmpfr -lgmp -lstdc++ -lgsl -lgslcblas -lm $LIBS"

# TODO: setting -flto -ffat-lto-objects assumes we are using gcc
if [[ $target == *-linux-* ]]; then
    ldflags="$ldflags -flto -ffat-lto-objects"
elif [[ $target == *-w64-mingw32* ]]; then
    ldflags="$ldflags -flto -ffat-lto-objects"
    # needed for dlib
    libs="$libs -lws2_32"
fi
if [[ $target != *-darwin* ]]; then
    ldflags="$ldflags -fopenmp"
fi

$CC -shared -o "${libdir}/libRNA.${dlext}" \
    $ldflags \
    -Wl,$(flagon --whole-archive) ./src/ViennaRNA/libRNA.a -Wl,$(flagon --no-whole-archive) \
    $libs

cp src/cthreadpool/LICENSE LICENSE-cthreadpool
cp src/dlib-*/LICENSE.txt LICENSE-dlib
cp src/json/LICENSE LICENSE-json
cp src/libsvm-*/COPYRIGHT COPYRIGHT-libsvm
cp src/RNAforester/COPYING COPYING-RNAforester
install_license LICENSE-cthreadpool
install_license LICENSE-dlib
install_license LICENSE-json
install_license COPYRIGHT-libsvm
install_license COPYING-RNAforester
install_license COPYING
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = supported_platforms(; experimental=true, exclude = p -> arch(p) == "powerpc64le")
platforms = expand_cxxstring_abis(platforms)

# The products that we will ensure are always built
products = [
    ExecutableProduct("AnalyseDists", :AnalyseDists),
    ExecutableProduct("AnalyseSeqs", :AnalyseSeqs),
    ExecutableProduct("b2ct", :b2ct),
    ExecutableProduct("ct2db", :ct2db),
    ExecutableProduct("Kinfold", :Kinfold),
    ExecutableProduct("kinwalker", :Kinfold),
    ExecutableProduct("popt", :popt),
    ExecutableProduct("RNA2Dfold", :RNA2Dfold),
    ExecutableProduct("RNAaliduplex", :RNAaliduplex),
    ExecutableProduct("RNAalifold", :RNAalifold),
    ExecutableProduct("RNAcofold", :RNAcofold),
    ExecutableProduct("RNAdistance", :RNAdistance),
    ExecutableProduct("RNAdos", :RNAdos),
    ExecutableProduct("RNAduplex", :RNAduplex),
    ExecutableProduct("RNAeval", :RNAeval),
    ExecutableProduct("RNAfold", :RNAfold),
    ExecutableProduct("RNAforester", :RNAforester),
    ExecutableProduct("RNAheat", :RNAheat),
    ExecutableProduct("RNAinverse", :RNAinverse),
    ExecutableProduct("RNALalifold", :RNALalifold),
    ExecutableProduct("RNALfold", :RNALfold),
    ExecutableProduct("RNAlocmin", :RNAlocmin),
    ExecutableProduct("RNAmultifold", :RNAmultifold),
    ExecutableProduct("RNApaln", :RNApaln),
    ExecutableProduct("RNAparconv", :RNAparconv),
    ExecutableProduct("RNApdist", :RNApdist),
    ExecutableProduct("RNAPKplex", :RNAPKplex),
    ExecutableProduct("RNAplex", :RNAplex),
    ExecutableProduct("RNAplfold", :RNAplfold),
    ExecutableProduct("RNAplot", :RNAplot),
    ExecutableProduct("RNApvmin", :RNApvmin),
    ExecutableProduct("RNAsnoop", :RNAsnoop),
    ExecutableProduct("RNAsubopt", :RNAsubopt),
    ExecutableProduct("RNAup", :RNAup),
    LibraryProduct("libRNA", :libRNA),
]

# Dependencies that must be installed before this package can be built
dependencies = [
    Dependency(PackageSpec(name="MPFR_jll", uuid="3a97d323-0669-5f0c-9066-3539efd106a3"))
    Dependency(PackageSpec(name="CompilerSupportLibraries_jll", uuid="e66e0078-7015-5450-92f7-15fbd957f2ae"))
    Dependency(PackageSpec(name="GSL_jll", uuid="1b77fbbe-d8ee-58f0-85f9-836ddc23a7a4"))
]

# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies;
               julia_compat="1.6", preferred_gcc_version = v"7")

max_stars_repo_name: staticfloat/BinaryBuilderRepos

max_issues_repo_name: staticfloat/BinaryBuilderRepos

max_forks_repo_name: staticfloat/BinaryBuilderRepos


text:
using QuadGK

function principalValueIntegral(f)
    g(x) = if x==0 0. else (f(x) - f(-x) + f(1/x) - f(-1/x))/x end
    return quadgk(g,0,1)[1]
end

function cauchyIntegral(f)
    return im*pi*f(0)+principalValueIntegral(f)
end

function infiniteIntegral(f)
    g(x) = f(tan(x))*(sec(x)^2)
    return quadgk(g,-pi/2,pi/2)[1]
end

export principalValueIntegral, cauchyIntegral, infiniteIntegral


text:
#Written By Johnathan Bizzano
export RegressableSummation, RegressableSummationTrainer

using LinearAlgebra
using ...Functions

const TermsArray{T, N} = Array{ProductFunction{T, N}, 1}

struct RegressableSummation{T, N}  <: AbstractMathFun{T, N}
    sum_function::AbstractMathFun{T, N}
    coefficients::Array{T, 1}

    #For Training
    terms::SumFunction{T, N}

    RegressableSummation{T, N}(sum_function::AbstractMathFun{T, N}, coefficients::Array{T, 1}, terms::SumFunction{T, N}) where {T, N} = new{T, N}(sum_function, coefficients, terms)

    RegressableSummation{T, N}(term_functions::TermsArray{T, N}) where {T, N} = RegressableSummation{T, N}(term_functions, zeros(T, length(term_functions)))

    function RegressableSummation{T, N}(term_functions::TermsArray{T, N}, coefficients::Array{T}) where {T, N}
        terms = Array{AbstractMathFun, 1}(undef, length(term_functions))
        #Put a constant coefficient term in front of all products
        for i in 1:length(term_functions)
            constant = ConstFunction{T}(1.0, force_emit = false)
            insert!(term_functions[i], 1, constant)
            terms[i] = term_functions[i]
        end

        #Create a summation function
        sum_function = SumFunction{T, N}(terms)

        #Compile the summation function to machine code and return math function
        new{T, N}(emit(sum_function, :RegressableSummationGeneration, EmitConstants = false), coefficients, sum_function)
    end

    (f::RegressableSummation{T, N})(call::MFCall) where {T, N} = call(f.sum_function(call.args, f.coefficients))

    Base.length(x::RegressableSummation) = Base.length(x.terms)

    function Base.string(x::RegressableSummation{T, N}) where {T, N}
        return functionheader(x, N) * Functions.string(x.terms, false) * "\nCoefficients:" * string(x.coefficients)
    end
end

Functions.simplify(x::RegressableSummation{T, N}) where {T, N} = RegressableSummation{T, N}(x.sum_function, x.coefficients, simplify(x.terms, false))

struct RegressableSummationTrainer{T, N} <: AbstractTrainer{T, N}
    f::RegressableSummation{T, N}
    trainableSVDMatrix::Matrix{T}
    trainableOutputs::Array{T}
    precision::UInt8

    function RegressableSummationTrainer{T, N}(f::RegressableSummation{T, N}; precision=10) where {T, N}
        RegressableSummationTrainer{T, N}(f, zeros(T, length(f), length(f)), zeros(T, length(f)), precision=precision)
    end

    function RegressableSummationTrainer{T, N}(f::RegressableSummation{T, N}, trainableSVDMatrix::Matrix{T}, trainableOutputs::AbstractArray{T}; precision=10) where {T, N}
        new{T, N}(f, trainableSVDMatrix, trainableOutputs, precision)
    end

    Base.sizeof(x::RegressableSummationTrainer{T, N}) where {T, N} = sizeof(RegressableSummationTrainer{T, N}) + sizeof(x.f) + sizeof(x.trainableOutputs) + sizeof(x.trainableSVDMatrix)

    Base.string(x::RegressableSummationTrainer) = string(x.f) * "\nMemory Size:" * string(sizeof(x)) * " Bytes\n"
end

function Functions.train!(f::RegressableSummationTrainer{T, N}, data::AbstractDataSet{T, N}; Data_Type::Type=T) where {T, N}
    length(data) == 0 && return

    for row in 1:length(f.f)
        for col in 1:length(f.f)

            #Only calculate upper trianglar matrix and transpose
            col >= row || continue
            product_sum = f.trainableSVDMatrix[row, col]
            row == 1 && (output_product_sum = f.trainableOutputs[col])

            #Calculate the element product of every function upon every product combination of terms
            for data_entry_index in 1:length(data)
                inputs = data[data_entry_index].inputs
                product::T = f.f.terms[row](inputs, Data_Type = Data_Type) * f.f.terms[col](inputs, Data_Type = Data_Type)
                product_sum += product
                row == 1 && (output_product_sum += data[data_entry_index].outputs[1] * product)
            end

            #Singular Transpose
            f.trainableSVDMatrix[row, col] = product_sum
            f.trainableSVDMatrix[col, row] = product_sum

            row == 1 && (f.trainableOutputs[col] = output_product_sum)
        end
    end

    #Perform Min Normalization to solve AX+B=Y for A
    #Copy the results to the function coefficients
    copy!(f.f.coefficients, round.(LAPACK.gesv!(copy(f.trainableSVDMatrix), copy(f.trainableOutputs))[1], digits=f.precision))
end


text:
# auxiliary simulation functions
#
@doc """
Simulates a stochastic process {yₜ} following an ARMA(1,1) with parameters φ and Θ for t = 1, ..., T periods.

```math
  y_t = \\mu_0 + \\mu_1 + \\phi*y_{t-1} + \\epsilon_t + \\theta*\\epsilon_{t-1}, \\quad \\epsilon_t \\sim \\mathbf{N}(0, \\sigma^2)
```

Required Input Parameters
----------------------------------
none

Optional Input Parameters
----------------------------------
`mu::Float64`: AR(1) process constant term. (default=0.0)

`lin_trend::Float64`: AR(1) process linear time trend. (default=0.0)

`ar::Float64`: AR(1) autorregressive parameter. (default=0.5)

`ma::Float64`: MA(1) autorregressive parameter. (default=0.5)

`T::Int64`: Length of simulated time series. (default=100)

`y_0::Float64`: Initial value of the series. (default=0.0)

`stderr::Float64` : Normally distributed innovation standard error. (default=1.0)

Output
----------------------------------
`y::Vector{Float64}`: Simulated ARMA(1,1) time series of length T.

""" ->
function simul_arma(;mu::Float64 = 0., lin_trend::Float64 = 0., ar::Float64 = .5, ma::Float64 = .5, T::Integer = 100, y_0::Float64 = 0.0, stderr::Float64 = 1.0)
  #y_t = μ + ϕy_t-1 + u_t/ u_t = ɛ_t + Θɛ_t-1
  y = zeros(T); ɛ = rand(Normal(0.0,stderr),T); u = zeros(T);
  for t in 2:T
    u[t, :] = ɛ[t, :] + ma*ɛ[t-1, :] #MA
    y[t, :] = mu + lin_trend*t + ar*y[t-1, :] + u[t, :] #AR
  end
  return y
end
#
#
function simul_llm(; T=100::Int64, x0=0.0::Float64)
  # x_t = μ_t + ϵ_t, ϵ_t∼N(0, σ2_ϵ)
  # μ_t = μ_{t-1} + η_t, ϵ_t∼N(0, σ2_η)
  #state and signal initalized at zero
  x = zeros(T)
  μ = zeros(T)
  σ2_ϵ = 1.0;
  σ2_η = 1.0;
  ϵ = rand(Normal(0.0, σ2_ϵ), T)
  η = rand(Normal(0.0, σ2_η), T)
  x[1] = x0
  for t in 2:T
    μ[t] = μ[t-1] + η[t]
    x[t] = μ[t] + ϵ[t]
  end
  return x
end


text:
using TimeSeries

function generate_header_ta_func_with_timearray()
    s_code = generate_header()
    s_code *= "\n"
    s_code *= "\n"
    s_code *= "using TimeSeries"
    s_code
end

function generate_ta_func_with_timearray(d::OrderedDict{Symbol,Any}, symb_func::Symbol)

    d_var_symb = Dict{String,Symbol}(
        "inReal" => :price,
        "Open" => _OPEN,
        "High" => _HIGH,
        "Low" => _LOW,
        "Close" => _CLOSE,
        "Volume" => _VOLUME,
    )

    function replace_var_to_symbol(s)
        get(d_var_symb, s, s)
    end

    func_info = d[symb_func]

    s_doc_RequiredInputArguments = ""
    s_doc_OptionalInputArguments = ""
    s_doc_OutputArguments = ""

    params_lv1_with_values = ""

    params_lv1 = String[]
    params_lv2 = String[]
    params_RequiredInputArguments = String[]
    params_OptionalInputArguments = String[]
    params_OutputArguments = String[]

    lst_args_name = AbstractString[]
    for arg = func_info["RequiredInputArguments"]
        push!(lst_args_name, arg["Name"])
    end
    N = length(lst_args_name)
    arg_typ = "TimeSeries.TimeArray"
    ret_typ = "TimeSeries.TimeArray"
    d_colnames = OrderedDict()
    if lst_args_name==["inReal0", "inReal1"]
        Nta_input = 2
        args = Symbol[:ta, :ta2]
        d_colnames = OrderedDict(
            :ta=>[:price],
            :ta2=>[:price]
        )
    else
        Nta_input = 1
        args = Symbol[:ta]
        for arg = func_info["RequiredInputArguments"]
            colname = string(replace_var_to_symbol(arg["Name"]))
            push!(params_lv1, colname)
            push!(params_RequiredInputArguments, colname)
            #s_doc_RequiredInputArguments *= "\n            - $colname"
        end
        d_colnames[:ta] = params_lv1
    end

    params_lv2_with_types = ""

    index = 1
    for (arg, params) in d_colnames
        s_doc_RequiredInputArguments *= "\n        - $arg::$arg_typ with:"
        if index != 1
            params_lv1_with_values *= ", "
            params_lv2_with_types *= ", "
        end

        for (j, colname) in enumerate(params)
            if j != 1
                params_lv1_with_values *= ", "
            end
            if string(colname) == "price"
                params_lv1_with_values *= "$arg[$colname].values"
            else
                params_lv1_with_values *= "$arg[\"$colname\"].values"
            end
            s_doc_RequiredInputArguments *= "\n            - $colname"
        end

        params_lv2_with_types *=  "$arg::$arg_typ"
        index += 1
    end

    if length(params_lv1_with_values) > 1
        params_lv1_with_values *= ", "
    end

    for arg = func_info["OptionalInputArguments"]
        varname = fix_varname(arg["Name"])
        vartyp = d_typ_to_jl[arg["Type"]]
        def_val = arg["DefaultValue"]
        push!(params_lv1, varname)
        push!(params_OptionalInputArguments, varname)
        s_doc_OptionalInputArguments *= "\n        - $varname=$vartyp($def_val)"
    end

    s_doc_OutputArguments *= "\n        - $ret_typ with:"
    for arg = func_info["OutputArguments"]
        varname = cleanup_prefix(arg["Name"])
        push!(params_OutputArguments, varname)
        s_doc_OutputArguments *= "\n            - $varname"
    end

    #params_lv1 = join(params_lv1, ", ")

    for (index, arg) in enumerate(func_info["RequiredInputArguments"])
        #if index != 1
        #    params_lv2_with_types *= ", "
        #end
        varname = string(replace_var_to_symbol(arg["Name"]))
        vartyp = d_typ_to_jl[arg["Type"]]
    end
    for (index, arg) in enumerate(func_info["OptionalInputArguments"])
        if index != 1
            params_lv2_with_types *= ", "
            params_lv1_with_values *= ", "
        else
            params_lv2_with_types *= "; "
        end
        varname = fix_varname(arg["Name"])
        vartyp = d_typ_to_jl[arg["Type"]]
        def_val = arg["DefaultValue"]
        params_lv2_with_types *= "$varname=$vartyp($def_val)"
        params_lv1_with_values *= "$varname=$varname"
    end

    funcname = string(symb_func)
    first_req_input_array = string(replace_var_to_symbol(func_info["RequiredInputArguments"][1]["Name"]))

    s = "

\"\"\"
    $funcname($params_lv2_with_types, price=:$(_PRICE))

$(func_info["ShortDescription"]) ($(func_info["CamelCaseName"]))

    $(func_info["GroupId"])

    Level: 2 - DataFrame

Arguments:

    RequiredInputArguments:$(s_doc_RequiredInputArguments)

    OptionalInputArguments:$(s_doc_OptionalInputArguments)

Returns:$(s_doc_OutputArguments)

\"\"\"
function $funcname($params_lv2_with_types, price=:$(_PRICE))
    price = string(price)
    result = $funcname($params_lv1_with_values)
    dt = ta.timestamp
    out = TimeArray(dt, result, $params_OutputArguments)
    out
end
"

s

end


text:
@testset "AbstractLayeredArray" begin
    x = MyType([1,2,3])
    @test (@inferred layerof(x))::Int == 1
    @test (@inferred eltype(x)) == Int
    @test (@inferred fill!(x, 0))::MyType{Int} == [0,0,0]
    @test (@inferred collect(x))::Vector{Int} == [0,0,0]
    @test (@inferred Array(x))::Vector{Int} == [0,0,0]
    y = [1,2,3]
    @test (@inferred broadcast!(identity, y, x))::Vector{Int} == [0,0,0]
end


text:
using Flux, Flux.Tracker, CuArrays, Test
using Flux.Tracker: TrackedArray, data

@testset "CUDNN BatchNorm" begin
    @testset "4D Input" begin
        x = TrackedArray(Float64.(collect(reshape(1:12, 2, 2, 3, 1))))
        m = BatchNorm(3)
        cx = gpu(x)
        cm = gpu(m)

        y = m(x)
        cy = cm(cx)

        @test cy isa TrackedArray{Float32,4,CuArray{Float32,4}}

        @test cpu(data(cy)) ≈ data(y)

        g = rand(size(y)...)
        Flux.back!(y, g)
        Flux.back!(cy, gpu(g))

        @test m.γ.grad ≈ cpu(cm.γ.grad)
        @test m.β.grad ≈ cpu(cm.β.grad)
        @test x.grad ≈ cpu(x.grad)
    end

    @testset "2D Input" begin
        x = TrackedArray(Float64.(collect(reshape(1:12, 3, 4))))
        m = BatchNorm(3)
        cx = gpu(x)
        cm = gpu(m)

        y = m(x)
        cy = cm(cx)

        @test cy isa TrackedArray{Float32,2,CuArray{Float32,2}}

        @test cpu(data(cy)) ≈ data(y)

        g = rand(size(y)...)
        Flux.back!(y, g)
        Flux.back!(cy, gpu(g))

        @test m.γ.grad ≈ cpu(cm.γ.grad)
        @test m.β.grad ≈ cpu(cm.β.grad)
        @test x.grad ≈ cpu(x.grad)
    end
end