text:
module PythonCall

const VERSION = v"0.6.1"

using Base: @propagate_inbounds
using MacroTools, Dates, Tables, Markdown, Serialization, Requires, Pkg

include("utils.jl")

include("cpython/CPython.jl")

include("Py.jl")
include("err.jl")
include("config.jl")
include("convert.jl")
# abstract interfaces
include("abstract/object.jl")
include("abstract/iter.jl")
include("abstract/builtins.jl")
include("abstract/number.jl")
include("abstract/collection.jl")
# concrete types
include("concrete/import.jl")
include("concrete/consts.jl")
include("concrete/str.jl")
include("concrete/bytes.jl")
include("concrete/tuple.jl")
include("concrete/list.jl")
include("concrete/dict.jl")
include("concrete/bool.jl")
include("concrete/int.jl")
include("concrete/float.jl")
include("concrete/complex.jl")
include("concrete/set.jl")
include("concrete/slice.jl")
include("concrete/range.jl")
include("concrete/none.jl")
include("concrete/type.jl")
include("concrete/fraction.jl")
include("concrete/method.jl")
include("concrete/datetime.jl")
include("concrete/code.jl")
include("concrete/ctypes.jl")
include("concrete/numpy.jl")
# @py
# anything below can depend on @py, anything above cannot
include("py_macro.jl")
# jlwrap
include("jlwrap/base.jl")
include("jlwrap/raw.jl")
include("jlwrap/callback.jl")
include("jlwrap/any.jl")
include("jlwrap/module.jl")
include("jlwrap/type.jl")
include("jlwrap/iter.jl")
include("jlwrap/objectarray.jl")
include("jlwrap/array.jl")
include("jlwrap/vector.jl")
include("jlwrap/dict.jl")
include("jlwrap/set.jl")
include("jlwrap/number.jl")
include("jlwrap/io.jl")
# pywrap
include("pywrap/PyIterable.jl")
include("pywrap/PyList.jl")
include("pywrap/PySet.jl")
include("pywrap/PyDict.jl")
include("pywrap/PyArray.jl")
include("pywrap/PyIO.jl")
include("pywrap/PyTable.jl")
include("pywrap/PyPandasDataFrame.jl")
# misc
include("pyconst_macro.jl")
include("juliacall.jl")
include("compat/stdlib.jl")
include("compat/with.jl")
include("compat/multimedia.jl")
include("compat/serialization.jl")
include("compat/gui.jl")
include("compat/ipython.jl")
include("compat/tables.jl")

function __init__()
    C.with_gil() do
        init_consts()
        init_pyconvert()
        init_datetime()
        # juliacall/jlwrap
        init_juliacall()
        init_jlwrap_base()
        init_jlwrap_raw()
        init_jlwrap_callback()
        init_jlwrap_any()
        init_jlwrap_module()
        init_jlwrap_type()
        init_jlwrap_iter()
        init_jlwrap_array()
        init_jlwrap_vector()
        init_jlwrap_dict()
        init_jlwrap_set()
        init_jlwrap_number()
        init_jlwrap_io()
        init_juliacall_2()
        # compat
        init_stdlib()
        init_pyshow()
        init_gui()
        init_ipython()
        init_tables()
        init_numpy()
        init_ctypes()
    end
    @require PyCall="438e738f-606a-5dbb-bf0a-cddfbfd45ab0" init_pycall(PyCall)
end

function init_pycall(PyCall::Module)
    # allow explicit conversion between PythonCall.Py and PyCall.PyObject
    # provided they are using the same interpretr
    errmsg = """
    Conversion between `PyCall.PyObject` and `PythonCall.Py` is only possible when using the same Python interpreter.

    There are two ways to achieve this:
    - Set the environment variable `JULIA_PYTHONCALL_EXE` to `"@PyCall"`. This forces PythonCall to use the same
      interpreter as PyCall, but PythonCall loses the ability to manage its own dependencies.
    - Set the environment variable `PYTHON` to `PythonCall.C.CTX.exe_path` and rebuild PyCall. This forces PyCall
      to use the same interpreter as PythonCall, but needs to be repeated whenever you switch Julia environment.
    """
    @eval function Py(x::$PyCall.PyObject)
        C.CTX.matches_pycall::Bool || error($errmsg)
        return pynew(C.PyPtr($PyCall.pyreturn(x)))
    end
    @eval function $PyCall.PyObject(x::Py)
        C.CTX.matches_pycall::Bool || error($errmsg)
        return $PyCall.PyObject($PyCall.PyPtr(incref(getptr(x))))
    end
end

end


text:
#=
This file is auto-generated. Do not edit.
=#
"""
    mutable struct Transformer2W <: ACBranch
        name::String
        available::Bool
        active_power_flow::Float64
        reactive_power_flow::Float64
        arc::Arc
        r::Float64
        x::Float64
        primary_shunt::Float64
        rate::Union{Nothing, Float64}
        services::Vector{Service}
        ext::Dict{String, Any}
        time_series_container::InfrastructureSystems.TimeSeriesContainer
        internal::InfrastructureSystemsInternal
    end

The 2-W transformer model uses an equivalent circuit assuming the impedance is on the High Voltage Side of the transformer. The model allocates the iron losses and magnetizing susceptance to the primary side.

# Arguments
- `name::String`
- `available::Bool`
- `active_power_flow::Float64`
- `reactive_power_flow::Float64`
- `arc::Arc`
- `r::Float64`: System per-unit value, validation range: `(-2, 4)`, action if invalid: `warn`
- `x::Float64`: System per-unit value, validation range: `(-2, 4)`, action if invalid: `warn`
- `primary_shunt::Float64`: System per-unit value, validation range: `(0, 2)`, action if invalid: `warn`
- `rate::Union{Nothing, Float64}`, validation range: `(0, nothing)`, action if invalid: `error`
- `services::Vector{Service}`: Services that this device contributes to
- `ext::Dict{String, Any}`
- `time_series_container::InfrastructureSystems.TimeSeriesContainer`: internal time_series storage
- `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify
"""
mutable struct Transformer2W <: ACBranch
    name::String
    available::Bool
    active_power_flow::Float64
    reactive_power_flow::Float64
    arc::Arc
    "System per-unit value"
    r::Float64
    "System per-unit value"
    x::Float64
    "System per-unit value"
    primary_shunt::Float64
    rate::Union{Nothing, Float64}
    "Services that this device contributes to"
    services::Vector{Service}
    ext::Dict{String, Any}
    "internal time_series storage"
    time_series_container::InfrastructureSystems.TimeSeriesContainer
    "power system internal reference, do not modify"
    internal::InfrastructureSystemsInternal
end

function Transformer2W(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, rate, services=Device[], ext=Dict{String, Any}(), time_series_container=InfrastructureSystems.TimeSeriesContainer(), )
    Transformer2W(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, rate, services, ext, time_series_container, InfrastructureSystemsInternal(), )
end

function Transformer2W(; name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, rate, services=Device[], ext=Dict{String, Any}(), time_series_container=InfrastructureSystems.TimeSeriesContainer(), internal=InfrastructureSystemsInternal(), )
    Transformer2W(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, rate, services, ext, time_series_container, internal, )
end

# Constructor for demo purposes; non-functional.
function Transformer2W(::Nothing)
    Transformer2W(;
        name="init",
        available=false,
        active_power_flow=0.0,
        reactive_power_flow=0.0,
        arc=Arc(Bus(nothing), Bus(nothing)),
        r=0.0,
        x=0.0,
        primary_shunt=0.0,
        rate=nothing,
        services=Device[],
        ext=Dict{String, Any}(),
        time_series_container=InfrastructureSystems.TimeSeriesContainer(),
    )
end

"""Get [`Transformer2W`](@ref) `name`."""
get_name(value::Transformer2W) = value.name
"""Get [`Transformer2W`](@ref) `available`."""
get_available(value::Transformer2W) = value.available
"""Get [`Transformer2W`](@ref) `active_power_flow`."""
get_active_power_flow(value::Transformer2W) = get_value(value, value.active_power_flow)
"""Get [`Transformer2W`](@ref) `reactive_power_flow`."""
get_reactive_power_flow(value::Transformer2W) = get_value(value, value.reactive_power_flow)
"""Get [`Transformer2W`](@ref) `arc`."""
get_arc(value::Transformer2W) = value.arc
"""Get [`Transformer2W`](@ref) `r`."""
get_r(value::Transformer2W) = value.r
"""Get [`Transformer2W`](@ref) `x`."""
get_x(value::Transformer2W) = value.x
"""Get [`Transformer2W`](@ref) `primary_shunt`."""
get_primary_shunt(value::Transformer2W) = value.primary_shunt
"""Get [`Transformer2W`](@ref) `rate`."""
get_rate(value::Transformer2W) = get_value(value, value.rate)
"""Get [`Transformer2W`](@ref) `services`."""
get_services(value::Transformer2W) = value.services
"""Get [`Transformer2W`](@ref) `ext`."""
get_ext(value::Transformer2W) = value.ext
"""Get [`Transformer2W`](@ref) `time_series_container`."""
get_time_series_container(value::Transformer2W) = value.time_series_container
"""Get [`Transformer2W`](@ref) `internal`."""
get_internal(value::Transformer2W) = value.internal

"""Set [`Transformer2W`](@ref) `available`."""
set_available!(value::Transformer2W, val) = value.available = val
"""Set [`Transformer2W`](@ref) `active_power_flow`."""
set_active_power_flow!(value::Transformer2W, val) = value.active_power_flow = set_value(value, val)
"""Set [`Transformer2W`](@ref) `reactive_power_flow`."""
set_reactive_power_flow!(value::Transformer2W, val) = value.reactive_power_flow = set_value(value, val)
"""Set [`Transformer2W`](@ref) `arc`."""
set_arc!(value::Transformer2W, val) = value.arc = val
"""Set [`Transformer2W`](@ref) `r`."""
set_r!(value::Transformer2W, val) = value.r = val
"""Set [`Transformer2W`](@ref) `x`."""
set_x!(value::Transformer2W, val) = value.x = val
"""Set [`Transformer2W`](@ref) `primary_shunt`."""
set_primary_shunt!(value::Transformer2W, val) = value.primary_shunt = val
"""Set [`Transformer2W`](@ref) `rate`."""
set_rate!(value::Transformer2W, val) = value.rate = set_value(value, val)
"""Set [`Transformer2W`](@ref) `services`."""
set_services!(value::Transformer2W, val) = value.services = val
"""Set [`Transformer2W`](@ref) `ext`."""
set_ext!(value::Transformer2W, val) = value.ext = val
"""Set [`Transformer2W`](@ref) `time_series_container`."""
set_time_series_container!(value::Transformer2W, val) = value.time_series_container = val

ext: jl


text:
"""
Basic types for identifying nodes participating in Paxos
"""
module Nodes

export NodeID

using UUIDs

struct NodeID
  value::UUID
end

"""
Return a new node ID
"""
NodeID() = NodeID(uuid4())

end


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

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing
        el
    end
end

# ╔═╡ 63ee8730-898e-11eb-0b20-c7e282000ee1
begin
	using PlutoUI # user-interface do Pluto.jl
	using Plots  # Julia package para gráficos
	using Dierckx  # Julia package para interpolação/extrapolação de dados
end

# ╔═╡ 3bc2bef1-b886-4fd1-a248-9d70a5551275
html"<button onclick='present()'>present</button>"

# ╔═╡ 8c0dc890-8be4-11eb-020b-1f0a062e06e2
md"""
# Máquinas de corrente contínua (Ex. 2)
Geradores de corrente contínua, exercício 2:
"""

# ╔═╡ 4464f340-898e-11eb-11d3-7f2dbd9ddb43
md"""
**Um gerador de corrente contínua $$[220\rm{V}, 12A, 1500rpm]$$ com excitação independente foi ensaiado em vazio e em carga, à velocidade nominal, tendo-se obtido as seguintes características:**
"""

# ╔═╡ 267f3200-8993-11eb-0428-a143f63b73db
md"""
Característica magnética: $$E_{0} =f(I_{exc})$$
com   $$n=constante$$
"""

# ╔═╡ 8a04fa10-8990-11eb-1acc-81903fcd9035
begin
	Iexc=[0.0, 0.25, 0.5, 0.75, 1.0, 1.5]
	E₀_1500=[20.0, 180.0, 238.0, 270.0, 284.0, 300.0]
	Iexc,E₀_1500
end

# ╔═╡ 39fea680-8993-11eb-25db-b3706ff6d45c
md"""
Característica externa: $$U =f(I)$$
com   $$n, R_{c}=constantes$$
"""

# ╔═╡ a8eecb8e-8990-11eb-1505-2f6355544f27
begin
	I=[0.0, 5.0, 10.0, 15.0, 20.0]
	U=[278.0, 260.0, 242.0, 216.0, 186.0]
	I,U
end

# ╔═╡ 2b8dbd10-898f-11eb-1253-f75830db2223
md"""
## a) Excitação separada
**Determine a queda de tensão interna total deste gerador.**
"""

# ╔═╡ c4d42c20-898f-11eb-0b5c-a54461ef6e5d
md"""
A tensão de vazio, $$U_{0}$$, depende da f.e.m. (controlado pelo circuito de excitação independente), $$U_{0}=E_{0}=$$ $(U[1,1])V
"""

