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

using Markdown
using InteractiveUtils

# ╔═╡ c6246074-6ee3-11ec-0279-23f36ba7bb51
using Pkg

# ╔═╡ 161039a4-9da6-4339-8a18-d98e20fe3d20
using Interact

# ╔═╡ b07f6111-9897-4589-8c88-98fa55c02e75
using CSV

# ╔═╡ 99e6b1f9-0b37-475e-ba7d-d5c52fe9c776
using DataFrames

# ╔═╡ a2be8c66-f666-4683-b425-d598003c1188
using WebIO

# ╔═╡ 8698b51c-c5f3-4f8a-a7fb-c5043c8eabeb
using Plots

# ╔═╡ fec5714a-40cd-4de2-87c3-9d16bea6f2e1
using Dates

# ╔═╡ c624604c-6ee3-11ec-2a15-bbe6fcffde98
html"""

Happy holiday! Remember to take care of yourself and your loved ones!

"""

# ╔═╡ 9ec943f6-80e5-4432-ab9c-4ed07d2edf8d
url ="https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv"

# ╔═╡ 473d0971-00d6-4b9b-8a5e-6ad29031e0ee
download(url, "covid_data.csv")

# ╔═╡ 96c190fc-191b-4c78-ac07-e9a80bc36534
CSV.read("covid_data.csv", DataFrame)

# ╔═╡ 58178f67-6c78-42c0-8b69-e0c69abcad4c
data = CSV.read("covid_data.csv", DataFrame);

# ╔═╡ 46d524f6-c982-4fff-b08d-548a22b83c29
data

# ╔═╡ c6b7e0d6-6d5c-40bf-ace1-dc0b6b2886b7
countries = collect(data[:,2])

# ╔═╡ 7b8d012a-a96a-497a-ac53-498b5d7170b4
unique_countries = unique(countries)

# ╔═╡ f22021a8-6049-4fd8-a8cc-2dd901633f49
startswith("I")

# ╔═╡ add27458-66d4-4e14-ada0-21a84e4a5117
I_countries = [startswith(country,"I") for country in countries];

# ╔═╡ 31353f8c-fbcd-4eda-8628-faeea9c9135a
data[I_countries, :]

# ╔═╡ 0aa83a4f-bfa5-4ed4-a855-fc87c3f49620
 countries .== "India"

# ╔═╡ 52bdb813-f51f-4b9f-94a5-6512313c059a
IND_row = findfirst(countries .=="India")

# ╔═╡ 6276d8b2-1d80-445e-b9fd-ce41108a2e1f
IND_data_row = data[IND_row, :]

# ╔═╡ 03a08a0a-d924-4eef-87a3-93b2b91bcec7
IND_data = collect(IND_data_row[5:end])

# ╔═╡ c94ecc1a-0bd0-42bd-b179-64afb4f1a6c9
plot(IND_data);

# ╔═╡ 91bfd14c-3766-49b4-ac37-24a5a45ea940
date_strings = String.(names(data))[5:end]

# ╔═╡ a2a8b9c2-f86a-4532-bcdc-2501b2a855ef
format = Dates.DateFormat("m/d/Y")

# ╔═╡ 4f756d10-ee41-420f-bd71-435a0e5856f2
dates = parse.(Date, date_strings, format) + Year(2000);

# ╔═╡ 037105b4-7bad-4641-b180-21c4eae3c184
plot(dates,IND_data, xticks=dates[1:60:end], xrotation=45, leg=:topleft, label="India COVID-19 Cases");

# ╔═╡ 9299543d-a043-4b10-b77e-1b60aebbe428
xlabel!("Date");

# ╔═╡ c88fe033-428c-4924-8d32-7b68d9d3a1ea
ylabel!("India Confirmed Cases")

# ╔═╡ 0c575356-9b02-4544-b9d4-2adb74785116
``I_{n+1} = I_n + (cI_n)``

# ╔═╡ fada77cc-8d79-46c0-a618-bb02d006be0f
I0 = 1

# ╔═╡ 9586acfa-accb-4ec8-8c11-8b3e36a97c01
I_0 = 1

# ╔═╡ 3c796505-f698-4ad8-bd17-f202e326eb56
I₀ = 1

# ╔═╡ fa2b70c3-b40b-4787-bb62-5c3cf0bb2125
c = 0.01  # average no. of people that each individual infects on each day

# ╔═╡ 26e1a780-7559-43b4-8e1f-3329b537f26f
λ = 1 + c ;

# ╔═╡ dca94f80-4f30-4339-9d9d-343607fcac83
I_1 = λ * I_0

# ╔═╡ 2c04f0d0-54a3-490f-8611-91f9a723205c
I_2 = λ * I_1

# ╔═╡ ea0098e0-93b2-49f9-a228-8ba1065607c0
I_3 = λ * I_2

# ╔═╡ 349ba73c-b638-4097-83dc-30f5cb92f59e
T=20

# ╔═╡ 261b66b3-46ff-4854-b7ce-83c05a59dadc
I = zeros(T)

# ╔═╡ a929e0c6-9935-4f59-9091-e0ce658abdfd
I[1] = I_0

# ╔═╡ 47facd64-1f46-457f-960c-8ca42792a52c
for n in 1:T-1
    I[n+1] = λ * I[n]
    @show n, I[n]
end

# ╔═╡ f5c8696a-b515-44aa-947d-d344e77cb9f2
I

# ╔═╡ ad049c2a-88ec-471e-bb7a-0f04fddd2e62
plot(I, m=:o, label="I[n]", legend=:topleft);

# ╔═╡ 35a78396-209e-41b4-8eeb-5fb22f1b163d
p = 0.02

# ╔═╡ 8a3537a2-8245-4428-8a83-f9385c9a5386
α = 0.01

# ╔═╡ 1951c463-59cc-43ea-ac4b-f4baf7cfbed3
N = 1000

# ╔═╡ afef1536-fd7e-47cc-8b6b-a9d4e716f882
function run_infection(T=20)

    I = zeros(T)
    I[1] = I_0

    for n in 1:T-1
        I[n+1] = λ * I[n]
    end

    return I
end

# ╔═╡ 9619a8e6-a1fd-4c27-9316-dd88c0a8c020
methods(run_infection)

# ╔═╡ fbecebf9-fc52-450a-8a4a-dd3d36c930e4
run_infection(10)

# ╔═╡ c962e3c2-a620-4fb5-8263-9e50066371e0
I_result1 = run_infection(10);

# ╔═╡ 9261c9aa-9101-43d8-8b5f-008191bd6965
end_T = 1000

# ╔═╡ d5e31593-ee2b-4d73-a7ff-06e5d7f2f691
plot(run_infection(1000),label="Exponential Infection Growth")

# ╔═╡ 612159b5-4cbb-4132-9e4d-7c8b712622e5
plot(run_infection(1000), yscale=:log10, label="Logarithmic Scale")

# ╔═╡ 54c37296-1fae-447b-a8fd-a792b60d2a57
I_result = run_infection(1000)

# ╔═╡ f56f1910-33c5-4ebe-8e0e-332752b8b923
I_result

# ╔═╡ d33b9f8b-9ffd-4f3f-809e-4cfdf6056d85
plot(I_result, m=:o)

# ╔═╡ 7c168d73-e3ec-4be0-9a37-d02e7afd98c7
plot(log10.(I_result))

# ╔═╡ 47990471-4301-427a-bf8a-d95e4c133b8d
ylabel!("log(I_n)")

# ╔═╡ 03ed1990-becf-4d5e-8082-b1649540b219
β(I, S) = p * α * S

# ╔═╡ 23d08bb2-a2dc-4d14-a787-c6c2997bf61b
I_20 = run_infection(20)

# ╔═╡ a559ae0b-468d-46d4-8e08-62f207ef4aa2
plot(I_20, m=:o)

# ╔═╡ bab09c8c-9d09-463f-bf2e-dd894402176a
plot(I_20, m=:o, yscale=:log10, label="Logarithmic Scale")

# ╔═╡ 23c0f7fd-facf-49e9-a4fb-c4186123a5bb
I_100= run_infection(100)

# ╔═╡ 77365d86-f39d-47ff-809e-6b7a8fc8f6f5
plot(I_100, yscale=:log10)

# ╔═╡ 390a3a67-7d80-42ea-a0e3-a29743e58dd5
c_average = 1.1

# ╔═╡ 0ce1fe85-7e68-4f61-bc22-b5c34e04f5ba
cs = [c_average + 0.1*randn() for i in 1:100]

# ╔═╡ 570b788b-1195-44a7-97c1-f2fe2c6ba828
scatter(cs)

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Interact = "c601a237-2ae4-5e1e-952c-7a85b0c7eef1"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
WebIO = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29"

