text:
__precompile__(true)

"""
Main module for `Documenter.jl` -- a documentation generation package for Julia.

Two functions are exported from this module for public use:

- [`makedocs`](@ref). Generates documentation from docstrings and templated markdown files.
- [`deploydocs`](@ref). Deploys generated documentation from *Travis-CI* to *GitHub Pages*.

Additionally it provides the unexported [`Documenter.generate`](@ref), which can be used to
generate documentation stubs for new packages.

$(EXPORTS)

"""
module Documenter

using Compat, DocStringExtensions
import Compat.Base64: base64decode, base64encode
import Compat: @info
import Compat.Pkg

@static if VERSION < v"0.7.0-DEV.3439"
    const IdDict = Base.ObjectIdDict
else
    const IdDict = Base.IdDict{Any,Any}
end

@static if VERSION < v"0.7.0-DEV.3500"
    import Base.REPL
    using Base.REPL: ip_matches_func
else
    import REPL
    using Base: ip_matches_func
end

# Submodules
# ----------

include("Utilities/Utilities.jl")
include("DocSystem.jl")
include("Selectors.jl")
include("Formats.jl")
include("Anchors.jl")
include("Documents.jl")
include("Builder.jl")
include("Expanders.jl")
include("CrossReferences.jl")
include("DocChecks.jl")
include("Writers/Writers.jl")
include("Deps.jl")
include("Generator.jl")
include("Travis.jl")

# User Interface.
# ---------------

export Travis, Deps, makedocs, deploydocs, hide

"""
    makedocs(
        root    = "<current-directory>",
        source  = "src",
        build   = "build",
        clean   = true,
        doctest = true,
        modules = Module[],
        repo    = "",
    )

Combines markdown files and inline docstrings into an interlinked document.
In most cases [`makedocs`](@ref) should be run from a `make.jl` file:

```julia
using Documenter
makedocs(
    # keywords...
)
```

which is then run from the command line with:

```sh
\$ julia make.jl
```

The folder structure that [`makedocs`](@ref) expects looks like:

    docs/
        build/
        src/
        make.jl

# Keywords

**`root`** is the directory from which `makedocs` should run. When run from a `make.jl` file
this keyword does not need to be set. It is, for the most part, needed when repeatedly
running `makedocs` from the Julia REPL like so:

    julia> makedocs(root = Pkg.dir("MyPackage", "docs"))

**`source`** is the directory, relative to `root`, where the markdown source files are read
from. By convention this folder is called `src`. Note that any non-markdown files stored
in `source` are copied over to the build directory when [`makedocs`](@ref) is run.

**`build`** is the directory, relative to `root`, into which generated files and folders are
written when [`makedocs`](@ref) is run. The name of the build directory is, by convention,
called `build`, though, like with `source`, users are free to change this to anything else
to better suit their project needs.

**`clean`** tells [`makedocs`](@ref) whether to remove all the content from the `build`
folder prior to generating new content from `source`. By default this is set to `true`.

**`doctest`** instructs [`makedocs`](@ref) on whether to try to test Julia code blocks
that are encountered in the generated document. By default this keyword is set to `true`.
Doctesting should only ever be disabled when initially setting up a newly developed package
where the developer is just trying to get their package and documentation structure correct.
After that, it's encouraged to always make sure that documentation examples are runnable and
produce the expected results. See the [Doctests](@ref) manual section for details about
running doctests.

**`modules`** specifies a vector of modules that should be documented in `source`. If any
inline docstrings from those modules are seen to be missing from the generated content then
a warning will be printed during execution of [`makedocs`](@ref). By default no modules are
passed to `modules` and so no warnings will appear. This setting can be used as an indicator
of the "coverage" of the generated documentation.
For example Documenter's `make.jl` file contains:

```julia
makedocs(
    modules = [Documenter],
    # ...
)
```

and so any docstring from the module `Documenter` that is not spliced into the generated
documentation in `build` will raise a warning.

**`repo`** specifies a template for the "link to source" feature. If you are
using GitHub, this is automatically generated from the remote. If you are using
a different host, you can use this option to tell Documenter how URLs should be
generated. The following placeholders will be replaced with the respective
value of the generated link:

  - `{commit}` Git branch or tag name, or commit hash
  - `{path}` Path to the file in the repository
  - `{line}` Line (or range of lines) in the source file

For example if you are using GitLab.com, you could use

```julia
makedocs(repo = \"https://gitlab.com/user/project/blob/{commit}{path}#{line}\")
```

# Experimental keywords

In addition to standard arguments there is a set of non-finalized experimental keyword
arguments. The behaviour of these may change or they may be removed without deprecation
when a minor version changes (i.e. except in patch releases).

**`checkdocs`** instructs [`makedocs`](@ref) to check whether all names within the modules
defined in the `modules` keyword that have a docstring attached have the docstring also
listed in the manual (e.g. there's a `@docs` blocks with that docstring). Possible values
are `:all` (check all names) and `:exports` (check only exported names). The default value
is `:none`, in which case no checks are performed. If `strict` is also enabled then the
build will fail if any missing docstrings are encountered.

**`linkcheck`** -- if set to `true` [`makedocs`](@ref) uses `curl` to check the status codes
of external-pointing links, to make sure that they are up-to-date. The links and their
status codes are printed to the standard output. If `strict` is also enabled then the build
will fail if there are any broken (400+ status code) links. Default: `false`.

**`linkcheck_ignore`** allows certain URLs to be ignored in `linkcheck`. The values should
be a list of strings (which get matched exactly) or `Regex` objects. By default nothing is
ignored.

**`strict`** -- [`makedocs`](@ref) fails the build right before rendering if it encountered
any errors with the document in the previous build phases.

## Non-MkDocs builds

Documenter also has (experimental) support for native HTML and LaTeX builds.
These can be enabled using the `format` keyword and they generally require additional
keywords be defined, depending on the format. These keywords are also currently considered
experimental.

**`format`** allows the output format to be specified. Possible values are `:html`, `:latex`
and `:markdown` (default).

Other keywords related to non-MkDocs builds (**`assets`**, **`sitename`**, **`analytics`**,
**`authors`**, **`pages`**, **`version`**) should be documented at the respective `*Writer`
modules ([`Writers.HTMLWriter`](@ref), [`Writers.LaTeXWriter`](@ref)).

# See Also

A guide detailing how to document a package using Documenter's [`makedocs`](@ref) is provided
in the [Usage](@ref) section of the manual.
"""
function makedocs(; debug = false, args...)
    document = Documents.Document(; args...)
    cd(document.user.root) do
        Selectors.dispatch(Builder.DocumentPipeline, document)
    end
    debug ? document : nothing
end

"""
$(SIGNATURES)

Allows a page to be hidden in the navigation menu. It will only show up if it happens to be
the current page. The hidden page will still be present in the linear page list that can be
accessed via the previous and next page links. The title of the hidden page can be overriden
using the `=>` operator as usual.

# Usage

```julia
makedocs(
    ...,
    pages = [
        ...,
        hide("page1.md"),
        hide("Title" => "page2.md")
    ]
)
```
"""
hide(page::Pair) = (false, page.first, page.second, [])
hide(page::AbstractString) = (false, nothing, page, [])

"""
$(SIGNATURES)

Allows a subsection of pages to be hidden from the navigation menu. `root` will be linked
to in the navigation menu, with the title determined as usual. `children` should be a list
of pages (note that it **can not** be hierarchical).

# Usage

```julia
makedocs(
    ...,
    pages = [
        ...,
        hide("Hidden section" => "hidden_index.md", [
            "hidden1.md",
            "Hidden 2" => "hidden2.md"
        ]),
        hide("hidden_index.md", [...])
    ]
)
```
"""
hide(root::Pair, children) = (true, root.first, root.second, map(hide, children))
hide(root::AbstractString, children) = (true, nothing, root, map(hide, children))

"""
    deploydocs(
        root   = "<current-directory>",
        target = "site",
        repo   = "<required>",
        branch = "gh-pages",
        latest = "master",
        osname = "linux",
        julia  = "<required>",
        deps   = <Function>,
        make   = <Function>,
    )

Converts markdown files generated by [`makedocs`](@ref) to HTML and pushes them to `repo`.
This function should be called from within a package's `docs/make.jl` file after the call to
[`makedocs`](@ref), like so

```julia
using Documenter, PACKAGE_NAME
makedocs(
    # options...
)
deploydocs(
    repo = "github.com/..."
)
```

# Required keyword arguments

**`julia`** is the version of Julia that will be used to deploy generated documentation.
This value must be one of those specified in the `julia:`
section of the `.travis.yml` configuration file.

**`repo`** is the remote repository where generated HTML content should be pushed to. Do not
specify any protocol - "https://" or "git@" should not be present. This keyword *must*
be set and will throw an error when left undefined. For example this package uses the
following `repo` value:

```julia
repo = "github.com/JuliaDocs/Documenter.jl.git"
```

# Optional keyword arguments

**`root`** has the same purpose as the `root` keyword for [`makedocs`](@ref).

**`target`** is the directory, relative to `root`, where generated HTML content should be
written to. This directory **must** be added to the repository's `.gitignore` file. The
default value is `"site"`.

**`branch`** is the branch where the generated documentation is pushed. If the branch does
not exist, a new orphaned branch is created automatically. It defaults to `"gh-pages"`.

**`latest`** is the branch that "tracks" the latest generated documentation. By default this
value is set to `"master"`.

**`osname`** is the operating system which will be used to deploy generated documentation.
This defaults to `"linux"`. This value must be one of those specified in the `os:` section
of the `.travis.yml` configuration file.

**`deps`** is the function used to install any dependencies needed to build the
documentation. By default this function installs `pygments` and `mkdocs` using the
[`Deps.pip`](@ref) function:

```julia
deps = Deps.pip("pygments", "mkdocs")
```

**`make`** is the function used to convert the markdown files to HTML. By default this just
runs `mkdocs build` which populates the `target` directory.

# See Also

The [Hosting Documentation](@ref) section of the manual provides a step-by-step guide to
using the [`deploydocs`](@ref) function to automatically generate docs and push them to
GitHub.
"""
function deploydocs(;
        root   = Utilities.currentdir(),
        target = "site",
        dirname = "",

        repo   = error("no 'repo' keyword provided."),
        branch = "gh-pages",
        latest = "master",

        osname = "linux",
        julia::Union{AbstractString,Nothing} = nothing,

        deps   = Deps.pip("pygments", "mkdocs"),
        make   = () -> run(`mkdocs build`),
    )
    # deprecation of julia defaulting to "nightly"
    if julia === nothing
        Base.depwarn("""
            `julia` keyword to `Documenter.deploydocs()` not specified.
            In the future `julia` will be a required keyword argument
            instead of defaulting to `"nightly"`.
            """, :deploydocs)
        julia = "nightly"
    end

    # Get environment variables.
    documenter_key      = get(ENV, "DOCUMENTER_KEY",       "")
    travis_branch       = get(ENV, "TRAVIS_BRANCH",        "")
    travis_pull_request = get(ENV, "TRAVIS_PULL_REQUEST",  "")
    travis_repo_slug    = get(ENV, "TRAVIS_REPO_SLUG",     "")
    travis_tag          = get(ENV, "TRAVIS_TAG",           "")
    travis_osname       = get(ENV, "TRAVIS_OS_NAME",       "")
    travis_julia        = get(ENV, "TRAVIS_JULIA_VERSION", "")

    # Other variables.
    sha = cd(root) do
        # We'll make sure we run the git commands in the source directory (root), in case
        # the working directory has been changed (e.g. if the makedocs' build argument is
        # outside root).
        try
            readchomp(`git rev-parse --short HEAD`)
        catch
            # git rev-parse will throw an error and return code 128 if it is not being
            # run in a git repository, which will make run/readchomp throw an exception.
            # We'll assume that if readchomp fails it is due to this and set the sha
            # variable accordingly.
            "(not-git-repo)"
        end
    end

    # Sanity checks
    if !isempty(travis_repo_slug) && !occursin(travis_repo_slug, repo)
        Compat.@warn("repo $repo does not match $travis_repo_slug")
    end

    # When should a deploy be attempted?
    should_deploy =
        occursin(travis_repo_slug, repo) &&
        travis_pull_request == "false"   &&
        travis_osname == osname &&
        travis_julia  == julia  &&
        (
            travis_branch == latest ||
            travis_tag    != ""
        )

    # check that the tag is valid
    if should_deploy && !isempty(travis_tag) && !occursin(Base.VERSION_REGEX, travis_tag)
        Compat.@warn("tag `$(travis_tag)` is not a valid VersionNumber")
        should_deploy = false
    end

    # check DOCUMENTER_KEY only if the branch, Julia version etc. check out
    if should_deploy && isempty(documenter_key)
        Compat.@warn("""
            DOCUMENTER_KEY environment variable missing, unable to deploy.
              Note that in Documenter v0.9.0 old deprecated authentication methods were removed.
              DOCUMENTER_KEY is now the only option. See the documentation for more information.""")
        should_deploy = false
    end

    if get(ENV, "DOCUMENTER_DEBUG", "") == "true"
        Utilities.debug("TRAVIS_REPO_SLUG       = \"$travis_repo_slug\"")
        Utilities.debug("  should match \"$repo\" (kwarg: repo)")
        Utilities.debug("TRAVIS_PULL_REQUEST    = \"$travis_pull_request\"")
        Utilities.debug("  deploying if equal to \"false\"")
        Utilities.debug("TRAVIS_OS_NAME         = \"$travis_osname\"")
        Utilities.debug("  deploying if equal to \"$osname\" (kwarg: osname)")
        Utilities.debug("TRAVIS_JULIA_VERSION   = \"$travis_julia\"")
        Utilities.debug("  deploying if equal to \"$julia\" (kwarg: julia)")
        Utilities.debug("TRAVIS_BRANCH          = \"$travis_branch\"")
        Utilities.debug("TRAVIS_TAG             = \"$travis_tag\"")
        Utilities.debug("  deploying if branch equal to \"$latest\" (kwarg: latest) or tag is set")
        Utilities.debug("git commit SHA         = $sha")
        Utilities.debug("DOCUMENTER_KEY exists  = $(!isempty(documenter_key))")
        Utilities.debug("should_deploy          = $should_deploy")
    end

    if should_deploy
        # Add local bin path if needed.
        Deps.updatepath!()
        # Install dependencies when applicable.
        if deps !== nothing
            Utilities.log("installing dependencies.")
            deps()
        end
        # Change to the root directory and try to deploy the docs.
        cd(root) do
            Utilities.log("setting up target directory.")
            isdir(target) || mkpath(target)
            # Run extra build steps defined in `make` if required.
            if make !== nothing
                Utilities.log("running extra build steps.")
                make()
            end
            Utilities.log("pushing new documentation to remote: $repo:$branch.")
            mktempdir() do temp
                git_push(
                    root, temp, repo;
                    branch=branch, dirname=dirname, target=target,
                    tag=travis_tag, key=documenter_key, sha=sha
                )
            end
        end
    else
        Utilities.log("""
            skipping docs deployment.
              You can set DOCUMENTER_DEBUG to "true" in Travis to see more information.""")
    end
