text:
# make your scripts automatically re-activate your project
cd(@__DIR__)
using Pkg; Pkg.activate("."); Pkg.instantiate()

# load packages
using StochasticDiffEq, DiffEqCallbacks
using Plots
using Statistics
using LinearAlgebra
using Random
using DiffEqNoiseProcess
using LaTeXStrings
#################################################
# parameters
numtrajplot = 256 # .. for plotting

# time range for the solver
dt = 0.0001f0 #0.001f0
tinterval = 0.02f0
tstart = 0.0f0
Nintervals = 150 # total number of intervals, total time = t_interval*Nintervals
tspan = (tstart,tinterval*Nintervals)
ts = Array(tstart:dt:(Nintervals*tinterval+dt)) # time array for noise grid

# Hamiltonian parameters
Δ = 20.0f0
Ωmax = 10.0f0 # control parameter (maximum amplitude)
κ = 1.0f0

# loss hyperparameters
C1 = Float32(1.0)  # evolution state fidelity
C2 = Float32(0.0) # action amplitudes
C3 = Float32(0.0) # evolution state fidelity for last few steps!

struct Parameters{flType,intType,tType}
	numtrajplot::intType
	dt::flType
	tinterval::flType
	tspan::tType
	Nintervals::intType
	ts::Vector{flType}
	Δ::flType
	Ωmax::flType
	κ::flType
	C1::flType
	C2::flType
	C3::flType
end

myparameters = Parameters{typeof(dt),typeof(numtrajplot), typeof(tspan)}(
  numtrajplot, dt, tinterval, tspan, Nintervals, ts,
  Δ, Ωmax, κ, C1, C2, C3)

###############################################
# strategy

function control(u, Ωmax)
  ceR, cdR, ceI, cdI = u

  if (cdI*ceR-cdR*ceI) > 0
   Ω = Ωmax
  else
	Ω = -Ωmax
  end
  return Ω
end

###############################################
# initial state anywhere on the Bloch sphere
function prepare_initial(dt, n_par)
  # shape 4 x n_par
  # input number of parallel realizations and dt for type inference
  # random position on the Bloch sphere
  theta = acos.(2*rand(typeof(dt),n_par).-1)  # uniform sampling for cos(theta) between -1 and 1
  phi = rand(typeof(dt),n_par)*2*pi  # uniform sampling for phi between 0 and 2pi
  # real and imaginary parts ceR, cdR, ceI, cdI
  u0 = [cos.(theta/2), sin.(theta/2).*cos.(phi), false*theta, sin.(theta/2).*sin.(phi)]
  return vcat(transpose.(u0)...) # build matrix
end

# target state
# ψtar = |up>

u0 = prepare_initial(myparameters.dt, myparameters.numtrajplot)

###############################################
# Define SDE

function qubit_drift!(du,u,p,t)
  # expansion coefficients |Ψ> = ce |e> + cd |d>
  ceR, cdR, ceI, cdI = u # real and imaginary parts

  # Δ: atomic frequency
  # Ω: Rabi frequency for field in x direction
  # κ: spontaneous emission
  Δ, Ωmax, κ = p[1:3]
  Ω = control(u, Ωmax)

  @inbounds begin
    du[1] = 1//2*(ceI*Δ-ceR*κ+cdI*Ω)
    du[2] = -cdI*Δ/2 + 1*ceR*(cdI*ceI+cdR*ceR)*κ+ceI*Ω/2
    du[3] = 1//2*(-ceR*Δ-ceI*κ-cdR*Ω)
    du[4] = cdR*Δ/2 + 1*ceI*(cdI*ceI+cdR*ceR)*κ-ceR*Ω/2
  end
  return nothing
end

function qubit_diffusion!(du,u,p,t)
  ceR, cdR, ceI, cdI = u # real and imaginary parts

  κ = p[end]

  du .= false

  @inbounds begin
    #du[1] = zero(ceR)
    du[2] += sqrt(κ)*ceR
    #du[3] = zero(ceR)
    du[4] += sqrt(κ)*ceI
  end
  return nothing
end

# normalization callback
condition(u,t,integrator) = true
function affect!(integrator)
  integrator.u=integrator.u/norm(integrator.u)
end
cb = DiscreteCallback(condition,affect!,save_positions=(false,false))

CreateGrid(t,W1) = NoiseGrid(t,W1)

# set scalar random process
W = sqrt(myparameters.dt)*randn(typeof(myparameters.dt),size(myparameters.ts)) #for 1 trajectory
W1 = cumsum([zero(myparameters.dt); W[1:end-1]], dims=1)
NG = CreateGrid(myparameters.ts,W1)

# get control pulses
p_all = [myparameters.Δ; myparameters.Ωmax; myparameters.κ]
# define SDE problem
prob = SDEProblem{true}(qubit_drift!, qubit_diffusion!, vec(u0[:,1]), myparameters.tspan, p_all,
   callback=cb, noise=NG
   )

