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

using Markdown
using InteractiveUtils

# ╔═╡ 85e74b35-5e6e-4e69-b7ad-50cedca5f4cf
using PlutoUI

# ╔═╡ e85323e0-e991-4c15-b41f-59b81571e4c2
begin
	using MLJ
	import RDatasets: dataset
	import DataFrames: DataFrame, select, Not, describe
	using Random
end

# ╔═╡ 274c3df4-713b-4643-b2ab-e002151c3164
using MLJMultivariateStatsInterface

# ╔═╡ 7bd93fe6-f392-45eb-95ff-6bacb7efc974
begin
	using MLJClusteringInterface
	@load KMeans pkg="Clustering"
end

# ╔═╡ f4aafce6-326e-4c7a-bd90-45669f0494ba
using Plots

# ╔═╡ 50defd99-5eb4-444a-9abb-5003764563e6
using UrlDownload

# ╔═╡ effa8648-8ca7-42ef-bab6-17f52a417ffd
begin
	using MLJScikitLearnInterface #También hay que instalar scikit-learn donde sea que tengamos a Julia, en mi caso, uso pip3 install scikit-learn
	@load KNeighborsClassifier pkg="ScikitLearn"
end

# ╔═╡ 146c09f4-f4c6-41ab-a565-03b2d6825129
using CSV, HTTP

# ╔═╡ a3052245-5f44-4166-922b-18df99c0a49d
using MLJDecisionTreeInterface

# ╔═╡ ca2a2e0c-f6f1-11eb-12d4-5d81b9cb97c1
md"""# Ciencia de Datos pt. 2

	- Oscar Alejando Esquivel Flores
	- Óscar Anuar Alvarado Morán
	- Mario Horacio Garrido Czacki
"""

# ╔═╡ c418450d-0ace-4a13-9fbc-9c4dc1c153c3
PlutoUI.TableOfContents(title="🔬 Ciencia de datos pt. 2 🔭", depth = 5)

# ╔═╡ 379fad8b-59b6-4e41-aa5f-d3ff7dbc4f26
md"# Aprendizaje Automatizado"

