text:
using LinearAlgebra: I, ⋅

@testset "P" begin
    @testset "pckopn/pckw02/pckcls" begin
        try
            pck = tempname()
            handle = pckopn(pck, "Test PCK file", 5000)
            pckw02(handle, 301, "j2000", 0.0, 1.0, "segid", 1.0, [[1.0, 2.0, 3.0]], 0.0)
            pckcls(handle)
        finally
            kclear()
        end
    end
    @testset "pckcov" begin
        try
            ids = SpiceIntCell(1000)
            cover = SpiceDoubleCell(2000)
            pckfrm!(ids, path(EXTRA, :earth_high_per_pck))
            scard!(cover, 0)
            pckcov!(cover, path(EXTRA, :earth_high_per_pck), ids[1])
            expected = [94305664.18380372, 757080064.1838132]
            @test cover ≈ expected
        finally
            kclear()
        end
    end
    @testset "pckfrm" begin
        try
            ids = SpiceIntCell(1000)
            pckfrm!(ids, path(EXTRA, :earth_high_per_pck))
            @test ids[1] == 3000
        finally
            kclear()
        end
    end
    @testset "pcklof" begin
        try
            handle = pcklof(path(EXTRA, :earth_high_per_pck))
            @test handle isa Number
            @test handle != -1
            pckuof(handle)
        finally
            kclear()
        end
        @test_throws SpiceError pcklof("test")
    end
    @testset "pgrrec" begin
        try
            furnsh(path(CORE, :pck))
            radii = bodvrd("MARS", "RADII", 3)
            re = radii[1]
            rp = radii[3]
            f = (re - rp) / re
            rectan = pgrrec("Mars", deg2rad(90.0), deg2rad(45), 300, re, f)
            expected = [1.604650025e-13, -2.620678915e+3, 2.592408909e+3]
            @test rectan ≈ expected
            @test_throws SpiceError pgrrec("norbert", deg2rad(90.0), deg2rad(45), 300, re, f)
            @test_throws SpiceError pgrrec("", deg2rad(90.0), deg2rad(45), 300, re, f)
            @test_throws SpiceError pgrrec("Mars", deg2rad(90.0), deg2rad(45), 300, -re, f)
            @test_throws SpiceError pgrrec("Mars", deg2rad(90.0), deg2rad(45), 300, re, f+1)
        finally
            kclear()
        end
    end
    @testset "phaseq" begin
        relate = ["=", "<", ">", "LOCMIN", "ABSMIN", "LOCMAX", "ABSMAX"]
        expected = Dict(
            "="=> [
                0.575988450,
                0.575988450,
                0.575988450,
                0.575988450,
                0.575988450,
                0.575988450,
                0.575988450,
                0.575988450,
                0.575988450,
                0.575988450,
            ],
            "<"=> [0.575988450, 0.575988450, 0.575988450, 0.575988450, 0.575988450, 0.468279091],
            ">"=> [0.940714974, 0.575988450, 0.575988450, 0.575988450, 0.575988450, 0.575988450],
            "LOCMIN"=> [0.086121423, 0.086121423, 0.079899769, 0.079899769],
            "ABSMIN"=> [0.079899769, 0.079899769],
            "LOCMAX"=> [3.055062862, 3.055062862, 3.074603891, 3.074603891],
            "ABSMAX"=> [3.074603891, 3.074603891],
        )
        try
            furnsh(path(CORE, :lsk), path(CORE, :pck), path(CORE, :spk))
            et0 = str2et("2006 DEC 01")
            et1 = str2et("2007 JAN 31")
            cnfine = SpiceDoubleCell(2)
            wninsd!(cnfine, et0, et1)
            result = SpiceDoubleCell(10000)
            for relation in relate
                result = gfpa("Moon", "Sun", "LT+S", "Earth", relation, 0.57598845, 0.0, spd(), 5000, cnfine)
                count = wncard(result)
                @test count > 0
                if count > 0
                    results = Float64[]
                    for i in 1:count
                        start, stop = wnfetd(result, i)
                        start_phase = phaseq(start, "moon", "sun", "earth", "lt+s")
                        stop_phase = phaseq(stop, "moon", "sun", "earth", "lt+s")
                        push!(results, start_phase)
                        push!(results, stop_phase)
                    end
                    exp = expected[relation]
                    @testset for i in eachindex(results, exp)
                        @test round(results[i], digits=9) ≈ exp[i] atol=1e-6
                    end
                end
            end
            start, stop = wnfetd(result, 1)
            @test_throws SpiceError phaseq(start, "moon", "moon", "moon", "lt+s")
        finally
            kclear()
        end
    end
    @testset "pi" begin
        @test SPICE._pi() ≈ π
    end
    @testset "pjelpl" begin
        cent = [1.0, 1.0, 1.0]
        vec1 = [2.0, 0.0, 0.0]
        vec2 = [0.0, 1.0, 1.0]
        normal = [0.0, 0.0, 1.0]
        plane = nvc2pl(normal, 0.0)
        elin = cgv2el(cent, vec1, vec2)
        ellipse = pjelpl(elin, plane)
        expected_smajor = [2.0, 0.0, 0.0]
        expected_sminor = [0.0, 1.0, 0.0]
        expected_center = [1.0, 1.0, 0.0]
        @test expected_center ≈ center(ellipse)
        @test expected_smajor ≈ semi_major(ellipse)
        @test expected_sminor ≈ semi_minor(ellipse)
    end
    @testset "pl2nvc" begin
        normal = [-1.0, 5.0, -3.5]
        point = [9.0, -0.65, -12.0]
        plane = nvp2pl(normal, point)
        normal, constant = pl2nvc(plane)
        expected_normal = [-0.16169042, 0.80845208, -0.56591646]
        @test constant ≈ 4.8102899
        @test expected_normal ≈ normal
    end
    @testset "pl2nvp" begin
        plane_norm = [2.44, -5.0 / 3.0, 11.0 / 9.0]
        con = 3.141592654
        plane = nvc2pl(plane_norm, con)
        norm_vec, point = pl2nvp(plane)
        expected_point = [0.74966576, -0.51206678, 0.37551564]
        @test expected_point ≈ point
    end
    @testset "pl2psv" begin
        normal = [-1.0, 5.0, -3.5]
        point = [9.0, -0.65, -12.0]
        plane = nvp2pl(normal, point)
        point, span1, span2 = pl2psv(plane)
        @test point ⋅ span1 ≈ 0 atol=sqrt(eps())
        @test point ⋅ span2 ≈ 0 atol=sqrt(eps())
        @test span1 ⋅ span2 ≈ 0 atol=sqrt(eps())
    end
    @testset "pltar" begin
        vrtces = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
        plates = [[1, 4, 3], [1, 2, 4], [1, 3, 2], [2, 3, 4]]
        @test pltar(vrtces, plates) ≈ 2.3660254037844
    end
    @testset "pltexp" begin
        iverts = [[sqrt(3.0) / 2.0, -0.5, 7.0], [0.0, 1.0, 7.0], [-sqrt(3.0) / 2.0, -0.5, 7.0]]
        overts = pltexp(iverts, 1.0)
        expected = [[1.732050807569, -1.0, 7.0], [0.0, 2.0, 7.0], [-1.732050807569, -1.0, 7.0]]
        @test all(expected ≈ overts)
    end
    @testset "pltnp" begin
        point = [2.0, 2.0, 2.0]
        v1 = [1.0, 0.0, 0.0]
        v2 = [0.0, 1.0, 0.0]
        v3 = [0.0, 0.0, 1.0]
        near, distance = pltnp(point, v1, v2, v3)
        @test [1.0/3.0, 1.0/3.0, 1.0/3.0] ≈ near
        @test round(distance, digits=7) ≈ 2.8867513
        @test_throws ArgumentError pltnp(point[1:2], v1, v2, v3)
        @test_throws ArgumentError pltnp(point, v1[1:2], v2, v3)
        @test_throws ArgumentError pltnp(point, v1, v2[1:2], v3)
        @test_throws ArgumentError pltnp(point, v1, v2, v3[1:2])
    end
    @testset "pltnrm" begin
        v1 = [sqrt(3.0) / 2.0, -0.5, 0.0]
        v2 = [0.0, 1.0, 0.0]
        v3 = [-sqrt(3.0) / 2.0, -0.5, 0.0]
        @test [0.0, 0.0, 2.59807621135] ≈ pltnrm(v1, v2, v3)
        @test_throws ArgumentError pltnrm(v1[1:2], v2, v3)
        @test_throws ArgumentError pltnrm(v1, v2[1:2], v3)
        @test_throws ArgumentError pltnrm(v1, v2, v3[1:2])
    end
    @testset "pltvol" begin
        vrtces = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
        plates = [[1, 4, 3], [1, 2, 4], [1, 3, 2], [2, 3, 4]]
        @test pltvol(vrtces, plates) ≈ 1.0 / 6.0
        vrtces1 = [[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [0.0, 0.0]]
        plates1 = [[1, 4], [1, 2], [1, 3], [2, 3]]
        @test_throws ArgumentError pltvol(vrtces1, plates)
        @test_throws ArgumentError pltvol(vrtces, plates1)
    end
    @testset "polyds" begin
        result = polyds([1.0, 3.0, 0.5, 1.0, 0.5, -1.0, 1.0], 3, 1)
        @test result ≈ [6.0, 10.0, 23.0, 78.0]
    end
    @testset "pos" begin
        string = "AN ANT AND AN ELEPHANT        "
        @test SPICE._pos(string, "AN", 1) == 1
        @test SPICE._pos(string, "AN", 3) == 4
        @test SPICE._pos(string, "AN", 6) == 8
        @test SPICE._pos(string, "AN", 10) == 12
        @test SPICE._pos(string, "AN", 14) == 20
        @test SPICE._pos(string, "AN", 22) == -1
        @test SPICE._pos(string, "AN", -6) == 1
        @test SPICE._pos(string, "AN", -1) == 1
        @test SPICE._pos(string, "AN", 31) == -1
        @test SPICE._pos(string, "AN", 44) == -1
        @test SPICE._pos(string, " AN", 1) == 3
        @test SPICE._pos(string, " AN ", 1) == 11
        @test SPICE._pos(string, " AN  ", 1) == -1

        @test first(findnext("AN", string, 1)) == SPICE._pos(string, "AN", 1)
        @test first(findnext("AN", string, 3)) == SPICE._pos(string, "AN", 3)
        @test first(findnext("AN", string, 6)) == SPICE._pos(string, "AN", 6)
        @test first(findnext("AN", string, 10)) == SPICE._pos(string, "AN", 10)
        @test first(findnext(" AN", string, 1)) == SPICE._pos(string, " AN", 1)
        @test first(findnext(" AN ", string, 1)) == SPICE._pos(string, " AN ", 1)
    end
    @testset "posr" begin
        string = "AN ANT AND AN ELEPHANT        "
        @test SPICE._posr(string, "AN", 30) == 20
        @test SPICE._posr(string, "AN", 19) == 12
        @test SPICE._posr(string, "AN", 11) == 8
        @test SPICE._posr(string, "AN", 7) == 4
        @test SPICE._posr(string, "AN", 3) == 1
        @test SPICE._posr(string, "AN", -6) == -1
        @test SPICE._posr(string, "AN", -1) == -1
        @test SPICE._posr(string, "AN", 31) == 20
        @test SPICE._posr(string, "AN", 44) == 20
        @test SPICE._posr(string, " AN", 30) == 11
        @test SPICE._posr(string, " AN ", 30) == 11
        @test SPICE._posr(string, " AN ", 10) == -1
        @test SPICE._posr(string, " AN  ", 30) == -1

        @test first(findprev("AN", string, 30)) == SPICE._posr(string, "AN", 30)
        @test first(findprev("AN", string, 19)) == SPICE._posr(string, "AN", 19)
        @test first(findprev("AN", string, 11)) == SPICE._posr(string, "AN", 11)
        @test first(findprev("AN", string, 7)) == SPICE._posr(string, "AN", 7)
        @test first(findprev("AN", string, 3)) == SPICE._posr(string, "AN", 3)
        @test first(findprev("AN", string, 31)) == SPICE._posr(string, "AN", 31)
        @test first(findprev("AN", string, 44)) == SPICE._posr(string, "AN", 44)
        @test first(findprev(" AN", string, 30)) == SPICE._posr(string, " AN", 30)
        @test first(findprev(" AN ", string, 30)) == SPICE._posr(string, " AN ", 30)
    end
    @testset "prop2b" begin
        mu = 398600.45
        r = 1.0e8
        speed = sqrt(mu / r)
        t = π * (r / speed)
        pvinit = [0.0, r / sqrt(2.0), r / sqrt(2.0), 0.0, -speed / sqrt(2.0), speed / sqrt(2.0)]
        state = prop2b(mu, pvinit, t)
        @test state ≈ -1.0 * pvinit
        @test_throws SpiceError prop2b(-mu, pvinit, t)
        @test_throws SpiceError prop2b(mu, [pvinit[1:3]; zeros(3)], t)
        @test_throws SpiceError prop2b(mu, [zeros(3); pvinit[4:6]], t)
        @test_throws SpiceError prop2b(mu, [pvinit[4:6] .* 1e3; pvinit[4:6]], t)
    end
    @testset "prsdp" begin
        # What an awful idea!
        @test SPICE._prsdp("-1. 000") == -1.0

        @test parse(Float64, "-1.0") == SPICE._prsdp("-1.0")
    end
    @testset "prsint" begin
        # This is an abomination!
        @test SPICE._prsint("PI") == 3

        @test parse(Int, "-1") == SPICE._prsdp("-1")
    end
    @testset "psv2pl" begin
        try
            epoch = "Jan 1 2005"
            frame = "ECLIPJ2000"
            furnsh(path(CORE, :lsk), path(CORE, :spk))
            et = str2et(epoch)
            state, ltime = spkezr("EARTH", et, frame, "NONE", "SOLAR SYSTEM BARYCENTER")
            es_plane = psv2pl(state[1:3], state[1:3], state[4:6])
            es_norm, es_const = pl2nvc(es_plane)
            mstate, mltime = spkezr("MOON", et, frame, "NONE", "EARTH BARYCENTER")
            em_plane = psv2pl(mstate[1:3], mstate[1:3], mstate[4:6])
            em_norm, em_const = pl2nvc(em_plane)
            @test rad2deg(vsep(es_norm, em_norm)) ≈ 5.0424941
            @test_throws SpiceError psv2pl(mstate[1:3], mstate[1:3], mstate[1:3])
            @test_throws ArgumentError psv2pl(mstate[1:2], mstate[1:3], mstate[4:6])
            @test_throws ArgumentError psv2pl(mstate[1:3], mstate[1:2], mstate[4:6])
            @test_throws ArgumentError psv2pl(mstate[1:3], mstate[1:3], mstate[4:5])
        finally
            kclear()
        end
    end
    @testset "pxform" begin
        try
            furnsh(path(CORE, :lsk), path(CORE, :pck), path(CORE, :spk))
            lon = deg2rad(118.25)
            lat = deg2rad(34.05)
            alt = 0.0
            utc = "January 1, 2005"
            et = str2et(utc)
            abc = bodvrd("EARTH", "RADII", 3)
            equatr = abc[1]
            polar = abc[3]
            f = (equatr - polar) / equatr
            epos = georec(lon, lat, alt, equatr, f)
            rotate = pxform("IAU_EARTH", "J2000", et)
            jstate = rotate' * epos
            expected = [5042.1309421, 1603.52962986, 3549.82398086]
            rot_exp = [-0.18437048 -0.98285670 0.00048614;
                       0.98285681 -0.18437050 -2.71973868E-07;
                       8.98973426E-05 0.00047776 0.99999988]
            @testset for i = eachindex(rotate, rot_exp)
                @test rotate[i] ≈ rot_exp[i] atol=1e-6
            end
            @testset for i = eachindex(jstate, expected)
                @test jstate[i] ≈ expected[i]
            end
            @test pxform("J2000", "J2000", 0.) ≈ Array{Float64}(I, 3, 3)
            @test_throws SpiceError pxform("Norbert", "J2000", 0.0)
        finally
            kclear()
        end
    end
    @testset "pxfrm2" begin
        try
            # load kernels
            furnsh(path(CORE, :lsk),
                   path(CORE, :pck),
                   path(CORE, :spk),
                   path(CASSINI, :pck),
                   path(CASSINI, :sat_spk),
                   path(CASSINI, :tour_spk),
                   path(CASSINI, :fk),
                   path(CASSINI, :ck),
                   path(CASSINI, :sclk),
                   path(CASSINI, :ik))

            # start of test
            etrec = str2et("2013 FEB 25 11:50:00 UTC")
            camid = bodn2c("CASSINI_ISS_NAC")
            shape, obsref, bsight, bounds = getfov(camid, 4)
            # run sincpt on boresight vector
            spoint, etemit, srfvec = sincpt("ELLIPSOID", "ENCELADUS",
                                            etrec, "IAU_ENCELADUS", "CN+S", "CASSINI", obsref, bsight)
            rotate = pxfrm2(obsref, "IAU_ENCELADUS", etrec, etemit)
            # get radii
            radii = bodvrd("ENCELADUS", "RADII", 3)
            # find position of center with respect to MGS
            pcassmr = spoint .- srfvec
            # rotate into IAU_ENCELADUS
            bndvec = rotate * (0.9999 .* bsight .+ 0.0001 .* bounds[2])
            # get surface point
            spoint = surfpt(pcassmr, bndvec, radii[1], radii[2], radii[3])
            @test spoint !== nothing
            if spoint !== nothing
                radius, lon, lat = reclat(spoint)
                lon = rad2deg(lon)
                lat = rad2deg(lat)
                @test radius ≈ 250.14507342586242
                @test lon ≈ 125.42089677611104
                @test lat ≈ -6.3718522103931585
            end
        finally
            kclear()
        end
    end
end


text:
type Box
    data::Vector{Int}
    children::Vector{Box}
end

Box() = Box(Int[], Box[])

"""
T: type of the coordinates
P: type of the points stored in the Octree.
"""
type Octree{T,P}
    center::P
    halfsize::T
    rootbox::Box

    points::Vector{P}
    radii::Vector{T}
    expanding_ratio::Float64 # This will add the expanding ratio of boxes

    splitcount::Int
    minhalfsize::T
end

"""
  boundingbox(v)

Compute the bounding cube/square for a Array of Point. The return values
are the center of the bounding box and the half size of the cube.
"""
function boundingbox{P}(v::Vector{P})
  #P are points values (x,y) in 2D or (x,y,z) in 3D
  ll = minimum(v)
  ur = maximum(v)
  #ll => LowerLeft
  #up => UpperRight
  c = (ll + ur)/2
  s = maximum(ur - c)
  #c => centre
  #s => biggest half width, i.e in 2D distance between points result in a rectangular
  #    (so we pick the bigger value here to form a rectangular later)
  return c, s
end

"""
Predicate used for iteration over an Octree. Returns true if two boxes
specified by their centers and halfsizes overlap. More carefull investigation
of the objects within is required to assess collision. False positives are possible.

    boxesoverlap(c1, hs1, c2, hs2)
"""
function boxesoverlap(c1, hs1, c2, hs2)

    tol = sqrt(eps(typeof(hs1)))
    # Checking the type of the problem domain 2D or 3D? and making sure the boxes are from same domain
    dim = length(c1)
    @assert dim == length(c2)
    #Note: I have fixed the condition, now it works for 3D and 2D
    hs = hs1 + hs2
    for i in 1 : dim
        if abs(c1[i] - c2[i]) > hs + tol
            return false
        end
    end

    return true
end

function Octree{T}(points::Vector, radii::Vector{T}, expanding_ratio=1.0, splitcount = 10,  minhalfsize = zero(T))

    n_points = length(points)
    n_dims = length(eltype(points))

    # compute the bounding box taking into account
    # the radius of the objects to be inserted
    radius =  maximum(radii)

	@assert !isempty(points)
	ll = points[1]
	ur = points[1]
	for i in 2:length(points)
		ll = min.(ll, points[i])
		ur = max.(ur, points[i])
	end

	ll = ll .- radius
	ur = ur .+ radius

    #ll = minimum(points) - radius
    #ur = maximum(points) + radius

    center = (ll + ur) / 2
    halfsize = maximum(ur - center)

    # if the minimal box size is not specified,
    # make a reasonable guess
    if minhalfsize == 0
        #TODO generalise
        minhalfsize = 0.1 * halfsize * (splitcount / n_points)^(1/3)
    end

    # Create an empty octree
    rootbox = Box()
    tree = Octree(center, halfsize, rootbox, points, radii, expanding_ratio, splitcount, minhalfsize)

    # populate
    for id in 1:n_points

        point, radius = points[id], radii[id]
        insert!(tree, tree.rootbox, center, halfsize, point, radius, id)

    end

    return tree

end

"""
  Octree(points)

Insert zero radius objects at positions `points` in an Octree
"""

Octree(points) = Octree(points, zeros(eltype(eltype(points)), length(points)))

"""
    childsector(point, center) -> sector

Computes the sector w.r.t. `center` that contains  point. Sector is an Int
that encodes the position of point along each axis in its bit representation
"""
function childsector(point, center)
  # in Case of 3D the Octant they are numbered as follows (+,+,+)->7, (+,+,-)->3, (+,-,+)->5, (+,-,-)->1
  #(-,+,+)->6, (-,+,-)->2, (-,-,+)->4, (-,-,-)->0
  #For 2D (-,-)->0, (-,+)->1, (+,-)->2, (+,+)->3
	sct = 0
	r = point - center
	for (i,x) in enumerate(r)
		if x > zero(x)
			sct |= (1 << (i-1))
		end
	end

	return sct # because Julia has 1-based indexing
end

isleaf(node) = isempty(node.children)

"""
    fitsinbox(pos, radius, center, halfsize) -> true/fasle

Finds out if the object with position (pos) and (raduis) fits inside the box.
It uses the box dimension (centre, and halfsize(w/2)) to do the comparsion
"""
function fitsinbox(pos, radius, center, halfsize)

	for i in 1:length(pos)
		(pos[i] - radius < center[i] - halfsize) && return false
		(pos[i] + radius > center[i] + halfsize) && return false
	end
# the code judege by comapring with the box lower left point and uper right point
	return true
end
"""
  itsinbox(Opj_c, Obj_rad, box_c, box_hf, ratio) -> true/fasle

  Finds out if the object with center position (Opj_c) and (Obj_rad) fits inside the box.
  It uses the box dimension (box_c, and box_hf(w/2)) to do the comparsion
  ratio is relative to box half width, so if you want to be just within the box
  then ratio =1, if the boundaries of the object is slightly bigger and you still
  want to include them make ratio bigger ex:1.2
"""
function fitsinbox(Opj_c, Obj_rad, box_c, box_hf, ratio)
  for i in 1:length(Opj_c)
		(Opj_c[i] - Obj_rad < box_c[i] - (box_hf*ratio)) && return false
		(Opj_c[i] + Obj_rad > box_c[i] + (box_hf*ratio)) && return false
	end
# the code judege by comapring with the box lower left point and uper right point
	return true

end

"""
  childcentersize(center, halfsize, sector) -> center, halfsize

Computes the center and halfsize of the child of the input box
that resides in octant `sector`
"""
@generated function childcentersize(center, halfsize, sector)
  D = length(center)
  xp1 = :(halfsize = halfsize / 2)
  xp2 = Expr(:call, center)
  for d in 1:D
    push!(xp2.args, :(center[$d] + (sector & (1 << $(d-1)) == 0 ? -halfsize : +halfsize)))
  end
  xp = quote
    $xp1
    return $xp2, halfsize
  end
  #@show xp
  #xp
end

"""
insert!(tree, box, center, halfsize, point, radius, id)

tree:     the tree in which to insert
box:      the box in which to try insertion
center:   center of the box
halfsize: 0.5 times the length of the box side
point:    the point at which to insert
radius:   the radius of the item to insert
id:       a unique id that identifies the inserted item uniquely
"""
function insert!{P,T}(tree, box, center::P, halfsize::T, point::P, radius::T, id)

    # if not saturated: insert here
    # if saturated and not internal : create children and redistribute
    # if saturated and internal and not fat: insert!(childbox,...)
    # if saturated and internal and fat: insert here
    # also if not saturated but there are non empty internal boxes try to insert there not here

    # or shorter:

    # sat & not internal: create children and redistibute
    # sat & internal & not fat: insert in childbox
    # all other cases: insert here
    # Will find out first if we are solveing octree or quadtree 3D/2D
    dim = length(P)
    nch = 2^dim
    expanding_ratio=tree.expanding_ratio

    saturated = (length(box.data) + 1) > tree.splitcount
    fat       = !fitsinbox(point, radius, center, halfsize,expanding_ratio) # we test if the point is within the box and the expanswion if there is any
    internal  = !isleaf(box)

    if (!internal && !saturated) || (saturated && internal && fat)
        # this will only insert in top level in two cases
        # 1) the object is fat anyway
        # 2) there is no child boxes and still there is a place in this box ( it is not saturated)
        push!(box.data, id)

    elseif internal && !fat
        # now if the box has a space or not but it has a childern try to insert in the child not here
        sct = childsector(point, center)
        chdbox = box.children[sct+1]
        chdcenter, chdhalfsize = childcentersize(center, halfsize, sct)
        if fitsinbox(point, radius, chdcenter, chdhalfsize,expanding_ratio) # check if it is fat and please consider the expansion
          insert!(tree, chdbox, chdcenter, chdhalfsize, point, radius, id)
        else
          push!(box.data, id)
        end

    else # saturated && not internal

        # if their was a previous attempt to subdivide this box,

        # insert the new element in this box for now as we will sort them after we create childrens
        push!(box.data, id)

        # if we are not allowed to subdivide any further stop. This will
        # avoid the contruction of a tree with N levels when N equal points
        # are inserted.
        if halfsize/2 < tree.minhalfsize
            return
        end

        # Create an array of childboxes
        box.children = Array{Box}(nch)
        for i in 1:nch
            box.children[i] = Box(Int[], Box[])
        end

        # subdivide:
        # for every id in this box
        #   find the correspdoning child sector
        #   if it fits in the child box, insert
        #   if not, add to the list of unmovables
        # replace the current box data with the list of unmovables

        unmovables = Int[]
        for id in box.data

            point = tree.points[id]
            radius = tree.radii[id]

            sct = childsector(point, center)
            chdbox = box.children[sct+1]
            chdcenter, chdhalfsize = childcentersize(center, halfsize, sct)
            if fitsinbox(point, radius, chdcenter, chdhalfsize,expanding_ratio)# # check if it is fat for the child and please consider the expansion
                push!(chdbox.data, id)
            else
                push!(unmovables, id)
            end

        end

        box.data = unmovables

    end

end

import Base.length
function length(tree::Octree)

    # Traversal order:
    #   data in the box
    #   data in all children
    #   data in the sibilings
    level = 0

    box = tree.rootbox
    sz = length(box.data)

    box_stack = [tree.rootbox]
    sct_stack = [1]

    sz = -0

    box = tree.rootbox
    sct = 0

    box_stack = Box[]
    sct_stack = Int[]

    while true

        # if this is the first time the box is visited, count the data
        if sct == 0
            sz += length(box.data)
            if length(box.data) != 0
                println("Adding ", length(box.data), " contributions at level: ", level)
            end
        end

        # if this box has unprocessed children
        # push this box on the stack and process the children
        if sct < length(box.children)
            push!(box_stack, box)
            push!(sct_stack, sct+1)
            level += 1

            box = box.children[sct+1]
            sct = 0

            continue
        end

        # if box and its children are processed,
        # and their is no parent above this box:
        # end the traversal:
        if isempty(box_stack)
            break
        end

        # if either no children or all children processed:
        # move up one level
        box = pop!(box_stack)
        sct = pop!(sct_stack)
        level -= 1

    end

    return sz

end

type BoxIterator{T,P,F}
    predicate::F
    tree::Octree{T,P}
end

type BoxIteratorStage{T,P}
    box::Box
    sct::Int
    center::P
    halfsize::T
end

boxes(tree::Octree, pred = (ctr,hsz)->true) = BoxIterator(pred, tree)

import Base: start, next, done
function start(bi::BoxIterator)

    pred     = bi.predicate
    center   = bi.tree.center
    halfsize = bi.tree.halfsize

    state = [ BoxIteratorStage(
        bi.tree.rootbox, 0, center, halfsize
    ) ]

    # If the rootbox does not satisfy the predicate,
    # fast forward to the next eligible box
    # take care of this deeply annoying corner case:
    if !pred(center, halfsize)
        box, state = next(bi, state)
    end

    return state

end

function next(bi::BoxIterator, state)

    item = last(state).box.data

    box = last(state).box   # current box
    sct = last(state).sct   # next child to visit
    hsz = last(state).halfsize
    ctr = last(state).center

    while true

        # scan for a next child box that meets the criterium
        childbox_found = false
        while sct < length(box.children)
            chd_ctr, chd_hsz = childcentersize(ctr, hsz, sct)
            if bi.predicate(chd_ctr, chd_hsz)
                childbox_found = true
                break
            end
            sct += 1
        end

        if childbox_found

            # if this box has unvisited children, increment
            # the next child sct counter and move down the tree
            last(state).sct = sct + 1
            ctr, hsz = childcentersize(ctr, hsz, sct)
            stage = BoxIteratorStage(box.children[sct+1], 0, ctr, hsz)
            push!(state, stage)

        else

            pop!(state)

        end

        # if we popped the root, we're finished
        if isempty(state)
            break
        end

        box = last(state).box
        sct = last(state).sct
        hsz = last(state).halfsize
        ctr = last(state).center

        # only stop the iteration when a new box is found
        # and if that box is non-empty
        # (sct == 0) implies that this is the first visit
        if sct == 0 && !isempty(box.data)
            break
        end

    end

    return item, state
end

done(bi::BoxIterator, state) = isempty(state)

import Base.find

"""
    find(octree, pos, tolerance=sqrt(eps(eltype(pos))))

Return an array containing the indices of values at `pos` (up to a tolerance)
"""
function find(tr::Octree, v; tol = sqrt(eps(eltype(v))))

    pred = (c,s) -> fitsinbox(v, 0.0, c, s)# i didn't change it because find will get the point anyway, it only chck for its existance
    I = Int[]
    for b in boxes(tr, pred)
      for i in b
        if norm(tr.points[i] - v) < tol
          push!(I, i)
        end
      end
    end

    return I

end

ext: jl

max_stars_repo_name: shakisparki/CollisionDetection

max_issues_repo_name: shakisparki/CollisionDetection

max_forks_repo_name: shakisparki/CollisionDetection


text:
module M0_1
function f(q::Vector{T}, q_dot::Vector{T}, xi::T) where T
    l1 = q[1]
    l2 = q[2]
    l3 = q[3]
    l1_dot = q_dot[1]
    l2_dot = q_dot[2]
    l3_dot = q_dot[3]

    -2.67167722233334e+17*l1.^18 + 2.73392656696369e+18*l1.^17.*l2 + 1.92897054519174e+18*l1.^17.*l3 - 2.19182832066861e+16*l1.^17 - 1.45432786330216e+19*l1.^16.*l2.^2 - 1.61381303512517e+19*l1.^16.*l2.*l3 + 1.87809603163173e+17*l1.^16.*l2 - 7.94325636050451e+18*l1.^16.*l3.^2 + 1.15178429399841e+17*l1.^16.*l3 - 1.23494057378614e+16*l1.^16 + 5.27349412587774e+19*l1.^15.*l2.^3 + 6.90209566581104e+19*l1.^15.*l2.^2.*l3 - 8.20001654085433e+17*l1.^15.*l2.^2 + 5.77346754029511e+19*l1.^15.*l2.*l3.^2 - 7.04823224685592e+17*l1.^15.*l2.*l3 + 1.22694111718278e+17*l1.^15.*l2 + 2.23589262858673e+19*l1.^15.*l3.^3 - 3.42097126127885e+17*l1.^15.*l3.^2 + 7.83253529924195e+16*l1.^15.*l3 + 514345935737395.0*l1.^15 - 1.44293197226472e+20*l1.^14.*l2.^4 - 1.97932639584095e+20*l1.^14.*l2.^3.*l3 + 2.38780355875192e+18*l1.^14.*l2.^3 - 2.14397615727157e+20*l1.^14.*l2.^2.*l3.^2 + 1.90817994975855e+18*l1.^14.*l2.^2.*l3 - 6.32851447039082e+17*l1.^14.*l2.^2 - 1.42062799779999e+20*l1.^14.*l2.*l3.^3 + 1.65547503749323e+18*l1.^14.*l2.*l3.^2 - 6.00581940887649e+17*l1.^14.*l2.*l3 - 3.8809738787458e+15*l1.^14.*l2 - 4.73332066262277e+19*l1.^14.*l3.^4 + 5.98240200464844e+17*l1.^14.*l3.^3 - 2.94430177907812e+17*l1.^14.*l3.^2 - 2.18430027254712e+15*l1.^14.*l3 + 230711649643284.0*l1.^14 + 3.14442254811672e+20*l1.^13.*l2.^5 + 4.14159386919363e+20*l1.^13.*l2.^4.*l3 - 5.0601150289318e+18*l1.^13.*l2.^4 + 5.48866429956099e+20*l1.^13.*l2.^3.*l3.^2 - 2.50298198815176e+18*l1.^13.*l2.^3.*l3 + 2.21242248965811e+18*l1.^13.*l2.^3 + 4.44916979110224e+20*l1.^13.*l2.^2.*l3.^3 - 3.03245894718386e+18*l1.^13.*l2.^2.*l3.^2 + 2.32115782938678e+18*l1.^13.*l2.^2.*l3 + 1.47757559720924e+16*l1.^13.*l2.^2 + 2.71351798953846e+20*l1.^13.*l2.*l3.^4 - 2.04570643262403e+18*l1.^13.*l2.*l3.^3 + 1.91907583473315e+18*l1.^13.*l2.*l3.^2 + 1.0848023371916e+16*l1.^13.*l2.*l3 - 2.07042229545173e+15*l1.^13.*l2 + 7.75486271057917e+19*l1.^13.*l3.^5 - 5.35493742657468e+17*l1.^13.*l3.^4 + 7.46057186484663e+17*l1.^13.*l3.^3 + 5.28373552166597e+15*l1.^13.*l3.^2 - 1.20213890956875e+15*l1.^13.*l3 - 6389716502175.74*l1.^13 - 5.62753372265446e+20*l1.^12.*l2.^6 - 6.57198362003287e+20*l1.^12.*l2.^5.*l3 + 8.1046075433664e+18*l1.^12.*l2.^5 - 1.05305129905122e+21*l1.^12.*l2.^4.*l3.^2 - 1.20335672507296e+18*l1.^12.*l2.^4.*l3 - 5.77154944915541e+18*l1.^12.*l2.^4 - 9.69592853362292e+20*l1.^12.*l2.^3.*l3.^3 + 2.14197497062987e+18*l1.^12.*l2.^3.*l3.^2 - 5.92280406770679e+18*l1.^12.*l2.^3.*l3 - 3.71264248159538e+16*l1.^12.*l2.^3 - 7.20349905829104e+20*l1.^12.*l2.^2.*l3.^4 - 9.3861824555691e+17*l1.^12.*l2.^2.*l3.^3 - 6.27065234831404e+18*l1.^12.*l2.^2.*l3.^2 - 2.01997676580504e+16*l1.^12.*l2.^2.*l3 + 9.5569755581068e+15*l1.^12.*l2.^2 - 4.15778261693094e+20*l1.^12.*l2.*l3.^5 + 1.1973399414476e+18*l1.^12.*l2.*l3.^4 - 4.18055266581092e+18*l1.^12.*l2.*l3.^3 - 2.02465263794811e+16*l1.^12.*l2.*l3.^2 + 8.07626110144377e+15*l1.^12.*l2.*l3 + 41208356517728.5*l1.^12.*l2 - 9.91535086159478e+19*l1.^12.*l3.^6 - 3.85074152023348e+17*l1.^12.*l3.^5 - 1.39006840194432e+18*l1.^12.*l3.^4 - 6.31242739314076e+15*l1.^12.*l3.^3 + 3.84561436440081e+15*l1.^12.*l3.^2 + 20952600877744.5*l1.^12.*l3 - 7584028447509.29*l1.^12 + 8.43332375411548e+20*l1.^11.*l2.^7 + 7.84732576150571e+20*l1.^11.*l2.^6.*l3 - 9.74718947309099e+18*l1.^11.*l2.^6 + 1.63207261432562e+21*l1.^11.*l2.^5.*l3.^2 + 1.29240512272836e+19*l1.^11.*l2.^5.*l3 + 1.18212614170407e+19*l1.^11.*l2.^5 + 1.50195169747444e+21*l1.^11.*l2.^4.*l3.^3 + 4.44038631551923e+18*l1.^11.*l2.^4.*l3.^2 + 1.05940003597763e+19*l1.^11.*l2.^4.*l3 + 6.62571082672626e+16*l1.^11.*l2.^4 + 1.42728392693868e+21*l1.^11.*l2.^3.*l3.^4 + 1.22742385957442e+19*l1.^11.*l2.^3.*l3.^3 + 1.43600457798315e+19*l1.^11.*l2.^3.*l3.^2 + 3.3666279430084e+15*l1.^11.*l2.^3.*l3 - 2.97411323850717e+16*l1.^11.*l2.^3 + 8.84936193498399e+20*l1.^11.*l2.^2.*l3.^5 + 9.35008175381691e+18*l1.^11.*l2.^2.*l3.^4 + 1.07643347379027e+19*l1.^11.*l2.^2.*l3.^3 + 1.87970060151303e+16*l1.^11.*l2.^2.*l3.^2 - 2.63462084991332e+16*l1.^11.*l2.^2.*l3 - 132884843560035.0*l1.^11.*l2.^2 + 5.38021820290143e+20*l1.^11.*l2.*l3.^6 + 1.2996252630788e+18*l1.^11.*l2.*l3.^5 + 7.18131136514905e+18*l1.^11.*l2.*l3.^4 + 1.30924420005882e+16*l1.^11.*l2.*l3.^3 - 2.23630885304469e+16*l1.^11.*l2.*l3.^2 - 75519126275252.6*l1.^11.*l2.*l3 + 55847200187255.9*l1.^11.*l2 + 9.53176070260235e+19*l1.^11.*l3.^7 + 2.31044491214009e+18*l1.^11.*l3.^6 + 1.89990189163657e+18*l1.^11.*l3.^5 - 0.875789473684211*l1.^11.*l3.^4 - 8.01504935132244e+15*l1.^11.*l3.^3 - 39129631740680.6*l1.^11.*l3.^2 + 35167415742729.6*l1.^11.*l3 + 941183981.085292*l1.^11 - 1.07043017981332e+21*l1.^10.*l2.^8 - 6.58456229759496e+20*l1.^10.*l2.^7.*l3 + 8.21376918914087e+18*l1.^10.*l2.^7 - 2.1190926796731e+21*l1.^10.*l2.^6.*l3.^2 - 3.22980945009583e+19*l1.^10.*l2.^6.*l3 - 1.95429028415933e+19*l1.^10.*l2.^6 - 1.77375809785776e+21*l1.^10.*l2.^5.*l3.^3 - 1.24547421045052e+19*l1.^10.*l2.^5.*l3.^2 - 1.33484735633902e+19*l1.^10.*l2.^5.*l3 - 8.58022538252836e+16*l1.^10.*l2.^5 - 1.97987562019239e+21*l1.^10.*l2.^4.*l3.^4 - 4.00236446759267e+19*l1.^10.*l2.^4.*l3.^3 - 2.46123043560196e+19*l1.^10.*l2.^4.*l3.^2 + 8.50541142823928e+16*l1.^10.*l2.^4.*l3 + 6.83751630099804e+16*l1.^10.*l2.^4 - 1.58656104587735e+21*l1.^10.*l2.^3.*l3.^5 - 2.28276770746341e+19*l1.^10.*l2.^3.*l3.^4 - 1.98019743894815e+19*l1.^10.*l2.^3.*l3.^3 + 1.58044478435672e+16*l1.^10.*l2.^3.*l3.^2 + 5.55044676534117e+16*l1.^10.*l2.^3.*l3 + 277899518631596.0*l1.^10.*l2.^3 - 8.55817017771676e+20*l1.^10.*l2.^2.*l3.^6 - 2.40430673669578e+19*l1.^10.*l2.^2.*l3.^5 - 1.4637439493664e+19*l1.^10.*l2.^2.*l3.^4 + 6.78001460744748e+16*l1.^10.*l2.^2.*l3.^3 + 6.18145306430279e+16*l1.^10.*l2.^2.*l3.^2 + 50125613373814.9*l1.^10.*l2.^2.*l3 - 206965878567755.0*l1.^10.*l2.^2 - 6.03946374063737e+20*l1.^10.*l2.*l3.^7 - 3.15279461969116e+18*l1.^10.*l2.*l3.^6 - 9.93580436081432e+18*l1.^10.*l2.*l3.^5 + 6.0786337859874e+15*l1.^10.*l2.*l3.^4 + 4.10115833708114e+16*l1.^10.*l2.*l3.^3 + 100475634536061.0*l1.^10.*l2.*l3.^2 - 199083591382509.0*l1.^10.*l2.*l3 + 195578031269.516*l1.^10.*l2 - 5.94735919891829e+19*l1.^10.*l3.^8 - 4.68621490364128e+18*l1.^10.*l3.^7 - 1.80713177845105e+18*l1.^10.*l3.^6 + 1.80488664722395e+16*l1.^10.*l3.^5 + 1.18204975106259e+16*l1.^10.*l3.^4 + 19204582315226.9*l1.^10.*l3.^3 - 94471309345854.5*l1.^10.*l3.^2 - 177695535628.898*l1.^10.*l3 + 55358859204.6269*l1.^10 + 1.15826424997009e+21*l1.^9.*l2.^9 + 2.5837486761846e+20*l1.^9.*l2.^8.*l3 - 3.23230211759777e+18*l1.^9.*l2.^8 + 2.42971563598519e+21*l1.^9.*l2.^7.*l3.^2 + 5.12801872984663e+19*l1.^9.*l2.^7.*l3 + 2.65101403686162e+19*l1.^9.*l2.^7 + 1.42909616159643e+21*l1.^9.*l2.^6.*l3.^3 + 1.56556709931992e+19*l1.^9.*l2.^6.*l3.^2 + 1.03608579534047e+19*l1.^9.*l2.^6.*l3 + 7.54218176676744e+16*l1.^9.*l2.^6 + 2.40819861861687e+21*l1.^9.*l2.^5.*l3.^4 + 7.04685698202726e+19*l1.^9.*l2.^5.*l3.^3 + 3.48330997618425e+19*l1.^9.*l2.^5.*l3.^2 - 2.48008258468286e+17*l1.^9.*l2.^5.*l3 - 1.22037907812257e+17*l1.^9.*l2.^5 + 1.61541075197846e+21*l1.^9.*l2.^4.*l3.^5 + 4.78935976579039e+19*l1.^9.*l2.^4.*l3.^4 + 2.37728362971435e+19*l1.^9.*l2.^4.*l3.^3 - 9.58553789328782e+16*l1.^9.*l2.^4.*l3.^2 - 7.61919928397844e+16*l1.^9.*l2.^4.*l3 - 394485270189777.0*l1.^9.*l2.^4 + 1.60821529586853e+21*l1.^9.*l2.^3.*l3.^6 + 3.67986486527312e+19*l1.^9.*l2.^3.*l3.^5 + 2.53673816494009e+19*l1.^9.*l2.^3.*l3.^4 - 2.18830816295546e+17*l1.^9.*l2.^3.*l3.^3 - 1.2426867398285e+17*l1.^9.*l2.^3.*l3.^2 + 260903581391982.0*l1.^9.*l2.^3.*l3 + 508106369495986.0*l1.^9.*l2.^3 + 5.67226509278647e+20*l1.^9.*l2.^2.*l3.^7 + 3.5559191225906e+19*l1.^9.*l2.^2.*l3.^6 + 1.38328136581061e+19*l1.^9.*l2.^2.*l3.^5 - 1.6622725468604e+17*l1.^9.*l2.^2.*l3.^4 - 8.16583713159569e+16*l1.^9.*l2.^2.*l3.^3 + 54625580078674.2*l1.^9.*l2.^2.*l3.^2 + 538753899145941.0*l1.^9.*l2.^2.*l3 - 987866706547.093*l1.^9.*l2.^2 + 6.15564570195812e+20*l1.^9.*l2.*l3.^8 + 2.92587592296312e+18*l1.^9.*l2.*l3.^7 + 1.191174470459e+19*l1.^9.*l2.*l3.^6 - 3.32922096586386e+16*l1.^9.*l2.*l3.^5 - 6.16218205899107e+16*l1.^9.*l2.*l3.^4 + 46771307483578.5*l1.^9.*l2.*l3.^3 + 458371992964279.0*l1.^9.*l2.*l3.^2 + 512380559302.82*l1.^9.*l2.*l3 - 291966080857.64*l1.^9.*l2 + 2.3536472307069e+18*l1.^9.*l3.^9 + 6.30172130705173e+18*l1.^9.*l3.^8 + 8.39904639449429e+17*l1.^9.*l3.^7 - 4.20360905661744e+16*l1.^9.*l3.^6 - 1.12330094747385e+16*l1.^9.*l3.^5 + 62716071398434.8*l1.^9.*l3.^4 + 162657913657818.0*l1.^9.*l3.^3 + 244896071878.386*l1.^9.*l3.^2 - 254844968417.144*l1.^9.*l3 + 1016631415.72286*l1.^9 - 1.07043017981332e+21*l1.^8.*l2.^10 + 2.5837486761846e+20*l1.^8.*l2.^9.*l3 - 3.23230211759777e+18*l1.^8.*l2.^9 - 2.52346351632351e+21*l1.^8.*l2.^8.*l3.^2 - 5.94269123272103e+19*l1.^8.*l2.^8.*l3 - 2.97441099025041e+19*l1.^8.*l2.^8 - 5.74660579713542e+20*l1.^8.*l2.^7.*l3.^3 - 6.63737187929529e+18*l1.^8.*l2.^7.*l3.^2 - 8.41316948521783e+17*l1.^8.*l2.^7.*l3 - 3.04399276513676e+16*l1.^8.*l2.^7 - 2.37767861224096e+21*l1.^8.*l2.^6.*l3.^4 - 1.00720957888607e+20*l1.^8.*l2.^6.*l3.^3 - 4.22666704960742e+19*l1.^8.*l2.^6.*l3.^2 + 4.23774292326183e+17*l1.^8.*l2.^6.*l3 + 1.73222333563331e+17*l1.^8.*l2.^6 - 1.53381699495838e+21*l1.^8.*l2.^5.*l3.^5 - 3.92053621028771e+19*l1.^8.*l2.^5.*l3.^4 - 1.97059798022247e+19*l1.^8.*l2.^5.*l3.^3 + 1.16990321019542e+17*l1.^8.*l2.^5.*l3.^2 + 6.14666782915347e+16*l1.^8.*l2.^5.*l3 + 368926404181075.0*l1.^8.*l2.^5 - 1.23374302514609e+21*l1.^8.*l2.^4.*l3.^6 - 7.99269536793461e+19*l1.^8.*l2.^4.*l3.^5 - 2.80053981857538e+19*l1.^8.*l2.^4.*l3.^4 + 5.10605238022941e+17*l1.^8.*l2.^4.*l3.^3 + 1.8583351741097e+17*l1.^8.*l2.^4.*l3.^2 - 1.0091263917669e+15*l1.^8.*l2.^4.*l3 - 908258767273302.0*l1.^8.*l2.^4 - 1.38571067029246e+21*l1.^8.*l2.^3.*l3.^7 - 2.41513694722143e+19*l1.^8.*l2.^3.*l3.^6 - 2.29567774287337e+19*l1.^8.*l2.^3.*l3.^5 + 2.25143243688687e+17*l1.^8.*l2.^3.*l3.^4 + 1.24350444692011e+17*l1.^8.*l2.^3.*l3.^3 - 304899318860751.0*l1.^8.*l2.^3.*l3.^2 - 923899540276669.0*l1.^8.*l2.^3.*l3 + 2403407414099.33*l1.^8.*l2.^3 - 1.54898457917441e+20*l1.^8.*l2.^2.*l3.^8 - 4.36921636063634e+19*l1.^8.*l2.^2.*l3.^7 - 8.92902551913404e+18*l1.^8.*l2.^2.*l3.^6 + 3.07625628292393e+17*l1.^8.*l2.^2.*l3.^5 + 8.91356377879753e+16*l1.^8.*l2.^2.*l3.^4 - 799718492351792.0*l1.^8.*l2.^2.*l3.^3 - 1.04400963230387e+15*l1.^8.*l2.^2.*l3.^2 - 1639918968642.96*l1.^8.*l2.^2.*l3 + 736071345363.576*l1.^8.*l2.^2 - 5.81099713632707e+20*l1.^8.*l2.*l3.^9 + 5.80189849588779e+16*l1.^8.*l2.*l3.^8 - 1.27344253934741e+19*l1.^8.*l2.*l3.^7 + 3.10010323085356e+16*l1.^8.*l2.*l3.^6 + 7.50306929717819e+16*l1.^8.*l2.*l3.^5 - 175746731150415.0*l1.^8.*l2.*l3.^4 - 678134490752519.0*l1.^8.*l2.*l3.^3 + 438779971981.95*l1.^8.*l2.*l3.^2 + 1090876747137.52*l1.^8.*l2.*l3 - 9701293478.1125*l1.^8.*l2 + 5.18074456144522e+19*l1.^8.*l3.^10 - 6.2763648617734e+18*l1.^8.*l3.^9 + 6.97059183538048e+17*l1.^8.*l3.^8 + 6.01784744812752e+16*l1.^8.*l3.^7 + 4.11770748070764e+15*l1.^8.*l3.^6 - 204022112492761.0*l1.^8.*l3.^5 - 196591625375049.0*l1.^8.*l3.^4 - 86965399852.2774*l1.^8.*l3.^3 + 611818931990.585*l1.^8.*l3.^2 + 3136484304.65918*l1.^8.*l3 + 33824342.4395588*l1.^8 + 8.43332375411548e+20*l1.^7.*l2.^11 - 6.58456229759496e+20*l1.^7.*l2.^10.*l3 + 8.21376918914087e+18*l1.^7.*l2.^10 + 2.42971563598519e+21*l1.^7.*l2.^9.*l3.^2 + 5.12801872984663e+19*l1.^7.*l2.^9.*l3 + 2.76598603172169e+19*l1.^7.*l2.^9 - 5.74660579713542e+20*l1.^7.*l2.^8.*l3.^3 - 6.63737187929529e+18*l1.^7.*l2.^8.*l3.^2 - 1.11887964859285e+19*l1.^7.*l2.^8.*l3 - 3.04399276513676e+16*l1.^7.*l2.^8 + 2.47838943195935e+21*l1.^7.*l2.^7.*l3.^4 + 1.0784826786311e+20*l1.^7.*l2.^7.*l3.^3 + 4.64617214941348e+19*l1.^7.*l2.^7.*l3.^2 - 4.97619673099909e+17*l1.^7.*l2.^7.*l3 - 1.98139612921163e+17*l1.^7.*l2.^7 + 3.6707934068841e+20*l1.^7.*l2.^6.*l3.^5 + 2.44040743844796e+19*l1.^7.*l2.^6.*l3.^4 + 4.15579752492444e+18*l1.^7.*l2.^6.*l3.^3 - 6.50881402314957e+16*l1.^7.*l2.^6.*l3.^2 + 189259331005754.0*l1.^7.*l2.^6.*l3 - 151404391573735.0*l1.^7.*l2.^6 + 1.75598750170749e+21*l1.^7.*l2.^5.*l3.^6 + 7.01797642062551e+19*l1.^7.*l2.^5.*l3.^5 + 3.20373505141543e+19*l1.^7.*l2.^5.*l3.^4 - 6.84547681745042e+17*l1.^7.*l2.^5.*l3.^3 - 2.40297292473647e+17*l1.^7.*l2.^5.*l3.^2 + 1.84115960565281e+15*l1.^7.*l2.^5.*l3 + 1.24101120820921e+15*l1.^7.*l2.^5 + 2.14163997022289e+20*l1.^7.*l2.^4.*l3.^7 + 6.1371192978721e+19*l1.^7.*l2.^4.*l3.^6 + 1.22737737870294e+19*l1.^7.*l2.^4.*l3.^5 - 3.73134597016765e+17*l1.^7.*l2.^4.*l3.^4 - 9.37656866641387e+16*l1.^7.*l2.^4.*l3.^3 + 582692539066249.0*l1.^7.*l2.^4.*l3.^2 + 1.03779697069498e+15*l1.^7.*l2.^4.*l3 - 3482568966811.69*l1.^7.*l2.^4 + 1.28725845858113e+21*l1.^7.*l2.^3.*l3.^8 + 1.03557441597707e+19*l1.^7.*l2.^3.*l3.^7 + 2.21098083071349e+19*l1.^7.*l2.^3.*l3.^6 - 2.85041165841378e+17*l1.^7.*l2.^3.*l3.^5 - 1.5232144253147e+17*l1.^7.*l2.^3.*l3.^4 + 1.56825611304787e+15*l1.^7.*l2.^3.*l3.^3 + 1.63677235352372e+15*l1.^7.*l2.^3.*l3.^2 + 5030440142104.51*l1.^7.*l2.^3.*l3 - 1120147595054.6*l1.^7.*l2.^3 - 2.6069584741182e+20*l1.^7.*l2.^2.*l3.^9 + 4.14487628546203e+19*l1.^7.*l2.^2.*l3.^8 + 3.98183906631534e+17*l1.^7.*l2.^2.*l3.^7 - 3.47323782787034e+17*l1.^7.*l2.^2.*l3.^6 - 4.96833002008919e+16*l1.^7.*l2.^2.*l3.^5 + 1.15564105574009e+15*l1.^7.*l2.^2.*l3.^4 + 1.14015304066663e+15*l1.^7.*l2.^2.*l3.^3 - 3195131378988.26*l1.^7.*l2.^2.*l3.^2 - 2325656905044.59*l1.^7.*l2.^2.*l3 + 30370660905.0331*l1.^7.*l2.^2 + 5.15088985412317e+20*l1.^7.*l2.*l3.^10 - 2.89493246431838e+18*l1.^7.*l2.*l3.^9 + 1.26273980213873e+19*l1.^7.*l2.*l3.^8 - 8.97767451468902e+15*l1.^7.*l2.*l3.^7 - 8.31702986265265e+16*l1.^7.*l2.*l3.^6 + 278572741996889.0*l1.^7.*l2.*l3.^5 + 785337866116897.0*l1.^7.*l2.*l3.^4 - 512757032895.256*l1.^7.*l2.*l3.^3 - 2085485305255.87*l1.^7.*l2.*l3.^2 - 14290566525.1138*l1.^7.*l2.*l3 - 1544280872.57862*l1.^7.*l2 - 8.16872045020224e+19*l1.^7.*l3.^11 + 4.64839512085327e+18*l1.^7.*l3.^10 - 2.06748138416277e+18*l1.^7.*l3.^9 - 6.05191451659844e+16*l1.^7.*l3.^8 + 7.47777855681224e+15*l1.^7.*l3.^7 + 317371667523040.0*l1.^7.*l3.^6 + 156255488201288.0*l1.^7.*l3.^5 - 917654381558.137*l1.^7.*l3.^4 - 936711721241.415*l1.^7.*l3.^3 - 160351958.315907*l1.^7.*l3.^2 + 1118551079.93554*l1.^7.*l3 - 23270257.9689913*l1.^7 - 5.62753372265445e+20*l1.^6.*l2.^12 + 7.84732576150571e+20*l1.^6.*l2.^11.*l3 - 9.74718947309099e+18*l1.^6.*l2.^11 - 2.1190926796731e+21*l1.^6.*l2.^10.*l3.^2 - 3.22980945009583e+19*l1.^6.*l2.^10.*l3 - 2.12318106050603e+19*l1.^6.*l2.^10 + 1.42909616159643e+21*l1.^6.*l2.^9.*l3.^3 + 1.56556709931992e+19*l1.^6.*l2.^9.*l3.^2 + 1.92018959478691e+19*l1.^6.*l2.^9.*l3 + 7.54218176676744e+16*l1.^6.*l2.^9 - 2.37767861224096e+21*l1.^6.*l2.^8.*l3.^4 - 1.00720957888607e+20*l1.^6.*l2.^8.*l3.^3 - 4.58351630902407e+19*l1.^6.*l2.^8.*l3.^2 + 4.23774292326183e+17*l1.^6.*l2.^8.*l3 + 1.83099075218958e+17*l1.^6.*l2.^8 + 3.6707934068841e+20*l1.^6.*l2.^7.*l3.^5 + 2.44040743844797e+19*l1.^6.*l2.^7.*l3.^4 + 1.36717777760352e+19*l1.^6.*l2.^7.*l3.^3 - 6.50881402314956e+16*l1.^6.*l2.^7.*l3.^2 - 7.88246739140157e+16*l1.^6.*l2.^7.*l3 - 151404391573735.0*l1.^6.*l2.^7 - 9.68831755946434e+20*l1.^6.*l2.^6.*l3.^6 - 1.01081964906129e+20*l1.^6.*l2.^6.*l3.^5 - 2.98235503666176e+19*l1.^6.*l2.^6.*l3.^4 + 8.2482384603706e+17*l1.^6.*l2.^6.*l3.^3 + 2.67741486718061e+17*l1.^6.*l2.^6.*l3.^2 - 2.24473929674217e+15*l1.^6.*l2.^6.*l3 - 1.32322873788094e+15*l1.^6.*l2.^6 - 9.16896113904311e+20*l1.^6.*l2.^5.*l3.^7 + 9.0973768415516e+18*l1.^6.*l2.^5.*l3.^6 - 8.98547562787135e+18*l1.^6.*l2.^5.*l3.^5 + 5.89159890026472e+16*l1.^6.*l2.^5.*l3.^4 + 2.47414998756287e+16*l1.^6.*l2.^5.*l3.^3 - 211144107041397.0*l1.^6.*l2.^5.*l3.^2 - 728735525856024.0*l1.^6.*l2.^5.*l3 + 2845575648413.19*l1.^6.*l2.^5 + 3.24054709471956e+20*l1.^6.*l2.^4.*l3.^8 - 7.39342371884828e+19*l1.^6.*l2.^4.*l3.^7 - 6.10269379027546e+18*l1.^6.*l2.^4.*l3.^6 + 6.55931344229471e+17*l1.^6.*l2.^4.*l3.^5 + 1.28407403343398e+17*l1.^6.*l2.^4.*l3.^4 - 2.85340408458528e+15*l1.^6.*l2.^4.*l3.^3 - 1.84459673762615e+15*l1.^6.*l2.^4.*l3.^2 - 10243846450132.0*l1.^6.*l2.^4.*l3 + 1037554583034.45*l1.^6.*l2.^4 - 1.13386030292494e+21*l1.^6.*l2.^3.*l3.^9 + 1.53427982446802e+19*l1.^6.*l2.^3.*l3.^8 - 1.85963698286906e+19*l1.^6.*l2.^3.*l3.^7 + 2.74941282012353e+16*l1.^6.*l2.^3.*l3.^6 + 1.0955536387949e+17*l1.^6.*l2.^3.*l3.^5 - 726549742386952.0*l1.^6.*l2.^3.*l3.^4 - 1.34295523739246e+15*l1.^6.*l2.^3.*l3.^3 + 7523071797610.75*l1.^6.*l2.^3.*l3.^2 + 3365107935513.11*l1.^6.*l2.^3.*l3 - 48856034659.6912*l1.^6.*l2.^3 + 4.99685137751365e+20*l1.^6.*l2.^2.*l3.^10 - 3.44400694715882e+19*l1.^6.*l2.^2.*l3.^9 + 6.92401599739838e+18*l1.^6.*l2.^2.*l3.^8 + 3.58545875930395e+17*l1.^6.*l2.^2.*l3.^7 + 1.29059176877081e+15*l1.^6.*l2.^2.*l3.^6 - 1.70601887327222e+15*l1.^6.*l2.^2.*l3.^5 - 987309740145160.0*l1.^6.*l2.^2.*l3.^4 + 444991786257.131*l1.^6.*l2.^2.*l3.^3 + 3276093030966.41*l1.^6.*l2.^2.*l3.^2 + 55186729974.0032*l1.^6.*l2.^2.*l3 + 7328175401.63967*l1.^6.*l2.^2 - 4.16287374153702e+20*l1.^6.*l2.*l3.^11 + 3.87480865473494e+18*l1.^6.*l2.*l3.^10 - 1.1377644199708e+19*l1.^6.*l2.*l3.^9 - 2.38469479296429e+16*l1.^6.*l2.*l3.^8 + 8.26892867358835e+16*l1.^6.*l2.*l3.^7 - 117884954543837.0*l1.^6.*l2.*l3.^6 - 700554731689867.0*l1.^6.*l2.*l3.^5 + 2995788611794.4*l1.^6.*l2.*l3.^4 + 2643571634782.87*l1.^6.*l2.*l3.^3 - 17324425576.4508*l1.^6.*l2.*l3.^2 - 2834489128.82053*l1.^6.*l2.*l3 + 151784334.961277*l1.^6.*l2 + 8.09910501475175e+19*l1.^6.*l3.^12 - 2.43078058464738e+18*l1.^6.*l3.^11 + 2.61461524579083e+18*l1.^6.*l3.^10 + 4.44207853591387e+16*l1.^6.*l3.^9 - 1.71630929315618e+16*l1.^6.*l3.^8 - 340651022838730.0*l1.^6.*l3.^7 - 63395557966933.0*l1.^6.*l3.^6 + 1929050687632.36*l1.^6.*l3.^5 + 974974522221.57*l1.^6.*l3.^4 - 2026848753.11309*l1.^6.*l3.^3 - 2660210036.02401*l1.^6.*l3.^2 - 48757746.1979689*l1.^6.*l3 - 4885634.89859731*l1.^6 + 3.14442254811672e+20*l1.^5.*l2.^13 - 6.57198362003287e+20*l1.^5.*l2.^12.*l3 + 8.1046075433664e+18*l1.^5.*l2.^12 + 1.63207261432562e+21*l1.^5.*l2.^11.*l3.^2 + 1.29240512272836e+19*l1.^5.*l2.^11.*l3 + 1.33122052128129e+19*l1.^5.*l2.^11 - 1.77375809785776e+21*l1.^5.*l2.^10.*l3.^3 - 1.24547421045052e+19*l1.^5.*l2.^10.*l3.^2 - 1.96154087360816e+19*l1.^5.*l2.^10.*l3 - 8.58022538252836e+16*l1.^5.*l2.^10 + 2.40819861861687e+21*l1.^5.*l2.^9.*l3.^4 + 7.04685698202726e+19*l1.^5.*l2.^9.*l3.^3 + 3.96446616419064e+19*l1.^5.*l2.^9.*l3.^2 - 2.48008258468286e+17*l1.^5.*l2.^9.*l3 - 1.36010137961215e+17*l1.^5.*l2.^9 - 1.53381699495838e+21*l1.^5.*l2.^8.*l3.^5 - 3.92053621028771e+19*l1.^5.*l2.^8.*l3.^4 - 2.70036802540832e+19*l1.^5.*l2.^8.*l3.^3 + 1.16990321019542e+17*l1.^5.*l2.^8.*l3.^2 + 1.27956299698395e+17*l1.^5.*l2.^8.*l3 + 368926404181075.0*l1.^5.*l2.^8 + 1.75598750170749e+21*l1.^5.*l2.^7.*l3.^6 + 7.01797642062551e+19*l1.^5.*l2.^7.*l3.^5 + 3.23587810412051e+19*l1.^5.*l2.^7.*l3.^4 - 6.84547681745042e+17*l1.^5.*l2.^7.*l3.^3 - 2.69213978366023e+17*l1.^5.*l2.^7.*l3.^2 + 1.84115960565281e+15*l1.^5.*l2.^7.*l3 + 1.10937038431609e+15*l1.^5.*l2.^7 - 9.16896113904311e+20*l1.^5.*l2.^6.*l3.^7 + 9.09737684155159e+18*l1.^5.*l2.^6.*l3.^6 - 9.43547836574261e+18*l1.^5.*l2.^6.*l3.^5 + 5.8915989002647e+16*l1.^5.*l2.^6.*l3.^4 + 9.22137669578403e+16*l1.^5.*l2.^6.*l3.^3 - 211144107041394.0*l1.^5.*l2.^6.*l3.^2 + 171008891432707.0*l1.^5.*l2.^6.*l3 - 415626846047.255*l1.^5.*l2.^6 + 1.37678819892655e+21*l1.^5.*l2.^5.*l3.^8 + 1.73283368410507e+18*l1.^5.*l2.^5.*l3.^7 + 1.80019958495951e+19*l1.^5.*l2.^5.*l3.^6 - 3.77062329616941e+17*l1.^5.*l2.^5.*l3.^5 - 1.70683250353374e+17*l1.^5.*l2.^5.*l3.^4 + 2.84978993809792e+15*l1.^5.*l2.^5.*l3.^3 + 1.71872944321855e+15*l1.^5.*l2.^5.*l3.^2 + 13664861984580.7*l1.^5.*l2.^5.*l3 - 443430981946.943*l1.^5.*l2.^5 - 9.45299446656119e+20*l1.^5.*l2.^4.*l3.^9 + 4.80861347339155e+19*l1.^5.*l2.^4.*l3.^8 - 7.94938807577487e+18*l1.^5.*l2.^4.*l3.^7 - 3.37785003615176e+17*l1.^5.*l2.^4.*l3.^6 + 1.79008921074154e+16*l1.^5.*l2.^4.*l3.^5 + 979894324589670.0*l1.^5.*l2.^4.*l3.^4 + 796066292819710.0*l1.^5.*l2.^4.*l3.^3 - 12860149680752.8*l1.^5.*l2.^4.*l3.^2 - 3741453831139.84*l1.^5.*l2.^4.*l3 + 40007813599.8193*l1.^5.*l2.^4 + 1.04481396228959e+21*l1.^5.*l2.^3.*l3.^10 - 2.04329971917389e+19*l1.^5.*l2.^3.*l3.^9 + 1.79668597819788e+19*l1.^5.*l2.^3.*l3.^8 + 5.38660470881343e+16*l1.^5.*l2.^3.*l3.^7 - 1.20510480295665e+17*l1.^5.*l2.^3.*l3.^6 + 880930489891462.0*l1.^5.*l2.^3.*l3.^5 + 1.22734922318446e+15*l1.^5.*l2.^3.*l3.^4 + 5389595949286.63*l1.^5.*l2.^3.*l3.^3 - 3052037073178.55*l1.^5.*l2.^3.*l3.^2 - 131886278675.669*l1.^5.*l2.^3.*l3 - 17536742299.8845*l1.^5.*l2.^3 - 5.44355385002108e+20*l1.^5.*l2.^2.*l3.^11 + 2.16965217530655e+19*l1.^5.*l2.^2.*l3.^10 - 1.0799791931553e+19*l1.^5.*l2.^2.*l3.^9 - 2.63017808047531e+17*l1.^5.*l2.^2.*l3.^8 + 5.18679002674295e+16*l1.^5.*l2.^2.*l3.^7 + 1.39311173964534e+15*l1.^5.*l2.^2.*l3.^6 + 437768187372420.0*l1.^5.*l2.^2.*l3.^5 - 7945475168321.79*l1.^5.*l2.^2.*l3.^4 - 3353223834414.67*l1.^5.*l2.^2.*l3.^3 + 66116319452.8157*l1.^5.*l2.^2.*l3.^2 + 6332483481.60482*l1.^5.*l2.^2.*l3 - 346303651.231617*l1.^5.*l2.^2 + 2.97545892179622e+20*l1.^5.*l2.*l3.^12 - 2.38264631564446e+18*l1.^5.*l2.*l3.^11 + 9.00649529394583e+18*l1.^5.*l2.*l3.^10 + 2.99255817156302e+16*l1.^5.*l2.*l3.^9 - 7.50035462729172e+16*l1.^5.*l2.*l3.^8 - 23527384976588.4*l1.^5.*l2.*l3.^7 + 552512456240323.0*l1.^5.*l2.*l3.^6 - 1907591692863.62*l1.^5.*l2.*l3.^5 - 2301552311371.14*l1.^5.*l2.*l3.^4 - 7684065842.49834*l1.^5.*l2.*l3.^3 + 3128656820.997*l1.^5.*l2.*l3.^2 + 287301874.842077*l1.^5.*l2.*l3 + 37178245.2780466*l1.^5.*l2 - 5.99261363986121e+19*l1.^5.*l3.^13 + 6.67862982415494e+17*l1.^5.*l3.^12 - 2.25827355945301e+18*l1.^5.*l3.^11 - 2.20233577938466e+16*l1.^5.*l3.^10 + 1.99641868742144e+16*l1.^5.*l3.^9 + 254336700846308.0*l1.^5.*l3.^8 - 27073337818508.4*l1.^5.*l3.^7 - 2606138443625.1*l1.^5.*l3.^6 - 687273831010.755*l1.^5.*l3.^5 + 16788850035.6757*l1.^5.*l3.^4 + 4120907045.40128*l1.^5.*l3.^3 - 70482338.8414889*l1.^5.*l3.^2 - 12239601.4866221*l1.^5.*l3 - 656274.840023902*l1.^5 - 1.44293197226472e+20*l1.^4.*l2.^14 + 4.14159386919363e+20*l1.^4.*l2.^13.*l3 - 5.0601150289318e+18*l1.^4.*l2.^13 - 1.05305129905122e+21*l1.^4.*l2.^12.*l3.^2 - 1.20335672507296e+18*l1.^4.*l2.^12.*l3 - 6.68657896327377e+18*l1.^4.*l2.^12 + 1.50195169747444e+21*l1.^4.*l2.^11.*l3.^3 + 4.44038631551923e+18*l1.^4.*l2.^11.*l3.^2 + 1.4119635550336e+19*l1.^4.*l2.^11.*l3 + 6.62571082672626e+16*l1.^4.*l2.^11 - 1.97987562019239e+21*l1.^4.*l2.^10.*l3.^4 - 4.00236446759267e+19*l1.^4.*l2.^10.*l3.^3 - 2.83359599723695e+19*l1.^4.*l2.^10.*l3.^2 + 8.50541142823928e+16*l1.^4.*l2.^10.*l3 + 7.99427883070284e+16*l1.^4.*l2.^10 + 1.61541075197846e+21*l1.^4.*l2.^9.*l3.^5 + 4.78935976579039e+19*l1.^4.*l2.^9.*l3.^4 + 2.81657518848702e+19*l1.^4.*l2.^9.*l3.^3 - 9.58553789328781e+16*l1.^4.*l2.^9.*l3.^2 - 1.22007095065473e+17*l1.^4.*l2.^9.*l3 - 394485270189778.0*l1.^4.*l2.^9 - 1.23374302514609e+21*l1.^4.*l2.^8.*l3.^6 - 7.99269536793461e+19*l1.^4.*l2.^8.*l3.^5 - 2.87673326933157e+19*l1.^4.*l2.^8.*l3.^4 + 5.10605238022941e+17*l1.^4.*l2.^8.*l3.^3 + 2.25777423909418e+17*l1.^4.*l2.^8.*l3.^2 - 1.00912639176691e+15*l1.^4.*l2.^8.*l3 - 725613558495056.0*l1.^4.*l2.^8 + 2.14163997022289e+20*l1.^4.*l2.^7.*l3.^7 + 6.13711929787211e+19*l1.^4.*l2.^7.*l3.^6 + 1.31714384720776e+19*l1.^4.*l2.^7.*l3.^5 - 3.73134597016765e+17*l1.^4.*l2.^7.*l3.^4 - 1.52088294172706e+17*l1.^4.*l2.^7.*l3.^3 + 582692539066250.0*l1.^4.*l2.^7.*l3.^2 + 243931257191870.0*l1.^4.*l2.^7.*l3 - 2118793378219.15*l1.^4.*l2.^7 + 3.24054709471956e+20*l1.^4.*l2.^6.*l3.^8 - 7.39342371884828e+19*l1.^4.*l2.^6.*l3.^7 - 6.77496697460563e+18*l1.^4.*l2.^6.*l3.^6 + 6.5593134422947e+17*l1.^4.*l2.^6.*l3.^5 + 1.46131632630627e+17*l1.^4.*l2.^6.*l3.^4 - 2.85340408458529e+15*l1.^4.*l2.^6.*l3.^3 - 1.31969699412529e+15*l1.^4.*l2.^6.*l3.^2 - 11524609611592.8*l1.^4.*l2.^6.*l3 - 225682904289.591*l1.^4.*l2.^6 - 9.45299446656119e+20*l1.^4.*l2.^5.*l3.^9 + 4.80861347339156e+19*l1.^4.*l2.^5.*l3.^8 - 7.37315391777758e+18*l1.^4.*l2.^5.*l3.^7 - 3.37785003615176e+17*l1.^4.*l2.^5.*l3.^6 - 3.36818303725905e+15*l1.^4.*l2.^5.*l3.^5 + 979894324589669.0*l1.^4.*l2.^5.*l3.^4 - 191592463014846.0*l1.^4.*l2.^5.*l3.^3 + 15103179344475.3*l1.^4.*l2.^5.*l3.^2 + 3562807132334.32*l1.^4.*l2.^5.*l3 - 1266780470.69569*l1.^4.*l2.^5 + 9.14333066930908e+20*l1.^4.*l2.^4.*l3.^10 - 4.64495695878163e+19*l1.^4.*l2.^4.*l3.^9 + 9.97403787813099e+18*l1.^4.*l2.^4.*l3.^8 + 4.76938958592857e+17*l1.^4.*l2.^4.*l3.^7 - 1.48704129916276e+16*l1.^4.*l2.^4.*l3.^6 - 2.48383988984762e+15*l1.^4.*l2.^4.*l3.^5 - 776439512437119.0*l1.^4.*l2.^4.*l3.^4 - 12508335108623.2*l1.^4.*l2.^4.*l3.^3 + 1056574216186.43*l1.^4.*l2.^4.*l3.^2 + 182987240751.783*l1.^4.*l2.^4.*l3 + 26187040147.9952*l1.^4.*l2.^4 - 7.95023847424998e+20*l1.^4.*l2.^3.*l3.^11 + 2.04209636244882e+19*l1.^4.*l2.^3.*l3.^10 - 1.45604856105133e+19*l1.^4.*l2.^3.*l3.^9 - 1.97088010830284e+17*l1.^4.*l2.^3.*l3.^8 + 9.51575601395976e+16*l1.^4.*l2.^3.*l3.^7 + 610330129852000.0*l1.^4.*l2.^3.*l3.^6 - 592290678730249.0*l1.^4.*l2.^3.*l3.^5 + 10430200878386.9*l1.^4.*l2.^3.*l3.^4 + 3395372795887.14*l1.^4.*l2.^3.*l3.^3 - 127165517022.848*l1.^4.*l2.^3.*l3.^2 - 14931715203.6973*l1.^4.*l2.^3.*l3 + 319910083.329087*l1.^4.*l2.^3 + 4.19553921981763e+20*l1.^4.*l2.^2.*l3.^12 - 1.08302105256567e+19*l1.^4.*l2.^2.*l3.^11 + 9.88291224124519e+18*l1.^4.*l2.^2.*l3.^10 + 1.72305888472027e+17*l1.^4.*l2.^2.*l3.^9 - 6.91134246812742e+16*l1.^4.*l2.^2.*l3.^8 - 1.21428235413805e+15*l1.^4.*l2.^2.*l3.^7 - 66297229284739.1*l1.^4.*l2.^2.*l3.^6 + 2127828744437.58*l1.^4.*l2.^2.*l3.^5 + 1730777803671.44*l1.^4.*l2.^2.*l3.^4 + 51466564541.0742*l1.^4.*l2.^2.*l3.^3 + 4090741238.17227*l1.^4.*l2.^2.*l3.^2 - 742686859.008502*l1.^4.*l2.^2.*l3 - 110054364.106411*l1.^4.*l2.^2 - 1.78731385994021e+20*l1.^4.*l2.*l3.^13 + 4.99393040905279e+17*l1.^4.*l2.*l3.^12 - 5.90245848168715e+18*l1.^4.*l2.*l3.^11 - 1.93113519508676e+16*l1.^4.*l2.*l3.^10 + 5.71284872227044e+16*l1.^4.*l2.*l3.^9 + 136770641580767.0*l1.^4.*l2.*l3.^8 - 373827858804695.0*l1.^4.*l2.*l3.^7 + 1975921649890.4*l1.^4.*l2.*l3.^6 + 1561832598919.94*l1.^4.*l2.*l3.^5 - 35556443236.9697*l1.^4.*l2.*l3.^4 - 7329576456.62901*l1.^4.*l2.*l3.^3 + 275405581.716381*l1.^4.*l2.*l3.^2 + 42170849.3394619*l1.^4.*l2.*l3 + 1193002.12753089*l1.^4.*l2 + 3.42489429236059e+19*l1.^4.*l3.^14 + 1.68469941510215e+17*l1.^4.*l3.^13 + 1.43591012760727e+18*l1.^4.*l3.^12 + 5.56428785025e+15*l1.^4.*l3.^11 - 1.57843115768757e+16*l1.^4.*l3.^10 - 134054126247125.0*l1.^4.*l3.^9 + 65427215027424.6*l1.^4.*l3.^8 + 2133475848324.08*l1.^4.*l3.^7 + 292845566933.692*l1.^4.*l3.^6 - 17619473179.7521*l1.^4.*l3.^5 - 3212319746.62224*l1.^4.*l3.^4 + 63851967.5832606*l1.^4.*l3.^3 + 8625904.11664126*l1.^4.*l3.^2 - 266302.479054925*l1.^4.*l3 - 178478.827704836*l1.^4 + 5.27349412587774e+19*l1.^3.*l2.^15 - 1.97932639584095e+20*l1.^3.*l2.^14.*l3 + 2.38780355875192e+18*l1.^3.*l2.^14 + 5.48866429956099e+20*l1.^3.*l2.^13.*l3.^2 - 2.50298198815176e+18*l1.^3.*l2.^13.*l3 + 2.60356449133687e+18*l1.^3.*l2.^13 - 9.69592853362292e+20*l1.^3.*l2.^12.*l3.^3 + 2.14197497062987e+18*l1.^3.*l2.^12.*l3.^2 - 7.3475320330573e+18*l1.^3.*l2.^12.*l3 - 3.71264248159538e+16*l1.^3.*l2.^12 + 1.42728392693868e+21*l1.^3.*l2.^11.*l3.^4 + 1.22742385957442e+19*l1.^3.*l2.^11.*l3.^3 + 1.58571431908151e+19*l1.^3.*l2.^11.*l3.^2 + 3.36662794300841e+15*l1.^3.*l2.^11.*l3 - 3.61175597734263e+16*l1.^3.*l2.^11 - 1.58656104587735e+21*l1.^3.*l2.^10.*l3.^5 - 2.28276770746341e+19*l1.^3.*l2.^10.*l3.^4 - 2.03264574079547e+19*l1.^3.*l2.^10.*l3.^3 + 1.58044478435672e+16*l1.^3.*l2.^10.*l3.^2 + 7.93746677371194e+16*l1.^3.*l2.^10.*l3 + 277899518631595.0*l1.^3.*l2.^10 + 1.60821529586853e+21*l1.^3.*l2.^9.*l3.^6 + 3.67986486527312e+19*l1.^3.*l2.^9.*l3.^5 + 2.22856736078574e+19*l1.^3.*l2.^9.*l3.^4 - 2.18830816295546e+17*l1.^3.*l2.^9.*l3.^3 - 1.51989469950011e+17*l1.^3.*l2.^9.*l3.^2 + 260903581391982.0*l1.^3.*l2.^9.*l3 + 362525003769116.0*l1.^3.*l2.^9 - 1.38571067029246e+21*l1.^3.*l2.^8.*l3.^7 - 2.41513694722143e+19*l1.^3.*l2.^8.*l3.^6 - 1.68001553479059e+19*l1.^3.*l2.^8.*l3.^5 + 2.25143243688687e+17*l1.^3.*l2.^8.*l3.^4 + 1.54254290595564e+17*l1.^3.*l2.^8.*l3.^3 - 304899318860752.0*l1.^3.*l2.^8.*l3.^2 - 340216051672859.0*l1.^3.*l2.^8.*l3 + 3008212240344.72*l1.^3.*l2.^8 + 1.28725845858113e+21*l1.^3.*l2.^7.*l3.^8 + 1.03557441597707e+19*l1.^3.*l2.^7.*l3.^7 + 1.33025357426657e+19*l1.^3.*l2.^7.*l3.^6 - 2.85041165841378e+17*l1.^3.*l2.^7.*l3.^5 - 1.53806526830009e+17*l1.^3.*l2.^7.*l3.^4 + 1.56825611304786e+15*l1.^3.*l2.^7.*l3.^3 + 890560420658822.0*l1.^3.*l2.^7.*l3.^2 + 5267618505338.0*l1.^3.*l2.^7.*l3 + 505203354448.948*l1.^3.*l2.^7 - 1.13386030292494e+21*l1.^3.*l2.^6.*l3.^9 + 1.53427982446803e+19*l1.^3.*l2.^6.*l3.^8 - 9.40494115888989e+18*l1.^3.*l2.^6.*l3.^7 + 2.74941282012353e+16*l1.^3.*l2.^6.*l3.^6 + 9.74550984676623e+16*l1.^3.*l2.^6.*l3.^5 - 726549742386951.0*l1.^3.*l2.^6.*l3.^4 - 343983546636952.0*l1.^3.*l2.^6.*l3.^3 - 11522350770038.2*l1.^3.*l2.^6.*l3.^2 - 2874732927724.74*l1.^3.*l2.^6.*l3 - 36156159561.0712*l1.^3.*l2.^6 + 1.04481396228959e+21*l1.^3.*l2.^5.*l3.^10 - 2.04329971917389e+19*l1.^3.*l2.^5.*l3.^9 + 1.07851712006297e+19*l1.^3.*l2.^5.*l3.^8 + 5.38660470881345e+16*l1.^3.*l2.^5.*l3.^7 - 9.42308314540547e+16*l1.^3.*l2.^5.*l3.^6 + 880930489891460.0*l1.^3.*l2.^5.*l3.^5 + 733548225584150.0*l1.^3.*l2.^5.*l3.^4 + 15588265568326.6*l1.^3.*l2.^5.*l3.^3 + 1020479119590.86*l1.^3.*l2.^5.*l3.^2 - 143431619674.414*l1.^3.*l2.^5.*l3 - 26021836024.4557*l1.^3.*l2.^5 - 7.95023847424998e+20*l1.^3.*l2.^4.*l3.^11 + 2.04209636244882e+19*l1.^3.*l2.^4.*l3.^10 - 1.05706586208749e+19*l1.^3.*l2.^4.*l3.^9 - 1.97088010830283e+17*l1.^3.*l2.^4.*l3.^8 + 7.63863823955901e+16*l1.^3.*l2.^4.*l3.^7 + 610330129851999.0*l1.^3.*l2.^4.*l3.^6 - 131141235801749.0*l1.^3.*l2.^4.*l3.^5 - 14058465125470.6*l1.^3.*l2.^4.*l3.^4 - 2769988593796.15*l1.^3.*l2.^4.*l3.^3 + 152809002196.729*l1.^3.*l2.^4.*l3.^2 + 25344745628.7104*l1.^3.*l2.^4.*l3 - 2441085.23815803*l1.^3.*l2.^4 + 5.25148988861926e+20*l1.^3.*l2.^3.*l3.^12 - 8.76043695853116e+18*l1.^3.*l2.^3.*l3.^11 + 1.01247778483681e+19*l1.^3.*l2.^3.*l3.^10 + 1.0848023371916e+17*l1.^3.*l2.^3.*l3.^9 - 8.60566148308146e+16*l1.^3.*l2.^3.*l3.^8 - 341572275864921.0*l1.^3.*l2.^3.*l3.^7 + 487666495745241.0*l1.^3.*l2.^3.*l3.^6 + 4840697451517.74*l1.^3.*l2.^3.*l3.^5 - 836364618712.507*l1.^3.*l2.^3.*l3.^4 - 126588249972.911*l1.^3.*l2.^3.*l3.^3 - 17046251777.3288*l1.^3.*l2.^3.*l3.^2 + 1133942721.80917*l1.^3.*l2.^3.*l3 + 175813993.269336*l1.^3.*l2.^3 - 2.48874740945517e+20*l1.^3.*l2.^2.*l3.^13 + 2.74365333316635e+18*l1.^3.*l2.^2.*l3.^12 - 6.39487674024328e+18*l1.^3.*l2.^2.*l3.^11 - 6.56492448886639e+16*l1.^3.*l2.^2.*l3.^10 + 5.98326652245744e+16*l1.^3.*l2.^2.*l3.^9 + 580566570544268.0*l1.^3.*l2.^2.*l3.^8 - 175974456348180.0*l1.^3.*l2.^2.*l3.^7 - 5101593651074.57*l1.^3.*l2.^2.*l3.^6 - 778433589080.987*l1.^3.*l2.^2.*l3.^5 + 78277411971.4942*l1.^3.*l2.^2.*l3.^4 + 9831221891.77146*l1.^3.*l2.^2.*l3.^3 - 792318705.597427*l1.^3.*l2.^2.*l3.^2 - 87559806.1733306*l1.^3.*l2.^2.*l3 - 50292.4186450479*l1.^3.*l2.^2 + 8.69061582107638e+19*l1.^3.*l2.*l3.^14 + 6.01678362536481e+17*l1.^3.*l2.*l3.^13 + 3.0341302167617e+18*l1.^3.*l2.*l3.^12 + 1.49627908578151e+15*l1.^3.*l2.*l3.^11 - 3.48677700849008e+16*l1.^3.*l2.*l3.^10 - 74763226356326.1*l1.^3.*l2.*l3.^9 + 230960249792333.0*l1.^3.*l2.*l3.^8 + 63247563528.9339*l1.^3.*l2.*l3.^7 - 783126459804.666*l1.^3.*l2.*l3.^6 - 1244331196.53146*l1.^3.*l2.*l3.^5 + 2765453359.00906*l1.^3.*l2.*l3.^4 + 210892708.95947*l1.^3.*l2.*l3.^3 + 9577487.64438719*l1.^3.*l2.*l3.^2 + 1907814.04499411*l1.^3.*l2.*l3 + 495519.055893047*l1.^3.*l2 - 1.5063557773862e+19*l1.^3.*l3.^15 - 3.07715505411514e+17*l1.^3.*l3.^14 - 6.74421831421232e+17*l1.^3.*l3.^13 + 1.54303780721219e+15*l1.^3.*l3.^12 + 8.93416379913129e+15*l1.^3.*l3.^11 + 40617809706067.2*l1.^3.*l3.^10 - 55717752031707.6*l1.^3.*l3.^9 - 1318598757500.46*l1.^3.*l3.^8 - 39295529374.3111*l1.^3.*l3.^7 + 16978065346.4884*l1.^3.*l3.^6 + 1793791354.22248*l1.^3.*l3.^5 - 167230328.455124*l1.^3.*l3.^4 - 12474972.0814594*l1.^3.*l3.^3 + 998428.179986113*l1.^3.*l3.^2 + 208274.648028393*l1.^3.*l3 - 1518.24103468548*l1.^3 - 1.45432786330216e+19*l1.^2.*l2.^16 + 6.90209566581104e+19*l1.^2.*l2.^15.*l3 - 8.20001654085432e+17*l1.^2.*l2.^15 - 2.14397615727157e+20*l1.^2.*l2.^14.*l3.^2 + 1.90817994975855e+18*l1.^2.*l2.^14.*l3 - 7.42062178732242e+17*l1.^2.*l2.^14 + 4.44916979110224e+20*l1.^2.*l2.^13.*l3.^3 - 3.03245894718386e+18*l1.^2.*l2.^13.*l3.^2 + 2.67668206805471e+18*l1.^2.*l2.^13.*l3 + 1.47757559720924e+16*l1.^2.*l2.^13 - 7.20349905829104e+20*l1.^2.*l2.^12.*l3.^4 - 9.3861824555691e+17*l1.^2.*l2.^12.*l3.^3 - 6.44446795162982e+18*l1.^2.*l2.^12.*l3.^2 - 2.01997676580504e+16*l1.^2.*l2.^12.*l3 + 1.18801149990525e+16*l1.^2.*l2.^12 + 8.84936193498399e+20*l1.^2.*l2.^11.*l3.^5 + 9.35008175381691e+18*l1.^2.*l2.^11.*l3.^4 + 9.96249974018226e+18*l1.^2.*l2.^11.*l3.^3 + 1.87970060151302e+16*l1.^2.*l2.^11.*l3.^2 - 3.50945996254184e+16*l1.^2.*l2.^11.*l3 - 132884843560036.0*l1.^2.*l2.^11 - 8.55817017771676e+20*l1.^2.*l2.^10.*l3.^6 - 2.40430673669578e+19*l1.^2.*l2.^10.*l3.^5 - 1.20390309860777e+19*l1.^2.*l2.^10.*l3.^4 + 6.78001460744748e+16*l1.^2.*l2.^10.*l3.^3 + 7.41253817120345e+16*l1.^2.*l2.^10.*l3.^2 + 50125613373814.9*l1.^2.*l2.^10.*l3 - 131835921800152.0*l1.^2.*l2.^10 + 5.67226509278647e+20*l1.^2.*l2.^9.*l3.^7 + 3.5559191225906e+19*l1.^2.*l2.^9.*l3.^6 + 1.04850214678596e+19*l1.^2.*l2.^9.*l3.^5 - 1.6622725468604e+17*l1.^2.*l2.^9.*l3.^4 - 9.49737455788176e+16*l1.^2.*l2.^9.*l3.^3 + 54625580078674.6*l1.^2.*l2.^9.*l3.^2 + 216266130057938.0*l1.^2.*l2.^9.*l3 - 2177711495435.08*l1.^2.*l2.^9 - 1.54898457917441e+20*l1.^2.*l2.^8.*l3.^8 - 4.36921636063634e+19*l1.^2.*l2.^8.*l3.^7 - 6.98564827417821e+18*l1.^2.*l2.^8.*l3.^6 + 3.07625628292393e+17*l1.^2.*l2.^8.*l3.^5 + 9.66673454517469e+16*l1.^2.*l2.^8.*l3.^4 - 799718492351793.0*l1.^2.*l2.^8.*l3.^3 - 463596337048906.0*l1.^2.*l2.^8.*l3.^2 - 216848789242.044*l1.^2.*l2.^8.*l3 - 384156755032.361*l1.^2.*l2.^8 - 2.6069584741182e+20*l1.^2.*l2.^7.*l3.^9 + 4.14487628546203e+19*l1.^2.*l2.^7.*l3.^8 + 1.95172672574023e+18*l1.^2.*l2.^7.*l3.^7 - 3.47323782787034e+17*l1.^2.*l2.^7.*l3.^6 - 6.08429818838026e+16*l1.^2.*l2.^7.*l3.^5 + 1.15564105574008e+15*l1.^2.*l2.^7.*l3.^4 + 356463622881877.0*l1.^2.*l2.^7.*l3.^3 + 4845215134626.94*l1.^2.*l2.^7.*l3.^2 + 1837083989603.9*l1.^2.*l2.^7.*l3 + 41916001903.7786*l1.^2.*l2.^7 + 4.99685137751365e+20*l1.^2.*l2.^6.*l3.^10 - 3.44400694715882e+19*l1.^2.*l2.^6.*l3.^9 + 2.117880279503e+18*l1.^2.*l2.^6.*l3.^8 + 3.58545875930395e+17*l1.^2.*l2.^6.*l3.^7 + 2.03603531047472e+16*l1.^2.*l2.^6.*l3.^6 - 1.70601887327222e+15*l1.^2.*l2.^6.*l3.^5 - 384767831236855.0*l1.^2.*l2.^6.*l3.^4 - 11366490702770.5*l1.^2.*l2.^6.*l3.^3 - 1937587252446.12*l1.^2.*l2.^6.*l3.^2 + 54032195874.1287*l1.^2.*l2.^6.*l3 + 17174440109.0361*l1.^2.*l2.^6 - 5.44355385002108e+20*l1.^2.*l2.^5.*l3.^11 + 2.16965217530655e+19*l1.^2.*l2.^5.*l3.^10 - 5.20180525917302e+18*l1.^2.*l2.^5.*l3.^9 - 2.63017808047532e+17*l1.^2.*l2.^5.*l3.^8 + 2.42596839044738e+16*l1.^2.*l2.^5.*l3.^7 + 1.39311173964534e+15*l1.^2.*l2.^5.*l3.^6 + 39222720467425.3*l1.^2.*l2.^5.*l3.^5 + 13222693750266.9*l1.^2.*l2.^5.*l3.^4 + 2597533604684.89*l1.^2.*l2.^5.*l3.^3 - 115722801277.425*l1.^2.*l2.^5.*l3.^2 - 26886884628.3508*l1.^2.*l2.^5.*l3 - 285862807.125258*l1.^2.*l2.^5 + 4.19553921981763e+20*l1.^2.*l2.^4.*l3.^12 - 1.08302105256567e+19*l1.^2.*l2.^4.*l3.^11 + 5.88697080816367e+18*l1.^2.*l2.^4.*l3.^10 + 1.72305888472027e+17*l1.^2.*l2.^4.*l3.^9 - 4.48190978004241e+16*l1.^2.*l2.^4.*l3.^8 - 1.21428235413806e+15*l1.^2.*l2.^4.*l3.^7 + 23548472418987.9*l1.^2.*l2.^4.*l3.^6 - 8402890583129.22*l1.^2.*l2.^4.*l3.^5 - 900846720460.408*l1.^2.*l2.^4.*l3.^4 + 161147304029.156*l1.^2.*l2.^4.*l3.^3 + 26388687797.1923*l1.^2.*l2.^4.*l3.^2 - 843421599.185767*l1.^2.*l2.^4.*l3 - 169781670.469847*l1.^2.*l2.^4 - 2.48874740945517e+20*l1.^2.*l2.^3.*l3.^13 + 2.74365333316635e+18*l1.^2.*l2.^3.*l3.^12 - 4.94180712821364e+18*l1.^2.*l2.^3.*l3.^11 - 6.56492448886638e+16*l1.^2.*l2.^3.*l3.^10 + 4.90351866108632e+16*l1.^2.*l2.^3.*l3.^9 + 580566570544267.0*l1.^2.*l2.^3.*l3.^8 - 218053606947860.0*l1.^2.*l2.^3.*l3.^7 + 4622719241498.37*l1.^2.*l2.^3.*l3.^6 + 1065171634252.93*l1.^2.*l2.^3.*l3.^5 - 117993385007.179*l1.^2.*l2.^3.*l3.^4 - 16049067895.702*l1.^2.*l2.^3.*l3.^3 + 940318825.451516*l1.^2.*l2.^3.*l3.^2 + 142115401.430832*l1.^2.*l2.^3.*l3 - 1435395.09608243*l1.^2.*l2.^3 + 1.06729366503797e+20*l1.^2.*l2.^2.*l3.^14 + 1.44402807008755e+17*l1.^2.*l2.^2.*l3.^13 + 2.84321098659083e+18*l1.^2.*l2.^2.*l3.^12 + 1.62720350578739e+16*l1.^2.*l2.^2.*l3.^11 - 3.28496454886624e+16*l1.^2.*l2.^2.*l3.^10 - 283934907046774.0*l1.^2.*l2.^2.*l3.^9 + 147867818709859.0*l1.^2.*l2.^2.*l3.^8 + 128753968612.474*l1.^2.*l2.^2.*l3.^7 - 105568720945.632*l1.^2.*l2.^2.*l3.^6 + 34020271476.3032*l1.^2.*l2.^2.*l3.^5 + 3787365355.03598*l1.^2.*l2.^2.*l3.^4 - 525611488.747147*l1.^2.*l2.^2.*l3.^3 - 91562090.2634901*l1.^2.*l2.^2.*l3.^2 - 2918609.21317163*l1.^2.*l2.^2.*l3 - 552955.986674505*l1.^2.*l2.^2 - 3.18799904842467e+19*l1.^2.*l2.*l3.^15 - 6.03397443572299e+17*l1.^2.*l2.*l3.^14 - 1.13527502438012e+18*l1.^2.*l2.*l3.^13 + 4.53559597877521e+15*l1.^2.*l2.*l3.^12 + 1.5496650111384e+16*l1.^2.*l2.*l3.^11 + 24082498979549.6*l1.^2.*l2.*l3.^10 - 109799833456568.0*l1.^2.*l2.*l3.^9 + 62682853140.2772*l1.^2.*l2.*l3.^8 + 351573298014.995*l1.^2.*l2.*l3.^7 - 14925560280.0448*l1.^2.*l2.*l3.^6 - 2832849975.46885*l1.^2.*l2.*l3.^5 + 256026136.463231*l1.^2.*l2.*l3.^4 + 46049913.2563688*l1.^2.*l2.*l3.^3 - 2436296.67370682*l1.^2.*l2.*l3.^2 - 373862.674243909*l1.^2.*l2.*l3 + 1017.37801293357*l1.^2.*l2 + 4.88997743188684e+18*l1.^2.*l3.^16 + 1.75346265653489e+17*l1.^2.*l3.^15 + 2.24608064443901e+17*l1.^2.*l3.^14 - 2.10414246438025e+15*l1.^2.*l3.^13 - 3.52641138772522e+15*l1.^2.*l3.^12 - 2669271588709.24*l1.^2.*l3.^11 + 28029115540460.7*l1.^2.*l3.^10 + 500709877937.361*l1.^2.*l3.^9 - 34791086885.9013*l1.^2.*l3.^8 - 6696297779.27236*l1.^2.*l3.^7 - 370033908.757795*l1.^2.*l3.^6 + 49248095.1977736*l1.^2.*l3.^5 - 3447912.4641*l1.^2.*l3.^4 - 774997.926661392*l1.^2.*l3.^3 - 126732.792475015*l1.^2.*l3.^2 - 375.647266313932*l1.^2.*l3 - 295.528747795414*l1.^2 + 2.73392656696369e+18*l1.*l2.^17 - 1.61381303512517e+19*l1.*l2.^16.*l3 + 1.87809603163173e+17*l1.*l2.^16 + 5.77346754029511e+19*l1.*l2.^15.*l3.^2 - 7.04823224685592e+17*l1.*l2.^15.*l3 + 1.38376140649056e+17*l1.*l2.^15 - 1.42062799779999e+20*l1.*l2.^14.*l3.^3 + 1.65547503749323e+18*l1.*l2.^14.*l3.^2 - 6.17390911463002e+17*l1.*l2.^14.*l3 - 3.8809738787458e+15*l1.*l2.^14 + 2.71351798953846e+20*l1.*l2.^13.*l3.^4 - 2.04570643262403e+18*l1.*l2.^13.*l3.^3 + 1.68121439009269e+18*l1.*l2.^13.*l3.^2 + 1.0848023371916e+16*l1.*l2.^13.*l3 - 2.55644402468979e+15*l1.*l2.^13 - 4.15778261693094e+20*l1.*l2.^12.*l3.^5 + 1.1973399414476e+18*l1.*l2.^12.*l3.^4 - 3.03394267015841e+18*l1.*l2.^12.*l3.^3 - 2.02465263794811e+16*l1.*l2.^12.*l3.^2 + 9.74826469964713e+15*l1.*l2.^12.*l3 + 41208356517728.6*l1.*l2.^12 + 5.38021820290143e+20*l1.*l2.^11.*l3.^6 + 1.2996252630788e+18*l1.*l2.^11.*l3.^5 + 4.14239887705173e+18*l1.*l2.^11.*l3.^4 + 1.30924420005882e+16*l1.*l2.^11.*l3.^3 - 2.36467189933819e+16*l1.*l2.^11.*l3.^2 - 75519126275252.5*l1.*l2.^11.*l3 + 31721628304785.1*l1.*l2.^11 - 6.03946374063737e+20*l1.*l2.^10.*l3.^7 - 3.15279461969116e+18*l1.*l2.^10.*l3.^6 - 4.28956029003474e+18*l1.*l2.^10.*l3.^5 + 6.07863378598739e+15*l1.*l2.^10.*l3.^4 + 3.75109943555686e+16*l1.*l2.^10.*l3.^3 + 100475634536061.0*l1.*l2.^10.*l3.^2 - 79139587491454.3*l1.*l2.^10.*l3 + 918972039131.651*l1.*l2.^10 + 6.15564570195812e+20*l1.*l2.^9.*l3.^8 + 2.92587592296312e+18*l1.*l2.^9.*l3.^7 + 3.61726865003955e+18*l1.*l2.^9.*l3.^6 - 3.32922096586387e+16*l1.*l2.^9.*l3.^5 - 4.62126609203732e+16*l1.*l2.^9.*l3.^4 + 46771307483578.5*l1.*l2.^9.*l3.^3 + 175394755576466.0*l1.*l2.^9.*l3.^2 - 1211115546860.52*l1.*l2.^9.*l3 + 154477977691.472*l1.*l2.^9 - 5.81099713632707e+20*l1.*l2.^8.*l3.^9 + 5.80189849588751e+16*l1.*l2.^8.*l3.^8 - 2.62534967903943e+18*l1.*l2.^8.*l3.^7 + 3.10010323085357e+16*l1.*l2.^8.*l3.^6 + 4.42815225011058e+16*l1.*l2.^8.*l3.^5 - 175746731150415.0*l1.*l2.^8.*l3.^4 - 216777451061012.0*l1.*l2.^8.*l3.^3 + 154165936101.767*l1.*l2.^8.*l3.^2 - 780950530502.358*l1.*l2.^8.*l3 - 23844336201.5757*l1.*l2.^8 + 5.15088985412317e+20*l1.*l2.^7.*l3.^10 - 2.89493246431838e+18*l1.*l2.^7.*l3.^9 + 2.12993660217547e+18*l1.*l2.^7.*l3.^8 - 8.97767451468906e+15*l1.*l2.^7.*l3.^7 - 3.84515107713215e+16*l1.*l2.^7.*l3.^6 + 278572741996889.0*l1.*l2.^7.*l3.^5 + 260556073615919.0*l1.*l2.^7.*l3.^4 + 3139789760900.44*l1.*l2.^7.*l3.^3 + 1314127627147.0*l1.*l2.^7.*l3.^2 + 8222848422.43982*l1.*l2.^7.*l3 - 7013685730.78637*l1.*l2.^7 - 4.16287374153702e+20*l1.*l2.^6.*l3.^11 + 3.87480865473494e+18*l1.*l2.^6.*l3.^10 - 2.14492182523317e+18*l1.*l2.^6.*l3.^9 - 2.38469479296429e+16*l1.*l2.^6.*l3.^8 + 3.25219956418282e+16*l1.*l2.^6.*l3.^7 - 117884954543837.0*l1.*l2.^6.*l3.^6 - 218720092022610.0*l1.*l2.^6.*l3.^5 - 5886541091299.68*l1.*l2.^6.*l3.^4 - 1721991772892.03*l1.*l2.^6.*l3.^3 + 23661534969.0955*l1.*l2.^6.*l3.^2 + 16631849878.7107*l1.*l2.^6.*l3 + 282739497.19172*l1.*l2.^6 + 2.97545892179622e+20*l1.*l2.^5.*l3.^12 - 2.38264631564446e+18*l1.*l2.^5.*l3.^11 + 2.34726453478493e+18*l1.*l2.^5.*l3.^10 + 2.99255817156303e+16*l1.*l2.^5.*l3.^9 - 3.04760238616368e+16*l1.*l2.^5.*l3.^8 - 23527384976588.0*l1.*l2.^5.*l3.^7 + 212222845526626.0*l1.*l2.^5.*l3.^6 + 5919294293841.45*l1.*l2.^5.*l3.^5 + 1166543899852.83*l1.*l2.^5.*l3.^4 - 70606174285.661*l1.*l2.^5.*l3.^3 - 22521087545.8015*l1.*l2.^5.*l3.^2 + 146273238.593907*l1.*l2.^5.*l3 + 95174173.2946861*l1.*l2.^5 - 1.78731385994021e+20*l1.*l2.^4.*l3.^13 + 4.99393040905279e+17*l1.*l2.^4.*l3.^12 - 2.14900060332646e+18*l1.*l2.^4.*l3.^11 - 1.93113519508676e+16*l1.*l2.^4.*l3.^10 + 2.69922354651375e+16*l1.*l2.^4.*l3.^9 + 136770641580768.0*l1.*l2.^4.*l3.^8 - 162487747005174.0*l1.*l2.^4.*l3.^7 - 4380458484767.05*l1.*l2.^4.*l3.^6 - 709297040166.974*l1.*l2.^4.*l3.^5 + 72681128626.2689*l1.*l2.^4.*l3.^4 + 19010100432.6372*l1.*l2.^4.*l3.^3 - 419664125.506742*l1.*l2.^4.*l3.^2 - 130085556.36366*l1.*l2.^4.*l3 + 933295.375511379*l1.*l2.^4 + 8.69061582107638e+19*l1.*l2.^3.*l3.^14 + 6.01678362536481e+17*l1.*l2.^3.*l3.^13 + 1.54079932196986e+18*l1.*l2.^3.*l3.^12 + 1.49627908578151e+15*l1.*l2.^3.*l3.^11 - 2.06537736591318e+16*l1.*l2.^3.*l3.^10 - 74763226356326.1*l1.*l2.^3.*l3.^9 + 137470230085127.0*l1.*l2.^3.*l3.^8 + 2055545814690.22*l1.*l2.^3.*l3.^7 + 70884935646.9212*l1.*l2.^3.*l3.^6 - 42230291742.0778*l1.*l2.^3.*l3.^5 - 10163983182.3598*l1.*l2.^3.*l3.^4 + 492949981.45581*l1.*l2.^3.*l3.^3 + 126723595.908864*l1.*l2.^3.*l3.^2 + 2600365.3837128*l1.*l2.^3.*l3 + 261782.979075489*l1.*l2.^3 - 3.18799904842467e+19*l1.*l2.^2.*l3.^15 - 6.03397443572299e+17*l1.*l2.^2.*l3.^14 - 7.90660202505082e+17*l1.*l2.^2.*l3.^13 + 4.53559597877521e+15*l1.*l2.^2.*l3.^12 + 1.16201056316289e+16*l1.*l2.^2.*l3.^11 + 24082498979549.6*l1.*l2.^2.*l3.^10 - 79506147552689.1*l1.*l2.^2.*l3.^9 - 1111350044865.48*l1.*l2.^2.*l3.^8 + 20754215389.0623*l1.*l2.^2.*l3.^7 + 22019530915.9406*l1.*l2.^2.*l3.^6 + 4132365326.62467*l1.*l2.^2.*l3.^5 - 338308830.582628*l1.*l2.^2.*l3.^4 - 63016429.3897232*l1.*l2.^2.*l3.^3 + 1199597.8545663*l1.*l2.^2.*l3.^2 + 325780.359265791*l1.*l2.^2.*l3 + 782.598471487359*l1.*l2.^2 + 8.08746815850928e+18*l1.*l2.*l3.^16 + 2.81929289874237e+17*l1.*l2.*l3.^15 + 2.73352319214813e+17*l1.*l2.*l3.^14 - 3.74069771445378e+15*l1.*l2.*l3.^13 - 4.51318637103606e+15*l1.*l2.*l3.^12 + 11291255038964.9*l1.*l2.*l3.^11 + 38044664332564.4*l1.*l2.*l3.^10 + 275202196069.331*l1.*l2.*l3.^9 - 96684452347.8451*l1.*l2.*l3.^8 - 4323088796.19691*l1.*l2.*l3.^7 - 361040735.196614*l1.*l2.*l3.^6 + 64917943.6697925*l1.*l2.*l3.^5 + 10203643.5350815*l1.*l2.*l3.^4 + 1032231.28104262*l1.*l2.*l3.^3 + 56951.7643216409*l1.*l2.*l3.^2 + 2660.83480305702*l1.*l2.*l3 + 459.60352733686*l1.*l2 - 1.07310327735902e+18*l1.*l3.^17 - 5.62999039230564e+16*l1.*l3.^16 - 4.77555967941239e+16*l1.*l3.^15 + 935174428613445.0*l1.*l3.^14 + 887676066772980.0*l1.*l3.^13 - 3933041765664.56*l1.*l3.^12 - 8642994760908.27*l1.*l3.^11 - 145507043475.782*l1.*l3.^10 + 20614471264.2962*l1.*l3.^9 + 2889542288.85268*l1.*l3.^8 + 126245785.161734*l1.*l3.^7 - 32608208.4870107*l1.*l3.^6 - 165784.905880862*l1.*l3.^5 + 371834.111621583*l1.*l3.^4 + 65122.0031789578*l1.*l3.^3 - 172.171663727219*l1.*l3.^2 + 124.263844797178*l1.*l3 - 1.07851851851852*l1 - 2.67167722233334e+17*l2.^18 + 1.92897054519174e+18*l2.^17.*l3 - 2.19182832066861e+16*l2.^17 - 7.94325636050451e+18*l2.^16.*l3.^2 + 1.15178429399841e+17*l2.^16.*l3 - 1.27311322420115e+16*l2.^16 + 2.23589262858673e+19*l2.^15.*l3.^3 - 3.42097126127885e+17*l2.^15.*l3.^2 + 6.87509481280438e+16*l2.^15.*l3 + 514345935737395.0*l2.^15 - 4.73332066262277e+19*l2.^14.*l3.^4 + 5.98240200464844e+17*l2.^14.*l3.^3 - 2.14217656137318e+17*l2.^14.*l3.^2 - 2.18430027254712e+15*l2.^14.*l3 + 272912195565257.0*l2.^14 + 7.75486271057916e+19*l2.^13.*l3.^5 - 5.35493742657468e+17*l2.^13.*l3.^4 + 4.5101923310251e+17*l2.^13.*l3.^3 + 5.28373552166597e+15*l2.^13.*l3.^2 - 1.30692482323831e+15*l2.^13.*l3 - 6389716502175.74*l2.^13 - 9.91535086159477e+19*l2.^12.*l3.^6 - 3.85074152023348e+17*l2.^12.*l3.^5 - 7.17847552365456e+17*l2.^12.*l3.^4 - 6.31242739314076e+15*l2.^12.*l3.^3 + 3.69072100415127e+15*l2.^12.*l3.^2 + 20952600877744.5*l2.^12.*l3 - 3868133983246.51*l2.^12 + 9.53176070260235e+19*l2.^11.*l3.^7 + 2.31044491214009e+18*l2.^11.*l3.^6 + 8.94354350266748e+17*l2.^11.*l3.^5 - 1.75157894736842*l2.^11.*l3.^4 - 6.96759908934595e+15*l2.^11.*l3.^3 - 39129631740680.6*l2.^11.*l3.^2 + 13463655934938.7*l2.^11.*l3 - 184848533885.146*l2.^11 - 5.94735919891829e+19*l2.^10.*l3.^8 - 4.68621490364128e+18*l2.^10.*l3.^7 - 9.04668631069648e+17*l2.^10.*l3.^6 + 1.80488664722395e+16*l2.^10.*l3.^5 + 9.81515654400127e+15*l2.^10.*l3.^4 + 19204582315226.9*l2.^10.*l3.^3 - 32806261322078.5*l2.^10.*l3.^2 + 502215772307.097*l2.^10.*l3 - 28971737164.9813*l2.^10 + 2.35364723070691e+18*l2.^9.*l3.^9 + 6.30172130705173e+18*l2.^9.*l3.^8 + 7.35596722411776e+17*l2.^9.*l3.^7 - 4.20360905661744e+16*l2.^9.*l3.^6 - 1.03041594753966e+16*l2.^9.*l3.^5 + 62716071398434.7*l2.^9.*l3.^4 + 49430659862753.5*l2.^9.*l3.^3 - 656381708408.863*l2.^9.*l3.^2 + 174728736226.272*l2.^9.*l3 + 5923401340.18968*l2.^9 + 5.18074456144522e+19*l2.^8.*l3.^10 - 6.2763648617734e+18*l2.^8.*l3.^9 - 4.49228874098923e+17*l2.^8.*l3.^8 + 6.01784744812752e+16*l2.^8.*l3.^7 + 7.84929422680759e+15*l2.^8.*l3.^6 - 204022112492761.0*l2.^8.*l3.^5 - 57011445350207.4*l2.^8.*l3.^4 + 7905945441.11829*l2.^8.*l3.^3 - 427682017080.249*l2.^8.*l3.^2 - 9563390793.96081*l2.^8.*l3 + 1394995325.26474*l2.^8 - 8.16872045020224e+19*l2.^7.*l3.^11 + 4.64839512085327e+18*l2.^7.*l3.^10 + 1.1782593587141e+17*l2.^7.*l3.^9 - 6.05191451659844e+16*l2.^7.*l3.^8 - 3.17529027518842e+15*l2.^7.*l3.^7 + 317371667523039.0*l2.^7.*l3.^6 + 40872006038479.1*l2.^7.*l3.^5 + 1323681150998.31*l2.^7.*l3.^4 + 711066208478.877*l2.^7.*l3.^3 + 3880517391.245*l2.^7.*l3.^2 - 4771507378.61872*l2.^7.*l3 - 93784576.0930762*l2.^7 + 8.09910501475175e+19*l2.^6.*l3.^12 - 2.43078058464738e+18*l2.^6.*l3.^11 + 1.61627884319423e+17*l2.^6.*l3.^10 + 4.44207853591387e+16*l2.^6.*l3.^9 - 1.57074631680427e+15*l2.^6.*l3.^8 - 340651022838730.0*l2.^6.*l3.^7 - 13936248592083.6*l2.^6.*l3.^6 - 2435031195863.79*l2.^6.*l3.^5 - 783572091623.875*l2.^6.*l3.^4 + 18177497994.6914*l2.^6.*l3.^3 + 8557607532.40784*l2.^6.*l3.^2 + 51976993.9792952*l2.^6.*l3 - 24528909.2331638*l2.^6 - 5.99261363986121e+19*l2.^5.*l3.^13 + 6.67862982415494e+17*l2.^5.*l3.^12 - 3.14895838726707e+17*l2.^5.*l3.^11 - 2.20233577938466e+16*l2.^5.*l3.^10 + 4.62178664090049e+15*l2.^5.*l3.^9 + 254336700846307.0*l2.^5.*l3.^8 - 15975132279905.2*l2.^5.*l3.^7 + 2516914202218.21*l2.^5.*l3.^6 + 657396904466.805*l2.^5.*l3.^5 - 37185619133.4593*l2.^5.*l3.^4 - 9384259839.63769*l2.^5.*l3.^3 + 100766719.45986*l2.^5.*l3.^2 + 49932620.9665331*l2.^5.*l3 - 309999.170664557*l2.^5 + 3.42489429236059e+19*l2.^4.*l3.^14 + 1.68469941510215e+17*l2.^4.*l3.^13 + 3.13381254107917e+17*l2.^4.*l3.^12 + 5.56428785025e+15*l2.^4.*l3.^11 - 5.09948628446207e+15*l2.^4.*l3.^10 - 134054126247125.0*l2.^4.*l3.^9 + 28950474141616.7*l2.^4.*l3.^8 - 1613942290765.01*l2.^4.*l3.^7 - 388258028623.077*l2.^4.*l3.^6 + 37220896564.2888*l2.^4.*l3.^5 + 6513389443.02209*l2.^4.*l3.^4 - 278646149.019437*l2.^4.*l3.^3 - 60387886.1068865*l2.^4.*l3.^2 - 179733.561715089*l2.^4.*l3 - 58480.3954101073*l2.^4 - 1.5063557773862e+19*l2.^3.*l3.^15 - 3.07715505411514e+17*l2.^3.*l3.^14 - 2.14156724591291e+17*l2.^3.*l3.^13 + 1.54303780721219e+15*l2.^3.*l3.^12 + 3.75659129045642e+15*l2.^3.*l3.^11 + 40617809706067.2*l2.^3.*l3.^10 - 27651095127585.1*l2.^3.*l3.^9 + 661840575499.157*l2.^3.*l3.^8 + 190519983597.678*l2.^3.*l3.^7 - 22276094049.2461*l2.^3.*l3.^6 - 2823342845.53622*l2.^3.*l3.^5 + 265929054.307112*l2.^3.*l3.^4 + 35877703.2036274*l2.^3.*l3.^3 - 1079225.83616996*l2.^3.*l3.^2 - 30157.0196180896*l2.^3.*l3 - 344.343327454438*l2.^3 + 4.88997743188684e+18*l2.^2.*l3.^16 + 1.75346265653489e+17*l2.^2.*l3.^15 + 1.01364482846411e+17*l2.^2.*l3.^14 - 2.10414246438025e+15*l2.^2.*l3.^13 - 1.90897288724357e+15*l2.^2.*l3.^12 - 2669271588709.24*l2.^2.*l3.^11 + 16179181976486.1*l2.^2.*l3.^10 - 100141975587.472*l2.^2.*l3.^9 - 68555233798.358*l2.^2.*l3.^8 + 6580844369.28491*l2.^2.*l3.^7 + 598579991.568613*l2.^2.*l3.^6 - 111927489.085849*l2.^2.*l3.^5 - 11003017.9773948*l2.^2.*l3.^4 + 90691.2467369713*l2.^2.*l3.^3 - 125167.59553204*l2.^2.*l3.^2 - 2253.8835978836*l2.^2.*l3 - 189.877954144621*l2.^2 - 1.07310327735902e+18*l2.*l3.^17 - 5.62999039230564e+16*l2.*l3.^16 - 3.13231192477919e+16*l2.*l3.^15 + 935174428613445.0*l2.*l3.^14 + 638839374391187.0*l2.*l3.^13 - 3933041765664.54*l2.*l3.^12 - 6407006190186.25*l2.*l3.^11 - 11105970976.8061*l2.*l3.^10 + 25338181078.4774*l2.*l3.^9 - 862693535.739591*l2.*l3.^8 - 92938334.8302317*l2.*l3.^7 + 27832635.6193478*l2.*l3.^6 + 2279131.18383814*l2.*l3.^5 - 61010.4750775989*l2.*l3.^4 + 65122.0031789578*l2.*l3.^3 + 297.387419165197*l2.*l3.^2 - 87.0377425044091*l2.*l3 - 1.07851851851852*l2 + 1.22417180883999e+17*l3.^18 + 8.59540517909258e+15*l3.^17 + 4.87005506469132e+15*l3.^16 - 173675251028211.0*l3.^15 - 108496888712493.0*l3.^14 + 1133849878389.78*l3.^13 + 1263160281743.8*l3.^12 + 16188364474.6665*l3.^11 - 4813343897.58701*l3.^10 - 327117994.964454*l3.^9 - 3115221.47301489*l3.^8 + 1257851.78210764*l3.^7 - 529026.507136675*l3.^6 - 159121.914729414*l3.^5 - 32717.5212837764*l3.^4 - 93.9118165784833*l3.^3 - 20.6673721340388*l3.^2 - 0.616296296296297*l3 - 0.221703703703704
end
end


text:
function fib(n)
    if n < 2
        return n
    end
    return fib(n-1) + fib(n-2)
end

print(fib(5))

max_stars_repo_name: nguyenphuminh/Fibonacci

max_issues_repo_name: nguyenphuminh/Fibonacci

max_forks_repo_name: nguyenphuminh/Fibonacci


text:
#=
# dReLU layer

In this example we look at what the dReLU layer hidden units look like,
for different parameter values.
=#

#=
First load some packages.
=#

import RestrictedBoltzmannMachines as RBMs
import Makie
import CairoMakie
using Statistics
nothing #hide

#=
Now initialize our dReLU layer, with unit parameters spanning an interesting range.
=#

θps = [-3.0; 3.0]
θns = [-3.0; 3.0]
γps = [0.5; 1.0]
γns = [0.5; 1.0]
layer = RBMs.dReLU(
    [θp for θp in θps, θn in θns, γp in γps, γn in γns],
    [θn for θp in θps, θn in θns, γp in γps, γn in γns],
    [γp for θp in θps, θn in θns, γp in γps, γn in γns],
    [γn for θp in θps, θn in θns, γp in γps, γn in γns]
)
nothing #hide

#=
Now we sample our layer to collect some data.
=#

data = RBMs.sample_from_inputs(layer, zeros(size(layer)..., 10^6))
nothing #hide

#=
Let's plot the resulting histogram of the activations of each unit.
We also overlay the analytical PDF.
=#

fig = Makie.Figure(resolution=(1000, 700))
xs = repeat(reshape(range(minimum(data), maximum(data), 100), 1,1,1,1,100), size(layer)...)
ps = exp.(RBMs.free_energies(layer) .- RBMs.energies(layer, xs))
for (iθp, θp) in enumerate(θps), (iθn, θn) in enumerate(θns)
    ax = Makie.Axis(fig[iθp,iθn], title="θp=$θp, θn=$θn", xlabel="h", ylabel="P(h)")
    for (iγp, γp) in enumerate(γps), (iγn, γn) in enumerate(γns)
        Makie.hist!(ax, data[iθp, iθn, iγp, iγn, :], normalization=:pdf, bins=30, label="γp=$γp, γn=$γn")
        Makie.lines!(ax, xs[iθp, iθn, iγp, iγn, :], ps[iθp, iθn, iγp, iγn, :], linewidth=2)
    end
    if iθp == iθn == 1
        Makie.axislegend(ax)
    end
end
fig


text:
#
# @description Unit tests for MD5 hash algorithm.
#
# @author Alejandro Claro (alejandro.claro@gmail.com)
#
# Copyright 2015 All rights reserved.
# Use of this source code is governed by a MIT-style license that can be found in the LICENSE file.
#
@testset "MD5 hasher tests" begin
  @test MD5_DIGEST_SIZE          == 16
  @test digest_size(Md5Hasher()) == 16

  hasher = Md5Hasher()
  update!(hasher, "")
  @test digest(hasher) == [ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e ]

  hasher = Md5Hasher()
  update!(hasher, "abc")
  reset!(hasher)
  update!(hasher, "")
  @test hexdigest(hasher) == "d41d8cd98f00b204e9800998ecf8427e"

  hasher = Md5Hasher()
  update!(hasher, [ 0x00, 0x01, 0x02 ])
  @test hexdigest(hasher) == "b95f67f61ebb03619622d798f45fc2d3"
  update!(hasher, [ 0x03, 0x04, 0x05 ])
  @test hexdigest(hasher) == "d15ae53931880fd7b724dd7888b4b4ed"

  @test digest(Md5Hasher(), "a") == [ 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 ]

  @test hexdigest(Md5Hasher(), "abc")                        == "900150983cd24fb0d6963f7d28e17f72"
  @test hexdigest(Md5Hasher(), "message digest")             == "f96b697d7cb7938d525a2f31aaf161d0"
  @test hexdigest(Md5Hasher(), "abcdefghijklmnopqrstuvwxyz") == "c3fcd3d76192e4007dfb496cca67e13b"

  @test hexdigest(Md5Hasher(), "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") == "d174ab98d277d9f5a5611c2c9f419d9f"
end


text:
@enum(QOS::UInt8,
AT_MOST_ONCE = 0x00,
AT_LEAST_ONCE = 0x01,
EXACTLY_ONCE = 0x02)

@enum(PacketType::UInt8,
CONNECT = 0x10,
CONNACK = 0x20,
PUBLISH = 0x30,
PUBACK = 0x40,
PUBREC = 0x50,
PUBREL = 0x60,
PUBCOMP = 0x70,
SUBSCRIBE = 0x80,
SUBACK = 0x90,
UNSUBSCRIBE = 0xA0,
UNSUBACK = 0xB0,
PINGREQ = 0xC0,
PINGRESP = 0xD0,
DISCONNECT = 0xE0)

abstract type Packet end
function write(s::IO, packet::Packet) end
read(s::IO, flags::UInt8, t::Type{<: Packet}) = t()
has_id(packet::Packet) = false
needs_id(packet::Packet) = false

abstract type HasId <: Packet end
has_id(packet::HasId) = true
needs_id(packet::HasId) = true

abstract type Ack <: HasId end
write(s::IO, packet::Ack) = mqtt_write(s, packet.id)
read(s::IO, flags::UInt8, t::Type{<: Ack}) = t(mqtt_read(s, UInt16))
needs_id(packet::Ack) = false

struct Message
    dup::Bool
    qos::QOS
    retain::Bool
    topic::String
    payload::Array{UInt8}
end
Base.show(io::IO, x::Message) = print(io, "[dup: ", x.dup,
    ", qos: ", x.qos, ", retain: ", x.retain, ", topic: ", x.topic, "]")

max_issues_repo_name: kivaari/jlMQTT

max_forks_repo_name: kivaari/jlMQTT


text:
struct stateVariables
"""
Defines the state to be passed to the Bellman
"""
    states::Vector{Float64}
    controls::Vector{Float64}
    exog_states::Dict{Symbol,Float64}
    mparams::Dict{Symbol,Any}
    space::Dict{Symbol,Any}
    opts::Dict{Symbol,Bool}
    space_terminal::Dict{Symbol,Any}
    node::Int64
end

struct simParameters
"""
Defines the initial parameters to be passed to the simulator
"""
    states::Array{Float64}
    exog_states::Dict{Symbol,Array{Float64}}
    mparams::Dict{Symbol,Any}
    space::Dict{Symbol,Any}
    opts::Dict{Symbol,Bool}
    coefficients::Array{Vector{Float64}}
    dam_exponent::Float64
    dam_coefficient::Vector{Float64}
    smax::Array{Float64}
    smin::Array{Float64}
end

struct taxParameters
"""
Defines the parameters to be passed to the tax calculator
"""
    states::Array{Float64}
    controls::Vector{Vector{Float64}}
    exog_states::Dict{Symbol,Array{Float64}}
    mparams::Dict{Symbol,Any}
    space::Dict{Symbol,Any}
    opts::Dict{Symbol,Bool}
    coefficients::Array{Vector{Float64}}
    smax::Array{Float64}
    smin::Array{Float64}
    loc_next::Vector{Array{Float64}}
    dam_next::Vector{Array{Float64}}
end

max_stars_repo_name: irudik/optimal-climate-policy-aej

max_issues_repo_name: irudik/optimal-climate-policy-aej

max_forks_repo_name: irudik/optimal-climate-policy-aej


text:
#================================================

Node-specific code

=================================================#

#===========================
Node constructors
===========================#

function Node{T,M}(
    vals,
    height;
    flags = 0x0,
    capacity = DEFAULT_NODE_CAPACITY,
    max_height = DEFAULT_MAX_HEIGHT
) where {T,M}

    height = min(height, max_height)
    next = Vector{Node{T,M}}(undef, height)
    Node{T,M}(vals, next, capacity, flags)
end

LeftSentinel{T,M}(; max_height = DEFAULT_MAX_HEIGHT, kws...) where {T,M} =
    Node{T,M}(Vector{T}(undef,0), max_height; flags = FLAG_IS_LEFT_SENTINEL, kws...)

RightSentinel{T,M}(; max_height = DEFAULT_MAX_HEIGHT, kws...) where {T,M} =
    Node{T,M}(Vector{T}(undef,0), max_height; flags = FLAG_IS_RIGHT_SENTINEL, kws...)

#===========================
Node external API
===========================#

function Base.string(node::Node)
    result = "$(node.vals), height = $(height(node))"
    "Node($result)"
end

Base.length(node::Node) = length(node.vals)

key(node::Node) = node.vals[1]

capacity(node::Node) = node.capacity
Base.isempty(node::Node) = (length(node) == 0)
isfull(node::Node) = is_sentinel(node) || (length(node) == capacity(node))

Base.in(val, node::Node) =
    searchsorted(node.vals, val) |>
    idx -> first(idx) ≤ last(idx)

@generated function Base.insert!(node::Node{T,M}, val) where {T,M}
    quote
        if length(node) ≥ capacity(node)
            "Node size exceeds capacity ($(capacity(node)))" |>
            ErrorException |>
            throw
        end

        idx = searchsorted(node.vals, val)

        $(
            if M == :Set
                quote
                    if first(idx) > last(idx)     # Value not found in node
                        insert!(node.vals, first(idx), val)
                    end
                end
            else
                quote
                    insert!(node.vals, first(idx), val)
                end
            end
        )
    end
end

Base.delete!(node::Node, val) =
    searchsorted(node.vals, val) |>
    idx -> if first(idx) ≤ last(idx)
        deleteat!(node.vals, first(idx))
    end

function split!(node::Node{T,M}; kws...) where {T,M}
    median_idx = div(length(node), 2)
    right_vals = splice!(node.vals, median_idx+1:length(node))
    node, Node{T,M}(right_vals; kws...)
end

"""
Insert a new node between a list of predecessor and successor nodes
"""
function interpolate_node!(predecessors, successors, node)
    for level = 1:height(node)
        link_nodes!(predecessors[level], node, level)
        link_nodes!(node, successors[level], level)
    end
end


text:
function trapz(values, dx)

    (sum(values) - values[1]/2 - values[end]/2)*dx

end

function trapz(values, dx, dy)

    temp = zeros(size(values, 1))
    for i = 1:size(values, 1)
      temp[i] = trapz(values[i, :], dy)
    end
    trapz(temp, dx)

end

function trapz(values, dx, dy, dz)

    temp = zeros(size(values, 1));
    for i = 1:size(values, 1)
        temp[i] = trapz(values[i, :, :], dy, dz)
    end
    trapz(temp, dx)

end

function trapz(values, dx, dy, dz, dw)

    temp = zeros(size(values, 1))
    for i = 1:size(values, 1)
        temp[i] = trapz(values[i, :, :, :], dy, dz, dw)
    end
    trapz(temp, dx)

end

function trapz(values, dx, dy, dz, dw, dv)

    temp = zeros(size(values, 1))
    for i = 1:size(values, 1)
      temp[i] = trapz(values[i, :, :, :, :], dy, dz, dw, dv)
    end
    trapz(temp, dx)

end


text:
using Genie.Renderer, Genie.Requests

greeting = "Welcome"
name = "Genie"

function htmlviewfile_withvars()
  raw"

$(@vars(:greeting))

This is a $(@vars(:name)) test

  "
end

function htmltemplatefile_withvars()
  raw"
  <!DOCTYPE HTML>

    <title>$(@vars(:name)) test</title>

    <% @yield %>

    Just a footer

  "
end

@testset "String HTML rendering with vars" begin
  r = Requests.HTTP.Response()

  @testset "String no layout with vars" begin
    r = html(htmlviewfile_withvars(), greeting = greeting, name = name)

    @test String(r.body) == "
$greeting

This is a $name test

"
  end;

  @testset "String with layout with vars" begin
    r = html(htmlviewfile_withvars(), layout = htmltemplatefile_withvars(), greeting = "Welcome", name = "Genie")

    @test String(r.body) == "<title>$name test</title>

$greeting

This is a $name test

\n
Just a footer"
  end;

  @test r.status == 200
  @test r.headers[1]["Content-Type"] == "text/html; charset=utf-8"
end;


text:
#
# Structure to contain DCD trajectories produces with Namd.
#

import FortranFiles

"""

$(TYPEDEF)

Structure to contain the data of a trajectory in NAMD/DCD format.

$(TYPEDFIELDS)

"""
struct NamdDCD{T<:AbstractVector} <: Trajectory

  #
  # Mandatory data for things to work
  #
  filename::String
  stream::FortranFile # special type of stream required for reading DCD files
  nframes::Int64

  # This vector must be filled up with the size of the periodic cell, if it
  # is not defined in the DCD file.
  sides::Vector{T}

  # Data structures of the solute and solvent
  solute::Selection
  solvent::Selection

  # Coordinates of the solute and solvent atoms in a frame (3,natoms) for each array:
  x_solute::Vector{T}
  x_solvent::Vector{T}

  #
  # Additional properties that might be required for implementing IO (not necessary for every
  # input/output format)
  #
  sides_in_dcd::Bool # if the DCD contains, or not, periodic cell information for each frame
  lastatom::Int64 # The last atom to be read from each line

  # Auxiliary vectors to read the coordinates without having the allocate/deallocate every time
  sides_read::Vector{Float64}
  x_read::Vector{Float32}
  y_read::Vector{Float32}
  z_read::Vector{Float32}

end

"""

```
NamdDCD(filename::String, solute::Selection, solvent::Selection;T::Type = SVector{3,Float64})
```

This function initializes the structure above, returning the data and the vectors with
appropriate lengths and, importantly, with the i/o stream OPENED, ready to read the first
trajectory frame using the "nextframe" function.

"""
function NamdDCD(filename::String, solute::Selection, solvent::Selection;
                  T::Type = SVector{3,Float64})

  stream = FortranFile(filename)

  # Read header
  IntVec = Vector{Int32}(undef,17)
  hdr, read_nframes, IntVec[1:8], ts, IntVec[9:17] = read(stream, FString{4}, Int32, (Int32,8), Float64, (Int32,9))
  dummyi, title = read(stream, Int32, FString{80})
  read_natoms = read(stream,Int32)

  # Check if dcd file contains axis information
  sides_in_dcd = false
  x = 0.
  try
    x = read(stream, [ Float32 for i in 1:read_natoms ])
  catch err
    sides_in_dcd = true
  end

  # rewind and let it ready to read first frame in the first call to nextframe
  firstframe(stream)

  nframes = getnframes(stream,sides_in_dcd)
  lastatom = max(maximum(solute.index),maximum(solvent.index))

  # Most commonly the sides of the box are written in each frame of the DCD file, and will
  # be updated upon reading the frame. Alternatively, the user must provide the sides in all
  # frames by filling up an array with the box side data.
  if sides_in_dcd
    sides = zeros(T,1)
  else
    sides = zeros(T,nframes)
  end

  return NamdDCD(filename, stream, nframes,
                 sides, # sides vector (if in dcd) or array to be filled up later
                 solute, solvent,
                 zeros(T,solute.natoms), # solute atom coordinates
                 zeros(T,solvent.natoms), # solvent atom coordinates
                 sides_in_dcd, lastatom,
                 Vector{Float64}(undef,6), # auxiliary vector to read sides
                 Vector{Float32}(undef,lastatom), # auxiliary x
                 Vector{Float32}(undef,lastatom), # auxiliary y
                 Vector{Float32}(undef,lastatom)  # auxiliary z
                )

end

function Base.show(io::IO, traj::NamdDCD )
  println(" Trajectory in NamdDCD format containing: ")
  println("     $(traj.nframes) frames ")
  println("     Sides in DCD: $(traj.sides_in_dcd) ")
end

#
# Function that reads the coordinates of the solute and solvent atoms from
# the next frame of the trajectory file
#
# The function modifies sides, x_solute and x_solvent within the trajectory structure.
# Having these vectors inside the trajectory structure avoids having to allocate
# them everytime a new frame is read
#

function nextframe!(trajectory::NamdDCD{T}) where T

  # Read the sides of the box from the DCD file, otherwise they must be set manually before
  if trajectory.sides_in_dcd
    read(trajectory.stream,trajectory.sides_read)
    trajectory.sides[1] = T(trajectory.sides_read[1],
                            trajectory.sides_read[3],
                            trajectory.sides_read[6])
  end

  # Read the coordinates
  read(trajectory.stream,trajectory.x_read)
  read(trajectory.stream,trajectory.y_read)
  read(trajectory.stream,trajectory.z_read)

  # Save coordinates of solute and solvent in trajectory arrays
  for i in 1:trajectory.solute.natoms
    trajectory.x_solute[i] = T(trajectory.x_read[trajectory.solute.index[i]],
                               trajectory.y_read[trajectory.solute.index[i]],
                               trajectory.z_read[trajectory.solute.index[i]])
  end
  for i in 1:trajectory.solvent.natoms
    trajectory.x_solvent[i] = T(trajectory.x_read[trajectory.solvent.index[i]],
                                trajectory.y_read[trajectory.solvent.index[i]],
                                trajectory.z_read[trajectory.solvent.index[i]])
  end

  nothing
end

#
# Function that closes the IO Stream of the trajectory
#

function closetraj(trajectory::NamdDCD)
  FortranFiles.close(trajectory.stream)
end

#
# Function that returns a vector of dimension 3 with the sides of the periodic box
# given the way that the box side information is stored in the Trajectory structure
#

function getsides(trajectory::NamdDCD, iframe)
  # In this (most common) case, sides is a vector and must only be returned
  if trajectory.sides_in_dcd
    return trajectory.sides[1]
  # otherwise, sides is an array that contains the sides for each frame, and we return the
  # vector containing the sides of the current frame
  else
    return trajectory.sides[iframe]
  end
end

#
# Leave DCD file in position to read the first frame
#

function firstframe(stream::FortranFile)
    # rewind
    rewind(stream)
    # skip header
    read(stream)
    read(stream)
    read(stream)
end
firstframe(trajectory::NamdDCD) = firstframe(trajectory.stream)

#
# Auxiliary functions
#

#
# Sometimes the DCD files contains a wrong number of frames in the header, so to
# get the actual number of frames, it is better to read it
#

function getnframes(stream::FortranFile, sides_in_dcd::Bool)
  firstframe(stream)
  nframes = 0
  while true
    try
      if sides_in_dcd
        read(stream,Float64)
      end
      read(stream,Float32)
      read(stream,Float32)
      read(stream,Float32)
      nframes = nframes + 1
    catch
      firstframe(stream)
      return nframes
    end
  end
end