text:
"""
Generates transition bounds with the given parameters.
"""
function generate_transition_bounds(params, gp_info_dict, region_data;
                                    reuse_mats_flag=false)

    exp_dir = params.experiment_directory
    region_dict = region_data[:extents]
    region_post_dict = region_data[:posts]

    tmat_filename = "$exp_dir/transition_mats.bson"
    if !reuse_mats_flag || !isfile(tmat_filename)
        @info "Calculating transition probability bounds between regions..."
        minPr_mat, maxPr_mat = process(region_dict, region_post_dict, params.data_params.epsilon, gp_info_dict, params)
    end

    res_mats = Dict("minPr" => minPr_mat, "maxPr" => maxPr_mat)
    return res_mats
end

"""
Generates transition bounds with the given parameters.
"""
function generate_transition_bounds(params, region_data;
                                    reuse_mats_flag=false)

    exp_dir = params.experiment_directory
    region_dict = region_data[:extents]
    region_post_dict = region_data[:posts]
    region_gp_dict = region_data[:gps]

    tmat_filename = "$exp_dir/transition_mats.bson"
    if !reuse_mats_flag || !isfile(tmat_filename)
        @info "Calculating transition probability bounds between regions..."
        results_df = process_foo(region_dict, region_post_dict, region_gp_dict, params.data_params.epsilon, params)

        # Save the matrices for use in MATLAB verification tool
        num_states = region_dict.count
        minPr_mat = spzeros(num_states, num_states)
        maxPr_mat = spzeros(num_states, num_states)
        for i = 1:1:num_states
            sub_row = results_df[results_df.Set1 .== i, :]
            if i == num_states
                minPr_mat[i, i] = 1.
                maxPr_mat[i, i] = 1.
            else
                for j = 1:1:num_states
                    if j == num_states
                        subsub_row = sub_row[sub_row.Set2 .== j, :]
                        minPr_mat[i, j] = 1. - subsub_row.MaxPr[1]
                        maxPr_mat[i, j] = 1. - subsub_row.MinPr[1]
                    else
                        subsub_row = sub_row[sub_row.Set2 .== j, :]
                        minPr_mat[i, j] = subsub_row.MinPr[1]
                        maxPr_mat[i, j] = subsub_row.MaxPr[1]
                    end
                end
            end
        end
    end

    res_mats = Dict("minPr" => minPr_mat, "maxPr" => maxPr_mat)
    return res_mats
end

function load_transition_matrices(filename)
    res_mats = BSON.load(filename)
    return res_mats
end

function save_transition_matrices(params::ExperimentParameters, res_mats::Dict)
    exp_dir = params.experiment_directory
    tmat_filename = "$exp_dir/transition_mats.bson"
    save_transition_matrices(res_mats, tmat_filename)
end

function save_transition_matrices(res_mats::Dict, filename::String)
    bson(filename, res_mats)
end

function fetch_results(N, r)
    results_df = DataFrame(Set1 = Int[], Set2 = Int[], MinPr = Float64[], MaxPr = Float64[], MinPrPoint = Array[], MaxPrPoint = Array[])
    for j in 1:N
        total_results = fetch(r[j])
        push!(results_df, total_results)
    end
    return results_df
end

function process(region_dict, region_post_dict, epsilon, gp_dict, params)

    minPrs = spzeros(region_dict.count, region_dict.count)
    maxPrs = spzeros(region_dict.count, region_dict.count)

    mean_dict = Dict()
    for i=1:region_dict.count-1
        region = region_dict[i]
        mean_dict[i] = [mean(region[dim_key]) for dim_key in keys(region)]
    end

    set_radius = sqrt(2)*params.discretization_step["x1"]

    for i=1:region_dict.count-1
        ϵ_crit = calculate_ϵ_crit(gp_dict, region_post_dict[i][2])
        # calculate center of post image
        post_image = region_post_dict[i][1]
        mean_pt = [mean(post_image[dim_key]) for dim_key in keys(post_image)]
        # TODO: This is not generalized
        image_radius = sqrt((mean_pt[1] - post_image["x1"][1])^2 + (mean_pt[1] - post_image["x2"][1])^2)
        for j=1:region_dict.count-1
            if fast_check(mean_pt, mean_dict[j], ϵ_crit, image_radius, set_radius)
                res = region_pair_transitions((i,j), region_dict, region_post_dict, epsilon, gp_dict, params)
            else
                res = [i, j, 0., 0., [-1., -1.], [-11., -11.]]
            end
            minPrs[i, j] = res[3]
            maxPrs[i, j] = res[4]
        end

        res = region_pair_transitions((i,region_dict.count), region_dict, region_post_dict, epsilon, gp_dict, params)
        minPrs[i, region_dict.count] = 1. - res[4]
        maxPrs[i, region_dict.count] = 1. - res[3]
    end

    minPrs[region_dict.count, region_dict.count] = 1.0
    maxPrs[region_dict.count, region_dict.count] = 1.0

    for (minrow, maxrow) in zip(eachrow(minPrs), eachrow(maxPrs))
        @assert sum(maxrow) >= 1
        @assert sum(minrow) <= 1
    end

    return minPrs, maxPrs
end

function process_foo(region_dict, region_post_dict, region_gp_dict, epsilon, params)
    N = region_dict.count
    r = Array{Array, 1}(undef, N)

    for (i, pair) = enumerate(Base.product(1:N, 1:N))
        i == N ? continue : nothing
        r[i] = region_pair_transitions(pairs[i], region_dict, region_post_dict, epsilon, region_gp_dict[pairs[i][1]], params)
    end

    results_df = fetch_results(N, r)
    return results_df
end

"Determine the set of states that will have non-zero transition probability upper bounds."
function fast_check(mean_pt, mean_target, ϵ_crit, image_radius, set_radius)
    flag = norm(mean_pt - mean_target) < ϵ_crit + image_radius + set_radius
    return flag
end

"Calculate the transition probabilities between a pair of regions."
function region_pair_transitions(region_pair, region_dict, region_post_dict, ϵ, gp_info_dict, params)
    dict_row = region_post_dict[region_pair[1]]
    σ_bounds = dict_row[2]

    # Get the subset of the safe region that matters.
    safe_keys = params.data_params.safety_dims
    S = Dict()
    Q_post_extent = Dict()
    for dim_key in safe_keys
        S[dim_key] = region_dict[region_pair[2]][dim_key]
        Q_post_extent[dim_key] = dict_row[1][dim_key]
    end

    # For now, do a naiive shrink - first noise, then the next
    if !isnothing(params.system_params.process_noise_dist)
        ϵ_noise = params.data_params.eta
        Pr_noise = (cdf(params.system_params.process_noise_dist, ϵ_noise) - cdf(params.system_params.process_noise_dist, -ϵ_noise))^length(σ_bounds)
    else
        ϵ_noise = 0.
        Pr_noise = 1.
    end

    Sshrink = margin_extent(S, ϵ_noise)
    Sexpand = margin_extent(S, -ϵ_noise)
    s_shape = extent_to_shape(Sshrink)
    S_shape = extent_to_shape(Sexpand)

    Q_shape = extent_to_shape(Q_post_extent)
    n_dims = length(safe_keys)
    axes = I+zeros(n_dims, n_dims)

    if ϵ > 0
        # Manual Epsilon Choice
        sd_min = Inf
        for dim_key in keys(Sshrink)
            sd_min = minimum([sd_min, 0.5*abs(Sshrink[dim_key][1]-Sshrink[dim_key][2])])
        end
        shrink_ϵ = minimum([ϵ, sd_min])
        expand_ϵ = ϵ

        Sshrink2 = margin_extent(S, shrink_ϵ)
        Sexpand2 = margin_extent(S, -expand_ϵ)
        s_shape2 = extent_to_shape(Sshrink2)
        S_shape2 = extent_to_shape(Sexpand2)

        shrink_int, _ = does_shape2_contain_shape1(Q_shape, s_shape2, axes=axes)
        expand_int, _ = do_shapes_intersect(Q_shape, S_shape2, axes=axes)
    else
        # Auto Epsilon Choice
        shrink_int, shrink_ϵ = does_shape2_contain_shape1(Q_shape, s_shape, axes=axes)
        expand_int, expand_ϵ = do_shapes_intersect(Q_shape, S_shape, axes=axes)
    end

    if (shrink_int && !expand_int)
        @info "Shrink Flag: ", shrink_int, "Expand Flag: ", expand_int
        @info "Q Post Extent: ", Q_post_extent
        @info "Q Post Shape: ", Q_shape
        @info "S Extent: ", S
        @info "S Shrink Ex: ", Sshrink
        @info "S Shrink Shape: ", s_shape
        @info "S Expand Ex: ", Sexpand
        @info "S Expand Shape: " S_shape
        @info "Shrink Ep: ", shrink_ϵ, "Expand Ep: ", expand_ϵ
        @error "You cannot both interesect and not intersect at the same time!"
    end

    if shrink_int
        P_bound_lower = calculate_probability_bound(gp_info_dict, σ_bounds, shrink_ϵ)
        minPr_LB = P_bound_lower*Pr_noise
    else
        minPr_LB = 0.
    end

    if !expand_int
        Pr_bound_upper = calculate_probability_bound(gp_info_dict, σ_bounds, expand_ϵ)
        maxPr_UB = 1. - Pr_bound_upper
    else
        maxPr_UB = 1.
    end

    @assert maxPr_UB >= minPr_LB

    foo = [0., 0.]
    frame_row = [region_pair[1], region_pair[2], minPr_LB, maxPr_UB, [shrink_ϵ, expand_ϵ], foo]
    return frame_row
end

