text:
using Dates: DateFormat, DatePart, min_width, max_width, tryparsenext_base10
using TimeZones.TZData: MIN_YEAR, MAX_YEAR

function tryparsenext_fixedtz(str, i, len, min_width::Int=1, max_width::Int=0)
    i == len && str[i] == 'Z' && return ("Z", i+1)

    tz_start, tz_end = i, 0
    min_pos = min_width <= 0 ? i : i + min_width - 1
    max_pos = max_width <= 0 ? len : min(chr2ind(str, ind2chr(str,i) + max_width - 1), len)
    state = 1
    @inbounds while i <= max_pos
        c, ii = iterate(str, i)::Tuple{Char, Int}
        if state == 1 && (c == '-' || c == '+')
            state = 2
            tz_end = i
        elseif (state == 1 || state == 2) && '0' <= c <= '9'
            state = 3
            tz_end = i
        elseif state == 3 && c == ':'
            state = 4
            tz_end = i
        elseif (state == 3 || state == 4) && '0' <= c <= '9'
            tz_end = i
        else
            break
        end
        i = ii
    end

    if tz_end <= min_pos
        return nothing
    else
        tz = SubString(str, tz_start, tz_end)
        return tz, i
    end
end

function tryparsenext_tz(str, i, len, min_width::Int=1, max_width::Int=0)
    tz_start, tz_end = i, 0
    min_pos = min_width <= 0 ? i : i + min_width - 1
    max_pos = max_width <= 0 ? len : min(chr2ind(str, ind2chr(str,i) + max_width - 1), len)
    @inbounds while i <= max_pos
        c, ii = iterate(str, i)::Tuple{Char, Int}
        if c == '/' || c == '_' || isletter(c)
            tz_end = i
        else
            break
        end
        i = ii
    end

    if tz_end == 0
        return nothing
    else
        name = SubString(str, tz_start, tz_end)

        # If the time zone is recognized make sure that it is well-defined. For our
        # purposes we'll treat all abbreviations except for UTC and GMT as ambiguous.
        # e.g. "MST": "Mountain Standard Time" (UTC-7) or "Moscow Summer Time" (UTC+3:31).
        if occursin("/", name) || name in ("UTC", "GMT")
            return name, i
        else
            return nothing
        end
    end
end

function Dates.tryparsenext(d::DatePart{'z'}, str, i, len)
    tryparsenext_fixedtz(str, i, len, min_width(d), max_width(d))
end

function Dates.tryparsenext(d::DatePart{'Z'}, str, i, len)
    tryparsenext_tz(str, i, len, min_width(d), max_width(d))
end

function Dates.format(io::IO, d::DatePart{'z'}, zdt, locale)
    write(io, string(current_zone(zdt).offset))
end

function Dates.format(io::IO, d::DatePart{'Z'}, zdt, locale)
    write(io, string(current_zone(zdt)))  # In most cases will be an abbreviation.
end

# Note: ISOZonedDateTimeFormat is defined in the module __init__ which means that this
# function can not be called from within this module. TODO: Ignore linting for this line
function ZonedDateTime(str::AbstractString, df::DateFormat=ISOZonedDateTimeFormat)
    try
        parse(ZonedDateTime, str, df)
    catch e
        if e isa ArgumentError
            rethrow(ArgumentError(
                "Unable to parse string \"$str\" using format $df. $(e.msg)"
            ))
        else
            rethrow()
        end
    end
end

function ZonedDateTime(str::AbstractString, format::AbstractString; locale::AbstractString="english")
    ZonedDateTime(str, DateFormat(format, locale))
end

Dates.default_format(::Type{ZonedDateTime}) = ISOZonedDateTimeFormat

"""
    _parsesub_tzabbr(str, [i, len]) -> Union{Tuple{AbstractString, Integer}, Exception}

Parses a section of a string as a time zone abbreviation as defined in the tzset(3) man
page. An abbreviation must be at least three or more alphabetic characters. When enclosed by
the less-than (<) and greater-than (>) signs the character set is expanded to include the
plus (+) sign, the minus (-) sign, and digits.

# Examples
```jldoctest
julia> _parsesub_tzabbr("ABC+1")
("ABC", 4)

julia> _parsesub_tzabbr("<ABC+1>+2")
("ABC+1", 6)
```
"""
function _parsesub_tzabbr(
    str::AbstractString,
    i::Integer=firstindex(str),
    len::Integer=lastindex(str),
)
    state = :started
    name_start = i
    name_end = prevind(str, i)

    @inbounds while i <= len
        c, ii = iterate(str, i)::Tuple{Char, Int}
        isascii(c) || break  # Restricts abbreviation support to ASCII characters

        if state == :simple && isletter(c)
            name_end = i
        elseif state == :expanded && (isletter(c) || isdigit(c) || c in ('+', '-'))
            name_end = i
        elseif state == :started && c == '<'
            name_start = ii
            name_end = i
            state = :expanded
        elseif state == :started && isletter(c)
            name_end = i
            state = :simple
        elseif state == :expanded && c == '>'
            i = ii
            state = :closed
            break
        else
            break
        end
        i = ii
    end

    if state == :expanded
        return ParseNextError("Expected expanded time zone abbreviation end with the greater-than sign (>)", str, prevind(str, name_start), i)
    elseif state != :closed && name_start > name_end
        return ParseNextError("Time zone abbreviation must start with a letter or the less-than (<) character", str, i)
    elseif length(str, name_start, name_end) < 3
        char_type = if state == :simple
            "alphabetic characters"
        else
            "characters which are either alphanumeric, the plus sign (+), or the minus sign (-)"
        end

        return ParseNextError("Time zone abbreviation must be at least three $char_type", str, name_start, name_end)
    else
        name = SubString(str, name_start, name_end)
        return name, i
    end
end

"""
    _parsesub_offset(str, [i, len]) -> Union{Tuple{Integer, Integer}, Exception}

Parses a section of a string as an offset of the form `[+|-]hh[:mm[:ss]]`. The hour must be
between 0 and 24, and the minutes and seconds 00 and 59. This follows specification for
offsets as defined in the tzset(3) man page.

# Example
```jldoctest
julia> _parsesub_offset("1:0:0")
(3600, 5)

julia> _parsesub_offset("-0:1:2")
(-62, 6)
```
"""
function _parsesub_offset(
    str::AbstractString,
    i::Integer=firstindex(str),
    len::Integer=lastindex(str);
    name::AbstractString="offset",
)
    coefficient = 1
    hour = minute = second = 0

    if i > len
        return ParseNextError("Expected $name and instead found end of string", str, i)
    end

    # Optional sign
    c, ii = iterate(str, i)::Tuple{Char, Int}
    if c in ('+', '-')
        coefficient = c == '-' ? -1 : 1
        if ii > len
            return ParseNextError("$(uppercasefirst(name)) sign ($c) is not followed by a value", str, i)
        end
        i = ii
    end

    # Hours
    val = tryparsenext_base10(str, i, len)
    if val === nothing
        return ParseNextError("Expected $name hour digits", str, i)
    end
    hour, ii = val
    if hour < 0 || hour > 24
        return ParseNextError("Hours outside of expected range [0, 24]", str, i, prevind(str, ii))
    end
    i = ii
    i > len && @goto done

    c, ii = iterate(str, i)::Tuple{Char, Int}
    c != ':' && @goto done
    i = ii

    # Minutes
    val = tryparsenext_base10(str, i, len)
    if val === nothing
        return ParseNextError("Expected $name minute digits after colon delimiter", str, i)
    end
    minute, ii = val
    if minute < 0 || minute > 59
        return ParseNextError("Minutes outside of expected range [0, 59]", str, i, prevind(str, ii))
    end
    i = ii
    i > len && @goto done

    c, ii = iterate(str, i)::Tuple{Char, Int}
    c != ':' && @goto done
    i = ii

    # Seconds
    val = tryparsenext_base10(str, i, len)
    if val === nothing
        return ParseNextError("Expected $name second digits after colon delimiter", str, i)
    end
    second, ii = val
    if second < 0 || second > 59
        return ParseNextError("Seconds outside of expected range [0, 59]", str, i, prevind(str, ii))
    end
    i = ii

    @label done
    duration = coefficient * (hour * 3600 + minute * 60 + second)
    return duration, i
end

"""
    _parsesub_tzdate(str, [i, len]) -> Union{Tuple{Function, Integer}, Exception}

Parses a section of a string as a day of the year as defined in tzset(3). The return value
includes an anonymous function which takes the argument `year::Integer` and returns a
`Date`. The day of year includes these three supported formats:

  Jn      Specifies the Julian day where `n` is between 1 and 365. Leap days are not
          counted. In this format, February 29 can't be represented; February 28 is day 59,
          and March 1 is always day 60.

  n       Specifies the zero-based Julian day with `n` between 0 and 365. February 29 is
          counted in leap years. For non-leap years 365 is January 1 of the following year.

  Mm.w.d  Specifies day `d` (0 <= `d` <= 6) of week `w` (1 <= `w` <= 5) of month `m`
          (1 <= `m` <= 12). Week 1 is the first week in which day `d` occurs and week 5 is
          the last week in which day `d` occurs. Day 0 is a Sunday.

# Example
```jldoctest
julia> f, i = _parsesub_tzdate("J60");

julia> f.(2019:2020)
2-element Array{Date,1}:
 2019-03-01
 2020-03-01

julia> f, i = _parsesub_tzdate("60");
2-element Array{Date,1}:
 2019-03-02
 2020-03-01

julia> f, i = _parsesub_tzdate("M3.3.0");  # Third Sunday in March

julia> f.(2019:2020)
2-element Array{Date,1}:
 2019-03-17
 2020-03-15
```
"""
function _parsesub_tzdate(
    str::AbstractString,
    i::Integer=firstindex(str),
    len::Integer=lastindex(str),
)
    if i > len
        return ParseNextError("Expected date and instead found end of string", str, i)
    end

    # Detect prefix
    c, ii = iterate(str, i)::Tuple{Char, Int}

    if c == 'J'
        i = ii

        val = tryparsenext_base10(str, i, len)
        if val === nothing
            return ParseNextError("Expected to find number of Julian days", str, i)
        end
        days, ii = val
        if days < 1 || days > 365
            return ParseNextError("Julian days outside of expected range [1, 365]", str, i, ii)
        end
        i = ii

        # The `J` prefix denotes a day of year between 1 and 365. Leap days are not counted.
        # In this format, February 29 can't be represented; February 28 is day 59, and
        # March 1 is always day 60.
        f = function (year::Integer)
            d = days + (isleapyear(year) && days >= 60)
            Date(year, 1) + Day(d - 1)
        end
        return f, i

    elseif c == 'M'
        i = ii

        # Month
        val = tryparsenext_base10(str, i, len)
        if val === nothing
            return ParseNextError("Expected to find month", str, i)
        end
        month, ii = val
        if month < 1 || month > 12
            return ParseNextError("Month outside of expected range [1, 12]", str, i, ii)
        end
        i = ii

        c, ii = iterate(str, i)::Tuple{Char, Int}
        (c != '.' || ii > len) && return ParseNextError("Expected to find delimiter (.)", str, i)
        i = ii

        # Week of month
        val = tryparsenext_base10(str, i, len)
        if val === nothing
            return ParseNextError("Expected to find week of month", str, i)
        end
        week_of_month, ii = val
        if week_of_month < 1 || week_of_month > 5
            return ParseNextError("Week of month outside of expected range [1, 5]", str, i, ii)
        end
        i = ii

        c, ii = iterate(str, i)::Tuple{Char, Int}
        (c != '.' || ii > len) && return ParseNextError("Expected to find delimiter (.)", str, i)
        i = ii

        # Day of week
        val = tryparsenext_base10(str, i, len)
        if val === nothing
            return ParseNextError("Expected to find day of week", str, i)
        end
        day_of_week, ii = val
        if day_of_week < 0 || day_of_week > 6
            return ParseNextError("Day of week outside of expected range [0, 6]", str, i, ii)
        end
        i = ii

        # Convert to the Julia day-of-week used by `Dates.dayofweek`
        # Equivalent to: `dow = (dow - 7) % 7 + 7`
        day_of_week == 0 && (day_of_week = 7)

        f = function (year::Integer)
            date = Date(year, month, (week_of_month - 1) * 7 + 1)
            if week_of_month < 5
                step = Day(1)
            else
                date = lastdayofmonth(date)
                step = Day(-1)
            end
            tonext(d -> dayofweek(d) == day_of_week, date; step=step, same=true, limit=7)
        end

        return f, i
    else
        val = tryparsenext_base10(str, i, len)
        if val === nothing
            return ParseNextError("Expected to find number of Julian days", str, i)
        end
        days, ii = val
        if days < 0 || days > 365
            # Note: On non-leap years day 365 will be the first day of the next year. This
            # is only supported as the tzset(3) man page explicitly states that the
            # zero-based Julia day is between 0 and 365.
            return ParseNextError("Julian days outside of expected range [0, 365]", str, i, ii)
        end
        i = ii

        # No prefix specifies the zero-based day of year between 0 and 365. February 29 is
        # counted in leap years.
        days += 1

        f = (year::Integer) -> Date(year, 1) + Day(days - 1)
        return f, i
    end
end

"""
    _parsesub_time(str, [i, len]) -> Union{Tuple{Integer, Integer}, Exception}

Parses a section of a string as a time of the form `hh[:mm[:ss]]`. Primarily this function
is used to parse daylight saving transition times as outlined in tzset(3).
"""
function _parsesub_time(
    str::AbstractString,
    i::Integer=firstindex(str),
    len::Integer=lastindex(str);
    name::AbstractString="time",
)
    if i > len
        return ParseNextError("Expected $name and instead found end of string", str, i)
    end

    # Require time does not start with a sign.
    c, ii = iterate(str, i)::Tuple{Char, Int}
    if c in ('+', '-')
        return ParseNextError("$(uppercasefirst(name)) should not have a sign", str, i)
    end

    return _parsesub_offset(str, i, len; name=name)
