text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

mutable struct DiskProperties <: SwaggerModel
    timeCreated::Any # spec type: Union{ Nothing, DateTime } # spec name: timeCreated
    osType::Any # spec type: Union{ Nothing, String } # spec name: osType
    hyperVGeneration::Any # spec type: Union{ Nothing, String } # spec name: hyperVGeneration
    creationData::Any # spec type: Union{ Nothing, CreationData } # spec name: creationData
    diskSizeGB::Any # spec type: Union{ Nothing, Int32 } # spec name: diskSizeGB
    diskSizeBytes::Any # spec type: Union{ Nothing, Int64 } # spec name: diskSizeBytes
    uniqueId::Any # spec type: Union{ Nothing, String } # spec name: uniqueId
    encryptionSettingsCollection::Any # spec type: Union{ Nothing, EncryptionSettingsCollection } # spec name: encryptionSettingsCollection
    provisioningState::Any # spec type: Union{ Nothing, String } # spec name: provisioningState
    diskIOPSReadWrite::Any # spec type: Union{ Nothing, Int64 } # spec name: diskIOPSReadWrite
    diskMBpsReadWrite::Any # spec type: Union{ Nothing, Int64 } # spec name: diskMBpsReadWrite
    diskIOPSReadOnly::Any # spec type: Union{ Nothing, Int64 } # spec name: diskIOPSReadOnly
    diskMBpsReadOnly::Any # spec type: Union{ Nothing, Int64 } # spec name: diskMBpsReadOnly
    diskState::Any # spec type: Union{ Nothing, String } # spec name: diskState
    encryption::Any # spec type: Union{ Nothing, Encryption } # spec name: encryption
    maxShares::Any # spec type: Union{ Nothing, Int32 } # spec name: maxShares
    shareInfo::Any # spec type: Union{ Nothing, Vector{ShareInfoElement} } # spec name: shareInfo
    networkAccessPolicy::Any # spec type: Union{ Nothing, NetworkAccessPolicy } # spec name: networkAccessPolicy
    diskAccessId::Any # spec type: Union{ Nothing, String } # spec name: diskAccessId

    function DiskProperties(;timeCreated=nothing, osType=nothing, hyperVGeneration=nothing, creationData=nothing, diskSizeGB=nothing, diskSizeBytes=nothing, uniqueId=nothing, encryptionSettingsCollection=nothing, provisioningState=nothing, diskIOPSReadWrite=nothing, diskMBpsReadWrite=nothing, diskIOPSReadOnly=nothing, diskMBpsReadOnly=nothing, diskState=nothing, encryption=nothing, maxShares=nothing, shareInfo=nothing, networkAccessPolicy=nothing, diskAccessId=nothing)
        o = new()
        validate_property(DiskProperties, Symbol("timeCreated"), timeCreated)
        setfield!(o, Symbol("timeCreated"), timeCreated)
        validate_property(DiskProperties, Symbol("osType"), osType)
        setfield!(o, Symbol("osType"), osType)
        validate_property(DiskProperties, Symbol("hyperVGeneration"), hyperVGeneration)
        setfield!(o, Symbol("hyperVGeneration"), hyperVGeneration)
        validate_property(DiskProperties, Symbol("creationData"), creationData)
        setfield!(o, Symbol("creationData"), creationData)
        validate_property(DiskProperties, Symbol("diskSizeGB"), diskSizeGB)
        setfield!(o, Symbol("diskSizeGB"), diskSizeGB)
        validate_property(DiskProperties, Symbol("diskSizeBytes"), diskSizeBytes)
        setfield!(o, Symbol("diskSizeBytes"), diskSizeBytes)
        validate_property(DiskProperties, Symbol("uniqueId"), uniqueId)
        setfield!(o, Symbol("uniqueId"), uniqueId)
        validate_property(DiskProperties, Symbol("encryptionSettingsCollection"), encryptionSettingsCollection)
        setfield!(o, Symbol("encryptionSettingsCollection"), encryptionSettingsCollection)
        validate_property(DiskProperties, Symbol("provisioningState"), provisioningState)
        setfield!(o, Symbol("provisioningState"), provisioningState)
        validate_property(DiskProperties, Symbol("diskIOPSReadWrite"), diskIOPSReadWrite)
        setfield!(o, Symbol("diskIOPSReadWrite"), diskIOPSReadWrite)
        validate_property(DiskProperties, Symbol("diskMBpsReadWrite"), diskMBpsReadWrite)
        setfield!(o, Symbol("diskMBpsReadWrite"), diskMBpsReadWrite)
        validate_property(DiskProperties, Symbol("diskIOPSReadOnly"), diskIOPSReadOnly)
        setfield!(o, Symbol("diskIOPSReadOnly"), diskIOPSReadOnly)
        validate_property(DiskProperties, Symbol("diskMBpsReadOnly"), diskMBpsReadOnly)
        setfield!(o, Symbol("diskMBpsReadOnly"), diskMBpsReadOnly)
        validate_property(DiskProperties, Symbol("diskState"), diskState)
        setfield!(o, Symbol("diskState"), diskState)
        validate_property(DiskProperties, Symbol("encryption"), encryption)
        setfield!(o, Symbol("encryption"), encryption)
        validate_property(DiskProperties, Symbol("maxShares"), maxShares)
        setfield!(o, Symbol("maxShares"), maxShares)
        validate_property(DiskProperties, Symbol("shareInfo"), shareInfo)
        setfield!(o, Symbol("shareInfo"), shareInfo)
        validate_property(DiskProperties, Symbol("networkAccessPolicy"), networkAccessPolicy)
        setfield!(o, Symbol("networkAccessPolicy"), networkAccessPolicy)
        validate_property(DiskProperties, Symbol("diskAccessId"), diskAccessId)
        setfield!(o, Symbol("diskAccessId"), diskAccessId)
        o
    end
end # type DiskProperties

const _property_map_DiskProperties = Dict{Symbol,Symbol}(Symbol("timeCreated")=>Symbol("timeCreated"), Symbol("osType")=>Symbol("osType"), Symbol("hyperVGeneration")=>Symbol("hyperVGeneration"), Symbol("creationData")=>Symbol("creationData"), Symbol("diskSizeGB")=>Symbol("diskSizeGB"), Symbol("diskSizeBytes")=>Symbol("diskSizeBytes"), Symbol("uniqueId")=>Symbol("uniqueId"), Symbol("encryptionSettingsCollection")=>Symbol("encryptionSettingsCollection"), Symbol("provisioningState")=>Symbol("provisioningState"), Symbol("diskIOPSReadWrite")=>Symbol("diskIOPSReadWrite"), Symbol("diskMBpsReadWrite")=>Symbol("diskMBpsReadWrite"), Symbol("diskIOPSReadOnly")=>Symbol("diskIOPSReadOnly"), Symbol("diskMBpsReadOnly")=>Symbol("diskMBpsReadOnly"), Symbol("diskState")=>Symbol("diskState"), Symbol("encryption")=>Symbol("encryption"), Symbol("maxShares")=>Symbol("maxShares"), Symbol("shareInfo")=>Symbol("shareInfo"), Symbol("networkAccessPolicy")=>Symbol("networkAccessPolicy"), Symbol("diskAccessId")=>Symbol("diskAccessId"))
const _property_types_DiskProperties = Dict{Symbol,String}(Symbol("timeCreated")=>"DateTime", Symbol("osType")=>"String", Symbol("hyperVGeneration")=>"String", Symbol("creationData")=>"CreationData", Symbol("diskSizeGB")=>"Int32", Symbol("diskSizeBytes")=>"Int64", Symbol("uniqueId")=>"String", Symbol("encryptionSettingsCollection")=>"EncryptionSettingsCollection", Symbol("provisioningState")=>"String", Symbol("diskIOPSReadWrite")=>"Int64", Symbol("diskMBpsReadWrite")=>"Int64", Symbol("diskIOPSReadOnly")=>"Int64", Symbol("diskMBpsReadOnly")=>"Int64", Symbol("diskState")=>"String", Symbol("encryption")=>"Encryption", Symbol("maxShares")=>"Int32", Symbol("shareInfo")=>"Vector{ShareInfoElement}", Symbol("networkAccessPolicy")=>"NetworkAccessPolicy", Symbol("diskAccessId")=>"String")
Base.propertynames(::Type{ DiskProperties }) = collect(keys(_property_map_DiskProperties))
Swagger.property_type(::Type{ DiskProperties }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_DiskProperties[name]))}
Swagger.field_name(::Type{ DiskProperties }, property_name::Symbol) =  _property_map_DiskProperties[property_name]

const _allowed_DiskProperties_osType = ["Windows", "Linux"]

const _allowed_DiskProperties_hyperVGeneration = ["V1", "V2"]

const _allowed_DiskProperties_diskState = ["Unattached", "Attached", "Reserved", "ActiveSAS", "ReadyToUpload", "ActiveUpload"]

function check_required(o::DiskProperties)
    (getproperty(o, Symbol("creationData")) === nothing) && (return false)
    true
end

function validate_property(::Type{ DiskProperties }, name::Symbol, val)
    if name === Symbol("osType")
        Swagger.validate_param(name, "DiskProperties", :enum, val, _allowed_DiskProperties_osType)
    end
    if name === Symbol("hyperVGeneration")
        Swagger.validate_param(name, "DiskProperties", :enum, val, _allowed_DiskProperties_hyperVGeneration)
    end
    if name === Symbol("diskState")
        Swagger.validate_param(name, "DiskProperties", :enum, val, _allowed_DiskProperties_diskState)
    end
end


text:
###############################################################################
#
#   Integers / Integer
#
###############################################################################

mutable struct Integers{T <: Integer} <: Ring
   function Integers{T}() where T <: Integer
      if haskey(IntegersID, T)
         z = IntegersID[T]::Integers{T}
      else
         z = new{T}()
         IntegersID[T] = z
      end
      return z
   end
end

const IntegersID = Dict{DataType, Ring}()

###############################################################################
#
#   Rationals / Rational
#
###############################################################################

mutable struct Rationals{T <: Integer} <: Field
   function Rationals{T}() where T <: Integer
      if haskey(RationalsID, T)
         z = RationalsID[T]::Rationals{T}
      else
         z = new{T}()
         RationalsID[T] = z
      end
      return z
   end
end

const RationalsID = Dict{DataType, Ring}()

###############################################################################
#
#   Floats / AbstractFloat
#
###############################################################################

mutable struct Floats{T <: AbstractFloat} <: Field
   function Floats{T}() where T <: AbstractFloat
      if haskey(FloatsID, T)
         z = FloatsID[T]::Floats{T}
      else
         z = new{T}()
         FloatsID[T] = z
      end
      return z
   end
end

const FloatsID = Dict{DataType, Field}()

###############################################################################
#
#   GFField/gfelem
#
###############################################################################

mutable struct GFField{T <: Integer} <: FinField
   p::T

   function GFField{T}(p::T) where T <: Integer
      if haskey(GFFieldID, (T, p))
         z = GFFieldID[T, p]::GFField{T}
      else
         z = new{T}(p)
         GFFieldID[T, p] = z
      end
      return z
   end
end

const GFFieldID = Dict{Tuple{DataType, Integer}, Field}()

struct gfelem{T <: Integer} <: FinFieldElem
   d::T
   parent::GFField{T}
end

###############################################################################
#
#   Unions of Nemo abstract types and Julia types
#
###############################################################################

const RingElement = Union{RingElem, Integer, Rational, AbstractFloat}

const FieldElement = Union{FieldElem, Rational, AbstractFloat}

ext: jl


text:
const CUDNN_DIM_MAX = 8
const CUDNN_LRN_MIN_N = 1
const CUDNN_LRN_MAX_N = 16
const CUDNN_LRN_MIN_K = 1.0e-5
const CUDNN_LRN_MIN_BETA = 0.01
const CUDNN_BN_MIN_EPSILON = 1.0e-5

mutable struct cudnnContext
end

const cudnnHandle_t = Ptr{cudnnContext}

# begin enum cudnnStatus_t
const cudnnStatus_t = UInt32
const CUDNN_STATUS_SUCCESS = (UInt32)(0)
const CUDNN_STATUS_NOT_INITIALIZED = (UInt32)(1)
const CUDNN_STATUS_ALLOC_FAILED = (UInt32)(2)
const CUDNN_STATUS_BAD_PARAM = (UInt32)(3)
const CUDNN_STATUS_INTERNAL_ERROR = (UInt32)(4)
const CUDNN_STATUS_INVALID_VALUE = (UInt32)(5)
const CUDNN_STATUS_ARCH_MISMATCH = (UInt32)(6)
const CUDNN_STATUS_MAPPING_ERROR = (UInt32)(7)
const CUDNN_STATUS_EXECUTION_FAILED = (UInt32)(8)
const CUDNN_STATUS_NOT_SUPPORTED = (UInt32)(9)
const CUDNN_STATUS_LICENSE_ERROR = (UInt32)(10)
# end enum cudnnStatus_t

mutable struct cudnnTensorStruct
end

const cudnnTensorDescriptor_t = Ptr{cudnnTensorStruct}

mutable struct cudnnConvolutionStruct
end

const cudnnConvolutionDescriptor_t = Ptr{cudnnConvolutionStruct}

mutable struct cudnnPoolingStruct
end

const cudnnPoolingDescriptor_t = Ptr{cudnnPoolingStruct}

mutable struct cudnnFilterStruct
end

const cudnnFilterDescriptor_t = Ptr{cudnnFilterStruct}

mutable struct cudnnLRNStruct
end

