text:
using Nervoso, FactCheck

facts("Layer") do
    context("Build a layer") do
        @fact FFNNLayer(10) --> not(nothing)
        @fact FFNNLayer(10, softmax, bias = false) --> not(nothing)

        layer1 = FFNNLayer(10)
        layer2 = FFNNLayer(10, softmax, bias = false)

        context("With Bias") do
            @fact layer1.bias --> true
            @fact length(layer1.neurons) --> 11
            @fact layer1.activation == tanh --> true
        end
        context("Without Bias and different activation function") do
            layer2 = FFNNLayer(10, softmax, bias = false)
            @fact layer2.bias --> false
            @fact length(layer2.neurons) --> 10
            @fact layer2.activation == softmax --> true
        end
    end

    layer1 = FFNNLayer(10)
    layer2 = FFNNLayer(10, softmax, bias = false)

    context("Basic informations of a layer") do
        context("Default activation") do
            @fact layer1 == FFNNLayer(10, tanh) --> true
        end

        context("Size and length") do
            @fact size(layer1)   --> 10
            @fact length(layer2) --> 10
            @fact size(layer1)   --> 10
            @fact length(layer2) --> 10
        end

        context("Access neurons") do
            @fact layer1[1] --> 0
            @fact layer2[1] --> 0
            @fact layer1[end] --> 0
            @fact layer2[end] --> 0
        end

        context("Access bias") do
            @fact layer1[0] --> 1.0
            @fact_throws layer2[0]
        end

        context("Iterating on a layer") do
            # Iterate on layer1
            c = 0
            for i in layer1
                @fact i --> 0.0
                c += 1
            end
            @fact c --> 10

            # Iterate on layer1
            c = 0
            for i in layer2
                @fact i --> 0.0
                c += 1
            end
            @fact c --> 10
        end
    end

    context("Update and activate a layer") do
        context("Activate") do
            @fact activate(layer1) --> vcat([1.0], zeros(10))
            @fact activate(layer2) --> ones(10)/10
        end

        context("Update") do
            @fact_throws update(layer1, [1])
            update!(layer1, ones(10))
            @fact layer1.neurons --> ones(11)

            @fact_throws update(layer2, [1])
            update!(layer2, ones(10))
            @fact layer2.neurons --> ones(10)
        end
    end

    context("Printing") do
        buf = IOBuffer()

        show(buf, layer1)
        repr = takebuf_string(buf)
        @fact startswith(repr, "Feedforward Neural Net Layer:") --> true
        @fact ismatch(r"bias", repr) --> true
        @fact startswith(repr, "Feedforward Neural Net Layer:") --> true

        show(buf, layer2)
        repr = takebuf_string(buf)
        @fact startswith(repr, "Feedforward Neural Net Layer:") --> true
        @fact ismatch(r"bias", repr) --> false
        @fact endswith(repr, "softmax") --> true
    end
end

facts("Network") do
    context("Build a network") do
        @fact FFNNet(10,10,10) --> not(nothing)
        @fact FFNNet(10,10,10,10,10) --> not(nothing)

        layer1 = FFNNLayer(10)
        layer2 = FFNNLayer(10, softmax, bias = false)
        @fact FFNNet([layer1, layer2], 10) --> not(nothing)

        @fact_throws FFNNet(10)
        @fact_throws FFNNet(10,10)
    end

    net1 = FFNNet(2,10,10)
    net2 = FFNNet(2,10,10,10,10)

    context("Basic informations of a network") do
        @fact length(net1) --> 2
        @fact length(net2) --> 4
        @fact size(net1) --> (2,2)
        @fact size(net2) --> (2,4)
    end

    context("Propagating examples") do
        @fact (typeof(propagate(net1, ones(2))) == Vector{Float64}) --> true
        @fact (typeof(propagate(net2, ones(2))) == Vector{Float64}) --> true
        @fact_throws propagate(net1, ones(1))
        @fact_throws propagate(net1, ones(3))
        @fact_throws propagate(net2, ones(1))
        @fact_throws propagate(net2, ones(3))
    end

    inputs = Vector{Float64}[
        rand(2),
        rand(2),
        rand(2),
    ]

    outputs = Vector{Float64}[
        rand(10),
        rand(10),
        rand(10),
    ]

    context("Training") do
        @fact train!(net1, inputs, outputs) --> nothing
        @fact train!(net2, inputs, outputs) --> nothing
    end

    context("Assessing performance") do
        @fact (typeof(meanerror(net1, inputs, outputs)) == Float64) --> true
        @fact (typeof(meanerror(net2, inputs, outputs)) == Float64) --> true
        @fact (typeof(classerror(net1, inputs, outputs)) == Int) --> true
        @fact (typeof(classerror(net2, inputs, outputs)) == Int) --> true
    end

    context("Printing") do
        buf = IOBuffer()

        show(buf, net1)
        repr = takebuf_string(buf)
        @fact startswith(repr, "2 Layers") --> true
        @fact ismatch(r"Feedforward Neural Network:", repr) --> true
        @fact ismatch(r"Input Size:", repr) --> true

        show(buf, net2)
        repr = takebuf_string(buf)
        @fact startswith(repr, "4 Layers") --> true
        @fact ismatch(r"Feedforward Neural Network:", repr) --> true
        @fact ismatch(r"Input Size:", repr) --> true
    end
end

facts("Activation functions") do
    layer1 = FFNNLayer(10)
    layer2 = FFNNLayer(10, bias = false)

    context("tanh") do
        @fact derivatives[tanh] == tanhprime --> true
        @fact der(tanh) == tanhprime --> true

        @fact typeof(tanh(layer1)) == Vector{Float64} --> true
        @fact length(tanh(layer1)) --> length(layer1) + 1
        @fact tanh(layer1) --> vcat([1.0], zeros(length(layer1)))
        @fact typeof(der(tanh)(layer1)) == Matrix{Float64} --> true
        @fact  size(der(tanh)(layer1)) --> (length(layer1) + 1, length(layer1) + 1)

        @fact typeof(tanh(layer1)) == Vector{Float64} --> true
        @fact length(softmax(layer2)) --> length(layer2)
        @fact tanh(layer2) --> zeros(length(layer2))
        @fact typeof(der(tanh)(layer2)) == Matrix{Float64} --> true
        @fact  size(der(tanh)(layer2)) --> (length(layer2), length(layer2))
    end

    context("softmax") do
        @fact derivatives[softmax] == softmaxprime --> true
        @fact der(softmax) == softmaxprime --> true

        @fact typeof(softmax(layer1)) == Vector{Float64} --> true
        @fact length(softmax(layer1)) --> length(layer1) + 1
        @fact typeof(der(softmax)(layer1)) == Matrix{Float64} --> true
        @fact  size(der(softmax)(layer1)) --> (length(layer1) + 1, length(layer1) + 1)

        @fact typeof(softmax(layer2)) == Vector{Float64} --> true
        @fact length(softmax(layer2)) --> length(layer2)
        @fact typeof(der(softmax)(layer2)) == Matrix{Float64} --> true
        @fact  size(der(softmax)(layer2)) --> (length(layer2), length(layer2))
    end

    context("logistic") do
        @pending derivatives[σ] == σprime --> true
        @pending der(σ) == σprime --> true
        @pending derivatives[logistic] == logisticprime --> true
        @pending der(logistic) == logisticprime --> true
    end
end

facts("Cost functions") do
    context("Quadratic Error") do
        @fact der(quaderror) == Nervoso.derivatives[quaderror] --> true
        @fact der(quaderror) == Nervoso.quaderrorprime --> true
        @fact quaderror([1.0,0.0], [0.0,1.0]) --> roughly(1.0)
        @fact Nervoso.quaderrorprime([1.0,0.0], [0.0,1.0]) --> [1.0,-1.0]
    end

    context("Cross-entropy Error") do
        @fact der(ceerror) == Nervoso.derivatives[ceerror] --> true
        @fact der(ceerror) == Nervoso.ceerrorprime --> true
        @fact ceerror([0.5,0.5], [0.5,0.5]) .< [Inf] --> Bool[true]
        @fact Nervoso.ceerrorprime([0.5,0.5], [0.5,0.5]) --> [-1.0, -1.0]
    end
end


text:
module SARA
using JSON
using Base.Threads
using LinearAlgebra
using Interpolations
using ForwardDiff

using CovarianceFunctions
const Kernel = CovarianceFunctions
using GaussianDistributions
using GaussianDistributions: input_transformation

export innerloop, inner, uncertainty_sampling, evaluate, TemperatureProfile,
        next_stripe, get_relevant_T, iSARA, oSARA, xrd_to_global, stripe_to_global,
        stripe_uncertainty_sampling

include("util.jl")
include("estimate_noise.jl")
include("temperature_profile.jl")
include("acquisition.jl") # acquisition functions
include("inner.jl") # inner and outer loops for optical spectroscopy
include("stripe_to_global.jl")
include("outer.jl")

end # SARA

ext: jl


text:
module TestUtils

using Bootstrap
using FactCheck

facts("Exact sampling") do

    mss = collect(Bootstrap.exact(4))
    @fact length(mss) --> 35
    @fact reduce(&, [issorted(c) for c in mss]) --> true

    for n in 1:6
        @fact length(Bootstrap.exact(n)) --> Bootstrap.nrun_exact(n)
    end

end

end


text:
module AmbientForcing
include("AmbientForcingODE.jl")
include("RandInitVectors.jl")
export ambient_forcing
export ambient_forcing_problem
export random_force
export idx_exclusive
export constraint_equations
end


text:
# -------------- Solve equation at equilibrium  --------------

using NLsolve

# I- NCDRe

## Parameter values
In1 = .3
rn  = 0.05
a1  = 0.6
b1  = 0.04
dD  = 0.1
df  = 0.05
f   = 0.8
a32 = 0.25
h32 = 0.005
d1  = 0.1
d2  = 0.001
e1  = 0.05
e2  = 0.05
e3  = 0.05

function f!(F, u)
    F[1] = In1 - rn * u[1] - a1 * u[1] * u[2] / ( b1 + u[1]) + dD * u[4] - df * u[1]
    F[2] = f * a1 * u[1] * u[2] / (b1 + u[1]) - a32 * u[2] * u[3] / (1. + a32*h32*u[2]) - (d1 + e1) * u[2]
    F[3] = f * a32 * u[2] * u[3] / (1. + a32*h32*u[2]) - (d2 + e2) * u[3]
    F[4] = d1 * u[2] + d2 * u[3] - (dD + e3) * u[4]
end

initU2 = (d2 + e2)/(f * a32 - a32 * h32 * (d2 + e2))

# function, jacobian (autodiff) and initial guess
# equilibrium for initial node i
soli = nlsolve(f!, [1.1; initU2; .6; .4], autodiff = :forward)
# check against results in example

# Hub node
function fh!(Fh, uh)
    Fh[1] = In1 - rn * uh[1] -a1 * uh[1] * uh[2] / ( b1 + uh[1]) + dD*uh[4] + df * soli.zero[1] - df * uh[1]
    Fh[2] = f * a1 * uh[1] * uh[2] / (b1 + uh[1]) - a32 * uh[2] * uh[3] / (1. + a32 * h32 * uh[2]) - (d1 + e1) * uh[2]
    Fh[3] = f * a32 * uh[2] * uh[3] / (1. + a32 * h32 * uh[2]) - (d2 + e2) * uh[3]
    Fh[4] = d1 * uh[2] + d2 * uh[3] - (dD + e3) * uh[4]
end

# function, jacobian (autodiff) and initial guess
# equilibrium for initial node i
solh = nlsolve(fh!, [1.1; initU2; .6; .4], autodiff = :forward)

function ft!(Ft, ut)
    Ft[1] = In1 - rn * ut[1] -a1 * ut[1] * ut[2] / ( b1 + ut[1]) + dD*ut[4] + df * solh.zero[1]
    Ft[2] = f * a1 * ut[1] * ut[2] / (b1 + ut[1]) - a32 * ut[2] * ut[3] / (1. + a32 * h32 * ut[2]) - (d1 + e1) * ut[2]
    Ft[3] = f * a32 * ut[2] * ut[3] / (1. + a32 * h32 * ut[2]) - (d2 + e2) * ut[3]
    Ft[4] = d1 * ut[2] + d2 * ut[3] - (dD + e3) * ut[4]
end

# function, jacobian (autodiff) and initial guess
# equilibrium for initial node i
solt = nlsolve(ft!, [ 1.1; initU2; .6; .4], autodiff = :forward)

# II- NCDReRle

## Additional parameters (remaining are set as above)

a11 = 0.35
b11 = 0.05
a42 = 0.25
h42 = 0.005
h43 = 0.005
a43 = 0.09
d11 = 0.11

function f!(F, u)
    F[1] = In1 - rn * u[1] -a1 * u[1] * u[2] / ( b1 + u[1]) - a11 * u[1] * u[3] / ( b11 + u[1]) + dD * u[5] - df * u[1]
    F[2] = f * a1 * u[1]*u[2] / (b1 + u[1]) - a42 * u[2] * u[4] / (1. + a42*h42*u[2]+a43*h43*u[3]) - (d1 + e1)*u[2]
    F[3] = f * a11 * u[1]*u[3] / (b11 + u[1]) - a43 * u[3] * u[4] / (1. + a42*h42*u[2]+a43*h43*u[3]) - (d11 + e1)*u[3]
    F[4] = f * a42 * u[2] * u[4] / (1. + a42*h42*u[2]+a43*h43*u[3]) +  f * a43 * u[3] * u[4] / (1. + a42*h42*u[2]+a43*h43*u[3]) - (d2 + e2) * u[4]
    F[5] = d1 * u[2] + d11 * u[3] + d2 * u[4] -  (dD + e3) * u[5]
end

#a43=0
initU1 = b1 * (d1 + e1) / (f * a1 -  (d1 + e1))
initU2 = (d2 + e2)/(f * a42 -  a42 * h42 * (d2 + e2))

#i nvasion criteria for inedible with N-values
Nstar = b11 * (d11 + e1)/(f * a11 - (d11+e1))
    if Nstar < 0
        Nstar = 1000000.
    end

if initU1 > Nstar
    initU1 = Nstar
end

# function, jacobian (autodiff) and initial guess
# equilibrium for initial node i
soli = nlsolve(f!, [ initU1; .01; .01;.1;.3], autodiff = :forward,ftol=1.0e-16,iterations = 1000000)
# mcpsolve(f!, [-1.e-16,0.0,0.0,0.0,0.0], [100,100,100,100,100], [ initU1; .01; .01;.1;.3], autodiff = :forward, ftol = 1.0e-16) # returns 6.25915e8