end

"""
    _parsesub_tz(str, [i, len]) -> Union{Tuple{TimeZone, Integer}, Exception}

Parse a direct representation of a time zone as specified by the tzset(3) man page.

# Examples
```jldoctest
julia> first(_parsesub_tz("EST+5"))
EST (UTC-5)

julia> first(_parsesub_tz("NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0"))
NZST/NZDT (UTC+12/UTC+13)
"""
function _parsesub_tz(
    str::AbstractString,
    i::Integer=firstindex(str),
    len::Integer=lastindex(str),
)
    # An empty or unset TZ environmental variable defaults to UTC
    if len == 0
        return FixedTimeZone("UTC"), i
    end

    x = _parsesub_tzabbr(str, i, len)
    if x isa Tuple
        std_name, i = x
    else
        return x
    end

    x = _parsesub_offset(str, i, len; name="standard offset")
    if x isa Tuple
        std_offset, i = x
    else
        return x
    end

    if i <= len
        x = _parsesub_tzabbr(str, i, len)
        if x isa Tuple
            dst_name, i = x
        else
            return x
        end
    else
        dst_name = nothing
    end

    dst_offset = nothing
    if dst_name !== nothing
        iter = iterate(str, i)
        if iter !== nothing && first(iter) != ','
            x = _parsesub_offset(str, i, len; name="daylight saving offset")
            if x isa Tuple
                dst_offset, i = x
            else
                return x
            end
        else
            dst_offset = std_offset - 3600
        end
    end

    start_dst = first(_parsesub_tzdate("M3.2.0"))::Function  # Second Sunday in March
    end_dst = first(_parsesub_tzdate("M11.1.0"))::Function   # First Sunday in November

    start_time = end_time = Hour(2)  # 02:00
    if i <= len
        c, ii = iterate(str, i)::Tuple{Char, Int}
        if c != ','
            return ParseNextError("Expected to find delimiter (,)", str, i)
        end
        i = ii

        # Daylight saving goes into effect
        x = _parsesub_tzdate(str, i, len)
        if x isa Tuple
            start_dst, i = x
        else
            return ParseNextError(
                "Unable to parse daylight saving start date. $(x.msg)",
                x.str, x.s, x.e,
            )
        end
        i > len && return ParseNextError("Expected to find daylight saving end and instead found end of string", str, i)

        c, ii = iterate(str, i)::Tuple{Char, Int}
        if c != '/' && c != ','
            return ParseNextError("Expected to find delimiter (,) or (/)", str, i)
        end
        i = ii

        if c == '/'
            x = _parsesub_time(str, i, len; name="daylight saving start time")
            if x isa Tuple
                start_time, i = x
                start_time = Second(start_time)
            else
                return x
            end
            i > len && return ParseNextError("Expected to find daylight saving end and instead found end of string", str, i)

            c, ii = iterate(str, i)::Tuple{Char, Int}
            if c != ','
                return ParseNextError("Expected to find delimiter (,)", str, i)
            end
            i = ii
        end

        x = _parsesub_tzdate(str, i, len)
        if x isa Tuple
            end_dst, i = x
        else
            return ParseNextError(
                "Unable to parse daylight saving end date. $(x.msg)",
                x.str, x.s, x.e,
            )
        end

        if i <= len
            c, ii = iterate(str, i)::Tuple{Char, Int}
            if c != '/'
                return ParseNextError("Expected to find delimiter (/)", str, i)
            end
            i = ii

            x = _parsesub_time(str, i, len; name="daylight saving end time")
            if x isa Tuple
                end_time, i = x
                end_time = Second(end_time)
            else
                return x
            end
        end
    end

    # "The offset is positive if the local timezone is west of the Prime Meridian and
    # negative if it is east". As this is the opposite of our internal representation we
    # have to negate the values.
    # e.g. "STD+1DST+2" results in a timezone with a std/dst offset of UTC-1/UTC-2
    std = FixedTimeZone(std_name, -std_offset)

    # Note: Most of the parsing time is spent creating the `VariableTimeZone`. The way I
    # would like to address this is by introducing a new `TimeZone` subtype which
    # dynamically calculates the transitions.
    tz = if dst_offset !== nothing
        dst = FixedTimeZone(dst_name, -std_offset, -(dst_offset - std_offset))

        transitions = Transition[]
        for year in 1900:MAX_YEAR
            # Note: "The offset specifies the time value to be added to the local time to get
            # Coordinated Universal Time (UTC)".
            utc_dst = DateTime(start_dst(year)) + start_time + Second(std_offset)
            utc_std = DateTime(end_dst(year)) + end_time + Second(dst_offset)

            append!(
                transitions,
                [
                    Transition(utc_dst, dst),
                    Transition(utc_std, std),
                ]
            )
        end
        sort!(transitions)

        cutoff_year = MAX_YEAR + 1
        utc_dst = DateTime(start_dst(cutoff_year)) + start_time + Second(std_offset)
        utc_std = DateTime(end_dst(cutoff_year)) + end_time + Second(dst_offset)
        cutoff = min(utc_dst, utc_std)

        # TODO: Ideally we would use a new TimeZone subtype which computes transitions
        # on-the-fly using the functions we provided.
        VariableTimeZone("$std_name/$dst_name", transitions, cutoff)
    else
        std
    end

    return tz, i
end


text:
# Placeholder file for the AbstractType TwEntity
# Twitter Entities include URLS, @mentions, #hashtags, etc.

type TwEntity
  data::Int
end

ext: jl

max_stars_repo_name: nick-paul/JuliaTwitter

max_issues_repo_name: nick-paul/JuliaTwitter

max_forks_repo_name: nick-paul/JuliaTwitter


text:
using CSDP

if !isdefined(:J) || !isa(J, AbstractArray)
    J = [1 3
         5 6]
    J = map(Float64, J)
end

br = CSDP.brec(reshape(J, length(J)), CSDP.MATRIX, 4)
ccall((:printb, CSDP.csdp), Void, (CSDP.blockrec,), br)
bra = [br, br]
block = CSDP.blockmatrix(1, pointer(bra))
println(block)
# ccall((:printm, CSDP.csdp), Void, (CSDP.blockmatrix,), block)
CSDP.triu(block)


text:
using SModels
using ScikitLearn
using ScikitLearn.GridSearch: GridSearchCV
using JLD, PyCallJLD
@sk_import neural_network: MLPClassifier
@sk_import neural_network: MLPRegressor
@sk_import preprocessing: StandardScaler
@sk_import metrics: accuracy_score

@static if VERSION < v"0.7.0-DEV.2005"
    using Base.Test
else
    using Test
end

srand(1234)

# This line should fail:
# @test 1 == 2

# Can we reproduce a basic example?
@testset "Testing Examples ScikitLearn.jl" begin

    X = [[0., 0.], [1., 1.]]
    y = [0, 1]

    clf = MLPClassifier(solver="lbfgs", alpha=1e-5,
                     hidden_layer_sizes=(5, 2), random_state=1)

    fit!(clf, X, y)

    res = predict(clf, [[2., 2.], [-1., -2.]])

    @test res[1] == 1
    @test res[2] == 0

    # Saving and loading
    #-------------------
    JLD.save("clf.jld", "clf", clf)
    clfloaded = JLD.load("clf.jld", "clf")

    res = predict(clfloaded, [[2., 2.], [-1., -2.]])

    @test res[1] == 1
    @test res[2] == 0

end

