text:
# Many derivative free methods of different orders

##################################################
## Helpers for the various methods
## issue with approx derivative
isissue(x) = (x == 0.0) || isnan(x) || isinf(x)

"""
heuristic to get a decent first step with Steffensen steps
"""
function steff_step(x::T, fx) where {T}
    thresh =  max(1, norm(x)) * sqrt(eps(T)) # max(1, sqrt(abs(x/fx))) * 1e-6
    norm(fx) <= thresh ? fx : sign(fx) * thresh
end

function guarded_secant_step(alpha::T, beta::T, falpha, fbeta) where {T <: AbstractFloat}

    fp = (fbeta - falpha) /  (beta - alpha)
    Δ::T = fbeta / fp
    ## odd, we get allocations if we define Delta, then beta - Delta
    ## Δ = beta - fbeta * (beta - alpha) / (fbeta - falpha)

    if isissue(Δ)
        Δ = one(T)/1000
    elseif norm(Δ) >= 100 * norm(alpha - beta) # guard runaway
        Δ = sign(Δ) * 100 * min(one(T), norm(alpha - beta))
    end

    if isissue(Δ)
        return (alpha + (beta - alpha)*(0.5), true) # midpoint
    else
        return (beta - Δ, false)
    end
end

## Different functions for approximating f'(xn)
## return fpxn and whether it is an issue

## use f[a,b] to approximate f'(x)
function _fbracket(a, b, fa, fb)
    num, den = fb - fa, b - a
    num == 0 && den == 0 && return Inf, true
    out = num / den
    out, isissue(out)
end

## use f[y,z] - f[x,y] + f[x,z] to approximate
function _fbracket_diff(a,b,c, fa, fb, fc)
    x1, _ = _fbracket(b, c, fb,  fc)
    x2, _ = _fbracket(a, b, fa,  fb)
    x3, _ = _fbracket(a, c, fa,  fc)
    out = x1 - x2 + x3
    out, isissue(out)
end

## use f[a,b] * f[a,c] / f[b,c]
function _fbracket_ratio(a, b, c, fa, fb, fc)
    x1, _ = _fbracket(a, b, fa, fb)
    x2, _ = _fbracket(a, c, fa, fc)
    x3, _ = _fbracket(b, c, fb, fc)
    out = (x2 * x3) / x3
    out, isissue(out)
end

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

## Order0 and Secant are related
"""
    Order0()

The `Order0` method is engineered to be a more robust, though possibly
slower, alternative to to the other derivative-free root-finding
methods. The implementation roughly follows the algorithm described in
*Personal Calculator Has Key to Solve Any Equation f(x) = 0*, the
SOLVE button from the
[HP-34C](http://www.hpl.hp.com/hpjournal/pdfs/IssuePDFs/1979-12.pdf).
The basic idea is to use a secant step. If along the way a bracket is
found, switch to bisection, using `Bisection` if possible, else
`A42`.  If the secant step fails to decrease the function value, a
quadratic step is used up to 3 times.

"""
mutable struct Order0 <: AbstractSecant end

"""
    Order1()

The `Order1()` method is an alias for `Secant` and performs a secant
step. This method keeps two values in its state, `x_n` and `x_n1`. The
updated point is the intersection point of x axis with the secant line
formed from the two points. The secant method uses 1 function
evaluation and has order `(1+sqrt(5))/2`.

"""
mutable struct Secant <: AbstractSecant end
const Order1 = Secant

function init_state(method::AbstractSecant, fs, x::Union{T, Vector{T}}, bracket) where {T <: AbstractFloat}

    if isa(x, Vector)
        x0, x1 = x[1:2]
        #        fx0, fx1 = fs.f(x0), fs.f(x1)
        fx0, fx1 = fs(x0), fs(x1)
    else
        x0 = float(x)
        #        fx0 = fs.f(x0)
        fx0 = fs(x0)
        stepsize = max(1/100, min(abs(fx0), abs(x0/100)))
        x1 = x0 + stepsize
#        x0, x1, fx0, fx1  = x1, x0, fs.f(x1), fx0 # switch
        x0, x1, fx0, fx1  = x1, x0, fs(x1), fx0 # switch
    end

    state = UnivariateZeroStateBase(
                                    promote(float(x1), float(x0))...,
                                    promote(fx1, fx0)...,
                                    bracket,
                                    0, 2,
                                    false, false, false, false,
                                    "")
    state
end

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

## in Order0, we run bisection if a bracketing interval is found
function _run_bisection(fs, o, options)
    verbose = options.verbose; options.verbose=false # turn off verbose
    find_zero(Bisection(), fs, o, options)
    options.verbose = verbose
    o.message = "Used bisection for last step"
end

## order 0
# goal: more robust to initial guess than higher order methods
# follows roughly algorithm described http://www.hpl.hp.com/hpjournal/pdfs/IssuePDFs/1979-12.pdf, the SOLVE button from the HP-34C
# though some modifications were made.
# * use secant step
# * if along the way a bracket is found, switch to bisection. (We use float64 bisection not a42 if available)
# * if secant step fails to decrease, we use quadratic step up to 3 times
#
# Goal is to return a value `x` with either:
# * `f(x) == 0.0` or
# * `f(prevfloat(x)) * f(nextfloat(x)) < 0`.
# if a bracket is found that can be done, otherwise secant step is used
function update_state(method::Order0, fs, o::UnivariateZeroState{T}, options::UnivariateZeroOptions) where {T}

    f = fs.f
    alpha, beta = o.xn0, o.xn1
    falpha, fbeta = o.fxn0, o.fxn1

    incsteps(o)

    if sign(falpha) * sign(fbeta) < 0.0
        _run_bisection(fs, o, options)
        return nothing
    end

    gamma, issue = guarded_secant_step(alpha, beta, falpha, fbeta)

    fgamma = f(gamma); incfn(o)

    if sign(fgamma)*sign(fbeta) < 0.0
        o.xn0, o.xn1 = gamma, beta
        o.fxn0, o.fxn1 = fgamma, fbeta
        _run_bisection(fs, o, options)
        return nothing
    end

    if norm(fgamma) <= norm(fbeta)
        o.xn0, o.xn1 = beta, gamma
        o.fxn0, o.fxn1 = fbeta, fgamma
        return nothing
    end

    ctr = 0
    while true
        ## quadratic step
        ctr += 1
        if ctr >= 3
            o.stopped = true
            o.message = "dithering, algorithm failed to improve using quadratic steps"
            return nothing
        end

        # quadratic_step. Put new gamma at vertex of parabola through alpha, beta, (old) gamma
        denom = (beta - alpha) * (fbeta - fgamma)  - (beta - fgamma) * (fbeta - falpha)
        if isissue(denom)
            o.stopped
            o.message = "dithering, algorithm failed to improve using quadratic steps"
            return nothing
        end
        gamma = beta -  ((beta - alpha)^2 * (fbeta - fgamma) - (beta - gamma)^2 * (fbeta - falpha))/denom/2

        fgamma = f(gamma); incfn(o)
        incfn(o)

        if norm(fgamma) < norm(fbeta)
            o.xn0, o.xn1 = beta, gamma
            o.fxn0, o.fxn1 = fbeta, fgamma
            return nothing
        end

        theta, issue = guarded_secant_step(beta, gamma, fbeta, fgamma)

        ftheta = f(theta); incfn(o)

        if sign(ftheta) * sign(fbeta) < 0
            o.xn0, o.xn1 = beta, theta
            o.fxn0, o.fxn1 = fbeta, ftheta

            _run_bisection(fs, o, options)
            return nothing
        end
    end

    # failed to improve
    o.stopped = true
    o.message = "failure to improve"
    return nothing
end

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

## Secant
## https://en.wikipedia.org/wiki/Secant_method
function update_state(method::Secant, fs, o::UnivariateZeroState{T}, options::UnivariateZeroOptions{T}) where {T <: AbstractFloat}

    incsteps(o)

    fp, issue = _fbracket(o.xn0, o.xn1, o.fxn0, o.fxn1)
    if issue
        o.stopped = true
        o.message = "Derivative approximation had issues"
        return
    end

    o.xn0 = o.xn1
    o.fxn0 = o.fxn1

    o.xn1 = o.xn1 -  o.fxn1 / fp
    #    o.fxn1 = fs.f(o.xn1)
    o.fxn1 = fs(o.xn1)
    incfn(o)

    nothing
end

"""

    secant_method(f, x0, x1; [kwargs...])

Solve for zero of `f(x) = 0` using the secant method.

Not exported.  Use `find_zero` with `Order1()`.
"""
secant_method(f, x0::Real, x1::Real; kwargs...) = find_zero(f, map(float, [x0,x1]), Order1(); kwargs...)

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

### Steffensen
## https://en.wikipedia.org/wiki/Steffensen's_method#Simple_description
mutable struct Steffensen <: UnivariateZeroMethod
end

"""
    Order2()

The quadratically converging
[Steffensen](https://en.wikipedia.org/wiki/Steffensen's_method#Simple_description)
method is used for the derivative free `Order2()` algorithm. Unlike
the quadratically converging Newton's method, no derivative is
necessary, though like Newton's method, two function calls per step
are. This algorithm is more sensitive than Newton's method to poor
initial guesses.

"""
const Order2 = Steffensen

function update_state(method::Steffensen, fs, o::UnivariateZeroState{T}, options::UnivariateZeroOptions{T}) where {T <: AbstractFloat}

    S = eltype(o.fxn1)

    incsteps(o)

    wn = o.xn1 + steff_step(o.xn1, o.fxn1)::T
    fwn = fs(wn)::S
    incfn(o)

    fp, issue = _fbracket(o.xn1, wn, o.fxn1, fwn)

    if issue
        o.stopped = true
        o.message = "Derivative approximation had issues"
        return
    end

    o.xn0 = o.xn1
    o.fxn0 = o.fxn1
    o.xn1 = o.xn1 - o.fxn1 / fp #xn1
    o.fxn1 = fs(o.xn1)
    incfn(o)

    nothing
end

steffenson(f, x0; kwargs...) = find_zero(f, x0, Steffensen(); kwargs...)

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

"""
    Order5()

Implements an algorithm
from *A New Fifth Order Derivative Free Newton-Type Method for Solving Nonlinear Equations*
by Manoj Kumar, Akhilesh Kumar Singh, and Akanksha,
Appl. Math. Inf. Sci. 9, No. 3, 1507-1513 (2015). Four function calls per step are needed.

"""
mutable struct Order5 <: UnivariateZeroMethod end

function update_state(method::Order5, fs, o::UnivariateZeroState{T}, options::UnivariateZeroOptions) where {T}

    xn = o.xn1
    fxn = o.fxn1
    S = eltype(o.fxn1)

    incsteps(o)

    wn::T = o.xn1 + steff_step(o.xn1, o.fxn1)
    fwn = fs(wn)::S
    incfn(o)

    fp, issue = _fbracket(o.xn1, wn, o.fxn1, fwn)
    if issue
        o.xn0, o.xn1 = o.xn1, wn
        o.fxn0, o.fxn1 = o.fxn1, fwn
        o.message = "Issue with divided difference f[xn, wn]"
        o.stopped  = true
        return
    end

    yn::T = o.xn1 - o.fxn1 / fp
    fyn = fs(yn)::S
    incfn(o)

    zn::T = xn - (fxn + fyn) / fp
    fzn = fs(zn)::S
    incfn(o)

    fp, issue = _fbracket_ratio(yn, o.xn1, wn, fyn, o.fxn1, fwn)
    if issue
        o.xn0, o.xn1 = o.xn1, yn
        o.fxn0, o.fxn1 = o.fxn1, fyn
        o.message = "Issue with f[xn,yn]*f[yn,wn] / f[xn, wn]"
        o.stopped = true
        return
    end

    o.xn0 = o.xn1
    o.fxn0 = o.fxn1
    o.xn1 = zn  - fzn  / fp
    o.fxn1 = fs(o.xn1)
    incfn(o)

    nothing
end

## If we have a derivative
function update_state(method::Order5, fs::FirstDerivative, o::UnivariateZeroState{T}, options::UnivariateZeroOptions) where {T}

    xn, fxn = o.xn1, o.fxn1
    S = eltype(fxn)

    incsteps(o)

    fpxn = fs.fp(xn)
    incfn(o)

    if isissue(fpxn)
        o.stopped  = true
        return
    end

    yn = xn - fxn / fpxn
    fyn, fpyn = fs.f(yn), fs.fp(yn)
    incfn(o, 2)

    if isissue(fpyn)
        o.xn0, o.xn1 = xn, yn
        o.fxn0, o.fxn1 = fxn, fyn
        o.stopped  = true
        return
    end

    zn = xn  - (fxn + fyn) / fpxn
    fzn = fs.f(zn)
    incfn(o, 1)

    xn1 = zn - fzn / fpyn
    fxn1 = fs.f(xn1)
    incfn(o, 1)

    o.xn0, o.xn1 = xn, xn1
    o.fxn0, o.fxn1 = fxn, fxn1

    nothing
end

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

"""
    Order8()

Implements an algorithm from
*New Eighth-Order Derivative-Free Methods for Solving Nonlinear Equations*
by Rajinder Thukral,
International Journal of Mathematics and Mathematical Sciences
Volume 2012 (2012), Article ID 493456, 12 pages. Four function calls per step are required.
"""
mutable struct Order8 <: UnivariateZeroMethod
end

function update_state(method::Order8, fs, o::UnivariateZeroState{T}, options::UnivariateZeroOptions) where {T}
    xn = o.xn1
    fxn = o.fxn1
    S = eltype(fxn)

    incsteps(o)

    wn::T = xn + steff_step(xn, fxn)
    fwn::S = fs(wn)
    incfn(o)

    if isissue(fwn)
        o.xn0,o.xn1 = xn, wn
        o.fxn0,o.fxn1 = fxn, fwn
        o.stopped = true
        o.message = "issue with Steffensen step fwn"
        return
    end

    fp, issue = _fbracket(xn, wn, fxn, fwn)
    issue && return (xn, true)

    if issue
        o.stopped = true
        o.message = "issue with divided difference f[xn, wn]"
        return
    end

    yn::T = xn - fxn / fp
    fyn::S = fs(yn)
    incfn(o)

    fp, issue = _fbracket(yn, xn, fyn, fxn)
    if issue #fp
        o.xn0,o.xn1 = xn, yn
        o.fxn0,o.fxn1 = fxn, fyn
        o.stopped = true
        o.message = "issue with divided difference f[xn, yn]"
        return
    end

    phi = (1 + fyn / fwn)           # pick one of options
    zn =  yn - phi * fyn / fp
    fzn::S = fs(zn)
    incfn(o)

    fp, issue =  _fbracket_diff(xn, yn, zn, fxn, fyn, fzn)
    if issue
        o.xn0,o.xn1 = xn, zn
        o.fxn0,o.fxn1 = fxn, fzn
        o.message = "issue with divided difference  f[y,z] - f[x,y] + f[x,z]"
        o.stopped = true
        return
    end

    w::T = 1 / (1 - fzn/fwn)

    xi::T = (1 - 2fyn*fyn*fyn / (fwn * fwn * fxn))

    xn1::T = zn - w * xi * fzn / fp
    fxn1::S = fs(xn1)
    incfn(o)

    o.xn0,o.xn1 = xn, xn1
    o.fxn0,o.fxn1 = fxn, fxn1

    nothing
end

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

