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

# Functions convertible to a AffineDecisionFunction
const ScalarAffineLike{T} = Union{MOIU.ScalarAffineLike{T}, SingleDecision, AffineDecisionFunction{T}}
const ScalarAffineDecisionLike{T} = Union{SingleDecision, AffineDecisionFunction{T}}

# Functions convertible to a QuadraticDecisionFunction
const ScalarQuadraticLike{T} = Union{MOIU.ScalarQuadraticLike{T}, SingleDecision, AffineDecisionFunction{T}, QuadraticDecisionFunction{T}}
const ScalarQuadraticDecisionLike{T} = Union{SingleDecision, AffineDecisionFunction{T}, QuadraticDecisionFunction{T}}

const TypedScalarDecisionLike{T} = Union{AffineDecisionFunction{T}, QuadraticDecisionFunction{T}}
const ScalarDecisionLike{T} = Union{SingleDecision, TypedScalarDecisionLike{T}}
const MixedTypedScalarLike{T} = Union{MOIU.TypedScalarLike{T}, TypedScalarDecisionLike{T}}
const MixedScalarLike{T} = Union{MOIU.ScalarLike{T}, ScalarDecisionLike{T}}

# Functions convertible to a VectorAffineDecisionFunction
const VectorAffineLike{T} = Union{MOIU.VectorAffineLike{T}, VectorOfDecisions, VectorAffineDecisionFunction{T}}
const VectorAffineDecisionLike{T} = Union{VectorOfDecisions, VectorAffineDecisionFunction{T}}

const TypedVectorDecisionLike{T} = Union{VectorAffineDecisionFunction{T}}
const VectorDecisionLike{T} = Union{VectorOfDecisions, VectorAffineDecisionFunction{T}}
const MixedVectorLike{T} = Union{MOIU.VectorLike{T}, VectorDecisionLike{T}}

const TypedDecisionLike{T} = Union{TypedScalarDecisionLike{T}, TypedVectorDecisionLike{T}}
const AffineLike{T} = Union{ScalarAffineLike{T}, VectorAffineLike{T}}
const AffineDecisionLike{T} = Union{ScalarAffineDecisionLike{T}, VectorAffineDecisionLike{T}}
const DecisionLike{T} = Union{ScalarDecisionLike{T}, VectorDecisionLike{T}}

# +/- #
# ========================== #
function MOIU.promote_operation(::typeof(-), ::Type{T},
                                ::Type{<:ScalarAffineDecisionLike{T}}) where T
    return AffineDecisionFunction{T}
end
function MOIU.promote_operation(::typeof(-), ::Type{T},
                                ::Type{<:ScalarQuadraticDecisionLike{T}}) where T
    return QuadraticDecisionFunction{T}
end
function MOIU.promote_operation(::typeof(-), ::Type{T},
                                ::Type{QuadraticDecisionFunction{T}}) where T
    return QuadraticDecisionFunction{T}
end

function MOIU.promote_operation(::Union{typeof(+), typeof(-)}, ::Type{T},
                                ::Type{<:ScalarAffineDecisionLike{T}},
                                ::Type{<:ScalarAffineLike{T}}) where T
    return AffineDecisionFunction{T}
end
function MOIU.promote_operation(::Union{typeof(+), typeof(-)}, ::Type{T},
                                ::Type{<:MOIU.ScalarAffineLike{T}},
                                ::Type{<:ScalarAffineDecisionLike{T}}) where T
    return AffineDecisionFunction{T}
end

function MOIU.promote_operation(::Union{typeof(+), typeof(-)}, ::Type{T},
                                ::Type{<:ScalarQuadraticDecisionLike{T}},
                                ::Type{<:ScalarQuadraticLike{T}}) where T
    return QuadraticDecisionFunction{T}
end
function MOIU.promote_operation(::Union{typeof(+), typeof(-)}, ::Type{T},
                                ::Type{<:MOIU.ScalarQuadraticLike{T}},
                                ::Type{<:ScalarQuadraticDecisionLike{T}}) where T
    return QuadraticDecisionFunction{T}
end

# Unary -
function MOIU.operate!(op::typeof(-), ::Type{T},
                       f::Union{AffineDecisionFunction{T},
                                QuadraticDecisionFunction{T}}) where T
    return MA.mutable_operate!(-, f)
end

# AffineDecisionFunction +/-! ...
function MOIU.operate!(op::Union{typeof(+), typeof(-)}, ::Type{T},
                       f::AffineDecisionFunction{T},
                       g::ScalarAffineLike{T}) where T
    return MA.mutable_operate!(op, f, g)
end
function MOIU.operate!(op::Union{typeof(+), typeof(-)}, ::Type{T},
                       f::SingleDecision,
                       g::ScalarQuadraticLike{T}) where T
    return MOIU.operate(op, T, f, g)
end
function MOIU.operate!(op::Union{typeof(+), typeof(-)}, ::Type{T},
                       f::AffineDecisionFunction{T},
                       g::MOI.ScalarQuadraticFunction{T}) where T
    return MOIU.operate(op, T, f, g)
end
function MOIU.operate!(op::Union{typeof(+), typeof(-)}, ::Type{T},
                       f::AffineDecisionFunction{T},
                       g::QuadraticDecisionFunction{T}) where T
    return MOIU.operate(op, T, f, g)
end
# QuadraticDecisionFunction +/-! ...
function MOIU.operate!(op::Union{typeof(+), typeof(-)}, ::Type{T},
                       f::QuadraticDecisionFunction{T},
                       g::ScalarQuadraticLike{T}) where T
    return MA.mutable_operate!(op, f, g)
end

# Scalar number +/- ...
function MOIU.operate(op::typeof(+), ::Type{T}, α::T, f::ScalarDecisionLike{T}) where T
    return MOIU.operate(op, T, f, α)
end
function MOIU.operate(op::typeof(-), ::Type{T}, α::T, f::ScalarDecisionLike{T}) where T
    return MOIU.operate!(+, T, MOIU.operate(-, T, f), α)
end

# SingleDecision +/- ...
function MOIU.operate(::typeof(-), ::Type{T}, f::SingleDecision) where T
    return AffineDecisionFunction{T}(convert(MOI.ScalarAffineFunction{T}, zero(T)),
                                     MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(-one(T), f.decision)], zero(T)))
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::SingleDecision, α::T) where T
    return AffineDecisionFunction{T}(convert(MOI.ScalarAffineFunction{T}, op(α)),
                                     MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(one(T), f.decision)], zero(T)))
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::SingleDecision,
                      g::MOI.SingleVariable) where T
    return AffineDecisionFunction{T}(MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(one(T), g.variable)], zero(T)),
                                     MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(one(T), f.decision)], zero(T)))
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::SingleDecision,
                      g::SingleDecision) where T
    return AffineDecisionFunction{T}(convert(MOI.ScalarAffineFunction{T}, zero(T)),
                                     MOI.ScalarAffineFunction(
                                         [MOI.ScalarAffineTerm(one(T), f.decision),
                                          MOI.ScalarAffineTerm(op(one(T)), g.decision)], zero(T)))
end
function MOIU.operate(op::typeof(+), ::Type{T},
                      f::SingleDecision,
                      g::MOI.ScalarAffineFunction{T}) where T
    return MOIU.operate(op, T, convert(AffineDecisionFunction{T}, g), f)
end
function MOIU.operate(op::typeof(-), ::Type{T},
                      f::SingleDecision,
                      g::MOI.ScalarAffineFunction{T}) where T
    return MOIU.operate!(+, T, MOIU.operate(-, T, convert(AffineDecisionFunction{T}, g)), f)
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::SingleDecision,
                      g::AffineDecisionFunction{T}) where T
    return MOIU.operate(op, T, convert(AffineDecisionFunction{T}, f), g)
end
function MOIU.operate(op::typeof(+), ::Type{T},
                      f::SingleDecision,
                      g::MOI.ScalarQuadraticFunction{T}) where T
    return MOIU.operate(op, T, convert(QuadraticDecisionFunction{T}, g), f)
end
function MOIU.operate(op::typeof(-), ::Type{T},
                      f::SingleDecision,
                      g::MOI.ScalarQuadraticFunction{T}) where T
    return MOIU.operate!(+, T, MOIU.operate(-, T, convert(QuadraticDecisionFunction{T}, g)), f)
end
function MOIU.operate(op::typeof(+), ::Type{T},
                      f::SingleDecision,
                      g::QuadraticDecisionFunction{T}) where T
    return MOIU.operate!(op, T, copy(g), f)
end
function MOIU.operate(op::typeof(-), ::Type{T},
                      f::SingleDecision,
                      g::QuadraticDecisionFunction{T}) where T
    return MOIU.operate!(+, T, operate(-, T, g), f)
end

# SingleVariable +- SingleDecision
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::MOI.SingleVariable,
                      g::SingleDecision) where T
    return MOIU.operate(op, T, g, f)
end

# Scalar Affine +/- ...
function MOIU.operate(op::Union{typeof(-)}, ::Type{T},
                      f::AffineDecisionFunction{T}) where T
    return AffineDecisionFunction(
        MOIU.operate(op, T, f.variable_part),
        MOIU.operate(op, T, f.decision_part))
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::AffineDecisionFunction{T},
                      g::ScalarAffineLike{T}) where T
    return MOIU.operate!(op, T, copy(f), g)
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::AffineDecisionFunction{T},
                      g::QuadraticDecisionFunction{T}) where T
    return QuadraticDecisionFunction(
            MOIU.operate(op, T, f.variable_part, g.variable_part),
            MOIU.operate(op, T, f.decision_part, g.decision_part),
            copy(g.cross_terms))
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::AffineDecisionFunction{T},
                      g::ScalarQuadraticLike{T}) where T
    return MOIU.operate(op, T, f, convert(QuadraticDecisionFunction{T}, g))
end

# Scalar Quadratic +/- ...
function MOIU.operate(op::Union{typeof(-)}, ::Type{T},
                      f::QuadraticDecisionFunction{T}) where T
    return QuadraticDecisionFunction(
            MOIU.operate(op, T, f.variable_part),
            MOIU.operate(op, T, f.decision_part),
            MOIU.operate(op, T, f.cross_terms))
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::QuadraticDecisionFunction{T},
                      g::ScalarQuadraticLike{T}) where T
    MOIU.operate!(op, T, copy(f), g)
end

# Base overloads
function Base.:+(arg::ScalarDecisionLike{T}, args::MixedScalarLike{T}...) where T
    return MOIU.operate(+, T, arg, args...)
end
function Base.:+(arg::MOIU.ScalarLike{T}, args::MixedScalarLike{T}...) where T
    return MOIU.operate(+, T, convert(AffineDecisionFunction{T}, arg), args...)
end
function Base.:+(α::T, arg::TypedScalarDecisionLike{T}, args::MixedScalarLike{T}...) where T
    return MOIU.operate(+, T, α, arg, args...)
end
function Base.:+(α::Number, f::SingleDecision)
    return MOIU.operate(+, typeof(α), α, f)
end
function Base.:+(f::TypedScalarDecisionLike{T}, α::T) where T
    return MOIU.operate(+, T, f, α)
end
function Base.:+(f::SingleDecision, α::Number)
    return MOIU.operate(+, typeof(α), f, α)
end
function Base.:-(arg::ScalarDecisionLike{T}, args::MixedScalarLike{T}...) where T
    return MOIU.operate(-, T, arg, args...)
end
function Base.:-(arg::MOIU.ScalarLike{T}, args::MixedScalarLike{T}...) where T
    return MOIU.operate(-, T, convert(AffineDecisionFunction{T}, arg), args...)
end
function Base.:-(f::TypedScalarDecisionLike{T}, α::T) where T
    return MOIU.operate(-, T, f, α)
end
function Base.:-(f::SingleDecision, α::Number)
    return MOIU.operate(-, typeof(α), f, α)
end
function Base.:-(α::T, f::TypedScalarDecisionLike{T}) where T
    return MOIU.operate(-, T, α, f)
end
function Base.:-(α::Number, f::SingleDecision)
    return MOIU.operate(-, typeof(α), α, f)
end

# VectorDecisionFunctions +/-
# ========================== #
function MOIU.promote_operation(::typeof(-), ::Type{T},
                                ::Type{<:VectorAffineDecisionLike{T}}) where T
    return VectorAffineDecisionFunction{T}
end

function MOIU.promote_operation(::Union{typeof(+), typeof(-)}, ::Type{T},
                                ::Type{<:VectorAffineDecisionLike{T}},
                                ::Type{<:VectorAffineLike{T}}) where T
    return VectorAffineDecisionFunction{T}
end
function MOIU.promote_operation(::Union{typeof(+), typeof(-)}, ::Type{T},
                                ::Type{<:MOIU.VectorAffineLike{T}},
                                ::Type{<:VectorAffineDecisionLike}) where T
    return VectorAffineDecisionFunction{T}
end

# Vector Decision +/- ...
function MOIU.operate!(op::Union{typeof(+), typeof(-)}, ::Type{T},
                       f::VectorOfDecisions,
                       g::VectorAffineDecisionLike{T}) where T
    return operate(op, T, f, g)
end
# VectorAffineDecision +/-! ...
function MOIU.operate_output_index!(
    op::Union{typeof(+), typeof(-)}, ::Type{T},
    output_index::Integer,
    f::VectorAffineDecisionFunction{T}, α::T) where T
    MOIU.operate_output_index!(op, T, output_index, f.variable_part, α)
    return f
