text:
###############################################################################
#
#   AnticTypes.jl : Antic types
#
###############################################################################

###############################################################################
#
#   AnticNumberField / nf_elem
#
###############################################################################

const AnticNumberFieldID = Dict{Tuple{FmpqPolyRing, fmpq_poly, Symbol}, Field}()

mutable struct AnticNumberField <: Field
   pol_coeffs::Ref{Void}
   pol_den::Int
   pol_alloc::Int
   pol_length::Int
   pinv_dinv::Ref{Void}
   pinv_n::Int
   pinv_norm::Int
   powers::Ref{Void}
   powers_len::Int
   traces_coeffs::Ref{Void}
   traces_den::Int
   traces_alloc::Int
   traces_length::Int
   flag::UInt
   pol::fmpq_poly
   S::Symbol
   auxilliary_data::Array{Any, 1}

   function AnticNumberField(pol::fmpq_poly, s::Symbol, cached::Bool = false)
      if !cached
         nf = new()
         nf.pol = pol
         ccall((:nf_init, :libflint), Void,
            (Ref{AnticNumberField}, Ref{fmpq_poly}), nf, pol)
         finalizer(nf, _AnticNumberField_clear_fn)
         nf.S = s
         nf.auxilliary_data = Array{Any}(5)
         return nf
      else
         if haskey(AnticNumberFieldID, (parent(pol), pol, s))
            return AnticNumberFieldID[parent(pol), pol, s]::AnticNumberField
         else
            nf = new()
            nf.pol = pol
            ccall((:nf_init, :libflint), Void,
               (Ref{AnticNumberField}, Ref{fmpq_poly}), nf, pol)
            finalizer(nf, _AnticNumberField_clear_fn)
            nf.S = s
            nf.auxilliary_data = Array{Any}(5)
            if cached
               AnticNumberFieldID[parent(pol), pol, s] = nf
            end
            return nf
         end
      end
   end
end

function _AnticNumberField_clear_fn(a::AnticNumberField)
   ccall((:nf_clear, :libflint), Void, (Ref{AnticNumberField},), a)
end

mutable struct nf_elem <: FieldElem
   elem_coeffs::Ref{Void}
   elem_den::Int
   elem_alloc::Int
   elem_length::Int
   parent::AnticNumberField

   function nf_elem(p::AnticNumberField)
      r = new()
      ccall((:nf_elem_init, :libflint), Void,
            (Ref{nf_elem}, Ref{AnticNumberField}), r, p)
      r.parent = p
      finalizer(r, _nf_elem_clear_fn)
      return r
   end

   function nf_elem(p::AnticNumberField, a::nf_elem)
      r = new()
      ccall((:nf_elem_init, :libflint), Void,
            (Ref{nf_elem}, Ref{AnticNumberField}), r, p)
      ccall((:nf_elem_set, :libflint), Void,
            (Ref{nf_elem}, Ref{nf_elem}, Ref{AnticNumberField}), r, a, p)
      r.parent = p
      finalizer(r, _nf_elem_clear_fn)
      return r
   end
end

function _nf_elem_clear_fn(a::nf_elem)
   ccall((:nf_elem_clear, :libflint), Void,
         (Ref{nf_elem}, Ref{AnticNumberField}), a, a.parent)
end


text:
include("../../neat_test.jl")

const DEFAULT_DATASET_PATH = "../../../../src/datasets"

println("--> Dataset 3")
config = "test_dataset3_config.txt"
#config = ARGS[1]
#generations = parse(Int, ARGS[2])
generations = 5000
st3 = run_NEAT_epochs(config, generations, false)
print_best_solution_perfomance(st3)
#print("* Calculating information plane points")
#calculate_information_plane_points(st3)

plot_neat_fitness(st3, imagename="fitness-dt3.png")
#plot_neat_IP(st3, imagename="IP-dt3.png", nbins=10)
plot_output_distribution(st3, imagename="distribution-dt3.png")
plot_complexity(st3, imagename="solution-complexity-dt3.png")
plot_total_accuracy(st3, imagename="total-accuracy-dt3.png")
plot_output_distribution_test(st3, imagename="output-test-distribution-best-NEAT-dt3.png")

#=
plot_neat_fitness(st3, imagename="fitness-dt3.png")
plot_neat_IP(st3, imagename="IP-dt3.png", nbins=10)
plot_neat_species(st3, imagename="species-dt3.png")
plot_output_distribution(st3, imagename="distribution-dt3.png")
plot_complexity(st3, imagename="solution-complexity-dt3.png")
plot_accuracy(st3, imagename="accuracy-dt3.png")
plot_total_accuracy(st3, imagename="total-accuracy-dt3.png")
plot_output_distribution_test(st3, imagename="output-test-distribution-best-NEAT-dt3.png")
plot_confusion_matrix(st3; imagename="confusion-matrix-testset-dt3.png", set=:test)
=#

# nohup julia neat_test_dt3.jl &> nohup-NEAT-dt3-relatorio.out &

ext: jl

max_stars_repo_name: Lucas-Muniz/MNEAT

max_issues_repo_name: Lucas-Muniz/MNEAT

max_forks_repo_name: Lucas-Muniz/MNEAT


text:
# Scope
function dump(x::Scope)
    @check_ptrs x
    return clang_Scope_dump(x)
end

function getParent(x::Scope)
    @check_ptrs x
    return Scope(clang_Scope_getParent(x))
end

function getDepth(x::Scope)::Int
    @check_ptrs x
    return clang_Scope_getDepth(x)
end


text:
# Intersection of line segments and utilities

@enum Orientation begin
    COUNTERCLOCKWISE = -1
    COLLINEAR        =  0
    CLOCKWISE        =  1
end

"Find orientation of three points in the plane."
function orientation(p::Point, q::Point, r::Point)
    pp, qq, rr = coordinates.([p, q, r])
    lhs = (qq[2] - pp[2])*(rr[1] - qq[1])
    rhs = (rr[2] - qq[2])*(qq[1] - pp[1])
    # check sign of (lhs - rhs)
    if isapprox(lhs, rhs) # zero
        return COLLINEAR
    elseif lhs < rhs      # negative
        return COUNTERCLOCKWISE
    else                  # positive
        return CLOCKWISE
    end
end

"Does q lie on segment [p,q] for collinear p, q and r?"
function collinear_intersect(p::Point, q::Point, r::Point)
    pp, qq, rr = coordinates.([p, q, r])
    x = min(pp[1], rr[1]) <= qq[1] <= max(pp[1], rr[1])
    y = min(pp[2], rr[2]) <= qq[2] <= max(pp[2], rr[2])
    return x && y
end

"Check whether segments [p1 q1] and [p2 q2] intersect."
function intersect_segments(p1::Point, q1::Point, p2::Point, q2::Point)
    # find all orientations of three points
    orient1 = orientation(p1, q1, p2)
    orient2 = orientation(p1, q1, q2)
    orient3 = orientation(p2, q2, p1)
    orient4 = orientation(p2, q2, q1)

    # general case (not parallel)
    if (orient1 != orient2) && (orient3 != orient4)
        return true
    end

    # special cases with collinear points
    if (((orient1 == COLLINEAR) && collinear_intersect(p1, p2, q1)) ||
        ((orient2 == COLLINEAR) && collinear_intersect(p1, q2, q1)) ||
        ((orient3 == COLLINEAR) && collinear_intersect(p2, p1, q2)) ||
        ((orient4 == COLLINEAR) && collinear_intersect(p2, q1, q2)))
        return true
    end

    # none of the above: not intersecting
    return false
end


text:
function F!{T}(byp::BansalYaronProblem, μs::Vector{Float64}, σs::Vector{Float64}, bs::Matrix{Float64}, bs∂μ::Matrix{Float64}, bs∂σ::Matrix{Float64}, bs∂2μ::Matrix{Float64}, bs∂2σ::Matrix{Float64}, y::Vector{T}, ydot::Vector{T})
    μn = length(μs)
    σn = length(σs)
    IJ = μn * σn
    ij = 0
    @inbounds for σi in 1:σn, μi in 1:μn
        ij += 1
        V = zero(T)
        @simd for kl in 1:IJ
            V += bs[kl, ij] * y[kl]
        end
        V∂μ = zero(T)
        @simd for kl in 1:IJ
            V∂μ += bs∂μ[kl, ij] * y[kl]
        end
        V∂σ = zero(T)
        @simd for kl in 1:IJ
            V∂σ += bs∂σ[kl, ij] * y[kl]
        end
        V∂2μ = zero(T)
        @simd for kl in 1:IJ
            V∂2μ += bs∂2μ[kl, ij] * y[kl]
        end
        V∂2σ = zero(T)
        @simd for kl in 1:IJ
            V∂2σ += bs∂2σ[kl, ij] * y[kl]
        end
        if (μi == 1 | μi == μn)
            ydot[ij] = V∂μ
        elseif (σi == 1 | σi == σn)
            ydot[ij] = V∂σ
        else
            ydot[ij] = (byp.ρ * byp.θ * max(zero(T), V^(1-1/byp.θ))
                           + (- byp.ρ * byp.θ + (1-byp.γ) * μs[μi] - 0.5 * (1-byp.γ) * byp.γ * byp.νD^2 * σs[σi]) * V
                           + (byp.κμ * (byp.μ - μs[μi])) * V∂μ
                           + (byp.κσ * (1.0 - σs[σi])) * V∂σ
                           + (0.5 * byp.νμ^2 * σs[σi]) * V∂2μ
                           + (0.5 * byp.νσ^2 * σs[σi]) * V∂2σ
                           )
        end
    end
    return ydot
end

function solve(::Type{Val{:spectral}}, byp::BansalYaronProblem, μs, σs,  bs::Matrix{Float64}, bs∂μ::Matrix{Float64}, bs∂σ::Matrix{Float64}, bs∂2μ::Matrix{Float64}, bs∂2σ::Matrix{Float64}, oldV; kwargs...)
    out = nlsolve((y, ydot) -> F!(byp, μs, σs,  bs, bs∂μ, bs∂σ, bs∂2μ, bs∂2σ, y, ydot), oldV; method = :trust_region, show_trace = true, kwargs...)
    V = bs' * out.zero
    return μs, σs, V
end

