text:
const keycodes =
Dict(
     "\eOA"                   => Keystroke("\eOA",                   :up,               false,  false,  false),
     "\e[1;2A"                => Keystroke("\e[1;2A",                :up,               false,  false,  true ),
     "\e[1;3A"                => Keystroke("\e[1;3A",                :up,               true,   false,  false),
     "\e[1;5A"                => Keystroke("\e[1;5A",                :up,               false,  true,   false),
     "\e[1;6A"                => Keystroke("\e[1;6A",                :up,               false,  true,   true ),
     "\e[1;9A"                => Keystroke("\e[1;9A",                :up,               true,   false,  false),
     "\e[1;10A"               => Keystroke("\e[1;10A",               :up,               true,   false,  true ),
     "\eOB"                   => Keystroke("\eOB",                   :down,             false,  false,  false),
     "\e[1;2B"                => Keystroke("\e[1;2B",                :down,             false,  false,  true ),
     "\e[1;3B"                => Keystroke("\e[1;3B",                :down,             true,   false,  false),
     "\e[1;5B"                => Keystroke("\e[1;5B",                :down,             false,  true,   false),
     "\e[1;6B"                => Keystroke("\e[1;6B",                :down,             false,  true,   true ),
     "\e[1;9B"                => Keystroke("\e[1;9B",                :down,             true,   false,  false),
     "\e[1;10B"               => Keystroke("\e[1;10B",               :down,             true,   false,  true ),
     "\eOC"                   => Keystroke("\eOC",                   :right,            false,  false,  false),
     "\e[1;2C"                => Keystroke("\e[1;2C",                :right,            false,  false,  true ),
     "\e[1;3C"                => Keystroke("\e[1;3C",                :right,            true,   false,  false),
     "\e[1;5C"                => Keystroke("\e[1;5C",                :right,            false,  true,   false),
     "\e[1;6C"                => Keystroke("\e[1;6C",                :right,            false,  true,   true ),
     "\e[1;9C"                => Keystroke("\e[1;9C",                :right,            true,   false,  false),
     "\e[1;10C"               => Keystroke("\e[1;10C",               :right,            true,   false,  true ),
     "\eOD"                   => Keystroke("\eOD",                   :left,             false,  false,  false),
     "\e[1;2D"                => Keystroke("\e[1;2D",                :left,             false,  false,  true ),
     "\e[1;3D"                => Keystroke("\e[1;3D",                :left,             true,   false,  false),
     "\e[1;5D"                => Keystroke("\e[1;5D",                :left,             false,  true,   false),
     "\e[1;6D"                => Keystroke("\e[1;6D",                :left,             false,  true,   true ),
     "\e[1;9D"                => Keystroke("\e[1;9D",                :left,             true,   false,  false),
     "\e[1;10D"               => Keystroke("\e[1;10D",               :left,             true,   false,  true ),
     "\e[A"                   => Keystroke("\e[A",                   :up,               false,  false,  false),
     "\e\e[A"                 => Keystroke("\e\e[A",                 :up,               true,   false,  false),
     "\e[B"                   => Keystroke("\e[B",                   :down,             false,  false,  false),
     "\e\e[B"                 => Keystroke("\e\e[B",                 :down,             true,   false,  false),
     "\e[C"                   => Keystroke("\e[C",                   :right,            false,  false,  false),
     "\e\e[C"                 => Keystroke("\e\e[C",                 :right,            true,   false,  false),
     "\e[D"                   => Keystroke("\e[D",                   :left,             false,  false,  false),
     "\e\e[D"                 => Keystroke("\e\e[D",                 :left,             true,   false,  false),
     "\e[H"                   => Keystroke("\e[H",                   :home,             false,  false,  false),
     "\e[1;2H"                => Keystroke("\e[1;2H",                :home,             false,  false,  true ),
     "\e[1;5H"                => Keystroke("\e[1;5H",                :home,             false,  true,   false),
     "\e[1;9H"                => Keystroke("\e[1;9H",                :home,             true,   false,  false),
     "\e[1;10H"               => Keystroke("\e[1;10H",               :home,             true,   false,  true ),
     "\e[1;13H"               => Keystroke("\e[1;13H",               :home,             true,   true,   false),
     "\e[F"                   => Keystroke("\e[F",                   :end,              false,  false,  false),
     "\e[1;2F"                => Keystroke("\e[1;2F",                :end,              false,  false,  true ),
     "\e[1;5F"                => Keystroke("\e[1;5F",                :end,              false,  true,   false),
     "\e[1;9F"                => Keystroke("\e[1;9F",                :end,              true,   false,  false),
     "\e[1;10F"               => Keystroke("\e[1;10F",               :end,              true,   false,  true ),
     "\e[1;13F"               => Keystroke("\e[1;13F",               :end,              true,   true,   false),
     "\eOP"                   => Keystroke("\eOP",                   :F1,               false,  false,  false),
     "\eOQ"                   => Keystroke("\eOQ",                   :F2,               false,  false,  false),
     "\eOR"                   => Keystroke("\eOR",                   :F3,               false,  false,  false),
     "\eOS"                   => Keystroke("\eOS",                   :F4,               false,  false,  false),
     "\e[15~"                 => Keystroke("\e[15~",                 :F5,               false,  false,  false),
     "\e[17~"                 => Keystroke("\e[17~",                 :F6,               false,  false,  false),
     "\e[18~"                 => Keystroke("\e[18~",                 :F7,               false,  false,  false),
     "\e[19~"                 => Keystroke("\e[19~",                 :F8,               false,  false,  false),
     "\e[20~"                 => Keystroke("\e[20~",                 :F9,               false,  false,  false),
     "\e[21~"                 => Keystroke("\e[21~",                 :F10,              false,  false,  false),
     "\e[23~"                 => Keystroke("\e[23~",                 :F11,              false,  false,  false),
     "\e[24~"                 => Keystroke("\e[24~",                 :F12,              false,  false,  false),
     "\e[1;2P"                => Keystroke("\e[1;2P",                :F1,               false,  false,  true),
     "\e[1;2Q"                => Keystroke("\e[1;2Q",                :F2,               false,  false,  true),
     "\e[1;2R"                => Keystroke("\e[1;2R",                :F3,               false,  false,  true),
     "\e[1;2S"                => Keystroke("\e[1;2S",                :F4,               false,  false,  true),
     "\e[15;2~"               => Keystroke("\e[15;2~",               :F5,               false,  false,  true),
     "\e[17;2~"               => Keystroke("\e[17;2~",               :F6,               false,  false,  true),
     "\e[18;2~"               => Keystroke("\e[18;2~",               :F7,               false,  false,  true),
     "\e[19;2~"               => Keystroke("\e[19;2~",               :F8,               false,  false,  true),
     "\e[20;2~"               => Keystroke("\e[20;2~",               :F9,               false,  false,  true),
     "\e[21;2~"               => Keystroke("\e[21;2~",               :F10,              false,  false,  true),
     "\e[23;2~"               => Keystroke("\e[23;2~",               :F11,              false,  false,  true),
     "\e[24;2~"               => Keystroke("\e[24;2~",               :F12,              false,  false,  true),
     "\e[1;3P"                => Keystroke("\e[1;3P",                :F1,               true,   false,  false),
     "\e[1;3Q"                => Keystroke("\e[1;3Q",                :F2,               true,   false,  false),
     "\e[1;3R"                => Keystroke("\e[1;3R",                :F3,               true,   false,  false),
     "\e[1;3S"                => Keystroke("\e[1;3S",                :F4,               true,   false,  false),
     "\e[15;3~"               => Keystroke("\e[15;3~",               :F5,               true,   false,  false),
     "\e[17;3~"               => Keystroke("\e[17;3~",               :F6,               true,   false,  false),
     "\e[18;3~"               => Keystroke("\e[18;3~",               :F7,               true,   false,  false),
     "\e[19;3~"               => Keystroke("\e[19;3~",               :F8,               true,   false,  false),
     "\e[20;3~"               => Keystroke("\e[20;3~",               :F9,               true,   false,  false),
     "\e[21;3~"               => Keystroke("\e[21;3~",               :F10,              true,   false,  false),
     "\e[23;3~"               => Keystroke("\e[23;3~",               :F11,              true,   false,  false),
     "\e[24;3~"               => Keystroke("\e[24;3~",               :F12,              true,   false,  false),
     "\e[1;5P"                => Keystroke("\e[1;5P",                :F1,               false,  true,   false),
     "\e[1;5Q"                => Keystroke("\e[1;5Q",                :F2,               false,  true,   false),
     "\e[1;5R"                => Keystroke("\e[1;5R",                :F3,               false,  true,   false),
     "\e[1;5S"                => Keystroke("\e[1;5S",                :F4,               false,  true,   false),
     "\e[15;5~"               => Keystroke("\e[15;5~",               :F5,               false,  true,   false),
     "\e[17;5~"               => Keystroke("\e[17;5~",               :F6,               false,  true,   false),
     "\e[18;5~"               => Keystroke("\e[18;5~",               :F7,               false,  true,   false),
     "\e[19;5~"               => Keystroke("\e[19;5~",               :F8,               false,  true,   false),
     "\e[20;5~"               => Keystroke("\e[20;5~",               :F9,               false,  true,   false),
     "\e[21;5~"               => Keystroke("\e[21;5~",               :F10,              false,  true,   false),
     "\e[23;5~"               => Keystroke("\e[23;5~",               :F11,              false,  true,   false),
     "\e[24;5~"               => Keystroke("\e[24;5~",               :F12,              false,  true,   false),
     "\eOn"                   => Keystroke("\eOn",                   :keypad_dot,       false,  false,  false),
     "\eOM"                   => Keystroke("\eOM",                   :keypad_enter,     false,  false,  false),
     "\eOj"                   => Keystroke("\eOj",                   :keypad_asterisk,  false,  false,  false),
     "\eOk"                   => Keystroke("\eOk",                   :keypad_plus,      false,  false,  false),
     "\eOm"                   => Keystroke("\eOm",                   :keypad_minus,     false,  false,  false),
     "\eOo"                   => Keystroke("\eOo",                   :keypad_slash,     false,  false,  false),
     "\eOX"                   => Keystroke("\eOX",                   :keypad_equal,     false,  false,  false),
     "\eOp"                   => Keystroke("\eOp",                   :keypad_0,         false,  false,  false),
     "\eOq"                   => Keystroke("\eOq",                   :keypad_1,         false,  false,  false),
     "\eOr"                   => Keystroke("\eOr",                   :keypad_2,         false,  false,  false),
     "\eOs"                   => Keystroke("\eOs",                   :keypad_3,         false,  false,  false),
     "\eOt"                   => Keystroke("\eOt",                   :keypad_4,         false,  false,  false),
     "\eOu"                   => Keystroke("\eOu",                   :keypad_5,         false,  false,  false),
     "\eOv"                   => Keystroke("\eOv",                   :keypad_6,         false,  false,  false),
     "\eOw"                   => Keystroke("\eOw",                   :keypad_7,         false,  false,  false),
     "\eOx"                   => Keystroke("\eOx",                   :keypad_8,         false,  false,  false),
     "\eOy"                   => Keystroke("\eOy",                   :keypad_9,         false,  false,  false),
     "\e[3~"                  => Keystroke("\e[3~",                  :delete,           false,  false,  false),
     "\e[5~"                  => Keystroke("\e[5~",                  :pageup,           false,  false,  false),
     "\e\e[5~"                => Keystroke("\e\e[5~",                :pageup,           true,   false,  false),
     "\e[6~"                  => Keystroke("\e[6~",                  :pagedown,         false,  false,  false),
     "\e\e[6~"                => Keystroke("\e\e[6~",                :pagedown,         true,   false,  false),
     "\e"*string(Char(0x153)) => Keystroke("\e"*string(Char(0x153)), :pageup,           true,   false,  false),
     "\e"*string(Char(0x152)) => Keystroke("\e"*string(Char(0x152)), :pagedown,         true,   false,  false),
     "\e[Z"                   => Keystroke("\e[Z",                   :tab,              false,  false,   true),
)

const nocharval = typemax(UInt32)


text:
using NeuralPDE, Flux, ModelingToolkit, GalacticOptim, Optim, DiffEqFlux
import ModelingToolkit: Interval, infimum, supremum, Plots
using Pkg

@parameters x y
@variables u(..)
Dxx = Differential(x)^2
Dyy = Differential(y)^2

# 2D PDE
eq  = Dxx(u(x,y)) + Dyy(u(x,y)) ~ 0

