text:
using Statistics: mean
import Zygote
# using StatsBase: mean, weights
# import StatsBase
# choose trace, and game pos from uniform distribution
sample_trace(memory) = rand(memory) #!
# sample_trace(memory) = memory[1]
sample_position(trace) = rand(1:length(trace)) #! HERE
# sample_position(trace) = 2

# TODO comments and documentation
#! wp - is white playing
# TODO debug indexes (sᵏ⁻¹, aᵏ) are index 1
function make_target(gspec, trace, state_idx, hyper)
  Ksteps = hyper.num_unroll_steps
  td_steps = hyper.td_steps
  γ = hyper.discount

  observation = trace.states[state_idx]
  x = GI.vectorize_state(gspec, observation) # convert observation to h_nn input
  a_mask = GI.actions_mask(GI.init(gspec, observation))
  wp = GI.white_playing(GI.init(gspec, observation))
  # TODO change into staticvector or smth fast - sizehint!
  target_values   = Float64[]         ; sizehint!(target_values, Ksteps+1)
  target_rewards  = Float64[]         ; sizehint!(target_rewards, Ksteps+1)
  target_policies = Vector{Float64}[] ; sizehint!(target_policies, Ksteps+1)
  #? should it be 2 dim array for easy f32 conversion
  #//target_policies = Array{Float64}(undef, 9, 0)
  actions         = Int[]

  #? change to map
  for idx in state_idx:state_idx+Ksteps
    # The value target is the discounted root value of the search tree td_steps into the
    # future, plus the discounted sum of all rewards until then.
    bootstrap_idx = idx + td_steps
    if bootstrap_idx <= length(trace)
      value = trace.rootvalues[bootstrap_idx] * γ^td_steps
    else
      bootstrap_idx = length(trace)
      value = 0.
    end

    for (i, reward) in enumerate(trace.rewards[idx:bootstrap_idx])
      value += reward * γ^(i-1) # numerating from 1
    end

    #= google implementation use masks for every target, ex:
      reward_mask = 1.0 if current_index > state_index else 0.0 =#
    if idx <= length(trace)
      reward = trace.rewards[idx]
      if GI.two_players(gspec)
        if !wp # rewards are stored in a view of white
          value = -value
          reward = -reward #? wp ? reward : -reward # no flipping in future, but when state is flipped it makes some sense, remember to change GI.white_reward function then too
        end
        wp = !wp
      end
      push!(target_values, value)
      push!(target_rewards, reward)
      # create full length policy vector
      a_m = GI.actions_mask(GI.init(gspec, trace.states[idx]))
      p = zeros(size(a_m))
      p[a_m] = trace.policies[idx]
      push!(target_policies, p)
      #target_policies = [target_policies p]
      # a = trace.actions[idx]
      push!(actions, trace.actions[idx])
    else
      push!(target_values, 0)
      push!(target_rewards, 0)
      all_actions = GI.actions(gspec)
      uniform_policy = fill(1/length(all_actions), length(all_actions))
      push!(target_policies, uniform_policy)
      #target_policies = [target_policies uniform_policy]
      push!(actions, rand(all_actions))
    end
  end
  if hyper.model_type == :mlp
    as = encode_a.(fill(gspec), actions; batchdim=2)
    as = Flux.batch(as)
  elseif hyper.model_type == :resnet
    as = GI.encode_action.(fill(gspec), actions) #TODO add support for simplemlp
    as = cat(as..., dims=3)
  else
    @error "Unsupported model_type. (should be :mlp or :resnet)"
  end

  return (; x, a_mask, as, vs=target_values, rs=target_rewards, ps=reduce(hcat,target_policies))
end

function sample_batch(gspec, memory, hyper)
  traces = [sample_trace(memory) for _ in 1:hyper.loss_computation_batch_size]
  trace_pos_idxs = [sample_position(t) for t in traces] #! ERROR; DO NOT USE GENERATORS WITH RAND()
  samples = (make_target(gspec, t, i, hyper) for (t,i) in zip(traces, trace_pos_idxs))

  X       = Flux.batch(smpl.x       for smpl in samples)
  A_mask  = Flux.batch(smpl.a_mask  for smpl in samples)
  As      = Flux.batch(smpl.as      for smpl in samples)
  Ps      = Flux.batch(smpl.ps      for smpl in samples)
  Vs      = Flux.batch(smpl.vs      for smpl in samples)
  Rs      = Flux.batch(smpl.rs      for smpl in samples)
  f32(arr) = convert(AbstractArray{Float32}, arr)
  # f32(arr) = convert(Float32, arr)
  return map(f32, (; X, A_mask, As, Ps, Vs, Rs))
end

lossₚ(p̂, p)::Float32 = Flux.Losses.crossentropy(p̂, p) #TODO move to hyper
lossᵥ(v̂, v)::Float32 = Flux.Losses.mse(v̂, v)
# lossᵣ(r̂, r)::Float32 = 0f0
lossᵣ(r̂, r)::Float32 = Flux.Losses.mse(r̂, r)

# lossᵥ(v̂, v)::Float32 = Flux.Losses.crossentropy(v̂, v)
# lossᵣ(r̂, r)::Float32 = Flux.Losses.crossentropy(r̂, r)

# TODO add assertions about sizes
function losses(nns, hyper, (X, A_mask, As, Ps, Vs, Rs))
  prediction, dynamics, representation = nns.f, nns.g, nns.h
  creg::Float32 = hyper.l2_regularization
  Ksteps = hyper.num_unroll_steps
  dimₐ = hyper.model_type==:mlp ? 2 : 3

  # initial step, from the real observation
  Hiddenstate = forward(representation, X)
  P̂⁰, V̂⁰ = forward(prediction, Hiddenstate)
  P̂⁰ = normalize_p(P̂⁰, A_mask)
  # R̂⁰ = zero(V̂⁰)
  # batchdim = ndims(Hiddenstate)

  scale_initial = iszero(Ksteps) ? 1f0 : 0.5f0
  Lp = scale_initial * lossₚ(P̂⁰, Ps[:, 1, :]) # scale=1
  Lv = scale_initial * lossᵥ(V̂⁰, Vs[1:1, :])
  Lr = zero(Lv) # starts at next step (see MuZero paper appendix)

  scale_recurrent = iszero(Ksteps) ? nothing : 0.5f0 / Ksteps #? instead of constant scale, maybe 2^(-i+1)
  # recurrent inference
  for k in 1:Ksteps
    # targets are stored as follows: [A⁰¹ A¹² ...] [P⁰ P¹ ...] [V⁰ V¹ ...] but [R¹ R² ...]
    # A = As[k, :]
    # A = As[:,:,k:k,:]
    A = selectdim(As, dimₐ, k)
    S_A = cat(Hiddenstate,A, dims=ndims(Hiddenstate)-1)
    # R̂, Hiddenstate = forward(dynamics, Hiddenstate, A) # obtain next hiddenstate
    R̂, Hiddenstate = forward(dynamics, S_A) # obtain next hiddenstate
    P̂, V̂ = forward(prediction, Hiddenstate) #? should flip V based on players
    # scale loss so that the overall weighting of the recurrent_inference (g,f nns)
    # is equal to that of the initial_inference (h,f nns)
    Lp += scale_recurrent * lossₚ(P̂, Ps[:, k+1, :]) #? @view
    Lv += scale_recurrent * lossᵥ(V̂, Vs[k+1:k+1, :])
    Lr += scale_recurrent * lossᵣ(R̂, Rs[k:k, :])
  end
  Lreg = iszero(creg) ? zero(Lv) : creg * sum(sum(w.^2) for w in regularized_params(nns))
  L = Lp + Lv + Lr + Lreg # + Lr
  # L = Lp + Lreg # + Lr
  # Zygote.@ignore @info "Loss" loss_total=L loss_policy=Lp loss_value=Lv loss_reward=Lr loss_reg_params=Lreg relative_entropy=Lp-Flux.Losses.crossentropy(Ps, Ps) #? check if compute means inside logger is avaliable
  return (L, Lp, Lv, Lr, Lreg)
end

# #TODO replace Zygote.withgradient() - new version
# function lossgrads(f, args...)
#   val, back = Zygote.pullback(f, args...)
#   grad = back(Zygote.sensitivity(val))
#   return val, grad
# end

# function train!(nns, opt, loss, data; cb=()->())
function μtrain!(nns, loss, data, opt)
  ps = Flux.params(nns)
  losses = Float32[]
  @progress "learning step (checkpoint)" for (i, d) in enumerate(data)
  # for (i, d) in enumerate(data)
    l, gs = Zygote.withgradient(ps) do
      loss(d...)
    end
    push!(losses, l)
    Flux.update!(opt, ps, gs)
    # @info "debug" η=opt.optim.eta
  end
  @info "Loss" mean_loss_total = mean(losses)
end

struct MuTrainer
  gspec
  nns # MuNetwork
  memory #? don't know if memory pointer in trainter is good idea
  hyper
  opt
  function MuTrainer(gspec, nns, memory, hyper, opt)
    return new(gspec, nns|>hyper.device|>Flux.trainmode!, memory, hyper, opt)
  end
end

function update_weights!(tr::MuTrainer, n)
  L(batch...) = losses(tr.nns, tr.hyper, batch)[1]
  #? move computing samples into Trainer constructor
  samples = (sample_batch(tr.gspec, tr.memory, tr.hyper)|>tr.hyper.device for _ in 1:n)

  μtrain!(tr.nns, L, samples, tr.opt)
  #? GC
end


text:
function __init__()
    @require DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" begin
        include("volume_df.jl")
    end

    @require StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd" begin
        include("plotting.jl")
    end
end

ext: jl

max_stars_repo_name: itsdfish/ParameterSpacePartitions

max_forks_repo_name: itsdfish/ParameterSpacePartitions


text:
# Use baremodule to shave off a few KB from the serialized `.ji` file
baremodule Gdbm_jll
using Base
using Base: UUID
import JLLWrappers

JLLWrappers.@generate_main_file_header("Gdbm")
JLLWrappers.@generate_main_file("Gdbm", UUID("54ca2031-c8dd-5cab-9ed4-295edde1660f"))
end  # module Gdbm_jll


text:
__precompile__()

module ChainDiag

using Markdown
using LinearAlgebra

export SpinChainSolver, BosonChainSolver, solve

abstract type Solver end

include("util.jl")
include("spin.jl")
include("boson.jl")
include("solve.jl")

end # module ChainDiag


text:
# Histogram (Bar) plots
# Vertical bars
function PlotBars(label_id, x::AbstractArray{T1}, y::AbstractArray{T2},
                  args...) where {T1<:Real,T2<:Real}
    return PlotBars(label_id, promote(x, y)..., args...)
end

function PlotBars(values::AbstractArray{T}; count::Integer=length(values),
                  label_id::String="", width=0.67, shift=0.0, offset::Integer=0,
                  stride::Integer=1) where {T<:ImPlotData}
    return PlotBars(label_id, values, count, width, shift, offset, stride * sizeof(T))
end

function PlotBars(x::AbstractArray{T}, y::AbstractArray{T};
                  count::Integer=min(length(x), length(y)), label_id::String="", width=0.67,
                  offset::Integer=0, stride::Integer=1) where {T<:ImPlotData}
    return PlotBars(label_id, x, y, count, width, offset, stride * sizeof(T))
end

function PlotBars(x::AbstractArray{T1}, y::AbstractArray{T2};
                  kwargs...) where {T1<:Real,T2<:Real}
    return PlotBars(promote(x, y)..., kwargs...)
end

# Horizontal bars
function PlotBarsH(label_id, x::AbstractArray{T1}, y::AbstractArray{T2},
                   args...) where {T1<:Real,T2<:Real}
    return PlotBarsH(label_id, promote(x, y)..., args...)
end

function PlotBarsH(values::AbstractArray{T}; count::Integer=length(values),
                   label_id::String="", width=0.67, shift=0.0, offset::Integer=0,
                   stride::Integer=1) where {T<:ImPlotData}
    return PlotBarsH(label_id, values, count, width, shift, offset, stride * sizeof(T))
end

function PlotBarsH(x::AbstractArray{T}, y::AbstractArray{T};
                   count::Integer=min(length(x), length(y)), label_id::String="",
                   width=0.67, offset::Integer=0, stride::Integer=1) where {T<:ImPlotData}
    return PlotBarsH(label_id, x, y, count, width, offset, stride * sizeof(T))
end

function PlotBarsH(x::AbstractArray{T1}, y::AbstractArray{T2};
                   kwargs...) where {T1<:Real,T2<:Real}
    return PlotBarsH(promote(x, y)..., kwargs...)
end


text:
###############################################################################
#
# The Stopping structure eases the implementation of algorithms and the
# stopping criterion.
#
# The following examples illustre the various possibilities offered by Stopping
#
###############################################################################

using Test, NLPModels, Stopping

printstyled("How to State ")
include("howtostate.jl")
printstyled("passed ✓ \n", color = :green)
printstyled("How to State for NLP ")
include("howtostate-nlp.jl")
printstyled("passed ✓ \n", color = :green)
printstyled("How to Stop ")
include("howtostop.jl")
printstyled("passed ✓ \n", color = :green)
printstyled("How to Stop II ")
include("howtostop-2.jl")
printstyled("passed ✓ \n", color = :green)
printstyled("How to Stop for NLP ")
include("howtostop-nlp.jl")
printstyled("passed ✓ \n", color = :green)


text:
module EntropicCone

using LinearAlgebra
using SparseArrays

import MathProgBase
using Polyhedra

import Base.setindex!, Base.*, Base.show, Base.getindex, Base.setdiff, Base.union, Base.issubset, Base.promote_rule, Base.in, Base.-, Base.copy, Base.intersect

include("entropy.jl")
include("setmanip.jl")
include("vector.jl")
include("famousnsi.jl")
include("cone.jl")
include("conelift.jl")
include("coneoperations.jl")
include("conelp.jl")
#include("lphierarchy.jl")
#include("doughertylists.jl")
#include("visualize.jl")

end # module


text:
using Dates, Formatting, Plots, ColorSchemes, WebIO, DataFrames, BenchmarkTools
plotly()
#using Makie

#include("load_covid19_data.jl")

