text:
### A Pluto.jl notebook ###
# v0.15.1

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing
        el
    end
end

# ╔═╡ 1b7462c4-1262-4b2b-9f72-ccabdba4ced4
begin
	using Agents
	using DataFrames
	using Distributions
	using GraphPlot
	using LightGraphs
	using Plots
	using PlutoUI
	using Clustering
	using Colors
end

# ╔═╡ 32a4f2d0-af4e-11eb-2ac9-4982b44dfc85
md"# Potential Binge Drinker Models"

# ╔═╡ 2aa5708e-9d31-405f-805a-3c0ebc78bea8
md"## Social Drinker
$\frac{ds}{dt} = s_{\text{slope}}s + m(t)$

$\frac{dp}{dt}  = \gamma[-p + \sigma\,(a s + b)]$

$s(t_i) \leftarrow s(t_i) - s_{drink} \quad \text{if } t_i \in e$

Where $c$ represents craving, $p$ represents probability of drinking (if alcohol is encountered), $m(t)$ is given and represents mood, and $e$ is a given set of encounter times. Together these equations model a healthy individual's drinking behavior. Adjust the sliders below to see how the different comnbinations of parameters affect drinking behavior.

IMPORTANT: *Uncheck the Run Parameters box when adjusting parameters.* Otherwise the notebook will attempt to run every combination of parameters the sliders pass through. This will kill the kernel. Insummary,

1. Uncheck to adjust parmaeter values
2. check to run
3. 🍺 to run again.
"

# ╔═╡ 50eb8165-87ab-42d6-a6b4-39419a98885f
md"Run Parameters: $(@bind run CheckBox())

`s_slope`: $(@bind s_slope Slider(-3.5:0.25:.5, default=-1.0)) `s_drink`: $(@bind s_drink Slider(-5.0:0.1:1.0, default=-.5))

`gamma`: $(@bind gamma Slider(.5:0.5:20.0, default=5.0)) `a`: $(@bind a Slider(.5:0.5:20.0, default=10.0))`b`: $(@bind b Slider(-5:0.05:5, default=0.0))
"

# ╔═╡ 2c1971cf-4208-4e09-8b6e-d6198ac468c1
md"""Run again: $(@bind runagain Button(" 🍺 "))

`s_slope = ` $(s_slope)   `s_drink =` $(s_drink) `gamma =` $(gamma) `a =` $a `b =` $b"""

# ╔═╡ f292ae07-57e2-4ca7-a2cb-03613b296832
md"## Binge Drinker 1
$\frac{ds}{dt} = (m(t) + s_{slope})*s - m(t)$

$\frac{dp}{dt}  = \gamma[-p + \sigma\,(a s + b)]$

$s(t_i) \leftarrow s(t_i) - s_{drink} \quad \text{if } t_i \in e$

Where $c$ represents craving, $p$ represents probability of drinking (if alcohol is encountered), $m(t)$ is given and represents mood, and $e$ is a given set of encounter times. Together these equations model a healthy individual's drinking behavior. Adjust the sliders below to see how the different comnbinations of parameters affect drinking behavior.

When drinking produces another opportunity to drink, this model produces binge period at the peak of negative mood followed by long periods of no drinking. However, we may be able to recreate this with an even less modified social drinker model.
"

# ╔═╡ 1ab8e236-58ee-4e40-9f97-55e0c00d6ded
md"Run Parameters: $(@bind run_b1 CheckBox())

`s_slope`: $(@bind s_slope_b1 Slider(-3.5:0.25:.5, default=-1.0)) `s_drink`: $(@bind s_drink_b1 Slider(-5.0:0.1:1.0, default=-.5))

`gamma`: $(@bind gamma_b1 Slider(.5:0.5:20.0, default=5.0)) `a`: $(@bind a_b1 Slider(.5:0.5:20.0, default=10.0))`b`: $(@bind b_b1 Slider(-5:0.05:5, default=0.0))
"

# ╔═╡ 9cd31936-8cf8-42f9-9cdd-3c3d13368732
md"""$(@bind runagain_b1 Button(" 🍺 ")) `s_slope = ` $(s_slope_b1)   `s_drink =` $(s_drink_b1) `gamma =` $(gamma_b1) `a =`: $a_b1 `b =`: $b_b1"""

# ╔═╡ e68e62f6-291a-4696-9849-b420a44ae5d8
md"## Social Drinker with Self Edges
For this model we will just explore the social drinker, with self edges.
"

# ╔═╡ 789a7cd6-0b5d-402a-ba56-c59b72fd5f34
md"Run Parameters: $(@bind run_b2 CheckBox())

`s_slope`: $(@bind s_slope_b2 Slider(-3.5:0.25:.5, default=-1.0)) `s_drink`: $(@bind s_drink_b2 Slider(-5.0:0.1:1.0, default=-.5))

`gamma`: $(@bind gamma_b2 Slider(.5:0.5:20.0, default=5.0)) `a`: $(@bind a_b2 Slider(.5:0.5:20.0, default=10.0))`b`: $(@bind b_b2 Slider(-5:0.05:5, default=0.0))
"

# ╔═╡ f33c8ad4-c9b3-4d13-9859-1154a399bd13
md"""$(@bind runagain_b2 Button(" 🍺 ")) `s_slope = ` $(s_slope_b2)   `s_drink =` $(s_drink_b2) `gamma =` $(gamma_b2) `a =`: $a `b =`: $b"""

# ╔═╡ e1d857cc-0750-4a61-bab9-ea927e676de5
md"# Simulation Backend"

# ╔═╡ fffd8aaa-5c57-47b2-a385-c8a782dc0c16
md"#### Plotting and Analysis"

# ╔═╡ b8fe39e4-142c-4bdc-969c-1cb8196cf6be
function plot_agent(i::Int, adf::DataFrame, mdf::DataFrame)
    ai = filter(:id => ==(i), adf)
    sp = plot(mdf.t, ai.s, color=:pink, linewidth=2, label="Social Propensity", legend=(.85, .8))
    maxtime = round(mdf.t[end])
    title!("$maxtime Days of Drinking Behavior")
    pp = plot(mdf.t, ai.p, color=:darkblue, alpha=.7, linewidth=2, label="Probability of Drinking", legend=(.85, .8))
    ylims!(-.1, 1.1)
    yticks!([0, 1])
    dp = plot(mdf.t, ai.e, color=:orange, alpha=.7, linewidth=2, label="Drinking opportunities")
    plot!(mdf.t, ai.d, color=:green, linewidth=2, label="Drinking Behavior", legend=(.85, .8))
    ylims!(-.2, 1.2)
    yticks!([0, 1], ["Abstain", "Drink"])
    p = plot(sp, pp, dp, layout=(3, 1), size=(1000,375))
    return p
end

# ╔═╡ 6e96c87b-d115-4278-9652-c1e7733d7d5a
function drinking_stats(i::Int, adf::DataFrame, mdf::DataFrame)
    aidf = filter(:id => ==(i), adf)
    totdrinks = sum(aidf.d)
    totenc = sum(aidf.e)
    meanprob = mean(aidf.p)
    return totdrinks, totenc, meanprob
end

# ╔═╡ c1401ec8-749c-4259-9e90-b924281d67d0
function raster_plot(adf::DataFrame; starttime=0.0, dt=0.001, opportunites=false)
    drinks = filter(:d => ==(1.0), adf)
    dtimes = drinks.step .* dt
    p = plot(dtimes, drinks.id, seriestype=:scatter, alpha=0.7, color=:green, label="Drinks")
    if opportunites
        opps = filter(:e => ==(1.0), adf)
        optimes = opps.step .* dt
        plot!(opptimes, opps.id)
    end
    ylabel!("Person Id")
    xlabel!("Time")
    return p
end

# ╔═╡ cb1f0cc2-09d9-41fa-a5cb-ec5785c2ac79
md"#### Model"

# ╔═╡ 8987cb85-ad0e-4c0d-92eb-ca28211f842b
function nightlife(
		newdrinker,
		drinker_args...;
		npeople=2,
		adj=[0. 1.; 1. 0.],
		starttime=0.0,
		maxtime=30.0,
		dt=.001
)
    space = GraphSpace(Graph(1)) # Dummy space to place agents
    properties = Dict(
		:t => starttime,
		:dt => dt,
		:adj => adj,
		:npeople => npeople
	)
	atype = typeof(newdrinker(1, drinker_args...))
    model = AgentBasedModel(atype, space; properties)
    for i in 1:npeople
        add_agent!(newdrinker(i, drinker_args...), model)
    end
    return model
end

# ╔═╡ 490cee2e-03b2-456b-a3eb-25e618641e85
"""
People are coupled in the model in the following way: If I drink, each of my neighbors in the supplied social network is given an **opportunity** to drink at the next timestep. That is, if I drink at time `e`, we add `t+dt` to each neighbor's set of drinking opportunities `e`.
"""
function model_step!(model)
    drinks = [model[i].d for i in 1:model.npeople]
    drink_influence = model.adj * drinks .> 0.0
    for id in findall(drink_influence)
        push!(model[id].events, model.t + model.dt)
    end
    model.t += model.dt
end

# ╔═╡ abb21b69-4bae-4677-a688-77f63837512e
abstract type AbstractDrinker <: AbstractAgent end

# ╔═╡ 972739e8-8b77-40c7-86b6-334fc7063f01
md"#### Social Drinker Definition"

# ╔═╡ a28665f5-fcd0-4ecc-bd8d-5f11aabc43f8
md"#### Mood and Event Time Generators"

# ╔═╡ 71970b0d-8c5d-4ee3-8c10-fcfab9a83165
"""
    random_event_times(end_time::T; start_time:T=0.0; dist::Distribution=Exponential, distparams=[1.0]) where T=Float64 ->

Returns an array of event times where t_i - t_(i-1) is distributed according to
`dist`.

**Parameters**

1. `end_time` maximum length of time to simulate. All returned event times
will be strictly less than this value
2. `start_time` Initial time. Defaults to zero. All events will be
strictly between start_time and max_time
3. `scale` Parameter for the exponential distribution
**Returns**

`event_times` An array of event times with values between start_time and end_time.
The distance between events is exponentially distributed with parameter `scale`.
"""
function random_event_times(
        end_time::Float64;
        start_time::Float64=0.0,
        dist::Type=Exponential,
        distparams::Array{Float64, 1}=[1.0]
)
    event_times::Array{Float64, 1} = []
    current_event = start_time
    d = dist(distparams...)
    while current_event < end_time
        next_event = current_event + rand(d)
        push!(event_times, next_event)
        current_event = next_event
    end
    return event_times
end

# ╔═╡ 9782145c-6d5e-46a8-a1f1-eb6eef8f5c38
"""
    random_phase_sin(freq) -> func

Creates a sin function with frequency `freq` and random phase.
"""
function random_phase_sin(freq::Float64)
    a = rand()
    func = t::Float64 -> sin(2π*freq*(t - a))
    return func
end

# ╔═╡ 94eaf0c6-f033-4307-af65-b510109b4099
begin
	mutable struct SocialDrinker{F, T} <: AbstractAgent
	    id::Int
	    pos::Int
	    s::T
	    p::T
	    d::T
	    e::T
	    m::F
	    s_slope::T
	    s_drink::T
	    γ::T
	    a::T
	    b::T
	    events::Array{T, 1}
	end

	SocialDrinker(id, maxdays, freq) =
	    SocialDrinker(id, 0, 0.0, 0.0, 0.0, 0.0, random_phase_sin(1.0), -1., -.5, 3.0, 10.0, 0.0, random_event_times(maxdays))
