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

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

Associates an AWS Certificate Manager (ACM) Amazon Resource Name (ARN) with AWS Elemental
MediaConvert.

# Arguments
- `arn`: The ARN of the ACM certificate that you want to associate with your MediaConvert
  resource.

"""
associate_certificate(arn; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/certificates", Dict{String, Any}("arn"=>arn); aws_config=aws_config)
associate_certificate(arn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/certificates", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("arn"=>arn), params)); aws_config=aws_config)

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

Permanently cancel a job. Once you have canceled a job, you can't start it again.

# Arguments
- `id`: The Job ID of the job to be cancelled.

"""
cancel_job(id; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("DELETE", "/2017-08-29/jobs/$(id)"; aws_config=aws_config)
cancel_job(id, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("DELETE", "/2017-08-29/jobs/$(id)", params; aws_config=aws_config)

"""
    create_job(role, settings)
    create_job(role, settings, params::Dict{String,<:Any})

Create a new transcoding job. For information about jobs and job settings, see the User
Guide at http://docs.aws.amazon.com/mediaconvert/latest/ug/what-is.html

# Arguments
- `role`: Required. The IAM role you use for creating this job. For details about
  permissions, see the User Guide topic at the User Guide at
  https://docs.aws.amazon.com/mediaconvert/latest/ug/iam-role.html.
- `settings`: JobSettings contains all the transcode settings for a job.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"accelerationSettings"`: Optional. Accelerated transcoding can significantly speed up
  jobs with long, visually complex content. Outputs that use this feature incur pro-tier
  pricing. For information about feature limitations, see the AWS Elemental MediaConvert User
  Guide.
- `"billingTagsSource"`: Optional. Choose a tag type that AWS Billing and Cost Management
  will use to sort your AWS Elemental MediaConvert costs on any billing report that you set
  up. Any transcoding outputs that don't have an associated tag will appear in your billing
  report unsorted. If you don't choose a valid value for this field, your job outputs will
  appear on the billing report unsorted.
- `"clientRequestToken"`: Optional. Idempotency token for CreateJob operation.
- `"hopDestinations"`: Optional. Use queue hopping to avoid overly long waits in the
  backlog of the queue that you submit your job to. Specify an alternate queue and the
  maximum time that your job will wait in the initial queue before hopping. For more
  information about this feature, see the AWS Elemental MediaConvert User Guide.
- `"jobTemplate"`: Optional. When you create a job, you can either specify a job template
  or specify the transcoding settings individually.
- `"priority"`: Optional. Specify the relative priority for this job. In any given queue,
  the service begins processing the job with the highest value first. When more than one job
  has the same priority, the service begins processing the job that you submitted first. If
  you don't specify a priority, the service uses the default value 0.
- `"queue"`: Optional. When you create a job, you can specify a queue to send it to. If you
  don't specify, the job will go to the default queue. For more about queues, see the User
  Guide topic at https://docs.aws.amazon.com/mediaconvert/latest/ug/what-is.html.
- `"simulateReservedQueue"`: Optional. Enable this setting when you run a test job to
  estimate how many reserved transcoding slots (RTS) you need. When this is enabled,
  MediaConvert runs your job from an on-demand queue with similar performance to what you
  will see with one RTS in a reserved queue. This setting is disabled by default.
- `"statusUpdateInterval"`: Optional. Specify how often MediaConvert sends STATUS_UPDATE
  events to Amazon CloudWatch Events. Set the interval, in seconds, between status updates.
  MediaConvert sends an update at this interval from the time the service begins processing
  your job to the time it completes the transcode or encounters an error.
- `"tags"`: Optional. The tags that you want to add to the resource. You can tag resources
  with a key-value pair or with only a key.  Use standard AWS tags on your job for automatic
  integration with AWS services and for custom integrations and workflows.
- `"userMetadata"`: Optional. User-defined metadata that you want to associate with an
  MediaConvert job. You specify metadata in key/value pairs.  Use only for existing
  integrations or workflows that rely on job metadata tags. Otherwise, we recommend that you
  use standard AWS tags.
"""
create_job(role, settings; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/jobs", Dict{String, Any}("role"=>role, "settings"=>settings, "clientRequestToken"=>string(uuid4())); aws_config=aws_config)
create_job(role, settings, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/jobs", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("role"=>role, "settings"=>settings, "clientRequestToken"=>string(uuid4())), params)); aws_config=aws_config)

"""
    create_job_template(name, settings)
    create_job_template(name, settings, params::Dict{String,<:Any})

Create a new job template. For information about job templates see the User Guide at
http://docs.aws.amazon.com/mediaconvert/latest/ug/what-is.html

# Arguments
- `name`: The name of the job template you are creating.
- `settings`: JobTemplateSettings contains all the transcode settings saved in the template
  that will be applied to jobs created from it.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"accelerationSettings"`: Accelerated transcoding can significantly speed up jobs with
  long, visually complex content. Outputs that use this feature incur pro-tier pricing. For
  information about feature limitations, see the AWS Elemental MediaConvert User Guide.
- `"category"`: Optional. A category for the job template you are creating
- `"description"`: Optional. A description of the job template you are creating.
- `"hopDestinations"`: Optional. Use queue hopping to avoid overly long waits in the
  backlog of the queue that you submit your job to. Specify an alternate queue and the
  maximum time that your job will wait in the initial queue before hopping. For more
  information about this feature, see the AWS Elemental MediaConvert User Guide.
- `"priority"`: Specify the relative priority for this job. In any given queue, the service
  begins processing the job with the highest value first. When more than one job has the same
  priority, the service begins processing the job that you submitted first. If you don't
  specify a priority, the service uses the default value 0.
- `"queue"`: Optional. The queue that jobs created from this template are assigned to. If
  you don't specify this, jobs will go to the default queue.
- `"statusUpdateInterval"`: Specify how often MediaConvert sends STATUS_UPDATE events to
  Amazon CloudWatch Events. Set the interval, in seconds, between status updates.
  MediaConvert sends an update at this interval from the time the service begins processing
  your job to the time it completes the transcode or encounters an error.
- `"tags"`: The tags that you want to add to the resource. You can tag resources with a
  key-value pair or with only a key.
"""
create_job_template(name, settings; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/jobTemplates", Dict{String, Any}("name"=>name, "settings"=>settings); aws_config=aws_config)
create_job_template(name, settings, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/jobTemplates", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("name"=>name, "settings"=>settings), params)); aws_config=aws_config)

"""
    create_preset(name, settings)
    create_preset(name, settings, params::Dict{String,<:Any})

Create a new preset. For information about job templates see the User Guide at
http://docs.aws.amazon.com/mediaconvert/latest/ug/what-is.html

# Arguments
- `name`: The name of the preset you are creating.
- `settings`: Settings for preset

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"category"`: Optional. A category for the preset you are creating.
- `"description"`: Optional. A description of the preset you are creating.
- `"tags"`: The tags that you want to add to the resource. You can tag resources with a
  key-value pair or with only a key.
"""
create_preset(name, settings; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/presets", Dict{String, Any}("name"=>name, "settings"=>settings); aws_config=aws_config)
create_preset(name, settings, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/presets", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("name"=>name, "settings"=>settings), params)); aws_config=aws_config)

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

Create a new transcoding queue. For information about queues, see Working With Queues in
the User Guide at
https://docs.aws.amazon.com/mediaconvert/latest/ug/working-with-queues.html

# Arguments
- `name`: The name of the queue that you are creating.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"description"`: Optional. A description of the queue that you are creating.
- `"pricingPlan"`: Specifies whether the pricing plan for the queue is on-demand or
  reserved. For on-demand, you pay per minute, billed in increments of .01 minute. For
  reserved, you pay for the transcoding capacity of the entire queue, regardless of how much
  or how little you use it. Reserved pricing requires a 12-month commitment. When you use the
  API to create a queue, the default is on-demand.
- `"reservationPlanSettings"`: Details about the pricing plan for your reserved queue.
  Required for reserved queues and not applicable to on-demand queues.
- `"status"`: Initial state of the queue. If you create a paused queue, then jobs in that
  queue won't begin.
- `"tags"`: The tags that you want to add to the resource. You can tag resources with a
  key-value pair or with only a key.
"""
create_queue(name; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/queues", Dict{String, Any}("name"=>name); aws_config=aws_config)
create_queue(name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/queues", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("name"=>name), params)); aws_config=aws_config)

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

Permanently delete a job template you have created.

# Arguments
- `name`: The name of the job template to be deleted.

"""
delete_job_template(name; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("DELETE", "/2017-08-29/jobTemplates/$(name)"; aws_config=aws_config)
delete_job_template(name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("DELETE", "/2017-08-29/jobTemplates/$(name)", params; aws_config=aws_config)

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

Permanently delete a preset you have created.

# Arguments
- `name`: The name of the preset to be deleted.

"""
delete_preset(name; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("DELETE", "/2017-08-29/presets/$(name)"; aws_config=aws_config)
delete_preset(name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("DELETE", "/2017-08-29/presets/$(name)", params; aws_config=aws_config)

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

Permanently delete a queue you have created.

# Arguments
- `name`: The name of the queue that you want to delete.

"""
delete_queue(name; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("DELETE", "/2017-08-29/queues/$(name)"; aws_config=aws_config)
delete_queue(name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("DELETE", "/2017-08-29/queues/$(name)", params; aws_config=aws_config)

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

Send an request with an empty body to the regional API endpoint to get your account API
endpoint.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Optional. Max number of endpoints, up to twenty, that will be returned at
  one time.
- `"mode"`: Optional field, defaults to DEFAULT. Specify DEFAULT for this operation to
  return your endpoints if any exist, or to create an endpoint for you and return it if one
  doesn't already exist. Specify GET_ONLY to return your endpoints if any exist, or an empty
  list if none exist.
- `"nextToken"`: Use this string, provided with the response to a previous request, to
  request the next batch of endpoints.
"""
describe_endpoints(; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/endpoints"; aws_config=aws_config)
describe_endpoints(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/endpoints", params; aws_config=aws_config)

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

Removes an association between the Amazon Resource Name (ARN) of an AWS Certificate Manager
(ACM) certificate and an AWS Elemental MediaConvert resource.

# Arguments
- `arn`: The ARN of the ACM certificate that you want to disassociate from your
  MediaConvert resource.

"""
disassociate_certificate(arn; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("DELETE", "/2017-08-29/certificates/$(arn)"; aws_config=aws_config)
disassociate_certificate(arn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("DELETE", "/2017-08-29/certificates/$(arn)", params; aws_config=aws_config)

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

Retrieve the JSON for a specific completed transcoding job.

# Arguments
- `id`: the job ID of the job.

"""
get_job(id; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/jobs/$(id)"; aws_config=aws_config)
get_job(id, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/jobs/$(id)", params; aws_config=aws_config)

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

Retrieve the JSON for a specific job template.

# Arguments
- `name`: The name of the job template.

"""
get_job_template(name; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/jobTemplates/$(name)"; aws_config=aws_config)
get_job_template(name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/jobTemplates/$(name)", params; aws_config=aws_config)

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

Retrieve the JSON for a specific preset.

# Arguments
- `name`: The name of the preset.

"""
get_preset(name; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/presets/$(name)"; aws_config=aws_config)
get_preset(name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/presets/$(name)", params; aws_config=aws_config)

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

Retrieve the JSON for a specific queue.

# Arguments
- `name`: The name of the queue that you want information about.

"""
get_queue(name; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/queues/$(name)"; aws_config=aws_config)
get_queue(name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/queues/$(name)", params; aws_config=aws_config)

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

Retrieve a JSON array of up to twenty of your job templates. This will return the templates
themselves, not just a list of them. To retrieve the next twenty templates, use the
nextToken string returned with the array

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"category"`: Optionally, specify a job template category to limit responses to only job
  templates from that category.
- `"listBy"`: Optional. When you request a list of job templates, you can choose to list
  them alphabetically by NAME or chronologically by CREATION_DATE. If you don't specify, the
  service will list them by name.
- `"maxResults"`: Optional. Number of job templates, up to twenty, that will be returned at
  one time.
- `"nextToken"`: Use this string, provided with the response to a previous request, to
  request the next batch of job templates.
- `"order"`: Optional. When you request lists of resources, you can specify whether they
  are sorted in ASCENDING or DESCENDING order. Default varies by resource.
"""
list_job_templates(; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/jobTemplates"; aws_config=aws_config)
list_job_templates(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/jobTemplates", params; aws_config=aws_config)

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

Retrieve a JSON array of up to twenty of your most recently created jobs. This array
includes in-process, completed, and errored jobs. This will return the jobs themselves, not
just a list of the jobs. To retrieve the twenty next most recent jobs, use the nextToken
string returned with the array.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Optional. Number of jobs, up to twenty, that will be returned at one time.
- `"nextToken"`: Optional. Use this string, provided with the response to a previous
  request, to request the next batch of jobs.
- `"order"`: Optional. When you request lists of resources, you can specify whether they
  are sorted in ASCENDING or DESCENDING order. Default varies by resource.
- `"queue"`: Optional. Provide a queue name to get back only jobs from that queue.
- `"status"`: Optional. A job's status can be SUBMITTED, PROGRESSING, COMPLETE, CANCELED,
  or ERROR.
"""
list_jobs(; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/jobs"; aws_config=aws_config)
list_jobs(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/jobs", params; aws_config=aws_config)

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

Retrieve a JSON array of up to twenty of your presets. This will return the presets
themselves, not just a list of them. To retrieve the next twenty presets, use the nextToken
string returned with the array.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"category"`: Optionally, specify a preset category to limit responses to only presets
  from that category.
- `"listBy"`: Optional. When you request a list of presets, you can choose to list them
  alphabetically by NAME or chronologically by CREATION_DATE. If you don't specify, the
  service will list them by name.
- `"maxResults"`: Optional. Number of presets, up to twenty, that will be returned at one
  time
- `"nextToken"`: Use this string, provided with the response to a previous request, to
  request the next batch of presets.
- `"order"`: Optional. When you request lists of resources, you can specify whether they
  are sorted in ASCENDING or DESCENDING order. Default varies by resource.
"""
list_presets(; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/presets"; aws_config=aws_config)
list_presets(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/presets", params; aws_config=aws_config)

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

Retrieve a JSON array of up to twenty of your queues. This will return the queues
themselves, not just a list of them. To retrieve the next twenty queues, use the nextToken
string returned with the array.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"listBy"`: Optional. When you request a list of queues, you can choose to list them
  alphabetically by NAME or chronologically by CREATION_DATE. If you don't specify, the
  service will list them by creation date.
- `"maxResults"`: Optional. Number of queues, up to twenty, that will be returned at one
  time.
- `"nextToken"`: Use this string, provided with the response to a previous request, to
  request the next batch of queues.
- `"order"`: Optional. When you request lists of resources, you can specify whether they
  are sorted in ASCENDING or DESCENDING order. Default varies by resource.
"""
list_queues(; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/queues"; aws_config=aws_config)
list_queues(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/queues", params; aws_config=aws_config)

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

Retrieve the tags for a MediaConvert resource.

# Arguments
- `arn`: The Amazon Resource Name (ARN) of the resource that you want to list tags for. To
  get the ARN, send a GET request with the resource name.

"""
list_tags_for_resource(arn; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/tags/$(arn)"; aws_config=aws_config)
list_tags_for_resource(arn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("GET", "/2017-08-29/tags/$(arn)", params; aws_config=aws_config)

"""
    tag_resource(arn, tags)
    tag_resource(arn, tags, params::Dict{String,<:Any})

Add tags to a MediaConvert queue, preset, or job template. For information about tagging,
see the User Guide at
https://docs.aws.amazon.com/mediaconvert/latest/ug/tagging-resources.html

# Arguments
- `arn`: The Amazon Resource Name (ARN) of the resource that you want to tag. To get the
  ARN, send a GET request with the resource name.
- `tags`: The tags that you want to add to the resource. You can tag resources with a
  key-value pair or with only a key.

"""
tag_resource(arn, tags; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/tags", Dict{String, Any}("arn"=>arn, "tags"=>tags); aws_config=aws_config)
tag_resource(arn, tags, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("POST", "/2017-08-29/tags", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("arn"=>arn, "tags"=>tags), params)); aws_config=aws_config)

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

Remove tags from a MediaConvert queue, preset, or job template. For information about
tagging, see the User Guide at
https://docs.aws.amazon.com/mediaconvert/latest/ug/tagging-resources.html

# Arguments
- `arn`: The Amazon Resource Name (ARN) of the resource that you want to remove tags from.
  To get the ARN, send a GET request with the resource name.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"tagKeys"`: The keys of the tags that you want to remove from the resource.
"""
untag_resource(arn; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("PUT", "/2017-08-29/tags/$(arn)"; aws_config=aws_config)
untag_resource(arn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("PUT", "/2017-08-29/tags/$(arn)", params; aws_config=aws_config)

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

Modify one of your existing job templates.

# Arguments
- `name`: The name of the job template you are modifying

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"accelerationSettings"`: Accelerated transcoding can significantly speed up jobs with
  long, visually complex content. Outputs that use this feature incur pro-tier pricing. For
  information about feature limitations, see the AWS Elemental MediaConvert User Guide.
- `"category"`: The new category for the job template, if you are changing it.
- `"description"`: The new description for the job template, if you are changing it.
- `"hopDestinations"`: Optional list of hop destinations.
- `"priority"`: Specify the relative priority for this job. In any given queue, the service
  begins processing the job with the highest value first. When more than one job has the same
  priority, the service begins processing the job that you submitted first. If you don't
  specify a priority, the service uses the default value 0.
- `"queue"`: The new queue for the job template, if you are changing it.
- `"settings"`: JobTemplateSettings contains all the transcode settings saved in the
  template that will be applied to jobs created from it.
- `"statusUpdateInterval"`: Specify how often MediaConvert sends STATUS_UPDATE events to
  Amazon CloudWatch Events. Set the interval, in seconds, between status updates.
  MediaConvert sends an update at this interval from the time the service begins processing
  your job to the time it completes the transcode or encounters an error.
"""
update_job_template(name; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("PUT", "/2017-08-29/jobTemplates/$(name)"; aws_config=aws_config)
update_job_template(name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("PUT", "/2017-08-29/jobTemplates/$(name)", params; aws_config=aws_config)

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

Modify one of your existing presets.

# Arguments
- `name`: The name of the preset you are modifying.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"category"`: The new category for the preset, if you are changing it.
- `"description"`: The new description for the preset, if you are changing it.
- `"settings"`: Settings for preset
"""
update_preset(name; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("PUT", "/2017-08-29/presets/$(name)"; aws_config=aws_config)
update_preset(name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("PUT", "/2017-08-29/presets/$(name)", params; aws_config=aws_config)

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

Modify one of your existing queues.

# Arguments
- `name`: The name of the queue that you are modifying.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"description"`: The new description for the queue, if you are changing it.
- `"reservationPlanSettings"`: The new details of your pricing plan for your reserved
  queue. When you set up a new pricing plan to replace an expired one, you enter into another
  12-month commitment. When you add capacity to your queue by increasing the number of RTS,
  you extend the term of your commitment to 12 months from when you add capacity. After you
  make these commitments, you can't cancel them.
- `"status"`: Pause or activate a queue by changing its status between ACTIVE and PAUSED.
  If you pause a queue, jobs in that queue won't begin. Jobs that are running when you pause
  the queue continue to run until they finish or result in an error.
"""
update_queue(name; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("PUT", "/2017-08-29/queues/$(name)"; aws_config=aws_config)
update_queue(name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = mediaconvert("PUT", "/2017-08-29/queues/$(name)", params; aws_config=aws_config)


text:
#RSDeltaSigmaPort: Optimization functions
#-------------------------------------------------------------------------------

"values for optimal zeros when opt==1"
const _VALUES_OPTZEROS_OPT1 = [ #Currently not type stable
	[0.0], # n = 1
	[sqrt(1/3)],
	[sqrt(3/5), 0],
	sqrt.([3/7+sqrt(9/49-3/35), 3/7-sqrt(9/49-3/35)]),
	sqrt.([5/9+sqrt(25/81-5/21), 5/9-sqrt(25/81-5/21), 0]), # n = 5
	[0.23862059, 0.66120988, 0.9324696],
	[0, 0.40584371, 0.74153078, 0.94910785],
	[0.18343709, 0.52553345, 0.79666684, 0.96028993],
	[0, 0.32425101, 0.61337056, 0.83603082, 0.9681602],
	[0.1834370913, 0.5255334458, 0.7966668433, 0.9602899327], # n = 10
	[0, 0.26953955, 0.51909468, 0.73015137, 0.88706238, 0.97822864],
	[0.12523875, 0.36783403, 0.58731921, 0.7699033, 0.90411753, 0.9815607],
	[0, 0.23045331, 0.44849063, 0.64234828, 0.8015776, 0.91759824, 0.98418306],
	[0.10806212, 0.31911586, 0.51525046, 0.68729392, 0.82720185, 0.92843513, 0.98628389], # n = 14
]

"values for optimal zeros when opt==2" #or other?; is it called in other cases?
const _VALUES_OPTZEROS_OPT2 = [
	_VALUES_OPTZEROS_OPT1[1], # n = 1
	[0.0],
	_VALUES_OPTZEROS_OPT1[3],
	[0, sqrt(5/7)],
	_VALUES_OPTZEROS_OPT1[5], # n = 5
	sqrt.([0, 7/11+sqrt(56)/33, 7/11-sqrt(56)/33]),
	_VALUES_OPTZEROS_OPT1[7],
	[0, 0.50563161, 0.79017286, 0.95914731],
	_VALUES_OPTZEROS_OPT1[9],
	[0, 0.41572267, 0.67208682, 0.86238894, 0.97342121], # n = 10
	_VALUES_OPTZEROS_OPT1[11],
	[0, 0.35222363, 0.58006251, 0.76647993, 0.90281326, 0.98132047],
	_VALUES_OPTZEROS_OPT1[13],
	[0, 0.30524384, 0.50836649, 0.6836066, 0.82537239, 0.92772336, 0.98615167], # n = 14
]
@assert(length(_VALUES_OPTZEROS_OPT1) == length(_VALUES_OPTZEROS_OPT2))

"""`optZeros = ds_optzeros( n, opt=1 )`
A helper function for the synthesizeNTF function of the Delta-Sigma Toolbox.
Returns the zeros which minimize the in-band noise power of
a delta-sigma modulator's NTF.
"""
function ds_optzeros(n, opt=1)
	norig = n; n = array_round(n) #VERIFYME
	local optZeros

	if opt==0
		optZeros = zeros(ceil(Int, norig/2))
	elseif n > length(_VALUES_OPTZEROS_OPT1)
		throw(ErrorException("Optimized zeros for n>14 are not available."))
	elseif opt==1
		optZeros = _VALUES_OPTZEROS_OPT1[n]
	else
		optZeros = _VALUES_OPTZEROS_OPT2[n]
	end

	# Sort the zeros and replicate them.
	z = sort(optZeros)
	optZeros = zeros(n)
	m=1

	if mod(n,2)==1
		optZeros[1] = z[1]
		z = z[2:length(z)]
		m=m+1
	end
	for i=1:length(z)
		optZeros[m]   =  z[i]
		optZeros[m+1] = -z[i]
		m = m+2
	end
	return optZeros
end

#Last line

ext: jl


text:
## general machinery for mathematical constants

immutable MathConst{sym} <: Real end

show{sym}(io::IO, x::MathConst{sym}) = print(io, "$sym = $(string(float(x))[1:15])...")

promote_rule{s}(::Type{MathConst{s}}, ::Type{Float32}) = Float32
promote_rule{s,t}(::Type{MathConst{s}}, ::Type{MathConst{t}}) = Float64
promote_rule{s,T<:Number}(::Type{MathConst{s}}, ::Type{T}) = promote_type(Float64,T)

convert(::Type{FloatingPoint}, x::MathConst) = float64(x)
convert(::Type{Float16}, x::MathConst) = float16(float32(x))
convert{T<:Real}(::Type{Complex{T}}, x::MathConst) = convert(Complex{T}, float64(x))
convert{T<:Integer}(::Type{Rational{T}}, x::MathConst) = convert(Rational{T}, float64(x))

=={s}(::MathConst{s}, ::MathConst{s}) = true
==(::MathConst, ::MathConst) = false

hash(x::MathConst, h::Uint) = hash(object_id(x), h)

-(x::MathConst) = -float64(x)
for op in {:+, :-, :*, :/, :^}
    @eval $op(x::MathConst, y::MathConst) = $op(float64(x),float64(y))
end

macro math_const(sym, val, def)
    esym = esc(sym)
    qsym = esc(Expr(:quote, sym))
    bigconvert = isa(def,Symbol) ? quote
        function Base.convert(::Type{BigFloat}, ::MathConst{$qsym})
            c = BigFloat()
            ccall(($(string("mpfr_const_", def)), :libmpfr),
                  Cint, (Ptr{BigFloat}, Int32),
                  &c, MPFR.ROUNDING_MODE[end])
            return c
        end
    end : quote
        Base.convert(::Type{BigFloat}, ::MathConst{$qsym}) = $(esc(def))
    end
    quote
        const $esym = MathConst{$qsym}()
        $bigconvert
        Base.convert(::Type{Float64}, ::MathConst{$qsym}) = $val
        Base.convert(::Type{Float32}, ::MathConst{$qsym}) = $(float32(val))
        @assert isa(big($esym), BigFloat)
        @assert float64($esym) == float64(big($esym))
        @assert float32($esym) == float32(big($esym))
    end
end

big(x::MathConst) = convert(BigFloat,x)

## specific mathematical constants

@math_const π        3.14159265358979323846  pi
@math_const e        2.71828182845904523536  exp(big(1))
@math_const γ        0.57721566490153286061  euler
@math_const catalan  0.91596559417721901505  catalan
@math_const φ        1.61803398874989484820  (1+sqrt(big(5)))/2

# aliases
const pi = π
const eu = e
const eulergamma = γ
const golden = φ

# special behaviors

# use exp for e^x or e.^x, as in
#    ^(::MathConst{:e}, x::Number) = exp(x)
#    .^(::MathConst{:e}, x) = exp(x)
# but need to loop over types to prevent ambiguity with generic rules for ^(::Number, x) etc.
for T in (MathConst, Rational, Integer, Number)
    ^(::MathConst{:e}, x::T) = exp(x)
end
for T in (Range, BitArray, SparseMatrixCSC, StridedArray, AbstractArray)
    .^(::MathConst{:e}, x::T) = exp(x)
end
^(::MathConst{:e}, x::AbstractMatrix) = expm(x)

log(::MathConst{:e}) = 1 # use 1 to correctly promote expressions like log(x)/log(e)
log(::MathConst{:e}, x) = log(x)

max_stars_repo_name: jakebolewski/julia

max_issues_repo_name: jakebolewski/julia

max_forks_repo_name: jakebolewski/julia


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

module DiskResourceProviderClient

using Random
using Dates
using HTTP
using Swagger
import Swagger: field_name, property_type, hasproperty, validate_property, SwaggerApi, SwaggerModel
import Base: convert, propertynames

include("modelincludes.jl")

include("api_DisksApi.jl")
include("api_SnapshotsApi.jl")

# export models
export convert, AccessUri
export convert, AccessUriOutput
export convert, AccessUriRaw
export convert, ApiError
export convert, ApiErrorBase
export convert, CreationData
export convert, DiskList
export convert, DiskProperties
export convert, DiskSku
export convert, DiskUpdateProperties
export convert, EncryptionSettings
export convert, GrantAccessData
export convert, ImageDiskReference
export convert, InnerError
export convert, KeyVaultAndKeyReference
export convert, KeyVaultAndSecretReference
export convert, OperationStatusResponse
export convert, Resource
export convert, ResourceUpdate
export convert, SnapshotList
export convert, SourceVault
export convert, Disk
export convert, DiskUpdate
export convert, Snapshot
export convert, SnapshotUpdate

# export operations
export convert, DisksApi, SnapshotsApi

export check_required, field_name, property_type, hasproperty, propertynames, validate_property, convert

end


text:
using Test, ImageFeatures, Images, TestImages, Distributions

@testset "Test freak params" begin
    freak_params = FREAK(pattern_scale = 20.0)
    @test freak_params.pattern_scale == 20.0
    pt, st = ImageFeatures._freak_tables(20.0)
    @test freak_params.pattern_table == pt
    @test freak_params.smoothing_table == st
end

@testset "Testing with Standard Images - Lighthouse (Rotation 45)" begin
    img = testimage("lighthouse")
    img_array_1 = Gray.(img)
    img_array_2 = _warp(img_array_1, pi / 4)

    keypoints_1 = Keypoints(fastcorners(img_array_1, 12, 0.35))
    keypoints_2 = Keypoints(fastcorners(img_array_2, 12, 0.35))
    freak_params = FREAK()

    desc_1, ret_keypoints_1 = create_descriptor(img_array_1, keypoints_1, freak_params)
    desc_2, ret_keypoints_2 = create_descriptor(img_array_2, keypoints_2, freak_params)
    matches = match_keypoints(ret_keypoints_1, ret_keypoints_2, desc_1, desc_2, 0.1)
    reverse_keypoints_1 = [_reverserotate(m[1], pi / 4, (256, 384)) for m in matches]
    @test all(isapprox(rk[1], m[2][1], atol = 4) && isapprox(rk[2], m[2][2], atol = 4) for (rk, m) in zip(reverse_keypoints_1, matches))
end

@testset "Testing with Standard Images - Lighthouse (Rotation 45, Translation (50, 40))" begin
    img = testimage("lighthouse")
    img_array_1 = Gray.(img)
    img_temp_2 = _warp(img_array_1, pi / 4)
    img_array_2 = _warp(img_temp_2, 50, 40)

    keypoints_1 = Keypoints(fastcorners(img_array_1, 12, 0.35))
    keypoints_2 = Keypoints(fastcorners(img_array_2, 12, 0.35))
    freak_params = FREAK()

    desc_1, ret_keypoints_1 = create_descriptor(img_array_1, keypoints_1, freak_params)
    desc_2, ret_keypoints_2 = create_descriptor(img_array_2, keypoints_2, freak_params)
    matches = match_keypoints(ret_keypoints_1, ret_keypoints_2, desc_1, desc_2, 0.1)
    reverse_keypoints_1 = [_reverserotate(m[1], pi / 4, (256, 384)) + CartesianIndex(50, 40) for m in matches]
    @test all(isapprox(rk[1], m[2][1], atol = 3) && isapprox(rk[2], m[2][2], atol = 3) for (rk, m) in zip(reverse_keypoints_1, matches))
end

@testset "Testing with Standard Images - Lighthouse (Rotation 75, Translation (50, 40))" begin
    img = testimage("lighthouse")
    img_array_1 = Gray.(img)
    img_temp_2 = _warp(img_array_1, 5 * pi / 6)
    img_array_2 = _warp(img_temp_2, 50, 40)

    keypoints_1 = Keypoints(fastcorners(img_array_1, 12, 0.35))
    keypoints_2 = Keypoints(fastcorners(img_array_2, 12, 0.35))
    freak_params = FREAK()

    desc_1, ret_keypoints_1 = create_descriptor(img_array_1, keypoints_1, freak_params)
    desc_2, ret_keypoints_2 = create_descriptor(img_array_2, keypoints_2, freak_params)
    matches = match_keypoints(ret_keypoints_1, ret_keypoints_2, desc_1, desc_2, 0.1)
    reverse_keypoints_1 = [_reverserotate(m[1], 5 * pi / 6, (256, 384)) + CartesianIndex(50, 40) for m in matches]
    @test all(isapprox(rk[1], m[2][1], atol = 4) && isapprox(rk[2], m[2][2], atol = 4) for (rk, m) in zip(reverse_keypoints_1, matches))
end

@testset "Testing with Standard Images - Lena (Rotation 45, Translation (10, 20))" begin
    img = testimage("lena_gray_512")
    img_array_1 = Gray.(img)
    img_temp_2 = _warp(img_array_1, pi / 4)
    img_array_2 = _warp(img_temp_2, 10, 20)

    keypoints_1 = Keypoints(fastcorners(img_array_1, 12, 0.2))
    keypoints_2 = Keypoints(fastcorners(img_array_2, 12, 0.2))
    freak_params = FREAK()

    desc_1, ret_keypoints_1 = create_descriptor(img_array_1, keypoints_1, freak_params)
    desc_2, ret_keypoints_2 = create_descriptor(img_array_2, keypoints_2, freak_params)
    matches = match_keypoints(ret_keypoints_1, ret_keypoints_2, desc_1, desc_2, 0.1)
    reverse_keypoints_1 = [_reverserotate(m[1], pi / 4, (256, 256)) + CartesianIndex(10, 20) for m in matches]
    @test isapprox(sum(isapprox(rk[1], m[2][1], atol = 4) && isapprox(rk[2], m[2][2], atol = 4) for (rk, m) in zip(reverse_keypoints_1, matches)), length(matches), atol = 2)
end


text:
# Model
include_model("biped")

# Visualize
# - Pkg.add any external deps from visualize.jl
include(joinpath(pwd(), "models/visualize.jl"))
vis = Visualizer()
render(vis)

# Configurations
# 1: x pos
# 2: z pos
# 3: torso angle (rel. to downward vertical)
# 4: thigh 1 angle (rel. to downward vertical)
# 5: calf 1 (rel. to thigh 1)
# 6: thigh 2 (rel. to downward vertical)
# 7: calf 2 (rel. to thigh 2)
# θ = pi / 12.5
# q1 = initial_configuration(model, θ) # generate initial config from θ
# qT = copy(q1)
# qT[1] += 1.0
# q1[3] -= pi / 30.0
# q1[4] += pi / 20.0
# q1[5] -= pi / 10.0
# q1, qT = loop_configurations(model, θ)
# qT[1] += 1.0

θ = pi / 5.0
q1 = zeros(model.nq)
q1[3] = pi
q1[4] = θ #+ pi / 20.0
q1[5] = -2.0 * θ
q1[6] = θ #- pi / 20.0
q1[7] = -2.0 * θ
q1[2] = model.l2 * cos(θ) + model.l3 * cos(θ)
qT = copy(q1)
qT[1] = 2.5
# qT[2] = 1.0
kinematics_2(model, q1, body = :leg_1, mode = :ee)[2]
kinematics_2(model, q1, body = :leg_2, mode = :ee)[2]

visualize!(vis, model, [q1])

# Horizon
T = 26

# Time step
tf = 2.5
h = tf / (T - 1)

# Bounds

# control
# u = (τ1..4, λ1..2, β1..4, ψ1..2, η1...4, s1)
# ul <= u <= uu
_uu = Inf * ones(model.m)
_uu[model.idx_u] = model.uU

_ul = zeros(model.m)
_ul[model.idx_u] = model.uL
ul, uu = control_bounds(model, T, _ul, _uu)

u1 = initial_torque(model, q1, h)[model.idx_u]

xl, xu = state_bounds(model, T,
    x1 = [q1; q1],
    xT = [qT; qT])

# Objective
include_objective(["velocity", "nonlinear_stage"])

q_ref = linear_interpolation(q1, qT, T)
x0 = configuration_to_state(q_ref)

# penalty on slack variable
obj_penalty = PenaltyObjective(1.0e5, model.m)

# quadratic tracking objective
# Σ (x - xref)' Q (x - x_ref) + (u - u_ref)' R (u - u_ref)
obj_control = quadratic_tracking_objective(
    [zeros(model.n, model.n) for t = 1:T],
    [Diagonal([1.0e-1 * ones(model.nu)..., zeros(model.m - model.nu)...]) for t = 1:T-1],
    [zeros(model.n) for t = 1:T],
    [[copy(u1); zeros(model.m - model.nu)] for t = 1:T-1])

# quadratic velocity penalty
# Σ v' Q v
obj_velocity = velocity_objective(
    [Diagonal(1.0 * ones(model.nq)) for t = 1:T-1],
    model.nq,
    h = h,
    idx_angle = collect([3, 4, 5, 6, 7]))

# torso height
t_h = kinematics_1(model, q1, body = :torso, mode = :com)[2]
l_stage_torso_h(x, u, t) = 10.0 * (kinematics_1(model, view(x, 8:14), body = :torso, mode = :com)[2] - t_h)^2.0
l_terminal_torso_h(x) = 0.0 #* (kinematics_1(model, view(x, 8:14), body = :torso, mode = :com)[2] - t_h)^2.0
obj_torso_h = nonlinear_stage_objective(l_stage_torso_h, l_terminal_torso_h)

# torso lateral
l_stage_torso_lat(x, u, t) = (1.0 * (kinematics_1(model, view(x, 8:14), body = :torso, mode = :com)[1] - kinematics_1(model, view(x0[t], 8:14), body = :torso, mode = :com)[1])^2.0)
l_terminal_torso_lat(x) = (0.0 * (kinematics_1(model, view(x, 8:14), body = :torso, mode = :com)[1] - kinematics_1(model, view(x0[T], 8:14), body = :torso, mode = :com)[1])^2.0)
obj_torso_lat = nonlinear_stage_objective(l_stage_torso_lat, l_terminal_torso_lat)

# foot 1 height
l_stage_fh1(x, u, t) = 10.0 * (kinematics_2(model, view(x, 8:14), body = :leg_1, mode = :ee)[2] - 0.025)^2.0
l_terminal_fh1(x) = 0.0 * (kinematics_2(model, view(x, 8:14), body = :leg_1, mode = :ee)[2])^2.0
obj_fh1 = nonlinear_stage_objective(l_stage_fh1, l_terminal_fh1)

# foot 2 height
l_stage_fh2(x, u, t) = 10.0 * (kinematics_2(model, view(x, 8:14), body = :leg_2, mode = :ee)[2] - 0.025)^2.0
l_terminal_fh2(x) = 0.0 * (kinematics_2(model, view(x, 8:14), body = :leg_2, mode = :ee)[2])^2.0
obj_fh2 = nonlinear_stage_objective(l_stage_fh2, l_terminal_fh2)

# initial configuration
# function l_stage_conf(x, u, t)
#     if t == 1
#         return 0.0#(x - [q1; q1])' * Diagonal(1000.0 * ones(model.n)) * (x - [q1; q1])
#     else
#         return 0.0
#     end
# end
# l_terminal_conf(x) = (x - [qT; qT])' * Diagonal(1000.0 * ones(model.n)) * (x - [qT; qT])
# obj_conf = nonlinear_stage_objective(l_stage_conf, l_terminal_conf)

obj = MultiObjective([obj_penalty,
                      obj_control,
                      obj_velocity,
                      obj_torso_h,
                      obj_torso_lat,
                      obj_fh1,
                      obj_fh2])
                      # obj_conf])

# Constraints
include_constraints("contact")

con_contact = contact_constraints(model, T)
con = multiple_constraints([con_contact])

# Problem
prob = trajectory_optimization_problem(model,
               obj,
               T,
               h = h,
               xl = xl,
               xu = xu,
               ul = ul,
               uu = uu,
               con = con)

# trajectory initialization
u0 = [[u1; 1.0e-3 * rand(model.m - model.nu)] for t = 1:T-1] # random controls

# Pack trajectories into vector
z0 = pack(x0, u0, prob)

# Solve
include_snopt()

@time z̄ , info = solve(prob, copy(z0),
    nlp = :SNOPT7,
    tol = 1.0e-3, c_tol = 1.0e-3,
    time_limit = 60 * 3, mapl = 5)

check_slack(z̄, prob)
x̄, ū = unpack(z̄, prob)

# Visualize
visualize!(vis, model, state_to_configuration(x̄), Δt = h)


text:
include("../base.jl")
import Random

patrones = [
    [2, 4],
    [1, 6],
    [8, 2],
    [5, 5],
    [0, 9],
    [12, 4],
    [10, 4],
    [1, 9],
    [8, 3],
    [10, 20],
    [7, 5],
]

x = Array{Int}(undef, 11)
y = Array{Int}(undef, 11)

for i = 1:11
    x[i] = patrones[i][1]
    y[i] = patrones[i][2]
end

clases = [true, true, false, true, true, false, false, true, false, true, false]

function CCR(genotype::STGPGenotype, gpExperimentInfo::STGPInfo, clases::Array{Bool}, x::Array{Int}, y::Array{Int})

    aciertos = 0

    fenotipo = getPhenotype(genotype)

    for i=1:11
        clase_estimada = evaluate(fenotipo, ["x", "y"], x[i], y[i])
        if typeof(clase_estimada) <: Bool
            if clases[i] == clase_estimada
                aciertos += 1
            end
        end
    end

    return (aciertos/11)*100
end

println("hola")
"""
rng = Random.MersenneTwister(142)

setIndividualType(STGPGenotype)
setRNG(rng)
setGPExperimentInfo()

setStopCondition(maxIterations = 50)
setEvaluator([FitnessFunction(CCR, clases, x, y, weight=1)])
setGenerator(rampedHalfHalfGenerator, popSize = 50, generateOneByOne = false)
setSelector(tournamentSelector, 5)
setCrossoverOperator(subtreeCross, probability = 0.9)
setMutationOperator(onePointMutation, probability = 0.2)
setReplacementOperator(replaceAllPopulation)

genPopulation!(GenJ)
evaluate!(GenJ, GenJ._population)
#phenotype, fenotipo = getPhenotype(GenJ._population[1]._genotype, GenJ._experimentInfo._GPExperimentInfo)
#evaluate!(GenJ, GenJ._population)
#children = onePointCross(GenJ._population[1]._genotype, GenJ._population[2]._genotype, GenJ._experimentInfo._GPExperimentInfo, rng)
#mutated = pointMutation(GenJ._population[1]._genotype, GenJ._experimentInfo._GPExperimentInfo, rng, 0.2)

"""

setIndividualType(STGPGenotype)
setRandomSeed(2)
setGPExperimentInfo()

setStopCondition(maxIterations = 50)
setEvaluator([FitnessFunction(CCR, clases, x, y, weight=1)])
setGenerator(rampedHalfHalfGenerator, popSize = 50, generateOneByOne = false)
setSelector(tournamentSelector, 5)
setCrossoverOperator(subtreeCross, probability = 0.9)
setMutationOperator(onePointMutation, probability = 0.2)
setReplacementOperator(replaceAllPopulation)

@time runGenJ(verbose = false)

max_stars_repo_name: SergioGmezM/GeneticJulia

max_issues_repo_name: SergioGmezM/GeneticJulia

max_forks_repo_name: SergioGmezM/GeneticJulia


text:
## Instruction and TapedFunction

abstract type AbstractInstruction end
const RawTape = Vector{AbstractInstruction}

mutable struct TapedFunction{F, TapeType}
    func::F # maybe a function, a constructor, or a callable object
    arity::Int
    ir::Core.CodeInfo
    tape::TapeType
    counter::Int
    bindings::Dict{Symbol, Any}
    retval::Symbol

    function TapedFunction{F, T}(f::F, args...; cache=false) where {F, T}
        args_type = _accurate_typeof.(args)
        cache_key = (f, args_type...)

        if cache && haskey(TRCache, cache_key) # use cache
            cached_tf = TRCache[cache_key]::TapedFunction{F, T}
            tf = copy(cached_tf)
            tf.counter = 1
            return tf
        end

        ir = CodeInfoTools.code_inferred(f, args_type...)
        bindings, tape = translate!(RawTape(), ir)

        tf = new{F, T}(f, length(args), ir, tape, 1, bindings, :none)
        TRCache[cache_key] = tf # set cache
        return tf
    end

    TapedFunction(f, args...; cache=false) =
        TapedFunction{typeof(f), RawTape}(f, args...; cache=cache)

    function TapedFunction{F, T0}(tf::TapedFunction{F, T1}) where {F, T0, T1}
        new{F, T0}(tf.func, tf.arity, tf.ir, tf.tape,
               tf.counter, tf.bindings, :none)
    end

    TapedFunction(tf::TapedFunction{F, T}) where {F, T} = TapedFunction{F, T}(tf)
end

const TRCache = LRU{Tuple, TapedFunction}(maxsize=10)
const CompiledTape = Vector{FunctionWrapper{Nothing, Tuple{TapedFunction}}}

function Base.convert(::Type{CompiledTape}, tape::RawTape)
    ctape = CompiledTape(undef, length(tape))
    for idx in 1:length(tape)
        ctape[idx] = FunctionWrapper{Nothing, Tuple{TapedFunction}}(tape[idx])
    end
    return ctape
end

compile(tf::TapedFunction{F, RawTape}) where {F} = TapedFunction{F, CompiledTape}(tf)

# const TypedFunction = FunctionWrapper
struct TypedFunction{OT, IT<:Tuple}
    func::Function
    retval::Base.RefValue{OT}
    TypedFunction{OT, IT}(f::Function) where {OT, IT<:Tuple} = new{OT, IT}(f, Ref{OT}())
end

function (f::TypedFunction{OT, IT})(args...) where {OT, IT<:Tuple}
    output = f.func(args...)
    f.retval[] = OT === Nothing ? nothing : output
    return f.retval[]
end

struct Box{T}
    id::Symbol
    get::TypedFunction{T, Tuple{TapedFunction, Symbol}}
    set::TypedFunction{Nothing, Tuple{TapedFunction, Symbol, T}}

    function Box{T}(id::Symbol) where T
        return new(id,
                   TypedFunction{T, Tuple{TapedFunction, Symbol}}(_inner_getter),
                   TypedFunction{Nothing, Tuple{TapedFunction, Symbol, T}}(_inner_setter))
    end
end

@inline _inner_getter(tf::TapedFunction, v::Symbol) = tf.bindings[v]
@inline _inner_setter(tf::TapedFunction, v::Symbol, c) = tf.bindings[v] = c
@inline _lookup(tf::TapedFunction, v) = v
@inline _lookup(tf::TapedFunction, v::Box{T}) where T = v.get(tf, v.id)
@inline _update_var!(tf::TapedFunction, v::Symbol, c) = tf.bindings[v] = c
@inline _update_var!(tf::TapedFunction, v::Box{T}, c::T) where T = v.set(tf, v.id, c)

"""
    Instruction

An `Instruction` stands for a function call
"""
struct Instruction{F, N, TO} <: AbstractInstruction
    func::F
    input::NTuple{N, Box{<:Any}}
    output::Box{TO}
end

struct GotoInstruction{T} <: AbstractInstruction
    condition::Box{T}
    # we enusre a 1-to-1 mapping between ir.code and instruction
    # so here we can use the index directly.
    dest::Int
end

struct ReturnInstruction{T} <: AbstractInstruction
    arg::Box{T}
end

@inline val(x) = x
@inline val(x::GlobalRef) = getproperty(x.mod, x.name)
@inline val(x::QuoteNode) = eval(x)
@inline val(x::TapedFunction) = x.func
@inline result(t::TapedFunction) = t.bindings[t.retval]

function (tf::TapedFunction)(args...; callback=nothing, continuation=false)
    if !continuation # reset counter and retval to run from the start
        tf.counter = 1;
        tf.retval = :none;
    end

    # set args
    if tf.counter <= 1
        haskey(tf.bindings, :_1) && _update_var!(tf, :_1, tf.func)
        for i in 1:length(args)
            slot = Symbol("_", i + 1)
            haskey(tf.bindings, slot) && _update_var!(tf, slot, args[i])
        end
    end

    # run the raw tape
    while true
        ins = tf.tape[tf.counter]
        ins(tf)
        callback !== nothing && callback()
        tf.retval !== :none && break
    end
    return result(tf)
end

function Base.show(io::IO, tf::TapedFunction)
    # we use an extra IOBuffer to collect all the data and then
    # output it once to avoid output interrupt during task context
    # switching
    buf = IOBuffer()
    println(buf, "TapedFunction:")
    println(buf, "* .func => $(tf.func)")
    println(buf, "* .ir   =>")
    println(buf, "------------------")
    println(buf, tf.ir)
    println(buf, "------------------")
    print(io, String(take!(buf)))
end

function Base.show(io::IO, rtape::RawTape)
    buf = IOBuffer()
    print(buf, length(rtape), "-element RawTape")
    isempty(rtape) || println(buf, ":")
    i = 1
    for instr in rtape
        print(buf, "\t", i, " => ")
        show(buf, instr)
        i += 1
    end
    print(io, String(take!(buf)))
end

## methods for Instruction
Base.show(io::IO, instr::AbstractInstruction) = println(io, "A ", typeof(instr))

function Base.show(io::IO, instr::Instruction)
    println(io, "Instruction(", instr.output, "=", instr.func, instr.input)
end

function Base.show(io::IO, instr::GotoInstruction)
    println(io, "GotoInstruction(", instr.condition, ", dest=", instr.dest, ")")
end

function (instr::Instruction{F})(tf::TapedFunction) where F
    # catch run-time exceptions / errors.
    try
        func = val(_lookup(tf, instr.func))
        inputs = map(x -> val(_lookup(tf, x)), instr.input)
        output = func(inputs...)
        _update_var!(tf, instr.output, output)
        tf.counter += 1
    catch e
        println("counter=", tf.counter)
        println("tf=", tf)
        println(e, catch_backtrace());
        rethrow(e);
    end
end

function (instr::GotoInstruction)(tf::TapedFunction)
    cond = instr.condition.id === :_true ? true :
        instr.condition.id === :_false ? false :
        val(_lookup(tf, instr.condition))

    if cond
        tf.counter += 1
    else # goto dest unless cond
        tf.counter = instr.dest
    end
end

function (instr::ReturnInstruction)(tf::TapedFunction)
    tf.retval = instr.arg.id
end

## internal functions

_accurate_typeof(v) = typeof(v)
_accurate_typeof(::Type{V}) where V = Type{V}
_loose_type(t) = t
_loose_type(::Type{Type{T}}) where T = isa(T, DataType) ? Type{T} : typeof(T)

"""
    __new__(T, args...)

Return a new instance of `T` with `args` even when there is no inner constructor for these args.
Source: https://discourse.julialang.org/t/create-a-struct-with-uninitialized-fields/6967/5
"""
@generated function __new__(T, args...)
    return Expr(:splatnew, :T, :args)
end

## Translation: CodeInfo -> Tape

function bind_var!(var, bindings::Dict{Symbol, Any}, ir::Core.CodeInfo) # for literal constants
    id = gensym()
    bindings[id] = var
    Box{typeof(var)}(id)
end
bind_var!(var::Core.SSAValue, bindings::Dict{Symbol, Any}, ir::Core.CodeInfo) =
    bind_var!(Symbol(var.id), bindings, ir.ssavaluetypes[var.id])
bind_var!(var::Core.TypedSlot, bindings::Dict{Symbol, Any}, ir::Core.CodeInfo) =
    bind_var!(Symbol(:_, var.id), bindings, ir.slottypes[var.id])
bind_var!(var::Core.SlotNumber, bindings::Dict{Symbol, Any}, ir::Core.CodeInfo) =
    bind_var!(Symbol(:_, var.id), bindings, ir.slottypes[var.id])
bind_var!(var::Symbol, boxes::Dict{Symbol, Any}, c::Core.Const) =
    bind_var!(var, boxes, _loose_type(Type{c.val}))
bind_var!(var::Symbol, boxes::Dict{Symbol, Any}, c::Core.PartialStruct) =
    bind_var!(var, boxes, _loose_type(c.typ))
function bind_var!(var::Symbol, bindings::Dict{Symbol, Any}, ::Type{T}) where T
    get!(bindings, var, nothing)
    Box{T}(var)
end

function translate!(tape::RawTape, ir::Core.CodeInfo)
    bindings = Dict{Symbol, Any}()

    for (idx, line) in enumerate(ir.code)
        isa(line, Core.Const) && (line = line.val) # unbox Core.Const
        ins = translate!!(Core.SSAValue(idx), line, bindings, ir)
        push!(tape, ins)
    end
    return (bindings, tape)
end

const IRVar = Union{Core.SSAValue, Core.SlotNumber}

function translate!!(var::IRVar, line::Core.NewvarNode,
                     bindings::Dict{Symbol, Any}, @nospecialize(ir))
    # use a noop to ensure the 1-to-1 mapping from ir.code to instructions
    # on tape. see GotoInstruction.dest.
    return GotoInstruction(Box{Bool}(:_true), 0)
end

function translate!!(var::IRVar, line::GlobalRef,
                     bindings::Dict{Symbol, Any}, ir)
    return Instruction(() -> val(line), (), bind_var!(var, bindings, ir))
end

function translate!!(var::IRVar, line::Core.SlotNumber,
                     bindings::Dict{Symbol, Any}, ir)
    return Instruction(identity, (bind_var!(line, bindings, ir),), bind_var!(var, bindings, ir))
end

function translate!!(var::IRVar, line::Core.TypedSlot,
                     bindings::Dict{Symbol, Any}, ir)
    input_box = bind_var!(Core.SlotNumber(line.id), bindings, ir)
    return Instruction(identity, (input_box,), bind_var!(var, bindings, ir))
end

function translate!!(var::IRVar, line::Core.GotoIfNot,
                     bindings::Dict{Symbol, Any}, ir)
    _cond = bind_var!(line.cond, bindings, ir)
    cond = if isa(_cond, Bool)
        Box{Bool}(_cond ? :_true : :_false)
    else
        _cond
    end
    return GotoInstruction(cond, line.dest)
end

function translate!!(var::IRVar, line::Core.GotoNode,
                     bindings::Dict{Symbol, Any}, @nospecialize(ir))
    return GotoInstruction(Box{Bool}(:_false), line.label)
end

function translate!!(var::IRVar, line::Core.ReturnNode,
                     bindings::Dict{Symbol, Any}, ir)
    return ReturnInstruction(bind_var!(line.val, bindings, ir))
end

function translate!!(var::IRVar, line::Expr,
                     bindings::Dict{Symbol, Any}, ir::Core.CodeInfo)
    head = line.head
    _bind_fn = (x) -> bind_var!(x, bindings, ir)
    if head === :new
        args = map(_bind_fn, line.args)
        return Instruction(__new__, args |> Tuple, _bind_fn(var))
    elseif head === :call
        args = map(_bind_fn, line.args)
        # args[1] is the function
        func = line.args[1]
        if Meta.isexpr(func, :static_parameter) # func is a type parameter
            func = ir.parent.sparam_vals[func.args[1]]
        else # isa(func, GlobalRef) or a var?
            func = args[1] # a var(box)
        end
        return Instruction(func, args[2:end] |> Tuple, _bind_fn(var))
    elseif head === :(=)
        # line.args[1] (the left hand side) is a SlotNumber, and it should be the output
        lhs = line.args[1]
        rhs = line.args[2] # the right hand side, maybe a Expr, or a var, or ...
        if Meta.isexpr(rhs, (:new, :call))
            return translate!!(lhs, rhs, bindings, ir)
        else # rhs is a single value
            return Instruction(identity, (_bind_fn(rhs),), _bind_fn(lhs))
        end
    else
        @error "Unknown Expression: " typeof(var) var typeof(line) line
        throw(ErrorException("Unknown Expression"))
    end
end

function translate!!(var, line, bindings, ir)
    @error "Unknown IR code: " typeof(var) var typeof(line) line
    throw(ErrorException("Unknown IR code"))
end

## copy Bindings, TapedFunction

"""
    tape_copy(x)

Function `tape_copy` is used to copy data while copying a TapedTask, the
default behavior is: 1. for `Array` and `Dict`, we do `deepcopy`; 2. for
other data types, we do not copy and share the data between tasks, i.e.,
`tape_copy(x) = x`. If one wants some kinds of data to be copied, or
deeply copied, one can add a method to this function.
"""
function tape_copy end
tape_copy(x) = x
# Core.Box is used as closure captured variable container, so we should tape_copy its contents
tape_copy(x::Core.Box) = Core.Box(tape_copy(x.contents))
# ?? should we deepcopy Array and Dict by default?
# tape_copy(x::Array) = deepcopy(x)
# tape_copy(x::Dict) = deepcopy(x)

function copy_bindings(old::Dict{Symbol, Any})
    newb = Dict{Symbol, Any}()
    for (k, v) in old
        newb[k] = tape_copy(v)
    end
    return newb
end

function Base.copy(tf::TapedFunction)
    # create a new uninitialized TapedFunction
    new_tf = TapedFunction(tf)
    new_tf.bindings = copy_bindings(tf.bindings)
    return new_tf
end

max_stars_repo_name: TuringLang/Libtask

max_issues_repo_name: TuringLang/Libtask

max_forks_repo_name: TuringLang/Libtask


text:
import JuMP: GenericAffExpr

init_vars(model::Model, net::Network, args...; kwargs...) = init_vars(model, net.layers, args...; kwargs...)
function init_vars(model::Model, layers::Vector{Layer}, name=nothing; binary=false, with_input = false)
    N = length(layers)
    vars = Vector{Vector{VariableRef}}(undef, N + with_input)

    if with_input
        n = size(layers[1].weights, 2)
        vars[1] = @variable(model, [1:n], binary = binary)
    end

    for i in 1:N
        n = n_nodes(layers[i])
        vars[i+with_input] = @variable(model, [1:n], binary = binary)
    end

    if !isnothing(name)
        for i in 1:length(vars), j in 1:length(vars[i])
            set_name(vars[i][j], string(name, i-with_input, '[', j, ']'))
        end
        model[name] = vars
    end
    return vars
end

# For the aux_* variables, we want unique names counting up from 1.
# E.g. aux_abs1. To this end, we store each type of aux variable in the
# model in a vector accessible as e.g. `m[:aux_abs]`. To create a new one,
# we count the length of the associated vector and add 1.
# I.e. if aux_abs1 exists in the model, this will return aux_abs2
function new_named_var(m::Model, base_symbol::Symbol)
    aux_vars = get!(m.obj_dict, base_symbol, VariableRef[])
    aux = @variable(m, base_name = string(base_symbol)*string(length(aux_vars)+1))
    push!(aux_vars, aux)
    aux
end

_model(a::Number) = nothing
_model(a::VariableRef) = a.model
_model(a::Array) = _model(first(a))
_model(a::GenericAffExpr) = isempty(a.terms) ? nothing : _model(first(keys(a.terms)))
_model(as...) = something(_model.(as)..., missing)

# These should only be hit if we're comparing 0 with 0 or if we somehow
# hit a branch that is numbers only (no variables or expressions).
# We don't have a way to get the model in that case. This is a problem since
# we do sometimes end up with (0, 0). It shouldn't happen in any other case.
symbolic_max(m::Missing, a, b) = (iszero(a) && iszero(b)) ? (return zero(promote_type(typeof(a), typeof(b)))) : ArgumentError("Cannot get model from ($a, $b)")

function symbolic_max(m::Model, a, b)
    aux = new_named_var(m, :aux_max)
    @constraint(m, aux >= a)
    @constraint(m, aux >= b)
    return aux
end
symbolic_max(a, b) = symbolic_max(_model(a, b), a, b)

function symbolic_max(m::Model, a...)
    aux = new_named_var(m, :aux_max)
    for z in a
        @constraint(m, aux >= z)
    end
    aux
end
symbolic_max(a...) = symbolic_max(_model(a...), a...)

function symbolic_abs(m::Model, v)
    aux = new_named_var(m, :aux_abs)
    @constraint(m, aux >= 0)
    @constraint(m, aux >= v)
    @constraint(m, aux >= -v)
    return aux
end
symbolic_abs(v) = symbolic_abs(_model(v), v)

function symbolic_infty_norm(m::Model, v::Array{<:GenericAffExpr})
    aux = new_named_var(m, :aux_inf)
    @constraint(m, aux >= 0)
    @constraint(m, aux .>= v)
    @constraint(m, aux .>= -v)
    return aux
end
symbolic_infty_norm(v::Array{<:GenericAffExpr}) = symbolic_infty_norm(_model(v), v)


text:
module PkgPage

import Franklin
import CommonMark
import NodeJS
using Pkg: TOML
using FranklinUtils

export newpage
export serve

export lx_lead, lx_figure, lx_alert
export env_column, env_table, env_section
# export lx_begin, lx_end, lx_column

export hfun_col

const F = Franklin

include("instantiate.jl")

include("latex/basic.jl")
# include("coms/begin-end.jl")
include("latex/environments.jl")

end # module


text:
using Test

@testset "Core" begin
  include("core/Core.jl")
end

@testset "Doctrines" begin
  include("doctrines/Doctrines.jl")
end

@testset "WiringDiagrams" begin
  include("wiring_diagrams/WiringDiagrams.jl")
end

@testset "Graphics" begin
  include("graphics/Graphics.jl")
end

@testset "Programs" begin
  include("programs/Programs.jl")
end

@testset "LinearAlgebra" begin
  include("linear_algebra/LinearAlgebra.jl")
end


text:
using PyCall

@pyimport imbalanced_databases as imbd
@pyimport smote_variants as sv

dataset= imbd.load_iris0()
oversampler= sv.SMOTE_ENN()

X_samp, y_samp= oversampler[:sample](dataset["data"], dataset["target"])


text:
"""
l1_adaptive_trend_filter{T<:Float64, S<:Int}(y::Vector{T}, components::Vector{S}; f::Vector{T} = Vector{T}(0), numλ::S=S(40), numγ::S=S(10), MAXITER::S=S(500), verbose::Bool=false,lower_bounds::Vector{T}=-10e+7*ones(T, TOTALCOMPONENTS), upper_bounds::Vector{T}=10e+7*ones(T, TOTALCOMPONENTS) )

The function `l1_adaptive_trend_filter` performs the filtering via coordinate descent and takes the following required inputs:

* y : Signal or time-series to be filtered; (Must be a vector of reals)
* components: List of integers corresponding to the types of components to be considered. (must be a vector of integers containing some of the following numbers: 1 = Step, 2 = Spike, 3 = Slope, 4 = Sine, 5 = Cossine )

Optional inputs:

* f: Vector of overcomplete frequencies (Default=ø);
* numλ: Size of the regularizer path for the parameter λ (Default=40);
* numγ: Size of the regularizer path for the parameter γ (Default=10);
* MAXITER: Maximum number of iterations (Default=500);
* verbose: Boolean flag for displaying progress of algorithm (Default=false);
* lower_bounds: List of lower bounds for each component type (Default=[-∞,-∞,-∞,-∞,-∞]);
* upper_bounds: List of upper bpunds for each component type (Default=[+∞,+∞,+∞,+∞,+∞]).

This function returns:

*  β_path: Path of components coefficients;
*  y_path: Path of filtered signals;
*  β_best: Best components coefficients according to the EBIC criteria;
*  y_best: Best filtered signal according to the EBIC criteria;
*  λ_best: Best value for the λ regularizer according to the EBIC criteria;
*  γ_best: Best value for the γ regularizer according to the EBIC criteria.

## Example

```
y = rand(18) # some inputs
components = [1,3] #(meaning we only consider step and slope components)

# run the algorithm
beta_path, y_path, beta_best, y_best, lambda_best, gamma_best = l1_adaptive_trend_filter(y,components)
```

"""
function l1_adaptive_trend_filter{T<:Float64, S<:Int}(
    y::Vector{T}, components::Vector{S}; f::Vector{T} = Vector{T}(0), numλ::S=S(40), numγ::S=S(10), MAXITER::S=S(500), verbose::Bool=false,
    lower_bounds::Vector{T}=-10e+7*ones(T, TOTALCOMPONENTS), upper_bounds::Vector{T}=10e+7*ones(T, TOTALCOMPONENTS) )

    # subtracting the mean
    y_mean = mean(y)
    y = y - y_mean

    # prepare check for dimension sizes
    const N = length(y)

    # iterator
    IT = initIT_range(N, components, f, MAXITER=MAXITER)::iterator

    # compute moments
    const d = initData(IT, f, f)::dataCD

    # inner products between response y and components
    const xdy = initXDY(IT, y, d)

    # build regularization path for λ (same path shape, different λs)
    path, λ_max = compute_λ_path(IT, xdy, numλ, d)

    # build regularization path for γ (unique path)
    const Γ = compute_γ_path(IT, xdy, numγ, d)

    # initialize weights
    w = Vector{Float64}[]
    for i in 1:TOTALCOMPONENTS
        if in(i,IT.components)
            push!(w, ones(IT.nelements[i]))
        else
            push!(w, ones(0))
        end
    end

    # lasso pass
    @fastmath β_path, y_path, β_best, y_best, λ_best, γ_best = coordinate_descent(
      IT, d, xdy, path, λ_max, [1.0,] , y, lower_bounds, upper_bounds, w, verbose
      )

    # exclude the components the lasso has set to zero
    update_components!(IT, w, β_best, d, xdy)

    @fastmath β_path, y_path, β_best, y_best, λ_best, γ_best = coordinate_descent(
      IT, d, xdy, path, λ_max, Γ, y, lower_bounds, upper_bounds, w, verbose
    )

    # adding back the mean
    y_best = y_best + y_mean

    if verbose
      print(string(
              "best regularization according to BIC was (λ=", round(λ_best, 3),
              ", γ=", round(γ_best, 3), ") \n"
              ))
    end

    return β_path, y_path, β_best, y_best, λ_best, γ_best
end

# coordinate descent algorithm for the regularization path (Λ x Γ)
function coordinate_descent(
    IT::iterator, d::dataCD, xdy::Vector{Vector{Float64}}, path::Vector{Float64}, λ_max::Vector{Float64}, Γ::Vector{Float64},
    y::Vector{Float64}, lower_bounds::Vector{Float64}, upper_bounds::Vector{Float64}, w::Vector{Vector{Float64}}, verbose::Bool; sparse::Int = 0
    )

  const N = IT.obs

  # initializations
  #if sparse == 1
  #  β_path, β_tilde, β, activeSet = initSparse(IT)
  #else
  β_path, β_tilde, β, activeSet = initDense(IT)
  #end

  # memory allocation
  BIC = Inf::Float64
  β_ols = 0.0::Float64
  partial_fit = 0.0
  β_best = 0.0
  y_best = 0
  λ_best = 0.0
  γ_best = 0.0
  path_iteration = 0

  y_path = Vector{Float64}[]
  #for i in 1:TOTALCOMPONENTS
  #  push!(w, zeros(IT.nelements[i]))
  #end

  # regularization path
  @inbounds for γ in Γ

    # clear warm-start
    clear_warmstart!(β_tilde, IT)

    @inbounds for path_iter in path

      λ = path_iter * λ_max

      change_flag = true

      if verbose
        path_iteration += 1
        print(string(
                "regularizers = (", round(λ, 3), ", ", round(γ, 3),
                ") path iteration = ", path_iteration, ".\n"
                ))
      end

      # loop until active set converges
      @inbounds for iter in 1:IT.maxIter

        if verbose
          println(iter)
        end

        # convergence check
        if !change_flag
          break
        end
        change_flag = false

        # cycle through every component
        @inbounds for c1 in IT.components, j in IT.elements[c1]

            # consider hoisting means and variaces, for better memoru use

            # compute the partial fit with the components in the active set
            partial_fit = 0.0
            @inbounds for c2 in IT.components, l in IT.elements[c2]
                @inbounds if activeSet[c2][l] && (c1, j) != (c2, l)
                    @inbounds partial_fit += GM2(c1, c2, j, l, d, N) * β_tilde[c2][l]
                end
            end

            # univariate ordinary leasts squares coefficient
            inner_prod_partial_residual = (xdy[c1][j] - partial_fit) / IT.obs

            # weighted penalty
            #w[c1][j] = 1.0 / (abs(β_ols)^γ)
            # w[c1][j] = 1.0 / abs(inner_prod_partial_residual)

            # # soft thresholding operator
            # if abs(inner_prod_partial_residual) <= λ[c1] * w[c1][j]^γ
            #     if activeSet[c1][j]
            #         β_tilde[c1][j] = 0.0
            #         activeSet[c1][j] = false
            #         change_flag = true
            #         #println("$(c1)  , $(j)")
            #     end
            # else
            #     β_tilde[c1][j] = sign(inner_prod_partial_residual) * (abs(inner_prod_partial_residual) - λ[c1] * w[c1][j]^γ) / (d.σ[c1][j]^2)

            #     # projection onto the box constraints [lower_bound, upper_bound]
            #     β_tilde[c1][j] = max(β_tilde[c1][j], lower_bounds[c1])
            #     β_tilde[c1][j] = min(β_tilde[c1][j], upper_bounds[c1])

            #     if !activeSet[c1][j] #&& β_tilde[c1][j] != 0.0
            #         activeSet[c1][j] = true
            #         change_flag = true
            #         #println("$(c1)  , $(j)")
            #     end
            # end
            change_flag = soft_treshold(j, inner_prod_partial_residual, λ[c1], γ, w[c1][j], activeSet[c1], β_tilde[c1], d.σ[c1][j], lower_bounds[c1], upper_bounds[c1])

          end
      end

      push!(β_path, deepcopy(β_tilde))

      # bayesian information criterion
      BIC_new, y_hat = compute_BIC(y, β_tilde, activeSet, IT, d, xdy)

      push!(y_path, copy(y_hat))

      if verbose
          print(string(" BIC = ", BIC_new))
      end

      # save the best fit so far
      if BIC_new < BIC
          BIC = BIC_new
          y_best = copy(y_hat)
          β_best = deepcopy(β_tilde)
          λ_best = λ
          γ_best = γ
      end

    end
  end

  return β_path, y_path, β_best, y_best, λ_best, γ_best
end

function clear_warmstart!(β_tilde::Vector{Vector{Float64}}, IT::iterator)

  # clear warm-start
    for i in IT.components
        for j in IT.elements[i]
            β_tilde[i][j] = 0.0
        end
    end

    nothing
end

function soft_treshold(j::Int, residual::Float64, λ::Float64, γ::Float64, w::Float64, activeSet::Vector{Bool}, β_tilde::Vector{Float64},
    var::Float64, lb::Float64, ub::Float64 )::Bool

    if abs(residual) <= λ * w^γ
        if activeSet[j]
            β_tilde[j] = 0.0
            activeSet[j] = false
            return true
            #println("$(c1)  , $(j)")
        else
            return false
        end
    else
        β_tilde[j] = sign(residual) * (abs(residual) - λ * w^γ) / (var^2)

        # projection onto the box constraints [lower_bound, upper_bound]
        β_tilde[j] = max(β_tilde[j], lb)
        β_tilde[j] = min(β_tilde[j], ub)

        if !activeSet[j] #&& β_tilde[c1][j] != 0.0
            activeSet[j] = true
            return true
            #println("$(c1)  , $(j)")
        else
            return false
        end
    end
    return false
end

function update_components!(IT, w, β, d, xdy)

  # clear given iterator
  for c in IT.components
    IT.elements[c] = Int[]
  end

  for c in IT.components
    for j in 1:IT.nelements[c]

      if β[c][j] != 0.0
        # pre-compute weight
        w[c][j] = abs(1.0 / β[c][j]) #/ (d.σ[c][j]^2)
        β[c][j] = 0.0
        # update iterator only with nonzero elements
        push!(IT.elements[c], j)
      end

    end
  end

  return nothing
end

max_stars_repo_name: joaquimg/ComponentFilterCD

max_issues_repo_name: joaquimg/ComponentFilterCD

max_forks_repo_name: joaquimg/ComponentFilterCD


text:
# Find the smallest order of magnitude that is larger than xspan This is a
# little opaque because I want to avoid assuming the log function is defined
# over typeof(xspan)
function bounding_order_of_magnitude{DT}(xspan::DT)
    one_dt = convert(DT, one(DT))

    a = 1
    step = 1
    while xspan < 10.0^a * one_dt
        a -= step
    end

    b = 1
    step = 1
    while xspan > 10.0^b * one_dt
        b += step
    end

    while a + 1 < b
        c = div(a + b, 2)
        if xspan < 10.0^c * one_dt
            b = c
        else
            a = c
        end
    end

    return b
end

# Empty catchall
optimize_ticks() = Any[]

# Find some reasonable values for tick marks.
#
# This is basically Wilkinson's ad-hoc scoring method that tries to balance
# tight fit around the data, optimal number of ticks, and simple numbers.
#
# Args:
#   x_min: minimum value occuring in the data.
#   x_max: maximum value occuring in the data.
#   Q: tick intervals and scores
#   k_min: minimum number of ticks
#   k_max: maximum number of ticks
#   k_ideal: ideal number of ticks
#   strict_span: true if no ticks should be outside [x_min, x_max].
#
# Returns:
#   A Float64 vector containing tick marks.
#
function optimize_ticks{T}(x_min::T, x_max::T; extend_ticks::Bool=false,
                           Q=[(1.0,1.0), (5.0, 0.9), (2.0, 0.7), (2.5, 0.5), (3.0, 0.2)],
                           k_min::Int=2, k_max::Int=10, k_ideal::Int=5,
                           granularity_weight::Float64=1/4, simplicity_weight::Float64=1/6,
                           coverage_weight::Float64=1/3, niceness_weight::Float64=1/4,
                           strict_span=false)

    Qv = [((@compat Float64(q[1])), (@compat Float64(q[2]))) for q in Q]
    optimize_ticks_typed(x_min, x_max, extend_ticks, Qv, k_min, k_max, k_ideal,
                         granularity_weight, simplicity_weight,
                         coverage_weight, niceness_weight, strict_span)
end

function optimize_ticks_typed{T}(x_min::T, x_max::T, extend_ticks,
                           Q::Vector{(@compat Tuple{Float64,Float64})}, k_min,
                           k_max, k_ideal,
                           granularity_weight::Float64, simplicity_weight::Float64,
                           coverage_weight::Float64, niceness_weight::Float64,
                           strict_span)
    one_t = convert(T, one(T))
    if x_max - x_min < eps()*one_t
        R = typeof(1.0 * one_t)
        return R[x_min], x_min - one_t, x_min + one_t
    end

    const n = length(Q)

    # generalizing "order of magnitude"
    xspan = x_max - x_min
    z = bounding_order_of_magnitude(xspan)

    high_score = -Inf
    z_best = 0.0
    k_best = 0
    r_best = 0.0
    q_best = 0.0

    while k_max * 10.0^(z+1) * one_t > xspan
        for k in k_min:k_max
            for (q, qscore) in Q
                span = (k - 1) * q * 10.0^z * one_t
                if span < xspan
                    continue
                end

                stp = q*10.0^z
                if stp < eps()
                    continue
                end
                r = ceil((x_max - span) / (stp * one_t))

                while r*stp * one_t <= x_min
                    has_zero = r <= 0 && abs(r) < k

                    # simplicity
                    s = has_zero ? 1.0 : 0.0

                    # granularity
                    g = 0 < k < 2k_ideal ? 1 - abs(k - k_ideal) / k_ideal : 0.0

                    # coverage
                    c = 1.5 * xspan/span

                    score = granularity_weight * g +
                            simplicity_weight * s +
                            coverage_weight * c +
                            niceness_weight * qscore

                    # strict limits on coverage
                    if strict_span && span > xspan
                        score -= 10000
                    elseif !strict_span && (span >= 2.0*xspan || span < xspan)
                        score -= 1000
                    end

                    if score > high_score
                        (q_best, r_best, k_best, z_best) = (q, r, k, z)
                        high_score = score
                    end
                    r += 1
                end
            end
        end
        z -= 1
    end

    if isinf(high_score)
        R = typeof(1.0 * one_t)
        return R[x_min], x_min - one_t, x_min + one_t
    end

    span = q_best * 10.0^z_best * one_t
    if extend_ticks
        S = Array(typeof(1.0 * one_t), (@compat Int(3 * k_best)))
        for i in 0:(3*k_best - 1)
            S[i+1] = (r_best + i - k_best) * span
        end
        viewmin, viewmax = S[k_best + 1], S[2 * k_best]
    else
        S = Array(typeof(1.0 * one_t), k_best)
        for i in 0:(k_best - 1)
            S[i+1] = (r_best + i) * span
        end
        viewmin, viewmax = S[1], S[end]
    end

    if strict_span
        viewmin = max(viewmin, x_min)
        viewmax = min(viewmax, x_max)
    end

    return S, viewmin, viewmax
end

function optimize_ticks(x_min::Date, x_max::Date; extend_ticks::Bool=false,
                        k_min=nothing, k_max=nothing, scale=:auto,
                        granularity_weight=nothing, simplicity_weight=nothing,
                        coverage_weight=nothing, niceness_weight=nothing,
                        strict_span=false)
    return optimize_ticks(convert(DateTime, x_min), convert(DateTime, x_max),
                          extend_ticks=extend_ticks, scale=scale)
end

function optimize_ticks(x_min::DateTime, x_max::DateTime; extend_ticks::Bool=false,
                        k_min=nothing, k_max=nothing, scale=:auto,
                        granularity_weight=nothing, simplicity_weight=nothing,
                        coverage_weight=nothing, niceness_weight=nothing,
                        strict_span=false)
    if x_min == x_max
        x_max += Second(1)
    end

    if year(x_max) - year(x_min) <= 1 && scale != :year
        if year(x_max) == year(x_min) && month(x_max) - month(x_min) <= 1 && scale != :month
            ticks = DateTime[]

            const scales = [
                Day(1), Hour(1), Minute(1), Second(1), Millisecond(100),
                Millisecond(10), Millisecond(1)
            ]

            # ticks on week boundries
            if x_min + Day(7) < x_max || scale == :week
                push!(ticks, x_min)
                while true
                    next_month = Date(year(ticks[end]), month(ticks[end])) + Month(1)
                    while ticks[end] + Week(1) < next_month - Day(2)
                        push!(ticks, ticks[end] + Week(1))
                    end
                    push!(ticks, next_month)
                    if next_month >= x_max
                        break
                    end
                end
            else
                scale = nothing
                if scale != :auto
                    # TODO: manually setting scale with :day, :minute, etc
                end

                if scale === nothing
                    for proposed_scale in [Day(1), Hour(1), Minute(1),
                                           Second(1), Millisecond(100),
                                           Millisecond(10), Millisecond(1)]
                        if x_min + proposed_scale < x_max
                            scale = proposed_scale
                            break
                        end
                    end
                end

                if scale === nothing
                    scale = Millisecond(1)
                end

                # round x_min down
                if scale === Day(1)
                    first_tick = DateTime(year(x_min), month(x_min), day(x_min))
                elseif scale === Hour(1)
                    first_tick = DateTime(year(x_min), month(x_min), day(x_min),
                                          hour(x_min))
                elseif scale === Minute(1)
                    first_tick = DateTime(year(x_min), month(x_min), day(x_min),
                                          hour(x_min), minute(x_min))
                elseif scale === Second(1)
                    first_tick = DateTime(year(x_min), month(x_min), day(x_min),
                                          hour(x_min), minute(x_min), second(x_min))
                elseif scale === Millisecond(100)
                    first_tick = DateTime(year(x_min), month(x_min), day(x_min),
                                          hour(x_min), minute(x_min),
                                          second(x_min), millisecond(x_min) % 100)
                elseif scale === Millisecond(10)
                    first_tick = DateTime(year(x_min), month(x_min), day(x_min),
                                          hour(x_min), minute(x_min),
                                          second(x_min), millisecond(x_min) % 10)
                else
                    first_tick = x_min
                end
                push!(ticks, first_tick)

                while ticks[end] < x_max
                    push!(ticks, ticks[end] + scale)
                end
            end

            viewmin, viewmax = ticks[1], ticks[end]
            return ticks, viewmin, viewmax
        else
            ticks = DateTime[]
            push!(ticks, Date(year(x_min), month(x_min)))
            while ticks[end] < x_max
                push!(ticks, ticks[end] + Month(1))
            end
            viewmin, viewmax = ticks[1], ticks[end]

            return ticks, x_min, x_max
        end
    else
        ticks, viewmin, viewmax =
            optimize_ticks(year(x_min), year(x_max + Year(1) - Day(1)), extend_ticks=extend_ticks)

        return DateTime[DateTime(round(y)) for y in ticks],
                        DateTime(round(viewmin)), DateTime(round(viewmax))
    end
end

# Generate ticks suitable for multiple scales.
function multilevel_ticks{T}(viewmin::T, viewmax::T;
                             scales=[0.5, 5.0, 10.0])

    ticks = Dict()
    for scale in scales
        ticks[scale] = optimize_ticks(viewmin, viewmax,
                                      k_min=max(1, (@compat round(Int, 2*scale))),
                                      k_max=max(3, (@compat round(Int, 10*scale))),
                                      k_ideal=max(2, (@compat round(Int, 15*scale))))[1]
    end

    return ticks
end

function multilevel_ticks(viewmin::Date, viewmax::Date;
                          scales=[:year, :month, :day])
    return multilevel_ticks(convert(DateTime, viewmin),
                            convert(DateTime, viewmax),
                            scales=scales)
end

function multilevel_ticks(viewmin::DateTime, viewmax::DateTime;
                          scales=[:year, :month, :day])
    # TODO: This needs to be improved for DateTime
    span = convert(Float64, Dates.toms(viewmax - viewmin))
    ticks = Dict()
    for scale in scales
        if scale == :year
            s = span / Dates.toms(Day(360))
        elseif scale == :month
            s = span / Dates.toms(Day(90))
        else
            s = span / Dates.toms(Day(1))
        end

        ticks[s/20] = optimize_ticks(viewmin, viewmax, scale=scale)[1]
    end

    return ticks
end


text:
# ---
# title: 792. Number of Matching Subsequences
# id: problem792
# author: Tian Jun
# date: 2020-10-31
# difficulty: Medium
# categories: Array
# link: <https://leetcode.com/problems/number-of-matching-subsequences/description/>
# hidden: true
# ---
#
# Given string `S` and a dictionary of words `words`, find the number of
# `words[i]` that is a subsequence of `S`.
#
#
#
#     **Example :**
#     Input:
#     S = "abcde"
#     words = ["a", "bb", "acd", "ace"]
#     Output: 3
#     Explanation: There are three words in words that are a subsequence of S: "a", "acd", "ace".
#
#
# **Note:**
#
#   * All words in `words` and `S` will only consists of lowercase letters.
#   * The length of `S` will be in the range of `[1, 50000]`.
#   * The length of `words` will be in the range of `[1, 5000]`.
#   * The length of `words[i]` will be in the range of `[1, 50]`.
#
#
## @lc code=start
using LeetCode

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


text:
#=
This file is auto-generated. Do not edit.
=#

#! format: off

"""
    mutable struct EX4VSA <: AVR
        Iflim::Float64
        d::Float64
        f::Float64
        Spar::Float64
        K1::Float64
        K2::Float64
        Oel_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
        G::Float64
        Ta::Float64
        Tb::Float64
        Te::Float64
        E_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
        V_ref::Float64
        ext::Dict{String, Any}
        states::Vector{Symbol}
        n_states::Int
        internal::InfrastructureSystemsInternal
    end

IEEE Excitation System for Voltage Security Assesment

# Arguments
- `Iflim::Float64`: OEL Field current limit, validation range: `(0, nothing)`, action if invalid: `warn`
- `d::Float64`: OEL parameter d, validation range: `(0, nothing)`, action if invalid: `warn`
- `f::Float64`: OEL parameter f, validation range: `(0, nothing)`, action if invalid: `warn`
- `Spar::Float64`: OEL parameter Spar, validation range: `(0, nothing)`, action if invalid: `warn`
- `K1::Float64`: OEL delay time constant, validation range: `(0, nothing)`, action if invalid: `warn`
- `K2::Float64`: OEL parameter K2, validation range: `(0, nothing)`, action if invalid: `warn`
- `Oel_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}`: Oel integrator limits (Oel_min, Oel_max)
- `G::Float64`: AVR Exciter Gain, validation range: `(0, nothing)`, action if invalid: `warn`
- `Ta::Float64`: Numerator lead-lag (lag) time constant in s, validation range: `(0, nothing)`, action if invalid: `warn`
- `Tb::Float64`: Denominator lead-lag (lag) time constant in s, validation range: `(0, nothing)`, action if invalid: `warn`
- `Te::Float64`: Exciter Time Constant in s, validation range: `(0, nothing)`, action if invalid: `warn`
- `E_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}`: Voltage regulator limits (regulator output) (E_min, E_max)
- `V_ref::Float64`: Reference Voltage Set-point, validation range: `(0, nothing)`
- `ext::Dict{String, Any}`
- `states::Vector{Symbol}`: The states are:
	Vll: Lead-lag internal state,
	Vex: Exciter Output,
	oel: OEL integrator state
- `n_states::Int`: The EX4VSA has 3 states
- `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify
"""
mutable struct EX4VSA <: AVR
    "OEL Field current limit"
    Iflim::Float64
    "OEL parameter d"
    d::Float64
    "OEL parameter f"
    f::Float64
    "OEL parameter Spar"
    Spar::Float64
    "OEL delay time constant"
    K1::Float64
    "OEL parameter K2"
    K2::Float64
    "Oel integrator limits (Oel_min, Oel_max)"
    Oel_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
    "AVR Exciter Gain"
    G::Float64
    "Numerator lead-lag (lag) time constant in s"
    Ta::Float64
    "Denominator lead-lag (lag) time constant in s"
    Tb::Float64
    "Exciter Time Constant in s"
    Te::Float64
    "Voltage regulator limits (regulator output) (E_min, E_max)"
    E_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
    "Reference Voltage Set-point"
    V_ref::Float64
    ext::Dict{String, Any}
    "The states are:
	Vll: Lead-lag internal state,
	Vex: Exciter Output,
	oel: OEL integrator state"
    states::Vector{Symbol}
    "The EX4VSA has 3 states"
    n_states::Int
    "power system internal reference, do not modify"
    internal::InfrastructureSystemsInternal
end

function EX4VSA(Iflim, d, f, Spar, K1, K2, Oel_lim, G, Ta, Tb, Te, E_lim, V_ref=1.0, ext=Dict{String, Any}(), )
    EX4VSA(Iflim, d, f, Spar, K1, K2, Oel_lim, G, Ta, Tb, Te, E_lim, V_ref, ext, [:Vll, :Vex, :oel], 3, InfrastructureSystemsInternal(), )
end

function EX4VSA(; Iflim, d, f, Spar, K1, K2, Oel_lim, G, Ta, Tb, Te, E_lim, V_ref=1.0, ext=Dict{String, Any}(), states=[:Vll, :Vex, :oel], n_states=3, internal=InfrastructureSystemsInternal(), )
    EX4VSA(Iflim, d, f, Spar, K1, K2, Oel_lim, G, Ta, Tb, Te, E_lim, V_ref, ext, states, n_states, internal, )
end

# Constructor for demo purposes; non-functional.
function EX4VSA(::Nothing)
    EX4VSA(;
        Iflim=0,
        d=0,
        f=0,
        Spar=0,
        K1=0,
        K2=0,
        Oel_lim=(min=0.0, max=0.0),
        G=0,
        Ta=0,
        Tb=0,
        Te=0,
        E_lim=(min=0.0, max=0.0),
        V_ref=0,
        ext=Dict{String, Any}(),
    )
end

"""Get [`EX4VSA`](@ref) `Iflim`."""
get_Iflim(value::EX4VSA) = value.Iflim
"""Get [`EX4VSA`](@ref) `d`."""
get_d(value::EX4VSA) = value.d
"""Get [`EX4VSA`](@ref) `f`."""
get_f(value::EX4VSA) = value.f
"""Get [`EX4VSA`](@ref) `Spar`."""
get_Spar(value::EX4VSA) = value.Spar
"""Get [`EX4VSA`](@ref) `K1`."""
get_K1(value::EX4VSA) = value.K1
"""Get [`EX4VSA`](@ref) `K2`."""
get_K2(value::EX4VSA) = value.K2
"""Get [`EX4VSA`](@ref) `Oel_lim`."""
get_Oel_lim(value::EX4VSA) = value.Oel_lim
"""Get [`EX4VSA`](@ref) `G`."""
get_G(value::EX4VSA) = value.G
"""Get [`EX4VSA`](@ref) `Ta`."""
get_Ta(value::EX4VSA) = value.Ta
"""Get [`EX4VSA`](@ref) `Tb`."""
get_Tb(value::EX4VSA) = value.Tb
"""Get [`EX4VSA`](@ref) `Te`."""
get_Te(value::EX4VSA) = value.Te
"""Get [`EX4VSA`](@ref) `E_lim`."""
get_E_lim(value::EX4VSA) = value.E_lim
"""Get [`EX4VSA`](@ref) `V_ref`."""
get_V_ref(value::EX4VSA) = value.V_ref
"""Get [`EX4VSA`](@ref) `ext`."""
get_ext(value::EX4VSA) = value.ext
"""Get [`EX4VSA`](@ref) `states`."""
get_states(value::EX4VSA) = value.states
"""Get [`EX4VSA`](@ref) `n_states`."""
get_n_states(value::EX4VSA) = value.n_states
"""Get [`EX4VSA`](@ref) `internal`."""
get_internal(value::EX4VSA) = value.internal

"""Set [`EX4VSA`](@ref) `Iflim`."""
set_Iflim!(value::EX4VSA, val) = value.Iflim = val
"""Set [`EX4VSA`](@ref) `d`."""
set_d!(value::EX4VSA, val) = value.d = val
"""Set [`EX4VSA`](@ref) `f`."""
set_f!(value::EX4VSA, val) = value.f = val
"""Set [`EX4VSA`](@ref) `Spar`."""
set_Spar!(value::EX4VSA, val) = value.Spar = val
"""Set [`EX4VSA`](@ref) `K1`."""
set_K1!(value::EX4VSA, val) = value.K1 = val
"""Set [`EX4VSA`](@ref) `K2`."""
set_K2!(value::EX4VSA, val) = value.K2 = val
"""Set [`EX4VSA`](@ref) `Oel_lim`."""
set_Oel_lim!(value::EX4VSA, val) = value.Oel_lim = val
"""Set [`EX4VSA`](@ref) `G`."""
set_G!(value::EX4VSA, val) = value.G = val
"""Set [`EX4VSA`](@ref) `Ta`."""
set_Ta!(value::EX4VSA, val) = value.Ta = val
"""Set [`EX4VSA`](@ref) `Tb`."""
set_Tb!(value::EX4VSA, val) = value.Tb = val
"""Set [`EX4VSA`](@ref) `Te`."""
set_Te!(value::EX4VSA, val) = value.Te = val
"""Set [`EX4VSA`](@ref) `E_lim`."""
set_E_lim!(value::EX4VSA, val) = value.E_lim = val
"""Set [`EX4VSA`](@ref) `V_ref`."""
set_V_ref!(value::EX4VSA, val) = value.V_ref = val
"""Set [`EX4VSA`](@ref) `ext`."""
set_ext!(value::EX4VSA, val) = value.ext = val


text:
include("wasm_runner.jl")

import JSON

@generated function js_print(arg)
  quote
    ccall("extern js_print", llvmcall, Nothing, ($arg,), arg)
  end
end

struct FooStruct
  bar::Int
  baz::Int
end

function square(x)
  x^2
end

function foo(x)
  return JSON.json(FooStruct(x, x))
end

open("output.wasm", "w") do io
  # write(io, wasmfunction(square, Tuple{Int}))
  write(io, wasmfunction(foo, Tuple{Int}))
end


text:
export huge, tiny, cholinv, diageye, eye, format, *, ^, mat, step!, init

# Constants to define smallest/largest supported numbers.
# Used for clipping quantities to ensure numerical stability.
const huge = 1e12
const tiny = 1e-12

# Forces cholesky argument to positive definite; replace with "Nothing" for cholesky to error on non-pd argument
const default_cholesky_mode = Positive

"""Cast input to a `Matrix` if necessary"""
ensureMatrix(arr::AbstractMatrix{T}) where T<:Number = arr
ensureMatrix(arr::Vector{T}) where T<:Number = Diagonal(arr)
ensureMatrix(n::Number) = fill!(Array{typeof(n)}(undef,1,1), n)
ensureMatrix(n::Nothing) = nothing

"""
Wrapper for `logabsgamma` function that returns first element of its output
"""
function labsgamma(x::Number)
    return logabsgamma(x)[1]
end

"""
Wrapper for `logabsbeta` function that returns first element of its output
"""
function labsbeta(x::Number, y::Number)
    return logabsbeta(x, y)[1]
end

cholesky(::Type{Nothing}, M::AbstractMatrix) = cholesky(Hermitian(Matrix(M))) # No strategy for enforcing PD-ness of M

"""
Matrix inversion using Cholesky decomposition
"""
cholinv(M::AbstractMatrix) = inv(cholesky(default_cholesky_mode, M))
cholinv(m::Number) = 1.0/m
cholinv(D::Diagonal) = Diagonal(1 ./ D.diag)

eye(n::Number) = Diagonal(I,n)
diageye(d::Int64) = Diagonal(ones(d))

# Symbol concatenation
*(sym::Symbol, num::Number) = Symbol(string(sym, num))
*(num::Number, sym::Symbol) = Symbol(string(num, sym))
*(sym1::Symbol, sym2::Symbol) = Symbol(string(sym1, sym2))
*(sym::Symbol, rng::AbstractRange) = Symbol[sym*k for k in rng]
*(rng::AbstractRange, sym::Symbol) = Symbol[k*sym for k in rng]
*(sym::Symbol, vec::Vector{T}) where T<:Number = Symbol[sym*k for k in vec]
*(vec::Vector{T}, sym::Symbol) where T<:Number = Symbol[k*sym for k in vec]
*(sym1::Symbol, sym2::Vector{Symbol}) = Symbol[sym1*s2 for s2 in sym2]
*(sym1::Vector{Symbol}, sym2::Symbol) = Symbol[s1*sym2 for s1 in sym1]

format(d::Bool) = string(d)

format(d::Symbol) = string(d)

format(d::Int) = string(d)

function format(d::AbstractFloat)
    if 0.01 < d < 100.0 || -100 < d < -0.01 || d==0.0
        return @sprintf("%.2f", d)
    else
        return @sprintf("%.2e", d)
    end
end

function format(d::Vector{T}) where T<:Union{AbstractFloat, Bool}
    s = "["
    for d_k in d[1:end-1]
        s*=format(d_k)
        s*=", "
    end
    s*=format(d[end])
    s*="]"
    return s
end

function format(d::Matrix{T}) where T<:AbstractFloat
    s = "["
    for r in 1:size(d, 1)
        s *= format(vec(d[r,:]))
    end
    s *= "]"
    return s
end

format(d::Diagonal{T}) where T<:AbstractFloat = "diag$(format(d.diag))"

function format(v::Vector{Any})
    str = ""
    for (i, entry) in enumerate(v)
        name = replace("$(entry)", "ForneyLab." => "")
        if i < length(v)
            str *= "`$(name)`, "
        else
            str *= "and `$(name)`."
        end
    end
    return str
end

function format(x::Any)
    return string(x)
end

"""Check if arguments are approximately equal"""
isApproxEqual(arg1, arg2) = maximum(abs.(arg1-arg2)) < tiny

"""Checks if input matrix is positive definite. We also perform rounding in order to prevent floating point precision problems that `isposdef()`` suffers from."""
isRoundedPosDef(arr::AbstractMatrix{Float64}) = ishermitian(round.(Matrix(arr), digits=round(Int, log10(huge)))) && isposdef(Hermitian(Matrix(arr), :L))

function viewFile(filename::AbstractString)
    # Open a file with the application associated with the file type
    Sys.iswindows() ? run(`cmd /c start $filename`) : (Sys.isapple() ? run(`open $filename`) : (is_linux() ? run(`xdg-open $filename`) : error("Cannot find an application for $filename")))
end

"""
Solve `trigamma(y) = x` for `y`.

Uses Newton's method on the convex function 1/trigramma(y).
Iterations converge monotonically.
Based on trigammaInverse implementation in R package "limma" by Gordon Smyth:
https://github.com/Bioconductor-mirror/limma/blob/master/R/fitFDist.R
"""
function trigammaInverse(x::Float64)
    y = 0.5 + 1/x
    iter = 0
    while iter < 20
        iter += 1
        tri = trigamma(y)
        dif = tri*(1-tri/x) / polygamma(2, y)
        y += dif
        ((-dif/y) > 1e-8) || break
    end

    return y
end

"""
    @symmetrical `function_definition`

Duplicate a method definition with the order of the first two arguments swapped.
This macro is used to duplicate methods that are symmetrical in their first two input arguments,
but require explicit definitions for the different argument orders.
Example:

    @symmetrical function prod!(x, y, z)
        ...
    end
"""
macro symmetrical(fn::Expr)
    # Check if macro is applied to a function definition
    # Valid function definitions include:
    # 1. foo([ args... ]) [ where ... [ where ... [ ... ] ] ] = :block
    # 2. function foo([ args... ]) [ where ... [ where ... [ ... ] ] ]
    #        :block
    #    end
    if (fn.head === :(=) || fn.head === :function) &&
        (fn.args[1] isa Expr && fn.args[2] isa Expr) &&
        (fn.args[2].head === :block)
        return esc(quote
            $fn
            $(swap_arguments(fn))
        end)
    else
        error("@symmetrical macro can be applied only to function definitions")
    end
end

function swap_arguments(fn::Expr)
    swapped = copy(fn)

    if swapped.args[1].head === :where
        swapped.args[1] = swap_arguments(swapped.args[1])
    elseif swapped.args[1].head === :call && length(fn.args[1].args) >= 3 # Note: >= 3, because the first argument is a function name
        swapped.args[1].args[2] = fn.args[1].args[3]
        swapped.args[1].args[3] = fn.args[1].args[2]
    else
        error("Function method passed for @symmetrical macro must have more than 2 arguments")
    end

    return swapped
end

"""
`leaftypes(datatype)` returns all subtypes of `datatype` that are leafs in the type tree.
"""
function leaftypes(datatype::Type)
    leafs = []
    stack = Type[datatype]
    while !isempty(stack)
        T = pop!(stack)
        if isconcretetype(T)
            push!(leafs, T)
        elseif typeof(T) == Union
            push!(stack, T.a) # Split Union types
            push!(stack, T.b)
        elseif T == Function # Prevent overflow
            push!(leafs, Function)
        else
            append!(stack, subtypes(T))
        end
    end

    return leafs
end

"""
Helper function to construct 1x1 `Matrix`
"""
mat(sc) = reshape([sc],1,1)

"""
Helper function to call dynamically generated `step!` functions
"""
function step!(id::Symbol, args...)
    getfield(Main, :step*id*:!)(args...)
end

"""
Helper function to call dynamically generated `init` functions
"""
function init(id::Symbol)
    getfield(Main, :init*id)()
end