states_of_interest = ["Virginia","North Carolina","West Virginia","Delaware", "Wisconsin", "Minnesota", "Idaho", "Tennessee", "Alabama", "New York", "New Jersey", "Massachusetts", "Texas","Florida","California","Michigan", "Ohio", "Washington", "Oregon", "Illinois", "Oklahoma", "Maryland", "District of Columbia", "Alaska", "Arizona","Georgia","South Carolina", "Mississippi", "Maine", "Pennsylvania", "Colorado", "New Hampshire", "Iowa", "Vermont","Hawaii", "Montana", "North Dakota", "South Dakota", "Arkansas", "Connecticut", "Indiana", "Kansas", "Kentucky", "Louisiana", "Missouri", "Nebraska", "Nevada", "New Mexico", "Utah", "Wyoming", "Rhode Island",  "Puerto Rico"]
#states_of_interest = ["Rhode Island",  "Puerto Rico"]
#states_of_interest = ["Puerto Rico",]

strnow = string(Dates.now())
strnow30 = strnow[1:4] * strnow[6:7] * strnow[9:10] * "T" * strnow[12:13] * strnow[15:16] * strnow[18:19]

# extracting county indices with land area and population
cind = findall((countyarea .> 0) .& (cpop .> 0));

reasonable_resolution() = (1440, 900)

tind = 1:length(covid19us[1].confirmed);
t = covid19us[1].time[tind];

#=
# plot a map of confirmed cases
#cval = cconfirmed[cind] ./ (countyarea[cind] .* cpop[cind]);
cval = cconfirmed[cind] ./ cpop[cind];
log10cval = log10.(cval);
#sval = countyarea[cind] .* cpop[cind];
sval = cpop[cind];
log10sval = log10.(sval);
dfconfirmed = DataFrame(LON = clon[cind], LAT = clat[cind], log10POPULATION = log10.(cpop[cind]), log10CONFIRMED = log10.(cconfirmed[cind] ./ cpop[cind]));
#Plotly.scattermapbox(dfconfirmed, lat="LAT", lon="LON", color="log10CONFIRMED", size="log10POPULATION", color_continuous_scale=ColorSchemes.matter.colors, mapbox_style="cart-positron");

scene = Makie.scatter(clon[cind],clat[cind], color = log10cval, markersize = log10sval/10, colormap = ColorSchemes.matter.colors, limits = FRect(-125, 25, 60, 27))
#text!(scene, "©Donglai Gong", textsize = 1, position = (-125, 26))
#cb = colorlegend!(scene, raw = true, camera=campixel!, width = (30,540))
axis = scene[Axis];
axis.names.axisnames = ("Longitude", "Latitude");
axis.names.title = (string(t[end])[1:10] * " Total Confirmed Cases per Capita (log)");
#scene_final = vbox(scene, cb)
Makie.save("/Volumes/GoogleDrive/My Drive/COVID19/" * "covid19_confirmed_map.png", scene)

# plot a map of change in confirmed cases
#cdval = dcconfirmed[cind] ./ (countyarea[cind] .* cpop[cind]);
cdval = dcconfirmed[cind] ./ cpop[cind];
bind = findall(cdval .< 0);
cdval[bind] .= 0;
log10cdval = log10.(cdval);
#sval = countyarea[cind] .* cpop[cind];
sval = cpop[cind];
log10sval = log10.(sval);

scene = Makie.scatter(clon[cind],clat[cind], color = log10cdval, markersize = log10sval/10, colormap = ColorSchemes.matter.colors, limits = FRect(-125, 25, 60, 27))
text!(scene, "©Donglai Gong", textsize = 1, position = (-125, 26))
axis = scene[Axis];
axis.names.axisnames = ("Longitude", "Latitude")
axis.names.title = string(t[end])[1:10] * " New Weekly Cases per Capita (log)"
Makie.save("/Volumes/GoogleDrive/My Drive/COVID19/" * "covid19_delta_confirmed_map.png", scene)

# plot a map of death cases
#cval = cconfirmed[cind] ./ (countyarea[cind] .* cpop[cind]);
cval = cdeath[cind] ./ cpop[cind];
log10cval = log10.(cval);
#sval = countyarea[cind] .* cpop[cind];
sval = cpop[cind];
log10sval = log10.(sval);

scene = Makie.scatter(clon[cind],clat[cind], color = log10cval, markersize = log10sval/10, colormap = ColorSchemes.matter.colors, limits = FRect(-125, 25, 60, 27))
text!(scene, "©Donglai Gong", textsize = 1, position = (-125, 26))
axis = scene[Axis];
axis.names.axisnames = ("Longitude", "Latitude");
axis.names.title = (string(t[end])[1:10] * " Total Death per Capita (log)");
Makie.save("/Volumes/GoogleDrive/My Drive/COVID19/" * "covid19_dealth_map.png", scene)

# plot a map of change in death cases
#cdval = dcconfirmed[cind] ./ (countyarea[cind] .* cpop[cind]);
cdval = dcdeath[cind] ./ cpop[cind];
bind = findall(cdval .< 0);
cdval[bind] .= 0;
log10cdval = log10.(cdval);
#sval = countyarea[cind] .* cpop[cind];
sval = cpop[cind];
log10sval = log10.(sval);
log10svalscl = (log10sval .- minimum(log10sval)) ./ (maximum(log10sval) - minimum(log10sval))

scene = Makie.scatter(clon[cind],clat[cind], color = log10cdval, markersize = log10sval/10, colormap = ColorSchemes.matter.colors, limits = FRect(-125, 25, 60, 27))
text!(scene, "©Donglai Gong", textsize = 1, position = (-125, 26))
axis = scene[Axis];
axis.names.axisnames = ("Longitude", "Latitude")
axis.names.title = string(t[end])[1:10] * " New Weekly Deaths per Capita (log)"
Makie.save("/Volumes/GoogleDrive/My Drive/COVID19/" * "covid19_delta_dealth_map.png", scene)
=#

