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

using Markdown
using InteractiveUtils

# ╔═╡ 1ed923c0-f5f0-11eb-3bef-f7866f2a40b0
begin
	using InteractiveUtils
	using PlutoUI

	using JSONLines
	using JSON3
	using CSV

	using HTTP

	using Tables
	using DataFrames
	using Chain
	using RollingFunctions
	using Statistics
	using Match

	using PerceptualColourMaps
	using Gadfly
	using Images
	import Plots

	Gadfly.set_default_plot_size(16cm, 14cm)

	# For allowing interactive Gadly Plots
	struct HTMLDocument
		embedded
	end
	function Base.show(io::IO, mime::MIME"text/html", doc::HTMLDocument)
		println(io, "<html>")
		show(io, mime, doc.embedded)
		println(io, "</html>")
	end
end

# ╔═╡ 0035970f-f027-4eea-91e2-113b22710002
html"<button onclick='present()'>Present</button>"

# ╔═╡ c47d2950-cd1f-47a3-a213-b06a27eb0746
md"""
# Looking Back

### Updates from last time
- linguistic analysis:
  - Distribution of distances to GPT-2 embeddings.
  - Log-probability of embedding sequences.
  - View samples
- Comparison of pretrained GPT2 with randomized weights:
  - Negative result on Seaquest
  - Probably negative result on smaller architecture

### Goals set last time
- Check if randomized weights in Abbeel paper were frozen.
- Compare random vs. pretrained across 2 more environments.
- Show progression of similarities over course of training (maybe just putting through neural network is sufficient to account for similarities).
- Compare log-probability with bytes sampled from random corpus.
- Compare log-probability with repeated words (maybe repetition is all that accounts for improved probability).
- Pick a domain in which four embeddings improves over one embedding as a signal that repetition is not sufficient.
- Record value as well as action in vew-samples analysis.
- Check distance between input and GPT output.
- Prime GPT with description?
- Double check that GPT2 with random parameters is actually random.
- Try with linear projection instead of patches.
- Don't overfit on Atari: Try BabyAI.
"""

# ╔═╡ 5fc027ad-704f-4045-b281-08a128a204ea
ling_analysis_colors = collect(Plots.palette(:tab10));

# ╔═╡ cfc7da80-170d-4eac-8367-f4c4a4aeadb2
md"""
# Response to question about Abbeel paper

> Hi Ethan,
>
> Excited to hear you're interested in our work! In Section 3.4, the random weights were frozen. By the way, in our v2 version, Appendix D is a bit more explicit as to where exactly each number comes from.
>
> Best,
> Kevin
"""

# ╔═╡ cf3ec4b5-c187-422b-81e5-dd1f03b9d96c
md"""
# Validation of Random Initialization
```python
import argparse

from torch import Tensor
from transformers import GPT2Config, GPT2LMHeadModel, GPT2Tokenizer

parser = argparse.ArgumentParser()
parser.add_argument("--random", type=bool)  # toggles random vs. pretrained
random = parser.parse_args().random

gpt_size = "gpt2-medium"
tokenizer = GPT2Tokenizer.from_pretrained(gpt_size)  # convert string to tokens

# initialize model
model = (
    GPT2LMHeadModel(
        GPT2Config.from_pretrained(
            gpt_size,
            pad_token_id=tokenizer.eos_token_id,
            use_cache=False,
            output_attentions=False,
            output_hidden_states=False,
        )
    )
    if random
    else GPT2LMHeadModel.from_pretrained(
        gpt_size,
        pad_token_id=tokenizer.eos_token_id,
        use_cache=False,
        output_attentions=False,
        output_hidden_states=False,
    )
)

# context sentence
input_ids = Tensor(
    tokenizer.encode("I enjoy walking with my cute dog", return_tensors="np")
).long()

# generate text until the output length (which includes the context length) reaches 50
greedy_output = model.generate(input_ids, max_length=50)

print("Output:\n" + 100 * "-")
print(tokenizer.decode(greedy_output[0], skip_special_tokens=True))
```
```
$ python generate_text.py --random

Output:
------------------------------------------------------------------------------------
I enjoy walking with my cute dog suitable autonom//////////////// pac TBotle keyboards curtain skirtsmanufactynastygat renamed bachelor////////////////� airspace Matthew LevinEL9203 Comes9292 Eden Cyborg Denis Matthew Matthew mushroomfighter Shattered Remote orthodox unsu Matthewotlegregation eased92 Fram92

$ python generate_text.py

Output:
------------------------------------------------------------------------------------
I enjoy walking with my cute dog, but I'm not sure if I can do it with my cat. I'm not sure if I can do it with my cat.

I'm not sure if I can do it with my cat.
```
"""

# ╔═╡ d9f3c726-79e9-4c43-95ad-b73e508630a7
md"""
# Comparison of Pretrained and Random Parameters
- On the original architecture, pretrained and random parameters seem to show equivalent performance on three Atari games
- Smaller architectures are capable of learning Atari games.
- One smaller architecture exhibited little to no advantage over the random parameters.
- Smaller architectures are either still in hyperparameter search, or the comparison runs have not yet converged.
"""

# ╔═╡ 1501042a-1ae2-44c6-a513-c36b4389fa72
function original_architecture_description(env, pretrained, random)
	return md"""
# "Original" Architecture
- Convolution with
  - output-size $32$
  - kernel-shape $8\times 8$
  - stride $4\times 4$
- ReLU
- Convolution with
  - output-size $64$
  - kernel-shape $4\times 4$
  - stride $2\times 2$
- ReLU
- Convolution with
  - output-size $64$
  - kernel-shape $3\times 3$
  - stride $1\times 1$
- ReLU
- **Linear layer with output-size = $n \times e$ where $n$ is the number of embeddings (a hyperparameter) and $e$ is the GPT embedding size (see table below).**
- **GPT2 Medium Architecture**
- **one 512-neuron layer**
- one layer projecting to action and value

|  | pretrained | random |
|-------------------|------------|--------|
| ` num_embeddings`         | $(pretrained)          | $(random)      |
"""
end;

# ╔═╡ 8fc7b1d2-15db-4356-b5f3-08c60ea2886c
original_architecture_description("Qbert", 8, 8)

# ╔═╡ ea7a2d4d-69e9-4046-bb78-c6e4c36fb4b6
original_architecture_description("", 8, 8)

# ╔═╡ 55ded444-4341-4132-9183-abb96671eea5
original_architecture_description("BeamRider", 4, 4)

# ╔═╡ e42a103e-292e-4fb8-b7c9-8cb47273d2cc
original_architecture_description("Breakout", 8, 2)

# ╔═╡ bca9cc5e-c243-4135-a350-393c50a99783
md"""
# Results with more minimal architectures
"""

# ╔═╡ 187cff60-2820-43fd-9486-d0dd6f322fde
md"""
# "One-Convolution, Multi-Embedding" Architecture
- Convolution with
  - **output-size $1024$**
  - kernel-shape $12\times 12$
  - stride $12\times 12$
  - This results in `num_embeddings = 49`
- **GPT2 Medium Architecture**
- single layer chosen from
  - 32
  - 64
  - 128
  - none
- one layer projecting to action and value

Currently running.
"""

# ╔═╡ 36db8d48-40f4-4c99-b371-9786ea05bc1f
md"""
## "Two-Convolution, Multi-Embedding" Architecture
- Convolution with
  - output-size $32$
  - kernel-shape $8\times 8$
  - stride $4\times 4$
- ReLU
- Convolution with
  - **output-size $1024$ (GPT embedding size)**
  - kernel-shape $16\times 16$
  - stride $2\times 2$
  - This results in `num_embeddings = 9`
- **GPT2 Medium Architecture**
- single 64 neuron dense layer
- one layer projecting to action and value

Comparison of best run with randomized parameters is currently running.

"""

# ╔═╡ f739cd9f-f6fb-4203-8af6-801408c69c3d
md"""
## "Two-Convolution, Multi-Embedding" Architecture "No GPT variant"
- Convolution with
  - output-size $32$
  - kernel-shape $8\times 8$
  - stride $4\times 4$
- ReLU
- Convolution with
  - **output-size $1024$ (GPT embedding size)**
  - kernel-shape $16\times 16$
  - stride $2\times 2$
  - This results in `num_embeddings = 9`
- **Sum-pool operator**
- single 64 neuron dense layer
- one layer projecting to action and value

Comparison of best run with randomized parameters is currently running.

"""

# ╔═╡ a3ed2be4-b4c3-4490-8971-daac16b5967d
md"""
# To Do
- Compare random vs. pretrained on one more environments.
- Show progression of similarities over course of training (maybe just putting through neural network is sufficient to account for similarities)
- Compare log-probability with bytes sampled from random corpus.
- Compare log-probability with repeated words (maybe repetition is all that accounts for improved probability)
- Pick a domain in which four embeddings improves over one embedding as a signal that repetition is not sufficient.
- Record value as well as action
- Check distance between input and GPT output.
- priming?
- Try with linear projection instead of patches.
- Don't overfit on Atari: Try BabyAI!!

- Try hyperparam search on No GPT
- Try different domain on No GPT
- Do not let GPT speak at every time-step
- Try Baby AI next
- Auxiliary task to reconstruct input?
- reproduce Abbeel result.
- Another machine!
"""

# ╔═╡ d121c942-2b52-4c5a-8739-a9afd6f402fd
md"#"

# ╔═╡ 0350341b-738c-4012-9d0e-90f6aa15ee51
begin
	HASRUA_ENDPOINT_URL = "http://rldl12.eecs.umich.edu:1200/v1/graphql"
end;

# ╔═╡ d73bfb4c-8427-4c97-ba43-84623a1acf37
# Colormap Gallery: https://colorcet.com/gallery.html
colors(n) = cmap("I1"; N=n);

