text:
function simulate_NDARMA(
    N::Int,
    p::Int,
    q::Int,
    prob::Vector{Float64},
    phi::Vector{Float64},
)
    X = zeros(Int64, N)
    X[1:p] = rand(Categorical(prob), p)
    d1 = Multinomial(1, phi)
    d2 = Categorical(prob)
    for t = (p+1):N
        alphabeta = rand(d1)
        eps = rand(d2, q + 1)
        X[t] = sum([X[(t-p):(t-1)]; eps] .* alphabeta)
    end
    return X
end

@testset "discretediag" begin
    Random.seed!(123)

    n = 10000
    x1 = simulate_NDARMA(n, 1, 0, [0.25, 0.5, 0.05, 0.2], [0.8, 0.2])
    x2 = simulate_NDARMA(n, 1, 0, [0.25, 0.5, 0.05, 0.2], [0.8, 0.2])
    x3 = simulate_NDARMA(n, 1, 0, [0.25, 0.5, 0.05, 0.2], [0.8, 0.2])

    sim = Chains(cat(x1, x2, x3, dims = 3))
    discretediag(sim)

    res = MCPhylo.weiss(hcat(x1, x2, x3))
    @test res[3] > 0.05

    x1 = simulate_NDARMA(n, 1, 0, [0.25, 0.5, 0.05, 0.2], [0.8, 0.2])
    x2 = simulate_NDARMA(n, 1, 0, [0.75, 0.15, 0.05, 0.05], [0.8, 0.2])
    x3 = simulate_NDARMA(n, 1, 0, [0.25, 0.5, 0.05, 0.2], [0.8, 0.2])
    res = MCPhylo.weiss(hcat(x1, x2, x3))
    @test res[3] < 0.05
end

max_stars_repo_name: erathorn/MCPhylo

max_issues_repo_name: erathorn/MCPhylo

max_forks_repo_name: erathorn/MCPhylo


text:
using JuMP, EAGO

                     m = Model()

                     EAGO.register_eago_operators!(m)

                     @variable(m, -1 <= x[i=1:2] <= 1)

                     @variable(m, -29.23432407510253 <= q <= 25.005662503891426)

                     add_NL_constraint(m, :(softplus(-0.9584800931585375 + 0.8291526833328144*softplus(0.45833851557375827 + -0.07893784992449904*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.05269389376863742*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.9157122134504139*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.14234137821989812*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + -0.47308336785041494*softplus(0.8182392255084516 + 0.5838043616725095*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.4648893036822681*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.819336300807536*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.1444146117738878*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + 0.6108443940953072*softplus(-0.7015763069538381 + -0.6574215519391942*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.13767395548269734*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.21605537563661414*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.3991258949611094*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + -0.4993930565410927*softplus(-0.21931284624450997 + 0.9567749529797225*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.8630566689068395*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.8170122079846647*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.11471605851894884*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))))) + softplus(0.475745519197857 + -0.20728788527253217*softplus(0.45833851557375827 + -0.07893784992449904*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.05269389376863742*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.9157122134504139*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.14234137821989812*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + 0.5536591664216424*softplus(0.8182392255084516 + 0.5838043616725095*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.4648893036822681*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.819336300807536*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.1444146117738878*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + 0.5772469178059145*softplus(-0.7015763069538381 + -0.6574215519391942*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.13767395548269734*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.21605537563661414*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.3991258949611094*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + 0.14258534816037427*softplus(-0.21931284624450997 + 0.9567749529797225*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.8630566689068395*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.8170122079846647*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.11471605851894884*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))))) + softplus(-0.19885854025662475 + 0.9363781836864602*softplus(0.45833851557375827 + -0.07893784992449904*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.05269389376863742*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.9157122134504139*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.14234137821989812*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + -0.2868856241387201*softplus(0.8182392255084516 + 0.5838043616725095*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.4648893036822681*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.819336300807536*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.1444146117738878*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + 0.6989952318088708*softplus(-0.7015763069538381 + -0.6574215519391942*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.13767395548269734*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.21605537563661414*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.3991258949611094*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + 0.2430276118759056*softplus(-0.21931284624450997 + 0.9567749529797225*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.8630566689068395*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.8170122079846647*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.11471605851894884*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))))) + softplus(-0.4748268724301301 + -0.943475605090133*softplus(0.45833851557375827 + -0.07893784992449904*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.05269389376863742*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.9157122134504139*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.14234137821989812*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + -0.504486324487766*softplus(0.8182392255084516 + 0.5838043616725095*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.4648893036822681*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.819336300807536*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.1444146117738878*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + -0.8621266685661562*softplus(-0.7015763069538381 + -0.6574215519391942*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.13767395548269734*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.21605537563661414*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.3991258949611094*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2])))) + -0.8772206856506037*softplus(-0.21931284624450997 + 0.9567749529797225*softplus(-0.22994750449881307 + -0.3590609593879259*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.10337862983418544*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.321850031280575*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.612120130564894*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.8630566689068395*softplus(0.19384674006188307 + -0.9239566552941776*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + -0.4571782009479768*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + -0.7401514915717242*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.3444562251116623*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + 0.8170122079846647*softplus(0.4065836733363821 + 0.7200826994240335*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.11568748742914314*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.5958961905666036*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + -0.0402986153245215*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))) + -0.11471605851894884*softplus(-0.18406387526761447 + 0.28290146144347617*softplus(-0.9795230057859095 + -0.9823842606294351*$(x[1]) + 0.3621989809961321*$(x[2])) + 0.5991916639069861*softplus(0.2857383741568795 + 0.17154081707188507*$(x[1]) + -0.2093148258397095*$(x[2])) + 0.7799932719867426*softplus(-0.5451083144913764 + -0.518481685587207*$(x[1]) + 0.024249687825614874*$(x[2])) + 0.858692422726886*softplus(-0.02703791931361943 + -0.7859299073841055*$(x[1]) + 0.7832525238663837*$(x[2]))))) - $q <= 0.0))

                     @objective(m, Min, q)

                     return m

ext: jl

max_stars_repo_name: PSORLab/RSActivationFunctions

max_issues_repo_name: PSORLab/RSActivationFunctions

max_forks_repo_name: PSORLab/RSActivationFunctions


text:
# Copyright (c) 2017: Miles Lubin and contributors
# Copyright (c) 2017: Google Inc.
#
# Use of this source code is governed by an MIT-style license that can be found
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.

"""
    SingleBridgeOptimizer{BT<:AbstractBridge}(model::MOI.ModelLike)

Return `AbstractBridgeOptimizer` that always bridges any objective function
supported by the bridge `BT`.

This is in contrast with the [`MathOptInterface.Bridges.LazyBridgeOptimizer`](@ref),
which only bridges the objective function if it is supported by the bridge `BT`
and unsupported by `model`.

## Example

```jldoctest con_singlebridgeoptimizer; setup=:(using MathOptInterface; const MOI = MathOptInterface)
julia> struct MyNewBridge{T} <: MOI.Bridges.Constraint.AbstractBridge end

julia> bridge = MOI.Bridges.Constraint.SingleBridgeOptimizer{MyNewBridge{Float64}}(
           MOI.Utilities.Model{Float64}(),
       )
MOIB.Constraint.SingleBridgeOptimizer{MyNewBridge{Float64}, MOIU.Model{Float64}}
with 0 constraint bridges
with inner model MOIU.Model{Float64}
```

## Implementation notes

All bridges should simplify the creation of `SingleBridgeOptimizer`s by defining
a constant that wraps the bridge in a `SingleBridgeOptimizer`.
```jldoctest con_singlebridgeoptimizer
julia> const MyNewBridgeModel{T,OT<:MOI.ModelLike} =
           MOI.Bridges.Constraint.SingleBridgeOptimizer{MyNewBridge{T},OT};
```
This enables users to create bridged models as follows:
```jldoctest con_singlebridgeoptimizer
julia> MyNewBridgeModel{Float64}(MOI.Utilities.Model{Float64}())
MOIB.Constraint.SingleBridgeOptimizer{MyNewBridge{Float64}, MOIU.Model{Float64}}
with 0 constraint bridges
with inner model MOIU.Model{Float64}
```
"""
mutable struct SingleBridgeOptimizer{BT<:AbstractBridge,OT<:MOI.ModelLike} <:
               MOI.Bridges.AbstractBridgeOptimizer
    model::OT
    map::Map # index of bridged constraint -> constraint bridge
    con_to_name::Dict{MOI.ConstraintIndex,String}
    name_to_con::Union{Dict{String,MOI.ConstraintIndex},Nothing}
end

function SingleBridgeOptimizer{BT}(model::OT) where {BT,OT<:MOI.ModelLike}
    return SingleBridgeOptimizer{BT,OT}(
        model,
        Map(),
        Dict{MOI.ConstraintIndex,String}(),
        nothing,
    )
end

bridges(::MOI.Bridges.AbstractBridgeOptimizer) = EmptyMap()

bridges(bridge::SingleBridgeOptimizer) = bridge.map

MOI.Bridges.supports_constraint_bridges(::SingleBridgeOptimizer) = true

# If `BT` bridges `MOI.Reals` (such as `Constraint.FunctionizeBridge` bridge,
# without this method, it creates a `StackOverflow` with `is_bridged`,
# `supports_bridging_constrained_variable` and `supports_add_constrained_variables`.
MOI.Bridges.is_bridged(::SingleBridgeOptimizer, ::Type{MOI.Reals}) = false

function MOI.Bridges.is_bridged(
    b::SingleBridgeOptimizer,
    S::Type{<:MOI.AbstractSet},
)
    return MOI.Bridges.supports_bridging_constrained_variable(b, S)
end

