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

#! format: off

"""
    mutable struct SimpleAFMachine <: Machine
        R::Float64
        Xd::Float64
        Xq::Float64
        Xd_p::Float64
        Xq_p::Float64
        Xd_pp::Float64
        Xq_pp::Float64
        Td0_p::Float64
        Tq0_p::Float64
        Td0_pp::Float64
        Tq0_pp::Float64
        ext::Dict{String, Any}
        states::Vector{Symbol}
        n_states::Int
        internal::InfrastructureSystemsInternal
    end

Parameters of 4-states simplified Anderson-Fouad (SimpleAFMachine) model.
 The derivative of stator fluxes (ψd and ψq) is neglected and ωψd = ψd and
 ωψq = ψq is assumed (i.e. ω=1.0). This is standard when transmission network
 dynamics is neglected.
 If transmission dynamics is considered use the full order Anderson Fouad model.

# Arguments
- `R::Float64`: Resistance after EMF in machine per unit, validation range: `(0, nothing)`
- `Xd::Float64`: Reactance after EMF in d-axis per unit, validation range: `(0, nothing)`
- `Xq::Float64`: Reactance after EMF in q-axis per unit, validation range: `(0, nothing)`
- `Xd_p::Float64`: Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`
- `Xq_p::Float64`: Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`
- `Xd_pp::Float64`: Sub-Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`
- `Xq_pp::Float64`: Sub-Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`
- `Td0_p::Float64`: Time constant of transient d-axis voltage, validation range: `(0, nothing)`
- `Tq0_p::Float64`: Time constant of transient q-axis voltage, validation range: `(0, nothing)`
- `Td0_pp::Float64`: Time constant of sub-transient d-axis voltage, validation range: `(0, nothing)`
- `Tq0_pp::Float64`: Time constant of sub-transient q-axis voltage, validation range: `(0, nothing)`
- `ext::Dict{String, Any}`
- `states::Vector{Symbol}`: The states are:
	eq_p: q-axis transient voltage,
	ed_p: d-axis transient voltage,
	eq_pp: q-axis subtransient voltage,
	ed_pp: d-axis subtransient voltage
- `n_states::Int`: SimpleAFMachine has 4 states
- `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify
"""
mutable struct SimpleAFMachine <: Machine
    "Resistance after EMF in machine per unit"
    R::Float64
    "Reactance after EMF in d-axis per unit"
    Xd::Float64
    "Reactance after EMF in q-axis per unit"
    Xq::Float64
    "Transient reactance after EMF in d-axis per unit"
    Xd_p::Float64
    "Transient reactance after EMF in q-axis per unit"
    Xq_p::Float64
    "Sub-Transient reactance after EMF in d-axis per unit"
    Xd_pp::Float64
    "Sub-Transient reactance after EMF in q-axis per unit"
    Xq_pp::Float64
    "Time constant of transient d-axis voltage"
    Td0_p::Float64
    "Time constant of transient q-axis voltage"
    Tq0_p::Float64
    "Time constant of sub-transient d-axis voltage"
    Td0_pp::Float64
    "Time constant of sub-transient q-axis voltage"
    Tq0_pp::Float64
    ext::Dict{String, Any}
    "The states are:
	eq_p: q-axis transient voltage,
	ed_p: d-axis transient voltage,
	eq_pp: q-axis subtransient voltage,
	ed_pp: d-axis subtransient voltage"
    states::Vector{Symbol}
    "SimpleAFMachine has 4 states"
    n_states::Int
    "power system internal reference, do not modify"
    internal::InfrastructureSystemsInternal
end

function SimpleAFMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext=Dict{String, Any}(), )
    SimpleAFMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext, [:eq_p, :ed_p, :eq_pp, :ed_pp], 4, InfrastructureSystemsInternal(), )
end

function SimpleAFMachine(; R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext=Dict{String, Any}(), states=[:eq_p, :ed_p, :eq_pp, :ed_pp], n_states=4, internal=InfrastructureSystemsInternal(), )
    SimpleAFMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext, states, n_states, internal, )
end

# Constructor for demo purposes; non-functional.
function SimpleAFMachine(::Nothing)
    SimpleAFMachine(;
        R=0,
        Xd=0,
        Xq=0,
        Xd_p=0,
        Xq_p=0,
        Xd_pp=0,
        Xq_pp=0,
        Td0_p=0,
        Tq0_p=0,
        Td0_pp=0,
        Tq0_pp=0,
        ext=Dict{String, Any}(),
    )
end

"""Get [`SimpleAFMachine`](@ref) `R`."""
get_R(value::SimpleAFMachine) = value.R
"""Get [`SimpleAFMachine`](@ref) `Xd`."""
get_Xd(value::SimpleAFMachine) = value.Xd
"""Get [`SimpleAFMachine`](@ref) `Xq`."""
get_Xq(value::SimpleAFMachine) = value.Xq
"""Get [`SimpleAFMachine`](@ref) `Xd_p`."""
get_Xd_p(value::SimpleAFMachine) = value.Xd_p
"""Get [`SimpleAFMachine`](@ref) `Xq_p`."""
get_Xq_p(value::SimpleAFMachine) = value.Xq_p
"""Get [`SimpleAFMachine`](@ref) `Xd_pp`."""
get_Xd_pp(value::SimpleAFMachine) = value.Xd_pp
"""Get [`SimpleAFMachine`](@ref) `Xq_pp`."""
get_Xq_pp(value::SimpleAFMachine) = value.Xq_pp
"""Get [`SimpleAFMachine`](@ref) `Td0_p`."""
get_Td0_p(value::SimpleAFMachine) = value.Td0_p
"""Get [`SimpleAFMachine`](@ref) `Tq0_p`."""
get_Tq0_p(value::SimpleAFMachine) = value.Tq0_p
"""Get [`SimpleAFMachine`](@ref) `Td0_pp`."""
get_Td0_pp(value::SimpleAFMachine) = value.Td0_pp
"""Get [`SimpleAFMachine`](@ref) `Tq0_pp`."""
get_Tq0_pp(value::SimpleAFMachine) = value.Tq0_pp
"""Get [`SimpleAFMachine`](@ref) `ext`."""
get_ext(value::SimpleAFMachine) = value.ext
"""Get [`SimpleAFMachine`](@ref) `states`."""
get_states(value::SimpleAFMachine) = value.states
"""Get [`SimpleAFMachine`](@ref) `n_states`."""
get_n_states(value::SimpleAFMachine) = value.n_states
"""Get [`SimpleAFMachine`](@ref) `internal`."""
get_internal(value::SimpleAFMachine) = value.internal

"""Set [`SimpleAFMachine`](@ref) `R`."""
set_R!(value::SimpleAFMachine, val) = value.R = val
"""Set [`SimpleAFMachine`](@ref) `Xd`."""
set_Xd!(value::SimpleAFMachine, val) = value.Xd = val
"""Set [`SimpleAFMachine`](@ref) `Xq`."""
set_Xq!(value::SimpleAFMachine, val) = value.Xq = val
"""Set [`SimpleAFMachine`](@ref) `Xd_p`."""
set_Xd_p!(value::SimpleAFMachine, val) = value.Xd_p = val
"""Set [`SimpleAFMachine`](@ref) `Xq_p`."""
set_Xq_p!(value::SimpleAFMachine, val) = value.Xq_p = val
"""Set [`SimpleAFMachine`](@ref) `Xd_pp`."""
set_Xd_pp!(value::SimpleAFMachine, val) = value.Xd_pp = val
"""Set [`SimpleAFMachine`](@ref) `Xq_pp`."""
set_Xq_pp!(value::SimpleAFMachine, val) = value.Xq_pp = val
"""Set [`SimpleAFMachine`](@ref) `Td0_p`."""
set_Td0_p!(value::SimpleAFMachine, val) = value.Td0_p = val
"""Set [`SimpleAFMachine`](@ref) `Tq0_p`."""
set_Tq0_p!(value::SimpleAFMachine, val) = value.Tq0_p = val
"""Set [`SimpleAFMachine`](@ref) `Td0_pp`."""
set_Td0_pp!(value::SimpleAFMachine, val) = value.Td0_pp = val
"""Set [`SimpleAFMachine`](@ref) `Tq0_pp`."""
set_Tq0_pp!(value::SimpleAFMachine, val) = value.Tq0_pp = val
"""Set [`SimpleAFMachine`](@ref) `ext`."""
set_ext!(value::SimpleAFMachine, val) = value.ext = val


text:
###############################################################################
#
# Temperature dependency parameter set
#
###############################################################################
#= AbstractTDParameterSet type tree
---> ArrheniusTD
---> ArrheniusPeakTD
=#
"""
    abstract type AbstractTDParameterSet{FT}

Hierarchy of the `AbstractTDParameterSet`:
- [`ArrheniusTD`](@ref)
- [`ArrheniusPeakTD`](@ref)
"""
abstract type AbstractTDParameterSet{FT} end

"""
    struct ArrheniusTD{FT}

An [`AbstractTDParameterSet`](@ref) type struct using
```math
corr = \\exp \\left( \\dfrac{ΔHa}{R T_0} - \\dfrac{ΔHa}{R T_1} \\right)
```

# Fields
$(TYPEDFIELDS)
"""
struct ArrheniusTD{FT<:AbstractFloat} <: AbstractTDParameterSet{FT}
    "Uncorrected value at 298.15 K"
    VAL_25::FT
    "Ratio between ΔHa and R `[K]`"
    ΔHa_to_R::FT
    "Ratio between ΔHa and R*K_25"
    ΔHa_to_RT25::FT
end

"""
    struct ArrheniusPeakTD{FT}

An [`AbstractTDParameterSet`](@ref) type struct using
```math
corr = \\exp \\left( \\dfrac{ΔHa}{R T_0} - \\dfrac{ΔHa}{R T_1} \\right)
       \\cdot
       \\dfrac{ 1 + \\exp \\left( \\dfrac{S_v T_0 - H_d}{R T_0} \\right) }
              { 1 + \\exp \\left( \\dfrac{S_v T_1 - H_d}{R T_1} \\right) }
```

# Fields
$(TYPEDFIELDS)
"""
struct ArrheniusPeakTD{FT<:AbstractFloat} <: AbstractTDParameterSet{FT}
    "Ratio between ΔHa and R*K_25"
    ΔHa_to_RT25::FT
    "Ratio between ΔHd and R"
    ΔHd_to_R::FT
    "Ratio between ΔSv and R"
    ΔSv_to_R::FT
    "Correction factor C = 1 + exp( Sv/R + Hd/(RT0) )"
    C::FT
end

"""
    struct Q10TD{FT}

An [`AbstractTDParameterSet`](@ref) type struct using
```math
VAL = VAL_{REF} \\left( \\dfrac{T_1 - T_{REF}}}{10} \\right)^{Q_{10}}
```

# Fields
$(TYPEDFIELDS)
"""
struct Q10TD{FT<:AbstractFloat} <: AbstractTDParameterSet{FT}
    "Uncorrected value at reference temperature"
    VAL_REF::FT
    "Reference temperature `[K]`"
    T_REF::FT
    "Power of Q10 correction"
    Q_10::FT
end

ext: jl

max_stars_repo_name: climate-machine/Land


text:
module Vehicles

export Contact, Vehicle, Car, Bike, Yacht, Powerboat, Boat
export Ford, BMW, VW, Scooter, MotorBike, Speedboat

mutable struct Contact
    name::String
    email::String
    phone::String
end

abstract type Vehicle end

abstract type Car <: Vehicle end
abstract type Bike <: Vehicle  end
abstract type Boat <: Vehicle end

abstract type Powerboat <: Boat end

mutable struct Ford <: Car
    owner::Contact
    make::String
    fuel::String
    color::String
	engine_cc::Int64
    speed_mph::Float64
    function Ford(owner, make, engine_cc,speed_mph)
        new (owner,make,"Petrol","Black",engine_cc,speed_mph)
     end
end

mutable struct BMW <: Car
    owner::Contact
    make::String
    fuel::String
    color::String
	engine_cc::Int64
    speed_mph::Float64
    function BMW(owner,make,engine_cc,speed_mph)
        new (owner,make,"Petrol","Blue",engine_cc,speed_mph)
   end
end

mutable struct VW <: Car
    owner::Contact
    make::String
    fuel::String
    color::String
	engine_cc::Int64
    speed_mph::Float64
end

mutable struct MotorBike <: Bike
    owner::Contact
    make::String
	engine_cc::Int64
    speed_mph::Float64
end

mutable struct Scooter <: Bike
    owner::Contact
    make::String
	engine_cc::Int64
    speed_mph::Float64
end

mutable struct Yacht <: Boat
    owner::Contact
    make::String
    length_m::Float64
end

mutable struct Speedboat <: Powerboat
    owner::Contact
    make::String
	fuel::String
	engine_cc::Int64
    speed_knots::Float64
	length_m::Float64
end

function is_quicker(a::VW, b::BMW)
   if (a.speed_mph == b.speed_mph)
      return nothing
    else
      return(a.speed_mph > b.speed_mph ? a : b)
     end
end

function is_quicker(a::Speedboat, b::Scooter)
   const KNOTS_TO_MPH = 1.151
   a_mph = KNOTS_TO_MPH * a.speed_knots
   if (a_mph == b.speed_mph)
       return nothing
    else
       return(a_mph > b.speed_mph ? a : b)
    end
end

function is_longer(a::Yacht, b::Speedboat)
   if (a.length_m == b.length_m)
       return nothing
    else
       return(a.length > b.length_m ? a : b)
    end
end

is_quicker(a::BMW, b::VW) = is_quicker(b,a)
is_quicker(a::Scooter, b::Speedboat) = is_quicker(b,a)
is_longer(a::Speedboat, b::Yacht) = is_longer(b,a)

end


text:
export SpaceOperation
export apply_operation
export dimension
export isidentity, istranslation, ispoint

import LinearAlgebra
import LinearAlgebraX

