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

using Markdown
using InteractiveUtils

# ╔═╡ 5e179f89-2302-4342-987f-ff341fa824b1
begin

	# import some packages -
	using PlutoUI
	using PrettyTables
	using Optim
	using Plots
	using LinearAlgebra

	# setup paths -
	const _PATH_TO_NOTEBOOK = pwd()
	const _PATH_TO_DATA = joinpath(_PATH_TO_NOTEBOOK,"data")
	const _PATH_TO_FIGS = joinpath(_PATH_TO_NOTEBOOK,"figs")
	const _PATH_TO_SRC = joinpath(_PATH_TO_NOTEBOOK,"src")

	# return -
	nothing
end

# ╔═╡ 84cd8fcb-f0f7-480b-abe6-58686d6bd7e2
md"""
### Reversibilty of a Metabolic Reaction

In this lecture, we will
1. Introduce a general model for the flux bounds constraints in a constraint-based calculation
1. Introduce direct Gibbs energy minimization using the partial molar Gibbs energy
1. Compute the reversibility of a single enzyme-catalyzed reaction
"""

# ╔═╡ db68d9a1-7b50-466d-985a-13bc8a2c3a03
md"""
### A model for flux bounds
The flux bounds are important constraints in flux balance analysis calculations and the convex decomposition of the stoichiometric array. Beyond their role in the flux estimation problem, the flux bounds are _integrative_, i.e., these constraints integrate many types of genetic and biochemical information into the flux estimation problem.

Flux bounds constrain the values that each reaction in a metabolic network can take. A general model for these bounds is given by:

$$-\delta_{j}\left[{V_{max,j}^{\circ}}\left(\frac{e}{e^{\circ}}\right)\theta_{j}\left(\dots\right){f_{j}\left(\dots\right)}\right]\leq{v_{j}}\leq{V_{max,j}^{\circ}}\left(\frac{e}{e^{\circ}}\right)\theta_{j}\left(\dots\right){f_{j}\left(\dots\right)}$$

where $V_{max,j}^{\circ}$ denotes the maximum reaction velocity (units: flux) computed at some characteristic enzyme abundance (units: concentration), the ratio $e/e^{\circ}$ is a correction for enzyme abundance (units: dimensioness), $\theta_{j}\left(\dots\right)\in\left[0,1\right]$ is the fraction of maximial enzyme activity (a function or measurement producing units: dimensionless), and $f_{j}\left(\dots\right)$ is a function describing the substrate dependence of the reaction rate $j$ (units: dimensionless). Both $\theta_{j}\left(\dots\right)$ and $f_{j}\left(\dots\right)$ could have associated parameters, e.g., saturation or binding constants, etc.  Finally, the quanity $\delta_{j}\in\left\{0,1\right\}$ is a _binary_ variable:
* If reaction $j$ is __reversible__ $\delta_{j}=1$ or,
* If reaction $j$ is __irreversible__ $\delta_{j}=0$

Today, let's focus on approaches for computing the binary direction parameter $\delta_{j}$. However, before we consider the reversibility, let's quickly discuss the other terms.
"""

# ╔═╡ ac28ae43-3d94-4c34-91a4-f002f13044cc
md"""
##### A glimpse into the future

In addition to thermodynamics, the flux bounds integrate two levels of biological control:
* __fast__ control mechanisms (allosteric) modulate enzyme activity (the biochemical state influences the catalytic rate), and
* __slow__ control mechanisms (gene expression) modulate the abundance of system enzymes

The $\theta_{j}\left(\dots\right)$ terms describe the __fast__ control mechansisms, while the __slow__ control mechanisms are buried in the enzyme abundance $e$.

Some classics references that we'll discuss (in the future sometime):
* [MONOD J, WYMAN J, CHANGEUX JP. ON THE NATURE OF ALLOSTERIC TRANSITIONS: A PLAUSIBLE MODEL. J Mol Biol. 1965 May;12:88-118. doi: 10.1016/s0022-2836(65)80285-6. PMID: 14343300.](https://pubmed.ncbi.nlm.nih.gov/14343300/)

* [Covert MW, Palsson BO. Constraints-based models: regulation of gene expression reduces the steady-state solution space. J Theor Biol. 2003 Apr 7;221(3):309-25. doi: 10.1006/jtbi.2003.3071. PMID: 12642111.](https://pubmed.ncbi.nlm.nih.gov/12642111/)

"""

# ╔═╡ 39c87c90-348e-444b-9375-02b81dc254aa
md"""
##### Direct Gibbs energy calculation for a single reaction in a closed system

We can compute the reversibility of biochemical reactions by computing the equilibrium (or steady-state in the case of open systems) reaction extent. To do this, we minimize the Gibbs energy for the reaction mixture by searching over the reaction extent $\epsilon$ (units: mol) subject to bounds on the extent.

For a single reaction with $\mathcal{M}$ chemical components, the Gibbs energy can be written as the sum of the partial molar Gibbs energies (what we call G-bar) at constant T,P:

$$\hat{G} = \sum_{i=1}^{\mathcal{M}}\bar{G}_{i}n_{i}$$

where $\hat{G}$ denotes the total Gibbs energy for the reaction mixture (units: kJ), $\bar{G}_{i}$ denotes the partial molar Gibbs energy for chemical component $i$ (units: kJ/mol) and $n_{i}$ denotes the number of mols of chemical component $i$. From classical thermodynamics we know that the partial molar Gibbs energy for chemical species $i$ is given by:

$$\bar{G}_{i} = G_{i}^{\circ} + RT\ln\hat{a}_{i}$$

where $G_{i}^{\circ}$ denotes the Gibbs energy for pure component $i$ at a reference state, and $\hat{a}_{i}$ denotes the ratio of fugacities (mixture at reaction T,P/pure component $i$ at reference conditions). We can subsitute $\bar{G}_{i}$ into the expression for $\hat{G}$, and after some algebraic magic, we get:

$$\frac{1}{RT}\left(\hat{G}-\sum_{i=1}^{\mathcal{M}}n_{i}^{\circ}G_{i}^{\circ}\right) =
\epsilon_{1}\frac{\Delta{G}^{\circ}}{RT}+\sum_{i=1}^{\mathcal{M}}n_{i}\ln\hat{a}_{i}$$

The first term on the right-hand side is the extent of reaction times the scaled Gibbs energy of reaction; we can think of this term as how much of the Gibbs energy of reaction we recover as the reaction proceeds to the right. The second term describes how the overall Gibbs energy changes as the composition changes (at a fixed T, P). In particular, we know that:

$$n_{i} = n_{i}^{\circ}+\sigma_{i1}\epsilon_{1}\qquad{i=1,2,\dots,\mathcal{M}}$$

and (for an ideal liquid reaction mixture) we know that $\hat{a}_{i}=x_{i}$ where:

$$x_{i} = \frac{n_{i}}{\sum_{j=1}^{\mathcal{M}}n_{j}}\qquad{i=1,2,\dots,\mathcal{M}}$$

Thus, we need to search for $\epsilon_{1}$ (subject to bounds on permissible values of the extent) such that the total Gibbs energy $\hat{G}$ is at a minimum. Once we have the equilibrium extent of reaction, we can compute the equilibrium constant (for an ideal liquid phase reaction at moderate pressures):

$$K_{eq} = \prod_{i=1}^{\mathcal{M}}x_{i}^{\sigma_{i1}}$$
"""

# ╔═╡ 3dfa9f6c-224f-4a1f-8d1f-683992c1b82e
md"""
##### Example reaction: phosphoglucose isomerase (PGI)
Phosphoglucose isomerase (PGI) is the second step in [glycolysis](https://www.kegg.jp/kegg-bin/show_pathway?eco00010).
"""

# ╔═╡ c659d217-9ba9-47f4-9f6f-7f96dcdbbea3
md"""$(PlutoUI.LocalResource("./figs/Fig-G6P-F6P.png"))"""

# ╔═╡ af832bd3-316b-4c78-bd00-d626cae50dff
# ideal gas cosntant R -
R = (8.314)*(1/1000)*(1/1000) # units: kJ/mmol-K

# ╔═╡ 5be16f22-24da-41a2-8e36-4d0a464b41cd
# temperature T -
T = 25+273.15 	# units: K

# ╔═╡ e64cf4ae-0808-4b91-bf83-ed7cabb1be77
begin

	# number of species and reactions -
	ℳ = 2
	ℛ = 1

	# setup the initial number of mols -
	initial_mol_array = zeros(ℳ,1)
	initial_mol_array[1,1] = 22.0 	# units: mmol G6P = 1
	initial_mol_array[2,1] = 0.0 	# units: mmol F6P = 2

	# G of formation -
	# we get these numbers from: eQuilibrator
	G_formation_array = zeros(ℳ,1)
	G_formation_array[1,1] = -1304.7*(1/1000) 	# units: kJ/mmol G6P
	G_formation_array[2,1] = -1302.1*(1/1000) 	# units: kJ/mmol F6P

	# stoichiometric coefficients -
	stoichiometric_array = zeros(ℳ,ℛ)
	stoichiometric_array[1,1] = -1
	stoichiometric_array[2,1] = 1

	# package -
	parameters_dict = Dict{String,Any}()
	parameters_dict["initial_mol_array"] = initial_mol_array
	parameters_dict["G_formation_array"] = G_formation_array
	parameters_dict["stoichiometric_array"] = stoichiometric_array

	# show -
	nothing
end

# ╔═╡ 3db609fc-0269-4208-9307-dd75229e3063
function objective_function(epsilon,parameters)

	# get stuff from the parameters dict -
	initial_mol_array = parameters["initial_mol_array"]
	G_formation_array = parameters["G_formation_array"]
	S = parameters["stoichiometric_array"]

	# what extent are we looking at?
	ϵ = sum(initial_mol_array)*epsilon[1]
	RT = R*T

	# compute the ΔG/RT term -
	ΔG_initial_term = ((1/(RT))*sum(S.*G_formation_array))*ϵ

	# compute the current number of mols -
	n_array = initial_mol_array + S*ϵ

	# compute the mol total -
	n_total = sum(n_array)

	# compute the mol fractions for each component -
	ln_x_array = log.((1/n_total)*n_array)

	# compute the second "reaction" term -
	reaction_term = sum(n_array.*ln_x_array)

	# put all together -
	energy_total = ΔG_initial_term + reaction_term

	# return -
	return energy_total