"""
Calculate transition probability bounds between two regions with a different flavor
"""
function region_pair_transitions(region_pair, region_dict, region_post_dict, ϵ, gp_info_dict, process_noise_dist, ϵ_noise)
    dict_row = region_post_dict[region_pair[1]]
    σ_bounds = dict_row[2]

    # Get the subset of the safe region that matters.
    # safe_keys = params.data_params.safety_dims
    S = Dict()
    Q_post_extent = Dict()
    safe_keys = keys(dict_row[1])
    for dim_key in safe_keys
        S[dim_key] = region_dict[region_pair[2]][dim_key]
        Q_post_extent[dim_key] = dict_row[1][dim_key]
    end

    # For now, do a naiive shrink - first noise, then the next
    if !isnothing(process_noise_dist)
        Pr_noise = (cdf(process_noise_dist, ϵ_noise) - cdf(process_noise_dist, -ϵ_noise))^length(σ_bounds)
    else
        ϵ_noise = 0.
        Pr_noise = 1.
    end

    Sshrink = margin_extent(S, ϵ_noise)
    Sexpand = margin_extent(S, -ϵ_noise)
    s_shape = extent_to_shape(Sshrink)
    S_shape = extent_to_shape(Sexpand)

    Q_shape = extent_to_shape(Q_post_extent)
    n_dims = length(safe_keys)
    axes = I+zeros(n_dims, n_dims)

    if ϵ > 0
        # Manual Epsilon Choice
        sd_min = Inf
        for dim_key in keys(Sshrink)
            sd_min = minimum([sd_min, 0.5*abs(Sshrink[dim_key][1]-Sshrink[dim_key][2])])
        end
        shrink_ϵ = minimum([ϵ, sd_min])
        expand_ϵ = ϵ

        Sshrink2 = margin_extent(S, shrink_ϵ)
        Sexpand2 = margin_extent(S, -expand_ϵ)
        s_shape2 = extent_to_shape(Sshrink2)
        S_shape2 = extent_to_shape(Sexpand2)

        shrink_int, _ = does_shape2_contain_shape1(Q_shape, s_shape2, axes=axes)
        expand_int, _ = do_shapes_intersect(Q_shape, S_shape2, axes=axes)
    else
        # Auto Epsilon Choice
        shrink_int, shrink_ϵ = does_shape2_contain_shape1(Q_shape, s_shape, axes=axes)
        expand_int, expand_ϵ = do_shapes_intersect(Q_shape, S_shape, axes=axes)
    end

    if (shrink_int && !expand_int)
        @info "Shrink Flag: ", shrink_int, "Expand Flag: ", expand_int
        @info "Q Post Extent: ", Q_post_extent
        @info "Q Post Shape: ", Q_shape
        @info "S Extent: ", S
        @info "S Shrink Ex: ", Sshrink
        @info "S Shrink Shape: ", s_shape
        @info "S Expand Ex: ", Sexpand
        @info "S Expand Shape: " S_shape
        @info "Shrink Ep: ", shrink_ϵ, "Expand Ep: ", expand_ϵ
        @error "You cannot both interesect and not intersect at the same time!"
    end

    if shrink_int
        P_bound_lower = calculate_probability_bound(gp_info_dict, σ_bounds, shrink_ϵ)
        minPr_LB = P_bound_lower*Pr_noise
    else
        minPr_LB = 0.
    end

    if !expand_int
        Pr_bound_upper = calculate_probability_bound(gp_info_dict, σ_bounds, expand_ϵ)
        maxPr_UB = 1. - Pr_bound_upper
    else
        maxPr_UB = 1.
    end

    @assert maxPr_UB >= minPr_LB

    foo = [0., 0.]
    frame_row = [region_pair[1], region_pair[2], minPr_LB, maxPr_UB, [shrink_ϵ, expand_ϵ], foo]
    return frame_row
end

"""
Calculate the transition probability bounds from a point to a target region.
"""
function point_region_transitions(μ::Dict, σ::Dict, target_region_idx, region_dict, ϵ, gp_info_dict; process_noise_dist=nothing)

    # Get the subset of the safe region that matters.
    # safe_keys = params.data_params.safety_dims
    safe_keys = keys(gp_info_dict)
    S = Dict()
    Q_post_extent = Dict()
    for dim_key in safe_keys
        S[dim_key] = region_dict[target_region_idx][dim_key]
        Q_post_extent[dim_key] = [μ[dim_key], μ[dim_key]]
    end

    n_dims = length(μ)

    # For now, do a naiive shrink - first noise, then the next
    if !isnothing(process_noise_dist)
        ϵ_noise = 0.02
        Pr_noise = (cdf(process_noise_dist, ϵ_noise) - cdf(process_noise_dist, -ϵ_noise))^n_dims
    else
        ϵ_noise = 0.
        Pr_noise = 1.
    end

    Sshrink = margin_extent(S, ϵ_noise)
    Sexpand = margin_extent(S, -ϵ_noise)
    s_shape = extent_to_shape(Sshrink)
    S_shape = extent_to_shape(Sexpand)

    Q_shape = extent_to_shape(Q_post_extent)
    axes = I+zeros(n_dims, n_dims)

    if ϵ > 0
        # Manual Epsilon Choice
        sd_min = Inf
        for dim_key in keys(Sshrink)
            sd_min = minimum([sd_min, 0.5*abs(Sshrink[dim_key][1]-Sshrink[dim_key][2])])
        end
        shrink_ϵ = minimum([ϵ, sd_min])
        expand_ϵ = ϵ

        Sshrink2 = margin_extent(S, shrink_ϵ)
        Sexpand2 = margin_extent(S, -expand_ϵ)
        s_shape2 = extent_to_shape(Sshrink2)
        S_shape2 = extent_to_shape(Sexpand2)

        shrink_int, _ = does_shape2_contain_shape1(Q_shape, s_shape2, axes=axes)
        expand_int, _ = do_shapes_intersect(Q_shape, S_shape2, axes=axes)
    else
        # Auto Epsilon Choice
        shrink_int, shrink_ϵ = does_shape2_contain_shape1(Q_shape, s_shape, axes=axes)
        expand_int, expand_ϵ = do_shapes_intersect(Q_shape, S_shape, axes=axes)
    end

    if (shrink_int && !expand_int)
        @info "Shrink Flag: ", shrink_int, "Expand Flag: ", expand_int
        @info "Q Post Extent: ", Q_post_extent
        @info "Q Post Shape: ", Q_shape
        @info "S Extent: ", S
        @info "S Shrink Ex: ", Sshrink
        @info "S Shrink Shape: ", s_shape
        @info "S Expand Ex: ", Sexpand
        @info "S Expand Shape: " S_shape
        @info "Shrink Ep: ", shrink_ϵ, "Expand Ep: ", expand_ϵ
        @error "You cannot both interesect and not intersect at the same time!"
    end

    if shrink_int
        P_bound_lower = calculate_probability_bound_dict(gp_info_dict, σ, shrink_ϵ)
        minPr_LB = P_bound_lower*Pr_noise
    else
        minPr_LB = 0.
    end

    if !expand_int
        Pr_bound_upper = calculate_probability_bound_dict(gp_info_dict, σ, expand_ϵ)
        maxPr_UB = 1. - Pr_bound_upper
    else
        maxPr_UB = 1.
    end

    @assert maxPr_UB >= minPr_LB

    if target_region_idx == region_dict.count
        frame_row = [1-maxPr_UB, 1-minPr_LB, [shrink_ϵ, expand_ϵ]]
    else
        frame_row = [minPr_LB, maxPr_UB, [shrink_ϵ, expand_ϵ]]
    end

    return frame_row
end

###############################################################################################
# Local Methods
###############################################################################################
function margin_extent(extent, ep)
    new_dict = Dict()
    for dim_key in keys(extent)
        new_dict[dim_key] = [extent[dim_key][1] + ep, extent[dim_key][2] - ep]
    end
    return return new_dict
end

function extent_to_shape(extent)
    extent_arrays = [extent[dim_key] for dim_key in keys(extent)]
    vert_tuples = collect(Base.product(extent_arrays...))
    vertices = [hcat([i[j] for j=1:length(i)]...) for i in vert_tuples]
    return Dict("vertices" => vertices[:])
 end

function calculate_probability_bound(gp_info_dict, σ_bounds, ϵ)
    Pr_bound = 1.
    for (i, dim_key) in enumerate(keys(gp_info_dict))
        bound_type = gp_info_dict[dim_key].bound_type
        if bound_type == "rkhs-tight"
            Pr_bound *= 1. - tight_rkhs_bound_prob(σ_bounds[i], ϵ, gp_info_dict[dim_key])

        elseif bound_type == "rkhs-original"
            Pr_bound *= 1. - original_rkhs_bound_prob(σ_bounds[i], ϵ, gp_info_dict[dim_key])
        # elseif bound_type == "munich"
        #     # TODO: Fix this so it works
        #     Pr_bound *= 1. - munich_bound_prob(point, gp_x1, prior_norms[1], ϵ)
        else
            @error "Invalid bound type:" bound_type
        end

    end
    return Pr_bound
end

function calculate_probability_bound_dict(gp_info_dict, σ_bounds, ϵ)
    Pr_bound = 1.
    for dim_key in keys(gp_info_dict)
        bound_type = gp_info_dict[dim_key].bound_type
        if bound_type == "rkhs-tight"
            Pr_bound *= 1. - tight_rkhs_bound_prob(σ_bounds[dim_key], ϵ, gp_info_dict[dim_key])
        elseif bound_type == "rkhs-original"
            Pr_bound *= 1. - original_rkhs_bound_prob(σ_bounds[dim_key], ϵ, gp_info_dict[dim_key])
        else
            @error "Invalid bound type:" bound_type
        end
    end
    return Pr_bound
end

function calculate_ϵ_crit(gp_info_dict, σ_bounds)
    candidates = []
    for (i, dim_key) in enumerate(keys(gp_info_dict))
        ϵ = 0.01
        P = 0.0
        bound_type = gp_info_dict[dim_key].bound_type
        while P != 1.0
            if bound_type == "rkhs-tight"
                P = 1. - tight_rkhs_bound_prob(σ_bounds[i], ϵ, gp_info_dict[dim_key])
            elseif bound_type == "rkhs-original"
                P = 1. - original_rkhs_bound_prob(σ_bounds[i], ϵ, gp_info_dict[dim_key])
            else
                @error "Invalid bound type:" bound_type
            end
            ϵ *= 1.5
        end
        push!(candidates, ϵ)
    end
    return maximum(candidates)
end


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

using Markdown
using InteractiveUtils

# ╔═╡ 5b4e526e-3dfa-11eb-3472-bd753d60c119
#hide
begin
#for sharing environments between notebooks
import Pkg
Pkg.activate(Base.current_project())
end

# ╔═╡ 5b3f2908-4bcf-4dea-b59b-e54a5f11f7b5
using PlutoTest

# ╔═╡ 1cfdfbea-3ef7-4a38-b42b-8610d0f90646
#hide
begin
using PlutoUI
TableOfContents()
end

# ╔═╡ 5bb30a64-043e-4ad0-9d60-3d470d22fd8f
#hide
include("../src/Documenter.jl")

# ╔═╡ 486bb5f0-54be-11eb-0e7c-1dcf55b5f983
md"The Export module helps in exporting the code to script files."

# ╔═╡ 0aecd4c0-0e14-11eb-1619-4f5e0ced1279
#export
import Pluto: Notebook, Cell, load_notebook_nobackup

# ╔═╡ 2181580b-7f3e-456f-aa62-68130d9b9178
#hide
load_notebook_nobackup("./01_export.jl")

# ╔═╡ 6ff1ad80-1479-11eb-3868-0df000f47cc9
md"## Lower Level Entities(Structs, methods etc.)

These are the objects on which nbdev's Export module was built. You can use it to extend nbdev but these are automtically used by Nbdev's internal engine to generate code files for you."

# ╔═╡ 16fbf5b0-54bf-11eb-3c21-2bf024188fac
md"## Nucleus type"

# ╔═╡ a5bfff40-1620-11eb-2824-2d49985a022d
#export
begin
"""
> struct Nucleus--> This is the lowest entity of a code notebook. This type represents the code cell in a Pluto notebook.
> * Fields:
>   * code--> String which makes up a code cell
"""
Base.@kwdef mutable struct Nucleus
	code::String=""
	end

"""
> Nucleus(code)-->Getter for accessing the constructer of the Nucleus type
"""
Nucleus(code) = Nucleus(code = code)
end