"""
    SpaceOperation{Tp<:Real, Tt<:Real}

Represent a spatial symmetry operation of the following form:
```math
S_{[M, \\mathbf{R}]}: \\mathbf{r} \\mapsto M \\cdot ( \\mathbf{r} + \\mathbf{R} )
```

# Fields
* `matrix`: Rotation matrix
* `displacement`: Displacement vector
"""
struct SpaceOperation{Tp<:Real, Tt<:Real} <:AbstractSpaceSymmetryOperation{Tt}
    matrix::Matrix{Tp}
    displacement::Vector{Tt}

    function SpaceOperation{Tp, Tt}(dim::Integer) where {Tp<:Real, Tt<:Real}
        return new{Tp, Tt}(Matrix{Tp}(LinearAlgebra.I, dim, dim), zeros(Tt, dim))
    end

    function SpaceOperation(::Type{Tp}, ::Type{Tt}, dim::Integer) where {Tp<:Real, Tt<:Real}
        return new{Tp, Tt}(Matrix{Tp}(LinearAlgebra.I, dim, dim), zeros(Tt, dim))
    end

    function SpaceOperation{Tp, Tt}(
        matrix::AbstractMatrix,
        displacement::AbstractVector,
    ) where {Tp<:Real, Tt<:Real}
        dim = size(matrix, 1)
        if size(matrix, 2) != dim
            throw(DimensionMismatch("matrix is not square: dimensions are $(size(matrix))"))
        elseif length(displacement) != dim
            throw(DimensionMismatch(
                "dimensions of matrix and displacement do not match:"*
                " matrix dimensions are $(size(matrix)),"*
                " and vector dimension is $(length(displacement))"
            ))
        end
        return new{Tp, Tt}(matrix, displacement)
    end

    @doc """
        SpaceOperation(matrix::AbstractMatrix{Tp}, displacement::AbstractVector{Tt}) where {Tp<:Real, Tt<:Real}

    Construct a space operation by `matrix` and `displacement`.
    """
    function SpaceOperation(
        matrix::AbstractMatrix{Tp},
        displacement::AbstractVector{Tt},
    ) where {Tp<:Real, Tt<:Real}
        return SpaceOperation{Tp, Tt}(matrix, displacement)
    end

    @doc """
        SpaceOperation([point], [translation])

    Construct a space operation by `point` and `translation`.

    # Arguments
    * `point::PointOperation{Tp}`
    * `translation::TranslationOperation{Tt}`
    """
    function SpaceOperation(
        point::PointOperation{Tp},
        translation::TranslationOperation{Tt},
    ) where {Tp<:Real, Tt<:Real}
        return SpaceOperation{Tp, Tt}(point.matrix, translation.displacement)
    end

    function SpaceOperation(point::PointOperation{Tp}) where {Tp}
        dim = dimension(point)
        return SpaceOperation{Tp, Tp}(point.matrix, zeros(Tp, dim))
    end

    function SpaceOperation(translation::TranslationOperation{Tt}) where {Tt}
        dim = dimension(translation)
        return SpaceOperation{Int, Tt}(
            Matrix{Int}(LinearAlgebra.I, dim, dim),
            translation.displacement,
        )
    end
end

## Conversion

function Base.convert(::Type{SpaceOperation{Tp1, Tt1}}, arg::SpaceOperation{Tp2, Tt2}) where {Tp1, Tt1, Tp2, Tt2}
    return SpaceOperation(convert(Matrix{Tp1}, arg.matrix), convert(Vector{Tt1}, arg.displacement))
end

# function Base.convert(::Type{SpaceOperation{Tp1, Tt1}}, op::IdentityOperation{T}) where {Tp1, Tt1, T}
#     dim = dimension(op)
#     mat = Matrix{Tp1}(LinearAlgebra.I, (dim, dim))
#     dis = zeros(Tt1, size(mat, 1))
#     return SpaceOperation(mat, dis)
# end

function Base.convert(::Type{SpaceOperation{Tp1, Tt1}}, op::PointOperation{Tp2}) where {Tp1, Tt1, Tp2}
    dim = dimension(op)
    mat = convert(Matrix{Tp1}, op.matrix)
    dis = zeros(Tt1, dim)
    return SpaceOperation(mat, dis)
end

function Base.convert(::Type{SpaceOperation{Tp1, Tt1}}, op::TranslationOperation{Tt2}) where {Tp1, Tt1, Tt2}
    dim = dimension(op)
    mat = Matrix{Tp1}(LinearAlgebra.I, (dim, dim))
    dis = convert(Vector{Tt1}, op.displacement)
    return SpaceOperation(mat, dis)
end

function Base.convert(::Type{SpaceOperation{Tp1, Tt1}}, arg::AbstractVector{Tt2}) where {Tp1, Tt1, Tt2}
    dim = length(arg)
    mat = Matrix{Tp1}(LinearAlgebra.I, (dim, dim))
    dis = convert(Vector{Tt1}, arg)
    return SpaceOperation(mat, dis)
end

function Base.convert(::Type{SpaceOperation{Tp1, Tt1}}, arg::AbstractMatrix{Tp2}) where {Tp1, Tt1, Tp2}
    dim = size(arg, 1)
    mat = convert(Matrix{Tp1}, arg)
    dis = zeros(Tt1, dim)
    return SpaceOperation(mat, dis)
end

function Base.promote_rule(::Type{SpaceOperation{Tp1, Tt1}}, ::Type{SpaceOperation{Tp2, Tt2}}) where {Tp1, Tt1, Tp2, Tt2}
    Tp = promote_type(Tp1, Tp2)
    Tt = promote_type(Tt1, Tt2)
    return SpaceOperation{Tp, Tt}
end

# function Base.promote_rule(::Type{SpaceOperation{Tp, Tt}}, ::Type{IdentityOperation{T}}) where {Tp, Tt, T}
#     return SpaceOperation{Tp, Tt}
# end

function Base.promote_rule(::Type{SpaceOperation{Tp1, Tt1}}, ::Type{TranslationOperation{Tt2}}) where {Tp1, Tt1, Tt2}
    Tt = promote_type(Tt1, Tt2)
    return SpaceOperation{Tp1, Tt}
end

function Base.promote_rule(::Type{SpaceOperation{Tp1, Tt1}}, ::Type{PointOperation{Tp2}}) where {Tp1, Tt1, Tp2}
    Tp = promote_type(Tp1, Tp2)
    return SpaceOperation{Tp, Tt1}
end

function Base.promote_rule(::Type{TranslationOperation{Tt}}, ::Type{PointOperation{Tp}}) where {Tp, Tt}
    return SpaceOperation{Tp, Tt}
end

## Properties

"""
    isidentity(arg::SpaceOperation)

Check whether `arg` is identity (i.e. identity point and identity translation)
"""
isidentity(arg::SpaceOperation) = isone(arg.matrix) && iszero(arg.displacement)

"""
    istranslation(arg::SpaceOperation)

Check whether `arg` is a translation operation (i.e., point operation is identity)
"""
istranslation(arg::SpaceOperation) = isone(arg.matrix)

"""
    ispoint(arg::SpaceOperation)

Check whether `arg` is a point operation (i.e. translation is identity)
"""
ispoint(arg::SpaceOperation) = iszero(arg.displacement)

"""
    dimension(arg::SpaceOperation)

Return the spatial dimension of `arg`.
"""
dimension(arg::SpaceOperation) = length(arg.displacement)

function Base.hash(op::SpaceOperation{Tp, Tt}, h::UInt) where {Tp, Tt}
    h = hash(op.matrix, h)
    h = hash(op.displacement, h)
    h = hash(SpaceOperation{Tp, Tt}, h)
    return h
end

## operators
function Base.:(==)(lhs::SpaceOperation{Tp, Tt}, rhs::SpaceOperation{Tp, Tt}) where {Tp, Tt}
    return lhs.matrix == rhs.matrix && lhs.displacement == rhs.displacement
end

function Base.:(==)(lhs::SpaceOperation{Tp, Tt}, rhs::TranslationOperation{Tt}) where {Tp, Tt}
    return isone(lhs.matrix) && lhs.displacement == rhs.displacement
end

function Base.:(==)(lhs::SpaceOperation{Tp, Tt}, rhs::PointOperation{Tp}) where {Tp, Tt}
    return iszero(lhs.displacement) && lhs.matrix == rhs.matrix
end

function Base.:(==)(lhs::TranslationOperation{Tt}, rhs::SpaceOperation{Tp, Tt}) where {Tp, Tt}
    return isone(rhs.matrix) && lhs.displacement == rhs.displacement
end

function Base.:(==)(lhs::PointOperation{Tp}, rhs::SpaceOperation{Tp, Tt}) where {Tp, Tt}
    return iszero(rhs.displacement) && lhs.matrix == rhs.matrix
end

# function Base.:(==)(sop::SpaceOperation{Tp, Tt}, iden::IdentityOperation{<:Union{Tp, Tt}}) where {Tp, Tt}
#     return dimension(sop) == dimension(iden) && iszero(sop.displacement) && isone(sop.matrix)
# end

# function Base.:(==)(iden::IdentityOperation{<:Union{Tp, Tt}}, sop::SpaceOperation{Tp, Tt}) where {Tp, Tt}
#     return dimension(sop) == dimension(iden) && iszero(sop.displacement) && isone(sop.matrix)
# end

function Base.:(*)(lhs::PointOperation{Tp}, rhs::TranslationOperation{Tt}) where {Tp, Tt}
    return SpaceOperation{Tp, Tt}(lhs.matrix, rhs.displacement)
end

function Base.:(*)(lhs::TranslationOperation{Tt}, rhs::PointOperation{Tp}) where {Tp, Tt}
    rhs_matrix_inv = Matrix{Tp}(LinearAlgebraX.invx(rhs.matrix))
    return SpaceOperation{Tp, Tt}(rhs.matrix, rhs_matrix_inv * lhs.displacement)
end

#   ML ⋅ ( MR ⋅ ( x + ρR ) + ρL )
# = ML MR x + ML MR ρR + ML ρL
# = ML MR (x + ρR + inv(MR) ⋅ ρL )
function Base.:(*)(lhs::SpaceOperation{Tp, Tt}, rhs::SpaceOperation{Tp, Tt}) where {Tp, Tt}
    matrix = lhs.matrix * rhs.matrix
    rhs_matrix_inv = Matrix{Tp}(LinearAlgebraX.invx(rhs.matrix))
    displacement = rhs.displacement + rhs_matrix_inv * lhs.displacement
    return SpaceOperation{Tp, Tt}(matrix, displacement)
end

function Base.:(*)(lhs::SpaceOperation{Tp, Tt}, rhs::TranslationOperation{Tt}) where {Tp, Tt}
    matrix = lhs.matrix
    displacement = rhs.displacement + lhs.displacement
    return SpaceOperation{Tp, Tt}(matrix, displacement)
end

function Base.:(*)(lhs::TranslationOperation{Tt}, rhs::SpaceOperation{Tp, Tt}) where {Tp, Tt}
    matrix = rhs.matrix
    rhs_matrix_inv = Matrix{Tp}(LinearAlgebraX.invx(rhs.matrix))
    displacement = rhs.displacement + rhs_matrix_inv * lhs.displacement
    return SpaceOperation{Tp, Tt}(matrix, displacement)
end

function Base.:(*)(lhs::SpaceOperation{Tp, Tt}, rhs::PointOperation{Tp}) where {Tp, Tt}
    matrix = lhs.matrix * rhs.matrix
    rhs_matrix_inv = Matrix{Tp}(LinearAlgebraX.invx(rhs.matrix))
    displacement = rhs_matrix_inv * lhs.displacement
    return SpaceOperation{Tp, Tt}(matrix, displacement)
end

function Base.:(*)(lhs::PointOperation{Tp}, rhs::SpaceOperation{Tp, Tt}) where {Tp, Tt}
    matrix = lhs.matrix * rhs.matrix
    displacement = rhs.displacement
    return SpaceOperation{Tp, Tt}(matrix, displacement)
end

function Base.inv(arg::SpaceOperation{Tp, Tt}) where {Tp, Tt}
    matrix_inv = Matrix{Tp}(LinearAlgebraX.invx(arg.matrix))
    return SpaceOperation{Tp, Tt}(matrix_inv, -arg.matrix * arg.displacement)
end

function Base.:(^)(op::SpaceOperation{Tp, Tt}, power::Integer) where {Tp, Tt}
    if power == 0
        return SpaceOperation(Tp, Tt, dimension(op))
    elseif power < 0
        op_inv = inv(op)
        return op_inv^(-power)
    else
        return op * op^(power-1)
    end
end

"""
    apply_operation(op::SpaceOperation{Tp, Tt}, coord::AbstractArray{<:Union{Tp, Tt}}) where {Tp, Tt}
"""
function apply_operation(op::SpaceOperation{Tp, Tt}, coord::AbstractArray{<:Union{Tp, Tt}}) where {Tp, Tt}
    return op.matrix * (coord .+ op.displacement)
end

function (op::SpaceOperation{Tp, Tt})(coord::AbstractArray{<:Union{Tp, Tt}}) where {Tp, Tt}
    return op.matrix * (coord .+ op.displacement)
end


text:
@testset "ExampleTestCase" begin

    @testset "test_example" begin
        using .Neo4jBolt

        driver = Neo4jBoltDriver("bolt://localhost:7687", auth=("neo4j", "password"))

        function add_friend(tx, args, kwargs)
            run(tx, "MERGE (a:Person {name: \$name}) " *
                    "MERGE (a)-[:KNOWS]->(friend:Person {name: \$friend_name})", name=args[1], friend_name=args[2])
        end

        function print_friends(tx, args, kwargs)
            for record in run(tx, "MATCH (a:Person)-[:KNOWS]->(friend) WHERE a.name = \$name " *
                                  "RETURN friend.name ORDER BY friend.name", name=args[1])
                println(record["friend.name"])
            end
        end

        session(driver) do sess
            write_transaction(sess, add_friend, "Arthur", "Guinevere")
            write_transaction(sess, add_friend, "Arthur", "Lancelot")
            write_transaction(sess, add_friend, "Arthur", "Merlin")
            read_transaction(sess, print_friends, "Arthur")
        end

    end
end


text:
#
# Atomic Orbitals - based on Christina C. Lee's blog post
# (see https://albi3ro.github.io/M4/prerequisites/Atomic-Orbitals.html)
#

using GSL    # GSL holds the special functions
using GR

a0 = 5.291772109217e-11

# The unitless radial coordinate
ρ(r,n) = 2r/(n*a0)