end

# ╔═╡ 8dc66d99-7a15-4aea-9805-77706246d77b
md"""
###### Method 1: Direct search of the Gibbs energy landscape
"""

# ╔═╡ 21718432-f5b5-4886-b04b-a00abfd451f4
begin

	# initialize -
	number_of_steps = 200
	gibbs_energy_array = Array{Float64,1}()
	epsilon_range = range(0.00001,stop=0.99999,length=number_of_steps) |> collect

	# compute -
	for ϵ in epsilon_range

		gibbs_energy_value = objective_function([ϵ],parameters_dict);
		push!(gibbs_energy_array,gibbs_energy_value)
	end
end

# ╔═╡ 2220acc0-e0b5-4aff-9e7e-0a15c356898d
begin

	# what is the min value of the G energy and the extent?
	min_G_ind = argmin(gibbs_energy_array)
	min_ϵ_value = epsilon_range[min_G_ind]
	min_G_value = gibbs_energy_array[min_G_ind]

	with_terminal() do
		# show -
		println("Min extent (G,ϵ) = ($(min_G_value) AU, $(min_ϵ_value) AU)")
	end
end

# ╔═╡ a94fe5bb-7804-4621-a2f2-9207e04cfa76
begin
	plot(epsilon_range, gibbs_energy_array,lw=3,legend=:topleft, label="Scaled Gibbs energy")
	xlabel!("Scaled extent of reaction ϵ [AU]",fontsize=18)
	ylabel!("Scaled Gibbs Energy [AU]",fontsize=18)
end

# ╔═╡ b8bed863-8140-4b17-a97b-a07a45e1099a
md"""
###### Method 2: Constrained nonlinear optimization problem
Let's recast the Gibbs energy estimation as a (nonlinear) _constrained_ optimization problem and solve this problem using the [Optim.jl](https://github.com/JuliaNLSolvers/Optim.jl) package.
"""

# ╔═╡ a4a028a8-6ffb-4849-8b4a-e41abd6290f7
begin

	# Use the answer from Method 2 as a starting point
	xinitial = [0.65]

	# setup bounds -
	L = 0.00001
	U = 0.99999

	# setup the objective function -
	OF(p) = objective_function(p, parameters_dict)

    # call the optimizer -
    opt_result = optimize(OF,L, U, xinitial, Fminbox(BFGS()))
end

# ╔═╡ ce55c19c-1137-4801-81c1-bf2ff07c0480
begin
	bgfs_soln = Optim.minimizer(opt_result)[1]
	with_terminal() do
		println("Optim found ϵ (scaled) = $(bgfs_soln) AU")
	end
end

# ╔═╡ 67e69515-6d22-4693-85e0-c3767e5b9a06
begin

	# what is the equilibrium extent?
	ϵ_scaled = bgfs_soln;
	ϵ = sum(initial_mol_array)*ϵ_scaled

	# compute the equlibrium constant -
	n_final = initial_mol_array + stoichiometric_array*ϵ

	# compute the final mol fraction -
	ln_x_final = log.((1/sum(n_final)).*n_final)

	# compute the Keq -
	tmp = dot(stoichiometric_array,ln_x_final)
	K_eq = exp(tmp)

	with_terminal() do
		println("Estimated Keq = $(K_eq)")
	end
end

# ╔═╡ a5d45e1a-a284-4aec-8025-791e89e2d9d1
n_final

# ╔═╡ 40eff115-6527-4fb9-8640-216ba104fd37
md"""
##### Rule of thumb for reversibility
The reversibility parameter can be computed in one of several possible ways. For example, one method in the literature is to use the sign of Gibbs reaction energy:

* if $sgn\left(\Delta{G}^{\circ}\right)<0$ then $\delta = 0$ (irreversible)
* if $sgn\left(\Delta{G}^{\circ}\right)>0$ then $\delta = 1$ (reversible)

Alternatively, the value of $\delta$ can be assigned based upon a cutoff on the equilibrium constant:

* if $K_{eq}>\star$ then $\delta = 0$ (irreversible)
* if $K_{eq}\leq\star$ then $\delta = 1$ (reversible)

where the metabolic engineer specifies the value $\star$.
"""

# ╔═╡ be13e99b-fc7c-4d80-9a19-5a0536eae108
md"""
### The eQuilibrator application programming interface (API)

The [eQuilibrator application programming interface](https://equilibrator.weizmann.ac.il) is a tool for thermodynamic calculations in biological reaction networks. It was developed by the [Milo lab](https://www.weizmann.ac.il/plants/Milo/) at the Weizmann Institute in Rehovot, Israel.

* [Beber ME, Gollub MG, Mozaffari D, Shebek KM, Flamholz AI, Milo R, Noor E. eQuilibrator 3.0: a database solution for thermodynamic constant estimation. Nucleic Acids Res. 2022 Jan 7;50(D1): D603-D609. doi: 10.1093/nar/gkab1106. PMID: 34850162; PMCID: PMC8728285.](https://pubmed.ncbi.nlm.nih.gov/34850162/)

The [eQuilibrator.jl](https://stelmo.github.io/eQuilibrator.jl/dev/) package is a [Julia](https://julialang.org) wrapper around eQuilibrator (which is written in Python).
"""

# ╔═╡ 66eb0580-706c-4321-a02c-c4f3733af494
md"""
### Summary and conclusions

In this lecture we:

1. Introduced a general model for the flux bounds constraints in a constraint-based calculation
1. Introduced direct Gibbs energy minimization using the partial molar Gibbs energy
1. Computed the reversibility of a single enzyme-catalyzed reaction
"""

# ╔═╡ 71ccee21-d68a-40c3-bac2-b5b9e102acde
md"""
### Next time
Could we use Direct Gibbs energy calculations to compute the reversibility of many coupled reactions (or perhaps the flux itself)?
"""

# ╔═╡ d29d1328-0993-4118-95da-ac0525dd2610
TableOfContents(title="📚 Table of Contents", indent=true, depth=5, aside=true)

# ╔═╡ 97eff132-84de-11ec-2343-513ada272849
html"""
<style>
main {
    max-width: 760px;
    width: 75%;
    margin: auto;
    font-family: "Roboto, monospace";
}

a {
    color: blue;
    text-decoration: none;
}
</style>"""

# ╔═╡ 0bfd4739-2c80-496e-a627-be06f68d950b
html"""
<script>
	// initialize -
	var section = 0;
	var subsection = 0;
	var subsubsection = 0;
	var headers = document.querySelectorAll('h3, h5, h6');

	// main loop -
	for (var i=0; i < headers.length; i++) {

		var header = headers[i];
	    var text = header.innerText;
	    var original = header.getAttribute("text-original");
	    if (original === null) {

			// Save original header text
	        header.setAttribute("text-original", text);
	    } else {

			// Replace with original text before adding section number
	        text = header.getAttribute("text-original");
	    }

	    var numbering = "";
	    switch (header.tagName) {
	        case 'H3':
	            section += 1;
	            numbering = section + ".";
	            subsection = 0;
	            break;
	        case 'H5':
	            subsection += 1;
	            numbering = section + "." + subsection;
	            break;
			case 'H6':
	            subsubsection += 1;
	            numbering = section + "." + subsection + "." + subsubsection;
	            break;
	    }
		// update the header text
		header.innerText = numbering + " " + text;
	};
</script>"""

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Optim = "429524aa-4258-5aef-a3af-852621145aeb"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"