"""
    Order16()

Implement the algorithm from
*New Sixteenth-Order Derivative-Free Methods for Solving Nonlinear Equations*
by R. Thukral,
American Journal of Computational and Applied Mathematics
p-ISSN: 2165-8935;    e-ISSN: 2165-8943; 2012;  2(3): 112-118
doi: 10.5923/j.ajcam.20120203.08.

Five function calls per step are required. Though rapidly converging, this method generally isn't faster (fewer
function calls/steps) over other methods when using `Float64` values,
but may be useful for solving over `BigFloat`.
"""
mutable struct Order16 <: UnivariateZeroMethod
end

function update_state(method::Order16, fs, o::UnivariateZeroState{T}, options::UnivariateZeroOptions) where {T}
    xn = o.xn1
    fxn = o.fxn1
    S = eltype(fxn)

    incsteps(o)

    wn::T = xn + steff_step(xn, fxn)
    fwn::S = fs(wn)
    incfn(o)

    fp, issue = _fbracket(xn, wn, fxn, fwn)

    if issue
        o.xn0, o.xn1 = xn, wn
        o.fxn0, o.fxn1 = fxn, fwn
        o.message = "issue with f[xn,wn]"
        o.stopped = true
        return
    end

    yn::T = xn - fxn / fp
    fyn::S = fs(yn)
    incfn(o)

    fp, issue = _fbracket_ratio(yn, xn, wn, fyn, fxn, fwn)
    if issue
        o.xn0, o.xn1 = xn, yn
        o.fxn0, o.fxn1 = fxn, fyn
        o.message = "issue with f[xn,yn]*f[yn,wn]/f[xn,wn]"
        o.stopped = true
        return
    end

    zn::T = yn - fyn / fp
    fzn::S = fs(zn)
    incfn(o)

    fp, issue = _fbracket_diff(xn, yn, zn, fxn, fyn, fzn)
    u2, u3, u4 = fzn/fwn, fyn/fxn, fyn/fwn
    eta = 1 / (1 + 2*u3*u4^2) / (1 - u2)
    if issue
        o.xn0, o.xn1 = xn, zn
        o.fxn0, o.fxn1 = fxn, fzn
        o.stopped = true
        o.message = "Approximate derivative failed"
        return
    end

    an = zn - eta * fzn / fp
    fan = fs(an)
    incfn(o)

    fp, issue = _fbracket_ratio(an, yn, zn, fan, fyn, fzn)
    if issue
        o.xn0, o.xn1 = xn, an
        o.fxn0, o.fxn1 = fxn, fan
        o.stopped = true
        o.message = "Approximate derivative failed"
        return
    end

    u1, u5, u6 = fzn/fxn, fan/fxn, fan/fwn
    sigma =  1 + u1*u2 - u1*u3*u4^2 + u5 + u6 + u1^2*u4 +
    u2^2*u3 + 3*u1*u4^2*(u3^2 - u4^2)/_fbracket(xn,yn, fxn, fyn)[1]

    xn1 = an - sigma * fan / fp
    fxn1 = fs(xn1)
    incfn(o)

    o.xn0, o.xn1 = xn, xn1
    o.fxn0, o.fxn1 = fxn, fxn1

    nothing
end


text:
type Dependency
  name::ASCIIString
  path::ASCIIString
  has_export::Bool
end

function write_html_head(io::IO)
	print(io, """
	<link href="https://cdnjs.cloudflare.com/ajax/libs/dc/1.7.5/dc.css" rel="stylesheet">

	""")
end

