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

import Dates

import ..isvalid_barekey_char

function printkey(io::IO, keys::Vector{String})
    for (i, k) in enumerate(keys)
        i != 1 && Base.print(io, ".")
        if length(k) == 0
            # empty key
            Base.print(io, "\"\"")
        elseif any(!isvalid_barekey_char, k)
            # quoted key
            Base.print(io, "\"", escape_string(k) ,"\"")
        else
            Base.print(io, k)
        end
    end
end

const MbyFunc = Union{Function, Nothing}
const TOMLValue = Union{AbstractVector, AbstractDict, Dates.DateTime, Dates.Time, Dates.Date, Bool, Integer, AbstractFloat, String}
function printvalue(f::MbyFunc, io::IO, value::AbstractVector; sorted=false)
    Base.print(io, "[")
    for (i, x) in enumerate(value)
        i != 1 && Base.print(io, ", ")
        if isa(x, AbstractDict)
            _print(f, io, x; sorted)
        else
            printvalue(f, io, x; sorted)
        end
    end
    Base.print(io, "]")
end
function printvalue(f::MbyFunc, io::IO, value; sorted)
    if f === nothing
        error("type `$(typeof(value))` is not a valid TOML type, pass a conversion function to `TOML.print`")
    end
    toml_value = f(value)
    if !(toml_value isa TOMLValue)
        error("TOML syntax function for type `$(typeof(value))` did not return a valid TOML type but a `$(typeof(toml_value))`")
    end
    Base.invokelatest(printvalue, f, io, toml_value; sorted)
end
printvalue(f::MbyFunc, io::IO, value::AbstractDict; sorted) =
    _print(f, io, value; sorted)
printvalue(f::MbyFunc, io::IO, value::Dates.DateTime; sorted) =
    Base.print(io, Dates.format(value, Dates.dateformat"YYYY-mm-dd\THH:MM:SS.sss\Z"))
printvalue(f::MbyFunc, io::IO, value::Dates.Time; sorted) =
    Base.print(io, Dates.format(value, Dates.dateformat"HH:MM:SS.sss"))
printvalue(f::MbyFunc, io::IO, value::Dates.Date; sorted) =
    Base.print(io, Dates.format(value, Dates.dateformat"YYYY-mm-dd"))
printvalue(f::MbyFunc, io::IO, value::Bool; sorted) =
    Base.print(io, value ? "true" : "false")
printvalue(f::MbyFunc, io::IO, value::Integer; sorted) =
    Base.print(io, Int64(value))  # TOML specifies 64-bit signed long range for integer
printvalue(f::MbyFunc, io::IO, value::AbstractFloat; sorted) =
    Base.print(io, isnan(value) ? "nan" :
                   isinf(value) ? string(value > 0 ? "+" : "-", "inf") :
                   Float64(value))  # TOML specifies IEEE 754 binary64 for float
printvalue(f::MbyFunc, io::IO, value::AbstractString; sorted) = Base.print(io, "\"", escape_string(value), "\"")

is_table(value)           = isa(value, AbstractDict)
is_array_of_tables(value) = isa(value, AbstractArray) &&
                            length(value) > 0 && isa(value[1], AbstractDict)
is_tabular(value)         = is_table(value) || is_array_of_tables(value)

function _print(f::MbyFunc, io::IO, a::AbstractDict,
    ks::Vector{String} = String[];
    indent::Int = 0,
    first_block::Bool = true,
    sorted::Bool,
    by::Function,
)
    akeys = keys(a)
    if sorted
        akeys = sort!(collect(akeys); by)
    end

    # First print non-tabular entries
    for key in akeys
        value = a[key]
        is_tabular(value) && continue
        Base.print(io, ' '^4max(0,indent-1))
        printkey(io, [String(key)])
        Base.print(io, " = ") # print separator
        printvalue(f, io, value; sorted)
        Base.print(io, "\n")  # new line?
        first_block = false
    end

    for key in akeys
        value = a[key]
        if is_table(value)
            push!(ks, String(key))
            header = !all(is_tabular(v) for v in values(value))::Bool
            if header
                # print table
                first_block || println(io)
                first_block = false
                Base.print(io, ' '^4indent)
                Base.print(io,"[")
                printkey(io, ks)
                Base.print(io,"]\n")
            end
            # Use runtime dispatch here since the type of value seems not to be enforced other than as AbstractDict
            Base.invokelatest(_print, f, io, value, ks; indent = indent + header, first_block = header, sorted, by)
            pop!(ks)
        elseif is_array_of_tables(value)
            # print array of tables
            first_block || println(io)
            first_block = false
            push!(ks, String(key))
            for v in value
                Base.print(io, ' '^4indent)
                Base.print(io,"[[")
                printkey(io, ks)
                Base.print(io,"]]\n")
                # TODO, nicer error here
                !isa(v, AbstractDict) && error("array should contain only tables")
                Base.invokelatest(_print, f, io, v, ks; indent = indent + 1, sorted, by)
            end
            pop!(ks)
        end
    end
end

print(f::MbyFunc, io::IO, a::AbstractDict; sorted::Bool=false, by=identity) = _print(f, io, a; sorted, by)
print(f::MbyFunc, a::AbstractDict; sorted::Bool=false, by=identity) = print(f, stdout, a; sorted, by)
print(io::IO, a::AbstractDict; sorted::Bool=false, by=identity) = _print(nothing, io, a; sorted, by)
print(a::AbstractDict; sorted::Bool=false, by=identity) = print(nothing, stdout, a; sorted, by)

max_stars_repo_name: vanillajonathan/julia

max_issues_repo_name: vanillajonathan/julia

max_forks_repo_name: vanillajonathan/julia


text:
"""
Delegates loading of code with functions and parameters specific to different instruments.
Subdirectories of src/instruments include provide functions specialized for each instrument,
typically the file I/O and pre-processing, so data ends up in a common format.
src/instruments/common.jl provides routines that can be shared by instruments.
"""
module EchelleInstruments

using RvSpectMLBase
using DataFrames, CSV, Query
using FITSIO

import RvSpectMLBase: default_ccf_mask_v_width  # So this function can be overriden for each instrument

include("common.jl")   # Mostly trait functions to be specialized by instruments
#function get_inst_module end

include("files.jl")
export make_manifest, read_manifest, write_manifest

include("io.jl")
export  read_metadata_from_fits, read_fits_header
# don't export read_header due to conflict with FITSIO

include("util.jl")
# TODO: Decide what to export from util.jl
#export add_line_boundaries_to_line_list, expand_line_boundaries_in_line_list  # moved to RvSpectMLBase

include("expres/expres.jl")
import .EXPRES: EXPRES1D, EXPRES2D, AnyEXPRES #, get_inst_module
#import .EXPRES: get_inst_module, filter_line_list, find_worst_telluric_in_each_chunk
export EXPRES, EXPRES1D, EXPRES2D, AnyEXPRES

include("harps-n/harps-n.jl")
export HARPSN, HARPSN1D, HARPSN2D, AnyHARPSN
import .HARPSN: HARPSN1D, HARPSN2D, AnyHARPSN #, get_inst_module
#=
#import .HARPSN: get_inst_module, filter_line_list, find_worst_telluric_in_each_chunk
=#

include("harps/harps.jl")
export HARPS, HARPS1D, HARPS2D, AnyHARPS
import .HARPS: HARPS1D, HARPS2D, AnyHARPS #, get_inst_module
#=
#import .HARPSN: get_inst_module, filter_line_list, find_worst_telluric_in_each_chunk
=#

include("hpf/hpf.jl")
export HPF, HPF1D, HPF2D, AnyHPF
import .HPF: HPF1D, HPF2D, AnyHPF #, get_inst_module
#=
#import .HPF: get_inst_module, filter_line_list, find_worst_telluric_in_each_chunk
=#

include("neid/neid.jl")
import .NEID: NEID1D, NEID2D, AnyNEID
#import .NEID: get_inst_module, filter_line_list #, find_worst_telluric_in_each_chunk
export NEID, NEID1D, NEID2D, AnyNEID

# TODO: Add more instruments:  HARPS-N, HPF, etc.

end

ext: jl

max_stars_repo_name: RvSpectML/EchelleInstruments

max_issues_repo_name: RvSpectML/EchelleInstruments

max_forks_repo_name: RvSpectML/EchelleInstruments


text:
# advent of code 2020 day 1

function load_data(path:: String):: AbstractArray
    file = open(path)
    data_array = readlines(file)
    close(file)
    # cast string to integer
    parse.(Int, data_array)
end

function find_sum_of_2(data_array:: AbstractArray, sum_to_find:: Int)
    length_data_array = length(data_array)
    for (i, d_1) in enumerate(data_array)
        for d_2 in data_array[i:length_data_array]
            _sum = d_1 + d_2
            if _sum == sum_to_find
                return d_1, d_2
            end

        end
    end

end

function find_sum_of_3(data_array:: AbstractArray, sum_to_find:: Int)
    length_data_array = length(data_array)
    for (i, d_1) in enumerate(data_array)
        for (j, d_2) in enumerate(data_array[i:length_data_array])
            for d_3 in data_array[j:length_data_array]

                _sum = d_1 + d_2 + d_3
                if _sum == sum_to_find
                    return d_1, d_2, d_3
                end
            end

        end
    end

end

data_array = load_data("./data/day1.txt")

sum_to_find = 2020

numbers = find_sum_of_2(data_array, sum_to_find)
numbers_product = prod(numbers)

println("results of 2: $numbers_product")

numbers = find_sum_of_3(data_array, sum_to_find)
numbers_product = prod(numbers)

println("results of 3: $numbers_product")


text:
function derivative{T}(s::Spline{T})
	nSplines = length(s.a)

	sDeriv = deepcopy(s)
	for i in 1:nSplines
		sDeriv.values[i] = sDeriv.b[i]
		sDeriv.a[i] = sDeriv.b[i]
		sDeriv.b[i] = sDeriv.c[i]*2
		sDeriv.c[i] = sDeriv.d[i]*3
		sDeriv.d[i] = 0
	end
	sDeriv.values[nSplines+1] = @evalpoly(s.knots[nSplines+1]-s.knots[nSplines], sDeriv.a[end], sDeriv.b[end], sDeriv.c[end], sDeriv.d[end]) #TODO: not tested

	return sDeriv
end

function derivative2{T}(s::Spline{T})
	nSplines = length(s.a)
	sDeriv = deepcopy(s)
	for i in 1:nSplines
		sDeriv.a[i] = sDeriv.c[i]*2
		sDeriv.b[i] = sDeriv.d[i]*6
		sDeriv.c[i] = zero(T)
		sDeriv.d[i] = zero(T)
	end
	sDeriv.values[nSplines+1] = 0
	return sDeriv
end

function derivative{T}(s::Spline{T}, x::T)
	if !indomain(s, x)
		throw(DomainError())
	end

	xpos = findlast(a->x>a, s.knots)

	return @evalpoly(x-s.knots[xpos], s.b[xpos], 2*s.c[xpos], sqrt(3)*s.d[xpos])
end

"""Compute the maximum absolute value of the second derivative of s"""
function maxabs2deriv(s::Spline)
	maxA2D = sum = 0
	for i in 1:length(s.knots)-1
		maxA2D = max(maxA2D, abs(sum += (2*s.c[i]+6*s.d[i]*(s.knots[i+1]-s.knots[i]))))
	end

	return maxA2D
end

function integral{T}(s::Spline{T}, a::T, b::T)
  if !indomain(s, a) || !indomain(s, b)
    throw(DomainError())
  end
  if b < a
    return -1*integral(s, b, a)
  end
  if b == a
    return zero(T)
  end

  startknot = findlast(x->x<=a, s.knots)
  endknot = findlast(x->x<b, s.knots)

	if startknot == endknot
		integral_val = integrate_cubic(a-s.knots[startknot], b-s.knots[startknot], s.a[startknot], s.b[startknot], s.c[startknot], s.d[startknot])
	else
  	integral_val = zero(T)
  	for knot in startknot:endknot
    	integral_val += integrate_cubic(0.0, s.knots[knot+1]-s.knots[knot], s.a[knot], s.b[knot], s.c[knot], s.d[knot])
  	end
  	integral_val -= integrate_cubic(0.0, a-s.knots[startknot], s.a[startknot], s.b[startknot], s.c[startknot], s.d[startknot])
  	integral_val -= integrate_cubic(b-s.knots[endknot], s.knots[endknot+1]-s.knots[endknot], s.a[endknot], s.b[endknot], s.c[endknot], s.d[endknot])
	end

  return integral_val
end

function integral_squared{T}(s::Spline{T}, a::T, b::T)
	return integral(s^2, a, b)
end

export derivative
export derivative2
export maxabs2deriv
export integral
export integral_squared


text:
using PyCall
using Plots
using LinearAlgebra
using Printf
using Revise
using fci

#n = 500
#m = 12
#before = rand(Float64, (n,n))
#matrix = Symmetric(before)
#Tm, V = lanczos(matrix, rand(Float64, n),m)

function lanczos(matrix, b, m=12)
    #initalize empty matrices for T and V
    T = zeros(Float64, m+1, m)
    V = zeros(Float64, size(matrix)[1], m+1)
    #normalize start vector
    V[:,1] = b/norm(b)
    #next vector
    w = matrix*V[:,1]
    #orthogonalise
    T[1,1] = dot(w,V[:,1])
    w = w - T[1,1]*V[:,1]
    #normalze next vector
    T[2,1] = norm(w)
    V[:,2] = w/T[2,1]
    print("B values: trying \n")
    for j = 2:m
        #make T symmetric
        println(T[j, j-1])

        T[j-1, j] = T[j, j-1]

        #next vector
        w = matrix*V[:,j]
        #orthogonalise agaisnt two previous vectors
        T[j,j] = dot(w,V[:, j])
        # below is like this w_3 = w_3 - a_2 |v_2> - b_2 |v_1>
        w = w - dot(w,V[:,j])*V[:,j] - T[j-1, j]*V[:, j-1] #subtract projection on v_j and v_(j-1)

        # note: <v_2 | H | v_0> = 0 so only have to subtract two previous vectors for othogonalization
        # that is what is being checked below
        #if j > 3
        #    value = dot(w, V[:,j-2])
        #    println("\n overlap with diff >1: ", value)
        #end

        #normalize
        T[j+1, j] = norm(w)
        V[:,j+1] = w/T[j+1, j]

        #convergence check
        if T[j+1, j] < 10E-8
            @printf("\n\nConverged at %i iteration \n", j)
            print("\n", T[j+1, j])
            Tm = T[1:j, 1:j]
            return Tm, V
            break
        end
    end

    #make T into symmetric matrix of shape (m,m)
    Tm = T[1:m, 1:m]
    return Tm, V
