text:
# syntax: proto3
using ProtoBuf
import ProtoBuf.meta

mutable struct Int64FeatureType <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function Int64FeatureType(; kwargs...)
        obj = new(meta(Int64FeatureType), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct Int64FeatureType
const __meta_Int64FeatureType = Ref{ProtoMeta}()
function meta(::Type{Int64FeatureType})
    ProtoBuf.metalock() do
        if !isassigned(__meta_Int64FeatureType)
            __meta_Int64FeatureType[] = target = ProtoMeta(Int64FeatureType)
            allflds = Pair{Symbol,Union{Type,String}}[]
            meta(target, Int64FeatureType, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_Int64FeatureType[]
    end
end

mutable struct DoubleFeatureType <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function DoubleFeatureType(; kwargs...)
        obj = new(meta(DoubleFeatureType), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct DoubleFeatureType
const __meta_DoubleFeatureType = Ref{ProtoMeta}()
function meta(::Type{DoubleFeatureType})
    ProtoBuf.metalock() do
        if !isassigned(__meta_DoubleFeatureType)
            __meta_DoubleFeatureType[] = target = ProtoMeta(DoubleFeatureType)
            allflds = Pair{Symbol,Union{Type,String}}[]
            meta(target, DoubleFeatureType, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_DoubleFeatureType[]
    end
end

mutable struct StringFeatureType <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function StringFeatureType(; kwargs...)
        obj = new(meta(StringFeatureType), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct StringFeatureType
const __meta_StringFeatureType = Ref{ProtoMeta}()
function meta(::Type{StringFeatureType})
    ProtoBuf.metalock() do
        if !isassigned(__meta_StringFeatureType)
            __meta_StringFeatureType[] = target = ProtoMeta(StringFeatureType)
            allflds = Pair{Symbol,Union{Type,String}}[]
            meta(target, StringFeatureType, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_StringFeatureType[]
    end
end

mutable struct SizeRange <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function SizeRange(; kwargs...)
        obj = new(meta(SizeRange), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct SizeRange
const __meta_SizeRange = Ref{ProtoMeta}()
function meta(::Type{SizeRange})
    ProtoBuf.metalock() do
        if !isassigned(__meta_SizeRange)
            __meta_SizeRange[] = target = ProtoMeta(SizeRange)
            allflds = Pair{Symbol,Union{Type,String}}[:lowerBound => UInt64, :upperBound => Int64]
            meta(target, SizeRange, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_SizeRange[]
    end
end
function Base.getproperty(obj::SizeRange, name::Symbol)
    if name === :lowerBound
        return (obj.__protobuf_jl_internal_values[name])::UInt64
    elseif name === :upperBound
        return (obj.__protobuf_jl_internal_values[name])::Int64
    else
        getfield(obj, name)
    end
end

const ImageFeatureType_ColorSpace = (;[
    Symbol("INVALID_COLOR_SPACE") => Int32(0),
    Symbol("GRAYSCALE") => Int32(10),
    Symbol("RGB") => Int32(20),
    Symbol("BGR") => Int32(30),
]...)

mutable struct ImageFeatureType_ImageSize <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ImageFeatureType_ImageSize(; kwargs...)
        obj = new(meta(ImageFeatureType_ImageSize), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct ImageFeatureType_ImageSize
const __meta_ImageFeatureType_ImageSize = Ref{ProtoMeta}()
function meta(::Type{ImageFeatureType_ImageSize})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ImageFeatureType_ImageSize)
            __meta_ImageFeatureType_ImageSize[] = target = ProtoMeta(ImageFeatureType_ImageSize)
            allflds = Pair{Symbol,Union{Type,String}}[:width => UInt64, :height => UInt64]
            meta(target, ImageFeatureType_ImageSize, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_ImageFeatureType_ImageSize[]
    end
end
function Base.getproperty(obj::ImageFeatureType_ImageSize, name::Symbol)
    if name === :width
        return (obj.__protobuf_jl_internal_values[name])::UInt64
    elseif name === :height
        return (obj.__protobuf_jl_internal_values[name])::UInt64
    else
        getfield(obj, name)
    end
end

mutable struct ImageFeatureType_EnumeratedImageSizes <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ImageFeatureType_EnumeratedImageSizes(; kwargs...)
        obj = new(meta(ImageFeatureType_EnumeratedImageSizes), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct ImageFeatureType_EnumeratedImageSizes
const __meta_ImageFeatureType_EnumeratedImageSizes = Ref{ProtoMeta}()
function meta(::Type{ImageFeatureType_EnumeratedImageSizes})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ImageFeatureType_EnumeratedImageSizes)
            __meta_ImageFeatureType_EnumeratedImageSizes[] = target = ProtoMeta(ImageFeatureType_EnumeratedImageSizes)
            allflds = Pair{Symbol,Union{Type,String}}[:sizes => Base.Vector{ImageFeatureType_ImageSize}]
            meta(target, ImageFeatureType_EnumeratedImageSizes, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_ImageFeatureType_EnumeratedImageSizes[]
    end
end
function Base.getproperty(obj::ImageFeatureType_EnumeratedImageSizes, name::Symbol)
    if name === :sizes
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{ImageFeatureType_ImageSize}
    else
        getfield(obj, name)
    end
end

mutable struct ImageFeatureType_ImageSizeRange <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ImageFeatureType_ImageSizeRange(; kwargs...)
        obj = new(meta(ImageFeatureType_ImageSizeRange), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct ImageFeatureType_ImageSizeRange
const __meta_ImageFeatureType_ImageSizeRange = Ref{ProtoMeta}()
function meta(::Type{ImageFeatureType_ImageSizeRange})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ImageFeatureType_ImageSizeRange)
            __meta_ImageFeatureType_ImageSizeRange[] = target = ProtoMeta(ImageFeatureType_ImageSizeRange)
            allflds = Pair{Symbol,Union{Type,String}}[:widthRange => SizeRange, :heightRange => SizeRange]
            meta(target, ImageFeatureType_ImageSizeRange, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_ImageFeatureType_ImageSizeRange[]
    end
end
function Base.getproperty(obj::ImageFeatureType_ImageSizeRange, name::Symbol)
    if name === :widthRange
        return (obj.__protobuf_jl_internal_values[name])::SizeRange
    elseif name === :heightRange
        return (obj.__protobuf_jl_internal_values[name])::SizeRange
    else
        getfield(obj, name)
    end
end

mutable struct ImageFeatureType <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ImageFeatureType(; kwargs...)
        obj = new(meta(ImageFeatureType), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct ImageFeatureType
const __meta_ImageFeatureType = Ref{ProtoMeta}()
function meta(::Type{ImageFeatureType})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ImageFeatureType)
            __meta_ImageFeatureType[] = target = ProtoMeta(ImageFeatureType)
            fnum = Int[1,2,21,31,3]
            allflds = Pair{Symbol,Union{Type,String}}[:width => Int64, :height => Int64, :enumeratedSizes => ImageFeatureType_EnumeratedImageSizes, :imageSizeRange => ImageFeatureType_ImageSizeRange, :colorSpace => Int32]
            oneofs = Int[0,0,1,1,0]
            oneof_names = Symbol[Symbol("SizeFlexibility")]
            meta(target, ImageFeatureType, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, oneofs, oneof_names)
        end
        __meta_ImageFeatureType[]
    end
end
function Base.getproperty(obj::ImageFeatureType, name::Symbol)
    if name === :width
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :height
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :enumeratedSizes
        return (obj.__protobuf_jl_internal_values[name])::ImageFeatureType_EnumeratedImageSizes
    elseif name === :imageSizeRange
        return (obj.__protobuf_jl_internal_values[name])::ImageFeatureType_ImageSizeRange
    elseif name === :colorSpace
        return (obj.__protobuf_jl_internal_values[name])::Int32
    else
        getfield(obj, name)
    end
end

const ArrayFeatureType_ArrayDataType = (;[
    Symbol("INVALID_ARRAY_DATA_TYPE") => Int32(0),
    Symbol("FLOAT32") => Int32(65568),
    Symbol("DOUBLE") => Int32(65600),
    Symbol("INT32") => Int32(131104),
]...)

mutable struct ArrayFeatureType_Shape <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ArrayFeatureType_Shape(; kwargs...)
        obj = new(meta(ArrayFeatureType_Shape), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct ArrayFeatureType_Shape
const __meta_ArrayFeatureType_Shape = Ref{ProtoMeta}()
function meta(::Type{ArrayFeatureType_Shape})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ArrayFeatureType_Shape)
            __meta_ArrayFeatureType_Shape[] = target = ProtoMeta(ArrayFeatureType_Shape)
            pack = Symbol[:shape]
            allflds = Pair{Symbol,Union{Type,String}}[:shape => Base.Vector{Int64}]
            meta(target, ArrayFeatureType_Shape, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, pack, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_ArrayFeatureType_Shape[]
    end
end
function Base.getproperty(obj::ArrayFeatureType_Shape, name::Symbol)
    if name === :shape
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{Int64}
    else
        getfield(obj, name)
    end
end

mutable struct ArrayFeatureType_EnumeratedShapes <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ArrayFeatureType_EnumeratedShapes(; kwargs...)
        obj = new(meta(ArrayFeatureType_EnumeratedShapes), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct ArrayFeatureType_EnumeratedShapes
const __meta_ArrayFeatureType_EnumeratedShapes = Ref{ProtoMeta}()
function meta(::Type{ArrayFeatureType_EnumeratedShapes})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ArrayFeatureType_EnumeratedShapes)
            __meta_ArrayFeatureType_EnumeratedShapes[] = target = ProtoMeta(ArrayFeatureType_EnumeratedShapes)
            allflds = Pair{Symbol,Union{Type,String}}[:shapes => Base.Vector{ArrayFeatureType_Shape}]
            meta(target, ArrayFeatureType_EnumeratedShapes, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_ArrayFeatureType_EnumeratedShapes[]
    end
end
function Base.getproperty(obj::ArrayFeatureType_EnumeratedShapes, name::Symbol)
    if name === :shapes
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{ArrayFeatureType_Shape}
    else
        getfield(obj, name)
    end
end

mutable struct ArrayFeatureType_ShapeRange <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ArrayFeatureType_ShapeRange(; kwargs...)
        obj = new(meta(ArrayFeatureType_ShapeRange), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct ArrayFeatureType_ShapeRange
const __meta_ArrayFeatureType_ShapeRange = Ref{ProtoMeta}()
function meta(::Type{ArrayFeatureType_ShapeRange})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ArrayFeatureType_ShapeRange)
            __meta_ArrayFeatureType_ShapeRange[] = target = ProtoMeta(ArrayFeatureType_ShapeRange)
            allflds = Pair{Symbol,Union{Type,String}}[:sizeRanges => Base.Vector{SizeRange}]
            meta(target, ArrayFeatureType_ShapeRange, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_ArrayFeatureType_ShapeRange[]
    end
end
function Base.getproperty(obj::ArrayFeatureType_ShapeRange, name::Symbol)
    if name === :sizeRanges
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{SizeRange}
    else
        getfield(obj, name)
    end
end

mutable struct ArrayFeatureType <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ArrayFeatureType(; kwargs...)
        obj = new(meta(ArrayFeatureType), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct ArrayFeatureType
const __meta_ArrayFeatureType = Ref{ProtoMeta}()
function meta(::Type{ArrayFeatureType})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ArrayFeatureType)
            __meta_ArrayFeatureType[] = target = ProtoMeta(ArrayFeatureType)
            fnum = Int[1,2,21,31,41,51,61]
            pack = Symbol[:shape]
            allflds = Pair{Symbol,Union{Type,String}}[:shape => Base.Vector{Int64}, :dataType => Int32, :enumeratedShapes => ArrayFeatureType_EnumeratedShapes, :shapeRange => ArrayFeatureType_ShapeRange, :intDefaultValue => Int32, :floatDefaultValue => Float32, :doubleDefaultValue => Float64]
            oneofs = Int[0,0,1,1,2,2,2]
            oneof_names = Symbol[Symbol("ShapeFlexibility"),Symbol("defaultOptionalValue")]
            meta(target, ArrayFeatureType, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, pack, ProtoBuf.DEF_WTYPES, oneofs, oneof_names)
        end
        __meta_ArrayFeatureType[]
    end
end
function Base.getproperty(obj::ArrayFeatureType, name::Symbol)
    if name === :shape
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{Int64}
    elseif name === :dataType
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :enumeratedShapes
        return (obj.__protobuf_jl_internal_values[name])::ArrayFeatureType_EnumeratedShapes
    elseif name === :shapeRange
        return (obj.__protobuf_jl_internal_values[name])::ArrayFeatureType_ShapeRange
    elseif name === :intDefaultValue
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :floatDefaultValue
        return (obj.__protobuf_jl_internal_values[name])::Float32
    elseif name === :doubleDefaultValue
        return (obj.__protobuf_jl_internal_values[name])::Float64
    else
        getfield(obj, name)
    end
end

mutable struct DictionaryFeatureType <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function DictionaryFeatureType(; kwargs...)
        obj = new(meta(DictionaryFeatureType), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct DictionaryFeatureType
const __meta_DictionaryFeatureType = Ref{ProtoMeta}()
function meta(::Type{DictionaryFeatureType})
    ProtoBuf.metalock() do
        if !isassigned(__meta_DictionaryFeatureType)
            __meta_DictionaryFeatureType[] = target = ProtoMeta(DictionaryFeatureType)
            allflds = Pair{Symbol,Union{Type,String}}[:int64KeyType => Int64FeatureType, :stringKeyType => StringFeatureType]
            oneofs = Int[1,1]
            oneof_names = Symbol[Symbol("KeyType")]
            meta(target, DictionaryFeatureType, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, oneofs, oneof_names)
        end
        __meta_DictionaryFeatureType[]
    end
end
function Base.getproperty(obj::DictionaryFeatureType, name::Symbol)
    if name === :int64KeyType
        return (obj.__protobuf_jl_internal_values[name])::Int64FeatureType
    elseif name === :stringKeyType
        return (obj.__protobuf_jl_internal_values[name])::StringFeatureType
    else
        getfield(obj, name)
    end
end

mutable struct SequenceFeatureType <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function SequenceFeatureType(; kwargs...)
        obj = new(meta(SequenceFeatureType), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct SequenceFeatureType
const __meta_SequenceFeatureType = Ref{ProtoMeta}()
function meta(::Type{SequenceFeatureType})
    ProtoBuf.metalock() do
        if !isassigned(__meta_SequenceFeatureType)
            __meta_SequenceFeatureType[] = target = ProtoMeta(SequenceFeatureType)
            fnum = Int[1,3,101]
            allflds = Pair{Symbol,Union{Type,String}}[:int64Type => Int64FeatureType, :stringType => StringFeatureType, :sizeRange => SizeRange]
            oneofs = Int[1,1,0]
            oneof_names = Symbol[Symbol("Type")]
            meta(target, SequenceFeatureType, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, oneofs, oneof_names)
        end
        __meta_SequenceFeatureType[]
    end
end
function Base.getproperty(obj::SequenceFeatureType, name::Symbol)
    if name === :int64Type
        return (obj.__protobuf_jl_internal_values[name])::Int64FeatureType
    elseif name === :stringType
        return (obj.__protobuf_jl_internal_values[name])::StringFeatureType
    elseif name === :sizeRange
        return (obj.__protobuf_jl_internal_values[name])::SizeRange
    else
        getfield(obj, name)
    end
end

mutable struct FeatureType <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FeatureType(; kwargs...)
        obj = new(meta(FeatureType), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            if fldval !== nothing
                values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
            end
        end
        obj
    end
end # mutable struct FeatureType
const __meta_FeatureType = Ref{ProtoMeta}()
function meta(::Type{FeatureType})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FeatureType)
            __meta_FeatureType[] = target = ProtoMeta(FeatureType)
            fnum = Int[1,2,3,4,5,6,7,1000]
            allflds = Pair{Symbol,Union{Type,String}}[:int64Type => Int64FeatureType, :doubleType => DoubleFeatureType, :stringType => StringFeatureType, :imageType => ImageFeatureType, :multiArrayType => ArrayFeatureType, :dictionaryType => DictionaryFeatureType, :sequenceType => SequenceFeatureType, :isOptional => Bool]
            oneofs = Int[1,1,1,1,1,1,1,0]
            oneof_names = Symbol[Symbol("Type")]
            meta(target, FeatureType, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, oneofs, oneof_names)
        end
        __meta_FeatureType[]
    end
end
function Base.getproperty(obj::FeatureType, name::Symbol)
    if name === :int64Type
        return (obj.__protobuf_jl_internal_values[name])::Int64FeatureType
    elseif name === :doubleType
        return (obj.__protobuf_jl_internal_values[name])::DoubleFeatureType
    elseif name === :stringType
        return (obj.__protobuf_jl_internal_values[name])::StringFeatureType
    elseif name === :imageType
        return (obj.__protobuf_jl_internal_values[name])::ImageFeatureType
    elseif name === :multiArrayType
        return (obj.__protobuf_jl_internal_values[name])::ArrayFeatureType
    elseif name === :dictionaryType
        return (obj.__protobuf_jl_internal_values[name])::DictionaryFeatureType
    elseif name === :sequenceType
        return (obj.__protobuf_jl_internal_values[name])::SequenceFeatureType
    elseif name === :isOptional
        return (obj.__protobuf_jl_internal_values[name])::Bool
    else
        getfield(obj, name)
    end
end

export Int64FeatureType, DoubleFeatureType, StringFeatureType, SizeRange, ImageFeatureType_ColorSpace, ImageFeatureType_ImageSize, ImageFeatureType_EnumeratedImageSizes, ImageFeatureType_ImageSizeRange, ImageFeatureType, ArrayFeatureType_ArrayDataType, ArrayFeatureType_Shape, ArrayFeatureType_EnumeratedShapes, ArrayFeatureType_ShapeRange, ArrayFeatureType, DictionaryFeatureType, SequenceFeatureType, FeatureType


text:
__precompile__()

module ChunkedArrays
  using EllipsisNotation, Compat

  const BUFFER_SIZE_DEFAULT = 1000
  const PARALLEL_DEFAULT = false

  import Base: start, next, done, getindex

  type ChunkedArray{T,N1,N2}
    chunkfunc::Function
    outputSize::NTuple{N1,Int}
    bufferSize::Int
    state::Int
    randBuffer::Array{T,N2}
    parallel::Bool
    randBuffer2::Future
  end

  function Base.next(bufRand::ChunkedArray)
    if bufRand.state>=bufRand.bufferSize
      if bufRand.parallel
        if bufRand.outputSize == ()
          bufRand.randBuffer2 = @spawn bufRand.chunkfunc(bufRand.bufferSize)
        elseif length(bufRand.outputSize) == 1
          bufRand.randBuffer2 = @spawn bufRand.chunkfunc(bufRand.outputSize[1],bufRand.bufferSize)
        else
          bufRand.randBuffer2 = @spawn bufRand.chunkfunc(bufRand.outputSize...,bufRand.bufferSize)
        end
        @compat bufRand.randBuffer[:] = fetch(bufRand.randBuffer2)[:]
      else
        if bufRand.outputSize == ()
          bufRand.randBuffer[:] = bufRand.chunkfunc(bufRand.bufferSize)
        elseif length(bufRand.outputSize) == 1
          bufRand.randBuffer[:] = bufRand.chunkfunc(bufRand.outputSize[1],bufRand.bufferSize)
        else
          bufRand.randBuffer[:] = bufRand.chunkfunc(bufRand.outputSize...,bufRand.bufferSize)
        end
      end
      bufRand.state = 0
    end
    bufRand.state += 1
    if length(bufRand.outputSize)<1
      return(bufRand.randBuffer[bufRand.state])
    else
      return(bufRand.randBuffer[..,bufRand.state])
    end
  end

  function ChunkedArray(chunkfunc::Function,outputSize::NTuple,bufferSize::Int=BUFFER_SIZE_DEFAULT,T::Type=Float64;parallel=PARALLEL_DEFAULT)
    if parallel
      ChunkedArray{T,length(outputSize),length(outputSize)+1}(chunkfunc,outputSize,bufferSize,0,chunkfunc(outputSize...,bufferSize),parallel,@spawn chunkfunc(outputSize...,bufferSize))
    else
      ChunkedArray{T,length(outputSize),length(outputSize)+1}(chunkfunc,outputSize,bufferSize,0,chunkfunc(outputSize...,bufferSize),parallel,Future())
    end
  end

  function ChunkedArray(chunkfunc::Function,bufferSize::Int=BUFFER_SIZE_DEFAULT,T::Type=Float64;parallel=PARALLEL_DEFAULT)
    if parallel
      ChunkedArray{T,0,1}(chunkfunc,(),bufferSize,0,chunkfunc(bufferSize),parallel,@spawn chunkfunc(bufferSize))
    else
      @compat ChunkedArray{T,0,1}(chunkfunc,(),bufferSize,0,chunkfunc(bufferSize),parallel,Future())
    end
  end

  function ChunkedArray(chunkfunc,randPrototype::AbstractArray,bufferSize=BUFFER_SIZE_DEFAULT;parallel=PARALLEL_DEFAULT)
    outputSize = size(randPrototype)
    if parallel
      ChunkedArray{eltype(randPrototype),length(outputSize),length(outputSize)+1}(chunkfunc,outputSize,bufferSize,0,
      chunkfunc(outputSize...,bufferSize),parallel,@spawn chunkfunc(outputSize...,bufferSize))
    else
      @compat ChunkedArray{eltype(randPrototype),length(outputSize),length(outputSize)+1}(chunkfunc,outputSize,bufferSize,0,
      chunkfunc(outputSize...,bufferSize),parallel,Future())
    end
  end

  export ChunkedArray

end # module

ext: jl


text:
######### StanSample example  ###########

using StanSample

bernoulli_model = "
data {
  int<lower=1> N;
  int<lower=0,upper=1> y[N];
}
parameters {
  real<lower=0,upper=1> theta;
}
model {
  theta ~ beta(1,1);
  y ~ bernoulli(theta);
}
";

bernoulli_data = Dict("N" => 10, "y" => [0, 1, 0, 1, 0, 0, 0, 0, 0, 1])

# Keep tmpdir identical to prevent re-compilation
#tmpdir=joinpath(@__DIR__, "tmp")
tmpdir=mktempdir()

sm = SampleModel(
  "bernoulli", bernoulli_model;
  method = StanSample.Sample(adapt=StanSample.Adapt(delta=0.85)),
  tmpdir=tmpdir)

rc = stan_sample(sm, data=bernoulli_data, n_chains=4)

# Fetch the cmdstan summary in sdf`
if success(rc)
	sdf = read_summary(sm)
	@test sdf[sdf.parameters .== :theta, :mean][1] ≈ 0.33 rtol=0.05

  # Included return formats

  samples = read_samples(sm)          # Return KeyesArray object
  a3d = read_samples(sm, :array)      # Return an a3d object
  df = read_samples(sm, :dataframe)   # Return a DataFrame object

  # If (and only if) MCMCChains is loaded:
  # chns = read_samples(sm, :mcmcchains)
  # See examples in directory `examples_mcmcchains`

end


text:
using Base.Test

function solveA(target)
    i = 1
    while i^2 < target
        i += 2
    end
    while target + i - 1 < i^2
        target += i - 1
    end
    return i - 1 - min(target - i^2 + i - 1, i^2 - target)
end

function solveB(target)
    fillSum(i, j) = sum(get(a, [m, n], 0) for m in i-1:i+1 for n in j-1:j+1)
    a = Dict([0, 0] => 1)
    i, j = 0, 0
    x = 1
    while true
        for (l, m, n) in [(0, 1, 0), (0, 0, 1), (1, -1, 0), (1, 0, -1)]
            for _ in 1:x+l
                i += m
                j += n
                a[[i, j]] = fillSum(i, j)
                if a[[i, j]] > target
                    return a[[i, j]]
                end
            end
        end
        x += 2
    end
end

@test solveA(1) == 0
@test solveA(12) == 3
@test solveA(23) == 2
@test solveA(1024) == 31
@test solveA(368078) == 371
println(solveA(368078))

@test solveB(8) == 10
@test solveB(500) == 747
println(solveB(368078))


text:
using InteractiveUtils

include("benchmarks.jl")

BenchmarkTools.DEFAULT_PARAMETERS.seconds = 0.5

covars, counts = bdata(n, p, 10^1)
# sum(all(iszero.(counts), dims=1))
@time m = fit(HDMR, covars, counts)
@code_warntype coef(m)

@code_warntype HurdleDMR.dmr_local_cluster(covars,counts,true,false,false,true)
@code_warntype HurdleDMR.dmr_remote_cluster(covars,counts,true,false,false,true)

@btime HurdleDMR.dmr_local_cluster(covars,counts,true,false,false,true)
@btime HurdleDMR.dmr_remote_cluster(covars,counts,true,false,false,true)

@code_warntype HurdleDMR.hdmr_local_cluster(covars,counts,1:p,1:p,true,true,false,false)
@code_warntype HurdleDMR.hdmr_remote_cluster(covars,counts,1:p,1:p,true,true,false,false)

@btime HurdleDMR.hdmr_local_cluster(covars,counts,1:p,1:p,true,true,false,false)
@btime HurdleDMR.hdmr_remote_cluster(covars,counts,1:p,1:p,true,true,false,false)

paths = dmrpaths(covars, counts)
DMRCoefs(paths, HurdleDMR.defsegselect)
@code_warntype DMRCoefs(paths, HurdleDMR.defsegselect)
@code_warntype coef(paths, HurdleDMR.defsegselect)

path = paths.nlpaths[1]
@code_warntype coef(path, HurdleDMR.defsegselect)

paths = hdmrpaths(covars, counts)
HDMRCoefs(paths, HurdleDMR.defsegselect)
@code_warntype HDMRCoefs(paths, HurdleDMR.defsegselect)
@code_warntype coef(paths, HurdleDMR.defsegselect)

using Lasso
HDMRCoefs(paths, MinCVKfold{MinCVmse}(10))
HDMRCoefs(paths, MinBIC())
@code_warntype DMRCoefs(paths, MinCVKfold{MinCVmse}(5))
@code_warntype coef(paths, MinCVKfold{MinCVmse}(10))

# @edit dmr_local_cluster(covars, counts)

m = fit(Hurdle, GammaLassoPath, covars, Vector{Float64}(counts[:,1]))
@code_warntype coef(m, AllSeg())


text:
## Convenient functions for creating polymer chains.

function homopolymer_chain(; label=:A, segment=KuhnSegment(label))
    labelE1 = Symbol(label, :1)
    labelE2 = Symbol(label, :2)
    A = PolymerBlock(label, segment, 1.0, FreeEnd(labelE1), FreeEnd(labelE2))
    return BlockCopolymer(label, [A])
end

function diblock_chain(; labelA=:A, labelB=:B, segmentA=KuhnSegment(labelA), segmentB=KuhnSegment(labelB), fA=0.5)
    labelAB = Symbol(labelA, labelB)
    fB = 1.0 - fA
    eAB = BranchPoint(labelAB)
    A = PolymerBlock(labelA, segmentA, fA, FreeEnd(labelA), eAB)
    B = PolymerBlock(labelB, segmentB, fB, FreeEnd(labelB), eAB)
    return BlockCopolymer(labelAB, [A,B])
end

## Convenient functions for creating non-polymer components.

solvent(; label=:S) = SmallMolecule(label)

## Convenient functions for creating polymer systems.

"Default AB diblock copolymer system: two species are A and B, lengths of both segmeents are 1.0. However, χN and fA can be changed by Keyword argument. Default values are: χN=20.0 and fA=0.5."
function AB_system(; χN=20.0, fA=0.5)
    polymer = Component(diblock_chain(; fA=fA))
    return PolymerSystem([polymer], Dict(Set([:A, :B])=>χN))
end

"AB diblock copolymers / A homopolymers blend."
function AB_A_system()
    polymerAB = Component(diblock_chain(), 1.0, 0.5)
    polymerA = Component(homopolymer_chain(; label=:hA, segment=KuhnSegment(:A)), 0.5, 0.5)
    return PolymerSystem([polymerAB, polymerA],
                         Dict(Set([:A, :B])=>20.0))
end

"AB diblock copolymers + solvent solution."
function AB_S_system()
    polymer = Component(diblock_chain(), 1.0, 0.1)
    sol = Component(solvent(), 0.01, 0.9)
    return PolymerSystem([polymer, sol],
                         Dict(
                             Set([:A,:B])=>20.0,
                             Set([:A,:S])=>100.0,
                             Set([:B,:S])=>100.0
                             )
                        )
end


text:
function demographics_test()
    d = init_demographics();
    @test validate_demographics(d)
end

@testset "Demographics" begin
    demographics_test();
end

# -------------


text:
using Flux
using Flux: throttle, nfan, glorot_uniform, glorot_normal,
             kaiming_normal, kaiming_uniform, orthogonal, truncated_normal,
             sparse_init, identity_init, stack, unstack, batch, unbatch,
             unsqueeze, params, loadparams!
using StatsBase: var, std
using Statistics, LinearAlgebra
using Random
using Test

@testset "Throttle" begin
  @testset "default behaviour" begin
    a = []
    f = throttle(()->push!(a, time()), 1, leading=true, trailing=false)
    f()
    f()
    f()
    sleep(1.01)
    @test length(a) == 1
  end

  @testset "leading behaviour" begin
    a = []
    f = throttle(()->push!(a, time()), 1, leading=true, trailing=false)
    f()
    @test length(a) == 1
    f()
    @test length(a) == 1
    sleep(1.01)
    f()
    @test length(a) == 2
  end

  @testset "trailing behaviour" begin
    a = []
    f = throttle(()->push!(a, time()), 1, leading=false, trailing=true)
    f()
    @test length(a) == 0
    f()
    @test length(a) == 0
    sleep(1.01)
    @test length(a) == 1
  end

  @testset "arguments" begin
    a = []
    f = throttle((x)->push!(a, x), 1, leading=true, trailing=true)
    f(1)
    @test a == [1]
    f(2)
    @test a == [1]
    f(3)
    @test a == [1]
    sleep(1.01)
    @test a == [1, 3]
  end
end

@testset "Initialization" begin
  # Set random seed so that these tests don't fail randomly
  Random.seed!(0)

  @testset "Fan in/out" begin
    @test nfan() == (1, 1) #For a constant
    @test nfan(100) == (1, 100) #For vector
    @test nfan(100, 200) == (200, 100) == nfan((100, 200)) #For Dense layer
    @test nfan(2, 30, 40) == (2 * 30, 2 * 40) #For 1D Conv layer
    @test nfan(2, 3, 40, 50) == (2 * 3 * 40, 2 * 3 * 50) #For 2D Conv layer
    @test nfan(2, 3, 4, 50, 60) == (2 * 3 * 4 * 50, 2 * 3 * 4 * 60) #For 3D Conv layer
  end

  @testset "Basics: $init" for init in [
      glorot_uniform, glorot_normal,
      kaiming_uniform, kaiming_normal,
      orthogonal,
      sparse_init,
      truncated_normal,
      identity_init,
      Flux.rand32,
      Flux.randn32,
    ]
    if init == sparse_init
      init = (args...) -> sparse_init(args...; sparsity=0.5)
    else
      # sparse_init is the only one which accepts only matrices:
      @test size(init(3)) == (3,)
      @test size(init(3, 4, 5)) == (3, 4, 5)
    end
    @test size(init(3, 4)) == (3, 4)
    # only init(size...) is accepted:
    @test_throws MethodError size(init((3, 4, 5))) == (3, 4, 5)

    # rng, and currying:
    @test size(init(MersenneTwister(1), 3, 4)) == (3, 4)
    closure = init(MersenneTwister(1))
    @test size(closure(3, 4)) == (3, 4)

    # eltype, default Float32
    @test eltype(init(3, 4)) == Float32

    # @non_differentiable
    @test gradient(x -> sum(x .* init(3, 4)), 5.0)[1] isa Number
  end

  @testset "glorot: $init" for init ∈ [glorot_uniform, glorot_normal]
    # glorot_uniform and glorot_normal should both yield a kernel with
    # variance ≈ 2/(fan_in + fan_out)
    for dims ∈ [(1000,), (100, 100), (100, 400), (2, 3, 32, 64), (2, 3, 4, 32, 64)]
        v = init(dims...)
        fan_in, fan_out = nfan(dims...)
        σ2 = 2 / (fan_in + fan_out)
        @test 0.9σ2 < var(v) < 1.1σ2
    end
    @test eltype(init(3, 4; gain=1.5)) == Float32
  end

  @testset "kaiming" begin
    # kaiming_uniform should yield a kernel in range [-sqrt(6/n_out), sqrt(6/n_out)]
    # and kaiming_normal should yield a kernel with stddev ~= sqrt(2/n_out)
    for (n_in, n_out) in [(100, 100), (100, 400)]
      v = kaiming_uniform(n_in, n_out)
      σ2 = sqrt(6/n_out)
      @test -1σ2  < minimum(v) < -0.9σ2
      @test 0.9σ2  < maximum(v) < 1σ2

      v = kaiming_normal(n_in, n_out)
      σ2 = sqrt(2/n_out)
      @test 0.9σ2 < std(v) < 1.1σ2
    end
    @test eltype(kaiming_uniform(3, 4; gain=1.5)) == Float32
    @test eltype(kaiming_normal(3, 4; gain=1.5)) == Float32
  end

  @testset "orthogonal" begin
    # A matrix of dim = (m,n) with m > n should produce a QR decomposition. In the other case, the transpose should be taken to compute the QR decomposition.
    for (rows,cols) in [(5,3),(3,5)]
      v = orthogonal(rows, cols)
      rows < cols ? (@test v * v' ≈ I(rows)) : (@test v' * v ≈ I(cols))
    end
    for mat in [(3,4,5),(2,2,5)]
      v = orthogonal(mat...)
      cols = mat[end]
      rows = div(prod(mat),cols)
      v = reshape(v, (rows,cols))
      rows < cols ? (@test v * v' ≈ I(rows)) : (@test v' * v ≈ I(cols))
    end
    @test eltype(orthogonal(3, 4; gain=1.5)) == Float32
  end

  @testset "sparse_init" begin
    # sparse_init should yield an error for non 2-d dimensions
    # sparse_init should yield no zero elements if sparsity < 0
    # sparse_init should yield all zero elements if sparsity > 1
    # sparse_init should yield exactly ceil(n_in * sparsity) elements in each column for other sparsity values
    # sparse_init should yield a kernel in its non-zero elements consistent with the std parameter

    @test_throws ArgumentError sparse_init(100, 100, 100, sparsity=0.1)
    v = sparse_init(100, 100, sparsity=-0.1)
    @test sum(v .== 0) == 0
    v = sparse_init(100, 100, sparsity=1.1)
    @test sum(v .== 0) == length(v)

    for (n_in, n_out, sparsity, σ) in [(100, 100, 0.25, 0.1), (100, 400, 0.75, 0.01)]
      expected_zeros = ceil(Integer, n_in * sparsity)
      v = sparse_init(n_in, n_out, sparsity=sparsity, std=σ)
      @test all([sum(v[:,col] .== 0) == expected_zeros for col in 1:n_out])
      @test 0.9 * σ < std(v[v .!= 0]) < 1.1 * σ
    end

    @test eltype(sparse_init(3, 4; std=1.5, sparsity=0.5)) == Float32
  end

  @testset "truncated_normal" begin
    m = truncated_normal(100, 100)
    @test minimum(m) ≈ -2 atol = 0.05  # default arguments
    @test maximum(m) ≈ 2 atol = 0.05
    @test mean(m) ≈ 0 atol = 0.1

    size100 = (100, 100, 100)
    for (μ, σ, lo, hi) in [(0.0, 1, -2, 3), (1, 2, -4.0, 5.0)]
      v = truncated_normal(size100...; mean = μ, std = σ, lo, hi)
      @test isapprox(mean(v), μ; atol = 1f-1)
      @test isapprox(minimum(v), lo; atol = 1f-2)
      @test isapprox(maximum(v), hi; atol = 1f-2)
      @test eltype(v) == Float32  # despite some Float64 arguments
    end
    for (μ, σ, lo, hi) in [(6, 2, -100.0, 100), (-7.0, 10, -100, 100)]
      v = truncated_normal(size100...; mean = μ, std = σ, lo, hi)
      @test isapprox(mean(v), μ; atol = 1f-1)
      @test isapprox(std(v), σ; atol = 1f-1)
    end
  end

  @testset "Partial application" begin
    partial_ku = kaiming_uniform(gain=1e9)
    @test maximum(partial_ku(8, 8)) > 1e9 / 2
    @test maximum(partial_ku(8, 8, gain=1)) < 1e9 / 2

    partial_kn = kaiming_normal(gain=1e9)
    @test maximum(partial_kn(8, 8)) > 1e9 / 2
    @test maximum(partial_kn(8, 8, gain=1)) < 1e9 / 2

    partial_si = sparse_init(sparsity=1)
    @test maximum(partial_si(8, 8)) == 0
    @test maximum(partial_si(8, 8, sparsity=0)) > 0
  end

  @testset "identity_init" begin
    @testset "Basic" begin
      partial = identity_init(gain=3)
      @test partial(3, 3) == identity_init(3, 3; gain=3) == [3 0 0; 0 3 0; 0 0 3]
      @test eltype(identity_init(3, 4; gain=1.5)) == Float32  # despite Float64 keyword
    end
    @testset "Non-identity sizes" begin
        @test identity_init(2, 3)[:, end] == zeros(Float32, 2)
        @test identity_init(3, 2; shift=1)[1, :] == zeros(Float32, 2)
        @test identity_init(1, 1, 3, 4)[:, :, :, end] == zeros(Float32, 1, 1, 3)
        @test identity_init(2, 1, 3, 3)[end, :, :, :] == zeros(Float32, 1, 3, 3)
        @test identity_init(1, 2, 3, 3)[:, end, :, :] == zeros(Float32, 1, 3, 3)
    end
    @testset "Dense ID mapping" begin
        l = Dense(3,3, init = identity_init)

        indata = reshape(collect(Float32, 1:9), 3, 3)
        @test l(indata) == indata
    end
    @testset "$layer ID mapping with kernelsize $kernelsize" for layer in (Conv, ConvTranspose, CrossCor), kernelsize in (
        (1,),
        (3,),
        (1, 3),
        (3, 5),
        (3, 5, 7))
        nch = 3
        l = layer(kernelsize, nch=>nch, init=identity_init, pad=SamePad())

        indata = randn(Float32, kernelsize..., nch, nch)
        @test l(indata) == indata
    end
    @testset "Inception identity" begin
      insize = 7
      path1 = Conv((1, 3), insize=>2; init=identity_init, pad=SamePad())
      path2 = Conv((3, 5), insize=>3; init=identity_init(shift=(0, 0, 2, 0)), pad=SamePad())
      path3 = Conv((5, 7), insize=>2; init=identity_init(shift=(0, 0, 5, 0)), pad=SamePad())
      block = Parallel((xs...) -> cat(xs...;dims=3), path1, path2, path3)

      indata = randn(Float32, 9, 9, 7, 2)
      @test block(indata) == indata
    end
  end
end

@testset "Params" begin
  m = Dense(10, 5)
  @test size.(params(m)) == [(5, 10), (5,)]
  m = RNN(10, 5)
  @test size.(params(m)) == [(5, 10), (5, 5), (5,), (5, 1)]

  # Layer duplicated in same chain, params just once pls.
  c = Chain(m, m)
  @test size.(params(c)) == [(5, 10), (5, 5), (5,), (5, 1)]

  # Self-referential array. Just want params, no stack overflow pls.
  r = Any[nothing,m]
  r[1] = r
  @test size.(params(r)) == [(5, 10), (5, 5), (5,), (5, 1)]
end

@testset "Precision" begin
  m = Chain(Dense(10, 5, relu), Dense(5, 2))
  x64 = rand(Float64, 10)
  x32 = rand(Float32, 10)
  @test eltype(m[1].weight) == Float32
  @test eltype(m(x32)) == Float32
  @test eltype(m(x64)) == Float64
  @test eltype(f64(m)(x32)) == Float64
  @test eltype(f64(m)(x64)) == Float64
  @test eltype(f64(m)[1].weight) == Float64
  @test eltype(f32(f64(m))[1].weight) == Float32
end

@testset "zero bias" begin
  m = Dense(3 => 2; bias=false)
  @test f64(m).bias === m.bias === false
  @test f32(m).bias === m.bias === false

  @testset "Gradients for broadcasted $op with sizes $s" for op in (+,-,*), s in ((1,), (2,3))
    o = ones(s)
    z = zeros(s)

    @testset "Explicit" begin
      gfun(args...) = gradient((x, y) -> sum(op.(x,y)), args...)
      g = gfun(o, z)
      @test gfun(o, false) == (g[1], nothing)

      g = gfun(z, o)
      @test gfun(false, o) == (nothing, g[2])
    end

    @testset "Implicit" begin
      gfun(args...) = gradient(() -> sum(op.(args...)), params(collect(args)))
      g = gfun(o, z)

      gres = gfun(o, false)
      @test gres[o] == g[o]
      @test false ∉ gres.params

      g = gfun(z, o)
      gres = gfun(false, o)
      @test gres[o] == g[o]
      @test false ∉ gres.params
    end
  end
end

@testset "unsqueeze" begin
  x = randn(2, 3, 2)
  @test @inferred(unsqueeze(x, dims=1)) == reshape(x, 1, 2, 3, 2)
  @test @inferred(unsqueeze(x, dims=2)) == reshape(x, 2, 1, 3, 2)
  @test @inferred(unsqueeze(x, dims=3)) == reshape(x, 2, 3, 1, 2)
  @test @inferred(unsqueeze(x, dims=4)) == reshape(x, 2, 3, 2, 1)
end

@testset "Stacking" begin
  x = randn(3,3)
  stacked = stack([x, x], dims=2)
  @test size(stacked) == (3,2,3)

  stacked_array=[ 8 9 3 5; 9 6 6 9; 9 1 7 2; 7 4 10 6 ]
  unstacked_array=[[8, 9, 9, 7], [9, 6, 1, 4], [3, 6, 7, 10], [5, 9, 2, 6]]
  @test unstack(stacked_array, dims=2) == unstacked_array
  @test stack(unstacked_array, dims=2) == stacked_array
  @test stack(unstack(stacked_array, dims=1), dims=1) == stacked_array
end

@testset "Batching" begin
  stacked_array=[ 8 9 3 5
                  9 6 6 9
                  9 1 7 2
                  7 4 10 6 ]
  unstacked_array=[[8, 9, 9, 7], [9, 6, 1, 4], [3, 6, 7, 10], [5, 9, 2, 6]]
  @test unbatch(stacked_array) == unstacked_array
  @test batch(unstacked_array) == stacked_array

  # no-op for vector of non-arrays
  @test batch([1,2,3]) == [1,2,3]
  @test unbatch([1,2,3]) == [1,2,3]

  # generic iterable
  @test batch(ones(2) for i=1:3) == ones(2, 3)
  @test unbatch(ones(2, 3)) == [ones(2) for i=1:3]
end

@testset "Param remapping" begin
  ls(dims...) = reshape(collect(Float32, 1:prod(dims)), dims...) # accepts dims in reverse order to Dense
  dl(nin, nout, bias) = Dense(ls(nout, nin), bias(nout))
  dm(bias) = Chain(
    dl(3, 5, bias),
    dl(5, 4, bias),
    dl(4, 3, bias)
  )

  nobias(n) = false
  testdense(m, bt) = @testset "Check layer $i" for (i, (l1, l2)) in enumerate(zip(m, dm(bt)))
    @test l1.weight == l2.weight
    @test l1.bias == l2.bias
    @test_skip typeof(l1.bias) === typeof(l2.bias)
  end

  @testset "loadparams!" begin
    pars(w, b) = [w, b]
    pars(l) = pars(l.weight, l.bias)
    pararray(m) = mapreduce(pars, vcat, m)
    weights(m) = mapreduce(l -> [l.weight], vcat, m)
    @testset "Bias type $bt" for bt in (Flux.zeros32, nobias)
      m = dm(bt)
      loadparams!(m, params(m))
      testdense(m, bt)
    end
  end

  @testset "destructure" begin
    import Flux: destructure
    @testset "Bias type $bt" for bt in (zeros, nobias)
      m = dm(bt)
      p, re = destructure(m)
      testdense(re(p), bt)
    end

    @testset "restructure in gradient" begin
      x = rand(Float32, 3, 1)
      m = dm(zeros)
      ∇m = gradient(m -> sum(m(x)), m)[1]
      p, re = destructure(m)
      ∇p = gradient(θ -> sum(re(θ)(x)), p)[1]
      @test ∇p ≈ destructure(∇m)[1]
    end
  end
end

@testset "loadparams! & absent bias" begin
  m0 = Chain(Dense(2 => 3; bias=false, init = Flux.ones32), Dense(3 => 1))
  m1 = Chain(Dense(2 => 3; bias = Flux.randn32(3)), Dense(3 => 1))
  m2 = Chain(Dense(Float32[1 2; 3 4; 5 6], Float32[7, 8, 9]), Dense(3 => 1))

  Flux.loadparams!(m1, Flux.params(m2))
  @test m1[1].bias == 7:9
  @test sum(m1[1].weight) == 21

  # load from a model without bias -- should ideally recognise the `false` but `Params` doesn't store it
  @test_broken Flux.loadparams!(m1, Flux.params(m0))
  @test_broken iszero(m1[1].bias)
  @test sum(m1[1].weight) == 6  # written before error

  # load into a model without bias -- should it ignore the parameter which has no home, or error?
  @test_broken Flux.loadparams!(m0, Flux.params(m2))
  @test iszero(m0[1].bias)  # obviously unchanged
  @test sum(m0[1].weight) == 21
end

@testset "Train and test mode" begin
  mutable struct DummyLayer
    testing::Bool
  end
  Flux.testmode!(m::DummyLayer, testing=true) = (m.testing = testing; m)

  c = Chain(DummyLayer(true))
  testmode!(c)
  @test c[1].testing
  trainmode!(c)
  @test !c[1].testing
end

@testset "modules" begin
  m1 = Conv((2,3), 4=>5; pad=6, stride=7)
  m2 = LayerNorm(8)
  m3 = m2.diag
  m4 = SkipConnection(m1, +)
  m5 =  Chain(m4, m2)
  modules = Flux.modules(m5)
  # Depth-first descent
  @test length(modules) == 6
  @test modules[1] === m5
  @test modules[3] === m4
  @test modules[4] === m1
  @test modules[5] === m2
  @test modules[6] === m3

  mod_par = Flux.modules(Parallel(Flux.Bilinear(2,2,2,cbrt), Dense(2,2,abs), Dense(2,2,abs2)))
  @test length(mod_par) == 5

  mod_rnn = Flux.modules(Chain(Dense(2,3), BatchNorm(3), LSTM(3,4)))
  @test length(mod_rnn) == 6
  @test mod_rnn[end] isa Flux.LSTMCell

  mod_skip = Flux.modules(Chain(SkipConnection(
                                  Conv((2,3), 4=>5; pad=6, stride=7),
                                  +),
                                LayerNorm(8)))
  @test length(mod_skip) == 6
  @test mod_skip[end] isa Flux.Diagonal
end

@testset "Patience triggers" begin
  @testset "patience" begin
    trigger = Flux.patience(() -> true, 3)

    @test trigger() == false
    @test trigger() == false
    @test trigger() == true

    v = [false, true, false, true, true, true]
    trigger = let v = v
      Flux.patience(i -> v[i], 3)
    end

    n_iter = 0
    for i in 1:length(v)
      trigger(i) && break
      n_iter += 1
    end

    @test n_iter == 5
  end

  @testset "early stopping" begin
    @testset "args & kwargs" begin
      es = Flux.early_stopping((x; y = 1) -> x + y, 10; min_dist=3)

      n_iter = 0
      while n_iter < 99
        es(-n_iter; y=-n_iter) && break
        n_iter += 1
      end

      @test n_iter == 9
    end

    @testset "distance" begin
      es = Flux.early_stopping(identity, 10; distance=(best_score, score) -> score - best_score)

      n_iter = 0
      while n_iter < 99
        es(n_iter) && break
        n_iter += 1
      end

      @test n_iter == 99
    end

    @testset "init_score" begin
      es = Flux.early_stopping(identity, 10; init_score=10)

      n_iter = 0
      while n_iter < 99
        es(n_iter) && break
        n_iter += 1
      end

      @test n_iter == 10
    end
  end

  @testset "plateau" begin
    f = let v = 10
      () -> v = v / abs(v) - v
    end

    trigger = Flux.plateau(f, 3, init_score=10, min_dist=18)

    n_iter = 0
    while n_iter < 99
      trigger() && break
      n_iter += 1
    end

    @test n_iter == 3
  end
end

@testset "Various destructure bugs" begin

  @testset "issue 1601" begin
    struct TwoDenses
        dense::Dense
        dense2::Dense
    end
    Flux.@functor TwoDenses

    function (m::TwoDenses)(x)
        out = m.dense(x)
    end

    model = TwoDenses(
        Dense(3,1),
        Dense(3,2)
    )
    p, re = Flux.destructure(model)

    x = [1., 2., 3.]
    y, back = Flux.Zygote.pullback((x, p) -> re(p)(x), x, p)

    dy = [4.]
    dx, dp = back(dy)
    @test length(p) == length(dp)
  end

  @testset "issue 1727" begin
    p, re = Flux.destructure(BatchNorm(3))  # 6 parameters, plus 6 non-trainable
    @test length(p) == 6

    x = rand(Float32, 3, 4)
    y, back = Flux.pullback(x, p) do x, p
      vec(re(p)(x))
    end
    @test_nowarn back(y)
    b = back(y)

    @test size(b[1]) == size(x)
    @test size(b[2]) == size(p)
  end

  @testset "issue 1767" begin
    struct Model{A}
        a::A
        b::A
    end
    Flux.@functor Model
    (m::Model)(x) = m.a(x) .+ m.b(x)

    d = Dense(1, 1)
    x = rand(Float32, 1, 1)

    # Sharing the parameters
    model = Model(d, d)

    # Works
    g1 = Flux.gradient(() -> sum(model(x)), Flux.params(model))

    p, re = Flux.destructure(model)
    # Fails
    g2 = Flux.gradient(p -> sum(re(p)(x)), p)

    @test g2[1] ≈ vcat(g1[d.weight], g1[d.bias])
  end

  @testset "issue 1826" begin
    struct Split{T}  # taken from: https://fluxml.ai/Flux.jl/stable/models/advanced/#Multiple-outputs:-a-custom-Split-layer
        paths::T
    end
    Split(paths...) = Split(paths)
    Flux.@functor Split
    (m::Split)(x::AbstractArray) = map(f -> f(x), m.paths)

    n_input, n_batch, n_shared = 5, 13, 11
    n_outputs = [3, 7]

    data = rand(Float32, n_input, n_batch)
    model = Chain(
        Dense(n_input, n_shared),
        Split(Dense(n_shared, n_outputs[1]), Dense(n_shared, n_outputs[2]))
    )

    pvec, re = Flux.destructure(model)
    loss(x, idx, pv) = sum(abs2, re(pv)(x)[idx])  # loss wrt `idx`th output term

    g = Flux.Zygote.ForwardDiff.gradient(pv -> loss(data, 1, pv), pvec)
    @test g ≈ Flux.Zygote.gradient(pv -> loss(data, 1, pv), pvec)[1]
  end

end


text:
# ---
# title: 674. Longest Continuous Increasing Subsequence
# id: problem674
# author: Tian Jun
# date: 2020-10-31
# difficulty: Easy
# categories: Array
# link: <https://leetcode.com/problems/longest-continuous-increasing-subsequence/description/>
# hidden: true
# ---
#
# Given an unsorted array of integers `nums`, return _the length of the longest
# **continuous increasing subsequence** (i.e. subarray)_. The subsequence must
# be **strictly** increasing.
#
# A **continuous increasing subsequence** is defined by two indices `l` and `r`
# (`l < r`) such that it is `[nums[l], nums[l + 1], ..., nums[r - 1], nums[r]]`
# and for each `l <= i < r`, `nums[i] < nums[i + 1]`.
#
#
#
# **Example 1:**
#
#
#
#     Input: nums = [1,3,5,4,7]
#     Output: 3
#     Explanation: The longest continuous increasing subsequence is [1,3,5] with length 3.
#     Even though [1,3,5,7] is an increasing subsequence, it is not continuous as elements 5 and 7 are separated by element
#     4.
#
#
# **Example 2:**
#
#
#
#     Input: nums = [2,2,2,2,2]
#     Output: 1
#     Explanation: The longest continuous increasing subsequence is [2] with length 1. Note that it must be strictly
#     increasing.
#
#
#
#
# **Constraints:**
#
#   * `0 <= nums.length <= 104`
#   * `-109 <= nums[i] <= 109`
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end


text:
using Knet
using CUDA
include("Layers.jl")

moments1 = [bnmoments(), bnmoments()]
params1 = [param(bnparams(1024)), param(bnparams(1024))]
ResUpBlock1 = Chain(BNorm(1024,moments1[1],params1[1],true),
                   Upsample(2),
                   Conv3x3(1024,1024,false),
                   BNorm(1024,moments1[2],params1[2],true),
                   Conv3x3(1024,1024,false))
Residual1 = Chain(Upsample(2),Conv1x1(1024,1024,false))

moments2 = [bnmoments(), bnmoments()]
params2 = [param(bnparams(1024)), param(bnparams(512))]
ResUpBlock2 = Chain(BNorm(1024,moments2[1],params2[1],true),
                   Upsample(2),
                   Conv3x3(1024,512,false),
                   BNorm(512,moments2[2],params2[2],true),
                   Conv3x3(512,512,false))
Residual2 = Chain(Upsample(2),Conv1x1(1024,512,false))

moments3 = [bnmoments(), bnmoments()]
params3 = [param(bnparams(1024)), param(bnparams(256))]
ResUpBlock3 = Chain(BNorm(1024,moments3[1],params3[1],true),
                   Upsample(2),
                   Conv3x3(1024,256,false),
                   BNorm(256,moments3[2],params3[2],true),
                   Conv3x3(256,256,false))
Residual3 = Chain(Upsample(2),Conv1x1(1024,256,false))

moments4 = [bnmoments(), bnmoments()]
params4 = [param(bnparams(256)), param(bnparams(128))]
ResUpBlock4 = Chain(BNorm(256,moments4[1],params4[1],true),
                   Upsample(2),
                   Conv3x3(256,128,false),
                   BNorm(128,moments4[2],params4[2],true),
                   Conv3x3(128,128,false))
Residual4 = Chain(Upsample(2),Conv1x1(256,128,false))

moments5 = [bnmoments(), bnmoments()]
params5 = [param(bnparams(128)), param(bnparams(64))]
ResUpBlock5 = Chain(BNorm(128,moments5[1],params5[1],true),
                   Upsample(2),
                   Conv3x3(128,64,false),
                   BNorm(64,moments5[2],params5[2],true),
                   Conv3x3(64,64,false))
Residual5 = Chain(Upsample(2),Conv1x1(128,64,false))

conditioning_dim = 128
rnn_out_dim = 1024
noise_dim = 100
batch_size = 5
image_feat_dim = 512
ConditionProjector = Chain(Dense(rnn_out_dim,conditioning_dim))
fc1 = Chain(Dense(noise_dim + conditioning_dim,1024 * 4 * 4))
params = param(bnparams(64))
moments = bnmoments()
bn = BNorm(64, moments, params,true)
conv = Chain(Conv3x3(64,3,false))

function forward(y,z,img_feats)
    y_cond = ConditionProjector(y)
    z = vcat(z, y_cond)
    x = fc1(z)
    x = reshape(x, 4, 4, 1024, batch_size)

    x_res = Residual1(x)
    x = ResUpBlock1(x)
    x = x + x_res

    x_res = Residual2(x)
    x = ResUpBlock2(x)
    x = x + x_res

    x = cat(x, img_feats, dims=3)

    x_res = Residual3(x)
    x = ResUpBlock3(x)
    x = x + x_res

    x_res = Residual4(x)
    x = ResUpBlock4(x)
    x = x + x_res

    x_res = Residual5(x)
    x = ResUpBlock5(x)
    x = x + x_res

    x = bn(x)
    x = conv(x)
    x = tanh.(x)
end


text:
module NotifyOverheads

using DataFrames
using DataFrames: AbstractDataFrame
using Plots
using ThreadsAPIBenchmarks: load_notify_overheads

load_rawdf(args...; kwargs...) =
    DataFrame(collect(load_notify_overheads(args...; kwargs...)))

function df_notify_overheads(rawdf::AbstractDataFrame)
    df = select(rawdf, Not(:notified))
    df[!, :max] = maximum.(rawdf.notified) .- df.pre
    df[!, :min] = minimum.(rawdf.notified) .- df.pre
    df[!, :notify] = df.post .- df.pre
    return df
end

function plot_hists(rawdf::AbstractDataFrame)
    df = df_notify_overheads(rawdf)

    groups = groupby(df, :nthreads, sort = true)
    colors = getindex.(Ref(cgrad(:vik)), range(0, 1, length = length(groups)))
    plt_max = plot()
    plt_min = plot()
    plt_notify = plot()
    xmin = 1e3
    xmax = 1e6
    xlim = (xmin, xmax)

    for (i, (k, g)) in enumerate(pairs(groups))
        stephist!(
            plt_max,
            g.max,
            # label = "N=$(k.nthreads)",
            label = "",
            color = colors[i],
            linewidth = 4,
        )
        stephist!(
            plt_min,
            g.min,
            # label = "N=$(k.nthreads)",
            label = "",
            color = colors[i],
            linewidth = 4,
        )
        stephist!(
            plt_notify,
            g.notify,
            label = "N=$(k.nthreads)",
            # label = "",
            color = colors[i],
            linewidth = 4,
        )
    end

    return plot(
        plot!(plt_max, ylabel = "max"),
        plot!(plt_min, ylabel = "min"),
        plot!(plt_notify, ylabel = "notify", xlabel = "overhead [ns] (log scale)"),
        yticks = nothing,
        layout = (3, 1),
        # layout = (2, 1),
        xlim = xlim,
        xscale = :log10,
        left_margin = 5 * Plots.mm,
    )
end

function plot_seq(rawdf::AbstractDataFrame)
    groups = groupby(rawdf, :nthreads, sort = true)
    colors = getindex.(Ref(cgrad(:vik)), range(0, 1, length = length(groups)))
    plts = map(enumerate(pairs(groups))) do (i, (k, g))
        xs_notified = [i for (i, xs) in enumerate(g.notified) for _ in xs]
        ys_notified = [x - pre for (pre, xs) in zip(g.pre, g.notified) for x in xs]
        ys_notify = g.post .- g.pre
        p = plot()
        scatter!(
            p,
            xs_notified,
            ys_notified,
            markershape = :xcross,
            markersize = 1,
            label = i == 1 ? "notified" : "",
            ylabel = "overhead [ns] (N=$(k.nthreads))",
            xlabel = "trial",
        )
        scatter!(
            p,
            ys_notify,
            markershape = :cross,
            markersize = 3,
            label = i == 1 ? "notify" : "",
        )
        return p
    end

    exs = map(zip(rawdf.pre, rawdf.post, rawdf.notified)) do (pre, post, notified)
        l, h = extrema(notified .- pre)
        d = post - pre
        return (min(l, d), max(h, d))
    end

    ymax = nextpow(10, maximum(last, exs))
    ymin = prevpow(10, minimum(first, exs))
    return plot(plts...; ylim = (ymin, ymax), yscale = :log10)
end

function analyze(args...; kwargs...)
    rawdf = load_rawdf(args...; kwargs...)
    return (
        rawdf = rawdf,
        hists = plot_hists(rawdf),
        seq = plot_seq(rawdf),
        #
    )
end

end # module NotifyOverheads


text:
type FastBreeder <: Breeder
  # The eigentype for this breeder.
  eigen::Type

  # The terminal source of this breeder.
  source::BreederSource

  FastBreeder() = new()
end

"""
Provides a definition for composing a fast breeder.
"""
type FastBreederDefinition <: BreederDefinition
  """
  A list containing definitions for the different sources used by this breeder.
  """
  sources::Vector{BreederSourceDefinition}
end

"""
Composes a fast breeder from a provided definition.
"""
function compose!(def::FastBreederDefinition, species::Species)
  b = FastBreeder()
  b.eigen = anonymous_type(breeder)

  # Construct a dictionary containing the sources for this breeder, indexed by
  # their labels.
  sd_dict = Dict{AbstractString, BreederSourceDefinition}(
    [(s.label, s) for s in def.sources]
  )
  labels = map(s -> s.label, def.sources)

  # Calculate the order of the breeding sources.
  i = 1
  while i < length(labels)
    gt_i = findfirst(labels) do j
      isa(sd_dict[labels[i]], VariationBreederSourceDefinition) &&
        sd_dict[labels[i]].source == j
    end
    if gt_i != 0 && gt_i > i
      labels[gt_i], labels[i] = labels[i], labels[gt_i]
    else
      i += 1
    end
  end

  # Compose each of the breeding sources, in the established order.
  sources = Dict{AbstractString, BreederSource}()
  for label in labels
    sources[label] = compose!(sd_dict[label], species, sources)
  end

  # Determine the terminal breeding source.
  b.source = sources[labels[end]]

  # Build the synchronisation operations.
  build_sync(species, b)
  b
end

"""
TODO: Document breeder.fast
"""
fast(sources::Vector{BreederSourceDefinition}) =
  FastBreederDefinition(sources)

# Returns a list of the sources to a breeding operation or a breeder.
sources(s::Union{VariationBreederSource, FastBreeder}) = if isa(s.source, MultiBreederSource)
  return s.source.sources
else
  return BreederSource[s.source]
end

breed!(
  b::FastBreeder,
  s::Species,
  members::IndividualCollection,
  capacity::Int,
  num_offspring::Int
) =
  breed!(b.source, s, members, num_offspring, b)

"""
Produces a requested number of (proto-)offspring from a multiple breeding source.
"""
function breed!(
  s::MultiBreederSource,
  sp::Species,
  members::IndividualCollection,
  n::Int,
  caller::Union{FastBreeder, BreederSource}
)
  proportions = proportion(n, s.proportions)
  vcat([breed!(s.sources[i], sp, members, proportions[i], caller) for i in 1:length(s.sources)])
end

# Produces a requested number of individuals for breeding using a given selection source.
# Each selected individual is cloned to avoid changes to the original population.
function breed!{I <: Individual}(
  s::SelectionBreederSource,
  species::Species,
  members::Vector{I},
  n::Int,
  caller::Union{FastBreeder, BreederSource}
)
  inds = select(s.operator, species, members, n)
  map!(clone, inds)
  sync(s.eigen, caller.eigen, species, inds)
end

function breed!{I <: Individual}(
  s::VariationBreederSource,
  sp::Species,
  members::Vector{I},
  n::Int,
  caller::Union{FastBreeder, BreederSource}
)
  # Full-time cache?

  # Cache the number of inputs and outputs to this operator.
  op_inputs = num_inputs(s.operator)
  op_outputs = num_outputs(s.operator)

  # Cache.
  buffer_individuals = Array(I, op_inputs)

  # Calculate the number of calls to the operator that are necessary to
  # produce the desired number of individuals.
  calls = ceil(Integer, n / op_outputs)

  # Generate the necessary input proto-offspring.
  inputs = breed!(s.source, sp, members, calls * op_outputs, s)

  # Now we need to synchronise the representation graph of our proto-offspring, such
  # that the stage that this operator works on is marked as clean.

  # If we're calling another variator directly, then we simply need to call a
  # lambda function, "prepare", which is applied to a homogeneous array of individuals.

  # But if our individuals come from a multi-source, we need to prepare each source
  # in a different way.

  # Produce the offspring.
  outputs = Array(I, calls * op_outputs)
  outputs_to = 0
  for c in 1:calls
    inputs_to = op_inputs * c
    inputs_from = inputs_to - op_inputs + 1

    outputs_to = op_outputs * c
    outputs_from = outputs_to - op_outputs + 1

    # Lots of room for optimisation.
    buffer_individuals = inputs[inputs_from:inputs_to]

    call!(s.operator, s.stage_getter, buffer_individuals)
    #operate!(s.operator, map(s.stage, buffer_individuals))

    outputs[outputs_from:outputs_to] = buffer_individuals
  end

  # Limit the number of produced offspring to the number desired.
  # (Is it faster to limit, or to not produce more than you need?)
  return sync(s.eigen, caller.eigen, sp, outputs[1:n])
end

# Load the components of this breeder.
include("fast/builder.jl")


text:
#=
This file is auto-generated. Do not edit.
=#
"""
    mutable struct Order <: Edit
        col::Array{Symbol,1}
        type::Array{DataType,1}
    end

Rearranges columns in the order specified by `cols` and sets them to the specified type.

# Arguments
- `col::Array{Symbol,1}`: Ordered list of DataFrame columns
- `type::Array{DataType,1}`: Ordered column types.
"""
mutable struct Order <: Edit
    "Ordered list of DataFrame columns"
    col::Array{Symbol,1}
    "Ordered column types."
    type::Array{DataType,1}
end

function Order(; col, type, )
    Order(col, type, )
end

"""Get [`Order`](@ref) `col`."""
get_col(value::Order) = value.col
"""Get [`Order`](@ref) `type`."""
get_type(value::Order) = value.type

"""Set [`Order`](@ref) `col`."""
set_col!(value::Order, val) = value.col = val
"""Set [`Order`](@ref) `type`."""
set_type!(value::Order, val) = value.type = val

max_stars_repo_name: matbesancon/SLiDE

max_issues_repo_name: matbesancon/SLiDE

max_forks_repo_name: matbesancon/SLiDE


text:
using Decimals
using Compat.Test
using Compat: @info

@testset "Deprecated Functions" begin
    @info("The following deprecation warnings are expected")

    @test inv(d) == map(inv, d)

    @test 1 + d == 1 .+ d
    @test d + 3.0 == d .+ 3.0
    @test 8.0 - d == 8.0 .- d
    @test d - 10 == d .- 10
    @test [1] + d == [1] .+ d
    @test d + [3.0] == d .+ [3.0]
    @test [8.0] - d == [8.0] .- d
    @test d - [10] == d .- [10]

    @test number(d) == number.(d)
    @test all(isint.([0, -102, 0x99]))
    @test !any(isint.(float.(d)))
    @test !any(isint.(string.(d)))

    @test decimal(float(d)) == d
end


text:
__precompile__()
module LocalModule

using Distributed
export myapp

function myapp()
    p = addprocs(1)
    @everywhere p println("Taking over the world...")
    rmprocs(p)
    nothing
end

end

max_stars_repo_name: YingboMa/julia

max_issues_repo_name: YingboMa/julia

max_forks_repo_name: YingboMa/julia


text:
function _next_10_multiple(x::Int)
	while x % 10 != 0
		x = x + 1
	end
	return x
end

function _is_working_end_time(time::DateTime)
	return Dates.hour(time) >= WORK_END
end

function _is_school_end_time(time::DateTime)
	return Dates.hour(time) >= SCHOOL_END
end

function _is_morning(time::DateTime)
	return DAY_START <= Dates.hour(time) < DAY_MEDIAN
end

function _is_afternoon(time::DateTime)
	return DAY_MEDIAN <= Dates.hour(time) < WORK_END
end

function _is_evening(time::DateTime)
	return WORK_END <= Dates.hour(time) < DAY_END
end

function _is_holiday(time::DateTime)
	return Dates.issaturday(time) || Dates.issunday(time)
end

function _get_day_phase(time::DateTime)
	if _is_morning(time)
		return MORNING
	elseif _is_afternoon(time)
		return AFTERNOON
	elseif _is_evening(time)
		return EVENING
	end
end

"""
	Return exact age, or the Integer mean between min and max age
"""
function calculate_age(exact,min,max)
	return exact != -1 ? exact : (min == -1 || max == -1 ? -1 : floor(Int,(min+max)/2) )
end

function is_student(p)
	return p.part_occupation == SCHOOL
end

function is_worker(p)
	return p.part_occupation == WORKING
end

function is_home(p)
	return p.part_occupation == UNEMPLOYED
end

# function divide_students_by_age(students)
# 	pre_school_students = []
# 	primary_students = []
# 	secondary_students = []
# 	higher_students = []
# 	for student in students
# 		if student.age <= PRE_SCHOOL_LIMIT
# 			push!(pre_school_students,student)
# 		elseif student.age <= PRIMARY_SCHOOL_LIMIT
# 			push!(primary_students,student)
# 		elseif student.age <= SECONDARY_SCHOOL_LIMIT
# 			push!(secondary_students,student)
# 		else
# 			push!(higher_students,student)
# 		end
# 	end

# 	return pre_school_students,primary_students, secondary_students, higher_students
# end

max_stars_repo_name: Luigi-Crisci/Hypergraphs-Epidemics

max_issues_repo_name: Luigi-Crisci/Hypergraphs-Epidemics

max_forks_repo_name: Luigi-Crisci/Hypergraphs-Epidemics


text:
typeof(1000)
sizeof(1000)
Sys.WORD_SIZE
pi
x="Hello"
typeof(x)
x=1,153
typeof(x)
x=1.153
typeof(x)
π
🎱='8'
typeof(🎱)
pi=3
#ja foi usada acima
Int
Int128
0xfa
(typemin(Int64), typemax(Int64))
for T in [Int8,Int16,Int32,Int64,Int128,UInt8,UInt16,UInt32,UInt64,UInt128]
    println("$(lpad(T,7)): [$(typemin(T)),$(typemax(T))]")
end

for T in [Int8,Int16,Int32,Int64,Int128]
    println("$(lpad(T,7)): $(sizeof(T)) Bytes")
end

y = typemax(Int64)
y+1 == typemin(Int64)
y+2
25/0
typemin(Int64)/-1
Float32(-1.56)
10_000
0.0 == -0.0
bitstring(0.0)
bitstring(-0.0)
Inf
-Inf
NaN
1/Inf
1/0
-1/0
0/0
Inf - Inf
0*Inf

(typemin(Float32), typemax(Float32))
eps(Float32)
2.0^-23
eps()
2.0^-52
eps(1.0)+1.0
nextfloat(1.0)
prevfloat(1.0)
big"12345678901234567890"+1
parse(BigInt, "12345678901234567890") +1
big"1.23456789012345678901"
parse(BigFloat, "1.23456789012345678901")
BigFloat(2.0^66) / 3
factorial(BigInt(1000000))
factorial(BigInt(40))
x = typemin(Int64)
x -= 1
typeof(x)
y = BigInt(typemin(Int64))
y -= 1
typeof(y)

setrounding(BigFloat, RoundUp) do
    BigFloat(1) + parse(BigFloat, "0.1")
end

setrounding(BigFloat, RoundDown) do
    BigFloat(1) + parse(BigFloat, "0.1")
end

setprecision(100) do
    BigFloat(1) + parse(BigFloat, "0.1")
end # do

[typemin(BigFloat), typemax(BigFloat)]
x = 3
2x^2 - 3x + 1
1.5x^2 - .5x +1
2^2x
2^(2x)
2(x-1)^2 - 3(x-1) +1
√2x
√(2x)
2x^3
2(x^3)
(2x)^3
(x-1)x
(x-1)(x+1)
x(x+1)
#nesses casos necessita do *
(x-1)*(x+1)
x*(x+1)
#evitar nomes de var como 0xaff, 1e10, 1.5f22
#conflito, 0 * xaff , 1 * e10 , 1.5 * 5f22
zero(Float32)
one(BigFloat)
#literal 0 and 1

max_stars_repo_name: Mutanne/hiworld

max_issues_repo_name: Mutanne/hiworld

max_forks_repo_name: Mutanne/hiworld


text:
module SpringCollab2020DisableIcePhysicsTrigger

using ..Ahorn, Maple

@mapdef Trigger "SpringCollab2020/DisableIcePhysicsTrigger" DisableIcePhysicsTrigger(x::Integer, y::Integer,
    width::Integer=Maple.defaultTriggerWidth, height::Integer=Maple.defaultTriggerHeight, disableIcePhysics::Bool=true)

const placements = Ahorn.PlacementDict(
    "Disable Ice Physics (Spring Collab 2020)" => Ahorn.EntityPlacement(
        DisableIcePhysicsTrigger,
        "rectangle"
    )
)

end


text:
v = 1:999
println(sum(v[(v .% 3 .== 0) .| (v .% 5 .== 0)]))

max_stars_repo_name: shanedrabing/project-euler

max_issues_repo_name: shanedrabing/project-euler

max_forks_repo_name: shanedrabing/project-euler


text:
using RecipesBase
using DiffEqBase
import StaticArrays:SVector

abstract type AbstractTrajectory{uType,tType} end

"""
    Trajectory(u, t[, i])

A trajectory represented as a list of events.

# Fields

- `t`: Vector of event times.
- `u`: Vector of the same length as `t`. `u[i]` is the vector of copy numbers in the interval from `t[i-1]` to `t[i]`.
- `i`: A vector of event/reaction indices corresponding to the event times `t`. If empty, no event indices were recorded.

# Indexing

Indexing a trajectory with an integer index yields a tuple `(u, t, i)`. `u` is the trajectory value **before** the event at time `t`!
"""
struct Trajectory{uType<:AbstractVector,tType<:Real} <: AbstractTrajectory{uType,tType}
    u::Vector{uType} # vector of length N. u[i] is the vector of copy numbers in the interval from t[i-1] to t[i]
    t::Vector{tType} # vector of length N, recording the reaction times and the end time of the trajectory
    i::Vector{Int} # vector of length N recording all reaction indices, or empty vector if no reaction indices
end

Trajectory(u::Vector{<:AbstractVector}, t::Vector) = Trajectory(u, t, Int[])

Base.copy(traj::Trajectory) = Trajectory(copy(traj.u), deepcopy(traj.t), copy(traj.i))

Base.getindex(traj::Trajectory, idx::Int) = (traj.u[idx], traj.t[idx], idx > length(traj.i) ? 0 : traj.i[idx])
Base.:(==)(traj1::Trajectory, traj2::Trajectory) = (traj1.t == traj2.t) && (traj1.u == traj2.u) && (traj1.i == traj2.i)

function (t::Trajectory)(time::Real)
    index = searchsortedfirst(t.t, time)
    if t.t[index] == time && index != lastindex(t.t)
        index += 1
    end
    if index > lastindex(t.t)
        error("Can't access trajectory that ends at t=$(last(t.t)) at time $time.")
    end
    t.u[index]
end

function (t::Trajectory)(times::AbstractArray{<:Real})
    hcat(t.(times)...)
end

function Trajectory(u::AbstractMatrix{T}, t::AbstractVector{tType}, i=Int[]) where {tType <: Real,T <: Real}
    num_components = size(u, 1)
    if num_components > 0
        u_vec = [SVector{num_components}(c) for c in eachcol(u)]
    else
        u_vec = SVector{0,T}[]
    end

    Trajectory(u_vec, convert(Vector{tType}, t), i)
end

function Trajectory(t::Trajectory)
    t
end

function Trajectory(sol::ODESolution)
    Trajectory(sol.u[begin:end-1], sol.t[begin+1:end])
end

Base.length(traj::AbstractTrajectory) = length(traj.t)
Base.firstindex(traj::AbstractTrajectory) = 1
Base.lastindex(traj::AbstractTrajectory) = length(traj)

function duration(traj::AbstractTrajectory)
    if length(traj) == 0
        return 0.0
    end
    traj.t[end] - traj.t[begin]
end

function Base.iterate(traj::Trajectory, index=1)
    index > length(traj) && return nothing
    traj[index], index + 1
end

Base.eltype(::Type{T}) where {uType,tType,T <: AbstractTrajectory{uType,tType}} = Tuple{uType,tType,Int}

function collect_trajectory(iter, nocopy=false)
    ((u, t, i), state) = iterate(iter)
    traj = Trajectory([nocopy ? u : copy(u)], [t], Int[i])

    for (u, t, i) in Iterators.rest(iter, state)
        push!(traj.t, t)
        push!(traj.u, nocopy ? u : copy(u))
        push!(traj.i, i)
    end

    traj
end

@recipe function f(traj::AbstractTrajectory{uType,tType}) where {uType,tType}
    seriestype --> :steppre
    # label --> hcat([String(sym) for sym in traj.syms]...)

    N = length(traj.u[1])
    uvec = zeros(eltype(uType), length(traj), N)
    tvec = zeros(tType, length(traj))
    for (i, (u, t)) in enumerate(traj)
        uvec[i, :] = u
        tvec[i] = t
    end

    tvec, uvec
end


text:
using JuMP, Ipopt, Juniper
using LinearAlgebra # for the dot product
optimizer = Juniper.Optimizer
nl_solver = optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0)

model = Model(optimizer_with_attributes(optimizer, "nl_solver" => nl_solver))

# model = Model(with_optimizer(Ipopt.Optimizer))
# set_optimizer_attribute(model, "max_cpu_time", 60.0)
# set_optimizer_attribute(display_verblevel=1,limits_gap=0.05)
# set_optimizer_attribute(model, print_level=1)

# Declare variables
a = 1
b = -1

@variable(model, -5 <= M <= -1, start = b,integer = true)
@variable(model, -5 <= D <= -1, start = b,integer = true)
@variable(model, -5 <= A <= -1, start = b,integer = true)
@variable(model, -5 <= Li <= -1, start = b,integer = true)
@variable(model, -5 <= Coda <= -1, start = b,integer = true)
@variable(model, -5 <= L <= -1, start = b,integer = true)
@variable(model, -5 <= Id <= -3, start = 2 * b,integer = true)

@variable(model, 0.01 <= α <= 0.9, start = 0.2)
@variable(model, 0.01 <= β <= 0.9, start = 0.9)
@variable(model, 0.01 <= γ <= 0.9, start = 0.4)
@variable(model, 0.01 <= δ <= 0.5, start = 0.5)
@variable(model, 0.5 <= ϵ <= 0.9, start = 0.7)

# δ = .3
# ϵ = .8

# Objective function : Harmony of the winner
@objective(model, Min, M * (α + γ + δ) + D * (2 - β - ϵ) + Id)

# Winner Harmony
winner = @expression(model, M * (α + γ + δ) + D * (2 - β - ϵ) + Id)

bhudta = @expression(model, winner - (M * (β + γ + δ) + D * (2 - α - ϵ) + A))
@constraint(model, bhudta >= a)

budhta = @expression(model, winner - (M * (α + γ + δ) + D * (2 - β - ϵ) + A + Li))
@constraint(model, budhta >= a)

budhita = @expression(model, winner - (M * (α + γ + δ) + D * (3 - β - ϵ)))
@constraint(model, budhita >= a)

# Fake constraints -> realistisch
# @constraint(model, δ <= ϵ - 0.10)
# @constraint(model, α <= β - 0.10)
# @constraint(model, γ <= β - 0.10)

display(model)

# Optimize / Solve
optimize!(model)

# Printing logic
println(JuMP.objective_value(model))
println(JuMP.termination_status(model))
println(JuMP.primal_status(model))
println("Max = ", value(M))
println("Dep = ", value(D))
println("Assimilate = ", value(A))
println("License = ", value(Li))
println("Coda = ", value(Coda))
println("Lazy = ", value(L))
println("Ident lar = ", value(Id))
println("bhud = ", value(α))
println("budh = ", value(β))
println("bhut = ", value(γ))
println("dha = ", value(δ))
println("ta = ", value(ϵ))

max_stars_repo_name: amasotti/grascom

max_issues_repo_name: amasotti/grascom

max_forks_repo_name: amasotti/grascom


text:
### Defines all multiplication routines for HssMatrices
#
# Matrix-vector multiplication
# as seen in
# Chandrasekaran, S., Dewilde, P., Gu, M., Lyons, W., & Pals, T. (2006). A fast solver for HSS representations via sparse matrices.
# SIAM Journal on Matrix Analysis and Applications, 29(1), 67–81. https://doi.org/10.1137/050639028
#
# Written by Boris Bonev, Nov. 2020

## PROMOTOE - look at LowRankApprox again
## TODO: read about promotion and improve the code
# convenience access - TODO: maybe move to hssmatrix.jl in the future
*(hssA::HssMatrix, B::AbstractMatrix) = mul!(similar(B, size(hssA,1), size(B,2)), hssA, B, 1., 0.)
*(A::AbstractMatrix, hssB::HssMatrix) = copy(mul!(similar(A, size(hssB,2), size(A,1)), hssB', copy(A'), 1., 0.)')
*(hssA::HssMatrix, x::AbstractVector) = reshape(hssA * reshape(x, length(x), 1), length(x))

# implement low-level mul! routines
function mul!(C::AbstractMatrix, hssA::HssMatrix, B::AbstractMatrix, α::Number, β::Number)
  size(hssA,2) == size(B,1) ||  throw(DimensionMismatch("First dimension of B does not match second dimension of A. Expected $(size(A, 2)), got $(size(B, 1))"))
  size(C) == (size(hssA,1), size(B,2)) ||  throw(DimensionMismatch("Dimensions of C don't match up with A and B."))
  if isleaf(hssA)
    return mul!(C, hssA.D, B, α, β)
  else
    hssA = rooted(hssA) # this is to avoid top-generators getting in the way if this is called on a sub-block of the HSS matrix
    Z = _matmatup(hssA, B) # saves intermediate steps of multiplication in a binary tree structure
    return _matmatdown!(C, hssA, B, Z, nothing, α, β)
  end
end

## auxiliary functions for the fast multiplication algorithm
# post-ordered step of mat-vec
function _matmatup(hssA::HssMatrix, B::AbstractMatrix)
  if isleaf(hssA)
    return BinaryNode(hssA.V' * B)
  else
    n1 = hssA.sz1[2]
    Z1 = _matmatup(hssA.A11, B[1:n1,:])
    Z2 = _matmatup(hssA.A22, B[n1+1:end,:])
    Z = BinaryNode(hssA.W1'*Z1.data .+ hssA.W2'*Z2.data, Z1, Z2)
    return Z
  end
end

function _matmatdown!(C::AbstractMatrix{T}, hssA::HssMatrix{T}, B::AbstractMatrix{T}, Z::BinaryNode{AT}, F::Union{AbstractMatrix{T}, Nothing}, α::Number, β::Number) where {T, AT<:AbstractArray{T}}
  if isleaf(hssA)
    mul!(C, hssA.D, B , α, β)
    if !isnothing(F); mul!(C, hssA.U, F , α, 1.); end
    return C
  else
    m1, n1 = hssA.sz1
    if !isnothing(F)
      F1 = hssA.B12 * Z.right.data + hssA.R1 * F
      F2 = hssA.B21 * Z.left.data + hssA.R2 * F
    else
      F1 = hssA.B12 * Z.right.data
      F2 = hssA.B21 * Z.left.data
    end
    _matmatdown!(@view(C[1:m1,:]), hssA.A11, @view(B[1:n1,:]), Z.left, F1, α, β)
    _matmatdown!(@view(C[m1+1:end,:]), hssA.A22, @view(B[n1+1:end,:]), Z.right, F2, α, β)
    return C
  end
end

## multiplication of two HSS matrices
function *(hssA::HssMatrix, hssB::HssMatrix)
  if isleaf(hssA) && isleaf(hssA)
    hssC = HssMatrix(hssA.D*hssB.D, hssA.U, hssB.V, true)
  elseif isbranch(hssA) && isbranch(hssA)
    hssA = rooted(hssA); hssB = rooted(hssB)
    # implememnt cluster equality checks
    #if cluster(hssA,2) != cluster(hssB,1); throw(DimensionMismatch("clusters of hssA and hssB must be matching")) end
    Z = _matmatup(hssA, hssB) # saves intermediate steps of multiplication in a binary tree structure
    F1 = hssA.B12 * Z.right.data * hssB.B21
    F2 = hssA.B21 * Z.left.data * hssB.B12
    B12 = blkdiagm(hssA.B12, hssB.B12)
    B21 = blkdiagm(hssA.B21, hssB.B21)
    A11 = _matmatdown!(hssA.A11, hssB.A11, Z.left, F1)
    A22 = _matmatdown!(hssA.A22, hssB.A22, Z.right, F2)
    hssC = HssMatrix(A11, A22, B12, B21, true)
  else
    error("Clusters don't seem to match")
  end
  return hssC
end

function _matmatup(hssA::HssMatrix{T}, hssB::HssMatrix{T}) where T<:Number
  if isleaf(hssA) & isleaf(hssB)
    return BinaryNode{Matrix{T}}(hssA.V' * hssB.U)
  elseif isbranch(hssA) && isbranch(hssB)
    Z1 = _matmatup(hssA.A11, hssB.A11)
    Z2 = _matmatup(hssA.A22, hssB.A22)
    return BinaryNode(hssA.W1' * Z1.data * hssB.R1 + hssA.W2' * Z2.data * hssB.R2, Z1, Z2)
  end
end

function _matmatdown!(hssA::HssMatrix{T}, hssB::HssMatrix{T}, Z::BinaryNode{Matrix{T}}, F::Matrix{T}) where T
  if isleaf(hssA) & isleaf(hssB)
    D = hssA.D * hssB.D + hssA.U * F * hssB.V'
    U = [hssA.U hssA.D * hssB.U]
    V = [hssB.D' * hssA.V hssB.V]
    return HssMatrix(D, U, V, false)
  elseif isbranch(hssA) && isbranch(hssB)
    # evaluate cross terms
    F1 = hssA.B12 * Z.right.data * hssB.B21 + hssA.R1 * F * hssB.W1'
    F2 = hssA.B21 * Z.left.data * hssB.B12 + hssA.R2 * F * hssB.W2'
    B12 = [hssA.B12 hssA.R1 * F * hssB.W2'; zeros(size(hssB.B12, 1), size(hssA.B12,2)) hssB.B12]
    B21 = [hssA.B21 hssA.R2 * F * hssB.W1'; zeros(size(hssB.B21, 1), size(hssA.B21,2)) hssB.B21]
    R1 = [hssA.R1 hssA.B12 * Z.right.data * hssB.R2; zeros(size(hssB.R1,1), size(hssA.R1,2)) hssB.R1];
    W1 = [hssA.W1 zeros(size(hssA.W1,1), size(hssB.W1,2)); hssB.B21' * Z.right.data' * hssA.W2 hssB.W1];
    R2 = [hssA.R2 hssA.B21 * Z.left.data * hssB.R1; zeros(size(hssB.R2,1), size(hssA.R2,2)) hssB.R2];
    W2 = [hssA.W2 zeros(size(hssA.W2,1), size(hssB.W2,2)); hssB.B12' * Z.left.data' * hssA.W1 hssB.W2];
    A11 = _matmatdown!(hssA.A11, hssB.A11, Z.left, F1)
    A22 = _matmatdown!(hssA.A22, hssB.A22, Z.right, F2)
    return HssMatrix(A11, A22, B12, B21, R1, W1, R2, W2, false)
  else
    error("Clusters don't seem to match")
  end
end


text:
module Loudspeakers

export fillinsert, rfft, irfft
export normdeg, deltadeg
export create_fir_filter, resamplefreq, zerophase, rms_mean

import Base: show, lpad, rpad, getindex, length, lastindex
using DataFrames
using Statistics
import Statistics: mean
using StatsBase
using Reexport
using CSV
using DSP
using FFTW
import FFTW: rfft, irfft
using LinearAlgebra
using RecipesBase
using IntervalSets
using Printf
using ProgressBars
using StatsBase
using WAV

using Interpolations
import Interpolations.interpolate
export interpolate

using FileIO: load, save, loadstreaming, savestreaming
using Unitful

using SampleArrays

include("utils.jl")

include("smoothing/octave.jl")

include("measurements/peak.jl")

include("measurements/directivity.jl")

include("measurements/spinorama.jl")

include("measurements/impexp.jl")

include("measurements/quasianechoic.jl")

include("measurements/expsweep.jl")

include("measurements/measure.jl")

include("vis/timedomain.jl")

include("vis/freqdomain.jl")

include("vis/directivity.jl")

# TOOLS

"""
    normdeg(α)

Normalize α in degrees to (-180, 180].
"""
function normdeg(α)
    α = mod(α, 360)
    α > 180 ? α - 360 : α
end

"""
    deltadeg(α, β)

Smallest delta degrees between α and β angles, sing positive for α to β CCW.
"""
deltadeg(α, β) = normdeg(β - α)

# CANERASE
# function Base.show(io::IO, ::MIME"text/html", buf::SampleBuf{T, N}) where {T <: Number, N}
#     show(io, MIME"text/html", buf)
# end

"""
    fillinsert(X::AbstractArray{T, 2}, n, idx, v=0, dim=1)

Insert into array `X`'s dimension `d` adding `n` to that dimension size; start after index `idx`, fill with `v`.
"""
function fillinsert(X::AbstractArray{T}, n, idx, v=zero(T), dim=1) where T
    idx > size(X, dim) && throw(ArgumentError("idx ($idx) > size(X, $dim) ($(size(X, dim)))!"))
    1 <= dim <= ndims(X) || throw(ArgumentError("wrong dim ($dim) should be in {1, ..., $(ndims(X))}"))
    tdims = collect(size(X))
    tdims[dim] += n

    t = similar(X, tdims...)
    idxs(sel, dim=dim, ndims=ndims(X)) = [i == dim ? sel : Colon() for i in 1:ndims]
    t[idxs(1:idx)...] .= X[idxs(1:idx)...]
    t[idxs(idx+1:idx+n)...] .= v
    t[idxs(idx+n+1:tdims[dim])...] .= X[idxs(idx+1:size(X, dim))...]
#     @show X[idxs(idx+1:end)...]
    t
end

"""
   lpad(X::AbstractArray{T}, n::Integer, v=0, dim=1)

Prepend array `X` in dimension `dim` with `n` values `v`.
"""
Base.lpad(X::AbstractArray{T}, n::Integer, v=zero(T), dim=1) where T = fillinsert(X, n, 0, v, dim)

"""
   rpad(X::AbstractArray{T}, n::Integer, v=0, dim=1)

Append `n` values `v` to array `X` in dimension `dim`.
"""
Base.rpad(X::AbstractArray{T}, n::Integer, v=zero(T), dim=1) where T = fillinsert(X, n, size(X, 1), v, dim)

function create_fir_filter(X::RFFTSpectrumArray, taps)
    @assert nchannels(X) == 1
    x = irfft(data(X), 2nfreqs(X)-1)
    x .= circshift(x, taps÷2)
    xsa = SampleArray(x[1:taps], rate(X)) .* hanning(taps; zerophase=false)
    xsa, rfft(xsa)
end

# TODO: move these to SampleArrays?
Statistics.mean(X::AbstractSpectrumArray{<:SignalElement}) = _mean(X, uweights(Float32, nchannels(X)))
Statistics.mean(X::AbstractSpectrumArray{<:SignalElement}, w::AbstractWeights) = _mean(X, w)

function _mean(X::AbstractSpectrumArray{<:SignalElement}, w::AbstractWeights)
    # complex mean over channels according to
    # Panzer: The use of continuous phase for interpolation, smoothing and forming mean values of complex frequency response curves, 2004
    # println("_mean()")
    # Xu = unwrap(X) # original
    Xu = X # NO UNWRAP
    mags = mean(abs.(Xu), w, dims=2) # original

    # phis = mean(angle.(Xu), w, dims=2) # original
    # phis = mean(angle.(Xu), dims=2) # NO WEIGHTING PHASE
    # phis = angle.(Xu)[:, argmax(w)] # PHASE OF A CLOSER
    phis = angle.(mean(data(X), w, dims=2)) # PHASE MEAN based on vector mean
    # phis = angle.(Xu)[:, 1]

    Y = similar(X, nframes(X), 1)
    Y .= (MagPhase(m, p) for (m, p) in zip(mags, phis))
    Y
end

Statistics.mean(X::AbstractSpectrumArray) = _mean(X, uweights(Float32, nchannels(X)))
Statistics.mean(X::AbstractSpectrumArray, w::AbstractWeights) = _mean(X, w)

_mean(X::AbstractSpectrumArray, w::AbstractWeights) = mean(X, w, dims=2)

rms_mean(X::AbstractSpectrumArray{<:SignalElement}) = _rms_mean(X, uweights(Float32, nchannels(X)))
rms_mean(X::AbstractSpectrumArray{<:SignalElement}, w::AbstractWeights) = _rms_mean(X, w)

function _rms_mean(X::AbstractSpectrumArray{<:SignalElement}, w::AbstractWeights)
    error("FIX phase!")
    # RMSE mean magnitude, unwrapped power
    # println("_rms_mean()")
    Xu = unwrap(X)
    # Xu = X
    ms = abs.(Xu)
    mags = sqrt.(mean(ms .* ms, w, dims=2))
    phis = mean(angle.(Xu), w, dims=2)
    Y = similar(X, nframes(X), 1)
    Y .= (MagPhase(m, p) for (m, p) in zip(mags, phis))
    Y
end

end # module


text:
using LinearAlgebra: AbstractTriangular

# Matrix wrapper types that we know are square and are thus potentially invertible. For
# these we can use simpler definitions for `/` and `\`.
const SquareMatrix{T} = Union{Diagonal{T},AbstractTriangular{T}}

#####
##### `dot`
#####

function frule((_, Δx, Δy), ::typeof(dot), x, y)
    return dot(x, y), sum(Δx .* y) + sum(x .* Δy)
end

function rrule(::typeof(dot), x, y)
    function dot_pullback(ΔΩ)
        return (NO_FIELDS, @thunk(ΔΩ .* y), @thunk(x .* ΔΩ))
    end
    return dot(x, y), dot_pullback
end

#####
##### `cross`
#####

function frule((_, Δa, Δb), ::typeof(cross), a::AbstractVector, b::AbstractVector)
    return cross(a, b), cross(Δa, b) .+ cross(a, Δb)
end

# TODO: support complex vectors
function rrule(::typeof(cross), a::AbstractVector{<:Real}, b::AbstractVector{<:Real})
    Ω = cross(a, b)
    function cross_pullback(ΔΩ)
        return (NO_FIELDS, @thunk(cross(b, ΔΩ)), @thunk(cross(ΔΩ, a)))
    end
    return Ω, cross_pullback
end

#####
##### `inv`
#####

function frule((_, Δx), ::typeof(inv), x::AbstractArray)
    Ω = inv(x)
    return Ω, -Ω * Δx * Ω
end

function rrule(::typeof(inv), x::AbstractArray)
    Ω = inv(x)
    function inv_pullback(ΔΩ)
        return NO_FIELDS, -Ω' * ΔΩ * Ω'
    end
    return Ω, inv_pullback
end

#####
##### `det`
#####

function frule((_, ẋ), ::typeof(det), x::Union{Number, AbstractMatrix})
    Ω = det(x)
    # TODO Performance optimization: probably there is an efficent
    # way to compute this trace without during the full compution within
    return Ω, Ω * tr(inv(x) * ẋ)
end

function rrule(::typeof(det), x::Union{Number, AbstractMatrix})
    Ω = det(x)
    function det_pullback(ΔΩ)
        return NO_FIELDS, Ω * ΔΩ * transpose(inv(x))
    end
    return Ω, det_pullback
end

#####
##### `logdet`
#####

function frule((_, Δx), ::typeof(logdet), x::Union{Number, AbstractMatrix})
    Ω = logdet(x)
    return Ω, tr(inv(x) * Δx)
end

function rrule(::typeof(logdet), x::Union{Number, AbstractMatrix})
    Ω = logdet(x)
    function logdet_pullback(ΔΩ)
        return (NO_FIELDS, ΔΩ * transpose(inv(x)))
    end
    return Ω, logdet_pullback
end

#####
##### `trace`
#####

function frule((_, Δx), ::typeof(tr), x)
    return tr(x), tr(Δx)
end

function rrule(::typeof(tr), x)
    # This should really be a FillArray
    # see https://github.com/JuliaDiff/ChainRules.jl/issues/46
    function tr_pullback(ΔΩ)
        return (NO_FIELDS, @thunk Diagonal(fill(ΔΩ, size(x, 1))))
    end
    return tr(x), tr_pullback
end

#####
##### `*`
#####

function rrule(::typeof(*), A::AbstractMatrix{<:Real}, B::AbstractMatrix{<:Real})
    function times_pullback(Ȳ)
        return (NO_FIELDS, @thunk(Ȳ * B'), @thunk(A' * Ȳ))
    end
    return A * B, times_pullback
end

#####
##### `/`
#####

function rrule(::typeof(/), A::AbstractMatrix{<:Real}, B::T) where T<:SquareMatrix{<:Real}
    Y = A / B
    function slash_pullback(Ȳ)
        S = T.name.wrapper
        ∂A = @thunk Ȳ / B'
        ∂B = @thunk S(-Y' * (Ȳ / B'))
        return (NO_FIELDS, ∂A, ∂B)
    end
    return Y, slash_pullback
end

function rrule(::typeof(/), A::AbstractVecOrMat{<:Real}, B::AbstractVecOrMat{<:Real})
    Aᵀ, dA_pb = rrule(adjoint, A)
    Bᵀ, dB_pb = rrule(adjoint, B)
    Cᵀ, dS_pb = rrule(\, Bᵀ, Aᵀ)
    C, dC_pb = rrule(adjoint, Cᵀ)
    function slash_pullback(Ȳ)
        # Optimization note: dAᵀ, dBᵀ, dC are calculated no matter which partial you want
        _, dC = dC_pb(Ȳ)
        _, dBᵀ, dAᵀ = dS_pb(unthunk(dC))

        ∂A = last(dA_pb(unthunk(dAᵀ)))
        ∂B = last(dA_pb(unthunk(dBᵀ)))

        (NO_FIELDS, ∂A, ∂B)
    end
    return C, slash_pullback
end

#####
##### `\`
#####

function rrule(::typeof(\), A::T, B::AbstractVecOrMat{<:Real}) where T<:SquareMatrix{<:Real}
    Y = A \ B
    function backslash_pullback(Ȳ)
        S = T.name.wrapper
        ∂A = @thunk S(-(A' \ Ȳ) * Y')
        ∂B = @thunk A' \ Ȳ
        return NO_FIELDS, ∂A, ∂B
    end
    return Y, backslash_pullback
end

function rrule(::typeof(\), A::AbstractVecOrMat{<:Real}, B::AbstractVecOrMat{<:Real})
    Y = A \ B
    function backslash_pullback(Ȳ)
        ∂A = @thunk begin
            B̄ = A' \ Ȳ
            Ā = -B̄ * Y'
            _add!(Ā, (B - A * Y) * B̄' / A')
            _add!(Ā, A' \ Y * (Ȳ' - B̄'A))
            Ā
        end
        ∂B = @thunk A' \ Ȳ
        return NO_FIELDS, ∂A, ∂B
    end
    return Y, backslash_pullback

end

#####
##### `norm`
#####

function rrule(::typeof(norm), A::AbstractArray{<:Real}, p::Real=2)
    y = norm(A, p)
    function norm_pullback(ȳ)
        u = y^(1-p)
        ∂A = @thunk ȳ .* u .* abs.(A).^p ./ A
        ∂p = @thunk ȳ * (u * sum(a->abs(a)^p * log(abs(a)), A) - y * log(y)) / p
        (NO_FIELDS, ∂A, ∂p)
    end
    return y, norm_pullback
end

function rrule(::typeof(norm), x::Real, p::Real=2)
    function norm_pullback(ȳ)
        ∂x = @thunk ȳ * sign(x)
        ∂p = @thunk zero(x)  # TODO: should this be Zero()?
        (NO_FIELDS, ∂x, ∂p)
    end
    return norm(x, p), norm_pullback
end


text:
using JuMP, EAGO

                     m = Model()

                     EAGO.register_eago_operators!(m)

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

                     @variable(m, -6.103907844236108 <= q <= 8.378675476959124)

                     add_NL_constraint(m, :(swish(-0.8297607126794757 + -0.5064858067335005*swish(-0.6188655598844357 + -0.38627203797486676*$(x[1]) + 0.4878933200630442*$(x[2])) + -0.8619658571743893*swish(-0.7914291135758744 + 0.8682104207735972*$(x[1]) + 0.3684602934879275*$(x[2])) + 0.8415580445654567*swish(-0.26405078449033637 + -0.6452849815457378*$(x[1]) + 0.9586530591287103*$(x[2]))) + swish(-0.0809505831099564 + 0.6185835236357913*swish(-0.6188655598844357 + -0.38627203797486676*$(x[1]) + 0.4878933200630442*$(x[2])) + -0.5288114683363174*swish(-0.7914291135758744 + 0.8682104207735972*$(x[1]) + 0.3684602934879275*$(x[2])) + -0.42070009030061817*swish(-0.26405078449033637 + -0.6452849815457378*$(x[1]) + 0.9586530591287103*$(x[2]))) + swish(0.16011867292674786 + -0.14898607305663658*swish(-0.6188655598844357 + -0.38627203797486676*$(x[1]) + 0.4878933200630442*$(x[2])) + -0.8220978033005912*swish(-0.7914291135758744 + 0.8682104207735972*$(x[1]) + 0.3684602934879275*$(x[2])) + -0.8518875556726564*swish(-0.26405078449033637 + -0.6452849815457378*$(x[1]) + 0.9586530591287103*$(x[2]))) - $q <= 0.0))

                     @objective(m, Min, q)

                     return m

max_stars_repo_name: PSORLab/RSActivationFunctions

max_issues_repo_name: PSORLab/RSActivationFunctions

max_forks_repo_name: PSORLab/RSActivationFunctions