text:
# test core language features

# basic type relationships
@test Int8 <: Integer
@test Int32 <: Integer
@test (Int8,Int8) <: (Integer,Integer)
@test !(AbstractArray{Float64,2} <: AbstractArray{Number,2})
@test !(AbstractArray{Float64,1} <: AbstractArray{Float64,2})
@test (Integer,Integer...) <: (Integer,Real...)
@test (Integer,Float64,Integer...) <: (Integer,Number...)
@test (Integer,Float64) <: (Integer,Number...)
@test (Int32,) <: (Number...)
@test () <: (Number...)
@test !((Int32...) <: (Int32,))
@test !((Int32...) <: (Number,Integer))
@test !((Integer...,) <: (Integer,Integer,Integer...))
@test !(Array{Int8,1} <: Array{Any,1})
@test !(Array{Any,1} <: Array{Int8,1})
@test Array{Int8,1} <: Array{Int8,1}
@test !(Type{None} <: Type{Int32})
@test !(Vector{Float64} <: Vector{Union(Float64,Float32)})
@test is(None, typeintersect(Vector{Float64},Vector{Union(Float64,Float32)}))

@test !isa(Array,Type{Any})
@test Type{Complex} <: DataType
@test isa(Complex,Type{Complex})
@test !(Type{Ptr{None}} <: Type{Ptr})
@test !(Type{Rational{Int}} <: Type{Rational})
let T = TypeVar(:T,true)
    @test !is(None, typeintersect(Array{None},AbstractArray{T}))
    @test  is(None, typeintersect((Type{Ptr{Uint8}},Ptr{None}),
                                  (Type{Ptr{T}},Ptr{T})))
    @test !(Type{T} <: TypeVar)

    @test isequal(typeintersect((Range{Int},(Int,Int)),(AbstractArray{T},Dims)),
                  (Range{Int},(Int,Int)))

    @test isequal(typeintersect((T, AbstractArray{T}),(Number, Array{Int,1})),
                  (Int, Array{Int,1}))

    @test isequal(typeintersect((T, AbstractArray{T}),(Int, Array{Number,1})),
                  None)

    @test isequal(typeintersect((T, AbstractArray{T}),(Any, Array{Number,1})),
                  (Number, Array{Number,1}))
    @test !is(None, typeintersect((Array{T}, Array{T}), (Array, Array{Any})))
    f47{T}(x::Vector{Vector{T}}) = 0
    @test_throws f47(Array(Vector,0))
    @test f47(Array(Vector{Int},0)) == 0
    @test typeintersect((T,T), (Union(Float64,Int64),Int64)) == (Int64,Int64)
    @test typeintersect((T,T), (Int64,Union(Float64,Int64))) == (Int64,Int64)

    TT = TypeVar(:T,Top)
    S = TypeVar(:S,true); N = TypeVar(:N,true)
    @test typeintersect(Type{TypeVar(:T,Array{TT,1})},Type{Array{S,N}}) == Type{Array{S,1}}
    # issue #5359
    @test typeintersect((Type{Array{T,1}},Array{T,1}),
                        (Type{AbstractVector},Vector{Int})) === None
    # issue #5559
    @test typeintersect((Type{Vector{Complex128}}, AbstractVector),
                        (Type{Array{T,N}}, Array{S,N})) == (Type{Vector{Complex128}},Vector)
    @test typeintersect((Type{Vector{Complex128}}, AbstractArray),
                        (Type{Array{T,N}}, Array{S,N})) == (Type{Vector{Complex128}},Vector)

    @test typeintersect(Type{Array{T}}, Type{AbstractArray{T}}) === None
end
let N = TypeVar(:N,true)
    @test isequal(typeintersect((NTuple{N,Integer},NTuple{N,Integer}),
                                ((Integer,Integer), (Integer...))),
                  ((Integer,Integer), (Integer,Integer)))
    @test isequal(typeintersect((NTuple{N,Integer},NTuple{N,Integer}),
                                ((Integer...), (Integer,Integer))),
                  ((Integer,Integer), (Integer,Integer)))
    local A = typeintersect((NTuple{N,Any},Array{Int,N}),
                            ((Int,Int...),Array))
    local B = ((Int,Int...),Array{Int,N})
    @test A<:B && B<:A
    @test isequal(typeintersect((NTuple{N,Any},Array{Int,N}),
                                ((Int,Int...),Array{Int,2})),
                  ((Int,Int), Array{Int,2}))
end
@test is(None, typeintersect(Type{Any},Type{Complex}))
@test is(None, typeintersect(Type{Any},Type{TypeVar(:T,Real)}))
@test !(Type{Array{Integer}} <: Type{AbstractArray{Integer}})
@test !(Type{Array{Integer}} <: Type{Array{TypeVar(:T,Integer)}})
@test is(None, typeintersect(Type{Function},UnionType))
@test is(Type{Int32}, typeintersect(Type{Int32},DataType))
@test !(Type <: TypeVar)
@test !is(None, typeintersect(DataType, Type))
@test !is(None, typeintersect(UnionType, Type))
@test !is(None, typeintersect(DataType, Type{Int}))
@test !is(None, typeintersect(DataType, Type{TypeVar(:T,Int)}))
@test !is(None, typeintersect(DataType, Type{TypeVar(:T,Integer)}))

@test isa(Int,Type{TypeVar(:T,Number)})
@test !isa(DataType,Type{TypeVar(:T,Number)})
@test DataType <: Type{TypeVar(:T,Type)}

@test isa((),Type{()})
@test (DataType,) <: Type{TypeVar(:T,Tuple)}
@test !((Int,) <: Type{TypeVar(:T,Tuple)})
@test isa((Int,),Type{TypeVar(:T,Tuple)})

@test !isa(Type{(Int,Int)},Tuple)
@test Type{(Int,Int)} <: Tuple
@test Type{(Int,)} <: (DataType,)

# this is fancy: know that any type T<:Number must be either a DataType or a UnionType
@test Type{TypeVar(:T,Number)} <: Union(DataType,UnionType)
@test !(Type{TypeVar(:T,Number)} <: DataType)
@test Type{TypeVar(:T,Tuple)} <: Union(Tuple,UnionType)
@test !(Type{TypeVar(:T,Tuple)} <: Union(DataType,UnionType))

@test !is(None, typeintersect((DataType,DataType),Type{TypeVar(:T,(Number,Number))}))
@test !is(None, typeintersect((DataType,UnionType),Type{(Number,None)}))

# issue #2997
let T = TypeVar(:T,Union(Float64,Array{Float64,1}),true)
    @test typeintersect(T,Real) === Float64
end

# join
@test typejoin(Int8,Int16) === Signed
@test typejoin(Int,String) === Any
@test typejoin(Array{Float64},BitArray) <: AbstractArray
@test typejoin(Array{Bool},BitArray) <: AbstractArray{Bool}
@test typejoin((Int,Int8),(Int8,Float64)) === (Signed,Real)
@test Base.typeseq(typejoin((ASCIIString,ASCIIString),(UTF8String,ASCIIString),
                            (ASCIIString,UTF8String),(Int,ASCIIString,Int)),
                   (Any,String,Int...))
@test Base.typeseq(typejoin((Int8,Int...),(Int8,Int8)),
                   (Int8,Signed...))
@test Base.typeseq(typejoin((Int8,Int...),(Int8,Int8...)),
                   (Int8,Signed...))
@test Base.typeseq(typejoin((Int8,Uint8,Int...),(Int8,Int8...)),
                   (Int8,Integer...))
@test Base.typeseq(typejoin(Union(Int,String),Int), Union(Int,String))
@test Base.typeseq(typejoin(Union(Int,String),Int8), Any)

@test promote_type(Bool,None) === Bool

# ntuples
nttest1{n}(x::NTuple{n,Int}) = n
@test nttest1(()) == 0
@test nttest1((1,2)) == 2
@test NTuple <: Tuple
@test NTuple{TypeVar(:T),Int32} <: (Int32...)
@test !(NTuple{TypeVar(:T),Int32} <: (Int32,Int32...))
@test (Int32...) <: NTuple{TypeVar(:T),Int32}
@test (Int32,Int32...) <: NTuple{TypeVar(:T),Int32}

# type declarations

abstract Sup_{A,B}
abstract Qux_{T} <: Sup_{Qux_{Int},T}

@test Qux_{Int}.super <: Sup_
@test is(Qux_{Int}, Qux_{Int}.super.parameters[1])
@test is(Qux_{Int}.super.parameters[2], Int)
@test Qux_{Char}.super <: Sup_
@test is(Qux_{Int}, Qux_{Char}.super.parameters[1])
@test is(Qux_{Char}.super.parameters[2], Char)

@test Qux_.super.parameters[1].super <: Sup_
@test is(Qux_{Int}, Qux_.super.parameters[1].super.parameters[1])
@test is(Int, Qux_.super.parameters[1].super.parameters[2])

type Foo_{T} x::Foo_{Int} end

@test is(Foo_.types[1], Foo_{Int})
@test is(Foo_.types[1].types[1], Foo_{Int})

type Circ_{T} x::Circ_{T} end
@test is(Circ_{Int}, Circ_{Int}.types[1])

# issue #3890
type A3890{T1}
    x::Matrix{Complex{T1}}
end
@test A3890{Float64}.types[1] === Array{Complex{Float64},2}
# make sure the field type Matrix{Complex{T1}} isn't cached
type B3890{T2}
    x::Matrix{Complex{T2}}
end
@test B3890{Float64}.types[1] === Array{Complex{Float64},2}

# issue #786
type Node{T}
    v::Vector{Node}
end

@test is(Node{Int}.types[1].parameters[1], Node)

type Node2{T}
    v::Vector{Node2{T}}
end

@test is(Node2{Int}.types[1].parameters[1], Node2{Int})

type FooFoo{A,B} y::FooFoo{A} end

@test FooFoo{Int} <: FooFoo{Int,String}.types[1]

x = (2,3)
@test +(x...) == 5

# bits types
if WORD_SIZE == 64
    @test isa((()->Intrinsics.box(Ptr{Int8},Intrinsics.unbox(Int64,0)))(), Ptr{Int8})
else
    @test isa((()->Intrinsics.box(Ptr{Int8},Intrinsics.unbox(Int32,0)))(), Ptr{Int8})
end
@test isa(convert(Char,65), Char)

# conversions
function fooo()
    local x::Int8
    x = 1000
    x
end
@test int32(fooo()) == -24
function fooo_2()
    local x::Int8
    x = 1000
end
@test fooo_2() == 1000
function fooo_3()
    local x::Int8
    y = x = 1000
    @test x == -24
    y
end
@test fooo_3() == 1000
function foo()
    local x::Int8
    function bar()
        x = 1000
    end
    bar()
    x
end
@test int32(foo()) == -24

function bar{T}(x::T)
    local z::Complex{T}
    z = x
    z
end
@test bar(3.0) == Complex(3.0,0.0)

z = convert(Complex{Float64},2)
@test z == Complex(2.0,0.0)

# misc
fib(n) = n < 2 ? n : fib(n-1) + fib(n-2)
@test fib(20) == 6765

# static parameters
sptest1{T}(x::T, y::T) = 42
sptest1{T,S}(x::T, y::S) = 43
@test sptest1(1,2) == 42
@test sptest1(1,"b") == 43

sptest2{T}(x::T) = T
@test is(sptest2(:a),Symbol)

