text:
using
  PyPlot,
  JLD2,
  Printf,
  Random,
  FourierFlows

using Statistics: mean
using FFTW: irfft

import GeophysicalFlows.BarotropicQG
import GeophysicalFlows.BarotropicQG: energy, enstrophy

# Numerical parameters and time-stepping parameters
nx  = 256      # 2D resolution = nx^2
stepper = "FilteredETDRK4"   # timestepper
dt  = 0.02     # timestep
nsteps = 8000  # total number of time-steps
nsubs  = 500   # number of time-steps for plotting
               # (nsteps must be multiple of nsubs)

# Physical parameters
 Lx  = 2π      # domain size
 nu  = 0e-05   # viscosity
 nnu = 1       # viscosity order
beta = 15.0    # planetary PV gradient
mu   = 0e-1    # bottom drag

# Initialize problem
prob = BarotropicQG.InitialValueProblem(nx=nx, Lx=Lx, beta=beta, nu=nu,
                                        nnu=nnu, mu=mu, dt=dt, stepper=stepper)
sol, cl, v, p, g = prob.sol, prob.clock, prob.vars, prob.params, prob.grid

# Files
filepath = "."
plotpath = "./plots_decayingbetaturb"
plotname = "snapshots"
filename = joinpath(filepath, "decayingbetaturb.jld2")

# File management
if isfile(filename); rm(filename); end
if !isdir(plotpath); mkdir(plotpath); end

# Initial condition that has power only at wavenumbers with
# 8<L/(2π)*sqrt(kx^2+ky^2)<10 and initial energy E0
Random.seed!(1234)
E0 = 0.1
modk = ones(g.nkr, g.nl)
modk[real.(g.Krsq).<(8*2*pi/g.Lx)^2] .= 0
modk[real.(g.Krsq).>(10*2*pi/g.Lx)^2] .= 0
modk[1, :] .= 0
psih = (randn(Float64, size(sol)) .+ im*randn(Float64, size(sol))).*modk
psih = @. psih*prob.timestepper.filter
Ein = real(sum(g.Krsq.*abs2.(psih)/(g.nx*g.ny)^2))
psih = psih*sqrt(E0/Ein)
qi = -irfft(g.Krsq.*psih, g.nx)
E0 = FourierFlows.parsevalsum(g.Krsq.*abs2.(psih), g)

BarotropicQG.set_zeta!(prob, qi)

# Create Diagnostic -- "energy" and "enstrophy" are functions imported at the top.
E = Diagnostic(energy, prob; nsteps=nsteps)
Z = Diagnostic(enstrophy, prob; nsteps=nsteps)
diags = [E, Z] # A list of Diagnostics types passed to "stepforward!" will
# be updated every timestep. They should be efficient to calculate and
# have a small memory footprint. (For example, the domain-integrated kinetic
# energy is just a single number for each timestep). See the file in
# src/diagnostics.jl and the stepforward! function in timesteppers.jl.

# Create Output
get_sol(prob) = sol # extracts the Fourier-transformed solution
get_u(prob) = irfft(im*g.l.*g.invKrsq.*sol, g.nx)
out = Output(prob, filename, (:sol, get_sol), (:u, get_u))

x, y = gridpoints(g)

function plot_output(prob, fig, axs; drawcolorbar=false)
  # Plot the vorticity and streamfunction fields as well as the zonal mean
  # vorticity and the zonal mean zonal velocity.

  sol, v, p, g = prob.sol, prob.vars, prob.params, prob.grid
  BarotropicQG.updatevars!(prob)

  sca(axs[1])
  cla()
  pcolormesh(x, y, v.q)
  axis("square")
  xticks(-2:2:2)
  yticks(-2:2:2)
  title(L"vorticity $\zeta = \partial_x v - \partial_y u$")
  if drawcolorbar==true
    colorbar()
  end

  sca(axs[2])
  cla()
  contourf(x, y, v.psi)
  if maximum(abs.(v.psi))>0
    contour(x, y, v.psi, colors="k")
  end
  axis("square")
  xticks(-2:2:2)
  yticks(-2:2:2)
  title(L"streamfunction $\psi$")
  if drawcolorbar==true
    colorbar()
  end

  sca(axs[3])
  cla()
  plot(Array(transpose(mean(v.zeta, dims=1))), y[1,:])
  plot(0*y[1,:], y[1,:], "k--")
  ylim(-Lx/2, Lx/2)
  xlim(-2, 2)
  title(L"zonal mean $\zeta$")

  sca(axs[4])
  cla()
  plot(Array(transpose(mean(v.u, dims=1))), y[1,:])
  plot(0*y[1,:], y[1,:], "k--")
  ylim(-Lx/2, Lx/2)
  xlim(-0.5, 0.5)
  title(L"zonal mean $u$")

  pause(0.001)
end

fig, axs = subplots(ncols=2, nrows=2, figsize=(8, 8))
plot_output(prob, fig, axs; drawcolorbar=false)

# Step forward
startwalltime = time()

while cl.step < nsteps
  stepforward!(prob, diags, nsubs)

  # Message
  log = @sprintf("step: %04d, t: %d, E: %.4f, Q: %.4f, τ: %.2f min",
    cl.step, cl.t, E.data[E.i], Z.data[Z.i],
    (time()-startwalltime)/60)

  println(log)

  plot_output(prob, fig, axs; drawcolorbar=false)
end

# how long did it take?
println((time()-startwalltime))

plot_output(prob, fig, axs; drawcolorbar=false)

# save the figure as png
savename = @sprintf("%s_%09d.png", joinpath(plotpath, plotname), cl.step)
savefig(savename)


text:
module JOLI4Flux

    using JOLI: joAbstractLinearOperator
    using Zygote
    using FillArrays
    import Base.*
    using Zygote: @adjoint

    @adjoint a::joAbstractLinearOperator * b::AbstractVecOrMat =
        *(a, b), Δ -> (nothing, transpose(a) * Δ)

    function *(
        A::joAbstractLinearOperator{ADDT,ARDT},
        v::FillArrays.Fill{vDT,1}
    ) where {ADDT,ARDT,vDT<:Number}

        dummy = Vector(v)
        res = A*dummy

    end

end

ext: jl


text:
module TestMachines

using MLJSerialization
using MLJBase
using Test

include(joinpath(@__DIR__, "_models", "models.jl"))
using .Models

@testset "serialization" begin

    @test MLJSerialization._filename("mymodel.jlso") == "mymodel"
    @test MLJSerialization._filename("mymodel.gz") == "mymodel"
    @test MLJSerialization._filename("mymodel") == "mymodel"

    model = DecisionTreeRegressor()

    X = (a = Float64[98, 53, 93, 67, 90, 68],
         b = Float64[64, 43, 66, 47, 16, 66],)
    Xnew = (a = Float64[82, 49, 16],
            b = Float64[36, 13, 36],)
    y =  [59.1, 28.6, 96.6, 83.3, 59.1, 48.0]

    mach =machine(model, X, y)
    filename = joinpath(@__DIR__, "machine.jlso")
    io = IOBuffer()
    @test_throws Exception MLJSerialization.save(io, mach; compression=:none)

    fit!(mach)
    report = mach.report
    pred = predict(mach, Xnew)
    MLJSerialization.save(io, mach; compression=:none)
    # Un-comment to update the `machine.jlso` file:
    #MLJSerialization.save(filename, mach)

    # test restoring data from filename:
    m = machine(filename)
    p = predict(m, Xnew)
    @test m.model == model
    @test m.report == report
    @test p ≈ pred
    m = machine(filename, X, y)
    fit!(m)
    p = predict(m, Xnew)
    @test p ≈ pred

    # test restoring data from io:
    seekstart(io)
    m = machine(io)
    p = predict(m, Xnew)
    @test m.model == model
    @test m.report == report
    @test p ≈ pred
    seekstart(io)
    m = machine(io, X, y)
    fit!(m)
    p = predict(m, Xnew)
    @test p ≈ pred

end

@testset "errors for deserialized machines" begin
    filename = joinpath(@__DIR__, "machine.jlso")
    m = machine(filename)
    @test_throws ArgumentError predict(m)
end

end # module

true


text:
module HANSsolver

    import Distributed, Mmap, Optim

    include("HANS_init.jl")
    include("HANS_utilities_functions.jl")
    include("solver/cube/cube.jl")
    include("solver/cube/cubeCPU.jl")
    include("solver/cube/cubeFunction.jl")
    # include("solver/cube/cubeGPU.jl")
    include("solver/cube/cubeMmap.jl")
    include("solver/density/prob_trans_iterator.jl")
    include("solver/dr_iterator/dr_CPU.jl")
    include("solver/dr_iterator/dr_iterator.base.jl")
    include("solver/solver.base.jl")
    include("solver/solver.functions.jl")
    include("tests/cubetest.jl")
    include("tests/modeltest.jl")

    export cubetest, modeltest, hans_solver, hans_solver_dynamic_griding, make_dimmensions, get_vars
    export Model, ModelInit, Utils, GridDef

end # module


text:
module ShipNoiseGenerators

using Distributions, DSP, StaticArrays, Random

export ShipNoiseGenerator, PinkNoiseGenerator

Base.@kwdef struct ShipNoiseGenerator{T}
     n::Int = 96000
     fs::Int = 96000
     As::AbstractArray{T, 1} = [0.5]
     frequencies::AbstractArray{T, 1} = [500.0]
     ϕs::AbstractArray{T, 1} = [0.0]
end

Base.@kwdef struct PinkNoiseGenerator
    n::Int
end

"""
Synthesis of 1/F Noise (Pink Noise) based on https://ccrma.stanford.edu/~jos/sasp/Example_Synthesis_1_F_Noise.html
"""
function Random.rand!(rng::AbstractRNG, g::PinkNoiseGenerator)
    n=g.n
    B = SVector{4}([0.049922035, -0.095993537, 0.050612699, -0.004408786])
    A = SVector{4}([1.0, -2.494956002, 2.017265875, -0.522189400])
    nT60 = 1430
    v = randn(n+nT60)
    x = filt(B, A, v)/0.08680587859687908
    view(x, nT60+1:length(x))
end

Base.rand(rng::AbstractRNG, g::PinkNoiseGenerator) = rand!(rng, g)

function Random.rand!(rng::AbstractRNG, g::ShipNoiseGenerator)
    n=g.n; fs=g.fs; As=g.As; frequencies=g.frequencies; ϕs=g.ϕs
    x = rand(PinkNoiseGenerator(n=n))
    t = (1:n)/fs
    m = zero(x)
    @inbounds for (A, frequency, ϕ) in zip(As, frequencies, ϕs)
        ω = 2π*frequency
        m .+= A.*sin.(ω.*t.+ϕ)
    end
    x .*= 1.0 .+ m
    x / std(x)
end

Base.rand(rng::AbstractRNG, g::ShipNoiseGenerator) = rand!(rng, g)

end


text:
#=
Style
=#

immutable TextProp
  fmt
end

abstract AbstractSpanProp
immutable StaticSpanProp <: AbstractSpanProp
  colspan::Int
  rowspan::Int
end
StaticSpanProp() = StaticSpanProp(1,1)

immutable CartesianSpanProp <: AbstractSpanProp
end
immutable ExpandSpanProp <: AbstractSpanProp
end

immutable HTMLStyleElement{S <: AbstractSpanProp} <: AbstractStyleElement
  text::TextProp
  span::S
  tagstring::String
end

text(txt, txtprop::TextProp) = txtprop.fmt(txt)

rowspan(style::HTMLStyleElement{StaticSpanProp}, datael, i, j) = style.span.rowspan
colspan(style::HTMLStyleElement{StaticSpanProp}, datael, i, j) = style.span.colspan
istext(style::HTMLStyleElement{StaticSpanProp},  datael, i, j) = true

function colspan(style::HTMLStyleElement{CartesianSpanProp},
                 datael::CartesianDataElement, i, j)
  isvertical(datael) ? datael.spansizes[i] : 1
