text:
################################################################################
#
#  Types
#
################################################################################

mutable struct RelFinField{T} <: FinField
  defining_polynomial::PolyElem{T}
  var::Symbol
  absolute_field::Nemo.FinFieldMorphism
  basis_tr::Vector{T}

  function RelFinField(f::PolyElem{T}, v::Symbol) where T
    K = new{T}()
    K.defining_polynomial = f
    K.var = v
    return K
  end
end

mutable struct RelFinFieldElem{S, T} <: FinFieldElem
  parent::S
  data::T
end

################################################################################
#
#  Show functions
#
################################################################################

function Base.show(io::IO, F::RelFinField)
  print(io, "Field extension defined by $(defining_polynomial(F)) over $(base_field(F)) ")
end

function Base.show(io::IO, a::RelFinFieldElem)
  print(io, AbstractAlgebra.obj_to_string(a, context = io))
end

function AbstractAlgebra.expressify(a::RelFinFieldElem; context = nothing)
  return AbstractAlgebra.expressify(a.data, var(parent(a)),
                                    context = context)
end

############################################################################
#
#  Basic properties
#
############################################################################

var(F::RelFinField) = F.var

prime_field(F::RelFinField; cached::Bool = true) = prime_field(base_field(F), cached = cached)

function defining_polynomial(F::RelFinField{T}) where T
  return F.defining_polynomial::dense_poly_type(T)
end

base_field(F::RelFinField{S}) where S= base_ring(F.defining_polynomial)::parent_type(S)

characteristic(F::RelFinField) = characteristic(base_field(F))

order(F::RelFinField) = order(base_field(F))^degree(F)

degree(F::RelFinField) = degree(defining_polynomial(F))

################################################################################
#
#  Absolute degree
#
################################################################################

absolute_degree(F::RelFinField) = degree(F)*absolute_degree(base_field(F))
absolute_degree(F::FinField) = degree(F)

################################################################################
#
#  Deepcopy
#
################################################################################

function Base.deepcopy_internal(x::RelFinFieldElem{S, T}, id::IdDict) where {S, T}
  return RelFinFieldElem{S, T}(x.parent, Base.deepcopy_internal(x.data, id))
end

################################################################################
#
#  Promotion rules
#
################################################################################

AbstractAlgebra.promote_rule(::Type{RelFinFieldElem{S, T}}, ::Type{fmpz}) where {S, T} = RelFinFieldElem{S, T}

AbstractAlgebra.promote_rule(::Type{fmpz}, ::Type{RelFinFieldElem{S, T}}) where {S, T} = RelFinFieldElem{S, T}

function AbstractAlgebra.promote_rule(::Type{RelFinFieldElem{RelFinField{S}, T}}, ::Type{V}) where {S, T, V <: Union{fq_nmod, fq, gfp_elem, gfp_fmpz_elem}}
  U = AbstractAlgebra.promote_rule(S, fq_nmod)
  if U === S
    return RelFinFieldElem{RelFinField{S}, T}
  else
    return Union{}
  end
end

function AbstractAlgebra.promote_rule(::Type{V}, ::Type{RelFinFieldElem{RelFinField{S}, T}}) where {S, T, V <: Union{fq_nmod, fq, gfp_elem, gfp_fmpz_elem}}
  U = AbstractAlgebra.promote_rule(S, fq_nmod)
  if U === S
    return RelFinFieldElem{RelFinField{S}, T}
  else
    return Union{}
  end
end

function AbstractAlgebra.promote_rule(::Type{RelFinFieldElem{RelFinField{S}, T}}, ::Type{RelFinFieldElem{RelFinField{U}, V}}) where {S <: FinFieldElem, T, U <: FinFieldElem, V}
  NT = AbstractAlgebra.promote_rule(S, U)
  if NT === S
    return RelFinFieldElem{RelFinField{S}, T}
  elseif NT === U
    return RelFinFieldElem{RelFinField{U}, V}
  else
    return Union{}
  end
end

function AbstractAlgebra.promote_rule(::Type{Hecke.RelFinFieldElem{Hecke.RelFinField{S},T}}, ::Type{Hecke.RelFinFieldElem{Hecke.RelFinField{S},T}}) where {S <: FinFieldElem, T}
  return Hecke.RelFinFieldElem{Hecke.RelFinField{S},T}
end

################################################################################
#
#  Basic properties of elements
#
################################################################################

parent(a::RelFinFieldElem) = a.parent
data(a::RelFinFieldElem) = a.data

iszero(x::RelFinFieldElem) = iszero(x.data)
isone(x::RelFinFieldElem) = isone(x.data)
isunit(x::RelFinFieldElem) = !iszero(x)

==(x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T} = x.data == y.data

coeff(a::RelFinFieldElem, i::Int) = coeff(a.data, i)

one(F::RelFinField{S}) where {S} = F(one(parent(defining_polynomial(F))))

zero(F::RelFinField{S}) where {S} = F(parent(defining_polynomial(F))())

function zero!(x::RelFinFieldElem)
  zero!(x.data)
  return x
end

elem_type(F::RelFinField{T}) where T = RelFinFieldElem{RelFinField{T}, dense_poly_type(T)}
elem_type(::Type{RelFinField{T}}) where T  = RelFinFieldElem{RelFinField{T}, dense_poly_type(T)}

parent_type(::RelFinFieldElem{S, T}) where {S, T} = S
parent_type(::Type{RelFinFieldElem{S, T}}) where {S, T}  = S

gen(F::RelFinField) = F(gen(parent(defining_polynomial(F))))

################################################################################
#
#  Special Coercion
#
################################################################################

function (F::RelFinField)()
  x = parent(defining_polynomial(F))()
  return RelFinFieldElem{typeof(F), typeof(x)}(F, x)
end

function (F::RelFinField{T})(x::S) where {S <: IntegerUnion, T}
  return F(parent(defining_polynomial(F))(x))
end

function (F::RelFinField{T})(x::PolyElem{T}) where T
  r = mod(x, defining_polynomial(F))
  return RelFinFieldElem{typeof(F), typeof(r)}(F, r)
end

function (F::RelFinField{T})(x::T) where {T}
  Kx = parent(defining_polynomial(F))
  r = Kx(x)
  return RelFinFieldElem{typeof(F), typeof(r)}(F, r)
end

function (F::RelFinField{T})(x::RelFinFieldElem{RelFinField{T}, S}) where {S, T}
  @assert parent(x) == F
  return x
end

function (F::RelFinField{T})(x::fq_nmod) where T
  y = base_field(F)(x)
  return F(parent(defining_polynomial(F))(y))
end

function (F::RelFinField{T})(x::gfp_elem) where T
  y = base_field(F)(x)
  return F(parent(defining_polynomial(F))(y))
end

function (F::RelFinField{T})(x::fq) where T
  y = base_field(F)(x)
  return F(parent(defining_polynomial(F))(y))
end

function (F::RelFinField{T})(x::gfp_fmpz_elem) where T
  y = base_field(F)(x)
  return F(parent(defining_polynomial(F))(y))
end

function (F::RelFinField{T})(x::S) where {S, T}
  U = AbstractAlgebra.promote_rule(elem_type(F), S)
  if U == S
    #I an trying to coerce x to the subfield F!
    g = data(x)
    for i = 1:degree(g)
      @assert iszero(coeff(g, i)) "Element not coercible!"
    end
    return F(coeff(g, 0))
  else
    #I an trying to coerce x to the overfield F!
    @assert U == elem_type(F)
    return F(base_field(F)(x))
  end
end

function (F::GaloisField)(a::RelFinFieldElem)
  for i = 1:degree(parent(a))-1
    @assert iszero(coeff(a, i))
  end
  return F(coeff(a, 0))
end

function (F::GaloisField)(a::fq_nmod)
  for i = 1:degree(parent(a))-1
    @assert iszero(coeff(a, i))
  end
  return F(coeff(a, 0))
end

function (F::GaloisFmpzField)(a::RelFinFieldElem)
  for i = 1:degree(parent(a))-1
    @assert iszero(coeff(a, i))
  end
  return F(coeff(a, 0))
end

function (F::GaloisFmpzField)(a::fq)
  for i = 1:degree(parent(a))-1
    @assert iszero(coeff(a, i))
  end
  return F(coeff(a, 0))
end

################################################################################
#
#  Basic operations
#
################################################################################

function Base.:(+)(x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T}
  return RelFinFieldElem{S, T}(parent(x), x.data+y.data)
end

function Base.:(-)(x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T}
  return RelFinFieldElem{S, T}(parent(x), x.data-y.data)
end

function Base.:(-)(x::RelFinFieldElem{S, T}) where {S, T}
  return RelFinFieldElem{S, T}(parent(x), -x.data)
end

function Base.:(*)(x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T}
  F = parent(x)
  @assert F === parent(y)
  return F(x.data*y.data)
end

function mul!(z::RelFinFieldElem{S, T}, x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T}
  z.parent = x.parent
  z.data = mul!(z.data, x.data, y.data)
  z.data = rem!(z.data, z.data, defining_polynomial(z.parent))
  return z
end

function add!(z::RelFinFieldElem{S, T}, x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T}
  z.parent = x.parent
  z.data = add!(z.data, x.data, y.data)
  z.data = rem!(z.data, z.data, defining_polynomial(z.parent))
  return z
end

function sub!(z::RelFinFieldElem{S, T}, x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T}
  z.parent = x.parent
  z.data = sub!(z.data, x.data, y.data)
  z.data = rem!(z.data, z.data, defining_polynomial(z.parent))
  return z
end

function addeq!(z::RelFinFieldElem{S, T}, x::RelFinFieldElem{S, T}) where {S, T}
  z.data = add!(z.data, z.data, x.data)
  z.data = rem!(z.data, z.data, defining_polynomial(parent(z)))
  return z
end

function Base.div(x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T}
  return x*inv(y)
end

function divexact(x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}; check::Bool = true) where {S, T}
  return x*inv(y)
end

function inv(x::RelFinFieldElem{S, T}) where {S, T}
  if iszero(x)
    error("Element not invertible")
  end
  d, a, b = gcdx(x.data, defining_polynomial(parent(x)))
  @assert isone(d)
  return RelFinFieldElem{S, T}(parent(x), a)
end

function Base.:(^)(a::RelFinFieldElem, b::Int)
  if b < 0
    return inv(a)^(-b)
  elseif b == 0
    return parent(a)(1)
  elseif b == 1
    return deepcopy(a)
  elseif mod(b, 2) == 0
    c = a^(div(b, 2))
    c = mul!(c, c, c)
    return c
  else
    #mod(b, 2) == 1
    b = a^(b - 1)
    b = mul!(b, b, a)
    return b
  end
end

################################################################################
#
#  Norm and Trace
#
################################################################################

#TODO: resultant or conjugates?
function norm(x::RelFinFieldElem)
  return resultant(x.data, defining_polynomial(parent(x)))
end

function assure_traces(F::RelFinField{T}) where T
  if isdefined(F, :basis_tr)
    return nothing
  end
  res = T[base_field(F)(degree(F))]
  append!(res, polynomial_to_power_sums(defining_polynomial(F), degree(F)-1))
  F.basis_tr = res
  return nothing
end

function tr(x::RelFinFieldElem)
  F = parent(x)
  assure_traces(F)
  res = base_field(F)()
  t = base_field(F)()
  for i = 0:degree(data(x))
    t = mul!(t, F.basis_tr[i+1], coeff(x, i))
    res = add!(res, res, t)
  end
  return res
end

################################################################################
#
#  Minpoly
#
################################################################################

function minpoly(a::T, Rx::PolyRing = PolynomialRing(base_field(parent(a)), "x", cached = false)[1]) where T <:RelFinFieldElem
  F = parent(a)
  d = degree(F)
  p = order(base_field(F))
  conjs = T[a]
  el = a
  for i = 2:d
    el = el^p
    if el != a
      push!(conjs, el)
    else
      break
    end
  end
  Fx, x = PolynomialRing(F, "x", cached = false)
  minp = prod([x - Fx(y) for y in conjs])

  Fp = base_ring(Rx)
  coeffs = Vector{elem_type(Fp)}(undef, degree(minp)+1)
  for i = 0:degree(minp)
    coeffs[i+1] = Fp(coeff(minp, i))
  end
  return Rx(coeffs)
end

################################################################################
#
#  Absolute norm and trace
#
################################################################################

function absolute_norm(x::FinFieldElem)
  F = prime_field(parent(x))
  return F(norm(x))::elem_type(F)
end
function absolute_norm(x::RelFinFieldElem)
  return absolute_norm(norm(x))::elem_type(prime_field(parent(x), cached = false))
end

function absolute_tr(x::FinFieldElem)
  return prime_field(parent(x))(tr(x))
end

function absolute_tr(x::RelFinFieldElem)
  return absolute_tr(tr(x))
end

################################################################################
#
#  Absolute minpoly
#
################################################################################

function absolute_minpoly(a::T, Rx::PolyRing = PolynomialRing(prime_field(parent(a), cached = false), "x", cached = false)[1]) where T <: FinFieldElem
  F = parent(a)
  d = absolute_degree(F)
  p = characteristic(F)
  conjs = T[a]
  el = a
  for i = 2:d
    el = el^p
    if el != a
      push!(conjs, el)
    else
      break
    end
  end
  Fx, x = PolynomialRing(F, "x", cached = false)
  minp = prod(typeof(x)[x - Fx(y) for y in conjs])

  #Now, I need to coerce the polynomial down to a gfp_poly/gfp_fmpz_poly
  Fp = base_ring(Rx)
  coeffs = Vector{elem_type(Fp)}(undef, degree(minp)+1)
  for i = 0:degree(minp)
    coeffs[i+1] = Fp(coeff(minp, i))
  end
  return Rx(coeffs)
end

