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

"""
    add_attributes_to_findings(attributes, finding_arns)
    add_attributes_to_findings(attributes, finding_arns, params::Dict{String,<:Any})

Assigns attributes (key and value pairs) to the findings that are specified by the ARNs of
the findings.

# Arguments
- `attributes`: The array of attributes that you want to assign to specified findings.
- `finding_arns`: The ARNs that specify the findings that you want to assign attributes to.

"""
add_attributes_to_findings(attributes, findingArns; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("AddAttributesToFindings", Dict{String, Any}("attributes"=>attributes, "findingArns"=>findingArns); aws_config=aws_config)
add_attributes_to_findings(attributes, findingArns, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("AddAttributesToFindings", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("attributes"=>attributes, "findingArns"=>findingArns), params)); aws_config=aws_config)

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

Creates a new assessment target using the ARN of the resource group that is generated by
CreateResourceGroup. If resourceGroupArn is not specified, all EC2 instances in the current
AWS account and region are included in the assessment target. If the service-linked role
isn’t already registered, this action also creates and registers a service-linked role to
grant Amazon Inspector access to AWS Services needed to perform security assessments. You
can create up to 50 assessment targets per AWS account. You can run up to 500 concurrent
agents per AWS account. For more information, see  Amazon Inspector Assessment Targets.

# Arguments
- `assessment_target_name`: The user-defined name that identifies the assessment target
  that you want to create. The name must be unique within the AWS account.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"resourceGroupArn"`: The ARN that specifies the resource group that is used to create
  the assessment target. If resourceGroupArn is not specified, all EC2 instances in the
  current AWS account and region are included in the assessment target.
"""
create_assessment_target(assessmentTargetName; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("CreateAssessmentTarget", Dict{String, Any}("assessmentTargetName"=>assessmentTargetName); aws_config=aws_config)
create_assessment_target(assessmentTargetName, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("CreateAssessmentTarget", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentTargetName"=>assessmentTargetName), params)); aws_config=aws_config)

"""
    create_assessment_template(assessment_target_arn, assessment_template_name, duration_in_seconds, rules_package_arns)
    create_assessment_template(assessment_target_arn, assessment_template_name, duration_in_seconds, rules_package_arns, params::Dict{String,<:Any})

Creates an assessment template for the assessment target that is specified by the ARN of
the assessment target. If the service-linked role isn’t already registered, this action
also creates and registers a service-linked role to grant Amazon Inspector access to AWS
Services needed to perform security assessments.

# Arguments
- `assessment_target_arn`: The ARN that specifies the assessment target for which you want
  to create the assessment template.
- `assessment_template_name`: The user-defined name that identifies the assessment template
  that you want to create. You can create several assessment templates for an assessment
  target. The names of the assessment templates that correspond to a particular assessment
  target must be unique.
- `duration_in_seconds`: The duration of the assessment run in seconds.
- `rules_package_arns`: The ARNs that specify the rules packages that you want to attach to
  the assessment template.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"userAttributesForFindings"`: The user-defined attributes that are assigned to every
  finding that is generated by the assessment run that uses this assessment template. An
  attribute is a key and value pair (an Attribute object). Within an assessment template,
  each key must be unique.
"""
create_assessment_template(assessmentTargetArn, assessmentTemplateName, durationInSeconds, rulesPackageArns; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("CreateAssessmentTemplate", Dict{String, Any}("assessmentTargetArn"=>assessmentTargetArn, "assessmentTemplateName"=>assessmentTemplateName, "durationInSeconds"=>durationInSeconds, "rulesPackageArns"=>rulesPackageArns); aws_config=aws_config)
create_assessment_template(assessmentTargetArn, assessmentTemplateName, durationInSeconds, rulesPackageArns, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("CreateAssessmentTemplate", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentTargetArn"=>assessmentTargetArn, "assessmentTemplateName"=>assessmentTemplateName, "durationInSeconds"=>durationInSeconds, "rulesPackageArns"=>rulesPackageArns), params)); aws_config=aws_config)

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

Starts the generation of an exclusions preview for the specified assessment template. The
exclusions preview lists the potential exclusions (ExclusionPreview) that Inspector can
detect before it runs the assessment.

# Arguments
- `assessment_template_arn`: The ARN that specifies the assessment template for which you
  want to create an exclusions preview.

"""
create_exclusions_preview(assessmentTemplateArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("CreateExclusionsPreview", Dict{String, Any}("assessmentTemplateArn"=>assessmentTemplateArn); aws_config=aws_config)
create_exclusions_preview(assessmentTemplateArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("CreateExclusionsPreview", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentTemplateArn"=>assessmentTemplateArn), params)); aws_config=aws_config)

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

Creates a resource group using the specified set of tags (key and value pairs) that are
used to select the EC2 instances to be included in an Amazon Inspector assessment target.
The created resource group is then used to create an Amazon Inspector assessment target.
For more information, see CreateAssessmentTarget.

# Arguments
- `resource_group_tags`: A collection of keys and an array of possible values,
  '[{\"key\":\"key1\",\"values\":[\"Value1\",\"Value2\"]},{\"key\":\"Key2\",\"values\":[\"Valu
  e3\"]}]'. For example,'[{\"key\":\"Name\",\"values\":[\"TestEC2Instance\"]}]'.

"""
create_resource_group(resourceGroupTags; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("CreateResourceGroup", Dict{String, Any}("resourceGroupTags"=>resourceGroupTags); aws_config=aws_config)
create_resource_group(resourceGroupTags, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("CreateResourceGroup", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("resourceGroupTags"=>resourceGroupTags), params)); aws_config=aws_config)

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

Deletes the assessment run that is specified by the ARN of the assessment run.

# Arguments
- `assessment_run_arn`: The ARN that specifies the assessment run that you want to delete.

"""
delete_assessment_run(assessmentRunArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DeleteAssessmentRun", Dict{String, Any}("assessmentRunArn"=>assessmentRunArn); aws_config=aws_config)
delete_assessment_run(assessmentRunArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DeleteAssessmentRun", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentRunArn"=>assessmentRunArn), params)); aws_config=aws_config)

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

Deletes the assessment target that is specified by the ARN of the assessment target.

# Arguments
- `assessment_target_arn`: The ARN that specifies the assessment target that you want to
  delete.

"""
delete_assessment_target(assessmentTargetArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DeleteAssessmentTarget", Dict{String, Any}("assessmentTargetArn"=>assessmentTargetArn); aws_config=aws_config)
delete_assessment_target(assessmentTargetArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DeleteAssessmentTarget", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentTargetArn"=>assessmentTargetArn), params)); aws_config=aws_config)

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

Deletes the assessment template that is specified by the ARN of the assessment template.

# Arguments
- `assessment_template_arn`: The ARN that specifies the assessment template that you want
  to delete.

"""
delete_assessment_template(assessmentTemplateArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DeleteAssessmentTemplate", Dict{String, Any}("assessmentTemplateArn"=>assessmentTemplateArn); aws_config=aws_config)
delete_assessment_template(assessmentTemplateArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DeleteAssessmentTemplate", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentTemplateArn"=>assessmentTemplateArn), params)); aws_config=aws_config)

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

Describes the assessment runs that are specified by the ARNs of the assessment runs.

# Arguments
- `assessment_run_arns`: The ARN that specifies the assessment run that you want to
  describe.

"""
describe_assessment_runs(assessmentRunArns; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeAssessmentRuns", Dict{String, Any}("assessmentRunArns"=>assessmentRunArns); aws_config=aws_config)
describe_assessment_runs(assessmentRunArns, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeAssessmentRuns", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentRunArns"=>assessmentRunArns), params)); aws_config=aws_config)

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

Describes the assessment targets that are specified by the ARNs of the assessment targets.

# Arguments
- `assessment_target_arns`: The ARNs that specifies the assessment targets that you want to
  describe.

"""
describe_assessment_targets(assessmentTargetArns; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeAssessmentTargets", Dict{String, Any}("assessmentTargetArns"=>assessmentTargetArns); aws_config=aws_config)
describe_assessment_targets(assessmentTargetArns, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeAssessmentTargets", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentTargetArns"=>assessmentTargetArns), params)); aws_config=aws_config)

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

Describes the assessment templates that are specified by the ARNs of the assessment
templates.

# Arguments
- `assessment_template_arns`:

"""
describe_assessment_templates(assessmentTemplateArns; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeAssessmentTemplates", Dict{String, Any}("assessmentTemplateArns"=>assessmentTemplateArns); aws_config=aws_config)
describe_assessment_templates(assessmentTemplateArns, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeAssessmentTemplates", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentTemplateArns"=>assessmentTemplateArns), params)); aws_config=aws_config)

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

Describes the IAM role that enables Amazon Inspector to access your AWS account.

"""
describe_cross_account_access_role(; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeCrossAccountAccessRole"; aws_config=aws_config)
describe_cross_account_access_role(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeCrossAccountAccessRole", params; aws_config=aws_config)

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

Describes the exclusions that are specified by the exclusions' ARNs.

# Arguments
- `exclusion_arns`: The list of ARNs that specify the exclusions that you want to describe.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"locale"`: The locale into which you want to translate the exclusion's title,
  description, and recommendation.
"""
describe_exclusions(exclusionArns; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeExclusions", Dict{String, Any}("exclusionArns"=>exclusionArns); aws_config=aws_config)
describe_exclusions(exclusionArns, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeExclusions", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("exclusionArns"=>exclusionArns), params)); aws_config=aws_config)

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

Describes the findings that are specified by the ARNs of the findings.

# Arguments
- `finding_arns`: The ARN that specifies the finding that you want to describe.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"locale"`: The locale into which you want to translate a finding description,
  recommendation, and the short description that identifies the finding.
"""
describe_findings(findingArns; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeFindings", Dict{String, Any}("findingArns"=>findingArns); aws_config=aws_config)
describe_findings(findingArns, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeFindings", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("findingArns"=>findingArns), params)); aws_config=aws_config)

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

Describes the resource groups that are specified by the ARNs of the resource groups.

# Arguments
- `resource_group_arns`: The ARN that specifies the resource group that you want to
  describe.

"""
describe_resource_groups(resourceGroupArns; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeResourceGroups", Dict{String, Any}("resourceGroupArns"=>resourceGroupArns); aws_config=aws_config)
describe_resource_groups(resourceGroupArns, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeResourceGroups", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("resourceGroupArns"=>resourceGroupArns), params)); aws_config=aws_config)

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

Describes the rules packages that are specified by the ARNs of the rules packages.

# Arguments
- `rules_package_arns`: The ARN that specifies the rules package that you want to describe.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"locale"`: The locale that you want to translate a rules package description into.
"""
describe_rules_packages(rulesPackageArns; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeRulesPackages", Dict{String, Any}("rulesPackageArns"=>rulesPackageArns); aws_config=aws_config)
describe_rules_packages(rulesPackageArns, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("DescribeRulesPackages", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("rulesPackageArns"=>rulesPackageArns), params)); aws_config=aws_config)

"""
    get_assessment_report(assessment_run_arn, report_file_format, report_type)
    get_assessment_report(assessment_run_arn, report_file_format, report_type, params::Dict{String,<:Any})

Produces an assessment report that includes detailed and comprehensive results of a
specified assessment run.

# Arguments
- `assessment_run_arn`: The ARN that specifies the assessment run for which you want to
  generate a report.
- `report_file_format`: Specifies the file format (html or pdf) of the assessment report
  that you want to generate.
- `report_type`: Specifies the type of the assessment report that you want to generate.
  There are two types of assessment reports: a finding report and a full report. For more
  information, see Assessment Reports.

"""
get_assessment_report(assessmentRunArn, reportFileFormat, reportType; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("GetAssessmentReport", Dict{String, Any}("assessmentRunArn"=>assessmentRunArn, "reportFileFormat"=>reportFileFormat, "reportType"=>reportType); aws_config=aws_config)
get_assessment_report(assessmentRunArn, reportFileFormat, reportType, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("GetAssessmentReport", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentRunArn"=>assessmentRunArn, "reportFileFormat"=>reportFileFormat, "reportType"=>reportType), params)); aws_config=aws_config)

"""
    get_exclusions_preview(assessment_template_arn, preview_token)
    get_exclusions_preview(assessment_template_arn, preview_token, params::Dict{String,<:Any})

Retrieves the exclusions preview (a list of ExclusionPreview objects) specified by the
preview token. You can obtain the preview token by running the CreateExclusionsPreview API.

# Arguments
- `assessment_template_arn`: The ARN that specifies the assessment template for which the
  exclusions preview was requested.
- `preview_token`: The unique identifier associated of the exclusions preview.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"locale"`: The locale into which you want to translate the exclusion's title,
  description, and recommendation.
- `"maxResults"`: You can use this parameter to indicate the maximum number of items you
  want in the response. The default value is 100. The maximum value is 500.
- `"nextToken"`: You can use this parameter when paginating results. Set the value of this
  parameter to null on your first call to the GetExclusionsPreviewRequest action. Subsequent
  calls to the action fill nextToken in the request with the value of nextToken from the
  previous response to continue listing data.
"""
get_exclusions_preview(assessmentTemplateArn, previewToken; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("GetExclusionsPreview", Dict{String, Any}("assessmentTemplateArn"=>assessmentTemplateArn, "previewToken"=>previewToken); aws_config=aws_config)
get_exclusions_preview(assessmentTemplateArn, previewToken, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("GetExclusionsPreview", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentTemplateArn"=>assessmentTemplateArn, "previewToken"=>previewToken), params)); aws_config=aws_config)

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

Information about the data that is collected for the specified assessment run.

# Arguments
- `assessment_run_arn`: The ARN that specifies the assessment run that has the telemetry
  data that you want to obtain.

"""
get_telemetry_metadata(assessmentRunArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("GetTelemetryMetadata", Dict{String, Any}("assessmentRunArn"=>assessmentRunArn); aws_config=aws_config)
get_telemetry_metadata(assessmentRunArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("GetTelemetryMetadata", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentRunArn"=>assessmentRunArn), params)); aws_config=aws_config)

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

Lists the agents of the assessment runs that are specified by the ARNs of the assessment
runs.

# Arguments
- `assessment_run_arn`: The ARN that specifies the assessment run whose agents you want to
  list.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"filter"`: You can use this parameter to specify a subset of data to be included in the
  action's response. For a record to match a filter, all specified filter attributes must
  match. When multiple values are specified for a filter attribute, any of the values can
  match.
- `"maxResults"`: You can use this parameter to indicate the maximum number of items that
  you want in the response. The default value is 10. The maximum value is 500.
- `"nextToken"`: You can use this parameter when paginating results. Set the value of this
  parameter to null on your first call to the ListAssessmentRunAgents action. Subsequent
  calls to the action fill nextToken in the request with the value of NextToken from the
  previous response to continue listing data.
"""
list_assessment_run_agents(assessmentRunArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListAssessmentRunAgents", Dict{String, Any}("assessmentRunArn"=>assessmentRunArn); aws_config=aws_config)
list_assessment_run_agents(assessmentRunArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListAssessmentRunAgents", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentRunArn"=>assessmentRunArn), params)); aws_config=aws_config)

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

Lists the assessment runs that correspond to the assessment templates that are specified by
the ARNs of the assessment templates.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"assessmentTemplateArns"`: The ARNs that specify the assessment templates whose
  assessment runs you want to list.
- `"filter"`: You can use this parameter to specify a subset of data to be included in the
  action's response. For a record to match a filter, all specified filter attributes must
  match. When multiple values are specified for a filter attribute, any of the values can
  match.
- `"maxResults"`: You can use this parameter to indicate the maximum number of items that
  you want in the response. The default value is 10. The maximum value is 500.
- `"nextToken"`: You can use this parameter when paginating results. Set the value of this
  parameter to null on your first call to the ListAssessmentRuns action. Subsequent calls to
  the action fill nextToken in the request with the value of NextToken from the previous
  response to continue listing data.
"""
list_assessment_runs(; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListAssessmentRuns"; aws_config=aws_config)
list_assessment_runs(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListAssessmentRuns", params; aws_config=aws_config)

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

Lists the ARNs of the assessment targets within this AWS account. For more information
about assessment targets, see Amazon Inspector Assessment Targets.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"filter"`: You can use this parameter to specify a subset of data to be included in the
  action's response. For a record to match a filter, all specified filter attributes must
  match. When multiple values are specified for a filter attribute, any of the values can
  match.
- `"maxResults"`: You can use this parameter to indicate the maximum number of items you
  want in the response. The default value is 10. The maximum value is 500.
- `"nextToken"`: You can use this parameter when paginating results. Set the value of this
  parameter to null on your first call to the ListAssessmentTargets action. Subsequent calls
  to the action fill nextToken in the request with the value of NextToken from the previous
  response to continue listing data.
"""
list_assessment_targets(; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListAssessmentTargets"; aws_config=aws_config)
list_assessment_targets(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListAssessmentTargets", params; aws_config=aws_config)

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

Lists the assessment templates that correspond to the assessment targets that are specified
by the ARNs of the assessment targets.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"assessmentTargetArns"`: A list of ARNs that specifies the assessment targets whose
  assessment templates you want to list.
- `"filter"`: You can use this parameter to specify a subset of data to be included in the
  action's response. For a record to match a filter, all specified filter attributes must
  match. When multiple values are specified for a filter attribute, any of the values can
  match.
- `"maxResults"`: You can use this parameter to indicate the maximum number of items you
  want in the response. The default value is 10. The maximum value is 500.
- `"nextToken"`: You can use this parameter when paginating results. Set the value of this
  parameter to null on your first call to the ListAssessmentTemplates action. Subsequent
  calls to the action fill nextToken in the request with the value of NextToken from the
  previous response to continue listing data.
"""
list_assessment_templates(; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListAssessmentTemplates"; aws_config=aws_config)
list_assessment_templates(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListAssessmentTemplates", params; aws_config=aws_config)

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

Lists all the event subscriptions for the assessment template that is specified by the ARN
of the assessment template. For more information, see SubscribeToEvent and
UnsubscribeFromEvent.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: You can use this parameter to indicate the maximum number of items you
  want in the response. The default value is 10. The maximum value is 500.
- `"nextToken"`: You can use this parameter when paginating results. Set the value of this
  parameter to null on your first call to the ListEventSubscriptions action. Subsequent calls
  to the action fill nextToken in the request with the value of NextToken from the previous
  response to continue listing data.
- `"resourceArn"`: The ARN of the assessment template for which you want to list the
  existing event subscriptions.
"""
list_event_subscriptions(; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListEventSubscriptions"; aws_config=aws_config)
list_event_subscriptions(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListEventSubscriptions", params; aws_config=aws_config)

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

List exclusions that are generated by the assessment run.

# Arguments
- `assessment_run_arn`: The ARN of the assessment run that generated the exclusions that
  you want to list.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: You can use this parameter to indicate the maximum number of items you
  want in the response. The default value is 100. The maximum value is 500.
- `"nextToken"`: You can use this parameter when paginating results. Set the value of this
  parameter to null on your first call to the ListExclusionsRequest action. Subsequent calls
  to the action fill nextToken in the request with the value of nextToken from the previous
  response to continue listing data.
"""
list_exclusions(assessmentRunArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListExclusions", Dict{String, Any}("assessmentRunArn"=>assessmentRunArn); aws_config=aws_config)
list_exclusions(assessmentRunArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListExclusions", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentRunArn"=>assessmentRunArn), params)); aws_config=aws_config)

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

Lists findings that are generated by the assessment runs that are specified by the ARNs of
the assessment runs.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"assessmentRunArns"`: The ARNs of the assessment runs that generate the findings that
  you want to list.
- `"filter"`: You can use this parameter to specify a subset of data to be included in the
  action's response. For a record to match a filter, all specified filter attributes must
  match. When multiple values are specified for a filter attribute, any of the values can
  match.
- `"maxResults"`: You can use this parameter to indicate the maximum number of items you
  want in the response. The default value is 10. The maximum value is 500.
- `"nextToken"`: You can use this parameter when paginating results. Set the value of this
  parameter to null on your first call to the ListFindings action. Subsequent calls to the
  action fill nextToken in the request with the value of NextToken from the previous response
  to continue listing data.
"""
list_findings(; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListFindings"; aws_config=aws_config)
list_findings(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListFindings", params; aws_config=aws_config)

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

Lists all available Amazon Inspector rules packages.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: You can use this parameter to indicate the maximum number of items you
  want in the response. The default value is 10. The maximum value is 500.
- `"nextToken"`: You can use this parameter when paginating results. Set the value of this
  parameter to null on your first call to the ListRulesPackages action. Subsequent calls to
  the action fill nextToken in the request with the value of NextToken from the previous
  response to continue listing data.
"""
list_rules_packages(; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListRulesPackages"; aws_config=aws_config)
list_rules_packages(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListRulesPackages", params; aws_config=aws_config)

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

Lists all tags associated with an assessment template.

# Arguments
- `resource_arn`: The ARN that specifies the assessment template whose tags you want to
  list.

"""
list_tags_for_resource(resourceArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListTagsForResource", Dict{String, Any}("resourceArn"=>resourceArn); aws_config=aws_config)
list_tags_for_resource(resourceArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("ListTagsForResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("resourceArn"=>resourceArn), params)); aws_config=aws_config)

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

Previews the agents installed on the EC2 instances that are part of the specified
assessment target.

# Arguments
- `preview_agents_arn`: The ARN of the assessment target whose agents you want to preview.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: You can use this parameter to indicate the maximum number of items you
  want in the response. The default value is 10. The maximum value is 500.
- `"nextToken"`: You can use this parameter when paginating results. Set the value of this
  parameter to null on your first call to the PreviewAgents action. Subsequent calls to the
  action fill nextToken in the request with the value of NextToken from the previous response
  to continue listing data.
"""
preview_agents(previewAgentsArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("PreviewAgents", Dict{String, Any}("previewAgentsArn"=>previewAgentsArn); aws_config=aws_config)
preview_agents(previewAgentsArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("PreviewAgents", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("previewAgentsArn"=>previewAgentsArn), params)); aws_config=aws_config)

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

Registers the IAM role that grants Amazon Inspector access to AWS Services needed to
perform security assessments.

# Arguments
- `role_arn`: The ARN of the IAM role that grants Amazon Inspector access to AWS Services
  needed to perform security assessments.

"""
register_cross_account_access_role(roleArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("RegisterCrossAccountAccessRole", Dict{String, Any}("roleArn"=>roleArn); aws_config=aws_config)
register_cross_account_access_role(roleArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("RegisterCrossAccountAccessRole", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("roleArn"=>roleArn), params)); aws_config=aws_config)

"""
    remove_attributes_from_findings(attribute_keys, finding_arns)
    remove_attributes_from_findings(attribute_keys, finding_arns, params::Dict{String,<:Any})

Removes entire attributes (key and value pairs) from the findings that are specified by the
ARNs of the findings where an attribute with the specified key exists.

# Arguments
- `attribute_keys`: The array of attribute keys that you want to remove from specified
  findings.
- `finding_arns`: The ARNs that specify the findings that you want to remove attributes
  from.

"""
remove_attributes_from_findings(attributeKeys, findingArns; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("RemoveAttributesFromFindings", Dict{String, Any}("attributeKeys"=>attributeKeys, "findingArns"=>findingArns); aws_config=aws_config)
remove_attributes_from_findings(attributeKeys, findingArns, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("RemoveAttributesFromFindings", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("attributeKeys"=>attributeKeys, "findingArns"=>findingArns), params)); aws_config=aws_config)

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

Sets tags (key and value pairs) to the assessment template that is specified by the ARN of
the assessment template.

# Arguments
- `resource_arn`: The ARN of the assessment template that you want to set tags to.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"tags"`: A collection of key and value pairs that you want to set to the assessment
  template.
"""
set_tags_for_resource(resourceArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("SetTagsForResource", Dict{String, Any}("resourceArn"=>resourceArn); aws_config=aws_config)
set_tags_for_resource(resourceArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("SetTagsForResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("resourceArn"=>resourceArn), params)); aws_config=aws_config)

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

Starts the assessment run specified by the ARN of the assessment template. For this API to
function properly, you must not exceed the limit of running up to 500 concurrent agents per
AWS account.

# Arguments
- `assessment_template_arn`: The ARN of the assessment template of the assessment run that
  you want to start.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"assessmentRunName"`: You can specify the name for the assessment run. The name must be
  unique for the assessment template whose ARN is used to start the assessment run.
"""
start_assessment_run(assessmentTemplateArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("StartAssessmentRun", Dict{String, Any}("assessmentTemplateArn"=>assessmentTemplateArn); aws_config=aws_config)
start_assessment_run(assessmentTemplateArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("StartAssessmentRun", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentTemplateArn"=>assessmentTemplateArn), params)); aws_config=aws_config)

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

Stops the assessment run that is specified by the ARN of the assessment run.

# Arguments
- `assessment_run_arn`: The ARN of the assessment run that you want to stop.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"stopAction"`: An input option that can be set to either START_EVALUATION or
  SKIP_EVALUATION. START_EVALUATION (the default value), stops the AWS agent from collecting
  data and begins the results evaluation and the findings generation process. SKIP_EVALUATION
  cancels the assessment run immediately, after which no findings are generated.
"""
stop_assessment_run(assessmentRunArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("StopAssessmentRun", Dict{String, Any}("assessmentRunArn"=>assessmentRunArn); aws_config=aws_config)
stop_assessment_run(assessmentRunArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("StopAssessmentRun", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentRunArn"=>assessmentRunArn), params)); aws_config=aws_config)

"""
    subscribe_to_event(event, resource_arn, topic_arn)
    subscribe_to_event(event, resource_arn, topic_arn, params::Dict{String,<:Any})

Enables the process of sending Amazon Simple Notification Service (SNS) notifications about
a specified event to a specified SNS topic.

# Arguments
- `event`: The event for which you want to receive SNS notifications.
- `resource_arn`: The ARN of the assessment template that is used during the event for
  which you want to receive SNS notifications.
- `topic_arn`: The ARN of the SNS topic to which the SNS notifications are sent.

"""
subscribe_to_event(event, resourceArn, topicArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("SubscribeToEvent", Dict{String, Any}("event"=>event, "resourceArn"=>resourceArn, "topicArn"=>topicArn); aws_config=aws_config)
subscribe_to_event(event, resourceArn, topicArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("SubscribeToEvent", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("event"=>event, "resourceArn"=>resourceArn, "topicArn"=>topicArn), params)); aws_config=aws_config)

"""
    unsubscribe_from_event(event, resource_arn, topic_arn)
    unsubscribe_from_event(event, resource_arn, topic_arn, params::Dict{String,<:Any})

Disables the process of sending Amazon Simple Notification Service (SNS) notifications
about a specified event to a specified SNS topic.

# Arguments
- `event`: The event for which you want to stop receiving SNS notifications.
- `resource_arn`: The ARN of the assessment template that is used during the event for
  which you want to stop receiving SNS notifications.
- `topic_arn`: The ARN of the SNS topic to which SNS notifications are sent.

"""
unsubscribe_from_event(event, resourceArn, topicArn; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("UnsubscribeFromEvent", Dict{String, Any}("event"=>event, "resourceArn"=>resourceArn, "topicArn"=>topicArn); aws_config=aws_config)
unsubscribe_from_event(event, resourceArn, topicArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("UnsubscribeFromEvent", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("event"=>event, "resourceArn"=>resourceArn, "topicArn"=>topicArn), params)); aws_config=aws_config)

"""
    update_assessment_target(assessment_target_arn, assessment_target_name)
    update_assessment_target(assessment_target_arn, assessment_target_name, params::Dict{String,<:Any})

Updates the assessment target that is specified by the ARN of the assessment target. If
resourceGroupArn is not specified, all EC2 instances in the current AWS account and region
are included in the assessment target.

# Arguments
- `assessment_target_arn`: The ARN of the assessment target that you want to update.
- `assessment_target_name`: The name of the assessment target that you want to update.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"resourceGroupArn"`: The ARN of the resource group that is used to specify the new
  resource group to associate with the assessment target.
"""
update_assessment_target(assessmentTargetArn, assessmentTargetName; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("UpdateAssessmentTarget", Dict{String, Any}("assessmentTargetArn"=>assessmentTargetArn, "assessmentTargetName"=>assessmentTargetName); aws_config=aws_config)
update_assessment_target(assessmentTargetArn, assessmentTargetName, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = inspector("UpdateAssessmentTarget", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("assessmentTargetArn"=>assessmentTargetArn, "assessmentTargetName"=>assessmentTargetName), params)); aws_config=aws_config)


text:
export visualize_environment

using RigidBodyDynamics
using DrakeVisualizer, CoordinateTransformations, ColorTypes, Rotations
using RigidBodyDynamics.Contact

function visualize_environment(mechanism::Mechanism, vis::Visualizer)
    root = root_body(mechanism)
    rootframe = default_frame(root)
    for (i, halfspace) in enumerate(mechanism.environment.halfspaces) # TODO: consider naming them
        name = "half-space $i"
        @framecheck Contact.frame(halfspace) rootframe # TODO
        R = Rotations.rotation_between(SVector(0., 0., 1.), halfspace.outward_normal.v)
        p = halfspace.point.v
        tf = Translation(p) ∘ LinearMap(R)
        thickness = 0.1
        length = 3.
        box = HyperRectangle(Vec(-length/2, -length/2, -thickness), Vec(length, length, thickness))
        box_vis = setgeometry!(vis[:environment][Symbol(name)], GeometryData(box, RGBA(0, 0, 1, 0.5)))
        settransform!(box_vis, tf)
    end
end

# radius = 0.01
# for foot in values(feet)
#     spheres = [HyperSphere(Point(location(point).v...), radius) for point in contact_points(foot)]
#     geomdata = [GeometryData(sphere, RGBA(1, 0, 0, 0.5)) for sphere in spheres]
#     dict = Dict{CartesianFrame3D, Vector{GeometryData}}(default_frame(foot) => geomdata)
#     setgeometry!(vis[:contactpoints][Symbol(name(foot))], dict)
# end

ext: jl


text:
using Distributions
using Random
using LinearAlgebra
using ProgressMeter
E = LinearAlgebra.I
eye(n) = Matrix(1.0E,n,n) #identity matrix

#
#import Fontconfig, Cairo
using Gadfly

@doc """
    rlct_R(M,N,H,r)

Calculate the real log canonical threshold of reduced rank regression
when the input dimmension is M, the output one is N,
the learner's rank is H, and the true rank is r.

The arguments must be positive integers and H>=r must hold.

# Example
```julia-repl
julia> rlct_R(4,3,2,1)
4.0
```
"""
function rlct_R(M,N,H,r)
    H_0 = r
    @assert (M>=1)&(N>=1)&(H>=H_0)&(H_0>=0)
    if (N+H_0<=M+H) & (M+H_0<=N+H) & (H+H_0<=M+N)
        if (M+N+H+H_0)%2 == 0
            return (2*(H+H_0)*(M+N)-(M-N)^2-(H+H_0)^2)/8
        else
            return (2*(H+H_0)*(M+N)-(M-N)^2-(H+H_0)^2 +1)/8
        end
    elseif M+H<N+H_0
        return (M*H+N*H_0-H*H_0)/2
    elseif N+H<M+H_0
        return (N*H+M*H_0-H*H_0)/2
    elseif M+N<H+H_0
        return M*N/2
    else #must not occur!
        return -1
    end
end

@doc """
    rlct_LDA(M,N,H,r)

Calculate the real log canonical threshold of latent Dirichlet allocation
when the input dimmension is M, the output one is N,
the learner's rank is H, and the rank of the transformed matrix U_0V_0 is r.
The rigorous definition of r is stated in the paper.

M>=2 and N>=2 and H>=r+1>=1 must hold.

# Example
```julia-repl
julia> rlct_LDA(4,3,2,1)
3.5
```
"""
function rlct_LDA(M,N,H,r)
    @assert (M>=2)&(N>=2)&(H>=r+1)&(r+1>=1)
    @assert (rlct_R(M,N,H,r+1)-N/2)==(rlct_R(M-1,N-1,H-1,r)+M/2-1/2)
    return rlct_R(M,N,H,r+1)-N/2
end

@doc """
    calc_r(A0, B0)

Calculate an intrinsic value of the true parameter as (A0, B0).
Transform from A0 and B0 to U0 and V0 and compute the rank of U_0V_0.
"""
function calc_r(A0, B0)
    M, H0 = size(A0)
    H02, N = size(B0)
    @assert H0==H02
    tildeA = A0[1:(M-1), 1:(H0-1)]
    a = A0[1:(M-1), H0]
    tildea = reduce(hcat, [a for _ in 1:(H0-1)])
    tildeB = B0[1:(H0-1), 1:(N-1)]
    b = B0[1:(H0-1), N]
    tildeb = reduce(hcat, [b for _ in 1:(N-1)])
    U0 = tildeA - tildea
    V0 = tildeB - tildeb
    return rank(U0*V0)
end

# fundamaental setting
## calc. RLCT
SIM_ITERS = 100
## MCMC
MCMC_K = 2000
BURNIN = 10000
THIN = 20
MCMC_ITER = BURNIN + THIN*MCMC_K
## hyperparameter in prior
ALPHA = 1.0
BETA = 1.0
## true and model
M = 4
N = 4
H_0 = 2
Random.seed!(1)
A_0 = hcat([rand(Dirichlet(ALPHA*ones(M))) for k in 1:H_0]...)
B_0 = hcat([rand(Dirichlet(BETA*ones(H_0))) for j in 1:N]...)
#### control variable (number of learner's topics)
H = 4
r = calc_r(A_0, B_0)

## data
SEED = 2020 #don't tune
L = 500 #number of words in each document
SAMPLESIZE = N*L
TESTSIZE = 200*SAMPLESIZE
## save path
LOG_FILE_PATH = joinpath("log","YYYYMMDD-LDA-H=$H-n=$SAMPLESIZE-T=$TESTSIZE.csv")
println(A_0)
println(B_0)

rlct_LDA(M,N,H,H_0)

@doc """
    generate_data(A::Array{Float64,2}, B::Array{Float64,2}; n::Int=SAMPLESIZE, seed=1)

    Generate artificiall data from the given LDA model like the following.
    for l=1:n
        generate words from Cat(x|AB[:,j]) for j=1,...,N
        as two format: docs array (N, n//N, M) and words array (n, M)
    end

    # Argments

    - A::Array{Float64,2}: stochastic matrix A= (the probability that the word is i when the topic is k)
      whose shape is (M,H).
    - B::Array{Float64,2}: stochastic matrix B= (the probability that the topic is k when the doc is j)
      whose shape is (H,N).
    - n::Int=SAMPLESIZE: the number of all words in all document. sample size.
    - seed::Int=1: the random seed.

    # Return
    - return: generated words (onehot(M) vectors) as two format
    - rtype: tuple(Array; shape is (N, n//N, M), Array; shape is (n, M))
"""
function generate_data(A::Array{Float64,2}, B::Array{Float64,2}; n::Int=SAMPLESIZE, seed=1)
    Random.seed!(seed);
    C = A*B
    M = size(C)[1]
    N = size(C)[2]
    L = div(n, N)
    @assert n%N==0
    words_arr = zeros(Bool,M,n)
    for j in 1:N
        words = rand(Multinomial(1, C[:,j]), L)
        words_arr[:,(1+(j-1)*L):(j*L)] = words
    end
    docs_arr = reshape(words_arr, (M,L,N))
    return (docs_arr, words_arr)
end

function make_onehot(hot_ind::Int, dim::Int; binary_type=Bool)
    @assert hot_ind <= dim
    @assert 1 <= hot_ind
    v = zeros(binary_type, dim);
    v[hot_ind] = 1;
    return v
end

function get_doc_onehot(docs_arr::Array{Bool,3}; n::Int=SAMPLESIZE)
    #===
    :return: Array of onehot vectors which mean each document id
    :rtype: Array{Float64,2}; shape is (N, n). each column means the document id corresponding word.
    ===#
    N = size(docs_arr)[3]
    L = div(n, N)
    doc_onehot = hcat([hcat([make_onehot(j, N) for l in 1:L]...) for j in 1:N]...)
    return doc_onehot
end

# each sampling step for Gibbs sampler
@doc """
    topic_step(docs_arr::Array{Bool,3}, A::Array{Float64,2}, B::Array{Float64,2}; n=SAMPLESIZE)

Generate a hidden variable (i.e. topic) in Gibbs sampler.

# Arguments
- docs_arr::Array{Bool,3}: data as documents form whose shape is (M, L==n//N, N).
- A::Array{Float64,2}: parameter matrix which represents word appearance probability for each topic.
- B::Array{Float64,2}: parameter matrix which represents topic propotion for each document.
- n::Int=SAMPLESIZE: sample size i.e. number of words.

# Return
- return: Bool topic matrix Y whose shape is (H, n).
"""
function topic_step(docs_arr::Array{Bool,3}, A::Array{Float64,2}, B::Array{Float64,2}; n=SAMPLESIZE)
    H = size(A)[2]
    N = size(B)[2]
    L = div(n, N)
    tmp = hcat([vcat(reshape(sum(docs_arr.*log.(A[:,k]),dims=1), (L,N)) .+ log.(B[k,:])'...) for k in 1:H]...)
    tmp = exp.(tmp)
    eta = tmp ./ sum(tmp, dims=2)
    Y = Array{Bool}(hcat([rand(Multinomial(1,eta[l,:])) for l in 1:n]...))
    return Y
end

@doc """
    A_step(words_arr::Array{Bool,2}, Y::Array{Bool,2}, alpha; n=SAMPLESIZE)

Generate a stochastic matrix in Gibbs sampler.

# Arguments
- words_arr::Array{Bool,2}: data as words form whose shape is (M, n).
- Y::Array{Bool,2}: topic matrix whose shape is (H, n).
- alpha: hyperparameter of Dirichlet prior for A.
- n::Int=SAMPLESIZE: sample size i.e. number of words.

# Return
- return: stochastic matrix which represents word appearance probability for each topic.
"""
function A_step(words_arr::Array{Bool,2}, Y::Array{Bool,2}, alpha; n=SAMPLESIZE)
    H = size(Y)[1]
    M = size(words_arr)[1]
    #use_words = reshape(words_arr, (n, M))
    hat_alpha = (Y*words_arr')' .+ alpha
    A = hcat([rand(Dirichlet(hat_alpha[:,k])) for k in 1:H]...)
    return A
end

@doc """
    B_step(doc_onehot::Array{Bool,2}, Y::Array{Bool,2}, beta; n=SAMPLESIZE)

Generate a stochastic matrix in Gibbs sampler.

# Arguments
- docs_arr::Array{Bool,3}: data as documents form whose shape is (M, L==n//N, N).
- Y::Array{Bool,2}: topic matrix whose shape is (H, n).
- beta: hyperparameter of Dirichlet prior for B.
- n::Int=SAMPLESIZE: sample size i.e. number of words.

# Return
- return: stochastic matrix which topic propotion for each document.
"""
function B_step(doc_onehot::Array{Bool,2}, Y::Array{Bool,2}, beta; n=SAMPLESIZE)
    #===
    (topic x num_of_docs) stochastic matrix sampling step.

    :param docs_arr: data as documents form; shape is (M, L=n//N, N)
    :param Y: topic matrix; shape is (H, n)
    :param beta: hyperparameter of Dirichlet prior for B
    :type beta: T(which means scalar) or Array{T,1}(which means 1-d vector); length is N. Where T is Int or Float.
    :return: param matrix B
    ===#
    H = size(Y)[1]
    N = size(doc_onehot)[1]
    #useZ = get_doc_onehot(docs_arr)'
    hat_beta = Y*(doc_onehot') .+ beta
    B = hcat([rand(Dirichlet(hat_beta[:,j])) for j in 1:N]...)
    return B
end

@doc """
    model_pmf(x::Array{Bool,1}, z::Array{Bool,1}, A::Array{Float64,2}, B::Array{Float64,2})

Calculate a probability mass for given data and parameter.

# Arguments
- x::Array{Bool,1}: M-dim onehot vector which means a word.
- z::Array{Bool,1}: N-dim onehot vector which means a document.
- A::Array{Float64,2}: (M,H) stochastic matrix
  whose (i,k) element means a probability that the word is i when the topic is k.
- B::Array{Float64,2}: (H,N) stochastic matrix
  whose (k,j) element means a probability that the topic is k when the document is j.
"""
function model_pmf(x::Array{Bool,1}, z::Array{Bool,1}, A::Array{Float64,2}, B::Array{Float64,2})
    #===
    probability mass function of model p(x|z,A,B).
    See also the above markdown cell.

    :param x: an M-dim onehot vector which means a word.
    :param x: an N-dim onehot vector which means a document.
    :param A: an (M,H) stochastic matrix whose (i,k) element means a probability that the word is i when the topic is k.
    :param B: an (H,N) stochastic matrix whose (k,j) element means a probability that the topic is k when the document is j.
    ===#
    @assert sum(z) == 1
    @assert sum(x) == 1
    @assert size(A)[2] == size(B)[1]
    j = argmax(z) #z_j=1, z_{j'}=0 (j' != j)
    i = argmax(x) #x_i=1, x_{i'}=0 (i' != i)
    AB = A*B
    return AB[i,j]
end

# Gibbs sampler
function run_all_sampling!(
        docs_arr::Array{Bool,3}, words_arr::Array{Bool,2}, doc_onehot::Array{Bool,2}, init_Y::Array{Bool,2},
        allYs::Array{Bool,3}, allAs::Array{Float64,3}, allBs::Array{Float64,3})
    iters = size(allYs)[3];
    alpha = ALPHA;
    beta = BETA;
    sampling_progress = Progress(iters);
    Y = init_Y;
    @time for k in 1:iters
        ## parameter matrix sampling and saving
        A = A_step(words_arr, Y, alpha);
        B = B_step(doc_onehot, Y, beta);
        allAs[:,:,k] = A;
        allBs[:,:,k] = B;
        ## hidden variable (topic indicator) sampling and saving
        Y = topic_step(docs_arr, A, B);
        allYs[:,:,k] = Y;
        ## Progress update
        next!(sampling_progress);
    end
    #return (allYs, allAs, allBs)
end

#===
function calc_likelihoodMat!(
        k::Int, words_arr::Array{Bool,2}, doc_onehot::Array{Bool,2}, A::Array{Float64,2}, B::Array{Float64,2},
        likelihoodMat::Array{Float64,2}; n::Int=SAMPLESIZE)
    #===
    ===#
    ## generated quantity: likelihood matrix
    for l in 1:n
        x = words_arr[:,l];
        z = doc_onehot[:,l];
        likelihoodMat[l,k] = model_pmf(x,z,A,B);
    end
    return likelihoodMat
end
===#

function run_thining!(
        words_arr::Array{Bool,2}, doc_onehot::Array{Bool,2},
        allYs::Array{Bool,3}, allAs::Array{Float64,3}, allBs::Array{Float64,3},
        gsYs::Array{Bool,3}, gsAs::Array{Float64,3}, gsBs::Array{Float64,3}, likelihoodMat::Array{Float64,2};
        K::Int=MCMC_K, burn::Int=BURNIN, th::Int=THIN, n::Int=SAMPLESIZE)
    ## burnin and thining
    K = size(gsYs)[3]
    thining_progress = Progress(K);
    @time for k in 1:K
        A = allAs[:,:,burn+k*th];
        gsAs[:,:,k] = A;
        B = allBs[:,:,burn+k*th];
        gsBs[:,:,k] = B;
        gsYs[:,:,k] = allYs[:,:,burn+k*th];
        ## generated quantity: likelihood matrix
        #likelihoodMat = calc_likelihoodMat!(k, words_arr, doc_onehot, A, B, likelihoodMat)
        for l in 1:n
            x = words_arr[:,l];
            z = doc_onehot[:,l];
            likelihoodMat[l,k] = model_pmf(x,z,A,B);
        end
        next!(thining_progress);
    end
    #return (gsYs, gsAs, gsBs, likelihoodMat)
end

function run_Gibbs_sampler_cored(
    docs_arr::Array{Bool,3}, words_arr::Array{Bool,2}; K::Int=MCMC_K, burn::Int=BURNIN, th::Int=THIN, n::Int=SAMPLESIZE)
    #===
    Version: separating core functions
    ===#
    ## initial value of A and B is sampled from the prior distributuion
    #### Assume that prior is SYMMETRIC Dirichlet distribution. Hyparam is scalar.
    init_A = hcat([rand(Dirichlet(M, ALPHA)) for k in 1:H]...);
    init_B = hcat([rand(Dirichlet(H, BETA)) for j in 1:N]...);
    init_Y = topic_step(docs_arr, init_A, init_B);
    ## sampling iteration
    #### allocate tensors for MCMC sample
    iters = burn + K*th;
    allAs = zeros(Float64, M, H, iters);
    gsAs = zeros(Float64, M, H, K);
    allBs = zeros(Float64, H, N, iters);
    gsBs = zeros(Float64, H, N, K);
    allYs = zeros(Bool, H, n, iters);
    gsYs = zeros(Bool, H, n, K);
    #### all sampling
    doc_onehot = get_doc_onehot(docs_arr);
    println("Start $iters iteration for GS")
    run_all_sampling!(docs_arr, words_arr, doc_onehot, init_Y, allYs, allAs, allBs)
    ## burnin and thining
    likelihoodMat = zeros(Float64, n, K)
    println("Start burn-in and thining from $iters to $K")
    run_thining!(words_arr, doc_onehot, allYs, allAs, allBs, gsYs, gsAs, gsBs, likelihoodMat)
    return (gsYs, gsAs, gsBs, likelihoodMat)
end

@doc """
    run_Gibbs_sampler(docs_arr, words_arr, alpha, beta; K=MCMC_K, burn=BURNIN, th=THIN, n=SAMPLESIZE, seed_MCMC=2)

Run Gibbs sampler for LDA.
Global variable `M` , `H` , and `N` are used
as vocab. size, num. of topics, and num. of documents, respectively.
Note that rtype is tuple of tensor(Array{T,3}), not tuple of Array{Array{T,2}}.
"""
function run_Gibbs_sampler(docs_arr, words_arr, alpha, beta; K=MCMC_K, burn=BURNIN, th=THIN, n=SAMPLESIZE, seed_MCMC=2)
    #===
    Run Gibbs sampler for LDA.
    Global variable `M` , `H` , and `N` are used
    as vocab. size, num. of topics, and num. of documents, respectively.
    Note that rtype is tuple of tensor(Array{T,3}), not tuple of Array{Array{T,2}}.

    :param docs_arr: data as document format
    :param words_arr: data as word format
    :param alpha: hyperparameter of Dirichlet prior for A
    :param beta: hyperparameter of Dirichlet prior for B
    :return: sample of Y(topic indicator variable),A and B from GS and likelihood matrix
    :rtype: tuple(Array{Bool,3};shape(H,n,K), Array{Float64,3};shape(M,H,K), Array{Float64,3};shape(H,N,K), Array{Float64,2};shape(n,K))
    ===#
    Random.seed!(seed_MCMC);
    ## initial value of A and B is sampled from the prior distributuion
    #### Assume that prior is SYMMETRIC Dirichlet distribution. Hyparam is scalar.
    init_A = hcat([rand(Dirichlet(M, alpha)) for k in 1:H]...);
    init_B = hcat([rand(Dirichlet(H, beta)) for j in 1:N]...);
    Y = topic_step(docs_arr, init_A, init_B);
    ## sampling iteration
    #### allocate tensors for MCMC sample
    iters = burn + K*th;
    allAs = zeros(Float64, M, H, iters);
    gsAs = zeros(Float64, M, H, K);
    allBs = zeros(Float64, H, N, iters);
    gsBs = zeros(Float64, H, N, K);
    allYs = zeros(Bool, H, n, iters);
    gsYs = zeros(Bool, H, n, K);
    #### all sampling
    doc_onehot = get_doc_onehot(docs_arr);
    println("Start $iters iteration for GS")
    sampling_progress = Progress(iters);
    @time for k in 1:iters
        ## parameter matrix sampling and saving
        A = A_step(words_arr, Y, alpha);
        B = B_step(doc_onehot, Y, beta);
        allAs[:,:,k] = A;
        allBs[:,:,k] = B;
        ## hidden variable (topic indicator) sampling and saving
        Y = topic_step(docs_arr, A, B);
        allYs[:,:,k] = Y;
        ## Progress update
        next!(sampling_progress);
    end
    ## burnin and thining
    likelihoodMat = zeros(Float64, n, K)
    println("Start burn-in and thining from $iters to $K")
    thining_progress = Progress(K);
    @time for k in 1:K
        A = allAs[:,:,burn+k*th];
        gsAs[:,:,k] = A;
        B = allBs[:,:,burn+k*th];
        gsBs[:,:,k] = B;
        gsYs[:,:,k] = allYs[:,:,burn+k*th];
        ## generated quantity: likelihood matrix
        for l in 1:n
            x = words_arr[:,l];
            z = doc_onehot[:,l];
            likelihoodMat[l,k] = model_pmf(x,z,A,B);
        end
        next!(thining_progress);
    end
    return (gsYs, gsAs, gsBs, likelihoodMat)
end

function run_prior_sampling(docs_arr, words_arr, alpha, beta; K=MCMC_K, burn=BURNIN, th=THIN, n=SAMPLESIZE, seed_MCMC=2)
    #===
    Run prior sampling K times.

    :return: sample of Y(topic indicator variable),A and B from GS and likelihood matrix
    :rtype: tuple(Array{Bool,3};shape(H,n,K), Array{Float64,3};shape(M,H,K), Array{Float64,3};shape(H,N,K), Array{Float64,2};shape(n,K))
    ===#
    Random.seed!(seed_MCMC);
    ## sampling iteration
    #### allocate tensors for MCMC sample
    gsAs = zeros(Float64, M, H, K);
    gsBs = zeros(Float64, H, N, K);
    gsYs = zeros(Bool, H, n, K);
    #### all sampling
    doc_onehot = get_doc_onehot(docs_arr);
    println("Start $K iteration for prior sampling (no thining)")
    sampling_progress = Progress(K);
    @time for k in 1:K
        ## parameter matrix sampling and saving
        A = hcat([rand(Dirichlet(M, alpha)) for k in 1:H]...);
        B = hcat([rand(Dirichlet(H, beta)) for j in 1:N]...);
        gsAs[:,:,k] = A;
        gsBs[:,:,k] = B;
        ## hidden variable (topic indicator) sampling and saving
        Y = topic_step(docs_arr, A, B);
        gsYs[:,:,k] = Y;
        ## Progress update
        next!(sampling_progress);
    end
    ## calc likelihood matrix
    likelihoodMat = zeros(Float64, n, K)
    println("Start calculating likelihood matrix")
    thining_progress = Progress(K);
    @time for k in 1:K
        A = gsAs[:,:,k];
        B = gsBs[:,:,k];
        ## generated quantity: likelihood matrix
        for l in 1:n
            x = words_arr[:,l];
            z = doc_onehot[:,l];
            likelihoodMat[l,k] = model_pmf(x,z,A,B);
        end
        next!(thining_progress);
    end
    return (gsYs, gsAs, gsBs, likelihoodMat)
end

# define functions for calculating RLCT
@doc """
    calc_functional_var(loglikeMat::Array{Float64,2})

Calculate a functional variance from given loglikelihood matrix.
"""
function calc_functional_var(loglikeMat::Array{Float64,2})
    #===
    Calculate functional variance from loglike matrix.

    :param loglikeMat: a matrix whose (l,k) element is log p(x_l|z_l,A_k,B_k)
    ===#
    n = size(loglikeMat)[1]
    K = size(loglikeMat)[2]
    first_term = reshape(mean(loglikeMat.^2, dims=2),n)
    second_term = reshape(mean(loglikeMat, dims=2).^2, n)
    func_var = sum(first_term - second_term)
    return func_var
end

@doc """
    calc_predict_dist(x, z, As, Bs)

Calculate predictive distribution from given MCMC sample.
"""
function calc_predict_dist(x, z, As, Bs)
    #===
    Calculate pmf of predictive distribution.

    :param x: an M-dim onehot vector which means a word.
    :param z: an N-dim onehot vector which means a document.
    :param As: an Array whose [:,:,k] element means an MCMC sample of A.
    :param Bs: an Array whose [:,:,k] element means an MCMC sample of B.
    ===#
    @assert size(As)[3]==size(Bs)[3]
    K = size(As)[3]
    mass = 0.0
    for k in 1:K
        mass += model_pmf(x, z, As[:,:,k], Bs[:,:,k])
    end
    return mass/K
end

@doc """
    calc_normalized_WAIC(words_arr, doc_onehots, true_A, true_B, likelihoodMat)

Calculate normalized WAIC, i.e. emperical loss - WAIC.
"""
function calc_normalized_WAIC(words_arr, doc_onehots, true_A, true_B, likelihoodMat)
    #===
    Calculating normalized WAIC.
    ===#
    n = size(words_arr)[2]
    emp_loss = -mean(log.(mean(likelihoodMat, dims=2)))
    emp_entropy = -mean([log(model_pmf(words_arr[:,l], doc_onehots[:,l], true_A, true_B)) for l in 1:n])
    func_var = calc_functional_var(log.(likelihoodMat))
    #println(typeof(emp_entropy))
    normalized_WAIC = emp_loss - emp_entropy + func_var/n
    return normalized_WAIC
end

@doc """
    calc_generalization_error(true_A, true_B, As, Bs; nT=TESTSIZE, seed_T=3)

Calculate generalization error, i.e. KL divergence from the true distribution to the predictive one
using many test data generated by the true distribution.
"""
function calc_generalization_error(true_A, true_B, As, Bs; nT=TESTSIZE, seed_T=3)
    #===
    Calculating generalization error using test data generated by true distribution.
    ===#
    test_doc, test_words = generate_data(true_A, true_B, n=nT, seed=seed_T)
    test_doc_onehot = get_doc_onehot(test_doc, n=nT)
    ge = 0.0
    calc_gerr_progress = Progress(nT)
    println(nT)
    @time for t in 1:nT
        q = model_pmf(test_words[:,t], test_doc_onehot[:,t], true_A, true_B)
        pred = calc_predict_dist(test_words[:,t], test_doc_onehot[:,t], As, Bs)
        ge += log(q) - log(pred) #log(q/pred), but q and pred is small number.
        next!(calc_gerr_progress)
    end
    ge /= nT
    return ge
end

@doc """
    run_single_inference(true_A, true_B, seed)

Carry out an inference.
- Generate sample.
- Run Gibbs sampler and make the posterior distribution.
- Calculate (generalization error, normalized WAIC) (this is the return).
"""
function run_single_inference(true_A, true_B, seed)
    #===
    Run single inference.

    Random seed of each module is determined by the following rule:
    generate train data: seed + 1
    run Gibbs sampler: seed + 2
    generate test data: seed + 3

    Macro seed (SEED) must be disjoint from 3 and larger than 10.
    ===#
    Random.seed!(seed);
    train_X_docs, train_X_words = generate_data(true_A, true_B, n=SAMPLESIZE, seed=seed+1)
    train_Z = get_doc_onehot(train_X_docs, n=SAMPLESIZE)
    println("Gibbs Sampling")
    topic_Ys, param_As, param_Bs, likelihoodMat = run_Gibbs_sampler(train_X_docs, train_X_words, ALPHA, BETA, seed_MCMC=seed+2)
    #topic_Ys, param_As, param_Bs, likelihoodMat = run_Gibbs_sampler_cored(train_X_docs, train_X_words)
    println("Calculation Normalized WAIC")
    normalized_WAIC = calc_normalized_WAIC(train_X_words, train_Z, true_A, true_B, likelihoodMat)
    println("Calculaton Generalization Error")
    ge = calc_generalization_error(true_A, true_B, param_As, param_Bs, seed_T=seed+3)
    return (ge, normalized_WAIC)
end

function run_single_inference_debug(true_A, true_B, seed)
    #===
    Run single inference for debug mode.
    ===#
    Random.seed!(seed);
    train_X_docs, train_X_words = generate_data(true_A, true_B, n=SAMPLESIZE, seed=seed+1)
    train_Z = get_doc_onehot(train_X_docs, n=SAMPLESIZE)
    println("Gibbs Sampling")
    topic_Ys, param_As, param_Bs, likelihoodMat = run_Gibbs_sampler(train_X_docs, train_X_words, ALPHA, BETA, seed_MCMC=seed+2)
    #topic_Ys, param_As, param_Bs, likelihoodMat = run_Gibbs_sampler_cored(train_X_docs, train_X_words)
    println("Calculation Normalized WAIC")
    normalized_WAIC = calc_normalized_WAIC(train_X_words, train_Z, true_A, true_B, likelihoodMat)
    println("Calculaton Generalization Error")
    ge = calc_generalization_error(true_A, true_B, param_As, param_Bs, seed_T=seed+3)
    return (topic_Ys, param_As, param_Bs, likelihoodMat, ge, normalized_WAIC)
end

function run_single_inference_PS(true_A, true_B, seed)
    #===
    Run single inference using prior sampling (worst benchmark).
    ===#
    Random.seed!(seed);
    train_X_docs, train_X_words = generate_data(true_A, true_B, n=SAMPLESIZE, seed=seed+1)
    train_Z = get_doc_onehot(train_X_docs, n=SAMPLESIZE)
    println("Prior Sampling")
    topic_Ys, param_As, param_Bs, likelihoodMat = run_prior_sampling(train_X_docs, train_X_words, ALPHA, BETA, seed_MCMC=seed+2)
    #topic_Ys, param_As, param_Bs, likelihoodMat = run_Gibbs_sampler_cored(train_X_docs, train_X_words)
    println("Calculation Normalized WAIC")
    normalized_WAIC = calc_normalized_WAIC(train_X_words, train_Z, true_A, true_B, likelihoodMat)
    println("Calculaton Generalization Error")
    ge = calc_generalization_error(true_A, true_B, param_As, param_Bs, seed_T=seed+3)
    return (topic_Ys, param_As, param_Bs, likelihoodMat, ge, normalized_WAIC)
end

@doc """
    run_multi_inference(true_A, true_B, sim_iters, log_file_path)

Independently repeat inferences.
"""
function run_multi_inference(true_A, true_B, sim_iters, log_file_path)
    #===
    for it in 1:sim_iters
        run_single_inference
    end
    and calculate RLCT from above $sim_iters simulation results.

    :param true_A: true parameter stochastic matrix A
    :param true_B: true parameter stochastic matrix B
    :param sim_iters: number of simulations
    :param log_file_path: path of the file to write the experimental log
    :return: generalization errors and normalized WAICs in the simulations
    :rtype: tuple(Array{Float64,1}, Array{Float64,1})
    ===#
    seeds = SEED .+ SEED * (1:sim_iters)
    gerrors = zeros(Float64, sim_iters)
    normalized_WAICs = zeros(Float64, sim_iters)
    open(log_file_path, "a") do fp
        println(fp, "## Simulation Setting")
        println(fp, "M,N,H,H_0,L,MCMC_K,BURNIN,THIN,TESTSIZE,SIM_ITERS,SEED")
        println(fp, "$M,$N,$H,$H_0,$L,$MCMC_K,$BURNIN,$THIN,$TESTSIZE,$sim_iters,$SEED")
        println(fp, "## Simulation Log")
        println(fp, "iter,gerror,normalized_WAIC,RLCT,RLCT_SEM")
    end
    simulation_progress = Progress(sim_iters)
    for it in 1:sim_iters
        println("# start $it th simulation")
        ge, norm_W = run_single_inference(true_A, true_B, seeds[it])
        gerrors[it] = ge
        normalized_WAICs[it] = norm_W
        now_ges = gerrors[1:it]
        now_nwaics = normalized_WAICs[1:it]
        rlct = (SAMPLESIZE/2)*mean(now_ges + now_nwaics)
        rlct_sem = (SAMPLESIZE/2)*std(now_ges + now_nwaics)/sqrt(it)
        open(log_file_path, "a") do fp
            println(fp,"$it,$ge,$norm_W,$rlct,$rlct_sem")
            println("$it,$ge,$norm_W,$rlct,$rlct_sem")
        end
        next!(simulation_progress)
        #@assert ge>=0
        #@assert norm_W>=0
    end
    return (gerrors, normalized_WAICs)
end

# main process
##===
gerrors, normalized_WAICs = @time run_multi_inference(A_0, B_0, SIM_ITERS, LOG_FILE_PATH)
ge_and_nW = gerrors + normalized_WAICs
each_lams = (SAMPLESIZE/2) .* ge_and_nW
lam = (SAMPLESIZE/2)*mean(ge_and_nW)
lam_sd = (SAMPLESIZE/2)*std(ge_and_nW)/sqrt(SIM_ITERS)
println("The numerical RLCT is $lam ± $lam_sd")
#===#

println("$M, $N, $H, $r")
λ = rlct_LDA(M,N,H,r)
println("The exact RLCT = $λ")

using DelimitedFiles
each_lams_savepath = split(LOG_FILE_PATH, ".")[1]*"_each_lams.csv"
writedlm(each_lams_savepath,  each_lams, ',')

each_lams_mean = mean(each_lams)
each_lams_std = std(each_lams)
upperline = each_lams_mean + each_lams_std
middleline = each_lams_mean
lowerline = each_lams_mean - each_lams_std
trueline = λ
plot(y=each_lams, yintercept = [upperline, middleline, lowerline, trueline],
    Geom.violin, Geom.hline(color=["orange","red","orange","blue"], style=[:dot,:dash,:dot,:solid]))


text:
using JuMP, EAGO

                     m = Model()

                     EAGO.register_eago_operators!(m)

                     @variable(m, -1 <= x[i=1:3] <= 1)

                     @variable(m, -12.75118444054646 <= q <= 9.039664285972906)

                     add_NL_constraint(m, :(gelu(0.715796138346545 + -0.1516695982843861*gelu(-0.317423658088571 + -0.8843064794993589*gelu(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])) + 0.6219431368805965*gelu(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])) + -0.24757066957523488*gelu(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))) + -0.0820632819191216*gelu(-0.8960501996212993 + -0.7682728024607406*gelu(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])) + -0.3378399703859083*gelu(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])) + 0.4153867033969405*gelu(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))) + -0.0571486344530765*gelu(0.054021626349418206 + -0.05819989275612114*gelu(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])) + 0.8875139231924525*gelu(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])) + 0.11280184637312685*gelu(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))) + gelu(-0.8464220616292248 + -0.9331432460947604*gelu(-0.317423658088571 + -0.8843064794993589*gelu(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])) + 0.6219431368805965*gelu(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])) + -0.24757066957523488*gelu(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))) + 0.425513343659472*gelu(-0.8960501996212993 + -0.7682728024607406*gelu(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])) + -0.3378399703859083*gelu(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])) + 0.4153867033969405*gelu(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))) + 0.1421259709107252*gelu(0.054021626349418206 + -0.05819989275612114*gelu(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])) + 0.8875139231924525*gelu(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])) + 0.11280184637312685*gelu(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))) + gelu(-0.5205460270098605 + 0.13812073353255405*gelu(-0.317423658088571 + -0.8843064794993589*gelu(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])) + 0.6219431368805965*gelu(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])) + -0.24757066957523488*gelu(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))) + 0.7749706249828683*gelu(-0.8960501996212993 + -0.7682728024607406*gelu(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])) + -0.3378399703859083*gelu(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])) + 0.4153867033969405*gelu(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))) + 0.5007112790542019*gelu(0.054021626349418206 + -0.05819989275612114*gelu(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])) + 0.8875139231924525*gelu(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])) + 0.11280184637312685*gelu(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))) - $q <= 0.0))

                     @objective(m, Min, q)

                     return m

max_stars_repo_name: PSORLab/RSActivationFunctions

max_issues_repo_name: PSORLab/RSActivationFunctions

max_forks_repo_name: PSORLab/RSActivationFunctions


text:
################################################################################
#  Copyright 2020, Tom Van Acker                                               #
################################################################################
# MultiStateSystems.jl                                                         #
# A Julia package to solve multi-state system models.                          #
# See http://github.com/timmyfaraday/MultiStateSystems.jl                      #
################################################################################
"""
Example considering a flow transmission system with three pipes taken from:

> Multi-State System Reliability Analysis and Optimization for Engineers and
  Industrial Managers by A. Lisnianski, I. Frenkel, and Y. Ding, pg. 11/209
  (2010)

The oil flow is transmitted from a source S to a user U (Fig. 1).

        n₁  pipe 1  n₂
        |----///----|   pipe 3  n₃
    S⋅--|           |----///----|--⋅ U
        |----///----|
            pipe 2
Fig. 1: Flow transmission system.

The pipes' performance is measured by their transmission capacity (m³/hr)
(Table 1).

Table 1: Transmission capacity of the pipes in the flow transmission system.
| pipe 1               | pipe 2               | pipe 3               |
|----------------------|----------------------|----------------------|
| g¹₁ = 0    m³/hr     | g²₁ = 0    m³/hr     | g³₁ = 0    m³/hr     |
| g¹₂ = 1500 m³/hr     | g²₂ = 2000 m³/hr     | g³₂ = 1800 m³/hr     |
|                      |                      | g³₃ = 4000 m³/hr     |
"""

# load pkgs
using Unitful
using MultiStateSystems

# initialize the state-transition diagrams corresponding with the pipes
stdᵖ¹, stdᵖ², stdᵖ³ = STD(), STD(), STD()

# add the states and transitions to the respective state-transition diagrams
## pipe 1
add_states!(stdᵖ¹, flow = [0u"m^3/hr", 1500u"m^3/hr"],
                   init = [0.0, 1.0])
add_transitions!(stdᵖ¹, states = [(1,2), (2,1)],
                        rate   = [μ¹, λ¹])
## pipe 2
add_states!(stdᵖ², flow = [0u"m^3/hr", 2000u"m^3/hr"],
                   init = [0.0, 1.0])
add_transitions!(stdᵖ², states = [(1,2), (2,1)],
                        rate   = [μ², λ²])
## pipe 3
add_states!(stdᵖ³, flow = [0u"m^3/hr", 1800u"m^3/hr", 4000u"m^3/hr"],
                   init = [0.0, 0.0, 1.0])
add_transitions!(stdᵖ³, states = [(1,2), (2,1), (2,3), (3,2)],
                        rate   = [μ³ᵃ, λ³ᵃ, μ³ᵇ, λ³ᵇ])

# solve the state-transition diagrams
solve!(stdᵖ¹, SteadyStateProcess())
solve!(stdᵖ², SteadyStateProcess())
solve!(stdᵖ³, SteadyStateProcess())

# initialize the network corresponding to the flow transmission system
ntwᶠᵗˢ = Network()

# add the user, source and components to the network ntwᶠᵗˢ
add_user!(ntwᶠᵗˢ, node = 3)
add_source!(ntwᶠᵗˢ, node = 1)
add_components!(ntwᶠᵗˢ, edge = [(1,2),(1,2),(2,3)],
                        name = ["pipe 1", "pipe 2", "pipe 3"],
                        std  = [stdᵖ¹, stdᵖ², stdᵖ³])

# return the network
return ntwᶠᵗˢ


text:
# -*- coding: utf-8 -*-
# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .jl
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.5.0
#   kernelspec:
#     display_name: Julia 1.4.2
#     language: julia
#     name: julia-1.4
# ---

# # Linear Regression
#
# `MLJ.jl` の練習として線形回帰の問題を解くことを考える.

# # 定式化
#
# 次元が $n$ の説明変数 $x=[x_1,\dots,x_n]^\top$ と 1 次元の目的変数 $y$ のペアからなるデータ $(x,y)$
# からなる $N$ この要素を持つ集合を $\mathcal{D}$ とおく:
#
# $$
# \mathcal{D} = \{\, (x^{(i)},y^{(i)})\mid i = 1,2,\dots, N  \,\}.
# $$
#
# 説明変数 $x$ と目的変数 $y$ を関連づけるモデルとして次の形をしてるパラメータ $\beta=[\beta_0,\beta_1,\dots,\beta_n]$ を持つ線形モデルであるとする:
#
# $$
# y = m(x;\beta)=\beta_0 + \beta_1 x_1 + \dots \beta_n x_n.
# $$
#
# この設定のもとで与えられているデータセットに適合するパラメータ $\beta$ を求めたい.
# 我々は適合の指標としてパラメータ $\beta$ に依存する損失関数 $L=L(\beta)$ を定義し, その損失関数の最小値を与える時の $\beta=\hat{\beta}$ を与える方針を取る. ここでは損失関数として次の形のものを採用する:
#
# $$
# L(\beta) = \frac{1}{2}\sum_{i=1}^N (m(x^{(i)};\beta)-y^{(i)})^2
# $$
#
# 各データの目的変数 $y^{(i)}$ と説明変数 $x^{(i)}$ に対するモデルの出力 $\hat{y}^{(i)}:=m(x^{(i)}; \beta)$ の二乗誤差が最小になるように設計している. この場合, 求めたいパラメータである $\hat{\beta}$ は次の極値問題を解けば良いことになる:
#
# $$
# \nabla_{\beta} L(\beta) =
# \begin{bmatrix}
# \frac{\partial L(\beta)}{\partial \beta_0} \\
# \frac{\partial L(\beta)}{\partial \beta_1} \\
# \vdots \\
# \frac{\partial L(\beta)}{\partial \beta_n}
# \end{bmatrix}
# =\bf{0}
# $$
#

# ## 極値問題を解く
#
# 上記の $L(\beta)$ を以下で述べるようにベクトルのノルムで表記し，それを用いてベクトルに対する微分の結果を用いて解くことにする.
#
# ### 記号の準備
#
# $y=[y^{(1)},\dots,y^{(N)}]^\top$, $\hat{y}=[\hat{y}^{(1)},\dots,\hat{y}^{(N)}]^\top$ とおく.
# 説明変数 $x^{(i)}=[x_1^{(i)},\dots,x_n^{(i)}]^\top$ を用いて得られる行列 $X$ を次のように定める:
#
# $$
# X = \begin{bmatrix}
# 1      & x_1^{(1)} & x_2^{(1)} & \dots  & x_n^{(1)} \\
# 1      & x_1^{(2)} & x_2^{(2)} & \dots  & x_n^{(2)} \\
# \vdots & \vdots    & \vdots    &        & \vdots    \\
# 1      & x_1^{(N)} & x_2^{(N)} & \dots  & x_n^{(N)}
# \end{bmatrix}_{\textstyle .}
# $$
#
# これはしばしば計画行列などと呼ばれる. さて $x^{(i)}$ に対するモデルの出力は次のように変形できることに注意する:
#
# $$
# \begin{align}
# \hat{y}^{(i)} &= m(x^{(i)};\beta) \\
#               &= [1,x_1^{(i)},\dots,x_n^{(i)}]
#               \begin{bmatrix}
#                   \beta_0 \\
#                   \beta_1 \\
#                   \vdots \\
#                   \beta_n
#               \end{bmatrix}_{\textstyle .}
# \end{align}
# $$
#
# したがって $\hat{y} = X \beta$ とかけるので $L(\beta)$ は
#
# $$
# \begin{align}
# L(\beta) &= \frac{1}{2}\sum_{i=1}^N (m(x^{(i)};\beta)-y^{(i)})^2 \\
#          &= \frac{1}{2} \langle \hat{y}-y, \hat{y}-y\rangle \\
#          &= \frac{1}{2} \langle X \beta -y, X\beta -y \rangle \\
# \end{align}
# $$
#
# となる.
#

# ## 勾配ベクトルの計算
#
# $z=z(\beta)=X^\top\beta-y$ とし $z_i$ を $z$ の第 $i$ 番目の成分とする. 定義によって
# $$
# \begin{align}
# L(\beta) &= \frac{1}{2}\langle z,z \rangle = \frac{1}{2}\sum_{i=1}^n z_i(\beta)^2, \\
# \frac{\partial z_i}{\partial \beta_j} &= X_{ij} , \\
# \frac{\partial}{\partial \beta_j} L(\beta)
# &= \sum_{i=1}^n z_i(\beta) \frac{\partial z_i}{\partial \beta_j} \\
# &= \sum_{i=1}^n z_i(\beta) X_{ij}
# \end{align}
# $$
#
# などから
#
# $\nabla_{\beta} L(\beta) = X^\top z = X^\top(X\beta - y)$ となる. $\nabla_{\beta} L(\beta)=0$ を $\beta$ についてとくと $\beta = (X X^\top)^{-1}X^\top y$ が得られる. したがって
#
# $$
# \hat{\beta} = (XX^\top)^{-1}X^\top y
# $$
#
# となる.

# # 実装
#
# - 住宅の価格予測をする Boston dataset があるのでそれを試してみよう. 説明変数は `Crim`, `Zn`, `Indus`, `NOx`, `Rm`, `Age`, `Dis`, `Rad`, `Tax`, `PTRatio`, `Black`, `LStat` という 12 項目からなる.
# - MLJ で提供されている `@load_boston` マクロを用いてデータをロードできる.

# ## パッケージの読み込み

# +
using LinearAlgebra

using DataFrames
using LaTeXStrings
using MLJ
using OffsetArrays
using Plots
# -

X, y = @load_boston
variable_names = keys(X)

# ## 計画行列の作成

X, y = @load_boston
ndata = length(y)
X = hcat(ones(ndata), [X[k] for k in variable_names]...)
X |> size

# ## $\widehat{\beta}$ の計算

β̂ = inv(X' * X) * X' * y

# +
## 結果の表示
function show_result(β,variable_names)
    for (i, (β̂_i,k)) in enumerate(zip(β,[:bias, variable_names...]))
        println("k = $k, β̂_$(i-1) = $(β̂_i)")
    end
end

show_result(β̂, variable_names)
# -

# ## RMS の計算
#
# - root mean squared error を計算する

ŷ = X * β̂
round(rms(ŷ, y), sigdigits=4)

# ## 説明変数が１次元の例
#
# - 説明変数の一つで線形モデルを解く. そうするとモデルは二次元平面上の線分として表示できるのでデータを可視化できる．ここでは `LStat` という項目を取り上げて調べてみよう.

X_, y = @load_boston
name = :LStat
ndata = length(y)
X = hcat(ones(ndata), [X_[k] for k in [name]]...)
β̂ = inv(X' * X) * X' * y
show_result(β̂,[name])

β̂ = OffsetArray(β̂,0:length(β̂)-1)
p=plot(xlabel="x",ylabel="y")
scatter!(p, X_[variable_names[1]], y,label=variable_names[1])
plot!(p, x->β̂[0] + β̂[1]*x, xlim=[minimum(X_[name]),maximum(X_[name])], label=L"y=\beta_0+\beta_1 x")

# # MLJ で解いてみる
#
# - 上記では線形モデルによる回帰問題を解いた. `MLJ.jl` では `LinearRegressor` という名前で上記と同様のことをすることができる機能を備えている.

# +
using MLJ

@load LinearRegressor pkg=MLJLinearModels
# -

# `fit_intercept=true` を指定しておくことで切片 $\beta_0$ も考慮できるようになる.

linearmodel = LinearRegressor(fit_intercept=true)

# `machine(model, 説明変数, 目的変数)` により学習器を作る.

X, y = @load_boston
m = machine(linearmodel, X, y)

# `fit!` によりモデルを学習させることができる.

fit!(m)

# 学習によってえられたモデルのパラメータを取得しその結果を表示する. この結果はスクラッチで作ったモデルと一致するはずである.

fp = fitted_params(m)
coefs = fp.coefs
intercept = fp.intercept
for (name, val) in coefs
    println("$(rpad(name, 8)):  $(round(val, sigdigits=3))")
end
println("Intercept: $(round(intercept, sigdigits=3))")

# ついでに説明変数が一変数の場合でも同様の結果が得られることを確認しよう.

X_, y = @load_boston
variable_names = [:LStat]
X = DataFrame([X_[variable_names[1]]])
m = machine(linearmodel, X, y)
fit!(m)
fp = fitted_params(m)
β̂ = [fp.intercept, [c.second for c in fp.coefs]...]

β̂ = OffsetArray(β̂,0:length(β̂)-1)
p=plot(xlabel="x",ylabel="y")
scatter!(p, X_[variable_names[1]], y,label=variable_names[1])
plot!(p, x->β̂[0] + β̂[1]*x, xlim=[minimum(X_[name]),maximum(X_[name])], label=L"y=\beta_0+\beta_1 x")


text:
#
# TODO: add tests for fast mode
#
module TestClient
  using FactCheck
  using Connection
  using Server
  using Client
  using Config
  using Event
  include("Helper.jl")

  facts("Tests sending of simple command") do
    answer = 0
    local scon::ServerConnection = Server.create(IP, PORT)
    local ccon::ClientConnection = Client.create(IP, PORT)

    Event.on(scon.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(ccon.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer = ans.data)

    Server.run(scon)
    Client.request(ccon, 1, 10) # function - 1, parameter - 10
    wait(()->answer !== 0)

    @fact answer.fn      --> 1
    @fact answer.args[1] --> 10

    Client.stop(ccon)
    Server.stop(scon)
  end
  facts("Tests sending many commands") do
    answer = 0
    local scon::ServerConnection = Server.create(IP, PORT)
    local ccon::ClientConnection = Client.create(IP, PORT)

    Event.on(scon.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(ccon.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer = ans.data)

    Server.run(scon)
    Client.request(ccon, 1, 10)
    wait(()->answer !== 0)
    @fact answer.fn      --> 1
    @fact answer.args[1] --> 10

    Client.request(ccon, 2, 20)
    wait(()->answer.fn === 2)
    @fact answer.fn      --> 2
    @fact answer.args[1] --> 20

    Client.request(ccon, 3, "hello")
    wait(()->answer.fn === 3)
    @fact answer.fn      --> 3
    @fact answer.args[1] --> "hello"

    Client.request(ccon, 4, 44)
    wait(()->answer.fn === 4)
    @fact answer.fn      --> 4
    @fact answer.args[1] --> 44

    Client.stop(ccon)
    Server.stop(scon)
  end
  facts("Tests pooling") do
    answer = Connection.Command(0, [])
    local scon::ServerConnection = Server.create(IP, PORT)
    local ccon::ClientConnection = Client.create(IP, PORT)

    Event.on(scon.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(ccon.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer = ans.data)

    Server.run(scon)

    for i=1:10
      Client.request(ccon, i, i * 10)
      wait(()->answer.fn === i)
      @fact answer.fn      --> i
      @fact answer.args[1] --> i * 10
    end

    Client.stop(ccon)
    Server.stop(scon)
  end
  facts("Tests huge amount of requests") do
    answer = Connection.Command(0, [])
    local scon::ServerConnection = Server.create(IP, PORT)
    local ccon::ClientConnection = Client.create(IP, PORT)

    Event.on(scon.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(ccon.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer = ans.data)

    Server.run(scon)

    for i=1:100
      Client.request(ccon, i, i, i)
      wait(()->answer.fn === i)
      @fact answer.fn           --> i
      @fact length(answer.args) --> 2
      @fact answer.args[1]      --> i
      @fact answer.args[2]      --> i
    end

    Client.stop(ccon)
    Server.stop(scon)
  end
  facts("Tests sending huge data") do
    answer = Connection.Command(0, [])
    local scon::ServerConnection = Server.create(IP, PORT)
    local ccon::ClientConnection = Client.create(IP, PORT)
    local data::Array{Int, 1}    = zeros(Int, 5000000)

    Event.on(scon.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(ccon.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer = ans.data)

    Server.run(scon)
    Client.request(ccon, 1, data)
    wait(()->answer.fn === 1)

    @fact answer.fn --> 1
    @fact answer.args[1] == data --> true

    Client.stop(ccon)
    Server.stop(scon)
  end
  facts("Tests two clients for one server") do
    answer = 0
    local scon::ServerConnection = Server.create(IP, PORT)
    local ccon1::ClientConnection = Client.create(IP, PORT)
    local ccon2::ClientConnection = Client.create(IP, PORT)

    Event.on(scon.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(ccon1.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer += ans.data.args[1])
    Event.on(ccon2.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer += ans.data.args[1])

    Server.run(scon)

    for i=1:10
      Client.request(ccon1, i, i)
      Client.request(ccon2, i, i)
    end
    wait(()->answer > 109)
    @fact answer --> 110 # summa of requests

    Client.stop(ccon1)
    Client.stop(ccon2)
    Server.stop(scon)
  end
  facts("Tests two clients for two servers") do
    answer = 0
    local scon1::ServerConnection = Server.create(IP, PORT)
    local scon2::ServerConnection = Server.create(IP, PORT + 1)
    local ccon1::ClientConnection = Client.create(IP, PORT)
    local ccon2::ClientConnection = Client.create(IP, PORT + 1)

    Event.on(scon1.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(scon2.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(ccon1.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer += ans.data.args[1])
    Event.on(ccon2.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer += ans.data.args[1])

    Server.run(scon1)
    Server.run(scon2)
    for i=1:10
      Client.request(ccon1, i, i)
      Client.request(ccon2, i, i + 1)
    end
    wait(()->answer > 119)
    @fact answer --> 120 # summa of requests

    Client.stop(ccon1)
    Client.stop(ccon2)
    Server.stop(scon2)
    Server.stop(scon1)
  end
  facts("Tests two clients for two servers, but one stopped") do
    answer = 0
    local scon1::ServerConnection = Server.create(IP, PORT)
    local scon2::ServerConnection = Server.create(IP, PORT + 1)
    local ccon1::ClientConnection = Client.create(IP, PORT)
    local ccon2::ClientConnection = Client.create(IP, PORT + 1)

    Event.on(scon1.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(scon2.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(ccon1.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer += ans.data.args[1])
    Event.on(ccon2.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer += ans.data.args[1])

    Server.run(scon1)
    Server.run(scon2)
    Server.stop(scon2)
    for i=1:10
      Client.request(ccon1, i, i)
      Client.request(ccon2, i, i + 1)
    end
    wait(()->answer > 54)
    @fact answer --> 55

    Client.stop(ccon1)
    Client.stop(ccon2)
    Server.stop(scon1)
  end
  facts("Tests isOk() function works fine") do
    local answer = 0
    local scon::ServerConnection = Server.create(IP, PORT)
    local ccon::ClientConnection = Client.create(IP, PORT)

    @fact Client.isOk(ccon) --> true
    Event.on(scon.observer, Connection.EVENT_BEFORE_RESPONSE, (sock, cmd, ans)->ans.data = cmd)
    Event.on(ccon.observer, Connection.EVENT_AFTER_REQUEST, (ans::Connection.Answer)->answer = ans.data)

    Server.run(scon)
    @fact Client.isOk(ccon) --> true
    Client.request(ccon, 1, 10) # function - 1, parameter - 10
    wait(()->answer !== 0)

    @fact Client.isOk(ccon) --> true
    @fact answer.fn         --> 1
    @fact answer.args[1]    --> 10

    Client.stop(ccon)
    Server.stop(scon)

    wait(()->!Client.isOk(ccon))
    @fact Client.isOk(ccon) --> false
  end
end

max_stars_repo_name: tmptrash/jevo

max_issues_repo_name: tmptrash/jevo

max_forks_repo_name: tmptrash/jevo


text:
using LinearAlgebra

struct ValueOne; end
ValueOne()

# Compute X <- a X + b I.
function matfun_axpby!(X,a,b,Y::UniformScaling)
    m,n=size(X)
    if ~(a isa ValueOne)
        rmul!(X,a)
    end
    @inbounds for i=1:n
        X[i,i]+=(b isa ValueOne) ? 1 : b
    end
end

@inline function exp_bbc_opt_rho1_9(A)
    T=promote_type(eltype(A),Float64)
    A_copy=similar(A,T); A_copy .= A;
    return exp_bbc_opt_rho1_9!(A_copy)
end

@inline function exp_bbc_opt_rho1_9!(A)
    T=promote_type(eltype(A),Float64) # Make it work for many 'bigger' types (matrices and scalars)
    # max_memslots=8
    n=size(A,1)
    # The first slots are precomputed nodes [:A]
    memslots2 = similar(A,T)
    memslots3 = similar(A,T)
    memslots4 = similar(A,T)
    memslots5 = similar(A,T)
    memslots6 = similar(A,T)
    memslots7 = similar(A,T)
    memslots8 = similar(A,T)
    # Assign precomputed nodes memslots
    memslots1=A # overwrite A
    # Uniform scaling is exploited.
    # No matrix I explicitly allocated.
    # Computation order: Bb2 Ba2 B2 Ba3 Bb3 B3 Ba4 Bb4 B4 Ba5 Bb5 B5 Ba6 Bb6 B6 T2k8
    # Computing Bb2 = x*I+x*A
    coeff1=-0.4242607265172309
    coeff2=1.1950771657897332
    memslots2 .= coeff2.*memslots1
    mul!(memslots2,true,I*coeff1,true,true)
    # Computing Ba2 = x*I+x*A
    coeff1=-0.4242607265172309
    coeff2=1.1950771657897332
    memslots3 .= coeff2.*memslots1
    mul!(memslots3,true,I*coeff1,true,true)
    # Computing B2 with operation: mult
    mul!(memslots4,memslots3,memslots2)
    # Deallocating Ba2 in slot 3
    # Deallocating Bb2 in slot 2
    # Computing Ba3 = x*I+x*A+x*B2
    coeff1=-0.38075288501512605
    coeff2=0.8627222226009553
    coeff3=0.021223247723999996
    memslots2 .= coeff2.*memslots1 .+ coeff3.*memslots4
    mul!(memslots2,true,I*coeff1,true,true)
    # Computing Bb3 = x*I+x*A+x*B2
    coeff1=-0.021792993546751255
    coeff2=-0.3404755645503017
    coeff3=0.876565481553418
    memslots3 .= coeff2.*memslots1 .+ coeff3.*memslots4
    mul!(memslots3,true,I*coeff1,true,true)
    # Computing B3 with operation: mult
    mul!(memslots5,memslots2,memslots3)
    # Deallocating Ba3 in slot 2
    # Deallocating Bb3 in slot 3
    # Computing Ba4 = x*I+x*A+x*B2+x*B3
    coeff1=5.9466829480949973e-5
    coeff2=-0.0034728192074554225
    coeff3=-0.26578830898107336
    coeff4=0.9731527852522692
    memslots2 .= coeff2.*memslots1 .+ coeff3.*memslots4 .+ coeff4.*memslots5
    mul!(memslots2,true,I*coeff1,true,true)
    # Computing Bb4 = x*I+x*A+x*B2+x*B3
    coeff1=5.9466829480949973e-5
    coeff2=-0.0034728192074554225
    coeff3=-0.26578830898107336
    coeff4=0.9731527852522692
    memslots3 .= coeff2.*memslots1 .+ coeff3.*memslots4 .+ coeff4.*memslots5
    mul!(memslots3,true,I*coeff1,true,true)
    # Computing B4 with operation: mult
    mul!(memslots6,memslots2,memslots3)
    # Deallocating Ba4 in slot 2
    # Deallocating Bb4 in slot 3
    # Computing Ba5 = x*I+x*A+x*B2+x*B3+x*B4
    coeff1=0.015468999442833017
    coeff2=-0.24257817849158173
    coeff3=-0.004371767791483258
    coeff4=-0.00033737278567153267
    coeff5=-1.0818706572379708e-7
    memslots2 .= coeff2.*memslots1 .+ coeff3.*memslots4 .+ coeff4.*memslots5 .+ coeff5.*memslots6
    mul!(memslots2,true,I*coeff1,true,true)
    # Computing Bb5 = x*I+x*A+x*B2+x*B3+x*B4
    coeff1=0.025702668821420974
    coeff2=0.038656450236714296
    coeff3=-0.2493161704221847
    coeff4=-0.010629231499670367
    coeff5=-2.2644581317176334e-6
    memslots3 .= coeff2.*memslots1 .+ coeff3.*memslots4 .+ coeff4.*memslots5 .+ coeff5.*memslots6
    mul!(memslots3,true,I*coeff1,true,true)
    # Computing B5 with operation: mult
    mul!(memslots7,memslots2,memslots3)
    # Deallocating Ba5 in slot 2
    # Deallocating Bb5 in slot 3
    # Computing Ba6 = x*I+x*A+x*B2+x*B3+x*B4+x*B5
    coeff1=-11.089873841786654
    coeff2=1.5695850557582407
    coeff3=0.10777934093048946
    coeff4=-0.0547023784540487
    coeff5=1.1843377663664171e-5
    coeff6=0.9049940153322246
    memslots2 .= coeff2.*memslots1 .+ coeff3.*memslots4 .+ coeff4.*memslots5 .+ coeff5.*memslots6 .+ coeff6.*memslots7
    mul!(memslots2,true,I*coeff1,true,true)
    # Computing Bb6 = x*I+x*A+x*B2+x*B3+x*B4+x*B5
    coeff1=-0.0688394655881371
    coeff2=-0.10086875671987898
    coeff3=0.03935278313404004
    coeff4=-0.05834755130517858
    coeff5=1.1857830431851822e-5
    coeff6=1.144156658763187
    memslots3 .= coeff2.*memslots1 .+ coeff3.*memslots4 .+ coeff4.*memslots5 .+ coeff5.*memslots6 .+ coeff6.*memslots7
    mul!(memslots3,true,I*coeff1,true,true)
    # Computing B6 with operation: mult
    mul!(memslots8,memslots2,memslots3)
    # Deallocating Ba6 in slot 2
    # Deallocating Bb6 in slot 3
    # Computing T2k8 = x*I+x*A+x*B2+x*B3+x*B4+x*B5+x*B6
    coeff1=-0.00923583715392215
    coeff2=0.35247666711675785
    coeff3=1.598102175541146
    coeff4=0.4923984017940168
    coeff5=-4.8910943480715535e-5
    coeff6=-0.037592213904829044
    coeff7=1.1421298417742292
    # Smart lincomb recycle A
    memslots1 .= coeff2.*memslots1 .+ coeff3.*memslots4 .+ coeff4.*memslots5 .+ coeff5.*memslots6 .+ coeff6.*memslots7 .+ coeff7.*memslots8
    mul!(memslots1,true,I*coeff1,true,true)
    # Deallocating B2 in slot 4
    # Deallocating B3 in slot 5
    # Deallocating B4 in slot 6
    # Deallocating B5 in slot 7
    # Deallocating B6 in slot 8
    return memslots1 # Returning T2k8
end

max_stars_repo_name: matrixfunctions/GraphMatFunData

max_issues_repo_name: matrixfunctions/GraphMatFunData

max_forks_repo_name: matrixfunctions/GraphMatFunData


text:
module MiniFB
using Colors
using MiniFB_jll

using CEnum

include("ctypes.jl")
export Ctm, Ctime_t, Cclock_t

include("libminifb_common.jl")
include( "libminifb_api.jl")

"""
    mfb_rgb(r, g, b)::UInt32

convert 8 bit color channels to a single 32 bit buffer. Input should be integers 0-255
"""
function mfb_rgb(r, g, b)::UInt32
    r=convert(UInt32, r)
    g=convert(UInt16, g)
    r << 16 | g << 8 | b
end

"""
    mfb_rgb(c::Colorant)::UInt32

convert a color object from Colors.jl into a 32 bit buffer.
"""
function mfb_rgb(c::Colorant)::UInt32
    cRGB24 = convert(RGB24, c)
    cr, cg, cb = [reinterpret(UInt8, c) for c in (red(cRGB24), green(cRGB24), blue(cRGB24))]
    return mfb_rgb(cr, cg, cb)
end

foreach(names(@__MODULE__, all=true)) do s
   if startswith(string(s), "mfb_")
       @eval export $s
   end
end

include( "libminifb_docs.jl")

end