end
function rowspan(style::HTMLStyleElement{CartesianSpanProp},
                 datael::CartesianDataElement, i, j)
  isvertical(datael) ? 1 : datael.spansizes[j]
end
function istext(style::HTMLStyleElement{CartesianSpanProp},
                datael::CartesianDataElement, i, j)
  if isvertical(datael)
    return mod(j-1, datael.spansizes[i]) == 0
  else
    return mod(i-1, datael.spansizes[j]) == 0
  end
end

function rowspan(style::HTMLStyleElement{ExpandSpanProp},
        datael, i, j)
  n, m = size(datael)
  return n
end
function colspan(style::HTMLStyleElement{ExpandSpanProp},
                 datael, i, j)
  n, m = size(datael)
  return m
end
istext(style::HTMLStyleElement{ExpandSpanProp}, datael, i, j) = i==1 && j==1


text:
# Use baremodule to shave off a few KB from the serialized `.ji` file
baremodule MAFFT_jll
using Base
using Base: UUID
import JLLWrappers

JLLWrappers.@generate_main_file_header("MAFFT")
JLLWrappers.@generate_main_file("MAFFT", UUID("72a4bdf2-be5e-5c84-b157-f1dc2927f791"))
end  # module MAFFT_jll


text:
"""
Module to keep global configs
Should become customizable at some point!
"""
module Config

using Reactive, GeometryTypes, Colors, GLFW, GLWindow, GLAbstraction

# don't want to repeat the compatibility code
import GLAbstraction: N0f8

# const shortcuts = Dict(
#     "paste" => Signal([GLFW.KEY_LEFT_CONTROL, GLFW.KEY_V]),
#     "copy"  => Signal([GLFW.KEY_LEFT_CONTROL, GLFW.KEY_C]),
#     "cut"   => Signal([GLFW.KEY_LEFT_CONTROL, GLFW.KEY_X]),
#     "rotate cam xy" => Signal([MOUSE_LEFT, GLFW.KEY_LEFT_CONTROL]),
# )

"""
default returns common defaults for a certain style and datatype.
This is convenient, to quickly switch out default styles.
"""
default(::T, s::Style=Style{:default}()) where {T} = default(T, s)

function default(::Type{T}, s::Style=Style{:default}(), index=1) where T <: Colorant
    color_defaults = RGBA{Float32}[
    	RGBA{Float32}(0.0f0,0.74736935f0,1.0f0,1.0f0),
    	RGBA{Float32}(0.78, 0.01, 0.93, 1.0),
    	RGBA{Float32}(0, 0, 0, 1.0),
    	RGBA{Float32}(0.78, 0.01, 0, 1.0)
    ]
    index > length(color_defaults) && error("There are only three color defaults.")
    color_defaults[index]
end
function default(::Type{Vector{T}}, s::Style = Style{:default}()) where T <: Colorant
    map(RGBA{N0f8}, colormap("Blues", 7))
end
export default

end


text:
@testset "contractions" begin

D = 10
d = 3
sites = 5
T = ComplexF64

ψ = randn(MPS{T}, sites, D, d)
ϕ = randn(MPS{T}, sites, D, d)
mpo_ψ = randn(MPO{T}, sites, D, d)
mpo = randn(MPO{T}, 2, 2, 2)

Id = fill(I(d), length(ψ))

Id_m = MPO(fill(ones(1,1,1,d), length(ϕ)))

@testset "dot products" begin
    @testset "is equal to itself" begin
        @test dot(ψ, ψ) ≈ dot(ψ, ψ)
    end

    @testset "change of arguments results in conjugation" begin
        @test dot(ψ, ϕ) ≈ conj(dot(ϕ, ψ))
        @test dot(ψ, Id, ϕ) ≈ conj(dot(ϕ, Id, ψ))
    end

    @testset "dot with identity equal to dot of two MPS" begin
        @test dot(ψ, Id, ϕ) ≈ dot(ψ, ϕ)
    end

    @testset "norm is 2-norm" begin
        @test norm(ψ) ≈ sqrt(abs(dot(ψ, ψ)))
    end

    @testset "renormalizations" begin
        ψ[end] *= 1 / norm(ψ)
        @test dot(ψ, ψ) ≈ 1

        ϕ[1] *= 1 / norm(ϕ)
        @test dot(ϕ, ϕ) ≈ 1
    end

    @testset "dot products of MPO" begin
        mpo1 = dot(mpo, mpo)

        @testset "has correct sisze" begin
            @test size(mpo1[1]) == (1, 2, 4, 2)
            @test size(mpo1[2]) == (4, 2, 1, 2)
        end
    end

end

@testset "left environment returns correct overlap" begin
    L = left_env(ϕ, ψ)
    @test L[end][1] ≈ dot(ϕ, ψ)
end

@testset "right environment returns correct overlap" begin
    R = right_env(ϕ, ψ)
    @test R[1][end] ≈ dot(ϕ, ψ)
end

@testset "Cauchy-Schwarz inequality of MPS is OK" begin
    @test abs(dot(ϕ, ψ)) <= norm(ϕ) * norm(ψ)
end

@testset "left_env correctly contracts MPS for a given configuration" begin
    D = 10
    d = 2
    sites = 5
    T = ComplexF64

    ψ = randn(MPS{T}, sites, D, d)
    state = 2 * (rand(sites) .< 0.5) .- 1

    C = I
    for (A, σ) ∈ zip(ψ, state) C *= A[:, idx(σ), :] end

    @test tr(C) ≈ left_env(ψ, map(idx, state))[]
end

@testset "right_env correctly contracts MPO with MPS for a given configuration" begin
    D = 10
    d = 2
    sites = 5
    T = Float64

    ψ = randn(MPS{T}, sites, D, d)
    W = randn(MPO{T}, sites, D, d)

    σ = 2 * (rand(sites) .< 0.5) .- 1

    ϕ = MPS(T, sites)
    for (i, A) ∈ enumerate(W)
        m = idx(σ[i])
        @cast B[x, s, y] := A[x, $m, y, s]
        ϕ[i] = B
    end

    @test dot(ψ, ϕ) ≈ right_env(ψ, W, map(idx, σ))[]
end

end


text:
#-------------------------------------------------------------------
#* EMSO Model Library (EML) Copyright (C) 2004 - 2007 ALSOC.
#*
#* This LIBRARY is free software; you can distribute it and/or modify
#* it under the therms of the ALSOC FREE LICENSE as available at
#* http://www.enq.ufrgs.br/alsoc.
#*
#* EMSO Copyright (C) 2004 - 2007 ALSOC, original code
#* from http://www.rps.eng.br Copyright (C) 2002-2004.
#* All rights reserved.
#*
#* EMSO is distributed under the therms of the ALSOC LICENSE as
#* available at http://www.enq.ufrgs.br/alsoc.
#*
#*--------------------------------------------------------------------
#* Model of basic streams
#*----------------------------------------------------------------------
#* Author: Paula B. Staudt and Rafael de P. Soares
#* $Id$
#*---------------------------------------------------------------------
type info_stream
	info_stream()=begin
		PP=outers.PP
		NComp=outers.NComp
		new(
			DanaPlugin(Dict{Symbol,Any}(
				:Brief=>"External Physical Properties",
				:Type=>"PP"
			)),
			DanaInteger(Dict{Symbol,Any}(
				:Brief=>"Number of chemical components",
				:Lower=>1
			)),
			fill(molweight(Dict{Symbol,Any}(
				:Brief=>"Component Mol Weight",
				:Protected=>true
			)),(NComp)),
			stream(Dict{Symbol,Any}(
				:Brief=>"Inlet Stream",
				:PosX=>0,
				:PosY=>0.50,
				:Protected=>true ,
				:Symbol=>"_{in}"
			)),
			stream(Dict{Symbol,Any}(
				:Brief=>"Outlet Stream",
				:PosX=>1,
				:PosY=>0.50,
				:Protected=>true ,
				:Symbol=>"_{out}"
			)),
			fraction(Dict{Symbol,Any}(
				:Brief=>"Vapourization fraction",
				:Hidden=>true
			)),
			fill(fraction(Dict{Symbol,Any}(
				:Brief=>"Liquid Molar Fraction",
				:Hidden=>true
			)),(NComp)),
			fill(fraction(Dict{Symbol,Any}(
				:Brief=>"Vapour Molar Fraction",
				:Hidden=>true
			)),(NComp)),
			fill(flow_mol(Dict{Symbol,Any}(
				:Brief=>"Component Molar Flow",
				:Protected=>true
			)),(NComp)),
			flow_mass(Dict{Symbol,Any}(
				:Brief=>"Total Mass Flow",
				:Protected=>true
			)),
			fill(flow_mass(Dict{Symbol,Any}(
				:Brief=>"Component Mass Flow",
				:Protected=>true
			)),(NComp)),
			flow_vol(Dict{Symbol,Any}(
				:Brief=>"Total Volumetric Flow",
				:Protected=>true
			)),
			DanaReal(Dict{Symbol,Any}(
				:Brief=>"Temperature in  C",
				:Lower=>-250,
				:Upper=>5000,
				:Protected=>true
			)),
			viscosity(Dict{Symbol,Any}(
				:Brief=>"Stream Viscosity",
				:Lower=>0.0001,
				:Symbol=>"\\mu",
				:Protected=>true
			)),
			cp_mol(Dict{Symbol,Any}(
				:Brief=>"Stream Molar Heat Capacity",
				:Upper=>1e10,
				:Protected=>true
			)),
			conductivity(Dict{Symbol,Any}(
				:Brief=>"Stream Thermal Conductivity",
				:Default=>1.0,
				:Lower=>1e-5,
				:Upper=>500,
				:Protected=>true
			)),
			molweight(Dict{Symbol,Any}(
				:Brief=>"Average Mol Weight",
				:Protected=>true
			)),
			volume_mol(Dict{Symbol,Any}(
				:Brief=>"Molar Volume",
				:Protected=>true
			)),
			dens_mass(Dict{Symbol,Any}(
				:Brief=>"Stream Mass Density",
				:Protected=>true
			)),
			dens_mol(Dict{Symbol,Any}(
				:Brief=>"Stream Molar Density",
				:Protected=>true
			)),
			entr_mol(Dict{Symbol,Any}(
				:Brief=>"Stream Entropy",
				:Protected=>true
			)),
			fill(fraction(Dict{Symbol,Any}(
				:Brief=>"Mass Fraction",
				:Protected=>true
			)),(NComp)),
			[
				:([v, x, y] = PP.FlashPH(Inlet.P, Inlet.h, Inlet.z)),
				:(Mw = sum(M*Inlet.z)),
				:(rho * ((1-v)/PP.LiquidDensity(Inlet.T,Inlet.P,x) + v/PP.VapourDensity(Inlet.T,Inlet.P,y)) = 1),
				:(rhom * Mw = rho),
				:(FwTotal = Mw*Inlet.F),
				:(Fw = FwTotal*zmass),
				:(vm = (1-v)*PP.LiquidVolume(Inlet.T, Inlet.P, x) + v*PP.VapourVolume(Inlet.T,Inlet.P,y)),
				:(FvolTotal = Inlet.F*vm),
				:(zmass = M*Inlet.z / Mw),
				:(Cp = (1-v)*PP.LiquidCp(Inlet.T, Inlet.P, x) + v*PP.VapourCp(Inlet.T,Inlet.P,y)),
				:(Mu = (1-v)*PP.LiquidViscosity(Inlet.T, Inlet.P, x) + v*PP.VapourViscosity(Inlet.T,Inlet.P,y)),
				:(K = (1-v)*PP.LiquidThermalConductivity(Inlet.T, Inlet.P, x) + v*PP.VapourThermalConductivity(Inlet.T,Inlet.P,y)),
				:(s = (1-v)*PP.LiquidEntropy(Inlet.T, Inlet.P, x) + v*PP.VapourEntropy(Inlet.T, Inlet.P, y)),
				:(T_Cdeg = Inlet.T/"K" - 273.15),
				:(Outlet.F = Inlet.F),
				:(F = Inlet.F*Inlet.z),
				:(Outlet.T = Inlet.T),
				:(Outlet.P = Inlet.P),
				:(Outlet.v = Inlet.v),
				:(Outlet.h = Inlet.h),
				:(Outlet.z= Inlet.z),
			],
			[
				"Flash Calculation","Average Molecular Weight","Mass Density","Mass or Molar Density","Total Flow Mass","Component Flow Mass","Molar Volume","Total Volumetric Flow","Mass Fraction","Stream Heat Capacity","Stream Viscosity","Stream ThermalConductivity","Stream Overall Entropy","Temperature in  C","Outlet Flow","Component Molar Flow","Outlet Temperature","Outlet Pressure","Outlet Vapour Fraction","Outlet Enthalpy","Outlet Composition",
			],
			[:PP,:NComp,:M,],
			[:Inlet,:Outlet,:v,:x,:y,:F,:FwTotal,:Fw,:FvolTotal,:T_Cdeg,:Mu,:Cp,:K,:Mw,:vm,:rho,:rhom,:s,:zmass,]
		)
	end
	PP::DanaPlugin
	NComp::DanaInteger
	M::Array{molweight}
	Inlet::stream
	Outlet::stream
	v::fraction
	x::Array{fraction}
	y::Array{fraction}
	F::Array{flow_mol}
	FwTotal::flow_mass
	Fw::Array{flow_mass}
	FvolTotal::flow_vol
	T_Cdeg::DanaReal
	Mu::viscosity
	Cp::cp_mol
	K::conductivity
	Mw::molweight
	vm::volume_mol
	rho::dens_mass
	rhom::dens_mol
	s::entr_mol
	zmass::Array{fraction}
	equations::Array{Expr,1}
	equationNames::Array{String,1}
	parameters::Array{Symbol,1}
	variables::Array{Symbol,1}
	attributes::Dict{Symbol,Any}