end
#={{{=#
#n = ARGS[1]
#m = ARGS[2]
#before = rand(Float64, (n,n))
#matrix = Symmetric(before)
#Tm, V = lanczos(matrix, rand(Float64, n),m)
#println("\nTm matrix from Lanczos:")
#Tm}}}

max_stars_repo_name: nbraunsc/fci

max_issues_repo_name: nbraunsc/fci

max_forks_repo_name: nbraunsc/fci


text:
module Maybes

using Foldable, Functor, Funs, Monad

import Base.show
import Base.eltype, Base.==
import Base.serialize, Base.deserialize
import Base.length, Base.start, Base.next, Base.done, Base.isempty
import Foldable.freduce
import Functor.fmap
import Monad.tycon, Monad.valtype
import Monad.munit, Monad.mjoin, Monad.mbind, Monad.mzero, Monad.mplus

export Maybe
export just
export isjust, isnothing
export maybe, fromjust, frommaybe
export arrayToMaybe, maybeToArray
export catMaybes, mapMaybe
export show
export eltype, ==
export serialize, deserialize
export length, start, next, done, isempty
export freduce
export fmap
export tycon, valtype
export munit, mjoin, mbind, mzero, mplus

immutable Maybe{T}
    isjust::Bool
    value::T
    Maybe() = new(false)
    Maybe(value) = new(true,value)
end
just{T}(value::T) = Maybe{T}(value)

isjust(m::Maybe) = m.isjust
isnothing(m::Maybe) = !isjust(m)

maybe{T}(zero, f::Callable, m::Maybe{T}; R::Type=eltype(f)) =
    isjust(m) ? f(m.value)::R : zero::R

fromjust(m::Maybe) = (@assert isjust(m); m.value)
frommaybe{T}(zero, m::Maybe{T}) = isjust(m) ? m.value : zero::T

arrayToMaybe{T}(xs::Array{T,1}) = isempty(xs) ? Maybe{T}() : just(xs[1])
maybeToArray{T}(m::Maybe{T}) = isnothing(m) ? T[] : T[m.value]

function catMaybes{T}(xs::Array{Maybe{T},1})
    rs = T[]
    for x in xs
        maybe(rs, (r->push!(rs,r)), x)
    end
    rs
end

function mapMaybe{MT}(f::Callable, xs::Array{MT,1}; R::Type=eltype(f))
    rs = R[]
    for x in xs
        maybe(rs, r->push!(rs, f(r)), x)
    end
    rs
end

show(io::IO, m::Maybe) = print(io, maybe("(?)", v->"(?$v)", m))

eltype{T}(m::Maybe{T}) = T

function =={T}(m1::Maybe{T}, m2::Maybe{T})
    if isnothing(m1) && isnothing(m2) return true end
    if isnothing(m1) || isnothing(m2) return false end
    fromjust(m1) == fromjust(m2)
end

function serialize{T}(s::AbstractSerializer, m::Maybe{T})
    Base.serialize_type(s, Maybe{T})
    write(s.io, m.isjust)
    if m.isjust
        write(s.io, fromjust(m))
    end
end
function deserialize{T}(s::AbstractSerializer, ::Type{Maybe{T}})
    isjust = read(s.io, Bool)
    if isjust
        value = read(s.io, T)
        Maybe{T}(value)
    else
        Maybe{T}()
    end
end

length(m::Maybe) = Int(isjust(m))
start(m::Maybe) = isnothing(m)
next(m::Maybe, i) = fromjust(m), true
done(m::Maybe, i) = i
isempty(m::Maybe) = isnothing(m)

@generated function freduce(op::Callable, zero, m::Maybe, ns::Maybe...;
        R::Type=eltype(op))
    quote
        tuple($([:(@assert isjust(ns[$i]) == isjust(m))
            for i in 1:length(ns)]...))
        if isnothing(m) return zero::R end
        op(zero, fromjust(m),
            $([:(fromjust(ns[$i])) for i in 1:length(ns)]...))::R
    end
end

@generated function fmap(f::Callable, m::Maybe, ns::Maybe...; R::Type=eltype(f))
    quote
        tuple($([:(@assert isjust(ns[$i]) == isjust(m))
            for i in 1:length(ns)]...))
        if isnothing(m) return Maybe{R}() end
        Maybe{R}(f(fromjust(m),
            $([:(fromjust(ns[$i])) for i in 1:length(ns)]...))::R)
    end
end

tycon{T,R}(::Type{Maybe{T}}, ::Type{R}) = Maybe{R}
valtype{T}(::Type{Maybe{T}}) = T

munit{T}(::Type{Maybe{T}}, x) = Maybe{T}(x)
mjoin{T}(xss::Maybe{Maybe{T}}) = frommaybe(Maybe{T}(), xss)
mbind{T}(f::Callable, xs::Maybe{T}; R::Type=eltype(f)) = mjoin(fmap(R=R, f, xs))

mzero{T}(::Type{Maybe{T}}) = Maybe{T}()
mplus{T}(xs::Maybe{T}) = xs
mplus{T}(xs::Maybe{T}, ys::Maybe{T}, zss::Maybe{T}...) =
    isjust(xs) ? xs : mplus(ys, zss...)

end


text:
import Distributions
import Gen: random, logpdf

struct TwoNormals <: Distribution{Float64} end
const two_normals = TwoNormals()

function logpdf(::TwoNormals, x, mu, sigma1, sigma2)
    if sigma1 < 0 || sigma2 < 0
        return -Inf
    end
    l1 = Distributions.logpdf(Distributions.Normal(mu, sigma1), x) + log(0.5)
    l2 = Distributions.logpdf(Distributions.Normal(mu, sigma2), x) + log(0.5)
    m = max(l1, l2)
    m + log(exp(l1 - m) + exp(l2 - m))
end

function random(::TwoNormals, mu, sigma1, sigma2)
    normal(mu, bernoulli(0.5) ? sigma1 : sigma2)
end

@gen (static) function generate_datum(mean::Float64,
        inlier_std::Float64, outlier_std::Float64)
    @trace(two_normals(mean, inlier_std, outlier_std), :z)
end

generate_data = Map(generate_datum)

@gen (static) function model(xs::Vector{Float64})
    n = length(xs)
    slope = @trace(normal(0, 2), :slope)
    intercept = @trace(normal(0, 2), :intercept)
    log_inlier_std = @trace(normal(0, 2), :log_inlier_std)
    log_outlier_std = @trace(normal(0, 2), :log_outlier_std)
    inlier_std = exp(log_inlier_std)
    outlier_std = exp(log_outlier_std)
    means = broadcast(+, slope * xs, intercept)
    ys = @trace(generate_data(means, fill(inlier_std, n), fill(outlier_std, n)), :data)
    return ys
end


text:
function importance_sampling(observations::K,
                             num_samples::Int,
                             model::Function,
                             args::Tuple) where K <: ConstrainedSelection
    calls = Vector{CallSite}(undef, num_samples)
    lws = Vector{Float64}(undef, num_samples)
    Threads.@threads for i in 1:num_samples
        _, calls[i], lws[i] = generate(observations, model, args...)
    end
    ltw = lse(lws)
    lnw = lws .- ltw
    return Particles(calls, lws, 0.0), lnw
end

function importance_sampling(observations::K,
                             num_samples::Int,
                             model::Function,
                             args::Tuple,
                             proposal::Function,
                             proposal_args::Tuple) where K <: ConstrainedSelection
    calls = Vector{CallSite}(undef, num_samples)
    lws = Vector{Float64}(undef, num_samples)
    Threads.@threads for i in 1:num_samples
        ret, pcall, pw = propose(proposal, proposal_args...)
        select = merge(pcall, observations)
        _, calls[i], lws[i] = generate(select, model, args...)
    end
    ltw = lse(lws)
    lnw = lws .- ltw
    return Particles(calls, lws, 0.0), lnw
end


text:
function  compute()
	numer=1
	denom=1

	for d=10:99
		for n =10:d-1
			n0=n%10
			n1=Int((n-n0)/10)
			d0=d%10
			d1=Int((d-d0)/10)
			if (n1==d0 && n0*d==n*d1)||(n0==d1&&n1*d==n*d0)
				numer*=n
				denom*=d
			end
		end
	end

	return Int(denom/gcd(numer,denom))
end

println(compute())


text:
"""
    repo, repo_path = git_repo(path::AbstractString)

Return the `repo::LibGit2.GitRepo` containing the file or directory `path`.
`path` does not necessarily need to be the top-level directory of the
repository. Also returns the `repo_path` of the top-level directory for the
repository.
"""
function git_repo(path::AbstractString)
    if isfile(path)
        path = dirname(path)
    end
    while true
        # check if we are at the repo root
        git_dir = joinpath(path, ".git")
        if ispath(git_dir)
            return LibGit2.GitRepo(path), path
        end
        # traverse to parent folder
        previous = path
        path = dirname(path)
        if previous == path
            return nothing, path
        end
    end
end

function git_tree(repo::LibGit2.GitRepo, commit="HEAD")
    return LibGit2.GitTree(repo, "$commit^{tree}")
end
function git_tree(path::AbstractString, commit="HEAD")
    repo, _ = git_repo(path)
    return git_tree(repo, commit)
end

"""
    files = git_files(repo)

Return the list of files checked into `repo`.
"""
function git_files(repo::LibGit2.GitRepo)
    status = LibGit2.GitStatus(repo;
        status_opts=LibGit2.StatusOptions(flags=LibGit2.Consts.STATUS_OPT_INCLUDE_UNMODIFIED))
    files = String[]
    for i = 1:length(status)
        e = status[i]
        dd = unsafe_load(e.head_to_index)
        push!(files, unsafe_string(dd.new_file.path))
    end
    return files
end
Base.keys(tree::LibGit2.GitTree) = git_files(tree.owner)

"""
    Revise.git_source(file::AbstractString, reference)

Read the source-text for `file` from a git commit `reference`.
The reference may be a string, Symbol, or `LibGit2.Tree`.

# Example:

    Revise.git_source("/path/to/myfile.jl", "HEAD")
    Revise.git_source("/path/to/myfile.jl", :abcd1234)  # by commit SHA
"""
function git_source(file::AbstractString, reference)
    fullfile = abspath(file)
    tree = git_tree(fullfile, reference)
    # git uses Unix-style paths even on Windows
    filepath = replace(relpath(fullfile, LibGit2.path(tree.owner)),
                       Base.Filesystem.path_separator_re=>'/')
    return git_source(filepath, tree)
end

function git_source(file::AbstractString, tree::LibGit2.GitTree)
    local blob
    blob = tree[file]
    if blob == nothing
        # assume empty tree when tracking new files
        src = ""
    else
        src = LibGit2.content(blob)
    end
    return src
end


text:
#=*****************************************************************************
 This is a module in an ozone NOx formaldehyde mechanism, adapted from Fortran
 by Obin Sturm (UC Davis) in October 2019.
 Written in Julia Version 1.2.0, tested up to 1.4.2

 This module was recieved from Mike Kleeman (UC Davis) in October 2018.
 ****************************************************************************=#

#  parameter definitions common to several subroutines

const maxcon, maxact, maxrxn, maxbo, maxsts = 10, 8, 20, 3, 2
const constn = zeros(Float64,1,maxcon) # note: renamed from Fortran const due to conflict with Julia function const()
const rpssa  = zeros(Float64,1,maxsts)
const r  = zeros(Float64,1,maxrxn)
const rk = zeros(Float64,1,maxrxn)
const fr  = zeros(Float64,1,maxact)
const rlr  = zeros(Float64,1,maxact)


text:
################################################################################
# fmpz_mat -> nemo file
# use as include(...)
################################################################################
function toNemo(io::IOStream, A::fmpz_mat; name = "A")
  println(io, name, " = MatrixSpace(FlintZZ, ", nrows(A), ", ", ncols(A), ")([")
  for i = 1:nrows(A)
    for j = 1:ncols(A)
      print(io, A[i,j])
      if j < ncols(A)
        print(io, " ")
      end
    end
    if i<nrows(A)
      println(io, ";")
    end
  end
  println(io, "]);")
  println(io, "println(\"Loaded ", name, "\")")
end

function toNemo(s::String, A::fmpz_mat)
  f = open(s, "w")
  toNemo(f, A)
  close(f)
end

################################################################################
# fmpz_mat -> magma file
# use as read(...)
################################################################################
function toMagma(io::IOStream, A::fmpz_mat; name = "A")
  println(io, name, " := Matrix(Integers(), ", nrows(A), ", ", ncols(A), ", [")
  for i = 1:nrows(A)
    for j = 1:ncols(A)
      print(io, A[i,j])
      if j < ncols(A)
        print(io, ", ")
      end
    end
    if i<nrows(A)
      println(io, ",")
    end
  end
  println(io, "]);")
  println(io, "\"Loaded ", name, "\";")
end

function toMagma(s::String, A::fmpz_mat)
  f = open(s, "w")
  toMagma(f, A)
  close(f)
end

################################################################################
# SMat -> magma file
# use as read(...)
################################################################################
function toMagma(io::IOStream, A::SMat; name = "A")
  println(io, name, " := SparseMatrix(Integers(), ", nrows(A), ", ", ncols(A), ", [")
  for i = 1:nrows(A)
    for xx = 1:length(A.rows[i].pos)
      print(io, "<", i, ", ", A.rows[i].pos[xx], ", ", A.rows[i].values[xx], ">")
      if xx < length(A.rows[i].pos) || i<nrows(A)
        print(io, ", ")
      end
    end
    println(io, "")
  end
  println(io, "]);")
  println(io, "\"Loaded ", name, "\";")
end

function toMagma(s::String, A::SMat)
  f = open(s, "w")
  toMagma(f, A)
  close(f)
end

################################################################################
# MPoly -> magma file
# use as read(...)
################################################################################
function toMagma(io::IOStream, R::AbstractAlgebra.MPolyRing; base_name::String = "S", name::String = "R")
  print(io, "$name<")
  S = symbols(R)
  for i = 1:length(S)-1
    print(io, "$(S[i]),")
  end
  print(io, "$(S[end])> := PolynomialRing($base_name, $(length(S)));\n")
end

function toMagma(p::String, R::AbstractAlgebra.MPolyRing; base_name::String = "S", name::String = "R", make::String = "w")
  f = open(p, mode)
  Hecke.toMagma(f, R, base_name = base_name, name = name)
  close(f)
end

function toMagma(io::IOStream, f::Generic.MPolyElem)
  S = symbols(parent(f))
  for i=1:length(f)
    if i>1
      print(io, "+")
    end
    s = "$(coeff(f, i))"
    s = replace(s, "//" => "/")
    print(io, "($s)")
    e = exponent_vector(f, i)
    if iszero(e)
      continue
    end
    print(io, "*")
    fi = true
    for j=1:length(S)
      if e[j] > 0
        if !fi
          print(io, "*")
        else
          fi = false
        end
        print(io, "$(S[j])^$(e[j])")
      end
    end
  end