const cudnnLRNDescriptor_t = Ptr{cudnnLRNStruct}

mutable struct cudnnActivationStruct
end

const cudnnActivationDescriptor_t = Ptr{cudnnActivationStruct}

# begin enum cudnnDataType_t
const cudnnDataType_t = UInt32
const CUDNN_DATA_FLOAT = (UInt32)(0)
const CUDNN_DATA_DOUBLE = (UInt32)(1)
const CUDNN_DATA_HALF = (UInt32)(2)
# end enum cudnnDataType_t

# begin enum cudnnNanPropagation_t
const cudnnNanPropagation_t = UInt32
const CUDNN_NOT_PROPAGATE_NAN = (UInt32)(0)
const CUDNN_PROPAGATE_NAN = (UInt32)(1)
# end enum cudnnNanPropagation_t

# begin enum cudnnTensorFormat_t
const cudnnTensorFormat_t = UInt32
const CUDNN_TENSOR_NCHW = (UInt32)(0)
const CUDNN_TENSOR_NHWC = (UInt32)(1)
# end enum cudnnTensorFormat_t

# begin enum cudnnAddMode_t
const cudnnAddMode_t = UInt32
const CUDNN_ADD_IMAGE = (UInt32)(0)
const CUDNN_ADD_SAME_HW = (UInt32)(0)
const CUDNN_ADD_FEATURE_MAP = (UInt32)(1)
const CUDNN_ADD_SAME_CHW = (UInt32)(1)
const CUDNN_ADD_SAME_C = (UInt32)(2)
const CUDNN_ADD_FULL_TENSOR = (UInt32)(3)
# end enum cudnnAddMode_t

# begin enum cudnnConvolutionMode_t
const cudnnConvolutionMode_t = UInt32
const CUDNN_CONVOLUTION = (UInt32)(0)
const CUDNN_CROSS_CORRELATION = (UInt32)(1)
# end enum cudnnConvolutionMode_t

# begin enum cudnnConvolutionFwdPreference_t
const cudnnConvolutionFwdPreference_t = UInt32
const CUDNN_CONVOLUTION_FWD_NO_WORKSPACE = (UInt32)(0)
const CUDNN_CONVOLUTION_FWD_PREFER_FASTEST = (UInt32)(1)
const CUDNN_CONVOLUTION_FWD_SPECIFY_WORKSPACE_LIMIT = (UInt32)(2)
# end enum cudnnConvolutionFwdPreference_t

# begin enum cudnnConvolutionFwdAlgo_t
const cudnnConvolutionFwdAlgo_t = UInt32
const CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_GEMM = (UInt32)(0)
const CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_PRECOMP_GEMM = (UInt32)(1)
const CUDNN_CONVOLUTION_FWD_ALGO_GEMM = (UInt32)(2)
const CUDNN_CONVOLUTION_FWD_ALGO_DIRECT = (UInt32)(3)
const CUDNN_CONVOLUTION_FWD_ALGO_FFT = (UInt32)(4)
const CUDNN_CONVOLUTION_FWD_ALGO_FFT_TILING = (UInt32)(5)
# end enum cudnnConvolutionFwdAlgo_t

mutable struct cudnnConvolutionFwdAlgoPerf_t
    algo::cudnnConvolutionFwdAlgo_t
    status::cudnnStatus_t
    time::Cfloat
    memory::Cint
end

# begin enum cudnnConvolutionBwdFilterPreference_t
const cudnnConvolutionBwdFilterPreference_t = UInt32
const CUDNN_CONVOLUTION_BWD_FILTER_NO_WORKSPACE = (UInt32)(0)
const CUDNN_CONVOLUTION_BWD_FILTER_PREFER_FASTEST = (UInt32)(1)
const CUDNN_CONVOLUTION_BWD_FILTER_SPECIFY_WORKSPACE_LIMIT = (UInt32)(2)
# end enum cudnnConvolutionBwdFilterPreference_t

# begin enum cudnnConvolutionBwdFilterAlgo_t
const cudnnConvolutionBwdFilterAlgo_t = UInt32
const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_0 = (UInt32)(0)
const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_1 = (UInt32)(1)
const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_FFT = (UInt32)(2)
const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_3 = (UInt32)(3)
# end enum cudnnConvolutionBwdFilterAlgo_t

mutable struct cudnnConvolutionBwdFilterAlgoPerf_t
    algo::cudnnConvolutionBwdFilterAlgo_t
    status::cudnnStatus_t
    time::Cfloat
    memory::Cint
end

# begin enum cudnnConvolutionBwdDataPreference_t
const cudnnConvolutionBwdDataPreference_t = UInt32
const CUDNN_CONVOLUTION_BWD_DATA_NO_WORKSPACE = (UInt32)(0)
const CUDNN_CONVOLUTION_BWD_DATA_PREFER_FASTEST = (UInt32)(1)
const CUDNN_CONVOLUTION_BWD_DATA_SPECIFY_WORKSPACE_LIMIT = (UInt32)(2)
# end enum cudnnConvolutionBwdDataPreference_t

# begin enum cudnnConvolutionBwdDataAlgo_t
const cudnnConvolutionBwdDataAlgo_t = UInt32
const CUDNN_CONVOLUTION_BWD_DATA_ALGO_0 = (UInt32)(0)
const CUDNN_CONVOLUTION_BWD_DATA_ALGO_1 = (UInt32)(1)
const CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT = (UInt32)(2)
const CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT_TILING = (UInt32)(3)
# end enum cudnnConvolutionBwdDataAlgo_t

mutable struct cudnnConvolutionBwdDataAlgoPerf_t
    algo::cudnnConvolutionBwdDataAlgo_t
    status::cudnnStatus_t
    time::Cfloat
    memory::Cint
end

# begin enum cudnnSoftmaxAlgorithm_t
const cudnnSoftmaxAlgorithm_t = UInt32
const CUDNN_SOFTMAX_FAST = (UInt32)(0)
const CUDNN_SOFTMAX_ACCURATE = (UInt32)(1)
const CUDNN_SOFTMAX_LOG = (UInt32)(2)
# end enum cudnnSoftmaxAlgorithm_t

# begin enum cudnnSoftmaxMode_t
const cudnnSoftmaxMode_t = UInt32
const CUDNN_SOFTMAX_MODE_INSTANCE = (UInt32)(0)
const CUDNN_SOFTMAX_MODE_CHANNEL = (UInt32)(1)
# end enum cudnnSoftmaxMode_t

# begin enum cudnnPoolingMode_t
const cudnnPoolingMode_t = UInt32
const CUDNN_POOLING_MAX = (UInt32)(0)
const CUDNN_POOLING_AVERAGE_COUNT_INCLUDE_PADDING = (UInt32)(1)
const CUDNN_POOLING_AVERAGE_COUNT_EXCLUDE_PADDING = (UInt32)(2)
# end enum cudnnPoolingMode_t

# begin enum cudnnActivationMode_t
const cudnnActivationMode_t = UInt32
const CUDNN_ACTIVATION_SIGMOID = (UInt32)(0)
const CUDNN_ACTIVATION_RELU = (UInt32)(1)
const CUDNN_ACTIVATION_TANH = (UInt32)(2)
const CUDNN_ACTIVATION_CLIPPED_RELU = (UInt32)(3)
const CUDNN_ACTIVATION_ELU = (UInt32)(4)
const CUDNN_ACTIVATION_IDENTITY = (UInt32)(5)
# end enum cudnnActivationMode_t

# begin enum cudnnLRNMode_t
const cudnnLRNMode_t = UInt32
const CUDNN_LRN_CROSS_CHANNEL_DIM1 = (UInt32)(0)
# end enum cudnnLRNMode_t

# begin enum cudnnDivNormMode_t
const cudnnDivNormMode_t = UInt32
const CUDNN_DIVNORM_PRECOMPUTED_MEANS = (UInt32)(0)
# end enum cudnnDivNormMode_t

# begin enum cudnnBatchNormMode_t
const cudnnBatchNormMode_t = UInt32
const CUDNN_BATCHNORM_PER_ACTIVATION = (UInt32)(0)
const CUDNN_BATCHNORM_SPATIAL = (UInt32)(1)
# end enum cudnnBatchNormMode_t

# begin enum cudnnMathType_t
const cudnnMathType_t = UInt32
const CUDNN_DEFAULT_MATH                    = 0
const CUDNN_TENSOR_OP_MATH                  = 1
const CUDNN_TENSOR_OP_MATH_ALLOW_CONVERSION = 2
# end enum cudnnMathType_t


text:
using LightGraphs
using LightGraphsFlows

flow_graph = DiGraph(4) # Create a flow graph
flow_edges = [
    (1,2,10),(1,3,5),(1,4,15),(2,3,4),(2,5,9),
    (2,6,15),(3,4,4),(3,6,8),(4,7,16),(5,6,15),
    (5,8,10),(6,7,15),(6,8,10),(7,3,6),(7,8,10)
]

capacity_matrix = zeros(Int, 8, 8)  # Create a capacity matrix

for e in flow_edges
    u, v, f = e
    add_edge!(flow_graph, u, v)
    capacity_matrix[u,v] = f
end

f, F = maximum_flow(flow_graph, 1, 8, capacity_matrix) # Run


text:
# asymmetric test kasa method
for _ in 1:10
    local x0 = 10*rand()
    local y0 = 10*rand()
    local r = rand()+1
    local x = r.*[-1.0,0,0,1,sqrt(2)/2,sqrt(2)/2] .+ x0
    local y = r.*[0.0,1,-1,0,sqrt(2)/2,-sqrt(2)/2] .+ y0
    coefs = CircleFit.kasa(x,y)
    @test x0 ≈ coefs[1]
    @test y0 ≈ coefs[2]
    @test r ≈ coefs[3]
end

# symmetric test kasa method
for _ in 1:10
    local x0 = 10*rand()
    local y0 = 10*rand()
    local r = rand()+1
    local x = r.*[-1.0,0,0,1] .+ x0
    local y = r.*[0.0,1,-1,0] .+ y0
    coefs = CircleFit.kasa(x,y)
    @test x0 ≈ coefs[1]
    @test y0 ≈ coefs[2]
    @test r ≈ coefs[3]
end


text:
module RigidBodyTools

export Body

const NDIM = 2
const CHUNK = 3*(NDIM-1)

abstract type BodyClosureType end
abstract type OpenBody <: BodyClosureType end
abstract type ClosedBody <: BodyClosureType end

abstract type PointShiftType end
abstract type Unshifted <: PointShiftType end
abstract type Shifted <: PointShiftType end

abstract type Body{N,C<:BodyClosureType} end

numpts(::Body{N}) where {N} = N
numpts(::Nothing) = 0

include("rigidbodymotions.jl")
include("directmotions.jl")
include("kinematics.jl")

include("rigidtransform.jl")
include("bodylist.jl")

include("tools.jl")
include("assignvelocity.jl")
include("shapes.jl")

include("plot_recipes.jl")

end


text:
module RocketMinOperatorTest

using Test
using Rocket

include("../test_helpers.jl")

@testset "operator: min()" begin

    println("Testing: operator min()")

    run_proxyshowcheck("Min", min())

    run_testset([
        (
            source      = from(1:42) |> min(),
            values      = @ts([ 1, c ]),
            source_type = Union{Int, Nothing}
        ),
        (
            source      = from(1:42) |> min(from = -100),
            values      = @ts([ -100, c ]),
            source_type = Union{Int, Nothing}
        ),
        (
            source      = from(1:42) |> min() |> some(),
            values      = @ts([ 1, c ]),
            source_type = Int
        ),
        (
            source      = completed(Int) |> min(),
            values      = @ts([ nothing, c ]),
            source_type = Union{Int, Nothing}
        ),
        (
            source      = faulted(String, "e") |> min(),
            values      = @ts(e("e")),
            source_type = Union{Nothing, String}
        ),
        (
            source = never() |> min(),
            values = @ts()
        )
    ])

end

end


text:
# This is part of Calendars.jl. See the copyright note there.
# ======================== DayNumbers =======================

# The fix day number of CE 1582-10-15.
const GregorysBreak = DPart(577736)
const JDN_DN  = DPart(1721425)
const DN_MJDN = DPart(678576)

# Days considered here start at midnight 00:00.

# Convert a fix day number to a Julian day number.
# If mod = true return the modified Julian day number.
# (which has epoch CE 1858-11-17, 00:00 UT).
function FixNumToJulianNum(rd::DPart, mod=false)
    if mod
        return rd - DN_MJDN
    else
        return rd + JDN_DN
    end
end

# Convert a Julian day number to a fix day number.
# If mod = true assume a modified Julian day number.
function JulianNumToFixNum(jdn::DPart, mod=false)
    if mod
        return jdn + DN_MJDN
    else
        return jdn - JDN_DN
    end
end

# Convert a fix day number to an European day number.
FixNumToEuroNum(fn::DPart) = fn + 2

# Convert an European day number to a fix day number.
EuroNumToFixNum(en::DPart) = en - 2

"""
Convert a Julian day number to an European day number.
```julia
julia> JulianNumToEuroNum(2440422)
```
The European day number of the first crewed moon landing (Apollo 11) is EN#719000.
"""
JulianNumToEuroNum(jn::DPart) = jn - JDN_DN + 2

"""
Convert an European day number to an Julian day number.
```julia
julia> EuroNumToJulianNum(719000)
```
The Julian day number of the first crewed moon landing (Apollo 11) is JN#2440422.
"""
EuroNumToJulianNum(en::DPart) = en + JDN_DN - 2


