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

using Markdown
using InteractiveUtils

# ╔═╡ 348236ba-8a69-11ec-23a2-3d09e5fc86f2
begin
	using Downloads
	using ARFFFiles
	using ScientificTypes
	using DataFrames
	import StatsBase
	using MLJ
	using MLJDecisionTreeInterface
	using Plots
	using PlutoUI
end

# ╔═╡ d91ebf78-571b-43a6-a091-29c53ed671a3
using AbstractTrees

# ╔═╡ 5825f015-5688-4a8b-8b1b-927f5289bae4
using GraphRecipes

# ╔═╡ 0ffb6837-d03f-421c-8e1f-d5d5142c1621
html"""

Machine Learning using Julia and its ecosystem

If things are not 'ready to use' (Part III)

&copy  Dr. Roland Schätzle

"""

# ╔═╡ 26fe03ce-2744-4a83-8db6-cfa1267dfa81
PlutoUI.TableOfContents(title = "Using a Decision Tree")

# ╔═╡ 4d7fd8ec-9e6f-4d35-8620-9482225951d0
md"""
## Setting up the environment
"""

# ╔═╡ ef618961-3223-4024-b797-79fa1364e0d2
begin
	glass_file = Downloads.download(
		"http://storm.cis.fordham.edu/~gweiss/data-mining/weka-data/glass.arff")
	glass = ARFFFiles.load(DataFrame, glass_file);
end

# ╔═╡ d2863600-a745-43f3-827e-217b27d96fab
begin
	yGlass, XGlass = unpack(glass, ==(:Type), rng = 123)
	MyDecisionTree = @load DecisionTreeClassifier pkg="DecisionTree"
	dc = MyDecisionTree()
	(Xtrain, Xtest), (ytrain, ytest) =
		partition((XGlass, yGlass), 0.7, multi = true, rng = 123)
	dc.max_depth = 3
	dc_mach = machine(dc, Xtrain, ytrain)
	fit!(dc_mach)
end

# ╔═╡ 3fa6c643-25c0-4490-8590-d0268e918421
md"""
# If things are not 'ready to use'
"""

# ╔═╡ 44f81e6d-4b4b-448b-8aa5-068c1b60e18c
md"""
The output of `print_tree()` in part II of the tutorial gives an impression of how the decision tree looks like ... but to be honest, it's a bit rudimentary: It's just ASCII-text and the nodes shwo only the attribute number, not the attribute name which is used for branching.

Wouldn't it be nice, to have a graphical depiction with more information? As there is no ready to use function for this purpose, we have to look on how this can be achieved using other means in the Julia ecosystem.
"""

# ╔═╡ 86bc822a-7616-4958-8d20-4b4efde2932e
md"""
## The building blocks
"""

# ╔═╡ e5261c62-d2f7-4fa0-ab2b-68db4bda6d24
md"""
What do we need to implement this by ourselves? Well, the following ingredients are surely the main building blocks:
1. The decision tree itself (the data structure)
2. Information about how this data structure looks like (internally)
3. A graphics package with the ability to plot trees

... and of course an idea, on how to glue these things together :-)
"""

# ╔═╡ 359b851e-2cd3-4bbd-b502-8266c46f42fb
md"""
### 1. The decision tree
"""

# ╔═╡ 965c5a42-de7c-4f2d-b914-039ae171f81f
md"""
The MLJ function `fitted_params()` delivers for each trained machine all the parameters which result from training. Of course this depends heavily on the model used. In case of a decision tree classifier one of these parameters is simply the tree itself:
"""

# ╔═╡ bcdb446c-43bf-4d3a-af37-7a895117de8c
fp = fitted_params(dc_mach)

# ╔═╡ 4d9e6b5c-4822-4c1c-a12c-15f21158e44b
typeof(fp.tree)

# ╔═╡ 6c07c132-94c7-4fb8-acbf-1e5787dac13a
md"""
### 2. Information about the data structure
"""

# ╔═╡ 8a37cdb4-0ff7-42f8-8c62-5888cc16515b
md"""
In order to get some information about the internal structure of the decision tree, we have to look at the source code of the `DecisionTree.jl` [package](https://github.com/bensadeghi/DecisionTree.jl/blob/468720922bc18bda751bf937b03cac3d26247bbd/src/DecisionTree.jl) on GitHub.

There we find the following definitions for `Leaf` and `Node`:

```Julia
struct Leaf{T}
    majority :: T
    values   :: Vector{T}
end

struct Node{S, T}
    featid  :: Int
    featval :: S
    left    :: Union{Leaf{T}, Node{S, T}}
    right   :: Union{Leaf{T}, Node{S, T}}
end
```

"""

# ╔═╡ 4379bbca-9029-4687-9349-b5c9571cd104
md"""
I.e. the tree structure is made up of `Node`s which store the number of the feature which is used for branching (`featid`) at that node and the threshold (`featval`) at which the branching took place. In addition each node has a `left` and a `right` subtree which is again a `Node` or a `Leaf` (if the bottom of the tree is reached).

The `Leaf`s know the majority class (`majority`) which will be predicted when reaching this leaf as well as a list of all target values (`values`) that have been classified into this leaf.
"""

# ╔═╡ 6dafc7d0-7fed-4012-a9f0-bf249466b6cd
md"""
### 3. A graphics package
"""

# ╔═╡ 12e68c64-bc54-4f53-8d8a-57981fbcb866
md"""
The Julia graphics package [`Plots.jl`](https://github.com/JuliaPlots/Plots.jl) by itself isn't capable of plotting trees. But there is a 'helper' package called [`GraphRecipes.jl`](https://github.com/JuliaPlots/GraphRecipes.jl) which contains several so-called plotting recipes. These are specifications which describe how different graph structures can be plotted using `Plots` (or another graphics package). Among other recipes, there is one for [trees](https://docs.juliaplots.org/stable/graphrecipes/examples/#AbstractTrees-Trees) (called `TreePlot`).

The `GraphRecipes` serve also as an abstraction layer between a structure to be plotted and a graphics package that does the plotting.
"""

# ╔═╡ ceb43211-4f01-47b0-9d27-81d03de3fdfb
md"""
## Bringing it all together
"""

# ╔═╡ 2a93ef90-5495-422a-9550-956610e312d5
md"""
### The basic concepts
"""

# ╔═╡ 4488c8e6-feeb-4258-8d36-f5b0886b0fda
md"""
As we have the main building blocks identified now, the question remains of how we can fit these things together, to obtain the desired result. The main question is: How does the plot recipe `TreePlot` know, what our decision tree looks like in detail, so that it can be plotted by `TreePlot`? Both packages (`DecisionTree.jl` and `GraphRecipes.jl`) have been developed independently. They don't know anything about each other.

The documentation of `TreePlot` tells us, that it expects a structure of type `AbstractTree` (from the package [`AbstractTree.jl`](https://github.com/JuliaCollections/AbstractTrees.jl). But a decision tree from the `DecisionTree.jl` package doesn't conform to this type. So are we stuck now?

We would be stuck, if we were using an 'ordinary' object-oriented language. In this case we could perhaps try to define a new class which inherits from `Node` as well as from `AbstractTree`. But that works only, if the language supports multiple inheritance. If not, we could try to define a new class which inherits from `AbstractTree` and wrap somehow the `Node` and `Leaf` structures inside. All of this involves probably quite a bit of work and doesn't seem to be an elegant solution.

Fortunately we use Julia. Here we only have to (re-)define a few functions from `AbstractTree` on our decision tree, that makes it *look like* an `AbstractTree`. The `TreePlot` recipe expects only a specific *behaviour* from our decision tree (it really doesn't care about the type of this data structure): It wants the tree to have
- a function `children(t)` that, when applied to the tree `t` (or to a node of the tree), returns a list of its subtrees
- and a function `printnode(io::IO, node)` that prints a representation of the node `node` to the output stream `io`.

That's all we need. Then the decision tree conforms to an `AbstractTree` (as far as `TreePlot` is concerned). So let's do it:
"""

# ╔═╡ 476c8e3c-b11f-4451-9256-de9a99d3689f
md"""
### A first and simple implementation
"""

# ╔═╡ 571a4abc-c9e8-47ab-99f8-e8f62e648228
md"""
As we will use some type and function definitions from the packages `DecisionTree` and `AbstractTree`, we have to declare their usage.
"""

# ╔═╡ 2951f22e-99e7-40f9-be2c-3972e8ff47c9
import DecisionTree