# not hub node
function fh!(Fh, uh)
    Fh[1] = In1 - rn * uh[1] -a1 * uh[1] * uh[2] / ( b1 + uh[1]) - a11 * uh[1] * uh[3] / ( b11 + uh[1]) + dD * uh[5] + df * soli.zero[1] - df * uh[1]
    Fh[2] = f * a1 * uh[1] * uh[2] / (b1 + uh[1]) - a42 * uh[2] * uh[4] / (1. + a42*h42*uh[2]+a43*h43*uh[3]) - (d1 + e1) * uh[2]
    Fh[3] = f * a11 * uh[1] * uh[3] / (b11 + uh[1]) - a43 * uh[3] * uh[4] / (1. + a42*h42*uh[2]+a43*h43*uh[3]) - (d11 + e1) * uh[3]
    Fh[4] = f * a42 * uh[2] * uh[4] / (1. + a42*h42*uh[2]+a43*h43*uh[3]) + f * a43 * uh[3] * uh[4] / (1. + a42*h42*uh[2]+a43*h43*uh[3]) - (d2 + e2) * uh[4]
    Fh[5] = d1 * uh[2] + d11 * uh[3] + d2 * uh[4] -  (dD + e3) * uh[5]
end

# function, jacobian (autodiff) and initial guess
# equilibrium for initial node i
solh = nlsolve(fh!, [ initU1; .01; .01;.1;.3], autodiff = :forward,ftol=1.0e-16,iterations=1000000)
NLsolve.mcpsolve(fh!, [0.,0.,0.,0.0,0.0], [Inf,Inf,Inf,Inf,Inf], [ initU1; .01; .01;.1;.3], reformulation = :smooth, autodiff = :forward,ftol=1.0e-16) # returns -1.48382
NLsolve.mcpsolve(fh!, [0.,0.,0.,0.0,0.0], [Inf,Inf,Inf,Inf,Inf], [ initU1; .01; .01;.1;.3], reformulation = :minmax, autodiff = :forward,ftol=1.0e-16) # returns -1.0
NLsolve.mcpsolve(fh!, [0.,0.,0.,0.0,0.0], [Inf,Inf,Inf,Inf,Inf], [ initU1; .01; .01;.1;.3], reformulation = :smooth, autodiff = :forward,ftol=1.0e-16, method = :newton) # returns 6.25915e8

function ft!(Ft, ut)
    Ft[1] = In1 - rn * ut[1] -a1 * ut[1] * ut[2] / ( b1 + ut[1]) - a11 * ut[1] * ut[3] / ( b11 + ut[1]) + dD * ut[5] + df * solh.zero[1]
    Ft[2] = f * a1 * ut[1] * ut[2] / (b1 + ut[1]) - a42 * ut[2] * ut[4] / (1. + a42*h42*ut[2]+a43*h43*ut[3]) - (d1 + e1) * ut[2]
    Ft[3] = f * a11 * ut[1] * ut[3] / (b11 + ut[1]) - a43 * ut[3] * ut[4] / (1. + a42*h42*ut[2]+a43*h43*ut[3]) - (d11 + e1) * ut[3]
    Ft[4] = f * a42 * ut[2] * ut[4] / (1. + a42*h42*ut[2]+a43*h43*ut[3]) + f * a43 * ut[3] * ut[4] / (1. + a42*h42*ut[2]+a43*h43*ut[3]) - (d2 + e2) * ut[4]
    Ft[5] = d1 * ut[2] + d11 * ut[3] + d2 * ut[4] -  (dD + e3) * ut[5]
end

# function, jacobian (autodiff) and initial guess
# equilibrium for initial node i
solt = nlsolve(ft!, [initU1; .01; .01; .1;.3], autodiff = :forward, ftol = 1.0e-16, iterations = 1e6)

max_stars_repo_name: McCannLab/NDID

max_issues_repo_name: McCannLab/NDID

max_forks_repo_name: McCannLab/NDID


text:
module DelaunayTriangulations

include("GeometryPredicates.jl")
using .GeometryPredicates
export orient_fast, orient_exact, orient, incircle_fast, incircle_exact, incircle

include("triangulation.jl")
export Triangulation, add_triangle!, delete_triangle!, adjacent, adjacent_to_vertex, orient, incircle

include("biased_random_order.jl")
export biased_random_order

include("delaunay.jl")
export delaunay_triangulation, insert_vertex!, dig_cavity!

end # module

max_stars_repo_name: PaulMatlashewski/DelaunayTriangulations

max_issues_repo_name: PaulMatlashewski/DelaunayTriangulations

max_forks_repo_name: PaulMatlashewski/DelaunayTriangulations


text:
using PyCall
export ASE

""" ASE interface simple

example
=======

>>> asemodel = ASE(("Al12Au",), Dict(:cell=>cell), "ase.calculators.emt", "EMT", (), Dict())

ASE(PyObject Atoms(symbols='Al12Au', pbc=False, cell=[5.727564927611035, 5.727564927611035, 13.75],
calculator=EMT(...)), PyObject <ase.calculators.emt.EMT object at 0x2b55d12a94d0>)
"""
struct ASE <: Model
    atoms
    calc
    results
end

function ASE(atoms_args, atoms_kwargs, calc_module, calc_name, calc_args, calc_kwargs)

    atoms = pyimport("ase.atoms")[:Atoms](atoms_args...; atoms_kwargs...)
    calc = pyimport(calc_module)[Symbol(calc_name)](calc_args...; calc_kwargs...)
    atoms.set_calculator(calc)
    ASE(atoms, calc, Dict())
end

@inline (model::ASE)(paths::Paths, coords::Coords, properties::Array{T, 1}) where {T} = (model::ASE)(coords::Coords, Array{String, 1}(properties))
@inline (model::ASE)(coords::Coords, properties::Array{T, 1}) where {T} = (model::ASE)(convert(Cartesian{eltype(coords), 3}, coords), Array{String, 1}(properties))

"""
coords : Cartesian; N x 3

return : N x size(property) results
"""
function (model::ASE)(coords::Cartesian{T, 3}, properties::Array{String, 1}) where {T<:Number}
    N, A, _ = size(coords)
    results = Dict()
    cache = Dict([(property, []) for property in properties])

    atoms = model.atoms

    # Initialize

    for i in 1:N
        positions = coords.coords[i, :, :]
        atoms.set_positions(positions)

        if "potential" in properties
            push!(cache["potential"], atoms.get_potential_energy())
        end

        if "gradients" in properties
            dV = -atoms.get_forces()
            push!(cache["gradients"], reshape(dV, 1, size(dV)...))
        end
    end

    for property in properties
        shape = size(cache[property][1])
        if shape == ()
            results[property] = cache[property]
        else
            results[property] = cat(cache[property]..., dims=1)
        end
    end
    merge!(model.results, results)

    return results
end

max_stars_repo_name: schinavro/taps

max_issues_repo_name: schinavro/taps

max_forks_repo_name: schinavro/taps


text:
"""
Convert raw `Neuropixels` data to gain-corrected voltages. The saved-channel id subset in data
will be used to get corresponding gain.

The full conversion with gain is:

``dataVolts = dataInt * fi2v / gain``

Note that each channel may have its own gain.

1. y: the saved data stream, excluding the last Sync channel.
2. meta: corresponding meta for y
"""
function gaincorrectnp(y,meta)
    yt = meta["from"][1:2]
    fi2v = meta["fi2v"]
    gain = meta["ro$(yt)gain"]
    nch = length(gain)
    savechids = meta["savedchans"]
    chids = yt == "ap" ? filter!(i->i<=nch,savechids) : filter!(i->i>nch,savechids).-nch

    cy=Array{Float64}(undef,size(y))
    for i in 1:size(y,1)
        cy[i,:] = y[i,:] * fi2v / gain[chids[i]]
    end
    return cy
end
"Logical mask for `Neuropixels` channels in probe shape"
function chmasknp(nch,chs,nrow,ncol)
    mask = falses(nch)
    mask[chs].=true
    mask = reshape(mask,ncol,nrow) # Neuropixel channel counting is from cols(left -> right), then rows(tip -> tail)
    permutedims(mask)
end
"Logical mask for `Neuropixels` reference channels in probe shape"
function refchmasknp(dataset;imecindex="0")
    nch = dataset["ap$imecindex"]["meta"]["acqApLfSy"][1]
    refch = dataset["ap$imecindex"]["meta"]["refch"]
    chmasknp(nch,refch,dataset["ap$imecindex"]["meta"]["nrowsaved"],dataset["ap$imecindex"]["meta"]["ncolsaved"])
end
"Logical mask for `Neuropixels` excluded channels in probe shape"
function exchmasknp(dataset;imecindex="0",datatype="lf",exch::Vector{Int}=Int[])
    nch = dataset["ap$imecindex"]["meta"]["acqApLfSy"][1]
    exchs = dataset[datatype]["meta"]["excludechans"]
    chmasknp(nch,union(exchs,exch),dataset["ap$imecindex"]["meta"]["nrowsaved"],dataset["ap$imecindex"]["meta"]["ncolsaved"])
end


text:
using RobotDynamics
using ForwardDiff
using LinearAlgebra

using RobotDynamics: dynamics, discrete_dynamics

function check_jacobians(model, z)
    t,dt, = z.t, z.dt
    xn = zeros(RD.state_dim(model))

    J0 = ForwardDiff.jacobian(z->RD.discrete_dynamics(model, z[1:4], z[5:5], t, dt), z.z)
    J = similar(J0)
    for sig in (RD.StaticReturn(), RD.InPlace()), diff in (RD.ForwardAD(), RD.FiniteDifference(), RD.UserDefined())
        atol = diff == RD.FiniteDifference() ? 1e-6 : 1e-10
        RD.jacobian!(sig, diff, model, J, xn, z)
        @test J ≈ J0 atol=atol
    end
end

cmodel = Cartpole()
x,u = rand(cmodel)
n,m = RD.dims(cmodel)
dt = 0.01
t = 0.0
z = RD.KnotPoint(x,u,t,dt)

# Check the Cartpole analytical Jacobian
J = zeros(n, n+m)
J0 = zero(J)
xdot = zeros(n)
RD.jacobian!(RD.StaticReturn(), RD.ForwardAD(), cmodel, J, xdot, z)
RD.jacobian!(RD.StaticReturn(), RD.UserDefined(), cmodel, J0, xdot, z)
@test J0 ≈ J

# Test Euler
model = RD.DiscretizedDynamics{RD.Euler}(cmodel)
xdot = RD.dynamics(cmodel, z)
@test discrete_dynamics(model, z) ≈ x + xdot * dt

check_jacobians(model, z)

# # Test RK2
# _k1 = dynamics(cmodel, x, u)*dt
# _k2 = dynamics(cmodel, x + _k1/2, u)*dt
# @test discrete_dynamics(model, z) ≈ x + _k2

# Test RK4
model = RD.DiscretizedDynamics{RD.RK4}(cmodel)
_k1 = dynamics(cmodel, x, u)*dt
_k2 = dynamics(cmodel, x + _k1/2, u)*dt
_k3 = dynamics(cmodel, x + _k2/2, u)*dt
_k4 = dynamics(cmodel, x + _k3, u)*dt

@test discrete_dynamics(model, z) ≈ x + (_k1 + 2*_k2 + 2*_k3 + _k4)/6
xn = zeros(n)
RD.discrete_dynamics!(model, xn, z)
@test xn ≈ x + (_k1 + 2*_k2 + 2*_k3 + _k4)/6
RD.discrete_dynamics!(model, xn, x, u, t, dt)
@test xn ≈ x + (_k1 + 2*_k2 + 2*_k3 + _k4)/6

check_jacobians(model, z)
J0 = ForwardDiff.jacobian(z->RD.discrete_dynamics(model, z[1:4], z[5:5], t, dt), z.z)
J = similar(J0)
RD.jacobian!(RD.InPlace(), RD.ForwardAD(), model, J, xn, z)
@test J ≈ J0
RD.jacobian!(RD.StaticReturn(), RD.UserDefined(), model, J, xn, z)
@test J ≈ J0

RD.jacobian!(RD.StaticReturn(), RD.UserDefined(), model, J, xn, z)
RD.jacobian!(RD.InPlace(), RD.UserDefined(), model, J, xn, z)
@test J ≈ J0

int1 = RD.RK4(cmodel)
int2 = copy(int1)
@test int1.k1 !== int2.k1
@test int1.k2 !== int2.k2
@test int1.A !== int2.A

# Test RK3 and jacobian
model = RD.DiscretizedDynamics{RD.RK3}(cmodel)
k1(x) = dynamics(cmodel, x,                   u, t       )*dt;
k2(x) = dynamics(cmodel, x + k1(x)/2,         u, t + dt/2)*dt;
k3(x) = dynamics(cmodel, x - k1(x) + 2*k2(x), u, t + dt  )*dt;
xnext(x) = x + (k1(x) + 4*k2(x) + k3(x))/6
k1_(u) = dynamics(cmodel, x,             u, t       )*dt;
k2_(u) = dynamics(cmodel, x + k1_(u)/2,      u, t + dt/2)*dt;
k3_(u) = dynamics(cmodel, x - k1_(u) + 2*k2_(u), u, t + dt  )*dt;
xnext_(u) = x + (k1_(u) + 4*k2_(u) + k3_(u))/6

# Make sure the test functions match
@test k1(x) == k1_(u)
@test k2(x) == k2_(u)
@test k3(x) == k3_(u)
@test xnext(x) == xnext_(u)

# Check actual implementation
@test xnext(x) ≈ RD.discrete_dynamics(model, z)
@test xnext_(u) ≈ RD.discrete_dynamics(model, z)
@test xnext(x) ≈ RD.discrete_dynamics(model, x, u, t, dt)

# Check Jacobian
A = ForwardDiff.jacobian(xnext, x)
B = ForwardDiff.jacobian(xnext_, u)
J0 = [A B]
J = zeros(n,n+m)
RD.jacobian!(RD.StaticReturn(), RD.UserDefined(), model, J, xn, z)
@test J ≈ J0
RD.jacobian!(RD.InPlace(), RD.UserDefined(), model, J, xn, z)
@test J ≈ J0

check_jacobians(model, z)


text:
#
# objects.jl -
#
# Management of Tcl objects.
#
# Tcl memory management is such that Tcl_Panic is called whenever memory
# allocation fails causing the program to abort.  It is therefore not necessary
# to check for the reference returned by object creation functions as it can
# never be NULL.  This simplifies the code (no needs to report such errors or
# throw exceptions and then catch them, etc.).
#

