text:
using Match

function is_inside(p::AbstractParticle, s::Shape)::Bool
    return is_inside(p.x, s)
end

"""
    Box(x1_min::Float64, x2_min::Float64, x3_min::Float64,
        x1_max::Float64, x2_max::Float64, x3_max::Float64)::Shape

Defines a box specified by two corners.
"""
struct Box <: Shape
    x1_min::Float64
    x2_min::Float64
    x3_min::Float64
    x1_max::Float64
    x2_max::Float64
    x3_max::Float64
end

function is_inside(x::RealVector, b::Box)::Bool
    return (
        b.x1_min <= x[1] <= b.x1_max &&
        b.x2_min <= x[2] <= b.x2_max &&
        b.x3_min <= x[3] <= b.x3_max
    )
end

function boundarybox(b::Box)::Box
    return b
end

"""
    Rectangle(x1_min, x2_min, x1_max, x2_max) <: Shape

Define a rectangle by specifying bottom left and top right corner.
"""
function Rectangle(x1_min::Float64, x2_min::Float64, x1_max::Float64, x2_max::Float64)::Box
    return Box(x1_min, x2_min, 0., x1_max, x2_max, 0.)
end

"""
    Circle(x1::Float64, x2::Float64, r::Float64) <: Shape

Define a circle by specifying the center `(x1, x2)` and the radius `r`.
"""
struct Circle <: Shape
    x1::Float64
    x2::Float64
    r::Float64
    Circle(x1::Float64, x2::Float64, r::Float64) = begin
        if r <= 0.0
            @warn("Degenerate circle definition (r <= 0)!")
        end
        return new(x1,x2,r)
    end
end

function is_inside(x::RealVector, c::Circle)::Bool
    return (x[1] - c.x1)^2 + (x[2] - c.x2)^2 <= c.r^2
end

function boundarybox(c::Circle)::Box
    return Rectangle(c.x1-c.r, c.x2-c.r, c.x1+c.r, c.x2+c.r)
end

"""
    Ellipse(x1::Float64, x2::Float64, r1::Float64, r2::Float64) <: Shape

Define an ellipse by specifying the center `(x1, x2)` and semi-major/minor
axes `r1`, `r2`.
"""
struct Ellipse <: Shape
    x1::Float64
    x2::Float64
    r1::Float64
    r2::Float64
    Ellipse(x1::Float64, x2::Float64, r1::Float64, r2::Float64) = begin
        if r1 <= 0.
            @warn("Degenerate ellipse definition (r1 <= 0)!")
        end
        if r2 <= 0.
            @warn("Degenerate ellipse definition (r2 <= 0)!")
        end
        return new(x1, x2, r1, r2)
    end
end

function is_inside(x::RealVector, e::Ellipse)::Bool
    return ((x[1] - e.x1)/e.r1)^2 + ((x[2] - e.x2)/e.r2)^2 <= 1
end

function boundarybox(e::Ellipse)::Box
    return Rectangle(e.x1-r1, e.x2-r2, e.x1+r1, e.x2+r2)
end

"""
    BooleanUnion(s1::Shape, s2::Shape) <: Shape

Define a shape as union of two shapes. Equivalent to `s1 + s2`.
"""

struct BooleanUnion <: Shape
    s1::Shape
    s2::Shape
end

function is_inside(x::RealVector, u::BooleanUnion)::Bool
    return is_inside(x, u.s1)||is_inside(x, u.s2)
end

function boundarybox(u::BooleanUnion)::Box
    r1 = boundarybox(u.s1)
    r2 = boundarybox(u.s2)
    x1_min = min(r1.x1_min, r2.x1_min)
    x2_min = min(r1.x2_min, r2.x2_min)
    x3_min = min(r1.x3_min, r2.x3_min)
    x1_max = max(r1.x1_max, r2.x1_max)
    x2_max = max(r1.x2_max, r2.x2_max)
    x3_max = max(r1.x3_max, r2.x3_max)
    return Box(x1_min, x2_min, x3_min, x1_max, x2_max, x3_max)
end

"""
    BooleanIntersection(s1::Shape, s2::Shape) <: Shape

Define a shape as intersection of two shapes. Equivalent to `s1 * s2`.
"""
struct BooleanIntersection <: Shape
    s1::Shape
    s2::Shape
end

function is_inside(x::RealVector, i::BooleanIntersection)::Bool
    return is_inside(x, i.s1) && is_inside(x, i.s2)
end

function boundarybox(i::BooleanIntersection)::Box
    r1 = boundarybox(i.s1)
    r2 = boundarybox(i.s2)
    x1_min = max(r1.x1_min, r2.x1_min)
    x2_min = max(r1.x2_min, r2.x2_min)
    x3_min = max(r1.x3_min, r2.x3_min)
    x1_max = min(r1.x1_max, r2.x1_max)
    x2_max = min(r1.x2_max, r2.x2_max)
    x3_max = min(r1.x3_max, r2.x3_max)
    return Box(x1_min, x2_min, x3_min, x1_max, x2_max, x3_max)
end

"""
    BooleanDifference(s1::Shape, s2::Shape) <: Shape

Define a shape as difference of two shapes. Equivalent to `s1 - s2`.
"""
struct BooleanDifference <: Shape
    s1::Shape
    s2::Shape
end

function is_inside(x::RealVector, d::BooleanDifference)::Bool
    return is_inside(x, d.s1) && !is_inside(x, d.s2)
end

function boundarybox(d::BooleanDifference)::Box
    return boundarybox(d.s1)
end

"""
    Specification(s::Shape, f::Function) <: Shape

Define a shape of all `x` in `s`, such that `f(x) == true`.
"""
struct Specification <: Shape
    s::Shape
    f::Function
end

function is_inside(x::RealVector, sp::Specification)::Bool
    return sp.f(x) && is_inside(x, sp.s)
end

function boundarybox(sp::Specification)::Box
    return boundarybox(sp.s)
end

"""
    BoundaryLayer(s::Shape, grid::Grid, width::Float64) <: Shape

Creates a layer of certain `width` around shape `s`. More specifically, a point is inside
boundary layer if it is not in `s` and at the same time has distance less than `width` to
at least one point on `grid` in `s`.
"""
struct BoundaryLayer <: Shape
    s::Shape
    dim::Int64
    dxs::Vector{RealVector}
    width::Float64
    BoundaryLayer(s::Shape, grid::Grid, width::Float64) = begin
        if width <= 0.
            @warn("Degenerate boundary layer definition (width <= 0)!")
        end
        dxs = covering(grid, Ball(0.,0.,0.,width))
        return new(s, dimension(grid), dxs, width)
    end
end

function is_inside(x::RealVector, bl::BoundaryLayer)::Bool
    if is_inside(x, bl.s)
        return false
    end
    for dx in bl.dxs
        if is_inside(x + dx, bl.s)
            return true
        end
    end
    return false
end

function boundarybox(bl::BoundaryLayer)::Box
    r = boundarybox(bl.s)
    x1_min = r.x1_min - bl.width
    x2_min = r.x2_min - bl.width
    x3_min = r.x3_min - bl.width
    x1_max = r.x1_max + bl.width
    x2_max = r.x2_max + bl.width
    x3_max = r.x3_max + bl.width
    if bl.dim == 2
        return Rectangle(x1_min, x2_min, x1_max, x2_max)
    else
        return Box(x1_min, x2_min, x3_min, x1_max, x2_max, x3_max)
    end
end

#define +,-,* on shapes as equivalent to BooleanUnion, BooleanDifference and BooleanIntersection respectively
Base.:+(s1::Shape, s2::Shape) = BooleanUnion(s1, s2)
Base.:-(s1::Shape, s2::Shape) = BooleanDifference(s1, s2)
Base.:*(s1::Shape, s2::Shape) = BooleanIntersection(s1, s2)

"""
    Ball(x1::Float64, x2::Float64, x3::Float64, r::Float64) <: Shape

Define a ball by specifying the center `(x1, x2, x3)` and the radius `r`.
"""
struct Ball <: Shape
    x1::Float64
    x2::Float64
    x3::Float64
    r::Float64
    Ball(x1::Float64, x2::Float64, x3::Float64, r::Float64) = begin
        if r <= 0.0
            @warn("Degenerate ball definition (r <= 0)!")
        end
        return new(x1,x2,x3,r)
    end
end

function is_inside(x::RealVector, b::Ball)::Bool
    return (x[1] - b.x1)^2 + (x[2] - b.x2)^2  + (x[3] - b.x3)^2 <= b.r^2
end

function boundarybox(b::Ball)::Box
    return Box(b.x1-b.r, b.x2-b.r, b.x3-b.r, b.x1+b.r, b.x2+b.r, b.x3+b.r)
end

"""
    Transform(s::Shape; A::RealMatrix = MAT1, b::RealVector = VEC0)

Define shape as a linear transform ``x \\to Ax + b`` applied to shape `s`.
"""
struct Transform <: Shape
    s::Shape
    A::RealMatrix
    A_inv::RealMatrix
    b::RealVector
    Transform(s::Shape; A::RealMatrix = MAT1, b::RealVector = VEC0) = new(s, A, inv(A), b)
end

function is_inside(x::RealVector, tr::Transform)::Bool
    return is_inside(tr.A_inv*(x - tr.b), tr.s)
end

function boundarybox(tr::Transform)::Box
    box = boundarybox(tr.s)
    x1 = (box.x1_min, box.x1_max)
    x2 = (box.x2_min, box.x2_max)
    x3 = (box.x3_min, box.x3_max)
    x_min = [+Inf, +Inf, +Inf]
    x_max = [-Inf, -Inf, -Inf]
    for i1 in 0:1, i2 in 0:1, i3 in 0:1
        x = tr.A*RealVector(x1[i1], x2[i2], x3[i3]) + tr.b
        x_min .= min.(x_min, x)
        x_max .= max.(x_max, x)
    end
    return Box(x_min[1], x_min[2], x_min[3], x_max[1], x_max[2], x_max[3])
end


text:
module TextAnalysis
    using SparseArrays
    using Printf
    using LinearAlgebra
    using StatsBase: countmap,addcounts!
    using Languages
    using WordTokenizers
    using Snowball

    using Tables
    using DataStructures
    using Statistics
    using Serialization
    using ProgressMeter

    import Base: depwarn, merge!
    import Serialization: serialize, deserialize

    export AbstractDocument, Document
    export FileDocument, StringDocument, TokenDocument, NGramDocument
    export GenericDocument
    export Corpus, DirectoryCorpus
    export stemmer_types, Stemmer
    export DocumentTermMatrix
    export text, tokens, ngrams
    export text!, tokens!, ngrams!
    export documents
    export language, title, author, timestamp
    export languages, titles, authors, timestamps
    export language!, title!, author!, timestamp!
    export languages!, titles!, authors!, timestamps!
    export ngram_complexity
    export lexicon, update_lexicon!, lexical_frequency, lexicon_size
    export inverse_index, update_inverse_index!, index_size
    export remove_corrupt_utf8
    export remove_corrupt_utf8!
    export remove_case
    export remove_case!
    export remove_words, remove_stop_words
    export remove_words!, remove_stop_words!
    export stem, tag_pos
    export stem!, tag_pos!
    export remove_html_tags, remove_html_tags!
    export prepare!
    export frequent_terms, sparse_terms
    export remove_frequent_terms!, remove_sparse_terms!
    export dtv, each_dtv, dtm, tdm
    export TextHashFunction, index_hash, cardinality, hash_function, hash_function!
    export hash_dtv, each_hash_dtv, hash_dtm, hash_tdm
    export CooMatrix, coom
    export standardize!
    export tf, tf_idf, bm_25, lsa, lda, summarize, cos_similarity
    export tf!, tf_idf!, bm_25!, lda!
    export remove_patterns!, remove_patterns
    export prune!

    export strip_patterns, strip_corrupt_utf8, strip_case, stem_words, tag_part_of_speech, strip_whitespace, strip_punctuation
    export strip_numbers, strip_non_letters, strip_indefinite_articles, strip_definite_articles, strip_articles
    export strip_prepositions, strip_pronouns, strip_stopwords, strip_sparse_terms, strip_frequent_terms, strip_html_tags

    export NaiveBayesClassifier
    export tag_scheme!
    export rouge_l_summary, rouge_l_sentence, rouge_n
    export PerceptronTagger, fit!, predict

    export Vocabulary, lookup, update
    export everygram, padding_ngram
    export maskedscore, logscore, entropy, perplexity
    export MLE, Lidstone, Laplace, WittenBellInterpolated, KneserNeyInterpolated, score

    export tokenize #imported from WordTokenizers

    include("tokenizer.jl")
    include("ngramizer.jl")
    include("document.jl")
    include("hash.jl")
    include("corpus.jl")
    include("metadata.jl")
    include("preprocessing.jl")

    include("stemmer.jl")
    include("dtm.jl")
    include("tf_idf.jl")
    include("lsa.jl")
    include("lda.jl")
    include("summarizer.jl")
    include("show.jl")
    include("bayes.jl")
    include("deprecations.jl")
    include("tagging_schemes.jl")
    include("utils.jl")

    include("evaluation_metrics.jl")
    include("coom.jl")

    # Lang_model
    include("LM/vocab.jl")
    include("LM/langmodel.jl")
    include("LM/api.jl")
    include("LM/counter.jl")
    include("LM/preprocessing.jl")

    function __init__()

    end
end

ext: jl


text:
import Base.zero