MOI.Bridges.is_bridged(::SingleBridgeOptimizer, ::MOI.VariableIndex) = false

function MOI.Bridges.is_bridged(
    b::SingleBridgeOptimizer,
    ci::MOI.ConstraintIndex{MOI.VariableIndex,S},
) where {S}
    return MOI.Bridges.is_bridged(b, MOI.VariableIndex, S) &&
           haskey(Constraint.bridges(b), ci)
end
function MOI.Bridges.is_bridged(
    b::SingleBridgeOptimizer,
    ci::MOI.ConstraintIndex{MOI.VectorOfVariables,S},
) where {S}
    return MOI.Bridges.is_bridged(b, MOI.VectorOfVariables, S) &&
           haskey(Constraint.bridges(b), ci)
end

function MOI.Bridges.supports_bridging_constrained_variable(
    b::SingleBridgeOptimizer,
    S::Type{<:MOI.AbstractSet},
)
    F = MOI.Utilities.variable_function_type(S)
    return MOI.Bridges.supports_bridging_constraint(b, F, S) &&
           MOI.supports_add_constrained_variables(b, MOI.Reals)
end

function MOI.Bridges.supports_bridging_constraint(
    ::SingleBridgeOptimizer{BT},
    F::Type{<:MOI.AbstractFunction},
    S::Type{<:MOI.AbstractSet},
) where {BT}
    return MOI.supports_constraint(BT, F, S)
end

function MOI.Bridges.is_bridged(
    b::SingleBridgeOptimizer,
    F::Type{<:MOI.AbstractFunction},
    S::Type{<:MOI.AbstractSet},
)
    return MOI.Bridges.supports_bridging_constraint(b, F, S)
end

function MOI.Bridges.is_bridged(
    ::SingleBridgeOptimizer,
    ::Type{<:MOI.AbstractScalarFunction},
)
    return false
end

function MOI.Bridges.bridge_type(
    ::SingleBridgeOptimizer{BT},
    ::Type{<:MOI.AbstractFunction},
    ::Type{<:MOI.AbstractSet},
) where {BT}
    return BT
end

MOI.Bridges.bridging_cost(::SingleBridgeOptimizer, args...) = 1.0

MOI.Bridges.recursive_model(b::SingleBridgeOptimizer) = b.model


text:
# Things are starting to get complicated enough that I feel like I need some tests for
# this ...
import AutoTM.Profiler: nodes, unx
import AutoTM.Utils: IOConfig, DRAM, PMEM, inputs, outputs

function merge_cb(data)
    node = nodes(data)[findfirst(x -> nGraph.description(unx(x)) == "Add", nodes(data))]
    io = vcat(inputs(node), outputs(node))
    merge!(io)

    # Test that all elements in "io" belong to the same group.
    @test isone(length(unique(map(x -> x.group, io))))
    return nothing
end

@testset "Testing Paired Parameters" begin
    backend = nGraph.Backend("CPU")
    cache = AutoTM.Profiler.CPUKernelCache(joinpath(@__DIR__, "cache.bin"); force_new = true)
    # First - test two of the same inputs to a node
    x = nGraph.parameter(Float32, (10, 10))
    f = x -> x + x
    fex = nGraph.compile(backend, f, x)

    # The code should generate such that the input is used twice for the sum.
    # We need to:
    # 1. Find the "Add" node in the compiled graph.
    # 2. Get a list of configs for it.
    # 3. Verify that the inputs to the add node don't vary since they come from the same
    #    input tensor
    data = AutoTM.Profiler.profile(fex; recache = true, cache = cache)
    node = nodes(data)[findfirst(x -> nGraph.description(unx(x)) == "Add", nodes(data))]

    # Now - we check the possible configs for the `Add` node
    configs = sort(AutoTM.Profiler.possible_configs(node))
    expected = [
        IOConfig((DRAM, DRAM), (DRAM,)),
        IOConfig((DRAM, DRAM), (PMEM,)),
        IOConfig((PMEM, PMEM), (DRAM,)),
        IOConfig((PMEM, PMEM), (PMEM,)),
    ]
    @test configs == expected

    # Next - we'll do the same things - but this time we'll mark the output of the addition
    # as belonging to the same group as the input - this should result in all inputs or
    # outputs as being in PMEM or DRAM.
    fex = nGraph.compile(backend, +, x, x)

    # Add a profiling callback to do the merging
    data = AutoTM.Profiler.profile(fex; recache = true, cache = cache, cb = merge_cb)
    node = nodes(data)[findfirst(x -> nGraph.description(unx(x)) == "Add", nodes(data))]

    # Now - we check the possible configs for the `Add` node
    configs = sort(AutoTM.Profiler.possible_configs(node))
    expected = [
        IOConfig((DRAM, DRAM), (DRAM,)),
        IOConfig((PMEM, PMEM), (PMEM,)),
    ]
    @test configs == expected
end

function test_embedding()
    context_size = 2
    embedding_dim = 10
    vocab = 96
    embedding_param = Flux.param(randn(Float32, embedding_dim, length(vocab)))

    f = function(x)
        a = reshape(embedding(x, embedding_param), :)
        # Mark the embedding parameter as an inplace update node.
        nGraph.__inplace(embedding_param)
        return softmax(a)
    end

    loss(a, b) = Flux.crossentropy(f(a), b)

    # Construct inputs and output placeholders
    inputs = zeros(Int32, context_size)
    expected = randn(Float32, embedding_dim * context_size)

    backend = nGraph.Backend("CPU")
    F = nGraph.compile(
        backend,
        loss,
        inputs,
        expected;
        optimizer = nGraph.SGD(Float32(0.01))
    )
    return F
end

@testset "Test `inplace` annotation" begin
    backend = nGraph.Backend("CPU")
    cache = AutoTM.Profiler.CPUKernelCache(joinpath(@__DIR__, "cache.bin"); force_new = true)

    # Use the `test_embedding` from nGraph.jl to generate an embedding table with backprop.
    fex = test_embedding()
    data = AutoTM.Profiler.profile(fex; recache = true, cache = cache)

    # Find the embedding backprop node in the graph
    ind = findfirst(x -> nGraph.description(unx(x)) == "EmbeddingLookupBackprop", nodes(data))
    node = nodes(data)[ind]

    println("Displaying Embedding Backprop Timings")
    display(node.timings)
    println()

    # Because of the inplace annotation - there should be only 8 entries for the
    # 4 inputs/outputs of the node since one input/output pair are joined.
    @test length(node.timings) == 8
end

max_stars_repo_name: darchr/AutoTM

max_issues_repo_name: darchr/AutoTM

max_forks_repo_name: darchr/AutoTM


text:
f = 1
@show f + 2


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

using Markdown
using InteractiveUtils

# ╔═╡ 9820cc3a-fe50-11ea-3fb6-991358edb7ff
using Pkg, DrWatson

# ╔═╡ 98210cc2-fe50-11ea-0fec-cfe81a89d0cb
begin
  using Distributions
  using StatsPlots
  using StatsBase
  using LaTeXStrings
  using CSV
  using DataFrames
  using LinearAlgebra
  using Random
	using StanSample, GLM
	using StatisticalRethinking
end

# ╔═╡ c5f141c2-fe4f-11ea-03d2-e5eb5d2349f6
md"## Clip-09-30s.jl"

# ╔═╡ 9831d8b8-fe50-11ea-38fd-c99a2b5fd0bc
md"### Snippet 6.1"

# ╔═╡ 98328740-fe50-11ea-3008-27d3dda98cd2
begin
	N = 100
	df = DataFrame(
		height = rand(Normal(10, 2), N),
		leg_prop = rand(Uniform(0.4, 0.5), N),
	)
	df.leg_left = df.leg_prop .* df.height + rand(Normal(0, 0.02), N)
	df.leg_right = df.leg_prop .* df.height + rand(Normal(0, 0.02), N)
end;

# ╔═╡ 9842396a-fe50-11ea-217d-2bba5fa44fb5
md"### Snippet 6.2"

# ╔═╡ 9842dbb8-fe50-11ea-158e-cbc2873c64bd
stan6_1 = "
data {
  int <lower=1> N;
  vector[N] H;
  vector[N] LL;
  vector[N] LR;
}
parameters {
  real a;
  real bL;
  real bR;
  real <lower=0> sigma;
}
model {
  vector[N] mu;
  mu = a + bL * LL + bR * LR;
  a ~ normal(10, 100);
  bL ~ normal(2, 10);
  bR ~ normal(2, 10);
  sigma ~ exponential(1);
  H ~ normal(mu, sigma);
}
";

# ╔═╡ 239f66a6-840f-11eb-3858-a3ae035d21f7
stan6_2 = "
data {
  int <lower=1> N;
  vector[N] H;
  vector[N] LL;
  vector[N] LR;
}
parameters {
  real a;
  real bL;
  real <lower=0> bR;
  real <lower=0> sigma;
}
model {
  vector[N] mu;
  mu = a + bL * LL + bR * LR;
  a ~ normal(10, 100);
  bL ~ normal(2, 10);
  bR ~ normal(2, 10);
  sigma ~ exponential(1);
  H ~ normal(mu, sigma);
}
";

# ╔═╡ 9851b4a8-fe50-11ea-083b-17e3c182a55a
begin
	m6_1s = SampleModel("m6.1s", stan6_1,
		method=StanSample.Sample(num_samples=1000))
	data = (H = df.height, LL = df.leg_left, LR = df.leg_right, N = size(df, 1))
	rc6_1s = stan_sample(m6_1s; data)
	if success(rc6_1s)
		post6_1s_df = read_samples(m6_1s, :dataframe)
	end
	m6_2s = SampleModel("m6.2s", stan6_2,
		method=StanSample.Sample(num_samples=1000))
	rc6_2s = stan_sample(m6_2s; data)

	if success(rc6_2s)
		post6_2s_df = read_samples(m6_2s, :dataframe)
	end