# Extend base methods for objects.

Base.string(obj::TclObj) = __objptr_to(String, __objptr(obj))

Base.show(io::IO, ::MIME"text/plain", obj::T) where {T<:TclObj} =
    print(io, "$T($(string(obj)))")

Base.show(io::IO, ::MIME"text/plain", obj::T) where {T<:TclObj{String}} =
    print(io, "$T(\"$(string(obj))\")")

# Provide short version for string interpolation in scripts (FIXME: also do
# that for other kind of objects).
Base.show(io::IO, obj::TclObj{<:Real}) =
    print(io, string(obj))

Base.show(io::IO, lst::T) where {T<:TclObj{List}} =
    print(io, llength(lst), "-element(s) $T(\"$(string(lst))\")")

# Finalizing the object is just a matter of decrementing its reference count.
__finalize(obj::TclObj) = Tcl_DecrRefCount(__objptr(obj))

"""
```julia
Tcl.getvalue(obj)
````

yields the value of a Tcl object.  The type of the result corresponds to
the internal representation of the object.

"""
getvalue(obj::TclObj{T}) where {T} = __objptr_to(T, __objptr(obj))

"""
```julia
TclObj(value)
```

yields a new instance of `TclObj` which stores a Tcl object pointer.  This
method may be overloaded to implement means to pass other kinds of arguments to
Tcl.  Tcl objects are used to efficiently build Tcl commands in the form of
`TclObj{List}`.

"""
TclObj(obj::TclObj) = obj

"""
```julia
AtomicType(x)
AtomicType(typeof(x))
```

yields either `Atomic()` of `NonAtomic()` indicating whether object `x` or
objects of type `typeof(x)` are atomic (that is always interpreted as a single
list element) or not.

If you decide to implement the *atomic* trait, then you must extend
the `AtomicType` method for your type as follows:

```julia
Tcl.AtomicType(::Type{<:MyType}) = Atomic() # or NonAtomic()
```

Atomic types are those of values that are considered as single list element.
The *atomic* trait indicates whether a value or an object is atomic or not;
Abstract type `AtomicType` has two concrete singleton sub-types: `Atomic` for
atomic objects and `NonAtomic` for other objects/values.  This trait is used
when concatenating objects or values in lists: atomic objects will be seen as a
single item while non atomic ones will be split in zero, one or several items.

See also [`Tcl.Trait`](@ref).

"""
AtomicType(::T) where {T} = AtomicType(T) # same as AtomicType(typeof(x))
AtomicType(::DataType) = error("unknown atomic type") # to break recursion

# Atomic types of generic objects.
AtomicType(::Type{<:Iterables}) = NonAtomic()
AtomicType(::Type{TclObj{T}}) where {T} = AtomicType(T)

"""
```julia
__objptr(arg)
```

yields a pointer to a Tcl object corresponding to argument `arg`.  This may
create a new (temporary) object so caller should make sure the reference count
of the result is correctly managed.  An exception may be thrown if the argument
cannot be converted into a Tcl object.

"""
__objptr(obj::TclObj) = obj.ptr

"""
```julia
__newobj(value)
```

yields a pointer to a temporary Tcl object with given value.  This method may
throw an exception.

""" __newobj

# Booleans.
#
#     Tcl boolean is in fact stored as an `Cint` despite the fact that it is
#     possible to create boolean objects, they are retrieved as `Cint` objects.

TclObj(value::Bool) = TclObj{Bool}(__newobj(value))

AtomicType(::Type{Bool}) = Atomic()

__objptr(value::Bool) = __newobj(value)

__newobj(value::Bool) = Tcl_NewBooleanObj(value)

# Integers.
#
#     For each integer type, we choose the Tcl integer which is large enough to
#     store a value of that type.  Small unsigned integers may be problematic,
#     but not so much as the smallest Tcl integer type is `Cint` which is at
#     least 32 bits.

for Tj in (Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64)
    (Tc, f) = (sizeof(Tj) ≤ sizeof(Cint) ? (Cint, :Tcl_NewIntObj) :
               sizeof(Tj) ≤ sizeof(Clong) ? (Clong, :Tcl_NewLongObj) :
               (WideInt, :Tcl_NewWideIntObj))
    @eval begin

        TclObj(value::$Tj) = TclObj{$Tc}(__newobj(value))

        AtomicType(::Type{$Tj}) = Atomic()

        __objptr(value::$Tj) = __newobj(value)

        __newobj(value::$Tj) = $f(value)

    end

end

# Floats.
#
#     All floating point types, rationals and irrationals yield `Cdouble` Tcl
#     objects.

TclObj(value::FloatingPoint) = TclObj{Cdouble}(__newobj(value))

AtomicType(::Type{<:FloatingPoint}) = Atomic()

__objptr(value::FloatingPoint) = __newobj(value)

__newobj(value::Cdouble) = Tcl_NewDoubleObj(value)
__newobj(value::FloatingPoint) = __newobj(convert(Cdouble, value))

# Strings.
#
#     Julia strings and symbols are assumed to be Tcl strings.  Julia
#     characters are assumed to Tcl strings of length 1.  Strings may be split
#     in several arguments (hence they are non-atomic) while characters and
#     symbols are atomic.
#
#     There are two alternatives to create Tcl string objects:
#     `Tcl_NewStringObj` or `Tcl_NewUnicodeObj`.  After some testings (see my
#     notes), the following works correctly.  To build a Tcl object from a
#     Julia string, use `Ptr{UInt8}` instead of `Cstring` and provide the
#     number of bytes with `sizeof(str)`.

TclObj(x::Union{Char,Symbol,AbstractString}) = TclObj{String}(__newobj(x))

AtomicType(::Type{<:Union{Char,Symbol}}) = Atomic()
AtomicType(::Type{<:AbstractString}) = NonAtomic()

__objptr(x::Union{Char,Symbol,AbstractString}) = __newobj(x)

__newobj(x::Union{Char,Symbol}) = __newobj(string(x))
__newobj(str::AbstractString) = Tcl_NewStringObj(str)

__newstringobj(ptr::Ptr{T}, nbytes::Integer) where {T<:Byte} =
    Tcl_NewStringObj(ptr, nbytes)

# Nothing and nothing.
#
#     Nothing is loosely aliased to "" in Tcl.  Could also be an empty list.

TclObj(x::Nothing) = TclObj{Nothing}(__newobj(x))

AtomicType(::Type{Nothing}) = Atomic()

__objptr(x::Nothing) = __newobj(x)

__newobj(::Nothing) = __newobj("")

@static if false
# Unsupported objects.
#
#     These fallbacks are only meet for unsupported types.

TclObj(::T) where T = __unsupported_object_type(T)

AtomicType(::Type{T}) where T = __unsupported_object_type(T)

__objptr(::T) where T = __unsupported_object_type(T)

__newobj(::T) where T = __unsupported_object_type(T)

@noinline __unsupported_object_type(::Type{T}) where T =
    Tcl.error("making a Tcl object for type $T is not supported")

end

#------------------------------------------------------------------------------

"""
```julia
__getobjtype(arg)
```

yields the address of a Tcl object type (`Tcl_ObjType*` in C).  Argument can be
a managed Tcl object or the address of a Tcl object (must not be `C_NULL`).

"""
__getobjtype(obj::TclObj) = __getobjtype(__objptr(obj))
__getobjtype(objptr::TclObjPtr) =
    unsafe_load(Ptr{TclObjTypePtr}(objptr + __offset_of_type))

const __bool_type    = Ref{Ptr{Cvoid}}(0)
const __int_type     = Ref{Ptr{Cvoid}}(0)
const __wideint_type = Ref{Ptr{Cvoid}}(0)
const __double_type  = Ref{Ptr{Cvoid}}(0)
const __list_type    = Ref{Ptr{Cvoid}}(0)
const __string_type  = Ref{Ptr{Cvoid}}(0)
const KnownTypes = Union{Nothing,Bool,Cint,WideInt,Cdouble,String,List}
function __init_types(bynames::Bool = false)
    if bynames
        __int_type[]     = Tcl_GetObjType("int")
        __wideint_type[] = Tcl_GetObjType("wideint")
        if __wideint_type[] == C_NULL
            __wideint_type[] = __int_type[]
        end
        __double_type[]  = Tcl_GetObjType("double")
        __string_type[]  = C_NULL
        __list_type[]    = Tcl_GetObjType("list")
        __bool_type[] = __int_type[]
    else
        int_obj = TclObj(Cint(0))
        wideint_obj = TclObj(WideInt(0))
        double_obj = TclObj(Cdouble(0))
        string_obj = TclObj("")
        list_obj = list(int_obj, wideint_obj)
        bool_obj = TclObj(true)
        __int_type[]     = __getobjtype(int_obj)
        __wideint_type[] = __getobjtype(wideint_obj)
        __double_type[]  = __getobjtype(double_obj)
        __string_type[]  = __getobjtype(string_obj)
        __list_type[]    = __getobjtype(list_obj)
        __bool_type[]    = __getobjtype(bool_obj)
    end
end

__illegal_null_object_pointer() =
    Tcl.error("illegal NULL Tcl object pointer")

__illegal_null_string_pointer() =
    Tcl.error("illegal NULL C-string pointer")

"""
```julia
__ptr_to(T::DataType, strptr::Cstring)
````

converts a C-string (for instance, returned by a C function) into a Julia value
of type `T`.  If `T` is `Any` or `String`, a Julia string is returned, if `T`
is `TclObj` or `TclObj{String}` a managed Tcl object with a string value is
returned.

See also: [`string`](@ref), [`__objptr_to`](@ref).

"""
__ptr_to(::Type{String}, strptr::Cstring) =
    # In principle, `unsafe_string` will refuse to convert NULL to string.  So
    # no checks here.
    unsafe_string(strptr)

__ptr_to(::Type{Any}, strptr::Cstring) = __ptr_to(String, strptr::Cstring)

__ptr_to(::Type{<:Union{TclObj,TclObj{String}}}, strptr::Cstring) =
    TclObj{String}(__newobj(__ptr_to(String, strptr)))

"""

```julia
__objptr_to(T::DataType, objptr::Ptr{Cvoid})
````

converts the Tcl object at address `objptr` into a value of type `T`.
See [`Tcl.getvar`](@ref) for details about how `T` is interpreted.

If reference `intptr` to Tcl interpreter is non NULL, it is used to retrieve an
error message if the conversion fails.

See also: [`Tcl.getvar`](@ref), [`Tcl.getvalue`](@ref).

"""
@inline __objptr_to(::Type{Any}, objptr::Ptr{Cvoid}) =
    __objptr_to(__objtype(objptr), objptr)

@inline __objptr_to(::Type{TclObj}, objptr::Ptr{Cvoid}) =
    TclObj{__objtype(objptr)}(objptr)

@inline function __objptr_to(::Type{String}, objptr::TclObjPtr) :: String
    ptr, len = Tcl_GetStringFromObj(objptr)
    if ptr == C_NULL
        Tcl.error("failed to retrieve string representation of Tcl object")
    end
    return unsafe_string(ptr, len)
end

@inline function __objptr_to(::Type{Char}, objptr::Ptr{Cvoid}) :: Char
    ptr, len = Tcl_GetStringFromObj(objptr)
    if ptr == C_NULL
        Tcl.error("failed to retrieve string representation of Tcl object")
    end
    if len != 1
        Tcl.error("failed to convert Tcl object to a single character")
    end
    return unsafe_string(ptr, 1)[1]
end

@inline function __objptr_to(::Type{Bool}, objptr::TclObjPtr) :: Bool
    status, value = Tcl_GetBooleanFromObj(__intptr(), objptr)
    if status != TCL_OK
        __contextual_error("failed to convert Tcl object to a boolean")
    end
    return value
end

# Find closest approximation for converting an object to an integer.
for Tj in (Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64)
    msg = "failed to convert Tcl object to an integer ($Tj)"
    for pass in 1:2,
        (f,Tc) in ((:Tcl_GetIntFromObj,     Cint),
                   (:Tcl_GetLongFromObj,    Clong),
                   (:Tcl_GetWideintFromObj, WideInt))
        if (pass == 1 && Tj == Tc) || (pass == 2 && sizeof(Tj) ≤ sizeof(Tc))
            # Exact match found or size large enough.
            result = (Tj == Tc ? :value : :(convert(Tj, value)))
            @eval @inline function __objptr_to(::Type{$Tj},
                                               objptr::TclObjPtr) :: $Tj
                status, value = $f(__intptr(), objptr)
                status == TCL_OK || __contextual_error($msg)
                return $result
            end
            break
        end
    end
end

@inline function __objptr_to(::Type{Cdouble}, objptr::TclObjPtr) :: Cdouble
    status, value = Tcl_GetDoubleFromObj(__intptr(), objptr)
    if status != TCL_OK
        __contextual_error("failed to convert Tcl object to a float")
    end
    return value
end

@inline function __objptr_to(::Type{T},
                             objptr::TclObjPtr) :: T where {T<:AbstractFloat}
    return convert(T, __objptr_to(Cdouble, objptr))
end

"""
```julia
__objtype(objptr::Ptr{Cvoid})
````

yields the equivalent Julia type of the Tcl object at address `objptr`.

This function should be considered as *private*.

See also: [`Tcl.getvalue`](@ref), [`Tcl.getresult`](@ref).

"""
@inline function __objtype(objptr::Ptr{Cvoid})
    # `wideint` must be checked before `int` because they may be the same
    # on some machines
    typeptr = __getobjtype(objptr)
    if typeptr == __wideint_type[]
        return WideInt
    elseif typeptr == __double_type[]
        return Cdouble
    elseif typeptr == __list_type[]
        return List
    elseif typeptr == __int_type[]
        return Cint
    elseif typeptr == __bool_type[]
        return Cint
    else
        return String
    end
end


text:
#!/usr/bin/env julia

function packagelt(a::String, b::String)
    a == "julia" && b != "julia" && return true
    a != "julia" && b == "julia" && return false
    return lowercase(a) < lowercase(b)
end

≲(v::VersionNumber, t::NTuple{0,Int}) = true
≲(v::VersionNumber, t::NTuple{1,Int}) = v.major ≤ t[1]
≲(v::VersionNumber, t::NTuple{2,Int}) = v.major < t[1] ||
                                        v.major ≤ t[1] && v.minor ≤ t[2]