# The θ and ϕ dependence
function Yml(m::Int,l::Int,θ::Real,ϕ::Real)
    (-1.0)^m*sf_legendre_Plm(l,abs(m),cos(θ))*e^(im*m*ϕ)
end

# The Radial dependence
function R(n::Int,l::Int,ρ::Real)
    sf_laguerre_n(n-l-1,2*l+1,ρ)*e^(-ρ/2)*ρ^l
end

# A normalization: This is dependent on the choice of polynomial representation
function norm(n::Int,l::Int)
    sqrt((2/n)^3 * factorial(n-l-1)/(2n*factorial(n+l)))
end

# Generates an Orbital Funtion of (r,θ,ϕ) for a specificied n,l,m.
function Orbital(n::Int,l::Int,m::Int)
    # we make sure l and m are within proper bounds
    if l > n || abs(m) > l
        throw(DomainError())
    end
    Ψ(ρ,θ,ϕ) = norm(n,l) * R(n,l,ρ) * abs(Yml(m,l,θ,ϕ))
    Ψ
end

function CarttoSph(x::Array,y::Array,z::Array)
    r = sqrt(x.^2+y.^2+z.^2)
    θ = acos(z./r)
    ϕ = atan(y./x)
    r,θ,ϕ
end

function calculate_electronic_density(n,l,m)
    N = 50
    r = 1e-9
    s = linspace(-r,r,N)
    x,y,z = meshgrid(s,s,s)

    r,θ,ϕ = CarttoSph(x,y,z)
    Ψ = Orbital(n,l,m)

    Ψv = zeros(Float32,N,N,N)
    for i in 1:N
        for j in 1:N
            for k in 1:N
                Ψv[i,j,k] = abs(Ψ(ρ(r[i,j,k],n),θ[i,j,k],ϕ[i,j,k]))
            end
        end
    end

    (Ψv-minimum(Ψv))/(maximum(Ψv)-minimum(Ψv))
end

Ψv = calculate_electronic_density(3,2,0)

for alpha in 0:360
    isosurface(Ψv,isovalue=0.25,rotation=alpha)
end


text:
# Autogenerated wrapper script for JasPer_jll for x86_64-w64-mingw32
export imgcmp, imginfo, jasper, libjasper

