text:
include("struct/tree.jl")

"""
Construit un arbre de décision par résolution d'un programme linéaire en nombres entiers

Entrées :
- x : caractéristiques des données d'entraînement
- y : classe des données d'entraînement
- D : Nombre maximal de séparations d'une branche (profondeur de l'arbre - 1)
- multivariate (optionnel): vrai si les séparations sont multivariées; faux si elles sont univariées (faux par défaut)
- mu (optionnel, utilisé en multivarié): distance minimale à gauche d'une séparation où aucune donnée ne peut se trouver (i.e., pour la séparation ax <= b, il n'y aura aucune donnée dans ]b - ax - mu, b - ax[) (10^-4 par défaut)
- time_limits (optionnel) : temps maximal de résolution (-1 si le temps n'est pas limité) (-1 par défaut)
"""
function build_tree(x::Matrix{Float64}, y::Vector{Int64}, D::Int64;multivariate::Bool=false, time_limit::Int64 = -1, mu::Float64=10^(-4))

    dataCount = length(y) # Nombre de données d'entraînement
    featuresCount = length(x[1, :]) # Nombre de caractéristiques
    classCount = length(unique(y)) # Nombre de classes différentes
    sepCount = 2^D - 1 # Nombre de séparations de l'arbre
    leavesCount = 2^D # Nombre de feuilles de l'arbre

    m = Model(CPLEX.Optimizer)
    set_silent(m)

    if time_limit!=-1
        set_time_limit_sec(m, time_limit)
    end

    # Plus petite différence entre deux données pour une caractéristique
    mu_min = 1.0
    # Plus grande différence entre deux données pour une caractéristique
    mu_max = 0.0

    if !multivariate # calcul des constantes mu_min, mu_max et du vecteur mu

        # mu_vect[j] est la plus petite différence (>0) entre deux données, pour la caractéristiques j
        mu_vect = ones(Float64, featuresCount)
        for j in 1:featuresCount
            for i1 in 1:dataCount
                for i2 in (i1+1):dataCount
                    if x[i1, j] - x[i2, j] != 0
                        mu_vect[j] = min(mu_vect[j], abs(x[i1, j] - x[i2, j]))
                    end
                end
            end
            mu_min = min(mu_min, mu_vect[j])
            mu_max = max(mu_max, mu_vect[j])
        end
    end

    ## Déclaration des variables
    if multivariate
        @variable(m, a[1:featuresCount, 1:sepCount], base_name="a_{j, t}")
        @variable(m, a_h[1:featuresCount, 1:sepCount], base_name="â_{j, t}")
        @variable(m, s[1:featuresCount, 1:sepCount], Bin, base_name="s_{j, t}")
        @variable(m, d[1:sepCount], Bin, base_name="d_t")
    else
        @variable(m, a[1:featuresCount, 1:sepCount], Bin, base_name="a")
    end
    @variable(m, b[1:sepCount], base_name="b_t")
    @variable(m, c[1:classCount, 1:(sepCount+leavesCount)], Bin, base_name = "c_{k, t}")
    @variable(m, u_at[1:dataCount, 1:(sepCount+leavesCount)], Bin, base_name = "u^i_{a(t), t}")
    @variable(m, u_tw[1:dataCount, 1:(sepCount+leavesCount)], Bin, base_name = "u^i_{t, w}")

    ## Déclaration des contraintes

    # contraintes définissant la structure de l'arbre
    if multivariate
        @constraint(m, [t in 1:sepCount], d[t] + sum(c[k, t] for k in 1:classCount) == 1) # on s'assure que le noeud applique une règle de branchement OU attribue une classe
        @constraint(m, [t in 1:sepCount], b[t] <= d[t]) # b doit être nul si il n'y a pas de branchement
        @constraint(m, [t in 1:sepCount], b[t] >= -d[t]) # b doit être nul si il n'y a pas de branchement
        @constraint(m, [t in 1:sepCount], sum(a_h[j, t] for j in 1:featuresCount) <= d[t]) # on borne la norme du vecteur a
        @constraint(m, [t in 1:sepCount, j in 1:featuresCount], a[j, t] <= a_h[j, t]) # définition de â borne sup de la valeur absolu de a
        @constraint(m, [t in 1:sepCount, j in 1:featuresCount], a[j, t] >= -a_h[j, t]) # définition de â borne sup de la valeur absolu de a
        @constraint(m, [t in 1:sepCount, j in 1:featuresCount], a[j, t] <= s[j, t]) # définition de s, non nul ssi a non nul
        @constraint(m, [t in 1:sepCount, j in 1:featuresCount], a[j, t] >= -s[j, t]) # définition de s, non nul ssi a non nul
        @constraint(m, [t in 1:sepCount, j in 1:featuresCount], s[j, t] <= d[t]) # définition de d, non nul si il existe un coef non nul
        @constraint(m, [t in 1:sepCount], sum(s[j, t] for j in 1:featuresCount) >= d[t]) # définition de d, non nul si il existe un coef non nul
        @constraint(m, [t in 2:sepCount], d[t] <= d[t ÷ 2]) # on s'assure que si un noeud de branchement n'applique pas de règle de branchement, ses fils non plus
    else
        @constraint(m, [t in 1:sepCount], sum(a[j, t] for j in 1:featuresCount) + sum(c[k, t] for k in 1:classCount) == 1) # on s'assure que le noeud applique une règle de branchement OU attribue une classe
        @constraint(m, [t in 1:sepCount], b[t] <= sum(a[j, t] for j in 1:featuresCount)) # b doit être nul si il n'y a pas de branchement
        @constraint(m, [t in 1:sepCount], b[t] >= 0) # b doit être positif
    end
    @constraint(m, [t in (sepCount+1):(sepCount+leavesCount)], sum(c[k, t] for k in 1:classCount) == 1) # on s'assure qu'on attribue une classe par feuille

    # contraintes de conservation du flot et contraintes de capacité
    @constraint(m, [i in 1:dataCount, t in 1:sepCount], u_at[i, t] == u_at[i, t*2] + u_at[i, t*2+1] + u_tw[i, t]) # conservation du flot dans les noeuds de branchement
    @constraint(m, [i in 1:dataCount, t in (sepCount+1):(sepCount+leavesCount)], u_at[i, t] == u_tw[i, t]) # conservation du flot dans les feuilles
    @constraint(m, [i in 1:dataCount, t in 1:(sepCount+leavesCount)], u_tw[i, t] <= c[y[i], t]) # contrainte de capacité qui impose le flot a etre nul si la classe de la feuille n'est pas la bonne
    if multivariate
        @constraint(m, [i in 1:dataCount, t in 1:sepCount], sum(a[j, t]*x[i, j] for j in 1:featuresCount) + mu <= b[t] + (2+mu)*(1-u_at[i, t*2])) # contrainte de capacité controlant le passage dans le noeud fils gauche
        @constraint(m, [i in 1:dataCount, t in 1:sepCount], sum(a[j, t]*x[i, j] for j in 1:featuresCount) >= b[t] - 2*(1-u_at[i, t*2 + 1])) # contrainte de capacité controlant le passage dans le noeud fils droit
        @constraint(m, [i in 1:dataCount, t in 1:sepCount], u_at[i, t*2+1] <= d[t]) # contrainte de capacité empechant les données de passer dans le fils droit d'un noeud n'appliquant pas de règle de branchement
    else
        @constraint(m, [i in 1:dataCount, t in 1:sepCount], sum(a[j, t]*(x[i, j]+mu_vect[j]-mu_min) for j in 1:featuresCount) + mu_min <= b[t] + (1+mu_max)*(1-u_at[i, t*2])) # contrainte de capacité controlant le passage dans le noeud fils gauche
        @constraint(m, [i in 1:dataCount, t in 1:sepCount], sum(a[j, t]*x[i, j] for j in 1:featuresCount) >= b[t] - (1-u_at[i, t*2 + 1])) # contrainte de capacité controlant le passage dans le noeud fils droit
        @constraint(m, [i in 1:dataCount, t in 1:sepCount], u_at[i, t*2+1] <= sum(a[j, t] for j in 1:featuresCount)) # contrainte de capacité empechant les données de passer dans le fils droit d'un noeud n'appliquant pas de règle de branchement
        @constraint(m, [i in 1:dataCount, t in 1:sepCount], u_at[i, t*2] <= sum(a[j, t] for j in 1:featuresCount)) # contrainte de capacité empechant les données de passer dans le fils gauche d'un noeud n'appliquant pas de règle de branchement
    end

    ## Déclaration de l'objectif
    if multivariate
        @objective(m, Max,  sum(u_at[i, 1] for i in 1:dataCount))
    else
        @objective(m, Max, sum(u_at[i, 1] for i in 1:dataCount))
    end

    classif = @expression(m, sum(u_at[i, 1] for i in 1:dataCount))

    starting_time = time()
    optimize!(m)
    resolution_time = time() - starting_time

    # class[t] : classe prédite par le sommet t
    class = Vector{Int64}(undef, sepCount+leavesCount)
    for t in 1:(sepCount+leavesCount)
        k = argmax(value.(c[:, t]))
        if value.(c[k, t])  >=  1.0 - 10^-4
            class[t] = k
        else
            class[t] = -1
        end
    end

    gap = -1.0

    # Arbre obtenu (vide si le solveur n'a trouvé aucune solution)
    T = nothing

    # Si une solution a été trouvée
    if primal_status(m) == MOI.FEASIBLE_POINT

        # Si une solution optimale a été trouvée
        if termination_status(m) == MOI.OPTIMAL
            gap = 0
        else
            # Calcul du gap relatif entre l'objectif de la meilleure solution entière et la borne continue en fin de résolution
            objective = JuMP.objective_value(m)
            bound = JuMP.objective_bound(m)
            gap = 100.0 * abs(objective - bound) / (objective + 10^-4) # +10^-4 permet d'éviter de diviser par 0
        end

        # Construction d'une variable de type Tree dans laquelle chaque séparation est recentrée
        if multivariate
            T = Tree(D, class, round.(Int, value.(u_at)), round.(Int, value.(s)), x)
        else
            T = Tree(D, value.(a), class, round.(Int, value.(u_at)), x)
        end
    end

    return T, objective_value(m), resolution_time, gap
end