#Threads.@threads
for j = 1:length(states_of_interest)
#j = 1
        #display(Threads.threadid())

    display(string(j) * " " * states_of_interest[j])
    ## calculate per state and total confirmed for US
    local tind = 1:length(covid19us[1].confirmed);
    local t = covid19us[1].time[tind];
    local totalconfirmed = zeros(length(t));
    local stateconfirmed = Array{Any}(undef, length(ustate));
    local dstateconfirmed = Array{Any}(undef, length(ustate));
    local totaldeath = zeros(length(t));
    local statedeath = Array{Any}(undef, length(ustate));
    local dstatedeath = Array{Any}(undef, length(ustate));

    #tind = 1:length(covid19us[1].confirmed);
    #t = covid19us[1].time[tind];
    #totalconfirmed = zeros(length(t));
    #stateconfirmed = Array{Any}(undef, length(ustate));
    #dstateconfirmed = Array{Any}(undef, length(ustate));
    #totaldeath = zeros(length(t));
    #statedeath = Array{Any}(undef, length(ustate));
    #dstatedeath = Array{Any}(undef, length(ustate));

    for si = 1:length(ustate)
        #display(ustate[si])
        ind = findall((country .== "US") .& (state .== ustate[si]));

        #confirmed = Array{Any}(undef,length(ind));
        confirmed = [Float64.(covid19us[ind[i]].confirmed) for i in 1:length(ind)];
        death = [Float64.(covid19us[ind[i]].death) for i in 1:length(ind)];

        stateconfirmed[si] = Float64.(deepcopy(confirmed[1]));
        statedeath[si] = Float64.(deepcopy(death[1]));

        for i = 2:length(confirmed)
            stateconfirmed[si] .= stateconfirmed[si] .+ confirmed[i];
        end
        totalconfirmed .= totalconfirmed .+ stateconfirmed[si];

        for i = 2:length(death)
            statedeath[si] .= statedeath[si] .+ death[i];
        end
        totaldeath .= totaldeath .+ statedeath[si];
        #display(totalconfirmed)
    end

    ## calculate the daily case count for the US and states
    local dtotalconfirmed = totalconfirmed[2:end] .- totalconfirmed[1:end-1];
    dtotalconfirmed = totalconfirmed[2:end] .- totalconfirmed[1:end-1];
    for  si = 1:length(stateconfirmed)
        dstateconfirmed[si] = stateconfirmed[si][2:end] - stateconfirmed[si][1:end-1];
    end

    ## calculate the daily case count for the US and states
    local dtotaldeath = totaldeath[2:end] .- totaldeath[1:end-1];
    dtotaldeath = totaldeath[2:end] .- totaldeath[1:end-1];
    for  si = 1:length(statedeath)
        dstatedeath[si] = statedeath[si][2:end] - statedeath[si][1:end-1];
    end

    ## turning 0 to NaN for total counts, this will allow for the use of log10 in y-axis for Plots.jl
    local ind0 = findall(totalconfirmed .== 0.0);
    totalconfirmed[ind0] .= NaN
    local dind0 = findall(dtotalconfirmed .== 0.0);
    #dtotalconfirmed[dind0] .= NaN

    ind0 = findall(totaldeath .== 0.0);
    totaldeath[ind0] .= NaN
    dind0 = findall(dtotaldeath .== 0.0);
    #dtotaldeath[dind0] .= NaN

    local state_of_interest = states_of_interest[j];

    ## calculate per county case counts for specific state
    local ind = findall(state .== state_of_interest);
    #ind = findall((state .== state_of_interest) .& (county .!= "Unassigned"));
    local population = [Float64.(covid19us[ind[i]].population) for i in 1:length(ind)];

    local countyconfirmed = [Float64.(covid19us[ind[i]].confirmed) for i in 1:length(ind)];
    local dcountyconfirmed = Array{Any}(undef, length(countyconfirmed));
    local dcountyconfirmedpc = Array{Any}(undef, length(countyconfirmed));

    local statetotalconfirmed = Float64.(deepcopy(countyconfirmed[1]));
    for ci = 2:length(countyconfirmed)
        statetotalconfirmed .= statetotalconfirmed .+ countyconfirmed[ci];
    end

    ## calculate the daily case count for specific state and the counties
    local dstatetotalconfirmed = Array{Any}(undef, length(statetotalconfirmed)-1);
    local dstatetotalconfirmed = statetotalconfirmed[2:end] - statetotalconfirmed[1:end-1];
    for ci = 1:length(countyconfirmed)
        dcountyconfirmed[ci] = countyconfirmed[ci][2:end] - countyconfirmed[ci][1:end-1];
        dcountyconfirmedpc[ci] = (countyconfirmed[ci][2:end] - countyconfirmed[ci][1:end-1]) ./ population[ci] .* 1.0e5;
        if population[ci] == 0.0
            dcountyconfirmedpc[ci][1] = 0.0;
        end
    end

    ## turning 0 to NaN for total counts, this will allow for the use of log10 in y-axis for Plots.jl
    ind0 = findall(statetotalconfirmed .== 0);
    statetotalconfirmed[ind0] .= NaN;
    dind0 = findall(dstatetotalconfirmed .== 0);
    #dstatetotalconfirmed[dind0] .= NaN;

    local countydeath = [Float64.(covid19us[ind[i]].death) for i in 1:length(ind)];
    local dcountydeath = Array{Any}(undef, length(countydeath));
    local dcountydeathpc = Array{Any}(undef, length(countydeath));

    local statetotaldeath = Float64.(deepcopy(countydeath[1]));
    for ci = 2:length(countydeath)
        statetotaldeath .= statetotaldeath .+ countydeath[ci];
    end

    ## calculate the daily case count for specific state and the counties
    local dstatetotaldeath = Array{Any}(undef, length(statetotaldeath)-1);
    local dstatetotaldeath = statetotaldeath[2:end] - statetotaldeath[1:end-1];
    for ci = 1:length(countydeath)
        dcountydeath[ci] = countydeath[ci][2:end] - countydeath[ci][1:end-1];
        dcountydeathpc[ci] = (countydeath[ci][2:end] - countydeath[ci][1:end-1]) ./ population[ci] .* 1.0e5;
        if population[ci] == 0.0
            dcountydeathpc[ci][1] = 0.0;
        end
    end

    ## turning 0 to NaN, this will allow for the use of log10 in y-axis for Plots.jl
    ind0 = findall(statetotaldeath .== 0);
    statetotaldeath[ind0] .= NaN;
    dind0 = findall(dstatetotaldeath .== 0);
    #dstatetotaldeath[dind0] .= NaN;

    tindstate = 1:length(covid19us[ind[1]].confirmed);
    tstate = covid19us[ind[1]].time[tindstate];

    #display(statetotaldeath)

    # Plot COVID19 data!
    #l8out = @layout([a; b; c; d; e])
    l8out = @layout([a b; c d; e f; g h; i j])
    #l8out = @layout [grid(5,2)]

    local totalconfirmed_strfmt = Formatting.format.(totalconfirmed[end], commas=true);
    local titlestr = "US - Confirmed COVID-19 Cases " * "as of " * string(t[end])[1:10] * ":  " * totalconfirmed_strfmt;
    local pCOVID19usa = Plots.plot(t, totalconfirmed, label="USA Total", yscale=:log10, ylim=(1,10^7.8), framestyle=:box, title = titlestr)
    for si = 1:length(ustate)
        confirmi = stateconfirmed[si];
        ind0 = findall(confirmi .== 0);
        confirmi[ind0] .= NaN;
        if length(ind0) != length(confirmi) # if everything is NaN, don't try to plot
            Plots.plot!(t, confirmi, label=ustate[si])
        end
    end
    #Plots.plot(pCOVID19usa, yscale=:log10, ylim=(1,10^7.6) ,framestyle=:box, title="US - Confirmed COVID-19 Cases " * "as of " * string(t[end])[1:10] * ":  " * totalconfirmed_strfmt)
    #Plots.plot(pCOVID19usa)

    local dtotalconfirmed_strfmt = Formatting.format.(dtotalconfirmed[end], commas=true);
    local titlestr = "US - Daily New COVID-19 Cases " * "on " * string(t[end])[1:10] * ":  " * dtotalconfirmed_strfmt;
    #dCOVID19usa = Plots.plot(t[2:end], dtotalconfirmed, m = (2, :auto), label="USA Daily Cases")
    local dCOVID19usa = Plots.plot(t[2:end], dtotalconfirmed, label="USA Daily Cases", framestyle=:box, title = titlestr)
    for si = 1:length(ustate)
        confirmi = dstateconfirmed[si];
        #ind0 = findall(confirmi .== 0);
        #confirmi[ind0] .= NaN;
        #Plots.plot!(t[2:end], confirmi, m = (1, :auto), label=ustate[si])
        Plots.plot!(t[2:end], confirmi, label=ustate[si])
    end
    #Plots.plot(dCOVID19usa, xrotation=20, size=(800,500), legend=:outertopright, framestyle=:box, title="US - Daily Confirmed COVID-19 Cases", line = (:dot, 2), marker = ([:hex :d], 2, 0.8, Plots.stroke(0, :gray)),  markerstrokewidth = 0)
    #Plots.plot(dCOVID19usa, framestyle=:box, title="US - Daily New COVID-19 Cases " * "on " * string(t[end])[1:10] * ":  " * dtotalconfirmed_strfmt, markershape = :circle, markersize = 1, markerstrokestyle = :dot,  markerstrokewidth = 0)
    #Plots.plot(dCOVID19usa)

    local statetotalconfirmed_strfmt = Formatting.format.(statetotalconfirmed[end], commas=true);
    local titlestr=state[ind[1]] * " - Confirmed COVID-19 Cases " * "as of " * string(t[end])[1:10] * ":  " * statetotalconfirmed_strfmt;
    local pCOVID19state = Plots.plot(t, statetotalconfirmed, label=state[ind[1]] * " Total", yscale=:log10, framestyle=:box, title = titlestr);
    for i = 1:length(ind)
        #display(i)
        confirmi = Float64.(deepcopy(covid19us[ind[i]].confirmed[tindstate]));
        ind0 = findall(confirmi .== 0.0);
        confirmi[ind0] .= NaN;
        if length(ind0) != length(confirmi) # if everything is NaN, don't try to plot
            Plots.plot!(covid19us[ind[i]].time[tind], confirmi, label=county[ind[i]])
        end
    end
    #Plots.plot(pCOVID19state)

    local dstatetotalconfirmed_strfmt = Formatting.format.(dstatetotalconfirmed[end], commas=true);
    local titlestr = state[ind[1]] * " - Daily New COVID-19 Cases " * "on " * string(t[end])[1:10] * ":  " * dstatetotalconfirmed_strfmt;
    local dCOVID19state = Plots.plot(tstate[2:end], dstatetotalconfirmed, label=state[ind[1]] * " Daily Cases", framestyle=:box, title = titlestr)
    for i = 1:length(ind)
        confirmi = dcountyconfirmed[i];
        #ind0 = findall(confirmi .== 0);
        #ind0 = isnan.(confirmi);
        #confirmi[ind0] .= NaN;
        Plots.plot!(tstate[2:end], confirmi, label=county[ind[i]])
    end
    #Plots.plot(dCOVID19state, framestyle=:box, title=state[ind[1]] * " - Daily New COVID-19 Cases " * "on " * string(t[end])[1:10] * ":  " * dstatetotalconfirmed_strfmt, marker = (2, :circle, 2),  markerstrokewidth = 0)
    #Plots.plot(dCOVID19state)

    local dstatetotalconfirmedpc_strfmt = Formatting.format.(dstatetotalconfirmed[end] / sum(population) * 1.0e5, commas=true, precision = 3);
    local titlestr=state[ind[1]] * " - Daily New COVID-19 Cases / 100k " * "on " * string(t[end])[1:10] * ":  " * dstatetotalconfirmedpc_strfmt;
    local dCOVID19statepc = Plots.plot(tstate[2:end], dstatetotalconfirmed / sum(population) * 1.0e5, label=state[ind[1]] * " Daily Cases", framestyle=:box, title = titlestr);
    for i = 1:length(ind)
        # 92, 125
        confirmi = dcountyconfirmedpc[i];
        #ind0 = findall(confirmi .== NaN);
        #ind0 = isnan.(confirmi);
        #confirmi[ind0] .= NaN;
        Plots.plot!(tstate[2:end], confirmi, label=county[ind[i]])
    end
    #Plots.plot(dCOVID19statepc, framestyle=:box, title=state[ind[1]] * " - Daily New COVID-19 Cases per 100k " * "on " * string(t[end])[1:10] * ":  " * dstatetotalconfirmedpc_strfmt, marker = (2, :circle, 2),  markerstrokewidth = 0)
    #Plots.plot(dCOVID19statepc)

    #for i = 1:length(ind)
    #    display(i)
    #    a = findall(isnan.(dcountyconfirmedpc[i]) .== 1)
    #    display(a)
    #end

    local totaldeath_strfmt = Formatting.format.(totaldeath[end], commas=true);
    local titlestr="US - COVID-19 Death " * "as of " * string(t[end])[1:10] * ":  " * totaldeath_strfmt;
    local pCOVID19usaD = Plots.plot(t, totaldeath, label="USA Total Deaths", yscale=:log10, ylim=(1,10^5.9), framestyle=:box, title = titlestr)
    for si = 1:length(ustate)
        deathi = statedeath[si];
        ind0 = findall(deathi .== 0.0);
        deathi[ind0] .= NaN;
        if length(ind0) != length(deathi) # if everything is NaN, don't try to plot
            Plots.plot!(t, deathi, label=ustate[si])
        end
    end
    #Plots.plot(pCOVID19usaD)

    local dtotaldeath_strfmt = Formatting.format.(dtotaldeath[end], commas=true);
    local titlestr = "US - Daily COVID-19 Deaths " * "on " * string(t[end])[1:10] * ":  " * dtotaldeath_strfmt;
    local dCOVID19usaD = Plots.plot(t[2:end], dtotaldeath, framestyle=:box, label="USA Daily Deaths", title = titlestr)
    for si = 1:length(ustate)
        deathi = dstatedeath[si];
        #ind0 = findall(deathi .== 0);
        #deathi[ind0] .= NaN;
        Plots.plot!(t[2:end], deathi, label=ustate[si])
    end
    #Plots.plot(dCOVID19usa, xrotation=20, size=(800,500), legend=:outertopright, framestyle=:box, title="US - Daily Confirmed COVID-19 Cases", line = (:dot, 2), marker = ([:hex :d], 2, 0.8, Plots.stroke(0, :gray)),  markerstrokewidth = 0)
    #Plots.plot(dCOVID19usaD, framestyle=:box, title="US - Daily COVID-19 Deaths " * "on " * string(t[end])[1:10] * ":  " * dtotaldeath_strfmt, marker = (2, :circle, 2),  markerstrokewidth = 0)
    #Plots.plot(dCOVID19usaD)

    local statetotaldeath_strfmt = Formatting.format.(statetotaldeath[end], commas=true);
    local titlestr = state[ind[1]] * " - COVID-19 Deaths " * "as of " * string(t[end])[1:10] * ":  " * statetotaldeath_strfmt;
    local pCOVID19stateD = Plots.plot(t, statetotaldeath, label=state[ind[1]] * " Total", yscale=:log10, framestyle=:box, title = titlestr)
    for i = 1:length(ind)
        deathi = Float64.(deepcopy(covid19us[ind[i]].death[tind]));
        ind0 = findall(deathi .== 0.0);
        deathi[ind0] .= NaN;
        if length(ind0) != length(deathi) # if everything is NaN, don't try to plot
            Plots.plot!(covid19us[ind[i]].time[tind], deathi, label=county[ind[i]])
        end
    end
    #Plots.plot(pCOVID19stateD, title=state[ind[1]] * " - COVID-19 Deaths " * "as of " * string(t[end])[1:10] * ":  " * statetotaldeath_strfmt)

    local dstatetotaldeath_strfmt = Formatting.format.(dstatetotaldeath[end], commas=true);
    local titlestr = state[ind[1]] * " - Daily COVID-19 Deaths " * "on " * string(t[end])[1:10] * ":  " * dstatetotaldeath_strfmt;
    local dCOVID19stateD = Plots.plot(tstate[2:end], dstatetotaldeath, label=state[ind[1]] * " Daily Death", framestyle=:box, title = titlestr)
    for i = 1:length(ind)
        deathi = dcountydeath[i];
        #ind0 = findall(deathi .== 0);
        #deathi[ind0] .= NaN;
        Plots.plot!(tstate[2:end], deathi, label=county[ind[i]])
    end
    #Plots.plot(dCOVID19stateD, framestyle=:box, title=state[ind[1]] * " - Daily COVID-19 Deaths " * "on " * string(t[end])[1:10] * ":  " * dstatetotaldeath_strfmt, marker = (2, :circle, 2),  markerstrokewidth = 0)
    #Plots.plot(dCOVID19stateD, title=state[ind[1]] * " - Daily COVID-19 Deaths " * "on " * string(t[end])[1:10] * ":  " * dstatetotaldeath_strfmt)

    local dstatetotaldeathpc_strfmt = Formatting.format.(dstatetotaldeath[end] / sum(population) * 1.0e5, commas=true, precision = 3);
    local titlestr = state[ind[1]] * " - Daily COVID-19 Deaths / 100k " * "on " * string(t[end])[1:10] * ":  " * dstatetotaldeathpc_strfmt;
    local dCOVID19statepcD = Plots.plot(tstate[2:end], dstatetotaldeath / sum(population) * 1.0e5, label=state[ind[1]] * " Daily Death", framestyle=:box, title = titlestr)
    for i = 1:length(ind)
        deathi = dcountydeathpc[i];
        #ind0 = findall(deathi .== 0);
        #deathi[ind0] .= NaN;
        #display([i length(deathi)])
        Plots.plot!(tstate[2:end], deathi, label=county[ind[i]])
    end
    #Plots.plot(dCOVID19statepcD, framestyle=:box, title=state[ind[1]] * " - Daily COVID-19 Deaths per 100k " * "on " * string(t[end])[1:10] * ":  " * dstatetotaldeathpc_strfmt, marker = (2, :circle, 2),  markerstrokewidth = 0)
    #Plots.plot(dCOVID19statepcD, title=state[ind[1]] * " - Daily COVID-19 Deaths / 100k " * "on " * string(t[end])[1:10] * ":  " * dstatetotaldeathpc_strfmt)

    #covid19plot_confirmed = Plots.plot(pCOVID19usa, dCOVID19usa, pCOVID19state, dCOVID19state, dCOVID19statepc, layout = l8out,  xrotation=30, size=(800,900), xticks = t[1:7:end], legend=:false);
    #covid19plot_death = Plots.plot(pCOVID19usa, dCOVID19usa, pCOVID19state, dCOVID19state, dCOVID19statepc, layout = l8out,  xrotation=30, size=(800,900), xticks = t[1:7:end], legend=:false);

    local covid19plot = Plots.plot(pCOVID19usa, pCOVID19usaD, dCOVID19usa, dCOVID19usaD, pCOVID19state, pCOVID19stateD, dCOVID19state, dCOVID19stateD, dCOVID19statepc, dCOVID19statepcD, layout = l8out,  xrotation=30, size=reasonable_resolution(), xticks = t[1:31:end], legend=:false);

    local figoutdir = "../covid19_public/timeseries/";
    #Plots.savefig(covid19plot_confirmed, figoutdir * "covid19ts_confirmed_" * filter(x -> !isspace(x), state_of_interest) * ".html")
    #Plots.savefig(covid19plot_death, figoutdir * "covid19ts_death_" * filter(x -> !isspace(x), state_of_interest) * ".html")
    Plots.savefig(covid19plot, figoutdir * "covid19ts_integrated_" * filter(x -> !isspace(x), state_of_interest) * ".html")

    #gui(covid19plot)
    #sleep(1.0)
end


text:
import UnixMmap
using Markdown
srcdir = dirname(pathof(UnixMmap))

# Same names as Sys.KERNEL
bsds = (:Apple, :DragonFly, :FreeBSD, :NetBSD, :OpenBSD)
for sys in (:Linux, bsds...)
    @eval module $(Symbol(sys, "Mmap"))
        module UnixMmap
            module Sys
                const KERNEL = $(Expr(:quote, sys))
                islinux() = $(sys === :Linux)
                isapple() = $(sys === :Apple)
                isbsd()   = $(sys in bsds)
                isdragonfly() = $(sys === :DragonFly)
                isfreebsd()   = $(sys === :FreeBSD)
                isnetbsd()    = $(sys === :NetBSD)
                isopenbsd()   = $(sys === :OpenBSD)
            end
            import Main.UnixMmap: @staticexpand
            include($(joinpath(srcdir, "consts.jl")))
        end
    end
end

function _flag_docs(T)
    buf = IOBuffer()
    for c in instances(T)
        println(buf, c)
    end
    return Markdown.parse("```julia\n" * String(take!(buf)) * "```\n")
end


text:
"""Utility functions"""

"""
Compute the squared L2 norm.
"""
norm²(x) = sum(abs2, x)

function spectrumflatten(x::AbstractArray{T,1}, Nnorm::Int) where T <:Real
    if Nnorm >= length(x)
        xfilt = x.-median(x)
        xfilt[xfilt.<0] .= 0
        return xfilt
    end
    M = map(median, Subsequence(x, Nnorm, Nnorm-1))
    xfilt = x.-M
    xfilt[xfilt.<0] .= 0
    xfilt
end

function spectrumflatten(x::AbstractArray{T,2}, Nnorm::Int) where T <: Real
    mapslices(row->spectrumflatten(row, Nnorm), x, dims=2)
end

"""
Get myriad constant given α and scale.
"""
function myriadconstant(α, scale)
    (α/(2-α+eps()))*(scale^2)
end

"""
Get myriad constant given `x`.
"""
function myriadconstant(x::AbstractVector{T}) where T<:Real
    d = fit(AlphaStable, x)
    myriadconstant(d.α, d.scale)
end

"""
Get vector myriad constants given α and Rₘ.
"""
vmyriadconstant(α::T, Rₘ::AbstractMatrix{T}) where T = (α/(2-α+eps())), Rₘ

"""
Get vector myriad constants given `x`.
"""
function vmyriadconstant(x::AbstractVector{T}, m::Integer=4) where T<:Real
    d = fit(AlphaSubGaussian, x, m)
    vmyriadconstant(d.α, d.R)
end

"""
Convert the real signal `x` to an acoustic pressure signal in micropascal.
"""
function pressure(x::AbstractVector{T}, sensitivity::T, gain::T; voltparams::Union{Nothing, Tuple{Int, T}}=nothing) where T<:Real
    ν = exp10(sensitivity/20)
    G = exp10(gain/20)
    if voltparams !== nothing
        nbits, vref = voltparams
        x .*= vref/(2^(nbits-1))
    end
    x./(ν*G)
end

"""
Generate a Hilbert envelope of the real signal `x`.
"""
function envelope(x::AbstractVector{T}) where T<:Real
    abs.(hilbert(x))
end

"""
Get the normalized envelope of of the real signal `x`.
"""
function normalize_envelope(x::AbstractVector{T}) where T<:Real
    env = envelope(x)
    env/sum(env)
end

"""
Get the normalized spectrum of the real signal `x`.
"""
function normalize_spectrum(s::AbstractMatrix{T}) where T<:Real
    sf = sum(s, dims=2)
    sf/sum(sf)
end


text:
struct Person
    name::String
    age::Int
