text:
### Abstract HMC state

abstract HMCState{F<:VariateForm} <: HMCSamplerState{F}

### HMC state subtypes

## UnvHMCState holds the internal state ("local variables") of the HMC sampler for univariate parameters

type UnvHMCState <: HMCState{Univariate}
  pstate::ParameterState{Continuous, Univariate} # Parameter state used internally by HMC
  tune::MCTunerState
  nleaps::Integer
  ratio::Real
  a::Real
  momentum::Real
  oldhamiltonian::Real
  newhamiltonian::Real
  count::Integer

  function UnvHMCState(
    pstate::ParameterState{Continuous, Univariate},
    tune::MCTunerState,
    nleaps::Integer,
    ratio::Real,
    a::Real,
    momentum::Real,
    oldhamiltonian::Real,
    newhamiltonian::Real,
    count::Integer
  )
    if !isnan(ratio)
      @assert ratio > 0 "Acceptance ratio should be positive"
    end
    if !isnan(a)
      @assert 0 <= a <= 1 "Acceptance probability should be in [0, 1]"
    end
    @assert count >= 0 "Number of iterations (count) should be non-negative"
    new(pstate, tune, nleaps, ratio, a, momentum, oldhamiltonian, newhamiltonian, count)
  end
end

UnvHMCState(pstate::ParameterState{Continuous, Univariate}, tune::MCTunerState=BasicMCTune(), nleaps::Integer=0) =
  UnvHMCState(pstate, tune, nleaps, NaN, NaN, NaN, NaN, NaN, 0)

## MuvHMCState holds the internal state ("local variables") of the HMC sampler for multivariate parameters

type MuvHMCState <: HMCState{Multivariate}
  pstate::ParameterState{Continuous, Multivariate} # Parameter state used internally by HMC
  tune::MCTunerState
  nleaps::Integer
  ratio::Real
  a::Real
  momentum::RealVector
  oldhamiltonian::Real
  newhamiltonian::Real
  count::Integer

  function MuvHMCState(
    pstate::ParameterState{Continuous, Multivariate},
    tune::MCTunerState,
    nleaps::Integer,
    ratio::Real,
    a::Real,
    momentum::RealVector,
    oldhamiltonian::Real,
    newhamiltonian::Real,
    count::Integer
  )
    if !isnan(ratio)
      @assert ratio > 0 "Acceptance ratio should be positive"
    end
    if !isnan(a)
      @assert 0 <= a <= 1 "Acceptance probability should be in [0, 1]"
    end
    @assert count >= 0 "Number of iterations (count) should be non-negative"
    new(pstate, tune, nleaps, ratio, a, momentum, oldhamiltonian, newhamiltonian, count)
  end
end

MuvHMCState(pstate::ParameterState{Continuous, Multivariate}, tune::MCTunerState=BasicMCTune(), nleaps::Integer=0) =
  MuvHMCState(pstate, tune, nleaps, NaN, NaN, Array(eltype(pstate), pstate.size), NaN, NaN, 0)

### Hamiltonian Monte Carlo (HMC)

immutable HMC <: HMCSampler
  leapstep::Real
  nleaps::Integer

  function HMC(leapstep::Real, nleaps::Integer)
    @assert leapstep > 0 "Leapfrog step is not positive"
    @assert nleaps > 0 "Number of leapfrog steps is not positive"
    new(leapstep, nleaps)
  end
end

HMC(leapstep::Real=0.1) = HMC(leapstep, 10)

### Initialize HMC sampler

## Initialize parameter state

function initialize!{F<:VariateForm}(
  pstate::ParameterState{Continuous, F},
  parameter::Parameter{Continuous, F},
  sampler::HMC,
  outopts::Dict
)
  parameter.uptogradlogtarget!(pstate)
  @assert isfinite(pstate.logtarget) "Log-target not finite: initial value out of support"
  @assert all(isfinite(pstate.gradlogtarget)) "Gradient of log-target not finite: initial values out of support"

  if !isempty(outopts[:diagnostics])
    pstate.diagnostickeys = copy(outopts[:diagnostics])
    pstate.diagnosticvalues = Array(Any, length(pstate.diagnostickeys))
  end
end

## Initialize HMC state

tuner_state(parameter::Parameter, sampler::HMC, tuner::DualAveragingMCTuner) =
  DualAveragingMCTune(
  step=sampler.leapstep,
  λ=sampler.nleaps*sampler.leapstep,
  εbar=tuner.ε0bar,
  hbar=tuner.h0bar,
  accepted=0,
  proposed=0,
  totproposed=tuner.period
)

sampler_state(
  parameter::Parameter{Continuous, Univariate},
  sampler::HMC,
  tuner::MCTuner,
  pstate::ParameterState{Continuous, Univariate},
  vstate::VariableStateVector
) =
  UnvHMCState(generate_empty(pstate), tuner_state(parameter, sampler, tuner), sampler.nleaps)

sampler_state(
  parameter::Parameter{Continuous, Multivariate},
  sampler::HMC,
  tuner::MCTuner,
  pstate::ParameterState{Continuous, Multivariate},
  vstate::VariableStateVector
) =
  MuvHMCState(generate_empty(pstate), tuner_state(parameter, sampler, tuner), sampler.nleaps)

function sampler_state(
  parameter::Parameter{Continuous, Univariate},
  sampler::HMC,
  tuner::DualAveragingMCTuner,
  pstate::ParameterState{Continuous, Univariate},
  vstate::VariableStateVector
)
  sstate = UnvHMCState(generate_empty(pstate), tuner_state(parameter, sampler, tuner), 0)
  initialize_step!(sstate, parameter, sampler, tuner, randn())
  sstate.tune.μ = log(10*sstate.tune.step)
  sstate
end

function sampler_state(
  parameter::Parameter{Continuous, Multivariate},
  sampler::HMC,
  tuner::DualAveragingMCTuner,
  pstate::ParameterState{Continuous, Multivariate},
  vstate::VariableStateVector
)
  sstate = MuvHMCState(generate_empty(pstate), tuner_state(parameter, sampler, tuner), 0)
  initialize_step!(sstate, parameter, sampler, tuner, randn(sstate.pstate.size))
  sstate.tune.μ = log(10*sstate.tune.step)
  sstate
end

## Reset parameter state

function reset!(
  pstate::ParameterState{Continuous, Univariate},
  x::Real,
  parameter::Parameter{Continuous, Univariate},
  sampler::HMC
)
  pstate.value = x
  parameter.uptogradlogtarget!(pstate)
end

function reset!(
  pstate::ParameterState{Continuous, Multivariate},
  x::RealVector,
  parameter::Parameter{Continuous, Multivariate},
  sampler::HMC
)
  pstate.value = copy(x)
  parameter.uptogradlogtarget!(pstate)
end

function reset!(tune::DualAveragingMCTune, sampler::HMC, tuner::DualAveragingMCTuner)
  tune.step = 1
  tune.λ = sampler.nleaps*sampler.leapstep
  tune.εbar = tuner.ε0bar
  tune.hbar = tuner.h0bar
  (tune.accepted, tune.proposed, tune.totproposed, tune.rate) = (0, 0, tuner.period, NaN)
end

function reset!(
  sstate::MuvHMCState,
  pstate::ParameterState{Continuous, Univariate},
  parameter::Parameter{Continuous, Univariate},
  sampler::HMC,
  tuner::DualAveragingMCTuner
)
  reset!(sstate.tune, sampler, tuner)
  initialize_step!(sstate, parameter, sampler, tuner, randn())
  sstate.tune.μ = log(10*sstate.tune.step)
  sstate.count = 0
end

function reset!(
  sstate::MuvHMCState,
  pstate::ParameterState{Continuous, Multivariate},
  parameter::Parameter{Continuous, Multivariate},
  sampler::HMC,
  tuner::DualAveragingMCTuner
)
  reset!(sstate.tune, sampler, tuner)
  initialize_step!(sstate, parameter, sampler, tuner, randn(sstate.pstate.size))
  sstate.tune.μ = log(10*sstate.tune.step)
  sstate.count = 0
end

leapfrog!(sstate::HMCState{Univariate}, gradlogtarget!::Function) =
  sstate.momentum = leapfrog!(sstate.pstate, sstate.pstate, sstate.momentum, sstate.tune.step, gradlogtarget!)

leapfrog!(sstate::HMCState{Multivariate}, gradlogtarget!::Function) =
  leapfrog!(sstate.pstate, sstate.momentum, sstate.pstate, sstate.momentum, sstate.tune.step, gradlogtarget!)

Base.show(io::IO, sampler::HMC) =
  print(io, "HMC sampler: number of leaps = $(sampler.nleaps), leap step = $(sampler.leapstep)")

Base.writemime(io::IO, ::MIME"text/plain", sampler::HMC) = show(io, sampler)


text:
module NChargedBodyTreecode
    using StaticArrays
    using LinearAlgebra

    export Particles
    export ClusterTree, num_cluster

    export updateParticlesField!
    export BruteForce, TreecodeUniform, TreecodeStretch, TreecodeAvgRestFrame

    export boostParticlesPosition!
    export transformParticlesMomentums!
    export transtransformParticlesField!

    export relerror

    include("algorithm.jl")
    include("particles.jl")
    include("cluster.jl")
    include("cluster_tree.jl")
    include("cluster2p.jl")
    include("update_particles_field.jl")
    include("force_kernel.jl")
    include("relativity.jl")
    include("diagnostic.jl")
end # module

ext: jl


text:
# general swaption engine types and methods
type NullSwaptionEngine <: PricingEngine end

_calculate!(::NullSwaptionEngine, ::Swaption) = error("Must set valid pricing engine, use update_pricing_engine")

function greater_than_or_equal_to{T}(x::T, y::T)
  return x >= y
end


text:
# Gnuplot.jl
# build dependency: gnuplot-v5

using BinDeps
using Compat

@BinDeps.setup

gnuplot = library_dependency("gnuplot")

@osx_only begin
	using Homebrew
	provides(Homebrew.HB, "gnuplot", gnuplot, os = :Darwin)
end

provides(AptGet, "gnuplot", gnuplot)
provides(Yum, "gnuplot", gnuplot)

julia_usrdir = normpath(JULIA_HOME*"/../") # This is a stopgap, we need a better built-in solution to get the included libraries
libdirs = AbstractString["$(julia_usrdir)/lib"]
includedirs = AbstractString["$(julia_usrdir)/include"]

provides(
	Sources,
	URI("http://sourceforge.net/projects/gnuplot/files/latest/download?source=files"),
	gnuplot
)

provides(
	BuildProcess,
	Autotools(lib_dirs = libdirs, include_dirs = includedirs),
	gnuplot
)

@compat @BinDeps.install Dict(:gnuplot => :gnuplot)

max_stars_repo_name: johncsnyder/Gnuplot


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

mutable struct AclStatusResult <: SwaggerModel
    AclStatus::Any # spec type: Union{ Nothing, AclStatus } # spec name: AclStatus

    function AclStatusResult(;AclStatus=nothing)
        o = new()
        validate_property(AclStatusResult, Symbol("AclStatus"), AclStatus)
        setfield!(o, Symbol("AclStatus"), AclStatus)
        o
    end
end # type AclStatusResult

const _property_map_AclStatusResult = Dict{Symbol,Symbol}(Symbol("AclStatus")=>Symbol("AclStatus"))
const _property_types_AclStatusResult = Dict{Symbol,String}(Symbol("AclStatus")=>"AclStatus")
Base.propertynames(::Type{ AclStatusResult }) = collect(keys(_property_map_AclStatusResult))
Swagger.property_type(::Type{ AclStatusResult }, name::Symbol) = Union{Nothing,eval(Meta.parse(_property_types_AclStatusResult[name]))}
Swagger.field_name(::Type{ AclStatusResult }, property_name::Symbol) =  _property_map_AclStatusResult[property_name]

function check_required(o::AclStatusResult)
    true
end

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


text:
function part1(input)
    starting_numbers = parse.(Int, split(read(input, String), ","))
    return run_game(starting_numbers, 2020)
end

function part2(input)
    starting_numbers = parse.(Int, split(read(input, String), ","))
    return run_game(starting_numbers, 30000000)
end

