text:
function part1(input)
    final_sum = 0
    w = 0
    analyzing = true
    for c in input.data
        if c == UInt8('|')
            analyzing = false
        elseif analyzing
            continue
        elseif c == UInt8(' ') || c == UInt8('\n')
            if 2 <= w <= 4 || w == 7
                final_sum += 1
            end
            w = 0

            if c == UInt8('\n')
                analyzing = true
            end
        else
            w += 1
        end
    end
    return final_sum
end

function part2(input)
    final_sum = 0
    current_number = 0
    wa = wb = wc = wd = we = wf = wg = 0
    w = 0
    analyzing = true
    for c in input.data
        if c == UInt8(' ') || c == UInt8('\n')
            analyzing && continue
            w == 0 && continue
            current_number *= 10
            w == 42 && (current_number += 0)
            w == 17 && (current_number += 1)
            w == 34 && (current_number += 2)
            w == 39 && (current_number += 3)
            w == 30 && (current_number += 4)
            w == 37 && (current_number += 5)
            w == 41 && (current_number += 6)
            w == 25 && (current_number += 7)
            w == 49 && (current_number += 8)
            w == 45 && (current_number += 9)
            w = 0

            if c == UInt8('\n')
                final_sum += current_number
                current_number = 0
                wa = wb = wc = wd = we = wf = wg = 0
                analyzing = true
            end
        elseif c == UInt8('a')
            analyzing ? (wa += 1) : (w += wa)
        elseif c == UInt8('b')
            analyzing ? (wb += 1) : (w += wb)
        elseif c == UInt8('c')
            analyzing ? (wc += 1) : (w += wc)
        elseif c == UInt8('d')
            analyzing ? (wd += 1) : (w += wd)
        elseif c == UInt8('e')
            analyzing ? (we += 1) : (w += we)
        elseif c == UInt8('f')
            analyzing ? (wf += 1) : (w += wf)
        elseif c == UInt8('g')
            analyzing ? (wg += 1) : (w += wg)
        elseif c == UInt8('|')
            analyzing = false
        end
    end
    return final_sum
end


text:
struct Tensor{S <: Tuple, T, N, L} <: AbstractTensor{S, T, N}
    data::NTuple{L, T}
    function Tensor{S, T, N, L}(data::NTuple{L, Real}) where {S, T, N, L}
        check_tensor_parameters(S, T, Val(N), Val(L))
        new{S, T, N, L}(convert_ntuple(T, data))
    end
end

@generated function check_tensor_parameters(::Type{S}, ::Type{T}, ::Val{N}, ::Val{L}) where {S, T, N, L}
    check_size_parameters(S)
    if tensororder(Space(S)) != N
        return :(throw(ArgumentError("Number of dimensions must be $(tensororder(Space(S))) for $S size, got $N.")))
    end
    if ncomponents(Space(S)) != L
        return :(throw(ArgumentError("Length of tuple data must be $(ncomponents(Space(S))) for $S size, got $L.")))
    end
end

# aliases
const SecondOrderTensor{dim, T, L} = Tensor{NTuple{2, dim}, T, 2, L}
const FourthOrderTensor{dim, T, L} = Tensor{NTuple{4, dim}, T, 4, L}
const SymmetricSecondOrderTensor{dim, T, L} = Tensor{Tuple{@Symmetry{dim, dim}}, T, 2, L}
const SymmetricFourthOrderTensor{dim, T, L} = Tensor{NTuple{2, @Symmetry{dim, dim}}, T, 4, L}
const Mat{m, n, T, L} = Tensor{Tuple{m, n}, T, 2, L}
const Vec{dim, T} = Tensor{Tuple{dim}, T, 1, dim}

# constructors
@inline function Tensor{S, T}(data::Tuple{Vararg{Any, L}}) where {S, T, L}
    N = tensororder(Space(S))
    Tensor{S, T, N, L}(data)
end
@inline function Tensor{S}(data::Tuple{Vararg{Any, L}}) where {S, L}
    N = tensororder(Space(S))
    T = promote_ntuple_eltype(data)
    Tensor{S, T, N, L}(data)
end
## for `tensortype` function
@inline function (::Type{Tensor{S, T, N, L} where {T}})(data::Tuple) where {S, N, L}
    T = promote_ntuple_eltype(data)
    Tensor{S, T, N, L}(data)
end
## from Vararg
@inline function (::Type{TT})(data::Vararg{Real}) where {TT <: Tensor}
    TT(data)
end
## from Function
@generated function (::Type{TT})(f::Function) where {TT <: Tensor}
    S = Space(TT)
    tocartesian = CartesianIndices(S)
    exps = [:(f($(Tuple(tocartesian[i])...))) for i in indices(S)]
    quote
        @_inline_meta
        TT($(exps...))
    end
end
## from AbstractArray
@generated function (::Type{TT})(A::AbstractArray) where {TT <: Tensor}
    S = Space(TT)
    if IndexStyle(A) isa IndexLinear
        exps = [:(A[$i]) for i in indices(S)]
    else
        tocartesian = CartesianIndices(S)
        exps = [:(A[$(tocartesian[i])]) for i in indices(S)]
    end
    quote
        @_inline_meta
        @boundscheck if length(TT) != length(A)
            throw(DimensionMismatch("expected input array of length $(length(A)), got length $(length(TT))"))
        end
        @inbounds TT($(exps...))
    end
end
## from StaticArray
@inline function Tensor(A::StaticArray{S, T}) where {S, T}
    Tensor{S, T}(Tuple(A))
end

## for aliases
@inline function Tensor{S, T, N}(data::Tuple{Vararg{Any, L}}) where {S, T, N, L}
    Tensor{S, T, N, L}(data)
end
@inline function (::Type{Tensor{S, T, N} where {T}})(data::Tuple) where {S, N}
    T = promote_ntuple_eltype(data)
    Tensor{S, T, N}(data)
end
@inline Vec(data::Tuple{Vararg{Any, dim}}) where {dim} = Vec{dim}(data)
@inline Vec{dim}(data::Tuple) where {dim} = (T = promote_ntuple_eltype(data); Vec{dim, T}(data))

# macros
macro Vec(ex)
    esc(:(Tensor(Tensorial.@SVector $ex)))
end
macro Mat(ex)
    esc(:(Tensor(Tensorial.@SMatrix $ex)))
end
macro Tensor(expr)
    if Meta.isexpr(expr, :ref)
        newargs = map(expr.args) do ex
            if Meta.isexpr(ex, :call) && ex.args[1] == :(:)
                Expr(:call, :($(StaticArrays.SUnitRange)), ex.args[2], ex.args[3])
            elseif Meta.isexpr(ex, :vect)
                Expr(:call, :($(StaticArrays.SVector)), ex.args...)
            else
                ex
            end
        end
        esc(Expr(:block, :($check_Tensor_macro($(newargs[1]))), Expr(expr.head, newargs...)))
    else
        esc(:(Tensor(Tensorial.@SArray $expr)))
    end
end
check_Tensor_macro(x::AbstractTensor) = nothing
check_Tensor_macro(x) = throw(ArgumentError("$(typeof(x)) is not supported in @Tensor"))

# special constructors
for (op, el) in ((:zero, :(zero(T))), (:ones, :(one(T))), (:rand, :(()->rand(T))), (:randn,:(()->randn(T))))
    @eval begin
        @inline Base.$op(::Type{Tensor{S}}) where {S} = $op(Tensor{S, Float64})
        @inline Base.$op(::Type{Tensor{S, T}}) where {S, T} = Tensor{S, T}(fill_tuple($el, Val(ncomponents(Space(S)))))
        # for aliases
        @inline Base.$op(::Type{Tensor{S, T, N}}) where {S, T, N} = $op(Tensor{S, T})
        @inline Base.$op(::Type{Tensor{S, T, N, L}}) where {S, T, N, L} = $op(Tensor{S, T})
        @inline Base.$op(::Type{Tensor{S, T, N} where {T}}) where {S, N} = $op(Tensor{S, Float64})
        @inline Base.$op(::Type{Tensor{S, T, N, L} where {T}}) where {S, N, L} = $op(Tensor{S, Float64})
        @inline Base.$op(x::Tensor) = $op(typeof(x))
    end
end

# identity tensors
_one(::Type{Tensor{S}}) where {S} = __one(Tensor{S, Float64})
_one(::Type{Tensor{S, T}}) where {S, T} = __one(Tensor{S, T})
Base.one(::Type{TT}) where {TT <: Tensor} = _one(basetype(TT))
Base.one(x::Tensor) = one(typeof(x))
@inline function __one(TT::Type{<: Union{Tensor{Tuple{dim,dim}, T}, Tensor{Tuple{@Symmetry{dim,dim}}, T}}}) where {dim, T}
    o = one(T)
    z = zero(T)
    TT((i,j) -> i == j ? o : z)
end
@inline function __one(TT::Type{Tensor{NTuple{4,dim}, T}}) where {dim, T}
    o = one(T)
    z = zero(T)
    TT((i,j,k,l) -> i == k && j == l ? o : z)
end
@inline function __one(TT::Type{Tensor{NTuple{2,@Symmetry{dim,dim}}, T}}) where {dim, T}
    o = one(T)
    z = zero(T)
    δ(i,j) = i == j ? o : z
    TT((i,j,k,l) -> (δ(i,k)*δ(j,l) + δ(i,l)*δ(j,k))/2)
end

# UniformScaling
@inline function (TT::Type{<: Tensor})(I::UniformScaling)
    TT((i,j) -> I[i,j])
end

# helpers
Base.Tuple(x::Tensor) = x.data
ncomponents(x::Tensor) = length(Tuple(x))
ncomponents(::Type{<: Tensor{<: Any, <: Any, <: Any, L}}) where {L} = L
@pure basetype(::Type{<: Tensor{S}}) where {S} = Tensor{S}
@pure basetype(::Type{<: Tensor{S, T}}) where {S, T} = Tensor{S, T}

# getindex
@generated function Base.getindex(x::Tensor, i::Int)
    quote
        @_inline_meta
        @boundscheck checkbounds(x, i)
        @inbounds Tuple(x)[$(independent_indices(x))[i]]
    end
end

# convert
@inline Base.convert(::Type{TT}, x::TT) where {TT <: Tensor} = x
@inline Base.convert(::Type{TT}, x::AbstractArray) where {TT <: Tensor} = TT(x)
@generated function Base.convert(::Type{TT}, x::AbstractTensor) where {TT <: Tensor}
    S = promote_space(Space(TT), Space(x))
    S == Space(TT) ||
        return :(throw(ArgumentError("Cannot `convert` an object of type $(typeof(x)) to an object of type $TT")))
    exps = [getindex_expr(x, :x, i) for i in indices(S)]
    quote
        @_inline_meta
        @inbounds TT(tuple($(exps...)))
    end
end
@inline Base.convert(::Type{TT}, x::Tuple) where {TT <: Tensor} = TT(x)

# promotion
@inline convert_eltype(::Type{T}, x::Real) where {T <: Real} = T(x)
@generated function convert_eltype(::Type{T}, x::Tensor) where {T <: Real}
    S = Space(x)
    TT = tensortype(S)
    quote
        @_inline_meta
        $TT{T}(x)
    end
end
@generated function promote_elements(xs::Vararg{Union{Real, Tensor}, N}) where {N}
    T = promote_type(eltype.(xs)...)
    exps = [:(convert_eltype($T, xs[$i])) for i in 1:N]
    quote
        @_inline_meta
        tuple($(exps...))
    end
end

function Base.promote_rule(::Type{Tensor{S, T, N, L}}, ::Type{Tensor{S, U, N, L}}) where {S, T, U, N, L}
    Tensor{S, promote_type(T, U), N, L}
end

ext: jl


text:
"""
    reformulate(lp::Problem) where T

Convert from IplpProblem to IplpStandardProblem.
"""
function reformulate(lp::AbstractProblem{T}) where T <: Real
    if isa(lp, AbstractStandardProblem)
        return lp
    end

    # count free and upper bounded variables
    free = 0
    ub = 0
    nzv = 0 # non-zero values
    for (i, (l, h)) in enumerate(zip(lp.lo, lp.hi))
        if l == -Inf && h == Inf
            # free
            free += 1
            nzv += length(lp.cols[i].ind)
        elseif isfinite(l) && isfinite(h)
            # l ⩽ x ⩽ h
            ub += 1
        elseif l == -Inf && isfinite(h)
            # x ⩽ h
            # will be dealt with later
        elseif isfinite(l) && h == Inf
            # l ⩽ x
            # will be dealt with later
        else
            error("unexpected bounds ($l, $h)")
        end

        nzv += length(lp.cols[i].ind)
    end

    nv = lp.nv

    I = Vector{Int}(undef, nzv) # row indices
    J = Vector{Int}(undef, nzv) # column indices
    V = Vector{T}(undef, nzv)
    ind_ub = Vector{Int}(undef, ub)
    val_ub = Vector{T}(undef, ub)

    b = copy(lp.b)
    c = Vector{T}(undef, nv + free)

    free = 0
    ub = 0
    nzv = 0
    @inbounds for (j, (l, h)) in enumerate(zip(lp.lo, lp.hi))
        column = lp.cols[j] # current column

        if l == -Inf && h == Inf
            # free variable
            # split into positive and negative parts: x = x⁺ - x⁻
            c[j + free]  = lp.c[j]
            for (i, v) in zip(column.ind, column.nzval)
                nzv += 1
                I[nzv] = i
                J[nzv] = j + free
                V[nzv] = v
            end

            c[j + free + 1] = -lp.c[j]
            for (i, v) in zip(column.ind, column.nzval)
                nzv += 1
                I[nzv] = i
                J[nzv] = j + free + 1
                V[nzv] = -v
            end

            free += 1
        elseif isfinite(l) && isfinite(h)
            # l ⩽ x ⩽ h
            c[j + free] = lp.c[j]
            for (i, v) in zip(column.ind, column.nzval)
                b[i] -= (v * l)

                nzv += 1
                I[nzv] = i
                J[nzv] = j + free
                V[nzv] = v
            end

            ub += 1
            ind_ub[ub] = j + free
            val_ub[ub] = h - l
        elseif l == -Inf && isfinite(h)
            # x ⩽ h
            c[j + free] = -lp.c[j]
            for (i, v) in zip(column.ind, column.nzval)
                b[i] -= (-v * u)

                nzv += 1
                I[nzv] = i
                J[nzv] = j + free
                V[nzv] = -v
            end
        elseif isfinite(l) && h == Inf
            # l ⩽ x
            c[j + free] = lp.c[j]
            for (i, v) in zip(column.ind, column.nzval)
                b[i] -= (v * l)

                nzv += 1
                I[nzv] = i
                J[nzv] = j + free
                V[nzv] = v
            end
        else
            # this error _should_ have already been caught
            error("unexpected bounds ($l, $h)")
        end
    end

    # construct A out of I, J, V
    # FIXME: currently assuming that `A` will be sparse
    nv += free
    A = sparse(I, J, V, lp.nc, nv)

    StandardProblem{T}(lp.nc, nv, ub, ind_ub, val_ub, A, b, c)