end

function toMagma(io::IOStream, k::AnticNumberField; name::String = "S", gen_name::String="_a")
  print(io, "$name<$gen_name> := NumberField($(k.pol));\n")
end

function toMagma(io::IOStream, s::Symbol, v::Any)
  print(io, "$s := ")
  Hecke.toMagma(io, v)
  print(io, ";\n")
end


text:
### file: Arithmetic/tools/generate.jl

## Copyright (c) 2015 Samuel B. Johnson

## Author: Samuel B. Johnson <sabjohnso@yahoo.com>

## This file is lincesed under a two license system. For commercial use
## that is not compatible with the GPLv3, please contact the author.
## Otherwise, continue reading below.

## This file is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3, or (at your option)
## any later version.

## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.

### Code:

using SymPy

@vars x y

import Base.hypot, Base.expm1, Base.atan2

hypot( x::SymPy.Sym, y::SymPy.Sym ) = sqrt( x^2 + y^2 )
hypot( x::SymPy.Sym, y::Number ) = sqrt( x^2 + y^2 )
hypot( x::Number, y::SymPy.Sym ) = sqrt( x^2 + y^2 )

atan2( y::SymPy.Sym, x::SymPy.Sym ) = atan( y / x )
atan2( y::SymPy.Sym, x::Number ) = atan( y / x )
atan2( y::Number, x::SymPy.Sym ) = atan( y / x )

expm1( x::SymPy.Sym ) = exp( x ) - 1

unary_function_list =
    [:+, :-,
     :cos,   :sin,   :tan,
     :acos,  :asin,  :atan,
     :cosh,  :sinh,  :tanh,
     :acosh, :asinh, :atanh,
     :sqrt,  :exp,   :log,
     :expm1,
     :erf,   :erfc ]

binary_function_list =
    [ :+,     :-,     :*,     :/,    :^,
      :hypot, :atan2 ]

diff_unary( io, f ) = print( io, "($f) => x -> ", :( $(diff( eval(f)( x )))))
diff_unary( f ) = diff_unary( STDOUT, f )

diff_binary1( io, f ) =  print( io, "($f) => ( x, y ) -> ", :( $(diff( eval(f)( x, y ), x))))
diff_binary1( f ) = diff_binary1( STDOUT, f )

diff_binary2( io, f ) =  print( io, "($f) => ( x, y ) -> ", :( $(diff( eval(f)( x, y ), y))))
diff_binary2( f ) = diff_binary2( STDOUT, f )

function print_unary_dict( io )
    print( io, "const unary_diff = Dict(\n" )
    print( io, "    " )
    diff_unary( io, unary_function_list[ 1 ] )
    for op in unary_function_list[ 2:end ]
        print( io, ",\n" )
        print( io, "    " )
        diff_unary( io, op )
    end
    print( io, ")" )
end

print_unary_dict() = print_unary_dict( STDOUT )

function print_binary1_dict( io )
    print( io, "const binary1_diff = Dict(\n" )
    print( io, "    " )
    diff_binary1( io, binary_function_list[ 1 ] )
    for op in binary_function_list[ 2:end ]
        print( io, ",\n" )
        print( io, "    " )
        diff_binary1( io, op )
    end
    print( io, ")" )
end

print_binary1_dict() = print_binary1_dict( STDOUT )

function print_binary2_dict( io )
    print( io, "const binary2_diff = Dict(\n" )
    print( io, "    " )
    diff_binary2( io, binary_function_list[ 1 ] )
    for op in binary_function_list[ 2:end ]
        print( io, ",\n" )
        print( io, "    " )
        diff_binary2( io, op )
    end
    print( io, ")" )
end

print_binary2_dict() = print_binary2_dict( STDOUT )

function print_function_lists( io )
    println( io, "const unary_function_list = ", unary_function_list )
    println( io, "const binary_function_list = ", binary_function_list )
end

print_function_lists() = print_function_lists( STDOUT )

function print_dictionaries( io )
    print_function_lists( io )
    print_unary_dict( io )
    print( io, "\n\n" )
    print_binary1_dict( io )
    print( io, "\n\n" )
    print_binary2_dict( io )
    print( io, "\n\n" )
end

print_dictionaries() = print_dictionaries( STDOUT )

max_stars_repo_name: sabjohnso/AutoDiff

max_issues_repo_name: sabjohnso/AutoDiff

max_forks_repo_name: sabjohnso/AutoDiff


text:
using ...Model
using ..Gui

# Data is a list of floats. This graph connects them end to end forming
# a curve.
# The data is loaded ???
mutable struct SomaAPFastGraph <: AbstractGraph
    show_vertical_t_bar_markers::Bool
    time_pos::Int64
    value::Float64

    function SomaAPFastGraph()
        o = new()
        o.show_vertical_t_bar_markers = false
        o
    end
end

function draw_header(graph::SomaAPFastGraph, gui_data::Gui.GuiData, model::Model.ModelData)
    if CImGui.TreeNode("Controls##2")
        CImGui.PushItemWidth(1000)

        duration = Cint(Model.duration(model))
        begin_v = Cint(Model.range_start(model))
        end_v = Cint(Model.range_end(model))
        @c CImGui.DragIntRange2("Range##2", &begin_v, &end_v, 1, 1, duration, "Start: %d", "End: %d")
        if Int64(begin_v) > 0 && Int64(end_v) <= duration
            if Int64(begin_v) < Int64(end_v)
                Model.set_range_start!(model, Int64(begin_v))
                Model.set_range_end!(model, Int64(end_v))
            end
        end

        pos = Cfloat(0.0)
        @c CImGui.SliderFloat("Scroll velocity", &pos, -5.0, 5.0, "%.2f")
        Model.set_scroll!(model, Float64(pos))

        range_start = Model.range_start(model)
        range_end = Model.range_end(model) # duration
        range = range_end - range_start

        if range < MAX_VERTICAL_BARS # Limit bars to less than 500 because Drawlist is limited to 2^16 items.
            @c CImGui.Checkbox("Vertical Time Bars", &graph.show_vertical_t_bar_markers)
        else
            graph.show_vertical_t_bar_markers = false
        end

        CImGui.PopItemWidth()

        CImGui.TreePop()
    end
end

function draw_data(graph::SomaAPFastGraph, gui_data::Gui.GuiData,
    draw_list::Ptr{CImGui.LibCImGui.ImDrawList},
    canvas_pos::CImGui.LibCImGui.ImVec2, canvas_size::CImGui.LibCImGui.ImVec2,
    model::Model.ModelData, samples::Model.Samples)
    CImGui.PushClipRect(draw_list, canvas_pos,
        ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), true) # clip lines within the canvas (if we resize it, etc.)

    # We can't render anything until the model has been loaded
    # ALONG with the samples.
    if !Model.is_loaded(model)
        return
    end

    io = CImGui.GetIO()

    synapses = Model.synapses(model)
    span_time = Model.span_time(model)
    duration = Model.duration(model)
    canvas_width = Float64(canvas_size.x)
    canvas_height = Float64(canvas_size.y)

    # ------------------------------------------------------------------------
    # Adjust range_start and range_end
    # ------------------------------------------------------------------------
    range_start = Model.range_start(model)
    range_end = Model.range_end(model)
    range = range_end - range_start
    # Use window_position (0.0->1.0) to Lerp Range-start and Range-end.
    scroll = Model.scroll(model)

    velocity = scroll_velocity(scroll)

    if scroll < 0
        range_start += velocity
        # Left
        if range_start > 0
            range_end = range_start + range
        else
            range_start = 1
            range_end = range_start + range
        end
    elseif scroll > 0
        range_end += velocity
        if range_end < duration
            range_start = range_end - range
        else
            range_end = duration
            range_start = range_end - range
        end
    end
    range_start = Int64(round(range_start))
    if range_start < 1
        range_start = 1
        range_end = range_start + range
    end

    range_end = Int64(round(range_end))

    # Reflect values back to model
    Model.set_range_start!(model, Int64(round(range_start)))
    Model.set_range_end!(model, Int64(round(range_end)))
    # ------------------------------------------------------------------------

    # ------------------------------------------------------------------------
    # Mouse vertical tracking and markers
    # ------------------------------------------------------------------------
    mouse_pos = CImGui.GetMousePos()
    mpx = mouse_pos.x

    data_samples = samples.soma_apFast_samples

    # Mapped data coords
    u_x = 0.0
    w_x = 0.0
    pl_vx = 0.0
    # time_pos tracks the actual time regardless of scrolling so it always
    # starts at the current range start value.
    time_pos = range_start

    # "t" is a counter over the range "size". time_pos is the actual
    # time value capture for the tooltip
    for t in 1:range
        # We want the markers to track with time as well, so we map "t".
        u_x = map_sample_to_unit(Float64(t), 0.0, Float64(range))
        w_x = map_unit_to_window(u_x, 0.0, canvas_width)
        (l_x, l_y) = map_window_to_local(w_x, 0.0, canvas_pos)

        if mpx > pl_vx && mpx < l_x
            CImGui.AddLine(draw_list,
                ImVec2(l_x, l_y),
                ImVec2(l_x, l_y + canvas_size.y),
                LIGHT_GREY, LINE_THICKNESS)
            graph.time_pos = time_pos + 1
            graph.value = data_samples.samples[graph.time_pos]
        else
            # Show vertical bars for visual references.
            if graph.show_vertical_t_bar_markers
                CImGui.AddLine(draw_list,
                    ImVec2(l_x, l_y),
                    ImVec2(l_x, l_y + canvas_size.y),
                    GREY, LINE_THICKNESS)
            end
        end

        pl_vx = l_x # Capture previous value for interval testing
        time_pos += 1
    end
    # ------------------------------------------------------------------------
    s_y = 0.0
    pl_y = 0.0 # previously mapped y value
    pl_x = 0.0 # previously mapped x value

    # ------------------------------------------------------------------------
    # Render segmented curve
    # ------------------------------------------------------------------------
    # A span is a collection of rows

    # Iterate samples with the defined range. "t" is mapped as "x" coord
    for t in range_start:range_end
        s_y = data_samples.samples[t]

        # The sample value needs to be mapped
        u_x = map_sample_to_unit(Float64(t), Float64(range_start), Float64(range_end))
        u_y = map_sample_to_unit(s_y, data_samples.min, data_samples.max)

        w_x = map_unit_to_window(u_x, 0.0, canvas_width)
        # graph space has +Y downward, but the data is oriented as +Y upward
        # so we flip in unit-space.
        u_y = 1.0 - u_y
        w_y = map_unit_to_window(u_y, 0.0, canvas_height)
        (l_x, l_y) = map_window_to_local(w_x, w_y, canvas_pos)

        CImGui.AddLine(draw_list,
            ImVec2(pl_x, pl_y), ImVec2(l_x, l_y),
            ORANGE, LINE_THICKNESS)

        # if model.bug println("vt: ", vt) end
        pl_x = l_x
        pl_y = l_y
    end

    # if model.bug print(l_x, ",") end
    # model.bug = false
    # Show the min/max values of the data.
    CImGui.AddText(draw_list, ImVec2(5 + canvas_pos.x, 3 + canvas_pos.y), WHITE_TRAN, @sprintf("%3.3f", data_samples.max))
    CImGui.AddText(draw_list, ImVec2(5 + canvas_pos.x, canvas_pos.y + canvas_size.y - 20), WHITE_TRAN, @sprintf("%3.3f", data_samples.min))

    CImGui.PopClipRect(draw_list)

end
# if model.bug print("") end

function draw_graph(graph::SomaAPFastGraph, gui_data::Gui.GuiData, model::Model.ModelData, samples::Model.Samples)
    draw_list = CImGui.GetWindowDrawList()
    canvas_pos = CImGui.GetCursorScreenPos()            # ImDrawList API uses screen coordinates!
    canvas_size = CImGui.GetContentRegionAvail()        # resize canvas to what's available

    cx, cy = canvas_size.x, canvas_size.y
    if cx < 50.0
        cx = 50.0
    end
    if cy < 50.0
        cy = 50.0
    end
    canvas_size = ImVec2(cx, cy)
    # A visible button scaled to the size of the canvas is used for hover checking
    CImGui.InvisibleButton("canvas", canvas_size)

    CImGui.AddRectFilledMultiColor(draw_list, canvas_pos,
        ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y),
        IM_COL32(GRAY, GRAY, GRAY, 255), IM_COL32(GRAY, GRAY, GRAY, 255),
        IM_COL32(GRAY, GRAY, GRAY, 255), IM_COL32(GRAY, GRAY, GRAY, 255))

    # CImGui.Text(@sprintf("hello"))

    if CImGui.IsItemHovered()
        CImGui.BeginTooltip()
        CImGui.Text(@sprintf("%d (%4.3f)", graph.time_pos, graph.value))
        CImGui.EndTooltip()
    end

    CImGui.AddRect(draw_list, canvas_pos,
        ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y),
        IM_COL32(128, 128, 128, 255))

    draw_data(graph, gui_data, draw_list, canvas_pos, canvas_size, model, samples)
end

function draw(graph::SomaAPFastGraph, gui_data::Gui.GuiData, model::Model.ModelData, samples::Model.Samples, vert_pos::Int64)
    # CImGui.SetNextWindowPos((0, 25 + WINDOW_HEIGHT), CImGui.ImGuiCond_Once)
    CImGui.SetNextWindowPos((0, vert_pos), CImGui.ImGuiCond_Once)
    CImGui.SetNextWindowSize((GRAPH_WINDOW_WIDTH, GRAPH_WINDOW_HEIGHT), CImGui.ImGuiCond_Always)

    CImGui.Begin("Soma apFast Graph")

    draw_header(graph, gui_data, model)

    CImGui.Separator()

    draw_graph(graph, gui_data, model, samples)

    CImGui.End()
end


text:
#File for plotting Figure 5

using JLD2
using Statistics
using DataFrames
using Gadfly
using CSV

import Cairo, Fontconfig

### Load data
load_dict = load("data/wide_sigma3.jld2")
res_mat1 = load_dict["out_list"][1]
res_mat1_const = load_dict["out_list"][2]

function data_to_plot(res_mat::Matrix, x_max::Int, σ)
    wide_df = DataFrame(res_mat[1:x_max, :], :auto)
    wide_df_plot = DataFrame()
    wide_df_plot[!, "depth"] = collect(1:x_max)
    wide_df_plot[!, "mean"] = mean.(eachrow(wide_df))

    wide_df_plot[!, "ymin"] = quantile.(eachrow(wide_df), 0.1)
    wide_df_plot[!, "ymax"] = quantile.(eachrow(wide_df), 0.9)
    wide_df_plot[!, "Approach"] = repeat([String(σ)], size(wide_df_plot, 1))

    return wide_df_plot