#########################################
# visualization -- run for new batch
function visualize(u0, prob::SDEProblem, myparameters::Parameters;
	 alg=EulerHeun(), all_traj = true
	 )
  pars = [myparameters.Δ; myparameters.Ωmax; myparameters.κ]

  function prob_func(prob, i, repeat)
    # prepare initial state and applied control pulse
    u0tmp = deepcopy(vec(u0[:,i]))
    W = sqrt(myparameters.dt)*randn(typeof(myparameters.dt),size(myparameters.ts)) #for 1 trajectory
    W1 = cumsum([zero(myparameters.dt); W[1:end-1]], dims=1)
    NG = CreateGrid(myparameters.ts,W1)

    remake(prob,
	    p = pars,
	  	u0 = u0tmp,
  	  	callback = cb,
		noise=NG
		)
  end

  ensembleprob = EnsembleProblem(prob,
   prob_func = prob_func,
   safetycopy = true
   )

  u = solve(ensembleprob, alg, EnsembleThreads(),
 	saveat=myparameters.tinterval,
 	dt=myparameters.dt,
 	adaptive=false, #abstol=1e-6, reltol=1e-6,
 	trajectories=myparameters.numtrajplot, batch_size=myparameters.numtrajplot)

  ceR = @view u[1,:,:]
  cdR = @view u[2,:,:]
  ceI = @view u[3,:,:]
  cdI = @view u[4,:,:]
  infidelity = @. (cdR^2 + cdI^2) / (ceR^2 + cdR^2 + ceI^2 + cdI^2)
  meaninfidelity = mean(infidelity)
  loss = myparameters.C1*meaninfidelity

  @info "Loss: " loss

  fidelity = @. (ceR^2 + ceI^2) / (ceR^2 + cdR^2 + ceI^2 + cdI^2)

  mf = mean(fidelity, dims=2)[:]
  sf = std(fidelity, dims=2)[:]

  # re-compute actions
  arrayu = Array(u)
  Ωlist = []
  for i = 1:(size(arrayu)[2])
    Ω = [control(arrayu[:,i,j], myparameters.Ωmax) for j = 1:(size(arrayu)[3])]
    push!(Ωlist, Ω)
  end
  Ωlist = hcat(Ωlist...)
  ma = mean(Ωlist, dims=1)[:]
  sa = std(Ωlist, dims=1)[:]
  #@show size(Ωlist) size(sa)

  pl1 = plot(0:myparameters.Nintervals, mf,
      ribbon = sf,
      ylim = (0,1), xlim = (0,myparameters.Nintervals),
      c=:navyblue, lw = 1.5, xlabel = L"i", title=L"F(t_i)", legend=false, grid=false)
  pl2 = plot(0:myparameters.Nintervals, ma,
      ribbon = sa,
      ylim=(-myparameters.Ωmax,myparameters.Ωmax), xlim = (0,myparameters.Nintervals),
      c=:orangered4, lw = 1.5, xlabel = L"i", title=L"\Omega(t_i)", legend=false, grid=false)
  if all_traj
     plot!(pl1, fidelity, legend=false, c=:gray, alpha=0.1)
     plot!(pl2, Ωlist', legend=false, c=:gray, alpha=0.1)
  else
     plot!(pl1, 0:myparameters.Nintervals, fidelity[:,end],  c=:black, lw = 1.5, legend=false)
     plot!(pl2, 0:myparameters.Nintervals, Ωlist[end,:], c=:black, lw = 1.5, legend=false)
  end

  pl = plot(pl1, pl2, layout = (1, 2), legend = false, size=(800,360))
  return pl1, pl2, loss, infidelity
end

u0 = prepare_initial(myparameters.dt, myparameters.numtrajplot)
u0[1,end] = 0.0f0
u0[2,end] = 1.0f0
u0[3,end] = 0.0f0
u0[4,end] = 0.0f0
pl1, pl2, lossval1, infid = @time visualize(u0, prob, myparameters, all_traj=false)

@info 1-mean(infid)
@info std(infid)

# pl = plot(pl1, pl2, margin=3.0Plots.mm, legend = false, size=(600,300))
# savefig(pl,"Figures/hand_crafted.png")

exit()


text:
function barplot(;x::AbstractVector = Int[],
                  y::AbstractVector = Int[],
                  y2::AbstractVector = Int[],
                  group::AbstractVector = Int[],
                  stacked::Bool = false,
                  horizontal::Bool = false,
                  normalize::Bool = false)

    v = VegaVisualization()

    add_data!(v, x = x, y = y, group = group, y2 = y2)
    default_scales!(v; typeXaxis = "ordinal")
    default_axes!(v)

    #Get unique table name
    table = v.data[1].name

    #If non-zero group is passed, add a legend
    if group != Int[]
      legend!(v)
    end

    #old add_rects code
    res = VegaMark(_type = "rect",
                  from = VegaMarkFrom(data=table),
                  properties = VegaMarkProperties(enter = VegaMarkPropertySet(x = VegaValueRef(scale = "x", field = "x"),
                                                                              y = VegaValueRef(scale = "y", field = "y"))
                                                  )
                  )

    v.marks == nothing? v.marks = [res] : push!(v.marks, res)
    #end add_rects code

    v.marks[1].properties.enter.width = VegaValueRef(scale = "x", band = true, offset = -1)
    v.marks[1].properties.enter.y = VegaValueRef(scale = "y", field = "y")
    v.marks[1].properties.enter.y2 = VegaValueRef(scale = "y", field = "y2")
    v.marks[1].properties.enter.fill = VegaValueRef(scale = "group", field = "group")

    if stacked
      push!(v.data, VegaData(name = "stats", source = table,
                             transform = [VegaTransform(Dict{Any, Any}("type"=> "aggregate", "groupby" => ["x"], "summarize"=>[Dict{Any,Any}("field" => "y", "ops" => ["sum"])]))]))

      # bind the y scale to layout start and layout end
      v.marks[1].properties.enter.y = VegaValueRef(scale = "y", field = "layout_start")
      v.marks[1].properties.enter.y2 = VegaValueRef(scale = "y", field = "layout_end")

      v.scales[2].domain = VegaDataRef(data = "stats", field = "sum_y")

      v.marks[1].from = VegaMarkFrom(data = table,
                                     transform = [VegaTransform(Dict{Any, Any}("type" => "stack", "groupby" => ["x"], "sortby" => ["group"], "field"=>"y", "offset" => normalize == true? "normalize" : "zero"))])

      if normalize
        ylim!(v, min = 0, max = 1)
      end

    end

    #Return horizontal bar chart
    if horizontal
        coord_flip!(v)
    end

    return v
end

ext: jl

max_stars_repo_name: jpthor/vega


text:
using StanSample, DataFrames

model = "
data {
  int<lower=0> N;
  int<lower=0,upper=1> y[N];
}
parameters {
  real<lower=0,upper=1> theta;
}
model {
  theta ~ beta(1,1);
    y ~ bernoulli(theta);
}
";

sm = SampleModel("bernoulli", model);

data = Dict("N" => 10, "y" => [0, 1, 0, 1, 0, 0, 0, 0, 0, 1]);

rc = stan_sample(sm; num_chains=4, data);

if success(rc)
  df = read_samples(sm, :dataframe);
  df |> display
end


text:
function versioninfo(io::IO=stdout)
    println("HSA Runtime ($(hsa_configured ? "ready" : "MISSING"))")
    if hsa_configured
        println("- Version: $(libhsaruntime_version)")
        println("- Initialized: $(repr(HSA_REFCOUNT[] > 0))")
    end
    println("HIP Runtime ($(hip_configured ? "ready" : "MISSING"))")
    if hip_configured
        # TODO: println("- Version: $(libhip_version)")
    end
    println("ROCm-Device-Libs ($(device_libs_configured ? "ready" : "MISSING"))")
    if device_libs_configured
        # TODO: println("- Version: $(device_libs_version)")
        println("- Downloaded: $(repr(device_libs_downloaded))")
    end
    println("rocBLAS ($(librocblas !== nothing ? "ready" : "MISSING"))")
    println("rocFFT ($(librocfft !== nothing ? "ready" : "MISSING"))")
    println("rocRAND ($(librocrand !== nothing ? "ready" : "MISSING"))")
    println("rocSPARSE ($(librocsparse !== nothing ? "ready" : "MISSING"))")
    println("rocALUTION ($(librocalution !== nothing ? "ready" : "MISSING"))")
    println("MIOpen ($(libmiopen !== nothing ? "ready" : "MISSING"))")

    if hsa_configured && HSA_REFCOUNT[] > 0
        println("HSA Agents ($(length(agents()))):")
        for agent in agents()
            println("- ", repr(agent))
        end
    end
end

function has_rocm_gpu()
    if !AMDGPU.hsa_configured
        return false
    else
        return length(AMDGPU.get_agents(:gpu)) > 0
    end
end


text:
# Main Embedder type, parametrized by S - typeof embedded object
# and T the type of Float of the vectors
abstract type AbstractEmbedder{T<:AbstractFloat,S}  end

"""
    document2vec(embedder, document [;isregex=false])

Embeds documents. The document representation is conceptually a vector
of sentences, the output is always a vector of floating point numbers.

# Arguments
  * `embedder::AbstractEmbedder` is the embedder
  * `document::Vector{AbstractString}` the document to be embedded,
     where each vector element corresponds to a sentence

# Keyword arguments
  * `isregex::Bool` a `false` value (default) specifies that the
     document tokens are to be matched exactly while a `true` value
     specifies that the tokens are to be matched partially
     (for DTV-based document embedding only)
"""
function document2vec(embedder::AbstractEmbedder, document::Vector{AbstractString}; kwargs...)
    # Prototype of the function only
    throw(ErrorException("`document2vec` is not implemented for the current arguments."))
end

"""
    sentences2vec(embedder, document_embedding, embedded_words [;dim=0])

Returns a matrix of sentence embeddings from a vector of matrices containing
individual sentence word embeddings. Used mostly for word-vectors based
embedders.

# Arguments
  * `embedder::AbstractEmbedder` is the embedder
  * `document_embedding::Vector{Matrix{AbstractFloat}}` are the document's
     word embeddings, where each element of the vector represents the
     embedding of a sentence (whith the matrix columns individual word
     embeddings)

# Keyword arguments
  * `dim::Int` is the dimension of the word embeddings i.e. number of
     components in the word vector (default `0`)
  * `embedded_words::Vector{Vector{AbstractString}}` are the words in
     each sentence the were embedded (their order corresponds to the
     order of the matrix columns in `document_embedding`

"""
function sentences2vec(embedder::AbstractEmbedder,
                       document_embedding::Vector{Matrix{AbstractFloat}};
                       kwargs...)
    # Prototype of the function only
    throw(ErrorException("`sentences2vec` is not implemented for the current arguments."))
end

function build_embedder(dbdata,
                        config;
                        vectors_eltype=DEFAULT_VECTORS_ELTYPE,
                        id_key=DEFAULT_ID_KEY)
    flags = config.text_strip_flags | (config.stem_words ? stem_words : 0x0)
    language = get(STR_TO_LANG, config.language, DEFAULT_LANGUAGE)()

    # Create documents
    documents = [join(dbentry2text(dbentry, config.embeddable_fields), " ")
              for dbentry in db_sorted_row_iterator(dbdata; id_key=id_key, rev=false)]

    # Build embedders
    if config.vectors in [:word2vec, :glove, :conceptnet, :compressed]
        return build_wv_embedder(documents, config; vectors_eltype=vectors_eltype)
    elseif config.vectors in [:count, :tf, :tfidf, :bm25]
        return build_dtv_embedder(documents, config; vectors_eltype=vectors_eltype)
    end
end

function build_dtv_embedder(documents, config; vectors_eltype=DEFAULT_VECTORS_ELTYPE)
    # Initialize dtm
    dtm = DocumentTermMatrix{vectors_eltype}(documents, ngram_complexity=config.ngram_complexity)
    mtype = RPModel
    k = 0
    config.vectors_transform === :none && true  # do nothing, mtype and k are initialized
    config.vectors_transform === :rp && (k=config.vectors_dimension)  # modify k
    config.vectors_transform === :lsa && (mtype=LSAModel, k=config.vectors_dimension)
    return DTVEmbedder(mtype,
                       dtm,
                       config;
                       # kwargs defaults from Garamond (override StringAnalysis defaults)
                       κ=DEFAULT_BM25_KAPPA,
                       β=DEFAULT_BM25_BETA,
                       # kwargs from config (overwritten by one below)
                       config.embedder_kwarguments...,
                       # specific kwargs from config (have highest priority)
                       k=k,
                       stats=config.vectors,
                       ngram_complexity=config.ngram_complexity)
end

function build_wv_embedder(documents, config; vectors_eltype=DEFAULT_VECTORS_ELTYPE)
    # Read word embeddings
    local embeddings
    if config.vectors == :conceptnet
        embeddings = load_embeddings(config.embeddings_path,
                                     languages=[Languages.English()],
                                     data_type=vectors_eltype)
    elseif config.vectors == :word2vec
        embeddings = Word2Vec.wordvectors(config.embeddings_path,
                                          vectors_eltype,
                                          kind=config.embeddings_kind,
                                          normalize=false)
    elseif config.vectors == :glove
        embeddings = Glowe.wordvectors(config.embeddings_path,
                                       vectors_eltype,
                                       kind=config.embeddings_kind,
                                       vocabulary=config.glove_vocabulary,
                                       normalize=false,
                                       load_bias=false)
    elseif config.vectors == :compressed
        embeddings = EmbeddingsAnalysis.compressedwordvectors(
                        config.embeddings_path,
                        vectors_eltype,
                        kind=config.embeddings_kind)
    end

    # Construct embedder based on document2vec method
    config.doc2vec_method === :boe &&
        return BOEEmbedder(embeddings,
                           config;
                           config.embedder_kwarguments...);
    config.doc2vec_method === :sif &&
        return SIFEmbedder(embeddings,
                           config;
                           config.embedder_kwarguments...,
                           lexicon=create_lexicon(documents, 1),
                           alpha=config.sif_alpha)
    config.doc2vec_method === :borep &&
        return BOREPEmbedder(embeddings,
                             config;
                             config.embedder_kwarguments...,
                             dim=config.borep_dimension,
                             pooling_function=config.borep_pooling_function)
    config.doc2vec_method === :cpmean &&
        return CPMeanEmbedder(embeddings,
                              config;
                              config.embedder_kwarguments...)
    config.doc2vec_method === :disc &&
        return DisCEmbedder(embeddings,
                            config;
                            config.embedder_kwarguments...,
                            n=config.disc_ngram)
end

Base.zeros(::AbstractSparseArray, T, dims) = spzeros(T, dims...)

Base.zeros(::AbstractArray, T, dims) = zeros(T, dims...)

firstcol(m::AbstractMatrix) = m[:,1]

function embed!(out::AbstractMatrix{T},
                is_embedded::BitArray,
                embedder::AbstractEmbedder{T},
                entries;
                fields=nothing,
                kwargs...) where {T}
    flags = embedder.config.text_strip_flags | (embedder.config.stem_words ? stem_words : 0x0)
    language = get(STR_TO_LANG, embedder.config.language, DEFAULT_LANGUAGE)()
    documents = [dbentry2text(entry, fields) for entry in entries]
    for i in eachindex(documents)
        out[:,i], is_embedded[i] = document2vec(embedder,
                                        prepare.(documents[i], flags; language=language);
                                        kwargs...)
    end
    nothing
end

function embed(embedder::AbstractEmbedder, entries; fields=nothing, kwargs...)
    n = length(entries)
    embedded = preallocate_embeddings(embedder, n)
    isemb = falses(n)
    embed!(embedded, isemb, embedder, entries; fields=fields, kwargs...)
    return embedded, isemb
end

function preallocate_embeddings(embedder::AbstractEmbedder{T,S}, len) where {T,S}
    m, _ = document2vec(embedder, S[])
    p = similar(m, T, (dimensionality(embedder), len))
    fill!(p, zero(T))
    return p
end


text:
function all_divisors(factors::Nemo.Fac{T}) where T <: Integer
	divisors = []

	function generate_divisors(curIndex::Int, curDivisor::T, factors::Nemo.Fac)
		result = iterate(factors, curIndex)
		if isnothing(result)
			push!(divisors, curDivisor)
			return
		else
			(pf, nextIndex) = result
		end

		for i = 0:pf.second
			generate_divisors(nextIndex, curDivisor, factors);
			curDivisor *= pf.first
		end
	end

	generate_divisors(1, T(1), factors)
	divisors
end

# Find all inverses of the Euler Totient function.
# This implements the algorithm of Contini, Croot, and Shparlinski (2006)
function inv_totient(x::T) where T <: Integer
	invs = Set{T}()

	function totient_reps(x::T, factor_list::Vector{Tuple{T,Int}})
		if x<1
			return
		end

		if x==1
			m = prod([p[1]^(p[2]+1) for p in factor_list[2:end]])
			push!(invs, m)
		end

		# TODO: Don't need to recalcuate this each time.
		factors = Nemo.factor(x)

		# Find all divisors of x of the form (p^0)*(p-1), where p is a prime
		for divisor in all_divisors(factors)
			d = divisor+1
			if Nemo.isprime(d) && d > factor_list[end][1]
				pair = (d, 0)
				totient_reps(div(x, divisor), cat(factor_list, pair, dims=1))
			end
		end

		# Find all divisors of x of the form (p^γ)*(p-1), γ>=1, where p is a prime
		for factor in factors
			for γ = 1:factor.second
				d = (factor.first^γ)*(factor.first-1)
				if divrem(x, d)[2]==0 && factor.first > factor_list[end][1]
					pair = (factor.first, γ)
					totient_reps(div(x, d), cat(factor_list, pair, dims=1))
				end
			end
		end
	end

	totient_reps(x, [(T(0),0)])

	return invs
end


text:
# This script actually solves the CoeurdacierReyWinant model with a risk-adjusted linearization
# and times the methods, if desired
using BenchmarkTools, RiskAdjustedLinearizations, Test, JLD2
include("crw.jl")

# Settings
diagnostics = true

# Set up
m_crw = CoeurdacierReyWinant()
m = crw(m_crw)
z0 = copy(m.z)
y0 = copy(m.y)
Ψ0 = copy(m.Ψ)

sssout = JLD2.jldopen(joinpath(dirname(@__FILE__), "..", "..", "test", "reference/crw_sss.jld2"), "r")

# Small perturbation b/c initialized at the stochastic steady state from a saved file
m.z .= 1.1 * m.z
m.y .= 1.1 * m.y
m.Ψ .= 1.1 * m.Ψ

# Solve!
solve!(m, m.z, m.y, m.Ψ; algorithm = :homotopy, step = .5)

# Only homotopy seems to work for this model. The relaxation algorithm
# has trouble finding an answer with smaller error than 1e-3
# solve!(m, m.z, m.y, m.Ψ; algorithm = :relaxation, verbose = :high, ftol = 5e-5, damping = .9)

@test isapprox(sssout["z_rss"], m.z)
@test isapprox(sssout["y_rss"], m.y)
@test isapprox(sssout["Psi_rss"], m.Ψ)

if diagnostics
    # See crw.jl for the definition of the functions
    # crw_cₜ, crw_logSDFxR, crw_𝔼_quadrature, and crw_endo_states
    shocks = JLD2.jldopen(joinpath(dirname(@__FILE__), "..", "..", "test", "reference", "crw_shocks.jld2"), "r")["shocks"]
    @test abs(euler_equation_error(m, crw_cₜ, crw_logSDFxR, crw_𝔼_quadrature, shocks, summary_statistic = x -> norm(x, Inf))) < 3e-5
    c_err, endo_states_err = dynamic_euler_equation_error(m, crw_cₜ, crw_logSDFxR, crw_𝔼_quadrature, crw_endo_states, 1, shocks)
    @test c_err < 2e-5
    @test endo_states_err < 1e-3
end


text:
push!(LOAD_PATH, "../src/")
include("../src/FCA.jl")
using Main.FCA
using Test
using Combinatorics, ForwardDiff, LinearAlgebra, Statistics

# function calculates relative error
function rel_error(x, y)
    return findmax(abs.(x - y) ./ (max.(1e-8, abs.(x) + abs.(y))))[1]
end

tests = [
    "embed.jl",
    "free_whiten.jl",
    "gradient.jl",
    "icf.jl",
    "fcf.jl"
]

# test embed
@testset "Test $script" for script in tests
    println(script)
    @time include(script)
end


text:
using PosteriorPlots
using Test
using Turing, Distributions, RDatasets, MCMCChains, Plots, StatsPlots, Random
using MLDataUtils: shuffleobs, splitobs, rescale!

Random.seed!(0)
Turing.setprogress!(false)

#------------- Run package tests --------------------

@testset "PosteriorPlots.jl" begin

    # Define an example model from the Turing.jl documentation

    data = RDatasets.dataset("datasets", "mtcars")

    # Remove the model column

    select!(data, Not(:Model))

    # Split our dataset 70%/30% into training/test sets

    trainset, testset = splitobs(shuffleobs(data), 0.7)

    # Turing requires data in matrix form

    target = :MPG
    train = Matrix(select(trainset, Not(target)))
    test = Matrix(select(testset, Not(target)))
    train_target = trainset[:, target]
    test_target = testset[:, target]

    # Standardize the features

    μ, σ = rescale!(train; obsdim = 1)
    rescale!(test, μ, σ; obsdim = 1)
    μtarget, σtarget = rescale!(train_target; obsdim = 1)
    rescale!(test_target, μtarget, σtarget; obsdim = 1)

    # Linear regression model

    @model function linear_regression(x, y)
        σ₂ ~ truncated(Normal(0, 100), 0, Inf)
        intercept ~ Normal(0, sqrt(3))
        nfeatures = size(x, 2)
        coefficients ~ MvNormal(nfeatures, sqrt(10))

        mu = intercept .+ x * coefficients
        y ~ MvNormal(mu, sqrt(σ₂))
    end

    model = linear_regression(train, train_target)
    chain = sample(model, NUTS(0.65), 3_000);

    #------------------------------
    # Run core PosteriorPlots tests
    #------------------------------

    p =  plot_posterior_intervals(chain)
    @test p isa Plots.Plot

    p1 = plot(plot_posterior_hist(chain, true)...)
    @test p1 isa Plots.Plot

    p2 = plot(plot_posterior_density(chain, true)...)
    @test p2 isa Plots.Plot

    #p3 =  plot_density_check(posterior)
    #@test isa(p3, Plot)

    #p4 =  plot_hist_check(posterior)
    #@test isa(p4, Plot)

    #p5 =  plot_ecdf_check(posterior)
    #@test isa(p5, Plot)
end


text:
module Aminda

module LibAminda
include("libaminda.jl")
end
import .LibAminda
include("types.jl")
include("camera.jl")
include("data.jl")
include("depth_map.jl")
include("labeling.jl")
include("fusion.jl")

end # module Aminda

max_stars_repo_name: twadleigh/aminda

max_issues_repo_name: twadleigh/aminda

max_forks_repo_name: twadleigh/aminda


text:
# AUTO GENERATED FILE - DO NOT EDIT

export accordionitem

"""
    accordionitem(;kwargs...)
    accordionitem(children::Any;kwargs...)
    accordionitem(children_maker::Function;kwargs...)

An AccordionItem component.
Utility component to pass to Accordion. For more information, see: https://mantine.dev/core/accordion/
Keyword arguments:
- `children` (a list of or a singular dash component, string or number; optional): Accordion content
- `description` (String; optional): Accordion description
- `label` (String; required): Accordion label
"""
function accordionitem(; kwargs...)
        available_props = Symbol[:children, :description, :label]
        wild_props = Symbol[]
        return Component("accordionitem", "AccordionItem", "dash_mantine_components", available_props, wild_props; kwargs...)
end

accordionitem(children::Any; kwargs...) = accordionitem(;kwargs..., children = children)
accordionitem(children_maker::Function; kwargs...) = accordionitem(children_maker(); kwargs...)


text:
module Replicate

    using Mustache
    import Pkg

    export hello, domath

    """
        hello(who::String)

    Return "Hello, `who`".
    """
    hello(who::String) = "Hello, $who"

    """
        domath(x::Number)

    Return `x + 5`.
    """
    domath(x::Number) = x + 5

    """
        bootstrap(gh_user::String,pkgname::String; path::String = joinpath(@__DIR__,"..",".."))

    Creates a new julia package using the current package as a template. This function
    will replace write a full julia package, including `tests` and `docs` to folder `path` - defaults to
    the directory below the root of this repo.

    ## Details

    copies also:
    * `.github/worklows/ci.yml` setup to run tests and build docs
    * `.gitignore`
    * `docs` Project.toml file for Documenter.jl

    """
    function bootstrap(gh_user::String,pkgname::String; path::String = joinpath(@__DIR__,"..",".."))
        if !contains(pkgname,".jl") error("please supply pkgname.jl with .jl") end
        @info "We'll create your package $pkgname now"
        modname = split(pkgname,".")[1]
        pkgpath = joinpath(path,modname)

        tpl_src = mt"""
            module {{name}}
            export hello, domath

            \"\"\"
                hello(who::String)

            Return "Hello, `who`".
            \"\"\"
            hello(who::String) = "Hello, $who"

            \"\"\"
                domath(x::Number)

            Return `x + 5`.
            \"\"\"
            domath(x::Number) = x + 5

            end
            """

        src = render(tpl_src, Dict("name" => modname))

        tpl_test = mt"""
            using Test, {{name}}

            @test hello("Julia") == "Hello, Julia"
            @test domath(2.0) ≈ 7.0
            """

        test = render(tpl_test, Dict("name" => modname))

        tpl_make = mt"""
            push!(LOAD_PATH,"../src/")
            using Documenter, {{name}}

            makedocs(modules = [{{name}}], sitename = "{{name}}.jl")

            deploydocs(repo = "github.com/{{user}}/{{name}}.jl.git", devbranch = "main")
            """

        makejl = render(tpl_make, Dict("name" => modname, "user" => gh_user))

        tpl_docs = mt"""
            # My Replication of xyz

            > This replication study was part of my evaluation for the course [Numerical Methods](https://floswald.github.io/NumericalMethods/) at SciencesPo Paris in Spring 2021

            In this replication study, we do ...

            ```@autodocs
            Modules = [{{name}}]
            ```

            end
            """

        docs = render(tpl_docs, Dict("name" => modname))
        # return (src = src, test = test, makejl = makejl, docs = docs)

        @info "Writing source code for new package $pkgname to folder $pkgpath"
        Pkg.generate(pkgpath)
        # dirs = [joinpath(path,"src"),joinpath(path,"test"),joinpath(path,"docs","src")]
        paths = [joinpath(pkgpath,"src",pkgname),joinpath(pkgpath,"test","runtests.jl"),joinpath(pkgpath,"docs","make.jl"),
                joinpath(pkgpath,"docs","src","index.md")]
        files = Dict(zip(paths, [src, test, makejl, docs]))

        # create directories
        mkpath(joinpath(pkgpath,"docs","src"))
        mkpath(joinpath(pkgpath,"test"))

        # return files

        # write files
        for (k,v) in files
            open(k, "w") do io
                print(io, v)
            end
        end

        @info "copying .github/workflow and other scaffold code"

        Pkg.activate(joinpath(pkgpath,"test"))
        Pkg.add("Test")

        root = joinpath(@__DIR__,"..")
        cp(joinpath(root,".gitignore"), joinpath(pkgpath,".gitignore"))
        mkpath(joinpath(pkgpath,".github","workflows"))
        cp(joinpath(root,".github","workflows","ci.yml"), joinpath(pkgpath,".github","workflows","ci.yml"))
        cp(joinpath(root,"docs","Project.toml"), joinpath(pkgpath,"docs","Project.toml"))

        @info "done."

    end

end # module


text:
function depwarn_ex(msg, name)
    return quote
        if VERSION >= v"0.6.0"
            Base.depwarn($msg, Symbol($name))
        end
    end
end

macro Dict(pairs...)
    esc(Expr(:block, depwarn_ex("@Dict is deprecated, use Dict instead", "@Dict"),
                       Expr(:call, :Dict, pairs...)))
end

macro AnyDict(pairs...)
    esc(Expr(:block, depwarn_ex("@AnyDict is deprecated, use Dict{Any,Any} instead", "@AnyDict"),
             Expr(:call, :(Base.AnyDict), pairs...)))
end

module CompatCartesian

import ..Compat: depwarn_ex

export @ngenerate, @nsplat

macro ngenerate(itersym, returntypeexpr, funcexpr)
    if isa(funcexpr, Expr) && funcexpr.head == :macrocall && funcexpr.args[1] == Symbol("@inline")
        funcexpr = Base._inline(funcexpr.args[2])
    end
    isfuncexpr(funcexpr) || error("Requires a function expression")
    esc(Expr(:block, depwarn_ex("@ngenerate is deprecated, used @generated function or (preferably) tuples/CartesianIndex instead", "@ngenerate"),
             _ngenerate(itersym, funcexpr)))
end

function _ngenerate(itersym::Symbol, funcexpr::Expr)
    prototype = funcexpr.args[1]
    body = funcexpr.args[2]
    varname, T = get_splatinfo(prototype, itersym)
    ex = Expr(:$, itersym)
    sreplace!(body, itersym, ex)
    if !isempty(varname)
        prototype, body = _nsplat(prototype, body, varname, T, itersym)
    else
        body = Expr(:quote, body)
    end
    Expr(:stagedfunction, prototype, body)
end

macro nsplat(itersym, args...)
    if length(args) == 1
        funcexpr = args[1]
    elseif length(args) == 2
        funcexpr = args[2]
    else
        error("Wrong number of arguments")
    end
    if isa(funcexpr, Expr) && funcexpr.head == :macrocall && funcexpr.args[1] == Symbol("@inline")
        funcexpr = Base._inline(funcexpr.args[2])
    end
    isfuncexpr(funcexpr) || error("Second argument must be a function expression")
    prototype = funcexpr.args[1]
    body = funcexpr.args[2]
    varname, T = get_splatinfo(prototype, itersym)
    isempty(varname) && error("Last argument must be a splat")
    prototype, body = _nsplat(prototype, body, varname, T, itersym)
        esc(Expr(:block, depwarn_ex("@nsplat is deprecated, using inlining instead", "@nsplat"),
                 Expr(:stagedfunction, prototype, body)))
end

function _nsplat(prototype, body, varname, T, itersym)
    varsym = Symbol(varname)
    prototype.args[end] = Expr(:..., Expr(:(::), varsym, T)) # :($varsym::$T...)
    varquot = Expr(:quote, varsym)
    bodyquot = Expr(:quote, body)
    newbody = quote
        $itersym = length($varsym)
        quote
            Base.Cartesian.@nexprs $($itersym) (d->$($(Expr(:quote, Symbol(varsym, "_d")))) = $($varquot)[d])
            $(Compat.CompatCartesian.resolvesplats!($bodyquot, $varquot, $itersym))
        end
    end
    prototype, newbody
end

# If using the syntax that will need "desplatting",
#     myfunction(A::AbstractArray, I::NTuple{N, Int}...)
# return the variable name (as a string) and type
function get_splatinfo(ex::Expr, itersym::Symbol)
    if ex.head == :call
        a = ex.args[end]
        if  isa(a, Expr) && a.head == :... && length(a.args) == 1
            b = a.args[1]
            if isa(b, Expr) && b.head == :(::)
                varname = string(b.args[1])
                c = b.args[2]
                if isa(c, Expr) && c.head == :curly && c.args[1] == :NTuple && c.args[2] == itersym
                    T = c.args[3]
                    return varname, T
                end
            end
        end
    end
    "", Void
end

resolvesplats!(arg, varname, N) = arg
function resolvesplats!(ex::Expr, varname, N::Int)
    if ex.head == :call
        for i = 2:length(ex.args)-1
            resolvesplats!(ex.args[i], varname, N)
        end
        a = ex.args[end]
        if isa(a, Expr) && a.head == :... && a.args[1] == Symbol(varname)
            ex.args[end] = :($varname[1]) # Expr(:ref, varname, 1)
            for i = 2:N
                push!(ex.args, :($varname[$i])) # Expr(:ref, varname, i))
            end
        else
            resolvesplats!(a, varname, N)
        end
    else
        for i = 1:length(ex.args)
            resolvesplats!(ex.args[i], varname, N)
        end
    end
    ex
end

isfuncexpr(ex::Expr) =
    ex.head == :function || (ex.head == :(=) && typeof(ex.args[1]) == Expr && ex.args[1].head == :call)
isfuncexpr(arg) = false

sreplace!(arg, sym, val) = arg
function sreplace!(ex::Expr, sym, val)
    for i = 1:length(ex.args)
        ex.args[i] = sreplace!(ex.args[i], sym, val)
    end
    ex
end
sreplace!(s::Symbol, sym, val) = s == sym ? val : s

end

using .CompatCartesian
export @ngenerate, @nsplat

export @functorize
macro functorize(f)
    code = f === :scalarmax          ? :(Base.scalarmax) :
           f === :scalarmin          ? :(Base.scalarmin) :
           f === :centralizedabs2fun ? :(primarytype(typeof(Base.centralizedabs2fun(0)))) :
           f
    warning = depwarn_ex("@functorize is deprecated as functor objects are no longer supported in julia", "@functorize")
    return quote
        $warning
        $code
    end
end

if VERSION >= v"0.6.0"
    Base.@deprecate_binding KERNEL Sys.KERNEL
    Base.@deprecate_binding UTF8String Core.String
    Base.@deprecate_binding ASCIIString Core.String
else
    const KERNEL = Sys.KERNEL
    const UTF8String = Core.String
    const ASCIIString = Core.String
end

# More things that could be removed in Compat.jl
# - new_style_call_overload
# - import Base.Filesystem
# - import Base.LinAlg.BLAS.@blasfunc


text:
# test Base Extensions
@testset "Base Extensions" begin
    # Setup data
    m = InfiniteModel();
    gvref = GeneralVariableRef(m, 1, PointVariableIndex)
    gvref2 = GeneralVariableRef(m, 2, PointVariableIndex)
    ivref = InfiniteVariableRef(m, InfiniteVariableIndex(1))
    hvref = HoldVariableRef(m, HoldVariableIndex(1))
    # test Base.copy
    @testset "Base.copy" begin
        @test copy(gvref) == gvref
        @test copy(ivref) == ivref
    end
    # test Base.:(==)
    @testset "Base.:(==)" begin
        @test gvref == gvref
        @test ivref == ivref
        @test !(gvref == ivref)
        @test !(hvref == ivref)
        @test !(gvref == gvref2)
    end
    # test Base.broadcastable
    @testset "Base.broadcastable" begin
        @test Base.broadcastable(gvref) isa Base.RefValue{GeneralVariableRef}
        @test Base.broadcastable(ivref) isa Base.RefValue{InfiniteVariableRef}
    end
    # test Base.length
    @testset "Base.length" begin
        @test length(gvref) == 1
        @test length(ivref) == 1
    end
    # test JuMP.isequal_canonical
    @testset "JuMP.isequal_canonical" begin
        @test JuMP.isequal_canonical(gvref, gvref)
        @test JuMP.isequal_canonical(ivref, ivref)
    end
    # test JuMP.variable_type
    @testset "JuMP.variable_type" begin
        @test JuMP.variable_type(m) == GeneralVariableRef
    end
    # test _remove_name_index
    @testset "_remove_name_index" begin
        pref = @independent_parameter(m, test, set = IntervalSet(0, 1))
        pref2 = @independent_parameter(m, θ, set = IntervalSet(0, 1))
        prefs = @independent_parameter(m, x[1:2], set = IntervalSet(0, 1))
        @test InfiniteOpt._remove_name_index(pref) == "test"
        @test InfiniteOpt._remove_name_index(prefs[1]) == "x"
        @test InfiniteOpt._remove_name_index(pref2) == "θ"
    end
    # test Basic getters
    @testset "Attribute Accessors" begin
        @test InfiniteOpt._index_type(gvref) == PointVariableIndex
        @test InfiniteOpt._raw_index(gvref) == 1
        @test InfiniteOpt._param_index(gvref) == -1
    end
end

# test Reference Accessers
@testset "Reference Accessers" begin
    # Setup data
    m = InfiniteModel();
    gvref1 = GeneralVariableRef(m, 1, PointVariableIndex)
    gvref2 = GeneralVariableRef(m, 1, DependentParameterIndex, 2)
    ivref = InfiniteVariableRef(m, InfiniteVariableIndex(1))
    # test JuMP.index (GeneralVariableRef)
    @testset "JuMP.index (GeneralVariableRef)" begin
        @test index(gvref1) == PointVariableIndex(1)
        @test index(gvref2) == DependentParameterIndex(DependentParametersIndex(1), 2)
    end
    # test JuMP.index (DispatchVariableRef)
    @testset "JuMP.index (DispatchVariableRef)" begin
        @test index(ivref) == InfiniteVariableIndex(1)
    end
    # test JuMP.owner_model (GeneralVariableRef)
    @testset "JuMP.owner_model (GeneralVariableRef)" begin
        @test owner_model(gvref1) == m
        @test owner_model(gvref2) == m
    end
    # test JuMP.owner_model (DispatchVariableRef)
    @testset "JuMP.owner_model (DispatchVariableRef)" begin
        @test owner_model(ivref) == m
    end
end

# test Dispatch Variabel Methods
@testset "dispatch_variable_ref" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test the test type
    @testset "TestVariableRef" begin
        @test dispatch_variable_ref(m, idx) == dvref
    end
    # test GeneralVariableRef input
    @testset "GeneralVariableRef" begin
        @test dispatch_variable_ref(gvref) == dvref
    end
end

# test Naming Methods
@testset "Naming Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test JuMP.name (Fallback)
    @testset "JuMP.name (Fallback)" begin
        @test_throws ArgumentError name(dvref)
    end
    # test JuMP.name (GeneralVariableRef)
    @testset "JuMP.name (GeneralVariableRef)" begin
        @test_throws ArgumentError name(gvref)
    end
    # test JuMP.set_name (Fallback)
    @testset "JuMP.set_name (Fallback)" begin
        @test_throws ArgumentError set_name(dvref, "new")
    end
    # test JuMP.set_name (GeneralVariableRef)
    @testset "JuMP.set_name (GeneralVariableRef)" begin
        @test_throws ArgumentError set_name(gvref, "new")
    end
end

# test Core data methods
@testset "Core Data Methods" begin
    # Setup data
    m = InfiniteModel();
    gvref = GeneralVariableRef(m, 1, TestIndex)
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    # test _data_dictionary with GeneralVariableRef
    @testset "_data_dictionary (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._data_dictionary(gvref)
    end
    # test _data_object with GeneralVariableRef
    @testset "_data_object (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._data_object(gvref)
    end
    # test _delete_data_object with DispatchVariableRef
    @testset "_delete_data_object (DispatchVariableRef)" begin
        @test_throws MethodError InfiniteOpt._delete_data_object(dvref)
    end
end

# test Validity Methods
@testset "Validity Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test JuMP.is_valid (Fallback)
    @testset "JuMP.is_valid (Fallback)" begin
        @test_throws MethodError is_valid(m, dvref)
    end
    # test JuMP.is_valid (GeneralVariableRef)
    @testset "JuMP.is_valid (GeneralVariableRef)" begin
        @test_throws MethodError is_valid(m, gvref)
    end
end

# test Core Object Methods
@testset "Core Object Methods" begin
    # Setup data
    m = InfiniteModel();
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test _core_variable_object (GeneralVariableRef)
    @testset "_core_variable_object (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._core_variable_object(gvref)
    end
end

# test Dependency Methods
@testset "Dependency Methods" begin
    # Setup data
    m = InfiniteModel();
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test _infinite_variable_dependencies (GeneralVariableRef)
    @testset "_infinite_variable_dependencies (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._infinite_variable_dependencies(gvref)
    end
    # test _reduced_variable_dependencies (GeneralVariableRef)
    @testset "_reduced_variable_dependencies (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._reduced_variable_dependencies(gvref)
    end
    # test _point_variable_dependencies (GeneralVariableRef)
    @testset "_point_variable_dependencies (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._point_variable_dependencies(gvref)
    end
    # test _measure_dependencies (GeneralVariableRef)
    @testset "_measure_dependenciess (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._measure_dependencies(gvref)
    end
    # test _constraint_dependencies (GeneralVariableRef)
    @testset "_constraint_dependencies (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._constraint_dependencies(gvref)
    end
    # test _derivative_dependencies (GeneralVariableRef)
    @testset "_derivative_dependencies (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._derivative_dependencies(gvref)
    end
    # test _derivative_constraint_dependencies (GeneralVariableRef)
    @testset "_derivative_constraint_dependencies (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._derivative_constraint_dependencies(gvref)
    end
    # test _parameter_function_dependencies (GeneralVariableRef)
    @testset "_parameter_function_dependencies (GeneralVariableRef)" begin
        @test_throws MethodError InfiniteOpt._parameter_function_dependencies(gvref)
    end
end

# test Usage Methods
@testset "Usage Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test used_by_infinite_variable (Fallback)
    @testset "used_by_infinite_variable (Fallback)" begin
        @test_throws ArgumentError used_by_infinite_variable(dvref)
    end
    # test used_by_infinite_variable (GeneralVariableRef)
    @testset "used_by_infinite_variable (GeneralVariableRef)" begin
        @test_throws ArgumentError used_by_infinite_variable(gvref)
    end
    # test used_by_reduced_variable (Fallback)
    @testset "used_by_reduced_variable (Fallback)" begin
        @test_throws ArgumentError used_by_reduced_variable(dvref)
    end
    # test used_by_reduced_variable (GeneralVariableRef)
    @testset "used_by_reduced_variable (GeneralVariableRef)" begin
        @test_throws ArgumentError used_by_reduced_variable(gvref)
    end
    # test used_by_point_variable (Fallback)
    @testset "used_by_point_variable (Fallback)" begin
        @test_throws ArgumentError used_by_point_variable(dvref)
    end
    # test used_by_point_variable (GeneralVariableRef)
    @testset "used_by_point_variable (GeneralVariableRef)" begin
        @test_throws ArgumentError used_by_point_variable(gvref)
    end
    # test used_by_measure (Fallback)
    @testset "used_by_measure (Fallback)" begin
        @test_throws ArgumentError used_by_measure(dvref)
    end
    # test used_by_measure (GeneralVariableRef)
    @testset "used_by_measure (GeneralVariableRef)" begin
        @test_throws ArgumentError used_by_measure(gvref)
    end
    # test used_by_objective (Fallback)
    @testset "used_by_objective (Fallback)" begin
        @test_throws ArgumentError used_by_objective(dvref)
    end
    # test used_by_objective (GeneralVariableRef)
    @testset "used_by_objective (GeneralVariableRef)" begin
        @test_throws ArgumentError used_by_objective(gvref)
    end
    # test used_by_constraint (Fallback)
    @testset "used_by_constraint (Fallback)" begin
        @test_throws ArgumentError used_by_constraint(dvref)
    end
    # test used_by_constraint (GeneralVariableRef)
    @testset "used_by_constraint (GeneralVariableRef)" begin
        @test_throws ArgumentError used_by_constraint(gvref)
    end
    # test used_by_derivative (Fallback)
    @testset "used_by_derivative (Fallback)" begin
        @test_throws ArgumentError used_by_derivative(dvref)
    end
    # test used_by_derivative (GeneralVariableRef)
    @testset "used_by_derivative (GeneralVariableRef)" begin
        @test_throws ArgumentError used_by_derivative(gvref)
    end
    # test is_used (Fallback)
    @testset "is_used (Fallback)" begin
        @test_throws ArgumentError is_used(dvref)
    end
    # test is_used (GeneralVariableRef)
    @testset "is_used (GeneralVariableRef)" begin
        @test_throws ArgumentError is_used(gvref)
    end
    # test has_derivative_constraints (Fallback)
    @testset "has_derivative_constraints (Fallback)" begin
        @test_throws ArgumentError has_derivative_constraints(dvref)
    end
    # test has_derivative_constraints (GeneralVariableRef)
    @testset "has_derivative_constraints (GeneralVariableRef)" begin
        @test_throws ArgumentError has_derivative_constraints(gvref)
    end
    # test used_by_parameter_function(Fallback)
    @testset "used_by_parameter_function (Fallback)" begin
        @test_throws ArgumentError used_by_parameter_function(dvref)
    end
    # test used_by_parameter_function (GeneralVariableRef)
    @testset "used_by_parameter_function (GeneralVariableRef)" begin
        @test_throws ArgumentError used_by_parameter_function(gvref)
    end
end

# test Delete Methods
@testset "Delete Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test JuMP.delete (Fallback)
    @testset "JuMP.delete (Fallback)" begin
        @test_throws ArgumentError JuMP.delete(m, dvref)
    end
    # test JuMP.delete (GeneralVariableRef)
    @testset "JuMP.delete (GeneralVariableRef)" begin
        @test_throws ArgumentError JuMP.delete(m, gvref)
    end
    # test JuMP.delete (GeneralVariableRefs)
    @testset "JuMP.delete (GeneralVariableRefs)" begin
        @test_throws ArgumentError JuMP.delete(m, [gvref])
    end
end

# test Parameter Methods
@testset "Parameter Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    gvrefs = [GeneralVariableRef(m, 1, TestIndex),
              GeneralVariableRef(m, 2, TestIndex)]
    sparse_gvrefs = convert(JuMPC.SparseAxisArray, gvrefs)
    dense_gvrefs = JuMPC.DenseAxisArray(gvrefs, 3:4)
    sset = IntervalSet(0, 1)
    aset = CollectionSet([sset, sset])
    # test _parameter_number
    @testset "_parameter_number" begin
        @test_throws MethodError InfiniteOpt._parameter_number(gvref)
    end
    # test _object_number
    @testset "_object_number" begin
        @test_throws MethodError InfiniteOpt._object_number(gvref)
    end
    # test infinite_set (Fallback)
    @testset "infinite_set (Fallback)" begin
        @test_throws ArgumentError infinite_set(dvref)
    end
    # test infinite_set (GeneralVariableRef)
    @testset "infinite_set (GeneralVariableRef)" begin
        @test_throws ArgumentError infinite_set(gvref)
    end
    # test infinite_set (GeneralVariableRef Array)
    @testset "infinite_set (GeneralVariableRef Array)" begin
        @test_throws ArgumentError infinite_set(gvrefs)
        @test_throws ArgumentError infinite_set(dense_gvrefs)
        @test_throws ArgumentError infinite_set(sparse_gvrefs)
    end
    # test set_infinite_set (Fallback)
    @testset "set_infinite_set (Fallback)" begin
        @test_throws ArgumentError set_infinite_set(dvref, sset)
    end
    # test set_infinite_set (GeneralVariableRef)
    @testset "set_infinite_set (GeneralVariableRef)" begin
        @test_throws ArgumentError set_infinite_set(gvref, sset)
    end
    # test set_infinite_set (GeneralVariableRef Array)
    @testset "set_infinite_set (GeneralVariableRef Array)" begin
        @test_throws ArgumentError set_infinite_set(gvrefs, aset)
        @test_throws ArgumentError set_infinite_set(dense_gvrefs, aset)
        @test_throws ArgumentError set_infinite_set(sparse_gvrefs, aset)
    end
    # test significant_digits (Fallback)
    @testset "significant_digits (Fallback)" begin
        @test_throws ArgumentError significant_digits(dvref)
    end
    # test significant_digits (GeneralVariableRef)
    @testset "significant_digits (GeneralVariableRef)" begin
        @test_throws ArgumentError significant_digits(gvref)
    end
    # test num_supports (Fallback)
    @testset "num_supports (Fallback)" begin
        @test_throws ArgumentError num_supports(dvref, label = All)
    end
    # test num_supports (GeneralVariableRef)
    @testset "num_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError num_supports(gvref, label = All)
    end
    # test num_supports (GeneralVariableRef Array)
    @testset "num_supports (GeneralVariableRef Array)" begin
        @test_throws ArgumentError num_supports(gvrefs, label = All)
        @test_throws ArgumentError num_supports(dense_gvrefs, label = All)
        @test_throws ArgumentError num_supports(sparse_gvrefs, label = All)
    end
    # test has_supports (Fallback)
    @testset "has_supports (Fallback)" begin
        @test_throws ArgumentError has_supports(dvref)
    end
    # test has_supports (GeneralVariableRef)
    @testset "has_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError has_supports(gvref)
    end
    # test has_supports (GeneralVariableRef Array)
    @testset "has_supports (GeneralVariableRef Array)" begin
        @test_throws ArgumentError has_supports(gvrefs)
        @test_throws ArgumentError has_supports(dense_gvrefs)
        @test_throws ArgumentError has_supports(sparse_gvrefs)
    end
    # test supports (Fallback)
    @testset "supports (Fallback)" begin
        @test_throws ArgumentError supports(dvref, label = All)
    end
    # test supports (GeneralVariableRef)
    @testset "supports (GeneralVariableRef)" begin
        @test_throws ArgumentError supports(gvref, label = All)
    end
    # test supports (GeneralVariableRef Array)
    @testset "supports (GeneralVariableRef Array)" begin
        @test_throws ArgumentError supports(gvrefs, label = All)
        @test_throws ArgumentError supports(dense_gvrefs, label = All)
        @test_throws ArgumentError supports(sparse_gvrefs, label = All)
    end
    # test set_supports (Fallback)
    @testset "set_supports (Fallback)" begin
        @test_throws ArgumentError set_supports(dvref, 2, label = All, force = true)
    end
    # test set_supports (GeneralVariableRef)
    @testset "set_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError set_supports(gvref, 2, label = All, force = true)
    end
    # test set_supports (GeneralVariableRef Array)
    @testset "set_supports (GeneralVariableRef Array)" begin
        @test_throws ArgumentError set_supports(gvrefs, ones(1, 1), label = All,
                                                force = true)
        @test_throws ArgumentError set_supports(dense_gvrefs, ones(1, 1),
                                                label = All, force = true)
        @test_throws ArgumentError set_supports(sparse_gvrefs, ones(1, 1),
                                                label = All, force = true)
    end
    # test add_supports (Fallback)
    @testset "add_supports (Fallback)" begin
        @test_throws ArgumentError add_supports(dvref, 2, label = All, check = true)
    end
    # test add_supports (GeneralVariableRef)
    @testset "add_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError add_supports(gvref, 2, label = All, check = true)
    end
    # test add_supports (GeneralVariableRef Array)
    @testset "add_supports (GeneralVariableRef Array)" begin
        @test_throws ArgumentError add_supports(gvrefs, ones(1, 1), label = All,
                                                check = true)
        @test_throws ArgumentError add_supports(dense_gvrefs, ones(1, 1),
                                                label = All, check = true)
        @test_throws ArgumentError add_supports(sparse_gvrefs, ones(1, 1),
                                                label = All, check = true)
    end
    # test delete_supports (Fallback)
    @testset "delete_supports (Fallback)" begin
        @test_throws ArgumentError delete_supports(dvref)
    end
    # test delete_supports (GeneralVariableRef)
    @testset "delete_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError delete_supports(gvref)
    end
    # test delete_supports (GeneralVariableRef Array)
    @testset "delete_supports (GeneralVariableRef Array)" begin
        @test_throws ArgumentError delete_supports(gvrefs)
        @test_throws ArgumentError delete_supports(dense_gvrefs)
        @test_throws ArgumentError delete_supports(sparse_gvrefs)
    end
    # test fill_in_supports! (Fallback)
    @testset "fill_in_supports! (Fallback)" begin
        @test_throws ArgumentError fill_in_supports!(dvref, num_supports = 1)
    end
    # test fill_in_supports! (GeneralVariableRef)
    @testset "fill_in_supports! (GeneralVariableRef)" begin
        @test_throws ArgumentError fill_in_supports!(gvref, num_supports = 1)
    end
    # test fill_in_supports! (GeneralVariableRef Array)
    @testset "fill_in_supports! (GeneralVariableRef Array)" begin
        @test_throws ArgumentError fill_in_supports!(gvrefs, num_supports = 1)
        @test_throws ArgumentError fill_in_supports!(dense_gvrefs, num_supports = 1)
        @test_throws ArgumentError fill_in_supports!(sparse_gvrefs,num_supports = 1)
    end
    # test parameter_value (Fallback)
    @testset "parameter_value (Fallback)" begin
        @test_throws ArgumentError parameter_value(dvref)
    end
    # test parameter_value (GeneralVariableRef)
    @testset "parameter_value (GeneralVariableRef)" begin
        @test_throws ArgumentError parameter_value(gvref)
    end
    # test JuMP.set_value (Fallback)
    @testset "JuMP.set_value (Fallback)" begin
        @test_throws ArgumentError set_value(dvref, 2)
    end
    # test JuMP.set_value (GeneralVariableRef)
    @testset "JuMP.set_value (GeneralVariableRef)" begin
        @test_throws ArgumentError set_value(gvref, 2)
    end
    # test derivative_method (Fallback)
    @testset "derivative_method (Fallback)" begin
        @test_throws ArgumentError derivative_method(dvref)
    end
    # test derivative_method (GeneralVariableRef)
    @testset "derivative_method (GeneralVariableRef)" begin
        @test_throws ArgumentError derivative_method(gvref)
    end
    # test set_derivative_method (Fallback)
    @testset "set_derivative_method (Fallback)" begin
        @test_throws ArgumentError set_derivative_method(dvref, FiniteDifference())
    end
    # test set_derivative_method (GeneralVariableRef)
    @testset "set_derivative_method (GeneralVariableRef)" begin
        @test_throws ArgumentError set_derivative_method(gvref, FiniteDifference())
    end
    # test has_internal_supports (Fallback)
    @testset "has_internal_supports (Fallback)" begin
        @test_throws ArgumentError has_internal_supports(dvref)
    end
    # test has_internal_supports (GeneralVariableRef)
    @testset "has_internal_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError has_internal_supports(gvref)
    end
    # test _set_has_internal_supports (Fallback)
    @testset "_set_has_internal_supports (Fallback)" begin
        @test_throws ArgumentError InfiniteOpt._set_has_internal_supports(dvref, true)
    end
    # test _set_has_internal_supports (GeneralVariableRef)
    @testset "_set_has_internal_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError InfiniteOpt._set_has_internal_supports(gvref, true)
    end
    # test has_derivative_supports (Fallback)
    @testset "has_derivative_supports (Fallback)" begin
        @test_throws ArgumentError has_derivative_supports(dvref)
    end
    # test has_derivative_supports (GeneralVariableRef)
    @testset "has_derivative_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError has_derivative_supports(gvref)
    end
    # test _set_has_derivative_supports (Fallback)
    @testset "_set_has_derivative_supports (Fallback)" begin
        @test_throws ArgumentError InfiniteOpt._set_has_derivative_supports(dvref, true)
    end
    # test _set_has_derivative_supports (GeneralVariableRef)
    @testset "_set_has_derivative_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError InfiniteOpt._set_has_derivative_supports(gvref, true)
    end
    # test _set_has_derivative_constraints (Fallback)
    @testset "_set_has_derivative_constraints (Fallback)" begin
        @test_throws ArgumentError InfiniteOpt._set_has_derivative_constraints(dvref, true)
    end
    # test _set_has_derivative_constraints (GeneralVariableRef)
    @testset "_set_has_derivative_constraints (GeneralVariableRef)" begin
        @test_throws ArgumentError InfiniteOpt._set_has_derivative_constraints(gvref, true)
    end
    # test add_derivative_supports (Fallback)
    @testset "add_derivative_supports (Fallback)" begin
        @test_throws ArgumentError InfiniteOpt.add_derivative_supports(dvref)
    end
    # test add_derivative_supports (GeneralVariableRef)
    @testset "add_derivative_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError InfiniteOpt.add_derivative_supports(gvref)
    end
    # test raw_function (Fallback)
    @testset "raw_function (Fallback)" begin
        @test_throws ArgumentError raw_function(dvref)
    end
    # test raw_function (GeneralVariableRef)
    @testset "raw_function (GeneralVariableRef)" begin
        @test_throws ArgumentError raw_function(gvref)
    end