end
export info_stream
function set(in::info_stream)
	M = PP.MolecularWeight()

end
function setEquationFlow(in::info_stream)
	addEquation(1)
	addEquation(2)
	addEquation(3)
	addEquation(4)
	addEquation(5)
	addEquation(6)
	addEquation(7)
	addEquation(8)
	addEquation(9)
	addEquation(10)
	addEquation(11)
	addEquation(12)
	addEquation(13)
	addEquation(14)
	addEquation(15)
	addEquation(16)
	addEquation(17)
	addEquation(18)
	addEquation(19)
	addEquation(20)
	addEquation(21)
end
function atributes(in::info_stream,_::Dict{Symbol,Any})
	fields::Dict{Symbol,Any}=Dict{Symbol,Any}()
	fields[:Pallete]=true
	fields[:Icon]="icon/Info_Stream"
	fields[:Brief]="Material stream information"
	fields[:Info]="
	This model should be used for middle streams when additional
	information about the stream is desired.

	Some of the additional informations calculated by this models are:
	 * Mass density
	 * Mass flow
	 * Mass compostions
	 * Specific volume
	 * Vapour fraction
	 * Volumetric flow
	 * Liquid and Vapour compositions
	 * Viscosity
	 * Heat Capacity
	 * Thermal Conductivity
	 * Temperature in Celsius Degrees
	"
	drive!(fields,_)
	return fields
end
info_stream(_::Dict{Symbol,Any})=begin
	newModel=info_stream()
	newModel.attributes=atributes(newModel,_)
	newModel
end


text:
using Parquet
using Test
using Random

if VERSION < v"1.3"
    using Missings: nonmissingtype
end

Random.seed!(1234567)

function test_write()
    N = 1000

    tbl = (
        int32 = rand(Int32, N),
        int64 = rand(Int64, N),
        float32 = rand(Float32, N),
        float64 = rand(Float64, N),
        bool = rand(Bool, N),
        string = [randstring(8) for i in 1:N],
        int32m = rand([missing, rand(Int32, 10)...], N),
        int64m = rand([missing, rand(Int64, 10)...], N),
        float32m = rand([missing, rand(Float32, 10)...], N),
        float64m = rand([missing, rand(Float64, 10)...], N),
        boolm = rand([missing, true, false], N),
        stringm = rand([missing, "abc", "def", "ghi"], N)
    )

    tmpfile = tempname()*".parquet"

    write_parquet(tmpfile, tbl)

    pf = ParFile(tmpfile; map_logical_types=true)

    # the file is very small so only one rowgroup
    col_chunks = columns(pf, 1)

    for (colnum, col_chunk) in enumerate(col_chunks)
        correct_vals = tbl[colnum]
        coltype = eltype(correct_vals)
        vals_from_file = values(pf, col_chunk)
        if Missing <: coltype
            @test ismissing.(correct_vals) == (vals_from_file[2] .== 0)
        end

        non_missing_vals = collect(skipmissing(correct_vals))

        if nonmissingtype(coltype) == String
            non_missing_vals_read = String.(vals_from_file[1][1:sum(vals_from_file[2])])
            @test all(non_missing_vals .== non_missing_vals_read)
        else
            non_missing_vals_read = vals_from_file[1][1:sum(vals_from_file[2])]
            @test all(non_missing_vals .== non_missing_vals_read)
        end
    end

    # test with BatchedColumnsCursor
    cc = Parquet.BatchedColumnsCursor(pf)
    vals, _ = iterate(cc)
    @test length(vals) == 12
    @test length(vals.boolm) == N
    for idx in 1:N
        @test ismissing(vals.boolm[idx]) == ismissing(tbl.boolm[idx])
        if !ismissing(vals.boolm[idx])
            @test vals.boolm[idx] == tbl.boolm[idx]
        end
    end

    # clean up
    close(pf)
end

test_write()


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