end
function MOIU.operate!(op::Union{typeof(+), typeof(-)}, ::Type{T},
                       f::VectorAffineDecisionFunction{T},
                       g::Vector{T}) where T
    MOIU.operate!(op, T, f.variable_part, g)
    return f
end
function MOIU.operate_output_index!(
    op::Union{typeof(+), typeof(-)}, ::Type{T},
    output_index::Integer,
    f::VectorAffineDecisionFunction{T},
    g::MOI.SingleVariable) where T
    MOIU.operate_output_index!(op, T, output_index, f.variable_part, g)
    return f
end
function MOIU.operate_output_index!(
    op::Union{typeof(+), typeof(-)}, ::Type{T},
    output_index::Integer,
    f::VectorAffineDecisionFunction{T},
    g::SingleDecision) where T
    push!(f.decision_part.terms, MOI.VectorAffineTerm(
        output_index, MOI.ScalarAffineTerm(op(one(T)), g.decision)))
    return f
end
function MOIU.operate!(op::Union{typeof(+), typeof(-)}, ::Type{T},
                       f::VectorAffineDecisionFunction{T},
                       g::MOI.VectorOfVariables) where T
    MOIU.operate!(op, T, f.variable_part, g)
    return f
end
function MOIU.operate!(op::Union{typeof(+), typeof(-)}, ::Type{T},
                       f::VectorAffineDecisionFunction{T},
                       g::VectorOfDecisions) where T
    d = MOI.output_dimension(g)
    @assert MOI.output_dimension(f.decision_part) == d
    append!(f.decision_part.terms, MOI.VectorAffineTerm.(
        collect(1:d),
        MOI.ScalarAffineTerm.(op(one(T)), g.decisions)))
    return f
end
function MOIU.operate_output_index!(
    op::Union{typeof(+), typeof(-)}, ::Type{T},
    output_index::Integer,
    f::VectorAffineDecisionFunction{T},
    g::MOI.ScalarAffineFunction{T}) where T
    MOIU.operate_output_index!(op, T, output_index, f.variable_part, g)
    return f
end
function MOIU.operate_output_index!(
    op::Union{typeof(+), typeof(-)}, ::Type{T},
    output_index::Integer,
    f::VectorAffineDecisionFunction{T},
    g::AffineDecisionFunction{T}) where T
    MOIU.operate_output_index!(op, T, output_index, f.variable_part, g.variable_part)
    MOIU.operate_output_index!(op, T, output_index, f.decision_part, g.decision_part)
    return f
end
function MOIU.operate!(op::Union{typeof(+), typeof(-)}, ::Type{T},
                       f::VectorAffineDecisionFunction{T},
                       g::VectorAffineDecisionFunction{T}) where T
    MOIU.operate!(op, T, f.variable_part, g.variable_part)
    MOIU.operate!(op, T, f.decision_part, g.decision_part)
    return f
end

function MOIU.operate(op::typeof(-), ::Type{T}, f::VectorOfDecisions) where T
    d = MOI.output_dimension(f)
    return VectorAffineDecisionFunction{T}(
        MOI.VectorAffineFunction(MOI.VectorAffineTerm{T}[], zeros(T, d)),
        MOI.VectorAffineFunction(MOI.VectorAffineTerm.(
            collect(1:d),
            MOI.ScalarAffineTerm.(-one(T), f.decisions)),
                                 fill(zero(T),d)))
end

# VectorDecision number +/- ...
function MOIU.operate(op::typeof(+), ::Type{T}, α::Vector{T}, f::Union{VectorOfDecisions, VectorAffineDecisionFunction{T}}) where T
    return MOIU.operate(op, T, f, α)
end
function MOIU.operate(op::typeof(-), ::Type{T}, α::Vector{T}, f::Union{VectorOfDecisions, VectorAffineDecisionFunction{T}}) where T
    return MOIU.operate!(+, T, operate(-, T, f), α)
end

# Vector Decisions +/- ...
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::VectorOfDecisions, α::Vector{T}) where T
    d = MOI.output_dimension(f)
    @assert length(α) == d
    return VectorAffineDecisionFunction{T}(
        MOI.VectorAffineFunction(MOI.VectorAffineTerm{T}[], op.(α)),
        MOI.VectorAffineFunction(MOI.VectorAffineTerm.(
            collect(1:d),
            MOI.ScalarAffineTerm.(one(T), f.decisions)),
                                 zeros(T, d)))
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::VectorOfDecisions,
                      g::MOI.VectorOfVariables) where T
    d = MOI.output_dimension(f)
    @assert MOI.output_dimension(g) == d
    return VectorAffineDecisionFunction{T}(
        MOI.VectorAffineFunction(MOI.VectorAffineTerm.(
            collect(1:d),
            MOI.ScalarAffineTerm.(op(one(T)), g.variables)),
                                 zeros(T, d)),
        MOI.VectorAffineFunction(MOI.VectorAffineTerm.(
            collect(1:d),
            MOI.ScalarAffineTerm.(one(T), f.decisions)),
                                 zeros(T, d)))
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::VectorOfDecisions,
                      g::VectorOfDecisions) where T
    d = MOI.output_dimension(f)
    @assert MOI.output_dimension(g) == d
    return VectorAffineDecisionFunction{T}(
        MOI.VectorAffineFunction(MOI.VectorAffineTerm{T}[], zeros(T, d)),
        MOI.VectorAffineFunction(
            vcat(
                MOI.VectorAffineTerm.(
                    collect(1:d),
                    MOI.ScalarAffineTerm.(one(T), f.decisions)),
                MOI.VectorAffineTerm.(
                    collect(1:d),
                    MOI.ScalarAffineTerm.(op(one(T)), g.decisions))),
            zeros(T, d)))
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::VectorOfDecisions,
                      g::MOI.VectorAffineFunction{T}) where T
    d = MOI.output_dimension(f)
    @assert MOI.output_dimension(g) == d
    return VectorAffineDecisionFunction{T}(
        MOIU.operate(op, T, g),
        MOI.VectorAffineFunction(
            MOI.VectorAffineTerm.(
                collect(1:d),
                MOI.ScalarAffineTerm.(one(T), f.decisions)),
            zeros(T, d)))
end

# Vector Variables +- Vector Decisions
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::MOI.VectorOfVariables,
                      g::VectorOfDecisions) where T
    return MOIU.operate(op, T, convert(VectorAffineDecisionFunction{T}, f), g)
end

# Vector Decisions +- VectorAffineFunction
function MOIU.operate(op::typeof(+), ::Type{T},
                      f::VectorOfDecisions,
                      g::VectorAffineDecisionFunction{T}) where T
    MOIU.operate!(op, T, convert(VectorAffineDecisionFunction{T}, f), g)
end
function MOIU.operate(op::typeof(-), ::Type{T},
                      f::VectorOfDecisions,
                      g::VectorAffineDecisionFunction{T}) where T
    MOIU.operate!(op, T, convert(VectorAffineDecisionFunction{T}, f), g)
end

# Vector Affine +/- ...
function MOIU.operate(op::Union{typeof(-)}, ::Type{T},
                      f::VectorAffineDecisionFunction{T}) where T
    return VectorAffineDecisionFunction(
        MOIU.operate(op, T, f.variable_part),
        MOIU.operate(op, T, f.decision_part))
end
function MOIU.operate(op::Union{typeof(+), typeof(-)}, ::Type{T},
                      f::VectorAffineDecisionFunction{T},
                      g::VectorAffineLike{T}) where T
    return MOIU.operate!(op, T, copy(f), g)
end

function Base.:+(arg::VectorDecisionLike{T}, args::MixedVectorLike{T}...) where T
    return MOIU.operate(+, T, arg, args...)
end
function Base.:+(arg::MOIU.VectorLike{T}, args::MixedVectorLike{T}...) where T
    return MOIU.operate(+, T, convert(VectorAffineDecisionFunction{T}, arg), args...)
end
function Base.:+(α::Vector{T}, f::VectorDecisionLike{T}, g::MixedVectorLike{T}...) where T
    return MOIU.operate(+, T, α, f, g...)
end
function Base.:+(f::VectorDecisionLike{T}, α::Vector{T}) where T
    return MOIU.operate(+, T, f, α)
end
function Base.:-(arg::VectorDecisionLike{T}, args::MixedVectorLike{T}...) where T
    return MOIU.operate(-, T, arg, args...)
end
function Base.:-(arg::MOIU.VectorLike{T}, args::MixedVectorLike{T}...) where T
    return MOIU.operate(-, T, convert(VectorAffineDecisionFunction{T}, arg), args...)
end
function Base.:-(f::VectorDecisionLike{T}, α::Vector{T}) where T
    return MOIU.operate(-, T, f, α)
end
function Base.:-(α::Vector{T}, f::VectorDecisionLike{T}) where T
    return MOIU.operate(-, T, α, f)
end

# * #
# ========================== #
function MOIU.promote_operation(::typeof(*), ::Type{T}, ::Type{T},
                                ::Type{<:ScalarAffineDecisionLike{T}}) where T
    return AffineDecisionFunction{T}
end
function MOIU.promote_operation(::typeof(*), ::Type{T},
                                ::Type{<:ScalarAffineDecisionLike{T}},
                                ::Type{T}) where T
    return AffineDecisionFunction{T}
end
function MOIU.promote_operation(::typeof(*), ::Type{T}, ::Type{T},
                                ::Type{QuadraticDecisionFunction{T}}) where T
    return QuadraticDecisionFunction{T}
end
function MOIU.promote_operation(::typeof(*), ::Type{T},
                                ::Type{QuadraticDecisionFunction{T}},
                                ::Type{T}) where T
    return QuadraticDecisionFunction{T}
end
function MOIU.promote_operation(::typeof(*), ::Type{T},
                                ::Type{<:ScalarAffineDecisionLike{T}},
                                ::Type{<:ScalarAffineLike{T}}) where T
    return QuadraticDecisionFunction{T}
end
function MOIU.promote_operation(::typeof(*), ::Type{T},
                                ::Type{<:MOIU.ScalarAffineLike{T}},
                                ::Type{<:ScalarAffineDecisionLike{T}}) where T
    return QuadraticDecisionFunction{T}
end

function MOIU.operate!(::typeof(*), ::Type{T}, f::SingleDecision, α::T) where T
    return MOIU.operate(*, T, α, f)
end
function MOIU.operate(::typeof(*), ::Type{T}, α::T, f::SingleDecision) where T
    return AffineDecisionFunction{T}(convert(MOIU.ScalarAffineLike{T}, zero(T)),
                                     MOI.ScalarAffineFunction{T}([MOI.ScalarAffineTerm(α, f.decision)], zero(T)))
end
function MOIU.operate(::typeof(*), ::Type{T}, α::T, f::VectorOfDecisions) where T
    d = MOI.output_dimension(f)
    return VectorAffineDecisionFunction{T}(
        MOI.VectorAffineFunction(MOI.VectorAffineTerm{T}[], zeros(T, d)),
        MOI.VectorAffineFunction(
            [MOI.VectorAffineTerm(i, MOI.ScalarAffineTerm(α, f.decisions[i]))
             for i in eachindex(f.decisions)], zeros(T, MOI.output_dimension(f))))
end
function MOIU.operate(::typeof(*), ::Type{T}, f::Union{SingleDecision, VectorOfDecisions}, α::T) where T
    return MOIU.operate(*, T, α, f)
end

function MOIU.operate!(::typeof(*), ::Type{T},
                       f::AffineDecisionFunction{T}, α::T) where T<:Number
    MOIU.operate!(*, T, f.variable_part, α)
    MOIU.operate!(*, T, f.decision_part, α)
    return f
end
function MOIU.operate!(::typeof(*), ::Type{T},
                       f::QuadraticDecisionFunction{T}, α::T) where T<:Number
    MOIU.operate!(*, T, f.variable_part, α)
    MOIU.operate!(*, T, f.decision_part, α)
    MOIU.operate!(*, T, f.cross_terms, α)
    return f
end

function MOIU.operate!(::typeof(*), ::Type{T},
                       f::VectorAffineDecisionFunction{T}, α::T) where T
    MOIU.operate!(*, T, f.variable_part, α)
    MOIU.operate!(*, T, f.decision_part, α)
    return f
end

function MOIU.operate(::typeof(*), ::Type{T}, α::T, f::TypedDecisionLike{T}) where T
    return MOIU.operate!(*, T, copy(f), α)
end

function MOIU.operate(::typeof(*), ::Type{T}, f::SingleDecision,
                      g::MOI.SingleVariable) where T
    return QuadraticDecisionFunction(
        convert(MOI.ScalarQuadraticFunction{T}, zero(T)),
        convert(MOI.ScalarQuadraticFunction{T}, zero(T)),
        MOI.ScalarQuadraticFunction{T}(
            MOI.ScalarAffineTerm{T}[],
            [MOI.ScalarQuadraticTerm(one(T), f.decision, g.variable)],
            zero(T)))
end
function MOIU.operate(::typeof(*), ::Type{T}, f::SingleDecision,
                      g::SingleDecision) where T
    return QuadraticDecisionFunction(
        convert(MOI.ScalarQuadraticFunction{T}, zero(T)),
        MOI.ScalarQuadraticFunction(
            MOI.ScalarAffineTerm{T}[],
            [MOI.ScalarQuadraticTerm(f.decision == g.decision ? 2one(T) : one(T),
                                     f.decision, g.decision)],
            zero(T)),
        convert(MOI.ScalarQuadraticFunction{T}, zero(T)))