end

# test Variable Methods
@testset "Variable Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test raw_parameter_refs (Fallback)
    @testset "raw_parameter_refs (Fallback)" begin
        @test_throws ArgumentError raw_parameter_refs(dvref)
    end
    # test raw_parameter_refs (GeneralVariableRef)
    @testset "raw_parameter_refs (GeneralVariableRef)" begin
        @test_throws ArgumentError raw_parameter_refs(gvref)
    end
    # test parameter_refs (Fallback)
    @testset "parameter_refs (Fallback)" begin
        @test_throws ArgumentError parameter_refs(dvref)
    end
    # test parameter_refs (GeneralVariableRef)
    @testset "parameter_refs (GeneralVariableRef)" begin
        @test_throws ArgumentError parameter_refs(gvref)
    end
    # test parameter_list (Fallback)
    @testset "parameter_list (Fallback)" begin
        @test_throws ArgumentError parameter_list(dvref)
    end
    # test parameter_list (GeneralVariableRef)
    @testset "parameter_list (GeneralVariableRef)" begin
        @test_throws ArgumentError parameter_list(gvref)
    end
    # test infinite_variable_ref (Fallback)
    @testset "infinite_variable_ref (Fallback)" begin
        @test_throws ArgumentError infinite_variable_ref(dvref)
    end
    # test infinite_variable_ref (GeneralVariableRef)
    @testset "infinite_variable_ref (GeneralVariableRef)" begin
        @test_throws ArgumentError infinite_variable_ref(gvref)
    end
    # test eval_supports (Fallback)
    @testset "eval_supports (Fallback)" begin
        @test_throws ArgumentError eval_supports(dvref)
    end
    # test eval_supports (GeneralVariableRef)
    @testset "eval_supports (GeneralVariableRef)" begin
        @test_throws ArgumentError eval_supports(gvref)
    end
    # test raw_parameter_values (Fallback)
    @testset "raw_parameter_values (Fallback)" begin
        @test_throws ArgumentError raw_parameter_values(dvref)
    end
    # test raw_parameter_values (GeneralVariableRef)
    @testset "raw_parameter_values (GeneralVariableRef)" begin
        @test_throws ArgumentError raw_parameter_values(gvref)
    end
    # test parameter_values (Fallback)
    @testset "parameter_values (Fallback)" begin
        @test_throws ArgumentError parameter_values(dvref)
    end
    # test parameter_values (GeneralVariableRef)
    @testset "parameter_values (GeneralVariableRef)" begin
        @test_throws ArgumentError parameter_values(gvref)
    end
    # test parameter_bounds (Fallback)
    @testset "parameter_bounds (Fallback)" begin
        @test_throws ArgumentError parameter_bounds(dvref)
    end
    # test parameter_vbounds (GeneralVariableRef)
    @testset "parameter_bounds (GeneralVariableRef)" begin
        @test_throws ArgumentError parameter_bounds(gvref)
    end
    # test has_parameter_vbounds (GeneralVariableRef)
    @testset "has_parameter_bounds (GeneralVariableRef)" begin
        @test !has_parameter_bounds(gvref)
    end
    # test set_parameter_bounds (Fallback)
    @testset "set_parameter_bounds (Fallback)" begin
        @test_throws ArgumentError set_parameter_bounds(dvref, ParameterBounds())
    end
    # test set_parameter_vbounds (GeneralVariableRef)
    @testset "set_parameter_bounds (GeneralVariableRef)" begin
        @test_throws ArgumentError set_parameter_bounds(gvref, ParameterBounds(),
                                                        force = true)
    end
    # test add_parameter_bounds (Fallback)
    @testset "add_parameter_bounds (Fallback)" begin
        @test_throws ArgumentError add_parameter_bounds(dvref, ParameterBounds())
    end
    # test add_parameter_vbounds (GeneralVariableRef)
    @testset "add_parameter_bounds (GeneralVariableRef)" begin
        @test_throws ArgumentError add_parameter_bounds(gvref, ParameterBounds())
    end
    # test delete_parameter_bounds (Fallback)
    @testset "delete_parameter_bounds (Fallback)" begin
        @test_throws ArgumentError delete_parameter_bounds(dvref)
    end
    # test delete_parameter_vbounds (GeneralVariableRef)
    @testset "delete_parameter_bounds (GeneralVariableRef)" begin
        @test_throws ArgumentError delete_parameter_bounds(gvref)
    end