@doc raw"""PodSpec is a description of a pod.

    IoK8sApiCoreV1PodSpec(;
        activeDeadlineSeconds=nothing,
        affinity=nothing,
        automountServiceAccountToken=nothing,
        containers=nothing,
        dnsConfig=nothing,
        dnsPolicy=nothing,
        enableServiceLinks=nothing,
        ephemeralContainers=nothing,
        hostAliases=nothing,
        hostIPC=nothing,
        hostNetwork=nothing,
        hostPID=nothing,
        hostname=nothing,
        imagePullSecrets=nothing,
        initContainers=nothing,
        nodeName=nothing,
        nodeSelector=nothing,
        overhead=nothing,
        preemptionPolicy=nothing,
        priority=nothing,
        priorityClassName=nothing,
        readinessGates=nothing,
        restartPolicy=nothing,
        runtimeClassName=nothing,
        schedulerName=nothing,
        securityContext=nothing,
        serviceAccount=nothing,
        serviceAccountName=nothing,
        shareProcessNamespace=nothing,
        subdomain=nothing,
        terminationGracePeriodSeconds=nothing,
        tolerations=nothing,
        topologySpreadConstraints=nothing,
        volumes=nothing,
    )

    - activeDeadlineSeconds::Int64 : Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers. Value must be a positive integer.
    - affinity::IoK8sApiCoreV1Affinity : If specified, the pod's scheduling constraints
    - automountServiceAccountToken::Bool : AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.
    - containers::Vector{IoK8sApiCoreV1Container} : List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated.
    - dnsConfig::IoK8sApiCoreV1PodDNSConfig : Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy.
    - dnsPolicy::String : Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.
    - enableServiceLinks::Bool : EnableServiceLinks indicates whether information about services should be injected into pod's environment variables, matching the syntax of Docker links. Optional: Defaults to true.
    - ephemeralContainers::Vector{IoK8sApiCoreV1EphemeralContainer} : List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is alpha-level and is only honored by servers that enable the EphemeralContainers feature.
    - hostAliases::Vector{IoK8sApiCoreV1HostAlias} : HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts file if specified. This is only valid for non-hostNetwork pods.
    - hostIPC::Bool : Use the host's ipc namespace. Optional: Default to false.
    - hostNetwork::Bool : Host networking requested for this pod. Use the host's network namespace. If this option is set, the ports that will be used must be specified. Default to false.
    - hostPID::Bool : Use the host's pid namespace. Optional: Default to false.
    - hostname::String : Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value.
    - imagePullSecrets::Vector{IoK8sApiCoreV1LocalObjectReference} : ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod
    - initContainers::Vector{IoK8sApiCoreV1Container} : List of initialization containers belonging to the pod. Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
    - nodeName::String : NodeName is a request to schedule this pod onto a specific node. If it is non-empty, the scheduler simply schedules this pod onto that node, assuming that it fits resource requirements.
    - nodeSelector::Dict{String, String} : NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
    - overhead::Dict{String, IoK8sApimachineryPkgApiResourceQuantity} : Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. This field will be autopopulated at admission time by the RuntimeClass admission controller. If the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. The RuntimeClass admission controller will reject Pod create requests which have the overhead already set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. More info: https://git.k8s.io/enhancements/keps/sig-node/20190226-pod-overhead.md This field is alpha-level as of Kubernetes v1.16, and is only honored by servers that enable the PodOverhead feature.
    - preemptionPolicy::String : PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. This field is alpha-level and is only honored by servers that enable the NonPreemptingPriority feature.
    - priority::Int32 : The priority value. Various system components use this field to find the priority of the pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority.
    - priorityClassName::String : If specified, indicates the pod's priority. \"system-node-critical\" and \"system-cluster-critical\" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default.
    - readinessGates::Vector{IoK8sApiCoreV1PodReadinessGate} : If specified, all readiness gates will be evaluated for pod readiness. A pod is ready when all its containers are ready AND all conditions specified in the readiness gates have status equal to \"True\" More info: https://git.k8s.io/enhancements/keps/sig-network/0007-pod-ready%2B%2B.md
    - restartPolicy::String : Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
    - runtimeClassName::String : RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod.  If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the \"legacy\" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md This is a beta feature as of Kubernetes v1.14.
    - schedulerName::String : If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.
    - securityContext::IoK8sApiCoreV1PodSecurityContext : SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty.  See type description for default values of each field.
    - serviceAccount::String : DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. Deprecated: Use serviceAccountName instead.
    - serviceAccountName::String : ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
    - shareProcessNamespace::Bool : Share a single process namespace between all of the containers in a pod. When this is set containers will be able to view and signal processes from other containers in the same pod, and the first process in each container will not be assigned PID 1. HostPID and ShareProcessNamespace cannot both be set. Optional: Default to false.
    - subdomain::String : If specified, the fully qualified Pod hostname will be \"<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>\". If not specified, the pod will not have a domainname at all.
    - terminationGracePeriodSeconds::Int64 : Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.
    - tolerations::Vector{IoK8sApiCoreV1Toleration} : If specified, the pod's tolerations.
    - topologySpreadConstraints::Vector{IoK8sApiCoreV1TopologySpreadConstraint} : TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. This field is alpha-level and is only honored by clusters that enables the EvenPodsSpread feature. All topologySpreadConstraints are ANDed.
    - volumes::Vector{IoK8sApiCoreV1Volume} : List of volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes
"""
mutable struct IoK8sApiCoreV1PodSpec <: SwaggerModel
    activeDeadlineSeconds::Any # spec type: Union{ Nothing, Int64 } # spec name: activeDeadlineSeconds
    affinity::Any # spec type: Union{ Nothing, IoK8sApiCoreV1Affinity } # spec name: affinity
    automountServiceAccountToken::Any # spec type: Union{ Nothing, Bool } # spec name: automountServiceAccountToken
    containers::Any # spec type: Union{ Nothing, Vector{IoK8sApiCoreV1Container} } # spec name: containers
    dnsConfig::Any # spec type: Union{ Nothing, IoK8sApiCoreV1PodDNSConfig } # spec name: dnsConfig
    dnsPolicy::Any # spec type: Union{ Nothing, String } # spec name: dnsPolicy
    enableServiceLinks::Any # spec type: Union{ Nothing, Bool } # spec name: enableServiceLinks
    ephemeralContainers::Any # spec type: Union{ Nothing, Vector{IoK8sApiCoreV1EphemeralContainer} } # spec name: ephemeralContainers
    hostAliases::Any # spec type: Union{ Nothing, Vector{IoK8sApiCoreV1HostAlias} } # spec name: hostAliases
    hostIPC::Any # spec type: Union{ Nothing, Bool } # spec name: hostIPC
    hostNetwork::Any # spec type: Union{ Nothing, Bool } # spec name: hostNetwork
    hostPID::Any # spec type: Union{ Nothing, Bool } # spec name: hostPID
    hostname::Any # spec type: Union{ Nothing, String } # spec name: hostname
    imagePullSecrets::Any # spec type: Union{ Nothing, Vector{IoK8sApiCoreV1LocalObjectReference} } # spec name: imagePullSecrets
    initContainers::Any # spec type: Union{ Nothing, Vector{IoK8sApiCoreV1Container} } # spec name: initContainers
    nodeName::Any # spec type: Union{ Nothing, String } # spec name: nodeName
    nodeSelector::Any # spec type: Union{ Nothing, Dict{String, String} } # spec name: nodeSelector
    overhead::Any # spec type: Union{ Nothing, Dict{String, IoK8sApimachineryPkgApiResourceQuantity} } # spec name: overhead
    preemptionPolicy::Any # spec type: Union{ Nothing, String } # spec name: preemptionPolicy
    priority::Any # spec type: Union{ Nothing, Int32 } # spec name: priority
    priorityClassName::Any # spec type: Union{ Nothing, String } # spec name: priorityClassName
    readinessGates::Any # spec type: Union{ Nothing, Vector{IoK8sApiCoreV1PodReadinessGate} } # spec name: readinessGates
    restartPolicy::Any # spec type: Union{ Nothing, String } # spec name: restartPolicy
    runtimeClassName::Any # spec type: Union{ Nothing, String } # spec name: runtimeClassName
    schedulerName::Any # spec type: Union{ Nothing, String } # spec name: schedulerName
    securityContext::Any # spec type: Union{ Nothing, IoK8sApiCoreV1PodSecurityContext } # spec name: securityContext
    serviceAccount::Any # spec type: Union{ Nothing, String } # spec name: serviceAccount
    serviceAccountName::Any # spec type: Union{ Nothing, String } # spec name: serviceAccountName
    shareProcessNamespace::Any # spec type: Union{ Nothing, Bool } # spec name: shareProcessNamespace
    subdomain::Any # spec type: Union{ Nothing, String } # spec name: subdomain
    terminationGracePeriodSeconds::Any # spec type: Union{ Nothing, Int64 } # spec name: terminationGracePeriodSeconds
    tolerations::Any # spec type: Union{ Nothing, Vector{IoK8sApiCoreV1Toleration} } # spec name: tolerations
    topologySpreadConstraints::Any # spec type: Union{ Nothing, Vector{IoK8sApiCoreV1TopologySpreadConstraint} } # spec name: topologySpreadConstraints
    volumes::Any # spec type: Union{ Nothing, Vector{IoK8sApiCoreV1Volume} } # spec name: volumes

    function IoK8sApiCoreV1PodSpec(;activeDeadlineSeconds=nothing, affinity=nothing, automountServiceAccountToken=nothing, containers=nothing, dnsConfig=nothing, dnsPolicy=nothing, enableServiceLinks=nothing, ephemeralContainers=nothing, hostAliases=nothing, hostIPC=nothing, hostNetwork=nothing, hostPID=nothing, hostname=nothing, imagePullSecrets=nothing, initContainers=nothing, nodeName=nothing, nodeSelector=nothing, overhead=nothing, preemptionPolicy=nothing, priority=nothing, priorityClassName=nothing, readinessGates=nothing, restartPolicy=nothing, runtimeClassName=nothing, schedulerName=nothing, securityContext=nothing, serviceAccount=nothing, serviceAccountName=nothing, shareProcessNamespace=nothing, subdomain=nothing, terminationGracePeriodSeconds=nothing, tolerations=nothing, topologySpreadConstraints=nothing, volumes=nothing)
        o = new()
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("activeDeadlineSeconds"), activeDeadlineSeconds)
        setfield!(o, Symbol("activeDeadlineSeconds"), activeDeadlineSeconds)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("affinity"), affinity)
        setfield!(o, Symbol("affinity"), affinity)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("automountServiceAccountToken"), automountServiceAccountToken)
        setfield!(o, Symbol("automountServiceAccountToken"), automountServiceAccountToken)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("containers"), containers)
        setfield!(o, Symbol("containers"), containers)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("dnsConfig"), dnsConfig)
        setfield!(o, Symbol("dnsConfig"), dnsConfig)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("dnsPolicy"), dnsPolicy)
        setfield!(o, Symbol("dnsPolicy"), dnsPolicy)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("enableServiceLinks"), enableServiceLinks)
        setfield!(o, Symbol("enableServiceLinks"), enableServiceLinks)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("ephemeralContainers"), ephemeralContainers)
        setfield!(o, Symbol("ephemeralContainers"), ephemeralContainers)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("hostAliases"), hostAliases)
        setfield!(o, Symbol("hostAliases"), hostAliases)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("hostIPC"), hostIPC)
        setfield!(o, Symbol("hostIPC"), hostIPC)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("hostNetwork"), hostNetwork)
        setfield!(o, Symbol("hostNetwork"), hostNetwork)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("hostPID"), hostPID)
        setfield!(o, Symbol("hostPID"), hostPID)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("hostname"), hostname)
        setfield!(o, Symbol("hostname"), hostname)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("imagePullSecrets"), imagePullSecrets)
        setfield!(o, Symbol("imagePullSecrets"), imagePullSecrets)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("initContainers"), initContainers)
        setfield!(o, Symbol("initContainers"), initContainers)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("nodeName"), nodeName)
        setfield!(o, Symbol("nodeName"), nodeName)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("nodeSelector"), nodeSelector)
        setfield!(o, Symbol("nodeSelector"), nodeSelector)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("overhead"), overhead)
        setfield!(o, Symbol("overhead"), overhead)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("preemptionPolicy"), preemptionPolicy)
        setfield!(o, Symbol("preemptionPolicy"), preemptionPolicy)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("priority"), priority)
        setfield!(o, Symbol("priority"), priority)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("priorityClassName"), priorityClassName)
        setfield!(o, Symbol("priorityClassName"), priorityClassName)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("readinessGates"), readinessGates)
        setfield!(o, Symbol("readinessGates"), readinessGates)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("restartPolicy"), restartPolicy)
        setfield!(o, Symbol("restartPolicy"), restartPolicy)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("runtimeClassName"), runtimeClassName)
        setfield!(o, Symbol("runtimeClassName"), runtimeClassName)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("schedulerName"), schedulerName)
        setfield!(o, Symbol("schedulerName"), schedulerName)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("securityContext"), securityContext)
        setfield!(o, Symbol("securityContext"), securityContext)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("serviceAccount"), serviceAccount)
        setfield!(o, Symbol("serviceAccount"), serviceAccount)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("serviceAccountName"), serviceAccountName)
        setfield!(o, Symbol("serviceAccountName"), serviceAccountName)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("shareProcessNamespace"), shareProcessNamespace)
        setfield!(o, Symbol("shareProcessNamespace"), shareProcessNamespace)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("subdomain"), subdomain)
        setfield!(o, Symbol("subdomain"), subdomain)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("terminationGracePeriodSeconds"), terminationGracePeriodSeconds)
        setfield!(o, Symbol("terminationGracePeriodSeconds"), terminationGracePeriodSeconds)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("tolerations"), tolerations)
        setfield!(o, Symbol("tolerations"), tolerations)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("topologySpreadConstraints"), topologySpreadConstraints)
        setfield!(o, Symbol("topologySpreadConstraints"), topologySpreadConstraints)
        validate_property(IoK8sApiCoreV1PodSpec, Symbol("volumes"), volumes)
        setfield!(o, Symbol("volumes"), volumes)
        o
    end
end # type IoK8sApiCoreV1PodSpec

const _property_map_IoK8sApiCoreV1PodSpec = Dict{Symbol,Symbol}(Symbol("activeDeadlineSeconds")=>Symbol("activeDeadlineSeconds"), Symbol("affinity")=>Symbol("affinity"), Symbol("automountServiceAccountToken")=>Symbol("automountServiceAccountToken"), Symbol("containers")=>Symbol("containers"), Symbol("dnsConfig")=>Symbol("dnsConfig"), Symbol("dnsPolicy")=>Symbol("dnsPolicy"), Symbol("enableServiceLinks")=>Symbol("enableServiceLinks"), Symbol("ephemeralContainers")=>Symbol("ephemeralContainers"), Symbol("hostAliases")=>Symbol("hostAliases"), Symbol("hostIPC")=>Symbol("hostIPC"), Symbol("hostNetwork")=>Symbol("hostNetwork"), Symbol("hostPID")=>Symbol("hostPID"), Symbol("hostname")=>Symbol("hostname"), Symbol("imagePullSecrets")=>Symbol("imagePullSecrets"), Symbol("initContainers")=>Symbol("initContainers"), Symbol("nodeName")=>Symbol("nodeName"), Symbol("nodeSelector")=>Symbol("nodeSelector"), Symbol("overhead")=>Symbol("overhead"), Symbol("preemptionPolicy")=>Symbol("preemptionPolicy"), Symbol("priority")=>Symbol("priority"), Symbol("priorityClassName")=>Symbol("priorityClassName"), Symbol("readinessGates")=>Symbol("readinessGates"), Symbol("restartPolicy")=>Symbol("restartPolicy"), Symbol("runtimeClassName")=>Symbol("runtimeClassName"), Symbol("schedulerName")=>Symbol("schedulerName"), Symbol("securityContext")=>Symbol("securityContext"), Symbol("serviceAccount")=>Symbol("serviceAccount"), Symbol("serviceAccountName")=>Symbol("serviceAccountName"), Symbol("shareProcessNamespace")=>Symbol("shareProcessNamespace"), Symbol("subdomain")=>Symbol("subdomain"), Symbol("terminationGracePeriodSeconds")=>Symbol("terminationGracePeriodSeconds"), Symbol("tolerations")=>Symbol("tolerations"), Symbol("topologySpreadConstraints")=>Symbol("topologySpreadConstraints"), Symbol("volumes")=>Symbol("volumes"))
const _property_types_IoK8sApiCoreV1PodSpec = Dict{Symbol,String}(Symbol("activeDeadlineSeconds")=>"Int64", Symbol("affinity")=>"IoK8sApiCoreV1Affinity", Symbol("automountServiceAccountToken")=>"Bool", Symbol("containers")=>"Vector{IoK8sApiCoreV1Container}", Symbol("dnsConfig")=>"IoK8sApiCoreV1PodDNSConfig", Symbol("dnsPolicy")=>"String", Symbol("enableServiceLinks")=>"Bool", Symbol("ephemeralContainers")=>"Vector{IoK8sApiCoreV1EphemeralContainer}", Symbol("hostAliases")=>"Vector{IoK8sApiCoreV1HostAlias}", Symbol("hostIPC")=>"Bool", Symbol("hostNetwork")=>"Bool", Symbol("hostPID")=>"Bool", Symbol("hostname")=>"String", Symbol("imagePullSecrets")=>"Vector{IoK8sApiCoreV1LocalObjectReference}", Symbol("initContainers")=>"Vector{IoK8sApiCoreV1Container}", Symbol("nodeName")=>"String", Symbol("nodeSelector")=>"Dict{String, String}", Symbol("overhead")=>"Dict{String, IoK8sApimachineryPkgApiResourceQuantity}", Symbol("preemptionPolicy")=>"String", Symbol("priority")=>"Int32", Symbol("priorityClassName")=>"String", Symbol("readinessGates")=>"Vector{IoK8sApiCoreV1PodReadinessGate}", Symbol("restartPolicy")=>"String", Symbol("runtimeClassName")=>"String", Symbol("schedulerName")=>"String", Symbol("securityContext")=>"IoK8sApiCoreV1PodSecurityContext", Symbol("serviceAccount")=>"String", Symbol("serviceAccountName")=>"String", Symbol("shareProcessNamespace")=>"Bool", Symbol("subdomain")=>"String", Symbol("terminationGracePeriodSeconds")=>"Int64", Symbol("tolerations")=>"Vector{IoK8sApiCoreV1Toleration}", Symbol("topologySpreadConstraints")=>"Vector{IoK8sApiCoreV1TopologySpreadConstraint}", Symbol("volumes")=>"Vector{IoK8sApiCoreV1Volume}")
Base.propertynames(::Type{ IoK8sApiCoreV1PodSpec }) = collect(keys(_property_map_IoK8sApiCoreV1PodSpec))
Swagger.property_type(::Type{ IoK8sApiCoreV1PodSpec }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_IoK8sApiCoreV1PodSpec[name]))}
Swagger.field_name(::Type{ IoK8sApiCoreV1PodSpec }, property_name::Symbol) =  _property_map_IoK8sApiCoreV1PodSpec[property_name]

