text:
if !isfile(joinpath(@__DIR__, "already_showed"))
    printstyled(stderr,
    """
    PkgBenchmark has been completely rewritten. Please see https://github.com/JuliaCI/PkgBenchmark.jl/
    for updated documentation and examples. Code written for previous versions of PkgBenchmark is
    unlikely to still work.
    """; color = Base.info_color())
    touch("already_showed")
end


text:
using Test, JLD2, UnicodePlots
using LinearAlgebra, ForwardDiff, Arpack
using SparseArrays, SparseDiffTools, Symbolics

# load mesh
meshfile = "$(@__DIR__)/data/squaremesh.jld2"
JLD2.@load(meshfile, p, t, jacK, jacM, ps, ts, jacKs, jacMs)
p, t, jacK, jacM =  ps, ts, jacKs, jacMs

np, nt = size(p, 1), size(t, 1)
ε = 1e-6
x, dp = p, 2 * rand(size(p)...) .- 1
xp, xm = p .+ ε * dp, p .- ε * dp
u, v = 2 * rand(np) .- 1, 2 * rand(np) .- 1

# finite differences
f = x -> FemAdjoint.costKproduv(x, t, u, v)
fp, fm = f(xp), f(xm)
g =  FemAdjoint.∇costKproduv(x, t, u, v, jacK = jacK, jacM = jacM)
println("")
println(fp)
println(fm)
println(" ")
println(dot(g, dp))
println((fp - fm) / (2 * ε))
println("")
@testset "test eval gradient dot function for costKproduv" begin
    @test abs(dot(g, dp) - (fp - fm) / (2 * ε)) < 1e-4
end

ext: jl


text:
abstract type ClusterRule end

"""
    StaticCluster(clusters::Vector{Float64})

Buffered cuts are sorting according to the supplied weights `clusters`

"""
struct StaticCluster <: ClusterRule
    clusters::Vector{Float64}

    function StaticCluster(clusters::Vector{Float64})
        sum(clusters) ≈ 1.0 || error("Static cluster")
        return new(clusters)
    end
end

function StaticCluster(frequencies::Vector{Int})
    return StaticCluster(frequencies ./ sum(frequencies))
end

function cluster(rule::StaticCluster, cuts::Vector{<:HyperPlane{OptimalityCut,T}}) where T <: AbstractFloat
    clusters::Vector{AggregatedOptimalityCut} = fill(zero(AggregatedOptimalityCut{T}), rule.clusters)
    i = 1
    for (j,n) in enumerate(round.(Int, rule.clusters * length(cuts)))
        for _ = 1:n
            clusters[j] += cuts[i]
            i += 1
            if i == length(cuts) + 1
                return clusters
            end
        end
    end
    return clusters
end

function str(::StaticCluster)
    return "static clustering"
end

struct ClusterByReference <: ClusterRule
    τ::Float64
    distance::Function
end

"""
    ClusterByReference(τ::AbstractFloat; distance::Function = absolute_distance)

Buffered cuts are aggregated if within the tolerance `τ` to a reference cut, according the supplied `distance` function. Behaves as multi-cut otherwise.

The following distance measures are available
- [`absolute_distance`](@ref)
- [`angular_distance`](@ref)
- [`spatioangular_distance`](@ref

"""
function ClusterByReference(τ::AbstractFloat; distance::Function = absolute_distance)
    return ClusterByReference(τ, distance)
end

function cluster(rule::ClusterByReference, cuts::Vector{<:HyperPlane{OptimalityCut,T}}) where T <: AbstractFloat
    clusters::Vector{AggregatedOptimalityCut} = fill(zero(AggregatedOptimalityCut{T}), length(cuts)+1)
    reference = zero(AggregatedOptimalityCut{T})
    for cut in cuts
        reference += cut
    end
    j = 2
    for cut in cuts
        if rule.distance(cut, reference) <= rule.τ
            # Cluster if distance to reference within tolerance
            clusters[1] += cut
        else
            # Multicut otherwise
            clusters[j] += cut
            j += 1
        end
    end
    return filter(c -> !iszero(c), clusters)
end

function str(::ClusterByReference)
    return "distance to reference based clustering"
end

"""
    Kmedoids(nclusters::Int; distance::Function = absolute_distance)

Buffered cuts are sorted into `nclusters` clusters, using a K-medoids algorithm over a generalized `distance` matrix.

The following distance measures are available
- [`absolute_distance`](@ref)
- [`angular_distance`](@ref)
- [`spatioangular_distance`](@ref

"""
struct Kmedoids <: ClusterRule
    nclusters::Int
    distance::Function
end

function Kmedoids(nclusters::Int; distance::Function = absolute_distance)
    return Kmedoids(nclusters, distance)
end

function cluster(rule::Kmedoids, cuts::Vector{<:HyperPlane{OptimalityCut,T}}) where T <: AbstractFloat
    clusters::Vector{AggregatedOptimalityCut} = fill(zero(AggregatedOptimalityCut{T}), rule.nclusters)
    if length(cuts) < rule.nclusters
        for (i,cut) in enumerate(cuts)
            clusters[i] += cut
        end
    else
        D = [rule.distance(c₁, c₂) for c₁ in cuts, c₂ in cuts]
        try
            kmeds = kmedoids(D, rule.nclusters)
            for (i, j) in enumerate(assignments(kmeds))
                clusters[j] += cuts[i]
            end
        catch
            # Fallback to even clustering
            (ncuts,extra) = divrem(length(cuts), length(clusters))
            extra > 0 && (ncuts += 1)
            i = 1
            for j in eachindex(clusters)
                for _ in 1:ncuts
                    clusters[j] += cuts[i]
                    i += 1
                    i == length(cuts)+1 && return filter(c -> !iszero(c), clusters)
                end
            end
        end
    end
    return filter(c -> !iszero(c), clusters)
end

function str(::Kmedoids)
    return "K-medoids clustering"
end

"""
    Hierarchical(nclusters::Int; distance::Function = absolute_distance, linkage::Symbol = :single)

Buffered cuts are sorted into `nclusters` clusters, using a Hierarchical algorithm, with the given `linkage`, over a generalized `distance` matrix.

The following distance measures are available
- [`absolute_distance`](@ref)
- [`angular_distance`](@ref)
- [`spatioangular_distance`](@ref

"""
struct Hierarchical <: ClusterRule
    nclusters::Int
    distance::Function
    linkage::Symbol