sptest3{T}(x::T) = y->T
let m = sptest3(:a)
    @test is(m(0),Symbol)
end

# closures
function clotest()
    c = 0
    function inc()
        c += 1
    end
    function dec()
        c -= 1
    end
    inc(); inc()
    @test c == 2
    dec()
    @test c == 1
    @test (()->c)() == 1

    fibb(n) = n < 2 ? n : fibb(n-1)+fibb(n-2)
    assert(fibb(10)==55)

    return (n->(c+=n), ()->c)
end
let T = clotest()
    (inc, C) = T
    inc(11)
    @test C() == 12
end

Yc(f) = (h->f(x->h(h)(x)))(h->f(x->h(h)(x)))
yfib = Yc(fib->(n->(n < 2 ? n : fib(n-1) + fib(n-2))))
@test yfib(20) == 6765

# variable scope, globals
glob_x = 23
function glotest()
    global glob_x
    glob_x = 24
    loc_x = 8
    function inner()
        global loc_x = 10
        glob_x = 88
    end
    function inner2()
        local glob_x  # override
        global loc_x
        glob_x = 2
        @test glob_x == 2
        @test loc_x == 10
    end
    inner()
    inner2()
    @test glob_x == 88
    @test loc_x == 8
end
glotest()
@test glob_x == 88
@test loc_x == 10

# let - new variables, including undefinedness
function let_undef()
    first = true
    for i = 1:2
        let x
            if first; x=1; first=false; end
            x+1
        end
    end
end
@test_throws let_undef()

# const implies local in a local scope block
function const_implies_local()
    let
        x = 1
        local y
        let
            const x = 0
            y = x
        end
        x, y
    end
end
@test const_implies_local() === (1, 0)

a = cell(3)
for i=1:3
    let ii = i
        a[i] = x->x+ii
    end
end
@test a[1](10) == 11
@test a[2](10) == 12
@test a[3](10) == 13

# syntax
@test (true ? 1 : false ? 2 : 3) == 1

# tricky space sensitive syntax cases
@test [-1 ~1] == [(-1) (~1)]

# undefinedness
type UndefField
    field
    UndefField() = new()
end

begin
    local a
    a = cell(2)
    @test !isdefined(a,1) && !isdefined(a,2)
    a[1] = 1
    @test isdefined(a,1) && !isdefined(a,2)
    a = Array(Float64,1)
    @test isdefined(a,1)
    @test isdefined(a)
    @test !isdefined(a,2)

    a = UndefField()
    @test !isdefined(a, :field)
    @test !isdefined(a, :foo)
    @test !isdefined(2, :a)

    @test  isdefined("a",:data)
    @test  isdefined("a", 1)
    @test !isdefined("a", 2)

    @test_throws isdefined(2)
end

# dispatch
begin
    local foo, bar, baz
    foo(x::(Any...))=0
    foo(x::(Integer...))=1
    @test foo((:a,))==0
    @test foo(( 2,))==1

    bar{T}(x::(T,T,T,T))=1
    bar(x::(Any,Any,Any,Any))=2
    @test bar((1,1,1,1)) == 1
    @test bar((1,1,1,"a")) == 2
    @test bar((:a,:a,:a,:a)) == 1

    baz(::Type{Rational}) = 1
    baz{T}(::Type{Rational{T}}) = 2
    @test baz(Rational) == 1
    @test baz(Rational{Int}) == 2
end

begin
    local mytype
    function mytype(vec)
        convert(Vector{(ASCIIString, DataType)}, vec)
    end
    some_data = {("a", Int32), ("b", Int32)}
    @test isa(mytype(some_data),Vector{(ASCIIString, DataType)})
end

type MyArray{N} <: AbstractArray{Int, N}
end
begin
    local x
    x = MyArray{1}()
    foob(x::AbstractArray)=0
    foob{T}(x::AbstractVector{T})=1
    @test foob(x) == 1
end

begin
    local f, g, a
    f{T}(a::Vector{Vector{T}}) = a
    g{T}(a::Vector{Vector{T}}) = a
    a = Vector{Int}[]
    @test is(f(a), a)
    @test is(g(a), a)
end

type _AA{T}; a::T; end
typealias _AoA{T} _AA{_AA{T}}
begin
    local g, a
    g{T}(a::_AA{_AA{T}}) = a
    a = _AA(_AA(1))
    @test is(g(a),a)
end

# try/finally
begin
    after = 0
    b = try
        1+2
    finally
        after = 1
    end
    @test b == 3
    @test after == 1

    after = 0
    gothere = 0
    try
        try
            error(" ")
        finally
            after = 1
        end
        gothere = 1
    end
    @test after == 1
    @test gothere == 0

    after = 0
    b = try
        error(" ")
    catch
        42
    finally
        after = 1
    end
    @test b == 42
    @test after == 1

    glo = 0
    function retfinally()
        try
            return 5
        finally
            glo = 18
        end
    end
    @test retfinally() == 5
    @test glo == 18
end

# chained and multiple assignment behavior (issue #2913)
begin
    local x, a, b, c, d, e
    x = (a,b,b,b,e) = (1,2,3,4,5)
    @test x === (1,2,3,4,5)
    @test a == 1
    @test b == 4
    @test e == 5
    x = (a,b,b,e) = (1,2,3,4,5)
    @test x === (1,2,3,4,5)
    @test a == 1
    @test b == 3
    @test e == 4

    a = complex(1,2)
    b = 3
    b, a = a.re, b
    @test b == 1
    @test a == 3
    a = complex(1,2)
    b = 3
    a, b = b, a.re
    @test a == 3
    @test b == 1
end

# accessing fields by index
begin
    local z = complex(3, 4)
    v = Int[0,0]
    for i=1:2
        v[i] = getfield(z, i)
    end
    @test v == [3,4]
    @test_throws getfield(z, -1)
    @test_throws getfield(z, 0)
    @test_throws getfield(z, 3)

    strct = LoadError("", 0, "")
    setfield!(strct, 2, 8)
    @test strct.line == 8
    setfield!(strct, 3, "hi")
    @test strct.error == "hi"
    setfield!(strct, 1, "yo")
    @test strct.file == "yo"
    @test_throws getfield(strct, 10)
    @test_throws setfield!(strct, 0, "")
    @test_throws setfield!(strct, 4, "")
end

# allow typevar in Union to match as long as the arguments contain
# sufficient information
# issue #814
begin
    local MatOrNothing, my_func, M
    typealias MatOrNothing{T} Union(AbstractMatrix{T}, Vector{None})
    my_func{T<:Real}(A::MatOrNothing{T}, B::MatOrNothing{T},
                     C::MatOrNothing{T}) = 0
    M = [ 2. 1. ; 1. 1. ]
    @test my_func([], M, M) == 0
end

begin
    local my_func, a, c
    my_func{T}(P::Vector{T}, Q::Vector{T}) = 0
    my_func{T}(x::T, P::Vector{T}) = 1
    # todo: this gives an ambiguity warning
    #my_func{T}(P::Vector{T}, x::T) = 2
    a = Int[3]
    c = Vector[a]

    @test my_func(c,c)==0
    @test_throws my_func(a,c)
end

begin
    local baar, foor, boor
    # issue #1131
    baar(x::DataType) = 0
    baar(x::UnionType) = 1
    baar(x::TypeConstructor) = 2
    @test baar(StridedArray) == 2
    @test baar(StridedArray.body) == 1
    @test baar(Vector) == 2
    @test baar(Vector.body) == 0

    boor(x) = 0
    boor(x::UnionType) = 1
    @test boor(StridedArray) == 0
    @test boor(StridedArray.body) == 1

    # issue #1202
    foor(x::UnionType) = 1
    @test_throws foor(StridedArray)
    @test foor(StridedArray.body) == 1
    @test_throws foor(StridedArray)
end

# issue #1153
type SI{m, s, kg}
    value::FloatingPoint
end

import Base.*

*{m1, m2, s1, s2, kg1, kg2}(x::SI{m1, s1, kg1}, y::SI{m2, s2, kg2}) = SI{m1 + m2, s1 + s2, kg1 + kg2}(x.value * y.value)

begin
    local a,b
    a = SI{0,0,1}(1.0) * SI{1,2,0}(2.0)
    b = SI{0,0,1}(1.0) * SI{1,-2,0}(2.0)
    @test typeof(a) === SI{1,2,1}
    @test typeof(b) === SI{1,-2,1}
end

# pull request 1270
begin
    local a,p, a2,p2
    a = [11,12,13]
    p = pointer(a)
    @test unsafe_load(p, 1) == 11
    unsafe_store!(p, 99, 2)
    @test a == [11,99,13]
    a2 = Any[101,102,103]
    p2 = pointer(a2)
    @test unsafe_load(p2) == 101
    unsafe_store!(p2, 909, 3)
    @test a2 == [101,102,909]
end

@test unsafe_pointer_to_objref(ccall(:jl_call1, Ptr{Void}, (Any,Any),
                                     x -> x+1, 314158)) == 314159
@test unsafe_pointer_to_objref(pointer_from_objref(e+pi)) == e+pi

immutable FooBar
    foo::Int
    bar::Int
end
begin
    local X, p
    X = FooBar[ FooBar(3,1), FooBar(4,4) ]
    p = convert(Ptr{FooBar}, X)
    @test unsafe_load(p, 2) == FooBar(4,4)
    unsafe_store!(p, FooBar(7,3), 1)
    @test X[1] == FooBar(7,3)
end

# issue #1287, combinations of try, catch, return
begin
    local f, g

    function f()
        try
            return 1
        end
    end
    @test f() == 1

    function g()
        try
            error("badness")
        catch
            return 2
        end
    end
    @test g() == 2
end

# issue #1442
type S1442{T}
end

begin
    local f1442
    f1442(::DataType) = 1
    f1442{T}(::Type{S1442{T}}) = 2

    @test f1442(S1442{Int}) == 2
    @test f1442(DataType) == 1
end

# issue #1727
abstract Component

type Transform <: Component
  x
  y
  z

  Transform() = new(0, 0, 0)
end

type Body <: Component
  vel
  curr_force

  Body() = new(0, 0)
end

function NewEntity{ T<:Component }(components::Type{T}...)
  map((c)->c(), components)
end

@test_throws NewEntity(Transform, Transform, Body, Body)
@test isa(NewEntity(Transform, Transform), (Transform, Transform))
@test_throws NewEntity(Transform, Transform, Body, Body)

# issue #1826
let
    a = (1,2)
    a,b = a
    @test a==1 && b==2
end

# issue #1876
let
    tst = 1
    m1(i) = (tst+=1;i-1)
    x = [1:4]
    x[1:end] *= 2
    @test x == [2:2:8]
    x[m1(end)] += 3
    @test x == [2,4,9,8]
    @test tst == 2

    # issue #1886
    X = [1:4]
    r = Array(Range1{Int},1)
    r[1] = 2:3
    X[r...] *= 2
    @test X == [1,4,6,4]
end

# issue #1632
let
    f1632{R,S}(::R, ::S) = 1
    f1632{T}(  ::T, ::T) = 2
    @test f1632(1, 2) == 2
    @test f1632(:a, 2) == 1
    g1632{T}(  ::T, ::T) = 2
    g1632{R,S}(::R, ::S) = 1
    @test g1632(1, 2) == 2
    @test g1632(:a, 2) == 1
