text:
@doc raw"""
GeometricProblem: stores a GeometricEquation togehter with initial conditions, parameters, time span and time step size.

### Parameters

* `ST <: GeometricEquation`: super type, used for dispatch
* `DT <: Number`: data type
* `TT <: Real`: time step type
* `AT <: AbstractArray{DT}`: array type
* `equType <: GeometricEquation`: equation type
* `icsType <: paramsType`: initial conditions type
* `parType <: OptionalParameters`: parameters type

### Fields

* `equation`: reference to the parent equation object
* `tspan`: time span for problem `(t₀,t₁)`
* `tstep`: time step to be used in simulation
* `ics`: `NamedTuple` containing the initial conditions
* `parameters`: either a `NamedTuple` containing the equation's parameters or `NullParameters`

### Subtypes

The `GeometricProblem` type has various subtypes for the different equations types, that are defined e.g. via
```
const ODEProblem = GeometricProblem{ODE}
```
and provide convenience constructors to construct and equation and the corresponding problem in one step.

"""
struct GeometricProblem{superType<:GeometricEquation,dType<:Number,tType<:Real,arrayType<:AbstractArray{dType},
    equType<:GeometricEquation,icsType<:NamedTuple,paramsType<:OptionalParameters} <: AbstractProblem{dType,tType,arrayType}
    equation::equType
    tspan::Tuple{tType,tType}
    tstep::tType
    ics::icsType
    parameters::paramsType

    function GeometricProblem(equ, tspan, tstep, ics, parameters)
        _tspan = promote_tspan(tspan)
        _tspan, _tstep = promote_tspan_and_tstep(_tspan, tstep)

        @assert check_initial_conditions(equ, ics)
        @assert check_methods(equ, _tspan, ics, parameters)

        superType = eval(typeof(equ).name.name)
        tType = typeof(_tstep)
        dType = datatype(equ, ics)
        arrayType = arrtype(equ, ics)

        new{superType,dType,tType,arrayType,typeof(equ),typeof(ics),typeof(parameters)}(equ, _tspan, _tstep, ics, parameters)
    end
end

GeometricProblem(equ, tspan, tstep, ics; parameters = NullParameters()) = GeometricProblem(equ, tspan, tstep, ics, parameters)
GeometricProblem(equ, tspan, tstep, ics, ::Nothing) = GeometricProblem(equ, tspan, tstep, ics, NullParameters())

# Base.hash(prob::GeometricProblem, h::UInt) = hash(hash(prob.equation,
#                                                   hash(prob.tspan, hash(prob.tstep,
#                                                   hash(prov.ics, hash(prov.parameters, h))))))

# Base.:(==)(prob1::GeometricProblem, prob2::GeometricProblem) = (
#                                 prob1.equation   == prob2.equation
#                              && prob1.tspan      == prob2.tspan
#                              && prob1.tstep      == prob2.tstep
#                              && prob1.ics        == prob2.ics
#                              && prob1.parameters == prob2.parameters)

datatype(::GeometricProblem{ST,DT,TT,AT}) where {ST,DT,TT,AT} = DT
timetype(::GeometricProblem{ST,DT,TT,AT}) where {ST,DT,TT,AT} = TT
arrtype(::GeometricProblem{ST,DT,TT,AT}) where {ST,DT,TT,AT} = AT
equtype(::GeometricProblem{ST,DT,TT,AT}) where {ST,DT,TT,AT} = ST

equation(prob::GeometricProblem) = prob.equation
tspan(prob::GeometricProblem) = prob.tspan
tstep(prob::GeometricProblem) = prob.tstep

GeometricBase.parameters(prob::GeometricProblem) = prob.parameters
GeometricBase.nsamples(::GeometricProblem) = 1

initial_conditions(prob::GeometricProblem) = (tbegin(prob), prob.ics...)

function Base.similar(prob::GeometricProblem, tspan, tstep = tstep(prob), ics = prob.ics, parameters = parameters(prob))
    GeometricProblem(equation(prob), tspan, tstep, ics, parameters)
end

function Base.similar(prob::GeometricProblem; tspan = tspan(prob), tstep = tstep(prob), ics = prob.ics, parameters = parameters(prob))
    similar(prob, tspan, tstep, ics, parameters)
end

@doc raw"""
`ODEProblem`: Ordinary Differential Equation Problem

Defines an initial value problem
```math
\dot{q} (t) = v(t, q(t)) , \qquad q(t_{0}) = q_{0} ,
```
with vector field ``v`` and initial condition ``q_{0}``.

### Constructors

```julia
ODE(v, tspan, tstep, ics::NamedTuple; kwargs...)
ODE(v, tspan, tstep, q₀::State; kwargs...)
```
where `ics` is a `NamedTuple` with entry `q`.

### Keyword arguments:

* `invariants = NullInvariants()`
* `parameters = NullParameters()`
* `periodicity = NullPeriodicity()`

"""
const ODEProblem = GeometricProblem{ODE}