# ╔═╡ 59a6e600-8993-11eb-2e5b-e7fba59b24bd
md"""
Queda de tensão total: $$\Delta U_{t}=E_{0}-U$$, com $$E_{0}$$ constante (não depende da corrente de carga).
"""

# ╔═╡ 545a5cfe-8996-11eb-2949-933aca247397
ΔUₜ=U[1,1].-U[:,1]

# ╔═╡ dff67510-89e1-11eb-06e0-51e2742ae650

# ╔═╡ 46f1ccc0-899b-11eb-38f4-b1430cdc3a32
md"""
!!! nota
	### Obter família de curvas 💻
	**Com base numa $$U =f(I)$$ pode-se obter uma família de características externas em função da corrente de campo e da velocidade de accionamento do gerador:**
"""

# ╔═╡ 47cb8820-89e1-11eb-3cd7-13c43f8d2b6d
md"""
Variação da f.e.m. com a velocidade (a partir do *slider* "Velocidade"):
"""

# ╔═╡ 9fb581f3-ad5c-45e5-8189-6f3800f174fd
md"""
> Forma computacional para consultar o valor da corrente de campo, para uma dada f.e.m. por interpolação:
"""

# ╔═╡ efafae10-8c37-11eb-04f9-399f14eb077d
#utilizando pkg Dierckx.jl
begin
	Spl_Iexc=Spline1D(E₀_1500,Iexc)
	Id00=Spl_Iexc(U[1,1])
	Id00=round(Id00, digits=2)
end;

# ╔═╡ d77b4d88-c7a6-4150-91ad-650467cafc8e
md"""
> Forma computacional para consultar o valor da f.e.m. à velocidade $$n$$, para uma dada corrente de campo, por interpolação:
"""

# ╔═╡ 342f3fc6-0dbb-4c0e-897b-4eb09153f996
begin
	H3=("Velocidade", @bind rpm PlutoUI.Slider(500:10:2000, default=1500, show_value=true))
	H3
end

# ╔═╡ 2fb64df0-89d8-11eb-0a6a-39826bc54d5d
E₀ₙ=round.((rpm/1500).*E₀_1500, digits=1)

# ╔═╡ a2a9e0e7-7c3d-40fb-af72-33faf1e6fb33
begin
	H2=("Iexc, corrente de excitação (exc. separada)", @bind Icampo PlutoUI.Slider(0:0.01:1.5, default=Id00, show_value=true))
	H2
end

# ╔═╡ 66553710-8c38-11eb-128e-65c4e8384922
#utilizando pkg Dierckx.jl
begin
	Spl_E₀ₙ=Spline1D(Iexc,E₀ₙ)
	E₀exx=Spl_E₀ₙ(Icampo)
	E₀exx=round(E₀exx, digits=2)
end;

# ╔═╡ 0ae6ec70-8b07-11eb-1975-519f634d69c1
begin
	H1=("Rcarga", @bind Rcarga PlutoUI.Slider(10:1000, default=20, show_value=true))
	H1
end

# ╔═╡ 2db74110-89c1-11eb-2c74-c1ed910c31e5
begin
	Uspeed=E₀exx.-ΔUₜ
	P1=plot(I,Uspeed, title="U=f(I)", xlabel = "I(A)", ylabel="U(V)", ylims=(0,420), xlims=(0,20), label="U=f(I)")
	plot!(I, Rcarga*I, xlims=(0,20),ylims=(0,400), linestyle=:dash, label="Reta de Carga=$(Rcarga)Ω", legend=:best)
	plot!(I,ΔUₜ, label="ΔUₜ", linecolor=:black)
	plot!([E₀exx], seriestype = :hline, linecolor=:green, label="E₀=f(I) => constante, U₀=$(round(E₀exx))V", legend=:topleft)
	P2=plot(Iexc,E₀ₙ,title="E₀=f(Iₑₓ), n=$(rpm)rpm", xflip=false, ylims=(0,400), xlabel = "Iₑₓ(A)", ylabel="E₀(V)", xlims=(0,1.5), label=false)
	plot!([Icampo], seriestype = :vline, linecolor=:green,linestyle=:dash, xlims=(0,1.5),ylims=(0,400), label="ponto de excitação=$(Icampo)A", legend=:bottomright)
	plot!([E₀exx], seriestype = :hline, linecolor=:green, linestyle=:dash, xlims=(0,1.5),ylims=(0,400), label=:none, legend=:bottomright)
	plot(P2, P1, layout = (1, 2))
end

# ╔═╡ 2c8d8e20-89c1-11eb-3562-e593af0e3888

# ╔═╡ b4912ee0-8998-11eb-2983-057aac94bbc2
md"""
## b) Excitação derivação
**O que é a resistência crítica de um gerador com uma excitação derivação? Qual a sua importância? Como se determina (aproximadamente) na prática?**
"""

# ╔═╡ 6873a262-8b08-11eb-1888-2f618e7b6ad4
md"""
A resistência crítica serve para determinar o valor máximo de resistência de um circuito de excitação e consequentemente dimensionar o valor máximo do reostato de campo. Pode ser determinada aproximadamente pelo 1º par de valores não nulos da característica magnética.
"""

# ╔═╡ a6b68340-899a-11eb-3981-bf8c4737e639
Rcrítica=E₀_1500[2,1]/Iexc[2,1]

# ╔═╡ 662608e0-8b08-11eb-187a-696ada1a8283
begin
	plot(Iexc,E₀_1500,title="E₀=f(Iₑₓ), n=1500rpm", xflip=false, ylims=(0,400), xlabel = "Iₑₓ(A)", ylabel="E₀(V)", xlims=(0,1.5), label=false)
	plot!(Iexc,E₀_1500.-E₀_1500[1,1], label="E₀-E₀ᵣₑₘ")
	plot!(Iexc,Rcrítica.*Iexc,label="Rcrítica")
end

# ╔═╡ 5ed2b082-89a4-11eb-20c7-79404ae96ed9
md"""
## c)
**Qual a resistência do enrolamento indutor, sabendo que como gerador derivação, à velocidade nominal, sem resistência de campo, $$U_0=294\rm{V}$$.**
"""

# ╔═╡ 0f63f472-c660-4732-9485-9a6298c52c08
md"""
A recta de excitação, $$U=R_{ex}I_d$$, determina o valor da tensão em vazio $$U_0$$ no ponto de intersecção com a característica magnética. Por conseguinte, não havendo reostato de campo, $$R_c=0Ω$$, a resistência do circuito de excitação, $$R_{ex}=R_c+R_d$$, corresponde apenas à resistência do enrolamento indutor, $$R_d$$.
"""

# ╔═╡ dd772af0-89e6-11eb-3776-c91da554ac2f
begin
		Id_294=round(Spl_Iexc(294), digits=2)
		Rd=round(294/Id_294, digits=1)
end;

# ╔═╡ d7471031-93bf-446f-b8b3-c7f23c424ac5
md"""
Assim, em dois passos determina-se o valor de $$R_{ex}=R_d$$:
- consultar a característica magnética para obter a corrente de campo correspondente a $$U_0=294$$V;
- cálculo da resistência do circuito de excitação
Obtém-se, $$R_d=$$ $(Rd)Ω
"""

# ╔═╡ 19cb80f0-89e7-11eb-3ab5-d9b274fce8c2

# ╔═╡ dd4bf910-89e2-11eb-0963-f91f846b1631
md"""
## d) Variação de  $$U =f(I)$$ com $$R_c$$ 💻
**Explicite qualitativamente qual a influência que a variação da resistência de campo tem, sobre a característica externa do gerador derivação. Justifique sucintamente.**
"""

# ╔═╡ 76c8e570-89b7-11eb-3875-b381a16288d2
begin
	H4=("Rexc, resistência total do circuito de excitação derivação", @bind Rexc PlutoUI.Slider(300/1.5:1:Rcrítica, default=356, show_value=true)) #default=278/Id00
	H4
end

# ╔═╡ abcd49a0-8a70-11eb-03b1-8dc34c0d2099
begin
	j=0.001
	id=0:j:1.5
	E₀shunt=Spline1D(Iexc,E₀ₙ)
	E₀_shunt=E₀shunt(id)
	ΔUₜ_exc=E₀_shunt-Rexc.*id
	ii=count(i->(i>= 0), ΔUₜ_exc)
	ΔUₜ_exc=ΔUₜ_exc[ΔUₜ_exc .>= 0]
	id_ii=0:j:((ii-1)*j)
	Ishunt=Spline1D(ΔUₜ,I)
	I_shunt=Ishunt(ΔUₜ_exc)
end;

# ╔═╡ e43a8b50-8a79-11eb-0b48-994a055418e7
begin
	Ud=Rexc.*id_ii
	I_shunt, id_ii, Ud, ΔUₜ_exc
	P3=plot(I_shunt,Ud, title="Característica externa", xlabel = "I(A)", ylabel="U(V)", ylims=(0,400), xlims=(0,30), label=false,linewidth=2)
	plot!(I, Rcarga.*I, label="Reta de Carga", legend=:topright)
	plot!(I_shunt, ΔUₜ_exc, label="ΔUₜ", legend=:topright)
	P4=plot(Iexc,E₀ₙ,title="Característica vazio", xflip=true, ylims=(0,400), xlabel = "Id(A)", ylabel="U₀(V)", xlims=(0,1.5), label=false, linewidth=2)
	plot!(id, Rexc.*id, xlims=(0,1.5),ylims=(0,400), label="Reta de excitação", legend=:topright)
	plot(P4, P3, layout = (1, 2))
end

# ╔═╡ 7d00fd4c-7ff5-4702-92fc-15db87026c5c
md"""
!!! nota
	### Variação de  $$U =f(I)$$ com $$n$$ 💻
	**Observe o comportamento da característica externa do gerador derivação, $$U =f(I)$$, para diferentes valores de velocidade de accionamento, $$n$$ , e reóstato de campo constante, $$R_c=constante$$. \
	Compare com o resultado anterior.**
"""

# ╔═╡ de153c80-89e2-11eb-17c3-cd70d615d6ef
md"""
## e)
**Nas condições de excitação da alínea c), como proceder para obter uma tensão de vazio de $$336\rm{V}$$.**
"""

# ╔═╡ 1685fd70-89e8-11eb-1473-cdfbd0fdba57
begin
	Id=round(336/(Rd), digits=1)
	Kϕ=300/1500
	n=336/Kϕ
end;

# ╔═╡ 950b164a-a605-4dfb-93e1-31297489430d
md"""
Não havendo reóstato de campo, apenas é possível ajustar de tensão de vazio através da velocidade de accionamento.
Calculando, obtém-se: $$n=$$ $(n) rpm
"""

# ╔═╡ a8c35150-89e9-11eb-2f3c-d5b5b352d408

# ╔═╡ f2ceacb5-51f3-46e6-a8f8-719a2e8cfc42
md"""
# Setup
"""

# ╔═╡ c2970a25-f58d-45d7-8187-cbf12d0c3a15
TableOfContents(title="📚 Índice, Exercício 2")

# ╔═╡ 43cbf32d-f2df-48f4-b454-5a7e7b011156
md"""
!!! info
	No índice deste *notebook*, os tópicos assinalados com "💻" permitem interacção com o utilizador.
"""

# ╔═╡ 71bb6235-34dd-4cb8-9354-6e2cf9c23932
md"""
## _Julia packages_
*Links to package help*: [Dierckx](https://github.com/kbarbary/Dierckx.jl), [Plots](http://docs.juliaplots.org/latest/), [PlutoUI](https://juliahub.com/docs/PlutoUI/abXFp/0.7.6/)
"""

# ╔═╡ 8748c630-8c83-11eb-2abe-5f6b058a4fb0
md"""
!!! info
	## Programação _Julia_ e _notebooks Pluto_
	Saber mais sobre: [_Julia_/_Pluto_](https://github.com/Ricardo-Luis/notebooks/blob/main/ME2/README.md)
"""

# ╔═╡ bf33336b-550c-4df9-a703-121ea7275920
version=VERSION;

# ╔═╡ 1a40a9b8-8b7e-41e7-95f8-a3a21835dfe6
md"""
## _Notebook_

*Notebook* realizado em linguagem de programação *Julia* versão $(version) para a unidade curricular de Máquinas Elétricas 2 (ISEL\LEE) \
**Ricardo Luís** (Professor Adjunto, ISEL\DEEEA\GDME) \
ISEL, 11/Out/2021
"""

# ╔═╡ 30141ef2-bd2f-442a-80aa-62f352daedc5
md"""
Este conteúdo possui licença [![](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/).
"""

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
Dierckx = "39dd38d3-220a-591b-8e3c-4c3a8c710a94"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"