using JpegTurbo_jll
JLLWrappers.@generate_wrapper_header("JasPer")
JLLWrappers.@declare_executable_product(imgcmp)
JLLWrappers.@declare_executable_product(imginfo)
JLLWrappers.@declare_executable_product(jasper)
JLLWrappers.@declare_library_product(libjasper, "libjasper.dll")
function __init__()
    JLLWrappers.@generate_init_header(JpegTurbo_jll)
    JLLWrappers.@init_executable_product(
        imgcmp,
        "bin\\imgcmp.exe",
    )

    JLLWrappers.@init_executable_product(
        imginfo,
        "bin\\imginfo.exe",
    )

    JLLWrappers.@init_executable_product(
        jasper,
        "bin\\jasper.exe",
    )

    JLLWrappers.@init_library_product(
        libjasper,
        "bin\\libjasper.dll",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
compute_rotation(::Nothing) = I
compute_rotation(I::UniformScaling) = I/opnorm(I)

function compute_rotation((ϕ,u)::Tuple{<:Real,<:AbstractVector{<:Real}})
    @assert length(u) == 3
    u = SVector{3}(normalize(u))
    s,c = sincos(ϕ)
    # https://en.wikipedia.org/wiki/Cross_product#Conversion_to_matrix_multiplication
    ucross = SMatrix{3,3}([0    -u[3]  u[2]
                           u[3]  0    -u[1]
                           -u[2] u[1]  0])
    # https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
    R = c*I + s*ucross + (1-c)*(u*u')
    R/opnorm(R)
end

function compute_rotation(R::AbstractMatrix{T}) where {T<:Real}
    size(R) == (3,3) ||
        throw(DimensionMismatch("Rotation matrix must have dimensions 3×3"))
    rank(R) < 3 &&
        throw(ArgumentError("Rotation matrix singular"))
    R = copy(R)
    for i = 2:3
        for j = 1:i-1
            R[:,i] -= dot(R[:,j],R[:,i])*R[:,j]
        end
    end
    SMatrix{3,3}(R/opnorm(R))
end

rotation_angle(R::AbstractMatrix) = acos(clamp((tr(R) - 1)/2, -1, 1))

# https://en.wikipedia.org/wiki/Rotation_matrix#Determining_the_axis
function rotation_axis(R::AbstractMatrix)
    ee = eigen(R)
    i = argmin(abs.(ee.values .- 1))
    normalize(real(ee.vectors[:,i]))
end


text:
include("../lib/utils.jl")
include("../lib/json.jl")

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

function test_01()
  list = []
  # println("[")
  # println("]")
  json_print(list)
end

function test_02()
  # println("[")
  # println("  1")
  # println("]")

  list = [1]
  json_print(list)
end

function test_03()
  # println("[")
  # println("  \"fdsa\"")
  # println("]")

  list = ["fdsa"]
  json_print(list)
end

function test_04()
  # println("[")
  # println("  -123,")
  # println("  \"fdsa\"")
  # println("]")

  list = [-123, "fdsa"]
  json_print(list)
end

function test_05()
  # println("[")
  # println("  [")
  # println("  ]")
  # println("]")

  list = [[]]
  json_print(list)
end

function test_06()
  # println("[")
  # println("  1,")
  # println("  \"a\",")
  # println("  [")
  # println("    2,")
  # println("    \"b\"")
  # println("  ],")
  # println("  3,")
  # println("  \"c\"")
  # println("]")

  list = [1, "a", [2, "b"], 3, "c"]
  json_print(list)
end

# test_01()
# test_02()
# test_03()
# test_04()
# test_05()
# test_06()

json = read_stdin_all()
list = json_parse(json)
json_print(list, true)


text:
# ------------------------------------------------------------------
# Licensed under the ISC License. See LICENSE in the project root.
# ------------------------------------------------------------------

"""
    NearestMapper

A mapping strategy in which data points are assigned to their nearest
point in the domain.
"""
struct NearestMapper <: AbstractMapper end

function Base.map(spatialdata::AbstractData{T,N},
                  domain::AbstractDomain{T,N},
                  targetvars::NTuple{K,Symbol},
                  mapper::NearestMapper) where {N,T,K}
  @assert targetvars ⊆ keys(variables(spatialdata)) "target variables must be present in spatial data"

  # dictionary with mappings
  mappings = Dict(var => Dict{Int,Int}() for var in targetvars)

  # pre-allocate memory for coordinates
  coords = MVector{N,T}(undef)

  # nearest neighbor search method
  neighbor = Vector{Int}(undef, 1)
  searcher = NearestNeighborSearcher(domain, 1)

  for ind in 1:npoints(spatialdata)
    # update datum coordinates
    coordinates!(coords, spatialdata, ind)

    # find nearest location in the domain
    search!(neighbor, coords, searcher)

    # save pair if there is data for variable
    for var in targetvars
      if isvalid(spatialdata, ind, var)
        push!(mappings[var], neighbor[1] => ind)
      end
    end
  end

  mappings
end


text:
using AOC

open("fuel_counter_input.txt") do file
    modules = parse.(Int, eachline(file))
    total_fuel = all_fuel(modules)
    total_fuel_recursive = all_fuel_recursive(modules)
    println(total_fuel)
    println(total_fuel_recursive)
end


text:
# Standard implementation of SGD

# Standard SGD: implementation
function sgd!{T<:AbstractFloat}(rmodel::SupervisedRiskModel, reg::Regularizer,
                                θ::StridedArray{T}, stream::SampleStream,
                                lrate, cbinterval::Int, callback)

    # preparing storage
    g = similar(θ)
    tloss = 0.0

    # main loop
    pm = rmodel.predmodel
    t = 0
    for (x, y) in stream
        t += 1
        n = ninputs(pm, x)

        # evaluate objective and gradient
        v, _ = value_and_grad!(rmodel, reg, g, θ, x, y)

        # update
        λ = convert(T, lrate(t))
        axpy!(-λ, g, θ)  # θ <- θ - λ * g

        # callback
        if cbinterval > 0 && t % cbinterval == 0
            callback(θ, t, n, v)
        end
    end

    # return the result
    return θ
end

# Standard SGD: facet
function sgd{T<:AbstractFloat}(rmodel::SupervisedRiskModel,
                               θ::StridedArray{T},
                               stream::SampleStream;
                               reg::Regularizer=ZeroReg(),
                               lrate=default_lrate,
                               cbinterval::Int = 0,
                               callback=simple_trace)

    sgd!(rmodel, reg, copy(θ), stream, lrate, cbinterval, callback)
end


text:
## playing around with references
struct Byte8
    a :: NTuple{8,UInt8}
end
struct Byte44
    a :: NTuple{4,UInt8}
    b :: NTuple{4,UInt8}
end
struct Byte4864
    d :: UInt8
    c :: UInt64
    a :: NTuple{4,UInt8}
    b :: NTuple{8,UInt8}
end

a   = Ref(Byte8(NTuple{8,UInt8}(1:8)))
b   = Ref(Byte44(NTuple{4,UInt8}(1:4),NTuple{4,UInt8}(1:4)))
c   = Ref(Byte4864(1,0x9900,NTuple{4,UInt8}(1:4),NTuple{8,UInt8}(1:8)))
pa  = Ptr{UInt8}(pointer_from_objref(a))
pb  = Ptr{UInt8}(pointer_from_objref(b))
pc  = Ptr{UInt8}(pointer_from_objref(c))

@show Base.padding(Byte4864)
##
# unsafe_store!(p,UInt8(100),4)
@show a[]size
@show b[]

unsafe_copyto!(pb,pa,8)
@show a[]
@show b[]

##
unsafe_store!(pc,0xff,11); c[]

unsafe_read()


text:
using Test

using FrankWolfe
import FrankWolfe: ActiveSet
using LinearAlgebra: norm

@testset "Active sets" begin

    @testset "Constructors and eltypes" begin
        active_set = ActiveSet([(0.1, [1, 2, 3]), (0.9, [2, 3, 4]), (0.0, [5, 6, 7])])

        @test active_set.weights == [0.1, 0.9, 0.0]
        @test active_set.atoms == [[1, 2, 3], [2, 3, 4], [5, 6, 7]]
        @test eltype(active_set) === Tuple{Float64,Vector{Int}}
        @test FrankWolfe.active_set_validate(active_set)

        # providing the weight type converts the provided weights
        active_set2 = ActiveSet{Vector{Int},Float64}([
            (0.1f0, [1, 2, 3]),
            (0.9f0, [2, 3, 4]),
            (0.0f0, [5, 6, 7]),
        ])

        @test eltype(active_set) === eltype(active_set2)
        @test first(active_set) isa eltype(active_set)
        @test first(active_set2) isa eltype(active_set)
    end

    @testset "Presence and cleanup" begin
        active_set = ActiveSet([(0.1, [1, 2, 3]), (0.9, [2, 3, 4]), (0.0, [5, 6, 7])])
        @test FrankWolfe.find_atom(active_set, [5, 6, 7]) > 0
        FrankWolfe.active_set_cleanup!(active_set)
        @test FrankWolfe.find_atom(active_set, [5, 6, 7]) == -1
    end

    @testset "Renormalization and validation" begin
        active_set = ActiveSet([(0.1, [1, 2, 3]), (0.8, [2, 3, 4]), (0.0, [5, 6, 7])])
        @test !FrankWolfe.active_set_validate(active_set)
        FrankWolfe.active_set_renormalize!(active_set)
        @test FrankWolfe.active_set_validate(active_set)
    end

    @testset "addition of elements and manipulation" begin
        active_set = ActiveSet([(0.5, [1, 2, 3]), (0.5, [2, 3, 4])])
        FrankWolfe.active_set_update!(active_set, 1 / 2, [5, 6, 7])
        @test collect(active_set) == [(0.25, [1, 2, 3]), (0.25, [2, 3, 4]), (0.5, [5, 6, 7])]

        # element addition
        @test FrankWolfe.active_set_validate(active_set) == true
        # update existing element
        FrankWolfe.active_set_update!(active_set, 1.0 / 2, [5, 6, 7])
        @test collect(active_set) == [(0.125, [1, 2, 3]), (0.125, [2, 3, 4]), (0.75, [5, 6, 7])]
        @test FrankWolfe.active_set_validate(active_set) == true
    end

    @testset "active set isempty" begin
        active_set = ActiveSet([(1.0, [1,2,3])])
        @test !isempty(active_set)
        empty!(active_set)
        @test isempty(active_set)
    end

    @testset "Away step operations" begin
        active_set = ActiveSet([(0.125, [1, 2, 3]), (0.125, [2, 3, 4]), (0.75, [5, 6, 7])])

        lambda = FrankWolfe.weight_from_atom(active_set, [5, 6, 7])
        @test lambda == 0.75
        lambda_max = lambda / (1 - lambda)
        FrankWolfe.active_set_update!(active_set, -lambda_max, [5, 6, 7])
        @test collect(active_set) == [(0.5, [1, 2, 3]), (0.5, [2, 3, 4])]

        ## intermediate away step
        lambda = FrankWolfe.weight_from_atom(active_set, [2, 3, 4])
        @test lambda == 0.5
        lambda_max = lambda / (1 - lambda)
        FrankWolfe.active_set_update!(active_set, -lambda_max / 2, [2, 3, 4])
        @test collect(active_set) == [(0.75, [1, 2, 3]), (0.25, [2, 3, 4])]
        x = FrankWolfe.compute_active_set_iterate(active_set)
        @test x == [1.25, 2.25, 3.25]
        λ, a, i = FrankWolfe.active_set_argmin(active_set, [1.0, 1.0, 1.0])
        @test a == [1, 2, 3] && λ == 0.75 && i == 1
        λ, a, i = FrankWolfe.active_set_argmin(active_set, [-1.0, -1.0, -1.0])
        @test a == [2, 3, 4] && λ == 0.25 && i == 2
    end

    @testset "Copying active sets" begin
        active_set = ActiveSet([(0.125, [1, 2, 3]), (0.125, [2, 3, 4]), (0.75, [5, 6, 7])])
        as_copy = copy(active_set)
        # copy is of same type
        @test as_copy isa ActiveSet{Vector{Int}, Float64, Vector{Float64}}
        # copy fields are also copied, same value different location in memory
        @test as_copy.weights !== active_set.weights
        @test as_copy.weights == active_set.weights
        @test as_copy.x !== active_set.x
        @test as_copy.x == active_set.x
        @test as_copy.atoms !== active_set.atoms
        @test as_copy.atoms == active_set.atoms
        # Individual atoms are not copied
        @test as_copy.atoms[1] === active_set.atoms[1]
    end
end

@testset "Simplex gradient descent" begin
    # Gradient descent over a 2-D unit simplex
    # each atom is a vertex, direction points to [1,1]
    # note: integers for atom element types
    # |\ - -  +
    # | \     |
    # |  \
    # |   \   |
    # |    \
    # |     \ |
    # |______\|

    active_set = ActiveSet([(0.5, [0, 0]), (0.5, [0, 1]), (0.0, [1, 0])])
    x = FrankWolfe.compute_active_set_iterate(active_set)
    @test x ≈ [0, 0.5]
    f(x) = (x[1] - 1)^2 + (x[2] - 1)^2

    gradient = similar(x)
    function grad!(storage, x)
        return storage .= [2 * (x[1] - 1), 2 * (x[2] - 1)]
    end
    FrankWolfe.simplex_gradient_descent_over_convex_hull(
        f,
        grad!,
        gradient,
        active_set,
        1e-3,
        1,
        0.0,
        0,
        max_iteration=1000,
        callback=nothing,
    )
    FrankWolfe.active_set_cleanup!(active_set)
    @test length(active_set) == 2
    @test [1, 0] ∈ active_set.atoms
    @test [0, 1] ∈ active_set.atoms
    active_set2 = ActiveSet([(0.5, [0, 0]), (0.0, [0, 1]), (0.5, [1, 0])])
    x2 = FrankWolfe.compute_active_set_iterate(active_set2)
    @test x2 ≈ [0.5, 0]
    FrankWolfe.simplex_gradient_descent_over_convex_hull(
        f,
        grad!,
        gradient,
        active_set2,
        1e-3,
        1,
        0.0,
        0,
        max_iteration=1000,
        callback=nothing,
    )
    @test length(active_set) == 2
    @test [1, 0] ∈ active_set.atoms
    @test [0, 1] ∈ active_set.atoms
    @test FrankWolfe.compute_active_set_iterate(active_set2) ≈ [0.5, 0.5]
    # updating again (at optimum) triggers the active set emptying
    for as in (active_set, active_set2)
        x = FrankWolfe.compute_active_set_iterate(as)
        number_of_steps = FrankWolfe.simplex_gradient_descent_over_convex_hull(
            f,
            grad!,
            gradient,
            as,
            1.0e-3,
            1,
            0.0,
            0,
            max_iteration=1000,
            callback=nothing,
        )
        @test number_of_steps == 0
    end
end

@testset "LP separation oracle" begin
    # Gradient descent over a L-inf ball of radius one
    # current active set contains 3 vertices
    # direction points to [1,1]
    # |\ - -  +
    # | \     |
    # |  \
    # |   \   |
    # |    \
    # |     \ |
    # |______\|

    active_set = ActiveSet([(0.6, [-1, -1]), (0.2, [0, 1]), (0.2, [1, 0])])
    f(x) = (x[1] - 1)^2 + (x[2] - 1)^2
    ∇f(x) = [2 * (x[1] - 1), 2 * (x[2] - 1)]
    lmo = FrankWolfe.LpNormLMO{Inf}(1)

    x = FrankWolfe.compute_active_set_iterate(active_set)
    @test x ≈ [-0.4, -0.4]
    gradient_dir = ∇f(x)
    (y, _) = FrankWolfe.lp_separation_oracle(lmo, active_set, gradient_dir, 0.5, 1)
    @test y ∈ active_set.atoms
    (y2, _) =
        FrankWolfe.lp_separation_oracle(lmo, active_set, gradient_dir, 3 + dot(x, gradient_dir), 1)
    # found new vertex not in active set
    @test y2 ∉ active_set.atoms

    # Criterion too high, no satisfactory point
    (y3, _) = FrankWolfe.lp_separation_oracle(
        lmo,
        active_set,
        gradient_dir,
        norm(gradient_dir)^2 + dot(x, gradient_dir),
        1,
    )
end

@testset "Argminmax" begin
    active_set = FrankWolfe.ActiveSet([(0.6, [-1, -1]), (0.2, [0, 1]), (0.2, [1, 0])])
    (λ_min, a_min, i_min, λ_max, a_max, i_max) =
        FrankWolfe.active_set_argminmax(active_set::ActiveSet, [1, 1.5])
    @test i_min == 1
    @test i_max == 2
end

@testset "LPseparationWithScaledHotVector" begin
    v1 = FrankWolfe.ScaledHotVector(1, 1, 2)
    v2 = FrankWolfe.ScaledHotVector(1, 2, 2)
    v3 = FrankWolfe.ScaledHotVector(0, 2, 2)
    active_set = FrankWolfe.ActiveSet([(0.6, v1), (0.2, v2), (0.2, v3)])
    lmo = FrankWolfe.LpNormLMO{Float64,1}(1.0)
    direction = ones(2)
    min_gap = 0.5
    Ktolerance = 1.0
    FrankWolfe.lp_separation_oracle(
        lmo,
        active_set,
        direction,
        min_gap,
        Ktolerance;
        inplace_loop=true,
    )
end


text:
module TestPipelineStatic

using Test
using MLJBase

t  = MLJBase.WrappedFunction(f=log)
f, = fit(t, 0)
@test transform(t, f, 5) ≈ log(5)

end

module TestPipelines

using MLJBase
using ..Models
using Test
using Statistics
using ScientificTypes
using StableRNGs

rng = StableRNG(698790187)

struct MyTransformer2 <: Static
    ftr::Symbol
end

const verb = 0 # verbosity

MLJBase.transform(transf::MyTransformer2, verbosity, X) =
    selectcols(X, transf.ftr)

NN = 7
X = MLJBase.table(rand(rng,NN, 3));
y = 2X.x1 - X.x2 + 0.05*rand(rng,NN);
Xs = source(X); ys = source(y)

broadcast_mode(v) = mode.(v)
doubler(y) = 2*y

@testset "pipeline helpers" begin
    @test MLJBase.super_type(KNNRegressor()) == Deterministic
    @test MLJBase.super_type(ConstantClassifier()) == Probabilistic
    @test MLJBase.super_type(Standardizer()) == Unsupervised
    @test MLJBase.super_type(:deterministic) == Deterministic
    @test MLJBase.super_type(:probabilistic) == Probabilistic
    @test MLJBase.super_type(:something) == Unsupervised
end

@testset "linear_learning_network" begin
    t = MLJBase.table
    m = MLJBase.matrix
    f = FeatureSelector()
    h = OneHotEncoder()
    k = KNNRegressor()
    u = UnivariateStandardizer()
    c = ConstantClassifier()

    models = [f, h]
    mach = MLJBase.linear_learning_network_machine(
        Unsupervised, Xs, nothing, nothing, nothing, nothing,
        true, predict, models...)
    tree= mach.fitresult.transform |> MLJBase.tree
    @test mach.model isa UnsupervisedSurrogate
    @test tree.operation == transform
    @test tree.model == h
    @test tree.arg1.operation == transform
    @test tree.arg1.model == f
    @test tree.arg1.arg1.source == Xs
    @test tree.arg1.train_arg1.source == Xs
    @test tree.train_arg1 == tree.arg1

    models = [f, k]
    mach = MLJBase.linear_learning_network_machine(
        Deterministic, Xs, ys, nothing, nothing, nothing,
        true, predict, models...)
    tree= mach.fitresult.predict |> MLJBase.tree
    @test mach.model isa DeterministicSurrogate
    @test tree.operation == predict
    @test tree.model == k
    @test tree.arg1.operation == transform
    @test tree.arg1.model == f
    @test tree.arg1.arg1.source == Xs
    @test tree.arg1.train_arg1.source == Xs
    @test tree.train_arg1 == tree.arg1
    @test tree.train_arg2.source == ys

    models = [m, t]
    mach = MLJBase.linear_learning_network_machine(
        Unsupervised, Xs, nothing, nothing, nothing, nothing,
        true, predict, models...)
    tree= mach.fitresult.transform |> MLJBase.tree
    @test mach.model isa UnsupervisedSurrogate
    @test tree.operation == t
    @test tree.model == nothing
    @test tree.arg1.operation == m
    @test tree.arg1.model == nothing
    @test tree.arg1.arg1.source == Xs

    # with learned target transformation:
    models = [f, k]
    mach = MLJBase.linear_learning_network_machine(
        Deterministic, Xs, ys, nothing, u, nothing,
        true, predict, models...)
    tree= mach.fitresult.predict |> MLJBase.tree
    @test mach.model isa DeterministicSurrogate
    @test tree.operation == inverse_transform
    @test tree.model == u
    @test tree.arg1.operation == predict
    @test tree.arg1.model == k
    @test tree.arg1.arg1.operation == transform
    @test tree.arg1.arg1.model == f
    @test tree.arg1.arg1.arg1.source == Xs
    @test tree.arg1.arg1.train_arg1.source == Xs
    @test tree.arg1.train_arg1 == tree.arg1.arg1
    @test tree.arg1.train_arg2.operation == transform
    @test tree.arg1.train_arg2.model == u
    @test tree.arg1.train_arg2.arg1.source == ys
    @test tree.arg1.train_arg2.train_arg1.source == ys
    @test tree.train_arg1.source == ys

    # with static target transformation:
    models = [f, k]
    mach = MLJBase.linear_learning_network_machine(
        Deterministic, Xs, ys, nothing, MLJBase.WrappedFunction(log),
        MLJBase.WrappedFunction(exp),
        true, predict, models...)
    tree= mach.fitresult.predict |> MLJBase.tree
    @test mach.model isa DeterministicSurrogate
    @test tree.operation == transform
    @test tree.model.f == exp
    @test tree.arg1.operation == predict
    @test tree.arg1.model == k
    @test tree.arg1.arg1.operation == transform
    @test tree.arg1.arg1.model == f
    @test tree.arg1.arg1.arg1.source == Xs
    @test tree.arg1.arg1.train_arg1.source == Xs
    @test tree.arg1.train_arg1 == tree.arg1.arg1
    @test tree.arg1.train_arg2.operation == transform
    @test tree.arg1.train_arg2.model.f == log
    @test tree.arg1.train_arg2.arg1.source == ys

    # with supervised model not at end and static target transformation:
    models = [f, c, broadcast_mode]
    mach = MLJBase.linear_learning_network_machine(
        Deterministic, Xs, ys, nothing, MLJBase.WrappedFunction(log),
        MLJBase.WrappedFunction(exp),
        true, predict, models...)
    tree= mach.fitresult.predict |> MLJBase.tree
    @test mach.model isa DeterministicSurrogate
    @test tree.operation == transform
    @test tree.model.f == exp
    @test tree.arg1.operation == broadcast_mode
    @test tree.arg1.model == nothing
    @test tree.arg1.arg1.operation == predict
    @test tree.arg1.arg1.model == c
    @test tree.arg1.arg1.arg1.operation == transform
    @test tree.arg1.arg1.arg1.model == f
    @test tree.arg1.arg1.arg1.arg1.source == Xs
    @test tree.arg1.arg1.arg1.train_arg1.source == Xs
    @test tree.arg1.arg1.train_arg1 == tree.arg1.arg1.arg1
    @test tree.arg1.arg1.train_arg2.operation == transform
    @test tree.arg1.arg1.train_arg2.model.f == log
    @test tree.arg1.arg1.train_arg2.arg1.source == ys

    # with supervised model not at end and with learned target transformation:
    models = [f, c, broadcast_mode]
    mach = MLJBase.linear_learning_network_machine(
        Deterministic, Xs, ys, nothing, u, nothing,
        true, predict, models...)
    tree = mach.fitresult.predict |> MLJBase.tree
    @test mach.model isa DeterministicSurrogate
    @test tree.operation == inverse_transform
    @test tree.model == u
    @test tree.arg1.operation == broadcast_mode
    @test tree.arg1.model == nothing
    @test tree.arg1.arg1.operation == predict
    @test tree.arg1.arg1.model == c
    @test tree.arg1.arg1.arg1.operation == transform
    @test tree.arg1.arg1.arg1.model == f
    @test tree.arg1.arg1.arg1.arg1.source == Xs
    @test tree.arg1.arg1.arg1.train_arg1.source == Xs
    @test tree.arg1.arg1.train_arg1 == tree.arg1.arg1.arg1
    @test tree.arg1.arg1.train_arg2.operation == transform
    @test tree.arg1.arg1.train_arg2.model == u
    @test tree.arg1.arg1.train_arg2.arg1.source == ys
    @test tree.arg1.arg1.train_arg2.train_arg1.source == ys
    @test tree.train_arg1.source == ys

    # test of invert_last=false - learned target transformation:
    models = [k, doubler]
    mach = MLJBase.linear_learning_network_machine(
        Deterministic, Xs, ys, nothing, u, nothing,
        false, predict, models...)
    tree = mach.fitresult.predict |> MLJBase.tree
    @test tree.operation == doubler
    @test tree.arg1.operation == inverse_transform
    @test tree.arg1.arg1.operation == predict
    @test tree.arg1.arg1.arg1.source == Xs
    @test tree.arg1.arg1.train_arg1.source == Xs
    @test tree.arg1.arg1.train_arg2.operation == transform
    @test tree.arg1.arg1.train_arg2.arg1.source == ys
    @test tree.arg1.arg1.train_arg2.train_arg1.source == ys
    @test tree.arg1.train_arg1.source == ys

    # test of invert_last=false - static target transformation:
    models = [k, doubler]
    mach = MLJBase.linear_learning_network_machine(
        Deterministic, Xs, ys, nothing, MLJBase.WrappedFunction(log),
        MLJBase.WrappedFunction(exp),
        false, predict, models...)
    tree = mach.fitresult.predict |> MLJBase.tree
    @test tree.operation == doubler
    @test tree.model == nothing
    @test tree.arg1.operation == transform
    @test tree.arg1.model.f == exp
    @test tree.arg1.arg1.operation == predict
    @test tree.arg1.arg1.arg1.source == Xs
    @test tree.arg1.arg1.train_arg1.source == Xs
    @test tree.arg1.arg1.train_arg2.operation == transform
    @test tree.arg1.arg1.train_arg2.model.f == log
    @test tree.arg1.arg1.train_arg2.arg1.source == ys

    # check a probablistic case:
    models = [f, c]
    mach = MLJBase.linear_learning_network_machine(
        Probabilistic, Xs, ys, nothing, u, nothing,
        true, predict, models...)
    @test mach.model isa ProbabilisticSurrogate

    # check a static case:
    models = [m, t]
    mach = MLJBase.linear_learning_network_machine(
        Static, Xs, ys, nothing, nothing, nothing,
        true, predict, models...)
    @test mach.model isa StaticSurrogate

    # build a linear network for training:
    mach = MLJBase.linear_learning_network_machine(
        Deterministic, Xs, ys, nothing, u, nothing,
        true, predict, f, k)

    # build the same network by hand:
    fM = machine(f, Xs)
    Xt = transform(fM, Xs)
    uM = machine(u, ys)
    yt = transform(uM, ys)
    kM = machine(k, Xt, yt)
    zhat = predict(kM, Xt)
    N2 = inverse_transform(uM, zhat)

    # compare predictions
    fit!(mach, verbosity=verb);
    fit!(N2, verbosity=0)
    yhat = predict(mach, X);
    @test yhat ≈ N2()
    k.K = 3; f.features = [:x3,]
    fit!(mach, verbosity=verb);
    fit!(N2, verbosity=0)
    @test !(yhat ≈ predict(mach, X))
    @test predict(mach, X) ≈ N2()
    global hand_built = predict(mach, X);

end

## PIPELINE_PREPROCESS

F = FeatureSelector()
H = OneHotEncoder()
K = KNNRegressor()
C = ConstantClassifier()
U = UnivariateStandardizer()

m = :(MLJBase.matrix)
t = :(MLJBase.table)
f = :(F)
h = :(H)
k = :(K)
c = :(C)
e = :(target=exp)
l = :(inverse=log)
u = :(target=U)
p = :(prediction_type=:deterministic)
v = :(invert_last=true)

exs = [f, m, t, h, k, u, p, v]
out = MLJBase.pipeline_preprocess(TestPipelines, exs...)
@test string(out[1])[1:8]  == "Pipeline"
@test out[2] ==  [:feature_selector, :one_hot_encoder,
                  :knn_regressor, :target]
@test eval.(out[3]) == [F, H, K, U]
@test eval.(out[4]) ==
    [Unsupervised, Unsupervised, Deterministic, Unsupervised]
@test eval.(out[5]) == [F, MLJBase.matrix, MLJBase.table, H, K]
@test eval.(out[6]) == U
@test eval.(out[7]) == nothing
@test out[8] == true
@test out[9] == predict
@test out[10] == Deterministic
@test haskey(out[11], :supports_weights)

exs =  [f, m, t, h, k, e, l, p, v]
out = MLJBase.pipeline_preprocess(TestPipelines, exs...)
@test out[2] == [:feature_selector, :one_hot_encoder, :knn_regressor,
                 :target, :inverse]
@test eval.(out[3]) == [F, H, K, MLJBase.WrappedFunction(exp),
                 MLJBase.WrappedFunction(log)]
@test eval.(out[4]) == [Unsupervised, Unsupervised,
                        Deterministic, Unsupervised, Unsupervised]
@test eval.(out[5]) == [F, MLJBase.matrix, MLJBase.table, H, K]
@test eval.(out[6]) == MLJBase.WrappedFunction(exp)
@test eval.(out[7]) == MLJBase.WrappedFunction(log)
@test out[10] == Deterministic

# invert_last = false:
exs = [k, :(doubler), u]
out = @test_logs((:info, r"Treating pipeline as"),
                 MLJBase.pipeline_preprocess(TestPipelines, exs...))
@test out[8] == false

exs = [m, t, :(MyTransformer2(:age))]
out = MLJBase.pipeline_preprocess(TestPipelines, exs...)
@test out[10] == Static

exs = [f, m, t, h, k, u, p, :(name=MyPipe)]
out = MLJBase.pipeline_preprocess(TestPipelines, exs...)
@test out[1] == :MyPipe

exs = [f, m, t, h, k, u, p, :(name="MyPipe2")]
out = MLJBase.pipeline_preprocess(TestPipelines, exs...)
@test out[1] == :MyPipe2

exs = [f, m, t, h, k, u, p, :(name=:MyPipe3)]
out = MLJBase.pipeline_preprocess(TestPipelines, exs...)
@test out[1] == :MyPipe3

# auto-detect probablistic predictions:
exs = [f, m, t, h, c]
out = MLJBase.pipeline_preprocess(TestPipelines, exs...)
@test out[10] == Probabilistic

# prediction_type=:probabilistic declared but no supervised models
exs = [f, m, t, h, :(prediction_type=:probabilistic)]
@test_logs (:warn, r"Pipeline appears to have no") begin
    MLJBase.pipeline_preprocess(TestPipelines, exs...)
end

exs = [f, m, t, h, k, u]
@test_logs (:info, r"Treating") begin
    MLJBase.pipeline_preprocess(TestPipelines, exs...)
end

# unsupported operation:
exs = [h, k, :(operation=transform)]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))
exs = [h, k, :(operation=:predict)]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# pipe_line error 3:
exs =  Symbol[]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# target is a function but no inverse=...:
exs =  [f, m, t, h, k, e, p]
@test_throws(ArgumentError,
MLJBase.pipeline_preprocess(TestPipelines, exs...))

