text:
# This file is auto-generated by AWSMetadata.jl
using AWS
using AWS.AWSServices: cloudcontrol
using AWS.Compat
using AWS.UUIDs

"""
    cancel_resource_request(request_token)
    cancel_resource_request(request_token, params::Dict{String,<:Any})

Cancels the specified resource operation request. For more information, see Canceling
resource operation requests in the Amazon Web Services Cloud Control API User Guide. Only
resource operations requests with a status of PENDING or IN_PROGRESS can be cancelled.

# Arguments
- `request_token`: The RequestToken of the ProgressEvent object returned by the resource
  operation request.

"""
function cancel_resource_request(
    RequestToken; aws_config::AbstractAWSConfig=global_aws_config()
)
    return cloudcontrol(
        "CancelResourceRequest",
        Dict{String,Any}("RequestToken" => RequestToken);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function cancel_resource_request(
    RequestToken,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return cloudcontrol(
        "CancelResourceRequest",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("RequestToken" => RequestToken), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_resource(desired_state, type_name)
    create_resource(desired_state, type_name, params::Dict{String,<:Any})

Creates the specified resource. For more information, see Creating a resource in the Amazon
Web Services Cloud Control API User Guide. After you have initiated a resource creation
request, you can monitor the progress of your request by calling GetResourceRequestStatus
using the RequestToken of the ProgressEvent type returned by CreateResource.

# Arguments
- `desired_state`: Structured data format representing the desired state of the resource,
  consisting of that resource's properties and their desired values.   Cloud Control API
  currently supports JSON as a structured data format.  Specify the desired state as one of
  the following:   A JSON blob   A local path containing the desired state in JSON data
  format   For more information, see Composing the desired state of the resource in the
  Amazon Web Services Cloud Control API User Guide. For more information about the properties
  of a specific resource, refer to the related topic for the resource in the Resource and
  property types reference in the Amazon Web Services CloudFormation Users Guide.
- `type_name`: The name of the resource type.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ClientToken"`: A unique identifier to ensure the idempotency of the resource request.
  As a best practice, specify this token to ensure idempotency, so that Amazon Web Services
  Cloud Control API can accurately distinguish between request retries and new resource
  requests. You might retry a resource request to ensure that it was successfully received. A
  client token is valid for 36 hours once used. After that, a resource request with the same
  client token is treated as a new request. If you do not specify a client token, one is
  generated for inclusion in the request. For more information, see Ensuring resource
  operation requests are unique in the Amazon Web Services Cloud Control API User Guide.
- `"RoleArn"`: The Amazon Resource Name (ARN) of the Identity and Access Management (IAM)
  for Cloud Control API to use when performing this resource operation. The role specified
  must have the permissions required for this operation. The necessary permissions for each
  event handler are defined in the  handlers  section of the resource type definition schema.
  If you do not specify a role, Cloud Control API uses a temporary session created using your
  Amazon Web Services user credentials. For more information, see Specifying credentials in
  the Amazon Web Services Cloud Control API User Guide.
- `"TypeVersionId"`: For private resource types, the type version to use in this resource
  operation. If you do not specify a resource version, CloudFormation uses the default
  version.
"""
function create_resource(
    DesiredState, TypeName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return cloudcontrol(
        "CreateResource",
        Dict{String,Any}(
            "DesiredState" => DesiredState,
            "TypeName" => TypeName,
            "ClientToken" => string(uuid4()),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_resource(
    DesiredState,
    TypeName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return cloudcontrol(
        "CreateResource",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "DesiredState" => DesiredState,
                    "TypeName" => TypeName,
                    "ClientToken" => string(uuid4()),
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_resource(identifier, type_name)
    delete_resource(identifier, type_name, params::Dict{String,<:Any})

Deletes the specified resource. For details, see Deleting a resource in the Amazon Web
Services Cloud Control API User Guide. After you have initiated a resource deletion
request, you can monitor the progress of your request by calling GetResourceRequestStatus
using the RequestToken of the ProgressEvent returned by DeleteResource.

# Arguments
- `identifier`: The identifier for the resource. You can specify the primary identifier, or
  any secondary identifier defined for the resource type in its resource schema. You can only
  specify one identifier. Primary identifiers can be specified as a string or JSON; secondary
  identifiers must be specified as JSON. For compound primary identifiers (that is, one that
  consists of multiple resource properties strung together), to specify the primary
  identifier as a string, list the property values in the order they are specified in the
  primary identifier definition, separated by |.  For more information, see Identifying
  resources in the Amazon Web Services Cloud Control API User Guide.
- `type_name`: The name of the resource type.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ClientToken"`: A unique identifier to ensure the idempotency of the resource request.
  As a best practice, specify this token to ensure idempotency, so that Amazon Web Services
  Cloud Control API can accurately distinguish between request retries and new resource
  requests. You might retry a resource request to ensure that it was successfully received. A
  client token is valid for 36 hours once used. After that, a resource request with the same
  client token is treated as a new request. If you do not specify a client token, one is
  generated for inclusion in the request. For more information, see Ensuring resource
  operation requests are unique in the Amazon Web Services Cloud Control API User Guide.
- `"RoleArn"`: The Amazon Resource Name (ARN) of the Identity and Access Management (IAM)
  for Cloud Control API to use when performing this resource operation. The role specified
  must have the permissions required for this operation. The necessary permissions for each
  event handler are defined in the  handlers  section of the resource type definition schema.
  If you do not specify a role, Cloud Control API uses a temporary session created using your
  Amazon Web Services user credentials. For more information, see Specifying credentials in
  the Amazon Web Services Cloud Control API User Guide.
- `"TypeVersionId"`: For private resource types, the type version to use in this resource
  operation. If you do not specify a resource version, CloudFormation uses the default
  version.
"""
function delete_resource(
    Identifier, TypeName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return cloudcontrol(
        "DeleteResource",
        Dict{String,Any}(
            "Identifier" => Identifier,
            "TypeName" => TypeName,
            "ClientToken" => string(uuid4()),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_resource(
    Identifier,
    TypeName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return cloudcontrol(
        "DeleteResource",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "Identifier" => Identifier,
                    "TypeName" => TypeName,
                    "ClientToken" => string(uuid4()),
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_resource(identifier, type_name)
    get_resource(identifier, type_name, params::Dict{String,<:Any})

Returns information about the current state of the specified resource. For details, see
Reading a resource's current state. You can use this action to return information about an
existing resource in your account and Amazon Web Services Region, whether or not those
resources were provisioned using Cloud Control API.

# Arguments
- `identifier`: The identifier for the resource. You can specify the primary identifier, or
  any secondary identifier defined for the resource type in its resource schema. You can only
  specify one identifier. Primary identifiers can be specified as a string or JSON; secondary
  identifiers must be specified as JSON. For compound primary identifiers (that is, one that
  consists of multiple resource properties strung together), to specify the primary
  identifier as a string, list the property values in the order they are specified in the
  primary identifier definition, separated by |.  For more information, see Identifying
  resources in the Amazon Web Services Cloud Control API User Guide.
- `type_name`: The name of the resource type.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"RoleArn"`: The Amazon Resource Name (ARN) of the Identity and Access Management (IAM)
  for Cloud Control API to use when performing this resource operation. The role specified
  must have the permissions required for this operation. The necessary permissions for each
  event handler are defined in the  handlers  section of the resource type definition schema.
  If you do not specify a role, Cloud Control API uses a temporary session created using your
  Amazon Web Services user credentials. For more information, see Specifying credentials in
  the Amazon Web Services Cloud Control API User Guide.
- `"TypeVersionId"`: For private resource types, the type version to use in this resource
  operation. If you do not specify a resource version, CloudFormation uses the default
  version.
"""
function get_resource(
    Identifier, TypeName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return cloudcontrol(
        "GetResource",
        Dict{String,Any}("Identifier" => Identifier, "TypeName" => TypeName);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_resource(
    Identifier,
    TypeName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return cloudcontrol(
        "GetResource",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("Identifier" => Identifier, "TypeName" => TypeName),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_resource_request_status(request_token)
    get_resource_request_status(request_token, params::Dict{String,<:Any})

Returns the current status of a resource operation request. For more information, see
Tracking the progress of resource operation requests in the Amazon Web Services Cloud
Control API User Guide.

# Arguments
- `request_token`: A unique token used to track the progress of the resource operation
  request. Request tokens are included in the ProgressEvent type returned by a resource
  operation request.

"""
function get_resource_request_status(
    RequestToken; aws_config::AbstractAWSConfig=global_aws_config()
)
    return cloudcontrol(
        "GetResourceRequestStatus",
        Dict{String,Any}("RequestToken" => RequestToken);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_resource_request_status(
    RequestToken,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return cloudcontrol(
        "GetResourceRequestStatus",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("RequestToken" => RequestToken), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_resource_requests()
    list_resource_requests(params::Dict{String,<:Any})

Returns existing resource operation requests. This includes requests of all status types.
For more information, see Listing active resource operation requests in the Amazon Web
Services Cloud Control API User Guide.  Resource operation requests expire after seven
days.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: The maximum number of results to be returned with a single call. If the
  number of available results exceeds this maximum, the response includes a NextToken value
  that you can assign to the NextToken request parameter to get the next set of results. The
  default is 20.
- `"NextToken"`: If the previous paginated request didn't return all of the remaining
  results, the response object's NextToken parameter value is set to a token. To retrieve the
  next set of results, call this action again and assign that token to the request object's
  NextToken parameter. If there are no remaining results, the previous response object's
  NextToken parameter is set to null.
- `"ResourceRequestStatusFilter"`: The filter criteria to apply to the requests returned.
"""
function list_resource_requests(; aws_config::AbstractAWSConfig=global_aws_config())
    return cloudcontrol(
        "ListResourceRequests"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_resource_requests(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return cloudcontrol(
        "ListResourceRequests",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_resources(type_name)
    list_resources(type_name, params::Dict{String,<:Any})

Returns information about the specified resources. For more information, see Discovering
resources in the Amazon Web Services Cloud Control API User Guide. You can use this action
to return information about existing resources in your account and Amazon Web Services
Region, whether or not those resources were provisioned using Cloud Control API.

# Arguments
- `type_name`: The name of the resource type.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: The maximum number of results to be returned with a single call. If the
  number of available results exceeds this maximum, the response includes a NextToken value
  that you can assign to the NextToken request parameter to get the next set of results. The
  default is 20.
- `"NextToken"`: If the previous paginated request didn't return all of the remaining
  results, the response object's NextToken parameter value is set to a token. To retrieve the
  next set of results, call this action again and assign that token to the request object's
  NextToken parameter. If there are no remaining results, the previous response object's
  NextToken parameter is set to null.
- `"ResourceModel"`: The resource model to use to select the resources to return.
- `"RoleArn"`: The Amazon Resource Name (ARN) of the Identity and Access Management (IAM)
  for Cloud Control API to use when performing this resource operation. The role specified
  must have the permissions required for this operation. The necessary permissions for each
  event handler are defined in the  handlers  section of the resource type definition schema.
  If you do not specify a role, Cloud Control API uses a temporary session created using your
  Amazon Web Services user credentials. For more information, see Specifying credentials in
  the Amazon Web Services Cloud Control API User Guide.
- `"TypeVersionId"`: For private resource types, the type version to use in this resource
  operation. If you do not specify a resource version, CloudFormation uses the default
  version.
"""
function list_resources(TypeName; aws_config::AbstractAWSConfig=global_aws_config())
    return cloudcontrol(
        "ListResources",
        Dict{String,Any}("TypeName" => TypeName);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_resources(
    TypeName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return cloudcontrol(
        "ListResources",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("TypeName" => TypeName), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_resource(identifier, patch_document, type_name)
    update_resource(identifier, patch_document, type_name, params::Dict{String,<:Any})

Updates the specified property values in the resource. You specify your resource property
updates as a list of patch operations contained in a JSON patch document that adheres to
the  RFC 6902 - JavaScript Object Notation (JSON) Patch  standard. For details on how Cloud
Control API performs resource update operations, see Updating a resource in the Amazon Web
Services Cloud Control API User Guide. After you have initiated a resource update request,
you can monitor the progress of your request by calling GetResourceRequestStatus using the
RequestToken of the ProgressEvent returned by UpdateResource. For more information about
the properties of a specific resource, refer to the related topic for the resource in the
Resource and property types reference in the Amazon Web Services CloudFormation Users Guide.

# Arguments
- `identifier`: The identifier for the resource. You can specify the primary identifier, or
  any secondary identifier defined for the resource type in its resource schema. You can only
  specify one identifier. Primary identifiers can be specified as a string or JSON; secondary
  identifiers must be specified as JSON. For compound primary identifiers (that is, one that
  consists of multiple resource properties strung together), to specify the primary
  identifier as a string, list the property values in the order they are specified in the
  primary identifier definition, separated by |.  For more information, see Identifying
  resources in the Amazon Web Services Cloud Control API User Guide.
- `patch_document`: A JavaScript Object Notation (JSON) document listing the patch
  operations that represent the updates to apply to the current resource properties. For
  details, see Composing the patch document in the Amazon Web Services Cloud Control API User
  Guide.
- `type_name`: The name of the resource type.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ClientToken"`: A unique identifier to ensure the idempotency of the resource request.
  As a best practice, specify this token to ensure idempotency, so that Amazon Web Services
  Cloud Control API can accurately distinguish between request retries and new resource
  requests. You might retry a resource request to ensure that it was successfully received. A
  client token is valid for 36 hours once used. After that, a resource request with the same
  client token is treated as a new request. If you do not specify a client token, one is
  generated for inclusion in the request. For more information, see Ensuring resource
  operation requests are unique in the Amazon Web Services Cloud Control API User Guide.
- `"RoleArn"`: The Amazon Resource Name (ARN) of the Identity and Access Management (IAM)
  for Cloud Control API to use when performing this resource operation. The role specified
  must have the permissions required for this operation. The necessary permissions for each
  event handler are defined in the  handlers  section of the resource type definition schema.
  If you do not specify a role, Cloud Control API uses a temporary session created using your
  Amazon Web Services user credentials. For more information, see Specifying credentials in
  the Amazon Web Services Cloud Control API User Guide.
- `"TypeVersionId"`: For private resource types, the type version to use in this resource
  operation. If you do not specify a resource version, CloudFormation uses the default
  version.
"""
function update_resource(
    Identifier, PatchDocument, TypeName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return cloudcontrol(
        "UpdateResource",
        Dict{String,Any}(
            "Identifier" => Identifier,
            "PatchDocument" => PatchDocument,
            "TypeName" => TypeName,
            "ClientToken" => string(uuid4()),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_resource(
    Identifier,
    PatchDocument,
    TypeName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return cloudcontrol(
        "UpdateResource",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "Identifier" => Identifier,
                    "PatchDocument" => PatchDocument,
                    "TypeName" => TypeName,
                    "ClientToken" => string(uuid4()),
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end


text:
@testset "exports" begin
    # Ensure that every exported name is actually defined
    for name in names(Geometry)
        @test isdefined(Geometry, name)
        !isdefined(Geometry, name) && println("MISSING: ", name)
    end
end

ext: jl


text:
using ReinforcementLearningCore

using AbstractTrees

"""
    EnrichedAction(action;kwargs...)

Inject some runtime info into the action
"""
struct EnrichedAction{A,M}
    action::A
    meta::M
end

EnrichedAction(action; kwargs...) = EnrichedAction(action, values(kwargs))

(env::AbstractEnv)(action::EnrichedAction) = env(action.action)


text:
module DGMultiFEOperatorsTests

# Testing Stokes problem with Dirichlet BCs for the velocity
# and pressure prescribed in a single point

using Test
using Gridap
import Gridap: ∇
import LinearAlgebra: tr

const T = VectorValue{2,Float64}

u(x) = VectorValue(x[1]*x[1], x[2])

∇u(x) = TensorValue(2*x[1],0.0,0.0,1.0)

∇(::typeof(u)) = ∇u

Δu(x) = VectorValue(2.0,0.0)

p(x) = x[1] - x[2]

∇p(x) = VectorValue(1.0,-1.0)

f(x) = - Δu(x) + ∇p(x)

g(x) = tr(∇u(x))

ud(x) = u(x)

# Discrete model
L = 1.0
limits = (0.0, L, 0.0, L)
ncellx = 4
model = CartesianDiscreteModel(domain=limits, partition=(ncellx,ncellx))
model = simplexify(model)

h = L / ncellx

order = 2
γ = order*(order+1)
γ0 = 1.0/10.0

# Construct the FEspace 1
fespace1 = DLagrangianFESpace(T,model,order)

# Construct the FEspace 2
fespace2 = DLagrangianFESpace(Float64,model,order)
fespace2 = ZeroMeanFESpace(fespace2,order)

# Define test and trial
Vh = TestFESpace(fespace1)
Qh = TestFESpace(fespace2)
Yh = [Vh, Qh]

Uh = TrialFESpace(fespace1)
Ph = TrialFESpace(fespace2)
Xh = [Uh, Ph]

# Define integration mesh and quadrature for volume
trian = Triangulation(model)
quad = CellQuadrature(trian,degree=2*order)

btrian = BoundaryTriangulation(model)
bquad = CellQuadrature(btrian,degree=2*order)
nb = NormalVector(btrian)

strian = SkeletonTriangulation(model)
squad = CellQuadrature(strian,degree=2*order)
ns = NormalVector(strian)

# Weak form

function A_Ω(y,x)
  u, p = x
  v, q = y
  inner(∇(v), ∇(u)) - inner(∇(q), u) + inner(v, ∇(p))
end

function B_Ω(y)
  v, q = y
  inner(v,f) + inner(q, g)
end

function A_∂Ω(y,x)
  u, p = x
  v, q = y
  (γ/h) * inner(v,u) - inner(v, ∇(u)*nb )  - inner(∇(v)*nb, u) + 2*inner(q*nb,u) # - inner(v, p*nb) + inner(v,p*nb)
end

function B_∂Ω(y)
  v, q = y
  (γ/h) * inner(v,ud) - inner(∇(v)*nb, ud) + inner(q*nb, ud)
end

function A_Γ(y,x)
  u, p = x
  v, q = y
  (γ/h) * inner( jump(outer(v,ns)), jump(outer(u,ns))) -
    inner( jump(outer(v,ns)), mean(∇(u)) ) -
    inner( mean(∇(v)), jump(outer(u,ns)) ) +
    (γ0*h) * inner( jump(q*ns), jump(p*ns)  ) +
    inner( jump(q*ns), mean(u) ) -
    inner( mean(v), jump(p*ns) )
end

t_Ω = AffineFETerm(A_Ω,B_Ω,trian,quad)

t_∂Ω = AffineFETerm(A_∂Ω,B_∂Ω,btrian,bquad)

t_Γ = LinearFETerm(A_Γ,strian,squad)

# Define the FEOperator
op = LinearFEOperator(Yh,Xh,t_Ω,t_∂Ω,t_Γ)

# Solve!
xh = solve(op)
uh, ph = xh

# Define exact solution and error
eu = u - uh

ep = p - ph

#writevtk(trian,"trian",cellfields=["uh"=>uh,"ph"=>ph, "eu"=>eu, "ep"=>ep])

# Define norms to measure the error
l2(u) = inner(u,u)
h1(u) = inner(∇(u),∇(u)) + l2(u)

# Compute errors
eul2 = sqrt(sum( integrate(l2(eu),trian,quad) ))
euh1 = sqrt(sum( integrate(h1(eu),trian,quad) ))

epl2 = sqrt(sum( integrate(l2(ep),trian,quad) ))

@test eul2 < 1.e-8
@test euh1 < 1.e-8

@test epl2 < 1.e-8

end # module


text:
# syntax: proto3
using ProtoBuf
import ProtoBuf.meta

mutable struct MultilineChartContent <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function MultilineChartContent(; kwargs...)
        obj = new(meta(MultilineChartContent), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct MultilineChartContent
const __meta_MultilineChartContent = Ref{ProtoMeta}()
function meta(::Type{MultilineChartContent})
    ProtoBuf.metalock() do
        if !isassigned(__meta_MultilineChartContent)
            __meta_MultilineChartContent[] = target = ProtoMeta(MultilineChartContent)
            allflds = Pair{Symbol,Union{Type,String}}[:tag => Base.Vector{AbstractString}]
            meta(target, MultilineChartContent, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_MultilineChartContent[]
    end
end
function Base.getproperty(obj::MultilineChartContent, name::Symbol)
    if name === :tag
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{AbstractString}
    else
        getfield(obj, name)
    end
end

mutable struct MarginChartContent_Series <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function MarginChartContent_Series(; kwargs...)
        obj = new(meta(MarginChartContent_Series), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct MarginChartContent_Series
const __meta_MarginChartContent_Series = Ref{ProtoMeta}()
function meta(::Type{MarginChartContent_Series})
    ProtoBuf.metalock() do
        if !isassigned(__meta_MarginChartContent_Series)
            __meta_MarginChartContent_Series[] = target = ProtoMeta(MarginChartContent_Series)
            allflds = Pair{Symbol,Union{Type,String}}[:value => AbstractString, :lower => AbstractString, :upper => AbstractString]
            meta(target, MarginChartContent_Series, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_MarginChartContent_Series[]
    end
end
function Base.getproperty(obj::MarginChartContent_Series, name::Symbol)
    if name === :value
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :lower
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :upper
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    else
        getfield(obj, name)
    end
end

mutable struct MarginChartContent <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function MarginChartContent(; kwargs...)
        obj = new(meta(MarginChartContent), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct MarginChartContent
const __meta_MarginChartContent = Ref{ProtoMeta}()
function meta(::Type{MarginChartContent})
    ProtoBuf.metalock() do
        if !isassigned(__meta_MarginChartContent)
            __meta_MarginChartContent[] = target = ProtoMeta(MarginChartContent)
            allflds = Pair{Symbol,Union{Type,String}}[:series => Base.Vector{MarginChartContent_Series}]
            meta(target, MarginChartContent, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_MarginChartContent[]
    end
end
function Base.getproperty(obj::MarginChartContent, name::Symbol)
    if name === :series
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{MarginChartContent_Series}
    else
        getfield(obj, name)
    end
end

mutable struct Chart <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function Chart(; kwargs...)
        obj = new(meta(Chart), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct Chart
const __meta_Chart = Ref{ProtoMeta}()
function meta(::Type{Chart})
    ProtoBuf.metalock() do
        if !isassigned(__meta_Chart)
            __meta_Chart[] = target = ProtoMeta(Chart)
            allflds = Pair{Symbol,Union{Type,String}}[:title => AbstractString, :multiline => MultilineChartContent, :margin => MarginChartContent]
            oneofs = Int[0,1,1]
            oneof_names = Symbol[Symbol("content")]
            meta(target, Chart, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, oneofs, oneof_names)
        end
        __meta_Chart[]
    end
end
function Base.getproperty(obj::Chart, name::Symbol)
    if name === :title
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :multiline
        return (obj.__protobuf_jl_internal_values[name])::MultilineChartContent
    elseif name === :margin
        return (obj.__protobuf_jl_internal_values[name])::MarginChartContent
    else
        getfield(obj, name)
    end
end

mutable struct Category <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function Category(; kwargs...)
        obj = new(meta(Category), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct Category
const __meta_Category = Ref{ProtoMeta}()
function meta(::Type{Category})
    ProtoBuf.metalock() do
        if !isassigned(__meta_Category)
            __meta_Category[] = target = ProtoMeta(Category)
            allflds = Pair{Symbol,Union{Type,String}}[:title => AbstractString, :chart => Base.Vector{Chart}, :closed => Bool]
            meta(target, Category, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_Category[]
    end
end
function Base.getproperty(obj::Category, name::Symbol)
    if name === :title
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :chart
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{Chart}
    elseif name === :closed
        return (obj.__protobuf_jl_internal_values[name])::Bool
    else
        getfield(obj, name)
    end
end

mutable struct Layout <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function Layout(; kwargs...)
        obj = new(meta(Layout), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct Layout
const __meta_Layout = Ref{ProtoMeta}()
function meta(::Type{Layout})
    ProtoBuf.metalock() do
        if !isassigned(__meta_Layout)
            __meta_Layout[] = target = ProtoMeta(Layout)
            allflds = Pair{Symbol,Union{Type,String}}[:version => Int32, :category => Base.Vector{Category}]
            meta(target, Layout, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_Layout[]
    end
end
function Base.getproperty(obj::Layout, name::Symbol)
    if name === :version
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :category
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{Category}
    else
        getfield(obj, name)
    end
end

export Chart, MultilineChartContent, MarginChartContent_Series, MarginChartContent, Category, Layout


text:
"""
FinEtools (C) 2017-2019, Petr Krysl

Finite Element tools.  Julia implementation  of the finite element method
for continuum mechanics.
"""
module FinEtools

__precompile__(true)

include("allmodules.jl")

# Exports follow:

###########################################################################
# General facilities
###########################################################################
using FinEtools.FTypesModule: FInt, FFlt, FCplxFlt, FFltVec, FIntVec, FFltMat, FIntMat, FMat, FVec, FDataDict
# Exported: basic numerical types, type of data dictionary
export FInt, FFlt, FCplxFlt, FFltVec, FIntVec, FFltMat, FIntMat, FMat, FVec, FDataDict

using FinEtools.BoxModule: inbox, initbox!, updatebox!, boundingbox, inflatebox!, boxesoverlap, intersectboxes
# Exported: methods for manipulating and testing boxes
export inbox, initbox!, updatebox!, boundingbox, inflatebox!, boxesoverlap, intersectboxes

using FinEtools.PhysicalUnitModule: phun
# Exported: function for evaluating physical units
export phun

using FinEtools.RotationUtilModule: rotmat3!, skewmat!, cross3!, cross2
# Exported: functions for 3D rotation matrix computation, skew symmetric matrix computation,  in-place  cross product of 3-vectors, and  cross product of 2-vectors
export rotmat3!, skewmat!, cross3!, cross2

using FinEtools.CSysModule: CSys, updatecsmat!
# Exported: type  for coordinate systems, methods to invoke the update callback
export CSys, updatecsmat!

using FinEtools.FESetModule: FESet,  FESet0Manifold,  FESet1Manifold,  FESet2Manifold,  FESet3Manifold, manifdim, nodesperelem, count, fromarray!, connasarray, setlabel!, subset, cat, updateconn!, bfun, bfundpar, map2parametric, inparametric, centroidparametric,  FESetP1, FESetL2, FESetL3, FESetT3, FESetQ4, FESetQ9, FESetQ8, FESetT6, FESetH8, FESetH20, FESetH27, FESetT4, FESetT10
# Exported: types of finite element sets, abstract and concrete
export FESet,  FESet0Manifold,  FESet1Manifold,  FESet2Manifold,  FESet3Manifold, FESetP1, FESetL2, FESetL3, FESetT3, FESetQ4, FESetQ9, FESetQ8, FESetT6, FESetH8, FESetH20, FESetH27, FESetT4, FESetT10
# Exported: methods for accessing dimensions and counts
export manifdim, nodesperelem, count
# Exported: methods for  manipulating connectivity  and labels
export fromarray!, connasarray, setlabel!, subset, cat, updateconn!
# Exported: methods for computing basis function values and derivatives of basis functions  with respect to the parametric coordinates, and methods for working with parametric coordinates
export bfun, bfundpar, map2parametric, inparametric, centroidparametric

using FinEtools.FENodeSetModule: FENodeSet, spacedim, xyz3, count
# Exported: type for FE node sets, methods for accessing dimensions  and counts
export FENodeSet, spacedim, xyz3, count

using FinEtools.FENodeToFEMapModule: FENodeToFEMap
# Exported: type for maps from nodes to finite elements
export FENodeToFEMap

using FinEtools.FieldModule: Field, ndofs,  nents, gathersysvec, gathersysvec!, gathervalues_asvec!, gathervalues_asmat!, gatherdofnums!, gatherfixedvalues_asvec!, gatherfixedvalues_asmat!,numberdofs!, setebc!, applyebc!, scattersysvec!, copyto!, wipe!
# Exported: abstract field type, methods for the abstract field type (retrieval of data  from a field, setting of data in the field)
export Field, ndofs,  nents, gathersysvec, gathersysvec!, gathervalues_asvec!, gathervalues_asmat!, gatherdofnums!, gatherfixedvalues_asvec!, gatherfixedvalues_asmat!, numberdofs!, setebc!, applyebc!, scattersysvec!, copyto!, wipe!

using FinEtools.GeneralFieldModule: GeneralField
# Exported: type of general field
export GeneralField

using FinEtools.NodalFieldModule: NodalField, nnodes
# Exported: type of nodal field
export NodalField, nnodes

using FinEtools.ElementalFieldModule: ElementalField, nelems
# Exported: type of elemental field
export ElementalField, nelems

using FinEtools.MeshUtilModule: linearspace, gradedspace
# Exported: functions to generate a sequence of numbers between start and stop
export linearspace, gradedspace

using FinEtools.MeshSelectionModule: connectednodes, connectedelems, selectnode, selectelem, findunconnnodes
# Exported: functions to select (find) nodes and elements
export connectednodes, connectedelems, selectnode, selectelem, findunconnnodes

using FinEtools.MeshExportModule: vtkexportmesh
# Exported: VTK export
export vtkexportmesh
using FinEtools.MeshExportModule: AbaqusExporter, close, HEADING, COMMENT, PART, END_PART,    ASSEMBLY, END_ASSEMBLY, INSTANCE, END_INSTANCE, NODE, ELEMENT,    NSET_NSET, ELSET_ELSET, ORIENTATION, MATERIAL, ELASTIC, EXPANSION, DENSITY, SECTION_CONTROLS, SOLID_SECTION, SURFACE_SECTION, STEP_PERTURBATION_STATIC, STEP_FREQUENCY,   STEP_PERTURBATION_BUCKLE, BOUNDARY, DLOAD, CLOAD, TEMPERATURE,    END_STEP,  NODE_PRINT, EL_PRINT,  ENERGY_PRINT
# Exported: Abaqus export
export AbaqusExporter, close, HEADING, COMMENT, PART, END_PART,    ASSEMBLY, END_ASSEMBLY, INSTANCE, END_INSTANCE, NODE, ELEMENT,    NSET_NSET, ELSET_ELSET, ORIENTATION, MATERIAL, ELASTIC, EXPANSION, DENSITY, SECTION_CONTROLS, SOLID_SECTION, SURFACE_SECTION, STEP_PERTURBATION_STATIC, STEP_FREQUENCY,   STEP_PERTURBATION_BUCKLE, BOUNDARY, DLOAD, CLOAD, TEMPERATURE,    END_STEP,  NODE_PRINT, EL_PRINT,  ENERGY_PRINT
using FinEtools.MeshExportModule: savecsv
# Exported: simple CSV export
export savecsv
using FinEtools.MeshExportModule: NASTRANExporter, close, CEND, BEGIN_BULK, ENDDATA, GRID, PSOLID, MAT1, CTETRA
# Exported: NASTRAN  export
export NASTRANExporter, close, CEND, BEGIN_BULK, ENDDATA, GRID, PSOLID, MAT1, CTETRA
using FinEtools.MeshExportModule: STLExporter, solid, facet, endsolid
# Exported: STL export
export STLExporter, solid, facet, endsolid
using FinEtools.MeshExportModule: h2libexporttri
# Exported: H2Lib export
export h2libexporttri

using FinEtools.MeshModificationModule: meshboundary,  fusenodes,  compactnodes,  mergemeshes, mergenmeshes, mergenodes,  renumberconn!,  meshsmoothing, mirrormesh, nodepartitioning, interior2boundary, adjgraph, nodedegrees, revcm
# Exported: extraction of boundary, fusing of nodes  and merging of meshes, mesh smoothing,  node partitioning
export  meshboundary,  fusenodes,  compactnodes,  mergemeshes, mergenmeshes, mergenodes,  renumberconn!,  meshsmoothing, mirrormesh, nodepartitioning, interior2boundary, adjgraph, nodedegrees, revcm

using FinEtools.MeshImportModule: import_NASTRAN, import_ABAQUS
# Exported: mesh import functions
export import_NASTRAN, import_ABAQUS

using FinEtools.VectorCacheModule: VectorCache, updateretrieve!
# Exported: vector-cache type and methods to invoke the update callback
export VectorCache, updateretrieve!

using FinEtools.ForceIntensityModule: ForceIntensity, updateforce!
# Exported: force-intensity type and methods to invoke the update callback
export ForceIntensity, updateforce!

using FinEtools.SurfaceNormalModule: SurfaceNormal, updatenormal!
# Exported: surface-normal evaluator type and methods to invoke the update callback
export SurfaceNormal, updatenormal!

using FinEtools.AssemblyModule: SysmatAssemblerBase, SysmatAssemblerSparse, SysmatAssemblerSparseSymm, SysmatAssemblerSparseHRZLumpingSymm, startassembly!, assemble!, makematrix!, SysvecAssemblerBase, SysvecAssembler, startassembly!, assemble!, makevector!
# Exported: types and methods for  sparse matrix assembly  and vector assembly
export SysmatAssemblerBase, SysmatAssemblerSparse, SysmatAssemblerSparseSymm, SysmatAssemblerSparseHRZLumpingSymm, startassembly!, assemble!, makematrix!, SysvecAssemblerBase, SysvecAssembler, startassembly!, assemble!, makevector!

using FinEtools.IntegRuleModule: IntegRule, TriRule, GaussRule, TetRule, PointRule, SimplexRule, TrapezoidalRule, NodalSimplexRule
# Exported: type for various integration rules
export IntegRule, TriRule, GaussRule, TetRule, PointRule, SimplexRule, TrapezoidalRule, NodalSimplexRule

using FinEtools.IntegDomainModule: IntegDomain, otherdimensionunity, Jacobianpoint, Jacobiancurve, Jacobiansurface, Jacobianvolume, Jacobianmdim, integrationdata
# Exported: type to handle  integration data for various manifold dimensions
export IntegDomain, otherdimensionunity, Jacobianpoint, Jacobiancurve, Jacobiansurface, Jacobianvolume, Jacobianmdim, integrationdata

using FinEtools.FEMMBaseModule: FEMMAbstractBase, FEMMBase, associategeometry!, integratefieldfunction, integratefunction, transferfield!, distribloads, connectionmatrix, fieldfromintegpoints, elemfieldfromintegpoints, innerproduct
# Exported: type base discretization methods
export FEMMAbstractBase, FEMMBase, associategeometry!, integratefieldfunction, integratefunction, transferfield!, distribloads, connectionmatrix, fieldfromintegpoints, elemfieldfromintegpoints, innerproduct

###########################################################################
# Mesh-generation functionality for various shapes
###########################################################################
using FinEtools.MeshQuadrilateralModule: Q4annulus, Q4quadrilateral, Q4elliphole, Q4block, Q4blockx, Q4refine, Q8block, Q4toQ8, Q8annulus, Q8blockx, Q4spheren, Q4circlen
# Exported: mesh generation functions for quadrilateral elements
export Q4annulus, Q4quadrilateral, Q4elliphole, Q4block, Q4blockx, Q4refine, Q8block, Q4toQ8, Q8annulus, Q8blockx, Q4spheren, Q4circlen

using FinEtools.MeshLineModule: L2block, L2blockx, L3blockx
# Exported: mesh generation functions for line elements
export L2block, L2blockx, L3blockx

using FinEtools.MeshTriangleModule: T3blockx, T3block,  T3toT6,  T6block,  Q4toT3,  T3refine, T6blockx, T3annulus, T6annulus
# Exported: mesh generation functions for triangular elements
export  T3blockx, T3block,  T3toT6,  T6block,  Q4toT3,  T3refine, T6blockx, T3annulus, T6annulus

using FinEtools.MeshHexahedronModule: H8block,  H8blockx,  H8sphere,  H8refine, H8hexahedron, H8extrudeQ4, H8spheren, H8voximg,  H8layeredplatex, H8elliphole, H8toH27,  H27block, H20block,  H8toH20, H20blockx, H27blockx, H8cylindern
# Exported: mesh generation functions for hexahedral elements
export  H8block,  H8blockx,  H8sphere,  H8refine, H8hexahedron, H8extrudeQ4, H8spheren, H8voximg,  H8layeredplatex, H8elliphole, H8toH27,  H27block, H20block,  H8toH20, H20blockx, H27blockx, H8cylindern

using FinEtools.MeshTetrahedronModule: T4block, T4blockx, T4toT10, T10toT4, T10block, T10blockx, T10layeredplatex, T4meshedges, T4voximg, T4refine, T10refine
# Exported: mesh generation functions for tetrahedral elements
export  T4block, T4blockx, T4toT10, T10toT4, T10block, T10blockx, T10layeredplatex, T4meshedges, T4voximg, T4refine, T10refine

using FinEtools.VoxelBoxModule: VoxelBoxVolume, voxeldims, size, fillvolume!, fillsolid!,  intersectionop, unionop, complementop, differenceop,  solidsphere, solidhalfspace, solidbox, solidcylinder, trim, pad, threshold,  vtkexport
# Exported: type for voxel-box data structure, query methods
export VoxelBoxVolume, voxeldims, size
# Exported: methods to set voxel values to generate geometry
export fillvolume!, fillsolid!,  intersectionop, unionop, complementop,differenceop,  solidsphere, solidhalfspace, solidbox, solidcylinder
# Exported: methods for  manipulation and visualization  of voxel boxes
export trim, pad, threshold,  vtkexport

using FinEtools.VoxelTetMeshingModule: ElementSizeWeightFunction, ImageMesher, mesh!, volumes
# Exported: type for the image mesher, type for control of element size gradation, method for generating  the mesh and queries
export ImageMesher, ElementSizeWeightFunction, mesh!, volumes

###########################################################################
# Heat diffusion functionality
###########################################################################
using FinEtools.MatHeatDiffModule: MatHeatDiff
# Exported: type of heat-diffusion  material
export MatHeatDiff

using FinEtools.FEMMHeatDiffModule: FEMMHeatDiff, conductivity, nzebcloadsconductivity, energy, inspectintegpoints
# Exported: type  for linear heat diffusion and discretization methods
export FEMMHeatDiff, conductivity, nzebcloadsconductivity, energy, inspectintegpoints

using FinEtools.FEMMHeatDiffSurfModule: FEMMHeatDiffSurf, surfacetransfer, surfacetransferloads, nzebcsurfacetransferloads
# Exported: type  for linear heat diffusion boundary conditions and discretization methods
export FEMMHeatDiffSurf, surfacetransfer, surfacetransferloads, nzebcsurfacetransferloads

###########################################################################
# Acoustics functionality
###########################################################################
using FinEtools.MatAcoustFluidModule: MatAcoustFluid
# Exported: type of acoustic fluid material
export MatAcoustFluid

using FinEtools.FEMMAcoustModule: FEMMAcoust, acousticmass, nzebcloadsacousticmass,
acousticstiffness, nzebcloadsacousticstiffness
# Exported: type for linear acoustics  and discretization methods
export FEMMAcoust, acousticmass, nzebcloadsacousticmass,
    acousticstiffness, nzebcloadsacousticstiffness

using FinEtools.FEMMAcoustSurfModule: FEMMAcoustSurf, acousticABC, pressure2resultantforce, pressure2resultanttorque, acousticcouplingpanels
# Exported: type for acoustic absorbing boundary condition  and  transformation matrices from pressure  to resultants
export FEMMAcoustSurf, acousticABC, pressure2resultantforce, pressure2resultanttorque, acousticcouplingpanels

###########################################################################
# Linear deformation functionality
###########################################################################
using FinEtools.DeforModelRedModule: DeforModelRed, DeforModelRed1D, DeforModelRed2DStrain,    DeforModelRed2DStress, DeforModelRed2DAxisymm, DeforModelRed3D, nstressstrain, nthermstrain, stresscomponentmap, Blmat!
# Exported: types  for model reduction in stress analysis
export DeforModelRed, DeforModelRed1D, DeforModelRed2DStrain,    DeforModelRed2DStress, DeforModelRed2DAxisymm, DeforModelRed3D
# Exported: num stresses/strains,  number of thermal strains, and map of  the numbering of stress components
export nstressstrain, nthermstrain, stresscomponentmap
# Exported: strain-displacement matrix  for all model-reduction types
export Blmat!

using FinEtools.MatDeforModule: MatDefor, strain2x2tto3v!, strain3vto2x2t!, strain3x3tto6v!, strain6vto3x3t!, strain9vto3x3t!, strain3x3tto9v!, strain9vto6v!, strain6vto9v!, stress2x2to3v!,  stress3vto2x2t!, stress3vto3x3t!, stress4vto3x3t!, stress6vto3x3t!, stress3x3tto6v!, stress9vto6v!,  stress6vto9v!, rotstressvec
# Exported: abstract type for  models of deformation,  conversion methods  for strain and stress, transformations  of strain and stress
export MatDefor, strain2x2tto3v!, strain3vto2x2t!, strain3x3tto6v!, strain6vto3x3t!, strain9vto3x3t!, strain3x3tto9v!, strain9vto6v!, strain6vto9v!, stress2x2to3v!,  stress3vto2x2t!, stress3vto3x3t!, stress4vto3x3t!, stress6vto3x3t!, stress3x3tto6v!, stress9vto6v!,  stress6vto9v!, rotstressvec

using FinEtools.MatDeforElastIsoModule: MatDeforElastIso
# Exported: type of  isotropic elastic material
export MatDeforElastIso

using FinEtools.MatDeforElastOrthoModule: MatDeforElastOrtho
# Exported: type of orthotropic elastic material
export MatDeforElastOrtho

using FinEtools.FEMMDeforLinearBaseModule: FEMMDeforLinearAbstract, stiffness, nzebcloadsstiffness, thermalstrainloads, mass, inspectintegpoints
# Exported: abstract type for linear information, discretization methods for the abstract type
export FEMMDeforLinearAbstract, stiffness, nzebcloadsstiffness, thermalstrainloads, mass, inspectintegpoints

using FinEtools.FEMMDeforLinearModule: FEMMDeforLinear
# Exported: type for linear deformation
export FEMMDeforLinear

using FinEtools.FEMMDeforWinklerModule: FEMMDeforWinkler, surfacenormalspringstiffness
# Exported: type for distributed-spring support, discretization method
export FEMMDeforWinkler, surfacenormalspringstiffness

using FinEtools.FEMMDeforLinearMSModule: FEMMDeforLinearMSH8, FEMMDeforLinearMST10, stiffness, nzebcloadsstiffness, thermalstrainloads, inspectintegpoints
# Exported: type for mean-strain solid elements, discretization methods
export FEMMDeforLinearMSH8, FEMMDeforLinearMST10, stiffness, nzebcloadsstiffness, thermalstrainloads, inspectintegpoints

using FinEtools.FEMMDeforSurfaceDampingModule: FEMMDeforSurfaceDamping, dampingABC
#Exported: type for surface damping (absorbing boundary conditions)
export FEMMDeforSurfaceDamping, dampingABC

using FinEtools.FEMMDeforLinearNICEModule: FEMMDeforLinearNICEH8, FEMMDeforLinearNICET4, stiffness, nzebcloadsstiffness, thermalstrainloads, inspectintegpoints
# Exported: type for NICE (Nodally-integrated continuum elements) solid elements, discretization methods
export FEMMDeforLinearNICEH8, FEMMDeforLinearNICET4, stiffness, nzebcloadsstiffness, thermalstrainloads, inspectintegpoints

using FinEtools.FEMMDeforLinearESNICEModule: FEMMDeforLinearESNICET4, stiffness, nzebcloadsstiffness, thermalstrainloads, inspectintegpoints
# Exported: type for ESICE (Energy-sampling stabilized nodally-integrated continuum elements) solid elements, discretization methods
export FEMMDeforLinearESNICET4, stiffness, nzebcloadsstiffness, thermalstrainloads, inspectintegpoints
end


text:
using SimpleDirectMediaLayer.LibSDL2
using Test

SDL2_pkg_dir = joinpath(@__DIR__, "..", "..")

@testset "Init+Quit" begin
    # Test that you can init and quit SDL multiple times correctly.
    @test SDL_Init(SDL_INIT_VIDEO) == 0
    SDL_Quit()

    @test SDL_Init(SDL_INIT_VIDEO) == 0
    SDL_Quit()
end

@testset "Window open+close" begin
    @test SDL_Init(SDL_INIT_VIDEO) == 0
    # Create window
    win = SDL_CreateWindow("Hello World!", 100, 100, 300, 400, SDL_WINDOW_HIDDEN)
    @test win != C_NULL

    renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE)
    if get(ENV, "HAS_JOSH_K_SEAL_OF_APPROVAL", "") == "true" && Sys.islinux()
        @test_broken renderer != C_NULL
    else
        @test renderer != C_NULL
    end

    # Close window
    SDL_DestroyWindow(win)

    # Create window again
    win = SDL_CreateWindow("Hello World!", 100, 100, 300, 400, SDL_WINDOW_HIDDEN)
    @test win != C_NULL
    renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE)
    @test renderer != C_NULL

    SDL_Quit()
end

@testset "Window" begin
    @test SDL_Init(SDL_INIT_VIDEO) == 0

    win = SDL_CreateWindow("Hello World!", 100, 100, 300, 400, SDL_WINDOW_HIDDEN)

    # Test get size
    w, h = Ref{Cint}(-1), Ref{Cint}(-1)
    SDL_GetWindowSize(win, w, h)
    @test w[] == 300
    @test h[] == 400

    # Test drawing
    renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE)

    rect = SDL_Rect(1, 1, 50, 50)
    @test SDL_RenderFillRect(renderer, Ref(rect)) == 0

    @testset "Load/Save BMP" begin
        img = SDL_LoadBMP_RW(SDL_RWFromFile(joinpath(SDL2_pkg_dir, "assets/cat.bmp"), "rb"), 1)
        @test img != C_NULL

        img_tex = SDL_CreateTextureFromSurface(renderer, img)
        @test img_tex != C_NULL

        src = SDL_Rect(0,0,0,0)
        @test SDL_RenderCopy(renderer, img_tex, C_NULL, C_NULL) == 0 # Fill the renderer with img
        SDL_RenderPresent(renderer)

        # Save bmp
        tmpFile = tempname()*".bmp"
        @test SDL_SaveBMP_RW(img, SDL_RWFromFile(tmpFile, "w"), 1) == 0

        img2 = SDL_LoadBMP_RW(SDL_RWFromFile(tmpFile, "r"), 1)
        @test img2 != C_NULL

        # Compare the two images
        # Some surfaces must be locked before accessing pixels.
        @test 0 == SDL_LockSurface(img)
        @test 0 == SDL_LockSurface(img2)

        img_surface1 = unsafe_load(img)
        img_surface2 = unsafe_load(img2)

        @test (img_surface1.w, img_surface1.h) == (img_surface2.w, img_surface2.h)

        @test img_surface1.format != C_NULL
        @test img_surface2.format != C_NULL

        # Test pixels are equal
        pxl_format1 = unsafe_load(img_surface1.format)
        numPixelBytes = img_surface1.w * img_surface1.h * pxl_format1.BytesPerPixel
        pixels1 = [unsafe_load(Ptr{UInt8}(img_surface1.pixels), i) for i in 1:numPixelBytes]
        pixels2 = [unsafe_load(Ptr{UInt8}(img_surface2.pixels), i) for i in 1:numPixelBytes]

        @test pixels1 == pixels2

        # Some surfaces must be locked/unlocked while accessing pixels.
        SDL_UnlockSurface(img)
        SDL_UnlockSurface(img2)
    end

    # Close window
    SDL_DestroyWindow(win)
    SDL_Quit()
end


text:
module SimplePSD

# A simple example code to calculate a PSD of a received signal
# This uses AbstractFFTs to compute the FFT here, even though FFTW would be faster

using UHDBindings
using FFTW

"""
Compute the PSD at the given carrier frequency, on the given bandwidth, withe SDR parameters args.
PSD is calculated a the periodogram (square root of the averaged FFT)
Input parameters
- carrierFreq = Carrier frequency (in Hz)
- samplingRate = Desired bandwidth (in Hz)
- gain = desired gain
- args = USRP device argument (ex: "addr=192.168.10.16")
- N : Desired FFT size [Default 1024]
- nbMean : Averaging factor. Number of buffers averaged before computed final result
Output parameters
xAx = Frequency values (Vector{Float})
psd = PSD values at the associated frequencies (Vector{Float})

The result then can be plotted by plot(xAx,10*log10.(psd))

"""
function computePSD(carrierFreq,samplingRate,gain;args="",N=1024,nbMean=32)
	# ----------------------------------------------------
	# --- Physical layer and RF parameters
	# ----------------------------------------------------
	# --- Create the radio object in function
    sdr			= openUHD(carrierFreq,samplingRate,gain,args=args)
	# --- Print the configuration
	print(sdr);
	# We will get complex samples from recv! method
	sig		  = zeros(Complex{Cfloat},N); # Buffer in time domain
	psd       = zeros(Cfloat,N); # Buffer in freq domain
    # ----------------------------------------------------
    # --- Acqusition and frequency domain calculation
    # ----------------------------------------------------
    for _ ∈ 1 : nbMean
        # Populate buffer
        recv!(sig,sdr)
        # Compute FFT
        psd += abs2.(fft(sig))
    end
    # --- Close SDR
    close(sdr)
    # --- Compute freq axis
    freqAx = ((0:N-1)/(N-1) .- 0.5) * samplingRate
    # --- Return tuple (freq,mag)
    return (freqAx, fftshift(psd))
end

end


text:
# include("myscript/test.jl")

function __BLOCK() 	# Foldable Comment Block
	"""
	yay

	"""
	if 0>1 # A Crappy comment block that folds and doesn't end correctly, but can be used inside functions.
	    #~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	    #~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	    #~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	    #~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	    #~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	    #~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	    #~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	    #~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	    #~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	 end # be sure to indent "end", one space will do
	#This ends the above Comment Block

	1#~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	#~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	#~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	#~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	#~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	#~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	#~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	#~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
	#~ Wall of Text Wall of Text Wall of Text Wall of Text Wall of Text
end;				# End of Comment Block

# Insertion Sort from "Introduction to Algorithms", pg 18
function insort!(arr)
	for j = 2 : length(arr)
		key = arr[j]
		i = j - 1
		while i > 0 && arr[i]>key
			arr[i + 1] = arr[i]
			i = i-1
		end
		arr[i + 1]=key
	end
end

# Same Insertion Sort that preserves the original array
function insort(arrorg)
	arr = copy(arrorg)
	for j = 2 : length(arr)
		key = arr[j]
		i = j - 1
		while i > 0 && arr[i] > key
			arr[i + 1] = arr[i]
			i = i - 1
		end
		arr[i + 1]=key
	end
	return arr
end

# Merge Sort pg 31
function msortmerge!(A, p, q, r)
	p = Int(p)
	q = Int(q)
	r = Int(r)
	n1 = q - p + 1
	n2 = r - q
	L = zeros(n1 + 1)
	R = zeros(n2 + 1)

	for i = 1 : n1
		L[i] = A[p + i - 1]
	end
	L[n1 + 1] = Inf

	for i = 1 : n2
		R[i]=A[q + i]
	end
	R[n2 + 1] = Inf

	j = i = 1
	for k = p : r
		if L[i] <= R[j]
			A[k] = L[i]
			i = i + 1
		else
			A[k] = R[j]
			j = j + 1
		end
	end
end

function msort!(A, p::Int = 1, r::Int = length(A))
	p = Int(p)
	r = Int(r)
	if p < r
		q = (p + r) / 2
		q = Int(floor(q))
		msort!(A, p, q)
		msort!(A, q + 1, r)
		msortmerge!(A, p, q, r)
	end
end

for i = 1 : 10
	A = rand(100_000 , 1)
	B = copy(A)
	C = copy(B)
	println("Run ", i)
	@time sort(C, dims = 1)
	@time msort!(A)
	@time insort!(B)
end


text:
seq_intp = SequentialInterpolatedResampling(StrictlyIncreasing(), RegularGrid(0, N, 2))
seq_intp2 = SequentialInterpolatedResampling(StrictlyIncreasing(), RegularGrid(1:1:100))

@test seq_intp isa SequentialInterpolatedResampling
@test seq_intp2 isa SequentialInterpolatedResampling


text:
module MatpowerCases

export
    loadcase, casenames,

    Case, extract_case, Bus, extract_bus, Gen, extract_gen, Branch, extract_branch,
    Gencost, extract_gencost

include("loadcase.jl")
include("brch.jl")
include("bus.jl")
include("gen.jl")
include("gencost.jl")
include("case.jl")

end


text:
# ---
# title: 808. Soup Servings
# id: problem808
# author: Tian Jun
# date: 2020-10-31
# difficulty: Medium
# categories: Dynamic Programming
# link: <https://leetcode.com/problems/soup-servings/description/>
# hidden: true
# ---
#
# There are two types of soup: type A and type B. Initially we have `N` ml of
# each type of soup. There are four kinds of operations:
#
#   1. Serve 100 ml of soup A and 0 ml of soup B
#   2. Serve 75 ml of soup A and 25 ml of soup B
#   3. Serve 50 ml of soup A and 50 ml of soup B
#   4. Serve 25 ml of soup A and 75 ml of soup B
#
# When we serve some soup, we give it to someone and we no longer have it.  Each
# turn, we will choose from the four operations with equal probability 0.25. If
# the remaining volume of soup is not enough to complete the operation, we will
# serve as much as we can.  We stop once we no longer have some quantity of both
# types of soup.
#
# Note that we do not have the operation where all 100 ml's of soup B are used
# first.
#
# Return the probability that soup A will be empty first, plus half the
# probability that A and B become empty at the same time.
#
#
#
#
#
#     **Example:**
#     Input: N = 50
#     Output: 0.625
#     Explanation:
#     If we choose the first two operations, A will become empty first. For the third operation, A and B will become empty at the same time. For the fourth operation, B will become empty first. So the total probability of A becoming empty first plus half the probability that A and B become empty at the same time, is 0.25 * (1 + 1 + 0.5 + 0) = 0.625.
#
#
#
# **Notes:**
#
#   * `0 <= N <= 10^9`.
#   * Answers within `10^-6` of the true value will be accepted as correct.
#
#
## @lc code=start
using LeetCode

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


text:
using MPITestImages
using Test
using Documenter

DocMeta.setdocmeta!(MPITestImages, :DocTestSetup, :(using MPITestImages); recursive=true)

@testset "MPITestImages.jl" begin
  @testset "Doctest" begin
    doctest(MPITestImages; manual = false)
  end
end


text:
push!(ARGS, "../../input_files/dynamic/basin_switching/8GPa/v_switch1.dat")
include("../../Basin.jl")
pop!(ARGS)
push!(ARGS, "../../input_files/dynamic/basin_switching/8GPa/v_switch2.dat")
include("../../Basin.jl")
pop!(ARGS)
push!(ARGS, "../../input_files/dynamic/basin_switching/8GPa/v_switch3.dat")
include("../../Basin.jl")
pop!(ARGS)
push!(ARGS, "../../input_files/dynamic/basin_switching/8GPa/v_switch4.dat")
include("../../Basin.jl")
pop!(ARGS)
push!(ARGS, "../../input_files/dynamic/basin_switching/8GPa/v_switch5.dat")
include("../../Basin.jl")
pop!(ARGS)


text:
# Note that this script can accept some limited command-line arguments, run
# `julia build_tarballs.jl --help` to see a usage message.
using BinaryBuilder

name = "LBFGSB"
version = v"3.0.0"

# Collection of sources required to build LBFGSB
sources = [
    "http://users.iems.northwestern.edu/~nocedal/Software/Lbfgsb.3.0.tar.gz" =>
    "f5b9a1c8c30ff6bcc8df9b5d5738145f4cbe4c7eadec629220e808dcf0e54720",

]

# Bash recipe for building across all platforms
script = raw"""
cd $WORKSPACE/srcdir
cd Lbfgsb.3.0/

cat > Makefile.patch << 'END'
--- Makefile
+++ Makefile
@@ -1,37 +1,30 @@
+VERSION = 3
+
 FC = gfortran
+FFLAGS = -O3 -fPIC -shared -Wall -fbounds-check -g -Wno-uninitialized

-FFLAGS = -O -Wall -fbounds-check -g -Wno-uninitialized
+LIB_SEARCH_PATH = lib

-DRIVER1_77 = driver1.f
-DRIVER2_77 = driver2.f
-DRIVER3_77 = driver3.f
-
-DRIVER1_90 = driver1.f90
-DRIVER2_90 = driver2.f90
-DRIVER3_90 = driver3.f90
+OS := $(shell uname)
+ifeq ($(OS), Linux)
+  SHLIB_EXT := so
+else ifeq ($(OS), Darwin)
+  SHLIB_EXT := dylib
+else
+  SHLIB_EXT := dll
+	LIB_SEARCH_PATH = bin
+endif

 LBFGSB  = lbfgsb.f
 LINPACK = linpack.f
 BLAS    = blas.f
 TIMER   = timer.f

-all :  lbfgsb_77_1 lbfgsb_77_2 lbfgsb_77_3 lbfgsb_90_1 lbfgsb_90_2 lbfgsb_90_3
-
-
-lbfgsb_77_1 : $(DRIVER1_77) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER)
-	$(FC) $(FFLAGS) $(DRIVER1_77) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER) -o x.lbfgsb_77_1
-
-lbfgsb_77_2 : $(DRIVER2_77) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER)
-	$(FC) $(FFLAGS) $(DRIVER2_77) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER) -o x.lbfgsb_77_2
-
-lbfgsb_77_3 : $(DRIVER3_77) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER)
-	$(FC) $(FFLAGS) $(DRIVER3_77) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER) -o x.lbfgsb_77_3
-
-lbfgsb_90_1 : $(DRIVER1_90) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER)
-	$(FC) $(FFLAGS) $(DRIVER1_90) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER) -o x.lbfgsb_90_1
+lbfgsb : $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER)
+	$(FC) $(LDFLAGS) $(FFLAGS) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER) -o liblbfgsb-$(VERSION).$(SHLIB_EXT)

