text:
module ParPoly

export @estrin, @horner_split, @horner_split_simd
using SIMD

include("estrin.jl")

macro horner_split_simd(t,p...)
    x1   = gensym("x1")
    x2   = gensym("x2")
    x1x2 = gensym("x1x2")
    x2x2 = gensym("x2x2")

    blk = quote
        T = typeof($(esc(t)))
        $x1 = $(esc(t))
        $x2 = $(esc(t)) * $(esc(t))
        $x1x2 = Vec{2,T}(($x1,$x2))
        $x2x2 = Vec{2,T}(($x2,$x2))
    end
    n = length(p)
    p0 = esc(p[1])
    m = n÷2
    c = Array(Symbol,m)
    for i = 1:m
        c[i] = gensym("c$i")
    end

    if isodd(n)
        for i = 1:m
            push!(blk.args, :( $(c[i]) = Vec{2,T}(( $(esc(p[2i])), $(esc(p[2i+1])) )) ))
        end
    elseif iseven(n)
        for i = 1:m-1
            push!(blk.args, :( $(c[i]) = Vec{2,T}(( $(esc(p[2i])), $(esc(p[2i+1])) )) ))
        end
        push!(blk.args, :( $(c[m]) = Vec{2,T}(( $(esc(p[2m])), zero(T) )) )) # pad with a zero
    end

    ex = c[end]
    for i = m-1:-1:1
        ex = :(muladd($(x2x2), $ex, $(c[i])))
    end
    cc = gensym("cc")
    push!(blk.args, :($p0 + sum($x1x2*$ex) ))

    return blk
end

macro horner_split(x,p...)
    t = gensym("x1")
    t2 = gensym("x2")
    blk = quote
        $t = $(esc(x))
        $t2 = $(esc(x)) * $(esc(x))
    end

    n = length(p)
    p0 = esc(p[1])

    if isodd(n)
        ex_o = esc(p[end-1])
        ex_e = esc(p[end])

        for i = n-3:-2:2
            ex_o = :(muladd($(t2), $ex_o, $(esc(p[i]))))
        end
        for i = n-2:-2:2
            ex_e = :(muladd($(t2), $ex_e, $(esc(p[i]))))
        end
    elseif iseven(n)
        ex_o = esc(p[end])
        ex_e = esc(p[end-1])

        for i = n-2:-2:2
            ex_o = :(muladd($(t2), $ex_o, $(esc(p[i]))))
        end
        for i = n-3:-2:2
            ex_e = :(muladd($(t2), $ex_e, $(esc(p[i]))))
        end
    end
    push!(blk.args,:($(p0) + $(t)*$(ex_o) + $(t2)*$(ex_e)) )
    return blk
end

end


text:
# This file is a part of ParallelProcessingTools.jl, licensed under the MIT License (MIT).

using ParallelProcessingTools
using Test

@testset "workpartition" begin

    @testset "workpartition" begin
        num = 99
        part = 7
        tmp = div(num, part)
        cmp_res = [tmp, tmp+1]
        old = 0
        for j=1:part
            res = @inferred ParallelProcessingTools._workpart_hi(num, part, j)
            @test res - old in cmp_res
            old = res
        end
        res = @inferred ParallelProcessingTools._workpart_hi(Int32(99), Int32(7), Int32(7))
        @test res == Int32(99)
        @test typeof(res) <: Int32
        @test_throws AssertionError ParallelProcessingTools._workpart_hi(-1, 7, 1)
        @test_throws AssertionError ParallelProcessingTools._workpart_hi(20, 0, 1)
        @test_throws AssertionError ParallelProcessingTools._workpart_hi(20, 7, -1)
        @test_throws AssertionError ParallelProcessingTools._workpart_hi(0, 7, 8)

        res = Array{Int}([])
        num = 24
        part = 6
        tmp = div(num, part)
        cmp_res = [tmp, tmp+1]
        for i =1:part
            tmp = @inferred ParallelProcessingTools._workpart_scheme(Base.OneTo(num), part, i)
            @test length(tmp) in cmp_res
            res = vcat(res, tmp)
        end
        @test res == collect(1:num)

        res = Array{Int}([])
        num = 27
        part = 3
        stp = 4
        fi = 3

        for i =1:part
            res = vcat(res, @inferred workpart(fi:stp:num, 1:part, i))
        end
        @test res == collect(fi:stp:num)

        res = Array{Int}([])
        num = 14
        part = 3
        fi = 7

        for i =1:part
            res = vcat(res, @inferred workpart(UnitRange(fi:num), 1:part, i))
        end
        @test res == collect(fi:num)

        num = 20
        part = 3
        cmp_res = rand(num)
        res = Array{Float64}([])

        for i =1:part
            res = vcat(res, @inferred workpart(cmp_res, 1:part, i))
        end
        @test res == cmp_res
    end

    @testset "Examples" begin
        using Distributed, Base.Threads
        @test begin
            A = rand(100)
            # ...
            sub_A = workpart(A, procs(), myid())
            # ...
            idxs = workpart(eachindex(sub_A), allthreads(), threadid())
            for i in idxs
                # ...
            end
            true
        end
    end
end

ext: jl


text:
module FaceRecognition

using Images
using FileIO
using StatsBase
using MultivariateStats

include("load_data.jl")
include("eigenfaces.jl")

export  load_images,
        Model,
        train_model,
        image_to_eigenfaces,
        eigenfaces_to_image,
        reconstruct_image,
        reconstruct_images,
        get_difference,
        get_eigenfaces,
        save,
        load

end


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

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

The CancelJob operation cancels an unfinished job.  You can only cancel a job that has a
status of Submitted. To prevent a pipeline from starting to process a job while you're
getting the job identifier, use UpdatePipelineStatus to temporarily pause the pipeline.

# Arguments
- `id`: The identifier of the job that you want to cancel. To get a list of the jobs
  (including their jobId) that have a status of Submitted, use the ListJobsByStatus API
  action.

