text:
#
#  CCall wrapper functions, thanks to TimHoly, copied from the HDF5-package
#
#
#
const NC_NOERR=0
const NC_MAX_NAME=256
const NC_VERBOSE=false
const NC_BYTE=1
const NC_CHAR =2
const NC_SHORT =3
const NC_INT =4
const NC_FLOAT=5
const NC_LONG=4
const NC_INT64=10
const NC_DOUBLE =6
const NC_STRING=12
const NC_GLOBAL=-1
const NC_CLOBBER=0x0000
const NC_NOCLOBBER=0x0004
const NC_NOWRITE=0x0000
const NC_WRITE=0x0001
const NC_CLASSIC_MODEL=0x0100 # Enforce classic model. Mode flag for nc_create()
const NC_64BIT_OFFSET =0x0200 # Use large (64-bit) file offsets. Mode flag for nc_create()
const NC_SHARE        =0x0800 #
const NC_NETCDF4      =0x1000 # Use netCDF-4/HDF5 format. Mode flag for nc_create()

@osx_only begin
    # Add Homebrew/lib to the DL_LOAD_PATH
    const brew_prefix = Pkg.dir("Homebrew", "deps", "usr")
    push!(Libdl.DL_LOAD_PATH, joinpath(brew_prefix, "lib"))
end
ncname= @windows ? "netcdf" : "libnetcdf"

function ccallexpr(lib::String, ccallsym::Symbol, outtype, argtypes::Tuple, argsyms::Tuple)
    ccallargs = Any[Expr(:tuple, Expr(:quote, ccallsym),lib), outtype, Expr(:tuple, argtypes...)]
    ccallargs = ccallsyms(ccallargs, length(argtypes), argsyms)
    Expr(:ccall, ccallargs...)
end

function ccallsyms(ccallargs, n, argsyms)
    if n > 0
        if length(argsyms) == n
            ccallargs = Any[ccallargs..., argsyms...]
        else
            for i = 1:length(argsyms)-1
                push!(ccallargs, argsyms[i])
            end
            for i = 1:n-length(argsyms)+1
                push!(ccallargs, Expr(:getindex, argsyms[end], i))
            end
        end
    end
    ccallargs
end

function funcdecexpr(funcsym, n::Int, argsyms)
    if length(argsyms) == n
        return Expr(:call, funcsym, argsyms...)
    else
        exargs = Any[funcsym, argsyms[1:end-1]...]
        push!(exargs, Expr(:..., argsyms[end]))
        return Expr(:call, exargs...)
    end
end

# Functions returning a single argument, and/or with more complex
# error messages
for (jlname, fname, outtype, argtypes, argsyms, ex_error) in
    ( (:_nc_open_c, :nc_open, Int32, (Ptr{Uint8}, Int32, Ptr{Int32}), (:fname,:omode,:ida), :(error("Error Opening file ", fname))),
      (:_nc_inq_dim_c,:nc_inq_dim,Int32,(Int32,Int32,Ptr{Uint8},Ptr{Int32}),(:id,:idim,:namea,:lengtha),:(error("Error inquiring dimension information"))),
      (:_nc_inq_dimid_c,:nc_inq_dimid,Int32,(Int32,Ptr{Uint8},Ptr{Int32}),(:id,:namea,:dimida),:(error("Error inquiring dimension id"))),
      (:_nc_inq_c,:nc_inq,Int32,(Int32,Ptr{Int32},Ptr{Int32},Ptr{Int32},Ptr{Int32}),(:id,:ndima,:nvara,:ngatta,:nunlimdimida),:(error("Error inquiring file information"))),
      (:_nc_inq_attname_c,:nc_inq_attname,Int32,(Int32,Int32,Int32,Ptr{Uint8}),(:ncid,:varid,:attnum,:namea),:(error("Error inquiring attribute name"))),
      (:_nc_inq_att_c,:nc_inq_att,Int32,(Int32,Int32,Ptr{Uint8},Ptr{Int32},Ptr{Int32}),(:ncid,:varid,:name,:typea,:nvals),:(error("Error inquiring attribute properties"))),

      (:_nc_get_att_text_c,:nc_get_att_text,Int32,(Int32,Int32,Ptr{Uint8},Ptr{Uint8}),(:ncid,:varid,:name,:valsa),:(error("Error reading attribute"))),
      (:_nc_get_att_short_c,:nc_get_att_short,Int32,(Int32,Int32,Ptr{Uint8},Ptr{Int16}),(:ncid,:varid,:name,:valsa),:(error("Error reading attribute"))),
      (:_nc_get_att_int_c,:nc_get_att_int,Int32,(Int32,Int32,Ptr{Uint8},Ptr{Int32}),(:ncid,:varid,:name,:valsa),:(error("Error reading attribute"))),
      (:_nc_get_att_float_c,:nc_get_att_float,Int32,(Int32,Int32,Ptr{Uint8},Ptr{Float32}),(:ncid,:varid,:name,:valsa),:(error("Error reading attribute"))),
      (:_nc_get_att_double_c,:nc_get_att_double,Int32,(Int32,Int32,Ptr{Uint8},Ptr{Float64}),(:ncid,:varid,:name,:valsa),:(error("Error reading attribute"))),
      (:_nc_get_att_byte_c,:nc_get_att,Int32,(Int32,Int32,Ptr{Uint8},Ptr{Int8}),(:ncid,:varid,:name,:valsa),:(error("Error reading attribute"))),
      (:_nc_inq_var_c,:nc_inq_var,Int32,(Int32,Int32,Ptr{Uint8},Ptr{Int32},Ptr{Int32},Ptr{Int32},Ptr{Int32}),(:id,:varid,:namea,:xtypea,:ndimsa,:dimida,:natta),:(error("Error reading variable information"))),

      (:_nc_put_att_text_c,:nc_put_att_text,Int32,(Int32,Int32,Ptr{Uint8},Int32,Ptr{Uint8}),(:ncid,:varid,:name,:size,:valsa),:(error("Error writing attribute"))),
      (:_nc_put_att_short_c,:nc_put_att_short,Int32,(Int32,Int32,Ptr{Uint8},Int32,Int32,Ptr{Int16}),(:ncid,:varid,:name,:nctype,:size,:valsa),:(error("Error writing attribute"))),
      (:_nc_put_att_int_c,:nc_put_att_int,Int32,(Int32,Int32,Ptr{Uint8},Int32,Int32,Ptr{Int32}),(:ncid,:varid,:name,:nctype,:size,:valsa),:(error("Error writing attribute"))),
      (:_nc_put_att_long_c,:nc_put_att_int,Int32,(Int32,Int32,Ptr{Uint8},Int32,Int32,Ptr{Int64}),(:ncid,:varid,:name,:nctype,:size,:valsa),:(error("Error writing attribute"))),
      (:_nc_put_att_float_c,:nc_put_att_float,Int32,(Int32,Int32,Ptr{Uint8},Int32,Int32,Ptr{Float32}),(:ncid,:varid,:nctype,:size,:name,:valsa),:(error("Error writing attribute"))),
      (:_nc_put_att_double_c,:nc_put_att_int,Int32,(Int32,Int32,Ptr{Uint8},Int32,Int32,Ptr{Float64}),(:ncid,:varid,:name,:nctype,:size,:valsa),:(error("Error writing attribute"))),
      (:_nc_put_att_byte_c,:nc_put_att,Int32,(Int32,Int32,Ptr{Uint8},Int32,Int32,Ptr{Int8}),(:ncid,:varid,:name,:nctype,:size,:valsa),:(error("Error writing attribute"))),

      (:_nc_get_vara_double_c,:nc_get_vara_double,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Float64}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error reading variable"))),
      (:_nc_get_vara_float_c,:nc_get_vara_float,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Float32}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error reading variable"))),
      (:_nc_get_vara_int_c,:nc_get_vara_int,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Int32}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error reading variable"))),
      (:_nc_get_vara_longlong_c,:nc_get_vara_longlong,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Int64}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error reading variable"))),
      (:_nc_get_vara_short_c,:nc_get_vara_short,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Int16}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error reading variable"))),
      (:_nc_get_vara_text_c,:nc_get_vara_text,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Uint8}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error reading variable"))),
      (:_nc_get_vara_schar_c,:nc_get_vara_schar,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Int8}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error reading variable"))),

      (:_nc_put_vara_schar_c,:nc_put_vara_schar,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Int8}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error writing variable"))),
      (:_nc_put_vara_text_c,:nc_put_vara_text,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Uint8}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error writing variable"))),
      (:_nc_put_vara_double_c,:nc_put_vara_double,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Float64}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error writing variable"))),
      (:_nc_put_vara_float_c,:nc_put_vara_float,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Float32}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error writing variable"))),
      (:_nc_put_vara_int_c,:nc_put_vara_int,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Int32}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error writing variable"))),
      (:_nc_put_vara_longlong_c,:nc_put_vara_longlong,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Int64}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error writing variable"))),
      (:_nc_put_vara_short_c,:nc_put_vara_short,Int32,(Int32,Int32,Ptr{Uint},Ptr{Uint},Ptr{Int16}),(:ncid,:varid,:start,:count,:retvalsa),:(error("Error writing variable"))),
      (:_nc_close_c,:nc_close,Int32,(Int32,),(:ncid,),:(error("Error closing variable"))),
      (:_nc_enddef_c,:nc_enddef,Int32,(Int32,),(:ncid,),:(error("Error leaving define mode"))),
      (:_nc_redef_c,:nc_redef,Int32,(Int32,),(:ncid,),:(error("Error entering define mode"))),
      (:_nc_sync_c,:nc_sync,Int32,(Int32,),(:ncid,),:(error("Error syncing file"))),
      (:_nc_create_c,:nc_create,Int32,(Ptr{Uint8},Int32,Ptr{Int32}),(:path,:comde,:ncida),:(error("Error creating netcdf file"))),
      (:_nc_def_dim_c,:nc_def_dim,Int32,(Int32,Ptr{Uint8},Int32,Ptr{Int32}),(:ncid,:name,:len,:dimida),:(error("Error creating dimension"))),
      (:_nc_def_var_c,:nc_def_var,Int32,(Int32,Ptr{Uint8},Int32,Int32,Ptr{Int32},Ptr{Int32}),(:ncid,:name,:xtype,:ndims,:dimida,:varida),:(error("Error creating variable"))),
      (:_nc_def_var_deflate_c,:nc_def_var_deflate,Int32,(Int32,Int32,Int32,Int32,Int32),(:ncid,:varid,:shuffle,:deflate,:deflate_level),:(error("Error setting compression"))),
     );

    ex_dec = funcdecexpr(jlname, length(argtypes), argsyms)
    ex_ccall = ccallexpr(ncname, fname, outtype, argtypes, argsyms)
    ex_body = quote
        ret = $ex_ccall
        if ret != 0
            println(ret)
            $ex_error
        end
        return ret
    end
    ex_func = Expr(:function, ex_dec, ex_body)
    @eval begin
        $ex_func
    end
end


text:
module CompressionStreams

using BufferedStreams
using Libz

export cstream

const MAGIC_TYPES = Dict(
    UInt8[0x1f, 0x8b] => ZlibInflateInputStream
)

function cstream(filename::Union{ASCIIString, UTF8String})
    bs = BufferedInputStream(open(filename))
    return cstream(bs)
end

function cstream(io::IO)
    bs = BufferedInputStream(io)
    return cstream(bs)
end

function cstream(bs::BufferedInputStream)
    compress_type = detect_type(bs)
    if compress_type == :Void
        return bs
    end
    return compress_type(bs)
end

function detect_type(stream::BufferedInputStream)
    buf = Vector{UInt8}(256)
    peekbytes!(stream, buf)
    for (magic, ztype) in MAGIC_TYPES
        if buf[1:length(magic)] == magic
            return ztype
        end
    end
    return :Void
end

end # module

ext: jl