export
    AVIO_SEEKABLE_NORMAL,
    AVSEEK_SIZE,
    AVSEEK_FORCE,
    AVIO_FLAG_READ,
    AVIO_FLAG_WRITE,
    AVIO_FLAG_READ_WRITE,
    AVIO_FLAG_NONBLOCK,
    AVIOInterruptCB,
    AVIOContext,
    AVPROBE_SCORE_EXTENSION,
    AVPROBE_SCORE_MAX,
    AVPROBE_PADDING_SIZE,
    AVFMT_NOFILE,
    AVFMT_NEEDNUMBER,
    AVFMT_SHOW_IDS,
    AVFMT_RAWPICTURE,
    AVFMT_GLOBALHEADER,
    AVFMT_NOTIMESTAMPS,
    AVFMT_GENERIC_INDEX,
    AVFMT_TS_DISCONT,
    AVFMT_VARIABLE_FPS,
    AVFMT_NODIMENSIONS,
    AVFMT_NOSTREAMS,
    AVFMT_NOBINSEARCH,
    AVFMT_NOGENSEARCH,
    AVFMT_NO_BYTE_SEEK,
    AVFMT_ALLOW_FLUSH,
    AVFMT_TS_NONSTRICT,
    AVFMT_TS_NEGATIVE,
    AVINDEX_KEYFRAME,
    AV_DISPOSITION_DEFAULT,
    AV_DISPOSITION_DUB,
    AV_DISPOSITION_ORIGINAL,
    AV_DISPOSITION_COMMENT,
    AV_DISPOSITION_LYRICS,
    AV_DISPOSITION_KARAOKE,
    AV_DISPOSITION_FORCED,
    AV_DISPOSITION_HEARING_IMPAIRED,
    AV_DISPOSITION_VISUAL_IMPAIRED,
    AV_DISPOSITION_CLEAN_EFFECTS,
    AV_DISPOSITION_ATTACHED_PIC,
    MAX_STD_TIMEBASES,
    MAX_PROBE_PACKETS,
    MAX_REORDER_DELAY,
    AV_PROGRAM_RUNNING,
    AVFMTCTX_NOHEADER,
    AVFMT_FLAG_GENPTS,
    AVFMT_FLAG_IGNIDX,
    AVFMT_FLAG_NONBLOCK,
    AVFMT_FLAG_IGNDTS,
    AVFMT_FLAG_NOFILLIN,
    AVFMT_FLAG_NOPARSE,
    AVFMT_FLAG_NOBUFFER,
    AVFMT_FLAG_CUSTOM_IO,
    AVFMT_FLAG_DISCARD_CORRUPT,
    AVFMT_FLAG_FLUSH_PACKETS,
    RAW_PACKET_BUFFER_SIZE,
    AVSEEK_FLAG_BACKWARD,
    AVSEEK_FLAG_BYTE,
    AVSEEK_FLAG_ANY,
    AVSEEK_FLAG_FRAME,
    AVCodecTag,
    AVInputFormat,
    AVOutputFormat,
    AVFrac,
    AVStreamParseType,
    AVSTREAM_PARSE_NONE,
    AVSTREAM_PARSE_FULL,
    AVSTREAM_PARSE_HEADERS,
    AVSTREAM_PARSE_TIMESTAMPS,
    AVSTREAM_PARSE_FULL_ONCE,
    AVPacketList,
    AVProbeData,
    Array_17_Int64,
    AVIndexEntry,
    AVStream,
    Array_1024_Uint8,
    AVProgram,
    AVChapter,
    AVFormatInternal,
    AVFormatContext

const AVIO_SEEKABLE_NORMAL = 0x0001
const AVSEEK_SIZE = 0x00010000
const AVSEEK_FORCE = 0x00020000
const AVIO_FLAG_READ = 1
const AVIO_FLAG_WRITE = 2
const AVIO_FLAG_READ_WRITE = AVIO_FLAG_READ | AVIO_FLAG_WRITE
const AVIO_FLAG_NONBLOCK = 8

immutable AVIOInterruptCB
    callback::Ptr{Void}
    opaque::Ptr{Void}
end

immutable AVIOContext
    av_class::Ptr{AVClass}
    buffer::Ptr{Cuchar}
    buffer_size::Cint
    buf_ptr::Ptr{Cuchar}
    buf_end::Ptr{Cuchar}
    opaque::Ptr{Void}
    read_packet::Ptr{Void}
    write_packet::Ptr{Void}
    seek::Ptr{Void}
    pos::Int64
    must_flush::Cint
    eof_reached::Cint
    write_flag::Cint
    max_packet_size::Cint
    checksum::Culong
    checksum_ptr::Ptr{Cuchar}
    update_checksum::Ptr{Void}
    error::Cint
    read_pause::Ptr{Void}
    read_seek::Ptr{Void}
    seekable::Cint
end

const AVPROBE_SCORE_EXTENSION = 50
const AVPROBE_SCORE_MAX = 100
const AVPROBE_PADDING_SIZE = 32
const AVFMT_NOFILE = 0x0001
const AVFMT_NEEDNUMBER = 0x0002
const AVFMT_SHOW_IDS = 0x0008
const AVFMT_RAWPICTURE = 0x0020
const AVFMT_GLOBALHEADER = 0x0040
const AVFMT_NOTIMESTAMPS = 0x0080
const AVFMT_GENERIC_INDEX = 0x0100
const AVFMT_TS_DISCONT = 0x0200
const AVFMT_VARIABLE_FPS = 0x0400
const AVFMT_NODIMENSIONS = 0x0800
const AVFMT_NOSTREAMS = 0x1000
const AVFMT_NOBINSEARCH = 0x2000
const AVFMT_NOGENSEARCH = 0x4000
const AVFMT_NO_BYTE_SEEK = 0x8000
const AVFMT_ALLOW_FLUSH = 0x00010000
const AVFMT_TS_NONSTRICT = 0x00020000
const AVFMT_TS_NEGATIVE = 0x00040000
const AVINDEX_KEYFRAME = 0x0001
const AV_DISPOSITION_DEFAULT = 0x0001
const AV_DISPOSITION_DUB = 0x0002
const AV_DISPOSITION_ORIGINAL = 0x0004
const AV_DISPOSITION_COMMENT = 0x0008
const AV_DISPOSITION_LYRICS = 0x0010
const AV_DISPOSITION_KARAOKE = 0x0020
const AV_DISPOSITION_FORCED = 0x0040
const AV_DISPOSITION_HEARING_IMPAIRED = 0x0080
const AV_DISPOSITION_VISUAL_IMPAIRED = 0x0100
const AV_DISPOSITION_CLEAN_EFFECTS = 0x0200
const AV_DISPOSITION_ATTACHED_PIC = 0x0400
const MAX_STD_TIMEBASES = 60 * 12 + 5
const MAX_PROBE_PACKETS = 2500
const MAX_REORDER_DELAY = 16
const AV_PROGRAM_RUNNING = 1
const AVFMTCTX_NOHEADER = 0x0001
const AVFMT_FLAG_GENPTS = 0x0001
const AVFMT_FLAG_IGNIDX = 0x0002
const AVFMT_FLAG_NONBLOCK = 0x0004
const AVFMT_FLAG_IGNDTS = 0x0008
const AVFMT_FLAG_NOFILLIN = 0x0010
const AVFMT_FLAG_NOPARSE = 0x0020
const AVFMT_FLAG_NOBUFFER = 0x0040
const AVFMT_FLAG_CUSTOM_IO = 0x0080
const AVFMT_FLAG_DISCARD_CORRUPT = 0x0100
const AVFMT_FLAG_FLUSH_PACKETS = 0x0200
const FF_FDEBUG_TS = 0x0001
const RAW_PACKET_BUFFER_SIZE = 2500000
const AVSEEK_FLAG_BACKWARD = 1
const AVSEEK_FLAG_BYTE = 2
const AVSEEK_FLAG_ANY = 4
const AVSEEK_FLAG_FRAME = 8

typealias AVCodecTag Void

immutable AVInputFormat
    name::Ptr{Uint8}
    long_name::Ptr{Uint8}
    flags::Cint
    extensions::Ptr{Uint8}
    codec_tag::Ptr{Ptr{AVCodecTag}}
    priv_class::Ptr{AVClass}
    next::Ptr{AVInputFormat}
    raw_codec_id::Cint
    priv_data_size::Cint
    read_probe::Ptr{Void}
    read_header::Ptr{Void}
    read_packet::Ptr{Void}
    read_close::Ptr{Void}
    read_seek::Ptr{Void}
    read_timestamp::Ptr{Void}
    read_play::Ptr{Void}
    read_pause::Ptr{Void}
    read_seek2::Ptr{Void}
end

immutable AVOutputFormat
    name::Ptr{Uint8}
    long_name::Ptr{Uint8}
    mime_type::Ptr{Uint8}
    extensions::Ptr{Uint8}
    audio_codec::AVCodecID
    video_codec::AVCodecID
    subtitle_codec::AVCodecID
    flags::Cint
    codec_tag::Ptr{Ptr{AVCodecTag}}
    priv_class::Ptr{AVClass}
    next::Ptr{AVOutputFormat}
    priv_data_size::Cint
    write_header::Ptr{Void}
    write_packet::Ptr{Void}
    write_trailer::Ptr{Void}
    interleave_packet::Ptr{Void}
    query_codec::Ptr{Void}
end

immutable AVFrac
    val::Int64
    num::Int64
    den::Int64
end

# begin enum AVStreamParseType
typealias AVStreamParseType Uint32
const AVSTREAM_PARSE_NONE = @compat UInt32(0)
const AVSTREAM_PARSE_FULL = @compat UInt32(1)
const AVSTREAM_PARSE_HEADERS = @compat UInt32(2)
const AVSTREAM_PARSE_TIMESTAMPS = @compat UInt32(3)
const AVSTREAM_PARSE_FULL_ONCE = @compat UInt32(4)
# end enum AVStreamParseType

immutable AVPacketList
    pkt::AVPacket
    next::Ptr{AVPacketList}
end

immutable AVProbeData
    filename::Ptr{Uint8}
    buf::Ptr{Cuchar}
    buf_size::Cint
end

immutable Array_17_Int64
    d1::Int64
    d2::Int64
    d3::Int64
    d4::Int64
    d5::Int64
    d6::Int64
    d7::Int64
    d8::Int64
    d9::Int64
    d10::Int64
    d11::Int64
    d12::Int64
    d13::Int64
    d14::Int64
    d15::Int64
    d16::Int64
    d17::Int64
end

zero(::Type{Array_17_Int64}) = Array_17_Int64(fill(zero(Int64),17)...)

immutable AVIndexEntry
    pos::Int64
    timestamp::Int64
    flags::Cint
    size::Cint
    min_distance::Cint
end

immutable AVStream
    index::Cint
    id::Cint
    codec::Ptr{AVCodecContext}
    priv_data::Ptr{Void}
    pts::AVFrac
    time_base::AVRational
    start_time::Int64
    duration::Int64
    nb_frames::Int64
    disposition::Cint
    discard::AVDiscard
    sample_aspect_ratio::AVRational
    metadata::Ptr{AVDictionary}
    avg_frame_rate::AVRational
    attached_pic::AVPacket
    info::Ptr{Void}
    pts_wrap_bits::Cint
    do_not_use::Int64
    first_dts::Int64
    cur_dts::Int64
    last_IP_pts::Int64
    last_IP_duration::Cint
    probe_packets::Cint
    codec_info_nb_frames::Cint
    need_parsing::AVStreamParseType
    parser::Ptr{AVCodecParserContext}
    last_in_packet_buffer::Ptr{AVPacketList}
    probe_data::AVProbeData
    pts_buffer::Array_17_Int64
    index_entries::Ptr{AVIndexEntry}
    nb_index_entries::Cint
    index_entries_allocated_size::Uint32
end