function check_required(o::IoK8sApiCoreV1PodSpec)
    (getproperty(o, Symbol("containers")) === nothing) && (return false)
    true
end

function validate_property(::Type{ IoK8sApiCoreV1PodSpec }, name::Symbol, val)
end


text:
using HierarchicalClusteringOT
using Test

@testset "HierarchicalClusteringOT.jl" begin
    # Write your tests here.
end


text:
__precompile__()
module ArviZ

using Base: @__doc__
using Requires
using REPL
using NamedTupleTools
using DataFrames

using PyCall
using Conda
using PyPlot

import Base:
    convert,
    get,
    getproperty,
    hash,
    haskey,
    iterate,
    length,
    propertynames,
    setindex,
    show,
    write,
    +
import Base.Docs: getdoc
using StatsBase: StatsBase
import StatsBase: summarystats
import Markdown: @doc_str
import PyCall: PyObject

# Exports

## Plots
export plot_autocorr,
    plot_bpv,
    plot_compare,
    plot_density,
    plot_dist,
    plot_dist_comparison,
    plot_elpd,
    plot_energy,
    plot_ess,
    plot_forest,
    plot_hdi,
    plot_kde,
    plot_khat,
    plot_loo_pit,
    plot_mcse,
    plot_pair,
    plot_parallel,
    plot_posterior,
    plot_ppc,
    plot_rank,
    plot_separation,
    plot_trace,
    plot_violin

## Stats
export summarystats, compare, hdi, loo, loo_pit, psislw, r2_score, waic

## Diagnostics
export bfmi, ess, rhat, mcse

## Stats utils
export autocov, autocorr, make_ufunc, wrap_xarray_ufunc

## Data
export InferenceData,
    convert_to_inference_data,
    load_arviz_data,
    to_netcdf,
    from_netcdf,
    from_namedtuple,
    from_dict,
    from_cmdstan,
    from_mcmcchains,
    from_samplechains,
    concat,
    concat!

## Utils
export with_interactive_backend

## rcParams
export rcParams, with_rc_context

const _min_arviz_version = v"0.11.3"
const arviz = PyNULL()
const xarray = PyNULL()
const bokeh = PyNULL()
const pandas = PyNULL()
const _rcParams = PyNULL()

include("setup.jl")

# Load ArviZ once at precompilation time for docstringS
copy!(arviz, import_arviz())
check_needs_update(; update=false)
const _precompile_arviz_version = arviz_version()

function __init__()
    initialize_arviz()
    @require MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" begin
        import .MonteCarloMeasurements: AbstractParticles
        include("particles.jl")
    end
    @require SampleChains = "754583d1-7fc4-4dab-93b5-5eaca5c9622e" begin
        include("samplechains.jl")
    end
    @require MCMCChains = "c7f686f2-ff18-58e9-bc7b-31028e88f75d" begin
        import .MCMCChains: Chains, sections
        include("mcmcchains.jl")
    end
    return nothing
end

include("utils.jl")
include("rcparams.jl")
include("dataset.jl")
include("data.jl")
include("diagnostics.jl")
include("plots.jl")
include("bokeh.jl")
include("stats.jl")
include("stats_utils.jl")
include("namedtuple.jl")

end # module


text:
function create_example_project(dst_example_dir)
    mkpath(dst_example_dir)

    lyceumdocs_project = Pkg.TOML.parsefile(joinpath(REPO_DIR, "Project.toml"))
    lyceumdocs_manifest = Pkg.TOML.parsefile(joinpath(REPO_DIR, "Manifest.toml"))

    # copy project skeleton over and setup project/manifest
    example_project = Pkg.TOML.parsefile(joinpath(EXAMPLE_DIR, "Project.toml"))
    for k in keys(example_project)
        if !(k in ("name", "uuid", "deps"))
            delete!(example_project, k)
        end
    end
    example_project["compat"] = Dict{String,Any}()

    # sync deps/compat with LyceumDocs
    example_project["version"] = lyceumdocs_project["version"]
    example_project["compat"]["julia"] = lyceumdocs_project["compat"]["julia"]
    specs = Pkg.Types.PackageSpec[]
    for (name, uuid) in pairs(example_project["deps"])
        if haskey(lyceumdocs_project["compat"], name)
            example_project["compat"][name] = lyceumdocs_project["compat"][name]
        end
        if haskey(lyceumdocs_manifest, name)
            idx = findfirst(x -> x["uuid"] == uuid, lyceumdocs_manifest[name])
            info = lyceumdocs_manifest[name][idx]
            haskey(info, "path") && @warn "Local path detected for $name"
            if haskey(info, "repo-rev")
                rev = info["repo-rev"]
                @warn "repo-rev $rev detected for $name"
                spec = PackageSpec(name = name, uuid = uuid, rev = rev)
                push!(specs, spec)
            end
        end
    end

    # write LyceumExamples to dst_example_dir,
    # overwriting project and deleting manifest if they exist
    DevTools.cpinto(EXAMPLE_DIR, dst_example_dir)
    open(joinpath(dst_example_dir, "Project.toml"), "w") do io
        Pkg.TOML.print(io, example_project)
    end
    rm(joinpath(dst_example_dir, "Manifest.toml"), force = true)

    curdir = pwd()
    curproj = Base.active_project()
    try
        cd(dst_example_dir)
        Pkg.activate(".")
        Pkg.add(specs)
        Pkg.instantiate()
    finally
        cd(curdir)
        Pkg.activate(curproj)
    end
end

function bundle_examples()
    Pkg.PlatformEngines.probe_platform_engines!()
    paths = map(p -> joinpath(STAGING_DIR, p), PATHS)
    mktempdir() do tmpdir
        proj = mkdir(joinpath(tmpdir, basename(EXAMPLE_DIR)))
        create_example_project(proj)
        isdir(paths.script) && cp(paths.script, joinpath(proj, basename(paths.script)))
        isdir(paths.notebook) && cp(paths.notebook, joinpath(proj, basename(paths.notebook)))
        run(Pkg.PlatformEngines.gen_package_cmd(tmpdir, paths.examples_tarfile))
    end
end


text:
#
# Simple example demonstring use a Yao circuit with QX framework
#

using YaoQX

# create a YaoBlocks circuit
circ = ghz(3)

# create a quantum register and apply the circuit
reg = QXReg(3)
apply!(reg, circ)

# get 10 measurements
measure(reg; nshots=10)


text:
#=
run from the benchmarks folder
~/julia/julia run.jl &> raw/bench.txt
=#

include(joinpath(@__DIR__, "..", "examples", "Examples.jl"))
using Test

# uncomment path for writing to results CSV
# csv = nothing
csv = joinpath(mkpath(joinpath(@__DIR__, "raw")), "bench.csv")

import MathOptInterface
const MOI = MathOptInterface

import Gurobi
gurobi = MOI.OptimizerWithAttributes(
    Gurobi.Optimizer,
    MOI.Silent() => true,
    "IntFeasTol" => 1e-9,
    "FeasibilityTol" => 1e-9,
    "MIPGap" => 1e-9,
    "DualReductions" => 0, # fix infeasible or unbounded statuses
    "InfUnbdInfo" => 1, # get ray of the primal OA continuous relaxation
)

# default MOIPajarito options
options = (;
    iteration_limit = 100000,
    time_limit = 600.0,
    verbose = true,
    oa_solver = gurobi,
    use_iterative_method = true,
    use_init_fixed_oa = false,
)

# instance sets to run
inst_sets = [
    # test instances (comment out usually):
    # "test",
    # generic formulations:
    "nat",
    "noext",
    "ext",
    # knapsack:
    "cont_geo",
    "cont_noext_geo",
    "cont_log",
    "cont_noext_log",
    "cont_inv",
    "cont_noext_inv",
    "nat_geo",
    "noext_geo",
    "ext_geo",
    # experiment design:
    "nat_rtdet",
    "ext_rtdet",
    "nat_entr",
    "ext_entr",
    # PWL formulations:
    "sos2",
    "logib",
    "cc",
]

# list of names of JuMP examples to run
examples = [
    # PSD:
    "completablepsd",
    # WSOS:
    "polyfacilitylocation",
    "polyregression",
    "twostagestochastic",
    # spectral norm:
    "matrixcompletion",
    "matrixdecomposition",
    "matrixregression",
    # spectral function:
    "experimentdesign",
    "inversecovariance",
    "knapsack",
    "vectorregression",
    # MIP formulations:
    "ballpacking",
    "modulardesign",
]

skip_limit = false
# skip_limit = true

Examples.load_examples(examples)

function run_benchmarks()
    @testset verbose = true "benchmarks" begin
        Examples.run_examples(examples, inst_sets, options, csv, skip_limit)
    end
    println()
    return
end

run_benchmarks()


text:
module HelloTests

include("mpiexec.jl")
run_mpi_driver(procs=3,file="driver_hello.jl")

end # module


text:
module DataWrangling

export
       # Coarse graining
       coarse_grain,

       # Feature scaling
       AbstractFeatureScaling, ZeroMeanUnitVarianceScaling, MinMaxScaling, scale, unscale,

       # Convective adjustment
       convective_adjust!,

       # Animations
       animate_gif

using Statistics
using OrderedCollections
using Plots

include("coarse_graining.jl")
include("feature_scaling.jl")
include("convective_adjust.jl")
include("animate_gif.jl")

end


text:
"""
    QuadratureVI(;ϵ::T=1e-5, nGaussHermite::Integer=20, clipping=Inf, natural::Bool=true, optimiser=Momentum(0.0001))

Variational Inference solver by approximating gradients via numerical integration via Quadrature

## Keyword arguments
- `ϵ::T` : convergence criteria
- `nGaussHermite::Int` : Number of points for the integral estimation
- `clipping::Real` : Limit the gradients values to avoid overshooting
- `natural::Bool` : Use natural gradients
- `optimiser` : Optimiser used for the variational updates. Should be an Optimiser object from the [Flux.jl](https://github.com/FluxML/Flux.jl) library, see list here [Optimisers](https://fluxml.ai/Flux.jl/stable/training/optimisers/) and on [this list](https://github.com/theogf/AugmentedGaussianProcesses.jl/tree/master/src/inference/optimisers.jl). Default is `Momentum(0.0001)`
"""
mutable struct QuadratureVI{T,N,Tx,Ty} <: NumericalVI{T}
    nPoints::Int # Number of points for the quadrature
    nodes::Vector{T} # Nodes locations
    weights::Vector{T} # Weights for each node
    clipping::T # Clipping value of the gradient
    ϵ::T #Convergence criteria
    nIter::Integer #Number of steps performed
    stoch::Bool #Use of mini-batches
    nSamples::Int #Number of samples of the data
    nMinibatch::Int #Size of mini-batches
    ρ::T #Stochastic Coefficient
    NaturalGradient::Bool
    HyperParametersUpdated::Bool # Flag for updating kernel matrices
    vi_opt::NTuple{N,NVIOptimizer}
    MBIndices::Vector{Int} #Indices of the minibatch
    xview::Tx
    yview::Ty

    function QuadratureVI{T}(
        ϵ::T,
        nPoints::Integer,
        optimiser,
        Stochastic::Bool,
        clipping::Real,
        nMinibatch::Int,
        natural::Bool,
    ) where {T}
        return new{T,1,Vector{T},Vector{T}}(
            nPoints,
            [],
            [],
            clipping,
            ϵ,
            0,
            Stochastic,
            0,
            nMinibatch,
            one(T),
            natural,
            true,
            (NVIOptimizer{T}(0, 0, optimiser),),
        )
    end

    function QuadratureVI{T}(
        ϵ::T,
        Stochastic::Bool,
        nPoints::Int,
        clipping::Real,
        nFeatures::Vector{<:Int},
        nSamples::Int,
        nMinibatch::Int,
        nLatent::Int,
        optimiser,
        natural::Bool,
        xview::Tx,
        yview::Ty,
    ) where {T,Tx,Ty}
        gh = gausshermite(nPoints)
        vi_opts = ntuple(
            i -> NVIOptimizer{T}(nFeatures[i], nMinibatch[i], optimiser), nLatent
        )
        return new{T,nLatent,Tx,Ty}(
            nPoints,
            gh[1] .* sqrt2,
            gh[2] ./ sqrtπ,
            clipping,
            ϵ,
            0,
            Stochastic,
            nSamples,
            nMinibatch,
            T(nSamples / nMinibatch),
            natural,
            true,
            vi_opts,
            1:nMinibatch,
            xview,
            yview,
        )
    end