function solve(::Type{Val{:spectral}}, byp::BansalYaronProblem; iterations = 50, kwargs...)
    μmin = byp.μ - 6 * byp.νμ / sqrt(2*byp.κμ)
    μmax = byp.μ + 6 * byp.νμ / sqrt(2*byp.κμ)
    σmin = 0.0
    σmax = 3.0
    basisμ = Basis(Cheb, 25, μmin, μmax)
    basisσ = Basis(Cheb, 25, σmin, σmax)
    basis = Basis(basisμ, basisσ)
    S, (μs, σs) = nodes(basis)
    bs = BasisStructure(basis, Expanded(), S, [0 0]').vals[1]'
    bs∂μ = BasisStructure(basis, Expanded(), S, [1 0]').vals[1]'
    bs∂σ = BasisStructure(basis, Expanded(), S, [0 1]').vals[1]'
    bs∂2μ = BasisStructure(basis, Expanded(), S, [2 0]').vals[1]'
    bs∂2σ = BasisStructure(basis, Expanded(), S, [0 2]').vals[1]'
    oldV = bs' \ fill(byp.V, size(bs, 1))
    solve(Val{:spectral}, byp, μs, σs, bs, bs∂μ, bs∂σ, bs∂2μ, bs∂2σ, oldV; iterations = iterations, kwargs...)
end


text:
include("Add.jl")
include("Drop.jl")
include("Describe.jl")
include("Group.jl")
include("Map.jl")
include("Melt.jl")
include("Operate.jl")
include("Order.jl")
include("Rename.jl")
include("Replace.jl")
include("Match.jl")
include("Stack.jl")

export get_axis
export get_col
export get_file
export get_from
export get_input
export get_kind
export get_on
export get_operation
export get_output
export get_to
export get_type
export get_val
export get_var
export set_axis!
export set_col!
export set_file!
export set_from!
export set_input!
export set_kind!
export set_on!
export set_operation!
export set_output!
export set_to!
export set_type!
export set_val!
export set_var!

max_stars_repo_name: matbesancon/SLiDE

max_issues_repo_name: matbesancon/SLiDE

max_forks_repo_name: matbesancon/SLiDE


text:
using StatisticalRethinking

ProjDir = @__DIR__

include("$(ProjDir)/m5.5.jl")

# Is ribbons() an option?

function plotbounds_ribbons(
  df::DataFrame,
  xvar::Symbol,
  yvar::Symbol,
  dfs::DataFrame,
  linkvars::Vector{Symbol};
  fig::AbstractString="",
  bounds::Vector{Symbol}=[:predicted, :hpdi],
  title::AbstractString="",
  xlab::AbstractString=String(xvar),
  ylab::AbstractString=String(yvar),
  alpha::Float64=0.11,
  colors::Vector{Symbol}=[:lightgrey, :grey],
  stepsize::Float64=0.01,
  rescale_axis=true
)

  xbar = mean(df[:, xvar])
  xstd = std(df[:, xvar])
  ybar = mean(df[:, yvar])
  ystd = std(df[:, yvar])

  xvar_s = Symbol(String(xvar)*"_s")
  yvar_s = Symbol(String(yvar)*"_s")

  x_s = minimum(df[:, xvar_s]):stepsize:maximum(df[:, xvar_s])
  y_s = link(dfs, linkvars, x_s);

  if rescale_axis
    x = rescale(x_s, xbar, xstd)
    y = [rescale(y_s[i], ybar, ystd) for i in 1:length(x)]
  else
    x = x_s
    y = y_s
    xbar = 0.0
    xstd = 1.0
    ybar = 0.0
    ystd = 1.0
  end

  mu = [mean(y[i]) for i in 1:length(x)]

  p = plot(xlab=xlab, ylab=ylab, title=title)

  if :predicted in bounds
    p_sim = zeros(length(x), nrow(dfs))
    for i in 1:length(x)
      for j in 1:nrow(dfs)
        p_sim[i, j] =
          ybar .+ rand(Normal(dfs[j, linkvars[1]] + ystd/xstd * dfs[j,
            linkvars[2]] * (x[i] - xbar), ystd*dfs[j, linkvars[3]]))
      end
    end

    pred_hpd = [hpdi(p_sim[i, :], alpha=alpha) for i in 1:length(x)]

    p = plot(xlab=xlab, ylab=ylab, title=title)
    hpdi_array = zeros(length(x), 2);
    for i in 1:length(x)
      hpdi_array[i, :] =  hpdi(p_sim[i, :]) - [mu[i], mu[i]]
    end
    plot!(x, mu; ribbon=(hpdi_array[:, 1], -hpdi_array[:, 2]), alpha=0.4, color=colors[1])
  end

  if :quantile in bounds
    bnds_quantile = [quantile(y[i], [alpha/2, 1-alpha/2]) for i in 1:length(x)]
    for i in 1:length(x)
      plot!([x[i], x[i]], bnds_quantile[i], color=colors[2], leg=false)
    end
  end

  if :hpdi in bounds
    bnds_hpd = [hpdi(y[i], alpha=alpha) for i in 1:length(x)]
    for i in 1:length(x)
      plot!([x[i], x[i]], bnds_hpd[i], color=colors[2], leg=false)
    end
  end

  plot!(x, mu, color=:black)
  if rescale_axis
    scatter!(df[:, xvar], df[:, yvar], leg=false, color=:darkblue)
  else
    scatter!(df[:, xvar_s], df[:, yvar_s], leg=false, color=:darkblue)
  end

  if fig == ""
    return(p)
  else
    savefig(p, fig)
  end
end

xvar = :neocortex_perc
yvar = :kcal_per_g
dfs = dfa5
linkvars = [:a, :bN, :sigma]
fig = "$ProjDir/pba.png"
title = "Kcal_per_g vs. neocortex_perc" * "\nshowing predicted and hpd range"

xlab=String(xvar)
ylab=String(yvar)
alpha=0.11
#colors=[:orangered, :lightgrey]
stepsize=0.01
rescale_axis=true
bounds = [:predicted, :hpdi]

plotbounds_ribbons(
  df, :neocortex_perc, :kcal_per_g,
  dfa5, [:a, :bN, :sigma];
  fig="$ProjDir/pb.png",
  title=title
)


text:
# types ------------------------------------------------------------------------

# type corresponding to a solution
mutable struct tSolution{T}
    x :: Vector{T}                # vector variables x (1..n)
    y :: Vector{T}                # vector outcomes  y (1..p)
end

# type corresponding to a point generator
mutable struct tGenerateur
    sRel :: tSolution{Float64}    # initial relaxed solution
    sInt :: tSolution{Int64}      # integer solution
    sPrj :: tSolution{Float64}    # projected solution
    sFea :: Bool                  # indicate if sInt is feasible or not
end

# type of a point (x,y) in the objective space
mutable struct tPoint
    x :: Float64
    y :: Float64
end

# type grouping the lists of points for dysplaying purposes
mutable struct tListDisplay
    xLf1  :: Vector{Float64};  yLf1  :: Vector{Float64} # liste des points (x,y) relaches
    xLf2  :: Vector{Float64};  yLf2  :: Vector{Float64} # liste des points (x,y) relaches
    xL    :: Vector{Float64};  yL    :: Vector{Float64} # liste des points (x,y) relaches
    XInt  :: Vector{Int64};    YInt  :: Vector{Int64}   # liste des points (x,y) entiers
    XProj :: Vector{Float64};  YProj :: Vector{Float64} # liste des points (x,y) projetes
    XFeas :: Vector{Int64};    YFeas :: Vector{Int64}   # liste des points (x,y) admissibles
    XPert :: Vector{Int64};    YPert :: Vector{Int64}   # liste des points (x,y) perturbes
end

# ==============================================================================
# Initialisation structure donnees contenant tous les generateurs

function allocateDatastructure(nbgen::Int64, nbvar::Int64, nbobj::Int64)

    verbose ? println("\n  → Allocation memoire pour ",nbgen," generateurs\n") : nothing

    vg = Vector{tGenerateur}(undef, nbgen)
    for k = 1:nbgen
        vg[k] = tGenerateur( tSolution{Float64}(zeros(Float64,nbvar),zeros(Float64,nbobj)),
                              tSolution{Int64}(zeros(Int64,nbvar),zeros(Int64,nbobj)),
                              tSolution{Float64}(zeros(Float64,nbvar),zeros(Float64,nbobj)),
                              false
                            )
    end
    return vg
end

max_stars_repo_name: ducanh-le/GravityMachine

max_issues_repo_name: ducanh-le/GravityMachine

max_forks_repo_name: ducanh-le/GravityMachine


text:
N = 10
fooErgmDirBin1
tmpDegsIO = [ Vector(1:N) Vector(1:N)]

Nnodes = N; deltaN = 3
tmpdegs  =   DegSeq2graphDegSeq(fooErgmDirBin1,tmpDegsIO)
tmpMod = ErgmDirBin1(tmpdegs)
out,it,estMod = estimate(tmpMod)

fit,degs = linSpacedFitnesses(fooErgmDirBin1,N)
par,it,estMod = estimate(ErgmDirBin1(degs))
parI = par[:,1];parO = par[:,2];parMat = parI.*parO'
expMat = putZeroDiag(parMat./(1 + parMat));expDeg = [squeeze(sum(expMat,2),2) squeeze(sum(expMat,1),1)]
relErrEst = maximum(abs.( (( expDeg - degs )./degs )[degs.!=0]))

##
sam = sampl(estMod,10)

meanMatSam = squeeze(mean(sam,3),3)
meanDeg = [squeeze(sum(meanMatSam,2),2) squeeze(sum(meanMatSam,1),1)]
relErrSam = maximum(abs.( (( meanDeg - degs )./degs )[degs.!=0]))


text:
"""
    initroot!(toCall::Stack{Function}, ::DFSearch, model::CPModel, variableHeuristic::AbstractVariableSelection, valueSelection::ValueSelection)

Used as a generic function to instantiate the research based on a specific Strategy <: SearchStrategy.

"""
function initroot!(toCall::Stack{Function}, ::DFSearch, model::CPModel, variableHeuristic::AbstractVariableSelection, valueSelection::ValueSelection)
    return expandDfs!(toCall, model, variableHeuristic, valueSelection)
end

"""
    expandDfs!(toCall::Stack{Function}, model::CPModel, variableHeuristic::Function, valueSelection::ValueSelection, newConstraints=nothing)

Add procedures to `toCall`, that, called in the stack order (LIFO) with the `model` parameter, will perform a DFS in the graph.
Some procedures will contain a call to `expandDfs!` itself. Each `expandDfs!` call is wrapped around a `saveState!` and a `restoreState!` to be
able to backtrack thanks to the trailer.
"""
function expandDfs!(toCall::Stack{Function}, model::CPModel, variableHeuristic::AbstractVariableSelection, valueSelection::ValueSelection, newConstraints=nothing; prunedDomains::Union{CPModification,Nothing}=nothing)

    # Dealing with limits
    model.statistics.numberOfNodes += 1
    model.statistics.numberOfNodesBeforeRestart += 1

    if !belowTimeLimit(model)
        return :TimeLimitStop
    end
    if !belowNodeLimit(model)
        return :NodeLimitStop
    end
    if !belowSolutionLimit(model)
        return :SolutionLimitStop
    end

    # Fix-point algorithm
    feasible, pruned = fixPoint!(model, newConstraints, prunedDomains)
    model.statistics.lastPruning=sum(map(x-> length(x[2]),collect(pruned)))

    if !feasible
        model.statistics.numberOfInfeasibleSolutions += 1
        model.statistics.numberOfInfeasibleSolutionsBeforeRestart += 1

        return :Infeasible
    end
    if solutionFound(model)
        triggerFoundSolution!(model)
        return :FoundSolution
    end

    # Variable selection
    x = variableHeuristic(model)
    # Value selection
    v = valueSelection(DecisionPhase, model, x)

    #println("Value : ", v, " assigned to : ", x.id)

    push!(toCall, (model) -> (restoreState!(model.trailer); :BackTracking))
    push!(toCall, (model) -> (
        prunedDomains = CPModification();
        addToPrunedDomains!(prunedDomains, x, remove!(x.domain, v));
        expandDfs!(toCall, model, variableHeuristic, valueSelection, getOnDomainChange(x); prunedDomains=prunedDomains)
    ))
    push!(toCall, (model) -> (saveState!(model.trailer); :SavingState))

    push!(toCall, (model) -> (restoreState!(model.trailer); :BackTracking))
    push!(toCall, (model) -> (
        prunedDomains = CPModification();
        addToPrunedDomains!(prunedDomains, x, assign!(x, v));
        expandDfs!(toCall, model, variableHeuristic, valueSelection, getOnDomainChange(x); prunedDomains=prunedDomains)
    ))
    push!(toCall, (model) -> (saveState!(model.trailer); :SavingState))

    return :Feasible
end


text:
"""
    print_autoconf_hint(state::WizardState)

Print a hint for projets that use autoconf to have a good `./configure` line.
"""
function print_autoconf_hint(state::WizardState)
    println(state.outs, "    The recommended options for GNU Autoconf are:")
    println(state.outs)
    printstyled(state.outs, "      ./configure --prefix=\${prefix} --build=\${MACHTYPE} --host=\${target}", bold=true)
    println(state.outs)
    println(state.outs)
    println(state.outs, "    followed by `make` and `make install`. Since the prefix environment")
    println(state.outs, "    variable is set already, this will automatically perform the installation")
    println(state.outs, "    into the correct directory.")
end

"""
    provide_hints(state::WizardState, path::AbstractString)

Given an unpacked source directory, provide hints on how a user might go about
building the binary bounty they so richly desire.
"""
function provide_hints(state::WizardState, path::AbstractString)
    files = readdir(path)
    println(state.outs, "You have the following contents in your working directory:")
    println(state.outs, join(map(x->string("  - ", x),files),'\n'))
    printed = false
    function start_hints()
        printed || printstyled(state.outs, "Hints:\n", color=:yellow)
        printed = true
    end
    # Avoid providing duplicate hints (even for files in separate directories)
    # As long as the hint is the same, people will get the idea
    hints_provided = Set{Symbol}()
    function already_hinted(sym)
        start_hints()
        (sym in hints_provided) && return true
        push!(hints_provided, sym)
        return false
    end
    for (root, dirs, files) in walkdir(path)
        for file in files
            file_path = joinpath(root, file)

            # Helper function to try to read the given path's contents, but
            # returning an empty string on error (for e.g. broken symlinks)
            read_contents(path) = try
                String(read(path))
            catch
                ""
            end

            if file == "configure" && occursin("Generated by GNU Autoconf", read_contents(file_path))
                already_hinted(:autoconf) && continue
                println(state.outs, "  - ", replace(file_path, "$path/" => ""), "\n")
                println(state.outs, "    This file is a configure file generated by GNU Autoconf. ")
                print_autoconf_hint(state)
            elseif file == "configure.in" || file == "configure.ac"
                already_hinted(:autoconf) && continue
                println(state.outs, "  - ", replace(file_path, "$path/" => ""), "\n")
                println(state.outs, "    This file is likely input to GNU Autoconf. ")
                print_autoconf_hint(state)
            elseif file == "CMakeLists.txt"
                already_hinted(:CMake) && continue
                println(state.outs, "  - ", replace(file_path, "$path/" => ""), "\n")
                print(state.outs,   "    This file is likely input to CMake. ")
                println(state.outs,   "The recommended options for CMake are")
                println(state.outs)
                printstyled(state.outs, "      cmake -DCMAKE_INSTALL_PREFIX=\$prefix -DCMAKE_TOOLCHAIN_FILE=\${CMAKE_TARGET_TOOLCHAIN}", bold=true)
                println(state.outs)
                println(state.outs)
                println(state.outs, "    followed by `make` and `make install`. Since the prefix environment")
                println(state.outs, "    variable is set already, this will automatically perform the installation")
                println(state.outs, "    into the correct directory.\n")
            elseif file == "meson.build"
                already_hinted(:Meson) && continue
                println(state.outs, "  - ", replace(file_path, "$path/" => ""), "\n")
                print(state.outs,   "    This file is likely input to Meson. ")
                println(state.outs,   "The recommended option for Meson is")
                println(state.outs)
                printstyled(state.outs, "      meson --cross-file=\${MESON_TARGET_TOOLCHAIN}", bold=true)
                println(state.outs)
                println(state.outs)
                println(state.outs, "    followed by `ninja` and `ninja install`. Since the prefix variable")
                println(state.outs, "    is set already, this will automatically perform the installation")
                println(state.outs, "    into the correct directory.\n")
            end
        end
    end
    println(state.outs)
end


text:
#!/usr/bin/env julia

using Gtk
using GtkBuilderAid

builder = @GtkBuilderAid userdata(example_app) begin

@guarded function click_ok(
    widget,
    app)
  println("OK clicked!")
  return nothing
end

@guarded function close_window(
    widget,
    window)
  destroy(window)
  return nothing
end

end

@guarded function activateApp(widget, userdata)
  app, builder = userdata
  built = builder("resources/main.ui")
  win = Gtk.GAccessor.object(built, "main_window")
  push!(app, win)
  showall(win)
  return nothing
end

example_app = @GtkApplication("io.github.matt5sean3.GtkBuilderAid.first", 0)
signal_connect(activateApp, example_app, :activate, Void, (), false, (example_app, builder))

println("Starting App")
run(example_app)


text:
abstract type GuessType end

struct MaximizeEntropy <: GuessType end
struct MinimizeExpected <: GuessType end

"""
    GuessScore

A `NamedTuple` for recording a guess and its score, when available.
"""
const GuessScore = NamedTuple{
    (:poolsz, :index, :guess, :expected, :entropy, :score, :sc),
    Tuple{Int,Int,String,Float64,Float64,Union{Missing,String},Union{Missing,Int}},
}

"""
    GamePool{N,S,G}

A struct that defines a Wordle-like game with targets of length `N`.
`S <: Unsigned` is the smallest unsigned integer type that can store values in the
range `0:(3 ^ N - 1)` (obtained as `Wordlegames.scoretype(N)`) and `G <: GuessType`
is the guess type, which defaults to `MaximizeEntropy`.

The fields are:

- `guesspool`: a `Vector{NTuple{N,Char}}` of potential guesses
- `validtargets`: a `BitVector` of valid targets in the `guesspool`
- `allscores`: a cache of pre-computed scores as a `Matrix{S}` of size `(sum(validtargets), length(guesspool))`
- `active`: `BitVector` of length `sum(validtargets)`. The active pool of targets is `guesspool[validtargets][active]`.
- `counts`: `Vector{Int}` of length `3 ^ N` in which bin counts are accumulated
- `guesses`: `Vector{GuessScore}` recording game play
- `hardmode`: `Bool` - should the game be played in "Hard Mode"?

Constructor signatures include

    GamePool(guesspool::Vector{NTuple{N,Char}}, validtargets::BitVector; guesstype=MaximizeEntropy, hardmode::Bool=true) where {N}
    GamePool(guesspool::Vector{NTuple{N,Char}}; guesstype=MaximizeEntropy, hardmode::Bool=true) where {N}
    GamePool(guesspool::AbstractVector{<:AbstractString}; guesstype=MaximizeEntropy, hardmode::Bool=true)
    GamePool(guesspool::AbstractVector; guesstype=MaximizeEntropy, hardmode::Bool=true)
"""
struct GamePool{N,S,G}
    guesspool::Vector{NTuple{N,Char}}
    validtargets::BitVector
    allscores::Matrix{S}
    active::BitVector
    counts::Vector{Int}
    guesses::Vector{GuessScore}
    hardmode::Bool
end

function GamePool(
    guesspool::Vector{NTuple{N,Char}},
    validtargets::BitVector;
    guesstype=MaximizeEntropy,
    hardmode::Bool=true,
) where {N}
    if !(guesstype <: GuessType)
        throw(ArgumentError("guesstype = $guesstype is not `<: GuessType`"))
    end
    if length(validtargets) ≠ length(guesspool)
        throw(ArgumentError("lengths of `guesspool` and `validtargets` must match"))
    end
    ## enhancements - remove any duplicates in guesspool
    S = scoretype(N)
    vtargs = view(guesspool, validtargets)
    allscores = Array{S}(undef, length(vtargs), length(guesspool))
    Threads.@threads for j in axes(allscores, 2)
        scorecolumn!(view(allscores, :, j), guesspool[j], vtargs)
    end
    return updateguess!(
        GamePool{N,S,guesstype}(
            guesspool,
            validtargets,
            allscores,
            trues(length(guesspool)),
            zeros(Int, 3^N),
            sizehint!(GuessScore[], 10),
            hardmode,
        ),
    )
end

function GamePool(
    guesspool::AbstractVector{<:AbstractString},
    validtargets::BitVector;
    guesstype=MaximizeEntropy,
    hardmode::Bool=true,
)
    N = length(first(guesspool))
    if any(≠(N) ∘ length, guesspool)
        throw(ArgumentError("`guesspool` elements must have the same length"))
    end
    return GamePool(NTuple{N,Char}.(guesspool), validtargets; guesstype, hardmode)
end

function GamePool(
    guesspool::AbstractVector,
    validtargets::BitVector;
    guesstype=MaximizeEntropy,
    hardmode::Bool=true,
)
    return GamePool(string.(guesspool), validtargets; guesstype, hardmode)
end

function GamePool(guesspool::AbstractVector; guesstype=MaximizeEntropy, hardmode::Bool=true)
    return GamePool(guesspool, trues(length(guesspool)); guesstype, hardmode)
end

"""
    bincounts!(counts, active, scorevec)
    bincounts!(gp::GamePool, k)

Return `counts` overwritten with bin probabilities from `scorevec[active]` or
update `gp.counts` from `gp.active` and `gp.allscores[:,k]`.
"""
function bincounts!(
    counts::AbstractVector{<:Integer},
    active::BitVector,
    scorevec::AbstractVector{<:Integer},
)
    fill!(counts, 0)
    for (i, a) in enumerate(active)
        if a
            counts[scorevec[i] + 1] += 1
        end
    end
    return counts
end

function bincounts!(gp::GamePool, k)
    bincounts!(gp.counts, gp.active, view(gp.allscores, :, k))
    return gp
end

"""
    entropy2(counts::AbstractVector{<:Real})
    entropy2(gp::GamePool)

Return the base-2 entropy of `counts` or `gp.counts`, converted to probabilities.

The result is the entropy measured in bits.
See the [Wikipedia entry](https://en.wikipedia.org/wiki/Entropy_(information_theory))
for the definition of entropy in information theory.
"""
function entropy2(counts::AbstractVector{<:Real})
    countsum = sum(counts)
    return -sum(counts) do k
        x = k / countsum
        xlogx = x * log(x)
        iszero(x) ? zero(xlogx) : xlogx
    end / log(2)
end

entropy2(gp::GamePool) = entropy2(gp.counts)

"""
    expectedpoolsize(gp::GamePool)

Return the expected pool size from `gp.counts`.
"""
function expectedpoolsize(gp::GamePool)
    return sum(abs2, gp.counts) / sum(gp.counts)
end

function Base.getproperty(gp::GamePool, s::Symbol)
    if s == :summary
        return disallowmissing!(DataFrame(gp.guesses); error=false)
    elseif s == :targetpool
        return gp.guesspool[gp.validtargets]
    elseif s == :activetargets
        return gp.active .& gp.validtargets
    else
        return getfield(gp, s)
    end
end

"""
    optimalguess(gp::GamePool{N,S,G}) where {N,S,G}

Return the optimal guess as a `Tuple{Int,Float64,Float64}` from
`view(gp.guesspool, gp.active)` according to strategy `G`
"""
function optimalguess(gp::GamePool{N,S,MaximizeEntropy}) where {N,S}
    gind, xpctd, entrpy = 0, Inf, -Inf
    for (k, a) in enumerate(gp.active)
        if a
            thisentropy = entropy2(bincounts!(gp, k))
            if thisentropy > entrpy
                gind, xpctd, entrpy = k, expectedpoolsize(gp), thisentropy
            end
        end
    end
    return gind, xpctd, entrpy
end

function optimalguess(gp::GamePool{N,S,MinimizeExpected}) where {N,S}
    gind, xpctd, entrpy = 0, Inf, -Inf
    for (k, a) in enumerate(gp.active)
        if a
            thisexpected = expectedpoolsize(bincounts!(gp, k))
            if thisexpected < xpctd
                gind, xpctd, entrpy = k, thisexpected, entropy2(gp)
            end
        end
    end
    return gind, xpctd, entrpy
end

"""
    playgame!(gp::GamePool, ind::Integer)
    playgame!(gp::GamePool[, rng::AbstractRNG])
    playgame!(gp::GamePool{N}, target::NTuple{N,Char}) where {N}
    playgame!(gp::GamePool{N}, target::AbstractString) where {N}

Return `gp` after playing a game with target `gp.targetpool[ind]`, or a randomly chosen target
or `target` given as an `AbstractString` or `NTuple{N,Char}`.

A `target` as a string must have `length(target) == N`.

See also: [`showgame!`](@ref)
"""
function playgame!(gp::GamePool{N}, ind::Integer) where {N}
    gp.validtargets[ind] || throw(ArgumentError("ind = $ind is not a valid target index"))
    reset!(gp)
    maxscore = (3^N) - 1
    while true     # FIXME: there should be a better way of writing this loop
        sc = score(gp, ind)
        scoreupdate!(gp, sc)
        sc == maxscore && break
    end
    return gp
end

playgame!(gp::GamePool, rng::AbstractRNG) = playgame!(gp, rand(rng, axes(gp.guesspool, 1)))

playgame!(gp::GamePool) = playgame!(gp, Random.GLOBAL_RNG)

function playgame!(gp::GamePool{N}, target::NTuple{N,Char}) where {N}
    targetind = findfirst(==(target), gp.guesspool)
    isnothing(targetind) && throw(ArgumentError("`target` is not in `gp.guesspool`"))
    return playgame!(gp, targetind)
end

function playgame!(gp::GamePool{N}, target::AbstractString) where {N}
    tlen = length(target)
    if length(target) ≠ N
        throw(ArgumentError("`length(target) = $tlen` must be $N for this `GamePool`"))
    end
    return playgame!(gp, NTuple{N,Char}(target))
end

function Base.propertynames(gp::GamePool, private::Bool=false)
    return (fieldnames(typeof(gp))..., :summary, :targetpool, :activetargets)
end

"""
    reset!(gp::GamePool)

Return `gp` with its `active`, `guess`, and `entropy` fields reset to initial values.
"""
function reset!(gp::GamePool)
    (; active, guesses) = gp
    (; poolsz, index, guess, expected, entropy, score, sc) = first(guesses)
    fill!(active, true)   # may need to change this if !all(gp.validtargets)
    push!(
        empty!(guesses),
        (; poolsz, index, guess, expected, entropy, score=missing, sc=missing),
    )
    return gp
end

score(gp::GamePool, targetind::Integer) = gp.allscores[targetind, last(gp.guesses).index]

"""
    scoreupdate!(gp::GamePool, sc::Integer)
    scoreupdate!(gp::GamePool{N}, scv::Vector{<:Integer}) where {N}

Update `gp` with the score `sc`, or a vector `scv` of length `N` whose elements are `0`, `1`, or `2` for `last(gp.guesses)`

Always `push!(gp.scores, sc)`.  If `sc` is the maximum possible score, `3 ^ N - 1`, the game is over and return `gp`.
Otherwise, update `gp.active` and call `updateguess!(gp)`.
"""
function scoreupdate!(gp::GamePool{N}, scr::Integer) where {N}
    (; active, allscores, counts, guesses) = gp
    (; poolsz, index, guess, expected, entropy, score, sc) = last(guesses)
    score = tiles(scr, N)
    sc = Int(scr)
    guesses[length(guesses)] = (; poolsz, index, guess, expected, entropy, score, sc)
    sc == length(counts) - 1 && return gp
    active .&= (view(allscores, :, index) .== sc)
    return updateguess!(gp)
end

function scoreupdate!(gp::GamePool{N}, score::Vector{<:Integer}) where {N}
    sclen = length(score)
    sclen == N || throw(ArgumentError("length(score) = $sclen should be $N"))
    all(∈((0, 1, 2)), score) || throw(ArgumentError("score elements must be in [0, 1, 2]"))
    return scoreupdate!(gp, evalpoly(3, reverse(score)))
end

"""
    showgame!(gp::GamePool[, target])

Return a `Tables.ColumnTable` of `playgame!(gp, target)))`.
"""
function showgame!(gp::GamePool, target)
    return disallowmissing!(DataFrame(playgame!(gp, target).guesses); error=false)
end

showgame!(gp::GamePool) = showgame!(gp, rand(axes(gp.active, 1)))

"""
    updateguess!(gp::GamePool)

Choose the optimal guess the `GuessType` of `gp` and push! a new tuple onto `gp.guesses`.
"""
function updateguess!(gp::GamePool)
    gind, xpctedpoolsize, entropy = optimalguess(gp)
    push!(
        gp.guesses,
        (;
            poolsz=sum(gp.active),
            index=gind,
            guess=string(gp.guesspool[gind]...),
            expected=xpctedpoolsize,
            entropy=entropy,
            score=missing,
            sc=missing,
        ),
    )
    return gp
end


text:
function find_closest_element(arr::Array{Int}, k::UInt, x::Int)
    larger = findfirst(v -> v>=x, arr)
    smaller = larger

    #
    len = lastindex(arr)
    larger isa Nothing && begin
        return arr[(len - k + 1):len]
        end
    smaller == 1 && return arr[1:k]

    #
    smaller -= 1
    count = 0

    while true
        smaller < 1 && return arr[1:k]
        larger > len && return arr[(len - k + 1):len]

        count == k && break

        if x - arr[smaller] <= arr[larger] - x
            smaller -= 1
        else
            larger += 1
        end
        count += 1
    end

    arr[smaller+1:larger-1]
end

max_stars_repo_name: ccqpein/Arithmetic-Exercises

max_issues_repo_name: ccqpein/Arithmetic-Exercises

max_forks_repo_name: ccqpein/Arithmetic-Exercises


text:
function sample_data_and_build_tree!(trnidx::Vector{Int}, validx::Vector{Int}, fitted_values_all_data_this_vector_is_modified_by_build_tree::Vector{Float64}, candMatWOMaxValues::Array{Array{Float64,1},1}, mappings::Array{Array{String,1},1}, settings::ModelSettings, numerator::Array{Float64,1}, denominator::Array{Float64,1}, weight::Array{Float64,1}, features, sampleSizeCanBeNEGATIVE, abssampleSize, sampleVector, T_Uint8_or_UInt16)
# NOTE: this function will call build_tree!()
	# fitted_values_all_data_this_vector_is_modified_by_build_tree=zeros(numerator)
	if abs(settings.subsampling_prop) >= 1.0
		n = build_tree!(trnidx, validx, candMatWOMaxValues, mappings, settings, numerator, denominator, weight, features, fitted_values_all_data_this_vector_is_modified_by_build_tree, T_Uint8_or_UInt16)
		return n
	else
        reused_fitted_leafnr_vector = zeros(Int, length(weight))
		# do subsampling
		# sampleSizeCanBeNEGATIVE=convert(Int,round(settings.subsampling_prop*length(denominator)))
		# note: this can probably be done more efficiently (see also bagging)
		# abssampleSize,sampleVector,num,denom,w,numf,charf,ooBagnum,ooBagdenom,ooBagw,ooBagnumf,ooBagcharf,ooBagsize=initBoostrapSample(sampleSizeCanBeNEGATIVE,numerator,denominator,weight,charfeatures,numfeatures)
		unusedSamplePart = sampleData!(trnidx, sampleSizeCanBeNEGATIVE, sampleVector)
		# build tree	on subsample of data
			thistree = build_tree!(sampleVector, validx, candMatWOMaxValues, mappings, deepcopy(settings), numerator, denominator, weight, features, fitted_values_all_data_this_vector_is_modified_by_build_tree, T_Uint8_or_UInt16)
	# apply tree to ooBagSample
			leaves_of_tree = create_leaves_array(thistree.rootnode)
        apply_tree_by_leaf!(fitted_values_all_data_this_vector_is_modified_by_build_tree, reused_fitted_leafnr_vector, unusedSamplePart, thistree.rootnode, features)
		# Determine Goodness of Fit
			# I think it is best to consider the goodness of fit per leaf here
			# out of bag performance should be measured here, however this is not coded yet (see also bagging!)
				# ooBagEstNumerator=ooBagEstimates.*ooBagdenom
				# fittedPerLeaf=Float64[x.fitted for x in leaves_of_tree]
				# ooBagcntperLeaf,ooBagsumnumeratorEST,ooBagsumnumerator,ooBagsumdenominator,ooBagsumweight=aggregateByLeafNr(leafNrooBag,ooBagEstNumerator,ooBagnum,ooBagdenom,ooBagw)
				# todo tbd check this!
				# thisError=calcErrorStats(fittedPerLeaf,ooBagsumnumerator./ooBagsumdenominator,ooBagsumweight)
				# thisError=goodnessOfFit(ooBagEstimates,ooBagnum,ooBagdenom,ooBagw,meanobservedvalue,ngroupsInput)
		thisError = ErrorStats() # Empty/Default Error Stats .
		return thistree
	end
end

function build_tree!(trnidx::Vector{Int}, validx::Vector{Int}, candMatWOMaxValues::Array{Array{Float64,1},1}, mappings::Array{Array{String,1},1}, settings::ModelSettings, numerator::Array{Float64,1}, denominator::Array{Float64,1}, weight::Array{Float64,1}, features, fitted_values::Vector{Float64}, T_Uint8_or_UInt16)
	intVarsUsed, inds, minweightcalculated = some_tree_settings(trnidx, validx, settings.fixedinds, candMatWOMaxValues, mappings, settings.minWeight, weight, settings.subsampling_features_prop, size(features, 2))
	settings.minWeight = minweightcalculated # update minWeight
	if !(length(inds) > 0)
        throw(ErrorException(string("Error: no features were selected length(inds)=", length(inds))))
    end
    # if (typeof(settings.crit) == mseSplit)||(typeof(settings.crit) == NormalDevianceDifferenceToMeanFitWEIGHTEDSplit)
    #    pointwiseRatio=numerator./denominator
    # else
    #   pointwiseRatio=zeros(length(numerator)) #this vector should not be used in this case (also we want to allow for zero deonominators in certain cases and thus refrain from calcuating the pointwise ratio)
    # end
    pointwiseRatio = Vector{Float64}(undef, length(numerator)) # this should not be used by any of the algorithms, hence it is not computed (it is filled with trash(undefined data))

	empty_xl_data = ExcelData(Array{ExcelSheet}(undef, 0), Array{Chart}(undef, 0))
	fp = get_feature_pools(features)
    thisEmptyNode = T_Uint8_or_UInt16 == UInt8 ? UInt8emptyNode : UInt16emptyNode
	resultingTree = Tree(thisEmptyNode, intVarsUsed, candMatWOMaxValues, mappings, inds, settings, empty_xl_data, fp)
	resultingTree.rootnode = build_tree_iteration!(trnidx, validx, settings, resultingTree, numerator, denominator, pointwiseRatio, weight, features, 0, settings.randomw, Array{Rulepath{T_Uint8_or_UInt16}}(undef, 0), Distributed.myid(), fitted_values, T_Uint8_or_UInt16)
	# set Leaf Numbers
	set_leaf_numbers!(resultingTree)
	return resultingTree
end

function build_tree_iteration!(trnidx::Vector{Int},validx::Vector{Int},settings::ModelSettings,thisTree::Tree,numerator::Array{Float64,1},denominator::Array{Float64,1},pointwiseRatio::Array{Float64,1},weight::Array{Float64,1},features::DataFrame,
									depth::Int,randomweight::Float64,parent_rp::Array{Rulepath{RPType},1},parentid::Int,fitted_values::Vector{Float64},T_Uint8_or_UInt16) where RPType
	# !!!! the current concept foresees that features is always the FULL DataFrame
	boolRandomizeOnlySplitAtTopNode = settings.boolRandomizeOnlySplitAtTopNode
	local inds
	# if fixedinds are provided we never change the selection of features for the whole tree! (bagged boosting model)
	if boolRandomizeOnlySplitAtTopNode || (length(settings.fixedinds) > 0)
		# these settings are randomly chosen by some_tree_settings in this case
		inds = thisTree.inds_considered
	else
		# inds need to be randomly picked for each iteration
		inds = randomFeatureSelection(size(features, 2), settings.subsampling_features_prop)
	end
	intVarsUsed = thisTree.intVarsUsed

	minweight = settings.minWeight
	crit = settings.crit
	spawnsmaller = settings.spawnsmaller
	catSortByThreshold = settings.catSortByThreshold
	catSortBy = settings.catSortBy

	nobs = size(numerator, 1)
	fnames = propertynames(features)
	# @code_warntype _split(settings.number_of_num_features,trnidx,validx,numerator,denominator,pointwiseRatio,weight,fnames,features, minweight, depth,randomweight,crit,parallel_level_threshold,parallel_weight_threshold,inds,catSortByThreshold,catSortBy)
	# T_Uint8_or_UInt16=T_Uint8_or_UInt16 #T_Uint8_or_UInt16=find_max_type(features)::DataType #Union{UInt8,UInt16}
	best_split = _split(one(T_Uint8_or_UInt16), settings.number_of_num_features, trnidx, validx, numerator, denominator, pointwiseRatio, weight, fnames, features, minweight, depth, randomweight, crit, inds, catSortByThreshold, catSortBy)
	id = best_split.featid
	subset = best_split.subset
	fname = best_split.featurename
	id2 = best_split.featid_new_positive

	tmpsn = sum(view(numerator, trnidx))
    tmpsd = sum(view(denominator, trnidx))
    # todo/tbd check if this "sort!(subset)" is necessary and find out why.... is it intended?
	sort!(subset)

	# check if no split was found
  # this can happen (EVEN AT THE TOP NODE) if subsampling (of data and or features) is enabled: it may be that there is in fact no split possible (e.g. if all variables are constant)
  # @show id,nobs,size(trnidx),subset
  # @show sum(view(weight,trnidx))
  # @show sum(view(weight,validx))
    if id == 0
	if (depth == 0)
		@warn("DTM: No split was found at the top node. This is generally not expected.")
	end
		trnsumn = sum(view(numerator, trnidx))
		trnsumd = sum(view(denominator, trnidx))
        mean_observed = trnsumn / trnsumd;this_leaf_size = sum(view(weight, trnidx))
		fitted_increment = mean_observed
        return Leaf(length(trnidx), mean_observed, fitted_increment, this_leaf_size, depth, parent_rp, trnsumn, trnsumd, -1)::Leaf
    end;
# Rulepath
		this_left_rp = deepcopy(parent_rp);
		this_right_rp = deepcopy(parent_rp);
		push!(this_left_rp, Rulepath(id, subset, true));
		push!(this_right_rp, Rulepath(id, subset, false));
		if id < 0 # (id<0 == !isa(features[!,id2].pool[1],Number)) #pool cannot be empty here, thus accessing the first element should be fine alternatively eltype(x)<:Number might be faster..
			# split by character variable
        for u in subset
            intVarsUsed[-id + settings.number_of_num_features][u] += 1
        end
    else
            # split by numeric variable
            # todo check performance of this and improve
        intVarsUsed[id][subset[end]] += 1 # set this value to true to indicate, that is is used by the tree
    end
    l, r = lrIndices(trnidx, features[!,id2], subset)

        # needs review: are these checks meaningful (June18 2020 )
    length(r), length(l), length(trnidx)
    @assert length(l) < length(trnidx)
    @assert length(r) < length(trnidx)

    countl = size(l, 1)
    countr = size(r, 1)
    sumwl = sum(view(weight, l))
    sumwr = sum(view(weight, r))

	leftchildwillbefurthersplit = sumwl < 2 * minweight
	rightchildwillbefurthersplit = sumwr < 2 * minweight
	(sumwr > sumwl) ? boolSpawnLeft = false : boolSpawnLeft = true
    if spawnsmaller;boolSpawnLeft = !boolSpawnLeft;end;

    boolRandomizeOnlySplitAtTopNode ? newrandomweight = copy(randomweight) : newrandomweight = 0.0

    # todo/tbd check the different if/then here, I think a few things are not quite accurate
	# Also, we probably do not need any parallelization for the construction of a single tree-> we should disable this functionality
	trnsumnl = sum(view(numerator, l))
	trnsumdl = sum(view(denominator, l))
	trnsumnr = sum(view(numerator, r))
	trnsumdr = sum(view(denominator, r))
	mean_observedl = trnsumnl / trnsumdl
	mean_observedr = trnsumnr / trnsumdr
	fitted_labelsl = mean_observedl;
	fitted_labelsr = mean_observedr;
	if (max(sumwr, sumwl) < minweight)
					if leftchildwillbefurthersplit
						fill_some_elements!(fitted_values, l, mean_observedl)
							remote_ref_build_tree_leftchild = Leaf(length(l), mean_observedl, fitted_labelsl, sumwl, depth + 1, this_left_rp, trnsumnl, trnsumdl, -1)
        else
            remote_ref_build_tree_leftchild = build_tree_iteration!(l, validx, settings, thisTree, numerator, denominator, pointwiseRatio, weight, features, depth + 1, newrandomweight, this_left_rp, Distributed.myid(), fitted_values, T_Uint8_or_UInt16)
		      end
					if rightchildwillbefurthersplit
						fill_some_elements!(fitted_values, r, mean_observedr)
            remote_ref_build_tree_rightchild = Leaf(length(r), mean_observedr, fitted_labelsr, sumwr, depth + 1, this_right_rp, trnsumnr, trnsumdr, -1)
        else
            remote_ref_build_tree_rightchild = build_tree_iteration!(r, validx, settings, thisTree, numerator, denominator, pointwiseRatio, weight, features, depth + 1, newrandomweight, this_right_rp, Distributed.myid(), fitted_values, T_Uint8_or_UInt16)
        end
    else
       # here we spawn a process for the smaller "child"
        if (!boolSpawnLeft)
        # here it is important that the @spawn is executed before the build_tree_iteration! call!
						if rightchildwillbefurthersplit
							fill_some_elements!(fitted_values, r, mean_observedr)
             	  remote_ref_build_tree_rightchild = Leaf(length(r), mean_observedr, fitted_labelsr, sumwr, depth + 1, this_right_rp, trnsumnr, trnsumdr, -1)
            else
                remote_ref_build_tree_rightchild = Distributed.@spawn build_tree_iteration!(r, validx, settings, thisTree, numerator, denominator, pointwiseRatio, weight, features, depth + 1, newrandomweight, this_right_rp, Distributed.myid(), fitted_values, T_Uint8_or_UInt16)
            end
						if leftchildwillbefurthersplit
							fill_some_elements!(fitted_values, l, mean_observedl)
						  remote_ref_build_tree_leftchild = Leaf(length(l), mean_observedl, fitted_labelsl, sumwl, depth + 1, this_left_rp, trnsumnl, trnsumdl, -1)
            else
                remote_ref_build_tree_leftchild = build_tree_iteration!(l, validx, settings, thisTree, numerator, denominator, pointwiseRatio, weight, features, depth + 1, newrandomweight, this_left_rp, Distributed.myid(), fitted_values, T_Uint8_or_UInt16)
            end
        else
						if leftchildwillbefurthersplit
							fill_some_elements!(fitted_values, l, mean_observedl)
						  remote_ref_build_tree_leftchild = Leaf(length(l), mean_observedl, fitted_labelsl, sumwl, depth + 1, this_left_rp, trnsumnl, trnsumdl, -1)
            else
                remote_ref_build_tree_leftchild = Distributed.@spawn build_tree_iteration!(l, validx, settings, thisTree, numerator, denominator, pointwiseRatio, weight, features, depth + 1, newrandomweight, this_left_rp, Distributed.myid(), fitted_values, T_Uint8_or_UInt16)
            end
						if rightchildwillbefurthersplit
							fill_some_elements!(fitted_values, r, mean_observedr)
                remote_ref_build_tree_rightchild = Leaf(length(r), mean_observedr, fitted_labelsr, sumwr, depth + 1, this_right_rp, trnsumnr, trnsumdr, -1)
            else
                remote_ref_build_tree_rightchild = build_tree_iteration!(r, validx, settings, thisTree, numerator, denominator, pointwiseRatio, weight, features, depth + 1, newrandomweight, this_right_rp, Distributed.myid(), fitted_values, T_Uint8_or_UInt16)
            end
        end
    end

    fetched_left = fetch(remote_ref_build_tree_leftchild)
    fetched_right = fetch(remote_ref_build_tree_rightchild)
  # fitted_values=mergeLeftAndRightFittedValues(fitted_valuesl,fitted_valuesr,left)
	if !((id < 0) || (maximum(subset) == subset[end])) # for numeric variables subset should generally be of the form [1:n], if not this means that the data was split in a way such that several candidates collapsed as there was no more data between to (or more) candidates.
        throw(ErrorException(string("Internal DTM Error. Subset had unexpected layout. You may want to report this as an issue")))
    end
    id2 = id < 0 ? abs(id) + settings.number_of_num_features : id
    return Node(id, id2, subset, fetched_left, fetched_right, parent_rp)::Node
end

function _split(val_of_some_UInt_type::T, number_of_num_features::Int, trnidx::Vector{Int}, validx::Vector{Int}, numerator::Array{Float64,1}, denominator::Array{Float64,1}, pointwiseRatio::Array{Float64,1}, weight::Array{Float64,1}, fnames::Vector{Symbol}, features, minweight::Float64, depth::Int, randomweight::Float64, crit::SplittingCriterion, inds::Array{Int,1}=Array{Int}(undef, 0), catSortByThreshold::Int=8, catSortBy::SortBy=SORTBYMEAN) where T <: Unsigned # ,RT<:Union{Splitdef{UInt16},Splitdef{UInt8}}
	# This function selects the maximal possible split defined by crit (thus depending on the impurity function, we need to put a minus sign in front of it)
		tmpsz::Int = 0
		if sum(view(weight, trnidx)) < 2 * minweight;
        if T == UInt8
            return UInt8emptySplitDef
        else
            return UInt16emptySplitDef
        end
		end
		tmp_splitlist = Vector{Splitdef{T}}(undef, 0)
		for i in inds
			# ATTENTION: for char variables we pass the variable i with a negative sing!!
			# this allows us to distinguish whether we are working on a char or num variable later on
			modified_i = eltype(features[!,i]) <: AbstractString ? number_of_num_features - i  :  i
			tmplist = _split_feature(val_of_some_UInt_type, number_of_num_features, trnidx, validx, numerator, denominator, pointwiseRatio, weight, fnames[i], features[!,i], minweight, crit, modified_i, randomweight, catSortByThreshold, catSortBy)::Vector{Splitdef{T}}
			append!(tmp_splitlist, tmplist)
		end

		# pick best "valid" (minweight feasible) split
		if !(size(tmp_splitlist, 1) > 0)
			if T == UInt8
            return UInt8emptySplitDef
        else
            return UInt16emptySplitDef
        end
		else
				tmp_splitlist = subset_splitlist(tmp_splitlist, minweight)
				if !(size(tmp_splitlist, 1) > 0)
					if T == UInt8
                return UInt8emptySplitDef
            else
                return UInt16emptySplitDef
            end
				else
            splitlist_sorted::Vector{Splitdef{T}} = sort_splitlist(tmp_splitlist)::Vector{Splitdef{T}}
						tmpsz = size(splitlist_sorted, 1)::Int
						if tmpsz > 0 # can it be that splitlist_sorted is empty even though tmp_splitlist was not? I think so!
							# randomize choice
							spl::Splitdef{T} = splitlist_sorted[1]
							if randomweight > 0 # ((depth==0) && (randomweight>0))
								rnd = Int(max(1, min(tmpsz, ceil(rand() * randomweight * tmpsz)))) # I am not sure if it can happen that rnd becomes 0 if we do not impose the max(1,...) condition. But it seems safe to enforce it in case an incredibly small random number is generated
								spl = splitlist_sorted[rnd]::Splitdef{T}
							else # randomweight<=0
								# deterministic choice (greedy)
								spl = splitlist_sorted[1]::Splitdef{T}
							end # "if condition randomweight>0"
							if isfinite(spl.splitvalue) && (spl.featid < 0)
								# For Character variables: The split can be defined by the subset or its complement, We choose to define it via the subset which defines the smaller child node such that when new values arrive (in out of sample testing) they will "go with the larger child node"
								if spl.weightl > spl.weightr
										lvls = unique(view(features[!,spl.featid_new_positive].refs, trnidx))
										spl = Splitdef(spl.featid, spl.featid_new_positive, spl.featurename, convert(Vector{T}, setdiff(lvls, spl.subset)), spl.splitvalue, spl.weightl, spl.weightr)::Splitdef{T}
								end
							end # isfinite(best_value_split) && (best[1]<0)
						end # size(splitlist_sorted,1)>0
        end # size(tmp_splitlist,1)>0
		end # size(tmp_splitlist,1)>0
    return spl::Splitdef{T}
end

# new approach; first summarize by label, then iterate over the gray code such that only one category needs to switch classes and "online" update the metrics
function _split_feature(ONE_return_type::T, number_of_num_features::Int, trnidx::Vector{Int}, validx::Vector{Int}, numerator::Array{Float64,1}, denominator::Array{Float64,1}, pointwiseRatio::Array{Float64,1}, weight::Array{Float64,1}, fname::Symbol, features, minweight::Float64, crit::SplittingCriterion, feature_column_id::Int, randomweight::Float64, catSortByThreshold::Int, catSortBy::SortBy) where T <: Unsigned
    crit_type = typeof(crit)
# This function is now for numeric and character variables!
# feature_column_id is negative in case of character variables
    best_value = -Inf
    best_thresh = best_wl = best_wr = NaN
    best_subset = Array{UInt8}(undef, 0)
    trnfeatures = view(features, trnidx)
    elt = T # eltype(trnfeatures.parent.refs) #not sure if this was really helping, let us determine elt through T
    labellist_sorted = collect(one(elt):convert(elt, length(trnfeatures.parent.pool))) # this used to be levels(features) #this also contains the val feature levels here! It is considerably faster than levels(view) \factor 100 or so

    case1a = (crit_type == DifferenceSplit || crit_type == MaxValueSplit || crit_type == MaxMinusValueSplit || crit_type == MaxAbsValueSplit)
    case1b = (crit_type == GammaDevianceSplit) || (crit_type == PoissonDevianceSplit)
    case1 = (crit_type == DifferenceSplit || crit_type == GammaDevianceSplit || crit_type == PoissonDevianceSplit || crit_type == MaxValueSplit || crit_type == MaxMinusValueSplit || crit_type == MaxAbsValueSplit)
    case2 = (crit_type == msePointwiseSplit) || (crit_type == mseSplit) || (crit_type == sseSplit)
	# THIS IS CRITICAL
	# THE WAY A PooledArray IS CONSTRUCTED, WE WILL ALWAYS HAVE
	# pda.pool[2] == "some string" -> any pda.refs[x].==0x02 will be "some string"
	# todo/tbd countsort here might be obsolete: we should check if levels is always sorted by construction
  # also we will later sort the labels in a different order anyway (then again the list probably needs to be sorted in the natural manner such that build_listOfMeanResponse is working properly)
    if size(labellist_sorted, 1) <= 1
        if T == UInt8
            return UInt8VECTORemptySplitDef
        else
            return UInt16VECTORemptySplitDef # collect(Vector{Splitdef{T}}(undef,0))::Vector{Splitdef{T}}
        end
    else
    # this may need improvement:
	if case1
    		labellist, sumnumerator, sumdenominator, sumweight, countlistfloat = build_listOfMeanResponse(crit, trnidx, validx, numerator, denominator, weight, trnfeatures, labellist_sorted, minweight)
	    elseif case2
		    labellist, sumnumerator, sumdenominator, sumweight, countlistfloat, moments_per_pdaclass = build_listOfMeanResponse(crit, numerator, denominator, weight, trnfeatures, labellist_sorted, minweight)
        # else #we catch this possibility earlier when checking the settings
        #	throw(ErrorException(string("Invalid Splitting criterion $(crit)")))
	end
  # todo/tbd
  # here we can introduce the possiblity to sort the labellist (e.g. by meanobserved or median (to be calculated)).
  # then we could only loop through the "increasing list" of sorted labels (instead of doing the 2^ncategories exhaustive search (bitflip_graycode_subsets))
    if feature_column_id > 0 # id>0 -> we are working on a numeric column
		# only consider to split at the candidate split points
		subs = increasing_subsets(labellist)
    else # id<0 -> we are working on a character column
		# distinguish between exhaustive and "increasing" search for split point
	    if size(labellist_sorted, 1) > catSortByThreshold
		    if case1
                sortlists!(catSortBy, labellist, sumnumerator, sumdenominator, sumweight, countlistfloat) # catSortBy::SortBy=SORTBYMEAN
            elseif case2
			    sortlists!(catSortBy, labellist, sumnumerator, sumdenominator, sumweight, countlistfloat, moments_per_pdaclass)
		    end
		subs = increasing_subsets(labellist)
	else
	    # perform exhaustive search
            subs = bitflip_graycode_subsetsHALF(labellist)
        end
	end

	if randomweight == 0.0
        if case1a
            tmp_result = calculateSplitValue(crit, fname, number_of_num_features, labellist, sumnumerator, sumdenominator, sumweight, countlistfloat, minweight, subs)
        elseif case2
            tmp_result = calculateSplitValue(crit, fname, number_of_num_features, labellist, sumnumerator, sumdenominator, sumweight, countlistfloat, minweight, subs, moments_per_pdaclass)
        elseif case1b
            tmp_result = calculateSplitValue(crit, fname, number_of_num_features, labellist, sumnumerator, sumdenominator, sumweight, countlistfloat, minweight, subs, numerator, denominator, pointwiseRatio, weight, trnfeatures)
        end
        if isfinite(tmp_result[1])
            feature_column_id2 = feature_column_id < 0 ? abs(feature_column_id) + number_of_num_features : feature_column_id
            return [Splitdef(feature_column_id, feature_column_id2, fname, Vector{T}(tmp_result[2]), tmp_result[1], tmp_result[3], tmp_result[4])]::Vector{Splitdef{T}}
        else
            if T == UInt8
                return UInt8VECTORemptySplitDef
            else
                return UInt16VECTORemptySplitDef # collect(Vector{Splitdef{T}}(undef,0))::Vector{Splitdef{T}}
            end
        end
    else
  # randomweight>0
        if case1a
            tmpres = calculateSplitValue(crit, fname, number_of_num_features, labellist, sumnumerator, sumdenominator, sumweight, countlistfloat, minweight, subs, feature_column_id)
        elseif case2
            tmpres = calculateSplitValue(crit, fname, number_of_num_features, labellist, sumnumerator, sumdenominator, sumweight, countlistfloat, minweight, subs, feature_column_id, moments_per_pdaclass)
        elseif case1b
            tmpres = calculateSplitValue(crit, fname, number_of_num_features, labellist, sumnumerator, sumdenominator, sumweight, countlistfloat, minweight, subs, numerator, denominator, pointwiseRatio, weight, trnfeatures, feature_column_id)
        end
            return tmpres::Vector{Splitdef{T}}
        end
    end
end


text:
using SimpleGraphs
using SimpleGraphRepresentations
using SimpleGraphDrawings
using PyPlot
using LatexPrint
using ProgressMeter
include("CircleRepresentationDrawing.jl")

"""
`CrossMatrix(list)` takes a circle representation list
and produces a signed adjacency matrix of the corresponding
circle graph. We have `+1` or `-1` entries depending on
how the segments cross each other. Every segment is oriented
and the sign is determined if based on left-to-right or
right-to-left orientation of the crossing segments.
"""
function CrossMatrix{T}(list::Array{T,1})
    positions = SimpleGraphRepresentations.list2locs(list)
    elts = collect(keys(positions))
    n = length(elts)
    try
        sort!(elts)
    end

    A = zeros(Int, n, n)

    for i = 1:n
        v = elts[i]
        a = positions[v]
        for j = 1:n
            w = elts[j]
            b = positions[w]
            if a[1] < b[1] < a[2] < b[2]
                A[i, j] = 1
            end
            if b[1] < a[1] < b[2] < a[2]
                A[i, j] = -1
            end
        end
    end
    return A
end

function find_firsts_seconds{T}(list::Array{T,1})
    F = Set{T}()  # firsts
    n = length(list)
    res = zeros(Int, n)
    for i = 1:n
        x = list[i]
        if in(x, F)
            res[i] = 2
        else
            push!(F, x)
            res[i] = 1
        end
    end
    return res
end

function find_jumps{T}(list::Array{T,1})
    n = length(list)
    fs = find_firsts_seconds(list)

    jumps = Int[]

    for i = 1:n-1
        if fs[i] != fs[i+1] && list[i] != list[i+1]
            push!(jumps, i)
        end
    end
    return jumps
end

# There's a spot at i,i+1 for a jump. Move the i to the right.
function jump_over_right{T}(list::Array{T,1}, i::Int)
    n = length(list)
    fs = find_firsts_seconds(list)
    if fs[i] == fs[i+1]
        error("Not a valid jump location")
    end

    if fs[i] == 1
        #println("intersecting")
        a = list[i+1]
        b = list[i]
        b_locs = find(list .== b)
        j = b_locs[2]
        idx = [collect(1:i); collect(i+2:j-1); i + 1; collect(j:n)]
    else
        #println("disjoint")
        a = list[i]
        b = list[i+1]
        b_locs = find(list .== b)
        j = b_locs[2]
        idx = [collect(1:i-1); collect(i+1:j); i; collect(j+1:n)]
    end
    #println(idx)
    return list[idx]
end

function jump_over_left{T}(list::Array{T,1}, i::Int)
    rev_list = reverse(list)
    n = length(list)
    rev_ans = jump_over_right(rev_list, i)
    return reverse(rev_ans)
end

function rotate{T}(list::Array{T,1})
    n = length(list)
    result = Array{T,1}(n)
    for i = 2:n
        result[i] = list[i-1]
    end
    result[1] = list[n]
    return result
end

function build_jump_graph{T}(list::Array{T,1}, early_quit::Bool = true)
    todo = []
    done = Set()
    push!(todo, list)
    G = SimpleGraph{Array{T,1}}()
    add!(G, list)

    while length(todo) > 0
        current = pop!(todo)
        if early_quit && maximum(deg(CircleGraph(current))) <= 1
            return G
        end

        if in(current, done)
            continue
        end
        jump_list = find_jumps(current)
        for i in jump_list
            next = jump_over_right(current, i)
            add!(G, current, next)
            push!(todo, next)
        end
        jump_list = find_jumps(reverse(current))
        for i in jump_list
            next = jump_over_left(current, i)
            add!(G, current, next)
            push!(todo, next)
        end
        next = rotate(current)
        add!(G, current, next)
        push!(todo, next)

        push!(done, current)
    end
    return G
end

function path2caravan{T}(list::Array{T,1})
    G = build_jump_graph(list)
    for v in G.V
        H = CircleGraph(v)
        if maximum(deg(H)) <= 1
            p = find_path(G, list, v)
            return p
        end
    end
    error("Cannot reduce to a caravan")
end

function trim_caravan_path{T}(P::Array{Array{T,1},1})
    n = length(P)
    for k = 1:n
        G = CircleGraph(P[k])
        if maximum(deg(G)) <= 1
            return P[1:k]
        end
    end
    return P
end

"""
`average_det(n,reps)`: Generate random circle graphs
and report the average determinant of their cross
matrix.
"""
function average_det(n::Int, reps::Int = 1000)
    total = 0.0
    P = Progress(reps, 1)
    for k = 1:reps
        A = CrossMatrix(RandomCircleRepresentation(n))
        total += round(det(A))
        next!(P)
    end
    return total / reps
end

function caravan_demo_latex{T}(list::Array{T,1})
    P = path2caravan(list)
    P = trim_caravan_path(P)
    np = length(P)
    println("Reduce to caravan in $np steps")
    run(`make very-clean`)
    F = open("caravan.tex", "w")

    println(F, "\\documentclass[12pt]{article}")
    println(F, "\\usepackage{graphicx}")
    println(F, "\\usepackage{txfonts}")
    println(F, "\\usepackage[margin=1in]{geometry}")
    println(F, "\\begin{document}")

    for i = 1:np
        a = P[i]
        G = CircleGraph(a)
        X = SimpleGraphDrawing(G)
        spectral!(X)
        spring!(X)
        stress!(X)
        figure(1)
        clf()
        set_vertex_size(20)
        draw(X)
        draw_labels(X)
        savefig("graph-$i.pdf")
        clf()
        RainbowDrawing(a)
        savefig("rainbow-$i.pdf")
        A = CrossMatrix(a)

        println(F, "\\begin{center}")
        println(F, "\\includegraphics[width=0.5\\textwidth]{graph-$i-crop}\\\\")
        println(F, "\\bigbreak\\hrule\\bigbreak")
        println(F, "\\includegraphics[width=0.75\\textwidth]{rainbow-$i-crop}\\\\")
        println(F, "\\[")
        lap(F, A)
        println(F, "\\]")
        println(F, "\\end{center}")
        if i < np
            println(F, "\\newpage")
        end

    end
    println(F, "\\end{document}")
    close(F)
    close()
    run(`make view`)
end

"""
`find_example(n,ngoal)`
Find an example of a connected circle graph with a given
cross matrix nullity.
"""
function find_example(n::Int, ngoal::Int = 0)
    while true
        seq = RandomCircleRepresentation(n)
        G = CircleGraph(seq)
        if !is_connected(G)
            continue
        end
        A = CrossMatrix(seq)
        r = rank(A)
        if r == n - ngoal
            return G, seq, A
        end
    end
end

"""
`find_example_tex(n,ngoal)`
"""
function find_example_tex(n::Int, ngoal::Int = 0)
    G, seq, A = find_example(n, ngoal)
    X = SimpleGraphDrawing(G)
    spectral!(X)
    spring!(X)
    stress!(X)
    figure(1)
    set_vertex_size(20)
    clf()
    draw(X)
    draw_labels(X)
    savefig("graph.pdf")
    run(`pdfcrop graph.pdf`)
    figure(2)
    clf()
    CircleRepresentationDrawing(seq)
    savefig("rep.pdf")
    run(`pdfcrop rep.pdf`)

    lap(A)

    F = open("example.tex", "w")

    println(F, "\\documentclass[12pt]{article}")
    println(F, "\\usepackage{graphicx}")
    println(F, "\\usepackage{txfonts}")
    println(F, "\\usepackage[margin=0.75in]{geometry}")
    println(F, "\\begin{document}")
    println(F, "\\begin{center}")
    println(F, "$n vertices with nullity $ngoal \\\\")
    println(F, "\\includegraphics[width=0.45\\textwidth]{graph-crop}  ")
    println(F, "\\includegraphics[width=0.45\\textwidth]{rep-crop} \\\\")
    println(F, "\\[")
    println(F, latex_form(A))
    println(F, "\\]")
    println(F, "\\end{center}")
    println(F, "\\end{document}")

    close(F)
    run(`pdflatex example`)
    run(`launch example.pdf`)

    return G, seq, A
end

function rank_indicator_vec{T}(list::Array{T,1})
    n = round(Int, length(list) / 2)
    result = zeros(Int, n)
    A = CrossMatrix(list)
    r = round(Int, rank(A))
    if n > 0
        result[r] = 1
    else
        warn("Rank zero skipped")
    end
    return result
end

function rand_hist(n::Int, reps::Int = 1000)
    result = zeros(Int, n)
    P = Progress(reps, 1)
    for j = 1:reps
        result += rank_indicator_vec(RandomCircleRepresentation(n))
        next!(P)
    end
    return result /= reps
end


text:
include("helper.jl")

my_tests = [

  "utilities/test_latin_hypercube_sampling.jl",
  "utilities/test_assign_ranks.jl",

  "test_parameters.jl",
  "test_fitness.jl",
  "test_population.jl",
  "test_bimodal_cauchy_distribution.jl",
  "test_search_space.jl",
  "test_frequency_adaptation.jl",
  "test_archive.jl",

#  "test_random_search.jl",
  "test_differential_evolution.jl",
  "test_adaptive_differential_evolution.jl",
  "test_natural_evolution_strategies.jl",
  "test_smoketest_bboptimize.jl",

  "problems/test_single_objective.jl",

  "test_generating_set_search.jl",
  "test_direct_search_with_probabilistic_descent.jl",
]

for t in my_tests
  include(t)
end

exitstatus()


text:
#Eye Diagram Tests

@testset "Eye Diagram Tests" begin #Scope for test data

testbits = [0,1,0,1,0,1,1,0,1,0,0,1,1,1,0,0,0,1,0]
#@show length(testbits)

#Simple function to build a triangular bit pattern from a bit sequence
function BuildTriangPat(bitseq; tbit::Float64=1.0)
	y = 1.0 .* bitseq #Get floating point values
	x = collect((0:1:(length(bitseq)-1)) .* tbit)
	return (x, y)
end

#For debug purposes:
function dbg_showeyedata(eyedata)
	for i in 1:length(eyedata.vx)
		println("$i:")
		@show eyedata.vx[i]
		@show eyedata.vy[i]
	end
end

tbit = 1.0
(x,y) = BuildTriangPat(testbits, tbit = tbit)

@testset "Eye Diagram: Centered" begin
	eyedata = buildeye(x, y, tbit, 2.0*tbit, tstart=0.0*tbit)

	@test length(eyedata.vx) == length(eyedata.vy)
	@test length(eyedata.vx) == length(testbits) - 1

#	dbg_showeyedata(eyedata)

	for i in 1:(length(eyedata.vx)-1)
		@test eyedata.vx[i] == [0.0, 1.0, 2.0]
		@test eyedata.vy[i] == Float64[testbits[i], testbits[i+1], testbits[i+2]]
	end

	i = length(eyedata.vx)
	@test eyedata.vx[end] == [0.0, 1.0] #Cannot extrapolate past last data point
	@test eyedata.vy[i] == Float64[testbits[i], testbits[i+1]]
end

@testset "Eye Diagram: Early" begin
	eyedata = buildeye(x, y, tbit, 2.0*tbit, tstart=0.8*tbit)

	@test length(eyedata.vx) == length(eyedata.vy)
	@test length(eyedata.vx) == length(testbits) - 2 #Skipped 1st data point

#	dbg_showeyedata(eyedata)

	for i in 1:length(eyedata.vx)
		@test eyedata.vx[i] ≈ [0.2, 1.2]
		@test eyedata.vy[i] == Float64[testbits[i+1], testbits[i+2]]
	end
end

@testset "Eye Diagram: Late" begin
	eyedata = buildeye(x, y, tbit, 2.0*tbit, tstart=0.2*tbit)

	@test length(eyedata.vx) == length(eyedata.vy)
	@test length(eyedata.vx) == length(testbits) - 2 #Skipped 1st data point

#	dbg_showeyedata(eyedata)

	for i in 1:length(eyedata.vx)
		#Last data point in sweep should be >= 2.0*tbit:
		@test eyedata.vx[i] ≈ [0.8, 1.8]
		@test eyedata.vy[i] == Float64[testbits[i+1], testbits[i+2]]
	end
end
end #"Eye Diagram Tests"


text:
using Test

include("../src/CustomTypes.jl")
include("../src/Spheroidal.jl")
include("../src/TeukolskyQNMFunctions.jl")

include("TestCHLaplacian.jl")
include("TestChebyshev.jl")
include("TestGegenbauer.jl")
include("TestRadialODE.jl")
include("TestSphere.jl")
include("TestSpheroidal.jl")

using .CustomTypes, ..TeukolskyQNMFunctions

import .TestCHLaplacian
import .TestChebyshev
import .TestGegenbauer
import .TestRadialODE
import .TestSphere
import .TestSpheroidal

import .Spheroidal: compute_l_min, eig_vals_vecs

avals = [0.0, 0.354, 0.7, 0.99] ## same as in generate.py

###--------------------------------------------------------------
## Test convergence of Chebyshev derivatives
##--------------------------------------------------------------
nx   = tomyI(16)
xmin = tomyF(-1.431)
xmax = tomyF(10.3)

f(x)   =      sin(2.0*x)
d1f(x) =  2.0*cos(2.0*x)
d2f(x) = -4.0*sin(2.0*x)
TestChebyshev.test_convergence(   nx, xmin, xmax, f, d1f, d2f)
TestChebyshev.test_convergence_fd(nx, xmin, xmax, f, d1f, d2f)

f(x)   =      exp(-2.0*x)
d1f(x) = -2.0*exp(-2.0*x)
d2f(x) =  4.0*exp(-2.0*x)
TestChebyshev.test_convergence(   nx, xmin, xmax, f, d1f, d2f)
TestChebyshev.test_convergence_fd(nx, xmin, xmax, f, d1f, d2f)

TestChebyshev.test_X_matrices(nx, xmin, xmax)

TestChebyshev.test_to_cheb(nx)
TestChebyshev.test_to_cheb_to_real(nx, xmin, xmax)
##--------------------------------------------------------------
## Test Chebyshev second derivative
##--------------------------------------------------------------
nx   = tomyI(40)
neig = tomyI(4)
xmin = tomyF(-1.0)
xmax = tomyF(1.0)

TestCHLaplacian.interval_laplacian_ch(nx,neig,xmin,xmax)
nx = tomyI(320)
TestCHLaplacian.interval_laplacian_fd(nx,neig,xmin,xmax)
#nx  = tomyI(40)
#TestCHLaplacian.interval_laplacian_chs(nx,neig,xmin,xmax)
##--------------------------------------------------------------
## Testing spherical function
##--------------------------------------------------------------
TestSphere.test_swal_inner_product(48,-2,-2)
TestSphere.test_swal_inner_product(48,-1,-2)
TestSphere.test_swal_inner_product(48, 0,-2)
TestSphere.test_swal_inner_product(48, 1,-2)
TestSphere.test_swal_inner_product(48, 2,-2)

TestSphere.test_swal_inner_product(48,-2,0)
TestSphere.test_swal_inner_product(48,-1,0)
TestSphere.test_swal_inner_product(48, 0,0)
TestSphere.test_swal_inner_product(48, 1,0)
TestSphere.test_swal_inner_product(48, 2,0)

TestSphere.test_swal_inner_product(48,-2,3)
TestSphere.test_swal_inner_product(48,-1,3)
TestSphere.test_swal_inner_product(48, 0,3)
TestSphere.test_swal_inner_product(48, 1,3)
TestSphere.test_swal_inner_product(48, 2,3)

TestSphere.test_norm_swal_lap(32, 0,0,2)

TestSphere.test_norm_swal_lap(32,-1,1,2)
TestSphere.test_norm_swal_lap(32, 0,1,2)
TestSphere.test_norm_swal_lap(32, 1,1,2)

TestSphere.test_norm_swal_lap(32,-2,-2,2)
TestSphere.test_norm_swal_lap(32,-1,-2,2)
TestSphere.test_norm_swal_lap(32, 0,-2,2)
TestSphere.test_norm_swal_lap(32, 1,-2,2)
TestSphere.test_norm_swal_lap(32, 2,-2,2)

TestSphere.test_norm_swal_lap(48,-2,5,23)
TestSphere.test_norm_swal_lap(48,-2,5,23)
TestSphere.test_norm_swal_lap(48,-1,5,23)
TestSphere.test_norm_swal_lap(48, 0,5,23)
TestSphere.test_norm_swal_lap(48, 1,5,23)
TestSphere.test_norm_swal_lap(48, 2,5,23)
###--------------------------------------------------------------
## Test Gegenbauer polynomial
##--------------------------------------------------------------
#=
nx=tomyI(20)
c0=tomyF(1.3243)
c1=tomyF(2.3)
om2=tomyF(1.0)
xmin=tomyF(-2.2321)
xmax=tomyF(+1.932)
TestGegenbauer.constant_sol_ode(nx,xmin,xmax,c0)
TestGegenbauer.linear_sol_ode(nx,xmin,xmax,c0,c1)
TestGegenbauer.airy_sol_ode(nx,xmin,xmax,om2)
n=tomyI(1)
a=tomyF(1.0)
b=tomyF(1.0)
TestGegenbauer.jacobi_sol_ode(6,n,a,b)
=#
##--------------------------------------------------------------
## Testing spheroidal functions
##--------------------------------------------------------------
nl   =  30
neig =  10

for s in [-2,-1,0]
   for m in [-3, 0]
      for a in avals
         for omegar in rand(2)
            for omegai in rand(2)
               om = (-1.0 + 2.0*omegar) + (-1.0 + 2.0*omegai)*im
               ## test reduces to spin weighted spherical harmonics
               ## when a*omega = 0
               if abs(a)<1e-16
                  lmin = compute_l_min(tomyI(s),tomyI(m))
                  ls, vs = eig_vals_vecs(tomyI(nl), tomyI(neig), tomyI(s), tomyI(m), tomyC(a*om))
                  for (i,la) in enumerate(ls)
                     l = (i-1) + lmin
                     @test abs((l-s)*(l+s+1) - la) < 1e-3
                  end
               end
               TestSpheroidal.test_m_symmetry(tomyI(nl),    tomyI(neig), tomyI(s), tomyI(m), tomyF(a), tomyC(om))
               TestSpheroidal.test_s_symmetry(tomyI(nl),    tomyI(neig), tomyI(s), tomyI(m), tomyF(a), tomyC(om))
               TestSpheroidal.test_conj_symmetry(tomyI(nl), tomyI(neig), tomyI(s), tomyI(m), tomyF(a), tomyC(om))
            end
         end
      end
   end
end
##--------------------------------------------------------------
## Testing Spheroidal ODE QNM
##--------------------------------------------------------------
for n=[0,1]
   for s=0:2
      for m=[0,2]
         lmin = compute_l_min(s,m)
         for l=lmin:(lmin+4)
            TestSpheroidal.compare_to_qnm(
                           tomyI(nl),
                           tomyI(neig),
                           tomyI(s),
                           tomyI(n),
                           tomyI(l),
                           tomyI(m),
                           [tomyF(a) for a in avals]
               )
         end
      end
   end
end
##--------------------------------------------------------------
## Testing Radial ODE QNM
##--------------------------------------------------------------
nr = 144

for n=[0,1]
   for s=-2:0
      mvals = [abs(s)]
      for m=[-2,0,1]
         lmin = compute_l_min(s,m)
         lvals = [lmin]
         if n==0
            mvals = lmin:(lmin+1)
         end
         for l=lvals
            TestRadialODE.compare_to_qnm(
                  tomyI(nr),
                  tomyI(s),
                  tomyI(n),
                  tomyI(l),
                  tomyI(m),
                  [tomyF(a) for a in avals]
               )
         end
      end
   end
end


text:
CI = CartesianIndex

function parse_data(l)
    m = match(r".*x=(-?\d+)\.\.(-?\d+), y=(-?\d+)\.\.(-?\d+)", l)
    x1, x2, y1, y2 = parse.(Int, m.captures)
    CI(x1, y1), CI(x2, y2)
end

const p1, p2 = parse_data(readline())

function step(pos, vel)
    pos = pos .+ vel
    vel = (sign(vel[1]) * (abs(vel[1]) - 1) , vel[2]-1)
    pos, vel
end

function step_until(vel, limit=500)
    pos = (0, 0)
    for i in 1:limit
        pos, vel = step(pos, vel)
        is_inside(pos) && return 1
        if pos[2] < p1.I[2] || pos[1] > p2.I[1]
            break
        end
    end
    0
end

is_inside(pos) = CI(pos...) ∈ p1:p2

# Part One
let n = abs(p1.I[2])-1
    n*(n+1)÷2
end |> println

# Part Two
sum(step_until((velx, vely)) for velx in 1:300, vely in -200:300) |> println

max_stars_repo_name: pLOPeGG/JuliaOfCode

max_issues_repo_name: pLOPeGG/JuliaOfCode

max_forks_repo_name: pLOPeGG/JuliaOfCode


text:
# Autogenerated wrapper script for OpenSpiel_jll for x86_64-linux-gnu-cxx11
export libspieljl

using libcxxwrap_julia_jll
JLLWrappers.@generate_wrapper_header("OpenSpiel")
JLLWrappers.@declare_library_product(libspieljl, "libspieljl.so")
function __init__()
    JLLWrappers.@generate_init_header(libcxxwrap_julia_jll)
    JLLWrappers.@init_library_product(
        libspieljl,
        "lib/libspieljl.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
using FactCheck
using DataStructures

# LLVM.Ast tests
include("datalayout.jl")

# LLVM tests
include("context.jl")
include("constants.jl")
include("jit.jl")


text:
#=
Results for the paper "QuantumCircuitOpt: An Open-source Frameworkfor Provably Optimal
Quantum Circuit Design" can be reproduced by executing this file.

Version of QCOpt: v0.3.0

Last updated: Oct 13, 2021
=#

import QuantumCircuitOpt as QCOpt
using JuMP
using Gurobi

include("gates_sc21.jl")

# Choosing a different MIP solver other than Gurobi can slow down the run times
qcm_optimizer = JuMP.optimizer_with_attributes(Gurobi.Optimizer, "Presolve" => 1)

#-----------------------------#
#      Results of Table-I     #
#-----------------------------#
table_I_gates = ["decompose_controlled_Z",
                 "decompose_controlled_V",
                 "decompose_controlled_H",
                 "decompose_magic_using_U3_CNot_2_1",
                 "decompose_iSwapGate",
                 "decompose_GroverDiffusion_using_U3"]

result_with_VC = Dict{String,Any}()
result_without_VC = Dict{String,Any}()
run_times_tab1 = zeros(length(table_I_gates),2)

k = 1
for gates in table_I_gates
    params = getfield(Main, Symbol(gates))()

    model_options = Dict{Symbol, Any}(:all_valid_constraints => 0)

    global result_with_VC = QCOpt.run_QCModel(params,
                                              qcm_optimizer;
                                              options = model_options)
    run_times_tab1[k,1] = result_with_VC["solve_time"]

    model_options = Dict{Symbol, Any}(:all_valid_constraints => -1)

    global result_without_VC = QCOpt.run_QCModel(params,
                                                 qcm_optimizer;
                                                 options = model_options)
    run_times_tab1[k,2] = result_without_VC["solve_time"]
    global k += 1
end

#--------------------------------------------#
#      Results of Figure 3 (Magic basis)     #
#--------------------------------------------#
result = Dict{String,Any}()
figure_3_gates = ["decompose_magic_using_SH_CNot_2_1",
                  "decompose_magic_using_U3_CNot_2_1",
                  "decompose_magic_using_SH_CNot_1_2",
                  "decompose_magic_using_U3_CNot_1_2",
                  ]

run_times_fig3 = zeros(length(figure_3_gates),1)

k = 1
for gates in figure_3_gates
    params = getfield(Main, Symbol(gates))()

    global result = QCOpt.run_QCModel(params, qcm_optimizer)

    run_times_fig3[k,1] = result["solve_time"]
    global k += 1
end

#------------------------------------------------#
#      Results of Figure 4 (Grover operator)     #
#------------------------------------------------#
result = Dict{String,Any}()
figure_4_gates = ["decompose_GroverDiffusion_using_Clifford",
                  "decompose_GroverDiffusion_using_U3"]

run_times_fig4 = zeros(length(figure_4_gates),1)

k = 1
for gates in figure_4_gates
    params = getfield(Main, Symbol(gates))()

    global result = QCOpt.run_QCModel(params, qcm_optimizer)

    run_times_fig4[k,1] = result["solve_time"]
    global k += 1
end

#------------------------------------------------#
#      Results of Figure 5 (larger circuits)     #
#------------------------------------------------#
result = Dict{String,Any}()
figure_5_gates = ["decompose_toffoli_with_controlled_gates",
                  "decompose_Fredkin",
                  "decompose_double_toffoli",
                  "decompose_quantum_fulladder",
                  ]

run_times_fig5 = zeros(length(figure_5_gates),1)

k = 1
for gates in figure_5_gates
    params = getfield(Main, Symbol(gates))()

    global result = QCOpt.run_QCModel(params, qcm_optimizer)

    run_times_fig5[k,1] = result["solve_time"]
    global k += 1
end


text:
using Dates

struct DBProject
    database::SQLite.DB
    pkey::Int
    parent::Union{DBProject,Missing}
    createdBy::DBPerson
    name::String
    description::String
end

function Base.show(io::IO, pr::DBProject)
    print(io, pr.name*(pr.parent.name != "Root" ? " <= "*repr(pr.parent) : ""))
end

Base.write(db::SQLite.DB, ::Type{DBProject}, name::String, desc::String, createdBy::DBPerson)::Int =
    write(db, DBProject, name, desc, createdBy.pkey, 0)

Base.write(db::SQLite.DB, ::Type{DBProject}, name::String, desc::String, createdBy::DBPerson, parent::DBProject)::Int =
    write(db, DBProject, name, desc, createdBy.pkey, parent.pkey)

function Base.write(db::SQLite.DB, ::Type{DBProject}, name::String, desc::String, personKey::Int, parentkey::Int)::Int
    stmt1 = SQLite.Stmt(db, "INSERT INTO PROJECT ( PARENT, CREATEDBY, NAME, DESCRIPTION ) VALUES ( ?, ?, ?, ? );")
    r = DBInterface.execute(stmt1, ( parentkey, personKey, name, desc ))
    return DBInterface.lastrowid(r)
end

function Base.read(db::SQLite.DB, ::Type{DBProject}, pkey::Int)::DBProject
    stmt1 = SQLite.Stmt(db, "SELECT * FROM PROJECT WHERE PKEY=?;")
    q = DBInterface.execute(stmt1, ( pkey, ))
    if SQLite.done(q)
        error("No known project with key '$(pkey)'.")
    end
    r = SQLite.Row(q)
    # Recursively read parent projects
    parent = r[:PARENT] < 0 ? missing : read(db, DBProject, r[:PARENT])
    return DBProject(db, r[:PKEY], parent, read(db, DBPerson, r[:CREATEDBY]), r[:NAME], r[:DESCRIPTION])
end

function Base.findall(db::SQLite.DB, ::Type{DBProject}, parent::DBProject; createdBy=missing, name=missing, desc=missing)::Vector{DBProject}
    bs = "SELECT * FROM PROJECT WHERE PARENT=?"
    args = Any[ parent.pkey ]
    if !ismissing(createdBy)
        bs *= "AND CREATEDBY=?"
        push!(args, createdBy)
    end
    if !ismissing(name)
        bs *= "AND NAME=?"
        push!(args, name)
    end
    if !ismissing(desc)
        bs *= "AND DESCRIPTION=?"
        push!(args, desc)
    end
    stmt1 = SQLite.Stmt(db, bs*";")
    q = DBInterface.execute(stmt1, args)
    return [ DBProject(db, r[:PKEY], parent, read(db, DBPerson, r[:CREATEDBY]), r[:NAME], r[:DESCRIPTION]) for r in q]
end

Base.findall(db::SQLite.DB, ::Type{DBProject}, parentkey::Int)::Vector{DBProject} =
    findall(db, DBProject, read(db, DBProject, parentkey))

function find(db::SQLite.DB, ::Type{DBProject}, parentkey::Int, name::String)::Int
    stmt1 = SQLite.Stmt(db, "SELECT PKEY FROM PROJECT WHERE PARENT=? AND NAME=?;")
    q = DBInterface.execute(stmt1, ( parentkey, name))
    return SQLite.done(q) ? -1 : SQLite.Row(q)[:PKEY]
end

function Base.read(db::SQLite.DB, ::Type{DBProject}, parentkey::Int, name::String)::DBProject
    stmt1 = SQLite.Stmt(db, "SELECT * FROM PROJECT WHERE PARENT=? AND NAME=?;")
    q = DBInterface.execute(stmt1, ( parentkey, name))
    if SQLite.done(q)
        error("No known project with $name.")
    end
    r = SQLite.Row(q)
    parent = r[:PARENT] >= 0 ? read(db, DBProject, r[:PARENT]) : missing
    return DBProject(db, r[:PKEY], parent, read(db, DBPerson, r[:CREATEDBY]), r[:NAME], r[:DESCRIPTION])
end

function Base.findall(db::SQLite.DB, ::Type{DBProject}, createdby::DBPerson)::Vector{DBProject}
    stmt1 = SQLite.Stmt(db, "SELECT PKEY FROM PROJECT WHERE CREATEDBY=?;")
    q = DBInterface.execute(stmt1, ( createdby.pkey, ))
    return [ read(db, DBProject, r[:PKEY]) for r in q]
end


text:
@testset "Elements" begin

    # Get known 'good' elements
    fname = "elements.txt"
    t0 = 7257.93115525-7300.0
    H = [3,1,1]
    init0 = ElementsIC(fname,H,t0)

    # Fill new methods with pre-calculated elements
    # See if we get back the proper array
    elems_arr = readdlm(fname,',',comments=true)

    # Convert ecosϖ/esinϖ to ϖ and e
    elems_a = copy(elems_arr[1,:])
    elems_b = copy(elems_arr[2,:])
    elems_c = copy(elems_arr[3,:])

    function convert_back!(elems::Vector{<:Real})
        e = sqrt(elems[4]^2 + elems[5]^2)
        ϖ = atan(elems[5],elems[4])
        elems .= [elems[1:3];e;ϖ;elems[6:end]]
        return
    end

    convert_back!.([elems_b,elems_c])
    a = Elements(elems_a...)
    b = Elements(elems_b...)
    c = Elements(elems_c...)
    init_test = ElementsIC(t0,a,b,c,H=H)

    @test isapprox(init0.elements[1:3,:],init_test.elements);

end;


text:
function Observers.update!(observer::ITensors.AbstractObserver; kwargs...)
  return measure!(observer; kwargs...)
end


text:
### Temporary definitions to support Flux

roc(xs) = adapt(ROCArray{Float32}, xs)
allowscalar(x::Bool) = nothing


text:
function zero_edges!(A::AbstractArray{T,4}) where {T}
    L₁ = last(axes(A,1)); L₂ = last(axes(A,2));
    if L₁ == L₂ && first(axes(A,1)) == first(axes(A,2))
        @avx for i₁ ∈ axes(A,2), i₃ ∈ axes(A,3), i₄ ∈ axes(A,4)
            A[i₁,1, i₃,i₄] = zero(T)
            A[i₁,L₁,i₃,i₄] = zero(T)
            A[1, i₁,i₃,i₄] = zero(T)
            A[L₁,i₁,i₃,i₄] = zero(T)
        end
    else
        for i₃ ∈ axes(A,3), i₄ ∈ axes(A,4)
            @avx for i₁ ∈ axes(A,1)
                A[i₁,1, i₃,i₄] = zero(T)
                A[i₁,L₂,i₃,i₄] = zero(T)
            end
            @avx for i₁ ∈ axes(A,2)
                A[1, i₁,i₃,i₄] = zero(T)
                A[L₁,i₁,i₃,i₄] = zero(T)
            end
        end
    end
    A
end

clippedrange(x) = staticp1(maybestaticfirst(x)):staticm1(maybestaticlast(x))
clippedrange(x, c) = maybestaticfirst(x)+c:maybestaticlast(x)-c

"""
For padded images, take a view to drop the padding. Used to pass image to maxpool2x2.
"""
@generated function clippedimageview(A::AbstractArray{<:Any,N}, ::AbstractArray) where {N}
    v = Expr(:call, :view, :A)
    for n in 1:N-2
        push!(v.args, :(clippedrange(axes(A,$n), maybestaticsize(A, Val{$n}()) >>> Static{1}())))
    end
    push!(v.args, :(:)); push!(v.args, :(:))
    Expr(:block, Expr(:meta,:inline), v)
end

unclippedrange(x) = staticm1(maybestaticfirst(x)):staticp1(maybestaticlast(x))
unclippedrange(x, c) = maybestaticfirst(x) - c:maybestaticlast(x) + c

@generated function unclip(A::AbstractArray{<:Any,N}, ::AbstractArray) where {N}
    v = Expr(:call, :view, :A)
    for n in 1:N
        if n < 3
            push!(v.args, :(unclippedrange(axes(A,$n), maybestaticsize(A, Val{$n}()) >>> Static{1}())))
        else
            push!(v.args, :(:))
        end
    end
    Expr(:block, Expr(:meta,:inline), v)
end

function alloc_maxpool2x2_output(img::AbstractArray{T}, ::Val{pad} = Val{true}()) where {T,pad}
    if pad
        H = vadd(PaddedMatrices.VectorizationBase.maybestaticsize(img, Val(1)) >> Static(1), Static(2))
        W = vadd(PaddedMatrices.VectorizationBase.maybestaticsize(img, Val(1)) >> Static(1), Static(2))
    else
        H = PaddedMatrices.VectorizationBase.maybestaticsize(img, Val(1)) >> Static(1)
        W = PaddedMatrices.VectorizationBase.maybestaticsize(img, Val(1)) >> Static(1)
    end
    O = PaddedMatrices.VectorizationBase.maybestaticsize(img, Val(3))
    N = PaddedMatrices.VectorizationBase.maybestaticsize(img, Val(4))
    A = allocarray(T, (O, H, W, N))
    P = PermutedDimsArray(A, Static((2,3,1,4)))
    padd ? zero_edges!(P) : P
end


text:
module linear_regression
export h, J, init_theta, grad

h(theta, X) = theta' * X
J(theta, X, y) = 0.5 * sum((h(theta, X) - y).^2) / size(X, 2)
init_theta(n) = randn(n, 1) * 0.01
grad(theta, X, y) = X * (h(theta, X) - y)' / size(X, 2)

end

max_stars_repo_name: ilkerkesen/ufldl-tutorial

max_issues_repo_name: ilkerkesen/ufldl-tutorial

max_forks_repo_name: ilkerkesen/ufldl-tutorial


text:
"""
    AmplitudeModulation(rate, phase, depth)

Apply amplitude modulation to the signal

Inputs
------
* `rate` (Hz) desired modulation rate to be applied to signal.
* `phase` phase of modulation to be applied to signal applied to signal.
  Defaults to pi so that modulation starts at a minimum.
* `depth` modulation depth.

Example
-------
```julia
modulate = AmplitudeModulation(1u"Hz")
modulated_sound = modify(modulate, original_sound)
```
"""
@with_kw mutable struct AmplitudeModulation
    rate::typeof(1.0u"Hz")=0.0u"Hz"
    phase::Number=π
    depth::Number=1
    enable::Bool=true
    time::Float64=0.0

    AmplitudeModulation(a::AbstractQuantity, b, c, d, e) = new(a, b, c, d, e)
    AmplitudeModulation(a::AbstractQuantity, b, c, d) = new(a, b, c, d, 0.0)
    AmplitudeModulation(a::AbstractQuantity, b, c) = new(a, b, c, true, 0.0)
    AmplitudeModulation(a::AbstractQuantity, b) = new(a, b, 1, true, 0.0)
    AmplitudeModulation(a::AbstractQuantity) = new(a, π, 1, true, 0.0)

end

function AmplitudeModulation(a::Number, args...)
    @error "You must use units for modulation rate."
end

function modify(sink::AmplitudeModulation, buf)
    start_time = sink.time
    end_time = start_time + (size(buf, 1) / samplerate(buf))
    if sink.enable
        t = range(start_time, stop=end_time, length=size(buf, 1))
        M = 1 .* cos.(2 * π * ustrip(sink.rate) * t .+ sink.phase) .* sink.depth
        buf.data = (1 .+ M) .* buf.data
    end
    sink.time = end_time
    return buf
end