immutable Array_1024_Uint8
    d1::Uint8
    d2::Uint8
    d3::Uint8
    d4::Uint8
    d5::Uint8
    d6::Uint8
    d7::Uint8
    d8::Uint8
    d9::Uint8
    d10::Uint8
    d11::Uint8
    d12::Uint8
    d13::Uint8
    d14::Uint8
    d15::Uint8
    d16::Uint8
    d17::Uint8
    d18::Uint8
    d19::Uint8
    d20::Uint8
    d21::Uint8
    d22::Uint8
    d23::Uint8
    d24::Uint8
    d25::Uint8
    d26::Uint8
    d27::Uint8
    d28::Uint8
    d29::Uint8
    d30::Uint8
    d31::Uint8
    d32::Uint8
    d33::Uint8
    d34::Uint8
    d35::Uint8
    d36::Uint8
    d37::Uint8
    d38::Uint8
    d39::Uint8
    d40::Uint8
    d41::Uint8
    d42::Uint8
    d43::Uint8
    d44::Uint8
    d45::Uint8
    d46::Uint8
    d47::Uint8
    d48::Uint8
    d49::Uint8
    d50::Uint8
    d51::Uint8
    d52::Uint8
    d53::Uint8
    d54::Uint8
    d55::Uint8
    d56::Uint8
    d57::Uint8
    d58::Uint8
    d59::Uint8
    d60::Uint8
    d61::Uint8
    d62::Uint8
    d63::Uint8
    d64::Uint8
    d65::Uint8
    d66::Uint8
    d67::Uint8
    d68::Uint8
    d69::Uint8
    d70::Uint8
    d71::Uint8
    d72::Uint8
    d73::Uint8
    d74::Uint8
    d75::Uint8
    d76::Uint8
    d77::Uint8
    d78::Uint8
    d79::Uint8
    d80::Uint8
    d81::Uint8
    d82::Uint8
    d83::Uint8
    d84::Uint8
    d85::Uint8
    d86::Uint8
    d87::Uint8
    d88::Uint8
    d89::Uint8
    d90::Uint8
    d91::Uint8
    d92::Uint8
    d93::Uint8
    d94::Uint8
    d95::Uint8
    d96::Uint8
    d97::Uint8
    d98::Uint8
    d99::Uint8
    d100::Uint8
    d101::Uint8
    d102::Uint8
    d103::Uint8
    d104::Uint8
    d105::Uint8
    d106::Uint8
    d107::Uint8
    d108::Uint8
    d109::Uint8
    d110::Uint8
    d111::Uint8
    d112::Uint8
    d113::Uint8
    d114::Uint8
    d115::Uint8
    d116::Uint8
    d117::Uint8
    d118::Uint8
    d119::Uint8
    d120::Uint8
    d121::Uint8
    d122::Uint8
    d123::Uint8
    d124::Uint8
    d125::Uint8
    d126::Uint8
    d127::Uint8
    d128::Uint8
    d129::Uint8
    d130::Uint8
    d131::Uint8
    d132::Uint8
    d133::Uint8
    d134::Uint8
    d135::Uint8
    d136::Uint8
    d137::Uint8
    d138::Uint8
    d139::Uint8
    d140::Uint8
    d141::Uint8
    d142::Uint8
    d143::Uint8
    d144::Uint8
    d145::Uint8
    d146::Uint8
    d147::Uint8
    d148::Uint8
    d149::Uint8
    d150::Uint8
    d151::Uint8
    d152::Uint8
    d153::Uint8
    d154::Uint8
    d155::Uint8
    d156::Uint8
    d157::Uint8
    d158::Uint8
    d159::Uint8
    d160::Uint8
    d161::Uint8
    d162::Uint8
    d163::Uint8
    d164::Uint8
    d165::Uint8
    d166::Uint8
    d167::Uint8
    d168::Uint8
    d169::Uint8
    d170::Uint8
    d171::Uint8
    d172::Uint8
    d173::Uint8
    d174::Uint8
    d175::Uint8
    d176::Uint8
    d177::Uint8
    d178::Uint8
    d179::Uint8
    d180::Uint8
    d181::Uint8
    d182::Uint8
    d183::Uint8
    d184::Uint8
    d185::Uint8
    d186::Uint8
    d187::Uint8
    d188::Uint8
    d189::Uint8
    d190::Uint8
    d191::Uint8
    d192::Uint8
    d193::Uint8
    d194::Uint8
    d195::Uint8
    d196::Uint8
    d197::Uint8
    d198::Uint8
    d199::Uint8
    d200::Uint8
    d201::Uint8
    d202::Uint8
    d203::Uint8
    d204::Uint8
    d205::Uint8
    d206::Uint8
    d207::Uint8
    d208::Uint8
    d209::Uint8
    d210::Uint8
    d211::Uint8
    d212::Uint8
    d213::Uint8
    d214::Uint8
    d215::Uint8
    d216::Uint8
    d217::Uint8
    d218::Uint8
    d219::Uint8
    d220::Uint8
    d221::Uint8
    d222::Uint8
    d223::Uint8
    d224::Uint8
    d225::Uint8
    d226::Uint8
    d227::Uint8
    d228::Uint8
    d229::Uint8
    d230::Uint8
    d231::Uint8
    d232::Uint8
    d233::Uint8
    d234::Uint8
    d235::Uint8
    d236::Uint8
    d237::Uint8
    d238::Uint8
    d239::Uint8
    d240::Uint8
    d241::Uint8
    d242::Uint8
    d243::Uint8
    d244::Uint8
    d245::Uint8
    d246::Uint8
    d247::Uint8
    d248::Uint8
    d249::Uint8
    d250::Uint8
    d251::Uint8
    d252::Uint8
    d253::Uint8
    d254::Uint8
    d255::Uint8
    d256::Uint8
    d257::Uint8
    d258::Uint8
    d259::Uint8
    d260::Uint8
    d261::Uint8
    d262::Uint8
    d263::Uint8
    d264::Uint8
    d265::Uint8
    d266::Uint8
    d267::Uint8
    d268::Uint8
    d269::Uint8
    d270::Uint8
    d271::Uint8
    d272::Uint8
    d273::Uint8
    d274::Uint8
    d275::Uint8
    d276::Uint8
    d277::Uint8
    d278::Uint8
    d279::Uint8
    d280::Uint8
    d281::Uint8
    d282::Uint8
    d283::Uint8
    d284::Uint8
    d285::Uint8
    d286::Uint8
    d287::Uint8
    d288::Uint8
    d289::Uint8
    d290::Uint8
    d291::Uint8
    d292::Uint8
    d293::Uint8
    d294::Uint8
    d295::Uint8
    d296::Uint8
    d297::Uint8
    d298::Uint8
    d299::Uint8
    d300::Uint8
    d301::Uint8
    d302::Uint8
    d303::Uint8
    d304::Uint8
    d305::Uint8
    d306::Uint8
    d307::Uint8
    d308::Uint8
    d309::Uint8
    d310::Uint8
    d311::Uint8
    d312::Uint8
    d313::Uint8
    d314::Uint8
    d315::Uint8
    d316::Uint8
    d317::Uint8
    d318::Uint8
    d319::Uint8
    d320::Uint8
    d321::Uint8
    d322::Uint8
    d323::Uint8
    d324::Uint8
    d325::Uint8
    d326::Uint8
    d327::Uint8
    d328::Uint8
    d329::Uint8
    d330::Uint8
    d331::Uint8
    d332::Uint8
    d333::Uint8
    d334::Uint8
    d335::Uint8
    d336::Uint8
    d337::Uint8
    d338::Uint8
    d339::Uint8
    d340::Uint8
    d341::Uint8
    d342::Uint8
    d343::Uint8
    d344::Uint8
    d345::Uint8
    d346::Uint8
    d347::Uint8
    d348::Uint8
    d349::Uint8
    d350::Uint8
    d351::Uint8
    d352::Uint8
    d353::Uint8
    d354::Uint8
    d355::Uint8
    d356::Uint8
    d357::Uint8
    d358::Uint8
    d359::Uint8
    d360::Uint8
    d361::Uint8
    d362::Uint8
    d363::Uint8
    d364::Uint8
    d365::Uint8
    d366::Uint8
    d367::Uint8
    d368::Uint8
    d369::Uint8
    d370::Uint8
    d371::Uint8
    d372::Uint8
    d373::Uint8
    d374::Uint8
    d375::Uint8
    d376::Uint8
    d377::Uint8
    d378::Uint8
    d379::Uint8
    d380::Uint8
    d381::Uint8
    d382::Uint8
    d383::Uint8
    d384::Uint8
    d385::Uint8
    d386::Uint8
    d387::Uint8
    d388::Uint8
    d389::Uint8
    d390::Uint8
    d391::Uint8
    d392::Uint8
    d393::Uint8
    d394::Uint8
    d395::Uint8
    d396::Uint8
    d397::Uint8
    d398::Uint8
    d399::Uint8
    d400::Uint8
    d401::Uint8
    d402::Uint8
    d403::Uint8
    d404::Uint8
    d405::Uint8
    d406::Uint8
    d407::Uint8
    d408::Uint8
    d409::Uint8
    d410::Uint8
    d411::Uint8
    d412::Uint8
    d413::Uint8
    d414::Uint8
    d415::Uint8
    d416::Uint8
    d417::Uint8
    d418::Uint8
    d419::Uint8
    d420::Uint8
    d421::Uint8
    d422::Uint8
    d423::Uint8
    d424::Uint8
    d425::Uint8
    d426::Uint8
    d427::Uint8
    d428::Uint8
    d429::Uint8
    d430::Uint8
    d431::Uint8
    d432::Uint8
    d433::Uint8
    d434::Uint8
    d435::Uint8
    d436::Uint8
    d437::Uint8
    d438::Uint8
    d439::Uint8
    d440::Uint8
    d441::Uint8
    d442::Uint8
    d443::Uint8
    d444::Uint8
    d445::Uint8
    d446::Uint8
    d447::Uint8
    d448::Uint8
    d449::Uint8
    d450::Uint8
    d451::Uint8
    d452::Uint8
    d453::Uint8
    d454::Uint8
    d455::Uint8
    d456::Uint8
    d457::Uint8
    d458::Uint8
    d459::Uint8
    d460::Uint8
    d461::Uint8
    d462::Uint8
    d463::Uint8
    d464::Uint8
    d465::Uint8
    d466::Uint8
    d467::Uint8
    d468::Uint8
    d469::Uint8
    d470::Uint8
    d471::Uint8
    d472::Uint8
    d473::Uint8
    d474::Uint8
    d475::Uint8
    d476::Uint8
    d477::Uint8
    d478::Uint8
    d479::Uint8
    d480::Uint8
    d481::Uint8
    d482::Uint8
    d483::Uint8
    d484::Uint8
    d485::Uint8
    d486::Uint8
    d487::Uint8
    d488::Uint8
    d489::Uint8
    d490::Uint8
    d491::Uint8
    d492::Uint8
    d493::Uint8
    d494::Uint8
    d495::Uint8
    d496::Uint8
    d497::Uint8
    d498::Uint8
    d499::Uint8
    d500::Uint8
    d501::Uint8
    d502::Uint8
    d503::Uint8
    d504::Uint8
    d505::Uint8
    d506::Uint8
    d507::Uint8
    d508::Uint8
    d509::Uint8
    d510::Uint8
    d511::Uint8
    d512::Uint8
    d513::Uint8
    d514::Uint8
    d515::Uint8
    d516::Uint8
    d517::Uint8
    d518::Uint8
    d519::Uint8
    d520::Uint8
    d521::Uint8
    d522::Uint8
    d523::Uint8
    d524::Uint8
    d525::Uint8
    d526::Uint8
    d527::Uint8
    d528::Uint8
    d529::Uint8
    d530::Uint8
    d531::Uint8
    d532::Uint8
    d533::Uint8
    d534::Uint8
    d535::Uint8
    d536::Uint8
    d537::Uint8
    d538::Uint8
    d539::Uint8
    d540::Uint8
    d541::Uint8
    d542::Uint8
    d543::Uint8
    d544::Uint8
    d545::Uint8
    d546::Uint8
    d547::Uint8
    d548::Uint8
    d549::Uint8
    d550::Uint8
    d551::Uint8
    d552::Uint8
    d553::Uint8
    d554::Uint8
    d555::Uint8
    d556::Uint8
    d557::Uint8
    d558::Uint8
    d559::Uint8
    d560::Uint8
    d561::Uint8
    d562::Uint8
    d563::Uint8
    d564::Uint8
    d565::Uint8
    d566::Uint8
    d567::Uint8
    d568::Uint8
    d569::Uint8
    d570::Uint8
    d571::Uint8
    d572::Uint8
    d573::Uint8
    d574::Uint8
    d575::Uint8
    d576::Uint8
    d577::Uint8
    d578::Uint8
    d579::Uint8
    d580::Uint8
    d581::Uint8
    d582::Uint8
    d583::Uint8
    d584::Uint8
    d585::Uint8
    d586::Uint8
    d587::Uint8
    d588::Uint8
    d589::Uint8
    d590::Uint8
    d591::Uint8
    d592::Uint8
    d593::Uint8
    d594::Uint8
    d595::Uint8
    d596::Uint8
    d597::Uint8
    d598::Uint8
    d599::Uint8
    d600::Uint8
    d601::Uint8
    d602::Uint8
    d603::Uint8
    d604::Uint8
    d605::Uint8
    d606::Uint8
    d607::Uint8
    d608::Uint8
    d609::Uint8
    d610::Uint8
    d611::Uint8
    d612::Uint8
    d613::Uint8
    d614::Uint8
    d615::Uint8
    d616::Uint8
    d617::Uint8
    d618::Uint8
    d619::Uint8
    d620::Uint8
    d621::Uint8
    d622::Uint8
    d623::Uint8
    d624::Uint8
    d625::Uint8
    d626::Uint8
    d627::Uint8
    d628::Uint8
    d629::Uint8
    d630::Uint8
    d631::Uint8
    d632::Uint8
    d633::Uint8
    d634::Uint8
    d635::Uint8
    d636::Uint8
    d637::Uint8
    d638::Uint8
    d639::Uint8
    d640::Uint8
    d641::Uint8
    d642::Uint8
    d643::Uint8
    d644::Uint8
    d645::Uint8
    d646::Uint8
    d647::Uint8
    d648::Uint8
    d649::Uint8
    d650::Uint8
    d651::Uint8
    d652::Uint8
    d653::Uint8
    d654::Uint8
    d655::Uint8
    d656::Uint8
    d657::Uint8
    d658::Uint8
    d659::Uint8
    d660::Uint8
    d661::Uint8
    d662::Uint8
    d663::Uint8
    d664::Uint8
    d665::Uint8
    d666::Uint8
    d667::Uint8
    d668::Uint8
    d669::Uint8
    d670::Uint8
    d671::Uint8
    d672::Uint8
    d673::Uint8
    d674::Uint8
    d675::Uint8
    d676::Uint8
    d677::Uint8
    d678::Uint8
    d679::Uint8
    d680::Uint8
    d681::Uint8
    d682::Uint8
    d683::Uint8
    d684::Uint8
    d685::Uint8
    d686::Uint8
    d687::Uint8
    d688::Uint8
    d689::Uint8
    d690::Uint8
    d691::Uint8
    d692::Uint8
    d693::Uint8
    d694::Uint8
    d695::Uint8
    d696::Uint8
    d697::Uint8
    d698::Uint8
    d699::Uint8
    d700::Uint8
    d701::Uint8
    d702::Uint8
    d703::Uint8
    d704::Uint8
    d705::Uint8
    d706::Uint8
    d707::Uint8
    d708::Uint8
    d709::Uint8
    d710::Uint8
    d711::Uint8
    d712::Uint8
    d713::Uint8
    d714::Uint8
    d715::Uint8
    d716::Uint8
    d717::Uint8
    d718::Uint8
    d719::Uint8
    d720::Uint8
    d721::Uint8
    d722::Uint8
    d723::Uint8
    d724::Uint8
    d725::Uint8
    d726::Uint8
    d727::Uint8
    d728::Uint8
    d729::Uint8
    d730::Uint8
    d731::Uint8
    d732::Uint8
    d733::Uint8
    d734::Uint8
    d735::Uint8
    d736::Uint8
    d737::Uint8
    d738::Uint8
    d739::Uint8
    d740::Uint8
    d741::Uint8
    d742::Uint8
    d743::Uint8
    d744::Uint8
    d745::Uint8
    d746::Uint8
    d747::Uint8
    d748::Uint8
    d749::Uint8
    d750::Uint8
    d751::Uint8
    d752::Uint8
    d753::Uint8
    d754::Uint8
    d755::Uint8
    d756::Uint8
    d757::Uint8
    d758::Uint8
    d759::Uint8
    d760::Uint8
    d761::Uint8
    d762::Uint8
    d763::Uint8
    d764::Uint8
    d765::Uint8
    d766::Uint8
    d767::Uint8
    d768::Uint8
    d769::Uint8
    d770::Uint8
    d771::Uint8
    d772::Uint8
    d773::Uint8
    d774::Uint8
    d775::Uint8
    d776::Uint8
    d777::Uint8
    d778::Uint8
    d779::Uint8
    d780::Uint8
    d781::Uint8
    d782::Uint8
    d783::Uint8
    d784::Uint8
    d785::Uint8
    d786::Uint8
    d787::Uint8
    d788::Uint8
    d789::Uint8
    d790::Uint8
    d791::Uint8
    d792::Uint8
    d793::Uint8
    d794::Uint8
    d795::Uint8
    d796::Uint8
    d797::Uint8
    d798::Uint8
    d799::Uint8
    d800::Uint8
    d801::Uint8
    d802::Uint8
    d803::Uint8
    d804::Uint8
    d805::Uint8
    d806::Uint8
    d807::Uint8
    d808::Uint8
    d809::Uint8
    d810::Uint8
    d811::Uint8
    d812::Uint8
    d813::Uint8
    d814::Uint8
    d815::Uint8
    d816::Uint8
    d817::Uint8
    d818::Uint8
    d819::Uint8
    d820::Uint8
    d821::Uint8
    d822::Uint8
    d823::Uint8
    d824::Uint8
    d825::Uint8
    d826::Uint8
    d827::Uint8
    d828::Uint8
    d829::Uint8
    d830::Uint8
    d831::Uint8
    d832::Uint8
    d833::Uint8
    d834::Uint8
    d835::Uint8
    d836::Uint8
    d837::Uint8
    d838::Uint8
    d839::Uint8
    d840::Uint8
    d841::Uint8
    d842::Uint8
    d843::Uint8
    d844::Uint8
    d845::Uint8
    d846::Uint8
    d847::Uint8
    d848::Uint8
    d849::Uint8
    d850::Uint8
    d851::Uint8
    d852::Uint8
    d853::Uint8
    d854::Uint8
    d855::Uint8
    d856::Uint8
    d857::Uint8
    d858::Uint8
    d859::Uint8
    d860::Uint8
    d861::Uint8
    d862::Uint8
    d863::Uint8
    d864::Uint8
    d865::Uint8
    d866::Uint8
    d867::Uint8
    d868::Uint8
    d869::Uint8
    d870::Uint8
    d871::Uint8
    d872::Uint8
    d873::Uint8
    d874::Uint8
    d875::Uint8
    d876::Uint8
    d877::Uint8
    d878::Uint8
    d879::Uint8
    d880::Uint8
    d881::Uint8
    d882::Uint8
    d883::Uint8
    d884::Uint8
    d885::Uint8
    d886::Uint8
    d887::Uint8
    d888::Uint8
    d889::Uint8
    d890::Uint8
    d891::Uint8
    d892::Uint8
    d893::Uint8
    d894::Uint8
    d895::Uint8
    d896::Uint8
    d897::Uint8
    d898::Uint8
    d899::Uint8
    d900::Uint8
    d901::Uint8
    d902::Uint8
    d903::Uint8
    d904::Uint8
    d905::Uint8
    d906::Uint8
    d907::Uint8
    d908::Uint8
    d909::Uint8
    d910::Uint8
    d911::Uint8
    d912::Uint8
    d913::Uint8
    d914::Uint8
    d915::Uint8
    d916::Uint8
    d917::Uint8
    d918::Uint8
    d919::Uint8
    d920::Uint8
    d921::Uint8
    d922::Uint8
    d923::Uint8
    d924::Uint8
    d925::Uint8
    d926::Uint8
    d927::Uint8
    d928::Uint8
    d929::Uint8
    d930::Uint8
    d931::Uint8
    d932::Uint8
    d933::Uint8
    d934::Uint8
    d935::Uint8
    d936::Uint8
    d937::Uint8
    d938::Uint8
    d939::Uint8
    d940::Uint8
    d941::Uint8
    d942::Uint8
    d943::Uint8
    d944::Uint8
    d945::Uint8
    d946::Uint8
    d947::Uint8
    d948::Uint8
    d949::Uint8
    d950::Uint8
    d951::Uint8
    d952::Uint8
    d953::Uint8
    d954::Uint8
    d955::Uint8
    d956::Uint8
    d957::Uint8
    d958::Uint8
    d959::Uint8
    d960::Uint8
    d961::Uint8
    d962::Uint8
    d963::Uint8
    d964::Uint8
    d965::Uint8
    d966::Uint8
    d967::Uint8
    d968::Uint8
    d969::Uint8
    d970::Uint8
    d971::Uint8
    d972::Uint8
    d973::Uint8
    d974::Uint8
    d975::Uint8
    d976::Uint8
    d977::Uint8
    d978::Uint8
    d979::Uint8
    d980::Uint8
    d981::Uint8
    d982::Uint8
    d983::Uint8
    d984::Uint8
    d985::Uint8
    d986::Uint8
    d987::Uint8
    d988::Uint8
    d989::Uint8
    d990::Uint8
    d991::Uint8
    d992::Uint8
    d993::Uint8
    d994::Uint8
    d995::Uint8
    d996::Uint8
    d997::Uint8
    d998::Uint8
    d999::Uint8
    d1000::Uint8
    d1001::Uint8
    d1002::Uint8
    d1003::Uint8
    d1004::Uint8
    d1005::Uint8
    d1006::Uint8
    d1007::Uint8
    d1008::Uint8
    d1009::Uint8
    d1010::Uint8
    d1011::Uint8
    d1012::Uint8
    d1013::Uint8
    d1014::Uint8
    d1015::Uint8
    d1016::Uint8
    d1017::Uint8
    d1018::Uint8
    d1019::Uint8
    d1020::Uint8
    d1021::Uint8
    d1022::Uint8
    d1023::Uint8
    d1024::Uint8