# ╔═╡ 89d53141-0675-40ac-8c2b-dd8d9c24b826
md"""
The implementation of `children` is a simple one-line function:
"""

# ╔═╡ e1ff9b54-583b-40c1-b6a7-87711ca47f16
AbstractTrees.children(node::DecisionTree.Node) = (node.left, node.right)

# ╔═╡ 0aa2e192-5443-44ce-a49f-0f5ee435465c
md"""
For printing we have to differentiate between nodes and leafs, because the output of a node looks different from that of a leaf. In most programming languages we would need an implementation that checks the type of the node/leaf to be printed and use an `if ... then ... else`-statement in this case.

Not so in Julia! Here we can use its multiple dispatch capability and implement two versions of `printnode`: One for `Node`s and another one for `Leaf`s. Julia chooses automatically the correct one, depending on the type of the second parameter.
"""

# ╔═╡ 1099149e-1988-40b5-913c-11966285e840
AbstractTrees.printnode(io::IO, node::DecisionTree.Node) =
	print(io, "Feature: ", node.featid, " - Threshold: ", node.featval)

# ╔═╡ ef4ae455-784a-414a-84f5-85cccf4455da
AbstractTrees.printnode(io::IO, leaf::DecisionTree.Leaf) =
	print(io, "maj: ", leaf.majority, " - vals: ", length(leaf.values))

# ╔═╡ a77fff5a-dd21-4254-96a6-f7181625123b
md"""
Here we have chosen a very simple implementation for `printnode` as a first step. The version for `Node` prints the same information as does the built-in `print_tree()` which we've used above (the ID of the feature and the threshold). The variant for `Leaf` is even simpler: It prints the ID of the predicted class and the number of values under consideration in this leaf.
"""

# ╔═╡ b6179be1-30bc-473c-8fc9-8320192f42e4
md"""
The `AbstractTree.jl` package also has a function `print_tree` which does a text based output of a tree using the two functions we've implemented above. Let's use `AbstractTree.print_tree` to test our first implementation:
"""

# ╔═╡ a14c820c-e57b-4307-a96a-9891f3c9a0df
AbstractTrees.print_tree(fp.tree)

# ╔═╡ a4ef1944-b093-4c90-9c2e-8bfa45b29798
md"""
Looks pretty good and all values correspond to the ones in our first printout of the decision tree above. So the implementation seems to work flawlessly!
"""

# ╔═╡ 8e85e7f5-350a-4a85-8877-b2a512c8b814
md"""
And now the graphical representation using `Plots` and `GraphRecipes`: As we already have implemented the necessary functions, we can just call `plot` using a `TreePlot`. That's it!
"""

# ╔═╡ d48b106b-1921-4594-bea7-c9f2bee6cef5
plt = plot(TreePlot(fp.tree), method = :buchheim, markeralpha = 0.5, root = :left,
		nodeshape = :rect, curves = false, shorten = 0.1, fontsize = 12,
		size = (1200, 1200))

# ╔═╡ 85edb2ff-a933-47f0-89d4-676002fdb65b
md"""
### Fine tuning the output
"""

# ╔═╡ 5776968d-0f54-41e8-ba6e-5e29f16febb8
md"""
In the next step we want a tree which shows feature *names* on its nodes and the *names* of the predicted classes on its leafs (instead of the IDs used before). Unfortunately a `DecisionTree` doesn't know this information at all. I.e. we have to add that information somehow so that they can be used by the mechanisms applied in the last section.
"""

# ╔═╡ 95bb56c0-9604-40b2-962e-134348eedc98
md"""
The idea is to add this information while traversing the decision tree using `children`, so that `printnode` has access to it. That's the only place where we need this information. There is no need to change the decision tree structures in any way.

So, instead of returning the `Node` and `Leaf` structures from `DecisionTree` directly, `children` will return enriched structures with added information. These enriched structures are defined as follows:
"""

# ╔═╡ 65f2c840-369b-406a-b9d9-81f8f32990cc
struct NamedNode{S, T}
	info :: NamedTuple
	dt_node :: Union{DecisionTree.Node{S, T}, DecisionTree.Leaf{T}}
end

# ╔═╡ fb689ff3-1906-4043-be75-d94f9e84990c
struct NamedLeaf{T}
	info :: NamedTuple
	dt_leaf :: DecisionTree.Leaf{T}
end

# ╔═╡ 632668d6-bdc3-492b-a028-ec97601329b0
md"""
The attribute `info` within these new `struct`s may contain any information we like to show on the printed tree. `dt_node` and `dt_leaf` are simply the decision tree elements we already used before.
"""

# ╔═╡ cd25e531-a82e-4dd9-b5fc-10278680ee44
md"""
In order to create these enriched structures on each call of `children`, we define a function `wrap_element` with two implementations: One to create a `NamedNode` and a second one to create a `NamedLeaf`. This is another situation where we rely on the multiple dispatch mechanism of Julia. Depending on the type of the second argument (a `Node` or a `Leaf`) the correct method will be chosen.
"""

# ╔═╡ 5adac17a-d13b-4759-a3d1-3a5364ae0746
wrap_element(infos::NamedTuple, dt_node::DecisionTree.Node) =
	NamedNode(infos, dt_node)

# ╔═╡ 1345a07d-1b73-4257-b15d-9b1e6fcfc19e
wrap_element(infos::NamedTuple, dt_leaf::DecisionTree.Leaf) =
	NamedLeaf(infos, dt_leaf)

# ╔═╡ e57d3aa8-4d2d-4595-886d-234c1d7d44db
md"""
This makes the implementation of our new `children` function quite easy: Just two calls to `makeNamedElement`, where we add the attribute names and the class names as parameters (as a `NamedTuple`; a Julia standard type which comes in handy here).
"""

# ╔═╡ f62753ae-5746-41b3-975c-75f6c2ba7e14
AbstractTrees.children(node::NamedNode) = (
	wrap_element((atr = names(XGlass), cls = levels(yGlass)), node.dt_node.left),
	wrap_element((atr = names(XGlass), cls = levels(yGlass)), node.dt_node.right)
)

# ╔═╡ 090871c6-63ad-4c10-af20-ce3b25cd3337
md"""
The implementations of `printnode` receive now a `NamedNode` or a `NamedLeaf` and can use the information within these elements for printing:
"""

# ╔═╡ 27ea6187-2303-4ca5-8acd-b9f9600acb5d
function AbstractTrees.printnode(io::IO, node::NamedNode)
	print(io, node.info.atr[node.dt_node.featid], " → ", node.dt_node.featval)
end

# ╔═╡ 98fe2763-00e7-4f8a-9b8f-da58cf56facc
function AbstractTrees.printnode(io::IO, leaf::NamedLeaf)
	matches     = findall(leaf.dt_leaf.values .== leaf.dt_leaf.majority)
	match_count = length(matches)
	val_count   = length(leaf.dt_leaf.values)
	print(io, leaf.info.cls[leaf.dt_leaf.majority], " ($match_count/$val_count)")
end

# ╔═╡ 387185f5-50a4-4b6b-9f2e-31f38dd190b3
md"""
`matches` are the instances which have been correctly classified on this leaf (out of all instances on this leaf in `values`).
"""

# ╔═╡ b63e004a-6e6f-4591-abc0-a3e26c684fdf
md"""
Now we can create a `NamedNode` for the root of the decision tree and use it for printing. First using `print_tree` and then using `plot` with the `TreePlot` recipe to obtain the desired result.
"""

# ╔═╡ eb824384-08fd-4071-9b51-4da8e85bc2ea
nn = NamedNode((atr = names(XGlass), cls = levels(yGlass)), fp.tree)

# ╔═╡ 36dedce2-2763-4d17-ac4c-d5480538fb51
AbstractTrees.print_tree(nn)

# ╔═╡ 74a38c54-ccca-430d-b4cc-3f54dbee9a23
plt2 = plot(TreePlot(nn), method = :buchheim, root = :left, nodeshape = :rect,
		markeralpha = 0.5, fontsize = 12, nodesize = 0.1,
		curves = false, shorten = 0.1,
		size = (1200, 1200))

