### A Pluto.jl notebook ###
# v0.17.1

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el)
        el
    end
end

# ╔═╡ dba46e66-8704-42de-938c-d576a1336398
using PlutoUI, Plots, Graphs, GraphMakie, CairoMakie, NetworkLayout, Test

# ╔═╡ 4b3e86ea-6973-11ec-014f-9f2708ba86cf
md"""

# RNAfolder

*STMO*

**Menno Van Damme**

This pluto notebook contains the code for a simple RNA secondary structure prediction tool.

## Nussinov's Algorithm

The tool uses an algorithm called Nussinov's algorithm. This is a basepair maximization algorithm, it predicts the optimal structure by trying to maximize the amount of paired nucleotides in an RNA sequence. This was one of the first ever algorithms to be used in RNA folding but sadly this algorithm is often too simple to get realistic results.

Other algorithms like energy minimization algorithms try to achieve the same thing but do this by taking base pairing energies, the energies of stacking of certain types of basepairs and the sizes of different structures into account and by calculating the total minimum free energy of the folded RNA. However, implementeing these is a lot more complicated and out of the scope of a project like this.

Nussinov's algorithm tries to maximize the amount of paired bases in the structure. It does this using the following formula:

$$S(i,j) = \max_{i\leq k<j} \begin{cases} S(i,j-1) \qquad\qquad\qquad\qquad\qquad\quad\; \text{if i unpaired} \\S(i,k-1)+S(k+1,j-1)+1 \qquad \text{if i, k complementary} \end{cases}$$

Here $$i$$, $$j$$, and $$k$$ are three positions in the RNA sequence with $$k$$ being equal to $$i$$ or in between $$i$$ and $$j$$. And $$S(i,j)$$ is the score of the subsequence from $$i$$ to $$j$$ given by the aglorithm, this score is equal to the amount of basepairs in the subsequence.

This formula is used to recursively fill in a dynamic programming matrix $$(S)$$ starting from smaller distances between $$i$$ and $$j$$ to larger ones, thus from smaller to larger subsequences, until $$i = 1$$ and $$j = n$$ (the length of the sequence). $$S(1,n)$$ then represents the score of the entire sequence.

If position $$j$$ is not paired to any nucleotide, the score does not change. So the score remains the same as the score of the subsequence one nucleotide smaller $$S(i,j-1)$$. If $$j$$ can basepair with a nucleotide $$k$$ in the range $$i:j-1$$ then the sequence is split into two subsequence $$i...k-1$$ and $$k+1...j-1$$, if we add their scores together with a $$+1$$ for the new basepair $$(k,j)$$ we get the score of the entire subsequence. if $$k=i$$ than we have a special case where $$S(i,k-1)=S(i,i-1)$$ this is why $$S(i,i-1)$$ is set to be equal to zero.

The matrix $$S$$ is initialized by all zeros and new values are only added to the upper right side of the matrix. Note that for two nucleotides to be able to basepair at least three other nucleotides need to be between them, otherwise there is not enough space for them to pair.

Below you can see the implementation for this algorithm.

"""

# ╔═╡ d3ee4413-c691-4fba-9f91-f24985fb8a88
md""" The Nussinov matrix for the example RNA looks like this: """

# ╔═╡ a455cfa0-ee29-4a4e-8b26-cf91c36985ec
md"""

To retrieve the basepairs which form the optimally scoring secondary structure we have to perform a backtracking procedure. This procedure starts in the upper right corner of the dynamic programming matrix where $$i=1$$ and $$j=n$$ and continues towards smaller subsequences. If $$S(i,j)$$ is equal to $$S(i,j-1)$$ we can say that $$j$$ is unpaired and we can continue the traceback from $$(i,j-1)$$. Else $$j$$ is paired to a $$k$$. If $$k=i$$ then $$S(i,j)=S(i+1,j-1)+1$$ and we can continue the traceback from $$(i+1,j-1)$$. If $$k \neq i$$ then $$S(i,j)=S(i,k-1)+S(i+1,j-1)+1$$ and the traceback splits up in the two substructures that were formed $$(i,k-1)$$ and $$(k+1,j-1)$$.

Since the rules of the Nussinov algorithm are simple there are most of the time many roads that lead to the same optimal score for a structure and thus many optimal ways to fold the RNA. This is because score for pairing $$j$$ with $$i$$ might give you the same score as pairing $$j$$ with $$k \; (\neq i)$$ or even the same as leaving $$j$$ unpaired.
"""

# ╔═╡ aea52dd9-7bcc-4873-9332-36b95592b27b
md""" If we backtrack from $$(i=1,j=n)$$ we get all the pairs in the sequence: """

# ╔═╡ 31aeff3d-5083-4c26-a556-847fbe76f9d6
md"""

## Tool

"""

# ╔═╡ b2084e43-7914-495f-b93e-cf56a87be3c7
md"""

You can either choose an example sequence or input you own (DNA sequences are also allowed).

"""

# ╔═╡ 59108cf2-d8a5-4c16-b373-bb6a23d13735
begin
	choices = ["Choose an example sequence:", "Input your own sequence:"]
	@bind choice Radio(choices, default = choices[1])
end

# ╔═╡ ed0a3dc5-99d3-4628-ad5c-7d13e699b353
begin
	RNAs = ["GGGAAUAUUAUAUCC" => "Example 1 (15 nucleotides)",
			"GGGCACUUGACUCGAGCAGACCGUAGCGAUAGCGCGAGAUUUGCCGGACUACCAC" => "Example 2 (55 nucleotides)", "GCTCGTGCGTCGATGAACAACGCAGCTAGCTGCGAGAATTAATGTGAATTGCAGGACACATTGATCATCGACACTTCGAACGCACTTGCGGCCCCGGGTTCCTCCCGGGGCTACGCCTGTCTGAGCGTCGCTTGAAAAAAAAAAAAAAAAAAAAAA" => "Human 5.8S rRNA (156 nucleotides)",
"ATGGACTCCAACACTGTGTCAAGCTTTCAGGTAGACTGCTTTCTTTGGCATGTCCGCAAACGATTTGCAGACCAAGAACTGGGTGATGCCCCATTCCTTGACCGGCTTCGCCGAGACCAGAAGTCCCTAAGAGGAAGAGGCAGCACTCTTGGTCTGGACATCGAGACAGCTACTCGTGCGGGAAAGCAAATAGTGGAGCGGATTCTGGGGGAAGAATCTGATGAAGCACTTAAAATGAATATTGCTTCTGTACCGACTTCACGCTACCTAACTGACATGACTCTTGAAGAAATGTCAAGAGACTGGTTCATGCTCATGCCCAAGCAGAAAGTAGCAGGTTCTCTCTGCATCAAAATGGACCAGGCAATAATGGATAAAACCATCATACTGAAAGCAAATTTCAGTGTGATTTTTGATCGGCTGGAAACCCTAATATTACTTAGAGCTTTCACAGAAGAAGGAGCAATTGTGGGAGAAATCTCACCATTACCTTCTCTTCCAGGACATACTGATGAGGATGTCAAAATTGCAATTGGGGTCCTCATCGGAGGGCTTGAATGGAATGATAACACAGTTCGAGTCTCTGAAACTCTACAGAGATTCACTTGGAGAAGCAGTAATGAGGATGGGAGACCTTCACTCCCTTCAAAACAGAAACGGAAAATGGCGAGAACAATTGAGTCAGAAGTTCGAGGAAATAAGATGGCTGATTGAGGAAATGCGACATAGATTGAAGACCACAGAGAACAGCTTCGAACAAATAACGTTTATGCAAGCTTTACAACTATTGCTTGAAGTGGAGCAAGAGATAAGAACCTTCTCGTTTCAGCTTATTTAA" => "Influenza A NS protein gene (838 nucleotides)"]

	if choice == choices[1]
		@bind rna Radio(RNAs, default = RNAs[1][1])
	elseif choice == choices[2]
		@bind rna TextField()
	end
end

# ╔═╡ 3c7f1384-33ac-4b2d-9a63-4bf412bfa685
RNA = replace(uppercase(rna), 'T' => 'U')

# ╔═╡ 45b4e0ec-5581-4a28-b6c1-c95b8e6a42bb
RNA

# ╔═╡ 42921538-4ff4-4902-aefa-d958f41d1404
md"""

Below you can see the dotbracket strucure of the RNA. This is a representation of the secondary structure by using dots and brackets. Each character represents a nucleotide in the sequence. Opening and closing brackets indicate two nucleotides that basepair. Dots represent unpaired nucleotides. Since guanine (G) and uracil (U) can also pair in RNA, GU pairs are allowed.

"""

# ╔═╡ fd14341c-f195-4b86-9f9c-379477eed4af
md"""

Here is the visualization of the secondary structure:

"""

# ╔═╡ ca99ac1a-e4da-41fe-8ab6-834e2b7134b7
md"""

Sadly there are no RNA visualization packages for Julia so I've had to use graph visualization libraries, these aren't ideal for this task so the structure might not look entirely correct. If you want a better view of the structure you can copy the following link. It will take you to a ViennaRNA webpage especially designed for displaying secondary RNA structures based on the sequence and dotbracket structure embedded in the link.

"""

# ╔═╡ 2fbe430d-ab80-406e-aa87-c377d6ed30c2
md"""

## Appendix

"""

# ╔═╡ e5650185-a6bc-488c-a02b-3c1363c52b8c
"""
	basepair(i, j, RNA)

Returns a the logical true if 2 nucleotides can basepair, else false.

"""
function basepair(i, j, RNA)
	pair = string(RNA[i], RNA[j])
	# all possible pairs (GU is also possible in RNA):
	pairs = ["AU", "UA", "GC", "CG", "UG", "GU"]
	if pair in pairs
		return true
	else
		return false
	end
end

