text:
using DataFrames

dipar = Dict(:nK => 40, :nz => 5, :γ => 2.)
p_1_all = createmodel(:CapitalAdjustModel; dipar..., :intdim=>:All)
p_1_sep = createmodel(:CapitalAdjustModel; dipar..., :intdim=>:Separable)
p_1_sep_states = createmodel(:CapitalAdjustModel; dipar..., :intdim=>:Separable_States)
p_1_sep_exogstates = createmodel(:CapitalAdjustModel; dipar..., :intdim=>:Separable_ExogStates)

optdict = Dict(:monotonicity=>true, :concavity=>true,
	:rewardcall=>:pre_partial)

sol_1_all = solve(p_1_all; optdict...)
sol_1_sep = solve(p_1_sep; optdict...)
sol_1_sep_states = solve(p_1_sep_states; optdict...)
sol_1_sep_exogstates = solve(p_1_sep_exogstates; optdict...)

shocks_1 = drawshocks(p_1_all, nPeriods=40, nFirms=100)

@testset "Simulate CapitalAdjustModel" begin
	@testset "conversion" begin
		sim = simulate(sol_1_sep_exogstates, shocks_1, get_value=true)
	    @test typeof(DataFrame(sim)) <: DataFrame
		@test typeof(Array(sim)) <: AbstractArray
		sim = simulate(sol_1_sep_exogstates, shocks_1, get_value=false)
	    @test typeof(DataFrame(sim)) <: DataFrame
		@test typeof(Array(sim)) <: AbstractArray
	end
	@testset "initialize_inexact" begin
		sim_opt = Dict(:initialize_exact=>false, :get_value=>true)
	    sim_1 = simulate(sol_1_all, shocks_1; sim_opt...)
	    sim_2 = simulate(sol_1_sep, shocks_1; sim_opt...)
	    sim_3 = simulate(sol_1_sep_states, shocks_1; sim_opt...)
	    sim_4 = simulate(sol_1_sep_exogstates, shocks_1; sim_opt...)
		@test isapprox(Array(sim_1), Array(sim_2), rtol=mytol)
		@test isapprox(Array(sim_2), Array(sim_3), rtol=mytol)
		@test isapprox(Array(sim_3), Array(sim_4), rtol=mytol)
	end
	@testset "initialize_exact" begin
		sim_opt = Dict(:initialize_exact=>true, :get_value=>true)
	    sim_1 = simulate(sol_1_all, shocks_1; sim_opt...)
	    sim_2 = simulate(sol_1_sep, shocks_1; sim_opt...)
	    sim_3 = simulate(sol_1_sep_states, shocks_1; sim_opt...)
	    sim_4 = simulate(sol_1_sep_exogstates, shocks_1; sim_opt...)
		@test isapprox(Array(sim_1), Array(sim_2), rtol=mytol)
		@test isapprox(Array(sim_2), Array(sim_3), rtol=mytol)
		@test isapprox(Array(sim_3), Array(sim_4), rtol=mytol)
	end
end

model = :CapitalAdjustModel2
dipar = Dict(:nK => 15, :nN => 10, :nz => 5, :ρ => 0.6)
p_2_all = createmodel(model; dipar..., :intdim=>:All)
p_2_sep = createmodel(model; dipar..., :intdim=>:Separable)
p_2_sep_states = createmodel(model; dipar..., :intdim=>:Separable_States)
p_2_sep_exogstates = createmodel(model; dipar..., :intdim=>:Separable_ExogStates)

optdict = Dict(:monotonicity=>[true,true], :concavity=>[true,true],
	:rewardcall=>:pre_partial)

sol_2_all = solve(p_2_all; optdict...)
sol_2_sep = solve(p_2_sep; optdict...)
sol_2_sep_states = solve(p_2_sep_states; optdict...)
sol_2_sep_exogstates = solve(p_2_sep_exogstates; optdict...)

shocks_2 = drawshocks(p_2_all, nPeriods=20, nFirms=10)

isapprox(sol_2_all, sol_2_sep)
isapprox(sol_2_all, sol_2_sep_states)
isapprox(sol_2_all, sol_2_sep_exogstates)
@testset "Simulate CapitalAdjustModel2" begin
	@testset "conversion" begin
		sim = simulate(sol_2_sep_exogstates, shocks_2, get_value=true)
	    @test typeof(DataFrame(sim)) <: DataFrame
		@test typeof(Array(sim)) <: AbstractArray
		sim = simulate(sol_2_sep_exogstates, shocks_2, get_value=false)
	    @test typeof(DataFrame(sim)) <: DataFrame
		@test typeof(Array(sim)) <: AbstractArray
	end
	@testset "initialize_inexact" begin
		sim_opt = Dict(:initialize_exact=>false, :get_value=>true)
	    sim_1 = simulate(sol_2_all, shocks_2; sim_opt...)
	    sim_2 = simulate(sol_2_sep, shocks_2; sim_opt...)
	    sim_3 = simulate(sol_2_sep_states, shocks_2; sim_opt...)
	    sim_4 = simulate(sol_2_sep_exogstates, shocks_2; sim_opt...)
		@test isapprox(Array(sim_1), Array(sim_2), rtol=mytol)
		@test isapprox(Array(sim_2), Array(sim_3), rtol=mytol)
		@test isapprox(Array(sim_3), Array(sim_4), rtol=mytol)
	end
	@testset "initialize_exact" begin
		sim_opt = Dict(:initialize_exact=>true, :get_value=>true)
	    sim_1 = simulate(sol_2_all, shocks_2; sim_opt...)
	    sim_2 = simulate(sol_2_sep, shocks_2; sim_opt...)
	    sim_3 = simulate(sol_2_sep_states, shocks_2; sim_opt...)
	    sim_4 = simulate(sol_2_sep_exogstates, shocks_2; sim_opt...)
		@test isapprox(Array(sim_1), Array(sim_2), rtol=mytol)
		@test isapprox(Array(sim_2), Array(sim_3), rtol=mytol)
		@test isapprox(Array(sim_3), Array(sim_4), rtol=mytol)
	end
end


text:
module B

value = 2

end

ext: jl


text:
using Random
using Test

@testset "ExaTronKernels" begin
    using CUDA
    using AMDGPU
    using oneAPI
    @testset "CUDA.jl" begin
        if CUDA.has_cuda_gpu()
            include("CUDA.jl")
        end
    end
    @testset "AMDGPU.jl" begin
        if AMDGPU.has_rocm_gpu()
            include("AMDGPU.jl")
        end
    end
    @testset "oneAPI.jl" begin
        if oneAPI.functional()
            include("oneAPI.jl")
        end
    end
    @testset "KA.jl" begin
        using KernelAbstractions
        KA = KernelAbstractions
        devices = Vector{KA.Device}()
        push!(devices, KA.CPU())
        if CUDA.has_cuda_gpu() || AMDGPU.has_rocm_gpu()
            include("KA.jl")
            if CUDA.has_cuda_gpu()
                using CUDAKernels
                push!(devices, CUDADevice())
            end
            if AMDGPU.has_rocm_gpu()
                using ROCKernels
                push!(devices, ROCDevice())
            end
        end
        include("admmtest.jl")
        @show devices
        @testset "Testing one-level ADMM using $device" for device in devices
            one_level_admm(CASE, device)
        end
    end
end


text:
# Conclusion: for e-fish, pretty similar.

function efish_replicates(dfns, parms, pts, lendatav)
  fish = zeros(3,3)
  _S   = Symmetric([matern(x, y, parms) for x in pts, y in pts])
  S    = cholesky!(_S)
  for j in 1:3
    dfj = dfns[j]
    Sj  = Symmetric([dfj(x, y, parms) for x in pts, y in pts])
    fish[j,j] = tr(S\(Sj*(S\Sj)))/2
    for k in (j+1):3
      dfk = dfns[k]
      Sk  = Symmetric([dfk(x, y, parms) for x in pts, y in pts])
      fish[j,k] = tr(S\(Sj*(S\Sk)))/2
      fish[k,j] = fish[j,k]
    end
  end
  fish*lendatav
end


text:
#__precompile__(false)

module Hip

using Compat

export  HipArray,
        sgemm!,
        naiveMul!,
        naivesgemm!,
        tilesgemm!,
        free!,
        synchronize,
        set_device

include("hip_interface.jl")

end # module


text:
module BaMichelle

using SearchBall
using GeometryTypes, Reactive
using Deldir

strategy_logger = SearchBall.getlogger(split(string(current_module()), ".")[end])
SearchBall.setlevel!(strategy_logger, "debug")
log_debug(text...) = SearchBall.debug(strategy_logger, strip(string(["$x " for x in text]...)))

function calc_myPlayers(config::SearchBall.Config, dt::Number, set_type::Symbol, moved_object::Union{SearchBall.Object{<:Number}, Nothing}=nothing)
    ws = config.ws
    if set_type==:init
        #initialization
    end

    # Berechnung der Voronoi-Zellen

    # Zeichnen der Kanten der Voronoi-Zellen
    ## config.drawables[strig("line", idx)] = ([edgw_start, edge_end], x -> SearchBall.GraphicLine(x, color=[0.0, 0.0, 0.0, 1.0]))

    #Eigene Spieler Voronoi Zellen

#    x_pos=getindex.(ws.myPlayers,1)
#    y_pos=getindex.(ws.myPlayers,2)

#    del, vor, summ=Deldir.deldirwrapper(x_pos,y_pos,[0.0; config.field_size[1]; 0.0; config.field_size[2]])

#    i=1
#    while i<=size(vor)[1]
#        config.drawables[string("line",i)]=([[vor[i,1],vor[i,2]],[vor[i,3],vor[i,4]]],x -> SearchBall.GraphicArrow(x,arrowloc=1.0, color=[0.0,0.8,0.2,0.6]))
#        i +=1
#    end

    #Loeschen der Linien
    for s in keys(config.drawables)
        if startswith(s,"aline")
            delete!(config.drawables,s)
        end
    end

    #Voronoi Zellen für Gegner und Eigenen Spieler
    x_pos=vcat(getindex.(ws.myPlayers,1),getindex.(ws.opponents,1))
    y_pos=vcat(getindex.(ws.myPlayers,2),getindex.(ws.opponents,2))

    del, vor, summ=Deldir.deldirwrapper(x_pos,y_pos,[0.0; config.field_size[1]; 0.0; config.field_size[2]])

    i=1
    while i<=size(vor)[1]
        config.drawables[string("aline",i)]=([[vor[i,1],vor[i,2]],[vor[i,3],vor[i,4]]],x -> SearchBall.GraphicLine(x, color=[0.9,0.3,0.6,0.8]))
        i +=1
    end
    ws.myPlayers
end

function calc_opponend(config::SearchBall.Config, dt::Number, set_type::Symbol, moved_object::Union{SearchBall.Object{<:Number}, Nothing}=nothing)
    ws = config.ws
    if set_type==:init
        #initialization
    end
    ws.opponents
end

function run_strategies(config::SearchBall.Config, dt::Number=0, set_type::Symbol=:default, moved_object::Union{SearchBall.Object{<:Number}, Nothing}=nothing)
    (
        calc_myPlayers(config, dt, set_type, moved_object),
        calc_opponend(config, dt, set_type, moved_object)
    )
end

end


text:
using Test, MLToolkit, Knet
import AutoGrad

@testset "RR Rho" begin
    function obj(R, r::Rho; k_max=100)
        return sum([pdf(r, k) * R(k) for k = 1:k_max])
    end

    toyR1(i) = i <= 10 ? -i + 20 : 0.01i + 9.9
    toyR2(x) = (x - 5)^2 * 0.1

    for toyR in [toyR1, toyR2]

        toyR_min = min(toyR.(1:100)...)

        for m in [1, 5]

            pr = Param(Rho())
            pr.opt = DynamicAdam()

            for _ = 1:100_000*div(5, m)
                ϵ = randn(100) * 0.1
                dLdrho = MLToolkit.gradRR(x -> toyR(x) + ϵ[x], AutoGrad.value(pr), m)
                updategrad!(AutoGrad.value(pr), dLdrho)
                update!(AutoGrad.value(pr), pr.opt)
            end

            @test obj(toyR, AutoGrad.value(pr)) ≈ toyR_min atol=0.2*m

        end
    end
end


text:
include("Include.jl")

# extra:
using Flux
using Flux: @epochs
using BSON: @save

# load training set -
full_training_data_frame = load_fibrinolysis_training_data()

# filter out the data -
experimental_data_table = filter(:visitid => x -> (x == 2 || x == 3 || x == 1), full_training_data_frame)

# initialize storage for the training data -
training_data = Vector{Tuple{Vector{Float32},Vector{Float32}}}()

# build a model architecture -
has_TM_flag = 0
number_of_inputs = 14
number_of_outputs = 4
dimension_hidden_layer = number_of_inputs + 2
deep_fibrinolysis_model = Chain(Dense(number_of_inputs, dimension_hidden_layer, σ), Dense(dimension_hidden_layer, number_of_outputs));