end

# issue #1628
type I1628{X}
    x::X
end
let
    # here the potential problem is that the run-time value of static
    # parameter X in the I1628 constructor is (DataType,DataType),
    # but type inference will track it more accurately as
    # (Type{Integer}, Type{Int}).
    f1628() = I1628((Integer,Int))
    @test isa(f1628(), I1628{(DataType,DataType)})
end

let
    fT{T}(x::T) = T
    @test fT(Any) === DataType
    @test fT(Int) === DataType
    @test fT(Type{Any}) === DataType
    @test fT(Type{Int}) === DataType

    ff{T}(x::Type{T}) = T
    @test ff(Type{Any}) === Type{Any}
    @test ff(Type{Int}) === Type{Int}
    @test ff(Any) === Any
    @test ff(Int) === Int
end

# issue #2098
let
    i2098() = (c={2.0};[1:1:c[1]])
    @test isequal(i2098(), [1.0,2.0])
end

# issue #2161
let
    i2161_1() = promote(2,2,2.0,2)
    i2161_2() = i2161_1()[1]
    @test i2161_2() === 2.0
end

# issue #2169
let
    i2169{T}(a::Array{T}) = typemin(T)
    @test invoke(i2169,(Array,),Int8[1]) === int8(-128)
end

# issue #2365
type B2365{T}
     v::Union(T, Nothing)
end
@test B2365{Int}(nothing).v === nothing
@test B2365{Int}(0).v === 0

# issue #2352
begin
    local Sum, n
    Sum=0.0; for n=1:2:10000
        Sum += -1/n + 1/(n+1)
    end
    @test Sum < -0.69
end

include("test_sourcepath.jl")

# issue #2509
immutable Foo2509; foo::Int; end
@test Foo2509(1) != Foo2509(2)
@test Foo2509(42) == Foo2509(42)

# issue #2517
immutable Foo2517; end
@test repr(Foo2517()) == "Foo2517()"
@test repr(Array(Foo2517,1)) == "[Foo2517()]"
@test Foo2517() === Foo2517()

# issue #1474
type X1474{a,b} end
begin
    local Y
    Y{A,B}(::Type{X1474{A,B}}) = 1
    Y{A}(::Type{X1474{A}}) = 2
    Y(::Type{X1474}) = 3
    @test Y(X1474) == 3
    @test Y(X1474{Int}) == 2
    @test Y(X1474{Int,String}) == 1
end

# issue #2562
type Node2562{T}
    value::T
    Node2562(value::T) = new(value)
end
Node2562{T}(value::T, args...) = Node2562{T}(value, args...)
makenode2562(value) = Node2562(value)
@test isa(Node2562(0), Node2562)
@test isa(makenode2562(0), Node2562)

# issue #2619
type I2619{T}
    v::T
    I2619(v) = new(convert(T,v))
end
bad2619 = false
function i2619()
    global e2619 = try
        I2619{Float64}(0.0f)
        global bad2619 = true
    catch _e
        _e
    end
end
i2619()
@test !bad2619
@test isa(e2619,UndefVarError) && e2619.var === :f

# issue #2919
typealias Foo2919 Int
type Baz2919; Foo2919::Foo2919; end
@test Baz2919(3).Foo2919 === 3

# issue #2982
module M2982
abstract U
macro bad(Y)
    quote
        type $(esc(Y)) <: U
        end
    end
end
export @bad
end

@M2982.bad(T2982)
@test T2982.super === M2982.U

# issue #3182
f3182{T}(::Type{T}) = 0
f3182(x) = 1
function g3182(t::DataType)
    # tricky thing here is that DataType is a concrete type, and a
    # subtype of Type, but we cannot infer the T in Type{T} just
    # by knowing (at compile time) that the argument is a DataType.
    # however the ::Type{T} method should still match at run time.
    f3182(t)
end
@test g3182(Complex) == 0

# issue #3221
let x = fill(nothing, 1)
    @test_throws x[1] = 1
end

# issue #3220
function x3220()
    a = [1]
    a::Vector{Int} += [1]
end
@test x3220() == [2]

# issue #3471
function f3471(y)
    convert(Array{typeof(y[1]),1}, y)
end
@test isa(f3471({1.0,2.0}), Vector{Float64})

# issue #3729
typealias A3729{B} Vector{Vector{B}}
typealias C3729{D} Vector{Vector{D}}
@test Vector{Vector{Int}} === A3729{Int} === C3729{Int}

# issue #3789
x3789 = 0
while(all([false for idx in 1:10]))
    x3789 = 1
end
@test x3789 == 0

# issue #3852
function f3852()
    local x
    for i = 1:10
        x = identity
    end
    x("hi")
end
@test f3852() == "hi"

# issue #3821
function f3821()
    p = []
    [x for x in p]
end
@test isa(f3821(), Array)

# issue #4075
immutable Foo4075
    x::Int64
    y::Float64
end

function foo4075(f::Foo4075, s::Symbol)
    x = getfield(f,s)
    gc()
    x
end

@test isa(foo4075(Foo4075(int64(1),2.0),:y), Float64)
# very likely to segfault the second time if this is broken
@test isa(foo4075(Foo4075(int64(1),2.0),:y), Float64)

# issue #3167
function foo(x)
    ret=Array(typeof(x[1]), length(x))
    for j = 1:length(x)
        ret[j] = x[j]
    end
    return ret
end
x = Array(Union(Dict{Int64,String},Array{Int64,3},Number,String,Nothing), 3)
x[1] = 1.0
x[2] = 2.0
x[3] = 3.0
foo(x) == [1.0, 2.0, 3.0]

# issue #4115
type Foo4115
end
typealias Foo4115s NTuple{3,Union(Foo4115,Type{Foo4115})}
baz4115(x::Foo4115s) = x
@test baz4115((Foo4115,Foo4115,Foo4115())) === (Foo4115,Foo4115,Foo4115())

# issue #4129
type Foo4129; end

abstract Bar4129

type Bar41291 <: Bar4129
    f::Foo4129
end
type Bar41292 <: Bar4129
    f::Foo4129
end

type Baz4129
    b::Bar4129
end

foo4129(a::Baz4129,c::Foo4129,b::Bar4129,x::ANY,y) = (a,b,c,x,y)
foo4129(a::Baz4129,b::Bar41291,args...) = foo4129(a,b.f,b,args...)
foo4129(a::Baz4129,b::Bar41292,args...) = foo4129(a,b.f,b,args...)
foo4129(a::Baz4129,args...)         = foo4129(a,a.b,args...)

@test isa(foo4129(Baz4129(Bar41291(Foo4129())),1,2), (Baz4129,Bar4129,Foo4129,Int,Int))

# issue #4141
type Vertex4141{N,T}; end
type Face4141{V}; end
type Hull4141{F<:Face4141}; end

g4141(N,T) = Hull4141{Face4141{Vertex4141{N,T}}}()
@test isa(g4141(4,Int), Hull4141{Face4141{Vertex4141{4,Int}}})

# issue #4154
type MyType4154{T}
    a1::T
    a2
end

foo4154(x) = MyType4154(x, {})
h4154() = typeof(foo4154(rand(2,2,2)))
g4154() = typeof(foo4154(rand(2,2,2,2,2,2,2,2,2)))

@test h4154() === MyType4154{Array{Float64,3}}
@test g4154() === MyType4154{Array{Float64,9}}

# issue #4208
type a4208
    a4208
end
@test isa(a4208(5),a4208)
type b4208
    b4208() = (local b4208=1;new())
end
@test isa(b4208(),b4208)

# make sure convert_default error isn't swallowed by typeof()
convert_default_should_fail_here() = similar([1],typeof(zero(typeof(rand(2,2)))))
@test_throws convert_default_should_fail_here()

# issue #4343
@test_throws Array{Float64}{Int, 2}

type Foo4376{T}
    x
    Foo4376(x::T) = new(x)
    Foo4376(a::Foo4376{Int}) = new(a.x)
end

@test isa(Foo4376{Float32}(Foo4376{Int}(2)), Foo4376{Float32})
@test_throws Foo4376{Float32}(Foo4376{Float32}(2.0f0))

type _0_test_ctor_syntax_
    _0_test_ctor_syntax_{T<:String}(files::Vector{T},step) = 0
end

# issue #4413
type A4413 end
type B4413 end
type C4413 end
f4413(::Union(A4413, B4413, C4413)) = "ABC"
f4413(::Union(A4413, B4413)) = "AB"
g4413(::Union(A4413, C4413)) = "AC"
g4413(::Union(A4413, B4413, C4413)) = "ABC"

@test f4413(A4413()) == "AB" && f4413(B4413()) == "AB"
@test g4413(A4413()) == "AC" && g4413(C4413()) == "AC"

# issue #4482
# what happens here: the method cache logic wants to widen the type of a
# tuple argument, but it shouldn't do that for an argument that a static
# parameter depends on.
f4482{T}(x::T) = T
@test f4482((Ptr,Ptr)) === (DataType,DataType)
@test f4482((Ptr,))    === (DataType,)

# issue #4486
try
    # note: this test expression must run at the top level,
    # in the interpreter.
    (function() end)(1)
    # should throw an argument count error
    @test false
end

# issue #4526
f4526(x) = isa(x.a, Nothing)
@test_throws f4526(1)
@test_throws f4526(im)
@test_throws f4526(1+2im)

# issue #4528
function f4528(A, B)
    if A
        reinterpret(Uint64, B)
    end
end
@test f4528(false, int32(12)) === nothing
@test_throws f4528(true, int32(12))

# issue #4518
f4518(x, y::Union(Int32,Int64)) = 0
f4518(x::ASCIIString, y::Union(Int32,Int64)) = 1
@test f4518("",1) == 1

# issue #4581
bitstype 64 Date4581{T}
let
    x = Intrinsics.box(Date4581{Int}, Intrinsics.unbox(Int64,int64(1234)))
    xs = Date4581[x]
    ys = copy(xs)
    @test ys !== xs
    @test ys == xs
end

# issue #4645
i4645(x) = (println(zz); zz = x; zz)
@test_throws i4645(4)

# issue #4505
let
    g4505{X}(::X) = 0
    @test g4505(0) == 0
end
@test !isdefined(:g4505)

# issue #4681
# ccall should error if convert() returns something of the wrong type
type Z4681
    x::Ptr{Void}
    Z4681() = new(C_NULL)
end
Base.convert(::Type{Ptr{Z4681}},b::Z4681) = b.x
@test_throws ccall(:printf,Int,(Ptr{Uint8},Ptr{Z4681}),"",Z4681())

# issue #4479
f4479(::Real,c) = 1
f4479(::Int, ::Int, ::Bool) = 2
f4479(::Int, x, a...) = 0
@test f4479(1,1,true) == 2

# issue #4688
a4688(y) = "should be unreachable by calling b"
b4688(y) = "not an Int"
begin
    a4688(y::Int) = "an Int"
    let x = true
        b4688(y::Int) = x == true ? a4688(y) : a4688(y)
    end
end
@test b4688(1) == "an Int"

# issue #4731
type SIQ{A,B} <: Number
    x::A
end
import Base: promote_rule
promote_rule{T,T2,S,S2}(A::Type{SIQ{T,T2}},B::Type{SIQ{S,S2}}) = SIQ{promote_type(T,S)}
@test_throws promote_type(SIQ{Int},SIQ{Float64})

