text:
get_test_curve1() = [CurvePt(VecSE2(0.0,0.0,0.0), 0.0),
                     CurvePt(VecSE2(1.0,0.0,0.0), 1.0),
                     CurvePt(VecSE2(3.0,0.0,0.0), 3.0)]

function get_test_roadway()
    roadway = Roadway()

    seg1 = RoadSegment(1,
        [Lane(LaneTag(1,1),
            [CurvePt(VecSE2(-2.0,0.0,0.0), 0.0),
             CurvePt(VecSE2(-1.0,0.0,0.0), 1.0)]),
         Lane(LaneTag(1,2),
            [CurvePt(VecSE2(-2.0,1.0,0.0), 0.0),
             CurvePt(VecSE2(-1.0,1.0,0.0), 1.0)]),
         Lane(LaneTag(1,3),
            [CurvePt(VecSE2(-2.0,2.0,0.0), 0.0),
             CurvePt(VecSE2(-1.0,2.0,0.0), 1.0)])
        ])

    seg2 = RoadSegment(2,
        [Lane(LaneTag(2,1),
            [CurvePt(VecSE2(0.0,0.0,0.0), 0.0),
             CurvePt(VecSE2(1.0,0.0,0.0), 1.0),
             CurvePt(VecSE2(2.0,0.0,0.0), 2.0),
             CurvePt(VecSE2(3.0,0.0,0.0), 3.0)]),
         Lane(LaneTag(2,2),
            [CurvePt(VecSE2(0.0,1.0,0.0), 0.0),
             CurvePt(VecSE2(1.0,1.0,0.0), 1.0),
             CurvePt(VecSE2(2.0,1.0,0.0), 2.0),
             CurvePt(VecSE2(3.0,1.0,0.0), 3.0)]),
         Lane(LaneTag(2,3),
            [CurvePt(VecSE2(0.0,2.0,0.0), 0.0),
             CurvePt(VecSE2(1.0,2.0,0.0), 1.0),
             CurvePt(VecSE2(2.0,2.0,0.0), 2.0),
             CurvePt(VecSE2(3.0,2.0,0.0), 3.0)])
         ])

    seg3 = RoadSegment(3,
        [Lane(LaneTag(3,1),
            [CurvePt(VecSE2(4.0,0.0,0.0), 0.0),
             CurvePt(VecSE2(5.0,0.0,0.0), 1.0)]),
         Lane(LaneTag(3,2),
            [CurvePt(VecSE2(4.0,1.0,0.0), 0.0),
             CurvePt(VecSE2(5.0,1.0,0.0), 1.0)]),
         Lane(LaneTag(3,3),
            [CurvePt(VecSE2(4.0,2.0,0.0), 0.0),
             CurvePt(VecSE2(5.0,2.0,0.0), 1.0)])
        ])

    for i in 1:3
        connect!(seg1.lanes[i], seg2.lanes[i])
        connect!(seg2.lanes[i], seg3.lanes[i])
    end

    push!(roadway.segments, seg1)
    push!(roadway.segments, seg2)
    push!(roadway.segments, seg3)

    roadway
end

@testset "1d roadway" begin
    roadway = StraightRoadway(20.0)
    s = 10.0
    @test mod_position_to_roadway(s, roadway) == s
    s = 25.0
    @test mod_position_to_roadway(s, roadway) == 5.0
    s = 45.0
    @test mod_position_to_roadway(s, roadway) == 5.0
    s = -5.0
    @test mod_position_to_roadway(s, roadway) == 15.0
    s_rear = 10.0
    s_fore = 15.0
    @test get_headway(s_rear, s_fore, roadway) == 5.0
    s_fore = 25.0
    @test get_headway(s_rear, s_fore, roadway) == 15.0
    s_fore = 5.0
    @test get_headway(s_rear, s_fore, roadway) == 15.0
end

@testset "Curves" begin
    p = lerp(CurvePt(VecSE2(0.0,0.0,0.0), 0.0), CurvePt(VecSE2(1.0,2.0,3.0), 4.0), 0.25)
    show(IOBuffer(), p)
    @test isapprox(convert(VecE2, p.pos), VecE2(0.25, 0.5))
    @test isapprox(p.pos.θ, 0.75)
    @test isapprox(p.s, 1.0)

    show(IOBuffer(), CurveIndex(1,0.0))

    @test isapprox(get_lerp_time(VecE2(0.0,0.0), VecE2(1.0,0.0), VecE2(1.0,0.0)), 1.0)
    @test isapprox(get_lerp_time(VecE2(0.0,0.0), VecE2(1.0,0.0), VecE2(0.5,0.0)), 0.5)
    @test isapprox(get_lerp_time(VecE2(0.0,0.0), VecE2(1.0,0.0), VecE2(0.5,0.5)), 0.5)
    @test isapprox(get_lerp_time(VecE2(0.0,0.0), VecE2(1.0,1.0), VecE2(0.5,0.5)), 0.5)
    @test isapprox(get_lerp_time(VecE2(1.0,0.0), VecE2(2.0,0.0), VecE2(1.5,0.5)), 0.5)
    @test isapprox(get_lerp_time(VecE2(0.0,0.0), VecE2(-1.0,0.0), VecE2(1.0,0.0)), 0.0)
    @test isapprox(get_lerp_time(VecE2(0.0,0.0), VecE2(-1.0,0.0), VecE2(-0.75,0.0)), 0.75)

    curve = get_test_curve1()
    @inferred index_closest_to_point(curve, VecE2(0.0,0.0))
    @test index_closest_to_point(curve, VecE2(0.0,0.0)) == 1
    @test index_closest_to_point(curve, VecE2(1.0,0.0)) == 2
    @test index_closest_to_point(curve, VecE2(2.1,0.0)) == 3
    @test index_closest_to_point(curve, VecE2(0.49,0.0)) == 1
    @test index_closest_to_point(curve, VecE2(1.9,-100.0)) == 2
    @test index_closest_to_point(curve, VecSE2(1.9,-100.0,0.0)) == 2
    @test index_closest_to_point(curve, VecSE2(-1.0,0.0,0.0)) == 1
    @test index_closest_to_point([CurvePt(VecSE2(0.0,0.0,0.0),0.0)], VecE2(0.0,0.0)) == 1
    @test get_curve_index(curve, 0.0) == CurveIndex(1, 0.0)
    @test get_curve_index(curve, 1.0) == CurveIndex(2, 0.0)
    @test get_curve_index(curve, 1.5) == CurveIndex(2, 0.25)
    @test get_curve_index(curve, 3.5) == CurveIndex(2, 1.0)
    @test get_curve_index(curve,-0.5) == CurveIndex(1, 0.0)

    p = curve[CurveIndex(1, 0.75)]
    @test isapprox(convert(VecE2, p.pos), VecE2(0.75, 0.0))
    @test isapprox(p.pos.θ, 0.0)
    @test isapprox(p.s, 0.75)

    @test get_curve_index(CurveIndex(1, 0.0), curve,  0.25) == CurveIndex(1,0.25)
    @test get_curve_index(CurveIndex(1, 0.0), curve,  1.25) == CurveIndex(2,0.125)
    @test get_curve_index(CurveIndex(1, 0.5), curve,  1.50) == CurveIndex(2,0.5)
    @test get_curve_index(CurveIndex(1, 0.5), curve, -0.25) == CurveIndex(1,0.25)
    @test get_curve_index(CurveIndex(2, 0.0), curve, -0.50) == CurveIndex(1,0.50)

    res = proj(VecSE2(0.0,0.0,0.0), curve)
    @inferred proj(VecSE2(0.0,0.0,0.0), curve)
    show(IOBuffer(), res)
    @test res.ind == CurveIndex(1, 0.0)
    @test isapprox(res.t, 0.0)
    @test isapprox(res.ϕ, 0.0)
    res = proj(VecSE2(0.25,0.5,0.1), curve)
    @inferred proj(VecSE2(0.25,0.5,0.1), curve)
    @test res.ind == CurveIndex(1, 0.25)
    @test isapprox(res.t, 0.5)
    @test isapprox(res.ϕ, 0.1)
    res = proj(VecSE2(0.25,-0.5,-0.1), curve)
    @test res.ind == CurveIndex(1, 0.25)
    @test isapprox(res.t, -0.5)
    @test isapprox(res.ϕ, -0.1)
    res = proj(VecSE2(1.5,0.5,-0.1), curve)
    @test res.ind == CurveIndex(2, 0.25)
    @test isapprox(res.t,  0.5)
    @test isapprox(res.ϕ, -0.1)
    res = proj(VecSE2(10.0,0.0,0.0), curve)
    @test res.ind == CurveIndex(length(curve)-1, 1.0)
    @test isapprox(res.t, 0.0)
    @test isapprox(res.ϕ, 0.0)

    curve2 = [CurvePt(VecSE2(-1.0,-1.0,π/4), 0.0),
              CurvePt(VecSE2( 1.0, 1.0,π/4), hypot(2.0,2.0)),
              CurvePt(VecSE2( 3.0, 3.0,π/4), hypot(4.0,4.0))]

   res = proj(VecSE2(0.0,0.0,0.0), curve2)
   @test res.ind == CurveIndex(1, 0.5)
   @test isapprox(res.t, 0.0)
   @test isapprox(res.ϕ, -π/4)
end # curve tests