text:
const simplenormalmixturestandata = [
Dict(
"N" => 1000,
"y" => [10.0787617156523, -9.51866467444093, 9.73922587306449, 11.5662681883816,9.62798489000074, -9.60265090119919, 8.90114345923455, 10.866328444034, 10.5347883361026, 8.60577222463504, -10.625227428575, -9.08615131315038, -8.99280046532217, 9.43533905966944, 8.92696803962787, 9.642301288006, 9.42066621557773, 9.90838406119759, 9.63911912487384, 7.55585122379505, 9.58069898235901, 9.63228461457187, -9.99589804304319, 8.61024296515084, -10.4988882191036, -8.45028703711596, 9.76066425342707, -8.68129886943495, 9.83763492226261, 7.29698608457303, 8.78881675784227, 10.6057117460834, 10.2807363791435, 9.54352982843898, -10.9911972452721, 12.2061931600758, 7.76887153466896, 10.7523541087606, -9.98525551020183, 10.6248182699128, 10.9092322100956, 9.85276119502607, 10.9778885179292, 10.4521386035968, 10.9501292674525, 8.78767098907235, 10.4760680578381, -10.5254343756996, 10.1066471851771, 8.98960108796381, 11.1788924241439, 8.16177207287154, 8.78778163498527, 9.22771109933542, -10.1948463841928, -10.2952820080142, -9.50335957628006, 9.99524569310745, 9.79654519990185, 10.6998634277736, 10.3014073262429, 8.33668631497077, -9.03423870378235, 9.64018036967314, 11.6691504372573, 10.9413492009848, -11.2272839144599, 10.8911157938285, 9.46898499012104, -9.5887646441991, 11.1152849920637, 10.1955967101101, 11.348570300012, 10.135897719167, 11.5544531837259, 9.86110328372943, 9.87931976177428, 10.752278211748, 10.3312880631571, 8.39765486915738, 9.22717521672948, 8.87715287722374, 10.3908345994533, 8.87861997541676, 9.93346546639017, 10.9956254670304, -9.28529380867817, 9.86324177715395, -11.4437979353353, -9.19387673640779, -11.7398350783033, -10.4013203095, -10.2875824887513, 9.8810095952169, 10.2244248320694, 8.87616842642094, 11.0817433200965, 11.2615426236089, 10.8182260738274, 10.5190581651096, 9.38550490079291, 12.827807696125, 11.5003104206829, -8.97369784173981, 9.16657709168524, 10.4418149946038, -9.36841324191389, -10.5804663984926, 10.1647431036369, 9.72644824357577, 10.476402714431, 10.7311506029696, 9.26382891181627, 11.3043847535379, 10.4198438027989, -9.91726516628864, -10.483882474015, 11.1093058479695, -8.83241303607449, 10.0804581453455, 10.091011715105, 10.3553007042538, 8.45462629127872, 9.958942029534, -9.18454036443283, 10.8157285063582, 9.65495165729484, 10.0482461316808, -10.905640775072, -9.98443651907025, 8.73484067100771, 8.37862639984215, -9.40580349855116, -10.2703152440041, 11.4642739554968, 11.5768548854893, 7.33318938830718, 10.0390903990974, 11.0785766571347, 8.47690794542766, 9.77532169953588, 9.71319992158507, 10.2670182524397, -10.6411181560584, -9.53554022933489, 12.0048819880247, 11.068294112414, -10.0476112199953, 10.7297692474882, -10.0035802700059, 10.8842322392817, 9.90100942917067, 7.95811834440273, 12.0537464016876, 10.6148585771334, 11.7695557842842, -10.1622575511924, 10.3283274641102, -9.21930070795023, -10.9812056220275, -10.1415857318327, -11.2562489529667, 11.5359251228164, 8.79455692191044, 8.04628480806038, 9.57003526472078, 10.5390674610495, -10.010258765208, 9.71633254444569, 10.2646183028619, 9.28031810911545, 9.52545784204816, 9.87544219275188, 8.93741938562221, 11.9649315861451, 8.22806692774107, 10.9095230555518, 8.12095747854901, 8.69662320765811, 11.1747826075257, 10.1439847159912, -8.6921722382838, -11.804975773816, 10.3501059450885, 9.6551446251821, 10.3322565976428, -11.1729836028224, 8.50923696349623, 8.8578894891086, 10.2092991197477, 10.1621595029931, 10.0081847236298, 9.56129159516384, -10.4432066820666, 9.8736814248717, -9.93494898961266, 10.8181022046474, -8.36565834150681, 10.1723657998346, 10.1379422169029, 10.8148837226889, -9.62070693292343, -10.3107408759354, 10.6741558699236, -11.6418647499083, -10.9885637415086, 10.1749081876493, 11.7678771112303, -9.89794804171576, -10.2874581716328, 9.1653908620136, 11.7156318787535, -10.6625885122872, 11.1781349786478, 10.3244312552014, 10.0642081984583, 11.5602518174107, 10.3443603035977, 8.75911725980491, 8.94722796805182, 9.56956921792536, -10.1309504794356, -9.5147885465912, 9.9283590779406, 12.2328395893027, 10.4175852097228, 11.1799855377854, 11.6944884582449, -11.1979346263839, 10.5990249224701, 8.46531130904106, 8.09287304940918, -10.4349607395643, 10.033450285969, 9.86348976236917, 11.2800118872818, 10.1429977591401, 9.16583583952832, 9.48731652641927, 8.09480196743456, 11.5068749881894, 8.32051497775634, 10.9777036311362, 11.1807577803244, -9.44231502565423, 10.1904046840125, -10.9821472074464, 10.9878405188951, -9.5521733916081, 9.26481707287272, 10.1825896458426, 10.8219756005116, 10.1008165456318, 10.7628687748061, 9.92090390936909, 10.6579628249169, -9.61545628377418, -8.99519566101998, 9.39510546534214, 11.3911257928786, 9.68678677769843, 9.5660673490616, 10.7776928224029, -9.03554593315622, 12.5210794021992, 10.6033297904601, -10.5716501470052, -11.4702828897835, 8.26263836326742, 11.2634731903223, -9.97665531906082, -12.7159252945058, -8.81471074857334, 10.983549854338, -10.0566727606766, -9.59343549056041, -11.3094299496401, -10.7066912868769, -8.96610833006209, 11.0242007344117, 10.8491427937478, -9.26175745003045, 8.6636551180621, 10.3606786467136, 10.1390993506887, -10.3545920057504, -9.81176114667915, 8.94812420534452, -7.84729915691064, -11.10973934267, -8.97049177792347, -8.62284525025174, -9.08518894812402, 9.18235800538324, 9.59052674565536, 11.1088826236572, 12.0591150513961, -11.0780344933821, -11.222331968246, -10.711444696028, 9.81632041095048, 10.2374039921351, -8.62076386764043, 10.6788651818835, 8.53465451310903, 8.86231220324369, 9.01034391877219, -9.47201121730324, 10.2530108947054, -10.4620363576056, 9.41425920571156, -9.86297844816024, -11.2996452388479, 11.1129580427685, 11.6065794209202, -9.19786212394995, 11.6345529259773, -11.3447009402143, 11.5155259028602, 9.86108612467055, 8.46155458966665, 9.0553374479857, 9.4210845900859, 10.6101411197351, 9.98698524477991, 8.57328785962276, 11.0265779119591, 10.2118052908858, 9.48822006918977, -9.709674325511, 11.4895755423417, 9.45484497569441, -10.192610254954, 8.23195215241814, 10.6262098035123, -10.6548353134147, 10.7406569549298, 12.0080438835213, -9.4619354198813, 9.45842990534921, 8.40313954146295, 11.7578057914613, -9.04913262501355, 9.26991967711579, 11.4560385077095, 11.0485057783357, -9.79982269426772, 9.43726689016695, -10.7568675398117, 9.62310645557329, 10.9180308553875, 9.78569200990921, -11.1549186595196, 10.0163780919448, 8.8567674249699, 11.0701873119837, -10.8284383814111, 9.34520294856411, -8.58355914738141, 9.04614723399203, 9.97518990138801, -10.466822252265, 10.7149245846268, 9.56415807741495, -8.18057472663792, 8.3583809576127, 10.6741185263892, -9.48454403117852, 11.0283684209902, 9.39414416764448, 9.44591964129117, 9.71871039604545, 8.76829165382753, 11.3075424170342, -8.75164149425368, -10.2470782304074, 9.81658069941223, 9.9219367166906, 9.95871616032122, -10.1675238559485, 9.55277984251774, 11.9529156963614, 10.8645790877641, 11.0719248954016, 8.23682452502462, -10.2615184127485, -10.3031776240722, 9.1518989363774, 9.01113204653102, -11.441687373266, 7.95371933160899, -10.7424822395852, -10.3909802469706, 9.82362803837905, 9.04852235837992, -8.50172736889872, 10.2821312885721, 8.05606153755322, 9.55880006007305, 11.5791596182345, -10.5918842177335, 10.6690084835082, -9.91207574282835, 7.78213174559851, 11.4331784789297, 9.25405144119079, 10.4530454882073, 8.79853723396448, 10.600672571192, -7.40422816215119, 12.2912539439291, 9.28522123051661, 10.6514510506905, 8.06040110464455, 10.2065839057819, 12.1107919012356, 11.0899790630955, 10.4114337565411, 9.52050648746652, 9.82332624489799, 13.039033405787, 9.57909265060003, 9.44804501017956, 9.37477275170591, -10.0180868587078, 10.3969627282485, 10.1736869695142, -8.93124104220478, 10.4419298185301, 8.73384842581038, 9.68372417466203, 10.0969584869323, -9.51083893907219, 8.94918229985524, 9.76536158967986, -9.75804592353706, 9.37280013220421, 9.54544737524905, -10.6553786961537, 8.20866218170873, 6.95463607002023, -9.12229173302214, -10.3922309126349, 10.1911800674397, 10.8111189290201, -10.7508305957708, 9.895373124421, 9.304493817718, 10.0031444122566, -12.0565376308283, -10.1541745028097, 10.8459935212827, 9.37595699942702, 10.8847432961232, -8.87146124283177, -10.4196432682773, 9.4519118340132, 10.3304971854621, 9.24652569281063, 11.1651379599112, -11.411214006235, -7.4348623691501, 9.72067399641766, -10.5655378187186, 10.1821841465586, -9.11928490265027, 11.5545470773444, 8.26222672814396, -8.15659176705974, 11.1319957518819, 9.97556499011801, 9.10361465582959, 9.60994307716486, 8.92135187555881, 10.9645697062262, -10.747766705257, -11.0374524778733, 8.94972532368806, 8.88611506234624, 11.3522464269832, 10.7886286987955, 7.7521198408217, -9.1523669054828, 12.5250783808459, 8.98359790096925, 8.27934666290151, 7.74804606379083, -10.7389817586684, -10.0977651328538, 10.9297634008603, -9.04293634192005, -9.44066582532207, 10.9612816497933, -10.1939803095617, -9.91366506535345, 10.0022054778892, 9.65317642712795, 9.51413820146579, 10.2167373077816, 8.85151358441184, -10.2868515649323, 10.0119293803061, 9.99071995497331, 9.69762244614936, 10.4923550217034, 9.39728038247446, 9.31772348034048, 10.2867372373666, 10.1655863562897, 9.15794606452223, 9.1778862812261, 8.57064917559631, 10.1347417193396, -9.38606645004695, 11.1205353766002, 10.922258127315, -11.4034162929597, 10.7963936702143, 7.32613210003171, 9.77181002251055, 10.0528228618798, 10.1658214064877, 9.83561702641547, 12.2220580879628, -10.3548551011225, 10.9045238862071, 8.70700033722994, 7.9219705200981, 10.7627920481292, 8.23133788739842, 7.90747212900534, 11.0409370394267, -7.31593919592432, 9.12670771537337, -9.89974533325839, -12.3025125166977, -8.82410513715091, 8.50745180007555, 9.86128675905982, -10.0026561459301, 9.96643873994312, 9.79259331981732, 9.80917563612823, 12.0569547005656, 9.34882661869191, -9.91442134449967, -9.61223097137049, 9.95007932522852, 11.7469087736797, 10.4001946875976, 10.5559784764237, 12.0789513191225, 9.31096813615993, -7.82775583217579, 9.40240583716087, 9.93255289266403, 8.88142505947862, -9.0766864110248, -10.9109119647925, 8.52931417680731, 8.66414238141873, 10.6497793290807, -11.6580335729395, 8.00698900123071, 9.66953768525166, 10.4132524628663, 8.91281566634883, -9.21143362031712, 9.35679234139273, -8.17615110803147, 10.2081246803034, -10.9715658969574, 13.023596733031, -11.2636561658954, -11.2782655062227, 9.53363135008856, 10.4197837527554, 9.58489244119664, 11.1685570711912, 10.793371128136, 10.3806972166891, 10.3350541573071, 10.4605243371586, 9.94626676685634, -10.3400801867328, 10.222955609595, 8.27010830457434, -9.84308741184729, 9.57082901043481, 10.2216458443269, 10.6827977409369, 10.342167834879, -11.0248281302695, 9.05151360161711, 9.77537449605376, 7.81716286622456, 11.0632011096347, 9.31694169760303, 9.35703856930842, 11.837217261589, 10.6948112203907, 8.9236093753546, 10.4592036913585, -10.1459458609891, 10.1386438855282, 11.232261753013, 11.8305096547063, 10.3184106728973, 10.7738538079572, 9.37037543376947, -10.4304860107623, 9.18693348678917, 11.2637648341454, 8.68434565720876, 9.18620197530073, 11.4599611446044, 10.4800031252848, -11.0945574088797, 10.2387376490566, 9.59364694537463, -8.99327095928061, 8.83506298266456, -10.3840194426966, 10.2240609113397, -10.5248893735639, 9.62760785759967, 10.079365063534, -10.7687001286491, 10.1637437699546, 9.80567102170068, 9.70754719843968, 10.6162073473761, 10.5610155839469, 7.82789601788298, 8.20523486136883, 10.5882338381721, 8.42742784923493, -10.9903876113961, -7.72292297951471, 9.88854076081528, 8.33821478475034, 9.32939312307841, 10.800619551179, 11.1011193106652, -10.1099261000022, 10.8839234028016, -9.92532887825002, -9.91868157364112, 9.61565565992152, 10.1156170783244, 9.6928511660629, 9.31774783705032, 10.4354172738829, 10.2507752169853, 12.2559617446477, 9.36685785602739, -10.4170817286227, -10.4898160137598, 9.12436733726013, 9.730982788654, 10.6828691425692, 11.4304351639013, 9.62265106404407, -11.6792916398537, 10.2603961417747, 11.2480384713198, 10.77884591054, 9.9690355475612, -9.20629682555333, 9.33979133995686, 10.9270575621656, 11.0235867535727, 8.78292038932752, 10.1749863269549, 9.3466010679362, 12.0151338126491, 10.2235037117164, 8.71495972474863, -10.925763153064, -8.40638278001894, -11.4159669203455, 10.3075336827178, 11.149452825723, -9.36604661013187, 12.5160741401274, 10.9221895473068, 8.20679689960437, 8.41288957698704, 9.95714952986613, -8.18851913715365, 10.3875227632695, -9.49964095054521, 8.29652826534535, 11.1452130604421, 9.61133393132873, 9.80245365211025, 12.5922520872747, 11.2871470933878, -9.81522553481041, 10.0062190534181, 9.33814985028829, 9.65318392302997, 11.3397324485649, 10.5924192662125, 10.7189040164074, 9.58858072236163, -8.93595486745599, 10.9020304830968, 10.2126174532676, 9.73654043085867, 9.16829715456166, 8.80933690601713, 8.65260186995893, -9.83420909356452, 10.47516319038, 9.4830670622285, 10.7032794934277, -10.5340316592913, -8.6873492038785, 10.0993895639375, 10.2610910117045, -10.3498244613826, 11.787849222301, 11.139568171058, 9.72299469820482, -11.1341460777791, 11.4917828432652, 9.96689142289024, 9.95304472516289, 8.08536614398298, -10.6508106381609, 10.0594483092865, 8.84993284847777, 10.0044806747115, -8.52480932841534, 10.6710460726635, -10.4253298310742, -11.638931473249, 10.3838794238539, -10.7787002085694, -10.4162764798642, 10.3147107148292, 9.29074853314924, 10.4294665746048, -9.79715019185052, -9.59815986623741, 10.5650236905173, 8.69592570012447, 10.5924173589288, -8.59647478034163, 9.77059656716617, 9.19862131679224, 9.46815770373167, 10.535023231829, -12.0856331661877, 7.62977295513694, -9.92902480043142, 11.8725972674065, -11.1169060701832, 8.6487521675505, 9.31377194553378, 10.8023045518987, -10.3808560779849, 8.38035043471661, -8.73444373054514, -8.56892169012415, -9.82402964738205, 10.3314711584406, 10.1854736755025, 11.6740735050919, 9.69110524373521, 12.0127425725907, 9.00779168174289, -9.65400953289059, 9.36081029523745, 9.19222268307935, 9.56776982984306, -9.18473040611654, 8.6060744953505, -9.66827478102834, 12.6011743606045, 10.6376999884738, 9.76079732069272, 12.1453450842378, 11.0301708480568, 11.1364735782076, -10.2447515836444, 10.1083484588802, -7.5382342225552, 9.09928083428771, -10.5175522522499, -9.55660613595525, -9.67189486763083, 10.2248931038303, 11.550545940199, 11.7984204539083, 9.12713331251177, -10.4491599389868, 9.41473403924722, 10.0912250749375, 9.83068226118461, 10.8793515341339, -9.78210140158989, 10.514483942795, 10.3945842150078, -11.0409626304229, 10.5886728560102, 10.1584352541332, 9.47184598841611, 8.40935619443552, -9.90894751957456, 8.97688134622493, 11.211019935232, 10.7491856593976, 10.7873017495269, 10.1867756324757, 9.74078386314273, 9.25211168598903, 9.73027150108826, -10.7090076216278, 10.3994484560168, 9.81579127086072, 9.81191557692066, 9.96373020802345, 11.3183603457445, 9.62939867216113, -10.4711625257198, -11.6249314544619, 10.3882388392976, 10.9521395154248, 9.2405113327342, 10.4425275739611, 9.87650089222106, 9.29171319084941, 8.91139651258156, 8.57139819900797, 9.9961424501687, -9.85990550795364, 9.70758313674743, 9.5039304177794, 12.0663244126421, 11.6591804852706, -11.4953826937721, -9.2783573030316, 8.95086190617294, 11.2400894968428, 10.310778918788, -10.4179760516405, 9.13536125727828, 10.9592471554322, 10.962662147166, 9.04760635394027, 10.8004882586687, -10.2262244850898, 9.22893569923024, -10.4561314128423, -10.6621156207949, -9.79050903429387, 9.47318635449212, -8.00116935967707, -10.0570763312332, -9.19645984538819, -10.0441212740922, 11.4788232730563, -9.43318866849756, -9.35091566403592, 8.52895033400044, 10.3534781327039, 10.8276184771636, 9.93337089247137, -11.0344276671851, 10.5590713711255, 8.99583556552668, 10.8999084829069, -11.1442773029976, 9.69869203817006, -8.90585531136116, -11.5624306545703, 10.2447855556335, 10.0827199392685, 9.95961077092137, 10.7566861862841, 11.7205344292616, 9.77358643907095, 10.1095239104352, 10.5382421565052, 10.0772574025846, 9.53819581618213, 10.7659953598585, 11.6698787710747, 10.9089919455957, -10.4081150203207, -9.24657759949556, -9.20335463377733, -10.7590681521328, 10.0616808307032, -8.09562344190554, 11.2170830676925, -9.78116905663081, -8.85504543833859, -10.1235456851063, 9.67787506856074, 8.89343949169863, -7.99575653561316, -10.7719795703418, -11.1788890735806, -10.5696798739893, -8.24517915453391, -11.7753693141591, -10.2097669134444, -11.2340440812683, 10.2859904417603, 9.6372472683742, 9.17954799125914, -8.33022093176597, -10.3953466788157, 10.4900275191026, -12.7678707807416, 11.1058750468863, 10.5081007688734, 8.76865008135527, 9.40406788245572, 11.0709345717393, 9.35359432240435, -9.52410557964191, 9.66609177641322, 11.2851482151796, 9.8946909948377, -9.97808771306627, 9.58070093523013, 8.7389504527192, 10.0852775370057, 10.1071144759014, -9.70645851904737, -10.7172305311259, 9.30759157963914, 6.96315753053229, 11.3145194333987, 10.354791246337, 10.47931719848, 11.6449389204673, -9.3834424140271, 10.7724131736268, -11.3673240394791, 11.049811963708, 9.15761537839109, 10.051498818984, 11.5409534253538, 11.0837643112649, 7.1387948180141, 9.80309472627036, -11.0768582653339, -10.1153934052011, 10.203025940557, 10.6349590757828, 10.3643448423615, -10.56952568002, 8.97628386871262, -7.63805118940883, 9.01328532413614, -9.70228671644457, 10.8489734196045, 10.8097332205942, -8.78098406667269, 10.6881885521687, 9.99759635978347, -9.14677074634077, 11.1882650946775, 7.92936829043119, 8.28045282240367, 9.94656850295367, 9.42421871899151, 10.3022543508761, 9.42637476373473, 11.4966226812476, -9.40317552426524, -9.63377150563604, -9.90684687612854, 9.52516052943005, 8.31384015076605, 11.8427680272746, -9.43061137227063, -9.74288461737338, 9.13603951857731, 9.53615106697376, -11.5305542491226, 9.62683068208445, 11.0372608634762, 9.66985167128222, 11.2747895360203, 9.6664620502666, -11.4198760101715, 9.21373329527328, 10.6594703226401, -9.85683654390669, -9.28952032750969, 10.7624268604215, 8.29988657732754, -10.6390998021297, -10.6627107313838]
)
]


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