end

"""
    starting_pt!(iter::Iterate{T}) where T

Convert `iter` to starting point. It is faster to first allocate memory and then
fill the desired values.
The starting point is:
    (x, λ, s, τ, κ) = (e, 0, e, 1, 1).
"""
function starting_pt!(iter::Iterate{T}) where T <: Real
    # primal
    iter.x .= oneunit(T)
    iter.v .= oneunit(T)

    # dual
    iter.λ .= zero(T)
    iter.s .= oneunit(T)
    iter.w .= oneunit(T)

    # homogenous constants
    iter.τ = oneunit(T)
    iter.κ = oneunit(T)

    nothing
end

function duality!(i::Iterate{T}) where T <: Real
    i.μ = (
        (i.τ * i.κ
        + dot(i.x, i.s)
        + dot(i.v, i.w))
        / (i.nv + i.nu + 1)
    )

    nothing
end

function get_solution(
    solv::Solver{T},
    org::AbstractProblem;
    verbose::Bool = true
) where T <: Real
    sln = Solution{T}()
    sln.status = solv.status == SolverOptimal

    slp = solv.lp

    ub = 0
    free = 0
    sln.x = zeros(T, org.nv)
    inv_τ = inv(solv.iter.τ)
    for (j, (l, h)) in enumerate(zip(org.lo, org.hi))
        _j = j + free
        if l == -Inf && h == Inf
            sln.x[j] = (solv.iter.x[_j] - solv.iter.x[_j + 1]) * inv_τ
        elseif l == -Inf && isfinite(h)
            sln.x[j] = u - solv.iter.x[_j] * inv_τ
        elseif isfinite(l) && isfinite(h)
            ub += 1
            sln.x[j] = l + solv.iter.x[_j] * inv_τ
        else
            sln.x[j] = l + solv.iter.x[_j] * inv_τ
        end
    end

    sln.A_std = slp.A
    sln.b_std = slp.b
    sln.c_std = slp.c

    f_iter = solv.iter
    sln.x_std = f_iter.x
    sln.λ_std = f_iter.λ
    sln.s_std = f_iter.s

    # results of checking KKT conditions
    if verbose
        # construct U and u
        ubi = slp.upb_ind
        ubv = slp.upb_val
        U = zeros(T, slp.nu, slp.nv)
        u = zeros(T, slp.nu)
        for i in ubi
            U[i, i] = oneunit(T)
            u[i] = ubv[i]
        end

        A = slp.A
        b = slp.b
        c = slp.c

        x = f_iter.x
        v = f_iter.v
        λ = f_iter.λ
        s = f_iter.s
        w = f_iter.w

        τ = f_iter.τ

        kkt = (
            norm([
                A' * λ + s - U' * w - c * τ;
                A * x - b * τ;
                U * x + v - u * τ;
                x .* s;
            ]) / norm([
                b; c; u
            ])
        )
    end

    return sln
end


text:
#=

@author : Spencer Lyon <spencer.lyon@nyu.edu>
          Victoria Gregory <victoria.gregory@nyu.edu>

=#
using QuantEcon
using Roots
using Plots
using LaTeXStrings
pyplot()

struct HistDepRamsey{TF<:AbstractFloat}
    # These are the parameters of the economy
    A0::AbstractFloat
    A1::AbstractFloat
    d::AbstractFloat
    Q0::AbstractFloat
    τ0::AbstractFloat
    μ0::AbstractFloat
    β::AbstractFloat

    # These are the LQ fields and stationary values
    R::Matrix{TF}
    A::Matrix{TF}
    B::Vector{TF}
    Q::TF
    P::Matrix{TF}
    F::Matrix{TF}
    lq::LQ
end

struct RamseyPath{TF<:AbstractFloat}
    y::Matrix{TF}
    uhat::Vector{TF}
    uhatdif::Vector{TF}
    τhat::Vector{TF}
    τhatdif::Vector{TF}
    μ::Vector{TF}
    G::Vector{TF}
    GPay::Vector{TF}
end

function HistDepRamsey(A0::AbstractFloat,
                       A1::AbstractFloat,
                       d::AbstractFloat,
                       Q0::AbstractFloat,
                       τ0::AbstractFloat,
                       μ::AbstractFloat,
                       β::AbstractFloat)
    # Create Matrices for solving Ramsey problem

    R = [     0.0  -A0 / 2      0.0      0.0
         -A0 / 2    A1 / 2   -μ / 2      0.0
             0.0    -μ / 2      0.0      0.0
             0.0       0.0      0.0    d / 2]

    A = [    1.0      0.0    0.0               0.0
             0.0      1.0    0.0               1.0
             0.0      0.0    0.0               0.0
         -A0 / d   A1 / d    0.0  A1 / d + 1.0 / β]

    B = [0.0; 0.0; 1.0; 1.0 / d]

    Q = 0.0

    # Use LQ to solve the Ramsey Problem.
    lq = LQ(Q, -R, A, B, bet=β)

    P, F, _d = stationary_values(lq)

    HistDepRamsey(A0, A1, d, Q0, τ0, μ0, β, R, A, B, Q, P, Array(F), lq)
end