end

function QuadratureVI(;
    ϵ::T=1e-5,
    nGaussHermite::Integer=100,
    optimiser=Momentum(1e-5),
    clipping::Real=0.0,
    natural::Bool=true,
) where {T<:Real}
    return QuadratureVI{T}(ϵ, nGaussHermite, optimiser, false, clipping, 1, natural)
end

"""
    QuadratureSVI(nMinibatch::Int; ϵ::T=1e-5, nGaussHermite::Int=20, clipping=Inf, natural=true, optimiser=Momentum(0.0001))

Stochastic Variational Inference solver by approximating gradients via numerical integration via Gaussian Quadrature.
See [`QuadratureVI`](@ref) for a more detailed reference.

## Arguments
-`nMinibatch::Integer` : Number of samples per mini-batches

## Keyword arguments
- `ϵ::T` : convergence criteria, which can be user defined
- `nGaussHermite::Int` : Number of points for the integral estimation (for the QuadratureVI)
- `natural::Bool` : Use natural gradients
- `optimiser` : Optimiser used for the variational updates. Should be an Optimiser object from the [Flux.jl](https://github.com/FluxML/Flux.jl) library, see list here [Optimisers](https://fluxml.ai/Flux.jl/stable/training/optimisers/) and on [this list](https://github.com/theogf/AugmentedGaussianProcesses.jl/tree/master/src/inference/optimisers.jl). Default is `Momentum(0.0001)`
"""
function QuadratureSVI(
    nMinibatch::Integer;
    ϵ::T=1e-5,
    nGaussHermite::Integer=100,
    optimiser=Momentum(1e-5),
    clipping::Real=0.0,
    natural=true,
) where {T<:Real}
    return QuadratureVI{T}(ϵ, nGaussHermite, optimiser, true, clipping, nMinibatch, natural)
end

function tuple_inference(
    i::QuadratureVI{T},
    nLatent::Int,
    nFeatures::Vector{<:Int},
    nSamples::Int,
    nMinibatch::Int,
    xview,
    yview,
) where {T}
    return QuadratureVI{T}(
        conv_crit(i),
        isStochastic(i),
        i.nPoints,
        i.clipping,
        nFeatures,
        nSamples,
        nMinibatch,
        nLatent,
        i.vi_opt[1].optimiser,
        i.NaturalGradient,
        xview,
        yview,
    )
end

function expec_loglikelihood(
    l::AbstractLikelihood, i::QuadratureVI, y, μ::AbstractVector, diagΣ::AbstractVector
)
    return mapreduce(apply_quad, :+, y, μ, diagΣ, i, l)
end

function apply_quad(y::Real, μ::Real, σ²::Real, i::QuadratureVI, l::AbstractLikelihood)
    xs = i.nodes * sqrt(σ²) .+ μ
    return dot(i.weights, loglikelihood.(Ref(l), y, xs))
    # return mapreduce((w, x) -> w * Distributions.loglikelihood(l, y, x), +, i.weights, xs)# loglikelihood.(l, y, x))
end

function grad_expectations!(m::AbstractGP{T,L,<:QuadratureVI}) where {T,L}
    y = yview(m)
    for (gp, opt) in zip(m.f, get_opt(inference(m)))
        μ = mean_f(gp)
        Σ = var_f(gp)
        for i in 1:nMinibatch(inference(m))
            opt.ν[i], opt.λ[i] = grad_quad(likelihood(m), y[i], μ[i], Σ[i], inference(m))
        end
    end
end

# Compute the first and second derivative of the log-likelihood using the quadrature nodes
function grad_quad(
    l::AbstractLikelihood{T}, y::Real, μ::Real, σ²::Real, i::AbstractInference
) where {T<:Real}
    x = i.nodes * sqrt(max(σ², zero(T))) .+ μ
    Edloglike = dot(i.weights, ∇loglikehood.(l, y, x))
    Ed²loglike = dot(i.weights, hessloglikehood.(l, y, x))
    if i.clipping != 0
        return (
            abs(Edloglike) > i.clipping ? sign(Edloglike) * i.clipping : -Edloglike::T,
            abs(Ed²loglike) > i.clipping ? sign(Ed²loglike) * i.clipping : -Ed²loglike::T,
        )
    else
        return -Edloglike::T, Ed²loglike::T
    end
end


text:
using Nullables

# depends on: scenes.jl

###############
# Generic RRT #
###############

struct RRTNode{C,U}
    conf::C
    # the previous configuration and the control needed to produce this node's
    # configuration from the previous configuration may be null if it is the
    # root node
    parent::Nullable{RRTNode{C,U}}
    control::Nullable{U}
    cost_from_start::Float64 # cost (e.g. distance) of moving from start to us
end

mutable struct RRTTree{C,U}
    nodes::Array{RRTNode{C,U}, 1}
end

function RRTTree(root_conf::C, ::Type{U}) where {C,U}
    nodes = Array{RRTNode{C,U},1}()
    push!(nodes, RRTNode(root_conf,
        Nullable{RRTNode{C,U}}(), Nullable{U}(), 0.0))
    RRTTree(nodes)
end

function Base.show(io::IO, tree::RRTTree{C,U}) where {C,U}
    write(io, "RRTTree with $(length(tree.nodes)) nodes")
end

function add_node!(tree::RRTTree{C,U}, parent::RRTNode{C,U},
                   new_conf::C, control::U,
                   cost_from_start::Float64) where {C,U}
    node = RRTNode(new_conf,
        Nullable{RRTNode{C,U}}(parent), Nullable{U}(control),
        cost_from_start)
    push!(tree.nodes, node)
    return node
end

root(tree::RRTTree{C,U}) where {C,U} = tree.nodes[1]

abstract type RRTScheme{C,U} end

function nearest_neighbor(scheme::RRTScheme{C,U}, conf::C,
                               tree::RRTTree{C,U}) where {C,U}
    nearest::RRTNode{C,U} = root(tree)
    best_dist::Float64 = dist(nearest.conf, conf)
    for node::RRTNode{C,U} in tree.nodes
        d = dist(node.conf, conf)
        if d < best_dist
            best_dist = d
            nearest = node
        end
    end
    nearest
end

struct SelectControlResult{C,U}
    start_conf::C
    new_conf::C
    control::U
    failed::Bool # new_conf is undefined in this case
    cost::Float64 # cost of this control action (e.g. distance)
end

function rrt(scheme::RRTScheme{C,U}, init::C, iters::Int, dt::Float64) where {C,U}
    tree = RRTTree(init, U) # init is the root of tree
    for iter=1:iters
        rand_conf::C = random_config(scheme)
        near_node::RRTNode{C,U} = nearest_neighbor(scheme, rand_conf, tree)
        result = select_control(scheme, rand_conf, near_node.conf, dt)
        if !result.failed
            cost_from_start = near_node.cost_from_start + result.cost
            add_node!(tree, near_node, result.new_conf, result.control, cost_from_start)
        end
    end
    tree
end

##############################
# RRT for holonomic 2D point #
##############################

struct HolonomicPointRRTScheme <: RRTScheme{Point,Point}
    scene::Scene
end

function random_config(scheme::HolonomicPointRRTScheme)
    x = rand() * (scheme.scene.xmax - scheme.scene.xmin) + scheme.scene.xmin
    y = rand() * (scheme.scene.ymax - scheme.scene.ymin) + scheme.scene.ymin
    Point(x, y)
end

function select_control(scheme::HolonomicPointRRTScheme,
                        target_conf::Point, start_conf::Point, dt::Float64)

    dist_to_target = dist(start_conf, target_conf)
    diff = Point(target_conf.x - start_conf.x, target_conf.y - start_conf.y)
    distance_to_move = min(dt, dist_to_target)
    scale = distance_to_move / dist_to_target
    control = Point(scale * diff.x, scale * diff.y)

    obstacles = scheme.scene.obstacles

    # go in the direction of target_conf from start_conf
    new_conf = Point(start_conf.x + control.x, start_conf.y + control.y)

    # test the obstacles
    failed = false
    for obstacle in obstacles
        if intersects_path(obstacle, start_conf, new_conf)
            # NOTE: could do more intelligent things like backtrack until you succeed
            failed = true
            break
        end
    end
    cost = distance_to_move
    SelectControlResult(start_conf, new_conf, control, failed, cost)
end

################
# path planner #
################

struct PlannerParams
    rrt_iters::Int
    rrt_dt::Float64 # the maximum proposal distance
    refine_iters::Int
    refine_std::Float64
end

struct Path
    start::Point
    goal::Point
    points::Array{Point,1}
end

function concatenate(a::Path, b::Path)
    if a.goal.x != b.start.x || a.goal.y != b.start.y
        error("goal of first path muts be start of second path")
    end
    points = Array{Point,1}()
    for point in a.points
        push!(points, point)
    end
    for point in b.points[2:end]
        push!(points, point)
    end
    @assert points[1].x == a.start.x
    @assert points[1].y == a.start.y
    @assert points[end].x == b.goal.x
    @assert points[end].y == b.goal.y
    Path(a.start, b.goal, points)
end

"""
Remove intermediate nodes that are not necessary, so that refinement
optimization is a lower-dimensional optimization problem.
"""
function simplify_path(scene::Scene, original::Path)
    new_points = Array{Point,1}()
    push!(new_points, original.start)
    for i=2:length(original.points) - 1
        if !line_of_site(scene, new_points[end], original.points[i + 1])
            push!(new_points, original.points[i])
        end
    end
    @assert line_of_site(scene, new_points[end], original.goal)
    push!(new_points, original.goal)
    Path(original.start, original.goal, new_points)
end

"""
Optimize the path to minimize its length while avoiding obstacles in the scene.
"""
function refine_path(scene::Scene, original::Path, iters::Int, std::Float64)
    # do stochastic optimization
    new_points = deepcopy(original.points)
    num_interior_points = length(original.points) -2
    if num_interior_points == 0
        return original
    end
    for i=1:iters
        point_idx = 2 + (i % num_interior_points)
        @assert point_idx > 1 # not start
        @assert point_idx < length(original.points) # not goal
        prev_point = new_points[point_idx-1]
        point = new_points[point_idx]
        next_point = new_points[point_idx+1]
        adjusted = Point(point.x + randn() * std, point.y + randn() * std)
        cur_dist = dist(prev_point, point) + dist(point, next_point)
        ok_backward = line_of_site(scene, prev_point, adjusted)
        ok_forward = line_of_site(scene, adjusted, next_point)
        if ok_backward && ok_forward
            new_dist = dist(prev_point, adjusted) + dist(adjusted, next_point)
            if new_dist < cur_dist
                # accept the change
                new_points[point_idx] = adjusted
            end
        end
    end
    Path(original.start, original.goal, new_points)