# ╔═╡ a233f78f-32d6-4828-bd1e-b54e3e5b100e
gadfly_theme = :default;

# ╔═╡ d85ab49d-f9b9-4b9b-a54c-801c3c0e4d86
function gql_query(query:: String; variables:: Dict = nothing)
	r = HTTP.request(
		"POST",
		HASRUA_ENDPOINT_URL;
		verbose=3,
		body= JSON3.write(Dict("query" => query, "variables" => variables)) ,
	)
	@chain r begin
		_.body
		String
		JSON3.read(_, Dict)
		_["data"]
	end
end;

# ╔═╡ 63c54d1e-af97-4d59-a7b3-79e688893c42
function sweep_runs(sweep_ids::AbstractVector{Int}, max_step::Int)
	set_default_plot_size(18cm, 15cm)

	query = """
		query getSweepRuns(\$ids: [Int!], \$max_step: Int!) {
		  logs_less_than_step(args: {max_step: \$max_step}, where: {run: {sweep_id: {_in: \$ids}}}) {
			log
			run_id
			run {
			  metadata
			  sweep_id
			}
		  }
		}
  	"""
	rows = @chain gql_query(query; variables=Dict("ids" => sweep_ids, "max_step" => max_step)) begin
		_["logs_less_than_step"]
		map(d -> Dict(
				"run_id" => d["run_id"],
				"sweep_id" => d["run"]["sweep_id"],
				d["log"]...,
				d["run"]["metadata"]["parameters"]...
				), _)

		map(d -> Dict(
				d...,
				"action_hidden_size" => if isnothing(get(d, "action_hidden_size", 0))
					0
				else
					get(d, "action_hidden_size", nothing)
				end,
				[k => v for (k1, v1, k2, v2) in [
							(
								"hours", get(d, "time-delta", 0) / 3600,
								"time-delta", get(d, "hours", 0) * 3600,
							),
							(
								"env", get(d, "env_name", nothing),
								"env_name", get(d, "env", nothing),
							)
						]
						for (k, v) in [
								(k1, get(d, k1, v1)),
								(k2, get(d, k2, v2)),
								]]...,
				[name => get(d, name, false) for name in [
							"randomize_parameters"
						]]...,
				[name => get(d, name, nothing) for name in [
							# "action_hidden_size",
							# "gpt",
							# "time",
							# "gae",
							# "gradient_clip",
							# "nonlinearity",
							# "normalize_observation",
							# "normalize_torso_output",
							# "optimizer",
							"num_embeddings",
							# "save_interval",
							# "save_path",
							"config",
							"graphql_endpoint",
							"linguistic_analysis_path",
							# "hidden_size",
							"host_machine",
							"kernel",
							"stride",
							"one_layer",
							"transpose",
						]]...
				), _)
		filter(d -> !isnothing(d["episode return"]), _)
	end
	vcat(DataFrame.(rows)...)
end;