# inverse but no target:
exs =  [f, k, l, p]
@test_throws(ArgumentError,
MLJBase.pipeline_preprocess(TestPipelines, exs...))

# target specified but no component is supervised:
exs =  [f, h, u]
@test_throws(ArgumentError,
MLJBase.pipeline_preprocess(TestPipelines, exs...))

# pipe_line error 8:
exs = [f, m, t, h, k, u, p, :("mary"=true)]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# target has wrong form:
exs = [f, m, t, h, k, u, p, :(target=KNNRegressor)]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))
exs = [f, m, t, h, k, u, p, :(target=KNNRegressor())]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))
exs = [f, m, t, h, k, u, p, :(target="junk")]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# inverse not a function:
exs =  [f, m, t, h, k, e, p, :(inverse=Standardizer())]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# bad name for pipeline:
exs = [f, m, t, h, k, u, p, :(name=true)]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# existing name:
exs = [f, m, t, h, k, u, :(name=Int)]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# bad prediction_type:
exs = [f, m, t, h, k, u, :(prediction_type=:junk)]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# invalid key-word
exs = [f, m, t, h, k, u, :(junk=:junk)]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# non-expression:
exs = [f, m, t, h, k, u, :("junk")]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# junk expression:
exs = [f, m, t, h, k, u, :(sin(2))]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# datatype that's not a model:
exs = [f, m, t, h, k, u, :Int]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

# More than one component of the pipeline is a supervised model:
exs = [f, m, t, h, k, u, k]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

exs = [f, m, k, :(prediction_type=:probabilistic)]
@test_throws(ArgumentError,
             MLJBase.pipeline_preprocess(TestPipelines, exs...))

exs = [h, c, u]
@test_logs((:info, r"Treating"),
           (:warn, r"Pipeline is applying"),
           MLJBase.pipeline_preprocess(TestPipelines, exs...))

## SIMPLE SUPERVISED PIPELINE WITH TARGET TRANSFORM

# test a simple pipeline prediction agrees with prediction of
# hand-built learning network built earlier:
p = @pipeline(FeatureSelector,
              KNNRegressor,
              target=UnivariateStandardizer,
              prediction_type=:deterministic)
p.knn_regressor.K = 3; p.feature_selector.features = [:x3,]
mach = machine(p, X, y)
fit!(mach, verbosity=verb)
@test MLJBase.tree(mach.fitresult.predict).arg1.model.K == 3
MLJBase.tree(mach.fitresult.predict).arg1.arg1.model.features == [:x3, ]
@test predict(mach, X) ≈ hand_built

# test a simple probabilistic classifier pipeline:
X = MLJBase.table(rand(rng,7,3));
y = categorical(collect("ffmmfmf"));
Xs = source(X)
ys = source(y)
p = @pipeline OneHotEncoder ConstantClassifier
mach = machine(p, X, y)
fit!(mach, verbosity=verb)
@test p isa ProbabilisticComposite
pdf(predict(mach, X)[1], 'f') ≈ 4/7

# test invalid replacement of classifier with regressor throws
# informative error message:
p.constant_classifier = ConstantRegressor()

@test_logs((:error, r"^Problem"),
           (:info, r"^Running type"),
           (:warn, r""),
           (:info, r"It seems"),
           (:error, r"Problem"),
           @test_throws Exception fit!(mach, verbosity=-1))

# test a simple deterministic classifier pipeline:
X = MLJBase.table(rand(rng,7,3))
y = categorical(collect("ffmmfmf"))
Xs = source(X)
ys = source(y)
p = @pipeline(OneHotEncoder, ConstantClassifier, broadcast_mode,
              prediction_type=:probabilistic)
mach = machine(p, X, y)
fit!(mach, verbosity=verb)
@test predict(mach, X) == fill('f', 7)

# test pipelines with weights:
w = map(y) do η
    η == 'm' ? 100 : 1
end
mach = machine(p, X, y, w)
fit!(mach, verbosity=verb)
@test predict(mach, X) == fill('m', 7)

# test a pipeline with static transformation of target:
NN = 100
X = (x1=rand(rng,NN), x2=rand(rng,NN), x3=categorical(rand(rng,"abc", NN)));
y = 1000*abs.(2X.x1 - X.x2 + 0.05*rand(rng,NN))
# by hand:
Xs =source(X); ys = source(y)
hot = OneHotEncoder()
hot_=machine(hot, Xs)
W = transform(hot_, Xs)
sel = FeatureSelector(features=[:x1,:x3__a])
sel_ = machine(sel, W)
Wsmall = transform(sel_, W)
z = log(ys)
knn = KNNRegressor(K=4)
knn_ = machine(knn, Wsmall, z)
zhat = predict(knn_, Wsmall)
yhat = exp(zhat)
fit!(yhat, verbosity=0)
pred1 = yhat();
# with pipeline:
p = @pipeline(OneHotEncoder,
              FeatureSelector,
              KNNRegressor,
              target=v->log.(v),
              inverse=v->exp.(v),
              prediction_type=:deterministic)
p.feature_selector.features = [:x1, :x3__a]
p.knn_regressor.K = 4
p_ = machine(p, X, y)
fit!(p_, verbosity=0)
pred2 = predict(p_, X);
@test pred1 ≈ pred2

# and another:
age = [23, 45, 34, 25, 67]
X = (age = age,
     gender = categorical(['m', 'm', 'f', 'm', 'f']))
height = [67.0, 81.5, 55.6, 90.0, 61.1]
p = @pipeline(X -> coerce(X, :age=>Continuous),
              OneHotEncoder,
              KNNRegressor(K=3),
              target = UnivariateStandardizer,
              prediction_type = :probabilistic)
fit!(machine(p, X, height), verbosity=0)

## STATIC TRANSFORMERS IN PIPELINES

p99 = @pipeline(X -> coerce(X, :age=>Continuous),
                OneHotEncoder,
                MyTransformer2(:age))

mach = fit!(machine(p99, X), verbosity=0)

@test transform(mach, X) == float.(X.age)

## PURE STATIC PIPLINES

p = @pipeline(X -> coerce(X, :age=>Continuous),
                MyTransformer2(:age))

# no training arguments!
mach = fit!(machine(p), verbosity=0)
@test transform(mach, X) == X.age

p = @pipeline exp log x-> 2*x
mach = fit!(machine(p), verbosity=0)
@test transform(mach, 20) ≈ 40

## OPERATION DIFFERENT FROM PREDICT

p = @pipeline(OneHotEncoder,
              ConstantRegressor,
              operation=predict_mean)

@test p isa Deterministic

mach = fit!(machine(p, X, height), verbosity=0)
@test scitype(predict(mach, X)) == AbstractVector{Continuous}

## USE OF INVERT_LAST

X = (x1 = float.(1:10),)
y = X.x1

p = @pipeline(KNNRegressor(K=1), doubler, target=UnivariateStandardizer,
              prediction_type=:deterministic)

mach = fit!(machine(p, X, y), verbosity=0)
@test predict(mach, X) ≈ doubler(y)

p = @pipeline(KNNRegressor(K=1), doubler, target=UnivariateStandardizer,
              invert_last=true, prediction_type=:deterministic)
mach = fit!(machine(p, X, y), verbosity=0)
@test !(predict(mach, X) ≈ doubler(y))

end

true


text:
using OffsetArrays
using Dates

const int64_t = Int64
const uint64_t = UInt64
const UA_INT64_MAX = typemax(Int64)
const UA_INT64_MIN = typemin(Int64)
const UA_UINT64_MAX = typemax(UInt64)
const UA_UINT64_MIN = typemin(UInt64)
const UA_FALSE = false
const UA_TRUE = true

const UA_EMPTY_ARRAY_SENTINEL = convert(Ptr{Nothing}, Int(0x01))


text:
struct Point
    x
    y
end

p = Point(1.0, 5.0)
println("$(p.x), $(p.y)")
# Structs are immutable after initialisation. This is invalid:
# p.x = 7.0

mutable struct MPoint
    x
    y
end

mp = MPoint(6, 10.0)
mp.x = 3.0
mp.y = 2.5
println("$(mp.x), $(mp.y)")

struct Rectangle
    width::Number
    height::Number
    corner
end

r = Rectangle(3, 7.1, MPoint(0.0, 0.0))
# Constructor must adhere to type requirements. This is invalid:
# r_invalid = Rectangle(3, "abc", Point(0.0, 0.0))
println(r.corner.x)

function movepoint!(p, dx, dy)
    p.x += dx
    p.y += dy
    nothing
end

movepoint!(mp, 1.0, 2.0)
println("$(mp.x), $(mp.y)")
# This is invalid since a Point is not mutable:
# movepoint!(p, 1.0, 2.0)