end

function optimize_path(scene::Scene, original::Path, refine_iters::Int, refine_std::Float64)
    #simplified = simplify_path(scene, original) # TODO?
    refined = refine_path(scene, original, refine_iters, refine_std)
    refined
end

"""
Plan path from start to goal that avoids obstacles in the scene.
"""
function plan_path(start::Point, goal::Point, scene::Scene,
                   params::PlannerParams=PlannerParams(2000, 3.0, 10000, 1.))
    scheme = HolonomicPointRRTScheme(scene)
    tree = rrt(scheme, start, params.rrt_iters, params.rrt_dt)

    # find the best path along the tree to the goal, if one exists
    best_node = tree.nodes[1]
    min_cost = Inf
    path_found = false
    for node in tree.nodes
        # check for line-of-site to the goal
        clear_path = line_of_site(scene, node.conf, goal)
        cost = node.cost_from_start + (clear_path ? dist(node.conf, goal) : Inf)
        if cost < min_cost
            path_found = true
            best_node = node
            min_cost = cost
        end
    end

    local path::Nullable{Path}
    if path_found
        # extend the tree to the goal configuration
        control = Point(goal.x - best_node.conf.x, goal.y - best_node.conf.y)
        goal_node = add_node!(tree, best_node, goal, control, min_cost)
        points = Array{Point,1}()
        node::RRTNode{Point,Point} = goal_node
        push!(points, node.conf)
        # the path will contain the start and goal
        while !isnull(node.parent)
            node = get(node.parent)
            push!(points, node.conf)
        end
        @assert points[end] == start # the start point
        @assert points[1] == goal
        path = Nullable{Path}(Path(start, goal, reverse(points)))
    else
        path = Nullable{Path}()
    end

    local optimized_path::Nullable{Path}
    if path_found
        optimized_path = Nullable{Path}(optimize_path(scene, get(path),
                                                      params.refine_iters, params.refine_std))
    else
        optimized_path = Nullable{Path}()
    end
    return optimized_path
end

function compute_distances_from_start(path::Path)
    distances_from_start = Vector{Float64}(undef, length(path.points))
    distances_from_start[1] = 0.0
    for i=2:length(path.points)
        distances_from_start[i] = distances_from_start[i-1] + dist(path.points[i-1], path.points[i])
    end
    return distances_from_start
end

"""
Sample the location of a walk along a path at given time points, for a fixed speed.
"""
function walk_path(path::Path, speed::Float64, times::Array{Float64,1})
    distances_from_start = compute_distances_from_start(path)
    locations = Vector{Point}(undef, length(times))
    locations[1] = path.points[1]
    for (time_idx, t) in enumerate(times)
        if t < 0.0
            error("times must be positive")
        end
        desired_distance = t * speed
        used_up_time = false
        # NOTE: can be improved (iterate through path points along with times)
        for i=2:length(path.points)
            prev = path.points[i-1]
            cur = path.points[i]
            dist_to_prev = dist(prev, cur)
            if distances_from_start[i] >= desired_distance
                # we overshot, the location is between i-1 and i
                overshoot = distances_from_start[i] - desired_distance
                @assert overshoot <= dist_to_prev
                past_prev = dist_to_prev - overshoot
                frac = past_prev / dist_to_prev
                locations[time_idx] = Point(prev.x * (1. - frac) + cur.x * frac,
                                     prev.y * (1. - frac) + cur.y * frac)
                used_up_time = true
                break
            end
        end
        if !used_up_time
            # sit at the goal indefinitely
            locations[time_idx] = path.goal
        end
    end
    locations
end

function walk_path(path::Path, distances_from_start::Vector{Float64}, dist::Float64)
    if dist <= 0.
        return path.points[1]
    end
    if dist >= distances_from_start[end]
        return path.points[end]
    end
    # dist > 0 and dist < dist-to-last-point
    path_point_index = 0
    for i=1:length(distances_from_start)
        path_point_index += 1
        if dist < distances_from_start[path_point_index]
            break
        end
    end
    @assert dist < distances_from_start[path_point_index]
    path_point_index -= 1
    @assert path_point_index > 0
    dist_from_path_point = dist - distances_from_start[path_point_index]
    dist_between_points = distances_from_start[path_point_index + 1] - distances_from_start[path_point_index]
    fraction_next = dist_from_path_point / dist_between_points
    point::Point = (fraction_next * path.points[path_point_index + 1]
           + (1. - fraction_next) * path.points[path_point_index])
    return point
end

max_stars_repo_name: georgematheos/Gen

max_issues_repo_name: georgematheos/Gen

max_forks_repo_name: georgematheos/Gen


text:
@doc raw"""
    HeteroscedasticLikelihood(λ::T=1.0)->HeteroscedasticGaussianLikelihood

## Arguments
- `λ::Real` : The maximum precision possible (this is optimized during training)

---

Gaussian with heteroscedastic noise given by another gp:
```math
    p(y|f,g) = \mathcal{N}(y|f,(\lambda \sigma(g))^{-1})
```
Where ``\sigma`` is the logistic function

The augmentation is not trivial and will be described in a future paper
"""
HeteroscedasticLikelihood(λ::Real) = HeteroscedasticGaussianLikelihood(InvScaledLogistic(λ))

struct InvScaledLogistic{T} <: AbstractLink
    λ::Vector{T}
end

InvScaledLogistic(λ::Real) = InvScaledLogistic([λ])

(l::InvScaledLogistic)(f::Real) = inv(l.λ[1] * logistic(f))

function implemented(
    ::HeteroscedasticGaussianLikelihood{<:InvScaledLogistic},
    ::Union{<:AnalyticVI,<:GibbsSampling},
)
    return true
end

function (l::HeteroscedasticGaussianLikelihood)(f, y::Real)
    return pdf(l(f), y)
end

function Distributions.loglikelihood(
    l::HeteroscedasticGaussianLikelihood, f::AbstractVector, y
)
    return logpdf(l(f), y)
end

function Base.show(io::IO, ::HeteroscedasticGaussianLikelihood)
    return print(io, "Gaussian likelihood with heteroscedastic noise")
end

n_latent(::HeteroscedasticGaussianLikelihood) = 2

function init_local_vars(
    ::HeteroscedasticGaussianLikelihood{<:InvScaledLogistic},
    batchsize::Int,
    T::DataType=Float64,
)
    return (;
        c=ones(T, batchsize), # Sqrt of expectation of g^2
        ϕ=ones(T, batchsize), # Expectation of (y - f)^2 / 2
        γ=ones(T, batchsize), # Expectation of q(n)
        θ=ones(T, batchsize), # Expectation of q(ω|n)
        σg=ones(T, batchsize), # Approximation of the expectation of σ(-g)
    )
end

function compute_proba(
    l::HeteroscedasticGaussianLikelihood,
    μ::AbstractVector{<:AbstractVector},
    Σ::AbstractVector{<:AbstractVector},
)
    return μ[1], Σ[1] .+ l.invlink.(μ[2])
end