# ╔═╡ 2d83c447-1d33-496a-8a39-75d1cb9b2de1
"""
	Nussinov(RNA)

Returns the Nussinov dynamic programming matrix of the RNA sequence.

"""
function Nussinov(RNA)
	n = length(RNA)
	S = zeros(n,n)
	# recursion happens from smaller to larger distancs between i and j,
	# from the diagonal towards the upper right corner in the matrix
	for d in 4:n-1 # at least 3 other nucleotides between a bp
		for i in 1:n-d
			j = i + d
			# j doesn't basepair
			nobp_score = S[i,j-1]
			# j basepairs with i (same as with k but S[i,k-1] = 0)
			if basepair(i,j,RNA)
				bpi_score = S[i+1,j-1] + 1
			else
				bpi_score = 0
			end
			# j basepairs with k in the range [i+1:j-4]
			bpk = []
			for k in i+1:j-4 # at least 3 other nucleotides between a bp
				if basepair(k,j,RNA)
					push!(bpk, S[i,k-1] + S[k+1,j-1] + 1)
				end
			end
			if !isempty(bpk)
				bpk_score = maximum(bpk)
			else
				bpk_score = 0
			end
			# the actual score is the maximum of these scores
			S[i,j] = max(nobp_score, bpi_score, bpk_score)
		end
	end
	return S
end

# ╔═╡ 0a20eddd-24f7-43c6-a0f3-6c1c138fb90a
S = Nussinov(RNA)

# ╔═╡ 463d18c3-e155-4b73-896f-2bbcdb71bbd2
"""
	traceback(RNA, S, i, j; pairs = [])

Performs a backtracking through the Nussinov dynamic programming matrix starting from position (i,j). Outputs a list of tuples with all the pairs in the sequence.

"""
function traceback(RNA, S, i, j; pairs = [])
	if i < j
		if  S[i,j] == S[i,j-1]
			traceback(RNA, S, i, j-1, pairs = pairs)
		elseif S[i,j] == S[i+1,j-1] + 1 && basepair(i, j, RNA)
			push!(pairs, (i,j))
			traceback(RNA, S, i+1, j-1, pairs = pairs)
		else
			for k in i+1:j-4
				if S[i,j] == S[i,k-1] + S[k+1,j-1] + 1 && basepair(k, j, RNA)
					push!(pairs, (k,j))
					traceback(RNA, S, i, k-1, pairs = pairs)
					traceback(RNA, S, k+1, j-1, pairs = pairs)
					break
				end
			end
		end
	end
	return pairs
end

# ╔═╡ 43f97b8d-cd9c-4b8f-8821-68542488e49d
pairs = traceback(RNA, S, 1, length(RNA))

# ╔═╡ b156a4c7-6ed9-4a4d-b3c9-d3c06fbc1faf
"""
	dotbracket(RNA, pairs)

Returns the dotbracket structure of the RNA, given a list of pairs.

"""
function dotbracket(RNA, pairs)
	n = length(RNA)
	db = collect('.' ^ n)
	for (i,j) in pairs
		db[i] = '('
		db[j] = ')'
	end
	db = join(db)
	return db
end

# ╔═╡ f66956d6-6d0d-42d1-b210-4bdf23ccd0b8
structure = dotbracket(RNA, pairs)

# ╔═╡ c86cc53d-4675-4cd1-af75-ec4a717fd7fa
link = "http://nibiru.tbi.univie.ac.at/forna/forna.html?id=url/name&sequence=$RNA&structure=$structure"

# ╔═╡ e25d53b9-0096-4b6c-85cb-fcae261fabcb
md""" $link """

# ╔═╡ f4e866fc-8e18-4917-b515-9cc00175a7a4
begin
	myblue = "#304da5"
	mygreen = "#2a9d8f"
	myyellow = "#e9c46a"
	myred = "#e76f51"
end

# ╔═╡ 2e8fb274-0658-43f8-bfa0-40f2f1daf6f3
"""
	plotstructure(RNA, pairs)

Plots the secondary structure of the RNA, given a list of pairs.

"""
function plotstructure(RNA, pairs)
	n = length(RNA)
	edges = [(i,i+1) for i in 1:n-1]
	append!(edges, pairs)
	G = SimpleGraph(Edge.(edges))
	colors = [mygreen, myblue, myyellow, myred]
	members = replace(collect(RNA), 'A' => 1, 'U' => 2, 'G' => 3, 'C' => 4)
	nodecolors = colors[members]
	edgecolors = []
	for edge in sort(edges)
		if edge in pairs
			push!(edgecolors, :red)
		else
			push!(edgecolors, :black)
		end
	end
	nuc = [string(i) for i in RNA]
	nodesize = 1000/n
	edgewidth = nodesize/3
	f, ax, p = graphplot(G,
						layout = Stress(),
						node_size = nodesize,
						node_color = nodecolors,
						edge_color = edgecolors,
						edge_width = edgewidth,
						nlabels = nuc,
						nlabels_align = (:center,:center),
						nlabels_textsize = nodesize,
						)
	hidedecorations!(ax); hidespines!(ax)
	ax.aspect = DataAspect()
	return f
end

# ╔═╡ 06983a7b-efca-4167-be5d-a158a4e0858d
plotstructure(RNA, pairs)

# ╔═╡ 94691ccf-b1ef-4cc3-8eed-72dd543001f5
md""" Unit tests are in the hidden chunk below: """

# ╔═╡ 32755c53-eefc-4d40-bf60-a8b21a545c6d
@testset "RNAfolder" begin

	@testset "Nussinov" begin

		@test Nussinov("AGCU") isa Array
		@test Nussinov("AAA") == zeros(3,3)
		@test Nussinov("AGCU") == zeros(4,4)
		@test Nussinov("AAAAU")[1,5] == 1.0

	end

	@testset "Traceback" begin

		@test traceback("AAA", Nussinov("AAA"), 1, 3) isa Array
		@test isempty(traceback("AAA", Nussinov("AAA"), 1, 3))
		@test traceback("AAAAU", Nussinov("AAAAU"), 1, 5) == [(1,5)]

	end