end

"""
    git_push(
        root, tmp, repo;
        branch="gh-pages", dirname="", target="site", tag="", key="", sha=""
    )

Handles pushing changes to the remote documentation branch.
"""
function git_push(
        root, temp, repo;
        branch="gh-pages", dirname="", target="site", tag="", key="", sha=""
    )
    dirname = isempty(dirname) ? temp : joinpath(temp, dirname)
    isdir(dirname) || mkpath(dirname)
    # Versioned docs directories.
    latest_dir = joinpath(dirname, "latest")
    stable_dir = joinpath(dirname, "stable")
    tagged_dir = joinpath(dirname, tag)

    keyfile = abspath(joinpath(root, ".documenter"))
    target_dir = abspath(target)

    # The upstream URL to which we push new content and the ssh decryption commands.
    upstream = "git@$(replace(repo, "github.com/" => "github.com:"))"

    write(keyfile, String(base64decode(key)))
    chmod(keyfile, 0o600)

    try
        # Use a custom SSH config file to avoid overwriting the default user config.
        withfile(joinpath(homedir(), ".ssh", "config"),
            """
            Host github.com
                StrictHostKeyChecking no
                HostName github.com
                IdentityFile $keyfile
            """
        ) do
            cd(temp) do
                # Setup git.
                run(`git init`)
                run(`git config user.name "autodocs"`)
                run(`git config user.email "autodocs"`)

                # Fetch from remote and checkout the branch.
                run(`git remote add upstream $upstream`)
                run(`git fetch upstream`)

                try
                    run(`git checkout -b $branch upstream/$branch`)
                catch e
                    Utilities.log("Checking out $branch failed with error: $e")
                    Utilities.log("Creating a new local $branch branch.")
                    run(`git checkout --orphan $branch`)
                    run(`git commit --allow-empty -m "Initial empty commit for docs"`)
                end

                # Copy docs to `latest`, or `stable`, `<release>`, and `<version>` directories.
                if isempty(tag)
                    gitrm_copy(target_dir, latest_dir)
                    Writers.HTMLWriter.generate_siteinfo_file(latest_dir, "latest")
                else
                    @assert occursin(Base.VERSION_REGEX, tag) # checked in deploydocs
                    version = VersionNumber(tag)
                    # only push to stable if this is the latest stable release
                    versions = filter!(x -> occursin(Base.VERSION_REGEX, x), readdir(dirname))
                    maxver = mapreduce(x -> VersionNumber(x), max, v"0.0.0", versions)
                    if version >= maxver && version.prerelease == () # don't deploy to stable for prereleases
                        gitrm_copy(target_dir, stable_dir)
                        Writers.HTMLWriter.generate_siteinfo_file(stable_dir, "stable")
                    end
                    gitrm_copy(target_dir, tagged_dir)
                    Writers.HTMLWriter.generate_siteinfo_file(tagged_dir, tag)
                    # Build a `release-*.*` folder as well
                    release = "release-$(version.major).$(version.minor)"
                    gitrm_copy(target_dir, joinpath(dirname, release))
                    Writers.HTMLWriter.generate_siteinfo_file(joinpath(dirname, release), release)
                end

                # Create the versions.js file containing a list of all docs
                # versions. This must always happen after the folder copying.
                Writers.HTMLWriter.generate_version_file(dirname)

                # Add, commit, and push the docs to the remote.
                run(`git add -A .`)
                if !success(`git diff --cached --exit-code`)
                    run(`git commit -m "build based on $sha"`)
                    run(`git push -q upstream HEAD:$branch`)
                else
                    Utilities.log("New docs identical to the old -- not committing nor pushing.")
                end
            end
        end
    finally
        # Remove the unencrypted private key.
        isfile(keyfile) && rm(keyfile)
    end
end

"""
    gitrm_copy(src, dst)

Uses `git rm -r` to remove `dst` and then copies `src` to `dst`. Assumes that the working
directory is within the git repository of `dst` is when the function is called.

This is to get around [#507](https://github.com/JuliaDocs/Documenter.jl/issues/507) on
filesystems that are case-insensitive (e.g. on OS X, Windows). Without doing a `git rm`
first, `git add -A` will not detect case changes in filenames.
"""
function gitrm_copy(src, dst)
    # --ignore-unmatch so that we wouldn't get errors if dst does not exist
    run(`git rm -rf --ignore-unmatch $(dst)`)
    Compat.cp(src, dst; force=true)
end

function withfile(func, file::AbstractString, contents::AbstractString)
    hasfile = isfile(file)
    original = hasfile ? read(file, String) : ""
    open(file, "w") do stream
        print(stream, contents)
        flush(stream) # Make sure file is written before continuing.
    end
    try
        func()
    finally
        if hasfile
            open(file, "w") do stream
                print(stream, original)
            end
        else
            rm(file)
        end
    end
end

function getenv(regex::Regex)
    for (key, value) in ENV
        occursin(regex, key) && return value
    end
    error("could not find key/iv pair.")
end

"""
$(SIGNATURES)

Creates a documentation stub for a package called `pkgname`. The location of
the documentation is assumed to be `<package directory>/docs`, but this can
be overriden with the keyword argument `dir`.

It creates the following files

```
docs/
    .gitignore
    src/index.md
    make.jl
    mkdocs.yml
```

# Arguments

**`pkgname`** is the name of the package (without `.jl`). It is used to
determine the location of the documentation if `dir` is not provided.

# Keywords

**`dir`** defines the directory where the documentation will be generated.
It defaults to `<package directory>/docs`. The directory must not exist.

# Examples

```jlcon
julia> using Documenter

julia> Documenter.generate("MyPackageName")
[ ... output ... ]
```
"""
function generate(pkgname::AbstractString; dir=nothing)
    # TODO:
    #   - set up deployment to `gh-pages`
    #   - fetch url and username automatically (e.g from git remote.origin.url)

    # Check the validity of the package name
    if length(pkgname) == 0
        error("Package name can not be an empty string.")
    end
    # Determine the root directory where we wish to generate the docs and
    # check that it is a valid directory.
    docroot = if dir === nothing
        pkgdir = Pkg.dir(pkgname)
        if !isdir(pkgdir)
            error("Unable to find package $(pkgname).jl at $(pkgdir).")
        end
        joinpath(pkgdir, "docs")
    else
        dir
    end

    if ispath(docroot)
        error("Directory $(docroot) already exists.")
    end

    # deploy the stub
    try
        @info("Deploying documentation to $(docroot)")
        mkdir(docroot)

        # create the root doc files
        Generator.savefile(docroot, ".gitignore") do io
            write(io, Generator.gitignore())
        end
        Generator.savefile(docroot, "make.jl") do io
            write(io, Generator.make(pkgname))
        end
        Generator.savefile(docroot, "mkdocs.yml") do io
            write(io, Generator.mkdocs(pkgname))
        end

        # Create the default documentation source files
        Generator.savefile(docroot, "src/index.md") do io
            write(io, Generator.index(pkgname))
        end
    catch
        rm(docroot, recursive=true)
        rethrow()
    end
    nothing
end

end


text:
# Use baremodule to shave off a few KB from the serialized `.ji` file
baremodule LibBirch_jll
using Base
using Base: UUID
import JLLWrappers

JLLWrappers.@generate_main_file_header("LibBirch")
JLLWrappers.@generate_main_file("LibBirch", UUID("9af553da-f2ee-58c4-bad9-1c5e8386f243"))
end  # module LibBirch_jll

ext: jl


text:
# using Revise
using Formatting
using LinearAlgebra
using Statistics, StatsBase

import DataFrames
import TimeSeries
import Dates
import FileIO
# import GLM

# import PyPlot; const plt = PyPlot
# plt.plt[:style][:use]("ggplot")

using Plots
# pyplot(reuse=true, size=(1000,250))
pyplot()
theme(:ggplot2)

Plots.scalefontsizes(1.)
# fnt = Plots.font("Helvetica", 10.0)
# default(titlefont=fnt, guidefont=fnt, tickfont=fnt, legendfont=fnt)

import FracFin

include("Utils.jl")

########### Load data and Visualization ##########
include("Parms_IO.jl")

project = "Analysis of Lazard NY dataset 2"  # name of the current project

outdir_root = homedir() * "/Outputs/$(project)/"  # root output directory
# outdir_root = pwd() * "/Outputs/"  # root output directory

Market = "Equity_1"  # market name
# input csv file
infile = homedir() * "/Database/Economy_and_Finance/Lusenn/Lazard NY 2/$(Market).csv"