[compat]
CSV = "~0.9.11"
DataFrames = "~1.3.1"
Interact = "~0.10.4"
Plots = "~1.25.4"
WebIO = "~0.8.16"
"""

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

julia_version = "1.7.0"
manifest_format = "2.0"

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

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

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

[[deps.AssetRegistry]]
deps = ["Distributed", "JSON", "Pidfile", "SHA", "Test"]
git-tree-sha1 = "b25e88db7944f98789130d7b503276bc34bc098e"
uuid = "bf4720bc-e11a-5d0c-854e-bdca1663c893"
version = "0.1.0"

[[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.CSSUtil]]
deps = ["Colors", "JSON", "Markdown", "Measures", "WebIO"]
git-tree-sha1 = "b9fb4b464ec10e860abe251b91d4d049934f7399"
uuid = "70588ee8-6100-5070-97c1-3cb50ed05fe8"
version = "0.1.1"

[[deps.CSV]]
deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings"]
git-tree-sha1 = "49f14b6c56a2da47608fe30aed711b5882264d7a"
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
version = "0.9.11"

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

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

[[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 = "a851fec56cb73cfdf43762999ec72eff5b86882a"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.15.0"

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

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

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

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

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

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

[[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 = "cfdfef912b7f93e4b848e80b9befdf9e331bc05a"
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
version = "1.3.1"

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

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

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

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

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

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

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

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

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

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

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

[[deps.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.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.FunctionalCollections]]
deps = ["Test"]
git-tree-sha1 = "04cb9cfaa6ba5311973994fe3496ddec19b6292a"
uuid = "de31a74c-ac4f-5751-b3fd-e18cd04993ca"
version = "0.5.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 = "0c603255764a1fa0b61752d2bec14cfbd18f7fe8"
uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
version = "3.3.5+1"

[[deps.GR]]
deps = ["Base64", "DelimitedFiles", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "Sockets", "Test", "UUIDs"]
git-tree-sha1 = "b9a93bcdf34618031891ee56aad94cfff0843753"
uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
version = "0.63.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 = "f97acd98255568c3c9b416c5a3cf246c1315771b"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.63.0+0"

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

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

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

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

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

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

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

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

[[deps.InlineStrings]]
deps = ["Parsers"]
git-tree-sha1 = "8d70835a3759cdd75881426fced1508bb7b7e1b6"
uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48"
version = "1.1.1"

[[deps.Interact]]
deps = ["CSSUtil", "InteractBase", "JSON", "Knockout", "Observables", "OrderedCollections", "Reexport", "WebIO", "Widgets"]
git-tree-sha1 = "311f9130aeb50ac93a12dd076fa02c9a430be525"
uuid = "c601a237-2ae4-5e1e-952c-7a85b0c7eef1"
version = "0.10.4"

[[deps.InteractBase]]
deps = ["Base64", "CSSUtil", "Colors", "Dates", "JSExpr", "JSON", "Knockout", "Observables", "OrderedCollections", "Random", "WebIO", "Widgets"]
git-tree-sha1 = "caf189c84e1cc6512b71fea0ec60fa8fdc761d7b"
uuid = "d3863d7c-f0c8-5437-a7b4-3ae773c01009"
version = "0.10.7"

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

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

[[deps.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.IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

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

[[deps.JSExpr]]
deps = ["JSON", "MacroTools", "Observables", "WebIO"]
git-tree-sha1 = "bd6c034156b1e7295450a219c4340e32e50b08b1"
uuid = "97c1335a-c9c5-57fe-bc5d-ec35cebe8660"
version = "0.5.3"

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

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

[[deps.Knockout]]
deps = ["JSExpr", "JSON", "Observables", "Test", "WebIO"]
git-tree-sha1 = "deb74017e1061d76050ff68d219217413be4ef59"
uuid = "bcebb21b-c2e3-54f8-a781-646b90f6d2cc"
version = "0.2.5"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[deps.OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "15003dcb7d8db3c6c857fda14891a539a8f2705a"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.10+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.Parsers]]
deps = ["Dates"]
git-tree-sha1 = "d7fa6237da8004be601e19bd6666083056649918"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.1.3"

[[deps.Pidfile]]
deps = ["FileWatching", "Test"]
git-tree-sha1 = "1be8660b2064893cd2dae4bd004b589278e4440d"
uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307"
version = "1.2.0"

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

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

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

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

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

[[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 = "2cf929d64681236a2e074ffafb8d568733d2e6af"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.3"

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

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

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

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

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

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

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

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

[[deps.Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "8f82019e525f4d5c669692772a6f4b0a58b06a6a"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.2.0"

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

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

[[deps.SentinelArrays]]
deps = ["Dates", "Random"]
git-tree-sha1 = "244586bc07462d22aed0113af9c731f2a518c93e"
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
version = "1.3.10"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[deps.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.Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

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

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

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

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

[[deps.WeakRefStrings]]
deps = ["DataAPI", "InlineStrings", "Parsers"]
git-tree-sha1 = "c69f9da3ff2f4f02e811c3323c22e5dfcb584cfa"
uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5"
version = "1.4.1"

[[deps.WebIO]]
deps = ["AssetRegistry", "Base64", "Distributed", "FunctionalCollections", "JSON", "Logging", "Observables", "Pkg", "Random", "Requires", "Sockets", "UUIDs", "WebSockets", "Widgets"]
git-tree-sha1 = "5fe32e4086d49f7ab9b087296742859f3ae6d62a"
uuid = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29"
version = "0.8.16"

[[deps.WebSockets]]
deps = ["Base64", "Dates", "HTTP", "Logging", "Sockets"]
git-tree-sha1 = "f91a602e25fe6b89afc93cf02a4ae18ee9384ce3"
uuid = "104b5d7c-a370-577a-8038-80a2059c5097"
version = "1.5.9"

[[deps.Widgets]]
deps = ["Colors", "Dates", "Observables", "OrderedCollections"]
git-tree-sha1 = "80661f59d28714632132c73779f8becc19a113f2"
uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62"
version = "0.6.4"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

# ╔═╡ Cell order:
# ╟─c624604c-6ee3-11ec-2a15-bbe6fcffde98
# ╠═c6246074-6ee3-11ec-0279-23f36ba7bb51
# ╠═161039a4-9da6-4339-8a18-d98e20fe3d20
# ╠═9ec943f6-80e5-4432-ab9c-4ed07d2edf8d
# ╠═473d0971-00d6-4b9b-8a5e-6ad29031e0ee
# ╠═b07f6111-9897-4589-8c88-98fa55c02e75
# ╠═99e6b1f9-0b37-475e-ba7d-d5c52fe9c776
# ╠═96c190fc-191b-4c78-ac07-e9a80bc36534
# ╠═58178f67-6c78-42c0-8b69-e0c69abcad4c
# ╠═46d524f6-c982-4fff-b08d-548a22b83c29
# ╠═c6b7e0d6-6d5c-40bf-ace1-dc0b6b2886b7
# ╠═7b8d012a-a96a-497a-ac53-498b5d7170b4
# ╠═a2be8c66-f666-4683-b425-d598003c1188
# ╠═f22021a8-6049-4fd8-a8cc-2dd901633f49
# ╠═add27458-66d4-4e14-ada0-21a84e4a5117
# ╠═31353f8c-fbcd-4eda-8628-faeea9c9135a
# ╠═0aa83a4f-bfa5-4ed4-a855-fc87c3f49620
# ╠═52bdb813-f51f-4b9f-94a5-6512313c059a
# ╠═6276d8b2-1d80-445e-b9fd-ce41108a2e1f
# ╠═03a08a0a-d924-4eef-87a3-93b2b91bcec7
# ╠═8698b51c-c5f3-4f8a-a7fb-c5043c8eabeb
# ╠═c94ecc1a-0bd0-42bd-b179-64afb4f1a6c9
# ╠═91bfd14c-3766-49b4-ac37-24a5a45ea940
# ╠═fec5714a-40cd-4de2-87c3-9d16bea6f2e1
# ╠═a2a8b9c2-f86a-4532-bcdc-2501b2a855ef
# ╠═4f756d10-ee41-420f-bd71-435a0e5856f2
# ╠═037105b4-7bad-4641-b180-21c4eae3c184
# ╠═9299543d-a043-4b10-b77e-1b60aebbe428
# ╠═c88fe033-428c-4924-8d32-7b68d9d3a1ea
# ╠═0c575356-9b02-4544-b9d4-2adb74785116
# ╠═fada77cc-8d79-46c0-a618-bb02d006be0f
# ╠═9586acfa-accb-4ec8-8c11-8b3e36a97c01
# ╠═3c796505-f698-4ad8-bd17-f202e326eb56
# ╠═fa2b70c3-b40b-4787-bb62-5c3cf0bb2125
# ╠═26e1a780-7559-43b4-8e1f-3329b537f26f
# ╠═dca94f80-4f30-4339-9d9d-343607fcac83
# ╠═2c04f0d0-54a3-490f-8611-91f9a723205c
# ╠═ea0098e0-93b2-49f9-a228-8ba1065607c0
# ╠═261b66b3-46ff-4854-b7ce-83c05a59dadc
# ╠═a929e0c6-9935-4f59-9091-e0ce658abdfd
# ╠═349ba73c-b638-4097-83dc-30f5cb92f59e
# ╠═47facd64-1f46-457f-960c-8ca42792a52c
# ╠═f5c8696a-b515-44aa-947d-d344e77cb9f2
# ╠═ad049c2a-88ec-471e-bb7a-0f04fddd2e62
# ╠═35a78396-209e-41b4-8eeb-5fb22f1b163d
# ╠═8a3537a2-8245-4428-8a83-f9385c9a5386
# ╠═1951c463-59cc-43ea-ac4b-f4baf7cfbed3
# ╠═afef1536-fd7e-47cc-8b6b-a9d4e716f882
# ╠═9619a8e6-a1fd-4c27-9316-dd88c0a8c020
# ╠═fbecebf9-fc52-450a-8a4a-dd3d36c930e4
# ╠═c962e3c2-a620-4fb5-8263-9e50066371e0
# ╠═f56f1910-33c5-4ebe-8e0e-332752b8b923
# ╠═d33b9f8b-9ffd-4f3f-809e-4cfdf6056d85
# ╠═9261c9aa-9101-43d8-8b5f-008191bd6965
# ╠═d5e31593-ee2b-4d73-a7ff-06e5d7f2f691
# ╠═612159b5-4cbb-4132-9e4d-7c8b712622e5
# ╠═54c37296-1fae-447b-a8fd-a792b60d2a57
# ╠═7c168d73-e3ec-4be0-9a37-d02e7afd98c7
# ╠═47990471-4301-427a-bf8a-d95e4c133b8d
# ╠═03ed1990-becf-4d5e-8082-b1649540b219
# ╠═23d08bb2-a2dc-4d14-a787-c6c2997bf61b
# ╠═a559ae0b-468d-46d4-8e08-62f207ef4aa2
# ╠═bab09c8c-9d09-463f-bf2e-dd894402176a
# ╠═23c0f7fd-facf-49e9-a4fb-c4186123a5bb
# ╠═77365d86-f39d-47ff-809e-6b7a8fc8f6f5
# ╠═390a3a67-7d80-42ea-a0e3-a29743e58dd5
# ╠═0ce1fe85-7e68-4f61-bc22-b5c34e04f5ba
# ╠═570b788b-1195-44a7-97c1-f2fe2c6ba828
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_name: virajvaidya/COVIDModelling

max_issues_repo_name: virajvaidya/COVIDModelling

max_forks_repo_name: virajvaidya/COVIDModelling


text:
# ---
# title: 516. Longest Palindromic Subsequence
# id: problem516
# author: Tian Jun
# date: 2020-10-31
# difficulty: Medium
# categories: Dynamic Programming
# link: <https://leetcode.com/problems/longest-palindromic-subsequence/description/>
# hidden: true
# ---
#
# Given a string s, find the longest palindromic subsequence's length in s. You
# may assume that the maximum length of s is 1000.
#
# **Example 1:**
# Input:
#
#
#
#     "bbbab"
#
#
# Output:
#
#
#
#     4
#
#
# One possible longest palindromic subsequence is "bbbb".
#
#
#
# **Example 2:**
# Input:
#
#
#
#     "cbbd"
#
#
# Output:
#
#
#
#     2
#
#
# One possible longest palindromic subsequence is "bb".
#
#
#
# **Constraints:**
#
#   * `1 <= s.length <= 1000`
#   * `s` consists only of lowercase English letters.
#
#
## @lc code=start
using LeetCode

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

ext: jl


text:
using HTTP

r = HTTP.request("POST", "http://localhost:8765", [],
		 """{
		 \"action\": \"deckNames\",
		 \"version\": 6
		 }""")
println(r.status)
println(String(r.body))


text:
# constraints
function constraint_jacobian_configuration(mechanism, contact::ContactConstraint, body::Body)
    return constraint_jacobian_configuration(contact.model, body, nothing, nothing, mechanism.timestep)
end

function constraint_jacobian_velocity(mechanism, contact::ContactConstraint, body::Body)
    return constraint_jacobian_velocity(contact.model, body, nothing, nothing, mechanism.timestep)
end

# impulses
function impulses!(mechanism, body::Body, contact::ContactConstraint)
    body.state.d -= impulse_map(mechanism, contact, body) * contact.impulses[2]
    return
end

function impulse_map(mechanism, contact::ContactConstraint, body::Body)
    return impulse_map(contact.model, body, nothing, nothing, mechanism.timestep)
end

function impulse_map_jacobian_configuration(mechanism, body::Body, contact::ContactConstraint{T}) where T
    x, q = next_configuration(body.state, mechanism.timestep)
    model = contact.model
    X = force_mapping(model, x, q)
    λ = X' * contact.impulses[2]

    ∇Q = skew(model.contact_point - vector_rotate(model.offset, inv(q))) * VRmat(q) * ∂LᵀVᵀmat∂q(λ)
    ∇Q += skew(model.contact_point - vector_rotate(model.offset, inv(q))) * ∂VRmat∂q(LᵀVᵀmat(q) * λ)
    ∇Q += -∂skew∂p(VRmat(q) * LᵀVᵀmat(q) * λ) * ∂rotation_matrix_inv∂q(q, model.offset)
    Z3 = szeros(T,3,3)
    Z4 = szeros(T,3,4)
    return [Z3 Z4;
            Z3 ∇Q]
end

function impulses_jacobian_velocity!(mechanism, body::Body, contact::ContactConstraint{T,N,Nc,Cs,N½}) where {T,N,Nc,Cs,N½}
    timestep= mechanism.timestep
    body.state.D -= impulse_map_jacobian_configuration(mechanism, body, contact) * integrator_jacobian_velocity(body, timestep)
    return
end

# off-diagonal terms for linear system
function off_diagonal_jacobians(mechanism, body::Body, contact::ContactConstraint{T,N,Nc,Cs,N½}) where {T,N,Nc,Cs,N½}
    Z = szeros(T,N½,6)
    return [Z' -impulse_map(mechanism, contact, body)], [Z; constraint_jacobian_velocity(mechanism, contact, body)]
end

# reset variables using cone-specific neutral vector
function reset!(contact::ContactConstraint{T,N,Nc,Cs,N½}; scale::T=1.0) where {T,N,Nc,Cs,N½}
    contact.impulses_dual[1] = scale * neutral_vector(contact.model)
    contact.impulses_dual[2] = scale * neutral_vector(contact.model)
    contact.impulses[1] = scale * neutral_vector(contact.model)
    contact.impulses[2] = scale * neutral_vector(contact.model)
    return
end

# dimension of cone
cone_degree(contact::ContactConstraint) = sum(cone_degree(contact.model))


text:
import Base.iterate

mutable struct WordStream
    fp::IO
    startpoint::Int
    endpoint::Int
    buffer::IOBuffer

    # filter configuration
    rate::Float64   # if rate > 0, words will be subsampled according to distr
    filter::Bool    # if filter is true, only words present in the keys(distr) will be considered
    distr::Dict{String, Float64}
end

function words_of(file::IO; subsampling=(0,false,nothing), startpoint=-1, endpoint=-1)
    rate, filter, distr = subsampling
    WordStream(file, startpoint, endpoint, IOBuffer(), rate, filter, (rate==0 && !filter) ? Dict{String,Float64}() : distr)
end

function iterate(ws::WordStream, state)
    # NEXT / DONE
    while !eof(ws.fp)
        if ws.endpoint >= 0 && position(ws.fp) > ws.endpoint
            break
        end
        c = read(ws.fp, Char)
        if c == ' ' || c == '\n' || c == '\0' || c == '\r'
            s = String(take!(ws.buffer))
            if s == "" || (ws.filter && !haskey(ws.distr, s))
                continue
            end
            if ws.rate > 0
                prob = (sqrt(ws.distr[s] / ws.rate) + 1) * ws.rate / ws.distr[s]
                if prob < rand()
                    # @printf "throw %s, prob is %f\n" s prob
                    continue
                end
            end
            write(ws.buffer, s)
            return (String(take!(ws.buffer)), state)
        else
            write(ws.buffer, c)
        end
    end
    #close(ws.fp)
    return nothing
end

function iterate(ws::WordStream)
    # START
    if ws.startpoint >= 0
        seek(ws.fp, ws.startpoint)
    else
        ws.startpoint = 0
        ws.endpoint = filesize(ws.fp)
    end

    return iterate(ws, nothing)
end

mutable struct SlidingWindow
    ws::WordStream
    lsize::Int
    rsize::Int
end

function Base.iterate(window::SlidingWindow, state=nothing)
    if state == nothing
        window_size = window.lsize + 1 + window.rsize
        state = Vector{String}(undef, window_size)
        state[1], _ = iterate(window.ws)
        for i = 2:window_size
            state[i], _ = iterate(window.ws, nothing)
        end
    end
    popfirst!(state)
    nextwindow = iterate(window.ws, nothing)
    if nextwindow == nothing
        return nothing
    end
    push!(state, nextwindow[1])
    return (state, state)
end

function sliding_window(words; lsize=5, rsize=5)
    SlidingWindow(words, lsize, rsize)
end


text:
@testset "Bold x*" begin # issue 223
    h = raw"**x\***" * J.EOS |> seval
    @test h == "
x*
\n"

    h = raw"_x\__" * J.EOS |> seval
    @test h == "
x_
\n"
end

@testset "Bold code" begin # issue 222
    h = raw"""A **`master`** B.""" * J.EOS |> seval
    @test h == "
A master B.
\n"
end

@testset "Tickssss" begin # issue 219
    st = raw"""A `B` C""" * J.EOS
    tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS)
    @test tokens[1].name == :CODE_SINGLE
    @test tokens[2].name == :CODE_SINGLE

    st = raw"""A ``B`` C""" * J.EOS
    tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS)
    @test tokens[1].name == :CODE_DOUBLE
    @test tokens[2].name == :CODE_DOUBLE

    st = raw"""A ``` B ``` C""" * J.EOS
    tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS)
    @test tokens[1].name == :CODE_TRIPLE
    @test tokens[2].name == :CODE_TRIPLE

    st = raw"""A ````` B ````` C""" * J.EOS
    tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS)
    @test tokens[1].name == :CODE_PENTA
    @test tokens[2].name == :CODE_PENTA

    st = raw"""A ```b B ``` C""" * J.EOS
    tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS)
    @test tokens[1].name == :CODE_LANG
    @test tokens[2].name == :CODE_TRIPLE

    st = raw"""A `````b B ````` C""" * J.EOS
    tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS)
    @test tokens[1].name == :CODE_LANG2
    @test tokens[2].name == :CODE_PENTA

    h = raw"""
        A
        `````markdown
        B
        `````
        C
        """ |> jd2html_td

    @test isapproxstr(h, raw"""