# Boundary conditions
bcs = [u(0,y) ~ 10., u(2,y) ~ 0.,
       u(x,0) ~ 0.0, u(x,2) ~ 0.]
# Space and time domains
domains = [x ∈ Interval(0.0,2.0),
           y ∈ Interval(0.0,2.0)]

# Neural network
dim = 2 # number of dimensions
chain = FastChain(FastDense(dim,16,Flux.σ),FastDense(16,16,Flux.σ),FastDense(16,1))
# Initial parameters of Neural network
initθ = Float64.(DiffEqFlux.initial_params(chain))

# Discretization
dx = 0.05
discretization = PhysicsInformedNN(chain,GridTraining(dx),init_params =initθ)

@named pde_system = PDESystem(eq,bcs,domains,[x,y],[u(x, y)])
prob = discretize(pde_system,discretization)

#Optimizer
opt = Optim.BFGS()
losses=[]
#Callback function
cb = function (p,l;ilosses=losses)
    println("Current loss is: $l")
    append!(ilosses,l)
    return false

end

res = GalacticOptim.solve(prob, opt, cb = cb, maxiters=1000)
phi = discretization.phi

using Plots

xs,ys = [infimum(d.domain):dx/10:supremum(d.domain) for d in domains]

u_predict = reshape([first(phi([x,y],res.minimizer)) for x in xs for y in ys],(length(xs),length(ys)))

plot(ys, xs, (u_predict), linetype=:contourf,title = "Solución NN")

Plots.plot(losses,label="Pérdida",ylabel="𝕃",xlabel="Iterción entrenamiento")
losses

plot(ys, xs, (u_predict .- Space), linetype=:contourf,title = "Diferencia NN")

using Statistics
mean((u_predict .- Space).^2)
mean((u_predict .- Space)./u_predict)

ext: jl

max_stars_repo_name: munozariasjm/Laplace-and-Julia

max_issues_repo_name: munozariasjm/Laplace-and-Julia

max_forks_repo_name: munozariasjm/Laplace-and-Julia


text:
type BurgerModel <: NonlinearSpectralModel
  d :: Float64
end

type BurgerData <: SpectralDataField
  n :: Int64
  x :: Array{Float64,2}
end

export BurgerModel, BurgerData
include("trunes.jl")

include("timegradient.jl")

function +(x:: BurgerData, y :: BurgerData)
  BurgerData(x.n,x.x+y.x)
end
function *(x:: BurgerData, y :: Float64)
  BurgerData(x.n,x.x*y)
end
function *(y :: Float64,x:: BurgerData )
  BurgerData(x.n,x.x*y)
end


text:
module Matching
using Random, Statistics

using UnPack
using Printf
using Erdos

export run_bp

getref(v::Vector, i::Integer) = pointer(v, i)

include("matching_bp.jl")

end #module


text:
using Random
using LinearAlgebra
using LinearAlgebra.BLAS: gemv!