println("Loading data...")
DataRaw, DataSplt = load_data(infile, parms_io)
Component = TimeSeries.colnames(DataRaw)[1]  # name of the working time-series
Price = TimeSeries.values(DataRaw)
TimeStamp = TimeSeries.timestamp(DataRaw)
LogPrice = log.(Price)  # supposed to be a fBm
Npd = isnothing(DataSplt) ? nothing : length(DataSplt[1])  # number of points per day, if meaningful

outdir_component = outdir_root * "/$(Market)/$(Component)/"  # outdir of the working time-series

#### Visualization of data ####
println("Plotting data...")

outdir_fig = outdir_component * "/data/"
try mkpath(outdir_fig) catch end

# fig1 = plot(TimeSeries.values(Data), label="Raw price", title=cname, size=(1000,250))
# savefig(outdir_fig * "/$(cname).pdf")

fig = plot(DataRaw, label="Raw price", title=Component, size=(1000,250))
fname = outdir_fig * "/$(Component).pdf"
savefig(fig, fname)

if parms_io.intraday
    outdir_fig = outdir_component * "/data/intraday/"
    try mkpath(outdir_fig) catch end

    for data in DataSplt
        date = Dates.Date(TimeSeries.timestamp(data)[1])

        fig = plot(data, label="Raw price", size=(1000,250))
        savefig(outdir_fig * "/$(date).pdf")
    end
end

########## Estimation ##########
include("Parms_BSpline_MLE_timescale.jl")
# include("Parms_BSpline_MLE_scale.jl")
# include("Parms_BSpline_MLE_time.jl")
# include("Parms_BSpline_Scalogram.jl")

rolling_window_estimator = (estimator, X) -> FracFin.rolling_apply(estimator, X, parms.wsize, 1, parms.pov; mode=:causal, boundary=parms.boundary)

outdir = outdir_component * "/estimation/$(parms)/"
try mkpath(outdir) catch end

#### Wavelet transform ####
W0, Mask = FracFin.cwt_bspline(LogPrice, parms.sclrng, parms.vm, parms.fmode)
# W0, Mask = FracFin.cwt_haar(LogPrice, parms.sclrng, parms.fmode);

# # truncation of boundary points
# t0 = findall(prod(Mask, dims=2))[1][1]
# t1 = findall(prod(Mask, dims=2))[end][1]
# Wt = W0[t0:t1, :]

#### Apply rolling window estimator ####
println("Applying rolling window estimation...")