# issue #4675
f4675(x::StridedArray...) = 1
f4675{T}(x::StridedArray{T}...) = 2
@test f4675(zeros(50,50), zeros(50,50)) == 2
g4675{T}(x::StridedArray{T}...) = 2
g4675(x::StridedArray...) = 1
@test g4675(zeros(50,50), zeros(50,50)) == 2

# issue #4771
module Lib4771
export @make_closure
macro make_closure()
    quote
        f = (x)->1
    end
end
end # module
@test (Lib4771.@make_closure)(0) == 1

# issue #4805
abstract IT4805{N, T}

let
    T = TypeVar(:T,Int)
    N = TypeVar(:N)
    @test typeintersect(Type{IT4805{1,T}}, Type{TypeVar(:_,IT4805{N,Int})}) != None
end

let
    test0{T <: Int64}(::Type{IT4805{1, T}}, x) = x
    test1() = test0(IT4805{1, Int64}, 1)
    test2() = test0(IT4805{1+0, Int64}, 1)
    test3(n) = test0(IT4805{n, Int64}, 1)

    @test test1() == 1
    @test test2() == 1
    @test test3(1) == 1
    @test_throws test3(2)
end

# issue #4873
macro myassert4873(ex)
    :($ex ? nothing : error("Assertion failed: ", $(string(ex))))
end
x4873 = 1
@myassert4873 (x -> x)(x4873) == 1

# issue from IRC
function invalid_tupleref()
    A = (1, "2", 3.0)
    try
        return A[0]
    catch
        return true
    end
end
@test invalid_tupleref()==true

# issue #5150
f5150(T) = Array(Rational{T},1)
@test typeof(f5150(Int)) === Array{Rational{Int},1}

# issue #5165
bitstype 64 T5165{S}
make_t(x::Int64) = Base.box(T5165{Nothing}, Base.unbox(Int64, x))
xs5165 = T5165[make_t(int64(1))]
b5165 = IOBuffer()
for x in xs5165
    println(b5165, x)   # segfaulted
end

# support tuples as type parameters

type TupleParam{P}
    x::Bool
end

function tupledispatch(a::TupleParam{(1,:a)})
    a.x
end

let
    # tuples can be used as type params
    t1 = TupleParam{(1,:a)}(true)
    t2 = TupleParam{(1,:b)}(true)

    # tuple type params can't contain invalid type params
    @test_throws t3 = TupleParam{(1,"nope")}(true)

    # dispatch works properly
    @test tupledispatch(t1) == true
    @test_throws tupledispatch(t2)
end

# issue #5254
f5254{T}(::Type{T}, b::T) = 0
f5254(a, b) = 1
@test f5254(None, 1) == 1

# evaluate arguments left-to-right, including assignments. issue #4990
let
    i = 0
    @test (i, i+=1, i+=1) === (0, 1, 2)
    @test i == 2
    x = 65
    @test [x, x|=0x20] == [65, 97]
end

# issue #5312
let
    local x = 0
    global incr5312, foo5312
    incr5312() = (x+=1; nothing)
    foo5312() = (incr5312(),)
    @test foo5312() === (nothing,)
    @test x == 1
end

# issue #5319
cnvt(T, x) = convert_default(T, x, cnvt)
cnvt{S, T, N}(::Type{Array{S, N}}, x::Array{T, N}) = convert(Array{S}, x)

function tighttypes!(adf)
    T = None
    tt = {Int}
    for t in tt
        T = typejoin(T, t)
    end
    cnvt(Vector{T}, adf[1])
end

@test isequal(tighttypes!({Any[1.0,2.0]}), [1,2])

# issue #5142
bitstype 64 Int5142
function h5142(a::Bool)
    x=a ? (int64(0),reinterpret(Int5142,int64(0))) : (int64(1),reinterpret(Int5142,int64(1)))
    x[2]::Int5142
end
function h5142(a::Int)
    x=(int64(0),reinterpret(Int5142,int64(0)))
    x[a]::Int5142
end
h5142(true)
@test_throws h5142(1)
h5142(2)

bitstype 8 Int5142b
function h5142b(a::Int)
    x=((int8(1),int8(2)),(reinterpret(Int5142b,int8(3)),reinterpret(Int5142b,int8(4))))
    x[a]::(Int8,Int8)
end
h5142b(1)
@test_throws h5142b(2)

# accessing bits tuples of structs
function test_bits_tuples()
    a = (complex(1,2),complex(1,3));s=0
    for i=1:10
        s += a[rand(1:2)]
    end
    s
end
@test real(test_bits_tuples()) == 10

# issue #5374
type FileObj5374
    io::IO
end
function read_file5374(fileobj)
    read(fileobj.io, Float32)
end
@test isa(read_file5374(FileObj5374(IOBuffer(Uint8[0,0,0,0]))), Float32)

# issue #5457
function f5457(obj_ptr::Ptr{Float64}, f)
    new_obj = convert(Float64, f(1.0))
    unsafe_store!(obj_ptr, new_obj)
    return int32(1)
end
let
    a = [1.0]
    f5457(pointer(a,1), sin)
end

# issue #5584
# this is an intermittent memory bug, but this code is very likely to trigger it
mapshape_5584{N}(s1::NTuple{N,Int}, s2::NTuple{N,Int}) =
    (s1 == s2 || error("Argument dimensions are not map-compatible."); s1)
function f5584()
    for i = 1:1000000
        a = rand(1:1000, 3)
        # the bug was a failure to root these tuples
        mapshape_5584(tuple(a...), tuple(a...))
    end
end
f5584()

# issue #5884

type Polygon5884{T<:Real}
    points::Vector{Complex{T}}
end

function test5884()
    star = Array(Polygon5884,(3,))
    star[1] = Polygon5884([Complex(1.0,1.0)])
    p1 = star[1].points[1]
    @test p1 == Complex(1.0,1.0)
    @test p1.re == 1.0
    @test star[1].points[1].re == 1.0
end
test5884()

# issue #5924
let
    function Test()
        func = function () end
        func
    end
    @test Test()() === nothing
end

# issue #5906

abstract Outer5906{T}

immutable Inner5906{T}
   a:: T
end

immutable Empty5906{T} <: Outer5906{T}
end

immutable Hanoi5906{T} <: Outer5906{T}
    a::T
    succ :: Outer5906{Inner5906{T}}
    Hanoi5906(a) = new(a, Empty5906{Inner5906{T}}())
end

function f5906{T}(h::Hanoi5906{T})
    if isa(h.succ, Empty5906) return end
    f5906(h.succ)
end

# can cause infinite recursion in type inference via instantiation of
# the type of the `succ` field
@test f5906(Hanoi5906{Int}(1)) === nothing

# make sure front end can correctly print values to error messages
let
    ex = expand(parse("\"a\"=1"))
    @test ex == Expr(:error, "invalid assignment location \"\"a\"\"") ||
          ex == Expr(:error, "invalid assignment location \"#<julia_value>\"")
end

# make sure that incomplete tags are detected correctly
# (i.e. error messages in src/julia-parser.scm must be matched correctly
# by the code in base/client.jl)
for (str, tag) in ["" => :none, "\"" => :string, "#=" => :comment, "'" => :char,
                   "`" => :cmd, "begin;" => :block, "quote;" => :block,
                   "let;" => :block, "for i=1;" => :block, "function f();" => :block,
                   "f() do x;" => :block, "module X;" => :block, "type X;" => :block,
                   "immutable X;" => :block, "(" => :other, "[" => :other,
                   "{" => :other, "begin" => :other, "quote" => :other,
                   "let" => :other, "for" => :other, "function" => :other,
                   "f() do" => :other, "module" => :other, "type" => :other,
                   "immutable" => :other]
    @test Base.incomplete_tag(parse(str, raise=false)) == tag
end

# issue #6031
macro m6031(x); x; end
@test @m6031([2,4,6])[3] == 6
@test (@m6031 [2,4,6])[2] == 4

# issue #6050
@test Base.getfield_tfunc({nothing,QuoteNode(:vals)},
                          Dict{Int64,(Range1{Int64},Range1{Int64})},
                          :vals) == Array{(Range1{Int64},Range1{Int64}),1}

# issue #6068
x6068 = 1
function test6068()
    local a
    while true
        a = x6068
        break
    end
    a + 1
end
@test test6068() == 2

# issue #6074
macro X6074()
    quote
        global x6074
        let x6074 = x6074
            x6074
        end
    end
end
x6074 = 6074
@test @X6074() == 6074

# issue #5536
test5536(a::Union(Real, AbstractArray)...) = "Splatting"
test5536(a::Union(Real, AbstractArray)) = "Non-splatting"
@test test5536(5) == "Non-splatting"

# multiline comments (#6139 and others raised in #6128)
@test 3 == include_string("1 + #=# 2") == include_string("1 + #==# 2") == include_string("1 + #===# 2") == include_string("1 + #= #= blah =# =# 2") == include_string("1 + #= #= #= nested =# =# =# 2")
@test_throws include_string("#=")
@test_throws include_string("#= #= #= =# =# =")

# issue #6142
type A6142 <: AbstractMatrix{Float64}; end
+{TJ}(x::A6142, y::UniformScaling{TJ}) = "UniformScaling method called"
+(x::A6142, y::AbstractArray) = "AbstractArray method called"
@test A6142() + I == "UniformScaling method called"

# issue #6175
function g6175(); print(""); (); end
g6175(i::Real, I...) = g6175(I...)
g6175(i, I...) = tuple(length(i), g6175(I...)...)
@test g6175(1:5) === (5,)

# issue #6242
f6242{N}(x::NTuple{N,Int})=(N==0 ? 1 : ntuple(n->x[n],N))
@test f6242(()) === 1

# issue #6292
let i = 0
    global g6292() = i+=1
end
@test g6292() == 1
@test g6292() == 2

max_stars_repo_name: alyst/julia

max_issues_repo_name: alyst/julia

max_forks_repo_name: alyst/julia


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

using Markdown
using InteractiveUtils

# ╔═╡ ab2e6b79-24f3-4736-8e9e-8362a7efd718
begin
	using Revise
	using Unitful
	using UnitfulUS
	using Match
	using DataStructures
	# using UnitfulCurrency
	using NativeSVG
	using DisplayAs
	using UUIDs
	using Plots
	using Printf
	using Logging
	using VectorLogging
	using PanelCutting
end

# ╔═╡ 202a21c7-e92a-4636-9859-c27626a96edc
WantedPanel

# ╔═╡ 60eb1ca9-cf1f-46d6-b9b9-ee9fb41723d1
md"""
  # Setup

  Prefer inches.
  """

# ╔═╡ e25b3bb7-93b3-4859-be30-ef912041479f
Logging.global_logger(VectorLogger())

# ╔═╡ 60fdb133-5d21-4445-90f9-3bbe49fb743b
begin
  Unitful.preferunits(u"inch")
end

# ╔═╡ 0f1516c2-e12d-439c-b57d-3af903cbf3f6
WantedPanel

# ╔═╡ ecacafd3-5f70-41d9-b6cd-6b4893186b2a
begin
  wanda_box_panels = [
    WantedPanel(length=25u"inch", width=30u"inch", label="back")
    WantedPanel(length=25u"inch", width=22u"inch", label="right side")
    WantedPanel(length=25u"inch", width=22u"inch", label="left side")
    WantedPanel(length=22u"inch", width=30u"inch", label="top")
    WantedPanel(length=22u"inch", width=30u"inch", label="bottom")
  ]
  sort(wanda_box_panels; lt=smaller, rev=true)