end

zero(::Type{Array_1024_Uint8}) = Array_1024_Uint8(fill(zero(Uint8),1024)...)

immutable AVProgram
    id::Cint
    flags::Cint
    discard::AVDiscard
    stream_index::Ptr{Uint32}
    nb_stream_indexes::Uint32
    metadata::Ptr{AVDictionary}
end

immutable AVChapter
    id::Cint
    time_base::AVRational
    start::Int64
    _end::Int64
    metadata::Ptr{AVDictionary}
end

typealias AVFormatInternal Void

immutable AVFormatContext
    av_class::Ptr{AVClass}
    iformat::Ptr{AVInputFormat}
    oformat::Ptr{AVOutputFormat}
    priv_data::Ptr{Void}
    pb::Ptr{AVIOContext}
    ctx_flags::Cint
    nb_streams::Uint32
    streams::Ptr{Ptr{AVStream}}
    filename::Array_1024_Uint8
    start_time::Int64
    duration::Int64
    bit_rate::Cint
    packet_size::Uint32
    max_delay::Cint
    flags::Cint
    probesize::Uint32
    max_analyze_duration::Cint
    key::Ptr{Uint8}
    keylen::Cint
    nb_programs::Uint32
    programs::Ptr{Ptr{AVProgram}}
    video_codec_id::AVCodecID
    audio_codec_id::AVCodecID
    subtitle_codec_id::AVCodecID
    max_index_size::Uint32
    max_picture_buffer::Uint32
    nb_chapters::Uint32
    chapters::Ptr{Ptr{AVChapter}}
    metadata::Ptr{AVDictionary}
    start_time_realtime::Int64
    fps_probe_size::Cint
    error_recognition::Cint
    interrupt_callback::AVIOInterruptCB
    debug::Cint
    max_interleave_delta::Int64
    packet_buffer::Ptr{AVPacketList}
    packet_buffer_end::Ptr{AVPacketList}
    data_offset::Int64
    raw_packet_buffer::Ptr{AVPacketList}
    raw_packet_buffer_end::Ptr{AVPacketList}
    parse_queue::Ptr{AVPacketList}
    parse_queue_end::Ptr{AVPacketList}
    raw_packet_buffer_remaining_size::Cint
    offset::Int64
    offset_timebase::AVRational
    internal::Ptr{AVFormatInternal}
end


text:
module adapters_sqlite_array_test

# https://discourse.julialang.org/t/use-julia-array-in-sqlite-query/32049

using Test # @test
using Octo.Adapters.SQLite # Repo Schema from SELECT FROM WHERE

import SQLite # pathof(SQLite)
dbfile = joinpath(dirname(pathof(SQLite)), "..", "test", "Chinook_Sqlite.sqlite")
dbfile2 = joinpath(@__DIR__, "test.sqlite")
cp(dbfile, dbfile2; force=true)
chmod(dbfile2, 0o666)

Repo.debug_sql()

Repo.connect(
    adapter = Octo.Adapters.SQLite,
    dbfile = dbfile2
)

struct Temp
end
Schema.model(Temp, table_name="temp")

Repo.execute([DROP TABLE IF EXISTS Temp])
Repo.execute(Raw("""
    CREATE TABLE Temp (
        id INTEGER PRIMARY KEY,
        label TEXT NOT NULL
    )"""))

Repo.insert!(Temp, [
                    (label="d",),
                    (label="c",),
                    (label="c",),
                    (label="b",),
                    (label="a",)])

df = Repo.query([SELECT * FROM Temp WHERE :label IN ("a","b","c")])
@test size(df) == (4,)

df = Repo.query([SELECT * FROM Temp WHERE :label IN ("a",)])
@test size(df) == (1,)

df = Repo.query([SELECT * FROM Temp WHERE :label IN ()])
@test size(df) == (0,)

Repo.disconnect()

end # module adapters_sqlite_array_test

module adapters_sqlite_repo_test

using Test # @test
using Octo.Adapters.SQLite # Repo Schema from SELECT FROM WHERE

import SQLite # pathof(SQLite)
dbfile = joinpath(dirname(pathof(SQLite)), "..", "test", "Chinook_Sqlite.sqlite")
dbfile2 = joinpath(@__DIR__, "test.sqlite")
cp(dbfile, dbfile2; force=true)
chmod(dbfile2, 0o666)

Repo.debug_sql()

Repo.connect(
    adapter = Octo.Adapters.SQLite,
    dbfile = dbfile2
)

struct Employee
end
Schema.model(Employee,
    table_name = "Employee",
    primary_key = "EmployeeId"
)

df = Repo.query(Employee)
@test df isa Vector{<:NamedTuple}
@test size(df) == (8,)

df = Repo.get(Employee, 2)
@test size(df) == (1,)

em = from(Employee)
df = Repo.query([SELECT * FROM em WHERE em.EmployeeId == 2])
@test size(df) == (1,)

# using Octo.Adapters.SQLite # CREATE TABLE IF NOT EXISTS
Repo.query([CREATE TABLE IF NOT EXISTS :temp AS SELECT * FROM :Album])

struct Temp
end
Schema.model(Temp, table_name="temp", primary_key="AlbumId")

df = Repo.query(Temp)
@test size(df) == (347,)

changes = (AlbumId=0, Title="Test Album", ArtistId=0)
result = Repo.insert!(Temp, changes)
@test result.num_affected_rows == 1

df = Repo.query(Temp)
@test size(df) == (348,)

df = Repo.get(Temp, 6)
@test df[1].Title == "Jagged Little Pill"

df = Repo.get(Temp, (Title="Jagged Little Pill",))
@test df[1].Title == "Jagged Little Pill"

changes = (AlbumId=6, Title="Texas")
result = Repo.update!(Temp, changes)
@test result.num_affected_rows == 1

df = Repo.get(Temp, 6)
@test df[1].Title == "Texas"

result = Repo.delete!(Temp, changes)
@test result.num_affected_rows == 1

df = Repo.get(Temp, 6)
@test size(df) == (0,)

❔  = Octo.PlaceHolder

a = from(Temp)
df = Repo.query([SELECT * FROM a WHERE a.Title == ❔  AND a.ArtistId == ❔ ], ["The Doors", 140])
@test size(df) == (1,)

Repo.disconnect()

end # module adapters_sqlite_repo_test


text:
using DrWatson
quickactivate(@__DIR__)
@show projectdir()
##
using CovidSurvey
using CSV
using DataFrames
using Dates
# using RCall
using Turing
using StatsPlots
using Plots.PlotMeasures
using Random
## ===========================================================================
# load data and model
# ============================================================================
# fname = projectdir("reports/2021-04-28/Rt_cases=2020-06-01_chains=10_hospit=true_model=contacts2_observ=2021-02-07_preds=CF,CC,CR,CS_seed=20000_sero=true_steps=2000_warmup=1000.csv")
# fname = projectdir("reports/2021-04-28/Rt_cases=2020-06-01_chains=10_hospit=true_model=v2_observ=2021-02-07_seed=10000_sero=true_steps=2000_warmup=1000.csv")
fname = projectdir("reports/2021-04-28/Rt_cases=2020-06-01_chains=10_hospit=true_model=contacts2_observ=2020-12-16_preds=CF,CC,CR,CS_seed=30000_sero=true_steps=1000_warmup=1000.csv")
# fname = projectdir("reports/2021-04-28-b/Rt_cases=2020-06-01_chains=10_hospit=true_model=contacts2_observ=2020-12-16_preds=CF,CC,CR,CS_seed=40000_sero=true_steps=2000_warmup=1000.csv")
# fname = projectdir("reports/2021-04-28-b/Rt_cases=2020-06-01_chains=10_hospit=true_model=contacts2_observ=2021-02-07_preds=CF,CC,CR,CS_seed=40000_sero=true_steps=2000_warmup=1000.csv")
rtp = load(fname) |> DataFrame
# fname = projectdir("reports/2021-04-28/Rt_cases=2020-06-01_chains=10_hospit=true_model=v2_observ=2021-02-07_seed=10000_sero=true_steps=2000_warmup=1000.csv")
# fname = projectdir("reports/constant_iar/Rt_cases=2020-06-01_chains=10_hospit=true_model=const_observ=2021-02-06_sero=true_steps=2000_warmup=1000.csv")
fname = projectdir("reports/2021-04-27/Rt_cases=2020-06-01_chains=10_hospit=true_model=v2_observ=2020-12-16_seed=10000_sero=true_steps=2000_warmup=1000.csv")
rt = load(fname) |> DataFrame
#------------------------------------------------------------------------------
# Rt_with_vs_without_predictors
Plots.scalefontsizes(1.3)
pgfplotsx()
p = let
    p = plot(legend=:bottomright, ylabel=L"R_t")
    plot!(rtp.date, rtp.mq, ribbon=(rtp.mq - rtp.llq, rtp.uuq - rtp.mq), lw=2, label="with predictors (contact data)")
    plot!(rt.date, rt.mq, ribbon=(rt.mq - rt.llq, rt.uuq - rt.mq), lw=2, label="without predictors")
    # xlims!((t[1],t[end]))
end
savefig(projectdir("figures/compare_Rt.png"))
#------------------------------------------------------------------------------
# model vs SSI
Plots.scalefontsizes(1.5)

function make_consistent(df1, df2; startdate=nothing, enddate=nothing)
    df1 = deepcopy(df1)
    df2 = deepcopy(df2)
    ts = isnothing(startdate) ? max(df1.date[1], df2.date[1]) : Date(startdate)
    te = isnothing(enddate) ? min(df1.date[end], df2.date[end]) : Date(enddate)
    df1 = df1[ findfirst(==(ts), df1.date) : findfirst(==(te), df1.date), :]
    df2 = df2[ findfirst(==(ts), df2.date) : findfirst(==(te), df2.date), :]
    @assert all(df1.date .== df2.date)
    return df1, df2
end

pgfplotsx()
p = let
    rt = projectdir("reports/test_single_observation_AlternativeDelays/Rt_cases=2020-06-01_chains=10_hospit=true_model=cases_observ=2021-02-06_sero=true_steps=2000_warmup=1000.csv") |> load |> DataFrame
    rt_ssi = projectdir("data/Rt_SSI.csv") |> load |> DataFrame
    rt, rt_ssi = make_consistent(rt, rt_ssi, enddate="2020-12-15")
    p = plot(legend=:topleft, ylabel=L"R_t", size=(800, 500))
    plot!(rt_ssi.date, rt_ssi.mq, ribbon=(rt_ssi.mq - rt_ssi.llq, rt_ssi.uuq - rt_ssi.mq), lw=2, label="SSI", c=:sienna)
    plot!(rt.date, rt.mq, ribbon=(rt.mq - rt.llq, rt.uuq - rt.mq), lw=2, label="model without predictors", c=:royalblue)
end
savefig(projectdir("figures/compare_Rt_model_without_predictors_vs_SSI.png"))
#------------------------------------------------------------------------------