end;

# ╔═╡ 64b0dad4-8410-11eb-1986-815525832db2
md"
```
rethinking simulation:
> precis(m5.8s)
      mean   sd  5.5% 94.5% n_eff Rhat4
a     0.97 0.29  0.52  1.43  1034     1
bl    0.18 2.52 -3.90  4.18   532     1
br    1.81 2.53 -2.18  5.94   530     1
sigma 0.64 0.05  0.57  0.71  1100     1
> precis(m5.8s2)
       mean   sd  5.5% 94.5% n_eff Rhat4
a      0.95 0.29  0.48  1.42   479  1.02
bl    -1.13 2.06 -4.65  1.75   377  1.00
br     3.13 2.06  0.28  6.64   379  1.00
sigma  0.64 0.04  0.57  0.71   773  1.00
```
"

# ╔═╡ 81b75f90-8410-11eb-3910-396d9d0ebdeb
success(rc6_1s) && PRECIS(post6_1s_df)

# ╔═╡ 4903312c-840f-11eb-0973-a91f30c64a1a
success(rc6_2s) && PRECIS(post6_2s_df)

# ╔═╡ 6aac1dd2-840f-11eb-1e9c-6392658b0a67
if success(rc6_1s) && success(rc6_2s)
	(s2, p2) = plot_model_coef([m6_1s, m6_2s], [:a, :bL, :bR, :sigma];
		title="Multicollinearity between bL and bR, bR > 0")
	p2
end

# ╔═╡ ebb2b764-8418-11eb-06d9-53ff20d9a4bb
trankplot(m6_1s, :bL)[1]

# ╔═╡ 297c0caa-8419-11eb-2842-1d9dcab60688
trankplot(m6_2s, :bL)[1]

# ╔═╡ 9862bdb4-fe50-11ea-1402-bbac3257c25d
md"## End of clip-06-02-06s.jl"

# ╔═╡ Cell order:
# ╟─c5f141c2-fe4f-11ea-03d2-e5eb5d2349f6
# ╠═9820cc3a-fe50-11ea-3fb6-991358edb7ff
# ╠═98210cc2-fe50-11ea-0fec-cfe81a89d0cb
# ╟─9831d8b8-fe50-11ea-38fd-c99a2b5fd0bc
# ╠═98328740-fe50-11ea-3008-27d3dda98cd2
# ╟─9842396a-fe50-11ea-217d-2bba5fa44fb5
# ╠═9842dbb8-fe50-11ea-158e-cbc2873c64bd
# ╠═239f66a6-840f-11eb-3858-a3ae035d21f7
# ╠═9851b4a8-fe50-11ea-083b-17e3c182a55a
# ╟─64b0dad4-8410-11eb-1986-815525832db2
# ╠═81b75f90-8410-11eb-3910-396d9d0ebdeb
# ╠═4903312c-840f-11eb-0973-a91f30c64a1a
# ╠═6aac1dd2-840f-11eb-1e9c-6392658b0a67
# ╠═ebb2b764-8418-11eb-06d9-53ff20d9a4bb
# ╠═297c0caa-8419-11eb-2842-1d9dcab60688
# ╟─9862bdb4-fe50-11ea-1402-bbac3257c25d


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

mutable struct IoK8sApiCoreV1Lifecycle <: SwaggerModel
    postStart::Any # spec type: Union{ Nothing, IoK8sApiCoreV1Handler } # spec name: postStart
    preStop::Any # spec type: Union{ Nothing, IoK8sApiCoreV1Handler } # spec name: preStop

    function IoK8sApiCoreV1Lifecycle(;postStart=nothing, preStop=nothing)
        o = new()
        validate_property(IoK8sApiCoreV1Lifecycle, Symbol("postStart"), postStart)
        setfield!(o, Symbol("postStart"), postStart)
        validate_property(IoK8sApiCoreV1Lifecycle, Symbol("preStop"), preStop)
        setfield!(o, Symbol("preStop"), preStop)
        o
    end
end # type IoK8sApiCoreV1Lifecycle

const _property_map_IoK8sApiCoreV1Lifecycle = Dict{Symbol,Symbol}(Symbol("postStart")=>Symbol("postStart"), Symbol("preStop")=>Symbol("preStop"))
const _property_types_IoK8sApiCoreV1Lifecycle = Dict{Symbol,String}(Symbol("postStart")=>"IoK8sApiCoreV1Handler", Symbol("preStop")=>"IoK8sApiCoreV1Handler")
Base.propertynames(::Type{ IoK8sApiCoreV1Lifecycle }) = collect(keys(_property_map_IoK8sApiCoreV1Lifecycle))
Swagger.property_type(::Type{ IoK8sApiCoreV1Lifecycle }, name::Symbol) = Union{Nothing,eval(Meta.parse(_property_types_IoK8sApiCoreV1Lifecycle[name]))}
Swagger.field_name(::Type{ IoK8sApiCoreV1Lifecycle }, property_name::Symbol) =  _property_map_IoK8sApiCoreV1Lifecycle[property_name]

function check_required(o::IoK8sApiCoreV1Lifecycle)
    true
end

function validate_property(::Type{ IoK8sApiCoreV1Lifecycle }, name::Symbol, val)
end


text:
module EffectSizes

using Statistics
using Distributions
using StatsBase

import Distributions: quantile
import StatsBase: confint

export
    AbstractEffectSize,
    EffectSize,
    CohenD,
    HedgeG,
    GlassΔ,
    effectsize,
    confint,
    quantile,
    AbstractConfidenceInterval,
    ConfidenceInterval,
    BootstrapConfidenceInterval,
    lower,
    upper

"""
    _update_module_doc()

This function updates the module docs and is called before running the doctests.
This way, the docs in README.md are also tested.
"""
function _update_module_doc()
    path = joinpath(@__DIR__, "..", "README.md")
    text = read(path, String)
    # The code blocks in the README.md should be julia blocks the syntax highlighter.
    text = replace(text, "```julia" => "```jldoctest")
    @doc text EffectSizes
end
_update_module_doc()

include("confidence_interval.jl")
include("effect_size.jl")

end # module


text:
using Random

function preparedata(N::Int)
    A = Array{Float64}(undef, N,N)
    b = rand(N);
    c = rand(N);
    A, b, c
end

function bench1!(A, b, c)
    col  = size(A)[2]
    for i in 1:col
        A[1, i] = b[i] * c[i]
    end
end

function bench2!(A, b, c)
    row = size(A)[1]
    for i in 1:row
        A[i, 1] = b[i] * c[i]
    end
end

function main(N)
    Random.seed!(1234);
    A, b, c = preparedata(N)
    @time bench1!(A, b, c)
    @time bench2!(A, b, c)
end

max_stars_repo_name: terasakisatoshi/juliaExer

max_issues_repo_name: terasakisatoshi/juliaExer

max_forks_repo_name: terasakisatoshi/juliaExer


text:
using NNlib, XConv, LinearAlgebra, BenchmarkTools, CUDA
initXConv(0, "TrueGrad")
BenchmarkTools.DEFAULT_PARAMETERS.samples=10

# CUDA
CUDA.allowscalar(false)
# BLAS param
nthreads = div(Sys.CPU_THREADS, 2)
BLAS.set_num_threads(nthreads)

#
cuda = ARGS["CUDA"]

sizes = [2^i for i=5:10]
batchsizes = [2^i for i=2:6]
channels = [4, 32]
ps = [4, 8, 16, 32]
nw   = 3;

t_nnlib = zeros(length(sizes), length(batchsizes), length(channels))
t_ev = zeros(length(sizes), length(batchsizes), length(channels), length(ps))

for (i,s)=enumerate(sizes)
    for (j, b)=enumerate(batchsizes)
        for (k, c)=enumerate(channels)
            # X/Y
            X = randn(Float32, s, s, c, b)
            Y0 = randn(Float32, s, s, c, b)
            w = randn(Float32, 3, 3, c, c)
            # conv
            cdims = NNlib.DenseConvDims(X, w;padding=1)
            Δ = conv(X, w, cdims) - Y0
            g1 = ∇conv_filter(X, Δ, cdims)
            # NNlib
            t_nnlib[i,j,k] = 1f-6*mean(@benchmark g1 = ∇conv_filter($X, $Δ, $cdims)).time
            for (l, p)=enumerate(ps)
                g2 = grad_ev(X, Δ, p, nw, 1)
                tt = @elapsed begin
                    # with memory
                    t_ev[i,j,k,l] = 1f-6*mean(@benchmark g2 = grad_ev($X, $Δ, $p, $nw, 1)).time
                end
                @info "CPU: $(tt)sec for $p probing vector, $c channels, batchise of $b and image size of $s x $s"
                @info "NNlib: $(t_nnlib[i,j,k])ms, EV: $(t_ev[i,j,k,l])ms"
            end
        end
    end
end

colrs = ["--*r", "--*k", "--*c", "--*g"]
count = 1
for (i,c)=enumerate(channels)
    for (k, b)=enumerate(batchsizes)
        # Remove ot of memory point
        (c==32 && b == 64) ? li = length(sizes)-1 : li=length(sizes)
        figure(count, figsize=(10, 5))
        global count +=1
        xlabel("N_x")
        ylabel("Runtime (ms)")
        for (l,p)=enumerate(ps)
            loglog(sizes[1:li], t_ev[1:li, k, i, l], label="probe-$p", colrs[l], markersize=3, linewidth=1,basex=2, basey=10)
        end
        loglog(sizes[1:li], t_nnlib[1:li, k, i], "--ob", label="NNlib", markersize=3, linewidth=1,basex=2, basey=10)
        legend(loc="upper left")
        tight_layout()
        savefig("./paper/figures/runtimes/bench_gpu_$(c)_$(b).png", bbox_inches="tight")
    end