-lbfgsb_90_2 : $(DRIVER2_90) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER)
-	$(FC) $(FFLAGS) $(DRIVER2_90) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER) -o x.lbfgsb_90_2
+all : lbfgsb

-lbfgsb_90_3 : $(DRIVER3_90) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER)
-	$(FC) $(FFLAGS) $(DRIVER3_90) $(LBFGSB) $(LINPACK) $(BLAS) $(TIMER) -o x.lbfgsb_90_3
+install :
+	mkdir -p $(WORKSPACE)/destdir/$(LIB_SEARCH_PATH)
+	cp -f liblbfgsb*$(SHLIB_EXT) $(WORKSPACE)/destdir/$(LIB_SEARCH_PATH)/
END

patch --ignore-whitespace < Makefile.patch

make -j${nproc}
make install

"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = [
    Linux(:i686, libc=:glibc),
    Linux(:x86_64, libc=:glibc),
    Linux(:aarch64, libc=:glibc),
    Linux(:armv7l, libc=:glibc, call_abi=:eabihf),
    Linux(:i686, libc=:musl),
    Linux(:x86_64, libc=:musl),
    Linux(:aarch64, libc=:musl),
    Linux(:armv7l, libc=:musl, call_abi=:eabihf),
    MacOS(:x86_64),
    FreeBSD(:x86_64),
    Windows(:i686),
    Windows(:x86_64)
]