#------------------------------------------------------------------------------
fnames = [
    # projectdir("reports/test_single_observation_AlternativeDelays/Rt_cases=2020-06-01_chains=10_hospit=true_model=cases_observ=2021-02-06_sero=true_steps=2000_warmup=1000.csv")
    # projectdir("reports/test_single_observation_AlternativeDelays/Rt_cases=2020-06-01_chains=10_hospit=true_model=hospit_observ=2021-02-06_sero=true_steps=2000_warmup=1000.csv")
    # projectdir("reports/test_single_observation_AlternativeDelays/Rt_cases=2020-06-01_chains=10_hospit=true_model=deaths_observ=2021-02-06_sero=true_steps=2000_warmup=1000.csv")

    # projectdir("reports/test_single_observation_BrauersParameters/Rt_cases=2020-06-01_chains=10_hospit=true_model=cases_observ=2021-03-25_sero=true_steps=2000_warmup=1000.csv")
    # projectdir("reports/test_single_observation_BrauersParameters/Rt_cases=2020-06-01_chains=10_hospit=true_model=hospit_observ=2021-03-25_sero=true_steps=2000_warmup=1000.csv")
    # projectdir("reports/test_single_observation_BrauersParameters/Rt_cases=2020-06-01_chains=10_hospit=true_model=deaths_observ=2021-03-25_sero=true_steps=2000_warmup=1000.csv")

    projectdir("reports/variable-delays/Rt_cases=2020-06-01_chains=10_hospit=true_model=cases_observ=2021-02-06_sero=true_steps=4000_warmup=1000.csv")
    projectdir("reports/variable-delays/Rt_cases=2020-06-01_chains=10_hospit=true_model=hospit_observ=2021-02-06_sero=true_steps=4000_warmup=1000.csv")
    projectdir("reports/variable-delays/Rt_cases=2020-06-01_chains=10_hospit=true_model=deaths_observ=2021-02-06_sero=true_steps=4000_warmup=1000.csv")
]
ns = ["cases", "hospit", "death"]

# pgfplotsx()
plotlyjs()
p = let
    # rt, rt_ssi = make_consistent(rt, rt_ssi, enddate="2020-12-15")
    p = plot(legend=:outertopright, ylabel="R_t", size=(1200, 600))
    for (fname, n) in zip(fnames, ns)
        rt = load(fname) |> DataFrame
        plot!(rt.date, rt.mq, ribbon=(rt.mq - rt.llq, rt.uuq - rt.mq), lw=2, label=n)
    end
    # xlims!((t[1],t[end]))
    rt = projectdir("data/Rt.csv") |> load |> DataFrame
    plot!(rt.date, rt[:,"Rt-SSI"], lw=2, label="SSI")
    # plot!(rt.date, rt[:,"Rt-SSI-shifted"], lw=2, label="SSI-shifted")
    # plot!(rt.date, rt[:,"Rt-observ-2021-02-07"], lw=2, label="observ-2021-02-07")
    survey = load( "/home/and/data/covidsurvey/smoothed_contacts.csv" ) |> DataFrame
    plot!(survey.date, survey.colleagues, ticks=:native, label="colleagues")
    plot!(survey.date, survey.family, ticks=:native, label="family")
    plot!(survey.date, survey.strangers, ticks=:native, label="strangers")
    plot!(survey.date, survey.friends, ticks=:native, label="friends")
    p
end;
savefig("/home/and/tmp/figures/Rt_vs_contacts_2021-06-04.html")
run(`firefox /home/and/tmp/figures/Rt_vs_contacts_2021-06-04.html`, wait=false)

#------------------------------------------------------------------------------
# Rt_vs_predictors
pgfplotsx()
cov = turing_data.covariates
p = let
    p = plot(legend=:topright)
    plot!(Rt_original.date, Rt_original.mq, ribbon=(Rt_original.mq - Rt_original.llq, Rt_original.uuq - Rt_original.mq), linewidth=2, label="Rt without predictors", c=:black)
    p2 = twinx()
    for (i, n) in enumerate(["colleagues","strangers","family","friends"])
        plot!(p2, t, cov[1:length(t),i], lw=2, label=n, grid=:off, xticks=:none)
    end
    xlims!((t[1],t[end]))
end
# savefig(p, projectdir("figures/", "Rt_vs_predictors.png") )
#------------------------------------------------------------------------------
# compare to SSI data to predictors
Rt_SSI = National.readsurvey("/home/and/data/covidsurvey/contacts.csv")
Rt_SSI = select( Rt_SSI, [:Rt,:uncertainty_lower,:uncertainty_upper, :date])
p = let
    p = plot(legend=:topright)
    plot!(Rt_SSI.date, Rt_SSI.Rt, ribbon=(Rt_SSI.Rt - Rt_SSI.uncertainty_lower, Rt_SSI.uncertainty_upper - Rt_SSI.Rt), linewidth=2, label="Rt (SSI) without predictors", c=:black)
    p2 = twinx()
    for (i, n) in enumerate(["colleagues","strangers","family","friends"])
        plot!(p2, t, cov[1:length(t),i], lw=2, label=n, grid=:off, xticks=:none)
    end
    xlims!((t[1],t[end]))
end
# savefig(p, projectdir("figures/", "Rt_from_SSI_vs_predictors.png") )
#------------------------------------------------------------------------------
# compare to SSI data to inferred Rt
p = let
    p = plot(legend=:topright)
    plot!(Rt_original.date, Rt_original.mq, ribbon=(Rt_original.mq - Rt_original.llq, Rt_original.uuq - Rt_original.mq), linewidth=2, label="Rt without predictors")
    plot!(Rt_SSI.date, Rt_SSI.Rt, ribbon=(Rt_SSI.Rt - Rt_SSI.uncertainty_lower, Rt_SSI.uncertainty_upper - Rt_SSI.Rt), linewidth=2, label="Rt (SSI)", c=:black)
    xlims!((t[1],t[end]))
end
# savefig(p, projectdir("figures/", "Rt_without_predictors_vs_Rt_from_SSI.png") )
#------------------------------------------------------------------------------
# compare to Rt from SSI or model to predictors
survey = National.readsurveys_raw()
p = let
    ps = []
    ts = survey.date
    for (i, n) in [(3,:family), (1,:colleagues), (4,:friends), (2,:strangers)] #"CC,CS,CF,CR"
        p = plot()
        plot!(
         #Rt_SSI.date, Rt_SSI.Rt, ribbon=(Rt_SSI.Rt - Rt_SSI.uncertainty_lower, Rt_SSI.uncertainty_upper - Rt_SSI.Rt),
         Rt_original.date, Rt_original.mq, ribbon=(Rt_original.mq - Rt_original.llq, Rt_original.uuq - Rt_original.mq),
         linewidth=2, label=nothing, c=:black, α=.5, ylabel="\$R_t\$",
         right_margin=20mm, bottom_margin=10mm)
        p2 = twinx()
        xs = survey[:, n]
        x = cov[1:length(t),i]
        National.surveynorm!(xs)
        plot!(p2, ts, xs / std(xs) * std(x), lw=2,
            label="$n (raw)", grid=:off, xticks=:none, c=:darkred,
            ylabel="contacts (normalized)",
            right_margin=20mm, bottom_margin=10mm,
            extra_kwargs=:subplot, legend=:outertop, legend_columns=-1)
        plot!(p2, t, x, lw=4, label="$n (smoothed)",
            grid=:off, xticks=:none, c=:darkorange,
            right_margin=20mm, bottom_margin=10mm,
            extra_kwargs=:subplot, legend=:outertop, legend_columns=-1)
        xlims!((t[1],t[end]))
        push!(ps, p)
    end
    #l = @layout [a{0.2w} b{0.2w}; c d]
    plot(ps..., layout=4, size=(1300, 1000))
end
# savefig(p, projectdir("figures/", "Rt_vs_predictors_smoothed_and_raw.png") )

max_stars_repo_name: andreaskoher/CovidSurvey

max_issues_repo_name: andreaskoher/CovidSurvey

max_forks_repo_name: andreaskoher/CovidSurvey


text:
module LayoutPointers

using ArrayInterface, Static, LinearAlgebra
using ArrayInterface: CPUPointer, StrideIndex, offsets
using SIMDTypes: Bit, FloatingTypes
using Static: Zero, One
using ArrayInterface: contiguous_axis, contiguous_axis_indicator, contiguous_batch_size,
  stride_rank, offsets, offset1, CPUTuple, static_first, static_step, strides
using ManualMemory: preserve_buffer, offsetsize

export stridedpointer

@inline _map(f::F, x::Tuple{}) where {F} = ()
@inline _map(f::F, x::Tuple{X1}) where {F,X1} = (f(getfield(x,1,false)), )
@inline _map(f::F, x::Tuple{X1,X2,Vararg{Any,K}}) where {F,X1,X2,K} = (f(getfield(x,1,false)), _map(f, Base.tail(x))...)

@inline _map(f::F, x::Tuple{}, y::Tuple{}) where {F} = ()
@inline _map(f::F, x::Tuple{X1}, y::Tuple{Y1}) where {F,X1,Y1} = (f(getfield(x,1,false), getfield(y,1,false)), )
@inline _map(f::F, x::Tuple{X1,X2,Vararg{Any,K}}, y::Tuple{Y1,Y2,Vararg{Any,K}}) where {F,X1,X2,Y1,Y2,K} = (f(getfield(x,1,false), getfield(y,1,false)), _map(f, Base.tail(x), Base.tail(y))...)

"""
  abstract type AbstractStridedPointer{T,N,C,B,R,X<:Tuple{Vararg{Integer,N}},O<:Tuple{Vararg{Integer,N}}} end

T: element type
N: dimensionality
C: contiguous dim
B: batch size
R: rank of strides
X: strides
O: offsets
"""
abstract type AbstractStridedPointer{T,N,C,B,R,X<:Tuple{Vararg{Integer,N}},O<:Tuple{Vararg{Integer,N}}} end

include("stridedpointers.jl")
include("grouped_strided_pointers.jl")
include("precompile.jl")

end


text:
module cheb
using LinearAlgebra

export chebdif, projmat

"""
flippy():
    Utility function that flips matrix up-down and left-right
        (or, equivalently, rotates it by 180deg).
"""
function flippy(M)
    M[end:-1:1,end:-1:1]
end

"""
chebdif():

Julia translation of the MATLAB routine by J.A.C. Weideman & S.C. Reddy (1998).

Original MATAB documentation:

%  The function DM =  chebdif(N,M) computes the differentiation
%  matrices D1, D2, ..., DM on Chebyshev nodes.
%
%  Input:
%  N:        Size of differentiation matrix.
%  M:        Number of derivatives required (integer).
%  Note:     0 < M <= N-1.
%
%  Output:
%  DM:       DM(1:N,1:N,ell) contains ell-th derivative matrix, ell=1..M.
%
%  The code implements two strategies for enhanced
%  accuracy suggested by W. Don and S. Solomonoff in
%  SIAM J. Sci. Comp. Vol. 6, pp. 1253--1268 (1994).
%  The two strategies are (a) the use of trigonometric
%  identities to avoid the computation of differences
%  x(k)-x(j) and (b) the use of the "flipping trick"
%  which is necessary since sin t can be computed to high
%  relative precision when t is small whereas sin (pi-t) cannot.
%
% J.A.C. Weideman, S.C. Reddy 1998.

"""
function chebdif(N::Integer,M::Integer)
    I  = diagm(ones(N))             # Identity matrix
    L  = I.!=0                      # Logical identity matrix

    n1 = N÷2;    n2 = n1 + N%2      # Indices used for flipping trick.

    k  = collect(0:N-1)             # Compute theta vector.
    th = k * π/(N-1)

    temp = collect(N-1:-2:1-N)
    x  = sin.(π*temp/(2.0*(N-1)))   # Compute Chebyshev points

    T  = repeat(th/2,1,N)
    DX = 2*sin.(T'+T) .* sin.(T'-T) # Trigonometric identity.

    DX = [DX[1:n1,:]; -flippy(DX[1:n2,:])]
    DX[L] .= 1.0

    temp = (-1.0).^k
    C = temp * temp'  # generates a Toeplitz matrix with diagonal of +1 and alternating signs on diags
    C[1,:]   *= 2;      C[end,:] *= 2
    C[:,1]   *= 0.5;    C[:,end] *= 0.5

    Z = 1.0./DX
    Z[L] .= 0.0
    D = diagm(ones(N))

    s = size(D)
    DM = zeros(s...,M)
    De = zeros(n2,n2,M)
    Do = zeros(n2,n2,M)
    (Pe,Po,Qe,Qo) = projmat(N)

    for ell in 1:M
        D = ell * Z .* (C .* repeat(diag(D),1,N) - D)
        D[L] = -sum(D,dims=2)
        DM[:,:,ell] = D
        if ell%2 == 0 # 2nd, 4th, 6th etc derivatives do not change parity
            De[:,:,ell] = Pe * D * Qe
            Do[:,:,ell] = Po * D * Qo
        else # 1st, 3rd, 5th etc derivatives change parity
            De[:,:,ell] = Po * D * Qe
            Do[:,:,ell] = Pe * D * Qo
        end
    end
    return (x,DM,De,Do)
end

"""
projmat():

    Constructs projection matrices to project (and de-project) onto space of
    even and odd functions, from general space of functions.

    I could try to be clever here, dealing with N odd or even, but I forgo
    cleverness in favor of readability. (In all likelihood this could be done
    in far fewer lines, I'm sure.)

    2*Peve' de-projects an even function back onto the full function space.
    2*Podd' de-projects an odd function back onto the full function space.

    Peve is the inverse of dPeve
    Podd is the inverse of dPodd
"""
function projmat(N::Integer)
    n1 = N÷2;  n2 = n1 + N%2
    isNodd = (n2>n1) # is N odd?
    top = diagm(ones(n2))
    if isNodd
        Qodd = [ top[1:n2,:] ; -top[n1:-1:1,:] ]
        Qodd[n2,:] .*= 0
        Podd = Qodd' *0.5
        Qeve = [ top[1:n2,:] ; top[n1:-1:1,:] ]
        Peve = Qeve' *0.5
        Peve[:,n2] .*= 2
    else
        Qodd = [ top[1:n1,:] ; -top[n1:-1:1,:] ]
        Qeve = [ top[1:n1,:] ;  top[n1:-1:1,:] ]
        Podd = Qodd' *0.5
        Peve = Qeve' *0.5
    end
    return (Peve,Podd,Qeve,Qodd)
end

end#module

max_stars_repo_name: diakosmos/razor

max_issues_repo_name: diakosmos/razor

max_forks_repo_name: diakosmos/razor


text:
module Stegr
using LinearAlgebra
using LinearAlgebra.BLAS: @blasfunc
using LinearAlgebra: BlasInt
import LinearAlgebra.LAPACK: stegr!
const liblapack = Base.liblapack_name