≲(v::VersionNumber, t::NTuple{3,Int}) = v.major < t[1] ||
                                        v.major ≤ t[1] && v.minor < t[2] ||
                                        v.major ≤ t[1] && v.minor ≤ t[2] && v.patch ≤ t[3]

≲(t::NTuple{0,Int}, v::VersionNumber) = true
≲(t::NTuple{1,Int}, v::VersionNumber) = t[1] ≤ v.major
≲(t::NTuple{2,Int}, v::VersionNumber) = t[1] < v.major ||
                                        t[1] ≤ v.major && t[2] ≤ v.minor
≲(t::NTuple{3,Int}, v::VersionNumber) = t[1] < v.major ||
                                        t[1] ≤ v.major && t[2] < v.minor ||
                                        t[1] ≤ v.major && t[2] ≤ v.minor && t[3] ≤ v.patch

function compress_versions(inc::Vector{VersionNumber}, from::Vector{VersionNumber})
    issorted(inc) || (inc = sort(inc))
    exc = sort!(setdiff(from, inc))
    pairs = []
    if isempty(exc)
        lo, hi = first(inc), last(inc)
        push!(pairs, (lo.major, lo.minor) => (hi.major, hi.minor))
    else
        for v in inc
            t = (v.major, v.minor)
            if any(t ≲ w ≲ t for w in exc)
                t = (v.major, v.minor, v.patch)
            end
            if isempty(pairs) || any(pairs[end][1] ≲ w ≲ t for w in exc)
                push!(pairs, t => t) # need a new interval
            else
                pairs[end] = pairs[end][1] => t # can be merged with last
            end
        end
    end
    @assert all(any(p[1] ≲ v ≲ p[2] for p ∈ pairs) for v ∈ inc)
    @assert all(!any(p[1] ≲ v ≲ p[2] for p ∈ pairs) for v ∈ exc)
    return pairs
end
compress_versions(f::Function, from::Vector{VersionNumber}) =
    compress_versions(filter(f, from), from)
compress_versions(vi::VersionInterval, from::Vector{VersionNumber}) =
    compress_versions(v->v in vi, from)
compress_versions(inc, from) = compress_versions(inc, collect(from))

versions_string(p::Pair) = versions_string(p...)
versions_string(a::Tuple{}, b::Tuple{}) = "*"
versions_string(a::NTuple{m,Int}, b::NTuple{n,Int}) where {m,n} =
    a == b ? join(a, '.') : "$(join(a, '.'))-$(join(b, '.'))"

versions_repr(x) = repr(versions_string(x))
versions_repr(v::Vector) = length(v) == 1 ? repr(versions_string(v[1])) :
    "[" * join(map(repr∘versions_string, v), ", ") * "]"


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

# Parametric singleton type representing a given string encoding via its symbol parameter

module Encodings

import Base: show, print, convert
export encoding, encodings_list, Encoding, @enc_str

struct Encoding{enc} end

Encoding(s) = Encoding{Symbol(s)}()
macro enc_str(s)
    :(Encoding{$(Expr(:quote, Symbol(s)))}())
end

convert(::Type{T}, ::Encoding{enc}) where {T<:AbstractString, enc} = string(enc)
Base.String(::Encoding{enc}) where {enc} = string(enc)

show(io::IO, ::Encoding{enc}) where {enc} = print(io, string(enc), " string encoding")
print(io::IO, ::Encoding{enc}) where {enc} = print(io, enc)

## Get the encoding used by a string type
encoding(::Type{String})  = enc"UTF-8"