# setup a loss function -
loss(x, y) = Flux.Losses.mae(deep_fibrinolysis_model(x), y; agg = mean)

# pointer to params -
ps = Flux.params(deep_fibrinolysis_model)

# # use old school gradient descent -
opt = Momentum(0.1, 0.95)

# main training loop -
(P, D) = size(experimental_data_table)

for i ∈ 1:P

    for j = 1:P

        # leave one out -
        if (i != j)

            # get input and output data -
            input_data = convert.(Float32, Vector(experimental_data_table[j, 3:16]))
            output_data = convert.(Float32, Vector(experimental_data_table[j, 17:20]))
            data_example = (input_data, output_data)

            # capture -
            push!(training_data, data_example)
        end
    end

    # ok, so have the training data for this case -
    # train -
    @epochs 12000 Flux.train!(loss, ps, training_data, opt)

    # save -
    model_name = "deep_fibrinolysis_model-L$(i)O-TF-TM-$(has_TM_flag)-ALL.bson"
    model_file_path = joinpath(_PATH_TO_MODELS, model_name)
    @save model_file_path deep_fibrinolysis_model

    # need to empty the training data -
    empty!(training_data)
end

max_stars_repo_name: varnerlab/UVM-TopDown-LegacyModel

max_issues_repo_name: varnerlab/UVM-TopDown-LegacyModel

max_forks_repo_name: varnerlab/UVM-TopDown-LegacyModel


text:
# Mutation of the attributes of a node at the node level, with attributes as MutableNamedTuple:

"""
    append!(node::Node{M<:AbstractNodeMTG, <:MutableNamedTuple}, attr)
    append!(node::Node{M<:AbstractNodeMTG, <:Dict}, attr)

Append new attributes to a node attributes.
"""
function Base.append!(node::Node{M,T}, attr) where {M<:AbstractNodeMTG,T<:MutableNamedTuple}
    node.attributes = MutableNamedTuple{(keys(node.attributes)..., keys(attr)...)}((values(node.attributes)..., values(attr)...))
end

function Base.append!(node::Node{M,T}, attr) where {M<:AbstractNodeMTG,T<:NamedTuple}
    node.attributes = NamedTuple{(keys(node.attributes)..., keys(attr)...)}((values(node.attributes)..., values(attr)...))
end

# [...] or with attributes as Dict:
function Base.append!(node::Node{M,T}, attr::T) where {M<:AbstractNodeMTG,T<:AbstractDict}
    merge!(node.attributes, attr)
end

# And ensure compatibility between both so a script wouldn't be broken if we just change the
# type of the attributes:
function Base.append!(node::Node{<:AbstractNodeMTG,<:AbstractDict}, attr)
    merge!(node.attributes, Dict(zip(keys(attr), values(attr))))
end

function Base.pop!(node::Node{M,T}, key) where {M<:AbstractNodeMTG,T<:MutableNamedTuple}
    attr_keys = keys(node.attributes)
    i_drop = findfirst(x -> x == key, attr_keys)
    i_drop === nothing && return nothing
    node.attributes = MutableNamedTuple{(attr_keys[setdiff(1:end, i_drop)]...,)}((values(node.attributes)[setdiff(1:end, i_drop)]...,))
end

function Base.pop!(node::Node{M,T}, key) where {M<:AbstractNodeMTG,T<:NamedTuple}
    attr_keys = keys(node.attributes)
    i_drop = findfirst(x -> x == key, attr_keys)
    i_drop === nothing && return nothing
    node.attributes = NamedTuple{(attr_keys[setdiff(1:end, i_drop)]...,)}((values(node.attributes)[setdiff(1:end, i_drop)]...,))
end

function Base.pop!(node::Node{<:AbstractNodeMTG,<:AbstractDict}, key)
    pop!(node.attributes, key, nothing)

    return nothing
end

# Renaming attributes:
function rename!(node::Node{M,T}, old_new) where {M<:AbstractNodeMTG,T<:MutableNamedTuple}
    attr_keys = replace([i for i in keys(node.attributes)], old_new)
    node.attributes = MutableNamedTuple{attr_keys}(values(node.attributes))
end

function rename!(node::Node{M,T}, old_new) where {M<:AbstractNodeMTG,T<:NamedTuple}
    attr_keys = replace([i for i in keys(node.attributes)], old_new)
    node.attributes = NamedTuple{attr_keys}(values(node.attributes))
end

function rename!(node::Node{<:AbstractNodeMTG,<:AbstractDict}, old_new)
    replace!(node.attributes) do kv
        first(kv) == first(old_new) ? last(old_new) => last(kv) : kv
    end
end


text:
using MultivariateOrthogonalPolynomials, Test

include("test_disk.jl")
include("test_triangle.jl")
# include("test_dirichlettriangle.jl")


text:
using Documenter, ImagePhaseCongruency
using TestImages
using DemoCards

testimage("cameraman") # used to trigger artifact downloading

# generate
demopage, postprocess_cb, demo_assets = makedemos("examples") # this is the relative path to docs/
assets = []
isnothing(demo_assets) || (push!(assets, demo_assets))

format = Documenter.HTML(edit_link = "master",
                         prettyurls = get(ENV, "CI", nothing) == "true",
                         assets = assets)
makedocs(
    format=format,
    sitename = "ImagePhaseCongruency",
    pages = [
        "index.md",
        demopage,
        "functions.md"
    ]
)

postprocess_cb()

deploydocs(
    repo = "github.com/peterkovesi/ImagePhaseCongruency.jl.git",
)

max_stars_repo_name: peterkovesi/ImagePhaseCongruency

max_issues_repo_name: peterkovesi/ImagePhaseCongruency

max_forks_repo_name: peterkovesi/ImagePhaseCongruency


text:
#NOTE: \perp does not work, reserved as infix operator
# use \bigbot instead
module TwoLevelSystems

export TwoLevelSystem
# export jacobian_lasing

using LinearAlgebra
using SparseArrays

import ..AbstractDispersion
import ..susceptability

"""
    struct TwoLevelSystem
    TwoLevelSystem(tls; :key1 => value1, :key2 => value2, ...) -> tls
"""
TwoLevelSystem

"""
    susceptability(::TwoLevelSystem,ω)
    susceptability(::TwoLevelSystem,ωs,ψs)
"""

mutable struct TwoLevelSystem <: AbstractDispersion
    ωₐ::Float64
    D₀::Float64
    γ⟘::Float64
    h::Array{Float64,1}
    h⁻¹::Array{Float64,1}
    chi::Array{ComplexF64,1}

    TwoLevelSystem(ωₐ, D₀, γ⟘) = new(ωₐ, D₀, γ⟘)
end
function TwoLevelSystem(;ωₐ = 0, D₀ = 0, γ⟘ = 1e8, kwargs...)

    ωa = get(kwargs,:ωa,ωₐ)
    omega_a = get(kwargs,:omega_a,ωa)
    ω = get(kwargs,:ω,omega_a)

    γ_perp = get(kwargs,:γ_perp,γ⟘)
    γp = get(kwargs,:γp,γ_perp)
    gamma_perp = get(kwargs,:gamma_perp,γp)
    γ = get(kwargs,:γ,gamma_perp)

    D0 = get(kwargs,:D0,D₀)
    D = get(kwargs,:D,D0)

    return TwoLevelSystem(ω, D, γ)
end

Base.conj(tls::TwoLevelSystem) = TwoLevelSystem(tls.ωa,tls.D0,-tls.γp)
Base.conj(()) = ()

function Base.getproperty(tls::TwoLevelSystem,sym::Symbol)
    if Base.sym_in(sym,(:γ,:γ_perp,:gamma_perp,:γp))
        return getfield(tls,:γ⟘)
    elseif Base.sym_in(sym,(:ω,:omega_a,:ωa))
        return getfield(tls,:ωₐ)
    elseif Base.sym_in(sym,(:D,:D0))
        return getfield(tls,:D₀)
    else
        return getfield(tls,sym)
    end
end
function Base.setproperty!(tls::TwoLevelSystem,sym::Symbol,val::Float64)
    if Base.sym_in(sym,(:γ,:γ_perp,:gamma_perp,:γp))
        return setfield!(tls,:γ⟘,val)
    elseif Base.sym_in(sym,(:ω,:omega_a,:ωa))
        return setfield!(tls,:ωₐ,val)
    elseif Base.sym_in(sym,(:D,:D0))
        return setfield!(tls,:D₀,val)
    else
        return setfield!(tls,sym,val)
    end
end
Base.setproperty!(tls::TwoLevelSystem,sym::Symbol,val::Number) = setproperty!(tls,sym,float(val))

function Base.show(io::IO, tls::TwoLevelSystem)
    print(io, "Two Level System:\n")
    print(io, "\tωₐ: ", tls.ωₐ, "\n",
    "\tD₀: ", tls.D₀, "\n",
    "\tγ⟘: ", tls.γ⟘)
end

"""
    susceptability(::TwoLevelSystem,ωs::Array,ψ::Array) -> χ::SparseMatrixCSC
"""
susceptability(tls::TwoLevelSystem,ω::Number) = χ(tls,ω)
susceptability(tls::TwoLevelSystem,args...) = χ!(tls,args...)

# function jacobian_scattering(dispersion::TwoLevelSystem,ωs::Array,ψ::Array)
#     jacobian_ψ(dispersion,ωs,ψ)
# end
#
#
# jacobian_lasing(tls::TwoLevelSystem,ωs::Array,ψ::Array) = jacobian_lasing_ψ(tls,ωs,ψ)# + jacobian_lasing_ω(tls,ωs,ψ)
#
#
# function jacobian_lasing_ψ(tls::TwoLevelSystem,ωs::Array,ψ::Array)
#     N,M = size(ψ)
#
#     x = χ(tls,ωs,ψ)
#     x_temp1 = Array{ComplexF64,1}(undef,M*N)
#     x_temp2 = Array{ComplexF64,1}(undef,M*N)
#     for μ ∈ eachindex(ωs)
#         for i ∈ 1:N
#             x_temp1[(μ-1)N+i] = -x[i,μ]*ωs[μ]^2
#             if i == N÷2 + INDEX_OFFSET
#                 x_temp2[(μ-1)N+i] = 0
#             else
#                 x_temp2[(μ-1)N+i] = -x[i,μ]*ωs[μ]^2
#             end
#         end
#     end
#     XΩ1² = spdiagm(0=>x_temp1)
#     XΩ2² = spdiagm(0=>x_temp2)
#
#     Jψr,Jψi,Jψ0 = ∂χ∂ψψ(tls,ωs,ψ)
#     J1 = Jψr+Jψ0-XΩ1²; dropzeros!(J1)
#     J2 = Jψi-XΩ2²; dropzeros!(J2)
#     Jr = hcat(real(J1),real(J2))
#     Ji = hcat(imag(J1),imag(J2))
#     return vcat(Jr,Ji)
# end
#
# function jacobian_lasing_ω(tls::TwoLevelSystem,ωs,ψ)
#     N,M = size(ψ)
#     x = χ(tls,ωs,ψ)
#     dxdwp = ∂χ∂ωψ(tls,ωs,ψ)
#
#     rows = Array{Int,1}(undef,N*M^2)
#     cols = Array{Int,1}(undef,N*M^2)
#     vals = Array{ComplexF64,1}(undef,N*M^2)
#     for μ ∈ eachindex(ωs)
#         for i ∈ 1:M*N
#             rows[(μ-1)N*M+i] = i
#             cols[(μ-1)N*M+i] = N*M+(μ-1)N+1
#             vals[(μ-1)N*M+i] = -2ωs[μ]*x[i]*ψ[i] - dxdwp[μ][i]
#         end
#     end
#     Jω = sparse(rows,cols,vals,N*M,2N*M)
#     return vcat(real(Jω),imag(Jω))
# end

##################### AUXILLIARIES FOR COMPUTING JACOBIANS #####################

χ(tls::TwoLevelSystem,ω) = tls.D₀*γ(tls,ω)

@inline function χ!(tls::TwoLevelSystem,ω,ωs::Array,ψs::Array)
    H!(tls,ωs,ψs)
    Dg = tls.D₀*γ(tls,ω)
    for i ∈ eachindex(tls.chi)
        tls.chi[i] = Dg*tls.h⁻¹[i]
    end
    return nothing
end

function χ(tls::TwoLevelSystem,ωs::Array,ψs::Array)
    N,M = size(ψs)
    chi = Array{ComplexF64,2}(undef,N,M)
    χ!(chi,tls,ωs)
    return chi
end
@inline function χ!(chi::Array{ComplexF64,2},tls::TwoLevelSystem,ωs::Array,ψs::Array)
    N,M = size(ψs)
    H!(tls,ωs,ψs)
    Dg = tls.D₀*γ(tls,ωs)
    for μ ∈ eachindex(ωs)
        for i ∈ eachindex(tls.h⁻¹)
            chi[i,μ] = Dg[μ]*tls.h⁻¹[i]
        end
    end
    return nothing