end

max_stars_repo_name: sheevy/XConv

max_issues_repo_name: sheevy/XConv

max_forks_repo_name: sheevy/XConv


text:
Base.flush(sock::ClickHouseSock) = Base.flush(sock.io)

function Base.close(sock::ClickHouseSock)
    @guarded sock begin
        !isnothing(sock.io) && Base.close(sock.io)
        sock.io = nothing
        sock.busy = false
    end
end

"""
    connect!(sock::ClickHouseSock; force = false)

Connects `sock` to ClickHouse server using connection settings from `sock.settings`
If `force = false` and `sock` already connected then existing connection is used
If `force = true` then `sock` then the socket is closed and a new connection is created
"""
function connect!(sock::ClickHouseSock; force = false)
    force && is_connected(sock) && close(sock)
    is_connected(sock) && return sock

    try
        set_busy!(sock, true)
        tcp = Sockets.TCPSocket()
        Base.buffer_writes(tcp, sock.settings.send_buffer_size)
        Sockets.connect!(tcp, sock.settings.host, sock.settings.port)

        timeout = Ref{Bool}(false)
        @async begin
            sleep(sock.settings.connection_timeout)
            if tcp.status == Sockets.StatusConnecting
                timeout[] = true
                tcp.status = Base.StatusClosing
                #force close of stream. Normal close will wait for handing of connecting process what we don't need
                ccall(:jl_forceclose_uv, Nothing, (Ptr{Nothing},), tcp.handle)
            end
        end
        try
            Sockets.wait_connected(tcp)
        catch e
            if timeout[]
                error("Connection timeout")
            end
            rethrow(e)
        end

        hello = @guarded sock begin
            sock.io = tcp
            ClientHello(
                CLIENT_NAME,
                DBMS_VER_MAJOR,
                DBMS_VER_MINOR,
                DBMS_VER_REV,
                sock.settings.database,
                sock.settings.username,
                sock.settings.password
            )

        end

        write_packet(sock, hello)
        info = read_packet(sock, ServerCodes)::ServerInfo
        @guarded sock begin
            sock.server_name = isempty(info.server_display_name) ?
                            info.server_name : info.server_display_name
            sock.server_rev = UInt64(info.server_rev)
            sock.server_timezone = info.server_timezone
            sock.busy = false
        end
    catch e
        close(sock)
        rethrow(e)
    end
    return sock
end

"""
    connect(host = "localhost", port = 9000;
        database = "",
        username = "default",
        password = "",
        connection_timeout = DBMS_DEFAULT_CONNECT_TIMEOUT,
        max_insert_block_size = DBMS_DEFAULT_MAX_INSERT_BLOCK,
        send_buffer_size = DBMS_DEFAULT_BUFFER_SIZE
    )

Return `ClickHouseSock` connected to ClickHouse server with the specified parameters
"""
function connect(
    host::AbstractString = "localhost",
    port::Integer = 9000;
    database::AbstractString = "",
    username::AbstractString = "default",
    password::AbstractString = "",
    connection_timeout = DBMS_DEFAULT_CONNECT_TIMEOUT,
    max_insert_block_size = DBMS_DEFAULT_MAX_INSERT_BLOCK,
    send_buffer_size = DBMS_DEFAULT_BUFFER_SIZE
)::ClickHouseSock
    sock = ClickHouseSock(
        nothing,
        CHSettings(
            host = host,
            port = port,
            database = database,
            username = username,
            password = password,
            connection_timeout = connection_timeout,
            max_insert_block_size = max_insert_block_size,
            send_buffer_size = send_buffer_size
        )
    )

    return connect!(sock)
end


text:
quote_lower(val) = Core.Compiler.quoted(val)

function lookup_lower_boundscheck(codestate::CodeState, args)
    # @show :boundscheck args
    true
end
function lookup_lower_loopinfo(codestate::CodeState, args)
    # @show :loopinfo args
    nothing
end
function lookup_lower_inbounds(codestate::CodeState, args)
    # @show :inbounds args
    args[1]
end
function lookup_lower_meta(codestate::CodeState, args)
    # @show :meta args
    args[1]
end

function lookup_lower_gc_preserve_begin(codestate::CodeState, args)
    # @show :gc_preserve_begin args
    nothing
end
function lookup_lower_gc_preserve_end(codestate::CodeState, args)
    # @show :gc_preserve_end args
    nothing
end

function isdefined_lower_static_parameter(codestate::CodeState, args)
    isassigned(codestate.sparam_vals, args[1]::Int)
end
function lookup_lower_static_parameter(codestate::CodeState, args)
    @assert isassigned(codestate.sparam_vals, args[1]::Int)
    codestate.sparam_vals[args[1]::Int]
end

function isdefined_lower_the_exception(codestate::CodeState, args)
    !isempty(codestate.interpstate.exceptions)
end
function lookup_lower_the_exception(codestate::CodeState, args)
    @assert !isempty(codestate.interpstate.exceptions)
    last(codestate.interpstate.exceptions).exception
end

function lookup_lower_isdefined(codestate::CodeState, args)
    isdefined_lower(codestate, args[1])
end

function lookup_lower_new(codestate::CodeState, args)
    # @show :new args
    type = quote_lower(lookup_lower(codestate, args[1]))
    # @show type typeof(type)
    parms = Any[quote_lower(lookup_lower(codestate, arg)) for arg in @view args[2:end]]
    # @show parms
    # ccall(:jl_new_structv, Any, (Any, Ptr{Any}, UInt), type, parms, length(parms))
    eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
        Expr(:new, type, parms...))
end
function lookup_lower_new_opaque_closure(codestate::CodeState, args)
    @show :new_opaque_closure args
    type = quote_lower(lookup_lower(codestate, args[1]))
    @show type typeof(type)
    parms = Any[quote_lower(lookup_lower(codestate, arg)) for arg in @view args[2:end]]
    @show parms
    eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
        Expr(:new_opaque_closure, type, parms...))
end
function lookup_lower_splatnew(codestate::CodeState, args)
    # @show :splatnew args
    type = quote_lower(lookup_lower(codestate, args[1]))
    # @show type typeof(type)
    # parms = ((lookup_lower(codestate, arg) for arg in @view args[2:end])...,)
    parms = Any[quote_lower(lookup_lower(codestate, arg)) for arg in @view args[2:end]]
    # @show parms
    # ccall(:jl_new_structt, Any, (Any, Any), type, parms[1])
    eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
        Expr(:splatnew, type, parms...))
end

function rootmodule(mod::Module)
    ans = mod
    parent = parentmodule(mod)
    while parent != mod
        ans = mod
        mod = parent
        parent = parentmodule(mod)
    end
    ans
end
function rootmodule(callable)
    parent::Module = parentmodule(callable)
    rootmodule(parent)
end
function clear_child_state(codestate::CodeState, callable)
    codestate.childstates[codestate.pc][codestate.cc] =
        callable, nothing
end
function set_child_state(codestate::CodeState, callable, parms)
    if !isassigned(codestate.childstates[codestate.pc], codestate.cc)
        wt = world_type(callable, parms)
        childstate = code_state_from_call(codestate, wt)
        codestate.childstates[codestate.pc][codestate.cc] = callable, childstate
        childstate
    else
        prev_callable, prev_childstate = codestate.childstates[codestate.pc][codestate.cc]
        if prev_childstate isa CodeState
            wt = world_type(callable, parms)
            if wt != prev_childstate.wt
                childstate = code_state_from_call(codestate, wt)
                codestate.childstates[codestate.pc][codestate.cc] = callable, childstate
                childstate
            else
                prev_childstate
            end
        else
            wt = world_type(callable, parms)
            childstate = code_state_from_call(codestate, wt)
            codestate.childstates[codestate.pc][codestate.cc] = callable, childstate
            childstate
        end
    end
end
function to_intercept(codestate::CodeState, callable)
    if haskey(codestate.interpstate.intercepts, callable)
        clear_child_state(codestate, callable)
        codestate.interpstate.intercepts[callable]
    else
        nothing
    end
end
function to_interpret(codestate::CodeState, callable, parms)
    root = rootmodule(callable)
    if root in codestate.interpstate.options.modules
        childstate = set_child_state(codestate, callable, parms)
        if childstate isa CodeState
            update_code_state(childstate, callable, parms)
            return childstate
        end
    elseif root in codestate.interpstate.options.limiteds && check_code_statistics(codestate)
        childstate = set_child_state(codestate, callable, parms)
        if childstate isa CodeState
            if check_interp_statistics(codestate.interpstate, childstate.mod_or_meth)
                update_code_state(childstate, callable, parms)
                return childstate
            end
        end
    end
    return nothing
end
function lookup_lower_call(codestate::CodeState, callable, parms)
    @nospecialize callable
    if (ans = to_intercept(codestate, callable)) !== nothing
        intercept::Base.Callable = ans
        return intercept(codestate, parms)
    elseif callable isa Core.Builtin || callable isa Core.IntrinsicFunction
        clear_child_state(codestate, callable)
    elseif (ans = to_interpret(codestate, callable, parms)) !== nothing
        childstate::CodeState = ans
        return interpret_lower(childstate)
    else
        clear_child_state(codestate, callable)
    end
    # eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
    #   Expr(:call, fun, parms...))
    if codestate.mod_or_meth isa Module
        return Base.invokelatest(callable, parms...)
    else
        # fun(parms...)
        # Base.invoke_in_world(codestate.wc, fun, parms...)
        return Base.invokelatest(callable, parms...)
    end