# ╔═╡ ad64c040-54bf-11eb-2c3d-ff1de3c15f3f
Documenter.showdoc(Nucleus)

# ╔═╡ 1d983360-54c0-11eb-0104-672aaffbbb95
md"Every time a code cell is parsed, it gets stored as a Nucleus type. The stored code can then be accessed using the `code` field in the Nucleus type."

# ╔═╡ cc7be350-54bf-11eb-2107-335896e7fbf3
md"#### Example"

# ╔═╡ d38222e0-54bf-11eb-309a-2722b3e78bbc
sample_code="a=1+1"

# ╔═╡ f1eadd80-54bf-11eb-1de4-ef2da2e36eda
nucleus=Nucleus(sample_code)

# ╔═╡ 0361d7d0-54c0-11eb-0a50-79dc00a9d848
#noop
@test nucleus.code == "a=1+1"

# ╔═╡ d236da00-54c6-11eb-3afe-859ccc31d041
md"## Nb type"

# ╔═╡ d17ebf90-1486-11eb-0d41-b967a8ab82ba
#export
begin
"""
> struct Nb--> a notebook having nuclei made up of code cells only.
> * Fields:
>   * nuclei--> Array of Nucleus type
>   * name--> name of notebook
"""
mutable struct Nb
	nuclei::Array{Nucleus,1}
	name::AbstractString
end

"""
> nuclei(nuclei::Array)--> Helper to collect an array of Nucleus.
"""
nuclei(nuclei::Array) = nuclei

"""
> nuclei(nuclei::Array)--> Helper to collect an name of a notebook.
"""
name(name::AbstractString) = name
end

# ╔═╡ 117932c0-54c8-11eb-158c-5be86ba8fd19
Documenter.showdoc(Nb)

# ╔═╡ 65163a40-54c8-11eb-3384-61a1dce37c10
Documenter.showdoc(nuclei)

# ╔═╡ 6d8afdf0-54c8-11eb-27e5-d59d375bd9eb
Documenter.showdoc(name)

# ╔═╡ 93dc68e0-54c8-11eb-0b28-eb809c1f15a6
md"A Nb type is used to collect all code cells(which are contained in the Nucleus type. These code cells are actual code represented as string."

# ╔═╡ 772778c0-54c8-11eb-3b23-01d2dc0c5dc0
md"#### Example"

# ╔═╡ 8e253e90-54c8-11eb-3456-97a428b1f232
samplecodes=[Nucleus("a=1+1"), Nucleus("function test(x)  x+1 end"), Nucleus("test(2)")]

# ╔═╡ 020a9620-54c9-11eb-107e-c107354dc90a
nb=Nb(samplecodes, "testnb.jl")

# ╔═╡ cf50547e-54c9-11eb-132d-894c0cfe9ccc
#noop
@test nb.nuclei == samplecodes

# ╔═╡ 99fd66a0-54ca-11eb-3d11-d92049fd2f6a
#noop
@test nb.name == "testnb.jl"

# ╔═╡ 296282f0-1770-11eb-0900-b37a94fbc69c
#export
begin
"""
Headers that would appear in a code file
"""
const header = "### A Nbdev script file ###"
const subheader = "### Autogenerated file. Don't modify. ###"
end

# ╔═╡ 2a36f0b0-54cb-11eb-1b53-0998e776d5a5
md"`collect_nuclei(notebook::ScrubbedNotebook, marker)` reads the entire notebook cell by cell and then checks if the content of that cell starts with a marker, only then it builds an array of the Nucleus type. "

# ╔═╡ 773b9da0-2fd4-11eb-1c65-a10ea8672725
#export
"""
This had to be done because having the cell iddelimeter as a constant gives an error during parsing the notebook
"""
celliddelim=string("#"," ╔═╡ ")

# ╔═╡ 6bfde500-2fcb-11eb-2b73-7ddce97351d3
#export
"""
marks the end of a cell
"""
const cellsuff = "\n\n"

# ╔═╡ 0561b9f0-54d5-11eb-01f0-8bde739e3e37
md"## loadscrubbednb"

# ╔═╡ 512e7b20-54d5-11eb-3ff9-b150bf2f9e26
md"`loadscrubbednb` reads the notebook in the given path cell by cell, while ignoring the stuffs in the notebook like the cell order delimeters and the cell start delimeter. The result is a `ScrubbedNotebook` type which contains only the code which you intend to export."

# ╔═╡ 12377150-54d6-11eb-18ff-ef441154f771
md"## High Level APIs

This too are called automatically by Nbdev."

# ╔═╡ c71b1460-54d5-11eb-3e6b-cb3dadbc0349
md"## loadnb"

# ╔═╡ 8b7e8030-54d6-11eb-2f48-d3bc02e21c96
md"## Scrubbednb"

# ╔═╡ 20c285d0-2fb4-11eb-1ef0-3b28829af7e8
#export
"""
> struct Scrubbednb--> Represents a notebook from which all but code to be exported are scrubbed off.
> * Fields-->
>   * cells--> Vector of strings.
"""
mutable struct Scrubbednb
	cells::Array{String, 1}
end

# ╔═╡ d4daaac0-0eb2-11eb-1d4d-7763fcfc0ed2
#export
"""
> collectnuclei(notebook::Scrubbednb, marker)--> Reads a notebook, collects code from code cells and returns an array of Nucelus.
"""
function collectnuclei(nb::Scrubbednb, marker)
	nbcells=nb.cells
	nuclei=[]

    for i in 1:length(nbcells)
    	raw_code=nbcells[i]
    	nucleus=Nucleus(raw_code)

    	if startswith(raw_code, marker)
            push!(nuclei,nucleus)
        end

    end
	 nuclei
end

# ╔═╡ f3cd62b0-54cb-11eb-0419-ab20ac4b8c14
Documenter.showdoc(collectnuclei)

# ╔═╡ 4d1217b0-2fcb-11eb-0e90-75867c5e4cb2
#export
begin
"""
>loadscrubbednb(io, path)::Scrubbednb--> These are modification of the Pluto.load_notebook methods. Scrubs the notebook of all stuff but the code to be exported.
"""
function loadscrubbednb(io, path)::Scrubbednb
    collectedcells = []

	# ignore first bits of file
    readuntil(io,celliddelim)

    last_read = ""
    while !eof(io)
        cellidstr = String(readline(io))
        if cellidstr == "Cell order:"
            break
        else
            rawcode = String(readuntil(io, celliddelim))
            # change Windows line endings to Linux
            normalisedcode = replace(rawcode, "\r\n" => "\n")
            # remove the cell appendix
            code = normalisedcode[1:prevind(normalisedcode, end, length(cellsuff))]

            readcell = code
            push!(collectedcells, readcell)
        end
    end

	Scrubbednb(collectedcells)
end

function loadscrubbednb(path::String)::Scrubbednb
    local loaded
    open(path, "r") do io
        loaded = loadscrubbednb(io, path)
    end
    loaded
end
end

# ╔═╡ 3500e370-54d5-11eb-1944-c9b82c127615
Documenter.showdoc(loadscrubbednb)

# ╔═╡ 0b0aaa7e-2fd5-11eb-3b82-9165d56b4f63
#export
begin
"""
> loadnb(filename::String, marker::String)--> High level function which calls _load_nb
"""
loadnb(filename::String, marker::String) = _loadnb(filename, marker)

"""
> _load_nb(filename::String, marker::String)--> creates a scrubbed notebook and returns a curated Nb type having code to be exported.
"""
function _loadnb(fn::String, marker::String)
		scrubbednb=loadscrubbednb(fn)
		collectednuclei=nuclei(collectnuclei(scrubbednb, marker))
		Nb(collectednuclei, basename(fn))
end

end

# ╔═╡ 5463e720-54d6-11eb-2ffd-7922b7a75131
Documenter.showdoc(loadnb)

# ╔═╡ 7d58fad2-54d6-11eb-0297-d350524a3101
Documenter.showdoc(_loadnb)

# ╔═╡ d13f9ca0-1758-11eb-143b-29bccf950cae
testnb= loadnb("01_export.jl", "#export")

# ╔═╡ e229a820-1777-11eb-37c5-c108ab5f7110
#noop
@test testnb.nuclei[1].code == "#export\nimport Pluto: Notebook, Cell, load_notebook_nobackup"

# ╔═╡ 54f54160-176f-11eb-0317-3542cb72f89f
md"something to save files"

# ╔═╡ 35a01900-1771-11eb-01a7-39297caf95fd
#hide
k="01_export.jl"

# ╔═╡ 16a58460-54d7-11eb-1f6a-97f11bc07049
md"## strip
> strip --> Helper fucntion to replace a substring y in a string x with blank."

# ╔═╡ 4c511e5e-1771-11eb-3c8e-5785e7399d70
#export
"""
> strip --> Helper fucntion to replace a substring y in a string x with blank.
"""
strip=(x::String,y) -> replace(x, y=>"")

# ╔═╡ 55ed2102-597d-11eb-342c-b589f4681bdd
#hide
@doc strip

# ╔═╡ 526b7d10-54d7-11eb-20f1-5d26e020ff16
md"#### Example"

# ╔═╡ 8be444d7-406f-4dcd-a8ec-9d6e34435481
fn = "01_export.jl"

# ╔═╡ 7b999f90-1775-11eb-031e-69d461ec4150
#noop
@test uppercasefirst(strip(strip(fn, r"[0-9_]"), r".jl")) == "Export"

# ╔═╡ a0169477-e5ba-43bc-b86e-a377fa3b6e39
md"## savenb"

# ╔═╡ 76f97bd0-177b-11eb-2d78-77c72b2aef81
md"To export the required code, the following scenarios must be considered.

👉 Check if the file is in the src directory. If it's there then overwrite it.

👉 If it's not there then create and then write."

# ╔═╡ 6069d790-176f-11eb-3020-41b450d430ad
#export
begin
"""
> savenb(io, nb)--> Reads the supplied notebook and creates an io and writes stuffs like the module name and the content to the created io.
"""
function savenb(io, nb)
    println(io, header)
    println(io, subheader)
    println(io, "")
    println(io, "module $(uppercasefirst(strip(strip(nb.name, r"[0-9_]"), r".jl")))")
	for nucleus in nb.nuclei
			println(io, nucleus.code*"\n")
    end
	#notebook
	print(io, "end")
end

"""
> savenb(nb::Nb, path::String)--> Creates a file in the supplied path with the name in the NB type.
"""
function savenb(nb::Nb, srcdir::String)
	fn=uppercasefirst(strip(nb.name, r"[0-9_]"))
	open(joinpath(srcdir, fn), "w") do io
        savenb(io, nb)
    end
end
end

# ╔═╡ d096aed0-54d7-11eb-31fc-b19801db8851
Documenter.showdoc(savenb)

# ╔═╡ f7f0d72e-54d7-11eb-1b8a-b3689e09598b
md"## readfilenames"