end

function Hierarchical(nclusters::Int; distance::Function = absolute_distance, linkage::Symbol = :single)
    return Hierarchical(nclusters, distance, linkage)
end

function cluster(rule::Hierarchical, cuts::Vector{<:HyperPlane{OptimalityCut,T}}) where T <: AbstractFloat
    clusters::Vector{AggregatedOptimalityCut} = fill(zero(AggregatedOptimalityCut{T}), rule.nclusters)
    D = [rule.distance(c₁, c₂) for c₁ in cuts, c₂ in cuts]
    tree = hclust(D, linkage = rule.linkage)
    for (i, j) in enumerate(Clustering.cutree(tree; k = rule.nclusters))
        clusters[j] += cuts[i]
    end
    return filter(c -> !iszero(c), clusters)
end

function str(::Hierarchical)
    return "hierarchical clustering"
end


text:
"""
    rebuild(x, vals, axs)
"""
rebuild(x, vals, axs) = rebuild(typeof(x), vals, axs)
function rebuild(::Type{T}, vals, axs) where {T<:IndicesArray}
    error("All subtypes of IndicesArray must implement rebuild method.")
end

rebuild(::Type{T}, vals, axs::Tuple{}) where {T<:IArray} = vals
function rebuild(::Type{T}, vals, axs::Tuple)  where {T<:IArray}
    return IArray(vals, axs, AllUnique, LengthChecked)
end

"""
    rebuild_rule(::Type, ::Type)
"""
rebuild_rule(a, b) = rebuild_rule(typeof(a), typeof(b))
rebuild_rule(::Type{A}, ::Type{B}) where {A<:IndicesArray,B<:AbstractArray} = A
rebuild_rule(::Type{A}, ::Type{B}) where {A<:AbstractArray,B<:IndicesArray} = B
rebuild_rule(::Type{A}, ::Type{B}) where {A<:IArray,B<:IArray} = A

function rebuild_rule(::Type{A}, ::Type{B}) where {A<:IndicesArray,B<:IndicesArray}
    T = promote_rule(A, B)
    return T<:Union{} ? promote_rule(B,A) : T
end


text:
# Chapter 2
# https://livebook.manning.com/book/classic-computer-science-problems-in-java/chapter-2/v-4/7

"""
    Nucleotide

Nucleotide
"""
@enum Nucleotide begin
    A = 1
    C = 2
    G = 3
    T = 4
end

function Nucleotide(x::Char)
    if 'A' == x
        return A::Nucleotide
    elseif 'C' == x
        return C::Nucleotide
    elseif 'G' == x
        return G::Nucleotide
    elseif 'T' == x
        return T::Nucleotide
    end

    throw(DomainError("Unknown nucleotide $x"))
end

function Base.convert(::Type{Char}, x::Nucleotide)
    if A == x
        return 'A'
    elseif C == x
        return 'C'
    elseif G == x
        return 'G'
    elseif T == x
        return 'T'
    end

    throw(DomainError("Unknown nucleotide $x"))
end

struct Codon
    nucleotide::Vector{Nucleotide}
end
function Codon(x::String)
    v = Vector{Nucleotide}([
        Nucleotide(x[1]),
        Nucleotide(x[2]),
        Nucleotide(x[3]),
    ])
    Codon(v)
end
Base.:(==)(x::Codon,y::Codon) = x.nucleotide == y.nucleotide
Base.:(<)(x::Codon,y::Codon) = x.nucleotide < y.nucleotide
Base.isless(x::Codon,y::Codon) = isless(x.nucleotide,y.nucleotide)
Base.hash(x::Codon, h::UInt64=UInt64(13)) = hash(x.nucleotide,h)

struct Gene
    codons::Vector{Codon}
end

function Gene(x::String)
    codons = Vector{Codon}()
    for i in 1:3:length(x)
        codon = Codon(x[i:i+2])
        push!(codons, codon)
    end

    return Gene(codons)
end

function linear_contains(gene::Gene, key::Codon)
    for codon in gene.codons
        if key == codon
            return true
        end
    end

    return false
end

function binary_contains(gene::Gene, key::Codon)
    codons = sort(gene.codons)
    low = 1
    high = length(codons)

    while low <= high
        middle = div(low+high, 2) #(low+high) ÷ 2 # integer divide

        if codons[middle] < key
            low = middle + 1
        elseif codons[middle] > key
            high = middle -1
        else # codons[middle] == key
            return true
        end
    end

    return false
end