function moverectangle!(rect, dx, dy)
    movepoint!(rect.corner, dx, dy)
end

# The following is valid, because the corner attribute of Rectangle is mutable.
moverectangle!(r, 1.0, 2.0)
println(r)
# Reassignment will still not work since that is mutating the Rectangle object.
# r.corner = MPoint(10.1, 3.2)

mpcopy = deepcopy(mp)
println("mp == mpcopy: $(mp == mpcopy)") # Default behavior follows ===
println("mp === mpcopy: $(mp === mpcopy)")

println("typeof(p): $(typeof(p))")
println("p isa Point: $(p isa Point)")
println("fieldnames(Point): $(fieldnames(Point))")
println("fieldnames(Dict): $(fieldnames(Dict))")
println("isdefined(p, :x): $(isdefined(p, :x))")
println("isdefined(p, :z): $(isdefined(p, :z))")

function isposeven(val::Int64)
    return val > 0 && val % 2 == 0
end

function addposeven(a::Int64, b::Int64)
    if !isposeven(a) || !isposeven(b)
        error("Invalid values used for addposeven.")
    end
    return a + b
end

function addposeven_assert(a::Int64, b::Int64)
    @assert(isposeven(a) && isposeven(b), "Invalid values used for addposeven.")
    return a + b
end

# println(addposeven(2, 3))
# println(addposeven_assert(2, 3))


text:
# Example inspiration and Lego model by https://github.com/Kevin-Mattheus-Moerman
# https://twitter.com/KMMoerman/status/1417759722963415041
using MeshIO, FileIO, GeometryBasics, RPRMakie

colors = Dict(
    "eyes" => "#000",
    "belt" => "#000059",
    "arm" => "#009925",
    "leg" => "#3369E8",
    "torso" => "#D50F25",
    "head" => "yellow",
    "hand" => "yellow"
)

origins = Dict(
    "arm_right" => Point3f(0.1427, -6.2127, 5.7342),
    "arm_left" => Point3f(0.1427, 6.2127, 5.7342),
    "leg_right" => Point3f(0, -1, -8.2),
    "leg_left" => Point3f(0, 1, -8.2),
)

rotation_axes = Dict(
    "arm_right" => Vec3f(0.0000, -0.9828, 0.1848),
    "arm_left" => Vec3f(0.0000, 0.9828, 0.1848),
    "leg_right" => Vec3f(0, -1, 0),
    "leg_left" => Vec3f(0, 1, 0),
)

function plot_part!(scene, parent, name::String)
    m = load(assetpath("lego_figure_" * name * ".stl"))
    color = colors[split(name, "_")[1]]
    trans = Transformation(parent)
    ptrans = Makie.transformation(parent)
    origin = get(origins, name, nothing)
    if !isnothing(origin)
        centered = m.position .- origin
        m = GeometryBasics.Mesh(meta(centered; normals=m.normals), faces(m))
        translate!(trans, origin)
    else
        translate!(trans, -ptrans.translation[])
    end
    return mesh!(scene, m; color=color, transformation=trans)
end

function plot_lego_figure(s, floor=true)
    # Plot hierarchical mesh!
    figure = Dict()
    # Plot hierarchical mesh!
    figure["torso"] = plot_part!(s, s, "torso")
        figure["head"] = plot_part!(s, figure["torso"], "head")
            figure["eyes_mouth"] = plot_part!(s, figure["head"], "eyes_mouth")
        figure["arm_right"] = plot_part!(s, figure["torso"], "arm_right")
            figure["hand_right"] = plot_part!(s, figure["arm_right"], "hand_right")
        figure["arm_left"] = plot_part!(s, figure["torso"], "arm_left")
            figure["hand_left"] = plot_part!(s, figure["arm_left"], "hand_left")
        figure["belt"] = plot_part!(s, figure["torso"], "belt")
            figure["leg_right"] = plot_part!(s, figure["belt"], "leg_right")
            figure["leg_left"] = plot_part!(s, figure["belt"], "leg_left")
    # lift the little guy up
    translate!(figure["torso"], 0, 0, 20)
    # add some floor
    floor && mesh!(s, Rect3f(Vec3f(-400, -400, -2), Vec3f(800, 800, 2)), color=:white)
    return figure
end