end

γ(tls::TwoLevelSystem,ωs::Array,ψs::Array) = γ(tls,ωs)
γ(tls::TwoLevelSystem,ωs::Array) = γ.(Ref(tls),ωs)
γ(tls::TwoLevelSystem,ω::Number) = tls.γ⟘/(ω-complex(tls.ωₐ,-tls.γ⟘)*one(ω))

Γ(tls::TwoLevelSystem,ωs::Array,ψs::Array) = Γ(tls,ωs)
Γ(tls::TwoLevelSystem,ωs::Array) = Γ.(Ref(tls),ωs)
Γ(tls::TwoLevelSystem,ω::Number) = abs2(γ(tls,ω))

@inline function H!(tls::TwoLevelSystem,ωs::Array,ψs::Array)
    N,M = size(ψs)
    isdefined(tls,:h) ? nothing : tls.h = zeros(Float64,N)
    isdefined(tls,:h⁻¹) ? nothing : tls.h⁻¹ = Array{Float64,1}(undef,N)
    isdefined(tls,:chi) ? nothing : tls.chi = Array{ComplexF64,1}(undef,N)
    length(tls.h)==N ? nothing : tls.h = zeros(Float64,N)
    length(tls.h⁻¹)==N ? nothing : tls.h⁻¹ = Array{Float64,1}(undef,N)
    length(tls.chi)==N ? nothing : tls.chi = Array{Float64,1}(undef,N)
    G = Γ(tls,ωs,ψs)
    for i ∈ 1:N
        tls.h[i] = 0
        for μ ∈ eachindex(ωs)
            i1 = 0N÷3 + mod1(i,N÷3)
            i2 = 1N÷3 + mod1(i,N÷3)
            i3 = 2N÷3 + mod1(i,N÷3)
            tls.h[i] += G[μ]*(abs2(ψs[i1,μ])+abs2(ψs[i2,μ])+abs2(ψs[i3,μ]))
        end
        tls.h⁻¹[i] = 1/(1+tls.h[i])
    end
    return nothing
end

# function ∂χ∂ωψ(tls::TwoLevelSystem,ωs::Array,ψ::Array)
#     N,M = size(ψ)
#     x = Array{ComplexF64,2}(undef,N,M)
#     χ!(x,tls,ωs,ψ)
#     dxdw = Array{Array{ComplexF64,2},1}(undef,M)
#     ∂χ∂ωψ!(dxdw,tls,ωs,ψ,x)
#     return map(i->dxdw[i][:].*ψ[:],eachindex(dxdw))
# end
# @inline function ∂χ∂ωψ!(dxdw::Array,tls::TwoLevelSystem,ωs::Array,ψ::Array,x::Array)
#     N,M = size(ψ)
#     h⁻¹ = 1 ./ (1 .+ H(tls,ωs,ψ))
#     dhdw = ∂H∂ω(tls,ωs,ψ)
#     g = γ(tls,ωs,ψ)
#     dg = ∂γ∂ω(tls,ωs,ψ)
#     for ρ ∈ eachindex(ωs)
#         dxdw[ρ] = Array{ComplexF64,2}(undef,N,M)
#         for μ ∈ eachindex(ωs)
#             for k ∈ eachindex(h⁻¹)
#                 dxdw[ρ][k,μ] = -x[k,μ]*h⁻¹[k]*dhdw[k,ρ]*ψ[k,μ]
#                 ρ==μ ? dxdw[μ][k,μ] += x[k,μ]*dg[μ]*ψ[k,μ]/g[μ] : nothing
#             end
#         end
#     end
#     return nothing
# end
#
# ∂γ∂ω(tls::TwoLevelSystem,ωs::Array,ψ::Array) = ∂γ∂ω(tls,ωs)
# ∂γ∂ω(tls::TwoLevelSystem,ωs::Array) = ∂γ∂ω.(Ref(tls),ωs)
# ∂γ∂ω(tls::TwoLevelSystem,ω::Number) = -γ(tls,ω)^2/tls.γ
#
# ∂Γ∂ω(tls::TwoLevelSystem,ωs::Array,ψ::Array) = ∂Γ∂ω(tls,ωs)
# ∂Γ∂ω(tls::TwoLevelSystem,ωs::Array) = ∂Γ∂ω.(Ref(tls),ωs)
# ∂Γ∂ω(tls::TwoLevelSystem,ω::Number) = -2Γ(tls,ω)^2*(ω-tls.ωₐ)/tls.γ^2
#
# function ∂H∂ω(tls::TwoLevelSystem,ωs::Array,ψ::Array)
#     a = Array{Float64,2}(undef,size(ψ))
#     ∂H∂ω!(a,tls,ωs,ψ)
#     return a
# end
# @inline function ∂H∂ω!(a::Array{Float64,2},tls::TwoLevelSystem,ωs::Array,ψ::Array)
#     b = ∂Γ∂ω(tls,ωs,ψ)
#     for μ ∈ eachindex(ωs)
#         for i ∈ 1:size(ψ,1)
#             a[i,μ] = b[μ]*abs2(ψ[i,μ])
#         end
#     end
#     return nothing
# end
#
# function ∂χ∂ψψ(tls::TwoLevelSystem,ωs::Array,ψ::Array)
#     N,M = size(ψ)
#
#     DXDPR = Array{SparseMatrixCSC{ComplexF64,Int},1}(undef,M^2)
#     DXDPI = Array{SparseMatrixCSC{ComplexF64,Int},1}(undef,M^2)
#
#     dxdpr = Array{Array{ComplexF64,2},1}(undef,M)
#     dxdpi = Array{Array{ComplexF64,2},1}(undef,M)
#     ∂χ∂ψψ!(dxdpr,dxdpi,tls,ωs,ψ)
#
#     DXDP0R = Array{SparseMatrixCSC{ComplexF64,Int},1}(undef,M^2)
#     dxdp0r = Array{Array{ComplexF64,2},1}(undef,M)
#     ∂χ∂ψ0ψ!(dxdp0r,tls,ωs,ψ)
#
#     temp0 = Array{ComplexF64,1}(undef,N)
#     temp = spdiagm(0=>temp0)
#     rows0 = Array{Int,1}(undef,N)
#     cols0 = Array{Int,1}(undef,N)
#
#     for μ ∈ eachindex(ωs)
#         for i ∈ 1:N rows0[i] = (μ-1)N+i end
#         for ν ∈ eachindex(ωs)
#             sμν = sparse([μ],[ν],ComplexF64[1],M,M)
#
#             for i ∈ 1:N temp.nzval[i] = dxdpr[ν][i,μ] end
#             DXDPR[(ν-1)M+μ] = kron(sμν,temp)
#
#             for i ∈ 1:N temp.nzval[i] = dxdpi[ν][i,μ] end
#             DXDPI[(ν-1)M+μ] = kron(sμν,temp)
#
#             for i ∈ 1:N temp0[i] = dxdp0r[ν][i,μ] end
#             for i ∈ 1:N cols0[i] = (ν-1)N+N÷2+INDEX_OFFSET end
#             DXDP0R[(ν-1)M+μ] = sparse(rows0,cols0,temp0,M*N,M*N)
#         end
#     end
#     return dropzeros!(sum(DXDPR)), dropzeros!(sum(DXDPI)), dropzeros!(sum(DXDP0R))
# end
# @inline function ∂χ∂ψψ!(dxdpr,dxdpi,tls::TwoLevelSystem,ωs::Array,ψ::Array)
#     x = Array{ComplexF64,2}(undef,size(ψ))
#     χ!(x,tls,ωs,ψ)
#     h⁻¹ = 1 ./ (1 .+ H(tls,ωs,ψ))
#     dhr, dhi = ∂H∂ψ(tls,ωs,ψ)
#
#     for ν ∈ eachindex(ωs)
#         dxdpr[ν] = Array{ComplexF64,2}(undef,size(ψ))
#         dxdpi[ν] = Array{ComplexF64,2}(undef,size(ψ))
#         for μ ∈ eachindex(ωs)
#             for k ∈ 1:size(ψ,1)
#                 if k==size(ψ,1)÷2+INDEX_OFFSET
#                     dxdpr[ν][k,μ] = 0
#                     dxdpi[ν][k,μ] = 0
#                 else
#                     dxdpr[ν][k,μ] = -x[k,μ]*h⁻¹[k]*dhr[ν][k]*ψ[k,μ]
#                     dxdpi[ν][k,μ] = -x[k,μ]*h⁻¹[k]*dhi[ν][k]*ψ[k,μ]
#                 end
#             end
#         end
#     end
#     return nothing
# end
# @inline function ∂χ∂ψ0ψ!(dxdp,tls::TwoLevelSystem,ωs::Array,ψ::Array)
#     x = Array{ComplexF64,2}(undef,size(ψ))
#     χ!(x,tls,ωs,ψ)
#     h⁻¹ = 1 ./ (1 .+ H(tls,ωs,ψ))
#
#     G = Γ(tls,ωs,ψ)
#     k = size(ψ,1)÷2+INDEX_OFFSET
#     for ν ∈ eachindex(ωs)
#         dxdp[ν] = Array{ComplexF64,2}(undef,size(ψ))
#         for μ ∈ eachindex(ωs)
#             Gν2ψ0ν = 2G[ν]/ψ[k,ν]
#             for j ∈ 1:size(ψ,1)
#                 dxdp[ν][j,μ] = -x[j,μ]*Gν2ψ0ν*abs2(ψ[j,ν])*ψ[j,μ]*h⁻¹[j]
#             end
#         end
#     end
#     return nothing
# end
#
# function ∂H∂ψ(tls::TwoLevelSystem,ωs::Array,ψ::Array)
#     N,M = size(ψ)
#     dhdpr = Array{Array{Float64,1},1}(undef,M)
#     dhdpi = Array{Array{Float64,1},1}(undef,M)
#     ∂H∂ψ!(dhdpr,dhdpi,tls,ωs,ψ)
#     return dhdpr, dhdpi
# end
# @inline function ∂H∂ψ!(dhdpr::Array,dhdpi::Array,tls::TwoLevelSystem,ωs::Array,ψ::Array)
#     G = Γ(tls,ωs,ψ)
#     for ρ ∈ eachindex(ωs)
#         dhdpr[ρ] = Array{Float64,1}(undef,size(ψ,1))
#         dhdpi[ρ] = Array{Float64,1}(undef,size(ψ,1))
#         for k ∈ 1:size(ψ,1)
#             dhdpr[ρ][k] = 2G[ρ]*real(ψ[k,ρ])
#             dhdpi[ρ][k] = 2G[ρ]*real(ψ[k,ρ])
#         end
#     end
#     return nothing
# end

end # module


text:
import JLD
import ..Infer
import ..ParallelRun: infer_init, one_node_infer, BoundingBox,
                      one_node_joint_infer, one_node_single_infer

"""
compare_vp_params
Helper to check whether two sets of variational parameters from the
result of joint inference are the same.

Return true if vp params are the same, false otherwise
"""
function compare_vp_params(r1, r2)

    # Create a map from thingid -> vp for r1
    r1_vp = Dict{Int64, Vector{Float64}}()
    for r1_result in r1
        r1_vp[r1_result.thingid] = r1_result.vs
    end

    # Check the existence and equivalence of each source's vp in r2
    for r2_result in r2
        if !haskey(r1_vp, r2_result.thingid) || r1_vp[r2_result.thingid] != r2_result.vs
            if r1_vp[r2_result.thingid] != r2_result.vs
                println("compare_vp_params: Mismatch - $(r1_vp[r2_result.thingid]) vs $(r2_result.vs)")
            end
            return false
        end
    end

    return length(r1) == length(r2)
end

"""
compute_obj_value
computes obj value given set of results from one_node_infer and one_node_joint_infer
"""
function compute_obj_value(results,
                           rcfs::Vector{RunCamcolField},
                           stagedir::String;
                           box=BoundingBox(-1000.,1000.,-1000.,1000.))
    catalog, target_sources = infer_init(rcfs, stagedir; box=box)
    images = SDSSIO.load_field_images(rcfs, stagedir)

    vp = [r.vs for r in results]

    # it may be better to pass `patches` as an argument to `compute_obj_value`.
    patches = Infer.get_sky_patches(images, catalog[target_sources])

    # if we don't call `load_active_pixels!`, these patches will be different
    # than the patches we used for optimizing---and then the objective
    # function could also be slightly different
    Infer.load_active_pixels!(images, patches)

    # this works since we're just generating patches for active_sources.
    # if instead you pass patches for all sources, then instead we'd used
    # active_sources = target_sources
    active_sources = collect(1:length(target_sources))

    ea = ElboArgs(images, vp, patches, active_sources,
                  calculate_gradient=false, calculate_hessian=false)
    DeterministicVI.elbo(ea).v[]
end