function compute_G(hdr::HistDepRamsey, μ::AbstractFloat)
    # simplify notation
    Q0, τ0, A, B, Q = hdr.Q0, hdr.τ0, hdr.A, hdr.B, hdr.Q
    β = hdr.β

    R = hdr.R
    R[2, 3] = R[3, 2] = -μ / 2
    lq = LQ(Q, -R, A, B, bet=β)

    P, F, _d = stationary_values(lq)

    # Need y_0 to compute government tax revenue.
    u0 = compute_u0(hdr, P)
    y0 = vcat([1.0 Q0 τ0]', u0)

    # Define A_F and S matricies
    AF = A - B * F
    S = [0.0 1.0 0.0 0]' * [0.0 0.0 1.0 0]

    # Solves equation (25)
    Ω = solve_discrete_lyapunov(sqrt(β) .* AF', β * AF' * S * AF)
    T0 = y0' * Ω * y0

    return T0[1], A, B, F, P
end

function compute_u0(hdr::HistDepRamsey, P::Matrix)
    # simplify notation
    Q0, τ0 = hdr.Q0, hdr.τ0

    P21 = P[4, 1:3]
    P22 = P[4, 4]
    z0 = [1.0 Q0 τ0]'
    u0 = reshape(-P22 ^ (-1) .* P21, 1, 3) * (z0)

    return u0[1]
end

function init_path{TF<:AbstractFloat}(hdr::HistDepRamsey{TF}, μ0::TF, T::Integer=20)
    # Construct starting values for the path of the Ramsey economy
    G0, A, B, F, P = compute_G(hdr, μ0)

    # Compute the optimal u0
    u0 = compute_u0(hdr, P)

    # Initialize vectors
    y = Array{TF}(4, T)
    uhat = Vector{TF}(T)
    uhatdif = Vector{TF}(T)
    τhat = Vector{TF}(T)
    τhatdif = Vector{TF}(T)
    μ = Vector{TF}(T)
    G = Vector{TF}(T)
    GPay = Vector{TF}(T)

    # Initial conditions
    G[1] = G0
    μ[1] = μ0
    uhatdif[1] = 0
    uhat[1] = u0
    τhatdif[1] = 0
    y[:, 1] = vcat([1.0 hdr.Q0 hdr.τ0]', u0)

    return RamseyPath(y, uhat, uhatdif, τhat, τhatdif, μ, G, GPay)
end

function compute_ramsey_path!(hdr::HistDepRamsey, rp::RamseyPath)
    # simplify notation
    y, uhat, uhatdif, τhat, = rp.y, rp.uhat, rp.uhatdif, rp.τhat
    τhatdif, μ, G, GPay = rp.τhatdif, rp.μ, rp.G, rp.GPay
    β = hdr.β

    _, A, B, F, P = compute_G(hdr, μ[1])

    for t=2:T
        # iterate government policy
        y[:, t] = (A - B * F) * y[:, t-1]

        # update G
        G[t] = (G[t - 1] - β * y[2, t] * y[3, t]) / β
        GPay[t] = β .* y[2, t] * y[3, t]

        #=
        Compute the μ if the government were able to reset its plan
        ff is the tax revenues the government would receive if they reset the
        plan with Lagrange multiplier μ minus current G
        =#
        ff(μ) = compute_G(hdr, μ)[1] - G[t]

        # find ff = 0
        μ[t] = fzero(ff, μ[t - 1])
        _, Atemp, Btemp, Ftemp, Ptemp = compute_G(hdr, μ[t])

        # Compute alternative decisions
        P21temp = Ptemp[4, 1:3]
        P22temp = P[4, 4]
        uhat[t] = dot(-P22temp ^ (-1) .* P21temp, y[1:3, t])

        yhat = (Atemp-Btemp * Ftemp) * [y[1:3, t-1]; uhat[t-1]]
        τhat[t] = yhat[4]
        τhatdif[t] = τhat[t] - y[4, t]
        uhatdif[t] = uhat[t] - y[4, t]
    end

    return rp
end

# Primitives
T = 20
A0 = 100.0
A1 = 0.05
d = 0.20
β = 0.95

# Initial conditions
μ0 = 0.0025
Q0 = 1000.0
τ0 = 0.0

# Solve Ramsey problem and compute path
hdr = HistDepRamsey(A0, A1, d, Q0, τ0, μ0, β)
rp = init_path(hdr, μ0, T)
compute_ramsey_path!(hdr, rp);                 # updates rp in place


text:
module css_code
	using Symplectic
	using errors

	type Code
		n::Int64
		w_x::Int64
		w_z::Int64
		X_S::Symp
		Z_S::Symp
		S_X::Array{Int64, 1}
		S_Z::Array{Int64, 1}
		E::Symp

		measure::Function
		decode::Function

		function Code(w_x::Int64, w_z::Int64, X_S::Symp, Z_S::Symp)

			this = new()

      		this.n = size(X_S)[2];
			this.w_x = w_x;
			this.w_z = w_z;
			this.X_S = X_S;
			this.Z_S = Z_S;

			(e_x, e_z) = _errors(this.n, this.w_x, this.w_z)
			n_E = size(e_x)[1];
			this.E = Symp(e_x, e_z)

			d_x = 2.^(0:(size(this.X_S)[1]-1));
			d_z = 2.^(0:(size(this.Z_S)[1]-1));
			this.S_X = zeros(n_E);
			this.S_Z = zeros(n_E);
			for k = 1:n_E
				this.S_X[k] = ((this.X_S*this.E[k,:])*d_x)[1];
				this.S_Z[k] = ((this.Z_S*this.E[k,:])*d_z)[1];
			end

			# Measure the syndromes
			this.measure = function(e::Symp)
			    s_x = this.X_S*e;
			    s_z = this.Z_S*e;
					d_x = 2.^(0:(size(s_x)[2]-1));
					d_z = 2.^(0:(size(s_z)[2]-1));
			    return (s_x*d_x, s_z*d_z)
			end

			this.decode = function(s_x::Array{Int64, 1}, s_z::Array{Int64, 1})
				hits_x = (s_x .== this.S_X)
				hits_z = (s_z .== this.S_Z)
				hits = hits_x & hits_z
				err_idx = find(hits)
				if length(err_idx) > 0
					# Correctable error or confusing error
					return (this.E[err_idx[1], :], length(err_idx))
				else
					# Uncorrectable error
					return (nothing, length(err_idx))
				end
			end

			return this
		end
	end
	export Code
end


text:
# Parameter of neural network
# Author: Philipp Witte, pwitte3@gatech.edu
# Date: January 2020

export Parameter, get_params, get_grads, set_params!, par2vec, vec2par

mutable struct Parameter
    data
    grad
end

convert_data!(::Type{T}, ::Parameter, ::AbstractArray{T, N}) where {T, N} = nothing
convert_data!(::Type{T}, p::Parameter, data::AbstractArray{T2, N}) where {T, T2, N} = (p.data = convert(AbstractArray{T, N}, data))
convert_data!(::Type{T}, ::Parameter, ::Nothing) where T = nothing

convert_grad!(::Type{T}, ::Parameter, ::AbstractArray{T, N}) where {T, N} = nothing
convert_grad!(::Type{T}, p::Parameter, data::AbstractArray{T2, N}) where {T, T2, N} = (p.grad = convert(AbstractArray{T, N}, data))
convert_grad!(::Type{T}, ::Parameter, ::Nothing) where T = nothing

function convert_param!(::Type{T}, p::Parameter) where T
    convert_data!(T, p, p.data)
    convert_grad!(T, p, p.grad)
end

"""
    Class for trainable network parameters.

 *Fields:*

 - `Parameter.data`: weights

 - `Parameter.grad`: gradient

"""
Parameter(x) = Parameter(x, nothing)

# Size and length for parameter types
size(x::Parameter) = size(x.data)
length(x::Parameter) = length(x.data)

@Flux.functor Parameter

"""
    clear_grad!(NL::NeuralNetLayer)

or

    clear_grad!(P::AbstractArray{Parameter, 1})

 Set gradients of each `Parameter` in the network layer to `nothing`.
"""
function clear_grad!(P::AbstractArray{Parameter, 1})
    for j=1:length(P)
        P[j].grad = nothing
    end
end

function get_grads(p::Parameter)
    return Parameter(p.grad)
end

function get_grads(pvec::Array{Parameter, 1})
    g = Array{Parameter, 1}(undef, length(pvec))
    for i = 1:length(pvec)
        g[i] = get_grads(pvec[i])
    end
    return g
end

function set_params!(pold::Parameter, pnew::Parameter)
    pold.data = pnew.data
    pold.grad = pnew.grad
end

function set_params!(pold::Array{Parameter, 1}, pnew::Array{Parameter, 1})
    for i = 1:length(pold)
        set_params!(pold[i], pnew[i])
    end
end

## Algebraic utilities for parameters

function dot(p1::Parameter, p2::Parameter)
    return dot(p1.data, p2.data)
end

function norm(p::Parameter)
    return norm(p.data)
end

function +(p1::Parameter, p2::Parameter)
    return Parameter(p1.data+p2.data)
end

function +(p1::Parameter, p2::T) where {T<:Real}
    return Parameter(p1.data+p2)
end

function +(p1::T, p2::Parameter) where {T<:Real}
    return p2+p1
end

function -(p1::Parameter, p2::Parameter)
    return Parameter(p1.data-p2.data)
end

function -(p1::Parameter, p2::T) where {T<:Real}
    return Parameter(p1.data-p2)
end

function -(p1::T, p2::Parameter) where {T<:Real}
    return -(p2-p1)
end

function -(p::Parameter)
    return Parameter(-p.data)
end

function *(p1::Parameter, p2::T) where {T<:Real}
    return Parameter(p1.data*p2)
end

function *(p1::T, p2::Parameter) where {T<:Real}
    return p2*p1
end

function /(p1::Parameter, p2::T) where {T<:Real}
    return Parameter(p1.data/p2)
end

function /(p1::T, p2::Parameter) where {T<:Real}
    return Parameter(p1/p2.data)
end

# Shape manipulation

par2vec(x::Parameter) = vec(x.data), size(x.data)

function vec2par(x::AbstractArray{T, 1}, s::NTuple{N, Int64}) where {T, N}
    return Parameter(reshape(x, s))
end

function par2vec(x::Array{Parameter, 1})
    v = cat([vec(x[i].data) for i=1:length(x)]..., dims=1)
    s = cat([size(x[i].data) for i=1:length(x)]..., dims=1)
    return v, s
end

function vec2par(x::AbstractArray{T, 1}, s::Array{Any, 1}) where T
    xpar = Array{Parameter, 1}(undef, length(s))
    idx_i = 0
    for i = 1:length(s)
        xpar[i] = vec2par(x[idx_i+1:idx_i+prod(s[i])], s[i])
        idx_i += prod(s[i])
    end
    return xpar
end


text:
# some code not tested to avoid redundancy from tests in NodesAndModes.
@testset "Reference elements" begin
    tol = 5e2*eps()

    N = 2
    @testset "Interval" begin
        rd = RefElemData(Line(),N)
        @test rd.r == rd.rst[1]
        @test rd.Np == length(rd.r)
        @test abs(sum(rd.rq.*rd.wq)) < tol
        @test rd.nrJ ≈ [-1,1]
        @test rd.Pq*rd.Vq ≈ I
        @test rd.r[rd.Fmask[:]] ≈ rd.rf
        @test invoke(inverse_trace_constant,Tuple{RefElemData},rd) ≈ inverse_trace_constant(rd)
        @test propertynames(rd)[1] == :elementType
    end

    @testset "Triangle" begin
        rd = RefElemData(Tri(),N)
        @test rd.r == rd.rst[1]
        @test rd.Np == length(rd.r)
        @test rd.Nq == length(rd.rq)
        @test abs(sum(rd.wq)) ≈ 2
        @test abs(sum(rd.wf)) ≈ 6
        @test abs(sum(rd.wf .* rd.nrJ)) + abs(sum(rd.wf .* rd.nsJ)) < tol
        @test rd.Pq*rd.Vq ≈ I
        Vfp = vandermonde(Line(),N,quad_nodes(Line(),N)[1])/vandermonde(Line(),N,nodes(Line(),N))
        rstf = (x->Vfp*x[reshape(rd.Fmask,rd.Nfq÷rd.Nfaces,rd.Nfaces)]).(rd.rst)
        @test all(vec.(rstf) .≈ rd.rstf)
        @test invoke(inverse_trace_constant,Tuple{RefElemData},rd) ≈ inverse_trace_constant(rd)
        @test propertynames(rd)[1] == :elementType
    end

    @testset "Quad" begin
        rd = RefElemData(Quad(),N)
        @test rd.r == rd.rst[1]
        @test rd.Np == length(rd.r)
        @test rd.Nq == length(rd.rq)
        @test abs(sum(rd.wq)) ≈ 4
        @test abs(sum(rd.wf)) ≈ 8
        @test abs(sum(rd.wf .* rd.nrJ)) + abs(sum(rd.wf .* rd.nsJ)) < tol
        @test rd.Pq*rd.Vq ≈ I
        Vfp = vandermonde(Line(),N,quad_nodes(Line(),N)[1])/vandermonde(Line(),N,nodes(Line(),N))
        rstf = (x->Vfp*x[reshape(rd.Fmask,rd.Nfq÷rd.Nfaces,rd.Nfaces)]).(rd.rst)
        @test all(vec.(rstf) .≈ rd.rstf)
        @test invoke(inverse_trace_constant,Tuple{RefElemData},rd) ≈ inverse_trace_constant(rd)
    end

    @testset "Hex" begin
        rd = RefElemData(Hex(),N)
        @test propertynames(rd)[1] == :elementType
        @test rd.t == rd.rst[3]
        @test rd.tf == rd.rstf[3]
        @test rd.tq == rd.rstq[3]
        @test rd.rp == rd.rstp[1]
        @test rd.sp == rd.rstp[2]
        @test rd.tp == rd.rstp[3]
        @test rd.Np == length(rd.r)
        @test rd.Nq == length(rd.rq)
        @test abs(sum(rd.wq)) ≈ 8
        @test abs(sum(rd.wf)) ≈ 6*4
        @test abs(sum(rd.wf .* rd.nrJ)) < tol
        @test abs(sum(rd.wf .* rd.nsJ)) < tol
        @test abs(sum(rd.wf .* rd.ntJ)) < tol
        @test rd.Pq*rd.Vq ≈ I
        @test invoke(inverse_trace_constant,Tuple{RefElemData},rd) ≈ inverse_trace_constant(rd)
        # TODO: test interpolation of Fmask matches rd.rstf.
    end

    @testset "Tet" begin
        rd = RefElemData(Tet(),N)
        @test propertynames(rd)[1] == :elementType
        @test rd.t == rd.rst[3]
        @test rd.tf == rd.rstf[3]
        @test rd.tq == rd.rstq[3]
        @test rd.rp == rd.rstp[1]
        @test rd.sp == rd.rstp[2]
        @test rd.tp == rd.rstp[3]
        @test rd.Np == length(rd.r)
        @test rd.Nq == length(rd.rq)
        @test abs(sum(rd.wq)) ≈ 4/3
        @test abs(sum(rd.wf)) ≈ 8
        @test abs(sum(rd.wf .* rd.nrJ)) < tol
        @test abs(sum(rd.wf .* rd.nsJ)) < tol
        @test abs(sum(rd.wf .* rd.ntJ)) < tol
        @test rd.Pq*rd.Vq ≈ I
        @test invoke(inverse_trace_constant,Tuple{RefElemData},rd) ≈ inverse_trace_constant(rd)
    end
end


text:
# Initialization of main function
function EthylDynamicGUI()
    # Suppress warnings
    #@suppress begin

    # Environmental variable to allow Windows decorations
    ENV["GTK_CSD"] = 0

    # CSS style
    global provider = CssProviderLeaf(filename = style_file)

    ################################################################################
    # Min Win
    ################################################################################
    mainWin = Window()
    # Properties for mainWin
    set_gtk_property!(mainWin, :title, "EthylDynamic")
    set_gtk_property!(mainWin, :window_position, 3)
    set_gtk_property!(mainWin, :accept_focus, true)
    set_gtk_property!(mainWin, :resizable, false)
    set_gtk_property!(mainWin, :visible, false)
    screen = Gtk.GAccessor.style_context(mainWin)
    push!(screen, StyleProvider(provider), 600)

    ################################################################################
    # Grids
    ################################################################################
    # Properties for mainGrid
    mainGrid = Grid()
    set_gtk_property!(mainGrid, :column_spacing, 20)
    set_gtk_property!(mainGrid, :row_spacing, 20)
    set_gtk_property!(mainGrid, :margin_top, 30)
    set_gtk_property!(mainGrid, :margin_bottom, 20)
    set_gtk_property!(mainGrid, :margin_left, 20)
    set_gtk_property!(mainGrid, :margin_right, 20)
    set_gtk_property!(mainGrid, :column_homogeneous, true)
    set_gtk_property!(mainGrid, :row_homogeneous, false)

    ################################################################################
    # Main buttons
    ################################################################################
    # New simulation actions
    new = Button("New simulation")
    set_gtk_property!(new, :name, "new")
    set_gtk_property!(new, :width_request, 150)
    set_gtk_property!(new, :height_request, 80)
    screen = Gtk.GAccessor.style_context(new)
    push!(screen, StyleProvider(provider), 600)

    open = Button("Open simulation")
    set_gtk_property!(open, :name, "open")
    screen = Gtk.GAccessor.style_context(open)
    push!(screen, StyleProvider(provider), 600)

    tools = Button("Tools")
    set_gtk_property!(tools, :name, "tools")
    set_gtk_property!(tools, :width_request, 150)
    set_gtk_property!(tools, :height_request, 80)
    screen = Gtk.GAccessor.style_context(tools)
    push!(screen, StyleProvider(provider), 600)

    tutorial = Button("Tutorial")
    set_gtk_property!(tutorial, :name, "tutorial")
    set_gtk_property!(tutorial, :width_request, 150)
    set_gtk_property!(tutorial, :height_request, 80)
    screen = Gtk.GAccessor.style_context(tutorial)
    push!(screen, StyleProvider(provider), 600)

    about = Button("About")
    set_gtk_property!(about, :name, "about")
    set_gtk_property!(about, :width_request, 150)
    set_gtk_property!(about, :height_request, 80)
    screen = Gtk.GAccessor.style_context(about)
    push!(screen, StyleProvider(provider), 600)

    close = Button("Close")
    set_gtk_property!(close, :name, "close")
    screen = Gtk.GAccessor.style_context(close)
    push!(screen, StyleProvider(provider), 600)

    ################################################################################
    # New simulation window
    ################################################################################
    signal_connect(new, :clicked) do widget

        newWin = Window()
        # Properties for mainWin
        set_gtk_property!(newWin, :title, "EthylDynamic 1.0 - *Untitled")
        set_gtk_property!(newWin, :window_position, 3)
        set_gtk_property!(newWin, :height_request, 800)
        set_gtk_property!(newWin, :width_request, 1200)
        set_gtk_property!(newWin, :accept_focus, true)
        set_gtk_property!(newWin, :resizable, false)
        #screen = Gtk.GAccessor.style_context(newWin)
        #push!(screen, StyleProvider(provider), 600)

        # Menu Icons
        tb1 = ToolButton("gtk-new")
        set_gtk_property!(tb1, :label, "New")
        set_gtk_property!(tb1, :tooltip_markup, "Create a new simulation environment")

        tb2 = ToolButton("gtk-open")
        set_gtk_property!(tb2, :label, "Open")
        set_gtk_property!(tb2, :tooltip_markup, "Open a simulation file")

        tb3 = ToolButton("gtk-floppy")
        set_gtk_property!(tb3, :label, "Save as")
        set_gtk_property!(
            tb3,
            :tooltip_markup,
            "Save the current state environment to a JLD file",
        )
        set_gtk_property!(tb3, :sensitive, false)

        # Close toolbar
        tb4 = ToolButton("gtk-close")
        set_gtk_property!(tb4, :label, "Close")
        set_gtk_property!(tb4, :tooltip_markup, "Close current simulation environment")

        signal_connect(tb4, :clicked) do widget
            destroy(newWin)
            set_gtk_property!(mainWin, :visible, true)
        end

        signal_connect(newWin, "key-press-event") do widget, event
            if event.keyval == 65307
                destroy(newWin)
                set_gtk_property!(mainWin, :visible, true)
            end
        end

        tb5 = ToolButton("gtk-media-previous")
        set_gtk_property!(tb5, :label, "Back")
        set_gtk_property!(tb5, :tooltip_markup, "Go to previous tab")

        tb6 = ToolButton("gtk-media-next")
        set_gtk_property!(tb6, :label, "Next")
        set_gtk_property!(tb6, :tooltip_markup, "Go to next tab")

        tb7 = ToggleToolButton("gtk-media-play")
        set_gtk_property!(tb7, :label, "Run (auto)")
        set_gtk_property!(tb7, :tooltip_markup, "Solve the simulation environment")

        tb8 = ToolButton("gtk-preferences")
        set_gtk_property!(tb8, :label, "Tools")
        set_gtk_property!(tb8, :tooltip_markup, "Simulation environtment tools")

        # Toolbar
        newToolbar = Toolbar()
        set_gtk_property!(newToolbar, :height_request, 20)
        set_gtk_property!(newToolbar, :toolbar_style, 2)
        push!(newToolbar, SeparatorToolItem())
        push!(newToolbar, tb1)
        push!(newToolbar, tb2)
        push!(newToolbar, tb3)
        push!(newToolbar, SeparatorToolItem())
        push!(newToolbar, tb5)
        push!(newToolbar, tb6)
        push!(newToolbar, tb7)
        push!(newToolbar, SeparatorToolItem())
        push!(newToolbar, tb8)
        push!(newToolbar, SeparatorToolItem())
        push!(newToolbar, tb4)
        push!(newToolbar, SeparatorToolItem())

        gridToolbar = Grid()
        set_gtk_property!(gridToolbar, :column_homogeneous, true)
        set_gtk_property!(gridToolbar, :row_homogeneous, false)

        frameToolbar = Frame()
        push!(frameToolbar, newToolbar)
        gridToolbar[1, 1] = frameToolbar

        # newNotebook
        global nb = Notebook()
        set_gtk_property!(nb, :tab_pos, 0)
        screen = Gtk.GAccessor.style_context(nb)
        push!(screen, StyleProvider(provider), 600)

        ############################################################################
        # Tab 0 - User properties
        ############################################################################
        nbFrame0 = Frame()
        screen = Gtk.GAccessor.style_context(nbFrame0)
        push!(screen, StyleProvider(provider), 600)

        vbox00 = Grid()
        set_gtk_property!(vbox00, :column_homogeneous, false)
        set_gtk_property!(vbox00, :row_homogeneous, false)
        set_gtk_property!(vbox00, :halign, 3)
        set_gtk_property!(vbox00, :valign, 3)
        set_gtk_property!(vbox00, :row_spacing, 20)

        vbox0 = Grid()
        set_gtk_property!(vbox0, :column_homogeneous, false)
        set_gtk_property!(vbox0, :row_homogeneous, false)
        set_gtk_property!(vbox0, :column_spacing, 10)
        set_gtk_property!(vbox0, :row_spacing, 10)
        set_gtk_property!(vbox0, :margin_top, 20)
        set_gtk_property!(vbox0, :margin_bottom, 20)
        set_gtk_property!(vbox0, :margin_left, 20)
        set_gtk_property!(vbox0, :margin_right, 20)
        set_gtk_property!(vbox0, :halign, 3)

        nameUser = Label("Username:")
        set_gtk_property!(nameUser, :name, "nameUser")
        screen = Gtk.GAccessor.style_context(nameUser)
        push!(screen, StyleProvider(provider), 600)

        nameUserEntry = Entry()
        screen = Gtk.GAccessor.style_context(nameUserEntry)
        push!(screen, StyleProvider(provider), 600)

        simName = Label("Simulation Name:")
        set_gtk_property!(simName, :name, "simName")
        screen = Gtk.GAccessor.style_context(simName)
        push!(screen, StyleProvider(provider), 600)

        simUserEntry = Entry()
        screen = Gtk.GAccessor.style_context(simUserEntry)
        push!(screen, StyleProvider(provider), 600)

        dirName = Label("Directory:")
        set_gtk_property!(dirName, :name, "dirName")
        screen = Gtk.GAccessor.style_context(dirName)
        push!(screen, StyleProvider(provider), 600)

        dirNameEntry = Entry()
        screen = Gtk.GAccessor.style_context(dirNameEntry)
        push!(screen, StyleProvider(provider), 600)

        compName = Label("Company:")
        set_gtk_property!(compName, :name, "compName")
        screen = Gtk.GAccessor.style_context(compName)
        push!(screen, StyleProvider(provider), 600)

        compNameEntry = Entry()
        screen = Gtk.GAccessor.style_context(compNameEntry)
        push!(screen, StyleProvider(provider), 600)

        dateName = Label("Date:")
        set_gtk_property!(dateName, :name, "dateName")
        set_gtk_property!(dateName, :width_request, 200)
        screen = Gtk.GAccessor.style_context(dateName)
        push!(screen, StyleProvider(provider), 600)

        dateNameEntry = Entry()
        set_gtk_property!(dateNameEntry, :editable, false)
        set_gtk_property!(dateNameEntry, :width_request, 700)
        screen = Gtk.GAccessor.style_context(dateNameEntry)
        push!(screen, StyleProvider(provider), 600)

        notesName = Label("Notes:")
        set_gtk_property!(notesName, :name, "notesName")
        screen = Gtk.GAccessor.style_context(notesName)
        push!(screen, StyleProvider(provider), 600)

        # TODO wrap text
        notesNameEntry = Entry()
        set_gtk_property!(notesNameEntry, :height_request, 200)
        screen = Gtk.GAccessor.style_context(notesNameEntry)
        push!(screen, StyleProvider(provider), 600)

        timenow = Dates.now()
        timenow1 = Dates.format(timenow, "dd u yyyy HH:MM:SS")
        set_gtk_property!(dateNameEntry, :text, timenow1)

        vbox0[1, 1] = nameUser
        vbox0[2, 1] = nameUserEntry
        vbox0[1, 2] = simName
        vbox0[2, 2] = simUserEntry
        vbox0[1, 3] = dirName
        vbox0[2, 3] = dirNameEntry
        vbox0[1, 4] = compName
        vbox0[2, 4] = compNameEntry
        vbox0[1, 5] = dateName
        vbox0[2, 5] = dateNameEntry
        vbox0[1, 6] = notesName
        vbox0[2, 6:12] = notesNameEntry

        vbox00[1:30, 1] = vbox0
        # Separador (decorator)
        sep0 = Frame()
        set_gtk_property!(sep0, :width_request, 1000)
        set_gtk_property!(sep0, :height_request, 0)

        #vbox00[1:12, 2] = sep0

        saveStartup = ToolButton("gtk-floppy")
        clearStartup = ToolButton("gtk-clear")

        vbox00[29, 3] = clearStartup
        vbox00[30, 3] = saveStartup

        push!(nbFrame0, vbox00)
        push!(nb, nbFrame0, "Startup")

        ############################################################################
        # Tab 1
        ############################################################################
        nbFrame1 = Frame()
        screen = Gtk.GAccessor.style_context(nbFrame1)
        push!(screen, StyleProvider(provider), 600)

        vbox1 = Grid()
        set_gtk_property!(vbox1, :column_homogeneous, false)
        set_gtk_property!(vbox1, :row_homogeneous, false)
        set_gtk_property!(vbox1, :column_spacing, 10)
        set_gtk_property!(vbox1, :row_spacing, 10)
        set_gtk_property!(vbox1, :margin_top, 10)
        set_gtk_property!(vbox1, :margin_bottom, 20)
        set_gtk_property!(vbox1, :margin_left, 20)
        set_gtk_property!(vbox1, :margin_right, 20)
        set_gtk_property!(vbox1, :halign, 3)

        # Frame for databank
        vbox1Frame1 = Frame("Databank")
        #set_gtk_property!(vbox1Frame1, :height_request, 340)
        set_gtk_property!(vbox1Frame1, :label_xalign, 0.50)
        set_gtk_property!(vbox1Frame1, :shadow_type, 0)

        # Frame for compouns
        vbox1Frame2 = Frame("Added Components")
        #set_gtk_property!(vbox1Frame2, :height_request, 280)
        set_gtk_property!(vbox1Frame2, :label_xalign, 0.50)
        set_gtk_property!(vbox1Frame2, :shadow_type, 0)

        # Separador (decorator)
        sep = Frame()
        set_gtk_property!(sep, :width_request, 1000)
        set_gtk_property!(sep, :height_request, 0)

        ############################################################################
        # Datasheet vbox1Frame1
        gridDatabank = Grid()
        set_gtk_property!(gridDatabank, :halign, 3)
        set_gtk_property!(gridDatabank, :valign, 3)

        # Grid for Buttons around TreeView dataBank
        gridDataButtons = Grid()
        set_gtk_property!(gridDataButtons, :halign, 3)
        set_gtk_property!(gridDataButtons, :valign, 3)
        set_gtk_property!(gridDataButtons, :column_homogeneous, false)
        set_gtk_property!(gridDataButtons, :row_homogeneous, false)
        set_gtk_property!(gridDataButtons, :column_spacing, 10)
        set_gtk_property!(gridDataButtons, :row_spacing, 10)

        # Frame with border to enhance the style
        frameDatabank = Frame()

        # GtkListStore where the data is actually saved
        global listDatabank = ListStore(
            String,
            String,
            Float64,
            Float64,
            Float64,
            Float64,
            Float64,
            Float64,
            Float64,
        )

        for i = 1:size(database)[1]
            push!(
                listDatabank,
                (
                 database[i, 1],
                 database[i, 2],
                 database[i, 3],
                 database[i, 4],
                 database[i, 5],
                 database[i, 6],
                 database[i, 7],
                 database[i, 8],
                 database[i, 9],
                ),
            )
        end

        # Gtk TreeView to show the graphical element
        global viewDatabank = TreeView(TreeModel(listDatabank))
        set_gtk_property!(viewDatabank, :enable_grid_lines, 3)
        set_gtk_property!(viewDatabank, :enable_search, true)
        screen = Gtk.GAccessor.style_context(viewDatabank)
        push!(screen, StyleProvider(provider), 600)

        # Window that allow scroll the TreeView
        scrollDatabank = ScrolledWindow(viewDatabank)
        set_gtk_property!(scrollDatabank, :width_request, 750)
        set_gtk_property!(scrollDatabank, :height_request, 250)
        selection1 = Gtk.GAccessor.selection(viewDatabank)

        # Column definitions
        cTxt1 = CellRendererText()

        c11 = TreeViewColumn("Molecule", cTxt1, Dict([("text", 0)]))
        c12 = TreeViewColumn("Name", cTxt1, Dict([("text", 1)]))
        c13 = TreeViewColumn("MW", cTxt1, Dict([("text", 2)]))
        c14 = TreeViewColumn("ω", cTxt1, Dict([("text", 3)]))
        c15 = TreeViewColumn("Tc [K]", cTxt1, Dict([("text", 4)]))
        c16 = TreeViewColumn("Pc [bar]", cTxt1, Dict([("text", 5)]))
        c17 = TreeViewColumn("Zc", cTxt1, Dict([("text", 6)]))
        c18 = TreeViewColumn("Vc [cm^3/mol]", cTxt1, Dict([("text", 7)]))
        c19 = TreeViewColumn("Tn [K]", cTxt1, Dict([("text", 8)]))

        # Add column to TreeView
        push!(viewDatabank, c11, c12, c13, c14, c15, c16, c17, c18, c19)

        # Add scrool window to the frame
        push!(frameDatabank, scrollDatabank)

        # Add frame to grid to allow halign & valign
        gridDatabank[1, 1] = frameDatabank

        # Buttons around TreeView of dataBank

        searchDatabank = Entry()
        set_gtk_property!(searchDatabank, :text, "Search component")

        loadDatabank = Button("Search")

        openDatabank = ToolButton("gtk-open")
        signal_connect(openDatabank, :clicked) do widget
            global pathDatabase = open_dialog_native("Pick a file", Null(), ("*.csv",))

            if ~isempty(pathDatabase)
                @sigatom selection1 = Gtk.GAccessor.selection(viewDatabank)
                @sigatom selection1 = Gtk.GAccessor.mode(
                    selection1,
                    Gtk.GConstants.GtkSelectionMode.NONE,
                )
                empty!(listDatabank)

                global database = CSV.read(pathDatabase)

                for i = 1:size(database)[1]
                    push!(
                        listDatabank,
                        (
                         database[i, 1],
                         database[i, 2],
                         database[i, 3],
                         database[i, 4],
                         database[i, 5],
                         database[i, 6],
                         database[i, 7],
                         database[i, 8],
                         database[i, 9],
                        ),
                    )
                end

                @sigatom selection1 = Gtk.GAccessor.selection(viewDatabank)
                @sigatom selection1 = Gtk.GAccessor.mode(
                    selection1,
                    Gtk.GConstants.GtkSelectionMode.SINGLE,
                )
            end
        end

        addDatabank = ToolButton("gtk-add")

        remDatabank = ToolButton("gtk-remove")
        signal_connect(remDatabank, :clicked) do widget
            if hasselection(selection1)
                global listDatabank
                currentIt = selected(selection1)
                deleteat!(listDatabank, currentIt)
            end
        end

        newDatabank = ToolButton("gtk-new")

        editDatabank = ToolButton("gtk-edit")

        selectDatabank = ToolButton("gtk-go-down")
        signal_connect(selectDatabank, :clicked) do widget
            if hasselection(selection1)
                global viewComp
                currentIt = selected(selection1)

                push!(
                    listComp,
                    (
                     listDatabank[currentIt, 1],
                     listDatabank[currentIt, 2],
                     listDatabank[currentIt, 3],
                     listDatabank[currentIt, 4],
                     listDatabank[currentIt, 5],
                     listDatabank[currentIt, 6],
                     listDatabank[currentIt, 7],
                     listDatabank[currentIt, 8],
                     listDatabank[currentIt, 9],
                    ),
                )

                selection2 = Gtk.GAccessor.selection(viewComp)
                selection2 = Gtk.GAccessor.mode(
                    selection2,
                    Gtk.GConstants.GtkSelectionMode.SINGLE,
                )
            end
        end

        # Functions to reacts to double click and add the selected component
        function activate_row_cb(widgetptr::Ptr, path::Ptr, column::Ptr, user_data)
            tv = convert(GtkTreeView, widgetptr)
            ls = user_data

            selection = Gtk.GAccessor.selection(tv)

            if hasselection(selection)
                global viewComp

                currentIt = selected(selection)
                push!(
                    listComp,
                    (
                     ls[currentIt, 1],
                     ls[currentIt, 2],
                     ls[currentIt, 3],
                     ls[currentIt, 4],
                     ls[currentIt, 5],
                     ls[currentIt, 6],
                     ls[currentIt, 7],
                     ls[currentIt, 8],
                     ls[currentIt, 9],
                    ),
                )

                global selection2 = Gtk.GAccessor.selection(viewComp)
                selection2 = Gtk.GAccessor.mode(
                    selection2,
                    Gtk.GConstants.GtkSelectionMode.SINGLE,
                )
            end
            nothing
        end

        # Call to activate_row_cb
        signal_connect(
            activate_row_cb,
            viewDatabank,
            "row-activated",
            Nothing,
            (Ptr{GtkTreePath}, Ptr{GtkTreeViewColumn}),
            false,
            listDatabank,
        )

        saveDatabank = ToolButton("gtk-floppy")

        clearDatabank = ToolButton("gtk-clear")

        csvDatabank = ToolButton("gtk-redo")

        printDatabank = ToolButton("gtk-print")

        # Close keyboard Esc
        signal_connect(clearDatabank, :clicked) do widget
            # Avoid julia session breaks
            @sigatom selection1 = Gtk.GAccessor.selection(viewDatabank)
            @sigatom selection1 = Gtk.GAccessor.mode(
                selection1,
                Gtk.GConstants.GtkSelectionMode.NONE,
            )
            empty!(listDatabank)
        end

        gridDataButtons[2, 1] = searchDatabank
        gridDataButtons[3, 1] = loadDatabank
        gridDataButtons[2:3, 2:8] = gridDatabank
        gridDataButtons[1, 2] = openDatabank
        gridDataButtons[1, 3] = newDatabank
        gridDataButtons[1, 4] = editDatabank
        gridDataButtons[1, 5] = saveDatabank
        gridDataButtons[1, 6] = csvDatabank
        gridDataButtons[4, 2] = remDatabank
        gridDataButtons[4, 3] = addDatabank
        gridDataButtons[4, 4] = selectDatabank
        gridDataButtons[4, 5] = clearDatabank
        gridDataButtons[4, 6] = printDatabank

        # Add to second frame in vbox1
        push!(vbox1Frame1, gridDataButtons)

        # Allow to resize columns
        for c in [c11, c12, c13, c14]
            Gtk.GAccessor.resizable(c, true)
        end

        # Allow to sort columns
        for (i, c) in enumerate([c11, c12, c13, c14])
            Gtk.GAccessor.sort_column_id(c, i - 1)
        end

        # Allow to reorder columns
        for (i, c) in enumerate([c11, c12, c13, c14])
            Gtk.GAccessor.reorderable(c, i)
        end

        ############################################################################
        # Datasheet vboxFrame2
        gridComp = Grid()
        set_gtk_property!(gridComp, :halign, 3)
        set_gtk_property!(gridComp, :valign, 3)

        # Grid for Buttons around TreeView viewComp
        gridCompButtons = Grid()
        set_gtk_property!(gridCompButtons, :halign, 3)
        set_gtk_property!(gridCompButtons, :valign, 3)
        set_gtk_property!(gridCompButtons, :column_homogeneous, false)
        set_gtk_property!(gridCompButtons, :row_homogeneous, false)
        set_gtk_property!(gridCompButtons, :column_spacing, 10)
        set_gtk_property!(gridCompButtons, :row_spacing, 10)

        # Frame with border to enhance the style
        frameComp = Frame()

        # GtkListStore where the data is actually saved
        global listComp = ListStore(
            String,
            String,
            Float64,
            Float64,
            Float64,
            Float64,
            Float64,
            Float64,
            Float64,
        )

        # Gtk TreeView to show the graphical element
        global viewComp = TreeView(TreeModel(listComp))
        set_gtk_property!(viewComp, :enable_grid_lines, 3)
        set_gtk_property!(viewComp, :enable_search, true)
        screen = Gtk.GAccessor.style_context(viewComp)
        push!(screen, StyleProvider(provider), 600)

        # Window that allow scroll the TreeView
        scrollComp = ScrolledWindow(viewComp)
        set_gtk_property!(scrollComp, :width_request, 750)
        set_gtk_property!(scrollComp, :height_request, 250)
        selection2 = Gtk.GAccessor.selection(viewComp)
        selection2 = Gtk.GAccessor.mode(
            selection2,
            Gtk.GConstants.GtkSelectionMode.SINGLE,
        )

        # Column definitions
        cTxt2 = CellRendererText()

        c21 = TreeViewColumn("Molecule", cTxt2, Dict([("text", 0)]))
        c22 = TreeViewColumn("Name", cTxt2, Dict([("text", 1)]))
        c23 = TreeViewColumn("MW", cTxt2, Dict([("text", 2)]))
        c24 = TreeViewColumn("ω", cTxt2, Dict([("text", 3)]))
        c25 = TreeViewColumn("Tc [K]", cTxt2, Dict([("text", 4)]))
        c26 = TreeViewColumn("Pc [bar]", cTxt2, Dict([("text", 5)]))
        c27 = TreeViewColumn("Zc", cTxt2, Dict([("text", 6)]))
        c28 = TreeViewColumn("Vc [cm^3/mol]", cTxt2, Dict([("text", 7)]))
        c29 = TreeViewColumn("Tn [K]", cTxt2, Dict([("text", 8)]))

        # Add column to TreeView
        push!(viewComp, c21, c22, c23, c24, c25, c26, c27, c28, c29)

        # Add scrool window to the frame
        push!(frameComp, scrollComp)

        # Buttons around TreeView of dataComp
        openComp = ToolButton("gtk-open")

        editComp = ToolButton("gtk-edit")

        saveComp = ToolButton("gtk-floppy")

        csvComp = ToolButton("gtk-redo")

        remComp = ToolButton("gtk-remove")
        signal_connect(remComp, :clicked) do widget
            if hasselection(selection2)
                global listComp
                currentIt = selected(selection2)
                deleteat!(listComp, currentIt)
            end
        end

        addComp = ToolButton("gtk-add")

        clearComp = ToolButton("gtk-clear")

        printComp = ToolButton("gtk-print")

        # Close keyboard Esc
        signal_connect(clearComp, :clicked) do widget
            # Avoid julia session breaks
            selection2 = Gtk.GAccessor.selection(viewComp)
            selection2 = Gtk.GAccessor.mode(
                selection2,
                Gtk.GConstants.GtkSelectionMode.NONE,
            )
            empty!(listComp)
        end

        # Add frame to grid to allow halign & valign
        gridComp[1, 1] = frameComp

        gridCompButtons[2:3, 1:6] = gridComp
        gridCompButtons[1, 1] = openComp
        gridCompButtons[1, 2] = editComp
        gridCompButtons[1, 3] = saveComp
        gridCompButtons[1, 4] = csvComp
        gridCompButtons[4, 1] = remComp
        gridCompButtons[4, 2] = addComp
        gridCompButtons[4, 3] = clearComp
        gridCompButtons[4, 4] = printComp

        # Add to second frame in vbox1
        push!(vbox1Frame2, gridCompButtons)

        # Allow to resize columns
        for c in [c21, c22, c23, c24]
            Gtk.GAccessor.resizable(c, true)
        end

        # Allow to sort columns
        for (i, c) in enumerate([c21, c22, c23, c24])
            Gtk.GAccessor.sort_column_id(c, i - 1)
        end

        # Allow to reorder columns
        for (i, c) in enumerate([c21, c22, c23, c24])
            Gtk.GAccessor.reorderable(c, i)
        end

        ############################################################################
        vbox1[1, 1] = vbox1Frame1
        vbox1[1, 2] = sep
        vbox1[1, 3] = vbox1Frame2

        push!(nbFrame1, vbox1)
        push!(nb, nbFrame1, "Compounds")

        ############################################################################
        # Tab 2
        ############################################################################
        nbFrame2 = Frame()
        screen = Gtk.GAccessor.style_context(nbFrame2)
        push!(screen, StyleProvider(provider), 600)

        vbox2 = Grid()
        set_gtk_property!(vbox2, :column_homogeneous, true)
        set_gtk_property!(vbox2, :row_homogeneous, false)
        set_gtk_property!(vbox2, :column_spacing, 20)
        set_gtk_property!(vbox2, :row_spacing, 20)
        set_gtk_property!(vbox2, :margin_top, 30)
        set_gtk_property!(vbox2, :margin_bottom, 30)
        set_gtk_property!(vbox2, :margin_left, 30)
        set_gtk_property!(vbox2, :margin_right, 30)
        set_gtk_property!(vbox2, :halign, 3)

        push!(nbFrame2, vbox2)
        push!(nb, nbFrame2, "Equipments")

        vbox2Button1 = Button("Separators")
        set_gtk_property!(vbox2Button1, :name, "Separators")
        set_gtk_property!(vbox2Button1, :width_request, 100)
        set_gtk_property!(vbox2Button1, :height_request, 80)
        screen = Gtk.GAccessor.style_context(vbox2Button1)
        push!(screen, StyleProvider(provider), 600)

        vbox2Button2 = Button("Columns")
        set_gtk_property!(vbox2Button2, :name, "Columns")
        set_gtk_property!(vbox2Button2, :width_request, 100)
        set_gtk_property!(vbox2Button2, :height_request, 80)
        screen = Gtk.GAccessor.style_context(vbox2Button2)
        push!(screen, StyleProvider(provider), 600)

        vbox2Button3 = Button("Heat Exchangers")
        set_gtk_property!(vbox2Button3, :name, "Exchangers")
        set_gtk_property!(vbox2Button3, :width_request, 100)
        set_gtk_property!(vbox2Button3, :height_request, 80)
        screen = Gtk.GAccessor.style_context(vbox2Button3)
        push!(screen, StyleProvider(provider), 600)

        vbox2Button4 = Button("Tanks")
        set_gtk_property!(vbox2Button4, :name, "Tanks")
        set_gtk_property!(vbox2Button4, :always_show_image, true)
        set_gtk_property!(vbox2Button4, :width_request, 100)
        set_gtk_property!(vbox2Button4, :height_request, 80)
        screen = Gtk.GAccessor.style_context(vbox2Button4)
        push!(screen, StyleProvider(provider), 600)

        vbox2Button5 = Button("Reactors")
        set_gtk_property!(vbox2Button5, :name, "Reactors")
        set_gtk_property!(vbox2Button5, :width_request, 100)
        set_gtk_property!(vbox2Button5, :height_request, 80)
        screen = Gtk.GAccessor.style_context(vbox2Button5)
        push!(screen, StyleProvider(provider), 600)

        equitFrameFig = Frame()
        set_gtk_property!(equitFrameFig, :height_request, 500)

        # TreeView for Equitments
        listStreamsEquit = ListStore(String, String, String)
        push!(listStreamsEquit, ("R1", "Reactor1", "Reactor"))
        push!(listStreamsEquit, ("R2", "Reactor2", "Reactor"))
        push!(listStreamsEquit, ("R3", "Reactor3", "Reactor"))

        viewStreamsEquit = TreeView(TreeModel(listStreamsEquit))
        set_gtk_property!(viewStreamsEquit, :enable_grid_lines, 3)
        set_gtk_property!(viewStreamsEquit, :enable_search, true)

        # Window that allow scroll the TreeView
        scrollStreamsEquit = ScrolledWindow(viewStreamsEquit)
        set_gtk_property!(scrollStreamsEquit, :width_request, 350)
        set_gtk_property!(scrollStreamsEquit, :height_request, 250)
        selection5 = Gtk.GAccessor.selection(viewStreamsEquit)

        # Column definitions
        cTxtREs3 = CellRendererText()

        cResEquit1 = TreeViewColumn("ID", cTxtREs3, Dict([("text", 0)]))
        cResEquit2 = TreeViewColumn("Name", cTxtREs3, Dict([("text", 1)]))
        cResEquit3 = TreeViewColumn("Type", cTxtREs3, Dict([("text", 2)]))

        # Add column to TreeView
        push!(viewStreamsEquit, cResEquit1, cResEquit2, cResEquit3)

        # Frame for viewEquit
        equitFrameTree = Frame()
        set_gtk_property!(equitFrameTree, :height_request, 500)

        push!(equitFrameTree, scrollStreamsEquit)

        vbox2[1:2, 1] = equitFrameFig
        vbox2[3:5, 1] = equitFrameTree
        vbox2[1, 2] = vbox2Button1
        vbox2[2, 2] = vbox2Button2
        vbox2[3, 2] = vbox2Button3
        vbox2[4, 2] = vbox2Button4
        vbox2[5, 2] = vbox2Button5

        ############################################################################
        # Tab 3 - Flowsheet
        ############################################################################
        nbFrame3 = Frame()
        screen = Gtk.GAccessor.style_context(nbFrame3)
        push!(screen, StyleProvider(provider), 600)

        vbox3 = Grid()
        set_gtk_property!(vbox3, :column_homogeneous, false)
        set_gtk_property!(vbox3, :row_homogeneous, false)
        set_gtk_property!(vbox3, :column_spacing, 10)
        set_gtk_property!(vbox3, :row_spacing, 10)
        set_gtk_property!(vbox3, :margin_top, 10)
        set_gtk_property!(vbox3, :margin_bottom, 20)
        set_gtk_property!(vbox3, :margin_left, 20)
        set_gtk_property!(vbox3, :margin_right, 20)
        set_gtk_property!(vbox3, :halign, 3)

        push!(nbFrame3, vbox3)
        push!(nb, nbFrame3, "Flowsheet")

        ############################################################################
        # Tab 4
        ############################################################################
        nbFrame4 = Frame()
        screen = Gtk.GAccessor.style_context(nbFrame4)
        push!(screen, StyleProvider(provider), 600)

        vbox4 = Grid()

        push!(nbFrame4, vbox4)
        # push!(nb, nbFrame4, "Thermodynamics")

        ############################################################################
        # Tab 5 - Security
        ############################################################################
        nbFrame5 = Frame()
        screen = Gtk.GAccessor.style_context(nbFrame5)
        push!(screen, StyleProvider(provider), 600)

        vbox5 = Grid()
        set_gtk_property!(vbox5, :column_homogeneous, false)
        set_gtk_property!(vbox5, :row_homogeneous, false)
        set_gtk_property!(vbox5, :column_spacing, 10)
        set_gtk_property!(vbox5, :row_spacing, 10)
        set_gtk_property!(vbox4, :margin_top, 10)
        set_gtk_property!(vbox5, :margin_bottom, 20)
        set_gtk_property!(vbox5, :margin_left, 20)
        set_gtk_property!(vbox5, :margin_right, 20)

        push!(nbFrame5, vbox5)
        push!(nb, nbFrame5, "Security")

        ############################################################################
        # Tab 6 - Results
        ############################################################################
        nbFrame6 = Frame()
        screen = Gtk.GAccessor.style_context(nbFrame6)
        push!(screen, StyleProvider(provider), 600)

        vbox6 = Grid()
        set_gtk_property!(vbox6, :halign, 3)
        set_gtk_property!(vbox6, :valign, 3)

        # newNotebook
        global nbResults = Notebook()
        nbResultsFrameTable = Frame()
        set_gtk_property!(nbResults, :width_request, 1080)
        set_gtk_property!(nbResults, :height_request, 650)

        gridResTable = Grid()
        set_gtk_property!(gridResTable, :column_homogeneous, false)
        set_gtk_property!(gridResTable, :row_homogeneous, false)
        set_gtk_property!(gridResTable, :column_spacing, 50)
        set_gtk_property!(gridResTable, :row_spacing, 20)
        set_gtk_property!(gridResTable, :margin_top, 20)
        set_gtk_property!(gridResTable, :margin_bottom, 20)
        set_gtk_property!(gridResTable, :margin_left, 20)
        set_gtk_property!(gridResTable, :margin_right, 20)
        set_gtk_property!(gridResTable, :halign, 3)
        set_gtk_property!(gridResTable, :valign, 3)

        ##################################################################################
        # TreeView for Tables (nbResults)
        listBlocksREs = ListStore(String, String, String)

        viewBlocksRes = TreeView(TreeModel(listBlocksREs))
        set_gtk_property!(viewBlocksRes, :enable_grid_lines, 3)
        set_gtk_property!(viewBlocksRes, :enable_search, true)

        # Window that allow scroll the TreeView
        scrollBlocksRes = ScrolledWindow(viewBlocksRes)
        set_gtk_property!(scrollBlocksRes, :width_request, 350)
        set_gtk_property!(scrollBlocksRes, :height_request, 250)
        selection3 = Gtk.GAccessor.selection(viewBlocksRes)

        # Column definitions
        cTxtREs1 = CellRendererText()

        cRes1 = TreeViewColumn("ID", cTxtREs1, Dict([("text", 0)]))
        cRes2 = TreeViewColumn("Name", cTxtREs1, Dict([("text", 1)]))
        cRes3 = TreeViewColumn("Type", cTxtREs1, Dict([("text", 2)]))

        # Add column to TreeView
        push!(viewBlocksRes, cRes1, cRes2, cRes3)

        # Frame for viewBlocksRes
        frameBlocksRes = Frame("Table X. Block")
        set_gtk_property!(frameBlocksRes, :label_xalign, 0.50)
        set_gtk_property!(frameBlocksRes, :shadow_type, 0)

        frameViewBlocksRes = Frame()

        push!(frameBlocksRes, frameViewBlocksRes)
        push!(frameViewBlocksRes, scrollBlocksRes)

        ##################################################################################
        # TreeView for Tables (nbResults)
        listStreamsRes = ListStore(String, String, String)

        viewStreamsRes = TreeView(TreeModel(listStreamsRes))
        set_gtk_property!(viewStreamsRes, :enable_grid_lines, 3)
        set_gtk_property!(viewStreamsRes, :enable_search, true)

        # Window that allow scroll the TreeView
        scrollStreamsRes = ScrolledWindow(viewStreamsRes)
        set_gtk_property!(scrollStreamsRes, :width_request, 350)
        set_gtk_property!(scrollStreamsRes, :height_request, 250)
        selection4 = Gtk.GAccessor.selection(viewStreamsRes)

        # Column definitions
        cTxtREs2 = CellRendererText()

        cResStr1 = TreeViewColumn("ID", cTxtREs2, Dict([("text", 0)]))
        cResStr2 = TreeViewColumn("Name", cTxtREs2, Dict([("text", 1)]))
        cResStr3 = TreeViewColumn("Type", cTxtREs2, Dict([("text", 2)]))

        # Add column to TreeView
        push!(viewStreamsRes, cResStr1, cResStr2, cResStr3)

        # Frame for viewBlocksRes
        frameStreamsRes = Frame("Table X. Streams")
        set_gtk_property!(frameStreamsRes, :label_xalign, 0.50)
        set_gtk_property!(frameStreamsRes, :shadow_type, 0)

        frameViewStreamsRes = Frame()

        push!(frameStreamsRes, frameViewStreamsRes)
        push!(frameViewStreamsRes, scrollStreamsRes)

        ##################################################################################
        # TreeView for Tables (nbResults)
        listResTable = ListStore(String, String, String)

        viewResTable = TreeView(TreeModel(listResTable))
        set_gtk_property!(viewResTable, :enable_grid_lines, 3)
        set_gtk_property!(viewResTable, :enable_search, true)

        # Window that allow scroll the TreeView
        scrollResTable = ScrolledWindow(viewResTable)
        set_gtk_property!(scrollResTable, :width_request, 350)
        set_gtk_property!(scrollResTable, :height_request, 250)
        selection4 = Gtk.GAccessor.selection(viewResTable)

        # Column definitions
        cTxtREs3 = CellRendererText()

        cResTab1 = TreeViewColumn("Temperature", cTxtREs3, Dict([("text", 0)]))
        cResTab2 = TreeViewColumn("Pressure", cTxtREs3, Dict([("text", 1)]))
        cResTab3 = TreeViewColumn("XA Concentration", cTxtREs3, Dict([("text", 2)]))

        # Add column to TreeView
        push!(viewResTable, cResTab1, cResTab2, cResTab3)

        # Frame for viewBlocksRes
        frameResTable = Frame("Table X. Results")
        set_gtk_property!(frameResTable, :label_xalign, 0.50)
        set_gtk_property!(frameResTable, :shadow_type, 0)

        frameViewResTable = Frame()

        push!(frameResTable, frameViewResTable)
        push!(frameViewResTable, scrollResTable)

        ############
        gridResTable[1, 1] = frameBlocksRes
        gridResTable[1, 2] = frameStreamsRes
        gridResTable[2, 1:2] = frameResTable

        push!(nbResultsFrameTable, gridResTable)
        push!(nbResults, nbResultsFrameTable, "Tables")

        nbResultsFramePlots = Frame()
        push!(nbResults, nbResultsFramePlots, "Graphs")

        vbox6[1, 1] = nbResults

        push!(nbFrame6, vbox6)
        push!(nb, nbFrame6, "Results")

        ############################################################################
        # Tab 7
        ############################################################################
        nbFrame7 = Frame()
        screen = Gtk.GAccessor.style_context(nbFrame7)
        push!(screen, StyleProvider(provider), 600)

        vbox7 = Grid()
        set_gtk_property!(vbox7, :column_homogeneous, false)
        set_gtk_property!(vbox7, :row_homogeneous, false)
        set_gtk_property!(vbox7, :column_spacing, 10)
        set_gtk_property!(vbox7, :row_spacing, 10)
        set_gtk_property!(vbox7, :margin_top, 10)
        set_gtk_property!(vbox7, :margin_bottom, 10)
        set_gtk_property!(vbox7, :margin_left, 20)
        set_gtk_property!(vbox7, :margin_right, 20)
        set_gtk_property!(vbox7, :halign, 3)

        labLogging = Label("Data Logging")
        frameLogging = Frame()
        set_gtk_property!(frameLogging, :name, "frameLogging")
        screen = Gtk.GAccessor.style_context(frameLogging)
        push!(screen, StyleProvider(provider), 600)

        scrollLogging = ScrolledWindow()
        set_gtk_property!(scrollLogging, :width_request, 1000)
        set_gtk_property!(scrollLogging, :height_request, 540)
        screen = Gtk.GAccessor.style_context(scrollLogging)
        push!(screen, StyleProvider(provider), 600)

        push!(frameLogging, scrollLogging)

        # Buttons for logging
        saveLog = ToolButton("gtk-floppy")
        remLog = ToolButton("gtk-clear")
        printLog = ToolButton("gtk-print")

        vbox7[12, 1] = labLogging
        vbox7[1:20, 2] = frameLogging
        vbox7[18, 3] = remLog
        vbox7[19, 3] = printLog
        vbox7[20, 3] = saveLog

        push!(nbFrame7, vbox7)
        push!(nb, nbFrame7, "Data Logging")

        gridToolbar[1, 2] = nb
        push!(newWin, gridToolbar)

        ############################################################################
        # Buttons for newWin
        ############################################################################
        newGButtons = Grid()
        set_gtk_property!(newGButtons, :column_homogeneous, false)
        set_gtk_property!(newGButtons, :width_request, 1160)
        set_gtk_property!(newGButtons, :height_request, 20)
        set_gtk_property!(newGButtons, :column_spacing, 20)
        set_gtk_property!(newGButtons, :margin_top, 20)
        set_gtk_property!(newGButtons, :margin_bottom, 20)
        set_gtk_property!(newGButtons, :margin_left, 20)
        set_gtk_property!(newGButtons, :margin_right, 20)
        set_gtk_property!(newGButtons, :valign, 3)

        # Buttons for newGButtons
        newGEmpty = Grid()
        set_gtk_property!(newGEmpty, :width_request, 680)
        set_gtk_property!(newGEmpty, :valign, 3)

        newLabel = Label("Designed at Instituto Tecnológico de Celaya - 2020
        Support granted by the Conacyt-Secretaría de Energía-Hidrocarburos sectorial fund")
        Gtk.GAccessor.justify(newLabel, Gtk.GConstants.GtkJustification.CENTER)
        screen = Gtk.GAccessor.style_context(newLabel)
        push!(screen, StyleProvider(provider), 600)
        newGEmpty[1, 1] = newLabel

        # Close newWin
        newGClose = Button("Close")
        set_gtk_property!(newGClose, :name, "newGClose")
        set_gtk_property!(newGClose, :width_request, 100)
        set_gtk_property!(newGClose, :height_request, 32)
        screen = Gtk.GAccessor.style_context(newGClose)
        push!(screen, StyleProvider(provider), 600)

        signal_connect(newWin, "key-press-event") do widget, event
            if event.keyval == 65307
                destroy(newWin)
                set_gtk_property!(mainWin, :visible, true)
            end
        end

        # Close keyboard Esc
        signal_connect(newGClose, :clicked) do widget
            destroy(newWin)
            set_gtk_property!(mainWin, :visible, true)
        end

        # Exit newWin
        newGExit = Button("Exit")
        set_gtk_property!(newGExit, :name, "newGExit")
        set_gtk_property!(newGExit, :width_request, 100)
        set_gtk_property!(newGExit, :height_request, 32)
        screen = Gtk.GAccessor.style_context(newGExit)
        push!(screen, StyleProvider(provider), 600)

            # Exit for newWin
        signal_connect(newGExit, :clicked) do widget
            destroy(newWin)
            destroy(mainWin)
        end

            # Back for newWin
        newGBack = Button("Back")
        set_gtk_property!(newGBack, :name, "newGBack")
        set_gtk_property!(newGBack, :width_request, 100)
        set_gtk_property!(newGBack, :height_request, 32)
        signal_connect(newGBack, :clicked) do widget
            global nb
            idTab = get_gtk_property(nb, :page, Int)

            if idTab !== 0
                global idTab = idTab - 1
                set_gtk_property!(nb, :page, idTab)
                set_gtk_property!(newGNext, :sensitive, false)
            end

            if idTab == 0
                set_gtk_property!(newGBack, :sensitive, false)
            end
        end

        screen = Gtk.GAccessor.style_context(newGBack)
        push!(screen, StyleProvider(provider), 600)

            # Next for newWin
        newGNext = Button("Next")
        set_gtk_property!(newGNext, :name, "newGNext")
        set_gtk_property!(newGNext, :width_request, 100)
        set_gtk_property!(newGNext, :height_request, 32)
        signal_connect(newGNext, :clicked) do widget
            global nb
            idTab = get_gtk_property(nb, :page, Int)

            if idTab !== 3
                global idTab = idTab + 1
                set_gtk_property!(nb, :page, idTab)
                set_gtk_property!(newGBack, :sensitive, true)
            end

            if idTab == 3
                set_gtk_property!(newGNext, :sensitive, false)
            end
        end

        screen = Gtk.GAccessor.style_context(newGNext)
        push!(screen, StyleProvider(provider), 600)

        newGButtons[1, 1] = newGEmpty
        newGButtons[2, 1] = newGBack
        newGButtons[3, 1] = newGNext
        newGButtons[4, 1] = newGClose
        newGButtons[5, 1] = newGExit

        gridToolbar[1, 3] = newGButtons

        Gtk.showall(newWin)
        set_gtk_property!(newWin:visible, true)
    end

    ############################################################################
    # Close mainWin
    ############################################################################
    signal_connect(mainWin, "key-press-event") do widget, event
        if event.keyval == 65307
            destroy(mainWin)
        end
    end

        # Close
    signal_connect(close, :clicked) do widget
        destroy(mainWin)
    end

    # TODO Checar texto y link
    ############################################################################
    # About mainWin
    ############################################################################
    signal_connect(about, :clicked) do widget
        aboutWin = Window()
        set_gtk_property!(aboutWin, :title, "About")
        set_gtk_property!(aboutWin, :window_position, 3)
        set_gtk_property!(aboutWin, :width_request, 100)
        screen = Gtk.GAccessor.style_context(aboutWin)
        push!(screen, StyleProvider(provider), 600)

        aboutGrid = Grid()
        set_gtk_property!(aboutGrid, :column_spacing, 30)
        set_gtk_property!(aboutGrid, :row_spacing, 30)
        set_gtk_property!(aboutGrid, :margin_bottom, 30)
        set_gtk_property!(aboutGrid, :margin_top, 30)
        set_gtk_property!(aboutGrid, :column_homogeneous, false)
        set_gtk_property!(aboutGrid, :row_homogeneous, false)
        set_gtk_property!(aboutGrid, :margin_left, 30)
        set_gtk_property!(aboutGrid, :margin_right, 30)

        closeAbout = Button("Close")
        set_gtk_property!(closeAbout, :name, "closeAbout")
        screen = Gtk.GAccessor.style_context(closeAbout)
        push!(screen, StyleProvider(provider), 600)
        signal_connect(closeAbout, :clicked) do widget
            destroy(aboutWin)
        end

        label1 = Label("Hola")
        Gtk.GAccessor.markup(
            label1,
            """<b>Dr. Kelvyn B. Sánchez Sánchez</b>
<i>Instituto Tecnológico de Celaya</i>\nkelvyn.baruc@gmail.com""",
        )
        Gtk.GAccessor.justify(label1, Gtk.GConstants.GtkJustification.CENTER)
        Gtk.GAccessor.selectable(label1, true)

        label2 = Label("Hola")
        Gtk.GAccessor.markup(
            label2,
            """<b>Dr. Arturo Jimenez Gutierrez</b>
<i>Instituto Tecnológico de Celaya</i>\narturo@iqcelaya.itc.mx""",
        )
        Gtk.GAccessor.justify(label2, Gtk.GConstants.GtkJustification.CENTER)
        Gtk.GAccessor.selectable(label2, true)

        label3 = Label("Hola")
        Gtk.GAccessor.markup(
            label3,
            """Free available at GitHub:
    <a href=\"https://github.com/JuliaChem/SimBioReactor.jl\"
    title=\"Clic to download\">https://github.com/JuliaChem/SimBioReactor.jl</a>""",
        )
        Gtk.GAccessor.justify(label3, Gtk.GConstants.GtkJustification.CENTER)

        aboutGrid[1:3, 1] = label1
        aboutGrid[4:6, 1] = label2
        aboutGrid[2:5, 2] = label3
        aboutGrid[3:4, 3] = closeAbout

        push!(aboutWin, aboutGrid)
        Gtk.showall(aboutWin)
    end

        # Label for main win
    mainlb1 = Label("Designed at Instituto Tecnológico de Celaya - 2020
    Support granted by the Conacyt-Secretaría de Energía-Hidrocarburos sectorial fund")
    Gtk.GAccessor.justify(mainlb1, Gtk.GConstants.GtkJustification.CENTER)
    screen = Gtk.GAccessor.style_context(mainlb1)
    push!(screen, StyleProvider(provider), 600)

    f1 = Frame()
    set_gtk_property!(f1, :margin_bottom, 0)
    set_gtk_property!(f1, :margin_top, 0)
    set_gtk_property!(f1, :margin_left, 0)
    set_gtk_property!(f1, :margin_right, 0)

    img = Gtk.Image(image_path)

    mainGrid[1:2, 1] = img
    mainGrid[1, 2] = new
    mainGrid[2, 2] = open
    mainGrid[1, 3] = tools
    mainGrid[2, 3] = tutorial
    mainGrid[1, 4] = about
    mainGrid[2, 4] = close
    mainGrid[1:2, 5] = mainlb1

    push!(f1, mainGrid)
    push!(mainWin, f1)
    Gtk.showall(mainWin)
    #end
end


text:
using Surrogates
using ForwardDiff
using LinearAlgebra
using Flux
using Flux: @epochs
using Flux.Tracker
using Zygote
#using Zygote: @nograd

#=
#FORWARD
###### 1D ######
lb = 0.0
ub = 10.0
n = 5
x = sample(n,lb,ub,SobolSample())
f = x -> x^2
y = f.(x)

#Radials
my_rad = RadialBasis(x,y,lb,ub,x->norm(x),2)
g = x -> ForwardDiff.derivative(my_rad,x)
g(5.0)

#Kriging
p = 1.5
my_krig = Kriging(x,y,p)
g = x -> ForwardDiff.derivative(my_krig,x)
g(5.0)

#Linear Surrogate
my_linear = LinearSurrogate(x,y,lb,ub)
g = x -> ForwardDiff.derivative(my_linear,x)
g(5.0)

#Inverse distance
p = 1.4
my_inverse = InverseDistanceSurrogate(x,y,p,lb,ub)
g = x -> ForwardDiff.derivative(my_inverse,x)
g(5.0)

#Lobachesky
n = 4
α = 2.4
my_loba = LobacheskySurrogate(x,y,α,n,lb,ub)
g = x -> ForwardDiff.derivative(my_loba,x)
g(5.0)

#Second order polynomial
my_second = SecondOrderPolynomialSurrogate(x,y,lb,ub)
g = x -> ForwardDiff.derivative(my_second,x)
g(5.0)

###### ND ######
lb = [0.0,0.0]
ub = [10.0,10.0]
n = 5
x = sample(n,lb,ub,SobolSample())
f = x -> x[1]*x[2]
y = f.(x)

#Radials
my_rad = RadialBasis(x,y,[lb,ub],z->norm(z),2)
g = x -> ForwardDiff.gradient(my_rad,x)
g([2.0,5.0])

#Kriging
theta = [2.0,2.0]
p = [1.9,1.9]
my_krig = Kriging(x,y,p,theta)
g = x -> ForwardDiff.gradient(my_krig,x)
g([2.0,5.0])

#Linear Surrogate
my_linear = LinearSurrogate(x,y,lb,ub)
g = x -> ForwardDiff.gradient(my_linear,x)
g([2.0,5.0])

#Inverse Distance
p = 1.4
my_inverse = InverseDistanceSurrogate(x,y,p,lb,ub)
g = x -> ForwardDiff.gradient(my_inverse,x)
g([2.0,5.0])

#Lobachesky
alpha = [1.4,1.4]
n = 4
my_loba_ND = LobacheskySurrogate(x,y,alpha,n,lb,ub)
g = x -> ForwardDiff.gradient(my_loba_ND,x)
g([2.0,5.0])

#Second order polynomial
my_second = SecondOrderPolynomialSurrogate(x,y,lb,ub)
g = x -> ForwardDiff.gradient(my_second,x)
g([2.0,5.0])

### Tracker ###
#=
#1D
lb = 0.0
ub = 10.0
n = 5
x = sample(n,lb,ub,SobolSample())
f = x -> x^2
y = f.(x)

#Radials
my_rad = RadialBasis(x,y,lb,ub,x->norm(x),2)
g = x -> Tracker.gradient(my_rad,x)
g(5.0)

#Kriging
p = 1.5
my_krig = Kriging(x,y,p)
g = x -> Tracker.gradient(my_krig,x)
g(5.0)

#Linear Surrogate
my_linear = LinearSurrogate(x,y,lb,ub)
g = x -> Tracker.gradient(my_linear,x)
g(5.0)

#Inverse distance
p = 1.4
my_inverse = InverseDistanceSurrogate(x,y,p,lb,ub)
g = x -> Tracker.gradient(my_inverse,x)
g(5.0)

#Lobachesky
n = 4
α = 2.4
my_loba = LobacheskySurrogate(x,y,α,n,lb,ub)
g = x -> Tracker.gradient(my_loba,x)
g(5.0)

#Second order polynomial
my_second = SecondOrderPolynomialSurrogate(x,y,lb,ub)
g = x -> Tracker.gradient(my_second,x)
g(5.0)

#ND
lb = [0.0,0.0]
ub = [10.0,10.0]
n = 100
x = sample(n,lb,ub,SobolSample())
f = x -> x[1]*x[2]^2
y = f.(x)

#Radials
my_rad = RadialBasis(x,y,[lb,ub],z->norm(z),2)
g = x -> Tracker.gradient(my_rad,x)
g([2.0,5.0])

#Kriging
theta = [2.0,2.0]
p = [1.9,1.9]
my_krig = Kriging(x,y,p,theta)
g = x -> Tracker.gradient(my_krig,x)
g([2.0,5.0])

#Linear Surrogate
my_linear = LinearSurrogate(x,y,lb,ub)
g = x -> Tracker.gradient(my_linear,x)
g([2.0,5.0])

#Inverse Distance
p = 1.4
my_inverse = InverseDistanceSurrogate(x,y,p,lb,ub)
g = x -> Tracker.gradient(my_inverse,x)
g([2.0,5.0])

#Lobachesky
alpha = [1.4,1.4]
n = 4
my_loba_ND = LobacheskySurrogate(x,y,alpha,n,lb,ub)
g = x -> Tracker.gradient(my_loba_ND,x)
g([2.0,5.0])

#Second order polynomial
my_second = SecondOrderPolynomialSurrogate(x,y,lb,ub)
g = x -> Tracker.gradient(my_second,x)
g([2.0,5.0])
=#

### ZYGOTE ###
=#
###### 1D ######
lb = 0.0
ub = 10.0
n = 5
x = sample(n,lb,ub,SobolSample())
f = x -> x^2
y = f.(x)

#Radials
my_rad = RadialBasis(x,y,lb,ub,x->norm(x),2)
g = x -> my_rad'(x)
g(5.0)

Zygote.refresh()
#Kriging
p = 1.5
my_krig = Kriging(x,y,p)
g = x -> my_krig'(x)
g(5.0)

Zygote.refresh()
#Linear Surrogate
my_linear = LinearSurrogate(x,y,lb,ub)
g = x -> my_linear'(x)
g(5.0)

Zygote.refresh()
#Inverse distance
p = 1.4
my_inverse = InverseDistanceSurrogate(x,y,p,lb,ub)
g = x -> my_inverse'(x)
g(5.0)

Zygote.refresh()
#Second order polynomial
my_second = SecondOrderPolynomialSurrogate(x,y,lb,ub)
g = x -> my_second'(x)
g(5.0)

Zygote.refresh()
#Lobachesky
n = 4
α = 2.4
my_loba = LobacheskySurrogate(x,y,α,n,lb,ub)
g = x -> my_loba'(x)
g(0.0)

#NN
Zygote.refresh()
model = Chain(Dense(1,1))
loss(x, y) = Flux.mse(model(x), y)
opt = Descent(0.01)
n_echos = 1
my_neural = NeuralSurrogate(x,y,lb,ub,model,loss,opt,n_echos)
g = x->my_neural'(x)
g(3.4)

###### ND ######

lb = [0.0,0.0]
ub = [10.0,10.0]
n = 5
x = sample(n,lb,ub,SobolSample())
f = x -> x[1]*x[2]
y = f.(x)

#Radials
my_rad = RadialBasis(x,y,[lb,ub],z->norm(z),2)
g = x -> Zygote.gradient(my_rad,x)
g((2.0,5.0))

#Kriging
Zygote.refresh()
theta = [2.0,2.0]
p = [1.9,1.9]
my_krig = Kriging(x,y,p,theta)
g = x -> Zygote.gradient(my_krig,x)
g((2.0,5.0))

#Linear Surrogate
Zygote.refresh()
my_linear = LinearSurrogate(x,y,lb,ub)
g = x -> Zygote.gradient(my_linear,x)
g((2.0,5.0))

#Inverse Distance
Zygote.refresh()
p = 1.4
my_inverse = InverseDistanceSurrogate(x,y,p,lb,ub)
g = x -> Zygote.gradient(my_inverse,x)
g((2.0,5.0))

#Lobachesky not working yet weird issue with Zygote @nograd
#=
Zygote.refresh()
alpha = [1.4,1.4]
n = 4
my_loba_ND = LobacheskySurrogate(x,y,alpha,n,lb,ub)
g = x -> Zygote.gradient(my_loba_ND,x)
g((2.0,5.0))
=#

#Second order polynomial mutating arrays
Zygote.refresh()
my_second = SecondOrderPolynomialSurrogate(x,y,lb,ub)
g = x -> Zygote.gradient(my_second,x)
g((2.0,5.0))

#NN
Zygote.refresh()
model = Chain(Dense(2,1))
loss(x, y) = Flux.mse(model(x), y)
opt = Descent(0.01)
n_echos = 1
my_neural = NeuralSurrogate(x,y,lb,ub,model,loss,opt,n_echos)
g = x -> Zygote.gradient(my_neural,x)
g((2.0,5.0))


text:
function generate_IR(str; ctx::LLVM.Context)
    cg = CodeGen(ctx)
    ps = Parser(str)
    while true
        tok = current_token(ps)
        if tok.kind == Kinds.EOF
            break
        else
            r = ParseTopLevelExpr(ps)
            codegen(cg, r)
        end
    end
    LLVM.verify(cg.mod)
    LLVM.dispose(cg.builder)
    return cg.mod
end

function optimize!(mod::LLVM.Module)
    LLVM.ModulePassManager() do pass_manager
        LLVM.instruction_combining!(pass_manager)
        LLVM.reassociate!(pass_manager)
        LLVM.gvn!(pass_manager)
        LLVM.cfgsimplification!(pass_manager)
        LLVM.promote_memory_to_register!(pass_manager)
        LLVM.run!(pass_manager, mod)
    end
    return mod
end

function run(mod::LLVM.Module, entry::String)
    res_jl = 0.0
    LLVM.JIT(mod) do engine
        if !haskey(LLVM.functions(engine), entry)
            error("did not find entry function '$entry' in module")
        end
        f = LLVM.functions(engine)[entry]
        res = LLVM.run(engine, f)
        res_jl = convert(Float64, res, LLVM.DoubleType(LLVM.context(mod)))
        LLVM.dispose(res)
    end
    return res_jl
end

function write_objectfile(mod::LLVM.Module, path::String)
    host_triple = Sys.MACHINE # LLVM.triple() might be wrong (see LLVM.jl#108)
    host_t = LLVM.Target(triple=host_triple)
    LLVM.TargetMachine(host_t, host_triple) do tm
        LLVM.emit(tm, mod, LLVM.API.LLVMObjectFile, path)
    end
end


text:
"""
R ではウェルチの方法による一元元配置分散分析がデフォルトなのであるが，Julia にはないので以下の関数を定義しておく。

関数定義
UnequalVarianceOneWayANOVATestOneWayANOVATest(groups::AbstractVector{<:Real}...)

OneWayANOVATest(groups::AbstractVector{<:Real}...) の場合と同じく，引数として各標本の観測データベクトルを列挙する。
"""

using Statistics, Distributions

function UnequalVarianceOneWayANOVATest(groups::AbstractVector{<:Real}...)
    roundn(x, digits) = round(x, digits=digits)
    formatp(p) = p < 0.00001 ? "< 0.00001" : "= " * string(roundn(p, 5))
    ni = Int[]
    mi = Float64[]
    vi = Float64[]
    for x in groups
        append!(ni, length(x))
        append!(mi, mean(x))
        append!(vi, var(x))
    end
    k = length(ni)
    wi = ni ./ vi
    sum_wi = sum(wi)
    tmp = sum((1 .- wi ./ sum_wi).^2 ./ (ni .- 1)) ./ (k^2 - 1)
    m = sum(wi .* mi) / sum_wi
    df1, df2 = k - 1, 1 / 3tmp
    F = sum(wi .* (mi .- m).^2) / (df1 * (1 + 2 * (k - 2) * tmp))
    p = ccdf(FDist(df1, df2), F)
    println("F = $(roundn(F, 5)),  df1 = $df1,  df2 = $(roundn(df2, 5)),  p-value $(formatp(p)))")
end;

"""
使用例

julia> g1 = [27.7, 45.2, 32.8, 49.5, 31.0, 55.5, 31.7, 53.9];

julia> g2 = [38.0, 47.4, 55.3, 52.5, 39.2, 34.9];

julia> g3 = [44.0, 29.8, 42.5, 23.4, 20.7, 57.3, 42.0, 56.8, 44.1, 32.7];

julia> UnequalVarianceOneWayANOVATest(g1, g2, g3)
F = 0.51339,  df1 = 2,  df2 = 13.589,  p-value = 0.60962)

"""

max_stars_repo_name: r-de-r/stats

max_issues_repo_name: r-de-r/stats

max_forks_repo_name: r-de-r/stats


text:
using GlobalSensitivity, QuasiMonteCarlo, Test

function linear_batch(X)
    A= 7
    B= 0.1
    @. A*X[1,:]+B*X[2,:]
end
function linear(X)
    A= 7
    B= 0.1
    A*X[1]+B*X[2]
end

p_range = [[-1, 1], [-1, 1]]
reg = gsa(linear_batch, RegressionGSA(), p_range; batch = true)

reg = gsa(linear, RegressionGSA(), p_range; batch = false)
reg = gsa(linear, RegressionGSA(true), p_range; batch = false)

f1m(x) = [x[1], -x[1]]
fn1(x) = 7x[1]
fnm(x) = [x[1], -x[2]]

@testset "f: R -> R^m" begin
    reg = gsa(f1m, RegressionGSA(rank = true), p_range; batch = false)
    @test reg.pearson[1, 1] ≈ 1
    @test reg.standard_regression[1, 1] ≈ 1
    @test reg.partial_correlation[1, 1] ≈ -1
    @test reg.pearson_rank[1, 1] ≈ 1
    @test reg.standard_rank_regression[1, 1] ≈ 1
    @test reg.partial_rank_correlation[1, 1] ≈ -1

    # loose tolerances, exact in limit
    @test reg.pearson[1, 2] ≈ -1
    @test reg.standard_regression[1, 2] ≈ -1
    @test reg.partial_correlation[1, 2] ≈ 1
    @test reg.standard_rank_regression[2, 1] ≈ 0 atol=1e-2
end

@testset "f: R^n -> R" begin
    reg = gsa(fn1, RegressionGSA(rank = true), p_range; batch = false)
    @test reg.pearson[1, 1] ≈ 1
    @test reg.standard_regression[1, 1] ≈ 1
    @test reg.partial_correlation[1, 1] ≈ -1
    @test reg.pearson_rank[1, 1] ≈ 1
    @test reg.standard_rank_regression[1, 1] ≈ 1
    @test reg.partial_rank_correlation[1, 1] ≈ -1

    # loose tolerances, exact in limit
    @test reg.pearson[2, 1] ≈ 0 atol=1e-2
    @test reg.standard_regression[2, 1] ≈ 0 atol=1e-2
    @test reg.partial_correlation[2, 1] ≈ 0 atol=1e-2
    @test reg.standard_rank_regression[2, 1] ≈ 0 atol=1e-2
end

@testset "f: R^n -> R^m" begin
    reg = gsa(fnm, RegressionGSA(rank = true), p_range; batch = false)

    @test reg.pearson[2, 2] ≈ -1
    @test reg.standard_regression[2, 2] ≈ -1
    @test reg.partial_correlation[2, 2] ≈ 1

    # loose tolerances, exact in limit
    @test reg.pearson[2, 1] ≈ 0 atol=1e-2
    @test reg.standard_regression[2, 1] ≈ 0 atol=1e-2
    @test reg.partial_correlation[2, 1] ≈ 0 atol=1e-2
    @test reg.pearson[1, 2] ≈ 0 atol=1e-2
    @test reg.standard_regression[1, 2] ≈ 0 atol=1e-2
    @test reg.partial_correlation[1, 2] ≈ 0 atol=1e-2
end


text:
lower(x::Dict{Symbol}) = BSONDict(x)
lower(x::BSONDict) = BSONDict(x)

# Basic Types

ismutable(::Type{Symbol}) = false
lower(x::Symbol) = BSONDict(:tag => "symbol", :name => String(x))
tags[:symbol] = d -> Symbol(d[:name])

lower(x::Tuple) = BSONDict(:tag => "tuple", :data => Any[x...])
tags[:tuple] = d -> (d[:data]...,)

ismutable(::Type{SimpleVector}) = false
lower(x::SimpleVector) = BSONDict(:tag => "svec", :data => Any[x...])
tags[:svec] = d -> Core.svec(d[:data]...)

# References

ref(path::Symbol...) = BSONDict(:tag => "ref", :path => Base.string.([path...]))

resolve(fs, init) = reduce((m, f) -> getfield(m, Symbol(f)), fs; init = init)

tags[:ref] = (d, init) -> resolve(d[:path], init)

function modpath(x::Module)
  y = parentmodule(x)
  x == y ? [nameof(x)] : [modpath(y)..., nameof(x)]
end

ismutable(::Type{Module}) = false
lower(m::Module) = ref(modpath(m)...)

# Types

@static if VERSION < v"1.7.0-DEV"
  # Borrowed from julia base
  function ismutabletype(@nospecialize(t::Type))
      t = Base.unwrap_unionall(t)
      # TODO: what to do for `Union`?
      return isa(t, DataType) && t.mutable
  end
end

ismutable(::Type{<:Type}) = false

typepath(x::DataType) = [modpath(x.name.module)..., x.name.name]

function lower(v::DataType)
  isanon(v) && return lower_anon(v)
  BSONDict(:tag => "datatype",
           :name => Base.string.(typepath(v)),
           :params => [v.parameters...])
end

# For issue #41. Type-params are normally Int32, or Int64 depending on saving system Int
# We should convert them both to loading system Int
normalize_typeparams(x) = x
normalize_typeparams(x::Union{Int32,Int64}) = Int(x)

constructtype(T, Ts) = (length(Ts) == 0) ? T : T{map(normalize_typeparams, Ts)...}
constructtype(T::Type{Tuple}, Ts) = T{map(normalize_typeparams, Ts)...}

tags[:datatype] = (d, init) -> constructtype(resolve(d[:name], init), d[:params])

lower(v::UnionAll) =
  BSONDict(:tag => "unionall",
           :body => v.body,
           :var => v.var)

tags[:unionall] = d -> UnionAll(d[:var], d[:body])

# Arrays

lower(x::Vector{Any}) = copy(x)
lower(x::Vector{UInt8}) = x

reinterpret_(::Type{T}, x) where T =
    T[_x for _x in reinterpret(T, x)]

function lower(x::Array)
  ndims(x) == 1 && !isbitstype(eltype(x)) && return Any[x...]
  BSONDict(:tag => "array", :type => eltype(x), :size => Any[size(x)...],
           :data => isbitstype(eltype(x)) ? reinterpret_(UInt8, reshape(x, :)) : Any[x...])
end

tags[:array] = d ->
  isbitstype(d[:type]) ?
    sizeof(d[:type]) == 0 ?
      fill(d[:type](), d[:size]...) :
      reshape(reinterpret_(d[:type], d[:data]), map(normalize_typeparams, d[:size])...) :
    Array{d[:type]}(reshape(d[:data], d[:size]...))

# Structs

structdata(x) = isprimitivetype(typeof(x)) ? reinterpret_(UInt8, [x]) :
    Any[getfield(x,f) for f in fieldnames(typeof(x)) if isdefined(x, f)]

function lower(x)
  BSONDict(:tag => "struct", :type => typeof(x), :data => structdata(x))
end

initstruct(T) = ccall(:jl_new_struct_uninit, Any, (Any,), T)

function newstruct!(x, fs...)
  for (i, f) = enumerate(fs)
    f = convert(fieldtype(typeof(x),i), f)
    ccall(:jl_set_nth_field, Nothing, (Any, Csize_t, Any), x, i-1, f)
  end
  return x
end

if VERSION < v"1.7-"
function newstruct(T, xs...)
  if !ismutabletype(T)
    flds = Any[convert(fieldtype(T, i), x) for (i,x) in enumerate(xs)]
    return ccall(:jl_new_structv, Any, (Any,Ptr{Cvoid},UInt32), T, flds, length(flds))
  else
    # Manual inline of newstruct! to work around bug
    # https://github.com/MikeInnes/BSON.jl/issues/2#issuecomment-452204339
    x = initstruct(T)

    for (i, f) = enumerate(xs)
      f = convert(fieldtype(typeof(x),i), f)
      ccall(:jl_set_nth_field, Nothing, (Any, Csize_t, Any), x, i-1, f)
    end
    x

  end
end
else
function newstruct(T, xs...)
  if !ismutabletype(T)
    flds = Any[convert(fieldtype(T, i), x) for (i,x) in enumerate(xs)]
    return ccall(:jl_new_structv, Any, (Any,Ptr{Cvoid},UInt32), T, flds, length(flds))
  else
    # Manual inline of newstruct! to work around bug
    # https://github.com/MikeInnes/BSON.jl/issues/2#issuecomment-452204339
    x = initstruct(T)

    for (i, f) = enumerate(xs)
      f = convert(fieldtype(typeof(x),i), f)
      ccall(:jl_set_nth_field, Nothing, (Any, Csize_t, Any), x, i-1, f)
    end
    x

  end
end
end

function newstruct_raw(cache, T, d, init)
  x = cache[d] = initstruct(T)
  fs = map(x -> raise_recursive(x, cache, init), d[:data])
  return newstruct!(x, fs...)
end

newprimitive(T, data) = reinterpret_(T, data)[1]

tags[:struct] = d ->
  isprimitivetype(d[:type]) ?
    newprimitive(d[:type], d[:data]) :
    newstruct(d[:type], d[:data]...)

iscyclic(T) = ismutable(T)

raise[:struct] = function (d, cache, init)
  T = d[:type] = raise_recursive(d[:type], cache, init)
  iscyclic(T) || return _raise_recursive(d, cache, init)
  return newstruct_raw(cache, T, d, init)
end

lower(v::Type{Union{}}) = BSONDict(:tag=>"jl_bottom_type")
tags[:jl_bottom_type] = d -> Union{}

# Base data structures

structdata(d::Union{IdDict,Dict}) = Any[collect(keys(d)), collect(values(d))]

initstruct(D::Type{<:Union{IdDict,Dict}}) = D()

function newstruct!(d::Union{IdDict,Dict}, ks, vs)
  for (k, v) in zip(ks, vs)
    d[k] = v
  end
  return d
end


text:
@testset "runtestTimesTwo" begin
    println("Testing runtestTimesTwo")
    include("../src/bfgaTimesTwo.jl")
    using .bfgaTimesTwo

    include("../src/Bf.jl")
    using .BfInterpreter

    @time model = test_serial()
    #@time model = test_parallel()
    prems = model.population[length(model.population)]
    println("Generation : $(model.params.currentGeneration)")
    println("& fitness : $(model.specific_fitness.fitness(prems, model.instructionsSet))")

    #bfcode :: Array{Float64,1}  = prems.dna
    println("code : $(prems.program) ") #$(join(genesToBfInstructions(bfcode), "") ) ")

    #bft = bfType(bfcode)

    for i in 1:3
        nb1 = rand(0:20)
        input = UInt8[ nb1]
        output, _ = execute(prems.program, input,  model.instructionsSet)
        @test length(output) >= 1
        @test Int(output[1]) == nb1*2
    end

    # do the test_parallel after ...
    #test_parallel()
end


text:
module FooBar

# package code goes here
export hello

function hello()
  print("Hello Julia!!")
end

end # module

max_stars_repo_name: comafire/FooBar

max_issues_repo_name: comafire/FooBar

max_forks_repo_name: comafire/FooBar