From b117881bfd1dd570f7e84575d4af1093a41e19ac Mon Sep 17 00:00:00 2001
From: Stephan Hilb <stephan@ecshi.net>
Date: Fri, 13 Aug 2021 18:38:40 +0200
Subject: [PATCH] add experiments

---
 scripts/Manifest.toml      | 1382 ++++++++++++++++++++++++++++++++++++
 scripts/Project.toml       |   20 +
 scripts/run_experiments.jl |  700 ++++++++++++++++++
 scripts/util.jl            |   88 +++
 4 files changed, 2190 insertions(+)
 create mode 100644 scripts/Manifest.toml
 create mode 100644 scripts/Project.toml
 create mode 100644 scripts/run_experiments.jl
 create mode 100644 scripts/util.jl

diff --git a/scripts/Manifest.toml b/scripts/Manifest.toml
new file mode 100644
index 0000000..e79a94f
--- /dev/null
+++ b/scripts/Manifest.toml
@@ -0,0 +1,1382 @@
+# This file is machine-generated - editing it directly is not advised
+
+[[AbstractFFTs]]
+deps = ["LinearAlgebra"]
+git-tree-sha1 = "8ed9de2f1b1a9b1dee48582ad477c6e67b83eb2c"
+uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c"
+version = "1.0.0"
+
+[[Adapt]]
+deps = ["LinearAlgebra"]
+git-tree-sha1 = "ffcfa2d345aaee0ef3d8346a073d5dd03c983ebe"
+uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
+version = "3.2.0"
+
+[[ArrayInterface]]
+deps = ["IfElse", "LinearAlgebra", "Requires", "SparseArrays"]
+git-tree-sha1 = "ee07ae00e3cc277dcfa5507ce25be522313ecc3e"
+uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
+version = "3.1.1"
+
+[[Artifacts]]
+deps = ["Pkg"]
+git-tree-sha1 = "c30985d8821e0cd73870b17b0ed0ce6dc44cb744"
+uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
+version = "1.3.0"
+
+[[AxisAlgorithms]]
+deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"]
+git-tree-sha1 = "a4d07a1c313392a77042855df46c5f534076fab9"
+uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950"
+version = "1.0.0"
+
+[[AxisArrays]]
+deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"]
+git-tree-sha1 = "f31f50712cbdf40ee8287f0443b57503e34122ef"
+uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9"
+version = "0.4.3"
+
+[[Base64]]
+uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
+
+[[BinaryProvider]]
+deps = ["Libdl", "Logging", "SHA"]
+git-tree-sha1 = "ecdec412a9abc8db54c0efc5548c64dfce072058"
+uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232"
+version = "0.5.10"
+
+[[Bzip2_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "c3598e525718abcc440f69cc6d5f60dda0a1b61e"
+uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
+version = "1.0.6+5"
+
+[[CEnum]]
+git-tree-sha1 = "215a9aa4a1f23fbd05b92769fdd62559488d70e9"
+uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82"
+version = "0.4.1"
+
+[[CSV]]
+deps = ["Dates", "Mmap", "Parsers", "PooledArrays", "SentinelArrays", "Tables", "Unicode"]
+git-tree-sha1 = "1f79803452adf73e2d3fc84785adb7aaca14db36"
+uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
+version = "0.8.3"
+
+[[CSVFiles]]
+deps = ["CodecZlib", "DataValues", "FileIO", "HTTP", "IterableTables", "IteratorInterfaceExtensions", "TableShowUtils", "TableTraits", "TableTraitsUtils", "TextParse"]
+git-tree-sha1 = "96e5ca744988563da0b4dac199287e2790fdb5dd"
+uuid = "5d742f6a-9f54-50ce-8119-2520741973ca"
+version = "1.0.0"
+
+[[Cairo_jll]]
+deps = ["Artifacts", "Bzip2_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"]
+git-tree-sha1 = "e2f47f6d8337369411569fd45ae5753ca10394c6"
+uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
+version = "1.16.0+6"
+
+[[CatIndices]]
+deps = ["CustomUnitRanges", "OffsetArrays"]
+git-tree-sha1 = "a0f80a09780eed9b1d106a1bf62041c2efc995bc"
+uuid = "aafaddc9-749c-510e-ac4f-586e18779b91"
+version = "0.2.2"
+
+[[CategoricalArrays]]
+deps = ["DataAPI", "Future", "JSON", "Missings", "Printf", "Statistics", "StructTypes", "Unicode"]
+git-tree-sha1 = "99809999c8ee01fa89498480b147f7394ea5450f"
+uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597"
+version = "0.9.2"
+
+[[ChainRulesCore]]
+deps = ["Compat", "LinearAlgebra", "SparseArrays"]
+git-tree-sha1 = "de4f08843c332d355852721adb1592bce7924da3"
+uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
+version = "0.9.29"
+
+[[CodeTracking]]
+deps = ["InteractiveUtils", "UUIDs"]
+git-tree-sha1 = "8ad457cfeb0bca98732c97958ef81000a543e73e"
+uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
+version = "1.0.5"
+
+[[CodecZlib]]
+deps = ["BinaryProvider", "Libdl", "TranscodingStreams"]
+git-tree-sha1 = "05916673a2627dd91b4969ff8ba6941bc85a960e"
+uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
+version = "0.6.0"
+
+[[ColorSchemes]]
+deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random", "StaticArrays"]
+git-tree-sha1 = "3141757b5832ee7a0386db87997ee5a23ff20f4d"
+uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
+version = "3.10.2"
+
+[[ColorTypes]]
+deps = ["FixedPointNumbers", "Random"]
+git-tree-sha1 = "4bffea7ed1a9f0f3d1a131bbcd4b925548d75288"
+uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
+version = "0.10.9"
+
+[[ColorVectorSpace]]
+deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase"]
+git-tree-sha1 = "4d17724e99f357bfd32afa0a9e2dda2af31a9aea"
+uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4"
+version = "0.8.7"
+
+[[Colors]]
+deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Reexport"]
+git-tree-sha1 = "ac5f2213e56ed8a34a3dd2f681f4df1166b34929"
+uuid = "5ae59095-9a9b-59fe-a467-6f913c188581"
+version = "0.12.6"
+
+[[CommonSubexpressions]]
+deps = ["MacroTools", "Test"]
+git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7"
+uuid = "bbf7d656-a473-5ed7-a52c-81e309532950"
+version = "0.3.0"
+
+[[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 = "919c7f3151e79ff196add81d7f4e45d91bbf420b"
+uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
+version = "3.25.0"
+
+[[CompilerSupportLibraries_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "8e695f735fca77e9708e795eda62afdb869cbb70"
+uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
+version = "0.3.4+0"
+
+[[ComputationalResources]]
+git-tree-sha1 = "52cb3ec90e8a8bea0e62e275ba577ad0f74821f7"
+uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3"
+version = "0.3.2"
+
+[[Contour]]
+deps = ["StaticArrays"]
+git-tree-sha1 = "9f02045d934dc030edad45944ea80dbd1f0ebea7"
+uuid = "d38c429a-6771-53c6-b99e-75d170b6e991"
+version = "0.5.7"
+
+[[CoordinateTransformations]]
+deps = ["LinearAlgebra", "StaticArrays"]
+git-tree-sha1 = "6d1c23e740a586955645500bbec662476204a52c"
+uuid = "150eb455-5306-5404-9cee-2592286d6298"
+version = "0.6.1"
+
+[[Crayons]]
+git-tree-sha1 = "3f71217b538d7aaee0b69ab47d9b7724ca8afa0d"
+uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
+version = "4.0.4"
+
+[[CustomUnitRanges]]
+git-tree-sha1 = "537c988076d001469093945f3bd0b300b8d3a7f3"
+uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce"
+version = "1.0.1"
+
+[[DataAPI]]
+git-tree-sha1 = "dfb3b7e89e395be1e25c2ad6d7690dc29cc53b1d"
+uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
+version = "1.6.0"
+
+[[DataFrames]]
+deps = ["CategoricalArrays", "Compat", "DataAPI", "Future", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrettyTables", "Printf", "REPL", "Reexport", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"]
+git-tree-sha1 = "b0db5579803eabb33f1274ca7ca2f472fdfb7f2a"
+uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
+version = "0.22.5"
+
+[[DataStructures]]
+deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
+git-tree-sha1 = "4437b64df1e0adccc3e5d1adbc3ac741095e4677"
+uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
+version = "0.18.9"
+
+[[DataTables]]
+deps = ["DataValues", "ReadOnlyArrays", "TableShowUtils", "TableTraitsUtils"]
+git-tree-sha1 = "9b069372a767fc6142feecc8e6d737d1b1de4711"
+uuid = "743a1d0a-8ebc-4f23-814b-50d006366bc6"
+version = "0.1.0"
+
+[[DataValueInterfaces]]
+git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
+uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
+version = "1.0.0"
+
+[[DataValues]]
+deps = ["DataValueInterfaces", "Dates"]
+git-tree-sha1 = "d88a19299eba280a6d062e135a43f00323ae70bf"
+uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5"
+version = "0.4.13"
+
+[[Dates]]
+deps = ["Printf"]
+uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
+
+[[DelimitedFiles]]
+deps = ["Mmap"]
+uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"
+
+[[DiffResults]]
+deps = ["StaticArrays"]
+git-tree-sha1 = "c18e98cba888c6c25d1c3b048e4b3380ca956805"
+uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5"
+version = "1.0.3"
+
+[[DiffRules]]
+deps = ["NaNMath", "Random", "SpecialFunctions"]
+git-tree-sha1 = "214c3fcac57755cfda163d91c58893a8723f93e9"
+uuid = "b552c78f-8df3-52c6-915a-8e097449b14b"
+version = "1.0.2"
+
+[[Distances]]
+deps = ["LinearAlgebra", "Statistics"]
+git-tree-sha1 = "366715149014943abd71aa647a07a43314158b2d"
+uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
+version = "0.10.2"
+
+[[Distributed]]
+deps = ["Random", "Serialization", "Sockets"]
+uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
+
+[[DoubleFloats]]
+deps = ["GenericSVD", "GenericSchur", "LinearAlgebra", "Polynomials", "Printf", "Quadmath", "Random", "Requires", "SpecialFunctions"]
+git-tree-sha1 = "3351fb3839b6967604f9abca62fd3c1f85875906"
+uuid = "497a8b3b-efae-58df-a0af-a86822472b78"
+version = "1.1.15"
+
+[[DualTVDD]]
+deps = ["Distributed", "LinearAlgebra", "Outsource", "StaticArrays", "StaticKernels"]
+path = "../code"
+uuid = "93adc0ee-851f-4b8b-8bf8-c8a87ded093b"
+version = "0.1.0"
+
+[[EarCut_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "92d8f9f208637e8d2d28c664051a00569c01493d"
+uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
+version = "2.1.5+1"
+
+[[EllipsisNotation]]
+deps = ["ArrayInterface"]
+git-tree-sha1 = "8041575f021cba5a099a456b4163c9a08b566a02"
+uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949"
+version = "1.1.0"
+
+[[Expat_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "1402e52fcda25064f51c77a9655ce8680b76acf0"
+uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
+version = "2.2.7+6"
+
+[[ExprTools]]
+git-tree-sha1 = "10407a39b87f29d47ebaca8edbc75d7c302ff93e"
+uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04"
+version = "0.1.3"
+
+[[EzXML]]
+deps = ["Printf", "XML2_jll"]
+git-tree-sha1 = "0fa3b52a04a4e210aeb1626def9c90df3ae65268"
+uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615"
+version = "1.1.0"
+
+[[FFMPEG]]
+deps = ["FFMPEG_jll", "x264_jll"]
+git-tree-sha1 = "9a73ffdc375be61b0e4516d83d880b265366fe1f"
+uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
+version = "0.4.0"
+
+[[FFMPEG_jll]]
+deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "LibVPX_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "Pkg", "Zlib_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"]
+git-tree-sha1 = "3cc57ad0a213808473eafef4845a74766242e05f"
+uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
+version = "4.3.1+4"
+
+[[FFTViews]]
+deps = ["CustomUnitRanges", "FFTW"]
+git-tree-sha1 = "70a0cfd9b1c86b0209e38fbfe6d8231fd606eeaf"
+uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd"
+version = "0.3.1"
+
+[[FFTW]]
+deps = ["AbstractFFTs", "FFTW_jll", "IntelOpenMP_jll", "Libdl", "LinearAlgebra", "MKL_jll", "Reexport"]
+git-tree-sha1 = "1b48dbde42f307e48685fa9213d8b9f8c0d87594"
+uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
+version = "1.3.2"
+
+[[FFTW_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "5a0d4b6a22a34d17d53543bd124f4b08ed78e8b0"
+uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a"
+version = "3.3.9+7"
+
+[[FileIO]]
+deps = ["Pkg"]
+git-tree-sha1 = "fee8955b9dfa7bec67117ef48085fb2b559b9c22"
+uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
+version = "1.4.5"
+
+[[FileWatching]]
+uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
+
+[[FillArrays]]
+deps = ["LinearAlgebra", "Random", "SparseArrays"]
+git-tree-sha1 = "bed538ad14d132aa8240bb2e8ab82fcd2fd2f548"
+uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
+version = "0.11.3"
+
+[[FiniteDiff]]
+deps = ["ArrayInterface", "LinearAlgebra", "Requires", "SparseArrays", "StaticArrays"]
+git-tree-sha1 = "f6f80c8f934efd49a286bb5315360be66956dfc4"
+uuid = "6a86dc24-6348-571c-b903-95158fe2bd41"
+version = "2.8.0"
+
+[[FixedPointNumbers]]
+deps = ["Statistics"]
+git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc"
+uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
+version = "0.8.4"
+
+[[Fontconfig_jll]]
+deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"]
+git-tree-sha1 = "35895cf184ceaab11fd778b4590144034a167a2f"
+uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
+version = "2.13.1+14"
+
+[[Formatting]]
+deps = ["Printf"]
+git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8"
+uuid = "59287772-0a20-5a39-b81b-1366585eb4c0"
+version = "0.4.2"
+
+[[ForwardDiff]]
+deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "NaNMath", "Random", "SpecialFunctions", "StaticArrays"]
+git-tree-sha1 = "d48a40c0f54f29a5c8748cfb3225719accc72b77"
+uuid = "f6369f11-7733-5829-9624-2563aa707210"
+version = "0.10.16"
+
+[[FreeType2_jll]]
+deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
+git-tree-sha1 = "cbd58c9deb1d304f5a245a0b7eb841a2560cfec6"
+uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
+version = "2.10.1+5"
+
+[[FriBidi_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "0d20aed5b14dd4c9a2453c1b601d08e1149679cc"
+uuid = "559328eb-81f9-559d-9380-de523a88c83c"
+version = "1.0.5+6"
+
+[[Future]]
+deps = ["Random"]
+uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"
+
+[[GLFW_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"]
+git-tree-sha1 = "a1bbf700b5388bffc3d882f4f4d625cf1c714fd7"
+uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
+version = "3.3.2+1"
+
+[[GR]]
+deps = ["Base64", "DelimitedFiles", "GR_jll", "HTTP", "JSON", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "Sockets", "Test", "UUIDs"]
+git-tree-sha1 = "aaebdf5588281c2902f499b49e67953f2b409c9c"
+uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
+version = "0.54.0"
+
+[[GR_jll]]
+deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Pkg", "Qt_jll", "Zlib_jll", "libpng_jll"]
+git-tree-sha1 = "8aee6fa096b0cbdb05e71750c978b96a08c78951"
+uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
+version = "0.53.0+0"
+
+[[GenericSVD]]
+deps = ["LinearAlgebra"]
+git-tree-sha1 = "62909c3eda8a25b5673a367d1ad2392ebb265211"
+uuid = "01680d73-4ee2-5a08-a1aa-533608c188bb"
+version = "0.3.0"
+
+[[GenericSchur]]
+deps = ["LinearAlgebra", "Printf"]
+git-tree-sha1 = "c6b383b8d005e6487b41ade2051e3410ec60af8a"
+uuid = "c145ed77-6b09-5dd9-b285-bf645a82121e"
+version = "0.4.1"
+
+[[GeometryBasics]]
+deps = ["EarCut_jll", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"]
+git-tree-sha1 = "4d4f72691933d5b6ee1ff20e27a102c3ae99d123"
+uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
+version = "0.3.9"
+
+[[Gettext_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"]
+git-tree-sha1 = "8c14294a079216000a0bdca5ec5a447f073ddc9d"
+uuid = "78b55507-aeef-58d4-861c-77aaff3498b1"
+version = "0.20.1+7"
+
+[[Glib_jll]]
+deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE_jll", "Pkg", "Zlib_jll"]
+git-tree-sha1 = "04690cc5008b38ecbdfede949220bc7d9ba26397"
+uuid = "7746bdde-850d-59dc-9ae8-88ece973131d"
+version = "2.59.0+4"
+
+[[Graphics]]
+deps = ["Colors", "LinearAlgebra", "NaNMath"]
+git-tree-sha1 = "2c1cf4df419938ece72de17f368a021ee162762e"
+uuid = "a2bd30eb-e257-5431-a919-1863eab51364"
+version = "1.1.0"
+
+[[Grisu]]
+git-tree-sha1 = "03d381f65183cb2d0af8b3425fde97263ce9a995"
+uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe"
+version = "1.0.0"
+
+[[HTTP]]
+deps = ["Base64", "Dates", "IniFile", "MbedTLS", "Sockets"]
+git-tree-sha1 = "c7ec02c4c6a039a98a15f955462cd7aea5df4508"
+uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
+version = "0.8.19"
+
+[[IdentityRanges]]
+deps = ["OffsetArrays"]
+git-tree-sha1 = "be8fcd695c4da16a1d6d0cd213cb88090a150e3b"
+uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca"
+version = "0.3.1"
+
+[[IfElse]]
+git-tree-sha1 = "28e837ff3e7a6c3cdb252ce49fb412c8eb3caeef"
+uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
+version = "0.1.0"
+
+[[ImageAxes]]
+deps = ["AxisArrays", "ImageCore", "Reexport", "SimpleTraits"]
+git-tree-sha1 = "1592c7fd668ac9cdcef73f704ca457ccdaac2933"
+uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac"
+version = "0.6.8"
+
+[[ImageContrastAdjustment]]
+deps = ["ColorVectorSpace", "ImageCore", "ImageTransformations", "Parameters"]
+git-tree-sha1 = "210f8fb370d4b97fa12d65322c62df06f3e5563b"
+uuid = "f332f351-ec65-5f6a-b3d1-319c6670881a"
+version = "0.3.6"
+
+[[ImageCore]]
+deps = ["AbstractFFTs", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"]
+git-tree-sha1 = "79badd979fbee9b8980cd995cd5a86a9e93b8ad7"
+uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534"
+version = "0.8.20"
+
+[[ImageDistances]]
+deps = ["ColorVectorSpace", "Distances", "ImageCore", "ImageMorphology", "LinearAlgebra", "Statistics"]
+git-tree-sha1 = "159e24b4313d9197eef900e97fbd7365986f2844"
+uuid = "51556ac3-7006-55f5-8cb3-34580c88182d"
+version = "0.2.10"
+
+[[ImageFiltering]]
+deps = ["CatIndices", "ColorVectorSpace", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "ImageCore", "ImageMetadata", "LinearAlgebra", "OffsetArrays", "Requires", "SparseArrays", "StaticArrays", "Statistics", "TiledIteration"]
+git-tree-sha1 = "f82a52fa2e684d4ed69028b16188852ff94b3f75"
+uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5"
+version = "0.6.19"
+
+[[ImageIO]]
+deps = ["FileIO", "Netpbm", "PNGFiles"]
+git-tree-sha1 = "0d6d09c28d67611c68e25af0c2df7269c82b73c7"
+uuid = "82e4d734-157c-48bb-816b-45c225c6df19"
+version = "0.4.1"
+
+[[ImageMetadata]]
+deps = ["AxisArrays", "ColorVectorSpace", "ImageAxes", "ImageCore", "IndirectArrays"]
+git-tree-sha1 = "ff77c7f234e7d8a618958fcf23b6959f2cbef2c6"
+uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49"
+version = "0.9.4"
+
+[[ImageMorphology]]
+deps = ["ColorVectorSpace", "ImageCore", "LinearAlgebra", "TiledIteration"]
+git-tree-sha1 = "113df7743f1e18da5f5ea5f98eb59ceb77092734"
+uuid = "787d08f9-d448-5407-9aad-5290dd7ab264"
+version = "0.2.9"
+
+[[ImageQualityIndexes]]
+deps = ["ColorVectorSpace", "ImageCore", "ImageDistances", "ImageFiltering", "OffsetArrays", "Statistics"]
+git-tree-sha1 = "80484f9e1beae36860ed8022f195d04c751cfec6"
+uuid = "2996bd0c-7a13-11e9-2da2-2f5ce47296a9"
+version = "0.2.1"
+
+[[ImageShow]]
+deps = ["Base64", "FileIO", "ImageCore", "Requires"]
+git-tree-sha1 = "c9df184bc7c2e665f971079174aabb7d18f1845f"
+uuid = "4e3cecfd-b093-5904-9786-8bbb286a6a31"
+version = "0.2.3"
+
+[[ImageTransformations]]
+deps = ["AxisAlgorithms", "ColorVectorSpace", "CoordinateTransformations", "IdentityRanges", "ImageCore", "Interpolations", "OffsetArrays", "Rotations", "StaticArrays"]
+git-tree-sha1 = "0426a62ca1a23f3b1ee75cc0e47320d859abd6ae"
+uuid = "02fcd773-0e25-5acc-982a-7f6622650795"
+version = "0.8.9"
+
+[[Images]]
+deps = ["AxisArrays", "Base64", "ColorVectorSpace", "FileIO", "Graphics", "ImageAxes", "ImageContrastAdjustment", "ImageCore", "ImageDistances", "ImageFiltering", "ImageMetadata", "ImageMorphology", "ImageQualityIndexes", "ImageShow", "ImageTransformations", "IndirectArrays", "OffsetArrays", "Random", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "TiledIteration"]
+git-tree-sha1 = "535bcaae047f017f4fd7331ee859b75f2b27e505"
+uuid = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
+version = "0.23.3"
+
+[[IndirectArrays]]
+git-tree-sha1 = "c2a145a145dc03a7620af1444e0264ef907bd44f"
+uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959"
+version = "0.5.1"
+
+[[IniFile]]
+deps = ["Test"]
+git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8"
+uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
+version = "0.5.0"
+
+[[IntelOpenMP_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "d979e54b71da82f3a65b62553da4fc3d18c9004c"
+uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0"
+version = "2018.0.3+2"
+
+[[InteractiveUtils]]
+deps = ["Markdown"]
+uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
+
+[[Interpolations]]
+deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"]
+git-tree-sha1 = "eb1dd6d5b2275faaaa18533e0fc5f9171cec25fa"
+uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
+version = "0.13.1"
+
+[[IntervalSets]]
+deps = ["Dates", "EllipsisNotation", "Statistics"]
+git-tree-sha1 = "93a6d78525feb0d3ee2a2ae83a7d04db1db5663f"
+uuid = "8197267c-284f-5f27-9208-e0e47529a953"
+version = "0.5.2"
+
+[[Intervals]]
+deps = ["Dates", "Printf", "RecipesBase", "Serialization", "TimeZones"]
+git-tree-sha1 = "323a38ed1952d30586d0fe03412cde9399d3618b"
+uuid = "d8418881-c3e1-53bb-8760-2df7ec849ed5"
+version = "1.5.0"
+
+[[InvertedIndices]]
+deps = ["Test"]
+git-tree-sha1 = "15732c475062348b0165684ffe28e85ea8396afc"
+uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
+version = "1.0.0"
+
+[[IterTools]]
+git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18"
+uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
+version = "1.3.0"
+
+[[IterableTables]]
+deps = ["DataValues", "IteratorInterfaceExtensions", "Requires", "TableTraits", "TableTraitsUtils"]
+git-tree-sha1 = "70300b876b2cebde43ebc0df42bc8c94a144e1b4"
+uuid = "1c8ee90f-4401-5389-894e-7a04a3dc0f4d"
+version = "1.0.0"
+
+[[IterativeSolvers]]
+deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"]
+git-tree-sha1 = "6f5ef3206d9dc6510a8b8e2334b96454a2ade590"
+uuid = "42fd0dbc-a981-5370-80f2-aaf504508153"
+version = "0.9.0"
+
+[[IteratorInterfaceExtensions]]
+git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
+uuid = "82899510-4779-5014-852e-03e436cf321d"
+version = "1.0.0"
+
+[[JLLWrappers]]
+git-tree-sha1 = "a431f5f2ca3f4feef3bd7a5e94b8b8d4f2f647a0"
+uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
+version = "1.2.0"
+
+[[JSON]]
+deps = ["Dates", "Mmap", "Parsers", "Unicode"]
+git-tree-sha1 = "81690084b6198a2e1da36fcfda16eeca9f9f24e4"
+uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
+version = "0.21.1"
+
+[[JpegTurbo_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "9aff0587d9603ea0de2c6f6300d9f9492bbefbd3"
+uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8"
+version = "2.0.1+3"
+
+[[JuliaInterpreter]]
+deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
+git-tree-sha1 = "86439cef50a24fa981583476f48b197b7dea691e"
+uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
+version = "0.8.9"
+
+[[LAME_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "df381151e871f41ee86cee4f5f6fd598b8a68826"
+uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d"
+version = "3.100.0+3"
+
+[[LZO_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "f128cd6cd05ffd6d3df0523ed99b90ff6f9b349a"
+uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
+version = "2.10.0+3"
+
+[[LaTeXStrings]]
+git-tree-sha1 = "c7aebfecb1a60d59c0fe023a68ec947a208b1e6b"
+uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
+version = "1.2.0"
+
+[[Latexify]]
+deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "Printf", "Requires"]
+git-tree-sha1 = "3a0084cec7bf157edcb45a67fac0647f88fe5eaf"
+uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
+version = "0.14.7"
+
+[[LazyArtifacts]]
+deps = ["Pkg"]
+git-tree-sha1 = "4bb5499a1fc437342ea9ab7e319ede5a457c0968"
+uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3"
+version = "1.3.0"
+
+[[LibGit2]]
+deps = ["Printf"]
+uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
+
+[[LibVPX_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "85fcc80c3052be96619affa2fe2e6d2da3908e11"
+uuid = "dd192d2f-8180-539f-9fb4-cc70b1dcf69a"
+version = "1.9.0+1"
+
+[[Libdl]]
+uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
+
+[[Libffi_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "a2cd088a88c0d37eef7d209fd3d8712febce0d90"
+uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490"
+version = "3.2.1+4"
+
+[[Libgcrypt_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"]
+git-tree-sha1 = "b391a18ab1170a2e568f9fb8d83bc7c780cb9999"
+uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4"
+version = "1.8.5+4"
+
+[[Libglvnd_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"]
+git-tree-sha1 = "7739f837d6447403596a75d19ed01fd08d6f56bf"
+uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29"
+version = "1.3.0+3"
+
+[[Libgpg_error_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "ec7f2e8ad5c9fa99fc773376cdbc86d9a5a23cb7"
+uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8"
+version = "1.36.0+3"
+
+[[Libiconv_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "8e924324b2e9275a51407a4e06deb3455b1e359f"
+uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
+version = "1.16.0+7"
+
+[[Libmount_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "51ad0c01c94c1ce48d5cad629425035ad030bfd5"
+uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9"
+version = "2.34.0+3"
+
+[[Libtiff_jll]]
+deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"]
+git-tree-sha1 = "291dd857901f94d683973cdf679984cdf73b56d0"
+uuid = "89763e89-9b03-5906-acba-b20f662cd828"
+version = "4.1.0+2"
+
+[[Libuuid_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "f879ae9edbaa2c74c922e8b85bb83cc84ea1450b"
+uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700"
+version = "2.34.0+7"
+
+[[LineSearches]]
+deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"]
+git-tree-sha1 = "f27132e551e959b3667d8c93eae90973225032dd"
+uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255"
+version = "7.1.1"
+
+[[LinearAlgebra]]
+deps = ["Libdl"]
+uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
+
+[[LinearMaps]]
+deps = ["LinearAlgebra", "SparseArrays"]
+git-tree-sha1 = "81fe47fe6e8499463d3afcc90a42a8349caefe72"
+uuid = "7a12625a-238d-50fd-b39a-03d52299707e"
+version = "3.2.0"
+
+[[Logging]]
+uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
+
+[[LoweredCodeUtils]]
+deps = ["JuliaInterpreter"]
+git-tree-sha1 = "f008f15264cc11de6de8cbdda3d4712dd152f0c3"
+uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
+version = "1.2.7"
+
+[[MKL_jll]]
+deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"]
+git-tree-sha1 = "c253236b0ed414624b083e6b72bfe891fbd2c7af"
+uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
+version = "2021.1.1+1"
+
+[[MacroTools]]
+deps = ["Markdown", "Random"]
+git-tree-sha1 = "6a8a2a625ab0dea913aba95c11370589e0239ff0"
+uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
+version = "0.5.6"
+
+[[MappedArrays]]
+deps = ["FixedPointNumbers"]
+git-tree-sha1 = "b92bd220c95a8bbe89af28f11201fd080e0e3fe7"
+uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900"
+version = "0.3.0"
+
+[[Markdown]]
+deps = ["Base64"]
+uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
+
+[[MbedTLS]]
+deps = ["Dates", "MbedTLS_jll", "Random", "Sockets"]
+git-tree-sha1 = "1c38e51c3d08ef2278062ebceade0e46cefc96fe"
+uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
+version = "1.0.3"
+
+[[MbedTLS_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "0eef589dd1c26a3ac9d753fe1a8bcad63f956fa6"
+uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
+version = "2.16.8+1"
+
+[[Measures]]
+git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f"
+uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
+version = "0.3.1"
+
+[[Missings]]
+deps = ["DataAPI"]
+git-tree-sha1 = "f8c673ccc215eb50fcadb285f522420e29e69e1c"
+uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
+version = "0.4.5"
+
+[[Mmap]]
+uuid = "a63ad114-7e13-5084-954f-fe012c677804"
+
+[[Mocking]]
+deps = ["ExprTools"]
+git-tree-sha1 = "916b850daad0d46b8c71f65f719c49957e9513ed"
+uuid = "78c3b35d-d492-501b-9361-3d52fe80e533"
+version = "0.7.1"
+
+[[MosaicViews]]
+deps = ["MappedArrays", "OffsetArrays", "PaddedViews"]
+git-tree-sha1 = "614e8d77264d20c1db83661daadfab38e8e4b77e"
+uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389"
+version = "0.2.4"
+
+[[NLSolversBase]]
+deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"]
+git-tree-sha1 = "39d6bc45e99c96e6995cbddac02877f9b61a1dd1"
+uuid = "d41bc354-129a-5804-8e4c-c37616107c6c"
+version = "7.7.1"
+
+[[NaNMath]]
+git-tree-sha1 = "bfe47e760d60b82b66b61d2d44128b62e3a369fb"
+uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
+version = "0.3.5"
+
+[[Netpbm]]
+deps = ["ColorVectorSpace", "FileIO", "ImageCore"]
+git-tree-sha1 = "03472ec5ea8884b791c6340712f3261c0f393691"
+uuid = "f09324ee-3d7c-5217-9330-fc30815ba969"
+version = "1.0.0"
+
+[[Nullables]]
+git-tree-sha1 = "8f87854cc8f3685a60689d8edecaa29d2251979b"
+uuid = "4d1e1d77-625e-5b40-9113-a560ec7a8ecd"
+version = "1.0.0"
+
+[[OffsetArrays]]
+deps = ["Adapt"]
+git-tree-sha1 = "986e7c0a0ef1863be969d191957ac32cb17d0d79"
+uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
+version = "1.6.0"
+
+[[Ogg_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "a42c0f138b9ebe8b58eba2271c5053773bde52d0"
+uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
+version = "1.3.4+2"
+
+[[OpenSSL_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "71bbbc616a1d710879f5a1021bcba65ffba6ce58"
+uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
+version = "1.1.1+6"
+
+[[OpenSpecFun_jll]]
+deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "9db77584158d0ab52307f8c04f8e7c08ca76b5b3"
+uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
+version = "0.5.3+4"
+
+[[OpticalFlowUtils]]
+deps = ["Colors", "FileIO", "LinearAlgebra", "StaticArrays"]
+path = "/home/stev47/.julia/dev/OpticalFlowUtils"
+uuid = "ab0dad50-ab19-448c-b796-13553ec8b2d3"
+version = "0.1.0"
+
+[[Optim]]
+deps = ["Compat", "FillArrays", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"]
+git-tree-sha1 = "3286df38aba45acf7445f3acd87b7b57b7c7feb7"
+uuid = "429524aa-4258-5aef-a3af-852621145aeb"
+version = "1.2.4"
+
+[[Opus_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "f9d57f4126c39565e05a2b0264df99f497fc6f37"
+uuid = "91d4177d-7536-5919-b921-800302f37372"
+version = "1.3.1+3"
+
+[[OrderedCollections]]
+git-tree-sha1 = "4fa2ba51070ec13fcc7517db714445b4ab986bdf"
+uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
+version = "1.4.0"
+
+[[Outsource]]
+deps = ["Distributed"]
+git-tree-sha1 = "ca47df86d1312aa07715bbf19a8c6187ccd6c758"
+repo-rev = "master"
+repo-url = "https://github.com/stev47/Outsource.jl"
+uuid = "ce4b2b2b-baef-434e-9229-2c3161aca78b"
+version = "0.1.0"
+
+[[PCRE_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "1b556ad51dceefdbf30e86ffa8f528b73c7df2bb"
+uuid = "2f80f16e-611a-54ab-bc61-aa92de5b98fc"
+version = "8.42.0+4"
+
+[[PNGFiles]]
+deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"]
+git-tree-sha1 = "aa6e87a2361c2fe5a63b1a6a4b567f13aa108991"
+uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883"
+version = "0.3.5"
+
+[[PaddedViews]]
+deps = ["OffsetArrays"]
+git-tree-sha1 = "0fa5e78929aebc3f6b56e1a88cf505bb00a354c4"
+uuid = "5432bcbf-9aad-5242-b902-cca2824c8663"
+version = "0.5.8"
+
+[[Parameters]]
+deps = ["OrderedCollections", "UnPack"]
+git-tree-sha1 = "2276ac65f1e236e0a6ea70baff3f62ad4c625345"
+uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a"
+version = "0.12.2"
+
+[[Parsers]]
+deps = ["Dates"]
+git-tree-sha1 = "50c9a9ed8c714945e01cd53a21007ed3865ed714"
+uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
+version = "1.0.15"
+
+[[Pixman_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "6a20a83c1ae86416f0a5de605eaea08a552844a3"
+uuid = "30392449-352a-5448-841d-b1acce4e97dc"
+version = "0.40.0+0"
+
+[[Pkg]]
+deps = ["Dates", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"]
+uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
+
+[[PlotThemes]]
+deps = ["PlotUtils", "Requires", "Statistics"]
+git-tree-sha1 = "a3a964ce9dc7898193536002a6dd892b1b5a6f1d"
+uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
+version = "2.0.1"
+
+[[PlotUtils]]
+deps = ["ColorSchemes", "Colors", "Dates", "Printf", "Random", "Reexport", "Statistics"]
+git-tree-sha1 = "ae9a295ac761f64d8c2ec7f9f24d21eb4ffba34d"
+uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
+version = "1.0.10"
+
+[[Plots]]
+deps = ["Base64", "Contour", "Dates", "FFMPEG", "FixedPointNumbers", "GR", "GeometryBasics", "JSON", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "PlotThemes", "PlotUtils", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs"]
+git-tree-sha1 = "7ecf7d0207e7208a5cad9fd3bd357f5d5eb16044"
+uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
+version = "1.10.5"
+
+[[Polynomials]]
+deps = ["Intervals", "LinearAlgebra", "OffsetArrays", "RecipesBase"]
+git-tree-sha1 = "1c6c5b0c3713738d6b987903c529d80622c37e07"
+uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
+version = "1.2.0"
+
+[[PooledArrays]]
+deps = ["DataAPI"]
+git-tree-sha1 = "0e8f5c428a41a81cd71f76d76f2fc3415fe5a676"
+uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
+version = "1.1.0"
+
+[[PositiveFactorizations]]
+deps = ["LinearAlgebra"]
+git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20"
+uuid = "85a6dd25-e78a-55b7-8502-1745935b8125"
+version = "0.2.4"
+
+[[PrettyTables]]
+deps = ["Crayons", "Formatting", "Markdown", "Reexport", "Tables"]
+git-tree-sha1 = "574a6b3ea95f04e8757c0280bb9c29f1a5e35138"
+uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
+version = "0.11.1"
+
+[[Printf]]
+deps = ["Unicode"]
+uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
+
+[[Qt_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 = "7760cfea90bec61814e31dfb204fa4b81bba7b57"
+uuid = "ede63266-ebff-546c-83e0-1c6fb6d0efc8"
+version = "5.15.2+1"
+
+[[Quadmath]]
+deps = ["Printf", "Random", "Requires"]
+git-tree-sha1 = "5a8f74af8eae654086a1d058b4ec94ff192e3de0"
+uuid = "be4d8f0f-7fa4-5f49-b795-2f01399ab2dd"
+version = "0.5.5"
+
+[[REPL]]
+deps = ["InteractiveUtils", "Markdown", "Sockets"]
+uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
+
+[[Random]]
+deps = ["Serialization"]
+uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
+
+[[RangeArrays]]
+git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5"
+uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d"
+version = "0.3.2"
+
+[[Ratios]]
+git-tree-sha1 = "37d210f612d70f3f7d57d488cb3b6eff56ad4e41"
+uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
+version = "0.4.0"
+
+[[ReadOnlyArrays]]
+deps = ["SparseArrays", "Test"]
+git-tree-sha1 = "65f17072a35c2be7ac8941aeeae489013212e71f"
+uuid = "988b38a3-91fc-5605-94a2-ee2116b3bd83"
+version = "0.1.1"
+
+[[RecipesBase]]
+git-tree-sha1 = "b3fb709f3c97bfc6e948be68beeecb55a0b340ae"
+uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
+version = "1.1.1"
+
+[[RecipesPipeline]]
+deps = ["Dates", "NaNMath", "PlotUtils", "RecipesBase"]
+git-tree-sha1 = "c4d54a78e287de7ec73bbc928ce5eb3c60f80b24"
+uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c"
+version = "0.3.1"
+
+[[Reexport]]
+git-tree-sha1 = "57d8440b0c7d98fc4f889e478e80f268d534c9d5"
+uuid = "189a3867-3050-52da-a836-e630ba90ab69"
+version = "1.0.0"
+
+[[Requires]]
+deps = ["UUIDs"]
+git-tree-sha1 = "cfbac6c1ed70c002ec6361e7fd334f02820d6419"
+uuid = "ae029012-a4dd-5104-9daa-d747884805df"
+version = "1.1.2"
+
+[[Revise]]
+deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"]
+git-tree-sha1 = "4697c220e6448fb5e9c55404ae1a13271d533b52"
+uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
+version = "3.1.12"
+
+[[Rotations]]
+deps = ["LinearAlgebra", "StaticArrays", "Statistics"]
+git-tree-sha1 = "2ed8d8a16d703f900168822d83699b8c3c1a5cd8"
+uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc"
+version = "1.0.2"
+
+[[SHA]]
+uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
+
+[[Scratch]]
+deps = ["Dates"]
+git-tree-sha1 = "ad4b278adb62d185bbcb6864dc24959ab0627bf6"
+uuid = "6c6a2e73-6563-6170-7368-637461726353"
+version = "1.0.3"
+
+[[SentinelArrays]]
+deps = ["Dates", "Random"]
+git-tree-sha1 = "6ccde405cf0759eba835eb613130723cb8f10ff9"
+uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
+version = "1.2.16"
+
+[[Serialization]]
+uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
+
+[[SharedArrays]]
+deps = ["Distributed", "Mmap", "Random", "Serialization"]
+uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"
+
+[[Showoff]]
+deps = ["Dates", "Grisu"]
+git-tree-sha1 = "ee010d8f103468309b8afac4abb9be2e18ff1182"
+uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
+version = "0.3.2"
+
+[[SimpleTraits]]
+deps = ["InteractiveUtils", "MacroTools"]
+git-tree-sha1 = "daf7aec3fe3acb2131388f93a4c409b8c7f62226"
+uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d"
+version = "0.9.3"
+
+[[Sockets]]
+uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
+
+[[SortingAlgorithms]]
+deps = ["DataStructures", "Random", "Test"]
+git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd"
+uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
+version = "0.3.1"
+
+[[SparseArrays]]
+deps = ["LinearAlgebra", "Random"]
+uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
+
+[[SpecialFunctions]]
+deps = ["ChainRulesCore", "OpenSpecFun_jll"]
+git-tree-sha1 = "5919936c0e92cff40e57d0ddf0ceb667d42e5902"
+uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
+version = "1.3.0"
+
+[[StaticArrays]]
+deps = ["LinearAlgebra", "Random", "Statistics"]
+git-tree-sha1 = "9da72ed50e94dbff92036da395275ed114e04d49"
+uuid = "90137ffa-7385-5640-81b9-e52037218182"
+version = "1.0.1"
+
+[[StaticKernels]]
+git-tree-sha1 = "b42c4dd298b987dfe9e7a4dcaa7e66e9efe1c828"
+uuid = "4c63dfa8-a427-4548-bd2f-4c19e87a7dc7"
+version = "0.6.0"
+
+[[Statistics]]
+deps = ["LinearAlgebra", "SparseArrays"]
+uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
+
+[[StatsBase]]
+deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics"]
+git-tree-sha1 = "400aa43f7de43aeccc5b2e39a76a79d262202b76"
+uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
+version = "0.33.3"
+
+[[StructArrays]]
+deps = ["Adapt", "DataAPI", "Tables"]
+git-tree-sha1 = "26ea43b4be7e919a2390c3c0f824e7eb4fc19a0a"
+uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
+version = "0.5.0"
+
+[[StructTypes]]
+deps = ["Dates", "UUIDs"]
+git-tree-sha1 = "65a43f5218197bc7091b76bc273a5e323a1d7b0d"
+uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
+version = "1.2.3"
+
+[[TableShowUtils]]
+deps = ["DataValues", "Dates", "JSON", "Markdown", "Test"]
+git-tree-sha1 = "14c54e1e96431fb87f0d2f5983f090f1b9d06457"
+uuid = "5e66a065-1f0a-5976-b372-e0b8c017ca10"
+version = "0.2.5"
+
+[[TableTraits]]
+deps = ["IteratorInterfaceExtensions"]
+git-tree-sha1 = "b1ad568ba658d8cbb3b892ed5380a6f3e781a81e"
+uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
+version = "1.0.0"
+
+[[TableTraitsUtils]]
+deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits"]
+git-tree-sha1 = "8fc12ae66deac83e44454e61b02c37b326493233"
+uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda"
+version = "1.0.1"
+
+[[Tables]]
+deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "TableTraits", "Test"]
+git-tree-sha1 = "a716dde43d57fa537a19058d044b495301ba6565"
+uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
+version = "1.3.2"
+
+[[Test]]
+deps = ["Distributed", "InteractiveUtils", "Logging", "Random"]
+uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
+
+[[TextParse]]
+deps = ["CodecZlib", "DataStructures", "Dates", "DoubleFloats", "Mmap", "Nullables", "WeakRefStrings"]
+git-tree-sha1 = "af728c38c839aee693637e15e244074a02f16c68"
+uuid = "e0df1984-e451-5cb5-8b61-797a481e67e3"
+version = "1.0.1"
+
+[[TiledIteration]]
+deps = ["OffsetArrays"]
+git-tree-sha1 = "05f74c5b3c00d5336bc109416df2df907e3bd91d"
+uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac"
+version = "0.2.5"
+
+[[TimeZones]]
+deps = ["Dates", "EzXML", "Mocking", "Pkg", "Printf", "RecipesBase", "Serialization", "Unicode"]
+git-tree-sha1 = "4ba8a9579a243400db412b50300cd61d7447e583"
+uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53"
+version = "1.5.3"
+
+[[TranscodingStreams]]
+deps = ["Random", "Test"]
+git-tree-sha1 = "7c53c35547de1c5b9d46a4797cf6d8253807108c"
+uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
+version = "0.9.5"
+
+[[UUIDs]]
+deps = ["Random", "SHA"]
+uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
+
+[[UnPack]]
+git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b"
+uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
+version = "1.0.2"
+
+[[Unicode]]
+uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
+
+[[Wayland_jll]]
+deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"]
+git-tree-sha1 = "dc643a9b774da1c2781413fd7b6dcd2c56bb8056"
+uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89"
+version = "1.17.0+4"
+
+[[Wayland_protocols_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll"]
+git-tree-sha1 = "2839f1c1296940218e35df0bbb220f2a79686670"
+uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
+version = "1.18.0+4"
+
+[[WeakRefStrings]]
+deps = ["DataAPI", "Random", "Test"]
+git-tree-sha1 = "28807f85197eaad3cbd2330386fac1dcb9e7e11d"
+uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5"
+version = "0.6.2"
+
+[[WoodburyMatrices]]
+deps = ["LinearAlgebra", "SparseArrays"]
+git-tree-sha1 = "59e2ad8fd1591ea019a5259bd012d7aee15f995c"
+uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6"
+version = "0.5.3"
+
+[[XML2_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"]
+git-tree-sha1 = "be0db24f70aae7e2b89f2f3092e93b8606d659a6"
+uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
+version = "2.9.10+3"
+
+[[XSLT_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Pkg", "XML2_jll"]
+git-tree-sha1 = "2b3eac39df218762d2d005702d601cd44c997497"
+uuid = "aed1982a-8fda-507f-9586-7b0439959a61"
+version = "1.1.33+4"
+
+[[Xorg_libX11_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"]
+git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527"
+uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc"
+version = "1.6.9+4"
+
+[[Xorg_libXau_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e"
+uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec"
+version = "1.0.9+4"
+
+[[Xorg_libXcursor_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"]
+git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd"
+uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724"
+version = "1.2.0+4"
+
+[[Xorg_libXdmcp_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4"
+uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05"
+version = "1.1.3+4"
+
+[[Xorg_libXext_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
+git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3"
+uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3"
+version = "1.3.4+4"
+
+[[Xorg_libXfixes_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
+git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4"
+uuid = "d091e8ba-531a-589c-9de9-94069b037ed8"
+version = "5.0.3+4"
+
+[[Xorg_libXi_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"]
+git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246"
+uuid = "a51aa0fd-4e3c-5386-b890-e753decda492"
+version = "1.7.10+4"
+
+[[Xorg_libXinerama_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"]
+git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123"
+uuid = "d1454406-59df-5ea1-beac-c340f2130bc3"
+version = "1.1.4+4"
+
+[[Xorg_libXrandr_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"]
+git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631"
+uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484"
+version = "1.5.2+4"
+
+[[Xorg_libXrender_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
+git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96"
+uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa"
+version = "0.9.10+4"
+
+[[Xorg_libpthread_stubs_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb"
+uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74"
+version = "0.1.0+3"
+
+[[Xorg_libxcb_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"]
+git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6"
+uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b"
+version = "1.13.0+3"
+
+[[Xorg_libxkbfile_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
+git-tree-sha1 = "926af861744212db0eb001d9e40b5d16292080b2"
+uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a"
+version = "1.1.0+4"
+
+[[Xorg_xcb_util_image_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
+git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97"
+uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b"
+version = "0.4.0+1"
+
+[[Xorg_xcb_util_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll"]
+git-tree-sha1 = "e7fd7b2881fa2eaa72717420894d3938177862d1"
+uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5"
+version = "0.4.0+1"
+
+[[Xorg_xcb_util_keysyms_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
+git-tree-sha1 = "d1151e2c45a544f32441a567d1690e701ec89b00"
+uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7"
+version = "0.4.0+1"
+
+[[Xorg_xcb_util_renderutil_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
+git-tree-sha1 = "dfd7a8f38d4613b6a575253b3174dd991ca6183e"
+uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e"
+version = "0.3.9+1"
+
+[[Xorg_xcb_util_wm_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
+git-tree-sha1 = "e78d10aab01a4a154142c5006ed44fd9e8e31b67"
+uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361"
+version = "0.4.1+1"
+
+[[Xorg_xkbcomp_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxkbfile_jll"]
+git-tree-sha1 = "4bcbf660f6c2e714f87e960a171b119d06ee163b"
+uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4"
+version = "1.4.2+4"
+
+[[Xorg_xkeyboard_config_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xkbcomp_jll"]
+git-tree-sha1 = "5c8424f8a67c3f2209646d4425f3d415fee5931d"
+uuid = "33bec58e-1273-512f-9401-5d533626f822"
+version = "2.27.0+4"
+
+[[Xorg_xtrans_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845"
+uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10"
+version = "1.4.0+3"
+
+[[Zlib_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "320228915c8debb12cb434c59057290f0834dbf6"
+uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
+version = "1.2.11+18"
+
+[[Zstd_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "2c1332c54931e83f8f94d310fa447fd743e8d600"
+uuid = "3161d3a3-bdf6-5164-811a-617609db77b4"
+version = "1.4.8+0"
+
+[[libass_jll]]
+deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
+git-tree-sha1 = "acc685bcf777b2202a904cdcb49ad34c2fa1880c"
+uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
+version = "0.14.0+4"
+
+[[libfdk_aac_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "7a5780a0d9c6864184b3a2eeeb833a0c871f00ab"
+uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280"
+version = "0.1.6+4"
+
+[[libpng_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
+git-tree-sha1 = "6abbc424248097d69c0c87ba50fcb0753f93e0ee"
+uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f"
+version = "1.6.37+6"
+
+[[libvorbis_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"]
+git-tree-sha1 = "fa14ac25af7a4b8a7f61b287a124df7aab601bcd"
+uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a"
+version = "1.3.6+6"
+
+[[x264_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "d713c1ce4deac133e3334ee12f4adff07f81778f"
+uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
+version = "2020.7.14+2"
+
+[[x265_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
+git-tree-sha1 = "487da2f8f2f0c8ee0e83f39d13037d6bbf0a45ab"
+uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
+version = "3.0.0+3"
+
+[[xkbcommon_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"]
+git-tree-sha1 = "ece2350174195bb31de1a63bea3a41ae1aa593b6"
+uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd"
+version = "0.9.1+5"
diff --git a/scripts/Project.toml b/scripts/Project.toml
new file mode 100644
index 0000000..8e731f6
--- /dev/null
+++ b/scripts/Project.toml
@@ -0,0 +1,20 @@
+[deps]
+CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
+CSVFiles = "5d742f6a-9f54-50ce-8119-2520741973ca"
+Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
+DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
+DataTables = "743a1d0a-8ebc-4f23-814b-50d006366bc6"
+DualTVDD = "93adc0ee-851f-4b8b-8bf8-c8a87ded093b"
+FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
+FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
+ImageIO = "82e4d734-157c-48bb-816b-45c225c6df19"
+Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
+IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153"
+LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e"
+OpticalFlowUtils = "ab0dad50-ab19-448c-b796-13553ec8b2d3"
+Optim = "429524aa-4258-5aef-a3af-852621145aeb"
+Outsource = "ce4b2b2b-baef-434e-9229-2c3161aca78b"
+Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
+Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
+StaticKernels = "4c63dfa8-a427-4548-bd2f-4c19e87a7dc7"
+Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
diff --git a/scripts/run_experiments.jl b/scripts/run_experiments.jl
new file mode 100644
index 0000000..4981645
--- /dev/null
+++ b/scripts/run_experiments.jl
@@ -0,0 +1,700 @@
+# environment setup
+
+const scriptpath = @__DIR__
+const datapath = joinpath(@__DIR__, "..", "data")
+
+
+#using Pkg
+#Pkg.activate(scriptpath)
+#Pkg.instantiate()
+
+#    function savelog(df, name)
+#        CSV.write(joinpath(datapath, "$(name)_energies.csv"), df)
+#        #display(df)
+#        df2 = DataFrame([a => a == :k ? b[1:end-1] : abs.(diff(b)) for (a, b) in pairs(eachcol(df))])
+#        #display(df2)
+#        CSV.write(joinpath(datapath, "$(name)_energydiffs.csv"), df2)
+#    end
+# experiments
+
+using Random: MersenneTwister
+using LinearAlgebra: Diagonal, I, dot, norm, mul!, diagm
+using Statistics: median
+
+using CSV
+using Colors: HSV
+using DataFrames
+using Distributed
+@everywhere using DualTVDD:
+    DualTVL1ROFOpProblem,
+    DualTVDDAlgorithm, ChambolleAlgorithm, NStepAlgorithm, ProjGradAlgorithm,# TVNewtonAlgorithm,
+    SurrogateAlgorithm,
+    DualTVDDSurrogateAlgorithm,
+    init, step!, fetch, fetch_u, gradient, divergence, normB, energy, residual
+using DualTVDD: fetch_u
+using FileIO
+using ImageIO
+using OpticalFlowUtils
+using FileIO: @format_str, add_format
+add_format(format"FLO", b"PIEH", ".flo", [:OpticalFlowUtils])
+using Optim
+using Plots
+using FFTW
+using StaticKernels: Kernel, ExtensionReplicate, ExtensionNothing, extend
+using LinearMaps
+using IterativeSolvers
+
+include("util.jl")
+isdefined(Main, :Revise) && Revise.track(joinpath(@__DIR__, "util.jl"))
+
+using .Util
+
+# Problems
+
+function DenoiseProblem(img::AbstractArray{T,d}; λ, β = 0.) where {T,d}
+    B = (1 + β) * I
+    g = img
+
+    return DualTVL1ROFOpProblem(g, B, λ)
+end
+
+function InpaintProblem(img::AbstractArray{T,d}, imgmask::AbstractArray{Bool,d}; λ, β) where {T,d}
+    pwop = imgmask .+ β .* Ref(I)
+    B = Diagonal(vec(inv.(pwop)))
+
+    ## we grey-out the inpainting area.
+    ## since β > 0 this actually matters and should be a sane default
+    #g = imgmask .* img .+ .!imgmask .* 0.5
+    g = imgmask .* img
+    return DualTVL1ROFOpProblem(g, B, λ)
+end
+
+function OptFlowProblem(f0::AbstractArray{T,d}, f1::AbstractArray{T,d}; λ, β) where {T,d}
+    size(f0) == size(f1) || throw(ArgumentError("mismatched sizes"))
+
+    ∇ = Kernel{ntuple(_->0:1, d)}(gradient)
+    ∇f0 = map(∇, extend(f0, ExtensionReplicate()))
+
+    Bval = inv.(∇f0 .* adjoint.(∇f0) .+ β .* Ref(I))
+    B = Diagonal(vec(Bval))
+
+    g = .-(f1 .- f0) .* ∇f0
+
+    return DualTVL1ROFOpProblem(g, B, λ)
+end
+
+function DFTProblem(img::AbstractArray{T,d}; λ, β=0.) where {T,d}
+    T <: Complex || throw(ArgumentError("need `<:Complex` eltype for frequency data"))
+    n = length(img)
+    B = 1 / (n + β) * I
+    g = real.(n * ifft(img))
+
+    return DualTVL1ROFOpProblem(g, B, λ)
+end
+
+function GlobalProblem(img::AbstractArray{T,d}, A; λ, β) where {T,d}
+    n = length(img)
+
+    B = LinearMap{Float64}(
+        b -> cg(A'*A + β * I, b; maxiter=10),
+        n, n; issymmetric=true, isposdef=β>0)
+
+    #B = inv(A'*A + β*I)
+    #B = (B' + B) / 2
+    g = reshape(A' * A * vec(img), size(img))
+
+    return DualTVL1ROFOpProblem(g, B, λ)
+end
+
+# Util
+
+toimg(arr) = Gray.(clamp.(arr, 0., 1.))
+loadimg(x) = Float64.(load(x))
+saveimg(io, x) = save(io, toimg(x))
+
+
+function run_algs(dataf, algs; maxiters)
+    flatten(x; kwargs...) =
+        (;kwargs..., (Symbol(a, "_", c) => d for (a, b) in pairs(x) for (c, d) in pairs(b))...)
+
+    df = DataFrame()
+    states = map(init, algs)
+    push!(df, flatten(map(dataf, states); k=0))
+
+    # log-skipping parameter
+    a = 20
+    for k in 1:maxiters
+        round(a*log(k+1)) - round(a*log(k)) == 0 && continue
+        push!(df.k, k)
+    end
+    for (algname, st) in pairs(states)
+        for k in 1:maxiters
+            step!(st)
+            round(a*log(k+1)) - round(a*log(k)) == 0 && continue
+            stepdata = dataf(st)
+            for (dataname, data) in pairs(stepdata)
+                push!(getproperty(df, Symbol(algname, "_", dataname)), data)
+            end
+        end
+    end
+
+    return df, states
+end
+
+comparison_algs(prob; τ, M, overlap, ninner) = (
+    glob = NStepAlgorithm(ChambolleAlgorithm(prob; τ), ninner),
+    ddseq = DualTVDDAlgorithm(prob; M, overlap, ninner, parallel=false, σ=1., subalg=x->ChambolleAlgorithm(x; τ)),
+    ddseqav = DualTVDDAlgorithm(prob; M, overlap, ninner, parallel=false, σ=0.25, subalg=x->ChambolleAlgorithm(x; τ)),
+    ddpar = DualTVDDAlgorithm(prob; M, overlap, ninner, parallel=true, σ=0.25, subalg=x->ChambolleAlgorithm(x; τ)))
+
+function calc_energymin(prob, alg; maxiters)
+    st = init(alg)
+    for _ in 1:maxiters
+        step!(st)
+    end
+    return energy(fetch(st), prob)
+end
+
+# Experiment Suite
+
+function compare_algs(prob; τ, M, overlap, maxiters, ninner)
+    algs = comparison_algs(prob; τ, M, overlap, ninner)
+
+    df, states = run_algs(algs; maxiters=maxiters ÷ 10) do state
+        return (
+            energy = energy(fetch(state), prob),
+            residual = residual(fetch(state), prob))
+    end
+
+    #filter!(:k => k -> k < maxiters / 10, df)
+
+    energymin = calc_energymin(prob, algs.glob; maxiters)
+    for x in names(df)
+        contains(x, r"_energy$") || continue
+        df[!,Symbol(x)] .-= energymin
+    end
+
+    return df, states, energymin
+end
+
+function run_while(fwhile, alg)
+    st = init(alg)
+    k = 0
+    while fwhile(st, k)
+        k += 1
+        step!(st)
+    end
+    return st
+end
+
+function suite(::Path{(:convergence, :test)}, input, output)
+    #fo = loadimg(input("input_original.png"))
+
+    #λ = 0.1
+    #β = 0.
+    #maxiters = 10
+    #ninner = 10
+
+    #M = (2,2)
+    #overlap = (5,5)
+
+    #noise_σ = 0.1
+
+    #f = clamp.(fo .+ noise_σ * randn(Float64, size(fo)), 0., 1.)
+    #saveimg(output("input_noisy.png"), f)
+
+    #prob = DenoiseProblem(f; λ, β)
+
+    fo = f0 = loadimg(input("input_f0.png"))
+    f1 = loadimg(input("input_f1.png"))
+
+    λ = 0.002
+    β = 0.01
+
+    maxiters = 100
+    ninner = 1000
+
+    M = (4,4)
+    overlap = (5,5)
+
+    prob = OptFlowProblem(f0, f1; λ, β)
+
+    algs = (;
+        #glob = ChambolleAlgorithm(prob),
+        #surrogate = SurrogateAlgorithm(prob; ninner=100, τ=2*normB(prob)+eps(normB(prob)),
+        #                               subalg=x->ChambolleAlgorithm(x)),
+
+        surrogate_ddseq = SurrogateAlgorithm(prob; ninner=1, τ = normB(prob) + eps(normB(prob)),
+            subalg = x -> DualTVDDAlgorithm(x; M, overlap, ninner, parallel = false, σ = 1.,
+                subalg = x -> ChambolleAlgorithm(x))),
+        ddseq_surrogate = DualTVDDAlgorithm(prob; M, overlap, ninner, parallel = false, σ = 1.,
+            subalg = x -> SurrogateAlgorithm(x; ninner=1, τ = normB(x) + eps(normB(x)),
+                subalg = x -> ChambolleAlgorithm(x))),
+        #ddseq = DualTVDDAlgorithm(prob; M, overlap, ninner, parallel = false, σ = 1.,
+        #    subalg = x -> ChambolleAlgorithm(x)),
+       )
+
+    #algs = comparison_algs(prob; τ, M, overlap, ninner)
+
+    df, states = run_algs(algs; maxiters) do state
+        return (
+            energy = energy(fetch(state), prob),
+            residual = residual(fetch(state), prob))
+    end
+    display(df)
+
+    CSV.write(output("energies.csv"), df)
+    #saveimg(output("output_glob.png"), fetch_u(states.glob))
+    savedata(output("data.tex"); lambda=λ, beta=β, maxiters,
+        width=size(fo, 2), height=size(fo, 1))
+end
+
+function suite(::Path{(:scaling, :opticalflow)}, input, output)
+    fo = f0 = loadimg(input("frame10.png"))
+    f1 = loadimg(input("frame11.png"))
+    d = 2
+
+    λ = 0.01
+    β = 0.001
+
+    ninner = 300
+    Mdir = 2 * floor(Int, sqrt(nworkers()))
+    M = (Mdir, Mdir)
+    overlap = (5, 5)
+
+    stopenergy = 130.
+    ntimings = 3
+
+    prob = OptFlowProblem(f0, f1; λ, β)
+    #return prob
+
+    galg = ChambolleAlgorithm(prob)
+    dalg(workers) =
+        DualTVDDAlgorithm(prob;
+            workers, M, overlap, ninner, parallel=false, σ=1.,
+            subalg = x -> ChambolleAlgorithm(x))
+
+    function timeit(alg)
+        # precompile
+        run_while((_, _) -> false, alg)
+
+        times = map(1:ntimings) do _
+            return @elapsed run_while(alg) do st, k
+                # min ~107
+                return energy(fetch(st), prob) > stopenergy
+            end
+        end
+        return minimum(times)
+    end
+
+    tg = timeit(galg)
+
+    ws = workers()
+    df = DataFrame()
+    for np in 0:Mdir÷2
+        nw = 2^np
+        push!(df, (
+            nworkers = nw,
+            time = timeit(dalg(ws[1:nw]))))
+    end
+
+    display(df)
+
+    CSV.write(output("timings.csv"), df)
+    #saveimg(output("output_glob.png"), fetch_u(states.glob))
+    savedata(output("data.tex"); lambda=λ, beta=β, Mdir,
+        ntimings, stopenergy, ninner,
+        width=size(fo, 2), height=size(fo, 1))
+end
+
+function prob_outerinner(input)
+end
+
+suite(::Path{(:surrogate, :outerinner)}, input, output) =
+    _surrogate_outerinner(input, output, false)
+suite(::Path{(:surrogate, :outerinner_ref)}, input, output) =
+    _surrogate_outerinner(input, output, true)
+
+function _surrogate_outerinner(input, output, ref)
+    fo = f0 = loadimg(input("frame10.png"))
+    f1 = loadimg(input("frame11.png"))
+
+    λ = 0.01
+    β = 0.001
+    prob = OptFlowProblem(f0, f1; λ, β)
+
+    maxiters = 100
+    ninner = 50
+    minenergy_maxiters = 10 * maxiters * ninner
+
+    M = (4,4)
+    overlap = (50,50)
+
+    # set B = I for reference
+    if ref
+        prob.B.diag .= Ref(Matrix(I, 2, 2))
+    end
+
+    energymin = calc_energymin(prob, ChambolleAlgorithm(prob); maxiters=minenergy_maxiters)
+
+    algs = (;
+        surrogate_ddseq = SurrogateAlgorithm(prob; ninner=1, τ = normB(prob) + eps(normB(prob)),
+            subalg = x -> DualTVDDAlgorithm(x; M, overlap, ninner, parallel = false, σ = 1.,
+                subalg = x -> ChambolleAlgorithm(x))),
+        #surrogate_ddpar = SurrogateAlgorithm(prob; ninner=1, τ = normB(prob) + eps(normB(prob)),
+        #    subalg = x -> DualTVDDAlgorithm(x; M, overlap, ninner, parallel = true, σ = 0.25,
+        #        subalg = x -> ChambolleAlgorithm(x))),
+        ddseq_surrogate = DualTVDDAlgorithm(prob; M, overlap, ninner=1, parallel = false, σ = 1.,
+            subalg = x -> SurrogateAlgorithm(x; ninner, τ = normB(x) + eps(normB(x)),
+                subalg = x -> ChambolleAlgorithm(x))),
+        #ddpar_surrogate = DualTVDDAlgorithm(prob; M, overlap, ninner=1, parallel = true, σ = 0.25,
+        #    subalg = x -> SurrogateAlgorithm(x; ninner, τ = normB(x) + eps(normB(x)),
+        #        subalg = x -> ChambolleAlgorithm(x))),
+       )
+
+    df, states = run_algs(algs; maxiters) do state
+        return (
+            energy = energy(fetch(state), prob) - energymin,
+            #residual = residual(fetch(state), prob),
+           )
+    end
+    display(df)
+
+    CSV.write(output("energies.csv"), df)
+    #saveimg(output("output_glob.png"), fetch_u(states.glob))
+    savedata(output("data.tex"); lambda=λ, beta=β, minenergy_maxiters, maxiters, ninner, M, overlap,
+        width=size(fo, 2), height=size(fo, 1))
+end
+
+function suite(::Path{(:convergence, :denoising)}, input, output)
+    fo = loadimg(input("input_original.png"))
+
+    λ = 0.1
+    β = 0.
+    maxiters = 10000
+    ninner = 100
+
+    M = (2,2)
+    overlap = (5,5)
+
+    noise_σ = 0.1
+
+    f = clamp.(fo .+ noise_σ * randn(Float64, size(fo)), 0., 1.)
+    saveimg(output("input_noisy.png"), f)
+
+    prob = DenoiseProblem(f; λ, β)
+
+    τ = inv(8 * normB(prob))
+    df, states, energymin = compare_algs(prob; τ, M, overlap, maxiters, ninner)
+
+    CSV.write(output("energies.csv"), df)
+    saveimg(output("output_glob.png"), fetch_u(states.glob))
+    savedata(output("data.tex"); lambda=λ, beta=β, tau=τ, maxiters, noise_sigma=noise_σ, energymin,
+        width=size(fo, 2), height=size(fo, 1))
+end
+
+function suite(::Path{(:convergence, :inpainting)}, input, output)
+    fo = loadimg(input("input_original.png"))
+
+    λ = 0.05
+    β = 0.001
+    maxiters = 100000
+    ninner = 100
+
+    M = (2,2)
+    overlap = (5,5)
+
+    f_mask = rand(Float64, size(fo)) .> 0.5
+
+    prob = InpaintProblem(fo, f_mask; λ, β)
+    saveimg(output("input_mask.png"), f_mask)
+    saveimg(output("input_g.png"), prob.g)
+
+    τ = inv(8 * normB(prob))
+    df, states, energymin = compare_algs(prob; τ, M, overlap, maxiters, ninner)
+
+    CSV.write(output("energies.csv"), df)
+    saveimg(output("output_glob.png"), fetch_u(states.glob))
+    savedata(output("data.tex"); lambda=λ, beta=β, tau=τ, maxiters, energymin,
+        width=size(fo, 2), height=size(fo, 1))
+end
+
+function suite(::Path{(:convergence, :opticalflow)}, input, output)
+    f0 = loadimg(input("input_f0.png"))
+    f1 = loadimg(input("input_f1.png"))
+
+    λ = 0.002
+    β = 0.001
+
+    maxiters = 100000
+    ninner = 100
+
+    M = (2,2)
+    overlap = (5,5)
+
+    prob = OptFlowProblem(f0, f1; λ, β)
+
+    τ = inv(8 * normB(prob))
+    df, states, energymin = compare_algs(prob; τ, M, overlap, maxiters, ninner)
+
+    CSV.write(output("energies.csv"), df)
+
+    cflow = colorflow(fetch_u(first(states)); maxflow=4.5/(584/48))
+    #p = plot(cflow); display(p)
+    save(output("flow.png"), cflow)
+
+    savedata(output("data.tex"); lambda=λ, beta=β, tau=τ, maxiters, energymin,
+        width=size(f0, 2), height=size(f0, 1))
+end
+
+function dwt!(y, x)
+    a = sqrt(1 / 2)
+    n = length(x)
+    n <= 1 && return (y .= x)
+    # use second half of y as scratch space
+    for i in 1:n÷2
+        j = 2*(i-1)+1
+        y[n÷2+i] = a * x[j] + a * x[j+1]
+    end
+    dwt!(view(y, 1:n÷2), view(y, n÷2+1:2*(n÷2)))
+    for i in 1:n÷2
+        j = 2*(i-1)+1
+        y[n÷2+i] = a * x[j] - a * x[j+1]
+    end
+    isodd(n) && (y[n] = x[n])
+    return y
+end
+
+function idwt!(y, x)
+    a = sqrt(1 / 2)
+    n = length(x)
+    n <= 1 && return (y .= x)
+    isodd(n) && (y[n] = x[n])
+    # use second half of y as scratch space
+    idwt!(view(y, n÷2+1:2*(n÷2)), view(x, 1:n÷2))
+    for i in 1:n÷2
+        j = 2*(i-1)+1
+        y[j]   = a * y[n÷2+i] + a * x[n÷2+i]
+        y[j+1] = a * y[n÷2+i] - a * x[n÷2+i]
+    end
+    return y
+end
+
+# TODO: non-allocating
+function mdwt!(y, x)
+    d = ndims(x)
+    s = size(x)
+    any(s .<= 1) && return (y .= x)
+
+    # transformation matrix
+    M = [sqrt(1/2^d)*(-1)^count_ones(i&j) for i in 0:2^d-1, j in 0:2^d-1]
+
+    offset = s.÷2
+    firsthalf = Base.OneTo.(offset)
+    for i in Iterators.product(firsthalf...)
+        j = @. 2*(i-1)+1
+
+        src_ix = ntuple(k->j[k]:1+j[k], d)
+        dst_ix = ntuple(k->i[k]:offset[k]:offset[k]+i[k], d)
+
+        src = vec(view(x, src_ix...))
+        dst = vec(view(y, dst_ix...))
+        mul!(dst, M, src)
+    end
+
+    mdwt!(view(y, firsthalf...), y[firsthalf...])
+
+    for k in 1:d
+        iseven(s[k]) && continue
+        selectdim(y, k, s[k]) .= selectdim(x, k, s[k])
+    end
+
+    return y
+end
+
+# TODO: non-allocating
+function imdwt!(y, x)
+    d = ndims(x)
+    s = size(x)
+    any(s .<= 1) && return (y .= x)
+
+    offset = s .÷ 2
+    firsthalf = Base.OneTo.(offset)
+
+    # transformation matrix
+    M = [sqrt(1 / 2^d)*(-1)^count_ones(i&j) for i in 0:2^d-1, j in 0:2^d-1]
+
+    for k in 1:d
+        iseven(s[k]) && continue
+        selectdim(y, k, s[k]) .= selectdim(x, k, s[k])
+    end
+
+    xt = copy(x)
+    imdwt!(view(xt, firsthalf...), x[firsthalf...])
+
+    for i in Iterators.product(firsthalf...)
+        j = @. 2*(i-1)+1
+
+        src_ix = ntuple(k->i[k]:offset[k]:offset[k]+i[k], d)
+        dst_ix = ntuple(k->j[k]:1+j[k], d)
+
+        src = vec(view(xt, src_ix...))
+        dst = vec(view(y, dst_ix...))
+        mul!(dst, M, src)
+    end
+
+    return y
+end
+mdwt(x) = mdwt!(similar(x), x)
+imdwt(x) = imdwt!(similar(x), x)
+
+function suite(::Path{(:global, :basic)}, input, output)
+    f = loadimg(input("input_original.png"))
+    #f = loadimg(input("frame10_small.png"))
+    ax = axes(f)
+
+    seed = 42
+    rng = MersenneTwister(seed)
+
+    λ = 0.02
+    β = 1e-3
+
+    #maxiters = 100000
+    maxiters = 100
+    ninner = 1000
+
+    M = (4,4)
+    overlap = (5,5)
+
+    n = length(f)
+    wr = rand(rng, 1:n, n÷2)
+    #wr = n÷4:n÷2
+
+    A = LinearMap{Float64}(
+        (y, x) -> (mdwt!(reshape(y, ax), reshape(x, ax)); y[wr] .= 0; y),
+        (y, x) -> (x[wr] .= 0; imdwt!(reshape(y, ax), reshape(x, ax))),
+        # no longer symmetric
+        n, n, issymmetric=false, isposdef=false)
+
+    #A = rand(rng, n, n) ./ n
+    #A = diagm(rand(rng, n))
+
+    #A = LinearMap{Float64}(x -> x, x -> x, n, n, issymmetric=true, isposdef=true)
+
+    prob = GlobalProblem(f, A; λ, β)
+
+
+    #τ = inv(8 * normB(prob))
+
+    algref = ChambolleAlgorithm(prob, τ=β/8)
+    st = init(algref)
+    u0 = fetch_u(st)
+
+    #alg = ChambolleAlgorithm(prob, τ=β/8)
+
+    τ = 2/β
+    alg = DualTVDDSurrogateAlgorithm(prob; M, overlap, ninner, τ, parallel=false)
+
+    #return alg
+    #alg = DualTVDDAlgorithm(prob; M, overlap, ninner)
+
+    #display(fetch(st))
+    #display(fetch_u(st))
+    #step!(st)
+    #display(fetch(st))
+    #display(fetch_u(st))
+    #step!(st)
+    #display(fetch(st))
+    #display(fetch_u(st))
+    #return
+
+    df, states = run_algs([alg]; maxiters=maxiters) do state
+        return (
+            energy = energy(fetch(state), prob),
+            residual = residual(fetch(state), prob))
+    end
+
+    #energymin = calc_energymin(prob, algref; maxiters)
+    #for x in names(df)
+    #    contains(x, r"_energy$") || continue
+    #    df[!,Symbol(x)] .-= energymin
+    #end
+
+    CSV.write(output("energies.csv"), df)
+
+    u = fetch_u(states[1])
+    #display(u)
+    p = plot(plot(toimg(f)), plot(toimg(u0)), plot(toimg(u)))
+
+    saveimg(output("input_orig.png"), f)
+    saveimg(output("input_g.png"), prob.g)
+    saveimg(output("output_u.png"), u)
+
+
+    display(p)
+
+
+    savedata(output("data.tex"); lambda=λ, beta=β, tau=τ, maxiters, ninner,
+        width=size(f, 2), height=size(f, 1))
+    return prob
+end
+
+
+function halve(img)
+    all(iseven.(size(img))) || throw(ArgumentError("uneven size"))
+
+    res = similar(img, size(img) .÷ 2)
+    fill!(res, zero(eltype(res)))
+
+    for i in CartesianIndices(img)
+        j = CartesianIndex((Tuple(i) .+ 1) .÷ 2)
+        res[j] += img[i]
+    end
+    res ./= 2 ^ ndims(img)
+
+    return res
+end
+
+
+"""
+    logfilter(dt; a=20)
+
+Reduce dataset such that the resulting dataset would have approximately
+equidistant datapoints on a log-scale. `a` controls density.
+"""
+logfilter(dt; a=20) = filter(:k => k -> round(a*log(k+1)) - round(a*log(k)) > 0, dt)
+
+#function calcmin(f, alg)
+#    ctx = init(alg)
+#    fmin = f(ctx)
+#    while true
+#        step!(ctx)
+#        fcur = f(ctx)
+#        fcur >= fmin && break
+#        fmin = min(fmin, fcur)
+#    end
+#    return fmin
+#end
+#
+#function seq(f; start, length)
+#    res = Vector{Float64}(undef, length)
+#    res[1] = f(1, start)
+#    for i in 2:length
+#        res[i] = f(i, res[i-1])
+#    end
+#    return res
+#end
+#
+#estmin(fk; p = 1) = estmin(axes(fk, 1), fk; p)
+#function estmin(k, fk; p = 1, last=length(k)-ceil(Int, 10^(log10(length(k)) * (1-1/3))))
+#    k = k[end-last+1:end]
+#    fk = fk[end-last+1:end]
+#
+#    #res = optimize(x -> minimum(fk) .- x[1] <= 0 || x[2] <= 0 ? NaN : sum((log.(fk .- x[1]) .+ 1*log.(k) .+ log(x[2])).^2), [-Inf, nextfloat(0.)], [nextfloat(minimum(fk)), Inf], [minimum(fk)-1, 1.], Fminbox())
+#
+#    #return res.minimizer[1]
+#
+#    A = hcat(ones(length(k)), (1 ./ k) .^ p)
+#    c0, c1 = A \ fk
+#    return c0
+#end
diff --git a/scripts/util.jl b/scripts/util.jl
new file mode 100644
index 0000000..36e1c57
--- /dev/null
+++ b/scripts/util.jl
@@ -0,0 +1,88 @@
+module Util
+
+using FileIO, CSV
+
+export Path, File, savedata, execute_all, execute_single
+
+struct Path{T} end
+
+Base.print(io::IO, path::Path{T}) where T = write(io, joinpath(path...))
+
+function Base.iterate(::Path{T}, state=1) where T
+    state > length(T) && return nothing
+    return string(T[state]), state + 1
+end
+
+struct File
+    root::String
+    path::Path
+    name::String
+end
+
+function execute_all(suite, root)
+    for method in methods(suite)
+        path = method.sig.parameters[2]()
+        execute_single(suite, path, root)
+    end
+end
+
+function execute_single(suite, path, root)
+    println("running `$(path)` ...")
+    input = x -> File(root, path, x)
+    output = x -> File(root, path, x)
+    suite(path, input, output)
+end
+
+FileIO.load(file::File) = load(joinpath(file.root, file.path..., file.name))
+FileIO.save(file::File, x) = save(joinpath(file.root, file.path..., file.name), x)
+CSV.write(file::File, x) = CSV.write(joinpath(file.root, file.path..., file.name), x)
+
+savedata(file::File; data...) =
+    open(joinpath(file.root, file.path..., file.name); write=true) do io
+        write_texdata(io, file.path; data...)
+    end
+
+isvalidname(x) = contains(string(x), r"^[^/\\]+$")
+
+Base.show(io, ::MIME"text/latex", x) = print(io, x)
+function Base.show(io::IO, ::MIME"text/latex", x::AbstractFloat)
+    exponent = x == 0. ? 0 : floor(Int, log10(x))
+    if abs(exponent) <= 3
+        print(io, "\\ensuremath{", x, "}")
+    else
+        base = x / 10. ^ exponent
+        print(io, "\\ensuremath{", base, "\\cdot 10^{", exponent, "}}")
+    end
+end
+function Base.show(io::IO, ::MIME"text/latex", x::Integer)
+    p = log10(x)
+    pr = round(Int, p)
+    if x == 10^pr
+        print(io, "\\ensuremath{10^{", pr, "}}")
+    else
+        print(io, "\\ensuremath{", x, "}")
+    end
+end
+
+function write_texdata(io, path; data...)
+    texcmd = "Data"
+    # data access tex-command
+    write(io, """
+        \\providecommand{\\$(texcmd)}[1]{
+            \\csname $(texcmd)/#1\\endcsname
+        }
+        """)
+
+    for (key, value) in pairs(data)
+        isvalidname(key) && isvalidname(value) ||
+            throw(ArgumentError("invalid key/value: $(key => value)"))
+
+        # actual data encoded as tex-commands
+        write(io, "\\expandafter\\def")
+        write(io, "\\csname $(texcmd)/$(join(path, "/"))/$(key)\\endcsname{")
+        show(io, MIME("text/latex"), value)
+        write(io, "}\n")
+    end
+end
+
+end
-- 
GitLab