#Special function in case one knows the degree of the result
function _minpoly(a::T, d::Int) where T <: FinFieldElem
  Fp = prime_field(parent(a))
  tr_in_K = Vector{elem_type(Fp)}(undef, 2*d)
  tr_in_K[1] = absolute_tr(a)
  el = one(parent(a))
  mul!(el, el, a)
  for i = 2:2*d
    mul!(el, el, a)
    tr_in_K[i] = absolute_tr(el)
  end
  fl, res = berlekamp_massey(tr_in_K)
  return res
end

################################################################################
#
#  Absolute basis and coordinates
#
################################################################################

function absolute_basis(F::RelFinField{T}) where T <: FinFieldElem
  BK = absolute_basis(base_field(F))
  gF = gen(F)
  BF = Vector{elem_type(F)}(undef, absolute_degree(F))
  ind = 1
  a = one(F)
  for i = 0:degree(F)-1
    for j = 1:length(BK)
      BF[ind] = a*BK[j]
      ind += 1
    end
    a = a*gF
  end
  return BF
end

function absolute_basis(F::T) where T <: FinField
  return powers(gen(F), degree(F)-1)
end

function absolute_coordinates(x::FinFieldElem)
  F = parent(x)
  Fp = prime_field(F)
  v = Vector{elem_type(Fp)}(undef, degree(F))
  if iszero(x)
    for i = 1:length(v)
      v[i] = Fp()
    end
    return v
  end
  for i = 1:length(v)
    v[i] = Fp(coeff(x, i-1))
  end
  return v
end

function absolute_coordinates(x::RelFinFieldElem)
  F = parent(x)
  f = data(x)
  Fp = prime_field(F)
  v = Vector{elem_type(Fp)}(undef, absolute_degree(F))
  ind = 1
  for i = 0:degree(F)-1
    c = coeff(f, i)
    vc = absolute_coordinates(c)
    for j = 1:length(vc)
      v[ind] = vc[j]
      ind += 1
    end
  end
  return v
end

################################################################################
#
#  Random element
#
################################################################################

function rand(F::RelFinField)
  Rx = parent(defining_polynomial(F))
  return rand(Rx, 0:degree(F)-1)
end

################################################################################
#
#  Interface
#
################################################################################

function FiniteField(f::T, s::String = "a" ; cached::Bool = true, check::Bool = true) where T <: Union{fq_nmod_poly, fq_poly}
  if check
    @assert isirreducible(f)
  end
  k = base_ring(f)
  F = RelFinField(f, Symbol(s))
  return F, gen(F)
end

function FiniteField(f::PolyElem{T}, s::String = "a" ; cached::Bool = true, check::Bool = true) where T <: RelFinFieldElem
  if check
    @assert isirreducible(f)
  end
  F = RelFinField(f, Symbol(s))
  return F, gen(F)
end

################################################################################
#
#  Morphisms
#
################################################################################

function id_hom(F::FinField)
  return Nemo.FinFieldMorphism(F, F, x -> identity(x), x -> identity(x))
end

function inv(f::Nemo.FinFieldMorphism)
  if absolute_degree(domain(f)) != absolute_degree(codomain(f))
    error("Not invertible!")
  end
  return Nemo.FinFieldMorphism(codomain(f), domain(f), inverse_fn(f), image_fn(f))
end

function hom(F::FinField, K::RelFinField, a::RelFinFieldElem; check::Bool = true)
  @assert parent(a) == K

  if check
    @assert iszero(defining_polynomial(F)(a))
  end

  #We need a preimage function
  p = characteristic(K)
  Kp = prime_field(K)
  Kpx = PolynomialRing(Kp, "x", cached = false)[1]
  Fp = prime_field(F)
  Fpx = PolynomialRing(Fp, "x", cached = false)[1]
  M = zero_matrix(Kp, absolute_degree(F), absolute_degree(K))
  el = one(K)
  M[1, 1] = one(Kp)
  for i = 2:nrows(M)
    el = mul!(el, el, a)
    v = absolute_coordinates(el)
    for j = 1:ncols(M)
      M[i, j] = Kp(v[j])
    end
  end

  aux = zero_matrix(Kp, 1, absolute_degree(F))
  aux1 = zero_matrix(Kp, 1, absolute_degree(K))
  bF = absolute_basis(F)
  bK = absolute_basis(K)
  function img(x::FinFieldElem)
    @assert parent(x) == F
    cx = absolute_coordinates(x)
    for i = 1:absolute_degree(F)
      aux[1, i] = Kp(cx[i])
    end
    mul!(aux1, aux, M)
    pol = sum(aux1[1, i]*bK[i] for i = 1:absolute_degree(K))
    return pol
  end

  function preimg(x::FinFieldElem)
    @assert parent(x) == K
    cx = absolute_coordinates(x)
    for i = 1:absolute_degree(K)
      aux1[1, i] = Kp(cx[i])
    end
    fl, y = can_solve_with_solution(M, aux1, side = :left)
    if !fl
      error("The element is not in the image!")
    end
    polF = sum(y[1, i]*bF[i] for i = 1:absolute_degree(F))
    return polF
  end

  return Nemo.FinFieldMorphism(F, K, img, preimg)
end

################################################################################
#
#  Absolute Field
#
################################################################################

function _char(F::FqFiniteField)
  return characteristic(F)
end

function _char(F::FqNmodFiniteField)
  return Int(characteristic(F))
end

function _char(F::RelFinField)
  return _char(base_field(F))
end

function absolute_field(F::T) where T <: FinField
  return F, id_hom(F)
end

function absolute_field(F::RelFinField{T}; cached::Bool = true) where T <: FinFieldElem
  if isdefined(F, :absolute_field)
    res_map = F.absolute_field
    return domain(res_map), res_map
  end
  p = _char(F)
  d = absolute_degree(F)
  K, gK = FiniteField(p, d, "a", cached = cached)
  k, mk = absolute_field(base_field(F))
  def_pol_new = map_coefficients(pseudo_inv(mk), defining_polynomial(F))
  img_gen_k = roots(defining_polynomial(k), K)[1]
  mp = hom(k, K, img_gen_k)
  g = map_coefficients(mp, def_pol_new)
  img_gen_F = roots(g)[1]
  img_basis_k = powers(img_gen_k, degree(k)-1)
  img_absolute_basis = Vector{elem_type(K)}(undef, degree(K))
  ind = 1
  el = one(K)
  for i = 0:degree(F)-1
    for j = 1:length(img_basis_k)
      img_absolute_basis[ind] = el*img_basis_k[j]
      ind += 1
    end
    el *= img_gen_F
  end
  #Now, I need to construct the hom.
  Fp = prime_field(K)
  M = zero_matrix(Fp, degree(K), degree(K))
  for i = 1:length(img_absolute_basis)
    for j = 0:degree(K)-1
      M[i, j+1] = coeff(img_absolute_basis[i], j)
    end
  end
  Minv = inv(M)
  abs_basis = absolute_basis(F)
  aux = zero_matrix(Fp, 1, degree(K))
  function img(x::FinFieldElem)
    @assert parent(x) == K
    for j = 1:degree(K)
      aux[1, j] = coeff(x, j-1)
    end
    mul!(aux, aux, Minv)
    el = F()
    for i = 1:degree(K)
      if !iszero(aux[1, i])
        el += aux[1, i]*abs_basis[i]
      end
    end
    return el
  end

  Fpx = PolynomialRing(Fp)[1]

  function preimg(x::RelFinFieldElem)
    @assert parent(x) == F
    v = absolute_coordinates(x)
    for j = 1:degree(K)
      aux[1, j] = v[j]
    end
    mul!(aux, aux, M)
    v1 = typeof(v[1])[aux[1, j] for j = 1:ncols(aux)]
    return K(Fpx(v1))
  end

  return K, Nemo.FinFieldMorphism(K, F, img, preimg)
end

################################################################################
#
#  Polynomial factorization
#
################################################################################

function factor(f::PolyElem{T}) where T <: RelFinFieldElem
  K = base_ring(f)
  Kx = parent(f)
  F, mF = absolute_field(K)
  imF = inv(mF)
  @assert domain(imF) == K
  fF = map_coefficients(imF, f)
  lfF = factor(fF)
  facs = Dict{typeof(f), Int}()
  for (p, k) in lfF
    facs[map_coefficients(mF, p, parent = Kx)] = k
  end
  return Fac(map_coefficients(mF, lfF.unit, parent = Kx), facs)
end

function isirreducible(f::PolyElem{T}) where T <: RelFinFieldElem
  l = factor(f)
  return length(l.fac) == 1
end

function (Rx::GFPPolyRing)(a::fq_nmod)
  el = Rx()
  for i = 0:degree(parent(a))
    setcoeff!(el, i, base_ring(Rx)(coeff(a, i)))
  end
  return el
end

function norm(f::PolyElem{fq_nmod})
  Fx = parent(f)
  Fp = prime_field(base_ring(Fx))
  Fpx = PolynomialRing(Fp, "x", cached = false)[1]
  Fpxy = PolynomialRing(Fpx, "y", cached = false)[1]

  dp = defining_polynomial(base_ring(Fx), Fpx)
  T = Fpxy()
  for i = 0:degree(dp)
    setcoeff!(T, i, Fpx(coeff(dp, i)))
  end
  h = fq_nmod_to_xy(f, Fpxy, Fpx)
  res = resultant(T, h)
  return res
end

function fq_nmod_to_xy(f, Qxy::PolyRing, Qx::PolyRing)
  K = base_ring(f)
  Qy = parent(defining_polynomial(K, prime_field(K)))
  y = gen(Qx)

  res = zero(Qxy)
  for i=degree(f):-1:0
    res *= y
    res += change_base_ring(Qx, Qy(coeff(f, i)), parent = Qxy)
  end
  return res
end


text:
# Create example data
angles = LinRange(0, 360, 40)
radii = LinRange(0, 2, 40)
# Draw the polar plot in degrees
polar(angles, radii, radians=false)

ext: jl


text:
"""
    qo_to_nq_basis(basis)

Converts a QuantumOptics.jl basis to NeuralQuantum basis of the hilbert
space.
"""
function qo_to_nq_basis(b::Basis)
    hilb_shape = b.shape
    if all(first(hilb_shape) .== hilb_shape)
        if first(b.bases) isa SpinBasis
            hilb = HomogeneousSpin(length(hilb_shape), first(b.bases).spinnumber)
        else
            hilb = HomogeneousFock(length(hilb_shape), first(hilb_shape))
        end
    else
        hilb = DiscreteHilbert(hilb_shape)
    end
    return hilb
end

# No op
qo_to_nq_basis(b::AbstractHilbert) = b

function nq_to_qo_basis(b::HomogeneousFock)
    cutoff = local_dim(b)
    N = nsites(b)
    lb = FockBasis(cutoff-1)
    return lb^N
end

function nq_to_qo_basis(b::HomogeneousSpin)
    cutoff = local_dim(b)
    S = (cutoff-1)//2
    N = nsites(b)
    lb = SpinBasis(S)
    return lb^N
end

function nq_to_qo_basis(b::SuperOpSpace)
    qo_b = nq_to_qo_basis(physical(b))
    return (qo_b, qo_b)
end

Base.convert(::Type{<:CompositeBasis}, b::AbstractHilbert) =
    nq_to_qo_basis(b)