@testset "roadways" begin
    curve = get_test_curve1()

    lanetag = LaneTag(1,1)
    lane = Lane(lanetag, curve)
    show(IOBuffer(), lanetag)

    @test !has_next(lane)
    @test !has_prev(lane)

    show(IOBuffer(), RoadIndex(CurveIndex(1,0.0), lanetag))

    roadway = get_test_roadway()

    io = IOBuffer()
    show(io, roadway)
    close(io)

    lane = roadway[LaneTag(1,1)]
    @test has_next(lane)
    @test !has_prev(lane)
    @test lane.exits[1].target == RoadIndex(CurveIndex(1,0.0), LaneTag(2,1))

    lane = roadway[LaneTag(2,1)]
    @test has_next(lane)
    @test has_prev(lane)
    @test lane.exits[1].target == RoadIndex(CurveIndex(1,0.0), LaneTag(3,1))
    @test lane.entrances[1].target == RoadIndex(CurveIndex(1,1.0), LaneTag(1,1))

    res = proj(VecSE2(1.0,0.0,0.0), lane, roadway)
    @inferred proj(VecSE2(1.0,0.0,0.0), lane, roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(1.0,0.0,0.0), lane, roadway, move_along_curves=false)
    @inferred proj(VecSE2(1.0,0.0,0.0), lane, roadway, move_along_curves=false)
    @test res.curveproj.ind == CurveIndex(2, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(1.5,0.25,0.1), lane, roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.5)
    @test isapprox(res.curveproj.t, 0.25)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == lane.tag

    res = proj(VecSE2(0.0,0.0,0.0), lane, roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(-0.75,0.0,0.0), lane, roadway)
    @test res.curveproj.ind == CurveIndex(0, 0.25)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(-1.75,0.0,0.0), lane, roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.25)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == prev_lane(lane, roadway).tag

    res = proj(VecSE2(-1.75,0.0,0.0), lane, roadway, move_along_curves=false)
    @test res.curveproj.ind == CurveIndex(0, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(4.25,0.2,0.1), lane, roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.25)
    @test isapprox(res.curveproj.t, 0.2)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == next_lane(lane, roadway).tag

    res = proj(VecSE2(4.25,0.2,0.1), lane, roadway, move_along_curves=false)
    @test res.curveproj.ind == CurveIndex(4, 1.0)
    @test isapprox(res.curveproj.t, 0.2)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == lane.tag

    res = proj(VecSE2(3.25,0.2,0.1), lane, roadway)
    @test res.curveproj.ind == CurveIndex(4, 0.25)
    @test isapprox(res.curveproj.t, 0.2)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == lane.tag

    res = proj(VecSE2(4.25,0.2,0.1), prev_lane(lane, roadway), roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.25)
    @test isapprox(res.curveproj.t, 0.2)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == next_lane(lane, roadway).tag

    res = proj(VecSE2(-0.75,0.0,0.0), next_lane(lane, roadway), roadway)
    @test res.curveproj.ind == CurveIndex(0, 0.25)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    ####

    seg = roadway[2]

    res = proj(VecSE2(1.0,0.0,0.0), seg, roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(1.5,0.25,0.1), seg, roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.5)
    @test isapprox(res.curveproj.t, 0.25)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == lane.tag

    res = proj(VecSE2(0.0,0.0,0.0), seg, roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(-0.75,0.0,0.0), seg, roadway)
    @test res.curveproj.ind == CurveIndex(0, 0.25)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(-1.75,0.0,0.0), seg, roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.25)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == prev_lane(lane, roadway).tag

    res = proj(VecSE2(4.25,0.2,0.1), seg, roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.25)
    @test isapprox(res.curveproj.t, 0.2)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == next_lane(lane, roadway).tag

    res = proj(VecSE2(3.25,0.2,0.1), seg, roadway)
    @test res.curveproj.ind == CurveIndex(4, 0.25)
    @test isapprox(res.curveproj.t, 0.2)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == lane.tag

    res = proj(VecSE2(4.25,0.2,0.1), roadway[1], roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.25)
    @test isapprox(res.curveproj.t, 0.2)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == next_lane(lane, roadway).tag

    res = proj(VecSE2(-0.75,0.0,0.0), roadway[3], roadway)
    @test res.curveproj.ind == CurveIndex(0, 0.25)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(1.0,1.0,0.0), seg, roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == LaneTag(2,2)

    res = proj(VecSE2(1.0,2.0,0.0), seg, roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == LaneTag(2,3)

    ###

    res = proj(VecSE2(1.0,0.0,0.0), roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(1.5,0.25,0.1), roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.5)
    @test isapprox(res.curveproj.t, 0.25)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == lane.tag

    res = proj(VecSE2(0.0,0.0,0.0), roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(-0.75,0.0,0.0), roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.25)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == prev_lane(lane, roadway).tag

    res = proj(VecSE2(-1.75,0.0,0.0), roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.25)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == prev_lane(lane, roadway).tag

    res = proj(VecSE2(4.25,0.2,0.1), roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.25)
    @test isapprox(res.curveproj.t, 0.2)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == next_lane(lane, roadway).tag

    res = proj(VecSE2(3.25,0.2,0.1), roadway)
    @test res.curveproj.ind == CurveIndex(4, 0.25)
    @test isapprox(res.curveproj.t, 0.2)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == lane.tag

    res = proj(VecSE2(4.25,0.2,0.1), roadway[1], roadway)
    @test res.curveproj.ind == CurveIndex(1, 0.25)
    @test isapprox(res.curveproj.t, 0.2)
    @test isapprox(res.curveproj.ϕ, 0.1)
    @test res.tag == next_lane(lane, roadway).tag

    res = proj(VecSE2(-0.75,0.0,0.0), roadway[3], roadway)
    @test res.curveproj.ind == CurveIndex(0, 0.25)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == lane.tag

    res = proj(VecSE2(1.0,1.0,0.0), roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == LaneTag(2,2)

    res = proj(VecSE2(1.0,2.0,0.0), roadway)
    @test res.curveproj.ind == CurveIndex(2, 0.0)
    @test isapprox(res.curveproj.t, 0.0)
    @test isapprox(res.curveproj.ϕ, 0.0)
    @test res.tag == LaneTag(2,3)

    ###

    roadind_0 = RoadIndex(CurveIndex(1, 0.0), LaneTag(2,1))
    roadind = move_along(roadind_0, roadway, 0.0)
    @inferred move_along(roadind_0, roadway, 0.0)
    @test roadind == roadind_0

    roadind = move_along(roadind_0, roadway, 1.0)
    @test roadind == RoadIndex(CurveIndex(2,0.0), LaneTag(2,1))

    roadind = move_along(roadind_0, roadway, 1.25)
    @test roadind == RoadIndex(CurveIndex(2,0.25), LaneTag(2,1))

    roadind = move_along(roadind_0, roadway, 3.0)
    @test roadind == RoadIndex(CurveIndex(3,1.0), LaneTag(2,1))

    roadind = move_along(roadind_0, roadway, 4.0)
    @test roadind == RoadIndex(CurveIndex(1,0.0), LaneTag(3,1))

    roadind = move_along(roadind_0, roadway, 4.5)
    @test roadind == RoadIndex(CurveIndex(1,0.5), LaneTag(3,1))

    roadind = move_along(roadind_0, roadway, 3.75)
    @test roadind == RoadIndex(CurveIndex(0,0.75), LaneTag(3,1))

    roadind = move_along(roadind_0, roadway, -1.0)
    @test roadind == RoadIndex(CurveIndex(0,0.0), LaneTag(2,1))

    roadind = move_along(roadind_0, roadway, -1.75)
    @test roadind == RoadIndex(CurveIndex(1,0.25), LaneTag(1,1))

    roadind = move_along(roadind_0, roadway, -0.75)
    @test roadind == RoadIndex(CurveIndex(0,0.25), LaneTag(2,1))

    roadind = move_along(roadind_0, roadway, -Inf)
    @test roadind == RoadIndex(CurveIndex(1,0.0), LaneTag(1,1))

    roadind = move_along(roadind_0, roadway, Inf)
    @test roadind == RoadIndex(CurveIndex(1,1.0), LaneTag(3,1))

    ####

    @test n_lanes_right(roadway[LaneTag(2,1)], roadway) == 0
    @test n_lanes_right(roadway[LaneTag(2,2)], roadway) == 1
    @test n_lanes_right(roadway[LaneTag(2,3)], roadway) == 2
    @test n_lanes_left(roadway[LaneTag(2,1)], roadway) == 2
    @test n_lanes_left(roadway[LaneTag(2,2)], roadway) == 1
    @test n_lanes_left(roadway[LaneTag(2,3)], roadway) == 0

    ####
    roadway = get_test_roadway()
    all_lanes = lanes(roadway)
    all_lane_tags = lanetags(roadway)
    @test all_lane_tags == [l.tag for l in all_lanes]
    @test all_lanes == Lane{Float64}[roadway[tag] for tag in all_lane_tags]
    for i=1:2
        for j=1:3
            @test roadway[LaneTag(i,j)] in all_lanes
            @test LaneTag(i,j) in all_lane_tags
        end
    end

end # roadway test

@testset "roadway read/write" begin
    roadway = Roadway()

    seg1 = RoadSegment(1,
        [Lane(LaneTag(1,1),
            [CurvePt(VecSE2(0.0,0.0,0.0), 0.0),
             CurvePt(VecSE2(1.0,0.0,0.0), 1.0)],
             width=1.0,
             boundary_left = LaneBoundary(:solid, :white),
             boundary_right = LaneBoundary(:broken, :yellow)),
         Lane(LaneTag(1,2),
            [CurvePt(VecSE2(0.0,1.0,0.0), 0.0),
             CurvePt(VecSE2(1.0,1.0,0.0), 1.0)],
             width=2.0,
             boundary_left = LaneBoundary(:double, :white))],
         )

    seg2 = RoadSegment(2,
        [Lane(LaneTag(2,1),
            [CurvePt(VecSE2(4.0,0.0,0.0), 0.0),
             CurvePt(VecSE2(5.0,0.0,0.0), 1.0)]),
         Lane(LaneTag(2,2),
            [CurvePt(VecSE2(4.0,1.0,0.0), 0.0),
             CurvePt(VecSE2(5.0,1.0,0.0), 1.0)])],
         )

    connect!(seg1.lanes[1], seg2.lanes[2])

    push!(roadway.segments, seg1)
    push!(roadway.segments, seg2)

    ############

    path, io = mktemp()
    write(io, MIME"text/plain"(), roadway)
    close(io)

    lines = open(readlines, path)

    for (line_orig, line_test) in zip(lines,
            [
             "ROADWAY",
             "2",
             "1",
             "   2",
             "   1",
             "       1.000",
             "       -Inf Inf",
             "       solid white",
             "       broken yellow",
             "       1",
             "           D (1 1.000000) 1 0.000000 2 2",
             "       2",
             "           (0.0000 0.0000 0.000000) 0.0000 NaN NaN",
             "           (1.0000 0.0000 0.000000) 1.0000 NaN NaN",
             "   2",
             "       2.000",
             "       -Inf Inf",
             "       double white",
             "       unknown unknown",
             "       0",
             "       2",
             "           (0.0000 1.0000 0.000000) 0.0000 NaN NaN",
             "           (1.0000 1.0000 0.000000) 1.0000 NaN NaN",
             "2",
             "   2",
             "   1",
             "       3.000",
             "       -Inf Inf",
             "       unknown unknown",
             "       unknown unknown",
             "       0",
             "       2",
             "           (4.0000 0.0000 0.000000) 0.0000 NaN NaN",
             "           (5.0000 0.0000 0.000000) 1.0000 NaN NaN",
             "   2",
             "       3.000",
             "       -Inf Inf",
             "       unknown unknown",
             "       unknown unknown",
             "       1",
             "           U (1 0.000000) 1 1.000000 1 1",
             "       2",
             "           (4.0000 1.0000 0.000000) 0.0000 NaN NaN",
             "           (5.0000 1.0000 0.000000) 1.0000 NaN NaN",
             ]
        )
        @test strip(line_orig) == strip(line_test)
    end

    io = open(path)
    roadway2 = read(io, MIME"text/plain"(), Roadway)
    close(io)
    rm(path)

    @test length(roadway.segments) == length(roadway2.segments)
    for (seg1, seg2) in zip(roadway.segments, roadway2.segments)
        @test seg1.id == seg2.id
        @test length(seg1.lanes) == length(seg2.lanes)
        for (lane1, lane2) in zip(seg1.lanes, seg2.lanes)
            @test lane1.tag == lane2.tag
            @test isapprox(lane1.width, lane2.width, atol=1e-3)
            @test isapprox(lane1.speed_limit.lo, lane2.speed_limit.lo, atol=1e-3)
            @test isapprox(lane1.speed_limit.hi, lane2.speed_limit.hi, atol=1e-3)
            @test lane1.boundary_left == lane2.boundary_left
            @test lane1.boundary_right == lane2.boundary_right
            for (conn1, conn2) in zip(lane1.exits, lane2.exits)
                @test conn1.downstream == conn2.downstream
                @test conn1.mylane.i == conn2.mylane.i
                @test isapprox(conn1.mylane.t, conn2.mylane.t, atol=1e-3)
                @test conn1.target.tag == conn2.target.tag
                @test conn1.target.ind.i == conn2.target.ind.i
                @test isapprox(conn1.target.ind.t, conn2.target.ind.t, atol=1e-3)
            end
            for (conn1, conn2) in zip(lane1.entrances, lane2.entrances)
                @test conn1.downstream == conn2.downstream
                @test conn1.mylane.i == conn2.mylane.i
                @test isapprox(conn1.mylane.t, conn2.mylane.t, atol=1e-3)
                @test conn1.target.tag == conn2.target.tag
                @test conn1.target.ind.i == conn2.target.ind.i
                @test isapprox(conn1.target.ind.t, conn2.target.ind.t, atol=1e-3)
            end
            for (pt1, pt2) in zip(lane1.curve, lane2.curve)
                @test normsquared(convert(VecE2, pt1.pos) - convert(VecE2, pt2.pos)) < 0.01
                @test angledist(pt1.pos.θ, pt2.pos.θ) < 1e-5
                @test isnan(pt1.s) || isapprox(pt1.s, pt2.s, atol=1e-3)
                @test isnan(pt1.k) || isapprox(pt1.k, pt2.k, atol=1e-6)
                @test isnan(pt1.kd) || isapprox(pt1.kd, pt2.kd, atol=1e-6)
            end
        end
    end
end # roadway read/write tests

@testset "Lane connection" begin
    lc = LaneConnection(true, CurveIndex(1,0.0), RoadIndex(CurveIndex(2,0.0), LaneTag(2,2)))
    show(IOBuffer(), lc)
end

@testset "Frenet" begin
    @test isapprox(AutomotiveDrivingModels._mod2pi2(0.0), 0.0)
    @test isapprox(AutomotiveDrivingModels._mod2pi2(0.5), 0.5)
    @test isapprox(AutomotiveDrivingModels._mod2pi2(2pi + 1), 1.0)
    @test isapprox(AutomotiveDrivingModels._mod2pi2(1 - 2pi), 1.0)

    roadway = get_test_roadway()
    roadproj = proj(VecSE2(0.0, 0.0, 0.0), roadway)
    roadind = RoadIndex(roadproj)

    @test roadind.ind.i == 1
    @test isapprox(roadind.ind.t, 0.0)
    @test roadind.tag == LaneTag(2,1)
    f = Frenet(roadind, roadway, t=0.1, ϕ=0.2)
    @test f.roadind === roadind
    @test isapprox(f.s, 0.0)
    @test f.t == 0.1
    @test f.ϕ == 0.2

    f = Frenet(roadproj, roadway)
    @test f.roadind === roadind
    @test isapprox(f.s, 0.0)
    @test f.t == 0.0
    @test f.ϕ == 0.0

    f = Frenet(VecSE2(0.0, 0.0, 0.0), roadway)
    @test f.roadind === roadind
    @test isapprox(f.s, 0.0)
    @test f.t == 0.0
    @test f.ϕ == 0.0
    @test get_posG(f, roadway) == VecSE2(0.0, 0.0, 0.0)

    lane = roadway[LaneTag(1,1)]
    f = Frenet(lane, 1.0, 0.0, 0.0)
    @test f.roadind.tag == lane.tag
    @test isapprox(f.s, 1.0)
    @test f.t == 0.0
    @test f.ϕ == 0.0
end

@testset "straight roadway" begin
    curve = gen_straight_curve(VecE2(25.0, -10.0), VecE2(25.0, 10.0), 2)
    @inferred gen_straight_curve(VecE2(25.0, -10.0), VecE2(25.0, 10.0), 2)
    @test length(curve) == 2
    @test curve[1].pos.x == 25.0

    roadway = gen_straight_roadway(1, 1000.0)
    @test length(roadway.segments) == 1

    seg = roadway[1]
    @test length(seg.lanes) == 1

    lane = seg.lanes[1]
    @test isapprox(lane.width, DEFAULT_LANE_WIDTH)
    @test lane.curve[1] == CurvePt(VecSE2(0.0,0.0,0.0), 0.0)
    @test lane.curve[2] == CurvePt(VecSE2(1000.0,0.0,0.0), 1000.0)

    roadway = gen_straight_roadway(3, 500.0, lane_width=1.0)
    @test length(roadway.segments) == 1

    seg = roadway[1]
    @test length(seg.lanes) == 3

    lane = seg.lanes[1]
    @test isapprox(lane.width, 1.0)
    @test lane.curve[1] == CurvePt(VecSE2(0.0,0.0,0.0), 0.0)
    @test lane.curve[2] == CurvePt(VecSE2(500.0,0.0,0.0), 500.0)

    lane = seg.lanes[2]
    @test isapprox(lane.width, 1.0)
    @test lane.curve[1] == CurvePt(VecSE2(0.0,1.0,0.0), 0.0)
    @test lane.curve[2] == CurvePt(VecSE2(500.0,1.0,0.0), 500.0)

    lane = seg.lanes[3]
    @test isapprox(lane.width, 1.0)
    @test lane.curve[1] == CurvePt(VecSE2(0.0,2.0,0.0), 0.0)
    @test lane.curve[2] == CurvePt(VecSE2(500.0,2.0,0.0), 500.0)

    origin = VecSE2(1.0,2.0,deg2rad(90))
    roadway = gen_straight_roadway(1, 100.0, lane_width=1.0, origin=origin)
    @test length(roadway.segments) == 1
    lane = roadway[1].lanes[1]
    @test lane.curve[1].pos == origin
    @test isapprox(lane.curve[2].pos.x,         1.0, atol=1e-6)
    @test isapprox(lane.curve[2].pos.y,       102.0, atol=1e-6)
    @test isapprox(lane.curve[2].pos.θ, deg2rad(90), atol=1e-6)

    roadway = gen_straight_roadway(2, 100.0, lane_widths=[1.0, 2.0])
    @test length(roadway.segments) == 1
    @test isapprox(roadway[1].lanes[1].curve[1].pos.y, 0.0, atol=1e-6)
    @test isapprox(roadway[1].lanes[2].curve[1].pos.y, 0.5 + 1.0, atol=1e-6)
end

@testset "bezier curve" begin
    # see intersection tutorial for visualization
    roadway = Roadway()
    # Define coordinates of the entry and exit points to the intersection
    r = 5.0 # turn radius
    A = VecSE2(0.0,DEFAULT_LANE_WIDTH,-π)
    B = VecSE2(0.0,0.0,0.0)
    C = VecSE2(r,-r,-π/2)
    D = VecSE2(r+DEFAULT_LANE_WIDTH,-r,π/2)
    E = VecSE2(2r+DEFAULT_LANE_WIDTH,0,0)
    F = VecSE2(2r+DEFAULT_LANE_WIDTH,DEFAULT_LANE_WIDTH,-π)

    # helper function
    function append_to_curve!(target::Curve, newstuff::Curve)
        s_end = target[end].s
        for c in newstuff
            push!(target, CurvePt(c.pos, c.s+s_end, c.k, c.kd))
        end
        return target
    end

    # Append right turn coming from the left
    curve = gen_straight_curve(convert(VecE2, B+VecE2(-100,0)), convert(VecE2, B), 2)
    append_to_curve!(curve, gen_bezier_curve(B, C, 0.6r, 0.6r, 51)[2:end])
    @test length(curve) == 52
    append_to_curve!(curve, gen_straight_curve(convert(VecE2, C), convert(VecE2, C+VecE2(0,-50.0)), 2))
    @test length(curve) == 54
    lane = Lane(LaneTag(length(roadway.segments)+1,1), curve)
    push!(roadway.segments, RoadSegment(lane.tag.segment, [lane]))

end

@testset "stadium roadway" begin
    roadway = gen_stadium_roadway(1, length=100.0, width=10.0,
                                  radius=25.0, ncurvepts_per_turn=2)
    @test length(roadway.segments) == 6

    seg = roadway[1]
    @test length(seg.lanes) == 1

    lane = seg.lanes[1]
    @test lane.curve[1] == CurvePt(VecSE2(100.0,0.0,0.0), 0.0)
    @test lane.curve[2] == CurvePt(VecSE2(125.0,25.0,π/2), 25*π/2)

    @test roadway[LaneTag(2,1)].curve[1] == CurvePt(VecSE2(125.0,35.0,π/2), 0.0)

    roadway = gen_stadium_roadway(4)
end

max_stars_repo_name: intelligent-control-lab/Autoenv

max_issues_repo_name: intelligent-control-lab/Autoenv

max_forks_repo_name: intelligent-control-lab/Autoenv


text:
module TestContainers

using LibCloud.Containers
using Base.Test
using PyCall

function ecs(key, secret)
    cp = ContainerDriver(ContainerProvider.ECS, key, secret, "us-east-1")
    println("Regions:\n", list_regions(cp))
    println("Images:\n", list_images(cp, "ecs-test"))
    println("Containers:\n", list_containers(cp))
    println("Clusters:\n", list_clusters(cp))
end

function docker(host, port)
    cp = ContainerDriver(ContainerProvider.DOCKER, host, port)
    println("Regions:\n", list_regions(cp))
    println("Images:\n", list_images(cp))
    println("Containers:\n", list_containers(cp))
    println("Locations:\n", list_locations(cp))
    println("Clusters:\n", list_clusters(cp))
end

function dummy()
    cp = ContainerDriver(ContainerProvider.DUMMY, "key", "secret")
    println("Regions:\n", list_regions(cp))
end

end # module TestContainers

ext: jl


text:
export GoogleSheetsClient, Spreadsheet, Sheet, CellRange, CellRanges, CellRangeValues, UpdateSummary, CellIndexRange1D, CellIndexRange2D, CellFormat

"""
A Google Sheets client.
"""
struct GoogleSheetsClient
    """ Client Python object. """
    client

    """ Rate limiter for API read calls. """
    rate_limiter_read::AbstractRateLimiter

    """ Rate limiter for API write calls. """
    rate_limiter_write::AbstractRateLimiter
end

"""
A spreadsheet.
"""
struct Spreadsheet
    """ Spreadsheet unique identifier. """
    id::AbstractString
end

"""
A sheet in a spreadsheet.
"""
struct Sheet
    """ Spreadsheet """
    spreadsheet::Spreadsheet

    """ Sheet unique identifier."""
    id::Int64

    """ Sheet title. """
    title::AbstractString
end

"""
    Sheet(client::GoogleSheetsClient, spreadsheet::Spreadsheet, id::Int64)

A sheet in a spreadsheet.

# Arguments
- `client::GoogleSheetsClient`: client
- `spreadsheet::Spreadsheet`: spreadsheet
- `id::Int64`: sheet id
"""
Sheet(client::GoogleSheetsClient, spreadsheet::Spreadsheet, id::Int64) = Sheet(spreadsheet, id, meta(client, spreadsheet, id)["title"])

"""
    Sheet(client::GoogleSheetsClient, spreadsheet::Spreadsheet, title::AbstractString)

A sheet in a spreadsheet.

# Arguments
- `client::GoogleSheetsClient`: client
- `spreadsheet::Spreadsheet`: spreadsheet
- `title::AbstractString`: sheet title
"""
Sheet(client::GoogleSheetsClient, spreadsheet::Spreadsheet, title::AbstractString) = Sheet(spreadsheet, meta(client, spreadsheet, title)["sheetId"], title)

"""
A range of cells within a spreadsheet.
"""
struct CellRange
    """ Spreadsheet containing the cells. """
    spreadsheet::Spreadsheet

    """ Range of cells. """
    range::AbstractString
end

"""
Multiple ranges of cells within a spreadsheet.
"""
struct CellRanges{T<:AbstractString}
    """ Spreadsheet containing the cells. """
    spreadsheet::Spreadsheet

    """ Ranges of cells. """
    ranges::Array{T,1}
end

"""
A range of cell values within a spreadsheet.
"""
struct CellRangeValues
    """ Range of cells within a spreadsheet. """
    range::CellRange

    """ Values of cells within a spreadsheet. """
    values::Union{Nothing,Array{String,2}}

    """ Major dimension of the cell values. """
    major_dimension::AbstractString
end

"""
Summary of updated updated cells.
"""
struct UpdateSummary
    """ Range of cells within a spreadsheet. """
    range::CellRange

    """ Number of updated columns. """
    updated_columns::Int64

    """ Number of updated rows. """
    updated_rows::Int64

    """ Number of updated cells. """
    updated_cells::Int64
end

"""
1D Range of cell values.
"""
struct CellIndexRange1D
    """ Sheet containing the cells. """
    sheet::Sheet

    """ Start index of the cells. """
    start_index::Integer

    """ End index of the cells. """
    end_index::Integer
end

"""
2D Range of cell values.
"""
struct CellIndexRange2D
    """ Sheet containing the cells. """
    sheet::Sheet

    """ Start row index of the cells. """
    start_row_index::Integer

    """ End row index of the cells. """
    end_row_index::Integer

    """ Start column index of the cells. """
    start_col_index::Integer

    """ End column index of the cells. """
    end_col_index::Integer
end

"""
Formatting for a cell.
"""
struct CellFormat
    """ Background color. """
    background_color::Union{Nothing,Colorant}

    """ Number format type. """
    number_format_type::Union{Nothing,NumberFormatType}

    """
    Number format pattern.
    See: https://developers.google.com/sheets/api/guides/formats
    """
    number_format_pattern::Union{Nothing,AbstractString}

    """ Should the text be formatted in italics. """
    text_italic::Union{Nothing,Bool}

    """ Should the text be bold. """
    text_bold::Union{Nothing,Bool}

    """ Should the text be strikethrough. """
    text_strikethrough::Union{Nothing,Bool}

    """ Text color. """
    text_color::Union{Nothing,Colorant}

    """ Text font size. """
    text_font_size::Union{Nothing,Real}

    """
    Formatting for a cell.

    # Arguments
    - `background_color=nothing`: background color
    - `number_format_type=nothing`: number format
    - `number_format_pattern=nothing`: number format pattern
    - `text_italic=nothing`: is text italics
    - `text_bold=nothing`: is text bold
    - `text_strikethrough=nothing`: is text strikethrough
    - `text_color=nothing`: text color
    - `text_font_size=nothing`: text_font_size
    """
    CellFormat(;
        background_color=nothing,
        number_format_type=nothing,
        number_format_pattern=nothing,
        text_italic=nothing,
        text_bold=nothing,
        text_strikethrough=nothing,
        text_color=nothing,
        text_font_size=nothing
        ) = new(background_color, number_format_type, number_format_pattern, text_italic, text_bold, text_strikethrough, text_color, text_font_size)
end


text:
# Continuation of ex 7.13, Least Squares WRM

using NumericalMethodsforEngineers
using Test

@sym begin
  ClearAll(xi, yi, N1, Y, Ydotdot, C11, ytilde1, ytilde2)
  xi = [0, 1//2, 1]
  yi = [0, a, 1]
  Y(x_) := LagrangePolynomial(xi, yi)
  #
  # Can be formulated as ytile(x) = F(x) + C1(a) * Ψ(x)
  #
  # F(x_) := 2*x^2 - x
  # C(a_) := -4a
  Ψ(x_) := x^2 - x
  #
  #Y(x_) := F(x) + C(a)*Ψ(x)
  #
  Ydotdot(x_) = D(Y(x), x, 2)
  R(x_) := Simplify(Expand(Ydotdot(x) - 3*x - 4*Y(x)))
  R(x_) = Simplify(Expand(R(x) ./ (a => -C1/4)))
  C11 = Solve(Integrate(R(x)*Ψ(x), [x, 0, 1]), C1)[1]
  SetJ(r, ToString(Simplify(R(x))))
  SetJ(C1, ToString(C11[1][2]))
  ytilde1 = Simplify(Y(x) ./ (a => -C1/4))
  ytilde2 = Simplify(ytilde1 ./ C11)
  SetJ(y, ToString(Simplify(Expand(ytilde2))));
end

println("\n\nExample 7.18: y''=3x + 4y, y(0)=0, y(1)=1")
println("using 1-point Galerkin Weighted Residual Method")
@sym Println("\nY(x) = $(Y(x))\n")
@sym Println("Y(x) = $(Simplify(Expand(Y(x) ./ (a => -C1/4))))\n")
@sym Println("R(x) = $(R(x))\n")
@sym Println("C1 = $(Solve(Integrate(R(x)*Ψ(x), [x, 0, 1]), C1)[1][1][2])\n")
@sym Println("ytilde_1pt_galerkin(x) = $(ytilde2)\n")
println("( Example 7.18 gives: ytilde = 1/4*x*(5x - 1) )\n")
@eval ytilde_1pt_galerkin(x) = $(Meta.parse(y))
@eval rf_1pt_galerkin(x, C1) = $(Meta.parse(r))

C1 = Meta.parse(C1)
rf_1pt_galerkin_1(x) = rf_1pt_galerkin(x, C1)
println()

@test r == "4 + 2C1 + x + 4C1*x - 8x^2 - 4C1*x^2"
@test y == "(1/4)*x*(-1 + 5x)"
#@test (quadgk(rf_1pt_galerkin_1, 0, 1))[1] < 5*eps()


text:
if !("Optimize" in keys(Pkg.installed()))
    Pkg.clone("https://github.com/JuliaSmoothOptimizers/Optimize.jl.git")
	Pkg.build("Optimize")
end

if !("NLPModels" in keys(Pkg.installed()))
    Pkg.add("NLPModels")
	Pkg.add("ForwardDiff")
	Pkg.add("MathProgBase")
	Pkg.add("JuMP")
	Pkg.build("NLPModels")
	Pkg.build("ForwardDiff")
	Pkg.build("MathProgBase")
	Pkg.build("JuMP")
end

if !("Plots" in keys(Pkg.installed()))
    Pkg.add("Plots")
	Pkg.build("Plots")
end

if !("LSDescentMethods" in keys(Pkg.installed()))
    Pkg.clone("https://github.com/vepiteski/LSDescentMethods.git")
	Pkg.build("LSDescentMethods")
end

if !("Stopping" in keys(Pkg.installed()))
    Pkg.clone("https://github.com/vepiteski/Stopping.jl.git")
	Pkg.build("Stopping")
end

if !("OptimizationProblems" in keys(Pkg.installed()))
    Pkg.clone("https://github.com/JuliaSmoothOptimizers/OptimizationProblems.jl.git")
	Pkg.build("OptimizationProblems")
end

if !("LineSearch" in keys(Pkg.installed()))
    Pkg.clone("https://github.com/Goysa2/LineSearch.git")
	Pkg.build("LineSearch")
end

if !("ScalarSolvers" in keys(Pkg.installed()))
    Pkg.clone("https://github.com/Goysa2/ScalarSolvers.git")
	Pkg.build("ScalarSolvers")
end

if !("LineSearches" in keys(Pkg.installed()))
    Pkg.clone("https://github.com/JuliaNLSolvers/LineSearches.jl.git")
    Pkg.build("LineSearches")
end

Pkg.update()


text:
module VirulenceEvolution

export Dynamics, record!, gillespie_single, gillespie_meta

include("sampling.jl")

include("utilities.jl")

include("singlepopulation.jl")

include("metapopulation.jl")

end # module


text:
@testset "softmax" begin
    for (sz, dims) in [((5,), :), ((5,), 1), ((5,5), :), ((5,5), 1), ((5,5), 2), ((5,5,5,5), (2,3)), ((5,5,5,5), (2,4))]
        x = randn(Float64, sz)
        y = softmax(x, dims=dims)
        dy = randn(Float64, sz)
        gputest(softmax, x, dims=dims)
        gputest(∇softmax, dy, x, y, dims=dims, checkgrad=false)
        y = logsoftmax(x, dims=dims)
        gputest(logsoftmax, x, dims=dims)
        gputest(∇logsoftmax, dy, x, y, dims=dims, checkgrad=false)
    end
end


text:
"""
    dataloader(name; header=true, dir=learninghorsedatasets)
Load a data for Machine Learning. `name` is either the name of the datasets or the full path of the data file to be loaded. The following three can be specified as the name of the dataset in `name`.
- `MNIST` : The MNIST Datasets
- `iris` : The iris Datasets
- `BostonHousing` : Boston Housing DataSets
And these datasets are downloaded and saved by creating a `dir` folder under the home directly(i.e. it is saved in the `/home_directory/learninghorsedatasets` by default).
When importing a data file, you can specify whether to read the header with `header`.

# Example
```@repl
julia> dataloader("MNIST");

julia> dataloader("/home/ubuntu/data/data.csv", header = false)
```
"""
function dataloader(name; header = true, dir = "learningdatasets")
    hd = homedir()
    dir = joinpath(hd, dir)
    mkpath(dir)
    current = pwd()
    cd(dir)
    if name == "MNIST"
        if !(isfile("mnist_train.csv"))
            yn = Base.prompt("Can I download the mnist_train.csv(110MB)? (y/n)")
            yn == "y" && Downloads.download("https://pjreddie.com/media/files/mnist_train.csv", "mnist_train.csv")
        end
        df_r = CSV.read("mnist_train.csv", header = false, DataFrame)
        if !(isfile("mnist_test.csv"))
            yn = Base.prompt("Can I download the mnist_test.csv(18MB)? (y/n)")
            yn == "y" && Downloads.download("https://pjreddie.com/media/files/mnist_test.csv", "mnist_test.csv")
        end
        df_e = CSV.read("mnist_test.csv",header = false , DataFrame)
        cd(current)
        return df_r, df_e
    elseif name == "iris"
        url = "https://gist.githubusercontent.com/netj/8836201/raw/6f9306ad21398ea43cba4f7d537619d0e07d5ae3/iris.csv"
        if !(isfile("iris.csv"))
            yn = Base.prompt("Can I download the iris.csv(4KB)? (y/n)")
            yn == "y" && Downloads.download(url, "iris.csv")
        end
        df = CSV.read("iris.csv", DataFrame)
        cd(current)
        return df
    elseif name == "BostonHousing"
        url = "https://raw.githubusercontent.com/selva86/datasets/master/BostonHousing.csv"
        if !(isfile("BostonHousing.csv"))
            yn = Base.prompt("Can I download the BostonHousing.csv(36KB)? (y/n)")
            yn == "y" && Downloads.download(url, "BostonHousing.csv")
        end
        df = CSV.read("BostonHousing.csv", DataFrame)
        cd(current)
        return df
    end
    try
        df = CSV.read(name, header=header, DataFrame)
        return df
    finally
        cd(current)
    end
end

"""
    DataSplitter(ndata; test_size=nothing, train_size=nothing)
Split the data into test data and training data. `ndata` is the number of the data, and you must specify either `test_size` or `train_size`. thease parameter can be proprtional or number of data.

!!! note
    If both `test_size` and `train_size` are specified, `test_size` takes precedence.

#Example
```jldoctest
julia> x = rand(20, 2);

julia> DS = DataSplitter(50, train_size = 0.3);

julia> train, test = DS(x, dims = 2);

julia> train |> size
(6, 2)

julia> test |> size
(14, 2)
```
"""
struct DataSplitter
    #TODO: make it possible to DataFrame split
    test_indices::Array{Int64, 1}
    train_indices::Array{Int64, 1}
    function DataSplitter(ndata; test_size=nothing, train_size=nothing)
        test_size == train_size == nothing && throw(ArgumentError("test_size and train_size wasn't specified. you must specify either one."))
        if test_size == nothing
            #number of train data is ceiled
            test_size = (0<=train_size<=1) ? ndata-ceil(train_size*ndata) : ndata-train_size
        else
            test_size = (0<=test_size<=1) ? ndata-ceil((1-test_size)*ndata) : test_size
        end
        new(sample(1:ndata, Int(test_size), nc=true)...)
    end
end

function (DS::DataSplitter)(xs; dims=1)
    test_index = fill!(Array{Union{Colon, Array{Int64, 1}}}(undef, ndims(xs)), :)
    train_index = fill!(Array{Union{Colon, Array{Int64, 1}}}(undef, ndims(xs)), :)
    train_index[dims] = DS.train_indices
    test_index[dims] = DS.test_indices
    return xs[train_index...], xs[test_index...]
end


text:
using Documenter

using Pkg
if haskey(ENV, "GITLAB_CI")
  Pkg.add([PackageSpec(name = x; rev = "master") for x in ["CUDAdrv", "LLVM"]])
end

using CUDAnative

makedocs(
    modules = [CUDAnative],
    format = Documenter.HTML(prettyurls = get(ENV, "CI", nothing) == "true"),
    sitename = "CUDAnative.jl",
    pages = [
        "Home"    => "index.md",
        "Manual"  => [
            "man/usage.md",
            "man/troubleshooting.md",
            "man/performance.md",
            "man/hacking.md"
        ],
        "Library" => [
            "lib/compilation.md",
            "lib/reflection.md",
            "Device Code" => [
                "lib/device/intrinsics.md",
                "lib/device/array.md",
                "lib/device/libdevice.md"
            ]
        ]
    ],
    doctest = true
)


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

@testset "indmax, indmin, findmax, findmin" begin
    S = sprand(100,80, 0.5)
    A = Array(S)
    @test indmax(S) == indmax(A)
    @test indmin(S) == indmin(A)
    @test findmin(S) == findmin(A)
    @test findmax(S) == findmax(A)
    for region in [(1,), (2,), (1,2)], m in [findmax, findmin]
        @test m(S, region) == m(A, region)
    end

    S = spzeros(10,8)
    A = Array(S)
    @test indmax(S) == indmax(A) == 1
    @test indmin(S) == indmin(A) == 1

    A = Array{Int}(0,0)
    S = sparse(A)
    iA = try indmax(A) end
    iS = try indmax(S) end
    @test iA === iS === nothing
    iA = try indmin(A) end
    iS = try indmin(S) end
    @test iA === iS === nothing
end

## findmin/findmax/minumum/maximum

stringf(a) = string(full(a))
stringf(a::Tuple) = string("(", stringf(a[1]), ", ", stringf(a[2]), ")")
Base.zero(::Type{T}) where {T<:AbstractString} = ""

A = sparse([1.0 3.0 6.0;
            5.0 2.0 4.0])
for (tup, rval, rind) in [((1,), [1.0 2.0 4.0], [1 4 6]),
                          ((2,), reshape([1.0,2.0], 2, 1), reshape([1,4], 2, 1)),
                          ((1,2), fill(1.0,1,1),fill(1,1,1))]
    println("tup = $tup A = $A")
    @test findmin(A, tup) == (rval, rind)
    @test findmin!(similar(rval), similar(rind), A) == (rval, rind)
    @test stringf(minimum(A, tup)) == string(rval)
    @test stringf(minimum!(similar(rval), A)) == string(rval)
    @test stringf(minimum!(copy(rval), A, init=false)) == string(rval)
end

"""
for (tup, rval, rind) in [((1,), [5.0 3.0 6.0], [2 3 5]),
                          ((2,), reshape([6.0,5.0], 2, 1), reshape([5,2], 2, 1)),
                          ((1,2), fill(6.0,1,1),fill(5,1,1))]
    @test findmax(A, tup) == (rval, rind)
    @test findmax!(similar(rval), similar(rind), A) == (rval, rind)
    @test stringf(maximum(A, tup)) == string(rval)
    @test stringf(maximum!(similar(rval), A)) == string(rval)
    @test stringf(maximum!(copy(rval), A, init=false)) == string(rval)
end

#issue 23209

A = sparse([1.0 3.0 6.0;
            NaN 2.0 4.0])
for (tup, rval, rind) in [((1,), [NaN 2.0 4.0], [2 4 6]),
                          ((2,), reshape([1.0, NaN], 2, 1), reshape([1,2], 2, 1)),
                          ((1,2), fill(NaN,1,1),fill(2,1,1))]
    @test stringf(findmin(A, tup)) == string((rval, rind))
    @test stringf(findmin!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(minimum(A, tup)) == string(rval)
    @test stringf(minimum!(similar(rval), A)) == string(rval)
    @test stringf(minimum!(copy(rval), A, init=false)) == string(rval)
end

for (tup, rval, rind) in [((1,), [NaN 3.0 6.0], [2 3 5]),
                          ((2,), reshape([6.0, NaN], 2, 1), reshape([5,2], 2, 1)),
                          ((1,2), fill(NaN,1,1),fill(2,1,1))]
    @test stringf(findmax(A, tup)) == string((rval, rind))
    @test stringf(findmax!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(maximum(A, tup)) == string(rval)
    @test stringf(maximum!(similar(rval), A)) == string(rval)
    @test stringf(maximum!(copy(rval), A, init=false)) == string(rval)
end

A = sparse([1.0 NaN 6.0;
            NaN 2.0 4.0])
for (tup, rval, rind) in [((1,), [NaN NaN 4.0], [2 3 6]),
                          ((2,), reshape([NaN, NaN], 2, 1), reshape([3,2], 2, 1)),
                          ((1,2), fill(NaN,1,1),fill(2,1,1))]
    @test stringf(findmin(A, tup))  == string((rval, rind))
    @test stringf(findmin!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(minimum(A, tup)) == string(rval)
    @test stringf(minimum!(similar(rval), A)) == string(rval)
    @test stringf(minimum!(copy(rval), A, init=false)) == string(rval)
end

for (tup, rval, rind) in [((1,), [NaN NaN 6.0], [2 3 5]),
                          ((2,), reshape([NaN, NaN], 2, 1), reshape([3,2], 2, 1)),
                          ((1,2), fill(NaN,1,1),fill(2,1,1))]
    @test stringf(findmax(A, tup)) == string((rval, rind))
    @test stringf(findmax!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(maximum(A, tup)) == string(rval)
    @test stringf(maximum!(similar(rval), A)) == string(rval)
    @test stringf(maximum!(copy(rval), A, init=false)) == string(rval)
end

A = sparse([Inf -Inf Inf  -Inf;
            Inf  Inf -Inf -Inf])
for (tup, rval, rind) in [((1,), [Inf -Inf -Inf -Inf], [1 3 6 7]),
                          ((2,), reshape([-Inf -Inf], 2, 1), reshape([3,6], 2, 1)),
                          ((1,2), fill(-Inf,1,1),fill(3,1,1))]
    @test stringf(findmin(A, tup))  == string((rval, rind))
    @test stringf(findmin!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(minimum(A, tup)) == string(rval)
    @test stringf(minimum!(similar(rval), A)) == string(rval)
    @test stringf(minimum!(copy(rval), A, init=false)) == string(rval)
end

for (tup, rval, rind) in [((1,), [Inf Inf Inf -Inf], [1 4 5 7]),
                          ((2,), reshape([Inf Inf], 2, 1), reshape([1,2], 2, 1)),
                          ((1,2), fill(Inf,1,1),fill(1,1,1))]
    @test stringf(findmax(A, tup)) == string((rval, rind))
    @test stringf(findmax!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(maximum(A, tup)) == string(rval)
    @test stringf(maximum!(similar(rval), A)) == string(rval)
    @test stringf(maximum!(copy(rval), A, init=false)) == string(rval)
end

A = sparse([BigInt(10)])
for (tup, rval, rind) in [((2,), [BigInt(10)], [1])]
    @test stringf(findmin(A, tup))  == string((rval, rind))
    @test stringf(findmin!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(minimum(A, tup)) == string(rval)
    @test stringf(minimum!(similar(rval), A)) == string(rval)
    @test stringf(minimum!(copy(rval), A, init=false)) == string(rval)
end

for (tup, rval, rind) in [((2,), [BigInt(10)], [1])]
    @test stringf(findmax(A, tup)) == string((rval, rind))
    @test stringf(findmax!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(maximum(A, tup)) == string(rval)
    @test stringf(maximum!(similar(rval), A)) == string(rval)
    @test stringf(maximum!(copy(rval), A, init=false)) == string(rval)
end

A = sparse([BigInt(-10)])
for (tup, rval, rind) in [((2,), [BigInt(-10)], [1])]
    @test stringf(findmin(A, tup))  == string((rval, rind))
    @test stringf(findmin!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(minimum(A, tup)) == string(rval)
    @test stringf(minimum!(similar(rval), A)) == string(rval)
    @test stringf(minimum!(copy(rval), A, init=false)) == string(rval)
end

for (tup, rval, rind) in [((2,), [BigInt(-10)], [1])]
    @test stringf(findmax(A, tup)) == string((rval, rind))
    @test stringf(findmax!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(maximum(A, tup)) == string(rval)
    @test stringf(maximum!(similar(rval), A)) == string(rval)
    @test stringf(maximum!(copy(rval), A, init=false)) == string(rval)
end

A = sparse([BigInt(10) BigInt(-10)])
for (tup, rval, rind) in [((2,), [BigInt(-10)], [2])]
    @test stringf(findmin(A, tup))  == string((rval, rind))
    @test stringf(findmin!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(minimum(A, tup)) == string(rval)
    @test stringf(minimum!(similar(rval), A)) == string(rval)
    @test stringf(minimum!(copy(rval), A, init=false)) == string(rval)
end

for (tup, rval, rind) in [((2,), [BigInt(10)], [1])]
    @test stringf(findmax(A, tup)) == string((rval, rind))
    @test stringf(findmax!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(maximum(A, tup)) == string(rval)
    @test stringf(maximum!(similar(rval), A)) == string(rval)
    @test stringf(maximum!(copy(rval), A, init=false)) == string(rval)
end

A = sparse(["a", "b"])
for (tup, rval, rind) in [((1,), ["a"], [1])]
    @test stringf(findmin(A, tup))  == string((rval, rind))
    @test stringf(findmin!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(minimum(A, tup)) == string(rval)
    @test stringf(minimum!(similar(rval), A)) == string(rval)
    @test stringf(minimum!(copy(rval), A, init=false)) == string(rval)
end

for (tup, rval, rind) in [((1,), ["b"], [2])]
    @test stringf(findmax(A, tup)) == string((rval, rind))
    @test stringf(findmax!(similar(rval), similar(rind), A)) == string((rval, rind))
    @test stringf(maximum(A, tup)) == string(rval)
    @test stringf(maximum!(similar(rval), A)) == string(rval)
    @test stringf(maximum!(copy(rval), A, init=false)) == string(rval)
end

"""


text:
# This file is available under the terms of the MIT License

@doc """
Types for describing DMD fit and storing necessary
variables
"""

"""
DMDParams - stores the description of the problem
including data and sizes. We
only provide constructors for BLAS friendly types
for now
"""

mutable struct DMDParams{T<:AbstractFloat}
    # dimensions
    m::Integer
    n::Integer
    k::Integer
    #
    # data
    X::Matrix{Complex{T}}
    x::Array{Vector{Complex{T}},1}
    t::Vector{Complex{T}}
    #
    # loss function and gradient
    lossFunc::Function
    lossGrad::Function
    #
    # variables
    a::Vector{Complex{T}}
    P::Matrix{Complex{T}}
    B::Matrix{Complex{T}}
    b::Array{Vector{Complex{T}},1}
    #
    R::Matrix{Complex{T}}
    r::Array{Vector{Complex{T}},1}
    #
    ar::Vector{T}
    br::Array{Vector{T},1}
    #
    # temp variables
    tv::Vector{Complex{T}}
    tM::Matrix{Complex{T}}
    #
    # inner solve options
    inner_opts::Any
end

# constructors
function DMDParams(k, X, t, lossFunc, lossGrad;
                   inner_opts=Optim.Options())
    m,n = size(X);
    x   = col_view(X);
    #
    Tx  = eltype(X);
    Tt  = eltype(t);
    if Tx ≠ Tt
        t = convert(Vector{Tx}, t);
    end
    #
    a = zeros(Tx, k);
    P = zeros(Tx, m, k);
    B = zeros(Tx, k, n);
    R = zeros(Tx, m, n);
    #
    b = col_view(B);
    r = col_view(R);
    #
    ar = col_view_real(a);
    br = col_view_real(B);
    #
    tv = zeros(Tx, k);
    tM = zeros(Tx, k, n);
    #
    return DMDParams(m, n, k, X, x, t, lossFunc, lossGrad,
        a, P, B, b, R, r, ar, br, tv, tM, inner_opts)
end


text:
# # [Illustration how to use mutating gradient functions](@id Mutations)
#
# When it comes to time critital operations, a main ingredient in Julia are
# mutating functions, i.e. those that compute in place without additional Memory
# allocations. In the following the illustrate how to do this with `Manopt.jl`.
#
# Let's start with the same function as in [Get Started: Optimize!](@ref Optimize)
# and compute the mean of some points. Just that here we use the sphere ``\mathbb S^{30}``
# and `n=800` points.
#
# From the just mentioned example, the implementation looks like
using Manopt, Manifolds, Random, BenchmarkTools, Test
Random.seed!(42)
m = 30
M = Sphere(m)
n = 800
σ = π / 8
x = zeros(Float64, m + 1)
x[2] = 1.0
data = [exp(M, x, random_tangent(M, x, Val(:Gaussian), σ)) for i in 1:n];
#
# ## Classical definition
#
# The variant from the previous tutorial defines a cost ``F(x)`` and its gradient ``gradF(x)``
F(x) = sum(1 / (2 * n) * distance.(Ref(M), Ref(x), data) .^ 2)
gradF(M, x) = sum(1 / n * grad_distance.(Ref(M), data, Ref(x)))
nothing #hide
#
# we further set the stopping criterion to be a little more strict, then we obtain
#
sc = StopWhenGradientNormLess(1e-10)
x0 = random_point(M)
m1 = gradient_descent(M, F, gradF, x0; stopping_criterion=sc)

@btime gradient_descent($M, $F, $gradF, $x0; stopping_criterion=$sc)
nothing #hide
#
# ## Inplace computation of the gradient
#
# We can reduce the memory allocations, by implementing the gradient as a [functor](https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects).
# The motivation is twofold: On the one hand, we want to avoid variables from global scope,
# for example the manifold `M` or the `data`, to be used within the function
# For more complicated cost functions it might also be worth considering to do the same.
#
# Here we store the data (as reference) and one temporary memory in order to avoid
# reallocation of memory per `grad_distance` computation. We have
struct grad!{TD,TTMP}
    data::TD
    tmp::TTMP
end
function (gradf!::grad!)(M, X, x)
    fill!(X, 0)
    for di in gradf!.data
        grad_distance!(M, gradf!.tmp, di, x)
        X .+= gradf!.tmp
    end
    X ./= length(gradf!.data)
    return X
end
#
# Then we just have to initialize the gradient and perform our final benchmark.
# Note that we also have to interpolate all variables passed to the benchmark with a `$`.
#
gradF2! = grad!(data, similar(data[1]))
m2 = deepcopy(x0)
gradient_descent!(M, F, gradF2!, m2; evaluation=MutatingEvaluation(), stopping_criterion=sc)

@btime gradient_descent!(
    $M, $F, $gradF2!, m2; evaluation=$(MutatingEvaluation()), stopping_criterion=$sc
) setup = (m2 = deepcopy($x0))
nothing #hide
#
# Mote that the results `m1`and `m2` are of course the same.
#
@test distance(M, m1, m2) ≈ 0


text:
function _trim(a::Array{T})::Tuple{Array{Int64},Array{Int64}} where {T<:AbstractFloat}

	#Functions first calculates 68% central percentile then returns list of deleted
	#indicies (i.e. outside the 68%) and accepted indicies (i.e. inside 68% percentile).

    if length(a) < 3
        return (Vector{Int64}(), collect(range(1,stop=length(a))))
    end
    # 1-sigma range of a unit normal distribution
    lower = quantile(a, 0.15865)
    upper = quantile(a, 0.84135)
    indices = findall(x-> x >= lower && x <= upper, a)
    return (setdiff(range(1,stop=length(a)), indices), indices)
end

function trim(x::Array)
    deleteat!(x, _trim(x)[1])
    x
end

function trim(
    res::IntermediateResults{T},
    dotrimming::Bool)::Array{Int64, 1} where {T<:AbstractFloat}

    deleteids, remainingids = _trim(res.integrals)

    if dotrimming && length(remainingids) > 1
		@debug "Trimming integration results: $(length(deleteids)) entries out of $(length(res.integrals)) deleted"
        deleteat!(res.integrals, deleteids)
        deleteat!(res.volumeID, deleteids)
        res.Y = res.Y[:, remainingids]
	elseif dotrimming && length(remainingids) < 2
		@warn "Trimming is NOT successful. No entries will be deleted"
    end

    deleteids
end

function split_dataset(dataset::DataSet{T, I})::Tuple{DataSet{T, I}, DataSet{T, I}} where {T<:Real, I<:Integer}

    ds1 = DataSet(dataset.data[:, 1:2:end], dataset.logprob[1:2:end], dataset.weights[1:2:end], dataset.nsubsets, dataset.subsetsize)
    ds2 = DataSet(dataset.data[:, 2:2:end-1], dataset.logprob[2:2:end-1], dataset.weights[2:2:end-1], dataset.nsubsets, dataset.subsetsize)

    return ds1, ds2
end


text:
module TestLength
using Compat
using Compat.Test
using CategoricalArrays

@testset "length(pool)" begin
    pool = CategoricalPool([1, 2, 3])
    @test length(pool) == 3

    pool = CategoricalPool([1, 2, 3], [3, 2, 1])
    @test length(pool) == 3
end

end


text:
#
# Manopt.jl – Proximal maps
#
# This file provides several proximal maps on manifolds or on small
# product manifolds, like M^2
#
# ---
# Manopt.jl - R. Bergmann – 2017-07-06

export proxDistance, proxTV, proxParallelTV, proxTV2, proxCollaborativeTV

@doc doc"""
    y = proxDistance(M,λ,f,x [,p=2])

compute the proximal map $\operatorname{prox}_{\lambda\varphi}$ with
parameter λ of $\varphi(x) = \frac{1}{p}d_{\mathcal M}^p(f,x)$.

# Input
* `M` – a [`Manifold`](@ref) $\mathcal M$
* `λ` – the prox parameter
* `f` – an [`MPoint`](@ref) $f\in\mathcal M$ (the data)
* `x` – the argument of the proximal map

# Optional argument
* `p` – (`2`) exponent of the distance.

# Ouput
* `y` – the result of the proximal map of $\varphi$
"""
function proxDistance(M::mT,λ::Number,f::T,x::T,p::Int=2) where {mT <: Manifold, T <: MPoint}
  d = distance(M,f,x)
  if p==2
    t =  λ/(1+λ);
  elseif p==1
    if λ < d
      t = λ/d;
    else
      t = 1.;
    end
  else
      throw(ErrorException(
        "Proximal Map of distance(M,f,x) not implemented for p=$(p) (requires p=1 or 2)"
      ))
  end
  return exp(M,x,log(M,x,f),t);
end
@doc doc"""
    (y1,y2) = proxTV(M,λ,(x1,x2) [,p=1])

Compute the proximal map $\operatorname{prox}_{\lambda\varphi}$ of
$\varphi(x,y) = d_{\mathcal M}^p(x,y)$ with
parameter `λ`.

# Input
* `M` – a [`Manifold`](@ref)
* `λ` – a real value, parameter of the proximal map
* `(x1,x2)` – a tuple of two [`MPoint`](@ref)s,

# Optional
(default is given in brackets)
* `p` – (1) exponent of the distance of the TV term

# Ouput
* `(y1,y2)` – resulting tuple of [`MPoint`](@ref) of the
  $\operatorname{prox}_{\lambda\varphi}($ `(x1,x2)` $)$
"""
function proxTV(M::mT,λ::Number, pointTuple::Tuple{P,P},p::Int=1)::Tuple{P,P} where {mT <: Manifold, P <: MPoint}
  x1 = pointTuple[1];
  x2 = pointTuple[2];
  d = distance(M,x1,x2);
  if p==1
    t = min(0.5, λ/d);
  elseif p==2
    t = λ/(1+2*λ);
  else
    throw(ErrorException(
      "Proximal Map of TV(M,x1,x2,p) not implemented for p=$(p) (requires p=1 or 2)"
    ))
  end
  return (  exp(M, x1, log(M, x1, x2), t), exp(M, x2, log(M, x2, x1), t)  );
end
@doc doc"""
    ξ = proxTV(M,λ,x [,p=1])

compute the proximal maps $\operatorname{prox}_{\lambda\varphi}$ of
all forward differences orrucirng in the power manifold array, i.e.
$\varphi(xi,xj) = d_{\mathcal M}^p(xi,xj)$ with `xi` and `xj` are array
elemets of `x` and `j = i+e_k`, where `e_k` is the $k$th unitvector.
The parameter `λ` is the prox parameter.

# Input
* `M` – a [`Manifold`](@ref)
* `λ` – a real value, parameter of the proximal map
* `x` – a [`PowPoint`](@ref).

# Optional
(default is given in brackets)
* `p` – (1) exponent of the distance of the TV term

# Ouput
* `y` – resulting of [`PowPoint`](@ref) with all mentioned proximal
  points evaluated (in a cylic order).
"""
function proxTV(M::Power, λ::Number, x::PowPoint,p::Int=1)::PowPoint
  R = CartesianIndices(M.powerSize)
  d = length(M.powerSize)
  maxInd = Tuple(last(R))
  y = copy(x)
  for k in 1:d # for all directions
    ek = CartesianIndex(ntuple(i  ->  (i==k) ? 1 : 0, d) ) #k th unit vector
    for l in 0:1
      for i in R # iterate over all pixel
        if (i[k] % 2) == l
          I = [i.I...] # array of index
          J = I .+ 1 .* (1:d .== k) #i + e_k is j
          if all( J .<= maxInd ) # is this neighbor in range?
            j = CartesianIndex(J...) # neigbbor index as Cartesian Index
            (y[i],y[j]) = proxTV( M.manifold,λ,(y[i],y[j]),p) # Compute TV on these
          end
        end
      end # i in R
    end # even odd
  end # directions
  return y
end
@doc doc"""
    ξ = proxParallelTV(M,λ,x [,p=1])

compute the proximal maps $\operatorname{prox}_{\lambda\varphi}$ of
all forward differences orrucirng in the power manifold array, i.e.
$\varphi(xi,xj) = d_{\mathcal M}^p(xi,xj)$ with `xi` and `xj` are array
elemets of `x` and `j = i+e_k`, where `e_k` is the $k$th unitvector.
The parameter `λ` is the prox parameter.

# Input
* `M`     – a [`Power`](@ref) manifold
* `λ`     – a real value, parameter of the proximal map
* `x`     – a [`PowPoint`](@ref).

# Optional
(default is given in brackets)
* `p` – (`1`) exponent of the distance of the TV term

# Ouput
* `y`  – resulting of Array [`PowPoint`](@ref)s with all mentioned proximal
  points evaluated (in a parallel within the arrays elements).

*See also* [`proxTV`](@ref)
"""
function proxParallelTV(M::Power, λ::Number, x::Array{PowPoint{P,N},1}, p::Int=1)::Array{PowPoint{P,N},1} where {P <: MPoint, N}
  R = CartesianIndices(getValue(x[1]))
  d = ndims(getValue(x[1]))
  if length(x) != 2*d
    throw(ErrorException("The number of inputs from the array ($(length(x))) has to be twice the data dimensions ($(d))."))
  end
  maxInd = Tuple(last(R))
  # create an array for even/odd splitted proxes along every dimension
  y = reshape(deepcopy(x),d,2)
  x = reshape(x,d,2)
  for k in 1:d # for all directions
    ek = CartesianIndex(ntuple(i  ->  (i==k) ? 1 : 0, d) ) #k th unit vector
    for l in 0:1 # even odd
      for i in R # iterate over all pixel
        if (i[k] % 2) == l
          I = [i.I...] # array of index
          J = I .+ 1 .* (1:d .== k) #i + e_k is j
          if all( J .<= maxInd ) # is this neighbor in range?
            j = CartesianIndex(J...) # neigbbor index as Cartesian Index
            # parallel means we apply each (direction even/odd) to a seperate copy of the data.
            (y[k,l+1][i],y[k,l+1][j]) = proxTV( M.manifold,λ,(x[k,l+1][i],x[k,l+1][j]),p) # Compute TV on these
          end
        end
      end # i in R
    end # even odd
  end # directions
  return y[:] # return as onedimensional array
end
@doc doc"""
    (y1,y2,y3) = proxTV2(M,λ,(x1,x2,x3),[p=1], kwargs...)

Compute the proximal map $\operatorname{prox}_{\lambda\varphi}$ of
$\varphi(x_1,x_2,x_3) = d_{\mathcal M}^p(c(x_1,x_3),x_2)$ with
parameter `λ`>0, where $c(x,z)$ denotes the mid point of a shortest
geodesic from `x1` to `x3` that is closest to `x2`.

# Input

* `M`          – a manifold
* `λ`          – a real value, parameter of the proximal map
* `(x1,x2,x3)` – a tuple of three [`MPoint`](@ref)s

* `p` – (`1`) exponent of the distance of the TV term

# Optional
`kwargs...` – parameters for the internal [`subGradientMethod`](@ref)
    (if `M` is neither `Euclidean` nor `Circle`, since for these a closed form
    is given)

# Output
* `(y1,y2,y3)` – resulting tuple of [`MPoint`](@ref)s of the proximal map
"""
function proxTV2(M::mT,λ,pointTuple::Tuple{P,P,P},p::Int=1;
  stoppingCriterion::StoppingCriterion = stopAfterIteration(5),
  kwargs...)::Tuple{P,P,P} where {mT <: Manifold, P <: MPoint}
  if p != 1
    throw(ErrorException(
      "Proximal Map of TV2(M,λ,pT,p) not implemented for p=$(p) (requires p=1) on general manifolds."
    ))
  end
  PowX = PowPoint([pointTuple...])
  PowM = Power(M,(3,))
  xInit = PowX
  F(x) = 1/2*distance(PowM,PowX,x)^2 + λ*costTV2(PowM,x)
  ∂F(x) = log(PowM,x,PowX) + λ*gradTV2(PowM,x)
  xR = subGradientMethod(PowM,F,∂F,xInit;stoppingCriterion=stoppingCriterion, kwargs...)
  return (getValue(xR)...,)
end
function proxTV2(M::Circle,λ,pointTuple::Tuple{S1Point,S1Point,S1Point},p::Int=1)::Tuple{S1Point,S1Point,S1Point}
  w = [1., -2. ,1. ]
  x = [getValue.(pointTuple)...]
  if p==1 # Theorem 3.5 in Bergmann, Laus, Steidl, Weinmann, 2014.
    m = min(   λ, abs(  symRem( sum( x .* w  ) )  )/(dot(w,w))   )
    s = sign( symRem(sum(x .* w)) )
    return Tuple( S1Point.( symRem.( x  .-  m .* s .* w ) ) )
  elseif p==2 # Theorem 3.6 ibd.
    t = λ * symRem( sum( x .* w ) ) / (1 + λ*dot(w,w) )
    return Tuple(  S1Point.( symRem.( x - t.*w ) )  )
  else
    throw(ErrorException(
      "Proximal Map of TV2(Circle,λ,pT,p) not implemented for p=$(p) (requires p=1 or 2)"
    ))
  end
end
function proxTV2(M::Euclidean,λ,pointTuple::Tuple{RnPoint,RnPoint,RnPoint},p::Int=1)::Tuple{RnPoint,RnPoint,RnPoint}
  w = [1., -2. ,1. ]
  x = [getValue.(pointTuple)...]
  if p==1 # Example 3.2 in Bergmann, Laus, Steidl, Weinmann, 2014.
    m = min.(Ref(λ),  abs.( x .* w  ) / (dot(w,w))   )
    s = sign.( sum(x .* w) )
    return Tuple( RnPoint.( x  .-  m .* s .* w ) )
  elseif p==2 # Theorem 3.6 ibd.
    t = λ * sum( x .* w ) / (1 + λ*dot(w,w) )
    return Tuple(  RnPoint.( x - t.*w ) )
  else
    throw(ErrorException(
      "Proximal Map of TV2(Euclidean,λ,pT,p) not implemented for p=$(p) (requires p=1 or 2)"
    ))
  end
end
@doc doc"""
    ξ = proxTV2(M,λ,x,[p])

compute the proximal maps $\operatorname{prox}_{\lambda\varphi}$ of
all centered second order differences orrucirng in the power manifold array, i.e.
$\varphi(x_k,x_i,x_j) = d_2(x_k,x_i.x_j)$, where $k,j$ are backward and forward
neighbors (along any dimension in the array of `x`).
The parameter `λ` is the prox parameter.

# Input
* `M` – a [`Manifold`](@ref)
* `λ` – a real value, parameter of the proximal map
* `x` – a [`PowPoint`](@ref).

# Optional
(default is given in brackets)
* `p` – (`1`) exponent of the distance of the TV term

# Ouput
* `y` – resulting of [`PowPoint`](@ref) with all mentioned proximal points
  evaluated (in a cylic order).
"""
function proxTV2(M::Power, λ::Number, x::PowPoint,p::Int=1)::PowPoint
  R = CartesianIndices(M.powerSize)
  d = length(size(x))
  minInd = [first(R).I...]
  maxInd = [last(R).I...]
  y = copy(x)
  for k in 1:d # for all directions
    for l in 0:1
      for i in R # iterate over all pixel
        if (i[k] % 3) == l
          I = [i.I...] # array of index
          JForward = I .+ 1 .* (1:d .== k) #i + e_k
          JBackward = I .+ 1 .* (1:d .== k) # i - e_k
          if all( JForward .<= maxInd ) && all( JBackward .>= minInd)
            jForward = CartesianIndex{d}(JForward...) # neigbbor index as Cartesian Index
            jBackward = CartesianIndex{d}(JForward...) # neigbbor index as Cartesian Index
            (y[jBackward], y[i], y[jForward]) =
              proxTV2( M.manifold, λ, (y[jBackward], y[i], y[jForward]),p) # Compute TV on these
          end
        end # if mod 3
      end # i in R
    end # for mod 3
  end # directions
  return y
end
@doc doc"""
    proxCollaborativeTV(M,λ,x [,p=2,q=1])

compute the prox of the collaborative TV prox for x on the [`Power`](@ref)
manifold, i.e. of the function

```math
F^q(x) = \sum_{i\in\mathcal G}
  \Bigl( \sum_{j\in\mathcal I_i}
    \sum_{k=1^d} \lVert X_{i,j}\rVert_x^p\Bigr)^\frac{q/p},
```

where $\mathcal G$ is the set of indices for $x\in\mathcal M$ and $\mathcal I_i$
is the set of its forward neighbors.
This is adopted from the paper by Duran, Möller, Sbert, Cremers:
_Collaborative Total Variation: A General Framework for Vectorial TV Models_
(arxiv: [1508.01308](https://arxiv.org/abs/1508.01308)), where the most inner
norm is not on a manifold but on a vector space, see their Example 3 for
details.
"""
function proxCollaborativeTV(N::Power,λ::Float64,x::PowPoint,Ξ::PowTVector,p::Float64=2.,q::Float64=1.)
  # Ξ = forwardLogs(M,x)
  if length(size(x)) == 1
    d = 1
    s = 1
    iRep = 1
  else
    d = size(x)[end]
    s = length(size(x))-1
    if s != d
      throw( ErrorException( "the last dimension ($(d)) has to be equal to the number of the previous ones ($(s)) but its not." ))
    end
    iRep = [Integer.(ones(d))...,d]
  end
  if q==1 # Example 3 case 2
    if p==1
      normΞ = norm.(Ref(N.manifold), getValue(x), getValue(Ξ) )
      return PowTVector( max.(normΞ .- λ, 0.) ./ ( (normΞ .== 0) .+ normΞ )  .*  getValue(Ξ) )
    elseif p==2 # Example 3 case 3
      norms = sqrt.( sum( norm.(Ref(N.manifold),getValue(x),getValue(Ξ)).^2, dims=d+1) )
      normΞ = repeat(norms,inner=iRep)
      # if the norm is zero add 1 to avoid division by zero, also then the
      # nominator is already (max(-λ,0) = 0) so it stays zero then
      return PowTVector( max.(normΞ .- λ, 0.) ./ ( (normΞ .== 0) .+ normΞ )  .*  getValue(Ξ) )
    else
      throw( ErrorException("The case p=$p, q=$q is not yet implemented"))
    end
  elseif q==Inf
    if p==2
      norms = sqrt.( sum( norm.(Ref(N.manifold),getValue(x),getValue(Ξ)).^2, dims=d+1) )
      normΞ = repeat(norms,inner=iRep)
    elseif p==1
      norms = sum( norm.(Ref(N.manifold),getValue(x),getValue(Ξ)), dims=d+1)
      normΞ = repeat(norms,inner=iRep)
    elseif p==Inf
      normΞ = norm.(Ref(N.manifold),getValue(x),getValue(Ξ))
    else
      throw( ErrorException("The case p=$p, q=$q is not yet implemented"))
    end
    return PowTVector(
      λ .* getValue(Ξ) ./ max.(Ref(λ), normΞ)
    )
  end # end q
  throw( ErrorException("The case p=$p, q=$q is not yet implemented"))
end
proxCollaborativeTV(N::Power,λ::Float64,x::PowPoint,Ξ::PowTVector,p::Int,q::Float64=1.) = proxCollaborativeTV(N,λ,x,Ξ,Float64(p),q)
proxCollaborativeTV(N::Power,λ::Float64,x::PowPoint,Ξ::PowTVector,p::Float64,q::Int) = proxCollaborativeTV(N,λ,x,Ξ,p,Float64(q))
proxCollaborativeTV(N::Power,λ::Float64,x::PowPoint,Ξ::PowTVector,p::Int,q::Int) = proxCollaborativeTV(N,λ,x,Ξ,Float64(p),Float64(q))


text:
include("src/NeuralNet.jl")

model_1 = NeuralNet.model_1(100,30);

nn = NeuralNet.NeuralNetwork([2,1]);
train_data = NeuralNet.train!(nn, model_1.xtrain, model_1.ytrain, batch_size = 2, epochs = 30, cost_function = NeuralNet.loss().mse);

### Plotting

using Plots

function getPlot_accuracy(train_data)
    the_plot = plot(train_data.accuracy,
             label="Accuracy",
             xlabel="Epochs",
             ylabel="Accuracy as %",
             title="Development of accuracy at each iteration");
    return the_plot
end

function getPlot_cost(train_data)
    the_plot = plot(train_data.costs,
             label="Cost Function",
             xlabel="Epochs",
             ylabel="Cost",
             color="red",
             title="Development of cost at each iteration");
    return the_plot
end

function plot_nn(train_data)
    Plots.plot(getPlot_accuracy(train_data), getPlot_cost(train_data), layout = (2, 1), size = (800, 600))
end

plot_nn(train_data)

## Predicting

NeuralNet.model(nn, [100,500])


text:
module TestInPartNames

using NCBITaxonomy
using Test

@test_throws IDNotFoundInBackbone taxon(1234567890000000000)
@test_throws NameHasMultipleMatches taxon("Reptilia")
@test_throws NameHasMultipleMatches taxon("Mus")
@test_throws NameHasNoDirectMatch taxon("This is not a name")

end


text:
@testset "Coordinate constructor" begin
    coord = Coordinate([1.0, 2.0, 3.0])
    @test isapprox(coord.x, 1.0, atol = 1e-5)
    @test isapprox(coord.y, 2.0, atol = 1e-5)
    @test isapprox(coord.z, 3.0, atol = 1e-5)
end

@testset "operator + for Coordinate" begin
    coord1 = Coordinate([1.0, 2.0, 3.0])
    coord2 = Coordinate([2.0, 3.0, 4.0])
    res = coord1 + coord2
    @test isapprox(res.x, 3.0, atol = 1e-5)
    @test isapprox(res.z, 7.0, atol = 1e-5)
end

@testset "operator - for Coordinate" begin
    coord1 = Coordinate([3.0, 2.0, 1.0])
    coord2 = Coordinate([2.0, 3.0, 4.0])
    res = coord2 - coord1
    @test isapprox(res.x, -1.0, atol = 1e-5)
    @test isapprox(res.z, 3.0, atol = 1e-5)
end

@testset "operator * for Coordinate" begin
    coord1 = Coordinate([1.0, 2.0, 3.0])
    coord2 = Coordinate([2.0, 3.0, 4.0])
    coord_coord_case = coord1 * coord2
    @test isapprox(coord_coord_case, 20.0, atol = 1e-5)
    coord_scholar_case = coord1 * 2.0
    @test isapprox(Array(coord_scholar_case), [2.0, 4.0, 6.0], atol = 1e-5)

end

@testset "operator / for Coordinate" begin
    coord1 = Coordinate([1.0, 2.0, 3.0])
    res = coord1 / 2.0
    @test isapprox(res.x, 0.5, atol = 1e-5)
    @test isapprox(res.z, 1.5, atol = 1e-5)
end

@testset "norm for Coordinate" begin
    coord = Coordinate([1.0, 2.0, 3.0])
    resnorm = norm(coord)
    predicted_val    = sqrt(1.0^2 + 2.0^2 + 3.0^2)
    @test isapprox(resnorm, predicted_val, atol = 1e-5)
end

@testset "broadcast for Coordinate" begin
    coord_a = Coordinate([1.0, 2.0, 3.0])
    coord_b = Coordinate([2.0, 3.0, 4.0])
    coord_c = Coordinate([3.0, 4.0, 5.0])
    coord_d = Coordinate([3.0, 2.0, 1.0])
    coords_vec = [coord_a, coord_b, coord_c]
    @test isapprox(Array((coords_vec .+ coord_d)[3]), [6.0, 6.0, 6.0],    atol = 1e-5)
    @test isapprox(Array((coords_vec .- coord_d)[2]), [-1.0, 1.0, 3.0],   atol = 1e-5)
    @test isapprox(       coords_vec .* coord_d,      [10.0, 16.0, 22.0], atol = 1e-5)
    @test isapprox(Array((coords_vec .* 2.0)[2]),     [4.0, 6.0, 8.0],    atol = 1e-5)
end


text:
module DashVtk
using Dash

const resources_path = realpath(joinpath( @__DIR__, "..", "deps"))
const version = "0.0.9"

include("vtk_algorithm.jl")
include("vtk_calculator.jl")
include("vtk_celldata.jl")
include("vtk_dataarray.jl")
include("vtk_fielddata.jl")
include("vtk_geometryrepresentation.jl")
include("vtk_glyphrepresentation.jl")
include("vtk_imagedata.jl")
include("vtk_mesh.jl")
include("vtk_pointcloudrepresentation.jl")
include("vtk_pointdata.jl")
include("vtk_polydata.jl")
include("vtk_reader.jl")
include("vtk_sharedataset.jl")
include("vtk_slicerepresentation.jl")
include("vtk_view.jl")
include("vtk_volume.jl")
include("vtk_volumecontroller.jl")
include("vtk_volumedatarepresentation.jl")
include("vtk_volumerepresentation.jl")

function __init__()
    DashBase.register_package(
        DashBase.ResourcePkg(
            "dash_vtk",
            resources_path,
            version = version,
            [
                DashBase.Resource(
    relative_package_path = "dash_vtk.min.js",
    external_url = "https://unpkg.com/dash_vtk@0.0.9/dash_vtk/dash_vtk.min.js",
    dynamic = nothing,
    async = nothing,
    type = :js
),
DashBase.Resource(
    relative_package_path = "dash_vtk.min.js.map",
    external_url = "https://unpkg.com/dash_vtk@0.0.9/dash_vtk/dash_vtk.min.js.map",
    dynamic = true,
    async = nothing,
    type = :js
),
DashBase.Resource(
    relative_package_path = "async-ReactVTK.js",
    external_url = "https://unpkg.com/dash_vtk@0.0.9/dash_vtk/async-ReactVTK.js",
    dynamic = nothing,
    async = :true,
    type = :js
),
DashBase.Resource(
    relative_package_path = "async-ReactVTK.js.map",
    external_url = "https://unpkg.com/dash_vtk@0.0.9/dash_vtk/async-ReactVTK.js.map",
    dynamic = true,
    async = nothing,
    type = :js
)
            ]
        )

    )
end
end

max_stars_repo_name: rodrigomologni/dash-vtk

max_issues_repo_name: rodrigomologni/dash-vtk

max_forks_repo_name: rodrigomologni/dash-vtk


text:
using Distributed
addprocs(4)

@everywhere include("inputs/5.txt")

@everywhere function scan_and_remove(polymer::String)::String
    for i in 1:length(polymer)-1
        a = polymer[i]
        b = polymer[i+1]
        if (uppercase(a) == uppercase(b)) &&
            ((isuppercase(a) && !isuppercase(b)) ||
            (!isuppercase(a) && isuppercase(b)))
            # Remove these two
            x = polymer[1:i-1]
            y = polymer[i+2:end]
            return join([x,y])
        end
    end
    return polymer
end

@everywhere function aocreduce(polymer::String)::String
    p2 = scan_and_remove(polymer)
    if length(p2) < length(polymer)
        return aocreduce(p2)
    end
    return p2
end

@everywhere function basetypes(polymer::String)::Set{Char}
    retval = Set()
    for c in polymer
        push!(retval, lowercase(c))
    end
    return retval
end

function part_2(polymer::String)
    bases = join(basetypes(polymer))
    results = @distributed (merge) for c in bases
        p2 = replace(polymer, c => "")
        p3 = replace(p2, uppercase(c) => "")
        reduced = aocreduce(p3)
        Dict(c => length(reduced))
    end
    sorted = sort(collect(results), by=x->x[2])
    return sorted
end

p = aocreduce(polymer)
println(length(p))
println(part_2(polymer))


text:
(results_uc, results_ed) = run_test_sim(TEST_RESULT_DIR)
problem_results = run_test_prob()

@testset "test filter results" begin
    gen = PG.get_generation_data(results_uc, curtailment = false)
    @test length(gen.data) == 7
    @test length(gen.time) == 48

    gen = PG.get_generation_data(
        results_uc,
        variable_keys = [
            PowerSimulations.VariableKey{ActivePowerVariable, ThermalStandard}(""),
            PowerSimulations.VariableKey{ActivePowerVariable, RenewableDispatch}(""),
        ],
        parameter_keys = [
            PowerSimulations.ParameterKey{ActivePowerTimeSeriesParameter, RenewableDispatch}(
                "",
            ),
        ],
        initial_time = Dates.DateTime("2020-01-02T02:00:00"),
        len = 3,
    )
    @test length(gen.data) == 3
    @test length(gen.time) == 3

    load = PG.get_load_data(results_ed)
    @test length(load.data) == 1
    @test length(load.time) == 48
    @test !any(Matrix(PG.no_datetime(load.data[:Load])) .< 0.0)

    load = PG.get_load_data(
        results_ed,
        parameter_keys = [
            PowerSimulations.ParameterKey{ActivePowerTimeSeriesParameter, PowerLoad}(""),
        ],
        initial_time = Dates.DateTime("2020-01-02T02:00:00"),
        len = 3,
    )
    @test length(load.data) == 1
    @test length(load.time) == 3
    @test !any(Matrix(PG.no_datetime(load.data[:Load])) .< 0.0)

    srv = PG.get_service_data(results_ed)
    @test length(srv.data) == 0

    srv = PG.get_service_data(results_uc)
    @test length(srv.data) == 1

    srv = PG.get_service_data(
        results_uc,
        variable_keys = [
            PowerSimulations.VariableKey{
                ActivePowerReserveVariable,
                VariableReserve{ReserveUp},
            }(
                "REG1",
            ),
        ],
        initial_time = Dates.DateTime("2020-01-02T02:00:00"),
        len = 5,
    )
    @test length(srv.data) == 1
    @test length(srv.time) == 5
end

@testset "test curtailment calculations" begin
    curtailment_params = PG._curtailment_parameters(
        PG.get_generation_parameter_keys(results_uc),
        PG.get_generation_variable_keys(results_uc),
    )
    @test length(curtailment_params) == 1

    curtailment_params = PG._curtailment_parameters(
        PG.get_generation_parameter_keys(problem_results),
        PG.get_generation_variable_keys(problem_results),
    )
    @test length(curtailment_params) == 1
end

@testset "test data aggregation" begin
    gen = PG.get_generation_data(results_uc)

    cat = PG.make_fuel_dictionary(results_uc.system)
    @test isempty(
        symdiff(
            keys(cat),
            ["Coal", "Wind", "Hydropower", "NG-CC", "NG-CT", "Storage", "PV", "Load"],
        ),
    )

    fuel = categorize_data(gen.data, cat)
    @test length(fuel) == 8

    fuel_agg = PG.combine_categories(fuel)
    @test size(fuel_agg) == (48, 8)
end

@testset "test html saving" begin
    plot_fuel(
        results_ed,
        set_display = false,
        save = TEST_RESULT_DIR,
        title = "fuel_html_output",
        format = "html",
    )
    @test isfile(joinpath(TEST_RESULT_DIR, "fuel_html_output.html"))
end

max_stars_repo_name: NREL-SIIP/InfrastructureSystemsPlots

max_issues_repo_name: NREL-SIIP/InfrastructureSystemsPlots

max_forks_repo_name: NREL-SIIP/InfrastructureSystemsPlots


text:
# a handler which can take actions when any event occurs on a tween
# typedef void TweenCallbackHandler(int type, BaseTween source);

# TweenCallbacks are used to trigger actions at some specific times.
# They are used in both Tweens and Timelines.
# The moment when the callback is triggered depends on its registered triggers:
#
# * [TweenCallback.begin]: right after the delay (if any)
# * [TweenCallback.start]: at each iteration beginning
# * [TweenCallback.end]: at each iteration ending, before the repeat delay
# * [TweenCallback.complete]: at last END event
# * [TweenCallback.backBegin]: at the beginning of the first backward iteration
# * [TweenCallback.backStart]: at each backward iteration beginning, after the repeat delay
# * [TweenCallback.backEnd]: at each backward iteration ending
# * [TweenCallback.backComplete]: at last BACK_END event
#
# forward :      begin                                   complete
# forward :      start    end      start    end      start    end
# |--------------[XXXXXXXXXX]------[XXXXXXXXXX]------[XXXXXXXXXX]
# backward:      bEnd  bStart      bEnd  bStart      bEnd  bStart
# backward:      bComplete                                 bBegin

const TWEEN_CALLBACK_BEGIN = UInt64(0x01)
const TWEEN_CALLBACK_START = UInt64(0x02)
const TWEEN_CALLBACK_END = UInt64(0x04)
const TWEEN_CALLBACK_COMPLETE = UInt64(0x08)

const TWEEN_CALLBACK_BACK_BEGIN = UInt64(0x10)
const TWEEN_CALLBACK_BACK_START = UInt64(0x20)
const TWEEN_CALLBACK_BACK_END = UInt64(0x40)
const TWEEN_CALLBACK_BACK_COMPLETE = UInt64(0x80)

const TWEEN_CALLBACK_ANY_FORWARD = UInt64(0x0F)
const TWEEN_CALLBACK_ANY_BACKWARD = UInt64(0xF0)
const TWEEN_CALLBACK_ANY = UInt64(0xFF)

max_stars_repo_name: wdevore/Ranger-Julia-SDL

max_issues_repo_name: wdevore/Ranger-Julia-SDL

max_forks_repo_name: wdevore/Ranger-Julia-SDL


text:
using DataDeps
@testset "SFD98 dust maps" begin

    # refebv obtained using http://irsa.ipac.caltech.edu/applications/DUST/
    # and manually inserting the following lines and reading off the values for
    # SFD (1998) reference pixel:
    #
    # 0. 0. gal
    # 90. 0. gal
    # 180. 0. gal
    # 270. 0. gal
    # 5.729577951308233 5.729577951308233 gal
    # 5.729577951308233 -5.729577951308233 gal
    #
    # Note that values are not expected to agree exactly because (1) IRSA
    # seems to not do linear interpolation and (2) IRSA seems to use a
    # resampled map (pixel values reported by IRSA don't seem to match any
    # pixel values in original maps).

    ref_l = [0., π / 2., π, 3π / 2., 0.1, 0.1 ]
    ref_b = [0., 0., 0., 0., 0.1, -0.1]

    refebv = [100.0270,
              2.6185,
              1.4182,
              3.4194,
              0.7949,
              0.5680]

    dustmap = SFD98Map()
    for i = 1:length(refebv)
        @test dustmap(ref_l[i], ref_b[i]) ≈ refebv[i] rtol = 0.02
    end
    # vectorized
    @test dustmap.(ref_l, ref_b) ≈ refebv rtol = 0.02

    # deprecations
    @test_deprecated ebv_galactic(dustmap, ref_l[1], ref_b[1])
    @test_deprecated ebv_galactic(dustmap, ref_l, ref_b)

    @testset "Measurements" begin
        ref_l_m = ref_l .± 0.03
        ref_b_m = ref_b .± 0.01
        output = dustmap.(ref_l_m, ref_b_m)
        @test Measurements.values.(output) ≈ refebv rtol = 0.02
    end

    @testset "Unitful" begin
        ref_l_u = ref_l * u"rad"
        ref_b_u = ref_b * u"rad"
        output = dustmap.(ref_l_u, ref_b_u)
        @test eltype(output) <: Gain
        @test ustrip.(output) ≈ refebv rtol = 0.02
    end
    mapdir = datadep"sfd98_map"
    @test sprint(show, dustmap) == "SFD98Map($mapdir)"
    @test_throws ErrorException SFD98Map(randstring(10))
end


text:
@testset "Print" begin
    buf = IOBuffer()

    print(buf, DNAKmer(""))
    @test String(take!(buf)) == ""

    print(buf, DNAKmer("ACGT"))
    @test String(take!(buf)) == "ACGT"

    print(buf, RNAKmer("ACGU"))
    @test String(take!(buf)) == "ACGU"
end

@testset "Show" begin
    buf = IOBuffer()

    show(buf, DNAKmer(""))
    @test String(take!(buf)) == "< EMPTY SEQUENCE >"

    show(buf, DNAKmer("AGAGT"))
    @test String(take!(buf)) == "AGAGT"
end


text:
using Statistics
using StatsBase: sample
using EvoTrees: sigmoid, logit

# prepare a dataset
features = rand(10_000) .* 5
X = reshape(features, (size(features)[1], 1))
Y = sin.(features) .* 0.5 .+ 0.5
Y = logit(Y) + randn(size(Y))
Y = sigmoid(Y)
𝑖 = collect(1:size(X,1))
seed = 123

# train-eval split
𝑖_sample = sample(𝑖, size(𝑖, 1), replace = false)
train_size = 0.8
𝑖_train = 𝑖_sample[1:floor(Int, train_size * size(𝑖, 1))]
𝑖_eval = 𝑖_sample[floor(Int, train_size * size(𝑖, 1))+1:end]

X_train, X_eval = X[𝑖_train, :], X[𝑖_eval, :]
Y_train, Y_eval = Y[𝑖_train], Y[𝑖_eval]

# linear
params1 = EvoTreeRegressor(
    loss=:linear, metric=:mae,
    nrounds=100, nbins=100,
    λ = 0.5, γ=0.1, η=0.05,
    max_depth = 6, min_weight = 1.0,
    rowsample=0.5, colsample=1.0, seed = seed)
model = fit_evotree(params1, X_train, Y_train, X_eval = X_eval, Y_eval = Y_eval, print_every_n = 25)
pred_train_linear = predict(model, X_train)

p1 = EvoTrees.predict(model, X_eval)
mean(abs.(p1 - Y_eval))

# logistic / cross-entropy
params1 = EvoTreeRegressor(
    loss=:logistic, metric=:logloss,
    nrounds=100,
    λ = 0.5, γ=0.1, η=0.05,
    max_depth = 6, min_weight = 1.0,
    rowsample=0.5, colsample=1.0, seed = seed)
model = fit_evotree(params1, X_train, Y_train, X_eval = X_eval, Y_eval = Y_eval, print_every_n = 25)
pred_train_logistic = predict(model, X_train)

# Poisson
params1 = EvoTreeCount(
    loss=:poisson, metric=:poisson,
    nrounds=100,
    λ = 0.5, γ=0.1, η=0.05,
    max_depth = 6, min_weight = 1.0,
    rowsample=0.5, colsample=1.0, seed = seed)
model = fit_evotree(params1, X_train, Y_train, X_eval = X_eval, Y_eval = Y_eval, print_every_n = 25)
pred_train_poisson = predict(model, X_train)

# L1
params1 = EvoTreeRegressor(
    loss=:L1, α=0.5, metric=:mae,
    nrounds=100, nbins=100,
    λ = 0.5, γ=0.0, η=0.05,
    max_depth = 6, min_weight = 1.0,
    rowsample=0.5, colsample=1.0, seed = seed)
model = fit_evotree(params1, X_train, Y_train, X_eval = X_eval, Y_eval = Y_eval, print_every_n = 25)
pred_train_L1 = predict(model, X_train)

# Quantiles
params1 = EvoTreeRegressor(
    loss=:quantile, α=0.5, metric = :quantile,
    nrounds=100, nbins=100,
    λ = 0.5, γ=0.0, η=0.05,
    max_depth = 6, min_weight = 1.0,
    rowsample=0.5, colsample=1.0, seed = seed)
model = fit_evotree(params1, X_train, Y_train, X_eval = X_eval, Y_eval = Y_eval, print_every_n = 25)
pred_train_poisson = predict(model, X_train)

# Gaussian
params1 = EvoTreeGaussian(
    loss=:gaussian, α=0.5, metric = :gaussian,
    nrounds=100, nbins=100,
    λ = 0.0, γ=0.0, η=0.05,
    max_depth = 6, min_weight = 10.0,
    rowsample=0.5, colsample=1.0, seed = seed)
model = fit_evotree(params1, X_train, Y_train, X_eval = X_eval, Y_eval = Y_eval, print_every_n = 25)
pred_train_gaussian = predict(model, X_train)

features_gain = importance(model, 1:1)


text:
include("helper.jl")
include("minitest.jl")
Minitest.do_tests() do

end


text:
using Clapeyron, Test, Unitful

@testset "SAFT methods, single components" begin
    system = PCSAFT(["ethanol"])
    p = 1e5
    T = 298.15
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 5.907908736304141e-5 rtol = 1e-6
        @test Clapeyron.volume(system, p, T;phase=:v) ≈ 0.020427920501436134 rtol = 1e-6
        @test Clapeyron.volume(system, p, T;threaded=:false) ≈ 5.907908736304141e-5 rtol = 1e-6
        @test Clapeyron.pip(system, 5.907908736304141e-5, T, [1.]) ≈ 6.857076349623449 rtol = 1e-6
        @test Clapeyron.compressibility_factor(system, p, T) ≈ 0.002383223535444557 rtol = 1e-6
        @test Clapeyron.pressure(system, 5.907908736304141e-5, T) ≈ p rtol = 1e-6
        @test Clapeyron.entropy(system, p, T) ≈ -58.87118569239617 rtol = 1E-6
        @test Clapeyron.chemical_potential(system, p, T)[1] ≈ -18323.877542682934 rtol = 1E-6
        @test Clapeyron.internal_energy(system, p, T) ≈ 2.9796670214913704e7 rtol = 1E-6
        @test Clapeyron.enthalpy(system, p, T) ≈ -35876.32155687084 rtol = 1E-6
        @test Clapeyron.gibbs_free_energy(system, p, T) ≈ -18323.87754268292 rtol = 1E-6
        @test Clapeyron.helmholtz_free_energy(system, p, T) ≈ -18329.785451419295 rtol = 1E-6
        @test Clapeyron.isochoric_heat_capacity(system, p, T) ≈ 48.37961296309505 rtol = 1E-6
        @test Clapeyron.isobaric_heat_capacity(system, p, T) ≈ 66.45719988319257 rtol = 1E-6
        @test Clapeyron.isothermal_compressibility(system, p, T) ≈ 1.1521981407243432e-9 rtol = 1E-6
        @test Clapeyron.isentropic_compressibility(system, p, T) ≈ 8.387789464951438e-10 rtol = 1E-6
        @test Clapeyron.speed_of_sound(system, p, T) ≈ 1236.4846683094133 rtol = 1E-6 #requires that the model has Mr
        @test Clapeyron.isobaric_expansivity(system, p, T) ≈ -0.0010874255138433413 rtol = 1E-6
        @test Clapeyron.joule_thomson_coefficient(system, p, T) ≈ -6.007581864883784e-7 rtol = 1E-6
        @test Clapeyron.second_virial_coefficient(system, T) ≈ -0.004883874325089262 rtol = 1E-6
        @test Clapeyron.inversion_temperature(system, 1.1e8) ≈ 824.4137805298458 rtol = 1E-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T)[1] ≈ 7972.550405922014 rtol = 1E-6
        @test Clapeyron.enthalpy_vap(system, T) ≈ 41712.78521121877 rtol = 1E-6
        @test Clapeyron.acentric_factor(system) ≈ 0.5730309964718605 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 533.1324329774004 rtol = 1E-6
    end
end

@testset "LJSAFT methods, single components" begin
    system = LJSAFT(["ethanol"])
    p = 1e5
    T = 298.15
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 5.8990680856791996e-5 rtol = 1e-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T)[1] ≈ 7933.046853495474 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 533.4350720160273 rtol = 1E-6
    end
end

@testset "BACKSAFT methods, single components" begin
    system = BACKSAFT(["decane"])
    p = 1e5
    T = 298.15
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 0.00015924416586849443 rtol = 1e-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T)[1] ≈ 581.785675150425 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 618.8455740197799 rtol = 1E-6
    end