[compat]
Dierckx = "~0.5.1"
Plots = "~1.22.4"
PlutoUI = "~0.7.15"
"""

# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised

[[Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "84918055d15b3114ede17ac6a7182f68870c16f7"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.1"

[[ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"

[[Artifacts]]
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"

[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.8+0"

[[Cairo_jll]]
deps = ["Artifacts", "Bzip2_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "f2202b55d816427cd385a9a4f3ffb226bee80f99"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.1+0"

[[ColorSchemes]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random"]
git-tree-sha1 = "a851fec56cb73cfdf43762999ec72eff5b86882a"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.15.0"

[[ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "024fe24d83e4a5bf5fc80501a314ce0d1aa35597"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.11.0"

[[Colors]]
deps = ["ColorTypes", "FixedPointNumbers", "Reexport"]
git-tree-sha1 = "417b0ed7b8b838aa6ca0a87aadf1bb9eb111ce40"
uuid = "5ae59095-9a9b-59fe-a467-6f913c188581"
version = "0.12.8"

[[Compat]]
deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"]
git-tree-sha1 = "31d0151f5716b655421d9d75b7fa74cc4e744df2"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.39.0"

[[CompilerSupportLibraries_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"

[[Contour]]
deps = ["StaticArrays"]
git-tree-sha1 = "9f02045d934dc030edad45944ea80dbd1f0ebea7"
uuid = "d38c429a-6771-53c6-b99e-75d170b6e991"
version = "0.5.7"

[[DataAPI]]
git-tree-sha1 = "cc70b17275652eb47bc9e5f81635981f13cea5c8"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.9.0"

[[DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "7d9d316f04214f7efdbb6398d545446e246eff02"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.10"

[[DataValueInterfaces]]
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
version = "1.0.0"

[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[DelimitedFiles]]
deps = ["Mmap"]
uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"

[[Dierckx]]
deps = ["Dierckx_jll"]
git-tree-sha1 = "5fefbe52e9a6e55b8f87cb89352d469bd3a3a090"
uuid = "39dd38d3-220a-591b-8e3c-4c3a8c710a94"
version = "0.5.1"

[[Dierckx_jll]]
deps = ["CompilerSupportLibraries_jll", "Libdl", "Pkg"]
git-tree-sha1 = "a580560f526f6fc6973e8bad2b036514a4e3b013"
uuid = "cd4c43a9-7502-52ba-aa6d-59fb2a88580b"
version = "0.0.1+0"

[[Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[Downloads]]
deps = ["ArgTools", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"

[[EarCut_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "3f3a2501fa7236e9b911e0f7a588c657e822bb6d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.2.3+0"

[[Expat_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b3bfd02e98aedfa5cf885665493c5598c350cd2f"
uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
version = "2.2.10+0"

[[FFMPEG]]
deps = ["FFMPEG_jll"]
git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8"
uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
version = "0.4.1"

[[FFMPEG_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "Pkg", "Zlib_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"]
git-tree-sha1 = "d8a578692e3077ac998b50c0217dfd67f21d1e5f"
uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
version = "4.4.0+0"

[[FixedPointNumbers]]
deps = ["Statistics"]
git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc"
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
version = "0.8.4"

[[Fontconfig_jll]]
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.93+0"

[[Formatting]]
deps = ["Printf"]
git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8"
uuid = "59287772-0a20-5a39-b81b-1366585eb4c0"
version = "0.4.2"

[[FreeType2_jll]]
deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "87eb71354d8ec1a96d4a7636bd57a7347dde3ef9"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.4+0"

[[FriBidi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91"
uuid = "559328eb-81f9-559d-9380-de523a88c83c"
version = "1.0.10+0"

[[GLFW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"]
git-tree-sha1 = "dba1e8614e98949abfa60480b13653813d8f0157"
uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
version = "3.3.5+0"

[[GR]]
deps = ["Base64", "DelimitedFiles", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "Sockets", "Test", "UUIDs"]
git-tree-sha1 = "c2178cfbc0a5a552e16d097fae508f2024de61a3"
uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
version = "0.59.0"

[[GR_jll]]
deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Pkg", "Qt5Base_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "cafe0823979a5c9bff86224b3b8de29ea5a44b2e"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.61.0+0"

[[GeometryBasics]]
deps = ["EarCut_jll", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"]
git-tree-sha1 = "58bcdf5ebc057b085e58d95c138725628dd7453c"
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
version = "0.4.1"

[[Gettext_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046"
uuid = "78b55507-aeef-58d4-861c-77aaff3498b1"
version = "0.21.0+0"

[[Glib_jll]]
deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "7bf67e9a481712b3dbe9cb3dac852dc4b1162e02"
uuid = "7746bdde-850d-59dc-9ae8-88ece973131d"
version = "2.68.3+0"

[[Graphite2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011"
uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472"
version = "1.3.14+0"

[[Grisu]]
git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2"
uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe"
version = "1.0.2"

[[HTTP]]
deps = ["Base64", "Dates", "IniFile", "Logging", "MbedTLS", "NetworkOptions", "Sockets", "URIs"]
git-tree-sha1 = "14eece7a3308b4d8be910e265c724a6ba51a9798"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.9.16"

[[HarfBuzz_jll]]
deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"]
git-tree-sha1 = "8a954fed8ac097d5be04921d595f741115c1b2ad"
uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566"
version = "2.8.1+0"

[[Hyperscript]]
deps = ["Test"]
git-tree-sha1 = "8d511d5b81240fc8e6802386302675bdf47737b9"
uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91"
version = "0.0.4"

[[HypertextLiteral]]
git-tree-sha1 = "f6532909bf3d40b308a0f360b6a0e626c0e263a8"
uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
version = "0.9.1"

[[IOCapture]]
deps = ["Logging", "Random"]
git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a"
uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
version = "0.2.2"

[[IniFile]]
deps = ["Test"]
git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8"
uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
version = "0.5.0"

[[InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

[[IterTools]]
git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.3.0"

[[IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "642a199af8b68253517b80bd3bfd17eb4e84df6e"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.3.0"

[[JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
git-tree-sha1 = "8076680b162ada2a031f707ac7b4953e30667a37"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.2"

[[JpegTurbo_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d735490ac75c5cb9f1b00d8b5509c11984dc6943"
uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8"
version = "2.1.0+0"

[[LAME_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c"
uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d"
version = "3.100.1+0"

[[LZO_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6"
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.1+0"

[[LaTeXStrings]]
git-tree-sha1 = "c7f1c695e06c01b95a67f0cd1d34994f3e7db104"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.2.1"

[[Latexify]]
deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "Printf", "Requires"]
git-tree-sha1 = "a4b12a1bd2ebade87891ab7e36fdbce582301a92"
uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
version = "0.15.6"

[[LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"

[[LibCURL_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"

[[LibGit2]]
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"

[[LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"

[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[Libffi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "761a393aeccd6aa92ec3515e428c26bf99575b3b"
uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490"
version = "3.2.2+0"

[[Libgcrypt_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"]
git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae"
uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4"
version = "1.8.7+0"

[[Libglvnd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"]
git-tree-sha1 = "7739f837d6447403596a75d19ed01fd08d6f56bf"
uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29"
version = "1.3.0+3"

[[Libgpg_error_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9"
uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8"
version = "1.42.0+0"

[[Libiconv_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "42b62845d70a619f063a7da093d995ec8e15e778"
uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
version = "1.16.1+1"

[[Libmount_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73"
uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9"
version = "2.35.0+0"

[[Libtiff_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"]
git-tree-sha1 = "340e257aada13f95f98ee352d316c3bed37c8ab9"
uuid = "89763e89-9b03-5906-acba-b20f662cd828"
version = "4.3.0+0"

[[Libuuid_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066"
uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700"
version = "2.36.0+0"

[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[MacroTools]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "5a5bc6bf062f0f95e62d0fe0a2d99699fed82dd9"
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
version = "0.5.8"

[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[MbedTLS]]
deps = ["Dates", "MbedTLS_jll", "Random", "Sockets"]
git-tree-sha1 = "1c38e51c3d08ef2278062ebceade0e46cefc96fe"
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
version = "1.0.3"

[[MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"

[[Measures]]
git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f"
uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
version = "0.3.1"

[[Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "bf210ce90b6c9eed32d25dbcae1ebc565df2687f"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.2"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"

[[MozillaCACerts_jll]]
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"

[[NaNMath]]
git-tree-sha1 = "bfe47e760d60b82b66b61d2d44128b62e3a369fb"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "0.3.5"

[[NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"

[[Ogg_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7937eda4681660b4d6aeeecc2f7e1c81c8ee4e2f"
uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
version = "1.3.5+0"

[[OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "15003dcb7d8db3c6c857fda14891a539a8f2705a"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.10+0"

[[Opus_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720"
uuid = "91d4177d-7536-5919-b921-800302f37372"
version = "1.3.2+0"

[[OrderedCollections]]
git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.4.1"

[[PCRE_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b2a7af664e098055a7529ad1a900ded962bca488"
uuid = "2f80f16e-611a-54ab-bc61-aa92de5b98fc"
version = "8.44.0+0"

[[Parsers]]
deps = ["Dates"]
git-tree-sha1 = "a8709b968a1ea6abc2dc1967cb1db6ac9a00dfb6"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.0.5"

[[Pixman_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b4f5d02549a10e20780a24fce72bea96b6329e29"
uuid = "30392449-352a-5448-841d-b1acce4e97dc"
version = "0.40.1+0"

[[Pkg]]
deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[PlotThemes]]
deps = ["PlotUtils", "Requires", "Statistics"]
git-tree-sha1 = "a3a964ce9dc7898193536002a6dd892b1b5a6f1d"
uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
version = "2.0.1"

[[PlotUtils]]
deps = ["ColorSchemes", "Colors", "Dates", "Printf", "Random", "Reexport", "Statistics"]
git-tree-sha1 = "b084324b4af5a438cd63619fd006614b3b20b87b"
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
version = "1.0.15"

[[Plots]]
deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "GeometryBasics", "JSON", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "PlotThemes", "PlotUtils", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs"]
git-tree-sha1 = "6841db754bd01a91d281370d9a0f8787e220ae08"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
version = "1.22.4"

[[PlutoUI]]
deps = ["Base64", "Dates", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "Random", "Reexport", "UUIDs"]
git-tree-sha1 = "633f8a37c47982bff23461db0076a33787b17ecd"
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
version = "0.7.15"

[[Preferences]]
deps = ["TOML"]
git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.2"

[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[[Qt5Base_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"]
git-tree-sha1 = "ad368663a5e20dbb8d6dc2fddeefe4dae0781ae8"
uuid = "ea2cea3b-5b76-57ae-a6ef-0a8af62496e1"
version = "5.15.3+0"

[[REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[RecipesBase]]
git-tree-sha1 = "44a75aa7a527910ee3d1751d1f0e4148698add9e"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.1.2"

[[RecipesPipeline]]
deps = ["Dates", "NaNMath", "PlotUtils", "RecipesBase"]
git-tree-sha1 = "7ad0dfa8d03b7bcf8c597f59f5292801730c55b8"
uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c"
version = "0.4.1"

[[Reexport]]
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.2.2"

[[Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "4036a3bd08ac7e968e27c203d45f5fff15020621"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.1.3"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Scratch]]
deps = ["Dates"]
git-tree-sha1 = "0b4b7f1393cff97c33891da2a0bf69c6ed241fda"
uuid = "6c6a2e73-6563-6170-7368-637461726353"
version = "1.1.0"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"

[[Showoff]]
deps = ["Dates", "Grisu"]
git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de"
uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
version = "1.0.3"

[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

[[SortingAlgorithms]]
deps = ["DataStructures"]
git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508"
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
version = "1.0.1"

[[SparseArrays]]
deps = ["LinearAlgebra", "Random"]
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "3c76dde64d03699e074ac02eb2e8ba8254d428da"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.13"

[[Statistics]]
deps = ["LinearAlgebra", "SparseArrays"]
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[[StatsAPI]]
git-tree-sha1 = "1958272568dc176a1d881acb797beb909c785510"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.0.0"

[[StatsBase]]
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "8cbbc098554648c84f79a463c9ff0fd277144b6c"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.33.10"

[[StructArrays]]
deps = ["Adapt", "DataAPI", "StaticArrays", "Tables"]
git-tree-sha1 = "2ce41e0d042c60ecd131e9fb7154a3bfadbf50d3"
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
version = "0.6.3"

[[TOML]]
deps = ["Dates"]
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

[[TableTraits]]
deps = ["IteratorInterfaceExtensions"]
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"

[[Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "TableTraits", "Test"]
git-tree-sha1 = "fed34d0e71b91734bf0a7e10eb1bb05296ddbcd0"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.6.0"

[[Tar]]
deps = ["ArgTools", "SHA"]
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"

[[Test]]
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[URIs]]
git-tree-sha1 = "97bbe755a53fe859669cd907f2d96aee8d2c1355"
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
version = "1.3.0"

[[UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[[Wayland_jll]]
deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "3e61f0b86f90dacb0bc0e73a0c5a83f6a8636e23"
uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89"
version = "1.19.0+0"

[[Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll"]
git-tree-sha1 = "2839f1c1296940218e35df0bbb220f2a79686670"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.18.0+4"

[[XML2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "1acf5bdf07aa0907e0a37d3718bb88d4b687b74a"
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
version = "2.9.12+0"

[[XSLT_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"]
git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a"
uuid = "aed1982a-8fda-507f-9586-7b0439959a61"
version = "1.1.34+0"

[[Xorg_libX11_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"]
git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527"
uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc"
version = "1.6.9+4"

[[Xorg_libXau_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e"
uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec"
version = "1.0.9+4"

[[Xorg_libXcursor_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd"
uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724"
version = "1.2.0+4"

[[Xorg_libXdmcp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4"
uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05"
version = "1.1.3+4"

[[Xorg_libXext_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3"
uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3"
version = "1.3.4+4"

[[Xorg_libXfixes_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4"
uuid = "d091e8ba-531a-589c-9de9-94069b037ed8"
version = "5.0.3+4"

[[Xorg_libXi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"]
git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246"
uuid = "a51aa0fd-4e3c-5386-b890-e753decda492"
version = "1.7.10+4"

[[Xorg_libXinerama_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"]
git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123"
uuid = "d1454406-59df-5ea1-beac-c340f2130bc3"
version = "1.1.4+4"

[[Xorg_libXrandr_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631"
uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484"
version = "1.5.2+4"

[[Xorg_libXrender_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96"
uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa"
version = "0.9.10+4"

[[Xorg_libpthread_stubs_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb"
uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74"
version = "0.1.0+3"

[[Xorg_libxcb_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"]
git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6"
uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b"
version = "1.13.0+3"

[[Xorg_libxkbfile_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "926af861744212db0eb001d9e40b5d16292080b2"
uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a"
version = "1.1.0+4"

[[Xorg_xcb_util_image_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97"
uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b"
version = "0.4.0+1"

[[Xorg_xcb_util_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll"]
git-tree-sha1 = "e7fd7b2881fa2eaa72717420894d3938177862d1"
uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5"
version = "0.4.0+1"

[[Xorg_xcb_util_keysyms_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "d1151e2c45a544f32441a567d1690e701ec89b00"
uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7"
version = "0.4.0+1"

[[Xorg_xcb_util_renderutil_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "dfd7a8f38d4613b6a575253b3174dd991ca6183e"
uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e"
version = "0.3.9+1"

[[Xorg_xcb_util_wm_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "e78d10aab01a4a154142c5006ed44fd9e8e31b67"
uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361"
version = "0.4.1+1"

[[Xorg_xkbcomp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxkbfile_jll"]
git-tree-sha1 = "4bcbf660f6c2e714f87e960a171b119d06ee163b"
uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4"
version = "1.4.2+4"

[[Xorg_xkeyboard_config_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xkbcomp_jll"]
git-tree-sha1 = "5c8424f8a67c3f2209646d4425f3d415fee5931d"
uuid = "33bec58e-1273-512f-9401-5d533626f822"
version = "2.27.0+4"

[[Xorg_xtrans_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845"
uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10"
version = "1.4.0+3"

[[Zlib_jll]]
deps = ["Libdl"]
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"

[[Zstd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "cc4bf3fdde8b7e3e9fa0351bdeedba1cf3b7f6e6"
uuid = "3161d3a3-bdf6-5164-811a-617609db77b4"
version = "1.5.0+0"

[[libass_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47"
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
version = "0.15.1+0"

[[libfdk_aac_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55"
uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280"
version = "2.0.2+0"

[[libpng_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c"
uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f"
version = "1.6.38+0"

[[libvorbis_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"]
git-tree-sha1 = "c45f4e40e7aafe9d086379e5578947ec8b95a8fb"
uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a"
version = "1.3.7+0"

[[nghttp2_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"

[[p7zip_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"

[[x264_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2021.5.5+0"

[[x265_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9"
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
version = "3.5.0+0"

[[xkbcommon_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"]
git-tree-sha1 = "ece2350174195bb31de1a63bea3a41ae1aa593b6"
uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd"
version = "0.9.1+5"
"""