using Markdown
using InteractiveUtils

# ╔═╡ 72047c34-de27-11ea-130a-e3b966b70dc3

# ╔═╡ f46abde2-db15-11ea-29fd-3d503b825cf1
area = sqrt(6*(6 - 4)*(6 - 5)*(6 - 3))

# ╔═╡ 6e954fd6-db16-11ea-2d62-8f66f6de8fdb
function classic_triangle_area(base, height)
	return (base*height)/2
end

# ╔═╡ beb7c8b0-db16-11ea-0656-85d886a2faf3
classic_triangle_area(4.0, 3.0)

# ╔═╡ Cell order:
# ╠═f46abde2-db15-11ea-29fd-3d503b825cf1
# ╠═6e954fd6-db16-11ea-2d62-8f66f6de8fdb
# ╠═beb7c8b0-db16-11ea-0656-85d886a2faf3
# ╠═72047c34-de27-11ea-130a-e3b966b70dc3

max_stars_repo_name: kantel/julia

max_issues_repo_name: kantel/julia

max_forks_repo_name: kantel/julia


text:
module Ops

using Compat
using LinearAlgebra
using Zeros
using ..LazyApply

using ..LazyApply: ∑, ∏, α, coefficient, Applied

import ..LazyApply: coefficient

import Base: show, *, /, +, -, Tuple, one, exp, adjoint, promote_rule, convert

export Op, sites, params

#####################################################################################
# General functionality
#

# Helper function to split a `Tuple` according to the function `f`.
# For example:
#
# julia> t = (1, "X", 1, 2, "Y", 2, "Z", 4)
# (1, "X", 1, 2, "Y", 2, "Z", 4)
#
# julia> split(x -> x isa AbstractString, t)
# ((1,), ("X", 1, 2), ("Y", 2), ("Z", 4))
#
function split(f, t::Tuple)
  n = findall(f, t)
  ti = t[1:(first(n) - 1)]
  ts = ntuple(i -> t[n[i]:(n[i + 1] - 1)], length(n) - 1)
  tf = t[last(n):end]
  return ti, ts..., tf
end

#
# General functionality
#####################################################################################

#####################################################################################
# LazyApply extensions
# TODO: Move to `LazyApply`
#

# Helper function for determing the cofficient type of an `Op` related type.
coefficient_type(o::Type) = One
coefficient_type(o::Type{<:α{<:Any,T}}) where {T} = T
coefficient_type(o::Type{<:∑{T}}) where {T} = coefficient_type(T)

coefficient_type(o::Applied) = coefficient_type(typeof(o))

#
# LazyApply extensions
#####################################################################################

const WhichOp = Union{String,AbstractMatrix,UniformScaling}

struct Op
  which_op::WhichOp
  sites::Tuple{Vararg{Int}}
  params::NamedTuple
end
which_op(o::Op) = o.which_op
sites(o::Op) = o.sites
params(o::Op) = o.params
op(o::Op) = o
coefficient_type(o::Op) = One
coefficient(o::Op) = one(coefficient_type(o))

params(o::Vector{Op}) = params(only(o))

# exp
exp(o::Op) = Applied(exp, o)

# adjoint
adjoint(o::Op) = Applied(adjoint, o)

Tuple(o::Op) = (which_op(o), sites(o), params(o))

const OpExpr = Union{Op,∑{Op},α{Op},∑{<:α{Op}},∏{Op},∑{∏{Op}},α{∏{Op}},∑{<:α{∏{Op}}}}

# Type promotion and conversion
convert(::Type{α{Op,T}}, o::Op) where {T} = one(T) * o
convert(::Type{∏{Op}}, o::Op) = ∏([o])
convert(::Type{∑{Op}}, o::Op) = ∑([o])
convert(::Type{α{∏{Op},T}}, o::Op) where {T} = one(T) * convert(∏{Op}, o)
function convert(::Type{∑{α{∏{Op},T}}}, o::Op) where {T}
  return ∑([convert(α{∏{Op},T}, o)])
end

# if VERSION < v"1.6"
const ∑α∏Op = ∑{α{∏{Op},T}} where {T}
const ∑α∏{S} = ∑{α{∏{S},T}} where {T}

convert(O::Type{<:Op}, o::Tuple) = O(o)
convert(O::Type{<:α{Op}}, o::Tuple) = convert(O, Op(o))
convert(O::Type{<:∏{Op}}, o::Tuple) = convert(O, Op(o))
convert(O::Type{<:∑{Op}}, o::Tuple) = convert(O, Op(o))
convert(O::Type{<:α{∏{Op}}}, o::Tuple) = convert(O, Op(o))
convert(O::Type{<:∑{α{∏{Op},T}} where {T}}, o::Tuple) = convert(O, Op(o))
## convert(O::Type{∑{α{∏{Op},T}} where {T}}, o::Tuple) = convert(O, Op(o))
convert(O::Type{∑α∏Op}, o::Tuple) = convert(O, Op(o))

convert(::Type{∑{<:α{∏{Op}}}}, o) = convert(∑{α{∏{Op},T}} where {T}, o)
∑{<:α{∏{Op}}}(o) = (∑{α{∏{Op},T}} where {T})(o)
∑{<:α{∏{Op}}}() = (∑{α{∏{Op},T}} where {T})()

# if VERSION > v"1.5"
## function (∑{α{∏{Op},T}} where {T})(o::OpExpr)
##   return convert(∑{α{∏{Op},T}} where {T}, o)
## end
## function (∑{α{∏{Op},T}} where {T})(o::Tuple)
##   return convert(∑{α{∏{Op},T}} where {T}, o)
## end
## function (∑{α{∏{Op},T}} where {T})(o::Vector{<:Union{OpExpr,Tuple}})
##   return reduce(+, o; init=(∑{α{∏{Op},T}} where {T})())
## end
## function (∑{α{∏{Op},T}} where {T})(o::WhichOp, args...)
##   return convert(∑{α{∏{Op},T}} where {T}, Op(o, args...))
## end
## function (∑{α{∏{Op},T}} where {T})(c::Number, o::WhichOp, args...)
##   return convert(∑{α{∏{Op},T}} where {T}, Op(c, o, args...))
## end
# if VERSION < v"1.6"
function ∑α∏Op(o::OpExpr)
  return convert(∑{α{∏{Op},T}} where {T}, o)
end
function ∑α∏Op(o::Tuple)
  return convert(∑{α{∏{Op},T}} where {T}, o)
end
function ∑α∏Op(o::Vector{<:Union{OpExpr,Tuple}})
  return reduce(+, o; init=(∑{α{∏{Op},T}} where {T})())
end
function ∑α∏Op(o::WhichOp, args...)
  return convert(∑{α{∏{Op},T}} where {T}, Op(o, args...))
end
function ∑α∏Op(c::Number, o::WhichOp, args...)
  return convert(∑{α{∏{Op},T}} where {T}, Op(c, o, args...))
end

# Default constructors
# if VERSION > v"1.5"
## (∑{α{∏{S},T}} where {T})() where {S} = ∑{α{∏{S},Zero}}()
## (∑{α{∏{Op},T}} where {T})(o) = convert(∑{α{∏{Op},T}} where {T}, o)
# if VERSION < v"1.6"
∑α∏{S}() where {S} = ∑{α{∏{S},Zero}}()
∑α∏Op(o) = convert(∑{α{∏{Op},T}} where {T}, o)

function convert(O::Type{α{∏{Op},T}}, o::α{Op}) where {T}
  return convert(T, coefficient(o)) * ∏([op(o)])
end
function convert(O::Type{∑{T}}, o::α{Op}) where {T<:Union{α{Op},α{∏{Op}}}}
  return ∑([convert(T, o)])
end

convert(O::Type{∑{∏{Op}}}, o::∏{Op}) = ∑([o])
convert(O::Type{α{∏{Op},T}}, o::∏{Op}) where {T} = one(T) * o
function convert(O::Type{∑{α{∏{Op},T}}}, o::∏{Op}) where {T}
  return ∑([convert(α{∏{Op},T}, o)])
end
convert(O::Type{∑{α{∏{Op},T}}}, o::∑{∏{Op}}) where {T} = one(T) * o

function convert(O::Type{∑{α{∏{Op},T}}}, o::α{∏{Op}}) where {T}
  return ∑([convert(α{∏{Op},T}, o)])
end

# Versions where the type paramater is left out.
function convert(O::Type{∑{α{∏{Op},T}} where {T}}, o)
  return convert(∑{α{∏{Op},coefficient_type(o)}}, o)
end

#
# Promotion rules.
#
# Rules for promoting Op-like objects when they are being added together.
#
# Should cover promotions between these types:
#
# Op
# α{Op,T}
# ∏{Op}
# ∑{Op}
# ∑{α{Op,T}}
# α{∏{Op},T}}
# ∑{∏{Op}}
# ∑{α{∏{Op},T}}
#