end

## Transform data
x_max = 20
r1 = data_to_plot(res_mat1, x_max, "weighted")
r2 = data_to_plot(res_mat1_const, x_max, "CART")

plot_df = vcat(r2, r1)

## Plot
p = plot(Scale.color_discrete_manual("#264653", "#E7C15F"))

push!(p, layer(plot_df, x=:depth, y=:mean, ymin=:ymin, ymax=:ymax, color="Approach", Geom.line, Geom.ribbon, alpha=[0.5]))

push!(p, Guide.YLabel("% of splits on noisy variables"))
push!(p, Guide.XLabel("Tree Depth"))
push!(p, Guide.title("Error term variance = 3"))
push!(p, Guide.yticks(ticks=0:0.25:0.8))
push!(p, Theme(key_position=:none, line_width=0.8mm))
# push!(p, Theme(line_width=0.8mm))

draw(PNG("/home/christian/UniMA/EMMA/figures/graphs/wide_sigmas3.png", 20cm, 12cm, dpi=300), p)

max_stars_repo_name: christianhilscher/emma

max_issues_repo_name: christianhilscher/emma

max_forks_repo_name: christianhilscher/emma


text:
function groupbycolnumericsummary(INPUT::Union{Array,DataFrame},groupbycol::String)  #数値型の基本統計量の算出
    SummaryVar=StatsBase.var(INPUT)
    SummaryStd=StatsBase.std(INPUT)
    SummaryQuartile=StatsBase.quantile( INPUT , [0.00, 0.25, 0.50, 0.75, 1.00])
    SummaryMedian=StatsBase.median(INPUT)
    SummaryMean=StatsBase.mean(INPUT)

    Output=DataFrame(colname=groupbycol,Var=SummaryVar,Std=SummaryStd,Mean=SummaryMean, Min=SummaryQuartile[1] ,Quartile1st=SummaryQuartile[2] ,Median=SummaryMedian,Quartile3rd=SummaryQuartile[4],Max=SummaryQuartile[5])

    return Output
end

function groupbycolnonnumericsummary(INPUT::Union{Array,DataFrame},groupbycol::Symbol,staticstargetcol::Symbol,setcolnames::Array)  #非数値型の基本統計量の算出
    result=zeros(Int,1,size(setcolnames,1)-1)
    result=DataFrame(result,Vector(setcolnames[2:end]))

    result=hcat(DataFrame(Matrix{Union{Any,Missing}}(missing,1,1),:auto),result)
    rename!(result,setcolnames)

    Output=combine(groupby(INPUT, staticstargetcol, sort=false, skipmissing=false), staticstargetcol=>df -> size(df, 1))
    result[1,groupbycol]=INPUT[1,groupbycol]

    for i in Output[:,staticstargetcol]
        result[1,Symbol(i)]=Output[Output[:,staticstargetcol] .==i , 2][1]
    end

    return result
end

function groupbycolunivariate(INPUT::DataFrame,groupbycol::Symbol,staticstargetcol::Symbol)
    colname=sort(unique(INPUT[:,groupbycol]))
    SummaryNum=DataFrame(colname="",Var=0.0,Std=0.0,Mean=0.0, Min=0.0 ,Quartile1st=0.0 ,Median=0.0,Quartile3rd=0.0,Max=0.0)
    SummaryNonNum=DataFrame(colname="",hist=0)
    firstresultflag=true

    if eltype(INPUT[:,staticstargetcol]) <: Real
        for i in colname
            work=INPUT[INPUT[:,groupbycol] .== i,:]
            if (firstresultflag)
                SummaryNum=groupbycolnumericsummary(work[:,staticstargetcol],i)
                firstresultflag=false
            else
                SummaryNum=vcat(SummaryNum,groupbycolnumericsummary(work[:,staticstargetcol],i) )
            end
        end
    else #非数値
        setcolnames=vcat(groupbycol,sort(union(INPUT[:,staticstargetcol])))
        setcolnames=map(Symbol,setcolnames)
        for i in colname
            work=INPUT[INPUT[:,groupbycol] .== i,:]
            if (firstresultflag)
                SummaryNonNum=groupbycolnonnumericsummary(work,groupbycol,staticstargetcol,setcolnames)
                firstresultflag=false
            else
                SummaryNonNum=vcat(SummaryNonNum,groupbycolnonnumericsummary(work,groupbycol,staticstargetcol,setcolnames) )
            end
        end
    end

    if eltype(INPUT[:,staticstargetcol]) <: Real
        result=SummaryNum
    else
        result=SummaryNonNum
    end

    return result
end


text:
## type aliases ##

if Int === Int32
typealias SmallSigned Union(Int8,Int16)
typealias SmallUnsigned Union(Uint8,Uint16)
else
typealias SmallSigned Union(Int8,Int16,Int32)
typealias SmallUnsigned Union(Uint8,Uint16,Uint32)
end

## integer arithmetic ##

-(x::SmallSigned) = -int(x)
-(x::SmallUnsigned) = -uint(x)

+{T<:SmallSigned}(x::T, y::T) = int(x) + int(y)
-{T<:SmallSigned}(x::T, y::T) = int(x) - int(y)
*{T<:SmallSigned}(x::T, y::T) = int(x) * int(y)

+{T<:SmallUnsigned}(x::T, y::T) = uint(x) + uint(y)
-{T<:SmallUnsigned}(x::T, y::T) = uint(x) - uint(y)
*{T<:SmallUnsigned}(x::T, y::T) = uint(x) * uint(y)

-(x::Int)     = box(Int,neg_int(unbox(Int,x)))
-(x::Uint)    = box(Uint,neg_int(unbox(Uint,x)))
-(x::Int64)   = box(Int64,neg_int(unbox(Int64,x)))
-(x::Uint64)  = box(Uint64,neg_int(unbox(Uint64,x)))
-(x::Int128)  = box(Int128,neg_int(unbox(Int128,x)))
-(x::Uint128) = box(Uint128,neg_int(unbox(Uint128,x)))

+(x::Int,     y::Int)     = box(Int,add_int(unbox(Int,x),unbox(Int,y)))
+(x::Uint,    y::Uint)    = box(Uint,add_int(unbox(Uint,x),unbox(Uint,y)))
+(x::Int64,   y::Int64)   = box(Int64,add_int(unbox(Int64,x),unbox(Int64,y)))
+(x::Uint64,  y::Uint64)  = box(Uint64,add_int(unbox(Uint64,x),unbox(Uint64,y)))
+(x::Int128,  y::Int128)  = box(Int128,add_int(unbox(Int128,x),unbox(Int128,y)))
+(x::Uint128, y::Uint128) = box(Uint128,add_int(unbox(Uint128,x),unbox(Uint128,y)))

-(x::Int,     y::Int)     = box(Int,sub_int(unbox(Int,x),unbox(Int,y)))
-(x::Uint,    y::Uint)    = box(Uint,sub_int(unbox(Uint,x),unbox(Uint,y)))
-(x::Int64,   y::Int64)   = box(Int64,sub_int(unbox(Int64,x),unbox(Int64,y)))
-(x::Uint64,  y::Uint64)  = box(Uint64,sub_int(unbox(Uint64,x),unbox(Uint64,y)))
-(x::Int128,  y::Int128)  = box(Int128,sub_int(unbox(Int128,x),unbox(Int128,y)))
-(x::Uint128, y::Uint128) = box(Uint128,sub_int(unbox(Uint128,x),unbox(Uint128,y)))

*(x::Int,     y::Int)     = box(Int,mul_int(unbox(Int,x),unbox(Int,y)))
*(x::Uint,    y::Uint)    = box(Uint,mul_int(unbox(Uint,x),unbox(Uint,y)))
*(x::Int64,   y::Int64)   = box(Int64,mul_int(unbox(Int64,x),unbox(Int64,y)))
*(x::Uint64,  y::Uint64)  = box(Uint64,mul_int(unbox(Uint64,x),unbox(Uint64,y)))

/(x::Integer, y::Integer) = float(x)/float(y)
inv(x::Integer) = float(one(x))/float(x)

isodd(n::Integer) = bool(rem(n,2))
iseven(n::Integer) = !isodd(n)

signbit(x::Integer) = x < 0
signbit(x::Unsigned) = false

flipsign(x::Int,    y::Int)    = box(Int,flipsign_int(unbox(Int,x),unbox(Int,y)))
flipsign(x::Int64,  y::Int64)  = box(Int64,flipsign_int(unbox(Int64,x),unbox(Int64,y)))
flipsign(x::Int128, y::Int128) = box(Int128,flipsign_int(unbox(Int128,x),unbox(Int128,y)))

flipsign{T<:Signed}(x::T,y::T)  = flipsign(int(x),int(y))
flipsign(x::Signed, y::Signed)  = flipsign(promote(x,y)...)
flipsign(x::Signed, y::Float32) = flipsign(x, reinterpret(Int32,y))
flipsign(x::Signed, y::Float64) = flipsign(x, reinterpret(Int64,y))
flipsign(x::Signed, y::Real)    = flipsign(x, -oftype(x,signbit(y)))

copysign(x::Signed, y::Signed)  = flipsign(x, x$y)
copysign(x::Signed, y::Float32) = copysign(x, reinterpret(Int32,y))
copysign(x::Signed, y::Float64) = copysign(x, reinterpret(Int64,y))
copysign(x::Signed, y::Real)    = copysign(x, -oftype(x,signbit(y)))

abs(x::Unsigned) = x
abs(x::Signed) = flipsign(x,x)

~(n::Integer) = -n-1

div(x::Signed, y::Unsigned) = flipsign(signed(div(unsigned(abs(x)),y)),x)
div(x::Unsigned, y::Signed) = unsigned(flipsign(signed(div(x,unsigned(abs(y)))),y))

rem(x::Signed, y::Unsigned) = flipsign(signed(rem(unsigned(abs(x)),y)),x)
rem(x::Unsigned, y::Signed) = rem(x,unsigned(abs(y)))

fld(x::Signed, y::Unsigned) = div(x,y)-(signbit(x)&(rem(x,y)!=0))
fld(x::Unsigned, y::Signed) = div(x,y)-(signbit(y)&(rem(x,y)!=0))

mod(x::Signed, y::Unsigned) = rem(y+unsigned(rem(x,y)),y)
mod(x::Unsigned, y::Signed) = rem(y+signed(rem(x,y)),y)

# Don't promote integers for div/rem/mod since there no danger of overflow,
# while there is a substantial performance penalty to 64-bit promotion.
typealias Signed64 Union(Int8,Int16,Int32,Int64)
typealias Unsigned64 Union(Uint8,Uint16,Uint32,Uint64)
typealias Integer64 Union(Signed64,Unsigned64)

div{T<:Signed64}  (x::T, y::T) = box(T,sdiv_int(unbox(T,x),unbox(T,y)))
div{T<:Unsigned64}(x::T, y::T) = box(T,udiv_int(unbox(T,x),unbox(T,y)))
rem{T<:Signed64}  (x::T, y::T) = box(T,srem_int(unbox(T,x),unbox(T,y)))
rem{T<:Unsigned64}(x::T, y::T) = box(T,urem_int(unbox(T,x),unbox(T,y)))
mod{T<:Signed64}  (x::T, y::T) = box(T,smod_int(unbox(T,x),unbox(T,y)))

mod{T<:Unsigned}(x::T, y::T) = rem(x,y)

fld{T<:Unsigned}(x::T, y::T) = div(x,y)
fld{T<:Integer }(x::T, y::T) = div(x,y)-(signbit(x$y)&(rem(x,y)!=0))

## integer bitwise operations ##

~(x::Int8 )  = box(Int8,not_int(unbox(Int8,x)))
~(x::Int16)  = box(Int16,not_int(unbox(Int16,x)))
~(x::Int32)  = box(Int32,not_int(unbox(Int32,x)))
~(x::Int64)  = box(Int64,not_int(unbox(Int64,x)))
~(x::Int128) = box(Int128,not_int(unbox(Int128,x)))

~(x::Uint8 )  = box(Uint8,not_int(unbox(Uint8,x)))
~(x::Uint16)  = box(Uint16,not_int(unbox(Uint16,x)))
~(x::Uint32)  = box(Uint32,not_int(unbox(Uint32,x)))
~(x::Uint64)  = box(Uint64,not_int(unbox(Uint64,x)))
~(x::Uint128) = box(Uint128,not_int(unbox(Uint128,x)))

(&)(x::Int8,   y::Int8 )  = box(Int8,and_int(unbox(Int8,x),unbox(Int8,y)))
(&)(x::Int16,  y::Int16)  = box(Int16,and_int(unbox(Int16,x),unbox(Int16,y)))
(&)(x::Int32,  y::Int32)  = box(Int32,and_int(unbox(Int32,x),unbox(Int32,y)))
(&)(x::Int64,  y::Int64)  = box(Int64,and_int(unbox(Int64,x),unbox(Int64,y)))
(&)(x::Int128, y::Int128) = box(Int128,and_int(unbox(Int128,x),unbox(Int128,y)))

(&)(x::Uint8,   y::Uint8 )  = box(Uint8,and_int(unbox(Uint8,x),unbox(Uint8,y)))
(&)(x::Uint16,  y::Uint16)  = box(Uint16,and_int(unbox(Uint16,x),unbox(Uint16,y)))
(&)(x::Uint32,  y::Uint32)  = box(Uint32,and_int(unbox(Uint32,x),unbox(Uint32,y)))
(&)(x::Uint64,  y::Uint64)  = box(Uint64,and_int(unbox(Uint64,x),unbox(Uint64,y)))
(&)(x::Uint128, y::Uint128) = box(Uint128,and_int(unbox(Uint128,x),unbox(Uint128,y)))

|(x::Int8,   y::Int8)   = box(Int8,or_int(unbox(Int8,x),unbox(Int8,y)))
|(x::Int16,  y::Int16)  = box(Int16,or_int(unbox(Int16,x),unbox(Int16,y)))
|(x::Int32,  y::Int32)  = box(Int32,or_int(unbox(Int32,x),unbox(Int32,y)))
|(x::Int64,  y::Int64)  = box(Int64,or_int(unbox(Int64,x),unbox(Int64,y)))
|(x::Int128, y::Int128) = box(Int128,or_int(unbox(Int128,x),unbox(Int128,y)))

|(x::Uint8,   y::Uint8)   = box(Uint8,or_int(unbox(Uint8,x),unbox(Uint8,y)))
|(x::Uint16,  y::Uint16)  = box(Uint16,or_int(unbox(Uint16,x),unbox(Uint16,y)))
|(x::Uint32,  y::Uint32)  = box(Uint32,or_int(unbox(Uint32,x),unbox(Uint32,y)))
|(x::Uint64,  y::Uint64)  = box(Uint64,or_int(unbox(Uint64,x),unbox(Uint64,y)))
|(x::Uint128, y::Uint128) = box(Uint128,or_int(unbox(Uint128,x),unbox(Uint128,y)))