A

B

 C

            """)

    h = raw"""
        A
        `````markdown
        ```julia
        B
        ```
        `````
        C
        """ |> jd2html_td

    @test isapproxstr(h, raw"""

A

```julia
            B
            ```

 C

            """)
end

@testset "Nested ind" begin # issue 285
    h = raw"""
    \newcommand{\hello}{
        yaya
        bar bar
    }
    \hello
    """ |> jd2html_td
    @test isapproxstr(h, raw"""yaya  bar bar""")
    h = raw"""
    @@da
        @@db
            @@dc
                blah
            @@
        @@
    @@
    """ |> jd2html_td
    @test isapproxstr(h, raw"""

                        blah

            """)
    h = raw"""
    \newcommand{\hello}[1]{#1}
    \hello{
        good lord
    }
    """ |> jd2html_td
    @test isapproxstr(h, "good lord")
end


text:
# Hard code for exponential families; temporary...

####### The above two are identical! Clean up.
function (target::MarginalDensityTarget{<:StandardNormalSample})(prior::ContinuousExponentialFamily;
	                                                             ngrid=100,
																 integrator = expectation(prior.base_measure; n = ngrid))
	function integrand(μ)
		riesz_representer(target,μ)*pdf(prior, μ; include_base_measure=false)
	end
    integrator(integrand)
end

function (target::PosteriorMeanNumerator{<:StandardNormalSample})(prior::ContinuousExponentialFamily;
	                                                             ngrid=100,
																 integrator = expectation(prior.base_measure; n = ngrid))
	function integrand(μ)
		riesz_representer(target,μ)*pdf(prior, μ; include_base_measure=false)
	end
    integrator(integrand)
end

#### LFSFNumerator requires different treatment.

function (target::LFSRNumerator{<:StandardNormalSample})(prior::ContinuousExponentialFamily;
	                                                             ngrid=500)
    b = maximum(prior) #TODO CHECK b>0
	integrator = expectation(Uniform(0, b); n=ngrid)
	function integrand(μ)
		riesz_representer(target,μ)*pdf(prior, μ; include_base_measure=true)*b
	end
    integrator(integrand)
end

#----------------- Under discretization
function (target::MarginalDensityTarget{<:DiscretizedStandardNormalSample})(prior::ContinuousExponentialFamily;
                                                                            integrator=expectation(prior.base_measure; n=500))
    Z_disc = location(target)
    grid = Z_disc.samples.mhist.grid
    i = Z_disc.bin
    if i == 1
        integrand = μ -> cdf(Normal(μ), first(grid))*pdf(prior, μ; include_base_measure=false)
    elseif i == lastindex(Z_disc.samples.mhist)
        integrand = μ -> ccdf(Normal(μ), last(grid))*pdf(prior, μ; include_base_measure=false)
    else
        integrand = μ -> (cdf(Normal(μ), grid[i]) -  cdf(Normal(μ), grid[i-1]))*pdf(prior, μ; include_base_measure=false)
    end
    # refactor into riesz representer..
    integrator(integrand)
end

#----------- loglikelihood

function loglikelihood(prior::ContinuousExponentialFamily,
                       Zs_discr::DiscretizedStandardNormalSamples;
                       integrator = expectation(prior.base_measure; n=200),
					   normalize=true)
    mhist = Zs_discr.mhist # need to be a bit careful...
    n_weights =  lastindex(mhist)
    ll = 0
	n = normalize ? nobs(Zs_discr) : 1
    for i=1:n_weights
        wt = mhist[i]
        if wt > 0
            target = MarginalDensityTarget(Zs_discr(i))
            ll += log(target(prior; integrator=integrator))*wt/n
        end
    end
    ll
end

function loglikelihood(prior::ContinuousExponentialFamily,
                       Zs::AbstractVector{<:StandardNormalSample};
                       integrator = expectation(prior.base_measure; n=50),
					   normalize=true)
	n = normalize ? nobs(Zs) : 1
	sum([log(MarginalDensityTarget(Z)(prior; integrator=integrator))/n for Z in Zs])
end

### Fitting Routine through (penalized MLE)

Base.@kwdef mutable struct FittedContinuousExponentialFamilyModel{CEFM<:ContinuousExponentialFamilyModel,
	                                          CEF<:ContinuousExponentialFamily,
											  T<:Real,
											  VT<:AbstractVector{T}}
	cefm::CEFM
	α_opt::VT
	α_bias = zero(α_opt)
	cef::CEF = cefm(α_opt)
	α_covmat = nothing
	nll_hessian = nothing
	nll_gradient = nothing
	regularizer_hessian = nothing
	regularizer_gradient = nothing
	fitter = nothing
end

Base.broadcastable(fcef::FittedContinuousExponentialFamilyModel) = Ref(fcef)

@with_kw struct ExponentialFamilyDeconvolutionMLE{CEFM<:ContinuousExponentialFamilyModel,
	                                           T <: Real}
	cefm::CEFM
	c0::T = 0.01
	integrator = expectation(cefm.base_measure; n=50)
	solver = NewtonTrustRegion()
	optim_options = Optim.Options(show_trace=true, show_every=1, g_tol=1e-6)
	marginal_grid = nothing # discretize?
	initializer = LindseyMethod(500) #TODO: make this depend on marginal_grid
end
_discretize(Zs::DiscretizedStandardNormalSamples, ::Nothing) = Zs
_discretize(Zs::AbstractVector{<:StandardNormalSample}, ::Nothing) = Zs
function _discretize(Zs::AbstractVector{<:StandardNormalSample}, marginal_grid::AbstractVector)
	DiscretizedStandardNormalSamples(Zs, marginal_grid)
end

function fit(cefm::ContinuousExponentialFamilyModel,
	         Zs::Union{EBayesSamples, DiscretizedStandardNormalSamples};
			 kwargs...)
    deconv = ExponentialFamilyDeconvolutionMLE(cefm=cefm, kwargs...)
	fit(deconv, Zs)
end

function fit(deconv::ExponentialFamilyDeconvolutionMLE,
	         Zs::Union{EBayesSamples, DiscretizedStandardNormalSamples})

			 cefm = deconv.cefm
			 @unpack c0, integrator, solver, optim_options, initializer = deconv

			 Zs = _discretize(Zs, deconv.marginal_grid)
			 n = nobs(Zs)
			 # initialize method through Lindsey's method
			 # this mostly makes sense for normal Zs
			 if isa(initializer, LindseyMethod)
			 	fit_init = fit(cefm, response(Zs), initializer)
			 	α_init = fit_init.α
			 else
				α_init = initializer
			 end
 		 	# set up objective
			 function _nll(α)
				 exp_family = cefm(α; integrator=integrator)
				 -loglikelihood(exp_family, Zs; integrator=integrator, normalize=true)
			 end
			 _s(α) = c0*norm(α)/n #sum(abs2, α)/n# c0*norm(α)/n #allow other choices
 			 _penalized_nll(α) = _nll(α) + _s(α)

			 # ready to descend
			 optim_res = optimize(_penalized_nll, α_init,
			                          solver, optim_options;
			 						 autodiff = :forward)

			α_opt = Optim.minimizer(optim_res)
			cef = cefm(α_opt)

			hessian_storage_nll = DiffResults.HessianResult(α_opt)
			hessian_storage_nll = ForwardDiff.hessian!(hessian_storage_nll, _nll, α_opt);

			nll_hessian = DiffResults.hessian(hessian_storage_nll)
			nll_gradient = DiffResults.gradient(hessian_storage_nll)

			# project onto psd cone
			nll_hessian_eigen = eigen(Symmetric(nll_hessian))
			nll_hessian_eigen.values .= max.(nll_hessian_eigen.values, 0.0)
			nll_hessian = Matrix(nll_hessian_eigen)

			hessian_storage_s = DiffResults.HessianResult(α_opt)
			hessian_storage_s = ForwardDiff.hessian!(hessian_storage_s, _s, α_opt);

			regularizer_hessian = DiffResults.hessian(hessian_storage_s)
			regularizer_gradient = DiffResults.gradient(hessian_storage_s)

			inv_mat = inv( (nll_hessian + regularizer_hessian).*sqrt(n))
			α_covmat = inv_mat*nll_hessian*inv_mat

			α_bias = -inv_mat*regularizer_gradient .* sqrt(n)

			FittedContinuousExponentialFamilyModel(;cefm=cefm,
			                                       α_opt=α_opt,
												   α_covmat=α_covmat,
												   α_bias = α_bias,
												   nll_hessian=nll_hessian,
												   nll_gradient=nll_gradient,
												   regularizer_hessian=regularizer_hessian,
												   regularizer_gradient=regularizer_gradient,
												   fitter=optim_res)
end

function fit(fcef::FittedContinuousExponentialFamilyModel, t::EBayesTarget)
	fcef
end

function target_bias_std(target::EBayesTarget,
	                     fcef::MinimaxCalibratedEBayes.FittedContinuousExponentialFamilyModel;
	                     bias_corrected=true,
						 clip=true)
	_fun(α) = target(fcef.cefm(α))
	α_opt = fcef.α_opt
	target_gradient = ForwardDiff.gradient(_fun, α_opt);
	target_bias = LinearAlgebra.dot(target_gradient, fcef.α_bias)
	target_variance = LinearAlgebra.dot(target_gradient, fcef.α_covmat*target_gradient)
	target_value = bias_corrected ? _fun(α_opt) - target_bias : _fun(α_opt)

	if clip
		target_value = clamp(target_value, extrema(target)...)
	end

	(estimated_target = target_value,
	 estimated_bias = target_bias,
	 estimated_std = sqrt(target_variance))
end

function Distributions.estimate(target::EBayesTarget, fcef::MinimaxCalibratedEBayes.FittedContinuousExponentialFamilyModel; kwargs...)
	target_bias_std(target, fcef; kwargs...)[:estimated_target]
end

function StatsBase.confint(target::EBayesTarget,
	                       fcef::MinimaxCalibratedEBayes.FittedContinuousExponentialFamilyModel;
						   level::Real = 0.9,
						   worst_case_bias_adjusted = false,
						   clip = true)
    if worst_case_bias_adjusted
		res = target_bias_std(target, fcef;
		                      clip = false, #we will clip the CIs themselves instead
							  bias_corrected = false) # we will account for worst case bias instead
		maxbias = abs(res[:estimated_bias])
	else
		res =  target_bias_std(target, fcef; clip=false, bias_corrected = true)
		maxbias = 0.0
	end

	q_mult = bias_adjusted_gaussian_ci(res[:estimated_std], maxbias=maxbias , level=level)

    L,U = res[:estimated_target] .+ (-1,1).*q_mult

	if clip
		L, U = clamp.((L,U), extrema(target)... )
	end

	L,U
end


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

==(w::WeakRef, v::WeakRef) = isequal(w.value, v.value)
==(w::WeakRef, v) = isequal(w.value, v)
==(w, v::WeakRef) = isequal(w, v.value)

"""
    finalizer(f, x)

Register a function `f(x)` to be called when there are no program-accessible references to
`x`, and return `x`. The type of `x` must be a `mutable struct`, otherwise the behavior of
this function is unpredictable.

`f` must not cause a task switch, which excludes most I/O operations such as `println`.
Using the `@async` macro (to defer context switching to outside of the finalizer) or
`ccall` to directly invoke IO functions in C may be helpful for debugging purposes.

# Examples
```julia
finalizer(my_mutable_struct) do x
    @async println("Finalizing \$x.")
end

finalizer(my_mutable_struct) do x
    ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.", repr(x))
end
```

A finalizer may be registered at object construction. In the following example note that
we implicitly rely on the finalizer returning the newly created mutable struct `x`.

# Example
```julia
mutable struct MyMutableStruct
    bar
    function MyMutableStruct(bar)
        x = new(bar)
        f(t) = @async println("Finalizing \$t.")
        finalizer(f, x)
    end
end
```
"""
function finalizer(@nospecialize(f), @nospecialize(o))
    if !ismutable(o)
        error("objects of type ", typeof(o), " cannot be finalized")
    end
    ccall(:jl_gc_add_finalizer_th, Cvoid, (Ptr{Cvoid}, Any, Any),
          Core.getptls(), o, f)
    return o
end

function finalizer(f::Ptr{Cvoid}, o::T) where T @inline
    if !ismutable(o)
        error("objects of type ", typeof(o), " cannot be finalized")
    end
    ccall(:jl_gc_add_ptr_finalizer, Cvoid, (Ptr{Cvoid}, Any, Ptr{Cvoid}),
          Core.getptls(), o, f)
    return o
end

"""
    finalize(x)

Immediately run finalizers registered for object `x`.
"""
finalize(@nospecialize(o)) = ccall(:jl_finalize_th, Cvoid, (Any, Any,),
                                   current_task(), o)

"""
    Base.GC

Module with garbage collection utilities.
"""
module GC

# mirrored from julia.h
const GC_AUTO = 0
const GC_FULL = 1
const GC_INCREMENTAL = 2

"""
    GC.gc([full=true])

Perform garbage collection. The argument `full` determines the kind of
collection: A full collection (default) sweeps all objects, which makes the
next GC scan much slower, while an incremental collection may only sweep
so-called young objects.

!!! warning
    Excessive use will likely lead to poor performance.
"""
gc(full::Bool=true) =
    ccall(:jl_gc_collect, Cvoid, (Cint,), full ? GC_FULL : GC_INCREMENTAL)

"""
    GC.enable(on::Bool)

Control whether garbage collection is enabled using a boolean argument (`true` for enabled,
`false` for disabled). Return previous GC state.

!!! warning
    Disabling garbage collection should be used only with caution, as it can cause memory
    use to grow without bound.
"""
enable(on::Bool) = ccall(:jl_gc_enable, Int32, (Int32,), on) != 0

"""
    GC.enable_finalizers(on::Bool)

Increment or decrement the counter that controls the running of finalizers on
the current Task. Finalizers will only run when the counter is at zero. (Set
`true` for enabling, `false` for disabling). They may still run concurrently on
another Task or thread.
"""
enable_finalizers(on::Bool) = on ? enable_finalizers() : disable_finalizers()

function enable_finalizers() @inline
    ccall(:jl_gc_enable_finalizers_internal, Cvoid, ())
    if Core.Intrinsics.atomic_pointerref(cglobal(:jl_gc_have_pending_finalizers, Cint), :monotonic) != 0
        ccall(:jl_gc_run_pending_finalizers, Cvoid, (Ptr{Cvoid},), C_NULL)
    end
end

function disable_finalizers() @inline
    ccall(:jl_gc_disable_finalizers_internal, Cvoid, ())
end

"""
    GC.@preserve x1 x2 ... xn expr

Mark the objects `x1, x2, ...` as being *in use* during the evaluation of the
expression `expr`. This is only required in unsafe code where `expr`
*implicitly uses* memory or other resources owned by one of the `x`s.

*Implicit use* of `x` covers any indirect use of resources logically owned by
`x` which the compiler cannot see. Some examples:
* Accessing memory of an object directly via a `Ptr`
* Passing a pointer to `x` to `ccall`
* Using resources of `x` which would be cleaned up in the finalizer.

`@preserve` should generally not have any performance impact in typical use
cases where it briefly extends object lifetime. In implementation, `@preserve`
has effects such as protecting dynamically allocated objects from garbage
collection.

# Examples

When loading from a pointer with `unsafe_load`, the underlying object is
implicitly used, for example `x` is implicitly used by `unsafe_load(p)` in the
following:

```jldoctest
julia> let
           x = Ref{Int}(101)
           p = Base.unsafe_convert(Ptr{Int}, x)
           GC.@preserve x unsafe_load(p)
       end
101
```

When passing pointers to `ccall`, the pointed-to object is implicitly used and
should be preserved. (Note however that you should normally just pass `x`
directly to `ccall` which counts as an explicit use.)

```jldoctest
julia> let
           x = "Hello"
           p = pointer(x)
           Int(GC.@preserve x @ccall strlen(p::Cstring)::Csize_t)
           # Preferred alternative
           Int(@ccall strlen(x::Cstring)::Csize_t)
       end
5
```
"""
macro preserve(args...)
    syms = args[1:end-1]
    for x in syms
        isa(x, Symbol) || error("Preserved variable must be a symbol")
    end
    esc(Expr(:gc_preserve, args[end], syms...))
end

"""
    GC.safepoint()

Inserts a point in the program where garbage collection may run.
This can be useful in rare cases in multi-threaded programs where some threads
are allocating memory (and hence may need to run GC) but other threads are doing
only simple operations (no allocation, task switches, or I/O).
Calling this function periodically in non-allocating threads allows garbage
collection to run.

!!! compat "Julia 1.4"
    This function is available as of Julia 1.4.
"""
safepoint() = ccall(:jl_gc_safepoint, Cvoid, ())

"""
    GC.enable_logging(on::Bool)

When turned on, print statistics about each GC to stderr.
"""
function enable_logging(on::Bool=true)
    ccall(:jl_enable_gc_logging, Cvoid, (Cint,), on)
end

end # module GC

max_stars_repo_name: BSnelling/julia

max_issues_repo_name: BSnelling/julia

max_forks_repo_name: BSnelling/julia


text:
# Kalman likelihood

"""
Computation engine for a stochastic differential equation
"""
abstract type SdeEngine{T} end

"""
Kalman computational engine based on eliminating the Q-matrix in the vector SDE(1)
representation using the standard state space.
"""
struct ElimQ{T,U<:AbstractMatrix{T},V<:AbstractMatrix{T}} <: SdeEngine{T}
  eq::Sde{T}
  A::U
  Σs::V
end

"""
    $SIGNATURES

Sde type used in an SdeEngine
"""
sdetype(::Type{ElimQ}) = Sde

function ElimQ(eq::Sde)
  veq = convert(VectorSde,eq)
  Σs = statcovz(veq)
  A = veq.A
  return ElimQ(eq,A,Σs)
end

"""
Kalman computational engine based on the matrix fraction computation.
"""
struct MatFrac{T,U<:AbstractMatrix{T},V<:AbstractMatrix{T}} <: SdeEngine{T}
  eq::Sde{T}
  A::U
  M::V
end

function MatFrac(eq::Sde)
  veq = convert(VectorSde,eq)
  A = veq.A
  Q = veq.Q
  p = order(eq)
  # Array mutation not supported by Zygote; using buffer.
  # Z = zeros(eltype(A),p,p)
  # M = [A  Q
  #      Z -A']
  M_buf = Zygote.bufferfrom(zeros(eltype(A),2p,2p))
  M_buf[1:p,1:p]     = A; M_buf[1:p,p+1:2p]     =  Q;
  M_buf[p+1:2p,p+1:2p] = -A';
  M = copy(M_buf)
  return MatFrac(eq,A,M)
end

sdetype(::Type{MatFrac}) = Sde

"""
Roots-based Kalman computational engine. Performs Kalman computations
based on the roots representation.
"""
struct SdeRootsEngine{T,T1,T2,T3} <: SdeEngine{T}
  eq::SdeRoots{T}
  A::T1
  U::T2
  Σs::T3
end

function SdeRootsEngine(eq::SdeRoots)
  A = Diagonal(eq.r)
  U = eigenvecA(eq)
  Σs = statcovz(eq,U)
  return SdeRootsEngine(eq,A,U,Σs)
end

struct VectorSdeEngine{T,T1} <: SdeEngine{T}
  eq::VectorSde{T}
  Σs::T1
end

SdeRootsEngine(eq::Sde) = SdeRootsEngine(SdeRoots(eq))

"SDE type corresponding to the engine type"
sdetype(::Type{SdeRootsEngine}) = SdeRoots

"Vector SDE based Kalman computation engine."
function VectorSdeEngine(eq::Sde)
  veq = convert(VectorSde,eq)
  Σs = statcovz(veq)
  return VectorSdeEngine(veq,Σs)
end

sdetype(::Type{VectorSdeEngine}) = VectorSde

const ENGINES = [VectorSdeEngine,ElimQ,MatFrac,SdeRootsEngine]

"Default SDE engine"
default_engine = SdeRootsEngine

statcovz(e::Union{SdeRootsEngine,ElimQ,VectorSdeEngine}) = e.Σs

statcovz(e::MatFrac) = statcovz(e.eq)

statstate(e::SdeEngine) = State(statcovz(e))

"""
$SIGNATURES

Distribution mean `μy` and variance `σ2y` of the current observation
for a probabilistic `state`.
"""
function obsdist(e::SdeRootsEngine,state::State)
  μ = real(sum(state.μ))
  σ2 = real(sum(state.Σ))
  return μ,σ2
end

function obsdist(e::Union{ElimQ,MatFrac},state::State)
  μ = state.μ[1]
  σ2 = state.Σ[1,1]
  return μ,σ2
end

function obsdist(e::VectorSdeEngine,state::State)
  C = e.eq.C
  μ = (C*state.μ)[1]
  Σ = C*state.Σ*C'+e.eq.R
  σ2 = Σ[1,1]
  return μ,σ2
end

"""
$SIGNATURES

Measurement step: condition state distribution on the current observation
`yc`.
"""
function measure(e::SdeRootsEngine,state,yc,μy,σ2y)
  w = sum(state.Σ;dims=2)
  μ = state.μ.+w[:].*(yc-μy)./σ2y
  Σ = state.Σ.-w*w'./σ2y
  return State(μ,Σ)
end

function measure(e::Union{ElimQ,MatFrac},state,yc,μy,σ2y)
  Pc = state.Σ[:,1]
  μ = state.μ.+Pc[:].*(yc-μy)/σ2y
  Σ = state.Σ.-Pc*Pc'./σ2y
  return State(μ,Σ)
end

function measure(e::VectorSdeEngine,state,yc,μy,σ2y)
  C = e.eq.C
  K = state.Σ*C'/σ2y # In Murphy, σ2y = S
  μ = state.μ.+K[:]*(yc-μy)
  Σ = (I-K*C)*state.Σ
  return State(μ,Σ)
end

function predict(A::AbstractMatrix,Σs::AbstractMatrix,state::State,Δt)
  F = exp(A*Δt)
  μ = F*state.μ
  Σ = Σs-F*(Σs-state.Σ)*F'
  return State(μ,Σ)
end

predict(e::Union{SdeRootsEngine,ElimQ},state,Δt) = predict(e.A,e.Σs,state,Δt)

predict(e::VectorSdeEngine,state,Δt) = predict(e.eq.A,e.Σs,state,Δt)

function predict(e::MatFrac,state::State,Δt)
  p = size(e.A,1)
  μp = exp(e.A*Δt)*state.μ
  C0 = state.Σ
  # CD0 = [C0;I] # Fails in Zygote ≤ v0.4.20
  CD0 = [C0;eye(eltype(C0),p)] # works with Zygote
  CD = exp(e.M*Δt)*CD0
  C,D = CD[1:p,:],CD[p+1:end,:]
  Pp = C/D
  return State(μp,Pp)
end

function logpdf_state(e::SdeEngine,state,data)
  μy,σ2y = obsdist(e,state)
  yc = data[1].y
  lp = if σ2y==0
    isapprox(yc,μy,rtol=1e-6) || error("Distribution inconsistent with observations: y[1] = $(y[1]) ≠ μy = $μy while σ2y==0")
    zero(μy)
  else
    state = measure(e,state,yc,μy,σ2y)
    logpdf(Normal(μy,√σ2y),yc)
  end
  for n in 2:length(data)
    tc = data[n].t; yc = data[n].y
    Δt = tc-data[n-1].t
    state = predict(e,state,Δt)
    μy,σ2y = obsdist(e,state)
    state = measure(e,state,yc,μy,σ2y)
    lp += logpdf(Normal(μy,√σ2y),yc)
  end
  return lp,state
end

"""
$SIGNATURES
 log probability `lp` an SDE process `proc` for `data`.
"""
function Distributions.logpdf(proc::ScalarSdeProcess{<:Any,<:Sde},data)
  lp,_ = logpdf_state(ElimQ(proc.eq),proc.state,data)
  return lp
end

function Distributions.logpdf(proc::ScalarSdeProcess{<:Any,<:SdeRoots},data)
  lp,_ = logpdf_state(SdeRootsEngine(proc.eq),proc.state,data)
  return lp
end


text:
#############################################################################
#Implementation of a mutable maximal Heap
#############################################################################
#Struct representing a node of the heap
struct Node{Tval, Tid, Trank}
  val::Tval
  id::Tid
  #larger ranks get picked last
  rank::Trank
end

#Mutable Heap (maximal value first)
struct MutHeap{Tval, Tid, Trank}
  # Vector containing the nodes of the heap
  nodes::Vector{Node{Tval, Tid, Trank}}
  # Vector providing a lookup for the nodes
  lookup::Vector{Tid}
end

#A function to swap two heapNodes in
function _swap!(h,
                a,
                b)
  #Assining the new values to the lookup table
  h.lookup[ h.nodes[a].id ] = b
  h.lookup[ h.nodes[b].id ] = a
  tempNode = h.nodes[a]
  h.nodes[a] = h.nodes[b]
  h.nodes[b] = tempNode
end

#Node comparisons
import Base.isless
function isless( a::Node, b::Node)
  isless((-a.rank, a.val), (-b.rank, b.val))
end

import Base.>=
function >=(a::Node, b::Node)
  (-a.rank, a.val) >= (-b.rank, b.val)
end

# presently not used
function >=(a::Node, b)
  a.val >= b
end

import Base.>
function >(a::Node, b::Node)
  (-a.rank, a.val) > (-b.rank, b.val)
end

# function >( a::Node{Tv,Ti}, b::Tv ) where {Tv,Ti}
#   a.val > b
# end

#Function that looks at element h.nodes[hInd] and moves it down the tree
#if it is sufficiently small. Returns the new index if a move took place,
#and lastindex(h.nodes), else
function _moveDown!(h::MutHeap, hInd)
  pivot = h.nodes[hInd]
  #If both children exist:
  if 2 * hInd + 1 <= lastindex( h.nodes )
    #If the left child is larger:
    if h.nodes[2 * hInd] >= h.nodes[ 2 * hInd + 1]
      #Check if the child is larger than the parent:
      if h.nodes[2 * hInd] >= pivot
        _swap!( h, hInd, 2 * hInd )
        return 2 * hInd
      else
        #No swap occuring:
        return lastindex( h.nodes )
      end
    #If the left child is larger:
    else
      #Check if the Child is larger than the paren:
      if h.nodes[2 * hInd + 1] >= pivot
        _swap!( h, hInd, 2 * hInd + 1 )
        return  2 * hInd + 1
      else
        #No swap occuring:
        return lastindex( h.nodes )
      end
    end
    #If only one child exists:
  elseif 2 * hInd <= lastindex( h.nodes )
    if h.nodes[2 * hInd] > pivot
      _swap!( h, hInd, 2 * hInd )
      return 2 * hInd
    end
  end
  #No swap occuring:
  return lastindex( h.nodes )
end

#Get the leading node
function topNode(h::MutHeap)
  return first(h.nodes)
end

#Gets the leading node and sets its rank to maximum.
function topNode!( h::MutHeap{Tval,Tid,Trank} ) where {Tval, Tid, Trank}
  h.nodes[1] = Node{Tval,Tid,Trank}(h.nodes[1].val,
                                      h.nodes[1].id,
                                      typemax(Trank))
  return first(h.nodes)
end

#Updates (decreases) an element of the heap and restores the heap property
function update!( h::MutHeap{Tv,Ti,Trank}, id::Ti, val::Tv ) where {Tv,Ti,Trank}
  tempInd::Ti = h.lookup[id]
  if h.nodes[tempInd].val > val
    h.nodes[tempInd] = typeof(h.nodes[tempInd])(val,id,h.nodes[tempInd].rank)
    while ( tempInd < lastindex( h.nodes ) )
      tempInd = _moveDown!( h, tempInd )
    end
    return val
  else
    return h.nodes[id].val
  end
end


text:
using CompositeProblems
using Test
using ForwardDiff
using LinearAlgebra

@testset "CompositeProblems.jl" begin
    # Write your tests here.

    n, m = 5, 3
    n1, n2 = 5, 4

    testcollection_pb = [
        ("Lasso", get_lasso_MLE(n=n, m=m, sparsity=0.5), :vec),
        ("Logistic", get_logit_MLE(n=n, m=m), :vec),                   # Beware, hessian of logistic is often null for n, m > 10, 10
        ("Tracenorm", get_tracenorm_MLE(n1=n1, n2=n2, m=m), :mat),
    ]

    @testset "$testcollection" for (testcollection, pb, itertype) in testcollection_pb
        x = itertype==:vec ? rand(n) : rand(n1, n2)
        h = itertype==:vec ? rand(n) : rand(n1, n2)

        # First order
        ∇f_x = itertype==:vec ? zeros(n) : zeros(n1,n2)
        ∇f!(pb, ∇f_x, x)

        @test isapprox(∇f_x, ∇f(pb, x))
        @test isapprox(∇f_x, ForwardDiff.gradient(x->f(pb, x), x))

        # Second order
        ∇²f_xh = itertype==:vec ? zeros(n) : zeros(n1,n2)
        ∇²f_h!(pb, ∇²f_xh, x, h)

        @test isapprox(∇²f_xh, ∇²f_h(pb, x, h))

        if itertype == :vec
            ∇²f_xh_AD = ForwardDiff.hessian(x->f(pb, x), x) * h
            @test isapprox(∇²f_xh, ∇²f_xh_AD)
        else
            ∇²f_xh_AD = ForwardDiff.hessian(x->f(pb, x), x) * vec(h)
            ∇²f_xh_AD = reshape(∇²f_xh_AD, (n1, n2))
            @test isapprox(∇²f_xh, ∇²f_xh_AD)
        end
    end
end


text:
# datagen.jl -- Generates CSV file containing 4 rows:
#               Row 1 contains resistor values from 0 to 100k Ohms
#               Row 2 contains capacitor values from 0 to 1u Farad
#               Row 3 contains times from 0 to 5RC (elementwise)
#               Row 4 contains outputs
#
# Accepts 2 inputs:
#               Input 1 is the number of datpoints to generate.
#               Input 2 is the filename to save the results to.

using Random
using DelimitedFiles

numRows = parse(UInt64, ARGS[1]);
vInitial = 10; # Value at t = 0

data = rand!(zeros(4,numRows));
data[1,:] *= 100000; # Put resistor column at 10k order of magnitude
data[2,:] /= 100000; # Put capacitor column at 1u order of magnitude

for i = 1:numRows
        data[3,i] *= 5*data[1,i]*data[2,i]; # Keeps t less than 5RC at each point
end

for i = 1:numRows
        data[4,i] = vInitial * exp(-data[3,i] / (data[1,i]*data[2,i])); # Ckt output value
end

writedlm(ARGS[2], data, ','); # Creates CSV file for data array.


text:
function modifier(ability)
    return floor((ability - 10) / 2)
end

function ability()
    dice = rand(1:6, 4)
    return sum(dice) - minimum(dice)
end

mutable struct DNDCharacter
    strength::Integer
    dexterity::Integer
    constitution::Integer
    intelligence::Integer
    wisdom::Integer
    charisma::Integer
    hitpoints::Integer

    function DNDCharacter()
        constitution = ability()
        new(ability(), ability(), constitution, ability(), ability(), ability(), 10 + modifier(constitution))
    end
end

max_stars_repo_name: twolodzko/Learning

max_issues_repo_name: twolodzko/Learning

max_forks_repo_name: twolodzko/Learning


text:
"""
    register(m::Module, can_type::DataType, func::Function, args::NTuple{N,DataType},
             kwargs::NTuple{N,Symbol}, ret::DataType) where N

Register a function `func` with the specified `can_type` type.
The `func` is expected to take arguments `args` and keyword arguments `kwargs`
and return a value of type `ret`.
"""
function register(m::Module,
                  can_type::DataType,
                  func::Function,
                  args::Tuple,
                  kwargs::NTuple{N,Symbol},
                  ret::Union{DataType,Nothing} = nothing) where N

    push_interface_map!(m, can_type, Contract(can_type, func, args, kwargs, ret))
    return nothing
end

"""
    contracts(module::Module, can_type::DataType)

Returns a set of [`Contracts`](@ref) that are required to be implemented
for objects that exihibits the specific `can_type` trait.
"""
function contracts(m::Module, can_type::DataType)
    current_contracts = get_interface_values(m, can_type)
    subcan_types = get_composite_values(m, can_type)
    if !isempty(subcan_types)
        contracts_array = contracts.(Ref(m), subcan_types)
        underlying_contracts = union(contracts_array...)
        return union(current_contracts, underlying_contracts)
    else
        return current_contracts
    end
end

"""
    @check(T::Assignable)
    check(module::Module, T::Assignable)

Check if the data type `T` has fully implemented all trait functions that it was
previously assigned. See also: [`@assign`](@ref).
"""
macro check(T)
    m = __module__
    esc(:(check($m, $T)))
end
function check(m::Module, T::Assignable)
    all_good = true
    implemented_contracts = Contract[]
    missing_contracts = Contract[]
    for contract in required_contracts(m, T)
        tuple_type = make_tuple_type(T, contract)
        method_exists = has_method(contract.func, tuple_type, contract.kwargs)
        if method_exists
            push!(implemented_contracts, contract)
        else
            @warn "Missing implementation" contract
            all_good = false
            push!(missing_contracts, contract)
        end
    end
    return InterfaceReview(data_type = T,
                           result = all_good,
                           implemented = implemented_contracts,
                           misses = missing_contracts)
end

"""
    make_tuple_type(T::Assignable, c::Contract)

Make a tuple type such that the placeholder (can-type) is replaced
with the type `T` that is being checked.
"""
function make_tuple_type(T::Assignable, c::Contract)
    args = [t == c.can_type ? T : t for t in c.args]
    return Tuple{args...}
end

"""
    required_contracts(module::Module, T::Assignable)

Return a set of contracts that is required to be implemented for
the provided type `T`.
"""
function required_contracts(m::Module, T::Assignable)
    c = [contracts(m, t) for t in traits(m, T)]  # returns array of set of contracts
    return isempty(c) ? valtype(storage().interface_map)() : union(c...)
end

"""
    @implement <CanType> by <FunctionSignature>

Register function signature for the specified `CanType` of a trait.
You can use the [`@check`](@ref) function to verify your implementation
after these interface contracts are registered.  The function
signature only needs to specify required arguments other than
the object itself.  Also, return type is optional and in that case
it will be ignored by the interface checker.

For examples:
```julia
@implement CanFly by fly(direction::Direction, speed::Float64)
@implement CanFly by has_wings()::Bool
```

The data types that exhibit those `CanFly` traits must implement
the function signature with the addition of an object as first
argument i.e.

```julia
fly(duck::Duck, direction::Direction, speed::Float64)
has_wings(duck::Duck)::Bool
```
"""
macro implement(can_type, by, sig)

    func_name, func_arg_names, func_arg_types, kwarg_names, return_type =
        parse_implement(can_type, by, sig)
    # @info "sig" func_name func_arg_names func_arg_types

    kwtuple = tuple(kwarg_names...)
    mod = __module__

    # generate code
    expr = quote
        function $func_name end
        BinaryTraits.register($mod, $can_type, $func_name,
                              ($(func_arg_types...),), $kwtuple, $return_type)
    end
    display_expanded_code(expr)
    return esc(expr)
end

# Parsing function for @implement macro
function parse_implement(can_type, by, sig)
    usage = "usage: @implement <Type> by <function specification>[::<ReturnType>]"
    can_type isa Symbol && sig isa Expr && by === :by || throw(SyntaxError(usage))

    # Is return type specified?
    if sig.head === :(::)
        return_type = sig.args[2]
        sig = sig.args[1]
    else
        return_type = :Any
    end

    sig isa Expr && sig.head === :call || throw(SyntaxError(usage))

    # parse signature
    func_name = sig.args[1]   # must be Symbol
    func_arg_names = Symbol[]
    func_arg_types = Any[]
    func_kwarg_names = Symbol[]
    firstarg = 2
    if length(sig.args) >= 2 && sig.args[2] isa Expr && sig.args[2].head == :parameters
        # this is the optional list of keyword arguments
        for x in sig.args[2].args
            push!(func_kwarg_names, extract_name(x, nothing))
        end
        firstarg += 1
    end
    # further arguments after the keyword argument list
    for (idx, x) in enumerate(sig.args[firstarg:end])  # x must be Expr of 1 or 2 symbols
        push!(func_arg_names, extract_name(x, Symbol("x$idx")))
        push!(func_arg_types, extract_type(x, can_type, :(Base.Bottom)))
    end

    return (func_name, func_arg_names, func_arg_types, func_kwarg_names, return_type)
end

extract_name(x::Symbol, default) = x
function extract_name(x::Expr, default)
    n = length(x.args)
    if x.head == :(::)
        # form: '<name> :: <type-spec>' or ':: <type-spec>'
        # we accept <name> if present or deliver default name
        n > 1 ? x.args[1] : default
    elseif n >= 1 && x.head == :kw
        # form: <something> <op> <rest>
        # we assume <something> has one of the previous forms - <op> <rest> is ignored
        extract_name(x.args[1], default)
    else
        # all other forms deliver default name
        text = "@implement argument is $x but needs syntax: [<name>][::<type>][=<expr>]"
        throw(SyntaxError(text))
    end
end

# If the symbol is an underscore, replace with the can-type.
# Otherwise, just return the default type.
function extract_type(s::Symbol, can_type, default)
    return s === :_ ? can_type : default
end

function extract_type(x::Expr, can_type, default)
    n = length(x.args)
    if x.head == :(::)
        # form: '<name> :: <type-spec>' or ':: <type-spec>'
        # we accept <type-spec>
        n > 1 ? x.args[2] : x.args[1]
    elseif n >= 1 && x.head == :kw
        # form: '<something> = <rest>'
        # we assume <something> has one of the previous forms and ignore rest
        extract_type(x.args[1], can_type, default)
    else
        throw(SyntaxError("@implement")) # will never be called, because extract_name throws
    end
end

"""
    has_method(f, Tuple{argument_types...}, (keyword_argument_names...,))

Check existence of a method with same name as `f`, same number of argument types, each
of which is `>:` to the given `argument_types`, and with all `keyword_argument_names`
supported.

This is an improvement over `Base.hasmethod` as it treats the `Base.Bottom` case correctly.
"""
function has_method(@nospecialize(f), @nospecialize(t), kwnames::Tuple{Vararg{Symbol}}=())
    _hasmethod(f, t, kwnames) && return true # assume hasmethod has no false positives
    t = Base.to_tuple_type(t)
    t = Base.signature_type(f, t)
    for m in methods(f)
        check_method(m, t, kwnames) && return true
    end
    false
end

function _hasmethod(@nospecialize(f), @nospecialize(t), kwnames::Tuple{Vararg{Symbol}}=())
    VERSION >= v"1.2" && !isempty(kwnames) ? hasmethod(f, t, kwnames) : hasmethod(f, t)
end

function check_method(@nospecialize(m::Method), @nospecialize(sig::Type{T}), kwnames::Tuple{Vararg{Symbol}}=tuple()) where T<:Tuple
    ssig = sig.parameters
    n = length(ssig)
    msig = m.sig.parameters
    n != length(msig) && return false
    for i = 1:n
        ssig[i] <: msig[i] || return false
    end
    isempty(kwnames) && return true
    VERSION >= v"1.2" || return false
    par = VERSION >= v"1.4" ? nothing : Core.kwftype(m.sig.parameters[1])
    kws = Base.kwarg_decl(m, par)
    for kw in kws
        endswith(String(kw), "...") && return true
    end
    return issubset(kwnames, kws)
end