end
function lookup_lower_call(codestate::CodeState, args)
    # @nospecialize args
    # @show :call args
    fun = lookup_lower(codestate, args[1])
    # @show fun typeof(fun)
    # parms = ((lookup_lower(codestate, arg) for arg in @view args[2:end])...,)
    parms = Any[lookup_lower(codestate, arg) for arg in @view args[2:end]]
    # @show parms
    if fun isa Base.Callable
        callable = fun
        lookup_lower_call(codestate, callable, parms)
    else
        # @show fun typeof(fun)
        Base.invokelatest(fun, parms...)
    end
end

function lookup_lower_cfunction(codestate::CodeState, args)
    # @nospecialize args
    # @show :cfunction args
    type = quote_lower(lookup_lower(codestate, args[1]))
    # @show type typeof(type)
    if codestate.mod_or_meth isa Method && !isempty(codestate.sparam_vals)
        rt = ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}),
            args[3], codestate.mod_or_meth.sig, codestate.sparam_vals)
        at = Core.svec((
            ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}),
                arg, codestate.mod_or_meth.sig, codestate.sparam_vals) for arg in args[4])...)
    else
        rt = args[3]
        at = args[4]
    end
    cc = args[5]
    # @show rt at cc
    parm = QuoteNode(lookup_lower(codestate, args[2]))
    # @show parm
    eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
        Expr(:cfunction, type, parm, rt, at, cc))
end
function lookup_lower_foreigncall(codestate::CodeState, args)
    # @nospecialize args
    # @show :foreigncall args
    fun = quote_lower(lookup_lower(codestate, args[1]))
    # @show fun typeof(fun)
    if codestate.mod_or_meth isa Method && !isempty(codestate.sparam_vals)
        rt = ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}),
            args[2], codestate.mod_or_meth.sig, codestate.sparam_vals)
        at = Core.svec((
            ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}),
                arg, codestate.mod_or_meth.sig, codestate.sparam_vals) for arg in args[3])...)
    else
        rt = args[2]
        at = args[3]
    end
    reshape
    nreq = args[4]
    cc = args[5]
    # @show rt at nreq cc
    # parms = ((lookup_lower(codestate, arg) for arg in args[6:end]))...,)
    parms = Any[quote_lower(lookup_lower(codestate, arg)) for arg in args[6:end]]
    # @show parms
    eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
        Expr(:foreigncall, fun, rt, at, nreq, cc, parms...))
end
function lookup_lower_method(codestate::CodeState, args)
    # @show :method args
    meth = args[1]
    # @show meth typeof(meth)
    # parms = ((lookup_lower(codestate, arg) for arg in @view args[2:end])...,)
    parms = Any[lookup_lower(codestate, arg) for arg in @view args[2:end]]
    # @show parms
    if length(parms) >= 2
        # branching on https://github.com/JuliaLang/julia/pull/41137
        @static if isdefined(Core.Compiler, :OverlayMethodTable)
            ccall(:jl_method_def, Cvoid, (Any, Ptr{Cvoid}, Any, Any),
                parms[1], C_NULL, parms[2], moduleof(codestate.mod_or_meth))
        else
            ccall(:jl_method_def, Cvoid, (Any, Any, Any),
                parms[1], parms[2], moduleof(codestate.mod_or_meth))
        end
    end
    if isdefined_lower(codestate, meth)
        lookup_lower(codestate, meth)
    else
        eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
            Expr(:function, meth))
    end
end
function lookup_lower_copyast(codestate::CodeState, args)
    val = lookup_lower(codestate, args[1])
    if val isa Expr
        expr = val
        copy(expr)
    else
        val
    end
end

function lookup_lower_enter(codestate::CodeState, args)
    codestate.interpstate.options.debug && @show :lookup_lower_enter args
    push!(codestate.handlers, args[1]::Int)
    length(codestate.interpstate.exceptions)
end
function lookup_lower_pop_exception(codestate::CodeState, args)
    codestate.interpstate.options.debug && @show :lookup_lower_pop_exception args
    deleteat!(codestate.interpstate.exceptions,
        lookup_lower(codestate, args[1])::Int + 1:length(codestate.interpstate.exceptions))
end
function lookup_lower_leave(codestate::CodeState, args)
    codestate.interpstate.options.debug && @show :lookup_lower_leave args
    len = length(codestate.handlers)
    deleteat!(codestate.handlers, len - args[1]::Int + 1:len)
end

function lookup_lower_assign(codestate::CodeState, args)
    codestate.interpstate.options.debug && @show :lookup_lower_assign args
    val = lookup_lower(codestate, args[2])
    assign_lower(codestate, args[1], val)
end

function lookup_lower_const(codestate::CodeState, args)
    codestate.interpstate.options.debug && @show :lookup_lower_const args
    eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
        Expr(:const, args...))
end
function lookup_lower_global(codestate::CodeState, args)
    codestate.interpstate.options.debug && @show :lookup_lower_global args
    eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
        Expr(:global, args...))
end
function lookup_lower_using(codestate::CodeState, args)
    codestate.interpstate.options.debug && @show :lookup_lower_using args
    eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
        Expr(:using, args...))
end

function lookup_lower_thunk(codestate::CodeState, args)
    codestate.interpstate.options.debug && @show :lookup_lower_thunk args
    mod = moduleof(codestate.mod_or_meth)
    codestate = code_state_from_thunk(codestate.interpstate, mod, args[1]::Core.CodeInfo)
    interpret_lower(codestate)
end

function isdefined_lower_expr(codestate::CodeState, expr::Expr)
    #= if expr.head == :boundscheck
        isdefined_lower_boundscheck(codestate, expr.args)
    elseif expr.head == :loopinfo
        isdefined_lower_loopinfo(codestate, expr.args)
    elseif expr.head == :inbounds
        isdefined_lower_inbounds(codestate, expr.args)
    elseif expr.head == :meta
        isdefined_lower_meta(codestate, expr.args)
    elseif expr.head == :gc_preserve_begin
        isdefined_lower_gc_preserve_begin(codestate, expr.args)
    elseif expr.head == :gc_preserve_end
        isdefined_lower_gc_preserve_end(codestate, expr.args)
    else =#
    if expr.head == :static_parameter
        isdefined_lower_static_parameter(codestate, expr.args)
    elseif expr.head == :the_exception
        isdefined_lower_the_exception(codestate, expr.args)
    #= elseif expr.head == :isdefined
        isdefined_lower_isdefined(codestate, expr.args)
    elseif expr.head == :new
        isdefined_lower_new(codestate, expr.args)
    elseif expr.head == :new_opaque_closure
        isdefined_lower_new_opaque_closure(codestate, expr.args)
    elseif expr.head == :splatnew
        isdefined_lower_splatnew(codestate, expr.args)
    elseif expr.head == :call
        isdefined_lower_call(codestate, expr.args)
    elseif expr.head == :cfunction
        isdefined_lower_cfunction(codestate, expr.args)
    elseif expr.head == :foreigncall
        isdefined_lower_foreigncall(codestate, expr.args)
    elseif expr.head == :method
        isdefined_lower_method(codestate, expr.args)
    elseif expr.head == :copyast
        isdefined_lower_copyast(codestate, expr.args) =#
    else
        @show expr.head expr.args
        @assert false
    end
end

function lookup_lower_expr(codestate::CodeState, expr::Expr)
    if expr.head == :boundscheck
        lookup_lower_boundscheck(codestate, expr.args)
    elseif expr.head == :loopinfo
        lookup_lower_loopinfo(codestate, expr.args)
    elseif expr.head == :inbounds
        lookup_lower_inbounds(codestate, expr.args)
    elseif expr.head == :meta
        lookup_lower_meta(codestate, expr.args)
    elseif expr.head == :gc_preserve_begin
        lookup_lower_gc_preserve_begin(codestate, expr.args)
    elseif expr.head == :gc_preserve_end
        lookup_lower_gc_preserve_end(codestate, expr.args)
    elseif expr.head == :static_parameter
        lookup_lower_static_parameter(codestate, expr.args)
    elseif expr.head == :the_exception
        lookup_lower_the_exception(codestate, expr.args)
    elseif expr.head == :isdefined
        lookup_lower_isdefined(codestate, expr.args)
    elseif expr.head == :new
        lookup_lower_new(codestate, expr.args)
    elseif expr.head == :new_opaque_closure
        lookup_lower_new_opaque_closure(codestate, expr.args)
    elseif expr.head == :splatnew
        lookup_lower_splatnew(codestate, expr.args)
    elseif expr.head == :call
        lookup_lower_call(codestate, expr.args)
    elseif expr.head == :cfunction
        lookup_lower_cfunction(codestate, expr.args)
    elseif expr.head == :foreigncall
        lookup_lower_foreigncall(codestate, expr.args)
    elseif expr.head == :method
        lookup_lower_method(codestate, expr.args)
    elseif expr.head == :copyast
        lookup_lower_copyast(codestate, expr.args)
    elseif expr.head == :enter
        lookup_lower_enter(codestate, expr.args)
    elseif expr.head == :pop_exception
        lookup_lower_pop_exception(codestate, expr.args)
    elseif expr.head == :leave
        lookup_lower_leave(codestate, expr.args)
    elseif expr.head == :(=)
        lookup_lower_assign(codestate, expr.args)
    elseif expr.head == :const
        lookup_lower_const(codestate, expr.args)
    elseif expr.head == :global
        lookup_lower_global(codestate, expr.args)
    elseif expr.head == :using
        lookup_lower_using(codestate, expr.args)
    elseif expr.head == :thunk
        lookup_lower_thunk(codestate, expr.args)
    else
        @show expr.head expr.args
        @assert false
    end
end