($)(x::Int8,   y::Int8)   = box(Int8,xor_int(unbox(Int8,x),unbox(Int8,y)))
($)(x::Int16,  y::Int16)  = box(Int16,xor_int(unbox(Int16,x),unbox(Int16,y)))
($)(x::Int32,  y::Int32)  = box(Int32,xor_int(unbox(Int32,x),unbox(Int32,y)))
($)(x::Int64,  y::Int64)  = box(Int64,xor_int(unbox(Int64,x),unbox(Int64,y)))
($)(x::Int128, y::Int128) = box(Int128,xor_int(unbox(Int128,x),unbox(Int128,y)))

($)(x::Uint8,   y::Uint8)   = box(Uint8,xor_int(unbox(Uint8,x),unbox(Uint8,y)))
($)(x::Uint16,  y::Uint16)  = box(Uint16,xor_int(unbox(Uint16,x),unbox(Uint16,y)))
($)(x::Uint32,  y::Uint32)  = box(Uint32,xor_int(unbox(Uint32,x),unbox(Uint32,y)))
($)(x::Uint64,  y::Uint64)  = box(Uint64,xor_int(unbox(Uint64,x),unbox(Uint64,y)))
($)(x::Uint128, y::Uint128) = box(Uint128,xor_int(unbox(Uint128,x),unbox(Uint128,y)))

<<(x::Int8,   y::Int32) = box(Int8,shl_int(unbox(Int8,x),unbox(Int32,y)))
<<(x::Int16,  y::Int32) = box(Int16,shl_int(unbox(Int16,x),unbox(Int32,y)))
<<(x::Int32,  y::Int32) = box(Int32,shl_int(unbox(Int32,x),unbox(Int32,y)))
<<(x::Int64,  y::Int32) = box(Int64,shl_int(unbox(Int64,x),unbox(Int32,y)))
<<(x::Int128, y::Int32) = box(Int128,shl_int(unbox(Int128,x),unbox(Int32,y)))

<<(x::Uint8,   y::Int32) = box(Uint8,shl_int(unbox(Uint8,x),unbox(Int32,y)))
<<(x::Uint16,  y::Int32) = box(Uint16,shl_int(unbox(Uint16,x),unbox(Int32,y)))
<<(x::Uint32,  y::Int32) = box(Uint32,shl_int(unbox(Int32,x),unbox(Uint32,y)))
<<(x::Uint64,  y::Int32) = box(Uint64,shl_int(unbox(Uint64,x),unbox(Int32,y)))
<<(x::Uint128, y::Int32) = box(Uint128,shl_int(unbox(Uint128,x),unbox(Int32,y)))

>>(x::Int8,   y::Int32) = box(Int8,ashr_int(unbox(Int8,x),unbox(Int32,y)))
>>(x::Int16,  y::Int32) = box(Int16,ashr_int(unbox(Int16,x),unbox(Int32,y)))
>>(x::Int32,  y::Int32) = box(Int32,ashr_int(unbox(Int32,x),unbox(Int32,y)))
>>(x::Int64,  y::Int32) = box(Int64,ashr_int(unbox(Int64,x),unbox(Int32,y)))
>>(x::Int128, y::Int32) = box(Int128,ashr_int(unbox(Int128,x),unbox(Int32,y)))

>>(x::Uint8,   y::Int32) = box(Uint8,lshr_int(unbox(Uint8,x),unbox(Int32,y)))
>>(x::Uint16,  y::Int32) = box(Uint16,lshr_int(unbox(Uint16,x),unbox(Int32,y)))
>>(x::Uint32,  y::Int32) = box(Uint32,lshr_int(unbox(Int32,x),unbox(Uint32,y)))
>>(x::Uint64,  y::Int32) = box(Uint64,lshr_int(unbox(Uint64,x),unbox(Int32,y)))
>>(x::Uint128, y::Int32) = box(Uint128,lshr_int(unbox(Uint128,x),unbox(Int32,y)))

>>>(x::Int8,   y::Int32) = box(Int8,lshr_int(unbox(Int8,x),unbox(Int32,y)))
>>>(x::Int16,  y::Int32) = box(Int16,lshr_int(unbox(Int16,x),unbox(Int32,y)))
>>>(x::Int32,  y::Int32) = box(Int32,lshr_int(unbox(Int32,x),unbox(Int32,y)))
>>>(x::Int64,  y::Int32) = box(Int64,lshr_int(unbox(Int64,x),unbox(Int32,y)))
>>>(x::Int128, y::Int32) = box(Int128,lshr_int(unbox(Int128,x),unbox(Int32,y)))

>>>(x::Uint8,   y::Int32) = box(Uint8,lshr_int(unbox(Uint8,x),unbox(Int32,y)))
>>>(x::Uint16,  y::Int32) = box(Uint16,lshr_int(unbox(Uint16,x),unbox(Int32,y)))
>>>(x::Uint32,  y::Int32) = box(Uint32,lshr_int(unbox(Int32,x),unbox(Uint32,y)))
>>>(x::Uint64,  y::Int32) = box(Uint64,lshr_int(unbox(Uint64,x),unbox(Int32,y)))
>>>(x::Uint128, y::Int32) = box(Uint128,lshr_int(unbox(Uint128,x),unbox(Int32,y)))

bswap(x::Int8)    = x
bswap(x::Uint8)   = x
bswap(x::Int16)   = box(Int16,bswap_int(unbox(Int16,x)))
bswap(x::Uint16)  = box(Uint16,bswap_int(unbox(Uint16,x)))
bswap(x::Int32)   = box(Int32,bswap_int(unbox(Int32,x)))
bswap(x::Uint32)  = box(Uint32,bswap_int(unbox(Uint32,x)))
bswap(x::Int64)   = box(Int64,bswap_int(unbox(Int64,x)))
bswap(x::Uint64)  = box(Uint64,bswap_int(unbox(Uint64,x)))
bswap(x::Int128)  = box(Int128,bswap_int(unbox(Int128,x)))
bswap(x::Uint128) = box(Uint128,bswap_int(unbox(Uint128,x)))

count_ones(x::Int8)    = int(box(Int8,ctpop_int(unbox(Int8,x))))
count_ones(x::Uint8)   = int(box(Uint8,ctpop_int(unbox(Uint8,x))))
count_ones(x::Int16)   = int(box(Int16,ctpop_int(unbox(Int16,x))))
count_ones(x::Uint16)  = int(box(Uint16,ctpop_int(unbox(Uint16,x))))
count_ones(x::Int32)   = int(box(Int32,ctpop_int(unbox(Int32,x))))
count_ones(x::Uint32)  = int(box(Uint32,ctpop_int(unbox(Uint32,x))))
count_ones(x::Int64)   = int(box(Int64,ctpop_int(unbox(Int64,x))))
count_ones(x::Uint64)  = int(box(Uint64,ctpop_int(unbox(Uint64,x))))
count_ones(x::Int128)  = int(box(Int128,ctpop_int(unbox(Int128,x))))
count_ones(x::Uint128) = int(box(Uint128,ctpop_int(unbox(Uint128,x))))

leading_zeros(x::Int8)    = int(box(Int8,ctlz_int(unbox(Int8,x))))
leading_zeros(x::Uint8)   = int(box(Uint8,ctlz_int(unbox(Uint8,x))))
leading_zeros(x::Int16)   = int(box(Int16,ctlz_int(unbox(Int16,x))))
leading_zeros(x::Uint16)  = int(box(Uint16,ctlz_int(unbox(Uint16,x))))
leading_zeros(x::Int32)   = int(box(Int32,ctlz_int(unbox(Int32,x))))
leading_zeros(x::Uint32)  = int(box(Uint32,ctlz_int(unbox(Uint32,x))))
leading_zeros(x::Int64)   = int(box(Int64,ctlz_int(unbox(Int64,x))))
leading_zeros(x::Uint64)  = int(box(Uint64,ctlz_int(unbox(Uint64,x))))
leading_zeros(x::Int128)  = int(box(Int128,ctlz_int(unbox(Int128,x))))
leading_zeros(x::Uint128) = int(box(Uint128,ctlz_int(unbox(Uint128,x))))

trailing_zeros(x::Int8)    = int(box(Int8,cttz_int(unbox(Int8,x))))
trailing_zeros(x::Uint8)   = int(box(Uint8,cttz_int(unbox(Uint8,x))))
trailing_zeros(x::Int16)   = int(box(Int16,cttz_int(unbox(Int16,x))))
trailing_zeros(x::Uint16)  = int(box(Uint16,cttz_int(unbox(Uint16,x))))
trailing_zeros(x::Int32)   = int(box(Int32,cttz_int(unbox(Int32,x))))
trailing_zeros(x::Uint32)  = int(box(Uint32,cttz_int(unbox(Uint32,x))))
trailing_zeros(x::Int64)   = int(box(Int64,cttz_int(unbox(Int64,x))))
trailing_zeros(x::Uint64)  = int(box(Uint64,cttz_int(unbox(Uint64,x))))
trailing_zeros(x::Int128)  = int(box(Int128,cttz_int(unbox(Int128,x))))
trailing_zeros(x::Uint128) = int(box(Uint128,cttz_int(unbox(Uint128,x))))

count_zeros  (x::Integer) = count_ones(~x)
leading_ones (x::Integer) = leading_zeros(~x)
trailing_ones(x::Integer) = trailing_zeros(~x)

## integer comparisons ##

<(x::Int8,   y::Int8)   = slt_int(unbox(Int8,x),unbox(Int8,y))
<(x::Int16,  y::Int16)  = slt_int(unbox(Int16,x),unbox(Int16,y))
<(x::Int32,  y::Int32)  = slt_int(unbox(Int32,x),unbox(Int32,y))
<(x::Int64,  y::Int64)  = slt_int(unbox(Int64,x),unbox(Int64,y))
<(x::Int128, y::Int128) = slt_int(unbox(Int128,x),unbox(Int128,y))

<(x::Uint8,   y::Uint8)   = ult_int(unbox(Uint8,x),unbox(Uint8,y))
<(x::Uint16,  y::Uint16)  = ult_int(unbox(Uint16,x),unbox(Uint16,y))
<(x::Uint32,  y::Uint32)  = ult_int(unbox(Uint32,x),unbox(Uint32,y))
<(x::Uint64,  y::Uint64)  = ult_int(unbox(Uint64,x),unbox(Uint64,y))
<(x::Uint128, y::Uint128) = ult_int(unbox(Uint128,x),unbox(Uint128,y))

<=(x::Int8,   y::Int8)   = sle_int(unbox(Int8,x),unbox(Int8,y))
<=(x::Int16,  y::Int16)  = sle_int(unbox(Int16,x),unbox(Int16,y))
<=(x::Int32,  y::Int32)  = sle_int(unbox(Int32,x),unbox(Int32,y))
<=(x::Int64,  y::Int64)  = sle_int(unbox(Int64,x),unbox(Int64,y))
<=(x::Int128, y::Int128) = sle_int(unbox(Int128,x),unbox(Int128,y))

<=(x::Uint8,   y::Uint8)   = ule_int(unbox(Uint8,x),unbox(Uint8,y))
<=(x::Uint16,  y::Uint16)  = ule_int(unbox(Uint16,x),unbox(Uint16,y))
<=(x::Uint32,  y::Uint32)  = ule_int(unbox(Uint32,x),unbox(Uint32,y))
<=(x::Uint64,  y::Uint64)  = ule_int(unbox(Uint64,x),unbox(Uint64,y))
<=(x::Uint128, y::Uint128) = ule_int(unbox(Uint128,x),unbox(Uint128,y))

==(x::Signed,   y::Unsigned) = (x >= 0) & (unsigned(x) == y)
==(x::Unsigned, y::Signed  ) = (y >= 0) & (x == unsigned(y))
< (x::Signed,   y::Unsigned) = (x <  0) | (unsigned(x) <  y)
< (x::Unsigned, y::Signed  ) = (y >  0) & (x <  unsigned(y))
<=(x::Signed,   y::Unsigned) = (x <= 0) | (unsigned(x) <= y)
<=(x::Unsigned, y::Signed  ) = (y >= 0) & (x <= unsigned(y))

## integer conversions ##

const _inttypes = (Bool, Int8, Uint8, Int16, Uint16, Int32, Uint32, Char,
                   Int64, Uint64, Int128, Uint128)

for to in _inttypes, from in _inttypes
    if !(to===from) && !(to===Bool)
        if to.size < from.size
            @eval convert(::Type{$to}, x::($from)) = box($to,trunc_int($to,unbox($from,x)))
        elseif from.size < to.size || from===Bool
            if issubtype(from, Signed)
                @eval convert(::Type{$to}, x::($from)) = box($to,sext_int($to,unbox($from,x)))
            else
                @eval convert(::Type{$to}, x::($from)) = box($to,zext_int($to,unbox($from,x)))
            end
        else
            @eval convert(::Type{$to}, x::($from)) = box($to,unbox($from,x))
        end
    end
end

for to in (Int8, Int16, Int32, Int64)
    @eval begin
        convert(::Type{$to}, x::Float32) = box($to,checked_fptosi($to,unbox(Float32,x)))
        convert(::Type{$to}, x::Float64) = box($to,checked_fptosi($to,unbox(Float64,x)))
    end
end

for to in (Uint8, Uint16, Uint32, Uint64)
    @eval begin
        convert(::Type{$to}, x::Float32) = box($to,checked_fptoui($to,unbox(Float32,x)))
        convert(::Type{$to}, x::Float64) = box($to,checked_fptoui($to,unbox(Float64,x)))
    end
end

function convert(::Type{Int128}, x::FloatingPoint)
    ax = abs(x)
    top = trunc(ldexp(ax,-64))
    bot = ax - ldexp(top,64)
    n = int128(convert(Uint64,top))<<64 + int128(convert(Uint64,bot))
    return x<0 ? -n : n
end
convert(::Type{Int128}, x::Float32) = convert(Int128, float64(x))

function convert(::Type{Uint128}, x::FloatingPoint)
    ax = abs(x)
    top = trunc(ldexp(ax,-64))
    bot = ax - ldexp(top,64)
    n = uint128(convert(Uint64,top))<<64 + uint128(convert(Uint64,bot))
    return x<0 ? -n : n
end
convert(::Type{Uint128}, x::Float32) = convert(Uint128, float64(x))

convert(::Type{Char}, x::Float32) = char(convert(Int, x))
convert(::Type{Char}, x::Float64) = char(convert(Int, x))

