text:
# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/cvodes/cvodes.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function __CVodeCreate(lmm::Cint, iter::Cint)
    ccall((:CVodeCreate, libsundials_cvodes), CVODEMemPtr, (Cint, Cint), lmm, iter)
end

function CVodeCreate(lmm, iter)
    __CVodeCreate(convert(Cint, lmm), convert(Cint, iter))
end

function __CVodeInit(cvode_mem, f::CVRhsFn, t0::realtype, y0::N_Vector)
    ccall((:CVodeInit, libsundials_cvodes), Cint, (CVODEMemPtr, CVRhsFn, realtype, N_Vector), cvode_mem, f, t0, y0)
end

function CVodeInit(cvode_mem, f, t0, y0)
    __y0 = convert(NVector, y0)
    __CVodeInit(cvode_mem, CVRhsFn_wrapper(f), t0, convert(N_Vector, __y0))
end

function __CVodeReInit(cvode_mem, t0::realtype, y0::N_Vector)
    ccall((:CVodeReInit, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, N_Vector), cvode_mem, t0, y0)
end

function CVodeReInit(cvode_mem, t0, y0)
    __y0 = convert(NVector, y0)
    __CVodeReInit(cvode_mem, t0, convert(N_Vector, __y0))
end

function CVodeSStolerances(cvode_mem, reltol::realtype, abstol::realtype)
    ccall((:CVodeSStolerances, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, realtype), cvode_mem, reltol, abstol)
end

function __CVodeSVtolerances(cvode_mem, reltol::realtype, abstol::N_Vector)
    ccall((:CVodeSVtolerances, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, N_Vector), cvode_mem, reltol, abstol)
end

function CVodeSVtolerances(cvode_mem, reltol, abstol)
    __abstol = convert(NVector, abstol)
    __CVodeSVtolerances(cvode_mem, reltol, convert(N_Vector, __abstol))
end

function CVodeWFtolerances(cvode_mem, efun::CVEwtFn)
    ccall((:CVodeWFtolerances, libsundials_cvodes), Cint, (CVODEMemPtr, CVEwtFn), cvode_mem, efun)
end

function __CVodeQuadInit(cvode_mem, fQ::CVQuadRhsFn, yQ0::N_Vector)
    ccall((:CVodeQuadInit, libsundials_cvodes), Cint, (CVODEMemPtr, CVQuadRhsFn, N_Vector), cvode_mem, fQ, yQ0)
end

function CVodeQuadInit(cvode_mem, fQ, yQ0)
    __yQ0 = convert(NVector, yQ0)
    __CVodeQuadInit(cvode_mem, fQ, convert(N_Vector, __yQ0))
end

function __CVodeQuadReInit(cvode_mem, yQ0::N_Vector)
    ccall((:CVodeQuadReInit, libsundials_cvodes), Cint, (CVODEMemPtr, N_Vector), cvode_mem, yQ0)
end

function CVodeQuadReInit(cvode_mem, yQ0)
    __yQ0 = convert(NVector, yQ0)
    __CVodeQuadReInit(cvode_mem, convert(N_Vector, __yQ0))
end

function CVodeQuadSStolerances(cvode_mem, reltolQ::realtype, abstolQ::realtype)
    ccall((:CVodeQuadSStolerances, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, realtype), cvode_mem, reltolQ, abstolQ)
end

function __CVodeQuadSVtolerances(cvode_mem, reltolQ::realtype, abstolQ::N_Vector)
    ccall((:CVodeQuadSVtolerances, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, N_Vector), cvode_mem, reltolQ, abstolQ)
end

function CVodeQuadSVtolerances(cvode_mem, reltolQ, abstolQ)
    __abstolQ = convert(NVector, abstolQ)
    __CVodeQuadSVtolerances(cvode_mem, reltolQ, convert(N_Vector, __abstolQ))
end

function __CVodeSensInit(cvode_mem, Ns::Cint, ism::Cint, fS::CVSensRhsFn, yS0)
    ccall((:CVodeSensInit, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Cint, CVSensRhsFn, Ptr{N_Vector}), cvode_mem, Ns, ism, fS, yS0)
end

function CVodeSensInit(cvode_mem, Ns, ism, fS, yS0)
    __CVodeSensInit(cvode_mem, convert(Cint, Ns), convert(Cint, ism), fS, yS0)
end

function __CVodeSensInit1(cvode_mem, Ns::Cint, ism::Cint, fS1::CVSensRhs1Fn, yS0)
    ccall((:CVodeSensInit1, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Cint, CVSensRhs1Fn, Ptr{N_Vector}), cvode_mem, Ns, ism, fS1, yS0)
end

function CVodeSensInit1(cvode_mem, Ns, ism, fS1, yS0)
    __CVodeSensInit1(cvode_mem, convert(Cint, Ns), convert(Cint, ism), fS1, yS0)
end

function __CVodeSensReInit(cvode_mem, ism::Cint, yS0)
    ccall((:CVodeSensReInit, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Ptr{N_Vector}), cvode_mem, ism, yS0)
end

function CVodeSensReInit(cvode_mem, ism, yS0)
    __CVodeSensReInit(cvode_mem, convert(Cint, ism), yS0)
end

function CVodeSensSStolerances(cvode_mem, reltolS::realtype, abstolS)
    ccall((:CVodeSensSStolerances, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Ptr{realtype}), cvode_mem, reltolS, abstolS)
end

function CVodeSensSVtolerances(cvode_mem, reltolS::realtype, abstolS)
    ccall((:CVodeSensSVtolerances, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Ptr{N_Vector}), cvode_mem, reltolS, abstolS)
end

function CVodeSensEEtolerances(cvode_mem)
    ccall((:CVodeSensEEtolerances, libsundials_cvodes), Cint, (CVODEMemPtr,), cvode_mem)
end

function CVodeQuadSensInit(cvode_mem, fQS::CVQuadSensRhsFn, yQS0)
    ccall((:CVodeQuadSensInit, libsundials_cvodes), Cint, (CVODEMemPtr, CVQuadSensRhsFn, Ptr{N_Vector}), cvode_mem, fQS, yQS0)
end

function CVodeQuadSensReInit(cvode_mem, yQS0)
    ccall((:CVodeQuadSensReInit, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{N_Vector}), cvode_mem, yQS0)
end

function CVodeQuadSensSStolerances(cvode_mem, reltolQS::realtype, abstolQS)
    ccall((:CVodeQuadSensSStolerances, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Ptr{realtype}), cvode_mem, reltolQS, abstolQS)
end

function CVodeQuadSensSVtolerances(cvode_mem, reltolQS::realtype, abstolQS)
    ccall((:CVodeQuadSensSVtolerances, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Ptr{N_Vector}), cvode_mem, reltolQS, abstolQS)
end

function CVodeQuadSensEEtolerances(cvode_mem)
    ccall((:CVodeQuadSensEEtolerances, libsundials_cvodes), Cint, (CVODEMemPtr,), cvode_mem)
end

function __CVodeRootInit(cvode_mem, nrtfn::Cint, g::CVRootFn)
    ccall((:CVodeRootInit, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVRootFn), cvode_mem, nrtfn, g)
end

function CVodeRootInit(cvode_mem, nrtfn, g)
    __CVodeRootInit(cvode_mem, convert(Cint, nrtfn), CVRootFn_wrapper(g))
end

function CVodeFree(cvode_mem)
    ccall((:CVodeFree, libsundials_cvodes), Cvoid, (Ref{CVODEMemPtr},), cvode_mem)
end

function CVodeQuadFree(cvode_mem)
    ccall((:CVodeQuadFree, libsundials_cvodes), Cvoid, (CVODEMemPtr,), cvode_mem)
end

function CVodeSensFree(cvode_mem)
    ccall((:CVodeSensFree, libsundials_cvodes), Cvoid, (CVODEMemPtr,), cvode_mem)
end

function CVodeQuadSensFree(cvode_mem)
    ccall((:CVodeQuadSensFree, libsundials_cvodes), Cvoid, (CVODEMemPtr,), cvode_mem)
end

function CVodeSetErrHandlerFn(cvode_mem, ehfun::CVErrHandlerFn, eh_data)
    ccall((:CVodeSetErrHandlerFn, libsundials_cvodes), Cint, (CVODEMemPtr, CVErrHandlerFn, Ptr{Cvoid}), cvode_mem, ehfun, eh_data)
end

function CVodeSetErrFile(cvode_mem, errfp)
    ccall((:CVodeSetErrFile, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{FILE}), cvode_mem, errfp)
end

function CVodeSetUserData(cvode_mem, user_data)
    ccall((:CVodeSetUserData, libsundials_cvodes), Cint, (CVODEMemPtr, Any), cvode_mem, user_data)
end

