text:
# This file is a part of Julia. License is MIT: https://julialang.org/license

## types ##

"""
    <:(T1, T2)

Subtype operator: returns `true` if and only if all values of type `T1` are
also of type `T2`.

# Examples
```jldoctest
julia> Float64 <: AbstractFloat
true

julia> Vector{Int} <: AbstractArray
true

julia> Matrix{Float64} <: Matrix{AbstractFloat}
false
```
"""
(<:)

"""
    >:(T1, T2)

Supertype operator, equivalent to `T2 <: T1`.
"""
const (>:)(@nospecialize(a), @nospecialize(b)) = (b <: a)

"""
    supertype(T::DataType)

Return the supertype of DataType `T`.

# Examples
```jldoctest
julia> supertype(Int32)
Signed
```
"""
function supertype(T::DataType)
    @_pure_meta
    T.super
end

function supertype(T::UnionAll)
    @_pure_meta
    UnionAll(T.var, supertype(T.body))
end

## generic comparison ##

"""
    ==(x, y)

Generic equality operator. Falls back to [`===`](@ref).
Should be implemented for all types with a notion of equality, based on the abstract value
that an instance represents. For example, all numeric types are compared by numeric value,
ignoring type. Strings are compared as sequences of characters, ignoring encoding.
For collections, `==` is generally called recursively on all contents,
though other properties (like the shape for arrays) may also be taken into account.

This operator follows IEEE semantics for floating-point numbers: `0.0 == -0.0` and
`NaN != NaN`.

The result is of type `Bool`, except when one of the operands is [`missing`](@ref),
in which case `missing` is returned
([three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic)).
For collections, `missing` is returned if at least one of the operands contains
a `missing` value and all non-missing values are equal.
Use [`isequal`](@ref) or [`===`](@ref) to always get a `Bool` result.

# Implementation
New numeric types should implement this function for two arguments of the new type, and
handle comparison to other types via promotion rules where possible.

[`isequal`](@ref) falls back to `==`, so new methods of `==` will be used by the
[`Dict`](@ref) type to compare keys. If your type will be used as a dictionary key, it
should therefore also implement [`hash`](@ref).
"""
==(x, y) = x === y

"""
    isequal(x, y)

Similar to [`==`](@ref), except for the treatment of floating point numbers
and of missing values. `isequal` treats all floating-point `NaN` values as equal
to each other, treats `-0.0` as unequal to `0.0`, and [`missing`](@ref) as equal
to `missing`. Always returns a `Bool` value.

# Implementation
The default implementation of `isequal` calls `==`, so a type that does not involve
floating-point values generally only needs to define `==`.

`isequal` is the comparison function used by hash tables (`Dict`). `isequal(x,y)` must imply
that `hash(x) == hash(y)`.

This typically means that types for which a custom `==` or `isequal` method exists must
implement a corresponding `hash` method (and vice versa). Collections typically implement
`isequal` by calling `isequal` recursively on all contents.

Scalar types generally do not need to implement `isequal` separate from `==`, unless they
represent floating-point numbers amenable to a more efficient implementation than that
provided as a generic fallback (based on `isnan`, `signbit`, and `==`).

# Examples
```jldoctest
julia> isequal([1., NaN], [1., NaN])
true

julia> [1., NaN] == [1., NaN]
false

julia> 0.0 == -0.0
true

julia> isequal(0.0, -0.0)
false
```
"""
isequal(x, y) = x == y

signequal(x, y) = signbit(x)::Bool == signbit(y)::Bool
signless(x, y) = signbit(x)::Bool & !signbit(y)::Bool

isequal(x::AbstractFloat, y::AbstractFloat) = (isnan(x) & isnan(y)) | signequal(x, y) & (x == y)
isequal(x::Real,          y::AbstractFloat) = (isnan(x) & isnan(y)) | signequal(x, y) & (x == y)
isequal(x::AbstractFloat, y::Real         ) = (isnan(x) & isnan(y)) | signequal(x, y) & (x == y)

"""
    isless(x, y)

Test whether `x` is less than `y`, according to a fixed total order.
`isless` is not defined on all pairs of values `(x, y)`. However, if it
is defined, it is expected to satisfy the following:
- If `isless(x, y)` is defined, then so is `isless(y, x)` and `isequal(x, y)`,
  and exactly one of those three yields `true`.
- The relation defined by `isless` is transitive, i.e.,
  `isless(x, y) && isless(y, z)` implies `isless(x, z)`.

Values that are normally unordered, such as `NaN`,
are ordered in an arbitrary but consistent fashion.
[`missing`](@ref) values are ordered last.

This is the default comparison used by [`sort`](@ref).

# Implementation
Non-numeric types with a total order should implement this function.
Numeric types only need to implement it if they have special values such as `NaN`.
Types with a partial order should implement [`<`](@ref).
"""
function isless end

isless(x::AbstractFloat, y::AbstractFloat) = (!isnan(x) & (isnan(y) | signless(x, y))) | (x < y)
isless(x::Real,          y::AbstractFloat) = (!isnan(x) & (isnan(y) | signless(x, y))) | (x < y)
isless(x::AbstractFloat, y::Real         ) = (!isnan(x) & (isnan(y) | signless(x, y))) | (x < y)

function ==(T::Type, S::Type)
    @_pure_meta
    return ccall(:jl_types_equal, Cint, (Any, Any), T, S) != 0
end
function !=(T::Type, S::Type)
    @_pure_meta
    return !(T == S)
end
==(T::TypeVar, S::Type) = false
==(T::Type, S::TypeVar) = false

## comparison fallbacks ##

"""
    !=(x, y)
    ≠(x,y)

Not-equals comparison operator. Always gives the opposite answer as [`==`](@ref).

# Implementation
New types should generally not implement this, and rely on the fallback definition
`!=(x,y) = !(x==y)` instead.

# Examples
```jldoctest
julia> 3 != 2
true

julia> "foo" ≠ "foo"
false
```
"""
!=(x, y) = !(x == y)
const ≠ = !=

"""
    ===(x,y) -> Bool
    ≡(x,y) -> Bool

Determine whether `x` and `y` are identical, in the sense that no program could distinguish
them. First the types of `x` and `y` are compared. If those are identical, mutable objects
are compared by address in memory and immutable objects (such as numbers) are compared by
contents at the bit level. This function is sometimes called "egal".
It always returns a `Bool` value.

# Examples
```jldoctest
julia> a = [1, 2]; b = [1, 2];

julia> a == b
true

julia> a === b
false

julia> a === a
true
```
"""
===
const ≡ = ===

"""
    !==(x, y)
    ≢(x,y)

Always gives the opposite answer as [`===`](@ref).

# Examples
```jldoctest
julia> a = [1, 2]; b = [1, 2];

julia> a ≢ b
true

julia> a ≢ a
false
```
"""
!==(@nospecialize(x), @nospecialize(y)) = !(x === y)
const ≢ = !==

"""
    <(x, y)

Less-than comparison operator. Falls back to [`isless`](@ref).
Because of the behavior of floating-point NaN values, this operator implements
a partial order.

# Implementation
New numeric types with a canonical partial order should implement this function for
two arguments of the new type.
Types with a canonical total order should implement [`isless`](@ref) instead.
(x < y) | (x == y)

# Examples
```jldoctest
julia> 'a' < 'b'
true

julia> "abc" < "abd"
true

julia> 5 < 3
false
```
"""
<(x, y) = isless(x, y)

"""
    >(x, y)

Greater-than comparison operator. Falls back to `y < x`.

# Implementation
Generally, new types should implement [`<`](@ref) instead of this function,
and rely on the fallback definition `>(x, y) = y < x`.

# Examples
```jldoctest
julia> 'a' > 'b'
false

julia> 7 > 3 > 1
true

julia> "abc" > "abd"
false

julia> 5 > 3
true
```
"""
>(x, y) = y < x

"""
    <=(x, y)
    ≤(x,y)

Less-than-or-equals comparison operator. Falls back to `(x < y) | (x == y)`.

# Examples
```jldoctest
julia> 'a' <= 'b'
true

julia> 7 ≤ 7 ≤ 9
true

julia> "abc" ≤ "abc"
true

julia> 5 <= 3
false
```
"""
<=(x, y) = (x < y) | (x == y)
const ≤ = <=

"""
    >=(x, y)
    ≥(x,y)

Greater-than-or-equals comparison operator. Falls back to `y <= x`.

# Examples
```jldoctest
julia> 'a' >= 'b'
false

julia> 7 ≥ 7 ≥ 3
true

julia> "abc" ≥ "abc"
true

julia> 5 >= 3
true
```
"""
>=(x, y) = (y <= x)
const ≥ = >=

# this definition allows Number types to implement < instead of isless,
# which is more idiomatic:
isless(x::Real, y::Real) = x<y

"""
    ifelse(condition::Bool, x, y)

Return `x` if `condition` is `true`, otherwise return `y`. This differs from `?` or `if` in
that it is an ordinary function, so all the arguments are evaluated first. In some cases,
using `ifelse` instead of an `if` statement can eliminate the branch in generated code and
provide higher performance in tight loops.

# Examples
```jldoctest
julia> ifelse(1 > 2, 1, 2)
2
```
"""
ifelse

"""
    cmp(x,y)

Return -1, 0, or 1 depending on whether `x` is less than, equal to, or greater than `y`,
respectively. Uses the total order implemented by `isless`.

# Examples
```jldoctest
julia> cmp(1, 2)
-1

julia> cmp(2, 1)
1

julia> cmp(2+im, 3-im)
ERROR: MethodError: no method matching isless(::Complex{Int64}, ::Complex{Int64})
[...]
```
"""
cmp(x, y) = isless(x, y) ? -1 : ifelse(isless(y, x), 1, 0)

"""
    cmp(<, x, y)

Return -1, 0, or 1 depending on whether `x` is less than, equal to, or greater than `y`,
respectively. The first argument specifies a less-than comparison function to use.
"""
cmp(<, x, y) = (x < y) ? -1 : ifelse(y < x, 1, 0)

# cmp returns -1, 0, +1 indicating ordering
cmp(x::Integer, y::Integer) = ifelse(isless(x, y), -1, ifelse(isless(y, x), 1, 0))

"""
    max(x, y, ...)

Return the maximum of the arguments. See also the [`maximum`](@ref) function
to take the maximum element from a collection.

# Examples
```jldoctest
julia> max(2, 5, 1)
5
```
"""
max(x, y) = ifelse(isless(y, x), x, y)

"""
    min(x, y, ...)

Return the minimum of the arguments. See also the [`minimum`](@ref) function
to take the minimum element from a collection.

# Examples
```jldoctest
julia> min(2, 5, 1)
1
```
"""
min(x,y) = ifelse(isless(y, x), y, x)

"""
    minmax(x, y)

Return `(min(x,y), max(x,y))`. See also: [`extrema`](@ref) that returns `(minimum(x), maximum(x))`.

# Examples
```jldoctest
julia> minmax('c','b')
('b', 'c')
```
"""
minmax(x,y) = isless(y, x) ? (y, x) : (x, y)

"""
    extrema(itr) -> Tuple

Compute both the minimum and maximum element in a single pass, and return them as a 2-tuple.

# Examples
```jldoctest
julia> extrema(2:10)
(2, 10)

julia> extrema([9,pi,4.5])
(3.141592653589793, 9.0)
```
"""
extrema(itr) = _extrema_itr(identity, itr)

"""
    extrema(f, itr) -> Tuple

Compute both the minimum and maximum of `f` applied to each element in `itr` and return
them as a 2-tuple. Only one pass is made over `itr`.

!!! compat "Julia 1.2"
    This method requires Julia 1.2 or later.

# Examples
```jldoctest
julia> extrema(sin, 0:π)
(0.0, 0.9092974268256817)
```
"""
extrema(f, itr) = _extrema_itr(f, itr)

function _extrema_itr(f, itr)
    y = iterate(itr)
    y === nothing && throw(ArgumentError("collection must be non-empty"))
    (v, s) = y
    vmin = vmax = f(v)
    while true
        y = iterate(itr, s)
        y === nothing && break
        (x, s) = y
        fx = f(x)
        vmax = max(fx, vmax)
        vmin = min(fx, vmin)
    end
    return (vmin, vmax)
end

extrema(x::Real) = (x, x)
extrema(f, x::Real) = (y = f(x); (y, y))

## definitions providing basic traits of arithmetic operators ##

"""
    identity(x)

The identity function. Returns its argument.

# Examples
```jldoctest
julia> identity("Well, what did you expect?")
"Well, what did you expect?"
```
"""
identity(x) = x

+(x::Number) = x
*(x::Number) = x
(&)(x::Integer) = x
(|)(x::Integer) = x
xor(x::Integer) = x

const ⊻ = xor

# foldl for argument lists. expand recursively up to a point, then
# switch to a loop. this allows small cases like `a+b+c+d` to be inlined
# efficiently, without a major slowdown for `+(x...)` when `x` is big.
afoldl(op,a) = a
afoldl(op,a,b) = op(a,b)
afoldl(op,a,b,c...) = afoldl(op, op(a,b), c...)
function afoldl(op,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,qs...)
    y = op(op(op(op(op(op(op(op(op(op(op(op(op(op(op(a,b),c),d),e),f),g),h),i),j),k),l),m),n),o),p)
    for x in qs; y = op(y,x); end
    y
end

for op in (:+, :*, :&, :|, :xor, :min, :max, :kron)
    @eval begin
        # note: these definitions must not cause a dispatch loop when +(a,b) is
        # not defined, and must only try to call 2-argument definitions, so
        # that defining +(a,b) is sufficient for full functionality.
        ($op)(a, b, c, xs...) = afoldl($op, ($op)(($op)(a,b),c), xs...)
        # a further concern is that it's easy for a type like (Int,Int...)
        # to match many definitions, so we need to keep the number of
        # definitions down to avoid losing type information.
    end
end