convert(::Type{Signed}, x::Uint8  ) = convert(Int,x)
convert(::Type{Signed}, x::Uint16 ) = convert(Int,x)
convert(::Type{Signed}, x::Uint32 ) = convert(Int,x)
convert(::Type{Signed}, x::Uint64 ) = convert(Int64,x)
convert(::Type{Signed}, x::Uint128) = convert(Int128,x)
convert(::Type{Signed}, x::Float32) = convert(Int,x)
convert(::Type{Signed}, x::Float64) = convert(Int,x)
convert(::Type{Signed}, x::Char)    = convert(Int,x)

convert(::Type{Unsigned}, x::Int8   ) = convert(Uint,x)
convert(::Type{Unsigned}, x::Int16  ) = convert(Uint,x)
convert(::Type{Unsigned}, x::Int32  ) = convert(Uint,x)
convert(::Type{Unsigned}, x::Int64  ) = convert(Uint64,x)
convert(::Type{Unsigned}, x::Int128 ) = convert(Uint128,x)
convert(::Type{Unsigned}, x::Float32) = convert(Uint,x)
convert(::Type{Unsigned}, x::Float64) = convert(Uint,x)
convert(::Type{Unsigned}, x::Char)    = convert(Uint,x)

convert(::Type{Integer}, x::Float32) = convert(Int,x)
convert(::Type{Integer}, x::Float64) = convert(Int,x)

int8(x) = convert(Int8,x)
int16(x) = convert(Int16,x)
int32(x) = convert(Int32,x)
int64(x) = convert(Int64,x)
int128(x) = convert(Int128,x)

uint8(x) = convert(Uint8,x)
uint16(x) = convert(Uint16,x)
uint32(x) = convert(Uint32,x)
uint64(x) = convert(Uint64,x)
uint128(x) = convert(Uint128,x)

signed(x) = convert(Signed,x)
unsigned(x) = convert(Unsigned,x)
integer(x) = convert(Integer,x)

round(x::Integer) = x
trunc(x::Integer) = x
floor(x::Integer) = x
 ceil(x::Integer) = x

iround(x::Integer) = x
iround{T<:Integer}(::Type{T}, x::Integer) = convert(T, x)
itrunc(x::Integer) = x
ifloor(x::Integer) = x
 iceil(x::Integer) = x

## integer construction ##

macro int128_str(str)
    int128(str)
end

macro uint128_str(str)
    uint128(str)
end

macro bigint_str(str)
    BigInt(str)
end

## system word size ##

const WORD_SIZE = int(Int.size)*8

## integer promotions ##

promote_rule(::Type{Int16},  ::Type{Int8} ) = Int
promote_rule(::Type{Int32},  ::Type{Int8} ) = Int
promote_rule(::Type{Int32},  ::Type{Int16}) = Int
promote_rule(::Type{Int64},  ::Type{Int8} ) = Int64
promote_rule(::Type{Int64},  ::Type{Int16}) = Int64
promote_rule(::Type{Int64},  ::Type{Int32}) = Int64
promote_rule(::Type{Int128}, ::Type{Int8} ) = Int128
promote_rule(::Type{Int128}, ::Type{Int16}) = Int128
promote_rule(::Type{Int128}, ::Type{Int32}) = Int128
promote_rule(::Type{Int128}, ::Type{Int64}) = Int128

promote_rule(::Type{Uint16},  ::Type{Uint8} ) = Uint
promote_rule(::Type{Uint32},  ::Type{Uint8} ) = Uint
promote_rule(::Type{Uint32},  ::Type{Uint16}) = Uint
promote_rule(::Type{Uint64},  ::Type{Uint8} ) = Uint64
promote_rule(::Type{Uint64},  ::Type{Uint16}) = Uint64
promote_rule(::Type{Uint64},  ::Type{Uint32}) = Uint64
promote_rule(::Type{Uint128}, ::Type{Uint8} ) = Uint128
promote_rule(::Type{Uint128}, ::Type{Uint16}) = Uint128
promote_rule(::Type{Uint128}, ::Type{Uint32}) = Uint128
promote_rule(::Type{Uint128}, ::Type{Uint64}) = Uint128

promote_rule(::Type{Uint8}, ::Type{Int8}  ) = Int
promote_rule(::Type{Uint8}, ::Type{Int16} ) = Int
promote_rule(::Type{Uint8}, ::Type{Int32} ) = Int
promote_rule(::Type{Uint8}, ::Type{Int64} ) = Int64
promote_rule(::Type{Uint8}, ::Type{Int128}) = Int128

promote_rule(::Type{Uint16}, ::Type{Int8}  ) = Int
promote_rule(::Type{Uint16}, ::Type{Int16} ) = Int
promote_rule(::Type{Uint16}, ::Type{Int32} ) = Int
promote_rule(::Type{Uint16}, ::Type{Int64} ) = Int64
promote_rule(::Type{Uint16}, ::Type{Int128}) = Int128

if WORD_SIZE == 64
    promote_rule(::Type{Uint32}, ::Type{Int8} ) = Int
    promote_rule(::Type{Uint32}, ::Type{Int16}) = Int
    promote_rule(::Type{Uint32}, ::Type{Int32}) = Int
else
    promote_rule(::Type{Uint32}, ::Type{Int8} ) = Uint
    promote_rule(::Type{Uint32}, ::Type{Int16}) = Uint
    promote_rule(::Type{Uint32}, ::Type{Int32}) = Uint
end
promote_rule(::Type{Uint32}, ::Type{Int64} ) = Int64
promote_rule(::Type{Uint32}, ::Type{Int128}) = Int128

promote_rule(::Type{Uint64}, ::Type{Int8}  ) = Uint64
promote_rule(::Type{Uint64}, ::Type{Int16} ) = Uint64
promote_rule(::Type{Uint64}, ::Type{Int32} ) = Uint64
promote_rule(::Type{Uint64}, ::Type{Int64} ) = Uint64
promote_rule(::Type{Uint64}, ::Type{Int128}) = Int128

promote_rule(::Type{Uint128}, ::Type{Int8}  ) = Uint128
promote_rule(::Type{Uint128}, ::Type{Int16} ) = Uint128
promote_rule(::Type{Uint128}, ::Type{Int32} ) = Uint128
promote_rule(::Type{Uint128}, ::Type{Int64} ) = Uint128
promote_rule(::Type{Uint128}, ::Type{Int128}) = Uint128

## traits ##

typemin(::Type{Int8  }) = int8(-128)
typemax(::Type{Int8  }) = int8(127)
typemin(::Type{Uint8 }) = uint8(0)
typemax(::Type{Uint8 }) = uint8(255)
typemin(::Type{Int16 }) = int16(-32768)
typemax(::Type{Int16 }) = int16(32767)
typemin(::Type{Uint16}) = uint16(0)
typemax(::Type{Uint16}) = uint16(65535)
typemin(::Type{Int32 }) = int32(-2147483648)
typemax(::Type{Int32 }) = int32(2147483647)
typemin(::Type{Uint32}) = uint32(0)
typemax(::Type{Uint32}) = uint32(4294967295)
typemin(::Type{Int64 }) = -9223372036854775808
typemax(::Type{Int64 }) = 9223372036854775807
typemin(::Type{Uint64}) = uint64(0)
typemax(::Type{Uint64}) = 0xffffffffffffffff
@eval begin
    typemin(::Type{Uint128}) = uint128(0)
    typemax(::Type{Uint128}) = $(uint128(-1))
    typemin(::Type{Int128} ) = $(int128((uint128(-1))>>int32(1))+int128(1))
    typemax(::Type{Int128} ) = $(int128((uint128(-1))>>int32(1)))
end

sizeof(::Type{Int8})    = 1
sizeof(::Type{Uint8})   = 1
sizeof(::Type{Int16})   = 2
sizeof(::Type{Uint16})  = 2
sizeof(::Type{Int32})   = 4
sizeof(::Type{Uint32})  = 4
sizeof(::Type{Int64})   = 8
sizeof(::Type{Uint64})  = 8
sizeof(::Type{Int128})  = 16
sizeof(::Type{Uint128}) = 16

widen(::Type{Int8}) = Int
widen(::Type{Int16}) = Int
widen(::Type{Int32}) = Int64
widen(::Type{Int64}) = Int128
widen(::Type{Uint8}) = Uint
widen(::Type{Uint16}) = Uint
widen(::Type{Uint32}) = Uint64
widen(::Type{Uint64}) = Uint128

## float to integer coercion ##

# requires int arithmetic defined, for the loops to work

for f in (:int, :int8, :int16, :int32, :signed, :integer)
    @eval ($f)(x::FloatingPoint) = ($f)(iround(x))
end

for (f,t) in ((:uint8,:Uint8), (:uint16,:Uint16), (:uint32,:Uint32),
              (:int64,:Int64), (:uint64,:Uint64),
              (:int128,:Int128), (:uint128,:Uint128),
              (:unsigned,:Uint), (:uint,:Uint))
    @eval ($f)(x::FloatingPoint) = iround($t,x)
end

## wide multiplication, Int128 multiply and divide ##

if WORD_SIZE==32
    function widemul(u::Int64, v::Int64)
        local u0::Uint64, v0::Uint64, w0::Uint64
        local u1::Int64, v1::Int64, w1::Int64, w2::Int64, t::Int64

        u0 = u&0xffffffff; u1 = u>>32
        v0 = v&0xffffffff; v1 = v>>32
        w0 = u0*v0
        t = u1*v0 + (w0>>>32)
        w2 = t>>32
        w1 = u0*v1 + (t&0xffffffff)
        hi = u1*v1 + w2 + (w1 >> 32)
        lo = w0&0xffffffff + (w1 << 32)
        int128(hi)<<64 + int128(uint128(lo))
    end

    function widemul(u::Uint64, v::Uint64)
        local u0::Uint64, v0::Uint64, w0::Uint64
        local u1::Uint64, v1::Uint64, w1::Uint64, w2::Uint64, t::Uint64

        u0 = u&0xffffffff; u1 = u>>>32
        v0 = v&0xffffffff; v1 = v>>>32
        w0 = u0*v0
        t = u1*v0 + (w0>>>32)
        w2 = t>>>32
        w1 = u0*v1 + (t&0xffffffff)
        hi = u1*v1 + w2 + (w1 >>> 32)
        lo = w0&0xffffffff + (w1 << 32)
        uint128(hi)<<64 + uint128(lo)
    end

    function *(u::Int128, v::Int128)
        u0 = uint64(u); u1 = int64(u>>64)
        v0 = uint64(v); v1 = int64(v>>64)
        lolo = widemul(u0, v0)
        lohi = widemul(int64(u0), v1)
        hilo = widemul(u1, int64(v0))
        t = hilo + (lolo>>>64)
        w2 = t>>64
        w1 = lohi + (t&0xffffffffffffffff)
        int128(lolo&0xffffffffffffffff) + int128(w1)<<64
    end

    function *(u::Uint128, v::Uint128)
        u0 = uint64(u); u1 = uint64(u>>>64)
        v0 = uint64(v); v1 = uint64(v>>>64)
        lolo = widemul(u0, v0)
        lohi = widemul(u0, v1)
        hilo = widemul(u1, v0)
        t = hilo + (lolo>>>64)
        w2 = t>>>64
        w1 = lohi + (t&0xffffffffffffffff)
        (lolo&0xffffffffffffffff) + uint128(w1)<<64
    end

    div(x::Int128, y::Int128) = int128(div(BigInt(x),BigInt(y)))
    div(x::Uint128, y::Uint128) = uint128(div(BigInt(x),BigInt(y)))

    rem(x::Int128, y::Int128) = int128(rem(BigInt(x),BigInt(y)))
    rem(x::Uint128, y::Uint128) = uint128(rem(BigInt(x),BigInt(y)))

    mod(x::Int128, y::Int128) = int128(mod(BigInt(x),BigInt(y)))

    << (x::Int128,  y::Int32) = y == 0 ? x : box(Int128,shl_int(unbox(Int128,x),unbox(Int32,y)))
    << (x::Uint128, y::Int32) = y == 0 ? x : box(Uint128,shl_int(unbox(Uint128,x),unbox(Int32,y)))
    >> (x::Int128,  y::Int32) = y == 0 ? x : box(Int128,ashr_int(unbox(Int128,x),unbox(Int32,y)))
    >> (x::Uint128, y::Int32) = y == 0 ? x : box(Uint128,lshr_int(unbox(Uint128,x),unbox(Int32,y)))
    >>>(x::Int128,  y::Int32) = y == 0 ? x : box(Int128,lshr_int(unbox(Int128,x),unbox(Int32,y)))
    >>>(x::Uint128, y::Int32) = y == 0 ? x : box(Uint128,lshr_int(unbox(Uint128,x),unbox(Int32,y)))
else
    *(x::Int128,  y::Int128)  = box(Int128,mul_int(unbox(Int128,x),unbox(Int128,y)))
    *(x::Uint128, y::Uint128) = box(Uint128,mul_int(unbox(Uint128,x),unbox(Uint128,y)))

    div(x::Int128,  y::Int128)  = box(Int128,sdiv_int(unbox(Int128,x),unbox(Int128,y)))
    div(x::Uint128, y::Uint128) = box(Uint128,udiv_int(unbox(Uint128,x),unbox(Uint128,y)))

    rem(x::Int128,  y::Int128)  = box(Int128,srem_int(unbox(Int128,x),unbox(Int128,y)))
    rem(x::Uint128, y::Uint128) = box(Uint128,urem_int(unbox(Uint128,x),unbox(Uint128,y)))

    mod(x::Int128, y::Int128) = box(Int128,smod_int(unbox(Int128,x),unbox(Int128,y)))
end

## checked +, - and *

for T in (Int8,Int16,Int32,Int64)#,Int128) ## FIXME: #4905
    @eval begin
        checked_add(x::$T, y::$T) = box($T,checked_sadd(unbox($T,x),unbox($T,y)))
        checked_sub(x::$T, y::$T) = box($T,checked_ssub(unbox($T,x),unbox($T,y)))
    end
end
for T in (Int16,Int32)
    @eval begin
        checked_mul(x::$T, y::$T) = box($T,checked_smul(unbox($T,x),unbox($T,y)))
    end
end
for T in (Uint8,Uint16,Uint32,Uint64)#,Uint128) ## FIXME: #4905
    @eval begin
        checked_add(x::$T, y::$T) = box($T,checked_uadd(unbox($T,x),unbox($T,y)))
        checked_sub(x::$T, y::$T) = box($T,checked_usub(unbox($T,x),unbox($T,y)))
    end
end
for T in (Uint16,Uint32)
    @eval begin
        checked_mul(x::$T, y::$T) = box($T,checked_umul(unbox($T,x),unbox($T,y)))
    end
end

# checked mul is broken for 8-bit types (LLVM bug?) ## FIXME: #4905