text:
function gillespie_meta(mutfunc, # virulence mutation function
                   T::Real; # max time
                   # variable parameters
                   S::AbstractVector{IntType}, # susceptible host population sizes
                   I::AbstractMatrix{IntType}, # infected host population sizes
                   R::AbstractMatrix{IntType}, # infected host population sizes
                   v::AbstractVector{RealType}, # virulences
                   # fixed parameters
                   β::RealType, # infect coefficient
                   b::RealType, # birth rate
                   d::RealType, # death rate
                   r::RealType, # recovery rate
                   μ::RealType, # immunity loss rate
                   mt::RealType, # matation rate
                   mg::RealType, # migration rate
                   maxepoch::Integer = 10_000_000) where {IntType <: Integer,RealType <: Real}
    length(S) == size(I, 2) == size(R, 2) || error("S, I, R must have the same metapopulation size!")
    length(v) == size(I, 1) == size(R, 1) || error("S, I, R must have the same number of viruses species!")

    t =  zero(RealType) # initial time
    epoch = 0x0000000000000000 # init epoch

    @apply copy S I R v

    sum_I = sum(I, dims = 1)
    sum_R = sum(R, dims = 1)
    p_I = I ./ sum_I
    E_v = sum(p_I .* v, dims = 1)
    dynamics_S = Dynamics.(t, S)
    dynamics_I = Dynamics.(t, sum_I)
    dynamics_R = Dynamics.(t, sum_R)
    dynamics_v = Dynamics.(t, E_v)

    maxepoch = UInt(maxepoch)
    while t <= T && epoch <= maxepoch && length(I) > 0
        epoch += 0x0000000000000001

        # calculate reactions

        viruses_num, population_num = size(I)

        reproduction_S = b * S
        reproduction_I = b * I
        reproduction_R = b * R

        death_S = d * S
        death_I = d * I
        death_R = d * R

        total_num = transpose(S) + sum(I, dims = 1) + sum(R, dims = 1)
        migration_S = Array{RealType}(undef, population_num, population_num)
        migration_I = Array{RealType}(undef, viruses_num, population_num, population_num)
        migration_R = Array{RealType}(undef, viruses_num, population_num, population_num)
        for i in 1:population_num
            migration_S[:, i] = total_num[i] * mg * S
            migration_I[:, :, i] = total_num[i] * mg * I
            migration_R[:, :, i] = total_num[i] * mg * R
            migration_S[i, i] = 0
            migration_I[:, i, i] = zeros(RealType, viruses_num)
            migration_R[:, i, i] = zeros(RealType, viruses_num)
        end

        infect_S = Array{RealType}(undef, viruses_num, population_num)
        infect_R = Array{RealType}(undef, viruses_num, viruses_num, population_num)
        for i in 1:population_num
            Ii = slicecol(I, i, viruses_num)
            Ri = slicecol(R, i, viruses_num)
            infect_S[:, i] = β * S[i] * Ii
            infect_R[:, :, i] = zeroatdiag!(β * Ii * transpose(Ri))
        end

        recovery = r * I
        immuneloss = μ * R

        kill = v .* I

        pathogenmutation = mt * I

        τ, r_idx, idx = choosereaction(reproduction_S, reproduction_I, reproduction_R,
                                       death_S, death_I, death_R,
                                       migration_S, migration_I, migration_R,
                                       infect_S, infect_R, recovery, immuneloss,
                                       kill, pathogenmutation)

        t += τ # time goes

        if r_idx == 1 # S reproduction
            S[idx] += 1
        elseif r_idx == 2 # I reproduction
            S[idx[2]] += 1
        elseif r_idx == 3 # R reproduction
            S[idx[2]] += 1
        elseif r_idx == 4 # S death
            S[idx] -= 1
        elseif r_idx == 5 # I death
            i, j = idx
            I[i, j] -= 1
            if minimum(I[i, :] .<= 0) && minimum(R[i, :] .<= 0)
                I = I[1:end .!= i, :]
                R = R[1:end .!= i, :]
                deleteat!(v, i)
            end
        elseif r_idx == 6 # R death
            i, j = idx
            R[i, j] -= 1
            if minimum(I[i, :] .<= 0) && minimum(R[i, :] .<= 0)
                I = I[1:end .!= i, :]
                R = R[1:end .!= i, :]
                deleteat!(v, i)
            end
        elseif r_idx == 7 # S migration
            i, j = idx
            S[i] -= 1
            S[j] += 1
        elseif r_idx == 8 # I migration
            i, j, k = idx
            I[i, j] -= 1
            I[i, k] += 1
        elseif r_idx == 9 # R migration
            i, j, k = idx
            R[i, j] -= 1
            R[i, k] += 1
        elseif r_idx == 10 # I_i infect S
            S[idx[2]] -= 1
            I[idx] += 1
        elseif r_idx == 11 # I_i infect R_j
            i, j, k = idx
            I[i, k] += 1

            R[j, k] -= 1
            if minimum(I[j, :] .<= 0) && minimum(R[j, :] .<= 0)
                I = I[1:end .!= j, :]
                R = R[1:end .!= j, :]
                deleteat!(v, j)
            end
        elseif r_idx == 12 # recovery
            I[idx] -= 1
            R[idx] += 1
        elseif r_idx == 13 # immunity loss
            i, j = idx
            S[j] += 1
            R[i, j] -= 1
            if minimum(I[i, :] .<= 0) && minimum(R[i, :] .<= 0)
                I = I[1:end .!= i, :]
                R = R[1:end .!= i, :]
                deleteat!(v, i)
            end
        elseif r_idx == 14 # pathogen kill host
            i, j = idx
            I[i, j] -= 1
            if minimum(I[i, :] .<= 0) && minimum(R[i, :] .<= 0)
                I = I[1:end .!= i, :]
                R = R[1:end .!= i, :]
                deleteat!(v, i)
            end
        elseif r_idx == 15 # pathogen mutation
            i, j = idx
            I = vcat(I, repeat([zero(IntType)], outer = (1, population_num)))
            R = vcat(R, repeat([zero(IntType)], outer = (1, population_num)))
            I[i, j] -= 1
            I[end, j] += 1
            new_v = mutfunc(v[i])
            push!(v, new_v)

            if minimum(I[i, :] .<= 0) && minimum(R[i, :] .<= 0)
                I = I[1:end .!= i, :]
                R = R[1:end .!= i, :]
                deleteat!(v, i)
            end
        end
        sum_I = sum(I, dims = 1)
        sum_R = sum(R, dims = 1)
        p_I = I ./ sum_I
        E_v = sum(p_I .* v, dims = 1)
        record!.(dynamics_S, t, S)
        record!.(dynamics_I, t, sum_I)
        record!.(dynamics_R, t, sum_R)
        record!.(dynamics_v, t, E_v)
    end
    println("Simulation ends at epoch ", Int(epoch), "!")
    dynamics_S, dynamics_I, dynamics_R, dynamics_v
end


text:
mbpP() = runbool(`env brishz_failure_expected=y brishzq.zsh isMBP`)
export mbpP


text:
module TestDataTableRow
    using Base.Test
    using DataTables, Compat

    dt = DataTable(a=NullableArray([1,   2,   3,   1,   2,   2 ]),
                   b=NullableArray(Nullable{Float64}[2.0, Nullable(),
                                                     1.2, 2.0,
                                                     Nullable(), Nullable()]),
                   c=NullableArray(Nullable{String}["A", "B", "C", "A", "B", Nullable()]),
                   d=NullableCategoricalArray(Nullable{Symbol}[:A,  Nullable(),  :C,  :A,
                                                           Nullable(),  :C]))
    dt2 = DataTable(a = NullableArray([1, 2, 3]))

    #
    # Equality
    #
    @test_throws ArgumentError isequal(DataTableRow(dt, 1), DataTableRow(dt2, 1))
    @test !isequal(DataTableRow(dt, 1), DataTableRow(dt, 2))
    @test !isequal(DataTableRow(dt, 1), DataTableRow(dt, 3))
    @test isequal(DataTableRow(dt, 1), DataTableRow(dt, 4))
    @test isequal(DataTableRow(dt, 2), DataTableRow(dt, 5))
    @test !isequal(DataTableRow(dt, 2), DataTableRow(dt, 6))

    # isless()
    dt4 = DataTable(a=NullableArray([1, 1, 2, 2, 2, 2, Nullable(), Nullable()]),
                    b=NullableArray([2.0, 3.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0]),
                    c=NullableArray([:B, Nullable(), :A, :C, :D, :D, :A, :A]))
    @test isless(DataTableRow(dt4, 1), DataTableRow(dt4, 2))
    @test !isless(DataTableRow(dt4, 2), DataTableRow(dt4, 1))
    @test !isless(DataTableRow(dt4, 1), DataTableRow(dt4, 1))
    @test isless(DataTableRow(dt4, 1), DataTableRow(dt4, 3))
    @test !isless(DataTableRow(dt4, 3), DataTableRow(dt4, 1))
    @test isless(DataTableRow(dt4, 3), DataTableRow(dt4, 4))
    @test !isless(DataTableRow(dt4, 4), DataTableRow(dt4, 3))
    @test isless(DataTableRow(dt4, 4), DataTableRow(dt4, 5))
    @test !isless(DataTableRow(dt4, 5), DataTableRow(dt4, 4))
    @test !isless(DataTableRow(dt4, 6), DataTableRow(dt4, 5))
    @test !isless(DataTableRow(dt4, 5), DataTableRow(dt4, 6))
    @test isless(DataTableRow(dt4, 7), DataTableRow(dt4, 8))
    @test !isless(DataTableRow(dt4, 8), DataTableRow(dt4, 7))

    # hashing
    @test !isequal(hash(DataTableRow(dt, 1)), hash(DataTableRow(dt, 2)))
    @test !isequal(hash(DataTableRow(dt, 1)), hash(DataTableRow(dt, 3)))
    @test isequal(hash(DataTableRow(dt, 1)), hash(DataTableRow(dt, 4)))
    @test isequal(hash(DataTableRow(dt, 2)), hash(DataTableRow(dt, 5)))
    @test !isequal(hash(DataTableRow(dt, 2)), hash(DataTableRow(dt, 6)))

    # check that hashrows() function generates the same hashes as DataTableRow
    dt_rowhashes = DataTables.hashrows(dt)
    @test dt_rowhashes == [hash(dr) for dr in eachrow(dt)]

    # test incompatible frames
    @test_throws UndefVarError isequal(DataTableRow(dt, 1), DataTableRow(dt3, 1))

    # test RowGroupDict
    N = 20
    d1 = rand(map(Int64, 1:2), N)
    dt5 = DataTable(Any[d1], [:d1])
    dt6 = DataTable(d1 = [2,3])

    # test_group("groupby")
    gd = DataTables.group_rows(dt5)
    @test gd.ngroups == 2

    # getting groups for the rows of the other frames
    @test length(gd[DataTableRow(dt6, 1)]) > 0
    @test_throws KeyError gd[DataTableRow(dt6, 2)]
    @test isempty(DataTables.findrows(gd, dt6, (gd.dt[1],), (dt6[1],), 2))

    # grouping empty frame
    gd = DataTables.group_rows(DataTable(x=Int[]))
    @test gd.ngroups == 0

    # grouping single row
    gd = DataTables.group_rows(dt5[1,:])
    @test gd.ngroups == 1
end


text:
"""
    ArcSwift()

Parser configuration for arc-swift dependency parsing.

Described in [Qi & Manning 2017](https://nlp.stanford.edu/pubs/qi2017arcswift.pdf).
"""
struct ArcSwift <: AbstractTransitionSystem end

initconfig(::ArcSwift, graph::DependencyTree) = ArcSwiftConfig(graph)
initconfig(::ArcSwift, deptype, words) = ArcSwiftConfig{deptype}(words)

transition_space(::ArcSwift, labels=[]; max_k=5) =
    isempty(labels) ? [LeftArc.(1:max_k)..., RightArc.(1:max_k)..., Shift()] :
    [[LeftArc(k, l) for k in 1:max_k for l in labels]...,
     [RightArc(k, l) for k in 1:max_k for l in labels]...,
     Shift()]

projective_only(::ArcSwift) = true

struct ArcSwiftConfig{T} <: AbstractParserConfiguration{T}
    σ::Vector{Int}
    β::Vector{Int}
    A::Vector{T}
end

function ArcSwiftConfig{T}(words) where T
    σ = [0]
    β = collect(1:length(words))
    A = [unk(T, id, w) for (id, w) in enumerate(words)]
    ArcSwiftConfig{T}(σ, β, A)
end

function ArcSwiftConfig{T}(gold::DependencyTree) where T
    σ = [0]
    β = collect(1:length(gold))
    A = [dep(word, head=-1) for word in gold]
    ArcSwiftConfig{T}(σ, β, A)
end
ArcSwiftConfig(gold::DependencyTree) = ArcSwiftConfig{eltype(gold)}(gold)

stack(cfg::ArcSwiftConfig)  = cfg.σ
buffer(cfg::ArcSwiftConfig) = cfg.β

token(cfg::ArcSwiftConfig, i) = iszero(i) ? root(deptype(cfg)) :
                                i == -1   ? noval(deptype(cfg)) :
                                cfg.A[i]
tokens(cfg::ArcSwiftConfig) = cfg.A
tokens(cfg::ArcSwiftConfig, is) = [token(cfg, i) for i in is if 0 <= i <= length(cfg.A)]

function leftarc(cfg::ArcSwiftConfig, k::Int, args...; kwargs...)
    # Assert a head-dependent relation between the word at the front
    # of the input buffer and the word at the top of the stack; pop
    # the stack.
    i = length(cfg.σ) - k + 1
    s, b = cfg.σ[i], cfg.β[1]
    A = copy(cfg.A)
    if s > 0
        A[s] = dep(A[s], args...; head=b, kwargs...)
    end
    ArcSwiftConfig(cfg.σ[1:i-1], cfg.β, A)
end

function rightarc(cfg::ArcSwiftConfig, k::Int, args...; kwargs...)
    # Assert a head-dependent relation between the word on the top of
    # the σ and the word at front of the input buffer; shift the
    # word at the front of the input buffer to the stack.
    i = length(cfg.σ) - k + 1
    s, b = cfg.σ[i], cfg.β[1]
    A = copy(cfg.A)
    A[b] = dep(A[b], args...; head=s, kwargs...)
    ArcSwiftConfig([cfg.σ[1:i] ; b], cfg.β[2:end], A)
end

function shift(cfg::ArcSwiftConfig)
    # Remove the word from the front of the input buffer and push it
    # onto the stack.
    ArcSwiftConfig([cfg.σ ; cfg.β[1]], cfg.β[2:end], cfg.A)
end

isfinal(cfg::ArcSwiftConfig) =
    all(a -> head(a) >= 0, cfg.A) #&& length(cfg.σ) > 0 && length(cfg.β) > 0

"""
    static_oracle(::ArcSwiftConfig, graph)

Return a training oracle function which returns gold transition
operations from a parser configuration with reference to `graph`.

Described in [Qi & Manning 2017](https://nlp.stanford.edu/pubs/qi2017arcswift.pdf).
"""
function static_oracle(cfg::ArcSwiftConfig, tree, arc=untyped)
    l = i -> arc(tree[i])
    S = length(cfg.σ)
    if S >= 1 && length(cfg.β) >= 1
        b = cfg.β[1]
        for k in 1:S
            i = S - k + 1
            s = cfg.σ[i]
            if has_arc(tree, b, s)
                return LeftArc(k, l(s)...)
            elseif has_arc(tree, s, b)
                return RightArc(k, l(b)...)
            end
        end
    end
    return Shift()
end

==(cfg1::ArcSwiftConfig, cfg2::ArcSwiftConfig) =
    cfg1.σ == cfg2.σ && cfg1.β == cfg2.β && cfg1.A == cfg2.A

# TODO
function possible_transitions(cfg::ArcSwiftConfig, graph::DependencyTree, arc=untyped)
    TransitionOperator[static_oracle(cfg, graph, arc)]
end

Base.show(io::IO, c::ArcSwiftConfig) =
    print(io, "ArcSwiftConfig($(c.σ),$(c.β))\n$(join([join([id(t),form(t),head(t)],'\t') for t in tokens(c)],'\n'))")


text:
# Here, we illustrate a pure ModernGL implementation of some polygon drawing
using ModernGL, GeometryTypes, GLFW

# Create the window. This sets all the hints and makes the context current.
window = GLFW.Window(name="Drawing polygons 5", resolution=(800,600))

# The shaders. Here we do everything manually, but life will get
# easier with GLAbstraction. See drawing_polygons5.jl for such an
# implementation.

# The vertex shader
vertex_source = Vector{UInt8}("""
#version 150

in vec2 position;
in vec3 color;

out vec3 Color;

void main()
{
    Color = color;
    gl_Position = vec4(position, 0.0, 1.0);
}
""")