text:
struct ReifiedBridge{T, B<:MOIBC.SetMapBridge{T}, A, S} <: MOIBC.AbstractBridge
    con_idx::CI
end

function MOI.supports_constraint(
    ::Type{<:ReifiedBridge{T, B}},
    ::Type{F},
    ::Type{<:CS.ReifiedSet{A,S}}
) where {T, B, F<:MOI.VectorAffineFunction, A, S}
    is_supported = MOI.supports_constraint(B, MOIU.scalar_type(F), S)
    !is_supported && return false
    S <: BoolSet && return true

    concrete_B = MOIBC.concrete_bridge_type(B, MOI.ScalarAffineFunction{T}, S)
    return supports_concreteB(concrete_B)
end

function MOIBC.concrete_bridge_type(
    ::Type{<:ReifiedBridge{T,B}},
    G::Type{<:MOI.VectorAffineFunction},
    ::Type{IS},
) where {T,B,A,S,IS<:CS.ReifiedSet{A,S}}
    if S <: BoolSet
        concrete_B = B
    else
        concrete_B = MOIBC.concrete_bridge_type(B, MOI.ScalarAffineFunction{T}, S)
    end
    return ReifiedBridge{T,concrete_B,A,S}
end

function MOIB.added_constraint_types(
    ::Type{<:ReifiedBridge{T,B,A,S}}
) where {T,B,A,S}
    if S <: BoolSet
        added_constraints = added_constraint_types(B, S)
    else
        added_constraints = MOIB.added_constraint_types(B)
    end
    return [(MOI.VectorAffineFunction{T}, CS.ReifiedSet{A,added_constraints[1][2]})]
end

function MOIB.added_constrained_variable_types(::Type{<:ReifiedBridge{T,B}}) where {T,B}
    return MOIB.added_constrained_variable_types(B)
end

function MOIBC.bridge_constraint(::Type{<:ReifiedBridge{T, B, A, S}}, model, func, set) where {T, B, A, S}
    f = MOIU.eachscalar(func)
    if S <: BoolSet
        new_func = MOIU.operate(vcat, T, f[1], map_function(B, f[2:end], set.set))
        new_inner_set = map_set(B, set.set)
    else
        new_func = MOIU.operate(vcat, T, f[1], MOIBC.map_function(B, f[2:end]))
        new_inner_set = MOIBC.map_set(B, set.set)
    end
    new_set = CS.ReifiedSet{A,typeof(new_inner_set)}(new_inner_set, 1+MOI.dimension(new_inner_set))
    return ReifiedBridge{T,B,A,S}(MOI.add_constraint(model, new_func, new_set))
end


text:
@static if Base.VERSION >= v"1.6"
    using TOML
    using Test
else
    using Pkg: TOML
    using Test
end

# To generate the new UUID, we simply modify the first character of the original UUID
const original_uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
const new_uuid      = "e43a241f-c20a-4ad4-852c-f6b1247861c6"

# `@__DIR__` is the `.ci/` folder.
# Therefore, `dirname(@__DIR__)` is the repository root.
const project_filename = joinpath(dirname(@__DIR__), "Project.toml")

@testset "Test that the UUID is unchanged" begin
    project_dict = TOML.parsefile(project_filename)
    @test project_dict["uuid"] == original_uuid
end

write(
    project_filename,
    replace(
        read(project_filename, String),
        r"uuid = .*?\n" => "uuid = \"$(new_uuid)\"\n",
    ),
)


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

"""
    CreateDataset()

Creates a new dataset in an Amazon Lookout for Vision project. CreateDataset can create a training or a test dataset from a valid dataset source (DatasetSource). If you want a single dataset project, specify train for the value of DatasetType. To have a project with separate training and test datasets, call CreateDataset twice. On the first call, specify train for the value of DatasetType. On the second call, specify test for the value of DatasetType. of dataset with

# Required Parameters
- `DatasetType`: The type of the dataset. Specify train for a training dataset. Specify test for a test dataset.
- `projectName`: The name of the project in which you want to create a dataset.

# Optional Parameters
- `DatasetSource`: The location of the manifest file that Amazon Lookout for Vision uses to create the dataset. If you don't specify DatasetSource, an empty dataset is created and the operation synchronously returns. Later, you can add JSON Lines by calling UpdateDatasetEntries.  If you specify a value for DataSource, the manifest at the S3 location is validated and used to create the dataset. The call to CreateDataset is asynchronous and might take a while to complete. To find out the current status, Check the value of Status returned in a call to DescribeDataset.
- `X-Amzn-Client-Token`: ClientToken is an idempotency token that ensures a call to CreateDataset completes only once. You choose the value to pass. For example, An issue, such as an network outage, might prevent you from getting a response from CreateDataset. In this case, safely retry your call to CreateDataset by using the same ClientToken parameter value. An error occurs if the other input parameters are not the same as in the first request. Using a different value for ClientToken is considered a new call to CreateDataset. An idempotency token is active for 8 hours.
"""
create_dataset(DatasetType, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects/$(projectName)/datasets", Dict{String, Any}("DatasetType"=>DatasetType, "X-Amzn-Client-Token"=>string(uuid4())); aws_config=aws_config)
create_dataset(DatasetType, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects/$(projectName)/datasets", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DatasetType"=>DatasetType, "X-Amzn-Client-Token"=>string(uuid4())), args)); aws_config=aws_config)

