text:
import Core: Expr

# Terminals
function julia_normalization_map(c::Int32, x::Ptr{Nothing})::Int32
    return c == 0x00B5 ? 0x03BC : # micro sign -> greek small letter mu
           c == 0x025B ? 0x03B5 : # latin small letter open e -> greek small letter
           c
end

# Note: This code should be in julia base
function utf8proc_map_custom(str::String, options, func)
    norm_func = @cfunction $func Int32 (Int32, Ptr{Nothing})
    nwords = ccall(:utf8proc_decompose_custom, Int, (Ptr{UInt8}, Int, Ptr{UInt8}, Int, Cint, Ptr{Nothing}, Ptr{Nothing}),
                   str, sizeof(str), C_NULL, 0, options, norm_func, C_NULL)
    nwords < 0 && Base.Unicode.utf8proc_error(nwords)
    buffer = Base.StringVector(nwords * 4)
    nwords = ccall(:utf8proc_decompose_custom, Int, (Ptr{UInt8}, Int, Ptr{UInt8}, Int, Cint, Ptr{Nothing}, Ptr{Nothing}),
                   str, sizeof(str), buffer, nwords, options, norm_func, C_NULL)
    nwords < 0 && Base.Unicode.utf8proc_error(nwords)
    nbytes = ccall(:utf8proc_reencode, Int, (Ptr{UInt8}, Int, Cint), buffer, nwords, options)
    nbytes < 0 && Base.Unicode.utf8proc_error(nbytes)
    return String(resize!(buffer, nbytes))
end

function normalize_julia_identifier(str::AbstractString)
    options = Base.Unicode.UTF8PROC_STABLE | Base.Unicode.UTF8PROC_COMPOSE
    utf8proc_map_custom(String(str), options, julia_normalization_map)
end

function sized_uint_literal(s::AbstractString, b::Integer)
    # We know integers are all ASCII, so we can use sizeof to compute
    # the length of ths string more quickly
    l = (sizeof(s) - 2) * b
    l <= 8   && return Base.parse(UInt8,   s)
    l <= 16  && return Base.parse(UInt16,  s)
    l <= 32  && return Base.parse(UInt32,  s)
    l <= 64  && return Base.parse(UInt64,  s)
    # l <= 128 && return Base.parse(UInt128, s)
    l <= 128 && return Expr(:macrocall, GlobalRef(Core, Symbol("@uint128_str")), nothing, s)
    return Base.parse(BigInt, s)
end

function sized_uint_oct_literal(s::AbstractString)
    s[3] == 0 && return sized_uint_literal(s, 3)
    len = sizeof(s)
    (len < 5  || (len == 5  && s <= "0o377")) && return Base.parse(UInt8, s)
    (len < 8  || (len == 8  && s <= "0o177777")) && return Base.parse(UInt16, s)
    (len < 13 || (len == 13 && s <= "0o37777777777")) && return Base.parse(UInt32, s)
    (len < 24 || (len == 24 && s <= "0o1777777777777777777777")) && return Base.parse(UInt64, s)
    # (len < 45 || (len == 45 && s <= "0o3777777777777777777777777777777777777777777")) && return Base.parse(UInt128, s)
    # return Base.parse(BigInt, s)
    (len < 45 || (len == 45 && s <= "0o3777777777777777777777777777777777777777777")) && return Expr(:macrocall, GlobalRef(Core, Symbol("@uint128_str")), nothing, s)
    return Meta.parse(s)
end

function _literal_expr(x)
    if kindof(x) == Tokens.TRUE
        return true
    elseif kindof(x) == Tokens.FALSE
        return false
    elseif is_nothing(x)
        return nothing
    elseif kindof(x) == Tokens.INTEGER || kindof(x) == Tokens.BIN_INT || kindof(x) == Tokens.HEX_INT || kindof(x) == Tokens.OCT_INT
        return Expr_int(x)
    elseif kindof(x) == Tokens.FLOAT
        return Expr_float(x)
    elseif kindof(x) == Tokens.CHAR
        return Expr_char(x)
    elseif kindof(x) == Tokens.MACRO
        return Symbol(valof(x))
    elseif kindof(x) == Tokens.STRING
        return valof(x)
    elseif kindof(x) == Tokens.TRIPLE_STRING
        return valof(x)
    elseif kindof(x) == Tokens.CMD
        return Expr_cmd(x)
    elseif kindof(x) == Tokens.TRIPLE_CMD
        return Expr_tcmd(x)
    end
end

const TYPEMAX_INT64_STR = string(typemax(Int))
const TYPEMAX_INT128_STR = string(typemax(Int128))
function Expr_int(x)
    is_hex = is_oct = is_bin = false
    val = replace(valof(x), "_" => "")
    if sizeof(val) > 2 && val[1] == '0'
        c = val[2]
        c == 'x' && (is_hex = true)
        c == 'o' && (is_oct = true)
        c == 'b' && (is_bin = true)
    end
    is_hex && return sized_uint_literal(val, 4)
    is_oct && return sized_uint_oct_literal(val)
    is_bin && return sized_uint_literal(val, 1)
    # sizeof(val) <= sizeof(TYPEMAX_INT64_STR) && return Base.parse(Int64, val)
    return Meta.parse(val)
    # # val < TYPEMAX_INT64_STR && return Base.parse(Int64, val)
    # sizeof(val) <= sizeof(TYPEMAX_INTval < TYPEMAX_INT128_STR128_STR) && return Base.parse(Int128, val)
    # # val < TYPEMAX_INT128_STR && return Base.parse(Int128, val)
    # Base.parse(BigInt, val)
end

function Expr_float(x)
    if !startswith(valof(x), "0x") && 'f' in valof(x)
        return Base.parse(Float32, replace(valof(x), 'f' => 'e'))
    end
    Base.parse(Float64, replace(valof(x), "_" => ""))
end
function Expr_char(x)
    val = _unescape_string(valof(x)[2:prevind(valof(x), sizeof(valof(x)))])
    # one byte e.g. '\xff' maybe not valid UTF-8
    # but we want to use the raw value as a codepoint in this case
    sizeof(val) == 1 && return Char(codeunit(val, 1))
    length(val) == 1 || error("Invalid character literal: $(Vector{UInt8}(valof(x)))")
    val[1]
end

# Expressions