# The fragment shader
fragment_source = Vector{UInt8}("""
# version 150

in vec3 Color;

out vec4 outColor;

void main()
{
    outColor = vec4(Color, 1.0);
}
""")

# Compile the vertex shader
vertex_shader = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vertex_shader, 1, Ptr{UInt8}[pointer(vertex_source)], Ref{GLint}(length(vertex_source)))  # nicer thanks to GLAbstraction
glCompileShader(vertex_shader)
# Check that it compiled correctly
status = Ref(GLint(0))
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, status)
if status[] != GL_TRUE
    buffer = Array(UInt8, 512)
    glGetShaderInfoLog(vertex_shader, 512, C_NULL, buffer)
    @error "$(unsafe_string(pointer(buffer), 512))"
end

# Compile the fragment shader
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fragment_shader, 1, Ptr{UInt8}[pointer(fragment_source)], Ref{GLint}(length(fragment_source)))  # nicer thanks to GLAbstraction
glCompileShader(fragment_shader)
# Check that it compiled correctly
status = Ref(GLint(0))
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, status)
if status[] != GL_TRUE
    buffer = Array(UInt8, 512)
    glGetShaderInfoLog(fragment_shader, 512, C_NULL, buffer)
    @error "$(unsafe_string(pointer(buffer), 512))"
end

# Connect the shaders by combining them into a program
shader_program = glCreateProgram()
glAttachShader(shader_program, vertex_shader)
glAttachShader(shader_program, fragment_shader)
glBindFragDataLocation(shader_program, 0, "outColor") # optional

glLinkProgram(shader_program)
glUseProgram(shader_program)

# The vertices of our triangle, with color
positions = Point{2,Float32}[(0,    0.5),   # red vertex
                            ( 0.5, -0.5),   # green vertex
                            (-0.5, -0.5)]   # blue vertex

colors = Vec3f0[(1, 0, 0),                     # top-left
                (0, 1, 0),                     # top-right
                (0, 0, 1)]

vao = Ref(GLuint(0))
glGenVertexArrays(1, vao)
glBindVertexArray(vao[])

# Create the Vertex Buffer Objects (VBO)
vbo = Ref(GLuint(0))   # initial value is irrelevant, just allocate space
glGenBuffers(1, vbo)
glBindBuffer(GL_ARRAY_BUFFER, vbo[])
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW)
# Link vertex data to attributes
pos_attribute = glGetAttribLocation(shader_program, "position")
glEnableVertexAttribArray(pos_attribute)
glVertexAttribPointer(pos_attribute, 2,
                      GL_FLOAT, GL_FALSE, 0, C_NULL)

# Color VBO
vbo1 = Ref(GLuint(0))
glGenBuffers(1, vbo1)
glBindBuffer(GL_ARRAY_BUFFER, vbo1[])
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW)

# Link color data to attributes
col_attribute = glGetAttribLocation(shader_program, "color")
glBindBuffer(GL_ARRAY_BUFFER, vbo1[])
glEnableVertexAttribArray(col_attribute)
glVertexAttribPointer(col_attribute, 3,
                      GL_FLOAT, GL_FALSE, 0, C_NULL)

# Draw while waiting for a close event
glClearColor(0,0,0,0)
while !GLFW.WindowShouldClose(window)
    glClear(GL_COLOR_BUFFER_BIT)
    glDrawArrays(GL_TRIANGLES, 0, length(positions))
    GLFW.SwapBuffers(window)
    GLFW.PollEvents()
    if GLFW.GetKey(window, GLFW.KEY_ESCAPE) == GLFW.PRESS
        GLFW.SetWindowShouldClose(window, true)
    end
end
GLFW.SetWindowShouldClose(window, false)

# Now we define another geometry that we will render, a rectangle, this one with an index buffer
# The positions of the vertices in our rectangle
positions = Point{2,Float32}[(-0.5,  0.5),     # top-left
                             ( 0.5,  0.5),     # top-right
                             ( 0.5, -0.5),     # bottom-right
                             (-0.5, -0.5)]     # bottom-left

# The colors assigned to each vertex
colors = Vec3f0[(1, 0, 0),                     # top-left
                (0, 1, 0),                     # top-right
                (0, 0, 1),                     # bottom-right
                (1, 1, 1)]                     # bottom-left

# Specify how vertices are arranged into faces
# Face{N,T} type specifies a face with N vertices, with index type
# T (you should choose UInt32), and index-offset O. If you're
# specifying faces in terms of julia's 1-based indexing, you should set
# O=0. (If you instead number the vertices starting with 0, set
# O=-1.)
elements = Face{3,UInt32}[(0,1,2),          # the first triangle
                          (2,3,0)]          # the second triangle

vao = Ref(GLuint(0))
glGenVertexArrays(1, vao)
glBindVertexArray(vao[])

# Create the Vertex Buffer Objects (VBO)
vbo = Ref(GLuint(0))   # initial value is irrelevant, just allocate space
glGenBuffers(1, vbo)
glBindBuffer(GL_ARRAY_BUFFER, vbo[])
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW)
# Link vertex data to attributes
pos_attribute = glGetAttribLocation(shader_program, "position")
glEnableVertexAttribArray(pos_attribute)
glVertexAttribPointer(pos_attribute, 2,
                      GL_FLOAT, GL_FALSE, 0, C_NULL)

# Color VBO
vbo1 = Ref(GLuint(0))
glGenBuffers(1, vbo1)
glBindBuffer(GL_ARRAY_BUFFER, vbo1[])
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW)

# Link color data to attributes
col_attribute = glGetAttribLocation(shader_program, "color")
glBindBuffer(GL_ARRAY_BUFFER, vbo1[])
glEnableVertexAttribArray(col_attribute)
glVertexAttribPointer(col_attribute, 3,
                      GL_FLOAT, GL_FALSE, 0, C_NULL)

# Create the Element Buffer Object (EBO)
ebo = Ref(GLuint(0))
glGenBuffers(1, ebo)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[])
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW)

# Draw while waiting for a close event
glClearColor(0,0,0,0)
while !GLFW.WindowShouldClose(window)
    glClear(GL_COLOR_BUFFER_BIT)
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, C_NULL)
    GLFW.SwapBuffers(window)
    GLFW.PollEvents()
    if GLFW.GetKey(window, GLFW.KEY_ESCAPE) == GLFW.PRESS
        GLFW.SetWindowShouldClose(window, true)
    end
end

GLFW.DestroyWindow(window)  # needed if you're running this from the REPL


text:
export convolutionProductFun

#
# A ProductFun constructor for bivariate functions on Intervals
# defined as the distance of their arguments.
#

function convolutionProductFun{U<:UnivariateSpace,V<:UnivariateSpace}(f::Function,u::U,v::V;tol=eps())
    du,dv = domain(u),domain(v)
    ext = extrema(du,dv)
    if ext[1] == 0
        ff = Fun(z->f(0,z),Chebyshev(Interval(-ext[2]/2,ext[2]/2)))
        fd,T = ff(0),eltype(ff)
        c = chop(coefficients(ff),norm(coefficients(ff),Inf)*100eps(T))
        N = length(c)
        N1 = isa(du,PeriodicDomain) ? 2N : N
        N2 = isa(dv,PeriodicDomain) ? 2N : N
        return ProductFun((x,y)->x==y?fd:f(x,y),u⊗v,N1,N2;tol=tol)
    else
        ff = Fun(z->f(0,z),Chebyshev(Interval(ext...)))
        c = chop(coefficients(ff),norm(coefficients(ff),Inf)*100eps(eltype(ff)))
        N = length(c)
        N1 = isa(du,PeriodicDomain) ? 2N : N
        N2 = isa(dv,PeriodicDomain) ? 2N : N
        return ProductFun(f,u⊗v,N1,N2;tol=tol)
    end
end

convolutionProductFun{U<:UnivariateSpace,
                      V<:UnivariateSpace,T}(f::Function,
                                            ss::TensorSpace{Tuple{U,V},T,2};kwds...) = convolutionProductFun(f,ss[1],ss[2];kwds...)

#
# ProductFun constructors for functions on periodic intervals.
#

#
# Suppose we are interested in K(ϕ-θ). Then, K(⋅) is periodic
# whether it's viewed as bivariate or univariate.
#

function convolutionProductFun{DD,T,DU,DV}(f::Fun{Fourier{DD},T},u::Fourier{DU},v::Fourier{DV};tol=eps())
    df,du,dv = domain(f),domain(u),domain(v)
    @assert df == du == dv && isa(df,PeriodicInterval)
    c = coefficients(f)
    N = length(c)
    X = zeros(T,N,N)
    X[1,1] += c[1]
    @inbounds for i=2:2:N-1
        X[i,i] += c[i+1]
        X[i+1,i] += c[i]
        X[i,i+1] -= c[i]
        X[i+1,i+1] += c[i+1]
    end
    if mod(N,2)==0 X[N,N-1],X[N-1,N] = c[N],-c[N] end
    ProductFun(X,u⊗v)
end

function convolutionProductFun{S<:CosSpace,T,DU,DV}(f::Fun{S,T},u::Fourier{DU},v::Fourier{DV};tol=eps())
    df,du,dv = domain(f),domain(u),domain(v)
    @assert df == du == dv && isa(df,PeriodicInterval)
    c = coefficients(f)
    N = 2length(c)-1
    X = zeros(T,N,N)
    X[1,1] += c[1]
    @inbounds for i=2:2:N
        X[i,i] += c[div(i,2)+1]
        X[i+1,i+1] += c[div(i,2)+1]
    end
    ProductFun(X,u⊗v)
end

function convolutionProductFun{S<:SinSpace,T,DU,DV}(f::Fun{S,T},u::Fourier{DU},v::Fourier{DV};tol=eps())
    df,du,dv = domain(f),domain(u),domain(v)
    @assert df == du == dv && isa(df,PeriodicInterval)
    c = coefficients(f)
    N = 2length(c)+1
    X = zeros(T,N,N)
    @inbounds for i=2:2:N
        X[i+1,i] += c[div(i,2)]
        X[i,i+1] -= c[div(i,2)]
    end
    ProductFun(X,u⊗v)
end

function convolutionProductFun{DS,T,DU,DV}(f::Fun{Laurent{DS},T},u::Laurent{DU},v::Laurent{DV};tol=eps())
    df,du,dv = domain(f),domain(u),domain(v)
    @assert df == du == dv && isa(df,PeriodicInterval)
    c = coefficients(f)
    N = length(c)
    X = mod(N,2) == 0 ? zeros(T,N+1,N) : zeros(T,N,N)
    X[1,1] += c[1]
    @inbounds for i=2:2:N-1
        X[i+1,i] += c[i]
        X[i,i+1] += c[i+1]
    end
    if mod(N,2)==0 X[N+1,N] = c[N] end
    ProductFun(X,u⊗v)
end

function convolutionProductFun{DS,T,DU,DV}(f::Fun{Taylor{DS},T},u::Laurent{DU},v::Laurent{DV};tol=eps())
    df,du,dv = domain(f),domain(u),domain(v)
    @assert df == du == dv && isa(df,PeriodicInterval)
    c = coefficients(f)
    N = 2length(c)-1
    X = zeros(T,N-1,N)
    X[1,1] += c[1]
    @inbounds for i=2:2:N-1
        X[i,i+1] += c[div(i,2)+1]
    end
    ProductFun(X,u⊗v)
end

function convolutionProductFun{DS,T,DU,DV}(f::Fun{Hardy{false,DS},T},u::Laurent{DU},v::Laurent{DV};tol=eps())
    df,du,dv = domain(f),domain(u),domain(v)
    @assert df == du == dv && isa(df,PeriodicInterval)
    c = coefficients(f)
    N = 2length(c)
    X = zeros(T,N+1,N)
    @inbounds for i=2:2:N
        X[i+1,i] += c[div(i,2)]
    end
    ProductFun(X,u⊗v)
end


text:
using PaddleChainRules.Paddle: paddle, PaddleModuleWrapper, PaddleFCNet
using Zygote

dim_ins = 3
hidden_size = 16
dim_outs = 2
batch_size = 32
num_layers = 2

# now only support full connected Dense network
NN = paddle.nn.Sequential(
        paddle.nn.Linear(dim_ins, hidden_size),
        paddle.nn.Sigmoid(),
        paddle.nn.Linear(hidden_size, dim_outs)
    )

jlwrap = PaddleModuleWrapper(NN)

# or use a constructor for full connected network
jlwrap = PaddleFCNet(dim_ins, dim_outs, num_layers, hidden_size; activation="sigmoid")

input = rand(Float32, dim_ins, batch_size)

output = jlwrap(input)

target = rand(Float32, dim_outs, batch_size)
loss(m, x, y) = sum(abs2.(m(x) .- y))

# grad of params
grad, = Zygote.gradient(m->loss(m, input, target), jlwrap)
# grad of input
grad, = Zygote.gradient(x->loss(jlwrap, x, target), input)

max_stars_repo_name: PangHua/InfiniteScience

max_issues_repo_name: PangHua/InfiniteScience

max_forks_repo_name: PangHua/InfiniteScience


text:
const ContactImplicitMPC = Main
include(joinpath(@__DIR__, "..", "src/dynamics", "quadruped", "visuals.jl"))
T = Float64
vis = Visualizer()
open(vis)
# render(vis)

# get simulation
s_no_load = get_simulation("quadruped", "flat_2D_lc", "flat")
s_load = get_simulation("quadruped", "flat_2D_lc", "payload",
    model_variable_name="quadruped_payload",
    dynamics_name="dynamics_payload")
model_no_load = s_no_load.model
model_load = s_load.model
env_no_load = s_no_load.env
env_load = s_load.env

nq = model.dim.q
nu = model.dim.u
nc = model.dim.c

@testset "Check Quadruped Load" begin
    @test (model_load.m_torso - model_no_load.m_torso) == 3.0
    @test (model_load.J_torso - model_no_load.J_torso) == 0.03
    q_ = rand(nq)
    @test (M_func(model_load, q_)[1,1] - M_func(model_no_load, q_)[1,1]) == 3.0
    @test (M_fast(model_load, q_)[1,1] - M_fast(model_no_load, q_)[1,1]) == 3.0