end

# test Measure Methods
@testset "Measure Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test measure_function (Fallback)
    @testset "measure_function (Fallback)" begin
        @test_throws ArgumentError measure_function(dvref)
    end
    # test measure_function (GeneralVariableRef)
    @testset "measure_function (GeneralVariableRef)" begin
        @test_throws ArgumentError measure_function(gvref)
    end
    # test measure_data (Fallback)
    @testset "measure_data (Fallback)" begin
        @test_throws ArgumentError measure_function(dvref)
    end
    # test measure_data (GeneralVariableRef)
    @testset "measure_data (GeneralVariableRef)" begin
        @test_throws ArgumentError measure_function(gvref)
    end
    # test is_analytic (Fallback)
    @testset "is_analytic (Fallback)" begin
        @test_throws ArgumentError is_analytic(dvref)
    end
    # test is_analytic (GeneralVariableRef)
    @testset "is_analytic (GeneralVariableRef)" begin
        @test_throws ArgumentError is_analytic(gvref)
    end
    # test expand (Fallback)
    @testset "expand (Fallback)" begin
        @test_throws ArgumentError expand(dvref)
    end
    # test expand (GeneralVariableRef)
    @testset "expand (GeneralVariableRef)" begin
        @test_throws ArgumentError expand(gvref)
    end