"""
    CreateModel()

Creates a new version of a model within an an Amazon Lookout for Vision project. CreateModel is an asynchronous operation in which Amazon Lookout for Vision trains, tests, and evaluates a new version of a model.  To get the current status, check the Status field returned in the response from DescribeModel. If the project has a single dataset, Amazon Lookout for Vision internally splits the dataset to create a training and a test dataset. If the project has a training and a test dataset, Lookout for Vision uses the respective datasets to train and test the model.  After training completes, the evaluation metrics are stored at the location specified in OutputConfig.

# Required Parameters
- `OutputConfig`: The location where Amazon Lookout for Vision saves the training results.
- `projectName`: The name of the project in which you want to create a model version.

# Optional Parameters
- `Description`: A description for the version of the model.
- `KmsKeyId`: The identifier of the AWS Key Management Service (AWS KMS) customer master key (CMK) to use for encypting the model. If this parameter is not specified, the model is encrypted by a key that AWS owns and manages.
- `X-Amzn-Client-Token`: ClientToken is an idempotency token that ensures a call to CreateModel completes only once. You choose the value to pass. For example, An issue, such as an network outage, might prevent you from getting a response from CreateModel. In this case, safely retry your call to CreateModel by using the same ClientToken parameter value. An error occurs if the other input parameters are not the same as in the first request. Using a different value for ClientToken is considered a new call to CreateModel. An idempotency token is active for 8 hours.
"""
create_model(OutputConfig, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects/$(projectName)/models", Dict{String, Any}("OutputConfig"=>OutputConfig, "X-Amzn-Client-Token"=>string(uuid4())); aws_config=aws_config)
create_model(OutputConfig, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects/$(projectName)/models", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("OutputConfig"=>OutputConfig, "X-Amzn-Client-Token"=>string(uuid4())), args)); aws_config=aws_config)

"""
    CreateProject()

Creates an empty Amazon Lookout for Vision project. After you create the project, add a dataset by calling CreateDataset.

# Required Parameters
- `ProjectName`: S nsme for the project.

# Optional Parameters
- `X-Amzn-Client-Token`: ClientToken is an idempotency token that ensures a call to CreateProject completes only once. You choose the value to pass. For example, An issue, such as an network outage, might prevent you from getting a response from CreateProject. In this case, safely retry your call to CreateProject by using the same ClientToken parameter value. An error occurs if the other input parameters are not the same as in the first request. Using a different value for ClientToken is considered a new call to CreateProject. An idempotency token is active for 8 hours.
"""
create_project(ProjectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects", Dict{String, Any}("ProjectName"=>ProjectName, "X-Amzn-Client-Token"=>string(uuid4())); aws_config=aws_config)
create_project(ProjectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ProjectName"=>ProjectName, "X-Amzn-Client-Token"=>string(uuid4())), args)); aws_config=aws_config)

"""
    DeleteDataset()

Deletes an existing Amazon Lookout for Vision dataset.  If your the project has a single dataset, you must create a new dataset before you can create a model. If you project has a training dataset and a test dataset consider the following.    If you delete the test dataset, your project reverts to a single dataset project. If you then train the model, Amazon Lookout for Vision internally splits the remaining dataset into a training and test dataset.   If you delete the training dataset, you must create a training dataset before you can create a model.   It might take a while to delete the dataset. To check the current status, check the Status field in the response from a call to DescribeDataset.

# Required Parameters
- `datasetType`: The type of the dataset to delete. Specify train to delete the training dataset. Specify test to delete the test dataset. To delete the dataset in a single dataset project, specify train.
- `projectName`: The name of the project that contains the dataset that you want to delete.

# Optional Parameters
- `X-Amzn-Client-Token`: ClientToken is an idempotency token that ensures a call to DeleteDataset completes only once. You choose the value to pass. For example, An issue, such as an network outage, might prevent you from getting a response from DeleteDataset. In this case, safely retry your call to DeleteDataset by using the same ClientToken parameter value. An error occurs if the other input parameters are not the same as in the first request. Using a different value for ClientToken is considered a new call to DeleteDataset. An idempotency token is active for 8 hours.
"""
delete_dataset(datasetType, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("DELETE", "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)", Dict{String, Any}("X-Amzn-Client-Token"=>string(uuid4())); aws_config=aws_config)
delete_dataset(datasetType, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("DELETE", "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("X-Amzn-Client-Token"=>string(uuid4())), args)); aws_config=aws_config)

"""
    DeleteModel()

Deletes an Amazon Lookout for Vision model. You can't delete a running model. To stop a running model, use the StopModel operation.

# Required Parameters
- `modelVersion`: The version of the model that you want to delete.
- `projectName`: The name of the project that contains the model that you want to delete.

# Optional Parameters
- `X-Amzn-Client-Token`: ClientToken is an idempotency token that ensures a call to DeleteModel completes only once. You choose the value to pass. For example, An issue, such as an network outage, might prevent you from getting a response from DeleteModel. In this case, safely retry your call to DeleteModel by using the same ClientToken parameter value. An error occurs if the other input parameters are not the same as in the first request. Using a different value for ClientToken is considered a new call to DeleteModel. An idempotency token is active for 8 hours.
"""
delete_model(modelVersion, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("DELETE", "/2020-11-20/projects/$(projectName)/models/$(modelVersion)", Dict{String, Any}("X-Amzn-Client-Token"=>string(uuid4())); aws_config=aws_config)
delete_model(modelVersion, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("DELETE", "/2020-11-20/projects/$(projectName)/models/$(modelVersion)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("X-Amzn-Client-Token"=>string(uuid4())), args)); aws_config=aws_config)

"""
    DeleteProject()

Deletes an Amazon Lookout for Vision project. To delete a project, you must first delete each version of the model associated with the project. To delete a model use the DeleteModel operation. The training and test datasets are deleted automatically for you. The images referenced by the training and test datasets aren't deleted.

# Required Parameters
- `projectName`: The name of the project to delete.

# Optional Parameters
- `X-Amzn-Client-Token`: ClientToken is an idempotency token that ensures a call to DeleteProject completes only once. You choose the value to pass. For example, An issue, such as an network outage, might prevent you from getting a response from DeleteProject. In this case, safely retry your call to DeleteProject by using the same ClientToken parameter value. An error occurs if the other input parameters are not the same as in the first request. Using a different value for ClientToken is considered a new call to DeleteProject. An idempotency token is active for 8 hours.
"""
delete_project(projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("DELETE", "/2020-11-20/projects/$(projectName)", Dict{String, Any}("X-Amzn-Client-Token"=>string(uuid4())); aws_config=aws_config)
delete_project(projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("DELETE", "/2020-11-20/projects/$(projectName)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("X-Amzn-Client-Token"=>string(uuid4())), args)); aws_config=aws_config)

"""
    DescribeDataset()

Describe an Amazon Lookout for Vision dataset.

# Required Parameters
- `datasetType`: The type of the dataset to describe. Specify train to describe the training dataset. Specify test to describe the test dataset. If you have a single dataset project, specify train
- `projectName`: The name of the project that contains the dataset that you want to describe.

"""
describe_dataset(datasetType, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)"; aws_config=aws_config)
describe_dataset(datasetType, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)", args; aws_config=aws_config)

"""
    DescribeModel()

Describes a version of an Amazon Lookout for Vision model.

# Required Parameters
- `modelVersion`: The version of the model that you want to describe.
- `projectName`: The project that contains the version of a model that you want to describe.

"""
describe_model(modelVersion, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects/$(projectName)/models/$(modelVersion)"; aws_config=aws_config)
describe_model(modelVersion, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects/$(projectName)/models/$(modelVersion)", args; aws_config=aws_config)

"""
    DescribeProject()

Describes an Amazon Lookout for Vision project.

# Required Parameters
- `projectName`: The name of the project that you want to describe.

"""
describe_project(projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects/$(projectName)"; aws_config=aws_config)
describe_project(projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects/$(projectName)", args; aws_config=aws_config)

"""
    DetectAnomalies()

Detects anomalies in an image that you supply.  The response from DetectAnomalies includes a boolean prediction that the image contains one or more anomalies and a confidence value for the prediction.  Before calling DetectAnomalies, you must first start your model with the StartModel operation. You are charged for the amount of time, in minutes, that a model runs and for the number of anomaly detection units that your model uses. If you are not using a model, use the StopModel operation to stop your model.

# Required Parameters
- `Body`: The unencrypted image bytes that you want to analyze.
- `content-type`: The type of the image passed in Body. Valid values are image/png (PNG format images) and image/jpeg (JPG format images).
- `modelVersion`: The version of the model that you want to use.
- `projectName`: The name of the project that contains the model version that you want to use.

"""
detect_anomalies(Body, content_type, modelVersion, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/detect", Dict{String, Any}("Body"=>Body, "headers"=>Dict{String, Any}("content-type"=>content_type)); aws_config=aws_config)
detect_anomalies(Body, content_type, modelVersion, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/detect", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Body"=>Body, "headers"=>Dict{String, Any}("content-type"=>content_type)), args)); aws_config=aws_config)

"""
    ListDatasetEntries()

Lists the JSON Lines within a dataset. An Amazon Lookout for Vision JSON Line contains the anomaly information for a single image, including the image location and the assigned label.

# Required Parameters
- `datasetType`: The type of the dataset that you want to list. Specify train to list the training dataset. Specify test to list the test dataset. If you have a single dataset project, specify train.
- `projectName`: The name of the project that contains the dataset that you want to list.

# Optional Parameters
- `anomalyClass`: Specify normal to include only normal images. Specify anomaly to only include anomalous entries. If you don't specify a value, Amazon Lookout for Vision returns normal and anomalous images.
- `createdAfter`: Only includes entries after the specified date in the response. For example, 2020-06-23T00:00:00.
- `createdBefore`: Only includes entries before the specified date in the response. For example, 2020-06-23T00:00:00.
- `labeled`: Specify true to include labeled entries, otherwise specify false. If you don't specify a value, Lookout for Vision returns all entries.
- `maxResults`: The maximum number of results to return per paginated call. The largest value you can specify is 100. If you specify a value greater than 100, a ValidationException error occurs. The default value is 100.
- `nextToken`: If the previous response was incomplete (because there is more data to retrieve), Amazon Lookout for Vision returns a pagination token in the response. You can use this pagination token to retrieve the next set of dataset entries.
- `sourceRefContains`: Perform a \"contains\" search on the values of the source-ref key within the dataset. For example a value of \"IMG_17\" returns all JSON Lines where the source-ref key value matches *IMG_17*.
"""
list_dataset_entries(datasetType, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)/entries"; aws_config=aws_config)
list_dataset_entries(datasetType, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)/entries", args; aws_config=aws_config)

"""
    ListModels()

Lists the versions of a model in an Amazon Lookout for Vision project.

# Required Parameters
- `projectName`: The name of the project that contains the model versions that you want to list.

# Optional Parameters
- `maxResults`: The maximum number of results to return per paginated call. The largest value you can specify is 100. If you specify a value greater than 100, a ValidationException error occurs. The default value is 100.
- `nextToken`: If the previous response was incomplete (because there is more data to retrieve), Amazon Lookout for Vision returns a pagination token in the response. You can use this pagination token to retrieve the next set of models.
"""
list_models(projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects/$(projectName)/models"; aws_config=aws_config)
list_models(projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects/$(projectName)/models", args; aws_config=aws_config)

"""
    ListProjects()

Lists the Amazon Lookout for Vision projects in your AWS account.

# Optional Parameters
- `maxResults`: The maximum number of results to return per paginated call. The largest value you can specify is 100. If you specify a value greater than 100, a ValidationException error occurs. The default value is 100.
- `nextToken`: If the previous response was incomplete (because there is more data to retrieve), Amazon Lookout for Vision returns a pagination token in the response. You can use this pagination token to retrieve the next set of projects.
"""
list_projects(; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects"; aws_config=aws_config)
list_projects(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("GET", "/2020-11-20/projects", args; aws_config=aws_config)

"""
    StartModel()

Starts the running of the version of an Amazon Lookout for Vision model. Starting a model takes a while to complete. To check the current state of the model, use DescribeModel. Once the model is running, you can detect custom labels in new images by calling DetectAnomalies.  You are charged for the amount of time that the model is running. To stop a running model, call StopModel.

# Required Parameters
- `MinInferenceUnits`: The minimum number of inference units to use. A single inference unit represents 1 hour of processing and can support up to 5 Transaction Pers Second (TPS). Use a higher number to increase the TPS throughput of your model. You are charged for the number of inference units that you use.
- `modelVersion`: The version of the model that you want to start.
- `projectName`: The name of the project that contains the model that you want to start.

# Optional Parameters
- `X-Amzn-Client-Token`: ClientToken is an idempotency token that ensures a call to StartModel completes only once. You choose the value to pass. For example, An issue, such as an network outage, might prevent you from getting a response from StartModel. In this case, safely retry your call to StartModel by using the same ClientToken parameter value. An error occurs if the other input parameters are not the same as in the first request. Using a different value for ClientToken is considered a new call to StartModel. An idempotency token is active for 8 hours.
"""
start_model(MinInferenceUnits, modelVersion, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/start", Dict{String, Any}("MinInferenceUnits"=>MinInferenceUnits, "X-Amzn-Client-Token"=>string(uuid4())); aws_config=aws_config)
start_model(MinInferenceUnits, modelVersion, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/start", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("MinInferenceUnits"=>MinInferenceUnits, "X-Amzn-Client-Token"=>string(uuid4())), args)); aws_config=aws_config)

"""
    StopModel()

Stops a running model. The operation might take a while to complete. To check the current status, call DescribeModel.

# Required Parameters
- `modelVersion`: The version of the model that you want to stop.
- `projectName`: The name of the project that contains the model that you want to stop.

# Optional Parameters
- `X-Amzn-Client-Token`: ClientToken is an idempotency token that ensures a call to StopModel completes only once. You choose the value to pass. For example, An issue, such as an network outage, might prevent you from getting a response from StopModel. In this case, safely retry your call to StopModel by using the same ClientToken parameter value. An error occurs if the other input parameters are not the same as in the first request. Using a different value for ClientToken is considered a new call to StopModel. An idempotency token is active for 8 hours.
"""
stop_model(modelVersion, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/stop", Dict{String, Any}("X-Amzn-Client-Token"=>string(uuid4())); aws_config=aws_config)
stop_model(modelVersion, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("POST", "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/stop", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("X-Amzn-Client-Token"=>string(uuid4())), args)); aws_config=aws_config)

"""
    UpdateDatasetEntries()

Adds one or more JSON Line entries to a dataset. A JSON Line includes information about an image used for training or testing an Amazon Lookout for Vision model. The following is an example JSON Line. Updating a dataset might take a while to complete. To check the current status, call DescribeDataset and check the Status field in the response.

# Required Parameters
- `Changes`: The entries to add to the dataset.
- `datasetType`: The type of the dataset that you want to update. Specify train to update the training dataset. Specify test to update the test dataset. If you have a single dataset project, specify train.
- `projectName`: The name of the project that contains the dataset that you want to update.

# Optional Parameters
- `X-Amzn-Client-Token`: ClientToken is an idempotency token that ensures a call to UpdateDatasetEntries completes only once. You choose the value to pass. For example, An issue, such as an network outage, might prevent you from getting a response from UpdateDatasetEntries. In this case, safely retry your call to UpdateDatasetEntries by using the same ClientToken parameter value. An error occurs if the other input parameters are not the same as in the first request. Using a different value for ClientToken is considered a new call to UpdateDatasetEntries. An idempotency token is active for 8 hours.
"""
update_dataset_entries(Changes, datasetType, projectName; aws_config::AWSConfig=global_aws_config()) = lookoutvision("PATCH", "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)/entries", Dict{String, Any}("Changes"=>Changes, "X-Amzn-Client-Token"=>string(uuid4())); aws_config=aws_config)
update_dataset_entries(Changes, datasetType, projectName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = lookoutvision("PATCH", "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)/entries", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Changes"=>Changes, "X-Amzn-Client-Token"=>string(uuid4())), args)); aws_config=aws_config)


text:
using Random;
using FileIO, CSV, Dates;

# load body of this script to save with jld file
function script_content( file_path )
    return open( file_path, "r" ) do this_file
        this_script = read( this_file, String );
    end
end

# define a function to save results
# `args` should be Dict or NamedTuple containing fields
# "outdir" and "filename"
function get_save_function( args; caller_path = @__FILE__, add_timestamp = true )

    this_script = script_content( caller_path );
    fn_rand_str = randstring(8)

    save_results = function(results_df; save_csv = true, save_jld = true)

        if !ispath(args["outdir"])
            try
                mkpath(args["outdir"])
            catch e
                @error "Could not make output path." exception=(e, catch_backtrace())
            end
        end

        if haskey( args, "filename") && args["filename"] != ""
            fn, fext = splitext( args["filename"] )
        else
            fn = "results_$(fn_rand_str)_$(join(size(results_df),"x"))";
            if add_timestamp
                fn = string( fn, "_", Dates.format(now(), "dd_u_Y__HH_MM_SS"))
            end
            fext = "";
        end

        fncsv = (save_csv || lowercase(fext) == ".csv" ) ? string( fn, ".csv" ) : nothing
        fnjld = (save_jld || lowercase(fext) == ".jld2" ) ? string( fn, ".jld2" ) : nothing

        try
            if !isnothing(fnjld)
                jldpath = joinpath(args["outdir"], fnjld);
                println("Saving jld2 results to $(jldpath).")
                save(jldpath, Dict("results" => results_df, "script" => this_script ));
            end
            if !isnothing(fncsv)
                csvpath = joinpath(args["outdir"], fncsv);
                println("Saving csv results $(csvpath).")
                CSV.write( csvpath, results_df );
            end
        catch e
            @error "Could not save results." exception=(e, catch_backtrace())
        end#try-catch

        return nothing
    end# function

    return save_results
end


text:
# useful conversion factors
mmHgToPa = 133.32;
cm3Tom3 = 1e-6;

# non-dimensional scalings
Ps = 25*mmHgToPa;
Vs = 135*cm3Tom3;
Qs = 400*cm3Tom3;
ts = 0.8;


text:
@testset "Printing" begin
    io = IOBuffer()

    game = IIEMatrixGame()
    sol = ESCFRSolver(game)
    train!(sol, 100_000)

    print(io, sol)
    @test String(take!(io)) isa String

    game = Kuhn()
    sol = ESCFRSolver(game)
    train!(sol, 1_000_000)

    print(io, sol)
    @test String(take!(io)) isa String
end

max_stars_repo_name: WhiffleFish/HelloCFR

max_issues_repo_name: WhiffleFish/HelloCFR

max_forks_repo_name: WhiffleFish/HelloCFR


text:
crabs = parse.(Int, split(readline("day7/crabs.txt"), ','))

move_crabs(crabs, to) = sum(abs.(crabs .- to))
p1 = minimum(move_crabs(crabs, i) for i in 0:maximum(crabs))

@show p1

move_crabs2(crabs, to) = sum(sum(1:abs(crab - to)) for crab in crabs)
p2 = minimum(move_crabs2(crabs, i) for i in 0:maximum(crabs))

@show p2


text:
using HorizonSideRobots
include("Functions.jl")
include("Structs.jl")

function cross_border(robot::Robot)
    cross_robot = MarkerBorderRobot(robot)
    sides = [Nord, West, Sud, Ost]
    for side in sides
        marker_to_edge!(cross_robot, side)
    end
end

max_stars_repo_name: Mananhina/mirea-progs

max_issues_repo_name: Mananhina/mirea-progs

max_forks_repo_name: Mananhina/mirea-progs


text:
using FlightMechanics
using FlightMechanics.Models

##----------------------------------------------------------------------------------------------------
## imports

# Aerodynamics
import FlightMechanics.Models:
    calculate_aerodynamics

# Propulsion
import FlightMechanics.Models:
    get_pfm, get_cj, get_power, get_efficiency, get_tanks,
    get_engine_position, get_engine_orientation, get_engine_gyro_effects,
    calculate_engine

# Aircraft Model
import FlightMechanics.Models:
    get_name, get_wing_area, get_wing_span, get_chord, get_arp,
    get_empty_mass_props,
    set_stick_lon!, set_stick_lat!, set_pedals!, set_thtl!,
    get_controls_ranges_trimmer

##----------------------------------------------------------------------------------------------------
## exports

# Aerodynamics
export F16Aerodynamics, calculate_aerodynamics

# Propulsion
export F16Engine,
    get_pfm, get_cj, get_power, get_efficiency, get_tanks,
    get_engine_position, get_engine_orientation,
    calculate_engine

# FCS
export F16FCS

# Aircraft Model
export F16,
    get_name,
    get_empty_mass_props,
    get_wing_area,
    get_wing_span,
    get_chord,
    get_arp

##----------------------------------------------------------------------------------------------------
## structs

# Aerodynamics
struct F16Aerodynamics<:Aerodynamics    # TODO: CDα, CLα, CYβ... could be included here
    wind_pfm::PointForcesMoments
    wind_coeff_pfm::PointForcesMoments
    body_pfm::PointForcesMoments
    body_coeff_pfm::PointForcesMoments
end

# Propulsion
struct F16Engine<:Engine
    pfm::PointForcesMoments
    cj::Number
    power::Number
    efficiency::Number
    tanks::Array{RigidSolid, 1}
    h::Array{T, 1} where T<:Number  # angular momentum [kg·m²/s]
end

# FCS
mutable struct F16FCS<:FCS      # TODO: implement also rate limits and time constants
    # Cabin controls
    stick_longitudinal::RangeControl
    stick_lateral::RangeControl
    pedals::RangeControl
    thtl::RangeControl

    # Aerodynamic surfaces
    de::RangeControl
    da::RangeControl
    dr::RangeControl
    # Engine
    cpl::RangeControl
    # Configuration
    allow_out_of_range::Bool
    throw_error_on_out_of_range::Bool
end

# Aircraft Model
struct F16<:Aircraft
    mass_props::RigidSolid
    pfm::PointForcesMoments
    aerodynamics::F16Aerodynamics
    propulsion::Propulsion
    fcs::FCS
end

##----------------------------------------------------------------------------------------------------
## constants

const DE_MAX = 25.0  # deg
const DA_MAX = 20.0  # deg  #XXX: In Stevens' book says 21.5 deg (Appendix A Section A.4)
const DR_MAX = 30.0  # deg

##----------------------------------------------------------------------------------------------------
## Aerodynamics

α_data = [-10. -5. 0. 5. 10. 15. 20. 25. 30. 35. 40. 45.]  # deg
β_data = [0. 5. 10. 15. 20. 25. 30.]  # deg

de_data = [-24. -12.   0.  12.  24.]  # deg

# UTILS for interpolations
function get_interp_idx(val, coeff, min_, max_, off_=3)
   s = val * coeff
   k = floor(Int, s)
   k = max(min_, k)
   k = min(k, max_)
   da = s - float(k)
   k += off_
   l = k + Int(sign(da))
   return k, l, da
end

function get_interp_idx2(val, coeff, min_, max_)
   s = abs(val) * coeff
   k = floor(Int, s)
   k = max(min_, k)
   k = min(k, max_)
   da = s - float(k)
   k += 1
   l = k + Int(sign(da))
   return k, l, da
end

function interp1d(val, coeff, min, max, data)
   k, l, da = get_interp_idx(val, coeff, min, max)
   res = data[k] + abs(da) * (data[l] - data[k])
   return res
end

function interp2d(val1, val2, coeff1, coeff2, min1, min2, max1, max2, data, off1=3, off2=3)
   k, l, da = get_interp_idx(val1, coeff1, min1, max1, off1)
   m, n, de = get_interp_idx(val2, coeff2, min2, max2, off2)

   t = data[k, m]
   u = data[k, n]
   v = t + abs(da) * (data[l, m] - t)
   w = u + abs(da) * (data[l, n] - u)
   res = v + (w - v) * abs(de)

   return res
end

function interp2d2(val1, val2, coeff1, coeff2, min1, min2, max1, max2, data)
   k, l, da = get_interp_idx(val1, coeff1, min1, max1)
   m, n, de = get_interp_idx2(val2, coeff2, min2, max2)

   t = data[k, m]
   u = data[k, n]
   v = t + abs(da) * (data[l, m] - t)
   w = u + abs(da) * (data[l, n] - u)
   res = v + (w - v) * abs(de)
   res *= sign(val2)

   return res
end

# DAMPING COEFFICIENTS
CXq_data = [-0.267  -0.110   0.308   1.340   2.080   2.910   2.760   2.050   1.500   1.490   1.830   1.210]
CYr_data = [ 0.882   0.852   0.876   0.958   0.962   0.974   0.819   0.483   0.590   1.210  -0.493  -1.040]
# XXX: -2.27 seems an error in Stenvens. In Morelli it is -0.2270
# CYp_data = [-0.108  -0.108  -0.188   0.110   0.258   0.226   0.344   0.362   0.611   0.529   0.298  -2.270]
CYp_data = [-0.108  -0.108  -0.188   0.110   0.258   0.226   0.344   0.362   0.611   0.529   0.298  -0.227]
CZq_data = [-8.800 -25.800 -28.900 -31.400 -31.200 -30.700 -27.700 -28.200 -29.000 -29.800 -38.300 -35.300]
Clr_data = [-0.126  -0.026   0.063   0.113   0.208   0.230   0.319   0.437   0.680   0.100   0.447  -0.330]
Clp_data = [-0.360  -0.359  -0.443  -0.420  -0.383  -0.375  -0.329  -0.294  -0.230  -0.210  -0.120  -0.100]
Cmq_data = [-7.210  -0.540  -5.230  -5.260  -6.110  -6.640  -5.690  -6.000  -6.200  -6.400  -6.600  -6.000]
Cnr_data = [-0.380  -0.363  -0.378  -0.386  -0.370  -0.453  -0.550  -0.582  -0.595  -0.637  -1.020  -0.840]
Cnp_data = [ 0.061   0.052   0.052  -0.012  -0.013  -0.024   0.050   0.150   0.130   0.158   0.240   0.150]

damp_data = [CXq_data; CYr_data; CYp_data; CZq_data; Clr_data; Clp_data;
             Cmq_data; Cnr_data; Cnp_data]'
damp_data = damp_data'

# CX
# rows: de, columns: alpha
CX_data = [-0.099 -0.081 -0.081 -0.063 -0.025 0.044 0.097 0.113 0.145 0.167 0.174 0.166;
           -0.048 -0.038 -0.040 -0.021  0.016 0.083 0.127 0.137 0.162 0.177 0.179 0.167;
           -0.022 -0.020 -0.021 -0.004  0.032 0.094 0.128 0.130 0.154 0.161 0.155 0.138;
           -0.040 -0.038 -0.039 -0.025  0.006 0.062 0.087 0.085 0.100 0.110 0.104 0.091;
           -0.083 -0.073 -0.076 -0.072 -0.046 0.012 0.024 0.025 0.043 0.053 0.047 0.040]
CX_data = CX_data'

# CZ
# columns: alpha
CZ_data = [0.770 0.241 -0.100 -0.416 -0.731 -1.053 -1.366 -1.646 -1.917 -2.120 -2.248 -2.229]

# Cm
# rows: de columns: alpha
Cm_data = [0.205  0.168  0.186  0.196  0.213  0.251  0.245  0.238  0.252  0.231  0.198  0.192;
           0.081  0.077  0.107  0.110  0.110  0.141  0.127  0.119  0.133  0.108  0.081  0.093;
          -0.046 -0.020 -0.009 -0.005 -0.006  0.010  0.006 -0.001  0.014  0.000 -0.013  0.032;
          -0.174 -0.145 -0.121 -0.127 -0.129 -0.102 -0.097 -0.113 -0.087 -0.084 -0.069 -0.006;
          -0.259 -0.202 -0.184 -0.193 -0.199 -0.150 -0.160 -0.167 -0.104 -0.076 -0.041 -0.005]
Cm_data = Cm_data'

# Cl
# rows: beta columns: alpha
# XXX: found differences in Morelli Cl_data for columns 6-9
# Stevens
Cl_data = [ 0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000;
           -0.001 -0.004 -0.008 -0.012 -0.016 -0.019 -0.020 -0.020 -0.015 -0.008 -0.013 -0.015;
           -0.003 -0.009 -0.017 -0.024 -0.030 -0.034 -0.040 -0.037 -0.016 -0.002 -0.010 -0.019;
           -0.001 -0.010 -0.020 -0.030 -0.039 -0.044 -0.050 -0.049 -0.023 -0.006 -0.014 -0.027;
            0.000 -0.010 -0.022 -0.034 -0.047 -0.046 -0.059 -0.061 -0.033 -0.036 -0.035 -0.035;
            0.007 -0.010 -0.023 -0.034 -0.049 -0.046 -0.068 -0.071 -0.060 -0.058 -0.062 -0.059;
            0.009 -0.011 -0.023 -0.037 -0.050 -0.047 -0.074 -0.079 -0.091 -0.076 -0.077 -0.076]
Cl_data = Cl_data'

# Morelli version
# Cl_data = [ 0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000;
#            -0.001 -0.004 -0.008 -0.012 -0.016 -0.022 -0.022 -0.021 -0.015 -0.008 -0.013 -0.015;
#            -0.003 -0.009 -0.017 -0.024 -0.030 -0.041 -0.045 -0.040 -0.016 -0.002 -0.010 -0.019;
#            -0.001 -0.010 -0.020 -0.030 -0.039 -0.054 -0.057 -0.054 -0.023 -0.006 -0.014 -0.027;
#             0.000 -0.010 -0.022 -0.034 -0.047 -0.060 -0.069 -0.067 -0.033 -0.036 -0.035 -0.035;
#             0.007 -0.010 -0.023 -0.034 -0.049 -0.063 -0.081 -0.079 -0.060 -0.058 -0.062 -0.059;
#             0.009 -0.011 -0.023 -0.037 -0.050 -0.068 -0.089 -0.088 -0.091 -0.076 -0.077 -0.076]
# Cl_data = Cl_data'

# rows: beta columns=alpha
clda_data = [-0.041 -0.052 -0.053 -0.056 -0.050 -0.056 -0.082 -0.059 -0.042 -0.038 -0.027 -0.017;
             -0.041 -0.053 -0.053 -0.053 -0.050 -0.051 -0.066 -0.043 -0.038 -0.027 -0.023 -0.016;
             -0.042 -0.053 -0.052 -0.051 -0.049 -0.049 -0.043 -0.035 -0.026 -0.016 -0.018 -0.014;
             -0.040 -0.052 -0.051 -0.052 -0.048 -0.048 -0.042 -0.037 -0.031 -0.026 -0.017 -0.012;
             -0.043 -0.049 -0.048 -0.049 -0.043 -0.042 -0.042 -0.036 -0.025 -0.021 -0.016 -0.011;
             -0.044 -0.048 -0.048 -0.047 -0.042 -0.041 -0.020 -0.028 -0.013 -0.014 -0.011 -0.010;
             -0.043 -0.049 -0.047 -0.045 -0.042 -0.037 -0.003 -0.013 -0.010 -0.003 -0.007 -0.008]
clda_data /= DA_MAX
clda_data = clda_data'
# Stevens
# rows: beta columns=alpha
cldr_data = [ 0.005  0.017  0.014  0.010 -0.005  0.009  0.019  0.005 -0.000 -0.005 -0.011  0.008;
              0.007  0.016  0.014  0.014  0.013  0.009  0.012  0.005  0.000  0.004  0.009  0.007;
              0.013  0.013  0.011  0.012  0.011  0.009  0.008  0.005 -0.002  0.005  0.003  0.005;  # Morelli diff
              0.018  0.015  0.015  0.014  0.014  0.014  0.014  0.015  0.013  0.011  0.006  0.001;
              0.015  0.014  0.013  0.013  0.012  0.011  0.011  0.010  0.008  0.008  0.007  0.003;
              0.021  0.011  0.010  0.011  0.010  0.009  0.008  0.010  0.006  0.005  0.000  0.001;
              0.023  0.010  0.011  0.011  0.011  0.010  0.008  0.010  0.006  0.014  0.020  0.000]
cldr_data /= DR_MAX
cldr_data = cldr_data'

# Morelli
# rows: beta columns=alpha
# cldr_data = [ 0.005  0.017  0.014  0.010 -0.005  0.009  0.019  0.005 -0.000 -0.005 -0.011  0.008;
#               0.007  0.016  0.014  0.014  0.013  0.009  0.012  0.005  0.000  0.004  0.009  0.007;
#               0.013  0.013  0.011  0.012  0.011  0.009  0.008  0.005  0.000  0.005  0.003  0.005;  # <<
#               0.018  0.015  0.015  0.014  0.014  0.014  0.014  0.015  0.013  0.011  0.006  0.001;
#               0.015  0.014  0.013  0.013  0.012  0.011  0.011  0.010  0.008  0.008  0.007  0.003;
#               0.021  0.011  0.010  0.011  0.010  0.009  0.008  0.010  0.006  0.005  0.000  0.001;
#               0.023  0.010  0.011  0.011  0.011  0.010  0.008  0.010  0.006  0.014  0.020  0.000]
# cldr_data /= DR_MAX
# cldr_data = cldr_data'

# Cn
# rows: beta columns: alpha
Cn_data = [0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000 0.000  0.000  0.000  0.000;
           0.018  0.019  0.018  0.019  0.019  0.018  0.013  0.007 0.004 -0.014 -0.017 -0.033;
           0.038  0.042  0.042  0.042  0.043  0.039  0.030  0.017 0.004 -0.035 -0.047 -0.057;
           0.056  0.057  0.059  0.058  0.058  0.053  0.032  0.012 0.002 -0.046 -0.071 -0.073;
           0.064  0.077  0.076  0.074  0.073  0.057  0.029  0.007 0.012 -0.034 -0.065 -0.041;
           0.074  0.086  0.093  0.089  0.080  0.062  0.049  0.022 0.028 -0.012 -0.002 -0.013;
           0.079  0.090  0.106  0.106  0.096  0.080  0.068  0.030 0.064  0.015  0.011 -0.001]
Cn_data = Cn_data'
# Stevens
# rows: beta columns=alpha
cnda_data = [ 0.001 -0.027 -0.017 -0.013 -0.012 -0.016  0.001  0.017  0.011  0.017  0.008  0.016;
              0.002 -0.014 -0.016 -0.016 -0.014 -0.019 -0.021  0.002  0.012  0.015  0.015  0.011;
             -0.006 -0.008 -0.006 -0.006 -0.005 -0.008 -0.005  0.007  0.004  0.007  0.006  0.006;
             -0.011 -0.011 -0.010 -0.009 -0.008 -0.006  0.000  0.004  0.007  0.010  0.004  0.010;
             -0.015 -0.015 -0.014 -0.012 -0.011 -0.008 -0.002  0.002  0.006  0.012  0.011  0.011;
             -0.024 -0.010 -0.004 -0.002 -0.001  0.003  0.014  0.006 -0.001  0.004  0.004  0.006;
             -0.022  0.002 -0.003 -0.005 -0.003 -0.001 -0.009 -0.009 -0.001  0.003 -0.002  0.001]
cnda_data /= DA_MAX
cnda_data = cnda_data'

# Morelli
# rows: beta columns=alpha
# cnda_data = [ 0.001 -0.027 -0.017 -0.013 -0.012 -0.016  0.001  0.017  0.011  0.017  0.008  0.016;
#               0.002 -0.014 -0.016 -0.016 -0.014 -0.019 -0.021  0.002  0.012  0.015  0.016  0.011; # <<
#              -0.006 -0.008 -0.006 -0.006 -0.005 -0.008 -0.005  0.007  0.004  0.007  0.006  0.006;
#              -0.011 -0.011 -0.010 -0.009 -0.008 -0.006  0.000  0.004  0.007  0.010  0.004  0.010;
#              -0.015 -0.015 -0.014 -0.012 -0.011 -0.008 -0.002  0.002  0.006  0.012  0.011  0.011;
#              -0.024 -0.010 -0.004 -0.002 -0.001  0.003  0.014  0.006 -0.001  0.004  0.004  0.006;
#              -0.022  0.002 -0.003 -0.005 -0.003 -0.001 -0.009 -0.009 -0.001  0.003 -0.002  0.001]
# cnda_data /= DA_MAX
# cnda_data = cnda_data'

# rows: beta columns=alpha
cndr_data = [-0.018 -0.052 -0.052 -0.052 -0.054 -0.049 -0.059 -0.051 -0.030 -0.037 -0.026 -0.013;
             -0.028 -0.051 -0.043 -0.046 -0.045 -0.049 -0.057 -0.052 -0.030 -0.033 -0.030 -0.008;
             -0.037 -0.041 -0.038 -0.040 -0.040 -0.038 -0.037 -0.030 -0.027 -0.024 -0.019 -0.013;
             -0.048 -0.045 -0.045 -0.045 -0.044 -0.045 -0.047 -0.048 -0.049 -0.045 -0.033 -0.016;
             -0.043 -0.044 -0.041 -0.041 -0.040 -0.038 -0.034 -0.035 -0.035 -0.029 -0.022 -0.009;
             -0.052 -0.034 -0.036 -0.036 -0.035 -0.028 -0.024 -0.023 -0.020 -0.016 -0.010 -0.014;
             -0.062 -0.034 -0.027 -0.028 -0.027 -0.027 -0.023 -0.023 -0.019 -0.009 -0.025 -0.010]
cndr_data /= DR_MAX
cndr_data = cndr_data'

"""
   dampings(aero::F16Aerodynamics, α)

Calculates CX_q, CY_r, CY_p, CZ_q, Cl_r, Cl_p, Cm_q, Cn_r, Cn_p for the given
angle of attack, α (deg).
"""
function dampings(aero::F16Aerodynamics, α)
   # k, l, da = get_interp_idx(α, 0.2, -1, 8)
   # dampings = damp_data[k, :] + abs(da) * (damp_data[l, :] - damp_data[k, :])
   # TODO: check if vectorized approach is faster than loop (it shouldn't)
   dampings = Array{Float64}(undef, 9)
   for ii in 1:9
      dampings[ii] = interp1d(α, 0.2, -1, 8, damp_data[ii, :])
   end
   return dampings
end

Cl_da(aero::F16Aerodynamics, α, β) = interp2d(α, β, 0.2, 0.1, -1, -2, 8, 2, clda_data, 3, 4)
Cl_dr(aero::F16Aerodynamics, α, β) = interp2d(α, β, 0.2, 0.1, -1, -2, 8, 2, cldr_data, 3, 4)
Cn_da(aero::F16Aerodynamics, α, β) = interp2d(α, β, 0.2, 0.1, -1, -2, 8, 2, cnda_data, 3, 4)
Cn_dr(aero::F16Aerodynamics, α, β) = interp2d(α, β, 0.2, 0.1, -1, -2, 8, 2, cndr_data, 3, 4)

CXαde(aero::F16Aerodynamics, α, de) = interp2d(α, de, .2, 1.0/12, -1, -1, 8, 1, CX_data)

CYdr(aero::F16Aerodynamics, dr) = 0.086 / DR_MAX * dr
CYda(aero::F16Aerodynamics, da) = 0.021 / DA_MAX * da
CYβ(aero::F16Aerodynamics, β) = -0.02 * β

CZα(aero::F16Aerodynamics, α) = interp1d(α, 0.2, -1, 8, CZ_data)
CZαβ(aero::F16Aerodynamics, α, β) = CZα(aero, α) * (1. - (β*DEG2RAD)^2)
CZde(aero::F16Aerodynamics, de) = -0.19/DE_MAX * de

Clαβ(aero::F16Aerodynamics, α, β) = interp2d2(α, β, .2, .2, -1, 1, 8, 5, Cl_data)
Cldr(aero::F16Aerodynamics, α, β, dr) = Cl_dr(aero, α, β) * dr
Clda(aero::F16Aerodynamics, α, β, da) = Cl_da(aero, α, β) * da

Cmαde(aero::F16Aerodynamics, α, de) = interp2d(α, de, .2, 1.0/12, -1, -1, 8, 1, Cm_data)

Cnαβ(aero::F16Aerodynamics, α, β) = interp2d2(α, β, .2, .2, -1, 1, 8, 5, Cn_data)
Cndr(aero::F16Aerodynamics, α, β, dr) = Cn_dr(aero, α, β) * dr
Cnda(aero::F16Aerodynamics, α, β, da) = Cn_da(aero, α, β) * da

function calculate_aerodynamics(
    ac::Aircraft, aero::F16Aerodynamics, aerostate::AeroState, state::State
    )

   ARP = get_arp(ac)

   qinf = get_qinf(aerostate)  # Pa
   Sw = get_wing_area(ac)  # m²
   b = get_wing_span(ac)  # m
   c = get_chord(ac)  # m

   fcs = get_fcs(ac)
   de = get_value(fcs.de) * RAD2DEG
   da = get_value(fcs.da) * RAD2DEG
   dr = get_value(fcs.dr) * RAD2DEG

   α = get_alpha(aerostate) * RAD2DEG
   β = get_beta(aerostate) * RAD2DEG
   tas = get_tas(aerostate) * M2FT
   # αdot = get_alpha_dot(aerostate)  # rad/s
   p, q, r = get_body_ang_velocity(state)  # rad/s

   c2v = c * M2FT / (2*tas)
   qc2v = q * c2v
   b2v = b * M2FT / (2*tas)

   CX_q, CY_r, CY_p, CZ_q, Cl_r, Cl_p, Cm_q, Cn_r, Cn_p = dampings(aero, α)

   CX = CXαde(aero, α, de) + CX_q * qc2v
   CY = CYβ(aero, β) + CYda(aero, da) + CYdr(aero, dr) + (CY_r*r + CY_p*p) * b2v
   CZ = CZαβ(aero, α, β) + CZde(aero, de) + CZ_q * qc2v

   Cl = Clαβ(aero, α, β) +  Clda(aero, α, β, da) + Cldr(aero, α, β, dr) +
       (Cl_r*r + Cl_p*p) * b2v
   Cm = Cmαde(aero, α, de) + Cm_q*qc2v
      # + CZ * (xcgr - xcg) is taken into account in pfm
   Cn = Cnαβ(aero, α, β) + Cnda(aero, α, β, da) + Cndr(aero, α, β, dr) +
       (Cn_r*r + Cn_p*p) * b2v
      # - CY * (xcgr - xcg) * c/b is taken into account in pfm

   # Pack results
   adim_pfm_body = PointForcesMoments(ARP, [CX, CY, CZ], [Cl, Cm, Cn])

   α = get_alpha(aerostate)
   β = get_beta(aerostate)
   # Generate aerodynamics  object
   aerodynamics_from_body_coeff(adim_pfm_body, α, β, qinf, Sw, b, c, aero)
end

##----------------------------------------------------------------------------------------------------
## Propulsion

function F16Engine()
    F16Engine(
        PointForcesMoments(zeros(3), zeros(3), zeros(3)),
        0,
        0,
        0,
        # Fuel tanks can be obtained from JSBSim model
        [PointMass(0 * LB2KG, [0., 0., 0.] .* IN2M)],
        [160.0*SLUGFT2_2_KGM2, 0.0, 0.0]
        )

end

# TODO: Engine position and orientation
get_engine_position(prop::F16Engine) = [0.35 * 11.32 * FT2M, 0.0, 0.0]
get_engine_orientation(prop::F16Engine) = [0., 0., 0.] .* DEG2RAD
get_engine_gyro_effects(prop::F16Engine) = [160.0*SLUGFT2_2_KGM2, 0.0, 0.0]  # [kg·m²/s]

# ENGINE DATA
"""
    tgear(thtl)

Given the thottle setting (0 ≤ thtl ≤ 1) calculate the commanded power level
(0 ≤ cpow ≤ 100)
"""
function tgear(thtl)
    if thtl <= .77
     cpow = 64.94 * thtl
    else
     cpow = 217.38 * thtl - 117.38
    end
    return cpow
end

"""
    pdot(p3, p1)

Rate of change of power with time using a first order lag (%/s)

# Arguments
p3::Number  Actual power (%)
p1::Number  Power command (%)
"""
function pdot(p3, p1)
    if p1 >= 50.
        if p3 >= 50.
            t = 5.
            p2 = p1
        else
            p2 = 60.
            t = rtau(p2-p3)
        end
    else
        if p3 >= 50.
            t = 5.
            p2 = 40.
        else
            p2 = p1
            t = rtau(p2-p3)
        end
    end
    pd = t * (p2 - p3)
    return pd
end

"""
    rtau(dp)

Calculate the reciprocal time constant (1/s) for a first-order thrust lag given
the difference between the commanded power level (%) and the actual power
level (%).
"""
function rtau(dp)
    if dp <= 25.
        rt = 1.0  # Reciprocal time constant
    elseif dp >= 50.
        rt = 0.1
    else
        rt = 1.9 - 0.036 * dp
    end
    return rt
end

idle_data =
    [ 1060.  670.   880.   1140.  1500.  1860.
      635.   425.   690.   1010.  1330.  1700.
      60.    25.    345.   755.   1130.  1525.
     -1020. -710.  -300.   350.   910.   1360.
     -2700. -1900. -1300. -247.   600.   1100.
     -3600. -1400. -595.  -342.  -200.   700.]'

# Mil data
mil_data =
    [12680. 9150.  6200.  3950.  2450. 1400.
     12680. 9150.  6313.  4040.  2470. 1400.
     12610. 9312.  6610.  4290.  2600. 1560.
     12640. 9839.  7090.  4660.  2840. 1660.
     12390. 10176. 7750.  5320.  3250. 1930.
     11680. 9848.  8050.  6100.  3800. 2310.]'

# Max data
max_data =
    [20000. 15000. 10800. 7000.  4000. 2500.
     21420. 15700. 11225. 7323.  4435. 2600.
     22700. 16860. 12250. 8154.  5000. 2835.
     24240. 18910. 13760. 9285.  5700. 3215.
     26070. 21075. 15975. 11115. 6860. 3950.
     28886. 23319. 18300. 13484. 8642. 5057.]'

"""
    thrust(pow, alt, rmach)

Given the commanded power level (%), the altitude (ft) and the Mach number,
calculate the engine thrust (lbf)
"""
function calculate_thrust(pow, alt, rmach)

    h = 0.0001 * alt
    i = floor(Int, h)
    if i >= 5
        i=4
    end

    dh = h - float(i)

    rm = 5.0 * rmach
    m = floor(Int, rm);
    if m >= 5
        m = 4
    end

    dm = rm - float(m)
    cdh = 1.0 - float(dh)

    i=i+1;
    m=m+1;

    s = mil_data[i, m] * cdh + mil_data[i+1, m] * dh
    t = mil_data[i, m+1] *cdh + mil_data[i+1, m+1] * dh
    tmil = s + (t - s) * dm

    if pow < 50.
        s = idle_data[i, m] * cdh + idle_data[i+1, m] * dh
        t = idle_data[i,m+1] * cdh + idle_data[i+1, m+1] * dh
        tidl = s + (t - s) * dm
        thrst = tidl + (tmil - tidl) * pow * 0.02
    else
        s = max_data[i, m] * cdh + max_data[i+1, m] * dh
        t = max_data[i, m+1] * cdh + max_data[i+1, m+1] * dh
        tmax = s + (t-s) * dm
        thrst = tmil + (tmax - tmil) * (pow-50.) * 0.02
    end

    return thrst
    end

"""
The F-16 engine power response is modelled by a first-order lag (pdot function).
The rest of the model consists of thottle gearing (tgear) and lookup tables for
thrust as a function of operating power level, altitude and Mach.

Lookup tables have rows corresponding to Mach from 0 to 1 in increments of 0.2
and columns correspond to altitudes from 0 to 50000ft in increments of 10000ft.
There is a table for each power level: idle, military and maximum. Results can
be extrapolated beyond the boundaries but results may be unrealistic.

# References

Reimplemented from:

- [1] Stevens, B. L., Lewis, F. L., & Johnson, E. N. (2015). Aircraft control
 and simulation: dynamics, controls design, and autonomous systems. John Wiley
 & Sons. (page 715)
"""
function calculate_engine(
    eng::F16Engine, fcs::FCS, aerostate::AeroState, state::State; consume_fuel=false
    )

    pow = get_thrust(fcs)  # Commanded power: between 0 and 100
    Mach = get_mach(aerostate)
    # TODO: Should be altitude
    height = get_height(state) * M2FT

    thrust = calculate_thrust(pow, height, Mach)
    thrust *= LBF2N
    cj = 0.0
    Pm = thrust * get_tas(aerostate)
    ηp = NaN

    if consume_fuel==true
        error("fuel consumption not implemented")
    else
        tanks = get_tanks(eng)
    end

    # TODO: Torque calcualtion is missing
    pfm = PointForcesMoments(get_engine_position(eng),
                             [thrust, 0, 0],
                             [0, 0, 0]
                             )

    return typeof(eng)(pfm, cj, Pm, ηp, tanks, get_engine_gyro_effects(eng))
end

##----------------------------------------------------------------------------------------------------
## FCS

# TODO: Move to FCS in models
get_thrust(fcs::F16FCS) = get_value(fcs.cpl)

F16FCS(stick_lon, stick_lat, pedals, thtl, de, da, dr, cpl) = F16FCS(
    stick_lon, stick_lat, pedals, thtl, de, da, dr, cpl, false, false
    )

F16FCS() = F16FCS(
    # Cabin Inputs
    RangeControl(0.0, [0, 1]),  # stick_longitudinal
    RangeControl(0.0, [0, 1]),  # stick_lateral
    RangeControl(0.0, [0, 1]),  # pedals
    RangeControl(0.0, [0, 1]),  # thtl
    # Controls
    RangeControl(0.0, [-DE_MAX, DE_MAX] .* DEG2RAD),  # elevator
    RangeControl(0.0, [-DA_MAX, DA_MAX] .* DEG2RAD),  # ailerons
    RangeControl(0.0, [-DR_MAX, DR_MAX] .* DEG2RAD),  # rudder
    # Commanded power level
    RangeControl(0.0, [0.0, 100.]),                # CPL
    )

function set_stick_lon!(fcs::F16FCS, value)
    set_value!(fcs.stick_longitudinal, value)
    min, max = get_value_range(fcs.de)
    range = max - min
    allow_out_of_range = get_allow_out_of_range_inputs(fcs)
    throw_error = get_throw_error_on_out_of_range_inputs(fcs)
    set_value!(fcs.de, min + range * value, allow_out_of_range, throw_error)
end

function set_stick_lat!(fcs::F16FCS, value)
    set_value!(fcs.stick_lateral, value)
    min, max = get_value_range(fcs.da)
    range = max - min
    allow_out_of_range = get_allow_out_of_range_inputs(fcs)
    throw_error = get_throw_error_on_out_of_range_inputs(fcs)
    set_value!(fcs.da, min + range * value, allow_out_of_range, throw_error)
end

function set_pedals!(fcs::F16FCS, value)
    set_value!(fcs.pedals, value)
    min, max = get_value_range(fcs.dr)
    range = max - min
    allow_out_of_range = get_allow_out_of_range_inputs(fcs)
    throw_error = get_throw_error_on_out_of_range_inputs(fcs)
    set_value!(fcs.dr, min + range * value, allow_out_of_range, throw_error)
end

function set_thtl!(fcs::F16FCS, value)
    set_value!(fcs.thtl, value)
    min, max = get_value_range(fcs.thtl)
    range = max - min
    allow_out_of_range = get_allow_out_of_range_inputs(fcs)
    throw_error = get_throw_error_on_out_of_range_inputs(fcs)
    set_value!(fcs.cpl, tgear(value), allow_out_of_range, throw_error)
end

function get_controls_ranges_trimmer(fcs::F16FCS)
    [get_value_range(fcs.stick_longitudinal),
     get_value_range(fcs.stick_lateral),
     get_value_range(fcs.pedals),
     get_value_range(fcs.thtl)]
end

##----------------------------------------------------------------------------------------------------
## Aircraft Model

function F16()
    pfm0 = PointForcesMoments(zeros(3), zeros(3), zeros(3))
    aero0 = F16Aerodynamics(pfm0, pfm0, pfm0, pfm0)
    engine = F16Engine()
    propulsion0 = Propulsion(
            PointForcesMoments(zeros(3), zeros(3), zeros(3)),
            0, 0, 0,
            [engine],
            get_gyro_effects(engine)
            )

    fcs = F16FCS()
    # mass properties cannot be retrieved until ac is created... so:
    ac = F16(RigidSolid(0, zeros(3), zeros(3, 3)),
              pfm0,
              aero0,
              propulsion0,
              fcs)
    mass = get_fuel_mass_props(get_propulsion(ac)) + get_empty_mass_props(ac)
            # + get_payload_mass_props(ac)
    F16(mass, pfm0, aero0, propulsion0, fcs)
end

# Name
function get_name(ac::F16)
    return "F16"
end

# GEOMETRIC PROPERTIES
get_wing_area(ac::F16) = 300.0 * FT2M^2
get_wing_span(ac::F16) = 30. * FT2M
get_chord(ac::F16) = 11.32 * FT2M

# Aerodynamic Reference Point
# Origin assumed leading edge of CMA
get_arp(ac::F16) = [-0.35 * get_chord(ac), 0.0, 0.0]
get_empty_cg(ac::F16) = [-0.35 * get_chord(ac), 0, 0]

# MASS PROPERTIES
function get_empty_mass_props(ac::F16)
    RigidSolid(
        20500 * LB2KG,                                # Empty mass
        get_empty_cg(ac),                             # Empty CG
        [9456.        0.    -982.;                     # Empty inertia
            0.    55814.       0.;
          -982.       0.   63100.]  .* SLUGFT2_2_KGM2
    )
end

# Crew and cargo
# get_pilot_mass_props(ac::F16) = PointMass(0 * LB2KG, [0., 0., 0.] .* IN2M)
# get_cargo_mass_props(ac::F16) = PointMass(0 * LB2KG, [0., 0., 0.] .* IN2M)

# get_payload_mass_props(ac::F16) = get_pilot_mass_props(ac)

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


text:
module LoopVectorization

using Static: StaticInt, gt, static
using VectorizationBase,
  SLEEFPirates, UnPack, OffsetArrays, ArrayInterfaceOffsetArrays, ArrayInterfaceStaticArrays
using VectorizationBase:
  mask,
  MM,
  AbstractMask,
  data,
  grouped_strided_pointer,
  AbstractSIMD,
  vzero,
  offsetprecalc,
  lazymul,
  vadd_nw,
  vadd_nsw,
  vadd_nuw,
  vsub_nw,
  vsub_nsw,
  vsub_nuw,
  vmul_nw,
  vmul_nsw,
  vmul_nuw,
  vfmaddsub,
  vfmsubadd,
  vpermilps177,
  vmovsldup,
  vmovshdup,
  maybestaticfirst,
  maybestaticlast,
  gep,
  gesp,
  NativeTypes, #llvmptr,
  vfmadd,
  vfmsub,
  vfnmadd,
  vfnmsub,
  vfmadd_fast,
  vfmsub_fast,
  vfnmadd_fast,
  vfnmsub_fast,
  vfmadd231,
  vfmsub231,
  vfnmadd231,
  vfnmsub231,
  vfma_fast,
  vmuladd_fast,
  vdiv_fast,
  vadd_fast,
  vsub_fast,
  vmul_fast,
  relu,
  stridedpointer,
  StridedPointer,
  StridedBitPointer,
  AbstractStridedPointer,
  _vload,
  _vstore!,
  reduced_add,
  reduced_prod,
  reduce_to_add,
  reduce_to_prod,
  reduced_max,
  reduced_min,
  reduce_to_max,
  reduce_to_min,
  reduced_all,
  reduced_any,
  reduce_to_all,
  reduce_to_any,
  vsum,
  vprod,
  vmaximum,
  vminimum,
  vany,
  vall,
  unwrap,
  Unroll,
  VecUnroll,
  preserve_buffer,
  zero_vecunroll,
  vbroadcast_vecunroll,
  _vzero,
  _vbroadcast,
  contract_add,
  collapse_add,
  contract_mul,
  collapse_mul,
  contract_max,
  collapse_max,
  contract_min,
  collapse_min,
  contract_and,
  collapse_and,
  contract_or,
  collapse_or,
  max_mask,
  maybestaticsize#,zero_mask

using HostCPUFeatures:
  pick_vector_width, register_size, register_count, has_opmask_registers
using CPUSummary: num_threads, num_cores, cache_linesize, cache_size

using LayoutPointers: stridedpointer_preserve, GroupedStridedPointers

using IfElse: ifelse

using ThreadingUtilities, PolyesterWeave
using Base.Broadcast: Broadcasted, DefaultArrayStyle
using LinearAlgebra: Adjoint, Transpose, Diagonal
using Base.Meta: isexpr
using DocStringExtensions
import LinearAlgebra # for check_args

using Base.FastMath:
  add_fast,
  sub_fast,
  mul_fast,
  div_fast,
  inv_fast,
  abs2_fast,
  rem_fast,
  max_fast,
  min_fast,
  pow_fast,
  sqrt_fast
using SLEEFPirates:
  log_fast, log2_fast, log10_fast, pow, sin_fast, cos_fast, sincos_fast, tan_fast

using ArrayInterface
using ArrayInterface:
  OptionallyStaticUnitRange,
  OptionallyStaticRange,
  Zero,
  One,
  StaticBool,
  True,
  False,
  reduce_tup,
  indices,
  UpTri,
  LoTri,
  strides,
  offsets,
  size,
  axes,
  StrideIndex
using CloseOpenIntervals: AbstractCloseOpen, CloseOpen#, SafeCloseOpen
# @static if VERSION ≥ v"1.6.0-rc1" #TODO: delete `else` when dropping 1.5 support
# using ArrayInterface: static_step
# else # Julia 1.5 did not define `step` on CartesianIndices
@inline static_step(x) = ArrayInterface.static_step(x)
@inline static_step(x::CartesianIndices) =
  VectorizationBase.CartesianVIndex(map(static_step, x.indices))
# end
const Static = StaticInt

export LowDimArray,
  stridedpointer,
  indices,
  static,
  @avx,
  @avxt,
  @turbo,
  @tturbo,
  *ˡ,
  _turbo_!,
  vmap,
  vmap!,
  vmapt,
  vmapt!,
  vmapnt,
  vmapnt!,
  vmapntt,
  vmapntt!,
  tanh_fast,
  sigmoid_fast,
  vfilter,
  vfilter!,
  vmapreduce,
  vreduce

const VECTORWIDTHSYMBOL, ELTYPESYMBOL, MASKSYMBOL =
  Symbol("##Wvecwidth##"), Symbol("##Tloopeltype##"), Symbol("##mask##")

include("vectorizationbase_compat/contract_pass.jl")
include("vectorizationbase_compat/subsetview.jl")
include("getconstindexes.jl")
include("predicates.jl")
include("simdfunctionals/map.jl")
include("simdfunctionals/filter.jl")
include("modeling/costs.jl")
include("modeling/operations.jl")
include("modeling/graphs.jl")
include("codegen/operation_evaluation_order.jl")
include("parse/memory_ops_common.jl")
include("parse/add_loads.jl")
include("parse/add_stores.jl")
include("parse/add_compute.jl")
include("parse/add_constants.jl")
include("parse/add_ifelse.jl")
include("modeling/determinestrategy.jl")
include("codegen/line_number_nodes.jl")
include("codegen/loopstartstopmanager.jl")
include("codegen/lower_compute.jl")
include("codegen/lower_constant.jl")
include("codegen/lower_memory_common.jl")
include("codegen/lower_load.jl")
include("codegen/lower_store.jl")
include("codegen/lowering.jl")
include("codegen/split_loops.jl")
include("codegen/lower_threads.jl")
include("condense_loopset.jl")
include("transforms.jl")
include("reconstruct_loopset.jl")
include("constructors.jl")
include("user_api_conveniences.jl")
include("simdfunctionals/mapreduce.jl")
include("broadcast.jl")

"""
LoopVectorization provides macros and functions that combine SIMD vectorization and
loop-reordering so as to improve performance:

- [`@turbo`](@ref): transform `for`-loops and broadcasting
- [`vmapreduce`](@ref): vectorized version of `mapreduce`
- [`vreduce`](@ref): vectorized version of `reduce`
- [`vmap`](@ref) and `vmap!`: vectorized version of `map` and `map!`
- [`vmapnt`](@ref) and `vmapnt!`: non-temporal variants of `vmap` and `vmap!`
- [`vmapntt`](@ref) and `vmapntt!`: threaded variants of `vmapnt` and `vmapnt!`
- [`vfilter`](@ref) and `vfilter!`: vectorized versions of `filter` and `filter!`
"""
LoopVectorization

include("precompile.jl")
_precompile_()

_vreduce(+, Float64[1.0])
# matmul_params(64, 32, 64)

# import ChainRulesCore, ForwardDiff
# include("vmap_grad.jl")
using ChainRulesCore, ForwardDiff, SpecialFunctions
include("simdfunctionals/vmap_grad_rrule.jl")
include("simdfunctionals/vmap_grad_forwarddiff.jl")
@inline SpecialFunctions.erf(x::AbstractSIMD) = VectorizationBase.verf(float(x))

end # module


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

using Markdown
using InteractiveUtils

# ╔═╡ 7022d960-2901-11eb-2528-87791813b415
using OffsetArrays

# ╔═╡ afa4a77e-28fc-11eb-1ab0-bbba1b653e46
data = reshape(rand(1:9,36),6,6)

# ╔═╡ 0019e726-28fd-11eb-0e86-31ec28b3c1a9
I = CartesianIndices(data)

# ╔═╡ 15548ecc-28fd-11eb-1206-476c5f44efdf
[ data[i] for i∈I]

# ╔═╡ 5fb6e7b6-2901-11eb-0e94-aba290fd0bae
A = OffsetArray(zeros(Int,8,8), 0:7 ,0:7)

# ╔═╡ 87c260a2-2901-11eb-1060-b1e4b6b5b02b
for i ∈ I
	A[i] = data[i]  # copy data
end

# ╔═╡ a5c7693a-2901-11eb-1083-0da8138a73c2
A

# ╔═╡ b6fde83c-2901-11eb-0e3b-4b3766579cc8
neighborhood = CartesianIndices((-1:1, -1:1))

# ╔═╡ babe3c24-2901-11eb-2d30-51256eb97e11
[ A[i.+neighborhood] for i ∈ I]

# ╔═╡ e6bd9dea-2901-11eb-1100-ad10705f41cc
stencil =  [ 0  -1   0
            -1   4  -1
            0  -1   0]

# ╔═╡ fe4f6df0-2901-11eb-1945-27e3f041ed1f
[  sum(A[i.+neighborhood].*stencil) for i ∈ I]

# ╔═╡ 77c06ce6-2902-11eb-30a7-51f210dbd723
begin
 B = copy(A)

 B[0,:] = B[6,:]  ## periodic
 B[7,:] = B[1,:]
 B[:,0] = B[:,6]
 B[:,7] = B[:,1]

 #B[0,:] = B[1,:]  ## zero derivative
 #B[7,:] = B[6,:]
 #B[:,0] = B[:,1]
 #B[:,7] = B[:,6]

 B
end

# ╔═╡ 4f342744-2902-11eb-1401-55e770d9d751

for i∈I
	B[i] = sum(A[i.+neighborhood].*stencil)
end

# ╔═╡ 6223e374-2902-11eb-3bb2-4d2d0d352801
B

# ╔═╡ Cell order:
# ╠═afa4a77e-28fc-11eb-1ab0-bbba1b653e46
# ╠═0019e726-28fd-11eb-0e86-31ec28b3c1a9
# ╠═15548ecc-28fd-11eb-1206-476c5f44efdf
# ╠═7022d960-2901-11eb-2528-87791813b415
# ╠═5fb6e7b6-2901-11eb-0e94-aba290fd0bae
# ╠═87c260a2-2901-11eb-1060-b1e4b6b5b02b
# ╠═a5c7693a-2901-11eb-1083-0da8138a73c2
# ╠═b6fde83c-2901-11eb-0e3b-4b3766579cc8
# ╠═babe3c24-2901-11eb-2d30-51256eb97e11
# ╠═e6bd9dea-2901-11eb-1100-ad10705f41cc
# ╠═fe4f6df0-2901-11eb-1945-27e3f041ed1f
# ╠═77c06ce6-2902-11eb-30a7-51f210dbd723
# ╠═4f342744-2902-11eb-1401-55e770d9d751
# ╠═6223e374-2902-11eb-3bb2-4d2d0d352801

max_stars_repo_name: mathijsvdv/ComputationalThinking

max_issues_repo_name: mathijsvdv/ComputationalThinking

max_forks_repo_name: mathijsvdv/ComputationalThinking


text:
@everywhere using Distributions

# Encode using iterated conditional modes
@everywhere function encode_icm_fully!{T <: AbstractFloat}(
  B::Union{Matrix{Int16},SharedMatrix{Int16}},  # in/out. Initialization, and the place where the results are saved.
  X::Matrix{T},                 # in. d-by-n data to encode
  C::Vector{Matrix{T}},         # in. m-long vector with d-by-h codebooks
  binaries::Vector{Matrix{T}},  # in. The binary terms
  cbi::Matrix{Int32},           # in. 2-by-ncbi. indices for inter-codebook interactions
  niter::Integer,               # in. number of iterations for block-icm
  randord::Bool,                # in. whether to randomize search order
  npert::Integer,               # in. number of codes to perturb per iteration
  IDX::UnitRange{Int64},        # in. Index to save the result
  V::Bool)                      # in. whether to print progress

  # Compute unaries
  unaries = get_unaries( X, C, V );

  h, n = size( unaries[1] );
  m, _ = size( B );

  ncbi = length( binaries );

  # Create a transposed copy of the binaries
  binaries_t = similar( binaries );
  for i = 1:ncbi
    binaries_t[i] = binaries[i]';
  end

  # Create an index from codebook pairs to indices
  cbpair2binaryidx   = zeros(Int32, m, m);
  for i = 1:ncbi
    cbpair2binaryidx[ cbi[1,i], cbi[2,i] ] = i;
  end

  # For codebook i, we have to condition on these codebooks
  to_look      = 1:m;
  to_condition = zeros(Int32, m-1, m);
  for i = 1:m
    tmp = collect(1:m);
    splice!( tmp, i );
    to_condition[:,i] = tmp;
  end

  # Make the order random
  if randord
    to_look      = randperm( m );
    to_condition = to_condition[:, to_look];
  end

  # Preallocate some space
  bb = Matrix{T}( h, h );
  ub = Matrix{T}( h, n );

  # Sample the indices to perturb in each code
  pertidx  = Matrix{Integer}( npert, n );
  for i = 1:n
    sampleidx = sample(1:m, npert, replace=false, ordered=true);
    for j = 1:npert
      pertidx[j, i] = sampleidx[j];
    end
  end
  pertvals = rand( 1:h, npert, n );

  # Perturb the solutions
  for i = 1:n
    for j = 1:npert
      B[ pertidx[j,i], IDX[i] ] = pertvals[j,i];
    end
  end

  @inbounds for i=1:niter # Do the number of passed iterations

    # This is the codebook that we are updating (i.e., the node)
    jidx = 1;
    for j = to_look
      # Get the unaries that we will work on
      uj = unaries[j];
      @simd for k = 1:h*n
        ub[k] = uj[k];
      end

      # These are all the nodes that we are conditioning on (i.e., the edges to 'absorb')
      for k = to_condition[:, jidx];

        # Determine the pairwise interactions that we'll use (for cache-friendliness)
        if j < k
          binariidx = cbpair2binaryidx[ j, k ];
          bb = binaries[ binariidx ];
        else
          binariidx = cbpair2binaryidx[ k, j ];
          bb = binaries_t[ binariidx ];
        end

        # Traverse the unaries, absorbing the appropriate binaries
        for l=1:n
          codek = B[k, IDX[l]];
          @simd for ll = 1:h
            ub[ll, l] += bb[ ll, codek ];
          end
        end
      end #for k=to_condition

      # Once we are done conditioning, traverse the absorbed unaries to find mins
      inidx = 1;
      for idx=IDX
        minv = ub[1, inidx]
        mini = 1
        for k = 2:h
          ubi = ub[k, inidx]
          if ubi < minv
            minv = ubi
            mini = k
          end
        end

        B[j, idx] = mini;
        inidx = inidx + 1;
      end

      jidx = jidx + 1;

    end # for j=to_look
  end # for i=1:niter

end

# Encode a full dataset
function encoding_icm{T <: AbstractFloat}(
  X::Matrix{T},         # d-by-n matrix. Data to encode
  oldB::Matrix{Int16},  # m-by-n matrix. Previous encoding
  C::Vector{Matrix{T}}, # m-long vector with d-by-h codebooks
  niter::Integer,       # number of ICM iterations
  randord::Bool,        # whether to use random order
  npert::Integer,       # the number of codes to perturb
  V::Bool=false)        # whether to print progress

  d, n =    size( X )
  m    =  length( C )
  _, h = size( C[1] )

  # Compute binaries between all codebook pairs
  binaries, cbi = get_binaries( C )
  _, ncbi       = size( cbi )

  # Compute the cost of the previous assignments
  prevcost = veccost( X, oldB, C )

  if nworkers() == 1
    B = zeros(Int16, m, n)
  else
    B = SharedArray(Int16, m, n)
  end

  @inbounds @simd for i = 1:m*n
    B[i] = oldB[i]
  end

  if nworkers() == 1
    encode_icm_fully!( B, X, C, binaries, cbi, niter, randord, npert, 1:n, V );
    #encode_icm_cpp!( B, X, C, binaries, cbi, niter, randord, npert, 1:n, V );
  else
    paridx = splitarray( 1:n, nworkers() );
    @sync begin
      for (i,wpid) in enumerate(workers())
        @async begin
          Xw = X[:,paridx[i]];
          remotecall_wait(encode_icm_fully!, wpid, B, Xw, C, binaries, cbi, niter, randord, npert, paridx[i], V );
        end
      end
    end
  end
  B = sdata(B)

  # Keep only the codes that improved
  newcost = veccost( X, B, C )

  areequal = newcost .== prevcost;
  if V println("$(sum(areequal)) new codes are equal"); end

  arebetter = newcost .< prevcost;
  if V println("$(sum(arebetter)) new codes are better"); end

  B[:, .~arebetter] = oldB[:, .~arebetter]

  return B
end

max_issues_repo_name: xiaosu-zhu/local-search-quantization

max_forks_repo_name: xiaosu-zhu/local-search-quantization


text:
#!/usr/bin/env julia

using ArgParse

s = ArgParseSettings()
@add_arg_table s begin
    "-M"
    help = "Print out the list of files this program will create."
    action = :store_true
    "config"
    help = "a YAML configuration file"
    default = "config.yaml"
end

parsed_args = parse_args(ARGS, s)

import YAML
config = YAML.load(open(parsed_args["config"]))

using DiskTracer.model
using DiskTracer.constants
using DiskTracer.geometry
using DiskTracer.trace

species = config["species"]
transition = config["transition"]
lam0 = lam0s[species*transition]
model = config["model"]
pars = convert_dict(config["parameters"], config["model"])

mol = mols[species*transition]

using NPZ

# Set up the grid interpolators
nr=128
rmax = 500 * AU
nz=128
zmax = 200 * AU

# Get the interpolator object for this particular setup.
interp = DiskTracer.model.get_grids(pars, mol, mol.nu_0, nr, rmax, nz, zmax)

npix = 128
xs = linspace(-500 * AU, 500 * AU, npix)
ys = linspace(-500 * AU, 500 * AU, npix)

nv = 9
vs = linspace(-4.0, 4.0, nv)

img = zeros(Float64, npix, npix, nv)
# tau = zeros(Float64, npix, npix, nv)
mask = Array{Bool}(npix, npix, nv)
mask_height = Array{Bool}(npix, npix, nv)

tic()
# Fill the boolean mask and trace image
for k=1:nv
    for j=1:npix
        for i=1:npix
            # Calculate DeltaVmax for this ray
            rcyl_min = abs(xs[i])
            DV2_max, junk, junk2 = interp(rcyl_min, 0.0)
            DeltaVmax = sqrt(DV2_max) * 1e-5 # km/s
            # println(DeltaVmax)
            # DeltaVmax = sqrt(2 * kB * temperature(rcyl_min, pars)/mol.mol_weight + (pars.ksi * 1e5)^2) * 1e-5 # km/s

            yes = verify_pixel(xs[i], ys[j], pars, vs[k], DeltaVmax, 400*AU)
            mask[j,i,k] = yes
            mask_height[j,i,k] = verify_pixel_height(xs[i], ys[j], pars, vs[k], DeltaVmax, 400*AU, 0.5)
            if yes
                # img[j,i,k], tau[j,i,k] = trace_pixel(xs[i], ys[j], vs[k], mol, pars, interp; get_tau=true)
                img[j,i,k] = trace_pixel(xs[i], ys[j], vs[k], mol, pars, interp)
            end
        end
    end
end
toc()

# Save the channel maps and mask
npzwrite("img.npy", img)
# npzwrite("tau.npy", tau)
npzwrite("mask.npy", mask)
npzwrite("mask_height.npy", mask_height)


text:
using Test
using Metatheory
using Metatheory.Library
using Metatheory.EGraphs
using Metatheory.Rules
using Metatheory.EGraphs.Schedulers

function rep(x, op, n::Int)
    foldl((x, y) -> :(($op)($x, $y)), repeat([x], n))
end

macro rep(x, op, n::Int)
    expr = rep(x, op, n)
    esc(expr)
end

rep(:a, :*, 3)

@rule (@rep :a (*) 3) => :b

Mid = @theory a begin
    a * :ε --> a
    :ε * a --> a
end

Massoc = @theory a b c begin
    a * (b * c) --> (a * b) * c
    (a * b) * c --> a * (b * c)
end

T = [
    @rule :b * :B --> :ε
    @rule :a * :a --> :ε
    @rule :b * :b * :b --> :ε
    @rule :B * :B --> :B
    @rule (@rep (:a * :b) (*) 7) --> :ε
    @rule (@rep (:a * :b * :a * :B) (*) 7) --> :ε
    # RewriteRule(makepattern(rep(:(:a * :b), :*, 7)), :ε)
    # RewriteRule(makepattern(rep(:(:a * :b * :a * :B), :*, 12)), :ε)
]

G = Mid ∪ Massoc ∪ T
expr = :(a * b * a * a * a * b * b * b * a * B * B * B * B * a)

ex = expr
g = EGraph(expr)
params = SaturationParams(timeout=8, scheduler=BackoffScheduler)# , schedulerparams=(128,4))#, scheduler=SimpleScheduler)
@timev saturate!(g, G, params)
ex = extract!(g, astsize)
@test ex == :ε

another_expr = :(b * B)
g = EGraph(another_expr)
saturate!(g, G, params)

another_expr = :(a * a * a * a)
some_eclass, _ = addexpr!(g, another_expr)
saturate!(g, G, params)
ex = extract!(g, astsize; root=some_eclass.id)
@test ex == :ε