platforms = expand_gcc_versions(platforms)

# The products that we will ensure are always built
products(prefix) = [
    LibraryProduct(prefix, "liblbfgsb", :liblbfgsb)
]

# Dependencies that must be installed before this package can be built
dependencies = [

]

# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies)

max_stars_repo_name: Gnimuc/L-BFGS-B-Builder

max_issues_repo_name: Gnimuc/L-BFGS-B-Builder

max_forks_repo_name: Gnimuc/L-BFGS-B-Builder


text:
using Statistics
using PyPlot
using DataFrames
using Distributed

# Experimental Prediction 1 (section 2.4)
#
# Sgm stands for Bayes Factor Surprise
# Ssh stands for Shannon Surprise
function runExperimentsSingleLearner_First(;
                        nsteps = [1000, 2000],
                        y_hat_centers = [1., 0., 0.5],
                        var_centers = [1., 0.5, 2.],
                        δ_centers = collect(0.:0.1:1.),
                        Δy_hats = [1.],
                        Δvars = [1.],
                        Δδs = [0.1],
                        seeds = [3, 4],
                        sigma = 0.5, changeprobability = 0.05,
                        learnertype = GNas12,
                        Npar = 1, etaleak = 0.1, m = 0.1)

    settings = collect(Iterators.product(nsteps,
                                        seeds,
                                        y_hat_centers,
                                        var_centers,
                                        Δy_hats,
                                        Δvars,
                                        Δδs
                                        )
                                    )

    df = @distributed vcat for setting in settings
        experiment = SurpriseExperiment(sigma = sigma,
                                    changeprobability = changeprobability,
                                    nsteps = setting[1], seed = [setting[2]],
                                    learnertype = learnertype,
                                    Npar = Npar, etaleak = etaleak, m = m
                                    )
        callback = runSingleExperiment(experiment)

        mean_Sgm_positive_s,
        mean_Sgm_negative_s,
        se_Sgm_positive_s,
        se_Sgm_negative_s,
        mean_Ssh_positive_s,
        mean_Ssh_negative_s,
        se_Ssh_positive_s,
        se_Ssh_negative_s = meanSurpriseOverδ(callback,
                                y_hat_center = setting[3],
                                var_center = setting[4],
                                Δy_hat = setting[5],
                                Δvar = setting[6],
                                Δδ = setting[7],
                                δs = δ_centers
                                )

        DataFrame(learnertype = experiment.learnertype,
                learnerparam = experiment.learnerparam,
                sigma = sigma,
                changeprobability = changeprobability,
                nsteps = setting[1],
                seedenvpolicy = experiment.specs.seedenvpolicy[1],
                seedlearner = experiment.specs.seedlearner[1],
                y_hat_center = setting[3],
                var_center = setting[4],
                Δy_hat = setting[5],
                Δvar = setting[6],
                Δδ = setting[7],
                δs = [δ_centers],
                mean_Sgm_positive_s = [mean_Sgm_positive_s],
                mean_Sgm_negative_s = [mean_Sgm_negative_s],
                se_Sgm_positive_s = [se_Sgm_positive_s],
                se_Sgm_negative_s = [se_Sgm_negative_s],
                mean_Ssh_positive_s = [mean_Ssh_positive_s],
                mean_Ssh_negative_s = [mean_Ssh_negative_s],
                se_Ssh_positive_s = [se_Ssh_positive_s],
                se_Ssh_negative_s = [se_Ssh_negative_s]
                )
            end
    df