"""
    reinitialize!(a::Arnoldi, j::Int = 0) → a

Generate a random `j+1`th column orthonormal against V[:,1:j]

Returns true if the column is a valid new basis vector.
Returns false if the column is numerically in the span of the previous vectors.
"""
function reinitialize!(arnoldi::Arnoldi{T}, j::Int = 0) where {T}
    V = arnoldi.V
    v = view(V, :, j+1)

    # Generate a new random column
    rand!(v)

    # Norm before orthogonalization
    rnorm = norm(v)

    # Just normalize, don't orthogonalize
    if j == 0
        v ./= rnorm
        return true
    end

    # Constant used by ARPACK.
    η = √2 / 2
    Vprev = view(V, :, 1:j)

    # Orthogonalize: h = Vprev' * v, v ← v - Vprev * Vprev' * v = v - Vprev * h
    h = Vprev' * v
    gemv!('N', -one(T), Vprev, h, one(T), v)

    # Norm after orthogonalization
    wnorm = norm(v)

    # Reorthogonalize once
    if wnorm < η * rnorm
        rnorm = wnorm
        mul!(h, Vprev', v)
        gemv!('N', -one(T), Vprev, h, one(T), v)
        wnorm = norm(v)
    end

    if wnorm ≤ η * rnorm
        # If we have to reorthogonalize thrice, then we're just numerically in the span
        return false
    else
        # Otherwise we just normalize this new basis vector
        v ./= wnorm
        return true
    end
end

"""
    orthogonalize!(arnoldi, j) → Bool

Orthogonalize arnoldi.V[:, j+1] against arnoldi.V[:, 1:j].

Returns true if the column is a valid new basis vector.
Returns false if the column is numerically in the span of the previous vectors.
"""
function orthogonalize!(arnoldi::Arnoldi{T}, j::Integer) where {T}
    V = arnoldi.V
    H = arnoldi.H

    # Constant used by ARPACK.
    η = √2 / 2

    Vprev = view(V, :, 1:j)
    v = view(V, :, j+1)
    h = view(H, 1:j, j)

    # Norm before orthogonalization
    rnorm = norm(v)

    # Orthogonalize: h = Vprev' * v, v ← v - Vprev * Vprev' * v = v - Vprev * h
    mul!(h, Vprev', v)
    gemv!('N', -one(T), Vprev, h, one(T), v)

    # Norm after orthogonalization
    wnorm = norm(v)

    # Reorthogonalize once
    if wnorm < η * rnorm
        rnorm = wnorm
        correction = Vprev' * v
        gemv!('N', -one(T), Vprev, correction, one(T), v)
        h .+= correction
        wnorm = norm(v)
    end

    if wnorm ≤ η * rnorm
        # If we have to reorthogonalize thrice, then we're just numerically in the span
        H[j+1,j] = zero(T)
        return false
    else
        # Otherwise we just normalize this new basis vector
        H[j+1,j] = wnorm
        v ./= wnorm
        return true
    end
end

"""
    iterate_arnoldi!(A, arnoldi, from:to) → arnoldi

Perform Arnoldi from `from` to `to`.
"""
function iterate_arnoldi!(A, arnoldi::Arnoldi{T}, range::UnitRange{Int}) where {T}
    V, H = arnoldi.V, arnoldi.H

    for j = range
        # Generate a new column of the Krylov subspace
        mul!(view(V, :, j+1), A, view(V, :,j))

        # Orthogonalize it against the other columns
        # If V[:,j+1] is in the span of V[:,1:j], then we generate a new
        # vector. If j == n, then obviously we cannot find a new orthogonal
        # column V[:,j+1].
        if orthogonalize!(arnoldi, j) === false && j != size(V, 1)
            reinitialize!(arnoldi, j)
        end
    end

    return arnoldi
end


text:
function check_grid_sell!(config, trade_grid, price_str, client, bot_path)
    #
    ## Test Bot?
    test_bot = config["testing"] == "1" ? true : false
    info = trade_grid[price_str]

    #
    ##
    if test_bot
        ticker, current_price = Pinguu.get_current_ticker(client, config, use_api=false)
        if current_price >= parse(Float64, info["order"]["price"])
            tmp = Dict(
                "status" => client.ORDER_STATUS_FILLED,
                "price" => info["order"]["price"],
                "time" => string(now()),
                "timeInForce" => client.TIME_IN_FORCE_GTC,
                "orderId" => 42,
                "executedQty" => info["order"]["origQty"],
                "clientOrderId" =>"2Y5skq9An12HbHQUDkFA9T",
                "symbol" => config["symbol"],
                "cummulativeQuoteQty" => round(parse(Float64, info["order"]["price"])*info["order"]["origQty"], digits=config["sell_precision"]),
                "origQty" =>info["order"]["origQty"],
                "side" =>client.SIDE_SELL,
                "type" =>"LIMIT",
                "test" => "true"
            )
        else
            tmp = Dict(
                "status" => client.ORDER_STATUS_NEW,
                "price" => info["order"]["price"],
                "time" => string(now()),
                "timeInForce" => client.TIME_IN_FORCE_GTC,
                "orderId" => 42,
                "executedQty" => "0.00",
                "clientOrderId" =>"2Y5skq9An12HbHQUDkFA9T",
                "symbol" => config["symbol"],
                "cummulativeQuoteQty" => "0.00",
                "origQty" =>info["order"]["origQty"],
                "side" =>client.SIDE_SELL,
                "type" =>"LIMIT",
                "test" => "true"
            )
        end
    else
        tmp = try client.get_order(
                symbol=config["symbol"],
                orderId=info["order"]["orderId"]
            )
        catch
            return
        end
    end
    ##
    #

    #
    ## Store changes
    if tmp["status"] != info["order"]["status"]
        trade_grid[price_str]["order"] = tmp
        open(joinpath(bot_path, "trade_grid.json"), "w") do f
            JSON.print(f, trade_grid, 4)
        end
    end

    #
    ## Order filled
    if tmp["status"] == client.ORDER_STATUS_FILLED
        closed_order = deepcopy(trade_grid[price_str])
        next_gridpoints = Pinguu.get_next_gridpoints(trade_grid, price_str)
        new_buy_price = next_gridpoints["BUY"]
        new_buy = Dict(
            "status" => "place",
            "side" => client.SIDE_BUY,
            "type" => "normal",
            "price" => new_buy_price,
            "qty" => tmp["executedQty"]
        )
        new_current = Dict("status" => "current")

        #
        ## Place new SELL and CURRENT
        trade_grid[new_buy_price] = new_buy
        trade_grid[price_str] = new_current

        #
        ## Freeze all ongoing orders
        for (k,v) in trade_grid
            if v["status"] == "check"
                trade_grid[k]["status"] = "freeze"
            end
        end

        #
        ## Create next SELL
        if haskey(next_gridpoints, "SELL")
            next_sell_price = next_gridpoints["SELL"]
            if trade_grid[next_sell_price]["status"] == "wait"
                trade_grid[next_sell_price]["status"] = "place"
            elseif trade_grid[next_sell_price]["status"] in ["frozen", "freeze"]
                trade_grid[next_sell_price]["status"] = "defrost"
            end
        end
        #
        ## Create closed_order file
        open(joinpath(bot_path, "temp/new_closed_" * string(now()) * ".json"), "w") do f
            JSON.print(f, closed_order, 4)
        end
        #
        ## Update grid file
        open(joinpath(bot_path, "trade_grid.json"), "w") do f
            JSON.print(f, trade_grid, 4)
        end
    end
end
export check_grid_sell!


text:
#
# foundations.jl -
#
# Sub-module exporting types and methods needed to extend or implement
# LazyAlgebra mappings.
#
#-------------------------------------------------------------------------------
#
# This file is part of LazyAlgebra (https://github.com/emmt/LazyAlgebra.jl)
# released under the MIT "Expat" license.
#
# Copyright (c) 2017-2021 Éric Thiébaut.
#

"""
    using LazyAlgebra.Foundations

imports types and methods that may be useful to extend or implement
`LazyAlgebra` mappings.

"""
module Foundations

using ..LazyAlgebra

for sym in (Symbol("@callable"),
            :Adjoint,
            :AdjointInverse,
            :DiagonalMapping,
            :DiagonalType,
            :Direct,
            :Endomorphism,
            :Inverse,
            :InverseAdjoint,
            :Linear,
            :LinearType,
            :Morphism,
            :MorphismType,
            :NonDiagonalMapping,
            :NonLinear,
            :NonSelfAdjoint,
            :Operations,
            :SelfAdjoint,
            :SelfAdjointType,
            :axpby_yields_zero,
            :axpby_yields_y,
            :axpby_yields_my,
            :axpby_yields_by,
            :axpby_yields_x,
            :axpby_yields_xpy,
            :axpby_yields_xmy,
            :axpby_yields_xpby,
            :axpby_yields_mx,
            :axpby_yields_ymx,
            :axpby_yields_mxmy,
            :axpby_yields_bymx,
            :axpby_yields_ax,
            :axpby_yields_axpy,
            :axpby_yields_axmy,
            :axpby_yields_axpby,
            :multiplier_type,
            :multiplier_floatingpoint_type,
            :promote_multiplier)
    @eval begin
        import ..LazyAlgebra: $sym
        export $sym
    end
end

end # module Foundations


text:
module CommunalHelperConnectedSolidExtension
using ..Ahorn, Maple

@mapdef Entity "CommunalHelper/SolidExtension" SolidExtension(
			x::Integer, y::Integer,
			width::Integer=16, height::Integer=16)

const placements = Ahorn.PlacementDict(
    "Connected Solid Extension (Communal Helper)" => Ahorn.EntityPlacement(
        SolidExtension,
		"rectangle"
    )
)

Ahorn.minimumSize(entity::SolidExtension) = 16, 16
Ahorn.resizable(entity::SolidExtension) = true, true

function Ahorn.selection(entity::SolidExtension)
    x, y = Ahorn.position(entity)

    width = Int(get(entity.data, "width", 8))
    height = Int(get(entity.data, "height", 8))

	return Ahorn.Rectangle(x, y, width, height)
end

const block = "objects/CommunalHelper/connectedZipMover/extension_outline"

const connectTo = [
                  "CommunalHelper/SolidExtension",
                  "CommunalHelper/ConnectedZipMover",
                  "CommunalHelper/ConnectedSwapBlock",
                  "CommunalHelper/ConnectedMoveBlock"
                  ]

# Gets rectangles from Zip Mover Extensions & Zip Movers
function getZipMoverRectangles(room::Maple.Room)
    entities = filter(e -> e.name in connectTo, room.entities)
    rects = []

    for e in entities
        push!(rects, Ahorn.Rectangle(
            Int(get(e.data, "x", 0)),
            Int(get(e.data, "y", 0)),
            Int(get(e.data, "width", 8)),
            Int(get(e.data, "height", 8))
        ))
    end

    return rects
end

# Checks for collision with an array of rectangles at specified tile position
function notAdjacent(entity::SolidExtension, ox, oy, rects)
    x, y = Ahorn.position(entity)
    rect = Ahorn.Rectangle(x + ox + 4, y + oy + 4, 1, 1)

    for r in rects
        if Ahorn.checkCollision(r, rect)
            return false
        end
    end

    return true
end

function Ahorn.renderAbs(ctx::Ahorn.Cairo.CairoContext, entity::SolidExtension, room::Maple.Room)
    rects = getZipMoverRectangles(room)

    x, y = Ahorn.position(entity)

    width = Int(get(entity.data, "width", 32))
    height = Int(get(entity.data, "height", 32))

    tileWidth = ceil(Int, width / 8)
    tileHeight = ceil(Int, height / 8)

    rect = Ahorn.Rectangle(x, y, width, height)
	if !(rect in rects)
        push!(rects, rect)
    end

    for i in 1:tileWidth, j in 1:tileHeight
        drawX, drawY = (i - 1) * 8, (j - 1) * 8

        closedLeft = !notAdjacent(entity, drawX - 8, drawY, rects)
        closedRight = !notAdjacent(entity, drawX + 8, drawY, rects)
        closedUp = !notAdjacent(entity, drawX, drawY - 8, rects)
        closedDown = !notAdjacent(entity, drawX, drawY + 8, rects)
        completelyClosed = closedLeft && closedRight && closedUp && closedDown

        if completelyClosed
            if notAdjacent(entity, drawX + 8, drawY + 8, rects)
                # down right
                Ahorn.drawImage(ctx, block, x + drawX + 7, y + drawY + 7, 0, 0, 8, 8)

            elseif notAdjacent(entity, drawX - 8, drawY + 8, rects)
                # down left
                Ahorn.drawImage(ctx, block, x + drawX - 7, y + drawY + 7, 16, 0, 8, 8)

            elseif notAdjacent(entity, drawX + 8, drawY - 8, rects)
                # up right
                Ahorn.drawImage(ctx, block, x + drawX + 7, y + drawY - 7, 0, 16, 8, 8)

            elseif notAdjacent(entity, drawX - 8, drawY - 8, rects)
                # up left
                Ahorn.drawImage(ctx, block, x + drawX - 7, y + drawY - 7, 16, 16, 8, 8)

            end

		else
            if closedLeft && closedRight && !closedUp && closedDown
                Ahorn.drawImage(ctx, block, x + drawX, y + drawY, 8, 0, 8, 8)

            elseif closedLeft && closedRight && closedUp && !closedDown
                Ahorn.drawImage(ctx, block, x + drawX, y + drawY, 8, 16, 8, 8)

            elseif closedLeft && !closedRight && closedUp && closedDown
                Ahorn.drawImage(ctx, block, x + drawX, y + drawY, 16, 8, 8, 8)

            elseif !closedLeft && closedRight && closedUp && closedDown
                Ahorn.drawImage(ctx, block, x + drawX, y + drawY, 0, 8, 8, 8)

            elseif closedLeft && !closedRight && !closedUp && closedDown
                Ahorn.drawImage(ctx, block, x + drawX, y + drawY, 16, 0, 8, 8)

            elseif !closedLeft && closedRight && !closedUp && closedDown
                Ahorn.drawImage(ctx, block, x + drawX, y + drawY, 0, 0, 8, 8)

            elseif !closedLeft && closedRight && closedUp && !closedDown
                Ahorn.drawImage(ctx, block, x + drawX, y + drawY, 0, 16, 8, 8)

            elseif closedLeft && !closedRight && closedUp && !closedDown
                Ahorn.drawImage(ctx, block, x + drawX, y + drawY, 16, 16, 8, 8)
            end
        end

    end
end

end

max_stars_repo_name: FlynnSC/CommunalHelper

max_issues_repo_name: FlynnSC/CommunalHelper

max_forks_repo_name: FlynnSC/CommunalHelper


text:
# This is data_import.jl
#
# This file contains functions to import different data types.
#
# Author: Marcel Thielmann, 05/2021

export Screenshot_To_GeoData, Screenshot_To_CartData, Screenshot_To_UTMData

# import CSV data using standard library functions
# here we assume that the data is indeed comma separated and that comments are preceded with a "#"

function ReadCSV_LatLon(filename::AbstractString,DepthCon::AbstractString)
    # import data from file with coordinates given in lat/lon/depth format and additional data given in additional columns
    # the idea here is to assign the data to a structure of the type GeoData which will then be used for further processing
    data,hdr = readdlm(filename,',', Float64,'\n'; header=true, skipblanks=true, comments=true, comment_char='#')

    # initialize array of structures to store the data
    # while doing so, separate the unit from the variable name
    ndata   = size(data,1) # number of entries
    nfields = size(data,2) # number of fields

    # declare some variables as local, otherwise they are not known outside of the following for loop
    local LonData
    local LatData
    local DepthData
    local vals_range
    vals_range = zeros(Int64,nfields-3)
    ivals = 1;
    # get the fields for lon/lat/depth
    for ifield = 1:nfields
        if occursin("lon",hdr[ifield])
            lon_ind = ifield;
            varname = GetVariableName(hdr[ifield])# get variable name
            varunit = GetVariableUnit(hdr[ifield])# get variable unit
            LonData = data[1:end,ifield]
        elseif occursin("lat",hdr[ifield])
            lat_ind = ifield;
            varname = GetVariableName(hdr[ifield])# get variable name
            varunit = GetVariableUnit(hdr[ifield])# get variable unit
            LatData = data[1:end,ifield]
        elseif occursin("depth",hdr[ifield])
            # ISSUE: WE DEFINE DEPTH AS NEGATIVE, BUT HOW DO WE SET THAT?
            # WE COULD ADD A FLAG THAT INDICATES THE DEPTH CONVENTION AND
            # TREAT IT ACCORDINGLY
            depth_ind = ifield;
            varname = GetVariableName(hdr[ifield])# get variable name
            varunit = GetVariableUnit(hdr[ifield])# get variable unit

            # take care of positive or negative convection for depth (here we use negative)
            if cmp(DepthCon,"positive")==0 # if depth is given as positive values, convert to negative
                DepthData = -1*data[1:end,ifield]
            elseif cmp(DepthCon,"negative")==0
                DepthData = data[1:end,ifield]
            else # default behaviour assumes that dpeth is negative
                DepthData = data[1:end,ifield]
            end

            # if depth is given in m, convert to km
            if cmp(varunit,"m")==0
                DepthData = DepthData./1e3;
            end

        else
            vals_range[ivals] = ifield
            ivals = ivals+1
        end
    end

    # create named tuple for additional data
    tmp_hdr  = hdr[vals_range];
    tmp_data = data[1:end,vals_range];

    nhdr = size(tmp_hdr,1)
    tmp_vec = Vector{Vector{Float64}}(undef, nhdr) # this is used for later tuple creation, I haven't found a better way around

    for ihdr = 1:nhdr

        # take care of the header strings
        varname = GetVariableName(tmp_hdr[ihdr])# get variable name
        varunit = GetVariableUnit(tmp_hdr[ihdr])# get variable unit
        if cmp(varunit,"%")==0
            tmp_hdr[ihdr] = string(varname,"_percentage")
        else
            tmp_hdr[ihdr] = string(varname,"_",varunit)
        end

        # take care of the matrix columns
        tmp_vec[ihdr] = tmp_data[1:end,ihdr];
    end

    hdr_tpl  = Tuple(Symbol(x) for x in tmp_hdr) # convert header to tuple
    data_tpl = Tuple.(tmp_vec for i in size(tmp_vec,1)) # convert data to tuple
    tmp = NamedTuple{hdr_tpl}(data_tpl)

    println(typeof(tmp))

    # initialize data structure
    importdata = GeoData(LonData,LatData,DepthData,tmp)

    # assign data to output
    return importdata

end

function GetVariableName(inputstring::SubString{String})
    # convert input to normal String
    inputstring = String(inputstring)
    # assume that if the string contains a unit, it is given in brackets (),[],{}
    indfirst = nothing
    iloop     = 1
    str2find = ["(","[","{"]
    # find first occurence of one of the brackets
    while isnothing(indfirst)
        indfirst = findfirst(str2find[iloop],inputstring)
        iloop = iloop + 1
        if iloop>length(str2find)
            break
        end
    end

    # either return the whole inputstring or only the part before the unit
    if isnothing(indfirst)
        return inputstring
    else
        indfirst = indfirst[1]-1
        return inputstring[1:indfirst]
    end
end

function GetVariableUnit(inputstring::SubString{String})
    # convert input to normal String
    inputstring = String(inputstring)
    # assume that if the string contains a unit, it is given in brackets (),[],{}
    indfirst = nothing
    iloop     = 1;
    firststr2find = ["(","[","{"]
    laststr2find = [")","]","}"]
    while isnothing(indfirst)
        indfirst = findfirst(firststr2find[iloop],inputstring)
        iloop = iloop + 1
        if iloop>length(firststr2find)
            break
        end
    end

    if isnothing(indfirst)
        return "none"
    else
        indlast = findfirst(laststr2find[iloop-1],inputstring)
        indfirst = indfirst[1]+1
        indlast = indlast[1]-1
        return inputstring[indfirst:indlast]
    end

end

"""
    Screenshot_To_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, Cartesian=false, UTM=false, UTMzone, isnorth=true)

Take a screenshot of Georeferenced image either a `lat/lon`, `x,y` (if `Cartesian=true`) or in UTM coordinates (if `UTM=true`) at a given depth or along profile and converts it to a `GeoData`, `CartData` or `UTMData` struct, which can be saved to Paraview

The lower left and upper right coordinates of the image need to be specified in tuples of `(lon,lat,depth)` or `(UTM_ew, UTM_ns, depth)`, where `depth` is negative in the Earth (and in km).

The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.

*Note*: if your data is in `UTM` coordinates you also need to provide the `UTMzone` and whether we are on the northern hemisphere or not (`isnorth`).
"""
function Screenshot_To_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, Cartesian=false, UTM=false, UTMzone=nothing, isnorth=true)

    img         =   load(filename)      # load image

    # Define lon/lat/depth of lower left corner

    # try to determine if this is a horizontal profile or not
    if abs(Corner_UpperRight[3]-Corner_LowerLeft[3])>0.0
        DepthProfile = true
    else
        DepthProfile = false
    end

    # We should be able to either define 4 corners or only 2 and reconstruct the other two from the
    if isnothing(Corner_LowerRight) || isnothing(Corner_UpperLeft)
        if DepthProfile
            Corner_LowerRight  = (Corner_UpperRight[1], Corner_UpperRight[2], Corner_LowerLeft[3])
            Corner_UpperLeft   = (Corner_LowerLeft[1],  Corner_LowerLeft[2], Corner_UpperRight[3])
        else
            Corner_LowerRight  = (Corner_UpperRight[1], Corner_LowerLeft[2],  Corner_LowerLeft[3])
            Corner_UpperLeft   = (Corner_LowerLeft[1],  Corner_UpperRight[2], Corner_UpperRight[3])
        end
    end

    # Print overview of the 4 corners here:
    if Cartesian
        println("Extracting CartData from: $(filename)")
        println("           └ Corners:         x         y         z")
        println("              └ lower left  = ($(rpad( Corner_LowerLeft[1],7)), $(rpad( Corner_LowerLeft[2],7)),  $(rpad( Corner_LowerLeft[3],7)))")
        println("              └ lower right = ($(rpad(Corner_LowerRight[1],7)), $(rpad(Corner_LowerRight[2],7)),  $(rpad(Corner_LowerRight[3],7)))")
        println("              └ upper left  = ($(rpad( Corner_UpperLeft[1],7)), $(rpad( Corner_UpperLeft[2],7)),  $(rpad( Corner_UpperLeft[3],7)))")
        println("              └ upper right = ($(rpad(Corner_UpperRight[1],7)), $(rpad(Corner_UpperRight[2],7)),  $(rpad(Corner_UpperRight[3],7)))")
    end
    if UTM
        if isnothing(UTMzone)
            error("You need to specify UTMzone and isnorth if reading in UTM data.")
        end
        println("Extracting UTMData from: $(filename)")
        if isnorth
        println("       UTM Zone $(UTMzone) Northern Hemisphere")
        else
        println("       UTM Zone $(UTMzone) Southern Hemisphere")
        end
        println("           └ Corners:         E-W (x)  | N-S (y) | depth (z)")
        println("              └ lower left  = ($(rpad( Corner_LowerLeft[1],7)), $(rpad( Corner_LowerLeft[2],7)),  $(rpad( Corner_LowerLeft[3],7)))")
        println("              └ lower right = ($(rpad(Corner_LowerRight[1],7)), $(rpad(Corner_LowerRight[2],7)),  $(rpad(Corner_LowerRight[3],7)))")
        println("              └ upper left  = ($(rpad( Corner_UpperLeft[1],7)), $(rpad( Corner_UpperLeft[2],7)),  $(rpad( Corner_UpperLeft[3],7)))")
        println("              └ upper right = ($(rpad(Corner_UpperRight[1],7)), $(rpad(Corner_UpperRight[2],7)),  $(rpad(Corner_UpperRight[3],7)))")
    end
    if (!Cartesian) && (!UTM)
        println("Extracting GeoData from: $(filename)")
        println("           └ Corners:         lon       lat       depth")
        println("              └ lower left  = ($(rpad( Corner_LowerLeft[1],7)), $(rpad( Corner_LowerLeft[2],7)),  $(rpad( Corner_LowerLeft[3],7)))")
        println("              └ lower right = ($(rpad(Corner_LowerRight[1],7)), $(rpad(Corner_LowerRight[2],7)),  $(rpad(Corner_LowerRight[3],7)))")
        println("              └ upper left  = ($(rpad( Corner_UpperLeft[1],7)), $(rpad( Corner_UpperLeft[2],7)),  $(rpad( Corner_UpperLeft[3],7)))")
        println("              └ upper right = ($(rpad(Corner_UpperRight[1],7)), $(rpad(Corner_UpperRight[2],7)),  $(rpad(Corner_UpperRight[3],7)))")
    end

    # Reconstruct the 4 corners into a matrix
    i = 1; Corners_lon     = [Corner_UpperLeft[i] Corner_UpperRight[i]; Corner_LowerLeft[i] Corner_LowerRight[i]; ]
    i = 2; Corners_lat     = [Corner_UpperLeft[i] Corner_UpperRight[i]; Corner_LowerLeft[i] Corner_LowerRight[i]; ]
    i = 3; Corners_depth   = [Corner_UpperLeft[i] Corner_UpperRight[i]; Corner_LowerLeft[i] Corner_LowerRight[i]; ]

   # i = 1; Corners_lon     = [Corner_LowerLeft[i] Corner_LowerRight[i]; Corner_UpperLeft[i] Corner_UpperRight[i];]
   # i = 2; Corners_lat     = [Corner_LowerLeft[i] Corner_LowerRight[i]; Corner_UpperLeft[i] Corner_UpperRight[i];]
   # i = 3; Corners_depth   = [Corner_LowerLeft[i] Corner_LowerRight[i]; Corner_UpperLeft[i] Corner_UpperRight[i];]

    # Extract the colors from the grid
    img_RGB     =   convert.(RGB, img)     # convert to  RGB data

    # extract the red-green-blue values from the image
    r           =   zeros(size(img_RGB))
    g           =   zeros(size(img_RGB))
    b           =   zeros(size(img_RGB))
    for i in eachindex(g)
        r[i] = Float64(img_RGB[i].r)
        g[i] = Float64(img_RGB[i].g)
        b[i] = Float64(img_RGB[i].b)
    end

    # Construct depth, lon and lat 2D grids from the corner points through linear interpolation
    grid_size               =   size(r)
    xs                      =   [1,grid_size[1]];
    zs                      =   [1,grid_size[2]];
    interp_linear_lon       =   LinearInterpolation((xs, zs), Corners_lon)      # create interpolation object
    interp_linear_lat       =   LinearInterpolation((xs, zs), Corners_lat)       # create interpolation object
    interp_linear_depth     =   LinearInterpolation((xs, zs), Corners_depth)     # create interpolation object

    # Interpolate
    X_int,Y_int,Depth       =   XYZGrid(1:grid_size[1],1:grid_size[2],0)
    X                       =   interp_linear_lon.(X_int,   Y_int);
    Y                       =   interp_linear_lat.(X_int,   Y_int);
    Depth                   =   interp_linear_depth.(X_int, Y_int);

    # Transfer to 3D arrays (check if needed or not; if yes, redo error message in struct routin)
    red                     =   zeros(size(Depth)); red[:,:,1]   = r;
    green                   =   zeros(size(Depth)); green[:,:,1] = g;
    blue                    =   zeros(size(Depth)); blue[:,:,1]  = b;

    # Create GeoData structure - NOTE: RGB data must be 2D matrixes, not 3D!
    if Cartesian
        data_Image              =   CartData(X, Y, Depth,(colors=(red,green,blue),))
    end
    if UTM
        data_Image              =   UTMData(X, Y, Depth, UTMzone, isnorth, (colors=(red,green,blue),))
    end
    if (!Cartesian) && (!UTM)
        data_Image              =   GeoData(X, Y, Depth, (colors=(red,green,blue),))
    end
    return data_Image
end

"""
    Data = Screenshot_To_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)

Does the same as `Screenshot_To_GeoData`, but returns a `CartData` structure
"""
function Screenshot_To_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)

    # first create a GeoData struct
    Data_Cart = Screenshot_To_GeoData(filename, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=Corner_LowerRight, Corner_UpperLeft=Corner_UpperLeft, Cartesian=true)

    return Data_Cart