# The rolling window estimator should be applied on `W0` but not `Wt` otherwise the output time indexes in `res` will not be aligned with the original ones. Use post-processing to remove the boundary coefficients in `W0` if necessary.
res = rolling_window_estimator(base_estimator, W0')

#### Post-processing of results ####
Tx = [x[1] for x in res]  # time index of estimation
Ts = TimeStamp[Tx] # time stamp of estimation
Ht = [x[2].hurst for x in res]  # hurst
Vt = [x[2].σ for x in res]  # volatility
# Et = [x[2].η for x in res]  # scaled log-volatility
# Rt = [x[2].residual for x in res];  # residual
Lt = [x[2].loglikelihood for x in res]  # log-likelihood

# Hs = [try GLM.stderror(x[2].optimizer)[2] catch NaN end for x in res]  # stderror of hurst
# Es = [try GLM.stderror(x[2].optimizer)[1] catch NaN end for x in res]  # stderror of scaled log-volatility
# cp = FracFin.normal_moment_factor(parms.pow)  # constant factor depending on p
# Vs = exp.((Es.-log(cp))/parms.pow)/parms.pow

# At0 = TimeSeries.TimeArray(Ts, [Tx Price[Tx] Ht Vt Rt], Symbol.(["Index", "Price", "Hurst", "Volatility", "Residual"]));
At0 = TimeSeries.TimeArray(Ts, [Tx Price[Tx] Ht Vt Lt], Symbol.(["Index", "Price", "Hurst", "Volatility", "LogLikelihood"]));

FileIO.save(outdir * "/results.jld2", Dict("parameters"=>parms, "estimates"=>At0))
TimeSeries.writetimearray(At0, outdir * "/results.csv")

#### Visualization ####
println("Plotting results of estimation...")

At = At0[5:end]  # truncation of boundary wavelet coefficients

fig1 = plot(At.Price, label="Price")
fig2 = plot(At.Hurst, shape=:circle, label="Hurst", ylim=(0.,1.))
hline!(fig2, [0.5], alpha=0.5, width=2, color=:red, label="")
fig3 = plot(At.Volatility, shape=:circle, label="Volatility")
fig4 = plot(At.LogLikelihood, shape=:circle, label="LogLikelihood")
# fig4 = plot(At.Residual, shape=:circle, label="Residual")

fig = vplot(fig1, fig2, fig3, fig4, link=:x)
outfile = outdir * "/results.pdf"
savefig(fig, outfile)

println("Results saved in $(outdir).")

max_stars_repo_name: yanncalec/FracFin

max_issues_repo_name: yanncalec/FracFin

max_forks_repo_name: yanncalec/FracFin


text:
using TravelingSalesmanHeuristics
const TSP = TravelingSalesmanHeuristics
using Test
using Random
using LinearAlgebra

###
# helpers
###

# generate a Euclidean distance matrix for n points in the unit square
function generate_planar_distmat(n)
    pts = rand(2, n)
    dm = [norm(pts[:,i] - pts[:,j]) for i in 1:n, j in 1:n]
end

# test that a path is acceptable:
# - at most one city appears twice, and if so must be first and last
# - all values 1:n are present where n is the maximum city index, and no other values
function testpathvalidity(path, iscycle)
    if iscycle
        @test path[1] == path[end]
    end
    n = iscycle ? length(path) - 1 : length(path)
    @test sort(unique(path)) == collect(1:n)
end

# tests that a path-cost pair is consistent with the distance matrix
# basically a reimplementation of `pathcost`, but hey...less likely to double a mistake?
function testpathcost(path, cost, dm)
    c = zero(eltype(dm))
    for i in 1:(length(path) - 1)
        c += dm[path[i], path[i+1]]
    end
    @test isapprox(c, cost)
end

###
# main tests
###

function test_nearest_neighbor()
    distmats = [generate_planar_distmat(10), generate_planar_distmat(2)]

    for dm in distmats
        n = size(dm, 1)
        randstartcity = rand(1:n)
        # standard
        path, cost = nearest_neighbor(dm)
        @test cost > 0
        testpathvalidity(path, true)
        # repetitive
        path, cost = repetitive_heuristic(dm, nearest_neighbor)
        @test cost > 0
        testpathvalidity(path, true)
        # no loop, 2 opt
        path, cost = nearest_neighbor(dm, closepath = false)
        @test cost > 0
        testpathvalidity(path, false)
        # no loop, no 2 opt
        path, cost = nearest_neighbor(dm, closepath = false, do2opt = false)
        @test cost > 0
        testpathvalidity(path, false)
        # fixed start, no loop
        path, cost = nearest_neighbor(dm, closepath = false, firstcity = randstartcity)
        @test cost > 0
        testpathvalidity(path, false)
    end

    dm_bad = rand(3,2)
    @test_throws ErrorException nearest_neighbor(dm_bad)
end

function test_cheapest_insertion()
    # default random start
    dm = generate_planar_distmat(8)
    path, cost = cheapest_insertion(dm)
    @test cost > 0
    testpathvalidity(path, true) # should be a closed path
    # repetitive start
    path, cost = repetitive_heuristic(dm, cheapest_insertion)
    @test cost > 0
    testpathvalidity(path, true)

    # bad input
    dmbad = rand(2,3)
    @test_throws ErrorException cheapest_insertion(dmbad)
end

function test_farthest_insertion()
    # standard symmetric case
    dm = generate_planar_distmat(8)
    path, cost = farthest_insertion(dm)
    testpathvalidity(path, true)
    testpathcost(path, cost, dm)
    # invalid argument
    @test_throws ErrorException farthest_insertion(dm; firstcity = 0)
    # asymmetric matrix
    dm = rand(20, 20)
    path, cost = farthest_insertion(dm; firstcity = 1, do2opt = true)
    testpathvalidity(path, true)
    testpathcost(path, cost, dm)
end

function test_simulated_annealing()
    dm = generate_planar_distmat(14)
    # single start
    path, cost = simulated_annealing(dm)
    @test cost > 0
    testpathvalidity(path, true) # closed path
    # multi-start
    dm = generate_planar_distmat(8)
    path, cost = simulated_annealing(dm, num_starts = 3)
    @test cost > 0
    testpathvalidity(path, true) # also closed
    # given init path
    init_path = collect(1:8)
    push!(init_path, 1)
    reverse!(init_path, 2, 6)
    path, cost = simulated_annealing(dm; init_path = init_path)
    @test cost > lowerbound(dm)
    testpathvalidity(path, true) # still closed
end

function test_bounds()
    dm = generate_planar_distmat(2)
    path, cost = solve_tsp(dm)
    lb = lowerbound(dm)
    @test lb <= cost
    dm = generate_planar_distmat(30)
    path, cost = solve_tsp(dm)
    lb = lowerbound(dm)
    @test lb <= cost
end

function test_path_costs()
    dm = [1 2 3; 4 5 6; 7 8 9]
    p1 = [1, 2, 3, 1]
    orig_cost = 2 + 6 + 7
    @test TSP.pathcost(dm, p1) == orig_cost
    # various reverse indices to test
    revs = [(1,4), (2,3), (2,4), (3,3)]
    for rev in revs
        path_rev = reverse(p1, rev[1], rev[2])
        @test TSP.pathcost(dm, path_rev) ≈
              orig_cost + TSP.pathcost_rev_delta(dm, p1, rev[1], rev[2])
    end
end

function test_solve_tsp()
    dm = rand(10,10)
    quality_factors = [-1, 0, 1.1, 35, 101]
    for qf in quality_factors
        path, cost = solve_tsp(dm; quality_factor = qf)
        testpathvalidity(path, true)
    end
end

function test_two_opt()
    n = 50
    dm = generate_planar_distmat(n)
    path = collect(1:n)
    path_2opt, _ = two_opt(dm, path)
    testpathvalidity(path_2opt, false)
    # shouldn't affect endpoints
    @test path_2opt[1] == 1
    @test path_2opt[end] == n
    cycle = vcat(path, 1)
    cycle_2opt, _ = two_opt(dm, cycle)
    testpathvalidity(cycle_2opt, true)
    # same endpoints
    @test cycle_2opt[1] == 1 == cycle_2opt[n+1]
end

function test_atypical_types()
    # rational distance matrix
    dm = [rationalize(rand(); tol = .01) for i in 1:10, j in 1:10]
    initpath = 1:2:9 # not a Vector, but <:AbstractVector{<:Int}
    p, c = cheapest_insertion(dm, initpath)
    testpathvalidity(p, false)
    # Symmetric matrix type. <: AbstractMatrix, not a matrix.
    dm = Symmetric(rand(15,15))
    p, c = solve_tsp(dm; quality_factor = 60)
    testpathvalidity(p, true)
end

###
# run
###
println("Hello tester")
Random.seed!(47)
test_nearest_neighbor()
test_cheapest_insertion()
test_farthest_insertion()
test_simulated_annealing()
test_bounds()
test_path_costs()
test_solve_tsp()
test_two_opt()
test_atypical_types()
println("Done testing.")


text:
module InterpNd

using Interpolations

function (itp::Interpolations.BSplineInterpolation)(x::AbstractVector,
                                                    xx::AbstractVector)
    didx = [0; 1.0./diff(x)]
    is = map(eachindex(xx)) do i
        im = indmin(abs.(x-xx[i]))
        im - didx[im]*(x[im] - xx[i])
    end
    eltype(itp)[itp[ii] for ii in is]
end

(itp::Interpolations.BSplineInterpolation)(x::AbstractVector,
                                           xx) = itp(x,[xx])[1]

interp1d = y -> interpolate(y, BSpline(Quadratic(Flat())), OnGrid())

export interp1d

end # module


text:
module test_julia_inbounds

using Test

if Base.JLOptions().check_bounds != 1  # --check-bounds=yes

vals = []
@inbounds for i in [0, 1, 2]
              c = getindex([10], i)
              push!(vals, c)
          end
@test ==(10).(vals) == [false, true, false]

vals = []
for i in [0, 1, 2]
    c = @inbounds getindex([10], i)
    push!(vals, c)
end
@test ==(10).(vals) == [false, true, false]

else # if Base.JLOptions().check_bounds != 1

@test_throws BoundsError for i in [0, 1, 2]
                             getindex([10], i)
                         end

end # if Base.JLOptions().check_bounds != 1

end # module test_julia_inbounds


text:
module TestBautin
include("preamble_plots.jl")

using Bifurcations: resolved_points
using Bifurcations.Codim2LimitCycle: FoldLimitCycleProblem
using Bifurcations.Examples.Bautin

prob = Bautin.make_prob()
solver1 = init(prob)
solve!(solver1)

codim1_points = resolved_points(solver1)
@test length(codim1_points) == 1
@test codim1_points[1].point_type === Codim1.PointTypes.hopf

hopf_prob = BifurcationProblem(
    codim1_points[1],
    solver1,
    (@lens _.β₂),
    (-2.0, 2.0),
)
hopf_solver = init(
    hopf_prob;
)
solve!(hopf_solver)

hopf_β₁ = [u[end-1] for sweep in hopf_solver.super.sol.sweeps for u in sweep.u]
hopf_β₂ = [u[end]   for sweep in hopf_solver.super.sol.sweeps for u in sweep.u]
@test all(@. abs(hopf_β₁) < 1e-6)
@test maximum(hopf_β₂) > 2
@test minimum(hopf_β₂) < -2

codim2_points = resolved_points(hopf_solver)
@test length(codim2_points) == 1
@test codim2_points[1].point_type === Codim2.PointTypes.bautin
β_bautin = codim2_points[1].u[end-1:end]
@test all(@. abs(β_bautin) < 1e-6)

plt = plot(hopf_solver)
@test_nothrow nullshow(plt)

flc_prob = FoldLimitCycleProblem(
    # codim2_points[1],  # SpecialPointInterval is required ATM
    special_intervals(hopf_solver, Codim2.PointTypes.bautin)[1],
    hopf_solver;
    num_mesh = 20,
    degree = 3,
)
@test flc_prob.t_domain == ([-2.0, -2.0], [2.0, 2.0])
flc_solver = init(
    flc_prob;
    start_from_nearest_root = true,
    max_branches = 0,  # TODO: stop manually doing this
)
solve!(flc_solver)

flc_β₁ = [u[end-1] for sweep in flc_solver.super.sol.sweeps for u in sweep.u]
flc_β₂ = [u[end]   for sweep in flc_solver.super.sol.sweeps for u in sweep.u]
@test all(@. abs(4 * flc_β₁ + flc_β₂^2) < 5e-3)
@test maximum(flc_β₂) > 2
@test minimum(flc_β₂) > -1e-6

plt_lcs = plot_state_space(flc_solver)
@test_nothrow nullshow(plt_lcs)

end  # module


text:
# A collection of iterated maps

LogisticMap(r) = IteratedMap{:LogisticMap,1}(x->r*x*(1-x))

LogisticMap(r,x) = LogisticMap(r)(x)

HenonMap(p) = IteratedMap{:HenonMap,2}(x->[1-p[1]*x[1]^2+x[2],p[2]*x[1]])
HenonMap(p,x) = HenonMap(p)(x)

DuffingMap(p) = IteratedMap{:DuffingMap,2}(x->[x[2],-p[2]*x[1]+p[1]*x[2]-x[2]^3])
DuffingMap(p,x) = DuffingMap(p)(x)

TentMap(μ) = IteratedMap{:TentMap,1}(x->x<0.5?μ*x:μ*(1-x))
TentMap(μ,x) = TentMap(μ)(x)

max_stars_repo_name: wkearn/IteratedMaps

max_issues_repo_name: wkearn/IteratedMaps

max_forks_repo_name: wkearn/IteratedMaps


text:
#
# function compcart: Compute cartesian coordinates using
#                    the center of mass, the canonical coordinates
#                    and the rotation matrix
#
# xcm: Coordinates of the center of mass of the molecule
# A : rotation matrix
# xref: reference coordinates (assumed to be centered at the origin)
#

# From the rotation matrix

function compcart( xcm :: Vector{Float64},
                   A :: Matrix{Float64},
                   xref :: Vector{Float64} )
  x = Vector{Float64}(undef,3)
  x[1] = xcm[1] + xref[1]*A[1,1] + xref[2]*A[2,1] + xref[3]*A[3,1]
  x[2] = xcm[2] + xref[1]*A[1,2] + xref[2]*A[2,2] + xref[3]*A[3,2]
  x[3] = xcm[3] + xref[1]*A[1,3] + xref[2]*A[2,3] + xref[3]*A[3,3]
  return x
end

# From the angles

function compcart( xcm :: Vector{Float64},
                   xref :: Vector{Float64},
                   beta :: Float64,
                   gamma :: Float64,
                   theta :: Float64 )
   A = eulermat(beta, gamma, theta)
   x = compcart( xcm, A, xref )
   return x
end

# From the angles, but angles given in degrees instead of radians

function compcart( xcm :: Vector{Float64},
                   xref :: Vector{Float64},
                   beta :: Float64,
                   gamma :: Float64,
                   theta :: Float64,
                   deg :: String )
   A = eulermat(beta, gamma, theta, deg)
   x = compcart( xcm, A, xref )
   return x
end

max_stars_repo_name: mcubeg/JPleXL

max_issues_repo_name: mcubeg/JPleXL

max_forks_repo_name: mcubeg/JPleXL


text:
function fasthist!(h, v, edg)
    n = length(edg)-1
    for x in v
        i = searchsortedfirst(edg, x)-1
        if 1 <= i <= n
            h[i] = h[i] + 1.0
        end
    end
end

function mi(probabilites)
    a = 0.
    @inbounds @fastmath for bin_i = 1:size(probabilites,2)
        p_value = sum(probabilites[:,bin_i]); # response probability
        for stim_i = 1:size(probabilites,1)
            p_stim = sum(probabilites[stim_i,:]); # stimulus probability
            if probabilites[stim_i,bin_i]>0
                PrGs = probabilites[stim_i,bin_i]; # response probability given stim
                inc = PrGs*log2(PrGs/(p_value*p_stim)); # MI
                a += inc
            end
        end
    end
    return a
end

function mutual_info(response, class_id)
    stims = sort(unique(class_id))
    nstim = length(stims)
    nfet = size(response,2)
    axis_MI= zeros(Float64,nfet);
    nbins_dist = 10::Int
    histcounts = StatsBase.histrange(extrema(response)..., nbins_dist,
        :left)::StepRangeLen
    probabilites = zeros(Float64,nstim,length(histcounts)-1);
    for axis_i in 1:nfet
        resp = view(response, :, axis_i)
        for (stim_i,stim) in enumerate(stims)
            fasthist!(view(probabilites,stim_i,:),resp[class_id.==stim],
                histcounts);
        end
        probabilites ./= sum(probabilites);
        axis_MI[axis_i]=mi(probabilites)
        fill!(probabilites,0.0)
    end
    return axis_MI
end

function surrogate_MI_coefs(wvmatrix, class_id, nsurr)
    MI_coefs_surrogate = zeros(nsurr,size(wvmatrix,2))
    for surr_i = 1:nsurr
        class_id_surrogate = StatsBase.shuffle(class_id);
        MI_coefs_surrogate[surr_i,:] = mutual_info(wvmatrix,class_id_surrogate);
    end
    return MI_coefs_surrogate
end

function level_per_thresh(MI_coefs_surrogate,  percentile, L)
    MI_thresholds = zeros(size(MI_coefs_surrogate,2))

	levelbounds = cumsum([0; L[1:end-1]]);
    levelthres = zeros(1,length(L)-1);
    for level_i in 1:length(L)-1
        level_coefs = levelbounds[level_i]+1:levelbounds[level_i+1];
        level_MI_nulldist = MI_coefs_surrogate[:,level_coefs];
        level_MI_nulldist = level_MI_nulldist[:];
        levelthres[level_i] = StatsBase.percentile(level_MI_nulldist,percentile);
        MI_thresholds[level_coefs] .= levelthres[level_i]
    end
    return MI_thresholds
end

function mutual_info_thresh(wvmatrix, class_id, nsurr, percentile, nscales)
    L = [1; [2^n for n in 1:nscales]];
    MI_coefs_surrogate = surrogate_MI_coefs(wvmatrix, class_id, nsurr)
    MI_thresholds = level_per_thresh(MI_coefs_surrogate,  percentile, L)
	return MI_thresholds
end

function mi_select(wvmatrix, class_id, opts=WIOpts())
    opts.nscales = opts.nscales == :max ?
        floor(Int,log2(size(wvmatrix,2))) : opts.nscales

    MI = mutual_info(wvmatrix, class_id)
    MI_bias = mutual_info_thresh(wvmatrix, class_id,
                             opts.nsurr, opts.percentile, opts.nscales)

    unbiased_MI = MI .- MI_bias
    selected_wvcoefs = findall(unbiased_MI.>0)

    if length(selected_wvcoefs) > opts.maxwvcoefs
        selected_wvcoefs = sortperm(unbiased_MI, rev=true)[1:opts.maxwvcoefs]
    elseif length(selected_wvcoefs) < opts.minwvcoefs
        selected_wvcoefs = sortperm(unbiased_MI, rev=true)[1:opts.minwvcoefs]
    end

    return selected_wvcoefs,(MI,unbiased_MI)
end


text:
#-------------------------------------------------------------------------------
# AST interface, built on top of raw tree

"""
Design options:
* rust-analyzer treats their version of an untyped syntax node as a cursor into
  the green tree. They deallocate aggressively.
"""
mutable struct SyntaxNode
    source::SourceFile
    raw::GreenNode{SyntaxHead}
    position::Int
    parent::Union{Nothing,SyntaxNode}
    is_leaf::Bool
    val::Any
end

# Value of an error node with no children
struct ErrorVal
end

Base.show(io::IO, ::ErrorVal) = printstyled(io, "✘", color=:light_red)

function SyntaxNode(source::SourceFile, raw::GreenNode{SyntaxHead}, position::Integer=1)
    if !haschildren(raw) && !(is_syntax_kind(raw) || is_keyword(raw))
        # Leaf node
        k = kind(raw)
        val_range = position:position + span(raw) - 1
        val_str = view(source, val_range)
        # Here we parse the values eagerly rather than representing them as
        # strings. Maybe this is good. Maybe not.
        val = if k in KSet`Integer Float BinInt OctInt HexInt`
            julia_string_to_number(val_str, k)
        elseif k == K"true"
            true
        elseif k == K"false"
            false
        elseif k == K"Char"
            unescape_julia_string(val_str, false, false)[2]
        elseif k == K"Identifier"
            if has_flags(head(raw), RAW_STRING_FLAG)
                s = unescape_julia_string(val_str, false, true)
                Symbol(normalize_identifier(s))
            else
                Symbol(normalize_identifier(val_str))
            end
        elseif is_keyword(k)
            # This should only happen for tokens nested inside errors
            Symbol(val_str)
        elseif k in KSet`String CmdString`
            is_cmd = k == K"CmdString"
            is_raw = has_flags(head(raw), RAW_STRING_FLAG)
            has_flags(head(raw), TRIPLE_STRING_FLAG) ?
                process_triple_strings!([val_str], is_raw)[1] :
                unescape_julia_string(val_str, is_cmd, is_raw)
        elseif is_operator(k)
            isempty(val_range)  ?
                Symbol(untokenize(k)) : # synthetic invisible tokens
                Symbol(normalize_identifier(val_str))
        elseif k == K"NothingLiteral"
            nothing
        elseif k == K"error"
            ErrorVal()
        elseif k == K"@."
            :var"@__dot__"
        elseif k == K"MacroName"
            Symbol("@$(normalize_identifier(val_str))")
        elseif k == K"StringMacroName"
            Symbol("@$(normalize_identifier(val_str))_str")
        elseif k == K"CmdMacroName"
            Symbol("@$(normalize_identifier(val_str))_cmd")
        elseif k == K"core_@doc"
            GlobalRef(Core, :var"@doc")
        elseif k == K"core_@cmd"
            GlobalRef(Core, :var"@cmd")
        elseif is_syntax_kind(raw)
            nothing
        else
            @error "Leaf node of kind $k unknown to SyntaxNode"
            val = nothing
        end
        return SyntaxNode(source, raw, position, nothing, true, val)
    else
        cs = SyntaxNode[]
        pos = position
        if kind(raw) == K"string" && has_flags(head(raw), TRIPLE_STRING_FLAG)
            # Triple quoted strings need special processing of sibling String literals
            strs = SubString[]
            str_nodes = SyntaxNode[]
            for (i,rawchild) in enumerate(children(raw))
                if !is_trivia(rawchild) || is_error(rawchild)
                    if kind(rawchild) == K"String"
                        val_range = pos:pos + span(rawchild) - 1
                        push!(strs, view(source, val_range))
                        n = SyntaxNode(source, rawchild, pos, nothing, true, nothing)
                        push!(cs, n)
                        push!(str_nodes, n)
                    else
                        push!(cs, SyntaxNode(source, rawchild, pos))
                    end
                end
                pos += rawchild.span
            end
            is_raw = has_flags(head(raw), RAW_STRING_FLAG)
            process_triple_strings!(strs, is_raw)
            for (s,n) in zip(strs, str_nodes)
                n.val = s
            end
        else
            for (i,rawchild) in enumerate(children(raw))
                # FIXME: Allowing trivia is_error nodes here corrupts the tree layout.
                if !is_trivia(rawchild) || is_error(rawchild)
                    push!(cs, SyntaxNode(source, rawchild, pos))
                end
                pos += rawchild.span
            end
        end
        node = SyntaxNode(source, raw, position, nothing, false, cs)
        for c in cs
            c.parent = node
        end
        return node
    end
end

is_error(node::SyntaxNode) = is_error(node.raw)
is_trivia(node::SyntaxNode) = is_trivia(node.raw)
has_flags(node::SyntaxNode, f) = has_flags(head(node), f)

head(node::SyntaxNode) = head(node.raw)
kind(node::SyntaxNode)  = kind(node.raw)
flags(node::SyntaxNode) = flags(node.raw)

haschildren(node::SyntaxNode) = !node.is_leaf
children(node::SyntaxNode) = haschildren(node) ? node.val::Vector{SyntaxNode} : ()

span(node::SyntaxNode) = span(node.raw)

"""
    sourcetext(node)

Get the full source text of a node.
"""
function sourcetext(node::SyntaxNode)
    val_range = (node.position-1) .+ (1:span(node))
    view(node.source, val_range)
end

function interpolate_literal(node::SyntaxNode, val)
    @assert kind(node) == K"$"
    SyntaxNode(node.source, node.raw, node.position, node.parent, true, val)
end

function _show_syntax_node(io, current_filename, node, indent)
    fname = node.source.filename
    line, col = source_location(node.source, node.position)
    posstr = "$(lpad(line, 4)):$(rpad(col,3))│$(lpad(node.position,6)):$(rpad(node.position+span(node)-1,6))│"
    nodestr = haschildren(node)   ?  "[$(untokenize(head(node)))]" :
              node.val isa Symbol ? string(node.val) :
              repr(node.val)
    treestr = string(indent, nodestr)
    # Add filename if it's changed from the previous node
    if fname != current_filename[]
        #println(io, "# ", fname)
        treestr = string(rpad(treestr, 40), "│$fname")
        current_filename[] = fname
    end
    println(io, posstr, treestr)
    if haschildren(node)
        new_indent = indent*"  "
        for n in children(node)
            _show_syntax_node(io, current_filename, n, new_indent)
        end
    end
end

function _show_syntax_node_sexpr(io, node)
    if !haschildren(node)
        if is_error(node)
            print(io, "(error)")
        else
            print(io, node.val isa Symbol ? string(node.val) : repr(node.val))
        end
    else
        print(io, "(", untokenize(head(node)))
        first = true
        for n in children(node)
            print(io, ' ')
            _show_syntax_node_sexpr(io, n)
            first = false
        end
        print(io, ')')
    end
end

function Base.show(io::IO, ::MIME"text/plain", node::SyntaxNode)
    println(io, "line:col│ byte_range  │ tree                                   │ file_name")
    _show_syntax_node(io, Ref{Union{Nothing,String}}(nothing), node, "")
end

function Base.show(io::IO, ::MIME"text/x.sexpression", node::SyntaxNode)
    _show_syntax_node_sexpr(io, node)
end

function Base.show(io::IO, node::SyntaxNode)
    _show_syntax_node_sexpr(io, node)
end

function Base.push!(node::SyntaxNode, child::SyntaxNode)
    if !haschildren(node)
        error("Cannot add children")
    end
    args = node.val::Vector{SyntaxNode}
    push!(args, child)
end

#-------------------------------------------------------------------------------
# Tree utilities

kind(node)  = kind(head(node))
flags(node) = flags(head(node))
is_infix(node) = is_infix(head(node))

"""
    child(node, i1, i2, ...)

Get child at a tree path. If indexing accessed children, it would be
`node[i1][i2][...]`
"""
function child(node, path::Integer...)
    n = node
    for index in path
        n = children(n)[index]
    end
    return n
end

function setchild!(node::SyntaxNode, path, x)
    n1 = child(node, path[1:end-1]...)
    n1.val[path[end]] = x
end

# We can overload multidimensional Base.getindex / Base.setindex! for node
# types.
#
# The justification for this is to view a tree as a multidimensional ragged
# array, where descending depthwise into the tree corresponds to dimensions of
# the array.
#
# However... this analogy is only good for complete trees at a given depth (=
# dimension). But the syntax is oh-so-handy!
function Base.getindex(node::Union{SyntaxNode,GreenNode}, path::Int...)
    child(node, path...)
end
function Base.setindex!(node::SyntaxNode, x::SyntaxNode, path::Int...)
    setchild!(node, path, x)
end

"""
Get absolute position and span of the child of `node` at the given tree `path`.
"""
function child_position_span(node::GreenNode, path::Int...)
    n = node
    p = 1
    for index in path
        cs = children(n)
        for i = 1:index-1
            p += span(cs[i])
        end
        n = cs[index]
    end
    return n, p, n.span
end

function child_position_span(node::SyntaxNode, path::Int...)
    n = child(node, path...)
    n, n.position, span(n)
end

"""
Print the code, highlighting the part covered by `node` at tree `path`.
"""
function highlight(code::String, node, path::Int...; color=(40,40,70))
    node, p, span = child_position_span(node, path...)
    q = p + span
    print(stdout, code[1:p-1])
    _printstyled(stdout, code[p:q-1]; color=color)
    print(stdout, code[q:end])
end

#-------------------------------------------------------------------------------
# Conversion to Base.Expr

function is_eventually_call(ex)
    return Meta.isexpr(ex, :call) || (Meta.isexpr(ex, (:where, :(::))) &&
                                      is_eventually_call(ex.args[1]))
end

function _to_expr(node::SyntaxNode, iteration_spec=false)
    if !haschildren(node)
        if node.val isa Union{Int128,UInt128,BigInt}
            # Ignore the values of large integers and convert them back to
            # symbolic/textural form for compatibility with the Expr
            # representation of these.
            str = replace(sourcetext(node), '_'=>"")
            headsym = :macrocall
            k = kind(node)
            macname = node.val isa Int128  ? Symbol("@int128_str")  :
                      node.val isa UInt128 ? Symbol("@uint128_str") :
                      Symbol("@big_str")
            return Expr(:macrocall, GlobalRef(Core, macname), nothing, str)
        else
            return node.val
        end
    end
    headstr = untokenize(head(node), include_flag_suff=false)
    headsym = !isnothing(headstr) ? Symbol(headstr) :
        error("Can't untokenize head of kind $(kind(node))")
    node_args = children(node)
    args = Vector{Any}(undef, length(node_args))
    if headsym == :for && length(node_args) == 2
        args[1] = _to_expr(node_args[1], true)
        args[2] = _to_expr(node_args[2], false)
    else
        map!(_to_expr, args, node_args)
    end
    # Julia's standard `Expr` ASTs have children stored in a canonical
    # order which is often not always source order. We permute the children
    # here as necessary to get the canonical order.
    if is_infix(node.raw)
        args[2], args[1] = args[1], args[2]
    end
    loc = source_location(LineNumberNode, node.source, node.position)
    # Convert elements
    if headsym == :macrocall
        insert!(args, 2, loc)
    elseif headsym in (:call, :ref)
        # Move parameters block to args[2]
        if length(args) > 1 && Meta.isexpr(args[end], :parameters)
            insert!(args, 2, args[end])
            pop!(args)
        end
    elseif headsym in (:tuple, :parameters, :vect)
        # Move parameters blocks to args[1]
        if length(args) > 1 && Meta.isexpr(args[end], :parameters)
            pushfirst!(args, args[end])
            pop!(args)
        end
    elseif headsym == :try
        # Try children in source order:
        #   try_block catch_var catch_block else_block finally_block
        # Expr ordering:
        #   try_block catch_var catch_block [finally_block] [else_block]
        catch_ = nothing
        if has_flags(node, TRY_CATCH_AFTER_FINALLY_FLAG)
            catch_ = pop!(args)
            catch_var = pop!(args)
        end
        finally_ = pop!(args)
        else_ = pop!(args)
        if has_flags(node, TRY_CATCH_AFTER_FINALLY_FLAG)
            pop!(args)
            pop!(args)
            push!(args, catch_var)
            push!(args, catch_)
        end
        # At this point args is
        # [try_block catch_var catch_block]
        if finally_ !== false
            push!(args, finally_)
        end
        if else_ !== false
            push!(args, else_)
        end
    elseif headsym == :filter
        pushfirst!(args, last(args))
        pop!(args)
    elseif headsym == :flatten
        # The order of nodes inside the generators in Julia's flatten AST
        # is noncontiguous in the source text, so need to reconstruct
        # Julia's AST here from our alternative `flatten` expression.
        gen = Expr(:generator, args[1], args[end])
        for i in length(args)-1:-1:2
            gen = Expr(:flatten, Expr(:generator, gen, args[i]))
        end
        return gen
    elseif headsym in (:nrow, :ncat)
        # For lack of a better place, the dimension argument to nrow/ncat
        # is stored in the flags
        pushfirst!(args, numeric_flags(flags(node)))
    elseif headsym == :typed_ncat
        insert!(args, 2, numeric_flags(flags(node)))
    elseif headsym == :(=)
        if is_eventually_call(args[1]) && !iteration_spec
            if Meta.isexpr(args[2], :block)
                pushfirst!(args[2].args, loc)
            else
                # Add block for short form function locations
                args[2] = Expr(:block, loc, args[2])
            end
        end
    elseif headsym == :(->)
        if Meta.isexpr(args[2], :block)
            pushfirst!(args[2].args, loc)
        else
            # Add block for source locations
            args[2] = Expr(:block, loc, args[2])
        end
    end
    if headsym == :inert || (headsym == :quote && length(args) == 1 &&
                 !(a1 = only(args); a1 isa Expr || a1 isa QuoteNode ||
                   a1 isa Bool  # <- compat hack, Julia 1.4+
                  ))
        return QuoteNode(only(args))
    else
        return Expr(headsym, args...)
    end
end

Base.Expr(node::SyntaxNode) = _to_expr(node)

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

function build_tree(::Type{SyntaxNode}, stream::ParseStream; filename="none", kws...)
    green_tree = build_tree(GreenNode, stream; kws...)
    source = SourceFile(sourcetext(stream), filename=filename)
    SyntaxNode(source, green_tree, first_byte(stream))
end

function build_tree(::Type{Expr}, stream::ParseStream; kws...)
    Expr(build_tree(SyntaxNode, stream; kws...))
end


text:
module FDMTests

include("../test_fdm.jl")

nparts = (2,2,2)
prun_debug(test_fdm,sequential,nparts)

nparts = 4
prun_debug(test_fdm,sequential,nparts)

end # module


text:
```
using Pkg
import Juniper

import JuMP
using JuMP: @variable, @constraint, @objective, Model, optimizer_with_attributes, read_from_file,set_optimizer,all_variables,all_constraints,VariableRef,optimize!
using JSON
using LinearAlgebra
using Random
using Distributed
using Statistics

using MathOptInterface
const MOI = MathOptInterface
const MOIU = MOI.Utilities

# functions
const SVF = MOI.SingleVariable
const SAF = MOI.ScalarAffineFunction{Float64}
const SQF = MOI.ScalarQuadraticFunction{Float64}
const VECTOR = MOI.VectorOfVariables

################
using Ipopt
using Cbc

using Base
```
using JuMP, Cbc, Juniper, Ipopt,Random
cd("/HDD/Workspace/CLT/FP/data")
#cd("/HDD/Workspace/CLT/mps/data")
pwd()
println("============================flag! read======================================")

m = read_from_file("mzzv42z.mps")
println("==========================flag! optimizer ======================================")
nl_solver= optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0)
mip_solver = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0 , "seconds" => 100, "feasibilityPump" => "on","maxSolutions" => 2)
optimizer = optimizer_with_attributes(Juniper.Optimizer, "nl_solver"=>nl_solver, "mip_solver"=>mip_solver,"feasibility_pump"=>true ,
    "solution_limit"=>10 ,"time_limit"=>300,
"feasibility_pump_tolerance_counter"=>100)
println("========================flag! set optimize======================================")
set_optimizer(m, optimizer)
println("========================flag! Juniper_result!======================================")
#Juniper_result!(m)
#println("==============flag! optimize!======================================")
optimize!(m)
println("=======================7=====================")
#include("/HDD/Workspace/CLT/FP/sjFP/src/fpump.jl")
#fpump(model,Juniper.JuniperProblem