end

function MOIU.operate(::typeof(*), ::Type{T}, f::MOI.SingleVariable, g::SingleDecision) where T
    return MOIU.operate(*, T, g, f)
end

function MOIU.operate(::typeof(*), ::Type{T}, f::AffineDecisionFunction{T},
                      g::AffineDecisionFunction{T}) where T
    # Variable part
    variable_part = MOIU.operate(*, T, f.variable_part, g.variable_part)
    # Decision part
    decision_part = MOIU.operate(*, T, f.decision_part, g.decision_part)
    if !iszero(f.variable_part.constant)
        for term in g.decision_part.terms
            new_term = MOIU.operate_term(*, f.variable_part.constant, term)
            add_term!(decision_part.affine_terms, new_term)
        end
    end
    if !iszero(g.variable_part.constant)
        for term in f.decision_part.terms
            new_term = MOIU.operate_term(*, g.variable_part.constant, term)
            add_term!(decision_part.affine_terms, new_term)
        end
    end
    # Cross terms
    cross_terms = convert(MOI.ScalarQuadraticFunction{T}, zero(T))
    for var_term in f.variable_part.terms
        for dvar_term in g.decision_part.terms
            new_term = MOIU.operate_term(*, dvar_term, var_term)
            add_term!(cross_terms.quadratic_terms, new_term)
        end
    end
    for var_term in g.variable_part.terms
        for dvar_term in f.decision_part.terms
            new_term = MOIU.operate_term(*, dvar_term, var_term)
            add_term!(cross_terms.quadratic_terms, new_term)
        end
    end
    return QuadraticDecisionFunction(
        variable_part,
        decision_part,
        cross_terms)
end
function MOIU.operate(::typeof(*), ::Type{T}, f::AffineDecisionFunction{T},
                      g::ScalarAffineLike{T}) where T
    return MOIU.operate(*, T, f, convert(AffineDecisionFunction{T}, g))
end
function MOIU.operate(::typeof(*), ::Type{T}, f::ScalarAffineLike{T},
                      g::AffineDecisionFunction{T}) where T
    return MOIU.operate(*, T, g, convert(AffineDecisionFunction{T}, f))
end
function MOIU.operate(::typeof(*), ::Type{T}, α::T,
                      g::AffineDecisionFunction{T}) where T
    return MOIU.operate!(*, T, copy(g), α)
end

MOIU.is_coefficient_type(::Type{<:Union{SingleDecision, VectorOfDecisions}}, ::Type) = true
MOIU.is_coefficient_type(::Type{<:TypedDecisionLike{T}}, ::Type{T}) where T = true
MOIU.is_coefficient_type(::Type{<:TypedDecisionLike}, ::Type) = false

function Base.:*(f::ScalarDecisionLike{T}, g::MixedScalarLike{T}, args::MixedScalarLike{T}...) where T
    return MOIU.operate(*, T, f, g, args...)
end
function Base.:*(f::MOIU.ScalarLike{T}, g::MixedScalarLike{T}, args::MixedScalarLike{T}...) where T
    return MOIU.operate(*, T, convert(AffineDecisionFunction{T}, f), g, args...)
end
function Base.:*(α::T, g::TypedDecisionLike{T}) where T
    return MOIU.operate_coefficients(β -> α * β, g)
end
function Base.:*(α::Number, g::TypedDecisionLike)
    return MOIU.operate_coefficients(β -> α * β, g)
end
function Base.:*(α::T, g::TypedDecisionLike{T}) where T <: Number
    return MOIU.operate_coefficients(β -> α * β, g)
end
function Base.:*(f::Number, g::Union{SingleDecision, VectorOfDecisions})
    return MOIU.operate(*, typeof(f), f, g)
end
function Base.:*(f::TypedDecisionLike{T}, α::T) where T
    return MOIU.operate_coefficients(β -> α * β, f)
end
function Base.:*(f::TypedDecisionLike, α::Number)
    return MOIU.operate_coefficients(β -> α * β, f)
end
function Base.:*(f::TypedDecisionLike{T}, α::T) where T <: Number
    return MOIU.operate_coefficients(β -> α * β, f)
end
function Base.:*(f::Union{SingleDecision, VectorOfDecisions}, g::Number)
    return MOIU.operate(*, typeof(g), f, g)
end
function Base.:*(f::TypedDecisionLike{T}, g::Bool) where T
    if g
        return MA.copy_if_mutable(f)
    else
        return zero(typeof(f))
    end
end

function Base.:^(func::AffineDecisionFunction{T}, p::Integer) where T
    if iszero(p)
        return one(QuadraticDecisionFunction{T})
    elseif isone(p)
        return convert(QuadraticDecisionFunction{T}, func)
    elseif p == 2
        return func * func
    else
        throw(ArgumentError("Cannot take $(typeof(func)) to the power $p."))
    end
end
function Base.:^(func::QuadraticDecisionFunction{T}, p::Integer) where T
    if iszero(p)
        return one(QuadraticDecisionFunction{T})
    elseif isone(p)
        return MA.mutable_copy(func)
    else
        throw(ArgumentError("Cannot take $(typeof(func)) to the power $p."))
    end
end

function LinearAlgebra.dot(f::ScalarDecisionLike, g::ScalarDecisionLike)
    return f * g
end
function LinearAlgebra.dot(α::T, func::TypedDecisionLike{T}) where T
    return α * func
end
function LinearAlgebra.dot(func::TypedDecisionLike{T}, α::T) where T
    return func * α
end
function LinearAlgebra.dot(f::VectorAffineDecisionFunction{T}, g::VectorAffineDecisionFunction{T}) where T
    result = zero(QuadraticDecisionFunction{T})
    for (lhs,rhs) in zip(MOIU.scalarize(f), MOIU.scalarize(g))
        term = MOIU.operate(*, T, lhs, rhs)
        MOIU.operate!(+, T, result, term)
    end
    return result
end

LinearAlgebra.adjoint(f::ScalarDecisionLike) = f
LinearAlgebra.transpose(f::ScalarDecisionLike) = f
LinearAlgebra.symmetric_type(::Type{F}) where {F <: ScalarDecisionLike} = F
LinearAlgebra.symmetric(f::ScalarDecisionLike, ::Symbol) = f

# / #
# ========================== #
function MOIU.promote_operation(::typeof(/), ::Type{T},
                                ::Type{<:ScalarAffineDecisionLike{T}},
                                ::Type{T}) where T
    AffineDecisionFunction{T}
end
function MOIU.promote_operation(::typeof(/), ::Type{T},
                                ::Type{QuadraticDecisionFunction{T}},
                                ::Type{T}) where T
    QuadraticDecisionFunction{T}
end

function MOIU.operate!(::typeof(/), ::Type{T}, f::SingleDecision,
                       α::T) where T
    return MOIU.operate(/, T, f, α)
end
function MOIU.operate(::typeof(/), ::Type{T},
                      α::T,
                      f::Union{SingleDecision, VectorOfDecisions}) where T
    return MOIU.operate(*, T, inv(α), f)
end
function MOIU.operate(::typeof(/), ::Type{T},
                      f::Union{SingleDecision, VectorOfDecisions},
                      α::T) where T
    return MOIU.operate(*, T, inv(α), f)
end

function MOIU.operate!(::typeof(/), ::Type{T},
                       f::Union{AffineDecisionFunction{T}, VectorAffineDecisionFunction{T}},
                       α::T) where T
    MOIU.operate!(/, T, f.variable_part, α)
    MOIU.operate!(/, T, f.decision_part, α)
    return f
end

function MOIU.operate!(::typeof(/), ::Type{T},
                       f::QuadraticDecisionFunction{T},
                       α::T) where T
    MOIU.operate!(/, T, f.variable_part, α)
    MOIU.operate!(/, T, f.decision_part, α)
    MOIU.operate!(/, T, f.cross_terms, α)
    return f
end

function MOIU.operate(::typeof(/), ::Type{T}, f::TypedDecisionLike{T}, α::T) where T
    return MOIU.operate!(/, T, copy(f), α)
end

function Base.:/(f::TypedDecisionLike{T}, g::T) where T
    return MOIU.operate(/, T, f, g)
end
function Base.:/(f::Union{SingleDecision, VectorOfDecisions}, g::Number)
    return MOIU.operate(/, typeof(g), f, g)
end

# vcat #
# ========================== #
function MOIU.fill_variables(decisions::Vector{MOI.VariableIndex}, offset::Int,
                             output_offset::Int, f::SingleDecision)
    decisions[offset + 1] = f.decision
end

function MOIU.fill_variables(decisions::Vector{MOI.VariableIndex}, offset::Int,
                             output_offset::Int, f::VectorOfDecisions)
    decisions[offset .+ (1:length(f.decisions))] .= f.decisions
end

function MOIU.promote_operation(::typeof(vcat), ::Type{T},
                                ::Type{<:Union{SingleDecision,
                                               VectorOfDecisions}}...) where T
    return VectorOfDecisions
end
function MOIU.operate(::typeof(vcat), ::Type{T},
                      funcs::Union{SingleDecision,
                                   VectorOfDecisions}...) where T
    out_dim = sum(func -> MOIU.output_dim(T, func), funcs)
    decisions = Vector{MOI.VariableIndex}(undef, out_dim)
    MOIU.fill_vector(decisions, T, 0, 0, MOIU.fill_variables, MOIU.output_dim, funcs...)
    return VectorOfDecisions(decisions)
end

function MOIU.promote_operation(::typeof(vcat), ::Type{T},
                                ::Type{<:AffineDecisionLike{T}},
                                ::Type{<:AffineLike{T}}...) where T
    return VectorAffineDecisionFunction{T}
end

function MOIU.promote_operation(::typeof(vcat), ::Type{T},
                                ::Type{QuadraticDecisionFunction{T}}) where T
    return QuadraticDecisionFunction{T}
end

function MOIU.operate(::typeof(vcat), ::Type{T},
                      funcs::VectorAffineDecisionFunction{T}...) where T
    # Variable part
    nvariable_terms = sum(f -> MOIU.number_of_affine_terms(T, f.variable_part), funcs)
    variable_out_dim = sum(f -> MOIU.output_dim(T, f.variable_part), funcs)
    variable_terms = Vector{MOI.VectorAffineTerm{T}}(undef, nvariable_terms)
    variable_constants = zeros(T, variable_out_dim)
    MOIU.fill_vector(variable_terms, T, 0, 0,
                     MOIU.fill_terms, MOIU.number_of_affine_terms, [f.variable_part for f in funcs]...)
    MOIU.fill_vector(variable_constants, T, 0, 0,
                     MOIU.fill_constant, MOIU.output_dim, [f.variable_part for f in funcs]...)
    # Decision part
    ndecision_terms = sum(f -> MOIU.number_of_affine_terms(T, f.decision_part), funcs)
    decision_out_dim = sum(f -> MOIU.output_dim(T, f.decision_part), funcs)
    decision_terms = Vector{MOI.VectorAffineTerm{T}}(undef, ndecision_terms)
    decision_constants = zeros(T, decision_out_dim)
    MOIU.fill_vector(decision_terms, T, 0, 0,
                     MOIU.fill_terms, MOIU.number_of_affine_terms, [f.decision_part for f in funcs]...)
    MOIU.fill_vector(decision_constants, T, 0, 0,
                     MOIU.fill_constant, MOIU.output_dim, [f.decision_part for f in funcs]...)
    # Pad output
    out_dim = max(variable_out_dim, decision_out_dim)
    append!(variable_constants, zeros(T, out_dim - length(variable_constants)))
    append!(decision_constants, zeros(T, out_dim - length(decision_constants)))
    return VectorAffineDecisionFunction{T}(MOIU.VAF(variable_terms, variable_constants),
                                           MOIU.VAF(decision_terms, decision_constants))
end

# First or second argument must be decision like to avoid type piracy
function MOIU.operate(::typeof(vcat), ::Type{T},
                      f::AffineDecisionLike{T},
                      funcs::AffineLike{T}...) where T
    return MOIU.operate(vcat,
                        T,
                        convert(VectorAffineDecisionFunction{T}, f),
                        [convert(VectorAffineDecisionFunction{T}, f) for f in funcs]...)
end
function MOIU.operate(::typeof(vcat), ::Type{T},
                      f::Union{MOIU.ScalarAffineLike{T}, MOIU.VectorAffineLike{T}},
                      g::AffineDecisionLike{T},
                      funcs::AffineLike{T}...) where T
    return MOIU.operate(vcat,
                        T,
                        convert(VectorAffineDecisionFunction{T}, f),
                        convert(VectorAffineDecisionFunction{T}, g),
                        [convert(VectorAffineDecisionFunction{T}, f) for f in funcs]...)
end

Base.promote_rule(::Type{F}, ::Type{T}) where {T, F<:Union{AffineDecisionFunction{T}, VectorAffineDecisionFunction{T}}} = F


text:
mutable struct PQPolygonSDKUserModel

    # data about the user -
    email::String
    apikey::String

    PQPolygonSDKUserModel() = new()
end

# what is the base type for all endpoint calls?
abstract type AbstractPolygonEndpointModel end

mutable struct PolygonGroupedDailyEndpointModel <: AbstractPolygonEndpointModel

    # data -
    date::Date
    adjusted::Bool
    apikey::String

    # constructor -
    PolygonGroupedDailyEndpointModel() = new()
end