end

# ╔═╡ 23847cd0-62cb-4ceb-9fe2-8d6108dd428b
begin
	newsocialdrinker(i, maxdays, frequency) =
		SocialDrinker(i, 0, 0.0, 0.0, 0.0, 0.0, random_phase_sin(1.0), Float64(s_slope), Float64(s_drink), Float64(gamma), Float64(a), Float64(b), random_event_times(maxdays));
end

# ╔═╡ 9d1f083f-694c-49a5-9240-6014568ab636
begin
	loopsocialdrinker(i, maxdays, frequency) =
		SocialDrinker(i, 0, 0.0, 0.0, 0.0, 0.0, random_phase_sin(frequency), Float64(s_slope_b2), Float64(s_drink_b2), Float64(gamma_b2), Float64(a_b2), Float64(b_b2), random_event_times(maxdays));
end

# ╔═╡ fa45763e-3266-470d-ba25-ff390e195e53
function Base.show(io::IO, sd::SocialDrinker)
    descr = "SocialDrinker"
    print(io, descr)
end

# ╔═╡ 3193f227-6b84-4dcb-8052-13a2fe4c3ca3
function Base.show(io::IO, a::Array{SocialDrinker, N}) where N
    descr = "Array{SocialDrinker, $N}"
    print(io, descr)
end

# ╔═╡ 24b718e0-1422-4c87-bc0a-557365686786
""" Social drinker response to drinking event """
function event_step!(sd::SocialDrinker)
    sd.e = 1.0
    if rand() < sd.p
        sd.d = 1.0
        sd.s += sd.s_drink
    end
end

# ╔═╡ 8f03a92c-7a6a-4bc7-807b-47fa783bebb8
md"#### Social Drinker"

# ╔═╡ 4eba4025-6b50-47a8-90fc-809c9c338111
""" Sigmoid function """
σ(x::T) where T = 1. / (1. + exp(-x))

# ╔═╡ 3bc63396-d9c9-4a5b-9401-405f0e707cd8
""" Derivative of social drinking propensity """
dsdt(s::T, t::T, s_slope::T, s_drink::T, m::F) where {F, T <: AbstractFloat} = s_slope * s + m(t)

# ╔═╡ f0cc3675-8c66-4f84-a9f3-8e40d97725bd
""" Deriviative of drinking probability """
dpdt(p::T, t::T, a::T, b::T, γ::T, s::T) where T = γ * (-p + σ(a * s + b))

# ╔═╡ e7c2b71b-7e3a-47eb-ae1a-e08ce58dbc3a
""" Return true if current timestep contains an event time """
event(events::Array{T, 1}, t::T, dt::T) where T = any((events .< t + dt) .& (events .>= t))

# ╔═╡ ef9cd36d-9381-41a6-9296-7f632c362ca2
md"#### Runge Kutta:"

# ╔═╡ 31d86d28-393a-42d6-b81e-a13b8bd43e9a
"""
	rk4_step(f::F, y::T, t::T, dt::T; params::Array{T, 1}=[]) -> dy

Returns the fourth order runge-kutta approximation of the change in `y` over the
timestep `dt`

### Parameters
1. `f` (callable) accepts `y`, `t` and all of the parameters in `params`
2. `y` current system state
3. `t` time value
4. `dt` timestep size
5. `params` parameters for `f`

### Returns
`dy` approximation of the change in `y` over the timestep `dt`
"""
function rk4_step(f::F, y::T, t::T, dt::T; params=[]) where {F, T <: AbstractFloat}
	two = convert(T, 2)
	dy1 = f(y, t, params...) * dt
	dy2 = f(y + dy1 / two, t + dt / two, params...) * dt
	dy3 = f(y + dy2 / two, t + dt / two, params...) * dt
	dy4 = f(y + dy3, t + dt, params...) * dt
	dy = convert(T, 1/6) * (dy1 + dy2 * two + dy3 * two + dy4)
	return dy
end

# ╔═╡ 515e90b9-986c-473e-a877-087601c3de3f
function rk4_step(f::F, y::Array{T,1}, t::T, dt::T; params=[]) where {F, T <: AbstractFloat}
	two = convert(T, 2)
	dy1 = f(y, t, params...) .* dt
	dy2 = f(y .+ dy1 ./ two, t .+ dt ./ two, params...) * dt
	dy3 = f(y .+ dy2 ./ two, t .+ dt ./ two, params...) * dt
	dy4 = f(y .+ dy3, t .+ dt, params...) * dt
	dy = convert(T, 1/6) .* (dy1 .+ dy2 .* two .+ dy3 .* two .+ dy4)
	return dy
end

# ╔═╡ cce89ff5-dc37-41fc-b996-509db481c78b
begin
	struct BingeDrinker1{T, F}
		id::Int
	    pos::Int
	    s::T
	    p::T
	    d::T
	    e::T
	    m::F
	    s_slope::T
	    s_drink::T
	    γ::T
	    a::T
	    b::T
	    events::Array{T, 1}
	end

	BingeDrinker1(i, maxdays, frequency) =
		SocialDrinker(i, 0, 0.0, 0.0, 0.0, 0.0, random_phase_sin(frequency), Float64(s_slope_b1), Float64(s_drink_b1), Float64(gamma_b1), Float64(a_b1), Float64(b_b1), random_event_times(maxdays));

	function Base.show(io::IO, sd::BingeDrinker1)
		descr = "BingeDrinker1"
		print(io, descr)
	end
	function Base.show(io::IO, a::Array{BingeDrinker1, N}) where N
		descr = "Array{BingeDrinker1, $N}"
		print(io, descr)
	end

	"""
	    agent_step!(sd::SocialDrinker, model::AgentBasedModel)

	The social drinker acts during a timestep. First, social drinking propensity
	and drinking probability are evolved according to their respective ODE, then
	if the agent has a drinking opportunity during this timestep, they drink with
	probability `sd.p`.
	"""
	function agent_step!(sd::BingeDrinker1, model::AgentBasedModel)
	    # Agent did not drink yet during this timestep
	    sd.d = 0.0
	    sd.e = 0.0
	    # Update internal state
	    sd.s += rk4_step(dsdt_b1, sd.s, model.t, model.dt, params=[sd.s_slope, sd.s_drink, sd.m])
	    sd.p += rk4_step(dpdt, sd.p, model.t, model.dt, params=[sd.a, sd.b, sd.γ, sd.s])
	    event(sd.events, model.t, model.dt) && event_step!(sd)
	end

	""" Social drinker response to drinking event """
	function event_step!(sd::BingeDrinker1)
	    sd.e = 1.0
	    if rand() < sd.p
	        sd.d = 1.0
	        sd.s += sd.s_drink
	    end
	end

	""" Binge drinker 1 propensity to drink """
	dsdt_b1(s::T, t::T, s_slope::T, s_drink::T, m::F) where {F, T <: AbstractFloat} = (m(t) + s_slope) * s - m(t)
end

# ╔═╡ 1f4921ef-c846-4f25-8a1e-90d8924475cf
"""
    agent_step!(sd::SocialDrinker, model::AgentBasedModel)

The social drinker acts during a timestep. First, social drinking propensity
and drinking probability are evolved according to their respective ODE, then
if the agent has a drinking opportunity during this timestep, they drink with
probability `sd.p`.
"""
function agent_step!(sd::SocialDrinker, model::AgentBasedModel)
    # Agent did not drink yet during this timestep
    sd.d = 0.0
    sd.e = 0.0
    # Update internal state
    sd.s += rk4_step(dsdt, sd.s, model.t, model.dt, params=[sd.s_slope, sd.s_drink, sd.m])
    sd.p += rk4_step(dpdt, sd.p, model.t, model.dt, params=[sd.a, sd.b, sd.γ, sd.s])
    event(sd.events, model.t, model.dt) && event_step!(sd)
end

# ╔═╡ a8039d3a-a7b5-4bd9-8afc-d8dfc886c0c8
"""
    simulate_drinker(drinkerinit, maxdays, drink_prms...; self_edge=0.0, dt=.001) -> single_adf, single_mdf, plt
Wrapper for creating a model with a single drinker
"""
function simulate_drinker(drinkerinit, maxdays, drink_prms...; self_edge=0.0, dt=.001)
	adata = [:s, :p, :d, :e]
	mdata = [:t]
	n = floor(Int, maxdays / dt)
	single_adj = reshape([self_edge], 1, 1)
	single_nl = nightlife(drinkerinit, maxdays, drink_prms..., maxtime=maxdays, npeople=1, adj=single_adj);
	single_adf, single_mdf = run!(single_nl, agent_step!, model_step!, n; adata, mdata);
	p = plot_agent(1, single_adf, single_mdf)
	return single_adf, single_mdf, p
end

# ╔═╡ 668b85bc-82d7-4f5e-b573-dd2145838c36
begin
	runagain
	if run
		maxdays = 30.0
		single_adf, single_mdf, p = simulate_drinker(newsocialdrinker, maxdays, 1.0)
		p
	end

end

# ╔═╡ 4f8af319-abd7-4a3b-9b4d-20423555f28a
begin
	if run
		td, te, mprob = drinking_stats(1, single_adf, single_mdf)
		Markdown.parse(
	"    Total Drinks:     $td (Per day = $(td/maxdays))

		Total Encounters: $te (Per day = $(te/maxdays))

		Drinks/Encounter: $(td/te)

		Mean of Prob:     $mprob"
		)
	end
end

# ╔═╡ c6bee36e-a1f4-4dd8-85da-49991bfd0a3d
begin
	runagain_b1
	if run_b1
		maxdays_b1 = 30.0
		frequency_b1 = 1.0
		single_adf_b1, single_mdf_b1, p_b1 = simulate_drinker(BingeDrinker1, maxdays_b1, frequency_b1, self_edge=1.0)
		p_b1
	end
end

# ╔═╡ 3a7b4bdb-36b3-49c4-a02f-9903c3b2512c
begin
	if run_b1
		td_b1, te_b1, mprob_b1 = drinking_stats(1, single_adf_b1, single_mdf_b1)
		Markdown.parse(
	"    Total Drinks:     $td_b1 (Per day = $(td_b1/maxdays_b1))

		Total Encounters: $te_b1 (Per day = $(te_b1/maxdays_b1))

		Drinks/Encounter: $(td_b1/te_b1)

		Mean of Prob:     $mprob_b1"
		)
	end
end

# ╔═╡ 017ad140-f21d-4046-8027-bc247ef67bcf
begin
	runagain_b2
	if run_b2
		maxdays_b2 = 30.0
		frequency_b2 = 1.0
		single_adf_b2, single_mdf_b2, p_b2 = simulate_drinker(loopsocialdrinker, maxdays_b2, frequency_b2; self_edge=1.0)
		p_b2
	end

end

# ╔═╡ c7cfa751-1f50-4c28-bdfa-130c31df06c5
begin
	if run_b2
		td_b2, te_b2, mprob_b2 = drinking_stats(1, single_adf_b2, single_mdf_b2)
		Markdown.parse(
	"    Total Drinks:     $td_b2 (Per day = $(td_b2/maxdays_b2))

		Total Encounters: $te_b2 (Per day = $(te_b2/maxdays_b2))

		Drinks/Encounter: $(td_b2/te_b2)

		Mean of Prob:     $mprob_b2"
		)
	end
end

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
Agents = "46ada45e-f475-11e8-01d0-f70cc89e6671"
Clustering = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
GraphPlot = "a2cc645c-3eea-5389-862e-a155d0052231"
LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"