"""
FONCTION SIMILAIRE A LA PRECEDENTE UTILISEE UNIQUEMENT SI VOUS FAITES DES REGROUPEMENTS

Construit un arbre de décision par résolution d'un programme linéaire en nombres entiers

Entrées :
- clusters : partition des données d'entraînement (chaque cluster contient des données de même classe)
- D : Nombre maximal de séparations d'une branche (profondeur de l'arbre - 1)
- multivariate (optionnel): vrai si les séparations sont multivariées; faux si elles sont univariées (faux par défaut)
- mu (optionnel, utilisé en multivarié): distance minimale à gauche d'une séparation où aucune donnée ne peut se trouver (i.e., pour la séparation ax <= b, il n'y aura aucune donnée dans ]b - ax - mu, b - ax[) (10^-4 par défaut)
- time_limits (optionnel) : temps maximal de résolution (-1 si le temps n'est pas limité) (-1 par défaut)
"""
function build_tree(clusters::Vector{Cluster}, D::Int64;multivariate::Bool=false, time_limit::Int64 = -1, mu::Float64=10^(-4))

    clusterCount = length(clusters) # Nombre de données d'entraînement
    featuresCount = length(clusters[1].lBounds) # Nombre de caractéristiques
    classCount = length(unique(c -> c.class, clusters)) # Nombre de classes différentes
    sepCount = 2^D - 1 # Nombre de séparations de l'arbre
    leavesCount = 2^D # Nombre de feuilles de l'arbre

    m = Model(CPLEX.Optimizer)

    set_silent(m) # Masque les sorties du solveur

    if time_limit!=-1
        set_time_limit_sec(m, time_limit)
    end

    # Plus petite différence entre deux données pour une caractéristique
    mu_min = 1.0
    # Plus grande différence entre deux données pour une caractéristique
    mu_max = 0.0

    if !multivariate # calcul des constantes mu_min, mu_max et du vecteur mu
        mu_vect = ones(Float64, featuresCount)
        for j in 1:featuresCount
            for i1 in 1:clusterCount
                for i2 in (i1+1):clusterCount

                    v1 = clusters[i1].lBounds[j] - clusters[i2].uBounds[j]
                    v2 = clusters[i2].lBounds[j] - clusters[i1].uBounds[j]

                    # Si les clusters n'ont pas des intervalles pour la caractéristique j qui s'intersectent
                    if v1 > 0 || v2 > 0
                        vMin = min(abs(v1), abs(v2))
                        mu_vect[j] = min(mu_vect[j], vMin)
                    end
                end
            end
            mu_min = min(mu_min, mu_vect[j])
            mu_max = max(mu_max, mu_vect[j])
        end
    end

    ## Déclaraction des variables
    if multivariate
        @variable(m, a[1:featuresCount, 1:sepCount], base_name="a_{j, t}")
        @variable(m, a_h[1:featuresCount, 1:sepCount], base_name="â_{j, t}")
        @variable(m, s[1:featuresCount, 1:sepCount], Bin, base_name="s_{j, t}")
        @variable(m, d[1:sepCount], Bin, base_name="d_t")
    else
        @variable(m, a[1:featuresCount, 1:sepCount], Bin, base_name="a")
    end
    @variable(m, b[1:sepCount], base_name="b_t")
    @variable(m, c[1:classCount, 1:(sepCount+leavesCount)], Bin, base_name = "c_{k, t}")
    @variable(m, u_at[1:clusterCount, 1:(sepCount+leavesCount)], Bin, base_name = "u^i_{a(t), t}")
    @variable(m, u_tw[1:clusterCount, 1:(sepCount+leavesCount)], Bin, base_name = "u^i_{t, w}")

    ## Déclaration des contraintes

    # Contraintes définissant la structure de l'arbre
    if multivariate
        @constraint(m, [t in 1:sepCount], d[t] + sum(c[k, t] for k in 1:classCount) == 1) # on s'assure que le noeud applique une règle de branchement OU attribue une classe
        @constraint(m, [t in 1:sepCount], b[t] <= d[t]) # b doit être nul si il n'y a pas de branchement
        @constraint(m, [t in 1:sepCount], b[t] >= -d[t]) # b doit être nul si il n'y a pas de branchement
        @constraint(m, [t in 1:sepCount], sum(a_h[j, t] for j in 1:featuresCount) <= d[t]) # on borne la norme du vecteur a
        @constraint(m, [t in 1:sepCount, j in 1:featuresCount], a[j, t] <= a_h[j, t]) # définition de â borne sup de la valeur absolu de a
        @constraint(m, [t in 1:sepCount, j in 1:featuresCount], a[j, t] >= -a_h[j, t]) # définition de â borne sup de la valeur absolu de a
        @constraint(m, [t in 1:sepCount, j in 1:featuresCount], a[j, t] <= s[j, t]) # définition de s, non nul ssi a non nul
        @constraint(m, [t in 1:sepCount, j in 1:featuresCount], a[j, t] >= -s[j, t]) # définition de s, non nul ssi a non nul
        @constraint(m, [t in 1:sepCount, j in 1:featuresCount], s[j, t] <= d[t]) # définition de d, non nul si il existe un coef non nul
        @constraint(m, [t in 1:sepCount], sum(s[j, t] for j in 1:featuresCount) >= d[t]) # définition de d, non nul si il existe un coef non nul
        @constraint(m, [t in 2:sepCount], d[t] <= d[t ÷ 2]) # on s'assure que si un noeud de branchement n'applique pas de règle de branchement, ses fils non plus
    else
        @constraint(m, [t in 1:sepCount], sum(a[j, t] for j in 1:featuresCount) + sum(c[k, t] for k in 1:classCount) == 1) # on s'assure que le noeud applique une règle de branchement OU attribue une classe
        @constraint(m, [t in 1:sepCount], b[t] <= sum(a[j, t] for j in 1:featuresCount)) # b doit être nul si il n'y a pas de branchement
        @constraint(m, [t in 1:sepCount], b[t] >= 0) # b doit être positif
    end
    @constraint(m, [t in (sepCount+1):(sepCount+leavesCount)], sum(c[k, t] for k in 1:classCount) == 1) # on s'assure qu'on attribue une classe par feuille

    # contraintes de conservation du flot et contraintes de capacité
    @constraint(m, [i in 1:clusterCount, t in 1:sepCount], u_at[i, t] == u_at[i, t*2] + u_at[i, t*2+1] + u_tw[i, t]) # conservation du flot dans les noeuds de branchement
    @constraint(m, [i in 1:clusterCount, t in (sepCount+1):(sepCount+leavesCount)], u_at[i, t] == u_tw[i, t]) # conservation du flot dans les feuilles
    @constraint(m, [i in 1:clusterCount, t in 1:(sepCount+leavesCount)], u_tw[i, t] <= c[clusters[i].class, t]) # contrainte de capacité qui impose le flot a etre nul si la classe de la feuille n'est pas la bonne
    if multivariate

        @constraint(m, [i in 1:clusterCount, t in 1:sepCount, dataId in 1:size(clusters[i].x, 1)], sum(a[j, t]*clusters[i].x[dataId, j] for j in 1:featuresCount) + mu <= b[t] + (2+mu)*(1-u_at[i, t*2])) # contrainte de capacité controlant le passage dans le noeud fils gauche
        @constraint(m, [i in 1:clusterCount, t in 1:sepCount, dataId in 1:size(clusters[i].x, 1)], sum(a[j, t]*clusters[i].x[dataId, j] for j in 1:featuresCount) >= b[t] - 2*(1-u_at[i, t*2 + 1])) # contrainte de capacité controlant le passage dans le noeud fils droit
        @constraint(m, [i in 1:clusterCount, t in 1:sepCount], u_at[i, t*2+1] <= d[t]) # contrainte de capacité empechant les données de passer dans le fils droit d'un noeud n'appliquant pas de règle de branchement
    else
        @constraint(m, [i in 1:clusterCount, t in 1:sepCount], sum(a[j, t]*(clusters[i].uBounds[j]+mu_vect[j]-mu_min) for j in 1:featuresCount) + mu_min <= b[t] + (1+mu_max)*(1-u_at[i, t*2])) # contrainte de capacité controlant le passage dans le noeud fils gauche
        @constraint(m, [i in 1:clusterCount, t in 1:sepCount], sum(a[j, t]*clusters[i].lBounds[j] for j in 1:featuresCount) >= b[t] - (1-u_at[i, t*2 + 1])) # contrainte de capacité controlant le passage dans le noeud fils droit
        @constraint(m, [i in 1:clusterCount, t in 1:sepCount], u_at[i, t*2+1] <= sum(a[j, t] for j in 1:featuresCount)) # contrainte de capacité empechant les données de passer dans le fils droit d'un noeud n'appliquant pas de règle de branchement
    end

    ## Déclaration de l'objectif
    if multivariate
        @objective(m, Max, sum(length(clusters[i].dataIds) * u_at[i, 1] for i in 1:clusterCount))
    else
        @objective(m, Max, sum(length(clusters[i].dataIds) * u_at[i, 1] for i in 1:clusterCount))
    end

    starting_time = time()
    optimize!(m)
    resolution_time = time() - starting_time

    # class[t] : classe prédite par le sommet t
    class = Vector{Int64}(undef, sepCount+leavesCount)
    for t in 1:(sepCount+leavesCount)
        k = argmax(value.(c[:, t]))
        if value.(c[k, t]) >= 1.0 - 10^-4
            class[t] = k
        else
            class[t] = -1
        end
    end

    gap = -1.0

    # Arbre obtenu (vide si le solveur n'a trouvé aucune solution)
    T = nothing

    # Si une solution a été trouvée
    if primal_status(m) == MOI.FEASIBLE_POINT

        # Si une solution optimale a été trouvée
        if termination_status(m) == MOI.OPTIMAL
            gap = 0
        else
            # Calcul du gap relatif entre l'objectif de la meilleure solution entière et la borne continue en fin de résolution
            objective = JuMP.objective_value(m)
            bound = JuMP.objective_bound(m)
            gap = 100.0 * abs(objective - bound) / (objective + 10^-4) # +10^-4 permet d'éviter de diviser par 0
        end

        # Construction d'une variable de type Tree dans laquelle chaque séparation est recentrée
        if multivariate
            T = Tree(D, class, round.(Int, value.(u_at)), round.(Int, value.(s)), clusters)
        else
            T = Tree(D, value.(a), class, round.(Int, value.(u_at)), clusters)
        end
    end

    return T, objective_value(m), resolution_time, gap