end

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
GraphMakie = "1ecd5474-83a3-4783-bb4f-06765db800d2"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
NetworkLayout = "46757867-2c16-5918-afeb-47bfcb05e46a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
CairoMakie = "~0.6.6"
GraphMakie = "~0.3.1"
Graphs = "~1.5.1"
NetworkLayout = "~0.4.4"
Plots = "~1.25.6"
PlutoUI = "~0.7.23"
"""

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

[[AbstractFFTs]]
deps = ["ChainRulesCore", "LinearAlgebra"]
git-tree-sha1 = "6f1d9bc1c08f9f4a8fa92e3ea3cb50153a1b40d4"
uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c"
version = "1.1.0"

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

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

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

[[Animations]]
deps = ["Colors"]
git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d"
uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340"
version = "0.4.1"

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

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

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

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

[[Automa]]
deps = ["Printf", "ScanByte", "TranscodingStreams"]
git-tree-sha1 = "d50976f217489ce799e366d9561d56a98a30d7fe"
uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b"
version = "0.8.2"

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

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

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

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

[[Cairo]]
deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"]
git-tree-sha1 = "d0b3f8b4ad16cb0a2988c6788646a5e6a17b6b1b"
uuid = "159f3aea-2a34-519c-b102-8c37f9878175"
version = "1.0.5"

[[CairoMakie]]
deps = ["Base64", "Cairo", "Colors", "FFTW", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "SHA", "StaticArrays"]
git-tree-sha1 = "774ff1cce3ae930af3948c120c15eeb96c886c33"
uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
version = "0.6.6"

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

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

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

[[ColorBrewer]]
deps = ["Colors", "JSON", "Test"]
git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4"
uuid = "a2cac450-b92f-5266-8821-25eda20663c8"
version = "0.4.0"

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

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

[[ColorVectorSpace]]
deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"]
git-tree-sha1 = "3f1f500312161f1ae067abe07d13b40f78f32e07"
uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4"
version = "0.9.8"

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

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

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

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

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

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

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

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

[[DensityInterface]]
deps = ["InverseFunctions", "Test"]
git-tree-sha1 = "80c3e8639e3353e5d2912fb3a1916b8455e2494b"
uuid = "b429d917-457f-4dbc-8f4c-0cc954292b1d"
version = "0.4.0"

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

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

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

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

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

[[EllipsisNotation]]
deps = ["ArrayInterface"]
git-tree-sha1 = "d7ab55febfd0907b285fbf8dc0c73c0825d9d6aa"
uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949"
version = "1.3.0"

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

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

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

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

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

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

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

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

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

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

[[FreeType]]
deps = ["CEnum", "FreeType2_jll"]
git-tree-sha1 = "cabd77ab6a6fdff49bfd24af2ebe76e6e018a2b4"
uuid = "b38be410-82b0-50bf-ab77-7b57e271db43"
version = "4.0.0"

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

[[FreeTypeAbstraction]]
deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics", "StaticArrays"]
git-tree-sha1 = "770050893e7bc8a34915b4b9298604a3236de834"
uuid = "663a7486-cb36-511b-a19d-713bb74d65c9"
version = "0.9.5"

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

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

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

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

[[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 = "a32d672ac2c967f3deb8a81d828afc739c838a06"
uuid = "7746bdde-850d-59dc-9ae8-88ece973131d"
version = "2.68.3+2"

[[GraphMakie]]
deps = ["GeometryBasics", "Graphs", "LinearAlgebra", "Makie", "NetworkLayout", "StaticArrays"]
git-tree-sha1 = "8fc75ea16d1836cbcfb94227605afd49d5f3facf"
uuid = "1ecd5474-83a3-4783-bb4f-06765db800d2"
version = "0.3.1"

[[Graphics]]
deps = ["Colors", "LinearAlgebra", "NaNMath"]
git-tree-sha1 = "1c5a84319923bea76fa145d49e93aa4394c73fc2"
uuid = "a2bd30eb-e257-5431-a919-1863eab51364"
version = "1.1.1"

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

[[Graphs]]
deps = ["ArnoldiMethod", "Compat", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"]
git-tree-sha1 = "d727758173afef0af878b29ac364a0eca299fc6b"
uuid = "86223c79-3864-5bf0-83f7-82e725a168b6"
version = "1.5.1"

[[GridLayoutBase]]
deps = ["GeometryBasics", "InteractiveUtils", "Observables"]
git-tree-sha1 = "70938436e2720e6cb8a7f2ca9f1bbdbf40d7f5d0"
uuid = "3955a311-db13-416c-9275-1d80ed98e5e9"
version = "0.6.4"

[[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 = "0fa77022fe4b511826b39c894c90daf5fce3334a"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.9.17"

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

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

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

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

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

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

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

[[Imath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "87f7662e03a649cffa2e05bf19c303e168732d3e"
uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1"
version = "3.1.2+0"

[[IndirectArrays]]
git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f"
uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959"
version = "1.0.0"

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

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

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

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

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

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

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

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

[[Isoband]]
deps = ["isoband_jll"]
git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137"
uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4"
version = "0.1.1"

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

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

[[JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "22df5b96feef82434b07327e2d3c770a9b21e023"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.4.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"

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

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

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

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

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

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

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

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

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

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

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

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

[[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 = ["ChainRulesCore", "ChangesOfVariables", "DocStringExtensions", "InverseFunctions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "e5718a00af0ab9756305a0392832c8952c7426c1"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.6"

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

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

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

[[Makie]]
deps = ["Animations", "Base64", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Distributions", "DocStringExtensions", "FFMPEG", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "Packing", "PlotUtils", "PolygonOps", "Printf", "Random", "RelocatableFolders", "Serialization", "Showoff", "SignedDistanceFields", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "UnicodeFun"]
git-tree-sha1 = "56b0b7772676c499430dc8eb15cfab120c05a150"
uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
version = "0.15.3"

[[MakieCore]]
deps = ["Observables"]
git-tree-sha1 = "7bcc8323fb37523a6a51ade2234eee27a11114c8"
uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b"
version = "0.1.3"

[[MappedArrays]]
git-tree-sha1 = "e8b359ef06ec72e8c030463fe02efe5527ee5142"
uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900"
version = "0.4.1"

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

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

[[MathTeXEngine]]
deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "Test"]
git-tree-sha1 = "70e733037bbf02d691e78f95171a1fa08cdc6332"
uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53"
version = "0.2.1"

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

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

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

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

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

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

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

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

[[Netpbm]]
deps = ["FileIO", "ImageCore"]
git-tree-sha1 = "18efc06f6ec36a8b801b23f076e3c6ac7c3bf153"
uuid = "f09324ee-3d7c-5217-9330-fc30815ba969"
version = "1.0.2"

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

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

[[Observables]]
git-tree-sha1 = "fe29afdef3d0c4a8286128d4e45cc50621b1e43d"
uuid = "510215fc-4207-5dde-b226-833fc4488ee2"
version = "0.4.0"

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

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

[[OpenEXR]]
deps = ["Colors", "FileIO", "OpenEXR_jll"]
git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633"
uuid = "52e1d378-f018-4a11-a4be-720524705ac7"
version = "0.3.2"

[[OpenEXR_jll]]
deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "923319661e9a22712f24596ce81c54fc0366f304"
uuid = "18a262bb-aa17-5467-a713-aee519bc75cb"
version = "3.1.1+0"

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

[[OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "648107615c15d4e09f7eca16307bc821c1f718d8"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.13+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 = "ee26b350276c51697c9c2d88a072b339f9f03d73"
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
version = "0.11.5"

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

[[Packing]]
deps = ["GeometryBasics"]
git-tree-sha1 = "1155f6f937fa2b94104162f01fa400e192e4272f"
uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566"
version = "0.4.2"

[[PaddedViews]]
deps = ["OffsetArrays"]
git-tree-sha1 = "03a7a85b76381a3d04c7a1656039197e70eda03d"
uuid = "5432bcbf-9aad-5242-b902-cca2824c8663"
version = "0.5.11"

[[Pango_jll]]
deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "9bc1871464b12ed19297fbc56c4fb4ba84988b0d"
uuid = "36c8627f-9965-5494-a995-c6b170f724f3"
version = "1.47.0+0"

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

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

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

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

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

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

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

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

[[PolygonOps]]
git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6"
uuid = "647866c9-e3ac-4575-94e7-e3d426903924"
version = "0.1.2"

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

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

[[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 = "78aadffb3efd2155af139781b8a8df1ef279ea39"
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
version = "2.4.2"

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

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

[[Ratios]]
deps = ["Requires"]
git-tree-sha1 = "01d341f502250e81f6fec0afe662aa861392a3aa"
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
version = "0.4.2"

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

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

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

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

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

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

[[SIMD]]
git-tree-sha1 = "39e3df417a0dd0c4e1f89891a281f82f5373ea3b"
uuid = "fdea26ae-647d-5447-a871-4b548cad5224"
version = "3.4.0"

[[ScanByte]]
deps = ["Libdl", "SIMD"]
git-tree-sha1 = "9cc2955f2a254b18be655a4ee70bc4031b2b189e"
uuid = "7b38b023-a4d7-4c5e-8d43-3f3097f304eb"
version = "0.3.0"

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

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

[[SignedDistanceFields]]
deps = ["Random", "Statistics", "Test"]
git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9"
uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96"
version = "0.4.0"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[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 = "bb1064c9a84c52e277f1096cf41434b675cd368b"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.6.1"

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

[[TensorCore]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6"
uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50"
version = "0.1.1"

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

[[TiffImages]]
deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"]
git-tree-sha1 = "991d34bbff0d9125d93ba15887d6594e8e84b305"
uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69"
version = "0.5.3"

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

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

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

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

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

[[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"]
git-tree-sha1 = "66d72dc6fcc86352f01676e8f0f698562e60510f"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.23.0+0"

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

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

[[isoband_jll]]
deps = ["Libdl", "Pkg"]
git-tree-sha1 = "a1ac99674715995a536bbce674b068ec1b7d893d"
uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4"
version = "0.2.2+0"

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

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

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

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

[[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 = "4fea590b89e6ec504593146bf8b988b2c00922b2"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2021.5.5+0"

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

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

# ╔═╡ Cell order:
# ╟─4b3e86ea-6973-11ec-014f-9f2708ba86cf
# ╠═2d83c447-1d33-496a-8a39-75d1cb9b2de1
# ╠═45b4e0ec-5581-4a28-b6c1-c95b8e6a42bb
# ╟─d3ee4413-c691-4fba-9f91-f24985fb8a88
# ╠═0a20eddd-24f7-43c6-a0f3-6c1c138fb90a
# ╟─a455cfa0-ee29-4a4e-8b26-cf91c36985ec
# ╠═463d18c3-e155-4b73-896f-2bbcdb71bbd2
# ╟─aea52dd9-7bcc-4873-9332-36b95592b27b
# ╠═43f97b8d-cd9c-4b8f-8821-68542488e49d
# ╟─31aeff3d-5083-4c26-a556-847fbe76f9d6
# ╟─b2084e43-7914-495f-b93e-cf56a87be3c7
# ╟─59108cf2-d8a5-4c16-b373-bb6a23d13735
# ╟─ed0a3dc5-99d3-4628-ad5c-7d13e699b353
# ╟─3c7f1384-33ac-4b2d-9a63-4bf412bfa685
# ╟─42921538-4ff4-4902-aefa-d958f41d1404
# ╟─f66956d6-6d0d-42d1-b210-4bdf23ccd0b8
# ╟─fd14341c-f195-4b86-9f9c-379477eed4af
# ╠═06983a7b-efca-4167-be5d-a158a4e0858d
# ╟─ca99ac1a-e4da-41fe-8ab6-834e2b7134b7
# ╟─e25d53b9-0096-4b6c-85cb-fcae261fabcb
# ╟─2fbe430d-ab80-406e-aa87-c377d6ed30c2
# ╠═dba46e66-8704-42de-938c-d576a1336398
# ╠═e5650185-a6bc-488c-a02b-3c1363c52b8c
# ╠═b156a4c7-6ed9-4a4d-b3c9-d3c06fbc1faf
# ╠═c86cc53d-4675-4cd1-af75-ec4a717fd7fa
# ╠═2e8fb274-0658-43f8-bfa0-40f2f1daf6f3
# ╠═f4e866fc-8e18-4917-b515-9cc00175a7a4
# ╟─94691ccf-b1ef-4cc3-8eed-72dd543001f5
# ╟─32755c53-eefc-4d40-bf60-a8b21a545c6d
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002


using AdFem

mmesh = Mesh3(20, 20, 20, 1/20)
xy = gauss_nodes(mmesh)
a = Variable(0.1)
κ = 1/(a+xy[:,1].^2 + xy[:,2].^2 + xy[:,3].^2)
K = compute_fem_laplace_matrix1(κ, mmesh)
rhs = compute_fem_source_term1(ones(get_ngauss(mmesh)), mmesh)
bd = bcnode(mmesh)
K, rhs = impose_Dirichlet_boundary_conditions(K, rhs, bd, zeros(length(bd)))
sol = K\rhs
sess = Session(); init(sess)
SOL = run(sess, sol)

############## Visualization 1
using PyPlot
using DelimitedFiles
idx = falses(mmesh.ndof)
s = 1
for k = 1:21
    for j = 1:21
        for i = 1:21
            if k==11 && j==11
                idx[s] = true
            end
            global s = s + 1
        end
    end
end
close("all")
x0 = LinRange(0,1,21)
plot(x0, readdlm("val.txt")[:], label = "FEniCS")
plot(x0, SOL[idx], "o", label = "AdFem")

legend()
xlabel("x")
ylabel("\$u(x, 0.5, 0.5)\$")
savefig("section_plot_mfem3d.png")

############## Visualization 2
visualize_scalar_on_fem_points(SOL, mmesh)
visualize_mesh(mmesh)


push!(LOAD_PATH, string(pwd(),"/src"))

using ModifiedStokesSolver
using FastGaussQuadrature
using Base.Test

panelorder1 = 32
panelorder2 = 160

glpoints1, glweights1 = gausslegendre(panelorder1)
glpoints2, glweights2 = gausslegendre(panelorder2)

@testset "Upsampling" begin
    U = ModifiedStokesSolver.upsampling_matrix(panelorder1, panelorder2)
    f(x) = @. 1/(x^2+2)
    fu = U * f(glpoints1)
    err = fu - f(glpoints2)
    relerr_inf = norm(err, Inf) / norm(fu, Inf)
    @test relerr_inf < 2e-14
end


using Jchemo, LinearAlgebra

n = 50 ; p = 7
Xtrain = rand(n, p)
m = 3
Xtest = rand(m, p)

nlv = 5
fm = pcasvd(Xtrain; nlv = nlv) ;
#fm = pcaeigen(Xtrain; nlv = nlv) ;
pnames(fm)
fm.T
fm.T' * fm.T
fm.P' * fm.P

Jchemo.transform(fm, Xtest)

res = Jchemo.summary(fm, Xtrain) ;
pnames(res)
res.explvar
res.contr_var
res.coord_var
res.cor_circle

# Weighted PCA
w = collect(1:n)
nlv = 5
fm = pcasvd(Xtrain, w; nlv = nlv) ;
D = Diagonal(mweights(w)) ;
fm.T' * D * fm.T
fm.P' * fm.P


using PolyChaos
using LinearAlgebra
using Distributions

## This is an example on the usage of PolyChaos for non-intrusive PCE using
## the projection and the regression approach and a comarison of them in the univariate setting.
## f = e^x, x ~ N(1, 0.1)

μ, σ = 1, 0.1
maxdegree = 7

# model equation
function model(x)
    exp.(μ + σ * x)
end

# Analytic refernce
k_values = 0:maxdegree
computeCoefficient_analytic(k::Int) = exp(μ + 0.5*σ^2) * σ^k / factorial(k)
y_ana = computeCoefficient_analytic.(k_values)

# Setup and compute PCE coefficients of x
op = GaussOrthoPoly(maxdegree, Nrec=2*maxdegree)
t2 = Tensor(2, op)

# ------- Projection -------
println("\t == Projection approach ==")

# Perform projection via numerical integration
function computeProjection(k::Int, model::Function)
    g(t) = model(t) * evaluate(k, t, op)
    γ = t2.get([k,k])
    integrate(g, op.quad) / γ
end

y_proj = computeProjection.(0:maxdegree, model)
println.(y_proj)
println()

# Comparison to analytical solution
println("Comapre coefficients analytic <-> projection:")
println(norm(y_ana - y_proj, Inf), "\n")

# ------- Regression -------
include("../src/regression.jl")

println("\t == Regression approach ==")

# FUTURE: Perform truncation somehow

# Draw n samples, where N > P has to hold
nSamples = maxdegree * 20
X = sampleMeasure(nSamples, op)

# Evaluate model -> vector Y
Y = model.(X)

# Build matrix Φ with ϕ(x(i))
# Φ = Array{Float64}(undef, nSamples, maxdegree+1)
Φ = [ evaluate(j, X[i], op) for i = 1:nSamples, j = 0:maxdegree]

# Ordinary least squares regression
y_reg = leastSquares(Φ, Y)
println.(y_reg)
println()

# Validation of PCE model
println("Comapre coefficients analytic <-> regression:")
println(norm(y_ana - y_reg, Inf))

# genError = empError(Y, Φ, y_reg)
# println("Determination coefficient R² (normalized empicial error): ", 1 - genError)

ϵLoo = looError(Y, Φ, y_reg)
println("Determination coefficient Q² (leave-one-out error): ", 1- ϵLoo)
println()

# ------- Monte-Carlo -------
# Evaluate model function on same set of previously drawn samples X
y_mc = model.(X)

# ------- Comparison of moments -------
println("Comparison of moments to analytic solution")

# Analytic moments for y
mean_ana = exp(μ + σ^2/2)
std_ana = sqrt(exp(2*μ + σ^2) * (exp(σ^2) - 1))
skew_ana = sqrt(exp(σ^2) - 1) * (exp(σ^2) + 2)

# MC moments
mean_mc, std_mc, skew_mc = mean(y_mc), std(y_mc), skewness(y_mc)
error_mean_mc = abs(mean_ana - mean_mc)
error_std_mc = abs(std_ana - std_mc)
println("\t\t\t error MC, mean: \t $(error_mean_mc)")
println("\t\t\t error MC, std: \t $(error_std_mc)")

# Projection moments
mean_proj = mean(y_proj, op)
std_proj = std(y_proj, op)
error_mean_proj = abs(mean_ana - mean_proj)
error_std_proj = abs(std_ana - std_proj)
println("\t\t\t error proj, mean: \t $(error_mean_proj)")
println("\t\t\t error proj, std: \t $(error_std_proj)")

# Regression moments
mean_reg = mean(y_reg, op)
std_reg = std(y_reg, op)
error_mean_reg = abs(mean_ana - mean_reg)
error_std_reg = abs(std_ana - std_reg)
println("\t\t\t error reg, mean: \t $(error_mean_reg)")
println("\t\t\t error reg, std: \t $(error_std_reg)")


function mass(u, q, w, v, x, t, mu, eta)
    m = [1.0, 1.0, 1.0];
    return m;
end
function flux(u, q, w, v, x, t, mu, eta)
    g = mu[1];
    r = u[1];  # total height: h
    ru = u[2]; # h*u
    rv = u[3]; # h*v
    r1 = 1/r;
    uv = ru*r1; # u
    vv = rv*r1; #v
    p = (0.5*g)*(r*r); # 0.5*g*h^2
    f = [ru, ru*uv+p, rv*uv, rv, ru*vv, rv*vv+p];
    # [h*u h*u^2 + 0.5*g*h^2  huv h*v h*u*v h*v^2+0.5*g*h^2]
    f = reshape(f,(3,2));

    return f;
end
function source(u, q, w, v, x, t, mu, eta)
    s = [0.0, 0.0, 0.0];
    return s;
end
function ubou(u, q, w, v, x, t, mu, eta, uhat, n, tau)
    ub = [0.0, 0.0, 0.0];
    return ub;
end
function fbou(u, q, w, v, x, t, mu, eta, uhat, n, tau)
    f = flux(u, q, w, v, x, t, mu, eta);
    fb = f[:,1]*n[1] + f[:,2]*n[2] + tau[1]*(u-uhat);
    return fb;
end
function initu(x, mu, eta)
    epsil = 0.1; # perturbation magnitude
    l = 0.5;     # Gaussian width
    k = 0.5;     # Sinusoidal wavenumber

    x1 = x[1];
    x2 = x[2];

    # The Bickley jet
    U = (1/cosh(x2))*(1/cosh(x2));

    # Slightly off-center vortical perturbations
    Psiprime = exp(-(x2 + l/10)*(x2 + l/10) / (2*(l*l))) * cos(k * x1) * cos(k * x2);

    # Vortical velocity fields (ũ, ṽ) = (-∂_y, +∂_x) ψ̃
    uprime =  Psiprime * (k * tan(k * x2) + x2 /(l*l));
    vprime = -Psiprime * k * tan(k * x1);

    u01 = 1.0; # h
    u02 = U + epsil * uprime; # h*u
    u03 = epsil * vprime;  # h*v

    u0 = [u01, u02, u03];
    return u0;
end


using SimulatedAnnealing
using Random

"""
    Tour