end

@testset "CPA methods, single components" begin
    system = CPA(["ethanol"])
    p = 1e5
    T = 298.15
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 5.913050998953597e-5 rtol = 1e-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T)[1] ≈ 7923.883649594267 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 539.218257256262 rtol = 1E-6
    end
end

@testset "SAFT-γ Mie methods, single components" begin
    system = SAFTγMie(["ethanol"])
    p = 1e5
    T = 298.15
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 5.753982584153832e-5 rtol = 1e-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T)[1] ≈ 7714.849872968086 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 521.959273608428 rtol = 1E-6
    end
end

@testset "SAFT-VR Mie methods, single components" begin
    system = SAFTVRMie(["methanol"])
    p = 1e5
    T = 298.15
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 4.064466003321247e-5 rtol = 1e-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T)[1] ≈ 16957.625653548406 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 524.1487001618932 rtol = 1E-6
    end
end

@testset "sCKSAFT methods, single component" begin
    system = sCKSAFT(["ethane"])
    tc_test,pc_test,vc_test = (321.00584034360014, 6.206975436514129e6, 0.0001515067748592245)
    tc,pc,vc = Clapeyron.crit_pure(system)
    @test tc ≈ tc_test rtol = 1E-3
    @test pc ≈ pc_test rtol = 1E-3
    @test vc ≈ vc_test rtol = 1E-3