# ╔═╡ f53e9f0c-b53d-4db6-abe2-2be82077bf38
function to_gif(images::Array{Vector{Vector{Float64}}, 1}, scale::Int = 3)
	anim = @Plots.animate for img in images
		Plots.heatmap(
			Matrix(hcat(img...)') ./ 255.0;
			color=:grays,
			clim=(0., 1.),
			legend=nothing,
			xaxis=nothing,
			yaxis=nothing,
			showaxis=false,
			aspect_ratio=:equal,
			size=(84 * scale, 84 * scale),
			# title="Observation"
		)
	end
	Plots.gif(anim, fps=length(images))
end

# ╔═╡ ec5e66ce-8244-4720-9cfb-13bdd1ade7bf
ppo_scores = Dict(
	"BreakoutNoFrameskip-v4" => 274.8,
	"BeamRider-v0" => 1590.0,
	"Seaquest-v0" => 1204.5,
	"Qbert-v0" => 14293.3,
	"PongNoFrameskip-v4" => 20.7
	)

# ╔═╡ 0a6d3d99-37bc-40f4-95e5-91ef76b29844
function plot_returns(;
		data,
		color,
		legend_title::String=color,
		labels=nothing
	)
	env = first(data)[:env]
	yintercept = ppo_scores[env]
	Gadfly.with_theme(gadfly_theme) do
		plot(
			data,
			x=:step, y="episode return",
			yintercept=[yintercept],
			group=:run_id,
			color=color,
			Guide.xlabel("Step"),
			Guide.ylabel("Episode Return"),
			Geom.line,
			Geom.hline(style=:dot,color="#b88fff"),
			Scale.color_discrete(colors, preserve_order=false),
			Guide.colorkey(title=legend_title, labels=labels),
			Guide.title(env),
			alpha=[0.5]
		) |> HTMLDocument
	end
end

# ╔═╡ 5839b81d-98ad-4672-ba05-2c92762c602a
plot_returns(
	data=filter(sweep_runs([831], 50000000)) do row
		row.env == "Qbert-v0"
	end,
	color=:randomize_parameters,
	legend_title="Random Parameters"
)

# ╔═╡ fc36279e-2088-4eba-b48a-f05e82443540
plot_returns(
	data=sweep_runs([826], 50000000),
	color=:randomize_parameters,
	legend_title="Random Parameters"
)

# ╔═╡ baf58341-a518-40ca-bafa-d2e4127b3089
plot_returns(
	data=sweep_runs([787, 690], 50000000),
	color=:randomize_parameters,
	legend_title="Random Parameters"
)

# ╔═╡ e7bd101e-a647-4ffd-9770-27c350396831
plot_returns(
	data=sweep_runs([687, 672], 50000000),
	color=:randomize_parameters,
	legend_title="Random Parameters"
)

# ╔═╡ fdc8f9ff-11e6-4a14-b4f5-44030672bd1d
plot_returns(
	data=sweep_runs([827], 50000000),
	color="run ID",
	legend_title="Random Parameters"
)

# ╔═╡ 5a55fb1a-2b96-4d3c-b274-58adf26e975d
begin
	@chain sweep_runs([830, 828], 50000000) begin
		groupby(_, [:sweep_id, :randomize_parameters])
		DataFrames.transform(_,
			[:sweep_id, :randomize_parameters] =>
			(ids, rps) -> map(zip(ids, rps)) do (id, rp)
				@match (id, rp) begin
					(830, _) => "No GPT"
					(_, true) => "Randomized GPT"
					(_, false) => "Pretrained GPT"
					_ => throw(DomainError())
				end
			end
		)
		plot_returns(
			data=_,
			color="sweep_id_randomize_parameters_function",
			legend_title="Architecture"
		)
	end
end

# ╔═╡ cf8c89cf-54ad-40ef-8900-ae0a8b28f469
begin
	@chain sweep_runs([830, 828], 50000000) begin
		groupby(_, [:sweep_id, :randomize_parameters])
		DataFrames.transform(_,
			[:sweep_id, :randomize_parameters] =>
			(ids, rps) -> map(zip(ids, rps)) do (id, rp)
				@match (id, rp) begin
					(830, _) => "No GPT"
					(_, true) => "Randomized GPT"
					(_, false) => "Pretrained GPT"
					_ => throw(DomainError())
				end
			end
		)
		plot_returns(
			data=_,
			color="sweep_id_randomize_parameters_function",
			legend_title="Architecture"
		)
	end
end

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
Chain = "8be319e6-bccf-4806-a6f7-6fae938471bc"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Gadfly = "c91e804a-d5a3-530f-b6f0-dfbca275c004"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
JSONLines = "24c2b838-1c8b-4567-aca0-d45e60436bb9"
Match = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf"
PerceptualColourMaps = "54e51dfa-9dd7-5231-aa84-a4037b83483a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
RollingFunctions = "b0e4dd01-7b14-53d8-9b45-175a3e362653"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"

[compat]
CSV = "~0.8.5"
Chain = "~0.4.7"
DataFrames = "~1.2.2"
Gadfly = "~1.3.3"
HTTP = "~0.9.13"
Images = "~0.24.1"
JSON3 = "~1.9.1"
JSONLines = "~2.0.1"
Match = "~1.1.0"
PerceptualColourMaps = "~0.3.5"
Plots = "~1.20.0"
PlutoUI = "~0.7.9"
RollingFunctions = "~0.6.2"
Tables = "~1.5.0"
"""

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

[[AbstractFFTs]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "485ee0867925449198280d4af84bdb46a2a404d0"
uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c"
version = "1.0.1"

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

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

[[ArrayInterface]]
deps = ["IfElse", "LinearAlgebra", "Requires", "SparseArrays", "Static"]
git-tree-sha1 = "2e004e61f76874d153979effc832ae53b56c20ee"
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
version = "3.1.22"

[[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"

[[AxisArrays]]
deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"]
git-tree-sha1 = "d127d5e4d86c7680b20c35d40b503c74b9a39b5e"
uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9"
version = "0.4.4"

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

[[Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c3598e525718abcc440f69cc6d5f60dda0a1b61e"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.6+5"

[[CEnum]]
git-tree-sha1 = "215a9aa4a1f23fbd05b92769fdd62559488d70e9"
uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82"
version = "0.4.1"

[[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 = "e2f47f6d8337369411569fd45ae5753ca10394c6"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.0+6"

[[CatIndices]]
deps = ["CustomUnitRanges", "OffsetArrays"]
git-tree-sha1 = "a0f80a09780eed9b1d106a1bf62041c2efc995bc"
uuid = "aafaddc9-749c-510e-ac4f-586e18779b91"
version = "0.2.2"

[[CategoricalArrays]]
deps = ["DataAPI", "Future", "JSON", "Missings", "Printf", "Statistics", "StructTypes", "Unicode"]
git-tree-sha1 = "2ac27f59196a68070e132b25713f9a5bbc5fa0d2"
uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597"
version = "0.8.3"

[[Chain]]
git-tree-sha1 = "c72673739e02d65990e5e068264df5afaa0b3273"
uuid = "8be319e6-bccf-4806-a6f7-6fae938471bc"
version = "0.4.7"

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

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

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

[[ColorVectorSpace]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase"]
git-tree-sha1 = "4d17724e99f357bfd32afa0a9e2dda2af31a9aea"
uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4"
version = "0.8.7"

[[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 = "344f143fa0ec67e47917848795ab19c6a455f32c"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.32.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"

[[ComputationalResources]]
git-tree-sha1 = "52cb3ec90e8a8bea0e62e275ba577ad0f74821f7"
uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3"
version = "0.3.2"

[[Conda]]
deps = ["JSON", "VersionParsing"]
git-tree-sha1 = "299304989a5e6473d985212c28928899c74e9421"
uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d"
version = "1.5.2"

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

[[CoordinateTransformations]]
deps = ["LinearAlgebra", "StaticArrays"]
git-tree-sha1 = "6d1c23e740a586955645500bbec662476204a52c"
uuid = "150eb455-5306-5404-9cee-2592286d6298"
version = "0.6.1"

[[CoupledFields]]
deps = ["LinearAlgebra", "Statistics", "StatsBase"]
git-tree-sha1 = "6c9671364c68c1158ac2524ac881536195b7e7bc"
uuid = "7ad07ef1-bdf2-5661-9d2b-286fd4296dac"
version = "0.2.0"

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

[[CustomUnitRanges]]
git-tree-sha1 = "537c988076d001469093945f3bd0b300b8d3a7f3"
uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce"
version = "1.0.1"

[[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 = "4437b64df1e0adccc3e5d1adbc3ac741095e4677"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.9"

[[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 = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SparseArrays", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns"]
git-tree-sha1 = "a837fdf80f333415b69684ba8e8ae6ba76de6aaa"
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
version = "0.24.18"

[[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 = "92d8f9f208637e8d2d28c664051a00569c01493d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.1.5+1"

[[EllipsisNotation]]
deps = ["ArrayInterface"]
git-tree-sha1 = "8041575f021cba5a099a456b4163c9a08b566a02"
uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949"
version = "1.1.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", "LibVPX_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 = "3cc57ad0a213808473eafef4845a74766242e05f"
uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
version = "4.3.1+4"

[[FFTViews]]
deps = ["CustomUnitRanges", "FFTW"]
git-tree-sha1 = "70a0cfd9b1c86b0209e38fbfe6d8231fd606eeaf"
uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd"
version = "0.3.1"

[[FFTW]]
deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"]
git-tree-sha1 = "f985af3b9f4e278b1d24434cbb546d6092fca661"
uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
version = "1.4.3"

[[FFTW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "3676abafff7e4ff07bbd2c42b3d8201f31653dcc"
uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a"
version = "3.3.9+8"

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

[[FillArrays]]
deps = ["LinearAlgebra", "Random", "SparseArrays"]
git-tree-sha1 = "693210145367e7685d8604aee33d9bfb85db8b31"
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
version = "0.11.9"

[[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 = "35895cf184ceaab11fd778b4590144034a167a2f"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.1+14"

[[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 = "cbd58c9deb1d304f5a245a0b7eb841a2560cfec6"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.1+5"

[[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 = "d59e8320c2747553788e4fc42231489cc602fa50"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.58.1+0"

[[Gadfly]]
deps = ["Base64", "CategoricalArrays", "Colors", "Compose", "Contour", "CoupledFields", "DataAPI", "DataStructures", "Dates", "Distributions", "DocStringExtensions", "Hexagons", "IndirectArrays", "IterTools", "JSON", "Juno", "KernelDensity", "LinearAlgebra", "Loess", "Measures", "Printf", "REPL", "Random", "Requires", "Showoff", "Statistics"]
git-tree-sha1 = "96da4818e4d481a29aa7d66aac1eb778432fb89a"
uuid = "c91e804a-d5a3-530f-b6f0-dfbca275c004"
version = "1.3.3"

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

[[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"

[[Graphics]]
deps = ["Colors", "LinearAlgebra", "NaNMath"]
git-tree-sha1 = "2c1cf4df419938ece72de17f368a021ee162762e"
uuid = "a2bd30eb-e257-5431-a919-1863eab51364"
version = "1.1.0"

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

[[HTTP]]
deps = ["Base64", "Dates", "IniFile", "Logging", "MbedTLS", "NetworkOptions", "Sockets", "URIs"]
git-tree-sha1 = "44e3b40da000eab4ccb1aecdc4801c040026aeb5"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.9.13"

[[Hexagons]]
deps = ["Test"]
git-tree-sha1 = "de4a6f9e7c4710ced6838ca906f81905f7385fd6"
uuid = "a1b4810d-1bce-5fbd-ac56-80944d57a21f"
version = "0.2.0"

[[IdentityRanges]]
deps = ["OffsetArrays"]
git-tree-sha1 = "be8fcd695c4da16a1d6d0cd213cb88090a150e3b"
uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca"
version = "0.3.1"

[[IfElse]]
git-tree-sha1 = "28e837ff3e7a6c3cdb252ce49fb412c8eb3caeef"
uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
version = "0.1.0"

[[ImageAxes]]
deps = ["AxisArrays", "ImageCore", "Reexport", "SimpleTraits"]
git-tree-sha1 = "794ad1d922c432082bc1aaa9fa8ffbd1fe74e621"
uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac"
version = "0.6.9"

[[ImageContrastAdjustment]]
deps = ["ColorVectorSpace", "ImageCore", "ImageTransformations", "Parameters"]
git-tree-sha1 = "2e6084db6cccab11fe0bc3e4130bd3d117092ed9"
uuid = "f332f351-ec65-5f6a-b3d1-319c6670881a"
version = "0.3.7"

[[ImageCore]]
deps = ["AbstractFFTs", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"]
git-tree-sha1 = "db645f20b59f060d8cfae696bc9538d13fd86416"
uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534"
version = "0.8.22"

[[ImageDistances]]
deps = ["ColorVectorSpace", "Distances", "ImageCore", "ImageMorphology", "LinearAlgebra", "Statistics"]
git-tree-sha1 = "6378c34a3c3a216235210d19b9f495ecfff2f85f"
uuid = "51556ac3-7006-55f5-8cb3-34580c88182d"
version = "0.2.13"

[[ImageFiltering]]
deps = ["CatIndices", "ColorVectorSpace", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "ImageCore", "LinearAlgebra", "OffsetArrays", "Requires", "SparseArrays", "StaticArrays", "Statistics", "TiledIteration"]
git-tree-sha1 = "bf96839133212d3eff4a1c3a80c57abc7cfbf0ce"
uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5"
version = "0.6.21"

[[ImageIO]]
deps = ["FileIO", "Netpbm", "PNGFiles", "TiffImages", "UUIDs"]
git-tree-sha1 = "d067570b4d4870a942b19d9ceacaea4fb39b69a1"
uuid = "82e4d734-157c-48bb-816b-45c225c6df19"
version = "0.5.6"

[[ImageMagick]]
deps = ["FileIO", "ImageCore", "ImageMagick_jll", "InteractiveUtils", "Libdl", "Pkg", "Random"]
git-tree-sha1 = "5bc1cb62e0c5f1005868358db0692c994c3a13c6"
uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
version = "1.2.1"

[[ImageMagick_jll]]
deps = ["JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pkg", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "1c0a2295cca535fabaf2029062912591e9b61987"
uuid = "c73af94c-d91f-53ed-93a7-00f77d67a9d7"
version = "6.9.10-12+3"

[[ImageMetadata]]
deps = ["AxisArrays", "ColorVectorSpace", "ImageAxes", "ImageCore", "IndirectArrays"]
git-tree-sha1 = "ae76038347dc4edcdb06b541595268fca65b6a42"
uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49"
version = "0.9.5"

[[ImageMorphology]]
deps = ["ColorVectorSpace", "ImageCore", "LinearAlgebra", "TiledIteration"]
git-tree-sha1 = "68e7cbcd7dfaa3c2f74b0a8ab3066f5de8f2b71d"
uuid = "787d08f9-d448-5407-9aad-5290dd7ab264"
version = "0.2.11"

[[ImageQualityIndexes]]
deps = ["ColorVectorSpace", "ImageCore", "ImageDistances", "ImageFiltering", "OffsetArrays", "Statistics"]
git-tree-sha1 = "1198f85fa2481a3bb94bf937495ba1916f12b533"
uuid = "2996bd0c-7a13-11e9-2da2-2f5ce47296a9"
version = "0.2.2"

[[ImageShow]]
deps = ["Base64", "FileIO", "ImageCore", "OffsetArrays", "Requires", "StackViews"]
git-tree-sha1 = "832abfd709fa436a562db47fd8e81377f72b01f9"
uuid = "4e3cecfd-b093-5904-9786-8bbb286a6a31"
version = "0.3.1"

[[ImageTransformations]]
deps = ["AxisAlgorithms", "ColorVectorSpace", "CoordinateTransformations", "IdentityRanges", "ImageCore", "Interpolations", "OffsetArrays", "Rotations", "StaticArrays"]
git-tree-sha1 = "e4cc551e4295a5c96545bb3083058c24b78d4cf0"
uuid = "02fcd773-0e25-5acc-982a-7f6622650795"
version = "0.8.13"

[[Images]]
deps = ["AxisArrays", "Base64", "ColorVectorSpace", "FileIO", "Graphics", "ImageAxes", "ImageContrastAdjustment", "ImageCore", "ImageDistances", "ImageFiltering", "ImageIO", "ImageMagick", "ImageMetadata", "ImageMorphology", "ImageQualityIndexes", "ImageShow", "ImageTransformations", "IndirectArrays", "OffsetArrays", "Random", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "TiledIteration"]
git-tree-sha1 = "8b714d5e11c91a0d945717430ec20f9251af4bd2"
uuid = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
version = "0.24.1"

[[IndirectArrays]]
git-tree-sha1 = "c2a145a145dc03a7620af1444e0264ef907bd44f"
uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959"
version = "0.5.1"

[[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"

[[IntelOpenMP_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d979e54b71da82f3a65b62553da4fc3d18c9004c"
uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0"
version = "2018.0.3+2"

[[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 = "1470c80592cf1f0a35566ee5e93c5f8221ebc33a"
uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
version = "0.13.3"

[[IntervalSets]]
deps = ["Dates", "EllipsisNotation", "Statistics"]
git-tree-sha1 = "3cc368af3f110a767ac786560045dceddfc16758"
uuid = "8197267c-284f-5f27-9208-e0e47529a953"
version = "0.5.3"

[[InvertedIndices]]
deps = ["Test"]
git-tree-sha1 = "15732c475062348b0165684ffe28e85ea8396afc"
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
version = "1.0.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"

[[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"

[[JSON3]]
deps = ["Dates", "Mmap", "Parsers", "StructTypes", "UUIDs"]
git-tree-sha1 = "b3e5984da3c6c95bcf6931760387ff2e64f508f3"
uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
version = "1.9.1"

[[JSONLines]]
deps = ["CategoricalArrays", "JSON3", "Mmap", "OrderedCollections", "StructTypes", "Tables"]
git-tree-sha1 = "78b3adf109ed44c0b8f1bcbc4a4e100ff16881a4"
uuid = "24c2b838-1c8b-4567-aca0-d45e60436bb9"
version = "2.0.1"

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

[[Juno]]
deps = ["Base64", "Logging", "Media", "Profile"]
git-tree-sha1 = "07cb43290a840908a771552911a6274bc6c072c7"
uuid = "e5e0dc1b-0480-54bc-9374-aad01c23163d"
version = "0.8.4"

[[KernelDensity]]
deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"]
git-tree-sha1 = "591e8dc09ad18386189610acafb970032c519707"
uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b"
version = "0.6.3"

[[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"

[[LazyArtifacts]]
deps = ["Artifacts", "Pkg"]
uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3"

[[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"

[[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"

[[LibVPX_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "12ee7e23fa4d18361e7c2cde8f8337d4c3101bc7"
uuid = "dd192d2f-8180-539f-9fb4-cc70b1dcf69a"
version = "1.10.0+0"

[[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"

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

[[Loess]]
deps = ["Distances", "LinearAlgebra", "Statistics"]
git-tree-sha1 = "b5254a86cf65944c68ed938e575f5c81d5dfe4cb"
uuid = "4345ca2d-374a-55d4-8d30-97f9976e7612"
version = "0.5.3"

[[LogExpFunctions]]
deps = ["DocStringExtensions", "LinearAlgebra"]
git-tree-sha1 = "7bd5f6565d80b6bf753738d2bc40a5dfea072070"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.2.5"

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

[[MKL_jll]]
deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"]
git-tree-sha1 = "c253236b0ed414624b083e6b72bfe891fbd2c7af"
uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
version = "2021.1.1+1"

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

[[MappedArrays]]
git-tree-sha1 = "18d3584eebc861e311a552cbb67723af8edff5de"
uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900"
version = "0.4.0"

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

[[Match]]
git-tree-sha1 = "5cf525d97caf86d29307150fcba763a64eaa9cbe"
uuid = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf"
version = "1.1.0"

[[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"

[[Media]]
deps = ["MacroTools", "Test"]
git-tree-sha1 = "75a54abd10709c01f1b86b84ec225d26e840ed58"
uuid = "e89f7d12-3494-54d1-8411-f7d8b9ae1f27"
version = "0.5.0"

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

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

[[MosaicViews]]
deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"]
git-tree-sha1 = "b34e3bc3ca7c94914418637cb10cc4d1d80d877d"
uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389"
version = "0.3.3"

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

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

[[Netpbm]]
deps = ["ColorVectorSpace", "FileIO", "ImageCore"]
git-tree-sha1 = "09589171688f0039f13ebe0fdcc7288f50228b52"
uuid = "f09324ee-3d7c-5217-9330-fc30815ba969"
version = "1.0.1"

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

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

[[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"

[[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"

[[PNGFiles]]
deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"]
git-tree-sha1 = "520e28d4026d16dcf7b8c8140a3041f0e20a9ca8"
uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883"
version = "0.3.7"

[[PaddedViews]]
deps = ["OffsetArrays"]
git-tree-sha1 = "0fa5e78929aebc3f6b56e1a88cf505bb00a354c4"
uuid = "5432bcbf-9aad-5242-b902-cca2824c8663"
version = "0.5.8"

[[Parameters]]
deps = ["OrderedCollections", "UnPack"]
git-tree-sha1 = "2276ac65f1e236e0a6ea70baff3f62ad4c625345"
uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a"
version = "0.12.2"

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

[[PerceptualColourMaps]]
deps = ["Colors", "Images", "Interpolations", "LinearAlgebra", "Printf", "PyPlot", "Statistics"]
git-tree-sha1 = "1a590b17c9a2fc3933c23587330fb39b85e82e10"
uuid = "54e51dfa-9dd7-5231-aa84-a4037b83483a"
version = "0.3.5"

[[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"

[[PkgVersion]]
deps = ["Pkg"]
git-tree-sha1 = "a7a7e1a88853564e551e4eba8650f8c38df79b37"
uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688"
version = "0.1.1"

[[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 = "501c20a63a34ac1d015d5304da0e645f42d91c9f"
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
version = "1.0.11"

[[Plots]]
deps = ["Base64", "Contour", "Dates", "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 = "e39bea10478c6aff5495ab522517fae5134b40e3"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
version = "1.20.0"

[[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 = "cde4ce9d6f33219465b55162811d8de8139c0414"
uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
version = "1.2.1"

[[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"

[[Profile]]
deps = ["Printf"]
uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"

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

[[PyCall]]
deps = ["Conda", "Dates", "Libdl", "LinearAlgebra", "MacroTools", "Serialization", "VersionParsing"]
git-tree-sha1 = "169bb8ea6b1b143c5cf57df6d34d022a7b60c6db"
uuid = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
version = "1.92.3"

[[PyPlot]]
deps = ["Colors", "LaTeXStrings", "PyCall", "Sockets", "Test", "VersionParsing"]
git-tree-sha1 = "67dde2482fe1a72ef62ed93f8c239f947638e5a2"
uuid = "d330b81b-6aea-500a-939a-2ce795aea3ee"
version = "2.9.0"

[[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"

[[RangeArrays]]
git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5"
uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d"
version = "0.3.2"

[[Ratios]]
git-tree-sha1 = "37d210f612d70f3f7d57d488cb3b6eff56ad4e41"
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
version = "0.4.0"

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

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

[[Reexport]]
git-tree-sha1 = "5f6c21241f0f655da3952fd60aa18477cf96c220"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.1.0"

[[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"

[[RollingFunctions]]
deps = ["LinearAlgebra", "Statistics", "StatsBase", "Test"]
git-tree-sha1 = "cdf9158377f81470b1b73c630d0853a3ec0c7445"
uuid = "b0e4dd01-7b14-53d8-9b45-175a3e362653"
version = "0.6.2"

[[Rotations]]
deps = ["LinearAlgebra", "StaticArrays", "Statistics"]
git-tree-sha1 = "2ed8d8a16d703f900168822d83699b8c3c1a5cd8"
uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc"
version = "1.0.2"

[[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 = "a3a337914a035b2d59c9cbe7f1a38aaba1265b02"
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
version = "1.3.6"

[[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 = "508822dca004bf62e210609148511ad03ce8f1d8"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "1.6.0"

[[StackViews]]
deps = ["OffsetArrays"]
git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c"
uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15"
version = "0.1.1"

[[Static]]
deps = ["IfElse"]
git-tree-sha1 = "62701892d172a2fa41a1f829f66d2b0db94a9a63"
uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
version = "0.3.0"

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "3fedeffc02e47d6e3eb479150c8e5cd8f15a77a0"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.10"

[[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 = "fed1ec1e65749c4d96fc20dd13bea72b55457e62"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.33.9"

[[StatsFuns]]
deps = ["LogExpFunctions", "Rmath", "SpecialFunctions"]
git-tree-sha1 = "30cd8c360c54081f806b1ee14d2eecbef3c04c49"
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
version = "0.9.8"

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

[[StructTypes]]
deps = ["Dates", "UUIDs"]
git-tree-sha1 = "e36adc471280e8b346ea24c5c87ba0571204be7a"
uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
version = "1.7.2"

[[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"

[[TiffImages]]
deps = ["ColorTypes", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "OffsetArrays", "OrderedCollections", "PkgVersion", "ProgressMeter"]
git-tree-sha1 = "03fb246ac6e6b7cb7abac3b3302447d55b43270e"
uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69"
version = "0.4.1"

[[TiledIteration]]
deps = ["OffsetArrays"]
git-tree-sha1 = "52c5f816857bfb3291c7d25420b1f4aca0a74d18"
uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac"
version = "0.3.0"

[[URIs]]
git-tree-sha1 = "97bbe755a53fe859669cd907f2d96aee8d2c1355"
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
version = "1.3.0"

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

[[UnPack]]
git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b"
uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
version = "1.0.2"

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

[[VersionParsing]]
git-tree-sha1 = "80229be1f670524750d905f8fc8148e5a8c4537f"
uuid = "81def892-9a0e-5fdd-b105-ffc91e053289"
version = "1.2.0"

[[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", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "acc685bcf777b2202a904cdcb49ad34c2fa1880c"
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
version = "0.14.0+4"

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

[[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"

[[x264_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d713c1ce4deac133e3334ee12f4adff07f81778f"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2020.7.14+2"

[[x265_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "487da2f8f2f0c8ee0e83f39d13037d6bbf0a45ab"
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
version = "3.0.0+3"

[[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:
# ╟─1ed923c0-f5f0-11eb-3bef-f7866f2a40b0
# ╟─0035970f-f027-4eea-91e2-113b22710002
# ╟─c47d2950-cd1f-47a3-a213-b06a27eb0746
# ╟─5fc027ad-704f-4045-b281-08a128a204ea
# ╟─cfc7da80-170d-4eac-8367-f4c4a4aeadb2
# ╟─cf3ec4b5-c187-422b-81e5-dd1f03b9d96c
# ╟─d9f3c726-79e9-4c43-95ad-b73e508630a7
# ╟─1501042a-1ae2-44c6-a513-c36b4389fa72
# ╠═8fc7b1d2-15db-4356-b5f3-08c60ea2886c
# ╟─5839b81d-98ad-4672-ba05-2c92762c602a
# ╟─ea7a2d4d-69e9-4046-bb78-c6e4c36fb4b6
# ╟─fc36279e-2088-4eba-b48a-f05e82443540
# ╟─55ded444-4341-4132-9183-abb96671eea5
# ╟─baf58341-a518-40ca-bafa-d2e4127b3089
# ╟─e42a103e-292e-4fb8-b7c9-8cb47273d2cc
# ╟─e7bd101e-a647-4ffd-9770-27c350396831
# ╟─bca9cc5e-c243-4135-a350-393c50a99783
# ╟─187cff60-2820-43fd-9486-d0dd6f322fde
# ╟─fdc8f9ff-11e6-4a14-b4f5-44030672bd1d
# ╟─36db8d48-40f4-4c99-b371-9786ea05bc1f
# ╟─5a55fb1a-2b96-4d3c-b274-58adf26e975d
# ╠═f739cd9f-f6fb-4203-8af6-801408c69c3d
# ╟─cf8c89cf-54ad-40ef-8900-ae0a8b28f469
# ╠═a3ed2be4-b4c3-4490-8971-daac16b5967d
# ╠═d121c942-2b52-4c5a-8739-a9afd6f402fd
# ╠═0a6d3d99-37bc-40f4-95e5-91ef76b29844
# ╠═0350341b-738c-4012-9d0e-90f6aa15ee51
# ╠═d73bfb4c-8427-4c97-ba43-84623a1acf37
# ╠═a233f78f-32d6-4828-bd1e-b54e3e5b100e
# ╠═d85ab49d-f9b9-4b9b-a54c-801c3c0e4d86
# ╠═63c54d1e-af97-4d59-a7b3-79e688893c42
# ╟─f53e9f0c-b53d-4db6-abe2-2be82077bf38
# ╟─ec5e66ce-8244-4720-9cfb-13bdd1ade7bf
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_name: GPT-RL/generalization

max_issues_repo_name: GPT-RL/generalization

max_forks_repo_name: GPT-RL/generalization


text:
using Distributions: TDist, Uniform, Normal, cf
import Distributions: cdf
"""
      Binomial Distribution is a distribution well known for its use in
           statistical tests and decision making models. In order to calculate
           binomial distribution, you will need the positives and size of your array.\n
      --------------------\n
      positives = 5\n
      n = 10\n
      r = binomial_dist(positives,n)
       """
function binomial_dist(positives, size; mode = :REC)
    # p = n! / x!(n-x!)*π^x*(1-π)^N-x
    n = size
    x = positives
    if mode != :REC
        factn = factorial(big(n))
        factx = factorial(big(x))
    else
        factn = fact(n)
        factx = fact(x)
    end
    return(factn / (factx * (n-x)))
end
# ---- Normal Distribution ----
"""
    ## Normal Distribution
    ### Description
      Calculates the normal distribution of an array.\n
      --------------------\n
    ### Input
      NormalDist(x)\n
      --------------------\n
      #### Positional Arguments
      Array{Any} - x:: Array for which the normal distribution should use the
      data from.\n
      --------------------\n
     ### Output
     norm:: A Lathe distribution\n
     ---------------------\n
     ### Functions
     Distribution.apply(xt) :: Applies the distribution to xt\n
     Distribution.cdf(statistic, alpha, dof) :: Applies the distribution's
     corresponding cummulitive distribution function.\n
     ---------------------\n
     ### Data
     σ :: Standard Deviation of the input data.\n
     μ :: Mean of the input data.
       """
struct NormalDist{c, p} <: Distribution
           σ::Float64
           μ::Float64
           N::Int64
           cdf::c
           apply::p
           function NormalDist(array)
              N = length(array)
               σ = std(array)
               μ = mean(array)
               apply(xt) = Array{Real}([i = (i-μ) / σ for i in xt])
               cdf(xt) = bvnuppercdf(σ, μ, xt)
               new{typeof(cdf), typeof(apply)}(σ, μ, N, cdf, apply)
            end
end
# ---- T distribution ----
"""
    ## T Distribution
    ### Description
      Calculates the T distribution of an array.\n
      --------------------\n
    ### Input
      TDist(x)\n
      --------------------\n
      #### Positional Arguments
      Array{Any} - x:: Array for which the T distribution should use the
      data from.\n
      --------------------\n
     ### Output
     t:: A Lathe distribution\n
     ---------------------\n
     ### Functions
     Distribution.apply(xt) :: Applies the distribution to xt\n
     Distribution.cdf(statistic, alpha, dof) :: Applies the distribution's
     corresponding cummulitive distribution function.\n
     ---------------------\n
     ### Data
     μ :: Mean of the input data.\n
     N :: The length of the input data.
       """
struct T_Dist{c, p} <: Distribution
μ::Float64
N::Int64
apply::p
cdf::c

function T_Dist(general)
  norm = NormalDist(general)
  general = norm.apply(general)
  μ = mean(general)
  N = length(general)
  apply(xt) = (mean(norm.apply(xt)) - μ) / (std(norm.apply(xt)) / sqrt(N))
  cdf(t, dog) = cf(TDist(dog), Real(t))
  new{typeof(cdf), typeof(apply)}(μ, N, apply, cdf)
  end
end
# ---- Uniform Dist ----
"""
    ## Uniform Distribution
    ### Description
      Calculates the Uniform distribution of an array.\n
      --------------------\n
    ### Input
      UniformDist(x)\n
      --------------------\n
      #### Positional Arguments
      Array{Any} - x:: Array for which the T distribution should use the
      data from.\n
      --------------------\n
     ### Output
     t:: A Lathe distribution\n
     ---------------------\n
     ### Functions
     Distribution.apply(xt) :: Applies the distribution to xt\n
     Distribution.cdf(xt) :: Applies the distribution's
     corresponding cummulitive distribution function.\n
     ---------------------
       """
function UniformDist(array)
    dist = Uniform(minimum(array), maximum(array))
    apply(xt) = pdf(dist, xt)
    cdf(x) = cdf(dist, x)
    (var) ->(dist;cdf;apply)
end

function bvnuppercdf(dh::Float64, dk::Float64, r::Float64)
	if abs(r) < 0.3
	   ng = 1
	   lg = 3
	elseif abs(r) < 0.75
	   ng = 2
	   lg = 6
	else
	   ng = 3
	   lg = 10
	end
	h = dh
	k = dk
	hk = h*k
	bvn = 0.0
	if abs(r) < 0.925
	   	if abs(r) > 0
	      	hs = (h * h + k * k) * 0.5
	      	asr = asin(r)
	      	for i = 1:lg
	         	for j = -1:2:1
	            	sn = sin(asr * (j * bvncdf_x_array[i, ng] + 1.0) * 0.5)
	            	bvn += bvncdf_w_array[i, ng] * exp((sn * hk - hs) / (1.0 - sn*sn))
	        	end
	      	end
	      	bvn *= asr / (4.0pi)
	   	end
	   	bvn += cdf(Normal(), -h) * cdf(Normal(), -k)
	else
	   	if r < 0
	      	k = -k
	      	hk = -hk
	   	end
	   	if abs(r) < 1
	      	as = (1.0 - r) * (1.0 + r)
	      	a = sqrt(as)
	      	bs = (h - k)^2
	      	c = (4.0 - hk) * 0.125
	      	d = (12.0 - hk) * 0.0625
	      	asr = -(bs / as + hk) * 0.5
	      	if ( asr > -100 )
	      		bvn = a * exp(asr) * (1.0 - c * (bs - as) * (1.0 - d * bs / 5.0) / 3.0 + c * d * as * as / 5.0)
	      	end
	      	if -hk < 100
	         	b = sqrt(bs)
	         	bvn -= exp(-hk * 0.5) * sqrt(2.0pi) * cdf(Normal(), -b / a) * b * (1.0 - c * bs * (1.0 - d * bs / 5.0) / 3.0)
	      	end
	     	a /= 2.0
		    for i = 1:lg
	         	for j = -1:2:1
	            	xs = (a * (j*bvncdf_x_array[i, ng] + 1.0))^2
	            	rs = sqrt(1.0 - xs)
	            	asr = -(bs / xs + hk) * 0.5
	            	if asr > -100
	               		bvn += a * bvncdf_w_array[i, ng] * exp(asr) * (exp(-hk * (1.0 - rs) / (2.0 * (1.0 + rs))) / rs - (1.0 + c * xs * (1.0 + d * xs)))
	            	end
	         	end
	        end
	      	bvn /= -2.0pi
	   	end
	   	if r > 0
	      	bvn += cdf(Normal(), -max(h, k))
	   	else
	      	bvn = -bvn
	      	if k > h
	      		bvn += cdf(Normal(), k) - cdf(Normal(), h)
	      	end
		end
	end
	return bvn
end

ext: jl


text:
"""
    objective_function_template(nobs::Function, obj_contribution::Function)

Define an `objective_function_template` by supplying:
+ `nobs`: a function of `data` that computes the number of observations of the particular data type,
+ `obj_contribution`: a function of the parameters `theta`, the `data` and the observation index `i` that returns a real.
"""
struct objective_function_template
    nobs::Function
    obj_contribution::Function
end

"""

    objective_function(theta::Vector, data::Any, template::objective_function_template, br::Bool = false)

Construct the objective function by adding up all contributions in the
`data` according to [`objective_function_template`](@ref), and
evaluate it at `theta`. If `br = true` then automatic differentiation
is used to compute the empirical bias-reducing penalty and add it to
the objective function.
"""
function objective_function(theta::Vector,
                            data::Any,
                            template::objective_function_template,
                            br::Bool = false)
    p = length(theta)
    n_obs = template.nobs(data)
    contributions = Vector(undef, n_obs)
    for i in 1:n_obs
        contributions[i] = template.obj_contribution(theta, data, i)
    end
    if (br)
        quants = obj_quantities(theta, data, template, br)
        sum(contributions) + quants[1]
    else
        sum(contributions)
    end
end

function obj_quantities(theta::Vector,
                        data::Any,
                        template::objective_function_template,
                        penalty::Bool = false)
    npsi(eta::Vector, i::Int) = ForwardDiff.gradient(beta -> template.obj_contribution(beta, data, i), eta)
    nj(eta::Vector, i::Int) = ForwardDiff.hessian(beta -> template.obj_contribution(beta, data, i), eta)
    p = length(theta)
    n_obs = template.nobs(data)
    psi = Matrix{Float64}(undef, n_obs, p)
    njmats = Vector(undef, n_obs)
    for i in 1:n_obs
        psi[i, :] =  npsi(theta, i)
        njmats[i] = nj(theta, i)
    end
    jmat_inv = inv(-sum(njmats))
    emat = psi' * psi
    vcov = jmat_inv * (emat * jmat_inv)
    if (penalty)
        penalty = - tr(jmat_inv * emat) / 2
        [penalty, jmat_inv, emat]
    else
        [vcov, jmat_inv, emat]
    end
end


text:
@inline function reim(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
     return x.re, x.im
end

square(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat} = x*x

# development from functions.wolfram.com

function sqrt(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    fourthroot = sqrt(hypot(rea, ima))
    halfatan = atan(ima, rea) * 0.5
    rea = fourthroot * cos(halfatan)
    ima = fourthroot * sin(halfatan)
    return Complex{DoubleFloat{T}}(rea, ima)
end

function exp(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    erea = exp(rea)
    realpart = erea * cos(ima)
    imagpart = erea * sin(ima)
    return Complex{DoubleFloat{T}}(realpart, imagpart)
end

function log(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    realpart = log(square(rea) + square(ima)) * 0.5
    imagpart = atan(ima, rea)
    return Complex{DoubleFloat{T}}(realpart, imagpart)
end

function sin(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    rea, ima = sin(rea) * cosh(ima), cos(rea) * sinh(ima)
    return Complex{DoubleFloat{T}}(rea, ima)
end

function cos(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    rea, ima = cos(rea) * cosh(ima), -sin(rea) * sinh(ima)
    return Complex{DoubleFloat{T}}(rea, ima)
end

function tan(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = 2*real(x), 2*imag(x)
    den = cos(rea) + cosh(ima)
    rea = sin(rea) / den
    ima = sinh(ima) / den
    return Complex{DoubleFloat{T}}(rea, ima)
end

function csc(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    den = cos(2*rea) - cosh(2*ima)
    rea, ima = 2*(sin(rea)*cosh(ima)), 2*(cos(rea)*sinh(ima))
    rea = -rea / den
    ima = ima / den
    return Complex{DoubleFloat{T}}(rea, ima)
end

function sec(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    den = cos(2*rea) + cosh(2*ima)
    rea, ima = 2*(cos(rea)*cosh(ima)), 2*(sin(rea)*sinh(ima))
    rea = rea / den
    ima = ima / den
    return Complex{DoubleFloat{T}}(rea, ima)
end

function cot(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = 2*real(x), 2*imag(x)
    den = cos(rea) - cosh(ima)
    rea = -sin(rea) / den
    ima = sinh(ima) / den
    return Complex{DoubleFloat{T}}(rea, ima)
end

function sinh(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    rea, ima = sinh(rea) * cos(ima), cosh(rea) * sin(ima)
    return Complex{DoubleFloat{T}}(rea, ima)
end

function cosh(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    rea, ima = cosh(rea) * cos(ima), sinh(rea) * sin(ima)
    return Complex{DoubleFloat{T}}(rea, ima)
end

function tanh(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = 2*real(x), 2*imag(x)
    den = cosh(rea) + cos(ima)
    rea = sinh(rea) / den
    ima = sin(ima) / den
    return Complex{DoubleFloat{T}}(rea, ima)
end

function csch(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    den = cos(2*ima) - cosh(2*rea)
    rea, ima = 2*(sinh(rea)*cos(ima)), 2*(cosh(rea)*sin(ima))
    rea = -rea / den
    ima = ima / den
    return Complex{DoubleFloat{T}}(rea, ima)
end

function sech(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    den = cos(2*ima) + cosh(2*rea)
    rea, ima = 2*(cos(ima)*cosh(rea)), 2*(sin(ima)*sinh(rea))
    rea = rea / den
    ima = -ima / den
    return Complex{DoubleFloat{T}}(rea, ima)
end

function coth(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = 2*real(x), 2*imag(x)
    den = cos(ima) - cosh(rea)
    rea = -sinh(rea) / den
    ima = sin(ima) / den
    return Complex{DoubleFloat{T}}(rea, ima)
end

function asin(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    xp1sq = square(rea + 1)
    xm1sq = square(rea - 1)
    ysq   = square(ima)
    xp1py = sqrt(xp1sq + ysq)
    xm1py = sqrt(xm1sq + ysq)
    rea = asin((xp1py - xm1py) * 0.5)
    x = (xm1py + xp1py) * 0.5
    ima = sign(ima) * log(x + sqrt(square(x) - 1))
   return Complex{DoubleFloat{T}}(rea, ima)
end

function acos(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    xp1sq = square(rea + 1)
    xm1sq = square(rea - 1)
    ysq   = square(ima)
    xp1py = sqrt(xp1sq + ysq)
    xm1py = sqrt(xm1sq + ysq)
    rea = acos((xp1py - xm1py) * 0.5)
    x = (xm1py + xp1py) * 0.5
    ima = -sign(ima) * log(x + sqrt(square(x) - 1))
   return Complex{DoubleFloat{T}}(rea, ima)
end

function atan(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    ima2 = square(ima)
    rea2 = square(rea)
    realpart = 0.5*(atan(2*rea/(1-rea2-ima2)) + (pio2(DoubleFloat{T})*(sign(rea2+ima2-1)+1)) * sign(rea))
    imagpart = (log(square(ima + 1) + rea2) - log(rea2 + square(1 - ima))) * 0.25
    return Complex{DoubleFloat{T}}(realpart, imagpart)
end

function acsc(z::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    return asin(inv(z))
end

function asec(z::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    return acos(inv(z))
end

function acot(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    ima2 = square(ima)
    rea2 = square(rea)
    den = rea2 + ima2
    realpart = (atanxy((1 + (ima/den)), (rea/den)) - atanxy((1 - (ima/den)), -(rea/den))) * 0.5
    imagpart = (log((square(ima - 1) + rea2)/den) - log((square(ima +1) + rea2)/den)) * 0.25
    return Complex{DoubleFloat{T}}(realpart, imagpart)
end

function asinh(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    return log( x + sqrt(square(x) + 1) )
end

function acosh(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    t2 = (rea - 1) ^ 2
    t3 = ima ^ 2
    t5 = sqrt(t2 + t3)
    t8 = (rea + 1) ^ 2
    t10 = sqrt(t8 + t3)
    t15 = sqrt((t5 + t10) ^ 2 / 4 - 1)
    t17 = log(t5 / 2 + t10 / 2 + t15)
    t19 = acos(-t10 / 2 + t5 / 2)
    t19 = pio1(DoubleFloat{T}) - t19
    return Complex{DoubleFloat{T}}(t17, t19)
end

function atanh(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    ima2 = square(ima)
    rea2 = square(rea)
    realpart = (log(square(rea + 1) + ima2) - log(square(rea) - 2*rea + ima2 + 1)) * 0.25
    imagpart = 0.5*(atan(2*ima/(1-rea2-ima2)) + (pio2(DoubleFloat{T})*(sign(rea2+ima2-1)+1)) * sign(ima))
    return Complex{DoubleFloat{T}}(realpart, imagpart)
end

function acsch(z::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(z)
    t1 = square(ima)
    t2 = square(rea)
    t3 = t1 + t2
    t4 = inv(t3)
    t6 = square(t2)
    t8 = square(t1 - 1)
    t13 = square(t3)
    t14 = inv(t13)
    t16 = t14 * (t6 + t8 + 2 * (t1 + 1) * t2)
    t16 = sqrt(sqrt(t16))
    t23 = atanxy(1 + t14 * (-t1 + t2), -2 * t14 * ima * rea)
    t24 = t23 / 2
    t25 = cos(t24)
    t28 = square(t4 * rea + t25 * t16)
    t30 = sin(t24)
    t33 = square(t4 * ima - t30 * t16)
    t35 = log(t28 + t33)/2
    t37 = t16 * t3
    t44 = atanxy((t25 * t37 + rea) * t4, (t30 * t37 - ima) * t4)
    return Complex{DoubleFloat{T}}(t35, t44)
end

function asech(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    return log((sqrt(1-square(x))+1)/x)
end

function acoth(x::Complex{DoubleFloat{T}}) where {T<:IEEEFloat}
    rea, ima = reim(x)
    rea2 = square(rea)
    ima2 = square(ima)
    den = rea2 + ima2
    num = den + 1
    num1 = num + 2*rea
    num2 = num - 2*rea
    realpart = (log(num1/den) - log(num2/den)) * 0.25
    num1 = rea / den
    num2 = ima / den
    imagpart = (atanxy(num1 + 1, -num2) - atanxy(1 - num1, num2)) * 0.5
    return Complex{DoubleFloat{T}}(realpart, imagpart)
end


text:
using LinearAlgebra
using Plots

using JuMP, Ipopt

# large random qp test
n = 20
m = 10
p = 5
P = rand(n,n)
P = P'*P
@show isposdef(P)
q = rand(n)
r = rand(1)[1]

A = rand(m,n)
b = rand(m)
C = rand(p,n)
d = rand(p)

# Validate model with JuMP
model = JuMP.Model(solver=IpoptSolver(print_level=0))

@variable(model, x[1:n])
@objective(model, Min, 0.5*x'*P*x + x'*q + r)
@constraint(model, con, A*x .>= b)
@constraint(model, con2, C*x .== d)
print(model)
status = JuMP.solve(model)
println("Objective value: ", getobjectivevalue(model))
println("x = ", getvalue(x))
println("λ = ", getdual(con),getdual(con2))

# Augmented Lagrangian
# n = 2
# P = [2.0 0.0; 0.0 2.0]
# q = [-2.0; -5.0]
# r = 7.25
#
# A = [1.0 -2.0;
#      -1.0 -2.0;
#      -1.0 2.0;
#      1.0 0.0;
#      0.0 1.0]
# b = [-2.0; -6.0; -2.0; 0.0; 0.0]

# n = 3
# P = [6. 2. 1.; 2. 5. 2.; 1. 2. 4.]
# q = [-8.; -3.; -3]
# r = 0
# A = [1. 0. 1.; 0. 1. 1.]
# b = [3.; 0.]

# # Validate model with JuMP
# model = JuMP.Model(solver=IpoptSolver(print_level=0))
#
# @variable(model, x[1:n])
# @objective(model, Min, 0.5*x'*P*x + x'*q + r)
# @constraint(model, con, A*x .>= b)
# # @constraint(model, con2, C*x .== d )
# print(model)
# status = JuMP.solve(model)
# println("Objective value: ", getobjectivevalue(model))
# println("x = ", getvalue(x))
# println("λ = ", getdual(con))#,getdual(con2))

##
b = [b;d]
A = [A;C]

f(x) = 0.5*x'*P*x + q'*x + r
∇f(x) = P*x + q
∇²f(x) = P

L(x,λ,Iμ) = 0.5*x'*P*x + q'*x + r + λ'*(b - A*x) + 0.5*(b - A*x)'*Iμ*(b - A*x)
∇L(x,λ,Iμ) = P*x + q + (-A)'*(λ +Iμ*(b - A*x))
∇²L(x,λ,Iμ) = P + (-A)'*Iμ*(-A)

g(x) = b - A*x
∇g(x) = -A

pI = m
pE = p
p = pI + pE

mutable struct Results
    x::Vector
    c::Vector
    c_prev::Vector
    λ::Vector
    λ_prev::Vector
    μ::Vector
    Iμ::Matrix
    H::Matrix

    val::Array
    grad::Array

    function Results(n::Int,p::Int)
        new(zeros(n),
        zeros(p),zeros(p),
        zeros(p),zeros(p),
        ones(p),
        1.0*Matrix(I,p,p),
        1.0*Matrix(I,p,p),
        Inf*ones(1),
        Inf*ones(1))
    end
end

struct Objective
    n::Int
    p::Int
    pI::Int
    f::Function
    P::Matrix
    q::Vector
    ∇f::Function
    ∇²f::Function
    L::Function
    ∇L::Function
    ∇²L::Function
    g::Function
    A::Matrix
    b::Vector
    ∇g::Function
end

mutable struct Opts
    iterations_outer::Int
    ϵ_gradient_norm::Float64
    ϵ_constraint_max::Float64
    γ::Float64
    τ::Float64
    bfgs_threshold::Float64
end

function solve_AuLa(x0,results,model,opts,p_update=:default,d_update=:first)
    x = results.x
    c = results.c
    c_prev = results.c_prev
    λ = results.λ
    λ_prev = results.λ_prev
    μ = results.μ
    Iμ = results.Iμ
    H = results.H
    val = results.val
    grad = results.grad

    x[:] = copy(x0)
    c[:] = mdl.g(x)
    Iμ_update!(results,mdl)
    c_prev[:] = c

    val[1] = mdl.L(x,λ,Iμ)[1]
    grad[1] = norm(mdl.∇L(x,λ,Iμ))

    val_hist = []
    grad_hist = []
    c_max_hist = []
    λ_hist = []
    c_max = 0
    outer_iter = 0
    for i = 1:opts.iterations_outer
        iter = 0
        while iter < 10 && norm(mdl.∇L(x,λ,Iμ)) > opts.ϵ_gradient_norm
            x[:] = -(mdl.P + mdl.A'*Iμ*A)\(mdl.q - mdl.A'*λ - mdl.A'*Iμ*mdl.b)
            c[:] = mdl.g(x)
            Iμ_update!(results,mdl)
            val[1] = mdl.L(x,λ,Iμ)
            grad[1] = norm(mdl.∇L(x,λ,Iμ))

            c_max = max_violation(results,model)
            push!(val_hist,val[1])
            push!(grad_hist,norm(grad))
            push!(c_max_hist,c_max)

            iter += 1
        end
        outer_iter = i
        if norm(grad) < opts.ϵ_gradient_norm && c_max < opts.ϵ_constraint_max
            println("*Solved*")
            break
        end

        if i == opts.iterations_outer
            println("--Solve Failed--")
        end

        outer_loop_update!(results,mdl,opts,p_update,d_update)
        Iμ_update!(results,mdl)
        push!(λ_hist,λ)
    end
    @show x
    @show c
    @show λ
    @show μ
    @show λ_prev
    @show c_prev
    @show L(x,λ,Iμ)
    @show f(x)
    return val_hist, grad_hist, c_max_hist, λ_hist, outer_iter
end

function Iμ_update!(results,model)
    for j = 1:model.p
        if ((model.g(results.x)[j] > 0.0 || results.λ[j] > 0.0) && j <= model.pI) || j > model.pI
            results.Iμ[j,j] = results.μ[j]
        else
            results.Iμ[j,j] = 0.0
        end
    end
end

function max_violation(results,model)
    maximum(map(x->x.>0, results.Iμ)*model.g(results.x))
end

function outer_loop_update!(results,model,opts,p_update=:default,d_update=:first)
    if p_update == :default
        if d_update == :buys
            active_set = zeros(Bool,p)
            for i = 1:p
                if results.Iμ[i,i] > 0.
                    active_set[i] = true
                end
            end
            results.λ[active_set] += (model.∇g(results.x)[active_set,:]*(model.∇²L(results.x,results.λ,results.Iμ)\model.∇g(results.x)[active_set,:]'))\model.g(results.x)[active_set]
            results.λ[1:model.pI] = max.(0.0,results.λ[1:model.pI])
        elseif d_update == :bfgs && maximum(results.μ) <= opts.bfgs_threshold
            results.λ .+= results.H*model.g(results.x)
            results.λ[1:model.pI] = max.(0.0,results.λ[1:model.pI])
        else # :first
            results.λ .+= results.μ.*results.c
            results.λ[1:pI] = max.(0.0,results.λ[1:pI])
        end
        if d_update != :bfgs || (d_update == :bfgs && maximum(results.μ) <= opts.bfgs_threshold)
            results.μ .= opts.γ.*results.μ
        end
    end

    if p_update == :feedback
        if d_update == :buys
            λ_step = zeros(p)
            active_set = zeros(Bool,p)
            for j = 1:p
                if results.Iμ[j,j] > 0.
                    active_set[j] = true
                end
            end
            λ_step[active_set] = results.λ[active_set] + (model.∇g(results.x)[active_set,:]*(model.∇²L(results.x,results.λ,results.Iμ)\model.∇g(results.x)[active_set,:]'))\model.g(results.x)[active_set]
        end
        if d_update == :bfgs
            λ_step = results.λ + results.H*model.g(results.x)
        end

        for i = 1:model.p
            if i <= model.pI
                if max(0.0,results.c[i]) <= opts.τ*max(0.0,results.c_prev[i])
                    if d_update == :buys
                        results.λ[i] = max.(0.0,λ_step[i])
                    elseif d_update == :bfgs && maximum(results.μ) <= opts.bfgs_threshold
                        results.λ[i] = max.(0.0,λ_step[i])
                    else
                        results.λ[i] += results.μ[i]*results.c[i]
                        results.λ[i] = max(0.0,results.λ[i])
                    end
                else
                    # results.μ[i] = opts.γ*results.μ[i]
                    if d_update != :bfgs || (d_update == :bfgs && maximum(results.μ) <= opts.bfgs_threshold)
                        results.μ[i] = opts.γ*results.μ[i]
                    end
                end
            else
                if abs(results.c[i]) <= opts.τ*abs(results.c_prev[i])
                    if d_update == :buys
                        results.λ[i] = λ_step[i]
                    elseif d_update == :bfgs && maximum(results.μ) <= opts.bfgs_threshold
                        results.λ[i] = λ_step[i]
                    else
                        results.λ[i] += results.μ[i]*results.c[i]
                    end
                else
                    # results.μ[i] *= opts.γ
                    if d_update != :bfgs || (d_update == :bfgs && maximum(results.μ) <= opts.bfgs_threshold)
                        results.μ[i] = opts.γ*results.μ[i]
                    end
                end
            end
        end
    end

    if d_update == :bfgs
        if maximum(results.μ) >= opts.bfgs_threshold
            y = results.c - results.c_prev
            s = results.λ - results.λ_prev

            if y'*s != 0.0
                ρ = 1.0/(y'*s)
            else
                ρ = 0.0
            end
            results.H .= (I - ρ*s*y')*results.H*(I - ρ*y*s') + ρ*s*s'
        end
    end

    results.c_prev .= copy(results.c)
    results.λ_prev .= copy(results.λ)
end

# L(x,λ,μ) = f(x) + λ'*g(x) + 0.5*g(x)'*Iμ(x,λ,μ)*g(x)
# ∇L(x,λ,μ) = ∇f(x) + ∇g(x)'*(λ +Iμ(x,λ,μ)*g(x))
# ∇²L(x,λ,μ) = ∇²f(x) + ∇g(x)'*Iμ(x,λ,μ)*∇g(x)
x0 = zeros(n)
mdl = Objective(n,p,pI,f,P,q,∇f,∇²f,L,∇L,∇²L,g,A,b,∇g)
opts = Opts(20,1e-8,1e-8,10,0.25,10)

results = Results(n,p)
val_hist, grad_hist, c_max_hist, λ_hist, outer_iter = solve_AuLa(x0,results,mdl,opts,:feedback,:buys)
@show outer_iter
# plot(val_hist,xlabel="iteration",ylabel="Cost")
# plot(grad_hist,xlabel="iteration",ylabel="Gradient l2-norm")
plot(c_max_hist,xlabel="iteration",ylabel="max violation")
c_max_hist[end]

val_hist


text:
using Test
using AeroAcoustics
import DSP

# Generate a test signal, a 2 Vrms sine wave at 1234 Hz, corrupted by
# 0.001 V**2/Hz of white noise sampled at 10 kHz.
# From scipy.signal.welch docs:
# https://github.com/scipy/scipy/blob/f2ec91c4908f9d67b5445fbfacce7f47518b35d1/scipy/signal/spectral.py#L223

@testset "CSM test:" begin
    fs = 10e3
    N = 1e5
    amp = 2*sqrt(2)
    fr = 1234.0
    noise_power = 0.001*fs/2
    time = (1:N)/fs
    x = amp*sin.(2*pi*fr.*time)
    x .+= sqrt.(noise_power).*rand(length(time))
    n = 1024
    Pxx_d = csm(x;n=n,noverlap=div(n,2),win=DSP.hanning(n),fs=fs,scaling="density")
    fc = Pxx_d.fc
    Pxx_d1 = real.(Pxx_d[1,1,:])
    Pxx_w = DSP.welch_pgram(x,n;onesided=true,fs=fs,window=DSP.hanning(n))
    @test Pxx_d1 ≈ Pxx_w.power
    @test Pxx_d == AeroAcoustics.csm_slow(x;n=n,noverlap=div(n,2),win=DSP.hanning(n),fs=fs,scaling="density")

    Pxx_s = csm(x;n=n,noverlap=div(n,2),win=DSP.hanning(n),fs=fs,scaling="spectrum")
    fc = Pxx_s.fc
    Pxx_s1 = real.(Pxx_s[1,1,:])
    ENBW = enbw(fs,DSP.hanning(1024))
    @test Pxx_s1 ≈ Pxx_w.power*ENBW
    @test Pxx_s == AeroAcoustics.csm_slow(x;n=n,noverlap=div(n,2),win=DSP.hanning(n),fs=fs,scaling="spectrum")
end


text:
module TestVariableTemplates

using Test
using StaticArrays
using ClimateMachine.VariableTemplates

@testset "VariableTemplates" begin
    include("test_base_functionality.jl")
    include("varsindex.jl")
    include("test_complex_models.jl")
end

end


text:
using NumericalMethodsforEngineers
using Test

A = Float64[3 -2 1;-2 3 2;1 2 2]
b = Float64[3, -3, 2]

L, U = lufac(A)
F = lu(A)

@test round.(U, digits=5) == [3.0 -2.0 1.0;0.0 1.66667 2.66667;0.0 0.0 -2.6]


text:
@testset "utils.jl" begin
    @testset "consistency_ranges" begin
        # consistency bars
        # single prediction
        @test ReliabilityDiagrams.consistency_ranges([0.0], ConsistencyBars()) == (0.0, 0.0)
        @test ReliabilityDiagrams.consistency_ranges([0.5], ConsistencyBars()) == (0.0, 1.0)
        @test ReliabilityDiagrams.consistency_ranges([1.0], ConsistencyBars()) == (1.0, 1.0)

        # multiple predictions
        @test ReliabilityDiagrams.consistency_ranges([0.0, 0.0], ConsistencyBars()) ==
              (0.0, 0.0)
        @test ReliabilityDiagrams.consistency_ranges([0.0, 1.0], ConsistencyBars()) ==
              (0.0, 1.0)
        @test ReliabilityDiagrams.consistency_ranges([1.0, 1.0], ConsistencyBars()) ==
              (1.0, 1.0)

        # dictionary of bins with predictions
        dict = OrderedDict(1 => rand(5), 2 => rand(3), 4 => rand(6))
        ranges = ReliabilityDiagrams.consistency_ranges(
            dict, ConsistencyBars(; samples=100_000)
        )
        @test ranges isa Vector{Tuple{Float64,Float64}}
        @test all(0 ≤ x[1] ≤ x[2] ≤ 1 for x in ranges)
        @test length(ranges) == 3
        for ((k, probs), range) in zip(dict, ranges)
            ranges_k = ReliabilityDiagrams.consistency_ranges(
                probs, ConsistencyBars(; samples=100_000)
            )
            @test 0 ≤ ranges_k[1] ≤ ranges_k[2] ≤ 1
            @test ranges_k[1] ≈ range[1] atol = 1e-2
            @test ranges_k[2] ≈ range[2] atol = 1e-2
        end

        # no consistency bars
        probabilities = OrderedDict{Int,Vector{Float64}}(1 => rand(10), 3 => rand(2))
        ranges = ReliabilityDiagrams.consistency_ranges(probabilities, nothing)
        @test ranges isa Vector{Tuple{Float64,Float64}}
        @test length(ranges) == 2
        @test all(isnan(x[1]) && isnan(x[2]) for x in ranges)
    end

    @testset "means_and_bars" begin
        probabilities = rand(100)
        outcomes = rand(Bool, 100)

        for binning in (EqualSize(; n=13), EqualMass(; n=17)),
            consistencybars in (ConsistencyBars(), nothing)
            # compute mean probabilities, frequencies, and consistency ranges
            meanprobabilities, meanfrequencies, ranges = ReliabilityDiagrams.means_and_bars(
                probabilities, outcomes; binning=binning, consistencybars=consistencybars
            )

            # check that length of arrays is consistent
            @test 1 ≤ length(meanprobabilities) ≤ binning.n
            @test length(meanfrequencies) == length(meanfrequencies)
            @test length(ranges) == length(meanfrequencies)

            # ensure that probabilities are sorted
            @test issorted(meanprobabilities)

            # check that length of arrays is correct
            bins = ReliabilityDiagrams.bins(probabilities, outcomes, binning)
            binindices = [ReliabilityDiagrams.binindex(bins, p) for p in probabilities]
            indices = unique(binindices)
            @test length(meanprobabilities) == length(indices)

            # check that values of mean probabilities and frequencies are correct
            indices_of_means = [
                ReliabilityDiagrams.binindex(bins, x) for x in meanprobabilities
            ]
            @test sort(indices) == sort(indices_of_means)
            for (j, index) in enumerate(indices_of_means)
                meanprobs = mean(
                    p for (p, b) in zip(probabilities, binindices) if b == index
                )
                meanfreqs = mean(o for (o, b) in zip(outcomes, binindices) if b == index)
                @test meanprobs ≈ meanprobabilities[j]
                @test meanfreqs ≈ meanfrequencies[j]
            end

            # rough test of consistency ranges
            if consistencybars === nothing
                @test all(isnan(x[1]) && isnan(x[2]) for x in ranges)
            else
                @test all(
                    0 ≤ x[1] ≤ y ≤ x[2] ≤ 1 for (x, y) in zip(ranges, meanprobabilities)
                )
            end
        end

        # exception
        for binning in (EqualSize(; n=12), EqualMass(; n=8)),
            consistencybars in (ConsistencyBars(), nothing)

            @test_throws ErrorException ReliabilityDiagrams.means_and_bars(
                rand(100), rand(Bool, 99); binning=binning, consistencybars=consistencybars
            )
            @test_throws ErrorException ReliabilityDiagrams.means_and_bars(
                rand(100), rand(Bool, 101); binning=binning, consistencybars=consistencybars
            )
        end
    end
end


text:
using Test
import Utils: date_in_years
import Dates: Date

@testset "Dates and Times" begin
    nw = Date( 2020, 01, 27)
    d = Date(1958,01,28)
    @test Utils.age_in_years( d, nw ) == 61
    d = Date(1958,01,27)
    @test Utils.age_in_years( d, nw ) == 62
    d = Date(1958,01,26)
    @test Utils.age_in_years( d, nw ) == 62

end # dates and times