# Conversion of `Op`
promote_rule(::Type{Op}, O::Type{<:α{Op}}) = O
promote_rule(::Type{Op}, O::Type{<:∏{Op}}) = O
promote_rule(::Type{Op}, O::Type{<:∑{Op}}) = O
promote_rule(::Type{Op}, O::Type{<:∑{α{Op}}}) = O
promote_rule(::Type{Op}, O::Type{<:α{∏{Op}}}) = O
promote_rule(::Type{Op}, O::Type{<:∑{∏{Op}}}) = O
promote_rule(::Type{Op}, O::Type{<:∑{α{∏{Op}}}}) = O

# Conversion of `α{Op}`
function promote_rule(::Type{α{Op,T}}, ::Type{α{Op,S}}) where {T,S}
  return α{Op,promote_type(T, S)}
end
promote_rule(::Type{α{Op,T}}, ::Type{∏{Op}}) where {T} = α{∏{Op},T}
promote_rule(::Type{α{Op,T}}, ::Type{∑{Op}}) where {T} = ∑{α{Op,T}}
function promote_rule(::Type{α{Op,T}}, ::Type{∑{α{Op,S}}}) where {T,S}
  return ∑{α{Op,promote_type(T, S)}}
end
function promote_rule(::Type{α{Op,T}}, ::Type{α{∏{Op},S}}) where {T,S}
  return α{∏{Op},promote_type(T, S)}
end
function promote_rule(::Type{α{Op,T}}, ::Type{∑{∏{Op}}}) where {T}
  return ∑{α{∏{Op},T}}
end
function promote_rule(::Type{α{Op,T}}, ::Type{∑{α{∏{Op},S}}}) where {T,S}
  return ∑{α{∏{Op},promote_type(T, S)}}
end

# Conversion of `∏{Op}`
promote_rule(::Type{∏{Op}}, ::Type{∑{Op}}) = ∑{∏{Op}}
function promote_rule(::Type{∏{Op}}, ::Type{∑{α{Op,S}}}) where {S}
  return ∑{α{∏{Op},S}}
end
promote_rule(::Type{∏{Op}}, ::Type{α{∏{Op},S}}) where {S} = α{∏{Op},S}
promote_rule(::Type{∏{Op}}, ::Type{∑{∏{Op}}}) = ∑{∏{Op}}
function promote_rule(::Type{∏{Op}}, ::Type{∑{α{∏{Op},S}}}) where {S}
  return ∑{α{∏{Op},S}}
end

# Conversion of `∑{Op}`
promote_rule(::Type{∑{Op}}, ::Type{∑{α{Op,S}}}) where {S} = ∑{α{Op,S}}
function promote_rule(::Type{∑{Op}}, ::Type{α{∏{Op},S}}) where {S}
  return ∑{α{∏{Op},S}}
end
promote_rule(::Type{∑{Op}}, ::Type{∑{∏{Op}}}) = ∑{∏{Op}}
function promote_rule(::Type{∑{Op}}, ::Type{∑{α{∏{Op},S}}}) where {S}
  return ∑{α{∏{Op},S}}
end

# Conversion of `∑{α{Op,T}}`
function promote_rule(::Type{∑{α{Op,T}}}, ::Type{∑{α{Op,S}}}) where {T,S}
  return ∑{α{Op,promote_type(T, S)}}
end
function promote_rule(::Type{∑{α{Op,T}}}, ::Type{α{∏{Op},S}}) where {T,S}
  return ∑{α{∏{Op},promote_type(T, S)}}
end
function promote_rule(::Type{∑{α{Op,T}}}, ::Type{∑{∏{Op}}}) where {T}
  return ∑{α{∏{Op},T}}
end
function promote_rule(::Type{∑{α{Op,T}}}, ::Type{∑{α{∏{Op},S}}}) where {T,S}
  return ∑{α{∏{Op},promote_type(T, S)}}
end

# Conversion of `α{∏{Op},T}`
function promote_rule(::Type{α{∏{Op},T}}, ::Type{α{∏{Op},S}}) where {T,S}
  return α{∏{Op},promote_type(T, S)}
end
function promote_rule(::Type{α{∏{Op},T}}, ::Type{∑{∏{Op}}}) where {T}
  return ∑{α{∏{Op},T}}
end
function promote_rule(::Type{α{∏{Op},T}}, ::Type{∑{α{∏{Op},S}}}) where {T,S}
  return ∑{α{∏{Op},promote_type(T, S)}}
end

# Conversion of `∑{∏{Op}}`
function promote_rule(::Type{∑{∏{Op}}}, ::Type{∑{α{∏{Op},S}}}) where {S}
  return ∑{α{∏{Op},S}}
end

# Conversion of `∑{α{∏{Op},T}}`
function promote_rule(::Type{∑{α{∏{Op},T}}}, ::Type{∑{α{∏{Op},S}}}) where {T,S}
  return ∑{α{∏{Op},promote_type(T, S)}}
end

op(o::α) = o.args[2]
sites(o::α) = sites(op(o))

which_op(o::α{Op}) = which_op(op(o))
params(o::α{Op}) = params(op(o))
one(o::α{Op}) = one(coefficient(o))

sites(o::Union{∑,∏}) = unique(Iterators.flatten(Iterators.map(sites, o)))

# General definition for single-tensor operations like `exp` or `adjoint`.
# F: exp, adjoint, etc.
op(o::Applied{F}) where {F} = o.args[1]
sites(o::Applied{F}) where {F} = sites(op(o))
which_op(o::Applied{F}) where {F} = which_op(op(o))
params(o::Applied{F}) where {F} = params(op(o))

const OpTuple = Union{Tuple{<:WhichOp,Vararg},Tuple{<:Number,<:WhichOp,Vararg}}

# Conversion from Tuple
Op(o::Tuple) = Op(o...)
Op(which_op::WhichOp, sites::Tuple; kwargs...) = Op(which_op, sites, values(kwargs))
Op(which_op::WhichOp, sites::Int...; kwargs...) = Op(which_op, sites; kwargs...)
Op(which_op::WhichOp, sites::Vector{Int}; kwargs...) = Op(which_op, Tuple(sites); kwargs...)
function Op(which_op::WhichOp, sites_params::Union{Int,<:NamedTuple}...)
  return Op(which_op, Base.front(sites_params), last(sites_params))
end
Op(α::Number, which_op::WhichOp, args...; kwargs...) = α * Op(which_op, args...; kwargs...)
function Op(which_op::WhichOp, sites_params::Union{Int,WhichOp,NamedTuple}...)
  ts = split(x -> x isa WhichOp, (which_op, sites_params...))
  args = filter(x -> !(x isa Tuple{}), ts)
  return ∏(collect(Op.(args)))
end

# Conversion to `∑{Op}` (replacement for `OpSum`)
∑{Op}(o::Vector{<:OpExpr}) = ∑(o)
∑{Op}(o::OpExpr) = ∑{Op}() + o
∑{Op}(o::OpTuple) = ∑{Op}(Op(o))
∑{Op}(which_op::WhichOp, args...; kwargs...) = ∑{Op}(Op(which_op, args...; kwargs...))
function ∑{Op}(α::Number, which_op::WhichOp, args...; kwargs...)
  return ∑{Op}(Op(α, which_op, args...; kwargs...))
end

# Lazy operations with Op
(arg1::Number * arg2::Op) = α(arg1, arg2)
(arg1::Op / arg2::Number) = inv(arg2) * arg1
(arg1::Op * arg2::Op) = ∏([arg1, arg2])
(arg1::Op + arg2::Op) = ∑([arg1, arg2])
-(o::Op) = -𝟏 * o

# Rules for adding, subtracting, and multiplying with Tuples
(arg1::OpExpr + arg2::Tuple) = arg1 + Op(arg2)
(arg1::Tuple + arg2::OpExpr) = Op(arg1) + arg2
(arg1::OpExpr - arg2::Tuple) = arg1 - Op(arg2)
(arg1::Tuple - arg2::OpExpr) = Op(arg1) - arg2
(arg1::OpExpr * arg2::Tuple) = arg1 * Op(arg2)
(arg1::Tuple * arg2::OpExpr) = Op(arg1) * arg2

function print_sites(io::IO, sites)
  nsites = length(sites)
  for n in 1:nsites
    print(io, sites[n])
    if n < nsites
      print(io, ", ")
    end
  end
end

function show(io::IO, ::MIME"text/plain", o::Op)
  print(io, which_op(o), "(")
  print_sites(io, sites(o))
  if !isempty(params(o))
    print(io, ", ", params(o))
  end
  return print(io, ")")
end

function show(io::IO, ::MIME"text/plain", o::∏{Op})
  for n in 1:length(o)
    print(io, o[n])
    if n < length(o)
      print(io, " * ")
    end
  end
end

function print_coefficient(io::IO, o)
  return print(io, o)
end

function print_coefficient(io::IO, o::Complex)
  return print(io, "(", o, ")")
end

function show(io::IO, ::MIME"text/plain", o::Union{α{Op},α{∏{Op}}})
  print_coefficient(io, coefficient(o))
  print(io, " ")
  return print(io, op(o))
end

function show(io::IO, ::MIME"text/plain", o::Union{∑{Op},∑{<:α{Op}},∑{∏{Op}},∑{<:α{∏{Op}}}})
  for n in 1:length(o)
    print(io, o[n])
    if n < length(o)
      print(io, " +\n")
    end
  end
end

show(io::IO, o::OpExpr) = show(io, MIME("text/plain"), o)

end


text:
using SweepContractor
using Test

@testset "ABCD" begin
    LTN = LabelledTensorNetwork{Char}()
    LTN['A'] = Tensor(['D','B'], [i^2-2j for i=0:2, j=0:2], 0, 1)
    LTN['B'] = Tensor(['A','D','C'], [-3^i*j+k for i=0:2, j=0:2, k=0:2], 0, 0)
    LTN['C'] = Tensor(['B','D'], [j for i=0:2, j=0:2], 1, 0)
    LTN['D'] = Tensor(['A','B','C'], [i*j*k for i=0:2, j=0:2, k=0:2], 1, 1)

    brute = 0.0
    for ab=1:3, ad=1:3, bc=1:3, bd=1:3, cd=1:3
        global brute += LTN['A'].arr[ad,ab] * LTN['B'].arr[ab,bd,bc] * LTN['C'].arr[bc,cd] *
            LTN['D'].arr[ad,bd,cd]
    end

    sweep = sweep_contract(LTN, 2, 4; fast=true)

    (mps,dangexp) = sweep_contract_dangling(LTN, 2, 4; fast=true)
    dang=0.0
    for i1=1:2, i2=1:2, da=1:3, db=1:3, dc=1:3
        global dang+=mps[1][1,da,i1]*mps[2][i1,db,i2]*mps[3][i2,dc,1]*LTN['D'].arr[da,db,dc]
    end

    @test ldexp(sweep...) == brute
    @test ldexp(sweep...) ≈ ldexp(dang,dangexp)
end

@testset "2d periodic" begin
    L=6; d=2

    LTN = LabelledTensorNetwork{Tuple{Int,Int}}()
    for i∈1:L, j∈1:L
        adj=[
            (mod1(i-1,L),mod1(j,L)),
            (mod1(i+1,L),mod1(j,L)),
            (mod1(i,L),mod1(j-1,L)),
            (mod1(i,L),mod1(j+1,L))
        ]
        LTN[i,j] = Tensor(adj, randn(d,d,d,d), i+0.01*rand(), j+0.01*rand())
    end

    last_val = 0.0
    this_val = 0.0
    for χ ∈ d.^(4:9)
        sweep = sweep_contract(LTN,χ, 2*χ)
        last_val = this_val
        this_val = sweep[1]
    end
    @test abs(last_val - this_val) < 1e-10
end


text:
using Test, MPI
include("../testhelpers.jl")

@testset "ODE Solvers" begin
  tests = [(1, "ode_tests.jl")]
  runmpi(tests, @__FILE__)
end

max_stars_repo_name: favba/CLIMA

max_issues_repo_name: favba/CLIMA

max_forks_repo_name: favba/CLIMA


text:
function _precompile_()
    # Precompiling this one methods seems to cut our allocations during package loading in half.
    @assert precompile(Tuple{typeof(Base.log), Memento.Logger, Memento.DefaultRecord})
end


text:
# This file is a part of TextSearch.jl

export TextConfig, Skipgram

# SKIP_WORDS = set(["…", "..", "...", "...."])

"""
    Skipgram(qsize, skip)

A skipgram is a kind of tokenization where `qsize` words having `skip` separation are used as a single token.
"""
struct Skipgram
    qsize::Int8
    skip::Int8
end

Base.isless(a::Skipgram, b::Skipgram) = isless((a.qsize, a.skip), (b.qsize, b.skip))
Base.isequal(a::Skipgram, b::Skipgram) = a.qsize == b.qsize && a.skip == b.skip

"""
    TextConfig(;
        del_diac::Bool=true,
        del_dup::Bool=false,
        del_punc::Bool=false,
        group_num::Bool=true,
        group_url::Bool=true,
        group_usr::Bool=false,
        group_emo::Bool=false,
        lc::Bool=true,
        qlist::Vector=Int8[],
        nlist::Vector=Int8[],
        slist::Vector{Skipgram}=Skipgram[]
    )

Defines a preprocessing and tokenization pipeline

- `del_diac`: indicates if diacritic symbols should be removed
- `del_dup`: indicates if duplicate contiguous symbols must be replaced for a single symbol
- `del_punc`: indicates if punctuaction symbols must be removed
- `group_num`: indicates if numbers should be grouped _num
- `group_url`: indicates if urls should be grouped as _url
- `group_usr`: indicates if users (@usr) should be grouped as _usr
- `group_emo`: indicates if emojis should be grouped as _emo
- `lc`: indicates if the text should be normalized to lower case
- `qlist`: a list of character q-grams to use
- `nlist`: a list of words n-grams to use
- `slist`: a list of skip-grams tokenizers to use

Note: If qlist, nlist, and slists are all empty arrays, then it defaults to nlist=[1]
"""
struct TextConfig
    del_diac::Bool
    del_dup::Bool
    del_punc::Bool
    group_num::Bool
    group_url::Bool
    group_usr::Bool
    group_emo::Bool
    lc::Bool
    qlist::Vector{Int8}
    nlist::Vector{Int8}
    slist::Vector{Skipgram}

    function TextConfig(del_diac, del_dup, del_punc, group_num, group_url, group_usr, group_emo, lc, qlist, nlist, slist)
        if length(qlist) == length(nlist) == length(slist) == 0
            nlist = [1]
        end
        qlist = sort!(Vector{Int8}(qlist))
        nlist = sort!(Vector{Int8}(nlist))
        slist = sort!(Vector{Skipgram}(slist))

        new(del_diac, del_dup, del_punc, group_num, group_url, group_usr, group_emo, lc, qlist, nlist, slist)
    end