end

@testset "SAFT methods, multi-components" begin
    system = PCSAFT(["methanol","cyclohexane"])
    p = 1e5
    T = 313.15
    z = [0.5,0.5]
    z_LLE = [0.27,0.73]
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T, z) ≈ 7.779694485714412e-5 rtol = 1e-6
        @test Clapeyron.speed_of_sound(system, p, T, z) ≈ 1087.0303138908864 rtol = 1E-6
        @test Clapeyron.activity_coefficient(system, p, T, z)[1] ≈ 1.794138454452822 rtol = 1E-6
        @test Clapeyron.fugacity_coefficient(system, p, T, z)[1] ≈ 0.5582931304564298 rtol = 1E-6
    end
    @testset "Equilibrium properties" begin
        @test Clapeyron.bubble_pressure(system,T,z)[1] ≈ 54532.249600937736 rtol = 1E-6
        @test Clapeyron.LLE_pressure(system,T,z_LLE)[1] ≈ 737971.7522006684 rtol = 1E-6
        @test Clapeyron.three_phase(system, T)[1] ≈ 54504.079665621306 rtol = 1E-6
        @test Clapeyron.crit_mix(system,z)[1] ≈ 518.0004062881115 rtol = 1E-6
    end
end

@testset "Cubic methods, single components" begin
    system = RK(["ethane"])
    p = 1e7
    p2 = 1e5
    T = 250.15
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 6.819297582048736e-5 rtol = 1e-6
        @test Clapeyron.volume(system, p2, T) ≈ 0.020539807199804024 rtol = 1e-6
        @test Clapeyron.volume(system, p2, T;phase=:vapour) ≈ 0.020539807199804024 rtol = 1e-6
        @test Clapeyron.volume(system, p2, T;phase=:liquid) ≈ 7.563111462588624e-5 rtol = 1e-6
        @test Clapeyron.speed_of_sound(system, p, T) ≈ 800.288303407983 rtol = 1e-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T)[1] ≈ 1.409820798879772e6 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 305.31999999999994 rtol = 1E-6
    end