function run_game(starting_numbers, iterations)
    last_spoken = Dict{Int, Int}()
    number = 0
    next_number = 0
    for i = 1:iterations
        if i <= length(starting_numbers)
            number = starting_numbers[i]
        else
            number = next_number
        end
        next_number = i - get(last_spoken, number, i)
        last_spoken[number] = i
    end
    return number
end


text:
__precompile__()

module OrthogEM

using Distributions
using LinearAlgebra, Arpack
using DataFrames, StaticArrays

export
    oem_fit

include("utils.jl")
include("thresholds.jl")
include("oem_fit.jl")

end # module


text:
using Test

include("lasagna.jl")

# Dear Julia learner,
# If you're reading this test suite to gain some insights, please be advised that it is somewhat unusual.
#
# Don't worry if you don't understand this test suite at this stage of your learning journey.
# We had to use some advanced features to be able to write assertions about docstrings.
# You wouldn't normally write assertions for that in a typical codebase.
# We're doing it here strictly for educational purposes.

"""
    hasdocstring(s::Symbol)

Return true if the binding `s` in `@__MODULE__` has a docstring

**Credit:** https://julialang.zulipchat.com/#narrow/stream/225542-helpdesk/topic/finding.20out.20if.20a.20function.20has.20a.20docstring
"""
function hasdocstring(s::Symbol)
    meta = Docs.meta(@__MODULE__)
    haskey(meta, Docs.Binding(@__MODULE__, s))
end

@testset "solution still works" begin
    @test preptime(2) == 4
    @test preptime(3) == 6
    @test preptime(8) == 16
    @test remaining_time(30) == 30
    @test remaining_time(50) == 10
    @test remaining_time(60) == 0
    @test total_working_time(3, 20) == 26
end

@testset "preptime has a docstring" begin
    @test hasdocstring(:preptime)
end

@testset "remaining_time has a docstring" begin
    @test hasdocstring(:remaining_time)
end

@testset "total_working_time has a docstring" begin
    @test hasdocstring(:total_working_time)
end


text:
import .ForwardDiff, .ForwardDiff.DiffResults

function ∂ℓπ∂θ_forwarddiff(ℓπ, θ::AbstractVector)
    res = DiffResults.GradientResult(θ)
    ForwardDiff.gradient!(res, ℓπ, θ)
    return DiffResults.value(res), DiffResults.gradient(res)
end

# Implementation 1
function ∂ℓπ∂θ_forwarddiff(ℓπ, θ::AbstractMatrix)
    jacob = similar(θ)
    res = DiffResults.JacobianResult(similar(θ, size(θ, 2)), jacob)
    ForwardDiff.jacobian!(res, ℓπ, θ)
    jacob_full = DiffResults.jacobian(res)

    d, n = size(jacob)
    for i in 1:n
        jacob[:,i] = jacob_full[i,1+(i-1)*d:i*d]
    end
    return DiffResults.value(res), jacob
end

# Implementation 2
# function ∂ℓπ∂θ_forwarddiff(ℓπ, θ::AbstractMatrix)
#     local densities
#     f(x) = (densities = ℓπ(x); sum(densities))
#     res = DiffResults.GradientResult(θ)
#     ForwardDiff.gradient!(res, f, θ)
#     return ForwardDiff.value.(densities), DiffResults.gradient(res)
# end

# Implementation 3
# function ∂ℓπ∂θ_forwarddiff(ℓπ, θ::AbstractMatrix)
#     v = similar(θ, size(θ, 2))
#     g = similar(θ)
#     for i in 1:size(θ, 2)
#         res = GradientResult(θ[:,i])
#         gradient!(res, ℓπ, θ[:,i])
#         v[i] = value(res)
#         g[:,i] = gradient(res)
#     end
#     return v, g
# end

function ForwardDiffHamiltonian(metric::AbstractMetric, ℓπ)
    ∂ℓπ∂θ(θ::AbstractVecOrMat) = ∂ℓπ∂θ_forwarddiff(ℓπ, θ)
    return Hamiltonian(metric, ℓπ, ∂ℓπ∂θ)
end

ADAVAILABLE[ForwardDiff] = ForwardDiffHamiltonian


text:
module DelayNetPlots

using DelayNetTools: Spike, SimpleNeuronType
using GLMakie
using AbstractPlotting

include("plotting.jl")
export spikeraster, spatialplot, spatialanim, spikeraster!

end

max_stars_repo_name: ddahlbom/DelayNetPlots

max_issues_repo_name: ddahlbom/DelayNetPlots

max_forks_repo_name: ddahlbom/DelayNetPlots


text:
# This file is an example of fitting an orbit to exoplanet astrometry
# using our new package, DirectDetections.

# We will use the paper "An Updated Visual Orbit of the Directly Imaged
# Exoplanet 51 Eridani b and Prospects for a Dynamical Mass Measurement with Gaia"
# by Rosa et al, 2019
# https://iopscience.iop.org/article/10.3847/1538-3881/ab4da4

# You can copy and paste these blocks one at a time, or modify it
# and run it all by typing: include("example-1.jl")

## Setup: requires Julia 1.7
# Run this once to install the necessary packages.
# You only need to run this once, ever.
cd(@__DIR__)
using Pkg
Pkg.activate(".")
Pkg.update()
Pkg.Registry.add(RegistrySpec(url="https://github.com/sefffal/DirectRegistry.git"))
Pkg.instantiate()

## Activate environment and import packages
cd(@__DIR__)
using Pkg
Pkg.activate(".")
using DirectDetections, Distributions

## Create a 1-planet model
@named b = Planet(
    Priors(
        a = TruncatedNormal(20, 10, 0, Inf),
        i = Sine(),
        e = Beta(1.5, 10),
        Ω = Uniform(0,  π),
        ω = Uniform(0, 2π),
        τ = Uniform(0, 1)
    ),
    Astrometry(
        (epoch=57009.0, ra= 69.3356, dec=-448.917, σ_ra= 1.82477,  σ_dec= 1.8787  ),
        (epoch=57052.0, ra= 78.3783, dec=-444.96 , σ_ra= 2.05054,  σ_dec= 2.05971 ),
        (epoch=57053.0, ra= 77.8303, dec=-450.121, σ_ra= 2.39716,  σ_dec= 2.565   ),
        (epoch=57054.0, ra= 76.9638, dec=-455.037, σ_ra=24.1568 ,  σ_dec=23.9074  ),
        (epoch=57266.0, ra=100.052 , dec=-443.966, σ_ra= 2.07345,  σ_dec= 2.22231 ),
        (epoch=57332.0, ra=108.641 , dec=-439.656, σ_ra= 4.56234,  σ_dec= 5.36208 ),
        (epoch=57374.0, ra=112.918 , dec=-441.705, σ_ra= 4.65729,  σ_dec= 6.13954 ),
        (epoch=57376.0, ra=112.464 , dec=-440.892, σ_ra= 3.39255,  σ_dec= 3.0549  ),
        (epoch=57415.0, ra=110.406 , dec=-440.845, σ_ra= 4.18857,  σ_dec= 5.93133 ),
        (epoch=57649.0, ra=142.053 , dec=-432.057, σ_ra= 2.05962,  σ_dec= 2.02432 ),
        (epoch=57652.0, ra=141.521 , dec=-428.673, σ_ra= 2.46576,  σ_dec= 2.6485  ),
        (epoch=57739.0, ra=153.258 , dec=-422.449, σ_ra= 2.12148,  σ_dec= 2.14627 ),
        (epoch=58068.0, ra=187.509 , dec=-406.365, σ_ra= 3.04171,  σ_dec= 3.02463 ),
        (epoch=58442.0, ra=219.468 , dec=-374.674, σ_ra= 1.815  ,  σ_dec= 1.9453  ),
    )
)
@named cEri = System(
    Priors(
        plx = gaia_plx(gaia_id=3205095125321700480),
        M   = TruncatedNormal(1.75, 0.05, 0, Inf),
    ),
    b
)

## Fit
# This could take ~5 minutes.
Random.seed!(9876543210)
@time chains = DirectDetections.hmc(
    cEri, 0.95,
    # adaptation=  1000,
    # iterations= 5_000,

    adaptation=  50,
    iterations= 50,
    tree_depth=    13,
)
# You can also run multiple chains in parallel - let us know and we can help you
# set that up.

## View summary of results
# display(chains)

## Plot fitted model (will take ~1 minute the first time), coloured by ecentricity.
# This is similar to figure 4.
using Plots
plotmodel(chains, color=:e, alpha=0.1)
xlims!(-1100,700)
ylims!(-600,1100)

## Look at just the semi-major axis histgoram (i.e. the marginal posterior)
histogram(chains["b[a]"])

## Create a corner plot like figure 3
using PairPlots
corner(chains)

max_stars_repo_name: sefffal/teps-problems

max_issues_repo_name: sefffal/teps-problems

max_forks_repo_name: sefffal/teps-problems


text:
const ROOT2OVER2 = 0.7071067811865476
const SKEW_2D = 0.366025403784439
const UNSKEW_2D = -0.21132486540518713

const RSQUARED_2D = 2.0f0 / 3.0f0

export ImproveX
struct ImproveX <: NoiseType end

"""
2D OpenSimplex2S/SuperSimplex noise, standard lattice orientation
"""
function noise(seed::Int64, x, y)
    # Get points for A2* lattice
    s = SKEW_2D * (x + y)
    _noise(seed, x + s, y + s)
end

"""
2D OpenSimplex2S/SuperSimplex noise, with Y pointing down the main diagonal.
Might be better for a 2D sandbox style game, where Y is vertical.
Probably slightly less optimal for heightmaps or continent maps,
unless your map is centered around an equator. It's a slight
difference, but the option is here to make it easy.
"""
function noise(::Type{ImproveX}, seed::Int64, x, y)
    # Skew transform and rotation baked into one.
    xx = x * ROOT2OVER2
    yy = y * (ROOT2OVER2 * (1 + 2 * SKEW_2D))
    _noise(seed, yy + xx, yy - xx)
end

dxy(x, y) = RSQUARED_2D - x * x - y * y

"""
2D  OpenSimplex2S/SuperSimplex noise base.
"""
function _noise(seed::Int64, xs, ys)

    # Get base points and offsets.
    xsb = fastFloor(xs)
    ysb = fastFloor(ys)
    xi = Float32(xs - xsb)
    yi = Float32(ys - ysb)

    # Prime pre-multiplication for hash.
    xsbp = (xsb * PRIME_X)%Int64
    ysbp = (ysb * PRIME_Y)%Int64

    # Unskew.
    t = (xi + yi) * Float32(UNSKEW_2D)
    dx0 = xi + t
    dy0 = yi + t

    UNSKEW_2D_2X = (1 + 2 * UNSKEW_2D)

    # First vertex.
    a0 = dxy(dx0, dy0)
    value = grad(a0, seed, xsbp, ysbp, dx0, dy0)

    # Second vertex.
    a = Float32(2 * UNSKEW_2D_2X * (1 / UNSKEW_2D + 2)) * t +
        (Float32(-2 * UNSKEW_2D_2X * UNSKEW_2D_2X) + a0)
    value += grad(a, seed, xsbp + PRIME_X, ysbp + PRIME_Y,
                  dx0 - Float32(UNSKEW_2D_2X), dy0 - Float32(UNSKEW_2D_2X))

    # Third and fourth vertices.
    # Nested conditionals were faster than compact bit logic/arithmetic.
    xmyi = xi - yi
    if t < UNSKEW_2D
        if xi + xmyi > 1
            dx = dx0 - Float32(3 * UNSKEW_2D + 2)
            dy = dy0 - Float32(3 * UNSKEW_2D + 1)
            a = dxy(dx, dy)
            if a > 0
                value += grad(a, seed, xsbp + (PRIME_X << 1), ysbp + PRIME_Y, dx, dy)
            end
        else
            dx = dx0 - Float32(UNSKEW_2D)
            dy = dy0 - Float32(UNSKEW_2D + 1)
            a = dxy(dx, dy)
            if a > 0
                value += grad(a, seed, xsbp, ysbp + PRIME_Y, dx, dy)
            end
        end

        if yi - xmyi > 1
            dx = dx0 - Float32(3 * UNSKEW_2D + 1)
            dy = dy0 - Float32(3 * UNSKEW_2D + 2)
            a = dxy(dx, dy)
            if a > 0
                value += grad(a, seed, xsbp + PRIME_X, ysbp + (PRIME_Y << 1), dx, dy)
            end
        else
            dx = dx0 - Float32(UNSKEW_2D + 1)
            dy = dy0 - Float32(UNSKEW_2D)
            a = dxy(dx, dy)
            if a > 0
                value += grad(a, seed, xsbp + PRIME_X, ysbp, dx, dy)
            end
        end
    else
        if xi + xmyi < 0
            dx = dx0 + Float32(1 + UNSKEW_2D)
            dy = dy0 + Float32(UNSKEW_2D)
            a = dxy(dx, dy)
            if a > 0
                value += grad(a, seed, xsbp - PRIME_X, ysbp, dx, dy)
            end
        else
            dx = dx0 - Float32(UNSKEW_2D + 1)
            dy = dy0 - Float32(UNSKEW_2D)
            a = dxy(dx, dy)
            if a > 0
                value += grad(a, seed, xsbp + PRIME_X, ysbp, dx, dy)
            end
        end

        if yi < xmyi
            dx = dx0 + Float32(UNSKEW_2D)
            dy = dy0 + Float32(UNSKEW_2D + 1)
            a = dxy(dx, dy)
            if a > 0
                value += grad(a, seed, xsbp, ysbp - PRIME_Y, dx, dy)
            end
        else
            dx = dx0 - Float32(UNSKEW_2D)
            dy = dy0 - Float32(UNSKEW_2D + 1)
            a = dxy(dx, dy)
            if a > 0
                value += grad(a, seed, xsbp, ysbp + PRIME_Y, dx, dy)
            end
        end
    end

    return Float32(value)