[compat]
Agents = "~4.5.4"
Clustering = "~0.14.2"
Colors = "~0.12.8"
DataFrames = "~1.2.2"
Distributions = "~0.25.16"
GraphPlot = "~0.4.4"
LightGraphs = "~1.3.5"
Plots = "~1.21.3"
PlutoUI = "~0.7.9"
"""

# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised

[[AbstractTrees]]
git-tree-sha1 = "03e0550477d86222521d254b741d470ba17ea0b5"
uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
version = "0.3.4"

[[Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "84918055d15b3114ede17ac6a7182f68870c16f7"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.1"

[[Agents]]
deps = ["CSV", "DataFrames", "DataStructures", "Distributed", "GraphRecipes", "JLD2", "LightGraphs", "LinearAlgebra", "OpenStreetMapX", "ProgressMeter", "Random", "RecipesBase", "Requires", "Scratch", "StatsBase"]
git-tree-sha1 = "7cc7d221f4e00fe17ec5777950d6056a673b299c"
uuid = "46ada45e-f475-11e8-01d0-f70cc89e6671"
version = "4.5.4"

[[ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"

[[ArnoldiMethod]]
deps = ["LinearAlgebra", "Random", "StaticArrays"]
git-tree-sha1 = "f87e559f87a45bece9c9ed97458d3afe98b1ebb9"
uuid = "ec485272-7323-5ecc-a04f-4719b315124d"
version = "0.1.0"

[[Artifacts]]
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"

[[AxisAlgorithms]]
deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"]
git-tree-sha1 = "a4d07a1c313392a77042855df46c5f534076fab9"
uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950"
version = "1.0.0"

[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.8+0"

[[CSV]]
deps = ["Dates", "Mmap", "Parsers", "PooledArrays", "SentinelArrays", "Tables", "Unicode"]
git-tree-sha1 = "b83aa3f513be680454437a0eee21001607e5d983"
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
version = "0.8.5"

[[Cairo_jll]]
deps = ["Artifacts", "Bzip2_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "f2202b55d816427cd385a9a4f3ffb226bee80f99"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.1+0"

[[ChainRulesCore]]
deps = ["Compat", "LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "bdc0937269321858ab2a4f288486cb258b9a0af7"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.3.0"

[[Clustering]]
deps = ["Distances", "LinearAlgebra", "NearestNeighbors", "Printf", "SparseArrays", "Statistics", "StatsBase"]
git-tree-sha1 = "75479b7df4167267d75294d14b58244695beb2ac"
uuid = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5"
version = "0.14.2"

[[CodecZlib]]
deps = ["TranscodingStreams", "Zlib_jll"]
git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da"
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
version = "0.7.0"

[[ColorSchemes]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random"]
git-tree-sha1 = "9995eb3977fbf67b86d0a0a0508e83017ded03f2"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.14.0"

[[ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "32a2b8af383f11cbb65803883837a149d10dfe8a"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.10.12"

[[Colors]]
deps = ["ColorTypes", "FixedPointNumbers", "Reexport"]
git-tree-sha1 = "417b0ed7b8b838aa6ca0a87aadf1bb9eb111ce40"
uuid = "5ae59095-9a9b-59fe-a467-6f913c188581"
version = "0.12.8"

[[Compat]]
deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"]
git-tree-sha1 = "727e463cfebd0c7b999bbf3e9e7e16f254b94193"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.34.0"

[[CompilerSupportLibraries_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"

[[Compose]]
deps = ["Base64", "Colors", "DataStructures", "Dates", "IterTools", "JSON", "LinearAlgebra", "Measures", "Printf", "Random", "Requires", "Statistics", "UUIDs"]
git-tree-sha1 = "c6461fc7c35a4bb8d00905df7adafcff1fe3a6bc"
uuid = "a81c6b42-2e10-5240-aca2-a61377ecd94b"
version = "0.9.2"

[[Contour]]
deps = ["StaticArrays"]
git-tree-sha1 = "9f02045d934dc030edad45944ea80dbd1f0ebea7"
uuid = "d38c429a-6771-53c6-b99e-75d170b6e991"
version = "0.5.7"

[[Crayons]]
git-tree-sha1 = "3f71217b538d7aaee0b69ab47d9b7724ca8afa0d"
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
version = "4.0.4"

[[DataAPI]]
git-tree-sha1 = "ee400abb2298bd13bfc3df1c412ed228061a2385"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.7.0"

[[DataFrames]]
deps = ["Compat", "DataAPI", "Future", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrettyTables", "Printf", "REPL", "Reexport", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"]
git-tree-sha1 = "d785f42445b63fc86caa08bb9a9351008be9b765"
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
version = "1.2.2"

[[DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "7d9d316f04214f7efdbb6398d545446e246eff02"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.10"

[[DataValueInterfaces]]
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
version = "1.0.0"

[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[DelimitedFiles]]
deps = ["Mmap"]
uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"

[[Distances]]
deps = ["LinearAlgebra", "Statistics", "StatsAPI"]
git-tree-sha1 = "abe4ad222b26af3337262b8afb28fab8d215e9f8"
uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
version = "0.10.3"

[[Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[Distributions]]
deps = ["ChainRulesCore", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SparseArrays", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns"]
git-tree-sha1 = "f4efaa4b5157e0cdb8283ae0b5428bc9208436ed"
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
version = "0.25.16"

[[DocStringExtensions]]
deps = ["LibGit2"]
git-tree-sha1 = "a32185f5428d3986f47c2ab78b1f216d5e6cc96f"
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
version = "0.8.5"

[[Downloads]]
deps = ["ArgTools", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"

[[EarCut_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "3f3a2501fa7236e9b911e0f7a588c657e822bb6d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.2.3+0"

[[Expat_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b3bfd02e98aedfa5cf885665493c5598c350cd2f"
uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
version = "2.2.10+0"

[[FFMPEG]]
deps = ["FFMPEG_jll"]
git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8"
uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
version = "0.4.1"

[[FFMPEG_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "Pkg", "Zlib_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"]
git-tree-sha1 = "d8a578692e3077ac998b50c0217dfd67f21d1e5f"
uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
version = "4.4.0+0"

[[FileIO]]
deps = ["Pkg", "Requires", "UUIDs"]
git-tree-sha1 = "937c29268e405b6808d958a9ac41bfe1a31b08e7"
uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
version = "1.11.0"

[[FillArrays]]
deps = ["LinearAlgebra", "Random", "SparseArrays", "Statistics"]
git-tree-sha1 = "a3b7b041753094f3b17ffa9d2e2e07d8cace09cd"
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
version = "0.12.3"

[[FixedPointNumbers]]
deps = ["Statistics"]
git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc"
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
version = "0.8.4"

[[Fontconfig_jll]]
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.93+0"

[[Formatting]]
deps = ["Printf"]
git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8"
uuid = "59287772-0a20-5a39-b81b-1366585eb4c0"
version = "0.4.2"

[[FreeType2_jll]]
deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "87eb71354d8ec1a96d4a7636bd57a7347dde3ef9"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.4+0"

[[FriBidi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91"
uuid = "559328eb-81f9-559d-9380-de523a88c83c"
version = "1.0.10+0"

[[Future]]
deps = ["Random"]
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"

[[GLFW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"]
git-tree-sha1 = "dba1e8614e98949abfa60480b13653813d8f0157"
uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
version = "3.3.5+0"

[[GR]]
deps = ["Base64", "DelimitedFiles", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "Sockets", "Test", "UUIDs"]
git-tree-sha1 = "182da592436e287758ded5be6e32c406de3a2e47"
uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
version = "0.58.1"

[[GR_jll]]
deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Pkg", "Qt5Base_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "ef49a187604f865f4708c90e3f431890724e9012"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.59.0+0"

[[GeometryBasics]]
deps = ["EarCut_jll", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"]
git-tree-sha1 = "15ff9a14b9e1218958d3530cc288cf31465d9ae2"
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
version = "0.3.13"

[[GeometryTypes]]
deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "StaticArrays"]
git-tree-sha1 = "07194161fe4e181c6bf51ef2e329ec4e7d050fc4"
uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb"
version = "0.8.4"

[[Gettext_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046"
uuid = "78b55507-aeef-58d4-861c-77aaff3498b1"
version = "0.21.0+0"

[[Glib_jll]]
deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "7bf67e9a481712b3dbe9cb3dac852dc4b1162e02"
uuid = "7746bdde-850d-59dc-9ae8-88ece973131d"
version = "2.68.3+0"

[[GraphPlot]]
deps = ["ArnoldiMethod", "ColorTypes", "Colors", "Compose", "DelimitedFiles", "LightGraphs", "LinearAlgebra", "Random", "SparseArrays"]
git-tree-sha1 = "dd8f15128a91b0079dfe3f4a4a1e190e54ac7164"
uuid = "a2cc645c-3eea-5389-862e-a155d0052231"
version = "0.4.4"

[[GraphRecipes]]
deps = ["AbstractTrees", "GeometryTypes", "InteractiveUtils", "Interpolations", "LightGraphs", "LinearAlgebra", "NaNMath", "NetworkLayout", "PlotUtils", "RecipesBase", "SparseArrays", "Statistics"]
git-tree-sha1 = "7269dc06b8cd8d16fc2b1756cf7f41901bbc3c52"
uuid = "bd48cda9-67a9-57be-86fa-5b3c104eda73"
version = "0.5.7"

[[Graphite2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011"
uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472"
version = "1.3.14+0"

[[Grisu]]
git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2"
uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe"
version = "1.0.2"

[[HTTP]]
deps = ["Base64", "Dates", "IniFile", "MbedTLS", "Sockets"]
git-tree-sha1 = "c7ec02c4c6a039a98a15f955462cd7aea5df4508"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.8.19"

[[HarfBuzz_jll]]
deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"]
git-tree-sha1 = "8a954fed8ac097d5be04921d595f741115c1b2ad"
uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566"
version = "2.8.1+0"

[[Inflate]]
git-tree-sha1 = "f5fc07d4e706b84f72d54eedcc1c13d92fb0871c"
uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9"
version = "0.1.2"

[[IniFile]]
deps = ["Test"]
git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8"
uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
version = "0.5.0"

[[InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

[[Interpolations]]
deps = ["AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"]
git-tree-sha1 = "61aa005707ea2cebf47c8d780da8dc9bc4e0c512"
uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
version = "0.13.4"

[[InvertedIndices]]
deps = ["Test"]
git-tree-sha1 = "15732c475062348b0165684ffe28e85ea8396afc"
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
version = "1.0.0"

[[IrrationalConstants]]
git-tree-sha1 = "f76424439413893a832026ca355fe273e93bce94"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.1.0"

[[IterTools]]
git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.3.0"

[[IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[JLD2]]
deps = ["DataStructures", "FileIO", "MacroTools", "Mmap", "Pkg", "Printf", "Reexport", "TranscodingStreams", "UUIDs"]
git-tree-sha1 = "59ee430ac5dc87bc3eec833cc2a37853425750b4"
uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
version = "0.4.13"

[[JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "642a199af8b68253517b80bd3bfd17eb4e84df6e"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.3.0"

[[JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
git-tree-sha1 = "8076680b162ada2a031f707ac7b4953e30667a37"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.2"

[[JpegTurbo_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d735490ac75c5cb9f1b00d8b5509c11984dc6943"
uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8"
version = "2.1.0+0"

[[LAME_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c"
uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d"
version = "3.100.1+0"

[[LZO_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6"
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.1+0"

[[LaTeXStrings]]
git-tree-sha1 = "c7f1c695e06c01b95a67f0cd1d34994f3e7db104"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.2.1"

[[Latexify]]
deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "Printf", "Requires"]
git-tree-sha1 = "a4b12a1bd2ebade87891ab7e36fdbce582301a92"
uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
version = "0.15.6"

[[LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"

[[LibCURL_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"

[[LibExpat]]
deps = ["Expat_jll", "Pkg"]
git-tree-sha1 = "27dc51f94ceb107fd53b367431a638b430e01e81"
uuid = "522f3ed2-3f36-55e3-b6df-e94fee9b0c07"
version = "0.6.1"

[[LibGit2]]
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"

[[LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"

[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[Libffi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "761a393aeccd6aa92ec3515e428c26bf99575b3b"
uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490"
version = "3.2.2+0"

[[Libgcrypt_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"]
git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae"
uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4"
version = "1.8.7+0"

[[Libglvnd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"]
git-tree-sha1 = "7739f837d6447403596a75d19ed01fd08d6f56bf"
uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29"
version = "1.3.0+3"

[[Libgpg_error_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9"
uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8"
version = "1.42.0+0"

[[Libiconv_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "42b62845d70a619f063a7da093d995ec8e15e778"
uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
version = "1.16.1+1"

[[Libmount_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73"
uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9"
version = "2.35.0+0"

[[Libtiff_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"]
git-tree-sha1 = "340e257aada13f95f98ee352d316c3bed37c8ab9"
uuid = "89763e89-9b03-5906-acba-b20f662cd828"
version = "4.3.0+0"

[[Libuuid_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066"
uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700"
version = "2.36.0+0"

[[LightGraphs]]
deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"]
git-tree-sha1 = "432428df5f360964040ed60418dd5601ecd240b6"
uuid = "093fc24a-ae57-5d10-9952-331d41423f4d"
version = "1.3.5"

[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[[LogExpFunctions]]
deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "3d682c07e6dd250ed082f883dc88aee7996bf2cc"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.0"

[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[MacroTools]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "0fb723cd8c45858c22169b2e42269e53271a6df7"
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
version = "0.5.7"

[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[MbedTLS]]
deps = ["Dates", "MbedTLS_jll", "Random", "Sockets"]
git-tree-sha1 = "1c38e51c3d08ef2278062ebceade0e46cefc96fe"
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
version = "1.0.3"

[[MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"

[[Measures]]
git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f"
uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
version = "0.3.1"

[[Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "2ca267b08821e86c5ef4376cffed98a46c2cb205"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.1"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"

[[MozillaCACerts_jll]]
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"

[[NaNMath]]
git-tree-sha1 = "bfe47e760d60b82b66b61d2d44128b62e3a369fb"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "0.3.5"

[[NearestNeighbors]]
deps = ["Distances", "StaticArrays"]
git-tree-sha1 = "16baacfdc8758bc374882566c9187e785e85c2f0"
uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
version = "0.4.9"

[[NetworkLayout]]
deps = ["GeometryBasics", "LinearAlgebra", "Random", "Requires", "SparseArrays"]
git-tree-sha1 = "76bbbe01d2e582213e656688e63707d94aaadd15"
uuid = "46757867-2c16-5918-afeb-47bfcb05e46a"
version = "0.4.0"

[[NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"

[[OffsetArrays]]
deps = ["Adapt"]
git-tree-sha1 = "c870a0d713b51e4b49be6432eff0e26a4325afee"
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
version = "1.10.6"

[[Ogg_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7937eda4681660b4d6aeeecc2f7e1c81c8ee4e2f"
uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
version = "1.3.5+0"

[[OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "15003dcb7d8db3c6c857fda14891a539a8f2705a"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.10+0"

[[OpenSpecFun_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1"
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
version = "0.5.5+0"

[[OpenStreetMapX]]
deps = ["CodecZlib", "DataStructures", "HTTP", "JSON", "LibExpat", "LightGraphs", "ProtoBuf", "Random", "Serialization", "SparseArrays", "StableRNGs", "Statistics"]
git-tree-sha1 = "3b2496e723fa8b5220e4154b10b215419afc93dd"
uuid = "86cd37e6-c0ff-550b-95fe-21d72c8d4fc9"
version = "0.2.5"

[[Opus_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720"
uuid = "91d4177d-7536-5919-b921-800302f37372"
version = "1.3.2+0"

[[OrderedCollections]]
git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.4.1"

[[PCRE_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b2a7af664e098055a7529ad1a900ded962bca488"
uuid = "2f80f16e-611a-54ab-bc61-aa92de5b98fc"
version = "8.44.0+0"

[[PDMats]]
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
git-tree-sha1 = "4dd403333bcf0909341cfe57ec115152f937d7d8"
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
version = "0.11.1"

[[Parsers]]
deps = ["Dates"]
git-tree-sha1 = "bfd7d8c7fd87f04543810d9cbd3995972236ba1b"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "1.1.2"

[[Pixman_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b4f5d02549a10e20780a24fce72bea96b6329e29"
uuid = "30392449-352a-5448-841d-b1acce4e97dc"
version = "0.40.1+0"

[[Pkg]]
deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[PlotThemes]]
deps = ["PlotUtils", "Requires", "Statistics"]
git-tree-sha1 = "a3a964ce9dc7898193536002a6dd892b1b5a6f1d"
uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
version = "2.0.1"

[[PlotUtils]]
deps = ["ColorSchemes", "Colors", "Dates", "Printf", "Random", "Reexport", "Statistics"]
git-tree-sha1 = "9ff1c70190c1c30aebca35dc489f7411b256cd23"
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
version = "1.0.13"

[[Plots]]
deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "GeometryBasics", "JSON", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "PlotThemes", "PlotUtils", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs"]
git-tree-sha1 = "2dbafeadadcf7dadff20cd60046bba416b4912be"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
version = "1.21.3"

[[PlutoUI]]
deps = ["Base64", "Dates", "InteractiveUtils", "JSON", "Logging", "Markdown", "Random", "Reexport", "Suppressor"]
git-tree-sha1 = "44e225d5837e2a2345e69a1d1e01ac2443ff9fcb"
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
version = "0.7.9"

[[PooledArrays]]
deps = ["DataAPI", "Future"]
git-tree-sha1 = "a193d6ad9c45ada72c14b731a318bedd3c2f00cf"
uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
version = "1.3.0"

[[Preferences]]
deps = ["TOML"]
git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.2"

[[PrettyTables]]
deps = ["Crayons", "Formatting", "Markdown", "Reexport", "Tables"]
git-tree-sha1 = "0d1245a357cc61c8cd61934c07447aa569ff22e6"
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
version = "1.1.0"

[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[[ProgressMeter]]
deps = ["Distributed", "Printf"]
git-tree-sha1 = "afadeba63d90ff223a6a48d2009434ecee2ec9e8"
uuid = "92933f4c-e287-5a05-a399-4b506db050ca"
version = "1.7.1"

[[ProtoBuf]]
deps = ["Logging", "protoc_jll"]
git-tree-sha1 = "3142e13697a7f6363798d1241daf3e6cead83008"
uuid = "3349acd9-ac6a-5e09-bcdb-63829b23a429"
version = "0.11.2"

[[Qt5Base_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"]
git-tree-sha1 = "ad368663a5e20dbb8d6dc2fddeefe4dae0781ae8"
uuid = "ea2cea3b-5b76-57ae-a6ef-0a8af62496e1"
version = "5.15.3+0"

[[QuadGK]]
deps = ["DataStructures", "LinearAlgebra"]
git-tree-sha1 = "12fbe86da16df6679be7521dfb39fbc861e1dc7b"
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
version = "2.4.1"

[[REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[Ratios]]
deps = ["Requires"]
git-tree-sha1 = "7dff99fbc740e2f8228c6878e2aad6d7c2678098"
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
version = "0.4.1"

[[RecipesBase]]
git-tree-sha1 = "44a75aa7a527910ee3d1751d1f0e4148698add9e"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.1.2"

[[RecipesPipeline]]
deps = ["Dates", "NaNMath", "PlotUtils", "RecipesBase"]
git-tree-sha1 = "d4491becdc53580c6dadb0f6249f90caae888554"
uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c"
version = "0.4.0"

[[Reexport]]
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.2.2"

[[Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "4036a3bd08ac7e968e27c203d45f5fff15020621"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.1.3"

[[Rmath]]
deps = ["Random", "Rmath_jll"]
git-tree-sha1 = "bf3188feca147ce108c76ad82c2792c57abe7b1f"
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa"
version = "0.7.0"

[[Rmath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "68db32dff12bb6127bac73c209881191bf0efbb7"
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
version = "0.3.0+0"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Scratch]]
deps = ["Dates"]
git-tree-sha1 = "0b4b7f1393cff97c33891da2a0bf69c6ed241fda"
uuid = "6c6a2e73-6563-6170-7368-637461726353"
version = "1.1.0"

[[SentinelArrays]]
deps = ["Dates", "Random"]
git-tree-sha1 = "54f37736d8934a12a200edea2f9206b03bdf3159"
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
version = "1.3.7"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"

[[Showoff]]
deps = ["Dates", "Grisu"]
git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de"
uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
version = "1.0.3"

[[SimpleTraits]]
deps = ["InteractiveUtils", "MacroTools"]
git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231"
uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d"
version = "0.9.4"

[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

[[SortingAlgorithms]]
deps = ["DataStructures"]
git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508"
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
version = "1.0.1"

[[SparseArrays]]
deps = ["LinearAlgebra", "Random"]
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[SpecialFunctions]]
deps = ["ChainRulesCore", "LogExpFunctions", "OpenSpecFun_jll"]
git-tree-sha1 = "a322a9493e49c5f3a10b50df3aedaf1cdb3244b7"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "1.6.1"

[[StableRNGs]]
deps = ["Random", "Test"]
git-tree-sha1 = "3be7d49667040add7ee151fefaf1f8c04c8c8276"
uuid = "860ef19b-820b-49d6-a774-d7a799459cd3"
version = "1.0.0"

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "3240808c6d463ac46f1c1cd7638375cd22abbccb"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.12"

[[Statistics]]
deps = ["LinearAlgebra", "SparseArrays"]
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[[StatsAPI]]
git-tree-sha1 = "1958272568dc176a1d881acb797beb909c785510"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.0.0"

[[StatsBase]]
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "8cbbc098554648c84f79a463c9ff0fd277144b6c"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.33.10"

[[StatsFuns]]
deps = ["ChainRulesCore", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
git-tree-sha1 = "46d7ccc7104860c38b11966dd1f72ff042f382e4"
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
version = "0.9.10"

[[StructArrays]]
deps = ["Adapt", "DataAPI", "StaticArrays", "Tables"]
git-tree-sha1 = "1700b86ad59348c0f9f68ddc95117071f947072d"
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
version = "0.6.1"

[[SuiteSparse]]
deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"]
uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"

[[Suppressor]]
git-tree-sha1 = "a819d77f31f83e5792a76081eee1ea6342ab8787"
uuid = "fd094767-a336-5f1f-9728-57cf17d0bbfb"
version = "0.2.0"

[[TOML]]
deps = ["Dates"]
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

[[TableTraits]]
deps = ["IteratorInterfaceExtensions"]
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"

[[Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "TableTraits", "Test"]
git-tree-sha1 = "d0c690d37c73aeb5ca063056283fde5585a41710"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.5.0"

[[Tar]]
deps = ["ArgTools", "SHA"]
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"

[[Test]]
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[TranscodingStreams]]
deps = ["Random", "Test"]
git-tree-sha1 = "216b95ea110b5972db65aa90f88d8d89dcb8851c"
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
version = "0.9.6"

[[UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[[Wayland_jll]]
deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "3e61f0b86f90dacb0bc0e73a0c5a83f6a8636e23"
uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89"
version = "1.19.0+0"

[[Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll"]
git-tree-sha1 = "2839f1c1296940218e35df0bbb220f2a79686670"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.18.0+4"

[[WoodburyMatrices]]
deps = ["LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "59e2ad8fd1591ea019a5259bd012d7aee15f995c"
uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6"
version = "0.5.3"

[[XML2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "1acf5bdf07aa0907e0a37d3718bb88d4b687b74a"
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
version = "2.9.12+0"

[[XSLT_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"]
git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a"
uuid = "aed1982a-8fda-507f-9586-7b0439959a61"
version = "1.1.34+0"

[[Xorg_libX11_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"]
git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527"
uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc"
version = "1.6.9+4"

[[Xorg_libXau_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e"
uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec"
version = "1.0.9+4"

[[Xorg_libXcursor_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd"
uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724"
version = "1.2.0+4"

[[Xorg_libXdmcp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4"
uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05"
version = "1.1.3+4"

[[Xorg_libXext_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3"
uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3"
version = "1.3.4+4"

[[Xorg_libXfixes_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4"
uuid = "d091e8ba-531a-589c-9de9-94069b037ed8"
version = "5.0.3+4"

[[Xorg_libXi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"]
git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246"
uuid = "a51aa0fd-4e3c-5386-b890-e753decda492"
version = "1.7.10+4"

[[Xorg_libXinerama_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"]
git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123"
uuid = "d1454406-59df-5ea1-beac-c340f2130bc3"
version = "1.1.4+4"

[[Xorg_libXrandr_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631"
uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484"
version = "1.5.2+4"

[[Xorg_libXrender_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96"
uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa"
version = "0.9.10+4"

[[Xorg_libpthread_stubs_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb"
uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74"
version = "0.1.0+3"

[[Xorg_libxcb_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"]
git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6"
uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b"
version = "1.13.0+3"

[[Xorg_libxkbfile_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "926af861744212db0eb001d9e40b5d16292080b2"
uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a"
version = "1.1.0+4"

[[Xorg_xcb_util_image_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97"
uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b"
version = "0.4.0+1"

[[Xorg_xcb_util_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll"]
git-tree-sha1 = "e7fd7b2881fa2eaa72717420894d3938177862d1"
uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5"
version = "0.4.0+1"

[[Xorg_xcb_util_keysyms_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "d1151e2c45a544f32441a567d1690e701ec89b00"
uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7"
version = "0.4.0+1"

[[Xorg_xcb_util_renderutil_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "dfd7a8f38d4613b6a575253b3174dd991ca6183e"
uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e"
version = "0.3.9+1"

[[Xorg_xcb_util_wm_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "e78d10aab01a4a154142c5006ed44fd9e8e31b67"
uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361"
version = "0.4.1+1"

[[Xorg_xkbcomp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxkbfile_jll"]
git-tree-sha1 = "4bcbf660f6c2e714f87e960a171b119d06ee163b"
uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4"
version = "1.4.2+4"

[[Xorg_xkeyboard_config_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xkbcomp_jll"]
git-tree-sha1 = "5c8424f8a67c3f2209646d4425f3d415fee5931d"
uuid = "33bec58e-1273-512f-9401-5d533626f822"
version = "2.27.0+4"

[[Xorg_xtrans_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845"
uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10"
version = "1.4.0+3"

[[Zlib_jll]]
deps = ["Libdl"]
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"

[[Zstd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "cc4bf3fdde8b7e3e9fa0351bdeedba1cf3b7f6e6"
uuid = "3161d3a3-bdf6-5164-811a-617609db77b4"
version = "1.5.0+0"

[[libass_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47"
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
version = "0.15.1+0"

[[libfdk_aac_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55"
uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280"
version = "2.0.2+0"

[[libpng_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c"
uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f"
version = "1.6.38+0"

[[libvorbis_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"]
git-tree-sha1 = "c45f4e40e7aafe9d086379e5578947ec8b95a8fb"
uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a"
version = "1.3.7+0"

[[nghttp2_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"

[[p7zip_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"

[[protoc_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "89b92b537ffde09cab61ad20636da135d0791007"
uuid = "c7845625-083e-5bbe-8504-b32d602b7110"
version = "3.15.6+0"

[[x264_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2021.5.5+0"

[[x265_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9"
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
version = "3.5.0+0"

[[xkbcommon_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"]
git-tree-sha1 = "ece2350174195bb31de1a63bea3a41ae1aa593b6"
uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd"
version = "0.9.1+5"
"""