end

# get trajectory
ref_traj_ = deepcopy(ContactImplicitMPC.get_trajectory(s_no_load.model, s_no_load.env,
    joinpath(module_dir(), "src/dynamics/quadruped/gaits/gait2.jld2"),
    load_type = :split_traj_alt))
ref_traj = deepcopy(ref_traj_)

# time
H = ref_traj.H
h = ref_traj.h
N_sample = 5
H_mpc = 10
h_sim = h / N_sample
H_sim = 2100

# barrier parameter
κ_mpc = 1.0e-4

obj = TrackingObjective(model_no_load, env_no_load, H_mpc,
    # q = [Diagonal(1e-2 * [10.0; 0.02; 0.25; 0.25 * ones(model.dim.q-3)]) for t = 1:H_mpc],
    q = [Diagonal(1e-2 * [10.0; 0.02; 0.25; 0.5 * ones(model.dim.q-3)]) for t = 1:H_mpc],
    u = [Diagonal(3e-2 * ones(model.dim.u)) for t = 1:H_mpc],
    γ = [Diagonal(1.0e-100 * ones(model.dim.c)) for t = 1:H_mpc],
    b = [Diagonal(1.0e-100 * ones(model.dim.c * friction_dim(env))) for t = 1:H_mpc])

p = linearized_mpc_policy(ref_traj, s_no_load, obj,
    H_mpc = H_mpc,
    N_sample = N_sample,
    κ_mpc = κ_mpc,
    n_opts = NewtonOptions(
        r_tol = 3e-4,
        solver = :ldl_solver,
        verbose = false,
        max_iter = 5),
    mpc_opts = LinearizedMPCOptions(
        # live_plotting=true,
        altitude_update = true,
        altitude_impact_threshold = 0.05,
        altitude_verbose = true,
        )
    )

# Test open loop policy to see the impact of the load
# p = open_loop_policy(deepcopy(ref_traj.u), N_sample=N_sample)

q1_ref = copy(ref_traj.q[2])
q0_ref = copy(ref_traj.q[1])
q1_sim = SVector{model.dim.q}(q1_ref)
q0_sim = SVector{model.dim.q}(copy(q1_sim - (q1_ref - q0_ref) / N_sample))
@assert norm((q1_sim - q0_sim) / h_sim - (q1_ref - q0_ref) / h) < 1.0e-8

sim_load = simulator(s_load, q0_sim, q1_sim, h_sim, H_sim,
    p = p,
    ip_opts = InteriorPointOptions(
        r_tol = 1.0e-8,
        κ_init = 1.0e-6,
        κ_tol = 2.0e-6,
        diff_sol = false,
        verbose = false),
    sim_opts = SimulatorOptions(warmstart = true))
time = @elapsed status = ContactImplicitMPC.simulate!(sim_load)

sim_no_load = simulator(s_no_load, q0_sim, q1_sim, h_sim, H_sim,
    p = p,
    ip_opts = InteriorPointOptions(
        r_tol = 1.0e-8,
        κ_init = 1.0e-6,
        κ_tol = 2.0e-6,
        diff_sol = false,
        verbose = false),
    sim_opts = SimulatorOptions(warmstart = true))
time = @elapsed status = ContactImplicitMPC.simulate!(sim_no_load)

# plt = plot(layout=(3,1), legend=false)
# plot!(plt[1,1], hcat(Vector.(vcat([fill(ref_traj.q[i], N_sample) for i=1:H]...))...)',
#     color=:red, linewidth=3.0)
# plot!(plt[1,1], hcat(Vector.(sim.traj.q)...)', color=:blue, linewidth=1.0)
# plot!(plt[2,1], hcat(Vector.(vcat([fill(ref_traj.u[i][1:nu], N_sample) for i=1:H]...))...)',
#     color=:red, linewidth=3.0)
# plot!(plt[2,1], hcat(Vector.([u[1:nu] for u in sim.traj.u]*N_sample)...)', color=:blue, linewidth=1.0)
# plot!(plt[3,1], hcat(Vector.([γ[1:nc] for γ in sim.traj.γ]*N_sample)...)', color=:blue, linewidth=1.0)
# render(vis)
plot_surface!(vis, s_load.env, ylims=[0.3, -0.05])
plot_lines!(vis, model, sim_no_load.traj.q[1:1:end], name=:NoPayload, offset=-0.15)
plot_lines!(vis, model, sim_load.traj.q[1:1:end], name=:Payload, offset=-0.15)
ext_ref_traj = repeat_ref_traj(ref_traj, 7; idx_shift = (1:1))
plot_lines!(vis, model, ext_ref_traj.q, offset=-0.17, name=:Ref, col=false,)

anim = visualize_meshrobot!(vis, s_load.model, sim_load.traj, anim=anim, sample=1, name=:Payload)
anim = visualize_meshrobot!(vis, s_no_load.model, sim_no_load.traj, sample=1, name=:NoPayload)
anim = visualize_payload!(vis, model, sim_load.traj, anim=anim, sample=1, name=:Payload, object=:mesh)
# anim = visualize_force!(vis, model, sim_no_load.traj, anim=anim, sample=5, h=h_sim, name=:NoPayload)
# anim = visualize_force!(vis, model, sim_load.traj, anim=anim, sample=5, h=h_sim, name=:Payload)

anim = visualize_meshrobot!(vis, model, sim_load.traj, sample=1, name=:Payload)
anim = visualize_payload!(vis, model, sim_load.traj, anim=anim, sample=1, name=:Payload, object=:mesh)
# settransform!(vis["/Cameras/default"],
#         compose(Translation(0.0, -25.0, -1.0), LinearMap(RotY(0.0 * π) * RotZ(-π / 2.0))))
# setprop!(vis["/Cameras/default/rotated/<object>"], "zoom", 20)

# Display ghosts
t_ghosts = [1]
mvis_ghosts = []
for (i,t) in enumerate(t_ghosts)
    α = i/(length(t_ghosts)+1)
    name = Symbol("ghost$i")
    mvis = build_meshrobot!(vis, model_load, name=name, α=α)
    build_load!(vis, model_load, name=name, α=α)
    push!(mvis_ghosts, mvis)
end

for (i,t) in enumerate(t_ghosts)
    name = Symbol("ghost$i")
    set_meshrobot!(vis, mvis_ghosts[i], model, sim_load.traj.q[t], name=name)
    set_load!(vis, model, sim_load.traj.q[t], name=name)
end

anim = visualize_load!(vis, model, sim_load.traj, anim=anim, sample=5, name=:Payload)

filename = "quadruped_payload_slow"
MeshCat.convert_frames_to_video(
    "/home/simon/Downloads/$filename.tar",
    "/home/simon/Documents/$filename.mp4", overwrite=true)

convert_video_to_gif(
    "/home/simon/Documents/$filename.mp4",
    "/home/simon/Documents/$filename.gif", overwrite=true)


text:
include("fuzzlib.jl")

using Random: seed!

@testset "Fuzz test" begin
    seed!(6174)
    for i=1:1500
        fuzz_test(10, num_spec)
    end
    for i=1:500
        fuzz_test(8, bool_spec)
    end
end


text:
export CreateLayoutTree, getInheritWidth
function getInheritWidth(document::Page, p)
        while p.shape.width < 1
            p == p.parent && (return document.width)
            p = p.parent
        end
        return p.shape.width
end
# width, h = getSize(p.shape)
# return width
# ======================================================================================
## CreateLayoutTree(document::Page, node::Element)
# Generate a layout tree starting at `node` in `document`. This should be callable
# starting at any point in the document tree.
# ======================================================================================, shape::Draw
function CreateLayoutTree(document::Page, parent)

    isa(parent.shape, TextLine) && return # TODO: may be able to make this part of multiple dispatch later

    parent.rows  = []  # Clean out old data (?)
    l,t,w,h = getContentBox(parent.shape)
    w = getInheritWidth(document::Page, parent) # because width may not be set
    children = parent.children

    for child in children
                child.parent = parent # attach to parent
                if isdefined(child, :children) && length(child.children) > 0
                    child.rows = []
                end
                #AtributesToLayout(document, child) # Create Child's DOM (DomToLayout.jl)
            if !child.shape.flags[DisplayNone] # only draw if not "display: none"
                PushToRow(document, child, l,t,w) # Put child into row
                CreateLayoutTree(document, child) # Create child's children
            end
    end

    # Clean-up! Generally the last row of each child is not yet finalized.
    if length(parent.rows) > 0
        lastRow = parent.rows[end]
        FinalizeRow(lastRow)
        # Set content height and width for scroller
        parent.scroll.contentHeight = lastRow.top + lastRow.height - parent.shape.top
        parent.scroll.contentWidth  = lastRow.left + lastRow.width  - parent.shape.left

        if !parent.shape.flags[FixedHeight]
            parent.shape.height = parent.scroll.contentHeight
        end
        # This is to be done after the parent node's size is finalised!
        if parent.shape.flags[HasAbsolute]
          # get node metrics again since the height etc. might have changed.
          l,t,w,h = getContentBox(parent.shape)
          for child in children
                shape = child.shape
                width, height = getSize(shape)
                if shape.flags[Absolute]
                  top,left = shape.top, shape.left # temp variables
                  setDistanceFromBounds(l,t,w,h,  shape )
                  rows = child.rows
                  for row in rows         # row.nodes[i]
                    for n in row.nodes
                      MoveAll(n, shape.left - left, shape.top - top)
                    end
                  end
                end
          end
        end
    end
end


text:
(t::Todo) -> begin
el(
  id = t.id |> Base.get,
  todo = t.title,
  completed = t.completed
)
end

max_stars_repo_name: essenciary/genie-todo-mvc

max_issues_repo_name: essenciary/genie-todo-mvc

max_forks_repo_name: essenciary/genie-todo-mvc


text:
#####################################################################################
#Forecast using OLS with lagged aggregate variable, and lagged disaggregate variable.
#The first out-of-sample forecast has vector index of J - (h_lag + h)
#####################################################################################
function OLS_oos_forc(J, h, h_lag, Y, Y_lag, X_lag)
    ## Vector Index for oos forecast goes from J - (h_lag + h) to length(Y)
    ŷ = zeros(Float64, size(J - (h_lag + h):length(Y)))
    for (n, vec_î) in enumerate(J - (h_lag + h):length(Y))
        LHS = Y[1:(vec_î - h)]
        sample_size = length(LHS)
        RHS = [ones(sample_size) Y_lag[1:sample_size] X_lag[1:sample_size, :]]
        β̂ = OLSestimator(LHS, RHS)
        RHS_crnt = [1.0; Y_lag[vec_î]; X_lag[vec_î, :]]
        ŷ[n] = dot(β̂, RHS_crnt)
    end
    RMSE = sqrt(mean((Y[J - (h_lag + h):length(Y)] - ŷ) .^ 2))
    return ŷ, RMSE
end

max_stars_repo_name: jungangl/forecast-machine-learning

max_issues_repo_name: jungangl/forecast-machine-learning

max_forks_repo_name: jungangl/forecast-machine-learning


text:
# Run with julia -L src/Cinta.jl test/runtests.jl

include("../src/Cinta.jl")

using Test
using .Cinta

a_line_retriever = LineRetrieverFromString("alfa\nbeta")
@test typeof(a_line_retriever) == LineRetrieverFromString
@test get_next_line(a_line_retriever) == "alfa"
@test get_next_line(a_line_retriever) == "beta"
@test get_next_line(a_line_retriever) == nothing
# @test_throws DataType get_next_line(a_line_retriever)

a_line_retriever = LineRetrieverFromFile("test/datos_test.txt")
@test typeof(a_line_retriever) == LineRetrieverFromFile
@test get_next_line(a_line_retriever) == "alfa"
@test get_next_line(a_line_retriever) == "beta"
@test get_next_line(a_line_retriever) == nothing
# @test_throws DataType get_next_line(a_line_retriever)

@test !is_header("")
@test is_header("09/08/2020 06:32 cinta ruta 8 303")
@test !is_header("09/08/2020 06:36 cinta 805")

@test !is_detail("")
@test !is_detail("09/08/2020 06:32 cinta ruta 8 303")
@test is_detail("09/08/2020 06:36 cinta 805")

my_parameters = Parameters(10.5, .2)
@test typeof(my_parameters) == Parameters

a_line_retriever = LineRetrieverFromString("alfa\nbeta")
@test get_output(my_parameters, a_line_retriever) == ""

a_line_retriever = LineRetrieverFromString("09/08/2020 06:32 cinta ruta 8 303")
@test get_output(my_parameters, a_line_retriever) == "8\t3\t39:\t3\t→\t12\t︾\t10.5\n"

a_line_retriever = LineRetrieverFromString("09/08/2020 06:32 cinta ruta 8 303\n09/08/2020 06:36 cinta 805")
@test get_output(my_parameters, a_line_retriever) == "8\t3\t39:\t3\t→\t12\t︾\t10.5\n8\t5\t35:\t8\t→\t9\t︽\t10.1\n"

a_line_retriever = LineRetrieverFromString("09/08/2020 06:32 cinta ruta 8 303\n09/08/2020 06:32 cinta ruta 9 303")
@test get_output(my_parameters, a_line_retriever) == "8\t3\t39:\t3\t→\t12\t︾\t10.5\n9\t3\t39:\t3\t→\t12\t︾\t10.5\n"

a_line_retriever = LineRetrieverFromString("09/08/2020 06:32 cinta ruta 7 303\n09/08/2020 06:32 cinta ruta 2 303")
@test get_output(my_parameters, a_line_retriever) == "7\t3\t39:\t3\t→\t12\t︾\t10.5\n2\t3\t39:\t3\t→\t12\t︾\t10.5\n"

max_stars_repo_name: AndresParraSilva/julia-start

max_issues_repo_name: AndresParraSilva/julia-start

max_forks_repo_name: AndresParraSilva/julia-start