end

@testset "Cubic methods, multi-components" begin
    system = RK(["ethane","undecane"])
    p = 1e7
    T = 298.15
    z = [0.5,0.5]
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T, z) ≈ 0.00017378014541520907 rtol = 1e-6
        @test Clapeyron.speed_of_sound(system, p, T, z) ≈ 892.4941848133369 rtol = 1e-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.bubble_pressure(system, T, z)[1] ≈ 1.5760730143760687e6 rtol = 1E-6
        @test Clapeyron.crit_mix(system, z)[1] ≈ 575.622237585033 rtol = 1E-6
    end
end

@testset "Activity methods, multi-components" begin
    system = Wilson(["methanol","benzene"])
    p = 1e7
    T = 298.15
    z = [0.5,0.5]
    @testset "VLE properties" begin
        @test Clapeyron.bubble_pressure(system, T, z)[1] ≈ 23758.647133460465 rtol = 1E-6
    end
end

@testset "GERG2008 methods, single components" begin
    system = GERG2008(["water"])
    p = 1e5
    T = 298.15
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 1.8067969591040684e-5 rtol = 1e-6
        @test Clapeyron.speed_of_sound(system, p, T) ≈ 1484.0034692716843 rtol = 1e-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T)[1] ≈ 3184.83242429761 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 647.0960000000457 rtol = 1E-6
    end