end

"""
    Data = Screenshot_To_UTMData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, UTMzone::Int64=nothing, isnorth::Bool=true)

Does the same as `Screenshot_To_GeoData`, but returns for UTM data
Note that you have to specify the `UTMzone` and `isnorth`
"""
function Screenshot_To_UTMData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, UTMzone::Int64=nothing, isnorth::Bool=true)

      # first create a GeoData struct
      Data_UTM = Screenshot_To_GeoData(filename, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=Corner_LowerRight, Corner_UpperLeft=Corner_UpperLeft, Cartesian=false, UTM=true, UTMzone=UTMzone, isnorth=isnorth)

      return Data_UTM

end


text:
abstract type TechsExportCurtail end
struct CanExport <: TechsExportCurtail end
struct CanCurtail <: TechsExportCurtail end
struct CanExportAndCurtail <: TechsExportCurtail end
struct CanNotExportCurtail <: TechsExportCurtail end

struct Techs{T <: TechsExportCurtail}
    type::T  # have to use the T parameter
    # names::Array{String, 1}
    # classes::AbstractArray{String, 1}
end

struct Parameter
    t::Techs{T} where {T}
end

# the following goes in utils.jl
ExportTiers = []
TechsCanCurtail = []

if !isempty(ExportTiers)
    if !isempty(TechsCanCurtail)
        techs = Techs(CanExportAndCurtail())
    else
        techs = Techs(CanExport())
    end
else
    if !isempty(TechsCanCurtail)
        techs = Techs(CanCurtail())
    else
        techs = Techs(CanNotExportCurtail())
    end
end

p = Parameter(techs)

# the following will be in reopt.jl
add_constraint(p::Parameter) = add_constraint(p.t)

function add_constraint(::Techs{CanExportAndCurtail})
    println("CanExportAndCurtail")
end

function add_constraint(::Techs{CanExport})
    println("CanExport")
end

function add_constraint(::Techs{CanCurtail})
    println("CanCurtail")
end

function add_constraint(::Techs{CanNotExportCurtail})
    println("CanNotExportCurtail")
end

add_constraint(p)


text:
function _get_repo_url_with_auth(org::AbstractString, pkg::AbstractString; token::Union{AbstractString, Nothing})
    if token === nothing
        return "https://github.com/$(org)/$(pkg).jl"
    else
        return "https://x-access-token:$(token)@github.com/$(org)/$(pkg).jl"
    end
end


text:
# MIT License
#
# Copyright (c) 2020 Joshua E Gentry

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
using SIMD

@inline function shuffle(
            x1::VECTOR,
            v::Tuple{Int, Int, Int, Int}
        )::VECTOR
    return shufflevector(x1, Val((v[4], v[3], v[2], v[1])))
end

@inline function shuffle(
            x1::VECTOR,
            x2::VECTOR,
            v::Tuple{Int, Int, Int, Int}
        )::VECTOR
    return shufflevector(x1, x2, Val((v[4], v[3], 4+v[2], 4+v[1])))
end

@inline function blend(x1::VECTOR, x2::VECTOR, mask::UInt8)::VECTOR
    local c1 = reinterpret(Vec{8, UInt16}, x1)
    local c2 = reinterpret(Vec{8, UInt16}, x2)
    local m = (
        (mask & 0x01) != 0 ? 8  : 0,
        (mask & 0x02) != 0 ? 9  : 1,
        (mask & 0x04) != 0 ? 10 : 2,
        (mask & 0x08) != 0 ? 11 : 3,
        (mask & 0x10) != 0 ? 12 : 4,
        (mask & 0x20) != 0 ? 13 : 5,
        (mask & 0x40) != 0 ? 14 : 6,
        (mask & 0x80) != 0 ? 15 : 7
    )
    local r = shufflevector(c1, c2, Val(m))

    return reinterpret(VECTOR, r)
end

@inline function unpacklo_64(x1::VECTOR, x2::VECTOR)::VECTOR
    local t1 = reinterpret(Vec{2, UInt64}, x1)
    local t2 = reinterpret(Vec{2, UInt64}, x2)
    local r  = shufflevector(t1, t2, Val((0, 2)))
    return reinterpret(VECTOR, r)
end

@inline function unpackhi_64(x1::VECTOR, x2::VECTOR)::VECTOR
    local t1 = reinterpret(Vec{2, UInt64}, x1)
    local t2 = reinterpret(Vec{2, UInt64}, x2)
    local r  = shufflevector(t1, t2, Val((1, 3)))
    return reinterpret(VECTOR, r)
end

@inline function unpackhi_32(x1::VECTOR, x2::VECTOR)::VECTOR
    return shufflevector(x1, x2, Val((2, 6, 3, 7)))
end

@inline function unpacklo_32(x1::VECTOR, x2::VECTOR)::VECTOR
    return shufflevector(x1, x2, Val((0, 4, 1, 5)))
end


text:
module Regularisers

using SHIPs: SHIPBasis, nspecies, _get_I_iz0
using LinearAlgebra: Diagonal

function _get_ww(ship::SHIPBasis{T}, iz0, weightfcn) where {T}
   ww = zeros(T, size(ship.A2B[iz0], 1))
   for ib = 1:length(ship.bgrps[iz0])
      izz, kk, ll =  ship.bgrps[iz0][i]
      Igrp = (ship.firstb[iz0][i]+1):ship.firstb[iz0][i+1]
      ww[Igrp] = weightfcn(kk, ll)
   end
   return ww
end

function _get_ww(ship::SHIPBasis{T}, weightfcn) where {T}
   ww = zeros(length(ship))
   for iz0 = 1:nspecies(ship)
      Iz = _get_I_iz0(ship, iz0)
      ww[Iz] = _get_ww(ship, iz0, weightfcn)
   end
   return ww
end

diffweight(kk, ll, diff) = sqrt(sum(kk.^(2*diff)) + sum(ll.^(2*diff)))

function diagonal_regulariser(shp::SHIPBasis;
                              diff = 0,
                              weightfcn = (kk, ll) -> diffweight(kk, ll, diff))
   return Diagonal(_get_ww(shp, weightfcn))
end

end

max_stars_repo_name: cortner/SHIPs

max_issues_repo_name: cortner/SHIPs

max_forks_repo_name: cortner/SHIPs