end

max_stars_repo_name: boumpteryx/RODM

max_issues_repo_name: boumpteryx/RODM

max_forks_repo_name: boumpteryx/RODM


text:
push!(LOAD_PATH,"../src/")
using InventoryManagement
using Documenter
makedocs(
         sitename = "InventoryManagement.jl",
         modules  = [InventoryManagement],
         pages=[
                "Home" => "index.md",
                "Sequence of Events" => "events.md",
                "Inventory Policies" => "policies.md",
                "Simulation Model" => "model.md",
                "Examples" => "examples.md",
                "API" => "api.md"
               ])
deploydocs(;
    repo="github.com/hdavid16/InventoryManagement.jl",
)

ext: jl


text:
#
# This file is part of module
#   ModiaMedia (ModiaMedia/src/ModiaMedia.jl)
#

#=
# A medium is defined by a struct and accompanying functions. The struct has the following structure:
    struct MediumXXX <: AbstractMedium
        mediumName::AbstractString
        substanceNames::Vector{AbstractString}
        < ... other generic data >
        fluidConstants::Vector{AbstractFluidConstants}
        fluidLimits::FluidLimits
        data  # medium specific data
    end

    All media are stored in dictionary mediumDict
=#

undefinedFunction(name::AbstractString, m::AbstractMedium) =
    error("\n\nModiaMedia: Function $name not defined for medium $(m.infos.mediumName).\n")

### Enumerations and constants --------------------------------------------------------------------

"""
    @enum IndependentVariables

Enumeration defining the independent variables of a medium. Possible values:

| Value                      | Independent variables                       |
|:---------------------------|:--------------------------------------------|
| `IndependentVariables_T`   | Temperature                                 |
| `IndependentVariables_pT`  | Pressure, temperature                       |
| `IndependentVariables_ph`  | Pressure, specific enthalpy                 |
| `IndependentVariables_phX` | Pressure, specific enthalpy, mass fractions |
| `IndependentVariables_pTX` | Pressure, temperature, mass fractions       |
| `IndependentVariables_dTX` | Density, temperature, mass fractions        |
"""
@enum IndependentVariables begin
    IndependentVariables_T=1       # Temperature
    IndependentVariables_pT        # Pressure, Temperature
    IndependentVariables_ph        # Pressure, Specific Enthalpy
    IndependentVariables_phX       # Pressure, Specific Enthalpy, Mass Fraction
    IndependentVariables_pTX       # Pressure, Temperature, Mass Fractions
    IndependentVariables_dTX       # Density, Temperature, Mass Fractions
end

"""
    state = ThermodynamicState_pT(p,T)

Generate a `ThermodynamicState_pT <: ThermodynamicState` object containg
pressure `p` [Pa] and temperature `T` [K] as states.
"""
mutable struct ThermodynamicState_pT <: ThermodynamicState
    p::Float64
    T::Float64
end

const ThermodynamicStates = MVector{6,Any}(nothing,
                                           ThermodynamicState_pT,
                                           nothing,
                                           nothing,
                                           nothing,
                                           nothing)

"""
    @enum ReferenceEnthalpy

Enumeration defining the reference enthalpy of a medium. Possible values:

- `ReferenceEnthalpy_ZeroAt0K`: The enthalpy is 0 at 0 K (default), if the enthalpy of formation is excluded
- `ReferenceEnthalpy_ZeroAt25C`: The enthalpy is 0 at 25 degC, if the enthalpy of formation is excluded
- `ReferenceEnthalpy_UserDefined`: The user-defined reference enthalpy is used at 293.15 K (25 degC)
"""
@enum ReferenceEnthalpy begin
    ReferenceEnthalpy_ZeroAt0K     # The enthalpy is 0 at 0 K (default), if the enthalpy of formation is excluded
    ReferenceEnthalpy_ZeroAt25C    # The enthalpy is 0 at 25 degC, if the enthalpy of formation is excluded
    ReferenceEnthalpy_UserDefined  # The user-defined reference enthalpy is used at 293.15 K (25 degC)
end

"""
    @enum ReferenceEntropy

Enumeration defining the reference entropy of a medium. Possible values:

- `ReferenceEntropy_ZeroAt0K`: The entropy is 0 at 0 K (default)
- `ReferenceEntropy_ZeroAt0C`: The entropy is 0 at 0 degC
- `ReferenceEntropy_UserDefined`: The user-defined reference entropy is used at 293.15 K (25 degC)
"""
@enum ReferenceEntropy begin
    ReferenceEntropy_ZeroAt0K      # The entropy is 0 at 0 K (default)
    ReferenceEntropy_ZeroAt0C      # The entropy is 0 at 0 degC
    ReferenceEntropy_UserDefined   # The user-defined reference entropy is used at 293.15 K (25 degC)
end

"Enumeration Init defining initialization for fluid flow"
@enum Init begin
    Init_NoInit                    # NoInit (no initialization)
    Init_InitialStates             # InitialStates (initialize medium states)
    Init_SteadyState               # SteadyState (initialize in steady state)
    Init_SteadyMass                # SteadyMass (initialize density or pressure in steady state)
end

"Enumeration pd defining whether p or d are known for the boundary condition"
@enum pd begin
    pd_default                     # Default (no boundary condition for p or d)
    pd_p_known                     # p_known (pressure p is known)
    pd_d_known                     # d_known (density d is known)
end

"Enumeration Th - defining whether T or h are known as boundary condition"
@enum Th begin
    Th_default                     # Default (no boundary condition for T or h)
    Th_T_known                     # T_known (temperature T is known)
    Th_h_known                     # h_known (specific enthalpy h is known)
end

### Data structures ---------------------------------------------------------------------------------

"""
    infos = FluidInfos(; <keyword arguments, see below>)

Generate a new `FluidInfos` object, containing generic properties of a medium.

# Keyword arguments

| Name and type                                  | Description                                                                                |
|:-----------------------------------------------|:--------------------------------------------------------------------------------------------------------|
| `mediumName::AbstractString`                   | Name of the medium                                                                                |
| `substanceNames::Vector{AbstractString}`       | Names of the mixture substances. Set substanceNames=[mediumName] if only one substance.                 |
| `extraPropertiesNames::Vector{AbstractString}` | Names of the additional (extra) transported properties. Set extraPropertiesNames=fill(\"\",0) if unused |
| `ThermoStates::IndependentVariables`           | Enumeration type for independent variables                                                              |
| `baseProperties::Symbol`                       | Symbol of baseProperties model = :BaseProperties_<StructName>                                           |
| `singleState::Bool`                            | = true, if u and d are not a function of pressure                                                       |
| `reducedX::Bool`                               | = true if medium contains the equation sum(X) = 1.0; set reducedX=true if only one substance            |
| `fixedX::Bool`                                 | = true if medium contains the equation X = reference_X                                                  |
| `reference_p`                                  | Reference pressure of Medium: default 1 atmosphere                                                      |
| `reference_T`                                  | Reference temperature of Medium: default 25 deg Celsius                                                 |
| `reference_X`                                  | Reference mass fractions of medium                                                                      |
| `p_default`                                    | Default value for pressure of medium (for initialization)                                               |
| `T_default`                                    | Default value for temperature of medium (for initialization)                                            |
| `h_default`                                    | Default value for specific enthalpy of medium (for initialization)                                      |
| `X_default`                                    | Default value for specific enthalpy of medium (for initialization)                                      |
| `nS`                                           | Number of substances                                                                                |
| `nX`                                           | Number of mass fractions                                                                                |
| `nXi`                                          | Number of structurally independent mass fractions                                                       |
| `nC`                                           | Number of extra (outside of standard mass-balance) transported properties                               |
| `C_nominal`                                    | Default for the nominal values for the extra properties                                                 |

# Example
```julia
import ModiaMedia

infos = ModiaMedia.FluidInfos(mediumName           = "simpleMedium",
                              substanceNames       = [mediumName],
                              extraPropertiesNames = fill("",0),
                              ThermoStates         = IndependentVariables_T)
```
"""
struct FluidInfos
    mediumName::AbstractString                   # "Name of the medium";
    substanceNames::Vector{AbstractString}       # "Names of the mixture substances. Set substanceNames=[mediumName] if only one substance.";
    extraPropertiesNames::Vector{AbstractString} # "Names of the additional (extra) transported properties. Set extraPropertiesNames=fill(\"\",0) if unused"
    ThermoStates::IndependentVariables           # "Enumeration type for independent variables";
    baseProperties::Symbol                       # "Symbol of baseProperties model = :BaseProperties_<StructName>
    singleState::Bool                            # "= true, if u and d are not a function of pressure";
    reducedX::Bool                               # "= true if medium contains the equation sum(X) = 1.0; set reducedX=true if only one substance (see docu for details)";
    fixedX::Bool                                 # "= true if medium contains the equation X = reference_X";
    reference_p::Float64                         # "Reference pressure of Medium: default 1 atmosphere";
    reference_T::Float64                         # "Reference temperature of Medium: default 25 deg Celsius";
    reference_X::AbstractVector                  # "Reference mass fractions of medium";
    p_default::Float64                           # "Default value for pressure of medium (for initialization)";
    T_default::Float64                           # "Default value for temperature of medium (for initialization)";
    h_default::Float64                           # "Default value for specific enthalpy of medium (for initialization)";
    X_default::Vector{Float64}                   # "Default value for specific enthalpy of medium (for initialization)";
    nS::Int                                      # "Number of substances"
    nX::Int                                      # "Number of mass fractions"
    nXi::Int                                     # "Default value for mass fractions of medium (for initialization)"
    nC::Int                                      # "Number of extra (outside of standard mass-balance) transported properties"
    C_nominal::Vector{Float64}                   # "Default for the nominal values for the extra properties"

    function FluidInfos(; mediumName=Missing,
                          substanceNames=[mediumName],
                          extraPropertiesNames=fill("",0),
                          ThermoStates=Missing,
                          baseProperties=Missing,
                          singleState=Missing,
                          reducedX=true,
                          fixedX=false,
                          reference_p=101325,
                          reference_T=298.15,
                          reference_X=fill(1/length(substanceNames),length(substanceNames)),
                          p_default=101325,
                          T_default=293.15,
                          h_default=NaN,
                          X_default=reference_X,
                          C_nominal=1e-6*ones(length(extraPropertiesNames)))
         nS  = length(substanceNames)
         nXi = fixedX ? 0 : ( reducedX ? nS-1 : nS )
         nC  = length(extraPropertiesNames)

         new(mediumName, substanceNames, extraPropertiesNames,
             ThermoStates, baseProperties, singleState, reducedX, fixedX, reference_p,
             reference_T, reference_X, p_default, T_default, h_default, X_default,
             nS, nS, nXi, nC, C_nominal)
    end