[compat]
Optim = "~1.6.0"
Plots = "~1.25.7"
PlutoUI = "~0.7.33"
PrettyTables = "~1.3.1"
"""

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

julia_version = "1.7.1"
manifest_format = "2.0"

[[deps.AbstractPlutoDingetjes]]
deps = ["Pkg"]
git-tree-sha1 = "8eaf9f1b4921132a4cff3f36a1d9ba923b14a481"
uuid = "6e696c72-6542-2067-7265-42206c756150"
version = "1.1.4"

[[deps.Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "af92965fb30777147966f58acb05da51c5616b5f"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.3"

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

[[deps.ArrayInterface]]
deps = ["Compat", "IfElse", "LinearAlgebra", "Requires", "SparseArrays", "Static"]
git-tree-sha1 = "1bdcc02836402d104a46f7843b6e6730b1948264"
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
version = "4.0.2"

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

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

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

[[deps.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 = "4b859a208b2397a7a623a03449e4636bdb17bcf2"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.1+1"

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

[[deps.ChangesOfVariables]]
deps = ["ChainRulesCore", "LinearAlgebra", "Test"]
git-tree-sha1 = "bf98fa45a0a4cee295de98d4c1462be26345b9a1"
uuid = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0"
version = "0.1.2"

[[deps.ColorSchemes]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random"]
git-tree-sha1 = "6b6f04f93710c71550ec7e16b650c1b9a612d0b6"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.16.0"

[[deps.ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "024fe24d83e4a5bf5fc80501a314ce0d1aa35597"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.11.0"

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

[[deps.CommonSubexpressions]]
deps = ["MacroTools", "Test"]
git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7"
uuid = "bbf7d656-a473-5ed7-a52c-81e309532950"
version = "0.3.0"

[[deps.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 = "44c37b4636bc54afac5c574d2d02b625349d6582"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.41.0"

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

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

[[deps.Crayons]]
git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15"
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
version = "4.1.1"

[[deps.DataAPI]]
git-tree-sha1 = "cc70b17275652eb47bc9e5f81635981f13cea5c8"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.9.0"

[[deps.DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "3daef5523dd2e769dad2365274f760ff5f282c7d"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.11"

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

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

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

[[deps.DiffResults]]
deps = ["StaticArrays"]
git-tree-sha1 = "c18e98cba888c6c25d1c3b048e4b3380ca956805"
uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5"
version = "1.0.3"

[[deps.DiffRules]]
deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"]
git-tree-sha1 = "84083a5136b6abf426174a58325ffd159dd6d94f"
uuid = "b552c78f-8df3-52c6-915a-8e097449b14b"
version = "1.9.1"

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

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

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

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

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

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

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

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

[[deps.FiniteDiff]]
deps = ["ArrayInterface", "LinearAlgebra", "Requires", "SparseArrays", "StaticArrays"]
git-tree-sha1 = "6eae72e9943d8992d14359c32aed5f892bda1569"
uuid = "6a86dc24-6348-571c-b903-95158fe2bd41"
version = "2.10.0"

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

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

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

[[deps.ForwardDiff]]
deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions", "StaticArrays"]
git-tree-sha1 = "1bd6fc0c344fc0cbee1f42f8d2e7ec8253dda2d2"
uuid = "f6369f11-7733-5829-9624-2563aa707210"
version = "0.10.25"

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

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

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

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

[[deps.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 = "aa22e1ee9e722f1da183eb33370df4c1aeb6c2cd"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.63.1+0"

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

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

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

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

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

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

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

[[deps.Hyperscript]]
deps = ["Test"]
git-tree-sha1 = "8d511d5b81240fc8e6802386302675bdf47737b9"
uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91"
version = "0.0.4"

[[deps.HypertextLiteral]]
git-tree-sha1 = "2b078b5a615c6c0396c77810d92ee8c6f470d238"
uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
version = "0.9.3"

[[deps.IOCapture]]
deps = ["Logging", "Random"]
git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a"
uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
version = "0.2.2"

[[deps.IfElse]]
git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1"
uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
version = "0.1.1"

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

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

[[deps.InverseFunctions]]
deps = ["Test"]
git-tree-sha1 = "a7254c0acd8e62f1ac75ad24d5db43f5f19f3c65"
uuid = "3587e190-3f89-42d0-90ee-14403ec27112"
version = "0.1.2"

[[deps.IrrationalConstants]]
git-tree-sha1 = "7fd44fd4ff43fc60815f8e764c0f352b83c49151"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.1.1"

[[deps.IterTools]]
git-tree-sha1 = "fa6287a4469f5e048d763df38279ee729fbd44e5"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.4.0"

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

[[deps.JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.4.1"

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

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

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

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

[[deps.LaTeXStrings]]
git-tree-sha1 = "f2355693d6778a178ade15952b7ac47a4ff97996"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.3.0"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[deps.LineSearches]]
deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"]
git-tree-sha1 = "f27132e551e959b3667d8c93eae90973225032dd"
uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255"
version = "7.1.1"

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

[[deps.LogExpFunctions]]
deps = ["ChainRulesCore", "ChangesOfVariables", "DocStringExtensions", "InverseFunctions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "e5718a00af0ab9756305a0392832c8952c7426c1"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.6"

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

[[deps.MacroTools]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "3d3e902b31198a27340d0bf00d6ac452866021cf"
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
version = "0.5.9"

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

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

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

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

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

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

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

[[deps.NLSolversBase]]
deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"]
git-tree-sha1 = "50310f934e55e5ca3912fb941dec199b49ca9b68"
uuid = "d41bc354-129a-5804-8e4c-c37616107c6c"
version = "7.8.2"

[[deps.NaNMath]]
git-tree-sha1 = "b086b7ea07f8e38cf122f5016af580881ac914fe"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "0.3.7"

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

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

[[deps.OpenBLAS_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"

[[deps.OpenLibm_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"

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

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

[[deps.Optim]]
deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"]
git-tree-sha1 = "916077e0f0f8966eb0dc98a5c39921fdb8f49eb4"
uuid = "429524aa-4258-5aef-a3af-852621145aeb"
version = "1.6.0"

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

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

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

[[deps.Parameters]]
deps = ["OrderedCollections", "UnPack"]
git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe"
uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a"
version = "0.12.3"

[[deps.Parsers]]
deps = ["Dates"]
git-tree-sha1 = "0b5cfbb704034b5b4c1869e36634438a047df065"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.2.1"

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

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

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

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

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

[[deps.PlutoUI]]
deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "Random", "Reexport", "UUIDs"]
git-tree-sha1 = "da2314d0b0cb518906ea32a497bb4605451811a4"
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
version = "0.7.33"

[[deps.PositiveFactorizations]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20"
uuid = "85a6dd25-e78a-55b7-8502-1745935b8125"
version = "0.2.4"

[[deps.Preferences]]
deps = ["TOML"]
git-tree-sha1 = "2cf929d64681236a2e074ffafb8d568733d2e6af"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.3"

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

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

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

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

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

[[deps.RecipesBase]]
git-tree-sha1 = "6bf3f380ff52ce0832ddd3a2a7b9538ed1bcca7d"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.2.1"

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

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

[[deps.RelocatableFolders]]
deps = ["SHA", "Scratch"]
git-tree-sha1 = "cdbd3b1338c72ce29d9584fdbe9e9b70eeb5adca"
uuid = "05181044-ff0b-4ac5-8273-598c1e38db00"
version = "0.1.3"

[[deps.Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.3.0"

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

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

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

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

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

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

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

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

[[deps.SpecialFunctions]]
deps = ["ChainRulesCore", "IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
git-tree-sha1 = "e6bf188613555c78062842777b116905a9f9dd49"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "2.1.0"

[[deps.Static]]
deps = ["IfElse"]
git-tree-sha1 = "b4912cd034cdf968e06ca5f943bb54b17b97793a"
uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
version = "0.5.1"

[[deps.StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "a635a9333989a094bddc9f940c04c549cd66afcf"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.3.4"

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

[[deps.StatsAPI]]
git-tree-sha1 = "d88665adc9bcf45903013af0982e2fd05ae3d0a6"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.2.0"

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

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

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

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

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

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

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

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

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

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

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

[[deps.UnicodeFun]]
deps = ["REPL"]
git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf"
uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1"
version = "0.4.1"

[[deps.Unzip]]
git-tree-sha1 = "34db80951901073501137bdbc3d5a8e7bbd06670"
uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d"
version = "0.1.2"

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

[[deps.Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "66d72dc6fcc86352f01676e8f0f698562e60510f"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.23.0+0"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[deps.libblastrampoline_jll]]
deps = ["Artifacts", "Libdl", "OpenBLAS_jll"]
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"

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

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

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

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

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

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

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

[[deps.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:
# ╠═84cd8fcb-f0f7-480b-abe6-58686d6bd7e2
# ╟─db68d9a1-7b50-466d-985a-13bc8a2c3a03
# ╟─ac28ae43-3d94-4c34-91a4-f002f13044cc
# ╟─39c87c90-348e-444b-9375-02b81dc254aa
# ╟─3dfa9f6c-224f-4a1f-8d1f-683992c1b82e
# ╟─c659d217-9ba9-47f4-9f6f-7f96dcdbbea3
# ╠═af832bd3-316b-4c78-bd00-d626cae50dff
# ╠═5be16f22-24da-41a2-8e36-4d0a464b41cd
# ╠═e64cf4ae-0808-4b91-bf83-ed7cabb1be77
# ╠═3db609fc-0269-4208-9307-dd75229e3063
# ╟─8dc66d99-7a15-4aea-9805-77706246d77b
# ╠═21718432-f5b5-4886-b04b-a00abfd451f4
# ╠═2220acc0-e0b5-4aff-9e7e-0a15c356898d
# ╠═a94fe5bb-7804-4621-a2f2-9207e04cfa76
# ╟─b8bed863-8140-4b17-a97b-a07a45e1099a
# ╠═a4a028a8-6ffb-4849-8b4a-e41abd6290f7
# ╠═ce55c19c-1137-4801-81c1-bf2ff07c0480
# ╠═67e69515-6d22-4693-85e0-c3767e5b9a06
# ╠═a5d45e1a-a284-4aec-8025-791e89e2d9d1
# ╟─40eff115-6527-4fb9-8640-216ba104fd37
# ╟─be13e99b-fc7c-4d80-9a19-5a0536eae108
# ╟─66eb0580-706c-4321-a02c-c4f3733af494
# ╟─71ccee21-d68a-40c3-bac2-b5b9e102acde
# ╠═d29d1328-0993-4118-95da-ac0525dd2610
# ╠═5e179f89-2302-4342-987f-ff341fa824b1
# ╠═97eff132-84de-11ec-2343-513ada272849
# ╠═0bfd4739-2c80-496e-a627-be06f68d950b
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002


text:
import UUIDs

struct PartialUnversionedPackage
    name::String
    uuid::Union{UUIDs.UUID, Nothing}
end

@inline function PartialUnversionedPackage(name::AbstractString)
    return PartialUnversionedPackage(name, nothing)
end

struct FullUnversionedPackage
    name::String
    uuid::UUIDs.UUID
end

"""
A specific version of a package.

Fields:
- `name::String`
- `uuid::UUID`
- `version::String`
- `tree::String`
"""
struct VersionedPackage
    name::String
    uuid::UUIDs.UUID
    version::String
    tree::String
end

struct VersionAndTree
    version::String
    tree::String
end

"""
Supertype for all registry types.
"""
abstract type AbstractRegistry end

"""
A registry that is cloned using Git.

## Examples

```julia
julia> registries = [GitRegistry("https://github.com/JuliaRegistries/General.git")]

julia> Pkg.add(latest("Example"; registries = registries))
```
"""
struct GitRegistry <: AbstractRegistry
    url::String
end

"""
A registry that already exists in a folder on the filesystem.

## Examples

```julia
julia> registries = [LocalFolderRegistry("/path/to/my/registry/")]

julia> Pkg.add(latest("Example"; registries = registries))
```
"""
struct LocalFolderRegistry <: AbstractRegistry
    path::String
end

struct ParsedRegistry
    dict::Dict{FullUnversionedPackage, VersionAndTree}
end

@inline function ParsedRegistry()
    dict = Dict{FullUnversionedPackage, VersionAndTree}()
    return ParsedRegistry(dict)
end

@inline function Base.keys(parseresult::ParsedRegistry)
    return Base.keys(parseresult.dict)
end

@inline function Base.haskey(parseresult::ParsedRegistry, key)
    return Base.haskey(parseresult.dict, key)
end

@inline function Base.getindex(parseresult::ParsedRegistry, key)
    return Base.getindex(parseresult.dict, key)
end

@inline function Base.setindex!(parseresult::ParsedRegistry, key, value)
    return Base.setindex!(parseresult.dict, key, value)
end

"""
A cache for holding the results of parsed registries.

## Examples