# ╔═╡ 3cc12cde-20cf-4527-a8b4-441ccaebd618
md"""
And finally a few explanations about the parameters used in the call to `plot`:
- `method`, `root` and `nodeshape` are the basic parameters, which choose the layout algorithm (`buchheim`), the orientation of the tree (`left` = from left to right) and the shape of the nodes (`rect` = rectangles).
- the remaining parameters are just for beautifying the tree:
  - a `markeralpha` of 0.5 gives the nodes a bit of transparency
  - `fontsize` sets the size of the font (a bit larger than the default)
  - a `nodesize` of 0.1 makes the nodes a bit larger than the default
  - with `curves = false` we get straight lines between the nodes
  - `shorten` avoids that the connecting lines interfere with the contents of the nodes
  - `size` sets the resolution for the plot.
"""

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
ARFFFiles = "da404889-ca92-49ff-9e8b-0aa6b4d38dc8"
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
DecisionTree = "7806a523-6efd-50cb-b5f6-3fa6f1930dbb"
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
GraphRecipes = "bd48cda9-67a9-57be-86fa-5b3c104eda73"
MLJ = "add582a8-e3ab-11e8-2d5e-e98b27df1bc7"
MLJDecisionTreeInterface = "c6f25543-311c-4c74-83dc-3ea6d1015661"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
ScientificTypes = "321657f4-b219-11e9-178b-2701a2544e81"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"