text:
#test exactShift:firmvalue example
originalH=[0.  0.  0.  0.  -1.1  0.  0.  0.  1.  1.  0.  0.;
           0.  -0.4  0.  0.  0.  1.  -1.  0.  0.  0.  0.  0.;
           0.  0.  0.  0.  0.  0.  1.  0.  0.  0.  0.  0.;
           0.  0.  0.  -1.  0.  0.  0.  1.  0.  0.  0.  0.]
exactShiftH=[
0.  0.  0.  0.  -1.1  0.  0.  0.  1.  1.  0.  0.;
0.  0.  0.  0.  0.  -0.4  0.  0.  0.  1.  -1.  0.;
0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.;
0.  0.  0.  0.  0.  0.  0.  -1.  0.  0.  0.  1.]
zf=[
0.  -0.4  0.  0.  0.  1.  -1.  0.;
0.  0.  0.  0.  0.  0.  1.  0.;
0.  0.  0.  -1.  0.  0.  0.  1.;
0.  0.  0.  0.  0.  0.  0.  0.]
neq=4::Int64;nlag=1::Int64;nlead=1::Int64;
qRows=(neq*nlead)::Int64;qCols=(neq*(nlag+nlead))::Int64
#=
(newH,qq,iq,nExact)= exactShift(originalH,qq,iq,qRows,qCols,neq)
@test nExact==2
@test isapprox(newH,exactShiftH,rtol::Float64=0.1e-16,atol::Float64=0)
@test isapprox(qq,zf,rtol::Float64=0.1e-16,atol::Float64=0)
=#

#test buildA:firmvalue example

hIn= [0.  0.  0.  0.  -1.1  0.  0.  0.  1.  1.  0.  0.;
         0.  0.  0.  0.  0.  -0.4  0.  0.  0.  1.  -1.  0.;
         0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.;
         0.  0.  0.  0.  0.  0.  0.  -1.  0.  0.  0.  1.]

aa=[1.1  -0.4  0.;
         0.  0.4  0.;
         0.  0.  1.]
js=[5  6  8]
qCols=8::Int64
neq=4::Int64;nlag=1::Int64;nlead=1::Int64;
qRows=(neq*nlead)::Int64;qCols=(neq*(nlag+nlead))::Int64
#=
(aa,ia,js) = buildA(hIn,qcols,neq)
=#

ww=[0.868243  0.  0.;
         -0.496139  0.  1.;
         0.  1.  0.]
rts=[1.1;
         1.;
         0.4]

#=
(w,rts,lgroots) = eigenSystem(a,uprbnd,min(length(js),qrows-iq+1))
=#

#Transpose[ww] . aa -  DiagonalMatrix[Flatten[rts]] . Transpose[ww]

#test augmentQ:firmvalue example
qqFinal=[0.  -0.4  0.  0.  0.  1.  -1.  0.;
         0.  0.  0.  0.  0.  0.  1.  0.;
         0.  0.  0.  -1.  0.  0.  0.  1.;
         0.  0.  0.  0.  0.  0.  0.  0.]

#=
qq = augmentQ(qq,ww,js,iq,qrows);
=#

#test reducedForm:firmvalue example

bb=[0.  0.228571  0.  0.;
         0.  0.4  0.  0.;
         0.  0.  0.  0.;
         0.  0.  0.  1.]

#=
(nonsing,bb) = reducedForm(qq,qrows,qcols,bcols,neq,condn);
=#

#test observStruct:firmvalue example

ss=[0.  0.  0.  0.  -1.1  0.628571  0.  0.;
         0.  -0.4  0.  0.  0.  1.  -1.  0.;
         0.  0.  0.  0.  0.  0.  1.  0.;
         0.  0.  0.  -1.  0.  0.  0.  1.]

#=
scof = observStruct(hh,bb,neq,nlag,nlead)
=#

#test makePhi:firmvalue example

#test makeF:firmvalue example

#test makeVartheta:firmvalue example

#test AMAErr:firmvalue example


text:
mutable struct HarvestOption
    f0_ceil::Cdouble
    f0_floor::Cdouble
    frame_period::Cdouble

    # allow uninitialized creation
    HarvestOption() = new()
end

function harvest(x::Vector{Float64}, fs::Int; kwargs...)
    harvestoption = Ref(HarvestOption())
    @ccall libworld.InitializeHarvestOption(harvestoption::Ptr{HarvestOption})::Cvoid

    for (symbol, value) in kwargs
        setproperty!(harvestoption[], symbol, value)
    end
    frame_period = harvestoption[].frame_period

    n_harvest_samples = @ccall libworld.GetSamplesForHarvest(fs::Cint, length(x)::Cint, frame_period::Cdouble)::Cint

    # allocate f0 and temporal positions vectors
    f0 = Vector{Cdouble}(undef, n_harvest_samples)
    temporal_positions = similar(f0)

    @ccall libworld.Harvest(x::Ptr{Cdouble}, length(x)::Cint, fs::Cint, harvestoption::Ptr{HarvestOption},
        temporal_positions::Ptr{Cdouble}, f0::Ptr{Cdouble})::Cvoid

    f0, temporal_positions
end


text:
import AQFED.Math: norminv
using Statistics
import AQFED.TermStructure: ConstantBlackModel, TSBlackModel, varianceByLogmoneyness, discountFactor, forward, logForward

function simulate(rng, model::ConstantBlackModel, spot::Float64, payoff::VanillaOption, nSim::Int)
    tte = payoff.maturity
    sqrtte = sqrt(tte)
    df = discountFactor(model, tte)
    z = Vector{Float64}(undef, nSim)
    nextn!(rng, z)
    pathValues =
        @. forward(model, spot, tte)*exp(model.vol * z * sqrtte - 0.5 * model.vol^2 * tte)
    mean(x -> evaluatePayoff(payoff, x, df), pathValues)
end

function ndims(model::TSBlackModel, specificTimes::Vector{Float64}, timestepSize::Float64)
    genTimes = pathgenTimes(model, specificTimes, timestepSize)
    return (length(genTimes) - 1) #0.0 does not count
end

function pathgenTimes(model, specificTimes::Vector{Float64}, timestepSize::Float64)
    t0 = 0.0
    pathTimes = Vector{Float64}(undef, 1)
    pathTimes[1] = t0
    for t1 in specificTimes
        currentSize = t1 - t0
        if timestepSize >= currentSize
            push!(pathTimes, t1)
        else
            nSubsteps = trunc(Int, currentSize / timestepSize + 0.5)
            dt = currentSize / nSubsteps
            for j = 1:nSubsteps-1
                push!(pathTimes, t0 + dt * j)
            end
            push!(pathTimes, t1)
        end
        t0 = t1
    end
    return pathTimes
end

function simulate(
    rng,
    model::TSBlackModel{S},
    spot::Float64,
    payoff::VanillaOption,
    start::Int,
    nSim::Int;
    withBB = false,
) where {S}
    specTimes = specificTimes(payoff)
    tte = specTimes[end]
    genTimes = pathgenTimes(model, specTimes, tte)

    local bb, cache
    if withBB
        cacheSize = ceil(Int, log2(length(genTimes))) * 4
        bb = BrownianBridgeConstruction(genTimes[2:end])
        cache = BBCache{Int,Vector{Float64}}(cacheSize)
    end
    logpathValues = Vector{Float64}(undef, nSim)
    z  = Vector{Float64}(undef, nSim)
    pathValues = Vector{Float64}(undef, nSim)
    local payoffValues

    t0 = genTimes[1]
    lnspot = log(spot)
    lnf0 = logForward(model, lnspot, t0)
    logpathValues .= lnf0
    for (dim, t1) in enumerate(genTimes[2:end])
        h = t1 - t0
        sqrth = sqrt(h)
        if withBB
            transformByDim!(bb, rng, start, dim, z, cache)
        else
            skipTo(rng, dim, start)
            nextn!(rng, dim, z)
            @. z *= sqrth
        end
        volSq = (varianceByLogmoneyness(model.surface, 0.0, t1)*t1 - varianceByLogmoneyness(model.surface, 0.0, t0)*t0)/h
        vol = sqrt(volSq)
        lnf1 = logForward(model, lnspot, t1)
        @. logpathValues += z * vol - 0.5 * volSq * h + lnf1 - lnf0
        if t1 == tte
            df = discountFactor(model, t1)
            @. pathValues = exp(logpathValues)
            payoffValues = map(x -> evaluatePayoff(payoff, x, df), pathValues)
        end
        t0 = t1
        lnf0 = lnf1
    end
    payoffMean = mean(payoffValues)
    return payoffMean, stdm(payoffValues, payoffMean) / sqrt(length(payoffValues))
end


text:
@testset "Functions" begin
    @polyvar x
    α = MOI.VariableIndex(1)
    f = MOI.SingleVariable(α)
    @test f * x isa AbstractTerm{MOI.SingleVariable}
    @test x * f isa AbstractTerm{MOI.SingleVariable}
    @test f * x^2 isa AbstractTerm{MOI.SingleVariable}
    @test x^2 * f isa AbstractTerm{MOI.SingleVariable}
    @test f * (1x) isa AbstractTerm{MOI.ScalarAffineFunction{Int}}
    @test (1x) * f isa AbstractTerm{MOI.ScalarAffineFunction{Int}}
    @test f * (1.0x) isa AbstractTerm{MOI.ScalarAffineFunction{Float64}}
    @test (1.0x) * f isa AbstractTerm{MOI.ScalarAffineFunction{Float64}}
    @test f * (1x + 2) isa AbstractPolynomial{MOI.ScalarAffineFunction{Int}}
    @test (1x + 2) * f isa AbstractPolynomial{MOI.ScalarAffineFunction{Int}}
    @test f * (1.0x + 2.0) isa AbstractPolynomial{MOI.ScalarAffineFunction{Float64}}
    @test (1.0x + 2.0) * f isa AbstractPolynomial{MOI.ScalarAffineFunction{Float64}}
end


text:
abstract type List{T} end

struct Nil{T} <: List{T} end

function Nil(T::Type)
    Nil{T}()
end

struct Cons{T} <: List{T}
    head::T
    tail::List{T}
end

function Cons{T}(entry::T)
    Cons{T}(entry, Nil{T}())
end

function List{T}(entries::T...)
    list = Nil{T}()
    for entry in reverse(entries)
        list = Cons{T}(entry, list)
    end
    list
end

function List{T}() where T
    Nil{T}()
end

function Base.show(io::IO, list::Nil{T}) where {T}
    print(io, "List{", T ,"}()")
end

function Base.show(io::IO, list::Cons{T}) where {T}
    print(io, "List{", T ,"}(")
    show(io, list.head)
    for entry in list.tail
        print(io, ", ")
        show(io, entry)
    end
    print(io, ")")
end

Base.start(list::Nil{T}) where {T} = list
Base.start(list::Cons{T}) where {T} = list
Base.done(list::List{T}, state::Nil{T}) where {T} = true
Base.done(list::List{T}, state::Cons{T}) where {T} = false
Base.next(list::Cons{T}, state::Cons{T}) where {T} = (state.head, state.tail)

Base.length(list::Nil{T}) where {T} = 0
Base.length(list::Cons{T}) where {T} = 1 + Base.length(list.tail)

Base.eltype(list::List{T}) where {T} = T
Base.eltype(::Type{List{T}}) where {T} = T

Base.isempty(list::Nil{T}) where {T} = true
Base.isempty(list::Cons{T}) where {T} = false

Base.endof(list::List{T}) where {T} = Base.length(list)

Base.in(item, list::Nil{T}) where T = false
Base.in(item, list::Cons{T}) where T = list.head == item || Base.in(item, list.tail)

Base.map(fn::Function, list::Nil{T}) where T = list
Base.map(fn::Function, list::Cons{T}) where T = Cons(fn(list.head), Base.map(fn, list.tail))

Base.filter(fn::Function, list::Nil{T}) where T = list
Base.filter(fn::Function, list::Cons{T}) where T =
    if fn(list.head)
        Cons(list.head, Base.filter(fn, list.tail))
    else
        Base.filter(fn, list.tail)
    end

Base.getindex(list::Nil{T}, index::Integer) where T = throw(BoundsError(list, index))
Base.getindex(list::Cons{T}, index::Integer) where T =
    if index == 1
        list.head
    else
        try
            Base.getindex(list.tail, index - 1)
        catch err
            if isa(err, BoundsError)
                throw(BoundsError(list, index))
            else
                throw(err)
            end
        end
    end


text:
using Test
using SafeTestsets

@testset "shallow_water" begin
  @safetestset "entropy_conservation_1d" begin include("entropy_conservation_1d.jl") end
end


text:
# washout simulation
include("include.jl")
include("SolveBalances.jl")

# set up simulation time for each phase
time_start = 0
PI_dura = 7
PII_dura = 10
PIII_dura = 8
time_step = 0.1

# phase I: run to steady state
DataDict = generate_model_parameters_dictionary()
TIEnd = time_start + PI_dura
(TP1, XP1) = SolveBalances(time_start, TIEnd, time_step, DataDict)
# phase II: add substrate
IniCond = XP1[end, :]
IniCond[1] = 0.001
IniCond[2] = 10
DataDict["initial_condition"] = IniCond
TIIEnd = TIEnd + PII_dura
(TP2, XP2) = SolveBalances(TIEnd, TIIEnd, time_step, DataDict)
# phase III: remove substrate
IniCond = XP2[end, :]
IniCond[2] = 0
DataDict["initial_condition"] = IniCond
TIIIEnd = TIIEnd + PIII_dura
(TP3, XP3) = SolveBalances(TIIEnd, TIIIEnd, time_step, DataDict)

# pack the three phases together
T = [TP1; TP2; TP3]
X = [XP1 ; XP2 ; XP3];
# plot results
all_species_reversed_dict = DataDict["all_species_reversed_dict"]