function isdefined_lower(codestate::CodeState, var)
    @nospecialize var
    # @show :isdefined_lower typeof(var) var
    if var isa Core.SSAValue
        ssavalue = var
        isassigned(codestate.ssavalues, ssavalue.id)
    elseif var isa Core.SlotNumber
        slotnumber = var
        isassigned(codestate.slots, slotnumber.id)
    elseif var isa Core.NewvarNode
        newvarnode = var
        isassigned(codestate.slots, newvarnode.slot.id)
    elseif var isa Symbol
        symbol = var
        isdefined(moduleof(codestate.mod_or_meth), symbol)
    elseif var isa GlobalRef
        globalref = var
        isdefined(globalref.mod, globalref.name)
    elseif var isa QuoteNode
        quotenode = var
        true
    elseif var isa Expr
        expr = var
        isdefined_lower_expr(codestate, expr)
    else
        true
    end
end

function lookup_lower(codestate::CodeState, var)
    @nospecialize var
    # @show :lookup_lower typeof(var) var
    if var isa Core.SSAValue
        ssavalue = var
        @assert isassigned(codestate.ssavalues, ssavalue.id)
        codestate.ssavalues[ssavalue.id]
    elseif var isa Core.SlotNumber
        slotnumber = var
        @assert isassigned(codestate.slots, slotnumber.id)
        codestate.slots[slotnumber.id]
    elseif var isa Core.NewvarNode
        newvarnode = var
        @assert isassigned(codestate.slots, newvarnode.slot.id)
        codestate.slots[newvarnode.slot.id]
    elseif var isa Symbol
        symbol = var
        getfield(moduleof(codestate.mod_or_meth), symbol)
    elseif var isa GlobalRef
        globalref = var
        getfield(globalref.mod, globalref.name)
    elseif var isa QuoteNode
        quotenode = var
        quotenode.value
    elseif var isa Expr
        expr = var
        val = lookup_lower_expr(codestate, expr)
        codestate.cc += 1
        if codestate.cc > length(codestate.childstates[codestate.pc])
            resize!(codestate.childstates[codestate.pc], codestate.cc)
        end
        val
    else
        # @show typeof(var) var
        var
    end
end

function assign_lower(codestate::CodeState, var, val)
    @nospecialize var val
    if var isa Core.SSAValue
        ssavalue = var
        codestate.ssavalues[ssavalue.id] = val
    elseif var isa Core.SlotNumber
        slotnumber = var
        codestate.slots[slotnumber.id] = val
    elseif var isa Core.NewvarNode
        newvarnode = var
        codestate.slots[newvarnode.slot.id] = val
    elseif var isa Symbol
        symbol = var
        eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
            Expr(:(=), symbol, quote_lower(val)))
    elseif var isa GlobalRef
        globalref = var
        eval_ast(codestate.interpstate, moduleof(codestate.mod_or_meth),
            Expr(:(=), globalref, quote_lower(val)))
    else
        @show :assign_lower typeof(var) var val
        @assert false
    end
end

function prepare_calls(codestate)
    codestate.cc = 1
    if !isassigned(codestate.childstates, codestate.pc)
        codestate.childstates[codestate.pc] = Vector{ChildState}(undef, codestate.cc)
    end
end

function interpret_lower_node(codestate::CodeState, node)
    @nospecialize node
    codestate.interpstate.options.debug && @show :interpret_lower codestate.pc codestate.src.code[codestate.pc]
    time = time_ns()
    try
        if node isa Core.NewvarNode
            newvarnode = node
            # @assert !isassigned(codestate.slots, newvarnode.slot.id)
            codestate.pc += 1
        elseif node isa Core.ReturnNode
            returnnode = node
            prepare_calls(codestate)
            return lookup_lower(codestate, returnnode.val)
        elseif node isa Core.GotoIfNot
            gotoifnot = node
            prepare_calls(codestate)
            if lookup_lower(codestate, gotoifnot.cond)
                codestate.pc += 1
            else
                codestate.pc = gotoifnot.dest
            end
        elseif node isa Core.GotoNode
            gotonode = node
            codestate.pc = gotonode.label
        else
            prepare_calls(codestate)
            val = lookup_lower(codestate, node)
            assign_lower(codestate, Core.SSAValue(codestate.pc), val)
            codestate.pc += 1
        end
    catch
        exceptions = Compat.current_exceptions()
        codestate.interpstate.options.debug && @show :interpret_lower last(exceptions)
        append!(codestate.interpstate.exceptions, exceptions)
        if isempty(codestate.handlers)
            rethrow(pop!(codestate.interpstate.exceptions).exception)
        else
            codestate.pc = last(codestate.handlers)
        end
    finally
        update_code_statistics(codestate, time_ns() - time)
    end
end

function interpret_lower(codestate::CodeState)
    codestate.interpstate.options.debug && @show :interpret_lower codestate.pc codestate.src
    time = time_ns()
    try
        while true
            node = codestate.src.code[codestate.pc]
            ans = interpret_lower_node(codestate, node)
            if node isa Core.ReturnNode
                return ans
            end
        end
    finally
        update_interp_statistics(codestate.interpstate, codestate.mod_or_meth, time_ns() - time)
    end
end


text:
#####
##### Operators of the form A * q where A is an area and q is some quantity.
#####

for metric in (:Δ, :A), dir in (:x, :y, :z), LX in (:ᶜ, :ᶠ), LY in (:ᶜ, :ᶠ), LZ in (:ᶜ, :ᶠ)

    operator   = Symbol(metric, dir, :_q, LX, LY, LZ)
    area       = Symbol(metric, dir, LX, LY, LZ)

    @eval begin
        $operator(i, j, k, grid, q) = $area(i, j, k, grid) * q[i, j, k]
        $operator(i, j, k, grid, f::Function, args...) = $area(i, j, k, grid) * f(i, j, k, grid, args...)
    end
end


text:
type SpreadCDSHelper{P <: Dates.Period, C <: BusinessCalendar, F <: Frequency, PC <: BusinessDayConvention, DC <: DayCount, YTS <: YieldTermStructure, PROB <: AbstractDefaultProbabilityTermStructure} <: AbstractCDSHelper
  runningSpread::Quote
  tenor::P
  settlementDays::Int
  calendar::C
  frequency::F
  paymentConvention::PC
  dc::DC
  recoveryRate::Float64
  schedule::Schedule
  discountCurve::YTS
  settlesAccrual::Bool
  paysAtDefaultTime::Bool
  protectionStart::Date
  probability::PROB
  swap::CreditDefaultSwap

  # main constructor
  SpreadCDSHelper(runningSpread::Quote, tenor::P, settlementDays::Int, calendar::C, frequency::F, paymentConvention::PC, dc::DC, recoveryRate::Float64, schedule::Schedule,
                  discountCurve::YTS, settlesAccrual::Bool, paysAtDefaultTime::Bool, protectionStart::Date, probability::PROB) =
                  new(runningSpread, tenor, settlementDays, calendar, frequency, paymentConvention, dc, recoveryRate, schedule, discountCurve, settlesAccrual, paysAtDefaultTime, protectionStart, probability)
end

# Catch all constructor
SpreadCDSHelper{P <: Dates.Period, C <: BusinessCalendar, F <: Frequency, PC <: BusinessDayConvention, DC <: DayCount, YTS <: YieldTermStructure, PROB <: AbstractDefaultProbabilityTermStructure}(
                runningSpread::Quote, tenor::P, settlementDays::Int, calendar::C, frequency::F, paymentConvention::PC, dc::DC, recoveryRate::Float64,
                schedule::Schedule, discountCurve::YTS, settlesAccrual::Bool, paysAtDefaultTime::Bool, protectionStart::Date, probability::PROB = NullDefaultProbabilityTermStructure()) =

                SpreadCDSHelper{P, C, F, PC, DC, YTS, PROB}(runningSpread, tenor, settlementDays, calendar, frequency, paymentConvention, dc, recoveryRate, schedule, discountCurve,
                                settlesAccrual, paysAtDefaultTime, protectionStart, probability)

# main outer constructor
function SpreadCDSHelper(runningSpread::Quote, tenor::Dates.Period, settlementDays::Int, calendar::BusinessCalendar, frequency::Frequency, paymentConvention::BusinessDayConvention, rule::DateGenerationRule,
                        dc::DayCount, recoveryRate::Float64, discountCurve::YieldTermStructure = NullYieldTermStructure(), settlesAccrual::Bool = true, paysAtDefaultTime::Bool = true)
  evalDate = settings.evaluation_date
  protectionStart, schedule = initialize_dates(SpreadCDSHelper, evalDate, settlementDays, calendar, paymentConvention, tenor, frequency, rule)

  return SpreadCDSHelper(runningSpread, tenor, settlementDays, calendar, frequency, paymentConvention, dc, recoveryRate, schedule, discountCurve, settlesAccrual, paysAtDefaultTime, protectionStart)
end

value(cdsHelper::SpreadCDSHelper) = cdsHelper.runningSpread.value

function initialize_dates(::Type{SpreadCDSHelper}, evaluationDate::Date, settlementDays::Int, calendar::BusinessCalendar, paymentConvention::BusinessDayConvention, tenor::Dates.Period, frequency::Frequency, rule::DateGenerationRule)
  protectionStart = evaluationDate + Dates.Day(settlementDays)
  startDate = adjust(calendar, paymentConvention, protectionStart)
  endDate = evaluationDate + tenor

  schedule = Schedule(startDate, endDate, TenorPeriod(frequency), paymentConvention, Unadjusted(), rule, false, calendar)

  return protectionStart, schedule
end

maturity_date(cds::SpreadCDSHelper) = cds.schedule.dates[end]

function reset_engine!(cds::SpreadCDSHelper)
  cds.swap = CreditDefaultSwap(Buyer(), 100.0, 0.01, cds.schedule, cds.paymentConvention, cds.dc, cds.settlesAccrual, cds.paysAtDefaultTime,
              cds.protectionStart, MidPointCdsEngine(cds.probability, cds.recoveryRate, cds.discountCurve))

  return cds