# ╔═╡ cdada98e-0e13-11eb-30aa-1777efffb181
#export
begin
"""
> readfilenames(nbsdir::String)--> Reads files in the directory and subdirectories in the given path. Reads only the files with ".jl" extension
"""
function readfilenames(nbsdir::String)
	files=[]
	for file in readdir(nbsdir)
			if endswith(file, ".jl")
				push!(files,joinpath(nbsdir, file))
			end
	end
	files
end

end

# ╔═╡ 37ffeb40-54d8-11eb-0c8a-af262b2bec28
Documenter.showdoc(readfilenames)

# ╔═╡ 4259e9b0-54d8-11eb-3768-85ede85ab315
md"#### Example"

# ╔═╡ 3a378ca5-ff38-44ac-ba50-db48679b1eaa
expected_list = ["..\\nbs\\00_nbdev.jl"
"..\\nbs\\01_export.jl"
"..\\nbs\\02_documenter.jl"
"..\\nbs\\03_codeRunner.jl"
"..\\nbs\\04_makedocs.jl"
"..\\nbs\\05_make.jl"
"..\\nbs\\developerguide.jl"
"..\\nbs\\index.jl"
"..\\nbs\\styleguide.jl"
"..\\nbs\\tutorial.jl"]

# ╔═╡ 9b436180-177c-11eb-1c9a-ffbac62c95df
#noop
@test readfilenames(joinpath("..", "nbs")) == expected_list

# ╔═╡ 528689b0-54d8-11eb-35f4-2b56012fa4e6
md"## exportfile"

# ╔═╡ 0be54350-177c-11eb-285a-93dd4d45e40e
#export
"""
> exportfile(f::String, srcdir::String, marker::String)--> Loads the file in the supplied path and reads the cells which are marked with "#export". Then saves the notebook in the given path
"""
function exportfile(f::String, srcdir::String, marker::String)
	nb=loadnb(f, marker)
	if !isempty(nb.nuclei)
	    savenb(nb, srcdir)
	end
end

# ╔═╡ a89665f0-54d8-11eb-1e5a-fd409b238ce1
Documenter.showdoc(exportfile)

# ╔═╡ a0129641-9a52-497c-9b34-944250f655c6
md"## exportcontent"

# ╔═╡ 41d65310-0e11-11eb-1a36-87dc9ac941fa
#export
"""
> exportcontent(fns::AbstractVector, srcdir::String, marker::String)--> maps the `export_file` function to each files
"""
function exportcontent(fns::AbstractVector, srcdir::String, marker::String)
	map(f->exportfile(f, srcdir, marker), fns)
end

# ╔═╡ 1b57d6f0-54d9-11eb-0a0a-db4b2959750b
Documenter.showdoc(exportcontent)

# ╔═╡ 23e775a0-54d9-11eb-0106-431100572909
md"## getfileextension"

# ╔═╡ 01608690-0e14-11eb-3faa-9b960f57f3fe
#export
"""
> getfileextension(fn)--> get the file extensions in the pwd
"""
function getfileextension(fn)
    return fn[findlast(isequal('.'),fn):end]
end

# ╔═╡ 3b2578c0-54d9-11eb-00a0-595ad6034cfa
Documenter.showdoc(getfileextension)

# ╔═╡ 44fa41a0-54d9-11eb-1cc1-bf7ce7d30abf
md"#### Example"

# ╔═╡ 06649ce0-177d-11eb-2092-d7160725252a
#noop
 @test getfileextension("test.jl") == ".jl"

# ╔═╡ 4de0d9f0-54d9-11eb-38c6-3de69a7ec1db
md"## notebook2script"

# ╔═╡ b34f9d82-0ede-11eb-0f08-afa0cc898e80
#export
"""
> notebook2script(nbsdir::String, srcdir::String)--> Export all the code from the provided notebook directory to the given source directory
"""
function notebook2script(nbsdir::String, srcdir::String)
	exportcontent(readfilenames(nbsdir), srcdir, "#export")
end

# ╔═╡ 822b3787-f4ec-4edf-bd8d-7469c9ccc8bf
#export
export notebook2script

# ╔═╡ 730bc63e-54d9-11eb-1489-39a31e9b0deb
Documenter.showdoc(notebook2script)

# ╔═╡ 7a9391e0-54d9-11eb-14f1-7f8e10036a1a
md"`notebook2script` can be called from a notebook which you intend to export. Usually in the last cell of that notebook"

# ╔═╡ baf3f1d0-0ede-11eb-2c02-1f53ed1a6cd7
notebook2script(joinpath("..", "nbs"), joinpath("..", "src"))

# ╔═╡ Cell order:
# ╠═486bb5f0-54be-11eb-0e7c-1dcf55b5f983
# ╠═5b4e526e-3dfa-11eb-3472-bd753d60c119
# ╠═5bb30a64-043e-4ad0-9d60-3d470d22fd8f
# ╠═0aecd4c0-0e14-11eb-1619-4f5e0ced1279
# ╠═5b3f2908-4bcf-4dea-b59b-e54a5f11f7b5
# ╠═2181580b-7f3e-456f-aa62-68130d9b9178
# ╠═1cfdfbea-3ef7-4a38-b42b-8610d0f90646
# ╠═822b3787-f4ec-4edf-bd8d-7469c9ccc8bf
# ╠═6ff1ad80-1479-11eb-3868-0df000f47cc9
# ╠═16fbf5b0-54bf-11eb-3c21-2bf024188fac
# ╠═a5bfff40-1620-11eb-2824-2d49985a022d
# ╠═ad64c040-54bf-11eb-2c3d-ff1de3c15f3f
# ╠═1d983360-54c0-11eb-0104-672aaffbbb95
# ╠═cc7be350-54bf-11eb-2107-335896e7fbf3
# ╠═d38222e0-54bf-11eb-309a-2722b3e78bbc
# ╠═f1eadd80-54bf-11eb-1de4-ef2da2e36eda
# ╠═0361d7d0-54c0-11eb-0a50-79dc00a9d848
# ╠═d236da00-54c6-11eb-3afe-859ccc31d041
# ╠═d17ebf90-1486-11eb-0d41-b967a8ab82ba
# ╠═117932c0-54c8-11eb-158c-5be86ba8fd19
# ╠═65163a40-54c8-11eb-3384-61a1dce37c10
# ╠═6d8afdf0-54c8-11eb-27e5-d59d375bd9eb
# ╠═93dc68e0-54c8-11eb-0b28-eb809c1f15a6
# ╠═772778c0-54c8-11eb-3b23-01d2dc0c5dc0
# ╠═8e253e90-54c8-11eb-3456-97a428b1f232
# ╠═020a9620-54c9-11eb-107e-c107354dc90a
# ╠═cf50547e-54c9-11eb-132d-894c0cfe9ccc
# ╠═99fd66a0-54ca-11eb-3d11-d92049fd2f6a
# ╠═296282f0-1770-11eb-0900-b37a94fbc69c
# ╠═d4daaac0-0eb2-11eb-1d4d-7763fcfc0ed2
# ╠═f3cd62b0-54cb-11eb-0419-ab20ac4b8c14
# ╠═2a36f0b0-54cb-11eb-1b53-0998e776d5a5
# ╠═773b9da0-2fd4-11eb-1c65-a10ea8672725
# ╠═6bfde500-2fcb-11eb-2b73-7ddce97351d3
# ╠═0561b9f0-54d5-11eb-01f0-8bde739e3e37
# ╠═4d1217b0-2fcb-11eb-0e90-75867c5e4cb2
# ╠═3500e370-54d5-11eb-1944-c9b82c127615
# ╠═512e7b20-54d5-11eb-3ff9-b150bf2f9e26
# ╠═12377150-54d6-11eb-18ff-ef441154f771
# ╠═c71b1460-54d5-11eb-3e6b-cb3dadbc0349
# ╠═0b0aaa7e-2fd5-11eb-3b82-9165d56b4f63
# ╠═5463e720-54d6-11eb-2ffd-7922b7a75131
# ╠═7d58fad2-54d6-11eb-0297-d350524a3101
# ╠═8b7e8030-54d6-11eb-2f48-d3bc02e21c96
# ╠═20c285d0-2fb4-11eb-1ef0-3b28829af7e8
# ╠═d13f9ca0-1758-11eb-143b-29bccf950cae
# ╠═e229a820-1777-11eb-37c5-c108ab5f7110
# ╟─54f54160-176f-11eb-0317-3542cb72f89f
# ╠═35a01900-1771-11eb-01a7-39297caf95fd
# ╠═16a58460-54d7-11eb-1f6a-97f11bc07049
# ╠═4c511e5e-1771-11eb-3c8e-5785e7399d70
# ╠═55ed2102-597d-11eb-342c-b589f4681bdd
# ╠═526b7d10-54d7-11eb-20f1-5d26e020ff16
# ╠═8be444d7-406f-4dcd-a8ec-9d6e34435481
# ╠═7b999f90-1775-11eb-031e-69d461ec4150
# ╠═a0169477-e5ba-43bc-b86e-a377fa3b6e39
# ╠═76f97bd0-177b-11eb-2d78-77c72b2aef81
# ╠═6069d790-176f-11eb-3020-41b450d430ad
# ╠═d096aed0-54d7-11eb-31fc-b19801db8851
# ╠═f7f0d72e-54d7-11eb-1b8a-b3689e09598b
# ╠═cdada98e-0e13-11eb-30aa-1777efffb181
# ╠═37ffeb40-54d8-11eb-0c8a-af262b2bec28
# ╠═4259e9b0-54d8-11eb-3768-85ede85ab315
# ╠═3a378ca5-ff38-44ac-ba50-db48679b1eaa
# ╠═9b436180-177c-11eb-1c9a-ffbac62c95df
# ╠═528689b0-54d8-11eb-35f4-2b56012fa4e6
# ╠═0be54350-177c-11eb-285a-93dd4d45e40e
# ╠═a89665f0-54d8-11eb-1e5a-fd409b238ce1
# ╠═a0129641-9a52-497c-9b34-944250f655c6
# ╠═41d65310-0e11-11eb-1a36-87dc9ac941fa
# ╠═1b57d6f0-54d9-11eb-0a0a-db4b2959750b
# ╠═23e775a0-54d9-11eb-0106-431100572909
# ╠═01608690-0e14-11eb-3faa-9b960f57f3fe
# ╠═3b2578c0-54d9-11eb-00a0-595ad6034cfa
# ╠═44fa41a0-54d9-11eb-1cc1-bf7ce7d30abf
# ╠═06649ce0-177d-11eb-2092-d7160725252a
# ╠═4de0d9f0-54d9-11eb-38c6-3de69a7ec1db
# ╠═b34f9d82-0ede-11eb-0f08-afa0cc898e80
# ╠═730bc63e-54d9-11eb-1489-39a31e9b0deb
# ╠═7a9391e0-54d9-11eb-14f1-7f8e10036a1a
# ╠═baf3f1d0-0ede-11eb-2c02-1f53ed1a6cd7

ext: jl


text:
#TODO add unit tests

@testset "test opf minimum cost" begin
    file =  "../test/data/matpower/case5.m"
    data = PMs.parse_file(file)
    result = PMPP.run_ac_opf_cost(data, ipopt_solver)
    @test result["termination_status"] == PMs.LOCALLY_SOLVED
    @test isapprox(result["objective"], 18269.1; atol = 1e-1)