# ╔═╡ Cell order:
# ╟─32a4f2d0-af4e-11eb-2ac9-4982b44dfc85
# ╟─2aa5708e-9d31-405f-805a-3c0ebc78bea8
# ╟─50eb8165-87ab-42d6-a6b4-39419a98885f
# ╟─2c1971cf-4208-4e09-8b6e-d6198ac468c1
# ╟─668b85bc-82d7-4f5e-b573-dd2145838c36
# ╟─4f8af319-abd7-4a3b-9b4d-20423555f28a
# ╟─23847cd0-62cb-4ceb-9fe2-8d6108dd428b
# ╟─f292ae07-57e2-4ca7-a2cb-03613b296832
# ╟─1ab8e236-58ee-4e40-9f97-55e0c00d6ded
# ╟─9cd31936-8cf8-42f9-9cdd-3c3d13368732
# ╟─c6bee36e-a1f4-4dd8-85da-49991bfd0a3d
# ╟─3a7b4bdb-36b3-49c4-a02f-9903c3b2512c
# ╟─cce89ff5-dc37-41fc-b996-509db481c78b
# ╟─e68e62f6-291a-4696-9849-b420a44ae5d8
# ╟─789a7cd6-0b5d-402a-ba56-c59b72fd5f34
# ╟─f33c8ad4-c9b3-4d13-9859-1154a399bd13
# ╟─017ad140-f21d-4046-8027-bc247ef67bcf
# ╟─c7cfa751-1f50-4c28-bdfa-130c31df06c5
# ╟─9d1f083f-694c-49a5-9240-6014568ab636
# ╠═e1d857cc-0750-4a61-bab9-ea927e676de5
# ╠═fffd8aaa-5c57-47b2-a385-c8a782dc0c16
# ╠═b8fe39e4-142c-4bdc-969c-1cb8196cf6be
# ╠═6e96c87b-d115-4278-9652-c1e7733d7d5a
# ╠═c1401ec8-749c-4259-9e90-b924281d67d0
# ╟─cb1f0cc2-09d9-41fa-a5cb-ec5785c2ac79
# ╠═a8039d3a-a7b5-4bd9-8afc-d8dfc886c0c8
# ╠═8987cb85-ad0e-4c0d-92eb-ca28211f842b
# ╠═490cee2e-03b2-456b-a3eb-25e618641e85
# ╠═abb21b69-4bae-4677-a688-77f63837512e
# ╠═972739e8-8b77-40c7-86b6-334fc7063f01
# ╠═94eaf0c6-f033-4307-af65-b510109b4099
# ╠═fa45763e-3266-470d-ba25-ff390e195e53
# ╠═3193f227-6b84-4dcb-8052-13a2fe4c3ca3
# ╠═1f4921ef-c846-4f25-8a1e-90d8924475cf
# ╠═24b718e0-1422-4c87-bc0a-557365686786
# ╠═a28665f5-fcd0-4ecc-bd8d-5f11aabc43f8
# ╠═71970b0d-8c5d-4ee3-8c10-fcfab9a83165
# ╠═9782145c-6d5e-46a8-a1f1-eb6eef8f5c38
# ╠═8f03a92c-7a6a-4bc7-807b-47fa783bebb8
# ╠═4eba4025-6b50-47a8-90fc-809c9c338111
# ╠═3bc63396-d9c9-4a5b-9401-405f0e707cd8
# ╠═f0cc3675-8c66-4f84-a9f3-8e40d97725bd
# ╠═e7c2b71b-7e3a-47eb-ae1a-e08ce58dbc3a
# ╠═ef9cd36d-9381-41a6-9296-7f632c362ca2
# ╠═31d86d28-393a-42d6-b81e-a13b8bd43e9a
# ╠═515e90b9-986c-473e-a877-087601c3de3f
# ╠═1b7462c4-1262-4b2b-9f72-ccabdba4ced4
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_name: djpasseyjr/ShinePDMP