end

@testset "GERG2008 methods, multi-components" begin
    @testset "Bulk properties" begin
        model = Clapeyron.GERG2008(["nitrogen","methane","ethane","propane","butane","isobutane","pentane"])
        lng_composition = [0.93,92.1,4.64,1.7,0.42,0.32,0.09]
        lng_composition_molar_fractions = lng_composition ./sum(lng_composition)
        @test Clapeyron.molar_density(model,(380.5+101.3)*1000.0,-153.0+273.15,lng_composition_molar_fractions)/1000 ≈ 24.98 rtol = 1E-2
        @test Clapeyron.mass_density(model,(380.5+101.3)*1000.0,-153.0+273.15,lng_composition_molar_fractions) ≈ 440.73 rtol = 1E-2
        @test Clapeyron.molar_density(model,(380.5+101.3)u"kPa",-153.0u"°C",lng_composition_molar_fractions;output=u"mol/L") ≈ 24.98*u"mol/L"  rtol=1E-2
        @test Clapeyron.mass_density(model,(380.5+101.3)u"kPa",-153.0u"°C",lng_composition_molar_fractions;output=u"kg/m^3")  ≈ 440.73*u"kg/m^3" rtol=1E-2
    end
    @testset "VLE properties" begin
        system = GERG2008(["carbon dioxide","water"])
        T = 298.15
        z = [0.8,0.2]
        @test Clapeyron.bubble_pressure(system, T,z)[1] ≈ 5.853909891112583e6 rtol = 1E-6
    end