Struct representing a tour visiting cities.

Fields
------
`order::Vector{Int}` order in which each city is visited.
`D::Matrix` Matrix of distances between each pair of cities. This is stored
to be able to pass it down to new candidates without the need of
recomputing it.
"""
struct Tour
    order::Vector{Int}
    D::Matrix{Float64}
end

"""
    Tour(D::Matrix)

Create a tour with random ordering of the cities.
"""
Tour(D::Matrix) = Tour(randcycle(size(D, 1)), D)

"""
    energy(tour::Tour)

Compute the energy of a `Tour` by summing the distances of successive cities
in the tour.
"""
function energy(tour::Tour)
    s = 0.0

    for (k, c1) in enumerate(tour.order)
        c2 = tour.order[mod1(k + 1, length(tour.order))]
        s += tour.D[c1, c2]
    end

    return s
end

"""
    propose_candidate(tour::Tour)

Propose a new candidate `Tour` by reversing the order of cities between two
random indices.
"""
function propose_candidate(tour::Tour)
    n = length(tour.order)
    order = copy(tour.order)

    # Order will be reversed between i1 and i2 included
    i1 = rand(1:n)
    i2 = mod1(rand(1:n-1) + i1, n)  # Make sure i1 != i2

    # Make sure that i1 < i2
    if i1 > i2
        i1, i2 = i2, i1
    end

    if i1 == 1 && i2 == n
        return Tour(order, tour.D), 0.0
    end

    city_a1 = order[i1]
    city_a2 = order[i2]

    city_b1 = order[mod1(i1 - 1, n)]  # Index following i1
    city_b2 = order[mod1(i2 + 1, n)]  # Index preceding i2

    dE = (tour.D[city_a1, city_b2] + tour.D[city_a2, city_b1]
          - tour.D[city_a1, city_b1] - tour.D[city_a2, city_b2])

    order[i1:i2] = reverse(order[i1:i2])

    dE = energy(Tour(order, tour.D)) - energy(tour)

    return Tour(order, tour.D), dE
end

cities = [
    [0.0 1.0 2.0 3.0 3.0 3.0 3.0 2.0 1.0 0.0 0.0 0.0] ;
    [0.0 0.0 0.0 0.0 1.0 2.0 3.0 3.0 3.0 3.0 2.0 1.0]
]

# Distance matrix, common for all Tour objects
D = sqrt.((cities[1, :] .- cities[1, :]').^2 +
          (cities[2, :] .- cities[2, :]').^2)
n = size(D, 1)

# Initial sampling of the configuration space
samples = [Tour(D) for _ in 1:1000]

# Run the algorithm with default parameters
prob = AnnealingOptimization(energy, propose_candidate, samples, n*(n - 1))
best_tour, tour_length = simulated_annealing(prob)


##########################
# FunctionCell Interface #
##########################
"""
	lr(r=0; trans=true, bias=true)