function __CVodeSetMaxOrd(cvode_mem, maxord::Cint)
    ccall((:CVodeSetMaxOrd, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, maxord)
end

function CVodeSetMaxOrd(cvode_mem, maxord)
    __CVodeSetMaxOrd(cvode_mem, convert(Cint, maxord))
end

function __CVodeSetMaxNumSteps(cvode_mem, mxsteps::Clong)
    ccall((:CVodeSetMaxNumSteps, libsundials_cvodes), Cint, (CVODEMemPtr, Clong), cvode_mem, mxsteps)
end

function CVodeSetMaxNumSteps(cvode_mem, mxsteps)
    __CVodeSetMaxNumSteps(cvode_mem, convert(Clong, mxsteps))
end

function __CVodeSetMaxHnilWarns(cvode_mem, mxhnil::Cint)
    ccall((:CVodeSetMaxHnilWarns, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, mxhnil)
end

function CVodeSetMaxHnilWarns(cvode_mem, mxhnil)
    __CVodeSetMaxHnilWarns(cvode_mem, convert(Cint, mxhnil))
end

function __CVodeSetStabLimDet(cvode_mem, stldet::Cint)
    ccall((:CVodeSetStabLimDet, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, stldet)
end

function CVodeSetStabLimDet(cvode_mem, stldet)
    __CVodeSetStabLimDet(cvode_mem, convert(Cint, stldet))
end

function CVodeSetInitStep(cvode_mem, hin::realtype)
    ccall((:CVodeSetInitStep, libsundials_cvodes), Cint, (CVODEMemPtr, realtype), cvode_mem, hin)
end

function CVodeSetMinStep(cvode_mem, hmin::realtype)
    ccall((:CVodeSetMinStep, libsundials_cvodes), Cint, (CVODEMemPtr, realtype), cvode_mem, hmin)
end

function CVodeSetMaxStep(cvode_mem, hmax::realtype)
    ccall((:CVodeSetMaxStep, libsundials_cvodes), Cint, (CVODEMemPtr, realtype), cvode_mem, hmax)
end

function CVodeSetStopTime(cvode_mem, tstop::realtype)
    ccall((:CVodeSetStopTime, libsundials_cvodes), Cint, (CVODEMemPtr, realtype), cvode_mem, tstop)
end

function __CVodeSetMaxErrTestFails(cvode_mem, maxnef::Cint)
    ccall((:CVodeSetMaxErrTestFails, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, maxnef)
end

function CVodeSetMaxErrTestFails(cvode_mem, maxnef)
    __CVodeSetMaxErrTestFails(cvode_mem, convert(Cint, maxnef))
end

function __CVodeSetMaxNonlinIters(cvode_mem, maxcor::Cint)
    ccall((:CVodeSetMaxNonlinIters, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, maxcor)
end

function CVodeSetMaxNonlinIters(cvode_mem, maxcor)
    __CVodeSetMaxNonlinIters(cvode_mem, convert(Cint, maxcor))
end

function __CVodeSetMaxConvFails(cvode_mem, maxncf::Cint)
    ccall((:CVodeSetMaxConvFails, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, maxncf)
end

function CVodeSetMaxConvFails(cvode_mem, maxncf)
    __CVodeSetMaxConvFails(cvode_mem, convert(Cint, maxncf))
end

function CVodeSetNonlinConvCoef(cvode_mem, nlscoef::realtype)
    ccall((:CVodeSetNonlinConvCoef, libsundials_cvodes), Cint, (CVODEMemPtr, realtype), cvode_mem, nlscoef)
end

function __CVodeSetIterType(cvode_mem, iter::Cint)
    ccall((:CVodeSetIterType, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, iter)
end

function CVodeSetIterType(cvode_mem, iter)
    __CVodeSetIterType(cvode_mem, convert(Cint, iter))
end

function CVodeSetRootDirection(cvode_mem, rootdir)
    ccall((:CVodeSetRootDirection, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Cint}), cvode_mem, rootdir)
end

function CVodeSetNoInactiveRootWarn(cvode_mem)
    ccall((:CVodeSetNoInactiveRootWarn, libsundials_cvodes), Cint, (CVODEMemPtr,), cvode_mem)
end

function __CVodeSetQuadErrCon(cvode_mem, errconQ::Cint)
    ccall((:CVodeSetQuadErrCon, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, errconQ)
end

function CVodeSetQuadErrCon(cvode_mem, errconQ)
    __CVodeSetQuadErrCon(cvode_mem, convert(Cint, errconQ))
end

function __CVodeSetSensDQMethod(cvode_mem, DQtype::Cint, DQrhomax::realtype)
    ccall((:CVodeSetSensDQMethod, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, realtype), cvode_mem, DQtype, DQrhomax)
end

function CVodeSetSensDQMethod(cvode_mem, DQtype, DQrhomax)
    __CVodeSetSensDQMethod(cvode_mem, convert(Cint, DQtype), DQrhomax)
end

function __CVodeSetSensErrCon(cvode_mem, errconS::Cint)
    ccall((:CVodeSetSensErrCon, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, errconS)
end

function CVodeSetSensErrCon(cvode_mem, errconS)
    __CVodeSetSensErrCon(cvode_mem, convert(Cint, errconS))
end

function __CVodeSetSensMaxNonlinIters(cvode_mem, maxcorS::Cint)
    ccall((:CVodeSetSensMaxNonlinIters, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, maxcorS)
end

function CVodeSetSensMaxNonlinIters(cvode_mem, maxcorS)
    __CVodeSetSensMaxNonlinIters(cvode_mem, convert(Cint, maxcorS))
end

function CVodeSetSensParams(cvode_mem, p, pbar, plist)
    ccall((:CVodeSetSensParams, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}, Ptr{realtype}, Ptr{Cint}), cvode_mem, p, pbar, plist)
end

function __CVodeSetQuadSensErrCon(cvode_mem, errconQS::Cint)
    ccall((:CVodeSetQuadSensErrCon, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, errconQS)
end

function CVodeSetQuadSensErrCon(cvode_mem, errconQS)
    __CVodeSetQuadSensErrCon(cvode_mem, convert(Cint, errconQS))
end

function CVodeSensToggleOff(cvode_mem)
    ccall((:CVodeSensToggleOff, libsundials_cvodes), Cint, (CVODEMemPtr,), cvode_mem)
end

function __CVode(cvode_mem, tout::realtype, yout::N_Vector, tret, itask::Cint)
    ccall((:CVode, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, N_Vector, Ptr{realtype}, Cint), cvode_mem, tout, yout, tret, itask)
end

function CVode(cvode_mem, tout, yout, tret, itask)
    __yout = convert(NVector, yout)
    __CVode(cvode_mem, tout, convert(N_Vector, __yout), tret, convert(Cint, itask))
end

function __CVodeGetDky(cvode_mem, t::realtype, k::Cint, dky::N_Vector)
    ccall((:CVodeGetDky, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Cint, N_Vector), cvode_mem, t, k, dky)
end

function CVodeGetDky(cvode_mem, t, k, dky)
    __dky = convert(NVector, dky)
    __CVodeGetDky(cvode_mem, t, convert(Cint, k), convert(N_Vector, __dky))
end

function __CVodeGetQuad(cvode_mem, tret, yQout::N_Vector)
    ccall((:CVodeGetQuad, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}, N_Vector), cvode_mem, tret, yQout)
end

function CVodeGetQuad(cvode_mem, tret, yQout)
    __yQout = convert(NVector, yQout)
    __CVodeGetQuad(cvode_mem, tret, convert(N_Vector, __yQout))
end

function __CVodeGetQuadDky(cvode_mem, t::realtype, k::Cint, dky::N_Vector)
    ccall((:CVodeGetQuadDky, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Cint, N_Vector), cvode_mem, t, k, dky)
end

function CVodeGetQuadDky(cvode_mem, t, k, dky)
    __dky = convert(NVector, dky)
    __CVodeGetQuadDky(cvode_mem, t, convert(Cint, k), convert(N_Vector, __dky))
end

function CVodeGetSens(cvode_mem, tret, ySout)
    ccall((:CVodeGetSens, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}, Ptr{N_Vector}), cvode_mem, tret, ySout)
end

function __CVodeGetSens1(cvode_mem, tret, is::Cint, ySout::N_Vector)
    ccall((:CVodeGetSens1, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}, Cint, N_Vector), cvode_mem, tret, is, ySout)
end

function CVodeGetSens1(cvode_mem, tret, is, ySout)
    __ySout = convert(NVector, ySout)
    __CVodeGetSens1(cvode_mem, tret, convert(Cint, is), convert(N_Vector, __ySout))
end

function __CVodeGetSensDky(cvode_mem, t::realtype, k::Cint, dkyA)
    ccall((:CVodeGetSensDky, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Cint, Ptr{N_Vector}), cvode_mem, t, k, dkyA)
end

function CVodeGetSensDky(cvode_mem, t, k, dkyA)
    __CVodeGetSensDky(cvode_mem, t, convert(Cint, k), dkyA)
end

function __CVodeGetSensDky1(cvode_mem, t::realtype, k::Cint, is::Cint, dky::N_Vector)
    ccall((:CVodeGetSensDky1, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Cint, Cint, N_Vector), cvode_mem, t, k, is, dky)
end

function CVodeGetSensDky1(cvode_mem, t, k, is, dky)
    __dky = convert(NVector, dky)
    __CVodeGetSensDky1(cvode_mem, t, convert(Cint, k), convert(Cint, is), convert(N_Vector, __dky))
end

function CVodeGetQuadSens(cvode_mem, tret, yQSout)
    ccall((:CVodeGetQuadSens, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}, Ptr{N_Vector}), cvode_mem, tret, yQSout)
end

function __CVodeGetQuadSens1(cvode_mem, tret, is::Cint, yQSout::N_Vector)
    ccall((:CVodeGetQuadSens1, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}, Cint, N_Vector), cvode_mem, tret, is, yQSout)
end

function CVodeGetQuadSens1(cvode_mem, tret, is, yQSout)
    __yQSout = convert(NVector, yQSout)
    __CVodeGetQuadSens1(cvode_mem, tret, convert(Cint, is), convert(N_Vector, __yQSout))
end

function __CVodeGetQuadSensDky(cvode_mem, t::realtype, k::Cint, dkyQS_all)
    ccall((:CVodeGetQuadSensDky, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Cint, Ptr{N_Vector}), cvode_mem, t, k, dkyQS_all)
end

function CVodeGetQuadSensDky(cvode_mem, t, k, dkyQS_all)
    __CVodeGetQuadSensDky(cvode_mem, t, convert(Cint, k), dkyQS_all)
end

function __CVodeGetQuadSensDky1(cvode_mem, t::realtype, k::Cint, is::Cint, dkyQS::N_Vector)
    ccall((:CVodeGetQuadSensDky1, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Cint, Cint, N_Vector), cvode_mem, t, k, is, dkyQS)
end

function CVodeGetQuadSensDky1(cvode_mem, t, k, is, dkyQS)
    __dkyQS = convert(NVector, dkyQS)
    __CVodeGetQuadSensDky1(cvode_mem, t, convert(Cint, k), convert(Cint, is), convert(N_Vector, __dkyQS))
end

function CVodeGetWorkSpace(cvode_mem, lenrw, leniw)
    ccall((:CVodeGetWorkSpace, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}), cvode_mem, lenrw, leniw)
end

function CVodeGetNumSteps(cvode_mem, nsteps)
    ccall((:CVodeGetNumSteps, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nsteps)
end

function CVodeGetNumRhsEvals(cvode_mem, nfevals)
    ccall((:CVodeGetNumRhsEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nfevals)
end

function CVodeGetNumLinSolvSetups(cvode_mem, nlinsetups)
    ccall((:CVodeGetNumLinSolvSetups, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nlinsetups)
end

function CVodeGetNumErrTestFails(cvode_mem, netfails)
    ccall((:CVodeGetNumErrTestFails, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, netfails)
end

function CVodeGetLastOrder(cvode_mem, qlast)
    ccall((:CVodeGetLastOrder, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Cint}), cvode_mem, qlast)
end

function CVodeGetCurrentOrder(cvode_mem, qcur)
    ccall((:CVodeGetCurrentOrder, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Cint}), cvode_mem, qcur)
end

function CVodeGetNumStabLimOrderReds(cvode_mem, nslred)
    ccall((:CVodeGetNumStabLimOrderReds, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nslred)
end

function CVodeGetActualInitStep(cvode_mem, hinused)
    ccall((:CVodeGetActualInitStep, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}), cvode_mem, hinused)
end

function CVodeGetLastStep(cvode_mem, hlast)
    ccall((:CVodeGetLastStep, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}), cvode_mem, hlast)
end

function CVodeGetCurrentStep(cvode_mem, hcur)
    ccall((:CVodeGetCurrentStep, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}), cvode_mem, hcur)
end

function CVodeGetCurrentTime(cvode_mem, tcur)
    ccall((:CVodeGetCurrentTime, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}), cvode_mem, tcur)
end

function CVodeGetTolScaleFactor(cvode_mem, tolsfac)
    ccall((:CVodeGetTolScaleFactor, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{realtype}), cvode_mem, tolsfac)
end

function __CVodeGetErrWeights(cvode_mem, eweight::N_Vector)
    ccall((:CVodeGetErrWeights, libsundials_cvodes), Cint, (CVODEMemPtr, N_Vector), cvode_mem, eweight)
end

function CVodeGetErrWeights(cvode_mem, eweight)
    __eweight = convert(NVector, eweight)
    __CVodeGetErrWeights(cvode_mem, convert(N_Vector, __eweight))
end

function __CVodeGetEstLocalErrors(cvode_mem, ele::N_Vector)
    ccall((:CVodeGetEstLocalErrors, libsundials_cvodes), Cint, (CVODEMemPtr, N_Vector), cvode_mem, ele)
end

function CVodeGetEstLocalErrors(cvode_mem, ele)
    __ele = convert(NVector, ele)
    __CVodeGetEstLocalErrors(cvode_mem, convert(N_Vector, __ele))
end

function CVodeGetNumGEvals(cvode_mem, ngevals)
    ccall((:CVodeGetNumGEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, ngevals)
end

function CVodeGetRootInfo(cvode_mem, rootsfound)
    ccall((:CVodeGetRootInfo, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Cint}), cvode_mem, rootsfound)
end

function CVodeGetIntegratorStats(cvode_mem, nsteps, nfevals, nlinsetups, netfails, qlast, qcur, hinused, hlast, hcur, tcur)
    ccall((:CVodeGetIntegratorStats, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}, Ptr{Clong}, Ptr{Clong}, Ptr{Cint}, Ptr{Cint}, Ptr{realtype}, Ptr{realtype}, Ptr{realtype}, Ptr{realtype}), cvode_mem, nsteps, nfevals, nlinsetups, netfails, qlast, qcur, hinused, hlast, hcur, tcur)
end

function CVodeGetNumNonlinSolvIters(cvode_mem, nniters)
    ccall((:CVodeGetNumNonlinSolvIters, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nniters)
end

function CVodeGetNumNonlinSolvConvFails(cvode_mem, nncfails)
    ccall((:CVodeGetNumNonlinSolvConvFails, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nncfails)
end

function CVodeGetNonlinSolvStats(cvode_mem, nniters, nncfails)
    ccall((:CVodeGetNonlinSolvStats, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}), cvode_mem, nniters, nncfails)
end

function __CVodeGetReturnFlagName(flag::Clong)
    ccall((:CVodeGetReturnFlagName, libsundials_cvodes), Cstring, (Clong,), flag)
end

function CVodeGetReturnFlagName(flag)
    __CVodeGetReturnFlagName(convert(Clong, flag))
end

function CVodeGetQuadNumRhsEvals(cvode_mem, nfQevals)
    ccall((:CVodeGetQuadNumRhsEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nfQevals)
end

function CVodeGetQuadNumErrTestFails(cvode_mem, nQetfails)
    ccall((:CVodeGetQuadNumErrTestFails, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nQetfails)
end

function __CVodeGetQuadErrWeights(cvode_mem, eQweight::N_Vector)
    ccall((:CVodeGetQuadErrWeights, libsundials_cvodes), Cint, (CVODEMemPtr, N_Vector), cvode_mem, eQweight)
end

function CVodeGetQuadErrWeights(cvode_mem, eQweight)
    __eQweight = convert(NVector, eQweight)
    __CVodeGetQuadErrWeights(cvode_mem, convert(N_Vector, __eQweight))
end

function CVodeGetQuadStats(cvode_mem, nfQevals, nQetfails)
    ccall((:CVodeGetQuadStats, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}), cvode_mem, nfQevals, nQetfails)
end

function CVodeGetSensNumRhsEvals(cvode_mem, nfSevals)
    ccall((:CVodeGetSensNumRhsEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nfSevals)
end

function CVodeGetNumRhsEvalsSens(cvode_mem, nfevalsS)
    ccall((:CVodeGetNumRhsEvalsSens, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nfevalsS)
end

function CVodeGetSensNumErrTestFails(cvode_mem, nSetfails)
    ccall((:CVodeGetSensNumErrTestFails, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nSetfails)
end

function CVodeGetSensNumLinSolvSetups(cvode_mem, nlinsetupsS)
    ccall((:CVodeGetSensNumLinSolvSetups, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nlinsetupsS)
end

function CVodeGetSensErrWeights(cvode_mem, eSweight)
    ccall((:CVodeGetSensErrWeights, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{N_Vector}), cvode_mem, eSweight)
end

function CVodeGetSensStats(cvode_mem, nfSevals, nfevalsS, nSetfails, nlinsetupsS)
    ccall((:CVodeGetSensStats, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}, Ptr{Clong}, Ptr{Clong}), cvode_mem, nfSevals, nfevalsS, nSetfails, nlinsetupsS)
end

function CVodeGetSensNumNonlinSolvIters(cvode_mem, nSniters)
    ccall((:CVodeGetSensNumNonlinSolvIters, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nSniters)
end

function CVodeGetSensNumNonlinSolvConvFails(cvode_mem, nSncfails)
    ccall((:CVodeGetSensNumNonlinSolvConvFails, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nSncfails)
end

function CVodeGetStgrSensNumNonlinSolvIters(cvode_mem, nSTGR1niters)
    ccall((:CVodeGetStgrSensNumNonlinSolvIters, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nSTGR1niters)
end

function CVodeGetStgrSensNumNonlinSolvConvFails(cvode_mem, nSTGR1ncfails)
    ccall((:CVodeGetStgrSensNumNonlinSolvConvFails, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nSTGR1ncfails)
end

function CVodeGetSensNonlinSolvStats(cvode_mem, nSniters, nSncfails)
    ccall((:CVodeGetSensNonlinSolvStats, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}), cvode_mem, nSniters, nSncfails)
end

function CVodeGetQuadSensNumRhsEvals(cvode_mem, nfQSevals)
    ccall((:CVodeGetQuadSensNumRhsEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nfQSevals)
end

function CVodeGetQuadSensNumErrTestFails(cvode_mem, nQSetfails)
    ccall((:CVodeGetQuadSensNumErrTestFails, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nQSetfails)
end

function CVodeGetQuadSensErrWeights(cvode_mem, eQSweight)
    ccall((:CVodeGetQuadSensErrWeights, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{N_Vector}), cvode_mem, eQSweight)
end

function CVodeGetQuadSensStats(cvode_mem, nfQSevals, nQSetfails)
    ccall((:CVodeGetQuadSensStats, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}), cvode_mem, nfQSevals, nQSetfails)
end

function __CVodeAdjInit(cvode_mem, steps::Clong, interp::Cint)
    ccall((:CVodeAdjInit, libsundials_cvodes), Cint, (CVODEMemPtr, Clong, Cint), cvode_mem, steps, interp)
end

function CVodeAdjInit(cvode_mem, steps, interp)
    __CVodeAdjInit(cvode_mem, convert(Clong, steps), convert(Cint, interp))
end

function CVodeAdjReInit(cvode_mem)
    ccall((:CVodeAdjReInit, libsundials_cvodes), Cint, (CVODEMemPtr,), cvode_mem)
end

function CVodeAdjFree(cvode_mem)
    ccall((:CVodeAdjFree, libsundials_cvodes), Cvoid, (CVODEMemPtr,), cvode_mem)
end

function __CVodeCreateB(cvode_mem, lmmB::Cint, iterB::Cint, which)
    ccall((:CVodeCreateB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Cint, Ptr{Cint}), cvode_mem, lmmB, iterB, which)
end

function CVodeCreateB(cvode_mem, lmmB, iterB, which)
    __CVodeCreateB(cvode_mem, convert(Cint, lmmB), convert(Cint, iterB), which)
end

function __CVodeInitB(cvode_mem, which::Cint, fB::CVRhsFnB, tB0::realtype, yB0::N_Vector)
    ccall((:CVodeInitB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVRhsFnB, realtype, N_Vector), cvode_mem, which, fB, tB0, yB0)
end

function CVodeInitB(cvode_mem, which, fB, tB0, yB0)
    __yB0 = convert(NVector, yB0)
    __CVodeInitB(cvode_mem, convert(Cint, which), fB, tB0, convert(N_Vector, __yB0))
end

function __CVodeInitBS(cvode_mem, which::Cint, fBs::CVRhsFnBS, tB0::realtype, yB0::N_Vector)
    ccall((:CVodeInitBS, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVRhsFnBS, realtype, N_Vector), cvode_mem, which, fBs, tB0, yB0)
end

function CVodeInitBS(cvode_mem, which, fBs, tB0, yB0)
    __yB0 = convert(NVector, yB0)
    __CVodeInitBS(cvode_mem, convert(Cint, which), fBs, tB0, convert(N_Vector, __yB0))
end

function __CVodeReInitB(cvode_mem, which::Cint, tB0::realtype, yB0::N_Vector)
    ccall((:CVodeReInitB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, realtype, N_Vector), cvode_mem, which, tB0, yB0)
end

function CVodeReInitB(cvode_mem, which, tB0, yB0)
    __yB0 = convert(NVector, yB0)
    __CVodeReInitB(cvode_mem, convert(Cint, which), tB0, convert(N_Vector, __yB0))
end

function __CVodeSStolerancesB(cvode_mem, which::Cint, reltolB::realtype, abstolB::realtype)
    ccall((:CVodeSStolerancesB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, realtype, realtype), cvode_mem, which, reltolB, abstolB)
end

function CVodeSStolerancesB(cvode_mem, which, reltolB, abstolB)
    __CVodeSStolerancesB(cvode_mem, convert(Cint, which), reltolB, abstolB)
end

function __CVodeSVtolerancesB(cvode_mem, which::Cint, reltolB::realtype, abstolB::N_Vector)
    ccall((:CVodeSVtolerancesB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, realtype, N_Vector), cvode_mem, which, reltolB, abstolB)
end

function CVodeSVtolerancesB(cvode_mem, which, reltolB, abstolB)
    __abstolB = convert(NVector, abstolB)
    __CVodeSVtolerancesB(cvode_mem, convert(Cint, which), reltolB, convert(N_Vector, __abstolB))
end

function __CVodeQuadInitB(cvode_mem, which::Cint, fQB::CVQuadRhsFnB, yQB0::N_Vector)
    ccall((:CVodeQuadInitB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVQuadRhsFnB, N_Vector), cvode_mem, which, fQB, yQB0)
end

function CVodeQuadInitB(cvode_mem, which, fQB, yQB0)
    __yQB0 = convert(NVector, yQB0)
    __CVodeQuadInitB(cvode_mem, convert(Cint, which), fQB, convert(N_Vector, __yQB0))
end

function __CVodeQuadInitBS(cvode_mem, which::Cint, fQBs::CVQuadRhsFnBS, yQB0::N_Vector)
    ccall((:CVodeQuadInitBS, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVQuadRhsFnBS, N_Vector), cvode_mem, which, fQBs, yQB0)
end

function CVodeQuadInitBS(cvode_mem, which, fQBs, yQB0)
    __yQB0 = convert(NVector, yQB0)
    __CVodeQuadInitBS(cvode_mem, convert(Cint, which), fQBs, convert(N_Vector, __yQB0))
end

function __CVodeQuadReInitB(cvode_mem, which::Cint, yQB0::N_Vector)
    ccall((:CVodeQuadReInitB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, N_Vector), cvode_mem, which, yQB0)
end

function CVodeQuadReInitB(cvode_mem, which, yQB0)
    __yQB0 = convert(NVector, yQB0)
    __CVodeQuadReInitB(cvode_mem, convert(Cint, which), convert(N_Vector, __yQB0))
end

function __CVodeQuadSStolerancesB(cvode_mem, which::Cint, reltolQB::realtype, abstolQB::realtype)
    ccall((:CVodeQuadSStolerancesB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, realtype, realtype), cvode_mem, which, reltolQB, abstolQB)
end

function CVodeQuadSStolerancesB(cvode_mem, which, reltolQB, abstolQB)
    __CVodeQuadSStolerancesB(cvode_mem, convert(Cint, which), reltolQB, abstolQB)
end

function __CVodeQuadSVtolerancesB(cvode_mem, which::Cint, reltolQB::realtype, abstolQB::N_Vector)
    ccall((:CVodeQuadSVtolerancesB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, realtype, N_Vector), cvode_mem, which, reltolQB, abstolQB)
end

function CVodeQuadSVtolerancesB(cvode_mem, which, reltolQB, abstolQB)
    __abstolQB = convert(NVector, abstolQB)
    __CVodeQuadSVtolerancesB(cvode_mem, convert(Cint, which), reltolQB, convert(N_Vector, __abstolQB))
end

function __CVodeF(cvode_mem, tout::realtype, yout::N_Vector, tret, itask::Cint, ncheckPtr)
    ccall((:CVodeF, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, N_Vector, Ptr{realtype}, Cint, Ptr{Cint}), cvode_mem, tout, yout, tret, itask, ncheckPtr)
end

function CVodeF(cvode_mem, tout, yout, tret, itask, ncheckPtr)
    __yout = convert(NVector, yout)
    __CVodeF(cvode_mem, tout, convert(N_Vector, __yout), tret, convert(Cint, itask), ncheckPtr)
end

function __CVodeB(cvode_mem, tBout::realtype, itaskB::Cint)
    ccall((:CVodeB, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, Cint), cvode_mem, tBout, itaskB)
end

function CVodeB(cvode_mem, tBout, itaskB)
    __CVodeB(cvode_mem, tBout, convert(Cint, itaskB))
end

function CVodeSetAdjNoSensi(cvode_mem)
    ccall((:CVodeSetAdjNoSensi, libsundials_cvodes), Cint, (CVODEMemPtr,), cvode_mem)
end

function __CVodeSetIterTypeB(cvode_mem, which::Cint, iterB::Cint)
    ccall((:CVodeSetIterTypeB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Cint), cvode_mem, which, iterB)
end

function CVodeSetIterTypeB(cvode_mem, which, iterB)
    __CVodeSetIterTypeB(cvode_mem, convert(Cint, which), convert(Cint, iterB))
end

function __CVodeSetUserDataB(cvode_mem, which::Cint, user_dataB)
    ccall((:CVodeSetUserDataB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Any), cvode_mem, which, user_dataB)
end

function CVodeSetUserDataB(cvode_mem, which, user_dataB)
    __CVodeSetUserDataB(cvode_mem, convert(Cint, which), user_dataB)
end

function __CVodeSetMaxOrdB(cvode_mem, which::Cint, maxordB::Cint)
    ccall((:CVodeSetMaxOrdB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Cint), cvode_mem, which, maxordB)
end

function CVodeSetMaxOrdB(cvode_mem, which, maxordB)
    __CVodeSetMaxOrdB(cvode_mem, convert(Cint, which), convert(Cint, maxordB))
end

function __CVodeSetMaxNumStepsB(cvode_mem, which::Cint, mxstepsB::Clong)
    ccall((:CVodeSetMaxNumStepsB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Clong), cvode_mem, which, mxstepsB)
end

function CVodeSetMaxNumStepsB(cvode_mem, which, mxstepsB)
    __CVodeSetMaxNumStepsB(cvode_mem, convert(Cint, which), convert(Clong, mxstepsB))
end

function __CVodeSetStabLimDetB(cvode_mem, which::Cint, stldetB::Cint)
    ccall((:CVodeSetStabLimDetB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Cint), cvode_mem, which, stldetB)
end

function CVodeSetStabLimDetB(cvode_mem, which, stldetB)
    __CVodeSetStabLimDetB(cvode_mem, convert(Cint, which), convert(Cint, stldetB))
end

function __CVodeSetInitStepB(cvode_mem, which::Cint, hinB::realtype)
    ccall((:CVodeSetInitStepB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, realtype), cvode_mem, which, hinB)
end

function CVodeSetInitStepB(cvode_mem, which, hinB)
    __CVodeSetInitStepB(cvode_mem, convert(Cint, which), hinB)
end

function __CVodeSetMinStepB(cvode_mem, which::Cint, hminB::realtype)
    ccall((:CVodeSetMinStepB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, realtype), cvode_mem, which, hminB)
end

function CVodeSetMinStepB(cvode_mem, which, hminB)
    __CVodeSetMinStepB(cvode_mem, convert(Cint, which), hminB)
end

function __CVodeSetMaxStepB(cvode_mem, which::Cint, hmaxB::realtype)
    ccall((:CVodeSetMaxStepB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, realtype), cvode_mem, which, hmaxB)
end

function CVodeSetMaxStepB(cvode_mem, which, hmaxB)
    __CVodeSetMaxStepB(cvode_mem, convert(Cint, which), hmaxB)
end

function __CVodeSetQuadErrConB(cvode_mem, which::Cint, errconQB::Cint)
    ccall((:CVodeSetQuadErrConB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Cint), cvode_mem, which, errconQB)
end

function CVodeSetQuadErrConB(cvode_mem, which, errconQB)
    __CVodeSetQuadErrConB(cvode_mem, convert(Cint, which), convert(Cint, errconQB))
end

function __CVodeGetB(cvode_mem, which::Cint, tBret, yB::N_Vector)
    ccall((:CVodeGetB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Ptr{realtype}, N_Vector), cvode_mem, which, tBret, yB)
end

function CVodeGetB(cvode_mem, which, tBret, yB)
    __yB = convert(NVector, yB)
    __CVodeGetB(cvode_mem, convert(Cint, which), tBret, convert(N_Vector, __yB))
end

function __CVodeGetQuadB(cvode_mem, which::Cint, tBret, qB::N_Vector)
    ccall((:CVodeGetQuadB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Ptr{realtype}, N_Vector), cvode_mem, which, tBret, qB)
end

function CVodeGetQuadB(cvode_mem, which, tBret, qB)
    __qB = convert(NVector, qB)
    __CVodeGetQuadB(cvode_mem, convert(Cint, which), tBret, convert(N_Vector, __qB))
end

function __CVodeGetAdjCVodeBmem(cvode_mem, which::Cint)
    ccall((:CVodeGetAdjCVodeBmem, libsundials_cvodes), Ptr{Cvoid}, (CVODEMemPtr, Cint), cvode_mem, which)
end

function CVodeGetAdjCVodeBmem(cvode_mem, which)
    __CVodeGetAdjCVodeBmem(cvode_mem, convert(Cint, which))
end

function __CVodeGetAdjY(cvode_mem, t::realtype, y::N_Vector)
    ccall((:CVodeGetAdjY, libsundials_cvodes), Cint, (CVODEMemPtr, realtype, N_Vector), cvode_mem, t, y)
end

function CVodeGetAdjY(cvode_mem, t, y)
    __y = convert(NVector, y)
    __CVodeGetAdjY(cvode_mem, t, convert(N_Vector, __y))
end

function CVodeGetAdjCheckPointsInfo(cvode_mem, ckpnt)
    ccall((:CVodeGetAdjCheckPointsInfo, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{CVadjCheckPointRec}), cvode_mem, ckpnt)
end

function __CVodeGetAdjDataPointHermite(cvode_mem, which::Cint, t, y::N_Vector, yd::N_Vector)
    ccall((:CVodeGetAdjDataPointHermite, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Ptr{realtype}, N_Vector, N_Vector), cvode_mem, which, t, y, yd)
end

function CVodeGetAdjDataPointHermite(cvode_mem, which, t, y, yd)
    __y = convert(NVector, y)
    __yd = convert(NVector, yd)
    __CVodeGetAdjDataPointHermite(cvode_mem, convert(Cint, which), t, convert(N_Vector, __y), convert(N_Vector, __yd))
end

function __CVodeGetAdjDataPointPolynomial(cvode_mem, which::Cint, t, order, y::N_Vector)
    ccall((:CVodeGetAdjDataPointPolynomial, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, Ptr{realtype}, Ptr{Cint}, N_Vector), cvode_mem, which, t, order, y)
end

function CVodeGetAdjDataPointPolynomial(cvode_mem, which, t, order, y)
    __y = convert(NVector, y)
    __CVodeGetAdjDataPointPolynomial(cvode_mem, convert(Cint, which), t, order, convert(N_Vector, __y))
end

function CVodeGetAdjCurrentCheckPoint(cvode_mem, addr)
    ccall((:CVodeGetAdjCurrentCheckPoint, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Ptr{Cvoid}}), cvode_mem, addr)
end
# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/cvodes/cvodes_bandpre.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function CVBandPrecInit(cvode_mem, N::sunindextype, mu::sunindextype, ml::sunindextype)
    ccall((:CVBandPrecInit, libsundials_cvodes), Cint, (CVODEMemPtr, sunindextype, sunindextype, sunindextype), cvode_mem, N, mu, ml)
end

function CVBandPrecGetWorkSpace(cvode_mem, lenrwLS, leniwLS)
    ccall((:CVBandPrecGetWorkSpace, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}), cvode_mem, lenrwLS, leniwLS)
end

function CVBandPrecGetNumRhsEvals(cvode_mem, nfevalsBP)
    ccall((:CVBandPrecGetNumRhsEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nfevalsBP)
end

function __CVBandPrecInitB(cvode_mem, which::Cint, nB::sunindextype, muB::sunindextype, mlB::sunindextype)
    ccall((:CVBandPrecInitB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, sunindextype, sunindextype, sunindextype), cvode_mem, which, nB, muB, mlB)
end

function CVBandPrecInitB(cvode_mem, which, nB, muB, mlB)
    __CVBandPrecInitB(cvode_mem, convert(Cint, which), nB, muB, mlB)
end
# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/cvodes/cvodes_bbdpre.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function CVBBDPrecInit(cvode_mem, Nlocal::sunindextype, mudq::sunindextype, mldq::sunindextype, mukeep::sunindextype, mlkeep::sunindextype, dqrely::realtype, gloc::CVLocalFn, cfn::CVCommFn)
    ccall((:CVBBDPrecInit, libsundials_cvodes), Cint, (CVODEMemPtr, sunindextype, sunindextype, sunindextype, sunindextype, sunindextype, realtype, CVLocalFn, CVCommFn), cvode_mem, Nlocal, mudq, mldq, mukeep, mlkeep, dqrely, gloc, cfn)
end

function CVBBDPrecReInit(cvode_mem, mudq::sunindextype, mldq::sunindextype, dqrely::realtype)
    ccall((:CVBBDPrecReInit, libsundials_cvodes), Cint, (CVODEMemPtr, sunindextype, sunindextype, realtype), cvode_mem, mudq, mldq, dqrely)
end

function CVBBDPrecGetWorkSpace(cvode_mem, lenrwBBDP, leniwBBDP)
    ccall((:CVBBDPrecGetWorkSpace, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}), cvode_mem, lenrwBBDP, leniwBBDP)
end

function CVBBDPrecGetNumGfnEvals(cvode_mem, ngevalsBBDP)
    ccall((:CVBBDPrecGetNumGfnEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, ngevalsBBDP)
end

function __CVBBDPrecInitB(cvode_mem, which::Cint, NlocalB::sunindextype, mudqB::sunindextype, mldqB::sunindextype, mukeepB::sunindextype, mlkeepB::sunindextype, dqrelyB::realtype, glocB::CVLocalFnB, cfnB::CVCommFnB)
    ccall((:CVBBDPrecInitB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, sunindextype, sunindextype, sunindextype, sunindextype, sunindextype, realtype, CVLocalFnB, CVCommFnB), cvode_mem, which, NlocalB, mudqB, mldqB, mukeepB, mlkeepB, dqrelyB, glocB, cfnB)
end

function CVBBDPrecInitB(cvode_mem, which, NlocalB, mudqB, mldqB, mukeepB, mlkeepB, dqrelyB, glocB, cfnB)
    __CVBBDPrecInitB(cvode_mem, convert(Cint, which), NlocalB, mudqB, mldqB, mukeepB, mlkeepB, dqrelyB, glocB, cfnB)
end

function __CVBBDPrecReInitB(cvode_mem, which::Cint, mudqB::sunindextype, mldqB::sunindextype, dqrelyB::realtype)
    ccall((:CVBBDPrecReInitB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, sunindextype, sunindextype, realtype), cvode_mem, which, mudqB, mldqB, dqrelyB)
end

function CVBBDPrecReInitB(cvode_mem, which, mudqB, mldqB, dqrelyB)
    __CVBBDPrecReInitB(cvode_mem, convert(Cint, which), mudqB, mldqB, dqrelyB)
end
# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/cvodes/cvodes_diag.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function CVDiag(cvode_mem)
    ccall((:CVDiag, libsundials_cvodes), Cint, (CVODEMemPtr,), cvode_mem)
end

function CVDiagGetWorkSpace(cvode_mem, lenrwLS, leniwLS)
    ccall((:CVDiagGetWorkSpace, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}), cvode_mem, lenrwLS, leniwLS)
end

function CVDiagGetNumRhsEvals(cvode_mem, nfevalsLS)
    ccall((:CVDiagGetNumRhsEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nfevalsLS)
end

function CVDiagGetLastFlag(cvode_mem, flag)
    ccall((:CVDiagGetLastFlag, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, flag)
end

function __CVDiagGetReturnFlagName(flag::Clong)
    ccall((:CVDiagGetReturnFlagName, libsundials_cvodes), Cstring, (Clong,), flag)
end

function CVDiagGetReturnFlagName(flag)
    __CVDiagGetReturnFlagName(convert(Clong, flag))
end

function __CVDiagB(cvode_mem, which::Cint)
    ccall((:CVDiagB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint), cvode_mem, which)
end

function CVDiagB(cvode_mem, which)
    __CVDiagB(cvode_mem, convert(Cint, which))
end
# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/cvodes/cvodes_direct.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function CVDlsSetLinearSolver(cvode_mem, LS::SUNLinearSolver, A::SUNMatrix)
    ccall((:CVDlsSetLinearSolver, libsundials_cvodes), Cint, (CVODEMemPtr, SUNLinearSolver, SUNMatrix), cvode_mem, LS, A)
end

function CVDlsSetJacFn(cvode_mem, jac::CVDlsJacFn)
    ccall((:CVDlsSetJacFn, libsundials_cvodes), Cint, (CVODEMemPtr, CVDlsJacFn), cvode_mem, jac)
end

function CVDlsGetWorkSpace(cvode_mem, lenrwLS, leniwLS)
    ccall((:CVDlsGetWorkSpace, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}), cvode_mem, lenrwLS, leniwLS)
end

function CVDlsGetNumJacEvals(cvode_mem, njevals)
    ccall((:CVDlsGetNumJacEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, njevals)
end

function CVDlsGetNumRhsEvals(cvode_mem, nfevalsLS)
    ccall((:CVDlsGetNumRhsEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nfevalsLS)
end

function CVDlsGetLastFlag(cvode_mem, flag)
    ccall((:CVDlsGetLastFlag, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, flag)
end

function __CVDlsGetReturnFlagName(flag::Clong)
    ccall((:CVDlsGetReturnFlagName, libsundials_cvodes), Cstring, (Clong,), flag)
end

function CVDlsGetReturnFlagName(flag)
    __CVDlsGetReturnFlagName(convert(Clong, flag))
end

function __CVDlsSetLinearSolverB(cvode_mem, which::Cint, LS::SUNLinearSolver, A::SUNMatrix)
    ccall((:CVDlsSetLinearSolverB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, SUNLinearSolver, SUNMatrix), cvode_mem, which, LS, A)
end

function CVDlsSetLinearSolverB(cvode_mem, which, LS, A)
    __CVDlsSetLinearSolverB(cvode_mem, convert(Cint, which), LS, A)
end

function __CVDlsSetJacFnB(cvode_mem, which::Cint, jacB::CVDlsJacFnB)
    ccall((:CVDlsSetJacFnB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVDlsJacFnB), cvode_mem, which, jacB)
end

function CVDlsSetJacFnB(cvode_mem, which, jacB)
    __CVDlsSetJacFnB(cvode_mem, convert(Cint, which), jacB)
end

function __CVDlsSetJacFnBS(cvode_mem, which::Cint, jacBS::CVDlsJacFnBS)
    ccall((:CVDlsSetJacFnBS, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVDlsJacFnBS), cvode_mem, which, jacBS)
end

function CVDlsSetJacFnBS(cvode_mem, which, jacBS)
    __CVDlsSetJacFnBS(cvode_mem, convert(Cint, which), jacBS)
end
# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/cvodes/cvodes_impl.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

# Julia wrapper for header: /home/osboxes/.julia/v0.6/Sundials/deps/usr/include/cvodes/cvodes_spils.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function CVSpilsSetLinearSolver(cvode_mem, LS::SUNLinearSolver)
    ccall((:CVSpilsSetLinearSolver, libsundials_cvodes), Cint, (CVODEMemPtr, SUNLinearSolver), cvode_mem, LS)
end

function CVSpilsSetEpsLin(cvode_mem, eplifac::realtype)
    ccall((:CVSpilsSetEpsLin, libsundials_cvodes), Cint, (CVODEMemPtr, realtype), cvode_mem, eplifac)
end

function CVSpilsSetPreconditioner(cvode_mem, pset::CVSpilsPrecSetupFn, psolve::CVSpilsPrecSolveFn)
    ccall((:CVSpilsSetPreconditioner, libsundials_cvodes), Cint, (CVODEMemPtr, CVSpilsPrecSetupFn, CVSpilsPrecSolveFn), cvode_mem, pset, psolve)
end

function CVSpilsSetJacTimes(cvode_mem, jtsetup::CVSpilsJacTimesSetupFn, jtimes::CVSpilsJacTimesVecFn)
    ccall((:CVSpilsSetJacTimes, libsundials_cvodes), Cint, (CVODEMemPtr, CVSpilsJacTimesSetupFn, CVSpilsJacTimesVecFn), cvode_mem, jtsetup, jtimes)
end

function CVSpilsGetWorkSpace(cvode_mem, lenrwLS, leniwLS)
    ccall((:CVSpilsGetWorkSpace, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}, Ptr{Clong}), cvode_mem, lenrwLS, leniwLS)
end

function CVSpilsGetNumPrecEvals(cvode_mem, npevals)
    ccall((:CVSpilsGetNumPrecEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, npevals)
end

function CVSpilsGetNumPrecSolves(cvode_mem, npsolves)
    ccall((:CVSpilsGetNumPrecSolves, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, npsolves)
end

function CVSpilsGetNumLinIters(cvode_mem, nliters)
    ccall((:CVSpilsGetNumLinIters, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nliters)
end

function CVSpilsGetNumConvFails(cvode_mem, nlcfails)
    ccall((:CVSpilsGetNumConvFails, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nlcfails)
end

function CVSpilsGetNumJTSetupEvals(cvode_mem, njtsetups)
    ccall((:CVSpilsGetNumJTSetupEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, njtsetups)
end

function CVSpilsGetNumJtimesEvals(cvode_mem, njvevals)
    ccall((:CVSpilsGetNumJtimesEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, njvevals)
end

function CVSpilsGetNumRhsEvals(cvode_mem, nfevalsLS)
    ccall((:CVSpilsGetNumRhsEvals, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, nfevalsLS)
end

function CVSpilsGetLastFlag(cvode_mem, flag)
    ccall((:CVSpilsGetLastFlag, libsundials_cvodes), Cint, (CVODEMemPtr, Ptr{Clong}), cvode_mem, flag)
end

function __CVSpilsGetReturnFlagName(flag::Clong)
    ccall((:CVSpilsGetReturnFlagName, libsundials_cvodes), Cstring, (Clong,), flag)
end

function CVSpilsGetReturnFlagName(flag)
    __CVSpilsGetReturnFlagName(convert(Clong, flag))
end

function __CVSpilsSetLinearSolverB(cvode_mem, which::Cint, LS::SUNLinearSolver)
    ccall((:CVSpilsSetLinearSolverB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, SUNLinearSolver), cvode_mem, which, LS)
end

function CVSpilsSetLinearSolverB(cvode_mem, which, LS)
    __CVSpilsSetLinearSolverB(cvode_mem, convert(Cint, which), LS)
end

function __CVSpilsSetEpsLinB(cvode_mem, which::Cint, eplifacB::realtype)
    ccall((:CVSpilsSetEpsLinB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, realtype), cvode_mem, which, eplifacB)
end

function CVSpilsSetEpsLinB(cvode_mem, which, eplifacB)
    __CVSpilsSetEpsLinB(cvode_mem, convert(Cint, which), eplifacB)
end

function __CVSpilsSetPreconditionerB(cvode_mem, which::Cint, psetB::CVSpilsPrecSetupFnB, psolveB::CVSpilsPrecSolveFnB)
    ccall((:CVSpilsSetPreconditionerB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVSpilsPrecSetupFnB, CVSpilsPrecSolveFnB), cvode_mem, which, psetB, psolveB)
end

function CVSpilsSetPreconditionerB(cvode_mem, which, psetB, psolveB)
    __CVSpilsSetPreconditionerB(cvode_mem, convert(Cint, which), psetB, psolveB)
end

function __CVSpilsSetPreconditionerBS(cvode_mem, which::Cint, psetBS::CVSpilsPrecSetupFnBS, psolveBS::CVSpilsPrecSolveFnBS)
    ccall((:CVSpilsSetPreconditionerBS, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVSpilsPrecSetupFnBS, CVSpilsPrecSolveFnBS), cvode_mem, which, psetBS, psolveBS)
end

function CVSpilsSetPreconditionerBS(cvode_mem, which, psetBS, psolveBS)
    __CVSpilsSetPreconditionerBS(cvode_mem, convert(Cint, which), psetBS, psolveBS)
end

function __CVSpilsSetJacTimesB(cvode_mem, which::Cint, jtsetupB::CVSpilsJacTimesSetupFnB, jtimesB::CVSpilsJacTimesVecFnB)
    ccall((:CVSpilsSetJacTimesB, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVSpilsJacTimesSetupFnB, CVSpilsJacTimesVecFnB), cvode_mem, which, jtsetupB, jtimesB)
end

function CVSpilsSetJacTimesB(cvode_mem, which, jtsetupB, jtimesB)
    __CVSpilsSetJacTimesB(cvode_mem, convert(Cint, which), jtsetupB, jtimesB)
end

function __CVSpilsSetJacTimesBS(cvode_mem, which::Cint, jtsetupBS::CVSpilsJacTimesSetupFnBS, jtimesBS::CVSpilsJacTimesVecFnBS)
    ccall((:CVSpilsSetJacTimesBS, libsundials_cvodes), Cint, (CVODEMemPtr, Cint, CVSpilsJacTimesSetupFnBS, CVSpilsJacTimesVecFnBS), cvode_mem, which, jtsetupBS, jtimesBS)
end

function CVSpilsSetJacTimesBS(cvode_mem, which, jtsetupBS, jtimesBS)
    __CVSpilsSetJacTimesBS(cvode_mem, convert(Cint, which), jtsetupBS, jtimesBS)
end


text:
"""
    U1 <: DAS
U1 symmetry singleton-type
"""
struct U1 <: DAS end
Base.show(io::IO, ::U1) = print(io,"U1")
"""
    U1Charges <: DASCharges
type for collection of `U1Charge` that holds `StepRange{Int,Int}` which represents the valid
values for `U1Charge`.

# Example
```julia-repl
julia>a = U1Charges(-1:1);
julia>foreach(println, a)
U1Charge(-1)
U1Charge(0)
U1Charge(1)
```
"""
struct U1Charges <: DASCharges
    v::StepRange{Int,Int}
end
Base.show(io::IO, s::U1Charges) = print(io,"U1Charges(",s.v,")")

function ⊕(a::U1Charges, b::U1Charges)
    loa, hia = extrema(a.v)
    lob, hib = extrema(b.v)
    step = min(abs(a.v.step), abs(b.v.step))
    return U1Charges((loa + lob):step:(hia + hib))
end
Base.inv(a::U1Charges) = U1Charges(-a.v.stop:(a.v.step):-a.v.start)
Base.length(a::U1Charges) = length(a.v)
Base.getindex(s::U1Charges, i::Int) = U1Charge(s.v[i])
chargestype(::U1) = U1Charges
Base.eltype(::Union{U1Charges, Type{U1Charges}}) = U1Charge
Base.intersect(a::U1Charges, b::U1Charges) = U1Charges(intersect(a.v,b.v))

"""
    U1Charge <: DASCharge
holds the charge of a U1 symmetry as an integer.

# Example
```julia-repl
julia>a = U1Charge(1);
julia>a ⊕ a
U1Charge(2)
```
"""
struct U1Charge <: DASCharge
    ch::Int
end
Base.show(io::IO, s::U1Charge) = print(io,"U1Charge(",s.ch,")")

⊕(a::U1Charge, b::U1Charge) = U1Charge(a.ch + b.ch)
function chargeindex(ch::U1Charge, chs::U1Charges)
    ch in chs || throw(ArgumentError(string(ch, " not in ", chs)))
    div(ch.ch - chs.v.start, chs.v.step)+1
end
chargetype(::U1) = U1Charge
Base.zero(::Type{U1Charge}) = U1Charge(zero(Int))
Base.:+(chs::U1Charges, ch::U1Charge) = U1Charges(chs.v .+ ch.ch)

ext: jl


text:
reset_default_graph(); sess = Session()
@testset "indexing for rank 3 tensors" begin
    a = rand(100,10,20)
    i1 = 3:8
    i2 = [1;3;4]
    V = a[i1,i2,:]
    P = constant(a)[i1,i2,:]
    @test run(sess, P)≈V
    P = constant(a)[2,i2,:]
    @test run(sess, P)≈a[2,i2,:]
    P = constant(a)[2,i2,5]
    @test run(sess, P)≈a[2,i2,5]
end

@testset "fcx" begin
    config = [2, 20,20,20,3]
    x = constant(rand(10,2))
    θ = ae_init(config)
    u, du = fcx(x, config[2:end], θ)
    y = ae(x, config[2:end], θ)

    @test run(sess, u) ≈ run(sess, y)

    DU = run(sess, du)
    @test run(sess, tf.gradients(y[:,1], x)[1]) ≈ DU[:,1,:]
    @test run(sess, tf.gradients(y[:,2], x)[1]) ≈ DU[:,2,:]
    @test run(sess, tf.gradients(y[:,3], x)[1]) ≈ DU[:,3,:]
end

@testset "dropout" begin
    a = rand(10,2)
    @test sum(run(sess, dropout(a, 0.999, true)).==0)/20>0.9
    @test sum(run(sess, dropout(a, 0.999, false)).==0)==0
end


text:
"""
    Simpler and more direct way to compute the transition matrix. Less precise.
"""
function Transition_Matrix2(par::ParsGrowth, bpar::BParsGrowth; T = 1_000_000)
    @unpack_ParsGrowth par
    @unpack_BParsGrowth bpar
    Π     = zeros(N, N)
    for i in 1:N
        a_bar = a_grid[i]
        μ     = μ_n(a_bar, par, bpar)

        a_next     = μ .+ √V_n*randn(T) .+ √σ²_ϵ.*randn(T)
        a_bar_next = n./(n+1).*a_bar .+ 1 ./(n+1).*a_next

        f          = ecdf(a_bar_next)

        for j in 1:N
            if j == 1
                Π[i,j] = f(a_thresholds[1])
            elseif j == N
                Π[i,j] = 1 - f(a_thresholds[j-1])
            else
                Π[i,j] = f(a_thresholds[j]) - f(a_thresholds[j-1])
            end
        end
    end
    return Π
end


text:
# Autogenerated wrapper script for BLST_jll for x86_64-w64-mingw32
export libblst

JLLWrappers.@generate_wrapper_header("BLST")
JLLWrappers.@declare_library_product(libblst, "libblst.dll")
function __init__()
    JLLWrappers.@generate_init_header()
    JLLWrappers.@init_library_product(
        libblst,
        "bin\\libblst.dll",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
function hessqr(A::AbstractArray{T,2}) where {T<:Number}
#
#  hessqr performs QR decomposition on an upper
#      Hessenberg matrix
#
#  assume A is a Hessenberg matrix
#  output  R -- upper triangular
#          Q -- rotation used
#
   m, n = size(A)
   if m < n throw(ArgumentError("m ($m) must be >= n ($n)")) end

   R = copy(A)
   Q = zeros(T, 2, min(n,m-1))

   for j = 1:n
       if j < m
           rjj = R[j,j]; rjpj = R[j+1,j]
           d = hypot(abs(rjj), abs(rjpj))
           if d != 0
               c = conj(rjj) / d; s = conj(rjpj) / d
               Tr = [c s; -conj(s) conj(c)]
               R[j:j+1,j:n] = Tr * R[j:j+1,j:n]
               Q[1,j] = c; Q[2,j] = s
           else
               Q[1,j] = 1; Q[2,j] = 0
           end
       end
   end
   R, Q
end


text:
# Container operations

# TODO: Macroize these definitions

function Base.push!(dv::DataVector, v::Missing)
    resize!(dv.data, length(dv.data) + 1)
    push!(dv.na, true)
    return v
end

function Base.push!(dv::DataVector{S}, v::T) where {S, T}
    push!(dv.data, v)
    push!(dv.na, false)
    return v
end

function Base.pop!(dv::DataVector)
    d, m = pop!(dv.data), pop!(dv.na)
    if m
        return missing
    else
        return d
    end
end

function Base.unshift!(dv::DataVector{T}, v::Missing) where T
    ccall(:jl_array_grow_beg, Cvoid, (Any, UInt), dv.data, 1)
    pushfirst!(dv.na, true)
    return v
end

function Base.unshift!(dv::DataVector{S}, v::T) where {S, T}
    pushfirst!(dv.data, v)
    pushfirst!(dv.na, false)
    return v
end

function Base.shift!(dv::DataVector{T}) where T
    d, m = popfirst!(dv.data), popfirst!(dv.na)
    if m
        return missing
    else
        return d
    end
end

function Base.splice!(dv::DataVector, inds::Union{Integer, UnitRange{Int}})
    v = dv[inds]
    deleteat!(dv.data, inds)
    deleteat!(dv.na, inds)
    v
end

function Base.splice!(dv::DataVector, inds::Union{Integer, UnitRange{Int}}, ins::AbstractVector)
    # We cannot merely use the implementation in Base because this
    # needs to handle missing in the replacement vector
    v = dv[inds]
    m = length(ins)
    a = dv.data
    if m == 0
        deleteat!(a, inds)
        deleteat!(dv.na, inds)
        return v
    end

    n = length(a)
    f = first(inds)
    l = last(inds)
    d = length(inds)

    if m < d
        delta = d - m
        i = (f - 1 < n - l) ? f : (l - delta + 1)
        Base._deleteat!(a, i, delta)
    elseif m > d
        delta = m - d
        i = (f - 1 < n - l) ? f : (l + 1)
        Base._growat!(a, i, delta)
    end

    for k = 1:m
        if !ismissing(ins, k)
            if isa(ins, DataVector)
                a[f+k-1] = ins.data[k]
            elseif isa(ins, PooledDataVector)
                a[f+k-1] = ins.pool[ins.refs[k]]
            else
                a[f+k-1] = ins[k]
            end
        end
    end

    splice!(dv.na, inds, ismissing.(ins))
    v
end

function Base.deleteat!(dv::DataVector, inds)
    deleteat!(dv.data, inds)
    deleteat!(dv.na, inds)
    dv
end

function Base.push!(pdv::PooledDataVector{T,R}, v::Missing) where {T,R}
    push!(pdv.refs, zero(R))
    return v
end

function Base.push!(pdv::PooledDataVector{S,R}, v::T) where {S,R,T}
    v = convert(S,v)
    push!(pdv.refs, getpoolidx(pdv, v))
    return v
end

Base.pop!(pdv::PooledDataVector) = pdv.pool[pop!(pdv.refs)]

function Base.unshift!(pdv::PooledDataVector{T,R}, v::Missing) where {T,R}
    pushfirst!(pdv.refs, zero(R))
    return v
end

function Base.unshift!(pdv::PooledDataVector{S,R}, v::T) where {S,R,T}
    v = convert(S,v)
    pushfirst!(pdv.refs, getpoolidx(pdv, v))
    return v
end

Base.shift!(pdv::PooledDataVector) = pdv.pool[popfirst!(pdv.refs)]

Base.reverse(x::AbstractDataVector) = x[end:-1:1]

function Base.splice!(pdv::PooledDataVector, inds::Union{Integer, UnitRange{Int}})
    v = pdv[inds]
    deleteat!(pdv.refs, inds)
    v
end

function Base.splice!(pdv::PooledDataVector, inds::Union{Integer, UnitRange{Int}}, ins::AbstractVector)
    v = pdv[inds]
    splice!(pdv.refs, inds, [getpoolidx(pdv, v) for v in ins])
    v
end

Base.deleteat!(pdv::PooledDataVector, inds) = (deleteat!(pdv.refs, inds); pdv)

function Base.append!(da::AbstractDataVector, items::AbstractVector)
    oldn = length(da)
    itn = length(items)
    resize!(da, oldn+itn)
    da[oldn+1:end] = items[1:itn]
    da
end

function Base.sizehint!(da::DataVector, newsz::Integer)
    sizehint!(da.data, newsz)
    sizehint!(da.na, newsz)
end
Base.sizehint!(pda::PooledDataVector, newsz::Integer) =
    sizehint!(pda.refs, newsz)

# Pad a vector with missings
"""
    padmissing(dv::AbstractDataVector, front::Integer, back::Integer) -> DataVector

Pad `dv` with `missing` values. `front` is an integer number of `missing`s to add at the
beginning of the array and `back` is the number of `missing`s to add at the end.

# Examples

```jldoctest
julia> padmissing(@data([1, 2, 3]), 1, 2)
6-element DataArrays.DataArray{Int64,1}:
  missing
 1
 2
 3
  missing
  missing
```
"""
function padmissing(dv::AbstractDataVector,
                 front::Integer,
                 back::Integer)
    n = length(dv)
    res = similar(dv, front + n + back)
    for i in 1:n
        res[i + front] = dv[i]
    end
    return res
end


text:
using TrussMorph
tm = TrussMorph
using Test
using Makie
using Colors

parse_result = true

node_dof = 3 # 2 for truss model, 3 for frames
full_node_dof = 3 # fixed for 2D cases

dir = "/Users/yijiangh/Dropbox (MIT)/Course_Work/6.838_2019_spring/final_project/code/gh_validation"
# result_file_dir = joinpath(pwd(),"test","results")
result_file_dir = "/Users/yijiangh/Dropbox (MIT)/Course_Work/6.838_2019_spring/final_project/code/results"

st_file_name  = "2D_truss_4.json"
end_file_name  = "2D_truss_5.json"
# st_file_name  = "2D_truss_0.json"
# end_file_name  = "2D_truss_1.json"
fp0 = joinpath(dir, st_file_name)
fp1 = joinpath(dir, end_file_name)
load_fp = joinpath(dir, "2D_truss_0_load_case.json")
design_var_ids = [4, 6]

path_disc = 20

t0,_ = parse_truss_json(fp0)
t1,_ = parse_truss_json(fp1)
load = parse_load_json(load_fp, node_dof)

n_v = size(t0.X,1)
n_e = size(t0.T,1)

# initial cross secs
r = ones(size(t0.T,1)) * 0.01
F = tm.assemble_load_vector(load, n_v, node_dof)
perm_vec, perm, n_dof_free = tm.dof_permutation(t0.S, n_v, node_dof)

F_perm = perm * F
F_m = Array(F_perm[1:n_dof_free])

weight_fn = tm.get_weight_calculation_fn(t0.X, r, t0.T, F_m, perm, n_dof_free,
node_dof, full_node_dof, t0.mp, design_var_ids)

if parse_result
    searchdir(path,key) = filter(x->occursin(key,x), readdir(path))

    opt_sE = Float64[]
    opt_wE = Float64[]
    opt_totE = Float64[]
    opt_sumE = 0.0
    morph_path = Matrix{Float64}[]
    parm= zeros(2)

    pure_st_file_name = SubString(st_file_name, 1:length(st_file_name)-length(".json"))
    pure_end_file_name = SubString(end_file_name, 1:length(end_file_name)-length(".json"))
    result_file_name = pure_st_file_name * "-" *  pure_end_file_name
    f_file_dir = joinpath(result_file_dir, result_file_name)
    if ispath(f_file_dir)
        result_jsons = searchdir(f_file_dir,string("-", path_disc+2, ".json"))
        # @show result_jsons
        morph_data = Dict()
        for json_fp in result_jsons
            full_json_fp = joinpath(f_file_dir, json_fp)

            parsed_truss, morph_data = parse_truss_json(full_json_fp, parse_morph=true)
            push!(morph_path, parsed_truss.X)
            push!(opt_wE, morph_data["weight_energy"])
            push!(opt_sE, morph_data["smoothness_energy"])
            push!(opt_totE, morph_data["tot_energy"])
            parm = [morph_data["smooth_parameter"], morph_data["weight_parameter"]]
            opt_sumE = morph_data["sum_energy"]
        end
        # @show opt_sumE
        # @show parsed_morph_path
    end

    # X_mat -> x_var
    design_var_id_map = zeros(Int, length(design_var_ids), 2)
    for i=1:length(design_var_ids)
        design_var_id_map[i,1] = Int.((design_var_ids[i] + design_var_ids[i]%2) / 2)
        design_var_id_map[i,2] = 2 - design_var_ids[i]%2
    end

    morph_var_path = zeros(length(morph_path) , length(design_var_ids))
    for t = 1:length(morph_path)
        for i=1:length(design_var_ids)
            morph_var_path[t,i] = morph_path[t][design_var_id_map[i,1], design_var_id_map[i,2]]
        end
    end
end

sc = Scene()
y1 = -1.2:0.005:1.2
y2 = -1.2:0.005:1.2
# y1 = -1.2:0.01:1.2
# y2 = -1.2:0.01:1.2
wF(x, y) = log(weight_fn([x,y]))
# wF(x, y) = weight_fn([x,y])

plot_alpha = 0.2
surface!(sc, y1, y2, wF, shading=false)
# , colormap=[RGBAf0(0,0,1,plot_alpha), RGBAf0(1, 1, 0, plot_alpha)]

# z = Float64[wF(x, y) for x in y1, y in y2]
# scatter!(sc, y1, y2, z, color=:blue, markersize=0.01)

if parse_result
    morph_weight = zeros(length(morph_path))
    color_array = Array{RGBAf0}(undef, plen)
    for i = 1:length(morph_path)
        morph_weight[i] = wF(morph_var_path[i,1], morph_var_path[i,2])
        mcolor = Float32.((length(morph_path) - i) / length(morph_path)) * RGBAf0(1.0,0.0,0.0,1) + Float32.(i / length(morph_path)) * RGBAf0(0.0,0.0,1.0,1)
        color_array[i] = mcolor
    end

    pts = vec(Point3f0.(morph_var_path[:,1], morph_var_path[:,2], morph_weight))
    scatter!(sc, pts, color=color_array, markersize=0.05)
    poly_vec = pts[2:end] - pts[1:end-1]
    push!(poly_vec, [0,0,0])

    arrows!(sc, pts, poly_vec, arrowsize = 0.03, linewidth = 3, linecolor = color_array, arrowcolor = color_array)
end

contour3d!(sc, y1, y2, (x, y) -> wF(x,y), levels = 15, linewidth = 3, color=RGBAf0(1,1,1,0.2))

axis = sc[Axis]
axis[:names][:axisnames] = ("y1", "y2", "log(weight)")
axis[:showaxis] = false
# axis[:showgrid] = (false, false, false)
display(sc)

result_file_dir = joinpath(pwd(),"test","results")
pure_st_file_name = SubString(st_file_name, 1:length(st_file_name)-length(".json"))
pure_end_file_name = SubString(end_file_name, 1:length(end_file_name)-length(".json"))
result_file_name = pure_st_file_name * "-" *  pure_end_file_name
f_file_dir = joinpath(result_file_dir, result_file_name)

result_img_name = result_file_name * "_weight_surface_" * string(Dates.now()) * ".png"

# result_file_dir = "/Users/yijiangh/Dropbox (MIT)/Course_Work/6.838_2019_spring/final_project/code/results"
# Makie.save(joinpath(result_file_dir, result_img_name), sc)


text:
include("Header.jl")

function getDataType(data)
    if     data == 0x5054 return "topography"
    elseif data == 0x5245 return "error"
    elseif data == 0x4850 return "phase"
    else return "none" end
end

function getAdRange(data)
    # ADレンジ定数（ユニポーラ0～1V）(使われていないらしい)
    if     data == 0x00000001 @assert false
    # ADレンジ定数（ユニポーラ0～2.5V）(使われていないらしい)
    elseif data == 0x00000002 @assert false
    # ADレンジ定数（ユニポーラ0～5V）(使われていないらしい)
    elseif data == 0x00000004 @assert false
    # ADレンジ定数（バイポーラ±1V）
    elseif data == 0x00010000 return 2.0
    # ADレンジ定数（バイポーラ±2.5V）
    elseif data == 0x00020000 return 5.0
    # ADレンジ定数（バイポーラ±5V）
    elseif data == 0x00040000 return 10.0
    # ADレンジ定数（バイポーラ±80V, データを編集した場合に仮想的にこれを使う。実際にバイポーラ80VでAD変換したわけではない。また、分解能は16ビットにする）
    elseif data == 0x00080000 return 160.0
    # 何も当てはまらない
    else @assert false end
    return nothing
end

function getOperatorName(io, operatorNameSize)
    ret = []
    for i in 1:operatorNameSize
        push!(ret, Int64(read(io, UInt8)))
    end
    return ret
end

function getComment(io, commentOffsetSize, commentSize)
    for i in 1:commentOffsetSize
        read(io, Bool)
    end
    ret = []
    for i in 1:commentSize
        push!(ret, Int64(read(io, UInt8)))
    end
    return ret
end

function readDate(io::IOStream)
    year              = Int64(read(io, Int16))
    month             = Int64(read(io, UInt8))
    day               = Int64(read(io, UInt8))
    hour              = Int64(read(io, UInt8))
    minute            = Int64(read(io, UInt8))
    second            = Int64(read(io, UInt8))
    return DateTime(year, month, day, hour, minute, second)
end

function readHeaderV0(io::IOStream)
    fileVersion       = 0
    dataType1ch       = getDataType(read(io, Int16))
    dataType2ch       = getDataType(read(io, Int16))
    fileHeaderSize    = Int64(read(io, Int32))
    frameHeaderSize   = Int64(read(io, Int32))
    operatorNameSize  = Int64(read(io, Int32))
    commentOffsetSize = Int64(read(io, Int32))
    commentSize       = Int64(read(io, Int32))
    pixelX            = Int64(read(io, Int16))
    pixelY            = Int64(read(io, Int16))
    scanningRangeX    = Int64(read(io, Int16))
    scanningRangeY    = Int64(read(io, Int16))
    frameRate         = Float64(read(io, Float32))
    piezoExtensionZ   = Float64(read(io, Float32))
    piezoGainZ        = Float64(read(io, Float32))
    adRange           = getAdRange(read(io, UInt32))
    AdResolution      = (2.0)^Int64(read(io, Int32))
    isAveraged        = read(io, Bool)
    averageWindow     = Int64(read(io, Int32))
    legacy            = Int64(read(io, Int16)) # ダミー
    day               = readDate(io)
    roundingDegree    = Int64(read(io, UInt8))
    maxRangeX         = Float64(read(io, Float32))
    maxRangeY         = Float64(read(io, Float32))
    booked1           = Int64(read(io, Int32))
    booked2           = Int64(read(io, Int32))
    booked3           = Int64(read(io, Int32))
    initFrame         = Int64(read(io, Int32))
    numFrames         = Int64(read(io, Int32))
    machineId         = Int64(read(io, Int32))
    fileId            = Int64(read(io, Int16))
    operatorName      = getOperatorName(io, operatorNameSize)
    sensorSensitivity = Float64(read(io, Float32))
    phaseSensitivity  = Float64(read(io, Float32))
    scannigDirection  = Int64(read(io, Int32))
    comment           = getComment(io, commentOffsetSize, commentSize)

    return HeaderV0(fileVersion, dataType1ch, dataType2ch, fileHeaderSize, frameHeaderSize, operatorNameSize, commentOffsetSize, commentSize, pixelX, pixelY, scanningRangeX, scanningRangeY, frameRate, piezoExtensionZ, piezoGainZ, adRange, AdResolution, isAveraged, averageWindow, day, roundingDegree, maxRangeX, maxRangeY, booked1, booked2, booked3, initFrame, numFrames, machineId, fileId, operatorName, sensorSensitivity, phaseSensitivity, scannigDirection, comment)
end

max_stars_repo_name: matsunagalab/BioAFM

max_issues_repo_name: matsunagalab/BioAFM

max_forks_repo_name: matsunagalab/BioAFM


text:
using DataFrames
using Distributions
using Gadfly
using HypothesisTests

# two columns named a and begin

df = DataFrame(A = 1:10, B = 2:2:20)

# selecting only rows 1 to 3 from colum

df[1:3, [:A]]

df[!,:Names] = ["A", "A", "A", "B", "C", "B", "A", "B", "C", "A"]

# selecting only values of a in Names

data_A = df[df[!,:Names] .== "A", :]
# simple statistics

describe(data_A[!,:A])
mean(df[!,:A])
sum(df[!,:A])

# creating a for-loop to randomly add M and F string values to the gender_array
data = DataFrame()

gender_array = ["F"]

for n = 1:199
    rn = rand()
    if rn <= 0
        append!(gender_array, ["F"])
    else
        append!(gender_array, ["M"])
    end
end

gender_array

data[!,:Gender] = gender_array

group_array = ["A"]

for n = 1:199
    rn = rand()
    if rn <= 0
        append!(group_array, ["B"])
    else
        append!(group_array, ["A"])
    end
end

data[!,:Group] = group_array
data[!,:Age] = rand(Normal(35,10),200)
data[!,:Days] = rand(Poisson(2), 200)
data[!,:Temp] = rand(Normal(38.5,2), 200)
data[!,:WCC] = rand(Normal(15,5),200)
data[!,:CRP] = rand(Poisson(2),200) .* 2 .+ 100

print(data)

plot(data, x = "Gender", color = "Gender", Geom.histogram,  Guide.title("Gender"), Guide.ylabel("Number"))
plot(data, x = "Gender", y = "Age", Geom.boxplot, Guide.title("Age Difference Between Male and Female"))
plot(data, x = "WCC", color = "Gender", Geom.density, Guide.title("WCC distribution in males and females"))

max_stars_repo_name: fmyilmaz/DSGE

max_issues_repo_name: fmyilmaz/DSGE

max_forks_repo_name: fmyilmaz/DSGE


text:
"""
    IntegDataModule

Module to manage geometry data.
"""
module IntegDataModule

using FinEtools.FTypesModule: FInt, FFlt, FCplxFlt, FFltVec, FIntVec, FFltMat, FIntMat, FMat, FVec, FDataDict
import FinEtools.FESetModule: FESet, FESet0Manifold, FESet1Manifold, FESet2Manifold, FESet3Manifold, Jacobian, bfun, bfundpar
import FinEtools.FENodeSetModule: FENodeSet
import FinEtools.IntegRuleModule: IntegRule

"""
    IntegData{T<:FESet}

Integration data.

T = type of finite element set.  The type of the FE set will be dependent upon the
operations required. For instance, for interior (volume) integrals such as body
load or the stiffness hexahedral H8 may be used, whereas for boundary  (surface)
integrals quadrilateral Q4 would be needed.
"""
mutable struct IntegData{S<:FESet, F<:Function}
    fes::S # finite element set object
    integration_rule::IntegRule  # integration rule object
    otherdimension::F
    axisymmetric::Bool
end

"""
    IntegData(fes::S, integration_rule::IntegRule) where {S<:FESet}

Construct with the default orientation matrix (identity), and the other
dimension  being the default 1.0.
"""
function  IntegData(fes::S, integration_rule::IntegRule) where {S<:FESet}
    return IntegData(fes, integration_rule, otherdimensionunity, false)
end

"""
    IntegData(fes::S, integration_rule::IntegRule,
      otherdimension::FFlt) where {S<:FESet}

Construct with the default orientation matrix (identity), and constant other
dimension.
"""
function  IntegData(fes::S, integration_rule::IntegRule, otherdimension::FFlt) where {S<:FESet}
    function otherdimensionfu(loc::FFltMat,
        conn::CC, N::FFltMat)::FFlt where {CC}
        return otherdimension::FFlt
    end
    return IntegData(fes, integration_rule, otherdimensionfu, false)
end

"""
    IntegData(fes::S, integration_rule::IntegRule,
      axisymmetric::Bool) where {S<:FESet}

Construct with the default orientation matrix (identity), for axially symmetric
models. The other dimension is  the default  unity (1.0).
"""
function IntegData(fes::S, integration_rule::IntegRule, axisymmetric::Bool) where {S<:FESet}
    return IntegData(fes, integration_rule, otherdimensionunity, axisymmetric)
end

"""
    IntegData(fes::S, integration_rule::IntegRule, axisymmetric::Bool,
      otherdimension::FFlt) where {S<:FESet}

Construct for axially symmetric models. The other dimension is given as a number.
"""
function IntegData(fes::S, integration_rule::IntegRule, axisymmetric::Bool, otherdimension::FFlt) where {S<:FESet}
    function otherdimensionfu(loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {CC}
        return otherdimension::FFlt
    end
    return IntegData(fes, integration_rule, otherdimensionfu, axisymmetric)
end

"""
    otherdimensionunity(loc::FFltMat, conn::CC, N::FFltMat)::FFlt
              where {CC}

Evaluate the other dimension: default is 1.0.
"""
function otherdimensionunity(loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {CC}
    return 1.0
end

"""
    Jacobianpoint(self::IntegData{T}, J::FFltMat,
                loc::FFltMat, conn::CC,
                N::FFltMat)::FFlt where {T<:FESet0Manifold, CC}

Evaluate the point Jacobian.

`J` = Jacobian matrix
`loc` = location of the quadrature point in physical coordinates,
`conn` = connectivity of the element,
`N` = matrix of basis function values at the quadrature point.
"""
function Jacobianpoint(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {T<:FESet0Manifold, CC}
    return Jacobian(self.fes, J)::FFlt
end

"""
    Jacobiancurve(self::IntegData{T}, J::FFltMat,
        loc::FFltMat, conn::CC,
        N::FFltMat)::FFlt where {T<:FESet0Manifold, CC}

Evaluate the curve Jacobian.

`J` = Jacobian matrix
`loc` = location of the quadrature point in physical coordinates,
`conn` = connectivity of the element,
`N` = matrix of basis function values at the quadrature point.
"""
function Jacobiancurve(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {T<:FESet0Manifold, CC}
    Jac = Jacobianpoint(self, J, loc, conn, N)
    if self.axisymmetric
        return Jac*2*pi*loc[1];
    else
        return Jac*self.otherdimension(loc, conn,  N)
    end
end

"""
    Jacobiansurface(self::IntegData{T}, J::FFltMat,
                loc::FFltMat, conn::CC,
                N::FFltMat)::FFlt where {T<:FESet0Manifold, CC}

Evaluate the surface Jacobian.

For the zero-dimensional cell,  the surface Jacobian is
    (i) the product of the point Jacobian and the other dimension
    (units of length squared);
    or,  when used as axially symmetric
    (ii) the product of the point Jacobian and the circumference of
    the circle through the point `loc` times the other dimension (units of length).

`J` = Jacobian matrix
`loc` = location of the quadrature point in physical coordinates,
`conn` = connectivity of the element,
`N` = matrix of basis function values at the quadrature point.
"""
function Jacobiansurface(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {T<:FESet0Manifold, CC}
    Jac = Jacobianpoint(self, J, loc, conn, N)::FFlt
    if self.axisymmetric
        return Jac*2*pi*loc[1]*self.otherdimension(loc, conn,  N);
    else
        return Jac*self.otherdimension(loc, conn,  N)
    end
end

"""
    Jacobianvolume(self::IntegData{T}, J::FFltMat,
          loc::FFltMat, conn::CC,
          N::FFltMat)::FFlt where {T<:FESet0Manifold, CC}

Evaluate the volume Jacobian.

For the zero-dimensional cell,  the volume Jacobian is
    (i) the product of the point Jacobian and the other dimension
    (units of length cubed);
    or,  when used as axially symmetric
    (ii) the product of the point Jacobian and the circumference of
    the circle through the point `loc` and the other dimension (units
    of length squared).

`J` = Jacobian matrix
`loc` = location of the quadrature point in physical coordinates,
`conn` = connectivity of the element,
`N` = matrix of basis function values at the quadrature point.
"""
function Jacobianvolume(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {T<:FESet0Manifold, CC}
    Jac = Jacobianpoint(self, J, loc, conn, N)
    if self.axisymmetric
        return Jac*2*pi*loc[1]*self.otherdimension(loc, conn,  N);
    else
        return Jac*self.otherdimension(loc, conn,  N)
    end
end

"""
    Jacobianmdim(self::IntegData{T}, J::FFltMat,
      loc::FFltMat, conn::CC,
      N::FFltMat, m::FInt)::FFlt where {T<:FESet0Manifold, CC}

Evaluate the manifold Jacobian for an m-dimensional manifold.

For an 0-dimensional finite element,  the manifold Jacobian is for
    m=0: +1
    m=1: Jacobiancurve
    m=2: Jacobiansurface
    m=3: Jacobianvolume
"""
function Jacobianmdim(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat, m::FInt)::FFlt where {T<:FESet0Manifold, CC}
    @assert (m >= 0)  && (m <= 3)
    if (m==3)
        return Jacobianvolume(self, J, loc, conn, N)
    elseif (m==2)
        return Jacobiansurface(self, J, loc, conn, N)
    elseif (m==1)
        return Jacobiancurve(self, J, loc, conn, N)
    else # (m==0)
        return Jacobianpoint(self, J, loc, conn, N)
    end
end

"""
    Jacobiancurve(self::IntegData{T}, J::FFltMat,
              loc::FFltMat, conn::CC,
              N::FFltMat)::FFlt where {T<:FESet1Manifold, CC}

Evaluate the curve Jacobian.

`J` = Jacobian matrix
`loc` = location of the quadrature point in physical coordinates,
`conn` = connectivity of the element,
`N` = matrix of basis function values at the quadrature point.
"""
function Jacobiancurve(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {T<:FESet1Manifold, CC}
    return Jacobian(self.fes, J)::FFlt
end

"""
    Jacobiansurface(self::IntegData{T}, J::FFltMat,
                loc::FFltMat, conn::CC,
                N::FFltMat)::FFlt where {T<:FESet1Manifold, CC}

Evaluate the surface Jacobian.

For the one-dimensional cell,  the surface Jacobian is
    (i) the product of the curve Jacobian and the other dimension
    (units of length);
    or,  when used as axially symmetric
    (ii) the product of the curve Jacobian and the circumference of
    the circle through the point `loc`.

`J` = Jacobian matrix
`loc` = location of the quadrature point in physical coordinates,
`conn` = connectivity of the element,
`N` = matrix of basis function values at the quadrature point.
"""
function Jacobiansurface(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {T<:FESet1Manifold, CC}
    Jac = Jacobiancurve(self, J, loc, conn, N)
    if self.axisymmetric
        return Jac*2*pi*loc[1];
    else
        return Jac*self.otherdimension(loc, conn,  N)
    end
end

"""
    Jacobianvolume(self::IntegData{T}, J::FFltMat,
                loc::FFltMat, conn::CC,
                N::FFltMat)::FFlt where {T<:FESet1Manifold, CC}

Evaluate the volume Jacobian.

For the one-dimensional cell,  the volume Jacobian is
    (i) the product of the curve Jacobian and the other dimension
    (units of length squared);
    or,  when used as axially symmetric
    (ii) the product of the curve Jacobian and the circumference of
    the circle through the point `loc` and the other dimension (units of length).

`J` = Jacobian matrix
`loc` = location of the quadrature point in physical coordinates,
`conn` = connectivity of the element,
`N` = matrix of basis function values at the quadrature point.
"""
function Jacobianvolume(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {T<:FESet1Manifold, CC}
    Jac = Jacobiancurve(self, J, loc, conn, N)
    if self.axisymmetric
        return Jac*2*pi*loc[1]*self.otherdimension(loc, conn,  N);
    else
        return Jac*self.otherdimension(loc, conn,  N)
    end
end

"""
    Jacobianmdim(self::IntegData{T}, J::FFltMat,
    loc::FFltMat, conn::CC,
    N::FFltMat, m::FInt)::FFlt where {T<:FESet1Manifold, CC}

Evaluate the manifold Jacobian for an m-dimensional manifold.

For an 1-dimensional finite element,  the manifold Jacobian is for
    m=1: Jacobiancurve
    m=2: Jacobiansurface
    m=3: Jacobianvolume
"""
function Jacobianmdim(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat, m::FInt)::FFlt where {T<:FESet1Manifold, CC}
    @assert (m >= 1) && (m <= 3)
    if (m==3)
        return Jacobianvolume(self, J, loc, conn, N)
    elseif (m==2)
        return Jacobiansurface(self, J, loc, conn, N)
    else # (m==1)
        return Jacobiancurve(self, J, loc, conn, N)
    end
end

"""
    Jacobiansurface(self::IntegData{T}, J::FFltMat,
                loc::FFltMat, conn::CC,
                 N::FFltMat)::FFlt where {T<:FESet2Manifold, CC}

Evaluate the surface Jacobian.

`J` = Jacobian matrix
`loc` = location of the quadrature point in physical coordinates,
`conn` = connectivity of the element,
`N` = matrix of basis function values at the quadrature point.
"""
function Jacobiansurface(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {T<:FESet2Manifold, CC}
    return Jacobian(self.fes, J)
end

"""
    Jacobianvolume(self::IntegData{T}, J::FFltMat,
                loc::FFltMat, conn::CC,
                N::FFltMat)::FFlt where {T<:FESet2Manifold, CC}

Evaluate the volume Jacobian.

For the two-dimensional cell,  the volume Jacobian is
    (i) the product of the surface Jacobian and the other dimension
    (units of length);
    or,  when used as axially symmetric
    (ii) the product of the surface Jacobian and the circumference of
    the circle through the point `loc` (units of length).

`J` = Jacobian matrix
`loc` = location of the quadrature point in physical coordinates,
`conn` = connectivity of the element,
`N` = matrix of basis function values at the quadrature point.
"""
function Jacobianvolume(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {T<:FESet2Manifold, CC}
    Jac = Jacobiansurface(self, J, loc, conn, N)::FFlt
    if self.axisymmetric
        return Jac*2*pi*loc[1];
    else
        return Jac*self.otherdimension(loc, conn,  N)
    end
end

"""
    Jacobianmdim(self::IntegData{T}, J::FFltMat,
                loc::FFltMat, conn::CC,
                N::FFltMat, m::FInt)::FFlt where {T<:FESet2Manifold, CC}

Evaluate the manifold Jacobian for an m-dimensional manifold.

For an 2-dimensional finite element,  the manifold Jacobian is for
    m=2: Jacobiansurface
    m=3: Jacobianvolume
"""
function Jacobianmdim(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat, m::FInt)::FFlt where {T<:FESet2Manifold, CC}
    @assert (m >= 2) && (m <= 3)
    if (m==3)
        return Jacobianvolume(self, J, loc, conn, N)
    else # (m==2)
        return Jacobiansurface(self, J, loc, conn, N)
    end
end

"""
    Jacobianvolume(self::IntegData{T}, J::FFltMat,
                loc::FFltMat, conn::CC,
                N::FFltMat)::FFlt where {T<:FESet3Manifold, CC}
Evaluate the volume Jacobian.

`J` = Jacobian matrix
`loc` = location of the quadrature point in physical coordinates,
`conn` = connectivity of the element,
`N` = matrix of basis function values at the quadrature point.
"""
function Jacobianvolume(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {T<:FESet3Manifold, CC}
    return Jacobian(self.fes, J)::FFlt
end

"""
    Jacobianmdim{T<:FESet3Manifold}(self::IntegData, J::FFltMat,
                loc::FFltMat, conn::FIntMat, N::FFltMat, m::FInt)

Evaluate the manifold Jacobian for an m-dimensional manifold.

For an 3-dimensional cell,  the manifold Jacobian is
    m=3: Jacobianvolume
"""
function Jacobianmdim(self::IntegData{T}, J::FFltMat, loc::FFltMat, conn::CC, N::FFltMat, m::FInt)::FFlt where {T<:FESet3Manifold, CC}
    @assert (m == 3)
    return Jacobianvolume(self, J, loc, conn, N)
end

"""
    integrationdata(self::IntegData)

Calculate the data needed for  numerical quadrature.

`npts`, `Ns`, `gradNparams`, `w`, `pc` = number of quadrature points, arrays of
basis function values at the quadrature points,  arrays of gradients of basis
functions  with respect  to the parametric coordinates, array of weights and
array of locations of the quadrature points.
"""
function  integrationdata(self::IntegData)
    pc::FFltMat = self.integration_rule.param_coords;
    w::FFltMat  =  self.integration_rule.weights ;
    npts::FInt = self.integration_rule.npts;
    # Precompute basis f. values + basis f. gradients wrt parametric coor
    Ns = FFltMat[];
    gradNparams = FFltMat[];
    for j=1:npts
        push!(Ns, bfun(self.fes,vec(pc[j,:])));
        push!(gradNparams, bfundpar(self.fes,vec(pc[j,:])));
    end
    return npts, reshape(Ns, 1,npts), reshape(gradNparams, 1,npts), w, pc
end

end


text:
using StatsPlots, Distributions

@testset "fa" begin
    Random.seed!(1234)
    a = rand(Uniform(0.5, 2.0), 30)
    b = [sort(rand(Uniform(-3, 3), 4); rev = false) for i in 1:30]
    θ = rand(Normal(0, 1), 3000)
    resp = generate_response(θ, a, b)

    fit1 = fa(resp; method = :em)
    @test all(loadings(fit1) .≤ 1.0)
    fit2 = fa(resp; method = :cm)
    @test all(loadings(fit2) .≤ 1.0)
    fit3 = fa(resp; cor_method = :Pearson, method = :em)
    @test all(loadings(fit3) .≤ 1.0)

    # @code_warntype fa(resp; method = :em)
    # @profview fa(resp; method = :em)
end

@testset "parallel" begin
    Random.seed!(1234)
    a = rand(Uniform(0.5, 2.0), 30)
    b = [sort(rand(Uniform(-3, 3), 4); rev = false) for i in 1:30]
    θ = rand(Normal(0, 1), 3000)
    resp = generate_response(θ, a, b)

    par_fit1 = parallel(resp, 10, x -> fa(x; cor_method = :Polychoric))
    @test ParallelAnalysis.findnfactors(par_fit1.FA.real, par_fit1.FA.resampled) == 1
    @test ParallelAnalysis.findnfactors(par_fit1.PCA.real, par_fit1.PCA.resampled) == 1
    par_fit2 = parallel(resp, 10, x -> fa(x; cor_method = :Pearson))
    @test ParallelAnalysis.findnfactors(par_fit2.FA.real, par_fit2.FA.resampled) == 1
    @test ParallelAnalysis.findnfactors(par_fit2.PCA.real, par_fit2.PCA.resampled) == 1
    # @code_warntype parallel(resp, 10, x -> fa(x; cor_method = :Polychoric))
    # @profview parallel(resp, 10, x -> fa(x; cor_method = :Polychoric))
    # @code_warntype parallel(resp, 100, x -> fa(x; cor_method = :Pearson))

    plot(par_fit1.PCA)
    plot(par_fit1.FA)
    plot(par_fit1)
    plot(par_fit1, markershape = :none)
end


text:
# During the back pass we want to make pointers available as soon as we can to save memory
# without waiting for gc. This is risky as we have to make sure the pointers are not going
# to be used again.  We initialize a priority queue in knetgcinit() where KnetPtrs are
# mapped to the smallest index of the tape they are used.  If a KnetPtr is in a Param
# value/outgrad Result value we do not want to free it, so we map those to 0. Only Result
# outgrads can be safely freed, Result values are not safe because the user can assign them
# to global variables (as is done in RNNs).  Every time knetgcnode() is called after a back
# step, we update the queue with the pointers from the new outgrads of the node and its
# parents. The values in the queue are only decreased, never increased. Finally we free the
# pointers whose queue value is the current tape position. Note that tape indices go forward
# in time from parameters to loss but are processed backward in time from loss to
# parameters.

using DataStructures: PriorityQueue, dequeue!, dequeue_pair!, DataStructures
using AutoGrad: Node, Tape, Result
const noresult = Result{Nothing}(nothing,nothing,nothing,nothing)

# The _queue maps KnetPtrs to the first index on tape they have a reference to. We use
# Base.Order.Reverse because we want to free the pointers with highest indices first.
const _queue = PriorityQueue{KnetPtr,Int}(Base.Order.Reverse)

# During the backward step parents of a node (who have lower indices) may have their
# outgrads modified, thus new KnetPtr references may appear. We want to keep the smallest
# index for each KnetPtr.
minidx!(q::PriorityQueue{KnetPtr,Int,typeof(Base.Order.Reverse)},k::KnetPtr,v::Int) =
    if v < get(q,k,typemax(Int)); q[k]=v; end  ## 0.190μs

const _index = IdDict{Node,Int}()
_tape = nothing

function knetgcinit(tape)  ## 2.35ms
    global _tape, _index, _queue
    _tape = WeakRef(tape)
    empty!(_index)
    empty!(_queue)
    tape isa Tape || return
    @inbounds for (i,n) in enumerate(tape.list)
        _index[n] = i
        if n.Value isa Result
            for k in knetptrs(n.Value.value); _queue[k] = 0; end # pointers with index 0 will never get gc'ed
            for k in knetptrs(n.outgrad);  get!(_queue,k,i); end # this only sets _queue[k] if it does not have a value
        else # n.Value isa Param
            for k in knetptrs(n.Value.value); _queue[k] = 0; end
            for k in knetptrs(n.outgrad);     _queue[k] = 0; end
        end
    end
end

function knetgcnode(n::Node, tape=nothing)  ## 16.3μs
    tape != _tape && knetgcinit(tape) ## 2μs amortized
    tape isa Tape || return
    ni = _index[n]
    if n.Value isa Result && n.outgrad isa KnetArray
        minidx!(_queue, n.outgrad.ptr, ni)
    end
    @inbounds for i in 1:length(n.parents);  ## 2.43μs
        isassigned(n.parents, i) || continue
        parent = n.parents[i]
        if parent.Value isa Result
            pi = _index[parent]
            for ptr in knetptrs(parent.outgrad); minidx!(_queue, ptr, pi); end
        else
            for ptr in knetptrs(parent.outgrad); _queue[ptr] = 0; end # protect Params
        end
    end
    while !isempty(_queue) && DataStructures.peek(_queue)[2] >= ni  ## 5.62μs
        (k,v) = dequeue_pair!(_queue)  ## 0.787μs
        if v != ni; @warn("k=$((k.ptr,k.len)) v=$v ni=$ni", maxlog=1); end  ## 0.160μs
        #DBG verifypointer(tape, ni, k)
        freeKnetPtr(k)  ## 4.06μs
    end
    if n.Value isa Result
        n.Value, n.outgrad = noresult, nothing
    end
end

# Recursively search for KnetPtrs based on deepcopy_internal

knetptrs(x, c=KnetPtr[], d=IdDict{Any,Bool}()) = (_knetptrs(x,c,d); c)

_knetptrs(x::Tuple, c::Vector{KnetPtr}, d::IdDict{Any,Bool}) =
    for xi in x; _knetptrs(xi, c, d); end

_knetptrs(x::Union{Module,String,Symbol,Core.MethodInstance,Method,GlobalRef,DataType,Union,UnionAll,Task,Regex},
          c::Vector{KnetPtr}, d::IdDict{Any,Bool}) = return

_knetptrs(x::Core.SimpleVector, c::Vector{KnetPtr}, d::IdDict{Any,Bool}) =
    if !haskey(d,x); d[x] = true; for xi in x; _knetptrs(xi, c, d); end; end

_knetptrs(x::Array, c::Vector{KnetPtr}, d::IdDict{Any,Bool}) =
    if !haskey(d,x); d[x] = true; _knetptrs_array_t(x, eltype(x), c, d); end

_knetptrs(x::Union{Dict,IdDict}, c::Vector{KnetPtr}, d::IdDict{Any,Bool}) =
    if !haskey(d,x); d[x] = true; for (k,v) in x; _knetptrs(k, c, d); _knetptrs(v, c, d); end; end

function _knetptrs_array_t(@nospecialize(x), T, c::Vector{KnetPtr}, d::IdDict{Any,Bool})
    if isbitstype(T)
        return
    end
    for i = 1:(length(x)::Int)
        if ccall(:jl_array_isassigned, Cint, (Any, Csize_t), x, i-1) != 0
            xi = ccall(:jl_arrayref, Any, (Any, Csize_t), x, i-1)
            if !isbits(xi)
                _knetptrs(xi, c, d)
            end
        end
    end
end

function _knetptrs(@nospecialize(x), c::Vector{KnetPtr}, d::IdDict{Any,Bool})
    T = typeof(x)::DataType
    nf = nfields(x)
    (isbitstype(T) || nf == 0) && return
    if haskey(d, x)
        return
    end
    if T.mutable
        d[x] = true
    end
    if T === KnetPtr
        push!(c, x)
    end
    for i in 1:nf
        if isdefined(x,i)
            _knetptrs(getfield(x,i), c, d)
        end
    end
end

## Old implementation: gets about half the pointers at about twice the speed (but the speed advantage is negligible)

function knetgcnode_old(n::Node, tape=nothing)
    if maybefree(n.outgrad, n, tape); n.outgrad = nothing; end
    if maybefree(n.Value.value, n, tape); n.Value.value = nothing; end
    # n.outgrad=n.Value.value=nothing # this prevents later shared pointers from being discovered
end

maybefree(x,n,t)=false

function maybefree(x::KnetArray, n::Node, tape::Tape)
    # cp = countpointer(x, tape) #DBG
    @inbounds for i in 1:length(n.parents)
        isassigned(n.parents, i) || continue
        p = n.parents[i]
        if maysharepointer(x, p.outgrad) || maysharepointer(x, p.Value.value) # need to check both outgrad and value
            # gcpointers[cp > 1 ? 2 : 3] += 1 #DBG
            # gcpointers[2] += x.ptr.len #DBG
            return false
        end
    end
    @inbounds for r in n.children
        if maysharepointer(x, r.outgrad) || maysharepointer(x, r.Value.value)
            # gcpointers[cp > 1 ? 2 : 3] += 1 #DBG
            # gcpointers[2] += x.ptr.len #DBG
            return false
        end
    end
    @dbg (push!(arraysizes,0); push!(blocksizes,0))
    # gcpointers[cp > 1 ? 4 : 1] += 1 #DBG
    # gcpointers[1] += x.ptr.len #DBG
    freeKnetPtr(x.ptr)
    return true
end

# This returns false only if we are sure there is no shared pointer. It is conservative, may return true when it shouldn't.
# Numbers, Nothing, unshared KnetArray with different pointer (98%) is safe.
function maysharepointer(x::KnetArray, y)
    # !(isbits(y) || (isa(y, KnetArray) && !isdefined(y.ptr,:parent) && pointer(y) != pointer(x)))
    if isbits(y)
        return false            # primitive number types do not share
    elseif !isa(y, KnetArray)
        return true             # data structures may share
    elseif isa(y.ptr.parent, KnetPtr) || isa(x.ptr.parent, KnetPtr)
        return true             # if one is a shared array they may share pointers
    else
        return (pointer(x) == pointer(y))
    end
end

function countpointer(x::KnetArray, tape::Tape)
    cnt = 0
    for n in tape.list
        if isa(n.outgrad,KnetArray) && pointer(n.outgrad) == pointer(x); cnt+=1; end
        if isa(n.Value.value,KnetArray) && pointer(n.Value.value) == pointer(x); cnt+=1; end
    end
    return cnt
end

## Debugging utilities

gcpointers = [ 0., 0., 0., 0. ]     #DBG

function verifypointer(tape::Tape, ni::Int, k::KnetPtr) # for debugging
    @show ni
    gcpointers[1] += k.len
    findk = false
    for n in tape.list
        if k in knetptrs(n.outgrad) || k in knetptrs(n.Value.value)
            findk = true
            @assert n.Value isa Result && n.Value.value isa KnetArray && n.outgrad isa KnetArray  (global _n=n; global _k=k; global _t=tape; "pointer $(k.ptr) found in $n")
        end
    end
    @assert findk
    for i in 1:length(tape.list)
        p = tape.list[i]
        if p.Value isa Param || i < ni
            @assert !isa(p.Value.value,KnetArray) || (p.Value.value.ptr != k && p.Value.value.ptr.ptr != C_NULL && p.Value.value.ptr.ptr != k.ptr)  (global _i=i; global _p=p; global _n=tape.list[ni]; global _ni=ni; "null value")
            @assert !isa(p.outgrad,KnetArray) || (p.outgrad.ptr != k && p.outgrad.ptr.ptr != C_NULL && p.outgrad.ptr.ptr != k.ptr)  (global _i=i; global _p=p; global _n=tape.list[ni]; global _ni=ni; "null outgrad")
        end
    end
end


text:
#
# This example shows how to write a basic JSON parser
#
# Adapted from the Lark example
#

using Lerche
using JSON

# Note the change in grammar vs Python: we do not
# use 'true' and 'false' as the names of the
# true/false aliases to avoid keyword collisions.

json_grammar = raw"""
    ?start: value

    ?value: object
          | array
          | string
          | SIGNED_NUMBER      -> number
          | "true"             -> t
          | "false"            -> f
          | "null"             -> null

    array  : "[" [value ("," value)*] "]"
    object : "{" [pair ("," pair)*] "}"
    pair   : string ":" value

    string : ESCAPED_STRING

    %import common.ESCAPED_STRING
    %import common.SIGNED_NUMBER
    %import common.WS

    %ignore WS
"""

struct TreeToJson <: Transformer end

@inline_rule string(t::TreeToJson, s) = replace(s[2:end-1],"\\\""=>"\"")

@rule  array(t::TreeToJson,a) = Array(a)
@rule  pair(t::TreeToJson,p) = Tuple(p)
@rule  object(t::TreeToJson,o) = Dict(o)
@inline_rule number(t::TreeToJson,n) = Base.parse(Float64,n)

@rule  null(t::TreeToJson,_) = nothing
@rule  t(t::TreeToJson,_) = true
@rule  f(t::TreeToJson,_) = false

json_parser = Lark(json_grammar, parser="lalr", lexer="standard", transformer=TreeToJson())

test() = begin
    test_json = """
        {
            "empty_object" : {},
            "empty_array"  : [],
            "booleans"     : { "YES" : true, "NO" : false },
            "numbers"      : [ 0, 1, -2, 3.3, 4.4e5, 6.6e-7 ],
            "strings"      : [ "This", [ "And" , "That", "And a \\\"b" ] ],
            "nothing"      : null
        }
    """

    j = Lerche.parse(json_parser,test_json)
    println(j)
    k = JSON.parse(test_json)
    println(k)
    @assert j == k
end

# Add a reader here if necessary
test()


text:
const data = readlines()
const m = length(data[1])

most_common(j; d=data) = sum(1:length(d)) do i
                             d[i][j] == '1'
                         end >= length(d) / 2 ? '1' : '0'

least_common(j; d=data) = most_common(j; d) == '1' ? '0' : '1'

Base.parse(cs::Vector{Char}) = parse(Int, join(cs); base=2)

# Part 1
(most_common.(1:m), least_common.(1:m)) .|> parse |> prod |> println

function rating(f; d=data)
    values = copy(d)
    for j in 1:m
        b = f(j; d=values)
        filter!(values) do num
            num[j] == b
        end
        length(values) == 1 && break
    end
    collect(values[1])
end

# Part 2
(most_common, least_common) .|> rating .|> parse |> prod |> println

max_stars_repo_name: pLOPeGG/JuliaOfCode

max_issues_repo_name: pLOPeGG/JuliaOfCode

max_forks_repo_name: pLOPeGG/JuliaOfCode


text:
InputFolder = './Images/EyeVesselsSpots/';
OutputFolder = './Results/Images/EyeVesselsSpotsSpots/';
Fill = 0;
Dilate = 4;

@iA = '*.tif';

@fxg_mIsoScanSpot [iA] > [M];
params.GRad = 0.75;
params.Len = 9;
params.Tol = 30;
params.NAngles = 9;
params.MinUnif = 0.6;
/endf

/show iA > M;
/keep M > tif;

max_stars_repo_name: SebastienTs/LOBSTER

max_issues_repo_name: SebastienTs/LOBSTER

max_forks_repo_name: SebastienTs/LOBSTER


text:
abstract type MessagePassing <: GraphNet end

"""
    message(mp, x_i, x_j, e_ij)

Message function for message-passing scheme. This function can be overrided to dispatch to custom layers.
First argument should be message-passing layer, the rest of arguments can be `x_i`, `x_j` and `e_ij`.

# Arguments
- `mp`: message-passing layer.
- `x_i`: the feature of node `x_i`.
- `x_j`: the feature of neighbors of node `x_i`.
- `e_ij`: the feature of edge (`x_i`, `x_j`).
"""
@inline message(mp::T, x_i, x_j, e_ij) where {T<:MessagePassing} = x_j
@inline message(mp::T, i::Integer, j::Integer, x_i, x_j, e_ij) where {T<:MessagePassing} = x_j

"""
    update(mp, m, x)

Update function for message-passing scheme. This function can be overrided to dispatch to custom layers.
First argument should be message-passing layer, the rest of arguments can be `X` and `M`.

# Arguments
- `mp`: message-passing layer.
- `m`: the message aggregated from message function.
- `x`: the single node feature.
"""
@inline update(mp::T, m, x) where {T<:MessagePassing} = m
@inline update(mp::T, i::Integer, m, x) where {T<:MessagePassing} = m

@inline function update_batch_edge(mp::T, adj, E::AbstractMatrix, X::AbstractMatrix, u) where {T<:MessagePassing}
    n = size(adj, 1)
    edge_idx = edge_index_table(adj)
    hcat([apply_batch_message(mp, i, adj[i], edge_idx, E, X, u) for i in 1:n]...)
end

@inline function apply_batch_message(mp::T, i, js, edge_idx, E::AbstractMatrix, X::AbstractMatrix, u) where {T<:MessagePassing}
    hcat([message(mp, get_feature(X, i), get_feature(X, j), get_feature(E, edge_idx[(i,j)])) for j = js]...)
end

@inline function update_batch_vertex(mp::T, M::AbstractMatrix, X::AbstractMatrix, u) where {T<:MessagePassing}
    hcat([update(mp, get_feature(M, i), get_feature(X, i)) for i in 1:size(X,2)]...)
end

@inline function aggregate_neighbors(mp::T, aggr::Symbol, M::AbstractMatrix, accu_edge) where {T<:MessagePassing}
    @assert !iszero(accu_edge) "accumulated edge must not be zero."
    cluster = generate_cluster(M, accu_edge)
    pool(aggr, cluster, M)
end

function propagate(mp::T, fg::FeaturedGraph, aggr::Symbol=:add) where {T<:MessagePassing}
    E, X = propagate(mp, adjacency_list(fg), fg.ef, fg.nf, aggr)
    FeaturedGraph(graph(fg), nf=X, ef=E, gf=Fill(0.f0, 0))
end

function propagate(mp::T, adj::AbstractVector{S}, E::R, X::Q, aggr::Symbol) where {T<:MessagePassing,S<:AbstractVector,R,Q}
    E, X, u = propagate(mp, adj, E, X, Fill(0.f0, 0), aggr, nothing, nothing)
    E, X
end