end

function TextConfig(;
        del_diac::Bool=true,
        del_dup::Bool=false,
        del_punc::Bool=false,
        group_num::Bool=true,
        group_url::Bool=true,
        group_usr::Bool=false,
        group_emo::Bool=false,
        lc::Bool=true,
        qlist::AbstractVector=[],
        nlist::AbstractVector=[],
        slist::AbstractVector=[]
    )

    TextConfig(del_diac, del_dup, del_punc, group_num, group_url, group_usr, group_emo, lc, qlist, nlist, slist)
end

function Base.copy(c::TextConfig;
        del_diac=c.del_diac,
        del_dup=c.del_dup,
        del_punc=c.del_punc,
        group_num=c.group_num,
        group_url=c.group_url,
        group_usr=c.group_usr,
        group_emo=c.group_emo,
        lc=c.lc,
        qlist=c.qlist,
        nlist=c.nlist,
        slist=c.slist
    )

    TextConfig(del_diac, del_dup, del_punc, group_num, group_url, group_usr, group_emo,
        lc, qlist, nlist, slist)
end

Base.broadcastable(c::TextConfig) = (c,)

max_stars_repo_name: sadit/TextModel

max_issues_repo_name: sadit/TextModel

max_forks_repo_name: sadit/TextModel


text:
struct ValidateError <: Exception end

const rgroups = (:POINT, :ANALOG)

const descriptives = (:LABELS, :DESCRIPTIONS, :UNITS)

const rpoint = (:USED, :DATA_START, :FRAMES)
const ratescale = (:SCALE, :RATE)

const ranalog = (:USED, :GEN_SCALE, :OFFSET) ∪ ratescale
const bitsformat = (:BITS, :FORMAT)

const rforceplatf = (:TYPE, :ZERO, :CORNERS, :ORIGIN, :CHANNEL, :CAL_MATRIX)

const pointsigncheck = ((:POINT, :USED),
                   (:POINT, :DATA_START),
                   (:POINT, :FRAMES))

# const analogsigncheck = (:ANALOG, :USED)
# const fpsigncheck = (:FORCE_PLATFORM, :ZERO)

function validatec3d(header::Header, groups::Dict{Symbol,Group})
    # The following if-else ensures the minimum set of information needed to succesfully
    # read a C3DFile
    if !(rgroups ⊆ keys(groups))
        if !haskey(groups, :ANALOG)
            groups[:ANALOG] = Group(0, Int8(6), false, Int8(0), "ANALOG", :ANALOG, Int16(0),
                UInt8(22), "Analog data parameters", Dict{Symbol,Parameter}())
            groups[:ANALOG].params[:USED] = Parameter(0, Int8(5), false, Int8(0), "USED",
                :USED, Int16(0), UInt8(30), "Number of analog channels used",
                ScalarParameter(zero(Int16)))
        else
            d = setdiff(rgroups, keys(groups))
            msg = "Required group(s)"
            for p in d
                msg *= " :"*string(p)
            end
            msg *= " are missing"
            throw(ErrorException(msg))
        end
    end

    # Validate the :POINT group
    pointkeys = keys(groups[:POINT].params)
    if !(rpoint ⊆ pointkeys)
        # The minimum set of parameters in :POINT is rpoint
        d = setdiff(rpoint, pointkeys)
        msg = ":POINT is missing required parameter(s)"
        for p in d
            msg *= " :"*string(p)
        end
        throw(ErrorException(msg))
    end

    # Fix the sign for any point parameters that are likely to need it
    for (group, param) in pointsigncheck
        if any(signbit, groups[group].params[param].payload.data)
            groups[group].params[param] = unsigned(groups[group].params[param])
        end
    end

    POINT_USED = groups[:POINT][Int, :USED]
    ANALOG_USED = groups[:ANALOG][Int, :USED]
    if POINT_USED != 0 # There are markers
        # If there are markers, the additional set of required parameters is ratescale
        if !(ratescale ⊆ pointkeys)
            if !(:RATE ∈ pointkeys) && ANALOG_USED == 0
                # If there is no analog data, POINT:RATE isn't technically required
            else
                d = setdiff(rpoint, pointkeys)
                msg = ":POINT is missing required parameter(s)"
                for p in d
                    msg *= " :"*string(p)
                end
                throw(ErrorException(msg))
            end
        end

        if !(descriptives ⊆ pointkeys) # Check that the descriptive parameters exist
            if !haskey(groups[:POINT].params, :LABELS)
                # While the C3D file can technically be read in the absence of a LABELS
                # parameter, this implementation requires LABELS (for indexing)
                @debug ":POINT is missing parameter :LABELS"
                labels = [ "M"*string(i, pad=3) for i in 1:POINT_USED ]
                groups[:POINT].params[:LABELS] = Parameter(0, Int8(0), false,
                    abs(groups[:POINT].gid), "LABELS", :LABELS, Int16(0), UInt8(13),
                    "Marker labels", StringParameter(labels))
            elseif !haskey(groups[:POINT].params, :DESCRIPTIONS)
                @debug ":POINT is missing parameter :DESCRIPTIONS"
            elseif !haskey(groups[:POINT].params, :UNITS)
                @debug ":POINT is missing parameter :UNITS"
            end
        elseif groups[:POINT].params[:LABELS] isa Parameter{ScalarParameter}
            # ie There is only one used marker (or the others are unlabeled)
            groups[:POINT].params[:LABELS] = Parameter{StringParameter}(groups[:POINT].params[:LABELS])
        end

        POINT_LABELS = groups[:POINT][Vector{String}, :LABELS]
        # Valid labels are required for each marker by the C3DFile constructor
        if any(isempty, POINT_LABELS) ||
           length(POINT_LABELS) < POINT_USED # Some markers don't have labels
            i = 2
            while length(POINT_LABELS) < POINT_USED
                # Check for the existence of a runoff labels group
                if haskey(groups[:POINT].params, Symbol("LABEL",i))
                    append!(POINT_LABELS, groups[:POINT][Vector{String}, Symbol("LABEL",i)])
                    i += 1
                else
                    push!(POINT_LABELS, "")
                end
            end

            idx = findall(isempty, POINT_LABELS)
            labels = [ "M"*string(i, pad=3) for i in 1:length(idx) ]
            POINT_LABELS[idx] .= labels
        end

        if !allunique(POINT_LABELS)
            dups = String[]
            for i in 1:POINT_USED
                if !in(POINT_LABELS[i], dups)
                    push!(dups, POINT_LABELS[i])
                else
                    m = match(r"_(?<num>\d+)$", POINT_LABELS[i])

                    if m === nothing
                        POINT_LABELS[i] *= "_2"
                        push!(dups, POINT_LABELS[i])
                    else
                        newlabel = POINT_LABELS[i][1:(m.offset - 1)] *
                            string('_',tryparse(Int,m[:num])+1)
                        POINT_LABELS[i] = newlabel
                        push!(dups, POINT_LABELS[i])
                    end
                end
            end
        end
    end # End validate :POINT

    # Validate the :ANALOG group
    analogkeys = keys(groups[:ANALOG].params)
    if !haskey(groups[:ANALOG].params, :USED)
        msg = ":ANALOG is missing required parameter :USED"
        throw(ErrorException(msg))
    end

    if signbit(ANALOG_USED)
        groups[:ANALOG].params[:USED] = unsigned(groups[:ANALOG].params[:USED])
    end

    if ANALOG_USED != 0 # There are analog channels

        @label analogkeychanged
        # If there are analog channels, the required set of parameters is ranalog
        if !(ranalog ⊆ analogkeys)
            if :OFFSETS ∈ analogkeys
                groups[:ANALOG].params[:OFFSET] = groups[:ANALOG].params[:OFFSETS]
                delete!(groups[:ANALOG].params, :OFFSETS)
                @goto analogkeychanged # OFFSETS might not be the only missing parameter
            else
                d = setdiff(ranalog, analogkeys)
                msg = ":ANALOG is missing required parameter(s)"
                for p in d
                    msg *= " :"*string(p)
                end
                throw(ErrorException(msg))
            end
        elseif !(descriptives ⊆ analogkeys) # Check that the descriptive parameters exist
            if !haskey(groups[:ANALOG].params, :LABELS)
                @debug ":ANALOG is missing parameter :LABELS"
                labels = [ "A"*string(i, pad=3) for i in 1:ANALOG_USED ]
                groups[:ANALOG].params[:LABELS] = Parameter{StringParameter}(0, Int8(0),
                    false, abs(groups[:ANALOG].gid), "LABELS", :LABELS, Int16(0), UInt8(14),
                    "Channel labels", StringParameter(labels))
            elseif !haskey(groups[:ANALOG].params, :DESCRIPTIONS)
                @debug ":ANALOG is missing parameter :DESCRIPTIONS"
            elseif !haskey(groups[:ANALOG].params, :UNITS)
                @debug ":ANALOG is missing parameter :UNITS"
            end
        elseif groups[:ANALOG].params[:LABELS] isa ScalarParameter
            groups[:ANALOG].params[:LABELS] = StringParameter(groups[:ANALOG].params[:LABELS])
        end

        # Pad scale and offset if shorter than :USED
        l = length(groups[:ANALOG][Vector{Float32}, :SCALE])
        if l < ANALOG_USED
            append!(groups[:ANALOG][Vector{Float32}, :SCALE],
                    fill(one(Float32), ANALOG_USED - l))
        end

        l = length(groups[:ANALOG][Vector{Int16}, :OFFSET])
        if l < ANALOG_USED
            append!(groups[:ANALOG][Vector{Int16}, :OFFSET],
                    fill(one(Float32), ANALOG_USED - l))
        end

        ANALOG_LABELS = groups[:ANALOG][Vector{String}, :LABELS]
        if any(isempty, ANALOG_LABELS) ||
           length(ANALOG_LABELS) < ANALOG_USED # Some markers don't have labels
            i = 2
            while length(ANALOG_LABELS) < ANALOG_USED
                if haskey(groups[:ANALOG].params, Symbol("LABEL",i)) # Check for the existence of a runoff labels group
                    append!(ANALOG_LABELS, groups[:ANALOG][Vector{String}, Symbol("LABEL",i)])
                    i += 1
                else
                    push!(ANALOG_LABELS, "")
                end
            end

            idx = findall(isempty, ANALOG_LABELS)
            labels = [ "A"*string(i, pad=3) for i in 1:length(idx) ]
            ANALOG_LABELS[idx] .= labels
        end

        if !allunique(ANALOG_LABELS)
            dups = String[]
            for i in 1:ANALOG_USED
                if !in(ANALOG_LABELS[i], dups)
                    push!(dups, ANALOG_LABELS[i])
                else
                    m = match(r"_(?<num>\d+)$", ANALOG_LABELS[i])

                    if m === nothing
                        ANALOG_LABELS[i] *= "_2"
                        push!(dups, ANALOG_LABELS[i])
                    else
                        newlabel = ANALOG_LABELS[i][1:(m.offset - 1)] *
                            string('_', tryparse(Int, m[:num]) + 1)
                        ANALOG_LABELS[i] = newlabel
                        push!(dups, ANALOG_LABELS[i])
                    end
                end
            end
        end
    end # End if analog channels exist

    return nothing
end


text:
# Autogenerated wrapper script for Clang_jll for i686-linux-musl-cxx03
export clang, libclang, libclang_cpp