Constructs an untrained cell that when piped data inside (observations and
responses) calculates the regularized (ridge) Least-Squares regression
coefficients of the data based on the responses and regularization parameter
`r`.

The parameter `r` can be a real scalar, a vector or symetric matrix.

# Keyword arguments (same as in `MultivariateStats`)
  * `trans` whether to use the trasposed form, (default `true` e.g. rows are variables, columns are observations)
  * `bias` whether to include a bias term (default `true`)

Read the `MultivariateStats.jl` documentation for more information.
"""
lr(r=0; trans::Bool=true, bias::Bool=true) =
	FunctionCell(lr, (r,), ModelProperties(),
	      kwtitle("Linear regressor", [(:trans,trans),(:bias,bias)]);
	      trans=trans, bias=bias)

############################
# DataCell/Array Interface #
############################
"""
	lr(x,y, [;kwargs])

Trains a Least-Squares regression function cell. Returns the regression coefficients and bias (if available)
"""
# Training
lr(x::T where T<:CellDataU, r::Union{Real, AbstractArray}=0; trans::Bool=true, bias::Bool=true) =
	lr((getx!(x), zeros(nobs(x))), r; trans=trans, bias=bias)
lr(x::T where T<:CellData, r::Union{Real, AbstractArray}=0; trans::Bool=true, bias::Bool=true) =
	lr((getx!(x), gety(x)), r; trans=trans, bias=bias)
lr(x::Tuple{T,S} where T<:AbstractVector where S<:AbstractArray, r::Union{Real, AbstractArray}=0; trans::Bool=true, bias::Bool=true) =
	lr((mat(x[1], LearnBase.ObsDim.Constant{2}()), x[2]), r; trans=trans, bias=bias)
lr(x::Tuple{T,S} where T<:AbstractMatrix where S<:AbstractArray, r::Union{Real, AbstractArray}=0; trans::Bool=true, bias::Bool=true ) = begin

	@assert nobs(x[1]) == nobs(x[2])

	# If y vector, leave as is, if matrix, traspose
	if x[2] isa Vector
		tmp = MultivariateStats.ridge(getobs(x[1]), x[2], r, trans=trans, bias=bias)
	else
		tmp = MultivariateStats.ridge(getobs(x[1]), x[2]', r, trans=trans, bias=bias)
	end

	if bias
		a = tmp[1:end-1,:]
		b = tmp[end,:]
	else
		a = tmp
		b = zeros(nvars(x[2]))
	end

	# Build model properties
	modelprops = ModelProperties(size(a,1), size(a,2))

	# Returned trained cell
	FunctionCell(lr, Model((a,b), modelprops), kwtitle("Linear regressor", [(:trans,trans),(:bias,bias)]))
end

# Execution
lr(x::T where T<:CellData, model::Model{<:Tuple{<:AbstractArray, <:AbstractArray}}) =
	datacell(lr(getx!(x), model), gety(x))
lr(x::T where T<:AbstractVector, model::Model{<:Tuple{<:AbstractArray, <:AbstractArray}}) =
	lr(mat(x, LearnBase.ObsDim.Constant{2}()), model)
lr(x::T where T<:AbstractMatrix, model::Model{<:Tuple{<:AbstractArray, <:AbstractArray}}) =
	model.data[1]'*x .+ model.data[2] # e.g. aᵀX+b


using JuSwarm, Optim, StaticArrays, Test

function spherefunc(x::AbstractVector)
    return sum(x.^2)
end

N = 14
PSOopts = PSOOptions(N; HybridOptimizer = Optim.LBFGS(), Display = "none")

sol = psoptimize(spherefunc, PSOopts)

@test sol.fbest <= sol.fbestPSO

@test sol.fbestPSO <= 1.0e-6

@test sol.fbest <= 1.0e-10


using ITensors
using UnicodePlots
using Zygote

include("ising_model.jl")
include("minimize.jl")
include("orthogonalize_eigenvectors.jl")

# Define the sites of the Hilbert space
n = 10
i = [Index(2, "S=1/2") for j in 1:n];

# Define the Hamiltonian
h = 0.5 # field
H = MPO(ising(n; h), i);

#
# An example of a cost function for minimizing the energy
#
function E(psi::MPS)
  psiHpsi = inner(psi', H, psi)
  psipsi = inner(psi, psi)
  return psiHpsi / psipsi
end
gradE(psi) = gradient(E, psi)[1]

# Compute the ground state with gradient descent
psi_init = MPS(i, "Zp");
psi0 = minimize(E, gradE, psi_init; nsteps=50, gamma=0.1, cutoff=1e-5, maxdim=10);
psi0 /= norm(psi0);

@show E(psi_init), E(psi0)

#
# Write a cost function the minimizes the energy
# as well as the overlap between states. For example:
#
# c = <psi_1|H|psi_1> + <psi_2|H|psi_2> + ... +
#     |<psi_1|psi_2>|^2 + |<psi_1|H|psi_3>|^2 + ...
#
# Make sure to normalize!
function cost_function(psis::Vector{MPS})
  nstates = length(psis)
  N = [inner(psis[i], psis[j]) for i in 1:nstates, j in 1:nstates]

  energy = 0.0
  for i in 1:nstates
    energy += inner(psis[i]', H, psis[i]) / N[i, i]
  end

  off_diagonal_overlap = 0.0
  for i in 1:(nstates - 1), j in (i + 1):nstates
    if i != j
      off_diagonal_overlap += abs2(N[i, j]) / (N[i, i] * N[j, j])
    end
  end
  return energy + off_diagonal_overlap
end
grad_cost_function(psi) = gradient(cost_function, psi)[1]

nstates = 3
psis_init = [randomMPS(i; linkdims=2) for _ in 1:nstates]
psis = minimize(cost_function, grad_cost_function, psis_init; nsteps=50, gamma=0.1, cutoff=1e-5, maxdim=10);
psis = normalize.(psis);

@show E.(psis)

# Plot <Sz> and <Sx> for our eigenvectors
for i in 1:nstates
  plt = lineplot(expect(psis[i], "Sz"); title="Ising model state $i from gradient descent before orthogonalization", name="Sz", xlim=[1,10], ylim=[-0.5,0.5])
  lineplot!(plt, expect(psis[i], "Sx"); name="Sx")
  display(plt)
end
# Construct an effective Hamiltonian `Heff` for the states we found
Heff = [inner(psis[i]', H, psis[j]) for i in 1:nstates, j in 1:nstates]

# Construct the overlap matrix `N` for the states we found
N = [inner(psis[i], psis[j]) for i in 1:nstates, j in 1:nstates]

println("\nHeff = <psi_i|H|psi_j> from DMRG")
display(Heff)

println("\nN = <psi_i|psi_j> from DMRG")
display(N)

#
# Orthogonalize the eigenvectors by solving the generalized eigenvector
# equations:
#
# <psi_i|H|psi_j><psi_j|v> = lambda_i * <psi_j|v>
#
# See `orthogonalize_eigenvectors.jl` for details.
#
psis = orthogonalize_eigenvectors(H, psis)

# Replot <Sz> and <Sx> for our eigenvectors
for i in 1:nstates
  plt = lineplot(expect(psis[i], "Sz"); title="Ising model state $i from gradient descent after orthogonalization", name="Sz", xlim=[1,10], ylim=[-0.5,0.5])
  lineplot!(plt, expect(psis[i], "Sx"); name="Sx")
  display(plt)
end

# Construct an effective Hamiltonian `Heff` for the states we found
Heff = [inner(psis[i]', H, psis[j]) for i in 1:nstates, j in 1:nstates]

# Construct the overlap matrix `N` for the states we found
N = [inner(psis[i], psis[j]) for i in 1:nstates, j in 1:nstates]

println("\nHeff = <psi_i|H|psi_j> from DMRG")
display(Heff)

println("\nN = <psi_i|psi_j> from DMRG")
display(N)


###############################
#
#        SECOND ORDER
#
###############################

# Thanks to https://web.media.mit.edu/~crtaylor/calculator.html
# For different stencil sizes:
# c1 = [1, -2, 1]
# c2 = [-1, 16, -30, 16, -1] / 12
# c3 = [2, -27, 270, -490, 270, -27, 2] / 180
# c4 = [-9, 128, -1008, 8064, -14350, 8064, …] / 5040
# etc

function fd_diff2_ord2!(dx2_U, U, dx⁻¹)
    local c1 = SA[1.0, -2.0, 1.0]
    for i = 2 : length(U)-1
        dx2_U[i] = dot(c1, U[i-1 : i+1])
    end
    dx2_U[1] = dx2_U[2]
    dx2_U[end] = dx2_U[end-1]

    @. dx2_U *= dx⁻¹ ^ 2

    nothing
end

function fd_diff2_ord4!(dx2_U, U, dx⁻¹)
    local c1 = SA[1.0, -2.0, 1.0]
    local c2 = SA[-1.0, 16.0, -30.0, 16.0, -1.0] * 0.08333333333333333333
    for i in 3 : length(U)-2
        dx2_U[i] = dot(c2, U[i-2 : i+2])
    end

    dx2_U[2] = dot(c1, U[1:3])
    dx2_U[end-1] = dot(c1, U[end-2 : end])

    dx2_U[1] = dx2_U[2]
    dx2_U[end] = dx2_U[end-1]

    @. dx2_U *= dx⁻¹ ^ 2

    nothing
end

function fd_diff2_ord6!(dx2_U, U, dx⁻¹)
    local c1 = SA[1.0, -2.0, 1.0]
    local c2 = SA[-1.0, 16.0, -30.0, 16.0, -1.0] * 0.08333333333333333333
    local c3 = SA[2.0, -27.0, 270.0, -490.0, 270.0, -27.0, 2.0]
    c3 *= 0.00555555555555555555
    for i in 4 : length(U)-3
        dx2_U[i] = dot(c3, U[i-3 : i+3])
    end

    dx2_U[3] = dot(c2, U[1:5])
    dx2_U[end-2] = dot(c2, U[end-4 : end])

    dx2_U[2] = dot(c1, U[1:3])
    dx2_U[end-1] = dot(c1, U[end-2 : end])

    dx2_U[1] = 2.0*dx2_U[2] - dx2_U[3]
    dx2_U[end] = 2.0*dx2_U[end-1] - dx2_U[end-2]

    @. dx2_U *= dx⁻¹ ^ 2

    nothing
end


#Tests using the NIST Matrix Market

using IterativeSolvers, MatrixMarket
@info("Testing matrices from the NIST Matrix Market")
for (setname, matname) in [("cylshell", "s3dkq4m2")]
    dl_filename = string(setname, "_", filename)
    isfile(dl_filename) || download("ftp://math.nist.gov/pub/MatrixMarket2/misc/$setname/$matname.mtx.gz", dl_filename)

    vars = matread(dl_filename)
    A, b = vars["Problem"]["A"], vars["Problem"]["b"][:]

    #Use direct solve as benchmark
    println("$dl_filename: Direct solve")
    tic()
    x = A \ b
    toc()

    @show Aissym = issym(A)
    @show Aisposdef = isposdef(A)
    solvers = {}
    Aissym && Aisposdef && push!(solvers, cg)
    #push!(solvers, gmres)
    for solver in solvers
        println("$dl_filename: Iterative solve using $solver")
        tic()
        xs, ch = solver(A, b)
        toc()
	r=norm(x-xs)
        println("Residual: $r matvecs: $(ch.mvps) iters: $(length(ch.residuals))")
    end
end


# consider using the project of this directory for tested versions
using PGFPlotsX, KernelDensity, HighestDensityRegions, Distributions, Contour, LinearAlgebra

d = MixtureModel([MultivariateNormal([-1, -1], Diagonal([0.5, 0.5])),
                  MultivariateNormal([1, 1], Diagonal([0.7, 1.5]))], [0.6, 0.4])
x = rand(d, 2000)
x1, x2 = x[1, :], x[2, :]
k = kde((x1, x2))
ik = InterpKDE(k)
ps = pdf.(Ref(ik), x1, x2)
qs = 0.05:0.1:0.95
thresholds = hdr_thresholds(qs, ps)

xgrid = range(minimum(x); stop = maximum(x), length = 100)
pgrid = pdf.(Ref(ik), xgrid, xgrid')

p = @pgf Axis({ xlabel = raw"$x_1$", ylabel = raw"$x_2$", width = "10cm", height = "10cm" },
              Plot({ thick }, Table(contours(xgrid, xgrid, pgrid, thresholds))))
pgfsave("2d-density.svg", p)


using Extremes, DataFrames, Gadfly, Test, Distributions

data = load("portpirie")

x = Variable("x", randn(100))
μ = 10 .+ x.value
σ = 1.0
ξ = .1
pd = GeneralizedExtremeValue.(μ, σ, ξ)
y = rand.(pd)

fm = gevfit(data, :SeaLevel)
fmns = gevfit(y, locationcov=[x])

probplot(fm)
probplot(fmns)

qqplot(fm)
qqplot(fmns)

returnlevelplot(fm)
returnlevelplot(fmns)

histplot(fm)
histplot(fmns)

diagnosticplots(fm)
diagnosticplots(fmns)

fm = gevfitbayes(data, :SeaLevel)
fmns = gevfitbayes(y, locationcov=[x])

probplot(fm)
probplot(fmns)

qqplot(fm)
qqplot(fmns)

returnlevelplot(fm)
returnlevelplot(fmns)

histplot(fm)
histplot(fmns)

diagnosticplots(fm)
diagnosticplots(fmns)

ys = rand(GeneralizedPareto(1,.1),100)

x = Variable("x", randn(100)/3)
ϕ = x.value
σ = exp.(ϕ)
ξ = .1
pd = GeneralizedPareto.(σ, ξ)
y = rand.(pd)

fm = gpfit(ys)
fmns = gpfit(y, logscalecov=[x])

probplot(fm)
probplot(fmns)

qqplot(fm)
qqplot(fmns)

returnlevelplot(fm)
returnlevelplot(fmns)

histplot(fm)
histplot(fmns)

diagnosticplots(fm)
diagnosticplots(fmns)

fm = gpfitbayes(ys)
fmns = gpfitbayes(y, logscalecov=[x])

probplot(fm)
probplot(fmns)

qqplot(fm)
qqplot(fmns)

returnlevelplot(fm)
returnlevelplot(fmns)

histplot(fm)
histplot(fmns)

diagnosticplots(fm)
diagnosticplots(fmns)


using FractionalCalculus
using Test

@testset "Test Fractional Integral" begin
    @test isapprox(fracint(x->x^4, 0.5, 0, 1.23, 1e-8, RL_Direct())[1], 1.163931646862977; atol = 0.00001)
    @test isapprox(fracint(x->x^4, 0.25, 0, 1.23, 1e-8, RL_Direct())[1], 1.64294134724409; atol = 0.00001)
    @test isapprox(fracint(x->x^4, 0.15, 0, 1.23, 1e-8, RL_Direct())[1], 1.878978485456182; atol = 0.00001)
    @test isapprox(fracint(x->sin(x), 0.5, 0, 0.97, 1e-8, RL_Direct())[1], 0.6442601778843754; atol = 0.00001)
    @test isapprox(fracint(x->sin(x), 0.25, 0, 0.97, 1e-8, RL_Direct())[1], 0.7448298999485293; atol = 0.00001)
    @test isapprox(fracint(x->sin(x), 0.15, 0, 0.97, 1e-8, RL_Direct())[1], 0.7802555196986999; atol = 0.00001)
end

@testset "Test Piecewise Fractional Integral" begin
    @test isapprox(fracint(x->x^4, 0.5, 1.23, 1e-4, RL_Piecewise()), 1.163931646862977; atol = 1e-5)
    @test isapprox(fracint(x->x^4, 0.25, 1.23, 1e-4, RL_Piecewise()), 1.64294134724409; atol = 1e-5)
    @test isapprox(fracint(sin, 0.5, 0.97, 1e-4, RL_Piecewise()), 0.6442601778843754; atol = 1e-5)
end


using LinearAlgebra

struct LatticeVars
    # lattice vectors stored column-wise
    avec::Array{Float64,2}
    # magnitude of random displacements added to lattice vectors
    rndavec::Float64
    # inverse of lattice vector matrix
    ainv::Array{Float64,2}
    # reciprocal lattice vectors
    bvec::Array{Float64,2}
    # inverse of reciprocal lattice vector matrix
    binv::Array{Float64,2}
    # unit cell volume
    omega::Float64
    # Brillouin zone volume
    omegabz::Float64
    # any vector with length less than epslat is considered zero
    epslat::Float64
end

#=
case('avec')
  read(50,*,err=20) avec(:,1)
  read(50,*,err=20) avec(:,2)
  read(50,*,err=20) avec(:,3)

avec is stored like lattice vectors in Quantum Espresso
=#

function LatticeVars( LatVecs )
    @assert size(LatVecs,1) == 3
    @assert size(LatVecs,2) == 3

    avec = LatVecs[:,:]
    ainv = inv(avec)

    bvec = 2*pi*inv(avec')
    binv = inv(bvec)

    omega = det(LatVecs)
    omegabz = (2*pi)^3/omega

    epslat = 1e-6
    rndavec = 0.0

    return LatticeVars( avec, rndavec, ainv, bvec, binv, omega, omegabz, epslat )
end


begin
	# Exponential Search

# Julia code to Exponential search x in arr[].
# If x is present then return its location,
# otherwise return -1
import Base:length,show,AbstractArray
arr = [2, 3, 4, 10, 40]
x = 48
n = length(arr)
function binarysearch(arr::AbstractArray{},l,r,x)
    if r >= l
		value=r-l//2
        mid = round(Int,l + (r - l) // 2)
        # If element is present at the middle itself
        if arr[mid] == x
            return mid
        # If element is smaller than mid, then it
        # can only be present in left subarray
		elseif arr[mid] > x
            return binarysearch(arr, l, mid-1, x)
        # Else the element can only be present
        # in right subarray
        else
            return binarysearch(arr, mid + 1, r, x)
		end
    else
        # Element is not present in the array
        return -1
	end
end

# Returns the position of first
# occurrence of x in array
function exponentialsearch(arr::AbstractArray{}, n, x)
    # IF x is present at first
    # location itself
    if arr[1] == x
        return 1
	end
    # Find range for binary search
    # j by repeated doubling
    i = 2
    while i < n+1 && arr[i] <= x
        i = i * 2
	end
	val=round(Int,i/2)
    # Call binary search for the found range
    return binarysearch( arr,val, min(i, n), x)
end
global result=-1

result=exponentialsearch(arr, n, x)

println("Result after function execution:",result)
if result == -1
    println("Element:",x," is not present in array",arr)
else
    println("Element:",x," is present at index:", result," in array",arr)
end
end


### A Pluto.jl notebook ###
# v0.12.7

using Markdown
using InteractiveUtils

# ╔═╡ 6fd616f6-1ea1-11eb-3814-8bfb4a096c49
using Pkg, DrWatson

# ╔═╡ 6ffe2628-1ea1-11eb-24ea-57f985146a72
begin
	@quickactivate "StatisticsWithJuliaPlutoNotebooks"
	using DataFrames
	using HCubature
end;

# ╔═╡ ed174bc4-1ea0-11eb-1e2f-a32874cec549
md"## Listing 3.33"

# ╔═╡ 70179b62-1ea1-11eb-13ce-7fb4d54bad4b
begin
	M = 4.5
	maxD = 10
end

# ╔═╡ dde25fec-228e-11eb-2ec8-099e48158d12
f(x) = (2*pi)^(-length(x)/2) * exp(-(1/2)*x'x)

# ╔═╡ dde2935e-228e-11eb-3074-f3bddb5149fc
begin
	df = DataFrame()
	for n in 1:maxD
    	a = -M*ones(n)
    	b = M*ones(n)
    	I,e = hcubature(f, a, b, maxevals = 10^7)
    append!(df, DataFrame(:n => n, :integral => I, :error => e))
	end
	df
end

# ╔═╡ 70182cd8-1ea1-11eb-094d-8d0d49cf15f3
md"## End of listing 3.33"

# ╔═╡ Cell order:
# ╟─ed174bc4-1ea0-11eb-1e2f-a32874cec549
# ╠═6fd616f6-1ea1-11eb-3814-8bfb4a096c49
# ╠═6ffe2628-1ea1-11eb-24ea-57f985146a72
# ╠═70179b62-1ea1-11eb-13ce-7fb4d54bad4b
# ╠═dde25fec-228e-11eb-2ec8-099e48158d12
# ╠═dde2935e-228e-11eb-3074-f3bddb5149fc
# ╟─70182cd8-1ea1-11eb-094d-8d0d49cf15f3


using ProgressMeter, Plots, StatsBase, Statistics, LaTeXStrings, JLD

function RandomWalker(P,L,X0)
    X = X0
    Tₛ= 0
    while abs(X) != round(Int,L/2)
        X += sample([1,-1], Weights([P,1-P]))
        Tₛ+= 1
    end
    return Tₛ
end

PList = hcat(0:0.01:1)
X0List = hcat(-20:20)
runnum = 10000

Data = zeros(length(X0List),length(PList),2)
progress = Progress(length(X0List)*length(PList)*runnum)

for i in 1:length(X0List)
    X0 = X0List[i]
    for j in 1:length(PList)
        P = PList[j]
        stepruns = []
        for run in 1:runnum
            push!(stepruns,RandomWalker(P,40,X0))
            next!(progress)
            update!(progress)
        end
        Data[i,j,1] = mean(stepruns)
        Data[i,j,2] = std(stepruns)
    end
end

save("../../Data/Q5/Q5-LT.jld", "Data", Data)
Data=load("../../Data/Q5/Q5-LT.jld")["Data"]

P1 = heatmap(0:0.01:1,-20:20,Data[:,:,1], xaxis=nothing,legend = nothing, yaxis=nothing,title = L"Average\ Life\ time")
P2 = contour(0:0.01:1,-20:20,Data[:,:,1], xaxis=nothing, fill = true ,legend = nothing,ylabel = L"X_{init}",title = L"Average\ Life\ time")
P3 = heatmap(0:0.01:1,-20:20,Data[:,:,2], yaxis=nothing, legend = nothing, xlabel = L"P",title = L"STD\ of\ Life\ time")
P4 = contour(0:0.01:1,-20:20,Data[:,:,2], fill = true ,legend = nothing, xlabel = L"P",ylabel = L"X_{init}",title = L"STD\ of\ Life\ time")

Pmain1 = begin
    P_tot = [P2 P4;P1 P3]
    CBar = plot(heatmap((0:400).*ones(401,1),xlabel ="",
        legend=:none, xticks=:none, yticks=(1:40:401, string.(0:40:400))),
            heatmap((0:300).*ones(301,1),xlabel = L"range",
                legend=:none, xticks=:none, yticks=(1:30:301, string.(0:30:300))),
                    layout = (2,1))
    plot(P_tot...,CBar,
        layout = @layout[grid(2,2) a{0.035w}],
        plot_title = L"Life\ time\ of\ a\ Random\ Walker\ (%$runnum \ runs)",size = (800,600))
end
savefig(Pmain1,"../../Figs/Q5/Q5-cont.pdf")

X0Plot = []
for X0 in [11,21,31]
    PLT = begin
        plot(PList,Data[X0,:,1], linestyle = :dot, c = :black)
        scatter!(PList,Data[X0,:,1], yerr = Data[X0,:,2], c = :black, markersize = 1.75)
        scatter!(PList,Data[X0,:,1], ribbon = Data[X0,:,2], markersize = 1.5, c = :purple, markerstrokewidth=0.2)
        plot!(title = L"X_{init} = %$(X0List[X0])",
            xlabel = L"P", ylabel = L"Avg\ Life\ Time", legend = :none)
    end
    push!(X0Plot, PLT)
end

X0P = plot(X0Plot...,layout = (1,3))

PPlot = []
for P in [26,51,76]
    PLT = begin
        plot(X0List,Data[:,P,1], linestyle = :dot, c = :black)
        scatter!(X0List,Data[:,P,1], yerr = Data[:,P,2], c = :black, markersize = 1.75)
        scatter!(X0List,Data[:,P,1], ribbon = Data[:,P,2], markersize = 1.5, c = :steelblue, markerstrokewidth=0.2)
        plot!(title = L"P = %$(PList[P])",
            xlabel = L"X0", ylabel = L"Avg\ Life\ Time", legend = :none)
    end
    push!(PPlot, PLT)
end
PPlot[1]
PP = plot(PPlot...,layout = (1,3))

Pmain2 = plot(PP,X0P,layout = (2,1),size = (850,690), plot_title = L"Life\ time\ of\ a\ Random\ Walker\ (%$runnum \ runs)")
savefig(Pmain2,"../../Figs/Q5/Q5-scat.pdf")


using LinearAlgebra
using Distributions
using StatsBase
using Plots

# Predefined Length
# The number printed at the end is the p-value of rejecting that the sample was
# generated by the MLE of p (which is number_of_up/total)

pathlength = 1000
prob = 0.7

jumps = sample([-1, 1], pweights([1-prob, prob]), pathlength)
path = cumsum(jumps)
counts = let
    c = addcounts!(Dict(-1 => 0, 1 => 0), jumps)
    [c[-1], c[1]]
end

n=length(path) # Number of trials
p=counts[2]/n # What you think value of p is

dist = Binomial(n, p)
threshold = pdf(dist, round(n*p))
I = [pdf(dist, i) for i in 1:n if pdf(dist, i) < threshold]
sum(I)

# Streaming version
pvalues = Float64[]
for t in 1:15
    jumps_t = jumps[1:t]
    path_t = cumsum(jumps_t)
    counts_t = let
        c = addcounts!(Dict(-1 => 0, 1 => 0), jumps_t)
        [c[-1], c[1]]
    end

    n=length(path_t) # Number of trials
    p=counts_t[2]/n # What you think value of p is
    dist = Binomial(n, p)
    threshold = pdf(dist, round(n*p))
    I = [pdf(dist, i) for i in 1:n if pdf(dist, i) < threshold]
    push!(pvalues, sum(I))
end

plot(pvalues, labels = "p-value", legend = :bottomright)

# Single changepoint
pathlength = 1000
prob1 = rand()
prob2 = rand()
changepoint = rand(1:1000)
jumps1 = sample([-1, 1], pweights([1-prob1, prob1]), changepoint)
jumps2 = sample([-1, 1], pweights([1-prob2, prob2]), 1000-changepoint)
jumps = vcat(jumps1, jumps2)
path = cumsum(jumps)
counts = let
    c = addcounts!(Dict(-1 => 0, 1 => 0), jumps)
    [c[-1], c[1]]
end

plot(path, labels="path", xlabel = "Step", ylabel = "Value")

# Streaming version
pvalues = Float64[]
probs = Float64[]
for t in 5:1000
    jumps_t = jumps[1:t]
    path_t = cumsum(jumps_t)
    counts_t = let
        c = addcounts!(Dict(-1 => 0, 1 => 0), jumps_t)
        [c[-1], c[1]]
    end

    n=length(path_t) # Number of trials
    p=counts_t[2]/n # What you think value of p is
    push!(probs, p)

    dist = Binomial(n, p)
    threshold = pdf(dist, round(n*p))
    I = [pdf(dist, i) for i in 1:n if pdf(dist, i) < threshold]
    push!(pvalues, sum(I))
end

plot(probs, legend = :topleft)


using GrupoBeta
using Test

@testset "Algoritmo_QR" begin
  E = [1 1 1; 1 2 1; 1 1 3]
  @test isapprox(autovalores(E), [4.214319 0.0 0.0; 0.0 1.460811 0.0; 0.0 0.0 0.324869], rtol = 1e-4)
  @test isapprox(autovetores(E), [0.39711 0.23319 -0.88765; 0.52065 0.73923 0.42713; 0.75578 -0.63178 0.17214], rtol = 1e-4)
  @test isapprox(iteracoes_QR(E), 24, rtol = 1e-1)
end

@testset "Metodo_potencias" begin
  A = [1 2; 3 2]
  @test isapprox(autovalor_dominante(A), 4, rtol = 1e-4)
  @test isapprox(autovetor_dominante(A), [0.55470; 0.83204], rtol = 1e-4)
  @test isapprox(iteracoes_potencias(A), 10, rtol = 1e-1)
end


function part1(input)
    public_keys = parse.(Int, readlines(input))
    secret_keys = find_log7.(public_keys)
    encryption_key1 = pow(public_keys[1], secret_keys[2])
    encryption_key2 = pow(public_keys[2], secret_keys[1])
    @assert encryption_key1 == encryption_key2
    return encryption_key1
end

function part2(input)
end

function find_log7(n)
    i = 0
    m = 1
    while m != n
        m *= 7
        i += 1
        if m > 20201227
            m = mod(m, 20201227)
        end
    end
    return i
end

function pow(b, n)
    m = 1
    for i = 1:n
        m *= b
        if m > 20201227
            m = mod(m, 20201227)
        end
    end
    return m
end


"""
    cumulants_to_raw_moments(N::Int, max_order::Int)