"""
function cancel_job(Id; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "DELETE",
        "/2012-09-25/jobs/$(Id)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function cancel_job(
    Id, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "DELETE",
        "/2012-09-25/jobs/$(Id)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

When you create a job, Elastic Transcoder returns JSON data that includes the values that
you specified plus information about the job that is created. If you have specified more
than one output for your jobs (for example, one output for the Kindle Fire and another
output for the Apple iPhone 4s), you currently must use the Elastic Transcoder API to list
the jobs (as opposed to the AWS Console).

# Arguments
- `pipeline_id`: The Id of the pipeline that you want Elastic Transcoder to use for
  transcoding. The pipeline determines several settings, including the Amazon S3 bucket from
  which Elastic Transcoder gets the files to transcode and the bucket into which Elastic
  Transcoder puts the transcoded files.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"Input"`: A section of the request body that provides information about the file that is
  being transcoded.
- `"Inputs"`: A section of the request body that provides information about the files that
  are being transcoded.
- `"Output"`:  A section of the request body that provides information about the transcoded
  (target) file. We strongly recommend that you use the Outputs syntax instead of the Output
  syntax.
- `"OutputKeyPrefix"`: The value, if any, that you want Elastic Transcoder to prepend to
  the names of all files that this job creates, including output files, thumbnails, and
  playlists.
- `"Outputs"`:  A section of the request body that provides information about the
  transcoded (target) files. We recommend that you use the Outputs syntax instead of the
  Output syntax.
- `"Playlists"`: If you specify a preset in PresetId for which the value of Container is
  fmp4 (Fragmented MP4) or ts (MPEG-TS), Playlists contains information about the master
  playlists that you want Elastic Transcoder to create. The maximum number of master
  playlists in a job is 30.
- `"UserMetadata"`: User-defined metadata that you want to associate with an Elastic
  Transcoder job. You specify metadata in key/value pairs, and you can add up to 10 key/value
  pairs per job. Elastic Transcoder does not guarantee that key/value pairs are returned in
  the same order in which you specify them.
"""
function create_job(PipelineId; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "POST",
        "/2012-09-25/jobs",
        Dict{String,Any}("PipelineId" => PipelineId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_job(
    PipelineId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return elastic_transcoder(
        "POST",
        "/2012-09-25/jobs",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("PipelineId" => PipelineId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_pipeline(input_bucket, name, role)
    create_pipeline(input_bucket, name, role, params::Dict{String,<:Any})

The CreatePipeline operation creates a pipeline with settings that you specify.

# Arguments
- `input_bucket`: The Amazon S3 bucket in which you saved the media files that you want to
  transcode.
- `name`: The name of the pipeline. We recommend that the name be unique within the AWS
  account, but uniqueness is not enforced. Constraints: Maximum 40 characters.
- `role`: The IAM Amazon Resource Name (ARN) for the role that you want Elastic Transcoder
  to use to create the pipeline.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"AwsKmsKeyArn"`: The AWS Key Management Service (AWS KMS) key that you want to use with
  this pipeline. If you use either s3 or s3-aws-kms as your Encryption:Mode, you don't need
  to provide a key with your job because a default key, known as an AWS-KMS key, is created
  for you automatically. You need to provide an AWS-KMS key only if you want to use a
  non-default AWS-KMS key, or if you are using an Encryption:Mode of aes-cbc-pkcs7, aes-ctr,
  or aes-gcm.
- `"ContentConfig"`: The optional ContentConfig object specifies information about the
  Amazon S3 bucket in which you want Elastic Transcoder to save transcoded files and
  playlists: which bucket to use, which users you want to have access to the files, the type
  of access you want users to have, and the storage class that you want to assign to the
  files. If you specify values for ContentConfig, you must also specify values for
  ThumbnailConfig. If you specify values for ContentConfig and ThumbnailConfig, omit the
  OutputBucket object.    Bucket: The Amazon S3 bucket in which you want Elastic Transcoder
  to save transcoded files and playlists.    Permissions (Optional): The Permissions object
  specifies which users you want to have access to transcoded files and the type of access
  you want them to have. You can grant permissions to a maximum of 30 users and/or predefined
  Amazon S3 groups.    Grantee Type: Specify the type of value that appears in the Grantee
  object:     Canonical: The value in the Grantee object is either the canonical user ID for
  an AWS account or an origin access identity for an Amazon CloudFront distribution. For more
  information about canonical user IDs, see Access Control List (ACL) Overview in the Amazon
  Simple Storage Service Developer Guide. For more information about using CloudFront origin
  access identities to require that users use CloudFront URLs instead of Amazon S3 URLs, see
  Using an Origin Access Identity to Restrict Access to Your Amazon S3 Content.  A canonical
  user ID is not the same as an AWS account number.     Email: The value in the Grantee
  object is the registered email address of an AWS account.    Group: The value in the
  Grantee object is one of the following predefined Amazon S3 groups: AllUsers,
  AuthenticatedUsers, or LogDelivery.      Grantee: The AWS user or group that you want to
  have access to transcoded files and playlists. To identify the user or group, you can
  specify the canonical user ID for an AWS account, an origin access identity for a
  CloudFront distribution, the registered email address of an AWS account, or a predefined
  Amazon S3 group     Access: The permission that you want to give to the AWS user that you
  specified in Grantee. Permissions are granted on the files that Elastic Transcoder adds to
  the bucket, including playlists and video files. Valid values include:     READ: The
  grantee can read the objects and metadata for objects that Elastic Transcoder adds to the
  Amazon S3 bucket.    READ_ACP: The grantee can read the object ACL for objects that Elastic
  Transcoder adds to the Amazon S3 bucket.    WRITE_ACP: The grantee can write the ACL for
  the objects that Elastic Transcoder adds to the Amazon S3 bucket.    FULL_CONTROL: The
  grantee has READ, READ_ACP, and WRITE_ACP permissions for the objects that Elastic
  Transcoder adds to the Amazon S3 bucket.      StorageClass: The Amazon S3 storage class,
  Standard or ReducedRedundancy, that you want Elastic Transcoder to assign to the video
  files and playlists that it stores in your Amazon S3 bucket.
- `"Notifications"`: The Amazon Simple Notification Service (Amazon SNS) topic that you
  want to notify to report job status.  To receive notifications, you must also subscribe to
  the new topic in the Amazon SNS console.     Progressing: The topic ARN for the Amazon
  Simple Notification Service (Amazon SNS) topic that you want to notify when Elastic
  Transcoder has started to process a job in this pipeline. This is the ARN that Amazon SNS
  returned when you created the topic. For more information, see Create a Topic in the Amazon
  Simple Notification Service Developer Guide.    Complete: The topic ARN for the Amazon SNS
  topic that you want to notify when Elastic Transcoder has finished processing a job in this
  pipeline. This is the ARN that Amazon SNS returned when you created the topic.    Warning:
  The topic ARN for the Amazon SNS topic that you want to notify when Elastic Transcoder
  encounters a warning condition while processing a job in this pipeline. This is the ARN
  that Amazon SNS returned when you created the topic.    Error: The topic ARN for the Amazon
  SNS topic that you want to notify when Elastic Transcoder encounters an error condition
  while processing a job in this pipeline. This is the ARN that Amazon SNS returned when you
  created the topic.
- `"OutputBucket"`: The Amazon S3 bucket in which you want Elastic Transcoder to save the
  transcoded files. (Use this, or use ContentConfig:Bucket plus ThumbnailConfig:Bucket.)
  Specify this value when all of the following are true:   You want to save transcoded files,
  thumbnails (if any), and playlists (if any) together in one bucket.   You do not want to
  specify the users or groups who have access to the transcoded files, thumbnails, and
  playlists.   You do not want to specify the permissions that Elastic Transcoder grants to
  the files.   When Elastic Transcoder saves files in OutputBucket, it grants full control
  over the files only to the AWS account that owns the role that is specified by Role.    You
  want to associate the transcoded files and thumbnails with the Amazon S3 Standard storage
  class.   If you want to save transcoded files and playlists in one bucket and thumbnails in
  another bucket, specify which users can access the transcoded files or the permissions the
  users have, or change the Amazon S3 storage class, omit OutputBucket and specify values for
  ContentConfig and ThumbnailConfig instead.
- `"ThumbnailConfig"`: The ThumbnailConfig object specifies several values, including the
  Amazon S3 bucket in which you want Elastic Transcoder to save thumbnail files, which users
  you want to have access to the files, the type of access you want users to have, and the
  storage class that you want to assign to the files. If you specify values for
  ContentConfig, you must also specify values for ThumbnailConfig even if you don't want to
  create thumbnails. If you specify values for ContentConfig and ThumbnailConfig, omit the
  OutputBucket object.    Bucket: The Amazon S3 bucket in which you want Elastic Transcoder
  to save thumbnail files.    Permissions (Optional): The Permissions object specifies which
  users and/or predefined Amazon S3 groups you want to have access to thumbnail files, and
  the type of access you want them to have. You can grant permissions to a maximum of 30
  users and/or predefined Amazon S3 groups.    GranteeType: Specify the type of value that
  appears in the Grantee object:     Canonical: The value in the Grantee object is either the
  canonical user ID for an AWS account or an origin access identity for an Amazon CloudFront
  distribution.  A canonical user ID is not the same as an AWS account number.     Email: The
  value in the Grantee object is the registered email address of an AWS account.     Group:
  The value in the Grantee object is one of the following predefined Amazon S3 groups:
  AllUsers, AuthenticatedUsers, or LogDelivery.      Grantee: The AWS user or group that you
  want to have access to thumbnail files. To identify the user or group, you can specify the
  canonical user ID for an AWS account, an origin access identity for a CloudFront
  distribution, the registered email address of an AWS account, or a predefined Amazon S3
  group.     Access: The permission that you want to give to the AWS user that you specified
  in Grantee. Permissions are granted on the thumbnail files that Elastic Transcoder adds to
  the bucket. Valid values include:     READ: The grantee can read the thumbnails and
  metadata for objects that Elastic Transcoder adds to the Amazon S3 bucket.    READ_ACP: The
  grantee can read the object ACL for thumbnails that Elastic Transcoder adds to the Amazon
  S3 bucket.    WRITE_ACP: The grantee can write the ACL for the thumbnails that Elastic
  Transcoder adds to the Amazon S3 bucket.    FULL_CONTROL: The grantee has READ, READ_ACP,
  and WRITE_ACP permissions for the thumbnails that Elastic Transcoder adds to the Amazon S3
  bucket.      StorageClass: The Amazon S3 storage class, Standard or ReducedRedundancy, that
  you want Elastic Transcoder to assign to the thumbnails that it stores in your Amazon S3
  bucket.
"""
function create_pipeline(
    InputBucket, Name, Role; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "POST",
        "/2012-09-25/pipelines",
        Dict{String,Any}("InputBucket" => InputBucket, "Name" => Name, "Role" => Role);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_pipeline(
    InputBucket,
    Name,
    Role,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return elastic_transcoder(
        "POST",
        "/2012-09-25/pipelines",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "InputBucket" => InputBucket, "Name" => Name, "Role" => Role
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The CreatePreset operation creates a preset with settings that you specify.  Elastic
Transcoder checks the CreatePreset settings to ensure that they meet Elastic Transcoder
requirements and to determine whether they comply with H.264 standards. If your settings
are not valid for Elastic Transcoder, Elastic Transcoder returns an HTTP 400 response
(ValidationException) and does not create the preset. If the settings are valid for Elastic
Transcoder but aren't strictly compliant with the H.264 standard, Elastic Transcoder
creates the preset and returns a warning message in the response. This helps you determine
whether your settings comply with the H.264 standard while giving you greater flexibility
with respect to the video that Elastic Transcoder produces.  Elastic Transcoder uses the
H.264 video-compression format. For more information, see the International
Telecommunication Union publication Recommendation ITU-T H.264: Advanced video coding for
generic audiovisual services.

# Arguments
- `container`: The container type for the output file. Valid values include flac, flv,
  fmp4, gif, mp3, mp4, mpg, mxf, oga, ogg, ts, and webm.
- `name`: The name of the preset. We recommend that the name be unique within the AWS
  account, but uniqueness is not enforced.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"Audio"`: A section of the request body that specifies the audio parameters.
- `"Description"`: A description of the preset.
- `"Thumbnails"`: A section of the request body that specifies the thumbnail parameters, if
  any.
- `"Video"`: A section of the request body that specifies the video parameters.
"""
function create_preset(Container, Name; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "POST",
        "/2012-09-25/presets",
        Dict{String,Any}("Container" => Container, "Name" => Name);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_preset(
    Container,
    Name,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return elastic_transcoder(
        "POST",
        "/2012-09-25/presets",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("Container" => Container, "Name" => Name), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The DeletePipeline operation removes a pipeline.  You can only delete a pipeline that has
never been used or that is not currently in use (doesn't contain any active jobs). If the
pipeline is currently in use, DeletePipeline returns an error.

# Arguments
- `id`: The identifier of the pipeline that you want to delete.

"""
function delete_pipeline(Id; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "DELETE",
        "/2012-09-25/pipelines/$(Id)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_pipeline(
    Id, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "DELETE",
        "/2012-09-25/pipelines/$(Id)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The DeletePreset operation removes a preset that you've added in an AWS region.  You can't
delete the default presets that are included with Elastic Transcoder.

# Arguments
- `id`: The identifier of the preset for which you want to get detailed information.

"""
function delete_preset(Id; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "DELETE",
        "/2012-09-25/presets/$(Id)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_preset(
    Id, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "DELETE",
        "/2012-09-25/presets/$(Id)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The ListJobsByPipeline operation gets a list of the jobs currently in a pipeline. Elastic
Transcoder returns all of the jobs currently in the specified pipeline. The response body
contains one element for each job that satisfies the search criteria.

# Arguments
- `pipeline_id`: The ID of the pipeline for which you want to get job information.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"Ascending"`:  To list jobs in chronological order by the date and time that they were
  submitted, enter true. To list jobs in reverse chronological order, enter false.
- `"PageToken"`:  When Elastic Transcoder returns more than one page of results, use
  pageToken in subsequent GET requests to get each successive page of results.
"""
function list_jobs_by_pipeline(
    PipelineId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "GET",
        "/2012-09-25/jobsByPipeline/$(PipelineId)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_jobs_by_pipeline(
    PipelineId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return elastic_transcoder(
        "GET",
        "/2012-09-25/jobsByPipeline/$(PipelineId)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The ListJobsByStatus operation gets a list of jobs that have a specified status. The
response body contains one element for each job that satisfies the search criteria.

# Arguments
- `status`: To get information about all of the jobs associated with the current AWS
  account that have a given status, specify the following status: Submitted, Progressing,
  Complete, Canceled, or Error.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"Ascending"`:  To list jobs in chronological order by the date and time that they were
  submitted, enter true. To list jobs in reverse chronological order, enter false.
- `"PageToken"`:  When Elastic Transcoder returns more than one page of results, use
  pageToken in subsequent GET requests to get each successive page of results.
"""
function list_jobs_by_status(Status; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "GET",
        "/2012-09-25/jobsByStatus/$(Status)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_jobs_by_status(
    Status, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "GET",
        "/2012-09-25/jobsByStatus/$(Status)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The ListPipelines operation gets a list of the pipelines associated with the current AWS
account.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"Ascending"`: To list pipelines in chronological order by the date and time that they
  were created, enter true. To list pipelines in reverse chronological order, enter false.
- `"PageToken"`: When Elastic Transcoder returns more than one page of results, use
  pageToken in subsequent GET requests to get each successive page of results.
"""
function list_pipelines(; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "GET",
        "/2012-09-25/pipelines";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_pipelines(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "GET",
        "/2012-09-25/pipelines",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The ListPresets operation gets a list of the default presets included with Elastic
Transcoder and the presets that you've added in an AWS region.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"Ascending"`: To list presets in chronological order by the date and time that they were
  created, enter true. To list presets in reverse chronological order, enter false.
- `"PageToken"`: When Elastic Transcoder returns more than one page of results, use
  pageToken in subsequent GET requests to get each successive page of results.
"""
function list_presets(; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "GET", "/2012-09-25/presets"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_presets(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "GET",
        "/2012-09-25/presets",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The ReadJob operation returns detailed information about a job.

# Arguments
- `id`: The identifier of the job for which you want to get detailed information.

"""
function read_job(Id; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "GET",
        "/2012-09-25/jobs/$(Id)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function read_job(
    Id, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "GET",
        "/2012-09-25/jobs/$(Id)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The ReadPipeline operation gets detailed information about a pipeline.

# Arguments
- `id`: The identifier of the pipeline to read.

"""
function read_pipeline(Id; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "GET",
        "/2012-09-25/pipelines/$(Id)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function read_pipeline(
    Id, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "GET",
        "/2012-09-25/pipelines/$(Id)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The ReadPreset operation gets detailed information about a preset.

# Arguments
- `id`: The identifier of the preset for which you want to get detailed information.

"""
function read_preset(Id; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "GET",
        "/2012-09-25/presets/$(Id)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function read_preset(
    Id, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "GET",
        "/2012-09-25/presets/$(Id)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    test_role(input_bucket, output_bucket, role, topics)
    test_role(input_bucket, output_bucket, role, topics, params::Dict{String,<:Any})

The TestRole operation tests the IAM role used to create the pipeline. The TestRole action
lets you determine whether the IAM role you are using has sufficient permissions to let
Elastic Transcoder perform tasks associated with the transcoding process. The action
attempts to assume the specified IAM role, checks read access to the input and output
buckets, and tries to send a test notification to Amazon SNS topics that you specify.

# Arguments
- `input_bucket`: The Amazon S3 bucket that contains media files to be transcoded. The
  action attempts to read from this bucket.
- `output_bucket`: The Amazon S3 bucket that Elastic Transcoder writes transcoded media
  files to. The action attempts to read from this bucket.
- `role`: The IAM Amazon Resource Name (ARN) for the role that you want Elastic Transcoder
  to test.
- `topics`: The ARNs of one or more Amazon Simple Notification Service (Amazon SNS) topics
  that you want the action to send a test notification to.

"""
function test_role(
    InputBucket,
    OutputBucket,
    Role,
    Topics;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return elastic_transcoder(
        "POST",
        "/2012-09-25/roleTests",
        Dict{String,Any}(
            "InputBucket" => InputBucket,
            "OutputBucket" => OutputBucket,
            "Role" => Role,
            "Topics" => Topics,
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function test_role(
    InputBucket,
    OutputBucket,
    Role,
    Topics,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return elastic_transcoder(
        "POST",
        "/2012-09-25/roleTests",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "InputBucket" => InputBucket,
                    "OutputBucket" => OutputBucket,
                    "Role" => Role,
                    "Topics" => Topics,
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

 Use the UpdatePipeline operation to update settings for a pipeline.  When you change
pipeline settings, your changes take effect immediately. Jobs that you have already
submitted and that Elastic Transcoder has not started to process are affected in addition
to jobs that you submit after you change settings.

# Arguments
- `id`: The ID of the pipeline that you want to update.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"AwsKmsKeyArn"`: The AWS Key Management Service (AWS KMS) key that you want to use with
  this pipeline. If you use either s3 or s3-aws-kms as your Encryption:Mode, you don't need
  to provide a key with your job because a default key, known as an AWS-KMS key, is created
  for you automatically. You need to provide an AWS-KMS key only if you want to use a
  non-default AWS-KMS key, or if you are using an Encryption:Mode of aes-cbc-pkcs7, aes-ctr,
  or aes-gcm.
- `"ContentConfig"`: The optional ContentConfig object specifies information about the
  Amazon S3 bucket in which you want Elastic Transcoder to save transcoded files and
  playlists: which bucket to use, which users you want to have access to the files, the type
  of access you want users to have, and the storage class that you want to assign to the
  files. If you specify values for ContentConfig, you must also specify values for
  ThumbnailConfig. If you specify values for ContentConfig and ThumbnailConfig, omit the
  OutputBucket object.    Bucket: The Amazon S3 bucket in which you want Elastic Transcoder
  to save transcoded files and playlists.    Permissions (Optional): The Permissions object
  specifies which users you want to have access to transcoded files and the type of access
  you want them to have. You can grant permissions to a maximum of 30 users and/or predefined
  Amazon S3 groups.    Grantee Type: Specify the type of value that appears in the Grantee
  object:    Canonical: The value in the Grantee object is either the canonical user ID for
  an AWS account or an origin access identity for an Amazon CloudFront distribution. For more
  information about canonical user IDs, see Access Control List (ACL) Overview in the Amazon
  Simple Storage Service Developer Guide. For more information about using CloudFront origin
  access identities to require that users use CloudFront URLs instead of Amazon S3 URLs, see
  Using an Origin Access Identity to Restrict Access to Your Amazon S3 Content.  A canonical
  user ID is not the same as an AWS account number.     Email: The value in the Grantee
  object is the registered email address of an AWS account.    Group: The value in the
  Grantee object is one of the following predefined Amazon S3 groups: AllUsers,
  AuthenticatedUsers, or LogDelivery.      Grantee: The AWS user or group that you want to
  have access to transcoded files and playlists. To identify the user or group, you can
  specify the canonical user ID for an AWS account, an origin access identity for a
  CloudFront distribution, the registered email address of an AWS account, or a predefined
  Amazon S3 group     Access: The permission that you want to give to the AWS user that you
  specified in Grantee. Permissions are granted on the files that Elastic Transcoder adds to
  the bucket, including playlists and video files. Valid values include:     READ: The
  grantee can read the objects and metadata for objects that Elastic Transcoder adds to the
  Amazon S3 bucket.    READ_ACP: The grantee can read the object ACL for objects that Elastic
  Transcoder adds to the Amazon S3 bucket.     WRITE_ACP: The grantee can write the ACL for
  the objects that Elastic Transcoder adds to the Amazon S3 bucket.    FULL_CONTROL: The
  grantee has READ, READ_ACP, and WRITE_ACP permissions for the objects that Elastic
  Transcoder adds to the Amazon S3 bucket.      StorageClass: The Amazon S3 storage class,
  Standard or ReducedRedundancy, that you want Elastic Transcoder to assign to the video
  files and playlists that it stores in your Amazon S3 bucket.
- `"InputBucket"`: The Amazon S3 bucket in which you saved the media files that you want to
  transcode and the graphics that you want to use as watermarks.
- `"Name"`: The name of the pipeline. We recommend that the name be unique within the AWS
  account, but uniqueness is not enforced. Constraints: Maximum 40 characters
- `"Notifications"`: The topic ARN for the Amazon Simple Notification Service (Amazon SNS)
  topic that you want to notify to report job status.  To receive notifications, you must
  also subscribe to the new topic in the Amazon SNS console.     Progressing: The topic ARN
  for the Amazon Simple Notification Service (Amazon SNS) topic that you want to notify when
  Elastic Transcoder has started to process jobs that are added to this pipeline. This is the
  ARN that Amazon SNS returned when you created the topic.    Complete: The topic ARN for the
  Amazon SNS topic that you want to notify when Elastic Transcoder has finished processing a
  job. This is the ARN that Amazon SNS returned when you created the topic.    Warning: The
  topic ARN for the Amazon SNS topic that you want to notify when Elastic Transcoder
  encounters a warning condition. This is the ARN that Amazon SNS returned when you created
  the topic.    Error: The topic ARN for the Amazon SNS topic that you want to notify when
  Elastic Transcoder encounters an error condition. This is the ARN that Amazon SNS returned
  when you created the topic.
- `"Role"`: The IAM Amazon Resource Name (ARN) for the role that you want Elastic
  Transcoder to use to transcode jobs for this pipeline.
- `"ThumbnailConfig"`: The ThumbnailConfig object specifies several values, including the
  Amazon S3 bucket in which you want Elastic Transcoder to save thumbnail files, which users
  you want to have access to the files, the type of access you want users to have, and the
  storage class that you want to assign to the files. If you specify values for
  ContentConfig, you must also specify values for ThumbnailConfig even if you don't want to
  create thumbnails. If you specify values for ContentConfig and ThumbnailConfig, omit the
  OutputBucket object.    Bucket: The Amazon S3 bucket in which you want Elastic Transcoder
  to save thumbnail files.    Permissions (Optional): The Permissions object specifies which
  users and/or predefined Amazon S3 groups you want to have access to thumbnail files, and
  the type of access you want them to have. You can grant permissions to a maximum of 30
  users and/or predefined Amazon S3 groups.    GranteeType: Specify the type of value that
  appears in the Grantee object:    Canonical: The value in the Grantee object is either the
  canonical user ID for an AWS account or an origin access identity for an Amazon CloudFront
  distribution.  A canonical user ID is not the same as an AWS account number.     Email: The
  value in the Grantee object is the registered email address of an AWS account.    Group:
  The value in the Grantee object is one of the following predefined Amazon S3 groups:
  AllUsers, AuthenticatedUsers, or LogDelivery.      Grantee: The AWS user or group that you
  want to have access to thumbnail files. To identify the user or group, you can specify the
  canonical user ID for an AWS account, an origin access identity for a CloudFront
  distribution, the registered email address of an AWS account, or a predefined Amazon S3
  group.     Access: The permission that you want to give to the AWS user that you specified
  in Grantee. Permissions are granted on the thumbnail files that Elastic Transcoder adds to
  the bucket. Valid values include:     READ: The grantee can read the thumbnails and
  metadata for objects that Elastic Transcoder adds to the Amazon S3 bucket.    READ_ACP: The
  grantee can read the object ACL for thumbnails that Elastic Transcoder adds to the Amazon
  S3 bucket.    WRITE_ACP: The grantee can write the ACL for the thumbnails that Elastic
  Transcoder adds to the Amazon S3 bucket.    FULL_CONTROL: The grantee has READ, READ_ACP,
  and WRITE_ACP permissions for the thumbnails that Elastic Transcoder adds to the Amazon S3
  bucket.       StorageClass: The Amazon S3 storage class, Standard or ReducedRedundancy,
  that you want Elastic Transcoder to assign to the thumbnails that it stores in your Amazon
  S3 bucket.
"""
function update_pipeline(Id; aws_config::AbstractAWSConfig=global_aws_config())
    return elastic_transcoder(
        "PUT",
        "/2012-09-25/pipelines/$(Id)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_pipeline(
    Id, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "PUT",
        "/2012-09-25/pipelines/$(Id)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

With the UpdatePipelineNotifications operation, you can update Amazon Simple Notification
Service (Amazon SNS) notifications for a pipeline. When you update notifications for a
pipeline, Elastic Transcoder returns the values that you specified in the request.

# Arguments
- `id`: The identifier of the pipeline for which you want to change notification settings.
- `notifications`: The topic ARN for the Amazon Simple Notification Service (Amazon SNS)
  topic that you want to notify to report job status.  To receive notifications, you must
  also subscribe to the new topic in the Amazon SNS console.     Progressing: The topic ARN
  for the Amazon Simple Notification Service (Amazon SNS) topic that you want to notify when
  Elastic Transcoder has started to process jobs that are added to this pipeline. This is the
  ARN that Amazon SNS returned when you created the topic.    Complete: The topic ARN for the
  Amazon SNS topic that you want to notify when Elastic Transcoder has finished processing a
  job. This is the ARN that Amazon SNS returned when you created the topic.    Warning: The
  topic ARN for the Amazon SNS topic that you want to notify when Elastic Transcoder
  encounters a warning condition. This is the ARN that Amazon SNS returned when you created
  the topic.    Error: The topic ARN for the Amazon SNS topic that you want to notify when
  Elastic Transcoder encounters an error condition. This is the ARN that Amazon SNS returned
  when you created the topic.

"""
function update_pipeline_notifications(
    Id, Notifications; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "POST",
        "/2012-09-25/pipelines/$(Id)/notifications",
        Dict{String,Any}("Notifications" => Notifications);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_pipeline_notifications(
    Id,
    Notifications,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return elastic_transcoder(
        "POST",
        "/2012-09-25/pipelines/$(Id)/notifications",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("Notifications" => Notifications), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

The UpdatePipelineStatus operation pauses or reactivates a pipeline, so that the pipeline
stops or restarts the processing of jobs. Changing the pipeline status is useful if you
want to cancel one or more jobs. You can't cancel jobs after Elastic Transcoder has started
processing them; if you pause the pipeline to which you submitted the jobs, you have more
time to get the job IDs for the jobs that you want to cancel, and to send a CancelJob
request.

# Arguments
- `id`: The identifier of the pipeline to update.
- `status`: The desired status of the pipeline:    Active: The pipeline is processing jobs.
     Paused: The pipeline is not currently processing jobs.

"""
function update_pipeline_status(
    Id, Status; aws_config::AbstractAWSConfig=global_aws_config()
)
    return elastic_transcoder(
        "POST",
        "/2012-09-25/pipelines/$(Id)/status",
        Dict{String,Any}("Status" => Status);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_pipeline_status(
    Id,
    Status,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return elastic_transcoder(
        "POST",
        "/2012-09-25/pipelines/$(Id)/status",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("Status" => Status), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end


text:
type FractalDict
	data::Dict{AbstractString,Function}
end
FractalDict()=FractalDict(Dict{AbstractString,Function}())

const frac_dict=FractalDict()
function add_frac!(fracname::AbstractString,f::Function)
	frac_dict.data[fracname]=f
end

fractal_names() = keys(frac_dict.data)
function create_fractal(fractal_name::AbstractString)
	if !(fractal_name in keys(frac_dict.data))
		error("Unknown fractal name: $fractal_name")
	end
	return frac_dict.data[fractal_name]
end

@inline num_params(f::Function) = length(Base.uncompressed_ast(f.code).args[2][1])

"""
    @fractal name inner_function
    @fractal name zinit inner_function

Create a fractal variation and add it to the catalog.

The first macro invocation is used when the complex-valued pixel location is intended to be used
as the initial 'z' value for the fractal iteration (as in Julia sets). In this case,
`inner_function` should not take any parameters.

The second macro invocation is used when the complex-valued pixel location is intended to be used
as an extra parameter to the fractal iteration and an initial 'z' value is needed (as in Mandelbrot
sets).  In this case, `zinit` is the initial 'z' value, and `inner_function` should take a
complex-valued parameter representing the pixel location.
"""
macro fractal(fracname,zinit_func...)
	frac_name=string(fracname)
	closure_name=symbol(frac_name*"_closure")
	if length(zinit_func)==1
		func=zinit_func[1]
		@assert typeof(eval(func))==Function
		@assert num_params(eval(func))==0
		return quote
			@inline function $(esc(closure_name)){T}(param::T)
				@fastmath @inline f(z::Complex)=$func()
				return f,param
			end
			add_frac!($fracname,$(esc(closure_name)))
		end
	elseif length(zinit_func)==2
		zinit=zinit_func[1]
		func=zinit_func[2]
		@assert typeof(eval(func))==Function
		@assert num_params(eval(func))==1
		return quote
			@inline function $(esc(closure_name)){T}(param::T)
				@fastmath @inline f(z::Complex)=$func(param)
				return f,$zinit
			end
			add_frac!($fracname,$(esc(closure_name)))
		end
	end

end

const czero=zero(Complex)
const chalf=Complex(0.5,0.0)
const cone=Complex(1.0,0.0)
const phi=(1.0+sqrt(5.0))/2.0

@fractal "mandelbrot" czero (c::Complex)->z*z+c
@fractal "mandelbrot_minvc" czero (c::Complex)->z*z-inv(c)
@fractal "mandelbrot_minvc_p25" czero (c::Complex)->z*z-inv(c)+0.25
@fractal "mandelbrot_minvc_m25" czero (c::Complex)->z*z-inv(c)-0.25
@fractal "mandelbrot_minvc_m50" czero (c::Complex)->z*z-inv(c)-0.50
@fractal "mandelbrot_minvc_m75" czero (c::Complex)->z*z-inv(c)-0.75
@fractal "mandelbrot_minvc_mmyreberg" czero (c::Complex)->z*z-inv(c)-1.40115
@fractal "mandelbrot_minvc_m2" czero (c::Complex)->z*z-inv(c)-2.0

@fractal "mandelbrot_lambda" chalf (lambda::Complex)->z*(1.0-z)*lambda
@fractal "mandelbrot_invlambda" chalf (lambda::Complex)->z*(1.0-z)*inv(lambda)
@fractal "mandelbrot_invlambda_m1" chalf (lambda::Complex)->z*(1.0-z)*(inv(lambda)+cone)

@fractal "burningship" czero (c::Complex)->Complex(abs(real(z)),abs(imag(z)))^2-c

@fractal "julia_z2_1mphi" ()->z*z+Complex(1.0-phi,0.0)
@fractal "julia_z2_phim1_phim1" ()->z*z+Complex(phi-2.0,phi-1.0)
@fractal "julia_z2_285" ()->z*z+Complex(0.285,0.0)
@fractal "julia_z2_285_01" ()->z*z+Complex(0.285,0.01)
@fractal "julia_z2_n8_156" ()->z*z+Complex(-0.8,0.156)
@fractal "julia_z2_n7629_1889" ()->z*z+Complex(-0.7269,0.1889)

@fractal "julia_expz_n65" ()->exp(z)+Complex(-0.65,0.0)
@fractal "julia_expz3_n59" ()->exp(z^3)+Complex(-0.59,0.0)
@fractal "julia_expz3_n621" ()->exp(z^3)+Complex(-0.621,0.0)

@fractal "julia_sqrtsinhz2" ()->sqrt(sinh(z^2))
@fractal "julia_sqrtsinhz2_065_122" ()->sqrt(sinh(z^2))+Complex(0.065,0.122)

@fractal "tricorn" czero (c::Complex)->z'*z'+c

max_stars_repo_name: jblondin/Fractal

max_issues_repo_name: jblondin/Fractal

max_forks_repo_name: jblondin/Fractal


text:
#
# This file is a part of MolecularGraph.jl
# Licensed under the MIT License http://opensource.org/licenses/MIT
#

export
    PlainDiGraph, plaindigraph

struct PlainDiGraph <: OrderedDiGraph
    outneighbormap::Vector{Dict{Int,Int}}
    inneighbormap::Vector{Dict{Int,Int}}
    edges::Vector{Tuple{Int,Int}}
    cache::Dict{Symbol,Any}
end

"""
    plaindigraph() -> PlainDiGraph

Generate empty `PlainDiGraph`.
"""
plaindigraph() = PlainDiGraph([], [], [], Dict())

"""
    plaindigraph(nodes, edges) -> PlainDiGraph

Generate `DiGraph` that have given nodes and edges represented by the list of
node indices in integer and the list of pairs of node indices, respectively.
"""
function plaindigraph(size::Int, edges)
    outnbrmap = [Dict{Int,Int}() for i in 1:size]
    innbrmap = [Dict{Int,Int}() for i in 1:size]
    edges = collect(edges)
    for (i, (s, t)) in enumerate(edges)
        outnbrmap[s][i] = t
        innbrmap[t][i] = s
    end
    return PlainDiGraph(outnbrmap, innbrmap, edges, Dict{Symbol,Any}())
end

"""
    plaindigraph(graph::OrderedDiGraph) -> PlainDiGraph

Convert an arbitrary `OrderedDiGraph` into a `PlainDiGraph`.
"""
function plaindigraph(graph::OrderedDiGraph)
    newg = plaindigraph()
    for nbr in graph.outneighbormap
        push!(newg.outneighbormap, copy(nbr))
    end
    for nbr in graph.inneighbormap
        push!(newg.inneighbormap, copy(nbr))
    end
    append!(newg.edges, graph.edges)
    return newg
end

"""
    plaindigraph(graph::DirectedGraph) -> PlainDiGraph

Convert an arbitrary `DirectedGraph` into a `PlainDiGraph`.

If the given graph has non-sequential indices (ex. subgraph view), node and
edge indices are sorted in ascending order and are re-indexed.
"""
function plaindigraph(graph::DirectedGraph)
    newg = plaindigraph()
    nkeys = sort(collect(nodeset(graph)))
    ekeys = sort(collect(edgeset(graph)))
    nmap = Dict{Int,Int}()
    for (i, n) in enumerate(nkeys)
        nmap[n] = i
        push!(newg.outneighbormap, Dict())
        push!(newg.inneighbormap, Dict())
    end
    for (i, e) in enumerate(ekeys)
        (olds, oldt) = getedge(graph, e)
        s = nmap[olds]
        t = nmap[oldt]
        push!(newg.edges, (s, t))
        newg.outneighbormap[s][i] = t
        newg.inneighbormap[t][i] = s
    end
    return newg
end

function unlinknodes(graph::PlainDiGraph, nodes)
    # TODO: costful
    subg = nodesubgraph(graph, setdiff(nodeset(graph), nodes))
    return plaindigraph(subg)
end

function unlinkedges(graph::PlainDiGraph, edges)
    # TODO: costful
    subg = SubgraphView(graph, nodeset(graph), setdiff(edgeset(graph), edges))
    return plaindigraph(subg)
end


text:
struct Point{T<:Real} <: Pointy{T}
    x::T
    y::T
end


text:
using Test

@testset "MuttsInterface.jl" begin
    include("MuttsInterface.jl")
end

# -----------------------------------------------------------
# --- Example packages
# -----------------------------------------------------------

import Pkg

# Run the tests for the packages in examples/...
@testset "examples" begin
    Pkg.activate("../examples/MuttsVersionedTrees")
    Pkg.test(coverage=true)
end

# Done runing example packages
Pkg.activate(".")

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


text:
module LogisticRegression

using Statistics, Optim, NLSolversBase, Distributions

export logreg

include("structures.jl")
include("estimation.jl")
include("hypothesis_tests.jl")

end # module


text:
# Type Definitions ############################################################
struct Path
  X::Array{Float64}
  Y::Array{Float64}
  dX::Array{Float64}
  dY::Array{Float64}
  ddX::Array{Float64}
  ddY::Array{Float64}
  Sx::Array{Float64}
  Sy::Array{Float64}
  Px::Array{Float64}
  Py::Array{Float64}
  R::Array{Float64}
  S::Array{Float64}
end

struct Road
  path::Path
  width::Float64
  road::Union{vis.RenderObject, Nothing}
end
Road(path, width) = Road(path, width, nothing)

mutable struct Agent
  id::Int
  x::Array{Float64, 1}
  dynamics!::Function
  controller!::Function
  is_braking::Bool
  custom::Any
  car::Union{vis.RenderObject, Nothing}
end
Agent(id, x) = Agent(id, x, default_dynamics!, default_controller!, false,
                     nothing, nothing)
Agent(id, x, car) = Agent(id, x, default_dynamics!, default_controller!, false,
                          nothing, car)

struct World
  road::Road
  agents::Array{Agent, 1}
  vis_scaling::Float64
end
World(road) = World(road, Agent[])


text:
# This file reproduces just enough functionality of BEAST to allow
# for meaningful testing of non-trivial user cases
using StaticArrays
using CompScienceMeshes

struct RTRefSpace{T<:Real} end

function (f::RTRefSpace{T})(x) where {T}
    u, v = parametric(x)
    j = jacobian(x)

    tu = tangents(x,1)
    tv = tangents(x,2)

    d = 2/j

    return SVector((
        ((tu*(u-1) + tv*v    ) / j, d),
        ((tu*u     + tv*(v-1)) / j, d),
        ((tu*u     + tv*v    ) / j, d)
    ))
end

numfunctions(::RTRefSpace) = 3


text:
monthwrap(m1,m2) = (v = mod1(m1+m2,12); return v < 0 ? 12 + v : v)

if m < d
    delta = d - m
    if f-1 < n-l
        _deleteat_beg!(a, f, delta)
    else
        _deleteat_end!(a, l-delta+1, delta)
    end
elseif m > d
    delta = m - d
    if f-1 < n-l
        _growat_beg!(a, f, delta)
    else
        _growat_end!(a, l+1, delta)
    end
end

@eval begin
    ($fname)(T::Type, dims...)       = fill!(Array(T, dims...), ($felt)(T))
    ($fname)(dims...)                = fill!(Array(Float64, dims...), ($felt)(Float64))
    ($fname){T}(A::AbstractArray{T}) = fill!(similar(A), ($felt)(T))
end

is(I,A) && (I = X::typeof(I))
c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))

if !in(v_elem, seen)
    push!(ret, v_elem)
    push!(seen, v_elem)
end

for j = offsetj+(1:n)
    for i = offseti+(1:m)
        B[j,i] = ctranspose(A[i,j])
    end
end

for f in (:-, :~, :conj, :sign)
    @eval begin
        function ($f)(A::StridedArray)
            F = similar(A)
            for i in eachindex(A)
                F[i] = ($f)(A[i])
            end
            return F
        end
    end
end

(-)(A::StridedArray{Bool}) = reshape([ -A[i] for i in eachindex(A) ], size(A))

function !(A::StridedArray{Bool})
    F = similar(A)
    for i in eachindex(A)
        F[i] = !A[i]
    end
    return F
end
.^(X::AbstractArray, y::Number      ) =
    reshape([ x ^ y for x in X ], size(X))

@inline wheel_index(n) = ( (d, r) = divrem(n - 1, 30); return 8d + wheel_indices[r+1] )

import Base.in
precompile(Base.LineEdit.edit_move_up, (Base.LineEdit.MIState,))
precompile(Base.LineEdit.edit_move_up, (IOBuffer,))

byteenv = ByteString[cstr(string(k)*"="*strin

max_stars_repo_name: lidiapopescu/JuliaDT

max_issues_repo_name: lidiapopescu/JuliaDT

max_forks_repo_name: JuliaComputing/JuliaDT


text:
using UnitaryDecomposition

U=rand(4,4)

N=2

UDecompose()


text:
include("je_polyagamma_struct.jl")
include("je_polyagamma_optimize.jl")

function joint_estimate_pg!(
    items::Vector{<:AbstractItem},
    examinees::Vector{<:AbstractExaminee},
    responses::Vector{<:AbstractResponse};
    max_time::Int64 = 100,
    mcmc_iter::Int64 = 10,
    x_tol_rel::Float64 = 0.001,
    item_sampling::Bool = false,
    examinee_sampling::Bool = false,
    kwargs...
    )
    I = size(items, 1)
    N = size(examinees, 1)

        #from now we work only on these, the algorithm is dependent on the type of latents and parameters.
        response_matrix = get_response_matrix(responses, I, N);
        parameters = map(i -> copy(get_parameters(i)), items)
        latents = map(e -> copy(get_latents(e)), examinees)

        #extract items per examinee and examinees per item indices
        n_index = Vector{Vector{Int64}}(undef, I)
        i_index = Array{Array{Int64,1},1}(undef, N)
        for n = 1 : N
            i_index[n] = findall(.!ismissing.(response_matrix[:, n]))
            if n <= I
                n_index[n] = findall(.!ismissing.(response_matrix[n, :]))
            end
        end #15ms
        responses_per_item = [ Vector{Float64}(response_matrix[i, n_index[i]]) for i = 1 : I]
        responses_per_examinee = [ Vector{Float64}(response_matrix[i_index[n], n]) for n = 1 : N]
        # #set starting chain
        # map(
        #     p -> begin
        #         p.chain = [[p.a, p.b] for j = 1:1000]
        #     end,
        #     parameters,
        # );

    je_pg_model =  JointEstimationPolyaGammaModel(
        parameters,
        latents,
        responses_per_item,
        responses_per_examinee,
        n_index,
        i_index,
        item_sampling,
        examinee_sampling,
        [Float64(mcmc_iter), Float64(mcmc_iter), Float64(verbosity)]
        )
    parameters, latents = optimize(je_pg_model)
    for n in 1 : N
        e = examinees[n]
        l = latents[n]
        examinees[n] = Examinee(e.idx, e.id, l)
        if n<=I
            i = items[n]
            p = parameters[n]
            items[n] = Item(i.idx, i.id, p)
        end
    end

    map(i -> update_estimate!(i), items);
    map(e -> update_estimate!(e), examinees);
    return nothing
end
# function joint_estimate_pg!(
#     items::Vector{<:AbstractItem},
#     examinees::Vector{<:AbstractExaminee},
#     responses::Vector{<:AbstractResponse};
#     max_time::Int64 = 100,
#     mcmc_iter::Int64 = 10,
#     x_tol_rel::Float64 = 0.001,
#     item_sampling::Bool = false,
#     examinee_sampling::Bool = false,
#     kwargs...
#     )

#     responses_per_examinee = map(
#         e -> sort(get_responses_by_examinee_id(e.id, responses), by = x -> x.item_idx),
#         examinees,
#     );
#     items_idx_per_examinee = map(
#         e -> sort(map(r -> items[r.item_idx].idx, responses_per_examinee[e.idx])),
#         examinees,
#     );
#     responses_per_item = map(
#         i -> sort(get_responses_by_item_id(i.id, responses), by = x -> x.examinee_idx),
#         items,
#     );
#     examinees_idx_per_item = map(
#         i -> sort(map(r -> examinees[r.examinee_idx].idx, responses_per_item[i.idx])),
#         items,
#     );

#     map(
#         i -> begin
#             i.parameters.chain = [[i.parameters.a, i.parameters.b] for j = 1:1000]
#         end,
#         items,
#     );

#     stop = false
#     old_pars = get_parameters_vals(items)
#     start_time = time()
#     iter = 1

#     while !stop
#             W = generate_w(
#                 items,
#                 map(i -> examinees[examinees_idx_per_item[i.idx]], items),
#             )
#             map(
#                 i -> mcmc_iter_pg!(
#                     i,
#                     examinees[examinees_idx_per_item[i.idx]],
#                     responses_per_item[i.idx],
#                     filter(w -> w.i_idx == i.idx, W);
#                     sampling = item_sampling,
#                     already_sorted = true,
#                 ),
#                 items,
#             )
#             map(
#                 e -> mcmc_iter_pg!(
#                     e,
#                     items[items_idx_per_examinee[e.idx]],
#                     responses_per_examinee[e.idx],
#                     filter(w -> w.e_idx == e.idx, W);
#                     sampling = examinee_sampling,
#                     already_sorted = true,
#                 ),
#                 examinees,
#             )
#             if (iter % 200) == 0
#                 #map(i -> update_estimate!(i), items);
#                 if any([
#                     check_iter(iter; max_iter = mcmc_iter),
#                     check_time(start_time; max_time = max_time)
#                     #check_x_tol_rel!(
#                     #     items,
#                     #     old_pars;
#                     #     x_tol_rel = x_tol_rel)
#                     ])

#                     stop = true
#                 end
#             end
#             iter += 1
#     end
#     map(i -> update_estimate!(i), items);
#     map(e -> update_estimate!(e), examinees);

#     return nothing
# end


text:
using Revise

using OpticalBlochEquations

using Plots
using SparseArrays
using LinearAlgebra
using StaticArrays
using BenchmarkTools
using PhysicalConstants.CODATA2018
import DifferentialEquations: ODEProblem, solve, DP5

const h     = PlanckConstant.val
const ħ     = h / 2π
const μB    = BohrMagneton.val
const c     = SpeedOfLightInVacuum.val
const ϵ0    = VacuumElectricPermittivity.val

# Define constants for the problem
ΩP0 = @with_unit 2π * 10 "MHz"
tP  = @with_unit 0.0 "μs"
τP  = @with_unit 30 "μs"
ω0P = @with_unit -10.5 "μs"
ΩS0 = @with_unit 2π * 10 "MHz" # maximum Rabi frequency
tS  = @with_unit 0.0 "μs"  # Stokes pulse offset time
τS  = @with_unit 30 "μs"  # Stokes pulse width
ω0S = @with_unit 0.0 "μs"    # Stokes initial frequency
α   = @with_unit 40 "THz"   # pump sweep rate
β   = @with_unit 40 "THz"   # Stokes sweep rate
Δ0  = @with_unit 1.5 "GHz"

# Generate states
m1 = Manifold(F=0, ω=0, μ=0)
m2 = Manifold(F=0, ω=0, μ=0)
m3 = Manifold(F=0, ω=0, μ=0)
states = [m1.states..., m2.states..., m3.states...]

@inline function Ω(t, Ω0, offset, τ_width)
    return Ω0 * exp(-(t - offset)^2 / (2τ_width^2))
end

@inline function ωt(t, start, rate, offset)
    return start + rate * (t-offset)
end

using Parameters
function f(H, t, p)
    @unpack ΩS0, tS, τS, ΩP0, tP, τP, α, β, ω0S, ω0P = p
    H.re[1,2] = H.re[2,1] = Ω(t, ΩP0, tP, τP)
    H.re[2,3] = H.re[3,2] = Ω(t, ΩS0, tS, τS)
    H.re[2,2] = ωt(t, 0, α, ω0S)
    H.re[3,3] = ωt(t, 0, β, ω0P)
end

p = @params ΩS0, ΩP0, tS, tP, τS, τP, α, β, ω0S, ω0P
d = zeros(3, 3, 3)
(dψ, ψ, p_) = schrödinger(states, lasers, d, f, p)
@btime ψ!(dψ, ψ, p_, 1.0)

tmax = 15.0e-6
tspan = (-tmax, tmax); tstops = -tmax:tmax/4000:tmax
prob = ODEProblem(ψ!, ψ, tspan, p_)
@time sol = solve(prob, alg=DP5(), saveat=tstops, abstol=1.0e-8, reltol=1.0e-6)

ρ₁₁ = [norm(x[1])^2 for x in sol.u]
ρ₂₂ = [norm(x[2])^2 for x in sol.u]
ρ₃₃ = [norm(x[3])^2 for x in sol.u]
plot(sol.t, ρ₁₁)
plot!(sol.t, ρ₂₂)
plot!(sol.t, ρ₃₃, 0.0:0.2:1.0)


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

using Markdown
using InteractiveUtils

# ╔═╡ 94e189e0-d4cf-11ec-20f5-c59770b3e5a0
begin
	using GLMakie,CairoMakie.GeometryBasics
	GLMakie.activate!()

    fig = Figure(resolution = (800, 800), fontsize = 14,lightposition = Vec3f(0, 0, 0.8), ambient = Vec3f(0.6, 0.6, 0.6),
        backlight = 2.0f0)
    azimuth = 0.1pi
    elevation = 0.1pi
    xs = LinRange(0, 10, 100)
    ys = LinRange(0, 10, 100)
    zs = [cos(x) * sin(y) for x in xs, y in ys]
    ax = Axis3(fig[1,1],elevation = elevation, azimuth = azimuth)
    tspan=LinRange(0, 2*π, 100)
	r=radius=4
	x1(t)=0
	y1(t)=radius*cos(t)
	z1(t)=radius*sin(t)
	x2(t)=radius*cos(t)
	y2(t)=radius*sin(t)
	z2(t)=0
	xs1=x1.(tspan)
	ys1=y1.(tspan)
	zs1=z1.(tspan)
	xs2=x2.(tspan)
	ys2=y2.(tspan)
	zs2=z2.(tspan)

	lines!(xs1,ys1,zs1)
	lines!(xs2,ys2,zs2)
	fig

end

# ╔═╡ Cell order:
# ╠═94e189e0-d4cf-11ec-20f5-c59770b3e5a0

max_stars_repo_name: phpsmarter/plutonote

max_issues_repo_name: phpsmarter/plutonote

max_forks_repo_name: phpsmarter/plutonote


text:
using Test
using Dates
using Printf
using NCDatasets

sz = (4,5)
filename = tempname()
#filename = "/tmp/test-6.nc"
#if isfile(filename)
#    rm(filename)
#end

# The mode "c" stands for creating a new file (clobber)
NCDatasets.NCDataset(filename,"c") do ds

    # define the dimension "lon" and "lat"
    ds.dim["lon"] = sz[1]
    ds.dim["lat"] = sz[2]

    v = NCDatasets.defVar(ds,"small",Float64,("lon","lat"))
#    @test_throws Union{NCDatasets.NetCDFError,DimensionMismatch} v[:] = zeros(sz[1]+1,sz[2])
    @test_throws NCDatasets.NetCDFError v[1:sz[1],1:sz[2]] = zeros(sz[1]+1,sz[2])
    @test_throws NCDatasets.NetCDFError v[sz[1]+1,1] = 1
    @test_throws NCDatasets.NetCDFError v[-1,1] = 1

    # variables
    for T in [UInt8,Int8,UInt16,Int16,UInt32,Int32,UInt64,Int64,Float32,Float64,
              Char,String]
    #for T in [String]
        local data
        data, scalar_data =
            if T == String
                [Char(i+60) * Char(j+60) for i = 1:sz[1], j = 1:sz[2]], "abcde"
            else
                [T(i+2*j) for i = 1:sz[1], j = 1:sz[2]], T(100)
            end

        v = NCDatasets.defVar(ds,"var-$T",T,("lon","lat"))
        v[:,:] = data
        @test v[:,:] == data[:,:]

        # issue #33
        @test Array(v) == data

        @test v[2,:] == data[2,:]

        @test v[:,3] == data[:,3]

        @test v[2,3] == data[2,3]

        # ignore extra index
        @test v[2,3,1,1] == data[2,3,1,1]

        # ignore extra index
        @test v[2:3,3,1,1] == data[2:3,3,1,1]

        @test v[[1,2,3],:] == data[[1,2,3],:]

        # write scalar
        v.var[1,1] = scalar_data
        v.var[:,:] .= scalar_data
        @test all(v.var[:,:][:] .== scalar_data)

        # stridded write and read
        v[1:2:end,1:2:end] = data[1:2:end,1:2:end]
        @test all(v[1:2:end,1:2:end] .== data[1:2:end,1:2:end])

    end
end

# quick interface
NCDataset(filename,"c") do ds
    data = Int32[i+3*j for i = 1:sz[1], j = 1:sz[2]]
    defVar(ds,"temp",data,("lon","lat"), attrib = [
        "units" => "degree_Celsius",
        "long_name" => "Temperature"
    ])
    @test ds["temp"][:] == data
    @test eltype(ds["temp"].var) == Int32
    @test ds.dim["lon"] == sz[1]
    @test ds.dim["lat"] == sz[2]

    # load in-place
    data2 = similar(data)
    NCDatasets.load!(ds["temp"].var,data2,:,:)
    @test data2 == data

    data2 = zeros(eltype(data),sz[1],2)
    NCDatasets.load!(ds["temp"].var,data2,:,1:2)
    @test data2 == data[:,1:2]

    data2 = zeros(eltype(data),sz[1],1)
    NCDatasets.load!(ds["temp"].var,data2,:,1)
    @test data2[:] == data[:,1]

    # test Union{Missing,T}
    defVar(ds,"foo",[missing,1.,2.],("dim",), fillvalue = -9999.)
    @test fillvalue(ds["foo"]) == -9999.
    @test isequal(ds["foo"][:], [missing,1.,2.])

    # test Union{Missing,T} and default fill value (issue #38)
    defVar(ds,"foo_default_fill_value",[missing,1.,2.],("dim",))
    @test fillvalue(ds["foo_default_fill_value"]) == fillvalue(Float64)
    @test isequal(ds["foo_default_fill_value"][:], [missing,1.,2.])

    for DT in [DateTime,
               DateTimeStandard,
               DateTimeJulian,
               DateTimeProlepticGregorian,
               DateTimeAllLeap,
               DateTimeNoLeap,
               DateTime360Day
               ]

        # test DateTime et al., array
        data_dt = [DT(2000,1,1),DT(2000,1,2),DT(2000,1,3)]
        defVar(ds,"foo_$(DT)",data_dt,("dim",))
        data_dt2 = ds["foo_$(DT)"][:]
        @test isequal(convert.(DT,data_dt2), data_dt)

        # test DateTime et al. with missing array
        data_dt = [missing,DT(2000,1,2),DT(2000,1,3)]
        defVar(ds,"foo_$(DT)_with_fill_value",data_dt,("dim",))

        data_dt2 = ds["foo_$(DT)_with_fill_value"][:]
        @test ismissing(data_dt2[1])

        @test isequal(convert.(DT,data_dt2[2:end]), data_dt[2:end])
    end

    defVar(ds,"scalar",123.)
    @test ds["scalar"][:] == 123.

    # test indexing with symbols #101
    @test ds[:scalar][:] == 123.
end
rm(filename)

# check bounds error
filename = tempname()
NCDataset(filename,"c") do ds
    defVar(ds,"temp",randn(10,11),("lon","lat"))
    @test_throws NCDatasets.NetCDFError defVar(ds,"salt",randn(10,12),("lon","lat"))
end
rm(filename)

# check error for unknown variable
filename = tempname()
NCDataset(filename,"c") do ds
    @test_throws NCDatasets.NetCDFError ds["does_not_exist"]
end
rm(filename)

# issue 23
# return type using CartesianIndex

filename = tempname()
ds = NCDataset(filename, "c");
ds.dim["lon"] = 5;
ds.dim["lat"] = 10;
ds.dim["time"] = Inf;

ncvar = defVar(ds, "var", Int64, ("lon", "lat", "time"));

nt = 25;
data = reshape(1:5*10*nt, 5, 10, nt);
ncvar[:,:,1:nt] = data;
close(ds);

ds = NCDataset(filename);
start = 1;
all(data[CartesianIndex(1, 1), start:end] .== ds["var"][CartesianIndex(1, 1), start:end])
data11 = ds["var"][CartesianIndex(1, 1), start:end]
close(ds)

@test typeof(data11[1]) == Int64
rm(filename)

# issue #36

x, y = collect(1:10), collect(10:18)

NCDataset("temp1.nc", "c") do ds
      defDim(ds, "x", length(x))
      defVar(ds, "x", x, ("x",))
      defDim(ds, "y", length(y))
      defVar(ds, "y", y, ("y",))
end

rm("temp1.nc")


text:
abstract type PotentialParameters end

struct LennardJonesParameters{pType <: Real} <: PotentialParameters
    ϵ::pType
    σ::pType
    R::pType
    σ2::pType
    R2::pType
end

function LennardJonesParameters(ϵ::Real, σ::Real, R::Real)
    LennardJonesParameters(ϵ, σ, R, σ^2, R^2)
end

function LennardJonesParameters()
    LennardJonesParameters(1.0, 1.0, 2.5)
end

function Base.show(stream::IO, pp::LennardJonesParameters)
    println(stream, "Lennard-Jones:")
    print(stream, "\tϵ:"); show(stream, pp.ϵ); println(stream)
    print(stream, "\tσ:"); show(stream, pp.σ); println(stream)
    print(stream, "\tR:"); show(stream, pp.R); println(stream)
end

struct GravitationalParameters{gType <: Real} <: PotentialParameters
    G::gType
end

function GravitationalParameters()
    GravitationalParameters(6.67408e-11)
end

function Base.show(stream::IO, pp::GravitationalParameters)
    println(stream, "Gravitational:")
    print(stream, "\tG:"); show(stream, pp.G);
    println(stream)
end

struct ElectrostaticParameters{pType <: Real} <: PotentialParameters
    k::pType
    R::pType
    R2::pType
end

function ElectrostaticParameters()
    ElectrostaticParameters(9e9, Inf, Inf)
end

function ElectrostaticParameters(k::Real)
    ElectrostaticParameters(k, Inf, Inf)
end

function ElectrostaticParameters(k::Real, R::Real)
    ElectrostaticParameters(k, R, R^2)
end

function Base.show(stream::IO, pp::ElectrostaticParameters)
    println(stream, "Electrostatic:")
    print(stream, "\tk:"); show(stream, pp.k);
    println(stream)
end

struct MagnetostaticParameters{mType <: Real} <: PotentialParameters
    μ_4π::mType
end

function MagnetostaticParameters()
    MagnetostaticParameters(1e-7)
end

function Base.show(stream::IO, pp::MagnetostaticParameters)
    println(stream, "Magnetostatic:")
    print(stream, "\tμ/4π:"); show(stream, pp.μ_4π);
    println(stream)
end

struct SPCFwParameters{pType <: Real} <: PotentialParameters
    rOH::pType
    aHOH::pType
    kb::pType
    ka::pType
end

function pairwise_lennard_jones_acceleration!(dv,
    rs,
    i::Integer,
    indxs::Vector{<:Integer},
    ms::Vector{<:Real},
    p::LennardJonesParameters,
    pbc::BoundaryConditions)

    force = @SVector [0.0, 0.0, 0.0];
    ri = @SVector [rs[1, i], rs[2, i], rs[3, i]]

    for j ∈ indxs
        if j != i
            rj = @SVector [rs[1, j], rs[2, j], rs[3, j]]
            (rij, r, rij_2) = get_interparticle_distance(ri, rj, pbc)

            if rij_2 < p.R2
                σ_rij_6 = (p.σ2 / rij_2)^3
                σ_rij_12 = σ_rij_6^2
                force += (2 * σ_rij_12 - σ_rij_6 ) * rij / rij_2
            end
        end
    end
    @. dv +=  24 * p.ϵ * force / ms[i]
end

function compute_pair_force(ri::SVector{3,T}, rj::SVector{3,T}, pbc::BoundaryConditions, p::PotentialParameters, data...) where T
    error("Force computation for potential $p not implemented yet.")
end

function compute_pair_force(ri::SVector{3,T}, rj::SVector{3,T}, pbc::BoundaryConditions, p::LennardJonesParameters, data...) where T
    # NOTE: ensuring that i!=j is the responsibility of the caller
    (rij, r, rij_2) = get_interparticle_distance(ri, rj, pbc)
    if rij_2 < p.R2
        σ_rij_6 = (p.σ2 / rij_2)^3
        σ_rij_12 = σ_rij_6^2
        force = (2*σ_rij_12 - σ_rij_6) * rij / rij_2 # NOTE: optimize this?
    end
    24 * p.ϵ * force
end

function pairwise_electrostatic_acceleration!(dv,
    rs,
    i::Integer,
    n::Integer,
    qs::Vector{<:Real},
    ms::Vector{<:Real},
    exclude::Dict{Int, Vector{Int}},
    p::ElectrostaticParameters,
    pbc::BoundaryConditions)

    force = @SVector [0.0, 0.0, 0.0]
    ri = @SVector [rs[1, i], rs[2, i], rs[3, i]]
    @inbounds for j = 1:n
        if !in(j, exclude[i])
            rj = @SVector [rs[1, j], rs[2, j], rs[3, j]]
            rij, r, r2 = get_interparticle_distance(ri, rj, pbc)
            if r2 < p.R2
                force += qs[j] * rij / (r*r2)
            end
        end
    end
    @. dv += p.k * qs[i] * force / ms[i]
end

function compute_pair_force(ri::SVector{3,T}, rj::SVector{3,T}, pbc::BoundaryConditions, p::ElectrostaticParameters, qi::T, qj::T) where T
    # NOTE: ensuring that i!=j and !in(j, exclude[i]) is the responsibility of the caller
    (rij, r, r2) = get_interparticle_distance(ri, rj, pbc)
    if r2 < p.R2
        force += qj * rij / (r*r2)
    end
    p.k * qi * force
end

function gravitational_acceleration!(dv,
    rs,
    i::Integer,
    n::Integer,
    bodies::Vector{<:MassBody},
    p::GravitationalParameters)

    accel = @SVector [0.0, 0.0, 0.0];
    ri = @SVector [rs[1, i], rs[2, i], rs[3, i]]
    @inbounds for j = 1:n
        if j != i
            rj = @SVector [rs[1, j], rs[2, j], rs[3, j]]
            rij = ri - rj
            accel -= p.G * bodies[j].m * rij / norm(rij)^3
        end
    end

    @. dv += accel
end

function magnetostatic_dipdip_acceleration!(dv,
    rs,
    i::Integer,
    n::Integer,
    bodies::Vector{<:MagneticParticle},
    p::MagnetostaticParameters)

    force = @SVector [0.0, 0.0, 0.0];
    mi = bodies[i].mm
    ri = @SVector [rs[1, i], rs[2, i], rs[3, i]]
    @inbounds for j = 1:n
        if j != i
            mj = bodies[j].mm
            rj = @SVector [rs[1, j], rs[2, j], rs[3, j]]
            rij = ri - rj
            rij4 = dot(rij, rij)^2
            r =  rij / norm(rij)
            mir = dot(mi, r)
            mij = dot(mj, r)
            force += (mi * mij + mj * mir + r * dot(mi, mj) - 5 * r * mir * mij) / rij4
        end
    end

    @. dv += 3 * p.μ_4π * force / bodies[i].m
end

function harmonic_bond_potential_acceleration!(dv,
    rs,
    i::Integer,
    ms::Vector{<:Real},
    neighbouhoods::Dict{Int,Vector{Tuple{Int,Float64}}},
    p::SPCFwParameters)

    force = @SVector [0.0, 0.0, 0.0];
    ri = @SVector [rs[1, i], rs[2, i], rs[3, i]]
    @inbounds for (j, k) in neighbouhoods[i]
        rj = @SVector [rs[1, j], rs[2, j], rs[3, j]]
        rij = ri - rj
        r = norm(rij)
        d = r - p.rOH
        force -= d * k * rij / r
    end

    @. dv += force / ms[i]
end

function valence_angle_potential_acceleration!(dv,
    rs,
    a::Integer,
    b::Integer,
    c::Integer,
    ms::Vector{<:Real},
    p::SPCFwParameters)
    ra = @SVector [rs[1, a], rs[2, a], rs[3, a]]
    rb = @SVector [rs[1, b], rs[2, b], rs[3, b]]
    rc = @SVector [rs[1, c], rs[2, c], rs[3, c]]

    rba = ra - rb
    rbc = rc - rb
    rcb = rb - rc

    rbaXbc = cross(rba, rbc)
    pa = normalize(cross(rba, rbaXbc))
    pc = normalize(cross(rcb, rbaXbc))

    cosine = dot(rba, rbc) / (norm(rba) * norm(rbc))

    if cosine>1
        cosine = 1
    elseif cosine<-1
        cosine =-1
    end
    aHOH = acos(cosine)

    force = - p.ka * (aHOH - p.aHOH)
    force_a = pa * force / norm(rba)
    force_c = pc * force / norm(rbc)
    force_b = -(force_a + force_c)

    @. dv[:,a] += force_a / ms[a]
    @. dv[:,b] += force_b / ms[b]
    @. dv[:,c] += force_c / ms[c]
end


text:
# Fannie Mae

# download("http://rapidsai-data.s3-website.us-east-2.amazonaws.com/notebook-mortgage-data/mortgage_2000-2007.tgz", "c:/data/mortgage_2000-2007.tgz")

# un-tar and uncompress the file
# ;tar zxvg mortgage_2000-2007.tgz

# uncomment for debugging
dirpath = "C:/data/perf/"
largest_file = "Performance_2004Q3.txt"
outpath = "c:/data/jdf-bench/Performance_2004Q3.txt"
data_label =  "Fannie Mae Performance 2004Q3"
# delim = ','
# header = true

include("C:/Users/RTX2080/git/JDF/benchmarks/benchmarks.jl")
#@timegen_benchmark("c:/data/AirOnTimeCSV/", "airOT199302.csv", "c:/data/jdf-bench/airOT199302.csv", "Air On Time 199302")
@time res = gen_benchmark(dirpath, largest_file, outpath, data_label, delim = '|', header = false);

write_perf = res[1]
read_perf = res[2]
pkgs = repeat(["JDF.jl", "CSV.jl", "Feather.jl", "data.table", "fst", "parquet R"], inner = 2)
run_group = repeat(["1st", "2nd"], outer = 6)

write_perf = write_perf[pkgs .!= "Feather.jl"]
run_group = run_group[pkgs .!= "Feather.jl"]
pkgs1 = pkgs[pkgs .!= "Feather.jl"]

plot_write = groupedbar(
    pkgs1,
    write_perf,
    group = run_group,
    ylab = "Seconds",
    title = "Disk-format Write performance comparison \n Julia $(VERSION)"
)
savefig(plot_write, joinpath(outpath, largest_file*"plot_write_less.png"))

pkgs = repeat(["JDF.jl", "CSV.jl", "Feather.jl", "data.table", "fst", "parquet R"], inner = 2)
run_group = repeat(["1st", "2nd"], outer = 6)
read_perf = read_perf[.!in.(pkgs, Ref(["CSV.jl", "parqeut R"]))]
run_group = run_group[.!in.(pkgs, Ref(["CSV.jl", "parqeut R"]))]
pkgs2 = pkgs[.!in.(pkgs, Ref(["CSV.jl", "parqeut R"]))]

plot_read = groupedbar(
    pkgs2,
    read_perf,
    group = run_group,
    ylab = "Seconds",
    title = "Disk-format Read performance comparison \n Julia $(VERSION)"
)
savefig(plot_read, joinpath(outpath, largest_file*"plot_read_less.png"))

write_perf = res[1]
read_perf = res[2]
pkgs = repeat(["JDF.jl", "CSV.jl", "Feather.jl", "data.table", "fst", "parquet R"], inner = 2)
run_group = repeat(["1st", "2nd"], outer = 6)

write_perf = write_perf[pkgs .!= "Feather.jl"]
run_group = run_group[pkgs .!= "Feather.jl"]
pkgs1 = pkgs[pkgs .!= "Feather.jl"]

plot_write = groupedbar(
    pkgs1,
    write_perf,
    group = run_group,
    ylab = "Seconds",
    title = "Disk-format Write performance comparison \n Julia $(VERSION)"
)
savefig(plot_write, joinpath(outpath, largest_file*"plot_write_less.png"))

pkgs = repeat(["JDF.jl", "CSV.jl", "Feather.jl", "data.table", "fst", "parquet R"], inner = 2)
run_group = repeat(["1st", "2nd"], outer = 6)
read_perf = read_perf[.!in.(pkgs, Ref(["CSV.jl", "parqeut R"]))]
run_group = run_group[.!in.(pkgs, Ref(["CSV.jl", "parqeut R"]))]
pkgs2 = pkgs[.!in.(pkgs, Ref(["CSV.jl", "parqeut R"]))]

plot_read = groupedbar(
    pkgs2,
    read_perf,
    group = run_group,
    ylab = "Seconds",
    title = "Disk-format Read performance comparison \n Julia $(VERSION)"
)
savefig(plot_read, joinpath(outpath, largest_file*"plot_read_less.png"))

sizedf = sum_file_size(outpath)

using StatsPlots

p = plot(
    sizedf.pkg,
    sizedf.fs/1024^3,
    linetype = :bar,
    ylab = "Size (GB)",
    legend = false,
    title = "On-disk file Size for various formats\n $data_label data")
savefig(p, joinpath(outpath, largest_file*"_filesize.png"))


text:
using Plots, Statistics, LinearAlgebra
using Flux, DiffEqFlux, StochasticDiffEq, DiffEqBase.EnsembleAnalysis
using FileIO, Serialization
using Distributions
using Optim
# don't call this function unless you really want to. Expensive.
# function generateTrueData(u0, tspan, tsteps, numTrajectories)
function generateTrueData(u0, tspan, tsteps, outputPath)

    numTrajectories = size(u0)[2];

    function trueDriftFunc(du, u, p, t)
        ρ = reshape(u[1:9],(3,3));
        M = reshape(u[10:18],(3,3));
        k = inv(ρ);
        Π = (k*k')/tr(k*k');
        placeHolder = [(M'*ρ); (-M^2 + tr(M^2)*Π)];
        du .= [reshape(placeHolder[1:3,1:3],9); reshape(placeHolder[4:6,1:3],9)] #du/dt = [ dρdt; dMdt]
    end

    function prob_func(prob, i, repeat)
        remake(prob,u0=u0[:,i]);
    end

    trueOdeProb = ODEProblem(trueDriftFunc, u0[:,1], tspan);

    ensembleProb = EnsembleProblem(trueOdeProb,
                                   prob_func = prob_func);#start each new problem with a different initial conditions

    #ensembleSol = solve(ensembleProb, SOSRI(), trajectories = numTrajectories);
    @time ensembleSol = solve(ensembleProb, Tsit5(), tstops = tsteps, trajectories = numTrajectories, saveat = tsteps);

    #return Array.(timeseries_point_meanvar(ensembleSol, tsteps));
    #save(ensembleSol,"/groups/chertkov/cmhyett/PureModelData/LearningTetrad/finalState.dat")
    #serialize("/groups/chertkov/cmhyett/PureModelData/LearningTetrad/trainingData.dat", ensembleSol)
    serialize(outputPath, ensembleSol);
    return ensembleSol;
end

max_stars_repo_name: cmhyett/MLCoarseGrainedVGT

max_issues_repo_name: cmhyett/MLCoarseGrainedVGT

max_forks_repo_name: cmhyett/MLCoarseGrainedVGT


text:
#=

  Computes f(x,y) for each entry

=#
export ComponentWiseBiFunction

type ComponentWiseBiFunction{D<:Device, F<:Float} <: Layer
  output::denseRealMatrix(D,F)
  left_gradient::denseRealMatrix(D,F)
  right_gradient::denseRealMatrix(D,F)

  ComponentWiseBiFunction() = new(array(device, F, 0, 0), array(device, F, 0, 0))
end

function forward!{D<:Device, F<:Float}(linear::ComponentWiseBiFunction{D,F}, x::DenseMatrix, y::DenseMatrix)
    @assert size(x) == size(y)
    @ensuresize
end

function compute_inputgradient!{D<:Device, F<:Float}(linear::ComponentWiseBiFunction{D,F}, input::DenseMatrix, gradOutput::DenseMatrix)
  @ensuresize linear.input_gradient, (size(gradOutput,1), size(linear.weight.values, 1))

  gemm!('N', 'T', 1., gradOutput, linear.weight.values, 0., linear.input_gradient)
end


text:
using Thesis
using Test

@testset "Thesis.jl" begin
    # Write your own tests here.
end


text:
"""
    Cropbox

Declarative crop modeling framework. https://github.com/cropbox/Cropbox.jl

See also: [`@system`](@ref), [`@config`](@ref), [`simulate`](@ref), [`evaluate`](@ref), [`calibrate`](@ref), [`visualize`](@ref), [`manipulate`](@ref)
"""
module Cropbox

include("system.jl")
include("unit.jl")
include("random.jl")
include("graph.jl")
include("macro.jl")
include("state.jl")
include("bundle.jl")
include("config.jl")

include("system/clock.jl")
include("system/context.jl")
include("system/controller.jl")
include("system/calendar.jl")
include("system/store.jl")
include("system/thermaltime.jl")

include("util/simulate.jl")
include("util/calibrate.jl")
include("util/evaluate.jl")
include("util/gather.jl")
include("util/color.jl")
include("util/dive.jl")
include("util/hierarchy.jl")
include("util/plot.jl")
include("util/visualize.jl")
include("util/manipulate.jl")

end


text:
module day5

using LinearAlgebra: dot
readInput() = readlines(joinpath(@__DIR__, "input.txt"))

function decode(s, low, high)
    for char in s
        if char == 'F' || char == 'L'
            high = (high + low) ÷ 2
        else
            low = (high + low) ÷ 2 + 1
        end
    end
    @assert low == high
    low
end

function decode(s)
    row = decode(view(s, 1:7), 0, 127)
    col = decode(view(s, 8:10), 0, 7)
    row, col
end

part1(input) = mapreduce(s -> dot(decode(s), (8,1)), max, input)

function part2(input)
    ids = sort!(map(s -> dot(decode(s), (8,1)), input))
    for i = 1:length(ids) - 1
        ids[i] + 1 != ids[i+1] && return ids[i] + 1
    end
end

end


text:
using Test, DocumentationGenerator
using Pkg

const julia = first(Base.julia_cmd())

@test length(keys(DocumentationGenerator.installable_on_version())) > 1500

@test DocumentationGenerator.maybe_redirect("https://docs.julialang.org/") == "https://docs.julialang.org/en/v1"

@testset "Running code with a timeout" begin
    let
        tempfile = tempname()
        str = """
        sleep(4)
        sleep(4)
        write("$tempfile", "hi")
        sleep(3)
        """
        proc, _ = DocumentationGenerator.run_with_timeout(`$julia -e $str`, timeout=7)
        wait(proc)
        @test !success(proc)
        @test !isfile(tempfile)
    end

    let
        tempfile = tempname()
        str = """
        for i = 1:10
        sleep(1)
        println(i)
        end
        write("$tempfile", "hi")
        """
        proc, _ = DocumentationGenerator.run_with_timeout(`$julia -e $str`, timeout=6)
        wait(proc)
        @test success(proc)
        @test String(read(tempfile)) == "hi"
    end

    let
        tempfile = tempname()
        logfile = tempname()
        str = """
        for i in 1:10
        println(i)
        sleep(1)
        end
        write("$tempfile", "hi")
        """
        proc, task = DocumentationGenerator.run_with_timeout(`$julia -e $str`, timeout=3, log=logfile)
        wait(proc)
        @test success(proc)
        @test String(read(tempfile)) == "hi"
        logstr = ""
        for i in 1:10
            logstr *= "$i"
        end
        wait(task)
        @test isfile(logfile)
        @test replace(String(read(logfile)), '\n' => "") == logstr
    end
end

@testset "Readme rendering" begin
    DocumentationGenerator.render_html(joinpath(@__DIR__, "fixtures", "readme.md"), joinpath(@__DIR__, "readme.html"), "/foo/", "/bar/")

    @test read(joinpath(@__DIR__, "fixtures", "readme.html"), String) == read(joinpath(@__DIR__, "readme.html"), String)
end

@testset "Documentation Generation" begin
    packages = [
        # without docs
        (
            name = "FixedPointNumbers",
            uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93",
            url = "https://github.com/JuliaMath/FixedPointNumbers.jl.git",
            versions = [v"0.8.4"],
            installs = [true],
            success = [true],
            doctype = ["fallback_autodocs"],
        ),
        (
            name = "ReactionNetworkImporters",
            url = "https://github.com/isaacsas/ReactionNetworkImporters.jl.git",
            uuid = "b4db0fb7-de2a-5028-82bf-5021f5cfa881",
            versions = [v"0.7.0"],
            installs = [true],
            success = [true],
            doctype = ["fallback_autodocs"],
        ),
        # with docs
        (
            name = "Example",
            url = "https://github.com/JuliaLang/Example.jl.git",
            uuid = "7876af07-990d-54b4-ab0e-23690620f79a",
            versions = [v"0.5.1", v"0.5.3"],
            installs = [true, true],
            success = [true, true],
            doctype = ["fallback_autodocs", "documenter"],
        ),
        (
            name = "DynamicHMC",
            url = "https://github.com/tpapp/DynamicHMC.jl.git",
            uuid = "bbc10e6e-7c05-544b-b16e-64fede858acb",
            versions = [v"3.1.0"],
            installs = [true],
            success = [true],
            doctype = ["documenter"],
        ),
        (
            name = "jlpkg",
            url = "https://github.com/fredrikekre/jlpkg",
            uuid = "c4c688b2-6cc8-11e9-1c12-6d20b663313d",
            versions = [v"1.3.2"],
            installs = [true],
            success = [true],
            doctype = ["fallback_autodocs"],
        ),
        # with hosted docs
        (
            name = "Juno",
            url = "https://github.com/JunoLab/Juno.jl.git",
            uuid = "e5e0dc1b-0480-54bc-9374-aad01c23163d",
            versions = [v"0.7.0"],
            installs = ["missing"],
            success = [true],
            hosted_uri = ["https://docs.junolab.org/latest"],
            doctype = ["hosted"]
        ),
        # Julia
        (
            name = "julia",
            url = "https://github.com/JuliaLang/julia",
            uuid = "1222c4b2-2114-5bfd-aeef-88e4692bbb3e",
            versions = [v"1.2.0", v"1.3.0", v"1.4.1", v"1.5.3"],
            installs = ["missing", "missing", "missing", "missing"],
            hosted_uri = ["https://docs.julialang.org/en/v1", "https://docs.julialang.org/en/v1", "https://docs.julialang.org/en/v1", "https://docs.julialang.org/en/v1"],
            success = [true, true, true, true],
            doctype = ["hosted", "hosted", "hosted", "hosted"]
        ),
        # git-dir docs
        (
            name = "Phylo",
            url = "https://github.com/richardreeve/Phylo.jl.git",
            uuid = "aea672f4-3940-5932-aa44-993d1c3ff149",
            versions = [v"0.4.19"],
            installs = [true],
            success = [true],
            doctype = ["documenter"],
        ),
        (
            name = "OpenSpiel_jll",
            url = "https://github.com/JuliaBinaryWrappers/OpenSpiel_jll.jl.git",
            uuid = "bd10a763-4654-5023-a028-c4918c6cd33e",
            versions = [v"0.3.6+0"],
            installs = [true],
            success = [true],
            doctype = ["fallback_autodocs"],
        ),
        (
            name = "TSVD",
            url = "https://github.com/JuliaLinearAlgebra/TSVD.jl.git",
            uuid = "9449cd9e-2762-5aa3-a617-5413e99d722e",
            versions = [v"0.4.2"],
            installs = [true],
            success = [true],
            doctype = ["documenter"],
        ),
        (
            name = "Crayons",
            url = "https://github.com/KristofferC/Crayons.jl.git",
            uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f",
            versions = [v"4.0.1"],
            installs = [true],
            success = [true],
            doctype = ["fallback_autodocs"],
        ),
        # make sure xvfb-run works:
        (
            name = "Tk",
            url = "https://github.com/JuliaGraphics/Tk.jl.git",
            uuid = "4225ea8a-3324-57e7-9ddc-5798a2cb9eab",
            versions = [v"0.7.0"],
            installs = [true],
            success = [true],
            doctype = ["documenter"],
            using_failed = [false]
        ),
        (
            name = "Zygote",
            url = "https://github.com/FluxML/Zygote.jl.git",
            uuid = "e88e6eb3-aa80-5325-afca-941959d7151f",
            versions = [v"0.6.10"],
            installs = [true],
            success = [true],
            doctype = ["documenter"],
            using_failed = [false]
        ),
        (
            name = "IntelGEMM",
            url = "https://github.com/AStupidBear/IntelGEMM.jl.git",
            uuid = "46a1a280-e6c3-11e9-0321-d12035ae5ac9",
            versions = [v"0.1.1"],
            installs = [true],
            success = [true],
            doctype = ["fallback_autodocs"],
            using_failed = [false]
        ),
        (
            name = "MethodAnalysis",
            url = "https://github.com/timholy/MethodAnalysis.jl.git",
            uuid = "85b6ec6f-f7df-4429-9514-a64bcd9ee824",
            versions = [v"0.4.4"],
            installs = [true],
            success = [true],
            doctype = ["documenter"],
            using_failed = [false]
        ),
        (
            name = "Octo",
            url = "https://github.com/wookay/Octo.jl.git",
            uuid = "16905944-f982-529b-abb2-b839f98f160b",
            versions = [v"0.2.9"],
            installs = [true],
            success = [true],
            doctype = ["documenter"],
            using_failed = [false]
        ),
        (
            name = "Electron",
            url = "https://github.com/davidanthoff/Electron.jl.git",
            uuid = "a1bb12fb-d4d1-54b4-b10a-ee7951ef7ad3",
            versions = [v"3.1.2"],
            installs = [true],
            success = [true],
            doctype = ["fallback_autodocs"],
            using_failed = [false]
        )
    ]

    basepath = @__DIR__
    rm(joinpath(basepath, "build"), force = true, recursive = true)

    DocumentationGenerator.build_documentation(
        packages, basepath = basepath, filter_versions = identity, processes = 6
    )

    build = joinpath(basepath, "build")
    @testset "build folder" begin
        for pkg in packages
            pkgbuild = joinpath(build, DocumentationGenerator.get_docs_dir(pkg.name, pkg.uuid))
            @test isdir(pkgbuild)
            @testset "$(pkg.name): $(version)" for (i, version) in enumerate(pkg.versions)
                log = joinpath(pkgbuild, "$(version).log")
                @test isfile(log)

                println("\n---- LOG $(pkg.name)@$(version) START ----\n")
                println(read(log, String))
                println("\n---- LOG $(pkg.name)@$(version) END ----\n")

                versiondir = joinpath(pkgbuild, string(version))
                @test isdir(versiondir)
                toml_path = joinpath(versiondir, "meta.toml")
                @test isfile(toml_path)
                if isfile(toml_path)
                    toml = Pkg.TOML.parsefile(toml_path)
                    pkginstalls = get(toml, "installable", false)
                    pkgsuccess = get(toml, "success", false)
                    pkgdoctype = get(toml, "doctype", "")
                    @test pkginstalls == pkg.installs[i]
                    @test pkgsuccess == pkg.success[i]
                    @test pkgdoctype == pkg.doctype[i]

                    if pkg.doctype[i] == "hosted"
                        @test get(toml, "hosted_uri", "") == pkg.hosted_uri[i]
                    end

                    if pkginstalls == true
                        doctype = get(toml, "doctype", nothing)
                        @test doctype == pkg.doctype[i]
                        @test isfile(joinpath(versiondir, "index.html"))
                        if doctype == "default"
                            @test isdir(joinpath(versiondir, "autodocs"))
                        end

                        if pkg.name !== "IntelGEMM"
                            @test isfile(joinpath(versiondir, "_readme", "readme.html"))
                        end
                        @test !isempty(toml["deps"])
                    end

                    if haskey(pkg, :using_failed)
                        @test pkg.using_failed[i] == toml["using_failed"]
                    end
                end

                if pkg.name == "Crayons"
                    # spot check some of the readme postprocessing
                    readme = read(joinpath(versiondir, "_readme", "readme.html"), String)
                    @test occursin("""src="/docs/Crayons/TXPcU/4.0.1/_packagesource/logo.png" """, readme)
                    @test occursin("""""", readme)
                    @test occursin("""
Installation
""", readme)
                end
            end
        end
    end
end

@testset "Documentation Registry" begin
    mktempdir() do dir
        reg = DocumentationGenerator.get_registry(dir)
        @test isfile(reg)
        toml = Pkg.TOML.parsefile(reg)
        @test length(keys(toml)) > 0
        @test haskey(toml, "e5e0dc1b-0480-54bc-9374-aad01c23163d")
        junosettings = toml["e5e0dc1b-0480-54bc-9374-aad01c23163d"]
        @test junosettings["method"] == "hosted"
    end
end

@testset "GitHub URL rewriting" begin
    @test DocumentationGenerator.github_to_raw("https://github.com/migarstka/COSMO_assets/blob/master/COSMO_logo_only.png") == "https://raw.githubusercontent.com/migarstka/COSMO_assets/master/COSMO_logo_only.png"
    @test DocumentationGenerator.github_to_raw("https://raw.githubusercontent.com/migarstka/COSMO_assets/master/COSMO_logo_only.png") == "https://raw.githubusercontent.com/migarstka/COSMO_assets/master/COSMO_logo_only.png"
    @test DocumentationGenerator.github_to_raw("https://www.github.com/migarstka/COSMO_assets/blob/master/COSMO_logo_only.png") == "https://raw.githubusercontent.com/migarstka/COSMO_assets/master/COSMO_logo_only.png"
    @test DocumentationGenerator.github_to_raw("https://github.com/migarstka/COSMO_assets/master/COSMO_logo_only.png") == "https://github.com/migarstka/COSMO_assets/master/COSMO_logo_only.png"
end


text:
using PenaltyFunctions, Optim, LinearAlgebra

cost_function_1 = build_loss_objective(prob1,Tsit5(),L2Loss(t,data),
                   Regularization(0.6,L2Penalty()),maxiters=10000,verbose=false,abstol=1e-8,reltol=1e-8)
cost_function_2 = build_loss_objective(prob2,Tsit5(),L2Loss(t,data),verbose=false,abstol=1e-8,reltol=1e-8,
                   Regularization(0.1,MahalanobisPenalty(Matrix(1.0I, 2, 2))),maxiters=10000)
cost_function_3 = build_loss_objective(prob3,Tsit5(),L2Loss(t,data),verbose=false,abstol=1e-8,reltol=1e-8,
                   Regularization(0.1,MahalanobisPenalty(Matrix(1.0I, 4, 4))),maxiters=10000)

println("Use Optim BFGS to fit the parameter")
result = Optim.optimize(cost_function_1, [1.0], Optim.BFGS())
@test result.minimizer[1] ≈ 1.5 atol=3e-1

result_bfgs = Optim.optimize(cost_function_2, [1.2,2.7], Optim.BFGS())
@test result_bfgs.minimizer ≈ [1.5;3.0] atol=3e-1

result_bfgs = Optim.optimize(cost_function_3, [1.3,0.8,2.8,1.2], Optim.BFGS())
@test result_bfgs.minimizer ≈ [1.5;1.0;3.0;1.0] atol=5e-1