end

# test Derivative Methods
@testset "Derivative Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test derivative_argument (Fallback)
    @testset "derivative_argument (Fallback)" begin
        @test_throws ArgumentError derivative_argument(dvref)
    end
    # test derivative_argument (GeneralVariableRef)
    @testset "derivative_argument (GeneralVariableRef)" begin
        @test_throws ArgumentError derivative_argument(gvref)
    end
    # test operator_parameter (Fallback)
    @testset "operator_parameter (Fallback)" begin
        @test_throws ArgumentError operator_parameter(dvref)
    end
    # test operator_parameter (GeneralVariableRef)
    @testset "operator_parameter (GeneralVariableRef)" begin
        @test_throws ArgumentError operator_parameter(gvref)
    end
    # test evaluate (Fallback)
    @testset "evaluate (Fallback)" begin
        @test_throws ArgumentError evaluate(dvref)
    end
    # test evaluate (GeneralVariableRef)
    @testset "evaluate (GeneralVariableRef)" begin
        @test_throws ArgumentError evaluate(gvref)
    end
    # test derivative_constraints (Fallback)
    @testset "derivative_constraints (Fallback)" begin
        @test_throws ArgumentError derivative_constraints(dvref)
    end
    # test derivative_constraints (GeneralVariableRef)
    @testset "derivative_constraints (GeneralVariableRef)" begin
        @test_throws ArgumentError derivative_constraints(gvref)
    end
    # test delete_derivative_constraints (Fallback)
    @testset "delete_derivative_constraints (Fallback)" begin
        @test_throws ArgumentError delete_derivative_constraints(dvref)
    end
    # test delete_derivative_constraints (GeneralVariableRef)
    @testset "delete_derivative_constraints (GeneralVariableRef)" begin
        @test_throws ArgumentError delete_derivative_constraints(gvref)
    end