Express all `N`-variate cumulants ``κ`` up to order given by `max_order`
in terms of raw moments ``μ``. Return a Dictionary mapping from
vector ``\\mathbf{i}`` (that indicates the cumulant ``κ_{\\mathbf{i}}``)
to the corresponding raw moment expressions.

# Example

```julia
cumulants_to_raw_moments(2, 2)

Dict{Any,Any} with 5 entries:
  (1, 0) => μ₁₀(t)
  (2, 0) => μ₂₀(t) - ((μ₁₀(t))^2)
  (0, 1) => μ₀₁(t)
  (0, 2) => μ₀₂(t) - ((μ₀₁(t))^2)
  (1, 1) => μ₁₁(t) - ((μ₀₁(t))*(μ₁₀(t)))
```
"""
function cumulants_to_raw_moments(N::Int, max_order::Int, μ=nothing)

    # following Smith (1995)

    iter_all = construct_iter_all(N, max_order)
    iter_1 = filter(x -> sum(x) == 1, iter_all)

    if μ == nothing
        μ = define_μ(N, max_order, iter_all)
    else
        @assert (μ isa Dict) && length(μ) == length(iter_all) "passed arguments are inconsistent (μ vs N & order)"
    end

    K = Dict()
    μ_star = Dict()

    μ_star[Tuple(fill(0, N))] = 1.0
    for i in 1:N
        eᵢ = iter_1[i]
        K[eᵢ] = μ[eᵢ]
        μ_star[eᵢ] = -μ[eᵢ]
    end

    for order in 2:max_order

        iter_order = filter(x -> sum(x) == order, iter_all)
        for r in iter_order

            ind = findall(x -> x!= 0, r)[end]
            r_sub = r .- iter_1[ind]
            iter_i = filter(x -> all(x .<= r_sub), iter_all)

            suma = 0.0
            for i in iter_i
                factor = 1.0
                for j in 1:N
                    factor *= binomial(r_sub[j], i[j])
                end
                suma += factor*μ[r.-i]*μ_star[i]
            end
            K[r] = simplify(suma)

            suma = 0.0
            for i in iter_i
                factor = 1.0
                for j in 1:N
                    factor *= binomial(r_sub[j], i[j])
                end
                suma += factor*(-K[r.-i])*μ_star[i]
            end
            μ_star[r] = simplify(suma)
        end

    end

    K

end

"""
    cumulants_to_central_moments(N::Int, max_order::Int)