# ╔═╡ ae8acf9e-5b1b-4d69-af47-96a66b42189a
md"## MLJ.jl
- [GitHub](https://github.com/alan-turing-institute/MLJ.jl)
- [Alan Turing Institute](https://alan-turing-institute.github.io/MLJ.jl/dev/)
- [DataScience Tutorials](https://alan-turing-institute.github.io/DataScienceTutorials.jl/)

`MLJ.jl` es un ambiente que provee de una _interfaz uniforme_ para **ajustar**, **evaluar** y **tunear** modelos de aprendizaje automatizado. Contiene más de 150 modelos de aprendizaje automatizado escritos en Julia y en otros lenguajes, en particular, MLJ envuelve un gran número de modelos del H.H.H `scikit.learn`."

# ╔═╡ 2bb7c88d-6894-4c48-b1eb-ef297ec33fa3
md"### Aprendizaje no supervisado
	- PCA
	- Agrupamiento"

# ╔═╡ 3460d637-a598-4bd4-a169-a10ad9e220d1
md"Usaremos el conjunto de datos [USArrests](https://www.rdocumentation.org/packages/datasets/versions/3.6.2/topics/USArrests), que consta de arrestos por cada 100,000 residentes para asalto, asesinato y violación en cada uno de los 50 estados de Estados Unidos en el año de 1973. También se presenta el porcentaje de la población viviendo en áreas urbanas."

# ╔═╡ a7cb38fc-7522-4c25-a062-9c5daae14145
begin
	data = dataset("datasets", "USArrests")
	first(data, 5)
end

# ╔═╡ 7c9406b5-21a8-41d7-a777-e7ba90fb7a00
md"Vemos un poco de descripción de los datos:"

# ╔═╡ 2be4cb86-17b7-4f0f-b66b-380a02038d46
describe(data, :mean, :std, :min, :max)

# ╔═╡ 981fc582-642e-43f1-bacc-340acd40f854
md"Obtengamos los datos numéricos"

# ╔═╡ abac24d2-765c-49aa-befe-291012e61b00
begin
	X = select(data, Not(:State))
	X = coerce(X, :UrbanPop => Continuous, :Assault => Continuous)
end

# ╔═╡ 3dedd727-c900-40c6-95ae-47a697891613
md"#### PCA
Primero, cargamos el modelo"

# ╔═╡ 752fecef-1da9-4943-94f9-d7af84bdf472
@load PCA pkg = MultivariateStats

# ╔═╡ cb9ed21f-996f-4104-b58e-8fe439fbeb06
md"¿Qué pasó aquí? La cosa es que MLJ es sólo una interface para usar paquetes de aprendizaje automatizado, por lo que habrá que instalar diferentes paquetes dependiendo del modelo que querramos usar. Podemos ver algunos modelos a continuación."

# ╔═╡ 8b5e4c86-6083-4977-bb35-0e993d63d7d5
models(matching(X))

# ╔═╡ be737177-8be8-4f0a-abfa-97aa286b1654
md"Si queremos ver todos los modelos disponibles podemos hacerlo como sigue:"

# ╔═╡ 32feb81d-8552-4415-b22f-bb5756581292
models()

# ╔═╡ 431ac7b3-96f3-41c0-a102-edbaf000ce00
md"Creamos el modelo"

# ╔═╡ e46948bc-7bd8-4904-a06e-3d5936c300be
pca_mdl = PCA()

# ╔═╡ 5763d717-d695-40a1-8d14-f3ed8a04fbac
md"Creamos una _máquina_, que es un objeto que vincula un modelo (algoritmo + hiperparámetros) con los datos. Esta almacena los parámetros aprendidos."

# ╔═╡ b65357a5-5af6-4cec-a31c-7ded59155a44
pca = machine(pca_mdl, X)

# ╔═╡ 046dd48c-c757-4cde-8483-8f9f02e1217e
md"¡Ajustamos!"

# ╔═╡ f23080a2-2303-414c-acf9-b642a5e7121f
fit!(pca)

# ╔═╡ 7237e74b-f35d-486e-a769-2f93bbad566d
md"¡Transformamos!"

# ╔═╡ 63ae7fa7-d2aa-48b1-872e-68e035b77422
W = MLJ.transform(pca, X)

# ╔═╡ 130769ec-7515-4149-b925-7ef07a6168b8
begin
	r = report(pca)
	cumsum(r.principalvars ./ r.tvar)
end

# ╔═╡ 9485c2f0-4378-4a1f-90cf-2b992e3714f6
md"Trabajemos con datos más interesantes:"

# ╔═╡ 79cfb0ed-7431-4dc8-ad02-62ca35e4f885
md"""
[Conjunto de datos Orange Juice](https://rdrr.io/cran/ISLR/man/OJ.html):

"The data contains 1070 purchases where the customer either purchased Citrus Hill or Minute Maid Orange Juice. A number of characteristics of the customer and product are recorded."
"""

# ╔═╡ a19df644-cfa2-46cb-875e-fd4a94c00134
begin
	data1 = dataset("ISLR", "OJ")
	X1 = select(data1, [:PriceCH, :PriceMM, :DiscCH, :DiscMM, :SalePriceMM,
                  :SalePriceCH, :PriceDiff, :PctDiscMM, :PctDiscCH]);
end

# ╔═╡ ada8f32b-aab1-4687-9ee1-b1a27ec8ca5d
names(data1)

# ╔═╡ c70c8298-c908-4ef8-a5da-79967d0d8ccb
begin
	SPCA = @pipeline(Standardizer(),
	                 PCA())

	spca = machine(SPCA, X1)
	fit!(spca)
	W1 = MLJ.transform(spca, X1)
	W1
end

# ╔═╡ 54b04b9f-731c-4642-a0f8-c1b6df24b6ba
begin
	rpca = collect(values(report(spca).report_given_machine))[2]
	cs = cumsum(rpca.principalvars ./ rpca.tvar)
end

# ╔═╡ bea29f95-25ea-4fb9-8f86-a2860c3f1120
md"#### Agrupamiento
Hagamos algo de agrupamiento con estos mismos datos que acabamos de obtener"

# ╔═╡ 7d961743-32f8-4ad0-896d-74e1484d8a9b
begin
	SPCA2 = @pipeline(Standardizer(),
	                  PCA(),
	                  MLJClusteringInterface.KMeans(k=3))

	spca2 = machine(SPCA2, X1)
	fit!(spca2)
end

# ╔═╡ a2bc7993-8570-4863-8dfd-baa107424198
models()

# ╔═╡ 7e54fca2-fadb-403c-b4b1-29aead7a2cb8
assignments = collect(values(report(spca2).report_given_machine))[3].assignments

# ╔═╡ 1bae87f9-2ec3-413c-a445-ddebdc52ea44
begin
	mask1 = assignments .== 1
	mask2 = assignments .== 2
	mask3 = assignments .== 3;
end

# ╔═╡ 0224fea6-3c9d-46cb-b936-9d986e53cd1d
plotly()

# ╔═╡ c091be98-c321-48e0-9b13-05de97c12cd9
begin
	plot(1,1,1, alpha = 0)
	for (m, c) in zip((mask1, mask2, mask3), ("red", "green", "blue"))
	    scatter!(W1[m, 1], W1[m, 2], W1[m, 3], markersize=1, color=c, alpha = 0.5)
	end
	plot!(1,1,1, alpha = 0)
end

# ╔═╡ 0798b789-50c1-4080-8386-1a6429b32f7d
md"### Aprendizaje supervisado"

# ╔═╡ b53de955-1b1d-4be5-9bd7-9ce9f84b83e5
md"#### Clasificación"

# ╔═╡ 098588b6-6c67-4656-b520-00a53f39237f
begin
	url2 = "http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data"
	header = ["Class", "Alcool", "Malic acid", "Ash", "Alcalinity of ash",
	          "Magnesium", "Total phenols", "Flavanoids",
	          "Nonflavanoid phenols", "Proanthcyanins", "Color intensity",
	          "Hue", "OD280/OD315 of diluted wines", "Proline"]
	data2 = urldownload(url2, true, format=:CSV, header=header)
end

# ╔═╡ eb79421f-624c-418a-8a5e-59b4e0c23bd0
begin
	df2 = DataFrame(data2)
	describe(df2)
end

# ╔═╡ af754478-fa99-414b-a48b-389af4fff2d3
y_wine, X_wine = unpack(df2, ==(:Class), colname->true)

# ╔═╡ 104558aa-b7a3-4008-8f68-c7e7f9241570
scitype(y_wine)

# ╔═╡ 84ed9b09-40a6-45e8-927c-c98217636f6a
yc = coerce(y_wine, OrderedFactor)

# ╔═╡ 84ce479d-acd0-4ac0-9dd1-4670444165d8
scitype(X_wine)

# ╔═╡ 5625705f-d6ca-4cb2-85b1-4d7cc5efe167
schema(X_wine)

# ╔═╡ 9a3d69b4-7342-4426-861a-56f9266a0706
Xc = coerce(X_wine, :Proline=>Continuous, :Magnesium=>Continuous)

# ╔═╡ aacbb24b-1056-48d2-ae51-b02718c6bdf7
describe(Xc, :mean, :std)

# ╔═╡ d7e4f63f-f950-4bbe-9248-ba21145436e7
models()

# ╔═╡ 225d1f19-7354-4d8c-ad8d-80498bdea59b
KnnPipe = @pipeline(Standardizer(), KNeighborsClassifier())

# ╔═╡ 345decc0-554c-431e-9e51-86160bbb296a
train, test = partition(eachindex(yc), 0.8, shuffle=true, rng=111)

# ╔═╡ ba19bae9-4cd0-4cf8-8953-466488e22b47
knn = machine(KnnPipe, Xc, yc)

# ╔═╡ d6bd99e2-57ab-491e-98ee-3f25bad44a66
fit!(knn, rows=train)

# ╔═╡ 9ca9182b-84a9-4a4e-8c66-fa54ac45ce17
ŷ = predict_mode(knn, rows=test)

# ╔═╡ 59db05e0-a2f6-4666-82e7-7508f2563b93
begin
	r3 = x -> round(x, sigdigits=3)
	accuracy(ŷ, yc[test]) |> r3
end

# ╔═╡ c4adf149-93b9-4a4f-8d16-790ea44088a4
begin
	req = HTTP.get("https://raw.githubusercontent.com/rupakc/UCI-Data-Analysis/master/Airfoil%20Dataset/airfoil_self_noise.dat");

	df_a = CSV.File(req.body; header=["Frequency","Attack_Angle","Chord+Length",
	                  "Free_Velocity","Suction_Side","Scaled_Sound"])
	df_air = DataFrame(df_a)
end

# ╔═╡ e6d330da-98ba-4689-97b9-119b5a5230f9
schema(df_air)

# ╔═╡ f4b660c3-367b-4207-9083-0d0fdcd2988a
y_q, X_q = unpack(df_air, ==(:Scaled_Sound), colname->true)

# ╔═╡ 97d665ec-0e30-4f4c-8480-2ef070e8350f
begin
	y_air, X_ai = unpack(df_air, ==(:Scaled_Sound), colname -> true)
	X_air = MLJ.transform(fit!(machine(Standardizer(), X_ai)), X_ai);
end

# ╔═╡ 15a264a7-78ee-4597-bfc5-79bc6890fb44
train_air, test_air = partition(eachindex(y_air), 0.7, shuffle=true, rng=111)

# ╔═╡ e664cc85-29f9-4c27-b128-6fbbf85dbb35
coerce!(X_air, :Frequency=>Continuous)

# ╔═╡ 19d8300c-97d0-4a9c-915d-83661c393dea
begin
	@load DecisionTreeRegressor pkg=DecisionTree
	dcr = DecisionTreeRegressor()
end

# ╔═╡ e6112bb6-184e-428c-b586-752403998533
begin
	dcrm = machine(dcr, X_air, y_air)

	fit!(dcrm, rows=train_air)
	pred_dcrm = MLJ.predict(dcrm, rows=test_air)
end

# ╔═╡ e1c234e9-7dd2-4079-9bd6-83edc3acf9f8
rms(pred_dcrm, y_air[test_air])

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
MLJ = "add582a8-e3ab-11e8-2d5e-e98b27df1bc7"
MLJClusteringInterface = "d354fa79-ed1c-40d4-88ef-b8c7bd1568af"
MLJDecisionTreeInterface = "c6f25543-311c-4c74-83dc-3ea6d1015661"
MLJMultivariateStatsInterface = "1b6a4a23-ba22-4f51-9698-8599985d3728"
MLJScikitLearnInterface = "5ae90465-5518-4432-b9d2-8a1def2f0cab"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
UrlDownload = "856ac37a-3032-4c1c-9122-f86d88358c8b"

[compat]
CSV = "~0.8.5"
DataFrames = "~1.2.2"
HTTP = "~0.9.13"
MLJ = "~0.16.7"
MLJClusteringInterface = "~0.1.4"
MLJDecisionTreeInterface = "~0.1.3"
MLJMultivariateStatsInterface = "~0.2.2"
MLJScikitLearnInterface = "~0.1.10"
Plots = "~1.20.0"
PlutoUI = "~0.7.9"
RDatasets = "~0.7.5"
UrlDownload = "~1.0.0"
"""

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

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

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

[[Arpack]]
deps = ["Arpack_jll", "Libdl", "LinearAlgebra"]
git-tree-sha1 = "2ff92b71ba1747c5fdd541f8fc87736d82f40ec9"
uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
version = "0.4.0"

[[Arpack_jll]]
deps = ["Libdl", "OpenBLAS_jll", "Pkg"]
git-tree-sha1 = "e214a9b9bd1b4e1b4f15b22c0994862b66af7ff7"
uuid = "68821587-b530-5797-8361-c406ea357684"
version = "3.5.0+3"

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

[[BSON]]
git-tree-sha1 = "92b8a8479128367aaab2620b8e73dff632f5ae69"
uuid = "fbb218c0-5317-5bc6-957e-2ee96dd4b1f0"
version = "0.3.3"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[DecisionTree]]
deps = ["DelimitedFiles", "Distributed", "LinearAlgebra", "Random", "ScikitLearnBase", "Statistics", "Test"]
git-tree-sha1 = "8b58db7954a6206399d9f66ef1a328da8c0f1d19"
uuid = "7806a523-6efd-50cb-b5f6-3fa6f1930dbb"
version = "0.10.10"

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

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

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

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

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

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

[[EarCut_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "92d8f9f208637e8d2d28c664051a00569c01493d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.1.5+1"

[[EarlyStopping]]
deps = ["Dates", "Statistics"]
git-tree-sha1 = "9427bc7a6c186d892f71b1c36ee7619e440c9e06"
uuid = "792122b4-ca99-40de-a6bc-6742525f08b6"
version = "0.1.8"

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

[[ExprTools]]
git-tree-sha1 = "b7e3d17636b348f005f11040025ae8c6f645fe92"
uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04"
version = "0.1.6"

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

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

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

[[FilePathsBase]]
deps = ["Dates", "Mmap", "Printf", "Test", "UUIDs"]
git-tree-sha1 = "0f5e8d0cb91a6386ba47bd1527b240bd5725fbae"
uuid = "48062228-2e41-5def-b9a4-89aafe57970f"
version = "0.9.10"

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

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

[[Fontconfig_jll]]
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "35895cf184ceaab11fd778b4590144034a167a2f"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.1+14"

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

[[FreeType2_jll]]
deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "cbd58c9deb1d304f5a245a0b7eb841a2560cfec6"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.1+5"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[IterationControl]]
deps = ["EarlyStopping", "InteractiveUtils"]
git-tree-sha1 = "f61d5d4d0e433b3fab03ca5a1bfa2d7dcbb8094c"
uuid = "b3c1a2ee-3fec-4384-bf48-272ea71de57c"
version = "0.4.0"

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

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

[[JLSO]]
deps = ["BSON", "CodecZlib", "FilePathsBase", "Memento", "Pkg", "Serialization"]
git-tree-sha1 = "e00feb9d56e9e8518e0d60eef4d1040b282771e2"
uuid = "9da8a3cd-07a3-59c0-a743-3fdc52c30d11"
version = "2.6.0"

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

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

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

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

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

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

[[LatinHypercubeSampling]]
deps = ["Random", "StableRNGs", "StatsBase", "Test"]
git-tree-sha1 = "42938ab65e9ed3c3029a8d2c58382ca75bdab243"
uuid = "a5e1c1ea-c99a-51d3-a14d-a9a37257b02d"
version = "1.8.0"

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

[[LearnBase]]
git-tree-sha1 = "a0d90569edd490b82fdc4dc078ea54a5a800d30a"
uuid = "7f8f8fb0-2700-5f03-b4bd-41f8cfc144b6"
version = "0.4.1"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[LossFunctions]]
deps = ["InteractiveUtils", "LearnBase", "Markdown", "RecipesBase", "StatsBase"]
git-tree-sha1 = "0f057f6ea90a84e73a8ef6eebb4dc7b5c330020f"
uuid = "30fc2ffe-d236-52d8-8643-a9d8f7c094a7"
version = "0.7.2"

[[MLJ]]
deps = ["CategoricalArrays", "ComputationalResources", "Distributed", "Distributions", "LinearAlgebra", "MLJBase", "MLJEnsembles", "MLJIteration", "MLJModels", "MLJOpenML", "MLJSerialization", "MLJTuning", "Pkg", "ProgressMeter", "Random", "ScientificTypes", "Statistics", "StatsBase", "Tables"]
git-tree-sha1 = "7cbd651e39fd3f3aa37e8a4d8beaccfa8d13b1cd"
uuid = "add582a8-e3ab-11e8-2d5e-e98b27df1bc7"
version = "0.16.7"

[[MLJBase]]
deps = ["CategoricalArrays", "ComputationalResources", "Dates", "DelimitedFiles", "Distributed", "Distributions", "InteractiveUtils", "InvertedIndices", "LinearAlgebra", "LossFunctions", "MLJModelInterface", "Missings", "OrderedCollections", "Parameters", "PrettyTables", "ProgressMeter", "Random", "ScientificTypes", "StatisticalTraits", "Statistics", "StatsBase", "Tables"]
git-tree-sha1 = "ad7fdd566e2639c1a189e0d1b2ef43085091c2c7"
uuid = "a7f614a8-145f-11e9-1d2a-a57a1082229d"
version = "0.18.15"

[[MLJClusteringInterface]]
deps = ["Clustering", "Distances", "MLJModelInterface"]
git-tree-sha1 = "f45ba59648f6093f733df1bb6bd9bbbc4d13408e"
uuid = "d354fa79-ed1c-40d4-88ef-b8c7bd1568af"
version = "0.1.4"

[[MLJDecisionTreeInterface]]
deps = ["DecisionTree", "MLJModelInterface", "Random"]
git-tree-sha1 = "e2a5e2f0fd72cae51d72a83e6c11167de96c7a4c"
uuid = "c6f25543-311c-4c74-83dc-3ea6d1015661"
version = "0.1.3"

[[MLJEnsembles]]
deps = ["CategoricalArrays", "ComputationalResources", "Distributed", "Distributions", "MLJBase", "MLJModelInterface", "ProgressMeter", "Random", "ScientificTypesBase", "StatsBase"]
git-tree-sha1 = "b9ce7bbc4bba927d52c26a3446ac2913777072c8"
uuid = "50ed68f4-41fd-4504-931a-ed422449fee0"
version = "0.1.1"

[[MLJIteration]]
deps = ["IterationControl", "MLJBase", "Random"]
git-tree-sha1 = "f927564f7e295b3205f37186191c82720a3d93a5"
uuid = "614be32b-d00c-4edb-bd02-1eb411ab5e55"
version = "0.3.1"

[[MLJModelInterface]]
deps = ["Random", "ScientificTypesBase", "StatisticalTraits"]
git-tree-sha1 = "54e0aa2c7e79f6f30a7b2f3e096af88de9966b7c"
uuid = "e80e1ace-859a-464e-9ed9-23947d8ae3ea"
version = "1.1.2"

[[MLJModels]]
deps = ["CategoricalArrays", "Dates", "Distances", "Distributions", "InteractiveUtils", "LinearAlgebra", "MLJBase", "MLJModelInterface", "OrderedCollections", "Parameters", "Pkg", "REPL", "Random", "Requires", "ScientificTypes", "Statistics", "StatsBase", "Tables"]
git-tree-sha1 = "a5dab276c8fe1ccd5c585ec1b876e143dbaf1f5c"
uuid = "d491faf4-2d78-11e9-2867-c94bc002c0b7"
version = "0.14.9"

[[MLJMultivariateStatsInterface]]
deps = ["Distances", "LinearAlgebra", "MLJModelInterface", "MultivariateStats", "StatsBase"]
git-tree-sha1 = "0cfc81ff677ea13ed72894992ee9e5f8ae4dbb9d"
uuid = "1b6a4a23-ba22-4f51-9698-8599985d3728"
version = "0.2.2"

[[MLJOpenML]]
deps = ["CSV", "HTTP", "JSON", "Markdown", "ScientificTypes"]
git-tree-sha1 = "a0d6e25ec042ab84505733a62a2b2894fbcf260c"
uuid = "cbea4545-8c96-4583-ad3a-44078d60d369"
version = "1.1.0"

[[MLJScikitLearnInterface]]
deps = ["MLJModelInterface", "PyCall", "ScikitLearn"]
git-tree-sha1 = "1a30a63d77c7dc858ae32e7450bd05ba1e1f85fd"
uuid = "5ae90465-5518-4432-b9d2-8a1def2f0cab"
version = "0.1.10"

[[MLJSerialization]]
deps = ["IterationControl", "JLSO", "MLJBase", "MLJModelInterface"]
git-tree-sha1 = "cd6285f95948fe1047b7d6fd346c172e247c1188"
uuid = "17bed46d-0ab5-4cd4-b792-a5c4b8547c6d"
version = "1.1.2"

[[MLJTuning]]
deps = ["ComputationalResources", "Distributed", "Distributions", "LatinHypercubeSampling", "MLJBase", "ProgressMeter", "Random", "RecipesBase"]
git-tree-sha1 = "1deadc54bf1577a46978d80fe2506d62fa8bf18f"
uuid = "03970b2e-30c4-11ea-3135-d1576263f10f"
version = "0.6.10"

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

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

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

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

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

[[Memento]]
deps = ["Dates", "Distributed", "JSON", "Serialization", "Sockets", "Syslogs", "Test", "TimeZones", "UUIDs"]
git-tree-sha1 = "19650888f97362a2ae6c84f0f5f6cda84c30ac38"
uuid = "f28f55f0-a522-5efc-85c2-fe41dfb9b2d9"
version = "1.2.0"

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

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

[[Mocking]]
deps = ["ExprTools"]
git-tree-sha1 = "748f6e1e4de814b101911e64cc12d83a6af66782"
uuid = "78c3b35d-d492-501b-9361-3d52fe80e533"
version = "0.7.2"

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

[[MultivariateStats]]
deps = ["Arpack", "LinearAlgebra", "SparseArrays", "Statistics", "StatsBase"]
git-tree-sha1 = "8d958ff1854b166003238fe191ec34b9d592860a"
uuid = "6f286f6a-111f-5878-ab1e-185364afe411"
version = "0.8.0"

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

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

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

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

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

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

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

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

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

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

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

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

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

[[PersistenceDiagramsBase]]
deps = ["Compat", "Tables"]
git-tree-sha1 = "ec6eecbfae1c740621b5d903a69ec10e30f3f4bc"
uuid = "b1ad91c1-539c-4ace-90bd-ea06abc420fa"
version = "0.1.1"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[RData]]
deps = ["CategoricalArrays", "CodecZlib", "DataFrames", "Dates", "FileIO", "Requires", "TimeZones", "Unicode"]
git-tree-sha1 = "19e47a495dfb7240eb44dc6971d660f7e4244a72"
uuid = "df47a6cb-8c03-5eed-afd8-b6050d6c41da"
version = "0.8.3"

[[RDatasets]]
deps = ["CSV", "CodecZlib", "DataFrames", "FileIO", "Printf", "RData", "Reexport"]
git-tree-sha1 = "06d4da8e540edb0314e88235b2e8f0429404fdb7"
uuid = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
version = "0.7.5"

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

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

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

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

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

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

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

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

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

[[ScientificTypes]]
deps = ["CategoricalArrays", "ColorTypes", "Dates", "PersistenceDiagramsBase", "PrettyTables", "ScientificTypesBase", "StatisticalTraits", "Tables"]
git-tree-sha1 = "345e33061ad7c49c6e860e42a04c62ecbea3eabf"
uuid = "321657f4-b219-11e9-178b-2701a2544e81"
version = "2.0.0"

[[ScientificTypesBase]]
git-tree-sha1 = "3f7ddb0cf0c3a4cff06d9df6f01135fa5442c99b"
uuid = "30f210dd-8aff-4c5f-94ba-8e64358c1161"
version = "1.0.0"

[[ScikitLearn]]
deps = ["Compat", "Conda", "DataFrames", "Distributed", "IterTools", "LinearAlgebra", "MacroTools", "Parameters", "Printf", "PyCall", "Random", "ScikitLearnBase", "SparseArrays", "StatsBase", "VersionParsing"]
git-tree-sha1 = "ccb822ff4222fcf6ff43bbdbd7b80332690f168e"
uuid = "3646fa90-6ef7-5e7e-9f22-8aca16db6324"
version = "0.6.4"

[[ScikitLearnBase]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "7877e55c1523a4b336b433da39c8e8c08d2f221f"
uuid = "6e75b9c4-186b-50bd-896f-2d2496a4843e"
version = "0.5.0"

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

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

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

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

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

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

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

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

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

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

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

[[StatisticalTraits]]
deps = ["ScientificTypesBase"]
git-tree-sha1 = "93f7326079b73910e5a81f8848e7a633f99a2946"
uuid = "64bff920-2084-43da-a3e6-9bb72801c0c9"
version = "2.0.1"

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

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

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

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

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

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

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

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

[[Syslogs]]
deps = ["Printf", "Sockets"]
git-tree-sha1 = "46badfcc7c6e74535cc7d833a91f4ac4f805f86d"
uuid = "cea106d9-e007-5e6c-ad93-58fe2094e9c4"
version = "0.3.0"

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

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

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

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

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

[[TimeZones]]
deps = ["Dates", "Future", "LazyArtifacts", "Mocking", "Pkg", "Printf", "RecipesBase", "Serialization", "Unicode"]
git-tree-sha1 = "81753f400872e5074768c9a77d4c44e70d409ef0"
uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53"
version = "1.5.6"

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

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

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

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

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

[[UrlDownload]]
deps = ["HTTP", "ProgressMeter"]
git-tree-sha1 = "05f86730c7a53c9da603bd506a4fc9ad0851171c"
uuid = "856ac37a-3032-4c1c-9122-f86d88358c8b"
version = "1.0.0"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

# ╔═╡ Cell order:
# ╟─ca2a2e0c-f6f1-11eb-12d4-5d81b9cb97c1
# ╠═85e74b35-5e6e-4e69-b7ad-50cedca5f4cf
# ╟─c418450d-0ace-4a13-9fbc-9c4dc1c153c3
# ╟─379fad8b-59b6-4e41-aa5f-d3ff7dbc4f26
# ╟─ae8acf9e-5b1b-4d69-af47-96a66b42189a
# ╟─2bb7c88d-6894-4c48-b1eb-ef297ec33fa3
# ╠═e85323e0-e991-4c15-b41f-59b81571e4c2
# ╟─3460d637-a598-4bd4-a169-a10ad9e220d1
# ╠═a7cb38fc-7522-4c25-a062-9c5daae14145
# ╟─7c9406b5-21a8-41d7-a777-e7ba90fb7a00
# ╠═2be4cb86-17b7-4f0f-b66b-380a02038d46
# ╟─981fc582-642e-43f1-bacc-340acd40f854
# ╠═abac24d2-765c-49aa-befe-291012e61b00
# ╟─3dedd727-c900-40c6-95ae-47a697891613
# ╠═274c3df4-713b-4643-b2ab-e002151c3164
# ╠═752fecef-1da9-4943-94f9-d7af84bdf472
# ╟─cb9ed21f-996f-4104-b58e-8fe439fbeb06
# ╠═8b5e4c86-6083-4977-bb35-0e993d63d7d5
# ╟─be737177-8be8-4f0a-abfa-97aa286b1654
# ╠═32feb81d-8552-4415-b22f-bb5756581292
# ╟─431ac7b3-96f3-41c0-a102-edbaf000ce00
# ╠═e46948bc-7bd8-4904-a06e-3d5936c300be
# ╟─5763d717-d695-40a1-8d14-f3ed8a04fbac
# ╟─b65357a5-5af6-4cec-a31c-7ded59155a44
# ╟─046dd48c-c757-4cde-8483-8f9f02e1217e
# ╠═f23080a2-2303-414c-acf9-b642a5e7121f
# ╟─7237e74b-f35d-486e-a769-2f93bbad566d
# ╠═63ae7fa7-d2aa-48b1-872e-68e035b77422
# ╠═130769ec-7515-4149-b925-7ef07a6168b8
# ╟─9485c2f0-4378-4a1f-90cf-2b992e3714f6
# ╟─79cfb0ed-7431-4dc8-ad02-62ca35e4f885
# ╠═a19df644-cfa2-46cb-875e-fd4a94c00134
# ╠═ada8f32b-aab1-4687-9ee1-b1a27ec8ca5d
# ╠═c70c8298-c908-4ef8-a5da-79967d0d8ccb
# ╠═54b04b9f-731c-4642-a0f8-c1b6df24b6ba
# ╟─bea29f95-25ea-4fb9-8f86-a2860c3f1120
# ╠═7bd93fe6-f392-45eb-95ff-6bacb7efc974
# ╠═7d961743-32f8-4ad0-896d-74e1484d8a9b
# ╠═a2bc7993-8570-4863-8dfd-baa107424198
# ╠═7e54fca2-fadb-403c-b4b1-29aead7a2cb8
# ╠═1bae87f9-2ec3-413c-a445-ddebdc52ea44
# ╠═f4aafce6-326e-4c7a-bd90-45669f0494ba
# ╠═0224fea6-3c9d-46cb-b936-9d986e53cd1d
# ╠═c091be98-c321-48e0-9b13-05de97c12cd9
# ╟─0798b789-50c1-4080-8386-1a6429b32f7d
# ╟─b53de955-1b1d-4be5-9bd7-9ce9f84b83e5
# ╠═50defd99-5eb4-444a-9abb-5003764563e6
# ╠═098588b6-6c67-4656-b520-00a53f39237f
# ╠═eb79421f-624c-418a-8a5e-59b4e0c23bd0
# ╠═af754478-fa99-414b-a48b-389af4fff2d3
# ╠═104558aa-b7a3-4008-8f68-c7e7f9241570
# ╠═84ed9b09-40a6-45e8-927c-c98217636f6a
# ╠═84ce479d-acd0-4ac0-9dd1-4670444165d8
# ╠═5625705f-d6ca-4cb2-85b1-4d7cc5efe167
# ╠═9a3d69b4-7342-4426-861a-56f9266a0706
# ╠═aacbb24b-1056-48d2-ae51-b02718c6bdf7
# ╠═effa8648-8ca7-42ef-bab6-17f52a417ffd
# ╠═d7e4f63f-f950-4bbe-9248-ba21145436e7
# ╠═225d1f19-7354-4d8c-ad8d-80498bdea59b
# ╠═345decc0-554c-431e-9e51-86160bbb296a
# ╠═ba19bae9-4cd0-4cf8-8953-466488e22b47
# ╠═d6bd99e2-57ab-491e-98ee-3f25bad44a66
# ╠═9ca9182b-84a9-4a4e-8c66-fa54ac45ce17
# ╠═59db05e0-a2f6-4666-82e7-7508f2563b93
# ╠═146c09f4-f4c6-41ab-a565-03b2d6825129
# ╠═c4adf149-93b9-4a4f-8d16-790ea44088a4
# ╠═e6d330da-98ba-4689-97b9-119b5a5230f9
# ╠═f4b660c3-367b-4207-9083-0d0fdcd2988a
# ╠═97d665ec-0e30-4f4c-8480-2ef070e8350f
# ╠═15a264a7-78ee-4597-bfc5-79bc6890fb44
# ╠═e664cc85-29f9-4c27-b128-6fbbf85dbb35
# ╠═a3052245-5f44-4166-922b-18df99c0a49d
# ╠═19d8300c-97d0-4a9c-915d-83661c393dea
# ╠═e6112bb6-184e-428c-b586-752403998533
# ╠═e1c234e9-7dd2-4079-9bd6-83edc3acf9f8
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

Curso Julia/Github - Material/src/CienciaDeDatos/AprendizajeAutomatizado.jl


using TravelingSalesmanExact, GLPK, Test
set_default_optimizer!(GLPK.Optimizer)

function test_valid_tour(tour, L)
    @test length(tour) == L
    @test isperm(tour)
    @test tour isa Vector{Int}
end

function tour_cost(tour, cost::AbstractMatrix)
    n = length(tour)
    inc(a) = a == n ? one(a) : a + 1
    s = zero(eltype(cost))
    for (index, city) in enumerate(tour)
        nextcity = tour[inc(index)]
        s += cost[city, nextcity]
    end
    return s
end

function tour_cost(
    tour,
    cities::AbstractVector;
    distance = TravelingSalesmanExact.euclidean_distance,
)
    n = length(cities)
    cost = [distance(cities[i], cities[j]) for i = 1:n, j = 1:n]
    return tour_cost(tour, cost)
end

function test_tour(input, opt = TravelingSalesmanExact.get_default_optimizer(); kwargs...)
    t, c = get_optimal_tour(input, opt; kwargs...)
    test_valid_tour(t, size(input, 1))
    if :distance in keys(kwargs)
        @test c ≈ tour_cost(t, input; distance = kwargs[:distance])
    else
        @test c ≈ tour_cost(t, input)
    end
    return t, c
end

@testset "Small random asymmetric" begin
    # chosen via rand(5,5)
    cost = 10 *
           [
        0.474886 0.350983 0.262651 0.138455 0.904042;
        0.683586 0.922968 0.278874 0.408406 0.0224372;
        0.513651 0.778167 0.140392 0.981211 0.891122;
        0.20529 0.976361 0.784706 0.98504 0.385203;
        0.489131 0.783738 0.538762 0.998821 0.0324331
    ]
    t1, c1 = test_tour(cost; verbose = true)
    t2, c2 = test_tour(cost; verbose = false)
    t3, c3 = test_tour(cost; verbose = false, lazy_constraints = true)
    @test c1 ≈ c2
    @test c2 ≈ c3

    # incorrect `symmetric` should give the wrong answers
    t4, c4 = get_optimal_tour(cost; verbose = false, symmetric = true)
    test_valid_tour(t4, 5)
    @test !(c2 ≈ c4)
    @test !(c4 ≈ tour_cost(t4, cost))
end

@testset "Medium random asymmetric" begin
    cost = 10 * rand(15, 15)
    t1, c1 = test_tour(cost; verbose = false)
    t2, c2 = test_tour(cost; verbose = true, lazy_constraints = true)
    @test c1 ≈ c2
end

@testset "Small random symmetric" begin
    cost = 10 *
           [
        0.474886 0.350983 0.262651 0.138455 0.904042;
        0.683586 0.922968 0.278874 0.408406 0.0224372;
        0.513651 0.778167 0.140392 0.981211 0.891122;
        0.20529 0.976361 0.784706 0.98504 0.385203;
        0.489131 0.783738 0.538762 0.998821 0.0324331
    ]
    cost_sym = cost + transpose(cost)
    t4, c4 = test_tour(cost_sym; verbose = false)
    t5, c5 = test_tour(cost_sym; symmetric = true, verbose = false)
    t6, c6 = test_tour(cost_sym; symmetric = false, verbose = false)
    t7, c7 = test_tour(cost_sym; symmetric = false, verbose = true, lazy_constraints = true)
    @test c4 ≈ c5
    @test c5 ≈ c6
    @test c6 ≈ c7
end

@testset "Small random cities" begin
    # cities = [ 100*rand(2) for _ in 1:5]
    cities = Array{Float64,1}[
        [48.8885, 41.0517],
        [35.6635, 12.1844],
        [95.6122, 15.9847],
        [67.5772, 9.54407],
        [16.6325, 51.9001],
    ]
    t7, c7 = test_tour(cities; verbose = true)
    t8, c8 = @inferred test_tour(cities; verbose = false, symmetric = false)
    cost = [TravelingSalesmanExact.euclidean_distance(c1, c2) for c1 in cities, c2 in cities]
    t9, c9 = test_tour(cost; verbose = false, symmetric = false)
    t10, c10 = test_tour(cost; verbose = false, symmetric = true)
    @test c7 ≈ c8
    @test c8 ≈ c9
    @test c9 ≈ c10
    @test c8 isa Float64
end

@testset "Medium random cities" begin
    # cities = [ 100*rand(2) for _ in 1:15]
    cities = Array{Float64,1}[
        [53.80996646037832, 19.19022341362766],
        [66.31428678667224, 61.80858818555463],
        [36.353148448445616, 41.255152847278474],
        [90.27061139767463, 6.978822544781482],
        [53.764677734646504, 29.81193167526588],
        [99.44803233011115, 66.55866205554817],
        [38.928236331570986, 18.22266760966855],
        [21.194033394576728, 56.14389699364914],
        [6.430489908372161, 92.08608470530129],
        [67.01950679275805, 53.82196541323463],
        [57.04078593130859, 88.74875672836768],
        [40.91801899608445, 23.47673907020007],
        [8.889246634653713, 44.183494522157886],
        [82.70468776751652, 74.73476674725042],
        [8.637366704185245, 87.23819026270408]
    ]
    t7, c7 = test_tour(cities; verbose = true, lazy_constraints = true)
    t8, c8 = @inferred test_tour(cities; verbose = false, symmetric = false)
    cost = [TravelingSalesmanExact.euclidean_distance(c1, c2) for c1 in cities, c2 in cities]
    t9, c9 = test_tour(cost; verbose = false, symmetric = false)
    t10, c10 = test_tour(cost; verbose = false, symmetric = true)
    @test c7 ≈ c8
    @test c8 ≈ c9
    @test c9 ≈ c10
    @test c8 isa Float64
end

@testset "Exceptions" begin
    cost = rand(5, 4)
    @test_throws ArgumentError test_tour(cost)

    cost = rand(5, 5)
    TravelingSalesmanExact.reset_default_optimizer!()
    @test_throws ArgumentError test_tour(cost)
    set_default_optimizer!(GLPK.Optimizer)
end

@testset "att48.tsp" begin
    cities = simple_parse_tsp(joinpath(@__DIR__, "..", "data", "att48.tsp"))

    @test cities == TravelingSalesmanExact.get_ATT48_cities()

    sym_tour, sym_cost = test_tour(
        cities;
        distance = TravelingSalesmanExact.ATT,
        verbose = true,
    )
    @test sym_cost ≈ 10628

    asym_tour, asym_cost = test_tour(
        cities;
        distance = TravelingSalesmanExact.ATT,
        symmetric = false,
    )
    @test asym_cost ≈ 10628
end

@testset "Time Windows" begin
    cost = zeros(4, 4)
    cost[1,2] = 1
    cost[2,1] = 0
    cost[1,4] = -1

    times = ones(4, 4)
    tw = [
        0 4
        0 1
        0 3
        0 2
    ]
    route, objective = get_optimal_tour(cost, times, tw)
    @test objective ≈ 1
    start = findfirst(route .== 1)
    route = circshift(route, 1-start)
    @test route == [1,2,4,3]

    tw[2,:] .= [0,2]
    route, objective = get_optimal_tour(cost, times, tw)
    @test objective ≈ -1
    times = [
        0 1 0 0
        10 0 10 10
        10 10 0 10
        10 10 10 0
    ]
    route, objective = get_optimal_tour(times, tw)
    @test objective ≈ Inf
    tw = [
        0 100
        0 1
        0 100
        0 100
    ]
    route, objective = get_optimal_tour(times, tw)
    @test objective ≈ 31
end

@testset "Dropped" begin
    cost = ones(10, 10)
    penalties = Dict(
        1 => 3,
        3 => 0,
    )
    route, objective = get_optimal_tour(cost, penalties)
    @test length(route) == 9
    @test objective ≈ 9

    times = [
        0 1 0 0
        10 0 10 10
        10 10 0 10
        10 10 10 0
    ]
    tw = [
        0 100
        0 1
        0 100
        0 100
    ]
    penalties = Dict(2 => 5)
    route, objective = get_optimal_tour(times, tw, penalties)
    @test objective ≈ 25
end


# ---
# title: 1521. Find a Value of a Mysterious Function Closest to Target
# id: problem1521
# author: Tian Jun
# date: 2020-10-31
# difficulty: Hard
# categories: Binary Search, Bit Manipulation, Segment Tree
# link: <https://leetcode.com/problems/find-a-value-of-a-mysterious-function-closest-to-target/description/>
# hidden: true
# ---
#
# ![](https://assets.leetcode.com/uploads/2020/07/09/change.png)
#
# Winston was given the above mysterious function `func`. He has an integer
# array `arr` and an integer `target` and he wants to find the values `l` and
# `r` that make the value `|func(arr, l, r) - target|` minimum possible.
#
# Return _the minimum possible value_ of `|func(arr, l, r) - target|`.
#
# Notice that `func` should be called with the values `l` and `r` where `0 <= l,
# r < arr.length`.
#
#
#
# **Example 1:**
#
#
#
#     Input: arr = [9,12,3,7,15], target = 5
#     Output: 2
#     Explanation: Calling func with all the pairs of [l,r] = [[0,0],[1,1],[2,2],[3,3],[4,4],[0,1],[1,2],[2,3],[3,4],[0,2],[1,3],[2,4],[0,3],[1,4],[0,4]], Winston got the following results [9,12,3,7,15,8,0,3,7,0,0,3,0,0,0]. The value closest to 5 is 7 and 3, thus the minimum difference is 2.
#
#
# **Example 2:**
#
#
#
#     Input: arr = [1000000,1000000,1000000], target = 1
#     Output: 999999
#     Explanation: Winston called the func with all possible values of [l,r] and he always got 1000000, thus the min difference is 999999.
#
#
# **Example 3:**
#
#
#
#     Input: arr = [1,2,4,8,16], target = 0
#     Output: 0
#
#
#
#
# **Constraints:**
#
#   * `1 <= arr.length <= 10^5`
#   * `1 <= arr[i] <= 10^6`
#   * `0 <= target <= 10^7`
#
#
## @lc code=start
using LeetCode

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


export bsizeof, bdistance, bit_length, onehot, log2i, hypercubic, log2dim1, indices_with
# NOTE: all binary specified operations begin with b

"""
    bsizeof(::Type)

Returns the size of given type in number of binary digits.
"""
bsizeof(::Type{T}) where T = sizeof(T) << 3
bsizeof(::T) where T = bsizeof(T)

"""
    bdistance(i::Integer, j::Integer) -> Int

Return number of different bits.
"""
bdistance(i::Ti, j::Ti) where Ti<:Integer = count_ones(i ⊻ j)

"""
    onehot([T=Float64], nbits, x::Integer; nbatch::Int])

Create an onehot vector in type `Vector{T}` or a batch of onehot vector in type `Matrix{T}`,
where index `x + 1` is one.
"""
function onehot(::Type{T}, nbits::Int, x::Integer) where T
    v = zeros(T, 1 << nbits)
    v[x + 1] = 1
    return v
end

onehot(nbits::Int, x::Integer) = onehot(Float64, nbits, x)

function onehot(::Type{T}, nbits::Int, x::Integer, nbatch::Int) where T
    v = zeros(T, 1 << nbits, nbatch)
    v[x + 1, :] .= 1
    return v
end

onehot(nbits::Int, x::Integer, nbatch::Int) = onehot(Float64, nbits, x, nbatch)

"""
    unsafe_sub(a::UnitRange, b::NTuple{N}) -> NTuple{N}

Returns result in type `Tuple` of `a .- b`. This will not check the length of `a` and `b`, use
at your own risk.
"""
@generated function unsafe_sub(a::UnitRange{T}, b::NTuple{N, T}) where {N, T}
    ex = Expr(:tuple)
    for k in 1:N
        push!(ex.args, :(a.start + $(k-1) - b[$k]))
    end
    return ex
end

"""
    unsafe_sub(a::UnitRange{T}, b::Vector{T}) where T

Returns `a .- b`, fallback version when b is a `Vector`.
"""
unsafe_sub(a::UnitRange{T}, b::Vector{T}) where T = a .- b

"""
    bit_length(x::Integer) -> Int

Return the number of bits required to represent input integer x.
"""
bit_length(x::Integer)  =  sizeof(x)*8 - leading_zeros(x)

"""
    log2i(x::Integer) -> Integer

Return log2(x), this integer version of `log2` is fast but only valid for number equal to 2^n.
"""
function log2i end

for N in [8, 16, 32, 64, 128]
    T = Symbol(:Int, N)
    UT = Symbol(:UInt, N)
    @eval begin
        log2i(x::$T) = !signbit(x) ? ($(N - 1) - leading_zeros(x)) : throw(ErrorException("nonnegative expected ($x)"))
        log2i(x::$UT) = $(N - 1) - leading_zeros(x)
    end
end

"""
    log2dim1(X)

Returns the `log2` of the first dimension's size.
"""
log2dim1(X) = log2i(size(X, 1))

"""
    hypercubic(A::Array) -> Array

get the hypercubic representation for an array.
"""
hypercubic(A::Array) = reshape(A, fill(2, size(A) |> prod |> log2i)...)

"""
    indices_with(n::Int, locs::Vector{Int}, vals::Vector{Int}) -> Vector{Int}

Return indices with specific positions `locs` with value `vals` in a hilbert space of `n` qubits.
"""
function indices_with(n::Int, locs::Vector{Int}, vals::Vector{Int})
    mask = bmask(locs)
    onemask = bmask(locs[vals.!=0])
    return filter(x->ismatch(x, mask, onemask), basis(n))
end


# Cross validation

## cross validation generators

abstract CrossValGenerator

# K-fold

immutable Kfold <: CrossValGenerator
    permseq::Vector{Int}
    k::Int
    coeff::Float64

    function Kfold(n::Int, k::Int)
        2 <= k <= n || error("The value of k must be in [2, length(a)].")
        new(randperm(n), k, n / k)
    end
end

length(c::Kfold) = c.k

immutable KfoldState
    i::Int      # the i-th of the subset
    s::Int      # starting index
    e::Int      # ending index
end

start(c::Kfold) = KfoldState(1, 1, @compat(round(Integer,c.coeff)))
next(c::Kfold, s::KfoldState) =
    (i = s.i+1; (setdiff(1:length(c.permseq), c.permseq[s.s:s.e]), KfoldState(i, s.e+1, @compat(round(Integer,c.coeff * i)))))
done(c::Kfold, s::KfoldState) = (s.i > c.k)

# Stratified K-fold

immutable StratifiedKfold <: CrossValGenerator
    n::Int                         #Total number of observations
    permseqs::Vector{Vector{Int}}  #Vectors of vectors of indexes for each stratum
    k::Int                         #Number of splits
    coeffs::Vector{Float64}        #About how many observations per strata are in a val set
    function StratifiedKfold(strata, k)
        2 <= k <= length(strata) || error("The value of k must be in [2, length(strata)].")
        strata_labels, permseqs = unique_inverse(strata)
        map(shuffle!, permseqs)
        coeffs = Float64[]
        for (stratum, permseq) in zip(strata_labels, permseqs)
            k <= length(permseq) || error("k is greater than the length of stratum $stratum")
            push!(coeffs, length(permseq) / k)
        end
        new(length(strata), permseqs, k, coeffs)
    end
end

length(c::StratifiedKfold) = c.k

start(c::StratifiedKfold) = 1
function next(c::StratifiedKfold, s::Int)
    r = Int[]
    for (permseq, coeff) in zip(c.permseqs, c.coeffs)
        a, b = @compat(round(Integer, [s-1, s] .* coeff))
        append!(r, view(permseq, a+1:b))
    end
    setdiff(1:c.n, r), s+1
end
done(c::StratifiedKfold, s::Int) = (s > c.k)

# LOOCV (Leave-one-out cross-validation)

function leave_one_out(n::Int, i::Int)
    @assert 1 <= i <= n
    x = Array(Int, n-1)
    for j = 1:i-1
        x[j] = j
    end
    for j = i+1:n
        x[j-1] = j
    end
    return x
end

immutable LOOCV <: CrossValGenerator
    n::Int
end

length(c::LOOCV) = c.n

start(c::LOOCV) = 1
next(c::LOOCV, s::Int) = (leave_one_out(c.n, s), s+1)
done(c::LOOCV, s::Int) = (s > c.n)

# Repeated random sub-sampling

immutable RandomSub <: CrossValGenerator
    n::Int    # total length
    sn::Int   # length of each subset
    k::Int    # number of subsets
end

length(c::RandomSub) = c.k

start(c::RandomSub) = 1
next(c::RandomSub, s::Int) = (sort!(sample(1:c.n, c.sn; replace=false)), s+1)
done(c::RandomSub, s::Int) = (s > c.k)

# Stratified repeated random sub-sampling

immutable StratifiedRandomSub <: CrossValGenerator
    idxs::Vector{Vector{Int}}    # total length
    sn::Int                      # length of subset
    sns::Vector{Int}             # num from each stratum for each subset
    k::Int                       # number of subsets
    function StratifiedRandomSub(strata, sn, k)
        n = length(strata)
        strata_labels, idxs = unique_inverse(strata)
        sn >= length(strata_labels) || error("sn is too small for all strata to be represented")
        lengths_ord = sortperm(map(length, idxs))
        sns = zeros(Int, n)
        remaining_n = n   # total in the strata we haven't seen yet
        remaining_sn = sn # total room in the subset that hasn't been "assinged" to a stratum yet
        #loop through strata from smallest to largest, making sure there is at least one idx
        #from each strata in each subset:
        for stratum_num in lengths_ord
            stratum_n = length(idxs[stratum_num])
            remaining_proportion = remaining_sn/remaining_n
            stratum_sn = max(@compat(round(Integer, remaining_proportion*stratum_n)), 1)
            remaining_n -= stratum_n
            remaining_sn -= stratum_sn
            sns[stratum_num] = stratum_sn
        end
        #@assert mapreduce(sum, +, sns) == sn
        new(idxs, sn, sns, k)
    end
end

length(c::StratifiedRandomSub) = c.k

start(c::StratifiedRandomSub) = 1
function next(c::StratifiedRandomSub, s::Int)
    idxs = Array(Int, 0)
    sizehint!(idxs, c.sn)
    for (stratum_sn, stratum_idxs) in zip(c.sns, c.idxs)
        append!(idxs, sample(stratum_idxs, stratum_sn, replace=false))
    end
    (sort!(idxs), s+1)
end
done(c::StratifiedRandomSub, s::Int) = (s > c.k)

## Cross validation algorithm
#
#  estfun: model estimation function
#
#          model = estfun(train_inds)
#
#          it takes as input the indices of
#          the samples for training, and returns
#          a trained model.
#
#  evalfun: model evaluation function
#
#           v = evalfun(model, test_inds)
#
#           it applies a trained model to a subset
#           of samples whose indices are given in
#           test_inds, and returns an overall score.
#
#  n:   the total number of samples
#
#  gen: an iterable object (e.g. an instance of CrossValGenerator)
#       where each element is a vector of indices
#
#  This function returns a tuple a vector of validation scores
#
function cross_validate(estfun::Function, evalfun::Function, n::Int, gen)
    best_model = nothing
    best_score = NaN
    best_inds = Int[]
    first = true

    scores = Float64[]
    for (i, train_inds) in enumerate(gen)
        test_inds = setdiff(1:n, train_inds)
        model = estfun(train_inds)
        score = evalfun(model, test_inds)
        push!(scores, score)
    end
    return scores
end

cross_validate(estfun::Function, evalfun::Function, n::Integer, gen) =
    cross_validate(estfun, evalfun, n, gen, Forward)


function load( filename )

    trans = Dict( "."=>0, "L"=>1,"#"=>2)

    open(filename) do f

        data = []
        for line in readlines(f)
           line = replace(line, "."=> "0" )
           line = replace(line, "L"=> "1" )
           line = replace(line, "#"=> "2" )
           push!(data, parse.(Int, collect(line)))
        end
        data = vcat(data'...)
        m, n = size(data)
        seats = zeros(Int, m+2, n+2)
        seats[2:m+1,2:n+1] .= data
        return seats

    end

end

function adjacents( i, j, seats )

    adjacents = [seats[i+1,j-1],
                 seats[i+1,j  ],
                 seats[i+1,j+1],
                 seats[i  ,j-1],
                 seats[i  ,j+1],
                 seats[i-1,j-1],
                 seats[i-1,j  ],
                 seats[i-1,j+1]]

    adjacents
end

state = Dict( 0=>'.', 1=>'L', 2=>'#')

function plot( seats )

    m, n = size(seats)
    for i in 2:size(seats)[1]-1
        for j in 2:size(seats)[2]-1
            print(state[seats[i,j]])
        end
        println()
     end
     println()
end

function round1!( seats )

    m, n = size(seats)
    old = copy(seats)
    state = true
    for i in 2:m-1, j in 2:n-1
        if old[i,j] == 1 && all(adjacents(i,j, old) .< 2)
            seats[i,j] = 2
            state = false
        end
        if old[i,j] == 2 && count(adjacents(i,j, old) .== 2) >= 4
            seats[i,j] = 1
            state = false
        end
    end
    state
end

function get_seat( seats, row, col)

    for (i,j) in zip(row, col)
        seats[i,j] == 1 && return false
        seats[i,j] == 2 && return true
    end
    return false
end

function get_seat(seats)
    for s in seats
        s == 1 && return false
        s == 2 && return true
    end
    false
end

function visible_seats( k, l, seats)

   m,n = size(seats)

   res = [
   get_seat(seats[k-1:-1:1,l]),
   get_seat(seats[k+1:1:m,l]),
   get_seat(seats[k,l-1:-1:1]),
   get_seat(seats[k,l+1:n]),
   get_seat(seats, k-1:-1:1+k-min(k,l), l-1:-1:1+l-min(k,l)),
   get_seat(seats, k-1:-1:k-min(k-1,n-l), l+1:1:l+min(k-1,n-l)),
   get_seat(seats, k+1:1:min(m-k,n-l)+k, l+1:1:min(m-k,n-l)+l),
   get_seat(seats, k+1:1:k+min(m-k,l-1), l-1:-1:l-min(m-k,l-1))]

   res
end

function round2!( seats )

    m, n = size(seats)
    old = copy(seats)
    state = true
    for i in 2:m-1, j in 2:n-1
        if old[i,j] == 1 && all(.!(visible_seats(i,j, old)))
            seats[i,j] = 2
            state = false
        end
        if old[i,j] == 2 && count(visible_seats(i,j, old)) >= 5
            seats[i,j] = 1
            state = false
        end
    end
    state
end

seats = load("input11.txt")
while true
   if round1!( seats)
       println(count(seats .== 2))
       break
  end
end

seats = load("input11.txt")
while true
   if round2!( seats)
       println(count(seats .== 2))
       break
  end
end


export @default_compute_rf_inner_solver
# Try to automatically determine an appropriate scalar compute_rf solver.
macro default_compute_rf_inner_solver(nep)
    return (nep isa PEP) ? PolyeigInnerSolver() : ScalarNewtonInnerSolver();
end

"""
    struct ScalarNewtonInnerSolver <: InnerSolver
    function ScalarNewtonInnerSolver(;tol=eps()*100,maxit=80,bad_solution_allowed=true)

This type can be used with  `compute_rf`. It solves the scalar nonlinear problem
using a Rayleig functional. In contrast to the `NewtonInnerSolver`, this
function does not require an SPMF (or precomputations associated with SPMFs).
"""
struct ScalarNewtonInnerSolver <: InnerSolver
    tol::Float64
    maxit::Int
    bad_solution_allowed::Bool
    function ScalarNewtonInnerSolver(;tol=eps()*100,maxit=80,bad_solution_allowed=true)
        return new(tol,maxit,bad_solution_allowed);
    end
end

function compute_rf(T0::Type{T}, nep::NEP, x, inner_solver::ScalarNewtonInnerSolver;
                        y=x, target=zero(T), λ0=target,
                        kwargs...) where T
    λ_iter = T(λ0);
    Δλ = T(Inf)
    count = 0
    while (abs(Δλ)>inner_solver.tol) & (count<inner_solver.maxit)
        count = count+1
        # compute function value and derivative
        z1 = compute_Mlincomb(nep, λ_iter, reshape(x,size(nep,1),1))
        z2 = compute_Mlincomb(nep, λ_iter, reshape(x,size(nep,1),1),[T(1)],1)

        Δλ = -dot(y,z1)/dot(y,z2);
        λ_iter += Δλ
    end

    if ((count==inner_solver.maxit) && (! (inner_solver.bad_solution_allowed )))
        throw(NoConvergenceException());
    end

    # Return type is a vector of correct type
    λ_star::Array{T,1} = Array{T,1}(undef, 1)
    if (T <: Real) && (typeof(λ_iter) != T) && (imag(λ_iter)/real(λ_iter) < inner_solver.tol)
        # Looking for a real quantity (AND) iterate is not real (AND) complex part is negligible
        λ_star[1] = real(λ_iter) # Truncate to real
    else
        λ_star[1] = λ_iter
    end
    return λ_star
end

"""
    compute_rf(eltype::Type,nep::NEP,x,inner_solver::InnerSolver;
               y=x, target=zero(T), λ0=target,TOL=eps(real(T))*1e3,max_iter=10)

Computes the Rayleigh functional of the `nep`, i.e., computes a vector
``Λ`` of values ``λ``
such that ``y^TM(λ)x=0``, using the procedure specified in `inner_solver`.
The default behaviour consists of a scalar valued
Newton-iteration, and the returned vector has only one element.

The given eltype<:Number is the type of the returned vector.

# Example

This uses `iar` to solve the (scalar) nonlinear problem.

```julia-repl
julia> nep=nep_gallery("dep0");
julia> x=ones(size(nep,1));
julia> s=compute_rf(ComplexF64,nep,x,IARInnerSolver())[1] # Take just first element
-1.186623627962043 - 1.5085094961223182im
julia> x'*compute_Mlincomb(nep,s,x)
-8.881784197001252e-16 + 1.0880185641326534e-14im
```
"""
    function compute_rf(T0::Type{T}, nep::NEP, x, inner_solver::InnerSolver;
                        y=x, target=zero(T), λ0=target,
                        TOL=eps(real(T))*1e3, max_iter=30,kwargs...) where T

        pnep=create_proj_NEP(nep);
        n=size(nep,1);
        set_projectmatrices!(pnep,reshape(y,n,1),reshape(x,n,1));

        local λv
        try
            (λv,xv)=inner_solve(inner_solver,T0,pnep,σ=target,λv=[λ0]);
        catch e
            # Even return the approximation upon failure
            if (e isa NoConvergenceException)
                λv=e.λ
            else
                rethrow(e)
            end
        end
        if (λv isa Vector)
            return λv
        else
            return [λv];
        end
    end

function compute_rf(::Type{T},nep::NEP,x, inner_solver::PolyeigInnerSolver; y=x, target=zero(T), λ0=target,
                    TOL=eps(real(T))*1e3,max_iter=10) where T

    @show λ0
    a=zeros(T,size(nep.A,1))
    for i=1:size(nep.A,1)
        a[i]=dot(y,nep.A[i]*x);
    end
    m=size(nep.A,1);
    # Build a companion matrix (maybe bigfloat)
    A=zeros(T,m-1,m-1);
    for k=1:m-1
        if (k<m-1)
            A[k,k+1]=1;
        end
        A[end,k]=-a[k]/a[end]
    end
    pp=eigvals(A);
    if (T <: Real) # If we specify real arithmetic, return real eigvals
        pp=real(pp);
    end

    II=sortperm(abs.(pp .- target))
    return pp[II];
end

# Overload a version of eigvals(::Matrix{BigFloat}) for compute_rf
import LinearAlgebra.eigvals
function eigvals(A::Union{Matrix{BigFloat},Matrix{Complex{BigFloat}}})
    T=eltype(A);
    Tfloat= (T <: Complex) ? (ComplexF64) : (Float64)
    Afloat=Matrix{Tfloat}(A);
    λv,X=eigen(Afloat);
    local λv_bigfloat=Vector{Complex{BigFloat}}(λv);
    # Some Rayleigh quotient iteration steps in bigfloat to improve accuracy:
    for j=1:size(λv,1)
        local s=λv_bigfloat[j];
        z=Vector{Complex{BigFloat}}(X[:,j])
        for f=1:3
            z=(A-s*I)\z; normalize!(z);
            s=z'*A*z;
        end
        λv_bigfloat[j]=s
    end
    if (maximum(abs.((λv_bigfloat-λv)./λv_bigfloat)) > eps()*100)
        @warn("Correction iteration of eigvals for bigfloat, made the eigenvalues move considerably")
    end

    return λv_bigfloat
end


# # Chapter 2

# ## Timing Julia
# `@time` is the simplest way to measure execution times
@time sqrt.(rand(1000));

# `@time` can also be used for any expression
s=0
@time for i=1:1000
   global s=s+sqrt(i)
end

# `@timev` provides additoinal information
@timev sqrt.(rand(1000));

# `@time` returns the value of the expression
sum(@time sqrt.(rand(1000)))

# `@elapsed` returns the elapsed execution time as a value ...
@elapsed sqrt.(rand(1000))

# ... and hence can be used in automated tests
using Test
@test @elapsed(sqrt.(rand(1000))) <= 10e-4

# ## Profiling

# Load the `Profile` stdlib module
using Profile

# We profile a simple function that creates a random matrix, and then
# computes the mean of the square of each row.
using Statistics
function randmsq()
    x = rand(10000, 1000)
    y = mean(x.^2, dims = 1)
    return y
end

# Run the function once before profiling, to compile it
randmsq()

# Execute the function while profiling it
@profile randmsq()

# `print` displays a tree view of the execution traces
Profile.print()

# Clear saved profiles
Profile.clear()

# Use the `init` function to configure the profiler
Profile.init(delay=.01)

# Run the profile using new setting
@profile randmsq()

# Profileview can be used to visualise the
# `] add ProfileView` to add the package

using Pkg
Pkg.add("ProfileView")

using ProfileView
ProfileView.view()
ProfileView.svgwrite("profile_results.svg")

# ## Statistically significant benchmarking
# `]add BenchmarkTools` to add the package
Pkg.add("BenchmarkTools")
using BenchmarkTools
@benchmark sqrt.(rand(1000))

@btime mean(rand(1000));


struct Numerics
    T::Float64
    dt::Float64
    S::Float64
    ds::Float64
end

struct Simulation
    equation::String #("GPE", "NPSE")
    potential::String #("barrier", "ellipse")
end

struct Potential
    type::String
    width::Float64
    position::Float64
    energy::Float64
    ϵ::Float64
    a::Float64
end

struct Apparatus
    m::Float64 # kg ω
    as::Float64 # m
    ω_perp::Float64 # rad/s
    N::Int64
    γ::Float64
    ω_z::Float64
end

struct InitialState
    type::String
    width::Float64
    v0::Float64
    x0::Float64
end

struct Coefficients
    α::ComplexF64
    β::Function
    γ::Function
    initial::Function
end

function potential(sim::Simulation, app::Apparatus, pot::Potential, s::Float64)
    hbar = 6.62607015e-34 / (2 * pi)
    l_perp = sqrt(hbar / (app.m * app.ω_perp))
    l_z = sqrt(hbar / (app.m * app.ω_z))
    if pot.type == "barrier"
        value = pot.energy * exp(-(s - pot.position)^2 / (2 * (pot.width))^2)
    elseif pot.type == "ellipse"
        target_error = 0.001 * pot.a
        lower_ϕ = -pi
        upper_ϕ = 3 * pi
        let error
            let midpoint
                error = target_error + 1
                while error > target_error
                    midpoint = (lower_ϕ + upper_ϕ) / 2
                    if s - pot.a * E(midpoint, pot.ϵ) > 0
                        lower_ϕ = midpoint
                    else
                        upper_ϕ = midpoint
                    end
                    error = abs(s - pot.a * E(midpoint, pot.ϵ))
                end
                value = -hbar^2 * (1 / pot.a * (sqrt(1 - pot.ϵ^2)) / (sin(midpoint)^2 + sqrt(1 - pot.ϵ^2) * cos(midpoint)^2)^(3 / 2))^2 / (8 * app.m)
            end
        end
    end
    return value
end

function β(sim::Simulation, app::Apparatus, pot::Potential, s::Float64)
    hbar = 6.62607015e-34 / (2 * pi)
    l_perp = sqrt(hbar / (app.m * app.ω_perp))
    l_z = sqrt(hbar / (app.m * app.ω_z))
    if (sim.equation == "NPSE")
        value = im * hbar / (8 * app.m)
    elseif (sim.equation == "GPE")
        value = -im * app.ω_perp
    end
    value += (-im / hbar) * potential(sim::Simulation, app::Apparatus, pot::Potential, s::Float64)
    return value
end

function γ(sim::Simulation, app::Apparatus, state::InitialState, ψ::ComplexF64)
    hbar = 6.62607015e-34 / (2 * pi)
    l_perp = sqrt(hbar / (app.m * app.ω_perp))
    l_z = sqrt(hbar / (app.m * app.ω_z))
    npse_gamma = app.γ * hbar * app.ω_perp / l_z^6 * 1e-4
    σ(ψ::ComplexF64) = l_perp * sqrt(sqrt(1 + 2 * app.as * (app.N - 1) * abs.(ψ)^2))
    if sim.equation == "NPSE"
        if 1 + 2 * app.as * (app.N - 1) * abs.(ψ)^2 >= 0
            value = -im * hbar / (2 * app.m * σ(ψ)^2) - im * app.m * app.ω_perp^2 / (2 * hbar) * σ(ψ)^2 - im * 2 * hbar * app.as * (app.N - 1) / (app.m * σ(ψ)^2) * abs.(ψ)^2 - npse_gamma * app.N^2 * abs.(ψ)^4
        else
            #print("\nCollapse detected!")
            return NaN
        end
    elseif sim.equation == "GPE"
        value = -im * 2 * hbar * app.as * (app.N - 1) / (app.m * l_perp^2) * abs.(ψ)^2
    end
    return value
end

function wave(sim::Simulation, app::Apparatus, state::InitialState, s::Float64)
    hbar = 6.62607015e-34 / (2 * pi)
    l_perp = sqrt(hbar / (app.m * app.ω_perp))
    interaction_g = abs(2*hbar^2 * app.as / app.m / l_perp^2)
    ggg = 2*hbar*app.ω_perp*abs(app.as)
    GSEnergy = -app.N^3/24*ggg^2 * app.m/hbar^2
    Energy = GSEnergy
    k0 = app.m/hbar * state.v0

    if state.type == "gaussian" # Gaussian Pulse
        return sqrt(1 / (sqrt(2 * pi) * state.width)) * exp.(-(s-state.x0) .^ 2 / (4 * state.width^2)) * exp(im * (s-state.x0) * k0)
    elseif state.type == "sech"
        return sqrt(1 / (2 * state.width)) * 2 ./ (exp.(-((s-state.x0) / (state.width))) .+ exp.((s-state.x0) / (state.width))) * exp(im * (s-state.x0) * k0)
    end
end

function get_coefficients(sim::Simulation, app::Apparatus, pot::Potential, state::InitialState)
    # implement with PhysicalConstants.CODATA2018.h
    hbar = 6.62607015e-34 / (2 * pi)
    l_perp = sqrt(hbar / (app.m * app.ω_perp))
    l_z = sqrt(hbar / (app.m * app.ω_z))
    npse_gamma = app.γ * hbar * app.ω_perp / l_z^6 * 1e-4
    @assert(sim.equation in ["NPSE", "GPE"])
    @assert(pot.type in ["barrier", "ellipse", ""])

    α = -im * hbar / (2 * app.m)
    beta(s::Float64) = β(sim::Simulation, app::Apparatus, pot::Potential, s)
    gamma(ψ::ComplexF64) = γ(sim::Simulation, app::Apparatus, state::InitialState, ψ)
    initial_state(s::Float64) = wave(sim::Simulation, app::Apparatus, state::InitialState, s)
    return Coefficients(α, beta, gamma, initial_state)
end

function run_ground_state(num::Numerics, sim::Simulation, app::Apparatus, pot::Potential, state::InitialState)

    coeffs = get_coefficients(sim, app, pot, state)

    display("Running ground-state simulation")
    results = ground_state_solve(num, coeffs)
    plot_ground_state(results...)
end

function run_dynamics(num::Numerics, sim::Simulation, app::Apparatus, pot::Potential, state::InitialState)

    coeffs = get_coefficients(sim, app, pot, state)

    display("Running Dynamic simulation")
    results = ssfm_solve(num, coeffs)
    plot_dynamics(results...)
end


using NiLang, NiLang.AD
using BenchmarkTools

include("../exmamples/besselj.jl")

# To test this function, we first define input parameters `a` and output `out!`
a = 1.0
out! = 0.0

# We wrap the output with a randomly initialized gradient field, suppose we get the gradients from a virtual loss function.
# Also, we need to initialize an empty gradient field for elements in input cuda tensor `a`.
out! = ibesselj(out!, 2, a)[1]
out_g! = GVar(out!, 1.0)
a_g = GVar(a)

# Call the inverse program, the multiple dispatch will drive you to the goal.
println("Benchmarking NiLang")
display(@benchmark ibesselj($out!, 2, $a))
println("Benchmarking NiLang.AD")
display(@benchmark (~ibesselj)($out_g!, 2, $a_g))


module MyFiles

using SpecialFunctions, Dierckx, SymEngine, DelimitedFiles, ProgressMeter, DSP, FFTW, Roots, Parameters, JSON, NumericalIntegration, Dates
import DifferentialEquations: ODEProblem, solve, Tsit5

export  gnlse, Fiber, createTimeGrid, Pulse, gaussianPulse, sechPulse,
        pulseFromFile, FWHM, Pulse, getElectricField, spectrogram, wbeta2,
        lbeta2, lbeta3, sorder, dlength, L_operator, trapz, beta0, beta1,
        beta2, lfiss, χ3, bound, adk, geisslerPlasma, plasmaTerms, gnlsetest,
        wbeta0, wbeta1, uppe, getElectricFieldE, mfft, mifft, lbeta0,
        uppe2, LE_operator, βnl, dis_wave, zero_disp, lbeta2,
        soliton_order, getGamma, Waist, systemInfo,  soliton_period, smoothstep,
        flipsmoothstep, diffsion, test, diffsion0, rhs2, testrhs, ionRateAdk,
        geisslerPlasmaUPPE, cumtrapz, arb_f, chirpSechPulse, System,
        c, ϵ0, rindex, χ30,refractive_index, O3_disp, dispersion_coeffecient,
        gas, Tk_0, grid, Realχ, splbeta, Realχ, testdis, beta

function __init__()
    global x = symbols(:x)
end

include("constants.jl")
include("grid.jl")
include("raman.jl")
include("functions.jl")

include("gas.jl")
include("plasma.jl")
include("pulse.jl")
include("fiber.jl")
include("dispersion.jl")
include("gnlse.jl")
include("system.jl")

include("uppe.jl")
include("test.jl")

end # module


"""
   s,f = rdciti(fname)

Read the scattering matrix and frequency list from a CITI file. `s` is a
`Complex{Float64}` array of dimension `(n,n,nf)` where `n` is the number of
electrical ports of the scattering matrix, and `nf` is the number of
frequencies.  `f` is a `Float{64}` vector (or range object) of length `nf`
containing the frequencies in GHz.
"""
function rdciti(fname)
    open(fname,"r") do fid

        line = ""
        while isempty(line)
            line = readline(fid)
        end
        occursin("CITIFILE", line) || error("$fname is not a CITI file")

        k = nothing
        while k==nothing
            line = readline(fid)
            k = findfirst("var freq mag", lowercase(line))
        end
        nf = parse(Int, line[1+k[end]:end]) # Number of frequencies in the file

        # Locate first data descriptor:
        search_str = "DATA S["; k = nothing
        while k==nothing
            line = readline(fid)
            k = findfirst(search_str, line)
        end
        data_format = split(line)[end]

        # Count square of the number of ports
        nsq = 0
        while k != nothing
            nsq += 1
            line = readline(fid)
            k = findfirst(search_str, line)
        end
        n = isqrt(nsq) # Number of ports
        n*n == nsq || error("Bad count of S-parameters in $fname")

        s1 = zeros(n,n,nf) # Pre-allocation
        s2 = zeros(n,n,nf)  # Pre-allocation
        f = zeros(nf)  # Pre-allocation

        # Find the frequencies.  There are two types of possible structures:
        # VAR_LIST_BEGIN and SEG_LIST_BEGIN
        while true
            k = findfirst("VAR_LIST_BEGIN", line)
            if k != nothing # gobble up frequencies
                for j = 1:nf
                    f[j] = parse(Float64, readline(fid)) / 1e9
                end
                break
            end

            k = findfirst("SEG_LIST_BEGIN", line)
            if k != nothing # gobble up frequencies
                line = readline(fid)  # Contains "SEG  f1  f2  Nf"
                flims = map(x -> parse(Int64,x),split(line[4:end]))
                f = range(flims[1]/1e9, flims[2]/1e9, length=flims[3])
                break
            end

            line = readline(fid)
        end

        # Now loop over the row and column indices of the scattering matrix.
        for irow = 1:n, icol = 1:n
            # Find start of next data block:
            search_str = "BEGIN"; k = nothing
            while k == nothing
                line = readline(fid)
                k = findfirst(search_str, line)
            end
            for ifreq = 1:nf
                line = readline(fid)
                s1[irow,icol,ifreq], s2[irow,icol,ifreq] =
                    map(x->parse(Float64,x),split(line,','))
            end
        end

        if data_format == "RI"
            s = complex.(s1,s2)
        elseif data_format == "MA"
            s = s1 .* cis.(deg2rad.(s2))
        else
            error("Unknown data format $data_format")
        end
        return s, f
    end
end


function convertToGensysOut(bb, phi, theF, cc, g0, g1, psi, ncpi)

    (nr, nc) = size(g1)
    (nrpsi,ncpsi) = size(psi)
    stateDim = size(bb, 2) - ncpi
    G1 = bb[1:nr, 1:nc]

    ststate = (g0 - g1) \ cc
    CC = (Compat.Matrix(I, nr, nr) - G1) * ststate

    thePsi = vcat(psi, zeros(ncpi, ncpsi))
    aa = phi * thePsi
    impact = aa[1:nr, :]

    # no unique way to represent these components
    (ywt, fmat, fwt) = smallF(theF, aa, stateDim)

    return CC, G1, impact, ywt, fmat, fwt

end # function


#== # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Description
#
#   Convert a satellite state vector from an Earth-Centered Inertial (ECI)
#   reference frame to another ECI reference frame.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# References
#
#   [1] Vallado, D. A (2013). Fundamentals of Astrodynamics and Applications.
#       Microcosm Press, Hawthorn, CA, USA.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ==#

export svECItoECI

"""
    svECItoECI(sv::SatelliteStateVector, args...)

Convert the satellite state vector `sv` from an ECI frame to another ECI frame.
The arguments `args...` must match those of the function `rECItoECI` **wihtout**
the rotation representation.

"""
function svECItoECI(sv::SatelliteStateVector, args...)
    D = rECItoECI(DCM, args...)

    # Since both frames does not have a significant angular velocity between
    # them, then we just need to convert the representations.
    return SatelliteStateVector(t = sv.t, r = D*sv.r, v = D*sv.v, a = D*sv.a)
end


using GR
using LaTeXStrings

formula = L"- \frac{{\hbar ^2}}{{2m}}\frac{{\partial ^2 \psi (x,t)}}{{\partial x^2 }} + U(x)\psi (x,t) = i\hbar \frac{{\partial \psi (x,t)}}{{\partial t}}"

selntran(0)

settextfontprec(232, 3)
settextalign(2, 3)
setbordercolorind(6)

mathtex(0.5, 0.5, formula)

tbx, tby = inqmathtex(0.5, 0.5, formula)
Δx = (tbx[2] - tbx[1]) / √2
Δy = (tby[3] - tby[1]) / √2
path([0.5+Δx, Δx, 2π], [0.5, Δy, 0], "MAs");

updatews()