end

"""
    fluidLimits = FluidLimits(; TMIN=NaN, TMAX=NaN, DMIN=NaN, DMAX=NaN, PMIN=NaN, PMAX=NaN,
                                HMIN=NaN, HMAX=NaN, SMIN=NaN, SMAX=NaN)

Generate a new `FluidLimits` object, containing the validity limits of the medium.
"""
mutable struct FluidLimits
    TMIN::Float64  # "Minimum temperature";
    TMAX::Float64  # "Maximum temperature";
    DMIN::Float64  # "Minimum density";
    DMAX::Float64  # "Maximum density";
    PMIN::Float64  # "Minimum pressure";
    PMAX::Float64  # "Maximum pressure";
    HMIN::Float64  # "Minimum enthalpy";
    HMAX::Float64  # "Maximum enthalpy";
    SMIN::Float64  # "Minimum entropy";
    SMAX::Float64  # "Maximum entropy";

    FluidLimits(; TMIN=NaN, TMAX=NaN, DMIN=NaN, DMAX=NaN, PMIN=NaN, PMAX=NaN,
                  HMIN=NaN, HMAX=NaN, SMIN=NaN, SMAX=NaN) =
              new(TMIN, TMAX, DMIN, DMAX, PMIN, PMAX, HMIN, HMAX, SMIN, SMAX)
end

"""
    fluidConstants = BasicFluidConstants(;iupacName="", casRegistryNumber="",
                         chemicalFormula="", structureFormula="", molarMass=NaN)

Generate a `BasicFluidConstants <: AbstractFluidConstants` object
containing the minimal information about the standard data of the medium.
"""
mutable struct BasicFluidConstants <: AbstractFluidConstants
    iupacName::AbstractString           # "Complete IUPAC name (or common name, if non-existent)";
    casRegistryNumber::AbstractString   # "Chemical abstracts sequencing number (if it exists)";
    chemicalFormula::AbstractString     # "Chemical formula, (brutto, nomenclature according to Hill";
    structureFormula::AbstractString    # "Chemical structure formula";
    molarMass::Float64                  # "Molar mass";

    BasicFluidConstants(;iupacName="", casRegistryNumber="", chemicalFormula="", structureFormula="", molarMass=NaN) =
       new(iupacName, casRegistryNumber, chemicalFormula, structureFormula, molarMass)
end

"""
    fluidConstants = IdealGasFluidConstants(; iupacName="", casRegistryNumber="",
          chemicalFormula="", structureFormula="", molarMass=NaN,
          criticalTemperature=NaN, criticalPressure=NaN, criticalMolarVolume=NaN,
          acentricFactor=NaN, meltingPoint=NaN, normalBoilingPoint=NaN, dipoleMoment=NaN,
          hasIdealGasHeatCapacity=false, hasCriticalData=false, hasDipoleMoment=false,
          hasFundamentalEquation=false, hasLiquidHeatCapacity=false, hasSolidHeatCapacity=false,
          hasAccurateViscosityData=false, hasAccurateConductivityData=false,
          hasVapourPressureCurve=false, hasAcentricFactor=false,
          HCRIT0=0.0, SCRIT0=0.0, deltah=0.0, deltas=0.0)

Generate a `IdealGasFluidConstants <: AbstractFluidConstants` object
containing the minimal information about the standard data of ideal gas media
(critical, triple, molecular and other standard data).
"""
mutable struct IdealGasFluidConstants <: AbstractFluidConstants
    iupacName::AbstractString           # "Complete IUPAC name (or common name, if non-existent)";
    casRegistryNumber::AbstractString   # "Chemical abstracts sequencing number (if it exists)";
    chemicalFormula::AbstractString     # "Chemical formula, (brutto, nomenclature according to Hill";
    structureFormula::AbstractString    # "Chemical structure formula";
    molarMass::Float64                  # "Molar mass";

    criticalTemperature::Float64        # "Critical temperature";
    criticalPressure::Float64           # "Critical pressure";
    criticalMolarVolume::Float64        # "Critical molar Volume";
    acentricFactor::Float64             # "Pitzer acentric factor";
    meltingPoint::Float64               # "Melting point at 101325 Pa";
    normalBoilingPoint::Float64         # "Normal boiling point (at 101325 Pa)";
    dipoleMoment::Float64               # "Dipole moment of molecule in Debye (1 debye = 3.33564e10-30 C.m)";

    hasIdealGasHeatCapacity::Bool       # "True if ideal gas heat capacity is available";
    hasCriticalData::Bool               # "True if critical data are known";
    hasDipoleMoment::Bool               # "True if a dipole moment known";
    hasFundamentalEquation::Bool        # "True if a fundamental equation";
    hasLiquidHeatCapacity::Bool         # "True if liquid heat capacity is available";
    hasSolidHeatCapacity::Bool          # "True if solid heat capacity is available";
    hasAccurateViscosityData::Bool      # "True if accurate data for a viscosity function is available";
    hasAccurateConductivityData::Bool   # "True if accurate data for thermal conductivity is available";
    hasVapourPressureCurve::Bool        # "True if vapour pressure data, e.g., Antoine coefficients are known";
    hasAcentricFactor::Bool             # "True if Pitzer accentric factor is known";

    HCRIT0::Float64                     # "Critical specific enthalpy of the fundamental equation";
    SCRIT0::Float64                     # "Critical specific entropy of the fundamental equation";
    deltah::Float64                     # "Difference between specific enthalpy model (h_m) and f.eq. (h_f) (h_m - h_f)";
    deltas::Float64                     # "Difference between specific enthalpy model (s_m) and f.eq. (s_f) (s_m - s_f)";

    IdealGasFluidConstants(; iupacName="", casRegistryNumber="", chemicalFormula="", structureFormula="", molarMass=NaN,
                             criticalTemperature=NaN, criticalPressure=NaN, criticalMolarVolume=NaN,
                             acentricFactor=NaN, meltingPoint=NaN, normalBoilingPoint=NaN, dipoleMoment=NaN,
                             hasIdealGasHeatCapacity=false, hasCriticalData=false, hasDipoleMoment=false,
                             hasFundamentalEquation=false, hasLiquidHeatCapacity=false, hasSolidHeatCapacity=false,
                             hasAccurateViscosityData=false, hasAccurateConductivityData=false,
                             hasVapourPressureCurve=false, hasAcentricFactor=false,
                             HCRIT0=0.0, SCRIT0=0.0, deltah=0.0, deltas=0.0) =
        new(iupacName, casRegistryNumber, chemicalFormula, structureFormula, molarMass,
            criticalTemperature, criticalPressure, criticalMolarVolume, acentricFactor, meltingPoint,
            normalBoilingPoint, dipoleMoment, hasIdealGasHeatCapacity, hasCriticalData, hasDipoleMoment,
            hasFundamentalEquation, hasLiquidHeatCapacity, hasSolidHeatCapacity, hasAccurateViscosityData,
            hasAccurateConductivityData, hasVapourPressureCurve, hasAcentricFactor,
            HCRIT0, SCRIT0, deltah, deltas)
end

"""
    state = setState_pTX(medium, p,T,X)

Generate a state object for medium `medium::AbstractMedium` for
pressure `p` [Pa], temperature `T` [K] and mass fractions vector `X` or `Xi`.
"""
setState_pTX(m::AbstractMedium,p,T,X) = undefinedFunction("setState_pTX", m)

"""
    state = setState_phX(medium, p,h,X)

Generate a state object for medium `medium::AbstractMedium` for
pressure `p` [Pa], specific enthalpy `h` [J/kg]] and mass fractions vector `X` or `Xi`.
"""
setState_phX(m::AbstractMedium,p,h,X) = undefinedFunction("setState_phX", m)

"""
    state = setState_psX(medium, p,s,X)

Generate a state object for medium `medium::AbstractMedium` for
pressure `p` [Pa], specific entropy `s` [J/(kg*K)] and mass fractions vector `X`  or `Xi`.
"""
setState_psX(m::AbstractMedium,p,s,X) = undefinedFunction("setState_psX", m)

"""
    state = setState_dTX(medium, d,T,X)

Generate a state object for medium `medium::AbstractMedium` for
density `d` [kg/m^3], temperature `T` [K] and mass fractions vector `X` or `Xi`.
"""
setState_dTX(m::AbstractMedium,d,T,X) = undefinedFunction("setState_dTX", m)

### Medium functions ---------------------------------------------------------------------------------

"p = pressure(medium,state) - return pressure for `medium` from `state` in [Pa]"
pressure(m::AbstractMedium, state::ThermodynamicState) = undefinedFunction("pressure", m)

"T = temperature(medium,state) - return temperature for `medium` from `state` in [K]"
temperature(m::AbstractMedium, state::ThermodynamicState) = undefinedFunction("temperature", m)

"d = density(medium,state) - return density for `medium` from `state` in [kg/m^3]"
density(m::AbstractMedium, state::ThermodynamicState) = undefinedFunction("density", m)

"h = specificEnthalpy(medium,state) - return specific enthalpy for `medium` from `state` in [J/kg]"
specificEnthalpy(m::AbstractMedium, state::ThermodynamicState) = undefinedFunction("specificEnthalpy", m)

"u = specificInternalEnergy(medium,state) - return specific internal energy from `medium` at `state` in [J/kg]"
specificInternalEnergy(m::AbstractMedium, state::ThermodynamicState) = undefinedFunction("specificInternalEnergy", m)

"cp = specificHeatCapacityCp(medium,state) - return specific heat capacity at constant pressure for `medium` from `state` in [J/(kg*K)]"
specificHeatCapacityCp(m::AbstractMedium, state::ThermodynamicState) = undefinedFunction("specificHeatCapacity", m)

### Medium functions expressed from the functions above -------------------------------------------------