text:
using JuMP, EAGO

                     m = Model()

                     EAGO.register_eago_operators!(m)

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

                     @variable(m, -53.467800048111016 <= q <= 50.665869089598125)

                     add_NL_constraint(m, :(log(1 + exp(-0.14052056007525238 + -0.5593120910347902*log(1 + exp(0.7927050633346799 + -0.9855209344073468*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8618242155643285*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.1409847014129051*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8981625305472791*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + -0.17714759684008552*log(1 + exp(-0.6180581651393844 + 0.5051816616434088*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.300474118407668*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.9746449193496836*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.5011252416621814*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + -0.8034040228386923*log(1 + exp(0.8979118028491286 + 0.6794924903988093*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.8327554381235851*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.9067656866208256*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.9508098734081298*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + 0.8830918026414509*log(1 + exp(-0.664219788116319 + -0.6624649067900212*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.3925221054786987*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8696160844053109*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.357347274050821*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))))) + log(1 + exp(-0.9657657813458713 + 0.6555921464493895*log(1 + exp(0.7927050633346799 + -0.9855209344073468*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8618242155643285*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.1409847014129051*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8981625305472791*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + -0.8721739939427047*log(1 + exp(-0.6180581651393844 + 0.5051816616434088*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.300474118407668*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.9746449193496836*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.5011252416621814*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + 0.2771767659228326*log(1 + exp(0.8979118028491286 + 0.6794924903988093*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.8327554381235851*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.9067656866208256*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.9508098734081298*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + -0.3272615516465871*log(1 + exp(-0.664219788116319 + -0.6624649067900212*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.3925221054786987*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8696160844053109*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.357347274050821*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))))) + log(1 + exp(0.1449115541174284 + 0.09677925519094499*log(1 + exp(0.7927050633346799 + -0.9855209344073468*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8618242155643285*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.1409847014129051*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8981625305472791*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + -0.7242562051573604*log(1 + exp(-0.6180581651393844 + 0.5051816616434088*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.300474118407668*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.9746449193496836*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.5011252416621814*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + -0.5148279577072672*log(1 + exp(0.8979118028491286 + 0.6794924903988093*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.8327554381235851*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.9067656866208256*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.9508098734081298*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + 0.31101299363436574*log(1 + exp(-0.664219788116319 + -0.6624649067900212*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.3925221054786987*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8696160844053109*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.357347274050821*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))))) + log(1 + exp(-0.29157998590300416 + 0.37951557973783334*log(1 + exp(0.7927050633346799 + -0.9855209344073468*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8618242155643285*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.1409847014129051*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8981625305472791*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + 0.5044820689237324*log(1 + exp(-0.6180581651393844 + 0.5051816616434088*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.300474118407668*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.9746449193496836*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.5011252416621814*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + 0.4692646156920386*log(1 + exp(0.8979118028491286 + 0.6794924903988093*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.8327554381235851*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.9067656866208256*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.9508098734081298*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))) + -0.6236220471665241*log(1 + exp(-0.664219788116319 + -0.6624649067900212*log(1 + exp(-0.5279345513587295 + 0.26674570975926315*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.6014540451740125*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.7842020578742437*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.7348995303901047*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + 0.3925221054786987*log(1 + exp(-0.9736042039183683 + -0.3730380073565449*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + -0.6111131700945078*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.6070668283472709*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + 0.602250903818204*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.8696160844053109*log(1 + exp(-0.7008144662498323 + 0.1168473746120049*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.28223204928638745*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.1750913505933096*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.6765062198397387*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))) + -0.357347274050821*log(1 + exp(0.7932740070802415 + 0.6457743599334909*log(1 + exp(-0.7911508587829115 + -0.06506911132939441*$(x[1]) + -0.852429148445272*$(x[2]) + 0.9902340539920638*$(x[3]) + -0.5325045469076417*$(x[4]) + 0.16346424911659252*$(x[5]))) + 0.13450970941280982*log(1 + exp(-0.31894961218704987 + -0.02324224975324851*$(x[1]) + -0.016870940285415248*$(x[2]) + 0.446182370860321*$(x[3]) + -0.9288490609590947*$(x[4]) + 0.29295311736763896*$(x[5]))) + -0.4617332497282156*log(1 + exp(-0.4972259981592049 + -0.8938534018236086*$(x[1]) + 0.008380370033680418*$(x[2]) + -0.18784778862206242*$(x[3]) + 0.20554715210351482*$(x[4]) + 0.7932560928666454*$(x[5]))) + -0.2655397829444155*log(1 + exp(-0.6657792028971241 + -0.5409713712241491*$(x[1]) + 0.49245843557230895*$(x[2]) + 0.7906244992303582*$(x[3]) + 0.4705847767166267*$(x[4]) + -0.3481500575812202*$(x[5]))))))))) - $q <= 0.0))

                     @objective(m, Min, q)

                     return m

max_stars_repo_name: PSORLab/RSActivationFunctions

max_issues_repo_name: PSORLab/RSActivationFunctions

max_forks_repo_name: PSORLab/RSActivationFunctions


text:
include("plot_recipes.jl")
include("interpolate.jl")
include("convert.jl")
include("adapt.jl")


text:
######################################################################
# simulation.jl
# Code for generating simulation traces
#
# t = 0
#  s,o,b,a
# ...
# t = T
#  s,o,b
#
# T is the time length, so vectors will be T+1 length (0:T)
######################################################################

type Simulation
	T::Int
	state_list::Vector{VehicleSet}
	obs_list::Vector{ObsSet}
	belief_list::Vector{Belief}

	function Simulation(m0::SearchDomain, X::VehicleSet, p::Policy, T::Int)
		m = deepcopy(m0)

		# Create the structures:
		state_list = Array(VehicleSet, T+1)
		obs_list = Array(ObsSet, T+1)
		belief_list = Array(Belief, T+1)

		# t = 0
		Z = observe(m, X)
		update_belief!(m, X, Z)
		A = get_action(m, X, p, 1)

		state_list[1] = deepcopy(X)
		obs_list[1] = deepcopy(Z)
		belief_list[1] = copy(m.b)
		for t = 1:T
			transition!(m, X, A)
			Z = observe(m, X)
			update_belief!(m, X, Z)
			A = get_action(m, X, p, t)

			# Log it all...
			state_list[t+1] = deepcopy(X)
			obs_list[t+1] = deepcopy(Z)
			belief_list[t+1] = copy(m.b)
		end
		return new(T, state_list, obs_list, belief_list)
	end
end


text:
# This file is a part of ValueShapes.jl, licensed under the MIT License (MIT).

@static if hasmethod(reshape, Tuple{Distribution{Multivariate,Continuous}, Int, Int})
    _reshape_arraylike_dist(d::Distribution, sz::Integer...) = reshape(d, sz)
else
    _reshape_arraylike_dist(d::Distribution, sz1::Integer, sz2::Integer) = MatrixReshaped(d, sz1, sz2)
end

"""
    ReshapedDist <: Distribution

An multivariate distribution reshaped using a given
[`AbstractValueShape`](@ref).

Constructors:

```julia
    ReshapedDist(dist::MultivariateDistribution, shape::AbstractValueShape)
```

In addition, `MultivariateDistribution`s can be reshaped via

```julia
(shape::AbstractValueShape)(dist::MultivariateDistribution)
```

with the difference that

```julia
(shape::ArrayShape{T,1})(dist::MultivariateDistribution)
```

will return the original `dist` instead of a `ReshapedDist`.
"""
struct ReshapedDist{
    VF <: VariateForm,
    VS <: ValueSupport,
    D <: Distribution{Multivariate,VS},
    S <: AbstractValueShape
} <: Distribution{VF,VS}
    dist::D
    shape::S
end

export ReshapedDist

_variate_form(shape::ScalarShape) = Univariate

@static if isdefined(Distributions, :ArrayLikeVariate)
    _variate_form(shape::ArrayShape{T,N}) where {T,N} = ArrayLikeVariate{N}
else
    _variate_form(shape::ArrayShape{T,1}) where T = Multivariate
    _variate_form(shape::ArrayShape{T,2}) where T = Matrixvariate
end

_variate_form(shape::NamedTupleShape{names}) where names = NamedTupleVariate{names}

_with_zeroconst(shape::AbstractValueShape) = replace_const_shapes(const_zero_shape, shape)

function ReshapedDist(dist::MultivariateDistribution{VS}, shape::AbstractValueShape) where {VS}
    @argcheck totalndof(varshape(dist)) == totalndof(shape)
    VF = _variate_form(shape)
    D = typeof(dist)
    S = typeof(shape)
    ReshapedDist{VF,VS,D,S}(dist, shape)
end

function (shape::ArrayShape{<:Real,1})(dist::MultivariateDistribution) where {T<:Real}
    @argcheck totalndof(varshape(dist)) == totalndof(shape)
    dist
end

(shape::ArrayShape{<:Real})(dist::MultivariateDistribution) = _reshape_arraylike_dist(dist, size(shape)...)

# ToDo: Enable when `reshape(::MultivariateDistribution, ())` becomes fully functional in Distributions:
#(shape::ScalarShape{<:Real})(dist::MultivariateDistribution) = _reshape_arraylike_dist(dist, size(shape)...)

(shape::AbstractValueShape)(dist::MultivariateDistribution) = ReshapedDist(dist, shape)

@inline varshape(rd::ReshapedDist) = rd.shape

@inline unshaped(rd::ReshapedDist) = rd.dist

Random.rand(rng::AbstractRNG, rd::ReshapedDist{Univariate}) = varshape(rd)(rand(rng, unshaped(rd)))

function Distributions._rand!(rng::AbstractRNG, rd::ReshapedDist{Multivariate}, x::AbstractVector{<:Real})
    Distributions._rand!(rng, unshaped(rd), x)
end

@static if isdefined(Distributions, :ArrayLikeVariate)
    function Distributions._rand!(rng::AbstractRNG, rd::ReshapedDist{<:ArrayLikeVariate{N}}, x::AbstractArray{<:Real,N}) where N
        Distributions._rand!(rng, _reshape_arraylike_dist(unshaped(rd), size(rd)...), x)
    end
else
    function Distributions._rand!(rng::AbstractRNG, rd::ReshapedDist{Matrixvariate}, x::AbstractMatrix{<:Real})
        Distributions._rand!(rng, _reshape_arraylike_dist(unshaped(rd), size(rd)...), x)
    end
end

Base.size(rd::ReshapedDist{<:PlainVariate}) = size(varshape(rd))

Base.length(rd::ReshapedDist{<:PlainVariate}) = prod(size(rd))

Statistics.mean(rd::ReshapedDist) = varshape(rd)(mean(unshaped(rd)))

StatsBase.mode(rd::ReshapedDist) = varshape(rd)(mode(unshaped(rd)))

Statistics.var(rd::ReshapedDist) = _with_zeroconst(varshape(rd))(var(unshaped(rd)))

Statistics.cov(rd::ReshapedDist{Multivariate}) = cov(unshaped(rd))

Distributions.pdf(rd::ReshapedDist{Univariate}, x::Real) = pdf(unshaped(rd), unshaped(x))
Distributions._pdf(rd::ReshapedDist{Multivariate}, x::AbstractVector{<:Real}) = pdf(unshaped(rd), x)
Distributions._pdf(rd::ReshapedDist{Matrixvariate}, x::AbstractMatrix{<:Real}) = pdf(_reshape_arraylike_dist(unshaped(rd), size(rd)...), x)

Distributions.logpdf(rd::ReshapedDist{Univariate}, x::Real) = logpdf(unshaped(rd), unshaped(x))
Distributions._logpdf(rd::ReshapedDist{Multivariate}, x::AbstractVector{<:Real}) = logpdf(unshaped(rd), x)
Distributions._logpdf(rd::ReshapedDist{Matrixvariate}, x::AbstractMatrix{<:Real}) = logpdf(_reshape_arraylike_dist(unshaped(rd), size(rd)...), x)

Distributions.insupport(rd::ReshapedDist{Univariate}, x::Real) = insupport(unshaped(rd), unshaped(x))
Distributions.insupport(rd::ReshapedDist{Multivariate}, x::AbstractVector{<:Real}) = insupport(unshaped(rd), x)
Distributions.insupport(rd::ReshapedDist{Matrixvariate}, x::AbstractMatrix{<:Real}) = insupport(_reshape_arraylike_dist(unshaped(rd), size(rd)...), x)


text:
"""
    DifferentialRKHSMethodS1(epsilon, lambda)

Differential loss reproducing kernel Hilbert space (RKHS) method on the circle, adapted from [1], Section III.
The kernel is a von Mises kernel.

### Parameters

- `kappa`:  scale parameter of the von Mises kernel. Large values produce a narrow kernel.
- `lambda`: regularization parameter, Eq. 20 in [1]

### Reference

[1] Radhakrishnan, A. & and Meyn, S. (2018). Feedback particle filter design using a differential-loss reproducing kernel Hilbert space. 2018 Annual American Control Conference (ACC). IEEE. https://doi.org/10.23919/ACC.2018.8431689
"""
struct DifferentialRKHSMethodS1 <: GainEstimationMethod
    kappa::Float64
    lambda::Float64
end

# Helper functions for DifferentialRKHSMethodS1
function DifferentialRKHS_MakeMatricesS1(vec::AbstractVector, kappa::Number)
    # constructs kernel matrices for DifferentialRKHSMethodS1
    L = length(vec)

    mat = zeros(Float64, L, L, 3)

    @inbounds @simd for i in 1:L
                mat[i,i,1] = exp(kappa)
                mat[i,i,3] = kappa * mat[i,i,1]
                @simd for j in i+1:L
                    diff = vec[i] - vec[j]
                    cosd = cos(diff)
                    sind = sin(diff)
                    K    = exp(kappa * cosd)
                    Kx   = -kappa * sind * K
                    Kxy  =  kappa * (cosd - kappa * sind^2) * K
                    mat[i,j,1] = mat[j,i,1] = K
                    mat[i,j,2] = Kx
                    mat[j,i,2] = -Kx
                    mat[i,j,3] = mat[j,i,3] = Kxy
                end
    end

    return view(mat, :, :, 1), view(mat, :, :, 2), view(mat, :, :, 3)
end

import FeedbackParticleFilters.solve!
function solve!(eq::PoissonEquation, method::DifferentialRKHSMethodS1)
    kappa = method.kappa
    N     = no_of_particles(eq)
    lamb  = N * method.lambda

    H = Htilde(eq)

    # Gaussian kernel and partial derivative matrices
    K, Kx, Kxy = DifferentialRKHS_MakeMatricesS1(eq.positions[1,:], kappa)

    # compute M and b
    M, b = DifferentialRKHS_M_and_b!(K, Kx, Kxy, H', lamb) # warning: this function multiplies K, Kx, and Kxy by lamb

    # solve linear system
    beta = M \ b

    # write potential and gain
    eq.potential  .= ( K*view(beta, 1:N, :) - Kx*view(beta, N+1:2*N, :) )' / lamb
    broadcast!(-, eq.potential, eq.potential, Statistics.mean(eq.potential, dims=2))
    eq.gain[1,:,:] = ( -Kx * view(beta, 1:N, :) + Kxy * view(beta, N+1:2*N, :) ) / lamb
end

max_stars_repo_name: simsurace/FeedbackParticleFilters

max_issues_repo_name: simsurace/FeedbackParticleFilters

max_forks_repo_name: simsurace/FeedbackParticleFilters


text:
# File that stores all isotope information
const file_path = String(@__DIR__) * "/iso_info.nc"

# Read in all the variables beforehand
const mols = ncread(file_path, "molecule")
const isos = ncread(file_path, "isotope")
const global_ids = ncread(file_path, "global_id")
const isonames = ncread(file_path, "isoname")
const abundances = ncread(file_path, "abundance")
const weights = ncread(file_path, "mol_weight")
const mol_names = ncread(file_path, "mol_name")

# Check that the value is not an "unfilled" value (using -1 and "" as defaults)
check_exists(value) = (value in (-1, "")) ? error("No matching (mol, iso) pair") : value

# Functions to get molecule/isotope information
mol_globalID(mol, iso) = check_exists(global_ids[mol, iso])
mol_isoname(mol, iso) = check_exists(isonames[mol, iso])
mol_abundance(mol, iso) = check_exists(abundances[mol, iso])
mol_weight(mol, iso) = check_exists(weights[mol, iso])
mol_name(mol, iso) = check_exists(names[mol, iso])

# Get molecule number from names
mol_number(name) = mols[findfirst(x->x==name, mol_names[:,1])]

# Convenience functions to explore available molecule information
show_molecules() = unique(mol_names)
search_molecules(search_str) = filter(x->occursin(search_str, x), unique(mol_names))


text:
using SuiteSparseGraphBLAS

"""
    GraphBLAS_sparse_square_matrix_cvd!(A::GBMatrix{T}) where T

Build a random sparse square matrix using GraphBLAS CVD version.
"""
function GraphBLAS_sparse_square_matrix_cvd!(A::GBMatrix{T}) where T

    nrows = size(A,1)
    ncols = size(A,2)

    # Build A with at most sqrt(N) elements,
    # N being the number of nonzero matrix elements
    ntuples = isqrt(nrows*ncols)

    for k in 1:ntuples

        i = rand(1:nrows)
        j = rand(1:ncols)
        x = rand(T)

        A[i,j] = x
        #SuiteSparseGraphBLAS.GrB_Matrix_setElement(A, x, i, j)
    end

end


text:
#
# This file is a part of MolecularGraph.jl
# Licensed under the MIT License http://opensource.org/licenses/MIT
#

export
    mincyclenodes, mincycleedges, node_cyclemem, edge_cyclemem,
    canonicalcycle

"""
    mincycles(graph::UndirectedGraph) -> Vector{Vector{Int}}

Calculate minimum cycle basis (also known as Smallest Set of Smallest Rings
in the context of molecular graph theory).
"""
@cache function mincycleedges(graph::UndirectedGraph)
    mincycs = Vector{Int}[]
    for biconn in two_edge_connected(graph)
        subg = nodesubgraph(graph, biconn)
        for cyc in mincyclebasis(subg)
            push!(mincycs, cyc)
        end
    end
    return mincycs
end

mincycleedges(view::SubgraphView) = mincycleedges(view.graph)

@cache function mincyclenodes(graph::UndirectedGraph)
    mincycs = Vector{Int}[]
    for cy in mincycleedges(graph)
        cycy = vcat(cy, cy)
        nodes = Int[]
        for i in 1:length(cy)
            a = getedge(graph, cycy[i])
            b = getedge(graph, cycy[i + 1])
            push!(nodes, iterate(intersect(a, b))[1])
        end
        push!(mincycs, nodes)
    end
    return mincycs
end

mincyclenodes(view::SubgraphView) = mincyclenodes(view.graph)

@cache function node_cyclemem(graph::OrderedGraph)
    nodes = [Set{Int}() for n in 1:nodecount(graph)]
    for (i, cyc) in enumerate(mincyclenodes(graph))
        for n in cyc
            push!(nodes[n], i)
        end
    end
    return nodes
end

node_cyclemem(view::SubgraphView) = node_cyclemem(view.graph)

@cache function edge_cyclemem(graph::OrderedGraph)
    edges = [Set{Int}() for n in 1:edgecount(graph)]
    for (i, cyc) in enumerate(mincycleedges(graph))
        for e in cyc
            push!(edges[e], i)
        end
    end
    return edges
end

edge_cyclemem(view::SubgraphView) = edge_cyclemem(view.graph)

function mincyclebasis(graph::UndirectedGraph)
    # de Pina algorithm re-interpreted by Kavitha et al.
    cycles = Vector{Int}[]
    root = pop!(nodeset(graph))
    S = [Set(e) for e in cotree_edges(graph, root)]
    N = length(S)  # N: circuit rank
    for k in 1:N
        minedges = findmincycle(graph, S[k])
        push!(cycles, minedges)
        for i in (k + 1):N
            if length(intersect(S[i], minedges)) % 2 == 1
                S[i] = symdiff(S[i], S[k])
            end
        end
    end
    return cycles
end

function findmincycle(graph, S)
    G = edgesubgraph(graph, setdiff(edgeset(graph), S))
    U = disjointunion(G, G)
    for s in S
        (u, v) = getedge(graph, s)
        u1 = getunionnode(U, 1, u)
        v1 = getunionnode(U, 1, v)
        u2 = getunionnode(U, 2, u)
        v2 = getunionnode(U, 2, v)
        addedge!(U, u1, v2, DisjointUnionEdge(1, s))
        addedge!(U, u2, v1, DisjointUnionEdge(1, s))
    end
    paths = []
    for n in nodeset(graph)
        n1 = getunionnode(U, 1, n)
        n2 = getunionnode(U, 2, n)
        sp = shortestpathedges(U, n1, n2)
        push!(paths, sp)
    end
    minpath = sortstablemin(paths, by=length)
    return [getsourceedge(U, e).sourcekey for e in minpath]
end

function canonicalcycle(nodes::Vector{Int})
    """Align cycle indices to start from lowest index and following one of
    neighbors that have the lower index
    """
    (fst, fstidx) = findmin(nodes)
    succidx = fstidx == lastindex(nodes) ? 1 : fstidx + 1
    succ = nodes[succidx]
    predidx = fstidx == 1 ? lastindex(nodes) : fstidx - 1
    pred = nodes[predidx]
    cp = succ < pred ? copy(nodes) : reverse(copy(nodes))
    while cp[1] != fst
        pushfirst!(cp, pop!(cp))
    end
    return cp
end


text:
using StochasticOptimization
using Base.Test

using ObjectiveFunctions
using Transformations.TestTransforms
using CatViews
using MLDataPattern
# using MLDataUtils

# include("tst_iteration.jl")
# Stop the tests
# error()

using Plots; unicodeplots(show=true,leg=false)

@testset "Rosenbrock-2" begin

    srand(1)
    n = 2
    t = tfunc(rosenbrock, n, rosenbrock_gradient)
    @show t
    # t = rosenbrock_transform(n)
    # obj = objective(t, NoLoss())

    # random starting values
    θ = params(t)
    startvals = 8rand(n)-4
    @show θ startvals

    # build a MetaLearner to use RMSProp w/ fixed learning rate,
    # setting max iterations, a custom convergence check, and a
    # custom iteration callback to collect data to plot
    converged = (m,i) -> totalcost(m) < 1e-6
    maxiter = 50000

    # this problem has no input (we're learning the params only),
    # and we know the minimum is zero, so we forever pull from this
    # fixed (inputs,targets) pair
    # data = zeros(0,1),zeros(1,1)

    # test the choices of ParamUpdaters
    for (T, lr) in [
                    (SGD, 5e-4),
                    (Adagrad, 1e-0),
                    (Adadelta, 1e-3),
                    (Adam, 1e-2),
                    (Adamax, 1e-2),
                    (RMSProp, 1e-3),
                    ]
        @show T,lr
        learner = make_learner(
            GradientLearner(lr, T()),
            # TimeLimit(10),
            # ShowStatus(1000),
            maxiter = maxiter,
            converged = converged
        )

        # learn forever (our maxiter and converge sub-learners will stop us)
        θ[:] = startvals
        learn!(t, learner) #, infinite_obs(data))

        tc = totalcost(t)
        @show tc
        @test 0 < tc < 1e-3
    end

    # rerun while tracking x/y
    x,y = zeros(0),zeros(0)
    learner = make_learner(
        GradientLearner(1e-1, Adamax()),
        maxiter = 50000,
        converged = converged,
        oniter = (m,i) -> begin
            θ = params(m)
            push!(x, θ[1])
            push!(y, θ[2])
            if mod1(i,2000)==1
                println("Iter: $i Loss: $(output_value(m)[1]) θ: $θ")
            end
        end
    )

    # learn forever (our maxiter and converge sub-learners will stop us)
    θ[:] = startvals
    learn!(t, learner)

    tc = totalcost(t)
    @show tc
    @test 0 < tc < 1e-3

    # plot our path to solution
    plot(x,y, ann=[(θ..., text("$θ", :left))])
end

@testset "LinReg" begin
    nin, nout = 10, 1

    # build our objective
    t = Affine(nin,nout)
    l = L2DistLoss()
    p = scaled(L1Penalty(), 1e-8)
    obj = objective(t, l, p)

    # create some fake data... affine transform plus noise
    # note: θ is the "true params"
    τ = 1000
    θ = randn(nout*(nin+1))
    w, b = splitview(θ, ((nout,nin),(nout,)))[1]
    inputs = randn(nin, τ)
    targets = w * inputs + repmat(b, 1, τ) + 0.1randn(nout, τ)

    # add norms to a trace vector
    # normvals = zeros(0)
    tracer = Tracer(Float64, (model,i) -> norm(θ - params(model)))

    # the MetaLearner have a bunch of specialized sub-learners
    learner = make_learner(
        GradientLearner(FixedLR(5e-3), Adamax()),
        ShowStatus(40),
        tracer,
        ConvergedTo(params, θ, tol=0.1, every=20),
        maxiter=5000,
    )

    learn!(obj, learner, RandomBatches(ObsView((inputs, targets)), size=20))

    # some summary output:

    println()
    plot(tracer.storage, title = "‖θₜᵣᵤₑ - θ‖²", xguide="Iteration")

    # scatter predicted output vs ground truth... should be diagonal line
    est_w, est_b = t.params.views
    pred = est_w * inputs + repmat(est_b, 1, τ)
    truth = w * inputs + repmat(b, 1, τ)
    @test maximum(pred - truth) < 5e-1

    println()
    plot(pred', truth', t=:scatter, xguide="Predicted Output", yguide="Actual Output")
end

max_stars_repo_name: JuliaML/StochasticOptimization

max_issues_repo_name: JuliaML/StochasticOptimization

max_forks_repo_name: JuliaML/StochasticOptimization


text:
s = """
a = begin end
"""
@test Lint.guesstype(parse(s), LintContext()) == Void
msgs = lintstr(s)
@test isempty(msgs)


text:
# A Julia translation of the log function of Yeppp:
#  https://bitbucket.org/MDukhan/yeppp/src/b8db687e912bbd7e2a26dd93c348ef2d7a5febdc/library/headers/yepBuiltin.h?at=default#cl-1128

# Available under following terms:
#
#                          Yeppp! library header
#
# This file is part of Yeppp! library and licensed under the New BSD license.
#
# Copyright (C) 2010-2012 Marat Dukhan
# Copyright (C) 2012-2013 Georgia Institute of Technology
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the Georgia Institute of Technology nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

function log_yeppp(x::Float64)
    xu = reinterpret(Uint64,x)
    if xu >= 0x0010_0000_0000_0000
        k = int(xu >> 52) & 0x07ff - 1023
        s = reinterpret(Float64,(xu & 0x000f_ffff_ffff_ffff) | 0x3ff0_0000_0000_0000)
    else
        offset = leading_zeros(xu)-11
        k = -1022 - offset
        s = reinterpret(Float64,((xu << offset) & 0x000f_ffff_ffff_ffff)
                        | 0x3ff0_0000_0000_0000)
    end
    if s >= 0x1.6A09E667F3BCDp+0 # sqrt(2)
        k += 1
        s *= 0.5
    end
    fk = Float64(k)

    t = s-1.0
    pt = @horner(t,
            -0x1.FFFFFFFFFFFF2p-2,
            0x1.5555555555103p-2,
            -0x1.00000000013C7p-2,
            0x1.9999999A43E4Fp-3,
            -0x1.55555554A6A2Bp-3,
            0x1.249248DAE4B2Ap-3,
            -0x1.FFFFFFBD8606Dp-4,
            0x1.C71C90DB06248p-4,
            -0x1.9999C5BE751E3p-4,
            0x1.745980F3FB889p-4,
            -0x1.554D5ACD502ABp-4,
            0x1.3B4ED39194B87p-4,
            -0x1.25480A82633AFp-4,
            0x1.0F23916A44515p-4,
            -0x1.EED2E2BB64B2Ep-5,
            0x1.EA17E14773369p-5,
            -0x1.1654764F478ECp-4,
            0x1.0266CD08DB2F2p-4,
            -0x1.CC4EC078138E3p-6)

    rf = t*(t*pt)+t
    f = fk*0x1.62E42FEFA3800p-1 + (fk*0x1.EF35793C76730p-45 + rf)
    if xu < 0
        NaN
    elseif xu == 0
        -Inf
    elseif !(x < Inf)
        x
    else
        f
    end
end

@vectorize_1arg Real log_yeppp


text:
module JuliaTranspiler

using ...MonkeyLang

transpile(program::MonkeyLang.Program; input::IO = stdin, output::IO = stdout)::Expr = quote
    # Define wrappers
    __IS_TRUTHY(a) = a != false && a != nothing
    __IS_FALSY(a) = !__IS_TRUTHY(a)

    __WRAPPED_GETINDEX(v::Vector, id::Int) = 0 <= id < length(v) ? v[id+1] : nothing
    __WRAPPED_GETINDEX(d::Dict, key) = get(d, key, nothing)

    __WRAPPED_STRING(a) = Base.string(a)
    __WRAPPED_STRING(::Nothing) = "null"
    __WRAPPED_STRING(s::String) = "\"" * s * "\""
    __WRAPPED_STRING(d::Dict) =
        "{" *
        join(
            map(
                x -> __WRAPPED_STRING(x.first) * ": " * __WRAPPED_STRING(x.second),
                collect(d),
            ),
            ", ",
        ) *
        "}"
    __WRAPPED_STRING(v::Vector) = "[" * join(map(__WRAPPED_STRING, v), ", ") * "]"
    Base.:(+)(a::String, b::String) = a * b

    # Define builtins
    __JULIA_FIRST = Base.first
    __JULIA_LAST = Base.last

    type(args...) = error(
        "argument error: wrong number of arguments. Got $(length(args)) instead of 1",
    )
    type(::String) = "STRING"
    type(::Int) = "INTEGER"
    type(::Bool) = "BOOLEAN"
    type(::Nothing) = "NULL"
    type(::Vector) = "ARRAY"
    type(::Dict) = "HASH"
    type(::Function) = "FUNCTION"

    len(args...) = error(
        "argument error: wrong number of arguments. Got $(length(args)) instead of 1",
    )
    len(arg::Any) =
        error("argument error: argument to `len` is not supported, got $(type(arg))")
    len(s::String) = length(s)
    len(v::Vector) = length(v)
    len(d::Dict) = length(d)

    first(args...) = error(
        "argument error: wrong number of arguments. Got $(length(args)) instead of 1",
    )
    first(arg::Any) =
        error("argument error: argument to `first` is not supported, got $(type(arg))")
    first(s::String) = length(s) >= 1 ? string(__JULIA_FIRST(s)) : nothing
    first(v::Vector) = length(v) >= 1 ? __JULIA_FIRST(v) : nothing

    last(args...) = error(
        "argument error: wrong number of arguments. Got $(length(args)) instead of 1",
    )
    last(arg::Any) =
        error("argument error: argument to `last` is not supported, got $(type(arg))")
    last(s::String) = length(s) >= 1 ? string(__JULIA_LAST(s)) : nothing
    last(v::Vector) = length(v) >= 1 ? __JULIA_LAST(v) : nothing

    rest(args...) = error(
        "argument error: wrong number of arguments. Got $(length(args)) instead of 1",
    )
    rest(arg::Any) =
        error("argument error: argument to `rest` is not supported, got $(type(arg))")
    rest(s::String) = length(s) >= 1 ? s[iterate(s)[2]:end] : nothing
    rest(v::Vector) = length(v) >= 1 ? v[2:end] : nothing

    push(args...) = error(
        "argument error: wrong number of arguments. Got $(length(args)) instead of 2 or 3",
    )
    push(arg::Any, _) =
        error("argument error: argument to `push` is not supported, got $(type(arg))")
    push(v::Vector, ele) = [v..., ele]
    push(arg::Any, _, _) =
        error("argument error: argument to `push` is not supported, got $(type(arg))")
    push(d::Dict, key, val) = Dict(d..., key => val)

    puts(args...) =
        for arg in args
            if isa(arg, String)
                println($output, arg)
            else
                println($output, __WRAPPED_STRING(arg))
            end
        end

    let
        try
            $(map(transpile, program.statements)...)
        catch e
            msg = if isa(e, UndefVarError)
                "identifier not found: $(e.var)"
            elseif isa(e, DivideError)
                "divide error: division by zero"
            elseif isa(e, MethodError)
                if !isa(e.f, Function)
                    "not a function: $(type(e.f))"
                elseif e.f == __WRAPPED_GETINDEX
                    c = e.args[1]
                    k = e.args[2]
                    if isa(c, Vector)
                        "unsupported index type: $(type(k))"
                    else
                        "index operator not supported: $(type(c))"
                    end
                elseif length(e.args) == 1 && e.f ∈ [!, -]
                    "unknown operator: $(e.f)$(type(e.args[1]))"
                elseif length(e.args) == 2 && e.f ∈ [+, -, *, /, (==), !=, <, >]
                    t1 = type(e.args[1])
                    t2 = type(e.args[2])
                    if t1 != t2
                        "type mismatch: $t1 $(e.f) $t2"
                    else
                        "unknown operator: $(type(e.args[1])) $(e.f) $(type(e.args[2]))"
                    end
                else
                    "argument error: wrong number of arguments: got $(length(e.args))"
                end
            else
                hasproperty(e, :msg) ? e.msg : string(e)
            end

            println($output, "ERROR: $msg")
        end
    end
end

transpile(bs::MonkeyLang.BlockStatement)::Expr = quote
    $(map(transpile, bs.statements)...)
end

transpile(::MonkeyLang.BreakStatement)::Expr = Expr(:break)

transpile(::MonkeyLang.ContinueStatement)::Expr = Expr(:continue)

transpile(es::MonkeyLang.ExpressionStatement) = transpile(es.expression)

transpile(ls::MonkeyLang.LetStatement)::Expr = begin
    value = transpile(ls.value)

    if isa(value, Expr) && value.head == :function
        parameters = value.args[1].args
        body = value.args[2]
        Expr(:function, Expr(:call, Symbol(ls.name.value), parameters...), body)
    else
        Expr(:(=), Symbol(ls.name.value), value)
    end
end

transpile(rs::MonkeyLang.ReturnStatement)::Expr = Expr(:return, transpile(rs.return_value))

transpile(ws::MonkeyLang.WhileStatement)::Expr =
    Expr(:while, simplify_condition(ws.condition), transpile(ws.body))

transpile(ie::MonkeyLang.InfixExpression)::Expr = begin
    op = ie.operator == "/" ? "÷" : ie.operator
    Expr(:call, Symbol(op), transpile(ie.left), transpile(ie.right))
end

transpile(pe::MonkeyLang.PrefixExpression)::Expr =
    if pe.operator == "!"
        Expr(:call, :__IS_FALSY, transpile(pe.right))
    else
        Expr(:call, Symbol(pe.operator), transpile(pe.right))
    end

transpile(ident::MonkeyLang.Identifier)::Symbol = Symbol(ident.value)

transpile(::Union{Nothing,MonkeyLang.NullLiteral})::Nothing = nothing

transpile(il::MonkeyLang.IntegerLiteral)::Int = il.value

transpile(bl::MonkeyLang.BooleanLiteral)::Bool = bl.value

transpile(sl::MonkeyLang.StringLiteral)::String = sl.value

transpile(al::MonkeyLang.ArrayLiteral)::Expr = Expr(:vect, map(transpile, al.elements)...)

transpile(hl::MonkeyLang.HashLiteral)::Expr = begin
    pairs = []
    for (k, v) in hl.pairs
        k = transpile(k)
        v = transpile(v)
        push!(pairs, :($k => $v))
    end

    Expr(:call, :Dict, pairs...)
end

transpile(fl::MonkeyLang.FunctionLiteral)::Expr = begin
    params = []
    for p in fl.parameters
        push!(params, Symbol(p.value))
    end

    body = transpile(fl.body)

    Expr(:function, :(($(params...),)), body)
end

transpile(ce::MonkeyLang.CallExpression)::Expr =
    Expr(:call, transpile(ce.fn), map(transpile, ce.arguments)...)

transpile(ce::MonkeyLang.IndexExpression)::Expr =
    Expr(:call, :__WRAPPED_GETINDEX, transpile(ce.left), transpile(ce.index))

transpile(ie::MonkeyLang.IfExpression)::Expr = Expr(
    :if,
    simplify_condition(ie.condition),
    transpile(ie.consequence),
    transpile(ie.alternative),
)

transpile(code::String; input::IO = stdin, output::IO = stdout) = begin
    raw_program = MonkeyLang.parse(code; input, output)
    if !isnothing(raw_program)
        macro_env = MonkeyLang.Environment(; input, output)
        program = MonkeyLang.define_macros!(macro_env, raw_program)
        expanded = MonkeyLang.expand_macros(program, macro_env)

        syntax_check_result = MonkeyLang.analyze(expanded)
        if isa(syntax_check_result, MonkeyLang.ErrorObj)
            println(output, syntax_check_result)
            return nothing
        end

        return transpile(expanded; input, output)
    end
end

simplify_condition(condition) = begin
    condition = transpile(condition)

    if isa(condition, Expr)
        if !(condition.head == :call && condition.args[1] ∈ [:<, :>, :(==), :!=])
            condition = Expr(:call, :__IS_TRUTHY, condition)
        end
    else
        condition = condition != false && !isnothing(condition)
    end

    return condition
end

run(code::String; input::IO = stdin, output::IO = stdout) = begin
    julia_program = transpile(code; input, output)
    if !isnothing(julia_program)
        eval(julia_program)
    end
end

macro monkey_julia_str(code::String)
    quote
        run($(esc(Meta.parse("\"$(escape_string(code))\""))))
    end
end

end