end

# ╔═╡ f6a43438-d7b0-442d-bb05-9e4488855665
md"""
  ### Supplier Data

  Taken from boulterplywood.com
  """

# ╔═╡ 65adef2d-9a53-4310-81a0-5dbb6d0918ca
begin    # Supplier Data

  BOULTER_PLYWOOD = Supplier(
		name = "Boulter Plywood",
		kerf = (1/8)u"inch",
		cost_per_cut = money(1.50),
		available_stock = [
    AvailablePanel("4 x 8 x 1/2", 4u"ft", 8u"ft", money(95.00)),
    AvailablePanel("5 x 5 x 1/2", 5u"ft", 5u"ft", money(49.00)),
    AvailablePanel("30 x 60 x 1/2", 30u"inch", 60u"inch", money(30.00)),
    AvailablePanel("30 x 30 x 1/2", 30u"inch", 30u"inch", money(19.00))
  ])
end

# ╔═╡ 85f95152-93a2-42cd-80f3-c3d7d931dbfe
md"""
# Describing the Cuts using SVG
"""

# ╔═╡ 134ac318-adb5-4939-96f7-3b70b12ffe43
#=
macro thismodule()
	:($__module__)
end
=#

# ╔═╡ 4cd74059-f59b-46e4-be23-bfbd95e4d96d
md"""
# Generic Dot Code
"""

# ╔═╡ f89c8f2e-8bdf-4d4e-8090-3f6a56e0ce85
  function PanelCutting.dotID(panel::AbstractPanel)
	t = split(string(typeof(panel)), ".")[end]
 	"$(t)_$(string(panel.uid))"
  end

# ╔═╡ dcbc9193-fa7a-435b-8f68-05b77e1d9b36
md"""
# Panel Progression Graph

A GraphViz graph that describes what panels are cut from what other panels.
"""

# ╔═╡ bd178f5d-7701-4a09-ba6d-0b80712bc3e2
begin
	# This graph just shows panels by their types and uids and
	# the relationships between them,
	function PanelCutting.dotgraph(io::IO, state::SearchState)::Nothing
		rpg = makePanelGraph(state)
		dotgraph(io, rpg)
		return
	end

end

# ╔═╡ 6bafdc76-dd65-47a6-9c34-90353408c488
md"""
# Panel Cut Graph

The Panel Cut Graph is limited to describing starting and ending panels and the cuts that are made.  Irrelevant panels are elided.
"""

# ╔═╡ b879cd1d-938a-4839-9c00-20d989ff5d45
begin

  struct NonlocalTransfer <: Exception
    uid

    function NonlocalTransfer()
      new(UUIDs.uuid1())
    end
  end

  function Base.showerror(io::IO, e::NonlocalTransfer)
    print(io, "NonlocalTransfer not caught!")
  end

  function transformingGraph(f)
	addset = Set()
	removeset = Set()
	exittag = NonlocalTransfer()
	add(arc) = push!(addset, arc)
	remove(arc) = push!(removeset, arc)
	function check(condition)
	  if !condition
		throw(exittag)
	  end
	end
	try
	  f(check, add, remove)
	catch e
	  if e != exittag
		rethrow(e)
	  end
	end
	return addset, removeset
  end

end

# ╔═╡ 7408dbb2-f396-4e8f-9686-d7ac1a522647
begin
  struct PanelCutGraph
    state::SearchState
    rpg::PanelGraph

    function PanelCutGraph(state::SearchState)
      pcg = new(state, makePanelGraph(state))
	  applyRule!(pcg.rpg, addCutNodes)
	  applyRule!(pcg.rpg, elideBoughtPanels)
	  applyRule!(pcg.rpg, elideTerminalPanels)
      pcg
    end
  end

  PanelCutting.arcs(pcg::PanelCutGraph) = arcs(pcg.rpg)

  PanelCutting.nodes(pcg::PanelCutGraph) = PanelCutting.nodes(pcg.rpg)

  struct CutNode
    panel1::Panel
    panel2::Panel
  end

  function PanelCutting.dotID(n::CutNode)
    return "CutNode_$(n.panel1.cut_from.uid)"
  end

  function PanelCutting.dotnode(io::IO, pcg::PanelCutGraph, n::CutNode)
    write(io, """  "$(dotID(n))"[shape=pentagon; label="$(dotnodelabel(pcg, n))"]\n""")
    return n
  end

  function dotnodelabel(pcg::PanelCutGraph, n::CutNode)::String
    from = if n.panel1.cut_axis isa LengthAxis
      "from end"
    elseif n.panel1.cut_axis isa WidthAxis
      "from side"
    end
    return "cut $(n.panel1.cut_at) $(from)"
  end

  md"""
  Compute the arguments to transform! in order to insert a
  CutNode wherever a panel is cut.
  """
  function addCutNodes(rpg::PanelGraph, key)
	transformingGraph() do check, add, remove
	  check(key isa CuttablePanel)
	  arcs = query(rpg, key, Panel)
	  check(length(arcs) == 2)
	  arc1, arc2 = Tuple(arcs)
	  check(key == arc1.second.cut_from)
	  check(key == arc2.second.cut_from)
	  cutnode = CutNode(arc1.second, arc2.second)
	  add(key => cutnode)
	  remove(arc1)
	  remove(arc2)
	  add(cutnode => cutnode.panel1)
      add(cutnode => cutnode.panel2)
	end
  end

  md"""
  Compute the arguments to transform! in order to elide a Panel that is
  succeeded by a TerminalPanel.

  """
  function elideTerminalPanels(rpg::PanelGraph, terminal)
    transformingGraph() do check, add, remove
      check(terminal isa TerminalPanel)
      arcs2 = query(rpg, Panel, terminal)
      check(length(arcs2) == 1)
      arc2 = first(arcs2)
      panel = arc2.first
      arcs1 = query(rpg, CutNode, panel)
      check(length(arcs1) == 1)
      arc1 = first(arcs1)
      precursor = arc1.first
      add(precursor => terminal)
      remove(arc1)
      remove(arc2)
    end
  end

  md"""
  Compute the arguments to transform! to elide BoughtPanels.
	"""
  function elideBoughtPanels(rpg::PanelGraph, bought)
	transformingGraph() do check, add, remove
	  check(bought isa BoughtPanel)
	  arcs1 = query(rpg, AvailablePanel, bought)
	  check(length(arcs1) == 1)
	  arc1 = first(arcs1)
	  arcs2 = query(rpg, bought, Any)
	  check(length(arcs2) == 1)
	  arc2 = first(arcs2)
	  remove(arc1)
	  remove(arc2)
	  add(arc1.first => arc2.second)
	end
  end

  function dotnodelabel(graph::PanelCutGraph, panel::BoughtPanel)::String
    return *("{",
			join(["$(split(string(typeof(panel)), ".")[end])",
                    "l: $(panel.length)",
                    "w: $(panel.width)",
                    "cost: $(panel.cost)"],
                   "|"),
              "}")
  end

  function dotnodelabel(graph::PanelCutGraph, panel::AvailablePanel)::String
    return *("{",
			join(["$(split(string(typeof(panel)), ".")[end])",
                    "l: $(panel.length)",
                    "w: $(panel.width)",
                    "cost: $(panel.cost)"],
                   "|"),
              "}")
  end

  function dotnodelabel(graph::PanelCutGraph, panel::FinishedPanel)::String
    return *("{",
			join(["$(split(string(typeof(panel)), ".")[end])",
					"$(panel.label)",
                    "l: $(panel.length)",
                    "w: $(panel.width)",
                    "x: $(panel.x)",
                    "y: $(panel.y)",
                    "cost: $(panel.cost)"],
                   "|"),
              "}")
  end

  function dotnodelabel(graph::PanelCutGraph, panel::AbstractPanel)::String
    return *("{",
			join(["$(split(string(typeof(panel)), ".")[end])",
                    "l: $(panel.length)",
                    "w: $(panel.width)",
                    "x: $(panel.x)",
                    "y: $(panel.y)",
                    "cost: $(panel.cost)"],
                   "|"),
              "}")
  end

  function PanelCutting.dotnode(io::IO, graph::PanelCutGraph, panel::AbstractPanel)
    write(io, """  "$(dotID(panel))"[shape=record; label="$(dotnodelabel(graph, panel))"]\n""")
  end

end

# ╔═╡ 75012d46-535c-4d51-9948-f3c611c7a72c
md"""
# Plots
"""

# ╔═╡ 9b16e856-dd32-400c-833a-cc2a3db5bf92
function plot_doneness_to_cost(searcher::Searcher)
  as = allstates(searcher)
  costs = (s -> s.accumulated_cost).(as)
  costs = (c -> unmoney(c)).(costs)
  done = doneness.(as)
  scatter(costs, done)
end

# ╔═╡ 1ea2113a-27f1-427a-a78e-23ef4bf52b33
md"""
# Report

Generate an HTML fragment that provides a detailed report of our cut search and results.
"""

# ╔═╡ f8b1780e-9614-4414-93e1-205233d3fb16

# ╔═╡ 0d804f8e-838a-49a0-983e-d517d7588f56
cat = `"c:/Program Files/Git/usr/bin/cat.exe"`

# ╔═╡ 58cd80ab-5a98-4b34-9bc2-a414d766a486
md"""
# Examples / Testing
"""

# ╔═╡ e3f1b65c-1bb2-44ee-bbec-8bda4e1ae6c3
let
	p1, p2 = cut(BoughtPanel(BOULTER_PLYWOOD.available_stock[1]),
		LengthAxis(), 10u"inch";
		kerf=BOULTER_PLYWOOD.kerf,
		cost=BOULTER_PLYWOOD.cost_per_cut)
	fp = FinishedPanel(p1, WantedPanel(length=10u"inch", width=p1.width, label="foo"))
	sp = ScrappedPanel(was=p2)
	rpg = PanelGraph()
	injest(rpg, fp)
	injest(rpg, sp)
	PanelCutting.nodes(rpg) .|> (key -> (elideTerminalPanels(rpg, key)))
end

# ╔═╡ c5f24393-4c92-4dcf-8a14-8f81c03cc2f0
md"""
## Two Panels From One Sheet of Stock
"""

# ╔═╡ 4a9ebc9b-b91c-4ff6-ba55-2c32093044be
let
  searcher = Searcher(BOULTER_PLYWOOD, wanda_box_panels[1:2])
  search(searcher)
  # ***** debug graph transformations:
  g = makePanelGraph(searcher.cheapest)
  base_path = "c:/Users/Mark Nahabedian/.julia/dev/PanelCutting/src/"
  message = "Wrote graph file"
  @info message, path=dotgraph(base_path*"two-panels-0.svg", g)
  applyRule!(g, addCutNodes)
  @info message, path=dotgraph(base_path*"two-panels-1.svg", g)
  applyRule!(g, elideBoughtPanels)
  @info message, path=dotgraph(base_path*"two-panels-2.svg", g)
  applyRule!(g, elideTerminalPanels)
  @info message, path=dotgraph(base_path*"two-panels-3.svg", g)
  # Back to our regularly scheduloed report
  report(searcher)
end