max_issues_repo_name: djpasseyjr/ShinePDMP

max_forks_repo_name: djpasseyjr/ShinePDMP


text:
module StatisticalRethinkingCommon

using Gen
using Statistics
import StatsBase
using StatsBase: fit, ZScoreTransform
using ProgressMeter

export vectorlist_to_matrix, vector_to_columnmatrix, vector_to_rowmatrix, standardize_columns, standardize_columns!, standardize_column, standardize_column!, sequential_sampling, sampling, mcmc, infer

function vectorlist_to_matrix(list_of_vectors)
    dim1 = length(list_of_vectors)
    dim2 = length(list_of_vectors[1])
    matrix_type = typeof(list_of_vectors[1][1])
    matrix = zeros(matrix_type, dim1, dim2)
    for i in 1:dim1
        for j in 1:dim2
            matrix[i,j] = list_of_vectors[i][j]
        end
    end
    return matrix
end

function vector_to_columnmatrix(vector)
    return reshape(vector, (length(vector), 1))
end

function vector_to_rowmatrix(vector)
    return reshape(vector, (1, length(vector)))
end

function standardize_columns(dataframe, columnsels; center=true, scale=true)
    new_dataframe = copy(dataframe)
    dts = standardize_columns!(new_dataframe, columnsels, center=center, scale=scale)
    return new_dataframe, dts
end

function standardize_columns!(dataframe, columnsels; center=true, scale=true)
    for columnsel in columnsels
        dts = standardize_column!(dataframe, columnsel, center=center, scale=scale)
    end
end

function standardize_column(dataframe, columnsel; center=true, scale=true)
    column = dataframe[:, columnsel]
    dt = fit(ZScoreTransform, column, dims=1, center=center, scale=scale)
    return Statsbase.transfrom(dt, column), dt
end

function standardize_column!(dataframe, columnsel; center=true, scale=true)
    column = dataframe[!, columnsel]
    dt = fit(ZScoreTransform, column, dims=1, center=center, scale=scale)
    dataframe[!, columnsel] = StatsBase.transform(dt, column)
    return dt
end

function sequential_sampling(model, modelargs=(), observations=Gen.EmptyChoiceMap(); steps=100, samples=1)
    return [Gen.importance_resampling(model, modelargs, observations, samples)[1] for _ in 1:steps]
end

function sampling(model, modelargs=(), observations=Gen.EmptyChoiceMap(); steps=100, samples=1, progress=nothing)
    if !isnothing(progress) && progress isa Bool && progress
        progress = Progress(steps * samples, desc="Sampling: " , showspeed=true)
    end
    lk = ReentrantLock()
    traces = []
    lml_ests = []
    Threads.@threads for _ in 1:steps
        trace,lml_est = Gen.importance_resampling(model, modelargs, observations, samples)
        lock(lk) do
            push!(traces, trace)
            push!(lml_ests, lml_est)
            if !isnothing(progress) && progress isa Progress
                update!(progress, samples)
            end
        end
    end

    if !isnothing(progress) && progress isa Progress
        finish!(progress)
    end
    return traces, lml_ests