@testset "Testing generic functions" begin

    # 2d->2d function we aim at fitting
    function trueFunction(x::Float64, y::Float64)
        [x^2 + y^2, exp(x)*cos(y)]
    end

    function trueFunction(z::Array{Float64,1})
        trueFunction(z[1], z[2])
    end

    # Function that fails  when z[2] > 0.5
    # to test if the package is able to handle functions
    # that may fail
    function trueFunctionRisk(z::Array{Float64,1})
        if z[2] < 0.5
            return trueFunction(z[1], z[2])
        else
            error("Failure of trueFunctionRisk.")
        end
    end

    # create an input matrix
    function createX(;dimInput = 2, lowerBoundX = -1.0, lowerBoundY = -1.0, upperBoundX = 1.0, upperBoundY = 1.0, nbPointsX = 10, nbPointsY = 10)

        # initialization
        X = Array{Array{Float64,1},1}(nbPointsX*nbPointsY)

        for (kIndex, tupleValue) in enumerate(collect(Iterators.product(linspace(lowerBoundX, upperBoundX, nbPointsX), linspace(lowerBoundY, upperBoundY, nbPointsY))))
            X[kIndex] = [tupleValue[1], tupleValue[2]]
        end

        return X

    end

    # create output matrix
    function createY(X::Array{Array{Float64,1},1}; dimOutput = 2)

        # initialization
        y = Array{Array{Float64,1},1}(size(X,1))

        # Looping over X
        for xIndex = 1:size(X,1)
            y[xIndex] = trueFunction(X[xIndex][1], X[xIndex][2])
        end

        return y

    end

    # create output matrix
    # penalty value when trueFunctionRisk fails
    function createYRisk(X::Array{Array{Float64,1},1}; dimOutput::Int64 = 2, penaltyValue::Float64 = 999.0)

        # initialization
        y = Array{Array{Float64,1},1}(size(X,1))

        # Looping over X
        for xIndex = 1:size(X,1)
          if X[xIndex][2] < 0.5
            y[xIndex] = trueFunction(X[xIndex][1], X[xIndex][2])
          else
            y[xIndex] = ones(dimOutput)*penaltyValue
          end

        end

        return y

    end

    @testset "Testing fitting a 2d->2d function" begin

        aTolMeanPerError = 0.05
        aTolMaxPerError = 1.0
        aTolScaled = 0.001

        #input
        X = createX()
        #ouptut
        y = createY(X)

        # splitting between train and test samples
        XTrain, XTest, yTrain, yTest = split_train_test(X, y, testRatio = false)

        # scaling
        scaler = StandardScaler()
        fit!(scaler, XTrain)
        XTrainScaled = transform(scaler, XTrain)
        XTestScaled = transform(scaler, XTest)

        # training network
        clfr = MLPRegressor(solver="lbfgs", alpha=1e-5, hidden_layer_sizes=(30, 30), random_state=1)
        fit!(clfr, XTrainScaled, yTrain)

        # Train set
        #----------
        yPredicted = predict(clfr, XTrainScaled)

        println("Mean Percentage Error Train Set = $(calculate_mean_per_error(yTrain, yPredicted))")
        println("Maximum Abs Percentage Error Train Set = $(calculate_maximum_abs_per_error(yTrain, yPredicted))")
        @test abs(calculate_mean_per_error(yTrain, yPredicted)) < aTolMeanPerError
        @test abs(calculate_maximum_abs_per_error(yTrain, yPredicted)) < aTolMaxPerError

        # Test set
        #---------
        yPredicted = predict(clfr, XTestScaled)

        println("Mean Percentage Error Test Set = $(calculate_mean_per_error(yTest, yPredicted))")
        println("Maximum Abs Percentage Error Test Set = $(calculate_maximum_abs_per_error(yTest, yPredicted))")
        @test abs(calculate_mean_per_error(yTest, yPredicted)) < aTolMeanPerError
        @test abs(calculate_maximum_abs_per_error(yTest, yPredicted)) < aTolMaxPerError

        yPredictedScaled = predict_one_obs_scaled(clfr, XTrainScaled[1,:])
        yPredictedUnscaled = predict_one_obs_unscaled(clfr, XTrain[1,:], scaler)

        #scaled versus unscaled observation
        @test yPredictedScaled ≈ yPredictedUnscaled atol = aTolScaled

    end

    #cross-validation to choose the hidden-layer
    #-------------------------------------------------
    @testset "Testing fitting a 2d->2d function tuning hyper-parameters" begin

        aTolMeanPerError = 0.05
        aTolMaxPerError = 2.5
        aTolScaled = 0.001

        #input
        X = createX()
        #ouptut
        y = createY(X)

        # splitting between train and test samples
        XTrain, XTest, yTrain, yTest = split_train_test(X, y, testRatio = false)

        # scaling
        scaler = StandardScaler()
        fit!(scaler, XTrain)
        XTrainScaled = transform(scaler, XTrain)
        XTestScaled = transform(scaler, XTest)

        gridsearch = GridSearchCV(MLPRegressor(solver="lbfgs", alpha=1e-5, random_state=1), Dict(:hidden_layer_sizes => ((10), (20), (30), (40), (10, 10), (10, 20), (10, 30), (20, 10), (20, 20), (20, 30), (30, 10), (30, 20), (30, 30))))
        fit!(gridsearch, X, y)
        println("Best hyper-parameters: $(gridsearch.best_params_)")

        # training network using the "best" hidden layer
        #-----------------------------------------------
        clfr = MLPRegressor(solver="lbfgs", alpha=1e-5, hidden_layer_sizes=gridsearch.best_params_[:hidden_layer_sizes], random_state=1)
        fit!(clfr, XTrainScaled, yTrain)

        # Train set
        #----------
        yPredicted = predict(clfr, XTrainScaled)

        println("Mean Percentage Error Train Set = $(calculate_mean_per_error(yTrain, yPredicted))")
        println("Maximum Abs Percentage Error Train Set = $(calculate_maximum_abs_per_error(yTrain, yPredicted))")
        @test abs(calculate_mean_per_error(yTrain, yPredicted)) < aTolMeanPerError
        @test abs(calculate_maximum_abs_per_error(yTrain, yPredicted)) < aTolMaxPerError

        # Test set
        #---------
        yPredicted = predict(clfr, XTestScaled)

        println("Mean Percentage Error Test Set = $(calculate_mean_per_error(yTest, yPredicted))")
        println("Maximum Abs Percentage Error Test Set = $(calculate_maximum_abs_per_error(yTest, yPredicted))")
        @test abs(calculate_mean_per_error(yTest, yPredicted)) < aTolMeanPerError
        @test abs(calculate_maximum_abs_per_error(yTest, yPredicted)) < aTolMaxPerError

        yPredictedScaled = predict_one_obs_scaled(clfr, XTrainScaled[1,:])
        yPredictedUnscaled = predict_one_obs_unscaled(clfr, XTrain[1,:], scaler)

        #scaled versus unscaled observation
        @test yPredictedScaled ≈ yPredictedUnscaled atol = aTolScaled

    end

    #cross-validation to choose the hidden-layer done "manually"
    #-----------------------------------------------------------
    @testset "Testing fitting a 2d->2d function manually tuning hyper-parameters" begin

        aTolMeanPerError = 0.05
        aTolMaxPerError = 2.5
        aTolScaled = 0.001

        #input
        X = createX()
        #ouptut
        y = createY(X)

        # splitting between train and test samples
        XTrain, XTest, yTrain, yTest = split_train_test(X, y, testRatio = false)

        # scaling
        scaler = StandardScaler()
        fit!(scaler, XTrain)
        XTrainScaled = transform(scaler, XTrain)
        XTestScaled = transform(scaler, XTest)

        d = Dict(:hidden_layer_sizes => ((10), (20), (30), (40), (10, 10), (10, 20), (10, 30), (20, 10), (20, 20), (20, 30), (30, 10), (30, 20), (30, 30)))
        bestMaxPerError = Inf
        bestParam = d[:hidden_layer_sizes][1]

        # Loop over hidden layers configuration
        # Looking fot the hidden layer configuration that minimizes the max error in the test set
        for (kIndex, kValue) in enumerate(d[:hidden_layer_sizes])

            println(kValue)
            clfr = MLPRegressor(solver="lbfgs", alpha=1e-5, hidden_layer_sizes = kValue, random_state=1)
            fit!(clfr, XTrainScaled, yTrain)

            yPredicted = predict(clfr, XTestScaled)
            maxPerErr = calculate_maximum_abs_per_error(yTest, yPredicted)

            if maxPerErr < bestMaxPerError
                bestMaxPerError = maxPerErr
                bestParam = kValue
            end

        end

        println("Best hyper-parameters: $(bestParam)")

        # training network using the "best" hidden layer
        #-----------------------------------------------
        clfr = MLPRegressor(solver="lbfgs", alpha=1e-5, hidden_layer_sizes=bestParam, random_state=1)
        fit!(clfr, XTrainScaled, yTrain)

        # Train set
        #----------
        yPredicted = predict(clfr, XTrainScaled)

        println("Mean Percentage Error Train Set = $(calculate_mean_per_error(yTrain, yPredicted))")
        println("Maximum Ans Percentage Error Train Set = $(calculate_maximum_abs_per_error(yTrain, yPredicted))")
        @test abs(calculate_mean_per_error(yTrain, yPredicted)) < aTolMeanPerError
        @test abs(calculate_maximum_abs_per_error(yTrain, yPredicted)) < aTolMaxPerError

        # Test set
        #---------
        yPredicted = predict(clfr, XTestScaled)

        println("Mean Percentage Error Test Set = $(calculate_mean_per_error(yTest, yPredicted))")
        println("Maximum Abs Percentage Error Test Set = $(calculate_maximum_abs_per_error(yTest, yPredicted))")
        @test abs(calculate_mean_per_error(yTest, yPredicted)) < aTolMeanPerError
        @test abs(calculate_maximum_abs_per_error(yTest, yPredicted)) < aTolMaxPerError

        yPredictedScaled = predict_one_obs_scaled(clfr, XTrainScaled[1,:])
        yPredictedUnscaled = predict_one_obs_unscaled(clfr, XTrain[1,:], scaler)

        #scaled versus unscaled observation
        @test yPredictedScaled ≈ yPredictedUnscaled atol = aTolScaled

    end

    #cross-validation to choose the hidden-layer done "manually"
    #-----------------------------------------------------------
    @testset "Testing package on 2d->1d function" begin

        function function_1d(z::Array{Float64,1})
          return cos(z[1])*exp(z[2])
        end

        # create output matrix
        function create_y_1d(X::Array{Array{Float64,1},1})

            y = zeros(size(X,1))

            # Looping over X
            for xIndex = 1:size(X,1)
                y[xIndex] = function_1d([X[xIndex][1], X[xIndex][2]])
            end

            return y
        end

        aTolMeanPerError = 0.05
        aTolMedianPerError = 0.05
        aTolMaxPerError = 0.5

        upperBoundX = [1.0; 1.0]
        lowerBoundX = [-1.0; -1.0]

        opts = SModelsOptions(sModelType = :MLPRegressor, classifierType = :MLPClassifier, batchSizeWorker = 10, desiredMinObs = 80)

        surrogatePb = SModelsProblem(lowerBound = lowerBoundX, #lower bound for the parameter space
                          upperBound = upperBoundX,                   #upper bound for the parameter space
                          dimX = 2,                #dimension of the input parameter
                          dimY = 1,                 #dimension of the output vector
                          options = opts)

        set_model_function!(surrogatePb, function_1d)

        # training the surrogate model
        surrogatem, classifier = train_surrogate_model(surrogatePb, verbose = true, saveToDisk = false, robust = true)

        #input
        X = createX()
        #ouptut
        y = create_y_1d(X)

        # non-robust:
        XScaled = transform(surrogatePb.scaler, X)
        yPredicted = predict(surrogatem, XScaled)
        # classifier:
        yConvergencePredicted = round.(Int64, predict(classifier, XScaled))

        println("Regressor:")
        println("Mean Percentage Different Set = $(calculate_mean_per_error(y, yPredicted))")
        println("Median Abs Percentage Different Set = $(calculate_median_abs_per_error(y, yPredicted))")
        println("Maximum Abs Percentage Error Different Set = $(calculate_maximum_abs_per_error(y, yPredicted))")

        @test calculate_mean_per_error(y, yPredicted) < aTolMeanPerError
        @test calculate_median_abs_per_error(y, yPredicted) < aTolMedianPerError
        @test calculate_maximum_abs_per_error(y, yPredicted) < aTolMaxPerError
        # Model never fails. The classsifier should predict this feature:
        @test sum(yConvergencePredicted) == length(yConvergencePredicted)

    end

    #cross-validation to choose the hidden-layer done "manually"
    #-----------------------------------------------------------
    @testset "Testing package on 2d->2d function" begin

        aTolMeanPerError = 0.05
        aTolMaxPerError = 1.2
        aTolScaled = 0.001

        upperBoundX = [1.0; 1.0]
        lowerBoundX = [-1.0; -1.0]

        opts = SModelsOptions(sModelType = :MLPRegressor, classifierType = :MLPClassifier, batchSizeWorker = 100, desiredMinObs = 100)

        surrogatePb = SModelsProblem(
                          lowerBound = lowerBoundX, #lower bound for the parameter space
                          upperBound = upperBoundX,                   #upper bound for the parameter space
                          dimX = 2,                #dimension of the input parameter
                          dimY = 2,                 #dimension of the output vector
                          options = opts)

        set_model_function!(surrogatePb, trueFunction)

        # training the surrogate model
        surrogatem, classifier = train_surrogate_model(surrogatePb, verbose = true, saveToDisk = false, robust = false)

        #input
        X = createX()
        #ouptut
        y = createY(X)

        # non-robust
        XScaled = transform(surrogatePb.scaler, X)
        yPredicted = predict(surrogatem, XScaled)

        # robust to model failures
        yPredictedRobust = predict_scaled_robust(surrogatem, classifier, XScaled,
                            nonConvergenceFlag = surrogatePb.options.nonConvergenceFlag,
                            convergenceFlag = surrogatePb.options.convergenceFlag,
                            penaltyValue = surrogatePb.options.penaltyValue)

        println("Regressor:")
        println("Mean Percentage Different Set = $(calculate_mean_per_error(y, yPredicted))")
        println("Maximum Abs Percentage Error Different Set = $(calculate_maximum_abs_per_error(y, yPredicted))")

        # Here the model cannot fail, so we should have the same results
        #---------------------------------------------------------------
        @test yPredicted == yPredictedRobust

    end

    @testset "Testing package on 2d->2d function that may fail" begin

        aTolMeanPerError = 0.05
        aTolMaxPerError = 1.2
        aTolScaled = 0.001

        upperBoundX = [1.0; 1.0]
        lowerBoundX = [-1.0; -1.0]

        # Need more observations to learn where the model fails
        # When the model fails, the output is a large positive value
        # This creates a large discontinuity
        opts = SModelsOptions(sModelType = :MLPRegressor, classifierType = :MLPClassifier,
                              nbBatches = 5, batchSizeWorker = 100,
                              desiredMinObs = 500, penaltyValue = 9.0)

        surrogatePb = SModelsProblem(    #function f:x -> y that we are trying to approximate
                          lowerBound = lowerBoundX, #lower bound for the parameter space
                          upperBound = upperBoundX,                   #upper bound for the parameter space
                          dimX = 2,                #dimension of the input parameter
                          dimY = 2,                 #dimension of the output vector
                          options = opts)

        set_model_function!(surrogatePb, trueFunctionRisk)

        # training the surrogate model, non-robust method
        surrogatem, classifier = train_surrogate_model(surrogatePb, verbose = true, robust = false)

        # training the surrogate model, robust method
        surrogatemRobust, classifierRobust = train_surrogate_model(surrogatePb, verbose = true, robust = true)

        # Test on a totally new sample:
        #-------------------------------
        #input
        X = createX()
        #ouptut
        y = createYRisk(X, penaltyValue = surrogatePb.options.penaltyValue)

        # non-robust: use normal scaler and ScikitLearn predict function
        #----------------------------------------------------------------
        XScaled = transform(surrogatePb.scaler, X)
        yPredicted = predict(surrogatem, XScaled)

        mean_per_error_non_robust = calculate_mean_per_error(y, yPredicted)
        median_per_error_non_robust = calculate_median_abs_per_error(y, yPredicted)
        max_per_error_non_robust = calculate_maximum_abs_per_error(y, yPredicted)

        # robust: use a different scaler
        #-------------------------------
        XScaledRobust = transform(surrogatePb.scalerRobust, X)
        # predict, but first check for convergence using a classifier:
        #-------------------------------------------------------------
        yPredictedRobust = predict_scaled_robust(surrogatemRobust, classifierRobust, XScaledRobust,
                                                nonConvergenceFlag = surrogatePb.options.nonConvergenceFlag,
                                                convergenceFlag = surrogatePb.options.convergenceFlag,
                                                penaltyValue = surrogatePb.options.penaltyValue)

        mean_per_error_robust = calculate_mean_per_error(y, yPredictedRobust)
        median_per_error_robust = calculate_median_abs_per_error(y, yPredictedRobust)
        max_per_error_robust = calculate_maximum_abs_per_error(y, yPredictedRobust)

        println("Regressor non-robust:")
        println("Mean Percentage Different Set = $(mean_per_error_non_robust)")
        println("Median Percentage Different Set = $(median_per_error_non_robust)")
        println("Maximum Abs Percentage Error Different Set = $(max_per_error_non_robust)")
        println("----------------------")
        println("Regressor robust:")
        println("Mean Percentage Different Set = $(mean_per_error_robust)")
        println("Median Percentage Different Set = $(median_per_error_robust)")
        println("Maximum Abs Percentage Error Different Set = $(max_per_error_robust)")

        # The robust option shoudl minimize the median percentage error:
        #---------------------------------------------------------------
        @test median_per_error_robust < median_per_error_non_robust

        # Not that the max percentage error is bigger with the non-robust option
        # This occurs because when the classifier makes a mistake : the penalty
        # value is wrongly returned.

    end

    @testset "Testing parallel capabilities" begin

        addprocs(3)

        listMeanPerErr = []
        listMaxPerErr = []

        for i = 1:3

            # with batchSizeWorker = 10
            #--------------------------
            @everywhere using SModels

            @everywhere upperBoundX = [1.0; 1.0]
            @everywhere lowerBoundX = [-1.0; -1.0]

            if i == 1
                @everywhere b = 10
            elseif i==2
                @everywhere b = 100
            else
                @everywhere b = 1000
            end
            @everywhere opts = SModelsOptions(sModelType = :MLPRegressor, batchSizeWorker = b, desiredMinObs = 20, nbBatches = 1)

            @everywhere surrogatePb = SModelsProblem(    #function f:x -> y that we are trying to approximate
                              lowerBound = lowerBoundX,  #lower bound for the parameter space
                              upperBound = upperBoundX,  #upper bound for the parameter space
                              dimX = 2,                  #dimension of the input parameter
                              dimY = 2,                  #dimension of the output vector
                              options = opts)

            # 2d->2d function we aim at fitting
            @everywhere function trueFunction(x::Float64, y::Float64)
                [x^2 + y^2, exp(x)*cos(y)]
            end

            @everywhere function trueFunction(z::Array{Float64,1})
                trueFunction(z[1], z[2])
            end

            set_model_function!(surrogatePb, trueFunction)

            # training the surrogate model
            surrogatem, classifier = train_surrogate_model(surrogatePb, verbose = true, saveToDisk = false, robust = false)

            #input
            X = createX()
            #ouptut
            y = createY(X)

            XScaled = transform(surrogatePb.scaler, X)

            yPredicted = predict(surrogatem, XScaled)

            append!(listMeanPerErr,calculate_mean_per_error(y, yPredicted))
            append!(listMaxPerErr, calculate_maximum_abs_per_error(y, yPredicted))

            println("Regressor:")
            println("Mean Percentage Different Set = $(calculate_mean_per_error(y, yPredicted))")
            println("Maximum Abs Percentage Error Different Set = $(calculate_maximum_abs_per_error(y, yPredicted))")

        end

        # More points should be converted to more precise surrogate models
        @test abs(listMeanPerErr[1]) > abs(listMeanPerErr[3])
        @test abs(listMaxPerErr[1]) > abs(listMaxPerErr[3])

    end