end

# test Lower Bound Methods
@testset "Lower Bound Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test JuMP.has_lower_bound (Fallback)
    @testset "JuMP.has_lower_bound (Fallback)" begin
        @test_throws ArgumentError has_lower_bound(dvref)
    end
    # test JuMP.has_lower_bound (GeneralVariableRef)
    @testset "JuMP.has_lower_bound (GeneralVariableRef)" begin
        @test_throws ArgumentError has_lower_bound(gvref)
    end
    # test JuMP.lower_bound (Fallback)
    @testset "JuMP.lower_bound (Fallback)" begin
        @test_throws ArgumentError lower_bound(dvref)
    end
    # test JuMP.lower_bound (GeneralVariableRef)
    @testset "JuMP.lower_bound (GeneralVariableRef)" begin
        @test_throws ArgumentError lower_bound(gvref)
    end
    # test JuMP.set_lower_bound (Fallback)
    @testset "JuMP.set_lower_bound (Fallback)" begin
        @test_throws ArgumentError set_lower_bound(dvref, 42)
    end
    # test JuMP.set_lower_bound (GeneralVariableRef)
    @testset "JuMP.set_lower_bound (GeneralVariableRef)" begin
        @test_throws ArgumentError set_lower_bound(gvref, 42)
    end
    # test JuMP.LowerBoundRef (Fallback)
    @testset "JuMP.LowerBoundRef (Fallback)" begin
        @test_throws ArgumentError LowerBoundRef(dvref)
    end
    # test JuMP.LowerBoundRef (GeneralVariableRef)
    @testset "JuMP.LowerBoundRef (GeneralVariableRef)" begin
        @test_throws ArgumentError LowerBoundRef(gvref)
    end
    # test JuMP.delete_lower_bound (Fallback)
    @testset "JuMP.delete_lower_bound (Fallback)" begin
        @test_throws ArgumentError delete_lower_bound(dvref)
    end
    # test JuMP.delete_lower_bound (GeneralVariableRef)
    @testset "JuMP.delete_lower_bound (GeneralVariableRef)" begin
        @test_throws ArgumentError delete_lower_bound(gvref)
    end
end

# test Upper Bound Methods
@testset "Upper Bound Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test JuMP.has_upper_bound (Fallback)
    @testset "JuMP.has_upper_bound (Fallback)" begin
        @test_throws ArgumentError has_upper_bound(dvref)
    end
    # test JuMP.has_upper_bound (GeneralVariableRef)
    @testset "JuMP.has_upper_bound (GeneralVariableRef)" begin
        @test_throws ArgumentError has_upper_bound(gvref)
    end
    # test JuMP.upper_bound (Fallback)
    @testset "JuMP.upper_bound (Fallback)" begin
        @test_throws ArgumentError upper_bound(dvref)
    end
    # test JuMP.upper_bound (GeneralVariableRef)
    @testset "JuMP.upper_bound (GeneralVariableRef)" begin
        @test_throws ArgumentError upper_bound(gvref)
    end
    # test JuMP.set_upper_bound (Fallback)
    @testset "JuMP.set_upper_bound (Fallback)" begin
        @test_throws ArgumentError set_upper_bound(dvref, 42)
    end
    # test JuMP.set_upper_bound (GeneralVariableRef)
    @testset "JuMP.set_upper_bound (GeneralVariableRef)" begin
        @test_throws ArgumentError set_upper_bound(gvref, 42)
    end
    # test JuMP.UpperBoundRef (Fallback)
    @testset "JuMP.UpperBoundRef (Fallback)" begin
        @test_throws ArgumentError UpperBoundRef(dvref)
    end
    # test JuMP.UpperBoundRef (GeneralVariableRef)
    @testset "JuMP.UpperBoundRef (GeneralVariableRef)" begin
        @test_throws ArgumentError UpperBoundRef(gvref)
    end
    # test JuMP.delete_upper_bound (Fallback)
    @testset "JuMP.delete_upper_bound (Fallback)" begin
        @test_throws ArgumentError delete_upper_bound(dvref)
    end
    # test JuMP.delete_upper_bound (GeneralVariableRef)
    @testset "JuMP.delete_upper_bound (GeneralVariableRef)" begin
        @test_throws ArgumentError delete_upper_bound(gvref)
    end
end

# test Fixing Methods
@testset "Fixing Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test JuMP.is_fixed (Fallback)
    @testset "JuMP.is_fixed (Fallback)" begin
        @test_throws ArgumentError is_fixed(dvref)
    end
    # test JuMP.is_fixed (GeneralVariableRef)
    @testset "JuMP.is_fixed (GeneralVariableRef)" begin
        @test_throws ArgumentError is_fixed(gvref)
    end
    # test JuMP.fix_value (Fallback)
    @testset "JuMP.fix_value (Fallback)" begin
        @test_throws ArgumentError fix_value(dvref)
    end
    # test JuMP.fix_value (GeneralVariableRef)
    @testset "JuMP.fix_value (GeneralVariableRef)" begin
        @test_throws ArgumentError fix_value(gvref)
    end
    # test JuMP.fix (Fallback)
    @testset "JuMP.fix (Fallback)" begin
        @test_throws ArgumentError fix(dvref, 42, force = true)
    end
    # test JuMP.fix (GeneralVariableRef)
    @testset "JuMP.fix (GeneralVariableRef)" begin
        @test_throws ArgumentError fix(gvref, 42, force = true)
    end
    # test JuMP.FixRef (Fallback)
    @testset "JuMP.FixRef (Fallback)" begin
        @test_throws ArgumentError FixRef(dvref)
    end
    # test JuMP.FixRef (GeneralVariableRef)
    @testset "JuMP.FixRef (GeneralVariableRef)" begin
        @test_throws ArgumentError FixRef(gvref)
    end
    # test JuMP.unfix (Fallback)
    @testset "JuMP.unfix (Fallback)" begin
        @test_throws ArgumentError unfix(dvref)
    end
    # test JuMP.unfix (GeneralVariableRef)
    @testset "JuMP.unfix (GeneralVariableRef)" begin
        @test_throws ArgumentError unfix(gvref)
    end
end

# test Start Value Methods
@testset "Start Value Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test JuMP.start_value (Fallback)
    @testset "JuMP.start_value (Fallback)" begin
        @test_throws ArgumentError start_value(dvref)
    end
    # test JuMP.start_value (GeneralVariableRef)
    @testset "JuMP.start_value (GeneralVariableRef)" begin
        @test_throws ArgumentError start_value(gvref)
    end
    # test JuMP.set_start_value (Fallback)
    @testset "JuMP.set_start_value(Fallback)" begin
        @test_throws ArgumentError set_start_value(dvref, 42)
    end
    # test JuMP.set_start_value (GeneralVariableRef)
    @testset "JuMP.set_start_value (GeneralVariableRef)" begin
        @test_throws ArgumentError set_start_value(gvref, 42)
    end
    # test start_value_function (Fallback)
    @testset "start_value_function (Fallback)" begin
        @test_throws ArgumentError start_value_function(dvref)
    end
    # test start_value_function (GeneralVariableRef)
    @testset "start_value_function (GeneralVariableRef)" begin
        @test_throws ArgumentError start_value_function(gvref)
    end
    # test set_start_value_function (Fallback)
    @testset "set_start_value(Fallback)" begin
        @test_throws ArgumentError set_start_value_function(dvref, 42)
    end
    # test set_start_value_function (GeneralVariableRef)
    @testset "set_start_value (GeneralVariableRef)" begin
        @test_throws ArgumentError set_start_value_function(gvref, 42)
    end
    # test reset_start_value_function (Fallback)
    @testset "reset_start_value(Fallback)" begin
        @test_throws ArgumentError reset_start_value_function(dvref)
    end
    # test reset_start_value_function (GeneralVariableRef)
    @testset "reset_start_value (GeneralVariableRef)" begin
        @test_throws ArgumentError reset_start_value_function(gvref)
    end
end