[compat]
ARFFFiles = "~1.4.1"
AbstractTrees = "~0.3.4"
DataFrames = "~1.3.2"
DecisionTree = "~0.10.11"
GraphRecipes = "~0.5.9"
MLJ = "~0.17.3"
MLJDecisionTreeInterface = "~0.2.1"
Plots = "~1.27.0"
PlutoUI = "~0.7.37"
ScientificTypes = "~3.0.0"
StatsBase = "~0.33.16"
"""

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

julia_version = "1.8.0-DEV.1390"
manifest_format = "2.0"
project_hash = "77e82a66748627a11c44e128f5ae20f53de3936c"

[[deps.ARFFFiles]]
deps = ["CategoricalArrays", "Dates", "Parsers", "Tables"]
git-tree-sha1 = "e8c8e0a2be6eb4f56b1672e46004463033daa409"
uuid = "da404889-ca92-49ff-9e8b-0aa6b4d38dc8"
version = "1.4.1"

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

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

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

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

[[deps.ArnoldiMethod]]
deps = ["LinearAlgebra", "Random", "StaticArrays"]
git-tree-sha1 = "62e51b39331de8911e4a7ff6f5aaf38a5f4cc0ae"
uuid = "ec485272-7323-5ecc-a04f-4719b315124d"
version = "0.2.0"

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

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

[[deps.BSON]]
git-tree-sha1 = "306bb5574b0c1c56d7e1207581516c557d105cad"
uuid = "fbb218c0-5317-5bc6-957e-2ee96dd4b1f0"
version = "0.3.5"

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

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

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

[[deps.Calculus]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad"
uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
version = "0.5.1"

[[deps.CategoricalArrays]]
deps = ["DataAPI", "Future", "Missings", "Printf", "Requires", "Statistics", "Unicode"]
git-tree-sha1 = "5196120341b6dfe3ee5f33cf97392a05d6fe80d0"
uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597"
version = "0.10.4"

[[deps.CategoricalDistributions]]
deps = ["CategoricalArrays", "Distributions", "Missings", "OrderedCollections", "Random", "ScientificTypesBase", "UnicodePlots"]
git-tree-sha1 = "8c340dc71d2dc9177b1f701726d08d2255d2d811"
uuid = "af321ab8-2d2e-40a6-b165-3d674595d28e"
version = "0.1.5"

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

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

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

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

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

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

[[deps.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 = "96b0bc6c52df76506efc8a441c6cf1adcb1babc4"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.42.0"

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

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

[[deps.ConstructionBase]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "f74e9d5388b8620b4cee35d4c5a618dd4dc547f4"
uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
version = "1.3.0"

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

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

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

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

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

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

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

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

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

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

[[deps.Distances]]
deps = ["LinearAlgebra", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "3258d0659f812acde79e8a74b11f17ac06d0ca04"
uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
version = "0.10.7"

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

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

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

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

[[deps.DualNumbers]]
deps = ["Calculus", "NaNMath", "SpecialFunctions"]
git-tree-sha1 = "90b158083179a6ccbce2c7eb1446d5bf9d7ae571"
uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74"
version = "0.6.7"

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

[[deps.EarlyStopping]]
deps = ["Dates", "Statistics"]
git-tree-sha1 = "98fdf08b707aaf69f524a6cd0a67858cefe0cfb6"
uuid = "792122b4-ca99-40de-a6bc-6742525f08b6"
version = "0.3.0"

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

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

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

[[deps.FilePathsBase]]
deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"]
git-tree-sha1 = "04d13bfa8ef11720c24e4d840c0033d145537df7"
uuid = "48062228-2e41-5def-b9a4-89aafe57970f"
version = "0.9.17"

[[deps.FileWatching]]
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[deps.GraphRecipes]]
deps = ["AbstractTrees", "GeometryTypes", "Graphs", "InteractiveUtils", "Interpolations", "LinearAlgebra", "NaNMath", "NetworkLayout", "PlotUtils", "RecipesBase", "SparseArrays", "Statistics"]
git-tree-sha1 = "1735085e3a8dd0e14020bdcbf8da9893a5508a3f"
uuid = "bd48cda9-67a9-57be-86fa-5b3c104eda73"
version = "0.5.9"

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

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

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

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

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

[[deps.HypergeometricFunctions]]
deps = ["DualNumbers", "LinearAlgebra", "SpecialFunctions", "Test"]
git-tree-sha1 = "65e4589030ef3c44d3b90bdc5aac462b4bb05567"
uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
version = "0.3.8"

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

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

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

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

[[deps.IniFile]]
git-tree-sha1 = "f550e6e32074c939295eb5ea6de31849ac2c9625"
uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
version = "0.5.1"

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

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

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

[[deps.InvertedIndices]]
git-tree-sha1 = "bee5f1ef5bf65df56bdd2e40447590b272a5471f"
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
version = "1.1.0"

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

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

[[deps.IterationControl]]
deps = ["EarlyStopping", "InteractiveUtils"]
git-tree-sha1 = "83c84b7b87d3063e48a909a86c3c5bf4c3521962"
uuid = "b3c1a2ee-3fec-4384-bf48-272ea71de57c"
version = "0.5.2"

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

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

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

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

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

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

[[deps.LERC_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "bf36f528eec6634efc60d7ec062008f171071434"
uuid = "88015f11-f218-50d7-93a8-a6af411a945d"
version = "3.0.0+1"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[deps.MLJDecisionTreeInterface]]
deps = ["DecisionTree", "MLJModelInterface", "Random", "Tables"]
git-tree-sha1 = "8cf2bb326b2d7d8a81c2b14e709dc2aeeb25bbc6"
uuid = "c6f25543-311c-4c74-83dc-3ea6d1015661"
version = "0.2.1"

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

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

[[deps.MLJModelInterface]]
deps = ["Random", "ScientificTypesBase", "StatisticalTraits"]
git-tree-sha1 = "74d7fb54c306af241c5f9d4816b735cb4051e125"
uuid = "e80e1ace-859a-464e-9ed9-23947d8ae3ea"
version = "1.4.2"

[[deps.MLJModels]]
deps = ["CategoricalArrays", "CategoricalDistributions", "Dates", "Distances", "Distributions", "InteractiveUtils", "LinearAlgebra", "MLJModelInterface", "Markdown", "OrderedCollections", "Parameters", "Pkg", "PrettyPrinting", "REPL", "Random", "ScientificTypes", "StatisticalTraits", "Statistics", "StatsBase", "Tables"]
git-tree-sha1 = "f6f971456d38f020ce476283e1c27f2481bf99ac"
uuid = "d491faf4-2d78-11e9-2867-c94bc002c0b7"
version = "0.15.6"

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

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

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

[[deps.MarchingCubes]]
deps = ["StaticArrays"]
git-tree-sha1 = "5f768e0a0c3875df386be4c036f78c8bd4b1a9b6"
uuid = "299715c1-40a9-479a-aaf9-4a633d36f717"
version = "0.1.2"

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

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

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

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

[[deps.Memento]]
deps = ["Dates", "Distributed", "Requires", "Serialization", "Sockets", "Test", "UUIDs"]
git-tree-sha1 = "9b0b0dbf419fbda7b383dc12d108621d26eeb89f"
uuid = "f28f55f0-a522-5efc-85c2-fe41dfb9b2d9"
version = "1.3.0"

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

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

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

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

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

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

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

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

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

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

[[deps.OpenML]]
deps = ["ARFFFiles", "HTTP", "JSON", "Markdown", "Pkg"]
git-tree-sha1 = "06080992e86a93957bfe2e12d3181443cedf2400"
uuid = "8b6db2d4-7670-4922-a472-f9537c81ab66"
version = "0.2.0"

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

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

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

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

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

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

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

[[deps.Parsers]]
deps = ["Dates"]
git-tree-sha1 = "85b5da0fa43588c75bb1ff986493443f821c70b7"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.2.3"

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

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

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

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

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

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

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

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

[[deps.PrettyPrinting]]
git-tree-sha1 = "4be53d093e9e37772cc89e1009e8f6ad10c4681b"
uuid = "54e16d92-306c-5ea0-a30b-337be88ac337"
version = "0.4.0"

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

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

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

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

[[deps.QuadGK]]
deps = ["DataStructures", "LinearAlgebra"]
git-tree-sha1 = "78aadffb3efd2155af139781b8a8df1ef279ea39"
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
version = "2.4.2"

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

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

[[deps.Ratios]]
deps = ["Requires"]
git-tree-sha1 = "dc84268fe0e3335a62e315a3a7cf2afa7178a734"
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
version = "0.4.3"

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

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

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

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

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

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

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

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

[[deps.ScientificTypes]]
deps = ["CategoricalArrays", "ColorTypes", "Dates", "Distributions", "PrettyTables", "Reexport", "ScientificTypesBase", "StatisticalTraits", "Tables"]
git-tree-sha1 = "ba70c9a6e4c81cc3634e3e80bb8163ab5ef57eb8"
uuid = "321657f4-b219-11e9-178b-2701a2544e81"
version = "3.0.0"

[[deps.ScientificTypesBase]]
git-tree-sha1 = "a8e18eb383b5ecf1b5e6fc237eb39255044fd92b"
uuid = "30f210dd-8aff-4c5f-94ba-8e64358c1161"
version = "3.0.0"

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

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

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

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

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

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

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

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

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

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

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

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

[[deps.StatisticalTraits]]
deps = ["ScientificTypesBase"]
git-tree-sha1 = "271a7fea12d319f23d55b785c51f6876aadb9ac0"
uuid = "64bff920-2084-43da-a3e6-9bb72801c0c9"
version = "3.0.0"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[deps.UnicodePlots]]
deps = ["Contour", "Crayons", "Dates", "LinearAlgebra", "MarchingCubes", "NaNMath", "SparseArrays", "StaticArrays", "StatsBase", "Unitful"]
git-tree-sha1 = "1785494cb9484f9ab05bbc9d81a2d4de4341eb39"
uuid = "b8865327-cd53-5732-bb35-84acbb429228"
version = "2.9.0"

[[deps.Unitful]]
deps = ["ConstructionBase", "Dates", "LinearAlgebra", "Random"]
git-tree-sha1 = "b649200e887a487468b71821e2644382699f1b0f"
uuid = "1986cc42-f94f-5a68-af5c-568840ba703d"
version = "1.11.0"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

# ╔═╡ Cell order:
# ╟─0ffb6837-d03f-421c-8e1f-d5d5142c1621
# ╟─26fe03ce-2744-4a83-8db6-cfa1267dfa81
# ╟─4d7fd8ec-9e6f-4d35-8620-9482225951d0
# ╠═348236ba-8a69-11ec-23a2-3d09e5fc86f2
# ╠═ef618961-3223-4024-b797-79fa1364e0d2
# ╠═d2863600-a745-43f3-827e-217b27d96fab
# ╟─3fa6c643-25c0-4490-8590-d0268e918421
# ╟─44f81e6d-4b4b-448b-8aa5-068c1b60e18c
# ╟─86bc822a-7616-4958-8d20-4b4efde2932e
# ╟─e5261c62-d2f7-4fa0-ab2b-68db4bda6d24
# ╟─359b851e-2cd3-4bbd-b502-8266c46f42fb
# ╟─965c5a42-de7c-4f2d-b914-039ae171f81f
# ╠═bcdb446c-43bf-4d3a-af37-7a895117de8c
# ╠═4d9e6b5c-4822-4c1c-a12c-15f21158e44b
# ╟─6c07c132-94c7-4fb8-acbf-1e5787dac13a
# ╟─8a37cdb4-0ff7-42f8-8c62-5888cc16515b
# ╟─4379bbca-9029-4687-9349-b5c9571cd104
# ╟─6dafc7d0-7fed-4012-a9f0-bf249466b6cd
# ╟─12e68c64-bc54-4f53-8d8a-57981fbcb866
# ╟─ceb43211-4f01-47b0-9d27-81d03de3fdfb
# ╟─2a93ef90-5495-422a-9550-956610e312d5
# ╟─4488c8e6-feeb-4258-8d36-f5b0886b0fda
# ╟─476c8e3c-b11f-4451-9256-de9a99d3689f
# ╟─571a4abc-c9e8-47ab-99f8-e8f62e648228
# ╠═2951f22e-99e7-40f9-be2c-3972e8ff47c9
# ╠═d91ebf78-571b-43a6-a091-29c53ed671a3
# ╟─89d53141-0675-40ac-8c2b-dd8d9c24b826
# ╠═e1ff9b54-583b-40c1-b6a7-87711ca47f16
# ╟─0aa2e192-5443-44ce-a49f-0f5ee435465c
# ╠═1099149e-1988-40b5-913c-11966285e840
# ╠═ef4ae455-784a-414a-84f5-85cccf4455da
# ╟─a77fff5a-dd21-4254-96a6-f7181625123b
# ╟─b6179be1-30bc-473c-8fc9-8320192f42e4
# ╠═a14c820c-e57b-4307-a96a-9891f3c9a0df
# ╟─a4ef1944-b093-4c90-9c2e-8bfa45b29798
# ╟─8e85e7f5-350a-4a85-8877-b2a512c8b814
# ╠═5825f015-5688-4a8b-8b1b-927f5289bae4
# ╠═d48b106b-1921-4594-bea7-c9f2bee6cef5
# ╟─85edb2ff-a933-47f0-89d4-676002fdb65b
# ╟─5776968d-0f54-41e8-ba6e-5e29f16febb8
# ╟─95bb56c0-9604-40b2-962e-134348eedc98
# ╠═65f2c840-369b-406a-b9d9-81f8f32990cc
# ╠═fb689ff3-1906-4043-be75-d94f9e84990c
# ╟─632668d6-bdc3-492b-a028-ec97601329b0
# ╟─cd25e531-a82e-4dd9-b5fc-10278680ee44
# ╠═5adac17a-d13b-4759-a3d1-3a5364ae0746
# ╠═1345a07d-1b73-4257-b15d-9b1e6fcfc19e
# ╟─e57d3aa8-4d2d-4595-886d-234c1d7d44db
# ╠═f62753ae-5746-41b3-975c-75f6c2ba7e14
# ╟─090871c6-63ad-4c10-af20-ce3b25cd3337
# ╠═27ea6187-2303-4ca5-8acd-b9f9600acb5d
# ╠═98fe2763-00e7-4f8a-9b8f-da58cf56facc
# ╟─387185f5-50a4-4b6b-9f2e-31f38dd190b3
# ╟─b63e004a-6e6f-4591-abc0-a3e26c684fdf
# ╠═eb824384-08fd-4071-9b51-4da8e85bc2ea
# ╠═36dedce2-2763-4d17-ac4c-d5480538fb51
# ╠═74a38c54-ccca-430d-b4cc-3f54dbee9a23
# ╟─3cc12cde-20cf-4527-a8b4-441ccaebd618
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_path: notebooks/ML-Tutorial 3 - If things are not ready to use.jl

max_stars_repo_name: roland-KA/JuliaForMLTutorial

max_issues_repo_name: roland-KA/JuliaForMLTutorial

max_forks_repo_name: roland-KA/JuliaForMLTutorial


text:
import Base: getindex
using CUDA: CuArray, CuPtr
using Knet.LibKnet8: @knet8
using Knet.KnetArrays: checkbetween

## Indexing with Int array: used in nll.

function getindex(x::CuArray{T}, i::AbstractArray{I}) where {T,I<:Real}
    y = similar(x, size(i))
    if isempty(y); return y; end
    i = Array{Int32}(i)
    checkbetween(i, 1, length(x))
    unsafe_getindex!(x,y,CuArray{Int32}(i))
    return y
end

for F in (32,64); T=Symbol("Float$F"); @eval begin

## Indexing with CuArray{Int32}: low level, only Int32 supported, no bounds checking

    function unsafe_getindex!(x::CuArray{$T}, y::CuArray{$T}, i::CuArray{Int32})
        @knet8($("getents_$F"),(Cint,CuPtr{Int},CuPtr{$T},CuPtr{$T}), length(i), i, x, y)
        return y
    end

end; end

ext: jl


text:
module MLJ

## METHOD EXPORT

export MLJ_VERSION

# utilities.jl:
export @curve, @pcurve, pretty

# resampling.jl:
export Holdout, CV, StratifiedCV, evaluate!, Resampler

# parameters.jl:
export Params, iterator

# tuning.jl:
export Grid, TunedModel

# learning_curves.jl
export learning_curve!, learning_curve

# ensembles.jl:
export EnsembleModel

# model_matching.jl:
export matching

# tasks.jl (deprecated):
export supervised, unsupervised

## METHOD RE-EXPORT

# re-export from Random, Statistics, Distributions, CategoricalArrays:
export pdf, mode, median, mean, shuffle!, categorical, shuffle,
    levels, levels!, std, support

# re-export from ScientificTypes:
export GrayImage, ColorImage, Image,
    Found, Continuous, Finite, Infinite,
    OrderedFactor, Unknown,
    Count, Multiclass, Binary, Scientific,
    scitype, scitype_union, coerce, schema, autotype, elscitype

# re-export from MLJBase:
export nrows, nfeatures, color_off, color_on,
    selectrows, selectcols, restrict, corestrict, complement,
    SupervisedTask, UnsupervisedTask, MLJTask,
    Deterministic, Probabilistic, Unsupervised, Supervised, Static,
    DeterministicNetwork, ProbabilisticNetwork,
    target_scitype, input_scitype, output_scitype,
    predict, predict_mean, predict_median, predict_mode,
    transform, inverse_transform, se, evaluate, fitted_params, params,
    @constant, @more, HANDLE_GIVEN_ID, UnivariateFinite,
    classes, table, report, rebind!,
    partition, unpack,
    default_measure, measures,
    @load_boston, @load_ames, @load_iris, @load_reduced_ames, @load_crabs,
    load_boston, load_ames, load_iris, load_reduced_ames, load_crabs,
    Machine, NodalMachine, machine, AbstractNode,
    source, node, fit!, freeze!, thaw!, Node, sources, origins,
    machines, sources, anonymize!, @from_network, fitresults,
    @pipeline

# re-export from MLJBase - relating to measures:
export measures,
    orientation, reports_each_observation,
    is_feature_dependent, aggregation,
    aggregate,
    default_measure, value,
    mav, mae, rms, rmsl, rmslp1, rmsp, l1, l2,
    confusion_matrix, confmat,
    cross_entropy, BrierScore,
    misclassification_rate, mcr, accuracy,
    balanced_accuracy, bacc, bac,
    matthews_correlation, mcc,
    auc, roc_curve, roc,
    TruePositive, TrueNegative, FalsePositive, FalseNegative,
    TruePositiveRate, TrueNegativeRate, FalsePositiveRate, FalseNegativeRate,
    FalseDiscoveryRate, Precision, NPV, FScore,
    TPR, TNR, FPR, FNR,
    FDR, PPV,
    Recall, Specificity, BACC,
    truepositive, truenegative, falsepositive, falsenegative,
    truepositive_rate, truenegative_rate, falsepositive_rate,
    falsenegative_rate, negativepredicitive_value,
    positivepredictive_value,
    tp, tn, fp, fn, tpr, tnr, fpr, fnr,
    falsediscovery_rate, fdr, npv, ppv,
    recall, sensitivity, hit_rate, miss_rate,
    specificity, selectivity, f1score, f1, fallout

# re-export from MLJModels:
export models, localmodels, @load, load, info,
    ConstantRegressor, ConstantClassifier,     # builtins/Constant.jl
    StaticTransformer, FeatureSelector,        # builtins/Transformers.jl
    UnivariateStandardizer, Standardizer,
    UnivariateBoxCoxTransformer,
    OneHotEncoder, UnivariateDiscretizer,
    FillImputer

## METHOD IMPORT

# from the Standard Library:
import Distributed: @distributed, nworkers, pmap
import Pkg
import Pkg.TOML

# from the MLJ universe:
using ScientificTypes
using MLJBase
import MLJBase
using MLJModels

using Tables
using OrderedCollections
using  CategoricalArrays
import Distributions
import Distributions: pdf, mode
import Statistics, StatsBase, LinearAlgebra, Random
import Random: AbstractRNG, MersenneTwister
using ProgressMeter
import PrettyTables
using ComputationalResources
using ComputationalResources: CPUProcesses
using DocStringExtensions: SIGNATURES, TYPEDEF
using RecipesBase

# to be extended:
import MLJBase: fit, update, clean!, fit!,
    predict, predict_mean, predict_median, predict_mode,
    transform, inverse_transform, se, evaluate, fitted_params,
    show_as_constructed, ==, getindex, setindex!
import MLJModels: models

## CONSTANTS

const DEFAULT_RESOURCE = Ref{AbstractResource}(CPU1())
const srcdir = dirname(@__FILE__)
const CategoricalElement = Union{CategoricalString,CategoricalValue}

# FIXME replace with either Pkg.installed()["MLJ"] or
# uuid = Pkg.project().dependencies["MLJ"]
# version = Pkg.dependencies()[uuid].version
# ---
# this is currently messy because it's been enacted then reverted
# see https://github.com/JuliaLang/julia/pull/33410
# and https://github.com/JuliaLang/Pkg.jl/pull/1086/commits/996c6b9b69ef0c058e0105427983622b7cc8cb1d
toml = Pkg.TOML.parsefile(joinpath(dirname(dirname(pathof(MLJ))), "Project.toml"))
const MLJ_VERSION = toml["version"]

## INCLUDE FILES

include("utilities.jl")     # general purpose utilities
include("resampling.jl")    # resampling strategies and model evaluation
include("parameters.jl")    # hyperparameter ranges and grid generation
include("tuning.jl")
include("learning_curves.jl")
include("ensembles.jl")     # homogeneous ensembles
include("model_matching.jl")# inferring model search criterion from data
include("tasks.jl")         # enhancements to MLJBase task interface
include("scitypes.jl")      # extensions to ScientificTypes.scitype
include("plotrecipes.jl")

end # module


text:
# Simulate a 2D actomyosin network
# Alex Tam, 12/10/2020

# Simulate network
"Control function for actomyosin network simulations"
function actomyosin_network(parN, parA, parM)
    # Specify domain width
    Lxx::Float64 = 2.0; Lxy::Float64 = 0; Lyx::Float64 = 0; Lyy::Float64 = 2.0; # Actual domain widths
    # Pre-allocate
    Force = [[0.0, 0.0, 0.0, 0.0] for idx in 1:parN.nT]; # [pN] Network force
    Bulk_Stress = [0.0 for idx in 1:parN.nT]; # Bulk stress
    Motor_Pos = [0.0 for idx in 1:parN.nT]; # Bulk stress
    Curvature = [0.0 for idx in 1:parN.nT]; # Mean filament curvature
    Index = [0.0 for idx in 1:parN.nT]; # Two-filament index
    Theta = [0.0 for idx in 1:parN.nT]; # Angle between filaments
    # Generate initial conditions
    state = State{Float64}(Vector{Vector{Vector}}(), Vector{Vector}()); # Initialise empty State struct
    mm = Vector{Myosin_Motor}(); # Pre-allocate empty myosin motors
    af, state = actin_ic(state, parN, parA, Lxx, Lyy); # Initialise actin filaments
    xl = intersection_search(state, af, mm); # Initialise cross-links
    mm, xl, state = myosin_ic(state, mm, parN, xl, Lxx, Lxy, Lyx, Lyy); # Initialise myosin motors
    state_old = state; # Store initial state to compute force
    # Time-stepping
    animation = @animate for i = 1:parN.nT
        # Compute force and draw network
        Force[i] = network_force(state, state_old, af, xl, mm, parN, parA, parM, Lxx, Lxy, Lyx, Lyy);
        draw_network(state, af, mm, parN, parA, Force[i], Lxx, Lxy, Lyx, Lyy);
        savefig("2f-$i.svg"); # Save image
        # Spatial statistics
        if parA.nSeg > 1
            Curvature[i] = curvature(af, state, Lxx, Lxy, Lyx, Lyy); # Compute curvature at current time step
        else
            Curvature[i] = 0;
        end
        Index[i], Theta[i] = two_filament_index(mm, state, Lxx, Lxy, Lyx, Lyy); # Compute two-filament index at current time step
        Bulk_Stress[i] = 0.5*(Force[i][1]/Lyy + Force[i][4]/Lxx);
        Motor_Pos[i] = 0.5*(state.mp[1][1]+state.mp[1][2]);
        # Compute solution
        if i != parN.nT # Ensure correct looping sequence
            # Turnover and polymerisation
            af = segment_translations(state, af); # Update filament translations
            state_old = state; # Store current state for energy functional
            # Compute network solution
            new_dof = optimise_network(state_old, af, mm, parN, parA, parM, Lxx, Lxy, Lyx, Lyy);
            state = build_state(new_dof, af, mm); # Construct State from vector
        end
    end
    # Output
    gif(animation, "2f.gif", fps = 50) # Save .gif of the network
    # Plot quantities versus time
    draw_stress(parN, Force, parN.nT, Lxx, Lyy); savefig("2f_stress.svg"); # Stress components
    draw_bulk_stress(parN, Force, parN.nT, Lxx, Lyy); savefig("2f_bulk_stress.svg"); # Bulk stress
    draw_angle(parN, Theta, parN.nT); savefig("2f_angle.svg"); # Angle
    # Write data to files
    writedlm("2f_angle.csv", Theta);
    writedlm("2f_index.csv", Index);
    writedlm("2f_bulk_stress.csv", Bulk_Stress);
    writedlm("2f_motor_pos.csv", Motor_Pos);
    # Compute time-integrated statistics
    Curvature_Int, Index_Int = integrated_statistics(parN, Curvature, Index);
    return state, af, mm, Force, Curvature_Int, Index_Int
end


text:
using StaticArrays
using LinearAlgebra
using Optim

function random_axis(t::Type{T}) where T <: AbstractFloat
    θ = rand(t)*2*π
    ϕ = acos(2*rand(t)-1)
    return SA[sin(ϕ)*cos(θ), sin(ϕ)*sin(θ), cos(ϕ)]
end

function random_rotation(t::Type{T}) where T <: AbstractFloat
    small = T(0.1)
    r0 = random_axis(t)
    dum = zero(T)
    while dum < small
        r1 = random_axis(t)
        r1 -= (r1 ⋅ r0)*r0
        dum = norm(r1)
    end
    r1 /= dum
    r2 = r0 × r1
    return hcat(r0, r1, r2)
end

function euler_angles(R)
    cos_θ = R[3, 3]
    sin_θ_sq = 1 - cos_θ^2

    if sin_θ_sq < 1e-11
        θ = acos(cos_θ)
        ψ = zero(eltype(R))
        ϕ = mod(atan(R[2, 1], R[1, 1]), 2π)
        return SA[ϕ, θ, ψ]
    end

    θ = acos(cos_θ)
    ϕ = mod(atan(R[1, 3], -R[2, 3]), 2π)
    ψ = mod(atan(R[3, 1], R[3, 2]), 2π)

    return SA[ϕ, θ, ψ]
end

function prepare_inclusions(vol_frac_goal::AbstractFloat, L::AbstractFloat, inclusiontype::Type, generator)
    ftype = typeof(L)
    total_volume = L^3

    # Make random grains
    total_inclusion_volume = zero(ftype)
    inclusions = inclusiontype[]
    while total_inclusion_volume < vol_frac_goal * total_volume
        midpoint = L * @SVector rand(ftype, 3)
        rot = random_rotation(ftype)
        inclusion = generator(midpoint, rot)
        push!(inclusions, inclusion)
        total_inclusion_volume += volume(inclusion)
    end

    return inclusions
end

function voxelize(shape, L::AbstractFloat, M::Integer)
    delta_x = L/M

    # Inexpensive bounding box of prism to limit the voxels to check:
    lower, upper = bounding_box(shape)
    loweri = floor.(typeof(M), lower*M/L)
    upperi = ceil.(typeof(M), upper*M/L)

    voxel_indices = Array{SVector{3, typeof(M)},1}(undef, prod(Int32.(upperi - loweri)))
    total_voxels = 0
    for iz in loweri[3]:upperi[3], iy in loweri[2]:upperi[2], ix in loweri[1]:upperi[1]
        i = SA[ix, iy, iz]
        r = delta_x .* (0.5 .+ i)
        if inside(shape, r)
            total_voxels += 1
            voxel_indices[total_voxels] = i
        end
    end
    return voxel_indices[1:total_voxels]
end

function pack_inclusions!(inclusions::AbstractArray, M::T, L::AbstractFloat, nr_tries::Integer, Δ::T) where T<:Integer
    grain_count_type = Int16
    grain_ids = zeros(grain_count_type, M, M, M)
    overlaps = zeros(grain_count_type, M, M, M)
    inclusions_voxels = Array{SVector{3, T},1}[]
    inc_voxels = 0
    M3 = Int64(M)^3
    for (i, inclusion) in enumerate(inclusions)
        inclusion_voxels = voxelize(inclusion, L, M)

        overlap_min = M3
        Δ_min = zeros(SVector{3, typeof(M)})
        Δ_try = Δ_min
        for n_try in 1:nr_tries
            overlap_try = 0
            for inclusion_voxel in inclusion_voxels
                wrapped_voxel = one(typeof(M)) .+ mod.(inclusion_voxel + Δ_try, M)
                if grain_ids[wrapped_voxel...] > 1 # claimed, so add overlap
                    overlap_try += 1
                end
            end

            if overlap_try < overlap_min
                overlap_min = overlap_try
                Δ_min = Δ_try
                if overlap_min == 0
                    break
                end
            end
            Δ_try = rand(-Δ:Δ, SVector{3})
        end

        # Move the truncated triangle to the right position as well:
        inclusions[i] = set_midpoint(inclusion, inclusion.midpoint + mod.(Δ_min * L/M, L))

        # Rerun with optimal delta_x, delta_y, delta_z
        for (j, inclusion_voxel) in enumerate(inclusion_voxels)
            wrapped_voxel = one(typeof(M)) .+ mod.(inclusion_voxel + Δ_min, M)
            inclusion_voxels[j] = wrapped_voxel
            if grain_ids[wrapped_voxel...] == 1 # still unclaimed binder
                grain_ids[wrapped_voxel...] = i+2
                inc_voxels += 1
            elseif grain_ids[wrapped_voxel...] > 1 # claimed, so add overlap
                overlaps[wrapped_voxel...] += 1
            end
        end
        push!(inclusions_voxels, sort(inclusion_voxels))
        println("grain $i: WC fraction: $(inc_voxels), tries: $nr_tries delta: $Δ_min")
    end

    return grain_ids, overlaps, inclusions_voxels
end

phases(grain_ids) = grain_ids .== 0

# Computes euler angles as used by Dream3D
function euler_angles(grain_ids, inclusions)
    inclusions_angles = euler_angles.(trunc_triangles)

    euler_angles = zeros(size(grain_ids)..., 3)
    for i in CartesianIndices(grain_ids)
        if grain_ids[i] > 1
            grain_id = grain_ids[i] - 1
            euler_angles[i, :] = inclusions_angles[i]
        end
    end

    return euler_angles
end

# Helper
function check_nb(id, old_id, new_id)
    if id == old_id
        return 1 # the new id is different, add 1 area
    elseif id == new_id
        return -1 # the new id is the same, subtract 1 area
    else
        return 0
    end
end

function neighbours(i::CartesianIndex{3}, M::Integer)
    # right, left, forward, backward, up, down
    sub(x) = ifelse(x > 1, x-1, M)
    add(x) = ifelse(x < M, x+1, 1)
    return SA[
        CartesianIndex(sub(i.I[1]), i.I[2], i.I[3]),
        CartesianIndex(add(i.I[1]), i.I[2], i.I[3]),
        CartesianIndex(i.I[1], sub(i.I[2]), i.I[3]),
        CartesianIndex(i.I[1], add(i.I[2]), i.I[3]),
        CartesianIndex(i.I[1], i.I[2], sub(i.I[3])),
        CartesianIndex(i.I[1], i.I[2], add(i.I[3])),
    ]
end

# Monte-Carlo Potts model suitable for minimizing ground boundaries by simulation grain boundary migrations.
# Effectively minimizes contiguity
function make_mcp_bound!(grain_ids, gb_voxels, overlaps, voxel_indices, steps::Integer, kBT::Real)
    M = size(grain_ids)[1] # TODO allow non-square domains

    # Compute the exponentials for different number of neighbouring voxels
    exp_ΔA_kBT = exp.(-SA[1,2,3,4]/kBT)

    overlap_index = findall((x)-> x > 0, overlaps)
    if len(overlap_index) == 0
        return
    end

    for step in 1:steps
        # Choose a random voxel in the overlapping regions
        gb_voxel_index = rand(overlap_index)

        # Check if it is a gb voxel
        if gb_voxels[gb_voxel_index]
            gb_voxel_id = grain_ids[gb_voxel_index]
            nb_indices = neighbours(gb_voxel_index, M)

            # Clear and populate the *set* of different neighbor indices that are allowed; id > 1, i.e. not binder
            nb_ids = grain_ids[nb_indices]

            # Find all possible values the voxel could switch to.
            nb_set = @SVector zeros(6)
            nr_diff_ids = 0
            for i in 1:6
                nb_id = nb_ids[i]
                if nb_id > 1 && nb_id != gb_voxel_id && nb_id ∈ nb_set
                    # Not in set and gb_voxel_id belongs to nb_id and can thus be changed to nb_id
                    if insorted(voxel_indices[nb_id-1], gb_voxel_index)
                        nr_diff_ids += 1
                        nb_set[nr_diff_ids] = nb_id
                    end
                end
            end

            # the set of allowed changes can be zero if we are at the edges of a truncated triangle
            if nr_diff_ids > 0
                new_id = nb_set[rand(1:nr_diff_ids)]

                ΔA = check_nb.(nb_ids, gb_voxel_id, new_id)
                sum_ΔA = sum(ΔA)

                # Metropolis algorithm
                if sum_ΔA <= 0 || (sum_ΔA > 0 && rand() < exp_ΔA_kBT[sum_ΔA-1])
                    grain_ids[gb_voxel_index] = new_id
                    gb_voxels[gb_voxel_index] += sum_ΔA
                    for (δ, nb_index) in zip(ΔA, nb_indices)
                        gb_voxels[nb_index] += δ
                    end
                end
            end
        end
    end
end


text:
"""
Google Cloud APIs
"""
module GoogleCloud

export
    Credentials, AnonymousCredentials, JSONCredentials, MetadataCredentials, GoogleSession, authorize,
    set_session!, get_session
export
    iam, storage, secrets, compute, container, pubsub, logging, datastore
export
    KeyStore, commit!, fetch!, sync!, clearcache!, clearpending!, destroy!, connect!, watch, unwatch

# submodules
include("root.jl")
include("error.jl")
include("credentials.jl")
include("session.jl")
include("api/api.jl")
include("collection.jl")

using .error
using .credentials
using .session
using .api
using .collection

# API bindings
import .api:
    _iam.iam,
    _storage.storage,
    _secrets.secrets,
    _compute.compute,
    _container.container,
    _pubsub.pubsub,
    _logging.logging,
    _datastore.datastore

end


text:
"""
    isinside(p::Point,pointlist::AbstractArray{<:Point,1})