mutable struct PolygonDailyOpenCloseEndpointModel <: AbstractPolygonEndpointModel

    # data -
    ticker::String
    adjusted::Bool
    date::Date
    apikey::String

    # constructor -
    PolygonDailyOpenCloseEndpointModel() = new()
end

mutable struct PolygonPreviousCloseEndpointModel <: AbstractPolygonEndpointModel

    # data -
    ticker::String
    adjusted::Bool
    apikey::String

    # constructor -
    PolygonPreviousCloseEndpointModel() = new()
end

mutable struct PolygonAggregatesEndpointModel <: AbstractPolygonEndpointModel

    # data -
    adjusted::Bool
    limit::Int64
    sortdirection::String
    ticker::String
    to::Date
    from::Date
    multiplier::Int64
    timespan::String
    apikey::String

    # constructor -
    PolygonAggregatesEndpointModel() = new()
end

mutable struct PolygonTickerNewsEndpointModel <: AbstractPolygonEndpointModel

    # data -
    ticker::String
    published_utc::Union{Date, Nothing}
    order::String
    limit::Int64
    sort::Union{String, Nothing}
    apikey::String

    # constructor -
    PolygonTickerNewsEndpointModel() = new()
end

mutable struct PolygonTickerDetailsEndpointModel <: AbstractPolygonEndpointModel

    # data -
    apikey::String
    ticker::String

    # constructor -
    PolygonTickerDetailsEndpointModel() = new()
end

mutable struct PolygonOptionsContractReferenceEndpoint <: AbstractPolygonEndpointModel

    # data -
    ticker::Union{Nothing,String}
    underlying_ticker::Union{Nothing, String}
    contract_type::String
    expiration_date::Date
    limit::Int64
    order::String
    sort::String
    apikey::String

    # constructor -
    PolygonOptionsContractReferenceEndpoint() = new()
end

ext: jl


text:
using Distributed
addprocs(2)

using Dagger
import Dagger: indexes, project
using CrimsonDagger
using Test

include("domain.jl")
include("array.jl")
include("scheduler-options.jl")
include("fault-tolerance.jl")
# TODO: include("cache.jl")
Dagger.cleanup()


text:
# vim: set et ts=2 sw=2:

# A file of miscellaneous utilities.
# ## Meta
same(s) = s

# ## Maths
# `int`: Round numbers
# `any`: Pull one thing from a list (at random)
int(x) = floor(Int,x)
any(a) =  a[ int(length(a) * rand()) + 1]

# `few`: Pull  `n` things from a list (at random)
few(a,n=it.divs.few) = length(a)<n ? a : [any(a) for _ in 1:n]

# ## Strings
# `thing`: coerce things to floats or strings
# `say,sayln`: print a struct, maybe with a trailing new line.
thing(x) = try parse(Float64,x) catch _ x end

sayln(i) = begin ay(i); println("") end

function say(i)
  fields(x) = fieldnames(typeof(x))
  s, pre="$(typeof(i)){", ""
  for f in sort!([x for x in fields(i) if !("$x"[1] == '_')])
    s = s * pre * "$f=$getfield(i,f)"
    pre=", " end
  print(s * "}") end

# ## Files
# `csv`: interate over a fiile
@resumable function csv(file;zap=r"(\s+|#.*)")
  b4=""
  for line in eachline(file)
    line = replace(line,zap =>"")
    if length(line) != 0
      if line[end] == ',' # if line ends with ",",
        b4 = b4 * line    # join it to next
      else
        @yield [thing(x) for x in split(b4*line,",")]
                b4 = "" end end end end

max_stars_repo_name: timm/jut

max_issues_repo_name: timm/jut

max_forks_repo_name: timm/jut


text:
importall Base

abstract Diagnostics
type Gradient <: Diagnostics
  epsilon::Float64
  error::Float64
end
Gradient(;epsilon=1e-6, error=1e-6) = Gradient(epsilon, error)

type Diagnose <: Methods
  diagnostic::Diagnostics
end
Diagnose(;d=Gradient()) = Diagnose(d)
#Diagnose(d=Gradient()) = Diagnose(d)

function diagnose_show(io::IO, d::Diagnose, compact::Bool)
  if compact
    println("Diagnose($(d.diagnostic))")
  else
    println("  method =                  Diagnose()")
    if isa(d.diagnostic, Gradient)
      println("    diagnostic =              Gradient()")
      println("      epsilon =                 ", d.diagnostic.epsilon)
      println("      error =                   ", d.diagnostic.error)
    end
  end
end

show(io::IO, d::Diagnose) = diagnose_show(io, d, false)
showcompact(io::IO, d::Diagnose) = diagnose_show(io, d, true)


text:
function main(r::Robot)
    path = go_to_west_south_corner_and_return_path!(r; go_around_barriers = true)

    for i ∈ (North, East, South, West)
        go_to_border_and_return_path!(r, i; markers = true)
    end
    go_by_path!(r, path)

end

max_stars_repo_name: Savko-fokin/mirea-progs

max_issues_repo_name: Savko-fokin/mirea-progs

max_forks_repo_name: Savko-fokin/mirea-progs


text:
module BigqueryTests

using Test
using Dates
using GCP
using GCP.Bigquery
using ..GCPTests

verbose = 0

@testset "BigQuery" begin

@testset "Datasets" begin

  datasetId = "dataset0"

  @test begin # insert
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    dataset = Bigquery.Dataset()
    dataset.datasetReference = Bigquery.DatasetReference()
    dataset.datasetReference.datasetId = datasetId
    res = p.bigquery.datasets.insert(dataset ; verbose=verbose)
    res != nothing
  end
  @test begin # get
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    res = p.bigquery.datasets.get(datasetId; verbose=verbose)
    res != nothing
  end
  @test begin # update
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    dataset = Bigquery.Dataset()
    dataset.datasetReference = Bigquery.DatasetReference()
    dataset.datasetReference.datasetId = datasetId
    dataset.friendlyName = "friendly-updated"
    res = p.bigquery.datasets.update(dataset, datasetId; verbose=verbose)
    res != nothing
  end
  @test begin # list
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    res = p.bigquery.datasets.list(; verbose=verbose)
    res != nothing
  end
  @test begin # patch
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    dataset = Bigquery.Dataset()
    dataset.datasetReference = Bigquery.DatasetReference()
    dataset.datasetReference.datasetId = datasetId
    dataset.friendlyName = "friendly-patched"
    res = p.bigquery.datasets.patch(dataset, datasetId; verbose=verbose)
    res != nothing
  end
  @test begin # delete
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    p.bigquery.datasets.delete(datasetId; verbose=verbose)
    true
  end

end # Datasets

function datasetInsert(datasetId::String)
  p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
  dataset = Bigquery.Dataset()
  dataset.datasetReference = Bigquery.DatasetReference()
  dataset.datasetReference.datasetId = datasetId
  p.bigquery.datasets.insert(dataset)
  true
end
function datasetDelete(datasetId::String)
  p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
  p.bigquery.datasets.delete(datasetId)
  true
end

@testset "Tables" begin

  datasetId = "dataset_tables"
  tableId = "test0"

  @test datasetInsert(datasetId)

  @test begin # insert
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    table = Bigquery.Table()
    table.tableReference = Bigquery.TableReference()
    table.tableReference.datasetId = datasetId
    table.tableReference.projectId = p.id
    table.tableReference.tableId = tableId
    table.schema = Bigquery.TableSchema()
    table.schema.fields = Vector{Bigquery.TableFieldSchema}()
    fld = Bigquery.TableFieldSchema()
    fld.name = "tme"
    fld.type_ = "TIMESTAMP"
    fld.mode = "REQUIRED"
    push!(table.schema.fields, fld)
    fld = Bigquery.TableFieldSchema()
    fld.name = "val"
    fld.type_ = "FLOAT"
    fld.mode = "REQUIRED"
    push!(table.schema.fields, fld)
    res = p.bigquery.tables.insert(table, datasetId ; verbose=verbose)
    res != nothing
  end
  @test begin # get
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    res = p.bigquery.tables.get(datasetId, tableId; verbose=verbose)
    res != nothing
  end
  @test begin # update
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    table = Bigquery.Table()
    table.tableReference = Bigquery.TableReference()
    table.tableReference.datasetId = datasetId
    table.tableReference.projectId = p.id
    table.tableReference.tableId = tableId
    table.friendlyName = "friendly-updated"
    res = p.bigquery.tables.update(table, datasetId, tableId; verbose=verbose)
    res != nothing
  end
  @test begin # list
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    res = p.bigquery.tables.list(datasetId; verbose=verbose)
    res != nothing
  end
  @test begin # patch
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    table = Bigquery.Table()
    table.tableReference = Bigquery.TableReference()
    table.tableReference.datasetId = datasetId
    table.tableReference.projectId = p.id
    table.tableReference.tableId = tableId
    table.friendlyName = "friendly-patched"
    res = p.bigquery.tables.patch(table, datasetId, tableId; verbose=verbose)
    res != nothing
  end
  @test begin # delete
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    p.bigquery.tables.delete(datasetId, tableId; verbose=verbose)
    true
  end

  @test datasetDelete(datasetId)

end # Tables

function tableInsert(datasetId::String, tableId::String)
  datasetInsert(datasetId)
  p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
  table = Bigquery.Table()
  table.tableReference = Bigquery.TableReference()
  table.tableReference.datasetId = datasetId
  table.tableReference.projectId = p.id
  table.tableReference.tableId = tableId
  table.schema = Bigquery.TableSchema()
  table.schema.fields = Vector{Bigquery.TableFieldSchema}()
  fld = Bigquery.TableFieldSchema()
  fld.name = "valTimestamp"
  fld.type_ = "TIMESTAMP"
  fld.mode = "REQUIRED"
  push!(table.schema.fields, fld)
  fld = Bigquery.TableFieldSchema()
  fld.name = "valFloat"
  fld.type_ = "FLOAT"
  fld.mode = "REQUIRED"
  push!(table.schema.fields, fld)

  fld = Bigquery.TableFieldSchema()
  fld.name = "valInt"
  fld.type_ = "INTEGER"
  fld.mode = "REQUIRED"
  push!(table.schema.fields, fld)
  fld = Bigquery.TableFieldSchema()
  fld.name = "valBool"
  fld.type_ = "BOOLEAN"
  fld.mode = "REQUIRED"
  push!(table.schema.fields, fld)
  fld = Bigquery.TableFieldSchema()
  fld.name = "valString"
  fld.type_ = "STRING"
  fld.mode = "REQUIRED"
  push!(table.schema.fields, fld)

  res = p.bigquery.tables.insert(table, datasetId ; verbose=verbose)
  true
end
function tableDelete(datasetId::String, tableId::String)
  p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
  p.bigquery.tables.delete(datasetId, tableId; verbose=verbose)
  datasetDelete(datasetId)
  true
end
struct TstTck <: GCP.Abstract # must inherit GCP.Abstract to use insertAll
  valTimestamp::DateTime
  valFloat::Float32
  valInt::Int32
  valBool::Bool
  valString::String
end

@testset "Tabledata" begin

  datasetId = "dataset_tabledata"
  tableId = "table_tabledata"

  @test tableInsert(datasetId, tableId)
  @test begin # insertAll
    p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
    tck = TstTck(now(), 1.0, 1, true, "abc")
    p.bigquery.tabledata.insertAll(tck, datasetId, tableId ; verbose=verbose)
    tcks = [TstTck(now(), 2.0, 2, true, "abc"), TstTck(now(), 3.0, 3, true, "abc")]
    res = p.bigquery.tabledata.insertAll(tcks, datasetId, tableId ; verbose=verbose)
    res != nothing
  end
  @test tableDelete(datasetId, tableId)

  # @test tableInsert(datasetId, tableId)
  # @test begin # list
  #   # p = GCP.Project(GCPTests.CredFilename, ["cloud-platform"])
  #   # tcks = Vector{TstTck}()
  #   # for n in 1:3
  #   #   push!(tcks, TstTck(now(), n, n, true, "abc"))
  #   # end
  #   # res = p.bigquery.tabledata.insertAll(tcks, datasetId, tableId ; verbose=verbose)
  #   # res = p.bigquery.tabledata.list(datasetId, tableId ; verbose=verbose)
  #   # res = p.bigquery.tabledata.list("oan_cor_tic", "aud_usd")
  #   # @info size(res)
  #   # res = p.bigquery.tables.get(datasetId, tableId ; verbose=verbose)
  #   # @info res
  #   true
  # end
  # @test tableDelete(datasetId, tableId)

end # Tabledata

end # BigQuery

end # module BigqueryTests

max_stars_repo_name: ProfLeao/mais

max_issues_repo_name: ProfLeao/mais

max_forks_repo_name: ProfLeao/mais


text:
using ArcadeLearningEnvironment
using CGP
using Logging
using ArgParse
import Images

include("../graphing/graph_utils.jl")

CGP.Config.init("cfg/atari.yaml")

max_reward_dict = Dict()

function stop_playing_check(cur_reward::Float64, frame_step::Int64)
    global max_reward_dict

    if haskey(max_reward_dict, frame_step)
        print("[", frame_step, "] Comparing: ", cur_reward, " to ", max_reward_dict[frame_step])

        if max_reward_dict[frame_step] == 0
            println()
            return false
        end

        val = ((max_reward_dict[frame_step] - cur_reward) / max_reward_dict[frame_step])
        println(" -- ", val)

        if val > 0.5
            return true
        end
    end

    false