end

@testset "test opf minimum losses" begin
    file =  "../test/data/matpower/case5.m"
    data = PMs.parse_file(file)
    result = PMPP.run_ac_opf_loss(data, ipopt_solver)
    @test result["termination_status"] == PMs.LOCALLY_SOLVED
    @test isapprox(result["objective"], 0.0280012; atol = 1e-3)
end

# test-branch-MD


text:
module PIEMetData

using TidalFluxConfigurations, DataFrames, CSV, Base.Dates

export parsemet

const metdatatypes = [Date, # Date
                      String, # Time
                      Int, # Julian day
                      Union{Missings.Missing,Float64}, # Precip
                      Float64, # Pyranometer
                      Float64, # PAR
                      Float64, # Temp
                      Float64, # RH
                      Float64, # Wind
                      Float64, # WindDir
                      Float64, # P
                      ]

function parsemet(year::Int,metdatadir=TidalFluxConfigurations.config[:_METDATA_DIR])
    ys = parse.(readdir(metdatadir))
    in(year,ys) || error("met data requested for unavailable year: $year")

    M = CSV.read(joinpath(TidalFluxConfigurations.config[:_METDATA_DIR],string(year),"met.csv"),
                 types=metdatatypes,
                 dateformat=DateFormat("dd-uuu-yyyy"))
    t = lpad.(M[:Time],5,"0") # Pad the time with zeros
    M[:DateTime] = DateTime(Dates.format(M[:Date],DateFormat("yyyy-mm-dd")).*"T".*t) # Combine Date and Time
    q = t.=="00:00"
    M[:DateTime] .+= Day.(q)
    rename!(M,[:BAR => :P;
               :Wind => :WindSpeed
               ])
    M
end

end # module


text:
"""
File to parse QNetwork with other graph types
"""

import SparseArrays:dropzeros!

"""
Remove both directions of the SimpleWeightedGraph edge properly as opposed
to just setting it to zero.
"""
function hard_rem_edge!(graph::SimpleWeightedDiGraph, src::Int64, dst::Int64)
    rem_edge!(graph, src, dst)
    rem_edge!(graph, dst, src)
    dropzeros!(graph.weights)
end

"""
Convert a path specifying node ints to a list of SimpleEdges
"""
function int_to_simpleedge(path::Vector{Tuple{Int, Int}})
    new_path = []
    for edge in path
        new_edge = LightGraphs.SimpleEdge(edge[1], edge[2])
        push!(new_path, new_edge)
    end
    return new_path
end

"""
Convert a path of SimpleEdges into a list of Int tuples
"""
function simpleedge_to_int(path::Vector{LightGraphs.SimpleGraphs.SimpleEdge{Int64}})
    new_path = []
    for edge in path
        new_edge = (edge.src, edge.dst)
        push!(new_path, new_edge)
    end
    return new_path
end

max_stars_repo_name: FalafelGood/QuNet

max_issues_repo_name: FalafelGood/QuNet

max_forks_repo_name: FalafelGood/QuNet


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

function GitHash(ptr::Ptr{UInt8})
    if ptr == C_NULL
        throw(ArgumentError("NULL pointer passed to GitHash() constructor"))
    end
    oid_ptr = Ref(GitHash())
    ccall((:git_oid_fromraw, :libgit2), Void, (Ptr{GitHash}, Ptr{UInt8}), oid_ptr, ptr)
    return oid_ptr[]
end

function GitHash(id::Array{UInt8,1})
    if length(id) != OID_RAWSZ
        throw(ArgumentError("invalid raw buffer size"))
    end
    return GitHash(pointer(id))
end

function GitHash(id::AbstractString)
    bstr = String(id)
    len = sizeof(bstr)
    if len < OID_HEXSZ
        throw(ArgumentError("Input string is too short, use `GitShortHash` for partial hashes"))
    end
    oid_ptr = Ref{GitHash}()
    @check ccall((:git_oid_fromstrn, :libgit2), Cint,
              (Ptr{GitHash}, Ptr{UInt8}, Csize_t), oid_ptr, bstr, len)
    return oid_ptr[]
end
function GitShortHash(id::AbstractString)
    bstr = String(id)
    len = sizeof(bstr)
    oid_ptr = Ref{GitHash}()
    @check ccall((:git_oid_fromstrn, :libgit2), Cint,
              (Ptr{GitHash}, Ptr{UInt8}, Csize_t), oid_ptr, bstr, len)
    GitShortHash(oid_ptr[], len)
end

macro githash_str(id)
    bstr = String(id)
    if sizeof(bstr) < OID_HEXSZ
        GitShortHash(id)
    else
        GitHash(id)
    end
end
function GitHash(ref::GitReference)
    isempty(ref) && return GitHash()
    reftype(ref) != Consts.REF_OID && return GitHash()
    oid_ptr = ccall((:git_reference_target, :libgit2), Ptr{UInt8}, (Ptr{Void},), ref.ptr)
    oid_ptr == C_NULL && return GitHash()
    return GitHash(oid_ptr)
end

function GitHash(repo::GitRepo, ref_name::AbstractString)
    isempty(repo) && return GitHash()
    oid_ptr  = Ref(GitHash())
    @check ccall((:git_reference_name_to_id, :libgit2), Cint,
                    (Ptr{GitHash}, Ptr{Void}, Cstring),
                     oid_ptr, repo.ptr, ref_name)
    return oid_ptr[]
end

function GitHash(obj::GitObject)
    GitHash(ccall((:git_object_id, :libgit2), Ptr{UInt8}, (Ptr{Void},), obj.ptr))
end

Base.hex(id::GitHash) = join([hex(i,2) for i in id.val])
Base.hex(id::GitShortHash) = hex(id.hash)[1:id.len]

raw(id::GitHash) = collect(id.val)

Base.string(id::AbstractGitHash) = hex(id)

Base.show(io::IO, id::GitHash) = print(io, "GitHash(\"$(string(id))\")")
Base.show(io::IO, id::GitShortHash) = print(io, "GitShortHash(\"$(string(id))\")")

Base.hash(id::GitHash, h::UInt) = hash(id.val, h)

function Base.cmp(id1::GitHash, id2::GitHash)
    Int(ccall((:git_oid_cmp, :libgit2), Cint,
              (Ptr{GitHash}, Ptr{GitHash}),
              Ref(id1), Ref(id2)))
end
function Base.cmp(id1::GitShortHash, id2::GitShortHash)
    # shortened hashes appear at the beginning of the order, i.e.
    # 000 < 01 < 010 < 011 < 0112
    c = Int(ccall((:git_oid_ncmp, :libgit2), Cint,
                  (Ptr{GitHash}, Ptr{GitHash}, Csize_t),
                  Ref(id1.hash), Ref(id2.hash), min(id1.len, id2.len)))
    return c == 0 ? cmp(id1.len, id2.len) : c
end
Base.cmp(id1::GitHash, id2::GitShortHash) = cmp(GitShortHash(id1, OID_HEXSZ), id2)
Base.cmp(id1::GitShortHash, id2::GitHash) = cmp(id1, GitShortHash(id2, OID_HEXSZ))

==(id1::GitHash, id2::GitHash) = cmp(id1, id2) == 0
Base.isless(id1::AbstractGitHash, id2::AbstractGitHash)  = cmp(id1, id2) < 0

function iszero(id::GitHash)
    for i in 1:OID_RAWSZ
        id.val[i] != zero(UInt8) && return false
    end
    return true
end

Base.zero(::Type{GitHash}) = GitHash()


text:
function divide(tree::Tree,
                objs::Vector{O},
                bboxes::Vector{AABB{T}},
                centroids::Vector{SVector{3,T}},
                indices::Vector{I},
                selection::UR,
                axis::I) where {T<:AbstractFloat,Tree<:AbstractTree{T},
                                O<:Intersectable{T},
                                I<:Integer,UR<:AbstractUnitRange{I}}
    # Calculate bbox encompassing all objects
    bbox = AABB(view(bboxes, selection))

    # A better SAH is needed
    length(selection) <= 2 && return add_leaf_node!(tree, view(objs, selection), bbox)

    sort!(view(indices, selection), by = i -> centroids[i][axis])
    m = round(I, mean(selection))

    (axis += 1) == 4 && (axis = 1)

    left = divide(tree, objs, bboxes, centroids, indices, selection[1]:m, axis)
    right = divide(tree, objs, bboxes, centroids, indices, m+1:selection[end], axis)

    add_binary_node!(tree, left, right)
end

function bvh_simple_build(::Type{Tree}, objs::Vector{O}) where {T<:AbstractFloat,Tree<:AbstractTree,O<:Intersectable{T}}
    tree = Tree{O}()
    bboxes = map(aabb, objs)
    centroids = map(center, bboxes)
    root = tree[divide(tree, objs, bboxes, centroids,
                       collect(eachindex(objs)), eachindex(objs), 1)]
    BVH(tree, root)
end

export bvh_simple_build


text:
include("common.jl")

macro include_testset(filename)
    @assert filename isa AbstractString
    quote
        @testset $(filename) begin
            include($(filename))
        end
    end
end

####
#### unit tests
####

#@include_testset("test-theta.jl")
#@include_testset("test-weierstrass.jl")
@include_testset("test-symbolic.jl")


text:
using Random
using TropicalTensors
using DelimitedFiles
using CuYao, CUDA
CUDA.device!(parse(Int, ARGS[1]))

function random_degeneracy(::Type{T}, lt; usecuda) where T
    sg = Spinglass(lt, rand(T[-1,1],length(sgbonds(lt))), zeros(T, length(lt)))
    res = solve(CountingTropical{T,T}, sg; usecuda=usecuda)
    return res.n, res.c
end

function main(::Type{T}, ::Type{LT}, Llist, nrepeat::Int; usecuda=false) where {T, LT}
    println("The number of repetition is $nrepeat.")
    for (i, L) in enumerate(Llist)
        lt = LT(L, L)
        out = zeros(T, nrepeat, 2)
        for j = 1:nrepeat
            println("L=$L, $j")
            @time out[j,:] .= random_degeneracy(T, lt; usecuda=usecuda)
        end
        fname = joinpath(@__DIR__, "$(name(LT))_degeneracy_L$L.dat")
        writedlm(fname, out)
    end
end

name(::Type{<:ChimeraLattice}) = "chimera"
name(::Type{<:SquareLattice}) = "square"
name(::Type{<:Cylinder}) = "cylinder"

if abspath(PROGRAM_FILE) == @__FILE__
    Random.seed!(2)
    nrepeat = 100
    L = parse(Int, ARGS[2])
    main(Float32, Cylinder, [L], nrepeat; usecuda=true)
end


text:
using Markdown
using InteractiveUtils

using Pkg
Pkg.activate("/global/u2/a/aramreye/RamirezReyes_Yang_2020_SpontaneousCyclogenesis")
using PyPlot
using PyCall
using Base64
using Printf
using Statistics
using AvailablePotentialEnergyFramework
using DelimitedFiles