text:
include("./base.jl")
using .base_things
using Base

inputing = []
weighting = []
minus_weight = []

println("변수 개수(사람의 수)를 입력하시오")
println()

number_of_input = parse(Int64,readline())
println()
println("반복횟수")
number_of_loop = parse(Int64,readline())

for i = 1:number_of_input
    append!(weighting,1)
end

for i = 1:number_of_input
    append!(minus_weight,0)
end

# julia 의 배열은 1부터 시작
for start = 1:number_of_loop

    println("변수를 입력하시요")

    if start==1
        for i = 1:number_of_input
            append!(inputing,parse(Float64,readline()))
        end
    else
        for i = 1:number_of_input
            inputing[i] =  parse(Float64,readline())
        end
    end

    println("실제로 나온 값 입력")
    real_input = readline()
    real_input = parse(Float64,real_input)

    vari = Vector{base_things.변수}(undef,number_of_input)

    for i = 1:number_of_input
        vari[i] = base_things.변수(inputing[i],weighting[i],real_input,0,minus_weight[i])
    end

    list_abs_error = zeros(Float64,1,number_of_input)
    for i = 1:number_of_input
        list_abs_error[i] = base_things.abs_error_cal(vari[i])
    end

    max_error = maximum(list_abs_error)

    sum_of_error = sum(list_abs_error)
    len_of_error = length(list_abs_error)
    avg_of_error = sum_of_error/len_of_error

    add_list = zeros(Float64,1,number_of_input)

    for i = 1:number_of_input
        add_list[i] = 1/(sum_of_error/list_abs_error[i])
    end

    sumofw = 0

    max_add = maximum(add_list)
    sum_add = sum(add_list)
    len_add = length(add_list)
    avg_add = sum_add/len_add

    for i = 1:number_of_input
        sumofw = sumofw + vari[i].Weight
    end

    forwarding = zeros(Float64,1,number_of_input)

    for i = 1:number_of_input
        forwarding[i] = base_things.forward(vari[i],sumofw)
    end

    result = 0

    for i = 1:number_of_input
        result = result + forwarding[i]
    end

    println("결과치")
    println(result)
    println()

    new_weigth_list = zeros(Float64,1,number_of_input)

    for i = 1:number_of_input
        new_weigth_list[i] = base_things.graph(add_list[i],max_add,avg_add)
    end

    backwarding = zeros(Float64,1,number_of_input)

    for i = 1:number_of_input
        weighting[i] , minus_weight[i] = base_things.backward(vari[i],new_weigth_list[i])
    end

    println()
    for i = 1:number_of_input
        vari[i].minus_weight = minus_weight[i]
        vari[i].Weight = weighting[i]
    end

end


text:
"PDDL planning domain."
abstract type Domain end

"Returns the name of a domain."
get_name(domain::Domain) = error("Not implemented.")

"Returns domain requirements as a map from requirement names to Boolean values."
get_requirements(domain::Domain) = error("Not implemented.")

"Returns a map from domain types to subtypes."
get_typetree(domain::Domain) = error("Not implemented.")

"Returns an iterator over types in the domain."
get_types(domain::Domain) = keys(get_typetree(domain))

"Returns an iterator over (immediate) subtypes of `type` in the domain."
get_subtypes(domain::Domain, type::Symbol) = get_typetree(domain)[type]

"Returns a map from domain datatypes to Julia types."
get_datatypes(domain::Domain) = error("Not implemented.")

"Returns the Julia type associated with the domain `datatype`."
get_datatype(domain::Domain, datatype::Symbol) = get_datatype(domain)[datatype]

"Returns the list of domain object constants."
get_constants(domain::Domain) = error("Not implemented.")

"Returns a map from domain constants to their types."
get_constypes(domain::Domain) = error("Not implemented.")

"Returns the type of the domain constant `obj`."
get_constype(domain::Domain, obj) = get_constypes[obj]

"Returns a map from predicate names to predicate signatures."
get_predicates(domain::Domain) = error("Not implemented.")

"Returns the signature associated with a predicate `name`."
get_predicate(domain::Domain, name::Symbol) = get_predicates(domain)[name]

"Returns a map from function names to function signatures."
get_functions(domain::Domain) = error("Not implemented.")

"Returns the signature associated with a function `name`."
get_function(domain::Domain, name::Symbol) = get_functions(domain)[name]

"Returns a map from function names to attached function definitions."
get_funcdefs(domain::Domain) = error("Not implemented.")

"Returns the definition associated with a function `name`."
get_funcdef(domain::Domain, name::Symbol) = get_funcdefs(domain)[name]

"Returns a map from domain fluent names to fluent signatures."
get_fluents(domain::Domain) = error("Not implemented.")

"Returns the signature associated with a fluent `name`."
get_fluent(domain::Domain, name::Symbol) = get_fluents(domain)[name]

"Returns a map from names of derived predicates to their corresponding axioms."
get_axioms(domain::Domain) = error("Not implemented.")

"Returns the axiom assocated with a derived predicate `name`."
get_axiom(domain::Domain, name::Symbol) = get_axioms(domain)[name]

"Returns a map from action names to action schemata."
get_actions(domain::Domain) = error("Not implemented.")

"Returns the action schema specified by `name`."
get_action(domain::Domain, name::Symbol) = get_actions(domain)[name]


text:
using GeometricIntegrators
using SafeTestsets

set_config(:verbosity, 2)

@safetestset "1st Poincaré Invariant Unit Tests                                               " begin include("poincare_invariant_1st_unittests.jl") end
@safetestset "1st Poincaré Invariant Function Tests                                           " begin include("poincare_invariant_1st_tests.jl") end
@safetestset "2nd Poincaré Invariant Unit Tests                                               " begin include("poincare_invariant_2nd_unittests.jl") end
@safetestset "2nd Poincaré Invariant Function Tests                                           " begin include("poincare_invariant_2nd_tests.jl") end


text:
"""
    LaneFollowingAccel
Longitudinal acceleration.
The resulting vehicle velocity is capped below at 0 (i.e. standstill). Negative velocities are not allowed.

# Fields
- `a::Float64` longitudinal acceleration [m/s^2]
"""
struct LaneFollowingAccel
    a::Float64
end

function propagate(veh::Vehicle1D, action::LaneFollowingAccel, roadway::StraightRoadway, Δt::Float64)

    a = action.a
    s, v = veh.state.s, veh.state.v

    s′ = s + v*Δt + a*Δt*Δt/2
    v′ = max(v + a*Δt, 0.)  # no negative velocities

    s′ = mod_position_to_roadway(s′, roadway)

    return State1D(s′, v′)
end

function propagate(veh::Entity{VehicleState,D,I}, action::LaneFollowingAccel, roadway::Roadway, ΔT::Float64) where {D,I}

    a_lon = action.a

    ds = vel(veh.state)

    ΔT² = ΔT*ΔT
    Δs = ds*ΔT + 0.5*a_lon*ΔT²

    v₂ = max(ds + a_lon*ΔT, 0.)  # no negative velocities

    roadind = move_along(posf(veh.state).roadind, roadway, Δs)
    posG = roadway[roadind].pos
    posF = Frenet(roadind, roadway, t=posf(veh.state).t, ϕ=posf(veh.state).ϕ)
    VehicleState(posG, posF, v₂)
end


text:
# ---
# title: 382. Linked List Random Node
# id: problem382
# author: zhwang
# date: 2022-02-15
# difficulty: Medium
# categories: Reservoir Sampling
# link: <https://leetcode.com/problems/linked-list-random-node/description/>
# hidden: true
# ---
#
# Given a singly linked list, return a random node's value from the linked list.
# Each node must have the **same probability** of being chosen.
#
# **Follow up:**
# What if the linked list is extremely large and its length is unknown to you?
# Could you solve this efficiently without using extra space?
#
# **Example:**
#
#
#
#     // Init a singly linked list [1,2,3].
#     ListNode head = new ListNode(1);
#     head.next = new ListNode(2);
#     head.next.next = new ListNode(3);
#     Solution solution = new Solution(head);
#
#     // getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.
#     solution.getRandom();
#
#
#
## @lc code=start
using LeetCode

function get_random(head::ListNode)::Int
    node, i, res = head, 1, 0
    while !isnothing(node)
        if rand(1:i) == 1  ## 1/i prob for value change
            res = node.val
        end
        node = node.next
        i += 1
    end
    return res
end
## @lc code=end


text:
module Traits
export has_axis, is_spin_polarized, ColinearSpin, SpinDegenerate, components,
       SpinCategory, FunctionalCategory, LDA, GGA, ColinearSpinFirst, ColinearSpinLast,
       concretize_type, standard_name

using DocStringExtensions
using AxisArrays
using Unitful
using ..UnitfulHartree
using ..Dispatch
const DD = Dispatch.Dimensions
const DH = Dispatch.Hartree

macro lintpragma(s) end
@lintpragma("Ignore use of undeclared variable unitful_dimensions")
@lintpragma("Ignore use of undeclared variable Q")
@lintpragma("Ignore use of undeclared variable T")
@lintpragma("Ignore use of undeclared variable D")
@lintpragma("Ignore use of undeclared variable U")
@lintpragma("Ignore use of undeclared variable H")
@lintpragma("Ignore unused array")

const UH = UnitfulHartree

has_axis(array::Type{<:AxisArray}, axis::Type{<:Axis}) =
    axisnames(axis)[1] ∈ axisnames(array)
has_axis(a::AxisArray, axis_type::Type{<:Axis}) = has_axis(typeof(a), axis_type)
has_axis(array::Type{<:AxisArray}, name::Symbol) = has_axis(array, Axis{name})
has_axis(a::AxisArray, name::Symbol) = has_axis(typeof(a), name)

""" Spin axis should have this type """
const SpinAxis = Axis{:spin, Q} where {Q <: Tuple{T, T, Vararg{T}} where T}
"""
True if the array is spin polarized, meaning it has an axis named `:spin` with
two or more values.

$(SIGNATURES)

Note that if the argument is a type (rather than an instance) then the values of the spin
axis should be a tuple, e.g.:

`typeof(Axis(:spin, (:+, :-))) === Axis{:spin, Tuple{Symbol, Symbol}}`

More explicitly, a spin axis is an `AxisArrays.Axis` instance of type
`Axis{:spin, <: Tuple{T, T, Vararg{T}} where T}`.
"""
is_spin_polarized(::Type{<: SpinAxis}) = true
is_spin_polarized(::Type{<: Axis}) = false
is_spin_polarized(ax::Axis) = is_spin_polarized(typeof(ax))
is_spin_polarized(array::AxisArray) = any(is_spin_polarized.(axes(array)))
is_spin_polarized(array::Type{<: AxisArray}) = findfirst(is_spin_polarized, array) ≠ 0
Base.findfirst(::typeof(is_spin_polarized), array::Type{<: AxisArray}) = begin
    index = 1
    for T in array.parameters[end].parameters
        is_spin_polarized(T) && return index
        index += 1
    end
    0
end

""" Union of all polarization traits """
abstract type SpinCategory end
""" Trait for functions accepting input in the colinear spin approximation """
abstract type AbstractColinearSpin <: SpinCategory end
""" Trait for functions accepting input in the colinear spin approximation """
struct ColinearSpin{L} <: AbstractColinearSpin end

""" Spin-polarized input where the spin axis is always the fastest changing """
const ColinearSpinFirst = ColinearSpin{1}
""" Spin-polarized input where the spin axis is always the slowest changing """
const ColinearSpinLast = ColinearSpin{:end}

"""
Trait to differentiate between Base and specialized spin functions

This type is used to select overloads of `Base.zeros` and friends that will change the
spin-axis if needed. More specifically, if `ρ` is a spin-polarized `AxisArray`, then
`Base.zeros(ρ, Dispatch.Scalars.∂³ϵ_∂ρ³, SpinAware)` is also spin-polarized and the
spin-axis has the correct dimension (4 in this case). If `ρ` is not spin-polarized, then
the call is equivalent to `Base.zeros(ρ, Dispatch.Scalars.∂³ϵ_∂ρ³)`.
"""
struct SpinAware <: SpinCategory end

""" Traits for unpolarized inputs """
struct SpinDegenerate <: SpinCategory end

""" Looks at axes to figure out the spin category

- no spin-axis -> SpinDegenerate
- fastest changing dimension -> ColinearSpinFirst
- `n`th dim -> ColinearSpin{n}

"""
(::Type{SpinCategory})(array::AxisArray) = SpinCategory(axes(array))
@generated (::Type{SpinCategory})(ax::Tuple{Axis, Vararg{Axis}}) = begin
    index = findfirst(is_spin_polarized, ax.parameters)
    if index == 0
        :(SpinDegenerate())
    elseif index == length(ax.parameters)
        :(ColinearSpinLast())
    else
        :(ColinearSpin{$index}())
    end