end
function getExperimentQuantities_first(callback)
    y_t = callback.state_history[3:end]
    y_hat_t = callback.estimated_history[2:end-1]
    var_hat_t = callback.var_history[2:end-1]
    Sgm_t = callback.Sgm_history[3:end]
    Ssh_t = callback.Ssh_history[3:end]

    δ_t = y_t - y_hat_t
    s_t = sign.(δ_t .* y_hat_t)

    y_t, y_hat_t, var_hat_t, δ_t, s_t, Sgm_t, Ssh_t
end
function getpositivenegativeSurprise(indices, Surprise_t, s_t)
    Surprise_positive_s = Surprise_t[indices .& (s_t .== 1)]
    Surprise_negative_s = Surprise_t[indices .& (s_t .== -1)]

    mean_Surprise_positive_s = mean(Surprise_positive_s)
    mean_Surprise_negative_s = mean(Surprise_negative_s)

    se_Surprise_positive_s = std(Surprise_positive_s) /
                            sqrt(length(Surprise_positive_s))
    se_Surprise_negative_s = std(Surprise_negative_s) /
                            sqrt(length(Surprise_negative_s))

    mean_Surprise_positive_s, mean_Surprise_negative_s, se_Surprise_positive_s, se_Surprise_negative_s
end
function getconditionedSurprise_first(callback;
                        y_hat_center = 1.,
                        var_center = 1.,
                        δ_cent = 0.3,
                        Δy_hat = 1.,
                        Δvar = 1.,
                        Δδ = 0.05
                        )

    y_t, y_hat_t, var_hat_t, δ_t, s_t, Sgm_t, Ssh_t = getExperimentQuantities_first(callback)

    indices = ((abs.(abs.(y_hat_t) .- y_hat_center) .<= Δy_hat)
                .&
                (abs.(var_hat_t .- var_center) .<= Δvar)
                .&
                (abs.(abs.(δ_t) .- δ_cent) .<= Δδ)
                )
    mean_Sgm_positive_s,
    mean_Sgm_negative_s,
    se_Sgm_positive_s,
    se_Sgm_negative_s = getpositivenegativeSurprise(indices, Sgm_t, s_t)

    mean_Ssh_positive_s,
    mean_Ssh_negative_s,
    se_Ssh_positive_s,
    se_Ssh_negative_s = getpositivenegativeSurprise(indices, Ssh_t, s_t)

    mean_Sgm_positive_s, mean_Sgm_negative_s, se_Sgm_positive_s, se_Sgm_negative_s,
    mean_Ssh_positive_s, mean_Ssh_negative_s, se_Ssh_positive_s, se_Ssh_negative_s