text:
# Solver for different starting points

@doc raw"""
    sumBassDiffStartSolver(p,q,m,c0,alpha,F,T,Pi)

This function maximizes the sum of Bass functions with same p, q, and m, but
heterogeneous 'starting points' c0. The function returns the maximizer
and maximum.
"""
function sumBassDiffStartSolver(p::Real,q::Real,m::Real,c0,alpha::Real,F::Real,T::Real,Pi::Real)
    n=length(c0)
    if n*F > Pi
        throw(DomainError(Pi,"the problem is unfeasible because the capacity is too small."))
    end
    x0 = Bass_inverse.(c0,p,q,m,0)
    z0 = Bass_inflection(p,q,m,0)
    C1 = findall(x0 .+ F .>= z0)
    C2 = findall(x0 .+ F .< z0)
    ind2 = sortperm(x0[C2],rev=true)
    ind1 = sortperm(x0[C1])
    ind = vcat(C2[ind2],C1[ind1])

    function P(l,lambda,p,q,m,F,T,x0,lenC2)
        xhat = Bass_derivative_inverse(lambda,p,q,m,0)[1]
        result = sum(min.(xhat .- x0[1:l],T)) + F*(lenC2 - l)
        if lenC2<n
            result += sum(min.(max.(xhat .- x0[(lenC2+1):end],F),T))
        end
        return result
    end

    lenC2 = length(C2)
    lambda_ub = Bass_derivative(z0,p,q,m,0)
    lambdas = Vector{Float64}(undef,lenC2)
    Psi = Vector{Float64}(undef,lenC2+1)
    for l in 1:lenC2
        try
            lambdas[l] = find_zero(y -> P(l,y,p,q,m,F,T,x0[ind],lenC2) - Pi,(0,lambda_ub))
            xhat = Bass_derivative_inverse(lambdas[l],p,q,m,0)[1]
            Psi[l] = alpha*sum(Bass(min(xhat - x0[ind[i]],T),p,q,m,c0[ind[i]]) for i in 1:l)
            if l<lenC2
                Psi[l] += alpha*sum(Bass(F,p,q,m,c0[ind[i]]) for i in (l+1):lenC2)
            end
            if lenC2<n
                Psi[l] += alpha*sum([Bass(min(max(xhat - x0[ind[i]],F),T),p,q,m,c0[ind[i]]) for i in (lenC2+1):n])
            end
        catch
            lambdas[l] = 0
            Psi[l] = 0
        end
    end

    Psi[lenC2+1] = alpha*Bass(min(Pi,T),p,q,m,c0[ind[1]]) + alpha*sum([Bass(F,p,q,m,c0[ind[i]]) for i in 2:n])
    lstar = argmax(Psi)
    x = Vector{Float64}(undef,n)
    if lstar == lenC2+1
        x .= F
        x[ind[1]] = min(Pi,T)
    else
        xhat = Bass_derivative_inverse(lambdas[lstar],p,q,m,0)[1]
        x[ind[1:lstar]] = [min(xhat - x0[ind[i]],T) for i in 1:lstar]
        x[ind[(lstar+1):lenC2]] .= F
        if lenC2<n
            x[ind[(lenC2+1):n]] = [min(max(xhat - x0[ind[i]],F),T) for i in (lenC2+1):n]
        end
    end
    return x, sum(alpha .* Bass.(x,p,q,m,c0))