function write_html_chart_entry(io::IO, chart::DCChart, indent::Int=0)
	tabbing = "  "^indent
	println(io, tabbing, "
")
	println(io, tabbing, "
", chart.title, "
")
	println(io, tabbing, "

")
	println(io, tabbing, "
")
end

function write_html_widget_entry(io::IO, widget::DCWidget, indent::Int=0)
  tabbing = "  "^indent
  println(io, tabbing, widget.html, "
")
end

function write_html_body(io::IO, dcout::DCOut)
	print(io, "

&nbsp

  ")
	for chart in dcout.charts
		write_html_chart_entry(io, chart, 1)
	end
	print(io, """

  """)
  for widget in dcout.widgets
    write_html_widget_entry(io, widget, 0)
  end
	println(io, "")
end

function write_script_dependencies(io::IO, dependencies::Vector{Dependency})
  print(io, """require.config({paths: {""")
	for i in 1 : length(dependencies)
    #=
		@printf(io, "\n", src)
    =#
    @printf(io, """ "%s": "%s" """, dependencies[i].name, dependencies[i].path)
    if i < length(dependencies)
      print(io, ",\n")
    end
	end
  print(io, """}});\n""")
end

function write_json_entry(io, names::Vector{Symbol}, values::Vector{Any})
	print(io, "{")
	for i in 1 : length(names)
		print(io, "\"", names[i], "\": ")
		v = values[i]
		if isa(v, AbstractString)
			print(io, "\"", v, "\"")
		else
			print(io, v)
		end
		if i < length(names)
			print(io, ", ")
		end
	end
	print(io, "}")
end

function write_data(io::IO, dcout::DCOut)
    df = dcout.df
	values = Array(Any, length(dcout.dims))
    colnames = map(dim->dim.name, dcout.dims)
	print(io, "data = [")
	for i in 1:nrow(df)
		for (j,dim) in enumerate(dcout.dims)
			values[j] = df[i,dim.name]
		end
		write_json_entry(io, colnames, values)
		if i < nrow(df)
			print(io, ",")
		end
	end
	println(io, "];")
end

function write_reset_script(io::IO, dcout::DCOut)
	print(io, "var charts = [")
	for i in 1 : length(dcout.charts)
		print(io, dcout.charts[i].parent)
		if i < length(dcout.charts)
			print(io, ", ")
		end
	end
	println(io, "];")
	print(io, "var chart_names = [")
	for i in 1 : length(dcout.charts)
		print(io, "\"", dcout.charts[i].parent, "\"")
		if i < length(dcout.charts)
			print(io, ", ")
		end
	end
	println(io, "];")
	print(io, """

var update_reset_buttons = function(chart) {
  var filter_in_use = false;
  for (var i = 0; i < charts.length; i++) {
    if (charts[i].filters().length > 0) {
      filter_in_use = true;
      break;
    }
  }
  var idx = charts.indexOf(chart);
  d3.select("#reset_all_btn_""", dcout.output_id,
  """").remove();
  d3.select("#heading_" + chart_names[idx]).select(".chart-reset").remove();

  if (filter_in_use) {
    d3.select("#reset_all_well_""", dcout.output_id, """")
      .append("a")
      .attr("class", "button-label")
      .attr("id", "reset_all_btn_""", dcout.output_id, """")
      .text(function(d) {
        return "Reset All";
      })
      .on("click", function() {
        for (var i = 0; i < charts.length; i++) {
          charts[i].filter(null);
        }
        dc.redrawAll();
      });

    if (chart.filters().length > 0) {
      d3.select("#heading_" + chart_names[idx])
        .append("span")
        .attr("class", "chart-reset fake-link")
        .text(function(d) {
          return "Reset";
        })
        .on("click", function(d) {
          chart.filter(null);
          dc.redrawAll();
        });
    }
  }
};

for (var i = 0; i < charts.length; i++) {
  charts[i].on('filtered', function(chart) {
    update_reset_buttons(chart);
  });
}
	""")
end

function quote_corrector() # doesn't actually do anything, just corrects quotes on sublime
	x = """
	a"c
	"""
end
function write_script(io::IO, dcout::DCOut, dependencies::Vector{Dependency})
	println(io, """")
end

function write_source_html(io::IO, dcout::DCOut)
	write_html_head(io)
	write_html_body(io, dcout)
 	# Note: dependencies must be ordered! (hence why this is not a dictionary)
	dependencies = [Dependency("d3","https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min", true),
	                Dependency("crossfilter","https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.7/crossfilter", false),
	                Dependency("dc","https://cdnjs.cloudflare.com/ajax/libs/dc/1.7.1/dc", true)]
	write_script(io, dcout, dependencies)
end

function Base.writemime(io::IO, ::MIME"text/html", dcout::DCOut)

	# If IJulia is present, go for it
	if isdefined(Main, :IJulia)
		#=
		1 - determine chart layout
		2 - generate iframe html + js page
		3 - write link to it
		=#

		iframe_width = 975 # [pix]
		row_height = 275 # [pix]x`

		ncharts = length(dcout.charts)
    widget_height_addition = 0
    for widget in dcout.widgets
      if widget.typ.concreteName == "dataCount"
        widget_height_addition += 15
      else
        widget_height_addition += 150
      end
    end
    has_widget = length(dcout.widgets) > 0
		nrows = ceil(Int, ncharts/3)
		iframe_height = nrows*275 + widget_height_addition + 15

    randomize_ids!(dcout)
    if dcout.elastic_height
      write(io, """
""")
    else
      write(io, """
""")
    end
    write_source_html(io, dcout)
    write(io, """
""")

    if dcout.html_debug
      f = open("output.html", "w")
      write(f, """

        """)
      write(f, """
""")
      write_source_html(f, dcout)
      write(f, """
""")
      close(f)
    end
	else
		# TODO
		# decide what to do in the absence of IJulia
	end
end

ext: jl


text:
# Begin Blocks

z = begin
  x = 1
  y = 2
  x + y # Value of Last subexpression assigned to z
end

println(z)

# Chains

z = (x = 1; y = 2; x + y)

# Combined

begin x = 1; y = 2; x + y end

max_stars_repo_name: cadamsmith/julia-programming

max_issues_repo_name: cadamsmith/julia-programming

max_forks_repo_name: cadamsmith/julia-programming


text:
function build_datastore_apicall_model(callFunction::Function, tickerSymbol::String;
    output::Symbol = :compact, datatype::Symbol = :json)::PSResult

    # TODO: Checks -

    # initialize -
    output_type_set = Set{Symbol}()
    datatype_set = Set{Symbol}()

    # check output types -
    push!(output_type_set,:compact)
    push!(output_type_set,:full)
    if (in(output,output_type_set) == false)
        return PSResult(ArgumentError("Incompatible output type. Expected {:compact,:full} but received $(string(output))"))
    end

    # check datatype -
    push!(datatype_set, :json)
    push!(datatype_set, :csv)
    if (in(datatype,datatype_set) == false)
        return PSResult(ArgumentError("Incompatible data type. Expected {:json,:csv} but received $(string(output))"))
    end

    # check the tickerSymbol -
    if (isa(tryparse(Float64,tickerSymbol), Number) == true)
        return PSResult(ArgumentError("Incompatible ticker symbol type"))
    end

    # TODO: how do we check is we have a specific function?

    # get stuff -
    parameter_object = PSDataStoreAPICallModel(callFunction, tickerSymbol; dataType=datatype, output=output)

    # return -
    return PSResult(parameter_object)
end

"""
    execute_api_call(user::PSUserModel, api::PSDataStoreAPICallModel; logger::Union{Nothing,AbstractLogger} = nothing)::PSResult

High-level convenience function to execute an data store application programming interface call.

# Arguments
"""
function execute_api_call(usermodel::PSUserModel, apimodel::PSDataStoreAPICallModel;
    logger::Union{Nothing,AbstractLogger} = nothing)::PSResult

    # get stuff from the parameters -
    tickerSymbol = apimodel.ticker
    outputsize = apimodel.outputsize
    datatype = apimodel.dataType
    apicall = apimodel.apicall

    # make the call -
    return apicall(usermodel,tickerSymbol; data_type = datatype, outputsize = outputsize, logger = logger)
end


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

using Markdown
using InteractiveUtils

# ╔═╡ 75852c20-4878-11ec-0f17-77727b908d78
using Pkg; Pkg.activate("C:\\Users\\sdani\\MakieDev")

# ╔═╡ f2f63242-e0ba-4fd6-a454-7fd0952236ad
using Revise, GLMakie

# ╔═╡ d5201580-108d-42e2-8eb5-c4489cc2ceb4
begin
	using WGLMakie, JSServe
	wgl = WGLMakie.activate!()
	Page(offline=true, exportable=true)
end

# ╔═╡ abe526e5-6d36-4ac5-876f-ebd65ff8a05f
using RPRMakie

# ╔═╡ ba3bb4b5-73b6-44b1-ab84-f57406058479
begin
	using MeshIO, FileIO, GeometryBasics

	colors = Dict(
	    "eyes" => "#000",
	    "belt" => "#000059",
	    "arm" => "#009925",
	    "leg" => "#3369E8",
	    "torso" => "#D50F25",
	    "head" => "yellow",
	    "hand" => "yellow"
	)

	origins = Dict(
	    "arm_right" => Point3f(0.1427, -6.2127, 5.7342),
	    "arm_left" => Point3f(0.1427, 6.2127, 5.7342),
	    "leg_right" => Point3f(0, -1, -8.2),
	    "leg_left" => Point3f(0, 1, -8.2),
	)

	rotation_axes = Dict(
	    "arm_right" => Vec3f(0.0000, -0.9828, 0.1848),
	    "arm_left" => Vec3f(0.0000, 0.9828, 0.1848),
	    "leg_right" => Vec3f(0, -1, 0),
	    "leg_left" => Vec3f(0, 1, 0),
	)

	function plot_part!(scene, parent, name::String)
	    m = load(assetpath("lego_figure_" * name * ".stl"))
	    color = colors[split(name, "_")[1]]
	    trans = Transformation(parent)
	    ptrans = Makie.transformation(parent)
	    origin = get(origins, name, nothing)
	    if !isnothing(origin)
	        centered = m.position .- origin
	        m = GeometryBasics.Mesh(meta(centered; normals=m.normals), faces(m))
	        translate!(trans, origin)
	    else
	        translate!(trans, -ptrans.translation[])
	    end
	    return mesh!(scene, m; color=color, transformation=trans)
	end
	function plot_lego_figure(s, floor=true)
		# Plot hierarchical mesh!
		figure = Dict()
	    # Plot hierarchical mesh!
	    figure["torso"] = plot_part!(s, s, "torso")
	        figure["head"] = plot_part!(s, figure["torso"], "head")
	            figure["eyes_mouth"] = plot_part!(s, figure["head"], "eyes_mouth")
	        figure["arm_right"] = plot_part!(s, figure["torso"], "arm_right")
	            figure["hand_right"] = plot_part!(s, figure["arm_right"], "hand_right")
	        figure["arm_left"] = plot_part!(s, figure["torso"], "arm_left")
	            figure["hand_left"] = plot_part!(s, figure["arm_left"], "hand_left")
	        figure["belt"] = plot_part!(s, figure["torso"], "belt")
	            figure["leg_right"] = plot_part!(s, figure["belt"], "leg_right")
	            figure["leg_left"] = plot_part!(s, figure["belt"], "leg_left")
		# lift the little guy up
	    translate!(figure["torso"], 0, 0, 20)
	    # add some floor
	    floor && mesh!(s, Rect3f(Vec3f(-400, -400, -2), Vec3f(800, 800, 2)), color=:white)
		return figure
	end
end

# ╔═╡ 87021c46-5fcd-4995-80fc-bb49fd194978
gl = GLMakie.activate!(); scene = Scene(;
    # clear everything behind scene
    clear = true,
    # the camera struct of the scene.
    visible = true,
    ssao = Makie.SSAO(),
    # Creates lights from theme, which right now defaults to `
	# set_theme!(lightposition=:eyeposition, ambient=RGBf(0.5, 0.5, 0.5))`
    lights = Makie.automatic,
    backgroundcolor = :gray,
	resolution = (500, 500)
)

# ╔═╡ 09fcfad7-0c3b-4910-b6ad-ba8e2f6b24f2
md"""
By default, the scenes goes from -1 to 1.
So to draw a rectangle outlining the screen, the following rectangle does the job:
"""

# ╔═╡ 98c046a9-9a4e-4dc2-ad5a-205805064a03
lines!(scene, Rect2f(-1, -1, 2, 2), linewidth=5, color=:black); scene

# ╔═╡ 8bae338c-1041-4cda-be49-2328f0d01d9c
md"""
this is, because the projection matrix and view matrix are the identity matrix by default, and Makie's default unit space is what's called `Clip space` in the OpenGL world
"""

# ╔═╡ 5bca7128-10fa-4674-b20d-a4ebdcbf6ec6
cam = camera(scene) # this is how to access the scenes camera

# ╔═╡ 4b05f6ee-ffe3-4658-87d0-4930035ee7d9
md"""
One can change the mapping, to e.g. draw from -3 to 5:
"""

# ╔═╡ f3842cab-564b-42ca-a7a2-cbe4a8991f86
cam.projection[] = Makie.orthographicprojection(-3f0, 5f0, -3f0, 5f0, -100f0, 100f0); scene

# ╔═╡ fc346f84-9d87-4f40-9bbe-ea1592db66bb
md"""
one can also change the camera to a perspective 3d projection:
"""

# ╔═╡ 20f97b0c-b579-4bdb-82e9-a0976f015a74
begin
	w, h = size(scene)
	cam.projection[] = Makie.perspectiveprojection(45f0, Float32(w / h), 0.1f0, 100f0)
	# Now, we also need to change the view matrix
	# to "put" the camera into some place.
	cam.view[] = Makie.lookat(Vec3f(10), Vec3f(0), Vec3f(0, 0, 1))
	scene
end

# ╔═╡ 68b06965-c4a9-4324-8ddd-1f30a1e4cf11
md"""
These are all camera transformations of the object.
In contrast, there are also scene transformations, or commonly referred to as world transformations.
To learn more about the different spaces, [learn opengl](https://learnopengl.com/Getting-started/Coordinate-Systems) offers some pretty nice explanations

The "world" transformations are implemented via the `Transformation` struct in Makie. Scenes and plots both contain these, so these types are considered as "Makie.Transformable".
The transformation of a scene will get inherited by all plots added to the scene.
An easy way to manipulate any `Transformable` is via these 3 functions:
{{doc translate!}}
{{doc rotate!}}
{{doc scale!}}
"""

# ╔═╡ e56bea12-6c1f-4057-88b5-a1557396854c
begin
	sphere_plot = mesh!(scene, Sphere(Point3f(0), 0.5), color=:red)
	scale!(scene, 2, 2, 2)
	rotate!(scene, Vec3f(1, 0, 0), 0.5) # 0.5 rad around the y axis
	scene
end

# ╔═╡ 8d18a5fe-ca4a-4bc7-a547-f816d634e2db
md"""
One can also transform the plot objects directly, which then adds the transformation from the plot object on top of the transformation from the scene.
One can add subscenes and interact with those dynamically.
Makie offers here what's usually referred to as a scene graph.
"""

# ╔═╡ 82e9cdd2-aa5e-451b-8af4-d181acaf9910
translate!(sphere_plot, Vec3f(0, 0, 1)); scene

# ╔═╡ e53c8b75-a44a-459d-a5f6-975dd9cc9c1b
md"""
The scene graph can be used to create rigid transformations, like for a robot arm:
"""

# ╔═╡ 7015a26c-f5a7-4e86-9c56-58432dbb0b44
begin
	gl
	parent = Scene()
	cam3d!(parent)
	camc = cameracontrols(parent)

	update_cam!(parent, camc, Vec3f(0, 8, 0), Vec3f(4.0, 0, 0))
	s1 = Scene(parent, camera=parent.camera)
	mesh!(s1, Rect3f(Vec3f(0, -0.1, -0.1), Vec3f(5, 0.2, 0.2)))
	s2 = Scene(s1, camera=parent.camera)
	mesh!(s2, Rect3f(Vec3f(0, -0.1, -0.1), Vec3f(5, 0.2, 0.2)), color=:red)
	translate!(s2, 5, 0, 0)
	s3 = Scene(s2, camera=parent.camera)
	mesh!(s3, Rect3f(Vec3f(-0.2), Vec3f(0.4)), color=:blue)
	translate!(s3, 5, 0, 0)
	parent
end

# ╔═╡ 032eac09-a05c-43f6-af93-4b268957d6d5
begin
	# Now, rotate the "joints"
	rotate!(s2, Vec3f(0, 1, 0), 0.5)
	rotate!(s3, Vec3f(1, 0, 0), 0.5)
	parent
end

# ╔═╡ 045c8539-6e68-40ec-bf93-889ba481e374
md"""
With this basic principle, we can even bring robots to life :)
[Kevin Moerman](https://github.com/Kevin-Mattheus-Moerman) was so nice to supply a Lego mesh, which we're going to animate!
When the scene graph is really just about a transformation Graph, one can use the Transformation struct directly, which is what we're going to do here.
This is more efficient and easier than creating a scene for each model.
"""

# ╔═╡ fa2373db-edd0-42fa-9256-492061a35190
App() do session
	wgl
	s = Scene(resolution=(500, 500))
    cam3d!(s)
	figure = plot_lego_figure(s, false)
	bodies = [
		"arm_left", "arm_right",
		"leg_left", "leg_right"]
	sliders = map(bodies) do name
		slider = if occursin("arm", name)
			JSServe.Slider(-60:4:60)
		else
			JSServe.Slider(-30:4:30)
		end
        rotvec = rotation_axes[name]
		bodymesh = figure[name]
        on(slider) do val
            rotate!(bodymesh, rotvec, deg2rad(val))
        end
        DOM.div(name, slider)
    end
	center!(s)
	JSServe.record_states(session, DOM.div(sliders..., s))
end

# ╔═╡ 3495dfd6-4a10-4178-9136-dd10a4d055b5
let
	RPRMakie.activate!(iterations=20)
	radiance = 50000
    lights = [
        # EnvironmentLight(1.5, rotl90(load(assetpath("sunflowers_1k.hdr"))')),
        PointLight(Vec3f(50, 0, 200), RGBf(radiance, radiance, radiance*1.1)),
    ]
    s = Scene(lights=lights, resolution=(500, 500))
    cam3d!(s)
    c = cameracontrols(s)
    c.near[] = 5
    c.far[] = 1000
    update_cam!(s, c, Vec3f(100, 30, 80), Vec3f(0, 0, -10))
	figure = plot_lego_figure(s)

    rot_joints_by = 0.25*pi
    total_translation = 50
    animation_strides = 10

    a1 = LinRange(0, rot_joints_by, animation_strides)
    angles = [a1; reverse(a1[1:end-1]); -a1[2:end]; reverse(-a1[1:end-1]);]
    nsteps = length(angles); #Number of animation steps
    translations = LinRange(0, total_translation, nsteps)
    Makie.Record(s, zip(translations[1:4], angles[1:4])) do (translation, angle)
        #Rotate right arm+hand
        for name in ["arm_left", "arm_right",
                			 "leg_left", "leg_right"]
            rotate!(figure[name], rotation_axes[name], angle)
        end
        translate!(figure["torso"], translation, 0, 20)
    end
end

# ╔═╡ 01bc92cf-6943-48be-a373-3cd328660bed

# ╔═╡ Cell order:
# ╠═75852c20-4878-11ec-0f17-77727b908d78
# ╠═f2f63242-e0ba-4fd6-a454-7fd0952236ad
# ╠═87021c46-5fcd-4995-80fc-bb49fd194978
# ╟─09fcfad7-0c3b-4910-b6ad-ba8e2f6b24f2
# ╠═98c046a9-9a4e-4dc2-ad5a-205805064a03
# ╟─8bae338c-1041-4cda-be49-2328f0d01d9c
# ╠═5bca7128-10fa-4674-b20d-a4ebdcbf6ec6
# ╟─4b05f6ee-ffe3-4658-87d0-4930035ee7d9
# ╠═f3842cab-564b-42ca-a7a2-cbe4a8991f86
# ╟─fc346f84-9d87-4f40-9bbe-ea1592db66bb
# ╠═20f97b0c-b579-4bdb-82e9-a0976f015a74
# ╟─68b06965-c4a9-4324-8ddd-1f30a1e4cf11
# ╠═e56bea12-6c1f-4057-88b5-a1557396854c
# ╟─8d18a5fe-ca4a-4bc7-a547-f816d634e2db
# ╠═82e9cdd2-aa5e-451b-8af4-d181acaf9910
# ╟─e53c8b75-a44a-459d-a5f6-975dd9cc9c1b
# ╠═7015a26c-f5a7-4e86-9c56-58432dbb0b44
# ╠═032eac09-a05c-43f6-af93-4b268957d6d5
# ╟─045c8539-6e68-40ec-bf93-889ba481e374
# ╠═ba3bb4b5-73b6-44b1-ab84-f57406058479
# ╠═d5201580-108d-42e2-8eb5-c4489cc2ceb4
# ╠═fa2373db-edd0-42fa-9256-492061a35190
# ╠═abe526e5-6d36-4ac5-876f-ebd65ff8a05f
# ╠═3495dfd6-4a10-4178-9136-dd10a4d055b5
# ╠═01bc92cf-6943-48be-a373-3cd328660bed


text:
# TODO: make this immutable, possibly by changing the mechanism to build
# the `BasisSet`

"""
Contracted Gaussian basis function.
```
CGBF = sum_{i=Ncontr} coefs[i]*PGBF(expn, center, power)
```
"""
mutable struct CGBF
    center::Tuple3F64
    power::Tuple3I64
    pgbfs::Array{PGBF,1}
    coefs::Array{Float64,1}
    NORM::Float64
end

import Base.println
function println( bf::CGBF )
    Ncontr = length(bf.pgbfs)
    @printf("\nContracted Gaussian basis function\n")
    @printf("\nNcontr = %d\n\n", Ncontr)
    for i = 1:Ncontr
        @printf("Coef = %18.10f", bf.coefs[i])
        println(bf.pgbfs[i])
    end
end

function init_CGBF( center::Tuple3F64, power::Tuple3I64 )
    return CGBF( center, power, PGBF[], Float64[], 1.0 )
end

init_CGBF(x=0,y=0,z=0,I=0,J=0,K=0) = CGBF( (x,y,z), (I,J,K), PGBF[], Float64[], 1.0 )

function evaluate(bf::CGBF,x::Float64,y::Float64,z::Float64)
    s = 0
    for (c,pbf) in primitives(bf)
        s += c*evaluate(pbf,x,y,z)
    end
    return bf.NORM*s
end

function normalize!(bf::CGBF)
    bf.NORM /= sqrt(overlap(bf,bf))
end

primitives(a::CGBF) = zip(a.coefs,a.pgbfs)

# This should become the constructor along with center and power
import Base: push!
function push!(cbf::CGBF, expn, coef)
    Base.push!(cbf.pgbfs, PGBF(expn, cbf.center, cbf.power))
    Base.push!(cbf.coefs, coef)
    normalize!(cbf)
end

function contract(f, a::CGBF, b::CGBF)
    s = 0.0
    for (ca,abf) in primitives(a)
    for (cb,bbf) in primitives(b)
        s += ca*cb*f(abf,bbf)
    end
    end
    return a.NORM*b.NORM*s
end

function contract(f,a::CGBF,b::CGBF,c::CGBF,d::CGBF)
    s = 0
    for (ca,abf) in primitives(a)
    for (cb,bbf) in primitives(b)
    for (cc,cbf) in primitives(c)
    for (cd,dbf) in primitives(d)
        s += ca*cb*cc*cd*f(abf,bbf,cbf,dbf)
    end
    end
    end
    end
    return a.NORM*b.NORM*c.NORM*d.NORM*s
end


text:
using SymWoodburyMatrices
using Base.Test

n = 10; k = 3

A = SymWoodbury(Diag(rand(n)), randn(n,k), randn(k,k))
x = randn(n,1)

@test norm(A*x - full(A)*x) < 1e-10
@test norm(inv(A)*x - inv(full(A))*x) < 1e-10

A = SymWoodbury(Diag(rand(n)), sparse(randn(n,k)), sparse(randn(k,k)))
x = randn(n,1)

@test norm(A*x - full(A)*x) < 1e-10
@test norm(inv(A)*x - inv(full(full(A)))*x) < 1e-10

A = SymWoodbury(Diag(rand(n)), sparse(randn(n,k)), randn(k,k))
x = randn(n,1)

@test norm(A*x - full(A)*x) < 1e-10
@test norm(inv(A)*x - inv(full(full(A)))*x) < 1e-10

A = SymWoodbury(eye(n), sparse(randn(n,k)), randn(k,k))
x = randn(n,1)

@test norm(A*x - full(A)*x) < 1e-10
@test norm(inv(A)*x - inv(full(full(A)))*x) < 1e-10
@test norm(liftFactor(A)(x) - inv(full(full(A)))*x) < 1e-10

x = randn(n)
o = copy(x)


text:
#
# OIFITS.jl --
#
# Support for OI-FITS (optical interferometry data format) in Julia.
#
#------------------------------------------------------------------------------
#
# This file is part of OIFITS.jl which is licensed under the MIT "Expat"
# License:
#
# Copyright (C) 2015: Éric Thiébaut.
#
#------------------------------------------------------------------------------

module OIFITS

import Base: getindex, setindex!, haskey, keys, start, done, next, show

include("oidata.jl")
include("fix-fitsio.jl")
include("misc.jl")
include("oifile.jl")
include("oiformat1.jl")
include("oipost.jl") # must be *after* oifile.jl and all oiformat*.jl
include("deprecations.jl")

end # module


text:
using TensorBoardLogger
using Test

@testset "Scalar Value Logger" begin
    logger = Logger("log/")
    @test isdir("log/")
    step = 1
    log_value(logger, "float32", 1.25f0, step=step)
    log_value(logger, "float64", 1.5, step=step)
    log_value(logger, "irr", pi, step=step)
    log_value(logger, "complex", 1.0 + 1.0im, step=step)

    log_value(logger, "float32", 1.25f0, step)
    log_value(logger, "float64", 1.5, step)
    log_value(logger, "irr", pi, step)
    log_value(logger, "complex", 1.0 + 1.0im, step)
end

@testset "Histogram Value Logger" begin
    logger = Logger("log/")
    @test isdir("log/")
    step = 1

    x0 = 0.5+step/30; s0 = 0.5/(step/20);
    edges = collect(-5:0.1:5)
    centers = collect(edges[1:end-1] .+0.05)
    histvals = [exp(-((c-x0)/s0)^2) for c=centers]
    data_tuple = (edges, histvals)

    log_histogram(logger, "hist/cust", data_tuple, step=step)
    log_histogram(logger, "hist/cust", rand(100), step=step)
end


text:
"""
---------------------------------------------------
Types and Constructors
---------------------------------------------------
"""

mutable struct HIGH_RECONNAISSANCE_SAMPLER <: SAMPLER
	z::Sampleable
	vx::Sampleable
	radius::Sampleable
	arc_length::Sampleable
end

function high_reconnaissance_sampler(;z = Normal(500,10),
						vx = Uniform(30,45),
						radius = Uniform(200,400),
						arc_length = Uniform(90,270))
	return HIGH_RECONNAISSANCE_SAMPLER(z, vx, radius, arc_length)
end

mutable struct HIGH_RECONNAISSANCE <: UAM_TRAJECTORY
	z::Float64
	vx::Float64
	radius::Float64
	arc_length::Float64
	sampler::SAMPLER
	dt::Float64
	vz_max::Float64
	az_max::Float64
	ax_max::Float64
	p::Array{Float64,2}
	v::Array{Float64,2}
end

function high_reconnaissance(;z = 0.0,
						vx = 0.0,
						radius = 0.0,
						arc_length = 0.0,
						sampler = high_reconnaissance_sampler(),
						dt = 1.0,
						vz_max = 550fpm2fps, # This doesn't actually get used
						az_max = 0.3g_ft, # This doesn't actually get used
						ax_max = 0.1g, # This doesn't actually get used
						p = zeros(1,3),
						v = zeros(1,3))
	return HIGH_RECONNAISSANCE(z, vx, radius, arc_length, sampler, dt,
								vz_max, az_max, ax_max, p, v)
end

"""
---------------------------------------------------
Functions
---------------------------------------------------
"""

function solve_trajectory!(τ::HIGH_RECONNAISSANCE)
	# Get the circular portion first
	θ̇ = rad2deg(τ.vx/τ.radius)
	arc_time = τ.arc_length/θ̇
	arc_steps = convert(Int64, floor(arc_time/τ.dt))
	θ = zeros(arc_steps)
	for i = 2:arc_steps
		θ[i] = θ[i-1] + θ̇*τ.dt
	end

	x = τ.radius*cosd.(θ)
	y = τ.radius*sind.(θ)
	z = τ.z*ones(arc_steps)

	p = hcat(x, y, z)

	N = size(p,1)
	D = zeros(N-1,N)
	for i = 1:(N-1)
	    D[i,i] = -1
	    D[i,i+1] = 1
	end
	D = D./τ.dt

	v = D*p
	v = vcat(v, v[end,:]')

	τ.p = copy(p)
	τ.v = copy(v)

	return true # Because others return if they are optimal
end

max_stars_repo_name: Airspace-Encounter-Models/em-model-uam

max_issues_repo_name: Airspace-Encounter-Models/em-model-uam

max_forks_repo_name: Airspace-Encounter-Models/em-model-uam


text:
"""
when Flux is used, include this file will automatically add functor to existing
kernels in Stheno.
"""

using .Flux
using .Flux: @functor

kernels = [:EQ, :PerEQ, :Exp, :Matern12, :Matern32, :Matern52, :RQ, :Cosine, :Linear, :Poly, :GammaExp, :Wiener,
    :WienerVelocity, :Sum, :Product, :Scaled, :Stretched]

for k in kernels
    @eval @functor $k
end


text:
# Automatically generated using Clang.jl

# const CIMGUI_API = EXTERN

struct ImVec2_Simple
    x::Cfloat
    y::Cfloat
end

struct ImVec4_Simple
    x::Cfloat
    y::Cfloat
    z::Cfloat
    w::Cfloat
end

struct ImColor_Simple
    Value::ImVec4_Simple
end

const ImGuiID = UInt32

struct ImGuiStoragePair
    key::ImGuiID
end

struct ImGuiTextRange
    b::Cstring
    e::Cstring
end

struct ImVec2
    x::Cfloat
    y::Cfloat
end

struct ImVector_float
    Size::Cint
    Capacity::Cint
    Data::Ptr{Cfloat}
end

const ImWchar = UInt16

struct ImVector_ImWchar
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImWchar}
end

struct ImFontGlyph
    Codepoint::ImWchar
    AdvanceX::Cfloat
    X0::Cfloat
    Y0::Cfloat
    X1::Cfloat
    Y1::Cfloat
    U0::Cfloat
    V0::Cfloat
    U1::Cfloat
    V1::Cfloat
end

struct ImVector_ImFontGlyph
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImFontGlyph}
end

const ImFontAtlasFlags = Cint
const ImTextureID = Ptr{Cvoid}

struct ImVector_ImFontPtr{ImFont_}
    Size::Cint
    Capacity::Cint
    Data::Ptr{Ptr{ImFont_}}
end

struct ImVector_ImFontAtlasCustomRect{_ImFontAtlasCustomRect}
    Size::Cint
    Capacity::Cint
    Data::Ptr{_ImFontAtlasCustomRect}
end

struct ImFontConfig{ImFont_}
    FontData::Ptr{Cvoid}
    FontDataSize::Cint
    FontDataOwnedByAtlas::Bool
    FontNo::Cint
    SizePixels::Cfloat
    OversampleH::Cint
    OversampleV::Cint
    PixelSnapH::Bool
    GlyphExtraSpacing::ImVec2
    GlyphOffset::ImVec2
    GlyphRanges::Ptr{ImWchar}
    GlyphMinAdvanceX::Cfloat
    GlyphMaxAdvanceX::Cfloat
    MergeMode::Bool
    RasterizerFlags::UInt32
    RasterizerMultiply::Cfloat
    EllipsisChar::ImWchar
    Name::NTuple{40, UInt8}
    DstFont::Ptr{ImFont_}
end

struct ImVector_ImFontConfig
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImFontConfig}
end

struct ImFontAtlas
    Locked::Bool
    Flags::ImFontAtlasFlags
    TexID::ImTextureID
    TexDesiredWidth::Cint
    TexGlyphPadding::Cint
    TexPixelsAlpha8::Ptr{Cuchar}
    TexPixelsRGBA32::Ptr{UInt32}
    TexWidth::Cint
    TexHeight::Cint
    TexUvScale::ImVec2
    TexUvWhitePixel::ImVec2
    Fonts::ImVector_ImFontPtr
    CustomRects::ImVector_ImFontAtlasCustomRect
    ConfigData::ImVector_ImFontConfig
    CustomRectIds::NTuple{1, Cint}
end

struct ImFont
    IndexAdvanceX::ImVector_float
    FallbackAdvanceX::Cfloat
    FontSize::Cfloat
    IndexLookup::ImVector_ImWchar
    Glyphs::ImVector_ImFontGlyph
    FallbackGlyph::Ptr{ImFontGlyph}
    DisplayOffset::ImVec2
    ContainerAtlas::Ptr{ImFontAtlas}
    ConfigData::Ptr{ImFontConfig}
    ConfigDataCount::Int16
    FallbackChar::ImWchar
    EllipsisChar::ImWchar
    Scale::Cfloat
    Ascent::Cfloat
    Descent::Cfloat
    MetricsTotalSurface::Cint
    DirtyLookupTables::Bool
end

struct ImFontAtlasCustomRect
    ID::UInt32
    Width::UInt16
    Height::UInt16
    X::UInt16
    Y::UInt16
    GlyphAdvanceX::Cfloat
    GlyphOffset::ImVec2
    Font::Ptr{ImFont}
end

struct ImVec4
    x::Cfloat
    y::Cfloat
    z::Cfloat
    w::Cfloat
end

struct ImVector_ImGuiTextRange
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImGuiTextRange}
end

struct ImGuiTextFilter
    InputBuf::NTuple{256, UInt8}
    Filters::ImVector_ImGuiTextRange
    CountGrep::Cint
end

struct ImVector_char
    Size::Cint
    Capacity::Cint
    Data::Cstring
end

struct ImGuiTextBuffer
    Buf::ImVector_char
end

const ImGuiDir = Cint

struct ImGuiStyle
    Alpha::Cfloat
    WindowPadding::ImVec2
    WindowRounding::Cfloat
    WindowBorderSize::Cfloat
    WindowMinSize::ImVec2
    WindowTitleAlign::ImVec2
    WindowMenuButtonPosition::ImGuiDir
    ChildRounding::Cfloat
    ChildBorderSize::Cfloat
    PopupRounding::Cfloat
    PopupBorderSize::Cfloat
    FramePadding::ImVec2
    FrameRounding::Cfloat
    FrameBorderSize::Cfloat
    ItemSpacing::ImVec2
    ItemInnerSpacing::ImVec2
    TouchExtraPadding::ImVec2
    IndentSpacing::Cfloat
    ColumnsMinSpacing::Cfloat
    ScrollbarSize::Cfloat
    ScrollbarRounding::Cfloat
    GrabMinSize::Cfloat
    GrabRounding::Cfloat
    TabRounding::Cfloat
    TabBorderSize::Cfloat
    ColorButtonPosition::ImGuiDir
    ButtonTextAlign::ImVec2
    SelectableTextAlign::ImVec2
    DisplayWindowPadding::ImVec2
    DisplaySafeAreaPadding::ImVec2
    MouseCursorScale::Cfloat
    AntiAliasedLines::Bool
    AntiAliasedFill::Bool
    CurveTessellationTol::Cfloat
    Colors::NTuple{48, ImVec4}
end

struct ImVector_ImGuiStoragePair
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImGuiStoragePair}
end

struct ImGuiStorage
    Data::ImVector_ImGuiStoragePair
end

struct ImGuiSizeCallbackData
    UserData::Ptr{Cvoid}
    Pos::ImVec2
    CurrentSize::ImVec2
    DesiredSize::ImVec2
end

struct ImGuiPayload
    Data::Ptr{Cvoid}
    DataSize::Cint
    SourceId::ImGuiID
    SourceParentId::ImGuiID
    DataFrameCount::Cint
    DataType::NTuple{33, UInt8}
    Preview::Bool
    Delivery::Bool
end

struct ImGuiOnceUponAFrame
    RefFrame::Cint
end

struct ImGuiListClipper
    StartPosY::Cfloat
    ItemsHeight::Cfloat
    ItemsCount::Cint
    StepNo::Cint
    DisplayStart::Cint
    DisplayEnd::Cint
end

const ImGuiInputTextFlags = Cint
const ImGuiKey = Cint

struct ImGuiInputTextCallbackData
    EventFlag::ImGuiInputTextFlags
    Flags::ImGuiInputTextFlags
    UserData::Ptr{Cvoid}
    EventChar::ImWchar
    EventKey::ImGuiKey
    Buf::Cstring
    BufTextLen::Cint
    BufSize::Cint
    BufDirty::Bool
    CursorPos::Cint
    SelectionStart::Cint
    SelectionEnd::Cint
end

const ImGuiConfigFlags = Cint
const ImGuiBackendFlags = Cint

struct ImGuiIO
    ConfigFlags::ImGuiConfigFlags
    BackendFlags::ImGuiBackendFlags
    DisplaySize::ImVec2
    DeltaTime::Cfloat
    IniSavingRate::Cfloat
    IniFilename::Cstring
    LogFilename::Cstring
    MouseDoubleClickTime::Cfloat
    MouseDoubleClickMaxDist::Cfloat
    MouseDragThreshold::Cfloat
    KeyMap::NTuple{22, Cint}
    KeyRepeatDelay::Cfloat
    KeyRepeatRate::Cfloat
    UserData::Ptr{Cvoid}
    Fonts::Ptr{ImFontAtlas}
    FontGlobalScale::Cfloat
    FontAllowUserScaling::Bool
    FontDefault::Ptr{ImFont}
    DisplayFramebufferScale::ImVec2
    MouseDrawCursor::Bool
    ConfigMacOSXBehaviors::Bool
    ConfigInputTextCursorBlink::Bool
    ConfigWindowsResizeFromEdges::Bool
    ConfigWindowsMoveFromTitleBarOnly::Bool
    ConfigWindowsMemoryCompactTimer::Cfloat
    BackendPlatformName::Cstring
    BackendRendererName::Cstring
    BackendPlatformUserData::Ptr{Cvoid}
    BackendRendererUserData::Ptr{Cvoid}
    BackendLanguageUserData::Ptr{Cvoid}
    GetClipboardTextFn::Ptr{Cvoid}
    SetClipboardTextFn::Ptr{Cvoid}
    ClipboardUserData::Ptr{Cvoid}
    ImeSetInputScreenPosFn::Ptr{Cvoid}
    ImeWindowHandle::Ptr{Cvoid}
    RenderDrawListsFnUnused::Ptr{Cvoid}
    MousePos::ImVec2
    MouseDown::NTuple{5, Bool}
    MouseWheel::Cfloat
    MouseWheelH::Cfloat
    KeyCtrl::Bool
    KeyShift::Bool
    KeyAlt::Bool
    KeySuper::Bool
    KeysDown::NTuple{512, Bool}
    NavInputs::NTuple{21, Cfloat}
    WantCaptureMouse::Bool
    WantCaptureKeyboard::Bool
    WantTextInput::Bool
    WantSetMousePos::Bool
    WantSaveIniSettings::Bool
    NavActive::Bool
    NavVisible::Bool
    Framerate::Cfloat
    MetricsRenderVertices::Cint
    MetricsRenderIndices::Cint
    MetricsRenderWindows::Cint
    MetricsActiveWindows::Cint
    MetricsActiveAllocations::Cint
    MouseDelta::ImVec2
    MousePosPrev::ImVec2
    MouseClickedPos::NTuple{5, ImVec2}
    MouseClickedTime::NTuple{5, Cdouble}
    MouseClicked::NTuple{5, Bool}
    MouseDoubleClicked::NTuple{5, Bool}
    MouseReleased::NTuple{5, Bool}
    MouseDownOwned::NTuple{5, Bool}
    MouseDownWasDoubleClick::NTuple{5, Bool}
    MouseDownDuration::NTuple{5, Cfloat}
    MouseDownDurationPrev::NTuple{5, Cfloat}
    MouseDragMaxDistanceAbs::NTuple{5, ImVec2}
    MouseDragMaxDistanceSqr::NTuple{5, Cfloat}
    KeysDownDuration::NTuple{512, Cfloat}
    KeysDownDurationPrev::NTuple{512, Cfloat}
    NavInputsDownDuration::NTuple{21, Cfloat}
    NavInputsDownDurationPrev::NTuple{21, Cfloat}
    InputQueueCharacters::ImVector_ImWchar
end

const ImGuiContext = Cvoid

struct ImColor
    Value::ImVec4
end

const ImU32 = UInt32

struct ImVector_ImU32
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImU32}
end

struct ImFontGlyphRangesBuilder
    UsedChars::ImVector_ImU32
end

struct ImDrawVert
    pos::ImVec2
    uv::ImVec2
    col::ImU32
end

const ImDrawCallback = Ptr{Cvoid}

struct ImDrawCmd
    ElemCount::UInt32
    ClipRect::ImVec4
    TextureId::ImTextureID
    VtxOffset::UInt32
    IdxOffset::UInt32
    UserCallback::ImDrawCallback
    UserCallbackData::Ptr{Cvoid}
end

struct ImVector_ImDrawCmd
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImDrawCmd}
end

const ImDrawIdx = UInt16

struct ImVector_ImDrawIdx
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImDrawIdx}
end

struct ImDrawChannel
    _CmdBuffer::ImVector_ImDrawCmd
    _IdxBuffer::ImVector_ImDrawIdx
end

struct ImVector_ImDrawChannel
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImDrawChannel}
end

struct ImDrawListSplitter
    _Current::Cint
    _Count::Cint
    _Channels::ImVector_ImDrawChannel
end

const ImDrawListSharedData = Cvoid

struct ImVector_ImDrawVert
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImDrawVert}
end

const ImDrawListFlags = Cint

struct ImVector_ImVec4
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImVec4}
end

struct ImVector_ImTextureID
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImTextureID}
end

struct ImVector_ImVec2
    Size::Cint
    Capacity::Cint
    Data::Ptr{ImVec2}
end

struct ImDrawList
    CmdBuffer::ImVector_ImDrawCmd
    IdxBuffer::ImVector_ImDrawIdx
    VtxBuffer::ImVector_ImDrawVert
    Flags::ImDrawListFlags
    _Data::Ptr{ImDrawListSharedData}
    _OwnerName::Cstring
    _VtxCurrentOffset::UInt32
    _VtxCurrentIdx::UInt32
    _VtxWritePtr::Ptr{ImDrawVert}
    _IdxWritePtr::Ptr{ImDrawIdx}
    _ClipRectStack::ImVector_ImVec4
    _TextureIdStack::ImVector_ImTextureID
    _Path::ImVector_ImVec2
    _Splitter::ImDrawListSplitter
end

struct ImDrawData
    Valid::Bool
    CmdLists::Ptr{Ptr{ImDrawList}}
    CmdListsCount::Cint
    TotalIdxCount::Cint
    TotalVtxCount::Cint
    DisplayPos::ImVec2
    DisplaySize::ImVec2
    FramebufferScale::ImVec2
end

const ImGuiCol = Cint
const ImGuiCond = Cint
const ImGuiDataType = Cint
const ImGuiNavInput = Cint
const ImGuiMouseCursor = Cint
const ImGuiStyleVar = Cint
const ImDrawCornerFlags = Cint
const ImGuiColorEditFlags = Cint
const ImGuiComboFlags = Cint
const ImGuiDragDropFlags = Cint
const ImGuiFocusedFlags = Cint
const ImGuiHoveredFlags = Cint
const ImGuiSelectableFlags = Cint
const ImGuiTabBarFlags = Cint
const ImGuiTabItemFlags = Cint
const ImGuiTreeNodeFlags = Cint
const ImGuiWindowFlags = Cint
const ImGuiInputTextCallback = Ptr{Cvoid}
const ImGuiSizeCallback = Ptr{Cvoid}
const ImS8 = UInt8
const ImU8 = Cuchar
const ImS16 = Int16
const ImU16 = UInt16
const ImS32 = Cint
const ImS64 = Int64
const ImU64 = UInt64

struct ImVector
    Size::Cint
    Capacity::Cint
    Data::Ptr{Cvoid}
end

@cenum ImGuiWindowFlags_::UInt32 begin
    ImGuiWindowFlags_None = 0
    ImGuiWindowFlags_NoTitleBar = 1
    ImGuiWindowFlags_NoResize = 2
    ImGuiWindowFlags_NoMove = 4
    ImGuiWindowFlags_NoScrollbar = 8
    ImGuiWindowFlags_NoScrollWithMouse = 16
    ImGuiWindowFlags_NoCollapse = 32
    ImGuiWindowFlags_AlwaysAutoResize = 64
    ImGuiWindowFlags_NoBackground = 128
    ImGuiWindowFlags_NoSavedSettings = 256
    ImGuiWindowFlags_NoMouseInputs = 512
    ImGuiWindowFlags_MenuBar = 1024
    ImGuiWindowFlags_HorizontalScrollbar = 2048
    ImGuiWindowFlags_NoFocusOnAppearing = 4096
    ImGuiWindowFlags_NoBringToFrontOnFocus = 8192
    ImGuiWindowFlags_AlwaysVerticalScrollbar = 16384
    ImGuiWindowFlags_AlwaysHorizontalScrollbar = 32768
    ImGuiWindowFlags_AlwaysUseWindowPadding = 65536
    ImGuiWindowFlags_NoNavInputs = 262144
    ImGuiWindowFlags_NoNavFocus = 524288
    ImGuiWindowFlags_UnsavedDocument = 1048576
    ImGuiWindowFlags_NoNav = 786432
    ImGuiWindowFlags_NoDecoration = 43
    ImGuiWindowFlags_NoInputs = 786944
    ImGuiWindowFlags_NavFlattened = 8388608
    ImGuiWindowFlags_ChildWindow = 16777216
    ImGuiWindowFlags_Tooltip = 33554432
    ImGuiWindowFlags_Popup = 67108864
    ImGuiWindowFlags_Modal = 134217728
    ImGuiWindowFlags_ChildMenu = 268435456
end

@cenum ImGuiInputTextFlags_::UInt32 begin
    ImGuiInputTextFlags_None = 0
    ImGuiInputTextFlags_CharsDecimal = 1
    ImGuiInputTextFlags_CharsHexadecimal = 2
    ImGuiInputTextFlags_CharsUppercase = 4
    ImGuiInputTextFlags_CharsNoBlank = 8
    ImGuiInputTextFlags_AutoSelectAll = 16
    ImGuiInputTextFlags_EnterReturnsTrue = 32
    ImGuiInputTextFlags_CallbackCompletion = 64
    ImGuiInputTextFlags_CallbackHistory = 128
    ImGuiInputTextFlags_CallbackAlways = 256
    ImGuiInputTextFlags_CallbackCharFilter = 512
    ImGuiInputTextFlags_AllowTabInput = 1024
    ImGuiInputTextFlags_CtrlEnterForNewLine = 2048
    ImGuiInputTextFlags_NoHorizontalScroll = 4096
    ImGuiInputTextFlags_AlwaysInsertMode = 8192
    ImGuiInputTextFlags_ReadOnly = 16384
    ImGuiInputTextFlags_Password = 32768
    ImGuiInputTextFlags_NoUndoRedo = 65536
    ImGuiInputTextFlags_CharsScientific = 131072
    ImGuiInputTextFlags_CallbackResize = 262144
    ImGuiInputTextFlags_Multiline = 1048576
    ImGuiInputTextFlags_NoMarkEdited = 2097152
end

@cenum ImGuiTreeNodeFlags_::UInt32 begin
    ImGuiTreeNodeFlags_None = 0
    ImGuiTreeNodeFlags_Selected = 1
    ImGuiTreeNodeFlags_Framed = 2
    ImGuiTreeNodeFlags_AllowItemOverlap = 4
    ImGuiTreeNodeFlags_NoTreePushOnOpen = 8
    ImGuiTreeNodeFlags_NoAutoOpenOnLog = 16
    ImGuiTreeNodeFlags_DefaultOpen = 32
    ImGuiTreeNodeFlags_OpenOnDoubleClick = 64
    ImGuiTreeNodeFlags_OpenOnArrow = 128
    ImGuiTreeNodeFlags_Leaf = 256
    ImGuiTreeNodeFlags_Bullet = 512
    ImGuiTreeNodeFlags_FramePadding = 1024
    ImGuiTreeNodeFlags_SpanAvailWidth = 2048
    ImGuiTreeNodeFlags_SpanFullWidth = 4096
    ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 8192
    ImGuiTreeNodeFlags_CollapsingHeader = 26
end

@cenum ImGuiSelectableFlags_::UInt32 begin
    ImGuiSelectableFlags_None = 0
    ImGuiSelectableFlags_DontClosePopups = 1
    ImGuiSelectableFlags_SpanAllColumns = 2
    ImGuiSelectableFlags_AllowDoubleClick = 4
    ImGuiSelectableFlags_Disabled = 8
    ImGuiSelectableFlags_AllowItemOverlap = 16
end

@cenum ImGuiComboFlags_::UInt32 begin
    ImGuiComboFlags_None = 0
    ImGuiComboFlags_PopupAlignLeft = 1
    ImGuiComboFlags_HeightSmall = 2
    ImGuiComboFlags_HeightRegular = 4
    ImGuiComboFlags_HeightLarge = 8
    ImGuiComboFlags_HeightLargest = 16
    ImGuiComboFlags_NoArrowButton = 32
    ImGuiComboFlags_NoPreview = 64
    ImGuiComboFlags_HeightMask_ = 30
end

@cenum ImGuiTabBarFlags_::UInt32 begin
    ImGuiTabBarFlags_None = 0
    ImGuiTabBarFlags_Reorderable = 1
    ImGuiTabBarFlags_AutoSelectNewTabs = 2
    ImGuiTabBarFlags_TabListPopupButton = 4
    ImGuiTabBarFlags_NoCloseWithMiddleMouseButton = 8
    ImGuiTabBarFlags_NoTabListScrollingButtons = 16
    ImGuiTabBarFlags_NoTooltip = 32
    ImGuiTabBarFlags_FittingPolicyResizeDown = 64
    ImGuiTabBarFlags_FittingPolicyScroll = 128
    ImGuiTabBarFlags_FittingPolicyMask_ = 192
    ImGuiTabBarFlags_FittingPolicyDefault_ = 64
end

@cenum ImGuiTabItemFlags_::UInt32 begin
    ImGuiTabItemFlags_None = 0
    ImGuiTabItemFlags_UnsavedDocument = 1
    ImGuiTabItemFlags_SetSelected = 2
    ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 4
    ImGuiTabItemFlags_NoPushId = 8
end

@cenum ImGuiFocusedFlags_::UInt32 begin
    ImGuiFocusedFlags_None = 0
    ImGuiFocusedFlags_ChildWindows = 1
    ImGuiFocusedFlags_RootWindow = 2
    ImGuiFocusedFlags_AnyWindow = 4
    ImGuiFocusedFlags_RootAndChildWindows = 3
end

@cenum ImGuiHoveredFlags_::UInt32 begin
    ImGuiHoveredFlags_None = 0
    ImGuiHoveredFlags_ChildWindows = 1
    ImGuiHoveredFlags_RootWindow = 2
    ImGuiHoveredFlags_AnyWindow = 4
    ImGuiHoveredFlags_AllowWhenBlockedByPopup = 8
    ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 32
    ImGuiHoveredFlags_AllowWhenOverlapped = 64
    ImGuiHoveredFlags_AllowWhenDisabled = 128
    ImGuiHoveredFlags_RectOnly = 104
    ImGuiHoveredFlags_RootAndChildWindows = 3
end

@cenum ImGuiDragDropFlags_::UInt32 begin
    ImGuiDragDropFlags_None = 0
    ImGuiDragDropFlags_SourceNoPreviewTooltip = 1
    ImGuiDragDropFlags_SourceNoDisableHover = 2
    ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 4
    ImGuiDragDropFlags_SourceAllowNullID = 8
    ImGuiDragDropFlags_SourceExtern = 16
    ImGuiDragDropFlags_SourceAutoExpirePayload = 32
    ImGuiDragDropFlags_AcceptBeforeDelivery = 1024
    ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 2048
    ImGuiDragDropFlags_AcceptNoPreviewTooltip = 4096
    ImGuiDragDropFlags_AcceptPeekOnly = 3072
end

@cenum ImGuiDataType_::UInt32 begin
    ImGuiDataType_S8 = 0
    ImGuiDataType_U8 = 1
    ImGuiDataType_S16 = 2
    ImGuiDataType_U16 = 3
    ImGuiDataType_S32 = 4
    ImGuiDataType_U32 = 5
    ImGuiDataType_S64 = 6
    ImGuiDataType_U64 = 7
    ImGuiDataType_Float = 8
    ImGuiDataType_Double = 9
    ImGuiDataType_COUNT = 10
end

@cenum ImGuiDir_::Int32 begin
    ImGuiDir_None = -1
    ImGuiDir_Left = 0
    ImGuiDir_Right = 1
    ImGuiDir_Up = 2
    ImGuiDir_Down = 3
    ImGuiDir_COUNT = 4
end

@cenum ImGuiKey_::UInt32 begin
    ImGuiKey_Tab = 0
    ImGuiKey_LeftArrow = 1
    ImGuiKey_RightArrow = 2
    ImGuiKey_UpArrow = 3
    ImGuiKey_DownArrow = 4
    ImGuiKey_PageUp = 5
    ImGuiKey_PageDown = 6
    ImGuiKey_Home = 7
    ImGuiKey_End = 8
    ImGuiKey_Insert = 9
    ImGuiKey_Delete = 10
    ImGuiKey_Backspace = 11
    ImGuiKey_Space = 12
    ImGuiKey_Enter = 13
    ImGuiKey_Escape = 14
    ImGuiKey_KeyPadEnter = 15
    ImGuiKey_A = 16
    ImGuiKey_C = 17
    ImGuiKey_V = 18
    ImGuiKey_X = 19
    ImGuiKey_Y = 20
    ImGuiKey_Z = 21
    ImGuiKey_COUNT = 22
end

@cenum ImGuiNavInput_::UInt32 begin
    ImGuiNavInput_Activate = 0
    ImGuiNavInput_Cancel = 1
    ImGuiNavInput_Input = 2
    ImGuiNavInput_Menu = 3
    ImGuiNavInput_DpadLeft = 4
    ImGuiNavInput_DpadRight = 5
    ImGuiNavInput_DpadUp = 6
    ImGuiNavInput_DpadDown = 7
    ImGuiNavInput_LStickLeft = 8
    ImGuiNavInput_LStickRight = 9
    ImGuiNavInput_LStickUp = 10
    ImGuiNavInput_LStickDown = 11
    ImGuiNavInput_FocusPrev = 12
    ImGuiNavInput_FocusNext = 13
    ImGuiNavInput_TweakSlow = 14
    ImGuiNavInput_TweakFast = 15
    ImGuiNavInput_KeyMenu_ = 16
    ImGuiNavInput_KeyLeft_ = 17
    ImGuiNavInput_KeyRight_ = 18
    ImGuiNavInput_KeyUp_ = 19
    ImGuiNavInput_KeyDown_ = 20
    ImGuiNavInput_COUNT = 21
    ImGuiNavInput_InternalStart_ = 16
end

@cenum ImGuiConfigFlags_::UInt32 begin
    ImGuiConfigFlags_None = 0
    ImGuiConfigFlags_NavEnableKeyboard = 1
    ImGuiConfigFlags_NavEnableGamepad = 2
    ImGuiConfigFlags_NavEnableSetMousePos = 4
    ImGuiConfigFlags_NavNoCaptureKeyboard = 8
    ImGuiConfigFlags_NoMouse = 16
    ImGuiConfigFlags_NoMouseCursorChange = 32
    ImGuiConfigFlags_IsSRGB = 1048576
    ImGuiConfigFlags_IsTouchScreen = 2097152
end

@cenum ImGuiBackendFlags_::UInt32 begin
    ImGuiBackendFlags_None = 0
    ImGuiBackendFlags_HasGamepad = 1
    ImGuiBackendFlags_HasMouseCursors = 2
    ImGuiBackendFlags_HasSetMousePos = 4
    ImGuiBackendFlags_RendererHasVtxOffset = 8
end

@cenum ImGuiCol_::UInt32 begin
    ImGuiCol_Text = 0
    ImGuiCol_TextDisabled = 1
    ImGuiCol_WindowBg = 2
    ImGuiCol_ChildBg = 3
    ImGuiCol_PopupBg = 4
    ImGuiCol_Border = 5
    ImGuiCol_BorderShadow = 6
    ImGuiCol_FrameBg = 7
    ImGuiCol_FrameBgHovered = 8
    ImGuiCol_FrameBgActive = 9
    ImGuiCol_TitleBg = 10
    ImGuiCol_TitleBgActive = 11
    ImGuiCol_TitleBgCollapsed = 12
    ImGuiCol_MenuBarBg = 13
    ImGuiCol_ScrollbarBg = 14
    ImGuiCol_ScrollbarGrab = 15
    ImGuiCol_ScrollbarGrabHovered = 16
    ImGuiCol_ScrollbarGrabActive = 17
    ImGuiCol_CheckMark = 18
    ImGuiCol_SliderGrab = 19
    ImGuiCol_SliderGrabActive = 20
    ImGuiCol_Button = 21
    ImGuiCol_ButtonHovered = 22
    ImGuiCol_ButtonActive = 23
    ImGuiCol_Header = 24
    ImGuiCol_HeaderHovered = 25
    ImGuiCol_HeaderActive = 26
    ImGuiCol_Separator = 27
    ImGuiCol_SeparatorHovered = 28
    ImGuiCol_SeparatorActive = 29
    ImGuiCol_ResizeGrip = 30
    ImGuiCol_ResizeGripHovered = 31
    ImGuiCol_ResizeGripActive = 32
    ImGuiCol_Tab = 33
    ImGuiCol_TabHovered = 34
    ImGuiCol_TabActive = 35
    ImGuiCol_TabUnfocused = 36
    ImGuiCol_TabUnfocusedActive = 37
    ImGuiCol_PlotLines = 38
    ImGuiCol_PlotLinesHovered = 39
    ImGuiCol_PlotHistogram = 40
    ImGuiCol_PlotHistogramHovered = 41
    ImGuiCol_TextSelectedBg = 42
    ImGuiCol_DragDropTarget = 43
    ImGuiCol_NavHighlight = 44
    ImGuiCol_NavWindowingHighlight = 45
    ImGuiCol_NavWindowingDimBg = 46
    ImGuiCol_ModalWindowDimBg = 47
    ImGuiCol_COUNT = 48
end

@cenum ImGuiStyleVar_::UInt32 begin
    ImGuiStyleVar_Alpha = 0
    ImGuiStyleVar_WindowPadding = 1
    ImGuiStyleVar_WindowRounding = 2
    ImGuiStyleVar_WindowBorderSize = 3
    ImGuiStyleVar_WindowMinSize = 4
    ImGuiStyleVar_WindowTitleAlign = 5
    ImGuiStyleVar_ChildRounding = 6
    ImGuiStyleVar_ChildBorderSize = 7
    ImGuiStyleVar_PopupRounding = 8
    ImGuiStyleVar_PopupBorderSize = 9
    ImGuiStyleVar_FramePadding = 10
    ImGuiStyleVar_FrameRounding = 11
    ImGuiStyleVar_FrameBorderSize = 12
    ImGuiStyleVar_ItemSpacing = 13
    ImGuiStyleVar_ItemInnerSpacing = 14
    ImGuiStyleVar_IndentSpacing = 15
    ImGuiStyleVar_ScrollbarSize = 16
    ImGuiStyleVar_ScrollbarRounding = 17
    ImGuiStyleVar_GrabMinSize = 18
    ImGuiStyleVar_GrabRounding = 19
    ImGuiStyleVar_TabRounding = 20
    ImGuiStyleVar_ButtonTextAlign = 21
    ImGuiStyleVar_SelectableTextAlign = 22
    ImGuiStyleVar_COUNT = 23
end

@cenum ImGuiColorEditFlags_::UInt32 begin
    ImGuiColorEditFlags_None = 0
    ImGuiColorEditFlags_NoAlpha = 2
    ImGuiColorEditFlags_NoPicker = 4
    ImGuiColorEditFlags_NoOptions = 8
    ImGuiColorEditFlags_NoSmallPreview = 16
    ImGuiColorEditFlags_NoInputs = 32
    ImGuiColorEditFlags_NoTooltip = 64
    ImGuiColorEditFlags_NoLabel = 128
    ImGuiColorEditFlags_NoSidePreview = 256
    ImGuiColorEditFlags_NoDragDrop = 512
    ImGuiColorEditFlags_AlphaBar = 65536
    ImGuiColorEditFlags_AlphaPreview = 131072
    ImGuiColorEditFlags_AlphaPreviewHalf = 262144
    ImGuiColorEditFlags_HDR = 524288
    ImGuiColorEditFlags_DisplayRGB = 1048576
    ImGuiColorEditFlags_DisplayHSV = 2097152
    ImGuiColorEditFlags_DisplayHex = 4194304
    ImGuiColorEditFlags_Uint8 = 8388608
    ImGuiColorEditFlags_Float = 16777216
    ImGuiColorEditFlags_PickerHueBar = 33554432
    ImGuiColorEditFlags_PickerHueWheel = 67108864
    ImGuiColorEditFlags_InputRGB = 134217728
    ImGuiColorEditFlags_InputHSV = 268435456
    ImGuiColorEditFlags__OptionsDefault = 177209344
    ImGuiColorEditFlags__DisplayMask = 7340032
    ImGuiColorEditFlags__DataTypeMask = 25165824
    ImGuiColorEditFlags__PickerMask = 100663296
    ImGuiColorEditFlags__InputMask = 402653184
end

@cenum ImGuiMouseCursor_::Int32 begin
    ImGuiMouseCursor_None = -1
    ImGuiMouseCursor_Arrow = 0
    ImGuiMouseCursor_TextInput = 1
    ImGuiMouseCursor_ResizeAll = 2
    ImGuiMouseCursor_ResizeNS = 3
    ImGuiMouseCursor_ResizeEW = 4
    ImGuiMouseCursor_ResizeNESW = 5
    ImGuiMouseCursor_ResizeNWSE = 6
    ImGuiMouseCursor_Hand = 7
    ImGuiMouseCursor_COUNT = 8
end

@cenum ImGuiCond_::UInt32 begin
    ImGuiCond_Always = 1
    ImGuiCond_Once = 2
    ImGuiCond_FirstUseEver = 4
    ImGuiCond_Appearing = 8
end

@cenum ImDrawCornerFlags_::UInt32 begin
    ImDrawCornerFlags_None = 0
    ImDrawCornerFlags_TopLeft = 1
    ImDrawCornerFlags_TopRight = 2
    ImDrawCornerFlags_BotLeft = 4
    ImDrawCornerFlags_BotRight = 8
    ImDrawCornerFlags_Top = 3
    ImDrawCornerFlags_Bot = 12
    ImDrawCornerFlags_Left = 5
    ImDrawCornerFlags_Right = 10
    ImDrawCornerFlags_All = 15
end

@cenum ImDrawListFlags_::UInt32 begin
    ImDrawListFlags_None = 0
    ImDrawListFlags_AntiAliasedLines = 1
    ImDrawListFlags_AntiAliasedFill = 2
    ImDrawListFlags_AllowVtxOffset = 4
end

@cenum ImFontAtlasFlags_::UInt32 begin
    ImFontAtlasFlags_None = 0
    ImFontAtlasFlags_NoPowerOfTwoHeight = 1
    ImFontAtlasFlags_NoMouseCursors = 2
end


text:
# TODO allow the lower and upper bounds to be parameterized.
# use default values for the lower and upper bounds ? (0 and 1)

struct Beta <: Distribution{Float64} end

"""
    beta(alpha::Real, beta::Real)

Sample a `Float64` from a beta distribution.
"""
const beta = Beta()

function logpdf(::Beta, x::Real, alpha::Real, beta::Real)
    (alpha - 1) * log(x) + (beta - 1) * log1p(-x) - logbeta(alpha, beta)
end

function logpdf_grad(::Beta, x::Real, alpha::Real, beta::Real)
    if 0 <= x <= 1
        deriv_x = (alpha - 1) / x - (beta - 1) / (1 - x)
        deriv_alpha = log(x) - (digamma(alpha) - digamma(alpha + beta))
        deriv_beta = log1p(-x) - (digamma(beta) - digamma(alpha + beta))
    else
        error("x is outside of support: $x")
    end
    (deriv_x, deriv_alpha, deriv_beta)
end

function random(::Beta, alpha::Real, beta::Real)
    rand(Distributions.Beta(alpha, beta))
end
is_discrete(::Beta) = false

(::Beta)(alpha, beta) = random(Beta(), alpha, beta)

has_output_grad(::Beta) = true
has_argument_grads(::Beta) = (true, true)

export beta


text:
function _precompile_()
    ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
    Base.precompile(Tuple{typeof(RecipesBase.create_kw_body),Expr})
    Base.precompile(Tuple{typeof(RecipesBase.get_function_def),Expr,Array{Any,1}})
    Base.precompile(Tuple{typeof(map),Function,Array{AbstractLayout,1}})
    Base.precompile(Tuple{typeof(map),Function,Array{AbstractLayout,2}})
end

_precompile_()


text:
using Pkg; Pkg.activate("..")
using PlotAxes, VegaLite, AxisArrays

x = cumsum(randn(100))
vlplot_axes(x)

x = rand(100,100)
vlplot_axes(x)

x = rand(100,100,3)
vlplot_axes(x)

myexception = nothing
try
  using RCall
catch e
  global myexception
  myexception = e
end


text:
# Height of the screen
HEIGHT = 200
# Width of the screen
WIDTH = 400
# Global variables to store a range of colors.
# The Colors package is always imported into a game
colors = range(colorant"black", colorant"white")
current_color, color_state = iterate(colors)

# The draw function is called once per frame to render objects to the screen.
# In our game, we only define the `draw` function, it's called by the engine.
# Within the function, we draw the individual elements, in this case line, rectangles and circles
function draw()
    fill(current_color)
    draw(Line(50, 100, 350, 100), colorant"white")
    draw(Rect(50, 100, 20, 50), colorant"red", fill=true)
    draw(Rect(50, 100, 20, 50), colorant"white")
    draw(Circle(330, 80, 20), colorant"red", fill=true)
    draw(Circle(330, 80, 20), colorant"white")

    draw(Circle(0,0,50), colorant"red", fill=true)
    draw(Circle(WIDTH,HEIGHT,50), colorant"green", fill=true)

end

# The update function is called once per frame by the game engine, and should be used
# to change the game state. In this case, we iterate through the color range, and store
# the current color in a global variable. The global value is then used in the `draw`
# function to render the screen background
function update()
    global current_color
    global color_state
    i = iterate(colors, color_state)
    if !isnothing(i)
        current_color, color_state = i
    else
        reverse!(colors)
        current_color, color_state = iterate(colors)
    end
end


text:
module DataAndPlotting

using HDF5
using Plots		#; pyplot() - default backend is gr()

# Wave params x & y directions
const ki = 3
const kj = 3

# define 20x30 array - used for storing standing waves
const ni = 300
const nj = 200

export init
function init()
	arr = zeros(Float64, ni, nj)
	for j in 1:nj, i in 1:ni
		x = index2coord(i, ni)
		y = index2coord(j, nj)
		arr[i, j] = sin(2pi*ki*x) * sin(2pi*kj*y)
	end
	arr
end

# i ranges from 1 to ni
# i - 1 ranges from 0 to ni - 1
# x ranges from 0 to 1
function index2coord(i, ni)
	@assert ni > 1
	@assert 1 <= i <= ni
	(i - 1) / (ni - 1)
end

#write data to file
export output
function output(arr::Array{Float64,2}, filename::String)
	h5write(filename, "data",arr)
end

export input
function input(filename::String)
	arr = h5read(filename, "data") #, (1:ni, 1:nj))
end

#Create Plots
export makeplot
function makeplot(arr::Array{Float64,2}, filename::String)
	heatmap(arr, clim=(-1.0, +1.0), color=:viridis)
	savefig(filename)
end

end # module


text:
struct VX
    id::Int
end

@testset "Basic Operations" begin

    g = OptimizingIR.Graphs.DirectedGraph(VX)

    @test OptimizingIR.Graphs.ne(g) == 0
    @test OptimizingIR.Graphs.nv(g) == 0

    v1 = VX(1)
    v2 = VX(2)

    OptimizingIR.Graphs.add_vertex!(g, v1)
    @test !OptimizingIR.Graphs.has_edge(g, v1, v1)

    @test OptimizingIR.Graphs.ne(g) == 0
    @test OptimizingIR.Graphs.nv(g) == 1

    OptimizingIR.Graphs.add_edge!(g, v1, v1)
    @test OptimizingIR.Graphs.has_edge(g, v1, v1)
    @test OptimizingIR.Graphs.ne(g) == 1
    OptimizingIR.Graphs.remove_edge!(g, v1, v1)
    @test !OptimizingIR.Graphs.has_edge(g, v1, v1)
    @test OptimizingIR.Graphs.ne(g) == 0

    OptimizingIR.Graphs.add_vertex!(g, v2)
    @test OptimizingIR.Graphs.ne(g) == 0
    @test OptimizingIR.Graphs.nv(g) == 2

    OptimizingIR.Graphs.add_edge!(g, v1, v2)
    @test OptimizingIR.Graphs.has_edge(g, v1, v2)
    @test !OptimizingIR.Graphs.has_edge(g, v2, v1)
    @test OptimizingIR.Graphs.ne(g) == 1
    @test OptimizingIR.Graphs.nv(g) == 2

    OptimizingIR.Graphs.add_edge!(g, v2, v2)
    @test OptimizingIR.Graphs.has_edge(g, v2, v2)
    @test !OptimizingIR.Graphs.has_edge(g, v2, v1)
    @test OptimizingIR.Graphs.ne(g) == 2
    @test OptimizingIR.Graphs.nv(g) == 2

    println(g)
end

@testset "CFG Example" begin
    cfg = OptimizingIR.Graphs.DirectedGraph(VX)

    for i in 0:8
        OptimizingIR.Graphs.add_vertex!(cfg, VX(i))
    end

    OptimizingIR.Graphs.add_edge!(cfg, VX(0), VX(1))
    OptimizingIR.Graphs.add_edge!(cfg, VX(1), VX(2))
    OptimizingIR.Graphs.add_edge!(cfg, VX(1), VX(5))
    OptimizingIR.Graphs.add_edge!(cfg, VX(2), VX(3))
    OptimizingIR.Graphs.add_edge!(cfg, VX(3), VX(4))
    OptimizingIR.Graphs.add_edge!(cfg, VX(5), VX(6))
    OptimizingIR.Graphs.add_edge!(cfg, VX(5), VX(8))
    OptimizingIR.Graphs.add_edge!(cfg, VX(6), VX(7))
    OptimizingIR.Graphs.add_edge!(cfg, VX(8), VX(7))
    OptimizingIR.Graphs.add_edge!(cfg, VX(7), VX(3))
    OptimizingIR.Graphs.add_edge!(cfg, VX(3), VX(1))

    @test OptimizingIR.Graphs.ne(cfg) == 11
    @test OptimizingIR.Graphs.nv(cfg) == 9

    # successors
    @test collect(OptimizingIR.Graphs.each_successor(cfg, VX(0))) == [ VX(1) ]
    @test OptimizingIR.Graphs.successors(cfg, VX(1)) == Set([ VX(2), VX(5) ])
    @test OptimizingIR.Graphs.successors(cfg, VX(1)) == Set([ VX(5), VX(2) ])
    @test OptimizingIR.Graphs.successors(cfg, VX(2)) == Set([ VX(3) ])
    @test OptimizingIR.Graphs.successors(cfg, VX(3)) == Set([ VX(1), VX(4) ])
    @test OptimizingIR.Graphs.successors(cfg, VX(4)) == Set()
    @test OptimizingIR.Graphs.successors_count(cfg, VX(4)) == 0
    @test eltype(OptimizingIR.Graphs.successors(cfg, VX(4))) == VX
    @test OptimizingIR.Graphs.successors(cfg, VX(5)) == Set([ VX(6), VX(8) ])
    @test OptimizingIR.Graphs.successors(cfg, VX(6)) == Set([ VX(7) ])
    @test OptimizingIR.Graphs.successors(cfg, VX(8)) == Set([ VX(7) ])
    @test OptimizingIR.Graphs.successors(cfg, VX(7)) == Set([ VX(3) ])
    @test OptimizingIR.Graphs.successors_count(cfg, VX(7)) == 1

    # predecessors
    @test OptimizingIR.Graphs.predecessors(cfg, VX(0)) == Set()
    @test OptimizingIR.Graphs.predecessors_count(cfg, VX(0)) == 0
    @test eltype(OptimizingIR.Graphs.predecessors(cfg, VX(0))) == VX
    @test OptimizingIR.Graphs.predecessors(cfg, VX(1)) == Set([ VX(0), VX(3) ])
    @test OptimizingIR.Graphs.predecessors(cfg, VX(2)) == Set([ VX(1) ])
    @test OptimizingIR.Graphs.predecessors(cfg, VX(3)) == Set([ VX(2), VX(7) ])
    @test OptimizingIR.Graphs.predecessors(cfg, VX(4)) == Set([ VX(3) ])
    @test OptimizingIR.Graphs.predecessors(cfg, VX(5)) == Set([ VX(1) ])
    @test OptimizingIR.Graphs.predecessors(cfg, VX(6)) == Set([ VX(5) ])
    @test OptimizingIR.Graphs.predecessors(cfg, VX(7)) == Set([ VX(6), VX(8) ])
    @test OptimizingIR.Graphs.predecessors_count(cfg, VX(7)) == 2

    # BFS
    @test OptimizingIR.Graphs.reachable_vertices(cfg, VX(4), true) == Set([ VX(4) ])
    @test OptimizingIR.Graphs.reachable_vertices(cfg, VX(3), true) == Set([ VX(1), VX(2), VX(3), VX(4), VX(5), VX(6), VX(7), VX(8) ])
    @test OptimizingIR.Graphs.reachable_vertices(cfg, VX(1), false) == Set([ VX(0), VX(1), VX(2), VX(3), VX(5), VX(6), VX(7), VX(8) ])

    # dominance
    @test OptimizingIR.Graphs.dominator_sets(cfg) == [Set([1]), Set([2, 1]), Set([2, 3, 1]), Set([4, 2, 1]), Set([4, 2, 5, 1]), Set([2, 6, 1]), Set([7, 2, 6, 1]), Set([2, 8, 6, 1]), Set([9, 2, 6, 1])]
    @test OptimizingIR.Graphs.strict_dominator_sets(cfg) == [Set(), Set([1]), Set([2, 1]), Set([2, 1]), Set([4, 2, 1]), Set([2, 1]), Set([2, 6, 1]), Set([2, 6, 1]), Set([2, 6, 1])]
    @test OptimizingIR.Graphs.idominators(cfg) == [nothing, 1, 2, 2, 4, 2, 6, 6, 6]
    @test OptimizingIR.Graphs.dominance_frontiers(cfg) == [Set([]), Set([2]), Set([4]), Set([2]), Set([]), Set([4]), Set([8]), Set([4]), Set([8])]
end


text:
using PyPlot, JLD2, Polynomials, PyCall, GLMakie, Images
include("../utils/Simulation.jl")
include("../utils/plotting.jl")

n = (64, 64, 64)
K = zeros(Float32, n)
K[:,:,1:36] .= 15f0
K[:,:,37:38] .= 1f-3
K[:,:,39:end] .= 5000f0

#K = Float32.(imfilter(K, Kernel.gaussian((2,2,2))))

phi = 0.36f0*ones(Float32, n)

for i = 1:n[1]
    for j = 1:n[2]
        for k = 1:n[3]
            p = Polynomial([-0.0314^2*K[i,j,k],2*0.0314^2*K[i,j,k],-0.0314^2*K[i,j,k],1.527^2])
            phi[i,j,k] = minimum(real(roots(p)[findall(real(roots(p)).== roots(p))]))
        end
    end
end

d = (100f0, 100f0, 24f0)
qinj = (d[1]*n[1]/2, d[2]*n[2]/2, d[3]*n[3]+(341-256)*6f0-500f0)
qrate = 7
time = 80
nt = 10

sat, p = TwoPhase(K, phi, qinj, qrate, d, time, nt; o=(0f0,0f0,(341-256)*6f0))

figure();imshow(K[:,32,:]')
figure();imshow(sat[end][:,32,:]')

#plot_3D(reverse(sat[end],dims=3))
#plot_3D(reverse(K,dims=3))
#plot_3D(reverse(phi,dims=3))

max_stars_repo_name: slimgroup/TwoPhaseSpeedTest

max_issues_repo_name: slimgroup/TwoPhaseSpeedTest

max_forks_repo_name: slimgroup/TwoPhaseSpeedTest


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

using Markdown
using InteractiveUtils

# ╔═╡ c9f9318a-1e89-11eb-2939-f3a5f1289a12
begin
	import Pkg; Pkg.add("ForwardDiff")
	Pkg.add("Plots")
	using ForwardDiff
	using Plots
end

# ╔═╡ 652e2558-1e7a-11eb-2483-cb1203507751
begin
	using LinearAlgebra

	using InstantiateFromURL

end

# ╔═╡ e30d5e5c-1e7b-11eb-0173-5dbf06d875bb
md"""
# Introductory Examples
### Solutions to the Exercise"""

# ╔═╡ 02f30026-1e7c-11eb-1bdf-713cc1950a22
md"""
##### `Exercise 1 - 4 are quite naive and will only help you to get familiarity with the platform` """

# ╔═╡ c0b1a1c0-1e8e-11eb-11e4-9187b5708dad
html"""

"""

# ╔═╡ 0297fd2c-1e7c-11eb-20de-ed44583cc810
md"""
##### Exercise 5
Simulate and plot the correlated time series

xt+1 = αxt + ϵt+1 wherex0 =0 and t= 0,…,n.
The sequence of shocks {ϵt} is assumed to be iid and standard normal.
Set n=200 and α=0.9."""

# ╔═╡ c5a9b326-1e7c-11eb-043e-6b700836e7df
begin
	path=accumulate(1:200;init=0) do old,i
		old*0.9 +randn()
	end
	plot(path,legend=false)
end

# ╔═╡ 79411808-1e7e-11eb-1073-d9d8e2b1a662
html"""

"""

# ╔═╡ 55e7aa80-1e7d-11eb-3447-810cb162aa9b
md"""
##### Exercise 6
Plot three simulated time series, one for each of the cases α=0, α=0.8 and α=0.98.

(The figure will illustrate how time series with the same one-step-ahead conditional volatilities, as these three processes have, can have very different unconditional volatilities)"""

# ╔═╡ 96c557f0-1e7d-11eb-0577-1bef484e817a
let p=plot()
	for α in [0,0.8,0.98]
		pa=accumulate(1:200;init=1) do old,i
			old*α +randn()
		end
		plot!(p,pa,label="α = $α")
	end
	p
end

# ╔═╡ 9438bd3c-1e7e-11eb-038d-c759ea6cf550
html"""

"""

# ╔═╡ b83ea3d6-1e7e-11eb-3c70-f5e2349bd425
md"""
##### Exercise 7
*This exercise is more challenging.*

Take a random walk, starting from x0=1
xt+1 = αxt + σϵt+1 where x0=1 and t= 0,…,tmax

* Furthermore, assume that the xtmax=0 (i.e. at tmax, the value drops to zero, regardless of its current state).
* The sequence of shocks {ϵt} is assumed to be iid and standard normal.

* For a given path {xt} define a first-passage time as Ta=min{t|xt≤a}, where by the assumption of the process Ta≤tmax.
Start with σ=0.2,α=1.0.
calculate the first-passage time, T0, for 100 simulated random walks – to a tmax=200 and plot a histogram
plot the sample mean of T0 from the simulation for α∈{0.8,1.0,1.2}"""

# ╔═╡ ae782114-1e7f-11eb-31bb-9f1b009f6853
let left= plot(), right=plot(), σ=0.2
	bigg=[]
	for j in [0.8,1.0,1.2]
		result_=Vector{}()
		for i ∈ 1:100
			pathing=accumulate(1:200;init=1) do old, i
				j*old + σ*randn()
			end
			push!(result_,findfirst(x->x<0.0,pathing))
		end
		push!(bigg,replace(result_,nothing=>200))
	end
	left=bar(bigg[2],bins=:scott,legend=false)
	right=bar(sum.(bigg)./100,bins=:scott,label=[0.8,1.0,1.2])
	plot(left,right)
end

# ╔═╡ a56d8f26-1e89-11eb-2c21-791307ccc9c2
html"""

"""

# ╔═╡ 6167139e-1e89-11eb-26f4-55cbdbc70de2
md"""
##### Exercise 8
*This exercise is more challenging.*

The root of a univariate function f(⋅) is an x such that f(x)=0.
One solution method to find local roots of smooth functions is called Newton’s method.
Starting with an x0 guess, a function f(⋅) and the first-derivative f′(⋅), the algorithm is to repeat

xn+1=xn−f(xn)f′(xn)

until |xn+1−xn| is below a tolerance

Use a variation of the fixedpointmap code to implement Newton’s method, where the function would accept arguments f, f_prime, x_0, tolerance, maxiter.
Test it with f(x)=(x−1)3 and another function of your choice where you can analytically find the derivative."""

# ╔═╡ 3928f3c2-1e8c-11eb-2244-3f9c7c2857d4
begin
	f(x) = (x-1)^3
	f_d(x) = ForwardDiff.derivative(f, x)

	f(1.7),f_d(1.7)
end

# ╔═╡ 4b431106-1e8b-11eb-00cd-814c8e98e0b7
let
	maxitr=200
	ini=rand(1:10)
	second=0
	for i in 1:maxitr
		second= ini - (f(ini)/f_d(ini))
		if abs(second-ini)< 1e-7
			break
		else
			ini=second
		end
	end
	second
end

# ╔═╡ Cell order:
# ╟─e30d5e5c-1e7b-11eb-0173-5dbf06d875bb
# ╟─02f30026-1e7c-11eb-1bdf-713cc1950a22
# ╟─c0b1a1c0-1e8e-11eb-11e4-9187b5708dad
# ╟─0297fd2c-1e7c-11eb-20de-ed44583cc810
# ╟─c5a9b326-1e7c-11eb-043e-6b700836e7df
# ╟─79411808-1e7e-11eb-1073-d9d8e2b1a662
# ╟─55e7aa80-1e7d-11eb-3447-810cb162aa9b
# ╠═96c557f0-1e7d-11eb-0577-1bef484e817a
# ╟─9438bd3c-1e7e-11eb-038d-c759ea6cf550
# ╟─b83ea3d6-1e7e-11eb-3c70-f5e2349bd425
# ╠═ae782114-1e7f-11eb-31bb-9f1b009f6853
# ╟─a56d8f26-1e89-11eb-2c21-791307ccc9c2
# ╟─6167139e-1e89-11eb-26f4-55cbdbc70de2
# ╠═3928f3c2-1e8c-11eb-2244-3f9c7c2857d4
# ╠═4b431106-1e8b-11eb-00cd-814c8e98e0b7
# ╠═c9f9318a-1e89-11eb-2939-f3a5f1289a12
# ╠═652e2558-1e7a-11eb-2483-cb1203507751

max_stars_repo_path: getting started with julia/Introductory Example.jl

max_stars_repo_name: nehamsoni/Quantitative-Economics

max_issues_repo_name: nehamsoni/Quantitative-Economics

max_forks_repo_name: nehamsoni/Quantitative-Economics


text:
# This file was generated, do not modify it. # hide
using Gnuplot, Random
Random.seed!(123)
goffset = "set offsets graph .05, graph .05, graph .05, graph .05" # hide
@gp rand(30) rand(30) "w p pt 6 ps 2 lc '#D55E00' lw 2 t 'marker'"
@gp :- title = "scatter plot" xlabel ="X" ylabel = "Y"
@gp :- "set key b l box opaque"
save(term="pngcairo size 600,400", output="./code/plt_ex11.png") # hide

max_stars_repo_name: lazarusA/gnuplot-examples

max_issues_repo_name: lazarusA/gnuplot-examples

max_forks_repo_name: lazarusA/gnuplot-examples


text:
import Random
using Distributions
using Dates: DateTime, Day
using UnPack: @unpack
import Bijectors

abstract type EpiRt end
## ===========================================================================
# Random Walk

struct RandomWalkDistribution{Tn, Ts} <: ContinuousMultivariateDistribution
    n::Tn
    s::Ts
end

Random.rand(rng::Random.AbstractRNG, d::RandomWalkDistribution{Tn, Ts}) where {Tn, Ts} = begin
    @unpack n, s = d
    step_prior = Normal(zero(Ts), s)
    x = Vector{Ts}(undef, n)

    ######## random walk
    x[1] = rand(step_prior)
    for i in 2:n
        x[i] = x[i-1] + rand(step_prior)
    end
    return x
end

Distributions.logpdf(d::RandomWalkDistribution{Tn, Ts}, x::AbstractVector{T}) where {Tn, Ts, T} =
    logpdf( MvNormal( d.n-1, d.s ), diff(x) )# + logpdf( Normal( zero(Ts), x[1] ) )
Bijectors.bijector(d::RandomWalkDistribution) = Bijectors.Identity{1}()

## ===========================================================================
"""
random walk with variable step interval
"""
struct RWModel{Tno, Tnt, Tns, Tin, Tli, Til} <: EpiRt
    nobs        ::Tno
    ntotal      ::Tnt
    nsteps      ::Tns
    index       ::Tin
    link        ::Tli
    invlink     ::Til
end

function stepindex(n, rwstep)
    index = Vector{Int64}(undef, n)
    nsteps = 1
    for i in eachindex(index)
        index[i] = nsteps
        i % rwstep == 0 && ( nsteps += 1 )
    end
    index
end

RWModel(
    dates     ::AbstractVector;
    endobs    = dates[end],
    rwstep    ::Int = 1,
    link      = exp,
    invlink   = log,
) = begin

	#@assert all( dates[1]:Day(1):dates[end] .== dates )
	ntotal  = length(dates)
	nobs    = findfirst(==(endobs), dates)
    index   = stepindex(nobs-1, rwstep)
    nsteps  = length( unique( index ) )

	RWModel(
        nobs,
		ntotal,
		nsteps,
		index,
		link,
		invlink
	)
end

(epirt::RWModel{Tno, Tnt, Tns, Tin, Tli, Til})(
	θ, ::Val{false}
) where {Tno, Tnt, Tns, Tin, Tli, Til} = begin
    @unpack rw, r0 = θ
    @unpack nobs, link = epirt

    rt         = Vector{typeof(r0)}(undef, nobs)
    rt[1]      = r0
    rt[2:nobs] = link.(rw)
    return rt
end

(epirt::RWModel{Tno, Tnt, Tns, Tin, Tli, Til})(
	θ, ::Val{true}
) where {Tno, Tnt, Tns, Tin, Tli, Til} = begin
    @unpack rw, r0 = θ
    @unpack ntotal, nobs, link = epirt

    rt              = Vector{typeof(r0)}(undef, ntotal)
    rt[1]           = r0
    rt[2:nobs]      = link.(rw)
    rt[nobs+1:end] .= rt[nobs]
    return rt
end

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

struct RWModelDistribution2{Tr0, Tσ, Tbm} <: ContinuousMultivariateDistribution
	r0_prior   ::Tr0
	σ_rw_prior ::Tσ
	rwmodel::Tbm
end

# RWModelDistribution2(
# 	r0_prior   ::Distribution,
# 	σ_rw_prior ::Distribution,
# 	args...; kwargs...
# ) = begin
# 	RWModelDistribution2(
# 		r0_prior, σ_rw_prior,
# 		RWModel(args...; kwargs...)
# 	)
# end

Base.rand(rng::Random.AbstractRNG, epirt::RWModelDistribution2) = begin
	@unpack r0_prior, σ_rw_prior, rwmodel = epirt
    @unpack nsteps, invlink = rwmodel

    ######## draw from univariate prior
    σ_rw = rand(rng, σ_rw_prior )
    r0   = rand(rng, r0_prior )

    ######## draw from random walk prior
    rw_prior = RandomWalkDistribution(nsteps, σ_rw)
    rw = rand(rng, rw_prior)
    return (; σ_rw, r0, rw)
end

Distributions.logpdf(epirt::RWModelDistribution2, θ) = begin
    @unpack rw, r0, σ_rw = θ
    @unpack r0_prior, σ_rw_prior, rwmodel = epirt
	@unpack nsteps, invlink = rwmodel

    rw_prior   = RandomWalkDistribution(nsteps, σ_rw)
    step_prior = Normal(zero(σ_rw), σ_rw) #NOTE same prior as in RandomWalkDistribution
    step = first(rw) - invlink(r0)

    target  = logpdf(σ_rw_prior, σ_rw)
    target += logpdf(r0_prior, r0)
    target += logpdf(step_prior, step)
    target += logpdf(rw_prior, rw)
    return target
end

Bijectors.bijector(d::RWModelDistribution2) = begin
	@unpack r0_prior, σ_rw_prior = d
	bj_r0 = Bijectors.bijector(r0_prior)
	bj_σ  = Bijectors.bijector(σ_rw_prior)
	bj_rw = Bijectors.Identity{1}()
	return Bijectors.Stacked( (bj_r0, bj_σ, bj_rw) )
end

## ===========================================================================
"""
random walk with constant early phase
"""
struct ConstantPhaseRWModel{Tr0, Tr1, Tσ, Tnc, Tno, Tnt, Tns, Tin, Tli, Til} <: EpiRt
    r0_prior    ::Tr0
    r1_prior    ::Tr1
    σ_rw_prior  ::Tσ
    nconst      ::Tnc
    nobs        ::Tno
    ntotal      ::Tnt
    nsteps      ::Tns
    index       ::Tin
    link        ::Tli
    invlink     ::Til
end

ConstantPhaseRWModel(
    dates     ::Vector{DateTime},
    startrw   ::DateTime;
    endobs    ::DateTime = dates[end],
    r0_prior  ::ContinuousUnivariateDistribution = truncated(Normal(3.5, 1.), 0, Inf),
    r1_prior  ::ContinuousUnivariateDistribution = truncated(Normal(1.,0.5), 0, Inf),
    σ_rw_prior::ContinuousUnivariateDistribution = truncated(Normal(0.02,0.01), 0, Inf),
    rwstep    ::Int = 1,
    link = exp,
    invlink = log,
) = begin

    @assert all( dates[1]:Day(1):dates[end] .== dates )
    ntotal  = length(dates)
    nconst  = findfirst(==(startrw), dates)-1
    nobs    = findfirst(==(endobs), dates)
    index   = stepindex(nobs-nconst-1, rwstep)
    nsteps  = length( unique( index ) )

	ConstantPhaseRWModel(
		r0_prior,
		r1_prior,
		σ_rw_prior,
		nconst,
		nobs,
		ntotal,
		nsteps,
		index,
		link,
		invlink
	)
end

(epirt::ConstantPhaseRWModel{Tr0, Tr1, Tσ, Tnc, Tno, Tnt, Tns, Tin, Tli, Til})(
	θ, ::Val{false}
) where {Tr0, Tr1, Tσ, Tnc, Tno, Tnt, Tns, Tin, Tli, Til} = begin
    @unpack rw, r0, r1 = θ
    @unpack nconst, nobs, link = epirt

    rt = Vector{typeof(r0)}(undef, nobs)
    rt[1:nconst]     .= r0
    rt[nconst+1]      = r1
    rt[nconst+2:end]  = link.(rw)
    return rt
end

(epirt::ConstantPhaseRWModel{Tr0, Tr1, Tσ, Tnc, Tno, Tnt, Tns, Tin, Tli, Til})(
	θ, ::Val{true}
) where {Tr0, Tr1, Tσ, Tnc, Tno, Tnt, Tns, Tin, Tli, Til} = begin
    @unpack rw, r0, r1 = θ
    @unpack nconst, ntotal, nobs, link, index = epirt

    rt = Vector{typeof(r0)}(undef, ntotal)
    rt[1:nconst]      .= r0
    rt[nconst+1]       = r1
    rt[nconst+2:nobs]  = link.(rw[index])
    rt[nobs+1:end]    .= rt[nobs]
    return rt
end

Base.rand(rng::Random.AbstractRNG, epirt::ConstantPhaseRWModel) = begin
    @unpack r0_prior, r1_prior, σ_rw_prior, nsteps, invlink = epirt

    ######## draw from univariate prior
    σ_rw = rand(rng, σ_rw_prior )
    r0   = rand(rng, r0_prior )
    r1   = rand(rng, r1_prior )

    ######## draw from random walk prior
    rw0 = invlink(r1)
    rw_prior = RandomWalkDistribution(nsteps, σ_rw)
    rw = rand(rng, rw_prior )
    return (; σ_rw, r0, r1, rw)
end

Distributions.logpdf(epirt::ConstantPhaseRWModel, θ) = begin
    @unpack rw, r0, r1, σ_rw = θ
    @unpack r0_prior, r1_prior, σ_rw_prior, nsteps, invlink = epirt

    rw_prior   = RandomWalkDistribution(nsteps, σ_rw)
    step_prior = Normal(zero(σ_rw), σ_rw) #NOTE same prior as in RadomWalk
    step = rw[1] - invlink(r1)

    target  = logpdf(σ_rw_prior, σ_rw)
    target += logpdf(r0_prior, r0)
    target += logpdf(r1_prior, r1)
    target += logpdf(step_prior, step)
    target += logpdf(rw_prior, rw)
    return target
end

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

# """
# # Arguments
#
# formula: An object of class formula which determines the linear predictor for the reproduction rates. The left hand side must take the form R(group, date), where group and date variables. group must be a factor vector indicating group membership (i.e. country, state, age cohort), and date must be a vector of class Date. This is syntactic sugar for the reproduction number in the given group at the given date.
#
# link: The link function. This must be either "identity", "log", or a call to scaled_logit.
#
# center: If TRUE then the covariates for the regression are centered to have mean zero. All of the priors are then interpreted as prior on the centered covariates. Defaults to FALSE.
#
# prior: Same as in stan_glm. In addition to the rstanarm provided priors, a shifted_gamma can be used. Note: If autoscale=TRUE in the call to the prior distribution then automatic rescaling of the prior may take place.
#
# prior_intercept: Same as in stan_glm. Prior for the regression intercept (if it exists).
#
# prior_covariance: Same as in stan_glmer. Only used if the formula argument specifies random effects.
#
# # Details
#
# epirt has a formula argument which defines the linear predictor, an argument link defining the link function, and additional arguments to specify priors on parameters making up the linear predictor.
# A general R formula gives a symbolic description of a model. It takes the form y ~ model, where y is the response and model is a collection of terms separated by the + operator. model fully defines a linear predictor used to predict y. In this case, the “response” being modeled are reproduction numbers which are unobserved. epirt therefore requires that the left hand side of the formula takes the form R(group, date), where group and date refer to variables representing the region and date respectively. The right hand side can consist of fixed effects, random effects, and autocorrelation terms.
#
# """
# function epirt(
#   formula,
#   link = "log",
#   center = FALSE,
#   prior = Normal(1, 0.5),
#   prior_intercept = Normal(1., 0.5),
#   prior_covariance = rstanarm::decov(scale = 0.5)
# ) end
#
#
# """
# A call to rw can be used in the 'formula' argument of epim, allowing random walks for the reproduction number.
#
# time:	An optional name defining the random walk time periods for each date and group. This must be a column name found in the data argument to epim. If not specified, determined by the dates column implied by the formula argument to epim is used.
#
# gr: Same as for time, except this defines the grouping to use for the random walks. A separate walk is defined for each group. If not specified a common random walk is used for all groups.
#
# prior_scale: The steps of the walks are independent zero mean normal with an unknown scale hyperparameter. This scale is given a half-normal prior. prior_scale sets the scale parameter of this hyperprior.
# """
# rw(time = "date", gr = "country", prior_scale = 0.2) = RWModel(time, gr, prior_scale)

# epirt(
#   formula,
#   link = "log",
#   prior = Normal(1, 0.5),
#   prior_intercept = Normal(1., 0.5),
#   prior_covariance = rstanarm::decov(scale = 0.5),
#   ...
# )


text:
# Note that this script can accept some limited command-line arguments, run
# `julia build_tarballs.jl --help` to see a usage message.
using BinaryBuilder, BinaryBuilderBase, Pkg, Base.BinaryPlatforms

name = "xtrx"
version = v"0.1.2"

# Collection of sources required to complete build
sources = [
    GitSource("https://github.com/xtrx-sdr/libxtrxdsp", "eec28640c0ebd5639b642f07b310a0a0d02d9834"),
    GitSource("https://github.com/xtrx-sdr/libxtrxll", "1b6eddfbedc700efb6f7e3c3594e43ac6ff29ea4"),
    GitSource("https://github.com/xtrx-sdr/libxtrx", "acb0b1cf7ab92744034767a04c1d4b4c281b840f"),
    GitSource("https://github.com/xtrx-sdr/liblms7002m", "b07761b7386181f0e6a35158456b75bce14f2aca"),
    DirectorySource("bundled"),
]

# Bash recipe for building across all platforms
script = raw"""

# Apply our patches
cd ${WORKSPACE}/srcdir
for f in ${WORKSPACE}/srcdir/patches/*.patch; do
    atomic_patch -p1 ${f}
done

# liblms7002m requires python3 and cheetah to perform build-time templating
apk add python3 py3-cheetah

if [[ ${bb_target} == x86_64-* ]] || [[ ${bb_target} == i686-* ]]; then
    XTRX_ARCH=x86
elif [[ ${bb_target} == aarch64-* ]] || [[ ${bb_target} == arm* ]]; then
    XTRX_ARCH=arm
fi

CMAKE_ARGS=(
    "-DCMAKE_INSTALL_PREFIX=${prefix}"
    "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TARGET_TOOLCHAIN}"
    "-DCMAKE_BUILD_TYPE=Release"

    # CC_ARCH isn't set properly; just override
    "-DFORCE_ARCH=${XTRX_ARCH}"

    # Install utilities to `bin`
    "-DXTRXDSP_UTILS_DIR=${bindir}"
    "-DXTRXLL_UTILS_DIR=${bindir}"
)

mkdir ${WORKSPACE}/srcdir/liblms7002m_build
cd ${WORKSPACE}/srcdir/liblms7002m_build
cmake ${CMAKE_ARGS[@]} ${WORKSPACE}/srcdir/liblms7002m
make -j${nproc}
make install

mkdir ${WORKSPACE}/srcdir/libxtrxdsp_build
cd ${WORKSPACE}/srcdir/libxtrxdsp_build
cmake ${CMAKE_ARGS[@]} ${WORKSPACE}/srcdir/libxtrxdsp
make -j${nproc}
make install

mkdir ${WORKSPACE}/srcdir/libxtrxll_build
cd ${WORKSPACE}/srcdir/libxtrxll_build
cmake ${CMAKE_ARGS[@]} -DENABLE_PCIE=ON ${WORKSPACE}/srcdir/libxtrxll
make -j${nproc}
make install

mkdir ${WORKSPACE}/srcdir/libxtrx_build
cd ${WORKSPACE}/srcdir/libxtrx_build
cmake ${CMAKE_ARGS[@]} ${WORKSPACE}/srcdir/libxtrx
make -j${nproc}
make install
install_license ${WORKSPACE}/srcdir/libxtrx/LICENSE
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = supported_platforms(; experimental=true)

# Disable everything except glibc Linux for now, and only intel/arm processors
filter!(p -> Sys.islinux(p) && libc(p) == "glibc" && proc_family(p) ∈ ("intel", "arm"), platforms)
platforms = expand_cxxstring_abis(platforms)

# The products that we will ensure are always built
products = [
    ExecutableProduct("test_xtrxll", :test_xtrxll),
    ExecutableProduct("test_xtrxflash", :test_xtrxflash),
    ExecutableProduct("test_xtrx", :test_xtrxflash),
    LibraryProduct("libxtrx", :libxtrx),
    LibraryProduct("libxtrxll", :libxtrxll),
    LibraryProduct("libxtrxdsp", :libxtrxdsp),
    LibraryProduct("liblms7compact", :liblms7compact),
    LibraryProduct("libXTRXSupport", :libXTRXSupport, ["lib/SoapySDR/modules0.8"]),
]

# Dependencies that must be installed before this package can be built
dependencies = Dependency[
    Dependency("soapysdr_jll"),
]

# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies; julia_compat="1.6", preferred_gcc_version=v"7")

max_stars_repo_name: jameskermode/Yggdrasil

max_issues_repo_name: jameskermode/Yggdrasil

max_forks_repo_name: jameskermode/Yggdrasil


text:
module IAE

export iae

"""
```julia
iae(error)
```
IAE (Integral Absolute Error) from error vector.
Inputs:
error -> error vector.
"""
function iae(error::Vector{T}) where T
    sum(abs.(error))
end

"""
```julia
iae(error)
```
IAE (Integral Absolute Error) from vector of error vector.
Inputs:
error -> vector of error vector.
"""
function iae(error::Vector{Vector{T}}) where T
    map(x->sum(abs.(x)), error)
end

"""
```julia
iae(x, t, desired)
```
IAE (Integral Absolute Error) from error betwwen desired value and controler output.
Inputs:
x -> controler output vector;
t -> time vector;
desired -> desired value function.
"""
function iae(x::Vector{T}, t::Vector{T}, desired::Function) where T
    x = x .- map(desired, t)
    sum(abs.(x))
end

end


text:
using Printf, BenchmarkTools, Trixi

function run_benchmarks(benchmark_run; levels=0:5, polydeg=3)
  runtimes = zeros(length(levels))
  for (idx,initial_refinement_level) in enumerate(levels)
    result = benchmark_run(; initial_refinement_level, polydeg)
    display(result)
    runtimes[idx] = result |> median |> time # in nanoseconds
  end
  return (; levels, runtimes, polydeg)
end

function tabulate_benchmarks(args...; kwargs...)
  result = run_benchmarks(args...; kwargs...)
  println("#Elements | Runtime in seconds")
  for (level,runtime) in zip(result.levels, result.runtimes)
    @printf("%9d | %.2e\n", 4^level, 1.0e-9 * runtime)
  end
  for (level,runtime) in zip(result.levels, result.runtimes)
    @printf("%.16e\n", 1.0e-9 * runtime)
  end
end

function benchmark_euler(; initial_refinement_level=1, polydeg=3)

  γ = 1.4
  equations = CompressibleEulerEquations2D(γ)

  surface_flux = flux_ranocha
  volume_flux  = flux_ranocha
  solver = DGSEM(polydeg, surface_flux, VolumeIntegralFluxDifferencing(volume_flux))

  coordinates_min = (-2.0, -2.0)
  coordinates_max = ( 2.0,  2.0)
  mesh = TreeMesh(coordinates_min, coordinates_max,
                  initial_refinement_level=initial_refinement_level,
                  n_cells_max=100_000)

  semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_weak_blast_wave, solver)

  t0 = 0.0
  u0 = compute_coefficients(t0, semi)
  du = similar(u0)

  @benchmark Trixi.rhs!($du, $u0, $semi, $t0)
end

# versioninfo(verbose=true)
@show Threads.nthreads()
tabulate_benchmarks(benchmark_euler, levels=0:8)