# ╔═╡ 40eda0d7-3871-48d6-9976-e9dd7829265d
md"""
## Panels for a Complete Five Sided Box
"""

# ╔═╡ aeaa6940-4f97-4286-97d4-7ad6dc6013b1
let
	searcher = Searcher(BOULTER_PLYWOOD, wanda_box_panels)
	search(searcher)
	@assert length(searcher.cheapest.finished) == length(wanda_box_panels)
	report(searcher)
end

# ╔═╡ a968cf5a-bed4-4939-980f-86e90903b756
md"""
## A Complete Box Allowing Flipping
"""

# ╔═╡ 81b8240b-e3c0-427d-b57a-b07e52963f15
let
	searcher = Searcher(BOULTER_PLYWOOD, flipped.(wanda_box_panels))
	search(searcher)
	report(searcher)
end

# ╔═╡ 1d99d3f7-f1a7-46f4-92d5-10a5b2677276
md"""
## An Example that Requires Flipped and Unflipped Panels for Optimality
"""

# ╔═╡ f1cf4d1c-2844-4bb5-b230-2e948af91852
let
	biggest = sort(BOULTER_PLYWOOD.available_stock, by=area, rev=true)[1]
	supplier = Supplier(name = "test",
		cost_per_cut = BOULTER_PLYWOOD.cost_per_cut,
		kerf = BOULTER_PLYWOOD.kerf,
		available_stock = [biggest])
	wanted = [
		WantedPanel(
			length = 1.1 * biggest.width,
			width = (biggest.length - 15u"inch") / 2,
			label = "panel 1"),
		WantedPanel(
			length = 1.1 * biggest.width,
			width = (biggest.length - 15u"inch") / 2,
			label = "panel 2"),
		WantedPanel(
			length = 14u"inch",
			width = 20u"inch",
			label = "panel 3"),
		WantedPanel(
			length = 14u"inch",
			width = 20u"inch",
			label = "panel 4")
		]
	searcher = Searcher(BOULTER_PLYWOOD, flipped.(wanted))
	search(searcher)
	report(searcher)
end

# ╔═╡ 70685b9d-b660-4443-ae7f-a0659456dc4f
md"""
  # Experiments
  """

# ╔═╡ bb38f4c1-4443-4b33-a526-b5cc653f437b
+(area.(Set(wanda_box_panels))...)

# ╔═╡ 2b814578-5137-4805-bedf-2c7759d87048
# typeof(20u"USD")

# ╔═╡ 7e368048-6a64-4439-8114-493f7f45ddfd
# 20u"USD" isa Quantity{N, CURRENCY} where N

# ╔═╡ 4049d967-f932-4eec-b6fc-711a5df79531
# zero(Quantity{Real, CURRENCY})

# ╔═╡ 758a62c8-512c-45a0-be1c-a3ec903e57b4
Logging.global_logger()

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
DisplayAs = "0b91fe84-8a4c-11e9-3e1d-67c38462b6d6"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
Match = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf"
NativeSVG = "5f95e7b2-fe07-4078-b4a7-f744f426795c"
PanelCutting = "c1372bff-64f3-4c29-a5fb-167619e966f3"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
UnitfulUS = "7dc9378f-8956-57ef-a780-aa31cc70ff3d"
VectorLogging = "ec499083-3b8a-4310-a81e-8622934b14d2"

