text:
# ~/zjul/corona/wrld/jmh/jdfs.jl
# 200504 002
# 002 Glatter df_dcfm_100 Pga.problem med NaNs o jR0.jl
# Read dfs files and make diff dfs

using CSV, DataFrames, Plots
println("Reading data...")
df_00       = CSV.read("dfs/df_00.csv");

df_cfm      = CSV.read("dfs/df_cfm.csv");
df_cfm_100  = CSV.read("dfs/df_cfm_100.csv");
df_cfm_100m = CSV.read("dfs/df_cfm_100m.csv");

df_dth      = CSV.read("dfs/df_dth.csv");
df_dth_10  = CSV.read("dfs/df_dth_10.csv");
df_dth_10m = CSV.read("dfs/df_dth_10m.csv");

df_rcv      = CSV.read("dfs/df_rcv.csv");
df_rcv_30   = CSV.read("dfs/df_rcv_30.csv");
df_rcv_30m  = CSV.read("dfs/df_rcv_30m.csv");

df_R0    = CSV.read("dfs/df_R0.csv");
df_Pred  = CSV.read("dfs/df_Pred.csv");
df_Clow  = CSV.read("dfs/df_Clow.csv");
df_Chgh  = CSV.read("dfs/df_Chgh.csv");
df_Cint  = CSV.read("dfs/df_Cint.csv");

function showframes()
    println()
    println()
    println("DATAFRAMES AVAILABLE:")
    println()
    println("Confirmed Cases:");
    println("df_cfm        : Per Date");
    println("df_cfm_100    : Per Days since 100 cases");
    println("df_cfm_100m   : Per Days since 100 cases, Per Million Population");
    println("df_dcfm       : Change per Day");

    println()
    println("Deaths:");
    println("df_dth        : Per Date");
    println("df_dth_10     : Per Days since 10 cases");
    println("df_dth_10m    : Per Days since 10 cases, Per Million Population");
    println("df_ddth       : Change per Day");
    println()

    println("Recovered:");
    println("df_rcv        : Per Date");
    println("df_rcv_30     : Per Days since 30 cases");
    println("df_rcv_30m    : Per Days since 100 cases, Per Million Population");
    println("df_drcv       : Change per Day");
    println()
    println("R0Analysis:");
    println("df_R0         : Basisc Reproduction Number");
    println("df_Pred       : Epidemic ModelPrediction");
    println("df_Clow       : Confidence Intervall Low");
    println("df_CHgh       : Confidence Intervall High");
    println("df_Cint       : Confidence Intervall Tuple(Low,High)");
    println()
    println("showframes()  to show this overview")
    println()
end

showframes()

# CALCULATIONS Differntial Matrices
cfm=Matrix(df_cfm[:,2:end])
dcfm = diff(cfm, dims=1)
df_dcfm = DataFrame(dcfm, names(df_cfm)[2:end])
df_dcfm = hcat(df_00[2:end,:], df_dcfm)
CSV.write("dfs/df_dcfm.csv", df_dcfm)

cfm_100  = Matrix(df_cfm_100)
dcfm_100 = diff(cfm_100, dims=1)
# Glatter for ikke å få 0 som gir NaN i jR0.jl
# Fordeler neste verdi på 2 dager: (Antar ikke 2 dager med0 på rad)
# NB Må unngå brøktall som gir inacacterror i jR0.jl
# 1: Check if zero:
for i = 1:size(dcfm_100)[1]
    for j = 1:size(dcfm_100)[2]-1
        if !ismissing(dcfm_100[i,j])
            if dcfm_100[i,j] == 0.0 && !ismissing(dcfm_100[i+1,j])
                dcfm_100[i,j]   = 0.5*dcfm_100[i+1,j]÷1
                dcfm_100[i+1,j] = dcfm_100[i,j]+2*(dcfm_100[i+1,j]%1)
            end
         end
    end
end
# 1: Check if negativ: (Norway!)
for i = 1:size(dcfm_100)[1]
    for j = 1:size(dcfm_100)[2]-1
        if !ismissing(dcfm_100[i,j])
            if dcfm_100[i,j] < 0.0 && !ismissing(dcfm_100[i+1,j])
                dcfm_100[i,j]   = 0.5*(dcfm_100[i,j] + dcfm_100[i+1,j])÷1
                dcfm_100[i+1,j] = dcfm_100[i,j]
            end
         end
    end
end
df_dcfm_100 = DataFrame(dcfm_100, names(df_cfm)[2:end])
CSV.write("dfs/df_dcfm_100.csv", df_dcfm_100)

# Moving average:
n=5
dcfm_100mv= Array{Union{Missing, Float64}}(missing,size(dcfm_100)[1]-(n-1), size(dcfm_100)[2])
vsm(vs,n) = [sum(@view vs[i:(i+n-1)])/n for i in 1:(length(vs)-(n-1))]
for j in 1:size(dcfm_100)[2]
    dcfm_100mv[:,j] = vsm(dcfm_100[:,j],5).÷1
end
df_dcfm_100mv = DataFrame(dcfm_100mv, names(df_cfm)[2:end])
CSV.write("dfs/df_dcfm_100mv.csv", df_dcfm_100mv)

dth=Matrix(df_dth[:,2:end])
ddth = diff(dth, dims=1)
df_ddth = DataFrame(ddth, names(df_dth)[2:end])
df_ddth = hcat(df_00[2:end,:], df_ddth)
CSV.write("dfs/df_ddth.csv", df_ddth)

dth_10  = Matrix(df_dth_10)
ddth_10 = diff(dth_10, dims=1)
df_ddth_10 = DataFrame(ddth_10, names(df_cfm)[2:end])
CSV.write("dfs/df_ddth_10.csv", df_ddth_10)

rcv=Matrix(df_rcv[:,2:end])
drcv = diff(rcv, dims=1)
df_drcv = DataFrame(drcv, names(df_rcv)[2:end])
df_drcv = hcat(df_00[2:end,:], df_drcv)
CSV.write("dfs/df_drcv.csv", df_drcv)

rcv_30  = Matrix(df_rcv_30)
drcv_30 = diff(rcv_30, dims=1)
df_drcv_30 = DataFrame(drcv_30, names(df_cfm)[2:end])
CSV.write("dfs/df_drcv_30.csv", df_drcv_30)

# PLOTTING:
println("Plotting Daily Changes in Confirmed Cases")
for i in 1:size(dcfm,2)
    println(names(df_cfm)[i+1], " ...")
    bar(df_cfm[:,1],dcfm[:,i], xrotation=45, legend=:topleft,
         label = names(df_cfm)[i+1],
         title = "Corona 2020\nDaily Change in Confirmed Cases")
    savefig("figs3/dcfm_"*String(names(df_cfm)[i+1])*".png")
end

println("Plotting Daily Changes in Deaths")
for i in 1:size(ddth,2)
    println(names(df_dth)[i+1], " ...")
    bar(df_dth[:,1],ddth[:,i], xrotation=45, legend=:topleft,
         label = names(df_dth)[i+1],
         title = "Corona 2020\nDaily Change in Deaths")
    savefig("figs4/ddth_"*String(names(df_dth)[i+1])*".png")
end

println("Plotting Daily Changes in Recovered")
for i in 1:size(drcv,2)
    println(names(df_rcv)[i+1], " ...")
    bar(df_rcv[:,1],drcv[:,i], xrotation=45, legend=:topleft,
         label = names(df_rcv)[i+1],
         title = "Corona 2020\nDaily Change in Recovered")
    savefig("figs4/drcv_"*String(names(df_rcv)[i+1])*".png")
end

println("Plotting deaths per million for Norway and Sweden ...")
plot([dropmissing(df_dth_10m, :Norway).Norway,
      dropmissing(df_dth_10m, :Sweden).Sweden],
      legend=:outertopright,
      label = ["Norway" "Sweden"],
      ylabel = "Accumulated Deaths",
      xlabel = "Days since first 10 cases",
      title  = "Corona 2020\n Deaths per Million Population")
savefig("figs2/dth_10m_NoSe.png")

println("Plotting deaths per million for Belgium, Norway and Sweden ...")
plot([dropmissing(df_dth_10m, :Belgium).Belgium, dropmissing(df_dth_10m, :Norway).Norway,
      dropmissing(df_dth_10m, :Sweden).Sweden],
      legend=:outertopright,
      label = ["Belgium" "Norway" "Sweden"],
      ylabel = "Accumulated Deaths",
      xlabel = "Days since first 10 cases",
      title  = "Corona 2020\n Deaths per Million Population")
savefig("figs2/dth_10m_BeNoSe.png")

### WIP:
mR0 = Matrix(df_R0)
# mCint = Matrix(df_Cint)   # Got Strings???
# mClow = [x[1] for x in mCint]
# mChgh = [x[2] for x in mCint]

mClow = Matrix(df_Clow)
mChgh = Matrix(df_Chgh)
i = 4  # Norway
mRx = mR0[:,i]
mCl = mRx-mClow[:,i]
mCh = mChgh[:,i]-mRx
plot(mRx, ribbon=(mCl,mCh))

#
# plot([first.(mCint[:,4]),last.(mCint[:,4])])           # 4:Norway
# plot([[x[2] for x in mCint],[x[2] for x in mCint]])

showframes()

# EOF

max_stars_repo_name: dyrehaugen/jdt

max_issues_repo_name: dyrehaugen/jdt

max_forks_repo_name: dyrehaugen/jdt


text:
struct Grid

    r0 :: Vector{Float64}
    r1 :: Vector{Float64}
    points :: Matrix{Float64}
    Proj :: SparseMatrixCSC
    dr :: Float64
    Nk :: Int64
    _Nx :: Int64
    _Ny :: Int64
    _Nbuffer :: Int64
    _nan_outside_boundaries :: Matrix{Float64}

end

function Grid(M::Mirror, h::Float64, r0::Vector{Float64}, r1::Vector{Float64}, p::Int64; Nbuffer=100)

    deltaX = r1[1] - r0[1]
    deltaY = r1[2] - r0[2]

    if deltaX < deltaY
        Nx = 2^p
        dr = deltaX / Nx
        Ny = Int64(div(deltaY, dr))
    else
        Ny = 2^p
        dr = deltaY / Ny
        Nx = Int64(div(deltaX, dr))
    end

    # recalculate r1
    r1 = r0 + dr*[Nx, Ny]

    _Nx = Nx + 2*Nbuffer
    _Ny = Ny + 2*Nbuffer

    points = zeros(Float64, (2, Nx*Ny))
    proj_rows = Int32[i for i=1:Nx*Ny]
    proj_cols = zeros(Int32, Nx*Ny)
    proj_vals = ones(Int32, Nx*Ny)
    _nan_outside_boundaries = fill(NaN, (Nx, Ny))
    k = 0

    for j=1:Ny
        for i=1:Nx

            x = r0[1] + (i-1)*dr
            y = r0[2] + (j-1)*dr
            if distance_to_mirror(x, y, M)[1] > -h
                k += 1
                points[:,k] = [x, y]
                proj_cols[k] = i + _Nx*(j-1+Nbuffer) + Nbuffer
                _nan_outside_boundaries[i,j] = 1.0
            end

        end
    end

    Proj = sparse(proj_rows[1:k], proj_cols[1:k], proj_vals[1:k], k, _Nx*_Ny)
    return Grid(r0, r1, points[:,1:k], Proj, dr, k, _Nx, _Ny, Nbuffer, _nan_outside_boundaries)
end