# ╔═╡ Cell order:
# ╟─3bc2bef1-b886-4fd1-a248-9d70a5551275
# ╟─8c0dc890-8be4-11eb-020b-1f0a062e06e2
# ╟─4464f340-898e-11eb-11d3-7f2dbd9ddb43
# ╟─267f3200-8993-11eb-0428-a143f63b73db
# ╠═8a04fa10-8990-11eb-1acc-81903fcd9035
# ╟─39fea680-8993-11eb-25db-b3706ff6d45c
# ╠═a8eecb8e-8990-11eb-1505-2f6355544f27
# ╟─2b8dbd10-898f-11eb-1253-f75830db2223
# ╟─c4d42c20-898f-11eb-0b5c-a54461ef6e5d
# ╟─59a6e600-8993-11eb-2e5b-e7fba59b24bd
# ╠═545a5cfe-8996-11eb-2949-933aca247397
# ╟─dff67510-89e1-11eb-06e0-51e2742ae650
# ╟─46f1ccc0-899b-11eb-38f4-b1430cdc3a32
# ╟─47cb8820-89e1-11eb-3cd7-13c43f8d2b6d
# ╠═2fb64df0-89d8-11eb-0a6a-39826bc54d5d
# ╟─9fb581f3-ad5c-45e5-8189-6f3800f174fd
# ╠═efafae10-8c37-11eb-04f9-399f14eb077d
# ╟─d77b4d88-c7a6-4150-91ad-650467cafc8e
# ╠═66553710-8c38-11eb-128e-65c4e8384922
# ╟─342f3fc6-0dbb-4c0e-897b-4eb09153f996
# ╟─a2a9e0e7-7c3d-40fb-af72-33faf1e6fb33
# ╟─0ae6ec70-8b07-11eb-1975-519f634d69c1
# ╟─2db74110-89c1-11eb-2c74-c1ed910c31e5
# ╟─2c8d8e20-89c1-11eb-3562-e593af0e3888
# ╟─b4912ee0-8998-11eb-2983-057aac94bbc2
# ╟─6873a262-8b08-11eb-1888-2f618e7b6ad4
# ╠═a6b68340-899a-11eb-3981-bf8c4737e639
# ╟─662608e0-8b08-11eb-187a-696ada1a8283
# ╟─5ed2b082-89a4-11eb-20c7-79404ae96ed9
# ╟─0f63f472-c660-4732-9485-9a6298c52c08
# ╟─d7471031-93bf-446f-b8b3-c7f23c424ac5
# ╠═dd772af0-89e6-11eb-3776-c91da554ac2f
# ╟─19cb80f0-89e7-11eb-3ab5-d9b274fce8c2
# ╟─dd4bf910-89e2-11eb-0963-f91f846b1631
# ╟─abcd49a0-8a70-11eb-03b1-8dc34c0d2099
# ╟─76c8e570-89b7-11eb-3875-b381a16288d2
# ╟─e43a8b50-8a79-11eb-0b48-994a055418e7
# ╟─7d00fd4c-7ff5-4702-92fc-15db87026c5c
# ╟─de153c80-89e2-11eb-17c3-cd70d615d6ef
# ╟─950b164a-a605-4dfb-93e1-31297489430d
# ╠═1685fd70-89e8-11eb-1473-cdfbd0fdba57
# ╟─a8c35150-89e9-11eb-2f3c-d5b5b352d408
# ╟─f2ceacb5-51f3-46e6-a8f8-719a2e8cfc42
# ╠═c2970a25-f58d-45d7-8187-cbf12d0c3a15
# ╟─43cbf32d-f2df-48f4-b454-5a7e7b011156
# ╟─71bb6235-34dd-4cb8-9354-6e2cf9c23932
# ╠═63ee8730-898e-11eb-0b20-c7e282000ee1
# ╟─8748c630-8c83-11eb-2abe-5f6b058a4fb0
# ╟─1a40a9b8-8b7e-41e7-95f8-a3a21835dfe6
# ╟─bf33336b-550c-4df9-a703-121ea7275920
# ╟─30141ef2-bd2f-442a-80aa-62f352daedc5
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_name: Ricardo-Luis/notebooks

max_issues_repo_name: Ricardo-Luis/notebooks

max_forks_repo_name: Ricardo-Luis/notebooks


text:
"""
    solve_newton is a symbolic Newton-Ralphson solver
    f is a symbolic equation to be solved (f ~ 0)
    x is the variable to solve
    x₀ is the initial guess
"""
function solve_newton(f, x, x₀; abstol=1e-8, maxiter=50)
    xₙ = Complex(x₀)
    ∂f = differentiate(f, x)

    for i = 1:maxiter
        xₙ₊₁ = xₙ - f(xₙ) / ∂f(xₙ)

        if abs(xₙ₊₁ - xₙ) < abstol
            return xₙ₊₁
        else
            xₙ = xₙ₊₁
        end
    end
    return nothing
end

"""
    find_roots returns all the real and complex roots of a polynomial (poly)
    for variable x

    the output is rs, sz, where rs is a list of real roots and zs is a list of
    complex roots

    if poly is not a polynomial, the number of desired roots (n) needs to be
    provided. For example, find_roots(sin(x), x, 10) returns 10 different, but
    not necessarily sequential, multiples of π
"""
function find_roots(T, p::AbstractPolynomial, x, n=-1; abstol=1e-8)
    n = (n == -1 ? deg(p, x) : n)
    rs = T[]
    zs = Complex{T}[]
    abstol = T(abstol)

    while n > 0
        z = solve_newton(p, x, exp(2π*im*rand()); abstol=abstol)
        if z != nothing
            if abs(imag(z)) < abstol
                r = real(z)
                push!(rs, r)
                p = p ÷ (x - r)
                n -= 1
            else
                if abs(real(z)) < abstol
                    z = Complex(0, imag(z))
                end
                append!(zs, [z, conj(z)])
                p = p ÷ (x^2 - 2x*real(z) + abs2(z))
                n -= 2
            end
        end
    end
    sort(rs), zs
end

function find_roots(p::AbstractPolynomial, x, n=-1; abstol=1e-8)
    find_roots(Float64, p, x, n; abstol=abstol)
end


text:
# This file is a part of Julia. License is MIT: http://julialang.org/license

@testset "RowVector" begin