```julia
julia> cache = RegistryParsingCache()

julia> Pkg.add(latest("PkgA", cache))

julia> Pkg.add(latest("PkgB", cache))

julia> Pkg.add(latest("PkgC", cache))
```
"""
struct RegistryParsingCache
    cachedict::Dict{AbstractRegistry, ParsedRegistry}
end

@inline function RegistryParsingCache()
    cachedict = Dict{AbstractRegistry, ParsedRegistry}()
    return RegistryParsingCache(cachedict)
end

@inline function Base.keys(cache::RegistryParsingCache)
    return Base.keys(cache.cachedict)
end

@inline function Base.haskey(cache::RegistryParsingCache, key)
    return Base.haskey(cache.cachedict, key)
end

@inline function Base.getindex(cache::RegistryParsingCache, key)
    return Base.getindex(cache.cachedict, key)
end

@inline function Base.setindex!(cache::RegistryParsingCache, key, value)
    return Base.setindex!(cache.cachedict, key, value)
end

@inline function Base.empty!(cache::RegistryParsingCache)
    return Base.empty!(cache.cachedict)
end

struct PackageAmbiguousException <: Exception
    msg::String
end

struct PackageNotFoundException <: Exception
    msg::String
end

struct RegistriesDisagreeException <: Exception
    msg::String
end

ext: jl


text:
# Tests for Multinomial

using Distributions
using Base.Test

p = [0.2, 0.5, 0.3]
nt = 10
d = Multinomial(nt, p)

# Basics

@test dim(d) == 3
@test d.n == nt
@test_approx_eq mean(d) [2., 5., 3.]
@test_approx_eq var(d) [1.6, 2.5, 2.1]
@test_approx_eq cov(d) [1.6 -1.0 -0.6; -1.0 2.5 -1.5; -0.6 -1.5 2.1]

@test insupport(d, [1, 6, 3])
@test !insupport(d, [2, 6, 3])

# random sampling

x = rand(d)
@test isa(x, Vector{Int})
@test sum(x) == nt
@test insupport(d, x)

x = rand(d, 100)
@test isa(x, Matrix{Int})
@test all(sum(x, 1) .== nt)
@test insupport(d, x)

# logpdf

x1 = [1, 6, 3]

@test_approx_eq_eps pdf(d, x1) 0.070875 1.0e-8
@test_approx_eq logpdf(d, x1) log(pdf(d, x1))

x = rand(d, 100)
pv = pdf(d, x)
lp = logpdf(d, x)
for i in 1 : size(x, 2)
	@test_approx_eq pv[i] pdf(d, x[:,i])
	@test_approx_eq lp[i] logpdf(d, x[:,i])
end

# fit

x = rand(d, 10^5)
@test size(x) == (dim(d), 10^5)
@test all(sum(x, 1) .== nt)

r = fit(Multinomial, x)
@test r.n == nt
@test dim(r) == length(p)
@test_approx_eq_eps r.prob p 0.02

r = fit_mle(Multinomial, x, fill(2.0, size(x,2)))
@test r.n == nt
@test dim(r) == length(p)
@test_approx_eq_eps r.prob p 0.02


text:
using StaticArrays

export delta_parallelepiped_sampling!

"""
Calcultate val = int_{parallelepiped} d^3k delta(`etarget` - e(k)) / volume
where `e(k) = e0 + k ⋅ v0`. The parallelepiped region is [-L/2, L/2]^3.
Divide the parallelepiped into six tetrahedra and use tetrahedron integration.
# Sampling
Sample points on the `e(k) = etarget` plane, where the spacing is relative to the edge
lengths. Sample around `nsample_1d` points along each dimension, and at most
`(nsample_1d+1)^2` points are sampled. Sampled points are stored in the array `ksamples`.
"""
@inline function delta_parallelepiped_sampling!(etarget::T, e0, v0, L, nsample_1d, ksamples) where {T}
    if norm(v0) < 1E-10
        # Velocity is too small. Tetrahedron method does not work.
        return zero(T), 0
    end

    L_div_2 = L ./ 2
    e1 = e0 + (-v0[1] * L_div_2[1] - v0[2] * L_div_2[2] - v0[3] * L_div_2[3])
    e2 = e0 + (+v0[1] * L_div_2[1] - v0[2] * L_div_2[2] - v0[3] * L_div_2[3])
    e3 = e0 + (-v0[1] * L_div_2[1] + v0[2] * L_div_2[2] - v0[3] * L_div_2[3])
    e4 = e0 + (+v0[1] * L_div_2[1] + v0[2] * L_div_2[2] - v0[3] * L_div_2[3])
    e5 = e0 + (-v0[1] * L_div_2[1] - v0[2] * L_div_2[2] + v0[3] * L_div_2[3])
    e6 = e0 + (+v0[1] * L_div_2[1] - v0[2] * L_div_2[2] + v0[3] * L_div_2[3])
    e7 = e0 + (-v0[1] * L_div_2[1] + v0[2] * L_div_2[2] + v0[3] * L_div_2[3])
    e8 = e0 + (+v0[1] * L_div_2[1] + v0[2] * L_div_2[2] + v0[3] * L_div_2[3])
    val = zero(T)
    val += delta_tetrahedron(etarget, SVector{4,T}(e1, e2, e4, e5))
    val += delta_tetrahedron(etarget, SVector{4,T}(e1, e3, e4, e5))
    val += delta_tetrahedron(etarget, SVector{4,T}(e2, e4, e6, e5))
    val += delta_tetrahedron(etarget, SVector{4,T}(e3, e4, e7, e5))
    val += delta_tetrahedron(etarget, SVector{4,T}(e4, e7, e8, e5))
    val += delta_tetrahedron(etarget, SVector{4,T}(e4, e6, e8, e5))

    # TODO: If |v0| = 0, skip sampling

    # Find one point on the e(k0) = etarget plane
    e = (e1, e2, e3, e4, e5, e6, e7, e8)
    imin = argmin(e)
    imax = argmax(e)
    emin = e[imin]
    emax = e[imax]
    # Trivial case: etarget outside the energy range
    if etarget < emin || emax < etarget
        return zero(T), 0
    end

    kmin, kmax = KLIST[imin], KLIST[imax]
    ratio = (etarget - emin) / (emax - emin)
    k0 = (kmin + (kmax - kmin) * ratio) .* L_div_2

    # Find two orthogonal unit vectors on the plane
    i = argmin(abs.(v0))
    if i == 1
        u0 = Vec3{T}(1, 0, 0)
    elseif i == 2
        u0 = Vec3{T}(0, 1, 0)
    else
        u0 = Vec3{T}(0, 0, 1)
    end
    u1 = cross(v0, u0)
    u2 = cross(v0, u1)

    # Normalize unit vectors according to the step size
    u1 = u1 / norm(u1 ./ L) / nsample_1d
    u2 = u2 / norm(u2 ./ L) / nsample_1d

    # k vectors on the e(k) = etarget plane is k0 + n1 * u1 + n2 * u2.
    # Sample k vectors on the plane and inside the cube.

    nmax = floor(Int, sqrt(3) * nsample_1d)
    nsamples = 0
    for n1 in -nmax:nmax
        was_inside = false
        k = k0 + n1 * u1 - nmax * u2
        for n2 in -nmax:nmax
            k += u2
            if all(abs.(k) .<= L_div_2)
                was_inside = true
                nsamples += 1
                ksamples[:, nsamples] .= k
            elseif was_inside
                # Was inside the cube, but moved out. The remaining points are all outside.
                break
            end
        end
    end

    return val / 6, nsamples
end

max_stars_repo_name: jaemolihm/TetrahedronIntegration

max_issues_repo_name: jaemolihm/TetrahedronIntegration

max_forks_repo_name: jaemolihm/TetrahedronIntegration


text:
using LinearAlgebra
using Distributions
using Random

struct SimWorld{A2<:Array{Float64,2}, F<:Float64, I<:Int64, A1<:Array{Float64,1}, AA<:Array{Array{Float64,2},1}}
    A::A2
    C::A2
    muInit::A1
    emitVar::A1
    endT::F
    dt::F
    endI::I
    allT::A1
    allAs::AA
end

function getStates(SW::SimWorld)
    Z = (SW.muInit .+ sqrt.(SW.emitVar).*randn(size(SW.muInit)))
    Zs = [A*Z for A in SW.allAs]
    Ys = [SW.C*z .+ rand!(MvNormal(zeros(size(SW.C*SW.C',1)), SW.C*diagm(SW.emitVar)*SW.C'), similar(SW.C*SW.muInit)) for z in Zs];
    return Zs::Array{Array{Float64,1},1}, Ys::Array{Array{Float64,1},1}
end

SimWorld(A::Array{Float64,2}, C::Array{Float64,2}, muPrior::Array{Float64,1}, emitVar::Array{Float64,1}, endT::Float64=1000., dt::Float64=.1) =
    SimWorld(A, C, muPrior, emitVar, endT, dt, Integer(ceil(endT/dt)))
SimWorld(A::Array{Float64,2}, C::Array{Float64,2}, muPrior::Array{Float64,1}, emitVar::Array{Float64,1}, endT::Float64, dt::Float64, endI::Int) =
    SimWorld(A, C, muPrior, emitVar, endT, dt, endI,
                Array{Float64,1}(0:dt:endI*dt),
                [A^t for t in 0:endI])

max_stars_repo_name: rhoadesScholar/Drugowitsch-Rotation

max_issues_repo_name: rhoadesScholar/Drugowitsch-Rotation

max_forks_repo_name: rhoadesScholar/Drugowitsch-Rotation


text:
"""
Graphics context attached to a window. Used to register drawing commands on the window surface.
"""
mutable struct GraphicsContext
    conn
    id
    function GraphicsContext(conn::Connection, win::XCBWindow; attributes=[], values=[])
        id = XCB.xcb_generate_id(conn)
        gc = new(conn, id)
        @check :error xcb_create_gc(gc.conn, gc.id, win.id, 0, C_NULL)
        set_attributes(gc, attributes, values)
        Base.finalizer(x -> @check(:error, xcb_free_gc(gc.conn, gc.id)), gc)
    end
end

function set_attributes(gc::GraphicsContext, attributes, values)
    values = values[sortperm(collect(attributes))]
    list = zeros(UInt32, 32)
    setindex!.(Ref(list), values, 1:length(values))
    @flush @check xcb_change_gc(gc.conn, gc.id, reduce(|, attributes), list)
end

attach_graphics_context!(win::XCBWindow, gc::GraphicsContext) = setproperty!(win, :gc, gc)


text:
"""
	ErdosRenyiNetwork <: AbstractNetwork

A random network contructed via the Erdos-Renyi method.