end

function score_velocity_score(reward_dict::Dict)
    score_vel = 0.0
    prev = 0.0
    step_scale = 1000

    for step in reward_dict
        if step[1] > 0 && step[2] != -Inf
            cur = step[2]

            diff = cur - prev
            score_vel += diff / step_scale

            prev = cur
        end
    end

    score_vel
end

function play_atari(c::Chromosome, id::String, seed::Int64;
                    render::Bool=false, folder::String=".", max_frames=18000,
                    step_size=200)

    score_dict = Dict()
    # Get the game with ID and seed
    game = Game(id, seed)

    # Reset the seed
    seed_reset = rand(0:100000)
    srand(seed)

    # Reset all parameters
    reward = 0.0
    frames = 0
    p_action = game.actions[1]
    outputs = zeros(Int64, c.nout)

    # Keep playing, while the game isn't over
    while ~game_over(game.ale)

        # Have the Chromosome process the current inputs
        output = process(c, get_rgb(game))

        # Log the move count
        outputs[indmax(output)] += 1

        # Do that action
        action = game.actions[indmax(output)]
        reward += act(game.ale, action)

        # Possibly repeat action randomly
        if rand() < 0.25
            reward += act(game.ale, action) # repeat action here for seeding
        end

        # If we are rendering the game, save the screen to a file
        if render
            screen = draw(game)
            filename = string(folder, "/", @sprintf("frame_%06d.png", frames))
            Images.save(filename, screen)
        end

        if (frames % step_size) == 0
            score_dict[frames] = reward

            if 0.5 * max_frames < frames && stop_playing_check(reward, frames)
                println("Exit due to early stopping.")
                break
            end
        end

        # Always log the frames
        frames += 1
        if frames > max_frames
            Logging.debug(string("Termination due to frame count on ", id))
            break
        end
    end

    # Close the game and reset the seed
    close!(game)
    srand(seed_reset)

    score_dict[frames] = reward

    vel_score = score_velocity_score(score_dict)

    println("Final score: ", reward)
    println("Final velocity: ", vel_score)

    global max_reward_dict

    if vel_score > score_velocity_score(max_reward_dict)
        max_reward_dict = score_dict
        println("Updated the local top fit!")
    end

    # Return the reward and the list of outputs
    reward, outputs, vel_score
end

# Gets the best Chromrosomes from a log file
function get_bests(logfile::String)
    bests = []
    for line in readlines(logfile)
        if contains(line, ":C:")
            genes = eval(parse(split(line, ":C: ")[2]))
            append!(bests, [genes])
        end
    end
    bests
end

# Gets the input/output parameters
function get_params(args::Dict)
    game = Game(args["id"], args["seed"])
    nin = 3 # r g b
    nout = length(game.actions)
    close!(game)
    nin, nout
end

# Renders a gene
function render_genes(genes::Array{Float64}, args::Dict;
                    ctype::DataType=CGPChromo, id::Int64=0)

    # Gets the Chromrosome
    nin, nout = get_params(args)
    chromo = ctype(genes, nin, nout)

    # Selects the folder
    folder = string("frames/", args["id"], "_", args["seed"], "_", id)
    mkpath(folder)

    # Plays the Atari with that individual
    reward, out_counts, fit_score = play_atari(chromo, args["id"], args["seed"];
                                        render=false, folder=folder,
                                        max_frames=args["frames"])

    # Logs that individual's performance
    println(@sprintf("R: %s %d %d %0.5f %d %d",
                     args["id"], args["seed"], id, reward,
                     sum([n.active for n in chromo.nodes]),
                     length(chromo.nodes)))

    Logging.info(string("Top individual scores: "))
    Logging.info(string("\tFitness Score: ", fit_score))
    Logging.info(string("\tGame Score: ", reward))

    println("Top individual scores: ")
    println("\tFitness Score: ", fit_score)
    println("\tGame Score: ", reward)

    # Copy our genes
    new_genes = deepcopy(chromo.genes)

    # Not sure what this all is about
    for o in 1:nout
        if out_counts[o] == 0.0
            # disable this section of the graph by forcing
            # the output to connect to an input node
            new_genes[nin+o] = 0.00001
        end
    end

    # Check how many active outputs we actually had
    active_outputs = out_counts .> 0

    # Take the new Chromosome with slight modification to draw
    chromo2 = ctype(new_genes, nin, nout)
    file =  string("graphs/", args["id"], "_", args["seed"], "_", id, ".pdf");
    chromo_draw(chromo2, file, active_outputs=active_outputs)
    # chromo_draw(chromo2)
end

# Parses all the command line arguments
function get_args()
    s = ArgParseSettings()

    @add_arg_table(
        s,
        "--seed", arg_type = Int, default = 0,
        "--log", arg_type = String, default = "atari.log",
        "--id", arg_type = String, default = "centipede",
        "--ea", arg_type = String, default = "oneplus",
        "--chromosome", arg_type = String, default = "CGPChromo",
        "--frames", arg_type = Int, default = 18000,
        "--render", action = :store_const, constant = true, default = false,
    )

    parse_args(CGP.Config.add_arg_settings!(s))
end

# We run this as a non-interactive experiment
if ~isinteractive()

    # Get the args
    args = get_args()

    # Configure the CGP experiment
    CGP.Config.init(Dict([k=>args[k] for k in setdiff(
        keys(args), ["seed", "log", "id", "ea", "chromosome"])]...))

    # Seed the random generator
    srand(args["seed"])

    # Set up logging
    Logging.configure(filename=string(args["id"], ".log"), level=INFO)

    # Get the inputs/outputs
    @everywhere nin, nout = get_params(args)

    # Select evolution schema
    ea = eval(parse(args["ea"]))

    # Select chromosome type
    ctype = eval(parse(args["chromosome"]))

    # Define the fitness function
    # We use [1] here because it selects the reward as the fitness
    # measure
    fit = x->play_atari(x, args["id"], args["seed"];
                            max_frames=args["frames"])[3]

    # Actually run the EA experiment
    maxfit, best = ea(nin, nout, fit;
                      seed=args["seed"], id=args["id"], ctype=ctype)

    # Log the maxfit individual
    Logging.info(@sprintf("E%0.6f", -maxfit))

    # If we are rendering, render this best Chromosome
    if args["render"]
        render_genes(best, args; ctype=ctype)
    end
end


text:
module test_test_broken

using Test

@test_broken 1 == 2
@test_skip   1 == 2

if VERSION >= v"1.7.0-DEV.865"  # Julia PR #39322
@test 1 == 2 broken=true
@test 1 == 2 skip=true
end

end # module test_test_broken


text:
using Statistics
getaverage = floor ∘ mean

max_stars_repo_name: UlrichBerntien/Codewars-Katas

max_issues_repo_name: UlrichBerntien/Codewars-Katas

max_forks_repo_name: UlrichBerntien/Codewars-Katas


text:
using Dates
############################
# Install P + S models + sample data
############################
base = dirname(@__FILE__)
download_dir = joinpath(base, "downloads")
download_dir = joinpath(base, "downloads")
mkpath(download_dir)
pmodel = joinpath(download_dir,"model_P.pt")
smodel = joinpath(download_dir,"model_S.pt")
edata = joinpath(download_dir,"2016.162.00.00.00.008.AZ.TRO.HHE.SAC")
ndata = joinpath(download_dir,"2016.162.00.00.00.008.AZ.TRO.HHN.SAC")
zdata = joinpath(download_dir,"2016.162.00.00.00.008.AZ.TRO.HHZ.SAC")

function get_release_data(file::String)
    toget = basename(file)
    url = "https://github.com/tclements/PhaseNet.jl/releases/download/Models/"
    url = joinpath(url,toget)
    println("Downloading $toget... ",now())
    download(url,file)
    println("$toget complete... ",now())
    return nothing
end

for dat in [pmodel,smodel,edata,ndata,zdata]
    if !isfile(dat)
        get_release_data(dat)
    end
end


text:
# using Pkg
# Pkg.add("Documenter")
using Documenter, PolyChaos

makedocs(
    sitename = "PolyChaos.jl",
    format = Documenter.HTML(assets = ["assets/myfont.css"]),
    modules = [PolyChaos],
    authors = "tillmann.muehlpfordt@kit.edu",
    doctest = true,
    pages = Any[
        "index.md",
        "type_hierarchy.md",
        "Usage" => [
            "numerical_integration.md",
            "quadrature_rules.md",
            "orthogonal_polynomials_canonical.md",
            "gaussian_mixture_model.md",
            "multiple_discretization.md",
            "scalar_products.md",
            "Polynomial Chaos" => [ "Basic Usage" => "pce_tutorial.md",
                                    "Chi Squared, One DOF" => "chi_squared_k1.md",
                                    "Chi Squared, Several DOFs" => "chi_squared_k_greater1.md",
                                    "Random ODE" => "random_ode.md"
                                  ],
            "Optimal Power Flow" => "DCsOPF.md"
            ],
    "math.md",
    "functions.md"
    ]
)

deploydocs(
    repo = "github.com/timueh/PolyChaos.jl.git",
    target = "build",
)


text:
using Test
using LinearAlgebra
using DFTK: determine_grid_size

include("testcases.jl")

@testset "Test determine_grid_size on Silicon" begin
    @test determine_grid_size(silicon.lattice, 3, supersampling=2) == [15, 15, 15]
    @test determine_grid_size(silicon.lattice, 4, supersampling=2) == [15, 15, 15]
    @test determine_grid_size(silicon.lattice, 5, supersampling=2) == [18, 18, 18]
    @test determine_grid_size(silicon.lattice, 15, supersampling=2) == [27, 27, 27]
    @test determine_grid_size(silicon.lattice, 25, supersampling=2) == [36, 36, 36]
    @test determine_grid_size(silicon.lattice, 30, supersampling=2) == [40, 40, 40]

    # Test the model interface as well
    model = Model(silicon.lattice; n_electrons=silicon.n_electrons)
    @test determine_grid_size(model, 30) == [40, 40, 40]
    @test determine_grid_size(model, 30, supersampling=1.8) == [36, 36, 36]
end

@testset "Test determine_grid_size on skewed lattice" begin
    lattice = Diagonal([1, 1e-12, 1e-12])
    @test determine_grid_size(lattice, 15, supersampling=2) == [5, 1, 1]
    @test determine_grid_size(lattice, 300, supersampling=2) == [18, 1, 1]
end


text:
module Game

struct Board
end

struct Game
    board :: Board
    currentPlayer
end

end

max_stars_repo_name: TheGluck/Connect-Four-AI

max_issues_repo_name: TheGluck/Connect-Four-AI

max_forks_repo_name: TheGluck/Connect-Four-AI


text:
using Gadfly, DataArrays, RDatasets

set_default_plot_size(6inch, 3inch)

plot(dataset("car", "UN"), x=:GDP, y=:InfantMortality,
     Geom.histogram2d, Scale.x_log10, Scale.y_log10)


text:
using DataFrames, JSON3, JSONTables, ZipFile, LazyJSON
Base.convert(::Type{JSON3.Array}, x::Vector{JSON3.Object}) = x

function get_events(events::String)
    zarchive = ZipFile.Reader("/tmp/events.zip")
    dictio = Dict(zarchive.files[i].name => i for i in eachindex(zarchive.files))
    file_num = dictio[events]
    str = read(zarchive.files[file_num])

    return str
end

function createDict(str)

    inDict = JSON3.read(str)
    return inDict
end

function create_subset_json(json_data, game_id::Int)
    subset_json_indexes = [i for i in eachindex(json_data) if json_data[i][:matchId] == game_id]
    subset_json = json_data[subset_json_indexes]
    json_data = nothing
    Base.GC.gc()
    subset_json = DataFrame(convert(JSON3.Array,subset_json))
    return subset_json
end

function all_process(events::String, game_id::Int)
    json_data = createDict(get_events(events))
    data = create_subset_json(json_data, 2576335)
    json_data = nothing
    Base.GC.gc()
    return data
end

# Base.GC.gc()
@time all_process("events_Italy.json", 2576335)

# str = get_events("events_Italy.json")

# @time v = LazyJSON.parse(str);

function subset_indexes_lazy(json_data, game_id::Int)
    json_data = convert(Vector{Any},v)
    json_data = [i for i in v if i["matchId"] == game_id]
    # json_data = DataFrame(json_data)
end

function transform_to_df(json_subset)
    subset_dic = convert.(Dict, json_subset)

    test_df = DataFrame(:playerId => zeros(length(subset_dic)),
        :matchId => zeros(length(subset_dic)),
        :eventName => "",
        :positions => [Vector{Dict}[] for i in eachindex(subset_dic)],
        :eventId => zeros(length(subset_dic)),
        :subEventName => "",
        :teamId => zeros(length(subset_dic)),
        :id => zeros(length(subset_dic)),
        :matchPeriod => "",
        :subEventId => "",
        :eventSec => zeros(length(subset_dic)),
        :tags => [Vector{Dict}[] for i in eachindex(subset_dic)])

    for i in eachindex(test_df.playerId)
        test_df[i, :playerId] = subset_dic[i]["playerId"]
        test_df[i, :positions] = [convert.(Dict,subset_dic[i]["positions"])]
        test_df[i, :matchId] = subset_dic[i]["matchId"]
        test_df[i, :eventName] = string(subset_dic[i]["eventName"])
        test_df[i, :eventId] = subset_dic[i]["eventId"]
        test_df[i, :subEventName] = string(subset_dic[i]["subEventName"])
        test_df[i, :teamId] = subset_dic[i]["teamId"]
        test_df[i, :id] = subset_dic[i]["id"]
        test_df[i, :matchPeriod] = string(subset_dic[i]["matchPeriod"])
        test_df[i, :subEventId] = string(subset_dic[i]["subEventId"])
        test_df[i, :eventSec] = subset_dic[i]["eventSec"]
        test_df[i, :tags] = [convert.(Dict,subset_dic[i]["tags"])]
    end

    return test_df