end


text:
using Jtac

chain = @stack MNKGame{5, 5, 4} stack_input=true begin
  Conv(256, relu)
  Dense(128, relu)
end

model = NeuralModel(MNKGame{5, 5, 4}, chain) |> to_gpu |> Async
player = MCTSPlayer(model, power = 25)

loss = Loss(value = 2.5, regularization = 1e-4)

mcts_opponents = [MCTSPlayer(power = p) for p in [10, 50, 100]]#, 200, 500, 1000]]
self_opponents = [MCTSPlayer(model, power = p, name = "current$p") for p in [10, 50]]

with_contest( train_self!
            , player
            , loss = loss
            , playings = 100
            , batchsize = 100
            , iterations = 10
            , branching = 0.1
            , epochs = 100
            , opponents = [mcts_opponents; self_opponents]
            , interval = 5
            , length = 2000 )

max_stars_repo_name: roSievers/jtac


text:
const COND_DATA_PATH = joinpath(@__DIR__,"data","boolean_table_RTG13.csv")
const DEL_CONC = 1e-4

"""
Steady state solver.

A Stiff solver is chosen `TRBDF2` (stand for Tranpezoidal Backward Differeital Formula) from **DifferentialEquations.jl** for robust simulation of stability.

`TRBF2` is a one-step method based on trapezoidal rule and the backward differentiaion formula of order 2, and it is strongly L-stable that means `TRBFS` is good at integrating stiff equations [1].

References
----------
1. Hosea, M. E., & Shampine, L. F. (1996). Analysis and implementation of TR-BDF2. Applied Numerical Mathematics, 20(1-2), 21-37. URL: https://www.sciencedirect.com/science/article/pii/0168927495001158?via%3Dihub
2. DifferentialEqiations.jl - Stiff Problems. [[link](https://diffeq.sciml.ai/stable/solvers/ode_solve/#Stiff-Problems)]
"""
const SSMETHOD = DynamicSS(TRBDF2())

const DataFiles = (;
    RNAseq= joinpath(@__DIR__,"data","RNAseq_RTG_expression.csv"),
    BoolCond = joinpath(@__DIR__,"data","boolean_table_RTG13.csv"),
    solution_rtgM4 = joinpath(@__DIR__,"data","solution_rtgM4.csv")
)

const default_sol_i = 1

"""
Parameter searching
"""
const K_dist = Exponential(1000)
const K_N_dist = Geometric(0.3)
const S_SPAN = (1e-6,1.0)
const Max_expr = 10000.
const TRANS_THRESHOLD = 1.5
const DataTables = getTables(DataFiles)
const DefaultCondition = "stressed"


text:
module HistoricBenefits
#
# This module provided matching routines to determine whether someone who was recieving
# some benefit was getting high/low/enhanced/standard/middle/whatever levels of it.
# Greatly messed up by what seem to be to be errors in benefit imputations in the FRS;
# see the notes in `docs/` and the blog post. Not part of the model per. se..
#
# FIXME the intention is to replace much of this
# with a series of complete parameter files, once we have
# everything defined fully.
#
using CSV, DataFrames, Dates
using ScottishTaxBenefitModel
using .Definitions
using .ModelHousehold: Person
using .Utils: nearesti, nearest
using .Randoms: testp
using .TimeSeriesUtils: fy_from_bits
export benefit_ratio, HISTORIC_BENEFITS, RATIO_BENS, make_benefit_ratios!
export should_switch_dla_to_pip,PIP_RECEIPTS,DLA_RECEIPTS
export switch_dla_to_pip!

const RATIO_BENS = [state_pension,bereavement_allowance_or_widowed_parents_allowance_or_bereavement]

function load_historic( file ) :: Dict
    df = CSV.File( file ) |> DataFrame
    nc = size( df )[2]
    nms = strip.(names( df ))
    db = Dict{Int,Dict}()
    for dr in eachrow(df)
        d = Dict{Symbol,Union{Missing,Float64}}()
        for i in 3:nc
            rn = Symbol(nms[i])
            # println( rn )
            # println( typeof( rn ))
            d[rn] = dr[i]
        end
        db[dr.year] = d
    end
    return db
end

function load_pip()
    pip=CSV.File( "$(MODEL_DATA_DIR)/receipts/pip_2002-2020_from_stat_explore.csv",
        missingstring="..",
        types=Dict([:Date=>String]))|>DataFrame
    pip.Date = Date.( pip.Date, dateformat"yyyymm" )
    return pip
end

function load_dla()
    dla=CSV.File( "$(MODEL_DATA_DIR)/receipts/dla_2002-2020_from_stat_explore.csv" )|> DataFrame
    dla.Date = Date.( dla.Date, dateformat"u-yy" ) .+Year(2000)
    return dla
end

const HISTORIC_BENEFITS = load_historic( "$(MODEL_PARAMS_DIR)/historic_benefits.csv" )
const DLA_RECEIPTS = load_dla()
const PIP_RECEIPTS =  load_pip()

function benefit_ratio(
    finyear :: Integer,
    amt :: Real,
    btype :: Incomes_Type ) :: Real
    brat = HISTORIC_BENEFITS[finyear][Symbol(btype)]
    return amt/brat
end

#
# Year 1st, then 1 before and 1 after, then 2..
#
function get_historic( finyear :: Integer, which :: Symbol, width::Int = 1 )::Vector{Real}
    out = []
    push!(out, HISTORIC_BENEFITS[finyear][which])
    for i in 1:width
        year = finyear-i
        push!(out, HISTORIC_BENEFITS[year][which])
        year = finyear+1
        push!(out, HISTORIC_BENEFITS[year][which])
    end
    return out
end

"""
  Find an exact match for some benefit level, given actual levels, -1..+1 years around finyear, or find
  the nearest amongst the current values, since sometimes the imputation
  seems to be for the wrong year (calendar vs financial). If that fails, pick the
  index of the current values that's closest.
"""
function get_matches( v :: Real, finyear :: Int, which ... ) :: Tuple
    n = length(which)
    all_current = []
    for i in 1:n
        hvals = get_historic( finyear, which[i])
        m = size(hvals)[1]
        push!(all_current,hvals[1])
        for j in 1:m
            if v ≈ hvals[j]
                # println( "on $(which[i]) matched $v at pos $i j=$j vals are $hvals ")
                return (i,j)
            end
        end
    end
    # if we get here, try searching nearest
    # println( "didn't match; trying against $(all_current)")
    n = nearesti( v, all_current... )
    return (n,99)
end

"""
Kinda-sorta randomly assign a dla case as pip so that the proportion
of dla/pip in the data for some period is roughly the same as the latest
dla/pip ratio. This is needed to model the DLA->PIP transition.
"""
function should_switch_dla_to_pip(
    onerand  :: String,
    interview_year :: Integer,
    interview_month :: Integer) :: Bool
    #
    # This weird-looking calculation gives the proportion of
    # dla cases we need to switch to PIP for the ratio at the
    # interview point to (roughly) match the latest DLA/PIP ratio.
    #
    latest_dla = last(DLA_RECEIPTS).Scotland
    latest_pip = last(PIP_RECEIPTS).Scotland
    d = Date( interview_year, interview_month, 1 )
    nearest_dla = DLA_RECEIPTS[nearest( d, DLA_RECEIPTS ),:Scotland]
    nearest_pip = PIP_RECEIPTS[nearest( d, PIP_RECEIPTS ),:Scotland]
    nearest_all = nearest_pip + nearest_dla
    latest_all = latest_pip + latest_dla
    # sw_prop - 70% of DLA needs to *stay* DLA -> 30% change (1-sw_prop)
    sw_prop = 1-(latest_dla/nearest_dla)*(nearest_all/latest_all)
    # println( "onerand $(onerand[Randoms.DLA_TO_PIP:Randoms.DLA_TO_PIP+Randoms.DEFAULT_CHUNK_SIZE-1])")
    # println( "sw_prop=$sw_prop latest_dla $latest_dla nearest_dla $nearest_dla latest_all $latest_all nearest_all $nearest_all" )
    # this should make 30% of DLAs change in that example
    switch = testp( onerand, sw_prop, Randoms.DLA_TO_PIP )
    # println( "switch=$switch")
    return switch
end

function switch_dla_to_pip!(
    pers :: Person,
    interview_year :: Integer,
    interview_month :: Integer )
    if (pers.dla_self_care_type != missing_lmh )||
       (pers.dla_mobility_type != missing_lmh)
        if should_switch_dla_to_pip(
            pers.onerand, interview_year, interview_month )
            # println("switching person $(pers.pid) year=$interview_year month=$interview_month")
            pers.pip_daily_living_type =
                if pers.dla_self_care_type == missing_lmh
                    no_pip
                elseif pers.dla_self_care_type in (low,mid)
                    standard_pip
                else
                    enhanced_pip
                end
            pers.pip_mobility_type =
                if pers.dla_mobility_type == missing_lmh
                    no_pip
                elseif pers.dla_mobility_type in (low,mid)
                    standard_pip
                else
                    enhanced_pip
                end
            pers.dla_mobility_type = missing_lmh
            pers.dla_self_care_type = missing_lmh
        end
    end
end # proc

#
# FIXME make all these names the same. Use the integer constants in `.STBIncomes.jl`.
# FIXME historic bit should be the whole parameter system eventually.
#
"""
 Return a dict of either ratios of recorded receipt to actual values or an indicator of which
 level of benefit is closest.
"""
function make_benefit_ratios!(
    pers :: Person,
    interview_year :: Integer,
    interview_month :: Integer )
    finyear :: Int = fy_from_bits( interview_year, interview_month )
    # short cut
    incd = pers.income;
    # for pensions, etc. we just accept what's there & assign the
    # ratio. FIXME: is this right for people who get the new state_pension
    # in the data
    for target in RATIO_BENS
        if haskey(incd, target )
            pers.benefit_ratios[target] = benefit_ratio( finyear, incd[target], target )
        end
    end
    # these seem to be usually imputed in the data. Find which one matches best.

    pers.pip_daily_living_type = no_pip
    if haskey( incd, personal_independence_payment_daily_living )
        v = incd[personal_independence_payment_daily_living]
        matches = get_matches( v, finyear, :pip_daily_living_standard,  :pip_daily_living_enhanced )
        pers.pip_daily_living_type = matches[1] == 1 ? standard_pip : enhanced_pip
        if matches[2] > 1
            # println( "!! pip daily living matched at $(matches[2])")
        end
    end

    pers.pip_mobility_type = no_pip
    if haskey( incd, personal_independence_payment_mobility )
        v = incd[personal_independence_payment_mobility]
        matches = get_matches( v, finyear, :pip_mobility_standard, :pip_mobility_enhanced )
        pers.pip_mobility_type = matches[1] == 1 ? standard_pip : enhanced_pip
        if matches[2] > 1
            # println( "!! pip mobility matched at $(matches[2])")
        end
    end

    pers.dla_self_care_type = missing_lmh
    if haskey( incd, dlaself_care )
        v = incd[dlaself_care]
        matches = get_matches( v, finyear,
            :dla_care_low,
            :dla_care_mid,
            :dla_care_high )
        pers.dla_self_care_type = if matches[1] == 1
                low
            elseif matches[1] == 2
                mid
            else
                high
            end
    end

    pers.dla_mobility_type = missing_lmh
    if haskey( incd, dlamobility )
        v = incd[dlamobility]
        matches = get_matches( v, finyear,
            :dla_mobility_low,
            :dla_mobility_high )
        pers.dla_mobility_type = matches[1] == 1 ? low : high # only 2 cases, despite low/mid/high
    end

    pers.attendance_allowance_type = missing_lmh
    if haskey( incd, attendance_allowance )
        v = incd[attendance_allowance]
        matches = get_matches( v,
            finyear,
            :attendance_allowance_low,
            :attendance_allowance_high )
        pers.attendance_allowance_type = matches[1] == 1 ? low : high # only 2 cases, despite low/mid/high
    end