end
function meanSurpriseOverδ(callback;
                        y_hat_center = 1.,
                        var_center = 1.,
                        Δy_hat = 1.,
                        Δvar = 1.,
                        Δδ = 0.05,
                        δs = collect(0.:0.1:1.))

    mean_Sgm_positive_s = zeros(length(δs))
    mean_Sgm_negative_s = zeros(length(δs))
    se_Sgm_positive_s = zeros(length(δs))
    se_Sgm_negative_s = zeros(length(δs))
    mean_Ssh_positive_s = zeros(length(δs))
    mean_Ssh_negative_s = zeros(length(δs))
    se_Ssh_positive_s = zeros(length(δs))
    se_Ssh_negative_s = zeros(length(δs))

    for i in 1:length(δs)
        mean_Sgm_positive_s[i],
        mean_Sgm_negative_s[i],
        se_Sgm_positive_s[i],
        se_Sgm_negative_s[i],
        mean_Ssh_positive_s[i],
        mean_Ssh_negative_s[i],
        se_Ssh_positive_s[i],
        se_Ssh_negative_s[i] = getconditionedSurprise_first(callback,
                                                δ_cent = δs[i],
                                                Δδ = Δδ,
                                                y_hat_center = y_hat_center,
                                                var_center = var_center,
                                                Δy_hat = Δy_hat,
                                                Δvar = Δvar)
    end

    mean_Sgm_positive_s, mean_Sgm_negative_s, se_Sgm_positive_s, se_Sgm_negative_s,
    mean_Ssh_positive_s, mean_Ssh_negative_s, se_Ssh_positive_s, se_Ssh_negative_s