end

max_stars_repo_name: andres-alban/res-alloc-bass-demands

max_issues_repo_name: andres-alban/res-alloc-bass-demands

max_forks_repo_name: andres-alban/res-alloc-bass-demands


text:
@defcomp radiativeforcing begin
    FORC      = Variable(index=[time])   #Increase in radiative forcing (watts per m2 from 1900)

    forcoth   = Parameter(index=[time])  #Exogenous forcing for other greenhouse gases
    MAT       = Parameter(index=[time])  #Carbon concentration increase in atmosphere (GtC from 1750)
    eqmat     = Parameter()              #Equilibrium concentration of CO2 in atmosphere (GTC)
    fco22x    = Parameter()              #Forcings of equilibrium CO2 doubling (Wm-2)

    function run_timestep(p, v, d, t)
        #Define function for FORC
        v.FORC[t] = p.fco22x * (log((p.MAT[t] / p.eqmat)) / log(2)) + p.forcoth[t]
    end
end


text:
import ScientificTypes.trait

struct Foo1 <: Supervised end
struct Bar1 <: Unsupervised end

@test trait(rms) == :measure
@test trait(Foo1()) == :supervised_model
@test trait(Bar1()) == :unsupervised_model

true


text:
module _BubbEn
export BubbEn
using GroupSlices
    """
        Bubb, H = BubbEn(Sig)

    Returns the bubble entropy (`Bubb`) and the conditional Rényi entropy (`H`)
    estimates of dimension m = 2 from the data sequence (`Sig`) using
    the default parameters:
    embedding dimension = 2, time delay = 1, logarithm = natural

        Bubb, H = BubbEn(Sig::AbstractArray{T,1} where T<:Real; m::Int=2, tau::Int=1, Logx::Real=exp(1))

    Returns the bubble entropy (`Bubb`) estimate of the data sequence (`Sig`)
    using the specified 'keyword' arguments:

    # Arguments:
    `m`     - Embedding Dimension, an integer > 1   \n
              BubbEn returns estimates for each dimension [2,...,m]
    `tau`   - Time Delay, a positive integer    \n
    `Logx`  - Logarithm base, a positive scalar \n

    # See also `PhasEn`, `MSEn`

    # References:
        [1] George Manis, M.D. Aktaruzzaman and Roberto Sassi,
            "Bubble entropy: An entropy almost free of parameters."
            IEEE Transactions on Biomedical Engineering
            64.11 (2017): 2711-2718.

    """
    function BubbEn(Sig::AbstractArray{T,1} where T<:Real; m::Int=2, tau::Int=1, Logx::Real=exp(1))

    N = size(Sig,1)
    (N > 10) ? nothing :  error("Sig:   must be a numeric vector")
    (m > 1) ? nothing :   error("m:     must be an integer > 1")
    (tau >0) ? nothing :  error("tau:   must be an integer > 0")
    (Logx>0) ? nothing :  error("Logx:     must be a positive scalar > 0")

    Sx = zeros(N,m+1)
    H = zeros(m+1)
    Sx[:,1] = Sig
    for k = 2:m+1
        Sx[1:N-(k-1)*tau,k] = Sig[1+(k-1)*tau:N]
        Swapx  = BubbSort(Sx[1:N-(k-1)*tau,1:k])

        Locs = getindex.(indexin(Swapx, unique(Swapx)))
        Temp = unique(Locs)

        p = zeros(size(Temp,1))
        for n in Temp
            p[n] = sum(Locs.==n);
        end
        p ./= (N-(k-1)*tau)
        H[k] = -log(Logx,  sum(p.^2))

        if round(sum(p),digits=6) != 1
            @warn("Potential error in detected swap number")
        end
    end

    Bubb = diff(H)./log.(Logx,  (2:m+1)./(0:m-1))
    Bubb = Bubb[2:end]

    return Bubb, H
    end

    function BubbSort(Data)
        x,N2 = size(Data)
        swaps = zeros(Int, x)
        for y = 1:x
            t = 1
            while t <= N2-1
                for kk = 1:N2-t
                    if Data[y,kk] > Data[y,kk+1]
                        temp = Data[y,kk]
                        Data[y,kk] = Data[y,kk+1]
                        Data[y,kk+1] = temp
                        swaps[y] = swaps[y] + 1
                    end
                end
                t = t + 1;
            end
        end
        bsorted = Data;
        return swaps # bsorted
    end

end

"""
Copyright 2021 Matthew W. Flood, EntropyHub

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

For Terms of Use see https://github.com/MattWillFlood/EntropyHub
"""


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

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

Closes a tunnel identified by the unique tunnel id. When a CloseTunnel request is received,
we close the WebSocket connections between the client and proxy server so no data can be
transmitted.