end

end # module

max_stars_repo_name: grahamstark/ScottishTaxBenefitModel

max_issues_repo_name: grahamstark/ScottishTaxBenefitModel

max_forks_repo_name: grahamstark/ScottishTaxBenefitModel


text:
using PkgBenchmark
using Memento

const FMT_STR = "[{level}|{name}] - {msg}"

"""
Sets up our memento logger with a given formatter.
"""
function memento_setup(fmt=DefaultFormatter(FMT_STR))
    return Logger(
        "Benchmarks",
        Dict("Buffer" => DefaultHandler(IOBuffer(),fmt)),
        "info",
        Dict(
           "not_set" => 0,
           "debug" => 10,
           "info" => 20,
           "warn" => 30,
           "error" => 40,
       ),
       DefaultRecord,
       true
    )
end

"""
Builds up a log message comparable to the default log messages
produced in Memento w/ the option to sleep to mimic expensive message
generations.
"""
function base_msg(level, name, msg; sleep_time=0.0)
    d = Dict("level" => level, "name" => name, "msg" => msg)

    function inner_func()
        sleep(sleep_time)

        result = FMT_STR
        for key in ("level", "name", "msg")
            result = replace(result, "{$key}", d[key])
        end

        return result
    end
end

"""
Mocks passing the memento message as a funtion w/
the option to sleep to mimic expensive message generation functions.
"""
function memento_msg(msg; sleep_time=0.0)
    function inner_func()
        sleep(sleep_time)
        return msg
    end
end

# Some basic benchmarks of logging in base julia as a point of reference.
@benchgroup "Base" begin
    @bench(
        "Logging raw string",
        info(io, "[info|Base] - Msg"),
        setup=(io = IOBuffer()),
    )
    @bench(
        "Loggin with interpolation (delay 0.0)",
        info(io, base_msg("info", "Base", "Msg")()),
        setup=(io = IOBuffer()),
    )
    @bench(
        "Logging with interpolation (delay 0.1)",
        info(io, base_msg("info", "Base", "Msg"; sleep_time=0.1)()),
        setup=(io = IOBuffer()),
    )
end

# All our Memento.jl benchmarks.
# NOTE: we're trying to mostly benchmark the general API rather than
# individual components as the implementation may change significantly between
# iterations.
@benchgroup "Memento" begin
    @bench(
        "Unfiltered log (delay 0.0)",
        info(memento_msg("Msg"), logger),
        setup=(logger = memento_setup()),
    )
    @bench(
        "Filtered log (delay 0.0)",
        debug(memento_msg("Msg"), logger),
        setup=(logger = memento_setup()),
    )
    @bench(
        "Unfiltered log (delay 0.1)",
        info(memento_msg("Msg"; sleep_time=0.1), logger),
        setup=(logger = memento_setup()),
    )
    @bench(
        "Filtered log (delay 0.1)",
        debug(memento_msg("Msg"; sleep_time=0.1), logger),
        setup=(logger = memento_setup()),
    )
    @bench(
        "Unfiltered log with StackTrace",
        info(memento_msg("Msg"), logger),
        setup=(logger = memento_setup(DefaultFormatter("[{level}] - {msg} -> {stacktrace}"))),
    )
    @bench(
        "Filtered log with StackTrace",
        debug(memento_msg("Msg"; sleep_time=0.1), logger),
        setup=(logger = memento_setup(DefaultFormatter("[{level}] - {msg} -> {stacktrace}"))),
    )
    @bench(
        "Unfiltered log as JSON (no aliases)",
        info(memento_msg("Msg"), logger),
        setup=(logger = memento_setup(DictFormatter())),
    )
    @bench(
        "Filtered log as JSON (no aliases)",
        debug(memento_msg("Msg"), logger),
        setup=(logger = memento_setup(DictFormatter())),
    )
    no_trace_aliases = Dict(
        :message => :msg,
        :level => :level,
        :logger => :name,
    )
    @bench(
        "Unfiltered log as JSON (aliases w/o trace)",
        info(memento_msg("Msg"), logger),
        setup=(logger = memento_setup(DictFormatter($no_trace_aliases))),
    )
    @bench(
        "Filtered log as JSON (aliases w/o trace)",
        debug(memento_msg("Msg"), logger),
        setup=(logger = memento_setup(DictFormatter($no_trace_aliases))),
    )
    trace_aliases = Dict(
        :backtrace => :stacktrace,
        :message => :msg,
        :level => :level,
        :logger => :name,
    )
    @bench(
        "Unfiltered log as JSON (aliases w/ trace)",
        info(memento_msg("Msg"), logger),
        setup=(logger = memento_setup(DictFormatter($trace_aliases))),
    )
    @bench(
        "Filtered log as JSON (aliases w/ trace)",
        debug(memento_msg("Msg"), logger),
        setup=(logger = memento_setup(DictFormatter($trace_aliases))),
    )
end


text:
using Jtac, Test, Random

Random.seed!(42)

include("game.jl")
include("layers.jl")
include("io.jl")


text:
using WAV
using GR

file = joinpath(dirname(Base.find_package("GR")), "..", "examples", "Monty_Python.wav")
y, fs = WAV.wavread(file)

shade(y, colormap=-GR.COLORMAP_BLUESCALE, ylim=(-1,1))


text:
using Test

using MarketData

using TimeSeries

@testset "broadcast" begin