end


text:
type ApproxDistinct <: ContinuousUnivariateStreamStat
    counter::HyperLogLog
    n::Int
end

ApproxDistinct() = ApproxDistinct(HyperLogLog(16), 0)

function update!(stat::ApproxDistinct, x::Any)
    stat.n += 1

    update!(stat.counter, x)

    return
end

state(stat::ApproxDistinct) = state(stat.counter)

nobs(stat::ApproxDistinct) = stat.n

Base.copy(stat::ApproxDistinct) = ApproxDistinct(copy(stat.counter), 0)

# function Base.merge(a::ApproxDistinct, b::ApproxDistinct)
#     TODO
# end

function Base.empty!(stat::ApproxDistinct)
    stat.counter = HyperLogLog(16)
    stat.n = 0
    return
end

function Base.show(io::IO, stat::ApproxDistinct)
    d = state(stat)
    n = nobs(stat)
    @printf(io, "Online Count Distinct\n")
    @printf(io, " * Approx Count Distinct: %f\n", d)
    @printf(io, " * N:                     %d\n", n)
    return
end


text:
# This file was generated, do not modify it. # hide
unwanted = [:lesion_1, :lesion_2, :lesion_3]
data = vcat(data_train, data_test)
select!(data, Not(unwanted));


text:
# pass test