file_control = "/global/homes/a/aramreye/SAM_model/SAM6.10.6/exp/f5e-4_2km_1000km_control/init_snd/snd300"
file_ensemble1 = "/global/homes/a/aramreye/SAM_model/SAM6.10.6/exp/f5e-4_2km_1000km_control_ensemble1/init_snd/snd300"
file_ensemble2 = "/global/homes/a/aramreye/SAM_model/SAM6.10.6/exp/f5e-4_2km_1000km_control_ensemble2/init_snd/snd300"

profile_control = readdlm(file_control;header=true,skipstart=1)[1][1:56,2:4]
profile_ensemble1= readdlm(file_ensemble1;header=true,skipstart=1)[1][1:56,2:4]
profile_ensemble2 = readdlm(file_ensemble2;header=true,skipstart=1)[1][1:56,2:4]

profile_enseble1_modified = copy(profile_ensemble1)

PyPlot.matplotlib.rc("font", family="sans-serif",size=8)

fig, ax = plt.subplots(1,2,sharey=true,figsize=(3,4),dpi=400)

ax[1].plot(profile_control[:,2],profile_control[:,1],ls)
ax[1].plot(profile_ensemble1[:,2],profile_ensemble1[:,1])
ax[1].plot(profile_ensemble2[:,2],profile_ensemble2[:,1])
ax[1].invert_yaxis()
ax[1].set_ylabel(string("Pressure ",L"(hPa)"))
ax[1].set_xlabel(string("Potential Temperature ",L"(K)"))
ax[2].plot(profile_control[:,3],profile_control[:,1])
ax[2].plot(profile_ensemble1[:,3],profile_ensemble1[:,1])
ax[2].plot(profile_ensemble2[:,3],profile_ensemble2[:,1])
ax[2].set_ylabel(string("Specific humidiy ",L"(g/kg)"))
plt.tight_layout()


text:
using FastTransforms, LinearAlgebra, Test

import FastTransforms: chebyshevmoments1, chebyshevmoments2,
                       chebyshevjacobimoments1, chebyshevjacobimoments2,
                       chebyshevlogmoments1, chebyshevlogmoments2

@testset "Fejér and Clenshaw–Curtis quadrature" begin
    N = 20
    f = x -> exp(x)

    x = clenshawcurtisnodes(Float64, N)
    μ = chebyshevmoments1(Float64, N)
    w = clenshawcurtisweights(μ)
    @test norm(dot(f.(x), w)-2sinh(1)) ≤ 4eps()

    μ = chebyshevjacobimoments1(Float64, N, 0.25, 0.35)
    w = clenshawcurtisweights(μ)
    @test norm(dot(f.(x), w)-2.0351088204147243) ≤ 4eps()

    μ = chebyshevlogmoments1(Float64, N)
    w = clenshawcurtisweights(μ)
    @test norm(sum(w./(x .- 3)) - π^2/12) ≤ 4eps()

    x = fejernodes1(Float64, N)
    μ = chebyshevmoments1(Float64, N)
    w = fejerweights1(μ)
    @test norm(dot(f.(x), w)-2sinh(1)) ≤ 4eps()

    μ = chebyshevjacobimoments1(Float64, N, 0.25, 0.35)
    w = fejerweights1(μ)
    @test norm(dot(f.(x), w)-2.0351088204147243) ≤ 4eps()

    μ = chebyshevlogmoments1(Float64, N)
    w = fejerweights1(μ)
    @test norm(sum(w./(x .- 3)) - π^2/12) ≤ 4eps()

    x = fejernodes2(Float64, N)
    μ = chebyshevmoments2(Float64, N)
    w = fejerweights2(μ)
    @test norm(dot(f.(x), w)-2sinh(1)) ≤ 4eps()

    μ = chebyshevjacobimoments2(Float64, N, 0.25, 0.35)
    w = fejerweights2(μ)
    @test norm(dot(f.(x), w)-2.0351088204147243) ≤ 4eps()

    μ = chebyshevlogmoments2(Float64, N)
    w = fejerweights2(μ)
    @test norm(sum(w./(x .- 3)) - π^2/12) ≤ 4eps()
end


text:
#####################
###### Modules ######
#####################

# The recommended style is not to indent the body of the module, since that would typically lead to
# whole files being indented. Also, it is common to use UpperCamelCase for module names (just like types),
# and use the plural form if applicable, especially if the module contains a similarly named identifier,
# to avoid name clashes.

module SomeModule

include("file1.jl")
include("file2.jl")

end

# Export lists

module NiceStuff

export nice, DOG

struct Dog end      # singleton type, not exported

const DOG = Dog()   # named instance, exported

nice(x) = "nice $x" # function, exported

end

# A module can have multiple export statements in arbitrary locations.

# Standalone using and import

using NiceStuff

# Would load the above code, making NiceStuff (the module name), DOG and nice available.
# Dog is not on the export list, but it can be accessed if the name is qualified with the module path
# (which here is just the module name) as NiceStuff.Dog.

# Importantly, using ModuleName is the only form for which export lists matter at all.

import NiceStuff

# brings only the module name into scope. Users would need to use NiceStuff.DOG, NiceStuff.Dog,
# and NiceStuff.nice to access its contents.

max_stars_repo_name: mauricioriva/learn-julia

max_issues_repo_name: mauricioriva/learn-julia

max_forks_repo_name: mauricioriva/learn-julia


text:
# add more julia processes
nprocs() < 4 ? addprocs(4-nprocs()) : nothing

using IncrementalInference
using HDF5, JLD, Gadfly, Colors, Cairo
using KernelDensityEstimate, Distributions
using Caesar, RoME
using RoMEPlotting
using DocStringExtensions
using ArgParse

## load all the model data
# d = odometry information
# f = laser scanner detections
# MM = multi-modal individual id references
# MMr = reworked to map to only one previous feature
# examplefolder, datafolder

include(joinpath(Pkg.dir("Caesar"),"examples","wheeled","loadVicPrkData.jl"))

# include(joinpath(ENV["HOME"],"Documents","blandauthlocal.jl"))
# backend_config, user_config = standardcloudgraphsetup(addrdict=addrdict)
# # Start new session
# addrdict["sessionId"] = "VICPRK_VID"
# addrdict["robotId"] = "Ute"
# fg = initfg(sessionname=user_config["sessionId"], robotname=user_config["robotId"], cloudgraph=backend_config)
# deleteServerSession!(fg.cg, user_config["sessionId"])

include(joinpath(Pkg.dir("Caesar"),"examples","wheeled","VicPrk_FrontEndUtils.jl"))

# run using local inference
function mainrun(dd,ff; frames=3, coord=Coord.Cartesian(xmin=-100,xmax=100,ymin=-150,ymax=50))

    currdirtime = now()
    imgdir = joinpath(ENV["HOME"], "Pictures", "vicprkimgs", "$(currdirtime)")
    mkdir(imgdir)

    ddd = deepcopy(dd)
    fff = deepcopy(ff)

    PL = Dict{Int, Any}()

    Podo=diagm([0.5;0.5;0.005])
    lsrNoise=diagm([0.1;1.0])

    # start factor graph
    N=75
    fg = initfg()
    lmoccur = Dict{Symbol, Int}()

    # init pose
    prevn = initFactorGraph!(fg, init=ddd[1][1:3])[1]

    findAddNewLandmarks!(fg, lmoccur, fff[1])
    # there might not be any landmarks yet
    findAddLandmFactorsByPose!(fg, :x0, fff[1], N=N)
    tree = wipeBuildNewTree!(fg, drawpdf=true)
    inferOverTree!(fg, tree, N=N)
    PL[1] = drawPoses(fg)
    Gadfly.draw(PDF(imgdir*"/x1.pdf", 30cm,20cm),PL[1])
    Gadfly.draw(PNG(imgdir*"/x1.png", 30cm,20cm),PL[1])

    for i in 2:frames
      PL[i] = donextframe!(fg, i, ddd, fff, lmoccur, Podo, N=N)
      PL[i].coord = coord
      Gadfly.draw(PDF(imgdir*"/x$(i).pdf", 30cm,20cm),PL[i])
      Gadfly.draw(PNG(imgdir*"/x$(i).png", 30cm,20cm),PL[i])
    end
    PL
end

# @async run('evince bt.pdf')
PL = mainrun(d,f; frames=40)

#


text:
typealias SceneRecord QueueRecord{Vehicle}
SceneRecord(capacity::Int, timestep::Float64, frame_capacity::Int=100) = QueueRecord(Vehicle, capacity, timestep, frame_capacity)
Base.show(io::IO, rec::SceneRecord) = print(io, "SceneRecord(nscenes=", nframes(rec), ")")


text:
# RNN:

@polly function rnn_forward(nt,np,ns,nq,out_F,s_F,inp_F,U,W,V)

	for t=1:nt
		for r=1:ns
			for p=1:np
				s_F[t,r] += U[r,p] * inp_F[t,p]
			end

			if t>1
				for s=1:ns
					s_F[t,r] += W[r,s] * s_F[t-1,s]
				end
			end
		end

		for q=1:nq
			for r=1:ns
				out_F[t,q] +=V[q,r] * s_F[t,r]
			end
		end
	end
end

@polly function rnn_backward(nt,np,ns,nq,bt,inp_F,s_F,W,V,err_out,del_U,del_W,del_V,del_TA,del_TB)

	for t=nt:-1:1
		for q=1:nq, s=1:ns
				del_V[q,s] = err_out[t,q] * s_F[t,s]
		end

		for s=1:ns
			del_TA[s] = Float32(0.0)
			for q=1:nq
				del_TA[s] += V[q,s] * err_out[t,q]
			end
		end

		for step=t+1:-1:max(0,t-bt)
			if step > 1
				for r=1:nr, s=1:ns
					del_W[r,s] +=del_TA[r] * s_F[step-1,s]
				end
			end

			for s=1:ns, p=1:np
				del_U[s,p] += del_TA[s] * inp_F[step,p]
			end

			for r=1:ns
				del_TB[r] = Float32(0.0)
				for s=1:ns
					del_TB[r] +=del_TA[s] * W[s,r]
				end
			end

			for r=1:ns
				del_TA[r] = del_TB[r]
			end
		end # step
	end # t
end