@testset "base element-wise operators on TimeArray values" begin
    @testset "only values on intersecting Dates computed" begin
        let
            ta = cl[1:2] ./ op[2:3]
            @test values(ta)[1]  ≈ 0.94688222
            @test length(ta)    == 1
        end

        let
            ta = cl[1:4] .+ op[4:7]
            @test values(ta)[1]  ≈ 201.12 atol=.01
            @test length(ta)    == 1
        end
    end

    @testset "unary operation on TimeArray values" begin
        @test values(+cl)[1]                  == values(cl)[1]
        @test values(-cl)[1]                  == -values(cl)[1]
        @test values(.!(cl .== op))[1]        == true
        @test values(log.(cl))[1]             == log.(values(cl)[1])
        @test values(sqrt.(cl))[1]            == sqrt.(values(cl)[1])
        @test values(+ohlc)[1, :]             == values(ohlc)[1,:]
        @test values(-ohlc)[1, :]             == -(values(ohlc)[1,:])
        @test values(.!(ohlc .== ohlc))[1, 1] == false
        @test values(log.(ohlc))[1, :]        == log.(values(ohlc)[1, :])
        @test values(sqrt.(ohlc))[1, :]       == sqrt.(values(ohlc)[1, :])
        @test_throws DomainError sqrt.(-ohlc)
    end

    @testset "dot operation between TimeArray values and Int/Float and viceversa" begin
        @test values(cl .- 100)[1]      ≈ 11.94      atol=.01
        @test values(cl .+ 100)[1]      ≈ 211.94     atol=.01
        @test values(cl .* 100)[1]      ≈ 11194      atol=1
        @test values(cl ./ 100)[1]      ≈ 1.1194     atol=.0001
        @test values(cl .^ 2)[1]        ≈ 12530.5636 atol=.0001
        @test values(cl .% 2)[1]       == values(cl)[1] % 2
        @test values(100 .- cl)[1]      ≈ -11.94 atol=.01
        @test values(100 .+ cl)[1]      ≈ 211.94 atol=.01
        @test values(100 .* cl)[1]      ≈ 11194  atol=.01
        @test values(100 ./ cl)[1]      ≈ 0.8933357155619082
        @test values(2 .^ cl)[1]       == 4980784073277740581384811358191616
        @test values(2 .% cl)[1]       == 2
        @test values(ohlc .- 100)[1,:] == values(ohlc)[1,:] .- 100
        @test values(ohlc .+ 100)[1,:] == values(ohlc)[1,:] .+ 100
        @test values(ohlc .* 100)[1,:] == values(ohlc)[1,:] .* 100
        @test values(ohlc ./ 100)[1,:] == values(ohlc)[1,:] ./ 100
        @test values(ohlc .^ 2)[1,:]   == values(ohlc)[1,:] .^ 2
        @test values(ohlc .% 2)[1,:]   == values(ohlc)[1,:] .% 2
        @test values(100 .- ohlc)[1,:] == 100 .- values(ohlc)[1,:]
        @test values(100 .+ ohlc)[1,:] == 100 .+ values(ohlc)[1,:]
        @test values(100 .* ohlc)[1,:] == 100 .* values(ohlc)[1,:]
        @test values(100 ./ ohlc)[1,:] == 100 ./ values(ohlc)[1,:]
        @test values(2 .^ ohlc)[1,:]   == 2 .^ values(ohlc)[1,:]
        @test values(2 .% ohlc)[1,:]   == 2 .% values(ohlc)[1,:]
    end

    @testset "mathematical operations between two same-column-count TimeArrays" begin
        @test values(cl .+ op)[1]            ≈ 216.82     atol=.01
        @test values(cl .- op)[1]            ≈ 7.06       atol=.01
        @test values(cl .* op)[1]            ≈ 11740.2672 atol=0.0001
        @test values(cl ./ op)[1]            ≈ 1.067315   atol=0.001
        @test values(cl .% op)              == values(cl) .% values(op)
        @test values(cl .^ op)              == values(cl) .^ values(op)
        @test values(cl .* (cl.> 200))      == values(cl) .* (values(cl) .> 200)
        @test values(round.(cl) .* cl)      == round.(Int, values(cl)) .* values(cl)
        @test values(ohlc .+ ohlc)          == values(ohlc) .+ values(ohlc)
        @test values(ohlc .- ohlc)          == values(ohlc) .- values(ohlc)
        @test values(ohlc .* ohlc)          == values(ohlc) .* values(ohlc)
        @test values(ohlc ./ ohlc)          == values(ohlc) ./ values(ohlc)
        @test values(ohlc .% ohlc)          == values(ohlc) .% values(ohlc)
        @test values(ohlc .^ ohlc)          == values(ohlc) .^ values(ohlc)
        @test values(ohlc .* (ohlc .> 200)) == values(ohlc) .* (values(ohlc) .> 200)
        @test values(round.(ohlc) .* ohlc)  == round.(Int, values(ohlc)) .* values(ohlc)
    end

    @testset "broadcasted mathematical operations between different-column-count TimeArrays" begin
        @test values(ohlc .+ cl)          == values(ohlc) .+ values(cl)
        @test values(ohlc .- cl)          == values(ohlc) .- values(cl)
        @test values(ohlc .* cl)          == values(ohlc) .* values(cl)
        @test values(ohlc ./ cl)          == values(ohlc) ./ values(cl)
        @test values(ohlc .% cl)          == values(ohlc) .% values(cl)
        @test values(ohlc .^ cl)          == values(ohlc) .^ values(cl)
        @test values(ohlc .* (cl.> 200))  == values(ohlc) .* (values(cl) .> 200)
        @test values(round.(ohlc) .* cl)  == round.(Int, values(ohlc)) .* values(cl)
        @test values(cl .+ ohlc)          == values(cl) .+ values(ohlc)
        @test values(cl .- ohlc)          == values(cl) .- values(ohlc)
        @test values(cl .* ohlc)          == values(cl) .* values(ohlc)
        @test values(cl ./ ohlc)          == values(cl) ./ values(ohlc)
        @test values(cl .% ohlc)          == values(cl) .% values(ohlc)
        @test values(cl .^ ohlc)          == values(cl) .^ values(ohlc)
        @test values(cl .* (ohlc .> 200)) == values(cl) .* (values(ohlc) .> 200)
        @test values(round.(cl) .* ohlc)  == round.(Int, values(cl)) .* values(ohlc)
        # One array must have a single column
        @test_throws DimensionMismatch (ohlc[:Open, :Close] .+ ohlc)
    end

    @testset "comparison operations between TimeArray values and Int/Float (and viceversa)" begin
        @test values(cl .> 111.94)[1]      == false
        @test values(cl .< 111.94)[1]      == false
        @test values(cl .>= 111.94)[1]     == true
        @test values(cl .<= 111.94)[1]     == true
        @test values(cl .== 111.94)[1]     == true
        @test values(cl .!= 111.94)[1]     == false
        @test values(111.94 .> cl)[1]      == false
        @test values(111.94 .< cl)[1]      == false
        @test values(111.94 .>= cl)[1]     == true
        @test values(111.94 .<= cl)[1]     == true
        @test values(111.94 .== cl)[1]     == true
        @test values(111.94 .!= cl)[1]     == false
        @test values(ohlc .> 111.94)[1,:]  == [false, true, false, false]
        @test values(ohlc .< 111.94)[1,:]  == [true, false, true, false]
        @test values(ohlc .>= 111.94)[1,:] == [false, true, false, true]
        @test values(ohlc .<= 111.94)[1,:] == [true, false, true, true]
        @test values(ohlc .== 111.94)[1,:] == [false, false, false, true]
        @test values(ohlc .!= 111.94)[1,:] == [true, true, true, false]
        @test values(111.94 .> ohlc)[1,:]  == [true, false, true, false]
        @test values(111.94 .< ohlc)[1,:]  == [false, true, false, false]
        @test values(111.94 .>= ohlc)[1,:] == [true, false, true, true]
        @test values(111.94 .<= ohlc)[1,:] == [false, true, false, true]
        @test values(111.94 .== ohlc)[1,:] == [false, false, false, true]
        @test values(111.94 .!= ohlc)[1,:] == [true, true, true, false]
    end

    @testset "comparison operations between TimeArray values and Bool (and viceversa)" begin
        @test values((cl .> 111.94) .== true)[1]     == false
        @test values((cl .> 111.94) .!= true)[1]     == true
        @test values(true .== (cl .> 111.94))[1]     == false
        @test values(true .!= (cl .> 111.94))[1]     == true
        @test values((ohlc .> 111.94).== true)[1,:]  == [false, true, false, false]
        @test values((ohlc .> 111.94).!= true)[1,:]  == [true, false, true, true]
        @test values(true .== (ohlc .> 111.94))[1,:] == [false, true, false, false]
        @test values(true .!= (ohlc .> 111.94))[1,:] == [true, false, true, true]
    end

    @testset "comparison operations between same-column-count TimeArrays" begin
        @test values(cl .> op)[1]        == true
        @test values(cl .< op)[1]        == false
        @test values(cl .<= op)[1]       == false
        @test values(cl .>= op)[1]       == true
        @test values(cl .== op)[1]       == false
        @test values(cl .!= op)[1]       == true
        @test values(ohlc .> ohlc)[1,:]  == [false, false, false, false]
        @test values(ohlc .< ohlc)[1,:]  == [false, false, false, false]
        @test values(ohlc .<= ohlc)[1,:] == [true, true, true, true]
        @test values(ohlc .>= ohlc)[1,:] == [true, true, true, true]
        @test values(ohlc .== ohlc)[1,:] == [true, true, true, true]
        @test values(ohlc .!= ohlc)[1,:] == [false, false, false, false]
    end

    @testset "comparison operations between different-column-count TimeArrays" begin
        @test values(ohlc .> cl)  == (values(ohlc) .> values(cl))
        @test values(ohlc .< cl)  == (values(ohlc) .< values(cl))
        @test values(ohlc .>= cl) == (values(ohlc) .>= values(cl))
        @test values(ohlc .<= cl) == (values(ohlc) .<= values(cl))
        @test values(ohlc .== cl) == (values(ohlc) .== values(cl))
        @test values(ohlc .!= cl) == (values(ohlc) .!= values(cl))
        @test values(cl .> ohlc)  == (values(cl) .> values(ohlc))
        @test values(cl .< ohlc)  == (values(cl) .< values(ohlc))
        @test values(cl .>= ohlc) == (values(cl) .>= values(ohlc))
        @test values(cl .<= ohlc) == (values(cl) .<= values(ohlc))
        @test values(cl .== ohlc) == (values(cl) .== values(ohlc))
        @test values(cl .!= ohlc) == (values(cl) .!= values(ohlc))
        # One array must have a single column
        @test_throws DimensionMismatch (ohlc[:Open, :Close] .== ohlc)
    end

    @testset "bitwise elementwise operations between bool and TimeArrays' values" begin
        @test values((cl .> 100) .& true)[1]      == true
        @test values((cl .> 100) .| true)[1]      == true
        @test values((cl .> 100) .⊻ true)[1]      == false
        @test values(false .& (cl .> 100))[1]     == false
        @test values(false .| (cl .> 100))[1]     == true
        @test values(false .⊻ (cl .> 100))[1]     == true
        @test values((ohlc .> 100) .& true)[4,:]  == [true, true, false, false]
        @test values((ohlc .> 100) .| true)[4,:]  == [true, true, true, true]
        @test values((ohlc .> 100) .⊻ true)[4,:]  == [false, false, true, true]
        @test values(false .& (ohlc .> 100))[4,:] == [false, false, false, false]
        @test values(false .| (ohlc .> 100))[4,:] == [true, true, false, false]
        @test values(false .⊻ (ohlc .> 100))[4,:] == [true, true, false, false]
      end

    @testset "bitwise elementwise operations between same-column-count TimeArrays' boolean values" begin
        @test values((cl .> 100) .& (cl .< 120))[1]       == true
        @test values((cl .> 100) .| (cl .< 120))[1]       == true
        @test values((cl .> 100) .⊻ (cl .< 120))[1]       == false
        @test values((ohlc .> 100) .& (ohlc .< 120))[4,:] == [true, true, false, false]
        @test values((ohlc .> 100) .| (ohlc .< 120))[4,:] == [true, true, true, true]
        @test values((ohlc .> 100) .⊻ (ohlc .< 120))[4,:] == [false, false, true, true]
        @test values((ohlc .> 100) .⊻ (cl .< 120))[4,:]   == [false, false, true, true]
    end
end

@testset "dot call auto-fusion" begin
    @testset "single TimeArray" begin
        let ta = sin.(log.(2, op))
            @test colnames(ta) == [:Open]
            @test timestamp(ta) == timestamp(op)
            @test meta(ta) == meta(op)
            @test values(ta)[1] == sin(log(2, values(op)[1]))
            @test values(ta)[end] == sin(log(2, values(op)[end]))
        end

        f(x, c) = x + c
        let ta = f.(cl, 42)
            @test colnames(ta) == [:Close]
            @test timestamp(ta) == timestamp(cl)
            @test meta(ta) == meta(cl)
            @test values(ta)[1] == values(cl)[1] + 42
            @test values(ta)[end] == values(cl)[end] + 42
        end

        let ta = sin.(log.(2, ohlc))
            @test colnames(ta) == [:Open, :High, :Low, :Close]
            @test timestamp(ta) == timestamp(ohlc)
            @test meta(ta) == meta(ohlc)

            @test values(ta)[1, 1] == sin(log(2, values(ohlc)[1, 1]))
            @test values(ta)[1, 2] == sin(log(2, values(ohlc)[1, 2]))
            @test values(ta)[1, 3] == sin(log(2, values(ohlc)[1, 3]))
            @test values(ta)[1, 4] == sin(log(2, values(ohlc)[1, 4]))

            @test values(ta)[end, 1] == sin(log(2, values(ohlc)[end, 1]))
            @test values(ta)[end, 2] == sin(log(2, values(ohlc)[end, 2]))
            @test values(ta)[end, 3] == sin(log(2, values(ohlc)[end, 3]))
            @test values(ta)[end, 4] == sin(log(2, values(ohlc)[end, 4]))
        end
    end

    @testset "TimeArray and Array" begin
        let ta = cl[1:4] .+ [1, 2, 3, 4]
            @test colnames(ta) == [:Close]
            @test timestamp(ta) == timestamp(cl)[1:4]
            @test meta(ta) == meta(cl)

            @test values(ta)[1] == values(cl)[1] + 1
            @test values(ta)[2] == values(cl)[2] + 2
            @test values(ta)[3] == values(cl)[3] + 3
            @test values(ta)[4] == values(cl)[4] + 4
        end

        let ta = ohlc[1:4] .+ [1, 2, 3, 4]
            @test colnames(ta) == [:Open, :High, :Low, :Close]
            @test timestamp(ta) == timestamp(ohlc)[1:4]
            @test meta(ta) == meta(ohlc)

            @test values(ta)[1, 1] == values(ohlc)[1, 1] + 1
            @test values(ta)[1, 2] == values(ohlc)[1, 2] + 1
            @test values(ta)[1, 3] == values(ohlc)[1, 3] + 1
            @test values(ta)[1, 4] == values(ohlc)[1, 4] + 1
        end

        let arr = [1, 2, 3, 4]
            @test_throws DimensionMismatch cl .+ arr
        end
    end

    @testset "custom function" begin
        let f(x, y, c) = x - y + c, ta = f.(op, cl, 42)
            @test colnames(ta) == [:Open_Close]
            @test timestamp(ta) == timestamp(cl)
            @test timestamp(ta) == timestamp(op)
            @test meta(ta) == meta(op)
            @test values(ta)[1] == values(op)[1] - values(cl)[1] + 42
            @test values(ta)[end] == values(op)[end] - values(cl)[end] + 42
        end
    end

    @testset "broadcast 2D TimeArray" begin
        let A = reshape(values(cl), 500, 1)  # 2D, dim -> 500×1
          ta = TimeArray(timestamp(cl), A) .+ ohlc
          @test length(colnames(ta)) == 4
          @test timestamp(ta) == timestamp(cl)
        end
    end
end  # @testset "dot call auto-fusion"

end  # @testset "broadcast"


text:
const symbol_numbers = Dict{Symbol, Int}()

"""Return a new, unique symbol like _z3.
Updates the global dict `symbol_numbers`"""
function make_symbol(s::Symbol)

    i = get(symbol_numbers, s, 0)
    symbol_numbers[s] = i + 1

    if i == 0
        return Symbol("_", s)
    else
        return Symbol("_", s, i)
    end
end

make_symbol(c::Char) = make_symbol(Symbol(c))

make_variable(s) = Variable(make_symbol(s))

let current_symbol = 'a'

    """Make a new symbol like `_c`.
    Cycles through the alphabet and adds numbers if necessary.
    """
    global function make_variable()
        current_sym = current_symbol

        if current_sym < 'z'
            current_symbol += 1
        else
            current_symbol = 'a'
        end

        return make_variable(current_sym)

    end
end


text: julia --color=yes -L ../../src/BlackBoxOptim.jl compare_optimizers.jl list --benchmarkfile benchmark_runs_150712.csv -o latest_toplist.csv


text:
using Test
using CausalDiscovery

function construct_data()
  Dict([("external" => []),
        ("initnext" => []),
        ("lifted" => []),
        ("types" => Dict())])
end

mod = nothing

function isinferred(f, args...; allow = Union{})
  ret = f(args...)
  inftypes = Base.return_types(f, Base.typesof(args...))
  rettype = ret isa Type ? Type{ret} : typeof(ret)
  rettype <: allow || rettype == Test.typesubtract(inftypes[1], allow)
end

function test_compile_if()
  data = construct_data()
  aexpr = au"""(if (== x 3) then (= y 4) else (= y 5))"""
  @test string(compile(aexpr, data)) == "if x == 3\n    y = 4\nelse\n    y = 5\nend"
end

function test_compile_assign()
  data = construct_data()
  aexpr = au"""(= x 3)"""
  @test compile(aexpr, data) == :(x = 3)
end

function test_compile_typedecl()
  data = construct_data()
  aexpr = au"""(: x Int)"""
  @test compile(aexpr, data) == :(local x::Int)
end