# metG = 3:7
# proG = 8:14
# mRNAG = 15:21
# group = ["metabolite", "protein", "mRNA"]
# sDt = Dict("metabolite" => metG, "protein" => proG, "mRNA" => mRNAG)
# for st in group
#   plt.figure(st)
#   # plt.plot(T[40:end]-4, X[40:end,sDt[st]], label=[all_species_reversed_dict[i] for i in sDt[st]])
#   for i in sDt[st]
#     plt.plot(T[40:end]-4, X[40:end,i], label=all_species_reversed_dict[i])
#   end
#   plt.title(st)
#   plt.legend()
#   plt.show()
# end

function plot_by_groups(groups, labels)
  for (key,val) in groups
    plt.figure(key)
    for i in val
      plt.plot(T[40:end] .- 4, X[40:end,i], label=all_species_reversed_dict[i])
    end
    plt.axvspan(0, 3, color="k", alpha=0.1)
    plt.axvspan(3,13, color="g", alpha=0.1)
    plt.axvspan(13,21, color="b", alpha=0.1)
    plt.title(key)
    plt.xlim(0, 21)
    plt.ylim(bottom=0)
    plt.xlabel("Time (h)")
    plt.ylabel("Concentration ($(labels[key]))")
    plt.legend()
    # plt.show()
  end
end

sDt = Dict("metabolite" => 3:7, "protein" => 8:14, "mRNA" => 15:21)
ylab = Dict("metabolite" => "mM", "protein" => "nM", "mRNA" => "nM")
plot_by_groups(sDt, ylab)
plt.show()
# sDt2 = Dict("TA" => [19,12,5], "A" => [5,15,16,8,9,6,7],
#             "C" => [7,17,21,10,14,4,6], "B" => [6,18,20,11,13,6])
# plot_by_groups(sDt2)

# writedlm("simulation.dat", [T X])

# column; species
# 1  BIOMASS
# 2  met_A_e
# 3  met_B_e
# 4  met_C_e
# 5  met_A_c
# 6  met_B_c
# 7  met_C_c
# 8  p_E1_c
# 9  p_E2_c
# 10  p_E3_c
# 11  p_E4_c
# 12  p_TA_c
# 13  p_TB_c
# 14  p_TC_c
# 15  mRNA_E1_c
# 16  mRNA_E2_c
# 17  mRNA_E3_c
# 18  mRNA_E4_c
# 19  mRNA_TA_c
# 20  mRNA_TB_c
# 21  mRNA_TC_c


text:
begin
if haskey(ENV, "MANUAL")
    include("build2.jl")
    @goto writedeps
end

push!(LOAD_PATH, "@stdlib")
using Pkg
using Conda

PYTHON = joinpath(Conda.BINDIR, "python")
!haskey(Pkg.installed(), "PyCall") && Pkg.add("PyCall")
ENV["PYTHON"]=PYTHON
Pkg.build("PyCall")

using PyCall
@info """
PyCall Python version: $(PyCall.python)
Conda Python version: $PYTHON
"""

easy_get = pkg->begin
    try
        strip(read(pipeline(`which $pkg`), String))
    catch
        Conda.add(pkg)
        joinpath(Conda.BINDIR, pkg)
    end
end

pkgs_dict = Conda._installed_packages_dict()
pkgs = collect(keys(pkgs_dict))

@info "Install binaries"
ZIP = easy_get("zip")
UNZIP = easy_get("unzip")
GIT = "LibGit2"

@info "Install CONDA dependencies..."
for pkg in ["make", "cmake", "tensorflow=1.15", "tensorflow-probability=0.7",
            "matplotlib"]
    if pkg in pkgs; continue; end
    if occursin("=", pkg)
        p = split(pkg,"=")[1]
        v = split(pkg,"=")[2]
        if haskey(pkgs_dict, p) && occursin(v, string(pkgs_dict[p][1]))
            continue
        end
    end
    Conda.add(pkg)
end
!("hdf5" in pkgs) && Conda.add("hdf5", channel="anaconda")

function enable_gpu()
    pkgs = Conda._installed_packages()

    if !("tensorflow-gpu" in pkgs)
        Conda.add("tensorflow-gpu=1.15")
    end

    if !("cudatoolkit" in pkgs)
        Conda.add("cudatoolkit", channel="anaconda")
    end

    gpus = joinpath(splitdir(tf.__file__)[1], "include/third_party/gpus")
    if !isdir(gpus)
    mkdir(gpus)
    end
    gpus = joinpath(gpus, "cuda")
    if !isdir(gpus)
    mkdir(gpus)
    end
    incpath = joinpath(splitdir(strip(read(`which nvcc`, String)))[1], "../include/")
    if !isdir(joinpath(gpus, "include"))
        cp(incpath, joinpath(gpus, "include"))
    end

    pth = joinpath(Conda.ROOTENV, "pkgs/cudatoolkit-10.1.168-0/lib/")
    # compatible
    files = readdir(pth)
    for f in files
        if f[end-2:end]==".10" && !isfile(joinpath(pth, f*".0"))
            symlink(joinpath(pth, f), joinpath(pth, f*".0"))
        end
        if f[end-4:end]==".10.1" && !isfile(joinpath(pth, f[1:end-2]*".0"))
            symlink(joinpath(pth, f), joinpath(pth, f[1:end-2]*".0"))
        end
    end

    @info("Run the following command in shell

    echo 'export LD_LIBRARY_PATH=$pth:\$LD_LIBRARY_PATH' >> ~/.bashrc")
end

@info "Preparing environment for custom operators"
tf = pyimport("tensorflow")
if haskey(ENV, "GPU");enable_gpu();end

core_path = joinpath(tf.sysconfig.get_compile_flags()[1][3:end], "..")
lib = readdir(core_path)
tflib = joinpath(core_path,lib[findall(occursin.("libtensorflow_framework", lib))[1]])
surfix = Sys.isapple() ? "dylib" : (Sys.islinux() ? "so" : "dll")
if !isfile(joinpath(splitdir(tflib)[1], "libtensorflow_framework.$surfix"))
    @info "making symbolic link to libtensorflow_framework"
    symlink(tflib, joinpath(splitdir(tflib)[1], "libtensorflow_framework.$surfix"))
end
tflib = joinpath(splitdir(tflib)[1], "libtensorflow_framework.$surfix")

TF_INC = tf.sysconfig.get_compile_flags()[1][3:end]
TF_ABI = tf.sysconfig.get_compile_flags()[2][end:end]

function install_custom_op_dependency()
    LIBDIR = "$(Conda.LIBDIR)/Libraries"

    # Install Eigen3 library
    if !isdir(LIBDIR)
        @info "Downloading dependencies to $LIBDIR..."
        mkdir(LIBDIR)
    end

    if !isfile("$LIBDIR/eigen.zip")
        download("http://bitbucket.org/eigen/eigen/get/3.3.7.zip","$LIBDIR/eigen.zip")
    end

    if !isdir("$LIBDIR/eigen3")
        run(`$UNZIP $LIBDIR/eigen.zip`)
        mv("eigen-eigen-323c052e1731", "$LIBDIR/eigen3", force=true)
    end
end

install_custom_op_dependency()

# useful command for debug
# readelf -p .comment libtensorflow_framework.so
# strings libstdc++.so.6 | grep GLIBCXX
if Sys.islinux()
    verinfo = read(`readelf -p .comment $tflib`, String)
    if occursin("5.4", verinfo)
        if !("gcc-5" in Conda._installed_packages())
            try
                # a workaround
                Conda.add("mpfr", channel="anaconda")
                if !isfile(joinpath(Conda.LIBDIR, "libmpfr.so.4")) && isfile(joinpath(Conda.LIBDIR, "libmpfr.so.6"))
                    symlink(joinpath(Conda.LIBDIR, "libmpfr.so.6"), joinpath(Conda.LIBDIR, "libmpfr.so.4"))
                end
                Conda.add("gcc-5", channel="psi4")
                Conda.add("libgcc")
            catch
                error("Installation of GCC failed. Follow the documentation for instructions.")
            end
        end
    elseif occursin("4.8.", verinfo)
        if !("gcc" in Conda._installed_packages())
            Conda.add("gcc", channel="anaconda")
            Conda.add("libgcc")
        end
    else
        @info("The GCC version which TensorFlow was compiled is not officially supported by ADCME. You have the following choices
1. Continue using ADCME. But you are responsible for the compatible issue of GCC versions for custom operators.
2. Report to the author of ADCME by opening an issue in https://github.com/kailaix/ADCME.jl/
Compiler information:
$verinfo
")
    end
    rm(joinpath(Conda.LIBDIR,"libstdc++.so.6"), force=true)
    @info "Making a symbolic link for libgcc"
    symlink(joinpath(Conda.LIBDIR,"libstdc++.so.6.0.26"), joinpath(Conda.LIBDIR,"libstdc++.so.6"))
end

s = ""
t = []
function adding(k, v)
    global s
    s *= "$k = \"$v\"\n"
    push!(t, "$k")
end
adding("BINDIR", Conda.BINDIR)
adding("LIBDIR", Conda.LIBDIR)
adding("TF_INC", TF_INC)
adding("TF_ABI", TF_ABI)
adding("EIGEN_INC", joinpath(Conda.LIBDIR,"Libraries"))
adding("CC", joinpath(Conda.BINDIR, "gcc"))
adding("CXX", joinpath(Conda.BINDIR, "g++"))
adding("CMAKE", joinpath(Conda.BINDIR, "cmake"))
adding("MAKE", joinpath(Conda.BINDIR, "make"))
adding("GIT", GIT)
adding("PYTHON", PyCall.python)
adding("TF_LIB_FILE", tflib)

t = "join(["*join(t, ",")*"], \";\")"
s *= "__STR__ = $t"
open("deps.jl", "w") do io
    write(io, s)
end

@label writedeps

end


text:
using VoiceConversion
using MelGeneralizedCepstrums
using HDF5
using JLD
using SynthesisFilters
using WORLD
using Base.Test

import WORLD: synthesis

for fname in ["dtw",
              "gmmmap",
              "trajectory_gmmmap",
              "vc",
              "diffvc"
              ]
    include(string(fname, ".jl"))
end


text:
struct SizedReducible{T,S<:Integer} <: Reducible
    reducible::T
    basesize::S
end

foldable(reducible::SizedReducible) = reducible.reducible

issmall(reducible, basesize) = amount(reducible) <= basesize

issmall(reducible::SizedReducible) =
    issmall(reducible.reducible, max(reducible.basesize, 1))

function _halve(reducible::SizedReducible)
    left, right = halve(reducible.reducible)
    return (
        SizedReducible(left, reducible.basesize),
        SizedReducible(right, reducible.basesize),
    )
end

abstract type DACContext end

struct NoopDACContext <: DACContext end
splitcontext(ctx::NoopDACContext) = (ctx, ctx)
should_abort(::NoopDACContext) = false
cancel!(::NoopDACContext) = nothing

struct CancellableDACContext <: DACContext
    listening::Vector{Threads.Atomic{Bool}}
    cancellables::Vector{Threads.Atomic{Bool}}
end

CancellableDACContext() =
    CancellableDACContext(Threads.Atomic{Bool}[], Threads.Atomic{Bool}[])

function splitcontext(ctx::CancellableDACContext)
    c = Threads.Atomic{Bool}(false)
    fg = CancellableDACContext(ctx.listening, vcat(ctx.cancellables, c))
    bg = CancellableDACContext(vcat(ctx.listening, c), ctx.cancellables)
    return (fg, bg)
end

function should_abort(ctx::CancellableDACContext)
    for c in ctx.listening
        c[] && return true
    end
    return false
end

function cancel!(ctx::CancellableDACContext)
    for c in ctx.cancellables
        c[] = true
    end
end

@noinline _reduce_basecase(rf::F, init::I, reducible) where {F,I} =
    restack(foldl_nocomplete(rf, start(rf, init), foldable(reducible)))
# `restack` here is crucial when using heap-allocated accumulator.
# See `ThreadsX.unique` and the MWE extracted from it:
# https://github.com/tkf/Restacker.jl/blob/master/benchmark/bench_unique.jl


text:
using Mocking

add_tags_to_resource_1_patch = @patch function add_tags_to_resource(a...; b...)
    return Dict{String, Any}()
end

create_endpoint_1_patch = @patch function create_endpoint(a...; b...)
    return Dict{String, Any}("Endpoint" => Dict{String, Any}("Username" => "username", "EngineName" => "mysql", "Status" => "active", "EndpointType" => "source", "EndpointArn" => "arn:aws:dms:us-east-1:123456789012:endpoint:RAAR3R22XSH46S3PWLC3NJAWKM", "KmsKeyId" => "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", "ServerName" => "mydb.cx1llnox7iyx.us-west-2.rds.amazonaws.com", "EndpointIdentifier" => "test-endpoint-1", "Port" => 3306))
end

create_replication_instance_1_patch = @patch function create_replication_instance(a...; b...)
    return Dict{String, Any}("ReplicationInstance" => Dict{String, Any}("ReplicationInstanceStatus" => "creating", "PubliclyAccessible" => true, "ReplicationInstanceIdentifier" => "test-rep-1", "PreferredMaintenanceWindow" => "sun:06:00-sun:14:00", "AutoMinorVersionUpgrade" => true, "AllocatedStorage" => 5, "ReplicationSubnetGroup" => Dict{String, Any}("ReplicationSubnetGroupDescription" => "default", "ReplicationSubnetGroupIdentifier" => "default", "SubnetGroupStatus" => "Complete", "Subnets" => Any[Dict{String, Any}("SubnetIdentifier" => "subnet-f6dd91af", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1d")), Dict{String, Any}("SubnetIdentifier" => "subnet-3605751d", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1b")), Dict{String, Any}("SubnetIdentifier" => "subnet-c2daefb5", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1c")), Dict{String, Any}("SubnetIdentifier" => "subnet-85e90cb8", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1e"))], "VpcId" => "vpc-6741a603"), "EngineVersion" => "1.5.0", "ReplicationInstanceClass" => "dms.t2.micro", "ReplicationInstanceArn" => "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", "KmsKeyId" => "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", "PendingModifiedValues" => Dict{String, Any}()))
end

create_replication_subnet_group_1_patch = @patch function create_replication_subnet_group(a...; b...)
    return Dict{String, Any}("ReplicationSubnetGroup" => Dict{String, Any}())