end
(::Type{SpinCategory})(S::SpinCategory) = S
""" ColinearSpin defaults to settings spin axis in last position

However, if the spin axis is already given, functions following this traits should not move
it.
"""
(::Type{ColinearSpin})() = ColinearSpin{:end}()

""" Supertype of all functional categories """
abstract type FunctionalCategory end
""" Trait identifying the LDA functional category """
type LDA <: FunctionalCategory end
""" Trait identifying the LDA functional category """
type GGA <: FunctionalCategory end

"""
Same as Unitful.dimension but for still abstract quantities
"""
unitful_dimensions(::Type{<: Quantity{T, D} where T}) where D = D()

"""
Figures out functional category, whether LDA or GGA

$(SIGNATURES)
"""
(::Type{FunctionalCategory})(::typeof(dimension(UH.ρ)))::LDA = LDA()
(::Type{FunctionalCategory})(::typeof(dimension(UH.∂ϵ_∂ρ))) = LDA()
(::Type{FunctionalCategory})(::typeof(dimension(UH.∂²ϵ_∂ρ²))) = LDA()
(::Type{FunctionalCategory})(::typeof(dimension(UH.∂³ϵ_∂ρ³))) = LDA()
(::Type{FunctionalCategory})(::typeof(dimension(UH.σₑ))) = GGA()
(::Type{FunctionalCategory})(::typeof(dimension(UH.∂ϵ_∂σ))) = GGA()
(::Type{FunctionalCategory})(::typeof(dimension(UH.∂²ϵ_∂ρ∂σ))) = GGA()
(::Type{FunctionalCategory})(::typeof(dimension(UH.∂²ϵ_∂σ²))) = GGA()
(::Type{FunctionalCategory})(::typeof(dimension(UH.∂³ϵ_∂ρ²∂σ))) = GGA()
(::Type{FunctionalCategory})(::typeof(dimension(UH.∂³ϵ_∂ρ∂σ²))) = GGA()
(::Type{FunctionalCategory})(::typeof(dimension(UH.∂³ϵ_∂σ³))) = GGA()
(::Type{FunctionalCategory})(u::Unitful.FreeUnits) = FunctionalCategory(dimension(u))
(::Type{FunctionalCategory})(u::DD.Scalars.All) = FunctionalCategory(dimension(u))
(::Type{FunctionalCategory})(T::Type{<: DD.Scalars.All}) =
    FunctionalCategory(unitful_dimensions(T))

"""
Labels of the standard components for LDA and GGA inputs

$(SIGNATURES)

ρ refers to the unpolarized density, α and β to the two spin channels of the density, σ to
the contracted gradient density (∇ρ⋅∇ρ), and σαα (∇α⋅∇α), σαβ, σββ  to the polarized
contracted gradient densities.
"""
components(::typeof(dimension(UH.ρ)), ::SpinDegenerate) = (:ρ,)
components(::typeof(dimension(UH.ϵ)), ::SpinDegenerate) = (:ϵ,)
components(::typeof(dimension(UH.∂ϵ_∂ρ)), ::SpinDegenerate) = (:∂ρ,)
components(::typeof(dimension(UH.∂²ϵ_∂ρ²)), ::SpinDegenerate) = (:∂ρ²,)
components(::typeof(dimension(UH.∂³ϵ_∂ρ³)), ::SpinDegenerate) = (:∂ρ³,)
components(::typeof(dimension(UH.ρ)), ::ColinearSpin) = :α, :β
components(::typeof(dimension(UH.ϵ)), ::ColinearSpin) = :α, :β
components(::typeof(dimension(UH.∂ϵ_∂ρ)), ::ColinearSpin) = :∂α, :∂β
components(::typeof(dimension(UH.∂²ϵ_∂ρ²)), ::ColinearSpin) = :∂α², :∂α∂β, :∂²β
components(::typeof(dimension(UH.∂³ϵ_∂ρ³)), ::ColinearSpin) = :∂α³, :∂α∂β², :∂α∂β², :∂β³
components(::typeof(dimension(UH.σₑ)), ::ColinearSpin) = :σαα, :σαβ, :σββ
components(::typeof(dimension(UH.∂ϵ_∂σ)), ::ColinearSpin) = :∂σαα, :∂σαβ, :∂σββ
components(::typeof(dimension(UH.∂²ϵ_∂ρ∂σ)), ::ColinearSpin) =
    :∂α∂σαα, :∂α∂σαβ, :∂α∂σββ, :∂β∂σαα, :∂β∂σαβ, :∂β∂σββ
components(::typeof(dimension(UH.∂²ϵ_∂σ²)), ::ColinearSpin) =
    :∂σαα², :∂σαα∂σαβ, :∂σαα∂σββ, :∂σαβ², :∂σαβσββ, :∂σββ²
components(::typeof(dimension(UH.∂³ϵ_∂ρ²∂σ)), ::ColinearSpin) = (
    :∂α²∂σαα, :∂α²∂σαβ, :∂α²∂σββ,
    :∂α∂β∂σαα, :∂α∂β∂σαβ, :∂α∂β∂σββ,
    :∂β²∂σαα, :∂β²∂σαβ, :∂β²∂σββ
)
components(::typeof(dimension(UH.∂³ϵ_∂ρ∂σ²)), ::ColinearSpin) = (
    :∂α∂σαα², :∂α∂σαα∂σαβ, :∂α∂σαα∂σββ, :∂α∂σαβ², :∂α∂σαβσββ, :∂α∂σββ²,
    :∂β∂σαα², :∂β∂σαα∂σαβ, :∂β∂σαα∂σββ, :∂β∂σαβ², :∂β∂σαβσββ, :∂β∂σββ²
)
components(::typeof(dimension(UH.∂³ϵ_∂σ³)), ::ColinearSpin) = (
    :∂σαα³, :∂σαα²∂σαβ, :∂σαα²∂σββ, :∂σαα∂σαβ², :∂σαα∂σαβ∂σββ, :∂σαα∂σββ²,
    :∂σαβ³, :∂σαβ²∂σββ, :∂σαβ∂σββ², :∂σββ³
)
components(::typeof(dimension(UH.σₑ)), ::SpinDegenerate) = (:σ,)
components(::typeof(dimension(UH.∂ϵ_∂σ)), ::SpinDegenerate) = (:∂σ,)
components(::typeof(dimension(UH.∂²ϵ_∂ρ∂σ)), ::SpinDegenerate) = (:∂ρ∂σ,)
components(::typeof(dimension(UH.∂²ϵ_∂σ²)), ::SpinDegenerate) = (:∂σ²,)
components(::typeof(dimension(UH.∂³ϵ_∂ρ²∂σ)), ::SpinDegenerate) = (:∂ρ²∂σ,)
components(::typeof(dimension(UH.∂³ϵ_∂ρ∂σ²)), ::SpinDegenerate) = (:∂ρ∂σ²,)
components(::typeof(dimension(UH.∂³ϵ_∂σ³)), ::SpinDegenerate) = (:∂σ³,)

components(u::Unitful.FreeUnits, P::SpinCategory) = components(dimension(u), P)
components(u::DD.Scalars.All, P::SpinCategory) = components(dimension(u), P)
components(T::Type{<: DD.Scalars.All}, P::SpinCategory) =
    components(unitful_dimensions(T), P)

""" helper function to concretize some types using Hartree units """
function hartree_concretize_type end
for (_, name) in Dispatch.Dimensioned
    @eval begin
        @inline hartree_concretize_type(T::Type{<:DD.Scalars.$name}) =
            hartree_concretize_type(DH.Scalars.$name, T)
        @inline hartree_concretize_type(::Type{DD.Scalars.$name},
                                        ::Type{<: Quantity{T}}) where T =
            DH.Scalars.$name{T}
        @inline hartree_concretize_type(::Type{DD.Scalars.$name}, T::Type{<: Number}) =
            DH.Scalars.$name{T}
        @inline hartree_concretize_type(::Type{DD.Scalars.$name{TT, U} where TT},
                                        ::Type{T}) where U where T <: Number =
            DD.Scalars.$name{T, U}
        @inline hartree_concretize_type(::Type{DD.Scalars.$name{TT, U} where TT},
                                        ::Type{<: Quantity{T}}) where {U, T} =
            DD.Scalars.$name{T, U}
    end
end

"""
Tries and figures a concrete type given `Q <: Quantity` and `T <: Number`

`Q` may be abstract: the underlying type or the units may be unknown (but the dimensions are
always specified). Whatever is missing is taken from `T`. If the units are unspecified, and
`Q <: Dispatch.Dimensions.Scalars.All`, then Hartree units are used by default.

# Examples

concretize_type(Dispatch.Dimensions.Scalars.ρ, Int16) === Dispatch.Hartree.Scalars.ρ{Int16}
concretize_type(typeof(1.0u"m^-3"), Int16) === typeof(Int16(1)u"m^-3")
"""
@inline concretize_type(::Type{Quantity{T, D, U}}, ::Type{<:Number}) where {T, D, U} =
    Quantity{T, D, U}
@inline concretize_type(::Type{Quantity{T, D}},
                        ::Type{Quantity{TT, D, U} where TT}) where {T, D, U} =
    Quantity{T, D, U}
@inline concretize_type(::Type{Quantity{TT, D} where TT},
                        ::Type{Quantity{T, D, U}}) where {T, D, U} = Quantity{T, D, U}
@inline concretize_type(H::Type{<: Quantity{TT, D} where TT}, T::Type{<: Number}) where D =
    hartree_concretize_type(H, T)
@inline concretize_type(Q::Type{<: Quantity}, x::DenseArray) = concretize_type(Q, eltype(x))
@inline concretize_type(Q::Type{<: Quantity}, x::AxisArray) = concretize_type(Q, eltype(x))
@inline concretize_type(Q::Type{<: Quantity}, x::Number) = concretize_type(Q, typeof(x))

""" Gets standard name for a given physical dimension """
function standard_name end
for (_, name) in Dispatch.Dimensioned
    @eval standard_name(::Type{<: DD.Scalars.$name}) = $(QuoteNode(name))
end
standard_name(n::DD.Scalars.All) = standard_name(typeof(n))
standard_name(array::AbstractArray) = standard_name(eltype(array))
end

max_stars_repo_name: mdavezac/DFTShims

max_issues_repo_name: mdavezac/DFTShims

max_forks_repo_name: mdavezac/DFTShims


text:
#==============================================================================#
# protected_try.jl
#
# "@protected try" and @ignore exception handling
#
# Copyright Sam O'Connor 2014 - All rights reserved
#==============================================================================#

#-------------------------------------------------------------------------------
#
# @protected try... re-writes "try_expr" to automatically rethrow()
# at end of "catch" block (unless exception has been set to nothing).
#
# @ignore if... re-writes "if..." to ignore exceptions thrown by the if
# "condition" and to set "exception" = nothing if the "condition" is true
# (to prevent automatic rethrow).
#
# Exceptions raised by the "if" condition in "@ignore if" are ignored.
# i.e. "@ignore if err.code == "404" is safe even if "err" has no "code" field.
#
# e.g.
#
#    @protected try
#
#       s3(aws, "PUT", bucket)
#
#    catch e
#       @ignore if e.code == "BucketAlreadyOwnedByYou" end
#    end
#
# becomes...
#
#    try
#
#        s3(aws, "PUT", bucket)
#
#    catch e
#        try
#            if e.code == "BucketAlreadyOwnedByYou"
#                e = nothing
#            end
#        end
#        e == nothing || rethrow(e)
#    end
#
#
#-------------------------------------------------------------------------------

macro protected(try_expr::Expr)

    # Extract exception variable and catch block from "try" expression...
    (try_block, exception, catch_block) = check_try_catch(try_expr, true)

    for (i, expr) in enumerate(catch_block.args)

        # Look for "@ignore if..." expressions in catch block...
        if (typeof(expr) == Expr
        &&  expr.head == :macrocall
        &&  expr.args[1] == Symbol("@ignore"))

            if_expr = check_macro_if(expr)
            (condition, action) = if_expr.args

            # Clear exception variable at end of "@ignore if..." block...
            push!(action.args, :($exception = nothing))

            # Replace "@ignore if...", with "if..."...
            catch_block.args[i] = if_expr
        end
    end

    # Check for nothing exception at start of catch block...
    pushfirst!(catch_block.args, :($exception == nothing && rethrow($exception)))

    # Check rethrow flag at end of catch block...
    push!(catch_block.args,  :($exception == nothing || rethrow($exception)))

    return esc(try_expr)