mutable struct StegrWork{T<:Real}
    jobz::Char
    range::Char
    dv::Vector{T}
    ev::Vector{T}
    vl::Real
    vu::Real
    il::BlasInt
    iu::BlasInt
    abstol::Vector{T}
    m::Vector{BlasInt}
    w::Vector{T}
    Z::Matrix{T}
    isuppz::Vector{BlasInt}
    work::Vector{T}
    lwork::BlasInt
    iwork::Vector{BlasInt}
    liwork::BlasInt
    info::Vector{BlasInt}
end

for (stegr,elty) in ((:dstegr_,:Float64),
                     (:sstegr_,:Float32))
    @eval begin
        function stegr!(n::BlasInt, sw::StegrWork{$elty})
            ldz = stride(sw.Z, 2)
            ccall((@blasfunc($stegr), liblapack), Cvoid,
                  (Ref{UInt8}, Ref{UInt8}, Ref{BlasInt}, Ptr{$elty},
                   Ptr{$elty}, Ref{$elty}, Ref{$elty}, Ref{BlasInt},
                   Ref{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$elty},
                   Ptr{$elty}, Ref{BlasInt}, Ptr{BlasInt}, Ptr{$elty},
                   Ref{BlasInt}, Ptr{BlasInt}, Ref{BlasInt}, Ptr{BlasInt}),
                  sw.jobz, sw.range, n,
                  sw.dv, sw.ev,
                  sw.vl, sw.vu, sw.il, sw.iu,
                  sw.abstol, sw.m,
                  sw.w, sw.Z, ldz,
                  sw.isuppz, sw.work, sw.lwork, sw.iwork, sw.liwork,
                  sw.info)
        end
    end
end

"""
    stegr!(α, β, sw)

Diagonalize the real-symmetric tridiagonal matrix with `α` on the
diagonal and `β` on the super-/subdiagonal, using the workspaces
allocated in `sw`.
"""
function stegr!(α::AbstractVector{T}, β::AbstractVector{T}, sw::StegrWork{T}) where T
    # @assert length(sw.dv) >= length(α)
    # @assert length(sw.ev) >= length(β)
    copyto!(sw.dv, α)
    copyto!(sw.ev, β)
    stegr!(BlasInt(length(α)), sw)
end

"""
    StegrWork(T, n)

Allocate work arrays for diagonalization of real-symmetric tridiagonal
matrices of sizes up to `n`×`n`.
"""
function StegrWork(::Type{T}, n::Integer,
                   jobz::Char = 'V', range::Char = 'A') where T
    n = convert(BlasInt, n)
    dv = Array{T}(undef, n)
    ev = Array{T}(undef, n)
    abstol = Array{T}(undef, 1)
    m = Vector{BlasInt}(undef, 1)
    w = Array{T}(undef, n)
    ldz = jobz == 'N' ? 1 : n
    Z = Array{T}(undef, ldz, n)
    isuppz = Array{BlasInt}(undef, 2n)
    work = Array{T}(undef, 1)
    lwork = -one(BlasInt)
    iwork = Array{BlasInt}(undef, 1)
    liwork = -one(BlasInt)
    info = Array{BlasInt}(undef, 1)
    sw = StegrWork(jobz, range,
                   dv, ev,
                   0.0, 0.0,
                   BlasInt(0), BlasInt(0),
                   abstol, m,
                   w, Z,
                   isuppz,
                   work, lwork,
                   iwork, liwork,
                   info)
    # Call stegr! once to query for necessary workspace sizes.
    stegr!(n, sw)
    sw.lwork = BlasInt(sw.work[1])
    sw.work = Array{T}(undef, sw.lwork)
    sw.liwork = sw.iwork[1]
    sw.iwork = Array{BlasInt}(undef, sw.liwork)
    sw
end

export StegrWork
end


text:
using Plotly
using JSON
using Base.Test

# just check that http://plot.ly/clientresp behaves as expected -- nothing to see here

Plotly.signin("unittest","tfzz811f5n", Dict("plotly_domain"=>"https://plot.ly","plotly_api_domain"=>"https://api.plot.ly"))

# Check for no error
original_plot = Plotly.plot([scatter(x=[1,2],y=[3,4])])
remote_plot = post(original_plot)
downloaded_plot = download(remote_plot)

# TODO: check that downloaded plot matches the original plot

#test get_plot_endpoint
endpoints = Dict("plotly_domain"=>"my_plotly_domain", "plotly_api_domain"=>"my_plotly_api_domain")
Plotly.signin("test_username", "test_api_key", endpoints)
plot_endpoint = Plotly.get_plot_endpoint()
@test plot_endpoint == "my_plotly_domain/clientresp"


text:
import .ExpressionExplorer: UsingsImports, SymbolsState

"A container for the result of parsing the cell code, with some extra metadata."
Base.@kwdef struct ExprAnalysisCache
    code::String=""
    parsedcode::Expr=Expr(:toplevel, LineNumberNode(1), Expr(:block))
    module_usings_imports::UsingsImports = UsingsImports()
    function_wrapped::Bool=false
    forced_expr_id::Union{PlutoRunner.ObjectID,Nothing}=nothing
end

ExprAnalysisCache(notebook, cell::Cell) = let
    parsedcode=parse_custom(notebook, cell)
    ExprAnalysisCache(
        code=cell.code,
        parsedcode=parsedcode,
        module_usings_imports=ExpressionExplorer.compute_usings_imports(parsedcode),
        function_wrapped=ExpressionExplorer.can_be_function_wrapped(parsedcode),
    )
end

function ExprAnalysisCache(old_cache::ExprAnalysisCache; new_properties...)
    properties = Dict{Symbol,Any}(field => getproperty(old_cache, field) for field in fieldnames(ExprAnalysisCache))
    merge!(properties, Dict{Symbol,Any}(new_properties))
    ExprAnalysisCache(;properties...)
end

struct DefaultDict{K,V} <: AbstractDict{K,V}
    default::Union{Function,DataType}
    container::Dict{K,V}
end

"The (information needed to create the) dependency graph of a notebook. Cells are linked by the names of globals that they define and reference. 🕸"
Base.@kwdef struct NotebookTopology
    nodes::DefaultDict{Cell,ReactiveNode} = DefaultDict{Cell,ReactiveNode}(ReactiveNode)
    codes::DefaultDict{Cell,ExprAnalysisCache}=DefaultDict{Cell,ExprAnalysisCache}(ExprAnalysisCache)

    unresolved_cells::Set{Cell} = Set{Cell}()
end

is_resolved(topology::NotebookTopology) = isempty(topology.unresolved_cells)

function set_unresolved(topology::NotebookTopology, unresolved_cells::Vector{Cell})
    codes = Dict{Cell,ExprAnalysisCache}(cell => ExprAnalysisCache(topology.codes[cell]; function_wrapped=false, forced_expr_id=nothing) for cell in unresolved_cells)
    NotebookTopology(nodes=topology.nodes, codes=merge(topology.codes, codes), unresolved_cells=union(topology.unresolved_cells, unresolved_cells))
end

DefaultDict{K,V}(default::Union{Function,DataType}) where {K,V} = DefaultDict{K,V}(default, Dict{K,V}())

function Base.getindex(aid::DefaultDict{K,V}, key::K)::V where {K,V}
    get!(aid.default, aid.container, key)
end
function Base.merge(a1::DefaultDict{K,V}, a2::DefaultDict{K,V}) where {K,V}
    DefaultDict{K,V}(a1.default, merge(a1.container, a2.container))
end
function Base.merge(a1::DefaultDict{K,V}, a2::AbstractDict) where {K,V}
    DefaultDict{K,V}(a1.default, merge(a1.container, a2))
end
Base.setindex!(aid::DefaultDict, args...) = Base.setindex!(aid.container, args...)
Base.delete!(aid::DefaultDict, args...) = Base.delete!(aid.container, args...)
Base.keys(aid::DefaultDict) = Base.keys(aid.container)
Base.values(aid::DefaultDict) = Base.values(aid.container)
Base.length(aid::DefaultDict) = Base.length(aid.container)
Base.iterate(aid::DefaultDict, args...) = Base.iterate(aid.container, args...)


text:
# This file covers everything related to retirement.

# The functions of the Retirement type require SimJulia and ResumableFunctions.

# The functions of the Retirement type require the Personnel, PersonnelDatabase,
#   and ManpowerSimulation types.
requiredTypes = [ "manpowerSimulation",
    "retirement" ]

for reqType in requiredTypes
    if !isdefined( Symbol( uppercase( string( reqType[ 1 ] ) ) * reqType[ 2:end ] ) )
        include( joinpath( typePath, reqType * ".jl" ) )
    end  # if !isdefined( Symbol( ...
end  # for reqType in requiredTypes

if !isdefined( :retirementReasons )
    const retirementReasons = [ "retirement", "attrition", "fired" ]
end # if !isdefined( :retirementReasons )

export setRetirementCondFlag

# This function sets the period length and the offset of the retirement
#   schedule.
export setRetirementSchedule
function setRetirementSchedule( retScheme::Retirement, freq::T1, offset::T2 ) where T1 <: Real where T2 <: Real

    if freq <= 0.0
        warn( "Retirement cycle length must be > 0.0. Not making changes to the retirement scheme." )
        return
    end  # if freq < 0.0

    retScheme.retireFreq = freq
    retScheme.retireOffset =  offset % freq + ( offset < 0.0 ? freq : 0.0 )

end  # setRetirementSchedule( retScheme, freq, offset )

# XXX the functions below need updating to properly handle changes in retirement
#   parameters.

# This function sets the maximal career length of the retirement scheme.
export setCareerLength
function setCareerLength( retScheme::Retirement, maxCareer::T ) where T <: Real

    if maxCareer < 0.0
        error( "Maximal career length must be => 0.0." )
    end  # if maxCareer < 0.0

    retScheme.maxCareerLength = maxCareer

end  # setCareerLength( retScheme, cLength )

# This function sets the maximal careeer length in the manpower simulation.
# If the max career length is entered as 0, no returement based on tenure
#   occurs.
# If the update flag is set, the retirement processes of all personnel records
#   need to be updated to reflect the change.
function setCareerLength( mpSim::ManpowerSimulation, maxCareer::T,
    updateRetirement::Bool = false ) where T <: Real

    if maxCareer < 0.0
        error( "Maximal career length must be ⩾ 0.0." )
    end  # if maxCareer < 0.0

    oldMaxCareer = mpSim.retirementScheme === nothing ? 0.0 :
        mpSim.retirementScheme.maxCareerLength   # To change for age.

    # Don't make unnecessary changes.
    if oldMaxCareer == maxCareer
        return
    end  # if oldMaxCareer == maxCareer

    # If there is no retirement scheme, create one.
    if mpSim.retirementScheme === nothing
        mpSim.retirementScheme = Retirement( maxCareer = maxCareer )
    else
        setCareerLength( mpSim.retirementScheme, maxCareer )
    end   # if maxCareer == 0.0

    # Update personnel records if necessary.
    if updateRetirement
        # XXX
    end
    # if updateRetirement

end # setCareerLength( mpSim, maxCareer, updateRetirement )

# This function sets the mandatory retirment of the retirement scheme.
export setRetirementAge
function setRetirementAge( retScheme::Retirement, retireAge::T ) where T <: Real

    if retireAge < 0.0
        error( "Mandatory retirement age must be => 0.0." )
    end  # if retireAge < 0.0

    retScheme.retireAge = retireAge

end  # setRetirementAge( retScheme, retireAge )

function setRetirementAge( mpSim::ManpowerSimulation, retireAge::T,
    updateRetirement::Bool = false ) where T <: Real

    oldRetireAge = mpSim.retirementScheme === nothing ? 0.0 :
        mpSim.retirementScheme.retireAge   # To change for age.

    # Don't make unnecessary changes.
    if oldRetireAge == retireAge
        return
    end  # if oldRetAge == retireAge

    # If there is no retirement scheme, create one.
    if mpSim.retirementScheme === nothing
        mpSim.retirementScheme = Retirement( retireAge = retireAge )
    else
        setRetirementAge( mpSim.retirementScheme, retireAge )
    end   # if maxCareer == 0.0

    # Update personnel records if necessary.
    if updateRetirement
        # XXX
    end  # if updateRetirement

end # setRetirementAge( mpSim, retireAge, updateRetirement )

"""
```
setRetirementCondFlag( retScheme::Retirement,
                       isEither::Bool )
```
This function sets the flag controlling whether one or both of the conditions
need to be satisfied for retirement scheme `retScheme` to `isEither`, where a
value of `true` stands for one of the conditions.

This function returns `nothing`.
"""
function setRetirementCondFlag( retScheme::Retirement, isEither::Bool )::Void

    retScheme.isEither = isEither
    return

end  # setRetirementCondFlag( retScheme, iseither )

"""
```
setRetirementCondFlag( mpSim::ManpowerSimulation,
                       isEither::Bool )
```
This function sets the flag controlling whether one or both of the conditions
need to be satisfied for the default retirement scheme in the manpower
simulation `mpSim` to `isEither`, where a value of `true` stands for one of the
conditions. If no default retirement scheme is defined, this function does
nothing.

This function returns `nothing`.
"""
function setRetirementCondFlag( mpSim::ManpowerSimulation, isEither::Bool )::Void

    if !isa( mpSim.retirementScheme, Void )
        setRetireCondFlag( mpSim.retirementScheme, isEither )
    end  # if !isa( mpSim.retirementScheme, Void )

    return

end  # setRetirementCondFlag( retScheme, iseither )

function retirePerson( mpSim::ManpowerSimulation, id::String, reason::String )

    if !in( reason, retirementReasons )
        error( "$reason -- unknown retirement reason." )
    end  # if !in( reason, retirementReasons )

    mpSim.personnelSize -= 1
    personInStates = [ "active" ]

    for state in keys( merge( mpSim.initStateList, mpSim.otherStateList ) )
        if haskey( state.inStateSince, id )
            push!( personInStates, state.name )
        end  # if haskey( state.inStateSince, id )

        delete!( state.inStateSince, id )
        delete!( state.isLockedForTransition, id )
    end  # for id in keys( merge( ...

    # Change the person's status in the personnel database.
    command = "UPDATE $(mpSim.personnelDBname)
        SET status = '$reason', timeExited = $(now( mpSim ))
        WHERE $(mpSim.idKey) = '$id'"
    SQLite.execute!( mpSim.simDB, command )

    # Add the person's status change to the history database.
    command = "INSERT INTO $(mpSim.historyDBname)
        ($(mpSim.idKey), attribute, timeIndex, strValue) VALUES
        ('$id', 'status', $(now( mpSim )), '$reason')"
    SQLite.execute!( mpSim.simDB, command )

    # Add the person's retirement event to the transition database.
    retEvents = "('$id', $(now( mpSim )), '$reason', '" .*
        personInStates .* "')"
    command = "INSERT INTO $(mpSim.transitionDBname)
        ($(mpSim.idKey), timeIndex, transition, startState) VALUES
        $(join( retEvents, ", " ))"
    SQLite.execute!( mpSim.simDB, command )