end


text:
module MakieLayout

using AbstractPlotting
using AbstractPlotting: Rect2D
import AbstractPlotting: IRect2D
using AbstractPlotting.Keyboard
using AbstractPlotting.Mouse
using AbstractPlotting: ispressed, is_mouseinside
using Observables: onany
import Observables
import Formatting
using Match
import Animations

include("types.jl")
include("gridlayout.jl")
include("helpers.jl")
include("mousestatemachine.jl")
include("geometry_integration.jl")
include("layout_engine.jl")
include("makie_integration.jl")
include("ticklocators/linear.jl")
include("defaultattributes.jl")
include("lineaxis.jl")
include("lobjects/laxis.jl")
include("lobjects/lcolorbar.jl")
include("lobjects/ltext.jl")
include("lobjects/lslider.jl")
include("lobjects/lbutton.jl")
include("lobjects/lrect.jl")
include("lobjects/ltoggle.jl")
include("lobjects/llegend.jl")
include("lobjects/lobject.jl")
include("lobjects/lscene.jl")
include("gridapi.jl")

export LAxis
export LSlider
export LButton
export LColorbar
export LText
export LRect
export LToggle
export LLegend
export LScene
export linkxaxes!, linkyaxes!, linkaxes!
export GridLayout, GridPosition
export ProtrusionLayout
export BBox
export solve
export shrinkbymargin
export applylayout
export Inside, Outside, Mixed
export Fixed, Auto, Relative, Aspect
export FixedSizeBox
export FixedHeightBox
export width, height, top, bottom, left, right
export with_updates_suspended
export appendcols!, appendrows!, prependcols!, prependrows!, deletecol!, deleterow!, trim!
export gridnest!
export AxisAspect, DataAspect
export autolimits!
export AutoLinearTicks, ManualTicks, CustomTicks
export hidexdecorations!, hideydecorations!
export tight_xticklabel_spacing!, tight_yticklabel_spacing!, tight_ticklabel_spacing!, tightlimits!
export colsize!, rowsize!, colgap!, rowgap!
export Left, Right, Top, Bottom, TopLeft, BottomLeft, TopRight, BottomRight
export LegendEntry, LineElement, MarkerElement, PolyElement
export grid!, hbox!, vbox!
export layoutscene
export swap!

const FPS = Node(30)
const COLOR_ACCENT = Ref(RGBf0(((79, 122, 214) ./ 255)...))
const COLOR_ACCENT_DIMMED = Ref(RGBf0(((174, 192, 230) ./ 255)...))

end # module


text:
using MAT
using jInv.Mesh
using jInv.LinearSolvers
using jInv.ForwardShare
using jInv.InverseSolve
using jInv.Utils
using ArgParse
using OED

function parse_commandline()
	s = ArgParseSettings()

	@add_arg_table s begin

	"--matfile"
		help = "matlab file storing problem description"
	"--exName"
		help = "name of example"
	"--model"
		help = "model function. Choose: 1-> parallelTomo, 2->identity"
		arg_type = Int
		default = 1
	"--IPmode"
		help = "inverse problem model. Choose: 0->unconstrained, 1->eqconstrained, 2->nonneq, 3->box "
		arg_type = Int
		default = 0
	"--alphaMin"
		help = "minimum regularization parameter for sparsity"
		default = "1e-10"
	"--alphaMax"
		help = "maximum regularization parameter for sparsity"
		default = "1e-1"
	"--nAlpha"
		help = "number of alphas"
		arg_type = Int
		default = 5
	"--maxIter"
		help = "maximum number of iteration"
		arg_type = Int
		default = 20
	"--noiseLevel"
		help = "noiseLevel"
		default = "1e-3"
	"--nex"
		help = "Number of examples. If -1 all examples will be used. Otherwise nEx examples will be randomly choosen"
		arg_type=Int
		default =-1
	end
	return parse_args(s)
end

function main()
	parsed_args = parse_commandline()

	matfile = matread(parsed_args["matfile"])
	A       = matfile["A"]

	if haskey(matfile,"L")
		L = matfile["L"]
		if size(L,2) != size(A,2)
			error("user supplied L has wrong size")
		end
	else
		L = speye(size(A,2))
	end
	Xtrue   = matfile["x_true"]
	B       = A*Xtrue
	theta   = matfile["theta"]
	nt      = length(theta)
	n       = Int(matfile["n"])
	nex     = parsed_args["nex"]

	Ce = matfile["Ce"]
	ce = Ce*Xtrue
	Ci = matfile["Ci"]
	ci = matfile["ci"]

	if nex!==-1
idx = 1:nex
		# idx = randperm(size(Xtrue,2))[1:nex]
		Xtrue = Xtrue[:,idx]
		B     = B[:,idx]
		ce    = ce[:,idx]
		ci    = ci[:,idx]
	end

	exName  = parsed_args["exName"]

	if parsed_args["model"] == 1 # parallel projections
		l      = round(Int64,size(A,1)/nt)
		modFun = v->parallelTomoMod(v,l)
		m0     = ones(nt)
		model  = :parallel
	elseif parsed_args["model"] == 2 # identity
		modFun = identityMod
		m0     = ones(size(A,1))
		model  = :identity
	end

	ipDict  = Dict(0=>:unconstr, 1=>:eqconstr, 2=>:nonnegconstr, 3=>:boxconstr)
	IPmode  = ipDict[parsed_args["IPmode"]]

	maxIter = parsed_args["maxIter"]
	# add noise
	noiseLevel = parse(parsed_args["noiseLevel"])
	N  = randn(size(B));
	N /= norm(vec(N));
	N = noiseLevel*norm(vec(B))*N
	B += N

	# divide problems among available workers
	ids = mod(0:size(Xtrue,2)-1,nworkers())+1
	OEDparam = Array{OEDTypeAParam}(nworkers())
	for k=1:nworkers()
		OEDparam[k] = OEDTypeAParam(A,B[:,ids.==k],zeros(0,0))
	end

	alphaMin = parse(parsed_args["alphaMin"])
	alphaMax = parse(parsed_args["alphaMax"])
	nAlpha   = parsed_args["nAlpha"]
	Alphas   = logspace(log10(alphaMin),log10(alphaMax),nAlpha)
	println("Alphas = $Alphas")

	runOEDTypeA(OEDparam,Xtrue,L,Alphas,modFun,IPmode,m0,Ce=Ce,Ci=Ci,ce=ce,ci=ci,maxIter=maxIter,exName=@sprintf "%s-%s-noise-%1.2e" exName model noiseLevel)

end

main()


text:
using Bootstrap

## COPY
function Base.copy(d::NamedTuple{(:X, :Y), Tuple{FreqTab, FreqTab}})
    return (X = copy(d.X), Y = copy(d.Y))
end

function Base.copy(t::FreqTab)
    FreqTab(
        copy(t.table),
        copy(t.raw),
        copy(t.interval),
        merge(t.stats)
    )
end

function copy(x::SGEquateResult)
    SGEquateResult(
        x.method,
        copy(x.table),
        isnothing(x.estimates) ? nothing : merge(x.estimates),
        copy(x.data)
    )
end

function Base.copy(d::NamedTuple{(:X, :Y), Tuple{NEATFreqTab, NEATFreqTab}})
    return (X = copy(d.X), Y = copy(d.Y))
end

function Base.copy(t::NEATFreqTab)
    NEATFreqTab(
        copy(t.tableX),
        copy(t.tableV),
        copy(t.rawX),
        copy(t.rawV),
        copy(t.intervalX),
        copy(t.intervalV),
        copy(t.marginal),
        merge(t.statsX),
        merge(t.statsV),
    )
end

function copy(x::NEATEquateResult)
    NEATEquateResult(
        x.method,
        copy(x.table),
        copy(x.synthetic),
        isnothing(x.estimates) ? nothing : merge(x.estimates),
        copy(x.data)
    )
end

##

function initialize!(t::FreqTab)
    t.table.freq .= zero(eltype(t.table.freq))
    t.table.cumfreq .= zero(eltype(t.table.cumfreq))
    t.table.prob .= zero(eltype(t.table.prob))
    t.table.cumprob .= zero(eltype(t.table.cumprob))
end

function initialize!(t::NEATFreqTab)
    # X
    t.tableX.freq .= zero(eltype(t.tableX.freq))
    t.tableX.cumfreq .= zero(eltype(t.tableX.cumfreq))
    t.tableX.prob .= zero(eltype(t.tableX.prob))
    t.tableX.cumprob .= zero(eltype(t.tableX.cumprob))
    # V
    t.tableV.freq .= zero(eltype(t.tableV.freq))
    t.tableV.cumfreq .= zero(eltype(t.tableV.cumfreq))
    t.tableV.prob .= zero(eltype(t.tableV.prob))
    t.tableV.cumprob .= zero(eltype(t.tableV.cumprob))
end

"""
    recalculate!(t::FreqTab)
Re-calculate `FreqTab` by using renewd raw vector. `interval` and the scale in table will not be changes.
"""
function recalculate!(t::FreqTab)
    t.stats = basicstats(t.raw)
    initialize!(t)
    freq = map(j -> count(i -> i == j, t.raw), t.table.scale)
    cumfreq = cumsum(freq)
    cumprob = cumsum(freq) ./ sum(freq)
    prob = freq ./ sum(freq)
    cumprob = cumprob
    for (i, s) in enumerate(freq)
        loc = [i]
        t.table[loc, :freq] .= freq[i]
        t.table[loc, :cumfreq] .= cumfreq[i]
        t.table[loc, :prob] .= prob[i]
        t.table[loc, :cumprob] .= cumprob[i]
    end
    return
end

function recalculate!(t::NEATFreqTab, form = ["X", "V"])
    t.statsX = basicstats(t.rawX)
    t.statsV = basicstats(t.rawV)
    initialize!(t)
    if "X" ∈ form
        # X
        freq = map(j -> count(i -> i == j, t.rawX), t.tableX.scale)
        cumfreq = cumsum(freq)
        cumprob = cumsum(freq) ./ sum(freq)
        prob = freq ./ sum(freq)
        cumprob = cumprob
        for (i, s) in enumerate(freq)
            loc = [i]
            t.tableX[loc, :freq] .= freq[i]
            t.tableX[loc, :cumfreq] .= cumfreq[i]
            t.tableX[loc, :prob] .= prob[i]
            t.tableX[loc, :cumprob] .= cumprob[i]
        end
    end
    if "V" ∈ form
        # V
        freq = map(j -> count(i -> i == j, t.rawV), t.tableV.scale)
        cumfreq = cumsum(freq)
        cumprob = cumsum(freq) ./ sum(freq)
        prob = freq ./ sum(freq)
        cumprob = cumprob
        for (i, s) in enumerate(freq)
            loc = [i]
            t.tableV[loc, :freq] .= freq[i]
            t.tableV[loc, :cumfreq] .= cumfreq[i]
            t.tableV[loc, :prob] .= prob[i]
            t.tableV[loc, :cumprob] .= cumprob[i]
        end
    end
    return
end

# Attach methods to functions in  bootstrab.jl

function Bootstrap.draw!(x::NamedTuple{(:X, :Y), Tuple{T, T}}, o::NamedTuple{(:X, :Y), Tuple{T, T}}) where {T <: FreqTab}
    idx = sample(examineeID(x.X.raw), length(x.X.raw))
    idy = sample(examineeID(x.Y.raw), length(x.Y.raw))
    for (to, from) in enumerate(idx)
        o.X.raw[to] = x.X.raw[from]
    end
    for (to, from) in enumerate(idy)
        o.Y.raw[to] = x.Y.raw[from]
    end
    # Re-evaluate freqtab
    recalculate!(o.X)
    recalculate!(o.Y)
end

function Bootstrap.draw!(x::NamedTuple{(:X, :Y), Tuple{T, T}}, o::NamedTuple{(:X, :Y), Tuple{T, T}}) where {T <: NEATFreqTab}
    idx = sample(examineeID(x.X.rawX), length(x.X.rawX))
    idy = sample(examineeID(x.Y.rawX), length(x.Y.rawX))
    for (to, from) in enumerate(idx)
        o.X.rawX[to] = x.X.rawX[from]
        o.X.rawV[to] = x.X.rawV[from]
    end
    for (to, from) in enumerate(idy)
        o.Y.rawX[to] = x.Y.rawX[from]
        o.Y.rawV[to] = x.Y.rawV[from]
    end
    # Re-evaluate freqtab
    recalculate!(o.X)
    recalculate!(o.Y)
end

function Base.size(x::NamedTuple{(:X, :Y), Tuple{T, T}}) where {T <: FreqTab}
    "X $(x.X.stats.N)", "Y $(x.Y.stats.N)"
end

function Base.size(x::NamedTuple{(:X, :Y), Tuple{T, T}}) where {T <: NEATFreqTab}
    "X.Main $(x.X.statsX.N)", "X.Common $(x.X.statsV.N)", "Y.Main $(x.Y.statsX.N)", "Y.Main $(x.Y.statsV.N)"