for T in (Int8,Uint8)
    @eval function checked_mul(x::$T, y::$T)
        xy = x*y
        xy8 = convert($T,xy)
        xy == xy8 || throw(OverflowError())
        return xy8
    end
end

if WORD_SIZE == 32
for T in (Int64,Uint64)
    @eval function checked_mul(x::$T, y::$T)
        xy = int128(x)*int128(y)
        xy64 = convert($T,xy)
        xy == xy64 || throw(OverflowError())
        return xy64
    end
end
else
    checked_mul(x::Int64, y::Int64)   = box(Int64,checked_smul(unbox(Int64,x),unbox(Int64,y)))
    checked_mul(x::Uint64, y::Uint64) = box(Uint64,checked_umul(unbox(Uint64,x),unbox(Uint64,y)))
end

# checked ops are broken for 128-bit types (LLVM bug) ## FIXME: #4905

checked_add(x::Int128, y::Int128) = x + y
checked_sub(x::Int128, y::Int128) = x - y
checked_mul(x::Int128, y::Int128) = x * y

checked_add(x::Uint128, y::Uint128) = x + y
checked_sub(x::Uint128, y::Uint128) = x - y
checked_mul(x::Uint128, y::Uint128) = x * y

max_stars_repo_name: jakebolewski/julia

max_issues_repo_name: jakebolewski/julia

max_forks_repo_name: jakebolewski/julia


text:
struct Model{A,B,M<:GeneralizedGenerated.TypeLevel} <: AbstractModel{A,B,M}
    args :: Vector{Symbol}
    body :: Expr
end

function Model(theModule::Module, args::Vector{Symbol}, body::Expr)
    A = NamedTuple{Tuple(args)}

    B = to_type(body)
    M = to_type(theModule)
    return Model{A,B,M}(args, striplines(body))
end

model(m::Model) = m

# ModelClosure{A,B,M,Args,Obs} <: AbstractModel{A,B,M,Argvals,Obs}
#     model::Model{A,B,M}
#     argvals :: Argvals
#     obs :: Obs
# end

function Base.convert(::Type{Expr}, m::Model)
    numArgs = length(m.args)
    args = if numArgs == 1
       m.args[1]
    elseif numArgs > 1
        Expr(:tuple, [x for x in m.args]...)
    end

    body = m.body

    q = if numArgs == 0
        @q begin
            @model $body
        end
    else
        @q begin
            @model $(args) $body
        end
    end

    striplines(q).args[1]
end

Base.show(io::IO, m :: Model) = println(io, convert(Expr, m))

function type2model(::Type{Model{A,B,M}}) where {A,B,M}
    args = [fieldnames(A)...]
    body = from_type(B)
    Model(from_type(M), convert(Vector{Symbol},args), body)
end

# julia> using Tilde, MeasureTheory

# julia> m = @model begin
#        p ~ Uniform()
#        x ~ Bernoulli(p) |> iid(3)
#        end;

# julia> f = interpret(m);

# julia> f(NamedTuple()) do x,d,ctx
#            r = rand(d)
#            (r, merge(ctx, NamedTuple{(x,)}((r,))))
#        end
# (p = 0.3863623559358842, x = Bool[0, 0, 0])

# julia> f(0) do x,d,n
#            r = rand(d)
#            (r, n+1)
#        end
# 2

# julia> f
# function = (_tilde, _ctx0;) -> begin
#     begin
#         _ctx = _ctx0
#         (p, _ctx) = _tilde(:p, (Main).Uniform(), _ctx)
#         (x, _ctx) = _tilde(:x, (Main).:|>((Main).Bernoulli(p), (Main).iid(3)), _ctx)
#         return _ctx
#     end
# end


text:
"""The module provides the Message type that bundles signals.
"""
module Messages
import Base
import ..Signals

"""
    Message

Messages model bundles of signals and enable the decoding of multiple signals. Additionally,
messages are defined using the number of bytes (`dlc`), a message name (`name`), and the
internal signals (`signals`).

# Fields
- `dlc::UInt8`: the number of required bytes
- `name::String`: the name of the message
- `signals::Dict{String, Signals.NamedSignal}`: a mapping of string
"""
mutable struct Message
    frame_id::UInt32
    dlc::UInt8
    name::String
    signals::Dict{String, Signals.NamedSignal}

    function Message(frame_id::UInt32, dlc::UInt8, name::String,
                     signals::Dict{String, Signals.NamedSignal}; strict::Bool=false)
        if name == ""
            throw(DomainError(name, "name cannot be the empty string"))
        end

        if strict
            e1 = enumerate(values(signals))
            l = [Signals.overlap(v1,v2) for (i,v1) in e1 for (j,v2) in e1 if i < j]
            do_overlap = any(l)
            if do_overlap
                throw(DomainError(do_overlap, "signals overlap"))
            end

            for signal in values(signals)
                is_ok = Signals.check(signal, dlc)
                if !is_ok
                        throw(DomainError(is_ok, "not enough data"))
                end
            end
        end

        return new(frame_id, dlc, name, signals)
    end
end

function Message(frame_id::Integer, dlc::Integer, name::String,
                 signals::Signals.NamedSignal...; strict::Bool=false)
    frame_id = convert(UInt32, frame_id)
    dlc = convert(UInt8, dlc)

    sigs = Dict{String, Signals.NamedSignal}()
    for signal in signals
        signal_name = Signals.name(signal)
        if get(sigs, signal_name, nothing) != nothing
            throw(DomainError(signal_name, "signal with same name already defined"))
        else
            sigs[signal_name] = signal
        end
    end

    return Message(frame_id, dlc, name, sigs; strict=strict)
end

"""
"""
function frame_id(message::Message)::UInt32
    return message.frame_id & 0x7F_FF_FF_FF
end

"""
    dlc(message::Message) -> UInt8

Returns the number of bytes that the message requires and operates on.

# Arguments
- `message::Message`: the message
"""
function dlc(message::Message)::UInt8
    return message.dlc
end

"""
    name(message::Message) -> String

Returns the message name.

# Arguments
- `message::Message`: the message
"""
function name(message::Message)::String
    return message.name
end

"""
    Base.getindex(message::Message, index::String) -> Signals.NamedSignal

Returns the signal with the name `index` inside `message`.

# Arguments
- `message::Message`: the message
- `index::String`: the index, i.e., the name of the signal we want to retrieve

# Throws
- `KeyError`: the signal with the name `index` does not exist inside `message`
"""
function Base.getindex(message::Message, index::String)::Signals.NamedSignal
    return message.signals[index]
end

"""
    Base.get(message::Message, key::String, default)

Returns the signal with the name `key` inside `message` if a signal with such a name
exists, otherwise we return `default`.

# Arguments
- `message::Message`: the message
- `key::String`: the index, i.e., the name of the signal we want to retrieve
- `default`: a default value
"""
function Base.get(message::Message, key::String, default)
    return get(message.signals, key, default)
end

"""
    Base.iterate(iter::Message)

Enables the iteration over the inside dictionary `signals`.

# Arguments
- `iter::Message`: the message
"""
function Base.iterate(iter::Message)
    return iterate(iter.signals)
end

"""
    Base.iterate(iter::Message, state)

Enables the iteration over the inside dictionary `signals`.

# Arguments
- `iter::Message`: the message
- `state`: the state of the iterator
"""
function Base.iterate(iter::Message, state)
    return iterate(iter.signals, state)
end

export Message, frame_id, dlc, name
end


text:
module Memoize
export @memoize

macro memoize(f)

    argnames, argtypes = begin
        root = f.args[1]

        while root.head!=:call
            root = root.args[1]
        end

        args = root.args[2:length(root.args)]

        args, map(ex->typeof(ex)==Expr ? ex.args[2] : :Any, args)
    end

    fname, ftype = begin
        root = f.args[1]
        fname, ftype = :Symbol, :Symbol
        while root.head!=:call
            if root.head == :(::)

                ftype = root.args[2]
            end
            root = root.args[1]
        end
        fname = root.args[1]

        insert!(
            root.args,
            2,
            Expr(
                :parameters,
                Expr(
                    :kw,
                    :memo,
                    Expr(
                        :call,
                        Expr(
                            :curly,
                            :Dict,
                            Expr(
                                :curly,
                                :Tuple,
                                argtypes...
                                ),
                            ftype
                            )
                        )
                    )
                )
        )
        fname, ftype
    end

    f.args[2] = begin
        root = f.args[2]

        stack=[root]
        while !isempty(stack)
            root = pop!(stack)
            if typeof(root)==Expr
                if root.args[1] == fname
                    push!(root.args, Expr(:kw, :memo, :memo))
                end

                nodes=filter(ex->typeof(ex)==Expr, root.args)

                while !isempty(nodes)
                    push!(stack, pop!(nodes))
                end
            end
        end

        f.args[2]
    end

    f.args[2] =
    :(
        let args=tuple($(argnames...))
            if haskey(memo, args)
                memo[args]
            else
                get!(memo, args, $(f.args[2]))
            end
        end
    )

    @eval $f

end
end


text:
abstract type ArrowVector{T} <: AbstractVector{T} end

Base.IndexStyle(::Type{A}) where {A <: ArrowVector} = Base.IndexLinear()

struct ValidityBitmap <: ArrowVector{Bool}
    bytes::Vector{UInt8} # arrow memory blob
    pos::Int # starting byte of validity bitmap
    ℓ::Int # # of _elements_ (not bytes!) in bitmap (because bitpacking)
end

Base.size(p::ValidityBitmap) = (p.ℓ,)

@propagate_inbounds function Base.getindex(p::ValidityBitmap, i::Integer)
    # no boundscheck because parent array should do it
    # if a validity bitmap is empty, it either means:
    #   1) the parent array null_count is 0, so all elements are valid
    #   2) parent array is also empty, so "all" elements are valid
    p.ℓ == 0 && return true
    # translate element index to bitpacked byte index
    a, b = fldmod1(i, 8)
    @inbounds byte = p.bytes[p.pos + a - 1]
    # check individual bit of byte
    return getbit(byte, b)
end

@propagate_inbounds function Base.setindex!(p::ValidityBitmap, v, i::Integer)
    x = convert(Bool, v)
    p.ℓ == 0 && !x && throw(ArgumentError(o0))
    a, b = fldmod1(i, 8)
    @inbounds byte = p.bytes[p.pos + a - 1]
    @inbounds p.bytes[p.pos + a - 1] = setbit(byte, convert(Bool, v), b)
    v
end

struct Primitive{T, S} <: ArrowVector{T}
    validity::ValidityBitmap
    data::Vector{S}
    ℓ::Int
end

Base.size(p::Primitive) = (p.ℓ,)

@propagate_inbounds function Base.getindex(p::Primitive{T, S}, i::Integer) where {T, S}
    @boundscheck checkbounds(p, i)
    if T !== S
        return p.validity[i] ? p.data[i] : missing
    else
        return p.data[i]
    end
end

struct Offsets{T <: Union{Int32, Int64}} <: ArrowVector{Tuple{T, T}}
    offsets::Vector{T}
end

Base.size(o::Offsets) = (length(o.offsets) - 1,)

@propagate_inbounds function Base.getindex(o::Offsets, i::Integer)
    @boundscheck checkbounds(o, i)
    @inbounds lo = o.offsets[i] + 1
    @inbounds hi = o.offsets[i + 1]
    return lo, hi
end

struct List{T, O, A <: AbstractVector} <: ArrowVector{T}
    validity::ValidityBitmap
    offsets::Offsets{O}
    data::A
    ℓ::Int
end

Base.size(l::List) = (l.ℓ,)

@propagate_inbounds function Base.getindex(l::List{T}, i::Integer) where {T}
    @boundscheck checkbounds(l, i)
    @inbounds lo, hi = l.offsets[i]
    if T === Union{String, Missing}
        return l.validity[i] ? unsafe_string(pointer(l.data, lo), hi - lo + 1) : missing
    elseif T === String
        return unsafe_string(pointer(l.data, lo), hi - lo + 1)
    elseif Base.nonmissingtype(T) !== T
        return l.validity[i] ? l.data[lo:hi] : missing
    else
        return l.data[lo:hi]
    end
end

struct FixedSizeList{T, A <: AbstractVector} <: ArrowVector{T}
    validity::ValidityBitmap
    data::A
    ℓ::Int
end

Base.size(l::FixedSizeList) = (l.ℓ,)
getn(::Type{NTuple{N, T}}) where {N, T} = N

@propagate_inbounds function Base.getindex(l::FixedSizeList{T}, i::Integer) where {T}
    @boundscheck checkbounds(l, i)
    N = getn(Base.nonmissingtype(T))
    off = (i - 1) * N
    if Base.nonmissingtype(T) !== T
        return l.validity[i] ? ntuple(j->l.data[off + j], N) : missing
    else
        return ntuple(j->l.data[off + j], N)
    end
end

struct Map{K, V, A, B} <: ArrowVector{Pair{K, V}}
    keys::A
    values::B
end

Base.size(m::Map) = size(m.keys)
Base.keytype(::Type{Map{K, V, A, B}}) where {K, V, A, B} = K
Base.valtype(::Type{Map{K, V, A, B}}) where {K, V, A, B} = V

_keytype(::Type{T}) where {T} = keytype(T)
_valtype(::Type{T}) where {T} = valtype(T)
_keytype(::Pair{K, V}) where {K, V} = K
_valtype(::Pair{K, V}) where {K, V} = V
_keytype(::Type{Pair{K, V}}) where {K, V} = K
_valtype(::Type{Pair{K, V}}) where {K, V} = V

@propagate_inbounds function Base.getindex(m::Map, i::Integer)
    @boundscheck checkbounds(m, i)
    return m.keys[i] => m.values[i]
end

struct Struct{T, S} <: ArrowVector{T}
    validity::ValidityBitmap
    data::S # Tuple of ArrowVector
    ℓ::Int
end

Base.size(s::Struct) = (s.ℓ,)
getn(::Type{NamedTuple{names, T}}) where {names, T} = length(names)

@propagate_inbounds function Base.getindex(s::Struct{T}, i::Integer) where {T}
    @boundscheck checkbounds(s, i)
    NT = Base.nonmissingtype(T)
    if NT !== T
        return s.validity[i] ? NT(ntuple(j->s.data[j][i], getn(NT))) : missing
    else
        return NT(ntuple(j->s.data[j][i], getn(NT)))
    end
end

struct DenseUnion{T, S} <: ArrowVector{T}
    typeIds::Vector{UInt8}
    offsets::Vector{Int32}
    data::S # Tuple of ArrowVector
end

Base.size(s::DenseUnion) = size(s.typeIds)

@propagate_inbounds function Base.getindex(s::DenseUnion{T}, i::Integer) where {T}
    @boundscheck checkbounds(s, i)
    @inbounds typeId = s.typeIds[i]
    @inbounds off = s.offsets[i]
    @inbounds x = s.data[typeId + 1][off + 1]
    return x