# Fields
- N              :: Integer -> Number of nodes
- p              :: Real -> Connection probability
- seed           :: Integer -> Seed for the random creation
"""
mutable struct ErdosRenyiNetwork <: AbstractNetwork
	N :: Integer
	p :: Union{Real, Nothing}
	seed :: Integer

	_adjMat :: AbstractMatrix
	_props :: NetworkProperties
end

"""
	ErdosRenyiNetwork(N, p; directed=false, seed=-1)

Create an Erdos-Renyi random network with `N` nodes and connection probability `p`.
"""
function ErdosRenyiNetwork(
	N::Integer,
	p::Real;
	directed::Bool=false,
	seed::Integer=-1
)
	(N <= 0) && throw(ArgumentError("Number of nodes must be a positive integer!"))
	(p > 1) && (p = 1.0)
	(p < 0) && (p = 0.0)

	_seed = seed < 0 ? rand(1:999999999) : seed
	mat = generateERAdjMat(N, p; directed=directed, seed=_seed)

	ErdosRenyiNetwork(N, p, _seed, mat, NetworkProperties(N, directed))
end

"""
	ErdosRenyiNetwork(N, numConnections; directed=false, seed=-1)

Create an Erdos-Renyi random network with `N` nodes and `numConnections` connections.
"""
function ErdosRenyiNetwork(
	N::Integer,
	numConnections::Integer;
	directed::Bool=false,
	seed::Integer=-1
)
	(N <= 0) && throw(ArgumentError("Number of nodes must be a positive integer!"))

	maxConnections = Int(N * (N - 1) / (directed ? 1 : 2))
	(numConnections > maxConnections) && (numConnections = maxConnections)
	(numConnections < 0) && (numConnections = 0)

	_seed = seed < 0 ? rand(1:999999999) : seed
	mat = generateERAdjMat(N, numConnections; directed=directed, seed=_seed)

	ErdosRenyiNetwork(N, nothing, _seed, mat, NetworkProperties(N, directed, numConnections))
end

function show(network::ErdosRenyiNetwork)
	print(isdirected(network) ? "Directed " : "Undirected ")
	println("Erdos-Renyi Random Network")
	println("- N = $(network.N)")
	println("- p = $(network.p)")
	println("- seed = $(network.seed)")
end


text:
using EHANK, JLD, BenchmarkTools

# Solve model
m = KrusellSmith()
T, R, C, inverse_basis, basis = solve(m)

# Get quarterly data using the truth to change from reduced to full basis
states = load("fine_data_red_basis.jld", "states")
data = zeros(1, (length(states) - 1) / 90)

# created daily data -> transform into quarterly data for discrete observations
for i = 1:length(data)
    full_state = inverse_basis * states[1+ (i-1)*90]
    data[i] = full_state[m.endogenous_states[:output][1]]
end

# Compute logliks
sim_freqs = [2; 3; 12]
for j = 1:length(sim_freqs)
    println("Sim_freq: ", sim_freqs[j], " states per quarter")
    update!(m.settings[:state_simulation_freq], Setting(:state_simulation_freq, sim_freqs[j]))

    # Run once to compile
    if j == 1
        TT = eye(T) + T * 1/get_setting(m, :state_simulation_freq) # adjust transition equation to account for discretization
        TT, RR, CC = transform_transition_matrices(m, TT, R, C; track_lag = false) # get expanded filter

        # Define measurement equation
        measure = measurement(m, TT, RR, CC, inverse_basis)
        ZZ = measure.ZZ
        DD = measure.DD
        QQ = measure.QQ
        EE = measure.EE

        out = HANK.kalman_filter(data, TT, RR, CC, QQ, ZZ, DD, EE)
    end

    # Define measurement equation
    TT = eye(T) + T * 1/get_setting(m, :state_simulation_freq) # adjust transition equation to account for discretization
    TT, RR, CC = transform_transition_matrices(m, TT, R, C; track_lag = false) # get expanded matrices

    measure = measurement(m, TT, RR, CC, inverse_basis)
    ZZ = measure.ZZ
    DD = measure.DD
    QQ = measure.QQ
    EE = measure.EE

    @btime begin
        ~ = HANK.kalman_filter($data, $TT, $RR, $CC, $QQ, $ZZ, $DD, $EE);
        print()
    end
end


text:
module TileCoding

mutable struct IHT
    size::Integer
    overfullCount::Int64
    dictionary::Dict{Array{Int64, 1}, Int64}
    IHT(sizeval) = new(sizeval, 0, Dict{Array{Int64, 1}, Int64}())
end

capacity(iht::IHT) = iht.size
count(iht::IHT) = length(iht.dictionary)
fullp(iht::IHT) = length(iht.dictionary) >= count(iht)

function getindex!(iht::IHT, obj::Array{Int64, 1}, readonly=false)
    d = iht.dictionary
    if obj in keys(d)
        return d[obj]::Int64
    elseif readonly
        return -1
    end
    iht_size = capacity(iht)
    iht_count = count(iht)
    if count(iht) >= capacity(iht)
        if iht.overfullCount==0
            println("IHT full, starting to allow collisions")
        end
        iht.overfullCount += 1
        # return (hash(obj) % capacity(iht))::Int64
        return convert(Int64,(hash(obj) % capacity(iht)))::Int64

    end
    d[obj] = iht_count
    return iht_count
end

hashcoords!(coordinates, m, readonly=false) = nothing
hashcoords!(coordinates, m::IHT, readonly=false) = getindex!(m, coordinates, readonly)
hashcoords!(coordinates, m::Integer, readonly=false) = hash(tuple(coordinates)) % m

function tiles!(ihtORsize, numtilings, floats, ints=[], readonly=false)
    qfloats = [floor(f*numtilings) for f in floats]
    tiles = zeros(Int64, numtilings)
    for tiling = 1:numtilings
        tilingX2 = tiling*2
        coords = [tiling]::Array{Int64, 1}
        b = tiling
        for (q_idx, q) in enumerate(qfloats)
            append!(coords, floor((q + b) / numtilings))
            b += tilingX2
        end
        append!(coords, ints)
        tiles[tiling] = hashcoords!(coords, ihtORsize, readonly)
    end
    return tiles
end

function tileswrap!(ihtORsize, numtilings, floats, wrapwidths, ints=[], readonly=false)
    qfloats = [floor(f*numtilings) for f in floats]
    tiles = zeros(Int64, numtilings)
    for tiling = 1:numtilings
        tilingX2 = tiling*2
        coords = [tiling]::Array{Int64, 1}
        b = tiling
        for (q_idx, q) in enumerate(qfloats)
            width = nothing
            if length(wrapwidths) >= q_idx
                width = wrapwidths[q_idx]
            end
            c = floor((q + b%numtilings) / numtilings)
            append!(coords, width==nothing ? c : c%width)
            b += tilingX2
        end
        append!(coords, ints)
        tiles[tiling] = hashcoords!(coords, ihtORsize, readonly)
    end
    return tiles
end

end # End TileCoding

# using MimimalRLCore
"""
    TileCoder(num_tilings, num_tiles, num_features, num_ints; wrap=false, wrapwidths=0.0)
Tile coder for coding all features together.
"""
mutable struct TileCoder{F}
    # Main Arguments
    tilings::Int
    tiles::Int
    dims::Int
    ints::Int

    # Optional Arguments
    wrap::Bool
    wrapwidths::Float64

    iht::TileCoding.IHT
    TileCoder{F}(num_tilings, num_tiles, num_features, num_ints=1; wrap=false, wrapwidths=0.0) where {F} =
        new{F}(num_tilings,
               num_tiles,
               num_features,
               num_ints,
               wrap,
               0.0,
               TileCoding.IHT(num_tilings*(num_tiles+1)^num_features * num_ints))
end

TileCoder(args...;kwargs...) = TileCoder{Vector{Int}}(args...; kwargs...)
SparseTileCoder(args...;kwargs...) = TileCoder{SparseVector{Int}}(args...; kwargs...)

function get_tc_indicies(fc::TileCoder, s; ints=[], readonly=false)
    if fc.wrap
        return 1 .+ TileCoding.tileswrap!(fc.iht, fc.tilings, s.*fc.tiles, fc.wrapwidths, ints, readonly)
    else
        return 1 .+ TileCoding.tiles!(fc.iht, fc.tilings, s.*fc.tiles, ints, readonly)
    end
end

create_features(fc::TileCoder{Vector{Int}}, s; ints=[], readonly=false) =
    get_tc_indicies(fc, s; ints=[], readonly=false)

function create_features(fc::TileCoder{SparseVector{N}}, s; ints=[], readonly=false) where {N}
    idx = get_tc_indicies(fc, s; ints=[], readonly=false)
    s = spzeros(N, size(fc))
    s[idx] .= N(1)
    return s
end

# feature_size(fc::TileCoder) = fc.tilings*(fc.tiles+1)^fc.dims * fc.ints
Base.size(fc::TileCoder) = fc.tilings*(fc.tiles+1)^fc.dims * fc.ints

(fc::TileCoder)(s; ints=[], readonly=false) =
    create_features(fc, s; ints=ints, readonly=readonly)

max_stars_repo_name: MatthewMcLeod/curiosity

max_issues_repo_name: MatthewMcLeod/curiosity

max_forks_repo_name: MatthewMcLeod/curiosity


text:
function beep(sound_type::String="alert")
    basename = joinpath(@__DIR__, "..", "sounds")

    path = joinpath(basename, string(sound_type, ".wav"))
    return(wavplay(path))
end


text:
#== # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Description
#
#   Functions to verify if the satellite is above some countries.
#
#   Initial version based on the code sent by Renato Branco.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ==#

export satellite_check_Brazil

"""
    function satellite_check_Brazil(lat::Number, lon::Number)

Verify if a point described by latitude `lat` [rad] and longitude `lon` [rad] is
inside Brazil. Returns `true` if the point is inside Brazil, of `false`
otherwise.

# Remarks

This function was based on the algorithm sent by Renato Branco to Ronan Arraes
by e-mail at 2016-02-16.