end

function process_lazy(events::String, game_id::Int)
    str = get_events(events)
    v = LazyJSON.parse(str)
    subset_test = subset_indexes_lazy(v, game_id)
    result = transform_to_df(subset_test)
end

# @time subset_test = subset_indexes_lazy(v, 2576335)

# @time result = transform_to_df(subset_dic)

@time test = process_lazy("events_Italy.json", 2576335)

# @time DataFrame(subset_dic)

# @time subset_df = vcat(DataFrame.(subset_dic)...)

# @time
# check = jsontable(subset_test)
# @time testDict = createDict(str)

typeof(testDict)

Base.convert(::Type{JSON3.Array}, x::Vector{JSON3.Object}) = x

@time test_subset = create_subset_json(testDict, 2576335)

typeof(convert(JSON3.Array, test_subset))


text:
export Gibbs, SliceSampler

mutable struct Gibbs <: PosteriorInference
        burnin::Int
        thinout::Int
        maxiter::Int

        Gibbs(; burnin = 0, thinout = 1, maxiter = 100) = new(burnin, thinout, maxiter)
end

mutable struct SliceSampler <: PosteriorInference
        burnin::Int
        thinout::Int
        maxiter::Int

        SliceSampler(; burnin = 0, thinout = 1, maxiter = 100) = new(burnin, thinout, maxiter)
end

function train(B::AbstractModelBuffer, P::AbstractHyperparam, I::Gibbs)

  results = AbstractModelData[]

  # burn-in phase
  for iter in 1:I.burnin
    # run one gibbs iteration
    gibbs!(B)

    # sample parameters
    sampleparameters!(B, P)
  end

  # Gibbs sweeps
  @showprogress 1 "Running Gibbs..." for iter in 1:I.maxiter
    for t in 1:I.thinout
      # run one gibbs iteration
      gibbs!(B)

      # sample parameters
      sampleparameters!(B, P)
    end

    push!(results, extractpointestimate(B))
  end

  return results

end

function train(B::AbstractModelBuffer, P::AbstractHyperparam, I::SliceSampler)

  results = AbstractModelData[]

  # burn-in phase
  for iter in 1:I.burnin
    # run one gibbs iteration
    slicesampling!(B)

    # sample parameters
    sampleparameters!(B, P)
  end

  # Gibbs sweeps
  @showprogress 1 "Running SliceSampler..." for iter in 1:I.maxiter
    for t in 1:I.thinout
      # run one gibbs iteration
      slicesampling!(B)

      # sample parameters
      sampleparameters!(B, P)
    end

    push!(results, extractpointestimate(B))
  end

  return results

end


text:
include("../GenEvo.jl")

module GenEvoTest

using GenEvo
using Base.Test

function testOnAllContexts(f, title)
    for ctx in [("AF/CPU", ArrayFire{CPU}())]
        println("BEGIN: $title on $(ctx[1])")
        scope!(ctx[2]) do this
            f(ctx[2])
        end
        println("PASSED")
    end
end

include("dna.jl")
include("synthesizer.jl")
include("comparers.jl")
include("optAlgoTests.jl")
include("ga.jl")
include("ce.jl")
include("pso.jl")

end

max_stars_repo_name: unbornchikken/julia-ml-proto

max_issues_repo_name: unbornchikken/julia-ml-proto

max_forks_repo_name: unbornchikken/julia-ml-proto


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

using Markdown
using InteractiveUtils

# ╔═╡ 83b52b3e-12e2-11ec-050b-0d5b599be67e
begin
    using Pkg
    Pkg.activate("..")
    using Revise, Javis, JUtils, Random, Colors, Animations, PlutoUI
    import Luxor
end

# ╔═╡ ecbdf12c-5c52-4325-88ed-192caf0818ea
let
    width = 500
    hwidth = width ÷ 2
    height = 300
    hheight = height ÷ 2
    λ = 0.01
    draw = @draw begin
        points = []
        centers =
            map(collect(Base.product((-hwidth):hwidth, (-hheight):hheight))) do mypoint
                if Random.rand() < λ
                    push!(points, mypoint)
                end
            end
        map(points) do c
            # randomcolor()
            circle(Point(c), 1, :fill)
        end
    end width height
end

# ╔═╡ 87e9bdcc-23e5-4d62-93c2-56f94a803f74
function _draw_point_process(λ = 0.0002; width = 500, height = 300)
    hwidth = width ÷ 2
    hheight = height ÷ 2

    points = []
    centers = map(Base.product((-hwidth):hwidth, (-hheight):hheight)) do mypoint
        if Random.rand() < λ
            push!(points, Point(mypoint))
        end
    end
    points = shuffle(points)
end

# ╔═╡ 32f03626-aa06-491d-be0b-4d7ebd7466d0
function make_point_process(λ; n_frames, width = 500, height = 300)
    points = _draw_point_process(λ, width = width, height = height)

    circles = map(enumerate(points)) do (idx, c)
        color = RGBA(randomhue()..., 0.6)
        Object(idx:n_frames, (args...) -> begin
            setcolor(color)
            circle(c, 14, :fill)
        end)
    end
end

# ╔═╡ 1cda21d0-ecb2-4baa-b220-57d976a7f948
function ground(args...)
    Javis.background("white")
    sethue("black")
end

# ╔═╡ 461353a2-02de-4201-8f05-4768c619678c
let
    width = 500
    height = 300
    λ = 0.0002

    points = _draw_point_process(λ, width = width, height = height)
    n_frames = length(points) + 100
    circles_video = Video(width, height)
    Background(1:n_frames, ground)
    make_point_process(λ, n_frames = n_frames, width = width, height = height)

    render(circles_video, pathname = "../output/poisson_point_process.gif")
end

# ╔═╡ c8d4652e-df15-4c21-88af-14ddd78a9f88
let
    width = 500
    height = 300
    λ = 0.001

    points = _draw_point_process(λ, width = width, height = height)
    n_frames = length(points)
    circles_video = Video(width, height)
    Background(1:n_frames, ground)
    final_points = [Point(-125, -75), Point(125, -75), Point(125, 75), Point(-125, 75)]
    for point in final_points
        @JLayer 1:n_frames 250 150 point begin
            sethue("white")
            p = make_point_process(λ, n_frames = n_frames, width = width, height = height)
            Object(1:n_frames, (args...) -> begin
                setline(3)
                box(O, 250, 150, :stroke)
            end)
        end
    end

    render(circles_video, pathname = "../output/4_poisson_point_process.gif")
end

# ╔═╡ 5aaec46b-156e-4881-90cb-77e6f84c9e09
begin
    width = 500
    height = 300
    λ = 0.0005

    points = _draw_point_process(λ, width = width, height = height)
    n_frames = 500
    circles_video = Video(width, height)

    points = _draw_point_process(λ)
    n_points = length(points)
    birth_times = rand(1:n_frames, n_points)
    growth_rates = rand(n_points)

    radiuses = hcat(map(zip(points, birth_times, growth_rates)) do (p, t₀, growth)
        map(1:n_frames) do t
            if t < t₀
                0
            elseif t == t₀
                1
            else
                growth * (t - t₀) + 1
            end
        end
    end...)

    radiuses_bis = deepcopy(radiuses)

    for i in 1:size(radiuses_bis, 1)

        future_mask = map(Base.product(1:n_points, 1:n_points)) do (x, y)
            intersect =
                intersection2circles(
                    points[x],
                    radiuses_bis[i, x],
                    points[y],
                    radiuses_bis[i, y],
                ) != 0.0

            (x == y) | !intersect | (radiuses_bis[i, x] <= 1)
        end
        mask = all(future_mask, dims = 1)

        radiuses_bis[(i + 1):end, :] = radiuses_bis[(i + 1):end, :] .* mask
    end

    Background(1:n_frames, ground)

    map(enumerate(eachcol(radiuses_bis))) do (idx, r_s)
        col = RGBA(randomhue()..., 0.6)
        map(enumerate(r_s)) do (tₙ, r)
            Object(tₙ:tₙ, (args...) -> begin
                setcolor(col)
                circle(points[idx], r, :fill)
                sethue("black")
                circle(points[idx], r, :stroke)
            end)
        end
    end

    v = render(circles_video, pathname = "../output/matern1_point_process.gif")
end

# ╔═╡ 3d29cbd9-2d4f-45a4-918d-2302822fc593
v_bis = let
    width = 500
    height = 300
    λ = 0.0005

    # Random.seed!(1234)

    points = _draw_point_process(λ, width = width, height = height)
    n_frames = 100
    circles_video = Video(width, height)

    points = _draw_point_process(λ)
    n_points = length(points)
    birth_times = rand(1:n_frames, n_points)
    growth_rates = rand(n_points)

    radiuses = hcat(map(zip(points, birth_times, growth_rates)) do (p, t₀, growth)
        map(1:n_frames) do t
            if t < t₀
                0
            elseif t == t₀
                1
            else
                growth * (t - t₀) + 1
            end
        end
    end...)

    radiuses_bis = deepcopy(radiuses)

    radiuses_at_first = deepcopy(radiuses)

    Background(1:n_frames, ground)

    map(enumerate(eachcol(radiuses))) do (idx, r_s)
        col = RGBA(randomhue()..., 0.6)
        map(enumerate(r_s)) do (tₙ, r)
            Object(tₙ:tₙ, (args...) -> begin
                setcolor(col)
                circle(points[idx], r, :fill)
            end)
        end
    end

    circles_video.background_frames = reverse(circles_video.background_frames)
    render(circles_video, pathname = "../output/boolean_point_process.gif")
end

# ╔═╡ Cell order:
# ╟─83b52b3e-12e2-11ec-050b-0d5b599be67e
# ╟─ecbdf12c-5c52-4325-88ed-192caf0818ea
# ╟─461353a2-02de-4201-8f05-4768c619678c
# ╟─c8d4652e-df15-4c21-88af-14ddd78a9f88
# ╟─5aaec46b-156e-4881-90cb-77e6f84c9e09
# ╟─3d29cbd9-2d4f-45a4-918d-2302822fc593
# ╟─32f03626-aa06-491d-be0b-4d7ebd7466d0
# ╟─87e9bdcc-23e5-4d62-93c2-56f94a803f74
# ╟─1cda21d0-ecb2-4baa-b220-57d976a7f948


text:
using Test
using CSV
include("../src/FindKm.jl")

################################################################################
# Tests for functions that normalise data like M3Drop expects
################################################################################

#Check can accurately find no. detected genes per cell
df = DataFrame(Column1 = ["I1", "I2", "I3", "I4"], Cell1 = Float64[0, 0, 0, 0],
Cell2 = Float64[0,1,1,1])
expected_output_true = DataFrame(Cells = [Symbol("Cell1"), Symbol("Cell2")],
DetectedGenes = Float64[0,3])
@test FindNumDetectedGenesPerCell(df, true) == expected_output_true

#Check can accurately find no. undetected genes per cell
expected_output_false = DataFrame(Cells = [Symbol("Cell1"), Symbol("Cell2")],
DetectedGenes = Float64[4,1])
@test FindNumDetectedGenesPerCell(df, false) == expected_output_false

#Check can find mean DetectedGenes
@test FindMean(expected_output_true) == 1.5
@test FindMean(expected_output_false) == 2.5

#Check can find sd DetectedGenes
@test FindStd(expected_output_true) ≈ 2.12 atol=0.01
@test FindStd(expected_output_false) ≈ 2.12 atol=0.01

#Check removing low quality cells works
expected_output = deepcopy(expected_output_false)
@test RemoveLowQuality(expected_output_false, 2.5, 2.12) == expected_output
df = DataFrame(Cells = [Symbol("Cell1")], DetectedGenes = Float64[8025])
@test RemoveLowQuality(df, 0, 1 ) == DataFrame(Cells = Symbol[],
DetectedGenes = Float64[])

#Check can remove cells correctly
orig_df = DataFrame(Isoforms = ["I1", "I2", "I3", "I4"], Cell1 = Float64[0, 0, 0, 0],
Cell2 = Float64[0,1,1,1])
@test KeepFiltered(df, orig_df) == DataFrame(Isoforms = ["I1", "I2", "I3", "I4"],
 Cell1 = Float64[0, 0, 0, 0])
@test KeepFiltered(DataFrame(Cells = []), orig_df) ==
DataFrame(Isoforms = ["I1", "I2", "I3", "I4"])

#Check can correctly remove undetected genes
test_data = DataFrame(Column1 = ["I1", "I2", "I3"], Cell1 = Float64[0, 0, 1],
Cell2 = Float64[0,1,1], Cell3 = Float64[1,1,1], Cell4 = [1,1,1])
expected_output = DataFrame(Column1 = ["I3"], Cell1 = Float64[1],
Cell2 = Float64[1], Cell3 = Float64[1], Cell4 = Float64[1])
@test RemoveUndetectedGenes(test_data) == expected_output