end

function implied_quote(cdsHelper::SpreadCDSHelper)
  recalculate!(cdsHelper.swap)
  return cdsHelper.swap.results.fairSpread
end

# defaults to existing prob ts, note: this doesn't copy the swap!
clone(cds::SpreadCDSHelper, probTs::AbstractDefaultProbabilityTermStructure = cds.probability) =
      SpreadCDSHelper(cds.runningSpread, cds.tenor, cds.settlementDays, cds.calendar, cds.frequency, cds.paymentConvention, cds.dc, cds.recoveryRate,
                      cds.schedule, cds.discountCurve, cds.settlesAccrual, cds.paysAtDefaultTime, cds.protectionStart, probTs)


text:
using GtkMarkdownTextView, Test
using Gtk

@testset "MarkdownTextView" begin

    w = GtkWindow("")

    md = """
IOBuffer([data::AbstractVector{UInt8}]; keywords...) -> IOBuffer
Create an in-memory I/O stream, which may optionally operate on a pre-existing array.
It may take optional keyword arguments:
- `read`, `write`, `append`: restricts operations to the buffer; see `open` for details.
- `truncate`: truncates the buffer size to zero length.
- `maxsize`: specifies a size beyond which the buffer may not be grown.
- `sizehint`: suggests a capacity of the buffer (`data` must implement `sizehint!(data, size)`).
When `data` is not given, the buffer will be both readable and writable by default.
"""

    v = MarkdownTextView(md)
    push!(w,v)
    showall(w)
    sleep(1)
    destroy(w)

end


text:
export choose

"""
`choose(ctx, loc, f, types, target, known. θ)`

Parametrically choose a value for variables in relation defined by method
`f(::types..)`, given information about other values in relation.

# Arguments
- `f(::types...)` - method to choose from
- `loc`    - Location
- `target` - which axis we wish to choose onto
- `given`  - what is given/known about values of the relation (e.g. value of input)
- `θ`      - Parameter values which determine which element to choose
"""
function choose end


text:
"""
constraint_list.jl
"""

############################################################################################
#					             CONSTRAINT LIST										   #
############################################################################################
"""
	AbstractConstraintSet

Stores constraint error and Jacobian values, correctly accounting for the error state if
necessary.

# Interface
- `get_convals(::AbstractConstraintSet)::Vector{<:ConVal}` where the size of the Jacobians
	match the full state dimension
- `get_errvals(::AbstractConstraintSet)::Vector{<:ConVal}` where the size of the Jacobians
	match the error state dimension
- must have field `c_max::Vector{<:AbstractFloat}` of length `length(get_convals(conSet))`

# Methods
Once the previous interface is defined, the following methods are defined
- `Base.iterate`: iterates over `get_convals(conSet)`
- `Base.length`: number of independent constraints
- `evaluate!(conSet, Z::Traj)`: evaluate the constraints over the entire trajectory `Z`
- `jacobian!(conSet, Z::Traj)`: evaluate the constraint Jacobians over the entire trajectory `Z`
- `error_expansion!(conSet, model, G)`: evaluate the Jacobians for the error state using the
	state error Jacobian `G`
- `max_violation(conSet)`: return the maximum constraint violation
- `findmax_violation(conSet)`: return details about the location of the maximum
	constraint violation in the trajectory
"""
abstract type AbstractConstraintSet end

"""
	ConstraintList

Stores the set of constraints included in a trajectory optimization problem. Includes a list
of both the constraint types [`AbstractConstraint`](@ref) as well as the knot points at which
the constraint is applied. Each constraint is assumed to apply to a contiguous set of knot points.

A `ConstraintList` supports iteration and indexing over the `AbstractConstraint`s, and
iteration of both the constraints and the indices of the knot points at which they apply
via `zip(cons::ConstraintList)`.

Constraints are added via the [`add_constraint!`](@ref) method, which verifies that the constraint
dimension is consistent with the state and control dimensions of the problem.

The total number of constraints at each knot point can be queried using the
[`num_constraints`](@ref) method.

The constraint list can also be sorted to separate `StageConstraint`s and `CoupledConstraint`s
via the `sort!` method.

A constraint list can be queried if it has a `DynamicsConstraint` via
`has_dynamics_constraint(::ConstraintList)`.

# Constructor
	ConstraintList(n::Int, m::Int, N::Int)
"""
struct ConstraintList{TM,TV} <: AbstractConstraintSet
    n::Int
    m::Int
    N::Int
	constraints::Vector{AbstractConstraint}
	inds::Vector{AbstractVector} # active knot points for each constraint in constraints
    M::TM
    V::TV
end

function ConstraintList(n::Int, m::Int, N::Int, M::TM, V::TV) where {TM,TV}
    constraints = AbstractConstraint[]
    inds = AbstractVector[]
    return ConstraintList{TM,TV}(n, m, N, constraints, inds, M, V)
end

# methods
Base.length(cons::ConstraintList) = length(cons.constraints)

"""
	add_constraint!(cons::ConstraintList, con::AbstractConstraint, inds::UnitRange, [idx])

Add constraint `cons` to `ConstraintList` `cons` for knot points given by `inds`.

Use `idx` to determine the location of the constraint in the constraint list.
`idx=-1` (default) adds the constraint at the end of the list.

# Example
Here is an example of adding a goal and control limit constraint for a cartpole swing-up.
```julia
# Dimensions of our problem
n,m,N = 4,1,51    # 51 knot points

# Create our list of constraints
cons = ConstraintList(n,m,N)

# Create the goal constraint
xf = [0,π,0,0]
goalcon = GoalConstraint(xf)
add_constraint!(cons, goalcon, N)  # add to the last time step

# Create control limits
ubnd = 3
bnd = BoundConstraint(n,m, u_min=-ubnd, u_max=ubnd, idx=1)  # make it the first constraint
add_constraint!(cons, bnd, 1:N-1)  # add to all but the last time step

# Indexing
cons[1] === bnd                            # (true)
cons[2] === goal                           # (true)
allcons = [con for con in cons]
cons_and_inds = [(con,ind) in zip(cons)]
cons_and_inds[1] == (bnd,1:n-1)            # (true)
```
"""
function add_constraint!(cons::ConstraintList, con::AbstractConstraint, inds::AbstractVector)
    push!(cons.constraints, con)
    push!(cons.inds, inds)
    return nothing
end


text:
module Arrhenius
    using YAML
    using NPZ
    using LinearAlgebra
    using SparseArrays

    include("Constants.jl")
    include("DataStructure.jl")
    include("Solution.jl")
    include("Magic.jl")
    include("Thermo.jl")
    include("Kinetics.jl")
end
```
Following codes are used during development phase only.
```
# using LinearAlgebra
# using DifferentialEquations
# using Sundials
# using Profile
# using ForwardDiff
# using SparseArrays

# R = Arrhenius.R
# one_atm = Arrhenius.one_atm

# # gas = Arrhenius.CreateSolution("../mechanism/nc7_ver3.1_mech.yaml")
# # const ns = gas.n_species
# # @show gas.thermo.nasa_high[Arrhenius.species_index(gas, "O2"), :]
# # Y0 = zeros(ns)
# # Y0[Arrhenius.species_index(gas, "NC7H16")] = 0.1
# # Y0[Arrhenius.species_index(gas, "O2")] = 0.2
# # Y0[Arrhenius.species_index(gas, "N2")] = 0.7

# gas = Arrhenius.CreateSolution("../mechanism/gri30.yaml")
# const ns = gas.n_species
# @show gas.thermo.nasa_high[Arrhenius.species_index(gas, "O2"), :]
# Y0 = zeros(ns)
# Y0[Arrhenius.species_index(gas, "CH4")] = 0.1
# Y0[Arrhenius.species_index(gas, "O2")] = 0.2
# Y0[Arrhenius.species_index(gas, "N2")] = 0.7

# T0 = 1200.0
# P = Arrhenius.one_atm
# wdot = Arrhenius.set_states(gas, T0, P, Y0)
# @show wdot

# T = T0
# Y = Y0
# mean_MW = 1. / dot(Y, 1 ./ gas.MW)
# ρ_mass = P / R / T * mean_MW
# X =  Arrhenius.Y2X(gas, Y, mean_MW)
# C =  Arrhenius.Y2C(gas, Y, ρ_mass)
# cp_mole, cp_mass =  Arrhenius.get_cp(gas, T, X, mean_MW)
# cv_mole, cv_mass = Arrhenius.get_cv(cp_mole, cp_mass, mean_MW)
#
# h_mole =  Arrhenius.get_H(gas, T, Y, X)
# u_mole = Arrhenius.get_U(h_mole, Y)
#
# S0 =  Arrhenius.get_S(gas, T, P, X)
# wdot = Arrhenius.wdot_func(gas.reaction, T, C, S0, h_mole; get_qdot=false)

# u0 = vcat(Y0, T0);
# function f(u)
#     # Arrhenius.set_states(gas, u[end], P, u[1:ns])[10]
#     T = u[end]
#     Y = @view(u[1:ns])
#     mean_MW = 1. / dot(Y, 1 ./ gas.MW)
#     ρ_mass = P / R / T * mean_MW
#     X =  Arrhenius.Y2X(gas, Y, mean_MW)
#     C =  Arrhenius.Y2C(gas, Y, ρ_mass)
#     cp_mole, cp_mass =  Arrhenius.get_cp(gas, T, X, mean_MW)
#     h_mole =  Arrhenius.get_H(gas, T, Y, X)
#     S0 =  Arrhenius.get_S(gas, T, P, X)
#     wdot = Arrhenius.wdot_func(gas.reaction, T, C, S0, h_mole; get_qdot=false)
#     # wdot = gas.reaction.vk * qdot
#     return wdot[end]
# end
#
# @time f(u0)
# @time grad = ForwardDiff.gradient(f, u0)