function coarse_grid(grd::Grid)

    _, ks, _ = findnz(grd.Proj)

    _Nxc = Int64(ceil(grd._Nx/2))
    _Nyc = Int64(ceil(grd._Ny/2))
    Nbuffer = Int64(ceil(grd._Nbuffer/2))

    dr = 2*grd.dr
    if iseven(grd._Nbuffer)
        r0 = grd.r0
        nan_outside_boundaries = grd._nan_outside_boundaries[1:2:end,1:2:end]
    else
        r0 = grd.r0 + [1,1]*grd.dr
        nan_outside_boundaries = grd._nan_outside_boundaries[2:2:end,2:2:end]
    end
    Nxc, Nyc = size(nan_outside_boundaries)
    r1 = r0 + dr*[Nxc, Nyc]

    points = zeros(2, grd.Nk)
    projc_js = zeros(grd.Nk)
    Nkc = 0
    for k=1:grd.Nk
        kc = ks[k]
        j = Int(ceil(kc / grd._Nx))
        i = kc - (j - 1) * grd._Nx
        if isodd(i) && isodd(j)
            Nkc += 1
            points[:,Nkc] = grd.points[:,k]

            ic = (i + 1)/2
            jc = (j + 1)/2
            projc_js[Nkc] = ic + (jc-1)*_Nxc
        end
    end

    Projc = sparse([1:Nkc...], projc_js[1:Nkc], ones(Nkc), Nkc, _Nxc*_Nyc)
    return Grid(r0, r1, points[:,1:Nkc], Projc, dr, Nkc, _Nxc, _Nyc, Nbuffer, nan_outside_boundaries)
end

@recipe function f(v::Vector{Float64}, grd::Grid)

    vp_cart = transpose(grd.Proj) * v
    V = reshape(vp_cart, grd._Nx, grd._Ny)
    Vplot = transpose(V[grd._Nbuffer+1:grd._Nx-grd._Nbuffer, grd._Nbuffer+1:grd._Ny-grd._Nbuffer] .* grd._nan_outside_boundaries)

    Nx = grd._Nx - 2*grd._Nbuffer
    Ny = grd._Ny - 2*grd._Nbuffer
    x = LinRange(grd.r0[1], grd.r1[1], Nx)
    y = LinRange(grd.r0[2], grd.r1[2], Ny)

    xlims --> (x[1], x[end])
    ylims --> (y[1], y[end])
    size --> (1000, 1000)
    aspect_ratio --> :equal

    x, y, Vplot
end

@recipe function f(v::Vector{Float64}, grd::Grid, z::Int64)

    vp = reshape(v, grd.Nk, :)[:,z]
    vp_cart = transpose(grd.Proj) * vp
    V = reshape(vp_cart, grd._Nx, grd._Ny)
    Vplot = transpose(V[grd._Nbuffer+1:grd._Nx-grd._Nbuffer, grd._Nbuffer+1:grd._Ny-grd._Nbuffer] .* grd._nan_outside_boundaries)

    Nx = grd._Nx - 2*grd._Nbuffer
    Ny = grd._Ny - 2*grd._Nbuffer
    x = LinRange(grd.r0[1], grd.r1[1], Nx)
    y = LinRange(grd.r0[2], grd.r1[2], Ny)

    xlims --> (x[1], x[end])
    ylims --> (y[1], y[end])
    size --> (1000, 1000)
    aspect_ratio --> :equal

    x, y, Vplot
end

function function_to_grid(f::Function, grd::Grid)

    return Float64[f(grd.points[:,k]...) for k=1:grd.Nk]
end

function operator_to_grid(O::Function, grd::Grid)

    return grd.Proj * O() * transpose(grd.Proj)
end

ext: jl


text:
export add_Hopf!
export Hopf_variables
export replace_Hopf_variable!

"Add a Hopf bifurcation to the system."
function add_Hopf!(eom::DifferentialEquation, Δω::Num)
    for var in get_variables(eom), ω in eom.harmonics[var]
        add_harmonic!(eom, var, ω + Δω)
        add_harmonic!(eom, var, ω - Δω)
    end
end

"Successively adds n Hopf bifurcations at the same frequency Δω"
add_Hopf!(eom::DifferentialEquation; frequency::Num, multiplicity::Int) = [add_Hopf!(eom, frequency) for k in 1:multiplicity]

"""
    Hopf_variables(eom, freq)
"""
Hopf_variables(eom::HarmonicEquation, freq::Num) = filter(x -> any(isequal.(freq, get_all_terms(x.ω))), eom.variables)

function replace_Hopf_variable!(eom::HarmonicEquation, freq::Num)
    pair_to_change = Hopf_variables(eom, freq)[1] # eliminate of the Cartesian variables, it does not matter from which VDP pair
    to_eliminate = pair_to_change.symbols[2]
    rules = Dict(freq => HarmonicBalance.declare_variable(string(freq), first(get_independent_variables(eom))), to_eliminate => Num(0))
    eom.equations = expand_derivatives.(substitute_all(eom.equations, rules))
    eom.parameters = setdiff(eom.parameters, [freq]) # freq is now NOT a parameter
    eom.variables = setdiff(eom.variables, [pair_to_change])
    new_variable = HarmonicBalance.declare_variable(string(freq))
    eom.variables = cat(eom.variables, _VDP_Hopf(pair_to_change, to_eliminate, new_variable), dims=1)
end

function replace_Hopf_variable(eom::HarmonicEquation, freq::Num)
    new_eom = deepcopy(eom)
    replace_Hopf_variable!(new_eom, freq)
    new_eom
end

function _VDP_Hopf(old::HarmonicVariable, eliminated::Num, new_sym::Num)
    new_VDP = deepcopy(old)
    idx = findall(x-> isequal(x, eliminated), old.symbols)[1]
    indep = Num(first(arguments(eliminated.val)))
    new_VDP.symbols[idx] = HarmonicBalance.declare_variable(string(new_sym), indep)
    new_VDP.types[idx] = "Hopf"
    new_VDP.names[new_sym] = string(new_sym)
    delete!(new_VDP.names, Num(var_name(eliminated)))
    return new_VDP
end


text:
# This file is auto-generated by AWSMetadata.jl
using AWS
using AWS.AWSServices: sso_admin
using AWS.Compat
using AWS.UUIDs
"""
    AttachManagedPolicyToPermissionSet()

Attaches an IAM managed policy ARN to a permission set.  If the permission set is already referenced by one or more account assignments, you will need to call  ProvisionPermissionSet  after this action to apply the corresponding IAM policy updates to all assigned accounts.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `ManagedPolicyArn`: The IAM managed policy ARN to be attached to a permission set.
- `PermissionSetArn`: The ARN of the PermissionSet that the managed policy should be attached to.

"""