"""
function satellite_check_Brazil(lat::Number, lon::Number)
    # Notes
    # ====
    #
    # SB: Superior bound.
    # IB: Inferior bound.

    # Convert latitude and longitude to degrees.
    lat *= 180.0/pi
    lon *= 180.0/pi

    # Rough verification
    # ==================
    if ( (lon <= -32.5) && (lon >= -75.0) && (lat <= 5.0) && (lat >= -35.0) )
        # Accurate verification
        # =====================

        # Zone 01.
        if (lon > -40.0)
            SB = -0.4*lon - 18.0
            IB =  2.0*lon + 60.0
        # Zone 02.
        elseif (lon > -45.0)
            SB = -0.4*lon   - 18.0
            IB =  0.667*lon + 6.667
        # Zone 03.
        elseif (lon > -47.5)
            SB = 0.0
            IB = 0.667*lon + 6.667
        # Zone 04.
        elseif (lon > -50.0)
            SB = 0.0
            IB = 2.0*lon + 70.0
        # Zone 05.
        elseif (lon > -52.5)
            SB = -2.0*lon - 100.0
            IB =  2.0*lon +  70.0
        # Zone 06.
        elseif (lon > -55.0)
            SB =  1.0*lon + 57.5
            IB = -1.0*lon - 87.5
        # Zone 07.
        elseif (lon > -57.5)
            SB = -0.5*lon - 25.0
            IB = -1.0*lon - 87.5
        # Zone 08.
        elseif (lon > -60.0)
            SB = -0.5*lon -  25.0
            IB = -5.0*lon - 317.5
        # Zone 09.
        elseif (lon > -67.5)
            SB =  0.25*lon + 20.0
            IB = -1.00*lon - 77.5
        # Zone 10.
        elseif (lon > -70.0)
            SB = 0.25*lon + 20.0
            IB = -10.0
        # Zone 11.
        elseif (lon > -72.5)
            SB = 1.5*lon + 107.5
            IB = -10.0
        # Zone 12.
        else
            SB =  1.5*lon + 107.5
            IB = -2.0*lon - 155.0
        end

        return ( (lat <= SB) && (lat >= IB) )
    end

    return false
end


text:
using Pkg; Pkg.activate(@__DIR__)
using MuJoCo
mj_activate("/home/taylor/.mujoco/bin/mjkey.txt") # set location to MuJoCo key path

using LyceumMuJoCo, LyceumMuJoCoViz
using FiniteDiff

using IterativeLQR
using LinearAlgebra
using Random

# ## load MuJoCo model
path = joinpath(@__DIR__, "../../../env/box/deps/block.xml")

include("mujoco_model.jl")
box = MuJoCoModel(path)
sim = LyceumMuJoCo.MJSim(box.m, box.d)

@show box.m.body_mass
@show box.m.body_inertia[:, :]

T = 100
states = Array(undef, statespace(sim), T)
sim.d.qpos[:] = [0.0; 0.0; -0.24 + 1.0; 0.0; 0.0; 0.0]
sim.d.qvel[:] = zeros(6)
sim.d.ctrl
for t = 1:T
    sim.d.ctrl[:] = [1.0; 0.0; 0.0]
    LyceumMuJoCo.step!(sim)
    states[:, t] .= getstate(sim)
end
visualize(sim, trajectories=[states])

# ## horizon
T = 101

# ## box
nx = box.nx
nu = box.nu

# ## model
dyn = Dynamics(
    (y, x, u, w) -> f!(y, box, x, u),
    (dx, x, u, w) -> fx!(dx, box, x, u),
    (du, x, u, w) -> fu!(du, box, x, u),
    nx, nx, nu)

model = [dyn for t = 1:T-1]

# ## initial conditions
x1 = [0.0; 0.0; -0.24; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0]
# xT = [1.0; 0.0; -0.24; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0] # right goal
xT = [0.0; 0.0; -0.24 + 1.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0] # right goal

# x1 = [0.0; 0.0; 0.0; 0.0]
# xM = [0.0; 0.2 * π; 0.0; 0.0]
# xT = [0.0; 0.2 * π; 0.0; 0.0]
# x_ref = [0.0; 0.2 * π; 0.0; 0.0]

# # rollout
ū = [zeros(3) for t = 1:T-1]
w = [zeros(0) for t = 1:T-1]
x̄ = rollout(model, x1, ū)

# ## objective
ot = (x, u, w) -> transpose(x - xT) * Diagonal(1.0 * ones(nx)) * (x - xT) + transpose(u) * Diagonal(1.0e-2 * ones(nu)) * u
oT = (x, u, w) -> transpose(x - xT) * Diagonal(1.0 * ones(nx)) * (x - xT)

ct = Cost(ot, nx, nu)
cT = Cost(oT, nx, 0)
obj = [[ct for t = 1:T-1]..., cT]

# ## constraints
goal(x, u, w) = x - xT

cont = Constraint()
conT = Constraint(goal, nx, 0)
cons = [[cont for t = 1:T-1]..., conT]

# ## problem
prob = solver(model, obj, cons,
    opts=Options(
        linesearch=:armijo,
        α_min=1.0e-5,
        obj_tol=1.0e-3,
        grad_tol=1.0e-3,
        con_tol=0.005,
        max_iter=100,
        max_al_iter=10,
        ρ_init=1.0,
        ρ_scale=10.0,
        verbose=true))
initialize_controls!(prob, ū)
initialize_states!(prob, x̄)

# ## solve
@time IterativeLQR.solve!(prob)

# ## solution
x_sol, u_sol = get_trajectory(prob)
@show IterativeLQR.eval_obj(prob.m_data.obj.costs, prob.m_data.x, prob.m_data.u, prob.m_data.w)
@show prob.s_data.iter[1]
@show norm(goal(prob.m_data.x[T], zeros(0), zeros(0)), Inf)

# ##
# using Plots
# plot(hcat(x_sol...)')
# plot(hcat(u_sol..., u_sol[end])', linetype=:steppost)

# ## visualize
x_vis = [[x_sol[1] for t = 1:10]..., x_sol..., [x_sol[end] for t = 1:10]...]
states = Array(undef, statespace(sim), length(x_vis))
for t = 1:length(x_vis)
    sim.d.qpos .= x_vis[t][1:6]
    sim.d.qvel .= x_vis[t][6 .+ (1:6)]
    sim.d.ctrl .= [0.0]
    # LyceumMuJoCo.step!(sim)
    states[:, t] .= getstate(sim)
end
visualize(sim, trajectories=[states])


text:
#=
Copyright (c) 2015, Intel Corporation

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of Intel Corporation nor the names of its contributors
      may be used to endorse or promote products derived from this software
      without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=#

# julia knob-test2.jl ../matrices/bcsstk14.mtx
# Turning on any of the commented statement to repro the bug.

include("../../src/Sparso.jl")
include("../../src/simple-show.jl")
include("./utils.jl")
using Sparso

function pcg_symgs(x, A, b, tolerance, maxiter)
    __mknobL4__ = Sparso.new_matrix_knob(:L,true,true,false,false,false,true)
    __mknobA1__ = Sparso.new_matrix_knob(:A,true,true,true,true,false,true)
    __mknobU6__ = Sparso.new_matrix_knob(:U,true,true,false,false,false,true)
    __fknobilu__ = Sparso.new_function_knob()
    __fknob3__ = Sparso.new_function_knob()
    __fknob2__ = Sparso.new_function_knob()
    __fknob5__ = Sparso.new_function_knob()
    __fknob7__ = Sparso.new_function_knob()
    __fknob0__ = Sparso.new_function_knob()
    __fknob8__ = Sparso.new_function_knob()
    Sparso.set_derivative(__mknobL4__,Sparso.DERIVATIVE_TYPE_LOWER_TRIANGULAR,__mknobA1__)
    Sparso.set_derivative(__mknobU6__,Sparso.DERIVATIVE_TYPE_SYMMETRIC,__mknobA1__)
    Sparso.set_derivative(__mknobL4__,Sparso.DERIVATIVE_TYPE_SYMMETRIC,__mknobA1__)
    Sparso.set_derivative(__mknobU6__,Sparso.DERIVATIVE_TYPE_UPPER_TRIANGULAR,__mknobA1__)
    Sparso.add_mknob_to_fknob(__mknobL4__,__fknob3__)
    Sparso.add_mknob_to_fknob(__mknobA1__,__fknob2__)
    Sparso.add_mknob_to_fknob(__mknobU6__,__fknob5__)
    Sparso.add_mknob_to_fknob(__mknobL4__,__fknob7__)
    Sparso.add_mknob_to_fknob(__mknobA1__,__fknob0__)
    Sparso.add_mknob_to_fknob(__mknobU6__,__fknob8__)
    Sparso.add_mknob_to_fknob(__mknobA1__,__fknobilu__)
    total_time = time()

    L = tril(A)
    U = SparseMatrixCSC{Cdouble, Cint}(spdiagm(1./diag(A)))*triu(A)
    # ISSUE: Either of the following will make the code run endlessly
    # L, U = Sparso.ilu(A)
    # L, U = Sparso.ilu(A, __fknobilu__)

    r = b - Sparso.SpMV(1,A,x,__fknob2__)
    normr0 = Sparso.norm(r)
    z = copy(r)
    Sparso.fwdTriSolve!(z,L,r,__fknob3__)
    Sparso.bwdTriSolve!(z,U,z,__fknob5__)
    p = copy(z)
    rz = Sparso.dot(r,z)
    rel_err = 1
    k = 1
    while true
            old_rz = rz
            Ap = Sparso.SpMV(1,A,p,__fknob0__)
            alpha = old_rz / Sparso.dot(p,Ap)
            Sparso.WAXPBY!(x,1,x,alpha,p)
            Sparso.WAXPBY!(r,1,r,-alpha,Ap)
            rel_err = Sparso.norm(r) / normr0
            if rel_err < tolerance
                break
            end
            Sparso.fwdTriSolve!(z,L,r,__fknob7__)
            Sparso.bwdTriSolve!(z,U,z,__fknob8__)
            rz = Sparso.dot(r,z)
            Sparso.WAXPBY!(p,1,z,rz / old_rz,p)
            k = k + 1
    end
    total_time = time() - total_time
    println("total = ",total_time,"s")
    Sparso.delete_matrix_knob(__mknobL4__)
    Sparso.delete_matrix_knob(__mknobA1__)
    Sparso.delete_matrix_knob(__mknobU6__)
    Sparso.delete_function_knob(__fknob3__)
    Sparso.delete_function_knob(__fknob2__)
    Sparso.delete_function_knob(__fknob5__)
    Sparso.delete_function_knob(__fknob7__)
    Sparso.delete_function_knob(__fknob0__)
    Sparso.delete_function_knob(__fknob8__)
    return x,k,rel_err
end

A         = matrix_market_read(ARGS[1], true, true)
m         = size(A, 1)
b         = ones(Float64, m)
originalA = copy(A)
tolerance = 1e-7
maxiter   = 20000

x = zeros(Float64, m)
x, k, rel_err = pcg_symgs(x, A, b, tolerance, maxiter)
println("\tOptimized sum of x=", sum(x))
println("\tOptimized k=", k)
println("\tOptimized rel_err=", rel_err)

max_stars_repo_name: IntelLabs/Sparso

max_issues_repo_name: IntelLabs/Sparso

max_forks_repo_name: IntelLabs/Sparso


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

JLLWrappers.@generate_main_file_header("XPA")
JLLWrappers.@generate_main_file("XPA", UUID("9dbca590-e19a-5566-89a8-3997bfd21c58"))
end  # module XPA_jll


text:
##  Test of fft, power spectrum, and Hilbert transform
##  using as example of the ElNino time series
##
##  Author Bernd Blasius (bernd.blasius@gmail.com)

module W

using CSV, PyPlot, FFTW, Statistics

include("../src/fft_power.jl")

function test_power_spectrum()
 # read in the data
  df = CSV.read("../data/ElNino_data.csv"; comment="#")
  t   = df[:,1]  # time (year)
  sst = df[:,2]  # el nino signal (sea surface temperature SST)
  x   = df[:,3]  # el nino temperature anomaly

  fs = 1 ./ (mean(diff(t)))  # mean sampling frequency
  f, pow = power_real(x,fs)

  figure("El Nino Power")
  clf()
  subplot(2,1,1)
  plot(t,x)
  ylabel("El Nino")
  xlabel("time")

  subplot(2,1,2)
  plot(f, log10.(pow))
  xlabel("frequency")
  ylabel("power")

end

function test_hilbert()
  # read in the El Nino data
  df = CSV.read("../data/ElNino_data.csv"; comment="#")
  t   = df[:,1]  # time (year)
  sst = df[:,2]  # el nino signal (sea surface temperature SST)
  x   = df[:,3]  # el nino temperature anomaly

  fs = 1 ./ (mean(diff(t)))  # mean sampling frequency
  h = hilbert(x,fs)

  figure("hilbert")
  clf()
  subplot(2,1,1)  # phase plane
  plot(t,x)  # El Nino
  plot(t,h,"r") # Hilber transform
  xlabel("time")
  ylabel("El Nino")

  subplot(2,1,2)  # phase plane
  plot(x,h)

end

#test_power_spectrum()
test_hilbert()

end # module

max_stars_repo_name: berndblasius/WaveletAnalysis

max_issues_repo_name: berndblasius/WaveletAnalysis

max_forks_repo_name: berndblasius/WaveletAnalysis


text:
# vim: set et ts=2 sw=2:

@with_kw mutable struct It
  char = (skip='?',less='<',more='>',num='$',klass='!')
  str  = (skip="?")
  some = (max=32,bins=.5, cohen=0.3, trivial=1.05)
  seed = 1
end

max_stars_repo_name: timm/misc

max_issues_repo_name: timm/misc

max_forks_repo_name: timm/misc


text:
function chunker(li, total_chunks)
    item_count = length(li)
    if total_chunks > item_count
        num_chunks = item_count
    else
        num_chunks = total_chunks
    end
    chunk_size = round(Int, item_count / num_chunks, RoundDown)
    remainder = item_count - (chunk_size * num_chunks)
    used_chunk_size = chunk_size + 1
    r = []
    # println("item_count: ", item_count, ", num_chunks: ", num_chunks, ", chunk_size: ", chunk_size, ", remainder: ", remainder)

    for i  = 0:num_chunks-1
        if i >= remainder
            cs = used_chunk_size - 1
        else
            cs = used_chunk_size
        end

        if i >= remainder
            offset = remainder
        else
            offset = 0
        end
        start = (i * cs + offset) + 1
        _end = (i * cs + offset) + cs
        push!(r, li[start:_end])
    end
    r
end

function run(chunk_idx, total_chunks, step, data_dir)
    args_path = string("args_", step, ".jld")
    args_f = joinpath(data_dir, args_path)
    args = JLD.jldopen(args_f, "r") do f_in
        read(f_in, "data")
    end

    # the file should contain the path to the folder containing the function
    # and the name of the module, separated by ;
    # ex: path/to/folder;moduleName
    func_path = string("func_", step, ".jld")
    func_f = joinpath(data_dir, func_path)
    func = JLD.jldopen(func_f, "r") do f_in
        read(f_in, "data")
    end

    global functionPath = split(func, ";")[1]
    moduleName = split(func, ";")[2]

    # function import
    # all worker has the path in workspace need using Distributed
    push!(LOAD_PATH, functionPath) #path to the folder containing the objfunc
    _module = Symbol(moduleName) #module name
    @eval using $_module

    if total_chunks == 1
        chunk = args
    else
        chunk = chunker(args, total_chunks)[chunk_idx+1]
    end

    result = []
    for arg in chunk
        _func(arg; kws...) = @eval objfuncF($arg...; $kws...)
        push!(result, _func(arg))
    end

    result_path = string("result_", chunk_idx, ".jld")
    result_f = joinpath(data_dir, result_path)
    JLD.jldopen(result_f, "w") do f_out
        write(f_out, "data", result)
    end
end

if abspath(PROGRAM_FILE) == @__FILE__
    chunk_idx = parse(Int, ARGS[1])
    total_chunks = parse(Int, ARGS[2])
    step = parse(Int, ARGS[3])
    data_dir = ARGS[4]
    println("worker.jl starting with chunk_idx: ", chunk_idx, "| total_chunks: ",total_chunks, " | step: ", step, " | data_dir: ", data_dir)
    run(chunk_idx, total_chunks, step, data_dir)
end

max_stars_repo_name: emews/EQ-JL

max_issues_repo_name: emews/EQ-JL

max_forks_repo_name: emews/EQ-JL


text:
using Test
using PooledArrays
using DataAPI: refarray, refvalue, refpool

@testset "PooledArrays" begin
    a = rand(10)
    b = rand(10,10)
    c = rand(1:10, 1000)

    @test PooledArray(a) == a
    @test PooledArray(b) == b
    pc = PooledArray(c)
    @test pc == c
    @test convert(Array, pc) == c
    #@test issorted(pc.invpool)

    @test copy(pc) == pc

    @test isa(similar(pc), typeof(pc))

    @test reverse(pc) == reverse(c)

    @test pc[34:250] == c[34:250]

    @test sort(pc) == sort(c)
    @test sortperm(pc) == sortperm(c)

    push!(pc, -10)
    push!(c, -10)
    @test pc == c
    @test maximum(values(pc.invpool)) == 11
    @test length(pc.pool) == 11

    pc2 = copy(pc)
    @test append!(pc2, [3, 1]) === pc2
    @test pc2 == [pc; 3; 1]

    pc2 = copy(pc)
    @test deleteat!(pc2, 2) === pc2
    @test pc2 == pc[[1; 3:end]]
    @test deleteat!(pc2, [2, 4]) === pc2
    @test pc2 == pc[[1; 4; 6:end]]

    #@test issorted(pc.invpool)

    @test map(identity, pc) == pc
    @test map(x->2x, pc) == map(x->2x, c)

    # case where the outputs are one-to-many
    pa = PooledArray([1,2,3,4,5,6])
    @test map(isodd, pa) == [true,false,true,false,true,false]

    px = PooledArray(rand(128))
    py = PooledArray(rand(200))

    @test isa(vcat(px, py), PooledArray{Float64, UInt16})
    @test vcat(px, Array(py)) == vcat(px, py)

    px2 = copy(px)
    resize!(px2, 100)
    @test px2 == px[1:100]

    px3 = PooledArray(px2)
    px3[1] = 0
    @test px2 !== px3
    @test px2 != px3

    @test findall(PooledArray([true,false,true])) == [1,3]

    @test PooledArray{Union{Int,Missing}}([1, 2]) isa PooledArray{Union{Int,Missing}}

    @test eltype(PooledArray(rand(128)).refs) == UInt32
    @test eltype(PooledArray(rand(300)).refs) == UInt32
    @test eltype(PooledArray(rand(128), UInt8).refs) == UInt8
    @test eltype(PooledArray(rand(300), UInt16).refs) == UInt16
    @test PooledVector == PooledArray{T, R, 1} where {T, R}
    @test PooledMatrix == PooledArray{T, R, 2} where {T, R}

    s = PooledArray(["a", "a", "b"])
    @test all(refarray(s) .== [1, 1, 2])
    for i in 1:3
        @test refvalue(s, refarray(s)[i]) == s[i]
    end
    @test refpool(s) == ["a", "b"]

    @testset "push!" begin
        xs = PooledArray([10, 20, 30])
        @test xs === push!(xs, -100)
        @test xs == [10, 20, 30, -100]
    end

    @testset "pushfirst!" begin
        ys = PooledArray([10, 20, 30])
        @test ys === pushfirst!(ys, -100)
        @test ys == [-100, 10, 20, 30]
    end
end


text:
"""
    closing(img; dims=coords_spatial(img), r=1)
    closing(img, se)