end

# Standard Equating method

examineeID(X) = range(1, length = length(X))

"""
    bootSE()
Estimate bootstrap standard error of equating (SEE).

The definition of SEE is the standard deviation of equating results (i.e. In linear equating, the slope and intercept).
The source of SEE is random error in data. Furthermore, the source of random error is specified by the data collection design, the method of equatings and the sample size.
"""
function bootSE()

end


text:
module DaprClient

include("http_client.jl")

end # module


text:
include("image.jl")

water_backgrounds = [Image(readpng("procgen/data/assets/water_backgrounds/water1.png")),
    Image(readpng("procgen/data/assets/water_backgrounds/water2.png")),
    Image(readpng("procgen/data/assets/water_backgrounds/water3.png")),
    Image(readpng("procgen/data/assets/water_backgrounds/water4.png")),
    Image(readpng("procgen/data/assets/water_backgrounds/underwater1.png")),
    Image(readpng("procgen/data/assets/water_backgrounds/underwater2.png")),
    Image(readpng("procgen/data/assets/water_backgrounds/underwater3.png"))]

sprites = Dict([("misc_assets/fishTile_072.png", Image(readpng("procgen/data/assets/misc_assets/fishTile_072.png"))),
    ("misc_assets/fishTile_074.png", Image(readpng("procgen/data/assets/misc_assets/fishTile_074.png"))),
    ("misc_assets/fishTile_078.png", Image(readpng("procgen/data/assets/misc_assets/fishTile_078.png"))),
    ("misc_assets/fishTile_080.png", Image(readpng("procgen/data/assets/misc_assets/fishTile_080.png"))),])

function get_asset_ptr(relpath::String)

    return get!(sprites, relpath, Image())
end


text:
fname = :TRMA57_abs
c = Combi(hessian_sparse,PDataMA57,solve_modelTRDiagAbs,preprocessMA57,decreaseFact,Tparam())
include("Template.jl")


text:
## SPLITTING DATA SETS

"""
    partition(rows::AbstractVector{Int}, fractions...; shuffle=false, rng=Random.GLOBAL_RNG)

Splits the vector `rows` into a tuple of vectors whose lengths are
given by the corresponding `fractions` of `length(rows)`. The last
fraction is not provided, as it is inferred from the preceding
ones. So, for example,

    julia> partition(1:1000, 0.2, 0.7)
    (1:200, 201:900, 901:1000)

If `rng` is an integer, then `MersenneTwister(rng)` is the random
number generator used for bagging. Otherwise some `AbstractRNG` object
is expected.

"""
function partition(rows::AbstractVector{Int}, fractions...; shuffle::Bool=false, rng=Random.GLOBAL_RNG)
    rows = collect(rows)

    if rng isa Integer
        rng = MersenneTwister(rng)
    end

    shuffle && shuffle!(rng, rows)
    rowss = []
    if sum(fractions) >= 1
        throw(DomainError)
    end
    n_patterns = length(rows)
    first = 1
    for p in fractions
        n = round(Int, p*n_patterns)
        n == 0 ? (@warn "A split has only one element"; n = 1) : nothing
        push!(rowss, rows[first:(first + n - 1)])
        first = first + n
    end
    if first > n_patterns
        @warn "Last vector in the split has only one element."
        first = n_patterns
    end
    push!(rowss, rows[first:n_patterns])
    return tuple(rowss...)
end

"""
    t1, t2, ...., tk = unnpack(table, t1, t2, ... tk; wrap_singles=false)

Split any Tables.jl compatible `table` into smaller tables (or
vectors) `t1, t2, ..., tk` by making selections *without replacement*
from the column names defined by the tests `t1`, `t2`, ...,
`tk`. A *test* is any object `t` such that `t(name)` is `true`
or `false` for each column `name::Symbol` of `table`.

Whenever a returned table contains a single column, it is converted to
a vector unless `wrap_singles=true`.

Scientific type conversions can be optionally specified (note
semicolon):

    unpack(table, t...; wrap_singles=false, col1=>scitype1, col2=>scitype2, ... )

### Example

```
julia> table = DataFrame(x=[1,2], y=['a', 'b'], z=[10.0, 20.0], w=[:A, :B])
julia> Z, XY = unpack(table, ==(:z), !=(:w);
               :x=>Continuous, :y=>Multiclass)
julia> XY
2×2 DataFrame
│ Row │ x       │ y            │
│     │ Float64 │ Categorical… │
├─────┼─────────┼──────────────┤
│ 1   │ 1.0     │ 'a'          │
│ 2   │ 2.0     │ 'b'          │

julia> Z
2-element Array{Float64,1}:
 10.0
 20.0
```
"""
function unpack(X, tests...; wrap_singles=false, pairs...)

    if isempty(pairs)
        Xfixed = X
    else
        Xfixed = ScientificTypes.coerce(X, pairs...)
    end

    unpacked = Any[]
    names_left = schema(Xfixed).names |> collect
    history = ""
    counter = 1
    for c in tests
        names = filter(c, names_left)
        filter!(!in(names), names_left)
        history *= "selection $counter: $names\n remaining: $names_left\n"
        isempty(names) &&
            error("Empty column selection encountered at selection $counter"*
                  "\n$history")
        length(names) == 1 && !wrap_singles && (names = names[1])
        push!(unpacked, selectcols(Xfixed, names))
        counter += 1
    end
    return Tuple(unpacked)
end

## DEALING WITH CATEGORICAL ELEMENTS

const CategoricalElement{U} = Union{CategoricalValue{<:Any,U},CategoricalString{U}}

"""
    classes(x)

All the categorical elements with in the same pool as `x` (including `x`),
returned as a list, with an ordering consistent with the pool. Here
`x` has `CategoricalValue` or `CategoricalString` type, and
`classes(x)` is a vector of the same eltype.

Not to be confused with the levels of `x.pool` which have a
different type. In particular, while `x in classes(x)` is always
true, `x in x.pool.levels` is not true.

    julia> v = categorical([:c, :b, :c, :a])
    julia> levels(v)
    3-element Array{Symbol,1}:
     :a
     :b
     :c
    julia> classes(v[4])
    3-element Array{CategoricalValue{Symbol,UInt32},1}:
     :a
     :b
     :c

"""
classes(p::CategoricalPool) = [p.valindex[p.invindex[v]] for v in p.levels]
classes(x::CategoricalElement) = classes(x.pool)

"""
   int(x)

The positional integer of the `CategoricalString` or `CategoricalValue`
`x`, in the ordering defined by the pool of `x`. The type of `int(x)`
is the refrence type of `x`.

Not to be confused with `x.ref`, which is unchanged by reordering of
the pool of `x`, but has the same type.

    int(X::CategoricalArray)
    int(W::Array{<:CategoricalString})
    int(W::Array{<:CategoricalValue})

Broadcasted versions of `int`.

    julia> v = categorical([:c, :b, :c, :a])
    julia> levels(v)
    3-element Array{Symbol,1}:
     :a
     :b
     :c
    julia> int(v)
    4-element Array{UInt32,1}:
     0x00000003
     0x00000002
     0x00000003
     0x00000001

See also: [`decoder`](@ref).
"""
int(x::CategoricalElement) = x.pool.order[x.pool.invindex[x]]
int(A::AbstractArray) = broadcast(int, A)

# get the integer representation of a level given pool (private
# method):
int(pool::CategoricalPool, level) =  pool.order[pool.invindex[level]]

struct CategoricalDecoder{T,R} # <: MLJType
    pool::CategoricalPool{T,R}
    invorder::Vector{Int}
end

"""
    d = decoder(x)

A callable object for decoding the integer representation of a
`CategoricalString` or `CategoricalValue` sharing the same pool as
`x`. (Here `x` is of one of these two types.) Specifically, one has
`d(int(y)) == y` for all `y in classes(x)`. One can also call `d` on
integer arrays, in which case `d` is broadcast over all elements.

    julia> v = categorical([:c, :b, :c, :a])
    julia> int(v)
    4-element Array{UInt32,1}:
     0x00000003
     0x00000002
     0x00000003
     0x00000001
    julia> d = decoder(v[3])
    julia> d(int(v)) == v
    true

*Warning:* It is *not* true that `int(d(u)) == u` always holds.

See also: [`int`](@ref), [`classes`](@ref).
"""
decoder(element::CategoricalElement) =
    CategoricalDecoder(element.pool, sortperm(element.pool.order))

(decoder::CategoricalDecoder{T,R})(i::Integer) where {T,R} =
    CategoricalValue{T,R}(decoder.invorder[i], decoder.pool)
(decoder::CategoricalDecoder{String,R})(i::Integer) where R =
    CategoricalString{R}(decoder.invorder[i], decoder.pool)
(decoder::CategoricalDecoder)(I::AbstractArray{<:Integer}) = broadcast(decoder, I)

## TABULAR DATA

# hack for detecting JuliaDB.NDSparse tables without loading as dependency:
# isndsparse(X) = isdefined(X, :data_buffer)

## UTILITY FOR CONVERTING BETWEEN TABULAR DATA AND MATRICES

"""
    MLJBase.matrix(X; transpose=false)

Convert a Tables.jl compatible table source `X` into an `Matrix`; or,
if `X` is a `AbstractMatrix`, return `X`. Optimized for column-based
sources. Rows of the table or input matrix, correspond to rows of the
output, unless `transpose=true`.
"""
matrix(X; kwargs...) = matrix(Val(ScientificTypes.trait(X)), X; kwargs...)
matrix(::Val{:other}, X; kwargs...) = throw(ArgumentError)
matrix(::Val{:other}, X::AbstractMatrix; transpose=false) =
    transpose ? permutedims(X) : X

matrix(::Val{:table}, X; kwargs...) = Tables.matrix(X; kwargs...)

# matrix(::Val{:table, X)
#     cols = Tables.columns(X) # property-accessible object
#     mat = reduce(hcat, [getproperty(cols, ftr) for ftr in propertynames(cols)])
#     # tightest eltype:
#     return broadcast(identity, mat)
# end

# function matrix(::Val{:sparse}, X)
#     K = keys(X)
#     features = schema(X).names
#     index_given_feature = Dict{Symbol,Int}()
#     for j in eachindex(features)
#         index_given_feature[features[j]] = j
#     end
#     I = [k[1] for k in K]
#     J = [index_given_feature[k[2]] for k in K]
#     V = [v[1] for v in values(X)]
#     return sparse(I, J, V)
# end

"""
    MLJBase.table(columntable; prototype=nothing)

Convert a named tuple of vectors or tuples `columntable`, into a table
of the "preferred sink type" of `prototype`. This is often the type of
`prototype` itself, when `prototype` is a sink; see the Tables.jl
documentation. If `prototype` is not specified, then a named tuple of
vectors is returned.

    MLJBase.table(A::AbstractMatrix; names=nothing, prototype=nothing)

Wrap an abstract matrix `A` as a Tables.jl compatible table with the
specified column `names` (a tuple of symbols). If `names` are not
specified, `names=(:x1, :x2, ..., :xn)` is used, where `n=size(A, 2)`.

If a `prototype` is specified, then the matrix is materialized as a
table of the preferred sink type of `prototype`, rather than
wrapped. Note that if `protottype` is *not* specified, then
`MLJ.matrix(MLJ.table(A))` is essentially a non-operation.
"""
function table(cols::NamedTuple; prototype=NamedTuple())
    Tables.istable(prototype) || error("`prototype` is not a table. ")
    if !Tables.istable(cols)
        tuple_of_vectors = Tuple([collect(v) for v in values(cols)])
        names = keys(cols)
        cols = NamedTuple{names}(tuple_of_vectors)
        Tables.istable(cols) || throw(ArgumentError(""))
    end
    return Tables.materializer(prototype)(cols)
end
function table(A::AbstractMatrix; names=nothing, prototype=nothing)
    if names == nothing
        _names = [Symbol(:x, j) for j in 1:size(A, 2)]
    else
        _names = collect(names)
    end
    matrix_table = Tables.table(A, header=_names)
    if prototype === nothing
        return matrix_table
    else
        return Tables.materializer(prototype)(matrix_table)
    end
end

## UNIFIED API FOR ACCESSING TABLES, MATRICES AND VECTORS

"""
    selectrows(X, r)

Select single or multiple rows from any table, or abstract vector `X`,
or matrix.  If `X` is tabular, the object returned is a table of the
preferred sink type of `typeof(X)`, even if only a single row is selected.

"""
selectrows(X, r) = selectrows(Val(ScientificTypes.trait(X)), X, r)
selectrows(::Val{:other}, X, r) = throw(ArgumentError)

"""
    selectcols(X, c)

Select single or multiple columns from any table or matrix `X`. If `c`
is an abstract vector of integers or symbols, then the object returned
is a table of the preferred sink type of `typeof(X)`. If `c` is a
*single* integer or column, then an `AbstractVector` is returned.

"""
selectcols(X, c) = selectcols(Val(ScientificTypes.trait(X)), X, c)
selectcols(::Val{:other}, X, c) = throw(ArgumentError)

"""
    select(X, r, c)

Select element of a table or matrix at row `r` and column
`c`. In the case of sparse data where the key `(r, c)`, zero or
`missing` is returned, depending on the value type.

See also: [`selectrows`](@ref), [`selectcols`](@ref).

"""
select(X, r, c) = select(Val(ScientificTypes.trait(X)), X, r, c)
select(::Val{:other}, X, r, c) = throw(ArgumentError)

"""
    nrows(X)

Return the number of rows in a table, abstract vector or abstract
matrix.

"""
nrows(X) = nrows(Val(ScientificTypes.trait(X)), X)
nrows(::Val{:other}, X) = throw(ArgumentError)