attach_managed_policy_to_permission_set(InstanceArn, ManagedPolicyArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("AttachManagedPolicyToPermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "ManagedPolicyArn"=>ManagedPolicyArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
attach_managed_policy_to_permission_set(InstanceArn, ManagedPolicyArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("AttachManagedPolicyToPermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "ManagedPolicyArn"=>ManagedPolicyArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)

"""
    CreateAccountAssignment()

Assigns access to a principal for a specified AWS account using a specified permission set.  The term principal here refers to a user or group that is defined in AWS SSO.   As part of a successful CreateAccountAssignment call, the specified permission set will automatically be provisioned to the account in the form of an IAM policy attached to the SSO-created IAM role. If the permission set is subsequently updated, the corresponding IAM policies attached to roles in your accounts will not be updated automatically. In this case, you will need to call  ProvisionPermissionSet  to make these updates.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the permission set that the admin wants to grant the principal access to.
- `PrincipalId`: An identifier for an object in AWS SSO, such as a user or group. PrincipalIds are GUIDs (For example, f81d4fae-7dec-11d0-a765-00a0c91e6bf6). For more information about PrincipalIds in AWS SSO, see the AWS SSO Identity Store API Reference.
- `PrincipalType`: The entity type for which the assignment will be created.
- `TargetId`: TargetID is an AWS account identifier, typically a 10-12 digit string (For example, 123456789012).
- `TargetType`: The entity type for which the assignment will be created.

"""

create_account_assignment(InstanceArn, PermissionSetArn, PrincipalId, PrincipalType, TargetId, TargetType; aws_config::AWSConfig=global_aws_config()) = sso_admin("CreateAccountAssignment", Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn, "PrincipalId"=>PrincipalId, "PrincipalType"=>PrincipalType, "TargetId"=>TargetId, "TargetType"=>TargetType); aws_config=aws_config)
create_account_assignment(InstanceArn, PermissionSetArn, PrincipalId, PrincipalType, TargetId, TargetType, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("CreateAccountAssignment", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn, "PrincipalId"=>PrincipalId, "PrincipalType"=>PrincipalType, "TargetId"=>TargetId, "TargetType"=>TargetType), args)); aws_config=aws_config)

"""
    CreatePermissionSet()

Creates a permission set within a specified SSO instance.  To grant users and groups access to AWS account resources, use  CreateAccountAssignment .

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `Name`: The name of the PermissionSet.

# Optional Parameters
- `Description`: The description of the PermissionSet.
- `RelayState`: Used to redirect users within the application during the federation authentication process.
- `SessionDuration`: The length of time that the application user sessions are valid in the ISO-8601 standard.
- `Tags`: The tags to attach to the new PermissionSet.
"""

create_permission_set(InstanceArn, Name; aws_config::AWSConfig=global_aws_config()) = sso_admin("CreatePermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "Name"=>Name); aws_config=aws_config)
create_permission_set(InstanceArn, Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("CreatePermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "Name"=>Name), args)); aws_config=aws_config)

"""
    DeleteAccountAssignment()

Deletes a principal's access from a specified AWS account using a specified permission set.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the permission set that will be used to remove access.
- `PrincipalId`: An identifier for an object in AWS SSO, such as a user or group. PrincipalIds are GUIDs (For example, f81d4fae-7dec-11d0-a765-00a0c91e6bf6). For more information about PrincipalIds in AWS SSO, see the AWS SSO Identity Store API Reference.
- `PrincipalType`: The entity type for which the assignment will be deleted.
- `TargetId`: TargetID is an AWS account identifier, typically a 10-12 digit string (For example, 123456789012).
- `TargetType`: The entity type for which the assignment will be deleted.

"""

delete_account_assignment(InstanceArn, PermissionSetArn, PrincipalId, PrincipalType, TargetId, TargetType; aws_config::AWSConfig=global_aws_config()) = sso_admin("DeleteAccountAssignment", Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn, "PrincipalId"=>PrincipalId, "PrincipalType"=>PrincipalType, "TargetId"=>TargetId, "TargetType"=>TargetType); aws_config=aws_config)
delete_account_assignment(InstanceArn, PermissionSetArn, PrincipalId, PrincipalType, TargetId, TargetType, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("DeleteAccountAssignment", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn, "PrincipalId"=>PrincipalId, "PrincipalType"=>PrincipalType, "TargetId"=>TargetId, "TargetType"=>TargetType), args)); aws_config=aws_config)

"""
    DeleteInlinePolicyFromPermissionSet()

Deletes the inline policy from a specified permission set.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the permission set that will be used to remove access.

"""

delete_inline_policy_from_permission_set(InstanceArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("DeleteInlinePolicyFromPermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
delete_inline_policy_from_permission_set(InstanceArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("DeleteInlinePolicyFromPermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)

"""
    DeletePermissionSet()

Deletes the specified permission set.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the permission set that should be deleted.

"""

delete_permission_set(InstanceArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("DeletePermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
delete_permission_set(InstanceArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("DeletePermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)

"""
    DescribeAccountAssignmentCreationStatus()

Describes the status of the assignment creation request.

# Required Parameters
- `AccountAssignmentCreationRequestId`: The identifier that is used to track the request operation progress.
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.

"""

describe_account_assignment_creation_status(AccountAssignmentCreationRequestId, InstanceArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("DescribeAccountAssignmentCreationStatus", Dict{String, Any}("AccountAssignmentCreationRequestId"=>AccountAssignmentCreationRequestId, "InstanceArn"=>InstanceArn); aws_config=aws_config)
describe_account_assignment_creation_status(AccountAssignmentCreationRequestId, InstanceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("DescribeAccountAssignmentCreationStatus", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AccountAssignmentCreationRequestId"=>AccountAssignmentCreationRequestId, "InstanceArn"=>InstanceArn), args)); aws_config=aws_config)

"""
    DescribeAccountAssignmentDeletionStatus()

Describes the status of the assignment deletion request.

# Required Parameters
- `AccountAssignmentDeletionRequestId`: The identifier that is used to track the request operation progress.
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.

"""

describe_account_assignment_deletion_status(AccountAssignmentDeletionRequestId, InstanceArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("DescribeAccountAssignmentDeletionStatus", Dict{String, Any}("AccountAssignmentDeletionRequestId"=>AccountAssignmentDeletionRequestId, "InstanceArn"=>InstanceArn); aws_config=aws_config)
describe_account_assignment_deletion_status(AccountAssignmentDeletionRequestId, InstanceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("DescribeAccountAssignmentDeletionStatus", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AccountAssignmentDeletionRequestId"=>AccountAssignmentDeletionRequestId, "InstanceArn"=>InstanceArn), args)); aws_config=aws_config)

"""
    DescribePermissionSet()

Gets the details of the permission set.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the permission set.

"""

describe_permission_set(InstanceArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("DescribePermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
describe_permission_set(InstanceArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("DescribePermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)

"""
    DescribePermissionSetProvisioningStatus()

Describes the status for the given permission set provisioning request.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `ProvisionPermissionSetRequestId`: The identifier that is provided by the ProvisionPermissionSet call to retrieve the current status of the provisioning workflow.

"""

describe_permission_set_provisioning_status(InstanceArn, ProvisionPermissionSetRequestId; aws_config::AWSConfig=global_aws_config()) = sso_admin("DescribePermissionSetProvisioningStatus", Dict{String, Any}("InstanceArn"=>InstanceArn, "ProvisionPermissionSetRequestId"=>ProvisionPermissionSetRequestId); aws_config=aws_config)
describe_permission_set_provisioning_status(InstanceArn, ProvisionPermissionSetRequestId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("DescribePermissionSetProvisioningStatus", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "ProvisionPermissionSetRequestId"=>ProvisionPermissionSetRequestId), args)); aws_config=aws_config)

"""
    DetachManagedPolicyFromPermissionSet()

Detaches the attached IAM managed policy ARN from the specified permission set.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `ManagedPolicyArn`: The IAM managed policy ARN to be attached to a permission set.
- `PermissionSetArn`: The ARN of the PermissionSet from which the policy should be detached.

"""

detach_managed_policy_from_permission_set(InstanceArn, ManagedPolicyArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("DetachManagedPolicyFromPermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "ManagedPolicyArn"=>ManagedPolicyArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
detach_managed_policy_from_permission_set(InstanceArn, ManagedPolicyArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("DetachManagedPolicyFromPermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "ManagedPolicyArn"=>ManagedPolicyArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)

"""
    GetInlinePolicyForPermissionSet()

Obtains the inline policy assigned to the permission set.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the permission set.

"""

get_inline_policy_for_permission_set(InstanceArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("GetInlinePolicyForPermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
get_inline_policy_for_permission_set(InstanceArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("GetInlinePolicyForPermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)

"""
    ListAccountAssignmentCreationStatus()

Lists the status of the AWS account assignment creation requests for a specified SSO instance.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.

# Optional Parameters
- `Filter`: Filters results based on the passed attribute value.
- `MaxResults`: The maximum number of results to display for the assignment.
- `NextToken`: The pagination token for the list API. Initially the value is null. Use the output of previous API calls to make subsequent calls.
"""

list_account_assignment_creation_status(InstanceArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListAccountAssignmentCreationStatus", Dict{String, Any}("InstanceArn"=>InstanceArn); aws_config=aws_config)
list_account_assignment_creation_status(InstanceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListAccountAssignmentCreationStatus", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn), args)); aws_config=aws_config)

"""
    ListAccountAssignmentDeletionStatus()

Lists the status of the AWS account assignment deletion requests for a specified SSO instance.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.

# Optional Parameters
- `Filter`: Filters results based on the passed attribute value.
- `MaxResults`: The maximum number of results to display for the assignment.
- `NextToken`: The pagination token for the list API. Initially the value is null. Use the output of previous API calls to make subsequent calls.
"""

list_account_assignment_deletion_status(InstanceArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListAccountAssignmentDeletionStatus", Dict{String, Any}("InstanceArn"=>InstanceArn); aws_config=aws_config)
list_account_assignment_deletion_status(InstanceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListAccountAssignmentDeletionStatus", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn), args)); aws_config=aws_config)

"""
    ListAccountAssignments()

Lists the assignee of the specified AWS account with the specified permission set.

# Required Parameters
- `AccountId`: The identifier of the AWS account from which to list the assignments.
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the permission set from which to list assignments.

# Optional Parameters
- `MaxResults`: The maximum number of results to display for the assignment.
- `NextToken`: The pagination token for the list API. Initially the value is null. Use the output of previous API calls to make subsequent calls.
"""

list_account_assignments(AccountId, InstanceArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListAccountAssignments", Dict{String, Any}("AccountId"=>AccountId, "InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
list_account_assignments(AccountId, InstanceArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListAccountAssignments", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AccountId"=>AccountId, "InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)

"""
    ListAccountsForProvisionedPermissionSet()

Lists all the AWS accounts where the specified permission set is provisioned.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the PermissionSet from which the associated AWS accounts will be listed.

# Optional Parameters
- `MaxResults`: The maximum number of results to display for the PermissionSet.
- `NextToken`: The pagination token for the list API. Initially the value is null. Use the output of previous API calls to make subsequent calls.
- `ProvisioningStatus`: The permission set provisioning status for an AWS account.
"""

list_accounts_for_provisioned_permission_set(InstanceArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListAccountsForProvisionedPermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
list_accounts_for_provisioned_permission_set(InstanceArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListAccountsForProvisionedPermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)

"""
    ListInstances()

Lists the SSO instances that the caller has access to.

# Optional Parameters
- `MaxResults`: The maximum number of results to display for the instance.
- `NextToken`: The pagination token for the list API. Initially the value is null. Use the output of previous API calls to make subsequent calls.
"""

list_instances(; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListInstances"; aws_config=aws_config)
list_instances(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListInstances", args; aws_config=aws_config)

"""
    ListManagedPoliciesInPermissionSet()

Lists the IAM managed policy that is attached to a specified permission set.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the PermissionSet whose managed policies will be listed.

# Optional Parameters
- `MaxResults`: The maximum number of results to display for the PermissionSet.
- `NextToken`: The pagination token for the list API. Initially the value is null. Use the output of previous API calls to make subsequent calls.
"""

list_managed_policies_in_permission_set(InstanceArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListManagedPoliciesInPermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
list_managed_policies_in_permission_set(InstanceArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListManagedPoliciesInPermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)

"""
    ListPermissionSetProvisioningStatus()

Lists the status of the permission set provisioning requests for a specified SSO instance.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.

# Optional Parameters
- `Filter`: Filters results based on the passed attribute value.
- `MaxResults`: The maximum number of results to display for the assignment.
- `NextToken`: The pagination token for the list API. Initially the value is null. Use the output of previous API calls to make subsequent calls.
"""

list_permission_set_provisioning_status(InstanceArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListPermissionSetProvisioningStatus", Dict{String, Any}("InstanceArn"=>InstanceArn); aws_config=aws_config)
list_permission_set_provisioning_status(InstanceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListPermissionSetProvisioningStatus", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn), args)); aws_config=aws_config)

"""
    ListPermissionSets()

Lists the PermissionSets in an SSO instance.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.

# Optional Parameters
- `MaxResults`: The maximum number of results to display for the assignment.
- `NextToken`: The pagination token for the list API. Initially the value is null. Use the output of previous API calls to make subsequent calls.
"""

list_permission_sets(InstanceArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListPermissionSets", Dict{String, Any}("InstanceArn"=>InstanceArn); aws_config=aws_config)
list_permission_sets(InstanceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListPermissionSets", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn), args)); aws_config=aws_config)

"""
    ListPermissionSetsProvisionedToAccount()

Lists all the permission sets that are provisioned to a specified AWS account.

# Required Parameters
- `AccountId`: The identifier of the AWS account from which to list the assignments.
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.

# Optional Parameters
- `MaxResults`: The maximum number of results to display for the assignment.
- `NextToken`: The pagination token for the list API. Initially the value is null. Use the output of previous API calls to make subsequent calls.
- `ProvisioningStatus`: The status object for the permission set provisioning operation.
"""

list_permission_sets_provisioned_to_account(AccountId, InstanceArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListPermissionSetsProvisionedToAccount", Dict{String, Any}("AccountId"=>AccountId, "InstanceArn"=>InstanceArn); aws_config=aws_config)
list_permission_sets_provisioned_to_account(AccountId, InstanceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListPermissionSetsProvisionedToAccount", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AccountId"=>AccountId, "InstanceArn"=>InstanceArn), args)); aws_config=aws_config)

"""
    ListTagsForResource()

Lists the tags that are attached to a specified resource.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `ResourceArn`: The ARN of the resource with the tags to be listed.

# Optional Parameters
- `NextToken`: The pagination token for the list API. Initially the value is null. Use the output of previous API calls to make subsequent calls.
"""

list_tags_for_resource(InstanceArn, ResourceArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListTagsForResource", Dict{String, Any}("InstanceArn"=>InstanceArn, "ResourceArn"=>ResourceArn); aws_config=aws_config)
list_tags_for_resource(InstanceArn, ResourceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ListTagsForResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "ResourceArn"=>ResourceArn), args)); aws_config=aws_config)

"""
    ProvisionPermissionSet()

The process by which a specified permission set is provisioned to the specified target.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the permission set.
- `TargetType`: The entity type for which the assignment will be created.

# Optional Parameters
- `TargetId`: TargetID is an AWS account identifier, typically a 10-12 digit string (For example, 123456789012).
"""

provision_permission_set(InstanceArn, PermissionSetArn, TargetType; aws_config::AWSConfig=global_aws_config()) = sso_admin("ProvisionPermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn, "TargetType"=>TargetType); aws_config=aws_config)
provision_permission_set(InstanceArn, PermissionSetArn, TargetType, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("ProvisionPermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn, "TargetType"=>TargetType), args)); aws_config=aws_config)

"""
    PutInlinePolicyToPermissionSet()

Attaches an IAM inline policy to a permission set.  If the permission set is already referenced by one or more account assignments, you will need to call  ProvisionPermissionSet  after this action to apply the corresponding IAM policy updates to all assigned accounts.

# Required Parameters
- `InlinePolicy`: The IAM inline policy to attach to a PermissionSet.
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the permission set.

"""

put_inline_policy_to_permission_set(InlinePolicy, InstanceArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("PutInlinePolicyToPermissionSet", Dict{String, Any}("InlinePolicy"=>InlinePolicy, "InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
put_inline_policy_to_permission_set(InlinePolicy, InstanceArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("PutInlinePolicyToPermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InlinePolicy"=>InlinePolicy, "InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)

"""
    TagResource()

Associates a set of tags with a specified resource.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `ResourceArn`: The ARN of the resource with the tags to be listed.
- `Tags`: A set of key-value pairs that are used to manage the resource.

"""

tag_resource(InstanceArn, ResourceArn, Tags; aws_config::AWSConfig=global_aws_config()) = sso_admin("TagResource", Dict{String, Any}("InstanceArn"=>InstanceArn, "ResourceArn"=>ResourceArn, "Tags"=>Tags); aws_config=aws_config)
tag_resource(InstanceArn, ResourceArn, Tags, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("TagResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "ResourceArn"=>ResourceArn, "Tags"=>Tags), args)); aws_config=aws_config)

"""
    UntagResource()

Disassociates a set of tags from a specified resource.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `ResourceArn`: The ARN of the resource with the tags to be listed.
- `TagKeys`: The keys of tags that are attached to the resource.

"""

untag_resource(InstanceArn, ResourceArn, TagKeys; aws_config::AWSConfig=global_aws_config()) = sso_admin("UntagResource", Dict{String, Any}("InstanceArn"=>InstanceArn, "ResourceArn"=>ResourceArn, "TagKeys"=>TagKeys); aws_config=aws_config)
untag_resource(InstanceArn, ResourceArn, TagKeys, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("UntagResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "ResourceArn"=>ResourceArn, "TagKeys"=>TagKeys), args)); aws_config=aws_config)

"""
    UpdatePermissionSet()

Updates an existing permission set.

# Required Parameters
- `InstanceArn`: The ARN of the SSO instance under which the operation will be executed. For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference.
- `PermissionSetArn`: The ARN of the permission set.

# Optional Parameters
- `Description`: The description of the PermissionSet.
- `RelayState`: Used to redirect users within the application during the federation authentication process.
- `SessionDuration`: The length of time that the application user sessions are valid for in the ISO-8601 standard.
"""

update_permission_set(InstanceArn, PermissionSetArn; aws_config::AWSConfig=global_aws_config()) = sso_admin("UpdatePermissionSet", Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn); aws_config=aws_config)
update_permission_set(InstanceArn, PermissionSetArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = sso_admin("UpdatePermissionSet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceArn"=>InstanceArn, "PermissionSetArn"=>PermissionSetArn), args)); aws_config=aws_config)


text:
# Autogenerated wrapper script for Conduit_jll for i686-linux-gnu-cxx03
export libconduit, libconduit_blueprint, libconduit_relay

JLLWrappers.@generate_wrapper_header("Conduit")
JLLWrappers.@declare_library_product(libconduit, "libconduit.so")
JLLWrappers.@declare_library_product(libconduit_blueprint, "libconduit_blueprint.so")
JLLWrappers.@declare_library_product(libconduit_relay, "libconduit_relay.so")
function __init__()
    JLLWrappers.@generate_init_header()
    JLLWrappers.@init_library_product(
        libconduit,
        "lib/libconduit.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@init_library_product(
        libconduit_blueprint,
        "lib/libconduit_blueprint.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@init_library_product(
        libconduit_relay,
        "lib/libconduit_relay.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
# private interface

"""
    isgaussian(dist)

Check if distribution `dist` is a Gaussian distribution.
"""
isgaussian(dist) = false
isgaussian(::Type{<:Distributions.Normal}) = true
isgaussian(::Type{<:Distributions.NormalCanon}) = true
isgaussian(::Type{<:Distributions.AbstractMvNormal}) = true

"""
    prior(model)

Return the prior distribution of the `model`.
"""
function prior(::AbstractMCMC.AbstractModel) end

"""
    initial_sample(rng, model)

Return the initial sample for the `model` using the random number generator `rng`.

By default, sample from [`prior(model)`](@ref).
"""
function initial_sample(rng::Random.AbstractRNG, model::AbstractMCMC.AbstractModel)
    return Random.rand(rng, prior(model))
end

"""
    proposal(prior, f, ν, θ)

Compute the proposal for the next sample in the elliptical slice sampling algorithm.

Mathematically, the proposal can be computed as
```math
f \\cos θ + ν \\sin θ + μ (1 - (\\sin θ + \\cos θ)),
```
where ``μ`` is the mean of the Gaussian `prior`, `f` is the previous sample, and `ν` is a
sample from the Gaussian `prior`.

See also: [`proposal!`](@ref)
"""
function proposal(prior, f, ν, θ)
    sinθ, cosθ = sincos(θ)
    a = 1 - (sinθ + cosθ)
    μ = Statistics.mean(prior)
    return @. cosθ * f + sinθ * ν + a * μ
end

"""
    proposal!(out, model, f, ν, θ)

Compute the proposal for the next sample in the elliptical slice sampling algorithm, and
save it to `out`.

Mathematically, the proposal can be computed as
```math
f \\cos θ + ν \\sin θ + μ (1 - (\\sin θ + \\cos θ)),
```
where ``μ`` is the mean of the Gaussian `prior`, `f` is the previous sample, and `ν` is a
sample from the Gaussian `prior`.

See also: [`proposal`](@ref)
"""
function proposal!(out, prior, f, ν, θ)
    sinθ, cosθ = sincos(θ)
    a = 1 - (sinθ + cosθ)
    μ = Statistics.mean(prior)
    @. out = cosθ * f + sinθ * ν + a * μ
    return out
end


text:
module DoubleDouble

export Double, Single
import Base:
    convert,
    *, +, -, /, sqrt, <,
    rem, abs, rand, promote_rule,
    show, big

abstract AbstractDouble{T} <: Real

# a Single is a wrapper for an ordinary floating point type such that arithmetic operations will return Doubles
immutable Single{T<:AbstractFloat} <: AbstractDouble{T}
    hi::T
end

# In a Double, hi uses the full mantissa, and abs(lo) <= 0.5eps(hi)
immutable Double{T<:AbstractFloat} <: AbstractDouble{T}
    hi::T
    lo::T

    # "Normalise" Doubles to ensure abs(lo) <= 0.5eps(hi)
    # assumes abs(u) > abs(v): if not, use Single + Single
    function Double(u::T, v::T)
        w = u + v
        new(w, (u-w) + v)
    end
end

# constructors
Double{T<:AbstractFloat}(u::T, v::T) = Double{T}(u, v)
Double{T<:AbstractFloat}(x::T) = Double(x, zero(T))

const half64 = 1.34217729e8
const half32 = 4097f0
const half16 = Float16(33.0)
const halfBig = 3.402823669209384634633746074317682114570000000000000000000000000000000000000000e+38
# 6.805647338418769269267492148635364229120000000000000000000000000000000000000000e38

# round floats to half-precision
# TODO: fix overflow for large values
halfprec(x::Float64) = (p = x*half64; (x-p)+p) # signif(x,26,2) for 26 is 6.7108865e7, this seems like 27
halfprec(x::Float32) = (p = x*half32; (x-p)+p) # float32(signif(x,12,2))
halfprec(x::Float16) = (p = x*half16; (x-p)+p) # float16(signif(x,5,2))
halfprec(x::BigFloat) = (p = x*halfBig; (x-p)+p) # BigFloat(signif(x,128,2))

function splitprec(x::AbstractFloat)
    h = halfprec(x)
    h, x-h
end

# ones(T::Double, dims...) = fill!(Array(T, dims...), (one)(T))
# zeros(T::Double, dims...) = fill!(Array(T, dims...), (zero)(T))

## promotion
promote_rule{T<:AbstractFloat}(::Type{Double{T}}, ::Type{Int64}) = Double{T}

## conversion

convert{T<:AbstractFloat}(::Type{Single{T}}, x::T) = Single(x)
convert{T<:AbstractFloat}(::Type{Double{T}}, x::T) = Double(x)

convert{T<:AbstractFloat}(::Type{Double{T}}, x::Single{T}) = Double(x.hi)
convert{T<:AbstractFloat}(::Type{Single{T}}, x::Double{T}) = Single(x.hi)

convert{T<:AbstractFloat}(::Type{T}, x::AbstractDouble{T}) = x.hi

convert{T<:AbstractFloat}(::Type{Single{T}}, x::Single{T}) = x # needed because Double <: FloatingPoint
convert{T<:AbstractFloat}(::Type{Double{T}}, x::Double{T}) = x # needed because Double <: FloatingPoint

convert{T<:AbstractFloat}(::Type{Single{T}}, x::AbstractFloat) = Single(convert(T,x))

function convert{T<:AbstractFloat}(::Type{Double{T}}, x::AbstractFloat)
    z = convert(T, x)
    Double(z, convert(T, x-z))
end

convert{T<:AbstractFloat}(::Type{Double{T}}, x::Irrational) = convert(Double{T}, big(x))

convert(::Type{BigFloat}, x::Single) = big(x.hi)
convert(::Type{BigFloat}, x::Double) = big(x.hi) + big(x.lo)

convert{T}(::Type{Single{T}}, x::Integer) = convert(Single{T}, T(x))
convert{T}(::Type{Double{T}}, x::Integer) = convert(Double{T}, T(x))

promote_rule{T<:AbstractFloat}(::Type{Single{T}}, ::Type{T}) = Single{T}
promote_rule{T<:AbstractFloat}(::Type{Double{T}}, ::Type{T}) = Double{T}
promote_rule{T<:AbstractFloat}(::Type{Double{T}}, ::Type{Single{T}}) = Double{T}

# promote_rule{T<:AbstractFloat}(::Type{AbstractDouble{T}}, ::Type{BigFloat}) = BigFloat  !!
promote_rule{s,T<:AbstractFloat}(::Type{Irrational{s}}, ::Type{Single{T}}) = Double{Float64}

Single(x::Real) = convert(Single{Float64}, Float64(x))

Double(x::Real) = convert(Double{Float64}, Float64(x))
Double(x::BigFloat) = convert(Double{Float64}, x)
Double(x::Irrational) = convert(Double{Float64}, x)

# <

function <{T}(x::Double{T}, y::Double{T})
    x.hi + x.lo < y.hi + y.lo
end

# add12
function +{T}(x::Single{T},y::Single{T})
    abs(x.hi) > abs(y.hi) ? Double(x.hi, y.hi) : Double(y.hi, x.hi)
end

# Dekker add2
function +{T}(x::Double{T}, y::Double{T})
    r = x.hi + y.hi
    s = abs(x.hi) > abs(y.hi) ? (((x.hi - r) + y.hi) + y.lo) + x.lo : (((y.hi - r) + x.hi) + x.lo) + y.lo
    Double(r, s)
end

# add122
function +{T}(x::Single{T}, y::Double{T})
    r = x.hi + y.hi
    s = abs(x.hi) > abs(y.hi) ? ((x.hi - r) + y.hi) + y.lo : ((y.hi - r) + x.hi) + y.lo
    Double(r, s)
end
+{T}(x::Double{T}, y::Single{T}) = y + x

-{T<:AbstractFloat}(x::Double{T}) = Double(-x.hi, -x.lo)

function -{T}(x::Double{T}, y::Double{T})
    r = x.hi - y.hi
    s = abs(x.hi) > abs(y.hi) ? (((x.hi - r) - y.hi) - y.lo) + x.lo : (((-y.hi - r) + x.hi) + x.lo) - y.lo
    Double(r, s)
end

# Dekker mul12
function *{T}(x::Single{T},y::Single{T})
    hx,lx = splitprec(x.hi)
    hy,ly = splitprec(y.hi)
    z = x.hi*y.hi
    Double(z, ((hx*hy-z) + hx*ly + lx*hy) + lx*ly)
end

# Dekker mul2
function *{T}(x::Double{T}, y::Double{T})
    c = Single(x.hi) * Single(y.hi)
    cc = (x.hi * y.lo + x.lo* y.hi) + c.lo
    Double(c.hi, cc)
end

# Dekker div2
function /{T}(x::Double{T}, y::Double{T})
    c = x.hi / y.hi
    u = Single(c) * Single(y.hi)
    cc = ((((x.hi - u.hi) - u.lo) + x.lo) - c*y.lo)/y.hi
    Double(c, cc)
end

# Dekker sqrt2
function sqrt{T}(x::Double{T})
    if x.hi <= 0
        throw(DomainError("sqrt will only return a complex result if called with a complex argument."))
    end
    c = sqrt(x.hi)
    u = Single(c)*Single(c)
    cc = (((x.hi - u.hi) - u.lo) + x.lo)*map(typeof(x.hi),0.5)/c
    Double(c, cc)
end

rem{T}(x::Double{T},d::Real) = Double(rem(x.hi,d), rem(x.lo,d))
abs{T}(x::Double{T})=x.hi>0 ?x:-x

# random numbers using full Uint64 range (respectively, UInt32, UInt16 and UInt128)
function rand(::Type{Double{Float64}})
    u = rand(UInt64)
    f = Float64(u)
    uf = UInt64(f)
    ur = uf > u ? uf-u : u-uf
    Double(5.421010862427522e-20*f, 5.421010862427522e-20*Float64(ur))
end

function rand(::Type{Double{Float32}})
    u = rand(UInt32)
    f = Float32(u)
    uf = UInt32(f)
    ur = uf > u ? uf-u : u-uf
    Double(2.3283064f-10*f, 2.3283064f-10*Float32(ur))
end

function rand(::Type{Double{Float16}})
    u = rand(UInt16)
    f = Float16(u)
    uf = UInt16(f)
    ur = uf > u ? uf-u : u-uf
    Double(Float16(1.526e-5)*f, Float16(1.526e-5)*Float16(ur))
end

function rand(::Type{Double{BigFloat}})
    u = rand(UInt128)
    f = BigFloat(u)
    uf = UInt128(f)
    ur = uf > u ? uf-u : u-uf
    Double(2.938735877055718769921841343055614194546663891930218803771879265696043148636818e-39*f, 2.938735877055718769921841343055614194546663891930218803771879265696043148636818e-39*BigFloat(ur))
end

# calculate constants from big numbers
macro twofloat_const_frombig(sym)
    esym = esc(sym)
    qsym = esc(Expr(:quote, sym))
    bigval = @eval big($sym)
    quote
        convert(::Type{Double{Float64}}, ::Irrational{$qsym}) = $(convert(Double{Float64}, bigval))
        convert(::Type{Double{Float32}}, ::Irrational{$qsym}) = $(convert(Double{Float32}, bigval))
        convert(::Type{Double{Float16}}, ::Irrational{$qsym}) = $(convert(Double{Float16}, bigval))
        convert(::Type{Double{BigFloat}}, ::Irrational{$qsym}) = $(convert(Double{BigFloat}, bigval))
    end
end

@twofloat_const_frombig π
@twofloat_const_frombig e
@twofloat_const_frombig γ
@twofloat_const_frombig catalan
@twofloat_const_frombig φ

big(x::Double) = BigFloat(x)

function show(io::IO, x::Double)
    println(io, "Double(", x.hi, ", ", x.lo, ")")
    print(io, " - value: ")
    @printf io "%.32g" convert(BigFloat, x)  # crude approximation to valid number of digits
end

end #module


text:
module GaussianProcesses

using Optim, PDMats, ElasticPDMats, ElasticArrays, Distances, FastGaussQuadrature, RecipesBase, Distributions, ProgressMeter
using StaticArrays
using StatsFuns, SpecialFunctions

using LinearAlgebra, Printf, Random, Statistics
import Statistics: mean, cov
import Base: size
import PDMats: dim, Matrix, diag, pdadd!, *, \, inv, logdet, eigmax, eigmin, whiten!, unwhiten!, quad, quad!, invquad, invquad!, X_A_Xt, Xt_A_X, X_invA_Xt, Xt_invA_X

# Functions that should be available to package
# users should be explicitly exported here
export GPBase, GP, GPE, GPA, ElasticGPE, Approx, predict_f, predict_y, Kernel, Likelihood, CompositeKernel, SumKernel, ProdKernel, Masked, FixedKernel, fix, Noise, Const, SE, SEIso, SEArd, Periodic, Poly, RQ, RQIso, RQArd, Lin, LinIso, LinArd, Matern, Mat12Iso, Mat12Ard, Mat32Iso, Mat32Ard, Mat52Iso, Mat52Ard, #kernel functions
    MeanZero, MeanConst, MeanLin, MeanPoly, SumMean, ProdMean, MeanPeriodic, #mean functions
    GaussLik, BernLik, ExpLik, StuTLik, PoisLik, BinLik,       #likelihood functions
    mcmc, ess, lss, optimize!, vi, var_exp, dv_var_exp, elbo, initialise_Q,    #inference functions
    set_priors!,set_params!, update_target!, autodiff, update_Q!, noise_variance
using ForwardDiff: GradientConfig, Dual, partials, copyto!, Chunk
import ForwardDiff: seed!

const φ = normpdf
const Φ = normcdf
const invΦ = norminvcdf

# all package code should be included here
include("means/means.jl")
include("kernels/kernels.jl")
include("likelihoods/likelihoods.jl")
include("common.jl")
include("utils.jl")
include("chol_utils.jl")
include("GP.jl")
include("GPE.jl")
include("GPEelastic.jl")
include("GPA.jl")
include("vi.jl")
include("mcmc.jl")
include("optimize.jl")
include("crossvalidation.jl")
include("plot.jl")
include("sparse/sparseGP.jl")

# ScikitLearnBase, which is a skeleton package.
include("ScikitLearn.jl")

end # module


text:
using Knet

# sample usage:
# m128 = MLP([3644,128,1])
# mlprun(data; model=m128, epochs=20)

# define a model type with weights and optimization params so we can
# use the Adam optimizer which works faster than SGD:

type MLP
    weights
    oparams
    function MLP(sizes; optimizer=Adam, winit=0.1, atype=Array{Float32})
        m = new(Any[],Any[])
        for i=2:length(sizes)
            w = convert(atype,winit*randn(sizes[i],sizes[i-1]))
            b = convert(atype,zeros(sizes[i],1))
            push!(m.weights, w)
            push!(m.oparams, optimizer(w))
            push!(m.weights, b)
            push!(m.oparams, optimizer(b))
        end
        return m
    end
end

# y = mlppred(model.weights, x)

function mlppred(w,x)
    for i=1:2:length(w)-2
        x = max(0, w[i]*x .+ w[i+1])
    end
    return w[end-1]*x .+ w[end]
end

# this is the logistic loss

mlploss(w,x,y) = mean(log(1 .+ exp(-y .* mlppred(w,x))))

mlpgrad = grad(mlploss)

# training loop, does one pass over data, modifies mlp in place

function train!(m::MLP, data)
    for (x,y) in data
        dw = mlpgrad(m.weights, x, y)
        for i in 1:length(m.weights)
            (m.weights[i],m.oparams[i]) = update!(m.weights[i], dw[i], m.oparams[i])
        end
    end
end

# returns logistic loss for model on data

function test(m::MLP, data)
    sumloss = numloss = 0
    for (x,y) in data
        sumloss += mlploss(m.weights, x, y)
        numloss += 1
    end
    sumloss / numloss
end

# returns classification accuracy for model on data

function acc(m::MLP, data)
    sumloss = numloss = 0
    for (x,y) in data
        z = mlppred(m.weights,x)
        sumloss += mean((z .* y) .> 0)
        numloss += 1
    end
    sumloss / numloss
end

# sample use script

function mlprun(data; epochs=10, sizes=[3644,128,1], model=MLP(sizes; atype = typeof(data[1][1][1])))
    msg(e) = println((e,map(d->acc(model,d),data)...,map(d->test(model,d),data)...)); msg(0)
    for epoch = 1:epochs
        train!(model, data[1])
        msg(epoch)
    end
    return model
end

# missing in Knet:
Base.mean(a::KnetArray) = sum(a)/length(a)
Base.mean(a::AutoGrad.Rec) = sum(a)/length(a)

# to convert models:

function cpu2gpu(m::MLP)
    g = deepcopy(m)
    for i=1:length(g.weights)
        g.weights[i] = KnetArray(g.weights[i])
        g.oparams[i].fstm = KnetArray(g.oparams[i].fstm)
        g.oparams[i].scndm = KnetArray(g.oparams[i].scndm)
    end
    return g
end

max_stars_repo_name: JuliaTagBot/melseg

max_issues_repo_name: JuliaTagBot/melseg

max_forks_repo_name: JuliaTagBot/melseg


text:
module TestInstall

using Test
using IonBase
using IonBase.InstallCmd
using IonBase.Options

include(joinpath(pkgdir(IonBase), "test", "utils.jl"))

with_test_ion() do
    @testset "find_julia_installer_info" begin
        version, _, _ = InstallCmd.find_julia_installer_info("stable")
        @test version <= v"2.0.0"
        version, _, _ = InstallCmd.find_julia_installer_info("nightly")
        @test version == "nightly"
        version, _, _ = InstallCmd.find_julia_installer_info("1.5.3")
        @test version == v"1.5.3"
        version, _, _ = InstallCmd.find_julia_installer_info("1.4")
        @test version == v"1.4.2"
    end

    @testset "test real installation" begin
        IonBase.install("julia", "stable";yes=true, cache=true)
        IonBase.install("julia", "nightly"; yes=true, cache=true)
        IonBase.install("julia", "latest"; yes=true, cache=true)
        # make sure 1.5.3 is installed
        # for later testing
        IonBase.install("julia", "1.5.3"; yes=true, cache=true)
        IonBase.install("julia", "1.4.2"; yes=true, cache=true)

        ion = Options.read()
        @test ion.julia.active === ion.julia.versions[v"1.4.2"]
        @test ion.julia.nightly !== nothing
        @test ion.julia.stable === v"1.5.3"
    end
end

end


text:
"""
    Acrobot{T}

A double-pendulum with actuation only at the elbow joint. It has 4 states and 1 control.

# Constructor
    Acrobot(; kwargs...)

with keyword arguments:
* `l` - `SVector{2,T}` of link lengths
* `m` - `SVector{2,T}` of link masses
* `J` - `SVector{2,T}` of link inertias
"""
@with_kw struct Acrobot{T} <: AbstractModel
    l::SVector{2,T} = @SVector [1.0, 1.0]
    m::SVector{2,T} = @SVector [1.0, 1.0]
    J::SVector{2,T} = @SVector [1.0, 1.0]
end

function dynamics(model::Acrobot, x, u)
    g = 9.81
    m1,m2 = model.m
    l1,l2 = model.l
    J1,J2 = model.J
    θ1,    θ2    = x[1], x[2]
    θ1dot, θ2dot = x[3], x[4]
    s1,c1 = sincos(θ1)
    s2,c2 = sincos(θ2)
    c12 = cos(θ1 + θ2)

    # mass matrix
    m11 = m1*l1^2 + J1 + m2*(l1^2 + l2^2 + 2*l1*l2*c2) + J2
    m12 = m2*(l2^2 + l1*l2*c2 + J2)
    m22 = l2^2*m2 + J2
    M = @SMatrix [m11 m12; m12 m22]

    # bias term
    tmp = l1*l2*m2*s2
    b1 = -(2 * θ1dot * θ2dot + θ2dot^2)*tmp
    b2 = tmp * θ1dot^2
    B = @SVector [b1, b2]

    # friction
    c = 1.0
    C = @SVector [c*θ1dot, c*θ2dot]

    # gravity term
    g1 = ((m1 + m2)*l2*c1 + m2*l2*c12) * g
    g2 = m2*l2*c12*g
    G = @SVector [g1, g2]

    # equations of motion
    τ = @SVector [0, u[1]]
    θddot = M\(τ - B - G - C)
    return @SVector [θ1dot, θ2dot, θddot[1], θddot[2]]
end

RobotDynamics.state_dim(::Acrobot) = 4
RobotDynamics.control_dim(::Acrobot) = 1


text:
module Test_Dynamic_Pendulum_zAxis

using  Modia3D
import Modia3D.ModiaMath

# Solids
groundMaterial = Modia3D.Material(color="DarkGreen", transparency=0.5)
# massProperties = Modia3D.MassProperties()
vmat1 = Modia3D.Material(color="LightBlue" , transparency=0.5)
vmat2 = Modia3D.Material(color="Red")

@assembly Bar(;Lx = 0.1, Ly=Lx/5, Lz=Ly, m=1.0) begin
   frame0 = Modia3D.Object3D(Modia3D.Solid(Modia3D.SolidBeam(Lx,Ly,Lz), Modia3D.MassProperties(m=m), vmat1))
   frame1 = Modia3D.Object3D(frame0; r=[-Lx/2, 0.0, 0.0])
   frame2 = Modia3D.Object3D(frame0; r=[ Lx/2, 0.0, 0.0])
   cyl    = Modia3D.Cylinder(Ly/2,1.2*Ly; material=vmat2)
   cyl1   = Modia3D.Object3D(frame1, cyl; visualizeFrame=false)
   cyl2   = Modia3D.Object3D(frame2, cyl; visualizeFrame=false)
end

@assembly DoublePendulum(;Lx = 1.0, m=1.0) begin
   world = Modia3D.Object3D(Modia3D.CoordinateSystem(0.5*Lx))
   bar1  = Bar(Lx=Lx, m=m)
   bar2  = Bar(Lx=Lx, m=m)
   rev1  = Modia3D.Revolute(world, bar1.frame1; axis = 3)
   rev2  = Modia3D.Revolute(bar1.frame2, bar2.frame1; axis = 3)
end

# Modia3D.visualizeAssembly!( DoublePendulum(), Modia3D.SceneOptions(visualizeFrames=true, defaultFrameLength=0.3) )

gravField = Modia3D.UniformGravityField(n=[0,-1,0])
doublePendulum = DoublePendulum(sceneOptions=Modia3D.SceneOptions(gravityField=gravField,visualizeFrames=true, defaultFrameLength=0.3))
model = Modia3D.SimulationModel( doublePendulum )
result = ModiaMath.simulate!(model; stopTime=5.0, tolerance=1e-6,interval=0.001, log=false)

ModiaMath.plot(result, [("rev1.phi", "rev2.phi"),
                        ("rev1.w"  , "rev2.w"),
                        ("rev1.a"  , "rev2.a")])

println("... success of Test_Dynamic_Pendulum_zAxis.jl!")
end


text:
"""
    univariatecalibrationrecipe(rmodel::UnivariateCalibration, X, Y;
                                            decimals = 3, text_location = :topleft)

Plots the calibration trend line of a UnivariateCalibration object given an input `X` and ground-truth `Y`.
"""
@recipe function univariatecalibrationrecipe(rmodel::UnivariateCalibration, X, Y;
                                            decimals = 3, text_location = :topleft)
    Yhat = rmodel.(X)
    seriestype := :scatter
    title := "Univariate Regression Plot"
    xlabel := Symbol("Fitted Values")
    ylabel := Symbol("Residuals")
    label := "Actual Values"
    @series y := (X, Y)
    seriestype := :straightline
    label := "Trend-Line"
    slope, bias, Rsq = string.( round.( [ rmodel.Slope, rmodel.Offset, rmodel.Rsq ], digits = decimals ) )
    @series begin
        annotation := (text_location, "y = " * slope * " x + " * bias * "\n R2 = " * Rsq )
        y := ( [0, 1], [rmodel.Offset, rmodel.Offset + rmodel.Slope])
    end
end

"""
    standard_addition_recipe(rmodel::StandardAddition, X, Y;
                                            decimals = 3, text_location = :topleft)

Plots a trend line of a StandardAddition object given an input `X` and ground-truth `Y`.
"""
@recipe function standard_addition_recipe(rmodel::StandardAddition, X, Y;
                                            decimals = 3, text_location = :topleft)
    seriestype := :scatter
    legend := :bottomright
    title := "Standard Addition Plot"
    xlabel := Symbol("Spike")
    ylabel := Symbol("Response")
    label := "Experiment"
    @series y := (X, Y)
    seriestype := :straightline
    label := "Trend-Line"
    slope, bias, Rsq = string.( round.( [ rmodel.Slope, rmodel.Offset, rmodel.Rsq ], digits = decimals ) )
    @series begin
        y := ( [0, 1], [rmodel.Offset, rmodel.Offset + rmodel.Slope])
    end
    seriestype := :scatter
    label := "Unknown"
    @series y := ( [ rmodel.Unknown ], [ 0 ] )
    seriestype := :hline
    label := ""
    color := :black
    @series y := [ 0 ]
    seriestype := :vline
    label := ""
    color := :black
    @series begin
        annotation := (text_location, "y = " * slope * " x + " * bias * "\n R2 = " * Rsq )
        x := [ X[1] ]
    end
end

"""
    residualsplotrecipe(rmodel::ChemometricsTools.RegressionModels, X, Y)

Plots the residuals of a RegressionModel object given an input `X` and ground-truth `Y`.
"""
@recipe function residualsplotrecipe(rmodel::ChemometricsTools.RegressionModels, X, Y)
    Yhat = rmodel(X)
    seriestype := :scatter
    title := "Residual vs Fitted Values Plot"
    xlabel := Symbol("Fitted Values")
    ylabel := Symbol("Residuals")
    @series y := (Yhat .- Y, Yhat)
end

struct QQ
    StoredTuple::Tuple
end

"""
    QQ( Y1, Y2; Quantiles = collect( 1 : 99 ) ./ 100 )

Returns a plotable object of a Quantile-Quantile plot between vectors `Y1` and `Y2` at the desired `Quantiles`.
"""
function QQ( Y1, Y2; Quantiles = collect( 1 : 99 ) ./ 100 )
    return QQ( (Statistics.quantile!(Y1, Quantiles), Statistics.quantile!(Y2, Quantiles) ))
end

"""
    quantilequantile(qq::QQ)

Plots a Quantile-Quantile plot.
"""
@recipe function quantilequantile(qq::QQ)
    m = sum( diff( qq.StoredTuple[ 1 ] ) ) / sum( diff( qq.StoredTuple[ 2 ] ) )
    int = qq.StoredTuple[2][2] - (m * qq.StoredTuple[1][2])

    seriestype := :scatter
    title := "Quantile-Quantile Plot"
    xlabel := Symbol("Quantile 1")
    ylabel := Symbol("Quantile 2")
    @series y := qq.StoredTuple

    seriestype := :straightline
    label := "Trend-Line"
    @series y := ([0, 1], [int, int + m])
end

struct BlandAltman
    means::Array{Float64, 1}
    differences::Array{Float64, 1}
    UpperLimit::Float64
    Center::Float64
    LowerLimit::Float64
    Outliers::Array{Float64}
end

"""
    BlandAltman(Y1, Y2; Confidence = 1.96)

Returns a Plottable object of a Bland-Altman plot between vectors `Y1` and `Y2` with a confidence limit of `Confidence`.
"""
function BlandAltman(Y1, Y2; Confidence = 1.96)
    means = (Y1 .+ Y2) ./ 2.0
    diffs = Y2 .- Y1
    MeanofDiffs = StatsBase.mean( diffs )
    StdofDiffs = StatsBase.std( diffs )

    UpperLimit = MeanofDiffs + Confidence * StdofDiffs
    Center = MeanofDiffs
    LowerLimit = MeanofDiffs - Confidence * StdofDiffs
    #To:Do Add trend-line....
    Outliers = findall( (diffs .> MeanofDiffs + Confidence*StdofDiffs) )
    Outliers = vcat(Outliers, findall( diffs .< MeanofDiffs - Confidence*StdofDiffs ) )
    return BlandAltman( means, diffs, UpperLimit, Center, LowerLimit, Outliers )
end

"""
    blandaltman(BA::BlandAltman)

Plots a Bland-Altman plot.
"""
@recipe function blandaltman(BA::BlandAltman)
    seriestype := :scatter
    title := "Bland Altman"
    xlabel := Symbol("Means")
    ylabel := Symbol("Differences")
    @series y := ( BA.means, BA.differences )
    seriestype := :straightline
    color := :red
    @series y := ([0, 1], [BA.UpperLimit, BA.UpperLimit])
    seriestype := :straightline
    color := :red
    @series y := ([0, 1], [BA.Center, BA.Center])
    seriestype := :straightline
    color := :red
    @series y := ([0, 1], [BA.LowerLimit, BA.LowerLimit])
end

#rectangle(w, h, x, y) = Shape(x .+ [0,w,w,0], y .+ [0,0,h,h])

"""
    IntervalOverlay(Spectra, Intervals, Err)

Creates a Plottable object to display the relative error(`Err`) of each `interval` ontop of a `Spectra`.
"""
struct IntervalOverlay
    Spectra
    Intervals
    Err
end

"""
    intervaloverlay(IO::IntervalOverlay)

Plots a barchart overlay over a spectra according to an `IntervalOverlay` object.
"""
@recipe function intervaloverlay(IO::IntervalOverlay)
    RelativeErr = IO.Err ./ sum(IO.Err);

    seriestype := :path
    title := "Spectral Error Overlay"
    xlabel := Symbol("Bins")
    ylabel := Symbol("Absorbance / Relative CV Error")
    legend := false
    @series y := IO.Spectra'

    seriestype := :shape
    opacity := 0.5
    for (i, line) in enumerate( IO.Intervals )
        scalethis = reduce(max, IO.Spectra)  / reduce(max, RelativeErr)
        w = line[end] - line[1]
        h = RelativeErr[i] * scalethis
        xloc = line[1]
        #@series y := rectangle(w,h,xloc,0)
        #seriestype := :shape
        @series ( xloc .+ [ 0, w, w, 0 ], [ 0, 0, h, h ] )
    end
end

"""
    PCA/LDA(::Union{PCA, LDA}; Axis = [1,2])

Plots scores of `PCA`/`LDA` object using the defined `Axis'`.
"""
@recipe function f(DA::Union{PCA, LDA}; Axis = [1,2])
    @assert(length(Axis) == 2, "Axis for PCA/LDA plot must be of length 2." )
    exvar = round.(ExplainedVariance(DA) .* 10000) /100
    seriestype := :scatter
    if isa(DA, PCA)
        title := "PCA Scores Plot"
        xlabel := "PCA $(Axis[1]) [$(exvar[Axis[1]]) %]"
        ylabel := "PCA $(Axis[2]) [$(exvar[Axis[2]]) %]"
    else
        title := "LDA Scores Plot"
        xlabel := "DA $(Axis[1]) [$(exvar[Axis[1]]) %]"
        ylabel := "DA $(Axis[2]) [$(exvar[Axis[2]]) %]"
    end
    @series y := ( DA.Scores[:,Axis[2]], DA.Scores[:,Axis[1]] )
end

"""
    DiscriminantAnalysisPlot(DA, GD, YHot, LblEncoding, UnlabeledData,
                                Axis = [1,2], Confidence = 0.90)

An object to hold all the information needed to plot a discriminant analysis.
`DA` = `LDA`/`PCA` object
`GD` = `GuassianDiscriminant` object
`YHot` = One hot encoded y vectors
`LblEncoding` = a `ClassificationLabel` object
`UnlabeledData` = data that does not have a known label (see where it falls in the plot).
`Axis` = principal or discriminant axis' to display
`Confidence` = Significance value from 0-1 for the confidence ellipses.
"""
struct DAPlot
    DA
    GD
    YHot
    LblEncoding
    UnlabeledData
    Axis
    Confidence
end

DiscriminantAnalysisPlot(DA, GD, YHot, LblEncoding, UnlabeledData;
                    Axis = [1,2], Confidence = 0.90) = DAPlot( DA, GD, YHot,
                    LblEncoding, UnlabeledData, Axis, Confidence)

"""
    discrimanalyplot(dap::DAPlot)

Plots two DA axis, with ellipsoids according to a `DiscriminantAnalysisPlot` object.
"""
@recipe function discrimanalyplot(dap::DAPlot)
    exvar = round.(ExplainedVariance(dap.DA) .* 10000) /100
    @assert all(dap.Axis .<= size(dap.UnlabeledData)[2])
    A = []
    Classes = size(dap.YHot)[2]
    colors = get_color_palette(:auto, plot_color(:white), Classes)
    for c in 1:Classes
        #Labelled data
        whichrows = dap.YHot[:,c] .== 1.0
        seriestype := :scatter
        color := colors[c]
        label := dap.LblEncoding.ToCold[c]
        @series y := ( dap.DA.Scores[whichrows,dap.Axis[1]], dap.DA.Scores[whichrows,dap.Axis[2]] )
        #Make confidence ellipse
        elipse = ConfidenceEllipse(dap.GD.ProjectedClassCovariances[c], dap.GD.ProjectedClassMeans[c,:],
                    dap.Confidence, dap.Axis; pointestimate = 180 );

        seriestype := :path
        color := :black
        linestyle := :dash
        linewidth := 2
        label := ""
        @series y := (elipse[:,1], elipse[:,2])
    end
    #New Data
    seriestype := :scatter
    color := :black
    markershape = :star
    label := ""
    legend := :topleft
    xlabel := "DA $(dap.Axis[1]) [$(exvar[dap.Axis[1]]) %]"
    ylabel := "DA $(dap.Axis[2]) [$(exvar[dap.Axis[2]]) %]"
    @series y := ( dap.UnlabeledData[:,dap.Axis[1]] , dap.UnlabeledData[:,dap.Axis[2]] )
end


text:
module FHIRClientXML

import Base64
import HTTP
import XMLDict

include("types.jl")

include("credentials.jl")
include("headers.jl")
include("requests.jl")

end # module


text:
@testset "Codegen" begin
    @testset "monomial_product" begin
        @test SP.monomial_product(Float64, [2, 3, 1], :(c[5]))[1] == :(c[5] * (x[1] * x[1]) * (x[2] * x[2] * x[2]) * x[3])
        #
        #
        @test SP.monomial_product(Float64, [2, 3, 1], :(c[5]), 2)[1] == :((3 * c[5] * (x[1] * x[1]) * (x[2] * x[2])) * x[3])

        # optimizations
        # no ^1
        @test SP.monomial_product(Float64, [1, 3, 1], :(c[5]))[1] == :(c[5] * x[1] * (x[2] * x[2] * x[2]) * x[3])
        # omit ^0
        @test SP.monomial_product(Float64, [1, 0, 1], :(c[5]))[1] == :(c[5] * x[1] * x[3])
        @test SP.monomial_product(Float64, [0, 0, 0], :(c[5]))[1] == :(c[5])
        # omit 1 * and ^0
        @test SP.monomial_product(Float64, [1, 3, 2], :(c[5]), 1)[1] == :(c[5] * (x[2] * x[2] * x[2]) * (x[3] * x[3]))
        # omit ^1 in derivative
        @test SP.monomial_product(Float64, [2, 2, 2], :(c[5]), 2)[1] == :((2 * c[5] * (x[1] * x[1]) * x[2]) * (x[3] * x[3]))
    end

    @testset "evaluate_codegen low_level" begin
        E = [ 4  4  1  3  5
              2  4  2  2  5
              0  1  2  2  2 ]
        degrees, subs = SP.degrees_submatrices(E)
        @test length(degrees) == 3
        @test degrees == [0, 1, 2]

        degrees2, subs2 = SP.degrees_submatrices(subs[3])
        @test subs2 == [[1 3], reshape([5], 1, 1)]
        @test degrees2 == [2, 5]

        @test SP.pow(:x, 0) == :(one(x))
    end

    @testset "evalpoly_deriv" begin
        z = rand(Complex{Float64})
        tol = 1e-12
        for T in [Float64, Complex{Float64}]
            c0, c1, c2, c3, c4, c5 = rand(T, 6)

            true_val = c0 + c1 * z + c2 * z^2 + c3 * z^3 + c4 * z^4 + c5 * z^5
            true_dval = c1 + 2c2 * z + 3c3 * z^2 + 4c4 * z^3 + 5c5 * z^4
            val, dval = SP.@goertzel_deriv z c0 c1 c2 c3 c4 c5
            @test abs(val - true_val) < tol
            @test abs(dval - true_dval) < tol
            val, dval = SP.@horner_deriv z c0 c1 c2 c3 c4 c5
            @test abs(val - true_val) < tol
            @test abs(dval - true_dval) < tol
            val, dval = SP.@evalpoly_derivative z c0 c1 c2 c3 c4 c5
            @test abs(val - true_val) < tol
            @test abs(dval - true_dval) < tol

            true_val = c0 + c1 * z + c2 * z^2
            true_dval = c1 + 2c2 * z
            val, dval = SP.@goertzel_deriv z c0 c1 c2
            @test abs(val - true_val) < tol
            @test abs(dval - true_dval) < tol
            val, dval = SP.@horner_deriv z c0 c1 c2
            @test abs(val - true_val) < tol
            @test abs(dval - true_dval) < tol

            true_val = c0 + c1 * z
            true_dval = c1
            val, dval = SP.@goertzel_deriv z c0 c1
            @test abs(val - true_val) < tol
            @test abs(dval - true_dval) < tol
            val, dval = SP.@horner_deriv z c0 c1
            @test abs(val - true_val) < tol
            @test abs(dval - true_dval) < tol
        end
    end

    @testset "gradient_codegen" begin
          # bugfix
          @polyvar a b t z
          f = -0.25a^5*t+0.25b^5*t+0.5z^6
          g = Polynomial(f)
          x = rand(4)
          vars = [a, b, t, z]
          @test map(v -> (MP.differentiate(f, v))(vars=>x), vars) ≈ gradient(g, x)
    end

end


text:
using Gadfly, DataFrames, Dates

set_default_plot_size(6inch, 3inch)

a = collect(Date("2013-01-01"):Day(1):Date("2014-01-01"))
b = collect(Date("2012-01-01"):Day(1):Date("2016-01-01"))
ya = sin.(0.01 * Float64.(Dates.value.(a)))
yb = cos.(0.01 * Float64.(Dates.value.(b)))

df1 = DataFrame(
    x = a,
    y = ya,
    label = "first"
)

df2 = DataFrame(
    x = b,
    y = yb,
    label = "second"
)

df = vcat(df1, df2)

plot(df, x = :x, y = :y, color=:label, Geom.line)


text:
"""
	grdblend(cmd0::String="", arg1=[], arg2=[], kwargs...)

Reads a listing of grid files and blend parameters, or up to 2 GTMgrid types, and creates
a grid by blending the other grids using cosine-taper weights.

Full option list at [`grdblend`](http://gmt.soest.hawaii.edu/doc/latest/grdblend.html)

Parameters
----------

- **I** : **inc** : -- Str or Number --

    *x_inc* [and optionally *y_inc*] is the grid spacing.
    [`-I`](http://gmt.soest.hawaii.edu/doc/latest/grdblend.html#i)
- $(GMT.opt_R)
- **G** : **outgrid** : -- Str --

    Output grid file name. Note that this is optional and to be used only when saving
    the result directly on disk. Otherwise, just use the G = grdblend(....) form.
    [`-G`](http://gmt.soest.hawaii.edu/doc/latest/grdblend.html#g)

- **C** : **clobber** : -- Str or [] --      Flags = f|l|o|u[±]

    Clobber mode: Instead of blending, simply pick the value of one of the grids that covers a node.
    [`-C`](http://gmt.soest.hawaii.edu/doc/latest/grdproject.html#c)
- **N** : **nodata** : -- Str or Number --

    No data. Set nodes with no input grid to this value [Default is NaN].
	[`-N`](http://gmt.soest.hawaii.edu/doc/latest/grdblend.html#n)
- **Q** : **headless** : -- Bool or [] --

    Create plain header-less grid file (for use with external tools). Requires that the output
    grid file is a native format (i.e., not netCDF). DO NOT USE WITH **G**.
	[`-Q`](http://gmt.soest.hawaii.edu/doc/latest/grdblend.html#q)
- **W** : **no_blend** : -- Str or [] --

    Do not blend, just output the weights used for each node [Default makes the blend].
    Append ``z`` to write the weight*z sum instead.
	[`-W`](http://gmt.soest.hawaii.edu/doc/latest/grdblend.html#w)
- **Z** : **scale** : -- Number --

    Scale output values by scale before writing to file.
	[`-Z`](http://gmt.soest.hawaii.edu/doc/latest/grdblend.html#z)
- $(GMT.opt_V)
- $(GMT.opt_f)
- $(GMT.opt_n)
- $(GMT.opt_r)
"""
function grdblend(cmd0::String="", arg1=[], arg2=[]; kwargs...)

	d = KW(kwargs)
	cmd, = parse_R("", d)
	cmd  = parse_V_params(cmd, d)
	cmd, = parse_f(cmd, d)
	cmd, = parse_n(cmd, d)
	cmd, = parse_r(cmd, d)

	cmd = add_opt(cmd, 'C', d, [:C :clobber])
	cmd = add_opt(cmd, 'G', d, [:G :outgrid])
    cmd = add_opt(cmd, 'I', d, [:I :inc])
	cmd = add_opt(cmd, 'N', d, [:N :nodata])
	cmd = add_opt(cmd, 'Q', d, [:Q :headless])
	cmd = add_opt(cmd, 'W', d, [:W :no_blend])
	cmd = add_opt(cmd, 'Z', d, [:Z :scale])

	cmd, got_fname, arg1, arg2 = find_data(d, cmd0, cmd, 2, arg1, arg2)
	return common_grd(d, cmd, got_fname, 2, "grdblend", arg1, arg2)		# Finish build cmd and run it
end

# ---------------------------------------------------------------------------------------------------
grdblend(arg1=[], arg2=[], cmd0::String=""; kw...) = grdblend(cmd0, arg1, arg2; kw...)


text:
# Highly inspired from https://github.com/tejank10/Flux-baselines/blob/master/baselines/dqn/duel-dqn.jl
struct DuelingNetwork
    base::Chain
    val::Chain
    adv::Chain
end

function (m::DuelingNetwork)(inpt)
    x = m.base(inpt)
    return m.val(x) .+ m.adv(x) .- mean(m.adv(x), dims=1)
end

Flux.@functor DuelingNetwork

function Flux.reset!(m::DuelingNetwork)
    Flux.reset!(m.base)
end

function Base.iterate(m::DuelingNetwork, i=1)
    if i > length(m.base.layers) + length(m.val.layers) + length(m.adv.layers)
        return nothing
    end
    if i <= length(m.base.layers)
        return (m.base[i], i+1)
    elseif i <= length(m.base.layers) + length(m.val.layers)
        return (m.val[i - length(m.base.layers)], i+1)
    elseif i <= length(m.base.layers) + length(m.val.layers) + length(m.adv.layers)
        return (m.adv[i - length(m.base.layers) - length(m.val.layers)], i+1)
    end
end

function Base.deepcopy(m::DuelingNetwork)
  DuelingNetwork(deepcopy(m.base), deepcopy(m.val), deepcopy(m.adv))
end

function create_dueling_network(m::Chain)
    duel_layer = -1
    for i=1:length(m.layers)
        l = m[end-i+1]
        if !isa(l, Dense)
            duel_layer = length(m.layers)-i+1
            break
        elseif i == length(m.layers)
            duel_layer = 0
        end
    end
    error_str = "DeepQLearningError: the qnetwork provided is incompatible with dueling"
    duel_layer == -1 ? throw(error_str) : nothing
    for l in m[duel_layer+1:end]
        @assert isa(l, Dense) error_str
    end
    nlayers = length(m.layers)
    _, last_layer_size = size(m[end].W)
    val = Chain([deepcopy(m[i]) for i=duel_layer+1:nlayers-1]..., Dense(last_layer_size, 1))
    adv = Chain([deepcopy(m[i]) for i=duel_layer+1:nlayers]...)
    base = Chain([deepcopy(m[i]) for i=1:duel_layer+1-1]...)
    return DuelingNetwork(base, val, adv)
end


text:
export DPMHyperparam, DPMData

"Dirichlet Process Mixture Model Hyperparameters"
struct DPMHyperparam <: AbstractHyperparam

  γ_a::Float64
  γ_b::Float64

  "default values"
  DPMHyperparam(;α = 1.0, β = 1.0) = new(α, β)

end

"Dirichlet Process Mixture Model Data Object"
mutable struct DPMData <: AbstractModelData

  # Energy
  energy::Float64

  # Dirichlet concentration parameter
  α::Float64

  # Distributions
  distributions::Array{ConjugatePostDistribution}

  # Assignments
  assignments::Array{Int}

  # Weights
  weights::Array{Float64}

end

mutable struct DPMBuffer <: AbstractModelBuffer

  # ids used for random access
  ids::Array{Int}

  # dimensionality of data
  D::Int

  # number of samples
  N::Int

  # samples
  X::AbstractArray

  # assignments
  Z::Array{Int}

  # number of samples per cluster
  C::Array{Int}

  # weights
  π::Vector{Float64}

  # number of active cluster
  K::Int

  # distributions
  G::Array{ConjugatePostDistribution}

  # base distribution
  G0::ConjugatePostDistribution

  # concentration parameter
  alpha::Float64
end

function init(X::AbstractArray{T}, model::DPM, init::KMeansInitialisation) where T <: Real

  (N, D) = size(X)

	if issparse(X)
    if !(T == Float64)
      R = Clustering.kmeans(convert(Matrix, float(full(X'))), init.k; maxiter = init.maxiterations)
    else
      R = Clustering.kmeans(convert(Matrix, full(X')), init.k; maxiter = init.maxiterations)
    end
	else
    R = Clustering.kmeans(convert(Matrix,X'), init.k; maxiter = init.maxiterations)
	end

  Z = assignments(R)
  G = Array{ConjugatePostDistribution}(undef, init.k)

  for c in 1:init.k
    idx = findall(Z .== c)

    if length(idx) > 0
      G[c] = add(model.H, X[idx,:])
    else
      G[c] = deepcopy(model.H)
    end
  end

  C = zeros(Int, init.k)
  for i = 1:init.k
    C[i] = sum(Z .== i)
  end

  K = init.k
  for k in sort(findall(C .== 0), rev = true)
    deleteat!(G, k)
    Z[Z .> k] -= 1
    deleteat!(C, k)
    K -= 1
  end

  return DPMBuffer(
    collect(1:N),
    D,
    N,
    X,
    Z,
    C,
    rand(Dirichlet(C)),
    K,
    G,
    model.H,
    model.α)
end

function init(X::AbstractArray{T}, model::DPM, init::RandomInitialisation) where T <: Real

  (N, D) = size(X)

  Z = rand(1:init.k, N)

  G = Array{ConjugatePostDistribution}(undef, init.k)

  for c in 1:init.k
    idx = findall(Z .== c)

    if length(idx) > 0
      G[c] = add(model.H, X[idx,:])
    else
      G[c] = deepcopy(model.H)
    end
  end

  C = zeros(Int, init.k)
  for i = 1:init.k
    C[i] = sum(Z .== i)
  end

  return DPMBuffer(
    collect(1:N),
    D,
    N,
    X,
    Z,
    C,
    rand(Dirichlet(C)),
    init.k,
    G,
    model.H,
    model.α)
end

"Single iteration of collabsed Gibbs sampling using CRP."
function gibbs!(B::DPMBuffer)

  # randomize data
  shuffle!(B.ids)

  z = -1
  k = -1

  for index in B.ids

    x = @view B.X[index, :]

    # get assignment
    z = B.Z[index]

    # remove sample from cluster
    remove!(B.G[z], x)

    # remove cluster assignment
    B.C[z] -= 1

    # udpate number of active clusters if necessary
    if B.C[z] < 1
      deleteat!(B.G, z)
      B.Z[B.Z .> z] .-= 1
      deleteat!(B.C, z)
      B.K -= 1
    end

    # remove cluster assignment
    z = -1

    # compute posterior predictive
    # compute priors using chinese restaurant process
    # see: Samuel J. Gershman and David M. Blei, A tutorial on Bayesian nonparametric models.
    # In Journal of Mathematical Psychology (2012)
    p = ones(B.K + 1) * -Inf
    for i in 1:length(B.C)
      llh = logpostpred( B.G[i], x )[1]
      crp = log( B.C[i] / (B.N + B.alpha - 1) )

      p[i] = llh + crp
    end

    p[B.K + 1] = logpostpred(B.G0, x)[1] + log( B.alpha / (B.N + B.alpha - 1) )
    p = exp.(p .- maximum(p))

    k = randomindex(p)

    if k > length(B.G)
      # add new cluster
      Gk = add(B.G0, x)
      B.G = vcat(B.G, Gk)
      B.C = vcat(B.C, 0)
    else
      # add to cluster
      add!(B.G[k], x)
    end

    if k > B.K
      B.K += 1
    end

    B.C[k] += 1
    B.Z[index] = k
  end

  B.π = Float64[B.C[i] / (B.N + B.alpha - 1) for i in 1:B.K]

  B
end

"Compute Energy of model for given data"
function updateenergy!(B::DPMData, X::AbstractArray)

  E = eps() * 10^10

  for xi in 1:size(X, 1)

    pp = 0.0
    c = 0

    for i = 1:length(B.weights)
      p = exp( logpostpred( B.distributions[i], X[xi, :] )[1] ) * B.weights[i]

      # only sum over actual values (excluding nans)
      if p == p
        pp += p
        c += 1
      end
    end

    E += pp

  end

  B.energy = log( E / size(X, 1) )

end

function sampleparameters!(B::DPMBuffer, P::DPMHyperparam)
  B.alpha = resampleα(B.alpha, B.N, B.K, k = P.γ_a, Θ = P.γ_b, maxiter = 10)
end

function extractpointestimate(B::DPMBuffer)
  model = DPMData(0.0, deepcopy(B.alpha), deepcopy(B.G), deepcopy(B.Z), copy(B.π))
  updateenergy!(model, B.X)
  model
end

function slicemap(i::Int, uu::Float64, ii::Int, π::Vector{Float64}, Zi::Int, Xi::AbstractArray,
    G::Vector{ConjugatePostDistribution}, G0::ConjugatePostDistribution, K::Int)
  if i == ii
		ui = uu
	else
		ui = rand(Uniform(uu, π[Zi]))
	end

	di = findall(π .>= ui)
	p = [logpostpred(G[d], Xi)[1] for d in filter(d -> d <= K, di)]
	if any(di .> K)
		push!(p, logpostpred(G0, Xi)[1])
	end
	z = di[randomindex(exp(p - maximum(p)))]
	(z, i)
end

function slicesampling!(B::DPMBuffer)
	# sample global parameters
	n = counts(B.Z, 1:B.K)
	π = rand(Dirichlet(vcat(n, B.alpha)))
	b = [rand(Beta(1, n[k])) for k in 1:B.K]
	u = π[1:end-1].*b
	(uu, kk) = findmin(u)
	ii = rand(findall(B.Z .== kk))

	# collect slices
	suffstat = @distributed (vcat) for i in 1:B.N
		slicemap(i, uu, ii, π, B.Z[i], view(B.X, i, :), B.G, B.G0, B.K)
	end

	# update GMM
	ki = 1
	emptyIds = Int[]

	for k in 1:B.K
		stats = filter(sstat -> sstat[1] == k, suffstat)
		if !isempty(stats)
			ids = reduce(vcat, (sstat[2] for sstat in stats))
			B.Z[ids] = ki
			B.G[ki] = add(B.G0, B.X[ids,:])
			ki += 1
		else
			push!(emptyIds, k)
		end
	end

	# remove empty clusters
	for eid in reverse(emptyIds)
		deleteat!(B.G, eid)
	end

	B.K = B.K - length(emptyIds)

	# add new components
	stats = filter(sstat -> sstat[1] > B.K + length(emptyIds), suffstat)

	if !isempty(stats)
		ids = reduce(vcat, (sstat[2] for sstat in stats))
		push!(B.G, add(B.G0, B.X[ids, :]))
		B.Z[ids] = B.K + 1
		B.K += 1
	end

  # update weights
  n = counts(B.Z, 1:B.K)
	B.π = rand(Dirichlet(n))
end


text:
"""
    load(task::AbstractString, type::AbstractString, frequency::AbstractString)

Load the data for a given task (`TaskA` or `TaskB`), its type (`annotations` or `ground_truth`), and its frequency (`10Hz` or `30Hz`).

Examples
========

    julia> df = load("TaskA", "annotations", "30Hz")
"""
function load(task::AbstractString, type::AbstractString, frequency::AbstractString)
    @assert task in ["TaskA", "TaskB"]
    @assert type in ["annotations", "ground_truth"]
    @assert frequency in ["10Hz", "30Hz"]

    path = p"" / @__FILE__
    return CSV.read(parent(parent(path)) / "data" / task / type / string(frequency, ".csv"), DataFrame)
end


text:
u = collect(-5:0.1:5)

KitBase.ib_briowu(5 / 3, 1.0, 0.5, hcat(u, u))
KitBase.ib_briowu(5 / 3, 1.0, 0.5, ones(8, 8, 2), ones(8, 8, 2))

ib_rh(1.2, 5 / 3)


text:
# Polynomial covariance function

@doc """
# Description
Constructor for the Polynomial kernel (covariance)

k(x,x') = σ²(xᵀx'+c)ᵈ
# Arguments:
* `lc::Float64`: Log of the constant c
* `lσ::Float64`: Log of the signal standard deviation σ
* `d::Int64`   : Degree of the Polynomial
""" ->
type Poly <: Kernel
    lc::Float64      # Log of constant
    lσ::Float64      # Log of signal std
    deg::Int64       # degree of polynomial
    Poly(lc::Float64, lσ::Float64, deg::Int64) = new(lc, lσ, deg)
end

function cov(poly::Poly, x::Vector{Float64}, y::Vector{Float64})
    c = exp(poly.lc)
    sigma2 = exp(2*poly.lσ)

    K = sigma2*(c+dot(x,y)).^poly.deg
    return K
end

get_params(poly::Poly) = Float64[poly.lc, poly.lσ]
get_param_names(poly::Poly) = [:lc, :lσ]
num_params(poly::Poly) = 2

function set_params!(poly::Poly, hyp::Vector{Float64})
    length(hyp) == 2 || throw(ArgumentError("Polynomial function has two parameters"))
    poly.lc, poly.lσ = hyp
end

function grad_kern(poly::Poly, x::Vector{Float64}, y::Vector{Float64})
    c = exp(poly.lc)
    sigma2 = exp(2*poly.lσ)

    dK_c   = c*poly.deg*sigma2*(c+dot(x,y)).^(poly.deg-1)
    dK_sigma = 2.0*sigma2*(c+dot(x,y)).^poly.deg
    dK_theta = [dK_c,dK_sigma]
    return dK_theta
end


text:
@test MLJ_VERSION isa VersionNumber
true


text:
include("utils.jl")

build_so("012")

immutable Foo
   a::Cint
   b::Cint
end

xs = [Foo(1, 2), Foo(3, 4)]

y = ccall(
    (:bar, "binary/lib012.so"),
    Void,
    (Ptr{Foo}, Cint),
    pointer(xs), length(xs)
)

@assert xs[1] == Foo(2, 2)
@assert xs[2] == Foo(4, 4)

@assert y === nothing


text:
@testset "Univariate" begin
    @testset "Known V, Known W" begin
        y = vcat(1., 2., 3.)[:,:]
        F = hcat(1., 0.)
        G = [1. 1.; 0. 1.]
        V = Symmetric(hcat(1.))
        W = Symmetric(diagm([1., 1.]))

        ## Filter tests

        a, R, m, C = kfilter(y, F, G, V, W)

        @test a[1,:] ≈ zeros(2)
        @test R[1] ≈ [3. 1.; 1. 2.]
        @test m[end,:] ≈ [2 + 900/999, 882/999]

        ## Smoother tests

        s, S = ksmoother(G, a, R, m, C)

        @test s[1,:] ≈ [954/999, 783/999]
        # Should be a copy, not using '≈' on purpose
        @test C[end] == S[end]

        ## Fitted tests

        f, Q = fitted(F, V, s, S)

        @test f[1,:] ≈ [954 / 999]
        @test Q[1] ≈ hcat(1 + 549/999)

        ## Forecast tests

        f, Q = forecast(F, G, V, W, s[end,:], C[end], 2)

        @test f[2,:] ≈ [4 + 2/3]
        @test Q[2] ≈ hcat(14 + 1/3)
    end

    @testset "Known V, Unknown W" begin
        y = vcat(1., 2., 3.)[:,:]
        F = hcat(1., 0.)
        G = [1. 1.; 0. 1.]
        V = Symmetric(hcat(1.))

        ## Filter tests

        a, R, m, C = kfilter(y, F, G, V, 0.5)

        @test a[1,:] ≈ zeros(2)
        @test R[1] ≈ [4. 2.; 2. 2.]
        @test m[end,:] ≈ [2.947368421052632, 0.9282296650717702]

        ## Smoother tests

        s, S = ksmoother(G, a, R, m, C)

        @test s[1,:] ≈ [0.9 + 45/990, 0.6290271132376396]
        # Should be a copy, not approximate on purpose
        @test C[end] == S[end]

        ## Fitted tests

        f, Q = fitted(F, V, s, S)

        @test f[1,:] ≈ [0.9 + 45/990]
        @test Q[1] ≈ hcat(1.5 + 81/990)

        ## Forecast tests

        f, Q = forecast(F, G, V, 0.5, s[end,:], C[end], 2)

        @test f[2,:] ≈ [4.803827751196172]
        @test Q[2] ≈ hcat(12.023923444976077)

        ## evolutional_covariances

        W = evolutional_covariances(y, F, G, V, 0.5)

        @test W[1] ≈ [2.8 1.6; 1.6 1.2]
        @test W[end][1,1] ≈ 2.258373205741627
        @test W[end][1,2] ≈ 0.9952153110047848
        @test W[end][2,2] ≈ 0.5741626794258374
    end

    @testset "Unknown V, Unknown W" begin
        y = vcat(1.1, 2.1, 2.9, 4.05)[:,:]
        F = hcat(1., 0.)
        G = [1. 1.; 0. 1.]

        θ, Σ, it = estimate(y, F, G, 0.8)
        f, Q = fitted(F, Σ, θ, evolutional_covariances(y, F, G, Σ, 0.8))

        @test f[1,:] ≈ [1.0941182414662356]
        @test f[end,:] ≈ [3.9948460619971886]
        @test Q[end] ≈ hcat(0.005579344922273387)
    end
end