end

function mcmc(model, modelargs=(), observations=Gen.EmptyChoiceMap(); selection=nothing, warmup=0, steps=100, kernel=Gen.mh, check=false, progress=nothing)
    trace, = Gen.generate(model, modelargs, observations)

    if !isnothing(progress) && progress isa Bool && progress
        progress = Progress(warmup + steps, desc="Prewarmup: " , showspeed=true)
    end

    if isnothing(selection)
        obs = []
        for (addr,) in Gen.get_values_shallow(observations)
            push!(obs, addr)
        end
        selection = Gen.complement(Gen.select(obs...))
    end

    if !isnothing(progress) && progress isa Progress
        update!(progress, 0, desc="Warmup:    ")
    end

    warmup_num_accepted = 0
    warmup_traces = []
    for _ in 1:warmup
        trace,accepted = kernel(trace, selection, observations=observations, check=check)
        push!(warmup_traces, trace)
        warmup_num_accepted += Int(accepted)
        if !isnothing(progress) && progress isa Progress
            next!(progress)
        end
    end

    if !isnothing(progress) && progress isa Progress
        update!(progress, 0, desc="MCMC:      ")
    end

    num_accepted = 0
    traces = []
    for _ in 1:steps
        trace,accepted = kernel(trace, selection, observations=observations, check=check)
        push!(traces, trace)
        num_accepted += Int(accepted)
        if !isnothing(progress) && progress isa Progress
            next!(progress)
        end
    end

    if !isnothing(progress) && progress isa Progress
        finish!(progress)
    end

    return traces, num_accepted, warmup_traces, warmup_num_accepted
end

function infer(traces, model, modelargs=(), parameter_addresses=(); combine=(p -> mean(p, dims=1)))
    choicemaps = Gen.get_choices.(traces)
    parameter_collection = []
    for (i, address) in enumerate(parameter_addresses)
        if i == 1
            parameter_collection = vector_to_columnmatrix(Gen.get_value.(choicemaps, address))
            continue
        end
        parameter_collection = hcat(parameter_collection, vector_to_columnmatrix(Gen.get_value.(choicemaps, address)))
    end
    parameters = combine(parameter_collection)
    constraints = Gen.choicemap()
    for (i,address) in enumerate(parameter_addresses)
        constraints[address] = parameters[i]
    end
    new_trace = Gen.generate(model, modelargs, constraints)
    return new_trace
end

end

ext: jl


text:
#===============================================================================

The number 512 is interesting because it is equal to the sum of its digits
raised to some power: 5 + 1 + 2 = 8, and 8^3 = 512. Another example of a number
with this property is 614656 = 28^4.

We shall define an to be the nth term of this sequence and insist that a number
must contain at least two digits to have a sum.

You are given that a2 = 512 and a10 = 614656.

Find a30.

--------------------------------------------------------------------------------

The solution is to build iteratively a table whose row and column indices
correspond respectively to the exponents and digit sums. The table is
semi-infinite in each direction (i.e. indices starts at 1 but are unlimited
otherwise).

At iteration n, all numbers up to 2^n (at least) are processed. Those that
fulfil the condition (col = digit_sum(col^row)) are inserted in order in a
queue.

The elements of the queue are returned in order. Once the queue is empty or if
the first element is greater than 2^n, then a new iteration is restarted.

===============================================================================#

import Base
using Base.Test

struct Item
    value :: Int64
    dsum  :: Int
    exp   :: Int
end

Item(dsum::Int, exp::Int) = Item(dsum^exp, dsum, exp)

index(item::Item) = item.dsum + item.exp

isvalid(item::Item) = sum(digits(item.value)) == item.dsum && item.value > 9

Base.isless(lhs::Item, rhs::Item) =  lhs.value < rhs.value

function insertSorted!(list, item)
    index = searchsortedfirst(list, item)
    insert!(list, index, item)
end

struct NumberIter end

mutable struct NumberIterState
    target :: Int
    borders :: Array{Item}
    queue :: Array{Item}
end

Base.start(::NumberIter) = NumberIterState(1, Item[Item(1, 1)], Item[])

function Base.next(::NumberIter, state)
    function populate()
        state.target *= 2

        # Extend existing rows
        for e in 2:length(state.borders) # e is the exponent
            item = state.borders[e]
            while item.value < state.target
                item = Item(item.dsum+1, e)
                if isvalid(item)
                    insertSorted!(state.queue, item)
                end
            end
            state.borders[e] = item
        end

        # Add a border
        push!(state.borders, Item(2, length(state.borders)+1))
    end

    while true
        if isempty(state.queue)
            populate()
        else
            item = shift!(state.queue)

            if item.value <= state.target
                return (item, state)
            else
                unshift!(state.queue, item)
                populate()
            end
        end
    end
end

Base.done(::NumberIter, state) = false

function Euler(limit)
    result = Int64[]
    for item in NumberIter()
        push!(result, item.value)
        if length(result) == limit
            return result
        end
    end
end

euler = Euler(30)

@test euler[2] == 512
@test euler[10] == 614656

println("Euler 0119: $(euler[30])")

max_stars_repo_name: dpieroux/euler

max_issues_repo_name: dpieroux/euler

max_forks_repo_name: dpieroux/euler


text:
## Functions that depend on the structure of BandedMatrix

function pad!(A::BandedMatrix,n,m)
    A.data = pad(A.data,size(A.data,1),m)
    A.raxis = Base.OneTo(n)
    A
end

# linear algebra

## Constructors that involve MultivariateFun
Fun(f::Fun) = f # Fun of Fun should be like a conversion

function Fun(fin::Function)
    f = dynamic(fin)

    if hasnumargs(f,1)
        # check for tuple
        try
            f(0)
        catch ex
            if isa(ex,BoundsError)
                # assume its a tuple
                return Fun(f,ChebyshevInterval()^2)
            else
                throw(ex)
            end
        end

        Fun(f,ChebyshevInterval())
    elseif hasnumargs(f,2)
            Fun(f,ChebyshevInterval()^2)
    else
        error("Function not defined on interval or square")
    end
end

## These hacks support PDEs with block matrices

## dot for AbstractVector{Number} * AbstractVector{Fun}

function dot(c::AbstractVector{T},f::AbstractVector{F}) where {T<:Union{Number,Fun,MultivariateFun},F<:Union{Fun,MultivariateFun}}
    @assert length(c)==length(f)
    ret = conj(first(c))*first(f)
    for k = 2:length(c)
        ret += conj(c[k])*f[k]
    end
    ret
end

function dotu(c::AbstractVector{T},f::AbstractVector{F}) where {T<:Union{Fun,MultivariateFun,Number},F<:Union{Fun,MultivariateFun,Number}}
    @assert length(c)==length(f)
    isempty(c) && return zero(Base.promote_op(*,T,F))
    ret = c[1]*f[1]
    for k = 2:length(c)
        ret += c[k]*f[k]
    end
    ret
end

## Gets blockbandwidths working for SpectralMeasures

# TODO: Is this a good definition?
blockbandwidths(T::FiniteOperator{AT,TT,SS1,SS2}) where {AT,TT,SS1<:Union{EuclideanSpace,SequenceSpace},
              SS2<:Union{EuclideanSpace,SequenceSpace}} = bandwidths(T)


text:
# simulates model performance and collects statistics

const ident_cs = [1e-1 0; 1e-2 0; 1e-3 0; 1e-4 0; 0 1e-4; 0 1e-3; 0 1e-2; 0 1e-1]
const categ_cs = [1.0 0.0; 0.8 0.2; 0.68 0.32; 0.56 0.44; 0.44 0.56; 0.32 0.68; 0.2 0.8; 0.0 1.0] * 0.1
const itlvd_cs = vcat(categ_cs, categ_cs * 0.1, categ_cs * 0.01, categ_cs * 0.001);
# loactions on x-axis (for plotting / psych curves)
const ident_xs = [-3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5]
const categ_xs = [0, 0.2, 0.32, 0.44, 0.56, 0.68, 0.8, 1.0]
const itlvd_xs = repeat(categ_xs, outer=[4])

# constructs evidence sequences out of base blocks by concatenating shuffled
# versions of the base block until the desired number of trials is reached.
function constructevidence(base_cs, base_ids, trials)
    base_n = size(base_cs, 1)
    @assert length(base_ids) == base_n
    blocks = ceil(Integer, trials / base_n)
    # first fill larger blocks, then truncate
    cs = similar(base_cs, blocks * base_n, size(base_cs, 2))
    ids = similar(base_ids, blocks * base_n)
    i = collect(1:base_n)
    for block_i = 1:blocks
        shuffle!(i)
        base_i = (block_i - 1) * base_n + 1
        cs[base_i:(base_i + base_n - 1), :] = base_cs[i, :]
        ids[base_i:(base_i + base_n - 1), :] = base_ids[i]
    end
    cs[1:trials, :], ids[1:trials]
end

# create full evidence block by first repeating each base block blockreps number
# of times, constructing a base number of trials. These are then concatenated
# with different shuffle orders, until 'trials' number of trials are reached
# (using constructevidence()). This is done for the two conditions separately,
# after which they are concatenated. Shuffling subblocks ensures an evenly
# spread out distribution of trials even for small numbers of trials.
function catevidence(ident_cs, categ_cs, blockreps, trials)
    ident_evidence, ident_ids = constructevidence(
        repeat(ident_cs, outer=[blockreps, 1]),
        repeat(collect(1:size(ident_cs, 1)), outer=[blockreps, 1]),
        trials)
    categ_evidence, categ_ids = constructevidence(
        repeat(categ_cs, outer=[blockreps, 1]),
        repeat(collect(1:size(categ_cs, 1)), outer=[blockreps, 1]),
        trials)
    return cat(ident_evidence, categ_evidence, dims=1), cat(ident_ids, categ_ids, dims=1)
end
# the same for the interleaved condition, without final concatenation
function catitlvdevidence(itlvd_cs, blockreps, trials)
    itlvd_evidence, itlvd_ids = constructevidence(
        repeat(itlvd_cs, outer=[blockreps, 1]),
        repeat(collect(1:size(itlvd_cs, 1)), outer=[blockreps, 1]),
        trials)
    return itlvd_evidence, itlvd_ids
end

# runs simulations with given evidence / stimulus id sequence, after
# which it splits results into two equally-sized blocks, each of which
# is returned as a DataFrame
function simmodel(m::ModelBase, ϕ::Vector{Float64}, evidence, ids)
    trials = length(ids)
    @assert size(evidence, 1) == trials
    @assert mod(trials, 2) == 0
    trials = div(trials, 2)

    resps, ts, gs = sim(m, ϕ, evidence)

    # determine correct replies by which-ever evidence is larger
    corrresps = convert(Vector{Int}, evidence[:,2] .> evidence[:,1])
    corr = resps .== corrresps

    # return results in two dataframes
    r1, r2 = 1:trials, (trials+1):(2*trials)
    stimmag = copy(ids)
    stimmag[stimmag .< 5] .= 9 .- stimmag[stimmag .< 5]
    previds = cat(ids[end], ids[1:end-1], dims=1)    # prev. before first is random
    prevcorr = cat(corr[end], corr[1:end-1], dims=1)
    return DataFrame(trial    = collect(r1),
              stimid   = ids[r1],
              previd   = previds[r1],
              stimmag  = stimmag[r1],
              corrresp = corrresps[r1],
              resp     = resps[r1],
              t        = ts[r1],
              conf     = gs[r1],
              corr     = corr[r1],
              prevcorr = prevcorr[r1],
              prevrew  = prevcorr[r1]),
    DataFrame(trial    = collect(r1),
              stimid   = ids[r2],
              previd   = previds[r2],
              stimmag  = stimmag[r2],
              corrresp = corrresps[r2],
              resp     = resps[r2],
              t        = ts[r2],
              conf     = gs[r2],
              corr     = corr[r2],
              prevcorr = prevcorr[r2],
              prevrew  = prevcorr[r2])