end  # retirePerson( mpSim, id, reason )

function retirePersons( mpSim::ManpowerSimulation, ids::Vector{String},
    reason::String )

    if !in( reason, retirementReasons )
        error( "$reason -- unknown retirement reason." )
    end  # if !in( reason, retirementReasons )

    mpSim.personnelSize -= length( ids )
    idsInStates = ids
    personInStates = fill( "active", length( ids ) )

    for state in keys( merge( mpSim.initStateList, mpSim.otherStateList ) ),
        id in ids
        if haskey( state.inStateSince, id )
            push!( idsInStates, id )
            push!( personInStates, state.name )
        end  # if haskey( state.inStateSince, id )

        delete!( state.inStateSince, id )
        delete!( state.isLockedForTransition, id )
    end  # for state in keys( merge( ...

    # Change the person's status in the personnel database.
    command = "UPDATE $(mpSim.personnelDBname)
        SET status = '$reason', timeExited = $(now( mpSim ))
        WHERE $(mpSim.idKey) IN ('$(join( ids, "', '" ))')"
    SQLite.execute!( mpSim.simDB, command )

    # Add the person's status change to the history database.
    command = "('" .* ids .* "', 'status', $(now( mpSim )), '$reason')"
    command = "INSERT INTO $(mpSim.historyDBname)
        ($(mpSim.idKey), attribute, timeIndex, strValue) VALUES
        $(join( command, ", " ))"
    SQLite.execute!( mpSim.simDB, command )

    # Add the person's retirement event to the transition database.
    command = "('" .* idsInStates .* "', $(now( mpSim )), '$reason', '" .*
        personInStates .* "')"
    command = "INSERT INTO $(mpSim.transitionDBname)
        ($(mpSim.idKey), timeIndex, transition, startState) VALUES
        $(join( command, ", " ))"
    SQLite.execute!( mpSim.simDB, command )

end  # function retirePersons( mpSim, ids, reason )

# This function computes the person's expected retirement time and returns it.
export computeExpectedRetirementTime
function computeExpectedRetirementTime( mpSim::ManpowerSimulation,
    retScheme::Retirement, ageAtRecruitment::T1, stateRetAge::T2,
    timeEntered::T3 ) where T1 <: Real where T2 <: Real where T3 <: Real

    # Compute how long the person is in the system already. Usually 0.0.
    timeInSystem = now( mpSim ) - timeEntered

    # Compute the time left until retirement.
    retireAge = stateRetAge > 0.0 ? stateRetAge : retScheme.retireAge
    timeToRetireAge = retireAge > 0.0 ? retireAge - ageAtRecruitment -
        timeInSystem : +Inf
    timeToCareerEnd = retScheme.maxCareerLength > 0.0 ?
        retScheme.maxCareerLength - timeInSystem : +Inf
    timeToRetire = min( timeToRetireAge, timeToCareerEnd )

    if !retScheme.isEither && ( timeToRetireAge < +Inf ) &&
        ( timeToCareerEnd < +Inf )
        timeToRetire = max( timeToRetireAge, timeToCareerEnd )
    end  # if !retScheme.isEither && ...

    timeOfRetirement = now( mpSim ) + timeToRetire
    return timeOfRetirement == +Inf ? "NULL" : timeOfRetirement

end  # computeExpectedRetirementTime( mpSim, ageAtRecruitment, timeEntered )

@resumable function retireProcess( sim::Simulation, mpSim::ManpowerSimulation )

    # Immediately terminate process if there's no retirement scheme.
    # XXX Will this be needed?
    if isa( mpSim.retirementScheme, Void )
        return
    end  # if isa( mpSim.retirementScheme, Void )

    processTime = Dates.Millisecond( 0 )
    tStart = now()

    retScheme = mpSim.retirementScheme
    timeOfNextRetirement = now( sim ) - retScheme.retireOffset
    timeOfNextRetirement = floor( timeOfNextRetirement /
        retScheme.retireFreq + 1 ) * retScheme.retireFreq
    timeOfNextRetirement += retScheme.retireOffset
    priority = mpSim.phasePriorities[ :retirement ]
    queryCmd = "SELECT $(mpSim.idKey) FROM $(mpSim.personnelDBname)
        WHERE status NOT IN ('fired', 'attrition', 'retirement')
            AND expectedRetirementTime <= "

    while timeOfNextRetirement <= mpSim.simLength
        processTime += now() - tStart
        @yield( timeout( sim, timeOfNextRetirement - now( sim ),
            priority = priority ) )
        tStart = now()

        # Find list of people who should retire now.
        idsToRetire = SQLite.query( mpSim.simDB,
            queryCmd * string( now( sim ) ) )[ Symbol( mpSim.idKey ) ]
        idsToRetire = Vector{String}( idsToRetire )

        if !isempty( idsToRetire )
            retirePersons( mpSim, idsToRetire, "retirement" )
        end  # if !isempty( idsToRetire )

        timeOfNextRetirement += retScheme.retireFreq
    end  # while timeOfNextRetirement <= mpSim.simLength

    processTime += now() - tStart
    println( "Retirement process took $(processTime.value / 1000) seconds." )

end  # retireProcess( sim, mpSim )

function Base.show( io::IO, retScheme::Retirement )

    if ( retScheme.maxCareerLength == 0.0 ) && ( retScheme.retireAge == 0.0 )
        print( io, "No retirement scheme." )
        return
    end   # if ( retScheme.maxCareerLength == 0.0 ) && ...

    out = "      Retirement schedule period: $(retScheme.retireFreq)"
    out *= " (+ $(retScheme.retireOffset))"

    if retScheme.maxCareerLength > 0.0
        out *= "\n      Max career length: $(retScheme.maxCareerLength)"
    end  # if retScheme.maxCareerLength > 0

    if retScheme.retireAge > 0.0
        out *= "\n      Retirement age: $(retScheme.retireAge)"
    end  # if retScheme.maxCareerLength > 0

    if retScheme.maxCareerLength * retScheme.retireAge > 0.0
        out *= "\n      " * ( retScheme.isEither ? "Either" : "Both" )
        out *= " condition" * ( retScheme.isEither ? "" : "s" )
        out *= " must be satisfied for retirement."
    end  # if retScheme.maxCareerLength * retScheme.retireAge > 0.0

    print( io, out )

end  # Base.show( io, retScheme )


text:
"""
Module: SymbolicDiff (Symbolic Operation for Arithmetic)
"""

"""
@vars(parms...)

generate symbolic variables

Example:
@vars x y
"""

macro vars(params...)
    if length(params) == 1 && Meta.isexpr(params[1], :block)
        args = params[1].args
    else
        args = params
    end
    body = []
    xargs = []
    for x = args
        if typeof(x) == Symbol
            push!(body, Expr(:(=), esc(x), esc(Expr(:call, :symbolic, Expr(:quote, x)))))
            push!(xargs, esc(x))
        else
            push!(body, x)
        end
    end
    push!(body, Expr(:tuple, [x for x = xargs]...))
    Expr(:block, body...)
end

"""
@bind(envname, block)

Set parameter values in the block to the environment

Example:
@bind env1 x = 1.0

@bind env1 begin
    x = 1.0
    y = 2.0
end
"""

macro bind(x...)
    if length(x) == 1
        envname = :globalenv
        arg = x[1]
    elseif length(x) == 2
        envname = x[1]
        arg = x[2]
    else
        throw(ErrorException("@bind should take 1 or 2 arguments"))
    end

    vars = []
    if Meta.isexpr(arg, :block)
        body = [_parameter(x, envname, vars) for x = arg.args]
        expr = Expr(:block, body...)
    else
        expr = _parameter(arg, envname, vars)
    end

    unique!(vars)
    esc(Expr(:block,
        expr,
        [Expr(:(=), x, Expr(:call, :symbolic, Expr(:quote, x))) for x = vars]...,
        Expr(:tuple, vars...)
        ))
end

function _parameter(x::Any, envname, vars)
    x
end

function _parameter(x::Symbol, envname, vars)
    push!(vars, x)
    nothing
end

function _parameter(x::Expr, envname, vars)
    if Meta.isexpr(x, :(=))
        var = x.args[1]
        push!(vars, var)
        val = x.args[2]
        :($(envname)[$(Expr(:quote, var))] = $(val))
    else
        throw(ErrorException("invalid expression for @bind."))
    end
end

"""
@expr x

Make SymbolicExpression

Example:
f = @expr x^2 + y
"""

macro expr(x)
    esc(_genexpr(x))
end

function _genexpr(x)
    if Meta.isexpr(x, :vect)
        Expr(:vect, [_genexpr(u) for u = x.args]...)
    elseif Meta.isexpr(x, :vcat)
        Expr(:vcat, [_genexpr(u) for u = x.args]...)
    elseif Meta.isexpr(x, :row)
        Expr(:row, [_genexpr(u) for u = x.args]...)
    else
        Expr(:call, :symbolic, Expr(:quote, x))
    end
end


text:
# ---
# title: 917. Reverse Only Letters
# id: problem917
# author: Tian Jun
# date: 2020-10-31
# difficulty: Easy
# categories: String
# link: <https://leetcode.com/problems/reverse-only-letters/description/>
# hidden: true
# ---
#
# Given a string `S`, return the "reversed" string where all characters that are
# not a letter stay in the same place, and all letters reverse their positions.
#
#
#
# **Example 1:**
#
#
#
#     Input: "ab-cd"
#     Output: "dc-ba"
#
#
# **Example 2:**
#
#
#
#     Input: "a-bC-dEf-ghIj"
#     Output: "j-Ih-gfE-dCba"
#
#
# **Example 3:**
#
#
#
#     Input: "Test1ng-Leet=code-Q!"
#     Output: "Qedo1ct-eeLg=ntse-T!"
#
#
#
#
# **Note:**
#
#   1. `S.length <= 100`
#   2. `33 <= S[i].ASCIIcode <= 122`
#   3. `S` doesn't contain `\` or `"`
#
#
## @lc code=start
using LeetCode

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


text: square(x) = exit(1)


text:
struct DecisionCoefficientChange{T} <: MOI.AbstractFunctionModification
    decision::MOI.VariableIndex
    new_coefficient::T
end

struct DecisionMultirowChange{T} <: MOI.AbstractFunctionModification
    decision::MOI.VariableIndex
    new_coefficients::Vector{Tuple{Int64, T}}
end

struct KnownCoefficientChange{T} <: MOI.AbstractFunctionModification
    known::MOI.VariableIndex
    new_coefficient::T
end

struct KnownMultirowChange{T} <: MOI.AbstractFunctionModification
    known::MOI.VariableIndex
    new_coefficients::Vector{Tuple{Int64, T}}
end

struct DecisionStateChange{T} <: MOI.AbstractFunctionModification
    decision::MOI.VariableIndex
    new_state::DecisionState
    value_difference::T
end

struct DecisionsStateChange <: MOI.AbstractFunctionModification end

struct KnownValueChange{T} <: MOI.AbstractFunctionModification
    known::MOI.VariableIndex
    value_difference::T
end

struct KnownValuesChange <: MOI.AbstractFunctionModification end

const DecisionModification = Union{DecisionCoefficientChange, DecisionStateChange, DecisionsStateChange}
const VectorDecisionModification = Union{DecisionMultirowChange, DecisionStateChange, DecisionsStateChange}
const KnownModification = Union{KnownCoefficientChange, KnownValueChange, KnownValuesChange}
const VectorKnownModification = Union{KnownMultirowChange, KnownValueChange, KnownValuesChange}


text:
__precompile__()
module AutoDiffSource

export @δ, δ, checkdiff, checkgrad

export δplus, δminus, δtimes, δdivide, δabs, δsum, δmean, δsqrt, δexp, δlog, δpower, δdot
export δdot_plus, δdot_minus, δdot_times, δdot_divide, δdot_abs, δdot_sqrt, δdot_exp, δdot_log, δdot_power
export δplus_const1, δminus_const1, δtimes_const1, δdivide_const1, δpower_const1
export δdot_plus_const1, δdot_minus_const1, δdot_times_const1, δdot_divide_const1, δdot_power_const1
export δplus_const2, δminus_const2, δtimes_const2, δdivide_const2, δpower_const2
export δdot_plus_const2, δdot_minus_const2, δdot_times_const2, δdot_divide_const2, δdot_power_const2
export δfanout, δzeros, δzeros_const, δones_const, δlength_const, δcolon_const, δref_const2, δtuple
export δsrand_const, δrand_const, δrandn_const, δsize_const, δsign_const

export δlog1p, δexpm1, δsin, δcos, δtan, δsinh, δcosh, δtanh, δasin, δacos, δatan
export δround_const, δfloor_const, δceil_const, δtrunc_const, δmod2pi, δmaximum, δminimum, δtranspose
export δerf, δerfc, δgamma, δlgamma, δmin, δmax, δmin_const1, δmax_const1, δmin_const2, δmax_const2

export δdot_min, δdot_max, δdot_min_const1, δdot_max_const1, δdot_min_const2, δdot_max_const2
export δmulticast, δmulticast_const1, δmulticast_const2

if VERSION >= v"0.6-"
    using SpecialFunctions
end

include("parse.jl")
include("diff.jl")
include("func.jl")
include("checkdiff.jl")
include("multicast.jl")

macro δ(expr::Expr)
    esc(:( $expr; $(δ(macroexpand(expr)))))
end

macro δ(f::Symbol)
    fs = methods(eval(GlobalRef(Main, f)))
    length(fs) >  0 || error("function '$f' not found")
    expr = Expr(:block)
    for fdef in fs.ms
        fn = VERSION >= v"0.6.0-" ? Base.uncompressed_ast(fdef, fdef.source).code : Base.uncompressed_ast(fdef.lambda_template)
        fcode = fn[2:end]
        info = Expr(:line, fdef.line, fdef.file)
        types = getfield(fdef.sig, 3)
        fargs = [Expr(:(::), Symbol("_$i"), types[i]) for i in 2:length(types)]
        fname = Symbol(string(f))
        func = :(function $fname($(fargs...)); end)
        body = func.args[2].args
        empty!(body)
        foreach(arg -> push!(body, arg), fcode)
        push!(expr.args, δ(func, info))
    end
    esc(expr)
end