function test_compile_external()
  data = construct_data()
  aexpr = au"""(external (: click Click))"""
  @test compile(aexpr, data) == :()
end

function test_compile_let()
  data = construct_data()
  aexpr = au"""(let ((= y 3) (= x y)) x)"""

  @test compile(aexpr, data).args[end - 2: end] == [:(y = 3), :(x = y), :x]
end

function test_compile_list()
  data = construct_data()
  aexpr = au"""(list 1 2 3 4 5)"""
  @test compile(aexpr, data) == :([1, 2, 3, 4, 5])
end

function test_compile_call()
  data = construct_data()
  aexpr = au"""(f 1 2 3) """
  @test compile(aexpr, data) == :(f(1, 2, 3))
end

function test_compile_field()
  data = construct_data()
  aexpr = au"""(.. position x)"""
  @test compile(aexpr, data) == :(position.x)
end

function test_compile_particles()
  a = au"""(program
    (: GRID_SIZE Int)
    (= GRID_SIZE 16)

    (type alias Position ((: x Int) (: y Int)))
    (type alias Particle ((: position Position)))

    (external (: click Click))

    (: particles (List Particle))
    (= particles (initnext (list) (if (occurred click)
                                then (push! (prev particles) (particleGen (Position 1 1)))
                                else (map nextParticle (prev particles)))))
    (: nparticles Int)
    (= nparticles (length particles))

    (: isFree (-> Position Bool))
    (= isFree (fn (position)
                  (== (length (filter (--> particle (== (.. particle position) position)) (prev particles))) 0)))

    (: isWithinBounds (-> Position Bool))
    (= isWithinBounds (fn (position)
                          (& (>= (.. position x) 0) (& (< (.. position x) GRID_SIZE) (& (>= (.. position y) 0) (< (.. position y) GRID_SIZE))))))

    (: adjacentPositions (-> Position (List Position)))
    (= adjacentPositions (fn (position)
                            (let ((= x (.. position x))
                                  (= y (.. position y))
                                  (= positions (filter isWithinBounds (list (Position (+ x 1) y) (Position (- x 1) y) (Position x (+ y 1)) (Position x (- y 1))))))
                                  positions)))

    (: nextParticle (-> Particle Particle))
    (= nextParticle (fn (particle)
                        (let ((= freePositions (filter isFree (adjacentPositions (.. particle position)))))
                            (case freePositions
                                  (=> (list) particle)
                                  (=> _ (Particle (uniformChoice freePositions)))))))

    (: particleGen (-> Position Particle))
    (= particleGen (fn (initPosition) (Particle initPosition)))
  )"""
  @test string(compiletojulia(a)) == "\$(Expr(:toplevel, :(module CompiledProgram\n  export init, next\n  import Base.min\n  using Distributions\n  using MLStyle: @match\n  begin\n      function occurred(click)\n          click !== nothing\n      end\n  end\n  begin\n      function uniformChoice(freePositions)\n          freePositions[rand(Categorical(ones(length(freePositions)) / length(freePositions)))]\n      end\n  end\n  begin\n      function uniformChoice(freePositions, n)\n          map((idx->begin\n                      freePositions[idx]\n                  end), rand(Categorical(ones(length(freePositions)) / length(freePositions)), n))\n      end\n  end\n  begin\n      function min(arr)\n          min(arr...)\n      end\n  end\n  begin\n      struct Click\n          x::BigInt\n          y::BigInt\n      end\n  end\n  begin\n      function range(start::BigInt, stop::BigInt)\n          [start:stop;]\n      end\n  end\n  begin\n      struct Position\n          x::Int\n          y::Int\n      end\n  end\n  begin\n      struct Particle\n          position::Position\n      end\n  end\n  begin\n      function isFree(position::Position)::Bool\n          length(filter((particle->begin\n                              particle.position == position\n                          end), particlesPrev())) == 0\n      end\n  end\n  begin\n      function isWithinBounds(position::Position)::Bool\n          (position.x >= 0) & ((position.x < GRID_SIZE) & ((position.y >= 0) & (position.y < GRID_SIZE)))\n      end\n  end\n  begin\n      function adjacentPositions(position::Position)::Array{Position}\n          begin\n              x = position.x\n              y = position.y\n              positions = filter(isWithinBounds, [Position(x + 1, y), Position(x - 1, y), Position(x, y + 1), Position(x, y - 1)])\n              positions\n          end\n      end\n  end\n  begin\n      function nextParticle(particle::Particle)::Particle\n          begin\n              freePositions = filter(isFree, adjacentPositions(particle.position))\n              begin\n                  @match freePositions begin\n                          [] => particle\n                          _ => Particle(uniformChoice(freePositions))\n                      end\n              end\n          end\n      end\n  end\n  begin\n      function particleGen(initPosition::Position)::Particle\n          Particle(initPosition)\n      end\n  end\n  begin\n      mutable struct STATE\n          time::Int\n          particlesHistory::Dict{Int64, Array{Particle}}\n          GRID_SIZEHistory::Dict{Int64, Int}\n          nparticlesHistory::Dict{Int64, Int}\n          clickHistory::Dict{Int64, Union{Click, Nothing}}\n      end\n  end\n  state = STATE(0, Dict{Int64, Array{Particle}}(), Dict{Int64, Int}(), Dict{Int64, Int}(), Dict{Int64, Union{Click, Nothing}}())\n  begin\n      function particlesPrev(n::Int=1)::Array{Particle}\n          state.particlesHistory[if state.time - n >= 0\n                  state.time - n\n              else\n                  0\n              end]\n      end\n  end\n  begin\n      function GRID_SIZEPrev(n::Int=1)::Int\n          state.GRID_SIZEHistory[if state.time - n >= 0\n                  state.time - n\n              else\n                  0\n              end]\n      end\n  end\n  begin\n      function nparticlesPrev(n::Int=1)::Int\n          state.nparticlesHistory[if state.time - n >= 0\n                  state.time - n\n              else\n                  0\n              end]\n      end\n  end\n  begin\n      function clickPrev(n::Int=1)::Union{Click, Nothing}\n          state.clickHistory[if state.time - n >= 0\n                  state.time - n\n              else\n                  0\n              end]\n      end\n  end\n  begin\n      function init(click::Union{Click, Nothing})::STATE\n          state = STATE(0, Dict{Int64, Array{Particle}}(), Dict{Int64, Int}(), Dict{Int64, Int}(), Dict{Int64, Union{Click, Nothing}}())\n          particles = []\n          GRID_SIZE = 16\n          nparticles = length(particles)\n          state.clickHistory[state.time] = click\n          state.particlesHistory[state.time] = particles\n          state.GRID_SIZEHistory[state.time] = GRID_SIZE\n          state.nparticlesHistory[state.time] = nparticles\n          deepcopy(state)\n      end\n  end\n  begin\n      function next(old_state::STATE, click::Union{Click, Nothing})::STATE\n          global state = deepcopy(old_state)\n          state.time = state.time + 1\n          particles = if occurred(click)\n                  push!(particlesPrev(), particleGen(Position(1, 1)))\n              else\n                  map(nextParticle, particlesPrev())\n              end\n          GRID_SIZE = 16\n          nparticles = length(particles)\n          state.clickHistory[state.time] = click\n          state.particlesHistory[state.time] = particles\n          state.GRID_SIZEHistory[state.time] = GRID_SIZE\n          state.nparticlesHistory[state.time] = nparticles\n          deepcopy(state)\n      end\n  end\n  end)))"
  global mod = eval(compiletojulia(a))
end

function test_compile_types_inferred()
  @test isinferred(mod.init, nothing)
  @test isinferred(mod.init, mod.Click(5,5))
  state = mod.init(nothing)
  @test isinferred(mod.next, state, mod.Click(5,5))
  @test isinferred(mod.next, state, nothing)
end

@testset "compile" begin
  test_compile_if()
  test_compile_assign()
  test_compile_typedecl()
  test_compile_external()
  test_compile_let()
  test_compile_list()
  test_compile_call()
  test_compile_field()
  test_compile_particles()
  test_compile_types_inferred()
end


text:
"""
    parse_repo(node, spdx::AbstractString)::NamedTuple

Parses a node and returns a suitable `NamedTuple` for the table.
"""
function parse_repo(node, spdx::AbstractString)
    @unpack id, createdAt, nameWithOwner, description, primaryLanguage, defaultBranchRef = node
    (id = id,
     spdx = spdx,
     slug = nameWithOwner,
     createdat = DateTime(replace(createdAt, "Z" => "")),
     description = something(description, missing),
     primarylanguage = isnothing(primaryLanguage) ? missing : primaryLanguage.name,
     branch = isnothing(defaultBranchRef) ? missing : defaultBranchRef.id,
     commits = isnothing(defaultBranchRef) ? 0 : defaultBranchRef.target.history.totalCount,
    )
end
"""
    find_repos(batch::AbstractDataFrame)::Nothing

Takes a batch of 10 spdx/createdat and puts the data in the database.
"""
function find_repos(batch::AbstractDataFrame)
    @unpack conn, schema = PARALLELENABLER
    output = DataFrame(id = String[], spdx = String[], slug = String[], createdat = DateTime[],
                       description = Union{Missing, String}[], primarylanguage = Union{Missing, String}[],
                       branch = Union{Missing, String}[], commits = Int[])
    subsquery = join([ string("_$idx:search(query:\"is:public fork:false mirror:false archived:false license:$(batch.spdx[idx]) created:",
                     format(batch.created[idx].first, "yyyy-mm-ddTHH:MM:SS\\Z"),
                     "..",
                     format(batch.created[idx].last, "yyyy-mm-ddTHH:MM:SS\\Z"),
                     "\",type:REPOSITORY, first:10, after:\$cursor_$idx){...A}") for idx in 1:size(batch, 1)]);
    query = string(String(read(joinpath(pkgdir(GHOST), "src", "assets", "graphql", "02_repos.graphql"))),
                          "query Search(\$until:String!,",
                          join((("\$cursor_$idx:String") for idx in 1:size(batch, 1)), ','),
                          "){$subsquery}") |>
        (obj -> replace(obj, r"\s+" => " ")) |>
        strip |>
        string;
    vars = Dict("until" => "$(parse(Int, match(r"\d{4}$", schema).match) + 1)-01-01T00:00:00Z")
    while true
        sleep(0.25)
        result = graphql(query, vars = vars)
        :Data ∈ propertynames(result) || return result
        json = JSON3.read(result.Data)
        append!(output,
                reduce(vcat,
                       DataFrame(parse_repo(node.node, spdx) for node in elem.edges)
                       for (elem, spdx) in zip(values(json.data), batch[!,:spdx])))
        any(elem -> elem.pageInfo.hasNextPage, values(json.data)) || break
        for idx in eachindex(json.data)
            if !isnothing(json.data[idx].pageInfo.endCursor)
                push!(vars, "cursor$idx" => json.data[idx].pageInfo.endCursor)
            end
        end
    end
    execute(conn, "BEGIN;")
    load!(output,
          conn,
          string("INSERT INTO $schema.repos VALUES(",
                 join(("\$$i" for i in 1:size(output, 2)), ','),
                 ") ON CONFLICT DO NOTHING;"))
    execute(conn, "COMMIT;")
    for row in eachrow(batch)
        execute(conn,
                """
                UPDATE $schema.queries
                SET done = true
                WHERE spdx = '$(row.spdx)' AND '$(row.created.first)'::timestamp <@ created
                ;
                """)
    end
end


text:
# Spherical harmonic I/O, storage, and conversions

# Spherical harmonic I/O

# SHRead
# SHRead2
# SHReadJPL

# Spherical harmonic storage