Express all `N`-variate cumulants ``κ`` up to order given by `max_order`
in terms of raw moments ``M``. Return a Dictionary mapping from
vector ``\\mathbf{i}`` (that indicates the cumulant ``κ_{\\mathbf{i}}``)
to the corresponding central moment expressions.
"""
function cumulants_to_central_moments(N::Int, max_order::Int)

    # obtain cumulants up to (m_order)^th order in terms of
    # central moments using formula from Balakrishan et al. (1998)

    K = Dict()
    M_star = Dict()

    iter_all = construct_iter_all(N, max_order)
    iter_1 = filter(x -> sum(x) == 1, iter_all)
    μ = define_μ(N, 1, iter_1)
    M = define_M(N, max_order, iter_all)

    M_star[Tuple(zeros(N))] = 1.0
    for i in 1:N
        eᵢ = iter_1[i]
        K[eᵢ] = μ[eᵢ]
        M_star[eᵢ] = 0.0
    end

    for order in 2:max_order
        # going up through the orders iteratively to build up the expressions (could do recursively?)

        iter_order = filter(x -> sum(x) == order, iter_all)
        for r in iter_order

            ind = findall(x -> x!= 0, r)[end]
            r_sub = r .- iter_1[ind]
            iter_i = filter(x -> all(x .<= r_sub), iter_all)
            # find the cumulant \kappa_{\bm{r}}}
            suma = 0.0
            for i in iter_i
                factor = 1.0
                for j in 1:N
                    factor *= binomial(r_sub[j], i[j])
                end
                suma += factor*M[r.-i]*M_star[i]
            end
            K[r] = simplify(suma)

            # Find the central moment \M^*_{\bm{r}}
            suma = 0.0
            for i in iter_i
                factor = 1.0
                for j in 1:N
                    factor *= binomial(r_sub[j], i[j])
                end
                suma += factor*(-K[r.-i])*M_star[i]
            end
            suma -= -μ[iter_1[ind]]*M_star[r_sub]
            M_star[r] = simplify(suma)

        end

    end

    K

end

function raw_to_central_moments(N::Int, order::Int, μ=nothing; bernoulli=false)

    # Return a dictionary of central moments expressed in terms of raw moments
    # example use:
    # 1 raw_to_central = raw_to_central_moments(2, 3)
    # 2 M₁₂ = raw_to_central[(1,2)] = 2 μ₁₀ μ₀₁² - 2μ₁₁μ₀₁ - μ₀₂μ₁₀ + μ₁₂
    # note that μ is an optional argument which can be used to pass
    # arbitrary values/symbols for each raw moment (different from default μᵢ)

    iter_all = construct_iter_all(N, order)
    iter_μ = filter(x -> sum(x) == 1, iter_all)
    M = define_M(N, order, iter_all)
    if μ == nothing
        μ = define_μ(N, order, iter_all)
    elseif !(μ isa Dict) || length(μ) != length(iter_all)
        if bernoulli
            iter_all = keys(μ)
        else
            error("passed arguments are inconsistent (μ vs N & order)")
        end
    else
        iter_all = construct_iter_all(N, order)
    end
    raw_to_central = Dict()

    for i in iter_all

        iter_j = Iterators.filter(x -> all(x .<= i), iter_all)
        suma = 0.0
        for j in iter_j
            term = μ[i.-j]
            for (k, e_k) in zip(1:N, iter_μ)
                term *= (-1)^(j[k])*binomial(i[k], j[k])*μ[e_k]^j[k]
            end
            suma += term
        end
        raw_to_central[i] = simplify(suma)
    end

    raw_to_central

end

function central_to_raw_moments(N::Int, order::Int)

    # Return a dictionary of raw moments expressed in terms of central moments
    # example use:
    # 1 central_to_raw = central_to_raw_moments(2, 3)
    # 2 μ₁₂ = central_to_raw[(1,2)] = 2 M₁₁ μ₀₁ + M₀₂μ₁₀ + M₁₂ + μ₁₀ μ₀₁²

    iter_all = construct_iter_all(N, order)
    iter_μ = filter(x -> sum(x) == 1, iter_all)

    M = define_M(N, order, iter_all)
    μ = define_μ(N, order, iter_μ)

    central_to_raw = Dict()

    central_to_raw[iter_all[1]] = 1.0
    for i in iter_all[2:end]

        iter_j = Iterators.filter(x -> all(x .<= i), iter_all)
        suma = 0.0
        for j in iter_j
            term = M[i.-j]
            for (k, e_k) in zip(1:N, iter_μ)
                term *= binomial(i[k], j[k])*μ[e_k]^j[k]
            end
            suma += term
        end
        central_to_raw[i] = simplify(suma)
    end

    central_to_raw

end


# This file is a part of AstroLib.jl. License is MIT "Expat".
# Copyright (C) 2016 Mosè Giordano.

function _mphase{T<:AbstractFloat}(jd::T)
    ram, decm, dism = moonpos(jd, radians=true)
    ras, decs = sunpos(jd, radians=true)
    # phi: geocentric elongation of the Moon from the Sun
    # inc: selenocentric (Moon centered) elongation of the Earth from the Sun
    phi = acos(sin(decs)*sin(decm) + cos(decs)*cos(decm)*cos(ras - ram))
    # "dism" is in kilometers, AU in meters
    inc = atan2(AU*sin(phi), dism*1e3 - AU*cos(phi))
    return (1.0 + cos(inc))/2.0
end

"""
    mphase(jd) -> k