end

#==============================================================================#
# End of file.
#==============================================================================#


text:
# -------- Players ----------------------------------------------------------- #

"""
Players are named entities that can evaluate game states via the `think`
function to yield policies.
"""
abstract type Player{G <: Game} end

"""
    think(player, game)

Let `player` think about `game` and return a policy to you.
"""
think(p :: Player, game :: Game) :: Vector{Float32} = error("Not implemented")

"""
    decide(player, game)

Let `player` make an action decision about `game`, based on the policy
`think(player, game)`.
"""
decide(p :: Player, game :: Game) = choose_index(think(p, game))

"""
    turn!(game, player)

Modify `game` by letting `player` take one turn.
"""
turn!(game :: Game, p :: Player) = apply_action!(game, decide(p, game))

"""
    name(player)

The name of a player.
"""
name(:: Player) :: String = error("Not implemented")

"""
    ntasks(player)

How many tasks the player wants to handle via asyncmap.
"""
ntasks(:: Player) = 1

# For automatic game interference
gametype(:: Player{G}) where {G <: Game} = G

# Players with potentially trainable models can be asked to return them
base_model(p :: Player)   = nothing
playing_model(:: Player)  = nothing
training_model(:: Player) = nothing

# Features that are supported by the player. Used for automatic feature
# detection during the generation of datasets in selfplays
features(:: Player) = []

# -------- Random Player ----------------------------------------------------- #

"""
A player with name "random" that always chooses a random (but allowed) action.
"""
struct RandomPlayer <: Player{Game} end

function think(:: RandomPlayer, game :: Game)
  actions = legal_actions(game)
  policy = zeros(Float32, policy_length(game))
  policy[actions] = 1f0 / length(actions)
  policy
end

name(p :: RandomPlayer) = "random"
Base.copy(p :: RandomPlayer) = p

# -------- Intuition Player -------------------------------------------------- #

"""
A player that relies on the policy returned by a model.
"""
struct IntuitionPlayer{G} <: Player{G}
  model :: Model
  temperature :: Float32
  name :: String
end

"""
    IntuitionPlayer(model [; temperature, name])
    IntuitionPlayer(player [; temperature, name])

Intuition player that uses `model` to generate policies which are cooled/heated
by `temperature` before making a decision. If provided a `player`, the
IntuitionPlayer shares this player's model and temperature.
"""
function IntuitionPlayer( model :: Model{G}
                        ; temperature = 1.
                        , name = nothing
                        ) where {G <: Game}
  if isnothing(name)
    id = get_id(model, temperature)
    name = "intuition-$id"
  end

  IntuitionPlayer{G}(model, temperature, name)

end

function IntuitionPlayer( player :: Player{G}
                        ; temperature = player.temperature
                        , name = nothing
                        ) where {G <: Game}

  IntuitionPlayer( playing_model(player)
                 , temperature = temperature
                 , name = name )

end

function think( p :: IntuitionPlayer{G}
              , game :: G
              ) :: Vector{Float32} where {G <: Game}

  # Get all legal actions and their model policy values
  actions = legal_actions(game)
  policy = zeros(Float32, policy_length(game))

  policy[actions] = apply(p.model, game).policy[actions]

  # Return the action that the player decides for
  if p.temperature == 0f0

    one_hot(length(policy), findmax(policy)[2])

  else

    weights = policy.^(1/p.temperature)
    weights / sum(weights)

  end

end

name(p :: IntuitionPlayer) = p.name
ntasks(p :: IntuitionPlayer) = ntasks(p.model)

base_model(p :: IntuitionPlayer) = base_model(p.model)
playing_model(p :: IntuitionPlayer) = p.model
training_model(p :: IntuitionPlayer) = training_model(p.model)

function features(p :: IntuitionPlayer)
  tm = training_model(p)
  isnothing(tm) ? Feature[] : features(tm)
end

function switch_model( p :: IntuitionPlayer{G}
                     , m :: Model{H}
                     ) where {H <: Game, G <: H}
  IntuitionPlayer{G}(m, p.temperature, p.name)
end

Base.copy(p :: IntuitionPlayer) = switch_model(p, copy(p.model))
swap(p :: IntuitionPlayer) = switch_model(p, swap(p.model))

# -------- MCTS Player ------------------------------------------------------- #

"""
A player that relies on Markov chain tree search policies that are constructed
with the support of a model.
"""
struct MCTSPlayer{G} <: Player{G}

  model :: Model

  power :: Int
  temperature :: Float32
  exploration :: Float32
  dilution :: Float32

  name :: String

end

"""
    MCTSPlayer([model; power, temperature, exploration, name])
    MCTSPlayer(player [; power, temperature, exploration, name])

MCTS Player powered by `model`, which defaults to `RolloutModel`. The model can
also be derived from `player` (this does not create a copy of the model).
"""
function MCTSPlayer( model :: Model{G}
                   ; power = 100
                   , temperature = 1.
                   , exploration = 1.41
                   , dilution = 0.0
                   , name = nothing
                   ) where {G <: Game}

  if isnothing(name)
    id = get_id(model, temperature, exploration, dilution)
    name = "mcts$(power)-$id"
  end

  MCTSPlayer{G}(model, power, temperature, exploration, dilution, name)

end

# The default MCTSPlayer uses the RolloutModel
MCTSPlayer(; kwargs...) = MCTSPlayer(RolloutModel(); kwargs...)

function MCTSPlayer( player :: IntuitionPlayer{G}
                   ; temperature = player.temperature
                   , kwargs...
                   ) where {G <: Game}

  MCTSPlayer(playing_model(player); temperature = temperature, kwargs...)

end

function MCTSPlayer( player :: MCTSPlayer{G}; kwargs... ) where {G <: Game}
  MCTSPlayer(playing_model(player); kwargs...)
end

function think( p :: MCTSPlayer{G}
              , game :: G
              ) :: Vector{Float32} where {G <: Game}

  # Improved policy over the allowed actions
  pol = mctree_policy( p.model
                     , game
                     , power = p.power
                     , temperature = p.temperature
                     , exploration = p.exploration
                     , dilution = p.dilution )

  # Full policy vector
  policy = zeros(Float32, policy_length(game))
  policy[legal_actions(game)] = pol

  policy

end

name(p :: MCTSPlayer) = p.name
ntasks(p :: MCTSPlayer) = ntasks(p.model)
playing_model(p :: MCTSPlayer) = p.model
base_model(p :: MCTSPlayer) = base_model(p.model)
training_model(p :: MCTSPlayer) = training_model(p.model)

function features(p :: MCTSPlayer)
  tm = training_model(p)
  isnothing(tm) ? Feature[] : features(tm)
end

function switch_model( p :: MCTSPlayer{G}
                     , m :: Model{H}) where {H <: Game, G <: H}

  MCTSPlayer{G}( m
               , p.power
               , p.temperature
               , p.exploration
               , p.dilution
               , p.name )
end

Base.copy(p :: MCTSPlayer) = switch_model(p, copy(p.model))
swap(p :: MCTSPlayer) = switch_model(p, swap(p.model))

# -------- Human Player ------------------------------------------------------ #

"""
A player that queries for interaction before making a decision.
"""
struct HumanPlayer <: Player{Game}
  name :: String
end

"""
    HumanPlayer([; name])

Human player with name `name`, defaulting to "you".
"""
HumanPlayer(; name = "you") = HumanPlayer(name)

function think(p :: HumanPlayer, game :: Game)

  # Draw the game
  println()
  draw(game)

  # Take the user input and return the one-hot policy
  while true
    print("$(p.name): ")
    input = readline()
    try
      action = parse(Int, input)
      if !is_action_legal(game, action)
        println("Action $input is illegal ($error)")
      else
        policy = zeros(Float32, policy_length(game))
        policy[action] = 1f0
        return policy
      end
    catch error
      if isa(error, ArgumentError)
        println("Cannot parse action ($error)")
      else
        println("An unknown error occured: $error")
      end

    end
  end

end

name(p :: HumanPlayer) = p.name

Base.copy(p :: HumanPlayer) = p

# -------- PvP --------------------------------------------------------------- #

"""
    pvp(player1, player2 [; game, callback])

Conduct one match between `player1` and `player2`. The `game` that
`player1` starts with is infered automatically if possible.
`callback(current_game)` is called after each turn. The game outcome from
perspective of `player1` (-1, 0, 1) is returned.
"""
function pvp( p1 :: Player
            , p2 :: Player
            ; game :: Game = derive_gametype([p1, p2])()
            , callback = (_) -> nothing )

  game = copy(game)

  while !is_over(game)
    if current_player(game) == 1
      turn!(game, p1)
    else
      turn!(game, p2)
    end
    callback(game)
  end

  status(game)

end

"""
    pvp_games(player1, player2 [; game, callback])

Conduct one match between `player1` and `player2`. The `game` that
`player1` starts with is infered automatically if possible.
`callback(current_game)` is called after each turn. The vector of played game
states is returned.
"""
function pvp_games( p1 :: Player
                  , p2 :: Player
                  ; game :: Game = derive_gametype([p1, p2])()
                  , callback = (_) -> nothing )

  game  = copy(game)
  games = [copy(game)]

  while !is_over(game)
    if current_player(game) == 1
      turn!(game, p1)
    else
      turn!(game, p2)
    end
    push!(games, copy(game))
    callback(game)
  end

  games

end

max_stars_repo_name: roSievers/jtac


text:
module IntervalEigenvalues

using IntervalArithmetic, IntervalRootFinding, Polynomials
using IntervalOptimisation
using LinearAlgebra

export characteristic_polynomial, eigenvalue_bounds

function characteristic_polynomial(A::AbstractMatrix{T}) where {T}

    n = size(A, 1)
    c = zeros(T, n+1)

    M_old = zeros(T, n, n)

    II = Matrix{T}(I, n, n)

    c[end] = 1

    for k = 1:n

        M_new = A * M_old + c[n+1-k+1] * II

        c[n+1-k] = -tr(A * M_new) / k  # `trace(A*M) / k` doesn't work for some reason

        M_old = M_new

        # should store product A*M for next step
    end

    return c
end

function eigenvalue_bounds(A::AbstractMatrix)
    AI = interval.(A)

    p = characteristic_polynomial(AI)
    P = Poly(p)

    @show P

    X = Complex(-10..10, -10..10)
    eigvals = IntervalRootFinding.roots(z->P(z), X)
    root_intervals = [root.interval for root in eigvals]

    rts = [ IntervalBox(reim(λ)) for λ in root_intervals ]
    rts = unify(rts)

    complex_roots = [Complex(root...) for root in rts]
    return complex_roots

end

end


text:
"""
    BoxModule

Module for working with bounding boxes.
"""
module BoxModule

__precompile__(true)

using ..FTypesModule: FInt, FFlt, FCplxFlt, FFltVec, FIntVec, FFltMat, FIntMat, FMat, FVec, FDataDict

"""
    inbox(box::AbstractVector, x::AbstractVector)

Is the given location inside the box?

- `box` = vector entries arranged as [minx,maxx,miny,maxy,minz,maxz] (or
  adjusted for lower space dimension).

Note: point on the boundary of the box is counted as being inside.
"""
function inbox(box::AbstractVector, x::AbstractVector)
    inrange(rangelo,rangehi,r) = ((r>=rangelo) && (r<=rangehi));
    sdim=length(x);
    @assert 2*sdim == length(box)
    if !inrange(box[1], box[2], x[1])
        return false # short-circuit
    end
    for i=2:sdim
        if !inrange(box[2*i-1], box[2*i], x[i])
            return false # short-circuit
        end
    end
    return true
end

function inbox(box::AbstractVector, x::AbstractArray)
    return inbox(box, vec(x))
end

"""
    initbox!(box::AbstractVector, x::AbstractVector)

Initialize a bounding box with a single point.
"""
function initbox!(box::AbstractVector, x::AbstractVector)
    sdim = length(x)
    if length(box) < 2*sdim
        box = fill(zero(FFlt), 2*sdim)
    end
    for i = 1:sdim
        box[2*i-1] = box[2*i] = x[i];
    end
    return box
end

