text:
# using Revise
using PiecewiseDeterministicMarkovProcesses, LinearAlgebra, Random, DifferentialEquations, Sundials
const PDMP = PiecewiseDeterministicMarkovProcesses

function F_tcp!(ẋ, xc, xd, parms, t)
	# vector field used for the continuous variable
	if mod(xd[1],2) == 0
		 ẋ[1] = 1.0
	else
		 ẋ[1] = -10.0 * xc[1]
	end
	nothing
end

rate_tcp(x) = 1/(1+exp(-x))

function R_tcp!(rate, xc, xd, parms, t, issum::Bool)
	if issum==false
		rate[1] = rate_tcp(xc[1])
		rate[2] = 0.0
		return rate_tcp(xc[1]), 1.0
	else
		return rate_tcp(xc[1]), 1.0
	end
end

function AnalyticalSample(xc0,xd0,ti,nj::Int64; verbose = false)
	verbose && printstyled(color=:red,"--> Start analytical method\n")
	xch = [xc0[1]]
	xdh = [xd0[1]]
	th  = [ti]
	t = ti
	xc = xc0[1]
	njumps = 1
	rt = zeros(2)
	lambda_star = R_tcp!(rt,xc0,xd0,ti,Float64[],true)[2]
	rate		= R_tcp!(rt,xc0,xd0,ti,Float64[],true)[1]
	S = -log(rand()) / lambda_star
	while njumps < nj
		xd  = [xdh[end] ,1]

		t += S
		if mod(xd[1],2) == 0
			xc = xc + S
		else
			xc = xc * exp(-10S)
		end
		verbose && println("--> S = $S, t = $t, xc = $xc, xd = $(xd[1]), λ_* = ", lambda_star)
		#reject?
		lambda_star = R_tcp!(rt,[xc],xd,ti,Float64[],true)[2]
		rate		= R_tcp!(rt,[xc],xd,ti,Float64[],true)[1]
		reject = rand() < (1 - rate / lambda_star)
		S = -log(rand()) / lambda_star
		if ~reject
			verbose && println("----> Jump!, ratio = ",rate / lambda_star)
			push!(th,t)
			push!(xch,xc)
			push!(xdh,xdh[end] + 1)
			njumps += 1
			# dummy call to rand to emulate sampling pfsample
			dum = -log(rand())
		end
	end
	return th, xch, xdh
end

xc0 = [ 0.0 ]
xd0 = [0, 0]

nu_tcp = [1 0;0 -1]
	parms = [0.0]
	tf = 100000.
	nj = 50
	errors = Float64[]

Random.seed!(1234)
	res_a = AnalyticalSample(xc0, xd0, 0.0, nj, verbose=false)

println("\n\nComparison of solvers")
	for ode in [(:cvode,"cvode"),(:lsoda,"lsoda"),(CVODE_BDF(),"CVODEBDF"),(CVODE_Adams(),"CVODEAdams"),(Tsit5(),"tsit5"),(Rodas4P(autodiff=false),"rodas4P-noAutoDiff"),(Rodas4P(),"rodas4P-AutoDiff"),(Rosenbrock23(),"RS23"),(AutoTsit5(Rosenbrock23()),"AutoTsit5RS23")]
	Random.seed!(1234)
	problem = PDMP.PDMPProblem(F_tcp!, R_tcp!, nu_tcp, xc0, xd0, parms, (0.0, tf))
	res =  PDMP.solve(problem, Rejection(ode[1]); n_jumps = nj)
	println("--> norm difference = ", norm(res.time[1:nj] - res_a[1],Inf64), "  - solver = ",ode[2])
	push!(errors, norm(res.xc[1,1:nj] - res_a[2], Inf64))
	end

println("test for allocations, should not depend on")
	Random.seed!(1234)
	problem = PDMP.PDMPProblem(F_tcp!, R_tcp!, nu_tcp, xc0, xd0, parms, (0.0, tf))
	res =  PDMP.solve(problem, Rejection(Tsit5()); n_jumps = nj, save_positions = (false, false))
	Random.seed!(1234)
	res =  @time PDMP.solve(problem, Rejection(Tsit5()); n_jumps = nj, save_positions = (false, false))
	Random.seed!(1234)
	res =  @time PDMP.solve(problem, Rejection(Tsit5()); n_jumps = 2nj, save_positions = (false, false))
	Random.seed!(1234)
	res =  @time PDMP.solve(problem, Rejection(Tsit5()); n_jumps = 3nj, save_positions = (false, false))

println("test for multiple calls, the result should not depend on")
	Random.seed!(1234)
	problem = PDMP.PDMPProblem(F_tcp!, R_tcp!, nu_tcp, xc0, xd0, parms, (0.0, tf))
	res1 =  PDMP.solve(problem, Rejection(Tsit5()); n_jumps = nj)
	res2 =  PDMP.solve(problem, Rejection(Tsit5()); n_jumps = nj)
	@assert res1.time != res2.time
	Random.seed!(1234)
	res1 =  PDMP.solve(problem, Rejection(Tsit5()); n_jumps = nj)
	Random.seed!(1234)
	res2 =  PDMP.solve(problem, Rejection(Tsit5()); n_jumps = nj)
	@assert res1.time == res2.time

# Random.seed!(1234)
# 	problem = PDMP.PDMPProblem(F_tcp!, R_tcp!, nu_tcp, xc0, xd0, parms, (0.0, tf))
# 	alloc1 =  @time PDMP.solve(problem, Rejection(Tsit5()); n_jumps = 2nj, save_positions = (false, false))
#
# Random.seed!(1234)
# 	problem = PDMP.PDMPProblem(F_tcp!, R_tcp!, nu_tcp, xc0, xd0, parms, (0.0, tf))
# 	alloc2 =  @time PDMP.solve(problem, Rejection(Tsit5()); n_jumps = 4nj, save_positions = (false, false))
#
# Random.seed!(1234)
# 	PDMP.PDMPProblem(F_tcp!, R_tcp!, nu_tcp, xc0, xd0, parms, (0.0, tf))
# 	res = @time PDMP.solve(problem, Rejection(Tsit5()); n_jumps = 4nj, save_positions = (false, false))
#
# Random.seed!(1234)
# 	problem = PDMP.PDMPProblem(F_tcp!, R_tcp!, nu_tcp, xc0, xd0, parms, (0.0, tf))
# 	res =  PDMP.solve(problem, Rejection(:lsoda); n_jumps = nj, save_positions = (false, false), save_rate = true)

# test the number of rejected jumps
Random.seed!(1234)
	problem = PDMP.PDMPProblem(F_tcp!, R_tcp!, nu_tcp, xc0, xd0, parms, (0.0, tf))
	res1 =  PDMP.solve(problem, Rejection(:cvode); n_jumps = nj)
Random.seed!(1234)
	problem = PDMP.PDMPProblem(F_tcp!, R_tcp!, nu_tcp, xc0, xd0, parms, (0.0, tf))
	res2 =  PDMP.solve(problem, Rejection(CVODE_BDF()); n_jumps = nj)


text:
using Base.Test
using LatexPrint