# project named tuple onto a tuple with only specified `labels` or indices:
project(t::NamedTuple, labels::AbstractArray{Symbol}) = NamedTuple{tuple(labels...)}(t)
project(t::NamedTuple, label::Colon) = t
project(t::NamedTuple, label::Symbol) = project(t, [label,])
project(t::NamedTuple, indices::AbstractArray{<:Integer}) =
    NamedTuple{tuple(keys(t)[indices]...)}(tuple([t[i] for i in indices]...))
project(t::NamedTuple, i::Integer) = project(t, [i,])

# multiple columns:
function selectcols(::Val{:table}, X, c::Union{Colon, AbstractArray{I}}) where I<:Union{Symbol,Integer}
    cols = Tables.columntable(X) # named tuple of vectors
    newcols = project(cols, c)
    return Tables.materializer(X)(newcols)
end

# single column:
function selectcols(::Val{:table}, X, c::I) where I<:Union{Symbol,Integer}
    cols = Tables.columntable(X) # named tuple of vectors
    return cols[c]
end

# multiple rows (using columntable):
function selectrows(::Val{:table}, X, r::Union{Colon,AbstractVector{<:Integer}})
    cols = Tables.columntable(X)
    new_cols = NamedTuple{keys(cols)}(tuple([c[r] for c in values(cols)]...))
    return Tables.materializer(X)(new_cols)
end

# single row (using columntable):
function selectrows(::Val{:table}, X, r::Integer)
    cols = Tables.columntable(X)
    new_cols = NamedTuple{keys(cols)}(tuple([c[r:r] for c in values(cols)]...))
    return Tables.materializer(X)(new_cols)
end

## ALTERNATIVE CODE FOR PREVIOUS TWO FUNCTIONS.
## ROWTABLE SELECTION OF ROWS INSTEAD OF COLUMNTABLE SELECTION
# # multiple rows:
# function selectrows(::Val{:table}, X, r::Union{Colon,AbstractVector{<:Integer}})
#     rows = Tables.rowtable(X) # vector of named tuples
#     return Tables.materializer(X)(rows[r])
# end

# # single row:
# function selectrows(::Val{:table}, X, r::Integer)
#     rows = Tables.rowtable(X) # vector of named tuples
#     return Tables.materializer(X)([rows[r]])
# end

select(::Val{:table}, X, r::Integer, c::Symbol) = selectcols(selectrows(X, r), c)[1]
select(::Val{:table}, X, r::Integer, c) = selectcols(selectrows(X, r), c)
select(::Val{:table}, X, r, c::Symbol) = selectcols(X, c)[r]
select(::Val{:table}, X, r, c) = selectcols(selectrows(X, r), c)

nrows(::Val{:table}, X) = schema(X).nrows

## ACCESSORS FOR ABSTRACT VECTORS

selectrows(::Val{:other}, v::AbstractVector, r) = v[r]
selectrows(::Val{:other}, v::CategoricalVector, r) = @inbounds v[r]

# single row selection must return a matrix!
selectrows(::Val{:other}, v::AbstractVector, r::Integer) = v[r:r]
selectrows(::Val{:other}, v::CategoricalVector, r::Integer) = @inbounds v[r:r]

nrows(::Val{:other}, v::AbstractVector) = length(v)

## ACCESSORS FOR ABSTRACT MATRICES

selectrows(::Val{:other}, A::AbstractMatrix, r) = A[r, :]
selectrows(::Val{:other}, A::CategoricalMatrix, r) = @inbounds A[r, :]

# single row selection must return a matrix!
selectrows(::Val{:other}, A::AbstractMatrix, r::Integer) = A[r:r, :]
selectrows(::Val{:other}, A::CategoricalMatrix, r::Integer) =
    @inbounds A[r:r, :]

nrows(::Val{:other}, A::AbstractMatrix) = size(A, 1)

## to be replaced (not used anywhere):
## ACCESSORS FOR JULIA NDSPARSE ARRAYS (N=2)

# nrows(::Val{:sparse}, X) = maximum([r[1] for r in keys(X)])
# function select(::Val{:sparse}, X, r::Integer, c::Symbol)
#     try
#         X[r,c][1]
#     catch exception
#         exception isa KeyError || throw(exception)
#         missing
#     end
# end
# select(::Val{:sparse}, X, r::AbstractVector{<:Integer}, c::Symbol) = [select(X, s, c) for s in r]
# select(::Val{:sparse}, X, ::Colon, c::Symbol) = [select(X, s, c) for s in 1:nrows(X)]
# selectrows(::Val{:sparse}, X, r::Integer) = X[r:r,:]
# selectrows(::Val{:sparse}, X, r) = X[r,:]
# selectcols(::Val{:sparse}, X, c::Symbol) = select(X, :, c)
# selectcols(::Val{:sparse}, X, c::AbstractVector{Symbol}) = X[:,sort(c)]
# selectcols(::Val{:sparse}, X, ::Colon) = X
# select(::Val{:sparse}, X, r::Integer, c::AbstractVector{Symbol}) = X[r,sort(c)]
# select(::Val{:sparse}, X, r::Integer, ::Colon) = X[r,:]
# select(::Val{:sparse}, X, r, c) = X[r,sort(c)]


text:
"""
    Prechelt

> Find a sequence of words such that the sequence of characters in these words exactly corresponds to the sequence of
> digits in the phone number. All possible solutions must be found and printed. The solutions are created word by word
> and if no word from the dictionary can be inserted at some point during that process, a single digit from the phone
> number can appear in the result at that position. Many phone numbers have no solution at all. Here is an example of
> the program output for the phone number “3586-75,” when the dictionary contained the words "Dali," "um," "Sao," "da,"
> "Pik," and 73,108 others:
>
>     3586-75: Dali um
>     3586-75: Sao 6 um
>     3586-75: da Pik 5
>
> A list of partial solutions needs to be maintained by the program while processing each number, and the dictionary
> must be embedded in a supporting data structure (such as a 10-ary digit tree) for efficient access.
>
>  -- <cite>Prechelt, Lutz. (1999). Comparing Java vs. C/C++ Efficiency Differences to Interpersonal Differences. Communications of the ACM. 42. 10.1145/317665.317683.</quote>

This implementation uses the [Aho-Corasick algorithm](https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm)
with two small specializations

    * words are mapped to digits as they are inserted in the Aho-Corasick data structure
    * the data structure uses fixed length arrays to minimize memory allocations

```jldoctest
julia> replaceall("358", ["Sao", "dal"])
1-element Vector{String}:
 "dal"

```
"""

const DIGITS = Vector{Int}(undef, 128)
DIGITS[codeunits("0123456789")] = 1:10
DIGITS[codeunits("ejnqrwxdsyftamcivbkulopghz")] = DIGITS[codeunits("01112223334455666777888999")]
DIGITS[codeunits("EJNQRWXDSYFTAMCIVBKULOPGHZ")] = DIGITS[codeunits("01112223334455666777888999")]

mutable struct Node
    depth::Int
    keys::Vector{String}
    next::Vector{Union{Missing,Node}}
    fail::Node

    function Node(depth::Int=0)
        node = new()
        node.depth = depth
        node.keys = String[]
        node.next = Vector{Union{Missing,Node}}(missing, 10)
        node
    end
end

digits(s::String) = DIGITS[codeunits(s)]

function insert!(node::Node, word::String)
    for digit ∈ digits(word)
        next = node.next[digit]
        if ismissing(node.next[digit])
            node.next[digit] = next = Node(node.depth + 1)
        end
        node = next
    end
    push!(node.keys, word)
end

function add_fail_transition!(node::Node)
    fail = node.fail
    for (index, next) ∈ enumerate(node.next)
        ismissing(next) && continue
        next.fail = coalesce(fail.next[index], fail)
    end
    for next ∈ skipmissing(node.next)
        add_fail_transition!(next)
    end
end

function search(node::Node, index::Int)
    coalesce(node.next[index], node.depth == 0 ? node : search(node.fail, index))
end

function aho_corasick(words::Union{Base.EachLine,Vector{String}})
    node = Node()
    node.fail = node
    for word ∈ words
        insert!(node, word)
    end
    for next ∈ skipmissing(node.next)
        next.fail = node
    end
    for next ∈ skipmissing(node.next)
        add_fail_transition!(next)
    end
    node
end

# varargs suppress StaticLint's "Possible method call error"
⊗(x...) = kron(x...)  # https://julialang.org/blog/2017/01/moredots/

function replaceall(number::String, node::Node)
    """
    ```jldoctest
    julia> replaceall("358675", ["Dali", "um", "Sao", "da", "Pik"])
    3-element Vector{String}:
     "Dalium"
     "Sao6um"
     "daPik5"

    ```
    """
    heads = Vector{Vector{String}}(undef, length(number))
    for (k, digit) ∈ enumerate(digits(number))
        node = next = search(node, digit)
        while length(next.keys) > 0
            rest = next.keys
            j = k - node.depth
            i = j - 1

            heads[k] = (
                isassigned(heads, i)
                ? [heads[j] ⊗ rest; heads[i] ⊗ (number[i:i] .* rest)]
                : isassigned(heads, j)
                ? heads[j] ⊗ rest
                : rest
            )
            next = next.fail
        end
    end
    filter(s -> count(r"\d", s) <= 1, [heads[end]; heads[end - 1] .* number[end:end]])
end

replaceall(number::String, words::Vector{String}) = replaceall(number, aho_corasick(words))

max_stars_repo_name: jburgy/blog

max_issues_repo_name: jburgy/blog

max_forks_repo_name: jburgy/blog


text:
# This file is based on a part of Julia. License is MIT: https://julialang.org/license

using QuasiArrays, Test
import Base: OneTo, Slice
import Base.Broadcast: check_broadcast_axes, newindex, broadcasted, broadcastable, Broadcasted, DefaultArrayStyle, BroadcastStyle
import QuasiArrays: QuasiCartesianIndex, QuasiCartesianIndices, DefaultQuasiArrayStyle, SubQuasiArray