function prepare_input(input_size)
	return zeros(input_size,1)
end

function test_function(input_data)
	return input_data
end


text:
# This file is a part of project JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/Materials.jl/blob/master/LICENSE

using Documenter
using Materials

deploydocs(
    deps = Deps.pip("mkdocs", "python-markdown-math"),
    repo = "github.com/JuliaFEM/Materials.jl.git")


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

using Markdown
using InteractiveUtils

# ╔═╡ 202da520-9e3e-406a-8185-9002574303ed
begin
    using Colors, DataFrames
end

# ╔═╡ 2bd744aa-c92a-11eb-0b7d-4fdd302c6272
begin
	# These colors are from https://allisonhorst.github.io/palmerpenguins/
	adeliecolor = colorant"#FC7808"
	chinstrapcolor = colorant"#8C00EC"
	gentoocolor = colorant"#107A78"
	originals = DataFrame(measured=[adeliecolor, chinstrapcolor, gentoocolor])
end

# ╔═╡ 0a488b60-1699-48b9-b95d-057fc4e4ffac

# ╔═╡ c8e05624-082c-4bb3-ac57-86e63e1376b9
colorant"chocolate1"

# ╔═╡ 7d1d633a-82f8-46f6-90ce-18af1e9ecfc3
colorant"#FC7808"

# ╔═╡ 1de7161b-f80a-43f9-8a4a-a960d4bf0517
DataFrame(measured=[adeliecolor, chinstrapcolor, gentoocolor])

# ╔═╡ 77fa1d35-7679-457b-bb95-cc0dbcee97ce
parse(Colorant, "DeepSkyBlue")

# ╔═╡ af118468-db14-4616-b93e-5799ec71a731

# ╔═╡ 75211344-1f60-4b3d-a4fe-04a490d32b95

# ╔═╡ 501aa5f5-e65a-46da-b5c2-b389cd0cb97a

# ╔═╡ 2de3e22e-754d-45a3-85df-8b18648b9df3

# ╔═╡ a89c9e5f-7a99-4c54-89a9-3646678715b1

# ╔═╡ 567d7650-97d0-44b5-8e54-09a84116f1f9

# ╔═╡ 67f6a601-3351-48b2-8dba-db4199a706d9

# ╔═╡ 07b6918b-1bd3-4d25-9366-a42dbee255ce

# ╔═╡ a62bcdb4-3b13-4152-b150-68afa502d7b2
function compare_colors(color_a, color_b)
    return colordiff(color_a, color_b)
end

# ╔═╡ dc3c36c5-a9a7-4582-b354-0a89a25b73d2
function getdistances(col::Color, acols)
    dists = Float64[]
    for (n, color) in enumerate(acols)
        push!(dists, compare_colors(col, color))
    end
    return sortperm(dists)
end

# ╔═╡ aea259b0-0e30-45f1-88a7-0663a908bd66
function convertcolorvalues(c)
   if typeof(c) == Tuple{Int64, Int64, Int64}
        convertedcolor = RGB{Float64}(c[1]/256, c[2]/256, c[3]/256)
   else
        convertedcolor = convert(RGB{Float64}, c)
   end
   return convertedcolor
end

# ╔═╡ c4b83cf0-5c1f-4a05-b14a-9b5480e1c4fc
namedcolnames  = collect(keys(Colors.color_names))

# ╔═╡ efb8e262-949d-4fba-a3bd-465603f6a620
namedcolvalues = map(convertcolorvalues, collect(values(Colors.color_names)))

# ╔═╡ a193eb78-91a8-49cd-b873-08e96a19b510
@show nearest10 = namedcolnames[getdistances(colorant"#FC7808", namedcolvalues)][1:10]

# ╔═╡ 4ae33a47-f8d9-46cf-83a8-df1429a4dc03
parse.(Colorant, nearest10)

# ╔═╡ 3249c965-790c-473e-981e-44fe4285d492

# ╔═╡ 1ae6176e-f881-43a6-8b6a-fa9da44b1245

# ╔═╡ 50b32008-2902-4b63-addd-65d2899121c3

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"

[compat]
Colors = "~0.12.8"
DataFrames = "~1.2.0"
"""

# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised

[[ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"

[[Artifacts]]
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"

[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "024fe24d83e4a5bf5fc80501a314ce0d1aa35597"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.11.0"

[[Colors]]
deps = ["ColorTypes", "FixedPointNumbers", "Reexport"]
git-tree-sha1 = "417b0ed7b8b838aa6ca0a87aadf1bb9eb111ce40"
uuid = "5ae59095-9a9b-59fe-a467-6f913c188581"
version = "0.12.8"

[[Compat]]
deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"]
git-tree-sha1 = "dc7dedc2c2aa9faf59a55c622760a25cbefbe941"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.31.0"

[[Crayons]]
git-tree-sha1 = "3f71217b538d7aaee0b69ab47d9b7724ca8afa0d"
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
version = "4.0.4"

[[DataAPI]]
git-tree-sha1 = "ee400abb2298bd13bfc3df1c412ed228061a2385"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.7.0"

[[DataFrames]]
deps = ["Compat", "DataAPI", "Future", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrettyTables", "Printf", "REPL", "Reexport", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"]
git-tree-sha1 = "1dadfca11c0e08e03ab15b63aaeda55266754bad"
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
version = "1.2.0"

[[DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "4437b64df1e0adccc3e5d1adbc3ac741095e4677"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.9"

[[DataValueInterfaces]]
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
version = "1.0.0"

[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[DelimitedFiles]]
deps = ["Mmap"]
uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"

[[Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[Downloads]]
deps = ["ArgTools", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"

[[FixedPointNumbers]]
deps = ["Statistics"]
git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc"
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
version = "0.8.4"

[[Formatting]]
deps = ["Printf"]
git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8"
uuid = "59287772-0a20-5a39-b81b-1366585eb4c0"
version = "0.4.2"

[[Future]]
deps = ["Random"]
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"

[[InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

[[InvertedIndices]]
deps = ["Test"]
git-tree-sha1 = "15732c475062348b0165684ffe28e85ea8396afc"
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
version = "1.0.0"

[[IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"

[[LibCURL_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"

[[LibGit2]]
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"

[[LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"

[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"

[[Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "4ea90bd5d3985ae1f9a908bd4500ae88921c5ce7"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.0"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"

[[MozillaCACerts_jll]]
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"

[[NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"

[[OrderedCollections]]
git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.4.1"

[[Pkg]]
deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[PooledArrays]]
deps = ["DataAPI", "Future"]
git-tree-sha1 = "cde4ce9d6f33219465b55162811d8de8139c0414"
uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
version = "1.2.1"

[[PrettyTables]]
deps = ["Crayons", "Formatting", "Markdown", "Reexport", "Tables"]
git-tree-sha1 = "0d1245a357cc61c8cd61934c07447aa569ff22e6"
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
version = "1.1.0"

[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[[REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[Reexport]]
git-tree-sha1 = "5f6c21241f0f655da3952fd60aa18477cf96c220"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.1.0"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"

[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

[[SortingAlgorithms]]
deps = ["DataStructures"]
git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508"
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
version = "1.0.1"

[[SparseArrays]]
deps = ["LinearAlgebra", "Random"]
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[Statistics]]
deps = ["LinearAlgebra", "SparseArrays"]
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[[TOML]]
deps = ["Dates"]
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

[[TableTraits]]
deps = ["IteratorInterfaceExtensions"]
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"

[[Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "TableTraits", "Test"]
git-tree-sha1 = "8ed4a3ea724dac32670b062be3ef1c1de6773ae8"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.4.4"

[[Tar]]
deps = ["ArgTools", "SHA"]
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"

[[Test]]
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[[Zlib_jll]]
deps = ["Libdl"]
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"

[[nghttp2_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"

[[p7zip_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
"""

# ╔═╡ Cell order:
# ╠═202da520-9e3e-406a-8185-9002574303ed
# ╠═2bd744aa-c92a-11eb-0b7d-4fdd302c6272
# ╠═0a488b60-1699-48b9-b95d-057fc4e4ffac
# ╠═a193eb78-91a8-49cd-b873-08e96a19b510
# ╠═4ae33a47-f8d9-46cf-83a8-df1429a4dc03
# ╠═c8e05624-082c-4bb3-ac57-86e63e1376b9
# ╠═7d1d633a-82f8-46f6-90ce-18af1e9ecfc3
# ╠═1de7161b-f80a-43f9-8a4a-a960d4bf0517
# ╠═77fa1d35-7679-457b-bb95-cc0dbcee97ce
# ╠═af118468-db14-4616-b93e-5799ec71a731
# ╠═75211344-1f60-4b3d-a4fe-04a490d32b95
# ╠═501aa5f5-e65a-46da-b5c2-b389cd0cb97a
# ╠═2de3e22e-754d-45a3-85df-8b18648b9df3
# ╠═a89c9e5f-7a99-4c54-89a9-3646678715b1
# ╠═567d7650-97d0-44b5-8e54-09a84116f1f9
# ╠═67f6a601-3351-48b2-8dba-db4199a706d9
# ╠═07b6918b-1bd3-4d25-9366-a42dbee255ce
# ╠═a62bcdb4-3b13-4152-b150-68afa502d7b2
# ╠═dc3c36c5-a9a7-4582-b354-0a89a25b73d2
# ╠═aea259b0-0e30-45f1-88a7-0663a908bd66
# ╠═c4b83cf0-5c1f-4a05-b14a-9b5480e1c4fc
# ╠═efb8e262-949d-4fba-a3bd-465603f6a620
# ╠═3249c965-790c-473e-981e-44fe4285d492
# ╠═1ae6176e-f881-43a6-8b6a-fa9da44b1245
# ╠═50b32008-2902-4b63-addd-65d2899121c3
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_name: StatisticalMice/julia-tutorials

max_issues_repo_name: StatisticalMice/julia-tutorials

max_forks_repo_name: StatisticalMice/julia-tutorials


text:
include("transformation_types.jl");
include("param_types.jl")

"""
	$(SIGNATURES)

Usually stores transformed values and bounds of the transformation.
`startIdx` refers to the start index in the `Vector{Float}` for all `ModelObject`s.
"""
mutable struct ParamInfo{T}
    pName :: Symbol
    startIdx :: Int
    # valueV :: T
    lbV :: T
    ubV :: T
end

mutable struct ValueVector{F1}
    d :: OrderedDict{Symbol, ParamInfo}
end

"""
	$(SIGNATURES)

Object that holds vectorized version of calibrated parameter values.
This can be passed into numerical optimizers.
Also stores the name of the `Param` for each entry. This ensures that going back from vector to `Dict` is correct.
"""
mutable struct Guess{T <: Real}
    d :: OrderedDict{ObjectId, ValueVector{T}}
end

# -----------


text:
""" Advent of Code 2021 day 23, stripped puzzle input of outer # shell at start """

data23 = """
 ...........
 ##D#A#C#C##
 ##D#A#B#B##
 """

insertstring = """##D#C#B#A##\n##D#B#A#C##"""

targetstring = """
...........
##A#B#C#D##
##A#B#C#D##
"""

C = CartesianIndex{2}

function printmat(m)
    println("#"^13)
    for i in 1:size(m, 1)
        println("#", join(m[i, begin:end]), "#")
    end
    return println("#"^13, "\n")