"""
test_different_result_with_different_iter()
Using 3 iters instead of 1 iters should result in a different set of parameters.
"""
function test_different_result_with_different_iter()
    # This bounding box has overlapping stars. (neighbor map is not empty)
    box = BoundingBox(4.39, 164.41, 9.11, 39.13)
    field_triplets = [RunCamcolField(3900, 6, 269),]

    infer_few(ctni...) = one_node_joint_infer(ctni...;
                                              n_iters=1,
                                              within_batch_shuffling=false)
    result_iter_1 = one_node_infer(field_triplets, datadir;
                                   infer_callback=infer_few, box=box)

    infer_many(ctni...) = one_node_joint_infer(ctni...;
                                             n_iters=5,
                                             within_batch_shuffling=false)
    result_iter_5 = one_node_infer(field_triplets, datadir;
                                   infer_callback=infer_many, box=box)

    # Make sure that parameters are not the same
    @test !compare_vp_params(result_iter_1, result_iter_5)
end

"""
test_same_result_with_diff_batch_sizes
Varying batch sizes using the cyclades algorithm should not change final objective value.
"""
function test_same_result_with_diff_batch_sizes()
    # This bounding box has overlapping stars. (neighbor map is not empty)
    box = BoundingBox(4.39, 164.41, 9.11, 39.13)
    field_triplets = [RunCamcolField(3900, 6, 269),]

    # With batch size = 7
    infer_few(ctni...) = one_node_joint_infer(ctni...;
                                n_iters=3,
                                batch_size=7,
                                within_batch_shuffling=false)
    result_bs_7 = one_node_infer(field_triplets, datadir;
                                 infer_callback=infer_few,
                                 box=box)

    # With batch size = 39
    infer_many(ctni...) = one_node_joint_infer(ctni...;
                                n_iters=3,
                                batch_size=39,
                                within_batch_shuffling=false)
    result_bs_39 = one_node_infer(field_triplets, datadir;
                                  infer_callback=infer_many,
                                  box=box)

    # Make sure that parameters are exactly the same
    @test compare_vp_params(result_bs_7, result_bs_39)
end

"""
test infer multi iter with a single (run, camcol, field).
This is basically just to make sure it runs at all.
"""
function test_one_node_joint_infer()
    # very small patch of sky that turns out to have 4 sources.
    # We checked that this patch is in the given field.
    box = BoundingBox(164.39, 164.41, 39.11, 39.13)
    field_triplets = [RunCamcolField(3900, 6, 269),]
    result = one_node_infer(field_triplets, datadir;
                            infer_callback=one_node_joint_infer,
                            box=box)
end

"""
test infer multi iter obj overlapping.
This makes sure one_node_joint_infer achieves sum objective value less
than single iter on non overlapping sources.
"""
function test_one_node_joint_infer_obj_overlapping()

    # This bounding box has overlapping stars. (neighbor map is not empty)
    box = BoundingBox(164.39, 164.41, 39.11, 39.13)
    field_triplets = [RunCamcolField(3900, 6, 269),]

    # 100 iterations
    tic()
    infer_multi(ctni...) = one_node_joint_infer(ctni...;
                                     n_iters=100,
                                     within_batch_shuffling=false)
    result_multi = one_node_infer(field_triplets, datadir;
                                  infer_callback=infer_multi,
                                  box=box)
    multi_iter_time = toq()
    score_multi = compute_obj_value(result_multi, field_triplets, datadir; box=box)

    # 2 iterations
    tic()
    infer_two(ctni...) = one_node_joint_infer(ctni...;
                                     n_iters=2,
                                     within_batch_shuffling=false)
    result_two = one_node_infer(field_triplets, datadir;
                                  infer_callback=infer_two,
                                  box=box)
    two_iter_time = toq()
    score_two = compute_obj_value(result_two, field_triplets, datadir; box=box)

    # One node infer (1 iteration, butm ore newton steps)
    tic()
    result_single = one_node_infer(field_triplets, datadir; box=box)
    single_iter_time = toq()
    score_single = compute_obj_value(result_single, field_triplets, datadir; box=box)

    println("One node joint infer objective value: $(score_multi)")
    println("One node joint infer 2 iter objective value: $(score_two)")
    println("Single iter objective value: $(score_single)")
    println("One node joint infer time: $(multi_iter_time)")
    println("One node joint infer 2 iter time: $(two_iter_time)")
    println("Single iter time: $(single_iter_time)")
    @test score_multi > score_single
    @test score_multi > score_two
end

"""
helper edges_between_sources
Helper function to determine if there are edges between 2 sets of sources
"""
function edges_between_sources(a, b, neighbor_map)
    for v_a in a, v_b in b
        # We assume undirected graph (symmetric map)
        if v_b in neighbor_map[v_a]
            println("Found edge between elements $(v_a) and $(v_b)")
            return true
        end
    end
    return false
end

"""
test cyclades partitioning.
Makes sure cyclades partitioning correctly partitions sources
"""
function test_cyclades_partitioning()
    """
    The conflict pattern is a connected 4x4 grid:
    1 -  2 - 3  - 4
    |    |   |    |
    5 -  6 - 7  - 8
    |    |   |    |
    9 - 10 - 11 - 12
    |    |   |    |
   13 - 14 - 15 - 16

    We offset 5 from every value.
    """
    neighbor_map = Dict(6=>[7,10],
                        7=>[6,8,14],
                        8=>[7,9,12],
                        9=>[8,13],
                        10=>[6,11,14],
                        11=>[7,10,12,15],
                        12=>[8,11,13,16],
                        13=>[9,12,17],
                        14=>[11,15,18],
                        15=>[11,14,16,19],
                        16=>[12,15,17,20],
                        17=>[13,16,21],
                        18=>[14,19],
                        19=>[18,15,20],
                        20=>[16,19,21],
                        21=>[17,20])

    target_sources = [6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]

    # 3 threads, 16 sources, batch_size = 4
    source_assignment = ParallelRun.partition_cyclades(3,
                                            target_sources,
                                            neighbor_map,
                                            batch_size=4)

    # Gather the entities across all batches.
    # 1. They should sum up to 16 exactly.
    # 2. They should be numbered from 1 - 16.
    all_sources =  Vector{Int64}()
    n_simulated_threads = length(source_assignment)
    n_batches = length(source_assignment[1])
    @test n_simulated_threads == 3
    for simulated_thread_id=1:3
        # Every thread must have the same # of batches.
        @test n_batches == length(source_assignment[simulated_thread_id])
        for batch=1:n_batches
            for source_id in source_assignment[simulated_thread_id][batch]
                push!(all_sources, source_id)
            end
        end
    end
    @test length(all_sources) == 16
    for source_id=1:16
        @test source_id in all_sources
    end

    # Now make sure elements of the same batches between threads do not
    # conflict (have an edge).
    for batch=1:n_batches
        t1_sources = [target_sources[x] for x in source_assignment[1][batch]]
        t2_sources = [target_sources[x] for x in source_assignment[2][batch]]
        t3_sources = [target_sources[x] for x in source_assignment[3][batch]]
        println("Batch $(batch) assignments: $t1_sources $t2_sources $t3_sources")
        @test !edges_between_sources(t1_sources, t2_sources, neighbor_map)
        @test !edges_between_sources(t1_sources, t3_sources, neighbor_map)
        @test !edges_between_sources(t2_sources, t3_sources, neighbor_map)
    end

    println("Cyclades partitioning test succeeded")
end

test_different_result_with_different_iter()
test_same_result_with_diff_batch_sizes()
test_one_node_joint_infer_obj_overlapping()

# Run this multiple times, since the cyclades algorithm shuffles the elements
# before batching them up.
for i=1:20
    test_cyclades_partitioning()
end

test_one_node_joint_infer()


text:
    """
    randomwalk(g, s, niter; seed=-1)

Perform a random walk on graph `g` starting at vertex `s` and continuing for
a maximum of `niter` steps. Return a vector of vertices visited in order.
"""
function randomwalk(g::AG, s::Integer, niter::Integer; seed::Int=-1) where AG <: AbstractGraph{T} where T
    s in vertices(g) || throw(BoundsError())
    rng = getRNG(seed)
    visited = Vector{T}()
    sizehint!(visited, niter)
    currs = s
    i = 1
    while i <= niter
        push!(visited, currs)
        i += 1
        nbrs = outneighbors(g, currs)
        length(nbrs) == 0 && break
        currs = rand(rng, nbrs)
    end
    return visited[1:(i - 1)]
end

"""
    non_backtracking_randomwalk(g, s, niter; seed=-1)

Perform a non-backtracking random walk on directed graph `g` starting at
vertex `s` and continuing for a maximum of `niter` steps. Return a
vector of vertices visited in order.
"""
function non_backtracking_randomwalk end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function non_backtracking_randomwalk(g::AG::(!IsDirected), s::Integer, niter::Integer; seed::Int=-1) where {T, AG<:AbstractGraph{T}}
    s in vertices(g) || throw(BoundsError())
    rng = getRNG(seed)
    visited = Vector{T}()
    sizehint!(visited, niter)
    currs = s
    prev = -1
    i = 1

    push!(visited, currs)
    i += 1
    nbrs = outneighbors(g, currs)
    length(nbrs) == 0 && return visited[1:(i - 1)]
    prev = currs
    currs = rand(rng, nbrs)

    while i <= niter
        push!(visited, currs)
        i += 1
        nbrs = outneighbors(g, currs)
        length(nbrs) == 1 && break
        idnext = rand(rng, 1:(length(nbrs) - 1))
        next = nbrs[idnext]
        if next == prev
            next = nbrs[end]
        end
        prev = currs
        currs = next
    end
    return visited[1:(i - 1)]
end

# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function non_backtracking_randomwalk(g::AG::IsDirected, s::Integer, niter::Integer; seed::Int=-1) where {T, AG<:AbstractGraph{T}}
    s in vertices(g) || throw(BoundsError())
    rng = getRNG(seed)
    visited = Vector{T}()
    sizehint!(visited, niter)
    currs = s
    prev = -1
    i = 1

    while i <= niter
        push!(visited, currs)
        i += 1
        nbrs = outneighbors(g, currs)
        length(nbrs) == 0 && break
        next = rand(rng, nbrs)
        if next == prev
            length(nbrs) == 1 && break
            idnext = rand(rng, 1:(length(nbrs) - 1))
            next = nbrs[idnext]
            if next == prev
                next = nbrs[end]
            end
        end
        prev = currs
        currs = next
    end
    return visited[1:(i - 1)]
end

"""
    self_avoiding_walk(g, s, niter; seed=-1)

Perform a [self-avoiding walk](https://en.wikipedia.org/wiki/Self-avoiding_walk)
on graph `g` starting at vertex `s` and continuing for a maximum of `niter` steps.
Return a vector of vertices visited in order.
"""
function self_avoiding_walk(g::AG, s::Integer, niter::Integer; seed::Int=-1) where AG <: AbstractGraph{T} where T
    s in vertices(g) || throw(BoundsError())
    rng = getRNG(seed)
    visited = Vector{T}()
    svisited = Set{T}()
    sizehint!(visited, niter)
    sizehint!(svisited, niter)
    currs = s
    i = 1
    while i <= niter
        push!(visited, currs)
        push!(svisited, currs)
        i += 1
        nbrs = setdiff(Set(outneighbors(g, currs)), svisited)
        length(nbrs) == 0 && break
        currs = rand(rng, collect(nbrs))
    end
    return visited[1:(i - 1)]
end

"""
    loop_erased_randomwalk(g, s, niter, distmx=weights(g); f=Set(), seed=-1,
                           rng=GLOBAL_RNG)

Perform a [loop-erased random walk](https://en.wikipedia.org/wiki/Loop-erased_random_walk)
on graph `g` starting at vertex `s` and continuing until one of the following
conditions are met: (i) `niter` steps are performed, (ii) the path has no more
places to go, (iii) or the walk reaches an element in f.

If f is specified and the final element of the walk is not in f, the function
will throw an error.

Return a vector of vertices visited in order.
"""
function loop_erased_randomwalk(
    g::AG, s::Integer,
    niter::Integer=max(100, nv(g)^2);
    distmx::AbstractMatrix{T}=weights(g),
    f::Union{Set{V},Vector{V}}=Set{Integer}(),
    seed::Int=-1,
    rng::AbstractRNG=GLOBAL_RNG
)::Vector{Int} where {T <: Real, U, AG <: AbstractGraph{U}, V <: Integer}
    s in vertices(g) || throw(BoundsError())

    if seed >= 0
        rng = getRNG(seed)
    end

    visited = Vector{Integer}(undef, 1)
    visited_view = view(visited, 1:1)
    visited_view[1] = s
    i = 1
    cur_pos = 1
    while i <= niter
        cur = visited_view[cur_pos]
        if cur in f
            break
        end
        nbrs = neighbors(g, cur)
        length(nbrs) == 0 && break
        wght = [distmx[cur, n] for n in nbrs]
        v = nbrs[findfirst(cumsum(wght) .> rand(rng)*sum(wght))]
        if v in visited_view
            cur_pos = indexin(v, visited_view)[1]
            visited_view = view(visited, 1:cur_pos)
        else
            cur_pos += 1
            if length(visited) < cur_pos
                resize!(visited, min(2*cur_pos, nv(g)))
            end
            visited[cur_pos] = v
            visited_view = view(visited, 1:cur_pos)
        end
        i += 1
    end

    length(f) == 0 || visited_view[cur_pos] in f || throw(ErrorException("termiating set was not reached"))
    return visited[1:cur_pos]