using Zlib_jll
using libLLVM_jll
JLLWrappers.@generate_wrapper_header("Clang")
JLLWrappers.@declare_executable_product(clang)
JLLWrappers.@declare_library_product(libclang, "libclang.so.13")
JLLWrappers.@declare_library_product(libclang_cpp, "libclang-cpp.so.13jl")
function __init__()
    JLLWrappers.@generate_init_header(Zlib_jll, libLLVM_jll)
    JLLWrappers.@init_executable_product(
        clang,
        "tools/clang",
    )

    JLLWrappers.@init_library_product(
        libclang,
        "lib/libclang.so",
        nothing,
    )

    JLLWrappers.@init_library_product(
        libclang_cpp,
        "lib/libclang-cpp.so",
        nothing,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
#
#      Manifold -- a manifold defined via its data types:
#  * A point on the manifold, MPoint
#  * A point in an tangential space TVector
#
# Manopt.jl, R. Bergmann, 2019
import LinearAlgebra: norm, dot
import Base: exp, log, +, -, *, /, ==, show, copy
# introcude new types
export Manifold, MPoint, TVector
# introduce new functions
export geodesic, midPoint, reflection, jacobiField, adjointJacobiField
export +, -, *, /, ==, show, copy
@doc doc"""
An abstract manifold $\mathcal M$ to keep global information on a specific manifold
"""
abstract type Manifold end

@doc doc"""
An abstract point $x$ on a [`Manifold`](@ref) $\mathcal M$.
"""
abstract type MPoint end

@doc doc"""
A tangent vector $\xi \in T_x\mathcal M$ at a [`MPoint`](@ref) point $x$ on a
[`Manifold`](@ref) $\mathcal M$.
"""
abstract type TVector end

# scale tangential vectors
*(ξ::T,s::N) where {T <: TVector, N <: Number} = T(s* getValue(ξ) )
*(s::N, ξ::T) where {T <: TVector, N <: Number} = T(s* getValue(ξ) )
# /
/(ξ::T,s::N) where {T <: TVector, N <: Number} = T( getValue(ξ) ./ s)
/(s::N, ξ::T) where {T <: TVector, N <: Number} = T(s ./ getValue(ξ) )
# + - of TVectors
+(ξ::T,ν::T) where {T <: TVector} = T( getValue(ξ) + getValue(ν) )
-(ξ::T,ν::T) where {T <: TVector} = T( getValue(ξ) - getValue(ν) )
# unary operators
-(ξ::T) where {T <: TVector} = T(- getValue(ξ))
+(ξ::T) where {T <: TVector} = T(getValue(ξ))

# compare Points & vectors
==(x::T, y::T) where {T <: MPoint} = all(getValue(x) == getValue(y) )
==(ξ::T,ν::T) where {T <: TVector} = (  all( getValue(ξ) == getValue(ν) )  )
#
#
# General functions available on manifolds based on exp/log/dist
#
#
@doc doc"""
    addNoise(M,x)

add noise to a [`MPoint`](@ref) `x` on the [`Manifold`](@ref) `M` by using the
[`randomTVector`](@ref) method and doing an exponential step.
Optional parameters, like the type of noise and parameters for the noise
may be given and are just passed on-
"""
addNoise(M::mT, x::P, options...) where {mT <: Manifold, P <: MPoint} = exp(
    M,x,randomTVector(M,x,options...)
)

@doc doc"""
    ζ = adjointJacobiField(M,x,y,t,η,w)

compute the AdjointJacobiField $J$ along the geodesic $g_{x,y}$ on the manifold
$\mathcal M$ with initial conditions (depending on the application)
$\eta\in T_{g(t;x,y)\mathcal M}$ and weights $\beta$. The result is a vector
$\zeta \in T_x\mathcal M$. The main difference to [`jacobiField`](@ref) is the,
that the input $\eta$ and the output $\zeta$ switched tangent spaces.

For detais see [`jacobiField`](@ref)
"""
function adjointJacobiField(M::mT,x::P,y::P,t::Number,η::T,β::Function=βDgx) where {mT<:Manifold, P<:MPoint, T<:TVector}
    z = geodesic(M,x,y,t); # Point the TzM of the resulting vector lies in
    Ξ,κ = tangentONB(M,x,y) # ONB at x
    Θ = parallelTransport.(Ref(M),Ref(x),Ref(z),Ξ) # Frame at z
    # Decompose wrt. Ξ, multiply with the weights from w and recompose with Θ.
    ξ = sum( ( dot.(Ref(M),Ref(z),Ref(η),Θ) ).* ( β.(κ,Ref(t),distance(M,x,y)) ).*Ξ )
end

copy(x::P) where {P <: MPoint} = P(copy(getValue(x)))
copy(ξ::T) where {T <: TVector} = T(copy(getValue(ξ)))

"""
    midPoint(M,x,y,z)

compute the mid point between x and y. If there is more than one mid point
of (not neccessarily miniizing) geodesics (i.e. on the sphere), the one nearest
to z.
"""
function midPoint(M::mT,x::T,y::T,z::T)::T where {mT <: Manifold, T <: MPoint}
    # since this is the fallback, it just uses the non-nearest one
    return midPoint(M,x,y)
end

"""
    midPoint(M,x,y)

compute the (geodesic) mid point of the two [`MPoint`](@ref)s `x` and `y` on the
[`Manifold`](@ref) `M`. If the geodesic is not unique, either a deterministic
choice is returned or an error is raised. For the deteministic choixe, see
[`midPoint(M,x,y,z)`](@ref), the mid point closest to a third [`MPoint`](@ref)
`z`.
"""
function midPoint(M::mT,x::T, y::T)::T where {mT <: Manifold, T <: MPoint}
  return exp(M,x,0.5*log(M,x,y))
end

"""
    geodesic(M,x,y)

return a function to evaluate the geodesic connecting the two [`MPoint`](@ref)s
`x` and `y` on the [`Manifold`](@ref) `M`.
"""
geodesic(M::mT, x::T,y::T) where {mT <: Manifold, T <: MPoint} = t -> exp(M,x,t*log(M,x,y))

"""
    geodesic(M,x,y,n)

return vector containing the equispaced `n` sample-values along the geodesic
connecting the two [`MPoint`](@ref)s `x` and `y` on the [`Manifold`](@ref) `M`."""
geodesic(M::mT, x::T,y::T,n::Integer) where {mT <: Manifold, T <: MPoint} = geodesic(M,x,y,[range(0.,1.,length=n)...])

"""
    geodesic(M,x,y,t)

return the point along the geodesic from [`MPoint`](@ref) `x` to `y` given by
at value `t` (in `[0,1]`) on the [`Manifold`](@ref) `M`
"""
geodesic(M::mT,x::T,y::T,t::N) where {mT <: Manifold, T <: MPoint, N <: Number} = geodesic(M,x,y)(t)

"""
    geodesic(M,x,y,T)

return vector containing the [`MPoint`](@ref) along the geodesic from
[`MPoint`](@ref) `x` to `y` on the [`Manifold`](@ref) `M` specified by the
points from the vector `T` (of numbers between 0 and 1).
"""
geodesic(M::mT, x::P,y::P,T::Vector{S}) where {mT <: Manifold, P <: MPoint, S <: Number} = geodesic(M,x,y).(T)

@doc doc"""
    getValue(x)

get the value representing the [`MPoint`](@ref) `x`.
This function defaults to returning `x.value`; if your representation is
different, you should implement this function for your type
"""
function getValue(x::P) where {P <: MPoint}
    try
        return x.value
    catch
        sig1 = string( typeof(x) )
        throw( DomainError("getValue not defined/implemented for a $sig1.") );
    end
end
@doc doc"""
    getValue(ξ)

get the value representing the [`TVector`](@ref) `ξ`.
This function defaults to returning `ξ.value`; if your representation is
different, you should implement this function for your type
"""
function getValue(ξ::T) where {T <: TVector}
    try
        return ξ.value
    catch
        sig1 = string( typeof(ξ) )
        throw( DomainError("getValue – not defined/implemented for tangent vector $sig1.") );
    end
end

@doc doc"""
    ζ = jacobiField(M,x,y,t,η,β)

compute the jacobiField $J$ along the geodesic $g_{x,y}$ on the
[`Manifold`](@ref) `M` $\mathcal M$ with initial conditions (depending on the
application) $\eta\in T_x\mathcal M$ and weights $\beta$. The result is a
[`TVector`](@ref) in $\zeta \in T_{g(t;x,y)}\mathcal M$.

# See also
 [`adjointJacobiField`](@ref)
"""
function jacobiField(M::mT,x::P,y::P,t::Number,η::T,β::Function=βDgx) where {mT<:Manifold, P<:MPoint, T<:TVector}
    z = geodesic(M,x,y,t); # Point the TzM of the resulting vector lies in
    Ξ,κ = tangentONB(M,x,y) # ONB at x
    Θ = parallelTransport.(Ref(M),Ref(x),Ref(z),Ξ) # Frame at z
    # Decompose wrt. Ξ, multiply with the weights from w and recompose with Θ.
    ξ = sum( ( dot.(Ref(M),Ref(x),Ref(η),Ξ) ).* ( β.(κ,Ref(t),Ref(distance(M,x,y))) ).*Θ )
end

@doc doc"""
    manifoldDimension(x)

return the dimension of the manifold `M` the point `x` belongs to.
"""
function manifoldDimension(x::P)::Integer where {P<:MPoint}
  sig1 = string( typeof(x) )
  throw( DomainError("manifoldDimension not defined/implemented for a $sig1." ) )
end
@doc doc"""
    manifoldDimension(M)

returns the dimension of the manifold `M`.
"""
function manifoldDimension(M::mT)::Integer where {mT<:Manifold}
  sig1 = string( typeof(M) )
  throw( DomainError("manifoldDimension not defined/implemented on $sig1." ) )
end

@doc doc"""
    norm(M,x,ξ)

computes the length of a [`TVector`](@ref) `ξ` in the tangent space of the
[`MPoint`](@ref) `x` on the [`Manifold`](@ref) `M` induced by the inner product.
"""
norm(M::mT,x::P,ξ::T) where {mT<:Manifold,P<:MPoint,T<:TVector} = sqrt(dot(M,x,ξ,ξ))

randomMPoint(M::mT,options...) where {mT <: Manifold} = randomMPoint(M, :Gaussian, options...)
@doc doc"""
    randomMPoint(M,x [,:Gaussian,options...])

generate a random [`MPoint`](@ref) on the [`Manifold`](@ref) `M` by falling
back to the default `:Gaussian` noise with the default standard deviation
on the specific manifold.
"""
randomMPoint(M::mT,s::Symbol,options...) where {mT <: Manifold} = randomMPoint(M, Val(s), options...)

randomTVector(M::mT, x::P, options...) where {mT <: Manifold, P <: MPoint} = randomTVector(M,x,:Gaussian,options...)
@doc doc"""
    randomTVector(M,x [,:Gaussian,options...])

generate a random tangent vector at [`MPoint`](@ref) `x`
on the [`Manifold`](@ref) `M` using `:Gaussian` noise where options usually
contain the standard deviation σ on the specific manifold.
"""
randomTVector(M::mT, x::P,s::Symbol,options...) where {mT <: Manifold, P <: MPoint} = randomTVector(M,x,Val(s),options...)

@doc doc"""
    y = reflection(M,p,x)

reflect the `MPoint x` at `MPoint p`, i.e. compute
$y = R_p(x) = \exp_p(-\log_px)$. On Euclidean space this results in the point
reflection $R_p(x) = p - (x-p) = 2p-x$.

# Arguments
* `M` – a [`Manifold`](@ref) $\mathcal M$
* `p` – an [`MPoint`](@ref) $p\in\mathcal M$ to relfect at
* `x` – an [`MPoint`](@ref) $x\in\mathcal M$ that is reflected

# Output
* `y` – the resulting reflection.
"""
reflection(M::mT, p::P, x::P) where {mT <: Manifold, P<: MPoint} = exp(M,p,-log(M,p,x))

"""
    typeofMPoint(ξ)

return the [`MPoint`](@ref) belonging to the [`TVector`](@ref) type of `ξ`.
"""
typeofMPoint(ξ::T) where {T <: TVector} = typeofMPoint(typeof(ξ))
"""
    typeofTVector(x)

return the [`TVector`](@ref) belonging to the [`MPoint`](@ref) type of `x`.
"""
typeofTVector(x::P) where {P <: MPoint} = typeofTVector(typeof(x))


text:
ZMQ_CONFLATE = 54

struct MercuryException <: Exception
    msg::String
end
Base.showerror(io::IO, e::MercuryException) = print(io, "Error from Mercury: " * e.msg)

# Set conflate option for ZMQ, not included in ZMQ.jl
function set_conflate(socket::ZMQ.Socket, option_val::Integer)
    rc = ccall(
        (:zmq_setsockopt, ZMQ.libzmq),
        Cint,
        (Ptr{Cvoid}, Cint, Ref{Cint}, Csize_t),
        socket,
        ZMQ_CONFLATE,
        option_val,
        sizeof(Cint),
    )
    if rc != 0
        throw(ZMQ.StateError(ZMQ.jl_zmq_error_str()))
    end
end
# Get the conflate option for ZMQ, not included in ZMQ.jl
function get_conflate(socket::ZMQ.Socket, option_val::Integer)
    rc = ccall(
        (:zmq_getsockopt, ZMQ.libzmq),
        Cint,
        (Ptr{Cvoid}, Cint, Ref{Cint}, Csize_t),
        socket,
        ZMQ_CONFLATE,
        option_val,
        sizeof(Cint),
    )
    if rc != 0
        throw(ZMQ.StateError(ZMQ.jl_zmq_error_str()))
    end
end

NUM_PUBS = 1;
reset_pub_count() = global NUM_PUBS = 1
function genpublishername()
    global NUM_PUBS
    name = "publisher_$NUM_PUBS"
    NUM_PUBS += 1
    return name
end

NUM_SUBS = 1;
reset_sub_count() = global NUM_SUBS = 1
function gensubscribername()
    global NUM_SUBS
    name = "subscriber_$NUM_SUBS"
    NUM_SUBS += 1
    return name
end

macro catchzmq(expr, errmsg)
    ex = quote
        try
            $expr
        catch e
            if e isa ZMQ.StateError
                @error $errmsg * "\n" * ZMQ.jl_zmq_error_str()
            end
            rethrow(e)
        end
    end
    return esc(ex)
end

macro catchserial(expr, errmsg)
    ex = quote
        try
            $expr
        catch e
            if e isa LibSerialPort.Timeout
                @error "LibSerialPort Timeout error thrown. Is a device connected to the serial port?\n"
            elseif e isa ErrorException
                @error $errmsg * "\n"
            end
            rethrow(e)
        end
    end
    return esc(ex)
end

tcpstring(ipaddr, port) = "tcp://" * string(ipaddr) * ":" * string(port)


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

@doc raw"""PodSecurityPolicySpec defines the policy enforced. Deprecated: use PodSecurityPolicySpec from policy API Group instead.

    IoK8sApiExtensionsV1beta1PodSecurityPolicySpec(;
        allowPrivilegeEscalation=nothing,
        allowedCSIDrivers=nothing,
        allowedCapabilities=nothing,
        allowedFlexVolumes=nothing,
        allowedHostPaths=nothing,
        allowedProcMountTypes=nothing,
        allowedUnsafeSysctls=nothing,
        defaultAddCapabilities=nothing,
        defaultAllowPrivilegeEscalation=nothing,
        forbiddenSysctls=nothing,
        fsGroup=nothing,
        hostIPC=nothing,
        hostNetwork=nothing,
        hostPID=nothing,
        hostPorts=nothing,
        privileged=nothing,
        readOnlyRootFilesystem=nothing,
        requiredDropCapabilities=nothing,
        runAsGroup=nothing,
        runAsUser=nothing,
        runtimeClass=nothing,
        seLinux=nothing,
        supplementalGroups=nothing,
        volumes=nothing,
    )

    - allowPrivilegeEscalation::Bool : allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.
    - allowedCSIDrivers::Vector{IoK8sApiExtensionsV1beta1AllowedCSIDriver} : AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
    - allowedCapabilities::Vector{String} : allowedCapabilities is a list of capabilities that can be requested to add to the container. Capabilities in this field may be added at the pod author's discretion. You must not list a capability in both allowedCapabilities and requiredDropCapabilities.
    - allowedFlexVolumes::Vector{IoK8sApiExtensionsV1beta1AllowedFlexVolume} : allowedFlexVolumes is a whitelist of allowed Flexvolumes.  Empty or nil indicates that all Flexvolumes may be used.  This parameter is effective only when the usage of the Flexvolumes is allowed in the \"volumes\" field.
    - allowedHostPaths::Vector{IoK8sApiExtensionsV1beta1AllowedHostPath} : allowedHostPaths is a white list of allowed host paths. Empty indicates that all host paths may be used.
    - allowedProcMountTypes::Vector{String} : AllowedProcMountTypes is a whitelist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.
    - allowedUnsafeSysctls::Vector{String} : allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection.  Examples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc.
    - defaultAddCapabilities::Vector{String} : defaultAddCapabilities is the default set of capabilities that will be added to the container unless the pod spec specifically drops the capability.  You may not list a capability in both defaultAddCapabilities and requiredDropCapabilities. Capabilities added here are implicitly allowed, and need not be included in the allowedCapabilities list.
    - defaultAllowPrivilegeEscalation::Bool : defaultAllowPrivilegeEscalation controls the default setting for whether a process can gain more privileges than its parent process.
    - forbiddenSysctls::Vector{String} : forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.  Examples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc.
    - fsGroup::IoK8sApiExtensionsV1beta1FSGroupStrategyOptions : fsGroup is the strategy that will dictate what fs group is used by the SecurityContext.
    - hostIPC::Bool : hostIPC determines if the policy allows the use of HostIPC in the pod spec.
    - hostNetwork::Bool : hostNetwork determines if the policy allows the use of HostNetwork in the pod spec.
    - hostPID::Bool : hostPID determines if the policy allows the use of HostPID in the pod spec.
    - hostPorts::Vector{IoK8sApiExtensionsV1beta1HostPortRange} : hostPorts determines which host port ranges are allowed to be exposed.
    - privileged::Bool : privileged determines if a pod can request to be run as privileged.
    - readOnlyRootFilesystem::Bool : readOnlyRootFilesystem when set to true will force containers to run with a read only root file system.  If the container specifically requests to run with a non-read only root file system the PSP should deny the pod. If set to false the container may run with a read only root file system if it wishes but it will not be forced to.
    - requiredDropCapabilities::Vector{String} : requiredDropCapabilities are the capabilities that will be dropped from the container.  These are required to be dropped and cannot be added.
    - runAsGroup::IoK8sApiExtensionsV1beta1RunAsGroupStrategyOptions : RunAsGroup is the strategy that will dictate the allowable RunAsGroup values that may be set. If this field is omitted, the pod's RunAsGroup can take any value. This field requires the RunAsGroup feature gate to be enabled.
    - runAsUser::IoK8sApiExtensionsV1beta1RunAsUserStrategyOptions : runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.
    - runtimeClass::IoK8sApiExtensionsV1beta1RuntimeClassStrategyOptions : runtimeClass is the strategy that will dictate the allowable RuntimeClasses for a pod. If this field is omitted, the pod's runtimeClassName field is unrestricted. Enforcement of this field depends on the RuntimeClass feature gate being enabled.
    - seLinux::IoK8sApiExtensionsV1beta1SELinuxStrategyOptions : seLinux is the strategy that will dictate the allowable labels that may be set.
    - supplementalGroups::IoK8sApiExtensionsV1beta1SupplementalGroupsStrategyOptions : supplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext.
    - volumes::Vector{String} : volumes is a white list of allowed volume plugins. Empty indicates that no volumes may be used. To allow all volumes you may use '*'.
"""
mutable struct IoK8sApiExtensionsV1beta1PodSecurityPolicySpec <: SwaggerModel
    allowPrivilegeEscalation::Any # spec type: Union{ Nothing, Bool } # spec name: allowPrivilegeEscalation
    allowedCSIDrivers::Any # spec type: Union{ Nothing, Vector{IoK8sApiExtensionsV1beta1AllowedCSIDriver} } # spec name: allowedCSIDrivers
    allowedCapabilities::Any # spec type: Union{ Nothing, Vector{String} } # spec name: allowedCapabilities
    allowedFlexVolumes::Any # spec type: Union{ Nothing, Vector{IoK8sApiExtensionsV1beta1AllowedFlexVolume} } # spec name: allowedFlexVolumes
    allowedHostPaths::Any # spec type: Union{ Nothing, Vector{IoK8sApiExtensionsV1beta1AllowedHostPath} } # spec name: allowedHostPaths
    allowedProcMountTypes::Any # spec type: Union{ Nothing, Vector{String} } # spec name: allowedProcMountTypes
    allowedUnsafeSysctls::Any # spec type: Union{ Nothing, Vector{String} } # spec name: allowedUnsafeSysctls
    defaultAddCapabilities::Any # spec type: Union{ Nothing, Vector{String} } # spec name: defaultAddCapabilities
    defaultAllowPrivilegeEscalation::Any # spec type: Union{ Nothing, Bool } # spec name: defaultAllowPrivilegeEscalation
    forbiddenSysctls::Any # spec type: Union{ Nothing, Vector{String} } # spec name: forbiddenSysctls
    fsGroup::Any # spec type: Union{ Nothing, IoK8sApiExtensionsV1beta1FSGroupStrategyOptions } # spec name: fsGroup
    hostIPC::Any # spec type: Union{ Nothing, Bool } # spec name: hostIPC
    hostNetwork::Any # spec type: Union{ Nothing, Bool } # spec name: hostNetwork
    hostPID::Any # spec type: Union{ Nothing, Bool } # spec name: hostPID
    hostPorts::Any # spec type: Union{ Nothing, Vector{IoK8sApiExtensionsV1beta1HostPortRange} } # spec name: hostPorts
    privileged::Any # spec type: Union{ Nothing, Bool } # spec name: privileged
    readOnlyRootFilesystem::Any # spec type: Union{ Nothing, Bool } # spec name: readOnlyRootFilesystem
    requiredDropCapabilities::Any # spec type: Union{ Nothing, Vector{String} } # spec name: requiredDropCapabilities
    runAsGroup::Any # spec type: Union{ Nothing, IoK8sApiExtensionsV1beta1RunAsGroupStrategyOptions } # spec name: runAsGroup
    runAsUser::Any # spec type: Union{ Nothing, IoK8sApiExtensionsV1beta1RunAsUserStrategyOptions } # spec name: runAsUser
    runtimeClass::Any # spec type: Union{ Nothing, IoK8sApiExtensionsV1beta1RuntimeClassStrategyOptions } # spec name: runtimeClass
    seLinux::Any # spec type: Union{ Nothing, IoK8sApiExtensionsV1beta1SELinuxStrategyOptions } # spec name: seLinux
    supplementalGroups::Any # spec type: Union{ Nothing, IoK8sApiExtensionsV1beta1SupplementalGroupsStrategyOptions } # spec name: supplementalGroups
    volumes::Any # spec type: Union{ Nothing, Vector{String} } # spec name: volumes

    function IoK8sApiExtensionsV1beta1PodSecurityPolicySpec(;allowPrivilegeEscalation=nothing, allowedCSIDrivers=nothing, allowedCapabilities=nothing, allowedFlexVolumes=nothing, allowedHostPaths=nothing, allowedProcMountTypes=nothing, allowedUnsafeSysctls=nothing, defaultAddCapabilities=nothing, defaultAllowPrivilegeEscalation=nothing, forbiddenSysctls=nothing, fsGroup=nothing, hostIPC=nothing, hostNetwork=nothing, hostPID=nothing, hostPorts=nothing, privileged=nothing, readOnlyRootFilesystem=nothing, requiredDropCapabilities=nothing, runAsGroup=nothing, runAsUser=nothing, runtimeClass=nothing, seLinux=nothing, supplementalGroups=nothing, volumes=nothing)
        o = new()
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("allowPrivilegeEscalation"), allowPrivilegeEscalation)
        setfield!(o, Symbol("allowPrivilegeEscalation"), allowPrivilegeEscalation)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("allowedCSIDrivers"), allowedCSIDrivers)
        setfield!(o, Symbol("allowedCSIDrivers"), allowedCSIDrivers)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("allowedCapabilities"), allowedCapabilities)
        setfield!(o, Symbol("allowedCapabilities"), allowedCapabilities)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("allowedFlexVolumes"), allowedFlexVolumes)
        setfield!(o, Symbol("allowedFlexVolumes"), allowedFlexVolumes)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("allowedHostPaths"), allowedHostPaths)
        setfield!(o, Symbol("allowedHostPaths"), allowedHostPaths)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("allowedProcMountTypes"), allowedProcMountTypes)
        setfield!(o, Symbol("allowedProcMountTypes"), allowedProcMountTypes)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("allowedUnsafeSysctls"), allowedUnsafeSysctls)
        setfield!(o, Symbol("allowedUnsafeSysctls"), allowedUnsafeSysctls)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("defaultAddCapabilities"), defaultAddCapabilities)
        setfield!(o, Symbol("defaultAddCapabilities"), defaultAddCapabilities)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("defaultAllowPrivilegeEscalation"), defaultAllowPrivilegeEscalation)
        setfield!(o, Symbol("defaultAllowPrivilegeEscalation"), defaultAllowPrivilegeEscalation)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("forbiddenSysctls"), forbiddenSysctls)
        setfield!(o, Symbol("forbiddenSysctls"), forbiddenSysctls)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("fsGroup"), fsGroup)
        setfield!(o, Symbol("fsGroup"), fsGroup)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("hostIPC"), hostIPC)
        setfield!(o, Symbol("hostIPC"), hostIPC)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("hostNetwork"), hostNetwork)
        setfield!(o, Symbol("hostNetwork"), hostNetwork)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("hostPID"), hostPID)
        setfield!(o, Symbol("hostPID"), hostPID)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("hostPorts"), hostPorts)
        setfield!(o, Symbol("hostPorts"), hostPorts)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("privileged"), privileged)
        setfield!(o, Symbol("privileged"), privileged)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("readOnlyRootFilesystem"), readOnlyRootFilesystem)
        setfield!(o, Symbol("readOnlyRootFilesystem"), readOnlyRootFilesystem)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("requiredDropCapabilities"), requiredDropCapabilities)
        setfield!(o, Symbol("requiredDropCapabilities"), requiredDropCapabilities)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("runAsGroup"), runAsGroup)
        setfield!(o, Symbol("runAsGroup"), runAsGroup)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("runAsUser"), runAsUser)
        setfield!(o, Symbol("runAsUser"), runAsUser)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("runtimeClass"), runtimeClass)
        setfield!(o, Symbol("runtimeClass"), runtimeClass)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("seLinux"), seLinux)
        setfield!(o, Symbol("seLinux"), seLinux)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("supplementalGroups"), supplementalGroups)
        setfield!(o, Symbol("supplementalGroups"), supplementalGroups)
        validate_property(IoK8sApiExtensionsV1beta1PodSecurityPolicySpec, Symbol("volumes"), volumes)
        setfield!(o, Symbol("volumes"), volumes)
        o
    end