end

p = Person("john", 10) # create object
println("이름:$(p.name), 나이:$(p.age)")

max_stars_repo_name: myyrakle/Julia-Example

max_issues_repo_name: myyrakle/Julia-Example

max_forks_repo_name: myyrakle/Julia-Example


text:
type RMSPropSolver <: Solver
   decayrate::Float64
   smootheps::Float64
   stepcache::Array{NNMatrix,1}
   RMSPropSolver() = new(0.999, 1e-8, Array(NNMatrix,0))
end

type RMSPropSolverParams <: SolverParams
    regc::Float64
    learning_rate::Float64
    clipval::Float64
end

function step!(solver::RMSPropSolver, model::Model, sparams::RMSPropSolverParams)

    # perform parameter update
    solverstats = Array(Float64,0)
    numclipped = 0
    numtot = 0

    # All of the matrices used by the model
    modelMatices = model.matrices

    # init stepcache if needed
    if length(solver.stepcache) == 0
         for m in modelMatices
            push!(solver.stepcache, NNMatrix(m.n, m.d))
        end
    end

    for k = 1:length(modelMatices)
        @inbounds m = modelMatices[k] # mat ref
        @inbounds s = solver.stepcache[k]
        for i = 1:m.n
            for j = 1:m.d

                # rmsprop adaptive learning rate
                @inbounds mdwi = m.dw[i,j]
                @inbounds s.w[i,j] = s.w[i,j] * solver.decayrate + (1.0 - solver.decayrate) * mdwi^2

                # gradient clip
                if mdwi > sparams.clipval
                    mdwi = sparams.clipval
                    numclipped += 1
                end

                if mdwi < -sparams.clipval
                    mdwi = -sparams.clipval
                    numclipped += 1
                end
                numtot += 1

                # update (and regularize)
                @inbounds m.w[i,j] += - sparams.learning_rate * mdwi / sqrt(s.w[i,j] + solver.smootheps) - sparams.regc * m.w[i,j]
                @inbounds m.dw[i,j] = 0. # reset gradients for next iteration
            end
        end
    end
    solverstats　=  numclipped * 1.0 / numtot
    return solverstats
end

max_forks_repo_name: haroldsoh/RecurrentNN


text:
## PARAMETER RANGES

abstract type ParamRange <: MLJType end

Base.isempty(::ParamRange) = false

abstract type Boundedness end

abstract type   Bounded <: Boundedness end
abstract type Unbounded <: Boundedness end

abstract type   LeftUnbounded <: Unbounded end
abstract type  RightUnbounded <: Unbounded end
abstract type DoublyUnbounded <: Unbounded end

struct NumericRange{B<:Boundedness,T,D} <: ParamRange
    field::Union{Symbol,Expr}
    lower::Union{T,Float64}     # Float64 to allow for -Inf
    upper::Union{T,Float64}     # Float64 to allow for Inf
    origin::Float64
    unit::Float64
    scale::D
end

struct NominalRange{T} <: ParamRange
    field::Union{Symbol,Expr}
    values::Tuple{Vararg{T}}
end

MLJBase.show_as_constructed(::Type{<:ParamRange}) = true

"""
    r = range(model, :hyper; values=nothing)

Defines a `NominalRange` object for a field `hyper` of `model`,
assuming the field value does not subtype `Real`. Note that `r` is not
directly iterable but `iterator(r)` iterates over `values`.

The specific type of the hyperparameter is automatically determined
from the current value at `model`. To override, specify a type in
place of `model`.

A nested hyperparameter is specified using dot notation. For example,
`:(atom.max_depth)` specifies the `:max_depth` hyperparameter of the
hyperparameter `:atom` of `model`.

    r = range(model, :hyper; upper=nothing, lower=nothing,
              scale=nothing, values=nothing)

Assuming `values` is not specified, this defines a `NumericRange`
object for a `Real` field `hyper` of `model`.  Note that `r` is not
directly iteratable but `iterator(r, n)` iterates over `n` values
controlled by the various parameters (see more at [`iterator`](@ref)).
The supported scales are `:linear`,` :log`, `:logminus`, `:log10`,
`:log2`, or a function (see below).

The iterator values for `Integer` types are rounded (with duplicate
values removed, resulting in possibly less than `n` values).

If `scale` is unspecified, it is set to `:linear`, `:log`,
`:logminus`, or `:linear`, according to whether the interval `(lower,
upper)` is bounded, right-unbounded, left-unbounded, or doubly
unbounded, respectively.  Note `upper=Inf` and `lower=-Inf` are
allowed.

If `values` is specified, the other keyword arguments are ignored and
a `NominalRange` object is returned (see above).

To override the automatically detected hyperparameter type, substitute
a type in place of `model`.

If a function `f` is provided as `scale`, then
`iterator(r, n)` iterates over the values `[f(x1), f(x2), ... ,
f(xn)]`, where `x1, x2, ..., xn` are linearly spaced between `lower`
and `upper`.
"""
function Base.range(model::Union{Model, Type}, field::Union{Symbol,Expr};
                    values=nothing, lower=nothing, upper=nothing,
                    origin=nothing, unit=nothing, scale::D=nothing) where D
    if model isa Model
        value = recursive_getproperty(model, field)
        T = typeof(value)
    else
        T = model
    end
    if T <: Real && values === nothing
        return numeric_range(T, D, field, lower, upper, origin, unit, scale)
    else
        return nominal_range(T, field, values)
    end
end

function numeric_range(T, D, field, lower, upper, origin, unit, scale)
    lower === Inf &&
        throw(ArgumentError("`lower` must be finite or `-Inf`."))
    upper === -Inf &&
        throw(ArgumentError("`upper` must be finite or `Inf`."))

    lower === nothing && (lower = -Inf)
    upper === nothing && (upper = Inf)

    lower < upper ||
        throw(ArgumentError("`lower` must be strictly less than `upper`."))

    is_unbounded = (lower === -Inf || upper === Inf)

    if origin === nothing
        is_unbounded &&
            throw(DomainError("For an unbounded range you must specify " *
                              "`origin=...` to define a centre.\nTo make " *
                              "the range bounded, specify finite " *
                              "`upper=...` and `lower=...`."))
        origin = (upper + lower)/2
    end
    if unit === nothing
        is_unbounded &&
            throw(DomainError("For an unbounded range you must specify " *
                              "`unit=...` to define a unit of scale.\nTo " *
                              "make the range bounded, specify finite " *
                              "`upper=...` and `lower=...`."))
        unit = (upper - lower)/2
    end
    unit > 0 || throw(DomainError("`unit` must be positive."))
    origin < upper && origin > lower ||
        throw(DomainError("`origin` must lie strictly between `lower` and " *
                          "`upper`."))
    if lower === -Inf
        if upper === Inf
            B = DoublyUnbounded
            scale === nothing && (scale = :linear)
        else
            B = LeftUnbounded
            scale === nothing && (scale = :logminus)
        end
    else
        if upper === Inf
            B = RightUnbounded
            scale === nothing && (scale = :log)
        else
            B = Bounded
            scale === nothing && (scale = :linear)
        end
    end
    scale isa Symbol && (D = Symbol)
    return NumericRange{B,T,D}(field, lower, upper, origin, unit, scale)
end

nominal_range(T, field, values) = throw(ArgumentError(
    "`values` does not have an appropriate type."))

nominal_range(T, field, ::Nothing) = throw(ArgumentError(
    "You must specify values=... for a nominal parameter."))

function nominal_range(::Type{T}, field, values::AbstractVector{T}) where T
    return NominalRange{T}(field, Tuple(values))
end


text:
module TestHelpers

using Test

using JuMP
using MathOptInterface
using TimerOutputs

using MIPVerify
using MIPVerify: find_adversarial_example
using MIPVerify: NeuralNet
using MIPVerify: PerturbationFamily

macro timed_testset(name::String, block)
    # copied from https://github.com/KristofferC/Tensors.jl/blob/master/test/runtests.jl#L8
    return quote
        @timeit "$($(esc(name)))" begin
            @testset "$($(esc(name)))" begin
                $(esc(block))
            end
        end
    end
end

const TEST_DEFAULT_TIGHTENING_ALGORITHM = lp

if Base.find_package("Gurobi") === nothing
    using Cbc
    optimizer = Cbc.Optimizer
    main_solve_options = Dict("logLevel" => 0)
    tightening_options = Dict("logLevel" => 0, "seconds" => 20)
else
    using Gurobi
    env = Gurobi.Env()
    optimizer = () -> Gurobi.Optimizer(env)
    main_solve_options = Dict("OutputFlag" => 0)
    tightening_options = Dict("OutputFlag" => 0, "TimeLimit" => 20)
end

get_optimizer() = optimizer
get_main_solve_options()::Dict = main_solve_options
get_tightening_options()::Dict = tightening_options

function get_new_model()::Model
    return Model(optimizer_with_attributes(get_optimizer(), get_main_solve_options()...))
end

"""
Tests the `find_adversarial_example` function.
  - If `input` is already classified in the target label, `expected_objective_value`
    should be 0.
  - If there is no adversarial example for the specified parameters,
    `expected_objective_value` should be NaN.
  - If there is an adversarial example, checks that the objective value is as expected,
    and that the perturbed output for the target label exceeds the perturbed
    output for all other labels by 0.
"""
function test_find_adversarial_example(
    nn::NeuralNet,
    input::Array{<:Real,N},
    target_selection::Union{Integer,Array{<:Integer,1}},
    pp::PerturbationFamily,
    norm_order::Real,
    expected_objective_value::Real;
    invert_target_selection::Bool = false,
) where {N}
    d = find_adversarial_example(
        nn,
        input,
        target_selection,
        get_optimizer(),
        get_main_solve_options(),
        pp = pp,
        norm_order = norm_order,
        tightening_options = get_tightening_options(),
        tightening_algorithm = TEST_DEFAULT_TIGHTENING_ALGORITHM,
        invert_target_selection = invert_target_selection,
    )
    if isnan(expected_objective_value)
        @test d[:SolveStatus] == MathOptInterface.INFEASIBLE ||
              d[:SolveStatus] == MathOptInterface.INFEASIBLE_OR_UNBOUNDED
    else
        actual_objective_value = JuMP.objective_value(d[:Model])
        if expected_objective_value == 0
            @test isapprox(actual_objective_value, expected_objective_value; atol = 1e-4)
        else
            @test isapprox(actual_objective_value, expected_objective_value; rtol = 5e-5)

            perturbed_output = JuMP.value.(d[:PerturbedInput]) |> nn
            perturbed_target_output =
                maximum(perturbed_output[Bool[i ∈ d[:TargetIndexes] for i in 1:length(d[:Output])]])
            maximum_perturbed_other_output =
                maximum(perturbed_output[Bool[i ∉ d[:TargetIndexes] for i in 1:length(d[:Output])]])
            @test perturbed_target_output / (maximum_perturbed_other_output) ≈ 1 atol = 5e-5
        end
    end
end

"""
Runs tests on the neural net described by `nn` for input `input` and the objective values
indicated in `expected objective values`.

# Arguments
- `test_cases::Array{Tuple}`:
   each element is: ((target_selection, perturbation_parameter, norm_order), expected_objective_value)
   `expected_objective_value` is `NaN` if there is no perturbation that brings the image
   into the target category.
"""
function batch_test_adversarial_example(
    nn::NeuralNet,
    input::Array{<:Real,N},
    test_cases::Array,
) where {N}
    for (test_params, expected_objective_value) in test_cases
        (target_selection, pp, norm_order) = test_params
        @testset "target labels = $target_selection, $(string(pp)) perturbation, norm order = $norm_order" begin
            test_find_adversarial_example(
                nn,
                input,
                target_selection,
                pp,
                norm_order,
                expected_objective_value,
            )
        end
    end
end
end