# Arguments
- `tunnel_id`: The ID of the tunnel to close.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"delete"`: When set to true, AWS IoT Secure Tunneling deletes the tunnel data
  immediately.
"""
function close_tunnel(tunnelId; aws_config::AbstractAWSConfig=global_aws_config())
    return iotsecuretunneling(
        "CloseTunnel",
        Dict{String,Any}("tunnelId" => tunnelId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function close_tunnel(
    tunnelId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return iotsecuretunneling(
        "CloseTunnel",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("tunnelId" => tunnelId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Gets information about a tunnel identified by the unique tunnel id.

# Arguments
- `tunnel_id`: The tunnel to describe.

"""
function describe_tunnel(tunnelId; aws_config::AbstractAWSConfig=global_aws_config())
    return iotsecuretunneling(
        "DescribeTunnel",
        Dict{String,Any}("tunnelId" => tunnelId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_tunnel(
    tunnelId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return iotsecuretunneling(
        "DescribeTunnel",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("tunnelId" => tunnelId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the tags for the specified resource.

# Arguments
- `resource_arn`: The resource ARN.

"""
function list_tags_for_resource(
    resourceArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return iotsecuretunneling(
        "ListTagsForResource",
        Dict{String,Any}("resourceArn" => resourceArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_tags_for_resource(
    resourceArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return iotsecuretunneling(
        "ListTagsForResource",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("resourceArn" => resourceArn), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

List all tunnels for an AWS account. Tunnels are listed by creation time in descending
order, newer tunnels will be listed before older tunnels.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to return at once.
- `"nextToken"`: A token to retrieve the next set of results.
- `"thingName"`: The name of the IoT thing associated with the destination device.
"""
function list_tunnels(; aws_config::AbstractAWSConfig=global_aws_config())
    return iotsecuretunneling(
        "ListTunnels"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_tunnels(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return iotsecuretunneling(
        "ListTunnels", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end

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

Creates a new tunnel, and returns two client access tokens for clients to use to connect to
the AWS IoT Secure Tunneling proxy server.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"description"`: A short text description of the tunnel.
- `"destinationConfig"`: The destination configuration for the OpenTunnel request.
- `"tags"`: A collection of tag metadata.
- `"timeoutConfig"`: Timeout configuration for a tunnel.
"""
function open_tunnel(; aws_config::AbstractAWSConfig=global_aws_config())
    return iotsecuretunneling(
        "OpenTunnel"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function open_tunnel(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return iotsecuretunneling(
        "OpenTunnel", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end

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

A resource tag.

# Arguments
- `resource_arn`: The ARN of the resource.
- `tags`: The tags for the resource.

"""
function tag_resource(resourceArn, tags; aws_config::AbstractAWSConfig=global_aws_config())
    return iotsecuretunneling(
        "TagResource",
        Dict{String,Any}("resourceArn" => resourceArn, "tags" => tags);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function tag_resource(
    resourceArn,
    tags,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return iotsecuretunneling(
        "TagResource",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("resourceArn" => resourceArn, "tags" => tags),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Removes a tag from a resource.

# Arguments
- `resource_arn`: The resource ARN.
- `tag_keys`: The keys of the tags to remove.

"""
function untag_resource(
    resourceArn, tagKeys; aws_config::AbstractAWSConfig=global_aws_config()
)
    return iotsecuretunneling(
        "UntagResource",
        Dict{String,Any}("resourceArn" => resourceArn, "tagKeys" => tagKeys);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function untag_resource(
    resourceArn,
    tagKeys,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return iotsecuretunneling(
        "UntagResource",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("resourceArn" => resourceArn, "tagKeys" => tagKeys),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end


text:
"""
    PlutoViewer

Wrapper to assist viewing rendered gifs as cell outputs of Pluto notebooks
when `liveview = false`
"""
struct PlutoViewer
    filename::String
end


text:
module GateSet
    export Gate

    abstract type Gate end
    abstract type OneQubitGate <: Gate end
    abstract type TwoQubitGate <: Gate end

    struct X <: OneQubitGate
        _target::Int64
        _name::String
    end

    function X(_target::Int64)
        return X(_target, "X")
    end

    struct Y <: OneQubitGate
        _target::Int64
        _name::String
    end

    function Y(_target::Int64)
        return Y(_target, "Y")
    end

    struct Z <: OneQubitGate
        _target::Int64
        _name::String
    end

    function Z(_target::Int64)
        return Z(_target, "Z")
    end

    struct H <: OneQubitGate
        _target::Int64
        _name::String
    end

    function H(_target::Int64)
        return H(_target, "H")
    end

    struct T <: OneQubitGate
        _target::Int64
        _name::String
    end

    function T(_target::Int64)
        return T(_target, "T")
    end

    struct S <: OneQubitGate
        _target::Int64
        _name::String
    end

    function S(_target::Int64)
        return S(_target, "S")
    end

    struct RX <: OneQubitGate
        _target::Int64
        _theta::Float64
        _name::String
    end

    function RX(_target::Int64, _theta::Float64)
        return RX(_target, _theta, "RX")
    end

    struct RY <: OneQubitGate
        _target::Int64
        _theta::Float64
        _name::String
    end

    function RY(_target::Int64, _theta::Float64)
        return RY(_target, _theta, "RY")
    end

    struct RZ <: OneQubitGate
        _target::Int64
        _theta::Float64
        _name::String
    end

    function RZ(_target::Int64, _theta::Float64)
        return RZ(_target, _theta, "RZ")
    end

    struct U3 <: OneQubitGate
        _target::Int64
        _theta::Float64
        _phi::Float64
        _lambd::Float64
        _name::String
    end

    function U3(_target::Int64, _theta::Float64, _phi::Float64, _lambd::Float64)
        return U3(_target, _theta, _phi, _lambd, "U3")
    end

    struct CX <: TwoQubitGate
        _control::Int64
        _target::Int64
        _name::String
    end

    function CX(_control::Int64, _target::Int64)
        return CX(_control, _target, "CX")
    end

    struct CZ <: TwoQubitGate
        _control::Int64
        _target::Int64
        _name::String
    end

    function CZ(_control::Int64, _target::Int64)
        return CZ(_control, _target, "CZ")
    end

    struct SWAP <: TwoQubitGate
        _control::Int64
        _target::Int64
        _name::String
    end

    function SWAP(_control::Int64, _target::Int64)
        return SWAP(_control, _target, "SWAP")
    end

    struct CP <: TwoQubitGate
        _control::Int64
        _target::Int64
        _theta::Float64
        _name::String
    end

    function CP(_control::Int64, _target::Int64, _theta::Float64)
        return CP(_control, _target, _theta, "CP")
    end

    struct CRX <: TwoQubitGate
        _control::Int64
        _target::Int64
        _theta::Float64
        _name::String
    end

    function CRX(_control::Int64, _target::Int64, _theta::Float64)
        return CRX(_control, _target, _theta, "CRX")
    end

    struct CRY <: TwoQubitGate
        _control::Int64
        _target::Int64
        _theta::Float64
        _name::String
    end

    function CRY(_control::Int64, _target::Int64, _theta::Float64)
        return CRY(_control, _target, _theta, "CRY")
    end

    struct CRZ <: TwoQubitGate
        _control::Int64
        _target::Int64
        _theta::Float64
        _name::String
    end

    function CRZ(_control::Int64, _target::Int64, _theta::Float64)
        return CRZ(_control, _target, _theta, "CRZ")
    end

    struct M <: OneQubitGate
        _target::Int64
        _cregidx::Int64
        _result::Int64
        _name::String
    end

    function M(_target::Int64, _cregidx::Int64=0)
        if _cregidx == 0 # creg index is not specified
            return M(_target, _target, 0, "M")
        else
            return M(_target, _cregidx, 0, "M")
        end
    end

    # export all OneQubit Gate and TwoQubitGate
    for n in names(@__MODULE__; all=true)
        if Base.isidentifier(n) && n ∉ (Symbol(@__MODULE__), :eval, :include)
            if @eval typeof($n) <: DataType
                if @eval $n <: Gate
                    @eval export $n
                end
            end
        end
    end

end

max_stars_repo_name: ryuNagai/blueqat-julia

max_issues_repo_name: ryuNagai/blueqat-julia

max_forks_repo_name: ryuNagai/blueqat-julia


text:
import Bukdu
importall Bukdu.Octo
using Base.Test

@test "user" == singularize("users")
@test "users" == pluralize("user")


text:
using HorizonSideRobots
export HorizonSide, HorizonSideRobots, Nord, Ost, Robot, Sud, West, isborder, ismarker, move!, putmarker!, save, show, show!, sitcreate, sitedit, sitedit!, temperature
next(side::HorizonSide) = HorizonSide(mod(Int(side)+1, 4))
inverse(side::HorizonSide) = HorizonSide(mod(Int(side)+2, 4)) ###Разварот
function putmarkers!(r::Robot, side::HorizonSide)   ###МаркеровОчка пока нет стеки
    while isborder(r,side)==false
        move!(r,side)
        putmarker!(r)
    end
end
function moves!(r::Robot, side::HorizonSide) ###счетчик
    num_steps=0
    while isborder(r,side)==false
        move!(r,side)
        num_steps+=1
    end
    return num_steps
end
function moves!(r::Robot,side::HorizonSide,num_steps::Int) #Обратно
    for _ in 1:numsteps # символ "_" заменяет фактически не используемую переменную
        move!(r,side)
    end
end
function movements!(r::Robot,side::HorizonSide,num_steps::Int) #Обратно2
    for _ in 1:num_steps
        move!(r,side)
    end
end

function movements!(r::Robot,side::HorizonSide) #Движение до стенки
    while isborder(r,side) == false
        move!(r,side)
    end
end
function moves!(r::Robot,side::HorizonSide)
    while move_if_possible!(r,side)

    end
end

movements!(r::Robot, side::HorizonSide) = while isborder(r,side)==false move!(r,side) end

function get_num_movements!(r::Robot, side::HorizonSide)
    num_steps = 0
    while isborder(r,side)==false
        move!(r,side)
        num_steps += 1
    end
    return num_steps
end

function through_rectangles_into_angle(r,angle::NTuple{2,HorizonSide})
    num_steps=[]
    while isborder(r,angle[1])==false || isborder(r,angle[2]) # Робот - не в юго-западном углу
        push!(num_steps, movements!(r, angle[2]))
        push!(num_steps, movements!(r, angle[1]))
    end
    return num_steps
end

function movements!(r,sides,num_steps::Vector{Int})
    for (i,n) in enumerate(num_steps)
        movements!(r, sides[mod(i-1, length(sides))+1], n)
    end
end

function through_rectangles_into_angle(r,angle::NTuple{2,HorizonSide})
    num_steps=[]
    while isborder(r,angle[1])==false || isborder(r,angle[2]) # Робот - не в юго-западном углу
        push!(num_steps, movements!(r, angle[2]))
        push!(num_steps, movements!(r, angle[1]))
    end
    return num_steps
end
function move_if_possible!(r::Robot, direct_side::HorizonSide)::Bool
    orthogonal_side = next(direct_side)
    reverse_side = reverse(orthogonal_side)
    num_steps=0
    while isborder(r,direct_side) == true
        if isborder(r, orthogonal_side) == false
            move(r, orthogonal_side)
            num_steps += 1
        else
            break
        end
    end
    #УТВ: Робот или уперся в угол внешней рамки поля, или готов сделать шаг (или несколько) в направлении
    # direct_side
    if isborder(r,direct_side) == false
        while isborder(r,reverse_side) == true
            move!(r,direct_side)
        end
        result = true
    else
        result = false
    end
    move!(r,reverse_side)
    return result
end
function moves!(r::Robot,side::HorizonSide)
    possible, _ = move_if_possible!(r,side)
    while possible
        possible, _ = move_if_possible!(r,side)
    end
end

function move_if_possible!(r::Robot, direct_side::HorizonSide)::Bool
    orthogonal_side = next(direct_side)
    reverse_side = inverse(orthogonal_side)
    num_steps=0
    while isborder(r, direct_side) == true
        if !isborder(r, orthogonal_side)
            move!(r, orthogonal_side)
            num_steps += 1
        else
            break
        end
    end
    #УТВ: Робот или уперся в угол внешней рамки поля, или готов сделать шаг (или несколько) в направлении
    # direct_side
    if isborder(r,direct_side) == false
        move!(r,direct_side)
        if num_steps > 0
            while isborder(r,reverse_side) == true
                move!(r,direct_side)
            end
        end
        result = true
    else
        result = false
    end

    for _ in 1:num_steps
        move!(r, reverse_side)
    end

    return result
end

max_stars_repo_name: MCPavlo/mirea-progs

max_issues_repo_name: MCPavlo/mirea-progs

max_forks_repo_name: MCPavlo/mirea-progs


text:
using Base.RefValue
struct PCG{A,CtrlType}
    ctrl::CtrlType
    pp::A
    zz::A
    ww::A
    δ::RefValue{Float64}
    α::RefValue{Float64}
    β::RefValue{Float64}
    η::RefValue{Float64}
    ηm::RefValue{Float64}
    err::RefValue{Float64}
end

function PCG(xx,ictrl)
    pp = similar(xx)
    zz = similar(xx)
    ww = similar(xx)
    return PCG{typeof(xx),typeof(ictrl)}(ictrl,pp,zz,ww,Ref(0.),Ref(0.),Ref(0.),Ref(0.),Ref(0.),Ref(0.))
end

function PCG(xx)
    ictrl = KrylovCtrl()
    return PCG(xx,ictrl)
end

function solve!(pcg::PCG,Mat,xx,rr,ini::Bool=false)
    header(pcg,Mat,xx,rr,ini)
    out = 0
    while (test(pcg.ctrl,pcg.err[],pcg.β[]) && out == 0)
        out = iter(pcg,Mat,xx,rr)
        output(pcg)
    end
    out != 0 && println("Exite jumped out at ",out)
    footer(pcg)
end

function header(pcg,Mat,xx,rr,ini::Bool)
    if ini
        pcg.η[] = evalT(Mat,pcg.zz,xx)
        @inbounds for i in linearindices(xx)
            rr[i] -= pcg.zz[i]
        end
    else
        @inbounds for i in linearindices(xx)
            xx[i] = zero(eltype(xx))
        end
    end
    pcg.η[] = evalP(Mat,pcg.zz,rr)
    pp = pcg.pp
    zz = pcg.zz
    @inbounds for i in linearindices(xx)
        pp[i] = zz[i]
    end
    pcg.err[] = pcg.η[]
    init(pcg.ctrl,pcg.err[])
    output(pcg)
end

function iter(pcg::PCG,Mat,xx,rr)
    pcg.δ[] = evalT(Mat,pcg.ww,pcg.pp)
    δ = pcg.δ[]
    tiny = get_tiny(pcg.ctrl)

    abs(δ) < tiny && return 1

    pcg.α[] = pcg.η[]/δ
    α = pcg.α[]
    pp = pcg.pp
    ww = pcg.ww
    @inbounds for i in linearindices(xx)
        xx[i] += α*pp[i]
        rr[i] -= α*ww[i]
    end
    pcg.ηm[] = pcg.η[]
    ηm = pcg.ηm[]
    pcg.η[]  = evalP(Mat,pcg.zz,rr)
    η = pcg.η[]
    abs(η) < tiny && return 2

    pcg.β[] = η/ηm
    β = pcg.β[]
    zz = pcg.zz
    for i in linearindices(xx)
        pp[i] = zz[i] + β*pp[i]
    end

    pcg.err[] = η
    return 0
end

function footer(pcg)
    verb = get_verb(pcg.ctrl)
    if verb >= 1
        println("PCG iterations = ",pcg.ctrl.cnt - 1)
        println(pcg.ctrl.exitval, "\t exit. Final err = ",pcg.err[]," ee = ", sqrt(abs(pcg.err[]/pcg.ctrl.err0)))
        println()
    end
end

function output(pcg::PCG)
    ctrl = pcg.ctrl
    verb = get_verb(ctrl)
    cnt = ctrl.cnt
    if cnt == 0
        if verb >= 1
            println()
            println("Initial err =",ctrl.err0)
            println("atol = ",get_abstol(ctrl),"\t","rtol = ",get_reltol(ctrl))
            verb >= 2 && println("  m,    err,    alpha,    beta,    delta  ")
        end
    else
        verb >= 2 && println(join((cnt,pcg.err[],pcg.α[],pcg.β[],pcg.δ[]),"\t"))
    end
end

function evalT(A::AbstractArray{T,2},out::AbstractVector{T2},input::AbstractVector{T2}) where {T,T2}
    A_mul_B!(out,A,input)
    δ = out⋅input
    return δ
end

function evalP(A::AbstractArray{T,2},out::AbstractVector{T2},input::AbstractVector{T2}) where {T,T2}
    δ = zero(T2)
    for i in linearindices(input)
        out[i] = input[i]/A[i,i]
        δ += out[i]*input[i]
    end
    return δ
end


text:
function transient_driver_inductionless_MHD(;t0::Float64 = 0.0, tF::Float64 = 1.0,
  model=nothing, nx = 4, Δt::Float64 = 0.1, θ::Float64 = 1.0, Re::Float64 = 10.0,
  Ha = (x) -> 10.0, fluid_dirichlet_tags = [], fluid_neumann_tags = [],
  c_w = 1.0, α=10.0,B = (x) -> VectorValue(0.0,1.0,0.0),
  magnetic_dirichlet_tags = [], magnetic_neumann_tags = [],
  magnetic_non_perfectly_conducting_walls_tag = [],
  fluid_dirichlet_conditions = (x) -> VectorValue(0.0,0.0,0.0),
  magnetic_dirichlet_conditions = (x) -> VectorValue(0.0,0.0,0.0),
  fluid_body_force = (x) -> VectorValue(0.0,0.0,0.0),
  u0 = (x) -> VectorValue(0.0,0.0,0.0), p0 = (x) -> 0.0,
  j0 = (x) -> VectorValue(0.0,0.0,0.0), φ0 = (x) -> 0.0,
  constraint_presures::NTuple{2,Bool}=(false,false), max_nl_it=10,
  usegmres = true, precond_tau = 1e-9, linesearch=BackTracking(),
  resultsfile = nothing, verbosity::Verbosity=Verbosity(1),nsubcells=1,print_order=2)

  if typeof(Ha) == typeof(10.0)
    N = (Ha*Ha)/Re
  else
    N(x) = (Ha(x)*Ha(x))/Re
  end

  # Discretization
  order = 2
  if model === nothing
    domain = (-1.0,1.0,-1.0,1.0,0.0,0.1)
    map(x) = VectorValue(sign(x[1])*(abs(x[1])*0.5)^0.5,
                        sign(x[2])*(abs(x[2])*0.5)^0.5, x[3]*sqrt(2)/2)*2/sqrt(2)

    dirichlet_tags_u = append!(collect(1:20),[23,24,25,26])
    dirichlet_tags_j = append!(collect(1:20),[23,24,25,26])

    partition=(nx,ny,3)
    model = CartesianDiscreteModel(domain,partition;isperiodic=(false,false,true))

    labels = get_face_labeling(model)
    add_tag_from_tags!(labels,"dirichlet_u",dirichlet_tags_u)
    add_tag_from_tags!(labels,"dirichlet_j",dirichlet_tags_j)
    fluid_dirichlet_tags = ["dirichlet_u"]
    magnetic_dirichlet_tags = ["dirichlet_j"]
  end

  preprocessStepOutput(verbosity,"Preprocess step (0/3): Starting preprocess")

  Vu = FESpace(model, ReferenceFE(lagrangian,VectorValue{3,Float64},order);
      conformity=:H1, dirichlet_tags=fluid_dirichlet_tags)

  if is_n_cube(model.grid_topology.polytopes[1])
    p_conformity = :L2
  else
    p_conformity = :H1
  end

  if constraint_presures[1]
    Vp = FESpace(model, ReferenceFE(lagrangian,Float64,order-1,space=:P);
    conformity=:L2, constraint=:zeromean)
  else
    Vp = FESpace(model, ReferenceFE(lagrangian,Float64,order-1,space=:P);
    conformity=:L2)
  end

  if length(magnetic_dirichlet_tags) == 0
    Vj = FESpace(model, ReferenceFE(raviart_thomas,Float64,order-1);
        conformity=:Hdiv)
  else
    Vj = FESpace(model, ReferenceFE(raviart_thomas,Float64,order-1);
        conformity=:Hdiv, dirichlet_tags=magnetic_dirichlet_tags)
  end

  if constraint_presures[2]
    Vφ = FESpace(model, ReferenceFE(lagrangian,Float64,order-1,space=:Q);
      conformity=:L2, constraint=:zeromean)
  else
    Vφ = FESpace(model, ReferenceFE(lagrangian,Float64,order-1,space=:Q);
    conformity=:L2)
  end

  U = TransientTrialFESpace(Vu,fluid_dirichlet_conditions)
  P = TransientTrialFESpace(Vp)
  J = TransientTrialFESpace(Vj,magnetic_dirichlet_conditions)
  Φ = TransientTrialFESpace(Vφ)

  Y = MultiFieldFESpace([Vu, Vp, Vj, Vφ])
  X = TransientMultiFieldFESpace([U, P, J, Φ])

  preprocessStepOutput(verbosity,"Preprocess step (1/3): Built FE spaces")

  trian = Triangulation(model)
  degree = 2*(order)
  dΩ = Measure(trian,degree)

  coord = get_physical_coordinate(trian)
  res_Ω(t,x,xt,y) = ∫(xt[1]⋅y[1])*dΩ +
    InductionlessMHD.dimensionless_residual(x, y, Re, N, B, fluid_body_force,dΩ,coord)
  jac_Ω(t,x,xt,dx,y) = InductionlessMHD.dimensionless_jacobian(x, dx, y, Re, N, B,dΩ,coord)
  jac_t(t,x,xt,dxt,y) = ∫(dxt[1]⋅y[1])*dΩ

  if length(magnetic_non_perfectly_conducting_walls_tag) == 0
    op  = TransientFEOperator(res_Ω,jac_Ω,jac_t,X,Y)
  else
    btrian_j = BoundaryTriangulation(model,tags=magnetic_non_perfectly_conducting_walls_tag)
    dΓ = Measure(btrian_j,degree)
    n = get_normal_vector(btrian_j)
    res_Γ(t,x,xt,y) = InductionlessMHD.dimensionless_conducting_wall(x, y, n, c_w, dΓ, α=α)
    jac_Γ(t,x,xt,dx,y) = InductionlessMHD.dimensionless_conducting_wall(dx, y, n, c_w, dΓ, α=α)

    res(t,x,xt,y) = res_Ω(t,x,xt,y) + res_Γ(t,x,xt,y)
    jac(t,x,xt,dx,y) = jac_Ω(t,x,xt,dx,y) + jac_Γ(t,x,xt,dx,y)
    op  = TransientFEOperator(res,jac,jac_t,X,Y)
  end

  uh0 = interpolate(u0,U(0.0))
  ph0 = interpolate(p0,P(0.0))
  jh0 = interpolate(j0,J(0.0))
  φh0 = interpolate(φ0,Φ(0.0))
  xh0 = interpolate([uh0,ph0,jh0,φh0],X(0.0))

  preprocessStepOutput(verbosity,"Preprocess step (2/3): Defined triangulation and formulation")

  if usegmres
    nls = NLSolver(GmresSolver(verbose=linearSolverOutput(verbosity), preconditioner=ilu,τ=precond_tau);
      show_trace=nonlinearSolverOutput(verbosity), method=:newton, linesearch=linesearch, iterations=max_nl_it)
  else
    nls = NLSolver(;
      show_trace=nonlinearSolverOutput(verbosity), method=:newton, linesearch=linesearch, iterations=max_nl_it)
  end
  odes = ThetaMethod(nls,Δt,θ)
  solver = TransientFESolver(odes)

  preprocessStepOutput(verbosity,"Preprocess step (3/3): Configured solver. Starting to solve.")

  xh_t = solve(solver,op,xh0,t0,tF)

  if resultsfile ≠ nothing
    startPVD(resultsfile)
    write_timestep(resultsfile,t0,trian,nsubcells=nsubcells, order=print_order,
        cellfields=["uh"=>uh0, "ph"=>ph0, "jh"=>jh0, "phih"=>φh0])
    it = 0
    timeStepOutput(verbosity,Δt,0.0,it)
    for (xh, t) in xh_t
      it += 1
      timeStepOutput(verbosity,Δt,t,it)

      uh, ph, jh, φh = xh
      write_timestep(resultsfile,t,trian,nsubcells=nsubcells, order=print_order,
        cellfields=["uh"=>uh, "ph"=>ph, "jh"=>jh, "phih"=>φh])
    end
    closePVD(resultsfile)
    return (xh_t, trian, dΩ)

  else
    results = []
    it = 0
    timeStepOutput(verbosity,Δt,0.0,it)
    for (xh, t) in xh_t
      it += 1
      timeStepOutput(verbosity,Δt,t,it)
      results = [results...,xh]
    end
    return (results, trian, dΩ)
  end
end