end # type IoK8sApiExtensionsV1beta1PodSecurityPolicySpec

const _property_map_IoK8sApiExtensionsV1beta1PodSecurityPolicySpec = Dict{Symbol,Symbol}(Symbol("allowPrivilegeEscalation")=>Symbol("allowPrivilegeEscalation"), Symbol("allowedCSIDrivers")=>Symbol("allowedCSIDrivers"), Symbol("allowedCapabilities")=>Symbol("allowedCapabilities"), Symbol("allowedFlexVolumes")=>Symbol("allowedFlexVolumes"), Symbol("allowedHostPaths")=>Symbol("allowedHostPaths"), Symbol("allowedProcMountTypes")=>Symbol("allowedProcMountTypes"), Symbol("allowedUnsafeSysctls")=>Symbol("allowedUnsafeSysctls"), Symbol("defaultAddCapabilities")=>Symbol("defaultAddCapabilities"), Symbol("defaultAllowPrivilegeEscalation")=>Symbol("defaultAllowPrivilegeEscalation"), Symbol("forbiddenSysctls")=>Symbol("forbiddenSysctls"), Symbol("fsGroup")=>Symbol("fsGroup"), Symbol("hostIPC")=>Symbol("hostIPC"), Symbol("hostNetwork")=>Symbol("hostNetwork"), Symbol("hostPID")=>Symbol("hostPID"), Symbol("hostPorts")=>Symbol("hostPorts"), Symbol("privileged")=>Symbol("privileged"), Symbol("readOnlyRootFilesystem")=>Symbol("readOnlyRootFilesystem"), Symbol("requiredDropCapabilities")=>Symbol("requiredDropCapabilities"), Symbol("runAsGroup")=>Symbol("runAsGroup"), Symbol("runAsUser")=>Symbol("runAsUser"), Symbol("runtimeClass")=>Symbol("runtimeClass"), Symbol("seLinux")=>Symbol("seLinux"), Symbol("supplementalGroups")=>Symbol("supplementalGroups"), Symbol("volumes")=>Symbol("volumes"))
const _property_types_IoK8sApiExtensionsV1beta1PodSecurityPolicySpec = Dict{Symbol,String}(Symbol("allowPrivilegeEscalation")=>"Bool", Symbol("allowedCSIDrivers")=>"Vector{IoK8sApiExtensionsV1beta1AllowedCSIDriver}", Symbol("allowedCapabilities")=>"Vector{String}", Symbol("allowedFlexVolumes")=>"Vector{IoK8sApiExtensionsV1beta1AllowedFlexVolume}", Symbol("allowedHostPaths")=>"Vector{IoK8sApiExtensionsV1beta1AllowedHostPath}", Symbol("allowedProcMountTypes")=>"Vector{String}", Symbol("allowedUnsafeSysctls")=>"Vector{String}", Symbol("defaultAddCapabilities")=>"Vector{String}", Symbol("defaultAllowPrivilegeEscalation")=>"Bool", Symbol("forbiddenSysctls")=>"Vector{String}", Symbol("fsGroup")=>"IoK8sApiExtensionsV1beta1FSGroupStrategyOptions", Symbol("hostIPC")=>"Bool", Symbol("hostNetwork")=>"Bool", Symbol("hostPID")=>"Bool", Symbol("hostPorts")=>"Vector{IoK8sApiExtensionsV1beta1HostPortRange}", Symbol("privileged")=>"Bool", Symbol("readOnlyRootFilesystem")=>"Bool", Symbol("requiredDropCapabilities")=>"Vector{String}", Symbol("runAsGroup")=>"IoK8sApiExtensionsV1beta1RunAsGroupStrategyOptions", Symbol("runAsUser")=>"IoK8sApiExtensionsV1beta1RunAsUserStrategyOptions", Symbol("runtimeClass")=>"IoK8sApiExtensionsV1beta1RuntimeClassStrategyOptions", Symbol("seLinux")=>"IoK8sApiExtensionsV1beta1SELinuxStrategyOptions", Symbol("supplementalGroups")=>"IoK8sApiExtensionsV1beta1SupplementalGroupsStrategyOptions", Symbol("volumes")=>"Vector{String}")
Base.propertynames(::Type{ IoK8sApiExtensionsV1beta1PodSecurityPolicySpec }) = collect(keys(_property_map_IoK8sApiExtensionsV1beta1PodSecurityPolicySpec))
Swagger.property_type(::Type{ IoK8sApiExtensionsV1beta1PodSecurityPolicySpec }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_IoK8sApiExtensionsV1beta1PodSecurityPolicySpec[name]))}
Swagger.field_name(::Type{ IoK8sApiExtensionsV1beta1PodSecurityPolicySpec }, property_name::Symbol) =  _property_map_IoK8sApiExtensionsV1beta1PodSecurityPolicySpec[property_name]