"h = specificEnthalpy_pTX(medium,p,T,X) - return specific enthalpy for `medium` from p, T, and X or Xi in [J/kg]"
specificEnthalpy_pTX(m::AbstractMedium, p,T,X) = specficEnthalpy(m, setState_pTX(m,p,T,X))

"T = temperature_phX(medium,p,h,X) - return temperature for `medium` from p, h, and X or Xi in [K]"
temperature_phX(m::AbstractMedium, p,h,X) = temperature(m, setState_phX(m,p,h,X))

"d = density_pTX(medium,p,T,X) - return density for `medium` from p, T, and X or Xi in [kg/m^3]"
density_pTX(m::AbstractMedium, p,T,X) = density(m, setState_pTX(m,p,T,X))

"d = density_phX(medium,p,h,X) - return density for `medium` from p, h, and X or Xi in [kg/m^3]"
density_phX(m::AbstractMedium, p,h,X) = density(m, setState_phX(m,p,h,X))

### Other functions operating on the medium ---------------------------------------------------------------------------------

to_DensityDisplayUnit(d) = d*1e-3
from_degC(Celsius)       = Celsius + 273.15

"""
    dict = standardCharacteristics(medium::AbstractMedium)

Return a `dict::dict{AbstractString,Any}` dictionary with the most
important characteristics of the medium as vectors.
"""
standardCharacteristics(m::AbstractMedium)::dict{AbstractString,Any} = undefinedFunction("standardCharacteristics", m)

"""
    standardPlot(medium::AbstractMedium; figure=1)

Plot the `standardCharacteristics(medium)` of the medium.
"""
standardPlot(m::AbstractMedium; figure=1) = undefinedFunction("standardPlot", m)

const T_zero = -273.15
to_degC(T_in_K) = T_in_K + Modelica.Constants.T_zero;


text:
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/UMAT.jl/blob/master/LICENSE

dependencies = [
    "https://github.com/TeroFrondelius/umat_binaries_builder/releases/download/v0.5.1/build_umat_binaries.v0.5.1.jl"
]

for build_script in dependencies
    script_name = split(build_script,"/")[end]
    include(download(build_script,script_name))
end


text:
#Struct to hold information on wavelet-grid (u-component).
struct UWavelets{T <: Real, N <: Integer}
          nxuw :: N                                       # Number of grid points in x in UWavelets (equal to UGrid)
          nyuw :: N                                       # Number of grid points in y in UWavelets (equal to UGrid)
        mask :: Array{Bool,2}                           # Model domain on the U grid
           n :: Base.RefValue{N}                        # Number of grid points in domain
        crop :: Base.RefValue{Diagonal{T,Array{T,1}}}   # Crop matrix: diagonal matrix with mask entries on diag
        samp :: Base.RefValue{SparseMatrixCSC{T,N}}     # Sampling matrix: take full domain to model domain
      spread :: Base.RefValue{SparseMatrixCSC{T,N}}     # Spread matrix: take model domain to full domain
      levels :: N                                       # Number of wavelet levels
        idwt :: KronType{T,N}                           # Wavelet matrix cross produce
    wavelets :: Array{T,2}                              # Wavelet matrix
end

"""
    UWavelets(;
            nxuw,
            nyuw,
            mask = trues(nxuw,nyuw),
            levels)

Construct a WAVI.jl UWavelets structure with size (nxuw,nyuw)
UWavelets stores wavelet matrix and associated fields for velocities in x direction

Keyword arguments
=================
    - 'nxuw': (required) Number of grid cells in x-direction in UWavelts
    - 'nyuw': (required) Number of grid cells in y-direction in UWavelets
    - 'mask': Mask specifying the model domain with respect to UWavelet grid (UGrid)
    - levels: (required) Number of levels in the preconditioner
"""
function UWavelets(;
                    nxuw,
                    nyuw,
                    mask = trues(nxuw,nyuw),
                    levels)

    (size(mask) == (nxuw,nyuw)) || throw(DimensionMismatch("Sizes of inputs to UWavelets must all be equal to nxuw x nyuw (i.e. $nxuw x $nyuw)"))

    #compute non-inputs
    n = Ref(count(mask));  @assert n[] == count(mask)
    crop = Ref(Diagonal(float(mask[:]))); @assert crop[] == Diagonal(float(mask[:]));
    samp  = Ref(crop[][mask[:],:]); @assert samp[] == crop[][mask[:],:]
    spread = Ref(sparse(samp[]')); @assert spread[] == sparse(samp[]')
    idwt =  wavelet_matrix(nyuw,levels,"reverse" ) ⊗ wavelet_matrix(nxuw,levels,"reverse")
    wavelets = zeros(nxuw,nyuw); @assert size(wavelets)==(nxuw,nyuw)

    #make sure boolean type rather than bitarray
    mask = convert(Array{Bool,2}, mask)

    return UWavelets(
                    nxuw,
                    nyuw,
                    mask,
                    n,
                    crop,
                    samp,
                    spread,
                    levels,
                    idwt,
                    wavelets)
end


text:
export layerLine, plotHex!, plotHex, plotHex_6, plotBeehive_6

# draw a line on plot
function layerLine(start::Vector{Float64}, stop::Vector{Float64}, color=colorant"green")
  layer(x=[start[1];stop[1]], y=[start[2];stop[2]], Geom.path, Theme(default_color=color))[1]
end

# draw a default hex shape on plot
function plotHex!(offsetxy::Vector{Float64}=zeros(2);
                  len::Float64=10.0,
                  PLT = [])
    #
    push!(PLT, layerLine([offsetxy[1]+0.0;offsetxy[2]+0.0], [offsetxy[1]+len;offsetxy[2]+0.0]))
    push!(PLT, layerLine([offsetxy[1]+len;offsetxy[2]+0.0], [offsetxy[1]+len*3/2;offsetxy[2]+len*sqrt(3)/2]))
    push!(PLT, layerLine([offsetxy[1]+len+5.0;offsetxy[2]+len*sqrt(3)/2], [offsetxy[1]+len;offsetxy[2]+len*sqrt(3)]))
    push!(PLT, layerLine([offsetxy[1]+0;offsetxy[2]+len*sqrt(3)], [offsetxy[1]+10;offsetxy[2]+len*sqrt(3)]))
    push!(PLT, layerLine([offsetxy[1]+0;offsetxy[2]+len*sqrt(3)], [offsetxy[1]-len/2; offsetxy[2]+len*sqrt(3)/2]))
    push!(PLT, layerLine([offsetxy[1]-len/2; offsetxy[2]+len*sqrt(3)/2], [offsetxy[1]+0.0; offsetxy[2]+0]))

    PLT
end

# draw a default hex shape on plot
function plotHex(offsetxy::Vector{Float64}=zeros(2);
                 len::Float64=10.0)
    #
    Gadfly.plot(plotHex!(offsetxy, len=len)...)
end

# draw a default ring of 6 hexes on plot
function plotHex_6(;PLT=[], len::Float64=10.0)
    plotHex!(zeros(2),PLT=PLT)
    plotHex!([3/2*len;-sqrt(3)/2*len],PLT=PLT)
    plotHex!([3/2*len;-sqrt(3)*3/2*len],PLT=PLT)
    plotHex!([0.0;-sqrt(3)*2*len],PLT=PLT)
    plotHex!([-3/2*len;-sqrt(3)*3/2*len],PLT=PLT)
    plotHex!([-3/2*len;-sqrt(3)/2*len],PLT=PLT)

    Gadfly.plot(PLT...)
end

"""
    $SIGNATURES

Plot first ring (ground truth) of beehive example.
"""
function plotBeehive_6(fgl::G; from::Int=0, to::Int=(2^(Sys.WORD_SIZE-1)-1), meanmax::Symbol=:max) where G <: AbstractDFG
  pl = plotHex_6()
  pl2 = drawPosesLandms(fgl, from=from, to=to, meanmax=meanmax)

  union!(pl2.layers, pl.layers)

  return pl2
end


text:
# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/kinsol/kinsol.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function KINCreate()
    ccall((:KINCreate, libsundials_kinsol), KINMemPtr, ())
end

function KINSetErrHandlerFn(kinmem, ehfun::KINErrHandlerFn, eh_data)
    ccall((:KINSetErrHandlerFn, libsundials_kinsol), Cint, (KINMemPtr, KINErrHandlerFn, Ptr{Void}), kinmem, ehfun, eh_data)
end

function KINSetErrFile(kinmem, errfp)
    ccall((:KINSetErrFile, libsundials_kinsol), Cint, (KINMemPtr, Ptr{FILE}), kinmem, errfp)
end

function KINSetInfoHandlerFn(kinmem, ihfun::KINInfoHandlerFn, ih_data)
    ccall((:KINSetInfoHandlerFn, libsundials_kinsol), Cint, (KINMemPtr, KINInfoHandlerFn, Ptr{Void}), kinmem, ihfun, ih_data)
end

function KINSetInfoFile(kinmem, infofp)
    ccall((:KINSetInfoFile, libsundials_kinsol), Cint, (KINMemPtr, Ptr{FILE}), kinmem, infofp)
end

function KINSetUserData(kinmem, user_data)
    ccall((:KINSetUserData, libsundials_kinsol), Cint, (KINMemPtr, Any), kinmem, user_data)
end

function __KINSetPrintLevel(kinmemm, printfl::Cint)
    ccall((:KINSetPrintLevel, libsundials_kinsol), Cint, (KINMemPtr, Cint), kinmemm, printfl)
end

function KINSetPrintLevel(kinmemm, printfl)
    __KINSetPrintLevel(kinmemm, convert(Cint, printfl))
end

function __KINSetMAA(kinmem, maa::Clong)
    ccall((:KINSetMAA, libsundials_kinsol), Cint, (KINMemPtr, Clong), kinmem, maa)
end

function KINSetMAA(kinmem, maa)
    __KINSetMAA(kinmem, convert(Clong, maa))
end

function __KINSetNumMaxIters(kinmem, mxiter::Clong)
    ccall((:KINSetNumMaxIters, libsundials_kinsol), Cint, (KINMemPtr, Clong), kinmem, mxiter)
end

function KINSetNumMaxIters(kinmem, mxiter)
    __KINSetNumMaxIters(kinmem, convert(Clong, mxiter))
end

function __KINSetNoInitSetup(kinmem, noInitSetup::Cint)
    ccall((:KINSetNoInitSetup, libsundials_kinsol), Cint, (KINMemPtr, Cint), kinmem, noInitSetup)
end

function KINSetNoInitSetup(kinmem, noInitSetup)
    __KINSetNoInitSetup(kinmem, convert(Cint, noInitSetup))
end

function __KINSetNoResMon(kinmem, noNNIResMon::Cint)
    ccall((:KINSetNoResMon, libsundials_kinsol), Cint, (KINMemPtr, Cint), kinmem, noNNIResMon)
end

function KINSetNoResMon(kinmem, noNNIResMon)
    __KINSetNoResMon(kinmem, convert(Cint, noNNIResMon))
end

function __KINSetMaxSetupCalls(kinmem, msbset::Clong)
    ccall((:KINSetMaxSetupCalls, libsundials_kinsol), Cint, (KINMemPtr, Clong), kinmem, msbset)
end

function KINSetMaxSetupCalls(kinmem, msbset)
    __KINSetMaxSetupCalls(kinmem, convert(Clong, msbset))
end

function __KINSetMaxSubSetupCalls(kinmem, msbsetsub::Clong)
    ccall((:KINSetMaxSubSetupCalls, libsundials_kinsol), Cint, (KINMemPtr, Clong), kinmem, msbsetsub)
end

function KINSetMaxSubSetupCalls(kinmem, msbsetsub)
    __KINSetMaxSubSetupCalls(kinmem, convert(Clong, msbsetsub))
end

function __KINSetEtaForm(kinmem, etachoice::Cint)
    ccall((:KINSetEtaForm, libsundials_kinsol), Cint, (KINMemPtr, Cint), kinmem, etachoice)
end

function KINSetEtaForm(kinmem, etachoice)
    __KINSetEtaForm(kinmem, convert(Cint, etachoice))
end

function KINSetEtaConstValue(kinmem, eta::realtype)
    ccall((:KINSetEtaConstValue, libsundials_kinsol), Cint, (KINMemPtr, realtype), kinmem, eta)
end

function KINSetEtaParams(kinmem, egamma::realtype, ealpha::realtype)
    ccall((:KINSetEtaParams, libsundials_kinsol), Cint, (KINMemPtr, realtype, realtype), kinmem, egamma, ealpha)
end

function KINSetResMonParams(kinmem, omegamin::realtype, omegamax::realtype)
    ccall((:KINSetResMonParams, libsundials_kinsol), Cint, (KINMemPtr, realtype, realtype), kinmem, omegamin, omegamax)
end

function KINSetResMonConstValue(kinmem, omegaconst::realtype)
    ccall((:KINSetResMonConstValue, libsundials_kinsol), Cint, (KINMemPtr, realtype), kinmem, omegaconst)
end

function __KINSetNoMinEps(kinmem, noMinEps::Cint)
    ccall((:KINSetNoMinEps, libsundials_kinsol), Cint, (KINMemPtr, Cint), kinmem, noMinEps)
end

function KINSetNoMinEps(kinmem, noMinEps)
    __KINSetNoMinEps(kinmem, convert(Cint, noMinEps))
end

function KINSetMaxNewtonStep(kinmem, mxnewtstep::realtype)
    ccall((:KINSetMaxNewtonStep, libsundials_kinsol), Cint, (KINMemPtr, realtype), kinmem, mxnewtstep)
end

function __KINSetMaxBetaFails(kinmem, mxnbcf::Clong)
    ccall((:KINSetMaxBetaFails, libsundials_kinsol), Cint, (KINMemPtr, Clong), kinmem, mxnbcf)
end

function KINSetMaxBetaFails(kinmem, mxnbcf)
    __KINSetMaxBetaFails(kinmem, convert(Clong, mxnbcf))
end

function KINSetRelErrFunc(kinmem, relfunc::realtype)
    ccall((:KINSetRelErrFunc, libsundials_kinsol), Cint, (KINMemPtr, realtype), kinmem, relfunc)
end

function KINSetFuncNormTol(kinmem, fnormtol::realtype)
    ccall((:KINSetFuncNormTol, libsundials_kinsol), Cint, (KINMemPtr, realtype), kinmem, fnormtol)
end

function KINSetScaledStepTol(kinmem, scsteptol::realtype)
    ccall((:KINSetScaledStepTol, libsundials_kinsol), Cint, (KINMemPtr, realtype), kinmem, scsteptol)
end

function __KINSetConstraints(kinmem, constraints::N_Vector)
    ccall((:KINSetConstraints, libsundials_kinsol), Cint, (KINMemPtr, N_Vector), kinmem, constraints)
end

function KINSetConstraints(kinmem, constraints)
    __constraints = convert(NVector, constraints)
    __KINSetConstraints(kinmem, convert(N_Vector, __constraints))
end

function __KINSetSysFunc(kinmem, func::KINSysFn)
    ccall((:KINSetSysFunc, libsundials_kinsol), Cint, (KINMemPtr, KINSysFn), kinmem, func)
end

function KINSetSysFunc(kinmem, func)
    __KINSetSysFunc(kinmem, KINSysFn_wrapper(func))
end

function __KINInit(kinmem, func::KINSysFn, tmpl::N_Vector)
    ccall((:KINInit, libsundials_kinsol), Cint, (KINMemPtr, KINSysFn, N_Vector), kinmem, func, tmpl)
end

function KINInit(kinmem, func, tmpl)
    __tmpl = convert(NVector, tmpl)
    __KINInit(kinmem, KINSysFn_wrapper(func), convert(N_Vector, __tmpl))
end

function __KINSol(kinmem, uu::N_Vector, strategy::Cint, u_scale::N_Vector, f_scale::N_Vector)
    ccall((:KINSol, libsundials_kinsol), Cint, (KINMemPtr, N_Vector, Cint, N_Vector, N_Vector), kinmem, uu, strategy, u_scale, f_scale)
end

function KINSol(kinmem, uu, strategy, u_scale, f_scale)
    __uu = convert(NVector, uu)
    __u_scale = convert(NVector, u_scale)
    __f_scale = convert(NVector, f_scale)
    __KINSol(kinmem, convert(N_Vector, __uu), convert(Cint, strategy), convert(N_Vector, __u_scale), convert(N_Vector, __f_scale))
end

function KINGetWorkSpace(kinmem, lenrw, leniw)
    ccall((:KINGetWorkSpace, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}, Ptr{Clong}), kinmem, lenrw, leniw)