# test Binary Methods
@testset "Binary Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test JuMP.is_binary (Fallback)
    @testset "JuMP.is_binary (Fallback)" begin
        @test_throws ArgumentError is_binary(dvref)
    end
    # test JuMP.is_binary (GeneralVariableRef)
    @testset "JuMP.is_binary (GeneralVariableRef)" begin
        @test_throws ArgumentError is_binary(gvref)
    end
    # test JuMP.set_binary (Fallback)
    @testset "JuMP.set_binary (Fallback)" begin
        @test_throws ArgumentError set_binary(dvref)
    end
    # test JuMP.set_binary (GeneralVariableRef)
    @testset "JuMP.set_binary (GeneralVariableRef)" begin
        @test_throws ArgumentError set_binary(gvref)
    end
    # test JuMP.BinaryRef (Fallback)
    @testset "JuMP.BinaryRef (Fallback)" begin
        @test_throws ArgumentError BinaryRef(dvref)
    end
    # test JuMP.BinaryRef (GeneralVariableRef)
    @testset "JuMP.BinaryRef (GeneralVariableRef)" begin
        @test_throws ArgumentError BinaryRef(gvref)
    end
    # test JuMP.unset_binary (Fallback)
    @testset "JuMP.unset_binary (Fallback)" begin
        @test_throws ArgumentError unset_binary(dvref)
    end
    # test JuMP.unset_binary (GeneralVariableRef)
    @testset "JuMP.unset_binary (GeneralVariableRef)" begin
        @test_throws ArgumentError unset_binary(gvref)
    end
end

# test Integer Methods
@testset "Integer Methods" begin
    # Setup data
    m = InfiniteModel();
    idx = TestIndex(1)
    dvref = TestVariableRef(m, idx)
    gvref = GeneralVariableRef(m, 1, TestIndex)
    # test JuMP.is_integer (Fallback)
    @testset "JuMP.is_integer (Fallback)" begin
        @test_throws ArgumentError is_integer(dvref)
    end
    # test JuMP.is_integer (GeneralVariableRef)
    @testset "JuMP.is_integer (GeneralVariableRef)" begin
        @test_throws ArgumentError is_integer(gvref)
    end
    # test JuMP.set_integer (Fallback)
    @testset "JuMP.set_integer (Fallback)" begin
        @test_throws ArgumentError set_integer(dvref)
    end
    # test JuMP.set_integer (GeneralVariableRef)
    @testset "JuMP.set_integer (GeneralVariableRef)" begin
        @test_throws ArgumentError set_integer(gvref)
    end
    # test JuMP.IntegerRef (Fallback)
    @testset "JuMP.IntegerRef (Fallback)" begin
        @test_throws ArgumentError IntegerRef(dvref)
    end
    # test JuMP.IntegerRef (GeneralVariableRef)
    @testset "JuMP.IntegerRef (GeneralVariableRef)" begin
        @test_throws ArgumentError IntegerRef(gvref)
    end
    # test JuMP.unset_integer (Fallback)
    @testset "JuMP.unset_integer (Fallback)" begin
        @test_throws ArgumentError unset_integer(dvref)
    end
    # test JuMP.unset_integer (GeneralVariableRef)
    @testset "JuMP.unset_integer (GeneralVariableRef)" begin
        @test_throws ArgumentError unset_integer(gvref)
    end
end


text: Binding.RayRectangle(p::RayVector2, width, height) = RayRectangle(p..., width, height)


text:
module FEA

using ..TopOpt: TopOpt, CPU, GPU, PENALTY_BEFORE_INTERPOLATION, whichdevice
using ..TopOptProblems, ..Utilities, Requires
using Ferrite, Setfield, TimerOutputs, Preconditioners
using IterativeSolvers, StaticArrays, SparseArrays
using LinearAlgebra
using Parameters: @unpack

export AbstractFEASolver,
    AbstractDisplacementSolver,
    DirectDisplacementSolver,
    PCGDisplacementSolver,
    StaticMatrixFreeDisplacementSolver,
    Displacement,
    Direct,
    CG,
    MatrixFree,
    FEASolver,
    Assembly,
    DefaultCriteria,
    EnergyCriteria,
    simulate

const to = TimerOutput()

# FEA solvers
abstract type AbstractFEASolver end

include("grid_utils.jl")
include("matrix_free_operator.jl")
include("convergence_criteria.jl")
include("direct_displacement_solver.jl")
include("assembly_cg_displacement_solvers.jl")
include("matrix_free_cg_displacement_solvers.jl")
include("matrix_free_apply_bcs.jl")
include("simulate.jl")
include("solvers_api.jl")

getcompliance(solver) = solver.u' * solver.globalinfo.K * solver.u

end


text:
using JuMP
using SCIP

function reopt_model(time_limit_seconds::Real, limits_gap::Real)

    m = Model(with_optimizer(SCIP.Optimizer, display_verblevel=0, limits_time=time_limit_seconds, limits_gap=limits_gap))
	m[:solver_name] = "SCIP"
	m[:timeout_seconds] = time_limit_seconds
	m[:optimality_tolerance] = limits_gap
	return m

end


text:
@enum ERROR_CODE ERROR_NONE=0x0
                 ERROR_PROTOCOL=0x1
                 ERROR_INTERNAL=0x2
                 ERROR_FLOW_CONTROL=0x3
                 ERROR_SETTINGS_TIMEOUT=0x4
                 ERROR_STREAM_CLOSED=0x5
                 ERROR_FRAME_SIZE=0x6
                 ERROR_REFUSED_STREAM=0x7
                 ERROR_CANCEL=0x8
                 ERROR_COMPRESSION=0x9
                 ERROR_CONNECT=0xa
                 ERROR_ENHANCE_YOUR_CALM=0xb
                 ERROR_INADEQUATE_SECURITY=0xc
                 ERROR_HTTP_1_1_REQUIRED=0xd

type ProtocolError
    message::AbstractString
end

type InternalError
    message::AbstractString
end

type NullError end

function goaway!(connection::HTTPConnection, error)
    error_code = if typeof(error) == NullError
        0x0
    elseif typeof(error) == InternalError
        0x2
    else
        0x1
    end

    frame = GoawayFrame(0x0, error_code, Array{UInt8, 1}())

    put!(connection.channel_act_raw, frame)
end

Base.close(connection::HTTPConnection) = goaway!(connection, NullError())


text:
"Square the sum of the numbers up to the given number"
function square_of_sum(n::Int)

end

"Sum the squares of the numbers up to the given number"
function sum_of_squares(n::Int)

end

"Subtract sum of squares from square of sums"
function difference(n::Int)

end


text:
immutable EnumerableOrderby{T,S,KS,TKS} <: Enumerable{T}
    source::S
    keySelector::KS
    descending::Bool
end

function orderby{T}(source::Enumerable{T}, f::Function, f_expr::Expr)
    TKS = Base.return_types(f, (T,))[1]
    return EnumerableOrderby{T,typeof(source), FunctionWrapper{TKS,Tuple{T}},TKS}(source, f, false)
end

function orderby_descending{T}(source::Enumerable{T}, f::Function, f_expr::Expr)
    TKS = Base.return_types(f, (T,))[1]
    return EnumerableOrderby{T,typeof(source), FunctionWrapper{TKS,Tuple{T}},TKS}(source, f, true)
end

# TODO This should be changed to a lazy implementation
function start{T,S,KS,TKS}(iter::EnumerableOrderby{T,S,KS,TKS})
    elements = Array(T,0)
    for i in iter.source
        push!(elements, i)
    end

    sort!(elements, by=iter.keySelector, rev=iter.descending)

    return elements, 1
end

function next{T,S,KS,TKS}(iter::EnumerableOrderby{T,S,KS,TKS}, state)
    elements = state[1]
    i = state[2]
    return elements[i], (elements, i+1)
end

done{T,S,KS,TKS}(f::EnumerableOrderby{T,S,KS,TKS}, state) = state[2] > length(state[1])

immutable EnumerableThenBy{T,S,KS,TKS} <: Enumerable{T}
    source::S
    keySelector::KS
    descending::Bool
end

function thenby{T}(source::Enumerable{T}, f::Function, f_expr::Expr)
    TKS = Base.return_types(f, (T,))[1]
    return EnumerableThenBy{T,typeof(source), FunctionWrapper{TKS,Tuple{T}},TKS}(source, f, false)
end

function thenby_descending{T}(source::Enumerable{T}, f::Function, f_expr::Expr)
    TKS = Base.return_types(f, (T,))[1]
    return EnumerableThenBy{T,typeof(source), FunctionWrapper{TKS,Tuple{T}},TKS}(source, f, true)
end

# TODO This should be changed to a lazy implementation
function start{T,S,KS,TKS}(iter::EnumerableThenBy{T,S,KS,TKS})
    # Find start of ordering sequence
    source = iter.source
    keySelectors = [source.keySelector,iter.keySelector]
    directions = [source.descending, iter.descending]
    while !isa(source, EnumerableOrderby)
        source = source.source
        insert!(keySelectors,1,source.keySelector)
        insert!(directions,1,source.descending)
    end
    keySelector = element->[i(element) for i in keySelectors]

    lt = (t1,t2) -> begin
        n1, n2 = length(t1), length(t2)
        for i = 1:min(n1, n2)
            a, b = t1[i], t2[i]
            descending = directions[i]
            if !isequal(a, b)
                return descending ? !isless(a, b) : isless(a, b)
            end
        end
        return n1 < n2
    end

    elements = Array(T,0)
    for i in source
        push!(elements, i)
    end

    sort!(elements, by=keySelector, lt=lt)

    return elements, 1
end

function next{T,S,KS,TKS}(iter::EnumerableThenBy{T,S,KS,TKS}, state)
    elements = state[1]
    i = state[2]
    return elements[i], (elements, i+1)
end

done{T,S,KS,TKS}(f::EnumerableThenBy{T,S,KS,TKS}, state) = state[2] > length(state[1])


text:
using BinaryBuilder, Pkg

name = "Enzyme"
repo = "https://github.com/wsmoses/Enzyme.git"

auto_version = "refs/tags/v0.0.10"
version = VersionNumber(split(auto_version, "/")[end])

# Collection of sources required to build attr
sources = [GitSource(repo, "7495e2ff0187c1e4188eabbd0685601629d92b6f")]

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = expand_cxxstring_abis(supported_platforms())

# Bash recipe for building across all platforms
script = raw"""
cd Enzyme
# install_license LICENSE.TXT
CMAKE_FLAGS=()
# Release build for best performance
CMAKE_FLAGS+=(-DENZYME_EXTERNAL_SHARED_LIB=ON)
CMAKE_FLAGS+=(-DCMAKE_BUILD_TYPE=RelWithDebInfo)
# Install things into $prefix
CMAKE_FLAGS+=(-DCMAKE_INSTALL_PREFIX=${prefix})
# Explicitly use our cmake toolchain file and tell CMake we're cross-compiling
CMAKE_FLAGS+=(-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TARGET_TOOLCHAIN})
CMAKE_FLAGS+=(-DCMAKE_CROSSCOMPILING:BOOL=ON)
# Tell CMake where LLVM is
CMAKE_FLAGS+=(-DLLVM_DIR="${prefix}/lib/cmake/llvm")
# Force linking against shared lib
CMAKE_FLAGS+=(-DLLVM_LINK_LLVM_DYLIB=ON)
# Build the library
CMAKE_FLAGS+=(-DBUILD_SHARED_LIBS=ON)
cmake -B build -S enzyme -GNinja ${CMAKE_FLAGS[@]}
ninja -C build -j ${nproc} install
"""

# The products that we will ensure are always built
products = Product[
    LibraryProduct(["libEnzyme-11", "libEnzyme"], :libEnzyme),
]

dependencies = [
    BuildDependency(PackageSpec(name="LLVM_full_jll", version=v"11.0.1")),
#    Dependency(PackageSpec(name="libLLVM_jll", version=v"9.0.1"))
]

# Build the tarballs.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies;
               preferred_gcc_version=v"8", julia_compat="1.6")


text:
function jt11c()
#
#  test polynomial suggested by Jenkins and Traub
#
    m = 25;
    y = exp.((im*pi) .*  (1-m:m-1) ./ (2*m))
    z = 0.9*exp.((im*pi) .* (m:3*m) ./ (2*m))
    u = [y; z]
    p = poly(u)
    z = [u ones(length(u))]
    p, PolyZeros(z)
end


text:
const filtering_labels = collect(0:9)#[0, 1]

function mnist_training_data()
    X, T = MLDatasets.MNIST.traindata()
    reshape_data(filter_data(X, T)...)
end

function mnist_training_data(n_samples::Int)
    random_sample(n_samples, mnist_training_data()...)
end

function mnist_testing_data()
    X, T = MLDatasets.MNIST.testdata()
    reshape_data(filter_data(X, T)...)
end

function mnist_testing_data(n_samples::Int)
    random_sample(n_samples, mnist_testing_data()...)
end

function filter_data(samples::T1,
                     targets::T2) where {T1 <: AbstractArray,
                                         T2 <: AbstractVector}
    indices = findall(x -> x ∈ filtering_labels, targets)
    (samples[:,:,indices], targets[indices])