end

@testset "IAPWS95 methods" begin
    system = IAPWS95()
    p = 1e5
    T = 298.15
    T_v = 380.15
    T_c = 750.
    p_c = 250e5
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 1.8068623941501927e-5 rtol = 1e-6
        @test Clapeyron.volume(system, p, T_v;phase=:vapour) ≈ 0.03116877990373624 rtol = 1e-6
        @test Clapeyron.volume(system, p_c, T_c) ≈ 0.00018553711945962424 rtol = 1e-6
        @test Clapeyron.volume(system, p_c, T_c;phase=:sc) ≈ 0.00018553711945962424 rtol = 1e-6
        @test Clapeyron.speed_of_sound(system, p, T) ≈ 1496.699163371358 rtol = 1e-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T)[1] ≈ 3169.9293390134403 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 647.096 rtol = 1E-5
    end
end

@testset "PropaneRef methods" begin
    system = PropaneRef()
    p = 1e5
    T = 230.15
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 7.577761282115866e-5 rtol = 1e-6
        @test Clapeyron.volume(system, p, T;phase=:vapour) ≈ 0.018421882342664616 rtol = 1e-6
        @test Clapeyron.speed_of_sound(system, p, T) ≈ 1166.6704395959607 rtol = 1e-6
    end
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T)[1] ≈ 97424.11102152328 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 369.8900089509652 rtol = 1E-6
    end