RPRMakie.activate!(iterations=200, plugin=RPR.Northstar)
radiance = 50000
lights = [
    EnvironmentLight(1.5, rotl90(load(assetpath("sunflowers_1k.hdr"))')),
    PointLight(Vec3f(50, 0, 200), RGBf(radiance, radiance, radiance*1.1)),
]
s = Scene(resolution=(500, 500), lights=lights)

cam3d!(s)
c = cameracontrols(s)
c.near[] = 5
c.far[] = 1000
update_cam!(s, c, Vec3f(100, 30, 80), Vec3f(0, 0, -10))
figure = plot_lego_figure(s)

rot_joints_by = 0.25*pi
total_translation = 50
animation_strides = 10

a1 = LinRange(0, rot_joints_by, animation_strides)
angles = [a1; reverse(a1[1:end-1]); -a1[2:end]; reverse(-a1[1:end-1]);]
nsteps = length(angles); #Number of animation steps
translations = LinRange(0, total_translation, nsteps)

Makie.record(s, "lego_walk.mp4", zip(translations, angles)) do (translation, angle)

    # Rotate right arm + hand
    for name in ["arm_left", "arm_right", "leg_left", "leg_right"]
        rotate!(figure[name], rotation_axes[name], angle)
    end
    translate!(figure["torso"], translation, 0, 20)
end


text:
module Square
	using FromFile
    @from "../types.jl" import MyInt

    int_square(x::MyInt)::MyInt = MyInt(x.value^2)
end

module Cube
	using FromFile
    @from "../types.jl" import MyInt

    int_cube(x::MyInt)::MyInt = MyInt(x.value^3)
end


text:
function demoHMMinferenceFG()

    H = 6 # number of Hidden states
    V = 2 # number of Visible states
    T = 5 # length of the time-series
    # setup the HMM
    phghm = rand(H,H); phghm = phghm./repmat(sum(phghm,1),H,1);# transition distribution p(h(t)|h(t-1))
    pvgh = rand(V,H); pvgh = pvgh./repmat(sum(pvgh,1),V,1);# emission distribution p(v(t)|h(t))
    ph1 = rand(H,1); ph1=ph1./sum(ph1); # initial p(h)
    # generate some fake data
    h=Array{Int64}(1,T)
    v=Array{Int64}(1,T)
    h[1] = randgen(ph1); v[1]=randgen(pvgh[:,h[1]]);
    for t=2:T
        h[t]=randgen(phghm[:,h[t-1]]);	v[t]=randgen(pvgh[:,h[t]]);
    end
    # Perform Inference tasks:
    #[logalpha,loglik]=HMMforward(v,phghm,ph1,pvgh); % forward
    #logbeta=HMMbackward(v,phghm,pvgh); % backward
    #% smoothed posteriors:
    #[phtgV1T,phthtpgV1T]=HMMsmooth(logalpha,logbeta,pvgh,phghm,v);
    #gamma=HMMgamma(logalpha,phghm); % alternative alpha-gamma (RTS) method
    #[viterbimaxstate logprob]=HMMviterbi(v,phghm,ph1,pvgh); % most likely joint state

    # Factor graph approach:
    ht=1:T; vt=T+1:2*T; # assign numbers to variables
    pot=Array{PotArray}(2*T)
    pot[ht[1]]=PotArray(ht[1],ph1);
    pot[vt[1]]=PotArray([vt[1] ht[1]], pvgh);
    for t=2:T
        pot[vt[t]]=PotArray([vt[t] ht[t]],pvgh);
        pot[ht[t]]=PotArray([ht[t] ht[t-1]],phghm);
    end

    newpot=Array{PotArray}(T)
    for t=1:T; newpot[t]=multpots([setpot(pot[vt[t]],vt[t],v[t]) pot[ht[t]]]); end

    AFG = FactorGraph(newpot)
    marg, mess=sumprod(newpot,AFG)
    # likelihood
    dum1, fact2var, dum2=FactorConnectingVariable(ht[1],AFG); # can choose any of the variable nodes
    tmpmess = multpots(mess[fact2var])
    FGloglik = log(sum(tmpmess.content))

    # check:
    println("\nLog likelihood computed by SumProd Algorithm and Raw Summation:")
    println([FGloglik log.((sum(prod(newpot))).content)])

    println("\nSmoothed Posterior marginal inference (smoothing) computed by SumProd verus Raw Summation:")

    for ht=1:T
        println("\nVariable $ht:")
        rawmarg=condpot(prod(newpot),ht)
        sumprodmarg=condpot(marg[ht],ht)
        println([sumprodmarg.content rawmarg.content])
    end

end


text:
using BenchmarkTools, Plots, SNOPT7
using MeshCatMechanisms, MeshCat, GeometryTypes

T = Float64

# options
max_con_viol = 1.0e-8
verbose=false

opts_ilqr = iLQRSolverOptions{T}(verbose=verbose,
    iterations=300,
    live_plotting=:off)

opts_al = AugmentedLagrangianSolverOptions{T}(verbose=verbose,
    opts_uncon=opts_ilqr,
    iterations=20,
    cost_tolerance=1.0e-6,
    cost_tolerance_intermediate=1.0e-5,
    constraint_tolerance=max_con_viol,
    penalty_scaling=50.,
    penalty_initial=0.01)

opts_pn = ProjectedNewtonSolverOptions{T}(verbose=verbose,
    feasibility_tolerance=max_con_viol,
    solve_type=:feasible)

opts_altro = ALTROSolverOptions{T}(verbose=verbose,
    opts_al=opts_al,
    opts_pn=opts_pn,
    projected_newton=true,
    projected_newton_tolerance=1.0e-5)

opts_ipopt = DIRCOLSolverOptions{T}(verbose=verbose,
    nlp=Ipopt.Optimizer(),
    feasibility_tolerance=max_con_viol)

opts_snopt = DIRCOLSolverOptions{T}(verbose=verbose,
    nlp=SNOPT7.Optimizer(),
    feasibility_tolerance=max_con_viol,
    opts=Dict(:Iterations_limit=>100000,
        :Major_iterations_limit=>1000))

# ALTRO w/ Newton
prob_altro = copy(Problems.kuka_problem)
@time p1, s1 = solve(prob_altro, opts_altro)
@benchmark p1, s1 = solve($prob_altro, $opts_altro)
max_violation_direct(p1)
plot(p1.X,title="Kuka state (ALTRO)")
plot(p1.U,title="Kuka control (ALTRO)")

# DIRCOL w/ Ipopt
prob_ipopt = copy(Problems.kuka_obstacles)
rollout!(prob_ipopt)
prob_ipopt = update_problem(prob_ipopt,model=Dynamics.kuka)
@time p2, s2 = solve(prob_ipopt, opts_ipopt)
@benchmark p2, s2 = solve($prob_ipopt, $opts_ipopt)
max_violation_direct(p2)
plot(p2.X,title="Kuka state (Ipopt)")
plot(p2.U,title="Kuka control (Ipopt)")

# DIRCOL w/ SNOPT
prob_snopt = copy(Problems.kuka_obstacles)
rollout!(prob_snopt)
prob_snopt = update_problem(prob_snopt,model=Dynamics.kuka) # get continuous time model
@time p3, s3 = solve(prob_snopt, opts_snopt)
@benchmark p3, s3 = solve($prob_snopt, $opts_snopt)
max_violation_direct(p3)
plot(p3.X,title="Kuka state (SNOPT)")
plot(p3.U,title="Kuka control (SNOPT)")

# Visualization
kuka = parse_urdf(Dynamics.urdf_kuka,remove_fixed_tree_joints=false)
kuka_visuals = URDFVisuals(Dynamics.urdf_kuka)

function plot_sphere(vis::MechanismVisualizer,frame::CartesianFrame3D,center,radius,mat,name="")
    geom = HyperSphere(Point3f0(center), convert(Float32,radius))
    setelement!(vis,frame,geom,mat,name)
end

function plot_cylinder(vis::MechanismVisualizer,frame::CartesianFrame3D,c1,c2,radius,mat,name="")
    geom = Cylinder(Point3f0(c1),Point3f0(c2),convert(Float32,radius))
    setelement!(vis,frame,geom,mat,name)
end

function addcircles!(vis,circles,robot)
    world = root_frame(robot)
    for (i,circle) in enumerate(circles)
        p = Point3D(world,collect(circle[1:3]))
        setelement!(vis,p,circle[4],"obs$i")
    end
end

function addcylinders!(vis,cylinders,robot,height=1.5,clr=MeshPhongMaterial(color=RGBA(0, 0, 1, 0.5)))
    world = root_frame(robot)
    for (i,cyl) in enumerate(cylinders)
        plot_cylinder(vis,world,[cyl[1],cyl[2],0],[cyl[1],cyl[2],height],cyl[3],clr,"cyl_$i")
    end
end

function visualize_kuka_obstacles(prob,circles_kuka,cylinders_kuka,kuka_points=false)
    N = length(prob.X)
    vis = Visualizer()
    open(vis)
    mvis = MechanismVisualizer(kuka, kuka_visuals, vis[:base])
    addcircles!(mvis,circles_kuka,kuka)
    addcylinders!(mvis,cylinders_kuka,kuka)

    if kuka_points
        plot=true
        bodies = [3,4,5,6]
        radii = [0.1,0.12,0.09,0.09]
        ee_body,ee_point = Dynamics.get_kuka_ee(kuka)
        ee_radii = 0.05
        body_collision = MeshPhongMaterial(color=RGBA(1, 0, 0, 0.25))

        points = Point3D[]
        frames = CartesianFrame3D[]
        for (idx,radius) in zip(bodies,radii)
            body = findbody(kuka,"iiwa_link_$idx")
            frame = default_frame(body)
            point = Point3D(frame,0.,0.,0.)
            plot ? plot_sphere(mvis,frame,0,radius,body_collision,"body_$idx") : nothing
            plot ? setelement!(mvis,point,radius,"body_$idx") : nothing
            push!(points,point)
            push!(frames,frame)
        end
    end

    q = [prob.X[k][1:convert(Int,prob.model.n/2)] for k = 1:N]
    t = range(0,stop=prob.tf,length=N)
    setanimation!(mvis,t,q)
end

visualize_kuka_obstacles(p2,Problems.kuka_obstacles_objects[1],Problems.kuka_obstacles_objects[2],true)

max_issues_repo_name: MehrdadZareian/GMARA

max_forks_repo_name: MehrdadZareian/GMARA


text:
import DataFrames
import Statistics

"""
```julia
chill(::Val{:CumulativeChillUnit}, weatherData::DataFrame)::DataFrame
```

Implements the [Cumulative Chill Unit](chill_CumulativeChillUnit.md) model
(also known as the Utah model).

# Arguments

- `weatherData::DataFrames.DataFrame`: The weather data used for calculating
    the cumulative chill units. `weatherData` must be formatted to match the
    output of [`BiTWeather.read`](@ref) and contain at least the `:temperature`
    field.

# Return

- A `DataFrames.DataFrame` containing the chill units indexed by
    year/month/day/hour. The returned columns are: year, month, temperature,
    ``\\Delta y(n)``, and ``y(n)``.

# Example

```julia
import DataFrames
import Dates
import BiTWeather

configuration = BiTWeather.Configuration(
    dsn = "meteobridge",
    table = "backinthirty",
    fieldMappings = Dict(
        :dateTime =>    BiTWeather.FieldMapping(name = "DateTime",   units = nothing),
        :temperature => BiTWeather.FieldMapping(name = "TempOutNow", units = "F")
    )
)

year::Int = 2021
rangeStart::Dates.Date = Dates.Date(year - 1, 11, 1)
rangeEnd::Dates.Date = Dates.Date(year, 2, 28)
range::Tuple{Float64, Float64} = (rangeStart, rangeEnd)
fields::Vector{Symbol} = [:temperature]
weatherData::DataFrames.DataFrame = BiTWeather.read(configuration, range, fields)
chillData::DataFrames.DataFrame = BiTWeather.chill(Val(:CumulativeChillUnit), weatherData)
println(chillData)
```
"""
function chill(::Val{:CumulativeChillUnit}, weatherData::DataFrames.DataFrame)::DataFrames.DataFrame

    # The chill calculation requires the :temperature field.
    if !(:temperature in DataFrames.propertynames(weatherData))
        error("weatherData must contain the :temperature field")
    end

    #= -------------------------------------------------------------------------
    This function performs the chill calculation for one interval. It is passed
    the temperature as well as the state needed to perform the calculation. It
    returns the result of the calculation and the state needed to perform the
    next interval's calculation.

    Arguments:
        temperature: The temperature.
        y_nMinus1::Float64: The accumulated chill units after the previous
            interval's calculation
    Returns:
        Result:
            delta_y_n::Float64: The number of chill units from this interval.
            y_n::Float64: The accumulated chill units at the completion of this
                interval.
        State:
            y_nMinus1
    ------------------------------------------------------------------------- =#
    function calculate(temperature::Float64, y_nMinus1::Float64)

        theta_n::Float64 = (temperature * (9.0 / 5.0)) + 32.0

        if     theta_n <= 34.0
            delta_y_n::Float64 =  0.0
        elseif theta_n <= 36.0
            delta_y_n =  0.5
        elseif theta_n <= 48.0
            delta_y_n =  1.0
        elseif theta_n <= 54.0
            delta_y_n =  0.5
        elseif theta_n <= 60.0
            delta_y_n =  0.0
        elseif theta_n <= 65.0
            delta_y_n = -0.5
        else
            delta_y_n = -1.0
        end

        y_n::Float64 = y_nMinus1 + delta_y_n

        return delta_y_n, y_n, y_n
    end

    ccu::DataFrames.DataFrame = weatherData

    # Determine the hourly temperature.
    gdf::DataFrames.GroupedDataFrame = DataFrames.groupby(ccu, [:year, :month, :day, :hour])
    ccu = DataFrames.combine(gdf,
        [:temperature] .=> Statistics.mean .=> [:temperature]
    )
    DataFrames.select!(ccu, [:year, :month, :day, :hour, :temperature])
    DataFrames.sort!(ccu, [:year, :month, :day, :hour])

    delta_y::Vector{Float64} = []
    y::Vector{Float64} = []

    y_nMinus1::Float64 = 0.0
    for row in DataFrames.eachrow(ccu)
        delta_y_n::Float64, y_n::Float64, y_nMinus1 = calculate(row.temperature, y_nMinus1)
        push!(delta_y, delta_y_n)
        push!(y, y_n)
    end

    ccu[!, :delta_y_n] = delta_y
    ccu[!, :y_n] = y

    for name in DataFrames.propertynames(ccu)
        if eltype(ccu[!, name]) == Float64
            ccu[!, name] = round.(ccu[!, name], digits = 2)
        end
    end

    return ccu
end

"""
```julia
chillPlot(::Val{:CumulativeChillUnit}, chillData::DataFrame)::PlotlyJS.Plot
```

Generates a plot of the [Cumulative Chill Unit](chill_CumulativeChillUnit.md) model
data.

# Arguments

- `chillData::DataFrames.DataFrame`: The chill data used in generating the plot.
    `chillData` must be formated to match the output of
    [`BiTWeather.chill`](@ref) called with `Val(:CumulativeChillUnit)`.

# Return

- A `PlotlyJS.Plot` containing a plot of the temperature and chill portion data.

# Example

```julia
import DataFrames
import Dates
import PlotlyJS
import BiTWeather

configuration = BiTWeather.Configuration(
    dsn = "meteobridge",
    table = "backinthirty",
    fieldMappings = Dict(
        :dateTime =>    BiTWeather.FieldMapping(name = "DateTime",   units = nothing),
        :temperature => BiTWeather.FieldMapping(name = "TempOutNow", units = "F")
    )
)

year::Int = 2021
rangeStart::Dates.Date = Dates.Date(year - 1, 11, 1)
rangeEnd::Dates.Date = Dates.Date(year, 2, 28)
range::Tuple{Float64, Float64} = (rangeStart, rangeEnd)
fields::Vector{Symbol} = [:temperature]
weatherData::DataFrames.DataFrame = BiTWeather.read(configuration, range, fields)
chillData::DataFrames.DataFrame = BiTWeather.chill(Val(:CumulativeChillUnit), weatherData)
plot::PlotlyJS.Plot = BiTWeather.chillPlot(Val(:CumulativeChillUnit), chillData)
PlotlyJS.display(plot)
```
"""
function chillPlot(::Val{:CumulativeChillUnit}, chillData::DataFrames.DataFrame)::PlotlyJS.Plot
    return _chillPlot(chillData, :temperature, :y_n, "Cumulative Chill Unit", "Units")
end

max_stars_repo_name: pebender/BiTWeather

max_issues_repo_name: pebender/BiTWeather

max_forks_repo_name: pebender/BiTWeather


text:
# collect(::Vector) does a copy.
# lazy_collect avoid this copy in case `v` is a Vector
lazy_collect(v::Vector) = v
lazy_collect(v) = collect(v)

# H-representation

"""
    hrep(hyperplanes::HyperPlaneIt, halfspaces::HalfSpaceIt)

Creates an H-representation for the polyhedron equal to the intersection of the hyperplanes `hyperplanes` and halfspaces `halfspaces`.

### Examples
For instance, the simplex
```math
\\begin{align*}
  x_1 + x_2 &= 1 \\\\
  x_1 &\\geq 0 \\\\
  x_2 &\\geq 0
\\end{align*}
```
can be created as follows:
```julia
hrep([HalfSpace([-1, 0], 0)], [HyperPlane([1, 1], 1), HalfSpace([0, -1], 0)])
```
"""
hrep(hyperplanes::HyperPlaneIt, halfspaces::HalfSpaceIt) = Intersection(hyperplanes, halfspaces)

"""
    hrep(halfspaces::HalfSpaceIt)

Creates an H-representation for the polyhedron equal to the intersection of the halfspaces `halfspaces`.

### Examples
For instance, the polytope
```math
\\begin{align*}
  x_1 + x_2 &\\leq 1 \\\\
  x_1 - x_2 &\\leq 0 \\\\
  x_1 & \\geq 0.
\\end{align*}
```
can be created as follows:
```julia
hrep([HalfSpace([1, 1], 1), HalfSpace([1, -1], 0), HalfSpace([-1, 0], 0)])
```
"""
hrep(halfspaces::ElemIt{HalfSpace{N, T, AT}}) where {N, T, AT} = hrep(HyperPlane{N, T, AT}[], halfspaces)

mutable struct Intersection{N, T, AT} <: HRepresentation{N, T}
    hyperplanes::HyperPlanesIntersection{N, T, AT}
    halfspaces::Vector{HalfSpace{N, T, AT}}
    function Intersection{N, T, AT}(hyperplanes::HyperPlaneIt{N, T}, halfspaces::HalfSpaceIt{N, T}) where {N, T, AT}
        new{N, T, AT}(HyperPlanesIntersection{N, T, AT}(hyperplanes), lazy_collect(halfspaces))
    end
end
Intersection(hyperplanes::ElemIt{HyperPlane{N, T, AT}}, halfspaces::ElemIt{HalfSpace{N, T, AT}}) where {N, T, AT} = Intersection{N, T, AT}(hyperplanes, halfspaces)
hvectortype(::Type{Intersection{N, T, AT}}) where {N, T, AT} = AT
similar_type(PT::Type{<:Intersection}, d::FullDim{N}, ::Type{T}) where {N, T} = Intersection{N, T, similar_type(hvectortype(PT), d, T)}

Intersection(h::HRepresentation{N, T}) where {N, T} = Intersection{N, T}(h)
Intersection{N, T}(h::HRepresentation{N}) where {N, T} = Intersection{N, T, similar_type(hvectortype(typeof(h)), T)}(h)

@subrepelem Intersection HyperPlane hyperplanes
@vecrepelem Intersection HalfSpace halfspaces

fulltype(::Type{<:Union{Intersection{N, T, AT}, HyperPlanesIntersection{N, T, AT}}}) where {N, T, AT} = Intersection{N, T, AT}

# V-representation

#"""
#    vrep(sympoints::SymPointIt)
#
#Creates a V-representation for the symmetric polytope equal to the convex hull of the symmetric points `sympoints`.
#
#### Examples
#The following creates a square
#```julia
#vrep([SymPoint([1, 1])], [SymPoint([1, -1])])
#```
#"""
#vrep(sympoints::SymPointIt) = SymPointsHull(sympoints)
#
#mutable struct SymPointsHull{N, T, AT} <: VSymPolytope{N, T}
#    sympoints::Vector{SymPoint{N, T, AT}}
#    function SymPointsHull{N, T, AT}(sympoints::SymPointIt{N, T}) where {N, T, AT}
#        new{N, T, AT}(lazy_collect(sympoints))
#    end
#end
#SymPointsHull(ps::ElemIt{SymPoint{N, T, AT}}) where {N, T, AT<:AbstractPoint{N, T}} = SymPointsHull{N, T, AT}(collect(ps))
#vectortype(::Union{SymPointsHull{N, T, AT}, Type{SymPointsHull{N, T, AT}}}) where {N, T, AT} = AT
#similar_type(PT::Type{<:SymPointsHull}, d::FullDim{N}, ::Type{T}) where {N, T} = SymPointsHull{N, T, similar_type(vectortype(PT), d, T)}
#
#SymPointsHull{N, T, AT}(sympoints::SymPointIt, points::PointIt, lines::LineIt, rays::RayIt) where {N, T, AT} = Hull{N, T, AT}(sympoints, points, lines, rays)
#SymPointsHull{N, T, AT}(sympoints::SymPointIt, lines::LineIt, rays::RayIt) where {N, T, AT} = Hull{N, T, AT}(sympoints, AT[], lines, rays)
#
#@vecrepelem SymPointsHull SymPoint sympoints
#
## SymPoint's can be split
#removevredundancy(vrep::SymPointsHull, hrep::HRep; kws...) = removevredundancy(PointsHull(sympoints(vrep), points(vrep)), hrep; kws...)

#"""
#    vrep(sympoints::SymPointIt, points::PointIt)
#
#Creates a V-representation for the polytope equal to the convex hull of the symmetric points `sympoints` and points `points`.
#
#### Examples
#The convex hull of ``(0, -1)``, ``(0, 1)`` and ``(1/2, 1/2)`` can be created as follows:
#```julia
#vrep([SymPoint([0, 1])], [[1/2, 1/2]])
#```
#"""
#vrep(sympoints::SymPointIt, points::PointIt) = PointsHull(sympoints, points)

"""
    vrep(points::PointIt)

Creates a V-representation for the polytope equal to the convex hull of the points `points`.

### Examples
The convex hull of ``(0, 0)``, ``(0, 1)`` and ``(1/2, 1/2)`` can be created as follows using exact arithmetic
```julia
vrep([[0, 0], [0, 1], [1//2, 1//2]])
```
or as follows using floating point arithmetic
```julia
vrep([[0, 0], [0, 1], [1/2, 1/2]])
```
"""
vrep(points::PointIt) = PointsHull(points)
#sympointtype(points::ElemIt{StaticArrays.SVector{N, T}}) where {N, T} = SymPoint{N, T, StaticArrays.SVector{N, T}}
#function sympointtype(points::PointIt)
#    isempty(points) && throw(ArgumentError("Cannot create a V-representation from an empty collection of points represented by $(eltype(points)) as the dimension cannot be computed. Use StaticArrays.SVector to represent points instead"))
#    SymPoint{length(first(points)), coefficienttype(eltype(points)), eltype(points)}
#end

mutable struct PointsHull{N, T, AT} <: VPolytope{N, T}
    points::Vector{AT}
    function PointsHull{N, T, AT}(points::PointIt) where {N, T, AT}
        new{N, T, AT}(lazy_collect(points))
    end
end
PointsHull(points::ElemIt{StaticArrays.SVector{N, T}}) where {N, T} = PointsHull{N, T, StaticArrays.SVector{N, T}}(points)
function PointsHull(points::PointIt)
    isempty(points) && throw(ArgumentError("Cannot create a V-representation from an empty collection of points represented by $(eltype(points)) as the dimension cannot be computed. Use StaticArrays.SVector to represent points instead"))
    PointsHull{length(first(points)), coefficienttype(eltype(points)), eltype(points)}(points)
end
vvectortype(::Type{PointsHull{N, T, AT}}) where {N, T, AT} = AT
similar_type(PT::Type{<:PointsHull}, d::FullDim{N}, ::Type{T}) where {N, T} = PointsHull{N, T, similar_type(vvectortype(PT), d, T)}

vreptype(::Type{PointsHull{N, T, AT}}) where {N, T, AT} = Hull{N, T, AT}

@vecrepelem PointsHull Point points

"""
    vrep(lines::LineIt, rays::RayIt)

Creates a V-representation for the polyhedral cone equal to the conic hull of the lines `lines` and rays `rays`.

### Examples
```julia
vrep([Line([0, 1])], [Ray([1, 0])])
```
creates a V-representation for the halfspace ``x_1 \\ge 0``.
"""
vrep(lines::LineIt, rays::RayIt) = RaysHull(lines, rays)

"""
    vrep(rays::RayIt)

Creates a V-representation for the polyhedral cone equal to the conic hull of the rays `rays`.

### Examples
```julia
vrep([Ray([1, 0]), Ray([0, 1])])
```
creates a V-representation for positive orthant.
"""
vrep(rays::ElemIt{Ray{N, T, AT}}) where {N, T, AT} = vrep(Line{N, T, AT}[], rays)

mutable struct RaysHull{N, T, AT} <: VCone{N, T}
    lines::LinesHull{N, T, AT}
    rays::Vector{Ray{N, T, AT}}
    function RaysHull{N, T, AT}(ls::LineIt{N, T}, rs::RayIt{N, T}) where {N, T, AT}
        new{N, T, AT}(LinesHull{N, T, AT}(ls), lazy_collect(rs))
    end
end
function RaysHull(ls::ElemIt{Line{N, T, AT}}, rs::ElemIt{Ray{N, T, AT}}) where {N, T, AT}
    RaysHull{N, T, AT}(ls, rs)
end
vvectortype(::Type{RaysHull{N, T, AT}}) where {N, T, AT} = AT
similar_type(PT::Type{<:RaysHull}, d::FullDim{N}, ::Type{T}) where {N, T} = RaysHull{N, T, similar_type(vvectortype(PT), d, T)}

@vecrepelem RaysHull Ray rays
@subrepelem RaysHull Line lines

vreptype(::Type{RaysHull{N, T, AT}}) where {N, T, AT} = Hull{N, T, AT}

"""
    vrep(points::PointIt, lines::LineIt, rays::RayIt)

Creates a V-representation for the polyhedron equal to the minkowski sum of the convex hull of `points` with the conic hull of `lines` and `rays`.
"""
vrep(points::PointIt, lines::LineIt, rays::RayIt) = Hull(points, lines, rays)

vrep(points::ElemIt{AT}, lines::ElemIt{Line{N, T, AT}}) where {N, T, AT} = Hull(points, lines, Ray{N, T, AT}[])

mutable struct Hull{N, T, AT} <: VRepresentation{N, T}
    points::PointsHull{N, T, AT}
    rays::RaysHull{N, T, AT}
    function Hull{N, T, AT}(vits::VIt{N, T}...) where {N, T, AT}
        points, lines, rays = fillvits(FullDim{N}(), vits...)
        # If points is empty and its eltype is Vector, by doing PointsHull(points), we loose the dimension information
        # If it is non-empty, we still have something type unstable
        new{N, T, AT}(PointsHull{N, T, AT}(points), RaysHull(lines, rays))
    end
end
function Hull(points::ElemIt{AT}, lines::ElemIt{Line{N, T, AT}}, rays::ElemIt{Ray{N, T, AT}}) where {N, T, AT}
    Hull{N, T, AT}(points, lines, rays)
end
vvectortype(::Type{Hull{N, T, AT}}) where {N, T, AT} = AT
similar_type(PT::Type{<:Hull}, d::FullDim{N}, ::Type{T}) where {N, T} = Hull{N, T, similar_type(vvectortype(PT), d, T)}

Hull(v::VRepresentation{N, T}) where {N, T} = Hull{N, T}(v)
Hull{N, T}(v::VRepresentation{N}) where {N, T} = Hull{N, T, similar_type(vvectortype(typeof(v)), T)}(v)

@subrepelem Hull Point points
@subrepelem Hull Line rays
@subrepelem Hull Ray rays

fulltype(::Type{<:Union{Hull{N, T, AT}, PointsHull{N, T, AT}, LinesHull{N, T, AT}, RaysHull{N, T, AT}}}) where {N, T, AT} = Hull{N, T, AT}

dualtype(::Type{<:Intersection{N, T}}, ::Type{AT}) where {N, T, AT} = Hull{N, T, AT}
dualtype(::Type{<:Hull{N, T}}, ::Type{AT}) where {N, T, AT} = Intersection{N, T, AT}
const AnyIntersection{N, T, AT} = Union{Intersection{N, T, AT}, HyperPlanesIntersection{N, T, AT}}
function dualfullspace(h::Union{AnyIntersection, Type{<:AnyIntersection}}, d::FullDim{N}, ::Type{T}, ::Type{AT}) where {N, T, AT}
    Hull{N, T, AT}([origin(AT, d)],
                   Line{N, T, AT}.(basis.(AT, d, 1:N)),
                   Ray{N, T, AT}[])
end


text:
using Tilings
using Test

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


text:
# Julia wrapper for header: /usr/local/include/libavcodec/dv_profile.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

export
    av_dv_frame_profile,
    av_dv_codec_profile,
    av_dv_codec_profile2

function av_dv_frame_profile(sys,frame,buf_size::Integer)
    ccall((:av_dv_frame_profile,libavcodec),Ptr{AVDVProfile},(Ptr{AVDVProfile},Ptr{UInt8},UInt32),sys,frame,buf_size)
end

function av_dv_codec_profile(width::Integer,height::Integer,pix_fmt::AVPixelFormat)
    ccall((:av_dv_codec_profile,libavcodec),Ptr{AVDVProfile},(Cint,Cint,AVPixelFormat),width,height,pix_fmt)
end

function av_dv_codec_profile2(width::Integer,height::Integer,pix_fmt::AVPixelFormat,frame_rate::AVRational)
    ccall((:av_dv_codec_profile2,libavcodec),Ptr{AVDVProfile},(Cint,Cint,AVPixelFormat,AVRational),width,height,pix_fmt,frame_rate)
end

max_stars_repo_name: asafasban/AAVideoIO

max_issues_repo_name: asafasban/AAVideoIO

max_forks_repo_name: asafasban/AAVideoIO


text:
function kerneldensity(xdata::RealVector; xeval::RealVector=xdata, lb::Real=-Inf, ub::Real=Inf, kernel::Function=gaussiankernel, h::Real=-Inf)

    xdata, xeval, kernel = boundit(xdata, xeval, kernel, lb, ub)
    if h <= 0
        h = bwlscv(xdata, kernel)
    end
    n = length(xdata)
    w = zeros(n)
    den = zeros(length(xeval))
    for i in 1:length(xeval)
        kernel(xeval[i], xdata, h, w, n)
        den[i] = mean(w)
    end
    return den
end

function kerneldensity(xdata::RealMatrix; xeval::RealMatrix=xdata,
    kernel::Vector=[gaussiankernel for i in 1:size(xdata)[2]], h::RealVector=-Inf .* ones(size(xdata, 2)))

    if any(h .<= 0)
        h = bwlcv(xdata, kernel)
        warn("The user are responsible for giving the bandwidth! The defaults may not work well.")
    end
    m, p=size(xeval)
    n, p1 = size(xdata)
    if length(h) != p || p1 != p
        error("xeval and h should have same dimension as xdata")
    end
    den=zeros(m)
    for i=1:m
        wtmp = zeros(n)
        w = ones(n)
        for j=1:p
            kernel[j](xeval[i, j], xdata[:, j], h[j], wtmp, n)
            for k in 1:n
                w[k] = w[k] * wtmp[k]
            end
        end
        den[i] = mean(w)
    end
    den
end

kde=kerneldensity


text:
function DampingKoeff(CG,Param)
K=zeros(CG.NumG,Param.Grid.nz);
H = Param.H
StrideDamp = Param.StrideDamp
Relax = Param.Relax
nz = Param.Grid.nz
z = Param.Grid.z
H = Param.H
for iz=nz-1:-1:1
  zLoc=z[iz+1];
  if zLoc>=H-StrideDamp
    K[:,iz] .= -Relax*
      sin(0.5*pi*(1.0 - (H - zLoc)/StrideDamp))^2;
  else
    break
  end
end
return K
end


text:
"""
    BFloat16(x::Float32)

Magic number is used to round the result rather than truncating it
https://stackoverflow.com/questions/55253233/convert-fp32-to-bfloat16-in-c
"""
function BFloat16(x::Float32)
    f = reinterpret(UInt32, x * 1.001957f0) # Magic number
    h = (f >> 16) % UInt16
    reinterpret(BFloat16, h)
end

BFloat16(x::BFloat16) = x
BFloat16(x::Float16) = BFloat16(Float32(x))
BFloat16(x::Float64) = BFloat16(Float32(x))

BFloat16(x::Integer) = BFloat16(Float32(x))
BFloat16(x::UInt16) = reinterpret(BFloat16, x) # Specifically interpret UInt16 by its bit pattern

BFloat16(x::Real) = BFloat16(Float32(x))
BFloat16(x::Rational) = BFloat16(Float32(x))
BFloat16(x::Number) = BFloat16(Float32(x))

## BFloat16 Promotion rules
for t in (Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UInt128)
    @eval promote_rule(::Type{BFloat16}, ::Type{$t}) = BFloat16
end
promote_rule(::Type{BFloat16}, ::Type{Bool}) = BFloat16
promote_rule(::Type{BFloat16}, ::Type{Float16}) = Float32
promote_rule(::Type{BFloat16}, ::Type{Float32}) = Float32
promote_rule(::Type{BFloat16}, ::Type{Float64}) = Float64

widen(::Type{BFloat16}) = Float32

# Interpretations
reinterpret(::Type{Unsigned}, x::BFloat16) = reinterpret(UInt16, x)
reinterpret(::Type{Signed}, x::BFloat16) = reinterpret(Int16, x)

## Conversions to other types (BFloat16 -> T)
function Float32(x::BFloat16)
    ival::UInt32 = reinterpret(uinttype(BFloat16), x)
    return reinterpret(Float32, (ival % UInt32) << 16)
end
Float16(x::BFloat16) = Float16(Float32(x))
Float64(x::BFloat16) = Float64(Float32(x))

# BFloat16 -> Integer
(::Type{T})(x::BFloat16) where {T<:Integer} = T(Float32(x))

Bool(x::BFloat16) = x==0 ? false : x==1 ? true : throw(InexactError(:Bool, Bool, x))


text:
"""
Read any of the citation network datasets “Cora”, “CiteSeer” and “PubMed”
from the “Revisiting Semi-Supervised Learning with Graph Embeddings” paper.
Nodes represent documents and edges represent citation links.

Data collected from
https://github.com/kimiyoung/planetoid/raw/master/data
"""
function read_planetoid_data(DEPNAME; dir=nothing, reverse_edges=true)
    name = lowercase(DEPNAME)

    x  = read_planetoid_file(DEPNAME, "ind.$(name).x", dir)
    y  = read_planetoid_file(DEPNAME, "ind.$(name).y", dir)
    allx  = read_planetoid_file(DEPNAME, "ind.$(name).allx", dir)
    ally  = read_planetoid_file(DEPNAME, "ind.$(name).ally", dir)
    tx  = read_planetoid_file(DEPNAME, "ind.$(name).tx", dir)
    ty  = read_planetoid_file(DEPNAME, "ind.$(name).ty", dir)
    graph = read_planetoid_file(DEPNAME, "ind.$(name).graph", dir)
    test_index = read_planetoid_file(DEPNAME, "ind.$(name).test.index", dir)

    ntrain = size(x, 2)
    train_index = 1:ntrain
    val_index = ntrain+1:ntrain+500
    sorted_test_index = sort(test_index)

    if name == "citeseer"
        # There are some isolated nodes in the Citeseer graph, resulting in
        # none consecutive test indices. We need to identify them and add them
        # as zero vectors to `tx` and `ty`.
        len_test_indices = (maximum(test_index) - minimum(test_index)) + 1

        tx_ext = zeros(size(tx,1), len_test_indices)
        tx_ext[:, sorted_test_index .- minimum(test_index) .+ 1] .= tx
        ty_ext = zeros(len_test_indices)
        ty_ext[sorted_test_index .- minimum(test_index) .+ 1] = ty

        tx, ty = tx_ext, ty_ext
    end
    x = hcat(allx, tx)
    y = vcat(ally, ty)
    x[:, test_index] = x[:, sorted_test_index]
    y[test_index] = y[sorted_test_index]
    test_index = size(allx,2)+1:size(x,2)

    num_nodes = size(x, 2)
    adj_list = [Int[] for i=1:num_nodes]
    for (i, neigs) in pairs(graph) # graph is dictionay representing the adjacency list
        neigs = unique(neigs) # remove duplicated edges
        neigs = filter(x -> x!=i, neigs)# remove self-loops
        append!(adj_list[i+1], neigs .+ 1) # convert to 1-indexed
    end
    if reverse_edges
        for (i, neigs) in enumerate(adj_list)
            for j in neigs
                i ∉ adj_list[j] && push!(adj_list[j], i)
            end
        end
    end

    return (; node_features = x,
              node_labels = y,
              adjacency_list = adj_list,
              train_indices = train_index,
              val_indices = val_index,
              test_indices = test_index,
              num_classes = length(unique(y)),
              num_nodes = num_nodes,
              num_edges = sum(length.(adj_list)),
              directed = reverse_edges != true)
end

function read_planetoid_file(DEPNAME, name, dir)
    filename = datafile(DEPNAME, name, dir)
    if endswith(name, "test.index")
        out = 1 .+ vec(readdlm(filename, Int))
    else
        out = py"pyread_planetoid_file"(filename, name)
        if out isa Matrix
            out = collect(out')
        end
    end
    if endswith(name, "y")
        out = map(y->y[1], argmax(out, dims=1)) |> vec
    end
    return out
end