@test latex_form(-5) == "-5"
@test latex_form(2.2) == "2.2"
@test latex_form("Hello") == "\\text{Hello}"
@test latex_form(-3//5) == "\\frac{-3}{5}"
@test latex_form(im) == "0+1i"
@test latex_form(1/0) == "\\infty"
@test latex_form(0/0) == "\\text{NaN}"
@test latex_form(pi) == "\\pi"
@test latex_form([1,2]) == "\\left[\n\\begin{array}{c}\n1 \\\\\n2 \\\\\n\\end{array}\n\\right]"
@test latex_form([1,2]') == "\\left[\n\\begin{array}{cc}\n1 & 2 \\\\\n\\end{array}\n\\right]"

ext: jl


text:
o1 = UncertainValue(Normal, 0, 0.2)
o2 = UncertainValue(Normal, 1, 0.3)
o3 = UncertainValue(Uniform, 0, 4)
o4 = UncertainValue(Uniform, rand(100))
o5 = UncertainValue(rand(Normal(), 1000))

D1 = UncertainDataset([o1, o2, o3, o5])
D2 = UncertainDataset([o1, o2, o4, o5])

##################
# Uncertain values
##################
@test mean(o1) isa Float64
@test median(o1) isa Float64
@test quantile(o1, 0.86) isa Float64
@test std(o1) isa Float64
@test var(o1) isa Float64

#####################
## Uncertain datasets
#####################
@test mean(D1, 10) isa Vector{Float64}
@test median(D1, 10) isa Vector{Float64}
@test middle(D1, 10) isa Vector{Float64}
@test std(D1, 10) isa Vector{Float64}
@test var(D1, 10) isa Vector{Float64}
@test quantile(D1, 0.4, 10) isa Vector{Float64}

@test cor(D1, D2, 10) isa Vector{Float64}
@test cov(D1, D2, 10) isa Vector{Float64}

@test cor(D1, D2) isa Float64
@test cov(D1, D2) isa Float64


text:
using Router, Hello

route("/hello") do
  Hello.greet()
  Router.serve_static_file("/hello-world.png")
end

max_stars_repo_name: essenciary/genie-demo-hello-world

max_issues_repo_name: essenciary/genie-demo-hello-world

max_forks_repo_name: essenciary/genie-demo-hello-world


text:
using BenchmarkTools
using Folds
using FoldsThreads

const SUITE = BenchmarkGroup()
const DATA_LENGTH = 2^23

for log2_basesize in 12:14
    basesize = 2^log2_basesize
    SUITE[basesize] = s1 = BenchmarkGroup()
    for log2_needleloc in 11:23
        needleloc = 2^log2_needleloc
        s1[needleloc] = s2 = BenchmarkGroup()
        xs = rand(DATA_LENGTH)
        xs[needleloc] = 2
        s2["ThreadedEx"] =
            @benchmarkable( Folds.findfirst(>(1), $xs, ThreadedEx(basesize = $basesize)))
        s2["WorkStealingEx"] =
            @benchmarkable(Folds.findfirst(>(1), $xs, WorkStealingEx(basesize = $basesize)))
        s2["DepthFirstEx"] =
            @benchmarkable(Folds.findfirst(>(1), $xs, DepthFirstEx(basesize = $basesize)))
        #=
        s2["SpawnAllEx"] =
            @benchmarkable(Folds.findfirst(>(1), $xs, SpawnAllEx(basesize = $basesize)))
        =#
    end
end


text:
using FFTW, Parameters, DiffEqOperators, Setfield, Parameters
FFTW.set_provider!("mkl")
using LinearAlgebra, Plots, SparseArrays

#============== Exports =============#
export GenericParams, Params, Flags, State, getXs
export ∂ₓ, ∂ₓₓ, ∂ₓₓₓₓ, ∇², ∇⁴, LaplaceOperator

#================ Classes ===============#

#  PARAMS contain all relevant parameters
# of the state. They will later be stored
# in State.
struct GenericParams
    N::Int
    Δx::Real
    p::Dict
end

#  FLAGS contain all relevant flags of the
# state, i.e. wether to compute derivatives
# using FFT or FD, etc.
@with_kw struct Flags
    useFFT::Bool = true
    sym::Bool = false
    switch::Bool = false
end

#  STATE is the main class, it will contain
# the solution u, and relevant parameters
# in the form of a dictionary, it MUST contain
# N and Δx
@with_kw struct State
    gp::GenericParams
    u::Matrix
    flags::Flags = Flags()
end

#============== Base functions =============#

function LaplaceOperator(N, Δx)
    D2x = CenteredDifference(2, 2, Δx, N)
    Qx = PeriodicBC(Float64)
    sp = sparse(D2x * Qx)[1]
    kron(sparse(I,  N, N), sp) + kron(sp, sparse(I, N, N))
end

function LaplaceOperator1D(N, Δx)
    D2x = CenteredDifference(2, 2, Δx, N)
    Qx = Dirichlet0BC(typeof(Δx))
    sparse(D2x * Qx)[1]
end

#  Base function that computes matrix derivatives
# along x or y, for arbitrary order.
function deriv_mat(A::Matrix, Δx::Real; axis::Char='x', order::Int=1, useFFT::Bool=true)

    N = size(A)[1];
    if useFFT
        freqs = fftfreq(N) * N;
        L = (N-1) * Δx;

        if axis == 'y'
            dim = 1;
            k = [freqs[i] for i in 1:N, j in 1:N];
        elseif axis == 'x'
            dim = 2;
            k = [freqs[j] for i in 1:N, j in 1:N];
        else
            println("Axis not understood");
        end
        real.(ifft( (2π / L * im) ^ order * k .^ order .* fft(A) ))
    else
        B = similar(A) # assuming order = 2
        for i in 1:N, j in 1:N
            j₋ = if j > 1 j - 1 else N end
            j₊ = if j < N j + 1 else 1 end
            i₊ = if i < N i + 1 else 1 end
            i₋ = if i > 1 i - 1 else N end
            B[j, i] = A[j₋, i] + A[j₊, i] + A[j, i₋] + A[j, i₊] - 4 * A[j, i]
        end
        B
    end
end

function getXs(gp::GenericParams)
    (0:gp.N-1) * gp.Δx
end

function getXs(S::State)
    getXs(S.gp)
end

### Definitions to simplify the code

∂ₓ(S::State; axis='x') = deriv_mat(S.u, S.gp.Δx, axis=axis, order=1, useFFT=S.flags.useFFT);
∂ₓₓ(S::State; axis='x') = deriv_mat(S.u, S.gp.Δx, axis=axis, order=2, useFFT=S.flags.useFFT);
∂ₓₓₓₓ(S::State; axis='x') = deriv_mat(S.u, S.gp.Δx, axis=axis, order=4, useFFT=S.flags.useFFT);

∇²(S::State) = ∂ₓₓ(S) + ∂ₓₓ(S, axis='y');
∇⁴(S::State) = ∂ₓₓₓₓ(S) + ∂ₓₓₓₓ(S, axis='y');

function ∇²(N::Int, Δx::Real; dim::Int=2)
    if dim == 2
        LaplaceOperator(N, Δx)
    elseif dim == 1
        LaplaceOperator1D(N, Δx)
    end
end

∇⁴(N::Int, Δx::Real; dim::Int=2) = ∇²(N, Δx; dim)^2

∇²(V::Array, N::Int, Δx::Real; dim::Int=2) = ∇²(N, Δx; dim) * V
∇⁴(V::Array, N::Int, Δx::Real; dim::Int=2) = ∇⁴(N, Δx; dim) * V


text:
"""
    PoptartExpr

Generate Poptart controls.

API is kept consistent with `Poptart.Desktop`
"""
module PoptartExpr

using Poptart.Desktop

export xpoptart_desktop, xpush_item, xexit

"""
`xcall` but support `Type` as function.

It is meant to be a private function.
"""
xcall_poptart(m::Module, name::Union{Type, Function}, xs...; kwargs...) = xcall_poptart(m, nameof(name), xs...; kwargs...)
xcall_poptart(m::Module, name::Symbol, xs...; kwargs...) = xcall_poptart(GlobalRef(m, name), xs...; kwargs...)

function xcall_poptart(ref::GlobalRef, xs...; kwargs...)
    params = Expr(:parameters)
    for (key, value) in kwargs
        if value isa Vector
            value = Expr(:vect, value...)
        end

        push!(params.args, Expr(:kw, key, value))
    end

    if isempty(kwargs)
        Expr(:call, ref, xs...)
    else
        return Expr(:call, ref, params, xs...)
    end
end

function xpoptart_desktop(control, xs...; kwargs...)
    xcall_poptart(Desktop, control, xs...; kwargs...)
end

const CONTROLS = (:Application, :Button, :InputText, :Window, :Checkbox, :Popup, :SameLine, :NewLine, :Label, :Slider, :Canvas, :Spacing, :Group, :Separator)

for control in CONTROLS
    funname = Symbol(:X, control)

    @eval export $funname

    @eval function ($funname)(; kwargs...)
        xpoptart_desktop($control; kwargs...)
    end

    @eval function ($funname)(control_var::Symbol; kwargs...)
        :($control_var = $(xpoptart_desktop($control; kwargs...)))
    end
end

const CLICKABLES = (:Button, :Checkbox)

for control in CLICKABLES
    funname = Symbol(:X, control)

    @eval function ($funname)(control_var::Symbol, click_event; kwargs...)
        click_function = :(function (event) $click_event end)
        quote
            $(($funname)(control_var; kwargs...))
            $(xpoptart_desktop(:didClick, click_function, control_var))
        end
    end
end

function xpush_item(control_var::Symbol, items...)
    ret = :(push!($control_var.items))
    append!(ret.args, items)
    ret
end

function xexit(app::Symbol; esc=true)
    quote
        Poptart.Desktop.exit_on_esc() = $esc
        Base.JLOptions().isinteractive==0 && wait($app.closenotify)
    end
end

end


text:
# Biryani -- A conversion and validation toolbox
# By: Emmanuel Raviart <emmanuel@raviart.com>
#
# Copyright (C) 2015 Emmanuel Raviart
# https://github.com/eraviart/Biryani.jl
#
# This file is part of Biryani.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

const year_or_month_or_day_re = r"(15|16|17|18|19|20)\d{2}(-(0[1-9]|1[0-2])(-([0-2]\d|3[0-1]))?)?$"

date_to_iso8601_string(convertible::Convertible) = call(date -> string(date))(convertible)
"""Convert a date to a string using ISO 8601 format."""

iso8601_input_to_date(convertible::Convertible) = pipe(strip, iso8601_string_to_date)(convertible)
"""Convert a string in ISO 8601 format to a date."""

iso8601_string_to_date(convertible::Convertible) = pipe(
  test(value -> ismatch(year_or_month_or_day_re, value), error = N_("Invalid ISO-8601 format for date.")),
  call(value -> Date(join(vcat(split(value, '-'), ["01", "01"])[1:3], '-'))),
)(convertible)
"""Convert a clean string in ISO 8601 format to a date.

.. note:: For a converter that doesn't require a clean string, see :func:`iso8601_input_to_date`.
"""

function to_date(convertible::Convertible)
  """Convert a Julia data to a date.

  .. warning:: Like most converters, a ``nothing`` value is not converted.
  """
  if convertible.error !== nothing || convertible.value === nothing
    return convertible
  end
  return to_date(convertible.value, convertible.context)
  # return Convertible(Date(convertible.value), convertible.context)
end

to_date(year::Int, context::Context) = Convertible(Date(year), context)
to_date(year::Int, month::Int, context::Context) = Convertible(Date(year, month), context)
to_date(year::Int, month::Int, day::Int, context::Context) = Convertible(Date(year, month, day), context)

to_date(value::Tuple{Int}, context::Context) = Convertible(Date(value[1]), context)
to_date(value::Tuple{Int, Int}, context::Context) = Convertible(Date(value[1], value[2]), context)
to_date(value::Tuple{Int, Int, Int}, context::Context) = Convertible(Date(value[1], value[2], value[3]), context)

function to_date(value::AbstractString, context::Context)
  if !('-' in value)
    # Work around bug in Julia 0.3: Date("2013") throws:
    # ERROR: ArgumentError("Delimiter mismatch. Couldn't find first delimiter, \"-\", in date string")
    value = string(value, "-1")
  end
  return Convertible(Date(value), context)
end

to_date(value, context::Context) = Convertible(Date(value), context)


text:
#   This file is part of UnitSystems.jl
#   It is licensed under the MIT license
#   UnitSystems Copyright (C) 2020 Michael Reed
#       _           _                         _
#      | |         | |                       | |
#   ___| |__   __ _| | ___ __ __ ___   ____ _| | __ _
#  / __| '_ \ / _` | |/ / '__/ _` \ \ / / _` | |/ _` |
# | (__| | | | (_| |   <| | | (_| |\ V / (_| | | (_| |
#  \___|_| |_|\__,_|_|\_\_|  \__,_| \_/ \__,_|_|\__,_|
#
#   https://github.com/chakravala
#   https://crucialflow.com

@doc """
```Julia
julia> deka
$deka

julia> hecto
$hecto

julia> kilo
$kilo

julia> mega
$mega

julia> giga
$giga

julia> tera
$tera

julia> peta
$peta

julia> exa
$exa

julia> zetta
$zetta

julia> yotta
$yotta
```
""" deka,hecto,kilo,mega,giga,tera,peta,exa,zetta,yotta

@doc """
```Julia
julia> deci
$deci

julia> centi
$centi

julia> milli
$milli

julia> micro
$micro

julia> nano
$nano

julia> pico
$pico

julia> femto
$femto

julia> atto
$atto

julia> zepto
$zepto

julia> yocto
$yocto
```
""" deci,centi,milli,micro,nano,pico,femto,atto,zepto,yocto

@doc """
```Julia
julia> byte
$byte

julia> kibi
$kibi

julia> mebi
$mebi

julia> gibi
$gibi

julia> tebi
$tebi

julia> pebi
$pebi

julia> exbi
$exbi

julia> zebi
$zebi

julia> yobi
$yobi
```
""" byte,kibi,mebi,gibi,tebi,pebi,exbi,zebi,yobi

# angle

@doc """
$(unitext(:radian,"angle(𝟏,U,Metric)"))

Unit of `angle` which is dimensionless.
```Julia
julia> radian(MetricEngineering)
$(radian(MetricEngineering))
```
""" radian

@doc """
$(unitext(:steradian,"solidangle(𝟏,U,Metric)"))

Unit of `solidangle` which is dimensionless.
```Julia
julia> steradian(MetricEngineering)
$(steradian(MetricEngineering))
```
""" steradian

@doc """
$(unitext(:degree,"angle(τ/𝟐^3/𝟑^2/𝟓,U,Metric)"))

Unit of `angle` which divides a `turn` into `360` parts.
```Julia
julia> degree(MetricEngineering)
$(degree(MetricEngineering))
```
""" degree

@doc """
$(unitext(:gradian,"angle(τ/𝟐^4/𝟓^2,U,Metric)"))

Unit of `angle` which divides a `turn` into `400` parts.
```Julia
julia> gradian(MetricEngineering)
$(gradian(MetricEngineering))
```
""" gradian

@doc """
$(unitext(:arcminute,"degree(U)/𝟐^2/𝟑/𝟓"))

Unit of `angle` which divides a `degree` into `60` parts.
```Julia
julia> arcminute(MetricEngineering)
$(arcminute(MetricEngineering))
```
""" arcminute

@doc """
$(unitext(:arcsecond,"arcminute(U)/𝟐^2/𝟑/𝟓"))

Unit of `angle` which divides a `arcminute` into `60` parts.
```Julia
julia> arcsecond(MetricEngineering)
$(arcsecond(MetricEngineering))
```
""" arcsecond

# time

@doc """
$(unitext(:second,"time(𝟏,U,Metric)"))

Unit of `time` defined by `hyperfine` transition frequency of Cs-133 atom.
```Julia
julia> second(Metric) # s
$(second(Metric))

julia> second(MPH) # h
$(second(MPH))

julia> second(IAU) # D
$(second(IAU))
```
""" second

@doc """
$(unitext(:minute,"𝟐^2*𝟑*𝟓*second(U)"))

Unit of `time` defined by 60 `second` intervals.
```Julia
julia> minute(Metric) # s
$(minute(Metric))

julia> minute(MPH) # h
$(minute(MPH))

julia> minute(IAU) # D
$(minute(IAU))
```
""" minute

@doc """
$(unitext(:hour,"𝟐^2*𝟑*𝟓*minute(U)"))

Unit of `time` defined by 60 `minute` intervals.
```Julia
julia> hour(Metric) # s
$(hour(Metric))

julia> hour(MPH) # h
$(hour(MPH))

julia> hour(IAU) # D
$(hour(IAU))
```
""" hour, HOUR

@doc """
$(unitext(:day,"𝟐^3*𝟑*hour(U)"))

Unit of `time` defined by 24 `hour` intervals.
```Julia
julia> day(Metric) # s
$(day(Metric))

julia> day(MPH) # h
$(day(MPH))

julia> day(IAU) # D
$(day(IAU))
```
""" day, DAY

@doc """
$(unitext(:year,"aⱼ*day(U)"))

Unit of `time` defined by Julian calendar year interval.
```Julia
julia> year(Metric) # s
$(year(Metric))

julia> year(MPH) # h
$(year(MPH))

julia> year(IAU) # D
$(year(IAU))
```
""" year, aⱼ

@doc """
$(unitext(:radarmile,"𝟐*nauticalmile(U)/lightspeed(U)"))

Unit of `time` delay from a two-way `nauticalmile` radar return.
```Julia
julia> radarmile(Metric)
$(radarmile(Metric))
```
""" radarmile

# length

@doc """
$(unitext(:meter,"length(𝟏,U,Metric)"))

Metric unit of `length` (m or ft).
```Julia
julia> meter(CGS) # cm
$(meter(CGS))

julia> meter(English) # ft
$(meter(English))

julia> meter(Meridian) # em
$(meter(Meridian))
```
""" meter

@doc """
$(unitext(:earthmeter,"greatcircle(U)/𝟐^9/𝟓^7"))

Meridian unit of `length` as originally defined in France (m or ft).
```Julia
julia> earthmeter(CGS) # cm
$(earthmeter(CGS))

julia> earthmeter(English) # ft
$(earthmeter(English))

julia> earthmeter(Meridian) # em
$(earthmeter(Meridian))
```
""" earthmeter

@doc """
$(unitext(:angstrom,"hecto*pico*meter(U)"))

Metric unit of `length` (m or ft).
```Julia
julia> angstrom(CGS) # cm
$(angstrom(CGS))

julia> angstrom(English) # ft
$(angstrom(English))

julia> angstrom(IPS) # in
$(angstrom(IPS))
```
""" angstrom

@doc """
$(unitext(:foot,"length(𝟏,U,English)"))

English unit of `length` (m or ft).
```Julia
julia> foot(Metric) # m
$(foot(Metric))

julia> foot(Survey) # ftUS
$(foot(Survey))

julia> foot(IPS) # in
$(foot(IPS))
```
""" foot

@doc """
$(unitext(:surveyfoot,"length(𝟏,U,Survey)"))

Survey unit of `length` (m or ft).
```Julia
julia> surveyfoot(Metric) # m
$(surveyfoot(Metric))

julia> surveyfoot(English) # ft
$(surveyfoot(English))

julia> surveyfoot(IPS) # in
$(surveyfoot(IPS))
```
""" surveyfoot

@doc """
$(unitext(:inch,"length(𝟏,U,IPS)"))

English unit of `length` (m or ft).
```Julia
julia> inch(Metric) # m
$(inch(Metric))

julia> inch(English) # ft
$(inch(English))

julia> inch(IPS) # in
$(inch(IPS))
```
""" inch

#=@doc """
$(unitext(:rackunit,"length($(ft*𝟕/𝟐^4/𝟑),U,English)"))

Height unit of a 19-inch rack frame (m or ft).
```Julia
julia> rackunit(Metric) # m
$(rackunit(Metric))

julia> rackunit(CGS) # cm
$(rackunit(CGS))

julia> rackunit(English) # ft
$(rackunit(English))
```
""" rackunit=#

@doc """
$(unitext(:yard,"𝟑*foot(U)"))

English unit of `length` (m or ft).
```Julia
julia> yard(Metric) # m
$(yard(Metric))

julia> yard(English) # ft
$(yard(English))

julia> yard(IPS) # in
$(yard(IPS))
```
""" yard

@doc """
$(unitext(:statutemile,"length(𝟐^5*𝟑*𝟓*𝟏𝟏,U,Survey)"))

Statute `Survey` mile (m or ft).
```Julia
julia> statutemile(Metric) # m
$(statutemile(Metric))

julia> statutemile(English) # ft
$(statutemile(English))

julia> statutemile(Survey) # ftUS
$(statutemile(Survey))
```
""" statutemile

@doc """
$(unitext(:astronomicalunit,"length(𝟏,U,IAU)"))

Standard astronomical unit from the International Astronomical Union (m or ft).
```Julia
julia> astronomicalunit(Metric) # m
$(astronomicalunit(Metric))

julia> astronomicalunit(English) # ft
$(astronomicalunit(English))

julia> astronomicalunit(Metric)/lightspeed(Metric) # s
$(astronomicalunit(Metric)/lightspeed(Metric))
```
""" astronomicalunit, au

@doc """
$(unitext(:lunardistance,"length(𝟏,U,IAUE)"))

Standard distance between the Earth and the Moon (m or ft).
```Julia
julia> lunardistance(Metric) # m
$(lunardistance(Metric))

julia> lunardistance(Nautical) # nm
$(lunardistance(Nautical))

julia> lunardistance(Metric)/lightspeed(Metric) # s
$(lunardistance(Metric)/lightspeed(Metric))
```
""" lunardistance, LD

@doc """
$(unitext(:jupiterdistance,"length(𝟏,U,IAUJ)"))

Standard distance between the Sun and the planet Jupiter (m or ft).
```Julia
julia> jupiterdistance(Metric) # m
$(jupiterdistance(Metric))

julia> jupiterdistance(IAU) # au
$(jupiterdistance(IAU))

julia> jupiterdistance(Metric)/lightspeed(Metric) # s
$(jupiterdistance(Metric)/lightspeed(Metric))
```
""" jupiterdistance, JD

@doc """
$(unitext(:mile,"length(𝟏,U,MPH)"))

Statute `English` mile (m or ft).
```Julia
julia> mile(Metric) # m
$(mile(Metric))

julia> mile(English) # ft
$(mile(English))

julia> mile(Nautical) # nm
$(mile(Survey))
```
""" mile

@doc """
$(unitext(:admiraltymile,"length(𝟐^6*𝟓*𝟏𝟗,U,English)"))

Historic nautical mile as defined by the Clarke authalic radius (m or ft).
```Julia
julia> admiraltymile(Metric) # m
$(admiraltymile(Metric))

julia> admiraltymile(English) # ft
$(admiraltymile(English))

julia> admiraltymile(Nautical) # nm
$(admiraltymile(Nautical))
```
""" admiraltymile

@doc """
$(unitext(:meridianmile,"length(𝟐^4*𝟓^5/𝟑^3,U,Metric)"))

Historic nautical mile as defined by naive meridian assumption (m or ft).
```Julia
julia> meridianmile(Metric) # m
$(meridianmile(Metric))

julia> meridianmile(English) # ft
$(meridianmile(English))

julia> meridianmile(Nautical) # nm
$(meridianmile(Nautical))
```
""" meridianmile

@doc """
$(unitext(:nauticalmile,"greatcircle(U)/𝟐^5/𝟑^3/𝟓^2"))

Standard `nauticalmile` as defined by `earthradius` (m or ft).
```Julia
julia> nauticalmile(Metric) # m
$(nauticalmile(Metric))

julia> nauticalmile(Meridian) # em
$(nauticalmile(Meridian))

julia> nauticalmile(English) # ft
$(nauticalmile(English))
```
""" nauticalmile, nm

@doc """
$(unitext(:lightyear,"year(U)*lightspeed(U)"))

Unit of `length` defined by distance traveled by light in 1 `year` unit.
```Julia
julia> lightyear(Metric) # m
$(lightyear(Metric))

julia> lightyear(English) # ft
$(lightyear(English))

julia> lightyear(IAU) # au
$(lightyear(IAU))
```
""" lightyear, ly

@doc """
$(unitext(:parsec,"astronomicalunit(U)*𝟐^2*𝟑^4*𝟓^3/τ"))

Unit of `length` defined at which 1 `astronomicalunit` subtends an angle of 1 arcsecond.
```Julia
julia> parsec(Metric) # m
$(parsec(Metric))

julia> parsec(English) # ft
$(parsec(English))

julia> parsec(IAU) # au
$(parsec(IAU))
```
""" parsec, pc

# area

@doc """
$(unitext(:barn,"area((𝟐*𝟓)^-28,U,Metric)"))

Unit of `area` defined by `100` square femto-meters (m² or ft²).
```Julia
julia> barn(Metric) # m²
$(barn(Metric))

julia> barn(CGS) # cm²
$(barn(CGS))

julia> barn(English) # ft²
$(barn(English))
```
""" barn

@doc """
$(unitext(:hectare,"area(hecto^2,U,Metric)"))

Metric unit of land `area` defined by `100` square meters (m² or ft²).
```Julia
julia> hectare(Metric) # m²
$(hectare(Metric))

julia> hectare(English) # ft²
$(hectare(English))

julia> hectare(Survey) # ftUS²
$(hectare(Survey))
```
""" hectare

@doc """
$(unitext(:acre,"area(𝟐^4*𝟓^4,U,Metric)"))

English unit of land `area` (m² or ft²).
```Julia
julia> acre(Metric) # m²
$(acre(Metric))

julia> acre(English) # ft²
$(acre(English))

julia> acre(Survey) # ftUS²
$(acre(Survey))
```
""" acre

@doc """
$(unitext(:surveyacre,"area(𝟐^3*𝟑^2*𝟓*𝟏𝟏^2,U,Survey)"))

Survey unit of land `area` (m² or ft²).
```Julia
julia> surveyacre(Metric) # m²
$(surveyacre(Metric))

julia> surveyacre(English) # ft²
$(surveyacre(English))

julia> surveyacre(Survey) # ftUS²
$(surveyacre(Survey))
```
""" surveyacre

# volume

@doc """
$(unitext(:gallon,"volume(𝟕*𝟏𝟏/𝟐^2,U,English)"))

Unit of `volume` derived from the US liquid `gallon` in cubic inches (m³ or ft³).
```Julia
julia> gallon(Metric) # m³
$(gallon(Metric))

julia> gallon(CGS) # cm³
$(gallon(CGS))

julia> gallon(IPS) # in³
$(gallon(IPS))
```
""" gallon, gal

@doc """
$(unitext(:liter,"volume(𝟏𝟎^-3,U,Metric)"))

Unit of `volume` derived from 1 cubic decimeter (m³ or ft³).
```Julia
julia> liter(Metric) # m³
$(liter(Metric))

julia> liter(CGS) # cm³
$(liter(CGS))

julia> liter(IPS) # in³
$(liter(IPS))
```
""" liter

@doc """
$(unitext(:quart,"gallon(U)/𝟐^2"))

English unit of `volume` (m³ or ft³).
```Julia
julia> quart(Metric) # m³
$(quart(Metric))

julia> quart(CGS) # cm³
$(quart(CGS))

julia> quart(IPS) # in³
$(quart(IPS))
```
""" quart

@doc """
$(unitext(:pint,"quart(U)/𝟐"))

English unit of `volume` (m³ or ft³).
```Julia
julia> pint(Metric) # m³
$(pint(Metric))

julia> pint(CGS) # cm³
$(pint(CGS))

julia> pint(IPS) # in³
$(pint(IPS))
```
""" pint

@doc """
$(unitext(:cup,"pint(U)/𝟐"))

English unit of `volume` (m³ or ft³).
```Julia
julia> cup(Metric) # m³
$(cup(Metric))

julia> cup(CGS) # cm³
$(cup(CGS))

julia> cup(IPS) # in³
$(cup(IPS))
```
""" cup

@doc """
$(unitext(:fluidounce,"cup(U)/𝟐^3"))

English unit of `volume` (m³ or ft³).
```Julia
julia> fluidounce(Metric) # m³
$(fluidounce(Metric))

julia> fluidounce(CGS) # cm³
$(fluidounce(CGS))

julia> fluidounce(IPS) # in³
$(fluidounce(IPS))
```
""" fluidounce

@doc """
$(unitext(:teaspoon,"𝟓*milli*liter(U)"))

Measuring `teaspoon` unit of `volume` (m³ or ft³).
```Julia
julia> teaspoon(Metric) # m³
$(teaspoon(Metric))

julia> teaspoon(CGS) # cm³
$(teaspoon(CGS))

julia> teaspoon(IPS) # in³
$(teaspoon(IPS))
```
""" teaspoon

@doc """
$(unitext(:tablespoon,"𝟑*teaspoon(U)"))

Measuring `tablespoon` unit of `volume` (m³ or ft³).
```Julia
julia> tablespoon(Metric) # m³
$(tablespoon(Metric))

julia> tablespoon(CGS) # cm³
$(tablespoon(CGS))

julia> tablespoon(IPS) # in³
$(tablespoon(IPS))
```
""" tablespoon

# speed

@doc """
$(unitext(:bubnoff,"meter(U)/year(U)"))

Reference unit of erosion `speed` (m⋅s⁻¹ or ft⋅s⁻¹).
```Julia
julia> bubnoff(CGS) # cm⋅s⁻¹
$(bubnoff(CGS))

julia> bubnoff(English) # ft⋅s⁻¹
$(bubnoff(English))
```
""" bubnoff

@doc """
$(unitext(:ips,"inch(U)/second(U)"))

Inch per second unit of `speed` (m⋅s⁻¹ or ft⋅s⁻¹).
```Julia
julia> ips(CGS) # cm⋅s⁻¹
$(ips(CGS))

julia> ips(English) # ft⋅s⁻¹
$(ips(English))
```
""" ips

@doc """
$(unitext(:fps,"feet(U)/second(U)"))

Feet per second unit of `speed` (m⋅s⁻¹ or ft⋅s⁻¹).
```Julia
julia> fps(Metric) # m⋅s⁻¹
$(fps(Metric))

julia> fps(KKH) # km⋅h⁻¹
$(fps(KKH))

julia> fps(MPH) # mi⋅h⁻¹
$(fps(MPH))
```
""" fps

@doc """
$(unitext(:fpm,"feet(U)/minute(U)"))

Feet per minute unit of `speed` (m⋅s⁻¹ or ft⋅s⁻¹).
```Julia
julia> fpm(CGS) # cm⋅s⁻¹
$(fpm(CGS))

julia> fpm(IPS) # in⋅s⁻¹
$(fpm(IPS))

julia> fpm(English) # ft⋅s⁻¹
$(fpm(English))
```
""" fpm

@doc """
$(unitext(:ms,"meter(U)/second(U)"))

Meters per second unit of `speed` (m⋅s⁻¹ or ft⋅s⁻¹).
```Julia
julia> ms(KKH) # km⋅h⁻¹
$(ms(KKH))

julia> ms(MPH) # mi⋅h⁻¹
$(ms(MPH))

julia> ms(Nautical) # nm⋅h⁻¹
$(ms(Nautical))
```
""" ms

@doc """
$(unitext(:kmh,"kilo(U)*meter(U)/hour(U)"))

Kilometers per hour unit of `speed` (m⋅s⁻¹ or ft⋅s⁻¹).
```Julia
julia> kmh(Metric) # m⋅s⁻¹
$(kmh(Metric))

julia> kmh(MPH) # mi⋅h⁻¹
$(kmh(MPH))

julia> kmh(Nautical) # nm⋅h⁻¹
$(kmh(Nautical))
```
""" kmh

@doc """
$(unitext(:mph,"mile(U)/hour(U)"))

Miles per hour unit of `speed` (m⋅s⁻¹ or ft⋅s⁻¹).
```Julia
julia> mph(Metric) # m⋅s⁻¹
$(mph(Metric))

julia> mph(KKH) # km⋅h⁻¹
$(mph(KKH))

julia> mph(Nautical) # nm⋅h⁻¹
$(mph(Nautical))
```
""" mph

@doc """
$(unitext(:knot,"nauticalmile(U)/hour(U)"))

Nautical miles per hour unit of `speed` (m⋅s⁻¹ or ft⋅s⁻¹).
```Julia
julia> knot(Metric) # m⋅s⁻¹
$(knot(Metric))

julia> knot(KKH) # km⋅h⁻¹
$(knot(KKH))

julia> knot(MPH) # mi⋅h⁻¹
$(knot(MPH))
```
""" knot

@doc """
$(unitext(:mps,"mile(U)/second(U)"))

Miles per second unit of `speed` (m⋅s⁻¹ or ft⋅s⁻¹).
```Julia
julia> mps(KKH) # km⋅h⁻¹
$(mps(KKH))

julia> mps(MPH) # mi⋅h⁻¹
$(mps(MPH))

julia> mps(Nautical) # nm⋅h⁻¹
$(mps(Nautical))
```
""" mps

# mass

@doc """
$(unitext(:grain,"milli(U)*pound(U)/𝟕"))

Ideal `grain` seed of cereal, unit of `mass` (kg or lb).
```Julia
julia> grain(Metric) # kg
$(grain(Metric))

julia> grain(CGS) # g
$(grain(CGS))

julia> grain(English) # lb
$(grain(English))
```
""" grain

@doc """
$(unitext(:gram,"mass(𝟏,U,Gauss)"))

Metric `gram` unit of `mass` (kg or lb).
```Julia
julia> gram(Metric) # kg
$(gram(Metric))

julia> gram(CGS) # g
$(gram(CGS))

julia> gram(English) # lb
$(gram(English))

julia> gram(British) # slug
$(gram(British))

julia> gram(GravitationalMetric) # hyl
$(gram(GravitationalMetric))
```
""" gram

@doc """
$(unitext(:earthgram,"mass(milli,U,Meridian)"))

Meridian `gram` unit of `mass` based on `earthmeter` (kg or lb).
```Julia
julia> earthgram(Meridian) # keg
$(earthgram(Meridian))

julia> earthgram(CGS) # g
$(earthgram(CGS))

julia> earthgram(English) # lb
$(earthgram(English))

julia> earthgram(British) # slug
$(earthgram(British))

julia> earthgram(GravitationalMetric) # hyl
$(earthgram(GravitationalMetric))
```
""" earthgram

@doc """
$(unitext(:kilogram,"mass(𝟏,U,Metric)"))

Metric `kilogram` unit of `mass` (kg or lb).
```Julia
julia> kilogram(Metric) # kg
$(kilogram(Metric))

julia> kilogram(CGS) # g
$(kilogram(CGS))

julia> kilogram(English) # lb
$(kilogram(English))

julia> kilogram(British) # slug
$(kilogram(British))

julia> kilogram(GravitationalMetric) # hyl
$(kilogram(GravitationalMetric))
```
""" kilogram

@doc """
$(unitext(:tonne,"mass(𝟏,U,MTS)"))

Metric `tonne` unit of `mass` (kg or lb).
```Julia
julia> tonne(Metric) # kg
$(tonne(Metric))

julia> tonne(MTS) # t
$(tonne(MTS))

julia> tonne(English) # lb
$(tonne(English))

julia> tonne(British) # slug
$(tonne(British))

julia> tonne(GravitationalMetric) # hyl
$(tonne(GravitationalMetric))
```
""" tonne

@doc """
$(unitext(:ton,"mass(𝟐*kilo,U,English)"))

English `ton` unit of `mass` (kg or lb).
```Julia
julia> ton(Metric) # kg
$(ton(Metric))

julia> ton(MTS) # t
$(ton(MTS))

julia> ton(English) # lb
$(ton(English))

julia> ton(British) # slug
$(ton(British))

julia> ton(GravitationalMetric) # hyl
$(ton(GravitationalMetric))
```
""" ton

@doc """
$(unitext(:pound,"mass(𝟏,U,English)"))

English `pound` unit of `mass` (kg or lb).
```Julia
julia> pound(Metric) # kg
$(pound(Metric))

julia> pound(CGS) # g
$(pound(CGS))

julia> pound(English) # lb
$(pound(English))

julia> pound(British) # slug
$(pound(British))

julia> pound(GravitationalMetric) # hyl
$(pound(GravitationalMetric))
```
""" pound

@doc """
$(unitext(:ounce,"pound(U)/𝟐^4"))

English `ounce` unit of `mass` (kg or lb).
```Julia
julia> ounce(Metric) # kg
$(ounce(Metric))

julia> ounce(CGS) # g
$(ounce(CGS))

julia> ounce(English) # lb
$(ounce(English))

julia> ounce(British) # slug
$(ounce(British))

julia> ounce(GravitationalMetric) # hyl
$(ounce(GravitationalMetric))
```
""" ounce

@doc """
$(unitext(:slug,"mass(𝟏,U,British)"))

British gravitational `slug` unit of `mass` (kg or lb).
```Julia
julia> slug(Metric) # kg
$(slug(Metric))

julia> slug(CGS) # g
$(slug(CGS))

julia> slug(English) # lb
$(slug(English))

julia> slug(British) # slug
$(slug(British))

julia> slug(GravitationalMetric) # hyl
$(slug(GravitationalMetric))
```
""" slug

@doc """
$(unitext(:slinch,"mass(𝟏,U,IPS)"))

British gravitational `slinch` unit of `mass` (kg or lb).
```Julia
julia> slinch(Metric) # kg
$(slinch(Metric))

julia> slinch(CGS) # g
$(slinch(CGS))

julia> slinch(English) # lb
$(slinch(English))

julia> slinch(British) # slug
$(slinch(British))

julia> slinch(GravitationalMetric) # hyl
$(slinch(GravitationalMetric))
```
""" slinch

@doc """
$(unitext(:hyl,"mass(𝟏,U,GravitationalMetric)"))

Gravitational Metric `hyl` unit of `mass` (kg or lb).
```Julia
julia> hyl(Metric) # kg
$(hyl(Metric))

julia> hyl(CGS) # g
$(hyl(CGS))

julia> hyl(English) # lb
$(hyl(English))

julia> hyl(British) # slug
$(hyl(British))

julia> hyl(GravitationalMetric) # hyl
$(hyl(GravitationalMetric))
```
""" hyl

# force

@doc """
$(unitext(:dyne,"force(𝟏,U,Gauss)"))

Historical `dyne` unit of `force` (N or lb).
```Julia
julia> dyne(Metric) # N
$(dyne(Metric))

julia> dyne(CGS) # dyn
$(dyne(CGS))

julia> dyne(English) # lb
$(dyne(English))

julia> dyne(FPS) # pdl
$(dyne(FPS))

julia> dyne(MetricEngineering) # kp
$(dyne(MetricEngineering))
```
""" dyne

@doc """
$(unitext(:newton,"force(𝟏,U,Metric)"))

Metric `newton` unit of `force` (N or lb).
```Julia
julia> newton(Metric) # N
$(newton(Metric))

julia> newton(CGS) # dyn
$(newton(CGS))

julia> newton(English) # lb
$(newton(English))

julia> newton(FPS) # pdl
$(newton(FPS))

julia> newton(MetricEngineering) # kp
$(newton(MetricEngineering))
```
""" newton

@doc """
$(unitext(:poundal,"force(𝟏,U,FPS)"))

Absolute English `poundal` unit of `force` (N or lb).
```Julia
julia> poundal(Metric) # N
$(poundal(Metric))

julia> poundal(CGS) # dyn
$(poundal(CGS))

julia> poundal(English) # lb
$(poundal(English))

julia> poundal(FPS) # pdl
$(poundal(FPS))

julia> poundal(MetricEngineering) # kp
$(poundal(MetricEngineering))
```
""" poundal

@doc """
    kilopond(U::UnitSystem) = force(𝟏,U,MetricEngineering)

Gravitational `kilopond` unit of `force` used in engineering systems (N or lb).
```Julia
julia> kilopond(Metric) # N
$(kilopond(Metric))

julia> kilopond(CGS) # dyn
$(kilopond(CGS))

julia> kilopond(English) # lb
$(kilopond(English))

julia> kilopond(FPS) # pdl
$(kilopond(FPS))

julia> kilopond(MetricEngineering) # kp
$(kilopond(MetricEngineering))
```
""" kilopond

@doc """
$(unitext(:poundforce,"force(𝟏,U,English)"))

English `poundforce` unit of `force` used in engineering systems (N or lb).
```Julia
julia> poundforce(Metric) # N
$(poundforce(Metric))

julia> poundforce(CGS) # dyn
$(poundforce(CGS))

julia> poundforce(English) # lb
$(poundforce(English))

julia> poundforce(FPS) # pdl
$(poundforce(FPS))

julia> poundforce(MetricEngineering) # kp
$(poundforce(MetricEngineering))
```
""" poundforce

# pressure

@doc """
$(unitext(:pascal,"pressure(𝟏,U,Metric)"))

Metric unit of `pressure` (Pa or lb⋅ft⁻²).
```Julia
julia> pascal(Metric) # Pa
$(pascal(Metric))

julia> pascal(English) # lb⋅ft⁻²
$(pascal(English))

julia> pascal(IPS) # lb⋅in⁻²
$(pascal(IPS))
```
""" pascal

@doc """
$(unitext(:bar,"pressure(hecto*kilo,U,Metric)"))

Reference unit of `pressure` (Pa or lb⋅ft⁻²).
```Julia
julia> bar(Metric) # Pa
$(bar(Metric))

julia> bar(English) # lb⋅ft⁻²
$(bar(English))

julia> bar(IPS) # lb⋅in⁻²
$(bar(IPS))
```
""" bar

@doc """
$(unitext(:barye,"pressure(𝟏,U,Gauss)"))

Historical unit of `pressure` (Pa or lb⋅ft⁻²).
```Julia
julia> barye(Metric) # Pa
$(barye(Metric))

julia> barye(English) # lb⋅ft⁻²
$(barye(English))

julia> barye(IPS) # lb⋅in⁻²
$(barye(IPS))
```
""" barye

@doc """
$(unitext(:psi,"pressure(𝟏,U,IPS)"))

English unit of `pressure` (Pa or lb⋅ft⁻²).
```Julia
julia> psi(Metric) # Pa
$(psi(Metric))

julia> psi(English) # lb⋅ft⁻²
$(psi(English))

julia> psi(IPS) # lb⋅in⁻²
$(psi(IPS))
```
""" psi

@doc """
$(unitext(:technicalatmosphere,"kilopond(U)/(centi*meter(U))^2"))

Gravitational Metric unit of `pressure` (Pa or lb⋅ft⁻²).
```Julia
julia> technicalatmosphere(Metric) # Pa
$(technicalatmosphere(Metric))

julia> technicalatmosphere(English) # lb⋅ft⁻²
$(technicalatmosphere(English))

julia> technicalatmosphere(IPS) # lb⋅in⁻²
$(technicalatmosphere(IPS))
```
""" technicalatmosphere

@doc """
$(unitext(:atmosphere,"pressure($atm,U)"))

Standard `pressure` reference level of one atmosphere `atm` (Pa or lb⋅ft⁻²).
```Julia
julia> atmosphere(Metric) # Pa
$(atmosphere(Metric))

julia> atmosphere(English) # lb⋅ft⁻²
$(atmosphere(English))

julia> atmosphere(IPS) # lb⋅in⁻²
$(atmosphere(IPS))
```
""" atmosphere, atm

@doc """
$(unitext(:inchmercury,"pressure(inHg,U,Metric)"))

Unit of `pressure` exerted by 1 inch of mercury at standard atmospheric conditions.
```Julia
juila> inchmercury(Metric) # Pa
$(inchmercury(Metric))

julia> inchmercury(English) # lb⋅ft⁻²
$(inchmercury(English))

julia> inchmercury(IPS) # lb⋅in⁻²
$(inchmercury(IPS))
```
""" inchmercury, inHg

@doc """
$(unitext(:torr,"pressure(atm/𝟐^3/𝟓/𝟏𝟗,U,Metric)"))

Unit of `pressure` exerted by 1 mm of mercury at standard atmospheric conditions.
```Julia
juila> torr(Metric) # Pa
$(torr(Metric))

julia> torr(English) # lb⋅ft⁻²
$(torr(English))

julia> torr(IPS) # lb⋅in⁻²
$(torr(IPS))
```
""" torr

# energy

@doc """
$(unitext(:erg,"energy(𝟏,U,Gauss)"))

Historical unit of `energy` (J or lb⋅ft).
```Julia
julia> erg(Metric) # J
$(erg(Metric))

julia> erg(CGS) # erg
$(erg(CGS))

julia> erg(British) # lb⋅ft
$(erg(British))
```
""" erg

@doc """
$(unitext(:joule,"energy(𝟏,U,Metric)"))

Metric unit of `energy` (J or lb⋅ft).
```Julia
julia> joule(Metric) # J
$(joule(Metric))

julia> joule(CGS) # erg
$(joule(CGS))

julia> joule(British) # lb⋅ft
$(joule(British))
```
""" joule

@doc """
$(unitext(:tontnt,"giga*calorie(U)"))

Ton TNT equivalent reference unit of `energy` (J or lb⋅ft).
```Julia
julia> tontnt(Metric) # J
$(tontnt(Metric))

julia> tontnt(CGS) # erg
$(tontnt(CGS))

julia> tontnt(British) # lb⋅ft
$(tontnt(British))
```
""" tontnt

@doc """
$(unitext(:gasgallon,"𝟐*𝟑*𝟏𝟗*kilo*thermalunit(U)"))

Gasoline gallon equivalent reference unit of `energy` (J or lb⋅ft).
```Julia
julia> gasgallon(Metric) # J
$(gasgallon(Metric))

julia> gasgallon(CGS) # erg
$(gasgallon(CGS))

julia> gasgallon(British) # lb⋅ft
$(gasgallon(British))
```
""" gasgallon

@doc """
$(unitext(:footpound,"poundforce(U)*foot(U)"))

English unit of `energy` in gravitational and engineering systems (J or lb⋅ft).
```Julia
julia> footpound(Metric) # J
$(footpound(Metric))

julia> footpound(CGS) # erg
$(footpound(CGS))

julia> footpound(British) # lb⋅ft
$(footpound(British))
```
""" footpound

@doc """
$(unitext(:kilocalorie,"energy(𝟐^5*𝟓^4*𝟑^2/𝟒𝟑,U,International)"))

Heat energy required to raise 1 kg of water by 1 Kelvin (`kcal`) in `International` units.
```Julia
julia> kilocalorie(International) # J
$(kilocalorie(International))

julia> kilocalorie(Metric) # J
$(kilocalorie(Metric))

julia> kilocalorie(English) # ft⋅lb
$(kilocalorie(English))
```
""" kilocalorie, kcal

@doc """
$(unitext(:calorie,"kilocalorie(U)/𝟐^3/𝟓^3"))

Heat energy required to raise 1 g of water by 1 Kelvin (`cal`) in `International` units.
```Julia
julia> calorie(International) # J
$(calorie(International))

julia> calorie(Metric) # J
$(calorie(Metric))

julia> calorie(English) # ft⋅lb
$(calorie(English))
```
""" calorie, cal

@doc """
$(unitext(:meancalorie,"energy(𝟐^2*𝟓*𝟑^2/𝟒𝟑,U,InternationalMean)"))

Heat energy required to raise 1 g of water by 1 Kelvin (`cal`) in `InternationalMean` units.
```Julia
julia> meancalorie(InternationalMean) # J
$(meancalorie(InternationalMean))

julia> meancalorie(Metric) # J
$(meancalorie(Metric))

julia> meancalorie(English) # ft⋅lb
$(meancalorie(English))
```
""" meancalorie

@doc """
$(unitext(:earthcalorie,"calorie(U)*(sqrt(g₀/GME)/τ)^3*𝟐^27*𝟓^21"))

Heat energy required to raise 1 `earthgram` of water by 1 `kelvin` in `Meridian` units.
```Julia
julia> earthcalorie(Meridian) # J
$(earthcalorie(Meridian))

julia> earthcalorie(Metric) # J
$(earthcalorie(Metric))

julia> earthcalorie(British) # ft⋅lb
$(earthcalorie(British))
```
""" earthcalorie

@doc """
$(unitext(:thermalunit,"kilocalorie(U)*𝟑^2/𝟓/lb"))

Heat energy required to raise 1 lb of water by 1 Rankine (`BTU`) in `International` units.
```Julia
julia> thermalunit(British) # J
$(thermalunit(British))

julia> thermalunit(International) # J
$(thermalunit(International))

julia> thermalunit(Metric) # ft⋅lb
$(thermalunit(Metric))
```
""" thermalunit, BTU, BTUJ, BTUftlb

@doc """
$(unitext(:electronvolt,"elementarycharge(U)*volt(U)"))

Unit of `energy` gained by a rest electron accelerated by 1 `volt` in vacuum (J or lb⋅ft).
```Julia
julia> electronvolt(SI2019) # J
$(electronvolt(SI2019))

julia> electronvolt(SI2019)/lightspeed(SI2019) # kg⋅m⋅s⁻¹
$(electronvolt(SI2019)/lightspeed(SI2019))

julia> electronvolt(SI2019)/lightspeed(SI2019)^2 # kg
$(electronvolt(SI2019)/lightspeed(SI2019)^2)

julia> electronvolt(SI2019)/planck(SI2019)/lightspeed(SI2019) # m⁻¹
$(electronvolt(SI2019)/planck(SI2019)/lightspeed(SI2019))

julia> electronvolt(SI2019)/boltzmann(SI2019) # K
$(electronvolt(SI2019)/boltzmann(SI2019))
```
""" electronvolt, eV

# power

@doc """
$(unitext(:watt,"power(𝟏,U,Metric)"))

Metric `watt` unit of `power` (W or lb⋅ft⋅s⁻¹).
```Julia
julia> watt(Metric) # W
$(watt(Metric))

julia> watt(English) # lb⋅ft⋅s⁻¹
$(watt(English))

julia> watt(MetricEngineering) # kgf⋅m⋅s⁻¹
$(watt(MetricEngineering))
```
""" watt

@doc """
$(unitext(:tonsrefrigeration,"frequency(𝟐*𝟓/𝟑,U,Metric)*thermalunit(U)"))

Unit of `power` derived from melting of 1 short ton of ice in 24 hours.
```Julia
julia> tonsrefrigeration(British) # lb⋅ft⋅s⁻¹
$(tonsrefrigeration(British))

julia> tonsrefrigeration(Metric) # W
$(tonsrefrigeration(Metric))

julia> tonsrefrigeration(MetricEngineering) # kgf⋅m⋅s⁻¹
$(tonsrefrigeration(MetricEngineering))
```
""" tonsrefrigeration

@doc """
$(unitext(:boilerhorsepower,"frequency(1339/𝟐^4/𝟑^2,U,Metric)*thermalunit(U)"))

Unit of `power` derived from evaporating 34.5 lb of boiling water in 1 hour.
```Julia
julia> boilerhorsepower(British) # lb⋅ft⋅s⁻¹
$(boilerhorsepower(British))

julia> boilerhorsepower(Metric) # W
$(boilerhorsepower(Metric))

julia> boilerhorsepower(MetricEngineering) # kgf⋅m⋅s⁻¹
$(boilerhorsepower(MetricEngineering))
```
""" boilerhorsepower

@doc """
$(unitext(:horsepower,"power(𝟐*𝟓^2*𝟏𝟏,U,British)"))

Unit of `power` derived from raising 550 lb by 1 ft in 1  in 1 s.
```Julia
julia> horsepower(British) # lb⋅ft⋅s⁻¹
$(horsepower(British))

julia> horsepower(Metric) # W
$(horsepower(Metric))

julia> horsepower(MetricEngineering) # kgf⋅m⋅s⁻¹
$(horsepower(MetricEngineering))
```
""" horsepower, HP

@doc """
$(unitext(:horsepowerwatt,"power(𝟐^4*𝟑^3/𝟓*τ,U,British)"))

Unit of `power` derived from Watt's exact original horse power estimate.
```Julia
julia> horsepowerwatt(British) # lb⋅ft⋅s⁻¹
$(horsepowerwatt(British))

julia> horsepowerwatt(Metric) # W
$(horsepowerwatt(Metric))

julia> horsepowerwatt(MetricEngineering) # kgf⋅m⋅s⁻¹
$(horsepowerwatt(MetricEngineering))
```
""" horsepowerwatt

@doc """
$(unitext(:horsepowermetric,"power(𝟑*𝟓^2,U,GravitationalMetric)"))

Unit of `power` derived from raising 75 kp by 1 m in 1  in 1 s.
```Julia
julia> horsepowermetric(British) # lb⋅ft⋅s⁻¹
$(horsepowermetric(British))

julia> horsepowermetric(Metric) # W
$(horsepowermetric(Metric))

julia> horsepowermetric(MetricEngineering) # kgf⋅m⋅s⁻¹
$(horsepowermetric(MetricEngineering))
```
""" horsepowermetric

@doc """
$(unitext(:electricalhorsepower,"power(746,U,Metric)"))

Unit of `power` for electrical motors in the United States.
```Julia
julia> electricalhorsepower(British) # lb⋅ft⋅s⁻¹
$(electricalhorsepower(British))

julia> electricalhorsepower(Metric) # W
$(electricalhorsepower(Metric))

julia> electricalhorsepower(MetricEngineering) # kgf⋅m⋅s⁻¹
$(electricalhorsepower(MetricEngineering))
```
""" electricalhorsepower

# electromagnetic

@doc """
$(unitext(:coulomb,"charge(𝟏,U,Metric)"))

Metric unit of `charge` (C).
```Julia
julia> coulomb(Metric) # C
$(coulomb(Metric))

julia> coulomb(EMU) # abC
$(coulomb(EMU))

julia> coulomb(ESU) # statC
$(coulomb(ESU))
```
""" coulomb

@doc """
$(unitext(:ampere,"current(𝟏,U,Metric)"))

Metric unit of `current` (C⋅s⁻¹).
```Julia
julia> ampere(Metric) # C⋅s⁻¹
$(ampere(Metric))

julia> ampere(EMU) # abC⋅s⁻¹
$(ampere(EMU))

julia> ampere(ESU) # statC⋅s⁻¹
$(ampere(ESU))
```
""" ampere

@doc """
$(unitext(:volt,"electricpotential(𝟏,U,Metric)"))

Metric unit of `electricpotential` (V).
```Julia
julia> volt(Metric) # V
$(volt(Metric))

julia> volt(EMU) # abV
$(volt(EMU))

julia> volt(ESU) # statV
$(volt(ESU))
```
""" volt

@doc """
$(unitext(:henry,"inductance(𝟏,U,Metric)"))

Metric unit of `inductance` (H).
```Julia
julia> henry(Metric) # H
$(henry(Metric))

julia> henry(EMU) # abH
$(henry(EMU))

julia> henry(ESU) # statH
$(henry(ESU))
```
""" henry

@doc """
$(unitext(:ohm,"resistance(𝟏,U,Metric)"))

Metric unit of `resistance` (Ω).
```Julia
julia> ohm(Metric) # Ω
$(ohm(Metric))

julia> ohm(EMU) # abΩ
$(ohm(EMU))

julia> ohm(ESU) # statΩ
$(ohm(ESU))
```
""" ohm

@doc """
$(unitext(:siemens,"conductance(𝟏,U,Metric)"))

Metric unit of `conductance` (S).
```Julia
julia> siemens(Metric) # S
$(siemens(Metric))

julia> siemens(EMU) # abS
$(siemens(EMU))

julia> siemens(ESU) # statS
$(siemens(ESU))
```
""" siemens

@doc """
$(unitext(:farad,"capacitance(𝟏,U,Metric)"))

Metric unit of `capacitance` (F).
```Julia
julia> farad(Metric) # F
$(farad(Metric))

julia> farad(EMU) # abF
$(farad(EMU))

julia> farad(ESU) # statF
$(farad(ESU))
```
""" farad

@doc """
$(unitext(:weber,"magneticflux(𝟏,U,Metric)"))

Metric unit of `magneticflux` (Wb).
```Julia
julia> weber(Metric) # Wb
$(weber(Metric))

julia> weber(EMU) # Mx
$(weber(EMU))

julia> weber(ESU) # statWb
$(weber(ESU))
```
""" weber

@doc """
$(unitext(:tesla,"magneticfluxdensity(𝟏,U,Metric)"))

Metric unit of `magneticfluxdensity` (T).
```Julia
julia> tesla(Metric) # T
$(tesla(Metric))

julia> tesla(EMU) # G
$(tesla(EMU))

julia> tesla(ESU) # statT
$(tesla(ESU))
```
""" tesla

@doc """
$(unitext(:abcoulomb,"charge(𝟏,U,EMU)"))

Electromagnetic unit of `charge` (C).
```Julia
julia> abcoulomb(Metric) # C
$(abcoulomb(Metric))

julia> abcoulomb(EMU) # abC
$(abcoulomb(EMU))

julia> abcoulomb(ESU) # statC
$(abcoulomb(ESU))
```
""" abcoulomb

@doc """
$(unitext(:abampere,"current(𝟏,U,EMU)"))

Electromagnetic unit of `current` (C⋅s⁻¹).
```Julia
julia> abampere(Metric) # C⋅s⁻¹
$(abampere(Metric))

julia> abampere(EMU) # abC⋅s⁻¹
$(abampere(EMU))

julia> abampere(ESU) # statC⋅s⁻¹
$(abampere(ESU))
```
""" abampere

@doc """
$(unitext(:abvolt,"electricpotential(𝟏,U,EMU)"))

Electromagnetic unit of `electricpotential` (V).
```Julia
julia> abvolt(Metric) # V
$(abvolt(Metric))

julia> abvolt(EMU) # abV
$(abvolt(EMU))

julia> abvolt(ESU) # statV
$(abvolt(ESU))
```
""" abvolt

@doc """
$(unitext(:abhenry,"inductance(𝟏,U,EMU)"))

Electromagnetic unit of `inductance` (H).
```Julia
julia> abhenry(Metric) # H
$(abhenry(Metric))

julia> abhenry(EMU) # abH
$(abhenry(EMU))

julia> abhenry(ESU) # statH
$(abhenry(ESU))
```
""" abhenry

@doc """
$(unitext(:abohm,"resistance(𝟏,U,EMU)"))

Electromagnetic unit of `resistance` (Ω).
```Julia
julia> abohm(Metric) # Ω
$(abohm(Metric))

julia> abohm(EMU) # abΩ
$(abohm(EMU))

julia> abohm(ESU) # statΩ
$(abohm(ESU))
```
""" abohm

@doc """
$(unitext(:abmho,"conductance(𝟏,U,EMU)"))

Electromagnetic unit of `conductance` (S).
```Julia
julia> abmho(Metric) # S
$(abmho(Metric))

julia> abmho(EMU) # abS
$(abmho(EMU))

julia> abmho(ESU) # statS
$(abmho(ESU))
```
""" abmho

@doc """
$(unitext(:abfarad,"capacitance(𝟏,U,EMU)"))

Electromagnetic unit of `capacitance` (F).
```Julia
julia> abfarad(Metric) # F
$(abfarad(Metric))

julia> abfarad(EMU) # abF
$(abfarad(EMU))

julia> abfarad(ESU) # statF
$(abfarad(ESU))
```
""" abfarad

@doc """
$(unitext(:maxwell,"magneticflux(𝟏,U,EMU)"))

Electromagnetic unit of `magneticflux` (Wb).
```Julia
julia> maxwell(Metric) # Wb
$(maxwell(Metric))

julia> maxwell(EMU) # Mx
$(maxwell(EMU))

julia> maxwell(ESU) # statWb
$(maxwell(ESU))
```
""" maxwell

@doc """
$(unitext(:gauss,"magneticfluxdensity(𝟏,U,EMU)"))

Electromagnetic unit of `magneticfluxdensity` (T).
```Julia
julia> gauss(Metric) # T
$(gauss(Metric))

julia> gauss(EMU) # G
$(gauss(EMU))

julia> gauss(ESU) # statT
$(gauss(ESU))
```
""" gauss

@doc """
$(unitext(:oersted,"magneticfield(𝟏,U,EMU)"))

Electromagnetic unit of `magneticfield` (Oe).
```Julia
julia> oersted(Metric) # A⋅m⁻¹
$(oersted(Metric))

julia> oersted(EMU) # Oe
$(oersted(EMU))

julia> oersted(ESU) # statA⋅cm⁻¹
$(oersted(ESU))
```
""" oersted

@doc """
$(unitext(:gilbert,"abampere(U)/𝟐/turn(U)"))

Electromagnetic unit of magnetization (Gb).
```Julia
julia> gilbert(Metric) # A⋅rad⁻¹
$(gilbert(Metric))

julia> gilbert(EMU) # Gb
$(gilbert(EMU))

julia> gilbert(ESU) # statA⋅rad⁻¹
$(gilbert(ESU))
```
""" gilbert

@doc """
$(unitext(:statcoulomb,"charge(𝟏,U,ESU)"))

Electrostatic unit of `charge` (C).
```Julia
julia> statcoulomb(Metric) # C
$(statcoulomb(Metric))

julia> statcoulomb(EMU) # abC
$(statcoulomb(EMU))

julia> statcoulomb(ESU) # statC
$(statcoulomb(ESU))
```
""" statcoulomb

@doc """
$(unitext(:statampere,"current(𝟏,U,ESU)"))

Electrostatic unit of `current` (C⋅s⁻¹).
```Julia
julia> statampere(Metric) # C⋅s⁻¹
$(statampere(Metric))

julia> statampere(EMU) # abC⋅s⁻¹
$(statampere(EMU))

julia> statampere(ESU) # statC⋅s⁻¹
$(statampere(ESU))
```
""" statampere

@doc """
$(unitext(:statvolt,"electricpotential(𝟏,U,ESU)"))

Electrostatic unit of `electricpotential` (V).
```Julia
julia> statvolt(Metric) # V
$(statvolt(Metric))

julia> statvolt(EMU) # abV
$(statvolt(EMU))

julia> statvolt(ESU) # statV
$(statvolt(ESU))
```
""" statvolt

@doc """
$(unitext(:stathenry,"inductance(𝟏,U,ESU)"))

Electrostatic unit of `inductance` (H).
```Julia
julia> stathenry(Metric) # H
$(stathenry(Metric))

julia> stathenry(EMU) # abH
$(stathenry(EMU))

julia> stathenry(ESU) # statH
$(stathenry(ESU))
```
""" stathenry

@doc """
$(unitext(:statohm,"resistance(𝟏,U,ESU)"))

Electrostatic unit of `resistance` (Ω).
```Julia
julia> statohm(Metric) # Ω
$(statohm(Metric))

julia> statohm(EMU) # abΩ
$(statohm(EMU))

julia> statohm(ESU) # statΩ
$(statohm(ESU))
```
""" statohm

@doc """
$(unitext(:statmho,"conductance(𝟏,U,ESU)"))

Electrostatic unit of `conductance` (S).
```Julia
julia> statmho(Metric) # S
$(statmho(Metric))

julia> statmho(EMU) # abS
$(statmho(EMU))

julia> statmho(ESU) # statS
$(statmho(ESU))
```
""" statmho

@doc """
$(unitext(:statfarad,"capacitance(𝟏,U,ESU)"))

Electrostatic unit of `capacitance` (F).
```Julia
julia> statfarad(Metric) # F
$(statfarad(Metric))

julia> statfarad(EMU) # abF
$(statfarad(EMU))

julia> statfarad(ESU) # statF
$(statfarad(ESU))
```
""" statfarad

@doc """
$(unitext(:statweber,"magneticflux(𝟏,U,ESU)"))

Electrostatic unit of `magneticflux` (Wb).
```Julia
julia> statweber(Metric) # Wb
$(statweber(Metric))

julia> statweber(EMU) # Mx
$(statweber(EMU))

julia> statweber(ESU) # statWb
$(statweber(ESU))
```
""" statweber

@doc """
$(unitext(:stattesla,"magneticfluxdensity(𝟏,U,ESU)"))

Electrostatic unit of `magneticfluxdensity` (T).
```Julia
julia> stattesla(Metric) # T
$(stattesla(Metric))

julia> stattesla(EMU) # G
$(stattesla(EMU))

julia> stattesla(ESU) # statT
$(stattesla(ESU))
```
""" stattesla

@doc """
$(unitext(:earthcoulomb,"charge(𝟏,U,Meridian)"))

Meridian unit of `charge` (C).
```Julia
julia> earthcoulomb(Metric) # C
$(earthcoulomb(Metric))

julia> earthcoulomb(EMU) # abC
$(earthcoulomb(EMU))

julia> earthcoulomb(ESU) # statC
$(earthcoulomb(ESU))
```
""" earthcoulomb

# temperature

@doc """
$(unitext(:kelvin,"temperature(𝟏,U,Metric)"))

Metric unit of `temperature` (K or °R).
```Julia
julia> kelvin(Metric) # K
$(kelvin(Metric))

julia> kelvin(SI2019) # K
$(kelvin(SI2019))

julia> kelvin(British) # °R
$(kelvin(British))
```
""" kelvin

@doc """
$(unitext(:rankine,"temperature(𝟏,U,English)"))

English unit of `temperature` (K or °R).
```Julia
julia> rankine(Metric) # K
$(rankine(Metric))

julia> rankine(SI2019) # K
$(rankine(SI2019))

julia> rankine(British) # °R
$(rankine(British))
```
""" rankine

@doc """
$(unitext(:celsius,"temperature(T₀,U,Metric)"))

Metric unit of `temperature` (K or °R).
```Julia
julia> celsius(Metric) # K
$(celsius(Metric))

julia> celsius(SI2019) # K
$(celsius(SI2019))

julia> celsius(British) # °R
$(celsius(British))
```
""" celsius, T₀

@doc """
$(unitext(:fahrenheit,"temperature(Constant(459.67),U,English)"))

English unit of `temperature` (K or °R).
```Julia
julia> fahrenheit(Metric) # K
$(fahrenheit(Metric))

julia> fahrenheit(SI2019) # K
$(fahrenheit(SI2019))

julia> fahrenheit(British) # °R
$(fahrenheit(British))
```
""" fahrenheit

#=@doc """
$(unitext(:delisle,"temperature(𝟐/𝟑,U,Metric)"))

Historical unit of `temperature` (K or °R).
```Julia
julia> delisle(Metric) # K
$(delisle(Metric))

julia> delisle(SI2019) # K
$(delisle(SI2019))

julia> delisle(British) # °R
$(delisle(British))
```
""" delisle

@doc """
$(unitext(:reaumur,"temperature(𝟓/𝟐^2,U,Metric)"))

Historical unit of `temperature` (K or °R).
```Julia
julia> reaumur(Metric) # K
$(reaumur(Metric))

julia> reaumur(SI2019) # K
$(reaumur(SI2019))

julia> reaumur(British) # °R
$(reaumur(British))
```
""" reaumur

@doc """
$(unitext(:freezing,"temperature(T₀-milli,U)"))

Standard `temperature` reference at `freezing` point of water (K or °R).
```Julia
julia> freezing(Metric) # K
$(freezing(Metric))

julia> freezing(SI2019) # K
$(freezing(SI2019))

julia> freezing(English) # °R
$(freezing(English))
```
""" freezing=#

@doc """
$(unitext(:boiling,"temperature(T₀+Constant(99.9839),U)"))

Standard `temperature` reference at `boiling` point of water (K or °R).
```Julia
julia> boiling(Metric) # K
$(boiling(Metric))

julia> boiling(SI2019) # K
$(boiling(SI2019))

julia> boiling(English) # °R
$(boiling(English))
```
""" boiling

@doc """
$(unitext(:sealevel,"temperature(T₀+𝟑*𝟓,U)"))

Standard `temperature` reference at `sealevel` (K or °R).
```Julia
julia> sealevel(Metric) # K
$(sealevel(Metric))

julia> sealevel(SI2019) # K
$(sealevel(SI2019))

julia> sealevel(English) # °R
$(sealevel(English))
```
""" sealevel

# mole

@doc """
$(unitext(:mole,"molaramount(𝟏,U,Metric)"))

Molecular `molaramount` unit (mol or lb-mol).
```Julia
julia> mole(Metric) # mol
$(mole(Metric))

julia> mole(English) # lb-mol
$(mole(English))

julia> mole(British) # slug-mol
$(mole(British))
```
""" mole

@doc """
$(unitext(:earthmole,"molaramount(𝟏,U,Meridian)"))

Molecular `molaramount` unit (mol or lb-mol).
```Julia
julia> earthmole(Metric) # mol
$(earthmole(Metric))

julia> earthmole(English) # lb-mol
$(earthmole(English))

julia> earthmole(British) # slug-mol
$(earthmole(British))
```
""" earthmole

@doc """
$(unitext(:poundmole,"molaramount(𝟏,U,English)"))

Molecular `molaramount` unit (mol or lb-mol).
```Julia
julia> poundmole(Metric) # mol
$(poundmole(Metric))

julia> poundmole(English) # lb-mol
$(poundmole(English))

julia> poundmole(British) # slug-mol
$(poundmole(British))
```
""" poundmole

@doc """
$(unitext(:slinchmole,"molaramount(𝟏,U,IPS)"))

Molecular `molaramount` unit (mol or lb-mol).
```Julia
julia> slinchmole(Metric) # mol
$(slinchmole(Metric))

julia> slinchmole(English) # lb-mol
$(slinchmole(English))

julia> slinchmole(British) # slug-mol
$(slinchmole(British))
```
""" slinchmole

@doc """
$(unitext(:slugmole,"molaramount(𝟏,U,British)"))

Molecular `molaramount` unit (mol or lb-mol).
```Julia
julia> slugmole(Metric) # mol
$(slugmole(Metric))

julia> slugmole(English) # lb-mol
$(slugmole(English))

julia> slugmole(British) # slug-mol
$(slugmole(British))
```
""" slugmole

# photometric

@doc """
$(unitext(:lumen,"luminousflux(𝟏,U,Metric)"))

Common unit of `luminousflux` (lm).
```Julia
julia> lumen(Metric) # lm
$(lumen(Metric))

julia> lumen(CGS) # lm
$(lumen(CGS))

julia> lumen(English) # lm
$(lumen(English))
```
""" lumen

@doc """
$(unitext(:candela,"luminousintensity(𝟏,U,Metric)"))

Common unit of `luminousintensity` (cd).
```Julia
julia> candela(MetricEngineering) # cd
$(candela(Metric))

julia> candela(CGS) # cd
$(candela(CGS))

julia> candela(English) # cd
$(candela(English))
```
""" candela

@doc """
$(unitext(:lux,"illuminance(𝟏,U,Metric)"))

Metric unit of `illuminance` (lx).
```Julia
julia> lux(Metric) # lx
$(lux(Metric))

julia> lux(CGS) # ph
$(lux(CGS))

julia> lux(English) # fc
$(lux(English))
```
""" lux

@doc """
$(unitext(:footcandle,"illuminance(𝟏,U,English)"))

English unit of `illuminance` (lx).
```Julia
julia> footcandle(Metric) # lx
$(footcandle(Metric))

julia> footcandle(CGS) # ph
$(footcandle(CGS))

julia> footcandle(English) # fc
$(footcandle(English))
```
""" footcandle

@doc """
$(unitext(:phot,"illuminance(𝟏,U,Gauss)"))

Historic unit of `illuminance` (lx).
```Julia
julia> phot(Metric) # lx
$(phot(Metric))

julia> phot(CGS) # ph
$(phot(CGS))

julia> phot(English) # fc
$(phot(English))
```
""" phot

@doc """
$(unitext(:nit,"luminance(𝟏,U,Metric)"))

Metric unit of `luminance` (lx⋅rad⁻²).
```Julia
julia> nit(Metric) # nt
$(nit(Metric))

julia> nit(CGS) # sb
$(nit(CGS))

julia> nit(English) # fc
$(nit(English))
```
""" nit

@doc """
$(unitext(:apostilb,"luminance(𝟐/turn(U),U,Metric)"))

Metric unit of `luminance` (lx⋅rad⁻²).
```Julia
julia> apostilb(Metric) # nt
$(apostilb(Metric))

julia> apostilb(CGS) # sb
$(apostilb(CGS))

julia> apostilb(English) # fc
$(apostilb(English))
```
""" apostilb

@doc """
$(unitext(:stilb,"luminance(𝟏,U,Gauss)"))

Historic unit of `luminance` (lx⋅rad⁻²).
```Julia
julia> stilb(Metric) # nt
$(stilb(Metric))

julia> stilb(CGS) # sb
$(stilb(CGS))

julia> stilb(English) # fc
$(stilb(English))
```
""" stilb

@doc """
$(unitext(:lambert,"luminance(𝟐/turn(U),U,Gauss)"))

Historic unit of `luminance` (nt).
```Julia
julia> lambert(Metric) # nt
$(lambert(Metric))

julia> lambert(CGS) # sb
$(lambert(CGS))

julia> lambert(English) # fc
$(lambert(English))
```
""" lambert

@doc """
$(unitext(:footlambert,"luminance(𝟐/turn(U),U,English)"))

English unit of `luminance` (nt).
```Julia
julia> footlambert(Metric) # nt
$(footlambert(Metric))

julia> footlambert(CGS) # sb
$(footlambert(CGS))

julia> footlambert(English) # fc
$(footlambert(English))
```
""" footlambert

@doc """
$(unitext(:bril,"centi*nano*lambert(U)"))

Reference unit of `luminance` (nt).
```Julia
julia> bril(Metric) # nt
$(bril(Metric))

julia> bril(CGS) # sb
$(bril(CGS))

julia> bril(English) # fc
$(bril(English))
```
""" bril

# special

@doc """
$(unitext(:hertz,"𝟏/second(U)"))

Metric unit of `frequency` (s⁻¹).
```Julia
julia> hertz(MetricEngineering) # rad⋅s⁻¹
$(hertz(MetricEngineering))

julia> hertz(IAU) # D⁻¹
$(hertz(IAU))
```
""" hertz

@doc """
$(unitext(:apm,"𝟏/minute(U)"))

Actions per minute `apm` unit of `frequency` (s⁻¹).
```Julia
julia> apm(MetricEngineering) # s⁻¹
$(apm(MetricEngineering))

julia> apm(IAU) # D⁻¹
$(apm(IAU))
```
""" apm

@doc """
$(unitext(:rpm,"turn(U)/minute(U)"))

Revolutions per minute `rpm` unit of `angularfrequency` (s⁻¹).
```Julia
julia> rpm(MetricEngineering) # rad⋅s⁻¹
$(rpm(MetricEngineering))

julia> rpm(IAU) # D⁻¹
$(rpm(IAU))
```
""" rpm

@doc """
$(unitext(:kayser,"wavenumber(𝟏,U,Gauss)"))

Metric unit of `wavenumber` or curvature (m⁻¹ or ft⁻¹).
```Julia
julia> kayser(Metric) # m⁻¹
$(kayser(Metric))

julia> kayser(CGS) # cm⁻¹
$(kayser(CGS))

julia> kayser(English) # ft⁻¹
$(kayser(English))
```
""" kayser

@doc """
$(unitext(:diopter,"wavenumber(𝟏,U,Metric)"))

Metric unit of `wavenumber` or curvature (m⁻¹ or ft⁻¹).
```Julia
julia> diopter(Metric) # m⁻¹
$(diopter(Metric))

julia> diopter(CGS) # cm⁻¹
$(diopter(CGS))

julia> diopter(English) # ft⁻¹
$(diopter(English))
```
""" diopter

@doc """
$(unitext(:gforce,"specificforce(𝟏,U,English)"))

Standard gravity `specificforce` `g₀` at geodetic reference latitude (m⋅s⁻² or ft⋅s⁻²).
```Julia
julia> gforce(CGS) # gal
$(gforce(CGS))

julia> gforce(British) # ft⋅s⁻²
$(gforce(British))

julia> gforce(English) # lbf⋅lbm⁻¹
$(gforce(English))
```
""" gforce, g₀, g0, lbm

@doc """
$(unitext(:galileo,"specificforce(𝟏,U,Gauss)"))

Metric unit of `specificforce` used in gravimetry (m⋅s⁻² or ft⋅s⁻²).
```Julia
julia> galileo(Metric) # m⋅s⁻²
$(galileo(Metric))

julia> galileo(CGS) # gal
$(galileo(CGS))

julia> galileo(English) # lbf⋅lbm⁻¹
$(galileo(English))
```
""" galileo

@doc """
$(unitext(:eotvos,"specificforce(nano,U,Gauss)/length(𝟏,U,Gauss)"))

Metric unit of `specificforce` per `length` used in gravimetry (s⁻² or gal⋅cm⁻¹).
```Julia
julia> eotvos(Metric) # s⁻²
$(eotvos(Metric))

julia> eotvos(CGS) # gal⋅cm⁻¹
$(eotvos(CGS))

julia> eotvos(English) # lbf⋅lbm⁻¹ft⁻¹
$(eotvos(English))
```
""" eotvos

@doc """
$(unitext(:darcy,"area(milli/atm,U,Gauss)"))

Metric unit of permeability (m² or ft²).
```Julia
julia> darcy(Metric) # m²
$(darcy(Metric))

julia> darcy(CGS) # cm²
$(darcy(CGS))

julia> darcy(English) # ft²
$(darcy(English))
```
""" darcy

@doc """
$(unitext(:poise,"viscosity(𝟏,U,Gauss)"))

Metric unit of `viscosity` (kg⋅m⁻¹⋅s⁻¹ or lb⋅s⋅ft⁻²).
```Julia
julia> poise(Metric) # kg⋅m⁻¹⋅s⁻¹
$(poise(Metric))

julia> poise(CGS) # g⋅cm⁻¹⋅s⁻¹
$(poise(CGS))

julia> poise(English) # lb⋅s⋅ft⁻²
$(poise(English))
```
""" poise

@doc """
$(unitext(:reyn,"viscosity(𝟏,U,IPS)"))

IPS unit of `viscosity` named after Reynolds (kg⋅m⁻¹⋅s⁻¹ or lb⋅s⋅ft⁻²).
```Julia
julia> reyn(Metric) # kg⋅m⁻¹⋅s⁻¹
$(reyn(Metric))

julia> reyn(CGS) # g⋅cm⁻¹⋅s⁻¹
$(reyn(CGS))

julia> reyn(English) # lb⋅s⋅ft⁻²
$(reyn(English))
```
""" reyn

@doc """
$(unitext(:stokes,"diffusivity(𝟏,U,Gauss)"))

Metric unit of `diffusivity` (m²⋅s⁻¹ or ft²⋅s⁻¹).
```Julia
julia> stokes(Metric) # m²⋅s⁻¹
$(stokes(Metric))

julia> stokes(CGS) # cm²⋅s⁻¹
$(stokes(CGS))

julia> stokes(English) # ft²⋅s⁻¹
$(stokes(English))
```
""" stokes

@doc """
$(unitext(:rayl,"specificimpedance(𝟏,U,Metric)"))

Metric unit of `specificimpedance` (kg⋅m⁻²⋅s⁻¹ or lb⋅s⋅ft⁻³).
```Julia
julia> rayl(Metric) # kg⋅m⁻²⋅s⁻¹
$(rayl(Metric))

julia> rayl(CGS) # g⋅cm⁻²⋅s⁻¹
$(rayl(CGS))

julia> rayl(English) # lb⋅s⋅ft⁻³
$(rayl(English))
```
""" rayl

@doc """
$(unitext(:katal,"catalysis(𝟏,U,Metric)"))

Metric unit of `catalysis` (mol⋅s⁻¹ or lb-mol⋅s⁻¹).
```Julia
julia> katal(Metric) # mol⋅s⁻¹
$(katal(Metric))

julia> katal(English) # lb-mol⋅s⁻¹
$(katal(English))

julia> katal(British) # slug-mol⋅s⁻¹
$(katal(British))
```
""" katal

@doc """
$(unitext(:mpge,"mile(U)/gasgallon(U)"))

Equivalent `mile` per `gasgallon` reference unit of `length` per `energy` (N⁻¹ or lb⁻¹).
```Julia
julia> mpge(Metric) # N⁻¹
$(mpge(Metric))

julia> mpge(CGS) # dyn⁻¹
$(mpge(CGS))

julia> mpge(English) # lb⁻¹
$(mpge(English))
```
""" mpge

@doc """
$(unitext(:langley,"calorie(U)/(centi*meter(U))^2"))

Solar radiation unit (kg⋅s⁻² or lb⋅ft⁻¹).
```Julia
julia> langley(Metric) # kg⋅s⁻²
$(langley(Metric))

julia> langley(CGS) # g⋅s⁻²
$(langley(CGS))

julia> langley(English) # lb⋅ft⁻¹
$(langley(English))
```
""" langley

@doc """
$(unitext(:jansky,"fluence(deci^-26,U,Metric)"))

Reference unit of spectral irradiance (kg⋅s⁻² or lb⋅ft⁻¹).
```Julia
julia> jansky(Metric) # kg⋅s⁻²
$(jansky(Metric))

julia> jansky(CGS) # g⋅s⁻²
$(jansky(CGS))

julia> jansky(English) # lb⋅ft⁻¹
$(jansky(English))
```
""" jansky

@doc """
$(unitext(:solarflux,"hecto^2*jansky(U)"))

Reference unit of spectral irradiance (kg⋅s⁻² or lb⋅ft⁻¹).
```Julia
julia> solarflux(Metric) # kg⋅s⁻²
$(solarflux(Metric))

julia> solarflux(CGS) # g⋅s⁻²
$(solarflux(CGS))

julia> solarflux(English) # lb⋅ft⁻¹
$(solarflux(English))
```
""" solarflux

@doc """
$(unitext(:curie,"frequency(𝟏,U,Metric)"))

Reference unit of radioactivity (Bq or s⁻¹).
```Julia
julia> curie(Metric) # Bq
$(curie(Metric))

julia> curie(IAU) # D⁻¹
$(curie(IAU))
```
""" curie

@doc """
$(unitext(:sievert,"energy(𝟏,U,Metric)/mass(U,Metric)"))

Metric unit of radioactivity (Sv or m²⋅s⁻²).
```Julia
julia> sievert(Metric) # Sv
$(sievert(Metric))
```
""" sievert

@doc """
    rem(U::UnitSystem) = centi*sievert(U)

Obsolete unit of radioactivity (Sv or m²⋅s⁻²).
```Julia
julia> rem(Metric) # Sv
$(rem(Metric))
```
""" rem

@doc """
$(unitext(:roentgen,"chargedensity(𝟏,U,ESU)/density(Constant(1.293),U,Metric)"))

Legacy unit of ionisation `exposure` (R or C⋅kg⁻¹).
```Julia
julia> roentgen(Metric) # R
$(roentgen(Metric))
```
""" roentgen


text:
# Autogenerated wrapper script for ArcadeLearningEnvironment_jll for x86_64-apple-darwin14-cxx03
export libale_c

using Zlib_jll
## Global variables
PATH = ""
LIBPATH = ""
LIBPATH_env = "DYLD_FALLBACK_LIBRARY_PATH"
LIBPATH_default = "~/lib:/usr/local/lib:/lib:/usr/lib"

# Relative path to `libale_c`
const libale_c_splitpath = ["lib", "libale_c.dylib"]

# This will be filled out by __init__() for all products, as it must be done at runtime
libale_c_path = ""

# libale_c-specific global declaration
# This will be filled out by __init__()
libale_c_handle = C_NULL

# This must be `const` so that we can use it with `ccall()`
const libale_c = "@rpath/libale_c.dylib"

"""
Open all libraries
"""
function __init__()
    global artifact_dir = abspath(artifact"ArcadeLearningEnvironment")

    # Initialize PATH and LIBPATH environment variable listings
    global PATH_list, LIBPATH_list
    # From the list of our dependencies, generate a tuple of all the PATH and LIBPATH lists,
    # then append them to our own.
    foreach(p -> append!(PATH_list, p), (Zlib_jll.PATH_list,))
    foreach(p -> append!(LIBPATH_list, p), (Zlib_jll.LIBPATH_list,))

    # Lastly, we need to add to LIBPATH_list the libraries provided by Julia
    append!(LIBPATH_list, [joinpath(Sys.BINDIR, Base.LIBDIR, "julia"), joinpath(Sys.BINDIR, Base.LIBDIR)])
    global libale_c_path = normpath(joinpath(artifact_dir, libale_c_splitpath...))

    # Manually `dlopen()` this right now so that future invocations
    # of `ccall` with its `SONAME` will find this path immediately.
    global libale_c_handle = dlopen(libale_c_path)
    push!(LIBPATH_list, dirname(libale_c_path))

    # Filter out duplicate and empty entries in our PATH and LIBPATH entries
    filter!(!isempty, unique!(PATH_list))
    filter!(!isempty, unique!(LIBPATH_list))
    global PATH = join(PATH_list, ':')
    global LIBPATH = join(LIBPATH_list, ':')

    # Add each element of LIBPATH to our DL_LOAD_PATH (necessary on platforms
    # that don't honor our "already opened" trick)
    #for lp in LIBPATH_list
    #    push!(DL_LOAD_PATH, lp)
    #end
end  # __init__()


text:
algorithms = [DMDPINV(), DMDSVD(1e-2), TOTALDMD(1e-2, DMDPINV()), TOTALDMD(1e-2,DMDSVD(1e-2))]

@info "Starting Dynamic Mode Decomposition tests"
@testset "Dynamic Mode Decomposition" begin

    @info "Starting linear discrete system tests"
    @testset "Linear Discrete System" begin
        # Create some linear data
        A = [0.9 -0.2; 0.0 0.2]
        y = [[10.; -10.]]
        for i in 1:10
            push!(y, A*y[end])
        end
        X = hcat(y...)
        for alg_ in algorithms
            @info "Testing $alg_"
            estimator = DMD(X, alg = alg_)
            @test operator(estimator) ≈ A
            @test isstable(estimator)
            @test eigvals(estimator) ≈ eigvals(A)
            @test eigvecs(estimator) ≈ eigvecs(A)
            @test is_discrete(estimator)
            @test_nowarn update!(estimator, X[:, end-1], X[:,end])
            @test_throws AssertionError outputmap(estimator)
        end
    end

    @info "Starting linear continuous system tests"
    @testset "Linear Continuous System" begin
        A = [-0.9 0.1; 0.0 -0.2]
        f(u, p, t) = A*u
        u0 = [10.0; -20.0]
        prob = ODEProblem(f, u0, (0.0, 10.0))
        sol = solve(prob, Tsit5(), saveat = 0.001)
        X = sol[:,:]
        DX = sol(sol.t, Val{1})[:,:]

        for alg_ in algorithms
            @info "Testing $alg_"
            estimator = gDMD(X, DX, alg = alg_)
            d2 = gDMD(sol.t, X, alg = alg_)
            d3 = gDMD(sol.t, X, alg = alg_, dt = 0.007)
            @test isapprox(generator(estimator), A, atol = 1e-3)
            @test isstable(estimator)
            @test isapprox(eigvals(estimator), eigvals(A), atol = 1e-3)
            @test isapprox(abs.(eigvecs(estimator)), abs.(eigvecs(A)), atol = 1e-3)
            @test isapprox(generator(estimator), generator(d2), atol = 1e-1)
            @test isapprox(generator(estimator), generator(d3), atol = 5e-1)
        end
    end

    @info "Starting big continuous system tests"
    @testset "Big System" begin
        dd(u, p, t) = -0.9*ones(length(u))*u[1] - 0.05*u
        u0 = randn(100)*100.0
        u0[1] = 100.0
        prob = ODEProblem(dd, u0, (0.0, 10.0))
        sol = solve(prob, Tsit5(), saveat = 0.001)
        X = sol[:,:]
        DX = sol(sol.t, Val{1})[:,:]

        for alg_ in algorithms
            @info "Testing $alg_"
            d = gDMD(X, DX, alg = alg_)
            test = ODEProblem(d, u0, (0.0, 10.0))
            sol_ = solve(test, Tsit5(), saveat = 0.001)
            @test norm(sol-sol_, Inf) < 2.0
        end
    end

    @info "Starting low rank linear system tests"
    @testset "Rank Reduction" begin
        K = -0.5*I + [0 0 -0.2; 0.1 0 -0.1; 0. -0.2 0]
        F = qr(randn(20, 3))
        Q = F.Q[:, 1:3]
        dudt(u, p, t) = K*u
        prob = ODEProblem(dudt, [10.0; 0.3; -5.0], (0.0, 10.0))
        sol_ = solve(prob, Tsit5(), saveat = 0.01)

        # True Rank is 3
        alg = TOTALDMD(3, DMDPINV())
        X = Q*sol_[:,:] + 1e-3*randn(20, 1001)
        DX = Q*sol_(sol_.t, Val{1})[:,:] + 1e-3*randn(20, 1001)
        approx = gDMD(X, DX, alg = alg)
        @test Q'*generator(approx)*Q ≈ K atol = 1e-1
        @test Q*K*Q' ≈ generator(approx) atol = 1e-1
        alg = TOTALDMD(0.01, DMDSVD())
        approx = gDMD(X, DX, alg = alg)
        @test Q'*generator(approx)*Q ≈ K atol = 1e-1
        @test Q*K*Q' ≈ generator(approx) atol = 1e-1
    end
end

@info "Starting Extended Dynamic Mode Decomposition tests"
@testset "Extended Dynamic Mode Decomposition" begin

    @info "Starting linear discrete system tests"
    @testset "Linear Discrete System" begin
        # Test for linear system
        function linear_sys(u, p, t)
            x = -0.9 * u[1]
            y = -0.3 * u[2]
            return [x; y]
        end

        u0 = [π; 1.0]
        tspan = (0.0, 50.0)
        prob = DiscreteProblem(linear_sys, u0, tspan)
        sol = solve(prob, FunctionMap())

        @variables u[1:2]
        h = [u[1]; u[2]; sin(u[1]); cos(u[1]); u[1] * u[2]; u[2]^2]
        basis = Basis(h, u)

        estimator = EDMD(sol[:, 1:15], basis, alg = DMDPINV())
        update!(estimator, sol[:, 15:end-1], sol[:, 16:end])
        p1 = DiscreteProblem(estimator, u0, tspan)
        s1 = solve(p1,FunctionMap())
        basis_2 = reduce_basis(estimator, threshold = 1e-5)
        @test basis == estimator.basis
        @test size(basis_2)[1] < size(basis)[1]
        @test sol[:,:] ≈ s1[:,:]

        # Check EDMD
        for alg_ in algorithms
            @info "Testing $alg_"
            estimator_ = EDMD(sol[:,:], basis_2)
            p_ = DiscreteProblem(estimator_, u0, tspan)
            s_ = solve(p_,FunctionMap())
            @test sol[:,:] ≈ s_[:,:]
            @test eigvals(estimator_) ≈ [-0.9; -0.3]
            @test isstable(estimator_)
        end
    end

    @info "Starting linear continuous system tests"
    @testset "Linear Continuous System" begin

        function nonlinear_sys2(du, u, p, t)
            du[1] = u[2]
            du[2] = -0.9u[1]
        end

        u0 = [10.0; -20.0]

        prob_nl = ODEProblem(nonlinear_sys2, u0, (0.0, 10.0))
        sol_nl = solve(prob_nl, Tsit5())

        X = Array(sol_nl)
        DX = sol_nl(sol_nl.t, Val{1})[:,:]

        @variables u[1:2]
        basis = Basis(u, u)

        for alg_ in algorithms
            @info "Testing $alg_"
            estimator = gEDMD(X, DX, basis, alg = alg_)
            estimator_derivative = gEDMD(sol_nl.t, X, basis, alg = alg_)
            estimator_interpolation = gEDMD(sol_nl.t, X, basis, dt = 0.1, alg = alg_)
            @test generator(estimator) ≈ [0  1.0; -0.9 0]
            @test outputmap(estimator) ≈ I(2)
            @test generator(estimator) ≈ generator(estimator_derivative) atol = 1e-1
            @test generator(estimator) ≈ generator(estimator_interpolation) atol = 1e-1
        end
    end

    @info "Starting nonlinear discrete system tests"
    @testset "Nonlinear Discrete System" begin
        function nonlinear_sys(du, u, p, t)
            du[1] = 0.9u[1] + 0.1u[2]^2
            du[2] = sin(u[1]) - 0.1u[1]
        end

        u0 = [π; 1.0]
        tspan = (0.0, 50.0)

        @variables u[1:2]
        h = [u[1]; u[2]; sin(u[1]); u[2]^2]
        basis = Basis(h, u)

        prob = DiscreteProblem(nonlinear_sys, u0, tspan)
        sol = solve(prob,FunctionMap())
        estimator = EDMD(sol[:,:], basis, alg = DMDPINV())
        sys = ODESystem(estimator)
        @test isa(sys, ODESystem)
        dudt = ODEFunction(sys)
        p_ = DiscreteProblem(dudt, u0, tspan)
        s_ = solve(p_,FunctionMap())
        @test sol[:,:] ≈ s_[:,:]

        for alg_ in algorithms
            @info "Testing $alg_"
            estimator_ = EDMD(sol[:,:], basis, alg = alg_)
            p_ = DiscreteProblem(estimator_, u0, tspan)
            s_ = solve(p_,FunctionMap())
            @test sol[:,:] ≈ s_[:,:] atol = 1e-1
        end
    end

    @info "Starting nonlinear continuous system tests"
    @testset "Nonlinear Continuous System" begin

            function slow_manifold(du, u, p, t)
                du[1] = p[1]*u[1]
                du[2] = p[2]*(u[2]-u[1]^2)
            end

            u0 = [3.0; -2.0]
            tspan = (0.0, 10.0)
            p = [-0.05, -0.9]

            prob = ODEProblem(slow_manifold, u0, tspan, p)
            sol = solve(prob, Tsit5(), saveat = 0.2)

            X = Array(sol)
            # This enforces more accurate results
            DX = similar(X)
            for (i,dx) in enumerate(eachcol(DX))
                slow_manifold(dx, X[:, i], p, sol.t[i])
            end

            @variables u[1:2]
            basis = Basis([u; u[1]^2], u)

            for alg_ in algorithms
                @info "Testing $alg_"
                estimator2 = gEDMD(X, DX, basis, alg = alg_)
                A_analytical = [p[1] 0 0; 0 p[2] -p[2]; 0 0 2*p[1]]
                outputmap(estimator2)
                generator(estimator2)
                @test generator(estimator2) ≈ [p[1] 0 0; 0 p[2] -p[2]; 0 0 2*p[1]] atol =  1e-3
                @test outputmap(estimator2) ≈ [1 0 0 ; 0 1 0] atol = 1e-3
                @test abs.(modes(estimator2)) ≈ abs.(eigvecs(A_analytical)) atol = 1e-3
                @test frequencies(estimator2) ≈ eigvals(A_analytical) atol = 1e-3
            end

    end
end

@info "Starting Dynamic Mode Decomposition with Control tests"
@testset "Dynamic Mode Decomposition with Control" begin

    # Define measurements from unstable system with known control input
    X = [4 2 1 0.5 0.25; 7 0.7 0.07 0.007 0.0007]
    U = [-4 -2 -1 -0.5]
    B = Float32[1; 0]

    # But with a little more knowledge
    for alg_ in algorithms
        @info "Testing $alg_"
        sys = DMDc(X, U, B = B, alg = alg_)
        @test operator(sys) ≈[1.5 0; 0 0.1]
        @test inputmap(sys) ≈ [1.0; 0.0]
        @test !isstable(sys)
        @test_nowarn eigen(sys)
    end

    sys = DMDc(X, U, B = B)
    sys2 = DMDc(X, U, B = B, alg = DMDSVD())
    @test operator(sys2) ≈ operator(sys)
    sys3 = gDMDc(X[:, 1:end-1], X[:, 2:end], U, B = B)
    @test generator(sys3) ≈ [1.5 0; 0 0.1]

    A = [0.9 0.3; -0.2 0.9]
    B = [1.0 0;0 0.5]
    X = zeros(Float64, 2, 11)
    U = zeros(Float64, 2, 10)
    X[:, 1] = [1.0; -3.0]
    for i in 1:10
        U[:, i] .= [sin(2.0/5.0*i); cos(5.0/7.0*i)]
        X[:, i+1] .= A*X[:,i]+B*[sin(2.0/5.0*i); cos(5.0/7.0*i)]
    end

    for alg_ in algorithms
        @info "Testing $alg_"
        sys4 = DMDc(X, U, alg = alg_)
        @test operator(sys4) ≈ A
        @test inputmap(sys4) ≈ B
        sys5 = gDMDc(X[:, 1:end-1], X[:, 2:end], U[:, 1:end])
        @test_throws AssertionError operator(sys5)
        @test generator(sys5) ≈ A
        @test inputmap(sys5) ≈ B
    end

    for alg_ in algorithms
        @info "Testing $alg_"
        sys6 = gDMDc(collect(0.0:9.0), X[:, 1:end-1], U, B = B, alg = alg_)
        @test exp(generator(sys6)) ≈ A atol = 1e-1
        @test inputmap(sys6) ≈ B
    end

end


text:
module ImageInspector

using Colors

export image, gridsize, imagegrid

function image(x::AbstractMatrix{T}; flip = true) where {T <: Real}
    xx = flip ? PermutedDimsArray(x, (2, 1)) : x
    return Gray.(xx)
end

function image(x::AbstractArray{T,3}; flip = true) where {T <: Real}
    s = size(x, 3)
    if s == 1
        return image(dropdims(x; dims = 3); flip)
    elseif s == 3
        xx = flip ? PermutedDimsArray(x, (2, 1, 3)) : x
        r, g, b = eachslice(xx; dims=3)
        return RGB.(r, g, b)
    else
        throw(ArgumentError("unsupported size of the third dimension $(s) ∉ [1,3]."))
    end
end

image(x::AbstractArray{T,3}, inds; flip = true) where {T <: Real} = [image(x[:,:,i]; flip) for i in inds]
image(x::AbstractArray{T,4}, inds; flip = true) where {T <: Real} = [image(x[:,:,:,i]; flip) for i in inds]
image(x::AbstractArray{T,3}, ind::Int; flip = true) where {T <: Real} = image(x, [ind]; flip)[1]
image(x::AbstractArray{T,4}, ind::Int; flip = true) where {T <: Real} = image(x, [ind]; flip)[1]

function gridsize(n::Int; nrows::Int = -1, ncols::Int = - 1)
    if nrows < 1
        if ncols < 1
            nrows = round(Int, sqrt(n))
            ncols = ceil(Int, n / nrows)
        else
            nrows = ceil(Int, n / ncols)
        end
    else
        ncols = ceil(Int, n / nrows)
    end
    return nrows, ncols
end

imagegrid(x, ind::Int; flip = true, kwargs...) = image(x, ind; flip)

function imagegrid(x, inds; flip = true, sep = 1, kwargs...)
    imgs = image(x, inds; flip)
    n = length(imgs)
    nrows, ncols = gridsize(n; kwargs...)

    h, w = size(imgs[1])
    A = fill(
        eltype(imgs[1])(1), # white color in proper color type
        nrows*h + (nrows + 1)*sep, # height of the reculting image
        ncols*w + (ncols + 1)*sep, # width of the reculting image
    )

    for i in 1:nrows, j in 1:ncols
        k = j + (i - 1) * ncols
        k > n && break

        rows = (1:h) .+ (i - 1)*h .+ i*sep
        cols = (1:w) .+ (j - 1)*w .+ j*sep
        A[rows, cols] = imgs[k]
    end
    return A
end

using Requires

function __init__()
    @require Plots="91a5bcdd-55d7-5caf-9e0b-520d859cae80" include("imageplot.jl")
end

end

max_stars_repo_name: NikolaGrover/ImageInspector

max_issues_repo_name: NikolaGrover/ImageInspector

max_forks_repo_name: NikolaGrover/ImageInspector


text:
# random DB interactions

## Uncomment out for command line operation
# cloudGraph, addrdict = standardcloudgraphsetup(nparticles=true)
# session = addrdict["session"]
# Nparticles = parse(Int,addrdict["num particles"])

# interactive operation
session = "SESSROX"
Nparticles = 100
include(joinpath(dirname(@__FILE__),"blandauthremote.jl"))

fg = initfg(sessionname=session, cloudgraph=cloudGraph)
fullLocalGraphCopy!(fg)

@show usrf = getData(fg.g.vertices[100003]).fnc.usrfnc!
pts = evalFactor(fg, fg.g.vertices[100003], fg.IDs[:l15])

pts = evalFactor(fg, fg.g.vertices[100003], fg.IDs[:x4])

v = getVert(fg, :x4, api=dlapi)
pts = getVal(fg, :x4, api=dlapi)

@show usrf.range

pts = getSample(usrf)
res = zeros(2)
usrf(res, 1, pts, getVal(fg, :x4), getVal(fg, :l15))
@show res

@show fieldnames(getData(fg.g.vertices[100003]).fnc)
@show getData(fg.g.vertices[100003]).fnc.particleidx

v = getVert(fg, :l15, api=dlapi)
getVal(fg, :l15, api=dlapi)

setVal!(v, randn(2,100))
updateFullCloudVertData!(fg, v)


text:
"""
    GeneralizedPareto(μ, σ, ξ)

The *Generalized Pareto distribution* with shape parameter `ξ`, scale `σ` and location `μ` has probability density function

```math
f(x; \\mu, \\sigma, \\xi) = \\begin{cases}
        \\frac{1}{\\sigma}(1 + \\xi \\frac{x - \\mu}{\\sigma} )^{-\\frac{1}{\\xi} - 1} & \\text{for } \\xi \\neq 0 \\\\
        \\frac{1}{\\sigma} e^{-\\frac{\\left( x - \\mu \\right) }{\\sigma}} & \\text{for } \\xi = 0
    \\end{cases}~,
    \\quad x \\in \\begin{cases}
        \\left[ \\mu, \\infty \\right] & \\text{for } \\xi \\geq 0 \\\\
        \\left[ \\mu, \\mu - \\sigma / \\xi \\right] & \\text{for } \\xi < 0
    \\end{cases}
```

```julia
GeneralizedPareto()             # Generalized Pareto distribution with unit shape and unit scale, i.e. GeneralizedPareto(0, 1, 1)
GeneralizedPareto(μ, σ)         # Generalized Pareto distribution with shape ξ and scale σ, i.e. GeneralizedPareto(0, σ, ξ)
GeneralizedPareto(μ, σ, ξ)      # Generalized Pareto distribution with shape ξ, scale σ and location μ.

params(d)       # Get the parameters, i.e. (μ, σ, ξ)
location(d)     # Get the location parameter, i.e. μ
scale(d)        # Get the scale parameter, i.e. σ
shape(d)        # Get the shape parameter, i.e. ξ
```

External links

* [Generalized Pareto distribution on Wikipedia](https://en.wikipedia.org/wiki/Generalized_Pareto_distribution)

"""
struct GeneralizedPareto{T<:Real} <: ContinuousUnivariateDistribution
    μ::T
    σ::T
    ξ::T
    GeneralizedPareto{T}(μ::T, σ::T, ξ::T) where {T} = new{T}(μ, σ, ξ)
end

function GeneralizedPareto(μ::T, σ::T, ξ::T; check_args=true) where {T <: Real}
    check_args && @check_args(GeneralizedPareto, σ > zero(σ))
    return GeneralizedPareto{T}(μ, σ, ξ)
end

GeneralizedPareto(μ::Real, σ::Real, ξ::Real) = GeneralizedPareto(promote(μ, σ, ξ)...)

function GeneralizedPareto(μ::Integer, σ::Integer, ξ::Integer)
    GeneralizedPareto(float(μ), float(σ), float(ξ))
end
GeneralizedPareto(σ::T, ξ::Real) where {T <: Real} = GeneralizedPareto(zero(T), σ, ξ)
GeneralizedPareto() = GeneralizedPareto(0.0, 1.0, 1.0, check_args=false)

minimum(d::GeneralizedPareto) = d.μ
maximum(d::GeneralizedPareto{T}) where {T<:Real} = d.ξ < 0 ? d.μ - d.σ / d.ξ : Inf

#### Conversions
function convert(::Type{GeneralizedPareto{T}}, μ::S, σ::S, ξ::S) where {T <: Real, S <: Real}
    GeneralizedPareto(T(μ), T(σ), T(ξ))
end
function convert(::Type{GeneralizedPareto{T}}, d::GeneralizedPareto{S}) where {T <: Real, S <: Real}
    GeneralizedPareto(T(d.μ), T(d.σ), T(d.ξ), check_args=false)
end

#### Parameters

location(d::GeneralizedPareto) = d.μ
scale(d::GeneralizedPareto) = d.σ
shape(d::GeneralizedPareto) = d.ξ
params(d::GeneralizedPareto) = (d.μ, d.σ, d.ξ)
partype(::GeneralizedPareto{T}) where {T} = T

#### Statistics

median(d::GeneralizedPareto) = d.ξ == 0 ? d.μ + d.σ * logtwo : d.μ + d.σ * expm1(d.ξ * logtwo) / d.ξ

function mean(d::GeneralizedPareto{T}) where {T<:Real}
    if d.ξ < 1
        return d.μ + d.σ / (1 - d.ξ)
    else
        return T(Inf)
    end
end

function var(d::GeneralizedPareto{T}) where {T<:Real}
    if d.ξ < 0.5
        return d.σ^2 / ((1 - d.ξ)^2 * (1 - 2 * d.ξ))
    else
        return T(Inf)
    end
end

function skewness(d::GeneralizedPareto{T}) where {T<:Real}
    (μ, σ, ξ) = params(d)

    if ξ < (1/3)
        return 2(1 + ξ) * sqrt(1 - 2ξ) / (1 - 3ξ)
    else
        return T(Inf)
    end
end

function kurtosis(d::GeneralizedPareto{T}) where T<:Real
    (μ, σ, ξ) = params(d)

    if ξ < 0.25
        k1 = (1 - 2ξ) * (2ξ^2 + ξ + 3)
        k2 = (1 - 3ξ) * (1 - 4ξ)
        return 3k1 / k2 - 3
    else
        return T(Inf)
    end
end

#### Evaluation

function logpdf(d::GeneralizedPareto{T}, x::Real) where T<:Real
    (μ, σ, ξ) = params(d)

    # The logpdf is log(0) outside the support range.
    p = -T(Inf)

    if x >= μ
        z = (x - μ) / σ
        if abs(ξ) < eps()
            p = -z - log(σ)
        elseif ξ > 0 || (ξ < 0 && x < maximum(d))
            p = (-1 - 1 / ξ) * log1p(z * ξ) - log(σ)
        end
    end

    return p
end

function logccdf(d::GeneralizedPareto{T}, x::Real) where T<:Real
    (μ, σ, ξ) = params(d)

    # The logccdf is log(0) outside the support range.
    p = -T(Inf)

    if x >= μ
        z = (x - μ) / σ
        if abs(ξ) < eps()
            p = -z
        elseif ξ > 0 || (ξ < 0 && x < maximum(d))
            p = (-1 / ξ) * log1p(z * ξ)
        end
    end

    return p
end

ccdf(d::GeneralizedPareto, x::Real) = exp(logccdf(d, x))
cdf(d::GeneralizedPareto, x::Real) = -expm1(logccdf(d, x))

function quantile(d::GeneralizedPareto{T}, p::Real) where T<:Real
    (μ, σ, ξ) = params(d)

    if p == 0
        z = zero(T)
    elseif p == 1
        z = ξ < 0 ? -1 / ξ : T(Inf)
    elseif 0 < p < 1
        if abs(ξ) < eps()
            z = -log1p(-p)
        else
            z = expm1(-ξ * log1p(-p)) / ξ
        end
    else
      z = T(NaN)
    end

    return μ + σ * z
end

#### Sampling

function rand(rng::AbstractRNG, d::GeneralizedPareto)
    # Generate a Float64 random number uniformly in (0,1].
    u = 1 - rand(rng)

    if abs(d.ξ) < eps()
        rd = -log(u)
    else
        rd = expm1(-d.ξ * log(u)) / d.ξ
    end

    return d.μ + d.σ * rd
end


text:
"""
CrystalViscoPlasticRed(E, ν, τ_y, H_iso, H_kin, q, α_∞, t_star, σ_c, m, slipsystems)

Crystal plasticity with
# Arguments
- `E::Float64`: Young's modulus
- `ν::Float64`: Poisson's ratio
- `τ_y`: critical resolved shear stress
- `H_iso`: hardening modulus for isotropic hardening
- `H_kin`: hardening modulus for kinematic hardening
- `q`: cross-hardening parameter for isotropic hardening
- `α_∞`: saturation stress for kinematic hardening
- `t_star`: visco-plastic characteristic time
- `σ_c`: visco-plastic characteristic stress
- `m`: visco-plastic exponent
- `slipsystems`: slipsystems
"""
struct CrystalViscoPlasticRed{S} <: AbstractMaterial
    E::Float64
    ν::Float64
    τ_y::Float64
    H_iso::Float64
    H_kin::Float64
    q::Float64
    α_∞::Float64
    t_star::Float64
    σ_c::Float64
    m::Float64

    # precomputed elastic tangent tensor and hardening matrix
    Eᵉ::SymmetricTensor{4,3,Float64,36}
    H::Matrix{Float64}
    MS::SVector{S,Tensor{2,3,Float64,9}} # m ⊗ s
    # store information about slip sytems
    nslipsystems::Int
    slipsystems::Vector{NTuple{2, Vec{3}}}

    function CrystalViscoPlasticRed(E, ν, τ_y, H_iso, H_kin, q, α_∞, t_star, σ_c, m, slipsystems)
        Eᵉ = elastic_tangent_3D(E, ν)
        nslipsystems = length(slipsystems)
        H = H_iso*(q*ones(nslipsystems, nslipsystems) + (1-q)*diagm(ones(nslipsystems)))
        MS = SVector{nslipsystems,Tensor{2,3,Float64,9}}([slipsystems[i][1] ⊗ slipsystems[i][2] for i=1:nslipsystems])
        return new{nslipsystems}(E, ν, τ_y, H_iso, H_kin, q, α_∞, t_star, σ_c, m, Eᵉ, H, MS, nslipsystems, slipsystems)
    end
end

# keyword argument constructor
CrystalViscoPlasticRed(; E, ν, τ_y, H_iso, H_kin, q, α_∞, t_star, σ_c, m, slipsystems) = CrystalViscoPlasticRed(E, ν, τ_y, H_iso, H_kin, q, α_∞, t_star, σ_c, m, slipsystems)

get_n_slipsystems(::CrystalViscoPlasticRed{S}) where S = S

struct CrystalViscoPlasticRedState{dim,T,M,S} <: AbstractMaterialState
    σ::SymmetricTensor{2,dim,T,M}
    κ::SVector{S, T}
    α::SVector{S, T}
    μ::SVector{S, T}
end

Base.zero(::Type{CrystalViscoPlasticRedState{dim,T,M,S}}) where {dim,T,M,S} = CrystalViscoPlasticRedState{dim,T,M,S}(zero(SymmetricTensor{2,dim,T,M}), SVector{S,T}(zeros(T, S)), SVector{S,T}(zeros(T, S)), SVector{S,T}(zeros(T, S)))
initial_material_state(::CrystalViscoPlasticRed{S}) where S = zero(CrystalViscoPlasticRedState{3,Float64,6,S})

function get_cache(m::CrystalViscoPlasticRed)
    state = initial_material_state(m)
    # it doesn't actually matter which state and strain step we use here,
    # f is overwritten in the constitutive driver before being used.
    f(r_vector, x_vector) = vector_residual!(((x)->MaterialModels.residuals(x, m, state, zero(SymmetricTensor{2,3}), 1.0)), r_vector, x_vector, m)
    v_cache = Vector{Float64}(undef, get_n_scalar_equations(m))
    cache = NLsolve.OnceDifferentiable(f, v_cache, v_cache; autodiff = :forward)
    return cache
end

# constitutive driver operates in 3D, so these can always be 3D
# TODO: Should Residuals have a Type Parameter N for the number of scalar equations?
struct ResidualsCrystalViscoPlasticRed{S, T}
    μ::SVector{S, T}
end

get_n_scalar_equations(::CrystalViscoPlasticRed{S}) where S = S
Tensors.get_base(::Type{CrystalViscoPlasticRed{S}}) where S = ResidualsCrystalViscoPlasticRed{S} # needed for frommandel

function Tensors.tomandel!(v::Vector{T}, r::ResidualsCrystalViscoPlasticRed{S, T}) where {S, T}
    v[1:S] = view(r.μ, :)
    return v
end

function Tensors.frommandel(::Type{ResidualsCrystalViscoPlasticRed{S}}, v::AbstractVector{T}) where {S, T}
    μ = SVector{S,T}(view(v, 1:S))
    return ResidualsCrystalViscoPlasticRed(μ)
end

function material_response(m::CrystalViscoPlasticRed{S}, Δε::SymmetricTensor{2,3,T,6}, state::CrystalViscoPlasticRedState{3},
    Δt=1.0; cache=get_cache(m), options::Dict{Symbol, Any} = Dict{Symbol, Any}()) where {S, T}

    # set the current residual function that depends only on the variables
    f(r_vector, x_vector) = vector_residual!((x->residuals(x,m,state,Δε,Δt)), r_vector, x_vector, m)
    update_cache!(cache, f)
    # initial guess
    σ_trial = state.σ + m.Eᵉ ⊡ Δε
    x0 = ResidualsCrystalViscoPlasticRed(state.μ)
    # convert initial guess to vector
    tomandel!(cache.x_f, x0)
    # solve for variables x
    nlsolve_options = get(options, :nlsolve_params, Dict{Symbol, Any}(:method=>:newton))
    haskey(nlsolve_options, :method) || merge!(nlsolve_options, Dict{Symbol, Any}(:method=>:newton)) # set newton if the user did not supply another method
    result = NLsolve.nlsolve(cache, cache.x_f; nlsolve_options...)

    if result.f_converged
        x_mandel = result.zero::Vector{T}
        x = frommandel(ResidualsCrystalViscoPlasticRed{S}, x_mandel)
        # compute other state variables
        σ, κ, α = get_state_vars(x.μ, Δε, m, state)
        ############################################
        # tangent computation
        ∂R∂x = cache.DF
        f2(r_vector, x_vector) = vector_residual!((Δε->residuals(x,m,state,Δε,Δt)), r_vector, x_vector, Δε)
        # lucky coincidence that we can reuse the buffers here
        tomandel!(view(cache.x_f, 1:6), Δε)
        ∂R∂ε = ForwardDiff.jacobian(f2, cache.F, view(cache.x_f, 1:6)) # ∂R∂ε = ∂R∂Δε
        ∂X∂ε = -inv(∂R∂x)*∂R∂ε
        # in this case X is only μ
        ∂σ∂ε = m.Eᵉ
        for i=1:S
            ∂μᵢ∂ε = frommandel(SymmetricTensor{2,3}, ∂X∂ε[i,:])
            # we've already done almost all the computations we need here - can they be reused?
            ∂σ∂μᵢ = -m.Eᵉ ⊡ m.MS[i]*sign(σ ⊡ m.MS[i] - α[i])
            ∂σ∂ε += ∂σ∂μᵢ ⊗ ∂μᵢ∂ε
        end
        return σ, ∂σ∂ε, CrystalViscoPlasticRedState(σ, κ, α, x.μ)
    else
        error("Material model not converged. Could not find material state.")
    end
end

# for a reduced equation system, we need to be able to do automatic differentiation according to vars and to Δε
function residuals(vars::ResidualsCrystalViscoPlasticRed{S,Tv}, mat::CrystalViscoPlasticRed{S}, material_state::CrystalViscoPlasticRedState{3}, Δε::SymmetricTensor{2,3,Tε}, Δt) where {S,Tv,Tε}
    T = promote_type(Tv, Tε)
    μ=vars.μ

    σ, κ, α = get_state_vars(μ, Δε, mat, material_state)
    Rμ = MVector{S, T}(undef)
    for i=1:S
        τ = σ ⊡ mat.MS[i]
        Φ = norm(τ - α[i]) - mat.τ_y - κ[i]
        Rμ[i] = Δt*(((Φ+abs(Φ))/2)/mat.σ_c)^mat.m - mat.t_star*μ[i]
    end

    return  ResidualsCrystalViscoPlasticRed(SVector{S,T}(Rμ))
end

# compute other state variables based on μ
function get_state_vars(μ::SVector{S,Tμ}, Δε::SymmetricTensor{2,3,Tε}, mat::CrystalViscoPlasticRed{S}, material_state::CrystalViscoPlasticRedState{dim, T, M, S}) where {Tμ, Tε, dim, T, M, S}
    σ_trial = material_state.σ + mat.Eᵉ ⊡ Δε
    sign_τ_red_trial = [sign(σ_trial ⊡ mat.MS[i] - material_state.α[i]) for i=1:S]
    temp_sum_σ = zero(SymmetricTensor{2,3})
    κ = MVector{S, Tμ}(undef)
    α = MVector{S, promote_type(Tμ, Tε)}(undef)
    for i=1:S
        temp_sum_σ += μ[i]*sign_τ_red_trial[i]*mat.MS[i]
        κ[i] = material_state.κ[i] + dot(view(mat.H, :, i), μ)
        α[i] = (material_state.α[i] + mat.H_kin*μ[i]*sign_τ_red_trial[i])/(1+mat.H_kin*μ[i]/mat.α_∞)
    end
    σ = σ_trial - mat.Eᵉ ⊡ temp_sum_σ
    return σ, SVector{S,Tμ}(κ), SVector{S,promote_type(Tμ,Tε)}(α)
end