@testset "Core" begin
    v = [1,2,3]
    z = [1+im,2,3]

    @test RowVector(v) == [1 2 3]
    @test RowVector{Int}(v) == [1 2 3]
    @test size(RowVector{Int}(3)) === (1,3)
    @test size(RowVector{Int}(1,3)) === (1,3)
    @test size(RowVector{Int}((3,))) === (1,3)
    @test size(RowVector{Int}((1,3))) === (1,3)
    @test_throws ErrorException RowVector{Float64, Vector{Int}}(v)

    @test (v.')::RowVector == [1 2 3]
    @test (v')::RowVector == [1 2 3]
    @test (z.')::RowVector == [1+im 2 3]
    @test (z')::RowVector == [1-im 2 3]

    rv = v.'
    tz = z.'

    @test (rv.')::Vector == [1, 2, 3]
    @test (rv')::Vector == [1, 2, 3]
    @test (tz.')::Vector == [1+im, 2, 3]
    @test (tz')::Vector == [1-im, 2, 3]

    @test conj(rv) === rv
    @test conj(tz) == [1-im 2 3]

    @test isa(similar(rv), RowVector)
    @test isa(similar(rv, Float64), RowVector)
    @test isa(copy(rv), RowVector)

    @test rv[2] === v[2]
    @test rv[1,2] === v[2]

    @test (rv2 = copy(rv); rv2[2] = 6; rv2[2] === 6)
    @test (rv2 = copy(rv); rv2[1,2] = 6; rv2[2] === 6)

    @test length(rv) === 3
    @test size(rv) === (1,3)
    @test size(rv,1) === 1
    @test size(rv,2) === 3

    @test map(-, rv)::RowVector == [-1 -2 -3]
    @test (-).(rv)::RowVector == [-1 -2 -3]
    @test (-).(rv,1)::RowVector == [0  1  2]

    y = rand(Complex{Float64},3)
    @test sum(abs2, imag.(diag(y .+ y'))) < 1e-20
end

@testset "Diagonal ambiguity methods" begin
    d = Diagonal([1,2,3])
    v = [2,3,4]
    rv = v.'

    @test (rv*d)::RowVector == [2,6,12].'
    @test_throws DimensionMismatch d*rv

    @test (d*rv.')::Vector == [2,6,12]

    @test_throws DimensionMismatch rv.'*d

    @test (d*rv')::Vector == [2,6,12]

    @test_throws DimensionMismatch rv'*d

    @test (rv/d)::RowVector ≈ [2/1  3/2  4/3]

    @test_throws DimensionMismatch d \ rv
end

@testset "Bidiagonal ambiguity methods" begin
    bd = Bidiagonal([1,2,3], [0,0], true)
    v = [2,3,4]
    rv = v.'

    @test (rv/bd)::RowVector ≈ [2/1  3/2  4/3]

    @test_throws DimensionMismatch bd \ rv
end

@testset "hcat" begin
    @test isa([([1, 2, 3].') 4], RowVector{Int})
    @test isa([([1, 2, 3].') ([4, 5].')], RowVector{Int})
end

@testset "Left Division" begin
    mat = diagm([1,2,3])
    v = [2,3,4]
    rv = v.'

    @test_throws DimensionMismatch mat \ rv
end

@testset "Multiplication" begin
    v = [1,2,3]
    rv = v.'
    mat = diagm([1,2,3])

    @test (rv*v) === 14
    @test (rv*mat)::RowVector == [1 4 9]
    @test_throws DimensionMismatch [1]*reshape([1],(1,1)) # no longer permitted
    @test_throws DimensionMismatch rv*rv
    @test (v*rv)::Matrix == [1 2 3; 2 4 6; 3 6 9]
    @test_throws DimensionMismatch v*v # Was previously a missing method error, now an error message
    @test_throws DimensionMismatch mat*rv

    @test_throws DimensionMismatch rv*v.'
    @test (rv*mat.')::RowVector == [1 4 9]
    @test_throws DimensionMismatch [1]*reshape([1],(1,1)).' # no longer permitted
    @test rv*rv.' === 14
    @test_throws DimensionMismatch v*rv.'
    @test (v*v.')::Matrix == [1 2 3; 2 4 6; 3 6 9]
    @test (mat*rv.')::Vector == [1,4,9]

    @test (rv.'*v.')::Matrix == [1 2 3; 2 4 6; 3 6 9]
    @test_throws DimensionMismatch rv.'*mat.'
    @test (v.'*mat.')::RowVector == [1 4 9]
    @test_throws DimensionMismatch rv.'*rv.'
    @test v.'*rv.' === 14
    @test_throws DimensionMismatch v.'*v.'
    @test (mat.'*rv.')::Vector == [1,4,9]

    @test_throws DimensionMismatch rv.'*v
    @test_throws DimensionMismatch rv.'*mat
    @test (v.'*mat)::RowVector == [1 4 9]
    @test (rv.'*rv)::Matrix == [1 2 3; 2 4 6; 3 6 9]
    @test_throws DimensionMismatch v.'*rv
    @test v.'*v === 14
    @test_throws DimensionMismatch mat.'*rv

    z = [1+im,2,3]
    cz = z'
    mat = diagm([1+im,2,3])

    @test cz*z === 15 + 0im

    @test_throws DimensionMismatch cz*z'
    @test (cz*mat')::RowVector == [-2im 4 9]
    @test_throws DimensionMismatch [1]*reshape([1],(1,1))' # no longer permitted
    @test cz*cz' === 15 + 0im
    @test_throws DimensionMismatch z*cz'
    @test (z*z')::Matrix == [2 2+2im 3+3im; 2-2im 4 6; 3-3im 6 9]
    @test (mat*cz')::Vector == [2im,4,9]

    @test (cz'*z')::Matrix == [2 2+2im 3+3im; 2-2im 4 6; 3-3im 6 9]
    @test_throws DimensionMismatch cz'*mat'
    @test (z'*mat')::RowVector == [-2im 4 9]
    @test_throws DimensionMismatch cz'*cz'
    @test z'*cz' === 15 + 0im
    @test_throws DimensionMismatch z'*z'
    @test (mat'*cz')::Vector == [2,4,9]

    @test_throws DimensionMismatch cz'*z
    @test_throws DimensionMismatch cz'*mat
    @test (z'*mat)::RowVector == [2 4 9]
    @test (cz'*cz)::Matrix == [2 2+2im 3+3im; 2-2im 4 6; 3-3im 6 9]
    @test_throws DimensionMismatch z'*cz
    @test z'*z === 15 + 0im
    @test_throws DimensionMismatch mat'*cz
end

@testset "norm" begin
   @test norm([3.0,4.0].') ≈ 5.0
   @test norm([3.0,4.0].', 1) ≈ 4.0
   @test norm([3.0,4.0].', Inf) ≈ 7.0
end

@testset "QR ambiguity methods" begin
    qrmat = Base.LinAlg.getq(qrfact(eye(3)))
    v = [2,3,4]
    rv = v.'

    @test (rv*qrmat')::RowVector == [2 3 4]
end

@testset "Right Division" begin
    mat = diagm([1,2,3])
    v = [2,3,4]
    rv = v.'

    @test (rv/mat)::RowVector ≈ [2/1  3/2  4/3]

    @test (v.'/mat)::RowVector ≈ [2/1  3/2  4/3]
    @test (v.'/mat.')::RowVector ≈ [2/1  3/2  4/3]
    @test (rv/mat.')::RowVector ≈ [2/1  3/2  4/3]

    @test (v'/mat)::RowVector ≈ [2/1  3/2  4/3]
    @test (v'/mat')::RowVector ≈ [2/1  3/2  4/3]
    @test (rv/mat')::RowVector ≈ [2/1  3/2  4/3]
end

@testset "Sparse ambiguity methods" begin
    mat = sparse(diagm([1,2,3]))
    v = [2,3,4]
    rv = v.'

    @test (rv/mat)::RowVector ≈ [2/1  3/2  4/3]

    @test_throws DimensionMismatch mat\rv
end

@testset "AbstractTriangular ambiguity methods" begin
    ut = UpperTriangular([1 0 0; 0 2 0; 0 0 3])
    v = [2,3,4]
    rv = v.'

    @test (rv*ut)::RowVector == [2 6 12]
    @test_throws DimensionMismatch ut*rv

    @test (rv*ut.')::RowVector == [2 6 12]
    @test (ut*rv.')::Vector == [2,6,12]

    @test (ut.'*rv.')::Vector == [2,6,12]
    @test_throws DimensionMismatch rv.'*ut.'

    @test_throws DimensionMismatch ut.'*rv
    @test_throws DimensionMismatch rv.'*ut

    @test (rv*ut')::RowVector == [2 6 12]
    @test (ut*rv')::Vector == [2,6,12]

    @test_throws DimensionMismatch rv'*ut'
    @test (ut'*rv')::Vector == [2,6,12]

    @test_throws DimensionMismatch ut'*rv
    @test_throws DimensionMismatch rv'*ut

    @test (rv/ut)::RowVector ≈ [2/1  3/2  4/3]
    @test (rv/ut.')::RowVector ≈ [2/1  3/2  4/3]
    @test (rv/ut')::RowVector ≈ [2/1  3/2  4/3]

    @test_throws DimensionMismatch ut\rv
end

end # @testset "RowVector"

max_stars_repo_name: oxinabox/julia

max_issues_repo_name: oxinabox/julia

max_forks_repo_name: oxinabox/julia


text:
# source path in tasks
path = Base.source_path()
@test endswith(path, joinpath("test","test_sourcepath.jl"))
@test yieldto(@task Base.source_path()) == path

max_stars_repo_name: jakebolewski/julia

max_issues_repo_name: jakebolewski/julia

max_forks_repo_name: jakebolewski/julia


text:
# Functions to aid in discretizing sets.

" Discretize a given extent into smaller extents with a grid size of delta.
# Arguments
- `set::Dict` - Set to discretize
- `grid_sizes::Dict` - Discretization delta for each component
"
function discretize_set(set::Dict, grid_sizes::Dict)

    extents = []
    for dim_key in keys(set)
        x = set[dim_key]
        x_d = x[1]:grid_sizes[dim_key]:x[2]
        push!(extents, [[x_d[i], x_d[i+1]] for i=1:length(x_d)-1])
    end

    state_extents = Base.product(extents...)
    discrete_sets = Dict()
    for (i, state) in enumerate(state_extents)
        for (j, dim_key) in enumerate(collect(keys(set)))
            if j==1
                discrete_sets[i] = Dict(dim_key => state[j])
            else
                discrete_sets[i][dim_key] = state[j]
            end
        end
    end

    return discrete_sets
end

" Discretize a given extent into smaller extents with a grid size of delta.
# Arguments
- `set::Dict` - Set to discretize
- `grid_sizes::Dict` - Discretization delta for each component
"
function discretize_set_lazy(set::Dict, grid_sizes::Dict)
    # TODO: Generalize this for n-dimensions
    x = set["x1"]
    y = set["x2"]

    x_epsilons = x[1]:grid_sizes["x1"]:x[2]
    y_epsilons = y[1]:grid_sizes["x2"]:y[2]

    discrete_sets = Dict()
    discrete_extents = Dict()
    idx = 1
    for i = 1:length(x_epsilons)-1
        for j = 1:length(y_epsilons)-1
            new_extent = Dict("x1" => [x_epsilons[i], x_epsilons[i+1]], "x2" => [y_epsilons[j], y_epsilons[j+1]])
            new_polygon = VPolygon([[x_epsilons[i], y_epsilons[j]], [x_epsilons[i], y_epsilons[j+1]],
                                    [x_epsilons[i+1], y_epsilons[j+1]], [x_epsilons[i+1], y_epsilons[j]]])
            discrete_sets[idx] = new_polygon
            discrete_extents[idx] = new_extent
            idx += 1
        end
    end
    return discrete_sets, discrete_extents
end

" Refine a discrete state uniformly and update the region info dict.
# Arguments
- `region_id::Int` - Region id to refine
- `region_info_dict:Dict` - Dictionary containing all of the region info
"
function uniform_refinement(region_id, extent_dict)
    extent = extent_dict[region_id]
    delta_dict = Dict()
    for dim in keys(extent)
        delta_dict[dim] = (extent[dim][2] - extent[dim][1])/2
    end

    refined_sets = discretize_set(extent_dict[region_id], delta_dict)

    # ! Does ordering matter? I don't think it should
    N_old = maximum(keys(extent_dict))
    last_extent = extent_dict[N_old]

    # Remove old state
    pop!(extent_dict, region_id)
    new_keys = []
    for i=1:refined_sets.count
        new_key = N_old + i - 1
        extent_dict[N_old + i - 1] = refined_sets[i]
        new_keys = new_keys ∪ [new_key]
    end

    extent_dict[N_old + refined_sets.count + 1] = last_extent

    return extent_dict, new_keys
end


text:
"""
    $(SIGNATURES)
Initialize empty visualizer
"""
function initVis(;showLocal::Bool = true)
    vis = Visualizer()
    showLocal && open(vis)
    return vis
end

"""
    $(SIGNATURES)
Initialize empty visualizer
"""
function initBotVis2(;showLocal::Bool = true)::BotVis2
    vis = Visualizer()
    showLocal && open(vis)
    return BotVis2(vis,
                   # Dict{Symbol, NTuple{3,Float64}}(),
                   # Dict{Symbol, NTuple{3,Float64}}(),
                   Dict{Symbol, Tuple{Symbol, Vector{Bool}, Vector{Float64}}}() )
end

"""
    $(SIGNATURES)
Draw all poses in an 2d factor graph, use meanmax = :max or :mean for distribution max or mean, respectively.
"""
function drawPoses2!(botvis::BotVis2,
                     fgl::FactorGraph;
                     meanmax::Symbol=:max,
                     triadLength=0.25,
                     sessionId::String="Session" )::Nothing
    #
    xx, ll = Caesar.ls(fgl)

    for x in xx
        X = getKDE(fgl, x)
        xmx = meanmax == :max ? getKDEMax(X) : getKDEMean(X)
        trans = Translation(xmx[1:2]..., 0.0) ∘ LinearMap(RotZ(xmx[3]))
        if !haskey(botvis.cachevars, x)
            triad = Triad(triadLength)
            setobject!(botvis.vis[Symbol(sessionId)][:poses][x], triad)
            botvis.cachevars[x] = (:Pose2, [true;], xmx)
        else
            botvis.cachevars[x][3][:] = xmx
        end
        settransform!(botvis.vis[Symbol(sessionId)][:poses][x], trans)
    end
	return nothing
end

"""
    $(SIGNATURES)
Draw all landmarks in an 2d factor graph, use meanmax = :max or :mean for distribution max or mean, respectively.
"""
function drawLandmarks2!(botvis::BotVis2,
                         fgl::FactorGraph;
                         meanmax::Symbol=:max,
                         sessionId::String="Session"  )::Nothing
    #
    xx, ll = Caesar.ls(fgl)

    for x in ll
        X = getKDE(fgl, x)
        xmx = meanmax == :max ? getKDEMax(X) : getKDEMean(X)
        trans = Translation(xmx[1:2]..., 0.0)
        if !haskey(botvis.cachevars, x)
            setobject!(botvis.vis[Symbol(sessionId)][:landmarks][x], lmpoint, greenMat)
            botvis.cachevars[x] = (:Point2, [true;], [xmx[1]; xmx[2]; 0.0 ] )
        else
            botvis.cachevars[x][3][1:2] = xmx[1:2]
        end
        settransform!(botvis.vis[Symbol(sessionId)][:landmarks][x], trans)
    end
	return nothing
end

#


text:
"""
    six_dof_quaternion_fixed_mass(state, mass, inertia, forces, moments,
                                  h=[0.0, 0.0, 0.0], k=0.0)

Six degrees of freedom dynamic system using quaternions for attitude
representation and assuming fixed mass.

Flat Earth hypothesis is applied and Earth reference frame is considered
inertial.

It is considered that the aircraft xb-zb plane is a plane of symmetry so that
Jxy and Jyz cross-product of inertia are zero and will not be taken into
account.

The effects of the angular momentum produced by spinning rotors is taken into
account with the optional argument `h`.

# Arguments
- `state::12-element Array{Number,1}`: state vector.
    u, v, w: inertial linear velocity expressed in body axis. (m/s)
    p, q, r: inertial rotatinal velocity expressed in body axis. (rad/s)
    q0, q1, q2, q3: attitude given by quaternions.
    xe, ye, ze: position wrt the inertial system origin expressed in Earth Axis. (m)
- `mass::Number`: total mass of the aircraft (kg)
- `inertia::3×3 Array{Number,2}`: inertia tensor (kg·m²)
- `forces::3-element Array{Number,1}`: total forces expressed in body axis. (N)
- `moments::3-element Array{Number,1}`: total moments expressed in body axis.(N·m)
- `h::3-element Array{Number,1}`: Additional angular momentum contributions such
  as those coming from spinning rotors (kg·m²/s).
- `k::Number`: orthonormality error factor.

# Returns
- `state_dot`: state vector derivative according to the equation of motion,
    inertial properties and applied forces and moments.

# Notes
- See [1] (page 41, formula 1.4-23) or [2] (page 372, formulas 10-11 to 10-14)
  for more information on quaternions <-> Euler angles conversions.
- Orthonormality error factor is related to a numerical stability artifact used
  in angular kinematic equations. Let λ = k * (1 - q0² - q1² - q2² - q3²) be
  the orthonormality error. The term k·λ·q is added to the angular kinematic
  equations in order to reduce the numerical integration error. According to
  reference [2] k·Δt ≤ 1. See [2] (page 372) for more information on
  orthonormality error factor.

# References
- [1] Stevens, B. L., Lewis, F. L., (1992). Aircraft control and simulation:
 dynamics, controls design, and autonomous systems. John Wiley & Sons.
 (Section 1.5, equations 1.5-4, page 46)

- [2] Zipfel, P. H. (2007). Modeling and simulation of aerospace vehicle
 dynamics. American Institute of Aeronautics and Astronautics.
 (page 368, figure 10.2)
"""
function six_dof_quaternion_fixed_mass(state, mass, inertia, forces, moments,
                                       h=[0.0, 0.0, 0.0], k=0.0)

    m = mass

    u, v, w, p, q, r, q0, q1, q2, q3, xe, ye, ze = state

    Fx, Fy, Fz = forces
    L, M, N = moments

    q02, q12, q22, q32 = q0*q0, q1*q1, q2*q2, q3*q3

    # Normalization λ*t < 1 (See Zipfel Chapter 4.3.3.4 p.126)
    # Zipfel, P. H. (2007). Modeling and simulation of aerospace vehicle dynamics.
    # American Institute of Aeronautics and Astronautics.
    λ = k * (1.0 - q02 - q12 - q22 - q32)

    # Linear momentum equations
    u_dot = Fx / m + r * v - q * w
    v_dot = Fy / m - r * u + p * w
    w_dot = Fz / m + q * u - p * v

    # Angular momentum equations
    Ix = inertia[1, 1]
    Iy = inertia[2, 2]
    Iz = inertia[3, 3]
    Jxz = -inertia[1, 3]

    Jxz2 = Jxz*Jxz
    Γ = (Ix*Iz - Jxz2)
    temp = (Ix + Iz - Iy)
    Jxz2 = Jxz*Jxz
    den = (Ix*Iz - Jxz2)
    temp = (Ix + Iz - Iy)

    # Engine angular momentum contribution
    hx, hy, hz = h

    rhy_qhz = (r*hy - q*hz)
    qhx_phy = (q*hx - p*hy)

    pe_dot = Iz * rhy_qhz + Jxz * qhx_phy
    qe_dot = -r*hx + p*hz
    re_dot = Jxz * rhy_qhz + Ix * qhx_phy

    # Angular momentum equations
    p_dot = L*Iz + N*Jxz - q*r*(Iz*Iz - Iz*Iy + Jxz2) + p*q * Jxz * temp + pe_dot
    p_dot /= Γ
    q_dot = M + (Iz - Ix) * p*r - Jxz * (p*p - r*r) + qe_dot
    q_dot /= Iy
    r_dot = L*Jxz + N*Ix + p*q * (Ix*Ix - Ix*Iy + Jxz2) - q*r * Jxz * temp + re_dot
    r_dot /= Γ

    # Angular Kinematic equations
    q0_dot = 0.5 * (     - p*q1 - q*q2 - r*q3 ) + λ * q0
    q1_dot = 0.5 * (p*q0        + r*q2 - q*q3 ) + λ * q1
    q2_dot = 0.5 * (q*q0 - r*q1        + p*q3 ) + λ * q2
    q3_dot = 0.5 * (r*q0 + q*q1 - p*q2        ) + λ * q3

    # Linear kinematic equations
    xe_dot = u*(q02 + q12 - q22 - q32) + 2*v*(q1*q2 - q0*q3) + 2*w*(q1*q3 + q0*q2)
    ye_dot = 2*u*(q1*q2 + q0*q3) + v*(q02 - q12 + q22 - q32) + 2*w*(q2*q3 - q0*q1)
    ze_dot = 2*u*(q1*q3 - q0*q2) + 2*v*(q2*q3 + q0*q1) + w*(q02 - q12 - q22 + q32)

    [u_dot v_dot w_dot p_dot q_dot r_dot q0_dot q1_dot q2_dot q3_dot xe_dot ye_dot ze_dot]
end


text:
module RobotOS

using PyCall

#Empty imported modules for valid precompilation
const __sys__ = PyCall.PyNULL()
const __rospy__ = PyCall.PyNULL()

function __init__()
    #Put julia's ARGS into python's so remappings will work
    copy!(__sys__, pyimport("sys"))
    __sys__["argv"] = ARGS

    try
        copy!(__rospy__, pyimport("rospy"))
    catch ex
        if (isa(ex, PyCall.PyError) &&
            pycall(pybuiltin("str"), PyAny, ex.val) == "No module named rospy")
            error("rospy not found!\nHas an environment setup script been run?")
        else
            rethrow(ex)
        end
    end
end

include("debug.jl")
include("time.jl")
include("gentypes.jl")
include("rospy.jl")
include("pubsub.jl")
include("services.jl")

end


text:
@doc raw"""
    BasicStructural(y::Vector{Fl}, s::Int) where Fl

The basic structural state-space model consists of a trend (level + slope) and a seasonal
component. It is defined by:
```math
\begin{gather*}
    \begin{aligned}
        y_{t} &=  \mu_{t} + \gamma_{t} + \varepsilon_{t} \quad &\varepsilon_{t} \sim \mathcal{N}(0, \sigma^2_{\varepsilon})\\
        \mu_{t+1} &= \mu_{t} + \nu_{t} + \xi_{t} \quad &\xi_{t} \sim \mathcal{N}(0, \sigma^2_{\xi})\\
        \nu_{t+1} &= \nu_{t} + \zeta_{t} \quad &\zeta_{t} \sim \mathcal{N}(0, \sigma^2_{\zeta})\\
        \gamma_{t+1} &= -\sum_{j=1}^{s-1} \gamma_{t+1-j} + \omega_{t} \quad & \omega_{t} \sim \mathcal{N}(0, \sigma^2_{\omega})\\
    \end{aligned}
\end{gather*}
```

# Example
```jldoctest
julia> model = BasicStructural(rand(100), 12)
BasicStructural
```

# References
 * Durbin, James, & Siem Jan Koopman. (2012). "Time Series Analysis by State Space Methods: Second Edition." Oxford University Press.
"""
mutable struct BasicStructural <: StateSpaceModel
    hyperparameters::HyperParameters
    system::LinearUnivariateTimeInvariant
    seasonality::Int
    results::Results

    function BasicStructural(y::Vector{Fl}, s::Int) where Fl
        Z = [1; 0; 1; zeros(Fl, s - 2)]
        T = [
            1 1 zeros(Fl, 1, s - 1)
            0 1 zeros(Fl, 1, s - 1)
            0 0 -ones(Fl, 1, s - 1)
            zeros(Fl, s - 2, 2) Matrix{Fl}(I, s - 2, s - 2) zeros(Fl, s - 2)
        ]
        R = [
            Matrix{Fl}(I, 3, 3)
            zeros(Fl, s - 2, 3)
        ]
        d = zero(Fl)
        c = zeros(Fl, s + 1)
        H = one(Fl)
        Q = zeros(Fl, 3, 3)

        system = LinearUnivariateTimeInvariant{Fl}(y, Z, T, R, d, c, H, Q)

        names = ["sigma2_ε", "sigma2_ξ", "sigma2_ζ", "sigma2_ω"]
        hyperparameters = HyperParameters{Fl}(names)

        return new(hyperparameters, system, s, Results{Fl}())
    end
end

function default_filter(model::BasicStructural)
    Fl = typeof_model_elements(model)
    steadystate_tol = Fl(1e-5)
    a1 = zeros(Fl, num_states(model))
    P1 = Fl(1e6) .* Matrix{Fl}(I, num_states(model), num_states(model))
    return UnivariateKalmanFilter(a1, P1, num_states(model), steadystate_tol)
end

function initial_hyperparameters!(model::BasicStructural)
    Fl = typeof_model_elements(model)
    initial_hyperparameters = Dict{String,Fl}(
        "sigma2_ε" => one(Fl),
        "sigma2_ξ" => one(Fl),
        "sigma2_ζ" => one(Fl),
        "sigma2_ω" => one(Fl),
    )
    set_initial_hyperparameters!(model, initial_hyperparameters)
    return model
end

function constrain_hyperparameters!(model::BasicStructural)
    constrain_variance!(model, "sigma2_ε")
    constrain_variance!(model, "sigma2_ξ")
    constrain_variance!(model, "sigma2_ζ")
    constrain_variance!(model, "sigma2_ω")
    return model
end

function unconstrain_hyperparameters!(model::BasicStructural)
    unconstrain_variance!(model, "sigma2_ε")
    unconstrain_variance!(model, "sigma2_ξ")
    unconstrain_variance!(model, "sigma2_ζ")
    unconstrain_variance!(model, "sigma2_ω")
    return model
end

function fill_model_system!(model::BasicStructural)
    model.system.H = get_constrained_value(model, "sigma2_ε")
    model.system.Q[1] = get_constrained_value(model, "sigma2_ξ")
    model.system.Q[5] = get_constrained_value(model, "sigma2_ζ")
    model.system.Q[end] = get_constrained_value(model, "sigma2_ω")
    return model
end

function reinstantiate(model::BasicStructural, y::Vector{Fl}) where Fl
    return BasicStructural(y, model.seasonality)
end

has_exogenous(::BasicStructural) = false


text:
# TODO: maybe allow for different noise levels per dimension (i.e. allow to pass covariance matrix
# here.). But in that case, we would also need to weigh the different dimensions with the correct
# information matrix in the KKT constraint approach.

function generate_dataset(;
    solve_args,
    solve_kwargs = (; solver_attributes = (; print_level = 1)),
    noise_levels,
    n_observation_sequences_per_noise_level,
    rng = Random.MersenneTwister(1),
)
    converged_gt, forward_solution_gt, forward_opt_model_gt =
        solve_game(solve_args...; solve_kwargs...)
    @assert converged_gt

    # add additional time step to make last x relevant state obseravable in the partially observed
    # case
    x_extra = DynamicsModelInterface.next_x(
        solve_args.control_system,
        forward_solution_gt.x[:, end],
        forward_solution_gt.u[:, end],
    )

    # Note: reducing over inner loop to flatten the dataset
    dataset = mapreduce(vcat, noise_levels) do σ
        n_samples = iszero(σ) ? 1 : n_observation_sequences_per_noise_level
        observations = map(1:n_samples) do _
            (;
                σ,
                x = forward_solution_gt.x + σ * randn(rng, size(forward_solution_gt.x)),
                u = forward_solution_gt.u + σ * randn(rng, size(forward_solution_gt.u)),
                x_extra = x_extra + σ * randn(rng, size(x_extra)),
            )
        end
    end

    forward_solution_gt, dataset
end


text:
"""
`abstract Pipeline`

Description
============

Abstract supertype for all image processing pipelines.
Every subtype of `Pipeline` has to implement the methods
oulined below.

Methods
========

- **`fit!`** : Fits all the image operations of the pipeline,
which have learnable parameters, to the given trainingset.

- **`transform`** : Applies the image operations of the pipline
to the given image or set of images and returns those.

- **`summary`** : Computes and prints a verbose description of
the image processing pipeline. The computation for this function
is a little more involved than for `show`.

Author(s)
==========

- Christof Stocker (Github: https://github.com/Evizero)

see also
=========

`fit!`, `transform`, `summary`

`LinearPipeline`
"""
abstract Pipeline

Base.eltype{T<:Pipeline}(::Type{T}) = ImageTransformation


text:
#= Polyline encoder and decoder

This module performes an encoding and decoding for
gps coordinates into a polyline using the algorithm
detailed in:
https://developers.google.com/maps/documentation/utilities/polylinealgorithm

Example:
    julia> enc = encodePolyline([[38.5 -120.2]; [40.7 -120.95]; [43.252 -126.453]])
    "_p~iF~ps|U_ulLnnqC_mqNvxq`@"

Todo:
    * Add polyline decoding
=#

__precompile__()

module Polyline

export decodePolyline, encodePolyline

# coodrinate is a type to represents a gps data point
struct coordinate{T}
    Lat::T
    Lng::T
end

include("encode.jl")
include("decode.jl")
include("loadGPX.jl")

end # module


text:
module FirstAndLastPlaceValues

export ufp, ulp, uls, rre, ε⁻, ε⁺, eta

#=
References

Accurate Floating-Point Summation Part I: Faithful Rounding
Siegfried M. Rump, Takeshi Ogita and Shin'ichi Oishi
http://oishi.info.waseda.ac.jp/~oishi/papers/RuOgOi07I.pdf

Fast quadruple-double floating point format
Naoya Yamanaka and Shin’ichi Oishi
2014-Jan-01

Error Estimation of Floating-Point Summation and Dot Product
Siegfried M. Rump

On the definition of ulp(x)
Jean-Michel Muller

Computing predecessor and successor in rounding to nearest
Siegfried Rump, Paul Zimmermann, Sylvie Boldo, Guillaume Melquiond

On various ways to split a floating-point number
Claude-Pierre Jeannerod, Jean-Michel Muller, Paul Zimmermann
=#

two(::Type{T}) where {T<:Real} = one(T) + one(T)
two(::Type{Float64}) = 2.0
two(::Type{Float32}) = 2.0f0
two(::Type{Float16}) = Float16(2.0)

#=
  Nicolas Fabiano, Jean-Michel Muller, Joris Picot.
  Algorithms for triple-word arithmetic.
  IEEE Transactions on Computers, Institute of Electrical and Electronics Engineers, 2019, 68 (11), pp.1573-1583.
  10.1109/TC.2019.2918451. hal-01869009v2
  Sylvie Boldo, Mioara Joldes, Jean-Michel Muller, Valentina Popescu.
  Formal Verification of a FloatingPoint Expansion Renormalization Algorithm.
  8th International Conference on Interactive Theorem Proving (ITP’2017), Sep 2017, Brasilia, Brazil.
  hal-01512417f
  ACCURATE FLOATING-POINT SUMMATION PART I: FAITHFUL ROUNDING
  SIEGFRIED M. RUMP, TAKESHI OGITA, AND SHIN’ICHI OISHI
  in SIAM J. Sci. Comput. Volume 31, Issue 1, pp. 189-224 (2008)
=#

#=
  ufp(x)  unit in the first place
              the weight of the most significant bit
  ulp(x)  unit in the last place
              the weight of the least significant bit
  uls(x)  unit in the last significant place
              the weight of the rightmost nonzero bit
              the largest power of 2 that divides x
              the largest k s.t. x / 2^k is an integer

  reu(T)  roundoff error unit
             2^(-precision)
             ulp(1) / 2

  blp(x)  bit in the last place:              ulp(x) == 2.0^blp(x)
  bfp(x)  bit in the first place:             ufp(x) == 2.0^bfp(x)
  bls(x)  bit in the last significant place:  uls(x) == 2.0^bls(x)
=#
#=
julia> x = cbrt(17*pi)        #  3.765878158314341
julia> ufp(x),ulp(x),uls(x)   #  (2.0, 4.440892098500626e-16, 8.881784197001252e-16)
julia> bfp(x),blp(x),bls(x)   #  (1, -51, -50)
julia> x = 1/cbrt(17*pi)      #  0.26554231389355776
julia> ufp(x),ulp(x),uls(x)   #  (0.25, 5.551115123125783e-17, 4.440892098500626e-16)
julia> bfp(x),blp(x),bls(x)   #  (-2, -54, -51)
=#

#=
    The relative rounding error unit (reu) ,
    the distance from 1.0 to the next smaller floating-point number, is denoted by eps, and
    the underflow unit by eta, that is the smallest positive (subnormal) floating-point number.

For IEEE 754 double precision we have eps = 2^(−53) and eta = 2^(−1074).
      The smallest positive normalized floating-point number is ets = (1/2)(eps^(-1))(eta) = (1/2)(2^(53-1074))
=#
#=
const BitPrecision = 1 + trailing_ones(Base.significand_mask(Float64))  # 53 = 1 implicit bit + 52 significand bits

const reu = 1.0 - prevfloat(1.0)  # 2.0^(-53)          # 1.0 - prevfloat(1.0)
const eta = nextfloat(0.0)        # 2.0^(-1074)        # smallest positive subnormal == nextfloat(0.0)
const ets = floatmin(Float64)     # 2.0^(53-1074) / 2  # smallest positive normal    == floatmin(Float64)
=#

explicit_precision(::Type{T}) where {T} = trailing_ones(Base.significand_mask(T))
implicit_precision(::Type{T}) where {T} = one(T) + explicit_precision(T)

reu(::Type{T}) where {T} = one(T) - prevfloat(one(T))
eta(::Type{T}) where {T} = nextfloat(zero(T))
ets(::Type{T}) where {T} = floatmin(T)

ufp(x) = 2.0^floor(Int,log2(abs(x)))
ulp(x::T) where {T} = ufp(x) * 2.0^(-explicit_precision(T)+1)
uls(x) = ulp(x) * 2.0^(trailing_zeros(reinterpret(UInt64,x)))

bfp(x) = round(Int, log2(ufp(x)))
blp(x) = round(Int, log2(ulp(x)))
bls(x) = round(Int, log2(uls(x)))

# for x <= sqrt(floatmax(T)) !! bounds need testing
fast_ufp(x::Float64) = reinterpret(Float64, reinterpret(UInt64, x) & 0xfff0000000000000)
fast_ufp(x::Float32) = reinterpret(Float32, reinterpret(UInt32, x) & 0xfff0_0000)
fast_ufp(x::Float16) = reinterpret(Float16, reinterpret(UInt16, x) & 0xfff0)

#=
eta is the smallest positive (nonzero, denormal)
eta(T) = nextfloat(zero(T))
=#
eta(::Type{T}) where {T<:AbstractFloat} = nextfloat(zero(T))

eta(::Type{Float64}) = 5.0e-324
eta(::Type{Float32}) = 1.0f-45
eta(::Type{Float16}) = Float16(6.0e-8)

#=
  epsilon (ε)
  ε⁻(T) = (one(T) - prevfloat(one(T)))
  ε⁺(T) = (nextfloat(one(T)) - one(T))
=#
ε⁻(::Type{T}) where {T<:AbstractFloat} = (one(T) - prevfloat(one(T)))
ε⁺(::Type{T}) where {T<:AbstractFloat} = (nextfloat(one(T)) - one(T))

ε⁻(::Type{Float64}) = 1.1102230246251565e-16
ε⁻(::Type{Float32}) = 5.9604645f-8
ε⁻(::Type{Float16}) = Float16(0.0004883)

ε⁺(::Type{Float64}) = 2.220446049250313e-16
ε⁺(::Type{Float32}) = 1.1920929f-7
ε⁺(::Type{Float16}) = Float16(0.000977)

#=
  relative rounding error (rre)
  rre(T) = (nextfloat(one(T)) - one(T)) / (one(T) + one(T))
  rre(T) = eps(T) / 2
=#

rre(::Type{Float64}) = 1.1102230246251565e-16
rre(::Type{Float32}) = 1.1920929f-7
rre(::Type{Float16}) = Float16(0.000977)

rre(::Type{T}) where {T<:AbstractFloat} =
    (nextfloat(one(T)) - one(T)) / two(T)

#=
inv2rre(T)
=#
inv2rre(::Type{T}) where {T<:AbstractFloat} =
    inv(two(T))*rre(T) + one(T)

#=
ufp(x) unit in the first place of x

ufp(zero(T)) ≝ zero(T)

ufp(x::T) ≝ 2^floor(Int, log2(abs(x)))
          ≡ ldexp(one(T), floor(Int,log2(abs(x))))

the unsigned constants used in `ufp(x::T)`
     Float64: ((~UInt64(0)) >> 52) << 52
     Float32: ((~UInt32(0)) >> 23) << 23
     Float16: ((~UInt16(0)) >> 10) << 10

the shifts: Base.trailing_ones(Base.significand_mask)
=#

ulp(::Type{T}) where {T<:AbstractFloat} = two(T) * ε⁻(T)

ulp(::Type{Float64}) = 2.220446049250313e-16
ulp(::Type{Float32}) = 1.1920929f-7
ulp(::Type{Float16}) = Float16(0.000977)

ulp(x::T) where {T<:AbstractFloat} = two(T) * ε⁻(T) * ufp(x)
# ulp(x::T) where {T<:AbstractFloat} = ε⁺(T) * ufp(x)

ulp(x::Float64) = 2.220446049250313e-16 * ufp(x)
ulp(x::Float32) = 1.1920929f-7 * ufp(x)
ulp(x::Float16) = Float16(0.000977) * ufp(x)

end # FirstAndLastPlaceValues


text:
using CSV

###### population loader #################

_load_population(region::Union{AbstractString,Regex},path::AbstractString) = _load_population((r"^$",region),path)

function _load_population(region::NTuple{2,Union{AbstractString,Regex}},path::AbstractString)
    header = ["Subregion","Region", "Population"];
    types = Dict(1=>Union{Missing,String}, 2=>Union{Missing,String}, 3=>Int)
    fp = rstrip(path,'/')*"/population.csv"
    df = CSV.read(fp,header=header,copycols=true,ignoreemptylines=true,types=types)
    for col in [:Subregion,:Region]
        df[ismissing.(df[:,col]),col] .= ""
        df[:,col] = strip.(df[:,col])
    end
    sub = occursin.(region[2],df.Region) .& occursin.(region[1],df.Subregion)
    try
        df[sub,:Population][1]
    catch e
        isa(e, BoundsError) || rethrow(e)
        error("no entry in `$fp' for $region")
    end
end


text:
using Test
using DataValues

@testset "DataValueArray: SubArrays" begin

    nd = rand(3:5)
    sz = [ rand(3:10) for i in 1:nd ]
    X = DataValueArray(rand(sz...), rand(Bool, sz...))

    I = [ rand(1:sz[i]) for i in 1:nd ]
    H = [ rand(1:sz[i]) for i in 1:nd ]

    for i in 1:nd
        J = [ (x -> x == i ? I[x] : Colon())(j) for j in 1:nd ]
        S = view(X, J...)
        H = [ (x -> x == i ? I[x] : rand(1:sz[x]))(j) for j in 1:nd ]
        _H = H[findall(x -> x != i, collect(1:nd))]

        @test values(S, _H...) == X.values[H...]
        @test isna(S, _H...) == X.isna[H...]
        @test any(isna, S) == any(isna, X[J...])
    end

end


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

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing
        el
    end
end

# ╔═╡ 6e986f20-0270-11eb-071e-e14defbf6af7
begin
	import Pkg
	Pkg.activate(mktempdir())
	Pkg.add([
			"GraphPlot",
			"LightGraphs",
			"PlutoUI"])
	using LightGraphs
	import GraphPlot
	using PlutoUI
end

# ╔═╡ 66c4bda2-0271-11eb-3447-87dd5a3904bd
md"Graphs from [SpecialGraphs.jl](https://github.com/JuliaGraphs/SpecialGraphs.jl/tree/master/src)"

# ╔═╡ fbe17668-0272-11eb-1085-e98901c9ca7d
@bind choice Select(["cycle", "wheel", "complete", "path"])

# ╔═╡ 0adfb774-0273-11eb-29c7-7bab996d8314
@bind n Slider(2:10, show_value=true)

# ╔═╡ 2446ba56-0272-11eb-2ad1-3d16e6334601
graph_function = Dict("cycle" => cycle_graph, "wheel" => wheel_graph, "complete" => complete_graph, "path" => path_graph)[choice]

# ╔═╡ 9e153cba-0270-11eb-03fc-17dd33397b80
graph = graph_function(n)

# ╔═╡ 83bcda80-0270-11eb-2c17-533a150fd29f
let
	nodelabel = 1:nv(graph)
	edgelabel = 1:ne(graph)
	GraphPlot.gplot(graph, nodelabel=nodelabel, edgelabel=edgelabel)
end

# ╔═╡ d0db318e-0270-11eb-2773-0b01a4ff6e8b
adj_matrix = Matrix(adjacency_matrix(graph))

# ╔═╡ Cell order:
# ╟─6e986f20-0270-11eb-071e-e14defbf6af7
# ╟─66c4bda2-0271-11eb-3447-87dd5a3904bd
# ╟─fbe17668-0272-11eb-1085-e98901c9ca7d
# ╟─0adfb774-0273-11eb-29c7-7bab996d8314
# ╟─83bcda80-0270-11eb-2c17-533a150fd29f
# ╟─d0db318e-0270-11eb-2773-0b01a4ff6e8b
# ╠═9e153cba-0270-11eb-03fc-17dd33397b80
# ╠═2446ba56-0272-11eb-2ad1-3d16e6334601

max_stars_repo_name: mathijsvdv/ComputationalThinking

max_issues_repo_name: mathijsvdv/ComputationalThinking

max_forks_repo_name: mathijsvdv/ComputationalThinking


text:
using Test

include("./test_minimax.jl")

max_stars_repo_name: elmomoilanen/Tic-tac-toe

max_issues_repo_name: elmomoilanen/Tic-tac-toe

max_forks_repo_name: elmomoilanen/Tic-tac-toe


text:
import .ForwardDiff

_eps(::Type{<:ForwardDiff.Dual{<:Any, Real}}) = _eps(Real)

# AD implementations
function jacobian(
    b::Union{<:ADBijector{<:ForwardDiffAD}, Inversed{<:ADBijector{<:ForwardDiffAD}}},
    x::Real
)
    return ForwardDiff.derivative(b, x)
end
function jacobian(
    b::Union{<:ADBijector{<:ForwardDiffAD}, Inversed{<:ADBijector{<:ForwardDiffAD}}},
    x::AbstractVector{<:Real}
)
    return ForwardDiff.jacobian(b, x)
end


text:
rgb24(x::UInt32) = reinterpret(RGB24, x)

@testset "JPEGGray" begin
    @testset "Constructors" begin
        @test JPEGGray{UInt8}(0x00).val === 0x00
        @test JPEGGray8(0xFF).val === 0xFF
        @test JPEGGray16(0x0000).val === 0x0000
        @test JPEGGray(0xFFFF).val === 0xFFFF
        @test JPEGGray(204f0).val === 204.f0

        @test JPEGGray(Gray{Float32}(0.8f0)).val === 204f0
        @test JPEGGray{Float16}(Gray(0.8)).val === Float16(204)
    end

    @testset "Traits" begin
        gray8 = JPEGGray8(Gray(0.6))
        gray16 = JPEGGray16(Gray(0.6))
        grayf32 = JPEGGray{Float32}(Gray(0.6))
        grayf64 = JPEGGray{Float64}(Gray(0.6))

        @test gray(gray8) === 0.6N0f8
        @test gray(gray16) === 0.6N0f16
        @test gray(grayf32) === 0.6f0
        @test gray(grayf64) === 0.6

        @test comp1(gray8) === 153f0
        @test comp1(gray16) === 153f0
        @test comp1(grayf32) === 153f0
        @test comp1(grayf64) === 153.0
    end

    @testset "Display" begin
        @test shown_string(JPEGGray8) == "JPEGGray{UInt8}"
        @test shown_string(JPEGGray8(0x12)) == "JPEGGray8(18)"
        @test shown_string(JPEGGray16(0x1234)) == "JPEGGray16(36.406)"
        @test shown_string(JPEGGray{Float32}(56.7f0)) == "JPEGGray{Float32}(56.7f0)"
    end

    @testset "Conversions" begin
        @test convert(JPEGGray8, RGB{Float64}(0, 0, 0)) === JPEGGray8(0x00)
        @test convert(JPEGGray8, RGB{Float32}(1, 0, 0)) === JPEGGray8(0x4C)
        @test convert(JPEGGray8, RGB{N0f8}(   0, 1, 0)) === JPEGGray8(0x96)
        @test convert(JPEGGray8, RGB{N0f16}(  0, 0, 1)) === JPEGGray8(0x1D)
        @test convert(JPEGGray8, RGB24(       1, 1, 1)) === JPEGGray8(0xFF)
        @test convert(JPEGGray8, rgb24(0xC0FFEE)) === JPEGGray8(0xEA)

        @test convert(JPEGGray16, RGB{Float64}(0, 0, 0)) === JPEGGray16(0x0000)
        @test convert(JPEGGray16, RGB{Float32}(1, 0, 0)) === JPEGGray16(0x261F)
        @test convert(JPEGGray16, RGB{N0f8}(   0, 1, 0)) === JPEGGray16(0x4AD8)
        @test convert(JPEGGray16, RGB{N0f16}(  0, 0, 1)) === JPEGGray16(0x0E89)
        @test convert(JPEGGray16, RGB24(       1, 1, 1)) === JPEGGray16(0x7F80)
        @test convert(JPEGGray16, rgb24(0xC0FFEE)) === JPEGGray16(0x751D)

        @test convert(JPEGGray8, Gray{Float64}(0.8)) === JPEGGray8(0xCC)
        @test convert(JPEGGray8, Gray{N0f8}(   0.4)) === JPEGGray8(0x66)
        @test convert(JPEGGray16, Gray{Float32}(0.8)) === JPEGGray16(0x6600)
        @test convert(JPEGGray16, Gray{N0f8}(   0.4)) === JPEGGray16(0x3300)
    end
end

@testset "JPEGYCbCr" begin
    @testset "Constructors" begin
        @test JPEGYCbCr{UInt8}(0xFF, 0x80, 0x00).y  === 0xFF
        @test JPEGYCbCr{UInt8}(0xFF, 0x80, 0x00).cb === 0x80
        @test JPEGYCbCr{UInt8}(0xFF, 0x80, 0x00).cr === 0x00
        @test JPEGYCbCr8(0x12, 0x34, 0x56).y  === 0x12
        @test JPEGYCbCr8(0x12, 0x34, 0x56).cb === 0x34
        @test JPEGYCbCr8(0x12, 0x34, 0x56).cr === 0x56
        @test JPEGYCbCr16(0xFFFF, 0x8000, 0x0000).y  === 0xFFFF
        @test JPEGYCbCr16(0xFFFF, 0x8000, 0x0000).cb === 0x8000
        @test JPEGYCbCr16(0xFFFF, 0x8000, 0x0000).cr === 0x0000
        @test JPEGYCbCr(0x1234, 0x5678, 0x9ABC).y  === 0x1234
        @test JPEGYCbCr(0x1234, 0x5678, 0x9ABC).cb === 0x5678
        @test JPEGYCbCr(0x1234, 0x5678, 0x9ABC).cr === 0x9ABC
        @test JPEGYCbCr(12.3f0, 45.6f0, -7.89f0).y  === 12.3f0
        @test JPEGYCbCr(12.3f0, 45.6f0, -7.89f0).cb === 45.6f0
        @test JPEGYCbCr(12.3f0, 45.6f0, -7.89f0).cr === -7.89f0
    end

    @testset "Traits" begin
        gray8 = convert(JPEGYCbCr8, Gray(0.6))
        gray16 = convert(JPEGYCbCr16, Gray(0.6))
        grayf32 = convert(JPEGYCbCr{Float32}, Gray(0.6))
        grayf64 = convert(JPEGYCbCr{Float64}, Gray(0.6))

        @test gray(gray8) === 0.6N0f8
        @test gray(gray16) === 0.6N0f16
        @test gray(grayf32) === 0.6f0
        @test gray(grayf64) === 0.6

        @test comp1(gray8) === 153f0
        @test comp1(gray16) === 153f0
        @test comp1(grayf32) === 153f0
        @test comp1(grayf64) === 153.0
        @test comp2(gray8) === 0f0
        @test comp2(gray16) === 0f0
        @test comp2(grayf32) === 0f0
        @test comp2(grayf64) === 0.0
        @test comp3(gray8) === 0f0
        @test comp3(gray16) === 0f0
        @test comp3(grayf32) === 0f0
        @test comp3(grayf64) === 0.0

        blue8 = convert(JPEGYCbCr8, RGB(0, 0, 1))
        blue16 = convert(JPEGYCbCr16, RGB(0, 0, 1))
        bluef32 = convert(JPEGYCbCr{Float32}, RGB(0, 0, 1))
        bluef64 = convert(JPEGYCbCr{Float64}, RGB(0, 0, 1))

        @test comp2(blue8) === 127f0
        @test comp2(blue16) === 127.5f0
        @test comp2(bluef32) === 127.5f0
        @test comp2(bluef64) === 127.5
        @test comp3(blue8) ≈ -21f0
        @test comp3(blue16) ≈ -20.734665f0
        @test comp3(bluef32) ≈ -20.734665f0
        @test comp3(bluef64) ≈ -20.734664916992188
    end

    @testset "Display" begin
        @test shown_string(JPEGYCbCr8) == "JPEGYCbCr{UInt8}"
        @test shown_string(JPEGYCbCr8(0x12, 0x34, 0xAB)) == "JPEGYCbCr8(18,-76,43)"
        @test shown_string(JPEGYCbCr16(0x1234, 0x5678, 0xABCD)) == "JPEGYCbCr16(36.406,172.938,-168.398)"
        @test shown_string(JPEGYCbCr{Float32}(12.3f0, 45.6f0, -7.89f0)) == "JPEGYCbCr{Float32}(12.3f0,45.6f0,-7.89f0)"
    end

    @testset "Conversions" begin
        @test convert(JPEGYCbCr8, RGB{Float64}(0, 0, 0)) === JPEGYCbCr8(0x00, 0x80, 0x80)
        @test convert(JPEGYCbCr8, RGB{Float32}(1, 0, 0)) === JPEGYCbCr8(0x4C, 0x55, 0xFF)
        @test convert(JPEGYCbCr8, RGB{N0f8}(   0, 1, 0)) === JPEGYCbCr8(0x96, 0x2C, 0x15)
        @test convert(JPEGYCbCr8, RGB{N0f16}(  0, 0, 1)) === JPEGYCbCr8(0x1D, 0xFF, 0x6B)
        @test convert(JPEGYCbCr8, RGB24(       1, 1, 1)) === JPEGYCbCr8(0xFF, 0x80, 0x80)
        @test convert(JPEGYCbCr8, rgb24(0xC0FFEE)) === JPEGYCbCr8(0xEA, 0x82, 0x62)

        @test convert(JPEGYCbCr16, RGB{Float64}(0, 0, 0)) === JPEGYCbCr16(0x0000, 0x0000, 0x0000)
        @test convert(JPEGYCbCr16, RGB{Float32}(1, 0, 0)) === JPEGYCbCr16(0x261F, 0xEA7C, 0x3FC0)
        @test convert(JPEGYCbCr16, RGB{N0f8}(   0, 1, 0)) === JPEGYCbCr16(0x4AD8, 0xD5C4, 0xCA9E)
        @test convert(JPEGYCbCr16, RGB{N0f16}(  0, 0, 1)) === JPEGYCbCr16(0x0E89, 0x3FC0, 0xF5A2)
        @test convert(JPEGYCbCr16, RGB24(       1, 1, 1)) === JPEGYCbCr16(0x7F80, 0x0000, 0x0000)
        @test convert(JPEGYCbCr16, rgb24(0xC0FFEE)) === JPEGYCbCr16(0x751D, 0x0111, 0xF0F1)

        @test convert(JPEGYCbCr{Float32}, rgb24(0xC0FFEE)) ≈ JPEGYCbCr{Float32}(234.22499f0, 2.1303558f0, -30.11769f0)

        ycbcr8 = convert(JPEGYCbCr8, rgb24(0xC0FFEE))
        @test convert(RGB24, ycbcr8) === rgb24(0xC0FFEE)

        ycbcr16 = convert(JPEGYCbCr16, rgb24(0xC0FFEE))
        @test convert(RGB24, ycbcr16) === rgb24(0xC0FFEE)

        for h in 0:60:300
            hsv = HSV{Float32}(h, 1, 1)
            ycc = convert(JPEGYCbCr{Float32}, hsv)
            @test ycc isa JPEGYCbCr{Float32}
            @test convert(HSV{Float32}, ycc) ≈ hsv atol=eps(360.0f0)
        end
    end

end


text:
module ArraysBenchs

using InplaceArrays.Arrays
using FillArrays

@inline function loop(a,cache)
  for i in eachindex(a)
    ai = getindex!(cache,a,i)
  end
end

@inline function loop_and_apply(ca,cai,cx,a,x...)
  for i in eachindex(a)
    ai = getindex!(ca,a,i)
    xi = getitems!(cx,x,i...)
    vi = apply_kernel!(cai,ai,xi...)
  end
end

function bench1(n)
  a = rand(n)
  k = -
  c = apply(k,a)
  cache = array_cache(c)
  @time loop(c,cache)
end

function bench2(n)
  a = rand(n)
  b = rand(n)
  k = -
  c = apply(k,a,b)
  cache = array_cache(c)
  @time loop(c,cache)
end

function bench3(n)
  a = fill(rand(2,3),n)
  b = rand(n)
  c = apply(bcast(-),a,b)
  cache = array_cache(c)
  @time loop(c,cache)
end

function bench4(n)
  a = fill(rand(2,3),n)
  b = rand(n)
  c = apply(bcast(-),a,b)
  d = apply(bcast(+),a,c)
  e = apply(bcast(*),d,c)
  cache = array_cache(e)
  @time loop(e,cache)
end

function bench7(n)
  k = +
  a = fill(k,n)
  x = rand(n)
  y = rand(n)
  v = apply(a,x,y)
  cache = array_cache(v)
  @time loop(v,cache)
end

function bench8(n)
  a = fill(bcast(+),n)
  x = [rand(2,3) for i in 1:n]
  y = [rand(1,3) for i in 1:n]
  v = apply(a,x,y)
  cache = array_cache(v)
  @time loop(v,cache)
end

function bench9(n)
  a = Fill(bcast(+),n)
  x = [rand(mod(i-1,3)+1,3) for i in 1:n]
  y = [rand(1,3) for i in 1:n]
  v = apply(a,x,y)
  cache = array_cache(v)
  @time loop(v,cache)
end

for n in (1,1,10,1000,100000)
  @eval begin
    println("+++ runing suite for n = $($n) +++")
    bench1($n)
    bench2($n)
    bench3($n)
    bench4($n)
    bench7($n)
    bench8($n)
    bench9($n)
  end
end

end # module


text:
using Test, OrdinaryDiffEq

for Alg in (Rosenbrock23, TRBDF2)
  tspan = (0, 10.)
  u0 = ones(2)
  tstops=range(0,10,length=1000)
  sol = solve(ODEProblem((du,u,p,t) -> du .= sin.(u), u0, tspan), Tsit5())
  @test_nowarn solve(ODEProblem((du, u, p, t) -> sol(du, t), u0, tspan), Alg(), tstops=tstops)
  @test_nowarn solve(ODEProblem((du, u, p, t) -> sol(du, t), u0, (tspan[2], tspan[1])), Alg(), tstops=tstops)

  for u0 in (1.0, ones(2))
    u0 = 1.0
    sol = solve(ODEProblem((u,p,t) -> sin.(u), u0, tspan), Tsit5())
    @test_nowarn solve(ODEProblem((u, p, t) -> sol(t), u0, tspan), Alg(), tstops=tstops)
    @test_nowarn solve(ODEProblem((u, p, t) -> sol(t), u0, (tspan[2], tspan[1])), Alg(), tstops=tstops)
  end
end