[compat]
DataStructures = "~0.18.11"
DisplayAs = "~0.1.2"
Match = "~1.2.0"
NativeSVG = "~0.1.0"
PanelCutting = "~0.1.0"
Plots = "~1.25.4"
Revise = "~3.3.1"
Unitful = "~1.10.1"
UnitfulUS = "~0.2.0"
VectorLogging = "~0.1.0"
"""

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

[[Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "9faf218ea18c51fcccaf956c8d39614c9d30fe8b"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.2"

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

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

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

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

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

[[ChainRulesCore]]
deps = ["Compat", "LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "d711603452231bad418bd5e0c91f1abd650cba71"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.11.3"

[[ChangesOfVariables]]
deps = ["ChainRulesCore", "LinearAlgebra", "Test"]
git-tree-sha1 = "bf98fa45a0a4cee295de98d4c1462be26345b9a1"
uuid = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0"
version = "0.1.2"

[[CodeTracking]]
deps = ["InteractiveUtils", "UUIDs"]
git-tree-sha1 = "9aa8a5ebb6b5bf469a7e0e2b5202cf6f8c291104"
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
version = "1.0.6"

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

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

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

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

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

[[ConstructionBase]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "f74e9d5388b8620b4cee35d4c5a618dd4dc547f4"
uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
version = "1.3.0"

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

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

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

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

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

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

[[DisplayAs]]
git-tree-sha1 = "44e8d47bc0b56ec09115056a692e5fa0976bfbff"
uuid = "0b91fe84-8a4c-11e9-3e1d-67c38462b6d6"
version = "0.1.2"

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

[[DocStringExtensions]]
deps = ["LibGit2"]
git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b"
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
version = "0.8.6"

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

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

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

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

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

[[FileWatching]]
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[InverseFunctions]]
deps = ["Test"]
git-tree-sha1 = "a7254c0acd8e62f1ac75ad24d5db43f5f19f3c65"
uuid = "3587e190-3f89-42d0-90ee-14403ec27112"
version = "0.1.2"

[[IrrationalConstants]]
git-tree-sha1 = "7fd44fd4ff43fc60815f8e764c0f352b83c49151"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.1.1"

[[IterTools]]
git-tree-sha1 = "fa6287a4469f5e048d763df38279ee729fbd44e5"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.4.0"

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

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

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

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

[[JuliaInterpreter]]
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
git-tree-sha1 = "a2366b16704ffe78be1831341e6799ab2f4f07d2"
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
version = "0.9.0"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[LogExpFunctions]]
deps = ["ChainRulesCore", "ChangesOfVariables", "DocStringExtensions", "InverseFunctions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "e5718a00af0ab9756305a0392832c8952c7426c1"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.6"

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

[[LoweredCodeUtils]]
deps = ["JuliaInterpreter"]
git-tree-sha1 = "f46e8f4e38882b32dcc11c8d31c131d556063f39"
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
version = "2.2.0"

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

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

[[Match]]
git-tree-sha1 = "1d9bc5c1a6e7ee24effb93f175c9342f9154d97f"
uuid = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf"
version = "1.2.0"

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

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

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

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

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

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

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

[[NativeSVG]]
deps = ["NodeJS"]
git-tree-sha1 = "25cfd8cdd020ea0f609d6016df9c479541f78f7e"
repo-rev = "master"
repo-url = "https://github.com/MarkNahabedian/NativeSVG.jl.git"
uuid = "5f95e7b2-fe07-4078-b4a7-f744f426795c"
version = "0.1.0-naha"

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

[[NodeJS]]
deps = ["Pkg"]
git-tree-sha1 = "905224bbdd4b555c69bb964514cfa387616f0d3a"
uuid = "2bd173c7-0d6d-553b-b6af-13a54713934c"
version = "1.3.0"

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

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

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

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

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

[[PanelCutting]]
deps = ["DataStructures", "DisplayAs", "HTTP", "InteractiveUtils", "Logging", "Markdown", "Match", "NativeSVG", "Plots", "Printf", "Revise", "UUIDs", "Unitful", "UnitfulUS", "VectorLogging"]
git-tree-sha1 = "682f0079a9b4732294e6cfb6b1d57ed9b967615d"
repo-rev = "master"
repo-url = "https://github.com/MarkNahabedian/PanelCutting.jl"
uuid = "c1372bff-64f3-4c29-a5fb-167619e966f3"
version = "0.1.0"

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

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

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

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

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

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

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

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

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

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

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

[[RecipesBase]]
git-tree-sha1 = "6bf3f380ff52ce0832ddd3a2a7b9538ed1bcca7d"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.2.1"

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

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

[[Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "8f82019e525f4d5c669692772a6f4b0a58b06a6a"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.2.0"

[[Revise]]
deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"]
git-tree-sha1 = "2f9d4d6679b5f0394c52731db3794166f49d5131"
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
version = "3.3.1"

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

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

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

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

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

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

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

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

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

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

[[StatsAPI]]
git-tree-sha1 = "d88665adc9bcf45903013af0982e2fd05ae3d0a6"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.2.0"

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

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

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

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

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

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

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

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

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

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

[[UnicodeFun]]
deps = ["REPL"]
git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf"
uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1"
version = "0.4.1"

[[Unitful]]
deps = ["ConstructionBase", "Dates", "LinearAlgebra", "Random"]
git-tree-sha1 = "b95e0b8a8d1b6a6c3e0b3ca393a7a285af47c264"
uuid = "1986cc42-f94f-5a68-af5c-568840ba703d"
version = "1.10.1"

[[UnitfulUS]]
deps = ["Unitful"]
git-tree-sha1 = "aa8a8a140729fbca8c8d960ab488e0bf6b87feed"
uuid = "7dc9378f-8956-57ef-a780-aa31cc70ff3d"
version = "0.2.0"

[[Unzip]]
git-tree-sha1 = "34db80951901073501137bdbc3d5a8e7bbd06670"
uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d"
version = "0.1.2"

[[VectorLogging]]
deps = ["Logging", "Test"]
git-tree-sha1 = "f4320fd358e078850d2ec23c799c61e32dc3d247"
uuid = "ec499083-3b8a-4310-a81e-8622934b14d2"
version = "0.1.0"

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

[[Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "66d72dc6fcc86352f01676e8f0f698562e60510f"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.23.0+0"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

# ╔═╡ Cell order:
# ╠═ab2e6b79-24f3-4736-8e9e-8362a7efd718
# ╠═202a21c7-e92a-4636-9859-c27626a96edc
# ╟─60eb1ca9-cf1f-46d6-b9b9-ee9fb41723d1
# ╠═e25b3bb7-93b3-4859-be30-ef912041479f
# ╠═60fdb133-5d21-4445-90f9-3bbe49fb743b
# ╠═0f1516c2-e12d-439c-b57d-3af903cbf3f6
# ╠═ecacafd3-5f70-41d9-b6cd-6b4893186b2a
# ╟─f6a43438-d7b0-442d-bb05-9e4488855665
# ╠═65adef2d-9a53-4310-81a0-5dbb6d0918ca
# ╟─85f95152-93a2-42cd-80f3-c3d7d931dbfe
# ╟─134ac318-adb5-4939-96f7-3b70b12ffe43
# ╟─4cd74059-f59b-46e4-be23-bfbd95e4d96d
# ╠═f89c8f2e-8bdf-4d4e-8090-3f6a56e0ce85
# ╟─dcbc9193-fa7a-435b-8f68-05b77e1d9b36
# ╠═bd178f5d-7701-4a09-ba6d-0b80712bc3e2
# ╟─6bafdc76-dd65-47a6-9c34-90353408c488
# ╠═b879cd1d-938a-4839-9c00-20d989ff5d45
# ╠═7408dbb2-f396-4e8f-9686-d7ac1a522647
# ╟─75012d46-535c-4d51-9948-f3c611c7a72c
# ╠═9b16e856-dd32-400c-833a-cc2a3db5bf92
# ╟─1ea2113a-27f1-427a-a78e-23ef4bf52b33
# ╠═f8b1780e-9614-4414-93e1-205233d3fb16
# ╠═0d804f8e-838a-49a0-983e-d517d7588f56
# ╟─58cd80ab-5a98-4b34-9bc2-a414d766a486
# ╠═e3f1b65c-1bb2-44ee-bbec-8bda4e1ae6c3
# ╟─c5f24393-4c92-4dcf-8a14-8f81c03cc2f0
# ╠═4a9ebc9b-b91c-4ff6-ba55-2c32093044be
# ╟─40eda0d7-3871-48d6-9976-e9dd7829265d
# ╠═aeaa6940-4f97-4286-97d4-7ad6dc6013b1
# ╟─a968cf5a-bed4-4939-980f-86e90903b756
# ╠═81b8240b-e3c0-427d-b57a-b07e52963f15
# ╟─1d99d3f7-f1a7-46f4-92d5-10a5b2677276
# ╠═f1cf4d1c-2844-4bb5-b230-2e948af91852
# ╟─70685b9d-b660-4443-ae7f-a0659456dc4f
# ╠═bb38f4c1-4443-4b33-a526-b5cc653f437b
# ╠═2b814578-5137-4805-bedf-2c7759d87048
# ╠═7e368048-6a64-4439-8114-493f7f45ddfd
# ╠═4049d967-f932-4eec-b6fc-711a5df79531
# ╠═758a62c8-512c-45a0-be1c-a3ec903e57b4
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

ext: jl


text:
using JuMP

pi = 30.*rand(24,6)

ssl = 13;
hh = 24;
num_types = 15;

const pick_o = vec(ones(24));
pick_o[13:17] = 2;
pick_o[18:24] = 3;
pick_o[1:5] = 4;
const pick_fine = vec(ones(24));
pick_fine[14:18]=2;
const lease=vec(ones(24).*105);
lease[5:16]=116;
const work_time = vec(ones(24));
work_time[5:17] = 2;

breakm = rand((24,12,15,6));
active_stop = round(rand((24,12,15,6)));
active_nonstop = round(3.*rand((24,12,15,6)));
inactive_start = round(10.*rand((24,15)));
inactive_nonstart = round(10.*rand((24,15)));
pw = [0.00255578, 0.0886157, 0.408828, 0.408828, 0.0886157, 0.00255578];
nwage = length(pw);
constr_mat = round(rand((num_types,24)))

m = Model()

@defVar(m,  0.0001 <= p_est[1:hh,1:ssl-1,1:num_types,1:nwage] <= 0.9999);
@defVar(m,  0.0001 <= q_est[1:hh,1:num_types] <= 0.9999);
@defVar(m, -1000 <= EV[1:hh,1:ssl-1,1:num_types,1:nwage] <= 1700);
@defVar(m, -1000 <= EVA[1:hh,1:ssl-1,1:num_types] <= 1700);
@defVar(m,0 <= λ_1 <= 20);
@defVar(m,0 <= λ_2 <= 20);
@defVar(m,0 <= λ_0[1:length(unique(pick_o))] <= 250);
@defVar(m,-100 <= f[1:2] <= 400);
@defVar(m, 0.1 <= σ <= 80);
@defVar(m, 0.1 <= σ_s <= 80);
@defVar(m,-500 <= μ[1:2] <= 600);

setValue(λ_1, -8.0);
setValue(λ_2, .8);
setValue(μ[1], 90.0);
setValue(μ[2], 90.0);

setValue(σ_s, 20.4);
setValue(σ, 20.0);

for h in [unique(pick_o)]
setValue(λ_0[h], 20.0)
end;

for h in [unique(pick_fine)]
    setValue(f[h], 30.0)
end;

for h=1:hh,sl=1:ssl-1, c=1:num_types, a=1:nwage
    setValue(p_est[h,sl,c,a], 0.06*sl)
end;

for h=1:hh,sl=1:ssl-1, c=1:num_types, a=1:nwage
setValue(EV[h,sl,c,a], 15)
end;

for h=1:hh,sl=1:ssl-1, c=1:num_types
setValue(EVA[h,sl,c], 15)
end;

for h=1:hh, c=1:num_types
    setValue(q_est[h,c], 0.5)hhend;

@setNLObjective(m, Max, sum{(1/10000)*(active_stop[h,sl,c,a]*log(p_est[h,sl,c,a])+active_nonstop[h,sl,c,a]*log(1-p_est[h,sl,c,a])),h=1:hh,sl=1:ssl-1,c=1:num_types, a=1:nwage}+sum{(1/10000)*(inactive_start[h,c]*log(q_est[h,c])+inactive_nonstart[h,c]*log(1-q_est[h,c])),h=1:hh,c=1:num_types})

for h=1:hh-1,sl=1:ssl-2, c=1:num_types, a=1:nwage
    @addNLConstraint(m, EV[h,sl,c,a]==σ*log(exp(1/σ)+exp((pi[h,a]*(1-breakm[h,sl,c,a])-λ_0[pick_o[h]]-λ_1*sl-λ_2*sl^2-constr_mat[c,h]*f[pick_fine[h]]+EVA[h+1,sl+1,c])/σ)))
end

for h=1:hh-1,sl=ssl-1, c=1:num_types, a=1:nwage
    @addNLConstraint(m, EV[h,sl,c,a]==σ*log(exp(1/σ)+exp((pi[h,a]*(1-breakm[h,sl,c,a])-λ_0[pick_o[h]]-λ_1*sl-λ_2*sl^2-constr_mat[c,h]*f[pick_fine[h]])/σ)))
end

for h=hh,sl=1:ssl-2, c=1:num_types, a=1:nwage
    @addNLConstraint(m, EV[h,sl,c,a]==σ*log(exp(1/σ)+exp((pi[h,a]*(1-breakm[h,sl,c,a])-λ_0[pick_o[h]]-λ_1*sl-λ_2*sl^2-constr_mat[c,h]*f[pick_fine[h]]+EVA[1,sl+1,c])/σ)))
end

for h=hh,sl=ssl-1, c=1:num_types, a=1:nwage
    @addNLConstraint(m, EV[h,sl,c,a]==σ*log(exp(1/σ)+exp((pi[h,a]*(1-breakm[h,sl,c,a])-λ_0[pick_o[h]]-λ_1*sl-λ_2*sl^2-constr_mat[c,h]*f[pick_fine[h]])/σ)))
end

for h=1:hh-1,sl=1:ssl-2, c=1:num_types, a=1:nwage
    @addNLConstraint(m, p_est[h,sl,c,a]==exp(1/σ)/(exp(1/σ)+exp((pi[h,a]*(1-breakm[h,sl,c,a])-λ_0[pick_o[h]]-λ_1*sl-λ_2*sl^2-constr_mat[c,h]*f[pick_fine[h]]+EVA[h+1,sl+1,c])/σ)))
end

for h=1:hh-1,sl=ssl-1, c=1:num_types, a=1:nwage
    @addNLConstraint(m, p_est[h,sl,c,a]==exp(1/σ)/(exp(1/σ)+exp((pi[h,a]*(1-breakm[h,sl,c,a])-λ_0[pick_o[h]]-λ_1*sl-λ_2*sl^2-constr_mat[c,h]*f[pick_fine[h]])/σ)))
end

for h=hh,sl=1:ssl-2, c=1:num_types, a=1:nwage
    @addNLConstraint(m, p_est[h,sl,c,a]==exp(1/σ)/(exp(1/σ)+exp((pi[h,a]*(1-breakm[h,sl,c,a])-λ_0[pick_o[h]]-λ_1*sl-λ_2*sl^2-constr_mat[c,h]*f[pick_fine[h]]+EVA[1,sl+1,c])/σ)))
end

for h=hh,sl=ssl-1, c=1:num_types, a=1:nwage
    @addNLConstraint(m, p_est[h,sl,c,a]==exp(1/σ)/(exp(1/σ)+exp((pi[h,a]*(1-breakm[h,sl,c,a])-λ_0[pick_o[h]]-λ_1*sl-λ_2*sl^2-constr_mat[c,h]*f[pick_fine[h]])/σ)))
end

for h=1:hh, c=1:num_types
    @addNLConstraint(m, q_est[h,c]==exp((EVA[h,1,c]-lease[h])/σ_s)/(exp((μ[work_time[h]])/σ_s)+exp((EVA[h,1,c]-lease[h])/σ_s)))
end;

for h=1:hh,sl=1:ssl-1, c=1:num_types
    @addNLConstraint(m, EVA[h,sl,c] == sum{pw[a]*EV[h,sl,c,a],a=1:nwage})
end

solve(m)

max_stars_repo_name: floswald/ucl-econ-julia

max_issues_repo_name: floswald/ucl-econ-julia

max_forks_repo_name: floswald/ucl-econ-julia


text:
"""
# module Thermostats

# Examples

```jldoctest
julia>
```
"""
module Thermostats

using Distributions: Normal
using StaticArrays: SVector, SMatrix, MVector, MMatrix

export homogeneous_atomic_gas_energy,
    andersen_heat_bath,
    perform_stochastic_collision,
    velocities_after_collision

const Boltzmann = 1

"""
    homogeneous_atomic_gas_energy(atomic_mass, velocities)

# e.g., v_i = v_{ix}^2 + v_{iy}^2 + v_{iz}^2 if `D` is `3`
# m_i v_i^2 for the atoms of an element

# Arguments
- `atomic_mass::Float64`:
- `velocities::SMatrix{N, D, Float64}`: `N` is the number of atoms of an element, `D` is the the
  dimensionality of the problem.
"""
function homogeneous_atomic_gas_energy(atomic_mass::Float64, v::SMatrix{N, D, Float64})::Float64 where {N, D}
    atomic_mass * sum(v .^ 2)
end

"""
    andersen_heat_bath(energy, atoms_amount[, dimension])

# Arguments
- `energy::Float64`: the total energy of atoms of an element.
- `atoms_amount::Int`: the number of atoms of an element.
- `dimension::Int=3`: the dimensionality of the problem.
"""
function andersen_heat_bath(energy::Float64, atoms_amount::Int, dimension::Int = 3)::Normal{Float64}
    instantaneous_temperature = energy / (Boltzmann * dimension * atoms_amount)
    σ = sqrt(instantaneous_temperature)  # Standard deviation of temperature
    Normal(0, σ)
end

"""
    perform_stochastic_collision(energy, ν, dt[, dimension])

Perform one stochastic collision with the heat bath.

# Arguments
- `rng`: a random number generator with normal distribution.
- `ν::Float64`: the collision frequency.
- `dt::Float64`: the time between two consecutive collisions.
- `atoms_amount::Int`: the number of atoms of an element.
- `dimension::Int=3`: the dimensionality of the problem.
"""
function perform_stochastic_collision(rng, ν::Float64, dt::Float64, atoms_amount::Int, dimension::Int = 3)::Vector{Tuple{Int, Float64}}
    probability = ν * dt  # The probability that a particle is selected in a time step of length Δt
    [rand() < probability && (i, rand(rng) / sqrt(dimension)) for i in 1:atoms_amount]
end

"""
    velocities_after_collision(atomic_mass, v, ν, dt)