Determine whether `p` is inside `pointlist`.

This function was copied from Luxor.jl. It is an
implementation of an algorithm due to Hormann and Agathos (2001)
"""
function isinside(p::Vec2,
                  pointlist::AbstractArray{<:Vec2, 1};
                  allowonedge::Bool=false)
    c = false
    @inbounds for counter in 1:length(pointlist)
        q1 = pointlist[counter]
        # if reached last point, set "next point" to first point
        if counter == length(pointlist)
            q2 = pointlist[1]
        else
            q2 = pointlist[counter + 1]
        end
        if q1 == p
            allowonedge || error("VertexException a")
            continue
        end
        if q2.y == p.y
            if q2.x == p.x
                allowonedge || error("VertexException b")
                continue
            elseif (q1.y == p.y) && ((q2.x > p.x) == (q1.x < p.x))
                allowonedge || error("EdgeException")
                continue
            end
        end
        if (q1.y < p.y) ≠ (q2.y < p.y) # crossing
            if q1.x >= p.x
                if q2.x > p.x
                    c = !c
                elseif ((det3p(q1, q2, p) > 0) == (q2.y > q1.y))
                    c = !c
                end
            elseif q2.x > p.x
                if ((det3p(q1, q2, p) > 0) == (q2.y > q1.y))
                    c = !c
                end
            end
        end
    end
    return c
end

function det3p(q1::Vec2, q2::Vec2, p::Vec2)
    (q1.x - p.x) * (q2.y - p.y) - (q2.x - p.x) * (q1.y - p.y)
end

isinside(z::Complex,pointlist::Array{<:Complex,1};kwargs...) =
    isinside(Vec2(z),map(Vec2,pointlist);kwargs...)

"""
    distance(x,y,a,b,c,d)