#Check cpm calculation is correct
input = DataFrame(Isoforms = ["I1", "I2", "I3", "I4"], Cell1 = Float64[0, 0, 0, 1],
Cell2 = Float64[0,0,1,1])
expected_output = DataFrame(Isoforms = ["I1", "I2", "I3", "I4"], Cell1 = Float64[0, 0, 0, 1000000],
Cell2 = Float64[0,0,500000,500000])
@test ConvertToCpm(input) == expected_output

#Check can correctly remove lowly expressed genes
expected_output = DataFrame(Isoforms = ["I3", "I4"], Cell1 = Float64[ 0, 1],
Cell2 = Float64[1,1])
@test RemoveLowlyExpressedGenes(input) == expected_output

################################################################################
# Tests for functions that calculate Km
################################################################################

input = DataFrame(Isoforms = ["I1", "I2"], Cell1 = [0, 1], Cell2 = [1, 1])
expected_output = DataFrame(Isoforms = ["I1", "I2"], p = [0.5, 0])
@test Findp(input) == expected_output

s_out = deepcopy(expected_output)
s_out[:s] = [0.5, 1]
@test Finds(expected_output, input) == s_out

#Check LogLikelihood function gives correct output
LogLikelihoodFn = LogLikelihood(Float64[1,2,3], Float64[1,2,3])
@test LogLikelihoodFn([1.0,1.0]) ≈ 8.05 atol=0.01

#Check maximum likelihood estimation is working
df = CSV.read("test/data/p.txt", header = true, delim = ',')
p=df.x
df = CSV.read("test/data/s.txt", header = true, delim = ',')
s=df.x
parameters = MaxLikelihoodEst(p, s)
@test parameters[1] ≈ 8.5 atol=0.1
@test parameters[2] ≈ 0.1 atol=0.1

max_stars_repo_name: jenni-westoby/Obstacles

max_issues_repo_name: jenni-westoby/Obstacles

max_forks_repo_name: jenni-westoby/Obstacles


text:
"""
**Get the next page of results**

This function will retrieve the next page of results. By default, it will walk
through queries 20 at a time. This can be modified by changing the
`.query["limit"]` value, to any value *below* 200.

If filters have been applied to this query before, they will be *removed* to
ensure that the previous and the new occurrences have the same status.
"""
function next!(o::GBIFRecords)
  !all(o.show) && allrecords!(o)
  if length(o.occurrences) == o.count
    @info "All occurences for this query have been returned"
  else
    if o.query == nothing
      o.query = Dict{String,Any}()
    end
    o.query["offset"] = length(o.occurrences)
    o.query["limit"] = get(o.query, "limit", 20)
    if (o.query["offset"] + o.query["limit"]) > o.count
      o.query["limit"] = o.count - o.query["offset"]
    end
    get_next = GBIF.occurrences(o.query)
    append!(o.occurrences, get_next.occurrences)
    append!(o.show, get_next.show)
    o.offset = length(o.occurrences)
    @assert o.offset == length(o.occurrences)
  end
end

"""
**Get all pages of results**

This function will retrieve *all* matches (up to the GBIF limit of 200000
records for a streaming query). It is recommended to set the limit to more than
the default of 20 before calling this function. If not, this will trigger a lot
of requests both from your end and on the GBIF infrastructure.

Internally, this function is simply calling `next!` until all records are
exhausted. This implies that the effect of filters that were previously applied
to the records will be removed.
"""
function complete!(o::GBIFRecords)
  while length(o.occurrences) < o.count
    next!(o)
  end
end


text:
using Flux, DelimitedFiles, CUDA, Surrogates, PyPlot, BSON
xpu = cpu
plt.style.use("seaborn-paper")
loaddir = "/home/chris/Documents/conductionblock/data/bikt/set/1/theta/"

PyPlot.rc("font", family="serif")
PyPlot.rc("text", usetex=true)
PyPlot.matplotlib.rcParams["axes.titlesize"] = 10
PyPlot.matplotlib.rcParams["axes.labelsize"] = 10
PyPlot.matplotlib.rcParams["xtick.labelsize"] = 9
PyPlot.matplotlib.rcParams["ytick.labelsize"] = 9

crit_dns = []
for th in 0:18
	tmp = readdlm("$(loaddir)$(th)/crit_dns")
	push!(crit_dns, tmp[2:end,1:end-1])
end
crit_dns = vcat(crit_dns...)

testyIndices = Int.(round.(range(1, size(crit_dns,1), length=10)))
trainIndices = []
for m in 1:size(crit_dns,1)
	if m ∉ testyIndices
		push!(trainIndices,m)
	end
end
print("(training, testing, total) = ($(length(trainIndices)), $(length(testyIndices)), $(size(crit_dns,1)))\n")
x = Float32.(collect(transpose(crit_dns[trainIndices,[1,3]]))) 	|> xpu
y = Float32.(collect(transpose(crit_dns[trainIndices,2]))) 		|> xpu
X = Float32.(collect(transpose(crit_dns[testyIndices,[1,3]]))) 	|> xpu
Y = Float32.(collect(transpose(crit_dns[testyIndices,2]))) 		|> xpu

model = Chain(
	Dense( 2, 16, relu),
	Dense(16, 16, relu),
	Dense(16, 16, relu),
	Dense(16, 16, relu),
	Dense(16,  1),
	) |> xpu

opt = ADADelta() #ADAM(0.001, (0.9, 0.999))
loss(x, y) = Flux.Losses.mae(model(x), y)
ps = Flux.params(model)
dl = Flux.DataLoader((x, y), batchsize=64, shuffle=true) |> xpu
Flux.@epochs 20000 Flux.train!(loss, ps, dl, opt; cb = Flux.throttle(() -> @show((loss(x,y), loss(X, Y))), 10))

plt.figure(figsize=(4,2))
plt.plot(x[1,1:15], y[1:15], "ok", label="DNS")
xx = 10.0.^(range(log10(minimum(x[1,1:15])), log10(maximum(x[1,1:15])), length=129))
yy = collect(transpose(model(collect(transpose(hcat(xx, zeros(length(xx))))))))
plt.plot(xx, yy, "-C0", linewidth=1, label="NN($(length(vcat([ps[n][:] for n=1:length(ps)]...))))")

model |> cpu; x |> cpu; y |> cpu; dl |> cpu;
BSON.@save "nn_Us.bson" model

model2 = RadialBasis([(x[1,n],x[2,n]) for n in 1:size(x,2)], [(y[n]) for n in 1:size(x,2)], [minimum(x[1,:]),minimum(x[2,:])], [maximum(x[1,:]),maximum(x[2,:])])

yy = model2.([(xx[n],0.0) for n in 1:length(xx)])
plt.plot(xx, yy, "--C1", linewidth=2, label="Surrogate")
plt.xscale("log"); plt.yscale("symlog")
plt.legend(loc=0, edgecolor="none")
plt.title("\$ \\theta = 0 \$")
plt.xlabel("\$ x_s \$")
plt.ylabel("\$ U_s(x_s,\\theta) \$")
plt.savefig("./comparison.svg", bbox_inches="tight")
plt.close()

# use contour plots to show approximate functions in (xs,th) plane
fig, axs = plt.subplots(1,3, figsize=(9,3), sharex=true, sharey=true, constrained_layout=true)
axs[1].plot(x[1,:], x[2,:], ".w", markersize=2)
axs[1].tricontour( x[1,:], x[2,:], y[:], levels=14, vmin=minimum(y[:]), vmax=maximum(y[:]), linewidths=0.5, colors="k")
img = axs[1].tricontourf(x[1,:], x[2,:], y[:], levels=14, vmin=minimum(y[:]), vmax=maximum(y[:]), cmap="Oranges")
axs[1].set_title("Triangulation")
axs[1].set_xlabel("\$ x_s \$")
axs[1].set_ylabel("\$ \\theta \$")
axs[1].set_xscale("log")
X = zeros(Float32,2,129*65)
for (m,xs) in enumerate(range(minimum(x[1,:]), maximum(x[1,:]), length=129))
	for (n,th) in enumerate(range(minimum(x[2,:]), maximum(x[2,:]), length=65))
		X[:,m + (n-1)*129] = [xs,th]
	end
end
Y = model(X)
axs[2].plot(x[1,:], x[2,:], ".w", markersize=2)
axs[2].tricontour( X[1,:], X[2,:], Y[:], levels=14, vmin=minimum(y[:]), vmax=maximum(y[:]), linewidths=0.5, colors="k")
axs[2].tricontourf(X[1,:], X[2,:], Y[:], levels=14, vmin=minimum(y[:]), vmax=maximum(y[:]), cmap="Oranges")
axs[2].set_title("Neural Network")
axs[2].set_xlabel("\$ x_s \$")
#axs[2].set_ylabel("\$ \\theta \$")
#axs[2].set_xscale("log")
Y = model2.([(X[1,n],X[2,n]) for n in 1:size(X,2)])
axs[3].plot(x[1,:], x[2,:], ".w", markersize=2)
axs[3].tricontour( X[1,:], X[2,:], Y[:], levels=14, vmin=minimum(y[:]), vmax=maximum(y[:]), linewidths=0.5, colors="k")
axs[3].tricontourf(X[1,:], X[2,:], Y[:], levels=14, vmin=minimum(y[:]), vmax=maximum(y[:]), cmap="Oranges")
axs[3].set_title("Surrogate Model")
axs[3].set_xlabel("\$ x_s \$")
#axs[2].set_ylabel("\$ \\theta \$")
#axs[2].set_xscale("log")
plt.colorbar(img, ax=axs, aspect=40, label="\$ U(x_s,\\theta) \$")
plt.savefig("./contour_comparison.svg", bbox_inches="tight")
plt.close()


text:
#low
@info "********* Low Level Api *********"
const HEOS_BACKEND_FAMILY = "HEOS"
const REFPROP_BACKEND_FAMILY = "REFPROP";#Need Install
const INCOMP_BACKEND_FAMILY = "INCOMP"
const IF97_BACKEND_FAMILY = "IF97"
const TREND_BACKEND_FAMILY = "TREND";#Not Imple
const TTSE_BACKEND_FAMILY = "TTSE"
const BICUBIC_BACKEND_FAMILY = "BICUBIC"
const SRK_BACKEND_FAMILY = "SRK"
const PR_BACKEND_FAMILY = "PR"
const VTPR_BACKEND_FAMILY = "VTPR";#Need Install
HEOS = AbstractState_factory(HEOS_BACKEND_FAMILY, "R245fa")
TTSE = AbstractState_factory(HEOS_BACKEND_FAMILY * "&" * TTSE_BACKEND_FAMILY, "R245fa")
BICU = AbstractState_factory(HEOS_BACKEND_FAMILY * "&" * BICUBIC_BACKEND_FAMILY, "R245fa")
SRK = AbstractState_factory(SRK_BACKEND_FAMILY, "R245fa")
PR = AbstractState_factory(PR_BACKEND_FAMILY, "R245fa")
PT_INPUTS = get_input_pair_index("PT_INPUTS")
AbstractState_update(HEOS, PT_INPUTS, 101325, 300)
AbstractState_update(TTSE, PT_INPUTS, 101325, 300)
AbstractState_update(BICU, PT_INPUTS, 101325, 300)
AbstractState_update(SRK, PT_INPUTS, 101325, 300)
AbstractState_update(PR, PT_INPUTS, 101325, 300)
rhmolar = get_param_index("DMOLAR")
println("HEOS:", AbstractState_keyed_output(HEOS, rhmolar))
@time AbstractState_keyed_output(HEOS, rhmolar)
println("TTSE:", AbstractState_keyed_output(TTSE, rhmolar))
@time AbstractState_keyed_output(TTSE, rhmolar)
println("BICU:", AbstractState_keyed_output(BICU, rhmolar))
@time AbstractState_keyed_output(BICU, rhmolar)
println("SRK:", AbstractState_keyed_output(SRK, rhmolar))
@time AbstractState_keyed_output(SRK, rhmolar)
println("PR:", AbstractState_keyed_output(PR, rhmolar))
@time AbstractState_keyed_output(PR, rhmolar)
AbstractState_free(HEOS)
AbstractState_free(TTSE)
AbstractState_free(BICU)
AbstractState_free(SRK)
AbstractState_free(PR)
IF97 = AbstractState_factory(IF97_BACKEND_FAMILY, "")
pin = 101325
tin = 308.15
println("IF97::Water property for PT_INPUTS $pin $tin")
AbstractState_update(IF97, PT_INPUTS, pin, tin)
for p in "PTHDSAUCO"
    pi = get_param_index("$p")
    println("IF97 $p = ", AbstractState_keyed_output(IF97, pi))
end
qin = 0.5
try
    println("IF97::Water property for QT_INPUTS $qin $tin")
    QT_INPUTS = get_input_pair_index("QT_INPUTS")
    AbstractState_update(IF97, QT_INPUTS, qin, tin)
    for p in "PTHDSAUQ"
        pi = get_param_index("$p")
        println("IF97 $p = ", AbstractState_keyed_output(IF97, pi))
    end
catch
    @warn "QT_INPUTS not ready"