# function profile_test(n)
#     for i = 1:n
#         Arrhenius.set_states(gas, T0, P, Y0)
#     end
# end
# @time profile_test(1000)
#
# # Profile.clear
# # @profile profile_test(1000)
# # Juno.profiler(; C = false)

# u0[end] = 1200 + rand()
# @time f(u0)
# @time f(u0)
#

# Profile.clear
# @profile grad = ForwardDiff.gradient(x -> f(x), u0)
# Juno.profiler(; C = false)


text:
import LinearAlgebra.naivesub!

const trs_mt_threshold = Ref(64.0)
mt_thresholds[:trs] = trs_mt_threshold;

function ldiv!(A::UpperTriangular{DoubleFloat{T}},
                   B::AbstractMatrix{DoubleFloat{T}}) where {T <: AbstractFloat}
    require_one_based_indexing(A, B)
    n = size(A.data, 2)
    m = size(B, 2)
    if !(n == size(B,1))
        throw(DimensionMismatch("second dimension of left hand side A, $n, and first dimension of right hand side B, $(size(B,1)), must be equal"))
    end
    liA = LinearIndices(A.data)
    liB = LinearIndices(B)
    use_threads = (nthreads() > 1) &&
        (Float64(m)*Float64(n) > trs_mt_threshold[])

    @inbounds for j in n:-1:1
        iszero(A.data[j,j]) && throw(SingularException(j))
    end
    @inbounds for j in n:-1:1
        if use_threads
            _mt_ldiv_loop1(m,j,A.data,liA[1,j],B,liB,Vec{Npref,T})
        else
            for k = 1:m
                xj = B[j,k] = A.data[j,j] \ B[j,k]
                # _axpy!(-xj,view(A.data,1:j-1,j),view(B,1:j-1,k),Vec{Npref,T})
                if j>1
                    _axpy!(j-1,-xj,A.data,liA[1,j],B,liB[1,k],Vec{Npref,T})
                end
            end
        end
    end
    B
end

# We attempt to insure good inference by use of function barriers.
# We may be overdoing it, since early development was based on
# now-questionable profiling results.
# (The tools used were driven beserk by threading when I started,
# but JN seems to be fixing them these days.)
# TODO: Revisit when threading has been overhauled.
# TODO: clean up the noise that doesn't really help the compiler.

@noinline function _mt_ldiv_loop1(m,j,A,idxA,B,liB,::Type{Vec{N,T}}) where {N,T}
    if j>1
        @threads for k = 1:m
            ib0::Int = liB[1,k]
            let ib=ib0
                @inbounds _mt_ldiv_kern1(j,k,A,B,idxA,ib,Vec{N,T})
            end
        end
    else
        @threads for k = 1:m
            @inbounds B[j,k] = A[j,j] \ B[j,k]
        end
    end
    nothing
end

@noinline function _mt_ldiv_kern1(j,k,A,B::AbstractMatrix{DoubleFloat{T}},
                      idxA::Int,idxB::Int,::Type{Vec{N,T}}) where {N,T}
    @inbounds begin
        xj::DoubleFloat{T} = A[j,j] \ B[j,k]
        B[j,k] = xj
        # _axpy!(-xj,view(A,1:j-1,j),view(B,1:j-1,k),VT)
        _axpy!(j-1,-xj,A,idxA,B,idxB,Vec{N,T})
    end
    nothing
end

function ldiv!(A::UnitLowerTriangular{DoubleFloat{T}},
                   B::AbstractMatrix{DoubleFloat{T}}) where {T <: AbstractFloat}
    require_one_based_indexing(A, B)
    n = size(A.data, 2)
    m = size(B, 2)
    if !(n == size(B,1))
        throw(DimensionMismatch("second dimension of left hand side A, $n, and first dimension of right hand side B, $(size(B,1)), must be equal"))
    end
    liA = LinearIndices(A.data)
    liB = LinearIndices(B)
    use_threads = (nthreads() > 1) &&
        (Float64(m)*Float64(n) > trs_mt_threshold[])
    @inbounds for j in 1:n-1
        if use_threads
            _mt_ldiv_loop2(m,n,j,A.data,liA[j+1,j],B,liB,Vec{Npref,T})
        else
            for k = 1:m
                xj = B[j,k]
                # _axpy!(-xj, view(A.data,j+1:n,j), view(B,j+1:n,k), Vec{Npref,T})
                # we know j<n from loop range
                _axpy!(n-j,-xj,A.data,liA[j+1,j],B,liB[j+1,k],Vec{Npref,T})
            end
        end
    end
    B
end

@noinline function _mt_ldiv_loop2(m,n,j,A,idxA,B,liB,::Type{Vec{N,T}}) where {N,T}
    @threads for k = 1:m
        @inbounds _mt_ldiv_kern2(n,j,k,A,B,idxA,liB[j+1,k],Vec{N,T})
        #=
        @inbounds begin
            xj = B[j,k]
            # _axpy!(-xj, view(A,j+1:n,j), view(B,j+1:n,k), VT)
            if j<n
                _axpy!(n-j,-xj,A,liA[j+1,j],B,liB[j+1,k],VT)
            end
        end
        =#
    end
    nothing
end

@noinline function _mt_ldiv_kern2(n,j,k,A,B,idxA,idxB,::Type{Vec{N,T}}) where {N,T}
    @inbounds begin
        xj = B[j,k]
        # _axpy!(-xj, view(A,j+1:n,j), view(B,j+1:n,k), VT)
        if j<n
            _axpy!(n-j,-xj,A,idxA,B,idxB,Vec{N,T})
        end
    end
    nothing
end

function naivesub!(A::UpperTriangular{DoubleFloat{T}},
                   b::AbstractVector{DoubleFloat{T}},
                   x::AbstractVector{DoubleFloat{T}} = b) where {T <: AbstractFloat}
    require_one_based_indexing(A, b, x)
    n = size(A, 2)
    if !(n == length(b) == length(x))
        throw(DimensionMismatch("second dimension of left hand side A, $n, length of output x, $(length(x)), and length of right hand side b, $(length(b)), must be equal"))
    end
    liA = LinearIndices(A.data)
    liB = LinearIndices(b)
    @inbounds for j in n:-1:1
        iszero(A.data[j,j]) && throw(SingularException(j))
        xj = x[j] = A.data[j,j] \ b[j]
        #    b[i] -= A.data[i,j] * xj
        #end
        # _axpy!(-xj,view(A.data,1:j-1,j),view(b,1:j-1),Vec{Npref,T})
        if j>1
            _axpy!(j-1,-xj,A.data,liA[1,j],b,liB[1],Vec{Npref,T})
        end
    end
    x
end

function naivesub!(A::UnitLowerTriangular{DoubleFloat{T}},
                   b::StridedVector{DoubleFloat{T}},
                   x::AbstractVector{DoubleFloat{T}} = b) where {T <: AbstractFloat}
    require_one_based_indexing(A, b, x)
    n = size(A, 2)
    if !(n == length(b) == length(x))
        throw(DimensionMismatch("second dimension of left hand side A, $n, length of output x, $(length(x)), and length of right hand side b, $(length(b)), must be equal"))
    end
    liA = LinearIndices(A.data)
    liB = LinearIndices(b)
    @inbounds for j in 1:n
        xj = x[j] = b[j]
        # for i in j+1:n
        #     b[i] -= A.data[i,j] * xj
        # end
        # _axpy!(-xj, view(A.data,j+1:n,j), view(b,j+1:n), Vec{Npref,T})
        if j<n
            _axpy!(n-j,-xj,A.data,liA[j+1,j],b,liB[j+1],Vec{Npref,T})
        end
    end
    x
end

max_stars_repo_name: RalphAS/DoubleBLAS

max_issues_repo_name: RalphAS/DoubleBLAS

max_forks_repo_name: RalphAS/DoubleBLAS


text:
const NULLNODE = Node()

function _findfirst(f::Function, p::AbstractNode, q::AbstractNode, r::AbstractNode)
	f(q) && return q
	for link in q.links
		link.to == p && continue
		r = _findfirst(f, q, link.to, r)
		r ≠ NULLNODE && return r
	end

	return NULLNODE
end

"""
	findfirst(f::Function, tree)
	findfirst(f::Function, p [, q])

Return the first node of a tree or subtree for which `f(node)` returns `true`. Return `nothing` if there is no such node.
"""
function Base.findfirst(f::Function, p::AbstractNode, q::AbstractNode)
	r = _findfirst(f, p, q, NULLNODE)
	return r == NULLNODE ? nothing : r
end
Base.findfirst(f::Function, p::AbstractNode) = findfirst(f, p, p)
Base.findfirst(f::Function, tree::AbstractTree) = findfirst(f, tree.origin)

function _findall(
	f::Function,
	list::Vector{T},
	p::T,
	q::T
	) where T <: AbstractNode

	f(q) && push!(list, q)
	for link in q.links
		link.to == p && continue
		_findall(f, list, q, link.to)
	end

	return list
end

"""
	findall(f::Function, tree)
	findall(f::Function, p [, q])

Return a vector of the nodes from a tree or subtree where `f(node)` returns `true`. If no such node is found, return an empty node vector.
"""
Base.findall(f::Function, p::AbstractNode, q::AbstractNode) =
	_findall(f, Vector{typeof(p)}(), p, q)
Base.findall(f::Function, p::AbstractNode) = _findall(f, Vector{typeof(p)}(), p, p)
Base.findall(f::Function, tree::AbstractTree) = _findall(f, Vector{typeof(tree.origin)}(), tree.origin, tree.origin)