end
# same as simmodel() but for interleaved trials, without the block splitting
function simitlvdmodel(m::ModelBase, ϕ::Vector{Float64}, evidence, ids)
    trials = length(ids)
    @assert size(evidence, 1) == trials

    resps, ts, gs = sim(m, ϕ, evidence)

    # determine correct replies by which-ever evidence is larger
    corrresps = convert(Vector{Int}, evidence[:,2] .> evidence[:,1])
    corr = resps .== corrresps

    # collect results in DataFrame
    stimmag = Vector{Int}(undef, trials)
    mixw = Vector{Int}(undef, trials)
    mixmag = Vector{Int}(undef, trials)
    concentr = Vector{Int}(undef, trials)
    for i = 1:4  # iterate over concentrations
        righttrials = (ids .>= 8i-3) .& (ids .<= 8i)
        lefttrials = (ids .>= 8i-7) .& (ids .<= 8i-4)
        alltrials = righttrials .| lefttrials
        stimmag[righttrials] .= ids[righttrials]
        stimmag[lefttrials] .= (16i - 7) .- ids[lefttrials]
        mixw[alltrials] .= ids[alltrials] .- 8(i-1)       # to 1-8 range
        mixmag[alltrials] .= stimmag[alltrials] .- (8i - 4)  # to 1-4 range
        concentr[alltrials] .= 5-i
    end

    return DataFrame(
        trial    = collect(1:trials),
        stimid   = ids,
        previd   = [ids[end]; ids[1:end-1]],
        stimmag  = stimmag,
        mixw     = mixw,
        mixmag   = mixmag,
        concentr = concentr,
        corrresp = corrresps,
        resp     = resps,
        t        = ts,
        conf     = gs,
        corr     = corr,
        prevcorr = [corr[end]; corr[1:end-1]],
        prevrew  = [corr[end]; corr[1:end-1]])
end
# same as simmodel(), but providing additional statistics
function simmodelwithstats(m::ModelBase, ϕ::Vector{Float64}, evidence, ids)
    trials = length(ids)
    @assert size(evidence, 1) == trials
    @assert mod(trials, 2) == 0
    trials = div(trials, 2)

    resps, ts, gs, dts, ws, biases, xs, inputs = simwithstats(m, ϕ, evidence)

    # determine correct replies by which-ever evidence is larger
    corrresps = convert(Vector{Int}, evidence[:,2] .> evidence[:,1])
    corr = resps .== corrresps

    # return results in two dataframes
    r1, r2 = 1:trials, (trials+1):(2*trials)
    stimmag = copy(ids)
    stimmag[stimmag .< 5] = 9 - stimmag[stimmag .< 5]
    previds = cat(ids[end], ids[1:end-1], dims=1)    # prev. before first is random
    prevcorr = cat(corr[end], corr[1:end-1], dims=1)
    mat2arrarr(A) = [A[i,:] for i in 1:size(A,1)]
    return DataFrame(trial    = collect(r1),
              stimid   = ids[r1],
              previd   = previds[r1],
              stimmag  = stimmag[r1],
              corrresp = corrresps[r1],
              resp     = resps[r1],
              t        = ts[r1],
              conf     = gs[r1],
              corr     = corr[r1],
              prevcorr = prevcorr[r1],
              prevrew  = prevcorr[r1],
              dt       = dts[r1],
              w        = mat2arrarr(ws[r1,:]),
              bias     = biases[r1],
              x        = mat2arrarr(xs[r1,:]),
              input    = mat2arrarr(inputs[r1,:]) ),
    DataFrame(trial    = collect(r1),
              stimid   = ids[r2],
              previd   = previds[r2],
              stimmag  = stimmag[r2],
              corrresp = corrresps[r2],
              resp     = resps[r2],
              t        = ts[r2],
              conf     = gs[r2],
              corr     = corr[r2],
              prevcorr = prevcorr[r2],
              prevrew  = prevcorr[r2],
              dt       = dts[r2],
              w        = mat2arrarr(ws[r2,:]),
              bias     = biases[r2],
              x        = mat2arrarr(xs[r2,:]),
              input    = mat2arrarr(inputs[r2,:]) )
end

# returns two DataFrames. The first provides psychometric / chronometric
# statistics over all stimulus id's. The second does the same over stimulus
# magnitudes. If datasets > 1, then the SEM is computed as average over the
# given number of datasets, rather than over all trials.
function getpsychchron(result_df, datasets::Int=1)
    id_df = by(result_df, :stimid,
        df -> DataFrame(tμ = mean(df[:t]), tσ = √(var(df[:t])),
                        tsem = √(datasets * var(df[:t]) / length(df[:t])),
                        tcorrμ = mean(df[df[:corr], :t]), tcorrσ = √(var(df[df[:corr], :t])),
                        tincorrμ = mean(df[.!df[:corr], :t]), tincorrσ = √(var(df[.!df[:corr], :t])),
                        pcorr = mean(df[:corr]), pr = mean(df[:resp] .== 1),
                        confμ = mean(df[:conf]), confσ = √(var(df[:conf]))))
    mag_df = by(result_df, :stimmag,
        df -> DataFrame(tμ = mean(df[:t]), tσ = √(var(df[:t])),
                        tsem = √(datasets * var(df[:t]) / length(df[:t])),
                        tcorrμ = mean(df[df[:corr], :t]), tcorrσ = √(var(df[df[:corr], :t])),
                        tincorrμ = mean(df[.!df[:corr], :t]), tincorrσ = √(var(df[.!df[:corr], :t])),
                        pcorr = mean(df[:corr]),
                        confμ = mean(df[:conf]), confσ = √(var(df[:conf]))))
    id_df, mag_df
end

# returns two DataFrames. The first groups trials by the current/prev. stimulus
# id tuple and provides p("right") and average times after correct and incorrect
# choices. The second fits a psychometric curve for reach prev. stimulus id, and
# returns mean and standard deviation of this fit for each prev. stimulus id.
# for the latter, idx[stimid] is used to map (current) stimulus ids onto
# the horizontal axis of the psychometric curve.
function getseqstats(result_df, idx)
    seq_df = by(result_df, [:stimid, :previd],
        df -> DataFrame(prcorr = mean(df[df[:prevcorr], :resp] .== 1),
                        tcorrμ = mean(df[df[:prevcorr], :t]), tcorrσ = √(var(df[df[:corr], :t])),
                        princorr = mean(df[.!df[:prevcorr], :resp] .== 1),
                        tincorrμ = mean(df[.!df[:prevcorr], :t]), tincorrσ = √(var(df[.!df[:corr], :t])),
                        x = idx[df[1, :stimid]]))
    # fit psychometric curves
    ids = unique(seq_df[:stimid])
    xcenter = (maximum(idx) + minimum(idx)) / 2
    seq_bias_df = DataFrame(previd = similar(ids, 0),
                            μcorr = similar(idx, 0), σcorr = similar(idx, 0), biascorr = similar(idx, 0),
                            μincorr = similar(idx, 0), σincorr = similar(idx, 0), biasincorr = similar(idx, 0))
    for i in ids
        μcorr, σcorr = psychprobitfit(
            Vector(seq_df[seq_df[:previd] .== i, :x]),
            Vector(seq_df[seq_df[:previd] .== i, :prcorr]))
        biascorr = Φ((xcenter - μcorr) / σcorr) - 0.5
        μincorr, σincorr = psychprobitfit(
            Vector(seq_df[seq_df[:previd] .== i, :x]),
            Vector(seq_df[seq_df[:previd] .== i, :princorr]))
        biasincorr = Φ((xcenter - μincorr) / σincorr) - 0.5
        push!(seq_bias_df, [i, μcorr, σcorr, biascorr,
                               μincorr, σincorr, biasincorr])
    end
    seq_df, seq_bias_df
end

# returns another dataframe of moving average p(correct) and RT, window size w
function getmovingavg(result_df, w)
    trials = size(result_df, 1)
    DataFrame(trial=collect((1:(trials-w+1))+div(w,2)),
              pc=movingavg(result_df[:corr], w), t=movingavg(result_df[:t], w))
end


text:
### A Pluto.jl notebook ###
# v0.11.1

using Markdown
using InteractiveUtils

# ╔═╡ c880bbe4-d252-11ea-299e-f1558843723b
using Revise

# ╔═╡ b5b404ac-d19f-11ea-23ce-ab33f91aa208
begin
	using Pkg
	Pkg.activate("../")
	using Raven
	using LinearAlgebra

	using Plots
	gr()

	import UnicodePlots
	using IterativeSolvers
end

# ╔═╡ 1b2c0ce4-d1a0-11ea-1c93-a1b0c254c74a
#edges=Raven.readToFeTedges(open("../testdata/10chain.edge","r"))
#edges=Raven.readToFeTedges(open("../testdata/scl.edge","r"))
#edges=Raven.generateLinearChain(20, J=0.01)
edges=Raven.generateNearestNeighbourCube(5)

# ╔═╡ 1e1dd7be-d1a0-11ea-1cc8-c56d0ae6af16
UnicodePlots.spy(edges)

# ╔═╡ 62f8d170-d1a4-11ea-27fd-799898035f6b
siteE=randn(edges.m)./1000

# ╔═╡ 2d27f084-d1a0-11ea-29c9-65aac7f32304
#rates=Raven.ratematrix(edges,Raven.rateAdiabatic)/1e13 # no site energies
rates=Raven.ratematrix(edges,siteE,Raven.rateMarcus)/1e13 # with site energy fluct

# ╔═╡ 307e6efe-d1a0-11ea-059e-4d022439bb2f
# OK, let's look at the SVD (dense) method, as a reference
begin
	if rates.m<1000 # Don't even try this if we have a big problem!
		SVD=Raven.solveMasterDense(rates)
	end
end

# ╔═╡ 351c10fe-d1a0-11ea-3536-6dc718e880b0
# Fiddle till we extract the value we want: the very small singular values, and their right vectors Vt
ρsvd=SVD.Vt[rates.m,:]

# ╔═╡ 434a6b3a-d1a0-11ea-339a-efba5cc9ccb6
sum(ρsvd)

# ╔═╡ 61f5ef98-d1a0-11ea-0700-3182aa28da18
# suspicious number, I wonder if this is...
sqrt(rates.m)

# ╔═╡ ab49bf56-d1a0-11ea-1312-a7547dc76221
r=IterativeSolvers.lobpcg(rates,  true, 1, maxiter=10000)

# ╔═╡ e619cc0c-d1a0-11ea-2173-792ee1914df9
ρ= rates.m* abs.(r.X)/sum(abs.(r.X))

# ╔═╡ 66ce27b8-d1a0-11ea-396a-6b0da7966500
# OK, let's check that we are in a steady state condition, by solving the first order ODE statement
rates.m<1000 && exp(collect(rates))*ρ