function ODEProblem(v, tspan, tstep, ics::NamedTuple; invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity())
    equ = ODE(v, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function ODEProblem(v, tspan, tstep, q₀::State; kwargs...)
    ics = (q = q₀,)
    ODEProblem(v, tspan, tstep, ics; kwargs...)
end

@doc raw"""
`PODEProblem`: Partitioned Ordinary Differential Equation Problem

Defines a partitioned initial value problem
```math
\begin{aligned}
\dot{q} (t) &= v(t, q(t), p(t)) , &
q(t_{0}) &= q_{0} , \\
\dot{p} (t) &= f(t, q(t), p(t)) , &
p(t_{0}) &= p_{0} ,
\end{aligned}
```
with vector fields ``v`` and ``f`` and initial conditions ``(q_{0}, p_{0})``.

### Constructors

```julia
PODE(v, f, tspan, tstep, ics; kwargs...)
PODE(v, f, tspan, tstep, q₀::State, p₀::State; kwargs...)
```
where `ics` is a `NamedTuple` with entries `q` and `p`.

### Keyword arguments:

* `invariants = NullInvariants()`
* `parameters = NullParameters()`
* `periodicity = NullPeriodicity()`

"""
const PODEProblem = GeometricProblem{PODE}

function PODEProblem(v, f, tspan, tstep, ics::NamedTuple; invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity())
    equ = PODE(v, f, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function PODEProblem(v, f, tspan, tstep, q₀::State, p₀::State; kwargs...)
    ics = (q = q₀, p = p₀)
    PODEProblem(v, f, tspan, tstep, ics; kwargs...)
end

@doc raw"""
`HODEProblem`: Hamiltonian Ordinary Differential Equation Problem

Defines a Hamiltonian ordinary differential initial value problem, that is
a canonical Hamiltonian system of equations,
```math
\begin{aligned}
\dot{q} (t) &= v(t, q(t), p(t)) , & q(t_{0}) &= q_{0} , \\
\dot{p} (t) &= f(t, q(t), p(t)) , & p(t_{0}) &= p_{0} ,
\end{aligned}
```
with vector fields ``v`` and ``f``, given by
```math
\begin{aligned}
v &=   \frac{\partial H}{\partial p} , &
f &= - \frac{\partial H}{\partial q} ,
\end{aligned}
```
initial conditions ``(q_{0}, p_{0})`` and the dynamical variables ``(q,p)``
taking values in ``\mathbb{R}^{d} \times \mathbb{R}^{d}``.

### Constructors

```julia
HODEProblem(v, f, poisson, hamiltonian, tspan, tstep, ics; kwargs...)
HODEProblem(v, f, poisson, hamiltonian, tspan, tstep, q₀::State, p₀::State; kwargs...)
```
where `ics` is a `NamedTuple` with entries `q` and `p`.

### Keyword arguments:

* `invariants = NullInvariants()`
* `parameters = NullParameters()`
* `periodicity = NullPeriodicity()`

"""
const HODEProblem = GeometricProblem{HODE}

function HODEProblem(v, f, poisson, hamiltonian, tspan, tstep, ics::NamedTuple; invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity())
    equ = HODE(v, f, poisson, hamiltonian, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function HODEProblem(v, f, poisson, hamiltonian, tspan, tstep, q₀::State, p₀::State; kwargs...)
    ics = (q = q₀, p = p₀)
    HODEProblem(v, f, poisson, hamiltonian, tspan, tstep, ics; kwargs...)
end

@doc raw"""
`IODEProblem`: Implicit Ordinary Differential Equation Problem

Defines an implicit initial value problem
```math
\begin{aligned}
\dot{q} (t) &= v(t) , &
q(t_{0}) &= q_{0} , \\
\dot{p} (t) &= f(t, q(t), v(t)) , &
p(t_{0}) &= p_{0} , \\
p(t) &= ϑ(t, q(t), v(t))
\end{aligned}
```
with momentum defined by ``\vartheta``, force field ``f``, projection field ``g``
and initial conditions ``(q_{0}, p_{0}, \lambda_{0})``.
This is a special case of a differential algebraic equation with dynamical
variables ``(q,p)`` and algebraic variable ``v``
"""
const IODEProblem = GeometricProblem{IODE}

function IODEProblem(ϑ, f, g, tspan, tstep, ics::NamedTuple; invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity(), v̄ = _iode_default_v̄, f̄ = f)
    equ = IODE(ϑ, f, g, v̄, f̄, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function IODEProblem(ϑ, f, g, tspan, tstep, q₀::State, p₀::State, λ₀::State = zero(q₀); kwargs...)
    ics = (q = q₀, p = p₀, λ = λ₀)
    IODEProblem(ϑ, f, g, tspan, tstep, ics; kwargs...)
end

@doc raw"""
`LODEProblem`: Lagrangian Ordinary Differential Equation Problem

Defines an implicit initial value problem
```math
\begin{aligned}
\dot{q} (t) &= v(t) , &
q(t_{0}) &= q_{0} , \\
\dot{p} (t) &= f(t, q(t), v(t)) , &
p(t_{0}) &= p_{0} , \\
p(t) &= ϑ(t, q(t), v(t))
\end{aligned}
```
with momentum ``p`` and force field ``f``, given by
```math
\begin{aligned}
p &= \frac{\partial L}{\partial v} , &
f &= \frac{\partial L}{\partial q} ,
\end{aligned}
```
and initial conditions ``(q_{0}, p_{0})``.
This is a special case of a differential algebraic equation with dynamical
variables ``(q,p)`` and algebraic variable ``v``.
"""
const LODEProblem = GeometricProblem{LODE}

function LODEProblem(ϑ, f, g, ω, l, tspan, tstep, ics::NamedTuple; invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity(), v̄ = _lode_default_v̄, f̄ = f)
    equ = LODE(ϑ, f, g, ω, v̄, f̄, l, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function LODEProblem(ϑ, f, g, ω, l, tspan, tstep, q₀::State, p₀::State, λ₀::State = zero(q₀); kwargs...)
    ics = (q = q₀, p = p₀, λ = λ₀)
    LODEProblem(ϑ, f, g, ω, l, tspan, tstep, ics; kwargs...)
end

@doc raw"""
`SODEProblem`: Split Ordinary Differential Equation Problem

Defines an initial value problem
```math
\dot{q} (t) = v(t, q(t)) , \qquad q(t_{0}) = q_{0} ,
```
with vector field ``v`` and initial condition ``q_{0}``. Here, the vector field
``v`` is given as a sum of vector fields
```math
v (t) = v_1 (t) + ... + v_r (t) .
```

### Fields

* `equation`: reference to the parent equation object
* `functions`: all functions (e.g. vector fields) provided by the equation
* `tspan`: time span for problem `(t₀,t₁)`
* `tstep`: time step to be used in simulation
* `ics`: initial condition (NamedTuple containing the field `q`)
* `parameters`: either a `NamedTuple` containing the equation's parameters or `nothing`

The functions `v_i` providing the vector field must have the interface
```julia
    function v_i(t, q, v, params)
        v[1] = ...
        v[2] = ...
        ...
    end
```
and the functions `q_i` providing the solutions must have the interface
```julia
    function q_i(t, q₀, q₁, h, params))
        q₁[1] = q₀[1] + ...
        q₁[2] = q₀[2] + ...
        ...
    end
```
where `t` is the current time, `q₀` is the current solution vector, `q₁` is the
new solution vector which holds the result of computing one substep with the
vector field ``v_i`` on `t` and `q₀`, and `h` is the (sub-)timestep to compute
the update for.

The fact that the function `v` returns the solution and not just the vector
field for each substep increases the flexibility for the use of splitting
methods, e.g., it allows to use another integrator for solving substeps.

### Constructors

```julia
SODE(v, q, t₀, q₀, invariants, parameters, periodicity)

SODE(v, q::Union{Tuple,Nothing}, t₀::Real, q₀::StateVector; kwargs...)
SODE(v, q::Union{Tuple,Nothing}, t₀::Real, q₀::State; kwargs...)
SODE(v, q::Union{Tuple,Nothing}, q₀::StateVector; kwargs...)
SODE(v, q::Union{Tuple,Nothing}, q₀::State; kwargs...)

SODE(v, t₀::Real, q₀::StateVector; kwargs...)
SODE(v, t₀::Real, q₀::State; kwargs...)
SODE(v, q₀::StateVector; kwargs...)
SODE(v, q₀::State; kwargs...)
```

"""
const SODEProblem = GeometricProblem{SODE}

function SODEProblem(v::Tuple, q::Union{Tuple,Nothing}, tspan, tstep, ics::NamedTuple; invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity())
    equ = SODE(v, q, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function SODEProblem(v::Tuple, q::Union{Tuple,Nothing}, tspan, tstep, q₀::State; kwargs...)
    ics = (q = q₀,)
    SODEProblem(v, q, tspan, tstep, ics; kwargs...)
end

function SODEProblem(v, tspan, tstep, ics::NamedTuple; kwargs...)
    SODEProblem(v, nothing, tspan, tstep, ics; kwargs...)
end

function SODEProblem(v, tspan, tstep, q₀::State; kwargs...)
    ics = (q = q₀,)
    SODEProblem(v, tspan, tstep, ics; kwargs...)
end

@doc raw"""
`DAEProblem`: Differential Algebraic Equation Problem

Defines a differential algebraic initial value problem
```math
\begin{aligned}
\dot{q} (t) &= v(t, q(t)) + u(t, q(t), \lambda(t)) , & q(t_{0}) &= q_{0} , \\
0 &= \phi (t, q(t), \lambda(t)) , & \lambda(t_{0}) &= \lambda_{0} ,
\end{aligned}
```
with vector field ``v``, projection ``u``, algebraic constraint ``\phi=0``,
and initial conditions ``q_{0}`` and ``\lambda_{0}``.
"""
const DAEProblem = GeometricProblem{DAE}

function DAEProblem(v, u, ϕ, ū, ψ, tspan, tstep, ics::NamedTuple; v̄ = v, invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity())
    equ = DAE(v, u, ϕ, ū, ψ, v̄, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function DAEProblem(v, u, ϕ, ū, ψ, tspan, tstep, q₀::State, λ₀::State, μ₀::State = zero(λ₀); kwargs...)
    ics = (q = q₀, λ = λ₀, μ = μ₀)
    DAEProblem(v, u, ϕ, ū, ψ, tspan, tstep, ics; kwargs...)
end

function DAEProblem(v, u, ϕ, tspan, tstep, ics::NamedTuple; kwargs...)
    DAEProblem(v, u, ϕ, nothing, nothing, tspan, tstep, ics; kwargs...)
end

function DAEProblem(v, u, ϕ, tspan, tstep, q₀::State, λ₀::State; kwargs...)
    ics = (q = q₀, λ = λ₀)
    DAEProblem(v, u, ϕ, tspan, tstep, ics; kwargs...)
end

@doc raw"""
`PDAEProblem`: Partitioned Differential Algebraic Equation Problem

Defines a partitioned differential algebraic initial value problem
```math
\begin{aligned}
\dot{q} (t) &= v(t, q(t), p(t)) + u(t, q(t), p(t), \lambda(t)) , & q(t_{0}) &= q_{0} , \\
\dot{p} (t) &= f(t, q(t), p(t)) + g(t, q(t), p(t), \lambda(t)) , & p(t_{0}) &= p_{0} , \\
0 &= \phi (t, q(t), p(t), \lambda(t)) , & \lambda(t_{0}) &= \lambda_{0} ,
\end{aligned}
```
with vector fields ``v`` and ``f``, projection ``u`` and ``g``,
algebraic constraint ``\phi=0``, and initial conditions
``(q_{0}, p_{0})`` and ``\lambda_{0}``.
"""
const PDAEProblem = GeometricProblem{PDAE}

function PDAEProblem(v, f, u, g, ϕ, ū, ḡ, ψ, tspan, tstep, ics::NamedTuple; v̄ = v, f̄ = f, invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity())
    equ = PDAE(v, f, u, g, ϕ, ū, ḡ, ψ, v̄, f̄, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function PDAEProblem(v, f, u, g, ϕ, ū, ḡ, ψ, tspan, tstep, q₀::State, p₀::State, λ₀::State, μ₀::State = zero(λ₀); kwargs...)
    ics = (q = q₀, p = p₀, λ = λ₀, μ = μ₀)
    PDAEProblem(v, f, u, g, ϕ, ū, ḡ, ψ, tspan, tstep, ics; kwargs...)
end

function PDAEProblem(v, f, u, g, ϕ, tspan, tstep, ics::NamedTuple; kwargs...)
    PDAEProblem(v, f, u, g, ϕ, nothing, nothing, nothing, tspan, tstep, ics; kwargs...)
end

function PDAEProblem(v, f, u, g, ϕ, tspan, tstep, q₀::State, p₀::State, λ₀::State; kwargs...)
    ics = (q = q₀, p = p₀, λ = λ₀)
    PDAEProblem(v, f, u, g, ϕ, tspan, tstep, ics; kwargs...)
end

@doc raw"""
`HDAE`: Hamiltonian Differential Algebraic Equation

Defines a Hamiltonian differential algebraic initial value problem, that is
a canonical Hamiltonian system of equations subject to Dirac constraints,
```math
\begin{aligned}
\dot{q} (t) &= v(t, q(t), p(t)) + u(t, q(t), p(t), \lambda(t)) + \bar{g}(t, q(t), p(t), \lambda(t), \gamma(t)) , & q(t_{0}) &= q_{0} , \\
\dot{p} (t) &= f(t, q(t), p(t)) + g(t, q(t), p(t), \lambda(t)) + \bar{f}(t, q(t), p(t), \lambda(t), \gamma(t)) , & p(t_{0}) &= p_{0} , \\
0 &= \phi (t, q(t), p(t)) , \\
0 &= \psi (t, q(t), p(t), \dot{q}(t), \dot{p}(t)) ,
\end{aligned}
```
with vector fields ``v``, ``u``, ``\bar{u}`` and ``f``, ``g``, ``\bar{g}``,
primary constraint ``\phi(q,p)=0`` and secondary constraint ``\psi(q,p,\lambda)=0``,
and initial conditions ``(q_{0}, p_{0})``.
"""
const HDAEProblem = GeometricProblem{HDAE}

function HDAEProblem(v, f, u, g, ϕ, ū, ḡ, ψ, poisson, hamiltonian, tspan, tstep, ics::NamedTuple; v̄ = v, f̄ = f, invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity())
    equ = HDAE(v, f, u, g, ϕ, ū, ḡ, ψ, v̄, f̄, poisson, hamiltonian, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function HDAEProblem(v, f, u, g, ϕ, ū, ḡ, ψ, poisson, hamiltonian, tspan, tstep, q₀::State, p₀::State, λ₀::State, μ₀::State = zero(λ₀); kwargs...)
    ics = (q = q₀, p = p₀, λ = λ₀, μ = μ₀)
    HDAEProblem(v, f, u, g, ϕ, ū, ḡ, ψ, poisson, hamiltonian, tspan, tstep, ics; kwargs...)
end

function HDAEProblem(v, f, u, g, ϕ, poisson, hamiltonian, tspan, tstep, ics::NamedTuple; kwargs...)
    HDAEProblem(v, f, u, g, ϕ, nothing, nothing, nothing, poisson, hamiltonian, tspan, tstep, ics; kwargs...)
end

function HDAEProblem(v, f, u, g, ϕ, poisson, hamiltonian, tspan, tstep, q₀::State, p₀::State, λ₀::State; kwargs...)
    ics = (q = q₀, p = p₀, λ = λ₀)
    HDAEProblem(v, f, u, g, ϕ, poisson, hamiltonian, tspan, tstep, ics; kwargs...)
end

@doc raw"""
`IDAEProblem`: Implicit Differential Algebraic Equation Problem

Defines an implicit differential algebraic initial value problem
```math
\begin{aligned}
\dot{q} (t) &= v(t) + u(t, q(t), p(t), \lambda(t)) , & q(t_{0}) &= q_{0} , \\
\dot{p} (t) &= f(t, q(t), v(t)) + g(t, q(t), p(t), \lambda(t)) , & p(t_{0}) &= p_{0} , \\
p(t) &= \vartheta(t, q(t), v(t)) , && \\
0 &= \phi (t, q(t), p(t)) , & \lambda(t_{0}) &= \lambda_{0} ,
\end{aligned}
```
with force field ``f``, the momentum defined by ``p``, projection ``u`` and ``g``,
algebraic constraint ``\phi=0``, and initial conditions
``(q_{0}, p_{0})`` and ``\lambda_{0}``.
"""
const IDAEProblem = GeometricProblem{IDAE}

function IDAEProblem(ϑ, f, u, g, ϕ, ū, ḡ, ψ, tspan, tstep, ics::NamedTuple; v̄ = _idae_default_v̄, f̄ = f, invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity())
    equ = IDAE(ϑ, f, u, g, ϕ, ū, ḡ, ψ, v̄, f̄, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function IDAEProblem(ϑ, f, u, g, ϕ, ū, ḡ, ψ, tspan, tstep, q₀::State, p₀::State, λ₀::State, μ₀::State = zero(λ₀); kwargs...)
    ics = (q = q₀, p = p₀, λ = λ₀, μ = μ₀)
    IDAEProblem(ϑ, f, u, g, ϕ, ū, ḡ, ψ, tspan, tstep, ics; kwargs...)
end

function IDAEProblem(ϑ, f, u, g, ϕ, tspan, tstep, ics::NamedTuple; kwargs...)
    IDAEProblem(ϑ, f, u, g, ϕ, nothing, nothing, nothing, tspan, tstep, ics; kwargs...)
end

function IDAEProblem(ϑ, f, u, g, ϕ, tspan, tstep, q₀::State, p₀::State, λ₀::State; kwargs...)
    ics = (q = q₀, p = p₀, λ = λ₀)
    IDAEProblem(ϑ, f, u, g, ϕ, tspan, tstep, ics; kwargs...)
end

@doc raw"""
`LDAEProblem`: Lagrangian Differential Algebraic Equation Problem

Defines a Lagrangian differential algebraic initial value problem, that is
a special implicit initial value problem
```math
\begin{aligned}
\dot{q} (t) &= v(t) + \lambda(t), &
q(t_{0}) &= q_{0} , \\
\dot{p} (t) &= f(t, q(t), v(t)) + g(t, q(t), \lambda(t)) + \bar{g} (t, q(t), \mu(t)) , &
p(t_{0}) &= p_{0} , \\
p(t) &= ϑ(t, q(t), v(t)) , \\
0 &= \phi (t, q(t), p(t)) , \\
0 &= \psi (t, q(t), p(t), \dot{q}(t), \dot{p}(t)) ,
\end{aligned}
```
with vector field ``f``, the momentum defined by ``p``, and initial conditions
``(q_{0}, p_{0}, \lambda_{0})``.
This is a special case of a differential algebraic equation with dynamical
variables ``(q,p)`` and algebraic variables ``v``, ``\lambda`` and ``\mu``.
"""
const LDAEProblem = GeometricProblem{LDAE}

function LDAEProblem(ϑ, f, u, g, ϕ, ū, ḡ, ψ, ω, lagrangian, tspan, tstep, ics::NamedTuple; v̄ = _ldae_default_v̄, f̄ = f, invariants = NullInvariants(), parameters = NullParameters(), periodicity = NullPeriodicity())
    equ = LDAE(ϑ, f, u, g, ϕ, ū, ḡ, ψ, ω, v̄, f̄, lagrangian, invariants, parameter_types(parameters), periodicity)
    GeometricProblem(equ, tspan, tstep, ics, parameters)
end

function LDAEProblem(ϑ, f, u, g, ϕ, ū, ḡ, ψ, ω, lagrangian, tspan, tstep, q₀::State, p₀::State, λ₀::State, μ₀::State = zero(λ₀); kwargs...)
    ics = (q = q₀, p = p₀, λ = λ₀, μ = μ₀)
    LDAEProblem(ϑ, f, u, g, ϕ, ū, ḡ, ψ, ω, lagrangian, tspan, tstep, ics; kwargs...)
end

function LDAEProblem(ϑ, f, u, g, ϕ, ω, lagrangian, tspan, tstep, ics::NamedTuple; kwargs...)
    LDAEProblem(ϑ, f, u, g, ϕ, nothing, nothing, nothing, ω, lagrangian, tspan, tstep, ics; kwargs...)
end

function LDAEProblem(ϑ, f, u, g, ϕ, ω, lagrangian, tspan, tstep, q₀::State, p₀::State, λ₀::State; kwargs...)
    ics = (q = q₀, p = p₀, λ = λ₀)
    LDAEProblem(ϑ, f, u, g, ϕ, ω, lagrangian, tspan, tstep, ics; kwargs...)
end

"""

"""
const SPDAEProblem = GeometricProblem{SPDAE}

"""

"""
const SDEProblem = GeometricProblem{SDE}

"""

"""
const PSDEProblem = GeometricProblem{PSDE}

"""

"""
const SPSDEProblem = GeometricProblem{SPSDE}


text:
"""
# module CAPIs

# Examples

```jldoctest
julia>
```
"""
module CAPIs

using CoordinateTransformations
using DataStructures: counter
using Setfield: @set

using JuSpglib.DataStructure: Cell

export get_symmetry, get_international, get_schoenflies,
    standardize_cell, find_primitive, refine_cell,
    niggli_reduce, delaunay_reduce

include(joinpath(dirname(@__FILE__), "..", "deps", "deps.jl"))

function getfields(obj, fields...)
    Tuple(getfield(obj, name) for name in fields)
end

function get_ccell(cell::Cell)::Cell
    lattice, positions, types = getfields(cell, :lattice, :positions, :numbers)
    clattice = convert(Matrix{Cdouble}, lattice)
    cpositions = convert(Matrix{Cdouble}, positions)
    cnumbers = convert(Vector{Cint}, [repeat([i], v) for (i, v) in (enumerate ∘ values ∘ counter)(types)] |> Iterators.flatten |> collect)
    return Cell(clattice, cpositions, cnumbers)
end

cchars_to_string(s::Vector{Cchar}) = map(Char, s) |> join |> x -> split(x, "\0") |> first

function get_symmetry(cell::Cell; symprec::Real = 1e-8)
    size(cell.positions, 2) != length(cell.numbers) && throw(DimensionMismatch("The number of positions and atomic types do not match!"))
    size(cell.positions, 1) != 3 && error("Operations in 3D space is supported here!")

    maxsize = 52
    rotations = Array{Cint}(undef, 3, 3, maxsize)
    translations = Array{Cdouble}(undef, 3, maxsize)

    ccell = get_ccell(cell)
    clattice, cpositions, cnumbers = getfields(ccell, :lattice, :positions, :numbers)

    numops = ccall((:spg_get_symmetry, spglib), Cint,
        (Ptr{Cint}, Ptr{Cdouble}, Cint, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cint}, Cint, Cdouble),
        rotations, translations, maxsize, clattice, cpositions, cnumbers, length(cnumbers), symprec)
    numops == 0 && error("Could not determine symmetries!")

    [AffineMap(transpose(rotations[:, :, i]), translations[:, i]) for i in 1:numops]
end

function get_international(cell::Cell; symprec::Real = 1e-8)
    result = zeros(Cchar, 11)

    ccell = get_ccell(cell)
    clattice, cpositions, cnumbers = getfields(ccell, :lattice, :positions, :numbers)

    numops = ccall((:spg_get_international, spglib), Cint,
        (Ptr{Cchar}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cint}, Cint, Cdouble),
        result, clattice, cpositions, cnumbers, length(cnumbers), symprec)
    numops == 0 && error("Could not determine the international symbol!")

    cchars_to_string(result)
end

function get_schoenflies(cell::Cell; symprec::Real = 1e-8)
    result = zeros(Cchar, 11)

    ccell = get_ccell(cell)
    clattice, cpositions, cnumbers = getfields(ccell, :lattice, :positions, :numbers)

    numops = ccall((:spg_get_schoenflies, spglib), Cint,
        (Ptr{Cchar}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cint}, Cint, Cdouble),
        result, clattice, cpositions, cnumbers, length(cnumbers), symprec)
    numops == 0 && error("Could not determine the Schoenflies symbol!")

    cchars_to_string(result)
end

function standardize_cell(cell::Cell, to_primitive::Bool = false, no_idealize::Bool = false, symprec::Real = 1e-5)
    ccell = get_ccell(cell)
    clattice, cpositions, cnumbers = getfields(ccell, :lattice, :positions, :numbers)
    to_primitive, no_idealize = map(x -> convert(Cint, x), (to_primitive, no_idealize))

    atoms_amount = ccall((:spg_standardize_cell, spglib), Cint,
        (Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cint}, Cint, Cint, Cint, Cdouble),
        clattice, cpositions, cnumbers, length(cnumbers), to_primitive, no_idealize, symprec)
    atoms_amount == 0 && error("Standardizing cell failed!")

    Cell(clattice, cpositions, cnumbers)
end

find_primitive(cell::Cell; symprec::Real = 1e-5) = standardize_cell(cell; to_primitive = true, no_idealize = false, symprec = symprec)

refine_cell(cell::Cell; symprec::Real = 1e-5) = standardize_cell(cell; to_primitive = false, no_idealize = false, symprec = symprec)

function niggli_reduce(cell::Cell, symprec::Real = 1e-5)
    ccell = get_ccell(cell)
    clattice = getfield(ccell, :lattice)

    ret = ccall((:spg_niggli_reduce, spglib), Cint, (Ptr{Cdouble}, Cdouble), clattice, symprec)
    ret == 0 && error("Niggli reduce failed!")

    @set cell.lattice = clattice
end

function delaunay_reduce(cell::Cell, symprec::Real = 1e-5)
    ccell = get_ccell(cell)
    clattice = getfield(ccell, :lattice)

    ret = ccall((:spg_niggli_reduce, spglib), Cint, (Ptr{Cdouble}, Cdouble), clattice, symprec)
    ret == 0 && error("Delaunay reduce failed!")

    @set cell.lattice = clattice
end

function get_ir_reciprocal_mesh(cell::Cell,
                                grid::Vector{T},
                                shift::Vector{T} = [0, 0, 0],
                                is_time_reversal::Bool = true,
                                symprec::Real = 1e-5) where {T <: Integer}
    all(x -> x in (zero(T), one(T)), shift) || throw(ArgumentError("The shift can be only a vector of ones or zeros!"))

    qpoints_amount = prod(grid)
    grid_address = Array{Cint}(undef, qpoints_amount, 3)
    mapping = Array{Cint}(undef, qpoints_amount)
    ccell = get_ccell(cell)
    clattice, cpositions, cnumbers = getfields(ccell, :lattice, :positions, :numbers)

    ret = ccall((:spg_get_ir_reciprocal_mesh, spglib), Cint,
        (Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Cint, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cint}, Cint, Cdouble),
        grid_address, mapping, grid, shift, is_time_reversal, clattice, cpositions, cnumbers, length(cnumbers), symprec)
    ret != qpoints_amount && error("Something wrong happens when finding mesh!")

    mapping, grid_address
end

function get_stabilized_reciprocal_mesh(rotations::Vector{Matrix{T}},
                                        grid::Vector{T},
                                        shift::Vector{T} = [0, 0, 0],
                                        qpoints::Vector{} = nothing,
                                        is_time_reversal::Bool = true) where {T <: Integer}
    all(x -> x in (zero(T), one(T)), shift) || throw(ArgumentError("The shift can be only a vector of ones or zeros!"))

    qpoints_amount = prod(grid)
    grid_address = Array{Cint}(undef, qpoints_amount, 3)
    mapping_table = Array{Cint}(undef, qpoints_amount)
    qpoints == nothing ? qpoints = Float64[0, 0, 0] : qpoints = Vector(qpoints)

    ret = ccall((:spg_get_stabilized_reciprocal_mesh, spglib), Cint,
        (Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Cint, Cint, Ptr{Cint}, Cint, Ptr{Cint}),
        grid_address, mapping_table, grid, shift, is_time_reversal, length(rotations), rotations, length(qpoints), qpoints)
    ret != qpoints_amount && error("Something wrong happens when finding mesh!")

    mapping_table, grid_address
end

end

ext: jl


text:
using MyApp

push!(ARGS, "arg")
MyApp.julia_main()

using Example
Example.hello("PackageCompiler")

using Crayons

# It is ok to use stdlibs that are not in the project dependencies
using Test
@test 1==1


text:
# Automatically generated using Clang.jl

# Skipping MacroDefinition: mtIdPropertyDef ( fName , objT , propertyT , propertyN ) MT_EXPORT Mt ## propertyT fName ( Mt ## objT * obj ) ;
# Skipping MacroDefinition: mtIdPropertyImpl ( fName , objT , propertyT , propertyN ) MT_EXPORT Mt ## propertyT fName ( Mt ## objT * obj ) { return [ ( id < MTL ## objT > ) obj propertyN ] ; }
# Skipping MacroDefinition: MT_EXPORT __attribute__ ( ( visibility ( "default" ) ) )
# Skipping MacroDefinition: MT_HIDE __attribute__ ( ( visibility ( "hidden" ) ) )
# Skipping MacroDefinition: MT_INLINE inline __attribute ( ( always_inline ) )
# Skipping MacroDefinition: MT_ALIGN ( X ) __attribute ( ( aligned ( X ) ) )

const NsUInteger = Culong
const NsInteger = Clong
const CfTimeInterval = Cdouble

struct NsRange
    location::NsUInteger
    length::NsUInteger
end

const NsError = Cvoid

struct NsDictionaryStringString
    keys::Ptr{Cstring}
    values::Ptr{Cstring}
end

@cenum MtPrimitiveType::UInt32 begin
    MtPrimitiveTypePoint = 0
    MtPrimitiveTypeLine = 1
    MtPrimitiveTypeLineStrip = 2
    MtPrimitiveTypeTriangle = 3
    MtPrimitiveTypeTriangleStrip = 4
end

@cenum MtVisibilityResultMode::UInt32 begin
    MtVisibilityResultModeDisabled = 0
    MtVisibilityResultModeBoolean = 1
    MtVisibilityResultModeCounting = 2
end

struct MtScissorRect
    x::UInt32
    y::UInt32
    width::UInt32
    height::UInt32
end

struct MtViewport
    originX::Cdouble
    originY::Cdouble
    width::Cdouble
    height::Cdouble
    znear::Cdouble
    zfar::Cdouble
end

@cenum MtCullMode::UInt32 begin
    MtCullModeNone = 0
    MtCullModeFront = 1
    MtCullModeBack = 2
end

@cenum MtWinding::UInt32 begin
    MtWindingClockwise = 0
    MtWindingCounterClockwise = 1
end

@cenum MtDepthClipMode::UInt32 begin
    MtDepthClipModeClip = 0
    MtDepthClipModeClamp = 1
end

@cenum MtTriangleFillMode::UInt32 begin
    MtTriangleFillModeFill = 0
    MtTriangleFillModeLines = 1
end

struct MtDrawPrimitivesIndirectArguments
    vertexCount::UInt32
    instanceCount::UInt32
    vertexStart::UInt32
    baseInstance::UInt32
end

struct MtDrawIndexedPrimitivesIndirectArguments
    indexCount::UInt32
    instanceCount::UInt32
    indexStart::UInt32
    baseVertex::Int32
    baseInstance::UInt32
end

struct MtDrawPatchIndirectArguments
    patchCount::UInt32
    instanceCount::UInt32
    patchStart::UInt32
    baseInstance::UInt32
end

struct MtQuadTessellationFactorsHalf
    edgeTessellationFactor::NTuple{4, UInt16}
    insideTessellationFactor::NTuple{2, UInt16}
end

struct MtTriangleTessellationFactorsHalf
    edgeTessellationFactor::NTuple{3, UInt16}
    insideTessellationFactor::UInt16
end

@cenum MtRenderStages::UInt32 begin
    MtRenderStageVertex = 1
    MtRenderStageFragment = 2
end

@cenum MtLoadAction::UInt32 begin
    MtLoadActionDontCare = 0
    MtLoadActionLoad = 1
    MtLoadActionClear = 2
end

@cenum MtIndexType::UInt32 begin
    MtIndexTypeUInt16 = 0
    MtIndexTypeUInt32 = 1
end

@cenum MtStoreAction::UInt32 begin
    MtStoreActionDontCare = 0
    MtStoreActionStore = 1
    MtStoreActionMultisampleResolve = 2
    MtStoreActionStoreAndMultisampleResolve = 3
    MtStoreActionUnknown = 4
    MtStoreActionCustomSampleDepthStore = 5
end

@cenum MtDeviceLocation::UInt32 begin
    MtDeviceLocationBuiltIn = 0
    MtDeviceLocationSlot = 1
    MtDeviceLocationExternal = 2
    MtDeviceLocationUnspecified = 100
end

@cenum MtLanguageVersion::UInt32 begin
    MtLanguageVersion1_0 = 65536
    MtLanguageVersion1_1 = 65537
    MtLanguageVersion1_2 = 65538
    MtLanguageVersion2_0 = 131072
    MtLanguageVersion2_1 = 131073
    MtLanguageVersion2_2 = 131074
end

@cenum MtFunctionType::UInt32 begin
    MtFunctionTypeVertex = 1
    MtFunctionTypeFragment = 2
    MtFunctionTypeKernel = 3
end

@cenum MtDispatchType::UInt32 begin
    MtDispatchTypeSerial = 0
    MtDispatchTypeConcurrent = 1
end

@cenum MtCommandBufferStatus::UInt32 begin
    MtCommandBufferStatusNotEnqueued = 0
    MtCommandBufferStatusEnqueued = 1
    MtCommandBufferStatusCommitted = 2
    MtCommandBufferStatusScheduled = 3
    MtCommandBufferStatusCompleted = 4
    MtCommandBufferStatusError = 5
end

@cenum MtResourceUsage::UInt32 begin
    MtResourceUsageRead = 1
    MtResourceUsageWrite = 2
    MtResourceUsageSample = 4
end

@cenum MtGPUFamily::UInt32 begin
    MtGPUFamilyApple1 = 1001
    MtGPUFamilyApple2 = 1002
    MtGPUFamilyApple3 = 1003
    MtGPUFamilyApple4 = 1004
    MtGPUFamilyApple5 = 1005
    MtGPUFamilyMac1 = 2001
    MtGPUFamilyMac2 = 2002
    MtGPUFamilyCommon1 = 3001
    MtGPUFamilyCommon2 = 3002
    MtGPUFamilyCommon3 = 3003
    MtGPUFamilyMacCatalyst1 = 4001
    MtGPUFamilyMacCatalyst2 = 4002
end

@cenum MtFeatureSet::UInt32 begin
    MtFeatureSet_macOS_GPUFamily1_v1 = 10000
    MtFeatureSet_OSX_GPUFamily1_v1 = 10000
    MtFeatureSet_macOS_GPUFamily1_v2 = 10001
    MtFeatureSet_OSX_GPUFamily1_v2 = 10001
    MtFeatureSet_macOS_ReadWriteTextureTier2 = 10002
    MtFeatureSet_OSX_ReadWriteTextureTier2 = 10002
    MtFeatureSet_macOS_GPUFamily1_v3 = 10003
    MtFeatureSet_macOS_GPUFamily1_v4 = 10004
    MtFeatureSet_macOS_GPUFamily2_v1 = 10005
end

@cenum MtPurgeableState::UInt32 begin
    MtPurgeableStateKeepCurrent = 1
    MtPurgeableStateNonVolatile = 2
    MtPurgeableStateVolatile = 3
    MtPurgeableStateEmpty = 4
end

@cenum MtCommandBufferError::UInt32 begin
    MtCommandBufferErrorNone = 0
    MtCommandBufferErrorInternal = 1
    MtCommandBufferErrorTimeout = 2
    MtCommandBufferErrorPageFault = 3
    MtCommandBufferErrorBlacklisted = 4
    MtCommandBufferErrorNotPermitted = 7
    MtCommandBufferErrorOutOfMemory = 8
    MtCommandBufferErrorInvalidResource = 9
    MtCommandBufferErrorMemoryless = 10
    MtCommandBufferErrorDeviceRemoved = 11
end

@cenum MtHeapType::UInt32 begin
    MtHeapTypeAutomatic = 0
    MtHeapTypePlacement = 1
end

@cenum MtBlitOption::UInt32 begin
    MtBlitOptionNone = 0
    MtBlitOptionDepthFromDepthStencil = 1
    MtBlitOptionStencilFromDepthStencil = 2
end

@cenum MtLibraryError::UInt32 begin
    MtLibraryErrorUnsupported = 1
    MtLibraryErrorInternal = 2
    MtLibraryErrorCompileFailure = 3
    MtLibraryErrorCompileWarning = 4
    MtLibraryErrorFunctionNotFound = 5
    MtLibraryErrorFileNotFound = 6
end

@cenum MtBarrierScope::UInt32 begin
    MtBarrierScopeBuffers = 1
    MtBarrierScopeTextures = 2
    MtBarrierScopeRenderTargets = 4
end

@cenum MtIndirectCommandType::UInt32 begin
    MIndirectCommandTypeDraw = 1
    MIndirectCommandTypeDrawIndexed = 2
    MIndirectCommandTypeDrawPatches = 4
    MIndirectCommandTypeDrawIndexedPatches = 8
end

@cenum MtDataType::UInt32 begin
    MtDataTypeNone = 0
    MtDataTypeStruct = 1
    MtDataTypeArray = 2
    MtDataTypeFloat = 3
    MtDataTypeFloat2 = 4
    MtDataTypeFloat3 = 5
    MtDataTypeFloat4 = 6
    MtDataTypeFloat2x2 = 7
    MtDataTypeFloat2x3 = 8
    MtDataTypeFloat2x4 = 9
    MtDataTypeFloat3x2 = 10
    MtDataTypeFloat3x3 = 11
    MtDataTypeFloat3x4 = 12
    MtDataTypeFloat4x2 = 13
    MtDataTypeFloat4x3 = 14
    MtDataTypeFloat4x4 = 15
    MtDataTypeHalf = 16
    MtDataTypeHalf2 = 17
    MtDataTypeHalf3 = 18
    MtDataTypeHalf4 = 19
    MtDataTypeHalf2x2 = 20
    MtDataTypeHalf2x3 = 21
    MtDataTypeHalf2x4 = 22
    MtDataTypeHalf3x2 = 23
    MtDataTypeHalf3x3 = 24
    MtDataTypeHalf3x4 = 25
    MtDataTypeHalf4x2 = 26
    MtDataTypeHalf4x3 = 27
    MtDataTypeHalf4x4 = 28
    MtDataTypeInt = 29
    MtDataTypeInt2 = 30
    MtDataTypeInt3 = 31
    MtDataTypeInt4 = 32
    MtDataTypeUInt = 33
    MtDataTypeUInt2 = 34
    MtDataTypeUInt3 = 35
    MtDataTypeUInt4 = 36
    MtDataTypeShort = 37
    MtDataTypeShort2 = 38
    MtDataTypeShort3 = 39
    MtDataTypeShort4 = 40
    MtDataTypeUShort = 41
    MtDataTypeUShort2 = 42
    MtDataTypeUShort3 = 43
    MtDataTypeUShort4 = 44
    MtDataTypeChar = 45
    MtDataTypeChar2 = 46
    MtDataTypeChar3 = 47
    MtDataTypeChar4 = 48
    MtDataTypeUChar = 49
    MtDataTypeUChar2 = 50
    MtDataTypeUChar3 = 51
    MtDataTypeUChar4 = 52
    MtDataTypeBool = 53
    MtDataTypeBool2 = 54
    MtDataTypeBool3 = 55
    MtDataTypeBool4 = 56
    MtDataTypeTexture = 58
    MtDataTypeSampler = 59
    MtDataTypePointer = 60
    MtDataTypeRenderPipeline = 78
    MtDataTypeIndirectCommandBuffer = 80
end

@cenum MtArgumentAccess::UInt32 begin
    MtArgumentAccessReadOnly = 0
    MtArgumentAccessReadWrite = 1
    MtArgumentAccessWriteOnly = 2
end

@cenum MtArgumentBuffersTier::UInt32 begin
    MtArgumentBuffersTier1 = 0
    MtArgumentBuffersTier2 = 1
end

@cenum MtTextureType::UInt32 begin
    MtTextureType1D = 0
    MtTextureType1DArray = 1
    MtTextureType2D = 2
    MtTextureType2DArray = 3
    MtTextureType2DMultisample = 4
    MtTextureTypeCube = 5
    MtTextureTypeCubeArray = 6
    MtTextureType3D = 7
    MtTextureType2DMultisampleArray = 8
    MtTextureTypeTextureBuffer = 9
end

@cenum MtTextureSwizzle::UInt32 begin
    MtTextureSwizzleZero = 0
    MtTextureSwizzleOne = 1
    MtTextureSwizzleRed = 2
    MtTextureSwizzleGreen = 3
    MtTextureSwizzleBlue = 4
    MtTextureSwizzleAlpha = 5
end

@cenum MtAttributeFormat::UInt32 begin
    MtAttributeFormatInvalid = 0
    MtAttributeFormatUChar2 = 1
    MtAttributeFormatUChar3 = 2
    MtAttributeFormatUChar4 = 3
    MtAttributeFormatChar2 = 4
    MtAttributeFormatChar3 = 5
    MtAttributeFormatChar4 = 6
    MtAttributeFormatUChar2Normalized = 7
    MtAttributeFormatUChar3Normalized = 8
    MtAttributeFormatUChar4Normalized = 9
    MtAttributeFormatChar2Normalized = 10
    MtAttributeFormatChar3Normalized = 11
    MtAttributeFormatChar4Normalized = 12
    MtAttributeFormatUShort2 = 13
    MtAttributeFormatUShort3 = 14
    MtAttributeFormatUShort4 = 15
    MtAttributeFormatShort2 = 16
    MtAttributeFormatShort3 = 17
    MtAttributeFormatShort4 = 18
    MtAttributeFormatUShort2Normalized = 19
    MtAttributeFormatUShort3Normalized = 20
    MtAttributeFormatUShort4Normalized = 21
    MtAttributeFormatShort2Normalized = 22
    MtAttributeFormatShort3Normalized = 23
    MtAttributeFormatShort4Normalized = 24
    MtAttributeFormatHalf2 = 25
    MtAttributeFormatHalf3 = 26
    MtAttributeFormatHalf4 = 27
    MtAttributeFormatFloat = 28
    MtAttributeFormatFloat2 = 29
    MtAttributeFormatFloat3 = 30
    MtAttributeFormatFloat4 = 31
    MtAttributeFormatInt = 32
    MtAttributeFormatInt2 = 33
    MtAttributeFormatInt3 = 34
    MtAttributeFormatInt4 = 35
    MtAttributeFormatUInt = 36
    MtAttributeFormatUInt2 = 37
    MtAttributeFormatUInt3 = 38
    MtAttributeFormatUInt4 = 39
    MtAttributeFormatInt1010102Normalized = 40
    MtAttributeFormatUInt1010102Normalized = 41
    MtAttributeFormatUChar4Normalized_BGRA = 42
    MtAttributeFormatUChar = 45
    MtAttributeFormatChar = 46
    MtAttributeFormatUCharNormalized = 47
    MtAttributeFormatCharNormalized = 48
    MtAttributeFormatUShort = 49
    MtAttributeFormatShort = 50
    MtAttributeFormatUShortNormalized = 51
    MtAttributeFormatShortNormalized = 52
    MtAttributeFormatHalf = 53
end

@cenum MtStepFunction::UInt32 begin
    MtStepFunctionConstant = 0
    MtStepFunctionPerVertex = 1
    MtStepFunctionPerInstance = 2
    MtStepFunctionPerPatch = 3
    MtStepFunctionPerPatchControlPoint = 4
    MtStepFunctionThreadPositionInGridX = 5
    MtStepFunctionThreadPositionInGridY = 6
    MtStepFunctionThreadPositionInGridXIndexed = 7
    MtStepFunctionThreadPositionInGridYIndexed = 8
end

@cenum MtPipelineOption::UInt32 begin
    MtPipelineOptionNone = 0
    MtPipelineOptionArgumentInfo = 1
    MtPipelineOptionBufferTypeInfo = 2
end

@cenum MtArgumentType::UInt32 begin
    MtArgumentTypeBuffer = 0
    MtArgumentTypeThreadgroupMemory = 1
    MtArgumentTypeTexture = 2
    MtArgumentTypeSampler = 3
end

struct MtSize
    width::NsUInteger
    height::NsUInteger
    depth::NsUInteger
end

struct MtOrigin
    x::NsUInteger
    y::NsUInteger
    z::NsUInteger
end

struct MtSizeAndAlign
    size::NsUInteger
    align::NsUInteger
end

const MtDevice = Cvoid
const MtRenderDesc = Cvoid
const MtRenderPipeline = Cvoid
const MtCommandQueue = Cvoid
const MtCommandEncoder = Cvoid
const MtBlitCommandEncoder = Cvoid
const MtLibrary = Cvoid
const MtRenderPassDesc = Cvoid
struct MtTexture end
const MtCommandBuffer = Cvoid
const MtDrawable = Cvoid
const MtVertexDescriptor = Cvoid
const MtTextureDescriptor = Cvoid
const MtIndirectCommandBufferDescriptor = Cvoid
const MtIndirectCommandBuffer = Cvoid
const MtIndirectComputeCommand = Cvoid
const MtIndirectRenderCommand = Cvoid
const MtDepthStencil = Cvoid
struct MtBuffer end
const MtCompileOptions = Cvoid
const MtFunction = Cvoid
const MtFunctionConstant = Cvoid
const MtFunctionConstantValues = Cvoid
const MtEvent = Cvoid
const MtSharedEvent = Cvoid
const MtSharedEventHandle = Cvoid
const MtFence = Cvoid
const MtSharedEventNotificationBlock = Cvoid
const MtCommandBufferHandlerFun = Ptr{Cvoid}
const MtSharedEventListener = Cvoid
struct MtResource end
const MtHeap = Cvoid
const MtHeapDescriptor = Cvoid
const MtAttribute = Cvoid
const MtVertexAttribute = Cvoid
const MtComputePipelineState = Cvoid
const MtSamplerState = Cvoid
const MtRenderCommandEncoder = Cvoid
const MtComputeCommandEncoder = Cvoid
const MtResourceStateCommandEncoder = Cvoid
const MtCounterSampleBuffer = Cvoid
const MtArgumentEncoder = Cvoid
const MtAutoreleasedArgument = Cvoid
const MtArgument = Cvoid
const MtArgumentDescriptor = Cvoid
const MtComputePipelineDescriptor = Cvoid
const MtPointerType = Cvoid
const MtArrayType = Cvoid
const MtStructType = Cvoid
const MtComputePipelineReflection = Cvoid
const MtRenderPipelineReflection = Cvoid

struct MtDispatchThreadgroupsIndirectArguments
    threadgroupsPerGrid::NTuple{3, UInt32}
end

struct MtStageInRegionIndirectArguments
    stageInOrigin::NTuple{3, UInt32}
    stageInSize::NTuple{3, UInt32}
end

struct MtRegion
    origin::MtOrigin
    size::MtSize
end

struct MtIndirectCommandBufferExecutionRange
    location::UInt32
    length::UInt32
end

struct MtTextureSwizzleChannels
    red::MtTextureSwizzle
    green::MtTextureSwizzle
    blue::MtTextureSwizzle
    alpha::MtTextureSwizzle
end

@cenum MtPixelFormat::UInt32 begin
    MtPixelFormatInvalid = 0
    MtPixelFormatA8Unorm = 1
    MtPixelFormatR8Unorm = 10
    MtPixelFormatR8Unorm_sRGB = 11
    MtPixelFormatR8Snorm = 12
    MtPixelFormatR8Uint = 13
    MtPixelFormatR8Sint = 14
    MtPixelFormatR16Unorm = 20
    MtPixelFormatR16Snorm = 22
    MtPixelFormatR16Uint = 23
    MtPixelFormatR16Sint = 24
    MtPixelFormatR16Float = 25
    MtPixelFormatRG8Unorm = 30
    MtPixelFormatRG8Unorm_sRGB = 31
    MtPixelFormatRG8Snorm = 32
    MtPixelFormatRG8Uint = 33
    MtPixelFormatRG8Sint = 34
    MtPixelFormatB5G6R5Unorm = 40
    MtPixelFormatA1BGR5Unorm = 41
    MtPixelFormatABGR4Unorm = 42
    MtPixelFormatBGR5A1Unorm = 43
    MtPixelFormatR32Uint = 53
    MtPixelFormatR32Sint = 54
    MtPixelFormatR32Float = 55
    MtPixelFormatRG16Unorm = 60
    MtPixelFormatRG16Snorm = 62
    MtPixelFormatRG16Uint = 63
    MtPixelFormatRG16Sint = 64
    MtPixelFormatRG16Float = 65
    MtPixelFormatRGBA8Unorm = 70
    MtPixelFormatRGBA8Unorm_sRGB = 71
    MtPixelFormatRGBA8Snorm = 72
    MtPixelFormatRGBA8Uint = 73
    MtPixelFormatRGBA8Sint = 74
    MtPixelFormatBGRX8Unorm = 75
    MtPixelFormatBGRA8Unorm = 80
    MtPixelFormatBGRA8Unorm_sRGB = 81
    MtPixelFormatRGB10A2Unorm = 90
    MtPixelFormatRGB10A2Uint = 91
    MtPixelFormatRG11B10Float = 92
    MtPixelFormatRGB9E5Float = 93
    MtPixelFormatBGR10A2Unorm = 94
    MtPixelFormatBGR10_XR = 554
    MtPixelFormatBGR10_XR_sRGB = 555
    MtPixelFormatRG32Uint = 103
    MtPixelFormatRG32Sint = 104
    MtPixelFormatRG32Float = 105
    MtPixelFormatRGBA16Unorm = 110
    MtPixelFormatRGBA16Snorm = 112
    MtPixelFormatRGBA16Uint = 113
    MtPixelFormatRGBA16Sint = 114
    MtPixelFormatRGBA16Float = 115
    MtPixelFormatBGRA10_XR = 552
    MtPixelFormatBGRA10_XR_sRGB = 553
    MtPixelFormatRGBA32Uint = 123
    MtPixelFormatRGBA32Sint = 124
    MtPixelFormatRGBA32Float = 125
    MtPixelFormatBC1_RGBA = 130
    MtPixelFormatBC1_RGBA_sRGB = 131
    MtPixelFormatBC2_RGBA = 132
    MtPixelFormatBC2_RGBA_sRGB = 133
    MtPixelFormatBC3_RGBA = 134
    MtPixelFormatBC3_RGBA_sRGB = 135
    MtPixelFormatBC4_RUnorm = 140
    MtPixelFormatBC4_RSnorm = 141
    MtPixelFormatBC5_RGUnorm = 142
    MtPixelFormatBC5_RGSnorm = 143
    MtPixelFormatBC6H_RGBFloat = 150
    MtPixelFormatBC6H_RGBUfloat = 151
    MtPixelFormatBC7_RGBAUnorm = 152
    MtPixelFormatBC7_RGBAUnorm_sRGB = 153
    MtPixelFormatPVRTC_RGB_2BPP = 160
    MtPixelFormatPVRTC_RGB_2BPP_sRGB = 161
    MtPixelFormatPVRTC_RGB_4BPP = 162
    MtPixelFormatPVRTC_RGB_4BPP_sRGB = 163
    MtPixelFormatPVRTC_RGBA_2BPP = 164
    MtPixelFormatPVRTC_RGBA_2BPP_sRGB = 165
    MtPixelFormatPVRTC_RGBA_4BPP = 166
    MtPixelFormatPVRTC_RGBA_4BPP_sRGB = 167
    MtPixelFormatEAC_R11Unorm = 170
    MtPixelFormatEAC_R11Snorm = 172
    MtPixelFormatEAC_RG11Unorm = 174
    MtPixelFormatEAC_RG11Snorm = 176
    MtPixelFormatEAC_RGBA8 = 178
    MtPixelFormatEAC_RGBA8_sRGB = 179
    MtPixelFormatETC2_RGB8 = 180
    MtPixelFormatETC2_RGB8_sRGB = 181
    MtPixelFormatETC2_RGB8A1 = 182
    MtPixelFormatETC2_RGB8A1_sRGB = 183
    MtPixelFormatASTC_4x4_sRGB = 186
    MtPixelFormatASTC_5x4_sRGB = 187
    MtPixelFormatASTC_5x5_sRGB = 188
    MtPixelFormatASTC_6x5_sRGB = 189
    MtPixelFormatASTC_6x6_sRGB = 190
    MtPixelFormatASTC_8x5_sRGB = 192
    MtPixelFormatASTC_8x6_sRGB = 193
    MtPixelFormatASTC_8x8_sRGB = 194
    MtPixelFormatASTC_10x5_sRGB = 195
    MtPixelFormatASTC_10x6_sRGB = 196
    MtPixelFormatASTC_10x8_sRGB = 197
    MtPixelFormatASTC_10x10_sRGB = 198
    MtPixelFormatASTC_12x10_sRGB = 199
    MtPixelFormatASTC_12x12_sRGB = 200
    MtPixelFormatASTC_4x4_LDR = 204
    MtPixelFormatASTC_5x4_LDR = 205
    MtPixelFormatASTC_5x5_LDR = 206
    MtPixelFormatASTC_6x5_LDR = 207
    MtPixelFormatASTC_6x6_LDR = 208
    MtPixelFormatASTC_8x5_LDR = 210
    MtPixelFormatASTC_8x6_LDR = 211
    MtPixelFormatASTC_8x8_LDR = 212
    MtPixelFormatASTC_10x5_LDR = 213
    MtPixelFormatASTC_10x6_LDR = 214
    MtPixelFormatASTC_10x8_LDR = 215
    MtPixelFormatASTC_10x10_LDR = 216
    MtPixelFormatASTC_12x10_LDR = 217
    MtPixelFormatASTC_12x12_LDR = 218
    MtPixelFormatGBGR422 = 240
    MtPixelFormatBGRG422 = 241
    MtPixelFormatDepth16Unorm = 250
    MtPixelFormatDepth32Float = 252
    MtPixelFormatStencil8 = 253
    MtPixelFormatDepth24Unorm_Stencil8 = 255
    MtPixelFormatDepth32Float_Stencil8 = 260
    MtPixelFormatX32_Stencil8 = 261
    MtPixelFormatX24_Stencil8 = 262
end

@cenum MtCPUCacheMode::UInt32 begin
    MtCPUCacheModeDefaultCache = 0
    MtCPUCacheModeWriteCombined = 1
end

@cenum MtHazardTrackingMode::UInt32 begin
    MtHazardTrackingModeDefault = 0
    MtHazardTrackingModeUntracked = 1
    MtHazardTrackingModeTracked = 2
end

@cenum MtStorageMode::UInt32 begin
    MtStorageModeShared = 0
    MtStorageModeManaged = 1
    MtStorageModePrivate = 2
    MtStorageModeMemoryless = 3
end

@cenum MtResourceOptions::UInt32 begin
    MtResourceCPUCacheModeDefaultCache = 0
    MtResourceCPUCacheModeWriteCombined = 1
    MtResourceStorageModeShared = 0
    MtResourceStorageModeManaged = 16
    MtResourceStorageModePrivate = 32
    MtResourceStorageModeMemoryless = 48
    MtResourceHazardTrackingModeDefault = 0
    MtResourceHazardTrackingModeUntracked = 256
    MtResourceHazardTrackingModeTracked = 512
end

@cenum MtVertexFormat::UInt32 begin
    MtVertexFormatInvalid = 0
    MtVertexFormatUChar2 = 1
    MtVertexFormatUChar3 = 2
    MtVertexFormatUChar4 = 3
    MtVertexFormatChar2 = 4
    MtVertexFormatChar3 = 5
    MtVertexFormatChar4 = 6
    MtVertexFormatUChar2Normalized = 7
    MtVertexFormatUChar3Normalized = 8
    MtVertexFormatUChar4Normalized = 9
    MtVertexFormatChar2Normalized = 10
    MtVertexFormatChar3Normalized = 11
    MtVertexFormatChar4Normalized = 12
    MtVertexFormatUShort2 = 13
    MtVertexFormatUShort3 = 14
    MtVertexFormatUShort4 = 15
    MtVertexFormatShort2 = 16
    MtVertexFormatShort3 = 17
    MtVertexFormatShort4 = 18
    MtVertexFormatUShort2Normalized = 19
    MtVertexFormatUShort3Normalized = 20
    MtVertexFormatUShort4Normalized = 21
    MtVertexFormatShort2Normalized = 22
    MtVertexFormatShort3Normalized = 23
    MtVertexFormatShort4Normalized = 24
    MtVertexFormatHalf2 = 25
    MtVertexFormatHalf3 = 26
    MtVertexFormatHalf4 = 27
    MtVertexFormatFloat = 28
    MtVertexFormatFloat2 = 29
    MtVertexFormatFloat3 = 30
    MtVertexFormatFloat4 = 31
    MtVertexFormatInt = 32
    MtVertexFormatInt2 = 33
    MtVertexFormatInt3 = 34
    MtVertexFormatInt4 = 35
    MtVertexFormatUInt = 36
    MtVertexFormatUInt2 = 37
    MtVertexFormatUInt3 = 38
    MtVertexFormatUInt4 = 39
    MtVertexFormatInt1010102Normalized = 40
    MtVertexFormatUInt1010102Normalized = 41
    MtVertexFormatUChar4Normalized_BGRA = 42
    MtVertexFormatUChar = 45
    MtVertexFormatChar = 46
    MtVertexFormatUCharNormalized = 47
    MtVertexFormatCharNormalized = 48
    MtVertexFormatUShort = 49
    MtVertexFormatShort = 50
    MtVertexFormatUShortNormalized = 51
    MtVertexFormatShortNormalized = 52
    MtVertexFormatHalf = 53
end

@cenum MtVertexStepFunction::UInt32 begin
    MtVertexStepFunctionConstant = 0
    MtVertexStepFunctionPerVertex = 1
    MtVertexStepFunctionPerInstance = 2
    MtVertexStepFunctionPerPatch = 3
    MtVertexStepFunctionPerPatchControlPoint = 4
end

@cenum MtCompareFunction::UInt32 begin
    MtCompareFunctionNever = 0
    MtCompareFunctionLess = 1
    MtCompareFunctionEqual = 2
    MtCompareFunctionLessEqual = 3
    MtCompareFunctionGreater = 4
    MtCompareFunctionNotEqual = 5
    MtCompareFunctionGreaterEqual = 6
    MtCompareFunctionAlways = 7
end

@cenum MtStencilOperation::UInt32 begin
    MtStencilOperationKeep = 0
    MtStencilOperationZero = 1
    MtStencilOperationReplace = 2
    MtStencilOperationIncrementClamp = 3
    MtStencilOperationDecrementClamp = 4
    MtStencilOperationInvert = 5
    MtStencilOperationIncrementWrap = 6
    MtStencilOperationDecrementWrap = 7
end

@cenum MtFuncType::UInt32 begin
    MT_FUNC_VERT = 1
    MT_FUNC_FRAG = 2
end

const MtCommandBufferOnCompleteFn = Ptr{Cvoid}
const MtCommandBufferOnCompleteFnNoSender = Ptr{Cvoid}


text:
bt = backtrace()
have_backtrace = false
for l in bt
    lkup = ccall(:jl_lookup_code_address, Any, (Ptr{Void},), l)
    if lkup[1] == :backtrace
        have_backtrace = true
        break
    end
end

@test have_backtrace

max_stars_repo_name: jakebolewski/julia

max_issues_repo_name: jakebolewski/julia

max_forks_repo_name: jakebolewski/julia


text:
################################################################################
# Template iterator

struct TemplateIterator{I <: Integer, T <: AbstractArray} <: ProximalAlgorithm{I,T}
    x::T
    maxit::I
    # Put here problem description, other parameters, method memory,
    # also maybe storage for in-place computations, etc...
end

################################################################################
# Constructor(s)

TemplateIterator(x0::T; maxit::I=10) where {I, T} = TemplateIterator{I, T}(x0, maxit)

################################################################################
# Utility methods

maxit(sol::TemplateIterator) = sol.maxit

converged(sol::TemplateIterator, it) = false

verbose(sol::TemplateIterator) = true
verbose(sol::TemplateIterator, it) = true

display(sol::TemplateIterator) = println("Iterations")
display(sol::TemplateIterator, it) = println("$(it)")

function Base.show(io::IO, sol::TemplateIterator)
	print(io, "Template Solver" )
end

################################################################################
# Initialization

function initialize!(sol::TemplateIterator)
    # One shouldn't really be printing anything here
    println("Initializing the iterations")
    return sol.x
end

################################################################################
# Iteration

function iterate!(sol::TemplateIterator{I, T}, it::I) where {I, T}
    # One shouldn't really be printing anything here
    println("Performing one iteration")
    return sol.x
end

################################################################################
# Solver interface(s)

function Template(x0; kwargs...)
    # Create iterable
    sol = TemplateIterator(x0; kwargs...)
    # Run iterations
    it, point = run!(sol)
    return it, point, sol
end


text:
@testset "set operations" begin

    Nsamps = 10^6

    a = interval(0,1) ∪ interval(2,3)

    b = interval(-1, 1) ∪ interval(2,5)

    aSamps = zeros(Nsamps); bSamps = zeros(Nsamps)

    for i = 1: Nsamps
        if rand() < 0.5
            aSamps[i] = rand()
        else
            aSamps[i] = rand() + 2
        end

        if rand() < 0.5
            bSamps[i] = (rand() * 2) -1
        else
            bSamps[i] = rand() * 3 + 2
        end
    end

    @test all(aSamps .∈ a)
    @test all(bSamps .∈ b)

    ac = complement(a)

    @test all(.~(aSamps .∈ ac))     # Test all samples are not in complement

    intersec = a ∩ b                 # Intersect

    aSampsB = aSamps[ aSamps .∈ b]
    bSampsA = bSamps[ bSamps .∈ a]

    @test all( aSampsB .∈ intersec)
    @test all( bSampsA .∈ intersec)

    diff = a \ b                 # Set difference

    @test diff[1] == interval(1)
    @test diff[2] == interval(2)

    bi = bisect(a, 0.5)         # Cut at a = 0.5

    @test bi[1] == interval(0, 0.5)
    @test bi[2] == interval(0.5, 1)
    @test bi[3] == interval(2, 3)

    @test a ⊂ interval(0, 3)     # Subset
    @test !(b ⊂ interval(0, 3))

end


text:
using LinearAlgebra
using Plots

m = 40 #parents
l = 3*m #childs
n = 10000 #DOFS
mr = 0.002*0 #mutation rate
par = 4 #parents
elites = 2
bl = -5.12 .*ones(1,n) #lower limits
bu = 5.12 .*ones(1,n) #upper limits
#1st generation
b = 10.24 .*rand(l,n) .-5.12
bnew = b
a = []
while true
    global b,bnew
    #evaluate
    #F = sum(b.^2,dims=2)
    F = 10*n .+ sum(b.^2 .-10 .*cos.(2*pi.*b),dims = 2)
    sort_ix = sortperm(F[:])
    sorted = F[sort_ix]
    #elitism
    i_elite = sort_ix[1:elites]
    #parent
    sorted = sorted./sum(F)
    for i = 2:l
        sorted[i] = sorted[i] + sorted[i-1] #make linear roulette
    end
    random = rand(m,1)
    selections = zeros(m,1)
    for i=1:m
        selections[i] = sort_ix[searchsortedfirst(sorted,random[i])] #select from roulette
    end
    selections = Int.(selections)
    # start crossover
    for i = 1:l
        indexOFthree = selections[rand(1:m,par)] #who will mate
        o = rand(par,n) #random interpolation constants
        pnew = o.*b[indexOFthree,:]./par
        pnew = sum(pnew,dims=1)
        if !(i in i_elite) #exclude elite
            bnew[i,:] = pnew #happy birthday
        end
    end
    #mutate
    for i=1:l
        if !(i in i_elite)
            for j=1:n
                if rand(1)[1]<mr
                    o = rand(1)[1]
                    bnew[i,j] = o*bl[j]+(1-o)*bu[j]
                end
            end
        end
    end
    b = bnew
    println(minimum(F))
    append!(a,minimum(F))
end

max_stars_repo_name: billyon/first

max_issues_repo_name: billyon/first

max_forks_repo_name: billyon/first


text:
# Test all of the helper methods
@testset "Helper Methods" begin
    # Setup
    m = InfiniteModel();
    @infinite_parameter(m, t in [0,1])
    @infinite_parameter(m, x[1:2] in [0,5], num_supports = 2)
    @infinite_variable(m, T(t, x))
    @infinite_variable(m, q(t))
    oc = OrthogonalCollocation(3, GaussLobatto())
    bad_oc = OrthogonalCollocation{GaussLegendre}(3, GaussLegendre())
    tref = dispatch_variable_ref(t)
    # test generative_support_info
    @testset "generative_support_info" begin
        # test Fallback
        @test_throws ErrorException generative_support_info(TestGenMethod())
        # test NonGenerativeDerivativeMethod
        @test generative_support_info(TestMethod()) == NoGenerativeSupports()
        # test OrthogonalCollocation with GaussLobatto
        @test generative_support_info(oc) == UniformGenerativeInfo([0.5], InternalGaussLobatto)
        @test generative_support_info(OrthogonalCollocation(2)) == NoGenerativeSupports()
        # test bad OrthogonalCollocation
        @test_throws ErrorException generative_support_info(bad_oc)
    end
    # test support_label
    @testset "support_label" begin
        # test Fallback
        @test_throws ErrorException support_label(TestMethod())
        # test GenerativeDerivativeMethod
        @test support_label(oc) == InternalGaussLobatto
    end
    # test make_reduced_expr
    @testset "make_reduced_expr" begin
        # test MeasureIndex based
        meas = support_sum(T, x)
        pidx = length(InfiniteOpt._data_dictionary(m, PointVariable)) + 1
        pts = [GeneralVariableRef(m, pidx, PointVariableIndex),
               GeneralVariableRef(m, pidx + 1, PointVariableIndex)]
        @test InfiniteOpt.make_reduced_expr(meas, t, 0.0, m) in [pts[1] + pts[2], pts[2] + pts[1]] # order is unknown
        @test parameter_values(pts[1]) in [(0., [0., 0.]), (0., [5., 5.])]
        @test parameter_values(pts[2]) in [(0., [0., 0.]), (0., [5., 5.])]
        # test InfiniteVariableIndex
        pt = GeneralVariableRef(m, pidx + 2, PointVariableIndex)
        @test InfiniteOpt.make_reduced_expr(q, t, 0.0, m) == pt
        @test parameter_values(pt) == (0.0,)
        ridx = 3 # 2 were previously made and deleted by the measure call
        rv = GeneralVariableRef(m, ridx, ReducedVariableIndex)
        @test InfiniteOpt.make_reduced_expr(T, t, 0.0, m) == rv
        @test parameter_list(rv) == [x[1], x[2]]
        @test eval_supports(rv)[1] == 0
        # test DerivativeIndex
        dT = @deriv(T, x[1])
        dq = @deriv(q, t)
        pt = GeneralVariableRef(m, pidx + 3, PointVariableIndex)
        @test InfiniteOpt.make_reduced_expr(dq, t, 0.0, m) == pt
        @test parameter_values(pt) == (0.0,)
        rv = GeneralVariableRef(m, ridx + 1, ReducedVariableIndex)
        @test InfiniteOpt.make_reduced_expr(dT, x[2], 0.0, m) == rv
        @test parameter_list(rv) == [t, x[1]]
        @test eval_supports(rv)[3] == 0
        # test ReducedVariableIndex
        rv2 = GeneralVariableRef(m, ridx + 2, ReducedVariableIndex)
        @test InfiniteOpt.make_reduced_expr(rv, x[1], 0.0, m) == rv2
        @test parameter_list(rv2) == [t]
        @test eval_supports(rv2)[3] == 0
        @test eval_supports(rv2)[2] == 0
        pt = GeneralVariableRef(m, pidx + 4, PointVariableIndex)
        @test InfiniteOpt.make_reduced_expr(rv2, t, 0.0, m) == pt
        @test parameter_values(pt) == (0.0, [0.0, 0.0])
    end
end

# Test evaluate_derivative and its helpers
@testset "evaluate_derivative" begin
    # setup
    m = InfiniteModel()
    @infinite_parameter(m, t in [0, 10], num_supports = 3)
    @infinite_parameter(m, x[1:2] in [0, 1], num_supports = 2)
    @infinite_variable(m, y(t))
    @infinite_variable(m, q(t, x))
    meas = support_sum(q, t)
    d1 = @deriv(y, t)
    d2 = @deriv(q, t)
    d3 = @deriv(q, x[2])
    d4 = @deriv(meas, x[1])
    # test fallback
    @testset "Fallback" begin
        @test_throws ErrorException InfiniteOpt.evaluate_derivative(d1, TestMethod(), m)
    end
    # test _make_difference_expr for Forward
    @testset "_make_difference_expr (Forward)" begin
        supps = supports(t, label = All)
        pidx = length(InfiniteOpt._data_dictionary(m, PointVariable)) + 1
        pts = [GeneralVariableRef(m, pidx, PointVariableIndex),
               GeneralVariableRef(m, pidx + 1, PointVariableIndex),
               GeneralVariableRef(m, pidx + 2, PointVariableIndex)]
        @test InfiniteOpt._make_difference_expr(d1, y, t, 1, supps, m, Forward()) == 5pts[1] - pts[2] + pts[3]
        @test parameter_values(pts[1]) == (0.,)
        @test parameter_values(pts[2]) == (5.,)
        @test parameter_values(pts[3]) == (0.,)
    end
    # test _make_difference_expr for Central
    @testset "_make_difference_expr (Central)" begin
        supps = supports(t, label = All)
        ridx = length(InfiniteOpt._data_dictionary(m, ReducedVariable)) + 1
        rvs = [GeneralVariableRef(m, ridx, ReducedVariableIndex),
               GeneralVariableRef(m, ridx + 1, ReducedVariableIndex),
               GeneralVariableRef(m, ridx + 2, ReducedVariableIndex)]
        @test InfiniteOpt._make_difference_expr(d2, q, t, 2, supps, m, Central()) == 10rvs[1] - rvs[2] + rvs[3]
        @test eval_supports(rvs[1])[1] == 5
        @test eval_supports(rvs[2])[1] == 10
        @test eval_supports(rvs[3])[1] == 0
    end
    # test _make_difference_expr for FDBackward
    @testset "_make_difference_expr (Backward)" begin
        supps = sort(supports(x[2], label = All))
        ridx = length(InfiniteOpt._data_dictionary(m, ReducedVariable)) + 1
        rvs = [GeneralVariableRef(m, ridx, ReducedVariableIndex),
               GeneralVariableRef(m, ridx + 1, ReducedVariableIndex),
               GeneralVariableRef(m, ridx + 2, ReducedVariableIndex)]
        @test InfiniteOpt._make_difference_expr(d3, q, x[2], 2, supps, m, Backward()) == rvs[1] - rvs[2] + rvs[3]
        @test eval_supports(rvs[1])[3] == 1
        @test eval_supports(rvs[2])[3] == 1
        @test eval_supports(rvs[3])[3] == 0
    end
    # test _make_difference_expr fallback
    @testset "_make_difference_expr (Fallback)" begin
        @test_throws ErrorException InfiniteOpt._make_difference_expr(d3, q, x[2], 2, [1], m, BadFiniteTech())
    end
    # test FiniteDifference with evaluate_derivative
    @testset "FiniteDifference" begin
        # test with independent parameter
        method = FiniteDifference(Central())
        pidx = length(InfiniteOpt._data_dictionary(m, PointVariable)) + 1
        pts = [GeneralVariableRef(m, pidx, PointVariableIndex),
               GeneralVariableRef(m, pidx + 1, PointVariableIndex),
               GeneralVariableRef(m, pidx + 2, PointVariableIndex)]
        exprs = [10pts[1] - pts[2] + pts[3]]
        @test InfiniteOpt.evaluate_derivative(d1, method, m) == exprs
        # test with dependent parameter
        method = FiniteDifference(Forward())
        ridx = length(InfiniteOpt._data_dictionary(m, ReducedVariable)) + 1
        rvs = [GeneralVariableRef(m, ridx, ReducedVariableIndex),
               GeneralVariableRef(m, ridx + 4, ReducedVariableIndex),
               GeneralVariableRef(m, ridx + 5, ReducedVariableIndex),
               GeneralVariableRef(m, ridx + 6, ReducedVariableIndex),
               GeneralVariableRef(m, ridx + 10, ReducedVariableIndex),
               GeneralVariableRef(m, ridx + 11, ReducedVariableIndex),
               GeneralVariableRef(m, ridx + 12, ReducedVariableIndex)]
        exprs = [rvs[1] - rvs[2] - rvs[3] - rvs[4] + rvs[5] + rvs[6] + rvs[7]]
        @test InfiniteOpt.evaluate_derivative(d4, method, m) == exprs
        # test using Backward without boundary constraint
        method = FiniteDifference(Backward(), false)
        pidx = length(InfiniteOpt._data_dictionary(m, PointVariable)) + 1
        pts = [GeneralVariableRef(m, pidx, PointVariableIndex),
               GeneralVariableRef(m, pidx + 1, PointVariableIndex),
               GeneralVariableRef(m, pidx + 2, PointVariableIndex)]
        exprs = [5pts[1] - pts[2] + pts[3]]
        @test InfiniteOpt.evaluate_derivative(d1, method, m) == exprs
        # test Backward with boundary constraint
        method = FiniteDifference(Backward(), true)
        pidx = length(InfiniteOpt._data_dictionary(m, PointVariable)) + 1
        pts = [GeneralVariableRef(m, pidx, PointVariableIndex),
               GeneralVariableRef(m, pidx + 1, PointVariableIndex),
               GeneralVariableRef(m, pidx + 2, PointVariableIndex),
               GeneralVariableRef(m, pidx + 3, PointVariableIndex),
               GeneralVariableRef(m, pidx + 4, PointVariableIndex),
               GeneralVariableRef(m, pidx + 5, PointVariableIndex)]
        exprs = [5pts[1] - pts[2] + pts[3],
                 5pts[4] - pts[5] + pts[6]]
        @test InfiniteOpt.evaluate_derivative(d1, method, m) == exprs
        # test without supports
        delete_supports(x)
        @test_throws ErrorException InfiniteOpt.evaluate_derivative(d3, method, m)
        # test parameter function
        f = parameter_function(sin, t)
        df = deriv(f, t)
        pts = [GeneralVariableRef(m, pidx + 6, PointVariableIndex),
               GeneralVariableRef(m, pidx + 7, PointVariableIndex)]
        @test InfiniteOpt.evaluate_derivative(df, method, m) == [5pts[1] - sin(5) + sin(0),
                                                                 5pts[2] - sin(10) + sin(5)]
    end
    # test OrthogonalCollocation with evaluate_derivative
    @testset "OrthogonalCollocation" begin
        # test first solve
        method = OrthogonalCollocation(3)
        set_derivative_method(t, method)
        Mt = [1. 5.; 1. 10]' \ [2.5 2.5^2; 5. 25.]'
        M = Mt'
        ridx = length(InfiniteOpt._data_dictionary(m, ReducedVariable)) + 6
        rvs = [GeneralVariableRef(m, ridx + i, ReducedVariableIndex) for i = 1:16]
        exprs = [@expression(m, M[1, 1] * rvs[1] + M[1, 2] * rvs[2] - rvs[3] + rvs[4]),
                 @expression(m, M[2, 1] * rvs[5] + M[2, 2] * rvs[6] - rvs[7] + rvs[8]),
                 @expression(m, M[1, 1] * rvs[9] + M[1, 2] * rvs[10] - rvs[11] + rvs[12]),
                 @expression(m, M[2, 1] * rvs[13] + M[2, 2] * rvs[14] - rvs[15] + rvs[16])]
        @test InfiniteOpt.evaluate_derivative(d2, method, m) == exprs
        @test supports(t) == [0, 5, 10]
        @test supports(t, label = All) == [0, 2.5, 5, 7.5, 10]
        # test resolve
        ridx = length(InfiniteOpt._data_dictionary(m, ReducedVariable)) + 6
        rvs = [GeneralVariableRef(m, ridx + i, ReducedVariableIndex) for i = 1:16]
        exprs = [@expression(m, M[1, 1] * rvs[1] + M[1, 2] * rvs[2] - rvs[3] + rvs[4]),
                 @expression(m, M[2, 1] * rvs[5] + M[2, 2] * rvs[6] - rvs[7] + rvs[8]),
                 @expression(m, M[1, 1] * rvs[9] + M[1, 2] * rvs[10] - rvs[11] + rvs[12]),
                 @expression(m, M[2, 1] * rvs[13] + M[2, 2] * rvs[14] - rvs[15] + rvs[16])]
        @test InfiniteOpt.evaluate_derivative(d2, method, m) == exprs
        @test supports(t) == [0, 5, 10]
        @test supports(t, label = All) == [0, 2.5, 5, 7.5, 10]
        @test has_generative_supports(t)
        @test has_internal_supports(t)
    end
end

# Test User Methods
@testset "User Methods" begin
    # setup
    m = InfiniteModel()
    @infinite_parameter(m, t in [0, 10], supports = [0, 3, 10])
    @infinite_parameter(m, x in [-1, 1], supports = [-1, 1],
                        derivative_method = OrthogonalCollocation(4))
    @infinite_variable(m, y(t))
    @infinite_variable(m, q(x))
    dy = @deriv(y, t)
    dq = @deriv(q, x)
    dy2 = @deriv(y, t^2)
    # test evaluate
    @testset "evaluate" begin
        # test evaluate first derivative
        @test derivative_method(t) isa FiniteDifference
        @test evaluate(dy) isa Nothing
        @test num_constraints(m) == 2
        @test !has_generative_supports(t)
        @test has_derivative_constraints(t)
        @test has_derivative_constraints(dy)
        @test length(derivative_constraints(dy)) == 2
        # test evaluate second derivative
        @test derivative_method(t) isa FiniteDifference
        @test evaluate(dy2) isa Nothing
        @test num_constraints(m) == 4
        @test !has_generative_supports(t)
        @test has_derivative_constraints(t)
        @test has_derivative_constraints(dy2)
        @test length(derivative_constraints(dy2)) == 2
    end
    # test evaluate_all_derivatives!
    @testset "evaluate_all_derivatives!" begin
        @test derivative_method(x) isa OrthogonalCollocation
        @test evaluate_all_derivatives!(m) isa Nothing
        @test num_constraints(m) == 7
        @test has_generative_supports(x)
        @test has_internal_supports(x)
        @test supports(x) == [-1, 1]
        @test num_supports(x, label = All) == 4
        @test supports(t) == [0, 3, 10]
        @test length(derivative_constraints(dy)) == 2
        @test length(derivative_constraints(dy2)) == 2
        @test length(derivative_constraints(dq)) == 3
        @test has_derivative_constraints(t)
        @test has_derivative_constraints(x)
        @test has_derivative_constraints(dy)
        @test has_derivative_constraints(dy2)
        @test has_derivative_constraints(dq)
    end
end


text:
"""
Scale Transform
```
    l = 2.0
    tr = ScaleTransform(l)
    v = rand(3)
    tr = ScaleTransform(v)
```
Multiply every element of the matrix by `l` for a scalar
Multiply every vector of observation by `v` element-wise for a vector
"""
struct ScaleTransform{T<:Union{Base.RefValue{<:Real},AbstractVector{<:Real}}} <: Transform
    s::T
end

function ScaleTransform(s::T=1.0) where {T<:Real}
    @check_args(ScaleTransform, s, s > zero(T), "s > 0")
    ScaleTransform{Base.RefValue{T}}(Ref(s))
end

function ScaleTransform(s::T,dims::Integer) where {T<:Real} # TODO Add test
    @check_args(ScaleTransform, s, s > zero(T), "s > 0")
    ScaleTransform{Vector{T}}(fill(s,dims))
end

function ScaleTransform(s::A) where {A<:AbstractVector{<:Real}}
    @check_args(ScaleTransform, s, all(s.>zero(eltype(A))), "s > 0")
    ScaleTransform{A}(s)
end

function set!(t::ScaleTransform{Base.RefValue{T}},ρ::T) where {T<:Real}
    t.s[] = ρ
end
function set!(t::ScaleTransform{<:AbstractVector{T}},ρ::AbstractVector{T}) where {T<:Real}
    @assert length(ρ) == dim(t) "Trying to set a vector of size $(length(ρ)) to ScaleTransform of dimension $(dim(t))"
    t.s .= ρ
end
set_params!(k::Kernel{T,<:ScaleTransform{<:Base.RefValue{<:Tρ}}},ρ::Tρ) where {T,Tρ<:Real} = set!(k.transform,ρ)
set_params!(k::Kernel{T,<:ScaleTransform{<:Base.RefValue{<:Tρ}}},ρ::AbstractVector{<:Tρ}) where {T,Tρ<:Real} = set!(k.transform,first(ρ))
set_params!(k::Kernel{T,<:ScaleTransform{<:AbstractVector{<:Tρ}}},ρ::AbstractVector{<:Tρ}) where {T,Tρ<:Real} = set!(k.transform,ρ)

params(t::ScaleTransform{<:Base.RefValue}) = t.s[]
params(t::ScaleTransform{<:AbstractVector}) = t.s

dim(str::ScaleTransform{Base.RefValue{<:Real}}) = 1 #TODO Add test
dim(str::ScaleTransform{<:AbstractVector{<:Real}}) = length(str.s)

function transform(t::ScaleTransform{<:AbstractVector{<:Real}},X::AbstractMatrix{<:Real},obsdim::Int)
    @boundscheck if dim(t) != size(X,feature_dim(obsdim))
        throw(DimensionMismatch("Array has size $(size(X,!Bool(obsdim-1)+1)) on dimension $(!Bool(obsdim-1)+1)) which does not match the length of the scale transform length , $(dim(t)).")) #TODO Add test
    end
    _transform(t,X,obsdim)
end
transform(t::ScaleTransform{<:AbstractVector{<:Real}},x::AbstractVector{<:Real},obsdim::Int=defaultobs) = t.s .* x
_transform(t::ScaleTransform{<:AbstractVector{<:Real}},X::AbstractMatrix{<:Real},obsdim::Int=defaultobs) = obsdim == 1 ? t.s'.*X : t.s .* X

transform(t::ScaleTransform{<:Base.RefValue{<:Real}},x::AbstractVecOrMat,obsdim::Int=defaultobs) = t.s[] .* x

Base.isequal(t::ScaleTransform{T},t2::ScaleTransform{T}) where {T<:Base.RefValue{<:Real}} = isequal(t.s[],t2.s[])
Base.isequal(t::ScaleTransform{T},t2::ScaleTransform{T}) where {T<:AbstractVector{<:Real}} = isequal(t.s,t2.s)


text:
using UnionFind

using Printf
using Test

@testset "Polymorphism" begin
    include("polymorphism.jl")
end

@testset "Table" begin
    include("table.jl")
end

@testset "Errors" begin
    include("errors.jl")
end

@testset "Benchmark" begin
    include("benchmark.jl")
end


text:
# Distance metrics for kernel functions

δ(Φ, z) = diff(Φ) ./ diff(z)

# this is norm(a-b)^2 but more efficient
function sq_mag(a,b) # ||a - b||^2
    ll = 0.0
    @inbounds for k in 1:length(a)
        ll += (a[k]-b[k])^2
    end
    return ll
end

"""
euclidean_distance: computes the Euclidean distance (l²-norm) between two vectors
"""
@inline function euclidean_distance(a,b,z) # d(x,x') = || x - x' ||
    return sqrt(sq_mag(a,b))
end

@inline function euclidean_distance(a,b) # d(x,x') = || x - x' ||
    return sqrt(sq_mag(a,b))
end

"""
derivative_distance: computes the H¹-norm w.r.t z of two vectors
"""
function derivative_distance(a,b,z) # d(x,x') = || diff(x)./diff(z) - diff(x')./diff(z) ||
    return sqrt(sq_mag( δ(a, z), δ(b, z) ))
end

"""
antiderivative_distance: computes the H⁻¹-norm w.r.t z of two vectors
"""
function antiderivative_distance(a,b,z) # || diff(x).*diff(z) - diff(x').*diff(z) ||
    return sqrt(sq_mag(diff(a).*diff(z) , diff(b).*diff(z)))
end

# """
# l2norm_strat_penalty: computes the Euclidean distance (l²-norm) between two vectors and adds
# the a proxy for the difference in the initial stratification from the corresponding temperature
# profiles, as approximated by the stratification at the bottom.
# """
# function l2norm_strat_penalty(a,b,z) # d(x,x') = || x - x' ||
#     α_proxy(x) = x[2] - x[1]
#     println(abs(α_proxy(a)-α_proxy(b)))
#     if abs(α_proxy(a)-α_proxy(b))>0.05
#         return l2_norm(a,b) + 0.0001
#     end
#     return l2_norm(a,b)
# end

max_stars_repo_name: adelinehillier/LearnConvection

max_issues_repo_name: adelinehillier/LearnConvection

max_forks_repo_name: adelinehillier/LearnConvection


text:
module StackedNets

	export error!,
	forward!,
	gradient_check,
	gradient_update!,
	train_sgd!,
	StackedNet,
	Units

	include("activation_functions.jl")
	include("layer.jl")
	include("stackednet.jl")
	include("error_functions.jl")
	include("units.jl")
	include("utils.jl")
end


text:
files = [
    "Arrow/docs/src/index.md",
    "Arrow/docs/src/manual.md",
    "Arrow/docs/src/reference.md",
    "Arrow/docs/make.jl",
    "Arrow/docs/Project.toml",
    "Arrow/src/arraytypes/arraytypes.jl",
    "Arrow/src/arraytypes/bool.jl",
    "Arrow/src/arraytypes/compressed.jl",
    "Arrow/src/arraytypes/dictencoding.jl",
    "Arrow/src/arraytypes/fixedsizelist.jl",
    "Arrow/src/arraytypes/list.jl",
    "Arrow/src/arraytypes/map.jl",
    "Arrow/src/arraytypes/primitive.jl",
    "Arrow/src/arraytypes/struct.jl",
    "Arrow/src/arraytypes/unions.jl",
    "Arrow/src/FlatBuffers/builder.jl",
    "Arrow/src/FlatBuffers/builder.jl",
    "Arrow/src/FlatBuffers/FlatBuffers.jl",
    "Arrow/src/FlatBuffers/table.jl",
    "Arrow/src/metadata/File.jl",
    "Arrow/src/metadata/Flatbuf.jl",
    "Arrow/src/metadata/Message.jl",
    "Arrow/src/metadata/Schema.jl",
    "Arrow/src/Arrow.jl",
    "Arrow/src/arrowtypes.jl",
    "Arrow/src/eltypes.jl",
    "Arrow/src/table.jl",
    "Arrow/src/utils.jl",
    "Arrow/src/write.jl",
    "Arrow/test/arrowjson/datetime.json",
    "Arrow/test/arrowjson/decimal.json",
    "Arrow/test/arrowjson/dictionary_unsigned.json",
    "Arrow/test/arrowjson/dictionary.json",
    "Arrow/test/arrowjson/map.json",
    "Arrow/test/arrowjson/nested.json",
    "Arrow/test/arrowjson/primitive_no_batches.json",
    "Arrow/test/arrowjson/primitive-empty.json",
    "Arrow/test/arrowjson/primitive.json",
    "Arrow/test/arrowjson.jl",
    "Arrow/test/dates.jl",
    "Arrow/test/integrationtest.jl",
    "Arrow/test/pyarrow_roundtrip.jl",
    "Arrow/test/runtests.jl",
    "Arrow/test/testtables.jl",
    "Arrow/.gitignore",
    "Arrow/LICENSE.md",
    "Arrow/Project.toml",
    # "Arrow/README.md", READMEs are slightly different between officially apache/arrow julia code and JuliaData/Arrow.jl
]

sourcedir = "/Users/jacobquinn/.julia/dev/"
destdir = "/Users/jacobquinn/arrow/julia/"

for file in files
    cp(joinpath(sourcedir, file), joinpath(destdir, file); force=true)
end


text:
## Diagonostic code
##

## debugging tools, basically
round2(x) = round.(x, digits=2)
round5(x) = round.(x, digits=5)
export round2, round5
printtp(x) = println(sprint(io -> show(io, "text/plain", x)))

### Random rotators are useful for testing
random_rotator(R::AbstractRotator, i) = random_rotator(typeof(R), i)
function random_rotator(t::Type{T}, i) where {T <: Real}
    a,b = rand(T, 2)
    c,s,_ = givensrot(a,b)
    Rotator(c,s,i)
end

function random_rotator(s::Type{S}, i) where {S <: Complex}
    a,b = rand(S, 2)
    c,s,_ = givensrot(a,b)
    ns = norm(s)
    alpha = conj(s)/ns
    Rotator(c*alpha,ns,i)
end

# simple graphic to show march of algorithm
function show_status(state, ctr)
    qs = [norm(u.s) for u in state.QF.Q.x[ctr.start_index:ctr.stop_index]]

    minq = length(qs) > 0 ?  minimum(qs) : 0.0

    x = fill(".", length(state.QF) + 2)
    x[ctr.zero_index+1] = "α"
    x[ctr.start_index+1] = "δ"
    x[ctr.stop_index+2] = "Δ"
    println(join(x, ""), " ($minq)")

end


text:
module STMOZOO

# execute your source file and export the module you made
include("example.jl")
export Example

include("beesalgorithm.jl")
export BeesAlgorithm

end # module

max_stars_repo_name: kirstvh/STMOZOO

max_issues_repo_name: kirstvh/STMOZOO

max_forks_repo_name: kirstvh/STMOZOO


text:
using Pyramids
using Base.Test, Images, Colors

function end_to_end(T; convert_to_arr=true)
    test_im = rand(128, 128)

    if !convert_to_arr
        test_im = convert(Image{Gray}, test_im)
    end

    if typeof(T) <: ComplexSteerablePyramid
        scale = 0.5^(1/4);
        pyramid = ImagePyramid(test_im, T, scale=scale, num_orientations=8, max_levels=23, min_size=15, twidth=1.0)
    else
        pyramid = ImagePyramid(test_im, T, max_levels=23, min_size=15)
    end

    test_im_recon = toimage(pyramid)

    return all((test_im_recon .- test_im) .< 0.0002)
end

println("Running end-to-end image comparison test for Complex Steerable Pyramid.")
@test end_to_end(ComplexSteerablePyramid())
println("\twithout array conversion")
@test end_to_end(ComplexSteerablePyramid(), convert_to_arr=false)

println("Running end-to-end image comparison test for Gaussian Pyramid.")
@test end_to_end(GaussianPyramid())
println("\twithout array conversion")
@test end_to_end(GaussianPyramid(), convert_to_arr=false)

println("Running end-to-end image comparison test for Laplacian Pyramid.")
@test end_to_end(LaplacianPyramid())

# TODO:
#    Test pyramid copying
#       Test that pyramid levels don't unexpectedly change
#    Test subband editing
#    Test another scale factor

println("Tests passing.")