"""
    \\(x, y)

Left division operator: multiplication of `y` by the inverse of `x` on the left. Gives
floating-point results for integer arguments.

# Examples
```jldoctest
julia> 3 \\ 6
2.0

julia> inv(3) * 6
2.0

julia> A = [4 3; 2 1]; x = [5, 6];

julia> A \\ x
2-element Array{Float64,1}:
  6.5
 -7.0

julia> inv(A) * x
2-element Array{Float64,1}:
  6.5
 -7.0
```
"""
\(x,y) = adjoint(adjoint(y)/adjoint(x))

# Core <<, >>, and >>> take either Int or UInt as second arg. Signed shift
# counts can shift in either direction, and are translated here to unsigned
# counts. Integer datatypes only need to implement the unsigned version.

"""
    <<(x, n)

Left bit shift operator, `x << n`. For `n >= 0`, the result is `x` shifted left
by `n` bits, filling with `0`s. This is equivalent to `x * 2^n`. For `n < 0`,
this is equivalent to `x >> -n`.

# Examples
```jldoctest
julia> Int8(3) << 2
12

julia> bitstring(Int8(3))
"00000011"

julia> bitstring(Int8(12))
"00001100"
```
See also [`>>`](@ref), [`>>>`](@ref).
"""
function <<(x::Integer, c::Integer)
    @_inline_meta
    typemin(Int) <= c <= typemax(Int) && return x << (c % Int)
    (x >= 0 || c >= 0) && return zero(x) << 0  # for type stability
    oftype(x, -1)
end
function <<(x::Integer, c::Unsigned)
    @_inline_meta
    if c isa UInt
        throw(MethodError(<<, (x, c)))
    end
    c <= typemax(UInt) ? x << (c % UInt) : zero(x) << UInt(0)
end
<<(x::Integer, c::Int) = c >= 0 ? x << unsigned(c) : x >> unsigned(-c)

"""
    >>(x, n)

Right bit shift operator, `x >> n`. For `n >= 0`, the result is `x` shifted
right by `n` bits, where `n >= 0`, filling with `0`s if `x >= 0`, `1`s if `x <
0`, preserving the sign of `x`. This is equivalent to `fld(x, 2^n)`. For `n <
0`, this is equivalent to `x << -n`.

# Examples
```jldoctest
julia> Int8(13) >> 2
3

julia> bitstring(Int8(13))
"00001101"

julia> bitstring(Int8(3))
"00000011"

julia> Int8(-14) >> 2
-4

julia> bitstring(Int8(-14))
"11110010"

julia> bitstring(Int8(-4))
"11111100"
```
See also [`>>>`](@ref), [`<<`](@ref).
"""
function >>(x::Integer, c::Integer)
    @_inline_meta
    if c isa UInt
        throw(MethodError(>>, (x, c)))
    end
    typemin(Int) <= c <= typemax(Int) && return x >> (c % Int)
    (x >= 0 || c < 0) && return zero(x) >> 0
    oftype(x, -1)
end
>>(x::Integer, c::Int) = c >= 0 ? x >> unsigned(c) : x << unsigned(-c)

"""
    >>>(x, n)

Unsigned right bit shift operator, `x >>> n`. For `n >= 0`, the result is `x`
shifted right by `n` bits, where `n >= 0`, filling with `0`s. For `n < 0`, this
is equivalent to `x << -n`.

For [`Unsigned`](@ref) integer types, this is equivalent to [`>>`](@ref). For
[`Signed`](@ref) integer types, this is equivalent to `signed(unsigned(x) >> n)`.

# Examples
```jldoctest
julia> Int8(-14) >>> 2
60

julia> bitstring(Int8(-14))
"11110010"

julia> bitstring(Int8(60))
"00111100"
```

[`BigInt`](@ref)s are treated as if having infinite size, so no filling is required and this
is equivalent to [`>>`](@ref).

See also [`>>`](@ref), [`<<`](@ref).
"""
function >>>(x::Integer, c::Integer)
    @_inline_meta
    typemin(Int) <= c <= typemax(Int) ? x >>> (c % Int) : zero(x) >>> 0
end
function >>>(x::Integer, c::Unsigned)
    @_inline_meta
    if c isa UInt
        throw(MethodError(>>>, (x, c)))
    end
    c <= typemax(UInt) ? x >>> (c % UInt) : zero(x) >>> 0
end
>>>(x::Integer, c::Int) = c >= 0 ? x >>> unsigned(c) : x << unsigned(-c)

# operator alias

"""
    rem(x, y)
    %(x, y)

Remainder from Euclidean division, returning a value of the same sign as `x`, and smaller in
magnitude than `y`. This value is always exact.

# Examples
```jldoctest
julia> x = 15; y = 4;

julia> x % y
3

julia> x == div(x, y) * y + rem(x, y)
true
```
"""
rem
const % = rem

"""
    div(x, y)
    ÷(x, y)

The quotient from Euclidean division. Computes `x/y`, truncated to an integer.

# Examples
```jldoctest
julia> 9 ÷ 4
2

julia> -5 ÷ 3
-1

julia> 5.0 ÷ 2
2.0
```
"""
div
const ÷ = div

"""
    mod1(x, y)

Modulus after flooring division, returning a value `r` such that `mod(r, y) == mod(x, y)`
in the range ``(0, y]`` for positive `y` and in the range ``[y,0)`` for negative `y`.

See also: [`fld1`](@ref), [`fldmod1`](@ref).

# Examples
```jldoctest
julia> mod1(4, 2)
2

julia> mod1(4, 3)
1
```
"""
mod1(x::T, y::T) where {T<:Real} = (m = mod(x, y); ifelse(m == 0, y, m))

"""
    fld1(x, y)

Flooring division, returning a value consistent with `mod1(x,y)`

See also: [`mod1`](@ref), [`fldmod1`](@ref).

# Examples
```jldoctest
julia> x = 15; y = 4;

julia> fld1(x, y)
4

julia> x == fld(x, y) * y + mod(x, y)
true

julia> x == (fld1(x, y) - 1) * y + mod1(x, y)
true
```
"""
fld1(x::T, y::T) where {T<:Real} = (m = mod1(x, y); fld(x + y - m, y))
function fld1(x::T, y::T) where T<:Integer
    d = div(x, y)
    return d + (!signbit(x ⊻ y) & (d * y != x))
end

"""
    fldmod1(x, y)

Return `(fld1(x,y), mod1(x,y))`.

See also: [`fld1`](@ref), [`mod1`](@ref).
"""
fldmod1(x, y) = (fld1(x, y), mod1(x, y))

"""
    widen(x)

If `x` is a type, return a "larger" type, defined so that arithmetic operations
`+` and `-` are guaranteed not to overflow nor lose precision for any combination
of values that type `x` can hold.

For fixed-size integer types less than 128 bits, `widen` will return a type with
twice the number of bits.

If `x` is a value, it is converted to `widen(typeof(x))`.

# Examples
```jldoctest
julia> widen(Int32)
Int64

julia> widen(1.5f0)
1.5
```
"""
widen(x::T) where {T} = convert(widen(T), x)
widen(x::Type{T}) where {T} = throw(MethodError(widen, (T,)))

# function pipelining

"""
    |>(x, f)

Applies a function to the preceding argument. This allows for easy function chaining.

# Examples
```jldoctest
julia> [1:5;] |> x->x.^2 |> sum |> inv
0.01818181818181818
```
"""
|>(x, f) = f(x)

# function composition

"""
    f ∘ g

Compose functions: i.e. `(f ∘ g)(args...)` means `f(g(args...))`. The `∘` symbol can be
entered in the Julia REPL (and most editors, appropriately configured) by typing `\\circ<tab>`.

Function composition also works in prefix form: `∘(f, g)` is the same as `f ∘ g`.
The prefix form supports composition of multiple functions: `∘(f, g, h) = f ∘ g ∘ h`
and splatting `∘(fs...)` for composing an iterable collection of functions.

!!! compat "Julia 1.4"
    Multiple function composition requires at least Julia 1.4.

!!! compat "Julia 1.5"
    Composition of one function ∘(f)  requires at least Julia 1.5.

# Examples
```jldoctest
julia> map(uppercase∘first, ["apple", "banana", "carrot"])
3-element Array{Char,1}:
 'A'
 'B'
 'C'

julia> fs = [
           x -> 2x
           x -> x/2
           x -> x-1
           x -> x+1
       ];

julia> ∘(fs...)(3)
3.0
```
"""
function ∘ end
∘(f) = f
∘(f, g) = (x...)->f(g(x...))
∘(f, g, h...) = ∘(f ∘ g, h...)

"""
    !f::Function

Predicate function negation: when the argument of `!` is a function, it returns a
function which computes the boolean negation of `f`.

# Examples
```jldoctest
julia> str = "∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε"
"∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε"

julia> filter(isletter, str)
"εδxyδfxfyε"

julia> filter(!isletter, str)
"∀  > 0, ∃  > 0: |-| <  ⇒ |()-()| < "
```
"""
!(f::Function) = (x...)->!f(x...)

"""
    Fix1(f, x)

A type representing a partially-applied version of the two-argument function
`f`, with the first argument fixed to the value "x". In other words,
`Fix1(f, x)` behaves similarly to `y->f(x, y)`.
"""
struct Fix1{F,T} <: Function
    f::F
    x::T

    Fix1(f::F, x::T) where {F,T} = new{F,T}(f, x)
    Fix1(f::Type{F}, x::T) where {F,T} = new{Type{F},T}(f, x)
end

(f::Fix1)(y) = f.f(f.x, y)

"""
    Fix2(f, x)

A type representing a partially-applied version of the two-argument function
`f`, with the second argument fixed to the value "x". In other words,
`Fix2(f, x)` behaves similarly to `y->f(y, x)`.
"""
struct Fix2{F,T} <: Function
    f::F
    x::T

    Fix2(f::F, x::T) where {F,T} = new{F,T}(f, x)
    Fix2(f::Type{F}, x::T) where {F,T} = new{Type{F},T}(f, x)
end

(f::Fix2)(y) = f.f(y, f.x)

"""
    isequal(x)

Create a function that compares its argument to `x` using [`isequal`](@ref), i.e.
a function equivalent to `y -> isequal(y, x)`.

The returned function is of type `Base.Fix2{typeof(isequal)}`, which can be
used to implement specialized methods.
"""
isequal(x) = Fix2(isequal, x)

"""
    ==(x)

Create a function that compares its argument to `x` using [`==`](@ref), i.e.
a function equivalent to `y -> y == x`.

The returned function is of type `Base.Fix2{typeof(==)}`, which can be
used to implement specialized methods.
"""
==(x) = Fix2(==, x)

"""
    !=(x)

Create a function that compares its argument to `x` using [`!=`](@ref), i.e.
a function equivalent to `y -> y != x`.
The returned function is of type `Base.Fix2{typeof(!=)}`, which can be
used to implement specialized methods.

!!! compat "Julia 1.2"
    This functionality requires at least Julia 1.2.
"""
!=(x) = Fix2(!=, x)

"""
    >=(x)

Create a function that compares its argument to `x` using [`>=`](@ref), i.e.
a function equivalent to `y -> y >= x`.
The returned function is of type `Base.Fix2{typeof(>=)}`, which can be
used to implement specialized methods.

!!! compat "Julia 1.2"
    This functionality requires at least Julia 1.2.
"""
>=(x) = Fix2(>=, x)

"""
    <=(x)

Create a function that compares its argument to `x` using [`<=`](@ref), i.e.
a function equivalent to `y -> y <= x`.
The returned function is of type `Base.Fix2{typeof(<=)}`, which can be
used to implement specialized methods.

!!! compat "Julia 1.2"
    This functionality requires at least Julia 1.2.
"""
<=(x) = Fix2(<=, x)

"""
    >(x)

Create a function that compares its argument to `x` using [`>`](@ref), i.e.
a function equivalent to `y -> y > x`.
The returned function is of type `Base.Fix2{typeof(>)}`, which can be
used to implement specialized methods.

!!! compat "Julia 1.2"
    This functionality requires at least Julia 1.2.
"""
>(x) = Fix2(>, x)

"""
    <(x)

Create a function that compares its argument to `x` using [`<`](@ref), i.e.
a function equivalent to `y -> y < x`.
The returned function is of type `Base.Fix2{typeof(<)}`, which can be
used to implement specialized methods.

!!! compat "Julia 1.2"
    This functionality requires at least Julia 1.2.
"""
<(x) = Fix2(<, x)

"""
    splat(f)

Defined as
```julia
    splat(f) = args->f(args...)
```
i.e. given a function returns a new function that takes one argument and splats
its argument into the original function. This is useful as an adaptor to pass
a multi-argument function in a context that expects a single argument, but
passes a tuple as that single argument.

# Example usage:
```jldoctest
julia> map(Base.splat(+), zip(1:3,4:6))
3-element Array{Int64,1}:
 5
 7
 9
```
"""
splat(f) = args->f(args...)

## in & contains

"""
    in(x)

Create a function that checks whether its argument is [`in`](@ref) `x`, i.e.
a function equivalent to `y -> y in x`.

The returned function is of type `Base.Fix2{typeof(in)}`, which can be
used to implement specialized methods.
"""
in(x) = Fix2(in, x)

function in(x, itr)
    anymissing = false
    for y in itr
        v = (y == x)
        if ismissing(v)
            anymissing = true
        elseif v
            return true
        end
    end
    return anymissing ? missing : false
end

const ∈ = in
∋(itr, x) = ∈(x, itr)
∉(x, itr) = !∈(x, itr)
∌(itr, x) = !∋(itr, x)

"""
    in(item, collection) -> Bool
    ∈(item, collection) -> Bool
    ∋(collection, item) -> Bool

Determine whether an item is in the given collection, in the sense that it is
[`==`](@ref) to one of the values generated by iterating over the collection.
Returns a `Bool` value, except if `item` is [`missing`](@ref) or `collection`
contains `missing` but not `item`, in which case `missing` is returned
([three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic),
matching the behavior of [`any`](@ref) and [`==`](@ref)).

Some collections follow a slightly different definition. For example,
[`Set`](@ref)s check whether the item [`isequal`](@ref) to one of the elements.
[`Dict`](@ref)s look for `key=>value` pairs, and the key is compared using
[`isequal`](@ref). To test for the presence of a key in a dictionary,
use [`haskey`](@ref) or `k in keys(dict)`. For these collections, the result
is always a `Bool` and never `missing`.

# Examples
```jldoctest
julia> a = 1:3:20
1:3:19

julia> 4 in a
true

julia> 5 in a
false

julia> missing in [1, 2]
missing

julia> 1 in [2, missing]
missing

julia> 1 in [1, missing]
true

julia> missing in Set([1, 2])
false
```
"""
in, ∋