end


text:
module PIMD
"""
PIMD package implemented in Julia.
"""

using Distributions

export OneDimensionalQuantumSystem
export harmonicPotential, anharmonicPotential, quarticPotential
export ClassicalSystem, IsomorphicClassicalSystem
export Primitive, Staging, Normal
export HamiltonianPhase
export cayley, sqrtcayley
export md
export PotentialPropagator, ExternalPotentialPropagator, KineticPropagator, LangevinPropagator, GeneralizedCayleyPropagator
export Integrator
export StatisticalProperty
export kinetic, potential
export estimatorPotential, estimatorKinetic, estimatorKineticVirial, estimatorHessian
export MonteCarloSample
export statistics

include("propagator.jl")

MonteCarloSample(system::ClassicalSystem, nSample::Int) = begin
    space = 1000
    ninit = 10000
    momenta = MvNormal(system.M / system.β)
    uniform = Uniform(-1., 1.)
    phaseArray = []

    q = zeros(system.n)
    v = potential(system, q)
    for nStep = -ninit:(nSample * space)
        qTrial = copy(q)
        qTrial[rand(1:system.n)] += rand(uniform)
        vTrial = potential(system, qTrial)
        if rand() < min(1., exp(-system.β * (vTrial - v)))
            q .= qTrial
            v = vTrial
        end
        if nStep > 0 && nStep % space == 0
            push!(phaseArray, HamiltonianPhase(q, rand(momenta)))
        end
    end
    phaseArray
end

end


text:
include("../src/linearMeshIO.jl")

of_casefolder = joinpath(pwd(), "tests/meshes/OpenFOAM/pipe_ascii")

of_mesh = linearMeshIO.ofMeshReader.read_openfoam_mesh(of_casefolder)

max_stars_repo_name: c-schubert/linearMeshIO

max_issues_repo_name: c-schubert/linearMeshIO

max_forks_repo_name: c-schubert/linearMeshIO


text:
include("euler/euler.jl")
using .Primes: prime_numbers
using BenchmarkTools
BenchmarkTools.DEFAULT_PARAMETERS.samples = 100

compute(n::Int)::Int = prod([prime ^ trunc(Int, log(prime, n)) for prime ∈ prime_numbers(n)])

compute(10)

compute(20)

@benchmark compute(20)

max_stars_repo_name: Dynortice/Project-Euler

max_issues_repo_name: Dynortice/Project-Euler

max_forks_repo_name: Dynortice/Project-Euler


text:
Random.seed!(2333)

include("../src/Component.jl");
include("../src/React.jl");
include("../src/Server.jl");

tog = Toggle()
cho = Choice()
sli = Slider()

b_set = @bind_set (tog, cho, sli)

update_text = @output_fn (b_set...)::String begin
    print(__update_hash)

    return "tog: " * string(tog) * ", cho: " * string(cho) * "sli: " * string(sli)
end

txt = TextOutput(update_text)

app = SplitView([
    StackView([
        tog,
        cho,
        sli
    ]),
    StackView([
        txt
    ])])

run_app(app)


text:
function compute_stages!(x, Q, V, P, F, params::AbstractParametersVPRK)
    # copy x to V
    compute_stages_v_vprk!(x, V, params)

    # compute Q
    compute_stages_q_vprk!(Q, V, params)

    # compute P and F
    compute_stages_p_vprk!(Q, V, P, F, params)
end

function compute_stages!(x, q, p, λ, Q, V, U, P, F, G, params::AbstractParametersVPRK)
    # copy x to V
    compute_stages_v_vprk!(x, V, params)

    # compute U, G and p̅
    compute_projection_vprk!(x, q, p, λ, V, U, G, params)

    # compute Q
    compute_stages_q_vprk!(Q, V, U, params)

    # compute P and F
    compute_stages_p_vprk!(Q, V, P, F, params)
end