end

function KINGetNumNonlinSolvIters(kinmem, nniters)
    ccall((:KINGetNumNonlinSolvIters, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, nniters)
end

function KINGetNumFuncEvals(kinmem, nfevals)
    ccall((:KINGetNumFuncEvals, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, nfevals)
end

function KINGetNumBetaCondFails(kinmem, nbcfails)
    ccall((:KINGetNumBetaCondFails, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, nbcfails)
end

function KINGetNumBacktrackOps(kinmem, nbacktr)
    ccall((:KINGetNumBacktrackOps, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, nbacktr)
end

function KINGetFuncNorm(kinmem, fnorm)
    ccall((:KINGetFuncNorm, libsundials_kinsol), Cint, (KINMemPtr, Ptr{realtype}), kinmem, fnorm)
end

function KINGetStepLength(kinmem, steplength)
    ccall((:KINGetStepLength, libsundials_kinsol), Cint, (KINMemPtr, Ptr{realtype}), kinmem, steplength)
end

function __KINGetReturnFlagName(flag::Clong)
    ccall((:KINGetReturnFlagName, libsundials_kinsol), Cstring, (Clong,), flag)
end

function KINGetReturnFlagName(flag)
    __KINGetReturnFlagName(convert(Clong, flag))
end

function KINFree(kinmem)
    ccall((:KINFree, libsundials_kinsol), Void, (Ref{KINMemPtr},), kinmem)
end
# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/kinsol/kinsol_bbdpre.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function KINBBDPrecInit(kinmem, Nlocal::sunindextype, mudq::sunindextype, mldq::sunindextype, mukeep::sunindextype, mlkeep::sunindextype, dq_rel_uu::realtype, gloc::KINBBDLocalFn, gcomm::KINBBDCommFn)
    ccall((:KINBBDPrecInit, libsundials_kinsol), Cint, (KINMemPtr, sunindextype, sunindextype, sunindextype, sunindextype, sunindextype, realtype, KINBBDLocalFn, KINBBDCommFn), kinmem, Nlocal, mudq, mldq, mukeep, mlkeep, dq_rel_uu, gloc, gcomm)
end

function KINBBDPrecGetWorkSpace(kinmem, lenrwBBDP, leniwBBDP)
    ccall((:KINBBDPrecGetWorkSpace, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}, Ptr{Clong}), kinmem, lenrwBBDP, leniwBBDP)
end

function KINBBDPrecGetNumGfnEvals(kinmem, ngevalsBBDP)
    ccall((:KINBBDPrecGetNumGfnEvals, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, ngevalsBBDP)
end
# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/kinsol/kinsol_direct.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function KINDlsSetLinearSolver(kinmem, LS::SUNLinearSolver, A::SUNMatrix)
    ccall((:KINDlsSetLinearSolver, libsundials_kinsol), Cint, (KINMemPtr, SUNLinearSolver, SUNMatrix), kinmem, LS, A)
end

function KINDlsSetJacFn(kinmem, jac::KINDlsJacFn)
    ccall((:KINDlsSetJacFn, libsundials_kinsol), Cint, (KINMemPtr, KINDlsJacFn), kinmem, jac)
end

function KINDlsGetWorkSpace(kinmem, lenrw, leniw)
    ccall((:KINDlsGetWorkSpace, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}, Ptr{Clong}), kinmem, lenrw, leniw)
end

function KINDlsGetNumJacEvals(kinmem, njevals)
    ccall((:KINDlsGetNumJacEvals, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, njevals)
end

function KINDlsGetNumFuncEvals(kinmem, nfevals)
    ccall((:KINDlsGetNumFuncEvals, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, nfevals)
end

function KINDlsGetLastFlag(kinmem, flag)
    ccall((:KINDlsGetLastFlag, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, flag)
end

function __KINDlsGetReturnFlagName(flag::Clong)
    ccall((:KINDlsGetReturnFlagName, libsundials_kinsol), Cstring, (Clong,), flag)
end

function KINDlsGetReturnFlagName(flag)
    __KINDlsGetReturnFlagName(convert(Clong, flag))
end
# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/kinsol/kinsol_impl.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/kinsol/kinsol_spils.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function KINSpilsSetLinearSolver(kinmem, LS::SUNLinearSolver)
    ccall((:KINSpilsSetLinearSolver, libsundials_kinsol), Cint, (KINMemPtr, SUNLinearSolver), kinmem, LS)
end

function KINSpilsSetPreconditioner(kinmem, psetup::KINSpilsPrecSetupFn, psolve::KINSpilsPrecSolveFn)
    ccall((:KINSpilsSetPreconditioner, libsundials_kinsol), Cint, (KINMemPtr, KINSpilsPrecSetupFn, KINSpilsPrecSolveFn), kinmem, psetup, psolve)
end

function KINSpilsSetJacTimesVecFn(kinmem, jtv::KINSpilsJacTimesVecFn)
    ccall((:KINSpilsSetJacTimesVecFn, libsundials_kinsol), Cint, (KINMemPtr, KINSpilsJacTimesVecFn), kinmem, jtv)
end

function KINSpilsGetWorkSpace(kinmem, lenrwLS, leniwLS)
    ccall((:KINSpilsGetWorkSpace, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}, Ptr{Clong}), kinmem, lenrwLS, leniwLS)
end

function KINSpilsGetNumPrecEvals(kinmem, npevals)
    ccall((:KINSpilsGetNumPrecEvals, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, npevals)
end

function KINSpilsGetNumPrecSolves(kinmem, npsolves)
    ccall((:KINSpilsGetNumPrecSolves, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, npsolves)
end

function KINSpilsGetNumLinIters(kinmem, nliters)
    ccall((:KINSpilsGetNumLinIters, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, nliters)
end

function KINSpilsGetNumConvFails(kinmem, nlcfails)
    ccall((:KINSpilsGetNumConvFails, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, nlcfails)
end

function KINSpilsGetNumJtimesEvals(kinmem, njvevals)
    ccall((:KINSpilsGetNumJtimesEvals, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, njvevals)
end

function KINSpilsGetNumFuncEvals(kinmem, nfevals)
    ccall((:KINSpilsGetNumFuncEvals, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, nfevals)
end

function KINSpilsGetLastFlag(kinmem, flag)
    ccall((:KINSpilsGetLastFlag, libsundials_kinsol), Cint, (KINMemPtr, Ptr{Clong}), kinmem, flag)
end

function __KINSpilsGetReturnFlagName(flag::Clong)
    ccall((:KINSpilsGetReturnFlagName, libsundials_kinsol), Cstring, (Clong,), flag)
end

function KINSpilsGetReturnFlagName(flag)
    __KINSpilsGetReturnFlagName(convert(Clong, flag))
end


text:
@testset "$(rpad("Order Conditions",80))" begin

    for s in 1:5
        g = TableauGauss(s)

        for σ in 1:s
            @test check_order_conditions_b(g,σ) == true
            @test check_order_conditions_c(g,σ) == Array{Bool}(ones(s))
            @test check_order_conditions_d(g,σ) == Array{Bool}(ones(s))
        end

        @test satisfies_simplifying_assumption_b(g)
        @test satisfies_simplifying_assumption_c(g)
        @test satisfies_simplifying_assumption_d(g)
    end

    for s in 2:5
        @test  satisfies_simplifying_assumption_b(TableauLobattoIIIA(s))
        @test  satisfies_simplifying_assumption_b(TableauLobattoIIIB(s))
        @test  satisfies_simplifying_assumption_b(TableauLobattoIIIC(s))
        @test  satisfies_simplifying_assumption_b(TableauLobattoIIIC̄(s))
        @test  satisfies_simplifying_assumption_b(TableauLobattoIIID(s))
        @test  satisfies_simplifying_assumption_b(TableauLobattoIIIE(s))
        @test  satisfies_simplifying_assumption_b(TableauRadauIA(s))
        @test  satisfies_simplifying_assumption_b(TableauRadauIIA(s))

        @test  satisfies_simplifying_assumption_c(TableauLobattoIIIA(s))
        @test !satisfies_simplifying_assumption_c(TableauLobattoIIIB(s))
        @test !satisfies_simplifying_assumption_c(TableauLobattoIIIC(s))
        @test !satisfies_simplifying_assumption_c(TableauLobattoIIIC̄(s))
        @test !satisfies_simplifying_assumption_c(TableauLobattoIIID(s))
        @test !satisfies_simplifying_assumption_c(TableauLobattoIIIE(s))
        @test !satisfies_simplifying_assumption_c(TableauRadauIA(s))
        @test  satisfies_simplifying_assumption_c(TableauRadauIIA(s))

        @test !satisfies_simplifying_assumption_d(TableauLobattoIIIA(s))
        @test  satisfies_simplifying_assumption_d(TableauLobattoIIIB(s))
        @test !satisfies_simplifying_assumption_d(TableauLobattoIIIC(s))
        @test !satisfies_simplifying_assumption_d(TableauLobattoIIIC̄(s))
        @test !satisfies_simplifying_assumption_d(TableauLobattoIIID(s))
        @test !satisfies_simplifying_assumption_d(TableauLobattoIIIE(s))
        @test  satisfies_simplifying_assumption_d(TableauRadauIA(s))
        @test !satisfies_simplifying_assumption_d(TableauRadauIIA(s))
    end

end


text:
using Genie

Genie.Sessions.init()

import AuthenticationController
import SearchLight: findone
import Users

export current_user
current_user() = findone(Users.User, id = get_authentication())

route("/login", AuthenticationController.show_login, named = :show_login)
route("/login", AuthenticationController.login, method = POST, named = :login)
route("/success", AuthenticationController.success, method = GET, named = :success)
route("/logout", AuthenticationController.logout, named = :logout)

#===#

# UNCOMMENT TO ENABLE REGISTRATION ROUTES

# route("/register", AuthenticationController.show_register, named = :show_register)
# route("/register", AuthenticationController.register, method = POST, named = :register)

max_stars_repo_name: genieframework/GenieAuthentication

max_issues_repo_name: genieframework/GenieAuthentication

max_forks_repo_name: genieframework/GenieAuthentication


text:
using JuMP, EAGO

                     m = Model()

                     EAGO.register_eago_operators!(m)

                     @variable(m, -1 <= x[i=1:5] <= 1)

                     @variable(m, -58.37772561872491 <= q <= 51.748312049639644)

                     add_NL_constraint(m, :(swish(-0.3976822916974827 + -0.11888104611683081*swish(-0.09559544092481564 + 0.23201220435158865*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + -0.9126138494455787*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + 0.24324641666113456*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.1690500900766101*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + 0.20833731206579253*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.8277675607937618*swish(-0.41653739657549194 + 0.7547021537813423*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.5787262183714494*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.11492508246438904*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.30062983013792843*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.1276250114011983*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + 0.37430250255255215*swish(0.9557400948867283 + -0.3128610884258398*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.29518845150992634*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.18188148649835556*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.8330182900675651*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.8804319372999063*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + 0.9159784725268092*swish(-0.32868009819829513 + 0.7041500634234112*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + -0.44147758504740464*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.5937281428689025*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + -0.3198554528784734*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.047330375221362964*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.21239133839693736*swish(-0.6560670298284208 + 0.11579976545709414*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.7227941593613254*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + 0.5041216754022764*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + -0.9501104307252297*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + 0.7033943599032555*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5])))) + swish(-0.962366690533889 + 0.21288820713294498*swish(-0.09559544092481564 + 0.23201220435158865*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + -0.9126138494455787*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + 0.24324641666113456*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.1690500900766101*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + 0.20833731206579253*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + 0.04621026197884115*swish(-0.41653739657549194 + 0.7547021537813423*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.5787262183714494*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.11492508246438904*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.30062983013792843*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.1276250114011983*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + 0.3579305330052933*swish(0.9557400948867283 + -0.3128610884258398*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.29518845150992634*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.18188148649835556*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.8330182900675651*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.8804319372999063*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.40247732796428703*swish(-0.32868009819829513 + 0.7041500634234112*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + -0.44147758504740464*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.5937281428689025*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + -0.3198554528784734*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.047330375221362964*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.3937461182921762*swish(-0.6560670298284208 + 0.11579976545709414*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.7227941593613254*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + 0.5041216754022764*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + -0.9501104307252297*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + 0.7033943599032555*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5])))) + swish(-0.9189915189234159 + -0.5125130010222394*swish(-0.09559544092481564 + 0.23201220435158865*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + -0.9126138494455787*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + 0.24324641666113456*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.1690500900766101*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + 0.20833731206579253*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.3502499398907637*swish(-0.41653739657549194 + 0.7547021537813423*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.5787262183714494*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.11492508246438904*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.30062983013792843*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.1276250114011983*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.8274375080497247*swish(0.9557400948867283 + -0.3128610884258398*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.29518845150992634*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.18188148649835556*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.8330182900675651*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.8804319372999063*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.7757421130805153*swish(-0.32868009819829513 + 0.7041500634234112*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + -0.44147758504740464*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.5937281428689025*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + -0.3198554528784734*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.047330375221362964*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + 0.6602598595684599*swish(-0.6560670298284208 + 0.11579976545709414*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.7227941593613254*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + 0.5041216754022764*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + -0.9501104307252297*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + 0.7033943599032555*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5])))) + swish(-0.760456357412739 + 0.8974231726544617*swish(-0.09559544092481564 + 0.23201220435158865*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + -0.9126138494455787*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + 0.24324641666113456*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.1690500900766101*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + 0.20833731206579253*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.7589867374120325*swish(-0.41653739657549194 + 0.7547021537813423*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.5787262183714494*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.11492508246438904*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.30062983013792843*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.1276250114011983*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.3014899851721653*swish(0.9557400948867283 + -0.3128610884258398*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.29518845150992634*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.18188148649835556*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.8330182900675651*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.8804319372999063*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + 0.03263132145111802*swish(-0.32868009819829513 + 0.7041500634234112*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + -0.44147758504740464*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.5937281428689025*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + -0.3198554528784734*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.047330375221362964*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + 0.8460059521417822*swish(-0.6560670298284208 + 0.11579976545709414*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.7227941593613254*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + 0.5041216754022764*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + -0.9501104307252297*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + 0.7033943599032555*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5])))) + swish(-0.1364886291423204 + -0.7689732133011344*swish(-0.09559544092481564 + 0.23201220435158865*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + -0.9126138494455787*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + 0.24324641666113456*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.1690500900766101*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + 0.20833731206579253*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + 0.9275671307049969*swish(-0.41653739657549194 + 0.7547021537813423*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.5787262183714494*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.11492508246438904*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.30062983013792843*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.1276250114011983*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.311285022430249*swish(0.9557400948867283 + -0.3128610884258398*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.29518845150992634*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.18188148649835556*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + 0.8330182900675651*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.8804319372999063*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + -0.2373305013184268*swish(-0.32868009819829513 + 0.7041500634234112*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + -0.44147758504740464*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + -0.5937281428689025*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + -0.3198554528784734*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + -0.047330375221362964*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5]))) + 0.7676258102518863*swish(-0.6560670298284208 + 0.11579976545709414*swish(0.22080335056838862 + -0.11207096478827117*$(x[1]) + 0.9802919969431398*$(x[2]) + -0.17783835331857878*$(x[3]) + 0.5553411614422452*$(x[4]) + 0.8384080073044262*$(x[5])) + 0.7227941593613254*swish(-0.03619259662306584 + -0.3774088093292831*$(x[1]) + 0.859114754276578*$(x[2]) + -0.4844223734792257*$(x[3]) + 0.08654340008535533*$(x[4]) + -0.46594229223618644*$(x[5])) + 0.5041216754022764*swish(-0.05960623749041094 + -0.4311407494411239*$(x[1]) + -0.025139997052890273*$(x[2]) + 0.060401892548068936*$(x[3]) + 0.5875386419954256*$(x[4]) + 0.5553096462934759*$(x[5])) + -0.9501104307252297*swish(0.12047524138880839 + -0.4988789730921872*$(x[1]) + -0.41177595995379823*$(x[2]) + -0.6913890776083331*$(x[3]) + 0.032955544793602076*$(x[4]) + -0.5657303188428733*$(x[5])) + 0.7033943599032555*swish(-0.14422850857319736 + 0.5362813944125526*$(x[1]) + 0.29620144485119626*$(x[2]) + -0.18264867223264059*$(x[3]) + 0.5265937438977235*$(x[4]) + 0.6008528580664168*$(x[5])))) - $q <= 0.0))

                     @objective(m, Min, q)

                     return m

max_stars_repo_name: PSORLab/RSActivationFunctions

max_issues_repo_name: PSORLab/RSActivationFunctions

max_forks_repo_name: PSORLab/RSActivationFunctions


text:
# Imported from  CUDAnative.jl

#
# code_* replacements
#

"""
    code_llvm([io], f, types; cpu = "skylake", optimizer! = jloptimize!, optimize = true, dump_module = false)

Prints the LLVM IR generated for the method matching the given generic function and type
signature to `io` which defaults to `STDOUT`. The IR is optimized according to `optimize`
(defaults to true), and the entire module, including headers and other functions, is dumped
if `dump_module` is set (defaults to false). The code is optimized for `cpu`, with the pass
order given by `optimize!`, by default we optimize for `"skylake"` and use the Julia pass order.
"""
function code_llvm(io::IO, @nospecialize(func::Core.Function), @nospecialize(types=Tuple);
               cpu::String = "skylake", optimize!::Core.Function = jloptimize!,
               optimize::Bool = true, dump_module::Bool = false)

    tt = Base.to_tuple_type(types)
    mod, llvmf = irgen(func, tt)
    if optimize
        target_machine(cpu) do tm
            optimize!(tm, mod)
        end
    end
    if dump_module
        show(io, mod)
    else
        show(io, llvmf)
    end
end
code_llvm(@nospecialize(func), @nospecialize(types=Tuple); kwargs...) = code_llvm(stdout, func, types; kwargs...)

"""
    code_native([io], f, types; cpu = "skylake", optimize! = jloptimize!, dump_module = false, verbose = false)

Emits assembly for the given `cpu` and `optimize!` pass pipline.
"""
function code_native(io::IO, @nospecialize(func::Core.Function), @nospecialize(types=Tuple);
                     cpu::String = "skylake", optimize!::Core.Function = jloptimize!,
                     dump_module::Bool = false, verbose::Bool = false)

    tt = Base.to_tuple_type(types)
    mod, llvmf = irgen(func, tt)
    asm = target_machine(cpu) do tm
        optimize!(tm, mod)
        asm_verbosity!(tm, verbose)
        LLVM.emit(tm, mod, LLVM.API.LLVMAssemblyFile)
    end
    dump_module && write(io, asm)

    # filter the assembly file
    foundStart = false
    start1 = string(LLVM.name(llvmf), ':')
    start2 = string('"', LLVM.name(llvmf), '"', ':')
    asmbuf = IOBuffer(asm)
    for line in eachline(asmbuf)
        if !foundStart
            foundStart = startswith(line, start1) ||
                         startswith(line, start2)
        end
        if foundStart
            write(io, line)
            if startswith(line, ".Lfunc_end")
                break
            end
            write(io, '\n')
        end
    end
    if !foundStart
    	warn("Did not find the start of the function")
	    write(io, asm)
    end
end
code_native(@nospecialize(func), @nospecialize(types=Tuple); kwargs...) =
code_native(STDOUT, func, types; kwargs...)


text:
mesh_file_names = ["../mesh/square_meshes/mesh_test_1.g",
                   "../mesh/square_meshes/mesh_test_0.5.g",
                   "../mesh/square_meshes/mesh_test_0.25.g",
                   "../mesh/square_meshes/mesh_test_0.125.g",
                   "../mesh/square_meshes/mesh_test_0.0625.g",
                   "../mesh/square_meshes/mesh_test_0.03125.g",
                   "../mesh/square_meshes/mesh_test_0.015625.g",
                   "../mesh/square_meshes/mesh_test_0.0078125.g"]

number_of_nodes = [4, 9, 25, 81, 289, 1089, 4225, 16641]
number_of_elements = [1, 2^2, 4^2, 8^2, 16^2, 32^2, 64^2, 128^2]
number_of_node_set_nodes = [1, 2, 4, 8, 16, 32, 64, 128] .+ 1

function test_square_mesh(n::Int)
    mesh_file_name = abspath(mesh_file_names[n])
    test_name = rpad("Testing square mesh: $(basename(mesh_file_name))", 96)
    @testset "$test_name" begin
        @suppress begin
            #
            # read method test
            #
            exo_id = Exodus.open_exodus_database(abspath(mesh_file_names[n]))
            init = Exodus.Initialization(exo_id)
            #
            # tests on the simple numbers
            #
            @test init.num_dim == 2
            @test init.num_nodes == number_of_nodes[n]
            @test init.num_elem == number_of_elements[n]
            @test init.num_elem_blk == 1
            @test init.num_node_sets == 4
            @test init.num_side_sets == 4
            #
            # test coordinates
            #
            coords = Exodus.read_coordinates(exo_id, init.num_dim, init.num_nodes)
            @test size(coords, 1) == number_of_nodes[n]
            @test size(coords, 2) == 2
            #
            # read block ids
            #
            block_ids = Exodus.read_block_ids(exo_id, init.num_elem_blk)
            @test size(block_ids, 1) == 1
            @test block_ids[1] == 1
            blocks = Exodus.read_blocks(exo_id, block_ids)
            block = blocks[1]
            @test block.block_id == 1
            @test block.num_elem == number_of_elements[n]
            @test block.num_nodes_per_elem == 4
            @test block.elem_type == "QUAD4"
            @test size(block.conn, 1) == 4 * number_of_elements[n]
            # @test size(block.conn, 1) == number_of_elements[n]
            # @test size(block.conn, 2) == 4
            #
            # test node set initialization
            #
            node_set_ids = Exodus.read_node_set_ids(exo_id, init.num_node_sets)
            @test node_set_ids == [1, 2, 3, 4]
            node_sets = Exodus.read_node_sets(exo_id, node_set_ids)
            @test size(node_sets, 1) == 4
            for (m, node_set) in enumerate(node_sets)
                # @show node_set
                @test node_set.node_set_id == node_set_ids[m]
                @test node_set.num_nodes == number_of_node_set_nodes[n]
                @test size(node_set.nodes, 1) == number_of_node_set_nodes[n]
            end
            #
            mesh = Exodus.Mesh(coords, blocks, node_sets)
            @test size(mesh.coords, 1) == number_of_nodes[n]
            @test size(mesh.coords, 2) == 2

            Exodus.close_exodus_database(exo_id)
        end
    end
end

for (n, mesh) in enumerate(mesh_file_names)
    test_square_mesh(n)
end


text:
struct XCoordinateDistance{M,R1,S} <: TaskMap{M,R1,S}
    x_position::S
end
XCoordinateDistance{M,R1}(c::S) where {M,R1,S} = XCoordinateDistance{M,R1,S}(c)

struct XCoordinateDistanceT{M,R1,S} <: TaskMapT{M,R1,S}
    base_map::XCoordinateDistance{M,R1,S}
end
XCoordinateDistanceT{M,R1}(c::S) where {M,R1,S} =
    XCoordinateDistanceT{M,R1,S}(XCoordinateDistance{M,R1,S}(c))

task_map_emb(::EmbRep, ::EmbRep, xm, task_map::XCoordinateDistance{ℝ{m}, R1}) where m =
    SA[abs(xm[1] - task_map.x_position)]

struct YCoordinateDistance{M,R1,S} <: TaskMap{M,R1,S}
    y_position::S
end
YCoordinateDistance{M,R1}(c::S) where {M,R1,S} = YCoordinateDistance{M,R1,S}(c)

struct YCoordinateDistanceT{M,R1,S} <: TaskMapT{M,R1,S}
    base_map::YCoordinateDistance{M,R1,S}
end
YCoordinateDistanceT{M,R1}(c::S) where {M,R1,S} =
    YCoordinateDistanceT{M,R1,S}(YCoordinateDistance{M,R1,S}(c))

task_map_emb(::EmbRep, ::EmbRep, xm, task_map::YCoordinateDistance{ℝ{m}, R1}) where m =
    SA[abs(xm[2] .- task_map.y_position)]