encodings_list = ["1026", "1046", "1047", "10646-1:1993", "10646-1:1993/UCS4",
                  "437", "500", "500V1", "850", "851", "852", "855", "856", "857",
                  "860", "861", "862", "863", "864", "865", "866", "866NAV", "869",
                  "874", "8859_1", "8859_2", "8859_3", "8859_4", "8859_5", "8859_6",
                  "8859_7", "8859_8", "8859_9", "904", "ANSI_X3.110", "ANSI_X3.110-1983",
                  "ANSI_X3.4", "ANSI_X3.4-1968", "ANSI_X3.4-1986", "ARABIC", "ARABIC7",
                  "ARMSCII-8", "ASCII", "ASMO_449", "ASMO-708", "BALTIC", "BIG-5",
                  "BIG-FIVE", "big5", "BIG5", "big5-hkscs", "BIG5-HKSCS", "BIG5-HKSCS:1999",
                  "BIG5-HKSCS:2001", "BIG5-HKSCS:2004", "BIG5-HKSCS:2008", "big5hkscs",
                  "BIG5HKSCS", "BIGFIVE", "BRF", "BS_4730", "C99", "CA", "CHINESE",
                  "CN", "CN-BIG5", "CN-GB", "CN-GB-ISOIR165", "CP-AR", "CP-GR",
                  "CP-HU", "CP-IS", "CP037", "CP038", "CP10007", "CP1004", "CP1008",
                  "cp1025", "CP1025", "CP1026", "CP1046", "CP1047", "CP1070", "CP1079",
                  "CP1081", "CP1084", "CP1089", "CP1097", "CP1112", "CP1122", "CP1123",
                  "CP1124", "CP1125", "CP1129", "CP1130", "CP1131", "CP1132", "CP1133",
                  "CP1137", "CP1140", "CP1141", "CP1142", "CP1143", "CP1144", "CP1145",
                  "CP1146", "CP1147", "CP1148", "CP1149", "CP1153", "CP1154", "CP1155",
                  "CP1156", "CP1157", "CP1158", "CP1160", "CP1161", "CP1162", "CP1163",
                  "CP1164", "CP1166", "CP1167", "CP1200", "CP12000", "CP12001",
                  "CP1201", "CP1250", "CP1251", "CP1252", "CP1253", "CP1254", "CP1255",
                  "CP1256", "CP1257", "CP1258", "CP12712", "CP1282", "CP1361",
                  "CP1364", "CP1371", "CP1388", "CP1390", "CP1399", "CP154", "CP16804",
                  "CP273", "CP274", "CP275", "CP278", "CP280", "CP281", "CP282",
                  "CP284", "CP285", "CP290", "CP297", "CP367", "CP420", "CP423",
                  "CP424", "CP437", "CP4517", "CP4899", "CP4909", "CP4971", "CP500",
                  "CP50221", "CP51932", "CP5347", "CP65001", "CP737", "CP770",
                  "CP771", "CP772", "CP773", "CP774", "CP775", "CP803", "CP813",
                  "CP819", "CP850", "CP851", "CP852", "CP853", "CP855", "CP856",
                  "CP857", "CP858", "CP860", "CP861", "CP862", "CP863", "CP864",
                  "CP865", "cp866", "CP866", "CP866NAV", "CP868", "CP869", "CP870",
                  "CP871", "CP874", "cp875", "CP875", "CP880", "CP891", "CP901",
                  "CP902", "CP903", "CP9030", "CP904", "CP905", "CP9066", "CP912",
                  "CP915", "CP916", "CP918", "CP920", "CP921", "CP922", "CP930",
                  "CP932", "CP933", "CP935", "CP936", "CP937", "CP939", "CP9448",
                  "CP949", "CP950", "CPIBM861", "CSA_T500", "CSA_T500-1983", "CSA_Z243.4-1985-1",
                  "CSA_Z243.4-1985-2", "CSA_Z243.419851", "CSA_Z243.419852", "CSA7-1",
                  "CSA7-2", "CSASCII", "CSBIG5", "CSDECMCS", "CSEBCDICATDE", "CSEBCDICATDEA",
                  "CSEBCDICCAFR", "CSEBCDICDKNO", "CSEBCDICDKNOA", "CSEBCDICES",
                  "CSEBCDICESA", "CSEBCDICESS", "CSEBCDICFISE", "CSEBCDICFISEA",
                  "CSEBCDICFR", "CSEBCDICIT", "CSEBCDICPT", "CSEBCDICUK", "CSEBCDICUS",
                  "CSEUCKR", "CSEUCPKDFMTJAPANESE", "CSEUCTW", "CSGB2312", "CSHALFWIDTHKATAKANA",
                  "CSHPROMAN8", "CSIBM037", "CSIBM038", "CSIBM1008", "CSIBM1025",
                  "CSIBM1026", "CSIBM1097", "CSIBM1112", "CSIBM1122", "CSIBM1123",
                  "CSIBM1124", "CSIBM1129", "CSIBM1130", "CSIBM1132", "CSIBM1133",
                  "CSIBM1137", "CSIBM1140", "CSIBM1141", "CSIBM1142", "CSIBM1143",
                  "CSIBM1144", "CSIBM1145", "CSIBM1146", "CSIBM1147", "CSIBM1148",
                  "CSIBM1149", "CSIBM1153", "CSIBM1154", "CSIBM1155", "CSIBM1156",
                  "CSIBM1157", "CSIBM1158", "CSIBM1160", "CSIBM1161", "CSIBM11621162",
                  "CSIBM1163", "CSIBM1164", "CSIBM1166", "CSIBM1167", "CSIBM12712",
                  "CSIBM1364", "CSIBM1371", "CSIBM1388", "CSIBM1390", "CSIBM1399",
                  "CSIBM16804", "CSIBM273", "CSIBM274", "CSIBM275", "CSIBM277",
                  "CSIBM278", "CSIBM280", "CSIBM281", "CSIBM284", "CSIBM285", "CSIBM290",
                  "CSIBM297", "CSIBM420", "CSIBM423", "CSIBM424", "CSIBM4517",
                  "CSIBM4899", "CSIBM4909", "CSIBM4971", "CSIBM500", "CSIBM5347",
                  "CSIBM803", "CSIBM851", "CSIBM855", "CSIBM856", "CSIBM857", "CSIBM860",
                  "CSIBM861", "CSIBM863", "CSIBM864", "CSIBM865", "CSIBM866", "CSIBM868",
                  "CSIBM869", "CSIBM870", "CSIBM871", "CSIBM880", "CSIBM891", "CSIBM901",
                  "CSIBM902", "CSIBM903", "CSIBM9030", "CSIBM904", "CSIBM905",
                  "CSIBM9066", "CSIBM918", "CSIBM921", "CSIBM922", "CSIBM930",
                  "CSIBM932", "CSIBM933", "CSIBM935", "CSIBM937", "CSIBM939", "CSIBM943",
                  "CSIBM9448", "CSISO10367BOX", "CSISO103T618BIT", "CSISO10SWEDISH",
                  "CSISO111ECMACYRILLIC", "CSISO11SWEDISHFORNAMES", "CSISO121CANADIAN1",
                  "CSISO122CANADIAN2", "CSISO139CSN369103", "CSISO141JUSIB1002",
                  "CSISO143IECP271", "CSISO14JISC6220RO", "CSISO150", "CSISO150GREEKCCITT",
                  "CSISO151CUBA", "CSISO153GOST1976874", "CSISO159JISX02121990",
                  "CSISO15ITALIAN", "CSISO16PORTUGESE", "CSISO17SPANISH", "CSISO18GREEK7OLD",
                  "CSISO19LATINGREEK", "CSISO2022CN", "csISO2022JP", "CSISO2022JP",
                  "CSISO2022JP2", "CSISO2022KR", "CSISO2033", "CSISO21GERMAN",
                  "CSISO25FRENCH", "CSISO27LATINGREEK1", "CSISO49INIS", "CSISO4UNITEDKINGDOM",
                  "CSISO50INIS8", "CSISO51INISCYRILLIC", "CSISO5427CYRILLIC", "CSISO5427CYRILLIC1981",
                  "CSISO5428GREEK", "CSISO57GB1988", "CSISO58GB1988", "CSISO58GB231280",
                  "CSISO60DANISHNORWEGIAN", "CSISO60NORWEGIAN1", "CSISO61NORWEGIAN2",
                  "CSISO646DANISH", "CSISO69FRENCH", "CSISO84PORTUGUESE2", "CSISO85SPANISH2",
                  "CSISO86HUNGARIAN", "CSISO87JISX0208", "CSISO88GREEK7", "CSISO89ASMO449",
                  "CSISO90", "CSISO92JISC62991984B", "CSISO99NAPLPS", "CSISOLATIN1",
                  "CSISOLATIN2", "CSISOLATIN3", "CSISOLATIN4", "CSISOLATIN5", "CSISOLATIN6",
                  "CSISOLATINARABIC", "CSISOLATINCYRILLIC", "CSISOLATINGREEK",
                  "CSISOLATINHEBREW", "CSKOI8R", "CSKSC56011987", "CSKSC5636",
                  "CSKZ1048", "CSMACINTOSH", "CSN_369103", "CSNATSDANO", "CSNATSSEFI",
                  "CSPC775BALTIC", "CSPC850MULTILINGUAL", "CSPC862LATINHEBREW",
                  "CSPC8CODEPAGE437", "CSPCP852", "CSPTCP154", "CSSHIFTJIS", "CSUCS4",
                  "CSUNICODE", "CSUNICODE11", "CSUNICODE11UTF7", "CSVISCII", "CSWINDOWS31J",
                  "CUBA", "CWI", "CWI-2", "CYRILLIC", "CYRILLIC-ASIAN", "DE", "DEC",
                  "DEC-MCS", "DECMCS", "DIN_66003", "DK", "DOS-720", "DOS-862",
                  "DS_2089", "DS2089", "E13B", "EBCDIC-AT-DE", "EBCDIC-AT-DE-A",
                  "EBCDIC-BE", "EBCDIC-BR", "EBCDIC-CA-FR", "EBCDIC-CP-AR1", "EBCDIC-CP-AR2",
                  "EBCDIC-CP-BE", "EBCDIC-CP-CA", "EBCDIC-CP-CH", "EBCDIC-CP-DK",
                  "EBCDIC-CP-ES", "EBCDIC-CP-FI", "EBCDIC-CP-FR", "EBCDIC-CP-GB",
                  "EBCDIC-CP-GR", "EBCDIC-CP-HE", "EBCDIC-CP-IS", "EBCDIC-CP-IT",
                  "EBCDIC-CP-NL", "EBCDIC-CP-NO", "EBCDIC-CP-ROECE", "EBCDIC-CP-SE",
                  "EBCDIC-CP-TR", "EBCDIC-CP-US", "EBCDIC-CP-WT", "EBCDIC-CP-YU",
                  "EBCDIC-CYRILLIC", "EBCDIC-DK-NO", "EBCDIC-DK-NO-A", "EBCDIC-ES",
                  "EBCDIC-ES-A", "EBCDIC-ES-S", "EBCDIC-FI-SE", "EBCDIC-FI-SE-A",
                  "EBCDIC-FR", "EBCDIC-GREEK", "EBCDIC-INT", "EBCDIC-INT1", "EBCDIC-IS-FRISS",
                  "EBCDIC-IT", "EBCDIC-JP-E", "EBCDIC-JP-KANA", "EBCDIC-PT", "EBCDIC-UK",
                  "EBCDIC-US", "EBCDICATDE", "EBCDICATDEA", "EBCDICCAFR", "EBCDICDKNO",
                  "EBCDICDKNOA", "EBCDICES", "EBCDICESA", "EBCDICESS", "EBCDICFISE",
                  "EBCDICFISEA", "EBCDICFR", "EBCDICISFRISS", "EBCDICIT", "EBCDICPT",
                  "EBCDICUK", "EBCDICUS", "ECMA-114", "ECMA-118", "ECMA-128", "ECMA-CYRILLIC",
                  "ECMACYRILLIC", "ELOT_928", "ES", "ES2", "EUC-CN", "EUC-JISX0213",
                  "euc-jp", "EUC-JP", "EUC-JP-MS", "euc-kr", "EUC-KR", "EUC-TW",
                  "EUCCN", "EUCJP", "EUCJP-MS", "EUCJP-OPEN", "EUCJP-WIN", "EUCKR",
                  "EUCTW", "EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", "FI",
                  "FR", "GB", "GB_1988-80", "GB_198880", "GB_2312-80", "GB13000",
                  "GB18030", "gb2312", "GB2312", "GBK", "GEORGIAN-ACADEMY", "GEORGIAN-PS",
                  "GOST_19768", "GOST_19768-74", "GOST_1976874", "GREEK", "GREEK-CCITT",
                  "GREEK7", "GREEK7-OLD", "GREEK7OLD", "GREEK8", "GREEKCCITT",
                  "HEBREW", "HP-GREEK8", "HP-ROMAN8", "HP-ROMAN9", "HP-THAI8",
                  "HP-TURKISH8", "HPGREEK8", "HPROMAN8", "HPROMAN9", "HPTHAI8",
                  "HPTURKISH8", "HU", "HZ", "hz-gb-2312", "HZ-GB-2312", "IBM-1008",
                  "IBM-1025", "IBM-1046", "IBM-1047", "IBM-1097", "IBM-1112", "IBM-1122",
                  "IBM-1123", "IBM-1124", "IBM-1129", "IBM-1130", "IBM-1132", "IBM-1133",
                  "IBM-1137", "IBM-1140", "IBM-1141", "IBM-1142", "IBM-1143", "IBM-1144",
                  "IBM-1145", "IBM-1146", "IBM-1147", "IBM-1148", "IBM-1149", "IBM-1153",
                  "IBM-1154", "IBM-1155", "IBM-1156", "IBM-1157", "IBM-1158", "IBM-1160",
                  "IBM-1161", "IBM-1162", "IBM-1163", "IBM-1164", "IBM-1166", "IBM-1167",
                  "IBM-12712", "IBM-1364", "IBM-1371", "IBM-1388", "IBM-1390",
                  "IBM-1399", "IBM-16804", "IBM-4517", "IBM-4899", "IBM-4909",
                  "IBM-4971", "IBM-5347", "IBM-803", "IBM-856", "IBM-901", "IBM-902",
                  "IBM-9030", "IBM-9066", "IBM-921", "IBM-922", "IBM-930", "IBM-932",
                  "IBM-933", "IBM-935", "IBM-937", "IBM-939", "IBM-943", "IBM-9448",
                  "IBM-CP1133", "IBM-Thai", "IBM00858", "IBM00924", "IBM01047",
                  "IBM01140", "IBM01141", "IBM01142", "IBM01143", "IBM01144", "IBM01145",
                  "IBM01146", "IBM01147", "IBM01148", "IBM01149", "IBM037", "IBM038",
                  "IBM1004", "IBM1008", "IBM1025", "IBM1026", "IBM1046", "IBM1047",
                  "IBM1089", "IBM1097", "IBM1112", "IBM1122", "IBM1123", "IBM1124",
                  "IBM1129", "IBM1130", "IBM1132", "IBM1133", "IBM1137", "IBM1140",
                  "IBM1141", "IBM1142", "IBM1143", "IBM1144", "IBM1145", "IBM1146",
                  "IBM1147", "IBM1148", "IBM1149", "IBM1153", "IBM1154", "IBM1155",
                  "IBM1156", "IBM1157", "IBM1158", "IBM1160", "IBM1161", "IBM1162",
                  "IBM1163", "IBM1164", "IBM1166", "IBM1167", "IBM12712", "IBM1364",
                  "IBM1371", "IBM1388", "IBM1390", "IBM1399", "IBM16804", "IBM256",
                  "IBM273", "IBM274", "IBM275", "IBM277", "IBM278", "IBM280", "IBM281",
                  "IBM284", "IBM285", "IBM290", "IBM297", "IBM367", "IBM420", "IBM423",
                  "IBM424", "IBM437", "IBM4517", "IBM4899", "IBM4909", "IBM4971",
                  "IBM500", "IBM5347", "ibm737", "ibm775", "IBM775", "IBM803",
                  "IBM813", "IBM819", "IBM848", "ibm850", "IBM850", "IBM851", "ibm852",
                  "IBM852", "IBM855", "IBM856", "ibm857", "IBM857", "IBM860", "ibm861",
                  "IBM861", "IBM862", "IBM863", "IBM864", "IBM865", "IBM866", "IBM866NAV",
                  "IBM868", "ibm869", "IBM869", "IBM870", "IBM871", "IBM874", "IBM875",
                  "IBM880", "IBM891", "IBM901", "IBM902", "IBM903", "IBM9030",
                  "IBM904", "IBM905", "IBM9066", "IBM912", "IBM915", "IBM916",
                  "IBM918", "IBM920", "IBM921", "IBM922", "IBM930", "IBM932", "IBM933",
                  "IBM935", "IBM937", "IBM939", "IBM943", "IBM9448", "IEC_P27-1",
                  "IEC_P271", "INIS", "INIS-8", "INIS-CYRILLIC", "INIS8", "INISCYRILLIC",
                  "ISIRI-3342", "ISIRI3342", "ISO_10367-BOX", "ISO_10367BOX", "ISO_11548-1",
                  "ISO_2033", "ISO_2033-1983", "ISO_5427", "ISO_5427-EXT", "ISO_5427:1981",
                  "ISO_5427EXT", "ISO_5428", "ISO_5428:1980", "ISO_646.IRV:1991",
                  "ISO_6937", "ISO_6937-2", "ISO_6937-2:1983", "ISO_6937:1992",
                  "ISO_69372", "iso_8859_1", "iso_8859_13", "iso_8859_15", "iso_8859_2",
                  "iso_8859_3", "iso_8859_4", "iso_8859_5", "iso_8859_6", "iso_8859_7",
                  "iso_8859_8", "iso_8859_8-i", "iso_8859_9", "iso_8859-1", "ISO_8859-1",
                  "ISO_8859-1:1987", "ISO_8859-10", "ISO_8859-10:1992", "ISO_8859-11",
                  "iso_8859-13", "ISO_8859-13", "ISO_8859-14", "ISO_8859-14:1998",
                  "iso_8859-15", "ISO_8859-15", "ISO_8859-15:1998", "ISO_8859-16",
                  "ISO_8859-16:2001", "iso_8859-2", "ISO_8859-2", "ISO_8859-2:1987",
                  "iso_8859-3", "ISO_8859-3", "ISO_8859-3:1988", "iso_8859-4",
                  "ISO_8859-4", "ISO_8859-4:1988", "iso_8859-5", "ISO_8859-5",
                  "ISO_8859-5:1988", "iso_8859-6", "ISO_8859-6", "ISO_8859-6:1987",
                  "iso_8859-7", "ISO_8859-7", "ISO_8859-7:1987", "ISO_8859-7:2003",
                  "iso_8859-8", "ISO_8859-8", "iso_8859-8-i", "ISO_8859-8:1988",
                  "iso_8859-9", "ISO_8859-9", "ISO_8859-9:1989", "ISO_8859-9E",
                  "ISO_9036", "ISO-10646", "ISO-10646-UCS-2", "ISO-10646-UCS-4",
                  "ISO-10646/UCS2", "ISO-10646/UCS4", "ISO-10646/UTF-8", "ISO-10646/UTF8",
                  "ISO-2022-CN", "ISO-2022-CN-EXT", "iso-2022-jp", "ISO-2022-JP",
                  "ISO-2022-JP-1", "ISO-2022-JP-2", "ISO-2022-JP-3", "ISO-2022-JP-MS",
                  "iso-2022-kr", "ISO-2022-KR", "iso-8859-1", "ISO-8859-1", "ISO-8859-10",
                  "ISO-8859-11", "iso-8859-13", "ISO-8859-13", "ISO-8859-14", "iso-8859-15",
                  "ISO-8859-15", "ISO-8859-16", "iso-8859-2", "ISO-8859-2", "iso-8859-3",
                  "ISO-8859-3", "iso-8859-4", "ISO-8859-4", "iso-8859-5", "ISO-8859-5",
                  "iso-8859-6", "ISO-8859-6", "iso-8859-7", "ISO-8859-7", "iso-8859-8",
                  "ISO-8859-8", "iso-8859-8-i", "iso-8859-9", "ISO-8859-9", "ISO-8859-9E",
                  "ISO-CELTIC", "ISO-IR-10", "ISO-IR-100", "ISO-IR-101", "ISO-IR-103",
                  "ISO-IR-109", "ISO-IR-11", "ISO-IR-110", "ISO-IR-111", "ISO-IR-121",
                  "ISO-IR-122", "ISO-IR-126", "ISO-IR-127", "ISO-IR-138", "ISO-IR-139",
                  "ISO-IR-14", "ISO-IR-141", "ISO-IR-143", "ISO-IR-144", "ISO-IR-148",
                  "ISO-IR-149", "ISO-IR-15", "ISO-IR-150", "ISO-IR-151", "ISO-IR-153",
                  "ISO-IR-155", "ISO-IR-156", "ISO-IR-157", "ISO-IR-159", "ISO-IR-16",
                  "ISO-IR-165", "ISO-IR-166", "ISO-IR-17", "ISO-IR-179", "ISO-IR-18",
                  "ISO-IR-19", "ISO-IR-193", "ISO-IR-197", "ISO-IR-199", "ISO-IR-203",
                  "ISO-IR-209", "ISO-IR-21", "ISO-IR-226", "ISO-IR-25", "ISO-IR-27",
                  "ISO-IR-37", "ISO-IR-4", "ISO-IR-49", "ISO-IR-50", "ISO-IR-51",
                  "ISO-IR-54", "ISO-IR-55", "ISO-IR-57", "ISO-IR-58", "ISO-IR-6",
                  "ISO-IR-60", "ISO-IR-61", "ISO-IR-69", "ISO-IR-8-1", "ISO-IR-84",
                  "ISO-IR-85", "ISO-IR-86", "ISO-IR-87", "ISO-IR-88", "ISO-IR-89",
                  "ISO-IR-9-1", "ISO-IR-90", "ISO-IR-92", "ISO-IR-98", "ISO-IR-99",
                  "ISO/TR_11548-1", "ISO11548-1", "ISO2022-JP", "ISO2022-JP-MS",
                  "iso2022-kr", "ISO2022CN", "ISO2022CNEXT", "ISO2022JP", "ISO2022JP2",
                  "ISO2022KR", "ISO646-CA", "ISO646-CA2", "ISO646-CN", "ISO646-CU",
                  "ISO646-DE", "ISO646-DK", "ISO646-ES", "ISO646-ES2", "ISO646-FI",
                  "ISO646-FR", "ISO646-FR1", "ISO646-GB", "ISO646-HU", "ISO646-IT",
                  "ISO646-JP", "ISO646-JP-OCR-B", "ISO646-KR", "ISO646-NO", "ISO646-NO2",
                  "ISO646-PT", "ISO646-PT2", "ISO646-SE", "ISO646-SE2", "ISO646-US",
                  "ISO646-YU", "ISO6937", "iso8859-1", "ISO8859-1", "ISO8859-10",
                  "ISO8859-11", "iso8859-13", "ISO8859-13", "ISO8859-14", "iso8859-15",
                  "ISO8859-15", "ISO8859-16", "iso8859-2", "ISO8859-2", "iso8859-3",
                  "ISO8859-3", "iso8859-4", "ISO8859-4", "iso8859-5", "ISO8859-5",
                  "iso8859-6", "ISO8859-6", "iso8859-7", "ISO8859-7", "iso8859-8",
                  "ISO8859-8", "iso8859-8-i", "iso8859-9", "ISO8859-9", "ISO8859-9E",
                  "ISO88591", "ISO885910", "ISO885911", "ISO885913", "ISO885914",
                  "ISO885915", "ISO885916", "ISO88592", "ISO88593", "ISO88594",
                  "ISO88595", "ISO88596", "ISO88597", "ISO88598", "ISO88599", "ISO88599E",
                  "IT", "JAVA", "JIS_C6220-1969-RO", "JIS_C62201969RO", "JIS_C6226-1983",
                  "JIS_C6229-1984-B", "JIS_C62291984B", "JIS_X0201", "JIS_X0208",
                  "JIS_X0208-1983", "JIS_X0208-1990", "JIS_X0212", "JIS_X0212-1990",
                  "JIS_X0212.1990-0", "JIS0208", "JISX0201-1976", "Johab", "JOHAB",
                  "JP", "JP-OCR-B", "JS", "JUS_I.B1.002", "KOI-7", "KOI-8", "KOI8",
                  "koi8-r", "KOI8-R", "KOI8-RU", "KOI8-T", "koi8-u", "KOI8-U",
                  "KOI8R", "KOI8U", "KOREAN", "ks_c_5601-1987", "KS_C_5601-1987",
                  "KS_C_5601-1989", "KSC_5601", "KSC5636", "KZ-1048", "L1", "L10",
                  "L2", "L3", "L4", "L5", "L6", "L7", "L8", "LATIN-9", "LATIN-GREEK",
                  "LATIN-GREEK-1", "LATIN1", "LATIN10", "LATIN2", "LATIN3", "LATIN4",
                  "LATIN5", "LATIN6", "LATIN7", "LATIN8", "LATIN9", "LATINGREEK",
                  "LATINGREEK1", "MAC", "MAC-CENTRALEUROPE", "MAC-CYRILLIC", "MAC-IS",
                  "MAC-SAMI", "MAC-UK", "MACARABIC", "MACCENTRALEUROPE", "MACCROATIAN",
                  "MACCYRILLIC", "MACGREEK", "MACHEBREW", "MACICELAND", "macintosh",
                  "MACINTOSH", "MACIS", "MACROMAN", "MACROMANIA", "MACTHAI", "MACTURKISH",
                  "MACUK", "MACUKRAINE", "MACUKRAINIAN", "MIK", "MS_KANJI", "MS-ANSI",
                  "MS-ARAB", "MS-CYRL", "MS-EE", "MS-GREEK", "MS-HEBR", "MS-MAC-CYRILLIC",
                  "MS-TURK", "MS50221", "MS51932", "MS932", "MS936", "MSCP1361",
                  "MSCP949", "MSMACCYRILLIC", "MSZ_7795.3", "MULELAO-1", "NAPLPS",
                  "NATS-DANO", "NATS-SEFI", "NATSDANO", "NATSSEFI", "NC_NC00-10",
                  "NC_NC00-10:81", "NC_NC0010", "NEXTSTEP", "NF_Z_62-010", "NF_Z_62-010_(1973)",
                  "NF_Z_62-010_1973", "NF_Z_62010", "NF_Z_62010_1973", "NO", "NO2",
                  "NS_4551-1", "NS_4551-2", "NS_45511", "NS_45512", "OS2LATIN1",
                  "OSF00010001", "OSF00010002", "OSF00010003", "OSF00010004", "OSF00010005",
                  "OSF00010006", "OSF00010007", "OSF00010008", "OSF00010009", "OSF0001000A",
                  "OSF00010020", "OSF00010100", "OSF00010101", "OSF00010102", "OSF00010104",
                  "OSF00010105", "OSF00010106", "OSF00030010", "OSF0004000A", "OSF0005000A",
                  "OSF05010001", "OSF10010001", "OSF10010004", "OSF10010006", "OSF10020025",
                  "OSF10020111", "OSF10020115", "OSF10020116", "OSF10020118", "OSF1002011C",
                  "OSF1002011D", "OSF10020122", "OSF10020129", "OSF100201A4", "OSF100201A8",
                  "OSF100201B5", "OSF100201F4", "OSF10020352", "OSF10020354", "OSF10020357",
                  "OSF10020359", "OSF1002035D", "OSF1002035E", "OSF1002035F", "OSF10020360",
                  "OSF10020364", "OSF10020365", "OSF10020366", "OSF10020367", "OSF1002036B",
                  "OSF10020370", "OSF1002037B", "OSF10020387", "OSF10020388", "OSF10020396",
                  "OSF100203B5", "OSF10020402", "OSF10020417", "PT", "PT154", "PT2",
                  "PTCP154", "R8", "R9", "RK1048", "ROMAN8", "ROMAN9", "RUSCII",
                  "SE", "SE2", "SEN_850200_B", "SEN_850200_C", "SHIFFT_JIS", "SHIFFT_JIS-MS",
                  "shift_jis", "SHIFT_JIS", "SHIFT_JISX0213", "shift-jis", "SHIFT-JIS",
                  "SJIS", "SJIS-MS", "SJIS-OPEN", "SJIS-WIN", "SS636127", "ST_SEV_358-88",
                  "STRK1048-2002", "T.61", "T.61-8BIT", "T.618BIT", "TCVN", "TCVN-5712",
                  "TCVN5712-1", "TCVN5712-1:1993", "THAI8", "TIS-620", "TIS620",
                  "TIS620-0", "TIS620.2529-1", "TIS620.2533-0", "TIS620.2533-1",
                  "TS-5881", "TSCII", "TURKISH8", "UCS-2", "UCS-2-INTERNAL", "UCS-2-SWAPPED",
                  "UCS-2BE", "UCS-2LE", "UCS-4", "UCS-4-INTERNAL", "UCS-4-SWAPPED",
                  "UCS-4BE", "UCS-4LE", "UCS2", "UCS2BE", "UCS2LE", "UCS4", "UCS4BE",
                  "UCS4LE", "UHC", "UJIS", "UK", "UNICODE", "UNICODE-1-1", "UNICODE-1-1-UTF-7",
                  "UNICODEBIG", "unicodeFFFE", "UNICODELITTLE", "US", "us-ascii",
                  "US-ASCII", "UTF-16", "UTF-16BE", "UTF-16LE", "UTF-32", "UTF-32BE",
                  "UTF-32LE", "UTF-7", "UTF-8", "UTF16", "UTF16BE", "UTF16LE",
                  "UTF32", "UTF32BE", "UTF32LE", "UTF7", "UTF8", "VISCII", "VISCII1.1-1",
                  "WCHAR_T", "WIN-SAMI-2", "WINBALTRIM", "windows-1250", "WINDOWS-1250",
                  "windows-1251", "WINDOWS-1251", "windows-1252", "WINDOWS-1252",
                  "windows-1253", "WINDOWS-1253", "windows-1254", "WINDOWS-1254",
                  "windows-1255", "WINDOWS-1255", "windows-1256", "WINDOWS-1256",
                  "windows-1257", "WINDOWS-1257", "windows-1258", "WINDOWS-1258",
                  "WINDOWS-31J", "WINDOWS-50221", "WINDOWS-51932", "windows-874",
                  "WINDOWS-874", "WINDOWS-932", "WINDOWS-936", "WINSAMI2", "WS2",
                  "x_Chinese-Eten", "x-Chinese_CNS", "x-cp20001", "x-cp20003",
                  "x-cp20004", "x-cp20005", "x-cp20261", "x-cp20269", "x-cp20936",
                  "x-cp20949", "x-cp50227", "x-EBCDIC-KoreanExtended", "x-Europa",
                  "x-IA5", "x-IA5-German", "x-IA5-Norwegian", "x-IA5-Swedish",
                  "x-iscii-as", "x-iscii-be", "x-iscii-de", "x-iscii-gu", "x-iscii-ka",
                  "x-iscii-ma", "x-iscii-or", "x-iscii-pa", "x-iscii-ta", "x-iscii-te",
                  "x-mac-arabic", "x-mac-ce", "x-mac-chinesesimp", "x-mac-chinesetrad",
                  "x-mac-croatian", "x-mac-cyrillic", "x-mac-greek", "x-mac-hebrew",
                  "x-mac-icelandic", "x-mac-japanese", "x-mac-korean", "x-mac-romanian",
                  "x-mac-thai", "x-mac-turkish", "x-mac-ukrainian", "X0201", "X0208",
                  "X0212", "YU"]