function compute_stages_v_vprk!(x::Vector{ST}, V::Vector{Vector{ST}}, params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(V)

    # copy x to V
    for i in 1:S
        @assert D == length(V[i])
        for k in 1:D
            V[i][k] = x[D*(i-1)+k]
        end
    end
end

function compute_stages_λ_vprk!(x::Vector{ST}, Λ::Vector{Vector{ST}}, params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(Λ)

    # copy x to Λ
    for i in 1:S
        @assert D == length(Λ[i])
        for k in 1:D
            Λ[i][k] = x[D*(S+i-1)+k]
        end
    end
end

function compute_stages_q_vprk!(Q::Vector{Vector{ST}}, V::Vector{Vector{ST}}, params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(Q) == length(V)

    local y1::ST
    local y2::ST

    # compute Q
    for i in 1:S
        @assert D == length(Q[i]) == length(V[i])
        for k in 1:D
            y1 = 0
            y2 = 0
            for j in 1:S
                y1 += params.tab.q.a[i,j] * V[j][k]
                y2 += params.tab.q.â[i,j] * V[j][k]
            end
            Q[i][k] = params.q̅[k] + params.Δt * (y1 + y2)
        end
    end
end

function compute_stages_q_vprk!(Q::Vector{Vector{ST}}, V::Vector{Vector{ST}}, U::Vector{Vector{ST}},
                                params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(Q) == length(V)
    @assert D == length(U[1]) == length(U[2])

    local y1::ST
    local y2::ST

    # compute Q
    for i in 1:S
        @assert D == length(Q[i]) == length(V[i])
        for k in 1:D
            y1 = 0
            y2 = 0
            for j in 1:S
                y1 += params.tab.q.a[i,j] * V[j][k]
                y2 += params.tab.q.â[i,j] * V[j][k]
            end
            Q[i][k] = params.q̅[k] + params.Δt * (y1 + y2 + params.R[1] * U[1][k])
        end
    end
end

function compute_stages_p_vprk!(Q::Vector{Vector{ST}}, V::Vector{Vector{ST}},
                                P::Vector{Vector{ST}}, F::Vector{Vector{ST}},
                                params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(Q) == length(V) == length(P) == length(F)

    local tᵢ::TT

    # compute P=ϑ(Q) and F=f(Q,V)
    for i in 1:S
        @assert D == length(Q[i]) == length(V[i]) == length(P[i]) == length(F[i])
        tᵢ = params.t̅ + params.Δt * params.tab.q.c[i]
        params.equ.ϑ(tᵢ, Q[i], V[i], P[i])
        params.equ.f(tᵢ, Q[i], V[i], F[i])
    end
end

function compute_rhs_vprk!(b::Vector{ST}, P::Vector{Vector{ST}}, F::Vector{Vector{ST}},
                                params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(P) == length(F)

    local z1::ST
    local z2::ST

    # compute b = - [(P-AF)]
    for i in 1:S
        @assert D == length(P[i]) == length(F[i])
        for k in 1:D
            z1 = 0
            z2 = 0
            for j in 1:S
                z1 += params.tab.p.a[i,j] * F[j][k]
                z2 += params.tab.p.â[i,j] * F[j][k]
            end
            b[D*(i-1)+k] = - (P[i][k] - params.p̅[k]) + params.Δt * (z1 + z2)
        end
    end
end

function compute_rhs_vprk!(b::Vector{ST}, P::Vector{Vector{ST}}, F::Vector{Vector{ST}}, G::Vector{Vector{ST}},
                                    params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(P) == length(F)

    local z1::ST
    local z2::ST

    # compute b = - [(P-G-AF)]
    for i in 1:S
        @assert D == length(P[i]) == length(F[i])
        for k in 1:D
            z1 = 0
            z2 = 0
            for j in 1:S
                z1 += params.tab.p.a[i,j] * F[j][k]
                z2 += params.tab.p.â[i,j] * F[j][k]
            end
            b[D*(i-1)+k] = - (P[i][k] - params.p̅[k]) + params.Δt * (z1 + z2 + params.R[1] * G[1][k])
        end
    end
end

function compute_rhs_vprk!(b::Vector{ST}, P::Vector{Vector{ST}}, F::Vector{Vector{ST}},
                                          R::Vector{Vector{ST}}, G::Vector{Vector{ST}},
                                          params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(P) == length(F)
    @assert S == length(R) == length(G)

    local z1::ST
    local z2::ST

    # compute b = - [(P-G-AF)]
    for i in 1:S
        @assert D == length(P[i]) == length(F[i])
        for k in 1:D
            z1 = 0
            z2 = 0
            for j in 1:S
                z1 += params.tab.p.a[i,j] * (F[j][k] + R[j][k])
                z2 += params.tab.p.â[i,j] * (F[j][k] + R[j][k])
            end
            b[D*(i-1)+k] = - (P[i][k] - params.p̅[k]) + params.Δt * (z1 + z2 + params.R[1] * G[1][k])
        end
    end
end

function compute_rhs_vprk_projection_q!(b::Vector{ST}, q::Vector{ST}, V::Vector{Vector{ST}}, U::Vector{Vector{ST}}, offset::Int,
                                    params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(V)

    local y1::ST
    local y2::ST

    for k in 1:D
        y1 = 0
        y2 = 0
        for j in 1:S
            y1 += params.tab.q.b[j] * V[j][k]
            y2 += params.tab.q.b̂[j] * V[j][k]
        end
        b[offset+k] = - (q[k] - params.q̅[k]) + params.Δt * (y1 + y2) + params.Δt * (params.R[1] * U[1][k] + params.R[2] * U[2][k])
    end
end

function compute_rhs_vprk_projection_p!(b::Vector{ST}, p::Vector{ST}, F::Vector{Vector{ST}}, G::Vector{Vector{ST}}, offset::Int,
                                    params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(F)

    local z1::ST
    local z2::ST

    for k in 1:D
        z1 = 0
        z2 = 0
        for j in 1:S
            z1 += params.tab.p.b[j] * F[j][k]
            z2 += params.tab.p.b̂[j] * F[j][k]
        end
        b[offset+k] = - (p[k] - params.p̅[k]) + params.Δt * (z1 + z2) + params.Δt * (params.R[1] * G[1][k] + params.R[2] * G[2][k])
    end
end

function compute_rhs_vprk_projection_p!(b::Vector{ST}, p::Vector{ST},
                                    F::Vector{Vector{ST}}, R::Vector{Vector{ST}}, G::Vector{Vector{ST}}, offset::Int,
                                    params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    @assert S == length(F)

    local z1::ST
    local z2::ST

    for k in 1:D
        z1 = 0
        z2 = 0
        for j in 1:S
            z1 += params.tab.p.b[j] * (F[j][k] + R[j][k])
            z2 += params.tab.p.b̂[j] * (F[j][k] + R[j][k])
        end
        b[offset+k] = - (p[k] - params.p̅[k]) + params.Δt * (z1 + z2) + params.Δt * (params.R[1] * G[1][k] + params.R[2] * G[2][k])
    end
end

@generated function compute_rhs_vprk_correction!(b::Vector{ST}, V::Vector{Vector{ST}},
                                    params::AbstractParametersVPRK{DT,TT,ET,D,S}) where {ST,DT,TT,ET,D,S}
    μ = zeros(ST,D)

    quote
        @assert S == length(V)

        local sl::Int = div(S+1, 2)

        if isdefined(params.tab, :d)
            # compute μ
            for k in 1:D
                $μ[k] = params.tab.p.b[sl] / params.tab.d[sl] * b[D*(sl-1)+k]
            end

            # replace equation for Pₗ with constraint on V
            for k in 1:D
                b[D*(sl-1)+k] = 0
                for i in 1:S
                    b[D*(sl-1)+k] += V[i][k] * params.tab.d[i]
                end
            end

            # modify P₁, ..., Pₛ except for Pₗ
            for i in 1:S
                if i ≠ sl
                    z = params.tab.d[i] / params.tab.p.b[i]
                    for k in 1:D
                        b[D*(i-1)+k] -= z * $μ[k]
                    end
                end
            end
        end
    end
end


text:
# by lazarusA # HIDE
# using GLMakie # HIDE
using CairoMakie
CairoMakie.activate!() # HIDE
let
    x = LinRange(0.01,30π,3000)
    y = sin.(x)
    lines(x, y, color = :black, figure = (resolution = (700,450),),
        axis = (xscale = log10, xlabel = "x", ylabel = "y", xgridstyle=:dash,
            ygridstyle=:dash, xminorticksvisible = true,
            xminorticks = IntervalsBetween(9)))
    ylims!(-1,1)
    current_figure()
    save(joinpath(@__DIR__, "output", "LineLogx.png"), current_figure(), px_per_unit = 2.0) # HIDE
end
using Pkg # HIDE
Pkg.status("CairoMakie") # HIDE

max_stars_repo_name: MisterBiggs/BeautifulMakie

max_issues_repo_name: MisterBiggs/BeautifulMakie

max_forks_repo_name: MisterBiggs/BeautifulMakie


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

using Markdown
using InteractiveUtils

# ╔═╡ 7c456c0c-aa2b-45a2-aa74-d50acf9b3e27
begin
	using DiffEqJump
	using Catalyst
end

# ╔═╡ 218c3506-6717-11ec-1529-71383cd2f400
md"# Modelisation of the ICEclc element"

# ╔═╡ 6297e440-3720-4ed4-a076-217efbce9422
md"## Packages"

# ╔═╡ 13119b26-15ec-4925-9766-98fdf840f6dc
md"## No loop"

# ╔═╡ 7bbabeae-90ca-4807-91d2-fba7916de0dc
let
	ice_model = @reaction_network ICE begin
	    A4, BisCD --> ∅
	    B1, 4BisR + PalpA_0 --> PalpA_BisR
	    B2, PalpA_BisR --> PalpA_0 + 4BisR
	    B3, PalpA_BisR --> PalpA_BisR + BisCD
	    B4,  ∅ --> BisR
	    B5, BisR --> ∅
	    end A4 B1 B2 B3 B4 B5

	A4 = 0.17;
	B1 = 1.0;
	B2 = 1.0;
	B3 = 1.0;
	B4 = 0.1;
	B5 = 0.17;

	p = (A4,B1,B2,B3,B4,B5);
	prob = DiscreteProblem([0,10,1,0],(0.0,100.0),p);

	jump_prob = JumpProblem(ice_model,prob,Direct());
	sol = solve(jump_prob,SSAStepper());
end;

# ╔═╡ 548c3582-d0af-4bee-bf94-fbbf931bcc35
md"## Self loop only"

# ╔═╡ 55478f82-6b7e-483c-83c0-b3ebef70a1a7
let
	ice_model = @reaction_network begin
	    A1, 2BisCD + PalpA_0 --> PalpA_BisCD
	    A2, PalpA_BisCD --> PalpA_0 + 2BisCD
	    A3, PalpA_BisCD --> PalpA_BisCD + BisCD
	    A4, BisCD --> ∅
	    end A1 A2 A3 A4

	A1 = 1.0;
	A2 = 1.0;
	A3 = 1.0;
	A4 = 0.17;

	p = (A1,A2,A3,A4);
	prob = DiscreteProblem([10,1,0],(0.0,100.0),p);

	jump_prob = JumpProblem(ice_model,prob,Direct());
	sol = solve(jump_prob,SSAStepper());
end;

# ╔═╡ 4121bd95-b06d-4343-97bf-23072127ea34
md"## Self loop with BisR"

# ╔═╡ c08ea54a-41db-4f9f-bcff-30451ae12ba4
let
	ice_model = @reaction_network begin
	    A1, 2BisCD + PalpA_0 --> PalpA_BisCD
	    A2, PalpA_BisCD --> PalpA_0 + 2BisCD
	    A3, PalpA_BisCD --> PalpA_BisCD + BisCD
	    A4, BisCD --> ∅
	    B1, 4BisR + PalpA_0 --> PalpA_BisR
	    B2, PalpA_BisR --> PalpA_0 + 4BisR
	    B3, PalpA_BisR --> PalpA_BisR + BisCD
	    B4,  ∅ --> BisR
	    B5, BisR --> ∅
	    end A1 A2 A3 A4 B1 B2 B3 B4 B5

	A1 = 1.0;
	A2 = 1.0;
	A3 = 1.0;
	A4 = 0.17;
	B1 = 1.0;
	B2 = 1.0;
	B3 = 1.0;
	B4 = 0.1;
	B5 = 0.17;

	p = (A1,A2,A3,A4,B1,B2,B3,B4,B5);
	prob = DiscreteProblem([0,1,0,10,0],(0.0,100.0),p);

	jump_prob = JumpProblem(ice_model,prob,Direct());
	sol = solve(jump_prob,SSAStepper());
end;

# ╔═╡ 193af49a-c365-4344-83fa-17fee8842b59
md"## Self loop with BisR and late promoter activation"

# ╔═╡ ff1eae8a-c77b-411b-baaf-bcbd334a10f0
let
	ice_model = @reaction_network begin
	    A1, 2BisCD + PalpA_0 --> PalpA_BisCD
	    A2, PalpA_BisCD --> PalpA_0 + 2BisCD
	    A3, PalpA_BisCD --> PalpA_BisCD + BisCD
	    A4, BisCD --> ∅
	    B1, 4BisR + PalpA_0 --> PalpA_BisR
	    B2, PalpA_BisR --> PalpA_0 + 4BisR
	    B3, PalpA_BisR --> PalpA_BisR + BisCD
	    B4,  ∅ --> BisR
	    B5, BisR --> ∅
		D1, 2BisCD + Late_0 --> Late_1
	    D2, Late_1 --> 2BisCD + Late_0
	    end A1 A2 A3 A4 B1 B2 B3 B4 B5 D1 D2

	A1 = 1.0;
	A2 = 1.0;
	A3 = 1.0;
	A4 = 0.17;
	B1 = 1.0;
	B2 = 1.0;
	B3 = 1.0;
	B4 = 0.1;
	B5 = 0.17;
	D1 = 1.0;
	D2 = 1.0;

	p = (A1,A2,A3,A4,B1,B2,B3,B4,B5,D1,D2);
	prob = DiscreteProblem([0,1,0,10,0,1,0],(0.0,100.0),p);

	jump_prob = JumpProblem(ice_model,prob,Direct());
	sol = solve(jump_prob,SSAStepper());
end;

# ╔═╡ 434e6385-61c4-4b3d-8aab-1574d7921f50
md"## Self loop with BisR, TciR induction and late promoter activation"

# ╔═╡ 878f2448-b239-4597-8769-58d5bbe36df0
let
	ice_model = @reaction_network begin
	    A1, 2BisCD + PalpA_0 --> PalpA_BisCD
	    A2, PalpA_BisCD --> PalpA_0 + 2BisCD
	    A3, PalpA_BisCD --> PalpA_BisCD + BisCD
	    A4, BisCD --> ∅
	    B1, 4BisR + PalpA_0 --> PalpA_BisR
	    B2, PalpA_BisR --> PalpA_0 + 4BisR
	    B3, PalpA_BisR --> PalpA_BisR + BisCD
	    B4,  ∅ --> BisR
	    B5, BisR --> ∅
	    C1, ∅ --> TciR
	    C2, TciR --> ∅
	    C3, 4TciR + PbisR_0 --> PbisR_1
	    C4, PbisR_1 --> 4TciR
	    C5, PbisR_1 --> PbisR_1 + 10BisR
	    D1, 2BisCD + Late_0 --> Late_1
		D2, Late_1 --> 2BisCD + Late_0
	    end A1 A2 A3 A4 B1 B2 B3 B4 B5 C1 C2 C3 C4 C5 D1 D2

	A1 = 1.0;
	A2 = 1.0;
	A3 = 1.0;
	A4 = 0.17;
	B1 = 1.0;
	B2 = 1.0;
	B3 = 1.0;
	B4 = 0.0;
	B5 = 0.17;
	C1 = 0.35;
	C2 = 0.17;
	C3 = 1.0;
	C4 = 1.0;
	C5 = 1.0;
	D1 = 1.0;
	D2 = 1.0;

	p = (A1,A2,A3,A4,B1,B2,B3,B4,B5,C1,C2,C3,C4,C5,D1,D2);
	prob = DiscreteProblem([0,1,0,0,0,0,1,0,1,0],(0.0,100.0),p);

	jump_prob = JumpProblem(ice_model,prob,Direct());
	sol = solve(jump_prob,SSAStepper());
end;

# ╔═╡ dc770cfe-fb45-453a-8857-ac0089a8c174
md"## Ptac modulation"

# ╔═╡ 83e3e47a-2deb-41e6-83e1-4bed6a6c1b77
let
	ice_model = @reaction_network begin
	    A1, 2BisCD + PalpA_0 --> PalpA_BisCD
	    A2, PalpA_BisCD --> PalpA_0 + 2BisCD
	    A3, PalpA_BisCD --> PalpA_BisCD + BisCD
	    A4, BisCD --> ∅
	    B1, 4BisR + PalpA_0 --> PalpA_BisR
	    B2, PalpA_BisR --> PalpA_0 + 4BisR
	    B3, PalpA_BisR --> PalpA_BisR + BisCD
	    B4,  ∅ --> BisR
	    B5, BisR --> ∅
	    E1, 2BisCD + PGFP_0 --> PGFP_1
	    E2, PGFP_1 --> 2BisCD + PGFP_0
	    E3, PGFP_1 --> PGFP_1 + GFP
		E4, GFP --> ∅
	    end A1 A2 A3 A4 B1 B2 B3 B4 B5 E1 E2 E3

	A1 = 1.0;
	A2 = 1.0;
	A3 = 1.0;
	A4 = 0.17;
	B1 = 1.0;
	B2 = 1.0;
	B3 = 1.0;
	B4 = 1.0; # vary between 0.0 and 1.0
	B5 = 0.17;
	E1 = 1.0;
	E2 = 1.0;
	E3 = 1.0;

	p = (A1,A2,A3,A4,B1,B2,B3,B4,B5,E1,E2,E3);
	prob = DiscreteProblem([0,1,0,0,0,1,0,0],(0.0,100.0),p);

	jump_prob = JumpProblem(ice_model,prob,Direct());
	sol = solve(jump_prob,SSAStepper());
end;

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
Catalyst = "479239e8-5488-4da2-87a7-35f2df7eef83"
DiffEqJump = "c894b116-72e5-5b58-be3c-e6d8d4ac2b12"

[compat]
Catalyst = "~10.3.0"
DiffEqJump = "~8.0.0"
"""

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

julia_version = "1.7.1"
manifest_format = "2.0"

[[deps.AbstractAlgebra]]
deps = ["GroupsCore", "InteractiveUtils", "LinearAlgebra", "Markdown", "Random", "RandomExtensions", "SparseArrays", "Test"]
git-tree-sha1 = "b5c1a469f9afd3a9d79930d2cead20c562458aae"
uuid = "c3fe647b-3220-5bb0-a1ea-a7954cac585d"
version = "0.22.3"

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

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

[[deps.ArgCheck]]
git-tree-sha1 = "dedbbb2ddb876f899585c4ec4433265e3017215a"
uuid = "dce04be8-c92d-5529-be00-80e4d2c0e197"
version = "2.1.0"

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

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

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

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

[[deps.AutoHashEquals]]
git-tree-sha1 = "45bb6705d93be619b81451bb2006b7ee5d4e4453"
uuid = "15f4f7f2-30c1-5605-9d31-71845cf9641f"
version = "0.2.0"

[[deps.BangBang]]
deps = ["Compat", "ConstructionBase", "Future", "InitialValues", "LinearAlgebra", "Requires", "Setfield", "Tables", "ZygoteRules"]
git-tree-sha1 = "95831c49cf801756a922e50641361e3b4476a782"
uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
version = "0.3.33"

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

[[deps.Baselet]]
git-tree-sha1 = "aebf55e6d7795e02ca500a689d326ac979aaf89e"
uuid = "9718e550-a3fa-408a-8086-8db961cd8217"
version = "0.1.1"

[[deps.Bijections]]
git-tree-sha1 = "705e7822597b432ebe152baa844b49f8026df090"
uuid = "e2ed5e7c-b2de-5872-ae92-c73ca462fb04"
version = "0.1.3"

[[deps.BitTwiddlingConvenienceFunctions]]
deps = ["Static"]
git-tree-sha1 = "bc1317f71de8dce26ea67fcdf7eccc0d0693b75b"
uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b"
version = "0.1.1"

[[deps.CPUSummary]]
deps = ["Hwloc", "IfElse", "Static"]
git-tree-sha1 = "87b0c9c6ee0124d6c1f4ce8cb035dcaf9f90b803"
uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9"
version = "0.1.6"

[[deps.CSTParser]]
deps = ["Tokenize"]
git-tree-sha1 = "f9a6389348207faf5e5c62cbc7e89d19688d338a"
uuid = "00ebfdb7-1f24-5e51-bd34-a7502290713f"
version = "3.3.0"

[[deps.Catalyst]]
deps = ["AbstractAlgebra", "DataStructures", "DiffEqBase", "DiffEqJump", "DocStringExtensions", "Graphs", "Latexify", "MacroTools", "ModelingToolkit", "Parameters", "Reexport", "Requires", "SparseArrays", "Symbolics"]
git-tree-sha1 = "e13b8322e890c6e577171d98fd973c2a08c744d0"
uuid = "479239e8-5488-4da2-87a7-35f2df7eef83"
version = "10.3.0"

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

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

[[deps.CloseOpenIntervals]]
deps = ["ArrayInterface", "Static"]
git-tree-sha1 = "7b8f09d58294dc8aa13d91a8544b37c8a1dcbc06"
uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9"
version = "0.1.4"

[[deps.Combinatorics]]
git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860"
uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
version = "1.0.2"

[[deps.CommonMark]]
deps = ["Crayons", "JSON", "URIs"]
git-tree-sha1 = "4aff51293dbdbd268df314827b7f409ea57f5b70"
uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6"
version = "0.8.5"

[[deps.CommonSolve]]
git-tree-sha1 = "68a0743f578349ada8bc911a5cbd5a2ef6ed6d1f"
uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2"
version = "0.2.0"

[[deps.CommonSubexpressions]]
deps = ["MacroTools", "Test"]
git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7"
uuid = "bbf7d656-a473-5ed7-a52c-81e309532950"
version = "0.3.0"

[[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.CompositeTypes]]
git-tree-sha1 = "d5b014b216dc891e81fea299638e4c10c657b582"
uuid = "b152e2b5-7a66-4b01-a709-34e65c35f657"
version = "0.1.2"

[[deps.CompositionsBase]]
git-tree-sha1 = "455419f7e328a1a2493cabc6428d79e951349769"
uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b"
version = "0.1.1"

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

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

[[deps.DEDataArrays]]
deps = ["ArrayInterface", "DocStringExtensions", "LinearAlgebra", "RecursiveArrayTools", "SciMLBase", "StaticArrays"]
git-tree-sha1 = "31186e61936fbbccb41d809ad4338c9f7addf7ae"
uuid = "754358af-613d-5f8d-9788-280bf1605d4c"
version = "0.2.0"

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

[[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.DefineSingletons]]
git-tree-sha1 = "77b4ca280084423b728662fe040e5ff8819347c5"
uuid = "244e2a9f-e319-4986-a169-4d1fe445cd52"
version = "0.1.1"

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

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

[[deps.DiffEqBase]]
deps = ["ArrayInterface", "ChainRulesCore", "DEDataArrays", "DataStructures", "Distributions", "DocStringExtensions", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "IterativeSolvers", "LabelledArrays", "LinearAlgebra", "Logging", "MuladdMacro", "NonlinearSolve", "Parameters", "PreallocationTools", "Printf", "RecursiveArrayTools", "RecursiveFactorization", "Reexport", "Requires", "SciMLBase", "Setfield", "SparseArrays", "StaticArrays", "Statistics", "SuiteSparse", "ZygoteRules"]
git-tree-sha1 = "9e91342bac01b4028b6344b0bf6acdd5cb8856bd"
uuid = "2b5f629d-d688-5b77-993f-72d75c75574e"
version = "6.79.0"

[[deps.DiffEqCallbacks]]
deps = ["DataStructures", "DiffEqBase", "ForwardDiff", "LinearAlgebra", "NLsolve", "OrdinaryDiffEq", "Parameters", "RecipesBase", "RecursiveArrayTools", "SciMLBase", "StaticArrays"]
git-tree-sha1 = "f42fade8d703f9b57d193d711b15ae7224a0db27"
uuid = "459566f4-90b8-5000-8ac3-15dfb0a30def"
version = "2.19.0"

[[deps.DiffEqJump]]
deps = ["ArrayInterface", "Compat", "DataStructures", "DiffEqBase", "FunctionWrappers", "Graphs", "LinearAlgebra", "PoissonRandom", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "StaticArrays", "TreeViews", "UnPack"]
git-tree-sha1 = "0aa2d003ec9efe2a93f93ae722de05a870ffc0b2"
uuid = "c894b116-72e5-5b58-be3c-e6d8d4ac2b12"
version = "8.0.0"

[[deps.DiffResults]]
deps = ["StaticArrays"]
git-tree-sha1 = "c18e98cba888c6c25d1c3b048e4b3380ca956805"
uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5"
version = "1.0.3"

[[deps.DiffRules]]
deps = ["LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"]
git-tree-sha1 = "9bc5dac3c8b6706b58ad5ce24cffd9861f07c94f"
uuid = "b552c78f-8df3-52c6-915a-8e097449b14b"
version = "1.9.0"

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

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

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

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

[[deps.DomainSets]]
deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "StaticArrays", "Statistics"]
git-tree-sha1 = "5f5f0b750ac576bcf2ab1d7782959894b304923e"
uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf"
version = "0.5.9"

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

[[deps.DynamicPolynomials]]
deps = ["DataStructures", "Future", "LinearAlgebra", "MultivariatePolynomials", "MutableArithmetics", "Pkg", "Reexport", "Test"]
git-tree-sha1 = "585de0d658506cf0fe5808026edff662bef5bf03"
uuid = "7c1d4256-1411-5781-91ec-d7bc3513ac07"
version = "0.4.1"

[[deps.EllipsisNotation]]
deps = ["ArrayInterface"]
git-tree-sha1 = "3fe985505b4b667e1ae303c9ca64d181f09d5c05"
uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949"
version = "1.1.3"

[[deps.ExponentialUtilities]]
deps = ["ArrayInterface", "LinearAlgebra", "Printf", "Requires", "SparseArrays"]
git-tree-sha1 = "1b873816d2cfc8c0fcb1edcb08e67fdf630a70b7"
uuid = "d4d017d3-3776-5f7e-afef-a10c40355c18"
version = "1.10.2"

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

[[deps.FastBroadcast]]
deps = ["LinearAlgebra", "Polyester", "Static"]
git-tree-sha1 = "e32a81c505ab234c992ca978f31ed8b0dabbc327"
uuid = "7034ab61-46d4-4ed7-9d0f-46aef9175898"
version = "0.1.11"

[[deps.FastClosures]]
git-tree-sha1 = "acebe244d53ee1b461970f8910c235b259e772ef"
uuid = "9aa1b823-49e4-5ca5-8b0f-3971ec8bab6a"
version = "0.3.2"

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

[[deps.FiniteDiff]]
deps = ["ArrayInterface", "LinearAlgebra", "Requires", "SparseArrays", "StaticArrays"]
git-tree-sha1 = "8b3c09b56acaf3c0e581c66638b85c8650ee9dca"
uuid = "6a86dc24-6348-571c-b903-95158fe2bd41"
version = "2.8.1"

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

[[deps.ForwardDiff]]
deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions", "StaticArrays"]
git-tree-sha1 = "2b72a5624e289ee18256111657663721d59c143e"
uuid = "f6369f11-7733-5829-9624-2563aa707210"
version = "0.10.24"

[[deps.FunctionWrappers]]
git-tree-sha1 = "241552bc2209f0fa068b6415b1942cc0aa486bcc"
uuid = "069b7b12-0de2-55c6-9aab-29f3d0a68a2e"
version = "1.1.2"

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

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

[[deps.GroupsCore]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "9e1a5e9f3b81ad6a5c613d181664a0efc6fe6dd7"
uuid = "d5909c97-4eac-4ecc-a3dc-fdd0858a4120"
version = "0.4.0"

[[deps.HostCPUFeatures]]
deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"]
git-tree-sha1 = "8f0dc80088981ab55702b04bba38097a44a1a3a9"
uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0"
version = "0.1.5"

[[deps.Hwloc]]
deps = ["Hwloc_jll"]
git-tree-sha1 = "92d99146066c5c6888d5a3abc871e6a214388b91"
uuid = "0e44f5e4-bd66-52a0-8798-143a42290a1d"
version = "2.0.0"

[[deps.Hwloc_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "3395d4d4aeb3c9d31f5929d32760d8baeee88aaf"
uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8"
version = "2.5.0+0"

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

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

[[deps.InitialValues]]
git-tree-sha1 = "40c555f961d7ccf86d8ccd150b9eef379cbfa0a3"
uuid = "22cec73e-a1b8-11e9-2c92-598750a2cf9c"
version = "0.3.0"

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

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

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

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

[[deps.IterativeSolvers]]
deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"]
git-tree-sha1 = "1169632f425f79429f245113b775a0e3d121457c"
uuid = "42fd0dbc-a981-5370-80f2-aaf504508153"
version = "0.9.2"

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

[[deps.JuliaFormatter]]
deps = ["CSTParser", "CommonMark", "DataStructures", "Pkg", "Tokenize"]
git-tree-sha1 = "51e6716cc630c157dc5fbd466429c891f5ce6462"
uuid = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
version = "0.20.5"

[[deps.KLU]]
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse_jll"]
git-tree-sha1 = "1ed18ccf6292d89abf85beba35b9399aeddff9b2"
uuid = "ef3ab10e-7fda-4108-b977-705223b18434"
version = "0.2.3"

[[deps.Krylov]]
deps = ["LinearAlgebra", "Printf", "SparseArrays"]
git-tree-sha1 = "0f47f7a2ecb7f8c4df6d258fd2268b56e62ab17c"
uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7"
version = "0.7.9"

[[deps.KrylovKit]]
deps = ["LinearAlgebra", "Printf"]
git-tree-sha1 = "0328ad9966ae29ccefb4e1b9bfd8c8867e4360df"
uuid = "0b1a1467-8014-51b9-945f-bf0ae24f4b77"
version = "0.5.3"

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

[[deps.LabelledArrays]]
deps = ["ArrayInterface", "ChainRulesCore", "LinearAlgebra", "MacroTools", "StaticArrays"]
git-tree-sha1 = "3609bbf5feba7b22fb35fe7cb207c8c8d2e2fc5b"
uuid = "2ee39098-c373-598a-b85f-a56591580800"
version = "1.6.7"

[[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.LayoutPointers]]
deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static"]
git-tree-sha1 = "83b56449c39342a47f3fcdb3bc782bd6d66e1d97"
uuid = "10f19ff3-798f-405d-979b-55457f8fc047"
version = "0.1.4"

[[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.LineSearches]]
deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"]
git-tree-sha1 = "f27132e551e959b3667d8c93eae90973225032dd"
uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255"
version = "7.1.1"

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

[[deps.LinearSolve]]
deps = ["ArrayInterface", "DocStringExtensions", "IterativeSolvers", "KLU", "Krylov", "KrylovKit", "LinearAlgebra", "RecursiveFactorization", "Reexport", "Requires", "SciMLBase", "Setfield", "SparseArrays", "SuiteSparse", "UnPack"]
git-tree-sha1 = "108bd078cf07636ddf0cd7e45739ba88a213b364"
uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae"
version = "1.2.0"

[[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.LoopVectorization]]
deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "Requires", "SIMDDualNumbers", "SLEEFPirates", "Static", "ThreadingUtilities", "UnPack", "VectorizationBase"]
git-tree-sha1 = "9e10579c154f785b911d9ceb96c33fcc1a661171"
uuid = "bdcacae8-1622-11e9-2a5c-532679323890"
version = "0.12.99"

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

[[deps.ManualMemory]]
git-tree-sha1 = "9cb207b18148b2199db259adfa923b45593fe08e"
uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667"
version = "0.1.6"

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

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

[[deps.Metatheory]]
deps = ["AutoHashEquals", "DataStructures", "Dates", "DocStringExtensions", "Parameters", "Reexport", "TermInterface", "ThreadsX", "TimerOutputs"]
git-tree-sha1 = "0886d229caaa09e9f56bcf1991470bd49758a69f"
uuid = "e9d8d322-4543-424a-9be4-0cc815abe26c"
version = "1.3.3"

[[deps.MicroCollections]]
deps = ["BangBang", "Setfield"]
git-tree-sha1 = "4f65bdbbe93475f6ff9ea6969b21532f88d359be"
uuid = "128add7d-3638-4c79-886c-908ea0c25c34"
version = "0.1.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.ModelingToolkit]]
deps = ["AbstractTrees", "ArrayInterface", "ConstructionBase", "DataStructures", "DiffEqBase", "DiffEqCallbacks", "DiffEqJump", "DiffRules", "Distributed", "Distributions", "DocStringExtensions", "DomainSets", "Graphs", "IfElse", "InteractiveUtils", "JuliaFormatter", "LabelledArrays", "Latexify", "Libdl", "LinearAlgebra", "MacroTools", "NaNMath", "NonlinearSolve", "RecursiveArrayTools", "Reexport", "Requires", "RuntimeGeneratedFunctions", "SafeTestsets", "SciMLBase", "Serialization", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicUtils", "Symbolics", "UnPack", "Unitful"]
git-tree-sha1 = "b04ebddbcae82117bc1dbc29e28b0cc1852ca8f2"
uuid = "961ee093-0014-501f-94e3-6117800e7a78"
version = "8.0.0"

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

[[deps.MuladdMacro]]
git-tree-sha1 = "c6190f9a7fc5d9d5915ab29f2134421b12d24a68"
uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221"
version = "0.2.2"

[[deps.MultivariatePolynomials]]
deps = ["DataStructures", "LinearAlgebra", "MutableArithmetics"]
git-tree-sha1 = "fa6ce8c91445e7cd54de662064090b14b1089a6d"
uuid = "102ac46a-7ee4-5c85-9060-abc95bfdeaa3"
version = "0.4.2"

[[deps.MutableArithmetics]]
deps = ["LinearAlgebra", "SparseArrays", "Test"]
git-tree-sha1 = "7bb6853d9afec54019c1397c6eb610b9b9a19525"
uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0"
version = "0.3.1"

[[deps.NLSolversBase]]
deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"]
git-tree-sha1 = "50310f934e55e5ca3912fb941dec199b49ca9b68"
uuid = "d41bc354-129a-5804-8e4c-c37616107c6c"
version = "7.8.2"

[[deps.NLsolve]]
deps = ["Distances", "LineSearches", "LinearAlgebra", "NLSolversBase", "Printf", "Reexport"]
git-tree-sha1 = "019f12e9a1a7880459d0173c182e6a99365d7ac1"
uuid = "2774e3e8-f4cf-5e23-947b-6d7e65073b56"
version = "4.5.1"

[[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.NonlinearSolve]]
deps = ["ArrayInterface", "FiniteDiff", "ForwardDiff", "IterativeSolvers", "LinearAlgebra", "RecursiveArrayTools", "RecursiveFactorization", "Reexport", "SciMLBase", "Setfield", "StaticArrays", "UnPack"]
git-tree-sha1 = "8dc3be3e9edf976a3e79363b3bd2ad776a627c31"
uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec"
version = "0.3.12"

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

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

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

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

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

[[deps.OrdinaryDiffEq]]
deps = ["Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "ExponentialUtilities", "FastClosures", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "LinearSolve", "Logging", "LoopVectorization", "MacroTools", "MuladdMacro", "NLsolve", "Polyester", "PreallocationTools", "RecursiveArrayTools", "Reexport", "SparseArrays", "SparseDiffTools", "StaticArrays", "UnPack"]
git-tree-sha1 = "40aa7e9ff9fc2ba7e3add71d6c0efcf2904340ac"
uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
version = "6.0.3"

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

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

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

[[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.PoissonRandom]]
deps = ["Random", "Statistics", "Test"]
git-tree-sha1 = "44d018211a56626288b5d3f8c6497d28c26dc850"
uuid = "e409e4f3-bfea-5376-8464-e040bb5c01ab"
version = "0.4.0"

[[deps.Polyester]]
deps = ["ArrayInterface", "BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "ManualMemory", "PolyesterWeave", "Requires", "Static", "StrideArraysCore", "ThreadingUtilities"]
git-tree-sha1 = "a804f11a4da30c0561c824e09fc627531270d9a1"
uuid = "f517fe37-dbe3-4b94-8317-1923a5111588"
version = "0.5.5"

[[deps.PolyesterWeave]]
deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"]
git-tree-sha1 = "a3ff99bf561183ee20386aec98ab8f4a12dc724a"
uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad"
version = "0.1.2"

[[deps.PreallocationTools]]
deps = ["Adapt", "ArrayInterface", "ForwardDiff", "LabelledArrays"]
git-tree-sha1 = "435379f01c1e6f7ca65cf46fdd403226f1d36e37"
uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46"
version = "0.2.1"

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

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

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

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

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

[[deps.RandomExtensions]]
deps = ["Random", "SparseArrays"]
git-tree-sha1 = "062986376ce6d394b23d5d90f01d81426113a3c9"
uuid = "fb686558-2515-59ef-acaa-46db3789a887"
version = "0.4.3"

[[deps.RandomNumbers]]
deps = ["Random", "Requires"]
git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111"
uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143"
version = "1.5.3"

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

[[deps.RecursiveArrayTools]]
deps = ["ArrayInterface", "ChainRulesCore", "DocStringExtensions", "FillArrays", "LinearAlgebra", "RecipesBase", "Requires", "StaticArrays", "Statistics", "ZygoteRules"]
git-tree-sha1 = "827ae9e1dc9fc0170319c8e77e7934b123c9bbdf"
uuid = "731186ca-8d62-57ce-b412-fbd966d074cd"
version = "2.21.1"

[[deps.RecursiveFactorization]]
deps = ["LinearAlgebra", "LoopVectorization", "Polyester", "StrideArraysCore", "TriangularSolve"]
git-tree-sha1 = "b7edd69c796b30985ea6dfeda8504cdb7cf77e9f"
uuid = "f2c3362d-daeb-58d1-803e-2bc74f2840b4"
version = "0.2.5"

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

[[deps.Referenceables]]
deps = ["Adapt"]
git-tree-sha1 = "e681d3bfa49cd46c3c161505caddf20f0e62aaa9"
uuid = "42d2dcc6-99eb-4e98-b66c-637b7d73030e"
version = "0.1.2"

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

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

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

[[deps.RuntimeGeneratedFunctions]]
deps = ["ExprTools", "SHA", "Serialization"]
git-tree-sha1 = "cdc1e4278e91a6ad530770ebb327f9ed83cf10c4"
uuid = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47"
version = "0.5.3"

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

[[deps.SIMDDualNumbers]]
deps = ["ForwardDiff", "IfElse", "SLEEFPirates", "VectorizationBase"]
git-tree-sha1 = "62c2da6eb66de8bb88081d20528647140d4daa0e"
uuid = "3cdde19b-5bb0-4aaf-8931-af3e248e098b"
version = "0.1.0"

[[deps.SIMDTypes]]
git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c"
uuid = "94e857df-77ce-4151-89e5-788b33177be4"
version = "0.1.0"

[[deps.SLEEFPirates]]
deps = ["IfElse", "Static", "VectorizationBase"]
git-tree-sha1 = "1410aad1c6b35862573c01b96cd1f6dbe3979994"
uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa"
version = "0.6.28"

[[deps.SafeTestsets]]
deps = ["Test"]
git-tree-sha1 = "36ebc5622c82eb9324005cc75e7e2cc51181d181"
uuid = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
version = "0.0.1"

[[deps.SciMLBase]]
deps = ["ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "RecipesBase", "RecursiveArrayTools", "StaticArrays", "Statistics", "Tables", "TreeViews"]
git-tree-sha1 = "c61870a745fb9a468649d9efdd05c18d30e6a6e2"
uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
version = "1.24.0"

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

[[deps.Setfield]]
deps = ["ConstructionBase", "Future", "MacroTools", "Requires"]
git-tree-sha1 = "0afd9e6c623e379f593da01f20590bacc26d1d14"
uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46"
version = "0.8.1"

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

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

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

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

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

[[deps.SparseDiffTools]]
deps = ["Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "Requires", "SparseArrays", "StaticArrays", "VertexSafeGraphs"]
git-tree-sha1 = "f33a0f6721b270cdf417f0c986e93c973e5913c8"
uuid = "47a9eef4-7e08-11e9-0b38-333d64bd3804"
version = "1.19.1"

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

[[deps.SplittablesBase]]
deps = ["Setfield", "Test"]
git-tree-sha1 = "39c9f91521de844bad65049efd4f9223e7ed43f9"
uuid = "171d559e-b47b-412a-8079-5efa626c420e"
version = "0.1.14"

[[deps.Static]]
deps = ["IfElse"]
git-tree-sha1 = "7f5a513baec6f122401abfc8e9c074fdac54f6c1"
uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
version = "0.4.1"

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

[[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 = "2bb0cb32026a66037360606510fca5984ccc6b75"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.33.13"

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

[[deps.StrideArraysCore]]
deps = ["ArrayInterface", "CloseOpenIntervals", "IfElse", "LayoutPointers", "ManualMemory", "Requires", "SIMDTypes", "Static", "ThreadingUtilities"]
git-tree-sha1 = "12cf3253ebd8e2a3214ae171fbfe51e7e8d8ad28"
uuid = "7792a7ef-975c-4747-a70f-980b88e8d1da"
version = "0.2.9"

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

[[deps.SuiteSparse_jll]]
deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"]
uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c"

[[deps.SymbolicUtils]]
deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LabelledArrays", "LinearAlgebra", "Metatheory", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "TermInterface", "TimerOutputs"]
git-tree-sha1 = "1b4d3f3bc8ecc80552b3ee24c7c5155905913931"
uuid = "d1185830-fcd6-423d-90d6-eec64667417b"
version = "0.18.2"

[[deps.Symbolics]]
deps = ["ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "IfElse", "Latexify", "Libdl", "LinearAlgebra", "MacroTools", "Metatheory", "NaNMath", "RecipesBase", "Reexport", "Requires", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicUtils", "TermInterface", "TreeViews"]
git-tree-sha1 = "c354713d0e64aa527ffd7298ce1106459540209b"
uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7"
version = "4.2.0"

[[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.TermInterface]]
git-tree-sha1 = "7aa601f12708243987b88d1b453541a75e3d8c7a"
uuid = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c"
version = "0.2.3"

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

[[deps.ThreadingUtilities]]
deps = ["ManualMemory"]
git-tree-sha1 = "03013c6ae7f1824131b2ae2fc1d49793b51e8394"
uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5"
version = "0.4.6"

[[deps.ThreadsX]]
deps = ["ArgCheck", "BangBang", "ConstructionBase", "InitialValues", "MicroCollections", "Referenceables", "Setfield", "SplittablesBase", "Transducers"]
git-tree-sha1 = "6dad289fe5fc1d8e907fa855135f85fb03c8fa7a"
uuid = "ac1d9e8a-700a-412c-b207-f0111f4b6c0d"
version = "0.1.9"

[[deps.TimerOutputs]]
deps = ["ExprTools", "Printf"]
git-tree-sha1 = "7cb456f358e8f9d102a8b25e8dfedf58fa5689bc"
uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
version = "0.5.13"

[[deps.Tokenize]]
git-tree-sha1 = "0952c9cee34988092d73a5708780b3917166a0dd"
uuid = "0796e94c-ce3b-5d07-9a54-7f471281c624"
version = "0.5.21"

[[deps.Transducers]]
deps = ["Adapt", "ArgCheck", "BangBang", "Baselet", "CompositionsBase", "DefineSingletons", "Distributed", "InitialValues", "Logging", "Markdown", "MicroCollections", "Requires", "Setfield", "SplittablesBase", "Tables"]
git-tree-sha1 = "3f0945b47207a41946baee6d1385e4ca738c25f7"
uuid = "28d57a85-8fef-5791-bfe6-a80928e7c999"
version = "0.4.68"

[[deps.TreeViews]]
deps = ["Test"]
git-tree-sha1 = "8d0d7a3fe2f30d6a7f833a5f19f7c7a5b396eae6"
uuid = "a2a6695c-b41b-5b7d-aed9-dbfdeacea5d7"
version = "0.3.0"

[[deps.TriangularSolve]]
deps = ["CloseOpenIntervals", "IfElse", "LayoutPointers", "LinearAlgebra", "LoopVectorization", "Polyester", "Static", "VectorizationBase"]
git-tree-sha1 = "ec9a310324dd2c546c07f33a599ded9c1d00a420"
uuid = "d5829a12-d9aa-46ab-831f-fb7c9ab06edf"
version = "0.1.8"

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

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

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

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

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

[[deps.VectorizationBase]]
deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "Hwloc", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static"]
git-tree-sha1 = "6e261bff5c9f2537776165dea3067df9de4440cf"
uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f"
version = "0.21.23"

[[deps.VertexSafeGraphs]]
deps = ["Graphs"]
git-tree-sha1 = "8351f8d73d7e880bfc042a8b6922684ebeafb35c"
uuid = "19fa3120-7c27-5ec5-8db8-b0b0aa330d6f"
version = "0.2.0"

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

[[deps.ZygoteRules]]
deps = ["MacroTools"]
git-tree-sha1 = "8c1a8e4dfacb1fd631745552c8db35d0deb09ea0"
uuid = "700de1a5-db45-46bc-99cf-38207098b444"
version = "0.2.2"

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

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

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

# ╔═╡ Cell order:
# ╟─218c3506-6717-11ec-1529-71383cd2f400
# ╟─6297e440-3720-4ed4-a076-217efbce9422
# ╠═7c456c0c-aa2b-45a2-aa74-d50acf9b3e27
# ╟─13119b26-15ec-4925-9766-98fdf840f6dc
# ╠═7bbabeae-90ca-4807-91d2-fba7916de0dc
# ╟─548c3582-d0af-4bee-bf94-fbbf931bcc35
# ╠═55478f82-6b7e-483c-83c0-b3ebef70a1a7
# ╟─4121bd95-b06d-4343-97bf-23072127ea34
# ╠═c08ea54a-41db-4f9f-bcff-30451ae12ba4
# ╟─193af49a-c365-4344-83fa-17fee8842b59
# ╠═ff1eae8a-c77b-411b-baaf-bcbd334a10f0
# ╟─434e6385-61c4-4b3d-8aab-1574d7921f50
# ╠═878f2448-b239-4597-8769-58d5bbe36df0
# ╟─dc770cfe-fb45-453a-8857-ac0089a8c174
# ╠═83e3e47a-2deb-41e6-83e1-4bed6a6c1b77
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_name: Flamanjaune/PHD-Thesis

max_issues_repo_name: Flamanjaune/PHD-Thesis

max_forks_repo_name: Flamanjaune/PHD-Thesis