let
	nt = 100
	np = 200
	nq = 250
	ns = 310
	bt = 3

	out_F = zeros(Float32,nt,nq)
	s_F = zeros(Float32,nt,ns)
	inp_F = zeros(Float32,nt,np)
	U = zeros(Float32,ns,np)
	W = zeros(Float32,ns,ns)
	V = zeros(Float32,nq,ns)
	err_out = zeros(Float32,nt,nq)
	del_U = zeros(Float32,ns,np)
	del_W = zeros(Float32,ns,ns)
	del_V = zeros(Float32,nq,ns)
	del_TA = zeros(Float32,ns)
	del_TB = zeros(Float32,ns)

	#init_array
	for a=1:nt, b=1:nq
		out_F[a,b] = Float32((a*b)%nq) / nq
		err_out[a,b] = Float32((a*(b+1))%nq) / nq
	end

	for a=1:nt, b=1:ns
		s_F[a,b] = Float32((a*b)%nt) / nt
	end

	for a=1:nt, b=1:np
		inp_F[a,b] = Float32((a*b)%np) / np
	end

	for a=1:ns
		for b=1:np
			U[a,b] = Float32((a*b)%nt) / nt
			del_U[a,b] = Float32(((a+1)*(b+1))%nt) / nt
		end
		for b=1:ns
			W[a,b] = Float32((a*b)%ns) / ns
			del_W[a,b] = Float32(((a+1)*(b+1))%nt) / nt
		end
	end

	for a=1:nq, b=1:ns
		V[a,b] = Float32(((a+1)*b)%nq) / nq
		del_V[a,b] = Float32(((a+1)*(b+1))%nt) / nt
	end

	if length(ARGS)==0 || ARGS[1]=="forward"
		print("Forward pass loaded")
		SUITE["rnn"] = @benchmarkable rnn_forward($nt,$np,$ns,$nq, out_F, s_F, inp_F, U, W, V) setup = (inp_F=copy($inp_F); out_F=copy($out_F); s_F=copy($s_F); U = copy($U); W = copy($W); V = copy($V); err_out=copy($err_out); del_U=copy($del_U); del_W=copy($del_W); del_V=copy($del_V); del_TA=copy($del_TA); del_TB=copy($del_TB))
	else
		print("Backward pass loaded")
		SUITE["rnn"] = @benchmarkable rnn_backward($nt,$np,$ns,$nq,$bt, inp_F, s_F, W, V, del_U, del_W, del_V, del_TA, del_TB) setup = (inp_F=copy($inp_F); out_F=copy($out_F); s_F=copy($s_F); U = copy($U); W = copy($W); V = copy($V); err_out=copy($err_out); del_U=copy($del_U); del_W=copy($del_W); del_V=copy($del_V); del_TA=copy($del_TA); del_TB=copy($del_TB))
	end
end

max_stars_repo_name: akileshbadrinaaraayanan/IITH

max_issues_repo_name: akileshbadrinaaraayanan/IITH

max_forks_repo_name: akileshbadrinaaraayanan/IITH


text:
@benchset "mean" begin
    @benchset "ZeroMean{Float64}()" create_benchmarks(ZeroMean{Float64}(); grads=false)
    @benchset "OneMean()" create_benchmarks(OneMean(); grads=false)
    @benchset "CustomMean(sin)" create_benchmarks(CustomMean(sin))
    @benchset "CustomMean(cos)" create_benchmarks(CustomMean(cos))
    @benchset "sin + cos" create_benchmarks(CustomMean(sin) + CustomMean(cos))
    @benchset "5 * CustomMean(sin)" create_benchmarks(5.0 * CustomMean(sin))
end


text:
"""
    Glyph <: AbstractArray{Bool,2}

Holds the bitmap associated to a Unifont glyph in a packed format.
"""
struct Glyph <: AbstractArray{Bool,2}
    data::Matrix{UInt8}
end

Base.size(A::Glyph) = (size(A.data, 1), size(A.data, 2) * 8)

function Base.getindex(A::Glyph, i::Int, j::Int)
    block = A.data[i, cld(j, 8)]
    k = (j - 1) % 8
    Bool((block >> k) & 1)
end

Base.hcat(a::Glyph, b::Glyph) = Glyph(hcat(a.data, b.data))

# https://discourse.julialang.org/t/convert-integer-to-bits-array/26663/7
function revbits(z::UInt8)
    z = (((z & 0xaa) >> 1) | ((z & 0x55) << 1))
    z = (((z & 0xcc) >> 2) | ((z & 0x33) << 2))
    z = (((z & 0xf0) >> 4) | ((z & 0x0f) << 4))
    return z
end

"""
    glyph!(v::Vector{UInt8}) -> Glyph

Creates a [`Glyph`](@ref) for a vector of bytes, assuming the vector represents a single Unifont character. Modifies `v` and may share its memory.
"""
function glyph!(v::Vector{UInt8})
    v .= revbits.(v)
    if length(v) == 16
        Glyph(reshape(v, 16, 1))
    elseif length(v) == 32
        Glyph(transpose(reshape(v, 2, 16)))
    else
        throw(ArgumentError("Input vector must have length 16 or 32, corresponding to a single character."))
    end
end

const UNIFONT_LOOKUP = let file = readdlm(joinpath(@__DIR__, "..", "data",
                                                   "unifont-12.1.04.hex"), ':', String)
    Dict{String,String}(r[1] => r[2] for r in eachrow(file))
end

const GLYPH_CHAR_CACHE = Dict{Char,Glyph}()

function key(c::Char)
    u = codepoint(c)
    return uppercase(string(u, base=16, pad=u ≤ 0xffff ? 4 : 6))
end

function get_char(k::AbstractString)
    Char(parse(UInt16, "0x$k"))
end

function Glyph(c::Char)
    get!(GLYPH_CHAR_CACHE, c) do
        k = key(c)
        haskey(UNIFONT_LOOKUP, k) || error("UNIFONT doesn't know how to render `c`.")
        return glyph!(hex2bytes(UNIFONT_LOOKUP[k]))
    end
end

"""
    Glyph(s::AbstractString) --> Glyph

Construct a `Glyph` from a string.

# Examples

```julia-repl
julia> Glyph("abc")
------------------------
------------------------
------------------------
---------#--------------
---------#--------------
---------#--------------
--####---#-###----####--
-#----#--##---#--#----#-
------#--#----#--#------
--#####--#----#--#------
-#----#--#----#--#------
-#----#--#----#--#------
-#---##--##---#--#----#-
--###-#--#-###----####--
------------------------
------------------------
```
"""
function Glyph(s::AbstractString)
    foldl(hcat, (Glyph(c) for c in s))
end

"""
    printglyph([io=stdout], g::Union{Char, AbstractString, Glyph})

Prints a visual representation of `g` to `io`.
"""
function printglyph end

function printglyph(io::IO, g::Glyph; symbols=("#", " "))
    rep = s -> s ? symbols[1] : symbols[2]
    for r in eachrow(g)
        println(io, mapreduce(rep, *, r))
    end
end

printglyph(g; kwargs...) = printglyph(stdout, g; kwargs...)
printglyph(io::IO, s::Union{Char, AbstractString}; kwargs...) = printglyph(io, Glyph(s); kwargs...)
printglyph(s::Union{Char, AbstractString}; kwargs...) = printglyph(stdout, s; kwargs...)

# Base.show(io::IO, ::MIME"text/plain", g::Glyph) = printglyph(io, g)
# Base.show(io::IO, g::Glyph) = printglyph(io, g)


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

using Markdown
using InteractiveUtils

# ╔═╡ 51a61cd4-185c-11ec-0a43-4517c063bc43
begin
	using LinearAlgebra
	using Random; Random.seed!()
	using DelimitedFiles
	using Plots
	"packages"
end

# ╔═╡ 0520406d-2b17-427d-a830-c563a191a816
md"""
Conformal transform h and h1
"""

# ╔═╡ c27ab801-37a4-4174-9c7d-623c08f63203
begin
	arg = [i for i in range(0,2π, length=100)]
	circle_x = [cos(i) for i in arg]
	circle_y = [sin(i) for i in arg]
	"circle r = 1"
end

# ╔═╡ d2f19b71-1947-4197-a00c-4d90df01fd96
md"""
###  Check θ(z)
"""

# ╔═╡ b71809a2-fc70-438c-8205-60dce946131f
md"""
#### delta function
"""