function δ(expr, info = Expr(:line))
    ops = parse_function(expr, info)
    for op in ops.body
        name = replace(string(op.name), r"^\.", "")
        if !isdefined(Symbol("δ$name")) && !isdefined(Symbol("δ$(name)_const"))
            eval(Main, :(@δ $(Symbol(name))))
        end
    end

    ex = Expr(:block)
    push!(ex.args, delta(ops))
    ins = filter(isvar, ops.inputs)
    if length(ins) > 1
        for name in ins
            if isa(name, Expr)
                name = name.args[1]
            end
            op = parse_function(expr, info, Dict{Symbol,Symbol}(name => Symbol(string(name) * "_const")))
            push!(ex.args, delta(op))
        end
        if length(ins) > 2
            for name1 in ins
                if isa(name1, Expr)
                    name1 = name1.args[1]
                end
                for name2 in ins
                    if isa(name2, Expr)
                        name2 = name2.args[1]
                    end
                    if name2 > name1
                        op = parse_function(expr, info, Dict{Symbol,Symbol}(name1 => Symbol(string(name1) * "_const"),
                                                                            name2 => Symbol(string(name2) * "_const")))
                        push!(ex.args, delta(op))
                    end
                end
            end
        end
    end
    ex
end

end


text:
@testset "2D Geometry" begin

    c = Square([1,2])
    HyperRectangle(c)

end


text:
function _unpackdensematrix!(A::GBVecOrMat{T}; desc = nothing) where {T}
    desc = _handledescriptor(desc)
    Csize = Ref{libgb.GrB_Index}(length(A) * sizeof(T))
    values = Ref{Ptr{Cvoid}}(Ptr{T}())
    isiso = Ref{Bool}(false)
    libgb.GxB_Matrix_unpack_FullC(
        A.p,
        values,
        Csize,
        isiso,
        desc
    )
    return unsafe_wrap(Array{T}, Ptr{T}(values[]), size(A))
end

function _unpackcscmatrix!(A::GBVecOrMat{T}; desc = nothing) where {T}
    desc = _handledescriptor(desc)
    colptr = Ref{Ptr{libgb.GrB_Index}}()
    rowidx = Ref{Ptr{libgb.GrB_Index}}()
    values = Ref{Ptr{Cvoid}}(Ptr{T}())
    colptrsize = Ref{libgb.GrB_Index}()
    rowidxsize = Ref{libgb.GrB_Index}()
    valsize = Ref{libgb.GrB_Index}()
    isiso = Ref{Bool}(false)
    isjumbled = Ref{Bool}(false)
    libgb.GxB_Matrix_unpack_CSC(
        A.p,
        colptr,
        rowidx,
        values,
        colptrsize,
        rowidxsize,
        valsize,
        isiso,
        isjumbled,
        desc
    )
    colptr = unsafe_wrap(Array{libgb.GrB_Index}, colptr[], colptrsize[] ÷ sizeof(libgb.GrB_Index))
    rowidx = unsafe_wrap(Array{libgb.GrB_Index}, rowidx[], rowidxsize[] ÷ sizeof(libgb.GrB_Index))
    colptr .+= 1
    rowidx .+= 1
    return colptr,
    rowidx,
    unsafe_wrap(Array{T}, Ptr{T}(values[]), valsize[] ÷ sizeof(T))
end

function _unpackcsrmatrix!(A::GBVecOrMat{T}; desc = nothing) where {T}
    desc = _handledescriptor(desc)
    rowptr = Ref{Ptr{libgb.GrB_Index}}()
    colidx = Ref{Ptr{libgb.GrB_Index}}()
    values = Ref{Ptr{Cvoid}}(Ptr{T}())
    colidxsize = Ref{libgb.GrB_Index}()
    rowptrsize = Ref{libgb.GrB_Index}()
    valsize = Ref{libgb.GrB_Index}()
    isiso = Ref{Bool}(false)
    isjumbled = Ref{Bool}(false)
    libgb.GxB_Matrix_unpack_CSR(
        A.p,
        rowptr,
        colidx,
        values,
        rowptrsize,
        colidxsize,
        valsize,
        isiso,
        isjumbled,
        desc
    )
    rowptr = unsafe_wrap(Array{libgb.GrB_Index}, rowptr[], rowptrsize[] ÷ sizeof(libgb.GrB_Index))
    colidx = unsafe_wrap(Array{libgb.GrB_Index}, colidx[], colidxsize[] ÷ sizeof(libgb.GrB_Index))
    rowptr .+= 1
    colidx .+= 1
    return rowptr,
    colidx,
    unsafe_wrap(Array{T}, Ptr{T}(values[]), valsize[] ÷ sizeof(T))
end


text:
#= Benchmarks

Test how much the recalculation of coordinates and dim types
costs over standard getindex/view.

Indexing with Y(1) has no overhead at all, but ranges
have an overhead for slicing the dimensions.
=#

g = DimensionalArray(rand(100, 50), (X(51:150), Y(-40:9)))

println("\n\nPerformance of view()\n")
vi1(g) = view(parent(g), 1, 2)
vd1(g) = view(g, X(1), Y(2))
vi2(g) = view(parent(g), :, :)
vd2(g) = view(g, X(:), Y(:))
vi3(g) = view(parent(g), 10:40, 1:20)
vd3(g) = view(g, X(10:40), Y(1:20))

println("Parent indices with Number")
@btime vi1($g)
println("Dims with Number")
@btime vd1($g)
println()
println("Parent indices with Colon")
@btime vi2($g);
println("Dims with Colon")
@btime vd2($g);
println()
println("Parent indices with UnitRange")
@btime vi3($g);
println("Dims with UnitRange")
@btime vd3($g);

println("\n\nPerformance of getindex()\n")
i1(g) = parent(g)[10, 20]
d1(g) = g[Y(10), X(20)]
i2(g) = parent(g)[:, :]
d2(g) = g[Y(:), X(:)]
i3(g) = parent(g)[1:20, 10:40]
d3(g) = g[Y(1:20), X(10:40)]

println("Parent indices with Number")
@btime i1($g)
println("Dims with Number")
@btime d1($g)
println()
println("Parent indices with Colon")
@btime i2($g)
println("Dims with Colon")
@btime d2($g)
println()
println("Parent indices with UnitRange")
@btime i3($g)
println("Dims with UnitRange")
@btime d3($g);

a = rand(5, 4, 3);
da = DimensionalArray(a, (Y((1u"m", 5u"m")), X(1:4), Time(1:3)))
dimz = dims(da)

if VERSION > v"1.1-"
    println("\n\neachslice: normal, numbers + rebuild, dims + rebuild")
    @btime (() -> eachslice($a; dims=2))();
    @btime (() -> eachslice($da; dims=2))();
    @btime (() -> eachslice($da; dims=Y))();
    println("eachslice to vector: normal, numbers + rebuild, dims + rebuild")
    @btime [slice for slice in eachslice($a; dims=2)];
    @btime [slice for slice in eachslice($da; dims=2)];
    @btime [slice for slice in eachslice($da; dims=X)];
    @test [slice for slice in eachslice(da; dims=1)] == [slice for slice in eachslice(da; dims=Y)]
end

println("\n\nmean: normal, numbers + rebuild, dims + rebuild")
@btime mean($a; dims=2);
@btime mean($da; dims=2);
@btime mean($da; dims=X);
println("permutedims: normal, numbers + rebuild, dims + rebuild")
@btime permutedims($a, (2, 1, 3))
@btime permutedims($da, (2, 1, 3))
@btime permutedims($da, (Y(), X(), Time()))
println("reverse: normal, numbers + rebuild, dims + rebuild")
@btime reverse($a; dims=1)
@btime reverse($da; dims=1)
@btime reverse($da; dims=Y)


text:
#! /usr/bin/julia

# Rosetta Code, Hofstadter Figure-Figure sequences

type FigureFigure{T<:Integer}
    r::Array{T,1}
    rnmax::T
    snmax::T
    snext::T
end

function grow!{T<:Integer}(ff::FigureFigure{T}, rnmax::T=100)
    ff.rnmax < rnmax || return nothing
    append!(ff.r, zeros(T, (rnmax-ff.rnmax)))
    snext = ff.snext
    for i in (ff.rnmax+1):rnmax
        ff.r[i] = ff.r[i-1] + snext
        snext += 1
        while snext in ff.r
            snext += 1
        end
    end
    ff.rnmax = rnmax
    ff.snmax = ff.r[end] - rnmax
    ff.snext = snext
    return nothing
end

function FigureFigure{T<:Integer}(rnmax::T=10)
    ff = FigureFigure([1], 1, 0, 2)
    grow!(ff, rnmax)
    return ff
end

function FigureFigure{T<:Integer}(rnmax::T, snmax::T)
    ff = FigureFigure(rnmax)
    while ff.snmax < snmax
        grow!(ff, 2ff.rnmax)
    end
    return ff
end

function make_ffr{T<:Integer}(nmax::T=10)
    ff = FigureFigure(nmax)
    function ffr{T<:Integer}(n::T)
        if n > ff.rnmax
            grow!(ff, 2n)
        end
        ff.r[n]
    end
end

function make_ffs{T<:Integer}(nmax::T=100)
    ff = FigureFigure(13, nmax)
    function ffs{T<:Integer}(n::T)
        while ff.snmax < n
            grow!(ff, 2ff.rnmax)
        end
        s = n
        for r in ff.r
            r <= s || return s
            s += 1
        end
    end
end

NR = 40
NS = 960
ffr = make_ffr(NR)
ffs = make_ffs(NS)

hi = 10
print("The first ", hi, " values of R are:\n    ")
for i in 1:hi
    print(ffr(i), "  ")
end
println()

tally = falses(NR+NS)
iscontained = true
for i in 1:NR
    try
        tally[ffr(i)] = true
    catch
        iscontained = false
    end
end
for i in 1:NS
    try
        tally[ffs(i)] = true
    catch
        iscontained = false
    end
end

println()
print("The first ", NR, " values of R and ", NS, " of S are ")
if !iscontained
    print("not ")
end
println("contained in the interval 1:", NR+NS, ".")
print("These values ")
if !all(tally)
    print("do not ")
end
println("cover the entire interval.")

max_stars_repo_name: MichaeLeroy/rosetta-code

max_issues_repo_name: MichaeLeroy/rosetta-code

max_forks_repo_name: MichaeLeroy/rosetta-code


text:
export IndGraph

abstract type IndGraph <: ProximableFunction end

"""
**Indicator of the graph of a linear operator**

    IndGraph(A)

For matrix `A` (dense or sparse) returns the indicator function of the set
```math
G_A = \\{(x, y) : Ax = y\\}.
```
The evaluation of `prox!` uses direct methods based on LDLt (LL for dense cases) matrix factorization and backsolve.

The `prox!` method operates on pairs `(x, y)` as input/output. So if `f = IndGraph(A)` is the indicator of the graph ``G_A``,
while `(x, y)` and `(c, d)` are pairs of vectors of the same sizes, then
```
prox!((c, d), f, (x, y))
```
writes to `(c, d)` the projection onto ``G_A`` of `(x, y)`.
"""
function IndGraph(A::AbstractArray{T,2}) where {T <: RealOrComplex}
  if issparse(A)
    IndGraphSparse(A)
  elseif size(A, 1) > size(A, 2)
    IndGraphSkinny(A)
  else
    IndGraphFat(A)
  end
end

is_convex(f::IndGraph) = true
is_set(f::IndGraph) = true
is_cone(f::IndGraph) = true

IndGraph(a::AbstractArray{T,1}) where {T <: RealOrComplex} =
  IndGraph{T}(a')

# fun_name(f::IndGraph) = "Indicator of an operator graph"
fun_dom(f::IndGraph) = "AbstractArray{Real,1}, AbstractArray{Complex,1}"
fun_expr(f::IndGraph) = "x,y ↦ 0 if Ax = y, +∞ otherwise"
fun_params(f::IndGraph) =
  string( "A = ", typeof(f.A), " of size ", size(f.A))

# Auxiliary function to be used in fused input call
function splitinput(f::IndGraph, xy::AbstractVector{T}) where
    {T <: RealOrComplex}
  @assert length(xy) == f.m + f.n
  x = view(xy, 1:f.n)
  y = view(xy, (f.n + 1):(f.n + f.m))
  return x, y
end

# prox! additional signature
function prox!(
    xy::AbstractVector{T},
    f::IndGraph,
    cd::AbstractVector{T},
    gamma=1.0) where
  {T<:RealOrComplex}
 x, y = splitinput(f, xy)
 c, d = splitinput(f, cd)
 prox!(x, y, f, c, d)
 return 0.0
end

prox!(
    xy::Tuple{AbstractVector{T1}, AbstractVector{T2}},
    f::IndGraph,
    cd::Tuple{AbstractVector{T1}, AbstractVector{T2}},
    gamma=1.0) where
  {T1<:RealOrComplex, T2<:RealOrComplex} = prox!(xy[1], xy[2], f, cd[1], cd[2])

# prox_naive additional signatures
function prox_naive(
    f::IndGraph,
    cd::AbstractVector{T},
    gamma=1.0) where
  {T<:RealOrComplex}
 c, d = splitinput(f, cd)
 x, y, f = prox_naive(f, c, d, gamma)
 return [x;y], f
end

function prox_naive(
    f::IndGraph,
    cd::Tuple{AbstractVector{T1}, AbstractVector{T2}},
    gamma=1.0) where
  {T1<:RealOrComplex, T2<:RealOrComplex}

  x, y, fv = prox_naive(f, cd[1], cd[2], gamma)
  return (x, y), fv
end

include("indGraphSparse.jl")
include("indGraphFat.jl")
include("indGraphSkinny.jl")


text:
using Koala
using KoalaElasticNet
using Base.Test

# Load some data and define train/test rows:
const X, y = load_ames();
y = log.(y)

const train, test = split(eachindex(y), 0.7); # 70:30 split

# Instantiate a model:
elastic = ElasticNetRegressor(lambda_min_ratio=1e-9)
showall(elastic)

# Change the default transformer behaviour to include Box-Cox
# transformations on input features:
tX = default_transformer_X(elastic)
showall(tX)
tX.boxcox = true

# Build a machine that uses the modified transformer:
elasticM = Machine(elastic, X, y, train, transformer_X=tX, verbosity=3)

# Train the model:
fit!(elasticM, train)
showall(elasticM)

rpt = elasticM.report

m = rpt[:loglambdaopt]
delta = rpt[:loglambdaopt_stde]
lambdas = exp.(linspace(m - delta, m + delta, 10))

# choose range for l1/l2 ratio:
alphas = linspace(0.8,1.0,15)

# tune using cross-validation
alphas, lambdas, rmserrors = @curve α alphas λ lambdas begin
    elastic.alpha, elastic.lambda = α, λ
    mean(cv(elasticM, train, parallel=true, n_folds=9, verbosity=0))
end

# set regularization parameters to optimal values:
j, k = ind2sub(size(rmserrors), indmin(rmserrors))
elastic.alpha, elastic.lambda = alphas[j], lambdas[k]

# retrain:
fit!(elasticM)

# report score:
score = err(elasticM, test)
@test score < 0.14 && score >0.12