end

function reshape_data(samples::T1,
                      targets::T2) where {T1 <: AbstractArray,
                                          T2 <: AbstractVector}
    (reshape_samples(samples), reshape_targets(targets))
end

function reshape_samples(samples::T) where {T <: AbstractArray}
    rows, cols, N = size(samples)
    reshape(samples, (rows * cols, N))
end

function reshape_targets(targets::T) where {T <: AbstractVector}
    [x ∈ [0, 1, 2, 3, 4] ? 1 : -1 for x ∈ targets]
    # [x == 1 ? 1 : -1 for x ∈ targets]
end

function random_sample(n_samples::Int,
                       samples::T1,
                       targets::T2) where {T1 <: AbstractArray,
                                           T2 <: AbstractVector}
    @assert n_samples <= length(targets) "Blah."
    range = length(targets)
    indices = Random.randperm(range)[1:n_samples]
    (samples[:,indices], targets[indices])
end


text:
# main module

module AppliSQLite

greet() = print("AppliSQLite")

#using SQLite

#using DataFrames

# Domain objects
#export create

# Database functions
export connect, archive, store, retrieve, runfunct

include("./infrastructure.jl")

end


text:
# additional helper functions for spherical harmonics spectra

"""
    TransSphericalToGrid!(mesh, snm )

Transforms a variable expressed in spherical harmonics (var_spherical[num_fourier+1, num_spherical+1]) onto a Gaussian grid (pfield[nλ, nθ])

[THIS IS USED FOR TESTING ONLY]

    With F_{m,n} = (-1)^m F_{-m,n}*
    P_{m,n} = (-1)^m P_{-m,n}

    F(λ, η) = ∑_{m= -N}^{N} ∑_{n=|m|}^{N} F_{m,n} P_{m,n}(η) e^{imλ}
    = ∑_{m= 0}^{N} ∑_{n=m}^{N} F_{m,n} P_{m,n} e^{imλ} + ∑_{m= 1}^{N} ∑_{n=m}^{N} F_{-m,n} P_{-m,n} e^{-imλ}

    Here η = sinθ, N = num_fourier, and denote
    ! extra coeffients in snm n > N are not used.

    ∑_{n=m}^{N} F_{m,n} P_{m,n}     = g_{m}(η) m = 1, ... N
    ∑_{n=m}^{N} F_{m,n} P_{m,n}/2.0 = g_{m}(η) m = 0

    We have

    F(λ, η) = ∑_{m= 0}^{N} g_{m}(η) e^{imλ} + ∑_{m= 0}^{N} g_{m}(η)* e^{-imλ}
    = 2real{ ∑_{m= 0}^{N} g_{m}(η) e^{imλ} }

    snm = F_{m,n}         # Complex{Float64} [num_fourier+1, num_spherical+1]
    qnm = P_{m,n,η}         # Float64[num_fourier+1, num_spherical+1, nθ]
    fourier_g = g_{m, η} # Complex{Float64} nλ×nθ with padded 0s fourier_g[num_fourier+2, :] == 0.0
    pfiled = F(λ, η)      # Float64[nλ, nθ]

    ! use all spherical harmonic modes

# Arguments
- mesh: struct with mesh information
- snm: spherical variable

# References
- Ehrendorfer, M., Spectral Numerical Weather Prediction Models, Appendix B, Society for Industrial and Applied Mathematics, 2011
"""
function trans_spherical_to_grid!(mesh, snm)
    num_fourier, num_spherical = mesh.num_fourier, mesh.num_spherical
    nλ, nθ, nd = mesh.nλ, mesh.nθ, mesh.nd

    qnm = mesh.qnm

    fourier_g = mesh.var_fourier .* 0.0
    fourier_s = mesh.var_fourier .* 0.0

    @assert(nθ % 2 == 0)
    nθ_half = div(nθ, 2)
    for m in 1:(num_fourier + 1)
        for n in m:num_spherical
            snm_t = transpose(snm[m, n, :, 1:nθ_half]) #snm[m,n, :] is complex number
            if (n - m) % 2 == 0
                fourier_s[m, 1:nθ_half, :] .+=
                    qnm[m, n, 1:nθ_half] .* sum(snm_t, dims = 1)   #even function part
            else
                fourier_s[m, (nθ_half + 1):nθ, :] .+=
                    qnm[m, n, 1:nθ_half] .* sum(snm_t, dims = 1)   #odd function part
            end
        end
    end
    fourier_g[:, 1:nθ_half, :] .=
        fourier_s[:, 1:nθ_half, :] .+ fourier_s[:, (nθ_half + 1):nθ, :]
    fourier_g[:, nθ:-1:(nθ_half + 1), :] .=
        fourier_s[:, 1:nθ_half, :] .- fourier_s[:, (nθ_half + 1):nθ, :] # this got ignored...

    fourier_g[1, :, :] ./= 2.0
    pfield = zeros(Float64, nλ, nθ, nd)
    for j in 1:nθ
        pfield[:, j, :] .= 2.0 * nλ * real.(ifft(fourier_g[:, j, :], 1)) #fourier for the first dimension
    end
    return pfield
end


text:
# deprecated methods

import Base: get

@deprecate get(set::TargetSet, name::String) getindex(set, name)

@deprecate FunctionType(rettyp, params, vararg) FunctionType(rettyp, params; vararg=vararg)


text:
function select_threadpool(cdims::DenseConvDims, batch_size::Int)
    inp_size = input_size(cdims)[1]
    if batch_size >= 32
        return shared_threadpool_dict[Int(NNPACK_CPU_THREADS)][]
    elseif batch_size >= 16 && inp_size >= 64
        return shared_threadpool_dict[Int(NNPACK_CPU_THREADS)][]
    elseif inp_size <= 32
        return C_NULL
    elseif inp_size >= 128
        return shared_threadpool_dict[Int(NNPACK_CPU_THREADS)][]
    elseif inp_size * batch_size >= 256
        return shared_threadpool_dict[Int(NNPACK_CPU_THREADS)][]
    end
    return C_NULL
end

function select_threadpool(pdims::PoolDims, batch_size::Int)
    inp_size = input_size(pdims)[1]
    if batch_size >= 32
        return shared_threadpool_dict[Int(NNPACK_CPU_THREADS)][]
    elseif batch_size >= 16 && inp_size >= 64
        return shared_threadpool_dict[Int(NNPACK_CPU_THREADS)][]
    elseif inp_size <= 32
        return C_NULL
    elseif inp_size >= 128
        return shared_threadpool_dict[Int(NNPACK_CPU_THREADS)][]
    elseif inp_size * batch_size >= 256
        return shared_threadpool_dict[Int(NNPACK_CPU_THREADS)][]
    end
    return C_NULL
end


text:
using DashBootstrapComponents

card = dbc_card(
    [
        dbc_row(
            [
                dbc_col(
                    dbc_cardimg(
                        src = "/static/images/portrait-placeholder.png",
                        className = "img-fluid rounded-start",
                    ),
                    className = "col-md-4",
                ),
                dbc_col(
                    dbc_cardbody([
                        html_h4("Card title", className = "card-title"),
                        html_p(
                            "This is a wider card with supporting text " *
                            "below as a natural lead-in to additional " *
                            "content. This content is a bit longer.",
                            className = "card-text",
                        ),
                        html_small(
                            "Last updated 3 mins ago",
                            className = "card-text text-muted",
                        ),
                    ]),
                    className = "col-md-8",
                ),
            ],
            className = "g-0 d-flex align-items-center",
        ),
    ],
    className = "mb-3",
    style = Dict("maxWidth" => "540px"),
)

max_issues_repo_name: sthagen/dash-bootstrap-components

max_forks_repo_name: sthagen/dash-bootstrap-components


text:
export cross_validation

"""
    cross_validation(
        n_fold::Int,
        metric::Type{<:Metric},
        k::Int,
        recommender_type::Type{<:Recommender},
        data::DataAccessor,
        recommender_args...
    )

Conduct `n_fold` cross validation for a combination of recommender `recommender_type` and metric `metric`. A recommender is initialized with `recommender_args`. For ranking metric, accuracy is measured by top-`k` recommendation.
"""
function cross_validation(n_fold::Int, metric::Type{<:Metric}, k::Int, recommender_type::Type{<:Recommender}, data::DataAccessor, recommender_args...)

    n_user, n_item = size(data.R)

    events = shuffle(data.events)
    n_events = length(events)

    step = convert(Int, round(n_events / n_fold))
    accum = 0.0

    for head in 1:step:n_events
        tail = min(head + step - 1, n_events)

        truth_events = events[head:tail]
        truth_data = DataAccessor(truth_events, n_user, n_item)

        train_events = vcat(events[1:head - 1], events[tail + 1:end])
        train_data = DataAccessor(train_events, n_user, n_item)

        # get recommender from the specified data type
        recommender = recommender_type(train_data, recommender_args...)
        build!(recommender)

        accum += evaluate(recommender, truth_data, metric(), k)
    end

    accum / n_fold
end


text:
using CategoricalArrays
import LinearAlgebra: pinv
using DataFrames
using MixedModels: getθ, nranef
import RCall: rcopy,
              reval,
              @R_str

"""
    categorical!(df::DataFrame, cols::Vector{Symbol})
    categorical!(df::DataFrame, col::Symbol)

Convert `cols` of `df` to CategoricalArrays.

This replaces functionality previously part of DataFrames.jl and
is intentionally not exported to avoid type piracy.
"""
categorical!(df::DataFrame, cols::Vector{Symbol}) = transform!(df, (cc => categorical for cc in cols)...; renamecols=false)
categorical!(df::DataFrame, col::Symbol) = transform!(df, col => categorical; renamecols=false)

_guarantee_array(val::AbstractArray) = val
_guarantee_array(val) = [val]

"""
    rcopyarray(robj)

Copy an object from R, guaranteeing that it is an array.

This is useful to undo RCall's automatic conversion of size 1 arrays to scalars.
"""
rcopyarray(robj) = _guarantee_array(rcopy(robj))

"""
get the contrasts from an R dataframe
"""
function get_r_contrasts(rdf)
    data = rcopy(rdf)
    # get categorical columns
    cnames = [c for c in propertynames(data)  if typeof(data[!, c]) <: CategoricalArray]
    Dict(c => HypothesisCoding(pinv(rcopy(R"contrasts($(rdf[c]))")),
                               labels=rcopyarray( R"colnames(contrasts($(rdf[c])))" )
                               )
         for c in cnames)
end

"""
set the contrasts on an R dataframe
this of course has a side effect: it changes the R dataframe
"""

function set_r_contrasts!(rdfname, formula)
    fixefform = first(formula.rhs)

    for tt in fixefform.terms
        if typeof(tt) <: CategoricalTerm
            R"""
            jellyme_contrasts <- $(tt.contrasts.matrix)
            colnames(jellyme_contrasts) <- $(tt.contrasts.termnames)
            rownames(jellyme_contrasts) <- $(tt.contrasts.levels)
            """
            # we need rdfname to be interpolated normally before the R macros stuff is called
            reval("""
            # we need to be double-plus sure these are factors
            $(rdfname)[, "$(tt.sym)"] <- factor($(rdfname)[, "$(tt.sym)"])
            contrasts($(rdfname)[, "$(tt.sym)"]) <- jellyme_contrasts
            """)
        elseif typeof(tt) <: InteractionTerm && any( typeof(tx) <: CategoricalTerm for tx in tt.terms)
            # do nothing -- unless you're doing something really crazy,
            # then this should be handled by the coding of the first-order terms
            # if you are doing something that crazy, then you know enough linear algebra
            # to copy and interpret the relevant matrices directly
            @info "contrasts on interaction terms are assumed to decompose into products of contrasts on the first-order terms" maxlog=1
            @info "(if you don't know what that means, you're probably fine)" maxlog=1
        end
    end
    rdfname
end

#####
##### See GitHub issue #38 on ordering
#####

function _reorder_theta_from_lme4(θlme4, model)
    reterms = model.reterms

    # not the most efficient procedure, but it's not too hard

    # put them in lme4 order
    rr = sort(reterms; rev=true, by=x -> length(x.levels) )
    # compute the permutation from lme4 to julia
    reperm = sort(1:length(rr); rev=true, by=x -> nranef(rr[x]))

    # extract the individual theta blocks
    start = 1
    θs = []
    for r in rr
        finish = start + length(getθ(r)) - 1
        push!(θs, θlme4[start:finish])
        start = finish + 1
    end

    # permute
    θjulia = vcat(θs[reperm]...)
    return θjulia
end

function _reorder_theta_to_lme4(model)
    # lme4 sorts the order of RE terms based on nlevels of the grouping var
    reperm = sort(1:length(model.reterms);
                  rev=true,
                  by=x-> length(model.reterms[x].levels))

    return vcat(getθ.(model.reterms)[reperm]...)
end