# ╔═╡ 0d7c7bef-170e-46e1-907f-9b2a8e60bd91
begin
	function eye(n::Int64)
		res = zeros(n,n)
		for i = 1:n res[i,i] = 1.0 end
		return res
	end

	function eye(dtype::DataType, n::Int64)
		res = zeros(dtype, n, n)
		I = 1.0 |> dtype
		for i = 1:n res[i,i] = I end
		return res
	end

	function pauli(symbol::Symbol)
		if symbol==:x return [0. 1.; 1. 0.]
		elseif symbol==:y return [0. -1im; 1im 0.]
		elseif symbol==:z return [1. 0.; 0. -1.]
		elseif symbol==:+ return [0. 1.; 0. 0.]
		elseif symbol==:- return [0. 0.; 1. 0.]
		else
			error("The input should be :x,:y,:z,:+,:-.")
		end
	end

	function delta(x::Real; c::Real = 0., η::Real = 0.05)
		num = η
		den = ((x-c)^2 + η^2) * π
		return num/den
	end

	function gaussian(x::Real, fac::AbstractVector)
		# f(x) = 1/(σ√(2π)) exp(-((x-μ)/σ)^2 /2 )
		μ = fac[1]; σ2 = fac[2]
		σ2 <= 0. ? (@error "σ2 should be positive.") :
		norm = √(2π * σ2)
		m = (x-μ)^2 / σ2
		return 1/norm*exp(-m/2)
	end

	function multi_gaussian(N::Int64; ms::Vector{Float64}=[-3.,3.], smax::Real=3.)
		fac = rand(N,2)
		fac[:,1] = rand(N) .* (ms[2] - ms[1]) .+ ms[1]
		fac[:,2] = rand(N) .* smax
		function f(x::Real)
			res = 0.
			for i = 1: N
				res += gaussian(x, fac[i,:])
			end
			res/N
		end
		return f, fac
	end

	function Masubara_freq(n::Int64, β::Real; type::Symbol= :f)
		if type == :b  N = 2n
		elseif type == :f  N = 2n + 1
		else @error "type should be :b for bosons and :f for fermions"
		end
		return N*π/β
	end

	function Masubara_GF(n::Int64, A::Function, β::Real;
		type::Symbol = :f, Λ::Float64=100., L::Int64=1000000)
		# G(iωn) = 1/2π ∫dΩ A(Ω)/(iωn - Ω)
		ωn = Masubara_freq(n, β, type=type)
		dL = 2*Λ/L
		Gn = 0.
		for n = 0:L
			ω = -Λ + dL*n
			Gn += A(ω)/(1.0im*ωn-ω) * dL
		end
		return Gn/(2π)
	end

	function h(z::Number)
		#Conformal mapping(Mobius transform)
		#\bar{C+} -> \bar{D}
		return (z - 1.0im)/(z + 1.0im)
	end

	function invh(z::Number)
		return 1.0im*(1 + z)/(1 - z)
	end

	function h1(z::Number, Y::Number)
		#Conformal mapping(Mobius transform)
		#C+ -> D
		return (z - Y)/(z - Y')
	end

	function invh1(z::Complex, Y::Number)
		return (z*Y'-Y)/(z-1)
	end

	function ispossemidef(A::Matrix)
		evals = eigvals(A)
		return all(evals .>= 0)
	end
	"utilities"
end

# ╔═╡ ac782b5a-26b2-4b8f-a9d8-3baf7d1c22c5
begin
	fnum = 50; β=100
	plot(circle_x, circle_y, line=(2, :black),label=false)
	ωn = [Masubara_freq(i,β,type=:f) for i=1:fnum]
	scatter!(zeros(fnum), ωn, label="iωn")
	hω = [h(1.0im*i) for i in ωn]
	scatter!(real.(hω), imag.(hω), label="h(iωn)")
	plot!(ylim = (-1.5,1.5), xlim =(-1.2,1.2))
end

# ╔═╡ 22756d1d-983c-47eb-b6a5-0caeaa8d6fa0
begin
	struct Giωn
		ωn::Real
		val::Complex
	end

	struct MasubaraGF
		number::Int64
		gtype::Symbol
		GF::Vector{Giωn}
	end

	function λ(G::Giωn)
    	return h(-G.val)
	end

	function pick_matrix(G::MasubaraGF)
		# input :freq: Masubara frenquencies; val: G
		N = G.num; g = G.GF
		pick = zeros(ComplexF64, N, N)
		for i = 1:N, j = 1:N
			up = 1 - λ(g[i])*λ(g[j])'
			down = 1 - h(1.0im*g[i].ωn)*h(1.0im*g[j].ωn)'
			pick[i,j] = up/down
		end
		return pick
	end

	function isNevanlinnasolvable(G::MasubaraGF; err::Float64 = 1.e-6)
		# check if the pick_matrix is semi positive semidefinite
		pick = pick_matrix(G)
		evals = eigvals(pick)
		return all((evals .+ err) .>= 0), minimum(evals)
	end
	"struct and pick_matrix"
end

# ╔═╡ e7027211-d85d-43c1-8647-8c48ce0c54f8
begin
	function θk(abcd::Matrix, val::Number)
	    up = -abcd[2,2] * val + abcd[1,2]
	    down = abcd[2,1] * val - abcd[1,1]
	    return up/down
	end

	function core(G::MasubaraGF)
		T = ComplexF64
		M=G.number; g = G.GF
		phis = zeros(T, M) ; phis[1] = λ(g[1]) #store λk(iω_(k+1))
		abcds = Vector{Matrix{T}}(undef,M)
		for i = 1:M
			abcds[i] = eye(T,2)
		end
		for j = 1:(M-1)
			for k=j:(M-1)
				prod = zeros(T,2,2)
				prod[1,1] = h1(1.0im*g[k].ωn,1.0im*g[j].ωn)
				prod[1,2] = phis[j]
				prod[2,1] = phis[j]' * h1(1.0im*g[k].ωn,1.0im*g[j].ωn)
				prod[2,2] = 1. |> T
				abcds[k] *= prod
			end
			phis[j+1] = θk(abcds[j+1], λ(g[j+1]))
		end
		return phis
	end

	function evaluation(z::Number, G::MasubaraGF;
		optim::Symbol = :none)
		dtype = ComplexF64
		M = G.number
		g = G.GF
		phis = core(G)
		abcd = eye(dtype,2)
		for j = 1:M
			prod = zeros(dtype,2,2)
			prod[1,1] = h1(z,1.0im*g[j].ωn)
			prod[1,2]= phis[j]
			prod[2,1] = phis[j]' * h1(z,1.0im*g[j].ωn)
			prod[2,2] = 1. |> dtype
			abcd *= prod
		end

		if optim == :none
			θm(z::Number) = 0.0 + 0.0im
		end

		up = abcd[1,1] * θm(z) + abcd[1,2]
		down = abcd[2,1] * θm(z) + abcd[2,2]
		θ = up/down
		return invh(θ)
	end

	function spectrum_density(ω::Real, η::Real, G::MasubaraGF)
		z = ω + 1.0im * η
		return evaluation(z, G)/π |> imag
	end
end

# ╔═╡ 02175367-7ea1-45c8-8188-10b01993efde
function make_input(path::String, num::Int64; type::Symbol = :f)
    data = readdlm(path)
    fnum = min(num, length(data[:,1])) # number of frenquencies used
    res = [Giωn(data[i,1],data[i,2]+1.0im*data[i,3]) for i = 1:fnum] |> reverse
    return MasubaraGF(fnum, type, res)
end

# ╔═╡ 4033c412-34be-439f-8dcf-42f4ed570611
begin
	N = 36
	p1 = "./data/idelta.txt"; G1 = make_input(p1,N)
	p2 = "./data/ig1.txt"; G2 = make_input(p2,N)
	p3 = "./data/ig3.txt"; G3 = make_input(p3,N)

	gf1 = G1.GF
	gf2 = G2.GF
	gf3 = G3.GF
	"load data"
end

# ╔═╡ 290742b3-a4fb-4763-b0b2-eaad702e7c94
N

# ╔═╡ 08f205d9-b396-4b95-9068-3097c36cf1bd
begin
	w = [gf1[i].ωn for i=1:N]
	gt = [-gf1[i].val for i=1:N]
	g = [evaluation(1.0im*i, G1) for i in w]
	scatter(real.(gt), imag.(gt),marker=(:hex,5),label="data:-g(iωn)")
	scatter!(real.(g), imag.(g), label="interploate")
	plot!(xlabel="1", ylabel="i")
end

# ╔═╡ 1a3e64ec-4491-478d-9885-d7c8f828618c
begin
	omega = [i for i in range(-5,5,length=1000)] ; η = 0.001
	A = [spectrum_density(i,η,G1) for i in omega]
	plot(omega,A,label=false)
end

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[compat]
Plots = "~1.22.1"
"""

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[IterTools]]
git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.3.0"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[Parsers]]
deps = ["Dates"]
git-tree-sha1 = "438d35d2d95ae2c5e8780b330592b6de8494e779"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.0.3"

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

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

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

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

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

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

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

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

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

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

[[RecipesBase]]
git-tree-sha1 = "44a75aa7a527910ee3d1751d1f0e4148698add9e"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.1.2"

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

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

[[Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "4036a3bd08ac7e968e27c203d45f5fff15020621"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.1.3"

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

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

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

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

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

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

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

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

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "3240808c6d463ac46f1c1cd7638375cd22abbccb"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.12"

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

[[StatsAPI]]
git-tree-sha1 = "1958272568dc176a1d881acb797beb909c785510"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.0.0"

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

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

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

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

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

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

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

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

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

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

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

[[Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll"]
git-tree-sha1 = "2839f1c1296940218e35df0bbb220f2a79686670"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.18.0+4"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

# ╔═╡ Cell order:
# ╟─290742b3-a4fb-4763-b0b2-eaad702e7c94
# ╟─0520406d-2b17-427d-a830-c563a191a816
# ╟─c27ab801-37a4-4174-9c7d-623c08f63203
# ╟─ac782b5a-26b2-4b8f-a9d8-3baf7d1c22c5
# ╟─d2f19b71-1947-4197-a00c-4d90df01fd96
# ╟─b71809a2-fc70-438c-8205-60dce946131f
# ╟─08f205d9-b396-4b95-9068-3097c36cf1bd
# ╟─1a3e64ec-4491-478d-9885-d7c8f828618c
# ╟─e7027211-d85d-43c1-8647-8c48ce0c54f8
# ╟─4033c412-34be-439f-8dcf-42f4ed570611
# ╟─02175367-7ea1-45c8-8188-10b01993efde
# ╟─22756d1d-983c-47eb-b6a5-0caeaa8d6fa0
# ╠═0d7c7bef-170e-46e1-907f-9b2a8e60bd91
# ╟─51a61cd4-185c-11ec-0a43-4517c063bc43
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002


text:
"""
    accuracy(pred::Vector{Int}, truth::Vector{Int})

Returns proportion of indices in `truth` that are also in `pred`.
"""
function accuracy(pred::Vector{Int}, truth::Vector{Int})
    detected = 0
    for t in truth
        (t in pred) && (detected += 1)
    end
    detected / length(truth)
end

"""
    falsepositive(pred::Vector{Int}, truth::Vector{Int})

Returns the proportion of indices in `pred` that are not in `truth`.
"""
function falsepositive(pred::Vector{Int}, truth::Vector{Int})
    detected = 0
    for p in pred
        (p in truth) || (detected += 1)
    end
    detected / length(pred)
end

function mse(pred::YVector, truth::YVector)
    sum(abs2.(pred - truth))
end
function mse(pred::YVector, pt::Float64)
    sum(abs2.(pred - pt))
end
"""
    oosRsquared(pred::Vector{Float64}, truth::Vector{Float64}, train::Vector{Float64})

Computes the out-of-sample R^2.
"""
function oosRsquared(pred::Vector{Float64}, truth::YVector, train::YVector)
    1 - mse(pred, truth) / mse(pred, mean(train))
end

"""
    isRsquared(pred::Vector{Float64}, truth::Vector{Float64})

Computes the in-sample R^2.
"""
function isRsquared(pred::Vector{Float64}, truth::YVector)
    1 - mse(pred, truth) / mse(truth, mean(truth))
end

function predict_sparse(X::Array{Float64,2}, indices::Vector{Int}, w::Vector{Float64})
    X[:, indices] * w
end

function dist2str(::Union{Normal, MvNormal})
    "normal"
end
function dist2str(::Uniform)
    "uniform"
end
function dist2str(::BinChoice)
    "binchoice"
end
function dist2str(::NoNoise)
    "nonoise"
end
function corr2str(::NoCorrelation)
    "none"
end
function corr2str(c::MatrixCorrelation)
    "rho_$(c.coeff)"
end
function data2str(bd::BenchmarkData)
    "x_" * dist2str(bd.Xdata.dist) *
    "_corr_" * corr2str(bd.Xdata.corr) *
    "_w_" * dist2str(bd.wdist) *
    "_noise_" * dist2str(bd.noisedist) *
    "_snr_$(bd.SNR)" *
    "_d_$(bd.nfeatures)" *
    "_k_$(bd.sparsity)"
end
function Base.mkdir(bd::BenchmarkData)
    mkdir(data2str(bd))
end
function method2str(m::RegressionMethod)
    error("You need to define `method2str` for $m.")
end
function solver2str(s::CplexSolver)
    "cplex"
end
function solver2str(s::GurobiSolver)
    "gurobi"
end
function method2str(m::ExactPrimalCuttingPlane)
    if m.warm_start != NoWarmStart()
        "exact_primal_tlimit_$(m.time_limit)_$(solver2str(m.solver))_ws"
    else
        "exact_primal_tlimit_$(m.time_limit)_$(solver2str(m.solver))"
    end
end
function method2str(m::PrimalWithHeuristics)
    if m.warm_start != NoWarmStart()
        "node_heuristics_primal_tlimit_$(m.time_limit)_$(solver2str(m.solver))_ws"
    else
        "node_heuristics_primal_tlimit_$(m.time_limit)_$(solver2str(m.solver))"
    end
end
function stepping2str(sr::ConstantStepping)
  "conststep_$(sr.stepsize)"
end
function stepping2str(sr::PolyakStepping)
  "polyak_$(sr.initial_factor)"
end
function method2str(m::RelaxDualSubgradient)
    "relax_dual_subgradient_" *
    stepping2str(m.sr) *
    "_maxiter_$(m.maxiter)"
end
function method2str(m::RelaxDualCutting)
    "relax_dual_cut_" * "$(solver2str(m.solver))"
end