@testset "Broadcasting" begin
    Z = QuasiArray(zeros(3,4),(0:0.5:1,0:3))
    z = QuasiArray(zeros(3),(0:0.5:1,))
    ax = (Inclusion(0:0.5:1),Slice(0:3))
    @test @inferred(Broadcast.combine_axes(Z,Z)) == ax
    @test @inferred(Broadcast.combine_axes(Z,z)) == ax
    @test @inferred(Broadcast.combine_axes(z,Z)) == ax
    @test_broken @inferred(Broadcast.combine_axes(z,Z, zeros(1))) == ax

    check_broadcast_axes(ax, Z)
    check_broadcast_axes(ax, z)
    check_broadcast_axes(ax, Z, z)
    check_broadcast_axes(ax, Z, 1)
    check_broadcast_axes(ax, 5, 2)
    @test_throws DimensionMismatch check_broadcast_axes(ax, zeros(2,5))
    @test_throws DimensionMismatch check_broadcast_axes(ax, zeros(3,4))
    @test_throws DimensionMismatch check_broadcast_axes(ax, zeros(3,4,2))
    @test_throws DimensionMismatch check_broadcast_axes(ax, zeros(3,5), zeros(2))

    ci(x) = QuasiCartesianIndex(x)
    @test @inferred(newindex(ci((2,2)), (true, true), (-1,-1)))   == ci((2,2))
    @test @inferred(newindex(ci((2,2)), (true, false), (-1,-1)))  == ci((2,-1))
    @test @inferred(newindex(ci((2,2)), (false, true), (-1,-1)))  == ci((-1,2))
    @test @inferred(newindex(ci((2,2)), (false, false), (-1,-1))) == ci((-1,-1))
    @test @inferred(newindex(ci((2,2)), (true,), (-1,-1)))   == ci((2,))
    @test @inferred(newindex(ci((2,2)), (true,), (-1,)))   == ci((2,))
    @test @inferred(newindex(ci((2,2)), (false,), (-1,))) == ci((-1,))
    @test @inferred(newindex(ci((2,2)), (), ())) == ci(())

    @test eltype(QuasiCartesianIndices(Inclusion.((0:0.1:1,0:0.2:1)))) == QuasiCartesianIndex{2,NTuple{2,Float64}}

    A = QuasiArray([1 0; 0 1], (0:0.5:0.5, 1:0.5:1.5))
    b = QuasiArray([1,2], (0:0.5:0.5,))
    @test @inferred(collect(eachindex(A))) == [QuasiCartesianIndex(0.0,1.0) QuasiCartesianIndex(0.0,1.5);
                                QuasiCartesianIndex(0.5,1.0) QuasiCartesianIndex(0.5,1.5)]
    @test collect(eachindex(A)) isa Matrix{QuasiCartesianIndex{2,NTuple{2,Float64}}}
    @test broadcastable(A) === A
    @test Base.BroadcastStyle(typeof(A)) === DefaultQuasiArrayStyle{2}()
    bc = broadcasted(+, A)
    @test bc isa Broadcasted{DefaultQuasiArrayStyle{2}}
    @test broadcast(+, A) == A
    @test broadcast(+, A, A) == QuasiArray([2 0; 0 2],A.axes)
    @test Base.BroadcastStyle(Base.BroadcastStyle(typeof(A)), Base.BroadcastStyle(Int)) == DefaultQuasiArrayStyle{2}()
    @test broadcast(+, A, 1) == QuasiArray([2 1; 1 2],A.axes)
    @test broadcast(+, A, b) == QuasiArray([2 1; 2 3],A.axes)
    A = QuasiArray([1 0; 0 1], (0:0.5:0.5, 1:0.5:1.5)); @test broadcast!(+, A, A, b) == QuasiArray([2 1; 2 3],A.axes)
    A = QuasiArray([1 0], (0:0, 1:0.5:1.5)); @test_throws DimensionMismatch broadcast!(+, A, A, b)
    A = QuasiArray([1 2], (0:0, 1:0.5:1.5)); B = QuasiArray([3,4], (0:0.5:0.5,));
    @test A .* B == QuasiArray([ 3 6; 4 8], (0:0.5:0.5,1:0.5:1.5))

    @testset "f.(args...) syntax (#15032)" begin
        x = QuasiVector([1, 3.2, 4.7],0:0.5:1)
        y = QuasiVector([3.5, pi, 1e-4],0:0.5:1)
        α = 0.2342
        @test sin.(x) == broadcast(sin, x)
        @test atan.(x, y) == broadcast(atan, x, y)
        @test atan.(x, y') == broadcast(atan, x, y')
        @test atan.(x, α) == broadcast(atan, x, α)
        @test atan.(α, y') == broadcast(atan, α, y')
    end

    @testset "sin" begin
        a = sin.(QuasiVector([1, 2],0:0.5:0.5))
        @test isa(a, QuasiVector{Float64})
        @test a ≈ QuasiVector([0.8414709848078965, 0.9092974268256817],0:0.5:0.5)
    end

    @testset "loop fusion" begin
        v = QuasiVector(1:10, range(0; stop=1,length=10))
        @test (x->x+1).((x->x+2).((x->x+3).(v))) == QuasiVector(7:16,range(0; stop=1,length=10))
        let A = QuasiArray([sqrt(i)+j for i = 1:3, j=1:4], (0:0.5:1,0:0.5:1.5))
            @test_broken atan.(log.(A), sum(A, dims=1)) == broadcast(atan, broadcast(log, A), sum(A, dims=1))
        end
        let x = sin.(v)
            @test atan.((x->x+1).(x), (x->x+2).(x)) == broadcast(atan, x.+1, x.+2)
            @test sin.(atan.([x.+1,x.+2]...)) == sin.(atan.(x.+1 ,x.+2)) == @. sin(atan(x+1,x+2))
            @test sin.(atan.(x, 3.7)) == broadcast(x -> sin(atan(x,3.7)), x)
            @test atan.(x, 3.7) == broadcast(x -> atan(x,3.7), x) == broadcast(atan, x, 3.7)
        end
        # fusion with splatted args:
        let x = sin.(v), a = [x]
            @test cos.(x) == cos.(a...)
            @test atan.(x,x) == atan.(a..., a...) == atan.([x, x]...)
            @test atan.(x, cos.(x)) == atan.(a..., cos.(x)) == broadcast(atan, x, cos.(a...)) == broadcast(atan, a..., cos.(a...))
            @test ((args...)->cos(args[1])).(x) == cos.(x) == ((y,args...)->cos(y)).(x)
        end
    end

    @testset "Fused in-place assignment" begin
        x = QuasiVector(1:4,0:0.5:1.5); y = x
        y .= QuasiVector(2:5,0:0.5:1.5)
        @test y === x == QuasiVector(2:5,0:0.5:1.5)
        y .= factorial.(x)
        @test y === x ==  QuasiVector([2,6,24,120],0:0.5:1.5)
        y .= 7
        @test y === x ==  QuasiVector([7,7,7,7],0:0.5:1.5)
        y .= factorial.(3)
        @test y === x ==  QuasiVector([6,6,6,6],0:0.5:1.5)
        f17510() = 9
        y .= f17510.()
        @test y === x ==  QuasiVector([9,9,9,9],0:0.5:1.5)
        y .-= 1
        @test y === x ==  QuasiVector([8,8,8,8],0:0.5:1.5)
        y .-= QuasiVector(1:4,0:0.5:1.5)   # @. should convert to .-=
        @test y === x ==  QuasiVector([7,6,5,4],0:0.5:1.5)
        view(x,0:0.5:0.5) .= 1
        @test y === x == QuasiVector([1,1,5,4],0:0.5:1.5)
        view(x,:) .= 0         # use .= to make sure @. works with dotted assignment
        @test y === x == QuasiVector([0,0,0,0],0:0.5:1.5)
    end

    @testset "BroadcastQuasiArray" begin
        a = QuasiVector(randn(6), 0:0.5:2.5)
        b = BroadcastQuasiArray(exp, a)
        @test b[0.5] == exp(a[0.5])
        @test b[0.5:0.5:1.0] isa QuasiArrays.BroadcastArray
        @test b[0.5:0.5:1.0] == b[[0.5,1.0]] == exp.(a[0.5:0.5:1.0])

        A = QuasiArray(randn(6,6), (0:0.5:2.5,0:0.5:2.5))
        B = BroadcastQuasiArray(exp, A)
        @test B[0.5,1.0] == exp(A[0.5,1.0])

        @test axes(exp.(A)) == axes(B)
        @test QuasiMatrix(B) == exp.(A)

        C = BroadcastQuasiArray(+, A, 2)
        @test C == A .+ 2
        D = BroadcastQuasiArray(+, A, C)
        @test D == A + C

        @test sum(B) ≈ sum(exp, A)
        @test sum(C) ≈ sum(A .+ 2)
    end

    @testset "SubQuasi Broadcast" begin
        a = QuasiVector(randn(6), 0:0.5:2.5)
        v = view(a,0:0.5:1)
        @test v isa SubArray
        @test BroadcastStyle(typeof(v)) isa DefaultArrayStyle{1}
        @test exp.(v) == exp.(Array(v))
        w = view(a,Inclusion(0:0.5:1))
        @test w isa SubQuasiArray
        @test BroadcastStyle(typeof(w)) isa DefaultQuasiArrayStyle{1}
        @test exp.(w) == exp.(a)[Inclusion(0:0.5:1)]
    end
end


text:
module DrakeVisualizer

using LCMCore
using GeometryTypes
using FileIO
using LinearAlgebra

import MeshIO
import JSON

using Meshing: MarchingTetrahedra
using Rotations: Rotation, Quat, rotation_between
using CoordinateTransformations: Transformation,
                                 transform_deriv,
                                 IdentityTransformation,
                                 AbstractAffineMap,
                                 AffineMap,
                                 LinearMap,
                                 Translation,
                                 compose
using ColorTypes: RGB, RGBA, Colorant, red, green, blue, alpha
using StaticArrays: SVector, StaticArray, SMatrix
using DataStructures: OrderedDict

import GeometryTypes: origin, radius, raw
import Base: convert, length, show, isempty, empty!, delete!

export GeometryData,
        Link,
        Robot,
        Visualizer,
        HyperRectangle,
        HyperEllipsoid,
        Cylinder,
        HyperSphere,
        HyperCube,
        MeshFile,
        PointCloud,
        Point,
        Vec,
        Triad,
        PolyLine,
        ArrowHead,
        contour_mesh,
        settransform!,
        setgeometry!,
        addgeometry!,
        load!,
        draw!,
        delete!,
        batch

const drake_visualizer_executable_name = "drake-visualizer"

function new_window(; script::Union{AbstractString, Nothing} = nothing)
    installed_visualizer_path = joinpath(dirname(@__FILE__), "..", "deps", "usr", "bin", "$drake_visualizer_executable_name")
    drake_visualizer = if isfile(installed_visualizer_path)
        # If we built drake-visualizer, then use it
        installed_visualizer_path
    else
        # Otherwise let the system try to find it
        drake_visualizer_executable_name
    end
    command = script == nothing ? `$drake_visualizer` : `$drake_visualizer --script $script`
    proc = open(command)
    proc
end

function any_open_windows()
    @static if Sys.isapple()
        return success(`pgrep $drake_visualizer_executable_name`)
    elseif Sys.islinux()
        return success(`pgrep -f $drake_visualizer_executable_name`)
    else
        warn("DrakeVisualizer.any_open_windows not implemented for $(Sys.KERNEL). This function will always return false.")
        return false
    end
end

function delete_director_binaries(skip_confirmation=false)
    root = joinpath(dirname(dirname(@__FILE__)), "deps")
    binary_paths = [
        joinpath(root, "usr"),
        joinpath(root, "downloads"),
        joinpath(root, "src"),
        joinpath(root, "builds"),
        joinpath(root, "deps.jl")
    ]
    if !skip_confirmation
        println("CAUTION: This will delete all downloaded binaries of Director.")
        println("The following paths will be deleted:")
        for path in binary_paths
            println(path)
        end
        print("After doing this, you will need to run 'using Pkg; Pkg.build(\"DrakeVisualizer\")'. Proceed? (y/n) ")
        choice = chomp(readline())
        if lowercase(choice[1]) != 'y'
            println("Canceled.")
            return
        end
    end
    for path in binary_paths
        println("Removing $path")
        rm(path, force=true, recursive=true)
    end
end

include("lcmtypes/comms_t.jl")
include("lazytree.jl")
include("contour_meshes.jl")
include("geometry_types.jl")
include("visualizer.jl")
include("serialization.jl")

end


text:
# adapted from Julia source

macro roundsig(source, sigdigs, target)
  :(streq( round(Robust32($source), sigdigits=$sigdigs), Robust32($target) ))
end
macro roundsig(source, sigdigs, base, target)
  :(streq( round(Robust32($source), sigdigits=$sigdigs, base=$base), Robust32($target) ))
end
macro rounddig(source, digs, target)
  :(streq( round(Robust32($source), digits=$digs), Robust32($target) ))
end
macro rounddig(source, digs, base, target)
  :(streq( round(Robust32($source), digits=$digs, base=$base), Robust32($target) ))
end

@testset "significant digits" begin
    @test @roundsig(123.456, 1, 100.0)
    @test @roundsig(123.456, 3, 123.0)
    @test @roundsig(123.456, 5, 123.46)
    @test @roundsig(123.456, 8, 2, 123.5)
    @test @roundsig(123.456, 2, 4, 128.0)

    @test @roundsig(0.0, 1, 0.0)
    @test @roundsig(-0.0, 5, -0.0)

    @test @roundsig(1.2, 2, 1.2)
    @test @roundsig(1.2, 3, 1.2)
    @test @roundsig(1.2, 4, 1.2)

    @test @roundsig(0.6, 1, 0.6)
    @test @roundsig(0.6, 2, 0.6)
    @test @roundsig(0.6, 3, 0.6)

    @test @roundsig(7.262839104539736f0, 2, 7.3)
    @test @roundsig(7.262839104539736f0, 3, 7.26)
    @test @roundsig(7.262839104539736f0, 4, 7.263)

    @test isinf(round(Robust32(Inf), sigdigits=3))
    @test isnan(round(Robust32(NaN), sigdigits=3))
 end


text:
function collatz_steps(n)
    n < 1 && throw(DomainError("Invalid number"))
    n == 1 && return 0
    iseven(n) ? 1 + collatz_steps(div(n, 2)) : 1 + collatz_steps(3n + 1)
end

max_stars_repo_name: koladilip/julia-exercism

max_issues_repo_name: koladilip/julia-exercism

max_forks_repo_name: koladilip/julia-exercism