Perform the morphological closing on `img`. The closing operation is defined as dilation
followed by an erosion: `erode(dilate(img, se), se)`.

$(_docstring_se)

# Examples

```jldoctest; setup = :(using ImageMorphology)
julia> img = falses(7,7); img[2, 2] = true; img[3:5, 3:5] .= true; img[4, 4] = false; img
7×7 BitMatrix:
 0  0  0  0  0  0  0
 0  1  0  0  0  0  0
 0  0  1  1  1  0  0
 0  0  1  0  1  0  0
 0  0  1  1  1  0  0
 0  0  0  0  0  0  0
 0  0  0  0  0  0  0

julia> closing(img)
7×7 BitMatrix:
 1  1  0  0  0  0  0
 1  1  0  0  0  0  0
 0  0  1  1  1  0  0
 0  0  1  1  1  0  0
 0  0  1  1  1  0  0
 0  0  0  0  0  0  0
 0  0  0  0  0  0  0

julia> closing(img, strel_diamond(img)) # # use diamond shape SE
7×7 BitMatrix:
 0  0  0  0  0  0  0
 0  1  0  0  0  0  0
 0  0  1  1  1  0  0
 0  0  1  1  1  0  0
 0  0  1  1  1  0  0
 0  0  0  0  0  0  0
 0  0  0  0  0  0  0
```