export SHCilmToCindex!
"""
    cindex = SHCilmToCindex!(cindex::AbstractArray{Cdouble,2},
                             cilm::AbstractArray{Cdouble,3};
                             degmax::Optional{Cint}=nothing,
                             exitstatus::Optional{Ref{<:Integer}}=nothing)
    cindex::AbstractArray{Cdouble,2}

Convert a three-dimensional array of spherical harmonic coefficients
to a two-dimensional indexed array.

See also: [`SHCilmToCindex`](@ref), [`SHCindexToCilm!`](@ref),
[`SHCilmToVector!`](@ref)
"""
function SHCilmToCindex!(cindex::AbstractArray{Cdouble,2},
                         cilm::AbstractArray{Cdouble,3};
                         degmax::Optional{Cint}=nothing,
                         exitstatus::Optional{Ref{<:Integer}}=nothing)
    @assert size(cilm, 1) == 2
    lmaxin = size(cilm, 2) - 1
    @assert lmaxin ≥ 0
    @assert size(cilm, 3) == size(cilm, 2)
    degmax′ = optional(degmax, lmaxin)
    @assert size(cindex, 1) == 2
    @assert size(cindex, 2) ≥ (degmax′ + 1) * (degmax′ + 2) ÷ 2
    exitstatus′ = Ref{Cint}()
    ccall((:SHCilmToCindex, libSHTOOLS), Cvoid,
          (Ptr{Cdouble}, Cint, Ptr{Cdouble}, Cint, Ref{Cint}, Ref{Cint}), cilm,
          size(cilm, 2), cindex, size(cindex, 2), degmax′, exitstatus′)
    if exitstatus === nothing
        exitstatus′[] ≠ 0 &&
            error("SHCilmToCindex!: Error code $(exitstatus′[])")
    else
        exitstatus[] = exitstatus′[]
    end
    return cindex
end

export SHCilmToCindex
"""
    cindex = SHCilmToCindex(cilm::AbstractArray{Cdouble,3};
                            degmax::Optional{Cint}=nothing,
                            exitstatus::Optional{Ref{<:Integer}}=nothing)
    cindex::Array{Cdouble,2}

Convert a three-dimensional array of spherical harmonic coefficients
to a two-dimensional indexed array.

See also: [`SHCilmToCindex!`](@ref), [`SHCindexToCilm`](@ref),
[`SHCilmToVector`](@ref)
"""
function SHCilmToCindex(cilm::AbstractArray{Cdouble,3};
                        degmax::Optional{Cint}=nothing,
                        exitstatus::Optional{Ref{<:Integer}}=nothing)
    @assert size(cilm, 1) == 2
    lmaxin = size(cilm, 2) - 1
    @assert lmaxin ≥ 0
    @assert size(cilm, 3) == size(cilm, 2)
    degmax′ = optional(degmax, lmaxin)
    cindex = Array{Cdouble}(undef, 2, (degmax′ + 1) * (degmax′ + 2) ÷ 2)
    SHCilmToCindex!(cindex, cilm; degmax=degmax, exitstatus=exitstatus)
    return cindex
end

export SHCindexToCilm!
"""
    cilm = SHCindexToCilm!(cilm::AbstractArray{Cdouble,3},
                           cindex::AbstractArray{Cdouble,2};
                           degmax::Optional{Cint}=nothing,
                           exitstatus::Optional{Ref{<:Integer}}=nothing)
    cilm::AbstractArray{Cdouble,3},

Convert a two-dimensional indexed array of spherical harmonic
coefficients to a three-dimensional array.

See also: [`SHCindexToCilm`](@ref), [`SHCilmToCindex!`](@ref),
[`SHVectorToCilm!`](@ref)
"""
function SHCindexToCilm!(cilm::AbstractArray{Cdouble,3},
                         cindex::AbstractArray{Cdouble,2};
                         degmax::Optional{Cint}=nothing,
                         exitstatus::Optional{Ref{<:Integer}}=nothing)
    @assert size(cindex, 1) == 2
    # (lmaxin + 1) * (lmaxin + 2) ÷ 2 = size(cindex, 2)
    lmaxin = round(Int, (sqrt(8 * size(cindex, 2) + 1) - 3) / 2)
    @assert size(cindex, 2) == (lmaxin + 1) * (lmaxin + 2) ÷ 2
    degmax′ = optional(degmax, lmaxin)
    @assert size(cindex, 2) ≥ degmax′
    @assert size(cilm, 1) == 2
    @assert size(cilm, 2) ≥ degmax′ + 1
    @assert size(cilm, 3) == size(cilm, 2)
    exitstatus′ = Ref{Cint}()
    ccall((:SHCindexToCilm, libSHTOOLS), Cvoid,
          (Ptr{Cdouble}, Cint, Ptr{Cdouble}, Cint, Ref{Cint}, Ref{Cint}),
          cindex, size(cindex, 2), cilm, size(cilm, 2), degmax′, exitstatus′)
    if exitstatus === nothing
        exitstatus′[] ≠ 0 &&
            error("SHCindexToCilm!: Error code $(exitstatus′[])")
    else
        exitstatus[] = exitstatus′[]
    end
    return cilm
end

export SHCindexToCilm
"""
    cilm = SHCindexToCilm(cindex::AbstractArray{Cdouble,2};
                          degmax::Optional{Cint}=nothing,
                          exitstatus::Optional{Ref{<:Integer}}=nothing)
    cilm::AbstractArray{Cdouble,3},

Convert a two-dimensional indexed array of spherical harmonic
coefficients to a three-dimensional array.

See also: [`SHCindexToCilm!`](@ref), [`SHCilmToCindex`](@ref),
[`SHVectorToCilm`](@ref)
"""
function SHCindexToCilm(cindex::AbstractArray{Cdouble,2},
                        degmax::Optional{Cint}=nothing,
                        exitstatus::Optional{Ref{<:Integer}}=nothing)
    @assert size(cindex, 1) == 2
    # (lmaxin + 1) * (lmaxin + 2) ÷ 2 = size(cindex, 2)
    lmaxin = round(Int, (sqrt(8 * size(cindex, 2) + 1) - 3) / 2)
    @assert size(cindex, 2) == (lmaxin + 1) * (lmaxin + 2) ÷ 2
    degmax′ = optional(degmax, lmaxin)
    @assert size(cindex, 2) ≥ degmax′
    cilm = Array{Cdouble}(undef, 2, degmax′ + 1, degmax′ + 1)
    SHCindexToCilm!(cilm, cindex; degmax=degmax, exitstatus=exitstatus)
    return cilm
end

export SHCilmToVector!
"""
    SHCilmToVector!(vector::AbstractVector{Cdouble},
                    cilm::AbstractArray{Cdouble,3},
                    lmax::Integer;
                    exitstatus::Union{Nothing,Ref{<:Integer}}=nothing)

Convert a three-dimensional array of real spherical harmonic
coefficients to a 1-dimensional indexed vector.

See also: [`SHCilmToVector`](@ref)
"""
function SHCilmToVector!(vector::AbstractVector{Cdouble},
                         cilm::AbstractArray{Cdouble,3}, lmax::Integer;
                         exitstatus::Optional{Ref{<:Integer}}=nothing)
    @assert lmax ≥ 0
    @assert length(vector) ≥ (lmax + 1)^2
    @assert size(cilm, 1) == 2
    @assert size(cilm, 2) ≥ lmax + 1
    @assert size(cilm, 3) == size(cilm, 2)
    exitstatus′ = Ref{Cint}()
    ccall((:SHCilmToVector, libSHTOOLS), Cvoid,
          (Ptr{Cdouble}, Cint, Ptr{Cdouble}, Cint, Ref{Cint}), cilm,
          size(cilm, 2), vector, lmax, exitstatus′)
    if exitstatus === nothing
        exitstatus′[] ≠ 0 &&
            error("SHCilmToVector!: Error code $(exitstatus′[])")
    else
        exitstatus[] = exitstatus′[]
    end
    return vector
end

export SHCilmToVector
"""
    vector = SHCilmToVector(cilm::AbstractArray{Cdouble,3},
                            lmax::Integer;
                            exitstatus::Union{Nothing,Ref{<:Integer}}=nothing)
    vector::Vector{Cdouble}

Convert a three-dimensional array of real spherical harmonic
coefficients to a 1-dimensional indexed array.

See also: [`SHCilmToVector!`](@ref)
"""
function SHCilmToVector(cilm::AbstractArray{Cdouble,3}, lmax::Integer;
                        exitstatus::Optional{Ref{<:Integer}}=nothing)
    @assert lmax ≥ 0
    vector = Array{Cdouble}(undef, (lmax + 1)^2)
    SHCilmToVector!(vector, cilm, lmax; exitstatus=exitstatus)
    return vector
end

export SHVectorToCilm!
"""
    SHVectorToCilm!(cilm::AbstractArray{Cdouble,3},
                    vector::AbstractVector{Cdouble},
                    lmax::Integer;
                    exitstatus::Union{Nothing,Ref{<:Integer}}=nothing)

Convert a 1-dimensional indexed vector of real spherical harmonic
coefficients to a 3-dimensional array.

See also: [`SHVectorToCilm`](@ref)
"""
function SHVectorToCilm!(cilm::AbstractArray{Cdouble,3},
                         vector::AbstractVector{Cdouble}, lmax::Integer;
                         exitstatus::Optional{Ref{<:Integer}}=nothing)
    @assert lmax ≥ 0
    @assert size(cilm, 1) == 2
    @assert size(cilm, 2) ≥ lmax + 1
    @assert size(cilm, 3) == size(cilm, 2)
    @assert length(vector) ≥ (lmax + 1)^2
    exitstatus′ = Ref{Cint}()
    ccall((:SHVectorToCilm, libSHTOOLS), Cvoid,
          (Ptr{Cdouble}, Ptr{Cdouble}, Cint, Cint, Ref{Cint}), vector, cilm,
          size(cilm, 2), lmax, exitstatus′)
    if exitstatus === nothing
        exitstatus′[] ≠ 0 &&
            error("SHVectorToCilm!: Error code $(exitstatus′[])")
    else
        exitstatus[] = exitstatus′[]
    end
    return cilm
end

export SHVectorToCilm
"""
    cilm = SHVectorToCilm(cilm::AbstractArray{Cdouble,3},
                          vector::AbstractVector{Cdouble},
                          lmax::Integer;
                          exitstatus::Union{Nothing,Ref{<:Integer}}=nothing)
    cilm::Array{Cdouble,3}

Convert a 1-dimensional indexed vector of real spherical harmonic
coefficients to a 3-dimensional array.

See also: [`SHVectorToCilm!`](@ref)
"""
function SHVectorToCilm(vector::AbstractVector{Cdouble}, lmax::Integer;
                        exitstatus::Optional{Ref{<:Integer}}=nothing)
    @assert lmax ≥ 0
    cilm = Array{Cdouble}(undef, 2, lmax + 1, lmax + 1)
    @assert length(vector) ≥ (lmax + 1)^2
    exitstatus′ = Ref{Cint}()
    SHVectorToCilm!(cilm, vector, lmax; exitstatus=exitstatus)
    return cilm
end

export YlmIndexVector
"""
    index = YlmIndexVector(i, l, m)

Determine the index of a 1D ordered vector of spherical harmonic
coefficients corresponding to `i`, `l`, and `m`.

See also: [`SHCilmToVector!`](@ref), [`SHCilmToVector`](@ref),
[`SHVectorToCilm!`](@ref), [`SHVectorToCilm`](@ref)
"""
function YlmIndexVector(i::Integer, l::Integer, m::Integer)
    @assert 1 ≤ i ≤ 2
    @assert 0 ≤ l
    @assert 0 ≤ m ≤ l
    return l^2 + (i - 1) * l + m + 1
end


text:
fname = :TRMA97
c = Combi(hessian_dense,PDataMA97,solve_modelTRDiag,preprocessMA97,decreaseFact,Tparam())
include("Template.jl")


text:
function get_p(obj::SchurTransformer)
    return jcall(obj, "getP", RealMatrix, ())
end

function get_pt(obj::SchurTransformer)
    return jcall(obj, "getPT", RealMatrix, ())
end

function get_t(obj::SchurTransformer)
    return jcall(obj, "getT", RealMatrix, ())
end


text:
using StatsBase

abstract type Agent end
abstract type Animal <: Agent end
abstract type Plant <: Agent end

mutable struct World{A<:Agent}
    agents::Dict{Int,A}
    max_id::Int
end
function World(agents::Vector{<:Agent})
    World(Dict(id(a)=>a for a in agents), maximum(id.(agents)))
end

# optional: you can overload the `show` method to get custom
# printing of your World
function Base.show(io::IO, w::World)
    println(io, typeof(w))
    for (_,a) in w.agents
        println(io,"  $a")
    end
end

function world_step!(world::World)
    # make sure that we only iterate over IDs that already exist in the
    # current timestep this lets us safely add agents
    ids = deepcopy(keys(world.agents))

    for id in ids
        # agents can be killed by other agents, so make sure that we are
        # not stepping dead agents forward
        !haskey(world.agents,id) && continue

        a = world.agents[id]
        agent_step!(a,world)
    end