"""
Generates a pseudorandom array of the specified `dims` with values in [lb, ub]
"""
function gen_array(dims::NTuple{N,Integer}, lb::Real, ub::Real) where {N}
    #! format: off
    rands = [
        0.823, 0.714, 0.970, 0.265, 0.969, 0.105, 0.242, 0.362, 0.061, 0.994,
        0.910, 0.439, 0.769, 0.092, 0.473, 0.530, 0.753, 0.966, 0.168, 0.245,
        0.164, 0.279, 0.799, 0.114, 0.615, 0.666, 0.853, 0.025, 0.856, 0.013,
        0.177, 0.340, 0.846, 0.766, 0.799, 0.506, 0.388, 0.412, 0.479, 0.980,
        0.278, 0.236, 0.539, 0.745, 0.934, 0.583, 0.147, 0.829, 0.007, 0.819,
        0.203, 0.073, 0.155, 0.585, 0.635, 0.252, 0.564, 0.824, 0.337, 0.432,
        0.042, 0.113, 0.783, 0.414, 0.623, 0.218, 0.621, 0.045, 0.088, 0.958,
        0.068, 0.885, 0.718, 0.451, 0.798, 0.387, 0.531, 0.992, 0.716, 0.845,
        0.361, 0.514, 0.172, 0.628, 0.995, 0.964, 0.083, 0.397, 0.504, 0.188,
        0.973, 0.692, 0.493, 0.218, 0.967, 0.498, 0.033, 0.752, 0.033, 0.641,
        0.585, 0.849, 0.347, 0.379, 0.211, 0.582, 0.453, 0.935, 0.355, 0.099,
        0.539, 0.697, 0.360, 0.333, 0.870, 0.127, 0.656, 0.579, 0.110, 0.270,
        0.260, 0.228, 0.168, 0.414, 0.847, 0.133, 0.409, 0.977, 0.882, 0.037,
        0.910, 0.257, 0.737, 0.545, 0.859, 0.770, 0.106, 0.691, 0.841, 0.309,
        0.167, 0.800, 0.722, 0.275, 0.779, 0.061, 0.139, 0.463, 0.798, 0.498,
        0.655, 0.716, 0.652, 0.042, 0.788, 0.278, 0.468, 0.627, 0.385, 0.862,
        0.575, 0.528, 0.711, 0.426, 0.983, 0.218, 0.577, 0.198, 0.820, 0.944,
        0.868, 0.001, 0.430, 0.468, 0.421, 0.976, 0.024, 0.441, 0.994, 0.760,
        0.967, 0.362, 0.408, 0.288, 0.640, 0.096, 0.074, 0.531, 0.011, 0.361,
        0.767, 0.697, 0.913, 0.272, 0.466, 0.115, 0.150, 0.719, 0.507, 0.769,
        0.469, 0.435, 0.569, 0.596, 0.816, 0.266, 0.376, 0.302, 0.297, 0.828,
        0.062, 0.986, 0.452, 0.885, 0.675, 0.679, 0.115, 0.974, 0.622, 0.696,
        0.353, 0.997, 0.153, 0.147, 0.329, 0.223, 0.866, 0.426, 0.234, 0.766,
        0.767, 0.507, 0.860, 0.876, 0.067, 0.962, 0.277, 0.196, 0.151, 0.903,
        0.043, 0.215, 0.910, 0.161, 0.086, 0.585, 0.411, 0.095, 0.551, 0.682,
        0.267, 0.858, 0.310, 0.262, 0.253, 0.613, 0.020, 0.090, 0.295, 0.593,
        0.066, 0.905, 0.455, 0.942, 0.613, 0.908, 0.304, 0.279, 0.886, 0.515,
        0.156, 0.435, 0.649, 0.926, 0.685, 0.719, 0.779, 0.616, 0.844, 0.328,
        0.605, 0.065, 0.238, 0.644, 0.477, 0.201, 0.867, 0.604, 0.402, 0.137,
        0.135, 0.135, 0.823, 0.395, 0.592, 0.636, 0.275, 0.824, 0.837, 0.735,
        0.838, 0.922, 0.369, 0.495, 0.796, 0.881, 0.616, 0.641, 0.236, 0.165,
        0.914, 0.244, 0.916, 0.403, 0.721, 0.119, 0.320, 0.725, 0.619, 0.102,
        0.300, 0.064, 0.502, 0.997, 0.030, 0.207, 0.534, 0.637, 0.434, 0.324,
        0.722, 0.425, 0.557, 0.245, 0.923, 0.873, 0.267, 0.202, 0.625, 0.388,
        0.119, 0.548, 0.973, 0.426, 0.859, 0.350, 0.459, 0.881, 0.340, 0.773,
        0.767, 0.266, 0.537, 0.179, 0.427, 0.197, 0.470, 0.596, 0.993, 0.912,
        0.801, 0.788, 0.242, 0.899, 0.892, 0.727, 0.031, 0.965, 0.251, 0.801,
        0.035, 0.957, 0.238, 0.246, 0.560, 0.222, 0.964, 0.812, 0.886, 0.753,
        0.484, 0.032, 0.714, 0.337, 0.850, 0.110, 0.629, 0.062, 0.086, 0.459,
        0.899, 0.685, 0.106, 0.184, 0.420, 0.043, 0.157, 0.701, 0.165, 0.237,
        0.951, 0.841, 0.017, 0.268, 0.796, 0.929, 0.680, 0.866, 0.579, 0.103,
        0.801, 0.189, 0.449, 0.247, 0.134, 0.134, 0.169, 0.201, 0.646, 0.318,
        0.124, 0.161, 0.493, 0.881, 0.472, 0.507, 0.613, 0.296, 0.114, 0.214,
        0.114, 0.897, 0.280, 0.889, 0.240, 0.641, 0.908, 0.614, 0.677, 0.453,
        0.079, 0.095, 0.119, 0.572, 0.169, 0.360, 0.803, 0.853, 0.250, 0.259,
        0.776, 0.777, 0.050, 0.556, 0.129, 0.395, 0.468, 0.639, 0.635, 0.306,
        0.104, 0.868, 0.602, 0.687, 0.412, 0.983, 0.349, 0.858, 0.483, 0.538,
        0.838, 0.837, 0.052, 0.836, 0.706, 0.179, 0.270, 0.538, 0.785, 0.463,
        0.184, 0.798, 0.306, 0.852, 0.632, 0.723, 0.151, 0.275, 0.740, 0.732,
        0.312, 0.186, 0.245, 0.935, 0.737, 0.940, 0.379, 0.641, 0.037, 0.338,
        0.196, 0.187, 0.242, 0.291, 0.795, 0.850, 0.454, 0.453, 0.653, 0.167,
        0.873, 0.519, 0.415, 0.667, 0.137, 0.660, 0.499, 0.060, 0.958, 0.309,
        0.654, 0.415, 0.850, 0.972, 0.147, 0.818, 0.667, 0.760, 0.089, 0.286,
        0.586, 0.197, 0.879, 0.489, 0.176, 0.381, 0.394, 0.072, 0.234, 0.205,
        0.632, 0.528, 0.399, 0.105, 0.045, 0.861, 0.850, 0.299, 0.985, 0.568,
        0.735, 0.585, 0.139, 0.961, 0.107, 0.318, 0.098, 0.376, 0.655, 0.404,
        0.548, 0.403, 0.419, 0.349, 0.766, 0.360, 0.654, 0.800, 0.782, 0.685,
        0.476, 0.575, 0.579, 0.148, 0.007, 0.611, 0.760, 0.845, 0.206, 0.975,
        0.602, 0.657, 0.055, 0.170, 0.237, 0.869, 0.656, 0.331, 0.423, 0.982,
        0.791, 0.547, 0.477, 0.308, 0.026, 0.631, 0.903, 0.119, 0.034, 0.166,
        0.049, 0.727, 0.617, 0.520, 0.113, 0.055, 0.582, 0.500, 0.050, 0.665,
        0.482, 0.356, 0.105, 0.702, 0.452, 0.752, 0.956, 0.649, 0.429, 0.745,
        0.665, 0.498, 0.087, 0.828, 0.197, 0.565, 0.108, 0.837, 0.696, 0.703,
        0.842, 0.805, 0.133, 0.798, 0.525, 0.342, 0.664, 0.894, 0.259, 0.781,
        0.169, 0.440, 0.444, 0.787, 0.150, 0.029, 0.162, 0.872, 0.494, 0.700,
        0.938, 0.434, 0.484, 0.647, 0.842, 0.808, 0.307, 0.445, 0.948, 0.500,
        0.783, 0.652, 0.737, 0.261, 0.289, 0.350, 0.754, 0.297, 0.796, 0.190,
        0.505, 0.153, 0.187, 0.875, 0.777, 0.823, 0.127, 0.259, 0.793, 0.424,
        0.622, 0.321, 0.431, 0.430, 0.999, 0.489, 0.524, 0.258, 0.410, 0.791,
        0.306, 0.444, 0.986, 0.542, 0.732, 0.776, 0.830, 0.325, 0.729, 0.692,
        0.796, 0.275, 0.446, 0.312, 0.866, 0.969, 0.122, 0.407, 0.836, 0.351,
        0.505, 0.167, 0.016, 0.440, 0.891, 0.816, 0.546, 0.776, 0.914, 0.606,
        0.392, 0.188, 0.225, 0.638, 0.318, 0.869, 0.182, 0.581, 0.014, 0.045,
        0.479, 0.741, 0.415, 0.120, 0.151, 0.753, 0.354, 0.412, 0.853, 0.509,
        0.068, 0.486, 0.745, 0.625, 0.349, 0.305, 0.997, 0.481, 0.021, 0.443,
        0.479, 0.010, 0.607, 0.692, 0.780, 0.827, 0.038, 0.781, 0.493, 0.044,
        0.468, 0.370, 0.779, 0.876, 0.935, 0.428, 0.869, 0.365, 0.557, 0.481,
        0.452, 0.203, 0.117, 0.123, 0.342, 0.573, 0.492, 0.639, 0.832, 0.842,
        0.644, 0.682, 0.952, 0.401, 0.173, 0.016, 0.798, 0.101, 0.571, 0.641,
        0.669, 0.274, 0.930, 0.181, 0.935, 0.072, 0.253, 0.012, 0.836, 0.023,
        0.094, 0.906, 0.276, 0.957, 0.416, 0.934, 0.175, 0.524, 0.975, 0.595,
        0.948, 0.024, 0.931, 0.465, 0.695, 0.220, 0.904, 0.277, 0.598, 0.467,
        0.775, 0.123, 0.215, 0.813, 0.960, 0.119, 0.296, 0.999, 0.431, 0.633,
        0.177, 0.714, 0.040, 0.921, 0.026, 0.746, 0.547, 0.073, 0.189, 0.085,
        0.080, 0.636, 0.225, 0.599, 0.291, 0.444, 0.558, 0.012, 0.039, 0.442,
        0.682, 0.315, 0.490, 0.299, 0.377, 0.529, 0.356, 0.548, 0.166, 0.043,
        0.929, 0.667, 0.433, 0.369, 0.682, 0.436, 0.926, 0.727, 0.411, 0.320,
        0.973, 0.043, 0.718, 0.649, 0.659, 0.347, 0.500, 0.065, 0.815, 0.723,
        0.651, 0.590, 0.191, 0.247, 0.784, 0.244, 0.109, 0.840, 0.106, 0.114,
        0.596, 0.617, 0.117, 0.791, 0.684, 0.770, 0.827, 0.802, 0.085, 0.745,
        0.479, 0.957, 0.538, 0.874, 0.170, 0.798, 0.524, 0.310, 0.865, 0.115,
        0.063, 0.634, 0.708, 0.352, 0.223, 0.127, 0.306, 0.430, 0.808, 0.873,
        0.470, 0.861, 0.315, 0.231, 0.255, 0.584, 0.157, 0.101, 0.181, 0.129,
        0.382, 0.821, 0.872, 0.856, 0.789, 0.669, 0.793, 0.439, 0.371, 0.253,
        0.976, 0.266, 0.095, 0.927, 0.025, 0.250, 0.623, 0.048, 0.458, 0.206,
        0.216, 0.678, 0.090, 0.494, 0.230, 0.376, 0.599, 0.143, 0.948, 0.753,
        0.863, 0.490, 0.401, 0.787, 0.853, 0.410, 0.866, 0.667, 0.311, 0.651,
        0.065, 0.853, 0.235, 0.672, 0.954, 0.753, 0.233, 0.417, 0.547, 0.837,
        0.699, 0.502, 0.072, 0.986, 0.454, 0.973, 0.232, 0.479, 0.799, 0.254,
        0.850, 0.282, 0.799, 0.109, 0.671, 0.595, 0.898, 0.717, 0.535, 0.349,
    ]
    #! format: on
    @assert prod(dims) <= prod(size(rands))
    @assert lb < ub
    xs = reshape(rands[1:prod(dims)], dims)
    return xs * (ub - lb) .+ lb
end


text:
using Unicode

pydict = Dict{Char, String}()
pyset = Set{String}()

for line in eachline(joinpath("D:\\", "pinyin.txt"))
        if startswith(line, "#"); continue; end
        code, pys, chr = split(line, [' ', '#', ':']; keepempty=false)
        pys = split(Unicode.normalize(pys; stripmark=true), ','; keepempty=false) |> unique

        for py in pys; push!(pyset, py); end

        pys = join(pys, ',')
        chr = chr[1]
        #@show pys
        pydict[chr] = pys
        #@show chr, pydict[chr]
end

@show length(pyset)

@show pyset

open(joinpath("D:\\", "chr2py.txt"), "w") do io
        for (k, v) in pydict; println(io, k, ' ', v); end
end

pinyin(c::Char) = get(pydict, c, c)

pinyin(s::AbstractString) = map(pinyi, s)

#pinyin(ss::Vector{T <: AbstractString}) where T = map(pinyi, ss)


text:
include("wave_base.jl")
include("wave_util.jl")
include("helm.jl")
include("helm_2d.jl")
include("helm_3d.jl")
include("wave_model_serial.jl")
include("wave_model_parallel.jl")


text:
module VorticityStream

using LinearAlgebra
using Base.Iterators
using StaticArrays
using Statistics
using TimerOutputs

using ..AeroMDAO: AbstractPanel, AbstractPanel2D, Panel2D, WakePanel2D, Point2D, Uniform2D, collocation_point, p1, p2, transform_panel, transform_panel_points, affine_2D, panel_length, panel_angle, panel_tangent, panel_normal, distance, panel_points, stream, pressure_coefficient, rotation, inverse_rotation, midpair_map, panel_points, reverse_panel, panel_scalar, trailing_edge_panel

include("singularities.jl")
include("matrix.jl")

## Dynamics helpers
#===========================================================================#

lift_coefficient(cp, dist_colpoints, panel_angle) = - cp * dist_colpoints * cos(panel_angle)

lift_coefficient(wake_strength, speed) = 2. * wake_strength / speed

## Matrix assembly
#===========================================================================#

# export solve_problem

# function solve_problem(panels :: Vector{<: Panel2D}, u, sources :: Bool, wake_length)
#   φs        = solve_linear(panels, u, sources; bound = wake_length)
#   cps, cls  = aerodynamic_coefficients(panels, φs, u, sources)
#   cl_wake   = lift_coefficient(last(φs), norm(u))

#   cps, cls, cl_wake
# end

# function solve_problem(panels :: Vector{<: Panel2D}, u, num_wake :: Integer, wake_length)
#   wakes     = wake_panels(panels, wake_length, num_wake)
#   φs    = solve_linear(panels, u, wakes; bound = wake_length)
#   cps, cls  = aerodynamic_coefficients(panels, φs, u, true)
#   cl_wake   = lift_coefficient(last(φs), norm(u))

#   cps, cls, cl_wake
# end

# function ψp_influence(panel_i :: Panel2D, point)
#   xp, yp = transform_panel(panel_i, point)
#   vortex_stream_1(1., xp, yp, 0., panel_length(panel_i)) + vortex_stream_2(1., xp, yp, 0., panel_length(panel_i))
# end

# function ψm_influence(panel_i :: Panel2D, point)
#   xp, yp = transform_panel(panel_i, point)
#   vortex_stream_1(1., xp, yp, 0., panel_length(panel_i)) - vortex_stream_2(1., xp, yp, 0., panel_length(panel_i))
# end

# function te_influence(panel_i :: Panel2D, point)
#   xp, yp = transform_panel(panel_i, point)
#   source_stream(1., xp, yp, 0., panel_length(panel_i)) + vortex_stream_1(1., xp, yp, 0., panel_length(panel_i))
# end

# function source_influence(panel_i :: Panel2D, point)
#   xp, yp = transform_panel(panel_i, point)
#   source_stream(1., xp, yp, 0., panel_length(panel_i))
# end

# function source_influence_te(panel_i :: Panel2D, point)
#   xp, yp = transform_panel(panel_i, point)
#   source_stream_te(1., xp, yp, 0., panel_length(panel_i))
# end

end