function check_required(o::IoK8sApiExtensionsV1beta1PodSecurityPolicySpec)
    (getproperty(o, Symbol("fsGroup")) === nothing) && (return false)
    (getproperty(o, Symbol("runAsUser")) === nothing) && (return false)
    (getproperty(o, Symbol("seLinux")) === nothing) && (return false)
    (getproperty(o, Symbol("supplementalGroups")) === nothing) && (return false)
    true
end

function validate_property(::Type{ IoK8sApiExtensionsV1beta1PodSecurityPolicySpec }, name::Symbol, val)
end


text:
# FunctorApplicativeMonad
# =======================

@test map(Identity(3)) do x
  x + 4
end == Identity(3 + 4)

@test mapn(Identity(3), Identity(4)) do x, y
  x + y
end == Identity(3 + 4)

@test pure(Identity, 5) == Identity(5)

h = @syntax_flatmap begin
  x = Identity(3)
  y = Identity(4)
  @pure x + y
end
@test h == Identity(3 + 4)

# MonoidAlternative
# =================

@test neutral(Identity{String}) == Option()
@test neutral(Identity) == Option()
@test Identity("hi") ⊕ Identity("ho") == Identity("hiho")

# FlipTypes
# ========

@test flip_types(Identity([1,2,3,4])) == Identity.([1,2,3,4])


text:
# The purpose of this script is to compare the filtering capability of the single snapshots
# estimates and the gas filter on a given

#

using JLD2,Utilities,StaticNets,DynNets, Clustering
using PyCall; pygui(:qt); using PyPlot

################## Compute score autororrelation on syntetic data
Nsample=10
save_fold = "./data/estimatesTest/asympTest/"
@load(save_fold*"FilterTestDynamicIncreasingSize_large_denseAndSparse_$(Nsample)_scaling.jld", dynFitDgp,
        dynDegsSam,estFitSS,indsTVnodes,storeGasPar,rmseSSandGas,filFitGas,convGasFlag)

 Nvals = [round(Int,length(dynDegsSam[i,1,1][:,1])/2) for i=1:size(dynDegsSam)[1]]
 Nsample = size(dynDegsSam)[2]

# Score autocorrelation for all TV parameters
groupsInds = [Int.(1:2N),Int.(ones(2N))];
 #groupsInds[2][indTvNodes] = 0
gasPar,~ = estimateTarg(modGasDirBin1;groupsInds = groupsInds)
tmpPar,~ = score_driven_filter_or_dgp(modGasDirBin1,array_2_vec_all_par(modGasDirBin1,gasPar),groupsInds=groupsInds)
sIO_T,gradIO_T = gasScoreSeries(modGasDirBin1,tmpPar;obsT = degsIO_T)
    tmp = [autocor(Float64.(sIO_T[i,:]),[1])[1] for i=1:2N]
    plot(tmp[indsTVnodes[indN,s,d]],".r")
    plot(tmp[.!indsTVnodes[indN,s,d]],".b")

groupsInds = [Int.(1:2N),Int.(zeros(2N))];
 groupsInds[2][indTvClust] = 1
gasPar,~ = estimateTarg(modGasDirBin1;groupsInds = groupsInds)
tmpPar,~ = score_driven_filter_or_dgp(modGasDirBin1,array_2_vec_all_par(modGasDirBin1,gasPar),groupsInds = groupsInds)
sIO_T,gradIO_T = gasScoreSeries(modGasDirBin1,tmpPar;obsT = degsIO_T)
    tmp = [autocor(Float64.(sIO_T[i,:]),[1])[1] for i=1:2N]
    plot(tmp[indsTVnodes[indN,s,d]],".r")
    plot(tmp[.!indsTVnodes[indN,s,d]],".b")

################## Compute score autororrelation on real data
using JLD2,Utilities,StaticNets,DynNets, Clustering
using PyCall; pygui(:qt); using PyPlot
halfPeriod = false
fold_Path =  "/home/Domenico/Dropbox/Dynamic_Networks/data/emid_data/juliaFiles/"
loadFilePartialName = "Weekly_eMid_Data_from_"
halfPeriod? periodEndStr =  "2012_03_12_to_2015_02_27.jld": periodEndStr =  "2009_06_22_to_2015_02_27.jld"
@load(fold_Path*loadFilePartialName*periodEndStr, AeMidWeekly_T,banksIDs,inactiveBanks, YeMidWeekly_T,weekInd,datesONeMid ,degsIO_T,strIO_T)

Ttrain = 100
matA_T = AeMidWeekly_T
N2,T = size(degsIO_T[:,1:Ttrain]);N = round(Int,N2/2)

# autocorrelation wrt constant parameters model
 close()
  groupsInds = [Int.(1:2N),Int.(ones(2N))];
  modGasDirBin1 = DynNets.SdErgmDirBin1(degsIO_T[:,1:Ttrain],[ zeros(2N) ,0.9  * ones(1), 0.01 * ones(1)],groupsInds,"FISHER-DIAG")
    statPar,~ = StaticNets.estimate((fooSdErgmDirBin1); degIO = meanSq(degsIO_T[:,1:Ttrain],2) )
    xOrder = 1:2N #maximum(degsIO_T[:,1:Ttrain],2) - minimum(degsIO_T[:,1:Ttrain],2)# mean(degsIO_T[:,1:Ttrain],2)#
    # Score autocorrelation for static parameters estimates
    sIO_T,gradIO_T = gasScoreSeries(modGasDirBin1,repmat(statPar,1,T);obsT = degsIO_T[:,1:Ttrain])
    tmp = [autocor(Float64.(sIO_T[i,:]),[1])[1] for i=1:2N]
    plot(xOrder,tmp,".k")
    indConstDegs = isnan(tmp)# falses(2N)#squeeze(std(degsIO_T[:,1:Ttrain],2).<=0.1,2)
    indNonConstDegs = .!indConstDegs
    plot(xOrder[indConstDegs],zeros(sum(indConstDegs)),"*k")
    grid()
    title("Score Autocorrelation emid, Train sample")

# clusters
maxNgroups = 1
 gasforeFitStore = Array{Array{Float64,2},1}(maxNgroups)
 gasParStore = Array{Array{Array{Float64,1},1},1}(maxNgroups)
 groupsIndsABStore = Array{Array{Float64,1},1}(maxNgroups)
 for Nclusters =1: maxNgroups
 #Nclusters =3
 totClustAssign = ones(Int,2N)
 if Nclusters > 1
 tmp1 = Array{Float64,2}(1,length(tmp) - sum(indConstDegs))
 figure()
    tmp1[1,:] = tmp[.!indConstDegs]
    clustTmp = Clustering.kmeans(tmp1,Nclusters)
    nodesClusterNumber = clustTmp.assignments
    constDegsClustInds = indmin(clustTmp.centers)
    for i=1:Nclusters
        inds = nodesClusterNumber .== i
        totClustAssign[find(indNonConstDegs)[inds]] = i
        plot(xOrder[indNonConstDegs][inds],tmp1[inds],".")
    end
    title("Score Autocorrelation WRT static model \n  divided in $(Nclusters) clusters")
 else
     constDegsClustInds = 1
     plot(xOrder,tmp,".")
     title("Score Autocorrelation WRT static model \n  divided in $(Nclusters) clusters")

 end
 groupsInds = [Int.(1:2N),totClustAssign];
 for i in find(indConstDegs)
     groupsInds[2][i] = constDegsClustInds
 end
 println( unique(groupsInds[2]) )
 groupsIndsABStore[Nclusters] = groupsInds[2]
 plot(xOrder[indConstDegs],zeros(sum(indConstDegs)),"*k")
 grid()

 figure()
 # Score autocorrelation for all TV parameters
 gasPar,~ = estimateTarg(modGasDirBin1;groupsInds = groupsInds)
    tmpPar,~ = score_driven_filter_or_dgp(modGasDirBin1,array_2_vec_all_par(modGasDirBin1,gasPar),groupsInds=groupsInds)
    sIO_T,gradIO_T = gasScoreSeries(modGasDirBin1,tmpPar;obsT = degsIO_T[:,1:Ttrain])
    tmp = [autocor(Float64.(sIO_T[i,:]),[1])[1] for i=1:2N]
    for i in (unique(groupsInds[2]))
        inds = groupsInds[2].==i
        plot(xOrder[inds],tmp[inds],".")
    end
    grid()
 gasParEstOnTrain = gasPar
    GasforeFit,~ = DynNets.score_driven_filter_or_dgp( DynNets.SdErgmDirBin1(degsIO_T),
            [gasParEstOnTrain[1];gasParEstOnTrain[2];gasParEstOnTrain[3]];groupsInds=groupsInds)
            gasforeFitStore[Nclusters] = Float64.(GasforeFit)
            gasParStore[Nclusters] = gasPar
 end

# Score autocorrelation for all TV parameters
# groupsInds = [Int.(1:2N),Int.(ones(2N))];
#  groupsInds[2][indConstDegs] = 0
#     gasPar,~ = estimateTarg(modGasDirBin1;groupsInds = groupsInds)
#     tmpPar,~ = score_driven_filter_or_dgp(modGasDirBin1,array_2_vec_all_par(modGasDirBin1,gasPar),groupsInds=groupsInds)
#     sIO_T,gradIO_T = gasScoreSeries(modGasDirBin1,tmpPar;obsT = degsIO_T[:,1:Ttrain])
#     tmp = [autocor(Float64.(sIO_T[i,:]),[1])[1] for i=1:2N]
#     plot(xOrder[indTvClust],tmp[indTvClust],".r")
#     plot(xOrder[.!indTvClust],tmp[.!indTvClust],".b")
#     gasParEstOnTrain = gasPar
#     GasforeFit,~ = DynNets.score_driven_filter_or_dgp( DynNets.SdErgmDirBin1(degsIO_T),
#             [gasParEstOnTrain[1];gasParEstOnTrain[2];gasParEstOnTrain[3]];groupsInds=groupsInds)
#             gasforeFit = Float64.(GasforeFit)

figure()
 #select links among largest banks in training sample
 remMat = squeeze(prod(.!matA_T,3),3)#falses(N,N)#
 sizeLeg = 15
 i = 1
 tmpTm1 =  StaticNets.nowCastEvalFitNet(  gasforeFitStore[i] ,matA_T,Ttrain;mat2rem = remMat,shift = 0)
    legTex = ["GAS $(i) group t-1 AUC = $(round(tmpTm1[3],3))"]
    # ROC for predictions from mean over Ttrain estimates
 for i=2:maxNgroups
     tmpTm1 =  StaticNets.nowCastEvalFitNet(  gasforeFitStore[i] ,matA_T,Ttrain;mat2rem = remMat,shift = 0)
        legTex = [legTex ; "GAS $(i) groups t-1 AUC = $(round(tmpTm1[3],3))"]
        legend(legTex)
 end

unique(groupsIndsABStore[4])
using GLM
degsIO_T = repmat(degsIO_T_store,20,1)
 N = round(Int,length(degsIO_T[:,1])/2)
 groupsInds = [Int.(1:2N),Int.(ones(2N))];
 modGasDirBin1 = DynNets.SdErgmDirBin1(degsIO_T[:,1:Ttrain],[ zeros(2N) ,0.9  * ones(1), 0.01 * ones(1)],groupsInds,"FISHER-DIAG")
 @time estimateTarg(modGasDirBin1)

targetErr=1e-5;identPost=false;identIter=false
      statPar = StaticNets.estimate(StaticNets.SnapSeqNetDirBin1(mean(degsIO_T,2)),targetErr = targetErr ,identPost=identPost,identIter= identIter)
     tmpPar = repmat(statPar,1,T)

s_T,grad_T = gasScoreSeries(modGasDirBin1,tmpPar;obsT = degsIO_T)
pval = zeros(2N)
for i=1:2N
 g_T_t = Float64.(grad_T[i,2:end])
 s_T_tm1 = Float64.(s_T[i,1:end-1])
 g_T_tm1 = Float64.(grad_T[i,1:end-1])
 g_delta_t = Float64.(grad_T[(1:2N).!=i,2:end])
 #I_T_t = Float64.(I_T[i,2:end])
 y = ones(T-1)
 ols = lm([   g_T_t  s_T_tm1.*g_T_t],y)
 yHat = predict(ols)
 yMean =1
 RSS = sum((yHat- yMean).^2)
 ESS = T - RSS
 pval[i] =  ccdf(Chisq(1), ESS)
end
plot(pval)
# aggiungere ai parametri statici anche i parametri statici dei parametri che
# sono gia stati battezzati TV.

figure()
 plot(tmp,pval,".")

#