Return the distance from the point (x,y) to the line
segment with endpoints (a,b) and (c,d)
"""
function distance(x,y,a,b,c,d)
    D = (a-c)^2 + (b-d)^2
    if D == 0
        return hypot(x-a,y-c)
    end
    # using SymPy
    # f = (x-a*t-c*(1-t))^2 + (y-b*t-d*(1-t))^2
    # solve(diff(f,t),t)
    t::Float64 = (-a*c + a*x - b*d + b*y + c^2 - c*x + d^2 - d*y) / D
    if t < 0
        t = 0.0
    elseif t > 1
        t = 1.0
    end
    hypot(x-(a*t+c*(1-t)),y-(b*t+d*(1-t)))
end

function distance(P::Vec2,A::Vec2,B::Vec2)
    return distance(P.x,P.y,A.x,A.y,B.x,B.y)
end

function distance(V::Vec2,path::Array{<:Vec2,1})
    minimum(distance(V,path[k],path[k+1]) for k=1:length(path)-1)
end

function iswellinside(V::Vec2,
                      pointlist::AbstractArray{<:Vec2, 1};
                      epsilon=1e-3);
    return distance(V,pointlist) > epsilon && isinside(V,pointlist)
end

# Path concatenation
function *(p::Union{Path3D,Path2D},q::Union{Path3D,Path2D})
    P = typeof(p)
    P ≠ typeof(q) && error("Can't mix 2D and 3D paths")
    k = endof(p.points) - (p.points[end] == q.points[1] ? 1 : 0)
    options = [getfield(p,f) for f in fieldnames(p)[2:end]]
    P(vcat(p.points[1:k],q.points),options...)
end

function axes(P)
    global _DEFAULT_PLOT2D_KWARGS
    D = deepcopy(_DEFAULT_PLOT2D_KWARGS)
    merge!(D,Dict(P.options))
    for s in [:xmin,:xmax,:ymin,:ymax]
        if D[s] == "-infinity"
            D[s] = -Inf
        elseif D[s] == "infinity"
            D[s] = Inf
        end
    end
    if D[:axisarrow] ≠ _DEFAULT_PLOT2D_KWARGS[:axisarrow]
        D[:xaxisarrow] = D[:axisarrow]
        D[:yaxisarrow] = D[:axisarrow]
    end
    bb = boundingbox(P)
    xmin, xmax, ymin, ymax = bb.xmin, bb.xmax, bb.ymin, bb.ymax
    if xmax < 0 xmax = 0 end
    if xmin > 0 xmin = 0 end
    if ymax < 0 ymax = 0 end
    if ymin > 0 ymin = 0 end

    if D[:xmax] <  Inf && xmax < D[:xmax] xmax = D[:xmax] end
    if D[:xmin] > -Inf && xmin > D[:xmin] xmin = D[:xmin] end
    if D[:ymax] <  Inf && ymax < D[:ymax] ymax = D[:ymax] end
    if D[:ymin] > -Inf && ymin < D[:ymin] ymin = D[:ymin] end

    xkwargs = [(:pen,D[:axispen]),(:arrow,D[:xaxisarrow])]
    ykwargs = [(:pen,D[:axispen]),(:arrow,D[:yaxisarrow])]
    width = xmax - xmin; height = ymax - ymin
    border = 0.025
    xmax += border*width; xmin -= border*width
    ymax += border*height; ymin -= border*height

    return [Path2D([xmin 0; xmax 0];xkwargs...),
            Path2D([0 ymin; 0 ymax];ykwargs...)]
end


text:
@testset "PolyModule" begin
    m = Model()
    # Triggers the creation of polydata
    @test PolyJuMP.getpolydata(m).nonnegpoly_default === nothing
    @test_throws ErrorException PolyJuMP.getdefault(m, PolyJuMP.NonNegPoly)
    @test PolyJuMP.getpolydata(m).posdefpolymatrix_default === nothing
    @test_throws ErrorException PolyJuMP.getdefault(m, PolyJuMP.PosDefPolyMatrix)
    setpolymodule!(m, TestPolyModule)
    @test PolyJuMP.getdefault(m, PolyJuMP.NonNegPoly) == TestPolyModule.TestNonNeg
    @test PolyJuMP.getdefault(m, PolyJuMP.PosDefPolyMatrix) == TestPolyModule.TestPosDefMatrix
    PolyJuMP.setdefault!(m, PolyJuMP.PosDefPolyMatrix, TestPolyModule.TestNonNeg)
    @test PolyJuMP.getdefault(m, PolyJuMP.PosDefPolyMatrix) == TestPolyModule.TestNonNeg
end


text:
#!/usr/bin/julia
n=parse(Int,ARGS[1])
println(rand(1:n,n,n))
@show b=3
c=4

max_stars_repo_path: src/Module A - Short Julia Course/deploy1.jl

max_stars_repo_name: ivanslapnicar/GIAN-Applied-NLA-Course

max_issues_repo_name: ivanslapnicar/GIAN-Applied-NLA-Course

max_forks_repo_name: ivanslapnicar/GIAN-Applied-NLA-Course


text:
using EmpiricalRiskMinimization
using CSV, Dataframes

# data from  https://web.stanford.edu/~hastie/Papers/LARS/diabetes.data
# There are 10 explanatory variables, including age (age),
# sex (sex), body mass index (bmi) and mean arterial blood pressure (map)
# of 442 patients as well as six blood serum measurements (tc, ldl, hdl,
# tch, ltg and glu). The response (y) is a continuous measure of disease
# progression one year after the baseline measurements.

DATA_URL = "https://web.stanford.edu/~hastie/Papers/LARS/diabetes.data"

function load_data()
    data = download(DATA_URL)
    D, header = CSV.read(data; delim="\t")
    V = floatarray(D[:,11])
    Vnames = Any[header[11]]
    U = floatarray(D[:,1:10])
    Unames = header[1:10]
    return U, V, Unames, Vnames
end

function individual_plots(U, V, colnames, theta, loss, yhat)
    cols = [1 2 3 4 5; 6 7 8 9 10]
    nrows, ncols = size(cols)

    # just plot data
    function f1(ax, i, j)
        col = cols[i,j]
        plot(ax, U[:,col], V, markersize=6)
             #xlabel=string(colnames[col])
    end
    arrayplot(f1, nrows, ncols, name="alldata.pdf")

    # plot regression lines
    function f2(ax, i, j)
        col = cols[i,j]
        plot(ax, U[:,col], V, xlabel=string(colnames[col]), markersize=6)
        regline(ax, theta[col])
        annotate(ax, 0.95, 0.01, @sprintf("MSE %.0f\n", loss[col]), horizontalalignment="right")
    end
    arrayplot(f2, nrows, ncols, name="alldata_reg.pdf")

    # plot performance of BMI, X column 3
    col = 3
    perfplot(yhat[col], V, xmin=0, xmax=350, name="bmi_perf.pdf")
    println("BMI loss = ", loss[col])
    showmatrix(theta[col], "BMI theta")

    # plot just bmi regression
    ax = plot(U[:,col], V, xlabel=string(colnames[col]))
    regline(ax, theta[col])
    plt.savefig(plotname("bmi_reg.pdf"))

end

function pairwise_table()
    srand(1)
    U, V, Unames, Vnames = loaddata()
    M = Model(U, V, Unames, Vnames, SquareLoss(), L2Reg();
              embedall=true, stand=false)

    d = size(U, 2)
    # all regressors, validated
    tests = Any[]
    train(M; trainfrac=0.8)
    push!(tests, ["all", trainloss(M), testloss(M)])

    # no regressors
    train(M, features=[1])
    push!(tests, ["NONE", trainloss(M), testloss(M)])

    # one regressor
    for i=1:d
        train(M, features=[1, i+1])
        push!(tests, [Unames[i], trainloss(M), testloss(M)])
    end

    # losses for pairs of regressors
    for i=2:d
        for j=1:i-1
            train(M, features=[1, i+1, j+1])
            push!(tests, [ [Unames[i], Unames[j]], trainloss(M), testloss(M)])
        end
    end
    tests = sort(tests, by = x->x[3])
    for a in tests
        if isa(a[1], Array)
            print(a[1][1], " and ", a[1][2])
        else
            print(a[1])
        end
        @printf("  &  %.4g   &  %.4g \\\\\n", a[2], a[3])
    end
end

function full_regression()
    U, V, Unames, Vnames = loaddata()
    M = Model(U, V, Unames, Vnames, SquareLoss(), L2Reg();
              embedall=true, stand=false)

    train(M, trainfrac=1)
    fulltheta = thetaopt(M)
    fullloss = trainloss(M)
    fullyhat = predict_y_from_train(M)

    ###################################################
    # plotting and display
    @printf("Loss based on all data = %.0f\n", fullloss)
    perfplot(fullyhat, V,  xmin=0, xmax=350, name="all_perf.pdf")
    showmatrix(fulltheta, "all theta")

end

function mean_predictor()
    U, V, Unames, Vnames = loaddata()

    # constant predictor
    n = length(V)
    Vmean = sum(V)/n
    meanloss = (1/n)*(norm(V-fill(Vmean,n))^2)

    println("ymean = ", Vmean)
    @printf("Loss of constant predictor = %.0f\n", meanloss)

end

function individual_regressions()
    U, V, Unames, Vnames = loaddata()
    M = Model(U, V, Unames, Vnames, SquareLoss(), L2Reg();
              embedall=true, stand=false)

    d = size(U,2)
    # compute all single variable regressions
    theta = Array{Any}(d)
    losses = zeros(d)
    yhat = Array{Any}(d)
    for i=1:10
        setfeatures(M, [1,i+1])
        train(M; trainfrac=1)
        theta[i] = thetaopt(M)
        losses[i] = trainloss(M)
        yhat[i] = predict_y_from_train(M)
    end
    individual_plots(U, V, Unames, theta, losses, yhat)
end

function repeated_train()
    U, V, Unames, Vnames = loaddata()
    M = Model(U, V, Unames, Vnames, SquareLoss(), L2Reg();
              embedall=true, stand=false)

    features = [3, 9]  # BMI and S5 in colnames
    features = features + 1 # shift to account for constant feature
    unshift!(features, 1)   # include constant feature in list
    setfeatures(M, features)

    trainlosses = Float64[]
    testlosses = Float64[]
    for i=1:1000
        train(M; resplit=true, trainfrac=0.8)
        push!(trainlosses, trainloss(M))
        push!(testlosses, testloss(M))
    end
    plot(testlosses; bins=20, plottype=:hist, xlabel="test loss",
         ylabel="no. of outcomes", name="repeated_test_loss.pdf")
    println("mean test loss = ", mean(testlosses))

    plot(trainlosses; bins=20, plottype=:hist, ylabel="training loss",
         xlim=[2000,5000])
    println("mean train loss = ", mean(trainlosses))

end

function main()
    close("all")

    mean_predictor()
    individual_regressions()
    full_regression()
    pairwise_table()

    srand(1)
    repeated_train()
end


text:
module Example
  function fn()
    println("Hello")
  end
end

max_stars_repo_name: mkanenobu/trashbox

max_issues_repo_name: mkanenobu/trashbox

max_forks_repo_name: mkanenobu/trashbox


text: makehomogeneous(readmag("data/small/Mag.nii"))


text:
# Autogenerated wrapper script for MiniFB_jll for x86_64-w64-mingw32
export libminifb

JLLWrappers.@generate_wrapper_header("MiniFB")
JLLWrappers.@declare_library_product(libminifb, "libminifb.dll")
function __init__()
    JLLWrappers.@generate_init_header()
    JLLWrappers.@init_library_product(
        libminifb,
        "bin\\libminifb.dll",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
module SignificantBits

import Base: significand_mask, trailing_ones

export significand_bits, # explicit
       significant_bits  # implicit = explicit + 1

# how many bits are present in the encoded significand (excludes the hidden bit)
significand_bits(::Type{Float64}) = trailing_ones(significand_mask(Float64))
significand_bits(::Type{Float32}) = trailing_ones(significand_mask(Float32))
significand_bits(::Type{Float16}) = trailing_ones(significand_mask(Float16))

# how many bits are represented with the significand (includes the hidden bit)
significant_bits(::Type{Float64}) = 1+significand_bits(Float64)
significant_bits(::Type{Float32}) = 1+significand_bits(Float32)
significant_bits(::Type{Float16}) = 1+significand_bits(Float16)

end # SignificantBits