end

function day23(part1=true)
    nrows, ncols = 3, 11
    nrgmax = part1 ? 19_100 : 48_350

    function readmat(s, r=nrows, c=ncols)
        mat = Matrix{Char}(undef, r, c)
        lines = split(s, "\n")
        for (i, line) in enumerate(lines[begin:(begin + r - 1)])
            length(line) < c && (line = rpad(line, c))
            mat[i, :] .= collect(line)
        end
        return mat
    end

    original = readmat(data23)
    target = readmat(targetstring)
    if !part1
        nrows = 5
        original = vcat(original[1:3, :], original[2:3, :])
        original[3, :] .= collect(insertstring[1:11])
        original[4, :] .= collect(insertstring[13:23])
        target = [target[1:3, :]; target[2:3, :]]
    end

    amphitypes = ['A', 'B', 'C', 'D']
    energy = Dict('A' => 1, 'B' => 10, 'C' => 100, 'D' => 1000)
    destcol = Dict('A' => 3, 'B' => 5, 'C' => 7, 'D' => 9)
    function allnotinplace(mat)
        ret = C[]
        for col in [3, 5, 7, 9], row in 2:nrows
            a = mat[row, col]
            a ∉ amphitypes && continue
            if col != destcol[a] || (row < nrows && any(mat[(row + 1):nrows, col] .!= a))
                push!(ret, C(row, col))
            end
        end
        append!(ret, [C(1, col) for col in 1:ncols if mat[1, col] != '.'])
        return ret
    end
    function movecost(mat, c1, c2)
        a, x1, y1, x2, y2 = mat[c1], c1[1], c1[2], c2[1], c2[2]
        return energy[a] * (y1 == y2 ? abs(x1 - x2) : abs(y1 - y2) + x1 + x2 - 2)
    end
    function homeready(mat, a, top=1)
        dcol = destcol[a]
        return top < nrows &&
               all(b -> b ∈ [a, '.'], mat[top:nrows, dcol]) &&
               any(mat[top:nrows, dcol] .== '.') &&
               issorted(mat[top:nrows, dcol])
    end
    function goalmove(mat, c)
        a, x, y = mat[c], c[1], c[2]
        a ∉ amphitypes && return nothing
        dcol = destcol[a]
        d = sign(dcol - y)
        drow = findlast(mat[1:nrows, dcol] .== '.')
        drow == nothing && return nothing
        if d == 0 && homeready(mat, a, x + 1) ||
            d != 0 &&
           homeready(mat, a) &&
           all(mat[1, (y + d):d:dcol] .== '.') &&
           (x == 1 || all(mat[1:(x - 1), y] .== '.'))
            return C(drow, dcol)
        end
        return nothing
    end

    function allmoves(omat=deepcopy(original))
        positions = [(omat, 0)]
        wins = Int[]
        while !isempty(positions)
            newpositions = empty(positions)
            for p in positions
                mat, cost = p
                cost > nrgmax && continue
                if mat == target
                    push!(wins, cost)
                    continue
                end
                notinplace, newmat, newcost = allnotinplace(mat), deepcopy(mat), 0
                for prev in notinplace
                    if (c = goalmove(newmat, prev)) != nothing
                        a, x, y = newmat[prev], prev[1], prev[2]
                        @assert newmat[c] == '.' && a ∈ amphitypes
                        newmat[prev], newmat[c] = newmat[c], newmat[prev]
                        newcost += movecost(mat, prev, c)
                    end
                end
                if newcost > 0
                    push!(newpositions, (newmat, cost + newcost))
                else
                    for prev in notinplace
                        a, x, y = mat[prev], prev[1], prev[2]
                        if x > 1 && all(mat[1:(x - 1), y] .== '.')
                            for col in [1, 2, 4, 6, 8, 10, 11]
                                if all(mat[1, y:sign(col - y):col] .== '.')
                                    c = C(1, col)
                                    @assert mat[c] == '.' && a ∈ amphitypes
                                    newmat = deepcopy(mat)
                                    newmat[prev] = mat[c]
                                    newmat[c] = mat[prev]
                                    push!(
                                        newpositions,
                                        (newmat, cost + movecost(mat, prev, c)),
                                    )
                                end
                            end
                        end
                    end
                end
            end
            positions = newpositions
        end
        return minimum(wins)
    end

    return allmoves()
end

part = [day23(), day23(false)]

println("Part 1: ", part[1]) # 19046
println("Part 2: ", part[2]) # 47484


text:
function myfunc()
    Plots.plot([1:100 1:100]);
    for i = 1:1000
        Plots.plot!([1:100 1:100]);
    end
end


text:
using Test

function test_grad(turing_model, grad_f; trans=Dict())
    model_f = turing_model()
    vi = model_f()
    for i in trans
        vi.flags["trans"][i] = true
    end
    d = length(vi.vals)
    @testset "Gradient using random inputs" begin
        for _ = 1:10000
            theta = rand(d)
            @test Turing.gradient_logp(TrackerAD(), theta, vi, model_f) == grad_f(theta)[2]
        end
    end
end


text:
@testset "Invariantizing embeddings" begin
    pos = [1, 2, 3, 3]
    lags = [1, -1, -1, 0]
    E1 = cembed([diff(rand(30)) for i = 1:4], pos, lags)
    E2 = cembed([diff(rand(1:10, 30)) for i = 1:4], pos, lags)
    inv_E1 = invariantize(E1)
    @test typeof(inv_E1) == LinearlyInvariantEmbedding{4, Float64}
end

@testset "Invariantizing points" begin
    pos = [1, 2, 3, 3]
    lags = [1, -1, -1, 0]
    pts = rand(3, 30)
    inv_pts = invariantize(pts)
    @test forwardlinearmap_invariant(inv_pts) == true
end

# Use Simplices.SimplexSplitting until the splitting routines are re-implemented
# for the column-wise approach
import Simplices.SimplexSplitting.refine_triangulation

"""
    canonical_simplex(dim; split_factor = 1)

Returns a tuple containing the vertices
"""
function canonical_simplex(dim; split_factor = 1)
    canonical_simplex_vertices = zeros(dim + 1, dim)
    canonical_simplex_vertices[2:(dim+1), :] = Matrix(1.0I, dim, dim)
    simplex_indices = zeros(Int, 1, dim + 1)
    simplex_indices[1, :] = round.(Int, collect(1:dim+1))

    refined = refine_triangulation(canonical_simplex_vertices, simplex_indices, [1], k)
    triang_vertices, triang_simplex_indices = refined[1], refined[2]
end


text:
valueref_spec =
[
	(:value, Any, nothing),
	(:field, Union{AbstractString, Dict{Any,Any}}, nothing),
	(:group, Union{AbstractString, Bool}, nothing),
	(:scale, Union{AbstractString, Dict{Any,Any}}, nothing),
	(:mult, Number, nothing),
	(:offset, Number, nothing),
	(:band, Bool, nothing),
	(:signal, AbstractString, nothing)
]

primitivefactory(:VegaValueRef, valueref_spec)

max_stars_repo_name: jpthor/vega


text:
function calc_boson_action(mc::AbstractDQMC, hsfield::Array{Float64,3}=mc.p.hsfield)
  p = mc.p
  l = mc.l

  S = 0.0

  if !p.edrun
    h = reshape(hsfield, (p.opdim,l.L,l.L,p.slices))

    # temporal gradient
    t = h - circshift(h, (0,0,0,-1))
    S += 0.5/p.delta_tau * 1/p.c^2 * dot(t,t);

    # spatial gradient
    # Count only top and right neighbor (avoid overcounting)
    @inbounds @simd for n in 2:3
      x = zeros(Int, 4)
      x[n] = -1
      t = h - circshift(h, x)
      S += p.delta_tau * 0.5 * dot(t,t);
    end

    # mass term & quartic interaction
    @inbounds @views begin
      @simd for s in 1:p.slices
        @simd for i in 1:l.sites

          squared = dot(hsfield[:,i,s],hsfield[:,i,s])
          S += p.delta_tau * p.r/2.0 * squared;
          S += p.delta_tau * p.u/4.0 * squared * squared;

        end
      end
    end

  else
    # --- ED RUN ---
    # mass term
    @inbounds @views begin
      @simd for s in 1:p.slices
        @simd for i in 1:l.sites

          squared = dot(hsfield[:,i,s],hsfield[:,i,s])
          S += p.delta_tau * p.r/2.0 * squared;

        end
      end
    end
  end

  return S;
end

"""
Calculate Delta_S_boson = S_boson' - S_boson
"""
function calc_boson_action_diff(mc::AbstractDQMC, site::Int, slice::Int, new_op::Vector{Float64})
  p = mc.p
  l = mc.l

  @mytimeit mc.a.to "calc_boson_action_diff" begin
  dS = 0.0

  @inbounds @views begin
    old_op = p.hsfield[:,site,slice]
    diff = new_op - old_op

    old_op_sq = dot(old_op, old_op)
    new_op_sq = dot(new_op, new_op)
    sq_diff = new_op_sq - old_op_sq

    old_op_pow4 = old_op_sq * old_op_sq
    new_op_pow4 = new_op_sq * new_op_sq
    pow4_diff = new_op_pow4 - old_op_pow4

    op_earlier = p.hsfield[:,site,l.time_neighbors[2,slice]]
    op_later = p.hsfield[:,site,l.time_neighbors[1,slice]]
    op_time_neighbors = op_later + op_earlier

    op_space_neighbors = zeros(p.opdim)
    @simd for n in 1:4
      op_space_neighbors += p.hsfield[:,l.neighbors[n,site],slice]
    end

    if !p.edrun
      dS += 1.0/(p.delta_tau * p.c^2)  * (sq_diff - dot(op_time_neighbors, diff));

      dS += 0.5 * p.delta_tau * (4 * sq_diff - 2.0 * dot(op_space_neighbors, diff));

      dS += p.delta_tau * (0.5 * p.r * sq_diff + 0.25 * p.u * pow4_diff);

    else
      # --- ED RUN ---
      dS += p.delta_tau * (0.5 * p.r * sq_diff);
    end
  end

  end #timeit

  return dS
end

max_stars_repo_name: crstnbr/dqmc

max_issues_repo_name: crstnbr/dqmc

max_forks_repo_name: crstnbr/dqmc


text:
# Operators that are diagonal in a dimension can be solved in O(n) operations
# isdiagop is used to inspect an operator to see if it is diagonal

Base.isdiag{T<:Number}(B::Operator{T}) = bandinds(B)==(0,0)

# multivariate case
isdiagop(K::KroneckerOperator,k) = isdiag(K.ops[k])
isdiagop(S::WrapperOperator,k) = isdiagop(S.op,k)
isdiagop(A::Union{PlusOperator,TimesOperator},k) = all(op->isdiagop(op,k),A.ops)

# diagop gets out the op corresponding to the k-th column
# TODO: diag in x direction

diagop(A::KroneckerOperator,col)=A.ops[2]

diagop(A::PlusOperator,col) = mapreduce(op->diagop(op,col),+,A.ops)
diagop(A::TimesOperator,col) = mapreduce(op->diagop(op,col),*,A.ops)
diagop(A::SpaceOperator,col) = diagop(A.op,col)
# TODO: Space for ConstantOperator
diagop(A::ConstantOperator,col) = ConstantOperator(A.c)
diagop(A::ConstantTimesOperator,col) = A.c*diagop(A.op,col)

diagop(L,k)=error("Override diagop for "*string(typeof(L)))