## See also

- [`opening!`](@ref) is the in-place version of this function.
- [`closing`](@ref) is the dual operator of `opening` in the sense that
  `complement.(opening(img)) == closing(complement.(img))`.
"""
closing(img; kwargs...) = closing!(similar(img), img, similar(img); kwargs...)
closing(img, se) = closing!(similar(img), img, se, similar(img))

"""
    closing!(out, img, buffer; [dims], [r])
    closing!(out, img, se, buffer)

The in-place version of [`closing`](@ref) with input image `img` and output image `out`. The
intermediate dilation result is stored in `buffer`.
"""
function closing!(out, img, buffer; dims=coords_spatial(img), r=nothing)
    return closing!(out, img, strel_box(img, dims; r), buffer)
end
function closing!(out, img, se, buffer)
    dilate!(buffer, img, se)
    erode!(out, buffer, se)
    return out
end
closing!(out::AbstractArray{<:Color3}, img, se, buffer) = throw(ArgumentError("color image is not supported"))


text:
# This file is a part of Julia. License is MIT: https://julialang.org/license

using Base.Printf: @sprintf

@generated function staged_t1(a,b)
    if a == Int
        return :(a+b)
    else
        return :(a*b)
    end
end

@test staged_t1(1,2) == 3
@test staged_t1(1.0,0.5) == 0.5
@test staged_t1(1,0.5) == 1.5

tinline(a,b) = staged_t1(a,b)

@test !isa(tinline(1,2),Expr)
@test tinline(1,0.5) == 1.5

@generated function splat(a,b...)
    :( ($a,$b,a,b) )
end

@test splat(1,2,3) == (Int,(Int,Int),1,(2,3))

stagediobuf = IOBuffer()
@generated function splat2(a...)
    print(stagediobuf, a)
    :(nothing)
end

const intstr = @sprintf("%s", Int)
splat2(1)
@test String(take!(stagediobuf)) == "($intstr,)"
splat2(1, 3)
@test String(take!(stagediobuf)) == "($intstr, $intstr)"
splat2(5, 2)
@test String(take!(stagediobuf)) == ""
splat2(1:3, 5.2)
@test String(take!(stagediobuf)) == "(UnitRange{$intstr}, Float64)"
splat2(3, 5:2:7)
@test String(take!(stagediobuf)) == "($intstr, StepRange{$intstr,$intstr})"
splat2(1, 2, 3, 4)
@test String(take!(stagediobuf)) == "($intstr, $intstr, $intstr, $intstr)"
splat2(1, 2, 3)
@test String(take!(stagediobuf)) == "($intstr, $intstr, $intstr)"
splat2(1:5, 3, 3:3)
@test String(take!(stagediobuf)) == "(UnitRange{$intstr}, $intstr, UnitRange{$intstr})"
splat2(1:5, 3, 3:3)
@test String(take!(stagediobuf)) == ""
splat2(1:5, 3:3, 3)
@test String(take!(stagediobuf)) == "(UnitRange{$intstr}, UnitRange{$intstr}, $intstr)"
splat2(1:5, 3:3)
@test String(take!(stagediobuf)) == "(UnitRange{$intstr}, UnitRange{$intstr})"
splat2(3, 3:5)
@test String(take!(stagediobuf)) == "($intstr, UnitRange{$intstr})"

# varargs specialization with parametric @generated functions (issue #8944)
@generated function splat3(A::AbstractArray{T,N}, indx::RangeIndex...) where {T,N}
    print(stagediobuf, indx)
    :(nothing)
end
A = rand(5,5,3)
splat3(A, 1:2, 1:2, 1)
@test String(take!(stagediobuf)) == "(UnitRange{$intstr}, UnitRange{$intstr}, $intstr)"
splat3(A, 1:2, 1, 1:2)
@test String(take!(stagediobuf)) == "(UnitRange{$intstr}, $intstr, UnitRange{$intstr})"

B = view(A, 1:3, 2, 1:3)
@generated function mygetindex(S::SubArray, indices::Real...)
    T, N, A, I = S.parameters
    if N != length(indices)
        error("Wrong number of indices supplied")
    end
    Ip = I.parameters
    NP = length(Ip)
    indexexprs = Vector{Expr}(uninitialized, NP)
    j = 1
    for i = 1:NP
        if Ip[i] == Int
            indexexprs[i] = :(S.indices[$i])
        else
            indexexprs[i] = :(S.indices[$i][indices[$j]])
            j += 1
        end
    end
    ex = :(S.parent[$(indexexprs...)])
    ex
end
@test mygetindex(B,2,2) == A[2,2,2]

# issue #8497
module MyTest8497
internalfunction(x) = x+1
@generated function h(x)
    quote
        internalfunction(x)
    end
end
end
@test MyTest8497.h(3) == 4

# static parameters (issue #8505)
@generated function foo1(a::Array{T,N}) where {N,T}
    "N = $N, T = $T"
end
@generated function foo2(a::Array{T,N}) where {T,N}
    "N = $N, T = $T"
end
@test foo1(randn(3,3)) == "N = 2, T = Float64"
@test foo2(randn(3,3)) == "N = 2, T = Float64"

# issue #9088
@generated function f9088(x, a=5)
    :(x+a)
end
@test f9088(7) == 12

# issue #10502
@generated function f10502(x...)
    :($x)
end
f10502() = ()
@test f10502(1) == (Int,)
@test f10502(1,2) == (Int,Int)
@test f10502(1,2,3) == (Int,Int,Int)

# One-line @generated functions
@generated oneliner(x,y) = :($x, x, $y, y)
@test oneliner(1, 2.) == (Int, 1, Float64, 2.)

# issue #11982
@generated function f11982(T)
    string(T.parameters[1])
end
@test f11982(Float32) == "Float32"
@test f11982(Int32) == "Int32"

# @generated functions that throw (shouldn't segfault or throw)
module TestGeneratedThrow
    using Test

    @generated function bar(x)
        error("I'm not happy with type $x")
    end

    foo() = (bar(rand() > 0.5 ? 1 : 1.0); error("foo"))
    function __init__()
        code_typed(foo,(); optimize = false)
        cfunction(foo,Cvoid,Tuple{})
    end
end

# @generated functions including inner functions
@generated function _g_f_with_inner(x)
    return :(y -> y)
end
@test_throws ErrorException _g_f_with_inner(1)

@generated function _g_f_with_inner2(x)
    return y -> y
end
@test _g_f_with_inner2(1)(2) == 2

# @generated functions errors
global gf_err_ref = Ref{Int}()

gf_err_ref[] = 0
let gf_err, tsk = @async nothing # create a Task for yield to try to run
    @generated function gf_err()
        gf_err_ref[] += 1
        yield()
        gf_err_ref[] += 1000
    end
    @test_throws ErrorException gf_err()
    @test_throws ErrorException gf_err()
    @test gf_err_ref[] == 4
end

gf_err_ref[] = 0
let gf_err2
    @generated function gf_err2(::f) where {f}
        gf_err_ref[] += 1
        reflect = f.instance
        gf_err_ref[] += 1
        reflect(+, (Int,Int))
        gf_err_ref[] += 1000
        return nothing
    end
    @test_throws ErrorException gf_err2(code_typed)
    @test_throws ErrorException gf_err2(code_llvm)
    @test_throws ErrorException gf_err2(code_native)
    @test gf_err_ref[] == 12
    @test gf_err2(code_lowered) === nothing
end

# issue #15043
decorated = Set{DataType}()
let
    @generated function decorate(t)
        push!(decorated, t)
    end

    foo() = return nothing
    decorate(foo)
    @test in(typeof(foo), decorated)

    bar() = return 1
    decorate(bar)
    @test in(typeof(bar), decorated)
end

# issue #19897
@test code_lowered(staged_t1, (Int,Int)) isa Array  # check no error thrown

# issue #10178
@generated function f10178(x::X) where X
    :(x)
end
g10178(x) = f10178(x)
@test g10178(5) == 5
@generated function f10178(x::X) where X
    :(2x)
end
g10178(x) = f10178(x)
@test g10178(5) == 10

# issue #22135
@generated f22135(x::T) where T = x
@test f22135(1) === Int

# PR #22440

f22440kernel(x...) = x[1] + x[1]
f22440kernel(x::AbstractFloat) = x * x
f22440kernel(::Type{T}) where {T} = one(T)
f22440kernel(::Type{T}) where {T<:AbstractFloat} = zero(T)

@generated function f22440(y)
    sig, spvals, method = Base._methods_by_ftype(Tuple{typeof(f22440kernel),y}, -1, typemax(UInt))[1]
    code_info = Base.uncompressed_ast(method)
    body = Expr(:block, code_info.code...)
    Base.Core.Inference.substitute!(body, 0, Any[], sig, Any[spvals...], 0, :propagate)
    return code_info
end

@test f22440(Int) === f22440kernel(Int)
@test f22440(Float64) === f22440kernel(Float64)
@test f22440(Float32) === f22440kernel(Float32)
@test f22440(0.0) === f22440kernel(0.0)
@test f22440(0.0f0) === f22440kernel(0.0f0)
@test f22440(0) === f22440kernel(0)

# PR #23168

function f23168(a, x)
    push!(a, 1)
    if @generated
        :(y = x + x)
    else
        y = 2x
    end
    push!(a, y)
    if @generated
        :(y = (y, $x))
    else
        y = (y, typeof(x))
    end
    push!(a, 3)
    return y
end

let a = Any[]
    @test f23168(a, 3) == (6, Int)
    @test a == [1, 6, 3]
    @test contains(string(code_lowered(f23168, (Vector{Any},Int))), "x + x")
    @test contains(string(Base.uncompressed_ast(first(methods(f23168)))), "2 * x")
    @test contains(string(code_lowered(f23168, (Vector{Any},Int), false)), "2 * x")
    @test contains(string(code_typed(f23168, (Vector{Any},Int))), "(Base.add_int)(x, x)")
end

# issue #18747
@test_throws ErrorException eval(:(f(x) = @generated g() = x))

max_stars_repo_name: YingboMa/julia

max_issues_repo_name: YingboMa/julia

max_forks_repo_name: YingboMa/julia