"""
function velocities_after_collision(atomic_mass::Float64, v::SMatrix{N, D, Float64}, ν::Float64, dt::Float64)::SMatrix{N, D, Float64} where {N, D}
    energy = homogeneous_atomic_gas_energy(atomic_mass, v)
    rng = andersen_heat_bath(energy, N, D)
    result = MMatrix(v)
    for (i, velocity) in perform_stochastic_collision(rng, ν, dt, N, D)
        result[i, :] .= velocity
    end
    result
end

end


text:
using Diagonalizations, LinearAlgebra, PosDefManifold, Test

# Method (1) real
n, t=10, 100
X=genDataMatrix(n, t)
C=(X*X')/t
pC=pca(Hermitian(C); simple=true)
# or, shortly
pC=pca(ℍ(C); simple=true)

# Method (1) complex
Xc=genDataMatrix(ComplexF64, n, t)
Cc=(Xc*Xc')/t
pCc=pca(Hermitian(Cc); simple=true)

# Method (2) real
pX=pca(X; simple=true)
@test C≈pC.F*pC.D*pC.iF
@test C≈pC.F*pC.D*pC.F'
@test pX≈pC

# Method (2) complex
pXc=pca(Xc; simple=true)
@test Cc≈pCc.F*pCc.D*pCc.iF
@test Cc≈pCc.F*pCc.D*pCc.F'
@test pXc≈pCc

# Method (3) real
k=10
Xset=[genDataMatrix(n, t) for i=1:k]

# pca on the average covariance matrix
p=pca(Xset)

# ... selecting subspace dimension allowing an explained variance = 0.5
p=pca(Xset; eVar=0.5)

# ... averaging the covariance matrices using the logEuclidean metric
p=pca(Xset; metric=logEuclidean, eVar=0.5)

# ... giving weights `w` to the covariance matrices
p=pca(Xset; metric=logEuclidean, w=abs2.(randn(k)), eVar=0.5)

# ... subtracting the mean
p=pca(Xset; meanX=nothing, metric=logEuclidean, w=abs2.(randn(k)), eVar=0.5)

# pca on the average of the covariance matrices computed along dims 1
p=pca(Xset; dims=1)

# explained variance
p.eVar

# name of the filter
p.name

using Plots
# plot regularized accumulated eigenvalues
plot(p.arev)

# plot the original covariance matrix and the rotated covariance matrix
 Cmax=maximum(abs.(C));
 h1 = heatmap(C, clim=(-Cmax, Cmax), yflip=true, c=:bluesreds, title="C");
 D=pC.F'*C*pC.F;
 Dmax=maximum(abs.(D));
 h2 = heatmap(D, clim=(0, Dmax), yflip=true, c=:amp, title="F'*C*F");
 📈=plot(h1, h2, size=(700, 300))
# savefig(📈, homedir()*"\\Documents\\Code\\julia\\Diagonalizations\\docs\\src\\assets\\FigPCA.png")

# Method (3) complex
k=10
Xcset=[genDataMatrix(ComplexF64, n, t) for i=1:k]

# pca on the average covariance matrix
pc=pca(Xcset)

# ... selecting subspace dimension allowing an explained variance = 0.5
pc=pca(Xcset; eVar=0.5)

# ... averaging the covariance matrices using the logEuclidean metric
pc=pca(Xcset; metric=logEuclidean, eVar=0.5)

# ... giving weights `w` to the covariance matrices
pc=pca(Xcset; metric=logEuclidean, w=abs2.(randn(k)), eVar=0.5)

# ... subtracting the mean
pc=pca(Xcset; meanX=nothing, metric=logEuclidean, w=abs2.(randn(k)), eVar=0.5)

# pca on the average of the covariance matrices computed along dims 1
pc=pca(Xcset; dims=1)

# explained variance
pc.eVar

# name of the filter
pc.name


text:
# This file contains utility functions necessary for:
# 1. handling input arguments to a script call
# 2. read large files in a given format with possible omission of commented and unnnecessary initial lines
# 3. output a number of type Int with the addition of the required number of zeros at the beginning
# 4. event logging function

# Functions for processing an incoming script argument specifying the degrees of approximation for output
# This function processes the parameter enclosed in square brackets
# and based on the specified data forms an array of elements
# Example:
# if the string "[1,2,3,4,5: 5: 20,30,40]" is input,
# Array{Int}[1,2,3,4,5,10,15,20,30,40] is formed as the output
function make_numberlist(arg_string)

    arg_split = split(strip(arg_string, ['[',']']), ",")

    arg_deg = Any[]
    for arg in arg_split
        s_arg = split(arg, ":")
        if length(s_arg) >1
            if length(s_arg) == 2
                st = parse(Int, s_arg[1])
                en = parse(Int, s_arg[2])
                push!(arg_deg, st:en)
            end
            if length(s_arg) == 3
                st = parse(Int, s_arg[1])
                sp = parse(Int, s_arg[2])
                en = parse(Int, s_arg[3])
                push!(arg_deg, st:sp:en)
            end
        else
            push!(arg_deg, parse(Int, arg))
        end
    end
    degs = Int[]
    for els in arg_deg
        if typeof(els) <: Integer
            push!(degs, els)
        else
            for el_in_collect in els
                push!(degs, el_in_collect)
            end
        end
    end
    return degs
end

# This function is designed to form sliding windows
# The input of the function is a string of arguments with windows parameters and the maximum size of the data onto which the windows are formed
# The argument string can be specified in three ways:
# M:N - in one window;
# M:W:N - windows overlapping in one point;
# M:W:S:N - with windows with a given overlap.
# Here:
# M - starting point of the first window
# N - last point of the last window (as the last point
# you can specify the end of the file, the "end" keyword is used for this)
# W - window size
# S - windows overlap
# !!! IMPORTANT NOTE - 1 !!!
# When forming windows, the last window is formed so that
# the last point of the window coincided with the last given point N,
# at the same time, the overlap with the penultimate window may be greater than specified S
# !!! IMPORTANT NOTE - 2 !!!
# If the specified window size is larger than the amount of data available, then the script exits logging the error in the log file.
# ***************************************************
# Examples
# "1:10", 20 => [(1,10)]
# "1:10:19", 18 => [(1, 10), (9, 18)]
# "1:10:19", 20 => [(1, 10), (10, 19)]
# "1:10:20", 20 => [(1, 10), (10, 19), (11, 20)]
# "1: 10: 3: 20", 20 => [(1, 10), (8, 17), (11, 20)]

function make_windows(arg_string, data_length)
    windows_array = Any[]
    arg = split(arg_string, ':')
    if length(arg) == 2 # Option when 1 window is used
        start_index = parse(Int, arg[1])
        if arg[2] == "end"
            end_index = data_length
        else
            end_index =  parse(Int, arg[2])
            if end_index>data_length
                return windows_array
            end
        end
        windows_array = [(start_index, end_index)]
    elseif length(arg) == 3 # windows with 1 point overlap
        start_index = parse(Int, arg[1])
        step_size = parse(Int, arg[2])
        if arg[3] == "end"
            end_index = data_length
        else
            end_index =  parse(Int, arg[3])
            if end_index>data_length
                return windows_array
            end
        end
        for start_window = start_index:step_size-1:end_index - step_size
            push!(windows_array, (start_window, start_window + step_size-1))
        end
        if length(windows_array) ==0
            return windows_array
        end
        if windows_array[end][2] < end_index
            push!(windows_array, (end_index - step_size+1, end_index))
        end
    elseif length(arg) == 4 # windows with overlapping
        start_index = parse(Int, arg[1])
        step_size = parse(Int, arg[2])
        overlap = parse(Int, arg[3])
        if arg[4] == "end"
            end_index = data_length
        else
            end_index =  parse(Int, arg[4])
            if end_index>data_length
                println("return")
                return windows_array
            end
        end
        println("read param: start$start_index - step$step_size - overlap$overlap - end$end_index")
        for start_window = start_index:(step_size - overlap):(end_index - step_size)
            push!(windows_array, (start_window, start_window + step_size-1))
        end
        if length(windows_array) ==0
            return windows_array
        end
        if windows_array[end][2] < end_index
            push!(windows_array, (end_index - step_size + 1, end_index))
        end
    else
        windows_array = [(1, data_length)]
    end
    return windows_array
end

# function for data reading
function readbigfile(filename::AbstractString, # input file name
    Columns::Array{Int, 1}, # numbers of columns to be read. If you specify 0 as one of the numbers to be read, then a column with line numbers will be generated (lines omitted during reading are not considered)
    T::Type # data type into which columns will be converted
    ;
    skip_first_row = 0 # the number of lines at the beginning of the file to skip
    )::Array{T, 2} # function returns a two-dimensional array

    # Open the file for reading
    in_file = readlines(filename)
    skip_row = 0
    for line in in_file
        if skip_first_row > skip_row
            skip_row=skip_row+1
            continue
        end
        # skip lines starting with '#' (IN THE FIRST POSITION!)
        if line[1] == '#'
            skip_row = skip_row+1
            continue
        end
        # if length(split(line)) < length(Columns)
        #     skip_row = skip_row+1
        #     continue
        # end
    end
    println("skipped rows: $skip_row")
    # Create a zero two-dimensional array of type T
    out_array = zeros(T, (length(in_file) - skip_row, length(Columns)))
    # We process the file line by line
    num_out_array_row = 1
    for num_str = 1+skip_first_row:length(in_file)
        if in_file[num_str][1] == '#'
            continue
        end
# skip rows with insufficient number of columns
        # if length(split(in_file[num_str])) < length(Columns)
        #     continue
        # end
        value_str = split(in_file[num_str])
        for num_col = 1:length(Columns)
            if Columns[num_col] == 0
                out_array[num_out_array_row,num_col] = num_out_array_row
            else
                out_array[num_out_array_row,num_col] = parse(T, value_str[Columns[num_col]])
            end
        end
        num_out_array_row = num_out_array_row + 1
    end
    # Return the array of data
    return out_array
end

# This function takes two numbers as input:
# 1. number to be printed
# 2. minimum number of characters in the number to be displayed (as a string). If the printed form of the number (first argument) is
# shorter than specified, zeros are padded before the number so that the length of the printed number with zeros is equal to the specified minimum length
# If the number is longer, just the number itself is output as a string
function print_with_zero(num::Integer, min_length_num::Integer)
    str_num = "$num"
    zero_in_begin = "0"^maximum([0,(min_length_num-length(str_num))])
    return "$(zero_in_begin)$(str_num)"
end

# The function appends the message indicated as the second argument to a file with the name specified as the first argument of the function,
# the current time stamp is indicated as well
function add_log_messange(log_file, message)
    out_file = open(log_file, "a")
    println(out_file, "[$(now())] $(message)")
    flush(out_file)
    close(out_file)
end

# Function outputs (by default to stdout) two-dimensional and one-dimensional arrays with the given separator between elements
# The input array is input and separators between the elements of the string can be specified (col_delims)
# as well as separators between the lines (row_delims)
function println_array(InputArray::Array;col_delims = "\t", row_delims="\n", out_stream = stdout)
    dims = ndims(InputArray)
    if dims == 1
        println(out_stream,join(map(x->"$(x)",InputArray),col_delims))
    elseif dims == 2
        num_rows = size(InputArray)[1]
        for ind_row = 1:num_rows
            print(out_stream,join(map(x->"$(x)",InputArray[ind_row, :]),col_delims))
            print(out_stream,row_delims)
        end
        println(out_stream)
    else
        println("warning: Dims > 2")
    end
end

max_stars_repo_name: sptsarev/high-deg-polynomial-fitting

max_issues_repo_name: sptsarev/high-deg-polynomial-fitting

max_forks_repo_name: sptsarev/high-deg-polynomial-fitting