function local_updates!(
    local_vars,
    l::HeteroscedasticGaussianLikelihood,
    y::AbstractVector,
    μ::NTuple{2,<:AbstractVector},
    diagΣ::NTuple{2,<:AbstractVector},
)
    # gp[1] is f and gp[2] is g (for approximating the noise)
    λ = only(l.invlink.λ)
    map!(local_vars.ϕ, μ[1], diagΣ[1], y) do μ, σ², y
        (abs2(μ - y) + σ²) / 2 # E[(f-y)^2/2]
    end
    map!(sqrt_expec_square, local_vars.c, μ[2], diagΣ[2]) # √E[g^2]
    map!(local_vars.σg, μ[2], local_vars.c) do μ, c
        safe_expcosh(-μ / 2, c / 2) / 2 # ≈ E[σ(-g)]
    end
    map!(local_vars.γ, local_vars.ϕ, local_vars.σg) do ϕ, σg
        λ * ϕ * σg
    end # E[n]
    map!(local_vars.θ, local_vars.γ, local_vars.c) do γ, c
        (1//2 + γ) * tanh(c / 2) / (2c)
    end # E[ω]
    l.invlink.λ .= max(length(y) / (2 * dot(local_vars.ϕ, 1 .- local_vars.σg)), λ)
    return local_vars
end

function sample_local!(
    local_vars, l::HeteroscedasticGaussianLikelihood, y, f::NTuple{2,<:AbstractVector}
)
    λ = only(l.invlink.λ)
    map!(local_vars.γ, f[1], f[2], y) do f, g, y
        rand(Poisson(λ * logistic(g) * abs2(f - y) / 2))
    end # Update of n
    map!(local_vars.θ, local_vars.γ, f[2]) do n, g
        rand(PolyaGamma(n + 1//2, abs(g)))
    end # update of ω
    return local_vars
end

@inline function ∇E_μ(
    l::HeteroscedasticGaussianLikelihood{<:InvScaledLogistic},
    ::AOptimizer,
    y::AbstractVector,
    state,
)
    return (y .* only(l.invlink.λ) .* state.σg / 2, (1//2 .- state.γ) / 2)
end

@inline function ∇E_Σ(
    l::HeteroscedasticGaussianLikelihood{<:InvScaledLogistic},
    ::AOptimizer,
    ::AbstractVector,
    state,
)
    return (only(l.invlink.λ) * state.σg / 2, state.θ / 2)
end

function compute_proba(
    l::HeteroscedasticGaussianLikelihood,
    μs::Tuple{<:AbstractVector,<:AbstractVector},
    σs::Tuple{<:AbstractVector,<:AbstractVector},
) where {T<:Real}
    return μs[1], σs[1] + l.invlink.(μs[2])
end

function predict_y(
    ::HeteroscedasticGaussianLikelihood, μs::Tuple{<:AbstractVector,<:AbstractVector}
)
    return first(μs) # For predict_y the variance is ignored
end

function expec_loglikelihood(
    l::HeteroscedasticGaussianLikelihood{<:InvScaledLogistic},
    ::AnalyticVI,
    y::AbstractVector,
    μ,
    diag_cov,
    state,
)
    tot = length(y) * (log(l.invlink.λ[1]) / 2 - log(2 * sqrt(twoπ)))
    tot +=
        (
            dot(μ[2], (1//2 .- state.γ)) - dot(abs2.(μ[2]), state.θ) -
            dot(diag_cov[2], state.θ)
        ) / 2
    tot -= PoissonKL(l, y, μ[1], diag_cov[1], state)
    return tot
end

function AugmentedKL(
    l::HeteroscedasticGaussianLikelihood{<:InvScaledLogistic}, state, ::Any
)
    return PolyaGammaKL(l, state)
end

function PoissonKL(
    l::HeteroscedasticGaussianLikelihood{<:InvScaledLogistic},
    y::AbstractVector,
    μ::AbstractVector,
    Σ::AbstractVector,
    state,
)
    λ = only(l.invlink.λ)
    return PoissonKL(state.γ, λ * (abs2.(y - μ) + Σ) / 2, log.(λ * (abs2.(μ - y) + Σ) / 2))
end

function PolyaGammaKL(::HeteroscedasticGaussianLikelihood{<:InvScaledLogistic}, state)
    return PolyaGammaKL(1//2 .+ state.γ, state.c, state.θ)
end


text:
using DiffEqBase, Test, RecursiveArrayTools

macro iop_def(funcdef::Expr)
    """Define in- and out-of-place functions simultaneously.

    Call on oop function definition, defines two functions with suffixes _op and _ip.
    """
    @assert funcdef.head ∈ (:function, :(=)) && funcdef.args[1].head == :call

    fname = funcdef.args[1].args[1]

    opname = Symbol("$(fname)_op")
    ipname = Symbol("$(fname)_ip")

    opdef = deepcopy(funcdef)
    opdef.args[1].args[1] = opname

    return quote
        $(esc(opdef))
        $(esc(ipname))(du, args...) = du .= $(esc(opname))(args...)
    end
end

function test_inplace(du, expected, f::Function, args...)
    """Test the in-place version of a function."""
    fill!(du, NaN)
    f(du, args...)
    @test du == expected
end

# Allocate du automatically based on type of expected result
test_inplace(expected, f::Function, args...) = test_inplace(similar(expected), expected, f, args...)

function test_iop(expected, f_op::Function, f_ip::Function, args...)
    """Test in- and out-of-place version of function both match expected value."""
    @test f_op(args...) == expected
    test_inplace(expected, f_ip, args...)
end

@iop_def f(u,p,t) = p[1] .* u
u = [1.0, 2.0, 3.0]
p = [2.0]
t = 0.0

# ODEFunction
odefun = ODEFunction{false}(f_op)
odefun_ip = ODEFunction{true}(f_ip)
expected = f_op(u, p, t)
test_iop(expected, odefun, odefun_ip, u, p, t)

# SplitFunction
@iop_def f2(u, p, t) = u .^ 2
sfun = SplitFunction{false}(f_op, f2_op)
sfun_ip = SplitFunction{true}(f_ip, f2_ip; _func_cache=similar(u))
expected = f_op(u, p, t) + f2_op(u, p, t)
test_iop(expected, sfun, sfun_ip, u, p, t)

# DynamicalODEFunction
@iop_def dode_f1(v, u, p, t) = -u
@iop_def dode_f2(v, u, p, t) = p[1] .* v
dodefun = DynamicalODEFunction{false}(dode_f1_op, dode_f2_op)
dodefun_ip = DynamicalODEFunction{true}(dode_f1_ip, dode_f2_ip)
v = [4.0, 5.0, 6.0]
expected = ArrayPartition(dode_f1_op(v, u, p, t), dode_f2_op(v, u, p, t))
test_iop(expected, dodefun, dodefun_ip, ArrayPartition(v, u), p, t)

# DiscreteFunction
dfun = DiscreteFunction{false}(f_op)
dfun_ip = DiscreteFunction{true}(f_ip)
test_iop(f_op(u, p, t), dfun, dfun_ip, u, p, t)

# Type stability
f_analytic(u,p,t) = u
jac = (u,p,t) -> 1
@inferred ODEFunction{false}(f_op,jac=jac)
@inferred DiscreteFunction{false}(f_op,analytic=f_analytic)


text:
# This file is auto-generated by AWSMetadata.jl
using AWS
using AWS.AWSServices: devops_guru
using AWS.Compat
using AWS.UUIDs

"""
    AddNotificationChannel()

# Required Parameters
- `Config`:

"""
add_notification_channel(Config; aws_config::AWSConfig=global_aws_config()) = devops_guru("PUT", "/channels", Dict{String, Any}("Config"=>Config); aws_config=aws_config)
add_notification_channel(Config, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("PUT", "/channels", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Config"=>Config), args)); aws_config=aws_config)

"""
    DescribeAccountHealth()

"""
describe_account_health(; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/accounts/health"; aws_config=aws_config)
describe_account_health(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/accounts/health", args; aws_config=aws_config)

"""
    DescribeAccountOverview()

# Required Parameters
- `FromTime`:

# Optional Parameters
- `ToTime`:
"""
describe_account_overview(FromTime; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/accounts/overview", Dict{String, Any}("FromTime"=>FromTime); aws_config=aws_config)
describe_account_overview(FromTime, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/accounts/overview", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("FromTime"=>FromTime), args)); aws_config=aws_config)

"""
    DescribeAnomaly()

# Required Parameters
- `Id`:

"""
describe_anomaly(Id; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/anomalies/$(Id)"; aws_config=aws_config)
describe_anomaly(Id, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/anomalies/$(Id)", args; aws_config=aws_config)

"""
    DescribeInsight()

# Required Parameters
- `Id`:

"""
describe_insight(Id; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/insights/$(Id)"; aws_config=aws_config)
describe_insight(Id, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/insights/$(Id)", args; aws_config=aws_config)

"""
    DescribeResourceCollectionHealth()

# Required Parameters
- `ResourceCollectionType`:

# Optional Parameters
- `NextToken`:
"""
describe_resource_collection_health(ResourceCollectionType; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/accounts/health/resource-collection/$(ResourceCollectionType)"; aws_config=aws_config)
describe_resource_collection_health(ResourceCollectionType, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/accounts/health/resource-collection/$(ResourceCollectionType)", args; aws_config=aws_config)

"""
    DescribeServiceIntegration()

"""
describe_service_integration(; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/service-integrations"; aws_config=aws_config)
describe_service_integration(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/service-integrations", args; aws_config=aws_config)

"""
    GetResourceCollection()

# Required Parameters
- `ResourceCollectionType`:

# Optional Parameters
- `NextToken`:
"""
get_resource_collection(ResourceCollectionType; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/resource-collections/$(ResourceCollectionType)"; aws_config=aws_config)
get_resource_collection(ResourceCollectionType, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("GET", "/resource-collections/$(ResourceCollectionType)", args; aws_config=aws_config)

"""
    ListAnomaliesForInsight()

# Required Parameters
- `InsightId`:

# Optional Parameters
- `MaxResults`:
- `NextToken`:
- `StartTimeRange`:
"""
list_anomalies_for_insight(InsightId; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/anomalies/insight/$(InsightId)"; aws_config=aws_config)
list_anomalies_for_insight(InsightId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/anomalies/insight/$(InsightId)", args; aws_config=aws_config)

"""
    ListEvents()

# Required Parameters
- `Filters`:

# Optional Parameters
- `MaxResults`:
- `NextToken`:
"""
list_events(Filters; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/events", Dict{String, Any}("Filters"=>Filters); aws_config=aws_config)
list_events(Filters, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/events", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Filters"=>Filters), args)); aws_config=aws_config)

"""
    ListInsights()

# Required Parameters
- `StatusFilter`:

# Optional Parameters
- `MaxResults`:
- `NextToken`:
"""
list_insights(StatusFilter; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/insights", Dict{String, Any}("StatusFilter"=>StatusFilter); aws_config=aws_config)
list_insights(StatusFilter, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/insights", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("StatusFilter"=>StatusFilter), args)); aws_config=aws_config)

"""
    ListNotificationChannels()

# Optional Parameters
- `NextToken`:
"""
list_notification_channels(; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/channels"; aws_config=aws_config)
list_notification_channels(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/channels", args; aws_config=aws_config)

"""
    ListRecommendations()

# Required Parameters
- `InsightId`:

# Optional Parameters
- `NextToken`:
"""
list_recommendations(InsightId; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/recommendations", Dict{String, Any}("InsightId"=>InsightId); aws_config=aws_config)
list_recommendations(InsightId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/recommendations", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InsightId"=>InsightId), args)); aws_config=aws_config)

"""
    PutFeedback()

# Optional Parameters
- `InsightFeedback`:
"""
put_feedback(; aws_config::AWSConfig=global_aws_config()) = devops_guru("PUT", "/feedback"; aws_config=aws_config)
put_feedback(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("PUT", "/feedback", args; aws_config=aws_config)

"""
    RemoveNotificationChannel()

# Required Parameters
- `Id`:

"""
remove_notification_channel(Id; aws_config::AWSConfig=global_aws_config()) = devops_guru("DELETE", "/channels/$(Id)"; aws_config=aws_config)
remove_notification_channel(Id, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("DELETE", "/channels/$(Id)", args; aws_config=aws_config)

"""
    SearchInsights()

# Required Parameters
- `StartTimeRange`:
- `Type`:

# Optional Parameters
- `Filters`:
- `MaxResults`:
- `NextToken`:
"""
search_insights(StartTimeRange, Type; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/insights/search", Dict{String, Any}("StartTimeRange"=>StartTimeRange, "Type"=>Type); aws_config=aws_config)
search_insights(StartTimeRange, Type, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("POST", "/insights/search", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("StartTimeRange"=>StartTimeRange, "Type"=>Type), args)); aws_config=aws_config)

"""
    UpdateResourceCollection()

# Required Parameters
- `Action`:
- `ResourceCollection`:

"""
update_resource_collection(Action, ResourceCollection; aws_config::AWSConfig=global_aws_config()) = devops_guru("PUT", "/resource-collections", Dict{String, Any}("Action"=>Action, "ResourceCollection"=>ResourceCollection); aws_config=aws_config)
update_resource_collection(Action, ResourceCollection, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("PUT", "/resource-collections", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Action"=>Action, "ResourceCollection"=>ResourceCollection), args)); aws_config=aws_config)

"""
    UpdateServiceIntegration()

# Required Parameters
- `ServiceIntegration`:

"""
update_service_integration(ServiceIntegration; aws_config::AWSConfig=global_aws_config()) = devops_guru("PUT", "/service-integrations", Dict{String, Any}("ServiceIntegration"=>ServiceIntegration); aws_config=aws_config)
update_service_integration(ServiceIntegration, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = devops_guru("PUT", "/service-integrations", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ServiceIntegration"=>ServiceIntegration), args)); aws_config=aws_config)


text:
# g_tests_bare.jl
#
# A Julia script searching for maximum cuts of 0-1 weighted benchmark
# graphs from G-set using the triangular model based solver
#
# Implements restarted free runs with two rounding techniques for comparison
#

using LightGraphs
using MatrixDepot
using GraphRecipes

include("DiceBasic.jl")

listTests = [1, 2 , 3, 4, 5, 22, 23, 24, 25, 26, 43, 44, 45, 46,
                 47, 48, 49, 50, 51, 52, 53, 54]

function best_random_cut(graph, V, num)
    # Evaluates cuts by looking at num random choices of the rounding center
    # Returns the best cut
    bestcut = -1
    for i in 1:num
        threshold = 4.0*rand() - 2.0
        cut = DiceBasic.cut(graph, DiceBasic.extract_configuration(V, threshold))
        if cut > bestcut
            bestcut = cut
        end
    end
    return bestcut
end

# Common model definitions
Ks = 0.00001
tmax = 1250      # the number of steps within one realization
domain = 0.3     # the size of the vicinity of zero for initial states

# How many returns
Nreruns = 100

# How many random roundings to try
Nrandcuts = 10

# Arrays with the best cuts
bestcuts = zeros(length(listTests))
bestrandcuts  = zeros(length(listTests))

for i in 1:length(listTests)
    nameG = "Gset/G"*string(listTests[i])
    println("Prosessing $nameG")
    Gcur = Graph(mdopen(nameG).A)
    Nvert = nv(Gcur)

    model = DiceBasic.Model(Gcur, DiceBasic.triangular, 15/Nvert, Ks)

    bestcut = -1
    bestrandcut = -1

    for j in 1:Nreruns
        print("\rRealization $j: ")

        # Sets the initial random state
        Vstart = domain.*DiceBasic.get_initial(Nvert, (-1.0, 1.0))
        Vend = DiceBasic.roundup(DiceBasic.propagate(model, tmax, Vstart))

        # random cuts
        cut = best_random_cut(Gcur, Vend, Nrandcuts)
        if cut > bestrandcut
            bestrandcut = cut
        end

        # search for the best rounding center
        cut = DiceBasic.get_best_cut(Gcur, Vend)
        print("Cut = $cut          ")
        if cut > bestcut
            bestcut = cut
        end
    end
    # From https://discourse.julialang.org/t/how-clear-the-printed-content-in-terminal-and-print-to-the-same-line/19549/4
    # with the reference to https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
    print("\e[2K") # clear line
    print("\e[1G") # move the cursor to column 1
    println("The best cut is $bestcut, the worst cut is $(leastcuts[i]); the best random cut is $bestrandcut")
    bestcuts[i] = bestcut
    bestrandcuts[i] = bestrandcut
end

max_stars_repo_name: merement/Dice

max_issues_repo_name: merement/Dice

max_forks_repo_name: merement/Dice