### Purpose ###

Return the illuminated fraction of the Moon at given Julian date(s).

### Arguments ###

* `jd`: the Julian ephemeris date.  It can be either a scalar or an array.

### Output ###

The illuminated fraction \$k\$ of Moon's disk, with \$0 \\leq k \\leq 1\$. \$k
= 0\$ indicates a new moon, while \$k = 1\$ stands for a full moon.  If `jd` is
given as an array, an array of the same number of elements as `jd` is returned.

### Method ###

Algorithm from Chapter 46 of "Astronomical Algorithms" by Jean Meeus
(Willmann-Bell, Richmond) 1991.  `sunpos` and `moonpos` are used to get
positions of the Sun and the Moon, and the Moon distance.  The selenocentric
elongation of the Earth from the Sun (phase angle) is then computed, and used to
determine the illuminated fraction.

### Example ###

Plot the illuminated fraction of the Moon for every day in January 2018 with a
hourly sampling.  Use [PyPlot.jl](https://github.com/stevengj/PyPlot.jl) for
plotting

``` julia
using PyPlot
points = DateTime(2018,01,01):Dates.Hour(1):DateTime(2018,01,31,23,59,59);
plot(points, mphase(jdcnv(points)))
```

Note that in this calendar month there are two full moons, this event is called
[blue moon](https://en.wikipedia.org/wiki/Blue_moon).

### Notes ###

Code of this function is based on IDL Astronomy User's Library.
"""
mphase(jd::Real) = _mphase(float(jd))

function mphase{J<:Real}(jd::AbstractArray{J})
    k = similar(jd, float(J))
    for i in eachindex(jd)
        k[i] = mphase(jd[i])
    end
    return k
end