end

struct SparseUnion{T, S} <: ArrowVector{T}
    typeIds::Vector{UInt8}
    data::S # Tuple of ArrowVector
end

Base.size(s::SparseUnion) = size(s.typeIds)

@propagate_inbounds function Base.getindex(s::SparseUnion{T}, i::Integer) where {T}
    @boundscheck checkbounds(s, i)
    @inbounds typeId = s.typeIds[i]
    @inbounds x = s.data[typeId + 1][i]
    return x
end

struct DictEncoding{T, A} <: ArrowVector{T}
    id::Int64
    data::ChainedVector{T, A}
    isOrdered::Bool
end

Base.size(d::DictEncoding) = size(d.data)

@propagate_inbounds function Base.getindex(d::DictEncoding, i::Integer)
    @boundscheck checkbounds(d, i)
    @inbounds x = d.data[i]
    return x
end

struct DictEncoded{T, S} <: ArrowVector{T}
    validity::ValidityBitmap
    indices::Vector{S}
    encoding::DictEncoding
end

Base.size(d::DictEncoded) = size(d.indices)

@propagate_inbounds function Base.getindex(d::DictEncoded{T}, i::Integer) where {T}
    @boundscheck checkbounds(d, i)
    @inbounds valid = d.validity[i]
    !valid && return missing
    @inbounds idx = d.indices[i]
    return d.encoding[idx + 1]
end


text:
# ---
# title: 6. ZigZag Conversion
# id: problem6
# author: Tian Jun
# date: 2020-10-31
# difficulty: Medium
# categories: String
# link: <https://leetcode.com/problems/zigzag-conversion/description/>
# hidden: true
# ---
#
# The string `"PAYPALISHIRING"` is written in a zigzag pattern on a given number
# of rows like this: (you may want to display this pattern in a fixed font for
# better legibility)
#
#
#
#     P   A   H   N
#     A P L S I I G
#     Y   I   R
#
#
# And then read line by line: `"PAHNAPLSIIGYIR"`
#
# Write the code that will take a string and make this conversion given a number
# of rows:
#
#
#
#     string convert(string s, int numRows);
#
#
#
#
# **Example 1:**
#
#
#
#     Input: s = "PAYPALISHIRING", numRows = 3
#     Output: "PAHNAPLSIIGYIR"
#
#
# **Example 2:**
#
#
#
#     Input: s = "PAYPALISHIRING", numRows = 4
#     Output: "PINALSIGYAHRPI"
#     Explanation:
#     P     I    N
#     A   L S  I G
#     Y A   H R
#     P     I
#
#
# **Example 3:**
#
#
#
#     Input: s = "A", numRows = 1
#     Output: "A"
#
#
#
#
# **Constraints:**
#
#   * `1 <= s.length <= 1000`
#   * `s` consists of English letters (lower-case and upper-case), `','` and `'.'`.
#   * `1 <= numRows <= 1000`
#
#
## @lc code=start
using LeetCode

function zig_zag_convert(s::String, num_rows::Int)::String
    if num_rows == 1 || num_rows >= length(s)
        s
    else
        table = [Char[] for _ in 1:num_rows]
        i, dir = 1, 1
        for x in s
            push!(table[i], x)
            if i == 1
                dir = 1
            elseif i == num_rows
                dir = -1
            end
            i += dir
        end
        join(Iterators.flatten(table))
    end
end
## @lc code=end


text:
import Pkg; Pkg.activate(@__DIR__)

using ClusterTrees
using StaticArrays
using CompScienceMeshes

const P = SVector{3,Float64}

mesh = meshsphere(1.0, 0.04)
# points = [rand(P) for i in 1:800]
points = vertices(mesh)
points = [cartesian(CompScienceMeshes.center(chart(mesh, c))) for c in cells(mesh)]

root_center = P(0,0,0)
root_size = 1.0
tree = ClusterTrees.LevelledTrees.LevelledTree(root_center, root_size, Int[])

smallest_box_size = 1.0 / 2.0^10
for i in 1:length(points)
    destination = (smallest_box_size = smallest_box_size, target_point = points[i])
    root_state = ClusterTrees.LevelledTrees.rootstate(tree, destination)
    ClusterTrees.update!(tree, root_state, i, destination) do tree, node, data
        push!(ClusterTrees.data(tree,node).values, data)
    end
end

num_bins = 7
bins = [P[] for i in 1:num_bins]

num_printed = 0
num_points = 0
num_nodes = length(tree.nodes)
for (i,node) in enumerate(ClusterTrees.DepthFirstIterator(tree, root(tree)))
    b = div((i-1)*num_bins, num_nodes) + 1
    append!(bins[b], points[ClusterTrees.data(tree,node).values])
    global num_printed += 1
    global num_points += length(data(tree,node).values)
end

ordered_points = reduce(append!, bins)
ordered_points = [p[i] for p in ordered_points, i = 1:3]
@assert num_printed == length(tree.nodes)
@show num_points
@show length(points)
@assert num_points == length(points)

num_points = 0
ordered_points = P[]
for b in ClusterTrees.LevelledTrees.LevelIterator(tree, length(tree.levels))
    global num_points += length(ClusterTrees.data(tree,b).values)
    append!(ordered_points, points[ClusterTrees.data(tree,b).values])
end
@assert num_points == length(points)

using Plots
plot()
for i in 1:length(bins)
    x = getindex.(bins[i],1)
    y = getindex.(bins[i],2)
    z = getindex.(bins[i],3)
    scatter!(x,y,z)
end
plot!(legend=false)


text:
using QIntegrations, Test

@testset "QIntegrations" begin

#@test scipy_quad((x)->x,0,1)[1] == 0.5
res = integrate_1d((x)->exp(-2*x),0,1)
@test isapprox(res[1], (1-exp(-2))/2, atol=1e-8, rtol=1e-6)
res = integrate_1d((x)->exp(-2*x),0,Inf)
@test isapprox(res[1], 0.5, atol=1e-8, rtol=1e-6)
res = integrate_1d((x)->exp(-x^2),-Inf,Inf)
@test isapprox(res[1], sqrt(pi), atol=1e-8, rtol=1e-6)

end


text:
module RobustLeastSquares

using StatsBase
using IterativeSolvers
using Logging
using LinearAlgebra
using SparseArrays

export reweighted_lsqr, refit_estimator

export MEstimator, L2Estimator, L1Estimator, L1L2Estimator, HuberEstimator, FairEstimator, CauchyEstimator, GemanEstimator, WelschEstimator,  TukeyEstimator, MultiEstimator
export estimator_rho, estimator_psi, estimator_weight, estimator_sqrtweight

include("MEstimators.jl")

function solve(A,b,weights=ones(length(b)),method=:qr,x0=nothing)
    if method == :qr
        return (Diagonal(weights) * A) \ (weights.*b)
        # this works for sparse matrices:
        #return Base.LinAlg.SparseMatrix.SPQR.solve(0,qrfact(sparse(spdiagm(weights)*A)),Base.LinAlg.SparseMatrix.CHOLMOD.Dense(spdiagm(weights)*b))
    elseif method == :normal
        return (A' * (Diagonal(weights.^2) * A)) \ (A' * (weights .^ 2 .*b))
    elseif method == :cg
        # Use a conjugate gradient method to find the solution (less memory)
        if x0 == nothing
            x0 = zeros(size(A,2))
        end
        sol = lsqr!(x0, Diagonal(weights) * A, weights.*b)
        return sol
    else
        error("Method :$method should have been one of :qr, :normal or :cg")
    end
end

"""
(sol,res) = reweighted_lsqr(sol::AbstractVector, A::AbstractMatrix,b::AbstractVector,estimator::MEstimator = L2Estimator,useqr::Type = Val{true}; n_iter=10)

Solves a reweighted least squares problem: min ∑ᵢ ρ((A*sol - b)ᵢ) using the specified MEstimator for ρ and starting with sol (for initial weights).
"""
function reweighted_lsqr(A::AbstractMatrix,b::AbstractVector,estimator::MEstimator = L2Estimator(), x0 = nothing;method::Symbol=:qr, n_iter::Integer=10, refit::Bool = false, quiet::Bool = false, kwargs...)
    local sol, res, weights

    s1,s2 = size(A)
    if s1 == s2
        warn("Encountered square matrix of size $s1. Julia will revert to linear solvers instead of least-square solvers, and throw an error if the matrix is singular.")
    end

    # Set the initial weights
    if x0 === nothing
        weights = fill(1, size(b))
    else
        res = A*x0 - b
        if refit
            weights = estimator_sqrtweight(res, refit_estimator(estimator, res, 3.0))
        else
            weights = estimator_sqrtweight(res, estimator)
        end
    end

    # Perform the reweighted least squares
    if issparse(A)
        quiet || @info "Solving a $(size(A)) reweighted least-squares problem. $(typeof(A)) matrix has $(nnz(A)) non-zero elements. Using $method method."
    else
        quiet || @info "Solving a $(size(A)) reweighted least-squares problem with a $(typeof(A)). Using $method method."
    end

    for i=1:n_iter
        if i == 1
            sol = solve(A,b,weights,method,x0)
        else
            sol = solve(A,b,weights,method,sol)
        end
        res = A*sol - b

        if refit
            weights = estimator_sqrtweight(res, refit_estimator(estimator,res,3.0))
        else
            weights = estimator_sqrtweight(res, estimator)
        end

        quiet || @info "Iteration $i, RMS residual $(sqrt(sum(res.*res)/length(res)))))"
    end

    quiet || @info "Root-mean-square weighted residual error = $(sqrt(sum(res.^2)/length(res)))"

    return (sol,res,weights)
end

end # module


text:
include(joinpath(pwd(), "src/direct_policy_optimization/problem.jl"))
include(joinpath(pwd(), "src/direct_policy_optimization/objective.jl"))
include(joinpath(pwd(), "src/direct_policy_optimization/dynamics.jl"))
include(joinpath(pwd(), "src/direct_policy_optimization/policy.jl"))
include(joinpath(pwd(), "src/direct_policy_optimization/disturbances.jl"))

max_issues_repo_name: zacmanchester/DirectMotionPlanning

max_forks_repo_name: zacmanchester/DirectMotionPlanning


text:
"
Working Examples for this module
"
############################################################################################
#Import
include("utility/utility.jl")
include("Metropolis/Metropolis.jl")
include("MALA/MALA.jl")
include("HMC/HMC.jl")
include("NUTS/NUTS.jl")
#!NOTE: A kernel that ignores MCMC tuning and explicitly takes user proposal distribution.
include("Custom/Custom.jl")

############################################################################################
#Export ~ All MCMC algorithm need to be dispatched on the following functions:
export update!, init, propagate, get_acceptrate


text:
if VERSION < VersionNumber("1.0.0")
	using Base.Test
else
	using Test
end

@testset "First Delaunay Wall Simplex" begin

	P = [
		1.0 1.0 1.5 2.0 2.0
		0.0 0.2 1.3 1.0 1.0
		2.0 0.0 0.0 1.0 0.5
	]

	axis = 1
	off = AlphaStructures.findMedian(P, axis)
	@test sort(AlphaStructures.firstDeWallSimplex(P, axis, off)) == [1, 2, 3, 4]

	axis = 2
	off = AlphaStructures.findMedian(P, axis)
	@test sort(AlphaStructures.firstDeWallSimplex(P, axis, off)) == [2, 3, 4, 5]

	axis = 3
	off = AlphaStructures.findMedian(P, axis)
	@test sort(AlphaStructures.firstDeWallSimplex(P, axis, off)) == [2, 3, 4, 5]

end

@testset "Find Wall Simplex" begin

	@testset "2D wall simplex" begin
		P = [ 0. 1. 0  1    2.;
		 	  0  0  1. 0.2  2.;
		 	]

		@test AlphaStructures.findWallSimplex(P, [2,3], [0., 0.]; DEBUG = true) == nothing
		@test AlphaStructures.findWallSimplex(P, [1,2], [0.,1.]) == nothing
		@test AlphaStructures.findWallSimplex(P, [4,3], [0.,0.]) == [3,4,5]
	end

	@testset "3D wall simplex" begin
		P = [ 0. 1. 0  0  2.;
			  0  0  1. 0  2.;
			  0  0  0  1. 2.]
		@test AlphaStructures.findWallSimplex(P, [2,3,4], [0., 0., 0.]; DEBUG = true) == [2,3,4,5]
		@test AlphaStructures.findWallSimplex(P, [2,3,5], [0., 0., 1.]) == nothing
		@test AlphaStructures.findWallSimplex(P, [2,3,4], [2., 2., 2.])  == [1,2,3,4]
		@test AlphaStructures.findWallSimplex(P, [2,3,4], [0., 0., 0.], 1, DEBUG = true) == nothing
	end

end

@testset "Delaunay Wall" begin

	@testset "one tetrahedron" begin
		P = [
			0.0 1.0 0.0 0.0
			0.0 0.0 1.0 0.0
			0.0 0.0 0.0 1.0
		];
		DT = sort(AlphaStructures.delaunayWall(P, 1))
		@test DT == [ [1, 2, 3, 4] ]
		@test sort(AlphaStructures.delaunayWall(P, 2)) == DT
		@test sort(AlphaStructures.delaunayWall(P, 3)) == DT
	end

	@testset "two tetrahedron" begin
		P = [
			0.0 1.0 0.0 0.0 2.0
			0.0 0.0 1.0 0.0 0.0
			0.0 0.0 0.0 1.0 0.0
		];
		DT = sort(AlphaStructures.delaunayWall(P, 1))
		@test DT == [ [1, 2, 3, 4], [2, 3, 4, 5] ]
		@test sort(AlphaStructures.delaunayWall(P, 2)) == DT
		@test sort(AlphaStructures.delaunayWall(P, 3)) == DT
	end

	@testset "points on a plane" begin
		P = [
			0.0 0.0 0.0 0.0 0.0
			2.0 0.0 1.0 0.0 2.0
			0.0 0.0 0.0 1.0 2.0
		];
	 	@test_throws AssertionError AlphaStructures.delaunayWall(P, 1)
		@test_throws AssertionError AlphaStructures.delaunayWall(P, 2)
		@test_throws AssertionError AlphaStructures.delaunayWall(P, 3)
	end

	@testset "cube" begin
		P = [
			0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
			0.0 0.0 1.0 1.0 0.0 0.0 1.0 1.0
			0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
		];
		DT = sort(AlphaStructures.delaunayWall(P, 1))
		@test length(DT) == 6
		@test DT == sort(AlphaStructures.delaunayWall(P, 2))
	end

end


text:
module GroupFFT

using Combinatorics, Groups

export
    fft

include("fft_O3.jl")
include("fft_symmetric_group.jl")

end