end # module


text:
using Constants

drx = 1.e-4

#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
function calculate_collisions!(hydro, erf_table)

	#--- calculate collision coefficients ---
	#----------------------------------------
	hydro, xiab, k_DT, ke = collision_coefficients(hydro, erf_table, drx)

	Qextra = zeros(Float64, nz)
	if friction_switch
		hydro, Qextra = friction(hydro, xiab)
	end

	return hydro, k_DT, ke, Qextra
end

#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
function collision_coefficients(hydro, erf_table, drx)

	pi = 2. * asin(1.)
	ε = 1.e-20

	mu_ion = Array{Float64}(nz, nspec)

    xiab = zeros(Float64, nz, nspec, nspec)
    L_ab = zeros(Float64, nz, nspec, nspec)
    k_DT = zeros(Float64, nz, nspec+1, nspec+1)
    nu_DT = zeros(Float64, nz, nspec+1, nspec+1)

    mi_eV = Array{Float64}(nspec)
    muab = Array{Float64}(nspec, nspec)
    muab_eV = Array{Float64}(nspec, nspec)
    L_ie = Array{Float64}(nz, nspec)
    ni_cc = Array{Float64}(nz, nspec)
    ne_cc = Array{Float64}(nz)
	ke = Array{Float64}(nz)
    Te_eV = Array{Float64}(nz)
    taue = Array{Float64}(nz)
    taui = Array{Float64}(nz)
    Mab = Array{Float64}(nz)
    Tab = Array{Float64}(nz)
    Dab = Array{Float64}(nz)
    Qab = Array{Float64}(nz)
    meanL_ie = Array{Float64}(nz)
    T_eV = Array{Float64}(nz, nspec+1)

    erf = Array{Float64}(nz)
    i_erf = Array{Int64}(nz)

	for i = 1:nspec
		mi_eV[i] = 3.e8^2 * mi[i] / qe_C
		ni_cc[:,i] = 1.e-3 * hydro.rho[:,i] / mi_g[i]  #cm-3
	end
	ne_cc = 1.e-3 * hydro.rho[:,nspec+1] / me_g #cm-3

	for i = 1:nspec+1
	    T_eV[:,i] = hydro.T[:,i] / qe_C #hydro.T[:,i] should always be > 0 as per enforced condition in numerics.jl
	end
	Te_eV = T_eV[:,nspec+1]

	for i = 1:nspec
		for j = 1:nspec
		    du = abs.(hydro.u[:,i] - hydro.u[:,j])
			muab[i,j] = 1.e-3 / ( mi_g[i] + mi_g[j] ) * mi_g[j] * mi_g[i]  #kg
			muab_eV[i,j] =  3.e8^2 / 1.6e-19 * muab[i,j]
			#The following L_ab is the same as the one used in LSP
			L_ab[:,i,j] = max.(Lab_min,  23. - log.(Zi[i]*Zi[j] *
			  sqrt.(ni_cc[:,i] * Zi[i]^2 ./ T_eV[:,i] +
                    ni_cc[:,j] * Zi[j]^2 ./ T_eV[:,j] ) ./
			  (muab_eV[i,j] * (T_eV[:,i]/mi_eV[i] +
			      T_eV[:,j]/mi_eV[j] + du.^2./3./3.e8^2 )))
				)
		end
	end

	#L_ab = dmax1(1.0, 23.0 - log( Z1*Z2*(m1_g + m2_g) / (m1_g*T2_eV + m2_g*T1_eV) * sqrt( n1_cc*Z1^2/T1_eV + n2_cc*Z2^2/T2_eV )  ));

	for i = 1:nspec #logLambda for ion-electrons
		L_ie[:,i] = max.(
            Lab_min,
            log.(3/2 * (Te_eV*qe_C*1.e7).^1.5 ./ sqrt.(pi * ne_cc) / (Zi[i]*qe^3)) #Krall&Trivelpiece
        )
	end

	for i = 1:nspec
		for j = 1:nspec
		    du = abs.(hydro.u[:,i] - hydro.u[:,j])
			Tab = ( mi_g[i] * hydro.T[:,j] + mi_g[j] * hydro.T[:,i] ) / ( mi_g[i] + mi_g[j] )
            Tab = max.(Tab, ε) #avoid negative values (coming from negative temperature)
			Mab = sqrt.( 0.5 * muab[i,j] ./ Tab ) .* (du + ε)
			i_erf = min.(max.(1, floor.(Int, Mab / drx) + 1), 100000)
			for k = 1:nz
				erf[k] = erf_table[i_erf[k]] +
				(erf_table[i_erf[k]+1] - erf_table[i_erf[k]]) / drx *
                (Mab[k] - (i_erf[k]-1) * drx)
			end
			erf = max.(0., min.(erf, 1.0)) #so that's between 0. and 1.
			Qab = 1. / (32 * pi) * (Zi[i]*Zi[j]*qe_C^2/eps0 ./ Tab).^2 .* L_ab[:,i,j] *
                    3./2./Mab.^3 .*( 0.5 * sqrt(pi) * erf - Mab .* exp.(-Mab.^2) )

			Dab = 3. * pi / 16 * sqrt.( 2 * Tab / pi ./ muab[i,j] ) ./ Qab

			if check_frequency
				xiab[:,i,j] = mi[i] * 1.e6 * ni_cc[:,i] .*
								min.(1.e6 * ni_cc[:,j] .* Tab ./ Dab / mi[i], 1./(smax*dtm))  #attenzione mi(i) si elide####
			else
				xiab[:,i,j] = (1.e6 * ni_cc[:,i]) .* (1.e6 * ni_cc[:,j]) .* Tab ./ Dab
			end

			xiab[:,i,j] = max.(0., xiab[:,i,j]) #avoid negative values too
		end
	end

	for i = 1:nz
		meanL_ie[i] = sum(L_ie[i,:]) / nspec
	end
	taue = 3.44e5 * Te_eV.^1.5 ./ meanL_ie #NRL page 37	- excluding density because it cancels out anyways
	ke = 3.2 * (1.6e-12 * Te_eV) .* taue / me_g  #all cgs
	#multiply by 100 to get SI units ([ke] = [L^-1*T^-1])
	ke = 1.e2 * ke

	#calculate ion viscosity
	for i = 1:nspec
		#NRL page 38 - excluding density because it cancels out anyways
		taui =  2.09e7 * T_eV[:,i].^1.5 ./ L_ab[:,i,i] * sqrt(Ai[i])
		mu_ion[:,i] = 0.96 * ( 1.6e-12 * T_eV[:,i] ) .* taui #all cgs
		mu_ion[:,i] = 1.e-1 * mu_ion[:,i] # [mu_ion] = [M*L^-1*T^-1]
	end
	#Redefine ion viscosity to include the factor 4./3 in front of derivative
	mu_ion = 4./3 * mu_ion

	#coefficients for heat transfer (NRL page 34)
	for i = 1:nspec
		for j = 1:nspec
			if i != j
				nu_DT[:,i,j] = 1.8e-19 * sqrt(mi_g[i]) * sqrt(mi_g[j]) * Zi[i]^2 * Zi[j]^2 *
                    ni_cc[:,j] .* L_ab[:,i,j] ./ (mi_g[i] * T_eV[:,j] + mi_g[j] * T_eV[:,i]).^1.5
			end
		end
	end
	#heat transfer with electrons
	for i = 1:nspec
		nu_DT[:,i,nspec+1] = 1.8e-19 * sqrt(mi_g[i]) * sqrt(me_g) * Zi[i]^2 *
			ne_cc .* L_ie[:,i] ./ (mi_g[i] * Te_eV + me_g * T_eV[:,i]).^1.5
		nu_DT[:,nspec+1,i] = 1.8e-19 * sqrt(me_g) * sqrt(mi_g[i]) * Zi[i]^2 *
			ni_cc[:,i] .* L_ie[:,i] ./ (me_g * T_eV[:,i] + mi_g[i] * Te_eV).^1.5
	end

	if check_frequency
		for i = 1:nspec
			for j = 1:nspec
				if i != j
					nu_DT[:,i,j] = min.(nu_DT[:,i,j], 1.e-1/dtm)
				end
			end
		end
		#heat transfer with electrons
		for i = 1:nspec
			nu_DT[:,i,nspec+1] = min.(nu_DT[:,i,nspec+1], 1.e-1/dtm)
			nu_DT[:,nspec+1,i] = min.(nu_DT[:,nspec+1,i], 1.e-1/dtm)
		end
	end

	for i = 1:nspec
		for j = 1:nspec
			k_DT[:,i,j] = 1.e6 * 3./2 * ni_cc[:,i] .* nu_DT[:,i,j]   #SI units
		end
	end
	#with electrons now
	for i = 1:nspec
		k_DT[:,i,nspec+1] = 1.e6 * 3./2 * ni_cc[:,i] .* nu_DT[:,i,nspec+1]   #SI units
		k_DT[:,nspec+1,i] = 1.e6 * 3./2 * ne_cc .* nu_DT[:,nspec+1,i]   #SI units
	end

	return hydro, xiab, k_DT, ke