end

create_replication_task_1_patch = @patch function create_replication_task(a...; b...)
    return Dict{String, Any}("ReplicationTask" => Dict{String, Any}("ReplicationTaskCreationDate" => "2016-12-14T18:25:43Z", "TableMappings" => "file://mappingfile.json", "TargetEndpointArn" => "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E", "ReplicationTaskArn" => "arn:aws:dms:us-east-1:123456789012:task:OEAMB3NXSTZ6LFYZFEPPBBXPYM", "ReplicationInstanceArn" => "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", "Status" => "creating", "SourceEndpointArn" => "arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", "MigrationType" => "full-load", "ReplicationTaskSettings" => "{\"TargetMetadata\":{\"TargetSchema\":\"\",\"SupportLobs\":true,\"FullLobMode\":true,\"LobChunkSize\":64,\"LimitedSizeLobMode\":false,\"LobMaxSize\":0},\"FullLoadSettings\":{\"FullLoadEnabled\":true,\"ApplyChangesEnabled\":false,\"TargetTablePrepMode\":\"DROP_AND_CREATE\",\"CreatePkAfterFullLoad\":false,\"StopTaskCachedChangesApplied\":false,\"StopTaskCachedChangesNotApplied\":false,\"ResumeEnabled\":false,\"ResumeMinTableSize\":100000,\"ResumeOnlyClusteredPKTables\":true,\"MaxFullLoadSubTasks\":8,\"TransactionConsistencyTimeout\":600,\"CommitRate\":10000},\"Logging\":{\"EnableLogging\":false}}", "ReplicationTaskIdentifier" => "task1"))
end

delete_certificate_1_patch = @patch function delete_certificate(a...; b...)
    return Dict{String, Any}("Certificate" => Dict{String, Any}())
end

delete_connection_1_patch = @patch function delete_connection(a...; b...)
    return Dict{String, Any}("Connection" => Dict{String, Any}())
end

delete_endpoint_1_patch = @patch function delete_endpoint(a...; b...)
    return Dict{String, Any}("Endpoint" => Dict{String, Any}("Username" => "username", "EngineName" => "mysql", "Status" => "active", "EndpointType" => "source", "EndpointArn" => "arn:aws:dms:us-east-1:123456789012:endpoint:RAAR3R22XSH46S3PWLC3NJAWKM", "KmsKeyId" => "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", "ServerName" => "mydb.cx1llnox7iyx.us-west-2.rds.amazonaws.com", "EndpointIdentifier" => "test-endpoint-1", "Port" => 3306))
end

delete_replication_instance_1_patch = @patch function delete_replication_instance(a...; b...)
    return Dict{String, Any}("ReplicationInstance" => Dict{String, Any}("ReplicationInstanceStatus" => "creating", "PubliclyAccessible" => true, "ReplicationInstanceIdentifier" => "test-rep-1", "PreferredMaintenanceWindow" => "sun:06:00-sun:14:00", "AutoMinorVersionUpgrade" => true, "AllocatedStorage" => 5, "ReplicationSubnetGroup" => Dict{String, Any}("ReplicationSubnetGroupDescription" => "default", "ReplicationSubnetGroupIdentifier" => "default", "SubnetGroupStatus" => "Complete", "Subnets" => Any[Dict{String, Any}("SubnetIdentifier" => "subnet-f6dd91af", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1d")), Dict{String, Any}("SubnetIdentifier" => "subnet-3605751d", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1b")), Dict{String, Any}("SubnetIdentifier" => "subnet-c2daefb5", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1c")), Dict{String, Any}("SubnetIdentifier" => "subnet-85e90cb8", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1e"))], "VpcId" => "vpc-6741a603"), "EngineVersion" => "1.5.0", "ReplicationInstanceClass" => "dms.t2.micro", "ReplicationInstanceArn" => "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", "KmsKeyId" => "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", "PendingModifiedValues" => Dict{String, Any}()))
end

delete_replication_subnet_group_1_patch = @patch function delete_replication_subnet_group(a...; b...)
    return Dict{String, Any}()
end

delete_replication_task_1_patch = @patch function delete_replication_task(a...; b...)
    return Dict{String, Any}("ReplicationTask" => Dict{String, Any}("ReplicationTaskCreationDate" => "2016-12-14T18:25:43Z", "TableMappings" => "file://mappingfile.json", "TargetEndpointArn" => "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E", "ReplicationTaskArn" => "arn:aws:dms:us-east-1:123456789012:task:OEAMB3NXSTZ6LFYZFEPPBBXPYM", "ReplicationInstanceArn" => "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", "Status" => "creating", "SourceEndpointArn" => "arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", "MigrationType" => "full-load", "ReplicationTaskSettings" => "{\"TargetMetadata\":{\"TargetSchema\":\"\",\"SupportLobs\":true,\"FullLobMode\":true,\"LobChunkSize\":64,\"LimitedSizeLobMode\":false,\"LobMaxSize\":0},\"FullLoadSettings\":{\"FullLoadEnabled\":true,\"ApplyChangesEnabled\":false,\"TargetTablePrepMode\":\"DROP_AND_CREATE\",\"CreatePkAfterFullLoad\":false,\"StopTaskCachedChangesApplied\":false,\"StopTaskCachedChangesNotApplied\":false,\"ResumeEnabled\":false,\"ResumeMinTableSize\":100000,\"ResumeOnlyClusteredPKTables\":true,\"MaxFullLoadSubTasks\":8,\"TransactionConsistencyTimeout\":600,\"CommitRate\":10000},\"Logging\":{\"EnableLogging\":false}}", "ReplicationTaskIdentifier" => "task1"))
end

describe_account_attributes_1_patch = @patch function describe_account_attributes(a...; b...)
    return Dict{String, Any}("AccountQuotas" => Any[Dict{String, Any}("AccountQuotaName" => "ReplicationInstances", "Max" => 20, "Used" => 0), Dict{String, Any}("AccountQuotaName" => "AllocatedStorage", "Max" => 20, "Used" => 0), Dict{String, Any}("AccountQuotaName" => "Endpoints", "Max" => 20, "Used" => 0)])
end

describe_certificates_1_patch = @patch function describe_certificates(a...; b...)
    return Dict{String, Any}("Marker" => "", "Certificates" => Any[])
end

describe_connections_1_patch = @patch function describe_connections(a...; b...)
    return Dict{String, Any}("Connections" => Any[Dict{String, Any}("ReplicationInstanceIdentifier" => "test", "ReplicationInstanceArn" => "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", "Status" => "successful", "EndpointArn" => "arn:aws:dms:us-east-arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", "EndpointIdentifier" => "testsrc1")], "Marker" => "")
end

describe_endpoint_types_1_patch = @patch function describe_endpoint_types(a...; b...)
    return Dict{String, Any}("Marker" => "", "SupportedEndpointTypes" => Any[])
end

describe_endpoints_1_patch = @patch function describe_endpoints(a...; b...)
    return Dict{String, Any}("Marker" => "", "Endpoints" => Any[])
end

describe_orderable_replication_instances_1_patch = @patch function describe_orderable_replication_instances(a...; b...)
    return Dict{String, Any}("Marker" => "", "OrderableReplicationInstances" => Any[])
end

describe_refresh_schemas_status_1_patch = @patch function describe_refresh_schemas_status(a...; b...)
    return Dict{String, Any}("RefreshSchemasStatus" => Dict{String, Any}())
end

describe_replication_instances_1_patch = @patch function describe_replication_instances(a...; b...)
    return Dict{String, Any}("Marker" => "", "ReplicationInstances" => Any[])
end

describe_replication_subnet_groups_1_patch = @patch function describe_replication_subnet_groups(a...; b...)
    return Dict{String, Any}("Marker" => "", "ReplicationSubnetGroups" => Any[])
end

describe_replication_tasks_1_patch = @patch function describe_replication_tasks(a...; b...)
    return Dict{String, Any}("Marker" => "", "ReplicationTasks" => Any[])
end

describe_schemas_1_patch = @patch function describe_schemas(a...; b...)
    return Dict{String, Any}("Schemas" => Any[], "Marker" => "")
end

describe_table_statistics_1_patch = @patch function describe_table_statistics(a...; b...)
    return Dict{String, Any}("Marker" => "", "ReplicationTaskArn" => "", "TableStatistics" => Any[])
end

import_certificate_1_patch = @patch function import_certificate(a...; b...)
    return Dict{String, Any}("Certificate" => Dict{String, Any}())
end

list_tags_for_resource_1_patch = @patch function list_tags_for_resource(a...; b...)
    return Dict{String, Any}("TagList" => Any[])
end

modify_endpoint_1_patch = @patch function modify_endpoint(a...; b...)
    return Dict{String, Any}("Endpoint" => Dict{String, Any}())
end

modify_replication_instance_1_patch = @patch function modify_replication_instance(a...; b...)
    return Dict{String, Any}("ReplicationInstance" => Dict{String, Any}("ReplicationInstanceStatus" => "available", "PubliclyAccessible" => true, "ReplicationInstanceIdentifier" => "test-rep-1", "PreferredMaintenanceWindow" => "sun:06:00-sun:14:00", "AutoMinorVersionUpgrade" => true, "AllocatedStorage" => 5, "ReplicationSubnetGroup" => Dict{String, Any}("ReplicationSubnetGroupDescription" => "default", "ReplicationSubnetGroupIdentifier" => "default", "SubnetGroupStatus" => "Complete", "Subnets" => Any[Dict{String, Any}("SubnetIdentifier" => "subnet-f6dd91af", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1d")), Dict{String, Any}("SubnetIdentifier" => "subnet-3605751d", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1b")), Dict{String, Any}("SubnetIdentifier" => "subnet-c2daefb5", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1c")), Dict{String, Any}("SubnetIdentifier" => "subnet-85e90cb8", "SubnetStatus" => "Active", "SubnetAvailabilityZone" => Dict{String, Any}("Name" => "us-east-1e"))], "VpcId" => "vpc-6741a603"), "EngineVersion" => "1.5.0", "ReplicationInstanceClass" => "dms.t2.micro", "ReplicationInstanceArn" => "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", "KmsKeyId" => "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", "PendingModifiedValues" => Dict{String, Any}()))
end

modify_replication_subnet_group_1_patch = @patch function modify_replication_subnet_group(a...; b...)
    return Dict{String, Any}("ReplicationSubnetGroup" => Dict{String, Any}())
end

refresh_schemas_1_patch = @patch function refresh_schemas(a...; b...)
    return Dict{String, Any}("RefreshSchemasStatus" => Dict{String, Any}())
end

remove_tags_from_resource_1_patch = @patch function remove_tags_from_resource(a...; b...)
    return Dict{String, Any}()
end

start_replication_task_1_patch = @patch function start_replication_task(a...; b...)
    return Dict{String, Any}("ReplicationTask" => Dict{String, Any}("ReplicationTaskCreationDate" => "2016-12-14T18:25:43Z", "TableMappings" => "file://mappingfile.json", "TargetEndpointArn" => "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E", "ReplicationTaskArn" => "arn:aws:dms:us-east-1:123456789012:task:OEAMB3NXSTZ6LFYZFEPPBBXPYM", "ReplicationInstanceArn" => "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", "Status" => "creating", "SourceEndpointArn" => "arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", "MigrationType" => "full-load", "ReplicationTaskSettings" => "{\"TargetMetadata\":{\"TargetSchema\":\"\",\"SupportLobs\":true,\"FullLobMode\":true,\"LobChunkSize\":64,\"LimitedSizeLobMode\":false,\"LobMaxSize\":0},\"FullLoadSettings\":{\"FullLoadEnabled\":true,\"ApplyChangesEnabled\":false,\"TargetTablePrepMode\":\"DROP_AND_CREATE\",\"CreatePkAfterFullLoad\":false,\"StopTaskCachedChangesApplied\":false,\"StopTaskCachedChangesNotApplied\":false,\"ResumeEnabled\":false,\"ResumeMinTableSize\":100000,\"ResumeOnlyClusteredPKTables\":true,\"MaxFullLoadSubTasks\":8,\"TransactionConsistencyTimeout\":600,\"CommitRate\":10000},\"Logging\":{\"EnableLogging\":false}}", "ReplicationTaskIdentifier" => "task1"))
end

stop_replication_task_1_patch = @patch function stop_replication_task(a...; b...)
    return Dict{String, Any}("ReplicationTask" => Dict{String, Any}("ReplicationTaskCreationDate" => "2016-12-14T18:25:43Z", "TableMappings" => "file://mappingfile.json", "TargetEndpointArn" => "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E", "ReplicationTaskArn" => "arn:aws:dms:us-east-1:123456789012:task:OEAMB3NXSTZ6LFYZFEPPBBXPYM", "ReplicationInstanceArn" => "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", "Status" => "creating", "SourceEndpointArn" => "arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", "MigrationType" => "full-load", "ReplicationTaskSettings" => "{\"TargetMetadata\":{\"TargetSchema\":\"\",\"SupportLobs\":true,\"FullLobMode\":true,\"LobChunkSize\":64,\"LimitedSizeLobMode\":false,\"LobMaxSize\":0},\"FullLoadSettings\":{\"FullLoadEnabled\":true,\"ApplyChangesEnabled\":false,\"TargetTablePrepMode\":\"DROP_AND_CREATE\",\"CreatePkAfterFullLoad\":false,\"StopTaskCachedChangesApplied\":false,\"StopTaskCachedChangesNotApplied\":false,\"ResumeEnabled\":false,\"ResumeMinTableSize\":100000,\"ResumeOnlyClusteredPKTables\":true,\"MaxFullLoadSubTasks\":8,\"TransactionConsistencyTimeout\":600,\"CommitRate\":10000},\"Logging\":{\"EnableLogging\":false}}", "ReplicationTaskIdentifier" => "task1"))
end

test_connection_1_patch = @patch function test_connection(a...; b...)
    return Dict{String, Any}("Connection" => Dict{String, Any}())
end