text:
# ----------------------------------------------------------------------------------- #
# Copyright (c) 2021 Varnerlab
# Robert Frederick Smith School of Chemical and Biomolecular Engineering
# Cornell University, Ithaca NY 14850
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# ----------------------------------------------------------------------------------- #
function generate_default_data_dictionary()::Union{Dict{String,Any},Exception}

	# initialize data storage -
	data_dictionary = Dict{String,Any}()

	try
		# load the stoichiometric_matrix -
		stoichiometric_matrix = readdlm("Network.dat")
		(number_of_species, number_of_reactions) = size(stoichiometric_matrix)

		# initialize objective coefficient array -
		objective_coefficient_array = zeros(number_of_reactions)

		# setup the flux bounds array -
		flux_bounds_array = [
			0.0 DEFAULT_UPPER_BOUND	;	#	1	R_gp_1
			0.0 DEFAULT_UPPER_BOUND	;	#	2	R_gp_2
			0.0 DEFAULT_UPPER_BOUND	;	#	3	R_gp_3
			0.0 DEFAULT_UPPER_BOUND	;	#	4	R_gp_4
			0.0 DEFAULT_UPPER_BOUND	;	#	5	R_gp
			0.0 DEFAULT_UPPER_BOUND	;	#	6	R_pgm
			0.0 DEFAULT_UPPER_BOUND	;	#	7	R_glk_atp
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	8	R_pgi
			0.0 DEFAULT_UPPER_BOUND	;	#	9	R_pfk
			0.0 DEFAULT_UPPER_BOUND	;	#	10	R_fdp
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	11	R_fbaA
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	12	R_tpiA
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	13	R_gpsA
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	14	R_gapA
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	15	R_pgk
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	16	R_gpm
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	17	R_eno
			0.0 DEFAULT_UPPER_BOUND	;	#	18	R_pyk
			0.0 DEFAULT_UPPER_BOUND	;	#	19	R_pck
			0.0 DEFAULT_UPPER_BOUND	;	#	20	R_ppc
			0.0 DEFAULT_UPPER_BOUND	;	#	21	R_pdh
			0.0 DEFAULT_UPPER_BOUND	;	#	22	R_pps
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	23	R_zwf
			0.0 DEFAULT_UPPER_BOUND	;	#	24	R_pgl
			0.0 DEFAULT_UPPER_BOUND	;	#	25	R_gnd
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	26	R_rpe
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	27	R_rpi
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	28	R_talAB
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	29	R_tkt1
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	30	R_tkt2
			0.0 DEFAULT_UPPER_BOUND	;	#	31	R_edd
			0.0 DEFAULT_UPPER_BOUND	;	#	32	R_eda
			0.0 DEFAULT_UPPER_BOUND	;	#	33	R_gltA
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	34	R_acn
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	35	R_icd
			0.0 DEFAULT_UPPER_BOUND	;	#	36	R_sucAB
			0.0 DEFAULT_UPPER_BOUND	;	#	37	R_sucCD
			0.0 DEFAULT_UPPER_BOUND	;	#	38	R_sdh
			0.0 DEFAULT_UPPER_BOUND	;	#	39	R_frd
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	40	R_fum
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	41	R_mdh
			0.0 DEFAULT_UPPER_BOUND	;	#	42	R_cyd
			0.0 DEFAULT_UPPER_BOUND	;	#	43	R_cyo
			0.0 DEFAULT_UPPER_BOUND	;	#	44	R_app
			0.0 DEFAULT_UPPER_BOUND	;	#	45	R_atp
			0.0 DEFAULT_UPPER_BOUND	;	#	46	R_DNP_leak
			0.0 DEFAULT_UPPER_BOUND	;	#	47	R_nuo
			0.0 DEFAULT_UPPER_BOUND	;	#	48	R_pnt1
			0.0 DEFAULT_UPPER_BOUND	;	#	49	R_pnt2
			0.0 DEFAULT_UPPER_BOUND	;	#	50	R_ndh1
			0.0 DEFAULT_UPPER_BOUND	;	#	51	R_ndh2
			0.0 DEFAULT_UPPER_BOUND	;	#	52	R_ppa
			0.0 DEFAULT_UPPER_BOUND	;	#	53	R_aceA
			0.0 DEFAULT_UPPER_BOUND	;	#	54	R_aceB
			0.0 DEFAULT_UPPER_BOUND	;	#	55	R_maeA
			0.0 DEFAULT_UPPER_BOUND	;	#	56	R_maeB
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	57	R_pta
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	58	R_ackA
			0.0 DEFAULT_UPPER_BOUND	;	#	59	R_acs
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	60	R_adhE
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	61	R_ldh
			0.0 DEFAULT_UPPER_BOUND	;	#	62	R_pflAB
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	63	R_alaAC
			0.0 DEFAULT_UPPER_BOUND	;	#	64	R_arg
			0.0 DEFAULT_UPPER_BOUND	;	#	65	R_aspC
			0.0 DEFAULT_UPPER_BOUND	;	#	66	R_asnB
			0.0 DEFAULT_UPPER_BOUND	;	#	67	R_asnA
			0.0 DEFAULT_UPPER_BOUND	;	#	68	R_cysEMK
			0.0 DEFAULT_UPPER_BOUND	;	#	69	R_gltBD
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	70	R_gdhA
			0.0 DEFAULT_UPPER_BOUND	;	#	71	R_glnA
			0.0 DEFAULT_UPPER_BOUND	;	#	72	R_glyA
			0.0 DEFAULT_UPPER_BOUND	;	#	73	R_his
			0.0 DEFAULT_UPPER_BOUND	;	#	74	R_ile
			0.0 DEFAULT_UPPER_BOUND	;	#	75	R_leu
			0.0 DEFAULT_UPPER_BOUND	;	#	76	R_lys
			0.0 DEFAULT_UPPER_BOUND	;	#	77	R_met
			0.0 DEFAULT_UPPER_BOUND	;	#	78	R_phe
			0.0 DEFAULT_UPPER_BOUND	;	#	79	R_pro
			0.0 DEFAULT_UPPER_BOUND	;	#	80	R_serABC
			0.0 DEFAULT_UPPER_BOUND	;	#	81	R_thr
			0.0 DEFAULT_UPPER_BOUND	;	#	82	R_trp
			0.0 DEFAULT_UPPER_BOUND	;	#	83	R_tyr
			0.0 DEFAULT_UPPER_BOUND	;	#	84	R_val
			0.0 DEFAULT_UPPER_BOUND	;	#	85	R_arg_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	86	R_asp_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	87	R_asn_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	88	R_gly_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	89	R_mglx_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	90	R_ser_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	91	R_pro_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	92	R_thr_deg1
			0.0 DEFAULT_UPPER_BOUND	;	#	93	R_thr_deg2
			0.0 DEFAULT_UPPER_BOUND	;	#	94	R_thr_deg3
			0.0 DEFAULT_UPPER_BOUND	;	#	95	R_trp_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	96	R_cys_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	97	R_lys_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	98	R_gln_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	99	R_glu_deg
			0.0 DEFAULT_UPPER_BOUND	;	#	100	R_gaba_deg1
			0.0 DEFAULT_UPPER_BOUND	;	#	101	R_gaba_deg2
			0.0 DEFAULT_UPPER_BOUND	;	#	102	R_chor
			0.0 DEFAULT_UPPER_BOUND	;	#	103	R_fol_e
			0.0 DEFAULT_UPPER_BOUND	;	#	104	R_fol_1
			0.0 DEFAULT_UPPER_BOUND	;	#	105	R_fol_2a
			0.0 DEFAULT_UPPER_BOUND	;	#	106	R_fol_2b
			0.0 DEFAULT_UPPER_BOUND	;	#	107	R_fol_3
			0.0 DEFAULT_UPPER_BOUND	;	#	108	R_fol_4
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	109	R_gly_fol
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	110	R_mthfd
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	111	R_mthfc
			0.0 DEFAULT_UPPER_BOUND	;	#	112	R_mthfr2a
			0.0 DEFAULT_UPPER_BOUND	;	#	113	R_mthfr2b
			0.0 DEFAULT_UPPER_BOUND	;	#	114	R_prpp_syn
			0.0 DEFAULT_UPPER_BOUND	;	#	115	R_or_syn_1
			0.0 DEFAULT_UPPER_BOUND	;	#	116	R_or_syn_2
			0.0 DEFAULT_UPPER_BOUND	;	#	117	R_omp_syn
			0.0 DEFAULT_UPPER_BOUND	;	#	118	R_ump_syn
			0.0 DEFAULT_UPPER_BOUND	;	#	119	R_ctp_1
			0.0 DEFAULT_UPPER_BOUND	;	#	120	R_ctp_2
			0.0 DEFAULT_UPPER_BOUND	;	#	121	R_A_syn_1
			0.0 DEFAULT_UPPER_BOUND	;	#	122	R_A_syn_2
			0.0 DEFAULT_UPPER_BOUND	;	#	123	R_A_syn_3
			0.0 DEFAULT_UPPER_BOUND	;	#	124	R_A_syn_4
			0.0 DEFAULT_UPPER_BOUND	;	#	125	R_A_syn_5
			0.0 DEFAULT_UPPER_BOUND	;	#	126	R_A_syn_6
			0.0 DEFAULT_UPPER_BOUND	;	#	127	R_A_syn_7
			0.0 DEFAULT_UPPER_BOUND	;	#	128	R_A_syn_8
			0.0 DEFAULT_UPPER_BOUND	;	#	129	R_A_syn_9
			0.0 DEFAULT_UPPER_BOUND	;	#	130	R_A_syn_10
			0.0 DEFAULT_UPPER_BOUND	;	#	131	R_A_syn_12
			0.0 DEFAULT_UPPER_BOUND	;	#	132	R_xmp_syn
			0.0 DEFAULT_UPPER_BOUND	;	#	133	R_gmp_syn
			0.0 DEFAULT_UPPER_BOUND	;	#	134	R_atp_amp
			0.0 DEFAULT_UPPER_BOUND	;	#	135	R_utp_ump
			0.0 DEFAULT_UPPER_BOUND	;	#	136	R_ctp_cmp
			0.0 DEFAULT_UPPER_BOUND	;	#	137	R_gtp_gmp
			0.0 DEFAULT_UPPER_BOUND	;	#	138	R_atp_adp
			0.0 DEFAULT_UPPER_BOUND	;	#	139	R_utp_adp
			0.0 DEFAULT_UPPER_BOUND	;	#	140	R_ctp_adp
			0.0 DEFAULT_UPPER_BOUND	;	#	141	R_gtp_adp
			0.0 DEFAULT_UPPER_BOUND	;	#	142	R_udp_utp
			0.0 DEFAULT_UPPER_BOUND	;	#	143	R_cdp_ctp
			0.0 DEFAULT_UPPER_BOUND	;	#	144	R_gdp_gtp
			0.0 DEFAULT_UPPER_BOUND	;	#	145	R_atp_ump
			0.0 DEFAULT_UPPER_BOUND	;	#	146	R_atp_cmp
			0.0 DEFAULT_UPPER_BOUND	;	#	147	R_atp_gmp
			0.0 DEFAULT_UPPER_BOUND	;	#	148	R_adk_atp
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	149	M_h2s_c_exchange
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	150	M_h2o_c_exchange
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	151	M_pi_c_exchange
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	152	M_nh3_c_exchange
			0.0 DEFAULT_UPPER_BOUND	;	#	153	M_hco3_c_exchange
			0.0 DEFAULT_UPPER_BOUND	;	#	154	M_etoh_c_exchange
			0.0 DEFAULT_UPPER_BOUND	;	#	155	M_mglx_c_exchange
			0.0 DEFAULT_UPPER_BOUND	;	#	156	M_prop_c_exchange
			0.0 DEFAULT_UPPER_BOUND	;	#	157	M_indole_c_exchange
			0.0 DEFAULT_UPPER_BOUND	;	#	158	M_cadav_c_exchange
			0.0 DEFAULT_UPPER_BOUND	;	#	159	M_gaba_c_exchange
			0.0 DEFAULT_UPPER_BOUND	;	#	160	M_glycoA_c_exchange
			0.0 DEFAULT_UPPER_BOUND	;	#	161	M_o2_c_exchange
			0.0 DEFAULT_UPPER_BOUND	;	#	162	M_co2_c_exchange
			DEFAULT_LOWER_BOUND DEFAULT_UPPER_BOUND	;	#	163	M_h_c_exchange
		]

		# setup the species bounds array -
		species_bounds_array = zeros(number_of_species,2)

		# ----------------------------------------------------------------------------------- #
		data_dictionary["flux_bounds_array"] = flux_bounds_array
		data_dictionary["stoichiometric_matrix"] = stoichiometric_matrix
		data_dictionary["objective_coefficient_array"] = objective_coefficient_array
		data_dictionary["species_bounds_array"] = species_bounds_array
		data_dictionary["number_of_species"] = number_of_species
		data_dictionary["number_of_reactions"] = number_of_reactions
		# ----------------------------------------------------------------------------------- #

		# return -
		return data_dictionary
	catch error
		rethrow(error)
	end
end

max_stars_repo_name: varnerlab/CellFreeModelGenerationKit

max_issues_repo_name: varnerlab/CellFreeModelGenerationKit

max_forks_repo_name: varnerlab/CellFreeModelGenerationKit


text:
"""
    GainEquation

Abstract type for a container representing a gain (vector field).
"""
abstract type GainEquation end

"""
    GainEstimationMethod

Abstract type for a method used to solve an equation of `GainEquation` type.
"""
abstract type GainEstimationMethod end

"""
    solve!(eq::GainEquation, method::GainEstimationMethod) --> eq

Solves the gain equation `eq` using method `method`.
"""
function solve!(eq::GainEquation, method::GainEstimationMethod) end

"""
    update!(eq::GainEquation)

Updates the gain equation `eq` such that all information contained in it is self-consistent.

    update!(eq::GainEquation, ens::ParticleRepresentation)

Updates the gain equation `eq` by incorporating new information from the ensemble `ens`.
"""
function update!(eq::GainEquation) end
function update!(eq::GainEquation, ens::ParticleRepresentation) end

function state_dim(eq::GainEquation) end
function obs_dim(eq::GainEquation) end

max_stars_repo_name: simsurace/FeedbackParticleFilters

max_issues_repo_name: simsurace/FeedbackParticleFilters

max_forks_repo_name: simsurace/FeedbackParticleFilters


text:
module WatchJuliaBurn

export c╯°□°ↄ╯
export 🗺, 📖, 📡
export ✅, 👍, 👌, 👎
export @🥩_str
export 🖨, ☝
export 🔥
export ⬛
export 🕵
export 😻, ⬇😻, ➡😻, 😹, ⬇😹, ➡😹, 🐈, ⬇🐈, ➡🐈
export 🔢, 🧺
export 🥧, 🍰, ㅠ
export 🧑🏻➡🧑🏽, 🗜

using LinearAlgebra
using EmojiSymbols

## Base
const c╯°□°ↄ╯ = throw
const 🗺 = map
const 📡 = broadcast
const 📖 = Dict
const ✅ = true
const 👍 = true
const 👌 = true
const 👎 = false
@eval $(Symbol("@🥩_str")) = $(getfield(Main, Symbol("@raw_str")))
const 🔥 = delete!
const 🖨 = print
const ⬛  = nothing
const 🕵 = findall
const ☝ = show
if VERSION >= v"1.5"
    export ⛰
    const ⛰ = peek
end

## Arrays
const 😻 = cat
const ⬇😻 = vcat
const ➡😻 = hcat
const 😹 = cat
const ⬇😹 = vcat
const ➡😹 = hcat
const 🐈 = cat
const ⬇🐈 = vcat
const ➡🐈 = hcat
const 🔢 = Matrix
const 🧺 = collect
if VERSION >= v"1.2"
    @eval export $(Symbol(Char(0x0001fa93) * Char(0x0001fa93)))
    @eval const $(Symbol(Char(0x0001fa93) * Char(0x0001fa93))) = axes # 🪓🪓
end
# const 🪟 = view

## Math
const 🥧 = π
const 🍰 = π
const ㅠ = π
const 🧑🏻➡🧑🏽 = tan
if VERSION >= v"1.5"
    @eval export $(Symbol(Char(0x0001fab5)))
    @eval const $(Symbol(Char(0x0001fab5))) = log # 🪵
end
const 🗜 = clamp

end