"""
    ∉(item, collection) -> Bool
    ∌(collection, item) -> Bool

Negation of `∈` and `∋`, i.e. checks that `item` is not in `collection`.

# Examples
```jldoctest
julia> 1 ∉ 2:4
true

julia> 1 ∉ 1:3
false
```
"""
∉, ∌

max_stars_repo_name: fungktt/julia

max_issues_repo_name: fungktt/julia

max_forks_repo_name: fungktt/julia


text:
# primitives.jl

#==
 Key concept is GOAL
 but not define it as type.

 GOAL is a literal Array.
 And a Set of GOAL should be maintained.
==#

## Type declare

FTerm=Expr
Term=Union{Symbol, Number, Expr}
Var = Symbol
Const = Union{Symbol, Number}

Vlist = Array
Tlist = Array

## primitives
isvar(sym::Symbol, vars::Vlist)=sym in vars
isvar(term, vars::Vlist)=false

function isevar(sym::Symbol, vars::Vlist)
 isvar(sym, vars) && isuppercase(string(sym)[1])
end
isevar(sym, vars::Vlist)=false

isconst(sym::Symbol, vars::Vlist)=!(sym in vars)
isconst(sym::Number, vars::Vlist)=true

# function
macro isdefined(x)
  try
    eval(x)
  catch
    return false
  end
  return true
end

ext: jl

max_stars_repo_name: sazare/cheapViews

max_issues_repo_name: sazare/cheapViews

max_forks_repo_name: sazare/cheapViews


text:
"""
`AbstractTable`

An abstract tabular data type.

The `AbstractTable` interface requisite methods can be found in
`src/interface.jl`.

The column-indexable interface (which assumes satisfaction of the
`AbstractTable` interface) requisite methods can be found in
`src/column-indexable/interface.jl`.

The query interface for column-indexable `T<:AbstractTable` requisite methods
can be found in `src/column-indexable/query/interface.jl`.
"""
abstract AbstractTable


text:
using Gnuplot
bgcp1 = "set object rectangle from screen 0,0 to screen 1,1"
bgcp2 = " behind fillcolor 'black' fillstyle solid noborder"
bgcolor = bgcp1*bgcp2
U  = LinRange(-π,π, 50)
V = LinRange(-π,π, 100)
r = 0.5
x = [1 + cos(u) + r * cos(u) * cos(v)  for u in U, v in V]
y = [r * sin(v)                        for u in U, v in V]
z = [sin(u) + r * sin(u) * cos(v)      for u in U, v in V]
@gsp "set pm3d depthorder"
@gsp :- "set style fill transparent solid 0.5"
@gsp :- "set pm3d lighting primary 0.05 specular 0.2"
@gsp :- x y z "w pm3d notit" palette(:cool) "set view 108,2"
@gsp :- "unset border" "set xyplane 0"
@gsp :- "unset tics"
@gsp :- "unset colorbox"
@gsp :- bgcolor
save(term="pngcairo size 600,400", output="torus1.png") # hide

max_stars_repo_name: lazarusA/gnuplot-examples

max_issues_repo_name: lazarusA/gnuplot-examples

max_forks_repo_name: lazarusA/gnuplot-examples


text:
using Documenter, Heatmap

makedocs(
    modules = [Heatmap],
    clean = false,
    sitename = "Heatmap.jl",
    pages = [
        "Home" => "index.md",
        "Gallery" => "gallery/Examples.md",
        "Library" => "lib/library.md"
    ],
)

deploydocs(
    repo = "github.com/Mattriks/Heatmap.jl.git",
)


text:
using Visualize, GeometryTypes, ModernGL
using Visualize.GLRasterization
using ModernGL, FileIO
import Visualize: GLRasterization
using Visualize: VertexN, Light, Shading, vert_mesh, frag_mesh, Debugging

include("mesh.jl")


text:
gwidget(w::T) where T <: Widget = getfield(w, :widget)
getprop(w::Widget, name::SymString, T::DataType) = getprop(gwidget(w), name, T)
setprop!(w::Widget, name::SymString, value::T) where {T} = setprop!(gwidget(w), name, value)
disconnect(w::Widget, id) = disconnect(gwidget(w), id)

Base.get(w::Widget, name::SymString, T::DataType) = getprop(w, name, T)
Base.getindex(w::Widget, name::SymString, T::DataType) = getprop(w, name, T)
Base.setindex!(w::Widget, value, name::SymString) = setprop!(w, name, value)

function onevent(callback::Function, event::SymString, self::Widget)
    return signal_connect(callback, gwidget(self), event)
end

function Base.push!(w::Container, children::Widget...)
    for child in children
        push!(gwidget(w), gwidget(child))
    end
end

function Base.setindex!(grid::Grid, child::Widget, indices::Vararg{Union{Int, UnitRange}})
    setindex!(gwidget(grid), gwidget(child), indices...)
end

Observables.on(f, input::Input; kwargs...) = on(f, input.value; kwargs...)

Gtk.showall(w::Widget) = Gtk.showall(gwidget(w))
Gtk.width(w::Widget) = Gtk.width(gwidget(w))
Gtk.height(w::Widget) = Gtk.height(gwidget(w))
Gtk.destroy(w::Widget) = Gtk.destroy(gwidget(w))

Base.size(w::Widget) = (Gtk.width(w), Gtk.height(w))
Base.show(w::Widget) = Gtk.show(gwidget(w))

Base.show(io::IO, ::T) where {T <: Widget} = write(io, "$T")

"""
        value(widget::Input{T}) -> T

Returns the `value` of a `Input` widget.
"""
function value(input::Input)
    return input.value[]
end
"""
        value!(widget::Input, value) -> Nothing

Sets the `value` of a `Input` widget.
"""
function value!(input::Input, value)
    input.value[] = value
end

Base.getindex(input::Input) = value(input)
Base.setindex!(input::Input, value) = value!(input, value)

value!(input::RangeWidget, value::Real) = G.value(input.adjustment, value)

function value!(w::ColorButton{T}, value::Colorant) where {T}
    w["rgba"] = convert(GdkRGBA, value)
end

value!(input::Activable, value::Bool) = G.active(gwidget(input), value)

value!(input::Switch, value::Bool) = setprop!(input, :active, value)

function value!(dropdown::Dropdown, value::Int)
    dropdown["active"] = value - 1
    dropdown.value[] = dropdown.choices[value]
end

Base.getindex(widget::Dropdown, index::Int) = widget.choices[index]

progress_bar_pulse(w::GtkProgressBar) = @ccall libgtk.gtk_progress_bar_pulse(w::Ptr{GObject})::Cvoid

"""
        pulse!(widget::ProgressBar) -> Nothing

Make the progress bar pulse, indicating that a unknown
amount of progress has been made.
"""
pulse!(bar::ProgressBar) = progress_bar_pulse(bar.widget)

"""
        fill!(bar::ProgressBar, fraction::Real) -> Nothing

Causes the progress bar to “fill in” the given `fraction` of the bar.
The fraction should be between 0.0 and 1.0, inclusive.
"""
Base.fill!(bar::ProgressBar, fraction::Real) = G.fraction(bar.widget, fraction)

function value!(input::TextField, value::String)
    GAccessor.text(input.widget, value)
    input.value[] = value
end

function Base.push!(button::Button, image::ImageView)
    GAccessor.always_show_image(button.widget, true)
    GAccessor.image(button.widget, image.widget)
end

macro showall(widget)
    return quote
        showall($( esc(widget) ))
    end
end


text:
module TriangulatedWindingNumbers

include("Vertexes.jl")
include("Simplexes.jl")