# Fallback
function Expr(x::EXPR)
    if isidentifier(x)
        return Symbol(normalize_julia_identifier(valof(x)))
    elseif iskw(x)
        if kindof(x) == Tokens.BREAK
            return Expr(:break)
        elseif kindof(x) == Tokens.CONTINUE
            return Expr(:continue)
        else
            return Symbol(lowercase(string(kindof(x))))
        end
    elseif isoperator(x)
        ret = x.val isa String ? Symbol(valof(x)) : UNICODE_OPS_REVERSE[kindof(x)]
        return x.dot ? Symbol(:., ret) : ret
    elseif ispunctuation(x)
        return string(kindof(x))
    elseif isliteral(x)
        return _literal_expr(x)
    elseif typof(x) === UnaryOpCall
        return _unary_expr(x)
    elseif typof(x) === BinaryOpCall
        return _binary_expr(x)
    elseif typof(x) === WhereOpCall
        return _where_expr(x)
    elseif typof(x) === ConditionalOpCall
        return Expr(:if, Expr(x.args[1]), Expr(x.args[3]), Expr(x.args[5]))
    elseif typof(x) === ErrorToken
        ret = Expr(:error)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === ChainOpCall
        ret = Expr(:call, Expr(x.args[2]))
        for i = 1:length(x.args)
            if isodd(i)
                push!(ret.args, Expr(x.args[i]))
            end
        end
        return ret
    elseif typof(x) === Comparison
        ret = Expr(:comparison)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === ColonOpCall
        return Expr(:call, :(:), Expr(x.args[1]), Expr(x.args[3]), Expr(x.args[5]))
    elseif typof(x) === TopLevel
        ret = Expr(:toplevel)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === MacroName
        if isidentifier(x.args[2])
            if valof(x.args[2]) == "."
                return Symbol("@", "__dot__")
            else
                return Symbol("@", valof(x.args[2]))
            end
        elseif isoperator(x.args[2])
            return Symbol("@", Expr(x.args[2]))

        else
            return Symbol("@")
        end
    elseif typof(x) === MacroCall
        ret = Expr(:macrocall)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        insert!(ret.args, 2, nothing)
        if ret.args[1] isa Expr && ret.args[1].head == :. && string(ret.args[1].args[2].value)[1] != '@'
            clear_at!(ret.args[1])
            ret.args[1].args[2] = QuoteNode(Symbol(string('@', ret.args[1].args[2].value)))
        end
        ret
    elseif typof(x) === x_Str
        if typof(x.args[1]) === BinaryOpCall && issyntaxcall(x.args[1].args[2])
            mname = Expr(x.args[1])
            mname.args[2] = QuoteNode(Symbol("@", mname.args[2].value, "_str"))
            ret = Expr(:macrocall, mname, nothing)
        else
            ret = Expr(:macrocall, Symbol("@", valof(x.args[1]), "_str"), nothing)
        end
        for i = 2:length(x.args)
            push!(ret.args, valof(x.args[i]))
        end
        return ret
    elseif typof(x) === x_Cmd
        ret = Expr(:macrocall, Symbol("@", valof(x.args[1]), "_cmd"), nothing)
        for i = 2:length(x.args)
            push!(ret.args, valof(x.args[i]))
        end
        return ret
    elseif typof(x) === Quotenode
        return QuoteNode(Expr(x.args[end]))
    elseif typof(x) === Call
        if kindof(x.args[1]) === Tokens.ISSUBTYPE || kindof(x.args[1]) === Tokens.ISSUPERTYPE
            ret = Expr(Expr(x.args[1]))
            for i in 2:length(x.args)
                a = x.args[i]
                if typof(a) === Parameters
                    insert!(ret.args, 2, Expr(a))
                elseif !(ispunctuation(a))
                    push!(ret.args, Expr(a))
                end
            end
            return ret
        end
        ret = Expr(:call)
        for a in x.args
            if typof(a) === Parameters
                insert!(ret.args, 2, Expr(a))
            elseif !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Braces
        ret = Expr(:braces)
        for a in x.args
            if typof(a) === Parameters
                insert!(ret.args, 1, Expr(a))
            elseif !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === BracesCat
        ret = Expr(:bracescat)
        for a in x.args
            if typof(a) === Parameters
                insert!(ret.args, 1, Expr(a))
            elseif !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Struct
        return Expr(:struct, false, Expr(x.args[2]), Expr(x.args[3]))
    elseif typof(x) === Mutable
        return length(x.args) == 4 ? Expr(:struct, true, Expr(x.args[2]), Expr(x.args[3])) : Expr(:struct, true, Expr(x.args[3]), Expr(x.args[4]))
    elseif typof(x) === Abstract
        return length(x.args) == 2 ? Expr(:abstract, Expr(x.args[2])) : Expr(:abstract, Expr(x.args[3]))
    elseif typof(x) === Primitive
        return Expr(:primitive, Expr(x.args[3]), Expr(x.args[4]))
    elseif typof(x) === FunctionDef
        ret = Expr(:function)
        for a in x.args
            if !(ispunctuation(a) || iskw(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Macro
        if length(x.args) == 3
            Expr(:macro, Expr(x.args[2]))
        else
            Expr(:macro, Expr(x.args[2]), Expr(x.args[3]))
        end
    elseif typof(x) === ModuleH
        return Expr(:module, true, Expr(x.args[2]), Expr(x.args[3]))
    elseif typof(x) === BareModule
        return Expr(:module, false, Expr(x.args[2]), Expr(x.args[3]))
    elseif typof(x) === If
        return _if_expr(x)
    elseif typof(x) === Try
        ret = Expr(:try)
        for a in x.args
            if !(ispunctuation(a) || iskw(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Let
        return _let_expr(x)
    elseif typof(x) === Do
        return Expr(:do, Expr(x.args[1]), Expr(:->, Expr(x.args[3]), Expr(x.args[4])))
    elseif typof(x) === Outer
        return Expr(:outer, Expr(x.args[2]))
    elseif typof(x) === For
        ret = Expr(:for)
        if typof(x.args[2]) === Block
            arg = Expr(:block)
            for a in x.args[2].args
                if !(ispunctuation(a))
                    push!(arg.args, fix_range(a))
                end
            end
            push!(ret.args, arg)
        else
            push!(ret.args, fix_range(x.args[2]))
        end
        push!(ret.args, Expr(x.args[3]))
        return ret
    elseif typof(x) === While
        ret = Expr(:while)
        for a in x.args
            if !(ispunctuation(a) || iskw(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === TupleH
        ret = Expr(:tuple)
        for a in x.args
            if typof(a) == Parameters
                insert!(ret.args, 1, Expr(a))
            elseif !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Curly
        ret = Expr(:curly)
        for a in x.args
            if typof(a) === Parameters
                insert!(ret.args, 2, Expr(a))
            elseif !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Vect
        ret = Expr(:vect)
        for a in x.args
            if typof(a) === Parameters
                pushfirst!(ret.args, Expr(a))
            elseif !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Row
        ret = Expr(:row)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Hcat
        ret = Expr(:hcat)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Vcat
        ret = Expr(:vcat)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Block
        ret = Expr(:block)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Kw
        return Expr(:kw, Expr(x.args[1]), Expr(x.args[3]))
    elseif typof(x) === Parameters
        ret = Expr(:parameters)
        for a in x.args
            if typof(a) === Parameters
                insert!(ret.args, 2, Expr(a))
            elseif !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Return
        ret = Expr(:return)
        for i = 2:length(x.args)
            a = x.args[i]
            push!(ret.args, Expr(a))
        end
        return ret
    elseif typof(x) === InvisBrackets
        return Expr(x.args[2])
    elseif typof(x) === Begin
        return Expr(x.args[2])
    elseif typof(x) === Quote
        if length(x.args) == 1
            return Expr(:quote, Expr(x.args[1]))
        elseif typof(x.args[2]) === InvisBrackets && (isoperator(x.args[2].args[2]) || isliteral(x.args[2].args[2]) || isidentifier(x.args[2].args[2]))
            return QuoteNode(Expr(x.args[2]))
        else
            return Expr(:quote, Expr(x.args[2]))
        end
    elseif typof(x) === Global
        ret = Expr(:global)
        if typof(x.args[2]) === Const
            ret = Expr(:const, Expr(:global, Expr(x.args[2].args[2])))
        elseif length(x.args) == 2 && typof(x.args[2]) === TupleH
            for a in x.args[2].args
                if !(ispunctuation(a))
                    push!(ret.args, Expr(a))
                end
            end
        else
            for i = 2:length(x.args)
                a = x.args[i]
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Local
        ret = Expr(:local)
        if typof(x.args[2]) === Const
            ret = Expr(:const, Expr(:global, Expr(x.args[2].args[2])))
        elseif length(x.args) == 2 && typof(x.args[2]) === TupleH
            for a in x.args[2].args
                if !(ispunctuation(a))
                    push!(ret.args, Expr(a))
                end
            end
        else
            for i = 2:length(x.args)
                a = x.args[i]
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Const
        ret = Expr(:const)
        for i = 2:length(x.args)
            a = x.args[i]
            push!(ret.args, Expr(a))
        end
        return ret
    elseif typof(x) === GlobalRefDoc
        return GlobalRef(Core, Symbol("@doc"))
    elseif typof(x) === Ref
        ret = Expr(:ref)
        for a in x.args
            if typof(a) === Parameters
                insert!(ret.args, 2, Expr(a))
            elseif !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === TypedHcat
        ret = Expr(:typed_hcat)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === TypedVcat
        ret = Expr(:typed_vcat)
        for a in x.args
            if typof(a) === Parameters
                insert!(ret.args, 2, Expr(a))
            elseif !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Comprehension || typof(x) === DictComprehension
        ret = Expr(:comprehension)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Flatten
        iters, args = get_inner_gen(x)
        i = popfirst!(iters)
        ex = Expr(:generator, Expr(args[1]), convert_iter_assign(i[1]))
        for i in iters
            if length(i) == 1
                ex = Expr(:generator, ex, convert_iter_assign(i[1]))
                ex = Expr(:flatten, ex)
            else
                ex = Expr(:generator, ex)
                for j in i
                    push!(ex.args, convert_iter_assign(j))
                end
                ex = Expr(:flatten, ex)
            end
        end
        return ex
    elseif typof(x) === Generator
        ret = Expr(:generator, Expr(x.args[1]))
        for i = 3:length(x.args)
            a = x.args[i]
            if !(ispunctuation(a))
                push!(ret.args, convert_iter_assign(a))
            end
        end
        return ret
    elseif typof(x) === Filter
        ret = Expr(:filter)
        push!(ret.args, Expr(last(x.args)))
        for i in 1:length(x.args) - 1
            a = x.args[i]
            if !(is_if(a) || ispunctuation(a))
                push!(ret.args, convert_iter_assign(a))
            end
        end
        return ret
    elseif typof(x) === TypedComprehension
        ret = Expr(:typed_comprehension)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === Import
        return expr_import(x, :import)
    elseif typof(x) === ImportAll
        return expr_import(x, :importall)
    elseif typof(x) === Using
        return expr_import(x, :using)
    elseif typof(x) === Export
        ret = Expr(:export)
        for i = 2:length(x.args)
            a = x.args[i]
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    elseif typof(x) === FileH
        ret = Expr(:file)
        for a in x.args
            push!(ret.args, Expr(a))
        end
        return ret
    elseif typof(x) === StringH
        ret = Expr(:string)
        for (i, a) in enumerate(x.args)
            if typof(a) === UnaryOpCall
                a = a.args[2]
            elseif isliteral(a) && kindof(a) == Tokens.STRING && span(a) == 0 || ((i == 1 || i == length(x.args)) && span(a) == 1) || isempty(valof(a))
                continue
            else isliteral(a) && kindof(a) == Tokens.TRIPLE_STRING && span(a) == 0 || ((i == 1 || i == length(x.args)) && span(a) == 3) || isempty(valof(a))
            end
            push!(ret.args, Expr(a))
        end
        return ret
    else
        ret = Expr(:call)
        for a in x.args
            if !(ispunctuation(a))
                push!(ret.args, Expr(a))
            end
        end
        return ret
    end
end

# Op. expressions

function _unary_expr(x)
    if isoperator(x.args[1]) && issyntaxunarycall(x.args[1])
        Expr(Expr(x.args[1]), Expr(x.args[2]))
    elseif isoperator(x.args[2]) && issyntaxunarycall(x.args[2])
        Expr(Expr(x.args[2]), Expr(x.args[1]))
    else
        Expr(:call, Expr(x.args[1]), Expr(x.args[2]))
    end
end
function _binary_expr(x)
    if issyntaxcall(x.args[2]) && !(kindof(x.args[2]) in (Tokens.COLON,))
        if kindof(x.args[2]) === Tokens.DOT
            arg1, arg2 = Expr(x.args[1]), Expr(x.args[3])
            if arg2 isa Expr && arg2.head === :macrocall && endswith(string(arg2.args[1]), "_cmd")
                return Expr(:macrocall, Expr(:., arg1, QuoteNode(arg2.args[1])), nothing, arg2.args[3])
            elseif arg2 isa Expr && arg2.head === :braces
                return Expr(:., arg1, Expr(:quote, arg2))
            end
        end
        Expr(Expr(x.args[2]), Expr(x.args[1]), Expr(x.args[3]))
    else
        Expr(:call, Expr(x.args[2]), Expr(x.args[1]), Expr(x.args[3]))
    end
end

function _where_expr(x)
    ret = Expr(:where, Expr(x.args[1]))
    for i = 3:length(x.args)
        a = x.args[i]
        if typof(a) === Parameters
            insert!(ret.args, 2, Expr(a))
        elseif !(ispunctuation(a) || iskw(a))
            push!(ret.args, Expr(a))
        end
    end
    return ret
end

# cross compatability for line number insertion in macrocalls
if VERSION > v"1.1-"
    Expr_cmd(x) = Expr(:macrocall, GlobalRef(Core, Symbol("@cmd")), nothing, valof(x))
    Expr_tcmd(x) = Expr(:macrocall, GlobalRef(Core, Symbol("@cmd")), nothing, valof(x))
else
    Expr_cmd(x) = Expr(:macrocall, Symbol("@cmd"), nothing, valof(x))
    Expr_tcmd(x) = Expr(:macrocall, Symbol("@cmd"), nothing, valof(x))
end

function clear_at!(x)
    if x isa Expr && x.head == :.
        if x.args[2] isa QuoteNode && string(x.args[2].value)[1] == '@'
            x.args[2].value = Symbol(string(x.args[2].value)[2:end])
        end
        if x.args[1] isa Symbol && string(x.args[1])[1] == '@'
            x.args[1] = Symbol(string(x.args[1])[2:end])
        else
            clear_at!(x.args[1])
        end
    end
end

"""
    remlineinfo!(x)
Removes line info expressions. (i.e. Expr(:line, 1))
"""
function remlineinfo!(x)
    if isa(x, Expr)
        if x.head == :macrocall && x.args[2] !== nothing
            id = findall(map(x->(isa(x, Expr) && x.head == :line) || (@isdefined(LineNumberNode) && x isa LineNumberNode), x.args))
            deleteat!(x.args, id)
            for j in x.args
                remlineinfo!(j)
            end
            insert!(x.args, 2, nothing)
        else
            id = findall(map(x->(isa(x, Expr) && x.head == :line) || (@isdefined(LineNumberNode) && x isa LineNumberNode), x.args))
            deleteat!(x.args, id)
            for j in x.args
                remlineinfo!(j)
            end
        end
        if x.head == :elseif && x.args[1] isa Expr && x.args[1].head == :block && length(x.args[1].args) == 1
            x.args[1] = x.args[1].args[1]
        end
    end
    x
end

function _if_expr(x)
    ret = Expr(:if)
    iselseif = false
    n = length(x.args)
    i = 0
    while i < n
        i += 1
        a = x.args[i]
        if iskw(a) && kindof(a) == Tokens.ELSEIF
            i += 1
            r1 = Expr(x.args[i].args[1])
            push!(ret.args, Expr(:elseif, r1.args...))
        elseif !(ispunctuation(a) || iskw(a))
            push!(ret.args, Expr(a))
        end
    end
    ret
end

function _let_expr(x)
    ret = Expr(:let)
    if length(x.args) == 3
        push!(ret.args, Expr(:block))
        push!(ret.args, Expr(x.args[2]))
        return ret
    elseif typof(x.args[2]) === Block
        arg = Expr(:block)
        for a in x.args[2].args
            if !(ispunctuation(a))
                push!(arg.args, fix_range(a))
            end
        end
        push!(ret.args, arg)
    else
        push!(ret.args, fix_range(x.args[2]))
    end
    push!(ret.args, Expr(x.args[3]))
    ret
end

function fix_range(a)
    if typof(a) === BinaryOpCall && (is_in(a.args[2]) || is_elof(a.args[2]))
        Expr(:(=), Expr(a.args[1]), Expr(a.args[3]))
    else
        Expr(a)
    end
end

function get_inner_gen(x, iters = [], arg = [])
    if typof(x) == Flatten
        get_inner_gen(x.args[1], iters, arg)
    elseif typof(x) === Generator
        # push!(iters, get_iter(x))
        get_iters(x, iters)
        if typof(x.args[1]) === Generator || typof(x.args[1]) === Flatten
            get_inner_gen(x.args[1], iters, arg)
        else
            push!(arg, x.args[1])
        end
    end
    return iters, arg
end

function get_iter(x)
    if typof(x) === Generator
        return x.args[3]
    end
end

function get_iters(x, iters)
    iters1 = []
    if typof(x) === Generator
        # return x.args[3]
        for i = 3:length(x.args)
            if typof(x.args[i]) !== PUNCTUATION
                push!(iters1, x.args[i])
            end
        end
    end
    push!(iters, iters1)
end

function convert_iter_assign(a)
    if typof(a) === BinaryOpCall && (is_in(a.args[2]) || is_elof(a.args[2]))
        return Expr(:(=), Expr(a.args[1]), Expr(a.args[3]))
    else
        return Expr(a)
    end
end

function _get_import_block(x, i, ret)
    while is_dot(x.args[i + 1])
        i += 1
        push!(ret.args, :.)
    end
    while i < length(x.args) && !(is_comma(x.args[i + 1]))
        i += 1
        a = x.args[i]
        if !(ispunctuation(a)) && !(is_dot(a) || is_colon(a))
            push!(ret.args, Expr(a))
        end
    end

    return i
end

function expr_import(x, kw)
    col = findall(a->isoperator(a) && precedence(a) == ColonOp, x.args)
    comma = findall(is_comma, x.args)

    header = []
    args = [Expr(:.)]
    i = 1 # skip keyword
    while i < length(x.args)
        i += 1
        a = x.args[i]
        if is_colon(a)
            push!(header, popfirst!(args))
            push!(args, Expr(:.))
        elseif is_comma(a)
            push!(args, Expr(:.))
        elseif !(ispunctuation(a))
            push!(last(args).args, Expr(a))
        end
    end
    if isempty(header)
        return Expr(kw, args...)
    else
        return Expr(kw, Expr(:(:), header..., args...))
    end
end

const UNICODE_OPS_REVERSE = Dict{Tokenize.Tokens.Kind,Symbol}()
for (k, v) in Tokenize.Tokens.UNICODE_OPS
    UNICODE_OPS_REVERSE[v] = Symbol(k)
end

UNICODE_OPS_REVERSE[Tokens.EQ] = :(=)
UNICODE_OPS_REVERSE[Tokens.PLUS_EQ] = :(+=)
UNICODE_OPS_REVERSE[Tokens.MINUS_EQ] = :(-=)
UNICODE_OPS_REVERSE[Tokens.STAR_EQ] = :(*=)
UNICODE_OPS_REVERSE[Tokens.FWD_SLASH_EQ] = :(/=)
UNICODE_OPS_REVERSE[Tokens.FWDFWD_SLASH_EQ] = :(//=)
UNICODE_OPS_REVERSE[Tokens.OR_EQ] = :(|=)
UNICODE_OPS_REVERSE[Tokens.CIRCUMFLEX_EQ] = :(^=)
UNICODE_OPS_REVERSE[Tokens.DIVISION_EQ] = :(÷=)
UNICODE_OPS_REVERSE[Tokens.REM_EQ] = :(%=)
UNICODE_OPS_REVERSE[Tokens.LBITSHIFT_EQ] = :(<<=)
UNICODE_OPS_REVERSE[Tokens.RBITSHIFT_EQ] = :(>>=)
UNICODE_OPS_REVERSE[Tokens.LBITSHIFT] = :(<<)
UNICODE_OPS_REVERSE[Tokens.RBITSHIFT] = :(>>)
UNICODE_OPS_REVERSE[Tokens.UNSIGNED_BITSHIFT] = :(>>>)
UNICODE_OPS_REVERSE[Tokens.UNSIGNED_BITSHIFT_EQ] = :(>>>=)
UNICODE_OPS_REVERSE[Tokens.BACKSLASH_EQ] = :(\=)
UNICODE_OPS_REVERSE[Tokens.AND_EQ] = :(&=)
UNICODE_OPS_REVERSE[Tokens.COLON_EQ] = :(:=)
UNICODE_OPS_REVERSE[Tokens.PAIR_ARROW] = :(=>)
UNICODE_OPS_REVERSE[Tokens.APPROX] = :(~)
UNICODE_OPS_REVERSE[Tokens.EX_OR_EQ] = :($=)
UNICODE_OPS_REVERSE[Tokens.XOR_EQ] = :(⊻=)
UNICODE_OPS_REVERSE[Tokens.RIGHT_ARROW] = :(-->)
UNICODE_OPS_REVERSE[Tokens.LAZY_OR] = :(||)
UNICODE_OPS_REVERSE[Tokens.LAZY_AND] = :(&&)
UNICODE_OPS_REVERSE[Tokens.ISSUBTYPE] = :(<:)
UNICODE_OPS_REVERSE[Tokens.ISSUPERTYPE] = :(>:)
UNICODE_OPS_REVERSE[Tokens.GREATER] = :(>)
UNICODE_OPS_REVERSE[Tokens.LESS] = :(<)
UNICODE_OPS_REVERSE[Tokens.GREATER_EQ] = :(>=)
UNICODE_OPS_REVERSE[Tokens.GREATER_THAN_OR_EQUAL_TO] = :(≥)
UNICODE_OPS_REVERSE[Tokens.LESS_EQ] = :(<=)
UNICODE_OPS_REVERSE[Tokens.LESS_THAN_OR_EQUAL_TO] = :(≤)
UNICODE_OPS_REVERSE[Tokens.EQEQ] = :(==)
UNICODE_OPS_REVERSE[Tokens.EQEQEQ] = :(===)
UNICODE_OPS_REVERSE[Tokens.IDENTICAL_TO] = :(≡)
UNICODE_OPS_REVERSE[Tokens.NOT_EQ] = :(!=)
UNICODE_OPS_REVERSE[Tokens.NOT_EQUAL_TO] = :(≠)
UNICODE_OPS_REVERSE[Tokens.NOT_IS] = :(!==)
UNICODE_OPS_REVERSE[Tokens.NOT_IDENTICAL_TO] = :(≢)
UNICODE_OPS_REVERSE[Tokens.IN] = :(in)
UNICODE_OPS_REVERSE[Tokens.ISA] = :(isa)
UNICODE_OPS_REVERSE[Tokens.LPIPE] = :(<|)
UNICODE_OPS_REVERSE[Tokens.RPIPE] = :(|>)
UNICODE_OPS_REVERSE[Tokens.COLON] = :(:)
UNICODE_OPS_REVERSE[Tokens.DDOT] = :(..)
UNICODE_OPS_REVERSE[Tokens.EX_OR] = :($)
UNICODE_OPS_REVERSE[Tokens.PLUS] = :(+)
UNICODE_OPS_REVERSE[Tokens.MINUS] = :(-)
UNICODE_OPS_REVERSE[Tokens.PLUSPLUS] = :(++)
UNICODE_OPS_REVERSE[Tokens.OR] = :(|)
UNICODE_OPS_REVERSE[Tokens.STAR] = :(*)
UNICODE_OPS_REVERSE[Tokens.FWD_SLASH] = :(/)
UNICODE_OPS_REVERSE[Tokens.REM] = :(%)
UNICODE_OPS_REVERSE[Tokens.BACKSLASH] = :(\)
UNICODE_OPS_REVERSE[Tokens.AND] = :(&)
UNICODE_OPS_REVERSE[Tokens.FWDFWD_SLASH] = :(//)
UNICODE_OPS_REVERSE[Tokens.CIRCUMFLEX_ACCENT] = :(^)
UNICODE_OPS_REVERSE[Tokens.DECLARATION] = :(::)
UNICODE_OPS_REVERSE[Tokens.CONDITIONAL] = :?
UNICODE_OPS_REVERSE[Tokens.DOT] = :(.)
UNICODE_OPS_REVERSE[Tokens.NOT] = :(!)
UNICODE_OPS_REVERSE[Tokens.PRIME] = Symbol(''')
UNICODE_OPS_REVERSE[Tokens.DDDOT] = :(...)
UNICODE_OPS_REVERSE[Tokens.TRANSPOSE] = Symbol(".'")
UNICODE_OPS_REVERSE[Tokens.ANON_FUNC] = :(->)
UNICODE_OPS_REVERSE[Tokens.WHERE] = :where


text:
using NNFEM
using PoreFlow
using PyPlot

m = 40
n = 40
h = 1/m
domain = example_domain(m, n, h)
x, y = domain.nodes[:,1], domain.nodes[:,2]
out = [@. x*y*(1-y)
      @. x*(1-y)]

EBC = zeros(Int64,domain.nnodes, 2)
g = [(@. x*y*(1-y)) (@. x*(1-y))]
FBC = zeros(Int64,domain.nnodes,2)
f = zeros(domain.nnodes,2)

for j = 1:n+1
    EBC[(j-1)*(m+1)+m+1, :] .= -1
    EBC[(j-1)*(m+1)+1, :] .= -1
end

for i = 1:m+1
    EBC[n*(m+1)+i, :] .= -1
    EBC[i, :] .= -1
end

nodes, elements = domain.nodes, domain.elements

domain = Domain(nodes, elements, 2, EBC, g, FBC, f)
H = domain.elements[1].mat[1].H

EBC_func = nothing
FBC_func = nothing

function body_func(x, y, t)
    f1 = @. -1.48148148148148x - 2.46913580246914
    f2 = @. 2.46913580246914 - 4.93827160493827y
    -[f1 f2]
end
globaldata = GlobalData(missing, missing, missing, missing, domain.neqs, EBC_func, FBC_func, body_func)

#-------------------------------------------------
# NNFEM Solver
@info "Solving using AD-free solver..."
globaldata, domain = LinearStaticSolver(globaldata, domain)
figure(figsize=(10,10))
title("NNFEM")
subplot(221)
visualize_scalar_on_scoped_body(domain.state[1:domain.nnodes], zeros(size(domain.state)...), domain)
subplot(222)
visualize_scalar_on_scoped_body(out[1:domain.nnodes], zeros(size(domain.state)...), domain)
subplot(223)
visualize_scalar_on_scoped_body(domain.state[domain.nnodes+1:end], zeros(size(domain.state)...), domain)
subplot(224)
visualize_scalar_on_scoped_body(out[domain.nnodes+1:end], zeros(size(domain.state)...), domain)

@info "Solving using AD-capable solver..."
domain = Domain(nodes, elements, 2, EBC, g, FBC, f)
globaldata = GlobalData(missing, missing, missing, missing, domain.neqs, EBC_func, FBC_func, body_func)
Fext = compute_external_force(globaldata, domain)
d = LinearStaticSolver(globaldata, domain, domain.state, H, Fext)
sess = Session(); init(sess)
domain.state = run(sess, d)

figure(figsize=(10,10))
subplot(221)
visualize_scalar_on_scoped_body(domain.state[1:domain.nnodes], zeros(size(domain.state)...), domain)
subplot(222)
visualize_scalar_on_scoped_body(out[1:domain.nnodes], zeros(size(domain.state)...), domain)
subplot(223)
visualize_scalar_on_scoped_body(domain.state[domain.nnodes+1:end], zeros(size(domain.state)...), domain)
subplot(224)
visualize_scalar_on_scoped_body(out[domain.nnodes+1:end], zeros(size(domain.state)...), domain)

ext: jl


text:
# This file is a part of RunStatistics.jl, licensed under the MIT License (MIT).

using RunStatistics
using Test

@testset "squares" begin
    T_obs = 3.4
    N = 30

    @test squares_pvalue(T_obs, N) ≈ 0.818208032939994
    @test squares_cdf(T_obs, N) ≈ 0.18179196706000597
end

@testset "squares_paper" begin
    alpha = 0.001

    @test abs(squares_pvalue(15.5, 5) - alpha) <= 0.00002
    @test abs(squares_pvalue(23.8, 50) - alpha) <= 0.00002
    @test abs(squares_pvalue(25.6, 100) - alpha) <= 0.00008
end

@testset "squares_mathematica" begin
    n = 20
    T = [2, 5, 10, 20, 50]
    P = [0.8936721808595665, 0.42457437866154357, 0.06934906413527009, 0.0014159488909252227, 9.575188641974819e-9]
    eps = [1e-15, 1e-15, 1e-15, 1e-15, 1e-15]

    for i in 1:5
        @test abs(squares_pvalue(T[i], n) - P[i]) <= eps[i]
    end
end

@testset "squares_critical" begin
    N = 50

    @test abs(squares_pvalue(19.645, 2 * N) - 0.01) <= 3e-5
    @test abs(squares_pvalue(15.34, 2 * N) - 0.05) <= 1e-4
end


text:
"""
```
choose_knots(k, x)
```

calculates k uniformly spaced knots given a vector of grid points x
"""
function choose_knots(k::Int, x::AbstractVector{S}) where {S <: Real}
    return collect(range(minimum(x), stop = maximum(x), length = k))
end

"""
```
bin_sort(x::AbstractVector{T}, bins::AbstractVector{T}) where {T <: Real}
```

returns a vector of Ints indicating in which bin each value of x belongs. The first function
assumes that `bins` defines the left edge of the bin and is sorted.
"""
function bin_sort(x::AbstractVector{S}, bins::AbstractVector{S}) where {S <: Real}

    # Fit the histogram
    h = fit(Histogram, x, bins)

    # Create index of bins
    out = map(y -> StatsBase.binindex(h, y), x)

    # Histogram uses [a, b) bins, but the last bin has just 1 point,
    # then we just lump it with the previous bin
    if maximum(x) == bins[end]
        max_vals = x .== maximum(x)
        out[max_vals] .= length(bins) - 1
    end

    return out
end


text:
export
    Packed_Factor

"""
    $TYPEDEF

FIXME see DFG #590 on Serialization and Marshaling

This type and use must be reviewed as part of the next gen (4Q20) serialization upgrades.

`::Any` has slower performance, so we should try avoid (but not critical)
"""
mutable struct Packed_Factor
    measurement::Vector{Dict{String, Any}}
    distType::String
end


text:
# This file is a part of PropDicts.jl, licensed under the MIT License (MIT).

using PropDicts
using Test

@testset "varsubst" begin
    @test @inferred(PropDicts.contains_vars(raw"fo\\$o")) == true
    @test @inferred(PropDicts.substitute_vars(raw"foo $bar ${baz} y", ignore_missing = true)) == raw"foo $bar ${baz} y"
    @test @inferred(PropDicts.substitute_vars(raw"foo $(bar) baz", Dict("bar" => "xyz"))) == "foo xyz baz"

    @test @inferred(PropDicts.substitute_vars(raw"x${nosuchvar}y", ignore_missing = true)) == raw"x${nosuchvar}y"
    @test @inferred(PropDicts.substitute_vars(raw"x$(nosuchvar)y", ignore_missing = true)) == raw"x$(nosuchvar)y"

    # Unknown variable during variable substitution:
    @test_throws ArgumentError PropDicts.substitute_vars(raw"x${nosuchvar}y")

    # Extra "{" during variable substitution:
    @test_throws ArgumentError PropDicts.substitute_vars(raw"${a{}", ignore_missing = true)

    # Closing ")" for open "{" during variable substitution:
    @test_throws ArgumentError PropDicts.substitute_vars(raw"x${nosuchvar)y", ignore_missing = true)

    # Illegal character "\" in variable name :
    @test_throws ArgumentError PropDicts.substitute_vars(raw"x${no\suchvar}y", ignore_missing = true)

    # Illegal variable name, starting with a digit
    @test_throws ArgumentError PropDicts.substitute_vars(raw"x${1nosuchvar}y", ignore_missing = true)

    # Missing "}" for "${" during variable substitution:
    @test_throws ArgumentError PropDicts.substitute_vars(raw"x${nosuchvary", ignore_missing = true)

    ENV["PROPDICT_TEST_A_"] = "some-var-value"
    @test @inferred(PropDicts.substitute_vars(raw"foo$(bar)x$PROPDICT_TEST_A_,baz", Dict("bar" => "xyz"), use_env = true)) == "fooxyzxsome-var-value,baz"
end


text:
"""
    varN(B::LogBinner[, lvl])

Calculates the variance/N of a given level in the Binning Analysis.
"""
function varN(B::LogBinner, lvl::Integer = _reliable_level(B))
    n = B.count[lvl]
    var(B, lvl) / n
end

"""
    var(B::LogBinner[, lvl])

Calculates the variance of a given level in the Binning Analysis.
"""
function var(B::LogBinner) end

function var(
        B::LogBinner{T,N},
        lvl::Integer = _reliable_level(B)
    ) where {N, T <: Real}

    n = B.count[lvl]
    X = B.x_sum[lvl]
    X2 = B.x2_sum[lvl]

    # lvl = 1 <=> original values
    # correct variance:
    # (∑ xᵢ^2) / (N-1) - (∑ xᵢ)(∑ xᵢ) / (N(N-1))
    X2 / (n - 1) - X^2 / (n*(n - 1))
end

function var(
        B::LogBinner{T,N},
        lvl::Integer = _reliable_level(B)
    ) where {N, T <: Complex}

    n = B.count[lvl]
    X = B.x_sum[lvl]
    X2 = B.x2_sum[lvl]

    # lvl = 1 <=> original values
    (real(X2) + imag(X2)) / (n - 1) - (real(X)^2 + imag(X)^2) / (n*(n - 1))
end

function var(
        B::LogBinner{<: AbstractArray{T, D}, N},
        lvl::Integer = _reliable_level(B)
    ) where {N, D, T <: Real}

    n = B.count[lvl]
    X = B.x_sum[lvl]
    X2 = B.x2_sum[lvl]

    @. X2 / (n - 1) - X^2 / (n*(n - 1))
end

function var(
        B::LogBinner{<: AbstractArray{T, D}, N},
        lvl::Integer = _reliable_level(B)
    ) where {N, D, T <: Complex}

    n = B.count[lvl]
    X = B.x_sum[lvl]
    X2 = B.x2_sum[lvl]

    @. (real(X2) + imag(X2)) / (n - 1) - (real(X)^2 + imag(X)^2) / (n*(n - 1))
end

"""
    all_vars(B::LogBinner)

Calculates the variance for each level of the Binning Analysis.
"""
function all_vars(B::LogBinner{T,N}) where {T,N}
    [var(B, lvl) for lvl in 1:N if B.count[lvl] > 1]
end

"""
    all_varNs(B::LogBinner)

Calculates the variance/N for each level of the Binning Analysis.
"""
function all_varNs(B::LogBinner{T,N}) where {T,N}
    [varN(B, lvl) for lvl in 1:N if B.count[lvl] > 1]
end

################################################################################

# NOTE works for all
"""
    mean(B::LogBinner[, lvl])

Calculates the mean for a given level in the Binning Analysis.
"""
function mean(B::LogBinner, lvl::Integer = 1)
    B.x_sum[lvl] / B.count[lvl]
end

# NOTE works for all
"""
    all_means(B::LogBinner)

Calculates the mean for each level of the `LogBinner`.
"""
function all_means(B::LogBinner{T,N}) where {T,N}
    [mean(B, lvl) for lvl in 1:N if B.count[lvl] > 1]
end

################################################################################

"""
    tau(B::LogBinner[, lvl])

Calculates the autocorrelation time tau.
"""
function tau(B::LogBinner{T,N}, lvl::Integer = _reliable_level(B)) where {N , T <: Number}
    var_0 = varN(B, 1)
    var_l = varN(B, lvl)
    0.5 * (var_l / var_0 - 1)
end
function tau(B::LogBinner{T,N}, lvl::Integer = _reliable_level(B)) where {N , T <: AbstractArray}
    var_0 = varN(B, 1)
    var_l = varN(B, lvl)
    @. 0.5 * (var_l / var_0 - 1)
end

"""
    all_taus(B::LogBinner)

Calculates the autocorrelation time tau for each level of the `LogBinner`.
"""
function all_taus(B::LogBinner{T,N}) where {T,N}
    [tau(B, lvl) for lvl in 1:N if B.count[lvl] > 1]
end

################################################################################

# Heuristic for selecting the level with the (presumably) most reliable
# standard error estimate:
# Take the highest lvl with at least 32 bins.
# (Chose 32 based on https://doi.org/10.1119/1.3247985)
function _reliable_level(B::LogBinner{T,N})::Int64 where {T,N}
    isempty(B) && (return 1)                # results in NaN in std_error
    i = findlast(x -> x >= 32, B.count)
    something(i, 1)
end

 """
    std_error(B::LogBinner[, lvl])

Calculates the standard error of the mean.
"""
function std_error(B::LogBinner) end

function std_error(B::LogBinner{T,N}, lvl::Integer=_reliable_level(B)) where {N, T <: Number}
    sqrt(varN(B, lvl))
end
function std_error(B::LogBinner{T,N}, lvl::Integer=_reliable_level(B)) where {N, T <: AbstractArray}
    sqrt.(varN(B, lvl))
end

"""
    all_std_errors(B::LogBinner)

Calculates the standard error for each level of the Binning Analysis.
"""
function all_std_errors(B::LogBinner) end

all_std_errors(B::LogBinner{T,N}) where {N, T <: Number} = sqrt.(all_varNs(B))
all_std_errors(B::LogBinner{T,N}) where {N, T <: AbstractArray} = (x -> sqrt.(x)).(all_varNs(B))

"""
    convergence(B::LogBinner, lvl)

Computes the difference between the variance of this lvl and the last,
normalized to the last lvl. If this value tends to 0, the Binning Analysis has
converged.
"""
function convergence(B::LogBinner) end

function convergence(B::LogBinner{T,N}, lvl::Integer=_reliable_level(B)) where {N, T <: Number}
    abs((varN(B, lvl+1) - varN(B, lvl)) / varN(B, lvl))
end
function convergence(B::LogBinner{T,N}, lvl::Integer=_reliable_level(B)) where {N, T <: AbstractArray}
    mean(abs.((varN(B, lvl+1) .- varN(B, lvl)) ./ varN(B, lvl)))
end

"""
    has_converged(B::LogBinner, lvl[, threshhold = 0.05])

Returns true if the Binning Analysis has converged for a given lvl.
"""
function has_converged(B::LogBinner, lvl::Integer=_reliable_level(B), threshhold::Float64 = 0.05)
    convergence(B, lvl) <= threshhold
end


text:
using MetoceanTools
using Base.Test

om=falses(5)

println("dlpRead test\n .. loading")
include("dlpRead_test.jl")
println(" .. running")
dlpRead_test()
om[1]=true
println(" .. done")

println("showSampling test\n .. loading")
include("showSampling_test.jl")
println(" .. running")
showSampling_test()
om[2]=true
println(" .. done")
println(" .. running test 1")
showSampling_test1()
om[3]=true
println(" .. done")

println("dlpRead test\n .. loading")
include("countUniqueValues_test.jl")
println(" .. running")
om[4]=countUniqueValues_test()
if !om[4]
  error("Failed on countUniqueValues")
end
println(" .. done")

println("tsZeroCross test\n .. loading")
include("tsZeroCross_test.jl")
println(" .. running")
om[5]=tsZeroCross_test()
if !om[5]
  error("Failed on tsZeroCross")
end
println(" .. done")

@test 1==1

max_stars_repo_name: jadamc/MetoceanTools

max_issues_repo_name: jadamc/MetoceanTools

max_forks_repo_name: jadamc/MetoceanTools


text:
# Location-preserving lowering for some of julia AST to improve quality of
# matching for the AST Interpreter

import JuliaParser: Lexer
import JuliaParser.Tokens: ¬, ⨳, ⪥, SourceExpr

function do_lowering(ex)
    isa(¬ex, Expr) || return ex
    if (¬ex).head == :typed_vcat
        if any(x->isexpr(x,:row), (¬ex).args)
            # TODO: Make this a split source range
            transformed_ex = ⨳(:call,Expr(:core, :typed_hvcat)⤄ex,first(children(ex)))
            ncols = length((¬ex).args[2].args) # Number of columns in the first row
            nrows = length((¬ex).args) - 1     # -1 for the type
            transformed_ex = transformed_ex ⪥ ((ncols,nrows)⤄ex,)
            for nex in drop(children(ex),1)
                @assert (¬nex).head == :row
                transformed_ex = transformed_ex ⪥ nex
            end
        else
            transformed_ex = ⨳(:call,GlobalRef(Main, :typed_vcat)⤄ex) ⪥ ex
        end
        transformed_ex
    elseif (¬ex).head == :(:)
        transformed_ex = ⨳(:call,GlobalRef(Main, :colon)⤄ex) ⪥ ex
        transformed_ex
    elseif (¬ex).head == :(.)
        transformed_ex = ⨳(:call,GlobalRef(Main, :getfield)⤄ex) ⪥ ex
        transformed_ex
    elseif (¬ex).head == :ref
        ex = treemap!(PreOrderDFS(ex)) do s
            !isa(¬s, Symbol) && return s
            ¬s == :end ? ⨳(:call,GlobalRef(Main, :endof)⤄s,copy(collect(children(ex))[1])) : s
        end
        transformed_ex = ⨳(:call,GlobalRef(Main, :getindex)⤄ex) ⪥ ex
        transformed_ex
    elseif (¬ex).head == :string
        transformed_ex = ⨳(:call,GlobalRef(Main, :string)⤄ex) ⪥ ex
        transformed_ex
    elseif (¬ex).head == :comparison
        @assert length((¬ex).args) == 3
        cs = collect(children(ex))
        transformed_ex = ⨳(:call,cs[2],cs[1],cs[3])
    elseif (¬ex).head == :(+=)
        ⨳(:(=), collect(children(ex))[1], (⨳(:call, :+⤄ex) ⪥ ex))
    elseif (¬ex).head == :tuple
        transformed_ex = ⨳(:call,GlobalRef(Main, :tuple)⤄ex) ⪥ ex
        transformed_ex
    else
        ex
    end
end

function lower!(ex)
    ex = treemap!(do_lowering,PreOrderDFS(ex))
end


text:
__precompile__()

module Forge

deps = joinpath(Pkg.dir("Forge"), "deps", "deps.jl")
if isfile(deps)
    include(deps)
else
    error("Forge not properly installed. Please run Pkg.build(\"Forge\")")
end

const FG_API_VERSION_CURRENT = 09
include("libforge_h.jl")
include("wrap.jl")

include("dsl.jl")

end # module


text:
# Use baremodule to shave off a few KB from the serialized `.ji` file
baremodule Gama_jll
using Base
using Base: UUID
import JLLWrappers

JLLWrappers.@generate_main_file_header("Gama")
JLLWrappers.@generate_main_file("Gama", UUID("e49eef03-c325-580d-b9c2-ffdb035fe7b1"))
end  # module Gama_jll


text:
using Test, FinancialMonteCarlo;
@show "Black Scholes Model"
S0 = 100.0;
K = 100.0;
r = 0.02;
T = 1.0;
d = 0.01;
D = 90.0;

underlying_name = "ENJ"
underlying_name_2 = "ABPL"

underlying_ = underlying_name * "_" * underlying_name_2 * "_TESL"

Nsim = 10000;
Nstep = 30;
sigma = 0.2;
mc = MonteCarloConfiguration(Nsim, Nstep);
mc1 = MonteCarloConfiguration(Nsim, Nstep, FinancialMonteCarlo.AntitheticMC());
toll = 0.8

rfCurve = ZeroRate(r);

FwdData = Forward(T)
EUData = EuropeanOptionND(T, K)
AMData = AmericanOption(T, K)
BarrierData = BarrierOptionDownOut(T, K, D)
AsianFloatingStrikeData = AsianFloatingStrikeOption(T)
AsianFixedStrikeData = AsianFixedStrikeOption(T, K)
Model_enj = BlackScholesProcess(sigma, Underlying(S0, d));
Model_abpl = BlackScholesProcess(sigma, Underlying(S0, d));
Model_tesl = BlackScholesProcess(sigma, Underlying(S0, d));
rho_1 = [1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0];
Model = GaussianCopulaNVariateProcess(rho_1, Model_enj, Model_abpl, Model_tesl)

display(Model)

mktdataset = underlying_ → Model

portfolio_ = [EUData];
portfolio = underlying_ → EUData

price_mkt = pricer(mktdataset, rfCurve, mc, portfolio)
price_old = sum(pricer(Model, rfCurve, mc, portfolio_))

@test abs(price_mkt - price_old) < 1e-8


text:
### A Pluto.jl notebook ###
# v0.14.0

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing
        el
    end
end

# ╔═╡ e73aaef4-97e7-11eb-1722-9d275d445f1c
html"""

Section 2.8

 Pascal

Lecture Video

"""

# ╔═╡ 568374de-9717-11eb-3ad1-571475dfe65c
function pascal_row(n)
	if n == 1
		[1]
	else
		prev = pascal_row(n-1)
		[prev; 0] .+ [0; prev]
	end
end

# ╔═╡ a5cb88e1-95de-4a01-8738-1761052d4886
pascal_row(3)

# ╔═╡ 4c6bdeec-cb3b-42da-9cba-f625818bc9c5
pascal(n) = pascal_row.(1:n)

# ╔═╡ 1a651f93-5df0-4ce6-991d-9720da29a7e3
@bind N Slider(1:17; default=5)

# ╔═╡ 3c0baae7-6a34-4126-8d19-5915cf64d7bd
pascal(N)

# ╔═╡ 3a765d51-95d0-444d-adab-f794190914f2
pyramid(pascal(N))

# ╔═╡ fec4bcfb-b88a-4008-82fa-194b8f7264e0
md"""
We need this magical mini-package
"""

# ╔═╡ 116ffb13-8b9a-40b4-aa1e-88d645d1124a
begin
    import Pkg
    Pkg.activate(mktempdir())
    Pkg.add([
        Pkg.PackageSpec(name="HypertextLiteral", version="0.6"),
        Pkg.PackageSpec(name="PlutoUI", version="0.7"),
    ])
    using HypertextLiteral, PlutoUI
end

# ╔═╡ 8de19918-2a32-4b74-a6c4-3fa229c36afd
rand_triangle = [round.(vi,digits=5) for vi ∈ [rand(i) for i=1:6]]

# ╔═╡ dd50d34b-edb3-4e3f-9a2f-77bfe0ed3fd0
pyramid(rand_triangle)

# ╔═╡ bdbd30d7-8714-44bb-a81f-adf988a225a4
md"""
### Vertical and horizontal padding
"""

# ╔═╡ 87b16571-05a3-4bf0-bc12-3f7bb302e364
pyramid(rand_triangle; padding_y = 20)

# ╔═╡ 2b4bd381-87ce-4b0c-8753-4b5a68a7389e
pyramid(rand_triangle; padding_x = 40)

# ╔═╡ 76f08f06-9351-4815-8881-dc978b0e2031
md"""
### Horizontal pyramid
"""

# ╔═╡ c6b3192f-efa3-4ad5-92c0-2eac700f6b26
pyramid(rand_triangle; horizontal=true)

# ╔═╡ 35f75f0a-08c5-47ea-9930-e70f20b8a64a
function pyramid(rows::Vector{<:Vector};
		horizontal=false,
		padding_x=8,
		padding_y=2,
	)

	style = (; padding = "$(padding_y)px $(padding_x)px")
	render_row(xs) = @htl("""
<padder></padder>$([@htl("$(x)") for x in xs])<padder></padder>
""")

	@htl("""

		$(render_row.(rows))

		""")
end

# ╔═╡ Cell order:
# ╠═e73aaef4-97e7-11eb-1722-9d275d445f1c
# ╠═568374de-9717-11eb-3ad1-571475dfe65c
# ╠═a5cb88e1-95de-4a01-8738-1761052d4886
# ╠═4c6bdeec-cb3b-42da-9cba-f625818bc9c5
# ╠═1a651f93-5df0-4ce6-991d-9720da29a7e3
# ╠═3c0baae7-6a34-4126-8d19-5915cf64d7bd
# ╠═3a765d51-95d0-444d-adab-f794190914f2
# ╟─fec4bcfb-b88a-4008-82fa-194b8f7264e0
# ╠═116ffb13-8b9a-40b4-aa1e-88d645d1124a
# ╠═8de19918-2a32-4b74-a6c4-3fa229c36afd
# ╠═dd50d34b-edb3-4e3f-9a2f-77bfe0ed3fd0
# ╟─bdbd30d7-8714-44bb-a81f-adf988a225a4
# ╠═87b16571-05a3-4bf0-bc12-3f7bb302e364
# ╠═2b4bd381-87ce-4b0c-8753-4b5a68a7389e
# ╟─76f08f06-9351-4815-8881-dc978b0e2031
# ╠═c6b3192f-efa3-4ad5-92c0-2eac700f6b26
# ╠═35f75f0a-08c5-47ea-9930-e70f20b8a64a


text:
push!(LOAD_PATH, "../src/")

using Pkg; Pkg.add("Documenter")
using Documenter, SeisMain

makedocs(
	modules = [SeisMain],
	doctest = false,
 	clean = true,
	checkdocs = :all,
	sitename = "SeisMain.jl",
	format = Documenter.HTML(prettyurls = get(ENV, "CI", nothing)== "true"),
	pages = [
	       "Home" => "index.md",
	       "Manual" => Any[
	       		"Guide" => "man/guide.md"],
		"Library" => Any[
			  "Public" => "lib/public.md",
				],
		],
)

deploydocs(
    repo = "github.com/SeismicJulia/SeisMain.jl.git",
    target = "build",
    deps = nothing,
    make = nothing
)


text:
"""
Module UniformHexMesh

Includes mesh related utility functions
"""

module UniformHexMesh

using SparseArrays
using CommonUtils # for meshgrid

export uniform_hex_mesh
export hex_face_vertices

"""
uniform_hex_mesh(Kx::Int,Ky::Int)

Matlab uniform hexahedral mesh.

# Examples
```jldoctest
```
"""

function uniform_hex_mesh(Nx,Ny,Nz)
        Nxp = Nx+1
        Nyp = Ny+1
        Nzp = Nz+1
        Nv = convert(Int,Nxp*Nyp*Nzp)
        K  = convert(Int,Nx*Ny*Nz)

        x1D = LinRange(-1,1,Nxp)
        y1D = LinRange(-1,1,Nyp)
        z1D = LinRange(-1,1,Nzp)

        # hack to work with old vertex ordering
        function mymeshgrid(x1D,y1D,z1D)
                Np = length(x1D)*length(y1D)*length(z1D)
                x = zeros(Np)
                y = zeros(Np)
                z = zeros(Np)
                sk = 1
                for k = 1:length(z1D)
                        for j = 1:length(y1D)
                                for i = 1:length(x1D)
                                        x[sk] = x1D[i]
                                        y[sk] = y1D[j]
                                        z[sk] = z1D[k]
                                        sk += 1
                                end
                        end
                end
                return x,y,z
        end
        x, y, z = mymeshgrid(x1D,y1D,z1D)

        EToV = zeros(Int,K,8)
        k = 1
        for e = 1:K
                em = e-1
                k = div(em,(Nx*Ny))
                j = div(em - k*Nx*Ny,Nx)
                i = em % Nx

                EToV[e,1] = i     + Nxp*j     + Nxp*Nyp*k
                EToV[e,2] = (i+1) + Nxp*j     + Nxp*Nyp*k
                EToV[e,3] = i     + Nxp*(j+1) + Nxp*Nyp*k
                EToV[e,4] = (i+1) + Nxp*(j+1) + Nxp*Nyp*k
                EToV[e,5] = i     + Nxp*j     + Nxp*Nyp*(k+1)
                EToV[e,6] = (i+1) + Nxp*j     + Nxp*Nyp*(k+1)
                EToV[e,7] = i     + Nxp*(j+1) + Nxp*Nyp*(k+1)
                EToV[e,8] = (i+1) + Nxp*(j+1) + Nxp*Nyp*(k+1)
        end
        EToV = @. EToV + 1 # re-index to 1 index

        VX = x[:];
        VY = y[:];
        VZ = z[:];
        return VX[:],VY[:],VZ[:],EToV
end

function uniform_hex_mesh(Kx)
        return uniform_hex_mesh(Kx,Kx,Kx)
end

function hex_face_vertices()
        x1D = LinRange(-1,1,2)
        r, s, t = meshgrid(x1D,x1D,x1D)
        fv1 = map(x->x[1], findall(@. abs(r+1) < 1e-10))
        fv2 = map(x->x[1], findall(@. abs(r-1) < 1e-10))
        fv3 = map(x->x[1], findall(@. abs(s+1) < 1e-10))
        fv4 = map(x->x[1], findall(@. abs(s-1) < 1e-10))
        fv5 = map(x->x[1], findall(@. abs(t+1) < 1e-10))
        fv6 = map(x->x[1], findall(@. abs(t-1) < 1e-10))
        return fv1,fv2,fv3,fv4,fv5,fv6
end

end

max_stars_repo_name: jlchan/ESDG-CNS

max_issues_repo_name: jlchan/ESDG-CNS

max_forks_repo_name: jlchan/ESDG-CNS


text:
using Statistics: median

"""
    KNNDetector(k=5,
                metric=Euclidean,
                algorithm=:kdtree,
                leafsize=10,
                reorder=true,
                reduction=:maximum)

Calculate the anomaly score of an instance based on the distance to its k-nearest neighbors.

Parameters
----------
$K_PARAM

$KNN_PARAMS

    reduction::Symbol
One of `(:maximum, :median, :mean)`. (`reduction=:maximum`) was proposed by [1]. Angiulli et al. [2] proposed sum to
reduce the distances, but mean has been implemented for numerical stability.

Examples
--------
$(SCORE_UNSUPERVISED("KNNDetector"))

References
----------
[1] Ramaswamy, Sridhar; Rastogi, Rajeev; Shim, Kyuseok (2000): Efficient Algorithms for Mining Outliers from Large Data
Sets.

[2] Angiulli, Fabrizio; Pizzuti, Clara (2002): Fast Outlier Detection in High Dimensional Spaces.
"""
OD.@detector mutable struct KNNDetector <: UnsupervisedDetector
    k::Integer = 5::(_ > 0)
    metric::DI.Metric = DI.Euclidean()
    algorithm::Symbol = :kdtree::(_ in (:kdtree, :balltree))
    static::Union{Bool,Symbol} = :auto::(_ in (true, false, :auto))
    leafsize::Integer = 10::(_ ≥ 0)
    reorder::Bool = true
    parallel::Bool = false
    reduction::Symbol = :maximum::(_ in (:maximum, :median, :mean))
end

struct KNNModel <: DetectorModel
    tree::NN.NNTree
end

function OD.fit(detector::KNNDetector, X::Data; verbosity)::Fit
    X = prepare_data(X, detector.static)

    # create the specified tree
    tree = @tree detector X

    # use tree to calculate distances
    _, dists = knn_others(tree, X, detector.k)

    # reduce distances to outlier score
    scores = _knn(dists, detector.reduction)
    return KNNModel(tree), scores
end

function OD.transform(detector::KNNDetector, model::KNNModel, X::Data)::Scores
    X = prepare_data(X, detector.static)

    if detector.parallel
        idxs, dists = knn_parallel(model.tree, X, detector.k)
        return _knn(dists, detector.reduction)
    else
        idxs, dists = NN.knn(model.tree, X, detector.k)
        return _knn(dists, detector.reduction)
    end
end

@inline function _knn(distances::AbstractVector{<:AbstractVector}, reduction::Symbol)::Scores
    # Helper function to reduce `k` distances to a single distance.
    if reduction == :maximum
        return maximum.(distances)
    elseif reduction == :median
        return median.(distances)
    elseif reduction == :mean
        return mean.(distances)
    end
end


text:
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.

module Runner
include("load.jl")
include("../shared/load.jl")
using ADPerfTest
using GMMData
using BAData
using HandData
using LSTMData
using Benchmark

test_type = lowercase(ARGS[1])
module_path = ARGS[2]
input_filepath = ARGS[3]
output_prefix = ARGS[4]
minimum_measurable_time = parse(Float64, ARGS[5])
nruns_f = parse(Int,ARGS[6])
nruns_J = parse(Int,ARGS[7])
time_limit = parse(Float64, ARGS[8])
replicate_point = size(ARGS,1) >= 9 && ARGS[9] == "-rep"

if !ispath(module_path) || isdir(module_path)
    throw(ArgumentError("File $module_path does not exist."))
end
if !endswith(module_path, ".jl")
    throw(ArgumentError("File $module_path is expected to be a Julia module and end with '.jl'."))
end
if !ispath(input_filepath) || isdir(input_filepath)
    throw(ArgumentError("File $input_filepath does not exist."))
end

module_abs_path = abspath(module_path)
module_dir = dirname(module_abs_path)
module_name = basename(module_path)[1:end - 3]
if !(module_dir ∈ LOAD_PATH)
    push!(LOAD_PATH, module_dir)
end

input_filename = basename(input_filepath)
lastdot = findlast(".", input_filename)
if (lastdot === nothing)
    input_name = input_filename
else
    input_name = input_filename[1:first(lastdot) - 1]
end

if test_type == "gmm"
    input = load_gmm_input(input_filepath, replicate_point)
    module_display_name = module_name[1:end - 3]
elseif test_type == "ba"
    input = load_ba_input(input_filepath)
    module_display_name = module_name[1:end - 2]
elseif test_type == "hand"
    input = load_hand_input(input_filepath, false)
    module_display_name = module_name[1:end - 4]
elseif test_type == "hand-complicated"
    input = load_hand_input(input_filepath, true)
    module_display_name = module_name[1:end - 4]
elseif test_type == "lstm"
    input = load_lstm_input(input_filepath)
    module_display_name = module_name[1:end - 4]
else
    throw(ArgumentError("Julia runner doesn't support tests of $test_type type."))
end

run_benchmark(input, input_name, module_name, output_prefix, module_display_name, minimum_measurable_time, nruns_f, nruns_J, time_limit)

end

max_stars_repo_name: dsyme/ADBench

max_issues_repo_name: dsyme/ADBench

max_forks_repo_name: dsyme/ADBench


text:
# Filters using Nullable types to represent missing measurements

function update{T}(kf::KalmanFilter,y::Nullable{Vector{T}})
    if isnull(y.y)
        return kf
    else
        return update(kf,Observation(get(y)))
    end
end

function update!{T}(kf::KalmanFilter,y::Nullable{Vector{T}})
    if isnull(y)
        return kf
    else
        update!(kf,Observation(get(y)))
        return kf
    end
end

function predictupdate{T}(kf::BasicKalmanFilter,y::Nullable{Vector{T}})
    update(predict(kf),y)
end

function predictupdate!{T}(kf::BasicKalmanFilter,y::Nullable{Vector{T}})
    update!(predict!(kf),y)
end


text:
### A Pluto.jl notebook ###
# v0.12.18

using Markdown
using InteractiveUtils

# ╔═╡ 330763c4-f1e2-11ea-071a-b13a3bea37e9
md"# Arrays: Slices and views"

# ╔═╡ 50e2aaa2-f1e2-11ea-37b2-9d23357ab558
md"Since arrays are a very common way of storing data (but by no means the only way!), it is important to know how to manipulate them."

# ╔═╡ 614126a8-f1e2-11ea-08ef-3d787d155416
md"Suppose we start with a vector (1-dimensional array) of all ones:"

# ╔═╡ 6d6e5194-f1e2-11ea-116c-c191e52dd2af
v = ones(Int, 10)

# ╔═╡ 79332324-f1e2-11ea-3c82-39cad3d2391c
md"""We can **index** into the array to extract a certain element using square brackets ("`[`" and "`]`"):"""

# ╔═╡ 8b0fca3e-f1e2-11ea-2b70-011aaeeb94cc
v[3]

# ╔═╡ 8cbf61b6-f1e2-11ea-3b49-cb59792e1fc1
md"And we can modify that element using the same syntax:"

# ╔═╡ a87a0238-f1e2-11ea-272d-0d8cd4795df6
v[3] = 2

# ╔═╡ abbf2a72-f1e2-11ea-3e76-2bbe6e068c59
v

# ╔═╡ b0bafcae-f1e2-11ea-1c5a-a98c25cf6bd4
md"If we want to extract a subset of the array, we can do so by indexing using a **range**:"

# ╔═╡ c8ec70ac-f1e2-11ea-30d6-7fc4e1f3cf63
v[3:5]

# ╔═╡ d6903d5e-f1e2-11ea-1525-35f7f6aa2f66
md"We call this a **slice** of the array."

# ╔═╡ 7c447b7a-f1e3-11ea-0ef2-c996690ae871
md"## Modifying a slice: Broadcasting"

# ╔═╡ cd2c8f1a-f1e2-11ea-1449-73d40f742c60
md"How can we *modify* this slice, say to replace them all by the value 4? Intuitively you might expect to be able to write"

# ╔═╡ edec3322-f1e2-11ea-32b8-ebd1445b18e2
v[3:5] = 4

# ╔═╡ 0ed6e116-f1e3-11ea-38ed-693262492cf2
md"""
But Julia does *not* allow this. The problem is that the two objects on the two sides of the assignment are different types: an array on the left, and a number on the right. What we want to do is modify the array *element by element*; for this we need to **broadcast** the assignment using "`.`":
"""

# ╔═╡ 446a93ba-f1e3-11ea-2957-e9c3bb7b66cd
v[3:5] .= 4

# ╔═╡ 4974c36c-f1e3-11ea-3543-63fce86af871
md"Let's check if this modified the original array:"

# ╔═╡ 86be1e4e-f1e3-11ea-1212-6949dd55b8e8
v

# ╔═╡ 887640e0-f1e3-11ea-2d35-a9a9d1ae1897
md"Success!"

# ╔═╡ 8d6fdcfa-f1e3-11ea-2f50-9783f4cd6339
md"Following the above idea, if we provide a new array of the correct length, we can also modify the array:"

# ╔═╡ 9b504332-f1e3-11ea-35a2-8d33db468a83
v[3:5] = [5, 6, 7]

# ╔═╡ a1685124-f1e3-11ea-396c-cd12b8cdfdbd
v

# ╔═╡ b6e74bf4-f1e3-11ea-1eab-7db865915fe8
md"## Array slices"

# ╔═╡ c1562b4e-f1e3-11ea-2b73-0d18fc361323
md"Now suppose we give a name to that array slice:"

# ╔═╡ d69da0d8-f1e3-11ea-092b-7b7e9fd262ce
w = v[3:5]

# ╔═╡ afbeb970-f1e3-11ea-3658-c973f6808f6d
md"An important question is the following:

> *What happens if we modify `w`*?

Take a moment to think about this before carrying on. What do you expect to happen? What are the possibilities?
"

# ╔═╡ fc774f0c-f1e3-11ea-0e5a-3141ec04348d
md"(Seriously, think about it!)"

# ╔═╡ ffa05138-f1e3-11ea-280e-bf7da83de269
md"Of course, after thinking about it we should ask Julia what actually happens!"

# ╔═╡ 12dbdf38-f1e4-11ea-0449-b39ed2f5f12d
md"Here's the current situation:"

# ╔═╡ 1123aade-f1e4-11ea-3cce-4534d7a72a60
w

# ╔═╡ 19ca7c32-f1e4-11ea-39a5-3dcf97e6fbcf
md"Now let's change the first element of `w`:"

# ╔═╡ 21a48678-f1e4-11ea-1143-c709ee295e0d
w[1] = 8

# ╔═╡ 25abc85a-f1e4-11ea-156b-7f15f0474e3b
w

# ╔═╡ 2765efc0-f1e4-11ea-1324-ede5df51f047
md"As expected, we modified `w`'s first element. But what happened to `v`?"

# ╔═╡ 3eb46116-f1e4-11ea-29e9-c74e8478d803
v

# ╔═╡ 4084ffca-f1e4-11ea-2d5d-abb022cd41cc
md"We see that *`v` did not get modified!* This is surprising to many people.

What is going on?"

# ╔═╡ 59e92208-f1e4-11ea-30a0-4d6d44bb9ae6
md"What is happening is that the slice syntax `v[3:5]` actually creates a *copy* of the data in a new place in memory. Then `w` is a label, or pointer, for that new piece of memory. So modifying it does not touch the original values at all!

We should be aware of this whenever we are tempted to modify slices."

# ╔═╡ aa48f298-f1e4-11ea-19ef-f120e959faa4
md"## Array views"

# ╔═╡ addcc056-f1e4-11ea-0090-eb82f5545c37
md"Of course, there are times when we do *not* want to make a copy. We might want to give a name to a slice of an array and manipulate the *original* array using the new name.

To do so we need to make a **view** of the array. This is literally like a window that allows us to view (read and write) to the *same data*.

To do this we use the `view` function:
"

# ╔═╡ f5cc5e80-f1e4-11ea-027c-9bef1852423d
z = view(v, 3:5)

# ╔═╡ 218aa662-f1e5-11ea-1516-15ffd9c9ba08
md"Now what happens if we modify `z` element by element using broadcasting?"

# ╔═╡ 2b955ddc-f1e5-11ea-1ca1-e91c81100478
z .= 9

# ╔═╡ 3a957e84-f1e5-11ea-2131-21fdd5d8c5d5
z

# ╔═╡ 3c96558c-f1e5-11ea-2109-79717714c977
md"`z` changed as we expected. But what about the original vector `v`?"

# ╔═╡ 4ed5d79a-f1e5-11ea-1515-3be1b3fa9a2b
v

# ╔═╡ 50259ee6-f1e5-11ea-317b-11a542b6cd9e
md"`v` also changed! This confirms that `z` is a window onto the same underlying data stored inside the block of memory labelled with the name `v`."

# ╔═╡ ff65101a-f1e4-11ea-1b51-f5b09ae1f0eb
md"Let's compare the types of `w` and `z`:"

# ╔═╡ fbd656aa-f1e4-11ea-2de2-61abc56ea71d
typeof(w), typeof(z)

# ╔═╡ 0ab7d32e-f1e5-11ea-048b-a74d7515b0c5
md"We see that they are of similar, but different types. `w` looks like other arrays we have seen, but `z` is a new type, called a `SubArray`."

# ╔═╡ 781e93da-f1e5-11ea-3d3f-57842f69c032
md"## Nicer syntax for views"

# ╔═╡ 83c8711a-f1e5-11ea-30c4-87104a7c1c2a
md"Now we know how to produce views / `SubArray`s. But to do so we had to move away from the nice, compact array slicing syntax, from `v[3:5]` to `view(v, 3:5)`. Could there be a way to combine the two?"

# ╔═╡ fb50b922-f1e5-11ea-0049-773084392b80
md"In fact there is: Julia provides a **macro** `@view` that converts the slicing syntax into a view:"

# ╔═╡ 0d25ffae-f1e6-11ea-05c4-49b25532ae49
z2 = @view v[3:5]

# ╔═╡ 27c47f2a-f1e6-11ea-3aa2-bb05fcd0e566
typeof(z2)

# ╔═╡ 2998132a-f1e6-11ea-3ccc-7951c392e9f3
z2 .= 10

# ╔═╡ 2c010994-f1e6-11ea-0022-79d21e0764b8
v

# ╔═╡ 2d6f84e2-f1e6-11ea-2683-8be3ea0d39ac
md"What is going on here? The macro `@view` literally takes the piece of Julia code `v[3:5]` and *replaces* it with the new piece of code `view(v, 3:5)`. Please see the separate video on macros for more detail!"

# ╔═╡ 4ff57544-f1e6-11ea-0274-15cc7917c3e3
md"Finally, there is also a macro `@views`, which replaces *all* slices by views in an entire expression."

# ╔═╡ ba6e586c-f1e8-11ea-1aba-ab1ba56ace6d
md"## Matrices: slices and views"

# ╔═╡ f0753bec-f1e8-11ea-0776-99b556737a05
md"Slices and views work the same way for matrices. For example, let's start with a matrix:"

# ╔═╡ cdf780b6-f1e8-11ea-2c90-bdae4d1dacaf
M = [10i + j for i in 0:5, j in 1:4]

# ╔═╡ 3464d66e-f1e9-11ea-0e53-e99f5c962594
md"We can make slices and views of matrices using extensions of the syntax we saw above for vectors:"

# ╔═╡ 4f3451e0-f1e9-11ea-07b4-456c5a6fa4c5
M[3:5, 1:2]

# ╔═╡ 5cb68536-f1e9-11ea-272e-179f8dfe8acc
view(M, 3:5, 1:2)

# ╔═╡ 615a74ee-f1e9-11ea-1f71-3be78c5545b2
@view M[3:5, 1:2]

# ╔═╡ 670bbc0e-f1e9-11ea-01a1-93cb78e8cb90
md"You should check that slices and views have the same behaviour that we described above."

# ╔═╡ 94c85c38-f1e9-11ea-3ab8-976569b36e23
md"## Reshaping matrices"

# ╔═╡ eb96a16a-f1e8-11ea-0398-1715aac5fb2d
md"There's something else we would like to be able to do with matrices: **reshape** them. We can do so using the `reshape` function:"

# ╔═╡ 24cefdea-f1e9-11ea-3c37-c3626e555e4e
M2 = reshape(M, 3, 8)

# ╔═╡ c0dca20e-5d6f-11eb-16dc-efa62e027511
typeof(M2)

# ╔═╡ c9e36c90-5d6f-11eb-0b8e-6538834cc678
M2[1, 2] = 42

# ╔═╡ dec30d50-5d6f-11eb-2b8a-6d3bb29422e4
M

# ╔═╡ e40f19c0-5d6f-11eb-3989-490c5629d307
M2[2, 1] = 42

# ╔═╡ 0a056c60-5d70-11eb-11fc-85569c278285
M

# ╔═╡ cae01608-f1e9-11ea-0878-a7b281aa6113
md"(Note the order in which the elements were taken.)"

# ╔═╡ 2b3cbb88-f1e9-11ea-16f1-436de44841de
md"Given the discussion so far, you are hopefully asking yourself: Is this a copy or a view? We'll leave it to you to find out!"

# ╔═╡ c36d3770-f1e9-11ea-2fa5-5ddb60c2adce
md"Similarly, we might want to turn the matrix into a vector. For this we can use the `vec` function:"

# ╔═╡ ecb7395a-f1e9-11ea-2346-abbd7f1bd73e
vv = vec(M)

# ╔═╡ 663c99e0-5d70-11eb-3e33-0fa3b4241e9e
vv[7] = 42

# ╔═╡ 785615be-5d70-11eb-1089-236000da5068
M

# ╔═╡ f0eb9eaa-f1e9-11ea-1bd5-3f47ff24cbf6
md"Again you should check if this is a copy or a view. The order of the elements here is showing us the **storage order** of a matrix, i.e. in which order in the (linear) memory inside the computer the elements of the 2D matrix are being stored."

# ╔═╡ 648b17b6-f1e6-11ea-3351-23b46a2e265d
md"## Summary"

# ╔═╡ 689e4c60-f1e6-11ea-3782-43decd275b5f
md"In summary, we need to be aware of when we want to copy data from an array, and when we actually want to avoid copying and make views instead. A slice like `v[1:3]` makes a copy *unless* there's an `@view` or `@views` macro telling you otherwise.

For other operations like `reshape` and `vec` it's also critical to know if they make copies or views.
"

# ╔═╡ Cell order:
# ╟─330763c4-f1e2-11ea-071a-b13a3bea37e9
# ╟─50e2aaa2-f1e2-11ea-37b2-9d23357ab558
# ╟─614126a8-f1e2-11ea-08ef-3d787d155416
# ╠═6d6e5194-f1e2-11ea-116c-c191e52dd2af
# ╟─79332324-f1e2-11ea-3c82-39cad3d2391c
# ╠═8b0fca3e-f1e2-11ea-2b70-011aaeeb94cc
# ╟─8cbf61b6-f1e2-11ea-3b49-cb59792e1fc1
# ╠═a87a0238-f1e2-11ea-272d-0d8cd4795df6
# ╠═abbf2a72-f1e2-11ea-3e76-2bbe6e068c59
# ╟─b0bafcae-f1e2-11ea-1c5a-a98c25cf6bd4
# ╠═c8ec70ac-f1e2-11ea-30d6-7fc4e1f3cf63
# ╟─d6903d5e-f1e2-11ea-1525-35f7f6aa2f66
# ╟─7c447b7a-f1e3-11ea-0ef2-c996690ae871
# ╟─cd2c8f1a-f1e2-11ea-1449-73d40f742c60
# ╠═edec3322-f1e2-11ea-32b8-ebd1445b18e2
# ╟─0ed6e116-f1e3-11ea-38ed-693262492cf2
# ╠═446a93ba-f1e3-11ea-2957-e9c3bb7b66cd
# ╟─4974c36c-f1e3-11ea-3543-63fce86af871
# ╠═86be1e4e-f1e3-11ea-1212-6949dd55b8e8
# ╟─887640e0-f1e3-11ea-2d35-a9a9d1ae1897
# ╟─8d6fdcfa-f1e3-11ea-2f50-9783f4cd6339
# ╠═9b504332-f1e3-11ea-35a2-8d33db468a83
# ╠═a1685124-f1e3-11ea-396c-cd12b8cdfdbd
# ╟─b6e74bf4-f1e3-11ea-1eab-7db865915fe8
# ╟─c1562b4e-f1e3-11ea-2b73-0d18fc361323
# ╠═d69da0d8-f1e3-11ea-092b-7b7e9fd262ce
# ╟─afbeb970-f1e3-11ea-3658-c973f6808f6d
# ╟─fc774f0c-f1e3-11ea-0e5a-3141ec04348d
# ╟─ffa05138-f1e3-11ea-280e-bf7da83de269
# ╟─12dbdf38-f1e4-11ea-0449-b39ed2f5f12d
# ╠═1123aade-f1e4-11ea-3cce-4534d7a72a60
# ╟─19ca7c32-f1e4-11ea-39a5-3dcf97e6fbcf
# ╠═21a48678-f1e4-11ea-1143-c709ee295e0d
# ╠═25abc85a-f1e4-11ea-156b-7f15f0474e3b
# ╟─2765efc0-f1e4-11ea-1324-ede5df51f047
# ╠═3eb46116-f1e4-11ea-29e9-c74e8478d803
# ╟─4084ffca-f1e4-11ea-2d5d-abb022cd41cc
# ╟─59e92208-f1e4-11ea-30a0-4d6d44bb9ae6
# ╟─aa48f298-f1e4-11ea-19ef-f120e959faa4
# ╟─addcc056-f1e4-11ea-0090-eb82f5545c37
# ╠═f5cc5e80-f1e4-11ea-027c-9bef1852423d
# ╟─218aa662-f1e5-11ea-1516-15ffd9c9ba08
# ╠═2b955ddc-f1e5-11ea-1ca1-e91c81100478
# ╠═3a957e84-f1e5-11ea-2131-21fdd5d8c5d5
# ╟─3c96558c-f1e5-11ea-2109-79717714c977
# ╠═4ed5d79a-f1e5-11ea-1515-3be1b3fa9a2b
# ╟─50259ee6-f1e5-11ea-317b-11a542b6cd9e
# ╟─ff65101a-f1e4-11ea-1b51-f5b09ae1f0eb
# ╠═fbd656aa-f1e4-11ea-2de2-61abc56ea71d
# ╟─0ab7d32e-f1e5-11ea-048b-a74d7515b0c5
# ╟─781e93da-f1e5-11ea-3d3f-57842f69c032
# ╟─83c8711a-f1e5-11ea-30c4-87104a7c1c2a
# ╟─fb50b922-f1e5-11ea-0049-773084392b80
# ╠═0d25ffae-f1e6-11ea-05c4-49b25532ae49
# ╠═27c47f2a-f1e6-11ea-3aa2-bb05fcd0e566
# ╠═2998132a-f1e6-11ea-3ccc-7951c392e9f3
# ╠═2c010994-f1e6-11ea-0022-79d21e0764b8
# ╟─2d6f84e2-f1e6-11ea-2683-8be3ea0d39ac
# ╟─4ff57544-f1e6-11ea-0274-15cc7917c3e3
# ╟─ba6e586c-f1e8-11ea-1aba-ab1ba56ace6d
# ╟─f0753bec-f1e8-11ea-0776-99b556737a05
# ╠═cdf780b6-f1e8-11ea-2c90-bdae4d1dacaf
# ╟─3464d66e-f1e9-11ea-0e53-e99f5c962594
# ╠═4f3451e0-f1e9-11ea-07b4-456c5a6fa4c5
# ╠═5cb68536-f1e9-11ea-272e-179f8dfe8acc
# ╠═615a74ee-f1e9-11ea-1f71-3be78c5545b2
# ╟─670bbc0e-f1e9-11ea-01a1-93cb78e8cb90
# ╟─94c85c38-f1e9-11ea-3ab8-976569b36e23
# ╟─eb96a16a-f1e8-11ea-0398-1715aac5fb2d
# ╠═24cefdea-f1e9-11ea-3c37-c3626e555e4e
# ╠═c0dca20e-5d6f-11eb-16dc-efa62e027511
# ╠═c9e36c90-5d6f-11eb-0b8e-6538834cc678
# ╠═dec30d50-5d6f-11eb-2b8a-6d3bb29422e4
# ╠═e40f19c0-5d6f-11eb-3989-490c5629d307
# ╠═0a056c60-5d70-11eb-11fc-85569c278285
# ╟─cae01608-f1e9-11ea-0878-a7b281aa6113
# ╟─2b3cbb88-f1e9-11ea-16f1-436de44841de
# ╟─c36d3770-f1e9-11ea-2fa5-5ddb60c2adce
# ╠═ecb7395a-f1e9-11ea-2346-abbd7f1bd73e
# ╠═663c99e0-5d70-11eb-3e33-0fa3b4241e9e
# ╠═785615be-5d70-11eb-1089-236000da5068
# ╟─f0eb9eaa-f1e9-11ea-1bd5-3f47ff24cbf6
# ╟─648b17b6-f1e6-11ea-3351-23b46a2e265d
# ╟─689e4c60-f1e6-11ea-3782-43decd275b5f

max_stars_repo_name: mathijsvdv/ComputationalThinking

max_issues_repo_name: mathijsvdv/ComputationalThinking

max_forks_repo_name: mathijsvdv/ComputationalThinking


text:
function Pauli(i)

if i==0

return [1.0 0.0; 0.0 1.0]

elseif i==1

return [0.0 1.0; 1.0 0.0]

elseif i==2

return [0. -1.0im; 1.0im 0.0]

elseif i==3

return [1.0 0.0 ; 0.0 -1.0]

else throw(DomainError())

end

end


text:
"""
    MWParameters

Returns MWParameters with default settings where not specified.

# Arguments
* `epsilon::Float=1.0`: Each iterations is `epsilon`-differentially private
* `iterations::Integer=10`: Number of iterations
* `repetitions::Integer=10`: Repeatedly update with previously selected queries.
* `noisy_init::Boolean=false`: Initialize with noisy histogram if true.
* `verbose::Boolean=false`: Print timing and error information (not private)
* `init_budget=0.05: fraction of the epsilon for the noisy initialization
* `noisy_max_budget: fraction of the badget from every step for for the noisy max
"""
function MWParameters(; epsilon=1.0,
                        iterations=10,
                        repetitions=10,
                        noisy_init=false,
                        verbose=false,
                        init_budget=0.05,
                        noisy_max_budget=0.5
                        )
    MWParameters(epsilon, iterations, repetitions, noisy_init, verbose, init_budget, noisy_max_budget)
end

"""
    noisy_max(mwstate::MWState)

Select index of query with largest error after noise addition.
"""
function noisy_max(mwstate::MWState, noisy_max_budget::Float64)
    diffs = mwstate.real_answers - evaluate(mwstate.queries, mwstate.synthetic)
    diffs[collect(keys(mwstate.measurements))] .= 0.0
    real_index = argmax(abs.(diffs) + rand(Laplace(0.0, mwstate.scale/noisy_max_budget), length(diffs)))
    real_index
end

"""
    update!(mwstate::MWState, qindex::QueryIndex)

Perform multiplicative weights update with query given by `qindex`.
"""
function update!(mwstate::MWState, qindex::QueryIndex)
    query = get(mwstate.queries, qindex)
    error = mwstate.measurements[qindex] - evaluate(query, mwstate.synthetic)
    update!(query, mwstate.synthetic, error)
end

"""
    mwem(queries::Queries, data::Data, ps::MWParameters)

Private Multiplicative Weights (MWEM) repeatedly selects largest error query
and performs multiplicative weights update.
"""
function mwem(queries::Queries, data::Data, ps=MWParameters())

    # Initialization
    time = @elapsed mwstate = initialize(queries, data, ps)

    if ps.verbose
        error = mean_squared_error(mwstate)
        print("Iter.\t Mean sq err\t time (sec)\n")
        @printf("0\t %.3f\t\t %.3f\n", error, time)
    end

    # Iterations
    for t = 1:ps.iterations
        time = @elapsed begin
            # select query via noisy max
            qindex = noisy_max(mwstate, ps.noisy_max_budget)
            mwstate.measurements[qindex] =
              mwstate.real_answers[qindex] + rand(Laplace(0.0, mwstate.scale/(1-ps.noisy_max_budget)))

            # update synthetic data approximation
            update!(mwstate, qindex)

            # repeatedly update on previously measured queries in random order
            for i = 1:ps.repetitions
                for qindex in shuffle(collect(keys(mwstate.measurements)))
                    update!(mwstate, qindex)
                end
            end
        end

        if ps.verbose
            error_mean = mean_squared_error(mwstate)
            error_max = maximum_error(mwstate)
            @printf("itr: %d\t mean_error: %.3f\t\t %.3f\n", t, error_mean, time)
            @printf("itr: %d\t max_error: %.3f\t\t %.3f\n", t, error_max, time)
        end
    end

    mwstate
end


text:
import Base: write

"""
`write{T<:FileFormat}(filename::AbstractString, object, format::Type{T}, mode::ASCIIString="w")`

This function opens a file with `filename` and `mode` (default: "w")
and writes (`print`) the `object` with the given `format`.
Gzipped files should end on `.gz`.
"""
function write(filename::AbstractString, object, format::Type{T},
               mode::String="w") where T<:FileFormat
    fh = open(filename, mode)
    if endswith(filename, ".gz")
        fh = GzipCompressorStream(fh)
    end
    try
        print(fh, object, format)
    finally
        close(fh)
    end
    nothing
end


text:
# BSE kernel for the t channel
function compute_t_BSE!(
    Λ    :: Float64,
    buff :: Matrix{Float64},
    v    :: Float64,
    dv   :: Float64,
    t    :: Float64,
    vt   :: Float64,
    vtp  :: Float64,
    r    :: Reduced_lattice,
    m    :: Mesh,
    a    :: Action_u1_dm,
    temp :: Array{Float64, 3}
    )    :: Nothing

    # get propagator and overlap
    p       = -get_propagator(Λ, v + 0.5 * t, v - 0.5 * t, m, a)
    overlap = r.overlap

    # get buffers for left non-local vertex
    bs1 = get_buffer_s( v + vt, 0.5 * (-t - v + vt), 0.5 * (-t + v - vt), m)
    bt1 = get_buffer_empty()
    bu1 = get_buffer_u(-v + vt, 0.5 * (-t + v + vt), 0.5 * ( t + v + vt), m)

    # get buffers for right non-local vertex
    bs2 = get_buffer_s(v + vtp, 0.5 * (-t + v - vtp), 0.5 * (-t - v + vtp), m)
    bt2 = get_buffer_t(t, v, vtp, m)
    bu2 = get_buffer_u(v - vtp, 0.5 * (-t + v + vtp), 0.5 * ( t + v + vtp), m)

    # get buffers for local left vertex
    bs3 = get_buffer_s( v + vt, 0.5 * (t + v - vt), 0.5 * (-t + v - vt), m)
    bt3 = get_buffer_t(-v + vt, 0.5 * (t + v + vt), 0.5 * (-t + v + vt), m)
    bu3 = get_buffer_empty()

    # get buffers for local right vertex
    bs4 = get_buffer_s(v + vtp, 0.5 * (t - v + vtp), 0.5 * (-t - v + vtp), m)
    bt4 = get_buffer_t(v - vtp, 0.5 * (t + v + vtp), 0.5 * (-t + v + vtp), m)
    bu4 = get_buffer_u(t, vtp, v, m)

    # cache local vertex values
    v3xx, v3zz, v3DM, v3dd, v3zd, v3dz = get_Γ(1, bs3, bt3, bu3, r, a, ch_u = false)
    v4xx, v4zz, v4DM, v4dd, v4zd, v4dz = get_Γ(1, bs4, bt4, bu4, r, a)

    # cache vertex values for all lattice sites in temporary buffer
    get_Γ_avx!(r, bs1, bt1, bu1, a, temp, 1, ch_t = false)
    get_Γ_avx!(r, bs2, bt2, bu2, a, temp, 2)

    # compute contributions for all lattice sites
    for i in eachindex(r.sites)
        # read cached values for site i
        v1xx = temp[i, 1, 1]
        v1zz = temp[i, 2, 1]
        v1DM = temp[i, 3, 1]
        v1dd = temp[i, 4, 1]
        v1zd = temp[i, 5, 1]
        v1dz = temp[i, 6, 1]

        v2xx = temp[i, 1, 2]
        v2zz = temp[i, 2, 2]
        v2DM = temp[i, 3, 2]
        v2dd = temp[i, 4, 2]
        v2zd = temp[i, 5, 2]
        v2dz = temp[i, 6, 2]

        # compute contribution at site i
        Γxx = -p * (v1DM * v4dz - v1DM * v4zd + v1xx * v4dd - v1xx * v4zz +
                    v3dd * v2xx + v3dz * v2DM - v3zd * v2DM - v3zz * v2xx)

        Γzz = -p * (v1zz * v4dd + 2.0 * v1zd * v4DM - v1zd * v4zd + v1zz * v4zz - 2.0 * v1zz * v4xx - v1zd * v4dz -
                    2.0 * v3DM * v2dz - v3dz * v2dz + v3dd * v2zz - 2.0 * v3xx * v2zz + v3zz * v2zz - v3zd * v2dz)

        ΓDM = -p * (v1DM * v4dd - v1xx * v4dz + v1xx * v4zd - v1DM * v4zz -
                    v3dz * v2xx + v3dd * v2DM + v3zd * v2xx - v3zz * v2DM)

        Γdd = -p * (-v1dz * v4dz + 2.0 * v1dd * v4xx + v1dd * v4zz - v1dz * v4zd - 2.0 * v1dz * v4DM + v1dd * v4dd +
                    2.0 * v3DM * v2zd + 2.0 * v3xx * v2dd + v3zz * v2dd - v3dz * v2zd + v3dd * v2dd - v3zd * v2zd)

        Γzd = -p * (v1zd * v4zz + v1zd * v4dd + 2.0 * v1zd * v4xx + v1zz * v4zd + 2.0 * v1zz * v4DM + v1zz * v4dz +
                    v3zd * v2dd + 2.0 * v3DM * v2dd + v3dd * v2zd + v3zz * v2zd - 2.0 * v3xx * v2zd + v3dz * v2dd)

        Γdz = -p * (-2.0 * v1dd * v4DM + v1dd * v4zd + v1dd * v4dz + v1dz * v4zz + v1dz * v4dd - 2.0 * v1dz * v4xx +
                    v3zd * v2zz + 2.0 * v3xx * v2dz + v3dd * v2dz + v3dz * v2zz - 2.0 * v3DM * v2zz + v3zz * v2dz)

        # determine overlap for site i
        overlap_i = overlap[i]

        # determine range for inner sum
        Range = size(overlap_i, 1)

        # compute inner sum
        @turbo unroll = 1 for j in 1 : Range
            # read cached values for inner site
            v1xx = temp[overlap_i[j, 1], 1, 1]
            v1zz = temp[overlap_i[j, 1], 2, 1]
            v1DM = temp[overlap_i[j, 1], 3, 1]
            v1dd = temp[overlap_i[j, 1], 4, 1]
            v1zd = temp[overlap_i[j, 1], 5, 1]
            v1dz = temp[overlap_i[j, 1], 6, 1]

            v2xx = temp[overlap_i[j, 2], 1, 2]
            v2zz = temp[overlap_i[j, 2], 2, 2]
            v2DM = temp[overlap_i[j, 2], 3, 2]
            v2dd = temp[overlap_i[j, 2], 4, 2]
            v2zd = temp[overlap_i[j, 2], 5, 2]
            v2dz = temp[overlap_i[j, 2], 6, 2]

            # compute contribution at inner site
            Γxx += -p * (-2.0) * overlap_i[j, 3] * (v1xx * v2xx - v1DM * v2DM)
            Γzz += -p * (-2.0) * overlap_i[j, 3] * (v1zz * v2zz - v1zd * v2dz)
            ΓDM += -p * (-2.0) * overlap_i[j, 3] * (v1DM * v2xx + v1xx * v2DM)
            Γdd += -p * (-2.0) * overlap_i[j, 3] * (v1dd * v2dd - v1dz * v2zd)
            Γzd += -p * (-2.0) * overlap_i[j, 3] * (v1zd * v2dd + v1zz * v2zd)
            Γdz += -p * (-2.0) * overlap_i[j, 3] * (v1dd * v2dz + v1dz * v2zz)
        end

        # parse result to output buffer
        buff[1, i] += dv * Γxx
        buff[2, i] += dv * Γzz
        buff[3, i] += dv * ΓDM
        buff[4, i] += dv * Γdd
        buff[5, i] += dv * Γzd
        buff[6, i] += dv * Γdz
    end

    return nothing
end


text:
"""
    function hamming_distance(s1::String, s2::String)

In information theory, the Hamming distance between two strings of equal length is the number of positions at which the corresponding symbols are different.
In other words, it measures the minimum number of substitutions required to change one string into the other, or the minimum number of errors that could have transformed one string into the other.
In a more general context, the Hamming distance is one of several string metrics for measuring the edit distance between two sequences. It is named after the American mathematician Richard Hamming.

Reference (https://en.wikipedia.org/wiki/Hamming_distance)

# Arguments:
- `s1`: First string to compare
- `s2`: Second string to compare

# Examples/Tests
```julia
julia> hamming_distance("karolin", "kathrin")
3

julia> hamming_distance("0000", "1111")
4

julia> hamming_distance("ABCDEFG", "AZCDWGM")
4
```

# Contributors:
- [Sedat Aybars Nazlica](https://github.com/saybarsnazlica)
"""

function hamming_distance(s1::String, s2::String)
    @assert length(s1) == length(s2) "String lengths must be the same"

    distance = 0

    for i in 1:length(s1)
        if s1[i] != s2[i]
            distance += 1
        end
    end
    return distance
end

max_issues_repo_name: AugustoCL/Julia

max_forks_repo_name: AugustoCL/Julia