end
AbstractState_free(IF97)
#AbstractState_output AbstractState_set_fractions AbstractState_specify_phase
handle = AbstractState_factory("HEOS", "Water&Ethanol")
pq_inputs = get_input_pair_index("PQ_INPUTS")
t = get_param_index("T")
AbstractState_set_fractions(handle, [0.4, 0.6])
AbstractState_update(handle,pq_inputs,101325, 0)
if (haskey(ENV, "includelocalwrapper") && ENV["includelocalwrapper"]=="on")
    T, p, rhomolar, hmolar, smolar = AbstractState_update_and_common_out(handle, pq_inputs, [101325.0], [0.0], 1)
    temp_, p, rhomolar, hmolar, smolar = AbstractState_update_and_common_out(handle, "PQ_INPUTS", [101325.0], [0.0], 1)
    out = AbstractState_update_and_1_out(handle, pq_inputs, [101325.0], [0.0],1, t)
    out_ = AbstractState_update_and_1_out(handle, "PQ_INPUTS", [101325.0], [0.0],1, "T")
    out1, out2, out3, out4, out5 = AbstractState_update_and_5_out(handle, pq_inputs, [101325.0], [0.0],1, [t, t, t, t, t])
    out1_, out2, out3, out4, out5 = AbstractState_update_and_5_out(handle, "PQ_INPUTS", [101325.0], [0.0],1, ["T", "T", "T", "T", "T"])
else
    T = [0.0]; p = [0.0]; rhomolar = [0.0]; hmolar = [0.0]; smolar = [0.0]; temp_=[0.0]; out=[0.0]; out_=[0.0]
    AbstractState_update_and_common_out(handle, pq_inputs, [101325.0], [0.0], 1, T, p, rhomolar, hmolar, smolar)
    AbstractState_update_and_common_out(handle, "PQ_INPUTS", [101325.0], [0.0], 1, temp_, p, rhomolar, hmolar, smolar)
    AbstractState_update_and_1_out(handle, pq_inputs, [101325.0], [0.0],1, t, out)
    AbstractState_update_and_1_out(handle, "PQ_INPUTS", [101325.0], [0.0],1, "T", out_)
    out1=[0.0]; out2=[0.0]; out3=[0.0]; out4=[0.0]; out5=[0.0]; out1_=[0.0]
    AbstractState_update_and_5_out(handle, pq_inputs, [101325.0], [0.0],1, [t, t, t, t, t], out1, out2, out3, out4, out5)
    AbstractState_update_and_5_out(handle, "PQ_INPUTS", [101325.0], [0.0],1, ["T", "T", "T", "T", "T"], out1_, out2, out3, out4, out5)
end
if Sys.isapple()
    @test AbstractState_keyed_output(handle,t) ≈ 352.3522212978604
    @test AbstractState_output(handle,"T") ≈ 352.3522212978604
    @test T[1] ≈ 352.3522212978604
    @test temp_[1] ≈ 352.3522212978604
    @test out[1] ≈ 352.3522212978604
    @test out_[1] ≈ 352.3522212978604
    @test out1[1] ≈ 352.3522212978604
    @test out1_[1] ≈ 352.3522212978604
else
    @test AbstractState_keyed_output(handle,t) ≈ 352.3522212991724
    @test AbstractState_output(handle,"T") ≈ 352.3522212991724
    @test T[1] ≈ 352.3522212991724
    @test temp_[1] ≈ 352.3522212991724
    @test out[1] ≈ 352.3522212991724
    @test out_[1] ≈ 352.3522212991724
    @test out1[1] ≈ 352.3522212991724
    @test out1_[1] ≈ 352.3522212991724
end
for phase in ["phase_liquid", "phase_gas", "phase_twophase", "phase_supercritical", "phase_supercritical_gas", "phase_supercritical_liquid", "phase_critical_point", "phase_unknown", "phase_not_imposed"]
    AbstractState_specify_phase(handle, phase)
end
#AbstractState_set_binary_interaction_double AbstractState_set_fractions
AbstractState_free(handle)
handle = AbstractState_factory("HEOS", "Water&Ethanol")
AbstractState_set_binary_interaction_double(handle, 0, 1, "betaT", 0.987)
pq_inputs = get_input_pair_index("PQ_INPUTS")
t = get_param_index("T")
AbstractState_set_fractions(handle, [0.4, 0.6])
AbstractState_update(handle, pq_inputs, 101325, 0)
res = AbstractState_keyed_output(handle,t)
AbstractState_free(handle)
#AbstractState_set_cubic_alpha_C AbstractState_set_fluid_parameter_double
handle = AbstractState_factory("SRK", "Ethanol")
#AbstractState_set_cubic_alpha_C http://www.cjche.com.cn/EN/article/downloadArticleFile.do?attachType=PDF&id=1635
try
    #do not export on all machines
    AbstractState_set_cubic_alpha_C(handle, 0, "TWU", 1.0, 1.0, 1.0)
catch err
    @warn "AbstractState_set_cubic_alpha_C fails with: $err"
end
AbstractState_set_fluid_parameter_double(handle, 0, "c", 1.0)
AbstractState_free(handle)
if (haskey(ENV, "includelocalwrapper") && ENV["includelocalwrapper"]=="on")
    handle = AbstractState_factory("HEOS", "Water")
    AbstractState_update(handle, "PQ_INPUTS", 15e5, 0)
    @test AbstractState_first_saturation_deriv(handle, get_param_index("Hmolar"), get_param_index("P")) ≈ 0.0025636362140578207
    @test AbstractState_first_partial_deriv(handle, get_param_index("Hmolar"), get_param_index("P"), get_param_index("S")) ≈ 2.07872526058326e-5
    AbstractState_free(handle)
    #envelope
    HEOS=AbstractState_factory("HEOS","Methane&Ethane")
    len=200
    t=zeros(len);p=zeros(len);x=zeros(2*len);y=zeros(2*len);rhomolar_vap=zeros(len);rhomolar_liq=zeros(len);
    tau=zeros(len);delta=zeros(len);m1=zeros(len);
    for x0 in [0.02, 0.2, 0.4, 0.8]
        AbstractState_set_fractions(HEOS, [x0, 1 - x0])
        try
            AbstractState_build_phase_envelope(HEOS, "none")
            AbstractState_get_phase_envelope_data(HEOS, len, t, p, rhomolar_vap, rhomolar_liq, x, y)
            AbstractState_build_spinodal(HEOS)
            AbstractState_get_spinodal_data(HEOS, len, tau, delta, m1)
        catch err
            println("$x0  $err")
        end
    end
    t, p, rhomolar_vap, rhomolar_liq, x, y = AbstractState_get_phase_envelope_data(HEOS, len, 2)
    tau, delta, m1 = AbstractState_get_spinodal_data(HEOS, len)
    rhomolar=zeros(len); stable=zeros(Clong, len)
    t, p, rhomolar, stable = AbstractState_all_critical_points(HEOS, len)
    AbstractState_free(HEOS)
end


text:
# Types for SQL nodes.

abstract type AbstractSQLType
end

Base.show(io::IO, ::MIME"text/plain", t::AbstractSQLType) =
    pprint(io, t)

struct EmptyType <: AbstractSQLType
end

PrettyPrinting.quoteof(::EmptyType) =
    Expr(:call, nameof(EmptyType))

struct ScalarType <: AbstractSQLType
end

PrettyPrinting.quoteof(::ScalarType) =
    Expr(:call, nameof(ScalarType))

struct AmbiguousType <: AbstractSQLType
end

PrettyPrinting.quoteof(::AmbiguousType) =
    Expr(:call, nameof(AmbiguousType))

struct RowType <: AbstractSQLType
    fields::OrderedDict{Symbol, Union{ScalarType, AmbiguousType, RowType}}
    group::Union{EmptyType, AmbiguousType, RowType}

    RowType(fields, group = EmptyType()) =
        new(fields, group)
end

const FieldTypeMap = OrderedDict{Symbol, Union{ScalarType, AmbiguousType, RowType}}
const GroupType = Union{EmptyType, AmbiguousType, RowType}
const HandleTypeMap = Dict{Int, Union{AmbiguousType, RowType}}

RowType() =
    RowType(FieldTypeMap())

RowType(fields::Pair{Symbol, <:AbstractSQLType}...; group = EmptyType()) =
    RowType(FieldTypeMap(fields...), group)

function PrettyPrinting.quoteof(t::RowType)
    ex = Expr(:call, nameof(RowType))
    for (f, ft) in t.fields
        push!(ex.args, Expr(:call, :(=>), QuoteNode(f), quoteof(ft)))
    end
    if !(t.group isa EmptyType)
        push!(ex.args, Expr(:kw, :group, quoteof(t.group)))
    end
    ex
end

struct BoxType <: AbstractSQLType
    name::Symbol
    row::RowType
    handle_map::HandleTypeMap
end

BoxType(name::Symbol, row::RowType) =
    BoxType(name, row, HandleTypeMap())

function BoxType(name::Symbol, fields::Pair{<:Union{Symbol, Int}, <:AbstractSQLType}...; group = EmptyType())
    field_map = FieldTypeMap()
    handle_map = HandleTypeMap()
    for (key, val) in fields
        if key isa Symbol
            field_map[key] = val
        else
            handle_map[key] = val
        end
    end
    BoxType(name, RowType(field_map, group), handle_map)
end

function PrettyPrinting.quoteof(t::BoxType)
    ex = Expr(:call, nameof(BoxType), QuoteNode(t.name))
    for (f, ft) in t.row.fields
        push!(ex.args, Expr(:call, :(=>), QuoteNode(f), quoteof(ft)))
    end
    if !(t.row.group isa EmptyType)
        push!(ex.args, Expr(:kw, :group, quoteof(t.row.group)))
    end
    for (h, ht) in sort!(collect(t.handle_map))
        push!(ex.args, Expr(:call, :(=>), h, quoteof(ht)))
    end
    ex
end

const EMPTY_BOX = BoxType(:_, RowType(), HandleTypeMap())

function add_handle(t::BoxType, handle::Int)
    if handle != 0
        handle_map = copy(t.handle_map)
        handle_map[handle] = t.row
        t = BoxType(t.name, t.row, handle_map)
    end
    t
end

# Type of `Append` (UNION ALL).

Base.intersect(::AbstractSQLType, ::AbstractSQLType) =
    EmptyType()

Base.intersect(::ScalarType, ::ScalarType) =
    ScalarType()

Base.intersect(::AmbiguousType, ::AmbiguousType) =
    AmbiguousType()

function Base.intersect(t1::RowType, t2::RowType)
    if t1 === t2
        return t1
    end
    fields = FieldTypeMap()
    for f in keys(t1.fields)
        if f in keys(t2.fields)
            t = intersect(t1.fields[f], t2.fields[f])
            if !isa(t, EmptyType)
                fields[f] = t
            end
        end
    end
    group = intersect(t1.group, t2.group)
    RowType(fields, group)
end

function Base.intersect(t1::BoxType, t2::BoxType)
    if t1 === t2
        return t1
    end
    handle_map = HandleTypeMap()
    for h in keys(t1.handle_map)
        if h in keys(t2.handle_map)
            t = intersect(t1.handle_map[h], t2.handle_map[h])
            if !(t isa EmptyType)
                handle_map[h] = t
            end
        end
    end
    name = t1.name == t2.name ? t2.name : :union
    BoxType(name, intersect(t1.row, t2.row), handle_map)
end

Base.issubset(::AbstractSQLType, ::AbstractSQLType) =
    false

Base.issubset(::T, ::T) where {T <: AbstractSQLType} =
    true

function Base.issubset(t1::RowType, t2::RowType)
    if t1 === t2
        return true
    end
    for f in keys(t1.fields)
        if !(f in keys(t2.fields) && issubset(t1.fields[f], t2.fields[f]))
            return false
        end
    end
    return true
end

function Base.issubset(t1::BoxType, t2::BoxType)
    if t1 === t2
        return true
    end
    t1.name == t2.name || return false
    issubset(t1.row, t2.row) || return false
    for h in keys(t1.handle_map)
        if !(h in keys(t2.handle_map) && issubset(t1.handle_map[h], t2.handle_map[h]))
            return false
        end
    end
    return true
end

# Type of `Join`.

Base.union(::AbstractSQLType, ::AbstractSQLType) =
    AmbiguousType()

Base.union(::EmptyType, ::EmptyType) =
    EmptyType()

Base.union(::EmptyType, t::AbstractSQLType) =
    t

Base.union(t::AbstractSQLType, ::EmptyType) =
    t

Base.union(::ScalarType, ::ScalarType) =
    ScalarType()

function Base.union(t1::RowType, t2::RowType)
    fields = FieldTypeMap()
    for (f, t) in t1.fields
        if f in keys(t2.fields)
            t′ = t2.fields[f]
            if t isa RowType && t′ isa RowType
                t = union(t, t′)
            else
                t = AmbiguousType()
            end
        end
        fields[f] = t
    end
    for (f, t) in t2.fields
        if !(f in keys(t1.fields))
            fields[f] = t
        end
    end
    if t1.group isa EmptyType
        group = t2.group
    elseif t2.group isa EmptyType
        group = t1.group
    else
        group = AmbiguousType()
    end
    RowType(fields, group)
end

function Base.union(t1::BoxType, t2::BoxType)
    handle_map = HandleTypeMap()
    for l in keys(t1.handle_map)
        if haskey(t2.handle_map, l)
            handle_map[l] = AmbiguousType()
        else
            handle_map[l] = t1.handle_map[l]
        end
    end
    for l in keys(t2.handle_map)
        if !haskey(t1.handle_map, l)
            handle_map[l] = t2.handle_map[l]
        end
    end
    BoxType(t1.name, union(t1.row, t2.row), handle_map)
end


text: # import HTTPClient