# ╔═╡ a0d2c4a2-d1a3-11ea-1fe8-b183f7586657
plot(ρ)

# ╔═╡ 2f365d34-d1aa-11ea-107f-91137d9f43e9
plot(siteE)

# ╔═╡ ea5f86a6-d1a0-11ea-3459-3bf8e7e84e90
# check stationary condition by forming matrix exponential (solution to first order rate equation)
# We cannot do this for real systems, as the matrix exponential is a dense object!
rates.m<1000 && exp(collect(rates))*r.X

# ╔═╡ bf03a888-d252-11ea-0906-3f477c6435bd
Raven.generateNearestNeighbourCube(5)

# ╔═╡ Cell order:
# ╠═c880bbe4-d252-11ea-299e-f1558843723b
# ╠═b5b404ac-d19f-11ea-23ce-ab33f91aa208
# ╠═1b2c0ce4-d1a0-11ea-1c93-a1b0c254c74a
# ╠═1e1dd7be-d1a0-11ea-1cc8-c56d0ae6af16
# ╠═62f8d170-d1a4-11ea-27fd-799898035f6b
# ╠═2d27f084-d1a0-11ea-29c9-65aac7f32304
# ╠═307e6efe-d1a0-11ea-059e-4d022439bb2f
# ╠═351c10fe-d1a0-11ea-3536-6dc718e880b0
# ╠═434a6b3a-d1a0-11ea-339a-efba5cc9ccb6
# ╠═61f5ef98-d1a0-11ea-0700-3182aa28da18
# ╠═66ce27b8-d1a0-11ea-396a-6b0da7966500
# ╠═ab49bf56-d1a0-11ea-1312-a7547dc76221
# ╠═e619cc0c-d1a0-11ea-2173-792ee1914df9
# ╠═a0d2c4a2-d1a3-11ea-1fe8-b183f7586657
# ╠═2f365d34-d1aa-11ea-107f-91137d9f43e9
# ╠═ea5f86a6-d1a0-11ea-3459-3bf8e7e84e90
# ╠═bf03a888-d252-11ea-0906-3f477c6435bd


text:
using Documenter, StructuredQueries

makedocs(
    modules = [StructuredQueries],
    format = :html,
    sitename = "StructuredQueries.jl",
    authors = "David A. Gold and contributors.",
    pages = Any[
        "Home" => "index.md",
        "Manual" => Any[
            "Guide" => "man/guide.md",
            # "Syntax" => "man/syntax.md",
            # "Extension" => "man/extension.md",
            "Examples" => "man/examples.md"
        ],
        "Library" => Any[
            "Public" => "lib/public.md"
            "Internals" => Any[
                "Internals" => "lib/internals.md",
                "lib/internals/query.md",
                "lib/internals/graph.md",
                "lib/internals/node.md",
                "lib/internals/helper.md",
                "lib/internals/expr.md",
                "lib/internals/collect.md"
            ]
        ]
    ]
)

deploydocs(
    repo = "github.com/davidagold/StructuredQueries.jl.git",
    target = "build",
    deps = nothing,
    make = nothing,
)


text:
export marginalrule

@marginalrule Beta(:out_a_b) (m_out::Beta, m_a::PointMass, m_b::PointMass) = begin
    return (out = prod(ProdAnalytical(), Beta(mean(m_a), mean(m_b)), m_out), a = m_a, b = m_b)
end


text:
module Sim
include("./name2idx/parameters.jl")
include("./name2idx/species.jl")
include("./set_model.jl")

using .C
using .V
using DelayDiffEq

function solvedde(diffeq::Function,u0::Vector{Float64},history::Vector{Float64},
                    tspan::Tuple{Float64,Float64},p::Vector{Float64},tau::Float64)
    h(p,t) = history
    lags = [tau]
    prob = DDEProblem(diffeq,u0,h,tspan,p;constant_lags=lags)
    alg = MethodOfSteps(BS3())
    sol = solve(prob,alg)
    return sol
end

function get_steady_state(p::Vector{Float64},u0::Vector{Float64},sstime::Float64,tau::Float64)
    # get steady state (t<0)
    param::Vector{Float64} = copy(p)
    param[C.term] = 1.0
    history::Vector{Float64} = u0
    tspan::Tuple{Float64,Float64} = (0.0,sstime)
    sol = solvedde(diffeq,u0,history,tspan,param,tau)

    return sol[:,end]
end

function get_time_course(p::Vector{Float64},u0::Vector{Float64},
                            sstime::Float64,simtime::Float64,tau::Float64)
    param::Vector{Float64} = copy(p)
    param[C.term] = 0.0
    u1::Vector{Float64} = get_steady_state(p,u0,sstime,tau)
    history::Vector{Float64} = u1
    tspan::Tuple{Float64,Float64} = (0.0,simtime)
    sol = solvedde(diffeq,u1,history,tspan,param,tau)

    return sol
end

const sstime = 1000.0
const simtime = 360.0

p = param_values()
u0 = initial_values()

sol = get_time_course(p,u0,sstime,simtime,p[C.delayrnae])

const t = sol.t

CBMa = sol[V.Cp,:] + sol[V.CpB,:] + sol[V.CpM,:] + sol[V.CpBM,:]
TAK1a = sol[V.TAK1p,:] + sol[V.TAK1pC,:]
IKKa = sol[V.IKKp,:] + sol[V.IKKpC,:] + sol[V.IKKppC,:] + sol[V.IKKpp,:]
NFkBa = sol[V.NFKBn,:]

end  # module


text:
using Test
using LinearAlgebra: norm
using GeometryTypes: Point
using Random: seed!

using GeometryReferenceGenericSolver
using GeometryReferenceGenericSolver: find_minimum_distance

r = find_minimum_distance((Point(-1,0), Point(1,0)), (Point(0,-1), Point(0, 1)))
@test r.d_sq < 100eps()
@test norm(r.p1 - [0, 0]) < 100eps()
@test norm(r.p2 - [0, 0]) < 100eps()

xy_plane = 1e6 .* (Point(-1,0,0), Point(1,0,0), Point(0, 1, 0))

seed!(1234)

@testset "projection xy" begin
    # make all points first, to facilitate test debugging and to improve performance measure
    testpoints = [1e5 .* rand(Point{3, Float64}) for i = 1:1000]
    t_start = nothing
    for i = 1:length(testpoints)
        if i == 2
            t_start = time() # don't measure compilation time in first iteration
        end
        p = testpoints[i]
        # project p onto xy_plane
        r = find_minimum_distance(xy_plane, (p,))
        @test isapprox(p[3]^2, r.d_sq)
        @test norm(r.p1[1:2] - p[1:2]) < 1e-6
    end
    # cheap-o performance benchmark
    @show time() - t_start
end

# with ~16 digits of signifance, and some x * x terms, having a `1e8` value is tough.
xy_plane_bad = 1e8 .* (Point(-1,0,0), Point(1,0,0), Point(0, 1, 0))
ps_bad = [
    Point(15099.411397006435, 63329.17689456945, 489.2398433903766),
    Point(56270.48118496456, 53948.45819773468, 34.889982642960504),
    Point(37517.76357686068, 84362.38878880453, 233.50717418757495)
]

@testset "projection xy numerical issue" begin
    for p in ps_bad
        r = find_minimum_distance(xy_plane_bad, (p,))
        @test isapprox(p[3]^2, r.d_sq, rtol=1e-4)
        @test norm(r.p1[1:2] - p[1:2]) < 1e-6
    end
end

max_stars_repo_name: goretkin/GeometryReferenceGenericSolver

max_issues_repo_name: goretkin/GeometryReferenceGenericSolver

max_forks_repo_name: goretkin/GeometryReferenceGenericSolver


text:
#-------------------------------------------------------------------
#* EMSO Model Library (EML) Copyright (C) 2004 - 2007 ALSOC.
#*
#* This LIBRARY is free software; you can distribute it and/or modify
#* it under the therms of the ALSOC FREE LICENSE as available at
#* http://www.enq.ufrgs.br/alsoc.
#*
#* EMSO Copyright (C) 2004 - 2007 ALSOC, original code
#* from http://www.rps.eng.br Copyright (C) 2002-2004.
#* All rights reserved.
#*
#* EMSO is distributed under the therms of the ALSOC LICENSE as
#* available at http://www.enq.ufrgs.br/alsoc.
#*
#*----------------------------------------------------------------------
#* Authors: Rafael de Pelegrini Soares
#*          Andrey Copat, Estefane S. Horn, Marcos L. Alencastro
#* $Id$
#*--------------------------------------------------------------------
#Needs to be reformulated
type HidraulicTurbineGenerator
	HidraulicTurbineGenerator()=begin
		new(
			HidraulicTurbine(),
			power(Dict{Symbol,Any}(
				:Brief=>"Eletrical Potency"
			)),
			[
				:(EPower = _base_1.BPower * _base_1.Meff),
			],
			[
				"Calculate Eletric Power",
			],
			[:EPower,]
		)
	end
	_base_1::HidraulicTurbine
	EPower::power
	equations::Array{Expr,1}
	equationNames::Array{String,1}
	variables::Array{Symbol,1}
	attributes::Dict{Symbol,Any}
end
export HidraulicTurbineGenerator
function setEquationFlow(in::HidraulicTurbineGenerator)
	addEquation(1)
end
function atributes(in::HidraulicTurbineGenerator,_::Dict{Symbol,Any})
	fields::Dict{Symbol,Any}=Dict{Symbol,Any}()
	fields[:Pallete]=true
	fields[:Icon]="icon/HidraulicTurbine"
	fields[:Brief]="Model of a Hidraulic Turbine."
	fields[:Info]="== Assumptions ==
* Steady State;
* Only Liquid;
* Adiabatic;
* Isentropic.

== Specify ==
* the inlet stream;
* the Pressure Increase (Pdiff) OR the outlet pressure (Outlet.P);
* the Turbine efficiency (Eff);
* the Brake efficiency (Meff);
* the Volumetric expansivity (Beta).
"
	drive!(fields,_)
	return fields
end
HidraulicTurbineGenerator(_::Dict{Symbol,Any})=begin
	newModel=HidraulicTurbineGenerator()
	newModel.attributes=atributes(newModel,_)
	newModel
end


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

JLLWrappers.@generate_main_file_header("tree_sitter_highlight")
JLLWrappers.@generate_main_file("tree_sitter_highlight", UUID("a99a7680-1b0c-57dd-b59a-79ab8f52c9a4"))
end  # module tree_sitter_highlight_jll


text:
# Simple script for running the GPU benchmarks.
#
# Fragmentation in GPU arrays allocated by CuArrays requires the Julia executable to be
# restarted between runs.

if length(ARGS) == 1
    jl_bin = first(ARGS)
else
    jl_bin = "julia"
end

@info """
    Using "$jl_bin" for the Julia binary executable.
    Run this script as

        julia gpu_script.jl <path/to/julia>

    to override.
    """

# Go through each of the GPU benchmarks
for i in 7:11
    # Go through the optimizers
    for opt in ("Synchronous", "Asynchronous")
        # Build the command string
        exe = """
            using Benchmarker, AutoTM;
            Benchmarker.run_gpu($i; optimizers = AutoTM.Optimizer.$opt);
        """

        cmd = [
            jl_bin,
            "--project=$(pwd())",
            "--color=yes",
            "-E",
            exe
        ]
        run(`$cmd`)
    end
end

max_stars_repo_name: darchr/AutoTM

max_issues_repo_name: darchr/AutoTM

max_forks_repo_name: darchr/AutoTM