function generatesimplices(f::F, lower::AbstractVector{T}, upper::AbstractVector{T},
    gridsize::AbstractVector{<:Integer}) where {F<:Function, T<:Number}
  all(gridsize .> 0) || throw(ArgumentError("gridsize must .> 0"))
  if !(length(lower) == length(upper) == length(gridsize))
    throw(ArgumentError("The lengths of lower, $lower, upper, $upper, and gridsize
                        $gridsize must be the same"))
  end
  if !(all(lower .< upper))
    throw(ArgumentError("lower, $lower must .< upper, $upper"))
  end
  dim = length(lower)
  index2position(i) = (i .- 1) ./ gridsize .* (upper .- lower) .+ lower
  index2values = Dict()
  totaltime = @elapsed for ii ∈ CartesianIndices(Tuple(gridsize .+ 1))
    index = collect(Tuple(ii))
    x = index2position(index)
    index2values[index] = f(x)
  end
  U = typeof(first(index2values)[2])
  simplices = Set{Simplex{T, U}}()
  function generatesimplices!(simplices, direction)
    for ii ∈ CartesianIndices(Tuple(((gridsize .+ 1) .* ones(Int, dim))))
      vertices = Vector{Vertex{T, U}}()
      index = collect(Tuple(ii))
      for i ∈ 1:dim + 1
        vertexindex = [index[j] + ((j == i) ? direction : 0) for j ∈ 1:dim]
        all(1 .<= vertexindex .<= gridsize .+ 1) || continue
        vertex = Vertex{T, U}(index2position(vertexindex),
                              index2values[vertexindex])
        push!(vertices, vertex)
      end
      length(vertices) != dim + 1 && continue
      push!(simplices, Simplex{T, U}(vertices))
    end
  end

  totaltime += @elapsed generatesimplices!(simplices, 1)
  totaltime += @elapsed generatesimplices!(simplices, -1)
  @assert length(simplices) == 2 * prod(gridsize)
  return (simplices, totaltime)
end

function convergenceconfig(dim::Int, T::Type; kwargs...)
  kwargs = Dict(kwargs)
  timelimit = get(kwargs, :timelimit, Inf)
  xtol_abs = get(kwargs, :xtol_abs, zeros(T)) .* ones(Bool, dim)
  xtol_rel = get(kwargs, :xtol_rel, eps(T)) .* ones(Bool, dim)
  ftol_abs = get(kwargs, :ftol_abs, 0)
  ftol_rel = get(kwargs, :ftol_rel, eps())
  stopvalroot = get(kwargs, :stopvalroot, nextfloat(0.0)) # zero makes it go haywire
  stopvalpole = get(kwargs, :stopvalpole, Inf)
  if any(iszero.(xtol_rel) .& iszero.(xtol_abs))
    throw(ArgumentError("xtol_rel .& xtol_abs must not contain zeros"))
  end
  return (timelimit=timelimit, xtol_abs=xtol_abs, xtol_rel=xtol_rel,
          ftol_abs=ftol_abs, ftol_rel=ftol_rel,
          stopvalroot=stopvalroot, stopvalpole=stopvalpole)
end

"""
    solve(f, lower, upper, gridsizeint; kwargs...)

Find the roots and poles of function, `f`, in a hyper-rectangle from
`lower` to `upper` with simplices generating in `gridsizeint`
sub-hyper-rectangles, and options passed in via kwargs.
"""
function solve(f::F, lower::AbstractVector{T}, upper::AbstractVector{T},
    gridsizeint::U; kwargs...) where {F<:Function, T<:Number, U<:Integer}
  gridsize = gridsizeint .* ones(typeof(gridsizeint), length(lower))
  return solve(f, lower, upper, gridsize;  kwargs...)
end

"""
    solve(f, lower, upper, gridsize; kwargs...)

Find the roots and poles of function, `f`, in a hyper-rectangle from
`lower` to `upper` with simplices generating in `gridsize`
sub-hyper-rectangles, and options passed in via kwargs.
"""
function solve(f::F, lower::AbstractVector{T}, upper::AbstractVector{T},
    gridsize::AbstractVector{<:Integer}; kwargs...) where {F<:Function, T<:Number}
  simplices, totaltime = generatesimplices(f, lower, upper, gridsize)
  return solve(f, collect(simplices), totaltime; kwargs...)
end

"""
    solve(f, simplices, totaltime=0.0; kwargs...)

Find the roots and poles of function, `f`, by subdividing `simplices` and
checking to see if the child simplices contain a root or a pole by evaluating
the winding number, and options passed in via kwargs.

Function `f` accepts an n-dimensional array as an argument and returns a complex
number.

# Keyword Arguments
-  stopval (default sqrt(eps())): stopping criterion when function evaluates
equal to or less than stopval
-  xtol_abs (default zeros(T)) .* ones(Bool, dimensionality(s)): stop if
the vertices of simplex get within this absolute tolerance
-  xtol_rel (default eps(T)) .* ones(Bool, dimensionality(s)): stop if
the vertices of simplex get within this relative tolerance
-  ftol_abs (default 0): stop if function evaluations at the
vertices are close to one another by this absolute tolerance
-  ftol_rel (default 1000eps(real(U))): stop if function evaluations at the
vertices are close to one another by this relative tolerance
-  timelimit (default Inf): stop if it takes longer than this in seconds
-  stopvalroot (default nextfloat(0.0): stop if any value is less than or
equal to this
-  stopvalpole (default Inf): stop if any value is greater than or equal to this
"""
function solve(f::F, simplices::AbstractVector{Simplex{T, U}}, totaltime=0.0;
    kwargs...) where {F<:Function, T<:Number, U<:Complex}

  config = convergenceconfig(dimensionality(first(simplices)), T; kwargs...)

  solutions = Vector{Tuple{eltype(simplices), Symbol}}()
  while totaltime < config[:timelimit]
    newsimplices = Vector{eltype(simplices)}()
    for (i, simplex) ∈ enumerate(simplices)
      windingnumber(simplex) == 0 && continue
      innermost = closestomiddlevertex(simplex)
      Δt = @elapsed centroidvertex = centroidignorevertex(f, simplex, innermost)
      for vertex ∈ simplex
        isequal(vertex, innermost) && continue
        newsimplex = deepcopy(simplex)
        swap!(newsimplex, vertex, centroidvertex)
        isequal(newsimplex, simplex) && continue
        windingnumber(newsimplex) == 0 && continue
        isconverged, returncode = assessconvergence(newsimplex, config)
        isconverged && push!(solutions, (newsimplex, returncode))
        isconverged || push!(newsimplices, newsimplex)
      end
      (totaltime += Δt) > config[:timelimit] && break
    end
    simplices = newsimplices
    isempty(simplices) && break
  end # while
  return solutions
end # solve

end


text:
@testset "Reading rasters" begin
    ga = GeoArrays.read("data/utmsmall.tif")
    @test bbox(ga) == (min_x=440720.0, min_y=3.74532e6, max_x=446720.0, max_y=3.75132e6)
    @test bboxes(ga)[1] == (min_x=440720.0, max_x=440780.0, min_y=3.75126e6, max_y=3.75132e6)
    @test bboxes(ga)[end] == (min_x=446660.0, max_x=446720.0, min_y=3.74532e6, max_y=3.74538e6)
end


text:
#-----------------------------------------------------------------------# General
const Tup = Union{Tuple, NamedTuple}
const XY = Union{AbstractVector, Tup, Pair}
const VectorOb = Union{AbstractVector, Tup}
const TwoThings{T,S} = Union{Tuple{T,S}, Pair{T,S}, NamedTuple{names, Tuple{T,S}}} where names

const ϵ = 1e-7

#-----------------------------------------------------------------------# BiasVec
"""
    BiasVec(x)

Lightweight wrapper of a vector which adds a "bias" term at the end.

# Example

    BiasVec(rand(5))
"""
struct BiasVec{T, A <: VectorOb} <: AbstractVector{T}
    x::A
    bias::T
end
BiasVec(x::AbstractVector{T}) where {T} = BiasVec(x, one(T))
BiasVec(x::Tup) = BiasVec(x, one(typeof(first(x))))

Base.length(v::BiasVec) = length(v.x) + 1
Base.size(v::BiasVec) = (length(v), )
Base.getindex(v::BiasVec, i::Int) = i > length(v.x) ? v.bias : v.x[i]
Base.IndexStyle(::Type{<:BiasVec}) = IndexLinear()

# #-----------------------------------------------------------------------# sparkline
# const ticks = ['▁','▂','▃','▄','▅','▆','▇']

# sparkline(x) = sparkline(stdout, x)
# sparkline(io::IO, x) = print(io, sparkstring(x))

# function sparkstring(x)
#     out = ""
#     if !isempty(x)
#         a, b = extrema(x)
#         for xi in x
#             i = round(Int, 7 * (xi-a) / (b-a))
#             out *= i == 0 ? ' ' : ticks[i]
#         end
#     end
#     out
# end


text:
module BenchmarkBot

using PkgBenchmark, GitHub, JSON, UUIDs, Dates, Base64
export BenchmarkConfig, submit_report, submit_issue, runbenchmarks, token

function token()
    if haskey(ENV, "GITHUB_BENCHMARK_TOKEN")
        return authenticate(ENV["GITHUB_BENCHMARK_TOKEN"])
    else
        error("set github token by export GITHUB_BENCHMARK_TOKEN")
    end
end

const REPO = repo("QuantumBFS/YaoBenchmarks.jl")

function submit_report(repo, package, results)
    file_json = JSON.parse(
        """
        {
            "message": "automatic generated benchmark report",
            "content": "$(base64encode(sprint(export_markdown, results)))"
        }
        """
    )

    t = Dates.now()
    folder = join(["reports", year(t), month(t), day(t), package], "/")
    filepath = join([folder, "/", string(uuid1()), ".md"])
    create_file(repo, filepath, params=file_json, auth=token())
    submit_issue(repo, filepath)
end

function submit_issue(repo, filepath)
    issue_json = JSON.parse(
        """
        {
            "title": "Benchmark Report Generated for multithreading",
            "body": "benchmark report generated. See details at $(escape_string(string(file(repo, filepath).html_url)))",
            "labels": ["benchmark report"]
        }
        """
    )

    create_issue(repo; params=issue_json, auth=token())
end

function runbenchmarks(;package, target, baseline)
    results = judge(package, target, baseline)
    submit_report(REPO, package, results)
end

end # module


text:
using Documenter, BeamFEA

makedocs(;
    modules=[BeamFEA],
    format=Documenter.HTML(),
    pages=[
        "Home" => "index.md",
        "Theory" => "theory.md",
    ],
    repo="https://github.com/byuflowlab/BeamFEA.jl/blob/{commit}{path}#L{line}",
    sitename="BeamFEA.jl",
    authors="Andrew Ning <aning@byu.edu>",
)

deploydocs(
    repo = "github.com/byuflowlab/BeamFEA.jl.git",
)


text:
# Compute the Leonard-Jones potential energy function

function upair(r,data)
  r6 = (r^2)^3
  r12 = (r^2)^6
  return data.eps4*(data.sig12/r12 - data.sig6/r6)

end


text:
using Interpolations

"""
Does a cubic spline interpolation and then takes a derivative across
the row for each column
"""
function numerical_derivative(dat, ts)
    # Take the approximate derivative in the row direction
    interp = []
    dat_grad = zeros(size(dat))
    if ts isa Array
        # Breaks the interpolation function if 'ts' is an array
        dt = ts[2]-ts[1]
        ts = ts[1]:dt:ts[end]
    end

    for i in 1:size(dat,1)
        push!(interp,CubicSplineInterpolation(ts, dat[i,:]))
        for (i2, t) in enumerate(ts)
            dat_grad[i,i2] = Array(Interpolations.gradient(interp[i], t))[1]
        end
    end
    return dat_grad
end

export numerical_derivative


text:
using Base.Dates
using QuantLib

ts = FlatForwardTermStructure(settlement_date, bbIR.rate, bbIR.dc, bbIR.comp, bbIR.freq)

# Construct a 6 month euribor index
euribor6m = euribor_index(QuantLib.Time.TenorPeriod(Base.Dates.Month(6)))

# Construct a 3 month usd libor index
libor_3m = usd_libor_index(QuantLib.Time.TenorPeriod(Base.Dates.Month(3)), ts)

# test date calculations
fixing_date(euribor6m, Date(2016, 4, 3)) == Date(2016, 3, 31)
maturity_date(euribor6m, Date(2016, 4, 3)) == Date(2016, 10, 3)
QuantLib.value_date(euribor6m, Date(2016, 4, 3)) == Date(2016, 4, 5)

fixing_date(libor_3m, Date(2016, 4, 3)) == Date(2016, 3, 31)
maturity_date(libor_3m, Date(2016, 4, 3)) == Date(2016, 7, 5)
QuantLib.value_date(libor_3m, Date(2016, 4, 3)) == Date(2016, 4, 5)

# other calculations
fixing(euribor6m, ts, fixing_date(euribor6m, Date(2016, 4, 3))) == 0.0540983606557383
fixing(libor_3m, ts, fixing_date(libor_3m, Date(2016, 4, 3))) == 0.05343944335694899


text:
##################
# HomogenousTrie #
##################

struct HomogenousTrie{K,V} <: Assignment
    leaf_nodes::Dict{K,V}
    internal_nodes::Dict{K,HomogenousTrie{K,V}}
end

HomogenousTrie{K,V}() where {K,V} = HomogenousTrie(Dict{K,V}(), Dict{K,HomogenousTrie{K,V}}())

# copy constructor for something supported read-only trie interface
function HomogenousTrie(other)
    trie = HomogenousTrie{Any,Any}()
    for (key, value) in get_leaf_nodes(other)
        set_leaf_node!(trie, key, value)
    end
    for (key, node) in get_internal_nodes(other)
        sub_trie = HomogenousTrie(node)
        set_internal_node!(trie, key, sub_trie)
    end
    trie
end

# TODO come up with a better printing method (and something nice for Jupyter
# notebooks)
import JSON
Base.println(trie::HomogenousTrie) = JSON.print(trie, 4)

# invariant: all internal nodes are nonempty
Base.isempty(trie::HomogenousTrie) = isempty(trie.leaf_nodes) && isempty(trie.internal_nodes)
get_leaf_nodes(trie::HomogenousTrie) = trie.leaf_nodes
get_internal_nodes(trie::HomogenousTrie) = trie.internal_nodes

function Base.values(trie::HomogenousTrie)
    iterators = convert(Vector{Any}, collect(map(values, values(trie.internal_nodes))))
    push!(iterators, values(trie.leaf_nodes))
    Iterators.flatten(iterators)
end

function has_internal_node(trie::HomogenousTrie, addr)
    haskey(trie.internal_nodes, addr)
end

function get_internal_node(trie::HomogenousTrie, addr)
    trie.internal_nodes[addr]
end

function set_internal_node!(trie::HomogenousTrie{K,V}, addr, new_node::HomogenousTrie{K,V}) where {K,V}
    if !isempty(new_node)
        trie.internal_nodes[addr] = new_node
    end
end

function set_internal_node!(trie::HomogenousTrie{K,V}, addr::Pair, new_node::HomogenousTrie{K,V}) where {K,V}
    (first, rest) = addr
    if haskey(trie.internal_nodes, first)
        node = trie.internal_nodes[first]
    else
        node = HomogenousTrie{K,V}()
        trie.internal_nodes[first] = node
    end
    set_internal_node!(node, rest, new_node)
end

function delete_internal_node!(trie::HomogenousTrie, addr)
    delete!(trie.internal_nodes, addr)
    return isempty(trie.leaf_nodes) && isempty(trie.internal_nodes)
end

function delete_internal_node!(trie::HomogenousTrie, addr::Pair)
    (first, rest) = addr
    if haskey(trie.internal_nodes, first)
        node = trie.internal_nodes[first]
        if delete_internal_node!(node, rest, new_node)
            delete!(trie.internal_nodes, first)
        end
    end
    return isempty(trie.leaf_nodes) && isempty(trie.internal_nodes)
end

function has_leaf_node(trie::HomogenousTrie, addr)
    haskey(trie.leaf_nodes, addr)
end

function get_leaf_node(trie::HomogenousTrie, addr)
    trie.leaf_nodes[addr]
end

function set_leaf_node!(trie::HomogenousTrie, addr, value)
    trie.leaf_nodes[addr] = value
end

function set_leaf_node!(trie::HomogenousTrie{K,V}, addr::Pair, value) where {K,V}
    (first, rest) = addr
    if haskey(trie.internal_nodes, first)
        node = trie.internal_nodes[first]
    else
        node = HomogenousTrie{K,V}()
        trie.internal_nodes[first] = node
    end
    node = trie.internal_nodes[first]
    set_leaf_node!(node, rest, value)
end

function delete_leaf_node!(trie::HomogenousTrie, addr)
    delete!(trie.leaf_nodes, addr)
    return isempty(trie.leaf_nodes) && isempty(trie.internal_nodes)
end

function delete_leaf_node!(trie::HomogenousTrie, addr::Pair)
    (first, rest) = addr
    if haskey(trie.internal_nodes[first])
        node = trie.internal_nodes[first]
        if delete_leaf_node!(node, rest)
            delete!(trie.internal_nodes, first)
        end
    end
    return isempty(trie.leaf_nodes) && isempty(trie.internal_nodes)
end

Base.setindex!(trie::HomogenousTrie, value, addr) = set_leaf_node!(trie, addr, value)

function Base.merge!(a::HomogenousTrie{K,V}, b::HomogenousTrie{K,V}) where {K,V}
    merge!(a.leaf_nodes, b.leaf_nodes)
    for (key, a_sub) in a.sub
        if haskey(b.sub, key)
            b_sub = b.sub[key]
            merge!(a_sub, b_sub)
        end
    end
    for (key, b_sub) in b.sub
        if !haskey(a.sub, key)
            a.sub[key] = b_sub
        end
    end
    a
end

function Base.delete!(trie::HomogenousTrie, addrs::AddressSet)
    for key in get_leaf_nodes(addrs)
        delete_leaf_node!(trie, key)
        delete_internal_node!(trie, key)
    end
    for (key, addrs_node) in get_internal_nodes(addrs)
        if has_internal_node(trie, key)
            trie_node = get_internal_node(trie, key)
            if delete!(trie_node, addrs_node)
                delete!(trie.internal_nodes, key)
            end
        end
    end
    return isempty(trie)
end

get_address_schema(::HomogenousTrie) = DynamicSchema()

export HomogenousTrie
export set_internal_node!
export delete_internal_node!
export set_leaf_node!
export delete_leaf_node!

max_stars_repo_name: BoltzmannBrain/Gen

max_issues_repo_name: BoltzmannBrain/Gen

max_forks_repo_name: BoltzmannBrain/Gen


text:
# ---
# title: 1074. Number of Submatrices That Sum to Target
# id: problem1074
# author: Tian Jun
# date: 2020-10-31
# difficulty: Hard
# categories: Array, Dynamic Programming, Sliding Window
# link: <https://leetcode.com/problems/number-of-submatrices-that-sum-to-target/description/>
# hidden: true
# ---
#
# Given a `matrix` and a `target`, return the number of non-empty submatrices
# that sum to target.
#
# A submatrix `x1, y1, x2, y2` is the set of all cells `matrix[x][y]` with `x1
# <= x <= x2` and `y1 <= y <= y2`.
#
# Two submatrices `(x1, y1, x2, y2)` and `(x1', y1', x2', y2')` are different if
# they have some coordinate that is different: for example, if `x1 != x1'`.
#
#
#
# **Example 1:**
#
# ![](https://assets.leetcode.com/uploads/2020/09/02/mate1.jpg)
#
#
#
#     Input: matrix = [[0,1,0],[1,1,1],[0,1,0]], target = 0
#     Output: 4
#     Explanation: The four 1x1 submatrices that only contain 0.
#
#
# **Example 2:**
#
#
#
#     Input: matrix = [[1,-1],[-1,1]], target = 0
#     Output: 5
#     Explanation: The two 1x2 submatrices, plus the two 2x1 submatrices, plus the 2x2 submatrix.
#
#
# **Example 3:**
#
#
#
#     Input: matrix = [[904]], target = 0
#     Output: 0
#
#
#
#
# **Constraints:**
#
#   * `1 <= matrix.length <= 100`
#   * `1 <= matrix[0].length <= 100`
#   * `-1000 <= matrix[i] <= 1000`
#   * `-10^8 <= target <= 10^8`
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end


text:
struct nk_glfw_vertex
    position::NTuple{2,Cfloat}
    uv::NTuple{2,Cfloat}
    col::NTuple{4,nk_byte}
end

mutable struct nk_glfw_device
    cmds::Ptr{nk_buffer}
    null::nk_draw_null_texture
    vbo::GLuint
    vao::GLuint
    ebo::GLuint
    prog::GLuint
    vert_shdr::GLuint
    frag_shdr::GLuint
    attrib_pos::GLint
    attrib_uv::GLint
    attrib_col::GLint
    uniform_tex::GLint
    uniform_proj::GLint
    font_tex::Cint
    tex_ids::Vector{Cuint}
    tex_count::Int
    nk_glfw_device() = new()
end

mutable struct nk_glfw
    win::GLFW.Window
    width::Cint
    height::Cint
    display_width::Cint
    display_height::Cint
    ogl::nk_glfw_device
    ctx::Ptr{nk_context}
    atlas::Ptr{nk_font_atlas}
    fb_scale::nk_vec2
    text::Vector{Char}
    text_len::Cint
    scroll::nk_vec2
    last_button_click::Cdouble
    is_double_click_down::Bool
    double_click_pos::nk_vec2
    nk_glfw() = new()
end


text:
using FvCFD

# All file paths are relative to the repository's main directory, 'include' this script from there

### Freestream Conditions (Mach 3) ###
P = 1
T = 1
U = [ 3, 0, 0 ]

### Define the fluid ###
Cp = 2.5
R = 0.71428
gamma = 1.4
fluid = Fluid(Cp, R, gamma)

### Choose a mesh ###
meshPath = "test/OFforwardStepMesh"
# meshPath = "test/OFforwardStepFineMesh"
boundaryConditions = [ supersonicInletBoundary, [P, T, U...], zeroGradientBoundary, [], symmetryBoundary, [], symmetryBoundary, [], wallBoundary, [], emptyBoundary, [] ]

### Run ###
mesh = OpenFOAMMesh(meshPath)
cellPrimitives = initializeUniformSolution3D(mesh, P, T, U...)
solve(mesh, meshPath, cellPrimitives, boundaryConditions, ShuOsher, initDt=0.00000001, endTime=4, outputInterval=0.5, targetCFL=0.95, silent=false, restart=false, fluid=fluid)

max_stars_repo_name: henrystoldt/fvCFD


text:
using DifferentialEquations
using Plots
using Markdown

description = md"""

Solve the Pendulum System:
``dθ/dt = ω(t),``
``dω/dt = -(3/2)(g/l)sinθ + (3/ml²)M(t)``
for mass m, length l, and where t∈[0,10], u₀= [0.01, 0.0], and M(t) is an external torque

"""
display(description)

l = 1.0
m = 1.0
g = 9.81

function pendulum!(du, u, p, t)
    du[1] = u[2]
    du[2] = -3g/(2l)*sin(u[1]) + 3/(m*l^2)*p(t)  # here p is a function
end

θ₀ = 0.01
ω₀ = 0.0
u0 = [θ₀, ω₀]

tspan = (0.0, 10.0)

M = t->0.1sin(t)  # this is the external torque

prob = ODEProblem(pendulum!, u0, tspan, M)
sol = solve(prob)

# visualize the result
plot(sol, linewidth=2, xaxis="t", label=["θ [rad]" "ω [rad/s]"], layout=(2,1))

max_stars_repo_name: john-waczak/SciML-examples

max_issues_repo_name: john-waczak/SciML-examples

max_forks_repo_name: john-waczak/SciML-examples


text:
module Simulate_DamperMacro

using  Modia3D
import Modia3D.ModiaMath

# Damper
@forceElement Damper(; d=1.0) begin
    w   = ModiaMath.RealScalar("w",   causality=ModiaMath.Input,  numericType=ModiaMath.WR)
    tau = ModiaMath.RealScalar("tau", causality=ModiaMath.Output, numericType=ModiaMath.WR)
end
function Modia3D.computeTorque(damper::Damper, sim::ModiaMath.SimulationState)
  damper.tau.value = -damper.d*damper.w.value
end

# Pendulum
vmat1 = Modia3D.Material(color="LightBlue" , transparency=0.5)
vmat2 = Modia3D.Material(color="Red")

@assembly PendulumWithDamper(;Lx = 1.0, Ly=0.2*Lx, Lz=0.2*Lx, m=1.0) begin
   world  = Modia3D.Object3D(Modia3D.CoordinateSystem(0.5*Lx))

   # Pendulum
   body   = Modia3D.Object3D(Modia3D.Solid(Modia3D.SolidBeam(Lx,Ly,Lz), Modia3D.MassProperties(m=m), vmat1))
   frame1 = Modia3D.Object3D(body; r=[-Lx/2, 0.0, 0.0])
   cyl    = Modia3D.Object3D(frame1,Modia3D.Cylinder(Ly/2,1.2*Ly; material=vmat2))

   # Connect pendulum to world
   rev        = Modia3D.Revolute(world, frame1)

   d     = Damper(d=0.2)
   damper = Modia3D.AdaptorForceElementToFlange(w=d.w, tau=d.tau)
   Modia3D.connect(damper, rev)
end
pendulum = PendulumWithDamper(Lx=1.6, m=0.5, sceneOptions = Modia3D.SceneOptions(visualizeFrames=true, defaultFrameLength=0.3))
model    = Modia3D.SimulationModel( pendulum )
result   = ModiaMath.simulate!(model, stopTime=5.0, log=false, tolerance=1e-4)

ModiaMath.plot(result, ["rev.phi", "rev.w", "rev.a", "rev.tau"])

println("... success of Simulate_DamperMacro.jl!")
end


text:
abstract type AbstractMultiObjectiveCriterion end

struct MultiObjectiveUCB <: AbstractMultiObjectiveCriterion
    weights::Vector{Float64}
    c::Float64
end

q_value(q_vec::Array{Float64}, crit::AbstractMultiObjectiveCriterion) = dot(crit.weights, q_vec)

function select_best(crit::MultiObjectiveUCB, node::AbstractStateNode, rng::AbstractRNG)
    best_UCB = -Inf
    sanode = 0
    ltn = log(total_n(node))
    for child in children(node)
        n = node.tree.n[child]
        wq = q_value(node.tree.q[child], crit)
        if (ltn <= 0 && n == 0) || crit.c == 0.0
            UCB = wq
        else
            UCB = wq + crit.c*sqrt(ltn/n)
        end
        @assert !isnan(UCB) "UCB was NaN (wq=$wq, q_vec=$(node.tree.q[child]), c=$(crit.c), ltn=$ltn, n=$n)"
        @assert !isequal(UCB, -Inf)
        if UCB > best_UCB
            best_UCB = UCB
            sanode = child
        end
    end
    sanode
end

struct MultiObjective <: AbstractMultiObjectiveCriterion
    weights::Vector{Float64}
end
MultiObjective(crit::MultiObjectiveUCB) = MultiObjective(crit.weights)

function select_best(crit::MultiObjective, node::AbstractStateNode, rng::AbstractRNG)
    best_Q = -Inf
    sanode = 0
    for child in children(node)
        wq = q_value(node.tree.q[child], crit)
        if wq > best_Q
            best_Q = wq
            sanode = child
        end
    end
    sanode
end

struct MaxTries <: AbstractMultiObjectiveCriterion end

function select_best(crit::MaxTries, node::AbstractStateNode, rng::AbstractRNG)
    best_child = first(children(node))
    best_n = total_n(best_child)
    @assert !isnan(best_n)
    for child in children(node)[2:end]
        if total_n(child) >= best_n
            best_n = total_n(child)
            best_child = child
        end
    end
    return best_child
end


text:
import StatsBase:sample

"""
      ExperienceSampleModel <: AbstractSampleModel

Generate a turn sample based on previous experiences.
"""
mutable struct ExperienceSampleModel <: AbstractSampleModel
   experiences::Dict{Any, Dict{Any, NamedTuple{(:reward, :isdone, :nextstate), Tuple{Float64, Bool, Any}}}}
   sample_count::Int
   ExperienceSampleModel() = new(Dict{Any, Dict{Any, NamedTuple{(:reward, :isdone, :nextstate), Tuple{Float64, Bool, Any}}}}(), 0)
end

update!(m::ExperienceSampleModel, buffer, learner) = update!(m, buffer)

function update!(m::ExperienceSampleModel, buffer::EpisodeSARDBuffer)
   s, a, r, d, s′ = buffer.state[end-1], buffer.action[end-1], buffer.reward[end], buffer.isdone[end], buffer.state[end]
   if haskey(m.experiences, s)
         m.experiences[s][a] = (reward=r, isdone=d, nextstate=s′)
   else
         m.experiences[s] = Dict{Any, NamedTuple{(:reward, :isdone, :nextstate), Tuple{Float64, Bool, Any}}}(a => (reward=r, isdone=d, nextstate=s′))
   end
end

function sample(model::ExperienceSampleModel)
    s = rand(keys(model.experiences))
    a = rand(keys(model.experiences[s]))
    model.sample_count += 1
    s, a, model.experiences[s][a]...
end


text:
export spqr_basic

"""
    `x, stats, NT = spqr_basic(A, B, opts)`

SPQR_BASIC approximate basic solution to min(norm(B-A*x))
for a rank deficient matrix A.

This function returns an approximate basic solution to
      min || B - A x ||                     (1)
for rank deficient matrices A.

Optionally returns statistics including the numerical rank of the matrix A
for tolerance tol (i.e. the number of singular values > tol), and
an orthonormal basis for the numerical null space of A'.

The solution is approximate since the algorithm allows small perturbations in
A (columns of A may be changed by no more than opts.tol).

Input:
  A -- an m by n matrix
  B -- an m by p right hand side matrix
  opts (optional) -- type 'help spqr_rank_opts' for details.

Output:
  x -- this n by p matrix contains basic solutions to (1).  Each column of x
      has at most k nonzero entries where k is the approximate numerical rank
      returned by spqr.  The magnitude of x(:,j) is bounded by
      norm(B[:,j])/s, where s = stats.est_sval_lower_bounds(nlarge_svals) is
      an estimated lower bound on (stats.rank)th singular value of A.
  stats -- statistics, type 'help spqr_rank_stats' for details.
  NT -- orthonormal basis for numerical null space of A'.
"""
function spqr_basic(A::AbstractMatrix{T}, B::AbstractMatrix{T};
                    nargout=3, opts...) where T <: Number
#=
Example:

    A = sparse(gallery('kahan',100))
    B = randn(100,1); B = B / norm(B)
    x = spqr_basic(A,B)
    norm_x = norm(x)
    # note compare with
    x2 = spqr_solve(A,B)
    norm_x2 = norm(x2)
    # or
    [x,stats,NT]=spqr_basic(A,B)
    norm_NT_transpose_times_A = norm(full(spqr_null_mult(NT,A,0)))
    # or
    opts = struct('tol',1.e-5)
    [x,stats,NT]=spqr_basic(A,B,opts)
    stats

See also spqr_cod, spqr_null, spqr_pinv, spqr_ssi, spqr_ssp

Copyright 2012, Leslie Foster and Timothy A Davis.

Algorithm:  First spqr is used to construct a QR factorization of the
   m by n matrix A: A*P1 = Q1*R where R' = [ R1' 0 ] + E1, R1 is a
   k by n upper trapezoidal matrix and E1 is a small error matrix.
   Let R11 be the leading k by k submatrix of R1. Subspace iteration,
   using the routine spqr_ssi,  is applied to R11 to determine if the rank
   returned by spqr is correct and also, often, to determine the correct
   numerical rank.  If k is the correct then the basic solution is
   x = R11 \ ch where ch is the first k entries in Q1'*B. If k is not
   the correct numerical rank, deflation (see SIAM SISC, 11:519-530,
   1990) is used in the calculation of a basic solution.
=#
#-------------------------------------------------------------------------------
# get opts: tolerance and number of singular values to estimate
#-------------------------------------------------------------------------------

start_tic = time_ns()

# get the options
opts, get_details, nsvals_small, nsvals_large = get_opts(opts, :get_details, :nsvals_small, :nsvals_large)
opts, tol, normest_A = get_tol_norm(opts, A)
stats = Statistics(real(T))

# order for the additional stats fields for case where get_details is 1 will be
#     set using spqr_rank_order_fields, called from spqr_rank_assign_stats

if get_details == 1
    stats.time_basis = 0
end

m, n = size(A)

#-------------------------------------------------------------------------------
# QR factorization of A, and initial estimate of numerical rank, via spqr
#-------------------------------------------------------------------------------

# compute Q * R = A[prow,pcol] and C = Q' * B.
Q, R, C, prow, pcol, info_spqr = spqr_wrapper(A, B, tol, get_details)

# the next line is equivalent to: rank_spqr = size(R,1)
rank_spqr = info_spqr.rank_A_estimate
norm_E_fro = info_spqr.norm_E_fro

# save the stats
if get_details == 1 || get_details == 2
    stats.rank_spqr = rank_spqr
    if get_details == 1
        stats.info_spqr = info_spqr
    end
end

#-------------------------------------------------------------------------------
# use spqr_ssi to check and adjust numerical rank from spqr
#-------------------------------------------------------------------------------

R11 = view(R, :, 1:rank_spqr) # should be square matrix!
get_details2 = get_details == 0 ? 2 : get_details
U, S, V, stats_ssi = spqr_ssi(R11; opts..., get_details=get_details2)

if get_details == 1 || get_details == 2
    stats.stats_ssi = stats_ssi
    if get_details == 1
        stats.time_svd = stats_ssi.time_svd
    end
end

#-------------------------------------------------------------------------------
# check for early return
#-------------------------------------------------------------------------------

if stats_ssi.flag == 4
    # overflow occurred during the inverse power method in ssi
    stats, x, NT = spqr_failure(4, stats, get_details, start_tic)
    return x, stats, NT
end

#-------------------------------------------------------------------------------
# Estimate lower bounds on the singular values of A
#-------------------------------------------------------------------------------

# In spqr the leading rank_spqr column of A*P are unmodified. Therefore
# by the interleave theorem for singular values the singular values of
# R11 = R[:,1:rank_spqr] are lower bounds for the singular
# values of A.  In spqr_ssi estimates for the errors in calculating the
# singular values of R are in stats_ssi.est_error_bounds.  Therefore,
# for i = 1:k, where S is k by k, estimated lower bounds on singular
# values number (rank_spqr - k + i) of A are in est_sval_lower_bounds:
#
# lower bounds on the remaining singular values of A are zero
est_sval_lower_bounds = fill(real(T)(0), length(S)+min(m,n)-rank_spqr)
copyto!(est_sval_lower_bounds, max.(S - stats_ssi.est_error_bounds, 0))

numerical_rank = stats_ssi.rank

## println("basic: rank spqr: $rank_spqr numerical: $numerical_rank ssimaxblock: $(stats_ssi.ssi_max_block_used)")
## println("basic: before: nsvals large: $nsvals_large small: $nsvals_small")
# limit nsvals_small and nsvals_large due to number of singular values
#     available and calculated by spqr_ssi
nsvals_small = min(nsvals_small, min(m,n) - numerical_rank)

nsvals_large = min(nsvals_large, rank_spqr, numerical_rank)
nsvals_large = min(nsvals_large, numerical_rank - rank_spqr + stats_ssi.ssi_max_block_used)

# return nsvals_large + nsvals_small of the estimates
resize!(est_sval_lower_bounds, nsvals_large+nsvals_small)
## println("basic: after: nsvals large: $nsvals_large small: $nsvals_small")

#-------------------------------------------------------------------------------
# Estimate upper bounds on the singular values of A
#-------------------------------------------------------------------------------

# By the minimax theorem for singular values, for any rank_spqr by k
# matrix U with orthonormal columns, for i = 1:k singular value i
# of U'*R is an upper bound on singular values rank_spqr - k + i of
# the rank_spqr by n matrix R.  Therefore we have upper bounds on the
# singular values number rank_spqr - k + i, i = 1:k, of R:

get_details == 1 && ( t = time_ns() )
s = svd(R' * U).S # Note: because U is dense, R' * U is dense for sparse R
get_details == 1 && ( stats.time_svd += time_ns() - t )

# Since the Frobenius norm of A*P - Q*R is norm_E_fro, the singular
# values of A and R differ by at most norm_E_fro.  Therefore we have
# the following upper bounds on the singular values of A:

# upper bounds on the remaining singular values of A are norm_E_fro
est_sval_upper_bounds = fill(norm_E_fro, length(S)+min(m,n)-rank_spqr)
copyto!(est_sval_upper_bounds, s .+ norm_E_fro)

# return nsvals_large + nsvals_small components of the estimates
resize!(est_sval_lower_bounds, nsvals_large+nsvals_small)

# restrict columns of U and V to the small singular values
nu = size(U, 2)
@assert nu >= nsvals_large "$nu >= $nsvals_large"
U0 = view(U, :, nsvals_large+1:nu)
V0 = view(V, :, nsvals_large+1:nu)

#-------------------------------------------------------------------------------
# if requested, calculate orthonormal basis for null space of A'
#-------------------------------------------------------------------------------

NT = []
if nargout == 3
    NT, stats, stats_ssp_NT, est_sval_upper_bounds =
        spqr_rank_form_basis(1, A, U0, V0, Q, prow, rank_spqr, numerical_rank,
                             stats, opts, est_sval_upper_bounds,
                             nsvals_small, nsvals_large)

    stats.est_err_bound_norm_A_transpose_times_NT = stats_ssp_NT.est_error_bounds[1]
end

#-------------------------------------------------------------------------------
# find solution R11 * wh = ch where R11 = R[:,1:rank_spqr]
#-------------------------------------------------------------------------------

R = view(R, :, 1:rank_spqr)   # discard R12, keep R11 only
x = spqr_rank_deflation(1, R, U0, V0, C, m, n, rank_spqr, numerical_rank, prow, pcol, Q;
                        opts..., nsvals_large=nsvals_large)

#-------------------------------------------------------------------------------
# determine flag which indicates accuracy of the estimated numerical rank
#    and return statistics
#-------------------------------------------------------------------------------

call_from = 1
stats_ssp_N = missing
if nargout < 3
    stats_ssp_NT = [ ]
end
#(call_from, est_sval_upper_bounds, est_sval_lower_bounds, tol, numerical_rank, nsvals_small, nsvals_large, stats, stats_ssi, opts, nargout, stats_ssp_N, stats_ssp_NT, start_tic)
stats.est_sval_upper_bounds = est_sval_upper_bounds
stats.est_sval_lower_bounds = est_sval_lower_bounds
stats.tol = tol
stats.rank = numerical_rank
stats.stats_ssi = stats_ssi
stats.opts_used = opts.data
stats.stats_ssp_N = stats_ssp_N
stats.stats_ssp_NT = stats_ssp_NT
stats.time = time_ns() - start_tic

return x, stats, NT
end


text:
# License for this file: MIT (expat)
# Copyright 2017-2018, DLR Institute of System Dynamics and Control
#
# This file is part of module
#   Modia3D.Composition (Modia3D/Composition/_module.jl)
#

# mutable struct of FreeMotion is defined in Modia3D/src/Composition/joints/object3DMotion.jl,
# since Object3D references FreeMotion and FreeMotion references Object3D

"""
    [angle1 angle2 angle3] = rot123fromR(R::Frames.RotationMatrix)

Return Cardan angles (rotation sequence x-y-z) from RotationMatrix `R`.
In case of singular state (angle2 +-90 deg, x and z axes parallel) `rot3_guess` defines angle3.
"""
function rot123fromR(R::Frames.RotationMatrix; rot3_guess=0.0)

    sbe = R[3,1]
    cbe2 = 1.0 - sbe*sbe
    if (cbe2 > 1e-12)
        al = atan(-R[3,2], R[3,3])
        be = atan(sbe/sqrt(cbe2))
        ga = atan(-R[2,1], R[1,1])
    else
        # be is 90 deg -> singular, only al+ga is defined -> set ga to zero
        al = atan(R[2,3], R[2,2]) - sign(sbe)*rot3_guess  # ???
        be = sign(sbe)*0.5*pi
        ga = rot3_guess
    end
    return [al, be, ga]

end

"""
    [angle1 angle2 angle3] = rot132fromR(R::Frames.RotationMatrix)

Return Cardan angles (rotation sequence x-z-y) from RotationMatrix `R`.
In case of singular state (angle2 +-90 deg, x and y axes parallel) `rot3_guess` defines angle3.
"""
function rot132fromR(R::Frames.RotationMatrix; rot3_guess=0.0)

    sga = - R[2,1]
    cga2 = 1.0 - sga*sga
    if (cga2 > 1e-12)
        al = atan(R[2,3], R[2,2])
        ga = atan(sga/sqrt(cga2))
        be = atan(R[3,1], R[1,1])
    else
        # ga is 90 deg -> singular, only al+be is defined -> set be to rot3_guess
        al = atan(-R[3,2], R[3,3]) - sign(sga)*rot3_guess  # ???
        ga = sign(sga)*0.5*pi
        be = rot3_guess
    end
    return [al, ga, be]

end

"""
    w = wfromrot132(rot132::AbstractVector, derrot132::AbstractVector)

Return relative rotational velocity Vector3D `w` from frame `1` to frame `2` resolved in frame `2`.

`rot132` are the Cardan angles (rotation sequence x-z-y) of rotation from frame `1` to frame `2`.
`derrot132` are the time derivatives of `rot132`.
"""
function wfromrot132(rot132::AbstractVector, derrot132::AbstractVector)

    (sga, cga) = sincos(rot132[2])
    (sbe, cbe) = sincos(rot132[3])
    return @SVector[ cbe*cga*derrot132[1] - sbe*derrot132[2]                ,
                        -sga*derrot132[1]                    + derrot132[3] ,
                     sbe*cga*derrot132[1] - cbe*derrot132[2]                ]

end


text:
import .Classification: fit!
using .Classification: SGDContext, StochasticGradientDescent
using  .NeuralNetwork: NeuralNet, backpropagation, evaluate!

function fit!(net::NeuralNet, context::SGDContext, X, y, labels)
    optim = StochasticGradientDescent(context)
    res = fit!(net, optim, X, y, labels)
    optim
end

function fit!(net::NeuralNet, optim::StochasticGradientDescent,
              X::Matrix{<:Real}, y::Matrix{<:Real}, labels)
    weave!(net, X, y)
    numsamples = size(X, 2)
    optim.loss = zeros(Float32, optim.context.maxiterations)
    batchsize = optim.context.batchsize
    if numsamples % batchsize != 0
        @warn "The minibatch size does not divide number of samples. Leftover $(numsamples%batchsize) dropped"
    end

    partitions = partition(numsamples, batchsize)
    for epoch in 1:optim.context.maxiterations
        shuffle!(X, y, labels)
        for batch in partitions
            minibatch!(net, optim, X, y, batch)
        end
        optim.iterations += 1
        evaluate!(net, optim, X, labels)
    end
end

function minibatch!(net::NeuralNet, optim::StochasticGradientDescent, X, y, batch)
    ∇b = [zeros(Float32, size(layer.b)) for layer in net.layers]
    ∇W = [zeros(Float32, size(layer.W)) for layer in net.layers]
    for i in batch
        Δ∇b, Δ∇W = backpropagation(net, X[:, i], y[:, i])
        ∇b .+= Δ∇b
        ∇W .+= Δ∇W
    end
    η = optim.context.learningrate
    B = length(batch)
    for (layer, ∂b, ∂W) in zip(net.layers, ∇b, ∇W)
        layer.b .-= η./B .* ∂b
        layer.W .-= η./B .* ∂W
    end
end

function shuffle!(X::Matrix{<:Real}, y::Matrix{<:Real})
    n = size(X, 2)
    j = 0
    for i in n:-1:2
        @fastmath j = 1 + abs(rand(Int))%n
        swapcols!(X, i, j)
        swapcols!(y, i, j)
    end
end

function shuffle!(X::Matrix{<:Real}, y::Matrix{<:Real}, z)
    n = size(X, 2)
    j = 0
    for i in n:-1:2
        @fastmath j = 1 + abs(rand(Int))%n
        swapcols!(X, i, j)
        swapcols!(y, i, j)
        swapcols!(z, i, j)
    end
end

function swapcols!(X, i, j)
    for k in 1:size(X, 1)
        X[k, i], X[k, j] = X[k, j], X[k, i]
    end
end


text:
using GARCH
using Pkg, Test, DelimitedFiles, Statistics

filename = Pkg.dir("GARCH", "test", "data", "price.csv")
price = Array{Float64}(readdlm(filename, ',')[:,2])

ret = diff(log.(price))
ret = ret .- mean(ret)
fit = garchFit(ret)

param = [2.469347e-06, 1.142268e-01, 8.691734e-01] #R fGarch garch(1,1) estimated params

@test fit.params ≈ param atol=1e-3
@test predict(fit) ≈ 0.005617744 atol = 1e-4
@test predict(fit, 2) ≈ [0.005617744, 0.005788309] atol = 1e-4


text:
using Pkg
Pkg.activate(pwd())

# # DataFrames.jl

using DataFrames

df = DataFrame(A = 1:4, B = ["M", "F", "F", "M"], C = rand(4))

#+

df.A

#+

df[!, :A]

#+

df.A[1] = 5
df

#+

col = df[:, :A]
col[1] = 4
df

#+

using CSV

CSV.write(joinpath(pwd(), "lecture_05", "dataframe.csv"), df)
table = CSV.read(joinpath(pwd(), "lecture_05", "dataframe.csv"), DataFrame; header = true)

#+

df.D = [:a, :b, :c, :d]
df

#+

insertcols!(df, 3, :B => rand(4), :B => 11:14; makeunique = true)
push!(df, [10, "F", 0.1, 15, 0.235, :f])
push!(df, (10, "F", 0.1, 15, 0.235, :f))
push!(df, Dict(:B_1 => 0.1, :B_2 => 15, :A => 10, :D => :f, :B => "F", :C => 0.235))
df

#+

df_empty = DataFrame()
df_empty.A = 1:3
df_empty.B = [:a, :b, :c]
df_empty

#+

df_empty = DataFrame(A = Int[], B = Symbol[])
push!(df_empty, [1, :a])
push!(df_empty, (2, :b))
push!(df_empty, Dict(:A => 3, :B => :c))
df_empty

# ## Renaming

names(df)

#+

propertynames(df)

#+

rename!(df, [:a, :b, :c, :d, :e, :f])
df

#+
rename!(df, :a => :A, :f => :F)
df

#+

myname(x) = string("column_", uppercase(x))
rename!(myname, df)
df

# ## Working with `DataFrame`s

using RDatasets, DataFrames

iris = dataset("datasets", "iris")
first(iris, 6)

#+

describe(iris)

#+

iris[2:4, [:SepalLength, :Species]]

#+

iris[2:4, Not([:SepalLength, :Species])]

#+

using Query

table = @from row in iris begin
    @where row.SepalLength >= 6 && row.SepalWidth >= 3.4
    @select {
        row.Species,
        SepalSum = row.SepalLength + row.SepalWidth,
        PetalSum = row.PetalLength + row.PetalWidth,
    }
    @collect DataFrame
end

# ## Visualizing using StatsPlots

using StatsPlots

@df iris scatter(
    :SepalLength,
    :SepalWidth;
    group = :Species,
    xlabel = "SepalLength",
    ylabel = "SepalWidth",
    marker = ([:d :h :star7], 8),
)

#+

@df iris marginalkde(
    :SepalLength,
    :SepalWidth;
    xlabel = "SepalLength",
    ylabel = "SepalWidth",
)

@df iris corrplot(
    cols(1:4);
    grid = false,
    nbins = 15,
    fillcolor = :viridis,
    markercolor = :viridis,
)


text:
module Graph2OpCode

import Basic.push!

function push!{C}(ins::Vector{Instruction{C}}, s::Sequence{C})
    for p in s.patterns
        push!(ins, p)
    end
end

function push!{C}(ins::Vector{Instruction{C}}, r::Range{C})
    if r.lo == r.hi
        push!(ins, Instruction{C}(EQ, 0, r.lo))
    else
        push!(ins, Instruction{C}(GE, 0, r.lo))
        push!(ins, Instruction{C}(LE, 0, r.hi))
    end
end

function push!{C}(ins::Vector{Instruction{C}}, c::Choice{C})
    jlast = length(c.patterns)
    for (j, p) in enumerate(c.patterns)
        if j != jlast
            i = Instruction{C}(ALT, 0, zero(C))
            push!(ins, p)
            i.n = length(ins) + 1
        else
            push!(ins, p)
        end
    end
end

function push!{C}(ins::Vector{Instruction{C}}, r::Repeat{C})

end

end


text:
using LocalRegistry
using LocalRegistry: find_package_path, find_registry_path
using Test
using Random
using Pkg

const TEST_GITCONFIG = Dict(
    "user.name" => "LocalRegistryTests",
    "user.email" => "localregistrytests@example.com",
)

include("utils.jl")

# Since these tests will need to modify active registries and we don't
# want interference from, e.g. the General registry, use a temporary
# DEPOT_PATH. But first add some packages while we have the General
# registry available. These will be used for some tests later.
pkg"add AutoHashEquals"
pkg"dev --local Multibreak"
empty!(DEPOT_PATH)
depot_path = mktempdir(@__DIR__)
push!(DEPOT_PATH, depot_path)

# We don't want Pkg to try to update our local registries since they
# contain fake URLs.
Pkg.UPDATED_REGISTRY_THIS_SESSION[] = true

# The following tests are primarily regression tests - checking that
# the results are the same as when the tests were written, regardless
# of correctness.
#
# The general strategy is that a number of project files have been
# stored. These are read and expanded to minimal stub packages, which
# are then registered in a newly created registry. The resulting
# registries after some selections of packages have been added have
# also been stored and are compared against.
#
# The project files have been extracted from the git history of the
# Flux and Images packages. The patch numbers have been faked to get
# more version samples out of their git histories. The FirstTest1
# project file is derived from this package.

# Set up packages and registry directories in a temporary location.
if VERSION >= v"1.2"
    testdir = mktempdir(prefix = "LocalRegistryTests")
else
    testdir = mktempdir()
end
packages_dir = joinpath(testdir, "packages")
if packages_dir ∉ LOAD_PATH
    push!(LOAD_PATH, packages_dir)
end
registry_dir = joinpath(testdir, "TestRegistry")

# Create a new registry.
create_registry(registry_dir, "git@example.com:Julia/TestRegistry.git",
                description = "For testing purposes only.",
                uuid = "ed6ca2f6-392d-11ea-3224-d3daf7fee369",
                gitconfig = TEST_GITCONFIG, push = false)

# Add the FirstTest1 package and check against the stored `registry1`.
prepare_package(packages_dir, "FirstTest1.toml")
using FirstTest
register(FirstTest, registry_dir, gitconfig = TEST_GITCONFIG, push = false)
@test check_result(registry_dir, "registry1")

# Reregister the same version of FirstTest to verify that nothing
# happens,
@test_logs (:info, "This version has already been registered and is unchanged.") register(FirstTest, registry_dir, gitconfig = TEST_GITCONFIG, push = false)
@test check_result(registry_dir, "registry1")

# Add 29 versions of the Flux project files and check against `registry2`.
for n = 1:29
    prepare_package(packages_dir, "Flux$(n).toml")
    using Flux
    register(Flux, registry_dir, gitconfig = TEST_GITCONFIG, push = false)
end
@test check_result(registry_dir, "registry2")

# Add 15 versions of the Images project files and check against `registry3`.
for n = 1:15
    prepare_package(packages_dir, "Images$(n).toml")
    using Images
    register(Images, registry_dir, gitconfig = TEST_GITCONFIG, push = false)
end
@test check_result(registry_dir, "registry3")

# Start over with a fresh registry and add all 46 project files but in
# shuffled order. Check that this also matches `registry3`.
registry_dir = joinpath(testdir, "test2", "TestRegistry")
create_registry(registry_dir, "git@example.com:Julia/TestRegistry.git",
                description = "For testing purposes only.",
                uuid = "ed6ca2f6-392d-11ea-3224-d3daf7fee369",
                gitconfig = TEST_GITCONFIG, push = false)
project_files = vcat("FirstTest1.toml",
                     ["Flux$(n).toml" for n = 1:29],
                     ["Images$(n).toml" for n = 1:15])
Random.seed!(13)
shuffle!(project_files)
for project_file in project_files
    prepare_package(packages_dir, project_file)
    package = match(r"[a-zA-Z]+", project_file).match
    # Register by path instead of module in this test.
    register(joinpath(packages_dir, package), registry_dir,
             gitconfig = TEST_GITCONFIG, push = false)
end
@test check_result(registry_dir, "registry3")

# Trying to register an already existing version with different content.
prepare_package(packages_dir, "Flux30.toml")
@test_throws ErrorException register(joinpath(packages_dir, "Flux"),
                                     registry_dir, gitconfig = TEST_GITCONFIG,
                                     push = false)

# Parse error in compat section.
prepare_package(packages_dir, "Broken1.toml")
if VERSION < v"1.2"
    @test_throws ErrorException register(joinpath(packages_dir, "Broken"),
                                         registry_dir,
                                         gitconfig = TEST_GITCONFIG,
                                         push = false)
else
    @test_throws Pkg.Types.PkgError register(joinpath(packages_dir, "Broken"),
                                             registry_dir,
                                             gitconfig = TEST_GITCONFIG,
                                             push = false)
end
# Trying to change name (UUID remains).
prepare_package(packages_dir, "Fluxx1.toml")
@test_throws ErrorException register(joinpath(packages_dir, "Fluxx"),
                                     registry_dir, gitconfig = TEST_GITCONFIG,
                                     push = false)

# Trying to change UUID.
prepare_package(packages_dir, "Flux31.toml")
@test_throws ErrorException register(joinpath(packages_dir, "Flux"),
                                     registry_dir, gitconfig = TEST_GITCONFIG,
                                     push = false)

# Depends on itself.
prepare_package(packages_dir, "Broken2.toml")
@test_throws ErrorException register(joinpath(packages_dir, "Broken"),
                                     registry_dir, gitconfig = TEST_GITCONFIG,
                                     push = false)

# Incorrect name of dependency.
prepare_package(packages_dir, "Broken3.toml")
@test_throws ErrorException register(joinpath(packages_dir, "Broken"),
                                     registry_dir, gitconfig = TEST_GITCONFIG,
                                     push = false)

# TODO: This should really be an error but RegistryTools 1.3.0 doesn't catch it.
# Incorrect UUID of dependency.
prepare_package(packages_dir, "Broken4.toml")
register(joinpath(packages_dir, "Broken"), registry_dir,
         gitconfig = TEST_GITCONFIG, push = false)

# Incorrect UUID of stdlib.
prepare_package(packages_dir, "Broken5.toml")
@test_throws ErrorException register(joinpath(packages_dir, "Broken"),
                                     registry_dir, gitconfig = TEST_GITCONFIG,
                                     push = false)

# Change the git remote before registration and verify that the
# registered repo is not changed.
prepare_package(packages_dir, "Flux32.toml")
package_dir = joinpath(packages_dir, "Flux")
git = gitcmd(package_dir, TEST_GITCONFIG)
package_file = joinpath(registry_dir, "F", "Flux", "Package.toml")
old_repo = TOML.parsefile(package_file)["repo"]
new_repo = "https://example.com/Julia/Flux.jl.git"
run(`$git remote set-url origin $(new_repo)`)
register(joinpath(packages_dir, "Flux"), registry_dir,
         gitconfig = TEST_GITCONFIG, push = false)
@test TOML.parsefile(package_file)["repo"] == old_repo

# Register with explicit repo argument and verify that the registered
# repo is updated.
prepare_package(packages_dir, "Flux33.toml")
register(joinpath(packages_dir, "Flux"), registry_dir, repo = new_repo,
         gitconfig = TEST_GITCONFIG, push = false)
@test TOML.parsefile(package_file)["repo"] == new_repo

pop!(LOAD_PATH)

# Register a package in a subdirectory of a git repository. Also add
# some dirt outside the subdirectory to verify that it is ignored.
prepare_package(packages_dir, "SubdirTest1.toml", "subdir")
write(joinpath(packages_dir, "SubdirTest", "README.md"), "dirty")
register(joinpath(packages_dir, "SubdirTest", "subdir"), registry_dir,
         gitconfig = TEST_GITCONFIG, push = false)
package_file = joinpath(registry_dir, "S", "SubdirTest", "Package.toml")
@test TOML.parsefile(package_file)["subdir"] == "subdir"

# Register a package with a JuliaProject.toml rather than a Project.toml.
prepare_package(packages_dir, "JuliaProjectTest1.toml",
                use_julia_project = true)
register(joinpath(packages_dir, "JuliaProjectTest"), registry_dir,
         gitconfig = TEST_GITCONFIG, push = false)
@test isfile(joinpath(registry_dir, "J", "JuliaProjectTest", "Package.toml"))

# Test automatic push functionality. The sequence of events is:
# 1. Create a bare "upstream" repository.
# 2. Create a new registry with the upstream as repo and `push = true`.
# 3. Register a package with `push = true`.
# 4. Verify that the registry and the upstream repo has the same two commits.
upstream_dir = joinpath(testdir, "upstream")
mkpath(upstream_dir)
upstream_git = gitcmd(upstream_dir, TEST_GITCONFIG)
run(`$(upstream_git) init --bare`)
registry_push_dir = joinpath(testdir, "TestRegistryPush")
create_registry(registry_push_dir, "file://$(upstream_dir)", push = true,
                gitconfig = TEST_GITCONFIG)
downstream_git = gitcmd(registry_push_dir, TEST_GITCONFIG)
register(joinpath(packages_dir, "FirstTest"), registry_push_dir,
         push = true, gitconfig = TEST_GITCONFIG)
@test readchomp(`$(downstream_git) log`) == readchomp(`$(upstream_git) log`)
@test length(readlines(`$(upstream_git) log --format=oneline`)) == 2

# Additional tests of `find_package_path` and `find_registry_path`.
# Many of these have the purpose to cover error cases, making them
# somewhat contrived. Another complicating factor is that some of the
# call variants have to interact with the package environment,
# including registries, of the running Julia process.

# Prepare by adding the registry used in previous tests.
Pkg.Registry.add(RegistrySpec(path = registry_dir))

# Use Multibreak as Guinea pig. The sleep is a Travis workaround. See
# a later comment.
sleep(1)
register("Multibreak", "TestRegistry",
         push = false, gitconfig = TEST_GITCONFIG)

# Directory already exists. Also tests code handling a trailing slash.
create_registry("TestRegistry2", "", gitconfig = TEST_GITCONFIG, push = false)
@test_throws ErrorException create_registry("TestRegistry2/", "",
                                            gitconfig = TEST_GITCONFIG,
                                            push = false)

# Not a developed package.
@test_throws ErrorException find_package_path("AutoHashEquals")

# Not a registered package.
pkg = Pkg.Types.Project(Dict("name" => "UUIDs",
                             "uuid" => "cf7118a7-6976-5b1a-9a39-7adc72f591a4"))
@test_throws ErrorException find_registry_path(nothing, pkg)

# Find package by module and path.
using Multibreak
package_path = find_package_path(Multibreak)
@test find_package_path(package_path) == package_path

# Find package by name.
if !Base.Sys.isapple()
    @test find_package_path("Multibreak") == package_path
else
    # Workaround a Travis macOS failure where presumably the same path
    # is obtained but prefixed by `/private`.
    @test occursin(package_path, find_package_path("Multibreak"))
end

# Not a package path.
corrupt_path = joinpath(package_path, "no_such_dir")
@test_throws ErrorException find_package_path(corrupt_path)

# Unknown package.
@test_throws ErrorException find_package_path("ZeroethTest")

# Find a registry by name.
pkg = Pkg.Types.read_project(joinpath(package_path, "Project.toml"))
@test find_registry_path("TestRegistry") == joinpath(first(DEPOT_PATH),
                                                     "registries",
                                                     "TestRegistry")

# The named registry does not exist.
@test_throws ErrorException find_registry_path("General", pkg)

# Find which registry contains a package.
@test find_registry_path(nothing, pkg) == joinpath(first(DEPOT_PATH),
                                                   "registries", "TestRegistry")

# Workaround for bad `mtime` resolution of 1 second on MacOS workers
# on Travis.
#
# The issue is that `read_registry` caches its results with respect to
# the file `mtime`. Since `read_registry` is called from within
# `register`, the old data will be read into the cache. If the new
# data is written close enough to the previous registry update so that
# `mtime` does not change, subsequent `read_registry` will keep using
# the old data from the cache.
sleep(1)

# More than one registry contains the package.
register("Multibreak", "TestRegistry2",
         repo = "file://$(packages_dir)/FirstTest",
         gitconfig = TEST_GITCONFIG, push = false)
@test_throws ErrorException find_registry_path(nothing, pkg)

# Dirty the registry repository and try to register a package.
registry_path = find_registry_path("TestRegistry2")
filename = joinpath(registry_path, "Registry.toml")
open(filename, "a") do io
    write(io, "\n")
end
@test_throws ErrorException register("Multibreak", "TestRegistry2",
                                     gitconfig = TEST_GITCONFIG, push = false)

# Dirty the package repository and try to register the package.
package_path = find_package_path("Multibreak")
filename = joinpath(package_path, "README.md")
open(filename, "a") do io
    write(io, "\n")
end
@test_throws ErrorException register("Multibreak", "TestRegistry2",
                                     gitconfig = TEST_GITCONFIG, push = false)

# Remove Project.toml from a package and try to register.
mv(joinpath(package_path, "Project.toml"),
   joinpath(package_path, "Project.txt"))
@test_throws ErrorException register("Multibreak", "TestRegistry2",
                                     gitconfig = TEST_GITCONFIG, push = false)
mv(joinpath(package_path, "Project.txt"),
   joinpath(package_path, "Project.toml"))

if VERSION < v"1.2"
    rm(depot_path, recursive = true)
end


text:
# ------------------------------------------------------------------
# Licensed under the ISC License. See LICENSE in the project root.
# ------------------------------------------------------------------

"""
    AbstractLearningTask

A statistical learning task (e.g. regression, clustering)
"""
abstract type AbstractLearningTask end

"""
    inputvars(task)

Return the input variables of learning `task`.
"""
inputvars(task::AbstractLearningTask) = features(task)

"""
    outputvars(task)

Return the output variables of learning `task`.
"""
outputvars(task::AbstractLearningTask) = (label(task),)

"""
    issupervised(task)

Check whether or not `task` is supervised.
"""
issupervised(task::AbstractLearningTask) = false

# ----------------
# IMPLEMENTATIONS
# ----------------
include("tasks/regression.jl")
include("tasks/classification.jl")
include("tasks/clustering.jl")


text:
function adjacency2modularity(A)

    degree_vector = sum(A,2)

    total_edges = sum(degree_vector)

    # purposeful typo to force throwing error
    B = A - degree_vector*degree_vector'/totla_edges
    return B
end


text:
# Use baremodule to shave off a few KB from the serialized `.ji` file
baremodule cmocka_jll
using Base
using Base: UUID
import JLLWrappers

JLLWrappers.@generate_main_file_header("cmocka")
JLLWrappers.@generate_main_file("cmocka", UUID("f83fd561-6387-5ecc-9835-b38c8eaffb11"))
end  # module cmocka_jll


text:
begin
    local b = fromfen("2r2k2/1P6/8/8/p7/2N3N1/8/R3K2R w KQ -")
    @test movefromsan(b, "b8=Q") == Move(SQ_B7, SQ_B8, QUEEN)
    @test movetosan(b, Move(SQ_B7, SQ_B8, QUEEN)) == "b8=Q"
    @test movefromsan(b, "bxc8=R+") == Move(SQ_B7, SQ_C8, ROOK)
    @test movetosan(b, Move(SQ_B7, SQ_C8, ROOK)) == "bxc8=R+"
    @test movefromsan(b, "Nxa4") == Move(SQ_C3, SQ_A4)
    @test movetosan(b, Move(SQ_C3, SQ_A4)) == "Nxa4"
    @test movefromsan(b, "Nge4") == Move(SQ_G3, SQ_E4)
    @test movetosan(b, Move(SQ_G3, SQ_E4)) == "Nge4"
    @test movefromsan(b, "Nce4") == Move(SQ_C3, SQ_E4)
    @test movetosan(b, Move(SQ_C3, SQ_E4)) == "Nce4"
    @test isnothing(movefromsan(b, "Ne4"))
    @test movefromsan(b, "O-O-O") == Move(SQ_E1, SQ_C1)
    @test movetosan(b, Move(SQ_E1, SQ_C1)) == "O-O-O"
    @test movefromsan(b, "O-O+") == Move(SQ_E1, SQ_G1)
    @test movetosan(b, Move(SQ_E1, SQ_G1)) == "O-O+"

    b = fromfen("2r2k2/1P6/8/8/pb6/2N3N1/8/R3K2R w KQ -")
    @test movefromsan(b, "Ne4") == Move(SQ_G3, SQ_E4)
    @test movetosan(b, Move(SQ_G3, SQ_E4)) == "Ne4"

    b = fromfen("4k3/R7/8/8/8/8/8/R3K3 w -")
    @test isnothing(movefromsan(b, "Ra6"))
    @test movefromsan(b, "R1a6") == Move(SQ_A1, SQ_A6)
    @test movetosan(b, Move(SQ_A1, SQ_A6)) == "R1a6"
    @test movefromsan(b, "R7a6") == Move(SQ_A7, SQ_A6)
    @test movetosan(b, Move(SQ_A7, SQ_A6)) == "R7a6"

    b = fromfen("4k3/8/8/3q1q2/3q1q2/8/8/4K3 b -")
    @test isnothing(movefromsan(b, "Qde4#"))
    @test isnothing(movefromsan(b, "Qfe4#"))
    @test isnothing(movefromsan(b, "Q4e4#"))
    @test isnothing(movefromsan(b, "Q5e4#"))
    @test movefromsan(b, "Qd4e4#") == Move(SQ_D4, SQ_E4)
    @test movetosan(b, Move(SQ_D4, SQ_E4)) == "Qd4e4#"
    @test movefromsan(b, "Qd5e4#") == Move(SQ_D5, SQ_E4)
    @test movetosan(b, Move(SQ_D5, SQ_E4)) == "Qd5e4#"
    @test movefromsan(b, "Qf4e4#") == Move(SQ_F4, SQ_E4)
    @test movetosan(b, Move(SQ_F4, SQ_E4)) == "Qf4e4#"
    @test movefromsan(b, "Qf5e4#") == Move(SQ_F5, SQ_E4)
    @test movetosan(b, Move(SQ_F5, SQ_E4)) == "Qf5e4#"
end


text:
""" Visualization of delta sets and dual complexes.

This module providers wrapper functions to plotting embedded delta sets using
Makie.jl, including wireframe, mesh, and scatter plots. Note that one of the
Makie backends (CairoMakie, GLMakie, or WGLMakie) must be imported in order for
plotting to work.
"""
module MeshGraphics

using Catlab.CategoricalAlgebra
using ..SimplicialSets
using ..MeshInterop
#import ...Makie: wireframe, wireframe!, mesh, mesh!, scatter, scatter!
#
#export wireframe, wireframe!, mesh, mesh!, scatter, scatter!

using GeometryBasics: Mesh
import ...Makie
import ...Makie: convert_arguments

""" This extends the "Mesh" plotting recipe for embedded deltasets by converting
an embedded deltaset into arguments that can be passed into Makie.mesh
"""

function convert_arguments(P::Union{Type{<:Makie.Wireframe},
                                    Type{<:Makie.Mesh},
                                    Type{<:Makie.Scatter}},
                           dset::HasDeltaSet)
  convert_arguments(P, Mesh(dset))
end

""" This extends the "LineSegments" plotting recipe for embedded deltasets by converting
an embedded deltaset into arguments that can be passed into Makie.linesegments
"""
function convert_arguments(P::Type{<:Makie.LineSegments}, dset::EmbeddedDeltaSet2D)
  edge_positions = zeros(ne(dset)*2,3)
  for e in edges(dset)
    edge_positions[2*e-1,:] = point(dset, src(dset, e))
    edge_positions[2*e,:] = point(dset, tgt(dset, e))
  end
  convert_arguments(P, edge_positions)
end

plottype(::EmbeddedDeltaSet2D) = Mesh

end


text:
# This file is a part of LegendGeSim.jl, licensed under the MIT License (MIT).

__precompile__(true)

"""
    LegendGeSim

Template for Julia packages.
"""
module LegendGeSim

using ArgCheck
using ArraysOfArrays
using Clustering
using CurveFit
using DelimitedFiles
using Distributions
using DSP # Julia's Digital Signal Processor (DSP) Package
using ElasticArrays
using EncodedArrays
using FillArrays
using HDF5 # later not supposed to be here, use LegendHDF5IO functions
using IntervalSets
using JSON
using LegendDataTypes
using LegendHDF5IO
using LegendTextIO
# using LegendTextIO # Geant4CSVInput
using LinearAlgebra
using LsqFit
using MJDSigGen
# using ProgressMeter
using Parameters
using Polynomials
using PropDicts
using RadiationDetectorDSP # dev branch
using RadiationDetectorSignals
using RadiationSpectra
using Random
using Random123
using RecipesBase
using Requires
using SolidStateDetectors
using StaticArrays
using Statistics
using StatsBase
using StructArrays
using Tables
using TypedTables
using Unitful

# using Plots

T = Float32

const energy_unit = u"keV"
const ns_unit = u"ns"
const μs_unit = u"μs"

const germanium_ionization_energy = SolidStateDetectors.material_properties[:HPGe].E_ionisation # in eV

Random.seed!(123) # only for testing

include("sim_config.jl")
include("pss.jl")
include("detector.jl")

include("preamp.jl")
include("fadc.jl")

include("noise.jl")
include("baselines.jl")

include("elec_chain.jl")

include("trigger.jl")
include("daq.jl")

include("pet_to_stp.jl")
include("stp_to_pss.jl")
include("pss_to_raw.jl")
include("pet_to_raw.jl")

include("waveform_utils.jl")
include("temp_utils.jl")

end # module


text:
using Luxor, Thebes

include(dirname(pathof(Thebes)) * "/../data/moreobjects.jl")

moreobjects = [boxcube, boxtorus, concave, cone, crossshape, cube,
cuboctahedron, dodecahedron , geodesic, # helix2, icosahedron,
icosidodecahedron, octahedron, octtorus, rhombicosidodecahedron,
rhombicuboctahedron, rhombitruncated_cubeoctahedron,
rhombitruncated_icosidodecahedron, snub_cube, snub_dodecahedron, sphere2, tet3d,
tetrahedron, triangle, truncated_cube, truncated_dodecahedron,
truncated_icosahedron, truncated_octahedron, truncated_tetrahedron]

objectnames = ["boxcube", "boxtorus", "concave", "cone", "crossshape", "cube",
"cuboctahedron", "dodecahedron", "geodesic", "helix2", "icosahedron",
"icosidodecahedron", "octahedron", "octtorus", "rhombicosidodecahedron",
"rhombicuboctahedron", "rhombitruncated_cubeoctahedron",
"rhombitruncated_icosidodecahedron", "snub_cube", "snub_dodecahedron",
"sphere2", "tet3d", "tetrahedron", "triangle", "truncated_cube",
"truncated_dodecahedron", "truncated_icosahedron", "truncated_octahedron",
"truncated_tetrahedron"]

function main()
    Drawing(800, 800.0, "test-5.svg")
    origin()

    eyepoint(Point3D(500, 500, 500))

    background("azure")
    setopacity(0.5)
    setline(1)
    fontsize(10)
    setlinejoin("bevel")

    tiles = Tiler(800, 800, 6, 6)
    for (pos, n) in tiles
        n > length(moreobjects) && continue
        @layer begin
            translate(pos)
            object = make(moreobjects[n])
            scaleby!(object, 15, 15, 15)
            rotateby!(object, 0, 0, 0)
            #sortfaces!(object)
            pin(object)
            sethue("black")
            label(string(objectnames[n]), :S, offset=tiles.tileheight/2)
        end
    end
    finish()
end

main()


text:
module tests_SolidFileMesh

using Modia3D
using Modia3D.StaticArrays
import Modia3D.ModiaMath

vmat1 = Modia3D.Material(color="LightBlue" , transparency=0.5)    # material of SolidFileMesh
vmat2 = deepcopy(vmat1)                                           # material of convex decomposition of SolidFileMesh
vmat2.transparency = 0.7

cmat = "Steel"

filenamePascal = joinpath(Modia3D.path, "objects", "pascal", "pascal.obj")
filenameCrank = joinpath(Modia3D.path, "objects", "engine", "crank", "crank.obj")
filenameRod = joinpath(Modia3D.path, "objects", "engine", "rod", "rod.obj")
filenameBunny = joinpath(Modia3D.path, "objects", "bunny", "bunny.obj")

@assembly ThreeDFiles begin
  world = Modia3D.Object3D(visualizeFrame=true)
  solidFileMeshCrank = Modia3D.SolidFileMesh(filenameCrank,1.0)
  #fileMesh1 = Modia3D.Object3D(world, Modia3D.Solid(solidFileMeshCrank, "Aluminium", vmat1; contactMaterial = cmat); r=[0.0,0.0,0.0], fixed=false)

  #boxMoving     = Modia3D.Object3D(world, Modia3D.Solid(Modia3D.SolidBox(0.3,0.3,0.3) , "Aluminium", vmat1; contactMaterial = cmat); r=[0.0, 0.0, 0.0], R=ModiaMath.rot2(-pi/3), fixed=false) # ,R=ModiaMath.rot2(-pi/3),

  sphereMoving     = Modia3D.Object3D(world, Modia3D.Solid(Modia3D.SolidSphere(0.5) , "Aluminium", vmat1; contactMaterial = cmat); r=[0.0, 0.0, 0.0],  fixed=false) # R=ModiaMath.rot2(-pi/2),

  #fileMesh2 = Modia3D.Object3D(world, Modia3D.SolidWithConvexDecomposition(solidFileMeshCrank, "Aluminium", vmat1, vmat2; contactMaterial = cmat); r=[3.0,0.0,0.0], fixed=false)

  #bunny = Modia3D.Object3D(world, Modia3D.SolidWithConvexDecomposition(Modia3D.SolidFileMesh(filenameBunny,0.1), "Aluminium", vmat1, vmat2; contactMaterial = cmat); r=[-3.0, 0.0, -1.0], fixed=true)

  box     = Modia3D.Object3D(world, Modia3D.Solid(Modia3D.SolidBox(1.0,4.0,20.0) , "Aluminium", vmat1; contactMaterial = cmat); r=[-3.0, 0.0, -2.0], fixed=true) # R=ModiaMath.rot2(-pi/3),
end

gravField = Modia3D.UniformGravityField(g=9.81, n=[-1,0,0])
threeD = ThreeDFiles(sceneOptions=Modia3D.SceneOptions(gravityField=gravField,visualizeFrames=true, defaultFrameLength=0.7,nz_max = 100, enableContactDetection=true, visualizeContactPoints=true))

# Modia3D.visualizeAssembly!( threeD )

model = Modia3D.SimulationModel( threeD )
result = ModiaMath.simulate!(model; stopTime=4.0, tolerance=1e-6,interval=0.001, log=false)

println("... success of tests_SolidFileMesh.jl!")

end