"""
    updatebox!(box::AbstractVector, x::AbstractArray)

Update a box with another location, or create a new box.

If the  `box` does not have  the correct dimensions,  it is correctly sized.

`box` = bounding box
    for 1-D `box=[minx,maxx]`, or
    for 2-D `box=[minx,maxx,miny,maxy]`, or
    for 3-D `box=[minx,maxx,miny,maxy,minz,maxz]`
    The `box` is expanded to include the
    supplied location `x`.   The variable `x`  can hold multiple points in rows.
"""
function updatebox!(box::AbstractVector, x::AbstractArray)
    sdim = size(x,2)
    if length(box) < 2*sdim
        box = fill(zero(FFlt), 2*sdim)
        for i = 1:size(x,2)
            box[2*i-1] = Inf;
            box[2*i]   = -Inf;
        end
    end
    for j = 1:size(x,1)
        for i = 1:sdim
            box[2*i-1] = min(box[2*i-1],x[j,i]);
            box[2*i]   = max(box[2*i],x[j,i]);
        end
    end
    return box
end

function updatebox!(box::AbstractVector, x::AbstractVector)
    return updatebox!(box, reshape(x, 1, length(x)))
end

"""
    boundingbox(x::AbstractArray)

Compute the bounding box of the points in `x`.

`x` = holds points, one per row.

Returns `box` = bounding box
    for 1-D `box=[minx,maxx]`, or
    for 2-D `box=[minx,maxx,miny,maxy]`, or
    for 3-D `box=[minx,maxx,miny,maxy,minz,maxz]`
"""
function boundingbox(x::AbstractArray)
    return updatebox!(FFlt[], x)
end

"""
    inflatebox!(box::AbstractVector, inflatevalue::Number)

Inflate the box by the value supplied.
"""
function inflatebox!(box::AbstractVector, inflatevalue::Number)
    abox = deepcopy(box)
    sdim = Int(length(box)/2);
    for i=1:sdim
        box[2*i-1] = min(abox[2*i-1],abox[2*i]) - inflatevalue;
        box[2*i]   = max(abox[2*i-1],abox[2*i]) + inflatevalue;
    end
    return box
end

"""
    boxesoverlap(box1::AbstractVector, box2::AbstractVector)

Do the given boxes overlap?
"""
function boxesoverlap(box1::AbstractVector, box2::AbstractVector)
    dim=Int(length(box1)/2);
    @assert 2*dim == length(box2) "Mismatched boxes"
    for i=1:dim
        if box1[2*i-1]>box2[2*i]
            return false;
        end
        if box1[2*i]<box2[2*i-1]
            return false;
        end
    end
    return  true;
end

"""
    intersectboxes(box1::AbstractVector, box2::AbstractVector)

Compute the intersection of two boxes.

The function returns an empty box (length(b) == 0) if the intersection is
empty; otherwise a box is returned.
"""
function intersectboxes(box1::AbstractVector, box2::AbstractVector)
    @assert length(box1) == length(box2) "Mismatched boxes"
    b = copy(box1)
    dim=Int(length(box1)/2);
    @assert 2*dim == length(box2) "Wrong box data"
    for i=1:dim
        lb = max(box1[2*i-1], box2[2*i-1])
        ub = min(box1[2*i], box2[2*i])
        if (ub <= lb) # intersection is empty
            return eltype(box1)[] # box of length zero signifies empty intersection
        end
        b[2*i-1] = lb
        b[2*i]   = ub
    end
    return  b;
end

end


text:
"""
An abstract type for real-valued 1-d profiles.
"""
abstract type Abstract1DProfile end

using ForwardDiff

import Base: >>, <<

"""
    ConstantProfile(c::Number)

Create a profile consisting of a constant `c`.

# Example

```jldoctest
julia> p = SpaceTimeFields.ConstantProfile(1.0)
Constant (2.3)
```
"""
struct ConstantProfile <: Abstract1DProfile
    c::Number
end

function show(io::IO, p::ConstantProfile)
    print(io, "Constant ($(p.c))")
end

(p::ConstantProfile)(t) = p.c

struct DerivativeProfile{P} <: Abstract1DProfile
    p::P
end

function show(io::IO, ṗ::DerivativeProfile)
    print(io, "d/dt ($(ṗ.p))")
end

(ṗ::DerivativeProfile)(t) = ForwardDiff.derivative(ṗ.p, t)

"""
    d_dt(p::Abstract1DProfile)

Take the time derivative of `p` and return it as a new profile.

# Example

```jldoctest
julia> s = SpaceTimeFields.Sinusoid(π)
Sinusoid (ω = 3.14)

julia> s.([0.0, 0.5, 0.75])
3-element Array{Float64,1}:
 0.0
 1.0
 0.707107

julia> c = SpaceTimeFields.d_dt(s)
d/dt (Sinusoid (ω = 3.14))

julia> c.([0.0, 0.5, 0.75])
3-element Array{Float64,1}:
  3.14159
  1.92367e-16
 -2.22144
```
"""
d_dt(p::Abstract1DProfile) = DerivativeProfile(p)

struct ScaledProfile{N <: Real, P <: Abstract1DProfile} <: Abstract1DProfile
    s::N
    p::P
end
function show(io::IO, p::ScaledProfile)
    print(io, "$(p.s) × ($(p.p))")
end

"""
    s::Number * p::Abstract1DProfile

Returns a scaled profile with `(s*p)(t) = s*p(t)`

# Example

```jldoctest
julia> s = SpaceTimeFields.Sinusoid(π)
Sinusoid (ω = 3.14)

julia> 2s
2 × (Sinusoid (ω = 3.14))

julia> (2s).([0.0, 0.5, 0.75])
3-element Array{Float64,1}:
 0.0
 2.0
 1.41421
```
"""
s::Number * p::Abstract1DProfile = ScaledProfile(s, p)

"""
    -(p₁::Abstract1DProfile, p₂::Abstract1DProfile)

```jldoctest
julia> s = SpaceTimeFields.Sinusoid(π)
Sinusoid (ω = 3.14)

julia> 2s
2 × (Sinusoid (ω = 3.14))

julia> (2s).([0.0, 0.5, 0.75])
3-element Array{Float64,1}:
 0.0
 2.0
 1.41421

julia> s = SpaceTimeFields.Sinusoid(π);

julia> s.([0.0, 0.5, 0.75])
3-element Array{Float64,1}:
 0.0
 1.0
 0.707107

julia> (-s).([0.0, 0.5, 0.75])
3-element Array{Float64,1}:
 -0.0
 -1.0
 -0.707107

julia> (s - s).([0.0, 0.5, 0.75])
3-element Array{Float64,1}:
 0.0
 0.0
 0.0
```
"""
-(p::Abstract1DProfile) = ScaledProfile(-1, p)
(p::ScaledProfile)(t) = p.s*p.p(t)

struct ShiftedProfile{N <: Real, P <: Abstract1DProfile} <: Abstract1DProfile
    Δt::N
    p::P
end
function show(io::IO, p::ShiftedProfile)
    print(io, "$(p.p) >> $(p.Δt)")
end

(p::ShiftedProfile)(t) = p.p(t - p.Δt)

"""
    p::Abstract1DProfile >> Δt::Number

Shift the profile in time so that `(p >> Δt)(t) = p(t - Δt)`

# Example

```jldoctest
julia> s = SpaceTimeFields.Sinusoid(π);

julia> s >> 0.5
Sinusoid (ω = 3.14) >> 0.5

julia> (s >> 0.5).([0.0, 0.5, 0.75])
3-element Array{Float64,1}:
 -1.0
  0.0
  0.707107

julia> (s << 0.5).([0.0, 0.5, 0.75])
3-element Array{Float64,1}:
  1.0
  1.22465e-16
 -0.707107
```
"""
>>(p::Abstract1DProfile,Δt::Number) = ShiftedProfile(Δt, p)
<<(p::Abstract1DProfile,Δt::Number) = ShiftedProfile(-Δt, p)

#p::Abstract1DProfile >> Δt::Number = ShiftedProfile(Δt, p)
#p::Abstract1DProfile << Δt::Number = ShiftedProfile(-Δt, p)

struct AddedProfiles{T <: Tuple} <: Abstract1DProfile
    ps::T
end
function show(io::IO, Σp::AddedProfiles)
    println(io, "AddedProfiles:")
    for p in Σp.ps
        println(io, "  $p")
    end
end

"""
    p₁::Abstract1DProfile + p₂::Abstract1DProfile

Add the profiles so that `(p₁ + p₂)(t) = p₁(t) + p₂(t)`.

# Examples

```jldoctest
julia> ramp₁ = SpaceTimeFields.EldredgeRamp(5)
logcosh ramp (aₛ = 5.0)

julia> ramp₂ = SpaceTimeFields.ColoniusRamp(5)
power series ramp (n = 5.0)

julia> ramp₁ + ramp₂
AddedProfiles:
  logcosh ramp (aₛ = 5.0)
  power series ramp (n = 5.0)

julia> ramp₁ + (ramp₂ + ramp₁) == ramp₁ + ramp₂ + ramp₁
true

```
"""
+(p::Abstract1DProfile, Σp::AddedProfiles) = AddedProfiles((p, Σp.ps...))
+(Σp::AddedProfiles, p::Abstract1DProfile) = AddedProfiles((Σp.ps..., p))
function +(Σp₁::AddedProfiles, Σp₂::AddedProfiles)
    AddedProfiles((Σp₁..., Σp₂...))
end

-(p₁::Abstract1DProfile, p₂::Abstract1DProfile) = p₁ + (-p₂)

+(p::Abstract1DProfile...) = AddedProfiles(p)

function (Σp::AddedProfiles)(t)
    f = 0.0
    for p in Σp.ps
        f += p(t)
    end
    f
end

struct MultipliedProfiles{T <: Tuple} <: Abstract1DProfile
    ps::T
end
function show(io::IO, Πp::MultipliedProfiles)
    println(io, "MultipliedProfiles:")
    for p in Πp.ps
        println(io, "  $p")
    end
end
*(p::Abstract1DProfile, Πp::MultipliedProfiles) = MultipliedProfiles((p, Πp.ps...))
*(Πp::MultipliedProfiles, p::Abstract1DProfile) = MultipliedProfiles((Πp.ps..., p))
function *(Πp₁::MultipliedProfiles, Πp₂::MultipliedProfiles)
    MultipliedProfiles((Πp₁..., Πp₂...))
end

function (Πp::MultipliedProfiles)(t)
    f = 1.0
    for p in Πp.ps
        f *= p(t)
    end
    f
end

## Functional forms of profiles

"""
    Gaussian(σ,x0,A)

Construct a 1-d Gaussian function centered at `x0` with standard deviation `σ`
and amplitude `A`. The resulting function can be evaluated at any real-valued
number.

# Example

```jldoctest
julia> g = Gaussian(0.2,1)
Gaussian(0.2, 1, 2.8209479177387813)

julia> g(0.2)
1.0377687435514866
```
"""
struct Gaussian <: Abstract1DProfile
  σ :: Real
  A :: Real
  fact :: Float64
  Gaussian(σ,A) = new(σ,A,A/sqrt(π*σ^2))
end
show(io::IO, s::Gaussian) = print(io,
      "Gaussian (σ = $(round(s.σ, digits=2)), A = $(round(s.A, digits=2)))")

@inline _gaussian(r;tol=6.0) = abs(r) < tol ? exp(-r^2) : 0.0

radius(g::Gaussian) = g.σ
strength(g::Gaussian) = g.A

(g::Gaussian)(x) = g.fact*_gaussian(x/radius(g))

DGaussian(σ,A) = d_dt(Gaussian(σ,A))

struct Sinusoid <: Abstract1DProfile
    ω::Float64
end
(s::Sinusoid)(t) = sin(s.ω*t)
show(io::IO, s::Sinusoid) = print(io, "Sinusoid (ω = $(round(s.ω, digits=2)))")

struct EldredgeRamp <: Abstract1DProfile
    aₛ::Float64
end
(r::EldredgeRamp)(t) = 0.5(log(2cosh(r.aₛ*t)) + r.aₛ*t)/r.aₛ
show(io::IO, r::EldredgeRamp) = print(io, "logcosh ramp (aₛ = $(round(r.aₛ, digits=2)))")

struct ColoniusRamp <: Abstract1DProfile
    n::Int
end
function (r::ColoniusRamp)(t)
    Δt = t + 0.5
    if Δt ≤ 0
        0.0
    elseif Δt ≥ 1
        Δt - 0.5
    else
        f = 0.0
        for j = 0:r.n
            f += binomial(r.n + j, j)*(r.n - j + 1)*(1 - Δt)^j
        end
        f*Δt^(r.n + 2)/(2r.n + 2)
    end
end
show(io::IO, r::ColoniusRamp) = print(io, "power series ramp (n = $(round(r.n, digits=2)))")