end

#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
function friction(hydro, xiab)

	hydro.R1D = zeros(Float64, nz, neqi+1)
	Qextra = zeros(Float64, nz)

	for i = 1:nspec
		for j = 1:nspec
			if i != j
				hydro.R1D[:,3*(i-1)+2] = hydro.R1D[:,3*(i-1)+2] -
                        xiab[:,i,j] .* (hydro.u[:,i] - hydro.u[:,j])
    		end
    	end
    	hydro.R1D[:,3*(i-1)+3] = hydro.u[:,i] .* hydro.R1D[:,3*(i-1)+2]
    end

 	for i = 1:nspec
		Qextra = Qextra - hydro.R1D[:,3*(i-1)+3]
	end

	return hydro, Qextra
end

max_stars_repo_name: cbellei/JUPL

max_issues_repo_name: cbellei/JUPL

max_forks_repo_name: cbellei/JUPL


text:
using Interpolations, Test, LinearAlgebra

@testset "Typing" begin
    nx = 10
    f(x) = convert(Float32, x^3/(nx-1))
    g(x) = convert(Float32, 3x^2/(nx-1))

    A = Float32[f(x) for x in 1:nx]

    itp = interpolate(A, BSpline(Quadratic(Flat(OnCell()))))

    # display(plot(
    #     layer(x=1:nx,y=[f(x) for x in 1:1//1:nx],Geom.point),
    #     layer(x=1:.1:nx,y=[itp[x] for x in 1:1//10:nx],Geom.path),
    # ))

    for x in 3.1:.2:4.3
        @test ≈(float(f(x)),float(itp(x)),atol=abs(0.1 * f(x)))
    end

    @test typeof(itp(3.5f0)) == Float32

    for x in 3.1:.2:4.3
        @test ≈([g(x)], Interpolations.gradient(itp,x),atol=abs(0.1 * g(x)))
    end

    @test typeof(Interpolations.gradient(itp, 3.5f0)[1]) == Float32

    # Rational element types
    R = Rational{Int}[x^2//10 for x in 1:10]
    itp = interpolate(R, BSpline(Quadratic(Free(OnCell()))))

    @test typeof(itp(11//10)) == Rational{Int}
    @test itp(11//10) == (11//10)^2//10
end


text:
############## radius.jl  ###############

import RiemannTheta.radius

≈(a,b) = isapprox(a, b, rtol=1e-1)

@testset "radius" begin

    @test radius(ϵ1, T1) ≈ 3.4
    @test radius(ϵ2, T1) ≈ 5.0
    @test radius(ϵ1, T2) ≈ 3.4
    @test radius(ϵ2, T2) ≈ 5.0
    @test radius(ϵ1, T3) ≈ 4.7
    @test radius(ϵ2, T3) ≈ 6.7

    @test radius(ϵ1, T1, derivs1) ≈ 4.1
    @test radius(ϵ1, T3, derivs2) ≈ 9.1

end

############## innerpoints  ###################

import RiemannTheta.innerpoints

@testset "innerpoints" begin

    R = radius(ϵ1, T1)
    pts = innerpoints(T1, R)
    @test length(pts) > 17
    @test length(pts) < 30
    @test all(length.(pts) .== 2)

    R = radius(ϵ2, T3)
    pts = innerpoints(T3, R)
    @test length(pts) > 100
    @test length(pts) < 300
    @test all(length.(pts) .== 10)

end

########### finite_sum.jl ##############

########### lll.jl ##############


text:
plot(linspace(-4,4,100), erf(linspace(-4,4,100)),"k-")

xlabel(L"x")
ylabel(L"\frac{2}{\sqrt{\pi}}\int^x_{0} dt\, e^{-t^2}")


text:
eM_box = output_eMesh_box()

@testset "extensions" begin
    @test_throws ErrorException volume(as_tri_eMesh(eM_box))
    @test_throws ErrorException area(as_tet_eMesh(eM_box))

    c = SVector(99.0, 99.0, 99.0)
    e = SVector(1.0, 2.0, 3.0)

    aabb = OBB(c, e, one(SMatrix{3,3,Float64,9}))
    @test 8 * 6.0 == volume(aabb)
    @test 4 * 22.0 == area(aabb)
end


text:
using Test
using AeroAcoustics, HDF5
import DSP

@testset "Test 2: Monopole source without flow:" begin
    csm_ref = h5open("data/test1_csm.h5", "r") do file
        read(file, "CsmData/csmReal")+im*read(file, "CsmData/csmImag")
    end
    t = h5open("data/test1_timeseries.h5", "r") do file
        read(file, "MicrophoneData/microphoneDataPa")
    end

    # Test csm
    fs = h5readattr("data/test1_csm.h5", "CsmData")["fs"]
    n = h5readattr("data/test1_csm.h5", "CsmData")["n"]
    csm_test = csm(t;n=n,noverlap=div(n,2),fs=fs,win=DSP.hanning(n))
    #@test csm_test.arr ≈ csm_ref

    # Setup beamforming
    fc2 = h5read("data/test1_csm.h5", "CsmData")["binCenterFrequenciesHz"]
    @test csm_test.fc==fc2
    z0 = h5readattr("data/test1_csm.h5", "CsmData")["z0"]
    micgeom = h5read("data/test1_csm.h5", "CsmData")["arrayGeom"]
    @test size(micgeom) == (3,84)
    weights_vector = ones(84)
    weights_vector[4:34] .= 0

    env = Environment(z0=z0,
                      micgeom=micgeom,
                      flim=(3000,4000),
                      wv=weights_vector,
                      Nx = 21,
                      Ny = 21,
                      xlim=(-0.5,0.5),
                      ylim=(-0.5,0.5),
                      CSM=csm_test)

    steeringvectors!(env)
    b = beamforming(env)
    bd = beamforming(env.CSM_s.arr,env.steeringvec.arr)
    @test b.arr ≈ bd
    idx = 1 # Frequency index
    s1,p1 = findmax(reshape(b[:,idx],env.Nx,env.Ny))
    bmax = ceil(SPL(s1./sqrt(2)))
    @test bmax == 51.0
    @test p1.I == (10,13) # (19,24) for n = 41
    p_1 = psf(env)[:,idx]
    s2,p2 = findmax(reshape(p_1,env.Nx,env.Ny))
    @test ceil(SPL(s2./sqrt(2))) == 94
    @test p2.I == (floor(Int,env.Nx/2)+1,floor(Int,env.Ny/2)+1)
    pcol_1 = zeros(env.N)
    AeroAcoustics.psf_col!(pcol_1,env.steeringvec.arr[:,:,idx],floor(Int,env.N/2)+1)
    @test pcol_1 ≈ p_1
    # DAMAS
    x = damas(env, b; maxiter = 10)
    x2 = damas(env, b,[b.fc[idx]]; maxiter = 10)
    @test x[:,idx] ≈ x2
    id1,id2 = UnitRange.(p1.I.-2,p1.I.+2)
    limits = [env.rx[id1][1],env.rx[id1][end],env.ry[id2][1],env.ry[id2][end]]
    @test abs.(bmax-SPL.(sourceintegration(x[:,idx],env,limits))) <= 1 # Within 1dB of beamforming is OK (increase number of iterations to get better estimate)
    #CLEAN-SC
    x_clean = cleanSC(env;maxiter=10,ϕ=0.5)
    @test abs.(bmax-SPL.(sourceintegration(x_clean[:,idx],env,limits)/sqrt(2))) <= 1
end


text:
using Parquet
using Test

function test_row_cursor(file::String)
    p = Parquet.File(file)

    t1 = time()
    nr = nrows(p)
    cnames = colnames(p)
    rc = RecordCursor(p)
    rec = nothing
    nread = 0
    for i in rc
        rec = i
        nread += 1
    end
    @test nr == nread
    @debug("loaded", file, count=nr, last_record=rec, time_to_read=time()-t1)

    iob = IOBuffer()
    show(iob, rc)
    sb = take!(iob)
    @test !isempty(sb)
    @debug("row cursor show", file, showbuffer=String(sb))
end

function test_batchedcols_cursor(file::String)
    p = Parquet.File(file)

    t1 = time()
    nr = nrows(p)
    cnames = colnames(p)
    cc = BatchedColumnsCursor(p)
    batch = nothing
    nread = 0
    for i in cc
        batch = i
        nread += length(first(batch))
    end
    @test nr == nread
    @debug("loaded", file, count=nr, ncols=length(propertynames(batch)), time_to_read=time()-t1)

    iob = IOBuffer()
    show(iob, cc)
    sb = take!(iob)
    @test !isempty(sb)
    @debug("batched column cursor show", file, showbuffer=String(sb))
end

function test_row_cursor_all_files()
    for encformat in ("SNAPPY", "GZIP", "NONE")
        for fname in ("nation", "customer")
            test_row_cursor(joinpath(@__DIR__, "parquet-compatibility", "parquet-testdata", "impala", "1.1.1-$encformat/$fname.impala.parquet"))
        end
    end
end

function test_batchedcols_cursor_all_files()
    for encformat in ("SNAPPY", "GZIP", "NONE")
        for fname in ("nation", "customer")
            test_batchedcols_cursor(joinpath(@__DIR__, "parquet-compatibility", "parquet-testdata", "impala", "1.1.1-$encformat/$fname.impala.parquet"))
        end
    end
end

@testset "cursors" begin
    test_row_cursor_all_files()
    test_batchedcols_cursor_all_files()
end


text:
# *****************************************************************************
# Written by Ritchie Lee, ritchie.lee@sv.cmu.edu
# *****************************************************************************
# Copyright ã ``2015, United States Government, as represented by the
# Administrator of the National Aeronautics and Space Administration. All
# rights reserved.  The Reinforcement Learning Encounter Simulator (RLES)
# platform is licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. You
# may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable
# law or agreed to in writing, software distributed under the License is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.
# _____________________________________________________________________________
# Reinforcement Learning Encounter Simulator (RLES) includes the following
# third party software. The SISLES.jl package is licensed under the MIT Expat
# License: Copyright (c) 2014: Youngjun Kim.
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
# "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# *****************************************************************************

"""
Collection of generic grammars
"""
module Grammars

using GrammaticalEvolution
using RLESUtils
using ExprSearch, DerivationTrees

import RLESTypes.SymbolTable

include("operators.jl")

function time_series_realonly1(real_feat_ids::Vector{Int64}, num_real_vals::Int64,
    real_vals::Vector, colnames::Vector{String}, colnames_full::Vector{String})

    @grammar grammar begin
        start = bin

        bin = always | eventually | implies
        always = Expr(:call, :G, bin_vec) #global
        eventually = Expr(:call, :F, bin_vec) #future
        implies = Expr(:call, :Y, bin_vec, bin_vec)

        #produces a bin_vec
        bin_vec = and | or | not  | eq | lt | lte | gt | gte
        and = Expr(:call, :&, bin_vec, bin_vec)
        or = Expr(:call, :|, bin_vec, bin_vec)
        not = Expr(:call, :!, bin_vec)

        #comparisons
        eq = bin_eq | real_eq
        bin_eq = Expr(:call, :eq, bin_vec, bin_vec)
        real_eq = Expr(:call, :eq, real_vec, real_vec) | Expr(:call, :feq, :D, real_feat_id, :V, real_val_id)
        lt = Expr(:call, :lt, real_vec, real_vec) | Expr(:call, :flt, :D, real_feat_id, :V, real_val_id)
        lte = Expr(:call, :lte, real_vec, real_vec) | Expr(:call, :flte, :D, real_feat_id, :V, real_val_id)
        gt = Expr(:call, :gt, real_vec, real_vec) | Expr(:call, :fgt, :D, real_feat_id, :V, real_val_id)
        gte = Expr(:call, :gte, real_vec, real_vec) | Expr(:call, :fgte, :D, real_feat_id, :V, real_val_id)

        #read features
        real_vec = Expr(:call, :g, :D, real_feat_id)
    end
    grammar.rules[:real_feat_id] = OrRule("real_feat_id", [Terminal("", real_feat_ids[i])
        for i=1:length(real_feat_ids)], nothing)
    grammar.rules[:real_val_id] = RangeRule("real_val_id", 1:num_real_vals, nothing)

    symtable = SymbolTable(
    :g => get_ref,
    :F => eventually,
    :G => globally,
    :Y => implies,
    :eq => eq,
    :lt => lt,
    :lte => lte,
    :gt => gt,
    :gte => gte,
    :feq => feq,
    :flt => flt,
    :flte => flte,
    :fgt => fgt,
    :fgte => fgte,
    :| => or,
    :& => and,
    :! => not
    )

    function get_format_pretty{T<:AbstractString}(real_vals::Vector, colnames::Vector{T})
        fmt = Format()

        fmt["always"] = (cmd, args) -> "G($(args[1]))"
        fmt["eventually"] = (cmd, args) -> "F($(args[1]))"

        bin_infix(cmd, args, insym) = "($(args[1]) $insym $(args[2]))"
        fmt["and"] = (cmd, args) -> bin_infix(cmd, args, "&")
        fmt["or"] = (cmd, args) -> bin_infix(cmd, args, "|")
        fmt["not"] = (cmd, args) -> "!($(args[1]))"
        fmt["implies"] = (cmd, args) -> "$(args[1]) => $(args[2])"

        bin_infix_eq(cmd, args) = bin_infix(cmd, args, ".==")
        bin_infix_lt(cmd, args) = bin_infix(cmd, args, ".<")
        bin_infix_lte(cmd, args) = bin_infix(cmd, args, ".<=")
        bin_infix_gt(cmd, args) = bin_infix(cmd, args, ".>")
        bin_infix_gte(cmd, args) = bin_infix(cmd, args, ".>=")
        fmt["bin_eq"] = bin_infix_eq
        fmt["real_eq.1"] = bin_infix_eq
        fmt["lt.1"] = bin_infix_lt
        fmt["lte.1"] = bin_infix_lte
        fmt["gt.1"] = bin_infix_gt
        fmt["gte.1"] = bin_infix_gte

        function bin_infix_f(cmd, args, insym)
            "($(colnames[parse(Int,args[1])]) $insym $(round(get_val(real_vals,parse(Int,args[1]),parse(Int,args[2])),4))"
        end
        bin_infix_feq(cmd, args) = bin_infix_f(cmd, args, ".==")
        bin_infix_flt(cmd, args) = bin_infix_f(cmd, args, ".<")
        bin_infix_flte(cmd, args) = bin_infix_f(cmd, args, ".<=")
        bin_infix_fgt(cmd, args) = bin_infix_f(cmd, args, ".>")
        bin_infix_fgte(cmd, args) = bin_infix_f(cmd, args, ".>=")
        fmt["real_eq.2"] = bin_infix_feq
        fmt["lt.2"] = bin_infix_flt
        fmt["lte.2"] = bin_infix_flte
        fmt["gt.2"] = bin_infix_fgt
        fmt["gte.2"] = bin_infix_fgte

        feat(cmd, args) = "$(colnames[parse(Int, args[1])])"
        fmt["real_vec"] = feat

        fmt
    end

    function get_format_natural{T<:AbstractString}(real_vals::Vector, colnames::Vector{T})
        fmt = Format()

        fmt["always"] = (cmd, args) -> "for all time, $(args[1])"
        fmt["eventually"] = (cmd, args) -> "at some point, $(args[1])"

        bin_infix(cmd, args, insym) = "[$(args[1]) $insym $(args[2])]"
        fmt["and"] = (cmd, args) -> bin_infix(cmd, args, "and")
        fmt["or"] = (cmd, args) -> bin_infix(cmd, args, "or")
        fmt["not"] = (cmd, args) -> "[it is not true that $(args[1])]"
        fmt["implies"] = (cmd, args) -> "whenever $(args[1]), it is also true that $(args[2])"

        bin_infix_eq(cmd, args) = bin_infix(cmd, args, "is equal to")
        bin_infix_lt(cmd, args) = bin_infix(cmd, args, "is less than")
        bin_infix_lte(cmd, args) = bin_infix(cmd, args, "is less than or equal to")
        bin_infix_gt(cmd, args) = bin_infix(cmd, args, "is greater than")
        bin_infix_gte(cmd, args) = bin_infix(cmd, args, "is greater than or equal to")
        fmt["bin_eq"] = bin_infix_eq
        fmt["real_eq.1"] = bin_infix_eq
        fmt["lt.1"] = bin_infix_lt
        fmt["lte.1"] = bin_infix_lte
        fmt["gt.1"] = bin_infix_gt
        fmt["gte.1"] = bin_infix_gte

        bin_infix_f(cmd, args, insym) = "[$(colnames[parse(Int,args[1])]) $insym $(round(get_val(real_vals,parse(Int,args[1]),parse(Int,args[2])),4))]"
        bin_infix_feq(cmd, args) = bin_infix_f(cmd, args, "is equal to")
        bin_infix_flt(cmd, args) = bin_infix_f(cmd, args, "is less than")
        bin_infix_flte(cmd, args) = bin_infix_f(cmd, args, "is less than or equal to")
        bin_infix_fgt(cmd, args) = bin_infix_f(cmd, args, "is greater than")
        bin_infix_fgte(cmd, args) = bin_infix_f(cmd, args, "is greater than or equal to")
        fmt["real_eq.2"] = bin_infix_feq
        fmt["lt.2"] = bin_infix_flt
        fmt["lte.2"] = bin_infix_flte
        fmt["gt.2"] = bin_infix_fgt
        fmt["gte.2"] = bin_infix_fgte

        feat(cmd, args) = "[$(colnames[parse(Int, args[1])])]"
        fmt["real_vec"] = feat

        fmt
    end

    fmt_pretty = get_format_pretty(real_vals, colnames)
    fmt_natural = get_format_natural(real_vals, colnames_full)

    (grammar, symtable, fmt_pretty, fmt_natural)
end

end #module

max_stars_repo_name: sisl/ExprSearch

max_issues_repo_name: sisl/ExprSearch


text:
#=
Copyright (c) 2015, Intel Corporation

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of Intel Corporation nor the names of its contributors
      may be used to endorse or promote products derived from this software
      without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=#

using FactCheck
using Latte

net = Net(8)
data,  data_value = MemoryDataLayer(net, :data, (20,))
fc1               = InnerProductLayer(:fc1, net, data, 10)
tanh1             = TanhLayer(:tanh1, net, fc1)

data_value[:]     = rand(Float32, size(data_value)...)

init(net)

ϵ = 1e-5
facts("Testing Tanh Layer") do
    fc1_expected = get_buffer(net, :fc1weights)' * data_value
    context("Forward") do
        forward(net; phase=Latte.Test)

        expected = tanh(fc1_expected)
        @fact expected --> roughly(get_buffer(net, :tanh1value))
    end
    context("Backward") do
        top_diff = get_buffer(net, :tanh1∇)
        rand!(top_diff)
        ∇tanh(x) = x .* (1.0f0 .- x)
        expected = ∇tanh(tanh(fc1_expected)) .* top_diff
        backward(net)
        @fact expected --> roughly(get_buffer(net, :fc1∇))
    end
end

FactCheck.exitstatus()


text:
using NumericalMethodsforEngineers
using Test

ProjDir = dirname(@__FILE__)
cd(ProjDir) do

  function f2(x::Float64, y::Vector{Float64})
    [y[2], 3x^2+4y[1]]
  end

  (iters, nsteps, converged, res) = shootingmethod(f2, [0.0, 0.0, 1.0, 1.0], [0.0, 1.0], 5)

  if !converged
    println("No conversion achieved.")
  elseif iters > 50
    println("Iter limit reached.")
  else
    @test round.(res[:, 2], digits=4)' == [0.0  0.0813  0.1815  0.3313  0.5794  1.0]
    #println()
    #res |> display
  end

end


text:
"""Struct holding the tendencies of the prognostic spectral variables plus some additional tendencies used in their calculation"""
struct Tendencies{NF<:AbstractFloat}
    vor_tend        ::Array{Complex{NF},3}      # Vorticity of horizontal wind field
    div_tend        ::Array{Complex{NF},3}      # Divergence of horizontal wind field
    temp_tend       ::Array{Complex{NF},3}      # Absolute temperature [K]
    pres_surf_tend  ::Array{Complex{NF},2}      # Log of surface pressure [log(Pa)]
    humid_tend      ::Array{Complex{NF},3}      # Specific humidity [g/kg]

    u_tend          ::Array{Complex{NF},3}      # zonal velocity
    v_tend          ::Array{Complex{NF},3}      # meridonal velocity
end

"""Struct holding the core prognostic spectral variables in grid point space, plus some additional grid quantities"""
struct GridVariables{NF<:AbstractFloat}
    vor_grid       ::Array{NF,3}  # Gridpoint field of vorticity
    div_grid       ::Array{NF,3}  # Gridpoint field of divergence
    temp_grid      ::Array{NF,3}  # Gridpoint field of absolute temperature [K]
    pres_surf_grid ::Array{NF,2}  # Gridpoint field of surface pressure logarithm [log(Pa)]
    humid_grid     ::Array{NF,3}  # Gridpoint field of specific_humidity

    geopot_grid ::Array{NF,3}  # Gridpoint field of geopotential
    tr_grid     ::Array{NF,3}  # Gridpoint field of tracers
    u_grid      ::Array{NF,3}  # Gridpoint field of zonal velocity
    v_grid      ::Array{NF,3}  # Gridpoint field of meridional velocity
    temp_grid_anomaly   ::Array{NF,3}  # Gridpoint field of absolute temperature anomaly [K]

end

struct MiscellaneousVariables{NF<:AbstractFloat}
    u_mean ::Array{NF,2}  # Mean gridpoint zonal velocity over all levels
    v_mean ::Array{NF,2}  # Mean gridpoint meridional velocity over all levels
    d_mean ::Array{NF,2}  # Mean gridpoint divergence over all levels

    dumc ::Array{NF,3}  # Array for holding x/y gradients of surface pressure

    px ::Array{NF,2}  # X Grad of pressure in grid point space
    py ::Array{NF,2}  # Y Grad of pressure in grid point space

    sigma_tend ::Array{NF,3} #vertical velocity in sigma coords
    sigma_m    ::Array{NF,3}
    puv :: Array{NF,3}

    #Arbitrary array just to hold some temporary values. Used in zonal/meridonal_wind_tendency!().
    #Named `temp` in Paxton/Chantry, but not a temperature quantity. `temp` for temporary?
    #Better name needed
    arbitrary_array ::Array{NF,3}

    d_meanc ::Array{NF,2} #used in get_spectral_tendencies
    sigma_tend_c ::Array{NF,3}
    dumk ::Array{NF,3}

 end

"""Struct holding the diagnostic variables."""
struct DiagnosticVariables{NF<:AbstractFloat}
    tendencies  ::Tendencies{NF}
    gridvars    ::GridVariables{NF}
    miscvars    ::MiscellaneousVariables{NF}
end


text:
using Test, QBase

@testset "./src/quantum_strategies.jl" begin

using BellScenario

@testset "quantum_strategy()" begin
    @testset "QBase types" begin
        q_strat = quantum_strategy(
            POVM([[1 0 0;0 0 0;0 0 0],[0 0 0;0 1 0;0 0 0],[0 0 0;0 0 0;0 0 1]]),
            State.([[1 0 0;0 0 0;0 0 0],[0 0 0;0 1 0;0 0 0],[0 0 0;0 0 0;0 0 1]])
        )

        @test q_strat isa Strategy
        @test q_strat.scenario == BlackBox(3,3)
        @test q_strat == [1 0 0;0 1 0;0 0 1]
    end

    @testset "matrix types" begin
        q_strat = quantum_strategy(
            [[1 0;0 0],[0 0;0 1]],
            [[1 0;0 0],[0 0;0 1]]
        )

        @test q_strat isa Strategy
        @test q_strat.scenario == BlackBox(2,2)
        @test q_strat == [1 0;0 1]
    end
end

@testset "quantum_strategy(LocalSignaling)" begin
    @testset "QBase types" begin
        scenario = LocalSignaling(3,3,2)
        q_strat = quantum_strategy(
            mirror_symmetric_qubit_3povm(π/3),
            trine_qubit_states(),
            scenario
        )

        @test q_strat isa Strategy
        @test q_strat ≈ [2/3 1/6 1/6;1/6 2/3 1/6;1/6 1/6 2/3]
        @test q_strat.scenario isa LocalSignaling
    end

    @testset "Matrix types" begin
        scenario = LocalSignaling(2,2,2)

        q_strat = quantum_strategy(
            [[1 0;0 0],[0 0;0 1]],
            [[1 0;0 0],[0 0;0 1]],
            scenario
        )

        @test q_strat isa Strategy
        @test q_strat.scenario == LocalSignaling(2,2,2)
        @test q_strat == [1 0;0 1]
    end

    @testset "DomainErrors" begin
        scenario = LocalSignaling(3,3,2)
        @test_throws DomainError quantum_strategy(
            POVM([[1 0 0;0 0 0;0 0 0],[0 0 0;0 1 0;0 0 0],[0 0 0;0 0 0;0 0 1]]),
            State.([[1 0 0;0 0 0;0 0 0],[0 0 0;0 1 0;0 0 0],[0 0 0;0 0 0;0 0 1]]),
            scenario
        )
    end
end

@testset "quantum_strategy(BipartiteNonSignaling)" begin
    @testset "QBase types ch violation" begin
        scenario = BipartiteNonSignaling(2,2,2,2)
        ρ_AB = State([1 0 0 1;0 0 0 0;0 0 0 0;1 0 0 1]/2)
        Π_Ax = [
            POVM([[1. 0;0 0],[0 0;0 1.]]),
            POVM([[1 1;1 1]/2,[1 -1;-1 1]/2])
        ]
        Π_By = [
            POVM([bloch_qubit_state(π/4),bloch_qubit_state(-3π/4)]),
            POVM([bloch_qubit_state(3π/4),bloch_qubit_state(-π/4)])
        ]

        q_strat = quantum_strategy(ρ_AB, Π_Ax, Π_By, scenario)
        @test q_strat isa Strategy
        @test q_strat.scenario isa BipartiteNonSignaling

        # generalized rep of CH inequality
        g = BellGame([1 0 1 1;1 1 0 0;0 1 1 0;1 1 1 0], 3)
        @test sum(g .* q_strat) ≈ 3.207 atol=2e-4
    end

    @testset "matrix types classical states" begin
        scenario = BipartiteNonSignaling(2,2,2,2)
        ρ_AB = kron([1 0;0 0],[0 0;0 1])
        Π_Ax = [
            [[1 0;0 0],[0 0;0 1]],
            [[0 0;0 1],[1 0;0 0]]
        ]
        Π_By = [
            [[1 0;0 0],[0 0;0 1]],
            [[0 0;0 1],[1 0;0 0]]
        ]

        q_strat = quantum_strategy(ρ_AB, Π_Ax, Π_By, scenario)
        @test q_strat isa Strategy
        @test q_strat == [0 1 0 0;1 0 0 0;0 0 0 1;0 0 1 0]
        @test q_strat.scenario == scenario
    end

    @testset "Domain Errors" begin
        ρ_AB = State(kron([1 0;0 0],[0 0;0 1]))
        Π = POVM([[1 0;0 0],[0 0;0 1]])
        Π_Ax = [Π, Π]
        Π_By = [Π, Π]

        scenario = BipartiteNonSignaling(3,2,2,2)
        @test_throws DomainError quantum_strategy(ρ_AB, Π_Ax, Π_By, scenario)

        scenario = BipartiteNonSignaling(2,3,2,2)
        @test_throws DomainError quantum_strategy(ρ_AB, Π_Ax, Π_By, scenario)

        scenario = BipartiteNonSignaling(2,2,3,2)
        @test_throws DomainError quantum_strategy(ρ_AB, Π_Ax, Π_By, scenario)

        scenario = BipartiteNonSignaling(2,2,2,3)
        @test_throws DomainError quantum_strategy(ρ_AB, Π_Ax, Π_By, scenario)
    end
end

end