text:
export quldecircuit
"""
    quldecircuit(n::Int,blk::TaylorParam,VS1::AbstractMatrix,VS2::AbstractMatrix) -> ChainBlock{n}

Generates circuit for solving linear differental equations for a unitary H input.
"""
function quldecircuit(n::Int,blk::TaylorParam,VS1::AbstractMatrix,VS2::AbstractMatrix)
    C_tilda = blk.C_tilda
    D_tilda = blk.D_tilda
    N = blk.N
    circinit = circuit_ends(n,blk,VS1,VS2)
    circmid = circuit_intermediate(n,1,blk)
    circfin =circuit_ends(n,blk,VS1',VS2')
    CPType = eltype(blk.H)
    V = CPType[C_tilda/N D_tilda/N; D_tilda/N -1*C_tilda/N]
    V = matblock(V)
    push!(circfin,put(1=>V))
    return chain(circinit, circmid,circfin)
end

"""
    quldecircuit(n::Int,blk::TaylorParam,VS1::AbstractMatrix,VS2::AbstractMatrix,VT::AbstractMatrix) -> ChainBlock{n}

Generates circuit for solving linear differental equations for a non-unitary H input.
"""
function quldecircuit(n::Int,blk::TaylorParam,VS1::AbstractMatrix,VS2::AbstractMatrix,VT::AbstractMatrix)
    C_tilda = blk.C_tilda
    D_tilda = blk.D_tilda
    N = blk.N
    circinit = circuit_ends(n,blk,VS1,VS2,VT)
    circmid = circuit_intermediate(n,1,blk)
    circfin =circuit_ends(n,blk,VS1',VS2',VT')
    CPType = eltype(blk.H)
    V = CPType[C_tilda/N D_tilda/N; D_tilda/N -1*C_tilda/N]
    V = matblock(V)
    push!(circfin,put(1=>V))
    return chain(circinit, circmid,circfin)
end

function DiffEqBase.solve(prob::QuLDEProblem{uType,tType,isinplace, F, P, false}, alg::QuLDE; kwargs...) where {uType,tType,isinplace, F, P}
    opn = opnorm(prob.A)
    b = prob.b
    t = prob.tspan[2] - prob.tspan[1]
    x = prob.u0
    nbit = log2i(length(b))
    k = alg.k
    CPType = eltype(x)
    blk = TaylorParam(k,t,prob)
    VS1 = calc_vs1(blk,x,opn)
    VS2 = calc_vs2(blk,b,opn)
    rs = blk.rs
    l = blk.l
    if rs !=k
        n = 1 + rs + nbit
        inreg = ArrayReg(x/norm(x)) ⊗ zero_state(CPType,rs) ⊗ ( (blk.C_tilda/blk.N) * zero_state(CPType, 1) ) +  ArrayReg(b/norm(b)) ⊗ zero_state(CPType, rs) ⊗ ((blk.D_tilda/blk.N) * ArrayReg(CPType, bit"1") )
        cir = quldecircuit(n,blk,VS1,VS2)
    else
        n = 1 + k*(1 + l) + nbit
        VT = calc_vt(CPType)
        inreg = ArrayReg(x/norm(x))⊗ zero_state(CPType, k*l)  ⊗ zero_state(CPType, k) ⊗ ( (blk.C_tilda/blk.N) * zero_state(CPType, 1) )+  ArrayReg(b/norm(b)) ⊗ zero_state(CPType, k*l) ⊗ zero_state(CPType, k) ⊗ ((blk.D_tilda/blk.N) * ArrayReg(CPType, bit"1") )
        cir = quldecircuit(n,blk,VS1,VS2,VT)
    end

    res = apply!(inreg,cir) |> focus!(1:n - nbit...,) |> select!(0) |> state
    out = (blk.N^2)*(vec(res))
    return out
end

function DiffEqBase.solve(prob::QuLDEProblem{uType, tType, isinplace, F, P, true}, alg::QuLDE; kwargs...) where {uType, tType, isinplace, F, P}
    opn = opnorm(prob.A)
    b = prob.b
    t = prob.tspan[2] - prob.tspan[1]
    k = alg.k
    nbit = log2i(length((b)))
    blk = TaylorParam(k,t,prob)
    CPType = eltype(b)
    VS2 = calc_vs2(blk,b,opn)
    l = blk.l
    rs = blk.rs
    if rs !=k
        n = rs + nbit
        inreg = ArrayReg(b/norm(b)) ⊗ zero_state(CPType, rs)
        cir = taylorcircuit(n,blk,VS2)
    else
        n = k*(1 + l) + nbit
        inreg = ArrayReg(b/norm(b)) ⊗ zero_state(CPType, k*l) ⊗ zero_state(CPType, k)
        VT = calc_vt(CPType)
        cir = taylorcircuit(n,blk,VS2,VT)
    end
    r = apply!(inreg,cir) |> focus!(1:n - nbit...,) |> select!(0) |> state
    out = blk.N * vec(r)
    return out
end;

function DiffEqBase.solve(prob::ODEProblem, alg::QuLDE; dt = (prob.tspan[2]-prob.tspan[1])/10 ,kwargs...)
    u0 = prob.u0
    siz, = size(u0)
    if !ispow2(siz) || siz == 1
        throw("Enter arrays of length that are powers of 2 greater than 1.")
    end
    nbit = log2i(siz)
    f = prob.f
    p = prob.p
    tspan = prob.tspan
    k = alg.k
    len = round(Int,(tspan[2] - tspan[1])/dt) + 1
    res = Array{eltype(u0),2}(undef,len,siz)
    utemp = u0
    b = zero(u0)
    for i in 0:len - 2
        res[i+1,:] = utemp
        f(b,utemp,p,i*dt + tspan[1])
        J = ForwardDiff.jacobian((du,u) -> f(du,u,p, i*dt+tspan[1]),b,utemp)
        qprob = QuLDEProblem(J,b,(0.0,dt))
        out = solve(qprob,QuLDE(k))
        utemp = real(out + utemp)
    end
    res[end,:] = utemp
    return res
end


text:
"""
# extract(chns::Array{Float64,3}, cnames::Vector{String})
RStan/PyStan style extract
chns: Array: [draws, vars, chains], cnames: ["lp__", "accept_stat__", "f.1", ...]
Output: namedtuple -> (var[1]=..., ...)
"""
function extract(chns::Array{Float64,3}, cnames::Vector{String})
    draws, vars, chains = size(chns)

    ex_dict = Dict{Symbol, Array}()

    group_map = Dict{Symbol, Array}()
    for (i, cname) in enumerate(cnames)
        sp_arr = split(cname, ".")
        name = Symbol(sp_arr[1])
        if length(sp_arr) == 1
            ex_dict[name] = chns[:,i,:]
        else
            if !(name in keys(group_map))
                group_map[name] = Any[]
            end
            push!(group_map[name], (i, [Meta.parse(i) for i in sp_arr[2:end]]))
        end
    end

    for (name, group) in group_map
        max_idx = maximum(hcat([idx for (i, idx) in group]...), dims=2)[:,1]
        ex_dict[name] = similar(chns, max_idx..., draws, chains)
    end

    for (name, group) in group_map
        for (i, idx) in group
            ex_dict[name][idx..., :, :] = chns[:,i,:]
        end
    end

    return (;ex_dict...)
end

function append_namedtuples(nts)
    dct = Dict()
    for par in keys(nts)
        if length(size(nts[par])) > 2
            r, s, c = size(nts[par])
            dct[par] = reshape(nts[par], r, s*c)
        else
            s, c = size(nts[par])
            dct[par] = reshape(nts[par], s*c)
        end
    end
    (;dct...)
end

"""

# convert_a3d

# Convert the output file(s) created by cmdstan to a NamedTuple. Append all chains

$(SIGNATURES)

"""
function convert_a3d(a3d_array, cnames, ::Val{:namedtuple})
    append_namedtuples(extract(a3d_array, cnames))
end

"""

# convert_a3d

# Convert the output file(s) created by cmdstan to a NamedTuple.

$(SIGNATURES)

"""
function convert_a3d(a3d_array, cnames, ::Val{:namedtuples})
    extract(a3d_array, cnames)
end

max_stars_repo_name: StanJulia/StanSample

max_issues_repo_name: StanJulia/StanSample

max_forks_repo_name: StanJulia/StanSample


text:
## PARTIALNEURALAREA
mutable struct PartialArea{T} <: BrainArea{T}
    neurons::Array{Neuron{T, PartialArea{T}}, 1}
    assembly_size::Int
    firing::Array{Int, 1}
    firing_prev::Array{Int, 1}
    plasticity ::T
    synapse_prob::T
end

function PartialArea(T::Type)
    return PartialArea(Neuron{T, PartialArea{T}}[], 0, Int[], Int[], T(0), T(0))
end

function PartialArea(num_neurons::Int, assem_size::Int, plasticity::T, synapse_prob::T) where T
    area = PartialArea(Neuron{T, PartialArea{T}}[], assem_size, Int[], Int[], plasticity, synapse_prob)
    area.neurons = [Neuron(area, i) for i in 1:num_neurons]
    return area
end

"""Print format for `NeuralArea`."""
function Base.show(io::IO, area::PartialArea{T}) where T
    descr = "PartialArea{$T}: $(num_neurons(area)) neurons"
    print(io, descr)
end

"""Random stimulus currents into a PartialArea."""
rand_stim(area::PartialArea{T}) where T = rand_stim(area, p=area.synapse_prob)

"""Generate synapses into the target neural area, `area`. Each synapses between
`neuron` and a neuron in `area` is generated randomly with probability
`neuron.area.synapse_prob`.
"""
function generate_synapses(
    neuron::Neuron{T, PartialArea{T}},
    area::BrainArea{T}
) where T
    mask = rand(Bernoulli(neuron.area.synapse_prob), length(area))
    target_neruons = area.neurons[mask]
    neuron.synapses[area] = Dict(target_neruons .=> ones(T, sum(mask)))
end

"""
    fire!(
        source_area::PartialArea,
        target_area::BrainArea,
        target_currents::Array{T, 1},
        attrib::AttributionGraph{Neuron{T, U}}
    ) where {T, U}

Fires each neuron in `source_area` into `target_area`. Adds resulting ion
currents to corresponding neuron indexes in `currents` array. Collects
neurons into the attribution graph.
"""
function fire!(
    source_area::PartialArea{T},
    target_area::BrainArea{T},
    target_currents::Array{T, 1},
    attrib::AttributionGraph{Neuron{T, U}}
) where {T, U}
    # Fire each neuron in the assembly into the target area
    for idx in source_area.firing
        neuron = source_area.neurons[idx]
        !haskey(neuron, target_area)  && generate_synapses(neuron, target_area)
        fire!(neuron, target_area, target_currents, attrib)
    end
end

"""
    fire!(
        assembly::Assembly{T},
        area::PartialArea{T},
        currents::Array{T, 1},
        attrib::AttributionGraph{Neuron{T, U}}
    ) where {T, U}

Fires each neuron in `assembly` into the target area. Adds resulting ion
currents to corresponding neuron indexes in `current` array.
"""
function fire!(
    assembly::Assembly{T},
    area::PartialArea{T},
    currents::Array{T, 1},
    attrib::AttributionGraph{Neuron{T, U}}
) where {T, U}
    # Fire each neuron in the assembly into the target area
    for idx in assembly.neurons
        neuron = assembly.area.neurons[idx]
        !haskey(neuron, area)  && generate_synapses(neuron, area)
        fire!(neuron, area, currents, attrib)
    end
end

"""Creates a `Brain` type with generative synapses. That is, because the
majority of synapses are not used in a typical simulation, synapses are
generated as needed during the simulation.
"""
function Brain(
    area_sizes::Array{Int, 1},
    assembly_sizes::Array{Int, 1},
    plasticities::Array{T, 1},
    synapse_probs::Array{T, 1}
) where T
    zipped_args = zip(area_sizes, assembly_sizes, plasticities, synapse_probs)
    areas = [PartialArea(args...) for args in zipped_args]
    brain_areas = Brain(areas, collect(1:length(areas)))
    return brain_areas
end

"""Creates a `Brain` type with generative synapses. That is, because the
majority of synapses are not used in a typical simulation, synapses are
generated as needed during the simulation.

This is the classic assembly calculus model where number of neurons `n`,
assembly size 'k', plasticity 'β' and synapse probability `p` is the same across
all areas.
"""
function Brain(;
    num_areas::Int = 1,
    n::Int = 10000,
    k::Int = 100,
    β::T = 0.01,
    p::T = 0.01
) where T
    int_args = map(x -> repeat(x, num_areas), [[n], [k]])
    float_args = map(x -> repeat(x, num_areas), [[β], [p]])
    return Brain(int_args..., float_args...)
end


text:
################################################################################
# Stamps
################################################################################

################################################################################
# Type Definition
################################################################################

abstract type AbstractStamp
end

mutable struct CStamp <: AbstractStamp
	dim::Symbol # dimension (:v or :h)
	con::Symbol # name of the constraint
	i::Int      # player i index
	j::Int      # player j index
	k::Int      # time index k
end

################################################################################
# Base functions
################################################################################

import Base.hash
import Base.==
import Base.isequal

Base.hash(stamp::CStamp, h::UInt)  = hash(stamp.dim, hash(stamp.con, hash(stamp.i, hash(stamp.j, hash(stamp.k, h)))))

function (==)(stamp1::CStamp, stamp2::CStamp)
    out = true
	for name in CStamp.name.names
        out &= getfield(stamp1, name) == getfield(stamp2, name)
    end
    return out
end

Base.isequal(stamp1::CStamp, stamp2::CStamp) = stamp1 == stamp2

################################################################################
# Methods
################################################################################

function CStamp()
	return CStamp(:x, :x, 0, 0, 0)
end

function stampify(dim::Symbol, con::Symbol, i::Int, j::Int, k::Int)
	return CStamp(dim,con,i,j,k)
end

function stampify!(stamp::CStamp, dim::Symbol, con::Symbol, i::Int, j::Int, k::Int)
	stamp.dim = dim
	stamp.con = con
	stamp.i = i
	stamp.j = j
	stamp.k = k
	return nothing
end

################################################################################
# Stamp Validity
################################################################################

function valid(s::CStamp, N::Int, p::Int)
	b = false
	if s.dim == :v # Vertical
		if s.i < s.j
			if s.i ∈ (1:p) && s.j ∈ (1:p) && s.k ∈ (2:N)
				return true
			end
		end
	elseif s.dim == :h # Horizontal
		if s.i ∈ (1:p) && s.j ∈ (1:p) && s.k ∈ (2:N) && s.i != s.j
			return true
		end
	else
		@show "Error invalid dim Symbol."
	end
	return b
end


text:
struct FixedPolicy <: BanditPolicy
    a::Int64
end

function choose(x::Vector{Float64}, policy::FixedPolicy)
    return policy.a
end

function update!(pol::FixedPolicy, x::Vector{Float64}, a::Int64, r::Float64)
    nothing
end


text:
using Revise
using PyPlot
using Infiltrator
using LinearAlgebra
using Bem2d

"""
    plotparticular(g, rho, lambda, mu)

Plot fundamental particular fields
"""
function plotparticular(g, rho, lambda, mu)
    npts = 100
    x, y = obsgrid(-20000, -20000, 20000, 20000, npts)
    Up, Sp = gravityparticularfunctions(x, y, g, rho, lambda, mu)
    figure(figsize=(20, 10))
    subplot(2, 3, 1)
    contourf(reshape(x, npts, npts), reshape(y, npts, npts), reshape(Up[:, 1], npts, npts), 50)
    colorbar()
    gca().set_aspect("equal")
    title("ux")
    subplot(2, 3, 2)
    contourf(reshape(x, npts, npts), reshape(y, npts, npts), reshape(Up[:, 2], npts, npts), 50)
    colorbar()
    gca().set_aspect("equal")
    title("uy")
    subplot(2, 3, 4)
    contourf(reshape(x, npts, npts), reshape(y, npts, npts), reshape(Sp[:, 1], npts, npts), 50)
    colorbar()
    gca().set_aspect("equal")
    title("Sxx")
    subplot(2, 3, 5)
    contourf(reshape(x, npts, npts), reshape(y, npts, npts), reshape(Sp[:, 2], npts, npts), 50)
    colorbar()
    gca().set_aspect("equal")
    title("Syy")
    subplot(2, 3, 6)
    contourf(reshape(x, npts, npts), reshape(y, npts, npts), reshape(Sp[:, 3], npts, npts), 50)
    colorbar()
    gca().set_aspect("equal")
    title("Sxy")
end

"""
    gravitysquareparticular()

Experiments with gravity body force.
"""
function gravitysquareparticular()
    # TODO: It's strange that the top of the model has to be at zero.  Can we generalize this?
    # TODO: Make a version of gravityparticularfunctions() for BC generation

    close("all")

    fontsize = 20
    mu = 3e10
    lambda = 3e10
    nu = 0.25
    rho = 2700
    g = 9.81
    nels = 20
    npts = 100
    L = 1e4
    offset = 10
    x, y = obsgrid(-L+offset, -2*L+offset, L-offset, 0-offset, npts)

    plotparticular(g, rho, lambda, mu)

    # Define BEM geometry
    els = Elements(Int(1e5))
    x1, y1, x2, y2 = discretizedline(-L, -2*L, L, -2*L, nels) # Bottom
    addelsez!(els, x1, y1, x2, y2, "B")
    x1, y1, x2, y2 = discretizedline(L, -2*L, L, 0, nels) # Right hand side
    addelsez!(els, x1, y1, x2, y2, "R")
    x1, y1, x2, y2 = discretizedline(L, 0, -L, 0, nels) # Top
    addelsez!(els, x1, y1, x2, y2, "T")
    x1, y1, x2, y2 = discretizedline(-L, 0, -L, -2*L, nels) # Left hand side
    addelsez!(els, x1, y1, x2, y2, "L")

    # Common indexing
    idx = getidxdict(els) # Should this return "all" - YES TODO
    bcidxU = idx["B"] # Boundaries with *displacement* BCs
    bcidxT = [idx["R"] ; idx["T"]; idx["L"]] # Boundaries with *traction* BCs
    bcidxall = collect(1:1:els.endidx) # All boundaries

    # Gravity square problem with quadratic elements
    T_pU_qall, _ = PUTQ(slip2dispstress, els, bcidxU, bcidxall, mu, nu)
    _, H_pT_qall = PUTQ(slip2dispstress, els, bcidxT, bcidxall, mu, nu)
    TH = [T_pU_qall ; H_pT_qall] # Assemble combined linear operator

    # Particular solution and effective boundary conditions
    xnodes = transpose(els.xnodes[idx["B"], :])[:]
    ynodes = transpose(els.ynodes[idx["B"], :])[:]
    UB, _ = gravityparticularfunctions(xnodes, ynodes, g, rho, lambda, mu)
    bcs = zeros(6 * els.endidx)
    bcs[1:2:6*nels] = UB[:, 1] # Bottom boundary (x-component)
    bcs[2:2:6*nels] = UB[:, 2] # Bottom boundary (y-component)
    bcs *= -1 # This is neccesary for the right answer and is consistent with derivation

    # BEM solve to get particular solution
    Ueffparticular = inv(TH) * bcs

    # Evaluate and plot interior solution
    Uinteriorcomplementary, Sinteriorcomplementary = quaddispstress(slip2dispstress, x, y, els, bcidxall, quadstack(Ueffparticular[1:2:end]), quadstack(Ueffparticular[2:2:end]), mu, nu)
    Uinteriorparticular, Sinteriorparticular = gravityparticularfunctions(x, y, g, rho, lambda, mu)
    U = @. Uinteriorcomplementary + Uinteriorparticular
    S = @. Sinteriorcomplementary + Sinteriorparticular
    Umag = sqrt.(U[:, 1].^2 + U[:, 2].^2)

    figure()
    contourf(reshape(x, npts, npts), reshape(y, npts, npts), reshape(Umag, npts, npts), 50)
    colorbar()
    gca().set_aspect("equal")
    title("BEM - below ground")

    #####
    ##### Now with top of box not at zero
    #####
    # New observaiton coordinates
    x, y = obsgrid(-L+offset, 0, L-offset, 2*L-offset, npts)
    num = -2*L
    num = 0
    y = y .+ num
    elsbox = Elements(Int(1e5))
    x1, y1, x2, y2 = discretizedline(-L, 0+num, L, 0+num, nels) # Bottom
    addelsez!(elsbox, x1, y1, x2, y2, "B")
    x1, y1, x2, y2 = discretizedline(L, 0+num, L, 2*L+num, nels) # Right hand side
    addelsez!(elsbox, x1, y1, x2, y2, "R")
    x1, y1, x2, y2 = discretizedline(L, 2*L+num, -L, 2*L+num, nels) # Top
    addelsez!(elsbox, x1, y1, x2, y2, "T")
    x1, y1, x2, y2 = discretizedline(-L, 2*L+num, -L, 0+num, nels) # Left hand side
    addelsez!(elsbox, x1, y1, x2, y2, "L")

    # Common indexing
    idxbox = getidxdict(elsbox) # Should this return "all" - YES TODO
    bcidxU = idxbox["B"] # Boundaries with *displacement* BCs
    bcidxT = [idxbox["R"] ; idxbox["T"]; idxbox["L"]] # Boundaries with *traction* BCs
    bcidxall = collect(1:1:elsbox.endidx) # All boundaries

    T_B_BRTL, H_B_BRTL = PUTC(slip2dispstress, elsbox, idxbox["B"],
                              [idxbox["B"] ; idxbox["R"] ; idxbox["T"] ; idxbox["L"]],
                              mu, nu)
    T_R_BRTL, H_R_BRTL = PUTC(slip2dispstress, elsbox, idxbox["R"],
                              [idxbox["B"] ; idxbox["R"] ; idxbox["T"] ; idxbox["L"]],
                              mu, nu)
    T_L_BRTL, H_L_BRTL = PUTC(slip2dispstress, elsbox, idxbox["L"],
                              [idxbox["B"] ; idxbox["R"] ; idxbox["T"] ; idxbox["L"]],
                              mu, nu)
    T_T_BRTL, H_T_BRTL = PUTC(slip2dispstress, elsbox, idxbox["T"],
                              [idxbox["B"] ; idxbox["R"] ; idxbox["T"] ; idxbox["L"]],
                              mu, nu)
    THbox = [T_B_BRTL ; H_R_BRTL; H_T_BRTL ; H_L_BRTL]

    # Displacement BCs for bottom
    Ugabove, Sgabove = gravityparticularfunctions(elsbox.xcenter[idxbox["B"]],
                                                  elsbox.ycenter[idxbox["B"]],
                                                  g, rho, lambda, mu)
    bcsboxgravity = zeros(2 * elsbox.endidx)
    bcsboxgravity[1:2:2*nels] = Ugabove[:, 1]
    bcsboxgravity[2:2:2*nels] = Ugabove[:, 2]

    # Traction BCs for top and sides
    # Ug, Sg = gravityparticularfunctions(elsbox.xcenter[idxbox["T"]],
    #                                     elsbox.ycenter[idxbox["T"]],
    #                                     g, rho, lambda, mu)
    # Ttx = zeros(nels)
    # Tty = zeros(nels)
    # for i in 1:length(Sg[:, 1])
    #     nvec = [elsbox.xnormal[idxbox["T"][i]] ; elsbox.ynormal[idxbox["T"][i]]]
    #     temp = [Sg[i, 1] Sg[i, 3] ; Sg[i, 3] Sg[i, 2]] * nvec
    #     Ttx[i] = temp[1]
    #     Tty[i] = temp[2]
    # end
    # bcsboxgravity[4*nels+1:2:6*nels] = Ttx
    # bcsboxgravity[4*nels+2:2:6*nels] = Tty
    bcsboxgravity *= -1
    Ueffboxparticular = THbox \ bcsboxgravity

    # Forward solution on grid
    Ucomp, Scomp = constdispstress(slip2dispstress, x, y, elsbox,
                                   [idxbox["B"] ; idxbox["R"] ; idxbox["T"] ; idxbox["L"]],
                                   Ueffboxparticular[1:2:end], Ueffboxparticular[2:2:end], mu, nu)
    Uint, Sint = gravityparticularfunctions(x, y, g, rho, lambda, mu)
    Ugravityonly = @. Ucomp + Uint
    Sgravityonly = @. Scomp + Sint
    bemaboveumag = sqrt.(Ugravityonly[:, 1].^2 + Ugravityonly[:, 2].^2)

    figure();
    contourf(reshape(x, npts, npts), reshape(y, npts, npts),
             reshape(bemaboveumag, npts, npts), 50)
    colorbar()
    gca().set_aspect("equal")
    title("BEM - above ground")
end
gravitysquareparticular()


text:
#
# Fast Nearest Neighbor Search on python using kd-tree
#
# author: Atsushi Sakai
#

module jufastnns

using NearestNeighbors
using PyCall

@pyimport matplotlib.pyplot as plt

function printmat(A)
    for i in 1:length(A[1,:])
        println(A[:,i])
    end
end

function test_3d()
    data3d = rand(3, 5000)
    # print(data3d)

    input3d = rand((3, 3))
    # print(input3d)

    kdtree = KDTree(data3d)

    idxs, dists = knn(kdtree, input3d, 1)
    println(idxs)
    println(dists)

end

function test()
    data2d = rand((2, 5000))
    # printmat(data2d)

    input2d = rand((2, 3))
    # printmat(input2d)

    kdtree = KDTree(data2d)

    idxs, dists = knn(kdtree, input2d, 1)
    println(idxs)
    println(dists)

    plt.plot(data2d[1, :], data2d[2, :], ".r")
    plt.plot(input2d[1,:], input2d[2, :], "xk")
    plt.plot([data2d[1, i] for i in idxs], [data2d[2, i] for i in idxs], "xb")
    plt.show()
end

function main()
    println(PROGRAM_FILE," start!!")
    test()
    test_3d()
    println(PROGRAM_FILE," Done!!")
end

if contains(@__FILE__, PROGRAM_FILE)
    @time main()
end

end

max_stars_repo_name: AtsushiSakai/jufastnns

max_issues_repo_name: AtsushiSakai/jufastnns

max_forks_repo_name: AtsushiSakai/jufastnns


text:
module TransientFEToolsTests

using Test

@testset "TransientFETests" begin include("TransientFETests.jl") end

@testset "TransientFEOperatorsTests" begin include("TransientFEOperatorsTests.jl") end

@testset "AffineFEOperatorsTests" begin include("AffineFEOperatorsTests.jl") end

@testset "ConstantFEOperatorsTests" begin include("ConstantFEOperatorsTests.jl") end

@testset "HeatEquationTests" begin include("HeatEquationTests.jl") end

@testset "HeatVectorEquationTests" begin include("HeatVectorEquationTests.jl") end

@testset "VectorHeatEquationTests" begin include("VectorHeatEquationTests.jl") end

@testset "StokesEquationTests" begin include("StokesEquationTests.jl") end

@testset "BoundaryEquationTests" begin include("BoundaryHeatEquationTests.jl") end

@testset "DGHeatEquationTests" begin include("DGHeatEquationTests.jl") end

end # module


text:
module HackerNewsAnalysis

export fetch_top_stories, fetch_story, fetch_story_details, take, logx
export Story

export average_score
export average_score2
export average_score3

using HTTP
using JSON3
using Statistics
using Dates
using Formatting

# Container for a story. Underlying data is a Dict from parsing JSON.
struct Story
    by::String
    descendants::Union{Nothing,Int}
    score::Int
    time::Int
    id::Int
    title::String
    kids::Union{Nothing,Vector{Int}}
    url::Union{Nothing,String}
end

# Construct a Story from a Dict (or Dict-compatible) object
function Story(obj)
    value = (x) -> get(obj, x, nothing)
    return Story(
        obj[:by],
        value(:descendants),
        obj[:score],
        obj[:time],
        obj[:id],
        obj[:title],
        value(:kids),
        value(:url))
end

# Find top 500 stories from HackerNews.  Returns an array of story id's.
function fetch_top_stories()
    url = "https://hacker-news.firebaseio.com/v0/topstories.json"
    response = HTTP.request("GET", url)
    return JSON3.read(response.body)
end

# Get a specific story item
function fetch_story(id)
    url = "https://hacker-news.firebaseio.com/v0/item/$(id).json"
    response = HTTP.request("GET", url)
    return Story(JSON3.read(response.body))
end

# average score of recent discussions
function average_score(n = 10)
    story_ids = fetch_top_stories()
    println(now(), " Found ", length(story_ids), " stories")

    top_stories = [fetch_story(id) for id in story_ids[1:min(n,end)]]
    println(now(), " Fetched ", n, " story details")

    avg_top_scores = mean(s.score for s in top_stories)
    println(now(), " Average score = ", avg_top_scores)

    return avg_top_scores
end

# code is pretty busy
# refactoring to smaller functions and make them pipe-friendly (i.e. single argument)

take(n::Int) = xs -> xs[1:min(n,end)]

fetch_story_details(ids::Vector{Int}) = fetch_story.(ids)

calculate_average_score(stories::Vector{Story}) = mean(s.score for s in stories)

# without logging
average_score2(n = 10) =
    fetch_top_stories() |>
    take(n) |>
    fetch_story_details |>
    calculate_average_score

# pipe friendly logging facility
logx(fmt::AbstractString, f::Function = identity) = x -> begin
    let y = f(x)
        print(now(), " ")
        printfmtln(fmt, y)
    end
    return x
end

# functional pipe including logging
average_score3(n = 10) =
    fetch_top_stories()                         |>
    logx("Number of top stories = {}", length)  |>
    take(n)                                     |>
    logx("Limited number of stories = $n")      |>
    fetch_story_details                         |>
    logx("Fetched story details")               |>
    calculate_average_score                     |>
    logx("Average score = {}")

# conditional logic
check_hotness(n = 10) =
    average_score3(n) |> hotness |> celebrate

hotness(score) = score > 100 ? Val(:high) : Val(:low)
celebrate(v::Val{:high}) = logx("Woohoo! Lots of hot topics!")(v)
celebrate(v::Val{:low}) = logx("It's just a normal day...")(v)

end # module


text:
# indicator of a point

immutable IndPoint{T <: Union{Real, Complex, AbstractArray}} <: IndicatorConvex
  p::T
  function IndPoint(p::T)
    new(p)
  end
end

"""
  IndPoint(p=0.0)

Returns the function `g = ind{x = p}`. Parameter `p` can be
either a scalar or an array of the same dimension as the function argument.
"""

IndPoint{T <: Union{Real, Complex, AbstractArray}}(p::T=0.0) = IndPoint{T}(p)

function (f::IndPoint){T <: RealOrComplex}(x::AbstractArray{T})
  if vecnorm(x-f.p, Inf) > 1e-14
    return +Inf
  end
  return 0.0
end

function prox!{T <: RealOrComplex}(f::IndPoint, x::AbstractArray{T}, y::AbstractArray{T}, gamma::Real=1.0)
  y[:] = f.p
  return 0.0
end

fun_name(f::IndPoint) = "indicator of a point"
fun_dom(f::IndPoint) = "AbstractArray{Real}, AbstractArray{Complex}"
fun_expr(f::IndPoint) = "x ↦ 0 if x = p, +∞ otherwise"
fun_params(f::IndPoint) =
  string( "p = ", typeof(f.p) <: AbstractArray ? string(typeof(f.p), " of size ", size(f.p)) : f.p, ", ")

function prox_naive{T <: RealOrComplex}(f::IndPoint, x::AbstractArray{T}, gamma::Real=1.0)
  return f.p, 0.0
end


text:
# steering angle model test
function threeDOFv1_test1(n)
  t0 = 0.0; tf = 20.0; t = Vector(linspace(t0,tf,100));
  U = zeros(length(t),2)
  sa(tt) = 0.15*sin(3*tt)
  U[:,1] = sa.(t)
  U[:,2] = 10.0
  X0 = [0.0, 0.0, 0.0, 0.0, 1.2038]
  sol, U = ThreeDOFv1(n,Vector(X0),t,U,t0,tf)
  actual = sol(sol.t[end])
  expected = [40.8714, 195.019, -0.170866, -0.0139167, 1.5131]
  A = zeros(length(actual))
  for i in 1:length(expected)
    A[i] = abs(expected[i]-actual[i])
  end
  return maximum(A)
end

# steering rate test
function threeDOFv2_test1(n)
  t0 = 0.0; tf = 20.0; t = Vector(linspace(t0,tf,100));
  U = zeros(length(t),2)
  sr(tt) = 0.45*cos(3*tt)
  U[:,1] = sr.(t)
  X0 = [0.0, 0.0, 0.0, 0.0, 1.2038, 0.0, 10.0, 0.0]
  sol, U = ThreeDOFv2(n,Vector(X0),t,U,t0,tf)
  actual = sol(sol.t[end])
  expected = [40.0552,195.17,-0.169685,-0.0114604,1.53446,-0.0439371,10.0,0.0]
  A = zeros(length(actual))
  for i in 1:length(expected)
    A[i] = abs(expected[i]-actual[i])
  end
  return maximum(A)
end

# constant speed test
function threeDOFv3_test1(n)
  t0 = 0.0; tf = 20.0; t = Vector(linspace(t0,tf,100));
  U = zeros(length(t),1)
  sr(tt) = 0.45*cos(3*tt)
  U[:,1] = sr.(t)
  X0 = [0.0, 0.0, 0.0, 0.0, 1.2038, 0.0, 10.0, 0.0]
  sol, U = ThreeDOFv3(n,Vector(X0),t,U,t0,tf)
  actual = sol(sol.t[end])
  expected = [24.2734,297.962,-1.18412,0.102708,1.70372,-0.0468365,10.0,0.0]
  A = zeros(length(actual))
  for i in 1:length(expected)
    A[i] = abs(expected[i]-actual[i])
  end
  return maximum(A)
end

@testset "threeDOF" begin
    n = NLOpt(); # constructor for test
    n.ocp.params = [Vpara()];
    @test threeDOFv1_test1(n) ≈ 0 atol=tol
    @test threeDOFv2_test1(n) ≈ 0 atol=tol
    @test threeDOFv3_test1(n) ≈ 0 atol=tol
end


text:
### ADDITION ###

"""
    adc(c_in, a, b)

    Calculates the sum of carry_in, a and b and returns their sum as well as an UInt8 for carry_out.
"""
function adc(c_in, a::ArbDigit, b::ArbDigit)
    s = DoubleArbDigit(a) + DoubleArbDigit(b) + DoubleArbDigit(c_in)
    hi, lo = fromDoubleArbDigit(s)
    lo, hi
end

function _add2!(a::AbstractVector{ArbDigit}, b::AbstractVector{ArbDigit})
    @assert length(a) >= length(b) "length(a) == $(length(a)) < $(length(b)) == length(b), should be >="
    a_lo = @view a[begin:length(b)]
    a_hi = @view a[length(b)+1:end]

    carry = zero(ArbDigit)
    @inbounds for (i,(a_el,b_el)) in enumerate(zip(a_lo, b))
        a_lo[i], carry = adc(carry, a_el, b_el)
    end

    if !iszero(carry)
        carry = _add2!(a_hi, carry)
    end

    carry
end

function _add2!(a::AbstractVector{ArbDigit}, carry)
    for (i,a_el) in enumerate(a)
        # TODO: can we do this faster, without going up in size?
        a[i], carry = adc(carry, a_el, zero(ArbDigit))
        iszero(carry) && break
    end

    carry
end

function add2!(a::AbstractVector{ArbDigit}, b::AbstractVector{ArbDigit})
    carry = _add2!(a, b)
    @assert iszero(carry)
end

"""
    add!(a, b)

    Adds b to a, saving the result in a. Returns a.
"""
function add! end

function add!(a::ArbUInt, b::ArbUInt)
    a_len = length(a.data)
    carry = if a_len < length(b.data)
        lo_carry = _add2!(a.data, @view(b.data[1:a_len]))
        append!(a.data, @view(b.data[a_len+1:end]))
        _add2!(@view(a.data[a_len+1:end]), lo_carry)
    else
        _add2!(a.data, b.data)
    end
    if !iszero(carry)
        push!(a.data, carry)
    end
    a
end

function add!(a::ArbUInt, b::ArbDigit)
    iszero(b) && return a
    if isempty(a.data)
        push!(a.data, b)
        return a
    end
    carry = _add2!(a.data, b)
    !iszero(carry) && push!(a.data, carry)
    a
end

function add!(a::ArbUInt, b::DoubleArbDigit)
    hi, lo = fromDoubleArbDigit(b)
    if iszero(hi)
        add!(a, lo)
    else
        while length(a.data) < 2
            push!(a.data, 0)
        end

        # TODO: get rid of this allocation
        carry = _add2!(a.data, [lo, hi])
        !iszero(carry) && push!(a.data, carry)
    end
    a
end

# define the 128 bit method if we have 32 bit digits
if DoubleArbDigit === UInt64
    function add!(a::ArbUInt, b::UInt128)
        if b <= typemax(UInt64)
            add!(a, UInt64(b))
        else
            a,b,c,d = u32_from_u128(b)
            carry = if a > 0
                while length(a.data) < 4
                    push!(a.data, 0)
                end
                _add2!(a.data, [d, c, b, a])
            else
                @assert b > 0
                while length(a.data) < 3
                    push!(a.data, 0)
                end
                _add2!(a.data, [d, c, b])
            end

            !iszero(carry) && push!(a.data, carry)
        end
        a
    end
end

# fallback gracefully to copying interface
Base.:(+)(a::DoubleArbDigit, b::ArbUInt) = add!(deepcopy(b), a)
Base.:(+)(a::ArbUInt, b::DoubleArbDigit) = add!(deepcopy(a), b)
Base.:(+)(a::Unsigned, b::ArbUInt) = add!(deepcopy(b), convert(ArbDigit, a))
Base.:(+)(a::ArbUInt, b::Unsigned) = add!(deepcopy(a), convert(ArbDigit, b))
Base.:(+)(a::ArbUInt, b::ArbUInt) = length(a.data) >= length(b.data) ? add!(deepcopy(a), b) : add!(deepcopy(b), a)
Base.:(+)(b::Signed, a::ArbUInt) = +(a,b)
Base.:(+)(_::ArbUInt, b::BigInt) = throw(ArgumentError("addition with BigInt not implemented"))
function Base.:(+)(a::ArbUInt, b::Signed)
    if b < 0
        a - abs(b)
    else
        a + unsigned(b)
    end
end

function (::Type{T})(x::ArbUInt) where T<:Base.BitUnsigned
    if iszero(x)
        return zero(T)
    elseif isone(length(x.data))
        return convert(T, x.data[1])
    else
        throw(InexactError(nameof(T), T, x))
    end
end

function (::Type{T})(x::ArbUInt) where T<:Base.BitSigned
    if iszero(x)
        return zero(T)
    elseif isone(length(x.data))
        return convert(T, x.data[1])
    else
        throw(InexactError(nameof(T), T, x))
    end
end


text:
# automatically generated by the FlatBuffers compiler, do not modify

NamespaceA.eval(quote

import .NamespaceB

FlatBuffers.@with_kw mutable struct TableInFirstNS
    foo_table::Union{NamespaceB.TableInNestedNS, Nothing} = nothing
    foo_enum::NamespaceB.EnumInNestedNS = 0
    foo_struct::Union{NamespaceB.StructInNestedNS, Nothing} = nothing
end
FlatBuffers.@ALIGN(TableInFirstNS, 1)
FlatBuffers.slot_offsets(::Type{T}) where {T<:TableInFirstNS} = [
    0x00000004, 0x00000006, 0x00000008
]

TableInFirstNS(buf::AbstractVector{UInt8}) = FlatBuffers.read(TableInFirstNS, buf)
TableInFirstNS(io::IO) = FlatBuffers.deserialize(io, TableInFirstNS)

end)

max_stars_repo_name: rjkat/flatbuffers-julia

max_issues_repo_name: rjkat/flatbuffers-julia

max_forks_repo_name: rjkat/flatbuffers-julia


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

import Test
Test.@testset "Package ParallelProcessingTools" begin
    @info "Testing with $(Base.Threads.nthreads()) Julia threads."

    include("test_threadsafe.jl")
    include("test_threadlocal.jl")
    include("test_workpartition.jl")
    include("test_onthreads.jl")
    include("test_onprocs.jl")
end


text:
using MLFS
using Test
using PrettyPrint
using Setfield
using MLFS.HM
using Debugger

# @testset "MLFS.jl" begin
#     t = Surf.TArrow(Surf.TVar(:Int), Surf.TVar(:Int))
     g = empty(GlobalTC)
     l = empty(LocalTC)

     l = @set l.typeEnv = l.typeEnv[
         [
         :Int => T(Nom(:int64)),
         :Str => T(Nom(:str)),
         :f => Arrow(Nom(:int64), Nom(:int64))
         ]
     ]

     l = @set l.symmap = l.symmap[
             :f => :f_0xa1
         ]

t1 = inferType(g, l, @surf_type Fn[a, (Int, a)] where a)
t2 = inferType(g, l, @surf_type Fn[a, Fn[b, (a, b)] where b] where a)
st = g.tcstate
v = st.new_tvar()
t1 = Arrow(v, t1)

t2_inst = st.instantiate(t2)
println(t2_inst)

println(st.unifyINST(t1, t2_inst))

@enter st.unifyINST(t1, t2_inst)


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

name = "ZLibBuilder"
version = v"1.2.11"

# Collection of sources required to build ZLibBuilder
sources = [
    "https://zlib.net/zlib-$(version).tar.gz" =>
    "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1",

]

# Bash recipe for building across all platforms
script = raw"""
cd $WORKSPACE/srcdir/zlib-1.2.11/

if [[ ${target} == *-w64-mingw* ]]; then
    EXTRA_CONFIGURE_FLAGS="--sharedlibdir=${prefix}/bin"
    EXTRA_MAKE_FLAGS="SHAREDLIB=libz.dll SHAREDLIBM=libz-1.dll SHAREDLIBV=libz-1.2.11.dll LDSHAREDLIBC= "
fi

./configure ${EXTRA_CONFIGURE_FLAGS} --prefix=$prefix

make install ${EXTRA_MAKE_FLAGS} -j${nproc}

if [[ ${target} == *-w64-mingw* ]]; then
    mkdir ${WORKSPACE}/destdir/tmp
    cp -L ${WORKSPACE}/destdir/bin/* ${WORKSPACE}/destdir/tmp
    rm -r ${WORKSPACE}/destdir/bin
    mv ${WORKSPACE}/destdir/tmp ${WORKSPACE}/destdir/bin
fi

"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = [
    Linux(:i686, libc=:glibc),
    Linux(:x86_64, libc=:glibc),
    Linux(:aarch64, libc=:glibc),
    Linux(:armv7l, libc=:glibc, call_abi=:eabihf),
    Linux(:powerpc64le, libc=:glibc),
    Linux(:i686, libc=:musl),
    Linux(:x86_64, libc=:musl),
    Linux(:aarch64, libc=:musl),
    Linux(:armv7l, libc=:musl, call_abi=:eabihf),
    MacOS(:x86_64),
    FreeBSD(:x86_64),
    Windows(:i686),
    Windows(:x86_64)
]

# The products that we will ensure are always built
products(prefix) = [
    LibraryProduct(prefix, "libz", :libz)
]

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

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

max_stars_repo_name: BenJWard/ZLibBuilder

max_issues_repo_name: BenJWard/ZLibBuilder

max_forks_repo_name: BenJWard/ZLibBuilder