end

function agent_step!(a::Plant, w::World)
    if size(a) != max_size(a)
        grow!(a)
    end
end

function agent_step!(a::Animal, w::World)
    incr_energy!(a,-1)
    if rand() <= foodprob(a)
        dinner = find_food(a,w)
        eat!(a, dinner, w)
    end
    if energy(a) <= 0
        kill_agent!(a,w)
        return
    end
    if rand() <= reprprob(a)
        reproduce!(a,w)
    end
    return a
end

mutable struct Grass <: Plant
    id::Int
    size::Int
    max_size::Int
end
Grass(id,m) = Grass(id, rand(1:m), m)

mutable struct Sheep <: Animal
    id::Int
    energy::Float64
    Δenergy::Float64
    reprprob::Float64
    foodprob::Float64
end

mutable struct Wolf <: Animal
    id::Int
    energy::Float64
    Δenergy::Float64
    reprprob::Float64
    foodprob::Float64
end

id(a::Agent) = a.id  # every agent has an ID so we can just define id for Agent here

Base.size(a::Plant) = a.size
max_size(a::Plant) = a.max_size
grow!(a::Plant) = a.size += 1

# get field values
energy(a::Animal) = a.energy
Δenergy(a::Animal) = a.Δenergy
reprprob(a::Animal) = a.reprprob
foodprob(a::Animal) = a.foodprob

# set field values
energy!(a::Animal, e) = a.energy = e
incr_energy!(a::Animal, Δe) = energy!(a, energy(a)+Δe)

function Base.show(io::IO, g::Grass)
    x = size(g)/max_size(g) * 100
    print(io,"🌿 #$(id(g)) $(round(Int,x))% grown")
end
function Base.show(io::IO, w::Wolf)
    e = energy(w)
    d = Δenergy(w)
    pr = reprprob(w)
    pf = foodprob(w)
    print(io,"🐺 #$(id(w)) E=$e ΔE=$d pr=$pr pf=$pf")
end
function Base.show(io::IO, s::Sheep)
    e = energy(s)
    d = Δenergy(s)
    pr = reprprob(s)
    pf = foodprob(s)
    print(io,"🐑 #$(id(s)) E=$e ΔE=$d pr=$pr pf=$pf")
end

function eat!(a::Sheep, b::Grass, w::World)
    incr_energy!(a, size(b)*Δenergy(a))
    b.size = 0
end
function eat!(wolf::Wolf, sheep::Sheep, w::World)
    incr_energy!(wolf, energy(sheep)*Δenergy(wolf))
    kill_agent!(sheep,w)
end
eat!(a::Animal,b::Nothing,w::World) = nothing

kill_agent!(a::Animal, w::World) = delete!(w.agents, id(a))

function find_food(a::Animal, w::World)
    as = filter(x->eats(a,x), w.agents |> values |> collect)
    isempty(as) ? nothing : sample(as)
end

eats(::Sheep,g::Grass) = size(g) > 0
eats(::Wolf,::Sheep) = true
eats(::Agent,::Agent) = false

function reproduce!(a::A, w::World) where A<:Animal
    energy!(a, energy(a)/2)
    a_vals = [getproperty(a,n) for n in fieldnames(A) if n!=:id]
    new_id = w.max_id + 1
    â = A(new_id, a_vals...)
    w.agents[id(â)] = â
    w.max_id = new_id
end


text:
@inline CI(a...) = CartesianIndex(a...)
@inline δ(a,d::Int) = CI(ntuple(i -> i==a ? 1 : 0, d))
@inline δ(a,I::CartesianIndex{N}) where {N} = δ(a,N)

@inline CR(a...) = CartesianIndices(a...)
@inline inside(M::NTuple{N,Int}) where {N} = CR(ntuple(i-> 2:M[i]-1,N))
@inline inside(a::Array; reverse::Bool=false) =
        reverse ? Iterators.reverse(inside(size(a))) : inside(size(a))
@inline inside_u(N::NTuple{n,T}) where {n,T} = CR(ntuple(i->2:N[i],n-1))
function inside_u(N::NTuple{n,Int},j::Int)::CartesianIndices{n} where n
    CartesianIndices(ntuple( i-> i==j ? (3:N[i]-1) : (2:N[i]), n))
end

import Base.mapreduce
@fastmath function mapreduce(f,op,R::CartesianIndices;init=0.)
    val = init
    @inbounds @simd for I ∈ R
        val = op(val,f(I))
    end
    val
end
L₂(a::Array{Float64}) = mapreduce(I->@inbounds(abs2(a[I])),+,inside(a))

macro inside(ex)
    @assert ex.head==:(=)
    a,I = Meta.parse.(split(string(ex.args[1]),union("[","]")))
    return quote
        @inbounds @simd for $I ∈ inside($a)
            $ex
        end
    end |> esc
end

function median(a,b,c)
    if a>b
        b>=c && return b
        a>c && return c
    else
        b<=c && return b
        a<c && return c
    end
    return a
end

"""
    apply(f, N...)

Apply a vector function f(i,x) to the faces of a uniform staggered grid.
"""
function apply(f,N...)
    # TODO be more clever with the type
    c = Array{Float64}(undef,N...)
    apply!(f,c)
    return c
end
function apply!(f,c)
    N = size(c)
    for b ∈ 1:N[end]
        @simd for I ∈ CR(N[1:end-1])
            x = collect(Float16, I.I) # location at cell center
            x[b] -= 0.5               # location at face
            @inbounds c[I,b] = f(b,x) # apply function to location
        end
    end
end

"""
    slice(N,s,dims) -> R

Return `CartesianIndices` slicing through an array of size `N`.
"""
function slice(N::NTuple{n,Int},s::Int,dims::Int,low::Int=1)::CartesianIndices{n} where n
    CartesianIndices(ntuple( i-> i==dims ? (s:s) : (low:N[i]), n))
end

function BC!(a::Array{T,m},A,f=1) where {T,m}
    n = m-1
    N = ntuple(i -> size(a,i), n)
    for j ∈ 1:n, i ∈ 1:n
        if i==j # Inline direction
            for s ∈ (1,2,N[j]); @simd for I ∈ slice(N,s,j)
                a[I,i] = f*A[i] # Dirichlet
            end; end
        else    # Perpendicular directions
            @simd for I ∈ slice(N,1,j)
                a[I,i] = a[I+δ(j,I),i] # Neumann
            end
            @simd for I ∈ slice(N,N[j],j)
                a[I,i] = a[I-δ(j,I),i] # Neumann
            end
        end
    end
end
function BC!(a::Array{T,n}) where {T,n}
    N = size(a)
    for j ∈ 1:n
        @simd for I ∈ slice(N,1,j)
            a[I] = a[I+δ(j,I)] # Neumann
        end
        @simd for I ∈ slice(N,N[j],j)
            a[I] = a[I-δ(j,I)] # Neumann
        end
    end
end


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

struct ApplicationGatewayPrivateEndpointConnectionsApi <: SwaggerApi
    client::Swagger.Client
end

"""

Deletes the specified private endpoint connection on application gateway.
Param: resourceGroupName::String (required)
Param: applicationGatewayName::String (required)
Param: connectionName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: Nothing
"""
function _swaggerinternal_applicationGatewayPrivateEndpointConnectionsDelete(_api::ApplicationGatewayPrivateEndpointConnectionsApi, resourceGroupName::String, applicationGatewayName::String, connectionName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "DELETE", Nothing, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/privateEndpointConnections/{connectionName}", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "applicationGatewayName", applicationGatewayName)  # type String
    Swagger.set_param(_ctx.path, "connectionName", connectionName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function applicationGatewayPrivateEndpointConnectionsDelete(_api::ApplicationGatewayPrivateEndpointConnectionsApi, resourceGroupName::String, applicationGatewayName::String, connectionName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_applicationGatewayPrivateEndpointConnectionsDelete(_api, resourceGroupName, applicationGatewayName, connectionName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function applicationGatewayPrivateEndpointConnectionsDelete(_api::ApplicationGatewayPrivateEndpointConnectionsApi, response_stream::Channel, resourceGroupName::String, applicationGatewayName::String, connectionName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_applicationGatewayPrivateEndpointConnectionsDelete(_api, resourceGroupName, applicationGatewayName, connectionName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Gets the specified private endpoint connection on application gateway.
Param: resourceGroupName::String (required)
Param: applicationGatewayName::String (required)
Param: connectionName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: ApplicationGatewayPrivateEndpointConnection
"""
function _swaggerinternal_applicationGatewayPrivateEndpointConnectionsGet(_api::ApplicationGatewayPrivateEndpointConnectionsApi, resourceGroupName::String, applicationGatewayName::String, connectionName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", ApplicationGatewayPrivateEndpointConnection, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/privateEndpointConnections/{connectionName}", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "applicationGatewayName", applicationGatewayName)  # type String
    Swagger.set_param(_ctx.path, "connectionName", connectionName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function applicationGatewayPrivateEndpointConnectionsGet(_api::ApplicationGatewayPrivateEndpointConnectionsApi, resourceGroupName::String, applicationGatewayName::String, connectionName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_applicationGatewayPrivateEndpointConnectionsGet(_api, resourceGroupName, applicationGatewayName, connectionName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function applicationGatewayPrivateEndpointConnectionsGet(_api::ApplicationGatewayPrivateEndpointConnectionsApi, response_stream::Channel, resourceGroupName::String, applicationGatewayName::String, connectionName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_applicationGatewayPrivateEndpointConnectionsGet(_api, resourceGroupName, applicationGatewayName, connectionName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Lists all private endpoint connections on an application gateway.
Param: resourceGroupName::String (required)
Param: applicationGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: ApplicationGatewayPrivateEndpointConnectionListResult
"""
function _swaggerinternal_applicationGatewayPrivateEndpointConnectionsList(_api::ApplicationGatewayPrivateEndpointConnectionsApi, resourceGroupName::String, applicationGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", ApplicationGatewayPrivateEndpointConnectionListResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/privateEndpointConnections", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "applicationGatewayName", applicationGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function applicationGatewayPrivateEndpointConnectionsList(_api::ApplicationGatewayPrivateEndpointConnectionsApi, resourceGroupName::String, applicationGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_applicationGatewayPrivateEndpointConnectionsList(_api, resourceGroupName, applicationGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function applicationGatewayPrivateEndpointConnectionsList(_api::ApplicationGatewayPrivateEndpointConnectionsApi, response_stream::Channel, resourceGroupName::String, applicationGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_applicationGatewayPrivateEndpointConnectionsList(_api, resourceGroupName, applicationGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Updates the specified private endpoint connection on application gateway.
Param: resourceGroupName::String (required)
Param: applicationGatewayName::String (required)
Param: connectionName::String (required)
Param: parameters::ApplicationGatewayPrivateEndpointConnection (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: ApplicationGatewayPrivateEndpointConnection
"""
function _swaggerinternal_applicationGatewayPrivateEndpointConnectionsUpdate(_api::ApplicationGatewayPrivateEndpointConnectionsApi, resourceGroupName::String, applicationGatewayName::String, connectionName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "PUT", ApplicationGatewayPrivateEndpointConnection, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/privateEndpointConnections/{connectionName}", ["azure_auth"], parameters)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "applicationGatewayName", applicationGatewayName)  # type String
    Swagger.set_param(_ctx.path, "connectionName", connectionName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function applicationGatewayPrivateEndpointConnectionsUpdate(_api::ApplicationGatewayPrivateEndpointConnectionsApi, resourceGroupName::String, applicationGatewayName::String, connectionName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_applicationGatewayPrivateEndpointConnectionsUpdate(_api, resourceGroupName, applicationGatewayName, connectionName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function applicationGatewayPrivateEndpointConnectionsUpdate(_api::ApplicationGatewayPrivateEndpointConnectionsApi, response_stream::Channel, resourceGroupName::String, applicationGatewayName::String, connectionName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_applicationGatewayPrivateEndpointConnectionsUpdate(_api, resourceGroupName, applicationGatewayName, connectionName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

export applicationGatewayPrivateEndpointConnectionsDelete, applicationGatewayPrivateEndpointConnectionsGet, applicationGatewayPrivateEndpointConnectionsList, applicationGatewayPrivateEndpointConnectionsUpdate