end

@testset "SPUNG methods" begin
    system = SPUNG(["ethane"])
    p = 1e5
    T = 313.15
    @testset "Bulk properties" begin
        @test Clapeyron.volume(system, p, T) ≈ 0.035641472902311774 rtol = 1e-6
        @test Clapeyron.volume(system, p, T;phase=:vapour) ≈ 0.035641472902311774 rtol = 1e-6
        @test Clapeyron.speed_of_sound(system, p, T) ≈ 357.8705332163255 rtol = 1e-6
    end

    T_sat = 250.15
    @testset "VLE properties" begin
        @test Clapeyron.sat_pure(system, T_sat)[1] ≈ 3.5120264571020138e6 rtol = 1E-6
        @test Clapeyron.crit_pure(system)[1] ≈ 270.27247485012657 rtol = 1E-6
    end
end


text:
# Autogenerated wrapper script for MbedTLS_jll for x86_64-apple-darwin
export libmbedcrypto, libmbedtls, libmbedx509

JLLWrappers.@generate_wrapper_header("MbedTLS")
JLLWrappers.@declare_library_product(libmbedcrypto, "@rpath/libmbedcrypto.7.dylib")
JLLWrappers.@declare_library_product(libmbedtls, "@rpath/libmbedtls.13.dylib")
JLLWrappers.@declare_library_product(libmbedx509, "@rpath/libmbedx509.1.dylib")
function __init__()
    JLLWrappers.@generate_init_header()
    JLLWrappers.@init_library_product(
        libmbedcrypto,
        "lib/libmbedcrypto.2.27.0.dylib",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@init_library_product(
        libmbedtls,
        "lib/libmbedtls.13.dylib",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@init_library_product(
        libmbedx509,
        "lib/libmbedx509.1.dylib",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()